aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/i8k.c
diff options
context:
space:
mode:
authorPali Rohár <pali.rohar@gmail.com>2015-01-12 08:31:57 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-25 12:17:58 -0500
commit5114b474cbb464e7a5da4ba5cdc551e798395151 (patch)
treef12643266d1524827ccad32a72390e9ae867b249 /drivers/char/i8k.c
parentd9b1652947c695d247b5e4603a16213ec55661ed (diff)
i8k: Add support for temperature sensor labels
This patch adds labels for temperature sensors if SMM function with EAX register 0x11a3 reports it. This information was taken from DOS binary NBSVC.MDM. Signed-off-by: Pali Rohár <pali.rohar@gmail.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Pali Rohár <pali.rohar@gmail.com> Tested-by: Steven Honeyman <stevenhoneyman@gmail.com> Tested-by: Gabriele Mazzotta <gabriele.mzt@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/char/i8k.c')
-rw-r--r--drivers/char/i8k.c74
1 files changed, 61 insertions, 13 deletions
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index e34a019eb930..663868b2adc4 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -42,6 +42,7 @@
42#define I8K_SMM_GET_FAN 0x00a3 42#define I8K_SMM_GET_FAN 0x00a3
43#define I8K_SMM_GET_SPEED 0x02a3 43#define I8K_SMM_GET_SPEED 0x02a3
44#define I8K_SMM_GET_TEMP 0x10a3 44#define I8K_SMM_GET_TEMP 0x10a3
45#define I8K_SMM_GET_TEMP_TYPE 0x11a3
45#define I8K_SMM_GET_DELL_SIG1 0xfea3 46#define I8K_SMM_GET_DELL_SIG1 0xfea3
46#define I8K_SMM_GET_DELL_SIG2 0xffa3 47#define I8K_SMM_GET_DELL_SIG2 0xffa3
47 48
@@ -288,6 +289,14 @@ static int i8k_set_fan(int fan, int speed)
288 return i8k_smm(&regs) ? : i8k_get_fan_status(fan); 289 return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
289} 290}
290 291
292static int i8k_get_temp_type(int sensor)
293{
294 struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP_TYPE, };
295
296 regs.ebx = sensor & 0xff;
297 return i8k_smm(&regs) ? : regs.eax & 0xff;
298}
299
291/* 300/*
292 * Read the cpu temperature. 301 * Read the cpu temperature.
293 */ 302 */
@@ -493,6 +502,29 @@ static int i8k_open_fs(struct inode *inode, struct file *file)
493 * Hwmon interface 502 * Hwmon interface
494 */ 503 */
495 504
505static ssize_t i8k_hwmon_show_temp_label(struct device *dev,
506 struct device_attribute *devattr,
507 char *buf)
508{
509 static const char * const labels[] = {
510 "CPU",
511 "GPU",
512 "SODIMM",
513 "Other",
514 "Ambient",
515 "Other",
516 };
517 int index = to_sensor_dev_attr(devattr)->index;
518 int type;
519
520 type = i8k_get_temp_type(index);
521 if (type < 0)
522 return type;
523 if (type >= ARRAY_SIZE(labels))
524 type = ARRAY_SIZE(labels) - 1;
525 return sprintf(buf, "%s\n", labels[type]);
526}
527
496static ssize_t i8k_hwmon_show_temp(struct device *dev, 528static ssize_t i8k_hwmon_show_temp(struct device *dev,
497 struct device_attribute *devattr, 529 struct device_attribute *devattr,
498 char *buf) 530 char *buf)
@@ -555,9 +587,17 @@ static ssize_t i8k_hwmon_set_pwm(struct device *dev,
555} 587}
556 588
557static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 0); 589static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 0);
590static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_temp_label, NULL,
591 0);
558static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 1); 592static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 1);
593static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, i8k_hwmon_show_temp_label, NULL,
594 1);
559static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 2); 595static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 2);
596static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, i8k_hwmon_show_temp_label, NULL,
597 2);
560static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 3); 598static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, i8k_hwmon_show_temp, NULL, 3);
599static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, i8k_hwmon_show_temp_label, NULL,
600 3);
561static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL, 601static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
562 I8K_FAN_LEFT); 602 I8K_FAN_LEFT);
563static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm, 603static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
@@ -569,31 +609,39 @@ static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, i8k_hwmon_show_pwm,
569 609
570static struct attribute *i8k_attrs[] = { 610static struct attribute *i8k_attrs[] = {
571 &sensor_dev_attr_temp1_input.dev_attr.attr, /* 0 */ 611 &sensor_dev_attr_temp1_input.dev_attr.attr, /* 0 */
572 &sensor_dev_attr_temp2_input.dev_attr.attr, /* 1 */ 612 &sensor_dev_attr_temp1_label.dev_attr.attr, /* 1 */
573 &sensor_dev_attr_temp3_input.dev_attr.attr, /* 2 */ 613 &sensor_dev_attr_temp2_input.dev_attr.attr, /* 2 */
574 &sensor_dev_attr_temp4_input.dev_attr.attr, /* 3 */ 614 &sensor_dev_attr_temp2_label.dev_attr.attr, /* 3 */
575 &sensor_dev_attr_fan1_input.dev_attr.attr, /* 4 */ 615 &sensor_dev_attr_temp3_input.dev_attr.attr, /* 4 */
576 &sensor_dev_attr_pwm1.dev_attr.attr, /* 5 */ 616 &sensor_dev_attr_temp3_label.dev_attr.attr, /* 5 */
577 &sensor_dev_attr_fan2_input.dev_attr.attr, /* 6 */ 617 &sensor_dev_attr_temp4_input.dev_attr.attr, /* 6 */
578 &sensor_dev_attr_pwm2.dev_attr.attr, /* 7 */ 618 &sensor_dev_attr_temp4_label.dev_attr.attr, /* 7 */
619 &sensor_dev_attr_fan1_input.dev_attr.attr, /* 8 */
620 &sensor_dev_attr_pwm1.dev_attr.attr, /* 9 */
621 &sensor_dev_attr_fan2_input.dev_attr.attr, /* 10 */
622 &sensor_dev_attr_pwm2.dev_attr.attr, /* 11 */
579 NULL 623 NULL
580}; 624};
581 625
582static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, 626static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
583 int index) 627 int index)
584{ 628{
585 if (index == 0 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1)) 629 if (index >= 0 && index <= 1 &&
630 !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
586 return 0; 631 return 0;
587 if (index == 1 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP2)) 632 if (index >= 2 && index <= 3 &&
633 !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP2))
588 return 0; 634 return 0;
589 if (index == 2 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP3)) 635 if (index >= 4 && index <= 5 &&
636 !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP3))
590 return 0; 637 return 0;
591 if (index == 3 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP4)) 638 if (index >= 6 && index <= 7 &&
639 !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP4))
592 return 0; 640 return 0;
593 if (index >= 4 && index <= 5 && 641 if (index >= 8 && index <= 9 &&
594 !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN1)) 642 !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN1))
595 return 0; 643 return 0;
596 if (index >= 6 && index <= 7 && 644 if (index >= 10 && index <= 11 &&
597 !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2)) 645 !(i8k_hwmon_flags & I8K_HWMON_HAVE_FAN2))
598 return 0; 646 return 0;
599 647