Skip to content

Commit

Permalink
hwmon: (lm63) Support extended lookup table of LM96163
Browse files Browse the repository at this point in the history
The LM96163 has an extended lookup table with 12 entries instead of 8,
add support for that.

Signed-off-by: Jean Delvare <[email protected]>
Tested-by: Guenter Roeck <[email protected]>
Acked-by: Guenter Roeck <[email protected]>
  • Loading branch information
Jean Delvare authored and Jean Delvare committed Jan 16, 2012
1 parent d216f68 commit 2fe28ab
Showing 1 changed file with 62 additions and 7 deletions.
69 changes: 62 additions & 7 deletions drivers/hwmon/lm63.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand All @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 2fe28ab

Please sign in to comment.