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