aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorAndre Prendel <andre.prendel@gmx.de>2009-06-15 12:39:47 -0400
committerJean Delvare <khali@linux-fr.org>2009-06-15 12:39:47 -0400
commitfce0758f5990b34af4ffba589b23f25c700beb2f (patch)
treebff545efd04dcaf050a9c7744758b30108007815 /drivers/hwmon
parentab2b79d5e22d3cdd2b191e479c60e69df528369a (diff)
hwmon: (tmp401) Add support for TI's TMP411 sensors chip
This adds support for TI's TMP411 sensor chip. Preliminary support were done by Gabriel Konat, Sander Leget and Wouter Willems. The chip is compatible with TI's TMP401 sensor chip. It has additional support for historical minimun/maximum measurements. Signed-off-by: Andre Prendel <andre.prendel@gmx.de> Acked-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/tmp401.c173
1 files changed, 149 insertions, 24 deletions
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
index 49932de571e6..7b34f2cd08bb 100644
--- a/drivers/hwmon/tmp401.c
+++ b/drivers/hwmon/tmp401.c
@@ -1,6 +1,9 @@
1/* tmp401.c 1/* tmp401.c
2 * 2 *
3 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com> 3 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
4 * Preliminary tmp411 support by:
5 * Gabriel Konat, Sander Leget, Wouter Willems
6 * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
4 * 7 *
5 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -40,8 +43,7 @@
40static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; 43static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
41 44
42/* Insmod parameters */ 45/* Insmod parameters */
43I2C_CLIENT_INSMOD_1(tmp401); 46I2C_CLIENT_INSMOD_2(tmp401, tmp411);
44
45 47
46/* 48/*
47 * The TMP401 registers, note some registers have different addresses for 49 * The TMP401 registers, note some registers have different addresses for
@@ -56,6 +58,7 @@ I2C_CLIENT_INSMOD_1(tmp401);
56#define TMP401_CONSECUTIVE_ALERT 0x22 58#define TMP401_CONSECUTIVE_ALERT 0x22
57#define TMP401_MANUFACTURER_ID_REG 0xFE 59#define TMP401_MANUFACTURER_ID_REG 0xFE
58#define TMP401_DEVICE_ID_REG 0xFF 60#define TMP401_DEVICE_ID_REG 0xFF
61#define TMP411_N_FACTOR_REG 0x18
59 62
60static const u8 TMP401_TEMP_MSB[2] = { 0x00, 0x01 }; 63static const u8 TMP401_TEMP_MSB[2] = { 0x00, 0x01 };
61static const u8 TMP401_TEMP_LSB[2] = { 0x15, 0x10 }; 64static const u8 TMP401_TEMP_LSB[2] = { 0x15, 0x10 };
@@ -68,6 +71,11 @@ static const u8 TMP401_TEMP_HIGH_LIMIT_LSB[2] = { 0x16, 0x13 };
68/* These are called the THERM limit / hysteresis / mask in the datasheet */ 71/* These are called the THERM limit / hysteresis / mask in the datasheet */
69static const u8 TMP401_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 }; 72static const u8 TMP401_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 };
70 73
74static const u8 TMP411_TEMP_LOWEST_MSB[2] = { 0x30, 0x34 };
75static const u8 TMP411_TEMP_LOWEST_LSB[2] = { 0x31, 0x35 };
76static const u8 TMP411_TEMP_HIGHEST_MSB[2] = { 0x32, 0x36 };
77static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 };
78
71/* Flags */ 79/* Flags */
72#define TMP401_CONFIG_RANGE 0x04 80#define TMP401_CONFIG_RANGE 0x04
73#define TMP401_CONFIG_SHUTDOWN 0x40 81#define TMP401_CONFIG_SHUTDOWN 0x40
@@ -82,6 +90,7 @@ static const u8 TMP401_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 };
82/* Manufacturer / Device ID's */ 90/* Manufacturer / Device ID's */
83#define TMP401_MANUFACTURER_ID 0x55 91#define TMP401_MANUFACTURER_ID 0x55
84#define TMP401_DEVICE_ID 0x11 92#define TMP401_DEVICE_ID 0x11
93#define TMP411_DEVICE_ID 0x12
85 94
86/* 95/*
87 * Functions declarations 96 * Functions declarations
@@ -100,6 +109,7 @@ static struct tmp401_data *tmp401_update_device(struct device *dev);
100 109
101static const struct i2c_device_id tmp401_id[] = { 110static const struct i2c_device_id tmp401_id[] = {
102 { "tmp401", tmp401 }, 111 { "tmp401", tmp401 },
112 { "tmp411", tmp411 },
103 { } 113 { }
104}; 114};
105MODULE_DEVICE_TABLE(i2c, tmp401_id); 115MODULE_DEVICE_TABLE(i2c, tmp401_id);
@@ -125,6 +135,7 @@ struct tmp401_data {
125 struct mutex update_lock; 135 struct mutex update_lock;
126 char valid; /* zero until following fields are valid */ 136 char valid; /* zero until following fields are valid */
127 unsigned long last_updated; /* in jiffies */ 137 unsigned long last_updated; /* in jiffies */
138 int kind;
128 139
129 /* register values */ 140 /* register values */
130 u8 status; 141 u8 status;
@@ -134,6 +145,8 @@ struct tmp401_data {
134 u16 temp_high[2]; 145 u16 temp_high[2];
135 u8 temp_crit[2]; 146 u8 temp_crit[2];
136 u8 temp_crit_hyst; 147 u8 temp_crit_hyst;
148 u16 temp_lowest[2];
149 u16 temp_highest[2];
137}; 150};
138 151
139/* 152/*
@@ -238,6 +251,28 @@ static ssize_t show_temp_crit_hyst(struct device *dev,
238 return sprintf(buf, "%d\n", temp); 251 return sprintf(buf, "%d\n", temp);
239} 252}
240 253
254static ssize_t show_temp_lowest(struct device *dev,
255 struct device_attribute *devattr, char *buf)
256{
257 int index = to_sensor_dev_attr(devattr)->index;
258 struct tmp401_data *data = tmp401_update_device(dev);
259
260 return sprintf(buf, "%d\n",
261 tmp401_register_to_temp(data->temp_lowest[index],
262 data->config));
263}
264
265static ssize_t show_temp_highest(struct device *dev,
266 struct device_attribute *devattr, char *buf)
267{
268 int index = to_sensor_dev_attr(devattr)->index;
269 struct tmp401_data *data = tmp401_update_device(dev);
270
271 return sprintf(buf, "%d\n",
272 tmp401_register_to_temp(data->temp_highest[index],
273 data->config));
274}
275
241static ssize_t show_status(struct device *dev, 276static ssize_t show_status(struct device *dev,
242 struct device_attribute *devattr, char *buf) 277 struct device_attribute *devattr, char *buf)
243{ 278{
@@ -361,6 +396,30 @@ static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute
361 return count; 396 return count;
362} 397}
363 398
399/*
400 * Resets the historical measurements of minimum and maximum temperatures.
401 * This is done by writing any value to any of the minimum/maximum registers
402 * (0x30-0x37).
403 */
404static ssize_t reset_temp_history(struct device *dev,
405 struct device_attribute *devattr, const char *buf, size_t count)
406{
407 long val;
408
409 if (strict_strtol(buf, 10, &val))
410 return -EINVAL;
411
412 if (val != 1) {
413 dev_err(dev, "temp_reset_history value %ld not"
414 " supported. Use 1 to reset the history!\n", val);
415 return -EINVAL;
416 }
417 i2c_smbus_write_byte_data(to_i2c_client(dev),
418 TMP411_TEMP_LOWEST_MSB[0], val);
419
420 return count;
421}
422
364static struct sensor_device_attribute tmp401_attr[] = { 423static struct sensor_device_attribute tmp401_attr[] = {
365 SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0), 424 SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0),
366 SENSOR_ATTR(temp1_min, 0644, show_temp_min, store_temp_min, 0), 425 SENSOR_ATTR(temp1_min, 0644, show_temp_min, store_temp_min, 0),
@@ -390,6 +449,21 @@ static struct sensor_device_attribute tmp401_attr[] = {
390}; 449};
391 450
392/* 451/*
452 * Additional features of the TMP411 chip.
453 * The TMP411 stores the minimum and maximum
454 * temperature measured since power-on, chip-reset, or
455 * minimum and maximum register reset for both the local
456 * and remote channels.
457 */
458static struct sensor_device_attribute tmp411_attr[] = {
459 SENSOR_ATTR(temp1_highest, 0444, show_temp_highest, NULL, 0),
460 SENSOR_ATTR(temp1_lowest, 0444, show_temp_lowest, NULL, 0),
461 SENSOR_ATTR(temp2_highest, 0444, show_temp_highest, NULL, 1),
462 SENSOR_ATTR(temp2_lowest, 0444, show_temp_lowest, NULL, 1),
463 SENSOR_ATTR(temp_reset_history, 0200, NULL, reset_temp_history, 0),
464};
465
466/*
393 * Begin non sysfs callback code (aka Real code) 467 * Begin non sysfs callback code (aka Real code)
394 */ 468 */
395 469
@@ -432,8 +506,17 @@ static int tmp401_detect(struct i2c_client *client, int kind,
432 return -ENODEV; 506 return -ENODEV;
433 507
434 reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG); 508 reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
435 if (reg != TMP401_DEVICE_ID) 509
510 switch (reg) {
511 case TMP401_DEVICE_ID:
512 kind = tmp401;
513 break;
514 case TMP411_DEVICE_ID:
515 kind = tmp411;
516 break;
517 default:
436 return -ENODEV; 518 return -ENODEV;
519 }
437 520
438 reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ); 521 reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
439 if (reg & 0x1b) 522 if (reg & 0x1b)
@@ -441,10 +524,11 @@ static int tmp401_detect(struct i2c_client *client, int kind,
441 524
442 reg = i2c_smbus_read_byte_data(client, 525 reg = i2c_smbus_read_byte_data(client,
443 TMP401_CONVERSION_RATE_READ); 526 TMP401_CONVERSION_RATE_READ);
527 /* Datasheet says: 0x1-0x6 */
444 if (reg > 15) 528 if (reg > 15)
445 return -ENODEV; 529 return -ENODEV;
446 } 530 }
447 strlcpy(info->type, "tmp401", I2C_NAME_SIZE); 531 strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE);
448 532
449 return 0; 533 return 0;
450} 534}
@@ -454,6 +538,7 @@ static int tmp401_probe(struct i2c_client *client,
454{ 538{
455 int i, err = 0; 539 int i, err = 0;
456 struct tmp401_data *data; 540 struct tmp401_data *data;
541 const char *names[] = { "TMP401", "TMP411" };
457 542
458 data = kzalloc(sizeof(struct tmp401_data), GFP_KERNEL); 543 data = kzalloc(sizeof(struct tmp401_data), GFP_KERNEL);
459 if (!data) 544 if (!data)
@@ -461,6 +546,7 @@ static int tmp401_probe(struct i2c_client *client,
461 546
462 i2c_set_clientdata(client, data); 547 i2c_set_clientdata(client, data);
463 mutex_init(&data->update_lock); 548 mutex_init(&data->update_lock);
549 data->kind = id->driver_data;
464 550
465 /* Initialize the TMP401 chip */ 551 /* Initialize the TMP401 chip */
466 tmp401_init_client(client); 552 tmp401_init_client(client);
@@ -473,6 +559,16 @@ static int tmp401_probe(struct i2c_client *client,
473 goto exit_remove; 559 goto exit_remove;
474 } 560 }
475 561
562 /* Register aditional tmp411 sysfs hooks */
563 if (data->kind == tmp411) {
564 for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) {
565 err = device_create_file(&client->dev,
566 &tmp411_attr[i].dev_attr);
567 if (err)
568 goto exit_remove;
569 }
570 }
571
476 data->hwmon_dev = hwmon_device_register(&client->dev); 572 data->hwmon_dev = hwmon_device_register(&client->dev);
477 if (IS_ERR(data->hwmon_dev)) { 573 if (IS_ERR(data->hwmon_dev)) {
478 err = PTR_ERR(data->hwmon_dev); 574 err = PTR_ERR(data->hwmon_dev);
@@ -480,7 +576,8 @@ static int tmp401_probe(struct i2c_client *client,
480 goto exit_remove; 576 goto exit_remove;
481 } 577 }
482 578
483 dev_info(&client->dev, "Detected TI TMP401 chip\n"); 579 dev_info(&client->dev, "Detected TI %s chip\n",
580 names[data->kind - 1]);
484 581
485 return 0; 582 return 0;
486 583
@@ -500,15 +597,60 @@ static int tmp401_remove(struct i2c_client *client)
500 for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) 597 for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++)
501 device_remove_file(&client->dev, &tmp401_attr[i].dev_attr); 598 device_remove_file(&client->dev, &tmp401_attr[i].dev_attr);
502 599
600 if (data->kind == tmp411) {
601 for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++)
602 device_remove_file(&client->dev,
603 &tmp411_attr[i].dev_attr);
604 }
605
503 kfree(data); 606 kfree(data);
504 return 0; 607 return 0;
505} 608}
506 609
610static struct tmp401_data *tmp401_update_device_reg16(
611 struct i2c_client *client, struct tmp401_data *data)
612{
613 int i;
614
615 for (i = 0; i < 2; i++) {
616 /*
617 * High byte must be read first immediately followed
618 * by the low byte
619 */
620 data->temp[i] = i2c_smbus_read_byte_data(client,
621 TMP401_TEMP_MSB[i]) << 8;
622 data->temp[i] |= i2c_smbus_read_byte_data(client,
623 TMP401_TEMP_LSB[i]);
624 data->temp_low[i] = i2c_smbus_read_byte_data(client,
625 TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8;
626 data->temp_low[i] |= i2c_smbus_read_byte_data(client,
627 TMP401_TEMP_LOW_LIMIT_LSB[i]);
628 data->temp_high[i] = i2c_smbus_read_byte_data(client,
629 TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8;
630 data->temp_high[i] |= i2c_smbus_read_byte_data(client,
631 TMP401_TEMP_HIGH_LIMIT_LSB[i]);
632 data->temp_crit[i] = i2c_smbus_read_byte_data(client,
633 TMP401_TEMP_CRIT_LIMIT[i]);
634
635 if (data->kind == tmp411) {
636 data->temp_lowest[i] = i2c_smbus_read_byte_data(client,
637 TMP411_TEMP_LOWEST_MSB[i]) << 8;
638 data->temp_lowest[i] |= i2c_smbus_read_byte_data(
639 client, TMP411_TEMP_LOWEST_LSB[i]);
640
641 data->temp_highest[i] = i2c_smbus_read_byte_data(
642 client, TMP411_TEMP_HIGHEST_MSB[i]) << 8;
643 data->temp_highest[i] |= i2c_smbus_read_byte_data(
644 client, TMP411_TEMP_HIGHEST_LSB[i]);
645 }
646 }
647 return data;
648}
649
507static struct tmp401_data *tmp401_update_device(struct device *dev) 650static struct tmp401_data *tmp401_update_device(struct device *dev)
508{ 651{
509 struct i2c_client *client = to_i2c_client(dev); 652 struct i2c_client *client = to_i2c_client(dev);
510 struct tmp401_data *data = i2c_get_clientdata(client); 653 struct tmp401_data *data = i2c_get_clientdata(client);
511 int i;
512 654
513 mutex_lock(&data->update_lock); 655 mutex_lock(&data->update_lock);
514 656
@@ -516,24 +658,7 @@ static struct tmp401_data *tmp401_update_device(struct device *dev)
516 data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS); 658 data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS);
517 data->config = i2c_smbus_read_byte_data(client, 659 data->config = i2c_smbus_read_byte_data(client,
518 TMP401_CONFIG_READ); 660 TMP401_CONFIG_READ);
519 for (i = 0; i < 2; i++) { 661 tmp401_update_device_reg16(client, data);
520 /* High byte must be read first immediately followed
521 by the low byte */
522 data->temp[i] = i2c_smbus_read_byte_data(client,
523 TMP401_TEMP_MSB[i]) << 8;
524 data->temp[i] |= i2c_smbus_read_byte_data(client,
525 TMP401_TEMP_LSB[i]);
526 data->temp_low[i] = i2c_smbus_read_byte_data(client,
527 TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8;
528 data->temp_low[i] |= i2c_smbus_read_byte_data(client,
529 TMP401_TEMP_LOW_LIMIT_LSB[i]);
530 data->temp_high[i] = i2c_smbus_read_byte_data(client,
531 TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8;
532 data->temp_high[i] |= i2c_smbus_read_byte_data(client,
533 TMP401_TEMP_HIGH_LIMIT_LSB[i]);
534 data->temp_crit[i] = i2c_smbus_read_byte_data(client,
535 TMP401_TEMP_CRIT_LIMIT[i]);
536 }
537 662
538 data->temp_crit_hyst = i2c_smbus_read_byte_data(client, 663 data->temp_crit_hyst = i2c_smbus_read_byte_data(client,
539 TMP401_TEMP_CRIT_HYST); 664 TMP401_TEMP_CRIT_HYST);