diff options
author | Davide Rizzo <elpa.rizzo@gmail.com> | 2009-03-31 18:24:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 11:59:21 -0400 |
commit | 061603275814544842e7df77d1157eff18565997 (patch) | |
tree | 4582b2e3e156eb2f0984df34e5469c96c3c4f9c0 /drivers/hwmon | |
parent | be84cfc588b19f14764d78556dc7b630ee8c914c (diff) |
hwmon: LM95241 driver
An hwmon driver for the National Semiconductor LM95241 triple temperature
sensors chip
Signed-off-by: Davide Rizzo <elpa-rizzo@gmail.com>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: "Mark M. Hoffman" <mhoffman@lightlink.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/Kconfig | 9 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
-rw-r--r-- | drivers/hwmon/lm95241.c | 527 |
3 files changed, 537 insertions, 0 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 51ff9b3d7ea2..8a91c9971558 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -582,6 +582,15 @@ config SENSORS_LTC4245 | |||
582 | This driver can also be built as a module. If so, the module will | 582 | This driver can also be built as a module. If so, the module will |
583 | be called ltc4245. | 583 | be called ltc4245. |
584 | 584 | ||
585 | config SENSORS_LM95241 | ||
586 | tristate "National Semiconductor LM95241 sensor chip" | ||
587 | depends on I2C | ||
588 | help | ||
589 | If you say yes here you get support for LM95241 sensor chip. | ||
590 | |||
591 | This driver can also be built as a module. If so, the module | ||
592 | will be called lm95241. | ||
593 | |||
585 | config SENSORS_MAX1111 | 594 | config SENSORS_MAX1111 |
586 | tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip" | 595 | tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip" |
587 | depends on SPI_MASTER | 596 | depends on SPI_MASTER |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index e332d6267920..81c88822a3eb 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -64,6 +64,7 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o | |||
64 | obj-$(CONFIG_SENSORS_LM90) += lm90.o | 64 | obj-$(CONFIG_SENSORS_LM90) += lm90.o |
65 | obj-$(CONFIG_SENSORS_LM92) += lm92.o | 65 | obj-$(CONFIG_SENSORS_LM92) += lm92.o |
66 | obj-$(CONFIG_SENSORS_LM93) += lm93.o | 66 | obj-$(CONFIG_SENSORS_LM93) += lm93.o |
67 | obj-$(CONFIG_SENSORS_LM95241) += lm95241.o | ||
67 | obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o | 68 | obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o |
68 | obj-$(CONFIG_SENSORS_MAX1111) += max1111.o | 69 | obj-$(CONFIG_SENSORS_MAX1111) += max1111.o |
69 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o | 70 | obj-$(CONFIG_SENSORS_MAX1619) += max1619.o |
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c new file mode 100644 index 000000000000..091d95f38aaa --- /dev/null +++ b/drivers/hwmon/lm95241.c | |||
@@ -0,0 +1,527 @@ | |||
1 | /* | ||
2 | * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware | ||
3 | * monitoring | ||
4 | * Copyright (C) 2008 Davide Rizzo <elpa-rizzo@gmail.com> | ||
5 | * | ||
6 | * Based on the max1619 driver. The LM95241 is a sensor chip made by National | ||
7 | * Semiconductors. | ||
8 | * It reports up to three temperatures (its own plus up to | ||
9 | * two external ones). Complete datasheet can be | ||
10 | * obtained from National's website at: | ||
11 | * http://www.national.com/ds.cgi/LM/LM95241.pdf | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
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 | static const unsigned short normal_i2c[] = { | ||
40 | 0x19, 0x2a, 0x2b, I2C_CLIENT_END}; | ||
41 | |||
42 | /* Insmod parameters */ | ||
43 | I2C_CLIENT_INSMOD_1(lm95241); | ||
44 | |||
45 | /* LM95241 registers */ | ||
46 | #define LM95241_REG_R_MAN_ID 0xFE | ||
47 | #define LM95241_REG_R_CHIP_ID 0xFF | ||
48 | #define LM95241_REG_R_STATUS 0x02 | ||
49 | #define LM95241_REG_RW_CONFIG 0x03 | ||
50 | #define LM95241_REG_RW_REM_FILTER 0x06 | ||
51 | #define LM95241_REG_RW_TRUTHERM 0x07 | ||
52 | #define LM95241_REG_W_ONE_SHOT 0x0F | ||
53 | #define LM95241_REG_R_LOCAL_TEMPH 0x10 | ||
54 | #define LM95241_REG_R_REMOTE1_TEMPH 0x11 | ||
55 | #define LM95241_REG_R_REMOTE2_TEMPH 0x12 | ||
56 | #define LM95241_REG_R_LOCAL_TEMPL 0x20 | ||
57 | #define LM95241_REG_R_REMOTE1_TEMPL 0x21 | ||
58 | #define LM95241_REG_R_REMOTE2_TEMPL 0x22 | ||
59 | #define LM95241_REG_RW_REMOTE_MODEL 0x30 | ||
60 | |||
61 | /* LM95241 specific bitfields */ | ||
62 | #define CFG_STOP 0x40 | ||
63 | #define CFG_CR0076 0x00 | ||
64 | #define CFG_CR0182 0x10 | ||
65 | #define CFG_CR1000 0x20 | ||
66 | #define CFG_CR2700 0x30 | ||
67 | #define R1MS_SHIFT 0 | ||
68 | #define R2MS_SHIFT 2 | ||
69 | #define R1MS_MASK (0x01 << (R1MS_SHIFT)) | ||
70 | #define R2MS_MASK (0x01 << (R2MS_SHIFT)) | ||
71 | #define R1DF_SHIFT 1 | ||
72 | #define R2DF_SHIFT 2 | ||
73 | #define R1DF_MASK (0x01 << (R1DF_SHIFT)) | ||
74 | #define R2DF_MASK (0x01 << (R2DF_SHIFT)) | ||
75 | #define R1FE_MASK 0x01 | ||
76 | #define R2FE_MASK 0x05 | ||
77 | #define TT1_SHIFT 0 | ||
78 | #define TT2_SHIFT 4 | ||
79 | #define TT_OFF 0 | ||
80 | #define TT_ON 1 | ||
81 | #define TT_MASK 7 | ||
82 | #define MANUFACTURER_ID 0x01 | ||
83 | #define DEFAULT_REVISION 0xA4 | ||
84 | |||
85 | /* Conversions and various macros */ | ||
86 | #define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \ | ||
87 | (val_h)) * 1000 + (val_l) * 1000 / 256) | ||
88 | |||
89 | /* Functions declaration */ | ||
90 | static int lm95241_attach_adapter(struct i2c_adapter *adapter); | ||
91 | static int lm95241_detect(struct i2c_adapter *adapter, int address, | ||
92 | int kind); | ||
93 | static void lm95241_init_client(struct i2c_client *client); | ||
94 | static int lm95241_detach_client(struct i2c_client *client); | ||
95 | static struct lm95241_data *lm95241_update_device(struct device *dev); | ||
96 | |||
97 | /* Driver data (common to all clients) */ | ||
98 | static struct i2c_driver lm95241_driver = { | ||
99 | .driver = { | ||
100 | .name = "lm95241", | ||
101 | }, | ||
102 | .attach_adapter = lm95241_attach_adapter, | ||
103 | .detach_client = lm95241_detach_client, | ||
104 | }; | ||
105 | |||
106 | /* Client data (each client gets its own) */ | ||
107 | struct lm95241_data { | ||
108 | struct i2c_client client; | ||
109 | struct device *hwmon_dev; | ||
110 | struct mutex update_lock; | ||
111 | unsigned long last_updated, rate; /* in jiffies */ | ||
112 | char valid; /* zero until following fields are valid */ | ||
113 | /* registers values */ | ||
114 | u8 local_h, local_l; /* local */ | ||
115 | u8 remote1_h, remote1_l; /* remote1 */ | ||
116 | u8 remote2_h, remote2_l; /* remote2 */ | ||
117 | u8 config, model, trutherm; | ||
118 | }; | ||
119 | |||
120 | /* Sysfs stuff */ | ||
121 | #define show_temp(value) \ | ||
122 | static ssize_t show_##value(struct device *dev, \ | ||
123 | struct device_attribute *attr, char *buf) \ | ||
124 | { \ | ||
125 | struct lm95241_data *data = lm95241_update_device(dev); \ | ||
126 | snprintf(buf, PAGE_SIZE - 1, "%d\n", \ | ||
127 | TEMP_FROM_REG(data->value##_h, data->value##_l)); \ | ||
128 | return strlen(buf); \ | ||
129 | } | ||
130 | show_temp(local); | ||
131 | show_temp(remote1); | ||
132 | show_temp(remote2); | ||
133 | |||
134 | static ssize_t show_rate(struct device *dev, struct device_attribute *attr, | ||
135 | char *buf) | ||
136 | { | ||
137 | struct lm95241_data *data = lm95241_update_device(dev); | ||
138 | |||
139 | snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ); | ||
140 | return strlen(buf); | ||
141 | } | ||
142 | |||
143 | static ssize_t set_rate(struct device *dev, struct device_attribute *attr, | ||
144 | const char *buf, size_t count) | ||
145 | { | ||
146 | struct i2c_client *client = to_i2c_client(dev); | ||
147 | struct lm95241_data *data = i2c_get_clientdata(client); | ||
148 | |||
149 | strict_strtol(buf, 10, &data->rate); | ||
150 | data->rate = data->rate * HZ / 1000; | ||
151 | |||
152 | return count; | ||
153 | } | ||
154 | |||
155 | #define show_type(flag) \ | ||
156 | static ssize_t show_type##flag(struct device *dev, \ | ||
157 | struct device_attribute *attr, char *buf) \ | ||
158 | { \ | ||
159 | struct i2c_client *client = to_i2c_client(dev); \ | ||
160 | struct lm95241_data *data = i2c_get_clientdata(client); \ | ||
161 | \ | ||
162 | snprintf(buf, PAGE_SIZE - 1, \ | ||
163 | data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \ | ||
164 | return strlen(buf); \ | ||
165 | } | ||
166 | show_type(1); | ||
167 | show_type(2); | ||
168 | |||
169 | #define show_min(flag) \ | ||
170 | static ssize_t show_min##flag(struct device *dev, \ | ||
171 | struct device_attribute *attr, char *buf) \ | ||
172 | { \ | ||
173 | struct i2c_client *client = to_i2c_client(dev); \ | ||
174 | struct lm95241_data *data = i2c_get_clientdata(client); \ | ||
175 | \ | ||
176 | snprintf(buf, PAGE_SIZE - 1, \ | ||
177 | data->config & R##flag##DF_MASK ? \ | ||
178 | "-127000\n" : "0\n"); \ | ||
179 | return strlen(buf); \ | ||
180 | } | ||
181 | show_min(1); | ||
182 | show_min(2); | ||
183 | |||
184 | #define show_max(flag) \ | ||
185 | static ssize_t show_max##flag(struct device *dev, \ | ||
186 | struct device_attribute *attr, char *buf) \ | ||
187 | { \ | ||
188 | struct i2c_client *client = to_i2c_client(dev); \ | ||
189 | struct lm95241_data *data = i2c_get_clientdata(client); \ | ||
190 | \ | ||
191 | snprintf(buf, PAGE_SIZE - 1, \ | ||
192 | data->config & R##flag##DF_MASK ? \ | ||
193 | "127000\n" : "255000\n"); \ | ||
194 | return strlen(buf); \ | ||
195 | } | ||
196 | show_max(1); | ||
197 | show_max(2); | ||
198 | |||
199 | #define set_type(flag) \ | ||
200 | static ssize_t set_type##flag(struct device *dev, \ | ||
201 | struct device_attribute *attr, \ | ||
202 | const char *buf, size_t count) \ | ||
203 | { \ | ||
204 | struct i2c_client *client = to_i2c_client(dev); \ | ||
205 | struct lm95241_data *data = i2c_get_clientdata(client); \ | ||
206 | \ | ||
207 | long val; \ | ||
208 | strict_strtol(buf, 10, &val); \ | ||
209 | \ | ||
210 | if ((val == 1) || (val == 2)) { \ | ||
211 | \ | ||
212 | mutex_lock(&data->update_lock); \ | ||
213 | \ | ||
214 | data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \ | ||
215 | if (val == 1) { \ | ||
216 | data->model |= R##flag##MS_MASK; \ | ||
217 | data->trutherm |= (TT_ON << TT##flag##_SHIFT); \ | ||
218 | } \ | ||
219 | else { \ | ||
220 | data->model &= ~R##flag##MS_MASK; \ | ||
221 | data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \ | ||
222 | } \ | ||
223 | \ | ||
224 | data->valid = 0; \ | ||
225 | \ | ||
226 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \ | ||
227 | data->model); \ | ||
228 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \ | ||
229 | data->trutherm); \ | ||
230 | \ | ||
231 | mutex_unlock(&data->update_lock); \ | ||
232 | \ | ||
233 | } \ | ||
234 | return count; \ | ||
235 | } | ||
236 | set_type(1); | ||
237 | set_type(2); | ||
238 | |||
239 | #define set_min(flag) \ | ||
240 | static ssize_t set_min##flag(struct device *dev, \ | ||
241 | struct device_attribute *devattr, const char *buf, size_t count) \ | ||
242 | { \ | ||
243 | struct i2c_client *client = to_i2c_client(dev); \ | ||
244 | struct lm95241_data *data = i2c_get_clientdata(client); \ | ||
245 | \ | ||
246 | long val; \ | ||
247 | strict_strtol(buf, 10, &val); \ | ||
248 | \ | ||
249 | mutex_lock(&data->update_lock); \ | ||
250 | \ | ||
251 | if (val < 0) \ | ||
252 | data->config |= R##flag##DF_MASK; \ | ||
253 | else \ | ||
254 | data->config &= ~R##flag##DF_MASK; \ | ||
255 | \ | ||
256 | data->valid = 0; \ | ||
257 | \ | ||
258 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \ | ||
259 | data->config); \ | ||
260 | \ | ||
261 | mutex_unlock(&data->update_lock); \ | ||
262 | \ | ||
263 | return count; \ | ||
264 | } | ||
265 | set_min(1); | ||
266 | set_min(2); | ||
267 | |||
268 | #define set_max(flag) \ | ||
269 | static ssize_t set_max##flag(struct device *dev, \ | ||
270 | struct device_attribute *devattr, const char *buf, size_t count) \ | ||
271 | { \ | ||
272 | struct i2c_client *client = to_i2c_client(dev); \ | ||
273 | struct lm95241_data *data = i2c_get_clientdata(client); \ | ||
274 | \ | ||
275 | long val; \ | ||
276 | strict_strtol(buf, 10, &val); \ | ||
277 | \ | ||
278 | mutex_lock(&data->update_lock); \ | ||
279 | \ | ||
280 | if (val <= 127000) \ | ||
281 | data->config |= R##flag##DF_MASK; \ | ||
282 | else \ | ||
283 | data->config &= ~R##flag##DF_MASK; \ | ||
284 | \ | ||
285 | data->valid = 0; \ | ||
286 | \ | ||
287 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \ | ||
288 | data->config); \ | ||
289 | \ | ||
290 | mutex_unlock(&data->update_lock); \ | ||
291 | \ | ||
292 | return count; \ | ||
293 | } | ||
294 | set_max(1); | ||
295 | set_max(2); | ||
296 | |||
297 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL); | ||
298 | static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL); | ||
299 | static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL); | ||
300 | static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1); | ||
301 | static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2); | ||
302 | static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1); | ||
303 | static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2); | ||
304 | static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1); | ||
305 | static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2); | ||
306 | static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate); | ||
307 | |||
308 | static struct attribute *lm95241_attributes[] = { | ||
309 | &dev_attr_temp1_input.attr, | ||
310 | &dev_attr_temp2_input.attr, | ||
311 | &dev_attr_temp3_input.attr, | ||
312 | &dev_attr_temp2_type.attr, | ||
313 | &dev_attr_temp3_type.attr, | ||
314 | &dev_attr_temp2_min.attr, | ||
315 | &dev_attr_temp3_min.attr, | ||
316 | &dev_attr_temp2_max.attr, | ||
317 | &dev_attr_temp3_max.attr, | ||
318 | &dev_attr_rate.attr, | ||
319 | NULL | ||
320 | }; | ||
321 | |||
322 | static const struct attribute_group lm95241_group = { | ||
323 | .attrs = lm95241_attributes, | ||
324 | }; | ||
325 | |||
326 | /* Init/exit code */ | ||
327 | static int lm95241_attach_adapter(struct i2c_adapter *adapter) | ||
328 | { | ||
329 | if (!(adapter->class & I2C_CLASS_HWMON)) | ||
330 | return 0; | ||
331 | return i2c_probe(adapter, &addr_data, lm95241_detect); | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * The following function does more than just detection. If detection | ||
336 | * succeeds, it also registers the new chip. | ||
337 | */ | ||
338 | static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind) | ||
339 | { | ||
340 | struct i2c_client *new_client; | ||
341 | struct lm95241_data *data; | ||
342 | int err = 0; | ||
343 | const char *name = ""; | ||
344 | |||
345 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
346 | goto exit; | ||
347 | |||
348 | data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); | ||
349 | if (!data) { | ||
350 | err = -ENOMEM; | ||
351 | goto exit; | ||
352 | } | ||
353 | |||
354 | /* The common I2C client data is placed right before the | ||
355 | LM95241-specific data. */ | ||
356 | new_client = &data->client; | ||
357 | i2c_set_clientdata(new_client, data); | ||
358 | new_client->addr = address; | ||
359 | new_client->adapter = adapter; | ||
360 | new_client->driver = &lm95241_driver; | ||
361 | new_client->flags = 0; | ||
362 | |||
363 | /* | ||
364 | * Now we do the remaining detection. A negative kind means that | ||
365 | * the driver was loaded with no force parameter (default), so we | ||
366 | * must both detect and identify the chip. A zero kind means that | ||
367 | * the driver was loaded with the force parameter, the detection | ||
368 | * step shall be skipped. A positive kind means that the driver | ||
369 | * was loaded with the force parameter and a given kind of chip is | ||
370 | * requested, so both the detection and the identification steps | ||
371 | * are skipped. | ||
372 | */ | ||
373 | if (kind < 0) { /* detection */ | ||
374 | if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) | ||
375 | != MANUFACTURER_ID) | ||
376 | || (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) | ||
377 | < DEFAULT_REVISION)) { | ||
378 | dev_dbg(&adapter->dev, | ||
379 | "LM95241 detection failed at 0x%02x.\n", | ||
380 | address); | ||
381 | goto exit_free; | ||
382 | } | ||
383 | } | ||
384 | |||
385 | if (kind <= 0) { /* identification */ | ||
386 | if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) | ||
387 | == MANUFACTURER_ID) | ||
388 | && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) | ||
389 | >= DEFAULT_REVISION)) { | ||
390 | |||
391 | kind = lm95241; | ||
392 | |||
393 | if (kind <= 0) { /* identification failed */ | ||
394 | dev_info(&adapter->dev, "Unsupported chip\n"); | ||
395 | goto exit_free; | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | |||
400 | if (kind == lm95241) | ||
401 | name = "lm95241"; | ||
402 | |||
403 | /* We can fill in the remaining client fields */ | ||
404 | strlcpy(new_client->name, name, I2C_NAME_SIZE); | ||
405 | data->valid = 0; | ||
406 | mutex_init(&data->update_lock); | ||
407 | |||
408 | /* Tell the I2C layer a new client has arrived */ | ||
409 | err = i2c_attach_client(new_client); | ||
410 | if (err) | ||
411 | goto exit_free; | ||
412 | |||
413 | /* Initialize the LM95241 chip */ | ||
414 | lm95241_init_client(new_client); | ||
415 | |||
416 | /* Register sysfs hooks */ | ||
417 | err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group); | ||
418 | if (err) | ||
419 | goto exit_detach; | ||
420 | |||
421 | data->hwmon_dev = hwmon_device_register(&new_client->dev); | ||
422 | if (IS_ERR(data->hwmon_dev)) { | ||
423 | err = PTR_ERR(data->hwmon_dev); | ||
424 | goto exit_remove_files; | ||
425 | } | ||
426 | |||
427 | return 0; | ||
428 | |||
429 | exit_remove_files: | ||
430 | sysfs_remove_group(&new_client->dev.kobj, &lm95241_group); | ||
431 | exit_detach: | ||
432 | i2c_detach_client(new_client); | ||
433 | exit_free: | ||
434 | kfree(data); | ||
435 | exit: | ||
436 | return err; | ||
437 | } | ||
438 | |||
439 | static void lm95241_init_client(struct i2c_client *client) | ||
440 | { | ||
441 | struct lm95241_data *data = i2c_get_clientdata(client); | ||
442 | |||
443 | data->rate = HZ; /* 1 sec default */ | ||
444 | data->valid = 0; | ||
445 | data->config = CFG_CR0076; | ||
446 | data->model = 0; | ||
447 | data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT); | ||
448 | |||
449 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, | ||
450 | data->config); | ||
451 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER, | ||
452 | R1FE_MASK | R2FE_MASK); | ||
453 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, | ||
454 | data->trutherm); | ||
455 | i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, | ||
456 | data->model); | ||
457 | } | ||
458 | |||
459 | static int lm95241_detach_client(struct i2c_client *client) | ||
460 | { | ||
461 | struct lm95241_data *data = i2c_get_clientdata(client); | ||
462 | int err; | ||
463 | |||
464 | hwmon_device_unregister(data->hwmon_dev); | ||
465 | sysfs_remove_group(&client->dev.kobj, &lm95241_group); | ||
466 | |||
467 | err = i2c_detach_client(client); | ||
468 | if (err) | ||
469 | return err; | ||
470 | |||
471 | kfree(data); | ||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static struct lm95241_data *lm95241_update_device(struct device *dev) | ||
476 | { | ||
477 | struct i2c_client *client = to_i2c_client(dev); | ||
478 | struct lm95241_data *data = i2c_get_clientdata(client); | ||
479 | |||
480 | mutex_lock(&data->update_lock); | ||
481 | |||
482 | if (time_after(jiffies, data->last_updated + data->rate) || | ||
483 | !data->valid) { | ||
484 | dev_dbg(&client->dev, "Updating lm95241 data.\n"); | ||
485 | data->local_h = | ||
486 | i2c_smbus_read_byte_data(client, | ||
487 | LM95241_REG_R_LOCAL_TEMPH); | ||
488 | data->local_l = | ||
489 | i2c_smbus_read_byte_data(client, | ||
490 | LM95241_REG_R_LOCAL_TEMPL); | ||
491 | data->remote1_h = | ||
492 | i2c_smbus_read_byte_data(client, | ||
493 | LM95241_REG_R_REMOTE1_TEMPH); | ||
494 | data->remote1_l = | ||
495 | i2c_smbus_read_byte_data(client, | ||
496 | LM95241_REG_R_REMOTE1_TEMPL); | ||
497 | data->remote2_h = | ||
498 | i2c_smbus_read_byte_data(client, | ||
499 | LM95241_REG_R_REMOTE2_TEMPH); | ||
500 | data->remote2_l = | ||
501 | i2c_smbus_read_byte_data(client, | ||
502 | LM95241_REG_R_REMOTE2_TEMPL); | ||
503 | data->last_updated = jiffies; | ||
504 | data->valid = 1; | ||
505 | } | ||
506 | |||
507 | mutex_unlock(&data->update_lock); | ||
508 | |||
509 | return data; | ||
510 | } | ||
511 | |||
512 | static int __init sensors_lm95241_init(void) | ||
513 | { | ||
514 | return i2c_add_driver(&lm95241_driver); | ||
515 | } | ||
516 | |||
517 | static void __exit sensors_lm95241_exit(void) | ||
518 | { | ||
519 | i2c_del_driver(&lm95241_driver); | ||
520 | } | ||
521 | |||
522 | MODULE_AUTHOR("Davide Rizzo <elpa-rizzo@gmail.com>"); | ||
523 | MODULE_DESCRIPTION("LM95241 sensor driver"); | ||
524 | MODULE_LICENSE("GPL"); | ||
525 | |||
526 | module_init(sensors_lm95241_init); | ||
527 | module_exit(sensors_lm95241_exit); | ||