aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/lm63.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/chips/lm63.c')
-rw-r--r--drivers/i2c/chips/lm63.c257
1 files changed, 137 insertions, 120 deletions
diff --git a/drivers/i2c/chips/lm63.c b/drivers/i2c/chips/lm63.c
index 18b2876e8df6..a1fd12bd615f 100644
--- a/drivers/i2c/chips/lm63.c
+++ b/drivers/i2c/chips/lm63.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * lm63.c - driver for the National Semiconductor LM63 temperature sensor 2 * lm63.c - driver for the National Semiconductor LM63 temperature sensor
3 * with integrated fan control 3 * with integrated fan control
4 * Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2004-2005 Jean Delvare <khali@linux-fr.org>
5 * Based on the lm90 driver. 5 * Based on the lm90 driver.
6 * 6 *
7 * The LM63 is a sensor chip made by National Semiconductor. It measures 7 * The LM63 is a sensor chip made by National Semiconductor. It measures
@@ -43,6 +43,7 @@
43#include <linux/jiffies.h> 43#include <linux/jiffies.h>
44#include <linux/i2c.h> 44#include <linux/i2c.h>
45#include <linux/i2c-sensor.h> 45#include <linux/i2c-sensor.h>
46#include <linux/i2c-sysfs.h>
46 47
47/* 48/*
48 * Addresses to scan 49 * Addresses to scan
@@ -157,16 +158,16 @@ struct lm63_data {
157 158
158 /* registers values */ 159 /* registers values */
159 u8 config, config_fan; 160 u8 config, config_fan;
160 u16 fan1_input; 161 u16 fan[2]; /* 0: input
161 u16 fan1_low; 162 1: low limit */
162 u8 pwm1_freq; 163 u8 pwm1_freq;
163 u8 pwm1_value; 164 u8 pwm1_value;
164 s8 temp1_input; 165 s8 temp8[3]; /* 0: local input
165 s8 temp1_high; 166 1: local high limit
166 s16 temp2_input; 167 2: remote critical limit */
167 s16 temp2_high; 168 s16 temp11[3]; /* 0: remote input
168 s16 temp2_low; 169 1: remote low limit
169 s8 temp2_crit; 170 2: remote high limit */
170 u8 temp2_crit_hyst; 171 u8 temp2_crit_hyst;
171 u8 alarms; 172 u8 alarms;
172}; 173};
@@ -175,33 +176,33 @@ struct lm63_data {
175 * Sysfs callback functions and files 176 * Sysfs callback functions and files
176 */ 177 */
177 178
178#define show_fan(value) \ 179static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
179static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ 180 char *buf)
180{ \ 181{
181 struct lm63_data *data = lm63_update_device(dev); \ 182 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
182 return sprintf(buf, "%d\n", FAN_FROM_REG(data->value)); \ 183 struct lm63_data *data = lm63_update_device(dev);
184 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index]));
183} 185}
184show_fan(fan1_input);
185show_fan(fan1_low);
186 186
187static ssize_t set_fan1_low(struct device *dev, struct device_attribute *attr, const char *buf, 187static ssize_t set_fan(struct device *dev, struct device_attribute *dummy,
188 size_t count) 188 const char *buf, size_t count)
189{ 189{
190 struct i2c_client *client = to_i2c_client(dev); 190 struct i2c_client *client = to_i2c_client(dev);
191 struct lm63_data *data = i2c_get_clientdata(client); 191 struct lm63_data *data = i2c_get_clientdata(client);
192 unsigned long val = simple_strtoul(buf, NULL, 10); 192 unsigned long val = simple_strtoul(buf, NULL, 10);
193 193
194 down(&data->update_lock); 194 down(&data->update_lock);
195 data->fan1_low = FAN_TO_REG(val); 195 data->fan[1] = FAN_TO_REG(val);
196 i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB, 196 i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB,
197 data->fan1_low & 0xFF); 197 data->fan[1] & 0xFF);
198 i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB, 198 i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB,
199 data->fan1_low >> 8); 199 data->fan[1] >> 8);
200 up(&data->update_lock); 200 up(&data->update_lock);
201 return count; 201 return count;
202} 202}
203 203
204static ssize_t show_pwm1(struct device *dev, struct device_attribute *attr, char *buf) 204static ssize_t show_pwm1(struct device *dev, struct device_attribute *dummy,
205 char *buf)
205{ 206{
206 struct lm63_data *data = lm63_update_device(dev); 207 struct lm63_data *data = lm63_update_device(dev);
207 return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ? 208 return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ?
@@ -209,7 +210,8 @@ static ssize_t show_pwm1(struct device *dev, struct device_attribute *attr, char
209 (2 * data->pwm1_freq)); 210 (2 * data->pwm1_freq));
210} 211}
211 212
212static ssize_t set_pwm1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 213static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
214 const char *buf, size_t count)
213{ 215{
214 struct i2c_client *client = to_i2c_client(dev); 216 struct i2c_client *client = to_i2c_client(dev);
215 struct lm63_data *data = i2c_get_clientdata(client); 217 struct lm63_data *data = i2c_get_clientdata(client);
@@ -228,77 +230,83 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *attr, const
228 return count; 230 return count;
229} 231}
230 232
231static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *attr, char *buf) 233static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dummy,
234 char *buf)
232{ 235{
233 struct lm63_data *data = lm63_update_device(dev); 236 struct lm63_data *data = lm63_update_device(dev);
234 return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2); 237 return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
235} 238}
236 239
237#define show_temp8(value) \ 240static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
238static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ 241 char *buf)
239{ \ 242{
240 struct lm63_data *data = lm63_update_device(dev); \ 243 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
241 return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->value)); \ 244 struct lm63_data *data = lm63_update_device(dev);
245 return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]));
242} 246}
243#define show_temp11(value) \ 247
244static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ 248static ssize_t set_temp8(struct device *dev, struct device_attribute *dummy,
245{ \ 249 const char *buf, size_t count)
246 struct lm63_data *data = lm63_update_device(dev); \ 250{
247 return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->value)); \ 251 struct i2c_client *client = to_i2c_client(dev);
252 struct lm63_data *data = i2c_get_clientdata(client);
253 long val = simple_strtol(buf, NULL, 10);
254
255 down(&data->update_lock);
256 data->temp8[1] = TEMP8_TO_REG(val);
257 i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]);
258 up(&data->update_lock);
259 return count;
248} 260}
249show_temp8(temp1_input); 261
250show_temp8(temp1_high); 262static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
251show_temp11(temp2_input); 263 char *buf)
252show_temp11(temp2_high); 264{
253show_temp11(temp2_low); 265 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
254show_temp8(temp2_crit); 266 struct lm63_data *data = lm63_update_device(dev);
255 267 return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]));
256#define set_temp8(value, reg) \
257static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
258 size_t count) \
259{ \
260 struct i2c_client *client = to_i2c_client(dev); \
261 struct lm63_data *data = i2c_get_clientdata(client); \
262 long val = simple_strtol(buf, NULL, 10); \
263 \
264 down(&data->update_lock); \
265 data->value = TEMP8_TO_REG(val); \
266 i2c_smbus_write_byte_data(client, reg, data->value); \
267 up(&data->update_lock); \
268 return count; \
269} 268}
270#define set_temp11(value, reg_msb, reg_lsb) \ 269
271static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \ 270static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
272 size_t count) \ 271 const char *buf, size_t count)
273{ \ 272{
274 struct i2c_client *client = to_i2c_client(dev); \ 273 static const u8 reg[4] = {
275 struct lm63_data *data = i2c_get_clientdata(client); \ 274 LM63_REG_REMOTE_LOW_MSB,
276 long val = simple_strtol(buf, NULL, 10); \ 275 LM63_REG_REMOTE_LOW_LSB,
277 \ 276 LM63_REG_REMOTE_HIGH_MSB,
278 down(&data->update_lock); \ 277 LM63_REG_REMOTE_HIGH_LSB,
279 data->value = TEMP11_TO_REG(val); \ 278 };
280 i2c_smbus_write_byte_data(client, reg_msb, data->value >> 8); \ 279
281 i2c_smbus_write_byte_data(client, reg_lsb, data->value & 0xff); \ 280 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
282 up(&data->update_lock); \ 281 struct i2c_client *client = to_i2c_client(dev);
283 return count; \ 282 struct lm63_data *data = i2c_get_clientdata(client);
283 long val = simple_strtol(buf, NULL, 10);
284 int nr = attr->index;
285
286 down(&data->update_lock);
287 data->temp11[nr] = TEMP11_TO_REG(val);
288 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
289 data->temp11[nr] >> 8);
290 i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
291 data->temp11[nr] & 0xff);
292 up(&data->update_lock);
293 return count;
284} 294}
285set_temp8(temp1_high, LM63_REG_LOCAL_HIGH);
286set_temp11(temp2_high, LM63_REG_REMOTE_HIGH_MSB, LM63_REG_REMOTE_HIGH_LSB);
287set_temp11(temp2_low, LM63_REG_REMOTE_LOW_MSB, LM63_REG_REMOTE_LOW_LSB);
288 295
289/* Hysteresis register holds a relative value, while we want to present 296/* Hysteresis register holds a relative value, while we want to present
290 an absolute to user-space */ 297 an absolute to user-space */
291static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf) 298static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy,
299 char *buf)
292{ 300{
293 struct lm63_data *data = lm63_update_device(dev); 301 struct lm63_data *data = lm63_update_device(dev);
294 return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp2_crit) 302 return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2])
295 - TEMP8_FROM_REG(data->temp2_crit_hyst)); 303 - TEMP8_FROM_REG(data->temp2_crit_hyst));
296} 304}
297 305
298/* And now the other way around, user-space provides an absolute 306/* And now the other way around, user-space provides an absolute
299 hysteresis value and we have to store a relative one */ 307 hysteresis value and we have to store a relative one */
300static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf, 308static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy,
301 size_t count) 309 const char *buf, size_t count)
302{ 310{
303 struct i2c_client *client = to_i2c_client(dev); 311 struct i2c_client *client = to_i2c_client(dev);
304 struct lm63_data *data = i2c_get_clientdata(client); 312 struct lm63_data *data = i2c_get_clientdata(client);
@@ -306,36 +314,37 @@ static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *
306 long hyst; 314 long hyst;
307 315
308 down(&data->update_lock); 316 down(&data->update_lock);
309 hyst = TEMP8_FROM_REG(data->temp2_crit) - val; 317 hyst = TEMP8_FROM_REG(data->temp8[2]) - val;
310 i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST, 318 i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
311 HYST_TO_REG(hyst)); 319 HYST_TO_REG(hyst));
312 up(&data->update_lock); 320 up(&data->update_lock);
313 return count; 321 return count;
314} 322}
315 323
316static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) 324static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
325 char *buf)
317{ 326{
318 struct lm63_data *data = lm63_update_device(dev); 327 struct lm63_data *data = lm63_update_device(dev);
319 return sprintf(buf, "%u\n", data->alarms); 328 return sprintf(buf, "%u\n", data->alarms);
320} 329}
321 330
322static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan1_input, NULL); 331static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
323static DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan1_low, 332static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
324 set_fan1_low); 333 set_fan, 1);
325 334
326static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1); 335static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1);
327static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL); 336static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);
328 337
329static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL); 338static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
330static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_high, 339static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
331 set_temp1_high); 340 set_temp8, 1);
332 341
333static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp2_input, NULL); 342static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
334static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp2_low, 343static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
335 set_temp2_low); 344 set_temp11, 1);
336static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp2_high, 345static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
337 set_temp2_high); 346 set_temp11, 2);
338static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp2_crit, NULL); 347static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2);
339static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst, 348static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
340 set_temp2_crit_hyst); 349 set_temp2_crit_hyst);
341 350
@@ -429,17 +438,25 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
429 438
430 /* Register sysfs hooks */ 439 /* Register sysfs hooks */
431 if (data->config & 0x04) { /* tachometer enabled */ 440 if (data->config & 0x04) { /* tachometer enabled */
432 device_create_file(&new_client->dev, &dev_attr_fan1_input); 441 device_create_file(&new_client->dev,
433 device_create_file(&new_client->dev, &dev_attr_fan1_min); 442 &sensor_dev_attr_fan1_input.dev_attr);
443 device_create_file(&new_client->dev,
444 &sensor_dev_attr_fan1_min.dev_attr);
434 } 445 }
435 device_create_file(&new_client->dev, &dev_attr_pwm1); 446 device_create_file(&new_client->dev, &dev_attr_pwm1);
436 device_create_file(&new_client->dev, &dev_attr_pwm1_enable); 447 device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
437 device_create_file(&new_client->dev, &dev_attr_temp1_input); 448 device_create_file(&new_client->dev,
438 device_create_file(&new_client->dev, &dev_attr_temp2_input); 449 &sensor_dev_attr_temp1_input.dev_attr);
439 device_create_file(&new_client->dev, &dev_attr_temp2_min); 450 device_create_file(&new_client->dev,
440 device_create_file(&new_client->dev, &dev_attr_temp1_max); 451 &sensor_dev_attr_temp2_input.dev_attr);
441 device_create_file(&new_client->dev, &dev_attr_temp2_max); 452 device_create_file(&new_client->dev,
442 device_create_file(&new_client->dev, &dev_attr_temp2_crit); 453 &sensor_dev_attr_temp2_min.dev_attr);
454 device_create_file(&new_client->dev,
455 &sensor_dev_attr_temp1_max.dev_attr);
456 device_create_file(&new_client->dev,
457 &sensor_dev_attr_temp2_max.dev_attr);
458 device_create_file(&new_client->dev,
459 &sensor_dev_attr_temp2_crit.dev_attr);
443 device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst); 460 device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
444 device_create_file(&new_client->dev, &dev_attr_alarms); 461 device_create_file(&new_client->dev, &dev_attr_alarms);
445 462
@@ -510,14 +527,14 @@ static struct lm63_data *lm63_update_device(struct device *dev)
510 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { 527 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
511 if (data->config & 0x04) { /* tachometer enabled */ 528 if (data->config & 0x04) { /* tachometer enabled */
512 /* order matters for fan1_input */ 529 /* order matters for fan1_input */
513 data->fan1_input = i2c_smbus_read_byte_data(client, 530 data->fan[0] = i2c_smbus_read_byte_data(client,
514 LM63_REG_TACH_COUNT_LSB) & 0xFC; 531 LM63_REG_TACH_COUNT_LSB) & 0xFC;
515 data->fan1_input |= i2c_smbus_read_byte_data(client, 532 data->fan[0] |= i2c_smbus_read_byte_data(client,
516 LM63_REG_TACH_COUNT_MSB) << 8; 533 LM63_REG_TACH_COUNT_MSB) << 8;
517 data->fan1_low = (i2c_smbus_read_byte_data(client, 534 data->fan[1] = (i2c_smbus_read_byte_data(client,
518 LM63_REG_TACH_LIMIT_LSB) & 0xFC) 535 LM63_REG_TACH_LIMIT_LSB) & 0xFC)
519 | (i2c_smbus_read_byte_data(client, 536 | (i2c_smbus_read_byte_data(client,
520 LM63_REG_TACH_LIMIT_MSB) << 8); 537 LM63_REG_TACH_LIMIT_MSB) << 8);
521 } 538 }
522 539
523 data->pwm1_freq = i2c_smbus_read_byte_data(client, 540 data->pwm1_freq = i2c_smbus_read_byte_data(client,
@@ -527,26 +544,26 @@ static struct lm63_data *lm63_update_device(struct device *dev)
527 data->pwm1_value = i2c_smbus_read_byte_data(client, 544 data->pwm1_value = i2c_smbus_read_byte_data(client,
528 LM63_REG_PWM_VALUE); 545 LM63_REG_PWM_VALUE);
529 546
530 data->temp1_input = i2c_smbus_read_byte_data(client, 547 data->temp8[0] = i2c_smbus_read_byte_data(client,
531 LM63_REG_LOCAL_TEMP); 548 LM63_REG_LOCAL_TEMP);
532 data->temp1_high = i2c_smbus_read_byte_data(client, 549 data->temp8[1] = i2c_smbus_read_byte_data(client,
533 LM63_REG_LOCAL_HIGH); 550 LM63_REG_LOCAL_HIGH);
534 551
535 /* order matters for temp2_input */ 552 /* order matters for temp2_input */
536 data->temp2_input = i2c_smbus_read_byte_data(client, 553 data->temp11[0] = i2c_smbus_read_byte_data(client,
537 LM63_REG_REMOTE_TEMP_MSB) << 8; 554 LM63_REG_REMOTE_TEMP_MSB) << 8;
538 data->temp2_input |= i2c_smbus_read_byte_data(client, 555 data->temp11[0] |= i2c_smbus_read_byte_data(client,
539 LM63_REG_REMOTE_TEMP_LSB); 556 LM63_REG_REMOTE_TEMP_LSB);
540 data->temp2_high = (i2c_smbus_read_byte_data(client, 557 data->temp11[1] = (i2c_smbus_read_byte_data(client,
541 LM63_REG_REMOTE_HIGH_MSB) << 8)
542 | i2c_smbus_read_byte_data(client,
543 LM63_REG_REMOTE_HIGH_LSB);
544 data->temp2_low = (i2c_smbus_read_byte_data(client,
545 LM63_REG_REMOTE_LOW_MSB) << 8) 558 LM63_REG_REMOTE_LOW_MSB) << 8)
546 | i2c_smbus_read_byte_data(client, 559 | i2c_smbus_read_byte_data(client,
547 LM63_REG_REMOTE_LOW_LSB); 560 LM63_REG_REMOTE_LOW_LSB);
548 data->temp2_crit = i2c_smbus_read_byte_data(client, 561 data->temp11[2] = (i2c_smbus_read_byte_data(client,
549 LM63_REG_REMOTE_TCRIT); 562 LM63_REG_REMOTE_HIGH_MSB) << 8)
563 | i2c_smbus_read_byte_data(client,
564 LM63_REG_REMOTE_HIGH_LSB);
565 data->temp8[2] = i2c_smbus_read_byte_data(client,
566 LM63_REG_REMOTE_TCRIT);
550 data->temp2_crit_hyst = i2c_smbus_read_byte_data(client, 567 data->temp2_crit_hyst = i2c_smbus_read_byte_data(client,
551 LM63_REG_REMOTE_TCRIT_HYST); 568 LM63_REG_REMOTE_TCRIT_HYST);
552 569