diff options
author | Jean Delvare <khali@linux-fr.org> | 2012-01-17 01:51:47 +0400 |
---|---|---|
committer | Jean Delvare <khali@endymion.delvare> | 2012-01-17 01:51:47 +0400 |
commit | 2fe28ab51d200121b9c39f9b34cf2d132fcf5de1 (patch) | |
tree | e3f51eb47a960a2bbd2a517f1c9988daa2c8755f /drivers | |
parent | d216f6809eb690b9a888c286cde68cda4d0c4cfa (diff) | |
download | linux-2fe28ab51d200121b9c39f9b34cf2d132fcf5de1.tar.xz |
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')
-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 { int update_interval; /* in milliseconds */ int max_convrate_hz; + int lut_size; /* 8 or 12 */ /* registers values */ u8 config, config_fan; u16 fan[2]; /* 0: input 1: low limit */ u8 pwm1_freq; - u8 pwm1[9]; /* 0: current output - 1-8: lookup table */ - s8 temp8[11]; /* 0: local input + u8 pwm1[13]; /* 0: current output + 1-12: lookup table */ + s8 temp8[15]; /* 0: local input 1: local high limit 2: remote critical limit - 3-10: lookup table */ + 3-14: lookup table */ s16 temp11[4]; /* 0: remote input 1: remote low limit 2: remote high limit @@ -653,6 +654,26 @@ static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO, show_lut_temp, NULL, 10); static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, show_lut_temp_hyst, NULL, 10); +static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9); +static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO, + show_lut_temp, NULL, 11); +static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 11); +static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10); +static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO, + show_lut_temp, NULL, 12); +static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 12); +static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11); +static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO, + show_lut_temp, NULL, 13); +static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 13); +static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12); +static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO, + show_lut_temp, NULL, 14); +static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO, + show_lut_temp_hyst, NULL, 14); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_local_temp8, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, @@ -732,6 +753,26 @@ static struct attribute *lm63_attributes[] = { NULL }; +static struct attribute *lm63_attributes_extra_lut[] = { + &sensor_dev_attr_pwm1_auto_point9_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point9_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point9_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point10_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point10_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point10_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point11_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point11_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point11_temp_hyst.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point12_pwm.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point12_temp.dev_attr.attr, + &sensor_dev_attr_pwm1_auto_point12_temp_hyst.dev_attr.attr, + NULL +}; + +static const struct attribute_group lm63_group_extra_lut = { + .attrs = lm63_attributes_extra_lut, +}; + /* * On LM63, temp2_crit can be set only once, which should be job * of the bootloader. @@ -861,6 +902,11 @@ static int lm63_probe(struct i2c_client *new_client, &dev_attr_temp2_type); if (err) goto exit_remove_files; + + err = sysfs_create_group(&new_client->dev.kobj, + &lm63_group_extra_lut); + if (err) + goto exit_remove_files; } data->hwmon_dev = hwmon_device_register(&new_client->dev); @@ -872,9 +918,13 @@ static int lm63_probe(struct i2c_client *new_client, return 0; exit_remove_files: - device_remove_file(&new_client->dev, &dev_attr_temp2_type); sysfs_remove_group(&new_client->dev.kobj, &lm63_group); sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); + if (data->kind == lm96163) { + device_remove_file(&new_client->dev, &dev_attr_temp2_type); + sysfs_remove_group(&new_client->dev.kobj, + &lm63_group_extra_lut); + } exit_free: kfree(data); exit: @@ -914,9 +964,11 @@ static void lm63_init_client(struct i2c_client *client) case lm63: case lm64: data->max_convrate_hz = LM63_MAX_CONVRATE_HZ; + data->lut_size = 8; break; case lm96163: data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ; + data->lut_size = 12; data->trutherm = i2c_smbus_read_byte_data(client, LM96163_REG_TRUTHERM) & 0x02; @@ -963,9 +1015,12 @@ static int lm63_remove(struct i2c_client *client) struct lm63_data *data = i2c_get_clientdata(client); hwmon_device_unregister(data->hwmon_dev); - device_remove_file(&client->dev, &dev_attr_temp2_type); sysfs_remove_group(&client->dev.kobj, &lm63_group); sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); + if (data->kind == lm96163) { + device_remove_file(&client->dev, &dev_attr_temp2_type); + sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut); + } kfree(data); return 0; @@ -1046,7 +1101,7 @@ static struct lm63_data *lm63_update_device(struct device *dev) if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || !data->lut_valid) { - for (i = 0; i < 8; i++) { + for (i = 0; i < data->lut_size; i++) { data->pwm1[1 + i] = i2c_smbus_read_byte_data(client, LM63_REG_LUT_PWM(i)); data->temp8[3 + i] = i2c_smbus_read_byte_data(client, |