summaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/gl520sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/gl520sm.c')
-rw-r--r--drivers/hwmon/gl520sm.c243
1 files changed, 146 insertions, 97 deletions
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index cd6085bbfba7..5ff452b6a4d0 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -1,25 +1,25 @@
1/* 1/*
2 gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware 2 * gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring 3 * monitoring
4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>, 4 * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>,
5 Kyösti Mälkki <kmalkki@cc.hut.fi> 5 * Kyösti Mälkki <kmalkki@cc.hut.fi>
6 Copyright (c) 2005 Maarten Deprez <maartendeprez@users.sourceforge.net> 6 * Copyright (c) 2005 Maarten Deprez <maartendeprez@users.sourceforge.net>
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 * (at your option) any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 * GNU General Public License for more details.
17 17 *
18 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 21 *
22*/ 22 */
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/init.h> 25#include <linux/init.h>
@@ -41,10 +41,11 @@ MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=tempe
41/* Addresses to scan */ 41/* Addresses to scan */
42static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; 42static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
43 43
44/* Many GL520 constants specified below 44/*
45One of the inputs can be configured as either temp or voltage. 45 * Many GL520 constants specified below
46That's why _TEMP2 and _IN4 access the same register 46 * One of the inputs can be configured as either temp or voltage.
47*/ 47 * That's why _TEMP2 and _IN4 access the same register
48 */
48 49
49/* The GL520 registers */ 50/* The GL520 registers */
50#define GL520_REG_CHIP_ID 0x00 51#define GL520_REG_CHIP_ID 0x00
@@ -142,11 +143,11 @@ static ssize_t get_cpu_vid(struct device *dev, struct device_attribute *attr,
142} 143}
143static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL); 144static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL);
144 145
145#define VDD_FROM_REG(val) (((val)*95+2)/4) 146#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4)
146#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255)) 147#define VDD_TO_REG(val) SENSORS_LIMIT((((val) * 4 + 47) / 95), 0, 255)
147 148
148#define IN_FROM_REG(val) ((val)*19) 149#define IN_FROM_REG(val) ((val) * 19)
149#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255)) 150#define IN_TO_REG(val) SENSORS_LIMIT((((val) + 9) / 19), 0, 255)
150 151
151static ssize_t get_in_input(struct device *dev, struct device_attribute *attr, 152static ssize_t get_in_input(struct device *dev, struct device_attribute *attr,
152 char *buf) 153 char *buf)
@@ -193,8 +194,13 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
193 struct i2c_client *client = to_i2c_client(dev); 194 struct i2c_client *client = to_i2c_client(dev);
194 struct gl520_data *data = i2c_get_clientdata(client); 195 struct gl520_data *data = i2c_get_clientdata(client);
195 int n = to_sensor_dev_attr(attr)->index; 196 int n = to_sensor_dev_attr(attr)->index;
196 long v = simple_strtol(buf, NULL, 10);
197 u8 r; 197 u8 r;
198 long v;
199 int err;
200
201 err = kstrtol(buf, 10, &v);
202 if (err)
203 return err;
198 204
199 mutex_lock(&data->update_lock); 205 mutex_lock(&data->update_lock);
200 206
@@ -222,8 +228,13 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
222 struct i2c_client *client = to_i2c_client(dev); 228 struct i2c_client *client = to_i2c_client(dev);
223 struct gl520_data *data = i2c_get_clientdata(client); 229 struct gl520_data *data = i2c_get_clientdata(client);
224 int n = to_sensor_dev_attr(attr)->index; 230 int n = to_sensor_dev_attr(attr)->index;
225 long v = simple_strtol(buf, NULL, 10);
226 u8 r; 231 u8 r;
232 long v;
233 int err;
234
235 err = kstrtol(buf, 10, &v);
236 if (err)
237 return err;
227 238
228 if (n == 0) 239 if (n == 0)
229 r = VDD_TO_REG(v); 240 r = VDD_TO_REG(v);
@@ -272,8 +283,10 @@ static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
272 get_in_max, set_in_max, 4); 283 get_in_max, set_in_max, 4);
273 284
274#define DIV_FROM_REG(val) (1 << (val)) 285#define DIV_FROM_REG(val) (1 << (val))
275#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div)))) 286#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (480000 / ((val) << (div))))
276#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255)) 287#define FAN_TO_REG(val, div) ((val) <= 0 ? 0 : \
288 SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, \
289 255))
277 290
278static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr, 291static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr,
279 char *buf) 292 char *buf)
@@ -317,8 +330,13 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
317 struct i2c_client *client = to_i2c_client(dev); 330 struct i2c_client *client = to_i2c_client(dev);
318 struct gl520_data *data = i2c_get_clientdata(client); 331 struct gl520_data *data = i2c_get_clientdata(client);
319 int n = to_sensor_dev_attr(attr)->index; 332 int n = to_sensor_dev_attr(attr)->index;
320 unsigned long v = simple_strtoul(buf, NULL, 10);
321 u8 r; 333 u8 r;
334 unsigned long v;
335 int err;
336
337 err = kstrtoul(buf, 10, &v);
338 if (err)
339 return err;
322 340
323 mutex_lock(&data->update_lock); 341 mutex_lock(&data->update_lock);
324 r = FAN_TO_REG(v, data->fan_div[n]); 342 r = FAN_TO_REG(v, data->fan_div[n]);
@@ -351,16 +369,30 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
351 struct i2c_client *client = to_i2c_client(dev); 369 struct i2c_client *client = to_i2c_client(dev);
352 struct gl520_data *data = i2c_get_clientdata(client); 370 struct gl520_data *data = i2c_get_clientdata(client);
353 int n = to_sensor_dev_attr(attr)->index; 371 int n = to_sensor_dev_attr(attr)->index;
354 unsigned long v = simple_strtoul(buf, NULL, 10);
355 u8 r; 372 u8 r;
373 unsigned long v;
374 int err;
375
376 err = kstrtoul(buf, 10, &v);
377 if (err)
378 return err;
356 379
357 switch (v) { 380 switch (v) {
358 case 1: r = 0; break; 381 case 1:
359 case 2: r = 1; break; 382 r = 0;
360 case 4: r = 2; break; 383 break;
361 case 8: r = 3; break; 384 case 2:
385 r = 1;
386 break;
387 case 4:
388 r = 2;
389 break;
390 case 8:
391 r = 3;
392 break;
362 default: 393 default:
363 dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v); 394 dev_err(&client->dev,
395 "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v);
364 return -EINVAL; 396 return -EINVAL;
365 } 397 }
366 398
@@ -385,7 +417,15 @@ static ssize_t set_fan_off(struct device *dev, struct device_attribute *attr,
385{ 417{
386 struct i2c_client *client = to_i2c_client(dev); 418 struct i2c_client *client = to_i2c_client(dev);
387 struct gl520_data *data = i2c_get_clientdata(client); 419 struct gl520_data *data = i2c_get_clientdata(client);
388 u8 r = simple_strtoul(buf, NULL, 10)?1:0; 420 u8 r;
421 unsigned long v;
422 int err;
423
424 err = kstrtoul(buf, 10, &v);
425 if (err)
426 return err;
427
428 r = (v ? 1 : 0);
389 429
390 mutex_lock(&data->update_lock); 430 mutex_lock(&data->update_lock);
391 data->fan_off = r; 431 data->fan_off = r;
@@ -410,7 +450,8 @@ static DEVICE_ATTR(fan1_off, S_IRUGO | S_IWUSR,
410 get_fan_off, set_fan_off); 450 get_fan_off, set_fan_off);
411 451
412#define TEMP_FROM_REG(val) (((val) - 130) * 1000) 452#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
413#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255)) 453#define TEMP_TO_REG(val) SENSORS_LIMIT(((((val) < 0 ? \
454 (val) - 500 : (val) + 500) / 1000) + 130), 0, 255)
414 455
415static ssize_t get_temp_input(struct device *dev, struct device_attribute *attr, 456static ssize_t get_temp_input(struct device *dev, struct device_attribute *attr,
416 char *buf) 457 char *buf)
@@ -430,8 +471,8 @@ static ssize_t get_temp_max(struct device *dev, struct device_attribute *attr,
430 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n])); 471 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n]));
431} 472}
432 473
433static ssize_t get_temp_max_hyst(struct device *dev, struct device_attribute 474static ssize_t get_temp_max_hyst(struct device *dev,
434 *attr, char *buf) 475 struct device_attribute *attr, char *buf)
435{ 476{
436 int n = to_sensor_dev_attr(attr)->index; 477 int n = to_sensor_dev_attr(attr)->index;
437 struct gl520_data *data = gl520_update_device(dev); 478 struct gl520_data *data = gl520_update_device(dev);
@@ -445,7 +486,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
445 struct i2c_client *client = to_i2c_client(dev); 486 struct i2c_client *client = to_i2c_client(dev);
446 struct gl520_data *data = i2c_get_clientdata(client); 487 struct gl520_data *data = i2c_get_clientdata(client);
447 int n = to_sensor_dev_attr(attr)->index; 488 int n = to_sensor_dev_attr(attr)->index;
448 long v = simple_strtol(buf, NULL, 10); 489 long v;
490 int err;
491
492 err = kstrtol(buf, 10, &v);
493 if (err)
494 return err;
449 495
450 mutex_lock(&data->update_lock); 496 mutex_lock(&data->update_lock);
451 data->temp_max[n] = TEMP_TO_REG(v); 497 data->temp_max[n] = TEMP_TO_REG(v);
@@ -460,7 +506,12 @@ static ssize_t set_temp_max_hyst(struct device *dev, struct device_attribute
460 struct i2c_client *client = to_i2c_client(dev); 506 struct i2c_client *client = to_i2c_client(dev);
461 struct gl520_data *data = i2c_get_clientdata(client); 507 struct gl520_data *data = i2c_get_clientdata(client);
462 int n = to_sensor_dev_attr(attr)->index; 508 int n = to_sensor_dev_attr(attr)->index;
463 long v = simple_strtol(buf, NULL, 10); 509 long v;
510 int err;
511
512 err = kstrtol(buf, 10, &v);
513 if (err)
514 return err;
464 515
465 mutex_lock(&data->update_lock); 516 mutex_lock(&data->update_lock);
466 data->temp_max_hyst[n] = TEMP_TO_REG(v); 517 data->temp_max_hyst[n] = TEMP_TO_REG(v);
@@ -507,7 +558,15 @@ static ssize_t set_beep_enable(struct device *dev, struct device_attribute
507{ 558{
508 struct i2c_client *client = to_i2c_client(dev); 559 struct i2c_client *client = to_i2c_client(dev);
509 struct gl520_data *data = i2c_get_clientdata(client); 560 struct gl520_data *data = i2c_get_clientdata(client);
510 u8 r = simple_strtoul(buf, NULL, 10)?0:1; 561 u8 r;
562 unsigned long v;
563 int err;
564
565 err = kstrtoul(buf, 10, &v);
566 if (err)
567 return err;
568
569 r = (v ? 0 : 1);
511 570
512 mutex_lock(&data->update_lock); 571 mutex_lock(&data->update_lock);
513 data->beep_enable = !r; 572 data->beep_enable = !r;
@@ -523,7 +582,12 @@ static ssize_t set_beep_mask(struct device *dev, struct device_attribute *attr,
523{ 582{
524 struct i2c_client *client = to_i2c_client(dev); 583 struct i2c_client *client = to_i2c_client(dev);
525 struct gl520_data *data = i2c_get_clientdata(client); 584 struct gl520_data *data = i2c_get_clientdata(client);
526 u8 r = simple_strtoul(buf, NULL, 10); 585 unsigned long r;
586 int err;
587
588 err = kstrtoul(buf, 10, &r);
589 if (err)
590 return err;
527 591
528 mutex_lock(&data->update_lock); 592 mutex_lock(&data->update_lock);
529 r &= data->alarm_mask; 593 r &= data->alarm_mask;
@@ -575,7 +639,11 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
575 int bitnr = to_sensor_dev_attr(attr)->index; 639 int bitnr = to_sensor_dev_attr(attr)->index;
576 unsigned long bit; 640 unsigned long bit;
577 641
578 bit = simple_strtoul(buf, NULL, 10); 642 int err;
643
644 err = kstrtoul(buf, 10, &bit);
645 if (err)
646 return err;
579 if (bit & ~1) 647 if (bit & ~1)
580 return -EINVAL; 648 return -EINVAL;
581 649
@@ -652,13 +720,16 @@ static const struct attribute_group gl520_group = {
652 .attrs = gl520_attributes, 720 .attrs = gl520_attributes,
653}; 721};
654 722
655static struct attribute *gl520_attributes_opt[] = { 723static struct attribute *gl520_attributes_in4[] = {
656 &sensor_dev_attr_in4_input.dev_attr.attr, 724 &sensor_dev_attr_in4_input.dev_attr.attr,
657 &sensor_dev_attr_in4_min.dev_attr.attr, 725 &sensor_dev_attr_in4_min.dev_attr.attr,
658 &sensor_dev_attr_in4_max.dev_attr.attr, 726 &sensor_dev_attr_in4_max.dev_attr.attr,
659 &sensor_dev_attr_in4_alarm.dev_attr.attr, 727 &sensor_dev_attr_in4_alarm.dev_attr.attr,
660 &sensor_dev_attr_in4_beep.dev_attr.attr, 728 &sensor_dev_attr_in4_beep.dev_attr.attr,
729 NULL
730};
661 731
732static struct attribute *gl520_attributes_temp2[] = {
662 &sensor_dev_attr_temp2_input.dev_attr.attr, 733 &sensor_dev_attr_temp2_input.dev_attr.attr,
663 &sensor_dev_attr_temp2_max.dev_attr.attr, 734 &sensor_dev_attr_temp2_max.dev_attr.attr,
664 &sensor_dev_attr_temp2_max_hyst.dev_attr.attr, 735 &sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
@@ -667,8 +738,12 @@ static struct attribute *gl520_attributes_opt[] = {
667 NULL 738 NULL
668}; 739};
669 740
670static const struct attribute_group gl520_group_opt = { 741static const struct attribute_group gl520_group_in4 = {
671 .attrs = gl520_attributes_opt, 742 .attrs = gl520_attributes_in4,
743};
744
745static const struct attribute_group gl520_group_temp2 = {
746 .attrs = gl520_attributes_temp2,
672}; 747};
673 748
674 749
@@ -717,35 +792,17 @@ static int gl520_probe(struct i2c_client *client,
717 gl520_init_client(client); 792 gl520_init_client(client);
718 793
719 /* Register sysfs hooks */ 794 /* Register sysfs hooks */
720 if ((err = sysfs_create_group(&client->dev.kobj, &gl520_group))) 795 err = sysfs_create_group(&client->dev.kobj, &gl520_group);
796 if (err)
721 goto exit_free; 797 goto exit_free;
722 798
723 if (data->two_temps) { 799 if (data->two_temps)
724 if ((err = device_create_file(&client->dev, 800 err = sysfs_create_group(&client->dev.kobj, &gl520_group_temp2);
725 &sensor_dev_attr_temp2_input.dev_attr)) 801 else
726 || (err = device_create_file(&client->dev, 802 err = sysfs_create_group(&client->dev.kobj, &gl520_group_in4);
727 &sensor_dev_attr_temp2_max.dev_attr))
728 || (err = device_create_file(&client->dev,
729 &sensor_dev_attr_temp2_max_hyst.dev_attr))
730 || (err = device_create_file(&client->dev,
731 &sensor_dev_attr_temp2_alarm.dev_attr))
732 || (err = device_create_file(&client->dev,
733 &sensor_dev_attr_temp2_beep.dev_attr)))
734 goto exit_remove_files;
735 } else {
736 if ((err = device_create_file(&client->dev,
737 &sensor_dev_attr_in4_input.dev_attr))
738 || (err = device_create_file(&client->dev,
739 &sensor_dev_attr_in4_min.dev_attr))
740 || (err = device_create_file(&client->dev,
741 &sensor_dev_attr_in4_max.dev_attr))
742 || (err = device_create_file(&client->dev,
743 &sensor_dev_attr_in4_alarm.dev_attr))
744 || (err = device_create_file(&client->dev,
745 &sensor_dev_attr_in4_beep.dev_attr)))
746 goto exit_remove_files;
747 }
748 803
804 if (err)
805 goto exit_remove_files;
749 806
750 data->hwmon_dev = hwmon_device_register(&client->dev); 807 data->hwmon_dev = hwmon_device_register(&client->dev);
751 if (IS_ERR(data->hwmon_dev)) { 808 if (IS_ERR(data->hwmon_dev)) {
@@ -757,7 +814,8 @@ static int gl520_probe(struct i2c_client *client,
757 814
758exit_remove_files: 815exit_remove_files:
759 sysfs_remove_group(&client->dev.kobj, &gl520_group); 816 sysfs_remove_group(&client->dev.kobj, &gl520_group);
760 sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); 817 sysfs_remove_group(&client->dev.kobj, &gl520_group_in4);
818 sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2);
761exit_free: 819exit_free:
762 kfree(data); 820 kfree(data);
763exit: 821exit:
@@ -809,15 +867,18 @@ static int gl520_remove(struct i2c_client *client)
809 867
810 hwmon_device_unregister(data->hwmon_dev); 868 hwmon_device_unregister(data->hwmon_dev);
811 sysfs_remove_group(&client->dev.kobj, &gl520_group); 869 sysfs_remove_group(&client->dev.kobj, &gl520_group);
812 sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); 870 sysfs_remove_group(&client->dev.kobj, &gl520_group_in4);
871 sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2);
813 872
814 kfree(data); 873 kfree(data);
815 return 0; 874 return 0;
816} 875}
817 876
818 877
819/* Registers 0x07 to 0x0c are word-sized, others are byte-sized 878/*
820 GL520 uses a high-byte first convention */ 879 * Registers 0x07 to 0x0c are word-sized, others are byte-sized
880 * GL520 uses a high-byte first convention
881 */
821static int gl520_read_value(struct i2c_client *client, u8 reg) 882static int gl520_read_value(struct i2c_client *client, u8 reg)
822{ 883{
823 if ((reg >= 0x07) && (reg <= 0x0c)) 884 if ((reg >= 0x07) && (reg <= 0x0c))
@@ -849,7 +910,8 @@ static struct gl520_data *gl520_update_device(struct device *dev)
849 910
850 data->alarms = gl520_read_value(client, GL520_REG_ALARMS); 911 data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
851 data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK); 912 data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
852 data->vid = gl520_read_value(client, GL520_REG_VID_INPUT) & 0x1f; 913 data->vid = gl520_read_value(client,
914 GL520_REG_VID_INPUT) & 0x1f;
853 915
854 for (i = 0; i < 4; i++) { 916 for (i = 0; i < 4; i++) {
855 data->in_input[i] = gl520_read_value(client, 917 data->in_input[i] = gl520_read_value(client,
@@ -910,23 +972,10 @@ static struct gl520_data *gl520_update_device(struct device *dev)
910 return data; 972 return data;
911} 973}
912 974
913 975module_i2c_driver(gl520_driver);
914static int __init sensors_gl520sm_init(void)
915{
916 return i2c_add_driver(&gl520_driver);
917}
918
919static void __exit sensors_gl520sm_exit(void)
920{
921 i2c_del_driver(&gl520_driver);
922}
923
924 976
925MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " 977MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
926 "Kyösti Mälkki <kmalkki@cc.hut.fi>, " 978 "Kyösti Mälkki <kmalkki@cc.hut.fi>, "
927 "Maarten Deprez <maartendeprez@users.sourceforge.net>"); 979 "Maarten Deprez <maartendeprez@users.sourceforge.net>");
928MODULE_DESCRIPTION("GL520SM driver"); 980MODULE_DESCRIPTION("GL520SM driver");
929MODULE_LICENSE("GPL"); 981MODULE_LICENSE("GPL");
930
931module_init(sensors_gl520sm_init);
932module_exit(sensors_gl520sm_exit);