1
2
3
4
5
6
7
8
9
10
11
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/capability.h>
16#include <linux/cpu.h>
17#include <linux/ctype.h>
18#include <linux/delay.h>
19#include <linux/dmi.h>
20#include <linux/err.h>
21#include <linux/errno.h>
22#include <linux/hwmon.h>
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/mutex.h>
26#include <linux/platform_device.h>
27#include <linux/proc_fs.h>
28#include <linux/seq_file.h>
29#include <linux/string.h>
30#include <linux/smp.h>
31#include <linux/types.h>
32#include <linux/uaccess.h>
33
34#include <linux/i8k.h>
35
36#define I8K_SMM_FN_STATUS 0x0025
37#define I8K_SMM_POWER_STATUS 0x0069
38#define I8K_SMM_SET_FAN 0x01a3
39#define I8K_SMM_GET_FAN 0x00a3
40#define I8K_SMM_GET_SPEED 0x02a3
41#define I8K_SMM_GET_FAN_TYPE 0x03a3
42#define I8K_SMM_GET_NOM_SPEED 0x04a3
43#define I8K_SMM_GET_TEMP 0x10a3
44#define I8K_SMM_GET_TEMP_TYPE 0x11a3
45#define I8K_SMM_GET_DELL_SIG1 0xfea3
46#define I8K_SMM_GET_DELL_SIG2 0xffa3
47
48#define I8K_FAN_MULT 30
49#define I8K_FAN_MAX_RPM 30000
50#define I8K_MAX_TEMP 127
51
52#define I8K_FN_NONE 0x00
53#define I8K_FN_UP 0x01
54#define I8K_FN_DOWN 0x02
55#define I8K_FN_MUTE 0x04
56#define I8K_FN_MASK 0x07
57#define I8K_FN_SHIFT 8
58
59#define I8K_POWER_AC 0x05
60#define I8K_POWER_BATTERY 0x01
61
62#define DELL_SMM_NO_TEMP 10
63#define DELL_SMM_NO_FANS 3
64
65struct dell_smm_data {
66 struct mutex i8k_mutex;
67 char bios_version[4];
68 char bios_machineid[16];
69 uint i8k_fan_mult;
70 uint i8k_pwm_mult;
71 uint i8k_fan_max;
72 bool disallow_fan_type_call;
73 bool disallow_fan_support;
74 unsigned int manual_fan;
75 unsigned int auto_fan;
76 int temp_type[DELL_SMM_NO_TEMP];
77 bool fan[DELL_SMM_NO_FANS];
78 int fan_type[DELL_SMM_NO_FANS];
79 int *fan_nominal_speed[DELL_SMM_NO_FANS];
80};
81
82MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
83MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");
84MODULE_DESCRIPTION("Dell laptop SMM BIOS hwmon driver");
85MODULE_LICENSE("GPL");
86MODULE_ALIAS("i8k");
87
88static bool force;
89module_param(force, bool, 0);
90MODULE_PARM_DESC(force, "Force loading without checking for supported models");
91
92static bool ignore_dmi;
93module_param(ignore_dmi, bool, 0);
94MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
95
96#if IS_ENABLED(CONFIG_I8K)
97static bool restricted = true;
98module_param(restricted, bool, 0);
99MODULE_PARM_DESC(restricted, "Restrict fan control and serial number to CAP_SYS_ADMIN (default: 1)");
100
101static bool power_status;
102module_param(power_status, bool, 0600);
103MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k (default: 0)");
104#endif
105
106static uint fan_mult;
107module_param(fan_mult, uint, 0);
108MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with (default: autodetect)");
109
110static uint fan_max;
111module_param(fan_max, uint, 0);
112MODULE_PARM_DESC(fan_max, "Maximum configurable fan speed (default: autodetect)");
113
114struct smm_regs {
115 unsigned int eax;
116 unsigned int ebx __packed;
117 unsigned int ecx __packed;
118 unsigned int edx __packed;
119 unsigned int esi __packed;
120 unsigned int edi __packed;
121};
122
123static const char * const temp_labels[] = {
124 "CPU",
125 "GPU",
126 "SODIMM",
127 "Other",
128 "Ambient",
129 "Other",
130};
131
132static const char * const fan_labels[] = {
133 "Processor Fan",
134 "Motherboard Fan",
135 "Video Fan",
136 "Power Supply Fan",
137 "Chipset Fan",
138 "Other Fan",
139};
140
141static const char * const docking_labels[] = {
142 "Docking Processor Fan",
143 "Docking Motherboard Fan",
144 "Docking Video Fan",
145 "Docking Power Supply Fan",
146 "Docking Chipset Fan",
147 "Docking Other Fan",
148};
149
150static inline const char __init *i8k_get_dmi_data(int field)
151{
152 const char *dmi_data = dmi_get_system_info(field);
153
154 return dmi_data && *dmi_data ? dmi_data : "?";
155}
156
157
158
159
160static int i8k_smm_func(void *par)
161{
162 ktime_t calltime = ktime_get();
163 struct smm_regs *regs = par;
164 int eax = regs->eax;
165 int ebx = regs->ebx;
166 long long duration;
167 int rc;
168
169
170 if (smp_processor_id() != 0)
171 return -EBUSY;
172
173#if defined(CONFIG_X86_64)
174 asm volatile("pushq %%rax\n\t"
175 "movl 0(%%rax),%%edx\n\t"
176 "pushq %%rdx\n\t"
177 "movl 4(%%rax),%%ebx\n\t"
178 "movl 8(%%rax),%%ecx\n\t"
179 "movl 12(%%rax),%%edx\n\t"
180 "movl 16(%%rax),%%esi\n\t"
181 "movl 20(%%rax),%%edi\n\t"
182 "popq %%rax\n\t"
183 "out %%al,$0xb2\n\t"
184 "out %%al,$0x84\n\t"
185 "xchgq %%rax,(%%rsp)\n\t"
186 "movl %%ebx,4(%%rax)\n\t"
187 "movl %%ecx,8(%%rax)\n\t"
188 "movl %%edx,12(%%rax)\n\t"
189 "movl %%esi,16(%%rax)\n\t"
190 "movl %%edi,20(%%rax)\n\t"
191 "popq %%rdx\n\t"
192 "movl %%edx,0(%%rax)\n\t"
193 "pushfq\n\t"
194 "popq %%rax\n\t"
195 "andl $1,%%eax\n"
196 : "=a"(rc)
197 : "a"(regs)
198 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
199#else
200 asm volatile("pushl %%eax\n\t"
201 "movl 0(%%eax),%%edx\n\t"
202 "push %%edx\n\t"
203 "movl 4(%%eax),%%ebx\n\t"
204 "movl 8(%%eax),%%ecx\n\t"
205 "movl 12(%%eax),%%edx\n\t"
206 "movl 16(%%eax),%%esi\n\t"
207 "movl 20(%%eax),%%edi\n\t"
208 "popl %%eax\n\t"
209 "out %%al,$0xb2\n\t"
210 "out %%al,$0x84\n\t"
211 "xchgl %%eax,(%%esp)\n\t"
212 "movl %%ebx,4(%%eax)\n\t"
213 "movl %%ecx,8(%%eax)\n\t"
214 "movl %%edx,12(%%eax)\n\t"
215 "movl %%esi,16(%%eax)\n\t"
216 "movl %%edi,20(%%eax)\n\t"
217 "popl %%edx\n\t"
218 "movl %%edx,0(%%eax)\n\t"
219 "lahf\n\t"
220 "shrl $8,%%eax\n\t"
221 "andl $1,%%eax\n"
222 : "=a"(rc)
223 : "a"(regs)
224 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
225#endif
226 if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
227 rc = -EINVAL;
228
229 duration = ktime_us_delta(ktime_get(), calltime);
230 pr_debug("smm(0x%.4x 0x%.4x) = 0x%.4x (took %7lld usecs)\n", eax, ebx,
231 (rc ? 0xffff : regs->eax & 0xffff), duration);
232
233 return rc;
234}
235
236
237
238
239static int i8k_smm(struct smm_regs *regs)
240{
241 int ret;
242
243 cpus_read_lock();
244 ret = smp_call_on_cpu(0, i8k_smm_func, regs, true);
245 cpus_read_unlock();
246
247 return ret;
248}
249
250
251
252
253static int i8k_get_fan_status(const struct dell_smm_data *data, int fan)
254{
255 struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
256
257 if (data->disallow_fan_support)
258 return -EINVAL;
259
260 regs.ebx = fan & 0xff;
261 return i8k_smm(®s) ? : regs.eax & 0xff;
262}
263
264
265
266
267static int i8k_get_fan_speed(const struct dell_smm_data *data, int fan)
268{
269 struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
270
271 if (data->disallow_fan_support)
272 return -EINVAL;
273
274 regs.ebx = fan & 0xff;
275 return i8k_smm(®s) ? : (regs.eax & 0xffff) * data->i8k_fan_mult;
276}
277
278
279
280
281static int _i8k_get_fan_type(const struct dell_smm_data *data, int fan)
282{
283 struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
284
285 if (data->disallow_fan_support || data->disallow_fan_type_call)
286 return -EINVAL;
287
288 regs.ebx = fan & 0xff;
289 return i8k_smm(®s) ? : regs.eax & 0xff;
290}
291
292static int i8k_get_fan_type(struct dell_smm_data *data, int fan)
293{
294
295 if (data->fan_type[fan] == INT_MIN)
296 data->fan_type[fan] = _i8k_get_fan_type(data, fan);
297
298 return data->fan_type[fan];
299}
300
301
302
303
304static int __init i8k_get_fan_nominal_speed(const struct dell_smm_data *data, int fan, int speed)
305{
306 struct smm_regs regs = { .eax = I8K_SMM_GET_NOM_SPEED, };
307
308 if (data->disallow_fan_support)
309 return -EINVAL;
310
311 regs.ebx = (fan & 0xff) | (speed << 8);
312 return i8k_smm(®s) ? : (regs.eax & 0xffff) * data->i8k_fan_mult;
313}
314
315
316
317
318static int i8k_enable_fan_auto_mode(const struct dell_smm_data *data, bool enable)
319{
320 struct smm_regs regs = { };
321
322 if (data->disallow_fan_support)
323 return -EINVAL;
324
325 regs.eax = enable ? data->auto_fan : data->manual_fan;
326 return i8k_smm(®s);
327}
328
329
330
331
332static int i8k_set_fan(const struct dell_smm_data *data, int fan, int speed)
333{
334 struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
335
336 if (data->disallow_fan_support)
337 return -EINVAL;
338
339 speed = (speed < 0) ? 0 : ((speed > data->i8k_fan_max) ? data->i8k_fan_max : speed);
340 regs.ebx = (fan & 0xff) | (speed << 8);
341
342 return i8k_smm(®s);
343}
344
345static int __init i8k_get_temp_type(int sensor)
346{
347 struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP_TYPE, };
348
349 regs.ebx = sensor & 0xff;
350 return i8k_smm(®s) ? : regs.eax & 0xff;
351}
352
353
354
355
356static int _i8k_get_temp(int sensor)
357{
358 struct smm_regs regs = {
359 .eax = I8K_SMM_GET_TEMP,
360 .ebx = sensor & 0xff,
361 };
362
363 return i8k_smm(®s) ? : regs.eax & 0xff;
364}
365
366static int i8k_get_temp(int sensor)
367{
368 int temp = _i8k_get_temp(sensor);
369
370
371
372
373
374
375
376
377 if (temp == 0x99) {
378 msleep(100);
379 temp = _i8k_get_temp(sensor);
380 }
381
382
383
384
385
386
387
388
389 if (temp > I8K_MAX_TEMP)
390 return -ENODATA;
391
392 return temp;
393}
394
395static int __init i8k_get_dell_signature(int req_fn)
396{
397 struct smm_regs regs = { .eax = req_fn, };
398 int rc;
399
400 rc = i8k_smm(®s);
401 if (rc < 0)
402 return rc;
403
404 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
405}
406
407#if IS_ENABLED(CONFIG_I8K)
408
409
410
411
412static int i8k_get_fn_status(void)
413{
414 struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
415 int rc;
416
417 rc = i8k_smm(®s);
418 if (rc < 0)
419 return rc;
420
421 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
422 case I8K_FN_UP:
423 return I8K_VOL_UP;
424 case I8K_FN_DOWN:
425 return I8K_VOL_DOWN;
426 case I8K_FN_MUTE:
427 return I8K_VOL_MUTE;
428 default:
429 return 0;
430 }
431}
432
433
434
435
436static int i8k_get_power_status(void)
437{
438 struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
439 int rc;
440
441 rc = i8k_smm(®s);
442 if (rc < 0)
443 return rc;
444
445 return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
446}
447
448
449
450
451
452static int
453i8k_ioctl_unlocked(struct file *fp, struct dell_smm_data *data, unsigned int cmd, unsigned long arg)
454{
455 int val = 0;
456 int speed, err;
457 unsigned char buff[16];
458 int __user *argp = (int __user *)arg;
459
460 if (!argp)
461 return -EINVAL;
462
463 switch (cmd) {
464 case I8K_BIOS_VERSION:
465 if (!isdigit(data->bios_version[0]) || !isdigit(data->bios_version[1]) ||
466 !isdigit(data->bios_version[2]))
467 return -EINVAL;
468
469 val = (data->bios_version[0] << 16) |
470 (data->bios_version[1] << 8) | data->bios_version[2];
471 break;
472
473 case I8K_MACHINE_ID:
474 if (restricted && !capable(CAP_SYS_ADMIN))
475 return -EPERM;
476
477 strscpy_pad(buff, data->bios_machineid, sizeof(buff));
478 break;
479
480 case I8K_FN_STATUS:
481 val = i8k_get_fn_status();
482 break;
483
484 case I8K_POWER_STATUS:
485 val = i8k_get_power_status();
486 break;
487
488 case I8K_GET_TEMP:
489 val = i8k_get_temp(0);
490 break;
491
492 case I8K_GET_SPEED:
493 if (copy_from_user(&val, argp, sizeof(int)))
494 return -EFAULT;
495
496 val = i8k_get_fan_speed(data, val);
497 break;
498
499 case I8K_GET_FAN:
500 if (copy_from_user(&val, argp, sizeof(int)))
501 return -EFAULT;
502
503 val = i8k_get_fan_status(data, val);
504 break;
505
506 case I8K_SET_FAN:
507 if (restricted && !capable(CAP_SYS_ADMIN))
508 return -EPERM;
509
510 if (copy_from_user(&val, argp, sizeof(int)))
511 return -EFAULT;
512
513 if (copy_from_user(&speed, argp + 1, sizeof(int)))
514 return -EFAULT;
515
516 err = i8k_set_fan(data, val, speed);
517 if (err < 0)
518 return err;
519
520 val = i8k_get_fan_status(data, val);
521 break;
522
523 default:
524 return -ENOIOCTLCMD;
525 }
526
527 if (val < 0)
528 return val;
529
530 switch (cmd) {
531 case I8K_BIOS_VERSION:
532 if (copy_to_user(argp, &val, 4))
533 return -EFAULT;
534
535 break;
536 case I8K_MACHINE_ID:
537 if (copy_to_user(argp, buff, 16))
538 return -EFAULT;
539
540 break;
541 default:
542 if (copy_to_user(argp, &val, sizeof(int)))
543 return -EFAULT;
544
545 break;
546 }
547
548 return 0;
549}
550
551static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
552{
553 struct dell_smm_data *data = PDE_DATA(file_inode(fp));
554 long ret;
555
556 mutex_lock(&data->i8k_mutex);
557 ret = i8k_ioctl_unlocked(fp, data, cmd, arg);
558 mutex_unlock(&data->i8k_mutex);
559
560 return ret;
561}
562
563
564
565
566static int i8k_proc_show(struct seq_file *seq, void *offset)
567{
568 struct dell_smm_data *data = seq->private;
569 int fn_key, cpu_temp, ac_power;
570 int left_fan, right_fan, left_speed, right_speed;
571
572 cpu_temp = i8k_get_temp(0);
573 left_fan = i8k_get_fan_status(data, I8K_FAN_LEFT);
574 right_fan = i8k_get_fan_status(data, I8K_FAN_RIGHT);
575 left_speed = i8k_get_fan_speed(data, I8K_FAN_LEFT);
576 right_speed = i8k_get_fan_speed(data, I8K_FAN_RIGHT);
577 fn_key = i8k_get_fn_status();
578 if (power_status)
579 ac_power = i8k_get_power_status();
580 else
581 ac_power = -1;
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
598 I8K_PROC_FMT,
599 data->bios_version,
600 (restricted && !capable(CAP_SYS_ADMIN)) ? "-1" : data->bios_machineid,
601 cpu_temp,
602 left_fan, right_fan, left_speed, right_speed,
603 ac_power, fn_key);
604
605 return 0;
606}
607
608static int i8k_open_fs(struct inode *inode, struct file *file)
609{
610 return single_open(file, i8k_proc_show, PDE_DATA(inode));
611}
612
613static const struct proc_ops i8k_proc_ops = {
614 .proc_open = i8k_open_fs,
615 .proc_read = seq_read,
616 .proc_lseek = seq_lseek,
617 .proc_release = single_release,
618 .proc_ioctl = i8k_ioctl,
619};
620
621static void i8k_exit_procfs(void *param)
622{
623 remove_proc_entry("i8k", NULL);
624}
625
626static void __init i8k_init_procfs(struct device *dev)
627{
628 struct dell_smm_data *data = dev_get_drvdata(dev);
629
630
631 if (proc_create_data("i8k", 0, NULL, &i8k_proc_ops, data))
632 devm_add_action_or_reset(dev, i8k_exit_procfs, NULL);
633}
634
635#else
636
637static void __init i8k_init_procfs(struct device *dev)
638{
639}
640
641#endif
642
643
644
645
646
647static umode_t dell_smm_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
648 int channel)
649{
650 const struct dell_smm_data *data = drvdata;
651
652 switch (type) {
653 case hwmon_temp:
654 switch (attr) {
655 case hwmon_temp_input:
656 case hwmon_temp_label:
657 if (data->temp_type[channel] >= 0)
658 return 0444;
659
660 break;
661 default:
662 break;
663 }
664 break;
665 case hwmon_fan:
666 if (data->disallow_fan_support)
667 break;
668
669 switch (attr) {
670 case hwmon_fan_input:
671 if (data->fan[channel])
672 return 0444;
673
674 break;
675 case hwmon_fan_label:
676 if (data->fan[channel] && !data->disallow_fan_type_call)
677 return 0444;
678
679 break;
680 case hwmon_fan_min:
681 case hwmon_fan_max:
682 case hwmon_fan_target:
683 if (data->fan_nominal_speed[channel])
684 return 0444;
685
686 break;
687 default:
688 break;
689 }
690 break;
691 case hwmon_pwm:
692 if (data->disallow_fan_support)
693 break;
694
695 switch (attr) {
696 case hwmon_pwm_input:
697 if (data->fan[channel])
698 return 0644;
699
700 break;
701 case hwmon_pwm_enable:
702 if (data->auto_fan)
703
704
705
706
707
708
709 return 0200;
710
711 break;
712 default:
713 break;
714 }
715 break;
716 default:
717 break;
718 }
719
720 return 0;
721}
722
723static int dell_smm_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
724 long *val)
725{
726 struct dell_smm_data *data = dev_get_drvdata(dev);
727 int ret;
728
729 switch (type) {
730 case hwmon_temp:
731 switch (attr) {
732 case hwmon_temp_input:
733 ret = i8k_get_temp(channel);
734 if (ret < 0)
735 return ret;
736
737 *val = ret * 1000;
738
739 return 0;
740 default:
741 break;
742 }
743 break;
744 case hwmon_fan:
745 switch (attr) {
746 case hwmon_fan_input:
747 ret = i8k_get_fan_speed(data, channel);
748 if (ret < 0)
749 return ret;
750
751 *val = ret;
752
753 return 0;
754 case hwmon_fan_min:
755 *val = data->fan_nominal_speed[channel][0];
756
757 return 0;
758 case hwmon_fan_max:
759 *val = data->fan_nominal_speed[channel][data->i8k_fan_max];
760
761 return 0;
762 case hwmon_fan_target:
763 ret = i8k_get_fan_status(data, channel);
764 if (ret < 0)
765 return ret;
766
767 if (ret > data->i8k_fan_max)
768 ret = data->i8k_fan_max;
769
770 *val = data->fan_nominal_speed[channel][ret];
771
772 return 0;
773 default:
774 break;
775 }
776 break;
777 case hwmon_pwm:
778 switch (attr) {
779 case hwmon_pwm_input:
780 ret = i8k_get_fan_status(data, channel);
781 if (ret < 0)
782 return ret;
783
784 *val = clamp_val(ret * data->i8k_pwm_mult, 0, 255);
785
786 return 0;
787 default:
788 break;
789 }
790 break;
791 default:
792 break;
793 }
794
795 return -EOPNOTSUPP;
796}
797
798static const char *dell_smm_fan_label(struct dell_smm_data *data, int channel)
799{
800 bool dock = false;
801 int type = i8k_get_fan_type(data, channel);
802
803 if (type < 0)
804 return ERR_PTR(type);
805
806 if (type & 0x10) {
807 dock = true;
808 type &= 0x0F;
809 }
810
811 if (type >= ARRAY_SIZE(fan_labels))
812 type = ARRAY_SIZE(fan_labels) - 1;
813
814 return dock ? docking_labels[type] : fan_labels[type];
815}
816
817static int dell_smm_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
818 int channel, const char **str)
819{
820 struct dell_smm_data *data = dev_get_drvdata(dev);
821
822 switch (type) {
823 case hwmon_temp:
824 switch (attr) {
825 case hwmon_temp_label:
826 *str = temp_labels[data->temp_type[channel]];
827 return 0;
828 default:
829 break;
830 }
831 break;
832 case hwmon_fan:
833 switch (attr) {
834 case hwmon_fan_label:
835 *str = dell_smm_fan_label(data, channel);
836 return PTR_ERR_OR_ZERO(*str);
837 default:
838 break;
839 }
840 break;
841 default:
842 break;
843 }
844
845 return -EOPNOTSUPP;
846}
847
848static int dell_smm_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel,
849 long val)
850{
851 struct dell_smm_data *data = dev_get_drvdata(dev);
852 unsigned long pwm;
853 bool enable;
854 int err;
855
856 switch (type) {
857 case hwmon_pwm:
858 switch (attr) {
859 case hwmon_pwm_input:
860 pwm = clamp_val(DIV_ROUND_CLOSEST(val, data->i8k_pwm_mult), 0,
861 data->i8k_fan_max);
862
863 mutex_lock(&data->i8k_mutex);
864 err = i8k_set_fan(data, channel, pwm);
865 mutex_unlock(&data->i8k_mutex);
866
867 if (err < 0)
868 return err;
869
870 return 0;
871 case hwmon_pwm_enable:
872 if (!val)
873 return -EINVAL;
874
875 if (val == 1)
876 enable = false;
877 else
878 enable = true;
879
880 mutex_lock(&data->i8k_mutex);
881 err = i8k_enable_fan_auto_mode(data, enable);
882 mutex_unlock(&data->i8k_mutex);
883
884 if (err < 0)
885 return err;
886
887 return 0;
888 default:
889 break;
890 }
891 break;
892 default:
893 break;
894 }
895
896 return -EOPNOTSUPP;
897}
898
899static const struct hwmon_ops dell_smm_ops = {
900 .is_visible = dell_smm_is_visible,
901 .read = dell_smm_read,
902 .read_string = dell_smm_read_string,
903 .write = dell_smm_write,
904};
905
906static const struct hwmon_channel_info *dell_smm_info[] = {
907 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
908 HWMON_CHANNEL_INFO(temp,
909 HWMON_T_INPUT | HWMON_T_LABEL,
910 HWMON_T_INPUT | HWMON_T_LABEL,
911 HWMON_T_INPUT | HWMON_T_LABEL,
912 HWMON_T_INPUT | HWMON_T_LABEL,
913 HWMON_T_INPUT | HWMON_T_LABEL,
914 HWMON_T_INPUT | HWMON_T_LABEL,
915 HWMON_T_INPUT | HWMON_T_LABEL,
916 HWMON_T_INPUT | HWMON_T_LABEL,
917 HWMON_T_INPUT | HWMON_T_LABEL,
918 HWMON_T_INPUT | HWMON_T_LABEL
919 ),
920 HWMON_CHANNEL_INFO(fan,
921 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |
922 HWMON_F_TARGET,
923 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |
924 HWMON_F_TARGET,
925 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX |
926 HWMON_F_TARGET
927 ),
928 HWMON_CHANNEL_INFO(pwm,
929 HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
930 HWMON_PWM_INPUT,
931 HWMON_PWM_INPUT
932 ),
933 NULL
934};
935
936static const struct hwmon_chip_info dell_smm_chip_info = {
937 .ops = &dell_smm_ops,
938 .info = dell_smm_info,
939};
940
941static int __init dell_smm_init_hwmon(struct device *dev)
942{
943 struct dell_smm_data *data = dev_get_drvdata(dev);
944 struct device *dell_smm_hwmon_dev;
945 int i, state, err;
946
947 for (i = 0; i < DELL_SMM_NO_TEMP; i++) {
948 data->temp_type[i] = i8k_get_temp_type(i);
949 if (data->temp_type[i] < 0)
950 continue;
951
952 if (data->temp_type[i] >= ARRAY_SIZE(temp_labels))
953 data->temp_type[i] = ARRAY_SIZE(temp_labels) - 1;
954 }
955
956 for (i = 0; i < DELL_SMM_NO_FANS; i++) {
957 data->fan_type[i] = INT_MIN;
958 err = i8k_get_fan_status(data, i);
959 if (err < 0)
960 err = i8k_get_fan_type(data, i);
961
962 if (err < 0)
963 continue;
964
965 data->fan[i] = true;
966 data->fan_nominal_speed[i] = devm_kmalloc_array(dev, data->i8k_fan_max + 1,
967 sizeof(*data->fan_nominal_speed[i]),
968 GFP_KERNEL);
969 if (!data->fan_nominal_speed[i])
970 continue;
971
972 for (state = 0; state <= data->i8k_fan_max; state++) {
973 err = i8k_get_fan_nominal_speed(data, i, state);
974 if (err < 0) {
975
976 devm_kfree(dev, data->fan_nominal_speed[i]);
977 data->fan_nominal_speed[i] = NULL;
978 break;
979 }
980 data->fan_nominal_speed[i][state] = err;
981 }
982 }
983
984 dell_smm_hwmon_dev = devm_hwmon_device_register_with_info(dev, "dell_smm", data,
985 &dell_smm_chip_info, NULL);
986
987 return PTR_ERR_OR_ZERO(dell_smm_hwmon_dev);
988}
989
990struct i8k_config_data {
991 uint fan_mult;
992 uint fan_max;
993};
994
995enum i8k_configs {
996 DELL_LATITUDE_D520,
997 DELL_PRECISION_490,
998 DELL_STUDIO,
999 DELL_XPS,
1000};
1001
1002
1003
1004
1005
1006
1007static const struct i8k_config_data i8k_config_data[] __initconst = {
1008 [DELL_LATITUDE_D520] = {
1009 .fan_mult = 1,
1010 .fan_max = I8K_FAN_TURBO,
1011 },
1012 [DELL_PRECISION_490] = {
1013 .fan_mult = 1,
1014 .fan_max = I8K_FAN_TURBO,
1015 },
1016 [DELL_STUDIO] = {
1017 .fan_mult = 1,
1018 .fan_max = I8K_FAN_HIGH,
1019 },
1020 [DELL_XPS] = {
1021 .fan_mult = 1,
1022 .fan_max = I8K_FAN_HIGH,
1023 },
1024};
1025
1026static const struct dmi_system_id i8k_dmi_table[] __initconst = {
1027 {
1028 .ident = "Dell Inspiron",
1029 .matches = {
1030 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
1031 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
1032 },
1033 },
1034 {
1035 .ident = "Dell Latitude",
1036 .matches = {
1037 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
1038 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
1039 },
1040 },
1041 {
1042 .ident = "Dell Inspiron 2",
1043 .matches = {
1044 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1045 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
1046 },
1047 },
1048 {
1049 .ident = "Dell Latitude D520",
1050 .matches = {
1051 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1052 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D520"),
1053 },
1054 .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520],
1055 },
1056 {
1057 .ident = "Dell Latitude 2",
1058 .matches = {
1059 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1060 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
1061 },
1062 },
1063 {
1064 .ident = "Dell Inspiron 3",
1065 .matches = {
1066 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1067 DMI_MATCH(DMI_PRODUCT_NAME, "MM061"),
1068 },
1069 },
1070 {
1071 .ident = "Dell Inspiron 3",
1072 .matches = {
1073 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1074 DMI_MATCH(DMI_PRODUCT_NAME, "MP061"),
1075 },
1076 },
1077 {
1078 .ident = "Dell Precision 490",
1079 .matches = {
1080 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1081 DMI_MATCH(DMI_PRODUCT_NAME,
1082 "Precision WorkStation 490"),
1083 },
1084 .driver_data = (void *)&i8k_config_data[DELL_PRECISION_490],
1085 },
1086 {
1087 .ident = "Dell Precision",
1088 .matches = {
1089 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1090 DMI_MATCH(DMI_PRODUCT_NAME, "Precision"),
1091 },
1092 },
1093 {
1094 .ident = "Dell Vostro",
1095 .matches = {
1096 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1097 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),
1098 },
1099 },
1100 {
1101 .ident = "Dell Studio",
1102 .matches = {
1103 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1104 DMI_MATCH(DMI_PRODUCT_NAME, "Studio"),
1105 },
1106 .driver_data = (void *)&i8k_config_data[DELL_STUDIO],
1107 },
1108 {
1109 .ident = "Dell XPS M140",
1110 .matches = {
1111 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1112 DMI_MATCH(DMI_PRODUCT_NAME, "MXC051"),
1113 },
1114 .driver_data = (void *)&i8k_config_data[DELL_XPS],
1115 },
1116 {
1117 .ident = "Dell XPS",
1118 .matches = {
1119 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1120 DMI_MATCH(DMI_PRODUCT_NAME, "XPS"),
1121 },
1122 },
1123 { }
1124};
1125
1126MODULE_DEVICE_TABLE(dmi, i8k_dmi_table);
1127
1128
1129
1130
1131
1132
1133
1134static const struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initconst = {
1135 {
1136 .ident = "Dell Studio XPS 8000",
1137 .matches = {
1138 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1139 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8000"),
1140 },
1141 },
1142 {
1143 .ident = "Dell Studio XPS 8100",
1144 .matches = {
1145 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1146 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"),
1147 },
1148 },
1149 {
1150 .ident = "Dell Inspiron 580",
1151 .matches = {
1152 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1153 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 580 "),
1154 },
1155 },
1156 { }
1157};
1158
1159
1160
1161
1162
1163
1164
1165static const struct dmi_system_id i8k_blacklist_fan_support_dmi_table[] __initconst = {
1166 {
1167 .ident = "Dell Inspiron 7720",
1168 .matches = {
1169 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1170 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"),
1171 },
1172 },
1173 {
1174 .ident = "Dell Vostro 3360",
1175 .matches = {
1176 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1177 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Vostro 3360"),
1178 },
1179 },
1180 {
1181 .ident = "Dell XPS13 9333",
1182 .matches = {
1183 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1184 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "XPS13 9333"),
1185 },
1186 },
1187 {
1188 .ident = "Dell XPS 15 L502X",
1189 .matches = {
1190 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1191 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L502X"),
1192 },
1193 },
1194 { }
1195};
1196
1197struct i8k_fan_control_data {
1198 unsigned int manual_fan;
1199 unsigned int auto_fan;
1200};
1201
1202enum i8k_fan_controls {
1203 I8K_FAN_34A3_35A3,
1204};
1205
1206static const struct i8k_fan_control_data i8k_fan_control_data[] __initconst = {
1207 [I8K_FAN_34A3_35A3] = {
1208 .manual_fan = 0x34a3,
1209 .auto_fan = 0x35a3,
1210 },
1211};
1212
1213static const struct dmi_system_id i8k_whitelist_fan_control[] __initconst = {
1214 {
1215 .ident = "Dell Latitude 5480",
1216 .matches = {
1217 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1218 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 5480"),
1219 },
1220 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1221 },
1222 {
1223 .ident = "Dell Latitude E6440",
1224 .matches = {
1225 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1226 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude E6440"),
1227 },
1228 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1229 },
1230 {
1231 .ident = "Dell Latitude E7440",
1232 .matches = {
1233 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1234 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude E7440"),
1235 },
1236 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1237 },
1238 {
1239 .ident = "Dell Precision 5530",
1240 .matches = {
1241 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1242 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Precision 5530"),
1243 },
1244 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1245 },
1246 {
1247 .ident = "Dell Precision 7510",
1248 .matches = {
1249 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1250 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Precision 7510"),
1251 },
1252 .driver_data = (void *)&i8k_fan_control_data[I8K_FAN_34A3_35A3],
1253 },
1254 { }
1255};
1256
1257static int __init dell_smm_probe(struct platform_device *pdev)
1258{
1259 struct dell_smm_data *data;
1260 const struct dmi_system_id *id, *fan_control;
1261 int fan, ret;
1262
1263 data = devm_kzalloc(&pdev->dev, sizeof(struct dell_smm_data), GFP_KERNEL);
1264 if (!data)
1265 return -ENOMEM;
1266
1267 mutex_init(&data->i8k_mutex);
1268 data->i8k_fan_mult = I8K_FAN_MULT;
1269 data->i8k_fan_max = I8K_FAN_HIGH;
1270 platform_set_drvdata(pdev, data);
1271
1272 if (dmi_check_system(i8k_blacklist_fan_support_dmi_table)) {
1273 dev_warn(&pdev->dev, "broken Dell BIOS detected, disallow fan support\n");
1274 if (!force)
1275 data->disallow_fan_support = true;
1276 }
1277
1278 if (dmi_check_system(i8k_blacklist_fan_type_dmi_table)) {
1279 dev_warn(&pdev->dev, "broken Dell BIOS detected, disallow fan type call\n");
1280 if (!force)
1281 data->disallow_fan_type_call = true;
1282 }
1283
1284 strscpy(data->bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
1285 sizeof(data->bios_version));
1286 strscpy(data->bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
1287 sizeof(data->bios_machineid));
1288
1289
1290
1291
1292
1293 id = dmi_first_match(i8k_dmi_table);
1294 if (id && id->driver_data) {
1295 const struct i8k_config_data *conf = id->driver_data;
1296
1297 if (!fan_mult && conf->fan_mult)
1298 fan_mult = conf->fan_mult;
1299
1300 if (!fan_max && conf->fan_max)
1301 fan_max = conf->fan_max;
1302 }
1303
1304 data->i8k_fan_max = fan_max ? : I8K_FAN_HIGH;
1305 data->i8k_pwm_mult = DIV_ROUND_UP(255, data->i8k_fan_max);
1306
1307 fan_control = dmi_first_match(i8k_whitelist_fan_control);
1308 if (fan_control && fan_control->driver_data) {
1309 const struct i8k_fan_control_data *control = fan_control->driver_data;
1310
1311 data->manual_fan = control->manual_fan;
1312 data->auto_fan = control->auto_fan;
1313 dev_info(&pdev->dev, "enabling support for setting automatic/manual fan control\n");
1314 }
1315
1316 if (!fan_mult) {
1317
1318
1319
1320
1321 for (fan = 0; fan < DELL_SMM_NO_FANS; ++fan) {
1322 ret = i8k_get_fan_nominal_speed(data, fan, data->i8k_fan_max);
1323 if (ret < 0)
1324 continue;
1325
1326 if (ret > I8K_FAN_MAX_RPM)
1327 data->i8k_fan_mult = 1;
1328 break;
1329 }
1330 } else {
1331
1332 data->i8k_fan_mult = fan_mult;
1333 }
1334
1335 ret = dell_smm_init_hwmon(&pdev->dev);
1336 if (ret)
1337 return ret;
1338
1339 i8k_init_procfs(&pdev->dev);
1340
1341 return 0;
1342}
1343
1344static struct platform_driver dell_smm_driver = {
1345 .driver = {
1346 .name = KBUILD_MODNAME,
1347 },
1348};
1349
1350static struct platform_device *dell_smm_device;
1351
1352
1353
1354
1355static int __init i8k_init(void)
1356{
1357
1358
1359
1360 if (!dmi_check_system(i8k_dmi_table)) {
1361 if (!ignore_dmi && !force)
1362 return -ENODEV;
1363
1364 pr_info("not running on a supported Dell system.\n");
1365 pr_info("vendor=%s, model=%s, version=%s\n",
1366 i8k_get_dmi_data(DMI_SYS_VENDOR),
1367 i8k_get_dmi_data(DMI_PRODUCT_NAME),
1368 i8k_get_dmi_data(DMI_BIOS_VERSION));
1369 }
1370
1371
1372
1373
1374 if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
1375 i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
1376 pr_err("unable to get SMM Dell signature\n");
1377 if (!force)
1378 return -ENODEV;
1379 }
1380
1381 dell_smm_device = platform_create_bundle(&dell_smm_driver, dell_smm_probe, NULL, 0, NULL,
1382 0);
1383
1384 return PTR_ERR_OR_ZERO(dell_smm_device);
1385}
1386
1387static void __exit i8k_exit(void)
1388{
1389 platform_device_unregister(dell_smm_device);
1390 platform_driver_unregister(&dell_smm_driver);
1391}
1392
1393module_init(i8k_init);
1394module_exit(i8k_exit);
1395