aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/tmp401.c565
3 files changed, 576 insertions, 0 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 86a5cff0c027..79117c3abb41 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -787,6 +787,16 @@ config SENSORS_THMC50
787 This driver can also be built as a module. If so, the module 787 This driver can also be built as a module. If so, the module
788 will be called thmc50. 788 will be called thmc50.
789 789
790config SENSORS_TMP401
791 tristate "Texas Instruments TMP401 and compatibles"
792 depends on I2C && EXPERIMENTAL
793 help
794 If you say yes here you get support for Texas Instruments TMP401 and
795 TMP411 temperature sensor chips.
796
797 This driver can also be built as a module. If so, the module
798 will be called tmp401.
799
790config SENSORS_VIA686A 800config SENSORS_VIA686A
791 tristate "VIA686A" 801 tristate "VIA686A"
792 depends on PCI 802 depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 0ae26984ba45..b793dce6bed5 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
82obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o 82obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
83obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o 83obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
84obj-$(CONFIG_SENSORS_THMC50) += thmc50.o 84obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
85obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
85obj-$(CONFIG_SENSORS_VIA686A) += via686a.o 86obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
86obj-$(CONFIG_SENSORS_VT1211) += vt1211.o 87obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
87obj-$(CONFIG_SENSORS_VT8231) += vt8231.o 88obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
new file mode 100644
index 000000000000..49932de571e6
--- /dev/null
+++ b/drivers/hwmon/tmp401.c
@@ -0,0 +1,565 @@
1/* tmp401.c
2 *
3 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
4 *
5 * 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
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20/*
21 * Driver for the Texas Instruments TMP401 SMBUS temperature sensor IC.
22 *
23 * Note this IC is in some aspect similar to the LM90, but it has quite a
24 * few differences too, for example the local temp has a higher resolution
25 * and thus has 16 bits registers for its value and limit instead of 8 bits.
26 */
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <linux/jiffies.h>
32#include <linux/i2c.h>
33#include <linux/hwmon.h>
34#include <linux/hwmon-sysfs.h>
35#include <linux/err.h>
36#include <linux/mutex.h>
37#include <linux/sysfs.h>
38
39/* Addresses to scan */
40static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
41
42/* Insmod parameters */
43I2C_CLIENT_INSMOD_1(tmp401);
44
45
46/*
47 * The TMP401 registers, note some registers have different addresses for
48 * reading and writing
49 */
50#define TMP401_STATUS 0x02
51#define TMP401_CONFIG_READ 0x03
52#define TMP401_CONFIG_WRITE 0x09
53#define TMP401_CONVERSION_RATE_READ 0x04
54#define TMP401_CONVERSION_RATE_WRITE 0x0A
55#define TMP401_TEMP_CRIT_HYST 0x21
56#define TMP401_CONSECUTIVE_ALERT 0x22
57#define TMP401_MANUFACTURER_ID_REG 0xFE
58#define TMP401_DEVICE_ID_REG 0xFF
59
60static const u8 TMP401_TEMP_MSB[2] = { 0x00, 0x01 };
61static const u8 TMP401_TEMP_LSB[2] = { 0x15, 0x10 };
62static const u8 TMP401_TEMP_LOW_LIMIT_MSB_READ[2] = { 0x06, 0x08 };
63static const u8 TMP401_TEMP_LOW_LIMIT_MSB_WRITE[2] = { 0x0C, 0x0E };
64static const u8 TMP401_TEMP_LOW_LIMIT_LSB[2] = { 0x17, 0x14 };
65static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_READ[2] = { 0x05, 0x07 };
66static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[2] = { 0x0B, 0x0D };
67static const u8 TMP401_TEMP_HIGH_LIMIT_LSB[2] = { 0x16, 0x13 };
68/* These are called the THERM limit / hysteresis / mask in the datasheet */
69static const u8 TMP401_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 };
70
71/* Flags */
72#define TMP401_CONFIG_RANGE 0x04
73#define TMP401_CONFIG_SHUTDOWN 0x40
74#define TMP401_STATUS_LOCAL_CRIT 0x01
75#define TMP401_STATUS_REMOTE_CRIT 0x02
76#define TMP401_STATUS_REMOTE_OPEN 0x04
77#define TMP401_STATUS_REMOTE_LOW 0x08
78#define TMP401_STATUS_REMOTE_HIGH 0x10
79#define TMP401_STATUS_LOCAL_LOW 0x20
80#define TMP401_STATUS_LOCAL_HIGH 0x40
81
82/* Manufacturer / Device ID's */
83#define TMP401_MANUFACTURER_ID 0x55
84#define TMP401_DEVICE_ID 0x11
85
86/*
87 * Functions declarations
88 */
89
90static int tmp401_probe(struct i2c_client *client,
91 const struct i2c_device_id *id);
92static int tmp401_detect(struct i2c_client *client, int kind,
93 struct i2c_board_info *info);
94static int tmp401_remove(struct i2c_client *client);
95static struct tmp401_data *tmp401_update_device(struct device *dev);
96
97/*
98 * Driver data (common to all clients)
99 */
100
101static const struct i2c_device_id tmp401_id[] = {
102 { "tmp401", tmp401 },
103 { }
104};
105MODULE_DEVICE_TABLE(i2c, tmp401_id);
106
107static struct i2c_driver tmp401_driver = {
108 .class = I2C_CLASS_HWMON,
109 .driver = {
110 .name = "tmp401",
111 },
112 .probe = tmp401_probe,
113 .remove = tmp401_remove,
114 .id_table = tmp401_id,
115 .detect = tmp401_detect,
116 .address_data = &addr_data,
117};
118
119/*
120 * Client data (each client gets its own)
121 */
122
123struct tmp401_data {
124 struct device *hwmon_dev;
125 struct mutex update_lock;
126 char valid; /* zero until following fields are valid */
127 unsigned long last_updated; /* in jiffies */
128
129 /* register values */
130 u8 status;
131 u8 config;
132 u16 temp[2];
133 u16 temp_low[2];
134 u16 temp_high[2];
135 u8 temp_crit[2];
136 u8 temp_crit_hyst;
137};
138
139/*
140 * Sysfs attr show / store functions
141 */
142
143static int tmp401_register_to_temp(u16 reg, u8 config)
144{
145 int temp = reg;
146
147 if (config & TMP401_CONFIG_RANGE)
148 temp -= 64 * 256;
149
150 return (temp * 625 + 80) / 160;
151}
152
153static u16 tmp401_temp_to_register(long temp, u8 config)
154{
155 if (config & TMP401_CONFIG_RANGE) {
156 temp = SENSORS_LIMIT(temp, -64000, 191000);
157 temp += 64000;
158 } else
159 temp = SENSORS_LIMIT(temp, 0, 127000);
160
161 return (temp * 160 + 312) / 625;
162}
163
164static int tmp401_crit_register_to_temp(u8 reg, u8 config)
165{
166 int temp = reg;
167
168 if (config & TMP401_CONFIG_RANGE)
169 temp -= 64;
170
171 return temp * 1000;
172}
173
174static u8 tmp401_crit_temp_to_register(long temp, u8 config)
175{
176 if (config & TMP401_CONFIG_RANGE) {
177 temp = SENSORS_LIMIT(temp, -64000, 191000);
178 temp += 64000;
179 } else
180 temp = SENSORS_LIMIT(temp, 0, 127000);
181
182 return (temp + 500) / 1000;
183}
184
185static ssize_t show_temp_value(struct device *dev,
186 struct device_attribute *devattr, char *buf)
187{
188 int index = to_sensor_dev_attr(devattr)->index;
189 struct tmp401_data *data = tmp401_update_device(dev);
190
191 return sprintf(buf, "%d\n",
192 tmp401_register_to_temp(data->temp[index], data->config));
193}
194
195static ssize_t show_temp_min(struct device *dev,
196 struct device_attribute *devattr, char *buf)
197{
198 int index = to_sensor_dev_attr(devattr)->index;
199 struct tmp401_data *data = tmp401_update_device(dev);
200
201 return sprintf(buf, "%d\n",
202 tmp401_register_to_temp(data->temp_low[index], data->config));
203}
204
205static ssize_t show_temp_max(struct device *dev,
206 struct device_attribute *devattr, char *buf)
207{
208 int index = to_sensor_dev_attr(devattr)->index;
209 struct tmp401_data *data = tmp401_update_device(dev);
210
211 return sprintf(buf, "%d\n",
212 tmp401_register_to_temp(data->temp_high[index], data->config));
213}
214
215static ssize_t show_temp_crit(struct device *dev,
216 struct device_attribute *devattr, char *buf)
217{
218 int index = to_sensor_dev_attr(devattr)->index;
219 struct tmp401_data *data = tmp401_update_device(dev);
220
221 return sprintf(buf, "%d\n",
222 tmp401_crit_register_to_temp(data->temp_crit[index],
223 data->config));
224}
225
226static ssize_t show_temp_crit_hyst(struct device *dev,
227 struct device_attribute *devattr, char *buf)
228{
229 int temp, index = to_sensor_dev_attr(devattr)->index;
230 struct tmp401_data *data = tmp401_update_device(dev);
231
232 mutex_lock(&data->update_lock);
233 temp = tmp401_crit_register_to_temp(data->temp_crit[index],
234 data->config);
235 temp -= data->temp_crit_hyst * 1000;
236 mutex_unlock(&data->update_lock);
237
238 return sprintf(buf, "%d\n", temp);
239}
240
241static ssize_t show_status(struct device *dev,
242 struct device_attribute *devattr, char *buf)
243{
244 int mask = to_sensor_dev_attr(devattr)->index;
245 struct tmp401_data *data = tmp401_update_device(dev);
246
247 if (data->status & mask)
248 return sprintf(buf, "1\n");
249 else
250 return sprintf(buf, "0\n");
251}
252
253static ssize_t store_temp_min(struct device *dev, struct device_attribute
254 *devattr, const char *buf, size_t count)
255{
256 int index = to_sensor_dev_attr(devattr)->index;
257 struct tmp401_data *data = tmp401_update_device(dev);
258 long val;
259 u16 reg;
260
261 if (strict_strtol(buf, 10, &val))
262 return -EINVAL;
263
264 reg = tmp401_temp_to_register(val, data->config);
265
266 mutex_lock(&data->update_lock);
267
268 i2c_smbus_write_byte_data(to_i2c_client(dev),
269 TMP401_TEMP_LOW_LIMIT_MSB_WRITE[index], reg >> 8);
270 i2c_smbus_write_byte_data(to_i2c_client(dev),
271 TMP401_TEMP_LOW_LIMIT_LSB[index], reg & 0xFF);
272
273 data->temp_low[index] = reg;
274
275 mutex_unlock(&data->update_lock);
276
277 return count;
278}
279
280static ssize_t store_temp_max(struct device *dev, struct device_attribute
281 *devattr, const char *buf, size_t count)
282{
283 int index = to_sensor_dev_attr(devattr)->index;
284 struct tmp401_data *data = tmp401_update_device(dev);
285 long val;
286 u16 reg;
287
288 if (strict_strtol(buf, 10, &val))
289 return -EINVAL;
290
291 reg = tmp401_temp_to_register(val, data->config);
292
293 mutex_lock(&data->update_lock);
294
295 i2c_smbus_write_byte_data(to_i2c_client(dev),
296 TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[index], reg >> 8);
297 i2c_smbus_write_byte_data(to_i2c_client(dev),
298 TMP401_TEMP_HIGH_LIMIT_LSB[index], reg & 0xFF);
299
300 data->temp_high[index] = reg;
301
302 mutex_unlock(&data->update_lock);
303
304 return count;
305}
306
307static ssize_t store_temp_crit(struct device *dev, struct device_attribute
308 *devattr, const char *buf, size_t count)
309{
310 int index = to_sensor_dev_attr(devattr)->index;
311 struct tmp401_data *data = tmp401_update_device(dev);
312 long val;
313 u8 reg;
314
315 if (strict_strtol(buf, 10, &val))
316 return -EINVAL;
317
318 reg = tmp401_crit_temp_to_register(val, data->config);
319
320 mutex_lock(&data->update_lock);
321
322 i2c_smbus_write_byte_data(to_i2c_client(dev),
323 TMP401_TEMP_CRIT_LIMIT[index], reg);
324
325 data->temp_crit[index] = reg;
326
327 mutex_unlock(&data->update_lock);
328
329 return count;
330}
331
332static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute
333 *devattr, const char *buf, size_t count)
334{
335 int temp, index = to_sensor_dev_attr(devattr)->index;
336 struct tmp401_data *data = tmp401_update_device(dev);
337 long val;
338 u8 reg;
339
340 if (strict_strtol(buf, 10, &val))
341 return -EINVAL;
342
343 if (data->config & TMP401_CONFIG_RANGE)
344 val = SENSORS_LIMIT(val, -64000, 191000);
345 else
346 val = SENSORS_LIMIT(val, 0, 127000);
347
348 mutex_lock(&data->update_lock);
349 temp = tmp401_crit_register_to_temp(data->temp_crit[index],
350 data->config);
351 val = SENSORS_LIMIT(val, temp - 255000, temp);
352 reg = ((temp - val) + 500) / 1000;
353
354 i2c_smbus_write_byte_data(to_i2c_client(dev),
355 TMP401_TEMP_CRIT_HYST, reg);
356
357 data->temp_crit_hyst = reg;
358
359 mutex_unlock(&data->update_lock);
360
361 return count;
362}
363
364static struct sensor_device_attribute tmp401_attr[] = {
365 SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0),
366 SENSOR_ATTR(temp1_min, 0644, show_temp_min, store_temp_min, 0),
367 SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0),
368 SENSOR_ATTR(temp1_crit, 0644, show_temp_crit, store_temp_crit, 0),
369 SENSOR_ATTR(temp1_crit_hyst, 0644, show_temp_crit_hyst,
370 store_temp_crit_hyst, 0),
371 SENSOR_ATTR(temp1_min_alarm, 0444, show_status, NULL,
372 TMP401_STATUS_LOCAL_LOW),
373 SENSOR_ATTR(temp1_max_alarm, 0444, show_status, NULL,
374 TMP401_STATUS_LOCAL_HIGH),
375 SENSOR_ATTR(temp1_crit_alarm, 0444, show_status, NULL,
376 TMP401_STATUS_LOCAL_CRIT),
377 SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1),
378 SENSOR_ATTR(temp2_min, 0644, show_temp_min, store_temp_min, 1),
379 SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1),
380 SENSOR_ATTR(temp2_crit, 0644, show_temp_crit, store_temp_crit, 1),
381 SENSOR_ATTR(temp2_crit_hyst, 0444, show_temp_crit_hyst, NULL, 1),
382 SENSOR_ATTR(temp2_fault, 0444, show_status, NULL,
383 TMP401_STATUS_REMOTE_OPEN),
384 SENSOR_ATTR(temp2_min_alarm, 0444, show_status, NULL,
385 TMP401_STATUS_REMOTE_LOW),
386 SENSOR_ATTR(temp2_max_alarm, 0444, show_status, NULL,
387 TMP401_STATUS_REMOTE_HIGH),
388 SENSOR_ATTR(temp2_crit_alarm, 0444, show_status, NULL,
389 TMP401_STATUS_REMOTE_CRIT),
390};
391
392/*
393 * Begin non sysfs callback code (aka Real code)
394 */
395
396static void tmp401_init_client(struct i2c_client *client)
397{
398 int config, config_orig;
399
400 /* Set the conversion rate to 2 Hz */
401 i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5);
402
403 /* Start conversions (disable shutdown if necessary) */
404 config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
405 if (config < 0) {
406 dev_warn(&client->dev, "Initialization failed!\n");
407 return;
408 }
409
410 config_orig = config;
411 config &= ~TMP401_CONFIG_SHUTDOWN;
412
413 if (config != config_orig)
414 i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config);
415}
416
417static int tmp401_detect(struct i2c_client *client, int kind,
418 struct i2c_board_info *info)
419{
420 struct i2c_adapter *adapter = client->adapter;
421
422 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
423 return -ENODEV;
424
425 /* Detect and identify the chip */
426 if (kind <= 0) {
427 u8 reg;
428
429 reg = i2c_smbus_read_byte_data(client,
430 TMP401_MANUFACTURER_ID_REG);
431 if (reg != TMP401_MANUFACTURER_ID)
432 return -ENODEV;
433
434 reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
435 if (reg != TMP401_DEVICE_ID)
436 return -ENODEV;
437
438 reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
439 if (reg & 0x1b)
440 return -ENODEV;
441
442 reg = i2c_smbus_read_byte_data(client,
443 TMP401_CONVERSION_RATE_READ);
444 if (reg > 15)
445 return -ENODEV;
446 }
447 strlcpy(info->type, "tmp401", I2C_NAME_SIZE);
448
449 return 0;
450}
451
452static int tmp401_probe(struct i2c_client *client,
453 const struct i2c_device_id *id)
454{
455 int i, err = 0;
456 struct tmp401_data *data;
457
458 data = kzalloc(sizeof(struct tmp401_data), GFP_KERNEL);
459 if (!data)
460 return -ENOMEM;
461
462 i2c_set_clientdata(client, data);
463 mutex_init(&data->update_lock);
464
465 /* Initialize the TMP401 chip */
466 tmp401_init_client(client);
467
468 /* Register sysfs hooks */
469 for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) {
470 err = device_create_file(&client->dev,
471 &tmp401_attr[i].dev_attr);
472 if (err)
473 goto exit_remove;
474 }
475
476 data->hwmon_dev = hwmon_device_register(&client->dev);
477 if (IS_ERR(data->hwmon_dev)) {
478 err = PTR_ERR(data->hwmon_dev);
479 data->hwmon_dev = NULL;
480 goto exit_remove;
481 }
482
483 dev_info(&client->dev, "Detected TI TMP401 chip\n");
484
485 return 0;
486
487exit_remove:
488 tmp401_remove(client); /* will also free data for us */
489 return err;
490}
491
492static int tmp401_remove(struct i2c_client *client)
493{
494 struct tmp401_data *data = i2c_get_clientdata(client);
495 int i;
496
497 if (data->hwmon_dev)
498 hwmon_device_unregister(data->hwmon_dev);
499
500 for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++)
501 device_remove_file(&client->dev, &tmp401_attr[i].dev_attr);
502
503 kfree(data);
504 return 0;
505}
506
507static struct tmp401_data *tmp401_update_device(struct device *dev)
508{
509 struct i2c_client *client = to_i2c_client(dev);
510 struct tmp401_data *data = i2c_get_clientdata(client);
511 int i;
512
513 mutex_lock(&data->update_lock);
514
515 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
516 data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS);
517 data->config = i2c_smbus_read_byte_data(client,
518 TMP401_CONFIG_READ);
519 for (i = 0; i < 2; i++) {
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
538 data->temp_crit_hyst = i2c_smbus_read_byte_data(client,
539 TMP401_TEMP_CRIT_HYST);
540
541 data->last_updated = jiffies;
542 data->valid = 1;
543 }
544
545 mutex_unlock(&data->update_lock);
546
547 return data;
548}
549
550static int __init tmp401_init(void)
551{
552 return i2c_add_driver(&tmp401_driver);
553}
554
555static void __exit tmp401_exit(void)
556{
557 i2c_del_driver(&tmp401_driver);
558}
559
560MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
561MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver");
562MODULE_LICENSE("GPL");
563
564module_init(tmp401_init);
565module_exit(tmp401_exit);