diff options
author | Jean Delvare <khali@linux-fr.org> | 2012-01-16 16:51:47 -0500 |
---|---|---|
committer | Jean Delvare <khali@endymion.delvare> | 2012-01-16 16:51:47 -0500 |
commit | 2fe28ab51d200121b9c39f9b34cf2d132fcf5de1 (patch) | |
tree | e3f51eb47a960a2bbd2a517f1c9988daa2c8755f /drivers/hwmon/lm63.c | |
parent | d216f6809eb690b9a888c286cde68cda4d0c4cfa (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.c | 69 |
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); |
654 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, | 655 | static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, |
655 | show_lut_temp_hyst, NULL, 10); | 656 | show_lut_temp_hyst, NULL, 10); |
657 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9); | ||
658 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO, | ||
659 | show_lut_temp, NULL, 11); | ||
660 | static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO, | ||
661 | show_lut_temp_hyst, NULL, 11); | ||
662 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10); | ||
663 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO, | ||
664 | show_lut_temp, NULL, 12); | ||
665 | static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO, | ||
666 | show_lut_temp_hyst, NULL, 12); | ||
667 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11); | ||
668 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO, | ||
669 | show_lut_temp, NULL, 13); | ||
670 | static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO, | ||
671 | show_lut_temp_hyst, NULL, 13); | ||
672 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12); | ||
673 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO, | ||
674 | show_lut_temp, NULL, 14); | ||
675 | static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO, | ||
676 | show_lut_temp_hyst, NULL, 14); | ||
656 | 677 | ||
657 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); | 678 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); |
658 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, | 679 | static 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 | ||
756 | static 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 | |||
772 | static 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 | ||
874 | exit_remove_files: | 920 | exit_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 | } | ||
878 | exit_free: | 928 | exit_free: |
879 | kfree(data); | 929 | kfree(data); |
880 | exit: | 930 | exit: |
@@ -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, |