Merge tag 'pidfd.v5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/brauner...
[sfrench/cifs-2.6.git] / sound / soc / intel / common / soc-intel-quirks.h
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_ENABLED(CONFIG_X86)
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 */