Commit 2fe28ab5 authored by Jean Delvare's avatar Jean Delvare Committed by Jean Delvare

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: default avatarJean Delvare <khali@linux-fr.org>
Tested-by: default avatarGuenter Roeck <guenter.roeck@ericsson.com>
Acked-by: default avatarGuenter Roeck <guenter.roeck@ericsson.com>
parent d216f680
...@@ -203,18 +203,19 @@ struct lm63_data { ...@@ -203,18 +203,19 @@ struct lm63_data {
int update_interval; /* in milliseconds */ int update_interval; /* in milliseconds */
int max_convrate_hz; int max_convrate_hz;
int lut_size; /* 8 or 12 */
/* registers values */ /* registers values */
u8 config, config_fan; u8 config, config_fan;
u16 fan[2]; /* 0: input u16 fan[2]; /* 0: input
1: low limit */ 1: low limit */
u8 pwm1_freq; u8 pwm1_freq;
u8 pwm1[9]; /* 0: current output u8 pwm1[13]; /* 0: current output
1-8: lookup table */ 1-12: lookup table */
s8 temp8[11]; /* 0: local input s8 temp8[15]; /* 0: local input
1: local high limit 1: local high limit
2: remote critical limit 2: remote critical limit
3-10: lookup table */ 3-14: lookup table */
s16 temp11[4]; /* 0: remote input s16 temp11[4]; /* 0: remote input
1: remote low limit 1: remote low limit
2: remote high limit 2: remote high limit
...@@ -653,6 +654,26 @@ static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO, ...@@ -653,6 +654,26 @@ static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO,
show_lut_temp, NULL, 10); show_lut_temp, NULL, 10);
static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO, static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO,
show_lut_temp_hyst, NULL, 10); 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_input, S_IRUGO, show_local_temp8, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8, static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_local_temp8,
...@@ -732,6 +753,26 @@ static struct attribute *lm63_attributes[] = { ...@@ -732,6 +753,26 @@ static struct attribute *lm63_attributes[] = {
NULL 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 * On LM63, temp2_crit can be set only once, which should be job
* of the bootloader. * of the bootloader.
...@@ -861,6 +902,11 @@ static int lm63_probe(struct i2c_client *new_client, ...@@ -861,6 +902,11 @@ static int lm63_probe(struct i2c_client *new_client,
&dev_attr_temp2_type); &dev_attr_temp2_type);
if (err) if (err)
goto exit_remove_files; 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); data->hwmon_dev = hwmon_device_register(&new_client->dev);
...@@ -872,9 +918,13 @@ static int lm63_probe(struct i2c_client *new_client, ...@@ -872,9 +918,13 @@ static int lm63_probe(struct i2c_client *new_client,
return 0; return 0;
exit_remove_files: 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);
sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1); 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: exit_free:
kfree(data); kfree(data);
exit: exit:
...@@ -914,9 +964,11 @@ static void lm63_init_client(struct i2c_client *client) ...@@ -914,9 +964,11 @@ static void lm63_init_client(struct i2c_client *client)
case lm63: case lm63:
case lm64: case lm64:
data->max_convrate_hz = LM63_MAX_CONVRATE_HZ; data->max_convrate_hz = LM63_MAX_CONVRATE_HZ;
data->lut_size = 8;
break; break;
case lm96163: case lm96163:
data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ; data->max_convrate_hz = LM96163_MAX_CONVRATE_HZ;
data->lut_size = 12;
data->trutherm data->trutherm
= i2c_smbus_read_byte_data(client, = i2c_smbus_read_byte_data(client,
LM96163_REG_TRUTHERM) & 0x02; LM96163_REG_TRUTHERM) & 0x02;
...@@ -963,9 +1015,12 @@ static int lm63_remove(struct i2c_client *client) ...@@ -963,9 +1015,12 @@ static int lm63_remove(struct i2c_client *client)
struct lm63_data *data = i2c_get_clientdata(client); struct lm63_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev); 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);
sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1); 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); kfree(data);
return 0; return 0;
...@@ -1046,7 +1101,7 @@ static struct lm63_data *lm63_update_device(struct device *dev) ...@@ -1046,7 +1101,7 @@ static struct lm63_data *lm63_update_device(struct device *dev)
if (time_after(jiffies, data->lut_last_updated + 5 * HZ) || if (time_after(jiffies, data->lut_last_updated + 5 * HZ) ||
!data->lut_valid) { !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, data->pwm1[1 + i] = i2c_smbus_read_byte_data(client,
LM63_REG_LUT_PWM(i)); LM63_REG_LUT_PWM(i));
data->temp8[3 + i] = i2c_smbus_read_byte_data(client, data->temp8[3 + i] = i2c_smbus_read_byte_data(client,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment