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