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(list: 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 | offset: 0x006, /* BIOS_CONFIG */ |
57 | mdr: &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 | |