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