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