aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/lm63.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2012-01-16 16:51:47 -0500
committerJean Delvare <khali@endymion.delvare>2012-01-16 16:51:47 -0500
commit2fe28ab51d200121b9c39f9b34cf2d132fcf5de1 (patch)
treee3f51eb47a960a2bbd2a517f1c9988daa2c8755f /drivers/hwmon/lm63.c
parentd216f6809eb690b9a888c286cde68cda4d0c4cfa (diff)
hwmon: (lm63) Support extended lookup table of LM96163
The LM96163 has an extended lookup table with 12 entries instead of 8, add support for that. Signed-off-by: Jean Delvare <khali@linux-fr.org> Tested-by: Guenter Roeck <guenter.roeck@ericsson.com> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/lm63.c')
-rw-r--r--drivers/hwmon/lm63.c69
1 files changed, 62 insertions, 7 deletions
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 1c06a333ba20..5e6457a6644d 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -203,18 +203,19 @@ struct lm63_data {
203 203
204 int update_interval; /* in milliseconds */ 204 int update_interval; /* in milliseconds */
205 int max_convrate_hz; 205 int max_convrate_hz;
206 int lut_size; /* 8 or 12 */
206 207
207 /* registers values */ 208 /* registers values */
208 u8 config, config_fan; 209 u8 config, config_fan;
209 u16 fan[2]; /* 0: input 210 u16 fan[2]; /* 0: input
210 1: low limit */ 211 1: low limit */
211 u8 pwm1_freq; 212 u8 pwm1_freq;
212 u8 pwm1[9]; /* 0: current output 213 u8 pwm1[13]; /* 0: current output
213 1-8: lookup table */ 214 1-12: lookup table */
214 s8 temp8[11]; /* 0: local input 215 s8 temp8[15]; /* 0: local input
215 1: local high limit 216 1: local high limit
216 2: remote critical limit 217 2: remote critical limit
217 3-10: lookup table */ 218 3-14: lookup table */
218 s16 temp11[4]; /* 0: remote input 219 s16 temp11[4]; /* 0: remote input
219 1: remote low limit 220 1: remote low limit
220 2: remote high limit 221 2: remote high limit
@@ -653,6 +654,26 @@ static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO,
653 show_lut_temp, NULL, 10); 654 show_lut_temp, NULL, 10);
654static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, 655static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO,
655 show_lut_temp_hyst, NULL, 10); 656 show_lut_temp_hyst, NULL, 10);
657static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9);
658static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO,
659 show_lut_temp, NULL, 11);
660static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO,
661 show_lut_temp_hyst, NULL, 11);
662static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10);
663static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO,
664 show_lut_temp, NULL, 12);
665static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO,
666 show_lut_temp_hyst, NULL, 12);
667static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11);
668static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO,
669 show_lut_temp, NULL, 13);
670static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO,
671 show_lut_temp_hyst, NULL, 13);
672static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12);
673static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO,
674 show_lut_temp, NULL, 14);
675static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO,
676 show_lut_temp_hyst, NULL, 14);
656 677
657static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); 678static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0);
658static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, 679static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8,
@@ -732,6 +753,26 @@ static struct attribute *lm63_attributes[] = {
732 NULL 753 NULL
733}; 754};
734 755
756static struct attribute *lm63_attributes_extra_lut[] = {
757 &sensor_dev_attr_pwm1_auto_point9_pwm.dev_attr.attr,
758 &sensor_dev_attr_pwm1_auto_point9_temp.dev_attr.attr,
759 &sensor_dev_attr_pwm1_auto_point9_temp_hyst.dev_attr.attr,
760 &sensor_dev_attr_pwm1_auto_point10_pwm.dev_attr.attr,
761 &sensor_dev_attr_pwm1_auto_point10_temp.dev_attr.attr,
762 &sensor_dev_attr_pwm1_auto_point10_temp_hyst.dev_attr.attr,
763 &sensor_dev_attr_pwm1_auto_point11_pwm.dev_attr.attr,
764 &sensor_dev_attr_pwm1_auto_point11_temp.dev_attr.attr,
765 &sensor_dev_attr_pwm1_auto_point11_temp_hyst.dev_attr.attr,
766 &sensor_dev_attr_pwm1_auto_point12_pwm.dev_attr.attr,
767 &sensor_dev_attr_pwm1_auto_point12_temp.dev_attr.attr,
768 &sensor_dev_attr_pwm1_auto_point12_temp_hyst.dev_attr.attr,
769 NULL
770};
771
772static const struct attribute_group lm63_group_extra_lut = {
773 .attrs = lm63_attributes_extra_lut,
774};
775
735/* 776/*
736 * On LM63, temp2_crit can be set only once, which should be job 777 * On LM63, temp2_crit can be set only once, which should be job
737 * of the bootloader. 778 * of the bootloader.
@@ -861,6 +902,11 @@ static int lm63_probe(struct i2c_client *new_client,
861 &dev_attr_temp2_type); 902 &dev_attr_temp2_type);
862 if (err) 903 if (err)
863 goto exit_remove_files; 904 goto exit_remove_files;
905
906 err = sysfs_create_group(&new_client->dev.kobj,
907 &lm63_group_extra_lut);
908 if (err)
909 goto exit_remove_files;
864 } 910 }
865 911
866 data->hwmon_dev = hwmon_device_register(&new_client->dev); 912 data->hwmon_dev = hwmon_device_register(&new_client->dev);
@@ -872,9 +918,13 @@ static int lm63_probe(struct i2c_client *new_client,
872 return 0; 918 return 0;
873 919
874exit_remove_files: 920exit_remove_files:
875 device_remove_file(&new_client->dev, &dev_attr_temp2_type);
876 sysfs_remove_group(&new_client->dev.kobj, &lm63_group); 921 sysfs_remove_group(&new_client->dev.kobj, &lm63_group);
877 sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); 922 sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1);
923 if (data->kind == lm96163) {
924 device_remove_file(&new_client->dev, &dev_attr_temp2_type);
925 sysfs_remove_group(&new_client->dev.kobj,
926 &lm63_group_extra_lut);
927 }
878exit_free: 928exit_free:
879 kfree(data); 929 kfree(data);
880exit: 930exit:
@@ -914,9 +964,11 @@ static void lm63_init_client(struct i2c_client *client)
914 case lm63: 964 case lm63:
915 case lm64: 965 case lm64:
916 data->max_convrate_hz = LM63_MAX_CONVRATE_HZ; 966 data->max_convrate_hz = LM63_MAX_CONVRATE_HZ;
967 data->lut_size = 8;
917 break; 968 break;
918 case lm96163: 969 case lm96163:
919 data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ; 970 data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ;
971 data->lut_size = 12;
920 data->trutherm 972 data->trutherm
921 = i2c_smbus_read_byte_data(client, 973 = i2c_smbus_read_byte_data(client,
922 LM96163_REG_TRUTHERM) & 0x02; 974 LM96163_REG_TRUTHERM) & 0x02;
@@ -963,9 +1015,12 @@ static int lm63_remove(struct i2c_client *client)
963 struct lm63_data *data = i2c_get_clientdata(client); 1015 struct lm63_data *data = i2c_get_clientdata(client);
964 1016
965 hwmon_device_unregister(data->hwmon_dev); 1017 hwmon_device_unregister(data->hwmon_dev);
966 device_remove_file(&client->dev, &dev_attr_temp2_type);
967 sysfs_remove_group(&client->dev.kobj, &lm63_group); 1018 sysfs_remove_group(&client->dev.kobj, &lm63_group);
968 sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); 1019 sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
1020 if (data->kind == lm96163) {
1021 device_remove_file(&client->dev, &dev_attr_temp2_type);
1022 sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut);
1023 }
969 1024
970 kfree(data); 1025 kfree(data);
971 return 0; 1026 return 0;
@@ -1046,7 +1101,7 @@ static struct lm63_data *lm63_update_device(struct device *dev)
1046 1101
1047 if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || 1102 if (time_after(jiffies, data->lut_last_updated + 5 * HZ) ||
1048 !data->lut_valid) { 1103 !data->lut_valid) {
1049 for (i = 0; i < 8; i++) { 1104 for (i = 0; i < data->lut_size; i++) {
1050 data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, 1105 data->pwm1[1 + i] = i2c_smbus_read_byte_data(client,
1051 LM63_REG_LUT_PWM(i)); 1106 LM63_REG_LUT_PWM(i));
1052 data->temp8[3 + i] = i2c_smbus_read_byte_data(client, 1107 data->temp8[3 + i] = i2c_smbus_read_byte_data(client,