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