Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only OR MIT
2/*
3 * Apple SMC hwmon driver for Apple Silicon platforms
4 *
5 * The System Management Controller on Apple Silicon devices is responsible for
6 * measuring data from sensors across the SoC and machine. These include power,
7 * temperature, voltage and current sensors. Some "sensors" actually expose
8 * derived values. An example of this is the key PHPC, which is an estimate
9 * of the heat energy being dissipated by the SoC.
10 *
11 * While each SoC only has one SMC variant, each platform exposes a different
12 * set of sensors. For example, M1 MacBooks expose battery telemetry sensors
13 * which are not present on the M1 Mac mini. For this reason, the available
14 * sensors for a given platform are described in the device tree in a child
15 * node of the SMC device. We must walk this list of available sensors and
16 * populate the required hwmon data structures at runtime.
17 *
18 * Originally based on a concept by Jean-Francois Bortolotti <jeff@borto.fr>
19 *
20 * Copyright The Asahi Linux Contributors
21 */
22
23#include <linux/bitfield.h>
24#include <linux/hwmon.h>
25#include <linux/mfd/macsmc.h>
26#include <linux/module.h>
27#include <linux/of.h>
28#include <linux/platform_device.h>
29
30#define MAX_LABEL_LENGTH 32
31
32/* Temperature, voltage, current, power, fan(s) */
33#define NUM_SENSOR_TYPES 5
34
35#define FLT_EXP_BIAS 127
36#define FLT_EXP_MASK GENMASK(30, 23)
37#define FLT_MANT_BIAS 23
38#define FLT_MANT_MASK GENMASK(22, 0)
39#define FLT_SIGN_MASK BIT(31)
40
41static bool fan_control;
42module_param_unsafe(fan_control, bool, 0644);
43MODULE_PARM_DESC(fan_control,
44 "Override the SMC to set your own fan speeds on supported machines");
45
46struct macsmc_hwmon_sensor {
47 struct apple_smc_key_info info;
48 smc_key macsmc_key;
49 char label[MAX_LABEL_LENGTH];
50 u32 attrs;
51};
52
53struct macsmc_hwmon_fan {
54 struct macsmc_hwmon_sensor now;
55 struct macsmc_hwmon_sensor min;
56 struct macsmc_hwmon_sensor max;
57 struct macsmc_hwmon_sensor set;
58 struct macsmc_hwmon_sensor mode;
59 char label[MAX_LABEL_LENGTH];
60 u32 attrs;
61 bool manual;
62};
63
64struct macsmc_hwmon_sensors {
65 struct hwmon_channel_info channel_info;
66 struct macsmc_hwmon_sensor *sensors;
67 u32 count;
68};
69
70struct macsmc_hwmon_fans {
71 struct hwmon_channel_info channel_info;
72 struct macsmc_hwmon_fan *fans;
73 u32 count;
74};
75
76struct macsmc_hwmon {
77 struct device *dev;
78 struct apple_smc *smc;
79 struct device *hwmon_dev;
80 struct hwmon_chip_info chip_info;
81 /* Chip + sensor types + NULL */
82 const struct hwmon_channel_info *channel_infos[1 + NUM_SENSOR_TYPES + 1];
83 struct macsmc_hwmon_sensors temp;
84 struct macsmc_hwmon_sensors volt;
85 struct macsmc_hwmon_sensors curr;
86 struct macsmc_hwmon_sensors power;
87 struct macsmc_hwmon_fans fan;
88};
89
90static int macsmc_hwmon_read_label(struct device *dev,
91 enum hwmon_sensor_types type, u32 attr,
92 int channel, const char **str)
93{
94 struct macsmc_hwmon *hwmon = dev_get_drvdata(dev);
95
96 switch (type) {
97 case hwmon_temp:
98 *str = hwmon->temp.sensors[channel].label;
99 break;
100 case hwmon_in:
101 *str = hwmon->volt.sensors[channel].label;
102 break;
103 case hwmon_curr:
104 *str = hwmon->curr.sensors[channel].label;
105 break;
106 case hwmon_power:
107 *str = hwmon->power.sensors[channel].label;
108 break;
109 case hwmon_fan:
110 *str = hwmon->fan.fans[channel].label;
111 break;
112 default:
113 return -EOPNOTSUPP;
114 }
115
116 return 0;
117}
118
119/*
120 * A number of sensors report data in a 48.16 fixed-point decimal format that is
121 * not used by any other function of the SMC.
122 */
123static int macsmc_hwmon_read_ioft_scaled(struct apple_smc *smc, smc_key key,
124 u64 *p, int scale)
125{
126 u64 val;
127 int ret;
128
129 ret = apple_smc_read_u64(smc, key, &val);
130 if (ret < 0)
131 return ret;
132
133 *p = mult_frac(val, scale, 65536);
134
135 return 0;
136}
137
138/*
139 * Many sensors report their data as IEEE-754 floats. No other SMC function uses
140 * them.
141 */
142static int macsmc_hwmon_read_f32_scaled(struct apple_smc *smc, smc_key key,
143 int *p, int scale)
144{
145 u32 fval;
146 u64 val;
147 int ret, exp;
148
149 ret = apple_smc_read_u32(smc, key, &fval);
150 if (ret < 0)
151 return ret;
152
153 val = ((u64)((fval & FLT_MANT_MASK) | BIT(23)));
154 exp = ((fval >> 23) & 0xff) - FLT_EXP_BIAS - FLT_MANT_BIAS;
155
156 /* We never have negatively scaled SMC floats */
157 val *= scale;
158
159 if (exp > 63)
160 val = U64_MAX;
161 else if (exp < -63)
162 val = 0;
163 else if (exp < 0)
164 val >>= -exp;
165 else if (exp != 0 && (val & ~((1UL << (64 - exp)) - 1))) /* overflow */
166 val = U64_MAX;
167 else
168 val <<= exp;
169
170 if (fval & FLT_SIGN_MASK) {
171 if (val > (-(s64)INT_MIN))
172 *p = INT_MIN;
173 else
174 *p = -val;
175 } else {
176 if (val > INT_MAX)
177 *p = INT_MAX;
178 else
179 *p = val;
180 }
181
182 return 0;
183}
184
185/*
186 * The SMC has keys of multiple types, denoted by a FourCC of the same format
187 * as the key ID. We don't know what data type a key encodes until we poke at it.
188 */
189static int macsmc_hwmon_read_key(struct apple_smc *smc,
190 struct macsmc_hwmon_sensor *sensor, int scale,
191 long *val)
192{
193 int ret;
194
195 switch (sensor->info.type_code) {
196 /* 32-bit IEEE 754 float */
197 case __SMC_KEY('f', 'l', 't', ' '): {
198 u32 flt_ = 0;
199
200 ret = macsmc_hwmon_read_f32_scaled(smc, sensor->macsmc_key,
201 &flt_, scale);
202 if (ret)
203 return ret;
204
205 *val = flt_;
206 break;
207 }
208 /* 48.16 fixed point decimal */
209 case __SMC_KEY('i', 'o', 'f', 't'): {
210 u64 ioft = 0;
211
212 ret = macsmc_hwmon_read_ioft_scaled(smc, sensor->macsmc_key,
213 &ioft, scale);
214 if (ret)
215 return ret;
216
217 *val = (long)ioft;
218 break;
219 }
220 default:
221 return -EOPNOTSUPP;
222 }
223
224 return 0;
225}
226
227static int macsmc_hwmon_write_f32(struct apple_smc *smc, smc_key key, int value)
228{
229 u64 val;
230 u32 fval = 0;
231 int exp = 0, neg;
232
233 val = abs(value);
234 neg = val != value;
235
236 if (val) {
237 int msb = __fls(val) - exp;
238
239 if (msb > 23) {
240 val >>= msb - FLT_MANT_BIAS;
241 exp -= msb - FLT_MANT_BIAS;
242 } else if (msb < 23) {
243 val <<= FLT_MANT_BIAS - msb;
244 exp += msb;
245 }
246
247 fval = FIELD_PREP(FLT_SIGN_MASK, neg) |
248 FIELD_PREP(FLT_EXP_MASK, exp + FLT_EXP_BIAS) |
249 FIELD_PREP(FLT_MANT_MASK, val);
250 }
251
252 return apple_smc_write_u32(smc, key, fval);
253}
254
255static int macsmc_hwmon_write_key(struct apple_smc *smc,
256 struct macsmc_hwmon_sensor *sensor, long val)
257{
258 switch (sensor->info.type_code) {
259 /* 32-bit IEEE 754 float */
260 case __SMC_KEY('f', 'l', 't', ' '):
261 return macsmc_hwmon_write_f32(smc, sensor->macsmc_key, val);
262 /* unsigned 8-bit integer */
263 case __SMC_KEY('u', 'i', '8', ' '):
264 return apple_smc_write_u8(smc, sensor->macsmc_key, val);
265 default:
266 return -EOPNOTSUPP;
267 }
268}
269
270static int macsmc_hwmon_read_fan(struct macsmc_hwmon *hwmon, u32 attr, int chan,
271 long *val)
272{
273 switch (attr) {
274 case hwmon_fan_input:
275 return macsmc_hwmon_read_key(hwmon->smc,
276 &hwmon->fan.fans[chan].now, 1, val);
277 case hwmon_fan_min:
278 return macsmc_hwmon_read_key(hwmon->smc,
279 &hwmon->fan.fans[chan].min, 1, val);
280 case hwmon_fan_max:
281 return macsmc_hwmon_read_key(hwmon->smc,
282 &hwmon->fan.fans[chan].max, 1, val);
283 case hwmon_fan_target:
284 return macsmc_hwmon_read_key(hwmon->smc,
285 &hwmon->fan.fans[chan].set, 1, val);
286 default:
287 return -EOPNOTSUPP;
288 }
289}
290
291static int macsmc_hwmon_write_fan(struct device *dev, u32 attr, int channel,
292 long val)
293{
294 struct macsmc_hwmon *hwmon = dev_get_drvdata(dev);
295 long min, max;
296 int ret;
297
298 if (!fan_control || hwmon->fan.fans[channel].mode.macsmc_key == 0)
299 return -EOPNOTSUPP;
300
301 /*
302 * The SMC does no sanity checks on requested fan speeds, so we need to.
303 */
304 ret = macsmc_hwmon_read_key(hwmon->smc, &hwmon->fan.fans[channel].min,
305 1, &min);
306 if (ret)
307 return ret;
308
309 ret = macsmc_hwmon_read_key(hwmon->smc, &hwmon->fan.fans[channel].max,
310 1, &max);
311 if (ret)
312 return ret;
313
314 if (val >= min && val <= max) {
315 if (!hwmon->fan.fans[channel].manual) {
316 /* Write 1 to mode key for manual control */
317 ret = macsmc_hwmon_write_key(hwmon->smc,
318 &hwmon->fan.fans[channel].mode, 1);
319 if (ret < 0)
320 return ret;
321
322 hwmon->fan.fans[channel].manual = true;
323 }
324 return macsmc_hwmon_write_key(hwmon->smc,
325 &hwmon->fan.fans[channel].set, val);
326 } else if (!val) {
327 if (hwmon->fan.fans[channel].manual) {
328 ret = macsmc_hwmon_write_key(hwmon->smc,
329 &hwmon->fan.fans[channel].mode, 0);
330 if (ret < 0)
331 return ret;
332
333 hwmon->fan.fans[channel].manual = false;
334 }
335 } else {
336 return -EINVAL;
337 }
338
339 return 0;
340}
341
342static int macsmc_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
343 u32 attr, int channel, long *val)
344{
345 struct macsmc_hwmon *hwmon = dev_get_drvdata(dev);
346 int ret = 0;
347
348 switch (type) {
349 case hwmon_temp:
350 ret = macsmc_hwmon_read_key(hwmon->smc,
351 &hwmon->temp.sensors[channel], 1000, val);
352 break;
353 case hwmon_in:
354 ret = macsmc_hwmon_read_key(hwmon->smc,
355 &hwmon->volt.sensors[channel], 1000, val);
356 break;
357 case hwmon_curr:
358 ret = macsmc_hwmon_read_key(hwmon->smc,
359 &hwmon->curr.sensors[channel], 1000, val);
360 break;
361 case hwmon_power:
362 /* SMC returns power in Watts with acceptable precision to scale to uW */
363 ret = macsmc_hwmon_read_key(hwmon->smc,
364 &hwmon->power.sensors[channel],
365 1000000, val);
366 break;
367 case hwmon_fan:
368 ret = macsmc_hwmon_read_fan(hwmon, attr, channel, val);
369 break;
370 default:
371 return -EOPNOTSUPP;
372 }
373
374 return ret;
375}
376
377static int macsmc_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
378 u32 attr, int channel, long val)
379{
380 switch (type) {
381 case hwmon_fan:
382 return macsmc_hwmon_write_fan(dev, attr, channel, val);
383 default:
384 return -EOPNOTSUPP;
385 }
386}
387
388static umode_t macsmc_hwmon_fan_is_visible(const struct macsmc_hwmon_fan *fan,
389 u32 attr)
390{
391 if (fan->attrs & BIT(attr)) {
392 if (attr == hwmon_fan_target && fan_control && fan->mode.macsmc_key)
393 return 0644;
394
395 return 0444;
396 }
397
398 return 0;
399}
400
401static umode_t macsmc_hwmon_is_visible(const void *data,
402 enum hwmon_sensor_types type, u32 attr,
403 int channel)
404{
405 const struct macsmc_hwmon *hwmon = data;
406 struct macsmc_hwmon_sensor *sensor;
407
408 switch (type) {
409 case hwmon_in:
410 sensor = &hwmon->volt.sensors[channel];
411 break;
412 case hwmon_curr:
413 sensor = &hwmon->curr.sensors[channel];
414 break;
415 case hwmon_power:
416 sensor = &hwmon->power.sensors[channel];
417 break;
418 case hwmon_temp:
419 sensor = &hwmon->temp.sensors[channel];
420 break;
421 case hwmon_fan:
422 return macsmc_hwmon_fan_is_visible(&hwmon->fan.fans[channel], attr);
423 default:
424 return 0;
425 }
426
427 /* Sensors only register ro attributes */
428 if (sensor->attrs & BIT(attr))
429 return 0444;
430
431 return 0;
432}
433
434static const struct hwmon_ops macsmc_hwmon_ops = {
435 .is_visible = macsmc_hwmon_is_visible,
436 .read = macsmc_hwmon_read,
437 .read_string = macsmc_hwmon_read_label,
438 .write = macsmc_hwmon_write,
439};
440
441/*
442 * Get the key metadata, including key data type, from the SMC.
443 */
444static int macsmc_hwmon_parse_key(struct device *dev, struct apple_smc *smc,
445 struct macsmc_hwmon_sensor *sensor,
446 const char *key)
447{
448 int ret;
449
450 ret = apple_smc_get_key_info(smc, _SMC_KEY(key), &sensor->info);
451 if (ret) {
452 dev_dbg(dev, "Failed to retrieve key info for %s\n", key);
453 return ret;
454 }
455
456 sensor->macsmc_key = _SMC_KEY(key);
457
458 return 0;
459}
460
461/*
462 * A sensor is a single key-value pair as made available by the SMC.
463 * The devicetree gives us the SMC key ID and a friendly name where the
464 * purpose of the sensor is known.
465 */
466static int macsmc_hwmon_create_sensor(struct device *dev, struct apple_smc *smc,
467 struct device_node *sensor_node,
468 struct macsmc_hwmon_sensor *sensor)
469{
470 const char *key, *label;
471 int ret;
472
473 ret = of_property_read_string(sensor_node, "apple,key-id", &key);
474 if (ret) {
475 dev_dbg(dev, "Could not find apple,key-id in sensor node\n");
476 return ret;
477 }
478
479 ret = macsmc_hwmon_parse_key(dev, smc, sensor, key);
480 if (ret)
481 return ret;
482
483 ret = of_property_read_string(sensor_node, "label", &label);
484 if (ret)
485 dev_dbg(dev, "No label found for sensor %s\n", key);
486 else
487 strscpy_pad(sensor->label, label, sizeof(sensor->label));
488
489 return 0;
490}
491
492/*
493 * Fan data is exposed by the SMC as multiple sensors.
494 *
495 * The devicetree schema reuses apple,key-id for the actual fan speed sensor.
496 * Min, max and target keys do not need labels, so we can reuse label
497 * for naming the entire fan.
498 */
499static int macsmc_hwmon_create_fan(struct device *dev, struct apple_smc *smc,
500 struct device_node *fan_node,
501 struct macsmc_hwmon_fan *fan)
502{
503 const char *label, *now, *min, *max, *set, *mode;
504 int ret;
505
506 ret = of_property_read_string(fan_node, "apple,key-id", &now);
507 if (ret) {
508 dev_err(dev, "apple,key-id not found in fan node!\n");
509 return ret;
510 }
511
512 ret = macsmc_hwmon_parse_key(dev, smc, &fan->now, now);
513 if (ret)
514 return ret;
515
516 fan->attrs = HWMON_F_INPUT;
517
518 ret = of_property_read_string(fan_node, "label", &label);
519 if (ret) {
520 dev_dbg(dev, "No label found for fan %s\n", now);
521 } else {
522 strscpy_pad(fan->label, label, sizeof(fan->label));
523 fan->attrs |= HWMON_F_LABEL;
524 }
525
526 /* The following keys are not required to simply monitor fan speed */
527 if (!of_property_read_string(fan_node, "apple,fan-minimum", &min)) {
528 ret = macsmc_hwmon_parse_key(dev, smc, &fan->min, min);
529 if (ret)
530 return ret;
531
532 fan->attrs |= HWMON_F_MIN;
533 }
534
535 if (!of_property_read_string(fan_node, "apple,fan-maximum", &max)) {
536 ret = macsmc_hwmon_parse_key(dev, smc, &fan->max, max);
537 if (ret)
538 return ret;
539
540 fan->attrs |= HWMON_F_MAX;
541 }
542
543 if (!of_property_read_string(fan_node, "apple,fan-target", &set)) {
544 ret = macsmc_hwmon_parse_key(dev, smc, &fan->set, set);
545 if (ret)
546 return ret;
547
548 fan->attrs |= HWMON_F_TARGET;
549 }
550
551 if (!of_property_read_string(fan_node, "apple,fan-mode", &mode)) {
552 ret = macsmc_hwmon_parse_key(dev, smc, &fan->mode, mode);
553 if (ret)
554 return ret;
555 }
556
557 /* Initialise fan control mode to automatic */
558 fan->manual = false;
559
560 return 0;
561}
562
563static int macsmc_hwmon_populate_sensors(struct macsmc_hwmon *hwmon,
564 struct device_node *hwmon_node)
565{
566 struct device_node *key_node __maybe_unused;
567 struct macsmc_hwmon_sensor *sensor;
568 u32 n_current = 0, n_fan = 0, n_power = 0, n_temperature = 0, n_voltage = 0;
569
570 for_each_child_of_node_with_prefix(hwmon_node, key_node, "current-") {
571 n_current++;
572 }
573
574 if (n_current) {
575 hwmon->curr.sensors = devm_kcalloc(hwmon->dev, n_current,
576 sizeof(struct macsmc_hwmon_sensor), GFP_KERNEL);
577 if (!hwmon->curr.sensors)
578 return -ENOMEM;
579
580 for_each_child_of_node_with_prefix(hwmon_node, key_node, "current-") {
581 sensor = &hwmon->curr.sensors[hwmon->curr.count];
582 if (!macsmc_hwmon_create_sensor(hwmon->dev, hwmon->smc, key_node, sensor)) {
583 sensor->attrs = HWMON_C_INPUT;
584
585 if (*sensor->label)
586 sensor->attrs |= HWMON_C_LABEL;
587
588 hwmon->curr.count++;
589 }
590 }
591 }
592
593 for_each_child_of_node_with_prefix(hwmon_node, key_node, "fan-") {
594 n_fan++;
595 }
596
597 if (n_fan) {
598 hwmon->fan.fans = devm_kcalloc(hwmon->dev, n_fan,
599 sizeof(struct macsmc_hwmon_fan), GFP_KERNEL);
600 if (!hwmon->fan.fans)
601 return -ENOMEM;
602
603 for_each_child_of_node_with_prefix(hwmon_node, key_node, "fan-") {
604 if (!macsmc_hwmon_create_fan(hwmon->dev, hwmon->smc, key_node,
605 &hwmon->fan.fans[hwmon->fan.count]))
606 hwmon->fan.count++;
607 }
608 }
609
610 for_each_child_of_node_with_prefix(hwmon_node, key_node, "power-") {
611 n_power++;
612 }
613
614 if (n_power) {
615 hwmon->power.sensors = devm_kcalloc(hwmon->dev, n_power,
616 sizeof(struct macsmc_hwmon_sensor), GFP_KERNEL);
617 if (!hwmon->power.sensors)
618 return -ENOMEM;
619
620 for_each_child_of_node_with_prefix(hwmon_node, key_node, "power-") {
621 sensor = &hwmon->power.sensors[hwmon->power.count];
622 if (!macsmc_hwmon_create_sensor(hwmon->dev, hwmon->smc, key_node, sensor)) {
623 sensor->attrs = HWMON_P_INPUT;
624
625 if (*sensor->label)
626 sensor->attrs |= HWMON_P_LABEL;
627
628 hwmon->power.count++;
629 }
630 }
631 }
632
633 for_each_child_of_node_with_prefix(hwmon_node, key_node, "temperature-") {
634 n_temperature++;
635 }
636
637 if (n_temperature) {
638 hwmon->temp.sensors = devm_kcalloc(hwmon->dev, n_temperature,
639 sizeof(struct macsmc_hwmon_sensor), GFP_KERNEL);
640 if (!hwmon->temp.sensors)
641 return -ENOMEM;
642
643 for_each_child_of_node_with_prefix(hwmon_node, key_node, "temperature-") {
644 sensor = &hwmon->temp.sensors[hwmon->temp.count];
645 if (!macsmc_hwmon_create_sensor(hwmon->dev, hwmon->smc, key_node, sensor)) {
646 sensor->attrs = HWMON_T_INPUT;
647
648 if (*sensor->label)
649 sensor->attrs |= HWMON_T_LABEL;
650
651 hwmon->temp.count++;
652 }
653 }
654 }
655
656 for_each_child_of_node_with_prefix(hwmon_node, key_node, "voltage-") {
657 n_voltage++;
658 }
659
660 if (n_voltage) {
661 hwmon->volt.sensors = devm_kcalloc(hwmon->dev, n_voltage,
662 sizeof(struct macsmc_hwmon_sensor), GFP_KERNEL);
663 if (!hwmon->volt.sensors)
664 return -ENOMEM;
665
666 for_each_child_of_node_with_prefix(hwmon_node, key_node, "volt-") {
667 sensor = &hwmon->temp.sensors[hwmon->temp.count];
668 if (!macsmc_hwmon_create_sensor(hwmon->dev, hwmon->smc, key_node, sensor)) {
669 sensor->attrs = HWMON_I_INPUT;
670
671 if (*sensor->label)
672 sensor->attrs |= HWMON_I_LABEL;
673
674 hwmon->volt.count++;
675 }
676 }
677 }
678
679 return 0;
680}
681
682/* Create NULL-terminated config arrays */
683static void macsmc_hwmon_populate_configs(u32 *configs, const struct macsmc_hwmon_sensors *sensors)
684{
685 int idx;
686
687 for (idx = 0; idx < sensors->count; idx++)
688 configs[idx] = sensors->sensors[idx].attrs;
689}
690
691static void macsmc_hwmon_populate_fan_configs(u32 *configs, const struct macsmc_hwmon_fans *fans)
692{
693 int idx;
694
695 for (idx = 0; idx < fans->count; idx++)
696 configs[idx] = fans->fans[idx].attrs;
697}
698
699static const struct hwmon_channel_info *const macsmc_chip_channel_info =
700 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ);
701
702static int macsmc_hwmon_create_infos(struct macsmc_hwmon *hwmon)
703{
704 struct hwmon_channel_info *channel_info;
705 int i = 0;
706
707 /* chip */
708 hwmon->channel_infos[i++] = macsmc_chip_channel_info;
709
710 if (hwmon->curr.count) {
711 channel_info = &hwmon->curr.channel_info;
712 channel_info->type = hwmon_curr;
713 channel_info->config = devm_kcalloc(hwmon->dev, hwmon->curr.count + 1,
714 sizeof(u32), GFP_KERNEL);
715 if (!channel_info->config)
716 return -ENOMEM;
717
718 macsmc_hwmon_populate_configs((u32 *)channel_info->config, &hwmon->curr);
719 hwmon->channel_infos[i++] = channel_info;
720 }
721
722 if (hwmon->fan.count) {
723 channel_info = &hwmon->fan.channel_info;
724 channel_info->type = hwmon_fan;
725 channel_info->config = devm_kcalloc(hwmon->dev, hwmon->fan.count + 1,
726 sizeof(u32), GFP_KERNEL);
727 if (!channel_info->config)
728 return -ENOMEM;
729
730 macsmc_hwmon_populate_fan_configs((u32 *)channel_info->config, &hwmon->fan);
731 hwmon->channel_infos[i++] = channel_info;
732 }
733
734 if (hwmon->power.count) {
735 channel_info = &hwmon->power.channel_info;
736 channel_info->type = hwmon_power;
737 channel_info->config = devm_kcalloc(hwmon->dev, hwmon->power.count + 1,
738 sizeof(u32), GFP_KERNEL);
739 if (!channel_info->config)
740 return -ENOMEM;
741
742 macsmc_hwmon_populate_configs((u32 *)channel_info->config, &hwmon->power);
743 hwmon->channel_infos[i++] = channel_info;
744 }
745
746 if (hwmon->temp.count) {
747 channel_info = &hwmon->temp.channel_info;
748 channel_info->type = hwmon_temp;
749 channel_info->config = devm_kcalloc(hwmon->dev, hwmon->temp.count + 1,
750 sizeof(u32), GFP_KERNEL);
751 if (!channel_info->config)
752 return -ENOMEM;
753
754 macsmc_hwmon_populate_configs((u32 *)channel_info->config, &hwmon->temp);
755 hwmon->channel_infos[i++] = channel_info;
756 }
757
758 if (hwmon->volt.count) {
759 channel_info = &hwmon->volt.channel_info;
760 channel_info->type = hwmon_in;
761 channel_info->config = devm_kcalloc(hwmon->dev, hwmon->volt.count + 1,
762 sizeof(u32), GFP_KERNEL);
763 if (!channel_info->config)
764 return -ENOMEM;
765
766 macsmc_hwmon_populate_configs((u32 *)channel_info->config, &hwmon->volt);
767 hwmon->channel_infos[i++] = channel_info;
768 }
769
770 return 0;
771}
772
773static int macsmc_hwmon_probe(struct platform_device *pdev)
774{
775 struct apple_smc *smc = dev_get_drvdata(pdev->dev.parent);
776 struct macsmc_hwmon *hwmon;
777 int ret;
778
779 /*
780 * The MFD driver will try to probe us unconditionally. Some devices
781 * with the SMC do not have hwmon capabilities. Only probe if we have
782 * a hwmon node.
783 */
784 if (!pdev->dev.of_node)
785 return -ENODEV;
786
787 hwmon = devm_kzalloc(&pdev->dev, sizeof(*hwmon),
788 GFP_KERNEL);
789 if (!hwmon)
790 return -ENOMEM;
791
792 hwmon->dev = &pdev->dev;
793 hwmon->smc = smc;
794
795 ret = macsmc_hwmon_populate_sensors(hwmon, hwmon->dev->of_node);
796 if (ret) {
797 dev_err(hwmon->dev, "Could not parse sensors\n");
798 return ret;
799 }
800
801 if (!hwmon->curr.count && !hwmon->fan.count &&
802 !hwmon->power.count && !hwmon->temp.count &&
803 !hwmon->volt.count) {
804 dev_err(hwmon->dev,
805 "No valid sensors found of any supported type\n");
806 return -ENODEV;
807 }
808
809 ret = macsmc_hwmon_create_infos(hwmon);
810 if (ret)
811 return ret;
812
813 hwmon->chip_info.ops = &macsmc_hwmon_ops;
814 hwmon->chip_info.info =
815 (const struct hwmon_channel_info *const *)&hwmon->channel_infos;
816
817 hwmon->hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
818 "macsmc_hwmon", hwmon,
819 &hwmon->chip_info, NULL);
820 if (IS_ERR(hwmon->hwmon_dev))
821 return dev_err_probe(hwmon->dev, PTR_ERR(hwmon->hwmon_dev),
822 "Probing SMC hwmon device failed\n");
823
824 dev_dbg(hwmon->dev, "Registered SMC hwmon device. Sensors:\n");
825 dev_dbg(hwmon->dev,
826 "Current: %d, Fans: %d, Power: %d, Temperature: %d, Voltage: %d",
827 hwmon->curr.count, hwmon->fan.count,
828 hwmon->power.count, hwmon->temp.count,
829 hwmon->volt.count);
830
831 return 0;
832}
833
834static const struct of_device_id macsmc_hwmon_of_table[] = {
835 { .compatible = "apple,smc-hwmon" },
836 {}
837};
838MODULE_DEVICE_TABLE(of, macsmc_hwmon_of_table);
839
840static struct platform_driver macsmc_hwmon_driver = {
841 .probe = macsmc_hwmon_probe,
842 .driver = {
843 .name = "macsmc-hwmon",
844 .of_match_table = macsmc_hwmon_of_table,
845 },
846};
847module_platform_driver(macsmc_hwmon_driver);
848
849MODULE_DESCRIPTION("Apple Silicon SMC hwmon driver");
850MODULE_AUTHOR("James Calligeros <jcalligeros99@gmail.com>");
851MODULE_LICENSE("Dual MIT/GPL");