Loading drivers/hwmon/adm1021.c +106 −88 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/jiffies.h> #include <linux/i2c.h> #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> #include <linux/err.h> #include <linux/mutex.h> Loading @@ -43,8 +44,8 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, /* The adm1021 registers */ /* Read-only */ #define ADM1021_REG_TEMP 0x00 #define ADM1021_REG_REMOTE_TEMP 0x01 /* For nr in 0-1 */ #define ADM1021_REG_TEMP(nr) (nr) #define ADM1021_REG_STATUS 0x02 /* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */ #define ADM1021_REG_MAN_ID 0xFE Loading @@ -62,25 +63,14 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, #define ADM1023_REG_REM_TOS_PREC 0x13 #define ADM1023_REG_REM_THYST_PREC 0x14 /* limits */ #define ADM1021_REG_TOS_R 0x05 #define ADM1021_REG_TOS_W 0x0B #define ADM1021_REG_REMOTE_TOS_R 0x07 #define ADM1021_REG_REMOTE_TOS_W 0x0D #define ADM1021_REG_THYST_R 0x06 #define ADM1021_REG_THYST_W 0x0C #define ADM1021_REG_REMOTE_THYST_R 0x08 #define ADM1021_REG_REMOTE_THYST_W 0x0E /* For nr in 0-1 */ #define ADM1021_REG_TOS_R(nr) (0x05 + 2 * (nr)) #define ADM1021_REG_TOS_W(nr) (0x0B + 2 * (nr)) #define ADM1021_REG_THYST_R(nr) (0x06 + 2 * (nr)) #define ADM1021_REG_THYST_W(nr) (0x0C + 2 * (nr)) /* write-only */ #define ADM1021_REG_ONESHOT 0x0F /* Conversions. Rounding and limit checking is only done on the TO_REG variants. Note that you should be a bit careful with which arguments these macros are called: arguments may be evaluated more than once. Fixing this is just not worth it. */ /* Conversions note: 1021 uses normal integer signed-byte format*/ #define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -128, 127) /* Initial values */ /* Note: Even though I left the low and high limits named os and hyst, Loading @@ -98,12 +88,9 @@ struct adm1021_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ s8 temp_max; /* Register values */ s8 temp_hyst; s8 temp_input; s8 remote_temp_max; s8 remote_temp_hyst; s8 remote_temp_input; s8 temp_max[2]; /* Register values */ s8 temp_min[2]; s8 temp[2]; u8 alarms; /* Special values for ADM1023 only */ u8 remote_temp_prec; Loading Loading @@ -133,19 +120,32 @@ static struct i2c_driver adm1021_driver = { .detach_client = adm1021_detach_client, }; #define show(value) \ static ssize_t show_##value(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct adm1021_data *data = adm1021_update_device(dev); \ return sprintf(buf, "%d\n", 1000 * data->value); \ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, char *buf) { int index = to_sensor_dev_attr(devattr)->index; struct adm1021_data *data = adm1021_update_device(dev); return sprintf(buf, "%d\n", 1000 * data->temp[index]); } static ssize_t show_temp_max(struct device *dev, struct device_attribute *devattr, char *buf) { int index = to_sensor_dev_attr(devattr)->index; struct adm1021_data *data = adm1021_update_device(dev); return sprintf(buf, "%d\n", 1000 * data->temp_max[index]); } static ssize_t show_temp_min(struct device *dev, struct device_attribute *devattr, char *buf) { int index = to_sensor_dev_attr(devattr)->index; struct adm1021_data *data = adm1021_update_device(dev); return sprintf(buf, "%d\n", 1000 * data->temp_min[index]); } show(temp_max); show(temp_hyst); show(temp_input); show(remote_temp_max); show(remote_temp_hyst); show(remote_temp_input); static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, Loading @@ -155,35 +155,55 @@ static ssize_t show_alarms(struct device *dev, return sprintf(buf, "%u\n", data->alarms); } #define set(value, reg) \ static ssize_t set_##value(struct device *dev, \ struct device_attribute *attr, \ const char *buf, size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct adm1021_data *data = i2c_get_clientdata(client); \ long temp = simple_strtol(buf, NULL, 10); \ \ mutex_lock(&data->update_lock); \ data->value = TEMP_TO_REG(temp); \ if (!read_only) \ i2c_smbus_write_byte_data(client, reg, data->value); \ mutex_unlock(&data->update_lock); \ return count; \ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { int index = to_sensor_dev_attr(devattr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1021_data *data = i2c_get_clientdata(client); long temp = simple_strtol(buf, NULL, 10) / 1000; mutex_lock(&data->update_lock); data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127); if (!read_only) i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index), data->temp_max[index]); mutex_unlock(&data->update_lock); return count; } static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { int index = to_sensor_dev_attr(devattr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1021_data *data = i2c_get_clientdata(client); long temp = simple_strtol(buf, NULL, 10) / 1000; mutex_lock(&data->update_lock); data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127); if (!read_only) i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index), data->temp_min[index]); mutex_unlock(&data->update_lock); return count; } set(temp_max, ADM1021_REG_TOS_W); set(temp_hyst, ADM1021_REG_THYST_W); set(remote_temp_max, ADM1021_REG_REMOTE_TOS_W); set(remote_temp_hyst, ADM1021_REG_REMOTE_THYST_W); static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst); static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL); static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_temp_max, set_remote_temp_max); static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_temp_hyst, set_remote_temp_hyst); static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote_temp_input, NULL); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max, 0); static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, set_temp_min, 0); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max, 1); static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, set_temp_min, 1); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static int adm1021_attach_adapter(struct i2c_adapter *adapter) { Loading @@ -193,12 +213,12 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter) } static struct attribute *adm1021_attributes[] = { &dev_attr_temp1_max.attr, &dev_attr_temp1_min.attr, &dev_attr_temp1_input.attr, &dev_attr_temp2_max.attr, &dev_attr_temp2_min.attr, &dev_attr_temp2_input.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_min.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, &sensor_dev_attr_temp2_min.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, &dev_attr_alarms.attr, NULL }; Loading Loading @@ -370,20 +390,18 @@ static struct adm1021_data *adm1021_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { int i; dev_dbg(&client->dev, "Starting adm1021 update\n"); data->temp_input = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP); data->temp_max = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R); data->temp_hyst = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R); data->remote_temp_input = i2c_smbus_read_byte_data(client, ADM1021_REG_REMOTE_TEMP); data->remote_temp_max = i2c_smbus_read_byte_data(client, ADM1021_REG_REMOTE_TOS_R); data->remote_temp_hyst = i2c_smbus_read_byte_data(client, ADM1021_REG_REMOTE_THYST_R); for (i = 0; i < 2; i++) { data->temp[i] = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(i)); data->temp_max[i] = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(i)); data->temp_min[i] = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(i)); } data->alarms = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS) & 0x7c; if (data->type == adm1023) { Loading Loading
drivers/hwmon/adm1021.c +106 −88 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/jiffies.h> #include <linux/i2c.h> #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> #include <linux/err.h> #include <linux/mutex.h> Loading @@ -43,8 +44,8 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, /* The adm1021 registers */ /* Read-only */ #define ADM1021_REG_TEMP 0x00 #define ADM1021_REG_REMOTE_TEMP 0x01 /* For nr in 0-1 */ #define ADM1021_REG_TEMP(nr) (nr) #define ADM1021_REG_STATUS 0x02 /* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */ #define ADM1021_REG_MAN_ID 0xFE Loading @@ -62,25 +63,14 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, #define ADM1023_REG_REM_TOS_PREC 0x13 #define ADM1023_REG_REM_THYST_PREC 0x14 /* limits */ #define ADM1021_REG_TOS_R 0x05 #define ADM1021_REG_TOS_W 0x0B #define ADM1021_REG_REMOTE_TOS_R 0x07 #define ADM1021_REG_REMOTE_TOS_W 0x0D #define ADM1021_REG_THYST_R 0x06 #define ADM1021_REG_THYST_W 0x0C #define ADM1021_REG_REMOTE_THYST_R 0x08 #define ADM1021_REG_REMOTE_THYST_W 0x0E /* For nr in 0-1 */ #define ADM1021_REG_TOS_R(nr) (0x05 + 2 * (nr)) #define ADM1021_REG_TOS_W(nr) (0x0B + 2 * (nr)) #define ADM1021_REG_THYST_R(nr) (0x06 + 2 * (nr)) #define ADM1021_REG_THYST_W(nr) (0x0C + 2 * (nr)) /* write-only */ #define ADM1021_REG_ONESHOT 0x0F /* Conversions. Rounding and limit checking is only done on the TO_REG variants. Note that you should be a bit careful with which arguments these macros are called: arguments may be evaluated more than once. Fixing this is just not worth it. */ /* Conversions note: 1021 uses normal integer signed-byte format*/ #define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -128, 127) /* Initial values */ /* Note: Even though I left the low and high limits named os and hyst, Loading @@ -98,12 +88,9 @@ struct adm1021_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ s8 temp_max; /* Register values */ s8 temp_hyst; s8 temp_input; s8 remote_temp_max; s8 remote_temp_hyst; s8 remote_temp_input; s8 temp_max[2]; /* Register values */ s8 temp_min[2]; s8 temp[2]; u8 alarms; /* Special values for ADM1023 only */ u8 remote_temp_prec; Loading Loading @@ -133,19 +120,32 @@ static struct i2c_driver adm1021_driver = { .detach_client = adm1021_detach_client, }; #define show(value) \ static ssize_t show_##value(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ struct adm1021_data *data = adm1021_update_device(dev); \ return sprintf(buf, "%d\n", 1000 * data->value); \ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, char *buf) { int index = to_sensor_dev_attr(devattr)->index; struct adm1021_data *data = adm1021_update_device(dev); return sprintf(buf, "%d\n", 1000 * data->temp[index]); } static ssize_t show_temp_max(struct device *dev, struct device_attribute *devattr, char *buf) { int index = to_sensor_dev_attr(devattr)->index; struct adm1021_data *data = adm1021_update_device(dev); return sprintf(buf, "%d\n", 1000 * data->temp_max[index]); } static ssize_t show_temp_min(struct device *dev, struct device_attribute *devattr, char *buf) { int index = to_sensor_dev_attr(devattr)->index; struct adm1021_data *data = adm1021_update_device(dev); return sprintf(buf, "%d\n", 1000 * data->temp_min[index]); } show(temp_max); show(temp_hyst); show(temp_input); show(remote_temp_max); show(remote_temp_hyst); show(remote_temp_input); static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, Loading @@ -155,35 +155,55 @@ static ssize_t show_alarms(struct device *dev, return sprintf(buf, "%u\n", data->alarms); } #define set(value, reg) \ static ssize_t set_##value(struct device *dev, \ struct device_attribute *attr, \ const char *buf, size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct adm1021_data *data = i2c_get_clientdata(client); \ long temp = simple_strtol(buf, NULL, 10); \ \ mutex_lock(&data->update_lock); \ data->value = TEMP_TO_REG(temp); \ if (!read_only) \ i2c_smbus_write_byte_data(client, reg, data->value); \ mutex_unlock(&data->update_lock); \ return count; \ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { int index = to_sensor_dev_attr(devattr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1021_data *data = i2c_get_clientdata(client); long temp = simple_strtol(buf, NULL, 10) / 1000; mutex_lock(&data->update_lock); data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127); if (!read_only) i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index), data->temp_max[index]); mutex_unlock(&data->update_lock); return count; } static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { int index = to_sensor_dev_attr(devattr)->index; struct i2c_client *client = to_i2c_client(dev); struct adm1021_data *data = i2c_get_clientdata(client); long temp = simple_strtol(buf, NULL, 10) / 1000; mutex_lock(&data->update_lock); data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127); if (!read_only) i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index), data->temp_min[index]); mutex_unlock(&data->update_lock); return count; } set(temp_max, ADM1021_REG_TOS_W); set(temp_hyst, ADM1021_REG_THYST_W); set(remote_temp_max, ADM1021_REG_REMOTE_TOS_W); set(remote_temp_hyst, ADM1021_REG_REMOTE_THYST_W); static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst); static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL); static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_temp_max, set_remote_temp_max); static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_temp_hyst, set_remote_temp_hyst); static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote_temp_input, NULL); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max, 0); static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, set_temp_min, 0); static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max, 1); static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, set_temp_min, 1); static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static int adm1021_attach_adapter(struct i2c_adapter *adapter) { Loading @@ -193,12 +213,12 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter) } static struct attribute *adm1021_attributes[] = { &dev_attr_temp1_max.attr, &dev_attr_temp1_min.attr, &dev_attr_temp1_input.attr, &dev_attr_temp2_max.attr, &dev_attr_temp2_min.attr, &dev_attr_temp2_input.attr, &sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_min.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp2_max.dev_attr.attr, &sensor_dev_attr_temp2_min.dev_attr.attr, &sensor_dev_attr_temp2_input.dev_attr.attr, &dev_attr_alarms.attr, NULL }; Loading Loading @@ -370,20 +390,18 @@ static struct adm1021_data *adm1021_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { int i; dev_dbg(&client->dev, "Starting adm1021 update\n"); data->temp_input = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP); data->temp_max = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R); data->temp_hyst = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R); data->remote_temp_input = i2c_smbus_read_byte_data(client, ADM1021_REG_REMOTE_TEMP); data->remote_temp_max = i2c_smbus_read_byte_data(client, ADM1021_REG_REMOTE_TOS_R); data->remote_temp_hyst = i2c_smbus_read_byte_data(client, ADM1021_REG_REMOTE_THYST_R); for (i = 0; i < 2; i++) { data->temp[i] = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(i)); data->temp_max[i] = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(i)); data->temp_min[i] = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(i)); } data->alarms = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS) & 0x7c; if (data->type == adm1023) { Loading