d58757fc532a62c4b587395f7208ec852fef3737
[linux-2.6.git] / drivers / misc / nct1008.c
1 /*
2  * drivers/misc/nct1008.c
3  *
4  * Driver for NCT1008, temperature monitoring device from ON Semiconductors
5  *
6  * Copyright (c) 2010-2011, NVIDIA Corporation.
7  *
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, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23
24 #include <linux/interrupt.h>
25 #include <linux/module.h>
26 #include <linux/i2c.h>
27 #include <linux/slab.h>
28 #include <linux/err.h>
29 #include <linux/gpio.h>
30 #include <linux/device.h>
31 #include <linux/nct1008.h>
32 #include <linux/delay.h>
33 #include <linux/regulator/consumer.h>
34
35 /* Register Addresses */
36 #define LOCAL_TEMP_RD                   0x00
37 #define EXT_TEMP_RD_HI                  0x01
38 #define EXT_TEMP_RD_LO                  0x10
39 #define STATUS_RD                       0x02
40 #define CONFIG_RD                       0x03
41
42 #define LOCAL_TEMP_HI_LIMIT_RD          0x05
43 #define LOCAL_TEMP_LO_LIMIT_RD          0x06
44
45 #define EXT_TEMP_HI_LIMIT_HI_BYTE_RD    0x07
46 #define EXT_TEMP_LO_LIMIT_HI_BYTE_RD    0x08
47
48 #define CONFIG_WR                       0x09
49 #define CONV_RATE_WR                    0x0A
50 #define LOCAL_TEMP_HI_LIMIT_WR          0x0B
51 #define LOCAL_TEMP_LO_LIMIT_WR          0x0C
52 #define EXT_TEMP_HI_LIMIT_HI_BYTE_WR    0x0D
53 #define EXT_TEMP_LO_LIMIT_HI_BYTE_WR    0x0E
54 #define ONE_SHOT                        0x0F
55 #define OFFSET_WR                       0x11
56 #define OFFSET_QUARTER_WR               0x12
57 #define EXT_THERM_LIMIT_WR              0x19
58 #define LOCAL_THERM_LIMIT_WR            0x20
59 #define THERM_HYSTERESIS_WR             0x21
60
61 /* Configuration Register Bits */
62 #define EXTENDED_RANGE_BIT              BIT(2)
63 #define THERM2_BIT                      BIT(5)
64 #define STANDBY_BIT                     BIT(6)
65 #define ALERT_BIT                       BIT(7)
66
67 /* Max Temperature Measurements */
68 #define EXTENDED_RANGE_OFFSET           64U
69 #define STANDARD_RANGE_MAX              127U
70 #define EXTENDED_RANGE_MAX              (150U + EXTENDED_RANGE_OFFSET)
71
72 #define NCT1008_MIN_TEMP -64
73 #define NCT1008_MAX_TEMP 191
74
75 #define MAX_STR_PRINT 50
76
77 #define MAX_CONV_TIME_ONESHOT_MS (52)
78 #define CELSIUS_TO_MILLICELSIUS(x) ((x)*1000)
79 #define MILLICELSIUS_TO_CELSIUS(x) ((x)/1000)
80
81
82 static int conv_period_ms_table[] =
83         {16000, 8000, 4000, 2000, 1000, 500, 250, 125, 63, 32, 16};
84
85 static inline s8 value_to_temperature(bool extended, u8 value)
86 {
87         return extended ? (s8)(value - EXTENDED_RANGE_OFFSET) : (s8)value;
88 }
89
90 static inline u8 temperature_to_value(bool extended, s8 temp)
91 {
92         return extended ? (u8)(temp + EXTENDED_RANGE_OFFSET) : (u8)temp;
93 }
94
95 static int nct1008_get_temp(struct device *dev, long *pTemp)
96 {
97         struct i2c_client *client = to_i2c_client(dev);
98         struct nct1008_platform_data *pdata = client->dev.platform_data;
99         s8 temp_local;
100         u8 temp_ext_lo;
101         s8 temp_ext_hi;
102         long temp_ext_milli;
103         long temp_local_milli;
104         u8 value;
105
106         /* Read Local Temp */
107         value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
108         if (value < 0)
109                 goto error;
110         temp_local = value_to_temperature(pdata->ext_range, value);
111         temp_local_milli = CELSIUS_TO_MILLICELSIUS(temp_local);
112
113         /* Read External Temp */
114         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
115         if (value < 0)
116                 goto error;
117         temp_ext_lo = (value >> 6);
118
119         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
120         if (value < 0)
121                 goto error;
122         temp_ext_hi = value_to_temperature(pdata->ext_range, value);
123
124         temp_ext_milli = CELSIUS_TO_MILLICELSIUS(temp_ext_hi) +
125                                 temp_ext_lo * 250;
126
127         /* Return max between Local and External Temp */
128         *pTemp = max(temp_local_milli, temp_ext_milli);
129
130         dev_dbg(dev, "\n %s: ret temp=%ldC ", __func__, *pTemp);
131         return 0;
132 error:
133         dev_err(&client->dev, "\n error in file=: %s %s() line=%d: "
134                 "error=%d ", __FILE__, __func__, __LINE__, value);
135         return value;
136 }
137
138 static ssize_t nct1008_show_temp(struct device *dev,
139         struct device_attribute *attr, char *buf)
140 {
141         struct i2c_client *client = to_i2c_client(dev);
142         struct nct1008_platform_data *pdata = client->dev.platform_data;
143         s8 temp1 = 0;
144         s8 temp = 0;
145         u8 temp2 = 0;
146         int value = 0;
147
148         if (!dev || !buf || !attr)
149                 return -EINVAL;
150
151         value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
152         if (value < 0)
153                 goto error;
154         temp1 = value_to_temperature(pdata->ext_range, value);
155
156         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
157         if (value < 0)
158                 goto error;
159         temp2 = (value >> 6);
160         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
161         if (value < 0)
162                 goto error;
163         temp = value_to_temperature(pdata->ext_range, value);
164
165         return snprintf(buf, MAX_STR_PRINT, "%d %d.%d\n",
166                 temp1, temp, temp2 * 25);
167
168 error:
169         return snprintf(buf, MAX_STR_PRINT,
170                 "Error read local/ext temperature\n");
171 }
172
173 static ssize_t nct1008_show_temp_overheat(struct device *dev,
174                                 struct device_attribute *attr,
175                                 char *buf)
176 {
177         struct i2c_client *client = to_i2c_client(dev);
178         struct nct1008_platform_data *pdata = client->dev.platform_data;
179         int value;
180         s8 temp, temp2;
181
182         /* Local temperature h/w shutdown limit */
183         value = i2c_smbus_read_byte_data(client, LOCAL_THERM_LIMIT_WR);
184         if (value < 0)
185                 goto error;
186         temp = value_to_temperature(pdata->ext_range, value);
187
188         /* External temperature h/w shutdown limit */
189         value = i2c_smbus_read_byte_data(client, EXT_THERM_LIMIT_WR);
190         if (value < 0)
191                 goto error;
192         temp2 = value_to_temperature(pdata->ext_range, value);
193
194         return snprintf(buf, MAX_STR_PRINT, "%d %d\n", temp, temp2);
195 error:
196         dev_err(dev, "%s: failed to read temperature-overheat "
197                 "\n", __func__);
198         return snprintf(buf, MAX_STR_PRINT, " Rd overheat Error\n");
199 }
200
201 static ssize_t nct1008_set_temp_overheat(struct device *dev,
202                         struct device_attribute *attr,
203                         const char *buf, size_t count)
204 {
205         long int num;
206         int err;
207         u8 temp;
208         long currTemp;
209         struct i2c_client *client = to_i2c_client(dev);
210         struct nct1008_platform_data *pdata = client->dev.platform_data;
211         char bufTemp[MAX_STR_PRINT];
212         char bufOverheat[MAX_STR_PRINT];
213         unsigned int ret;
214
215         if (strict_strtol(buf, 0, &num)) {
216                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
217                         __LINE__, __func__);
218                 return -EINVAL;
219         }
220         if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
221                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
222                         __LINE__, __func__);
223                 return -EINVAL;
224         }
225         /* check for system power down */
226         err = nct1008_get_temp(dev, &currTemp);
227         if (err)
228                 goto error;
229
230         currTemp = MILLICELSIUS_TO_CELSIUS(currTemp);
231
232         if (currTemp >= (int)num) {
233                 ret = nct1008_show_temp(dev, attr, bufTemp);
234                 ret = nct1008_show_temp_overheat(dev, attr, bufOverheat);
235                 dev_err(dev, "\nCurrent temp: %s ", bufTemp);
236                 dev_err(dev, "\nOld overheat limit: %s ", bufOverheat);
237                 dev_err(dev, "\nReset from overheat: curr temp=%ld, "
238                         "new overheat temp=%d\n\n", currTemp, (int)num);
239         }
240
241         /* External temperature h/w shutdown limit */
242         temp = temperature_to_value(pdata->ext_range, (s8)num);
243         err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, temp);
244         if (err < 0)
245                 goto error;
246
247         /* Local temperature h/w shutdown limit */
248         temp = temperature_to_value(pdata->ext_range, (s8)num);
249         err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, temp);
250         if (err < 0)
251                 goto error;
252         return count;
253 error:
254         dev_err(dev, " %s: failed to set temperature-overheat\n", __func__);
255         return err;
256 }
257
258 static ssize_t nct1008_show_temp_alert(struct device *dev,
259                                 struct device_attribute *attr,
260                                 char *buf)
261 {
262         struct i2c_client *client = to_i2c_client(dev);
263         struct nct1008_platform_data *pdata = client->dev.platform_data;
264         int value;
265         s8 temp_hi, temp_lo;
266         /* External Temperature Throttling hi-limit */
267         value = i2c_smbus_read_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
268         if (value < 0)
269                 goto error;
270         temp_hi = value_to_temperature(pdata->ext_range, value);
271
272         /* External Temperature Throttling lo-limit */
273         value = i2c_smbus_read_byte_data(client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
274         if (value < 0)
275                 goto error;
276         temp_lo = value_to_temperature(pdata->ext_range, value);
277
278         return snprintf(buf, MAX_STR_PRINT, "lo:%d hi:%d\n", temp_lo, temp_hi);
279 error:
280         dev_err(dev, "%s: failed to read temperature-alert\n", __func__);
281         return snprintf(buf, MAX_STR_PRINT, " Rd alert Error\n");
282 }
283
284 static ssize_t nct1008_set_temp_alert(struct device *dev,
285                         struct device_attribute *attr,
286                         const char *buf, size_t count)
287 {
288         long int num;
289         int value;
290         int err;
291         struct i2c_client *client = to_i2c_client(dev);
292         struct nct1008_platform_data *pdata = client->dev.platform_data;
293
294         if (strict_strtol(buf, 0, &num)) {
295                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
296                         __LINE__, __func__);
297                 return -EINVAL;
298         }
299         if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
300                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
301                         __LINE__, __func__);
302                 return -EINVAL;
303         }
304
305         /* External Temperature Throttling limit */
306         value = temperature_to_value(pdata->ext_range, (s8)num);
307         err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
308                 value);
309         if (err < 0)
310                 goto error;
311
312         /* Local Temperature Throttling limit */
313         err = i2c_smbus_write_byte_data(client, LOCAL_TEMP_HI_LIMIT_WR,
314                 value);
315         if (err < 0)
316                 goto error;
317
318         return count;
319 error:
320         dev_err(dev, "%s: failed to set temperature-alert "
321                 "\n", __func__);
322         return err;
323 }
324
325 static ssize_t nct1008_show_ext_temp(struct device *dev,
326         struct device_attribute *attr, char *buf)
327 {
328         struct i2c_client *client = to_i2c_client(dev);
329         struct nct1008_platform_data *pdata = client->dev.platform_data;
330         s8 temp_value;
331         int data = 0;
332         int data_lo;
333
334         if (!dev || !buf || !attr)
335                 return -EINVAL;
336
337         /* When reading the full external temperature value, read the
338          * LSB first. This causes the MSB to be locked (that is, the
339          * ADC does not write to it) until it is read */
340         data_lo = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
341         if (data_lo < 0) {
342                 dev_err(&client->dev, "%s: failed to read "
343                         "ext_temperature, i2c error=%d\n", __func__, data_lo);
344                 goto error;
345         }
346
347         data = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
348         if (data < 0) {
349                 dev_err(&client->dev, "%s: failed to read "
350                         "ext_temperature, i2c error=%d\n", __func__, data);
351                 goto error;
352         }
353
354         temp_value = value_to_temperature(pdata->ext_range, data);
355
356         return snprintf(buf, MAX_STR_PRINT, "%d.%d\n", temp_value,
357                 (25 * (data_lo >> 6)));
358 error:
359         return snprintf(buf, MAX_STR_PRINT, "Error read ext temperature\n");
360 }
361
362 static DEVICE_ATTR(temperature, S_IRUGO, nct1008_show_temp, NULL);
363 static DEVICE_ATTR(temperature_overheat, (S_IRUGO | (S_IWUSR | S_IWGRP)),
364                 nct1008_show_temp_overheat, nct1008_set_temp_overheat);
365 static DEVICE_ATTR(temperature_alert, (S_IRUGO | (S_IWUSR | S_IWGRP)),
366                 nct1008_show_temp_alert, nct1008_set_temp_alert);
367 static DEVICE_ATTR(ext_temperature, S_IRUGO, nct1008_show_ext_temp, NULL);
368
369 static struct attribute *nct1008_attributes[] = {
370         &dev_attr_temperature.attr,
371         &dev_attr_temperature_overheat.attr,
372         &dev_attr_temperature_alert.attr,
373         &dev_attr_ext_temperature.attr,
374         NULL
375 };
376
377 static const struct attribute_group nct1008_attr_group = {
378         .attrs = nct1008_attributes,
379 };
380
381 #ifdef CONFIG_DEBUG_FS
382 #include <linux/debugfs.h>
383 #include <linux/seq_file.h>
384 static void print_reg(const char *reg_name, struct seq_file *s,
385                 int offset)
386 {
387         struct nct1008_data *nct_data = s->private;
388         int ret;
389
390         ret = i2c_smbus_read_byte_data(nct_data->client,
391                 offset);
392         if (ret >= 0)
393                 seq_printf(s, "Reg %s Addr = 0x%02x Reg 0x%02x "
394                 "Value 0x%02x\n", reg_name,
395                 nct_data->client->addr,
396                         offset, ret);
397         else
398                 seq_printf(s, "%s: line=%d, i2c read error=%d\n",
399                 __func__, __LINE__, ret);
400 }
401
402 static int dbg_nct1008_show(struct seq_file *s, void *unused)
403 {
404         seq_printf(s, "nct1008 nct72 Registers\n");
405         seq_printf(s, "------------------\n");
406         print_reg("Local Temp Value    ",     s, 0x00);
407         print_reg("Ext Temp Value Hi   ",     s, 0x01);
408         print_reg("Status              ",     s, 0x02);
409         print_reg("Configuration       ",     s, 0x03);
410         print_reg("Conversion Rate     ",     s, 0x04);
411         print_reg("Local Temp Hi Limit ",     s, 0x05);
412         print_reg("Local Temp Lo Limit ",     s, 0x06);
413         print_reg("Ext Temp Hi Limit Hi",     s, 0x07);
414         print_reg("Ext Temp Hi Limit Lo",     s, 0x13);
415         print_reg("Ext Temp Lo Limit Hi",     s, 0x08);
416         print_reg("Ext Temp Lo Limit Lo",     s, 0x14);
417         print_reg("Ext Temp Value Lo   ",     s, 0x10);
418         print_reg("Ext Temp Offset Hi  ",     s, 0x11);
419         print_reg("Ext Temp Offset Lo  ",     s, 0x12);
420         print_reg("Ext THERM Limit     ",     s, 0x19);
421         print_reg("Local THERM Limit   ",     s, 0x20);
422         print_reg("THERM Hysteresis    ",     s, 0x21);
423         print_reg("Consecutive ALERT   ",     s, 0x22);
424         return 0;
425 }
426
427 static int dbg_nct1008_open(struct inode *inode, struct file *file)
428 {
429         return single_open(file, dbg_nct1008_show, inode->i_private);
430 }
431
432 static const struct file_operations debug_fops = {
433         .open           = dbg_nct1008_open,
434         .read           = seq_read,
435         .llseek         = seq_lseek,
436         .release        = single_release,
437 };
438
439 static int __init nct1008_debuginit(struct nct1008_data *nct)
440 {
441         int err = 0;
442         struct dentry *d;
443         if (nct->chip == NCT72)
444                 d = debugfs_create_file("nct72", S_IRUGO, NULL,
445                                 (void *)nct, &debug_fops);
446         else
447                 d = debugfs_create_file("nct1008", S_IRUGO, NULL,
448                                 (void *)nct, &debug_fops);
449         if ((!d) || IS_ERR(d)) {
450                 dev_err(&nct->client->dev, "Error: %s debugfs_create_file"
451                         " returned an error\n", __func__);
452                 err = -ENOENT;
453                 goto end;
454         }
455         if (d == ERR_PTR(-ENODEV)) {
456                 dev_err(&nct->client->dev, "Error: %s debugfs not supported "
457                         "error=-ENODEV\n", __func__);
458                 err = -ENODEV;
459         } else {
460                 nct->dent = d;
461         }
462 end:
463         return err;
464 }
465 #else
466 static int __init nct1008_debuginit(struct nct1008_data *nct)
467 {
468         return 0;
469 }
470 #endif
471
472 static int nct1008_enable(struct i2c_client *client)
473 {
474         struct nct1008_data *data = i2c_get_clientdata(client);
475         int err;
476
477         err = i2c_smbus_write_byte_data(client, CONFIG_WR,
478                                   data->config & ~STANDBY_BIT);
479         if (err < 0)
480                 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
481                 __func__, __LINE__, err);
482         return err;
483 }
484
485 static int nct1008_disable(struct i2c_client *client)
486 {
487         struct nct1008_data *data = i2c_get_clientdata(client);
488         int err;
489
490         err = i2c_smbus_write_byte_data(client, CONFIG_WR,
491                                   data->config | STANDBY_BIT);
492         if (err < 0)
493                 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
494                 __func__, __LINE__, err);
495         return err;
496 }
497
498 static int nct1008_within_limits(struct nct1008_data *data)
499 {
500         int intr_status;
501
502         intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD);
503
504         return !(intr_status & (BIT(3) | BIT(4)));
505 }
506
507 static void nct1008_work_func(struct work_struct *work)
508 {
509         struct nct1008_data *data = container_of(work, struct nct1008_data,
510                                                 work);
511         int intr_status;
512         struct timespec ts;
513
514         nct1008_disable(data->client);
515
516         if (data->alert_func)
517                 if (!nct1008_within_limits(data))
518                         data->alert_func(data->alert_data);
519
520         /* Initiate one-shot conversion */
521         i2c_smbus_write_byte_data(data->client, ONE_SHOT, 0x1);
522
523         /* Give hardware necessary time to finish conversion */
524         ts = ns_to_timespec(MAX_CONV_TIME_ONESHOT_MS * 1000 * 1000);
525         hrtimer_nanosleep(&ts, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
526
527         intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD);
528
529         nct1008_enable(data->client);
530
531         enable_irq(data->client->irq);
532 }
533
534 static irqreturn_t nct1008_irq(int irq, void *dev_id)
535 {
536         struct nct1008_data *data = dev_id;
537
538         disable_irq_nosync(irq);
539         queue_work(data->workqueue, &data->work);
540
541         return IRQ_HANDLED;
542 }
543
544 static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
545 {
546         int ret;
547         if (!data->nct_reg) {
548                 data->nct_reg = regulator_get(&data->client->dev, "vdd");
549                 if (IS_ERR_OR_NULL(data->nct_reg)) {
550                         if (PTR_ERR(data->nct_reg) == -ENODEV)
551                                 dev_info(&data->client->dev,
552                                         "no regulator found for vdd."
553                                         " Assuming vdd is always powered");
554                         else
555                                 dev_warn(&data->client->dev, "Error [%ld] in "
556                                         "getting the regulator handle for"
557                                         " vdd\n", PTR_ERR(data->nct_reg));
558                         data->nct_reg = NULL;
559                         return;
560                 }
561         }
562         if (is_enable)
563                 ret = regulator_enable(data->nct_reg);
564         else
565                 ret = regulator_disable(data->nct_reg);
566
567         if (ret < 0)
568                 dev_err(&data->client->dev, "Error in %s rail vdd_nct%s, "
569                         "error %d\n", (is_enable) ? "enabling" : "disabling",
570                         (data->chip == NCT72) ? "72" : "1008",
571                         ret);
572         else
573                 dev_info(&data->client->dev, "success in %s rail vdd_nct%s\n",
574                         (is_enable) ? "enabling" : "disabling",
575                         (data->chip == NCT72) ? "72" : "1008");
576 }
577
578 static int __devinit nct1008_configure_sensor(struct nct1008_data* data)
579 {
580         struct i2c_client *client = data->client;
581         struct nct1008_platform_data *pdata = client->dev.platform_data;
582         u8 value;
583         s8 temp;
584         u8 temp2;
585         int err;
586
587         if (!pdata || !pdata->supported_hwrev)
588                 return -ENODEV;
589
590         /* Place in Standby */
591         data->config = STANDBY_BIT;
592         err = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
593         if (err)
594                 goto error;
595
596         /* External temperature h/w shutdown limit */
597         value = temperature_to_value(pdata->ext_range, NCT1008_MAX_TEMP);
598         err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, value);
599         if (err)
600                 goto error;
601
602         /* Local temperature h/w shutdown limit */
603         value = temperature_to_value(pdata->ext_range, NCT1008_MAX_TEMP);
604         err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, value);
605         if (err)
606                 goto error;
607
608         /* set extended range mode if needed */
609         if (pdata->ext_range)
610                 data->config |= EXTENDED_RANGE_BIT;
611         data->config &= ~(THERM2_BIT | ALERT_BIT);
612
613         err = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
614         if (err)
615                 goto error;
616
617         /* Temperature conversion rate */
618         err = i2c_smbus_write_byte_data(client, CONV_RATE_WR, pdata->conv_rate);
619         if (err)
620                 goto error;
621
622         data->conv_period_ms = conv_period_ms_table[pdata->conv_rate];
623
624         /* Setup local hi and lo limits */
625         err = i2c_smbus_write_byte_data(client,
626                 LOCAL_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
627         if (err)
628                 goto error;
629
630         err = i2c_smbus_write_byte_data(client,
631                 LOCAL_TEMP_LO_LIMIT_WR, 0);
632         if (err)
633                 goto error;
634
635         /* Setup external hi and lo limits */
636         err = i2c_smbus_write_byte_data(client,
637                 EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
638         if (err)
639                 goto error;
640         err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
641                         NCT1008_MAX_TEMP);
642         if (err)
643                 goto error;
644
645         /* read initial temperature */
646         value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
647         if (value < 0) {
648                 err = value;
649                 goto error;
650         }
651         temp = value_to_temperature(pdata->ext_range, value);
652         dev_dbg(&client->dev, "\n initial local temp = %d ", temp);
653
654         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
655         if (value < 0) {
656                 err = value;
657                 goto error;
658         }
659         temp2 = (value >> 6);
660         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
661         if (value < 0) {
662                 err = value;
663                 goto error;
664         }
665         temp = value_to_temperature(pdata->ext_range, value);
666
667         if (temp2 > 0)
668                 dev_dbg(&client->dev, "\n initial ext temp = %d.%d deg",
669                                 temp, temp2 * 25);
670         else
671                 dev_dbg(&client->dev, "\n initial ext temp = %d.0 deg", temp);
672
673         /* Remote channel offset */
674         err = i2c_smbus_write_byte_data(client, OFFSET_WR, pdata->offset / 4);
675         if (err < 0)
676                 goto error;
677
678         /* Remote channel offset fraction (quarters) */
679         err = i2c_smbus_write_byte_data(client, OFFSET_QUARTER_WR,
680                                         (pdata->offset % 4) << 6);
681         if (err < 0)
682                 goto error;
683
684         /* register sysfs hooks */
685         err = sysfs_create_group(&client->dev.kobj, &nct1008_attr_group);
686         if (err < 0) {
687                 dev_err(&client->dev, "\n sysfs create err=%d ", err);
688                 goto error;
689         }
690
691         return 0;
692 error:
693         dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
694         return err;
695 }
696
697 static int __devinit nct1008_configure_irq(struct nct1008_data *data)
698 {
699         data->workqueue = create_singlethread_workqueue((data->chip == NCT72) \
700                                                         ? "nct72" : "nct1008");
701
702         INIT_WORK(&data->work, nct1008_work_func);
703
704         if (data->client->irq < 0)
705                 return 0;
706         else
707                 return request_irq(data->client->irq, nct1008_irq,
708                         IRQF_TRIGGER_LOW,
709                         (data->chip == NCT72) ? "nct72" : "nct1008",
710                         data);
711 }
712
713 int nct1008_thermal_get_temp(struct nct1008_data *data, long *temp)
714 {
715         return nct1008_get_temp(&data->client->dev, temp);
716 }
717
718 int nct1008_thermal_get_temp_low(struct nct1008_data *data, long *temp)
719 {
720         *temp = 0;
721         return 0;
722 }
723
724 int nct1008_thermal_set_limits(struct nct1008_data *data,
725                                 long lo_limit_milli,
726                                 long hi_limit_milli)
727 {
728         int err;
729         u8 value;
730         bool extended_range = data->plat_data.ext_range;
731         long lo_limit = MILLICELSIUS_TO_CELSIUS(lo_limit_milli);
732         long hi_limit = MILLICELSIUS_TO_CELSIUS(hi_limit_milli);
733
734         if (lo_limit >= hi_limit)
735                 return -EINVAL;
736
737         if (data->current_lo_limit != lo_limit) {
738                 value = temperature_to_value(extended_range, lo_limit);
739                 pr_debug("%s: set lo_limit %ld\n", __func__, lo_limit);
740                 err = i2c_smbus_write_byte_data(data->client,
741                                 EXT_TEMP_LO_LIMIT_HI_BYTE_WR, value);
742                 if (err)
743                         return err;
744
745                 data->current_lo_limit = lo_limit;
746         }
747
748         if (data->current_hi_limit != hi_limit) {
749                 value = temperature_to_value(extended_range, hi_limit);
750                 pr_debug("%s: set hi_limit %ld\n", __func__, hi_limit);
751                 err = i2c_smbus_write_byte_data(data->client,
752                                 EXT_TEMP_HI_LIMIT_HI_BYTE_WR, value);
753                 if (err)
754                         return err;
755
756                 data->current_hi_limit = hi_limit;
757         }
758
759         return 0;
760 }
761
762 int nct1008_thermal_set_alert(struct nct1008_data *data,
763                                 void (*alert_func)(void *),
764                                 void *alert_data)
765 {
766         data->alert_data = alert_data;
767         data->alert_func = alert_func;
768
769         return 0;
770 }
771
772 int nct1008_thermal_set_shutdown_temp(struct nct1008_data *data,
773                                         long shutdown_temp_milli)
774 {
775         struct i2c_client *client = data->client;
776         struct nct1008_platform_data *pdata = client->dev.platform_data;
777         int err;
778         u8 value;
779         long shutdown_temp;
780
781         shutdown_temp = MILLICELSIUS_TO_CELSIUS(shutdown_temp_milli);
782
783         /* External temperature h/w shutdown limit */
784         value = temperature_to_value(pdata->ext_range, shutdown_temp);
785         err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, value);
786         if (err)
787                 return err;
788
789         /* Local temperature h/w shutdown limit */
790         value = temperature_to_value(pdata->ext_range, shutdown_temp);
791         err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, value);
792         if (err)
793                 return err;
794
795         return 0;
796 }
797
798 /*
799  * Manufacturer(OnSemi) recommended sequence for
800  * Extended Range mode is as follows
801  * 1. Place in Standby
802  * 2. Scale the THERM and ALERT limits
803  *      appropriately(for Extended Range mode).
804  * 3. Enable Extended Range mode.
805  *      ALERT mask/THERM2 mode may be done here
806  *      as these are not critical
807  * 4. Set Conversion Rate as required
808  * 5. Take device out of Standby
809  */
810
811 /*
812  * function nct1008_probe takes care of initial configuration
813  */
814 static int __devinit nct1008_probe(struct i2c_client *client,
815                                 const struct i2c_device_id *id)
816 {
817         struct nct1008_data *data;
818         int err;
819
820         data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
821         if (!data)
822                 return -ENOMEM;
823
824         data->client = client;
825         data->chip = id->driver_data;
826         memcpy(&data->plat_data, client->dev.platform_data,
827                 sizeof(struct nct1008_platform_data));
828         i2c_set_clientdata(client, data);
829
830         nct1008_power_control(data, true);
831         /* extended range recommended steps 1 through 4 taken care
832          * in nct1008_configure_sensor function */
833         err = nct1008_configure_sensor(data);   /* sensor is in standby */
834         if (err < 0) {
835                 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
836                         __FILE__, __func__, __LINE__);
837                 goto error;
838         }
839
840         err = nct1008_configure_irq(data);
841         if (err < 0) {
842                 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
843                         __FILE__, __func__, __LINE__);
844                 goto error;
845         }
846         dev_info(&client->dev, "%s: initialized\n", __func__);
847
848         /* extended range recommended step 5 is in nct1008_enable function */
849         err = nct1008_enable(client);           /* sensor is running */
850         if (err < 0) {
851                 dev_err(&client->dev, "Error: %s, line=%d, error=%d\n",
852                         __func__, __LINE__, err);
853                 goto error;
854         }
855
856         err = nct1008_debuginit(data);
857         if (err < 0)
858                 err = 0; /* without debugfs we may continue */
859
860         /* notify callback that probe is done */
861         if (data->plat_data.probe_callback)
862                 data->plat_data.probe_callback(data);
863
864         return 0;
865
866 error:
867         dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
868         nct1008_power_control(data, false);
869         if (data->nct_reg)
870                 regulator_put(data->nct_reg);
871         kfree(data);
872         return err;
873 }
874
875 static int __devexit nct1008_remove(struct i2c_client *client)
876 {
877         struct nct1008_data *data = i2c_get_clientdata(client);
878
879         if (data->dent)
880                 debugfs_remove(data->dent);
881
882         free_irq(data->client->irq, data);
883         cancel_work_sync(&data->work);
884         sysfs_remove_group(&client->dev.kobj, &nct1008_attr_group);
885         nct1008_power_control(data, false);
886         if (data->nct_reg)
887                 regulator_put(data->nct_reg);
888
889         kfree(data);
890
891         return 0;
892 }
893
894 #ifdef CONFIG_PM
895 static int nct1008_suspend(struct i2c_client *client, pm_message_t state)
896 {
897         int err;
898
899         disable_irq(client->irq);
900         err = nct1008_disable(client);
901         return err;
902 }
903
904 static int nct1008_resume(struct i2c_client *client)
905 {
906         int err;
907
908         err = nct1008_enable(client);
909         if (err < 0) {
910                 dev_err(&client->dev, "Error: %s, error=%d\n",
911                         __func__, err);
912                 return err;
913         }
914         enable_irq(client->irq);
915
916         return 0;
917 }
918 #endif
919
920 static const struct i2c_device_id nct1008_id[] = {
921         { "nct1008", NCT1008 },
922         { "nct72", NCT72},
923         {}
924 };
925 MODULE_DEVICE_TABLE(i2c, nct1008_id);
926
927 static struct i2c_driver nct1008_driver = {
928         .driver = {
929                 .name   = "nct1008_nct72",
930         },
931         .probe          = nct1008_probe,
932         .remove         = __devexit_p(nct1008_remove),
933         .id_table       = nct1008_id,
934 #ifdef CONFIG_PM
935         .suspend        = nct1008_suspend,
936         .resume         = nct1008_resume,
937 #endif
938 };
939
940 static int __init nct1008_init(void)
941 {
942         return i2c_add_driver(&nct1008_driver);
943 }
944
945 static void __exit nct1008_exit(void)
946 {
947         i2c_del_driver(&nct1008_driver);
948 }
949
950 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008/NCT72");
951 MODULE_LICENSE("GPL");
952
953 module_init(nct1008_init);
954 module_exit(nct1008_exit);