aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/adm1021.c226
1 files changed, 122 insertions, 104 deletions
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index c466329b2ef4..5418a675bb60 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -1,6 +1,6 @@
1/* 1/*
2 adm1021.c - Part of lm_sensors, Linux kernel modules for hardware 2 adm1021.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring 3 monitoring
4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and 4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
5 Philip Edelbrock <phil@netroedge.com> 5 Philip Edelbrock <phil@netroedge.com>
6 6
@@ -32,11 +32,12 @@
32/* Addresses to scan */ 32/* Addresses to scan */
33static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a, 33static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
34 0x29, 0x2a, 0x2b, 34 0x29, 0x2a, 0x2b,
35 0x4c, 0x4d, 0x4e, 35 0x4c, 0x4d, 0x4e,
36 I2C_CLIENT_END }; 36 I2C_CLIENT_END };
37 37
38/* Insmod parameters */ 38/* Insmod parameters */
39I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066); 39I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
40 mc1066);
40 41
41/* adm1021 constants specified below */ 42/* adm1021 constants specified below */
42 43
@@ -45,20 +46,21 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
45#define ADM1021_REG_TEMP 0x00 46#define ADM1021_REG_TEMP 0x00
46#define ADM1021_REG_REMOTE_TEMP 0x01 47#define ADM1021_REG_REMOTE_TEMP 0x01
47#define ADM1021_REG_STATUS 0x02 48#define ADM1021_REG_STATUS 0x02
48#define ADM1021_REG_MAN_ID 0x0FE /* 0x41 = AMD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi*/ 49/* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */
49#define ADM1021_REG_DEV_ID 0x0FF /* ADM1021 = 0x0X, ADM1023 = 0x3X */ 50#define ADM1021_REG_MAN_ID 0xFE
50#define ADM1021_REG_DIE_CODE 0x0FF /* MAX1617A */ 51/* ADM1021 = 0x0X, ADM1023 = 0x3X */
52#define ADM1021_REG_DEV_ID 0xFF
51/* These use different addresses for reading/writing */ 53/* These use different addresses for reading/writing */
52#define ADM1021_REG_CONFIG_R 0x03 54#define ADM1021_REG_CONFIG_R 0x03
53#define ADM1021_REG_CONFIG_W 0x09 55#define ADM1021_REG_CONFIG_W 0x09
54#define ADM1021_REG_CONV_RATE_R 0x04 56#define ADM1021_REG_CONV_RATE_R 0x04
55#define ADM1021_REG_CONV_RATE_W 0x0A 57#define ADM1021_REG_CONV_RATE_W 0x0A
56/* These are for the ADM1023's additional precision on the remote temp sensor */ 58/* These are for the ADM1023's additional precision on the remote temp sensor */
57#define ADM1021_REG_REM_TEMP_PREC 0x010 59#define ADM1023_REG_REM_TEMP_PREC 0x10
58#define ADM1021_REG_REM_OFFSET 0x011 60#define ADM1023_REG_REM_OFFSET 0x11
59#define ADM1021_REG_REM_OFFSET_PREC 0x012 61#define ADM1023_REG_REM_OFFSET_PREC 0x12
60#define ADM1021_REG_REM_TOS_PREC 0x013 62#define ADM1023_REG_REM_TOS_PREC 0x13
61#define ADM1021_REG_REM_THYST_PREC 0x014 63#define ADM1023_REG_REM_THYST_PREC 0x14
62/* limits */ 64/* limits */
63#define ADM1021_REG_TOS_R 0x05 65#define ADM1021_REG_TOS_R 0x05
64#define ADM1021_REG_TOS_W 0x0B 66#define ADM1021_REG_TOS_W 0x0B
@@ -77,14 +79,13 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
77 these macros are called: arguments may be evaluated more than once. 79 these macros are called: arguments may be evaluated more than once.
78 Fixing this is just not worth it. */ 80 Fixing this is just not worth it. */
79/* Conversions note: 1021 uses normal integer signed-byte format*/ 81/* Conversions note: 1021 uses normal integer signed-byte format*/
80#define TEMP_FROM_REG(val) (val > 127 ? (val-256)*1000 : val*1000) 82#define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -128, 127)
81#define TEMP_TO_REG(val) (SENSORS_LIMIT((val < 0 ? (val/1000)+256 : val/1000),0,255))
82 83
83/* Initial values */ 84/* Initial values */
84 85
85/* Note: Even though I left the low and high limits named os and hyst, 86/* Note: Even though I left the low and high limits named os and hyst,
86they don't quite work like a thermostat the way the LM75 does. I.e., 87they don't quite work like a thermostat the way the LM75 does. I.e.,
87a lower temp than THYST actually triggers an alarm instead of 88a lower temp than THYST actually triggers an alarm instead of
88clearing it. Weird, ey? --Phil */ 89clearing it. Weird, ey? --Phil */
89 90
90/* Each client has this additional data */ 91/* Each client has this additional data */
@@ -97,12 +98,12 @@ struct adm1021_data {
97 char valid; /* !=0 if following fields are valid */ 98 char valid; /* !=0 if following fields are valid */
98 unsigned long last_updated; /* In jiffies */ 99 unsigned long last_updated; /* In jiffies */
99 100
100 u8 temp_max; /* Register values */ 101 s8 temp_max; /* Register values */
101 u8 temp_hyst; 102 s8 temp_hyst;
102 u8 temp_input; 103 s8 temp_input;
103 u8 remote_temp_max; 104 s8 remote_temp_max;
104 u8 remote_temp_hyst; 105 s8 remote_temp_hyst;
105 u8 remote_temp_input; 106 s8 remote_temp_input;
106 u8 alarms; 107 u8 alarms;
107 /* Special values for ADM1023 only */ 108 /* Special values for ADM1023 only */
108 u8 remote_temp_prec; 109 u8 remote_temp_prec;
@@ -116,9 +117,6 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter);
116static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind); 117static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind);
117static void adm1021_init_client(struct i2c_client *client); 118static void adm1021_init_client(struct i2c_client *client);
118static int adm1021_detach_client(struct i2c_client *client); 119static int adm1021_detach_client(struct i2c_client *client);
119static int adm1021_read_value(struct i2c_client *client, u8 reg);
120static int adm1021_write_value(struct i2c_client *client, u8 reg,
121 u16 value);
122static struct adm1021_data *adm1021_update_device(struct device *dev); 120static struct adm1021_data *adm1021_update_device(struct device *dev);
123 121
124/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ 122/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
@@ -135,11 +133,12 @@ static struct i2c_driver adm1021_driver = {
135 .detach_client = adm1021_detach_client, 133 .detach_client = adm1021_detach_client,
136}; 134};
137 135
138#define show(value) \ 136#define show(value) \
139static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ 137static ssize_t show_##value(struct device *dev, \
138 struct device_attribute *attr, char *buf) \
140{ \ 139{ \
141 struct adm1021_data *data = adm1021_update_device(dev); \ 140 struct adm1021_data *data = adm1021_update_device(dev); \
142 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ 141 return sprintf(buf, "%d\n", 1000 * data->value); \
143} 142}
144show(temp_max); 143show(temp_max);
145show(temp_hyst); 144show(temp_hyst);
@@ -148,26 +147,29 @@ show(remote_temp_max);
148show(remote_temp_hyst); 147show(remote_temp_hyst);
149show(remote_temp_input); 148show(remote_temp_input);
150 149
151#define show2(value) \ 150static ssize_t show_alarms(struct device *dev,
152static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ 151 struct device_attribute *attr,
153{ \ 152 char *buf)
154 struct adm1021_data *data = adm1021_update_device(dev); \ 153{
155 return sprintf(buf, "%d\n", data->value); \ 154 struct adm1021_data *data = adm1021_update_device(dev);
155 return sprintf(buf, "%u\n", data->alarms);
156} 156}
157show2(alarms); 157
158 158#define set(value, reg) \
159#define set(value, reg) \ 159static ssize_t set_##value(struct device *dev, \
160static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ 160 struct device_attribute *attr, \
161{ \ 161 const char *buf, size_t count) \
162 struct i2c_client *client = to_i2c_client(dev); \ 162{ \
163 struct adm1021_data *data = i2c_get_clientdata(client); \ 163 struct i2c_client *client = to_i2c_client(dev); \
164 int temp = simple_strtoul(buf, NULL, 10); \ 164 struct adm1021_data *data = i2c_get_clientdata(client); \
165 \ 165 int temp = simple_strtoul(buf, NULL, 10); \
166 mutex_lock(&data->update_lock); \ 166 \
167 data->value = TEMP_TO_REG(temp); \ 167 mutex_lock(&data->update_lock); \
168 adm1021_write_value(client, reg, data->value); \ 168 data->value = TEMP_TO_REG(temp); \
169 mutex_unlock(&data->update_lock); \ 169 if (!read_only) \
170 return count; \ 170 i2c_smbus_write_byte_data(client, reg, data->value); \
171 mutex_unlock(&data->update_lock); \
172 return count; \
171} 173}
172set(temp_max, ADM1021_REG_TOS_W); 174set(temp_max, ADM1021_REG_TOS_W);
173set(temp_hyst, ADM1021_REG_THYST_W); 175set(temp_hyst, ADM1021_REG_THYST_W);
@@ -208,35 +210,44 @@ static const struct attribute_group adm1021_group = {
208static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) 210static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
209{ 211{
210 int i; 212 int i;
211 struct i2c_client *new_client; 213 struct i2c_client *client;
212 struct adm1021_data *data; 214 struct adm1021_data *data;
213 int err = 0; 215 int err = 0;
214 const char *type_name = ""; 216 const char *type_name = "";
217 int conv_rate, status, config;
215 218
216 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 219 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
220 pr_debug("adm1021: detect failed, "
221 "smbus byte data not supported!\n");
217 goto error0; 222 goto error0;
223 }
218 224
219 /* OK. For now, we presume we have a valid client. We now create the 225 /* OK. For now, we presume we have a valid client. We now create the
220 client structure, even though we cannot fill it completely yet. 226 client structure, even though we cannot fill it completely yet.
221 But it allows us to access adm1021_{read,write}_value. */ 227 But it allows us to access adm1021 register values. */
222 228
223 if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) { 229 if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
230 pr_debug("adm1021: detect failed, kzalloc failed!\n");
224 err = -ENOMEM; 231 err = -ENOMEM;
225 goto error0; 232 goto error0;
226 } 233 }
227 234
228 new_client = &data->client; 235 client = &data->client;
229 i2c_set_clientdata(new_client, data); 236 i2c_set_clientdata(client, data);
230 new_client->addr = address; 237 client->addr = address;
231 new_client->adapter = adapter; 238 client->adapter = adapter;
232 new_client->driver = &adm1021_driver; 239 client->driver = &adm1021_driver;
233 new_client->flags = 0; 240 status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS);
241 conv_rate = i2c_smbus_read_byte_data(client,
242 ADM1021_REG_CONV_RATE_R);
243 config = i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R);
234 244
235 /* Now, we do the remaining detection. */ 245 /* Now, we do the remaining detection. */
236 if (kind < 0) { 246 if (kind < 0) {
237 if ((adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0x03) != 0x00 247 if ((status & 0x03) != 0x00 || (config & 0x3F) != 0x00
238 || (adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x3F) != 0x00 248 || (conv_rate & 0xF8) != 0x00) {
239 || (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) & 0xF8) != 0x00) { 249 pr_debug("adm1021: detect failed, "
250 "chip not detected!\n");
240 err = -ENODEV; 251 err = -ENODEV;
241 goto error1; 252 goto error1;
242 } 253 }
@@ -244,9 +255,10 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
244 255
245 /* Determine the chip type. */ 256 /* Determine the chip type. */
246 if (kind <= 0) { 257 if (kind <= 0) {
247 i = adm1021_read_value(new_client, ADM1021_REG_MAN_ID); 258 i = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
248 if (i == 0x41) 259 if (i == 0x41)
249 if ((adm1021_read_value(new_client, ADM1021_REG_DEV_ID) & 0x0F0) == 0x030) 260 if ((i2c_smbus_read_byte_data(client,
261 ADM1021_REG_DEV_ID) & 0xF0) == 0x30)
250 kind = adm1023; 262 kind = adm1023;
251 else 263 else
252 kind = adm1021; 264 kind = adm1021;
@@ -255,15 +267,16 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
255 else if (i == 0x23) 267 else if (i == 0x23)
256 kind = gl523sm; 268 kind = gl523sm;
257 else if ((i == 0x4d) && 269 else if ((i == 0x4d) &&
258 (adm1021_read_value(new_client, ADM1021_REG_DEV_ID) == 0x01)) 270 (i2c_smbus_read_byte_data(client,
271 ADM1021_REG_DEV_ID) == 0x01))
259 kind = max1617a; 272 kind = max1617a;
260 else if (i == 0x54) 273 else if (i == 0x54)
261 kind = mc1066; 274 kind = mc1066;
262 /* LM84 Mfr ID in a different place, and it has more unused bits */ 275 /* LM84 Mfr ID in a different place, and it has more unused bits */
263 else if (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) == 0x00 276 else if (conv_rate == 0x00
264 && (kind == 0 /* skip extra detection */ 277 && (kind == 0 /* skip extra detection */
265 || ((adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x7F) == 0x00 278 || ((config & 0x7F) == 0x00
266 && (adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0xAB) == 0x00))) 279 && (status & 0xAB) == 0x00)))
267 kind = lm84; 280 kind = lm84;
268 else 281 else
269 kind = max1617; 282 kind = max1617;
@@ -286,26 +299,27 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
286 } else if (kind == mc1066) { 299 } else if (kind == mc1066) {
287 type_name = "mc1066"; 300 type_name = "mc1066";
288 } 301 }
302 pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n",
303 type_name, i2c_adapter_id(adapter), address);
289 304
290 /* Fill in the remaining client fields and put it into the global list */ 305 /* Fill in the remaining client fields */
291 strlcpy(new_client->name, type_name, I2C_NAME_SIZE); 306 strlcpy(client->name, type_name, I2C_NAME_SIZE);
292 data->type = kind; 307 data->type = kind;
293 data->valid = 0;
294 mutex_init(&data->update_lock); 308 mutex_init(&data->update_lock);
295 309
296 /* Tell the I2C layer a new client has arrived */ 310 /* Tell the I2C layer a new client has arrived */
297 if ((err = i2c_attach_client(new_client))) 311 if ((err = i2c_attach_client(client)))
298 goto error1; 312 goto error1;
299 313
300 /* Initialize the ADM1021 chip */ 314 /* Initialize the ADM1021 chip */
301 if (kind != lm84) 315 if (kind != lm84 && !read_only)
302 adm1021_init_client(new_client); 316 adm1021_init_client(client);
303 317
304 /* Register sysfs hooks */ 318 /* Register sysfs hooks */
305 if ((err = sysfs_create_group(&new_client->dev.kobj, &adm1021_group))) 319 if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group)))
306 goto error2; 320 goto error2;
307 321
308 data->class_dev = hwmon_device_register(&new_client->dev); 322 data->class_dev = hwmon_device_register(&client->dev);
309 if (IS_ERR(data->class_dev)) { 323 if (IS_ERR(data->class_dev)) {
310 err = PTR_ERR(data->class_dev); 324 err = PTR_ERR(data->class_dev);
311 goto error3; 325 goto error3;
@@ -314,9 +328,9 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
314 return 0; 328 return 0;
315 329
316error3: 330error3:
317 sysfs_remove_group(&new_client->dev.kobj, &adm1021_group); 331 sysfs_remove_group(&client->dev.kobj, &adm1021_group);
318error2: 332error2:
319 i2c_detach_client(new_client); 333 i2c_detach_client(client);
320error1: 334error1:
321 kfree(data); 335 kfree(data);
322error0: 336error0:
@@ -326,10 +340,10 @@ error0:
326static void adm1021_init_client(struct i2c_client *client) 340static void adm1021_init_client(struct i2c_client *client)
327{ 341{
328 /* Enable ADC and disable suspend mode */ 342 /* Enable ADC and disable suspend mode */
329 adm1021_write_value(client, ADM1021_REG_CONFIG_W, 343 i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W,
330 adm1021_read_value(client, ADM1021_REG_CONFIG_R) & 0xBF); 344 i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF);
331 /* Set Conversion rate to 1/sec (this can be tinkered with) */ 345 /* Set Conversion rate to 1/sec (this can be tinkered with) */
332 adm1021_write_value(client, ADM1021_REG_CONV_RATE_W, 0x04); 346 i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
333} 347}
334 348
335static int adm1021_detach_client(struct i2c_client *client) 349static int adm1021_detach_client(struct i2c_client *client)
@@ -347,19 +361,6 @@ static int adm1021_detach_client(struct i2c_client *client)
347 return 0; 361 return 0;
348} 362}
349 363
350/* All registers are byte-sized */
351static int adm1021_read_value(struct i2c_client *client, u8 reg)
352{
353 return i2c_smbus_read_byte_data(client, reg);
354}
355
356static int adm1021_write_value(struct i2c_client *client, u8 reg, u16 value)
357{
358 if (!read_only)
359 return i2c_smbus_write_byte_data(client, reg, value);
360 return 0;
361}
362
363static struct adm1021_data *adm1021_update_device(struct device *dev) 364static struct adm1021_data *adm1021_update_device(struct device *dev)
364{ 365{
365 struct i2c_client *client = to_i2c_client(dev); 366 struct i2c_client *client = to_i2c_client(dev);
@@ -371,19 +372,36 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
371 || !data->valid) { 372 || !data->valid) {
372 dev_dbg(&client->dev, "Starting adm1021 update\n"); 373 dev_dbg(&client->dev, "Starting adm1021 update\n");
373 374
374 data->temp_input = adm1021_read_value(client, ADM1021_REG_TEMP); 375 data->temp_input = i2c_smbus_read_byte_data(client,
375 data->temp_max = adm1021_read_value(client, ADM1021_REG_TOS_R); 376 ADM1021_REG_TEMP);
376 data->temp_hyst = adm1021_read_value(client, ADM1021_REG_THYST_R); 377 data->temp_max = i2c_smbus_read_byte_data(client,
377 data->remote_temp_input = adm1021_read_value(client, ADM1021_REG_REMOTE_TEMP); 378 ADM1021_REG_TOS_R);
378 data->remote_temp_max = adm1021_read_value(client, ADM1021_REG_REMOTE_TOS_R); 379 data->temp_hyst = i2c_smbus_read_byte_data(client,
379 data->remote_temp_hyst = adm1021_read_value(client, ADM1021_REG_REMOTE_THYST_R); 380 ADM1021_REG_THYST_R);
380 data->alarms = adm1021_read_value(client, ADM1021_REG_STATUS) & 0x7c; 381 data->remote_temp_input = i2c_smbus_read_byte_data(client,
382 ADM1021_REG_REMOTE_TEMP);
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,
388 ADM1021_REG_STATUS) & 0x7c;
381 if (data->type == adm1023) { 389 if (data->type == adm1023) {
382 data->remote_temp_prec = adm1021_read_value(client, ADM1021_REG_REM_TEMP_PREC); 390 data->remote_temp_prec =
383 data->remote_temp_os_prec = adm1021_read_value(client, ADM1021_REG_REM_TOS_PREC); 391 i2c_smbus_read_byte_data(client,
384 data->remote_temp_hyst_prec = adm1021_read_value(client, ADM1021_REG_REM_THYST_PREC); 392 ADM1023_REG_REM_TEMP_PREC);
385 data->remote_temp_offset = adm1021_read_value(client, ADM1021_REG_REM_OFFSET); 393 data->remote_temp_os_prec =
386 data->remote_temp_offset_prec = adm1021_read_value(client, ADM1021_REG_REM_OFFSET_PREC); 394 i2c_smbus_read_byte_data(client,
395 ADM1023_REG_REM_TOS_PREC);
396 data->remote_temp_hyst_prec =
397 i2c_smbus_read_byte_data(client,
398 ADM1023_REG_REM_THYST_PREC);
399 data->remote_temp_offset =
400 i2c_smbus_read_byte_data(client,
401 ADM1023_REG_REM_OFFSET);
402 data->remote_temp_offset_prec =
403 i2c_smbus_read_byte_data(client,
404 ADM1023_REG_REM_OFFSET_PREC);
387 } 405 }
388 data->last_updated = jiffies; 406 data->last_updated = jiffies;
389 data->valid = 1; 407 data->valid = 1;