blob: 061146288e4167eb0b929fa0162c3df07f60e739 [file] [log] [blame]
Hans de Goedeab2b79d2009-06-15 18:39:46 +02001/* tmp401.c
2 *
3 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
Andre Prendelfce07582009-06-15 18:39:47 +02004 * Preliminary tmp411 support by:
5 * Gabriel Konat, Sander Leget, Wouter Willems
6 * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
Hans de Goedeab2b79d2009-06-15 18:39:46 +02007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23/*
24 * Driver for the Texas Instruments TMP401 SMBUS temperature sensor IC.
25 *
26 * Note this IC is in some aspect similar to the LM90, but it has quite a
27 * few differences too, for example the local temp has a higher resolution
28 * and thus has 16 bits registers for its value and limit instead of 8 bits.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
Guenter Roeck947e9272013-03-27 08:48:03 -070033#include <linux/bitops.h>
Hans de Goedeab2b79d2009-06-15 18:39:46 +020034#include <linux/slab.h>
35#include <linux/jiffies.h>
36#include <linux/i2c.h>
37#include <linux/hwmon.h>
38#include <linux/hwmon-sysfs.h>
39#include <linux/err.h>
40#include <linux/mutex.h>
41#include <linux/sysfs.h>
42
43/* Addresses to scan */
Guenter Roecka1fac922013-03-15 12:55:08 -070044static const unsigned short normal_i2c[] = { 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
Hans de Goedeab2b79d2009-06-15 18:39:46 +020045
Guenter Roecka1fac922013-03-15 12:55:08 -070046enum chips { tmp401, tmp411, tmp431 };
Hans de Goedeab2b79d2009-06-15 18:39:46 +020047
48/*
49 * The TMP401 registers, note some registers have different addresses for
50 * reading and writing
51 */
52#define TMP401_STATUS 0x02
53#define TMP401_CONFIG_READ 0x03
54#define TMP401_CONFIG_WRITE 0x09
55#define TMP401_CONVERSION_RATE_READ 0x04
56#define TMP401_CONVERSION_RATE_WRITE 0x0A
57#define TMP401_TEMP_CRIT_HYST 0x21
Hans de Goedeab2b79d2009-06-15 18:39:46 +020058#define TMP401_MANUFACTURER_ID_REG 0xFE
59#define TMP401_DEVICE_ID_REG 0xFF
60
Guenter Roeck14f2a662013-03-27 21:23:10 -070061static const u8 TMP401_TEMP_MSB_READ[6][2] = {
62 { 0x00, 0x01 }, /* temp */
63 { 0x06, 0x08 }, /* low limit */
64 { 0x05, 0x07 }, /* high limit */
65 { 0x20, 0x19 }, /* therm (crit) limit */
66 { 0x30, 0x34 }, /* lowest */
67 { 0x32, 0x36 }, /* highest */
68};
Hans de Goedeab2b79d2009-06-15 18:39:46 +020069
Guenter Roeck14f2a662013-03-27 21:23:10 -070070static const u8 TMP401_TEMP_MSB_WRITE[6][2] = {
71 { 0, 0 }, /* temp (unused) */
72 { 0x0C, 0x0E }, /* low limit */
73 { 0x0B, 0x0D }, /* high limit */
74 { 0x20, 0x19 }, /* therm (crit) limit */
75 { 0x30, 0x34 }, /* lowest */
76 { 0x32, 0x36 }, /* highest */
77};
78
79static const u8 TMP401_TEMP_LSB[6][2] = {
80 { 0x15, 0x10 }, /* temp */
81 { 0x17, 0x14 }, /* low limit */
82 { 0x16, 0x13 }, /* high limit */
83 { 0, 0 }, /* therm (crit) limit (unused) */
84 { 0x31, 0x35 }, /* lowest */
85 { 0x33, 0x37 }, /* highest */
86};
Andre Prendelfce07582009-06-15 18:39:47 +020087
Hans de Goedeab2b79d2009-06-15 18:39:46 +020088/* Flags */
Guenter Roeck947e9272013-03-27 08:48:03 -070089#define TMP401_CONFIG_RANGE BIT(2)
90#define TMP401_CONFIG_SHUTDOWN BIT(6)
91#define TMP401_STATUS_LOCAL_CRIT BIT(0)
92#define TMP401_STATUS_REMOTE_CRIT BIT(1)
93#define TMP401_STATUS_REMOTE_OPEN BIT(2)
94#define TMP401_STATUS_REMOTE_LOW BIT(3)
95#define TMP401_STATUS_REMOTE_HIGH BIT(4)
96#define TMP401_STATUS_LOCAL_LOW BIT(5)
97#define TMP401_STATUS_LOCAL_HIGH BIT(6)
Hans de Goedeab2b79d2009-06-15 18:39:46 +020098
99/* Manufacturer / Device ID's */
100#define TMP401_MANUFACTURER_ID 0x55
101#define TMP401_DEVICE_ID 0x11
Guenter Roeck4ce5b1f2013-03-29 17:56:07 -0700102#define TMP411A_DEVICE_ID 0x12
103#define TMP411B_DEVICE_ID 0x13
104#define TMP411C_DEVICE_ID 0x10
Guenter Roecka1fac922013-03-15 12:55:08 -0700105#define TMP431_DEVICE_ID 0x31
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200106
107/*
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200108 * Driver data (common to all clients)
109 */
110
111static const struct i2c_device_id tmp401_id[] = {
112 { "tmp401", tmp401 },
Andre Prendelfce07582009-06-15 18:39:47 +0200113 { "tmp411", tmp411 },
Guenter Roecka1fac922013-03-15 12:55:08 -0700114 { "tmp431", tmp431 },
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200115 { }
116};
117MODULE_DEVICE_TABLE(i2c, tmp401_id);
118
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200119/*
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 */
Jean Delvaredc71afe2010-03-05 22:17:26 +0100128 enum chips kind;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200129
130 /* register values */
131 u8 status;
132 u8 config;
Guenter Roeck14f2a662013-03-27 21:23:10 -0700133 u16 temp[6][2];
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200134 u8 temp_crit_hyst;
135};
136
137/*
138 * Sysfs attr show / store functions
139 */
140
141static int tmp401_register_to_temp(u16 reg, u8 config)
142{
143 int temp = reg;
144
145 if (config & TMP401_CONFIG_RANGE)
146 temp -= 64 * 256;
147
Guenter Roeck14f2a662013-03-27 21:23:10 -0700148 return DIV_ROUND_CLOSEST(temp * 125, 32);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200149}
150
Guenter Roeck14f2a662013-03-27 21:23:10 -0700151static u16 tmp401_temp_to_register(long temp, u8 config, int zbits)
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200152{
153 if (config & TMP401_CONFIG_RANGE) {
Guenter Roeck2a844c12013-01-09 08:09:34 -0800154 temp = clamp_val(temp, -64000, 191000);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200155 temp += 64000;
156 } else
Guenter Roeck2a844c12013-01-09 08:09:34 -0800157 temp = clamp_val(temp, 0, 127000);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200158
Guenter Roeck14f2a662013-03-27 21:23:10 -0700159 return DIV_ROUND_CLOSEST(temp * (1 << (8 - zbits)), 1000) << zbits;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200160}
161
Guenter Roeck14f2a662013-03-27 21:23:10 -0700162static int tmp401_update_device_reg16(struct i2c_client *client,
163 struct tmp401_data *data)
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200164{
Guenter Roeck14f2a662013-03-27 21:23:10 -0700165 int i, j, val;
166 int num_regs = data->kind == tmp411 ? 6 : 4;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200167
Guenter Roeck14f2a662013-03-27 21:23:10 -0700168 for (i = 0; i < 2; i++) { /* local / rem1 */
169 for (j = 0; j < num_regs; j++) { /* temp / low / ... */
170 /*
171 * High byte must be read first immediately followed
172 * by the low byte
173 */
174 val = i2c_smbus_read_byte_data(client,
175 TMP401_TEMP_MSB_READ[j][i]);
176 if (val < 0)
177 return val;
178 data->temp[j][i] = val << 8;
179 if (j == 3) /* crit is msb only */
180 continue;
181 val = i2c_smbus_read_byte_data(client,
182 TMP401_TEMP_LSB[j][i]);
183 if (val < 0)
184 return val;
185 data->temp[j][i] |= val;
Andre Prendelea63c2b2010-05-27 19:58:49 +0200186 }
187 }
Guenter Roeck14f2a662013-03-27 21:23:10 -0700188 return 0;
Andre Prendelea63c2b2010-05-27 19:58:49 +0200189}
190
191static struct tmp401_data *tmp401_update_device(struct device *dev)
192{
193 struct i2c_client *client = to_i2c_client(dev);
194 struct tmp401_data *data = i2c_get_clientdata(client);
Guenter Roeck14f2a662013-03-27 21:23:10 -0700195 struct tmp401_data *ret = data;
196 int val;
Andre Prendelea63c2b2010-05-27 19:58:49 +0200197
198 mutex_lock(&data->update_lock);
199
200 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
Guenter Roeck14f2a662013-03-27 21:23:10 -0700201 val = i2c_smbus_read_byte_data(client, TMP401_STATUS);
202 if (val < 0) {
203 ret = ERR_PTR(val);
204 goto abort;
205 }
206 data->status = val;
207 val = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
208 if (val < 0) {
209 ret = ERR_PTR(val);
210 goto abort;
211 }
212 data->config = val;
213 val = tmp401_update_device_reg16(client, data);
214 if (val < 0) {
215 ret = ERR_PTR(val);
216 goto abort;
217 }
218 val = i2c_smbus_read_byte_data(client, TMP401_TEMP_CRIT_HYST);
219 if (val < 0) {
220 ret = ERR_PTR(val);
221 goto abort;
222 }
223 data->temp_crit_hyst = val;
Andre Prendelea63c2b2010-05-27 19:58:49 +0200224
225 data->last_updated = jiffies;
226 data->valid = 1;
227 }
228
Guenter Roeck14f2a662013-03-27 21:23:10 -0700229abort:
Andre Prendelea63c2b2010-05-27 19:58:49 +0200230 mutex_unlock(&data->update_lock);
Guenter Roeck14f2a662013-03-27 21:23:10 -0700231 return ret;
Andre Prendelea63c2b2010-05-27 19:58:49 +0200232}
233
Guenter Roeck14f2a662013-03-27 21:23:10 -0700234static ssize_t show_temp(struct device *dev,
235 struct device_attribute *devattr, char *buf)
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200236{
Guenter Roeck14f2a662013-03-27 21:23:10 -0700237 int nr = to_sensor_dev_attr_2(devattr)->nr;
238 int index = to_sensor_dev_attr_2(devattr)->index;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200239 struct tmp401_data *data = tmp401_update_device(dev);
240
Guenter Roeck14f2a662013-03-27 21:23:10 -0700241 if (IS_ERR(data))
242 return PTR_ERR(data);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200243
244 return sprintf(buf, "%d\n",
Guenter Roeck14f2a662013-03-27 21:23:10 -0700245 tmp401_register_to_temp(data->temp[nr][index], data->config));
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200246}
247
248static ssize_t show_temp_crit_hyst(struct device *dev,
249 struct device_attribute *devattr, char *buf)
250{
251 int temp, index = to_sensor_dev_attr(devattr)->index;
252 struct tmp401_data *data = tmp401_update_device(dev);
253
Guenter Roeck14f2a662013-03-27 21:23:10 -0700254 if (IS_ERR(data))
255 return PTR_ERR(data);
256
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200257 mutex_lock(&data->update_lock);
Guenter Roeck14f2a662013-03-27 21:23:10 -0700258 temp = tmp401_register_to_temp(data->temp[3][index], data->config);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200259 temp -= data->temp_crit_hyst * 1000;
260 mutex_unlock(&data->update_lock);
261
262 return sprintf(buf, "%d\n", temp);
263}
264
265static ssize_t show_status(struct device *dev,
266 struct device_attribute *devattr, char *buf)
267{
268 int mask = to_sensor_dev_attr(devattr)->index;
269 struct tmp401_data *data = tmp401_update_device(dev);
270
Guenter Roeck14f2a662013-03-27 21:23:10 -0700271 if (IS_ERR(data))
272 return PTR_ERR(data);
273
274 return sprintf(buf, "%d\n", !!(data->status & mask));
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200275}
276
Guenter Roeck14f2a662013-03-27 21:23:10 -0700277static ssize_t store_temp(struct device *dev, struct device_attribute *devattr,
278 const char *buf, size_t count)
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200279{
Guenter Roeck14f2a662013-03-27 21:23:10 -0700280 int nr = to_sensor_dev_attr_2(devattr)->nr;
281 int index = to_sensor_dev_attr_2(devattr)->index;
282 struct i2c_client *client = to_i2c_client(dev);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200283 struct tmp401_data *data = tmp401_update_device(dev);
284 long val;
285 u16 reg;
286
Guenter Roeck14f2a662013-03-27 21:23:10 -0700287 if (IS_ERR(data))
288 return PTR_ERR(data);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200289
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100290 if (kstrtol(buf, 10, &val))
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200291 return -EINVAL;
292
Guenter Roeck14f2a662013-03-27 21:23:10 -0700293 reg = tmp401_temp_to_register(val, data->config, nr == 3 ? 8 : 4);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200294
295 mutex_lock(&data->update_lock);
296
Guenter Roeck14f2a662013-03-27 21:23:10 -0700297 i2c_smbus_write_byte_data(client,
298 TMP401_TEMP_MSB_WRITE[nr][index],
299 reg >> 8);
300 if (nr != 3) {
301 i2c_smbus_write_byte_data(client,
302 TMP401_TEMP_LSB[nr][index],
303 reg & 0xFF);
304 }
305 data->temp[nr][index] = reg;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200306
307 mutex_unlock(&data->update_lock);
308
309 return count;
310}
311
312static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute
313 *devattr, const char *buf, size_t count)
314{
315 int temp, index = to_sensor_dev_attr(devattr)->index;
316 struct tmp401_data *data = tmp401_update_device(dev);
317 long val;
318 u8 reg;
319
Guenter Roeck14f2a662013-03-27 21:23:10 -0700320 if (IS_ERR(data))
321 return PTR_ERR(data);
322
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100323 if (kstrtol(buf, 10, &val))
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200324 return -EINVAL;
325
326 if (data->config & TMP401_CONFIG_RANGE)
Guenter Roeck2a844c12013-01-09 08:09:34 -0800327 val = clamp_val(val, -64000, 191000);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200328 else
Guenter Roeck2a844c12013-01-09 08:09:34 -0800329 val = clamp_val(val, 0, 127000);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200330
331 mutex_lock(&data->update_lock);
Guenter Roeck14f2a662013-03-27 21:23:10 -0700332 temp = tmp401_register_to_temp(data->temp[3][index], data->config);
Guenter Roeck2a844c12013-01-09 08:09:34 -0800333 val = clamp_val(val, temp - 255000, temp);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200334 reg = ((temp - val) + 500) / 1000;
335
Guenter Roeck14f2a662013-03-27 21:23:10 -0700336 i2c_smbus_write_byte_data(to_i2c_client(dev), TMP401_TEMP_CRIT_HYST,
337 reg);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200338
339 data->temp_crit_hyst = reg;
340
341 mutex_unlock(&data->update_lock);
342
343 return count;
344}
345
Andre Prendelfce07582009-06-15 18:39:47 +0200346/*
347 * Resets the historical measurements of minimum and maximum temperatures.
348 * This is done by writing any value to any of the minimum/maximum registers
349 * (0x30-0x37).
350 */
351static ssize_t reset_temp_history(struct device *dev,
352 struct device_attribute *devattr, const char *buf, size_t count)
353{
Guenter Roeck8eb6d902013-04-14 04:39:46 -0700354 struct i2c_client *client = to_i2c_client(dev);
355 struct tmp401_data *data = i2c_get_clientdata(client);
Andre Prendelfce07582009-06-15 18:39:47 +0200356 long val;
357
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100358 if (kstrtol(buf, 10, &val))
Andre Prendelfce07582009-06-15 18:39:47 +0200359 return -EINVAL;
360
361 if (val != 1) {
Guenter Roeckb55f3752013-01-10 10:01:24 -0800362 dev_err(dev,
363 "temp_reset_history value %ld not supported. Use 1 to reset the history!\n",
364 val);
Andre Prendelfce07582009-06-15 18:39:47 +0200365 return -EINVAL;
366 }
Guenter Roeck8eb6d902013-04-14 04:39:46 -0700367 mutex_lock(&data->update_lock);
368 i2c_smbus_write_byte_data(client, TMP401_TEMP_MSB_WRITE[5][0], val);
369 data->valid = 0;
370 mutex_unlock(&data->update_lock);
Andre Prendelfce07582009-06-15 18:39:47 +0200371
372 return count;
373}
374
Guenter Roeck14f2a662013-03-27 21:23:10 -0700375static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
376static SENSOR_DEVICE_ATTR_2(temp1_min, S_IWUSR | S_IRUGO, show_temp,
377 store_temp, 1, 0);
378static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp,
379 store_temp, 2, 0);
380static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IWUSR | S_IRUGO, show_temp,
381 store_temp, 3, 0);
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700382static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO,
383 show_temp_crit_hyst, store_temp_crit_hyst, 0);
384static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_status, NULL,
385 TMP401_STATUS_LOCAL_LOW);
386static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_status, NULL,
387 TMP401_STATUS_LOCAL_HIGH);
388static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_status, NULL,
389 TMP401_STATUS_LOCAL_CRIT);
Guenter Roeck14f2a662013-03-27 21:23:10 -0700390static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1);
391static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp,
392 store_temp, 1, 1);
393static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp,
394 store_temp, 2, 1);
395static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IWUSR | S_IRUGO, show_temp,
396 store_temp, 3, 1);
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700397static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst,
398 NULL, 1);
399static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_status, NULL,
400 TMP401_STATUS_REMOTE_OPEN);
401static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_status, NULL,
402 TMP401_STATUS_REMOTE_LOW);
403static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_status, NULL,
404 TMP401_STATUS_REMOTE_HIGH);
405static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_status, NULL,
406 TMP401_STATUS_REMOTE_CRIT);
407
408static struct attribute *tmp401_attributes[] = {
409 &sensor_dev_attr_temp1_input.dev_attr.attr,
410 &sensor_dev_attr_temp1_min.dev_attr.attr,
411 &sensor_dev_attr_temp1_max.dev_attr.attr,
412 &sensor_dev_attr_temp1_crit.dev_attr.attr,
413 &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
414 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
415 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
416 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
417
418 &sensor_dev_attr_temp2_input.dev_attr.attr,
419 &sensor_dev_attr_temp2_min.dev_attr.attr,
420 &sensor_dev_attr_temp2_max.dev_attr.attr,
421 &sensor_dev_attr_temp2_crit.dev_attr.attr,
422 &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
423 &sensor_dev_attr_temp2_fault.dev_attr.attr,
424 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
425 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
426 &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
427
428 NULL
429};
430
431static const struct attribute_group tmp401_group = {
432 .attrs = tmp401_attributes,
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200433};
434
435/*
Andre Prendelfce07582009-06-15 18:39:47 +0200436 * Additional features of the TMP411 chip.
437 * The TMP411 stores the minimum and maximum
438 * temperature measured since power-on, chip-reset, or
439 * minimum and maximum register reset for both the local
440 * and remote channels.
441 */
Guenter Roeck14f2a662013-03-27 21:23:10 -0700442static SENSOR_DEVICE_ATTR_2(temp1_lowest, S_IRUGO, show_temp, NULL, 4, 0);
443static SENSOR_DEVICE_ATTR_2(temp1_highest, S_IRUGO, show_temp, NULL, 5, 0);
444static SENSOR_DEVICE_ATTR_2(temp2_lowest, S_IRUGO, show_temp, NULL, 4, 1);
445static SENSOR_DEVICE_ATTR_2(temp2_highest, S_IRUGO, show_temp, NULL, 5, 1);
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700446static SENSOR_DEVICE_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history,
447 0);
448
449static struct attribute *tmp411_attributes[] = {
450 &sensor_dev_attr_temp1_highest.dev_attr.attr,
451 &sensor_dev_attr_temp1_lowest.dev_attr.attr,
452 &sensor_dev_attr_temp2_highest.dev_attr.attr,
453 &sensor_dev_attr_temp2_lowest.dev_attr.attr,
454 &sensor_dev_attr_temp_reset_history.dev_attr.attr,
455 NULL
456};
457
458static const struct attribute_group tmp411_group = {
459 .attrs = tmp411_attributes,
Andre Prendelfce07582009-06-15 18:39:47 +0200460};
461
462/*
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200463 * Begin non sysfs callback code (aka Real code)
464 */
465
466static void tmp401_init_client(struct i2c_client *client)
467{
468 int config, config_orig;
469
470 /* Set the conversion rate to 2 Hz */
471 i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5);
472
473 /* Start conversions (disable shutdown if necessary) */
474 config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
475 if (config < 0) {
476 dev_warn(&client->dev, "Initialization failed!\n");
477 return;
478 }
479
480 config_orig = config;
481 config &= ~TMP401_CONFIG_SHUTDOWN;
482
483 if (config != config_orig)
484 i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config);
485}
486
Jean Delvare310ec792009-12-14 21:17:23 +0100487static int tmp401_detect(struct i2c_client *client,
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200488 struct i2c_board_info *info)
489{
Jean Delvaredbe73c82009-12-09 20:35:54 +0100490 enum chips kind;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200491 struct i2c_adapter *adapter = client->adapter;
Jean Delvaredbe73c82009-12-09 20:35:54 +0100492 u8 reg;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200493
494 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
495 return -ENODEV;
496
497 /* Detect and identify the chip */
Jean Delvaredbe73c82009-12-09 20:35:54 +0100498 reg = i2c_smbus_read_byte_data(client, TMP401_MANUFACTURER_ID_REG);
499 if (reg != TMP401_MANUFACTURER_ID)
500 return -ENODEV;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200501
Jean Delvaredbe73c82009-12-09 20:35:54 +0100502 reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200503
Jean Delvaredbe73c82009-12-09 20:35:54 +0100504 switch (reg) {
505 case TMP401_DEVICE_ID:
Guenter Roecka1fac922013-03-15 12:55:08 -0700506 if (client->addr != 0x4c)
507 return -ENODEV;
Jean Delvaredbe73c82009-12-09 20:35:54 +0100508 kind = tmp401;
509 break;
Guenter Roeck4ce5b1f2013-03-29 17:56:07 -0700510 case TMP411A_DEVICE_ID:
511 if (client->addr != 0x4c)
512 return -ENODEV;
513 kind = tmp411;
514 break;
515 case TMP411B_DEVICE_ID:
516 if (client->addr != 0x4d)
517 return -ENODEV;
518 kind = tmp411;
519 break;
520 case TMP411C_DEVICE_ID:
521 if (client->addr != 0x4e)
522 return -ENODEV;
Jean Delvaredbe73c82009-12-09 20:35:54 +0100523 kind = tmp411;
524 break;
Guenter Roecka1fac922013-03-15 12:55:08 -0700525 case TMP431_DEVICE_ID:
526 if (client->addr == 0x4e)
527 return -ENODEV;
528 kind = tmp431;
529 break;
Jean Delvaredbe73c82009-12-09 20:35:54 +0100530 default:
531 return -ENODEV;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200532 }
Jean Delvaredbe73c82009-12-09 20:35:54 +0100533
534 reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
535 if (reg & 0x1b)
536 return -ENODEV;
537
538 reg = i2c_smbus_read_byte_data(client, TMP401_CONVERSION_RATE_READ);
539 /* Datasheet says: 0x1-0x6 */
540 if (reg > 15)
541 return -ENODEV;
542
Jean Delvaredc71afe2010-03-05 22:17:26 +0100543 strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200544
545 return 0;
546}
547
Andre Prendelea63c2b2010-05-27 19:58:49 +0200548static int tmp401_remove(struct i2c_client *client)
549{
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700550 struct device *dev = &client->dev;
Andre Prendelea63c2b2010-05-27 19:58:49 +0200551 struct tmp401_data *data = i2c_get_clientdata(client);
Andre Prendelea63c2b2010-05-27 19:58:49 +0200552
553 if (data->hwmon_dev)
554 hwmon_device_unregister(data->hwmon_dev);
555
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700556 sysfs_remove_group(&dev->kobj, &tmp401_group);
Andre Prendelea63c2b2010-05-27 19:58:49 +0200557
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700558 if (data->kind == tmp411)
559 sysfs_remove_group(&dev->kobj, &tmp411_group);
Andre Prendelea63c2b2010-05-27 19:58:49 +0200560
Andre Prendelea63c2b2010-05-27 19:58:49 +0200561 return 0;
562}
563
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200564static int tmp401_probe(struct i2c_client *client,
565 const struct i2c_device_id *id)
566{
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700567 struct device *dev = &client->dev;
568 int err;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200569 struct tmp401_data *data;
Guenter Roecka1fac922013-03-15 12:55:08 -0700570 const char *names[] = { "TMP401", "TMP411", "TMP431" };
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200571
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700572 data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200573 if (!data)
574 return -ENOMEM;
575
576 i2c_set_clientdata(client, data);
577 mutex_init(&data->update_lock);
Andre Prendelfce07582009-06-15 18:39:47 +0200578 data->kind = id->driver_data;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200579
580 /* Initialize the TMP401 chip */
581 tmp401_init_client(client);
582
583 /* Register sysfs hooks */
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700584 err = sysfs_create_group(&dev->kobj, &tmp401_group);
585 if (err)
586 return err;
587
588 /* Register additional tmp411 sysfs hooks */
589 if (data->kind == tmp411) {
590 err = sysfs_create_group(&dev->kobj, &tmp411_group);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200591 if (err)
592 goto exit_remove;
593 }
594
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700595 data->hwmon_dev = hwmon_device_register(dev);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200596 if (IS_ERR(data->hwmon_dev)) {
597 err = PTR_ERR(data->hwmon_dev);
598 data->hwmon_dev = NULL;
599 goto exit_remove;
600 }
601
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700602 dev_info(dev, "Detected TI %s chip\n", names[data->kind]);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200603
604 return 0;
605
606exit_remove:
Guenter Roeck0df9fc72012-06-02 11:35:53 -0700607 tmp401_remove(client);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200608 return err;
609}
610
Andre Prendelea63c2b2010-05-27 19:58:49 +0200611static struct i2c_driver tmp401_driver = {
612 .class = I2C_CLASS_HWMON,
613 .driver = {
614 .name = "tmp401",
615 },
616 .probe = tmp401_probe,
617 .remove = tmp401_remove,
618 .id_table = tmp401_id,
619 .detect = tmp401_detect,
620 .address_list = normal_i2c,
621};
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200622
Axel Linf0967ee2012-01-20 15:38:18 +0800623module_i2c_driver(tmp401_driver);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200624
625MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
626MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver");
627MODULE_LICENSE("GPL");