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