1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 // Copyright(c) 2021 Intel Corporation. 3 4 /* 5 * Soundwire DMI quirks 6 */ 7 8 #include <linux/device.h> 9 #include <linux/dmi.h> 10 #include <linux/soundwire/sdw.h> 11 #include "bus.h" 12 13 struct adr_remap { 14 u64 adr; 15 u64 remapped_adr; 16 }; 17 18 static const struct adr_remap global_ghost_adr[] = { 19 { 20 0x000000D010010500ull, 21 0x0000000000000000ull 22 }, 23 {} 24 }; 25 26 /* 27 * Some TigerLake devices based on an initial Intel BIOS do not expose 28 * the correct _ADR in the DSDT. 29 * Remap the bad _ADR values to the ones reported by hardware 30 */ 31 static const struct adr_remap intel_tgl_bios[] = { 32 { 33 0x000010025D070100ull, 34 0x000020025D071100ull 35 }, 36 { 37 0x000110025d070100ull, 38 0x000120025D130800ull 39 }, 40 {} 41 }; 42 43 /* 44 * The initial version of the Dell SKU 0A3E did not expose the devices 45 * on the correct links. 46 */ 47 static const struct adr_remap dell_sku_0A3E[] = { 48 /* rt715 on link0 */ 49 { 50 0x00020025d071100ull, 51 0x00021025d071500ull 52 }, 53 /* rt711 on link1 */ 54 { 55 0x000120025d130800ull, 56 0x000120025d071100ull, 57 }, 58 /* rt1308 on link2 */ 59 { 60 0x000220025d071500ull, 61 0x000220025d130800ull 62 }, 63 {} 64 }; 65 66 /* 67 * The HP Omen 16-k0005TX does not expose the correct version of RT711 on link0 68 * and does not expose a RT1316 on link3 69 */ 70 static const struct adr_remap hp_omen_16[] = { 71 /* rt711-sdca on link0 */ 72 { 73 0x000020025d071100ull, 74 0x000030025d071101ull 75 }, 76 /* rt1316-sdca on link3 */ 77 { 78 0x000120025d071100ull, 79 0x000330025d131601ull 80 }, 81 {} 82 }; 83 84 /* 85 * Intel NUC M15 LAPRC510 and LAPRC710 86 */ 87 static const struct adr_remap intel_rooks_county[] = { 88 /* rt711-sdca on link0 */ 89 { 90 0x000020025d071100ull, 91 0x000030025d071101ull 92 }, 93 /* rt1316-sdca on link2 */ 94 { 95 0x000120025d071100ull, 96 0x000230025d131601ull 97 }, 98 {} 99 }; 100 101 /* 102 * Many platforms have ghost realtek devices in the ACPI that don't physically 103 * exist, remove those devices. 104 */ 105 static const struct adr_remap ghost_realtek[] = { 106 /* rt722 on link3 */ 107 { 108 0x000330025d072201ull, 109 0x0000000000000000ull 110 }, 111 {} 112 }; 113 114 static const struct dmi_system_id adr_remap_quirk_table[] = { 115 /* TGL devices */ 116 { 117 .matches = { 118 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 119 DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"), 120 }, 121 .driver_data = (void *)intel_tgl_bios, 122 }, 123 { 124 .matches = { 125 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 126 DMI_MATCH(DMI_BOARD_NAME, "8709"), 127 }, 128 .driver_data = (void *)intel_tgl_bios, 129 }, 130 { 131 /* quirk used for NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */ 132 .matches = { 133 DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 134 DMI_MATCH(DMI_PRODUCT_NAME, "LAPBC"), 135 }, 136 .driver_data = (void *)intel_tgl_bios, 137 }, 138 { 139 /* quirk used for NUC15 LAPBC710 skew */ 140 .matches = { 141 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), 142 DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"), 143 }, 144 .driver_data = (void *)intel_tgl_bios, 145 }, 146 { 147 /* 148 * quirk used for Avell B.ON (OEM rebrand of NUC15 'Bishop County' 149 * LAPBC510 and LAPBC710) 150 */ 151 .matches = { 152 DMI_MATCH(DMI_SYS_VENDOR, "Avell High Performance"), 153 DMI_MATCH(DMI_PRODUCT_NAME, "B.ON"), 154 }, 155 .driver_data = (void *)intel_tgl_bios, 156 }, 157 { 158 /* quirk used for NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */ 159 .matches = { 160 DMI_MATCH(DMI_SYS_VENDOR, "Intel(R) Client Systems"), 161 DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"), 162 }, 163 .driver_data = (void *)intel_rooks_county, 164 }, 165 { 166 /* quirk used for NUC15 LAPRC710 skew */ 167 .matches = { 168 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), 169 DMI_MATCH(DMI_BOARD_NAME, "LAPRC710"), 170 }, 171 .driver_data = (void *)intel_rooks_county, 172 }, 173 { 174 .matches = { 175 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), 176 DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") 177 }, 178 .driver_data = (void *)dell_sku_0A3E, 179 }, 180 /* ADL devices */ 181 { 182 .matches = { 183 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 184 DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16"), 185 }, 186 .driver_data = (void *)hp_omen_16, 187 }, 188 /* PTL devices */ 189 { 190 .matches = { 191 DMI_MATCH(DMI_SYS_VENDOR, "ASUS"), 192 DMI_MATCH(DMI_BOARD_NAME, "B9406CAA"), 193 }, 194 .driver_data = (void *)ghost_realtek, 195 }, 196 { 197 .matches = { 198 DMI_MATCH(DMI_SYS_VENDOR, "ASUS"), 199 DMI_MATCH(DMI_BOARD_NAME, "GX651AR"), 200 }, 201 .driver_data = (void *)ghost_realtek, 202 }, 203 { 204 .matches = { 205 DMI_MATCH(DMI_SYS_VENDOR, "ASUS"), 206 DMI_MATCH(DMI_BOARD_NAME, "UX5406AA"), 207 }, 208 .driver_data = (void *)ghost_realtek, 209 }, 210 { 211 .matches = { 212 DMI_MATCH(DMI_SYS_VENDOR, "ASUS"), 213 DMI_MATCH(DMI_BOARD_NAME, "UX8407AA"), 214 }, 215 .driver_data = (void *)ghost_realtek, 216 }, 217 { 218 .matches = { 219 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 220 DMI_MATCH(DMI_PRODUCT_NAME, "83QK"), 221 }, 222 .driver_data = (void *)ghost_realtek, 223 }, 224 { 225 .matches = { 226 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 227 DMI_MATCH(DMI_PRODUCT_NAME, "83SF"), 228 }, 229 .driver_data = (void *)ghost_realtek, 230 }, 231 {} 232 }; 233 234 u64 sdw_dmi_override_adr(struct sdw_bus *bus, u64 addr) 235 { 236 const struct dmi_system_id *dmi_id; 237 int i; 238 239 /* check if any address remap quirk applies */ 240 dmi_id = dmi_first_match(adr_remap_quirk_table); 241 if (dmi_id) { 242 struct adr_remap *map; 243 244 for (map = dmi_id->driver_data; map->adr; map++) { 245 if (map->adr == addr) { 246 dev_dbg(bus->dev, "remapped _ADR 0x%llx as 0x%llx\n", 247 addr, map->remapped_adr); 248 addr = map->remapped_adr; 249 goto out; 250 } 251 } 252 } 253 254 /* remap the ghost ADRs */ 255 for (i = 0; i < ARRAY_SIZE(global_ghost_adr); i++) { 256 if (global_ghost_adr[i].adr == addr) { 257 dev_dbg(bus->dev, "remapped _ADR 0x%llx as 0x%llx\n", 258 addr, global_ghost_adr[i].remapped_adr); 259 addr = global_ghost_adr[i].remapped_adr; 260 break; 261 } 262 } 263 out: 264 return addr; 265 } 266