aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adm1021.c
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2007-09-09 13:51:14 -0400
committerMark M. Hoffman <mhoffman@lightlink.com>2007-10-09 22:56:31 -0400
commita8d6646e24fa72de38de5838df8bd1f21af59710 (patch)
tree61ebbed4ea0f7d693ed92a77a592cd4ea7892fae /drivers/hwmon/adm1021.c
parentbba891c24a77419e9dcf76f866bd0d8ecf66d770 (diff)
hwmon: (adm1021) dynamic sysfs callbacks conversion
This is conversion of the driver to the dynamic sysfs callbacks. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Acked-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
Diffstat (limited to 'drivers/hwmon/adm1021.c')
-rw-r--r--drivers/hwmon/adm1021.c194
1 files changed, 106 insertions, 88 deletions
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index 5667630ac05a..cc4097094282 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -25,6 +25,7 @@
25#include <linux/jiffies.h> 25#include <linux/jiffies.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/hwmon.h> 27#include <linux/hwmon.h>
28#include <linux/hwmon-sysfs.h>
28#include <linux/err.h> 29#include <linux/err.h>
29#include <linux/mutex.h> 30#include <linux/mutex.h>
30 31
@@ -43,8 +44,8 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
43 44
44/* The adm1021 registers */ 45/* The adm1021 registers */
45/* Read-only */ 46/* Read-only */
46#define ADM1021_REG_TEMP 0x00 47/* For nr in 0-1 */
47#define ADM1021_REG_REMOTE_TEMP 0x01 48#define ADM1021_REG_TEMP(nr) (nr)
48#define ADM1021_REG_STATUS 0x02 49#define ADM1021_REG_STATUS 0x02
49/* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */ 50/* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */
50#define ADM1021_REG_MAN_ID 0xFE 51#define ADM1021_REG_MAN_ID 0xFE
@@ -62,25 +63,14 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
62#define ADM1023_REG_REM_TOS_PREC 0x13 63#define ADM1023_REG_REM_TOS_PREC 0x13
63#define ADM1023_REG_REM_THYST_PREC 0x14 64#define ADM1023_REG_REM_THYST_PREC 0x14
64/* limits */ 65/* limits */
65#define ADM1021_REG_TOS_R 0x05 66/* For nr in 0-1 */
66#define ADM1021_REG_TOS_W 0x0B 67#define ADM1021_REG_TOS_R(nr) (0x05 + 2 * (nr))
67#define ADM1021_REG_REMOTE_TOS_R 0x07 68#define ADM1021_REG_TOS_W(nr) (0x0B + 2 * (nr))
68#define ADM1021_REG_REMOTE_TOS_W 0x0D 69#define ADM1021_REG_THYST_R(nr) (0x06 + 2 * (nr))
69#define ADM1021_REG_THYST_R 0x06 70#define ADM1021_REG_THYST_W(nr) (0x0C + 2 * (nr))
70#define ADM1021_REG_THYST_W 0x0C
71#define ADM1021_REG_REMOTE_THYST_R 0x08
72#define ADM1021_REG_REMOTE_THYST_W 0x0E
73/* write-only */ 71/* write-only */
74#define ADM1021_REG_ONESHOT 0x0F 72#define ADM1021_REG_ONESHOT 0x0F
75 73
76
77/* Conversions. Rounding and limit checking is only done on the TO_REG
78 variants. Note that you should be a bit careful with which arguments
79 these macros are called: arguments may be evaluated more than once.
80 Fixing this is just not worth it. */
81/* Conversions note: 1021 uses normal integer signed-byte format*/
82#define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -128, 127)
83
84/* Initial values */ 74/* Initial values */
85 75
86/* Note: Even though I left the low and high limits named os and hyst, 76/* Note: Even though I left the low and high limits named os and hyst,
@@ -98,19 +88,16 @@ struct adm1021_data {
98 char valid; /* !=0 if following fields are valid */ 88 char valid; /* !=0 if following fields are valid */
99 unsigned long last_updated; /* In jiffies */ 89 unsigned long last_updated; /* In jiffies */
100 90
101 s8 temp_max; /* Register values */ 91 s8 temp_max[2]; /* Register values */
102 s8 temp_hyst; 92 s8 temp_min[2];
103 s8 temp_input; 93 s8 temp[2];
104 s8 remote_temp_max; 94 u8 alarms;
105 s8 remote_temp_hyst; 95 /* Special values for ADM1023 only */
106 s8 remote_temp_input; 96 u8 remote_temp_prec;
107 u8 alarms; 97 u8 remote_temp_os_prec;
108 /* Special values for ADM1023 only */ 98 u8 remote_temp_hyst_prec;
109 u8 remote_temp_prec; 99 u8 remote_temp_offset;
110 u8 remote_temp_os_prec; 100 u8 remote_temp_offset_prec;
111 u8 remote_temp_hyst_prec;
112 u8 remote_temp_offset;
113 u8 remote_temp_offset_prec;
114}; 101};
115 102
116static int adm1021_attach_adapter(struct i2c_adapter *adapter); 103static int adm1021_attach_adapter(struct i2c_adapter *adapter);
@@ -133,19 +120,32 @@ static struct i2c_driver adm1021_driver = {
133 .detach_client = adm1021_detach_client, 120 .detach_client = adm1021_detach_client,
134}; 121};
135 122
136#define show(value) \ 123static ssize_t show_temp(struct device *dev,
137static ssize_t show_##value(struct device *dev, \ 124 struct device_attribute *devattr, char *buf)
138 struct device_attribute *attr, char *buf) \ 125{
139{ \ 126 int index = to_sensor_dev_attr(devattr)->index;
140 struct adm1021_data *data = adm1021_update_device(dev); \ 127 struct adm1021_data *data = adm1021_update_device(dev);
141 return sprintf(buf, "%d\n", 1000 * data->value); \ 128
129 return sprintf(buf, "%d\n", 1000 * data->temp[index]);
130}
131
132static ssize_t show_temp_max(struct device *dev,
133 struct device_attribute *devattr, char *buf)
134{
135 int index = to_sensor_dev_attr(devattr)->index;
136 struct adm1021_data *data = adm1021_update_device(dev);
137
138 return sprintf(buf, "%d\n", 1000 * data->temp_max[index]);
139}
140
141static ssize_t show_temp_min(struct device *dev,
142 struct device_attribute *devattr, char *buf)
143{
144 int index = to_sensor_dev_attr(devattr)->index;
145 struct adm1021_data *data = adm1021_update_device(dev);
146
147 return sprintf(buf, "%d\n", 1000 * data->temp_min[index]);
142} 148}
143show(temp_max);
144show(temp_hyst);
145show(temp_input);
146show(remote_temp_max);
147show(remote_temp_hyst);
148show(remote_temp_input);
149 149
150static ssize_t show_alarms(struct device *dev, 150static ssize_t show_alarms(struct device *dev,
151 struct device_attribute *attr, 151 struct device_attribute *attr,
@@ -155,35 +155,55 @@ static ssize_t show_alarms(struct device *dev,
155 return sprintf(buf, "%u\n", data->alarms); 155 return sprintf(buf, "%u\n", data->alarms);
156} 156}
157 157
158#define set(value, reg) \ 158static ssize_t set_temp_max(struct device *dev,
159static ssize_t set_##value(struct device *dev, \ 159 struct device_attribute *devattr,
160 struct device_attribute *attr, \ 160 const char *buf, size_t count)
161 const char *buf, size_t count) \ 161{
162{ \ 162 int index = to_sensor_dev_attr(devattr)->index;
163 struct i2c_client *client = to_i2c_client(dev); \ 163 struct i2c_client *client = to_i2c_client(dev);
164 struct adm1021_data *data = i2c_get_clientdata(client); \ 164 struct adm1021_data *data = i2c_get_clientdata(client);
165 long temp = simple_strtol(buf, NULL, 10); \ 165 long temp = simple_strtol(buf, NULL, 10) / 1000;
166 \ 166
167 mutex_lock(&data->update_lock); \ 167 mutex_lock(&data->update_lock);
168 data->value = TEMP_TO_REG(temp); \ 168 data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127);
169 if (!read_only) \ 169 if (!read_only)
170 i2c_smbus_write_byte_data(client, reg, data->value); \ 170 i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index),
171 mutex_unlock(&data->update_lock); \ 171 data->temp_max[index]);
172 return count; \ 172 mutex_unlock(&data->update_lock);
173
174 return count;
173} 175}
174set(temp_max, ADM1021_REG_TOS_W);
175set(temp_hyst, ADM1021_REG_THYST_W);
176set(remote_temp_max, ADM1021_REG_REMOTE_TOS_W);
177set(remote_temp_hyst, ADM1021_REG_REMOTE_THYST_W);
178
179static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
180static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
181static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL);
182static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_temp_max, set_remote_temp_max);
183static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_temp_hyst, set_remote_temp_hyst);
184static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote_temp_input, NULL);
185static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
186 176
177static ssize_t set_temp_min(struct device *dev,
178 struct device_attribute *devattr,
179 const char *buf, size_t count)
180{
181 int index = to_sensor_dev_attr(devattr)->index;
182 struct i2c_client *client = to_i2c_client(dev);
183 struct adm1021_data *data = i2c_get_clientdata(client);
184 long temp = simple_strtol(buf, NULL, 10) / 1000;
185
186 mutex_lock(&data->update_lock);
187 data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127);
188 if (!read_only)
189 i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index),
190 data->temp_min[index]);
191 mutex_unlock(&data->update_lock);
192
193 return count;
194}
195
196static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
197static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
198 set_temp_max, 0);
199static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min,
200 set_temp_min, 0);
201static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
202static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
203 set_temp_max, 1);
204static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min,
205 set_temp_min, 1);
206static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
187 207
188static int adm1021_attach_adapter(struct i2c_adapter *adapter) 208static int adm1021_attach_adapter(struct i2c_adapter *adapter)
189{ 209{
@@ -193,12 +213,12 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter)
193} 213}
194 214
195static struct attribute *adm1021_attributes[] = { 215static struct attribute *adm1021_attributes[] = {
196 &dev_attr_temp1_max.attr, 216 &sensor_dev_attr_temp1_max.dev_attr.attr,
197 &dev_attr_temp1_min.attr, 217 &sensor_dev_attr_temp1_min.dev_attr.attr,
198 &dev_attr_temp1_input.attr, 218 &sensor_dev_attr_temp1_input.dev_attr.attr,
199 &dev_attr_temp2_max.attr, 219 &sensor_dev_attr_temp2_max.dev_attr.attr,
200 &dev_attr_temp2_min.attr, 220 &sensor_dev_attr_temp2_min.dev_attr.attr,
201 &dev_attr_temp2_input.attr, 221 &sensor_dev_attr_temp2_input.dev_attr.attr,
202 &dev_attr_alarms.attr, 222 &dev_attr_alarms.attr,
203 NULL 223 NULL
204}; 224};
@@ -370,20 +390,18 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
370 390
371 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 391 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
372 || !data->valid) { 392 || !data->valid) {
393 int i;
394
373 dev_dbg(&client->dev, "Starting adm1021 update\n"); 395 dev_dbg(&client->dev, "Starting adm1021 update\n");
374 396
375 data->temp_input = i2c_smbus_read_byte_data(client, 397 for (i = 0; i < 2; i++) {
376 ADM1021_REG_TEMP); 398 data->temp[i] = i2c_smbus_read_byte_data(client,
377 data->temp_max = i2c_smbus_read_byte_data(client, 399 ADM1021_REG_TEMP(i));
378 ADM1021_REG_TOS_R); 400 data->temp_max[i] = i2c_smbus_read_byte_data(client,
379 data->temp_hyst = i2c_smbus_read_byte_data(client, 401 ADM1021_REG_TOS_R(i));
380 ADM1021_REG_THYST_R); 402 data->temp_min[i] = i2c_smbus_read_byte_data(client,
381 data->remote_temp_input = i2c_smbus_read_byte_data(client, 403 ADM1021_REG_THYST_R(i));
382 ADM1021_REG_REMOTE_TEMP); 404 }
383 data->remote_temp_max = i2c_smbus_read_byte_data(client,
384 ADM1021_REG_REMOTE_TOS_R);
385 data->remote_temp_hyst = i2c_smbus_read_byte_data(client,
386 ADM1021_REG_REMOTE_THYST_R);
387 data->alarms = i2c_smbus_read_byte_data(client, 405 data->alarms = i2c_smbus_read_byte_data(client,
388 ADM1021_REG_STATUS) & 0x7c; 406 ADM1021_REG_STATUS) & 0x7c;
389 if (data->type == adm1023) { 407 if (data->type == adm1023) {