1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * soc-intel-quirks.h - prototypes for quirk autodetection 4 * 5 * Copyright (c) 2019, Intel Corporation. 6 * 7 */ 8 9 #ifndef _SND_SOC_INTEL_QUIRKS_H 10 #define _SND_SOC_INTEL_QUIRKS_H 11 12 #include <linux/platform_data/x86/soc.h> 13 14 #if IS_REACHABLE(CONFIG_IOSF_MBI) 15 16 #include <linux/dmi.h> 17 #include <asm/iosf_mbi.h> 18 19 static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) 20 { 21 /* 22 * List of systems which: 23 * 1. Use a non CR version of the Bay Trail SoC 24 * 2. Contain at least 6 interrupt resources so that the 25 * platform_get_resource(pdev, IORESOURCE_IRQ, 5) check below 26 * succeeds 27 * 3. Despite 1. and 2. still have their IPC IRQ at index 0 rather then 5 28 * 29 * This needs to be here so that it can be shared between the SST and 30 * SOF drivers. We rely on the compiler to optimize this out in files 31 * where soc_intel_is_byt_cr is not used. 32 */ 33 static const struct dmi_system_id force_bytcr_table[] = { 34 { /* Lenovo Yoga Tablet 2 series */ 35 .matches = { 36 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 37 DMI_MATCH(DMI_PRODUCT_FAMILY, "YOGATablet2"), 38 }, 39 }, 40 {} 41 }; 42 struct device *dev = &pdev->dev; 43 int status = 0; 44 45 if (!soc_intel_is_byt()) 46 return false; 47 48 if (dmi_check_system(force_bytcr_table)) 49 return true; 50 51 if (iosf_mbi_available()) { 52 u32 bios_status; 53 54 status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */ 55 MBI_REG_READ, /* 0x10 */ 56 0x006, /* BIOS_CONFIG */ 57 &bios_status); 58 59 if (status) { 60 dev_err(dev, "could not read PUNIT BIOS_CONFIG\n"); 61 } else { 62 /* bits 26:27 mirror PMIC options */ 63 bios_status = (bios_status >> 26) & 3; 64 65 if (bios_status == 1 || bios_status == 3) { 66 dev_info(dev, "Detected Baytrail-CR platform\n"); 67 return true; 68 } 69 70 dev_info(dev, "BYT-CR not detected\n"); 71 } 72 } else { 73 dev_info(dev, "IOSF_MBI not available, no BYT-CR detection\n"); 74 } 75 76 if (!platform_get_resource(pdev, IORESOURCE_IRQ, 5)) { 77 /* 78 * Some devices detected as BYT-T have only a single IRQ listed, 79 * causing platform_get_irq with index 5 to return -ENXIO. 80 * The correct IRQ in this case is at index 0, as on BYT-CR. 81 */ 82 dev_info(dev, "Falling back to Baytrail-CR platform\n"); 83 return true; 84 } 85 86 return false; 87 } 88 89 #else 90 91 static inline bool soc_intel_is_byt_cr(struct platform_device *pdev) 92 { 93 return false; 94 } 95 96 #endif 97 98 #endif /* _SND_SOC_INTEL_QUIRKS_H */ 99