Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | /* SPDX-License-Identifier: GPL-2.0-only */ /* * soc-intel-quirks.h - prototypes for quirk autodetection * * Copyright (c) 2019, Intel Corporation. * */ #ifndef _SND_SOC_INTEL_QUIRKS_H #define _SND_SOC_INTEL_QUIRKS_H #if IS_ENABLED(CONFIG_X86) #include <linux/dmi.h> #include <asm/cpu_device_id.h> #include <asm/intel-family.h> #include <asm/iosf_mbi.h> #define SOC_INTEL_IS_CPU(soc, type) \ static inline bool soc_intel_is_##soc(void) \ { \ static const struct x86_cpu_id soc##_cpu_ids[] = { \ X86_MATCH_INTEL_FAM6_MODEL(type, NULL), \ {} \ }; \ const struct x86_cpu_id *id; \ \ id = x86_match_cpu(soc##_cpu_ids); \ if (id) \ return true; \ return false; \ } SOC_INTEL_IS_CPU(byt, ATOM_SILVERMONT); SOC_INTEL_IS_CPU(cht, ATOM_AIRMONT); SOC_INTEL_IS_CPU(apl, ATOM_GOLDMONT); SOC_INTEL_IS_CPU(glk, ATOM_GOLDMONT_PLUS); SOC_INTEL_IS_CPU(cml, KABYLAKE_L); static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) { /* * List of systems which: * 1. Use a non CR version of the Bay Trail SoC * 2. Contain at least 6 interrupt resources so that the * platform_get_resource(pdev, IORESOURCE_IRQ, 5) check below * succeeds * 3. Despite 1. and 2. still have their IPC IRQ at index 0 rather then 5 * * This needs to be here so that it can be shared between the SST and * SOF drivers. We rely on the compiler to optimize this out in files * where soc_intel_is_byt_cr is not used. */ static const struct dmi_system_id force_bytcr_table[] = { { /* Lenovo Yoga Tablet 2 series */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_FAMILY, "YOGATablet2"), }, }, {} }; struct device *dev = &pdev->dev; int status = 0; if (!soc_intel_is_byt()) return false; if (dmi_check_system(force_bytcr_table)) return true; if (iosf_mbi_available()) { u32 bios_status; status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */ MBI_REG_READ, /* 0x10 */ 0x006, /* BIOS_CONFIG */ &bios_status); if (status) { dev_err(dev, "could not read PUNIT BIOS_CONFIG\n"); } else { /* bits 26:27 mirror PMIC options */ bios_status = (bios_status >> 26) & 3; if (bios_status == 1 || bios_status == 3) { dev_info(dev, "Detected Baytrail-CR platform\n"); return true; } dev_info(dev, "BYT-CR not detected\n"); } } else { dev_info(dev, "IOSF_MBI not available, no BYT-CR detection\n"); } if (!platform_get_resource(pdev, IORESOURCE_IRQ, 5)) { /* * Some devices detected as BYT-T have only a single IRQ listed, * causing platform_get_irq with index 5 to return -ENXIO. * The correct IRQ in this case is at index 0, as on BYT-CR. */ dev_info(dev, "Falling back to Baytrail-CR platform\n"); return true; } return false; } #else static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) { return false; } static inline bool soc_intel_is_byt(void) { return false; } static inline bool soc_intel_is_cht(void) { return false; } static inline bool soc_intel_is_apl(void) { return false; } static inline bool soc_intel_is_glk(void) { return false; } static inline bool soc_intel_is_cml(void) { return false; } #endif #endif /* _SND_SOC_INTEL_QUIRKS_H */ |