1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * HWMON driver for ASUS motherboards that publish some sensor values
4 * via the embedded controller registers.
5 *
6 * Copyright (C) 2021 Eugene Shalygin <eugene.shalygin@gmail.com>
7
8 * EC provides:
9 * - Chipset temperature
10 * - CPU temperature
11 * - Motherboard temperature
12 * - T_Sensor temperature
13 * - VRM temperature
14 * - Water In temperature
15 * - Water Out temperature
16 * - CPU Optional fan RPM
17 * - Chipset fan RPM
18 * - VRM Heat Sink fan RPM
19 * - Water Flow fan RPM
20 * - CPU current
21 * - CPU core voltage
22 */
23
24 #include <linux/acpi.h>
25 #include <linux/bitops.h>
26 #include <linux/dev_printk.h>
27 #include <linux/dmi.h>
28 #include <linux/hwmon.h>
29 #include <linux/init.h>
30 #include <linux/jiffies.h>
31 #include <linux/kernel.h>
32 #include <linux/module.h>
33 #include <linux/platform_device.h>
34 #include <linux/sort.h>
35 #include <linux/units.h>
36
37 #include <linux/unaligned.h>
38
39 static char *mutex_path_override;
40
41 /* Writing to this EC register switches EC bank */
42 #define ASUS_EC_BANK_REGISTER 0xff
43 #define SENSOR_LABEL_LEN 16
44
45 /*
46 * Arbitrary set max. allowed bank number. Required for sorting banks and
47 * currently is overkill with just 2 banks used at max, but for the sake
48 * of alignment let's set it to a higher value.
49 */
50 #define ASUS_EC_MAX_BANK 3
51
52 #define ACPI_LOCK_DELAY_MS 500
53
54 /* ACPI mutex for locking access to the EC for the firmware */
55 #define ASUS_HW_ACCESS_MUTEX_ASMX "\\AMW0.ASMX"
56
57 #define ASUS_HW_ACCESS_MUTEX_RMTW_ASMX "\\RMTW.ASMX"
58
59 #define ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0 "\\_SB_.PCI0.SBRG.SIO1.MUT0"
60
61 #define MAX_IDENTICAL_BOARD_VARIATIONS 3
62
63 /* Moniker for the ACPI global lock (':' is not allowed in ASL identifiers) */
64 #define ACPI_GLOBAL_LOCK_PSEUDO_PATH ":GLOBAL_LOCK"
65
66 typedef union {
67 u32 value;
68 struct {
69 u8 index;
70 u8 bank;
71 u8 size;
72 u8 dummy;
73 } components;
74 } sensor_address;
75
76 #define MAKE_SENSOR_ADDRESS(size, bank, index) { \
77 .value = (size << 16) + (bank << 8) + index \
78 }
79
80 static u32 hwmon_attributes[hwmon_max] = {
81 [hwmon_chip] = HWMON_C_REGISTER_TZ,
82 [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL,
83 [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL,
84 [hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL,
85 [hwmon_fan] = HWMON_F_INPUT | HWMON_F_LABEL,
86 };
87
88 struct ec_sensor_info {
89 char label[SENSOR_LABEL_LEN];
90 enum hwmon_sensor_types type;
91 sensor_address addr;
92 };
93
94 #define EC_SENSOR(sensor_label, sensor_type, size, bank, index) { \
95 .label = sensor_label, .type = sensor_type, \
96 .addr = MAKE_SENSOR_ADDRESS(size, bank, index), \
97 }
98
99 enum ec_sensors {
100 /* chipset temperature [℃] */
101 ec_sensor_temp_chipset,
102 /* CPU temperature [℃] */
103 ec_sensor_temp_cpu,
104 /* CPU package temperature [℃] */
105 ec_sensor_temp_cpu_package,
106 /* motherboard temperature [℃] */
107 ec_sensor_temp_mb,
108 /* "T_Sensor" temperature sensor reading [℃] */
109 ec_sensor_temp_t_sensor,
110 /* VRM temperature [℃] */
111 ec_sensor_temp_vrm,
112 /* CPU Core voltage [mV] */
113 ec_sensor_in_cpu_core,
114 /* CPU_Opt fan [RPM] */
115 ec_sensor_fan_cpu_opt,
116 /* VRM heat sink fan [RPM] */
117 ec_sensor_fan_vrm_hs,
118 /* Chipset fan [RPM] */
119 ec_sensor_fan_chipset,
120 /* Water flow sensor reading [RPM] */
121 ec_sensor_fan_water_flow,
122 /* CPU current [A] */
123 ec_sensor_curr_cpu,
124 /* "Water_In" temperature sensor reading [℃] */
125 ec_sensor_temp_water_in,
126 /* "Water_Out" temperature sensor reading [℃] */
127 ec_sensor_temp_water_out,
128 /* "Water_Block_In" temperature sensor reading [℃] */
129 ec_sensor_temp_water_block_in,
130 /* "Water_Block_Out" temperature sensor reading [℃] */
131 ec_sensor_temp_water_block_out,
132 /* "T_sensor_2" temperature sensor reading [℃] */
133 ec_sensor_temp_t_sensor_2,
134 /* "Extra_1" temperature sensor reading [℃] */
135 ec_sensor_temp_sensor_extra_1,
136 /* "Extra_2" temperature sensor reading [℃] */
137 ec_sensor_temp_sensor_extra_2,
138 /* "Extra_3" temperature sensor reading [℃] */
139 ec_sensor_temp_sensor_extra_3,
140 };
141
142 #define SENSOR_TEMP_CHIPSET BIT(ec_sensor_temp_chipset)
143 #define SENSOR_TEMP_CPU BIT(ec_sensor_temp_cpu)
144 #define SENSOR_TEMP_CPU_PACKAGE BIT(ec_sensor_temp_cpu_package)
145 #define SENSOR_TEMP_MB BIT(ec_sensor_temp_mb)
146 #define SENSOR_TEMP_T_SENSOR BIT(ec_sensor_temp_t_sensor)
147 #define SENSOR_TEMP_VRM BIT(ec_sensor_temp_vrm)
148 #define SENSOR_IN_CPU_CORE BIT(ec_sensor_in_cpu_core)
149 #define SENSOR_FAN_CPU_OPT BIT(ec_sensor_fan_cpu_opt)
150 #define SENSOR_FAN_VRM_HS BIT(ec_sensor_fan_vrm_hs)
151 #define SENSOR_FAN_CHIPSET BIT(ec_sensor_fan_chipset)
152 #define SENSOR_FAN_WATER_FLOW BIT(ec_sensor_fan_water_flow)
153 #define SENSOR_CURR_CPU BIT(ec_sensor_curr_cpu)
154 #define SENSOR_TEMP_WATER_IN BIT(ec_sensor_temp_water_in)
155 #define SENSOR_TEMP_WATER_OUT BIT(ec_sensor_temp_water_out)
156 #define SENSOR_TEMP_WATER_BLOCK_IN BIT(ec_sensor_temp_water_block_in)
157 #define SENSOR_TEMP_WATER_BLOCK_OUT BIT(ec_sensor_temp_water_block_out)
158 #define SENSOR_TEMP_T_SENSOR_2 BIT(ec_sensor_temp_t_sensor_2)
159 #define SENSOR_TEMP_SENSOR_EXTRA_1 BIT(ec_sensor_temp_sensor_extra_1)
160 #define SENSOR_TEMP_SENSOR_EXTRA_2 BIT(ec_sensor_temp_sensor_extra_2)
161 #define SENSOR_TEMP_SENSOR_EXTRA_3 BIT(ec_sensor_temp_sensor_extra_3)
162
163 enum board_family {
164 family_unknown,
165 family_amd_400_series,
166 family_amd_500_series,
167 family_amd_600_series,
168 family_intel_300_series,
169 family_intel_600_series
170 };
171
172 /* All the known sensors for ASUS EC controllers */
173 static const struct ec_sensor_info sensors_family_amd_400[] = {
174 [ec_sensor_temp_chipset] =
175 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a),
176 [ec_sensor_temp_cpu] =
177 EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b),
178 [ec_sensor_temp_mb] =
179 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c),
180 [ec_sensor_temp_t_sensor] =
181 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d),
182 [ec_sensor_temp_vrm] =
183 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e),
184 [ec_sensor_in_cpu_core] =
185 EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2),
186 [ec_sensor_fan_cpu_opt] =
187 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xbc),
188 [ec_sensor_fan_vrm_hs] =
189 EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2),
190 [ec_sensor_fan_chipset] =
191 /* no chipset fans in this generation */
192 EC_SENSOR("Chipset", hwmon_fan, 0, 0x00, 0x00),
193 [ec_sensor_fan_water_flow] =
194 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xb4),
195 [ec_sensor_curr_cpu] =
196 EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4),
197 [ec_sensor_temp_water_in] =
198 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x0d),
199 [ec_sensor_temp_water_out] =
200 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x0b),
201 };
202
203 static const struct ec_sensor_info sensors_family_amd_500[] = {
204 [ec_sensor_temp_chipset] =
205 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a),
206 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b),
207 [ec_sensor_temp_mb] =
208 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c),
209 [ec_sensor_temp_t_sensor] =
210 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d),
211 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e),
212 [ec_sensor_in_cpu_core] =
213 EC_SENSOR("CPU Core", hwmon_in, 2, 0x00, 0xa2),
214 [ec_sensor_fan_cpu_opt] =
215 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0),
216 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2),
217 [ec_sensor_fan_chipset] =
218 EC_SENSOR("Chipset", hwmon_fan, 2, 0x00, 0xb4),
219 [ec_sensor_fan_water_flow] =
220 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc),
221 [ec_sensor_curr_cpu] = EC_SENSOR("CPU", hwmon_curr, 1, 0x00, 0xf4),
222 [ec_sensor_temp_water_in] =
223 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00),
224 [ec_sensor_temp_water_out] =
225 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01),
226 [ec_sensor_temp_water_block_in] =
227 EC_SENSOR("Water_Block_In", hwmon_temp, 1, 0x01, 0x02),
228 [ec_sensor_temp_water_block_out] =
229 EC_SENSOR("Water_Block_Out", hwmon_temp, 1, 0x01, 0x03),
230 [ec_sensor_temp_sensor_extra_1] =
231 EC_SENSOR("Extra_1", hwmon_temp, 1, 0x01, 0x09),
232 [ec_sensor_temp_t_sensor_2] =
233 EC_SENSOR("T_sensor_2", hwmon_temp, 1, 0x01, 0x0a),
234 [ec_sensor_temp_sensor_extra_2] =
235 EC_SENSOR("Extra_2", hwmon_temp, 1, 0x01, 0x0b),
236 [ec_sensor_temp_sensor_extra_3] =
237 EC_SENSOR("Extra_3", hwmon_temp, 1, 0x01, 0x0c),
238 };
239
240 static const struct ec_sensor_info sensors_family_amd_600[] = {
241 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x30),
242 [ec_sensor_temp_cpu_package] = EC_SENSOR("CPU Package", hwmon_temp, 1, 0x00, 0x31),
243 [ec_sensor_temp_mb] =
244 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x32),
245 [ec_sensor_temp_vrm] =
246 EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x33),
247 [ec_sensor_temp_t_sensor] =
248 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x36),
249 [ec_sensor_temp_water_in] =
250 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00),
251 [ec_sensor_temp_water_out] =
252 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01),
253 [ec_sensor_fan_cpu_opt] =
254 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0),
255 };
256
257 static const struct ec_sensor_info sensors_family_intel_300[] = {
258 [ec_sensor_temp_chipset] =
259 EC_SENSOR("Chipset", hwmon_temp, 1, 0x00, 0x3a),
260 [ec_sensor_temp_cpu] = EC_SENSOR("CPU", hwmon_temp, 1, 0x00, 0x3b),
261 [ec_sensor_temp_mb] =
262 EC_SENSOR("Motherboard", hwmon_temp, 1, 0x00, 0x3c),
263 [ec_sensor_temp_t_sensor] =
264 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d),
265 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e),
266 [ec_sensor_fan_cpu_opt] =
267 EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0),
268 [ec_sensor_fan_vrm_hs] = EC_SENSOR("VRM HS", hwmon_fan, 2, 0x00, 0xb2),
269 [ec_sensor_fan_water_flow] =
270 EC_SENSOR("Water_Flow", hwmon_fan, 2, 0x00, 0xbc),
271 [ec_sensor_temp_water_in] =
272 EC_SENSOR("Water_In", hwmon_temp, 1, 0x01, 0x00),
273 [ec_sensor_temp_water_out] =
274 EC_SENSOR("Water_Out", hwmon_temp, 1, 0x01, 0x01),
275 };
276
277 static const struct ec_sensor_info sensors_family_intel_600[] = {
278 [ec_sensor_temp_t_sensor] =
279 EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x3d),
280 [ec_sensor_temp_vrm] = EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x3e),
281 };
282
283 /* Shortcuts for common combinations */
284 #define SENSOR_SET_TEMP_CHIPSET_CPU_MB \
285 (SENSOR_TEMP_CHIPSET | SENSOR_TEMP_CPU | SENSOR_TEMP_MB)
286 #define SENSOR_SET_TEMP_WATER (SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT)
287 #define SENSOR_SET_WATER_BLOCK \
288 (SENSOR_TEMP_WATER_BLOCK_IN | SENSOR_TEMP_WATER_BLOCK_OUT)
289
290 struct ec_board_info {
291 unsigned long sensors;
292 /*
293 * Defines which mutex to use for guarding access to the state and the
294 * hardware. Can be either a full path to an AML mutex or the
295 * pseudo-path ACPI_GLOBAL_LOCK_PSEUDO_PATH to use the global ACPI lock,
296 * or left empty to use a regular mutex object, in which case access to
297 * the hardware is not guarded.
298 */
299 const char *mutex_path;
300 enum board_family family;
301 };
302
303 static const struct ec_board_info board_info_prime_x470_pro = {
304 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
305 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
306 SENSOR_FAN_CPU_OPT |
307 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
308 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH,
309 .family = family_amd_400_series,
310 };
311
312 static const struct ec_board_info board_info_prime_x570_pro = {
313 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
314 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET,
315 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
316 .family = family_amd_500_series,
317 };
318
319 static const struct ec_board_info board_info_prime_x670e_pro_wifi = {
320 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE |
321 SENSOR_TEMP_MB | SENSOR_TEMP_VRM |
322 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT,
323 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH,
324 .family = family_amd_600_series,
325 };
326
327 static const struct ec_board_info board_info_pro_art_x570_creator_wifi = {
328 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
329 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT |
330 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
331 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
332 .family = family_amd_500_series,
333 };
334
335 static const struct ec_board_info board_info_pro_art_x670E_creator_wifi = {
336 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE |
337 SENSOR_TEMP_MB | SENSOR_TEMP_VRM |
338 SENSOR_TEMP_T_SENSOR,
339 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH,
340 .family = family_amd_600_series,
341 };
342
343 static const struct ec_board_info board_info_pro_art_b550_creator = {
344 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
345 SENSOR_TEMP_T_SENSOR |
346 SENSOR_FAN_CPU_OPT,
347 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
348 .family = family_amd_500_series,
349 };
350
351 static const struct ec_board_info board_info_pro_ws_x570_ace = {
352 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM |
353 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET |
354 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
355 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
356 .family = family_amd_500_series,
357 };
358
359 static const struct ec_board_info board_info_crosshair_x670e_hero = {
360 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE |
361 SENSOR_TEMP_MB | SENSOR_TEMP_VRM |
362 SENSOR_SET_TEMP_WATER,
363 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH,
364 .family = family_amd_600_series,
365 };
366
367 static const struct ec_board_info board_info_crosshair_x670e_gene = {
368 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE |
369 SENSOR_TEMP_T_SENSOR |
370 SENSOR_TEMP_MB | SENSOR_TEMP_VRM,
371 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH,
372 .family = family_amd_600_series,
373 };
374
375 static const struct ec_board_info board_info_crosshair_viii_dark_hero = {
376 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
377 SENSOR_TEMP_T_SENSOR |
378 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
379 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW |
380 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
381 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
382 .family = family_amd_500_series,
383 };
384
385 static const struct ec_board_info board_info_crosshair_viii_hero = {
386 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
387 SENSOR_TEMP_T_SENSOR |
388 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
389 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET |
390 SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU |
391 SENSOR_IN_CPU_CORE,
392 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
393 .family = family_amd_500_series,
394 };
395
396 static const struct ec_board_info board_info_maximus_xi_hero = {
397 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
398 SENSOR_TEMP_T_SENSOR |
399 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
400 SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW,
401 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
402 .family = family_intel_300_series,
403 };
404
405 static const struct ec_board_info board_info_crosshair_viii_impact = {
406 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
407 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
408 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
409 SENSOR_IN_CPU_CORE,
410 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
411 .family = family_amd_500_series,
412 };
413
414 static const struct ec_board_info board_info_strix_b550_e_gaming = {
415 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
416 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
417 SENSOR_FAN_CPU_OPT,
418 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
419 .family = family_amd_500_series,
420 };
421
422 static const struct ec_board_info board_info_strix_b550_i_gaming = {
423 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
424 SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
425 SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU |
426 SENSOR_IN_CPU_CORE,
427 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
428 .family = family_amd_500_series,
429 };
430
431 static const struct ec_board_info board_info_strix_x570_e_gaming = {
432 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
433 SENSOR_TEMP_T_SENSOR |
434 SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
435 SENSOR_IN_CPU_CORE,
436 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
437 .family = family_amd_500_series,
438 };
439
440 static const struct ec_board_info board_info_strix_x570_e_gaming_wifi_ii = {
441 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
442 SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU |
443 SENSOR_IN_CPU_CORE,
444 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
445 .family = family_amd_500_series,
446 };
447
448 static const struct ec_board_info board_info_strix_x570_f_gaming = {
449 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
450 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET,
451 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
452 .family = family_amd_500_series,
453 };
454
455 static const struct ec_board_info board_info_strix_x570_i_gaming = {
456 .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM |
457 SENSOR_TEMP_T_SENSOR |
458 SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET |
459 SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE,
460 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
461 .family = family_amd_500_series,
462 };
463
464 static const struct ec_board_info board_info_strix_z390_f_gaming = {
465 .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM |
466 SENSOR_TEMP_T_SENSOR |
467 SENSOR_FAN_CPU_OPT,
468 .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
469 .family = family_intel_300_series,
470 };
471
472 static const struct ec_board_info board_info_strix_z690_a_gaming_wifi_d4 = {
473 .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM,
474 .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX,
475 .family = family_intel_600_series,
476 };
477
478 static const struct ec_board_info board_info_zenith_ii_extreme = {
479 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR |
480 SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER |
481 SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_VRM_HS |
482 SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE |
483 SENSOR_SET_WATER_BLOCK |
484 SENSOR_TEMP_T_SENSOR_2 | SENSOR_TEMP_SENSOR_EXTRA_1 |
485 SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3,
486 .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0,
487 .family = family_amd_500_series,
488 };
489
490 static const struct ec_board_info board_info_tuf_gaming_x670e_plus = {
491 .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE |
492 SENSOR_TEMP_MB | SENSOR_TEMP_VRM |
493 SENSOR_TEMP_WATER_IN | SENSOR_TEMP_WATER_OUT |
494 SENSOR_FAN_CPU_OPT,
495 .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH,
496 .family = family_amd_600_series,
497 };
498
499 #define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, board_info) \
500 { \
501 .matches = { \
502 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, \
503 "ASUSTeK COMPUTER INC."), \
504 DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \
505 }, \
506 .driver_data = (void *)board_info, \
507 }
508
509 static const struct dmi_system_id dmi_table[] = {
510 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO",
511 &board_info_prime_x470_pro),
512 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO",
513 &board_info_prime_x570_pro),
514 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X670E-PRO WIFI",
515 &board_info_prime_x670e_pro_wifi),
516 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI",
517 &board_info_pro_art_x570_creator_wifi),
518 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X670E-CREATOR WIFI",
519 &board_info_pro_art_x670E_creator_wifi),
520 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt B550-CREATOR",
521 &board_info_pro_art_b550_creator),
522 DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS X570-ACE",
523 &board_info_pro_ws_x570_ace),
524 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII DARK HERO",
525 &board_info_crosshair_viii_dark_hero),
526 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII FORMULA",
527 &board_info_crosshair_viii_hero),
528 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO",
529 &board_info_crosshair_viii_hero),
530 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO (WI-FI)",
531 &board_info_crosshair_viii_hero),
532 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E HERO",
533 &board_info_crosshair_x670e_hero),
534 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR X670E GENE",
535 &board_info_crosshair_x670e_gene),
536 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO",
537 &board_info_maximus_xi_hero),
538 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO (WI-FI)",
539 &board_info_maximus_xi_hero),
540 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII IMPACT",
541 &board_info_crosshair_viii_impact),
542 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-E GAMING",
543 &board_info_strix_b550_e_gaming),
544 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING",
545 &board_info_strix_b550_i_gaming),
546 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING",
547 &board_info_strix_x570_e_gaming),
548 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING WIFI II",
549 &board_info_strix_x570_e_gaming_wifi_ii),
550 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-F GAMING",
551 &board_info_strix_x570_f_gaming),
552 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-I GAMING",
553 &board_info_strix_x570_i_gaming),
554 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z390-F GAMING",
555 &board_info_strix_z390_f_gaming),
556 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-A GAMING WIFI D4",
557 &board_info_strix_z690_a_gaming_wifi_d4),
558 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME",
559 &board_info_zenith_ii_extreme),
560 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME ALPHA",
561 &board_info_zenith_ii_extreme),
562 DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X670E-PLUS",
563 &board_info_tuf_gaming_x670e_plus),
564 {},
565 };
566
567 struct ec_sensor {
568 unsigned int info_index;
569 s32 cached_value;
570 };
571
572 struct lock_data {
573 union {
574 acpi_handle aml;
575 /* global lock handle */
576 u32 glk;
577 } mutex;
578 bool (*lock)(struct lock_data *data);
579 bool (*unlock)(struct lock_data *data);
580 };
581
582 /*
583 * The next function pairs implement options for locking access to the
584 * state and the EC
585 */
lock_via_acpi_mutex(struct lock_data * data)586 static bool lock_via_acpi_mutex(struct lock_data *data)
587 {
588 /*
589 * ASUS DSDT does not specify that access to the EC has to be guarded,
590 * but firmware does access it via ACPI
591 */
592 return ACPI_SUCCESS(acpi_acquire_mutex(data->mutex.aml,
593 NULL, ACPI_LOCK_DELAY_MS));
594 }
595
unlock_acpi_mutex(struct lock_data * data)596 static bool unlock_acpi_mutex(struct lock_data *data)
597 {
598 return ACPI_SUCCESS(acpi_release_mutex(data->mutex.aml, NULL));
599 }
600
lock_via_global_acpi_lock(struct lock_data * data)601 static bool lock_via_global_acpi_lock(struct lock_data *data)
602 {
603 return ACPI_SUCCESS(acpi_acquire_global_lock(ACPI_LOCK_DELAY_MS,
604 &data->mutex.glk));
605 }
606
unlock_global_acpi_lock(struct lock_data * data)607 static bool unlock_global_acpi_lock(struct lock_data *data)
608 {
609 return ACPI_SUCCESS(acpi_release_global_lock(data->mutex.glk));
610 }
611
612 struct ec_sensors_data {
613 const struct ec_board_info *board_info;
614 const struct ec_sensor_info *sensors_info;
615 struct ec_sensor *sensors;
616 /* EC registers to read from */
617 u16 *registers;
618 u8 *read_buffer;
619 /* sorted list of unique register banks */
620 u8 banks[ASUS_EC_MAX_BANK + 1];
621 /* in jiffies */
622 unsigned long last_updated;
623 struct lock_data lock_data;
624 /* number of board EC sensors */
625 u8 nr_sensors;
626 /*
627 * number of EC registers to read
628 * (sensor might span more than 1 register)
629 */
630 u8 nr_registers;
631 /* number of unique register banks */
632 u8 nr_banks;
633 };
634
register_bank(u16 reg)635 static u8 register_bank(u16 reg)
636 {
637 return reg >> 8;
638 }
639
register_index(u16 reg)640 static u8 register_index(u16 reg)
641 {
642 return reg & 0x00ff;
643 }
644
is_sensor_data_signed(const struct ec_sensor_info * si)645 static bool is_sensor_data_signed(const struct ec_sensor_info *si)
646 {
647 /*
648 * guessed from WMI functions in DSDT code for boards
649 * of the X470 generation
650 */
651 return si->type == hwmon_temp;
652 }
653
654 static const struct ec_sensor_info *
get_sensor_info(const struct ec_sensors_data * state,int index)655 get_sensor_info(const struct ec_sensors_data *state, int index)
656 {
657 return state->sensors_info + state->sensors[index].info_index;
658 }
659
find_ec_sensor_index(const struct ec_sensors_data * ec,enum hwmon_sensor_types type,int channel)660 static int find_ec_sensor_index(const struct ec_sensors_data *ec,
661 enum hwmon_sensor_types type, int channel)
662 {
663 unsigned int i;
664
665 for (i = 0; i < ec->nr_sensors; i++) {
666 if (get_sensor_info(ec, i)->type == type) {
667 if (channel == 0)
668 return i;
669 channel--;
670 }
671 }
672 return -ENOENT;
673 }
674
bank_compare(const void * a,const void * b)675 static int bank_compare(const void *a, const void *b)
676 {
677 return *((const s8 *)a) - *((const s8 *)b);
678 }
679
setup_sensor_data(struct ec_sensors_data * ec)680 static void setup_sensor_data(struct ec_sensors_data *ec)
681 {
682 struct ec_sensor *s = ec->sensors;
683 bool bank_found;
684 int i, j;
685 u8 bank;
686
687 ec->nr_banks = 0;
688 ec->nr_registers = 0;
689
690 for_each_set_bit(i, &ec->board_info->sensors,
691 BITS_PER_TYPE(ec->board_info->sensors)) {
692 s->info_index = i;
693 s->cached_value = 0;
694 ec->nr_registers +=
695 ec->sensors_info[s->info_index].addr.components.size;
696 bank_found = false;
697 bank = ec->sensors_info[s->info_index].addr.components.bank;
698 for (j = 0; j < ec->nr_banks; j++) {
699 if (ec->banks[j] == bank) {
700 bank_found = true;
701 break;
702 }
703 }
704 if (!bank_found) {
705 ec->banks[ec->nr_banks++] = bank;
706 }
707 s++;
708 }
709 sort(ec->banks, ec->nr_banks, 1, bank_compare, NULL);
710 }
711
fill_ec_registers(struct ec_sensors_data * ec)712 static void fill_ec_registers(struct ec_sensors_data *ec)
713 {
714 const struct ec_sensor_info *si;
715 unsigned int i, j, register_idx = 0;
716
717 for (i = 0; i < ec->nr_sensors; ++i) {
718 si = get_sensor_info(ec, i);
719 for (j = 0; j < si->addr.components.size; ++j, ++register_idx) {
720 ec->registers[register_idx] =
721 (si->addr.components.bank << 8) +
722 si->addr.components.index + j;
723 }
724 }
725 }
726
setup_lock_data(struct device * dev)727 static int setup_lock_data(struct device *dev)
728 {
729 const char *mutex_path;
730 int status;
731 struct ec_sensors_data *state = dev_get_drvdata(dev);
732
733 mutex_path = mutex_path_override ?
734 mutex_path_override : state->board_info->mutex_path;
735
736 if (!mutex_path || !strlen(mutex_path)) {
737 dev_err(dev, "Hardware access guard mutex name is empty");
738 return -EINVAL;
739 }
740 if (!strcmp(mutex_path, ACPI_GLOBAL_LOCK_PSEUDO_PATH)) {
741 state->lock_data.mutex.glk = 0;
742 state->lock_data.lock = lock_via_global_acpi_lock;
743 state->lock_data.unlock = unlock_global_acpi_lock;
744 } else {
745 status = acpi_get_handle(NULL, (acpi_string)mutex_path,
746 &state->lock_data.mutex.aml);
747 if (ACPI_FAILURE(status)) {
748 dev_err(dev,
749 "Failed to get hardware access guard AML mutex '%s': error %d",
750 mutex_path, status);
751 return -ENOENT;
752 }
753 state->lock_data.lock = lock_via_acpi_mutex;
754 state->lock_data.unlock = unlock_acpi_mutex;
755 }
756 return 0;
757 }
758
asus_ec_bank_switch(u8 bank,u8 * old)759 static int asus_ec_bank_switch(u8 bank, u8 *old)
760 {
761 int status = 0;
762
763 if (old) {
764 status = ec_read(ASUS_EC_BANK_REGISTER, old);
765 }
766 if (status || (old && (*old == bank)))
767 return status;
768 return ec_write(ASUS_EC_BANK_REGISTER, bank);
769 }
770
asus_ec_block_read(const struct device * dev,struct ec_sensors_data * ec)771 static int asus_ec_block_read(const struct device *dev,
772 struct ec_sensors_data *ec)
773 {
774 int ireg, ibank, status;
775 u8 bank, reg_bank, prev_bank;
776
777 bank = 0;
778 status = asus_ec_bank_switch(bank, &prev_bank);
779 if (status) {
780 dev_warn(dev, "EC bank switch failed");
781 return status;
782 }
783
784 if (prev_bank) {
785 /* oops... somebody else is working with the EC too */
786 dev_warn(dev,
787 "Concurrent access to the ACPI EC detected.\nRace condition possible.");
788 }
789
790 /* read registers minimizing bank switches. */
791 for (ibank = 0; ibank < ec->nr_banks; ibank++) {
792 if (bank != ec->banks[ibank]) {
793 bank = ec->banks[ibank];
794 if (asus_ec_bank_switch(bank, NULL)) {
795 dev_warn(dev, "EC bank switch to %d failed",
796 bank);
797 break;
798 }
799 }
800 for (ireg = 0; ireg < ec->nr_registers; ireg++) {
801 reg_bank = register_bank(ec->registers[ireg]);
802 if (reg_bank < bank) {
803 continue;
804 }
805 ec_read(register_index(ec->registers[ireg]),
806 ec->read_buffer + ireg);
807 }
808 }
809
810 status = asus_ec_bank_switch(prev_bank, NULL);
811 return status;
812 }
813
get_sensor_value(const struct ec_sensor_info * si,u8 * data)814 static inline s32 get_sensor_value(const struct ec_sensor_info *si, u8 *data)
815 {
816 if (is_sensor_data_signed(si)) {
817 switch (si->addr.components.size) {
818 case 1:
819 return (s8)*data;
820 case 2:
821 return (s16)get_unaligned_be16(data);
822 case 4:
823 return (s32)get_unaligned_be32(data);
824 default:
825 return 0;
826 }
827 } else {
828 switch (si->addr.components.size) {
829 case 1:
830 return *data;
831 case 2:
832 return get_unaligned_be16(data);
833 case 4:
834 return get_unaligned_be32(data);
835 default:
836 return 0;
837 }
838 }
839 }
840
update_sensor_values(struct ec_sensors_data * ec,u8 * data)841 static void update_sensor_values(struct ec_sensors_data *ec, u8 *data)
842 {
843 const struct ec_sensor_info *si;
844 struct ec_sensor *s, *sensor_end;
845
846 sensor_end = ec->sensors + ec->nr_sensors;
847 for (s = ec->sensors; s != sensor_end; s++) {
848 si = ec->sensors_info + s->info_index;
849 s->cached_value = get_sensor_value(si, data);
850 data += si->addr.components.size;
851 }
852 }
853
update_ec_sensors(const struct device * dev,struct ec_sensors_data * ec)854 static int update_ec_sensors(const struct device *dev,
855 struct ec_sensors_data *ec)
856 {
857 int status;
858
859 if (!ec->lock_data.lock(&ec->lock_data)) {
860 dev_warn(dev, "Failed to acquire mutex");
861 return -EBUSY;
862 }
863
864 status = asus_ec_block_read(dev, ec);
865
866 if (!status) {
867 update_sensor_values(ec, ec->read_buffer);
868 }
869
870 if (!ec->lock_data.unlock(&ec->lock_data))
871 dev_err(dev, "Failed to release mutex");
872
873 return status;
874 }
875
scale_sensor_value(s32 value,int data_type)876 static long scale_sensor_value(s32 value, int data_type)
877 {
878 switch (data_type) {
879 case hwmon_curr:
880 case hwmon_temp:
881 return value * MILLI;
882 default:
883 return value;
884 }
885 }
886
get_cached_value_or_update(const struct device * dev,int sensor_index,struct ec_sensors_data * state,s32 * value)887 static int get_cached_value_or_update(const struct device *dev,
888 int sensor_index,
889 struct ec_sensors_data *state, s32 *value)
890 {
891 if (time_after(jiffies, state->last_updated + HZ)) {
892 if (update_ec_sensors(dev, state)) {
893 dev_err(dev, "update_ec_sensors() failure\n");
894 return -EIO;
895 }
896
897 state->last_updated = jiffies;
898 }
899
900 *value = state->sensors[sensor_index].cached_value;
901 return 0;
902 }
903
904 /*
905 * Now follow the functions that implement the hwmon interface
906 */
907
asus_ec_hwmon_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)908 static int asus_ec_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
909 u32 attr, int channel, long *val)
910 {
911 int ret;
912 s32 value = 0;
913
914 struct ec_sensors_data *state = dev_get_drvdata(dev);
915 int sidx = find_ec_sensor_index(state, type, channel);
916
917 if (sidx < 0) {
918 return sidx;
919 }
920
921 ret = get_cached_value_or_update(dev, sidx, state, &value);
922 if (!ret) {
923 *val = scale_sensor_value(value,
924 get_sensor_info(state, sidx)->type);
925 }
926
927 return ret;
928 }
929
asus_ec_hwmon_read_string(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,const char ** str)930 static int asus_ec_hwmon_read_string(struct device *dev,
931 enum hwmon_sensor_types type, u32 attr,
932 int channel, const char **str)
933 {
934 struct ec_sensors_data *state = dev_get_drvdata(dev);
935 int sensor_index = find_ec_sensor_index(state, type, channel);
936 *str = get_sensor_info(state, sensor_index)->label;
937
938 return 0;
939 }
940
asus_ec_hwmon_is_visible(const void * drvdata,enum hwmon_sensor_types type,u32 attr,int channel)941 static umode_t asus_ec_hwmon_is_visible(const void *drvdata,
942 enum hwmon_sensor_types type, u32 attr,
943 int channel)
944 {
945 const struct ec_sensors_data *state = drvdata;
946
947 return find_ec_sensor_index(state, type, channel) >= 0 ? S_IRUGO : 0;
948 }
949
950 static int
asus_ec_hwmon_add_chan_info(struct hwmon_channel_info * asus_ec_hwmon_chan,struct device * dev,int num,enum hwmon_sensor_types type,u32 config)951 asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan,
952 struct device *dev, int num,
953 enum hwmon_sensor_types type, u32 config)
954 {
955 int i;
956 u32 *cfg = devm_kcalloc(dev, num + 1, sizeof(*cfg), GFP_KERNEL);
957
958 if (!cfg)
959 return -ENOMEM;
960
961 asus_ec_hwmon_chan->type = type;
962 asus_ec_hwmon_chan->config = cfg;
963 for (i = 0; i < num; i++, cfg++)
964 *cfg = config;
965
966 return 0;
967 }
968
969 static const struct hwmon_ops asus_ec_hwmon_ops = {
970 .is_visible = asus_ec_hwmon_is_visible,
971 .read = asus_ec_hwmon_read,
972 .read_string = asus_ec_hwmon_read_string,
973 };
974
975 static struct hwmon_chip_info asus_ec_chip_info = {
976 .ops = &asus_ec_hwmon_ops,
977 };
978
get_board_info(void)979 static const struct ec_board_info *get_board_info(void)
980 {
981 const struct dmi_system_id *dmi_entry;
982
983 dmi_entry = dmi_first_match(dmi_table);
984 return dmi_entry ? dmi_entry->driver_data : NULL;
985 }
986
asus_ec_probe(struct platform_device * pdev)987 static int asus_ec_probe(struct platform_device *pdev)
988 {
989 const struct hwmon_channel_info **ptr_asus_ec_ci;
990 int nr_count[hwmon_max] = { 0 }, nr_types = 0;
991 struct hwmon_channel_info *asus_ec_hwmon_chan;
992 const struct ec_board_info *pboard_info;
993 const struct hwmon_chip_info *chip_info;
994 struct device *dev = &pdev->dev;
995 struct ec_sensors_data *ec_data;
996 const struct ec_sensor_info *si;
997 enum hwmon_sensor_types type;
998 struct device *hwdev;
999 unsigned int i;
1000 int status;
1001
1002 pboard_info = get_board_info();
1003 if (!pboard_info)
1004 return -ENODEV;
1005
1006 ec_data = devm_kzalloc(dev, sizeof(struct ec_sensors_data),
1007 GFP_KERNEL);
1008 if (!ec_data)
1009 return -ENOMEM;
1010
1011 dev_set_drvdata(dev, ec_data);
1012 ec_data->board_info = pboard_info;
1013
1014 switch (ec_data->board_info->family) {
1015 case family_amd_400_series:
1016 ec_data->sensors_info = sensors_family_amd_400;
1017 break;
1018 case family_amd_500_series:
1019 ec_data->sensors_info = sensors_family_amd_500;
1020 break;
1021 case family_amd_600_series:
1022 ec_data->sensors_info = sensors_family_amd_600;
1023 break;
1024 case family_intel_300_series:
1025 ec_data->sensors_info = sensors_family_intel_300;
1026 break;
1027 case family_intel_600_series:
1028 ec_data->sensors_info = sensors_family_intel_600;
1029 break;
1030 default:
1031 dev_err(dev, "Unknown board family: %d",
1032 ec_data->board_info->family);
1033 return -EINVAL;
1034 }
1035
1036 ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors);
1037 ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors,
1038 sizeof(struct ec_sensor), GFP_KERNEL);
1039 if (!ec_data->sensors)
1040 return -ENOMEM;
1041
1042 status = setup_lock_data(dev);
1043 if (status) {
1044 dev_err(dev, "Failed to setup state/EC locking: %d", status);
1045 return status;
1046 }
1047
1048 setup_sensor_data(ec_data);
1049 ec_data->registers = devm_kcalloc(dev, ec_data->nr_registers,
1050 sizeof(u16), GFP_KERNEL);
1051 ec_data->read_buffer = devm_kcalloc(dev, ec_data->nr_registers,
1052 sizeof(u8), GFP_KERNEL);
1053
1054 if (!ec_data->registers || !ec_data->read_buffer)
1055 return -ENOMEM;
1056
1057 fill_ec_registers(ec_data);
1058
1059 for (i = 0; i < ec_data->nr_sensors; ++i) {
1060 si = get_sensor_info(ec_data, i);
1061 if (!nr_count[si->type])
1062 ++nr_types;
1063 ++nr_count[si->type];
1064 }
1065
1066 if (nr_count[hwmon_temp])
1067 nr_count[hwmon_chip]++, nr_types++;
1068
1069 asus_ec_hwmon_chan = devm_kcalloc(
1070 dev, nr_types, sizeof(*asus_ec_hwmon_chan), GFP_KERNEL);
1071 if (!asus_ec_hwmon_chan)
1072 return -ENOMEM;
1073
1074 ptr_asus_ec_ci = devm_kcalloc(dev, nr_types + 1,
1075 sizeof(*ptr_asus_ec_ci), GFP_KERNEL);
1076 if (!ptr_asus_ec_ci)
1077 return -ENOMEM;
1078
1079 asus_ec_chip_info.info = ptr_asus_ec_ci;
1080 chip_info = &asus_ec_chip_info;
1081
1082 for (type = 0; type < hwmon_max; ++type) {
1083 if (!nr_count[type])
1084 continue;
1085
1086 asus_ec_hwmon_add_chan_info(asus_ec_hwmon_chan, dev,
1087 nr_count[type], type,
1088 hwmon_attributes[type]);
1089 *ptr_asus_ec_ci++ = asus_ec_hwmon_chan++;
1090 }
1091
1092 dev_info(dev, "board has %d EC sensors that span %d registers",
1093 ec_data->nr_sensors, ec_data->nr_registers);
1094
1095 hwdev = devm_hwmon_device_register_with_info(dev, "asusec",
1096 ec_data, chip_info, NULL);
1097
1098 return PTR_ERR_OR_ZERO(hwdev);
1099 }
1100
1101 MODULE_DEVICE_TABLE(dmi, dmi_table);
1102
1103 static struct platform_driver asus_ec_sensors_platform_driver = {
1104 .driver = {
1105 .name = "asus-ec-sensors",
1106 },
1107 .probe = asus_ec_probe,
1108 };
1109
1110 static struct platform_device *asus_ec_sensors_platform_device;
1111
asus_ec_init(void)1112 static int __init asus_ec_init(void)
1113 {
1114 asus_ec_sensors_platform_device =
1115 platform_create_bundle(&asus_ec_sensors_platform_driver,
1116 asus_ec_probe, NULL, 0, NULL, 0);
1117
1118 if (IS_ERR(asus_ec_sensors_platform_device))
1119 return PTR_ERR(asus_ec_sensors_platform_device);
1120
1121 return 0;
1122 }
1123
asus_ec_exit(void)1124 static void __exit asus_ec_exit(void)
1125 {
1126 platform_device_unregister(asus_ec_sensors_platform_device);
1127 platform_driver_unregister(&asus_ec_sensors_platform_driver);
1128 }
1129
1130 module_init(asus_ec_init);
1131 module_exit(asus_ec_exit);
1132
1133 module_param_named(mutex_path, mutex_path_override, charp, 0);
1134 MODULE_PARM_DESC(mutex_path,
1135 "Override ACPI mutex path used to guard access to hardware");
1136
1137 MODULE_AUTHOR("Eugene Shalygin <eugene.shalygin@gmail.com>");
1138 MODULE_DESCRIPTION(
1139 "HWMON driver for sensors accessible via ACPI EC in ASUS motherboards");
1140 MODULE_LICENSE("GPL");
1141