blob: 4d306b29ba716806f284c074f1ff96172977b9e8 [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{
354 long val;
355
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100356 if (kstrtol(buf, 10, &val))
Andre Prendelfce07582009-06-15 18:39:47 +0200357 return -EINVAL;
358
359 if (val != 1) {
Guenter Roeckb55f3752013-01-10 10:01:24 -0800360 dev_err(dev,
361 "temp_reset_history value %ld not supported. Use 1 to reset the history!\n",
362 val);
Andre Prendelfce07582009-06-15 18:39:47 +0200363 return -EINVAL;
364 }
365 i2c_smbus_write_byte_data(to_i2c_client(dev),
Guenter Roeck14f2a662013-03-27 21:23:10 -0700366 TMP401_TEMP_MSB_WRITE[5][0], val);
Andre Prendelfce07582009-06-15 18:39:47 +0200367
368 return count;
369}
370
Guenter Roeck14f2a662013-03-27 21:23:10 -0700371static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
372static SENSOR_DEVICE_ATTR_2(temp1_min, S_IWUSR | S_IRUGO, show_temp,
373 store_temp, 1, 0);
374static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp,
375 store_temp, 2, 0);
376static SENSOR_DEVICE_ATTR_2(temp1_crit, S_IWUSR | S_IRUGO, show_temp,
377 store_temp, 3, 0);
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700378static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO,
379 show_temp_crit_hyst, store_temp_crit_hyst, 0);
380static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_status, NULL,
381 TMP401_STATUS_LOCAL_LOW);
382static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_status, NULL,
383 TMP401_STATUS_LOCAL_HIGH);
384static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_status, NULL,
385 TMP401_STATUS_LOCAL_CRIT);
Guenter Roeck14f2a662013-03-27 21:23:10 -0700386static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1);
387static SENSOR_DEVICE_ATTR_2(temp2_min, S_IWUSR | S_IRUGO, show_temp,
388 store_temp, 1, 1);
389static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp,
390 store_temp, 2, 1);
391static SENSOR_DEVICE_ATTR_2(temp2_crit, S_IWUSR | S_IRUGO, show_temp,
392 store_temp, 3, 1);
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700393static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst,
394 NULL, 1);
395static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_status, NULL,
396 TMP401_STATUS_REMOTE_OPEN);
397static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_status, NULL,
398 TMP401_STATUS_REMOTE_LOW);
399static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_status, NULL,
400 TMP401_STATUS_REMOTE_HIGH);
401static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_status, NULL,
402 TMP401_STATUS_REMOTE_CRIT);
403
404static struct attribute *tmp401_attributes[] = {
405 &sensor_dev_attr_temp1_input.dev_attr.attr,
406 &sensor_dev_attr_temp1_min.dev_attr.attr,
407 &sensor_dev_attr_temp1_max.dev_attr.attr,
408 &sensor_dev_attr_temp1_crit.dev_attr.attr,
409 &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
410 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
411 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
412 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
413
414 &sensor_dev_attr_temp2_input.dev_attr.attr,
415 &sensor_dev_attr_temp2_min.dev_attr.attr,
416 &sensor_dev_attr_temp2_max.dev_attr.attr,
417 &sensor_dev_attr_temp2_crit.dev_attr.attr,
418 &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr,
419 &sensor_dev_attr_temp2_fault.dev_attr.attr,
420 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
421 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
422 &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
423
424 NULL
425};
426
427static const struct attribute_group tmp401_group = {
428 .attrs = tmp401_attributes,
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200429};
430
431/*
Andre Prendelfce07582009-06-15 18:39:47 +0200432 * Additional features of the TMP411 chip.
433 * The TMP411 stores the minimum and maximum
434 * temperature measured since power-on, chip-reset, or
435 * minimum and maximum register reset for both the local
436 * and remote channels.
437 */
Guenter Roeck14f2a662013-03-27 21:23:10 -0700438static SENSOR_DEVICE_ATTR_2(temp1_lowest, S_IRUGO, show_temp, NULL, 4, 0);
439static SENSOR_DEVICE_ATTR_2(temp1_highest, S_IRUGO, show_temp, NULL, 5, 0);
440static SENSOR_DEVICE_ATTR_2(temp2_lowest, S_IRUGO, show_temp, NULL, 4, 1);
441static SENSOR_DEVICE_ATTR_2(temp2_highest, S_IRUGO, show_temp, NULL, 5, 1);
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700442static SENSOR_DEVICE_ATTR(temp_reset_history, S_IWUSR, NULL, reset_temp_history,
443 0);
444
445static struct attribute *tmp411_attributes[] = {
446 &sensor_dev_attr_temp1_highest.dev_attr.attr,
447 &sensor_dev_attr_temp1_lowest.dev_attr.attr,
448 &sensor_dev_attr_temp2_highest.dev_attr.attr,
449 &sensor_dev_attr_temp2_lowest.dev_attr.attr,
450 &sensor_dev_attr_temp_reset_history.dev_attr.attr,
451 NULL
452};
453
454static const struct attribute_group tmp411_group = {
455 .attrs = tmp411_attributes,
Andre Prendelfce07582009-06-15 18:39:47 +0200456};
457
458/*
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200459 * Begin non sysfs callback code (aka Real code)
460 */
461
462static void tmp401_init_client(struct i2c_client *client)
463{
464 int config, config_orig;
465
466 /* Set the conversion rate to 2 Hz */
467 i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5);
468
469 /* Start conversions (disable shutdown if necessary) */
470 config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
471 if (config < 0) {
472 dev_warn(&client->dev, "Initialization failed!\n");
473 return;
474 }
475
476 config_orig = config;
477 config &= ~TMP401_CONFIG_SHUTDOWN;
478
479 if (config != config_orig)
480 i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config);
481}
482
Jean Delvare310ec792009-12-14 21:17:23 +0100483static int tmp401_detect(struct i2c_client *client,
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200484 struct i2c_board_info *info)
485{
Jean Delvaredbe73c82009-12-09 20:35:54 +0100486 enum chips kind;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200487 struct i2c_adapter *adapter = client->adapter;
Jean Delvaredbe73c82009-12-09 20:35:54 +0100488 u8 reg;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200489
490 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
491 return -ENODEV;
492
493 /* Detect and identify the chip */
Jean Delvaredbe73c82009-12-09 20:35:54 +0100494 reg = i2c_smbus_read_byte_data(client, TMP401_MANUFACTURER_ID_REG);
495 if (reg != TMP401_MANUFACTURER_ID)
496 return -ENODEV;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200497
Jean Delvaredbe73c82009-12-09 20:35:54 +0100498 reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200499
Jean Delvaredbe73c82009-12-09 20:35:54 +0100500 switch (reg) {
501 case TMP401_DEVICE_ID:
Guenter Roecka1fac922013-03-15 12:55:08 -0700502 if (client->addr != 0x4c)
503 return -ENODEV;
Jean Delvaredbe73c82009-12-09 20:35:54 +0100504 kind = tmp401;
505 break;
Guenter Roeck4ce5b1f2013-03-29 17:56:07 -0700506 case TMP411A_DEVICE_ID:
507 if (client->addr != 0x4c)
508 return -ENODEV;
509 kind = tmp411;
510 break;
511 case TMP411B_DEVICE_ID:
512 if (client->addr != 0x4d)
513 return -ENODEV;
514 kind = tmp411;
515 break;
516 case TMP411C_DEVICE_ID:
517 if (client->addr != 0x4e)
518 return -ENODEV;
Jean Delvaredbe73c82009-12-09 20:35:54 +0100519 kind = tmp411;
520 break;
Guenter Roecka1fac922013-03-15 12:55:08 -0700521 case TMP431_DEVICE_ID:
522 if (client->addr == 0x4e)
523 return -ENODEV;
524 kind = tmp431;
525 break;
Jean Delvaredbe73c82009-12-09 20:35:54 +0100526 default:
527 return -ENODEV;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200528 }
Jean Delvaredbe73c82009-12-09 20:35:54 +0100529
530 reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
531 if (reg & 0x1b)
532 return -ENODEV;
533
534 reg = i2c_smbus_read_byte_data(client, TMP401_CONVERSION_RATE_READ);
535 /* Datasheet says: 0x1-0x6 */
536 if (reg > 15)
537 return -ENODEV;
538
Jean Delvaredc71afe2010-03-05 22:17:26 +0100539 strlcpy(info->type, tmp401_id[kind].name, I2C_NAME_SIZE);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200540
541 return 0;
542}
543
Andre Prendelea63c2b2010-05-27 19:58:49 +0200544static int tmp401_remove(struct i2c_client *client)
545{
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700546 struct device *dev = &client->dev;
Andre Prendelea63c2b2010-05-27 19:58:49 +0200547 struct tmp401_data *data = i2c_get_clientdata(client);
Andre Prendelea63c2b2010-05-27 19:58:49 +0200548
549 if (data->hwmon_dev)
550 hwmon_device_unregister(data->hwmon_dev);
551
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700552 sysfs_remove_group(&dev->kobj, &tmp401_group);
Andre Prendelea63c2b2010-05-27 19:58:49 +0200553
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700554 if (data->kind == tmp411)
555 sysfs_remove_group(&dev->kobj, &tmp411_group);
Andre Prendelea63c2b2010-05-27 19:58:49 +0200556
Andre Prendelea63c2b2010-05-27 19:58:49 +0200557 return 0;
558}
559
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200560static int tmp401_probe(struct i2c_client *client,
561 const struct i2c_device_id *id)
562{
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700563 struct device *dev = &client->dev;
564 int err;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200565 struct tmp401_data *data;
Guenter Roecka1fac922013-03-15 12:55:08 -0700566 const char *names[] = { "TMP401", "TMP411", "TMP431" };
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200567
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700568 data = devm_kzalloc(dev, sizeof(struct tmp401_data), GFP_KERNEL);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200569 if (!data)
570 return -ENOMEM;
571
572 i2c_set_clientdata(client, data);
573 mutex_init(&data->update_lock);
Andre Prendelfce07582009-06-15 18:39:47 +0200574 data->kind = id->driver_data;
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200575
576 /* Initialize the TMP401 chip */
577 tmp401_init_client(client);
578
579 /* Register sysfs hooks */
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700580 err = sysfs_create_group(&dev->kobj, &tmp401_group);
581 if (err)
582 return err;
583
584 /* Register additional tmp411 sysfs hooks */
585 if (data->kind == tmp411) {
586 err = sysfs_create_group(&dev->kobj, &tmp411_group);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200587 if (err)
588 goto exit_remove;
589 }
590
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700591 data->hwmon_dev = hwmon_device_register(dev);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200592 if (IS_ERR(data->hwmon_dev)) {
593 err = PTR_ERR(data->hwmon_dev);
594 data->hwmon_dev = NULL;
595 goto exit_remove;
596 }
597
Guenter Roeckb4e665c2013-03-27 08:58:46 -0700598 dev_info(dev, "Detected TI %s chip\n", names[data->kind]);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200599
600 return 0;
601
602exit_remove:
Guenter Roeck0df9fc72012-06-02 11:35:53 -0700603 tmp401_remove(client);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200604 return err;
605}
606
Andre Prendelea63c2b2010-05-27 19:58:49 +0200607static struct i2c_driver tmp401_driver = {
608 .class = I2C_CLASS_HWMON,
609 .driver = {
610 .name = "tmp401",
611 },
612 .probe = tmp401_probe,
613 .remove = tmp401_remove,
614 .id_table = tmp401_id,
615 .detect = tmp401_detect,
616 .address_list = normal_i2c,
617};
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200618
Axel Linf0967ee2012-01-20 15:38:18 +0800619module_i2c_driver(tmp401_driver);
Hans de Goedeab2b79d2009-06-15 18:39:46 +0200620
621MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
622MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver");
623MODULE_LICENSE("GPL");