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