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