misc: nct1008: added shutdown functionality
[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 s8 value_to_temperature(bool extended, u8 value)
106 {
107         return extended ? (s8)(value - EXTENDED_RANGE_OFFSET) : (s8)value;
108 }
109
110 static inline u8 temperature_to_value(bool extended, s8 temp)
111 {
112         return extended ? (u8)(temp + EXTENDED_RANGE_OFFSET) : (u8)temp;
113 }
114
115 static int nct1008_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         s8 temp_local;
152         u8 temp_ext_lo;
153         s8 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         s8 temp1 = 0;
200         s8 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         s8 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, (s8)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, (s8)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         s8 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, (s8)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         s8 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 temp, trip_temp, low_temp = 0, high_temp = NCT1008_MAX_TEMP * 1000;
478         int count;
479         enum events type = 0;
480
481         if (!thz)
482                 return;
483
484         thermal_zone_device_update(thz);
485
486         thz->ops->get_temp(thz, &temp);
487
488         for (count = 0; count < thz->trips; count++) {
489                 thz->ops->get_trip_temp(thz, count, &trip_temp);
490
491                 if ((trip_temp >= temp) && (trip_temp < high_temp)) {
492                         high_temp = trip_temp;
493                         type = THERMAL_AUX1;
494                 }
495
496                 if ((trip_temp < temp) && (trip_temp > low_temp)) {
497                         low_temp = trip_temp -
498                                    data->plat_data.trips[count].hysteresis;
499                         type = THERMAL_AUX0;
500                 }
501         }
502
503         thermal_generate_netlink_event(thz->id, type);
504         nct1008_thermal_set_limits(data, low_temp, high_temp);
505 }
506
507 static int nct1008_ext_get_temp(struct thermal_zone_device *thz,
508                                         unsigned long *temp)
509 {
510         struct nct1008_data *data = thz->devdata;
511         struct i2c_client *client = data->client;
512         struct nct1008_platform_data *pdata = client->dev.platform_data;
513         s8 temp_ext_hi;
514         s8 temp_ext_lo;
515         long temp_ext_milli;
516         u8 value;
517
518         /* Read External Temp */
519         value = nct1008_read_reg(client, EXT_TEMP_RD_LO);
520         if (value < 0)
521                 return -1;
522         temp_ext_lo = (value >> 6);
523
524         value = nct1008_read_reg(client, EXT_TEMP_RD_HI);
525         if (value < 0)
526                 return -1;
527         temp_ext_hi = value_to_temperature(pdata->ext_range, value);
528
529         temp_ext_milli = CELSIUS_TO_MILLICELSIUS(temp_ext_hi) +
530                          temp_ext_lo * 250;
531         *temp = temp_ext_milli;
532         data->etemp = temp_ext_milli;
533
534         return 0;
535 }
536
537 static int nct1008_ext_bind(struct thermal_zone_device *thz,
538                             struct thermal_cooling_device *cdev)
539 {
540         struct nct1008_data *data = thz->devdata;
541         int i;
542         bool bind = false;
543
544         for (i = 0; i < data->plat_data.num_trips; i++) {
545                 if (!strcmp(data->plat_data.trips[i].cdev_type, cdev->type)) {
546                         thermal_zone_bind_cooling_device(thz, i, cdev,
547                                         data->plat_data.trips[i].state,
548                                         data->plat_data.trips[i].state);
549                         bind = true;
550                 }
551         }
552
553         if (bind)
554                 nct1008_update(data);
555
556         return 0;
557 }
558
559 static int nct1008_ext_unbind(struct thermal_zone_device *thz,
560                               struct thermal_cooling_device *cdev)
561 {
562         struct nct1008_data *data = thz->devdata;
563         int i;
564
565         for (i = 0; i < data->plat_data.num_trips; i++) {
566                 if (!strcmp(data->plat_data.trips[i].cdev_type, cdev->type))
567                         thermal_zone_unbind_cooling_device(thz, i, cdev);
568         }
569         return 0;
570 }
571
572 static int nct1008_ext_get_trip_temp(struct thermal_zone_device *thz,
573                                      int trip,
574                                      unsigned long *temp)
575 {
576         struct nct1008_data *data = thz->devdata;
577
578         *temp = data->plat_data.trips[trip].trip_temp;
579         return 0;
580 }
581
582 static int nct1008_ext_set_trip_temp(struct thermal_zone_device *thz,
583                                      int trip,
584                                      unsigned long temp)
585 {
586         struct nct1008_data *data = thz->devdata;
587
588         data->plat_data.trips[trip].trip_temp = temp;
589         nct1008_update(data);
590         return 0;
591 }
592
593 static int nct1008_ext_get_trip_type(struct thermal_zone_device *thz,
594                                      int trip,
595                                      enum thermal_trip_type *type)
596 {
597         struct nct1008_data *data = thz->devdata;
598
599         *type = data->plat_data.trips[trip].trip_type;
600         return 0;
601 }
602
603 static int nct1008_ext_get_trend(struct thermal_zone_device *thz,
604                                  int trip,
605                                  enum thermal_trend *trend)
606 {
607         struct nct1008_data *data = thz->devdata;
608         struct nct_trip_temp *trip_state;
609
610         trip_state = &data->plat_data.trips[trip];
611
612         switch (trip_state->trip_type) {
613         case THERMAL_TRIP_ACTIVE:
614                 /* aggressive active cooling */
615                 *trend = THERMAL_TREND_RAISING;
616                 break;
617         case THERMAL_TRIP_PASSIVE:
618                 if (data->etemp > trip_state->trip_temp)
619                         *trend = THERMAL_TREND_RAISING;
620                 else
621                         *trend = THERMAL_TREND_DROPPING;
622                 break;
623         default:
624                 return -EINVAL;
625         }
626
627         return 0;
628 }
629
630 static int nct1008_int_get_temp(struct thermal_zone_device *thz,
631                                 unsigned long *temp)
632 {
633         struct nct1008_data *data = thz->devdata;
634         struct i2c_client *client = data->client;
635         struct nct1008_platform_data *pdata = client->dev.platform_data;
636         s8 temp_local;
637         long temp_local_milli;
638         u8 value;
639
640         /* Read Local Temp */
641         value = nct1008_read_reg(client, LOCAL_TEMP_RD);
642         if (value < 0)
643                 return -1;
644         temp_local = value_to_temperature(pdata->ext_range, value);
645
646         temp_local_milli = CELSIUS_TO_MILLICELSIUS(temp_local);
647         *temp = temp_local_milli;
648
649         return 0;
650 }
651
652 static int nct1008_int_bind(struct thermal_zone_device *thz,
653                             struct thermal_cooling_device *cdev)
654 {
655         return 0;
656 }
657
658 static int nct1008_int_get_trip_temp(struct thermal_zone_device *thz,
659                                      int trip,
660                                      unsigned long *temp)
661 {
662         return -1;
663 }
664
665 static int nct1008_int_get_trip_type(struct thermal_zone_device *thz,
666                                      int trip,
667                                      enum thermal_trip_type *type)
668 {
669         return -1;
670 }
671
672 static struct thermal_zone_device_ops nct_int_ops = {
673         .get_temp = nct1008_int_get_temp,
674         .bind = nct1008_int_bind,
675         .unbind = nct1008_int_bind,
676         .get_trip_type = nct1008_int_get_trip_type,
677         .get_trip_temp = nct1008_int_get_trip_temp,
678 };
679
680 static struct thermal_zone_device_ops nct_ext_ops = {
681         .get_temp = nct1008_ext_get_temp,
682         .bind = nct1008_ext_bind,
683         .unbind = nct1008_ext_unbind,
684         .get_trip_type = nct1008_ext_get_trip_type,
685         .get_trip_temp = nct1008_ext_get_trip_temp,
686         .set_trip_temp = nct1008_ext_set_trip_temp,
687         .get_trend = nct1008_ext_get_trend,
688 };
689 #else
690 static void nct1008_update(struct nct1008_data *data)
691 {
692 }
693 #endif /* CONFIG_THERMAL */
694
695 #ifdef CONFIG_DEBUG_FS
696 #include <linux/debugfs.h>
697 #include <linux/seq_file.h>
698 static void print_reg(const char *reg_name, struct seq_file *s,
699                 int offset)
700 {
701         struct nct1008_data *nct_data = s->private;
702         int ret;
703
704         ret = nct1008_read_reg(nct_data->client, offset);
705         if (ret >= 0)
706                 seq_printf(s, "Reg %s Addr = 0x%02x Reg 0x%02x "
707                 "Value 0x%02x\n", reg_name,
708                 nct_data->client->addr,
709                         offset, ret);
710         else
711                 seq_printf(s, "%s: line=%d, i2c read error=%d\n",
712                 __func__, __LINE__, ret);
713 }
714
715 static int dbg_nct1008_show(struct seq_file *s, void *unused)
716 {
717         seq_printf(s, "nct1008 nct72 Registers\n");
718         seq_printf(s, "------------------\n");
719         print_reg("Local Temp Value    ",     s, 0x00);
720         print_reg("Ext Temp Value Hi   ",     s, 0x01);
721         print_reg("Status              ",     s, 0x02);
722         print_reg("Configuration       ",     s, 0x03);
723         print_reg("Conversion Rate     ",     s, 0x04);
724         print_reg("Local Temp Hi Limit ",     s, 0x05);
725         print_reg("Local Temp Lo Limit ",     s, 0x06);
726         print_reg("Ext Temp Hi Limit Hi",     s, 0x07);
727         print_reg("Ext Temp Hi Limit Lo",     s, 0x13);
728         print_reg("Ext Temp Lo Limit Hi",     s, 0x08);
729         print_reg("Ext Temp Lo Limit Lo",     s, 0x14);
730         print_reg("Ext Temp Value Lo   ",     s, 0x10);
731         print_reg("Ext Temp Offset Hi  ",     s, 0x11);
732         print_reg("Ext Temp Offset Lo  ",     s, 0x12);
733         print_reg("Ext THERM Limit     ",     s, 0x19);
734         print_reg("Local THERM Limit   ",     s, 0x20);
735         print_reg("THERM Hysteresis    ",     s, 0x21);
736         print_reg("Consecutive ALERT   ",     s, 0x22);
737         return 0;
738 }
739
740 static int dbg_nct1008_open(struct inode *inode, struct file *file)
741 {
742         return single_open(file, dbg_nct1008_show, inode->i_private);
743 }
744
745 static const struct file_operations debug_fops = {
746         .open           = dbg_nct1008_open,
747         .read           = seq_read,
748         .llseek         = seq_lseek,
749         .release        = single_release,
750 };
751
752 static int nct1008_debuginit(struct nct1008_data *nct)
753 {
754         int err = 0;
755         struct dentry *d;
756         if (nct->chip == NCT72)
757                 d = debugfs_create_file("nct72", S_IRUGO, NULL,
758                                 (void *)nct, &debug_fops);
759         else
760                 d = debugfs_create_file("nct1008", S_IRUGO, NULL,
761                                 (void *)nct, &debug_fops);
762         if ((!d) || IS_ERR(d)) {
763                 dev_err(&nct->client->dev, "Error: %s debugfs_create_file"
764                         " returned an error\n", __func__);
765                 err = -ENOENT;
766                 goto end;
767         }
768         if (d == ERR_PTR(-ENODEV)) {
769                 dev_err(&nct->client->dev, "Error: %s debugfs not supported "
770                         "error=-ENODEV\n", __func__);
771                 err = -ENODEV;
772         } else {
773                 nct->dent = d;
774         }
775 end:
776         return err;
777 }
778 #else
779 static int nct1008_debuginit(struct nct1008_data *nct)
780 {
781         return 0;
782 }
783 #endif /* CONFIG_DEBUG_FS */
784
785 static int nct1008_enable(struct i2c_client *client)
786 {
787         struct nct1008_data *data = i2c_get_clientdata(client);
788         int err;
789
790         err = nct1008_write_reg(client, CONFIG_WR, data->config);
791         if (err < 0)
792                 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
793                 __func__, __LINE__, err);
794         return err;
795 }
796
797 static int nct1008_disable(struct i2c_client *client)
798 {
799         struct nct1008_data *data = i2c_get_clientdata(client);
800         int err;
801
802         err = nct1008_write_reg(client, CONFIG_WR,
803                                 data->config | STANDBY_BIT);
804         if (err < 0)
805                 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
806                 __func__, __LINE__, err);
807         return err;
808 }
809
810 static int nct1008_within_limits(struct nct1008_data *data)
811 {
812         int intr_status;
813
814         intr_status = nct1008_read_reg(data->client, STATUS_RD);
815         if (intr_status < 0)
816                 return intr_status;
817
818         return !(intr_status & (BIT(3) | BIT(4)));
819 }
820
821 static void nct1008_work_func(struct work_struct *work)
822 {
823         struct nct1008_data *data = container_of(work, struct nct1008_data,
824                                                 work);
825         int err;
826         struct timespec ts;
827
828         err = nct1008_disable(data->client);
829         if (err == -ENODEV)
830                 return;
831
832         if (!nct1008_within_limits(data))
833                 nct1008_update(data);
834
835         /* Initiate one-shot conversion */
836         nct1008_write_reg(data->client, ONE_SHOT, 0x1);
837
838         /* Give hardware necessary time to finish conversion */
839         ts = ns_to_timespec(MAX_CONV_TIME_ONESHOT_MS * 1000 * 1000);
840         hrtimer_nanosleep(&ts, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
841
842         nct1008_read_reg(data->client, STATUS_RD);
843
844         nct1008_enable(data->client);
845
846         enable_irq(data->client->irq);
847 }
848
849 static irqreturn_t nct1008_irq(int irq, void *dev_id)
850 {
851         struct nct1008_data *data = dev_id;
852
853         disable_irq_nosync(irq);
854         queue_work(data->workqueue, &data->work);
855
856         return IRQ_HANDLED;
857 }
858
859 static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
860 {
861         int ret;
862         if (!data->nct_reg) {
863                 data->nct_reg = regulator_get(&data->client->dev, "vdd");
864                 if (IS_ERR_OR_NULL(data->nct_reg)) {
865                         if (PTR_ERR(data->nct_reg) == -ENODEV)
866                                 dev_info(&data->client->dev,
867                                         "no regulator found for vdd."
868                                         " Assuming vdd is always powered");
869                         else
870                                 dev_warn(&data->client->dev, "Error [%ld] in "
871                                         "getting the regulator handle for"
872                                         " vdd\n", PTR_ERR(data->nct_reg));
873                         data->nct_reg = NULL;
874                         return;
875                 }
876         }
877         if (is_enable) {
878                 ret = regulator_enable(data->nct_reg);
879                 usleep_range(100, 1000);
880         } else {
881                 ret = regulator_disable(data->nct_reg);
882         }
883
884         if (ret < 0)
885                 dev_err(&data->client->dev, "Error in %s rail vdd_nct%s, "
886                         "error %d\n", (is_enable) ? "enabling" : "disabling",
887                         (data->chip == NCT72) ? "72" : "1008",
888                         ret);
889         else
890                 dev_info(&data->client->dev, "success in %s rail vdd_nct%s\n",
891                         (is_enable) ? "enabling" : "disabling",
892                         (data->chip == NCT72) ? "72" : "1008");
893 }
894
895 static int nct1008_configure_sensor(struct nct1008_data *data)
896 {
897         struct i2c_client *client = data->client;
898         struct nct1008_platform_data *pdata = client->dev.platform_data;
899         u8 value;
900         s8 temp;
901         u8 temp2;
902         int err;
903
904         if (!pdata || !pdata->supported_hwrev)
905                 return -ENODEV;
906
907         /* Initially place in Standby */
908         err = nct1008_write_reg(client, CONFIG_WR, STANDBY_BIT);
909         if (err)
910                 goto error;
911
912         /* External temperature h/w shutdown limit */
913         value = temperature_to_value(pdata->ext_range,
914                                         pdata->shutdown_ext_limit);
915         err = nct1008_write_reg(client, EXT_THERM_LIMIT_WR, value);
916         if (err)
917                 goto error;
918
919         /* Local temperature h/w shutdown limit */
920         value = temperature_to_value(pdata->ext_range,
921                                         pdata->shutdown_local_limit);
922         err = nct1008_write_reg(client, LOCAL_THERM_LIMIT_WR, value);
923         if (err)
924                 goto error;
925
926         /* set extended range mode if needed */
927         if (pdata->ext_range)
928                 data->config |= EXTENDED_RANGE_BIT;
929         data->config &= ~(THERM2_BIT | ALERT_BIT);
930
931         err = nct1008_write_reg(client, CONFIG_WR, data->config);
932         if (err)
933                 goto error;
934
935         /* Temperature conversion rate */
936         err = nct1008_write_reg(client, CONV_RATE_WR, pdata->conv_rate);
937         if (err)
938                 goto error;
939
940         data->conv_period_ms = conv_period_ms_table[pdata->conv_rate];
941
942         /* Setup local hi and lo limits */
943         err = nct1008_write_reg(client,
944                 LOCAL_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
945         if (err)
946                 goto error;
947
948         err = nct1008_write_reg(client, LOCAL_TEMP_LO_LIMIT_WR, 0);
949         if (err)
950                 goto error;
951
952         /* Setup external hi and lo limits */
953         err = nct1008_write_reg(client, EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
954         if (err)
955                 goto error;
956         err = nct1008_write_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
957                         NCT1008_MAX_TEMP);
958         if (err)
959                 goto error;
960
961         /* read initial temperature */
962         value = nct1008_read_reg(client, LOCAL_TEMP_RD);
963         if (value < 0) {
964                 err = value;
965                 goto error;
966         }
967         temp = value_to_temperature(pdata->ext_range, value);
968         dev_dbg(&client->dev, "\n initial local temp = %d ", temp);
969
970         value = nct1008_read_reg(client, EXT_TEMP_RD_LO);
971         if (value < 0) {
972                 err = value;
973                 goto error;
974         }
975         temp2 = (value >> 6);
976         value = nct1008_read_reg(client, EXT_TEMP_RD_HI);
977         if (value < 0) {
978                 err = value;
979                 goto error;
980         }
981         temp = value_to_temperature(pdata->ext_range, value);
982
983         if (temp2 > 0)
984                 dev_dbg(&client->dev, "\n initial ext temp = %d.%d deg",
985                                 temp, temp2 * 25);
986         else
987                 dev_dbg(&client->dev, "\n initial ext temp = %d.0 deg", temp);
988
989         /* Remote channel offset */
990         err = nct1008_write_reg(client, OFFSET_WR, pdata->offset / 4);
991         if (err < 0)
992                 goto error;
993
994         /* Remote channel offset fraction (quarters) */
995         err = nct1008_write_reg(client, OFFSET_QUARTER_WR,
996                                         (pdata->offset % 4) << 6);
997         if (err < 0)
998                 goto error;
999
1000         return 0;
1001 error:
1002         dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
1003         return err;
1004 }
1005
1006 static int __devinit nct1008_configure_irq(struct nct1008_data *data)
1007 {
1008         data->workqueue = create_singlethread_workqueue((data->chip == NCT72) \
1009                                                         ? "nct72" : "nct1008");
1010
1011         INIT_WORK(&data->work, nct1008_work_func);
1012
1013         if (data->client->irq < 0)
1014                 return 0;
1015         else
1016                 return request_irq(data->client->irq, nct1008_irq,
1017                         IRQF_TRIGGER_LOW,
1018                         (data->chip == NCT72) ? "nct72" : "nct1008",
1019                         data);
1020 }
1021
1022 /*
1023  * Manufacturer(OnSemi) recommended sequence for
1024  * Extended Range mode is as follows
1025  * 1. Place in Standby
1026  * 2. Scale the THERM and ALERT limits
1027  *      appropriately(for Extended Range mode).
1028  * 3. Enable Extended Range mode.
1029  *      ALERT mask/THERM2 mode may be done here
1030  *      as these are not critical
1031  * 4. Set Conversion Rate as required
1032  * 5. Take device out of Standby
1033  */
1034
1035 /*
1036  * function nct1008_probe takes care of initial configuration
1037  */
1038 static int __devinit nct1008_probe(struct i2c_client *client,
1039                                 const struct i2c_device_id *id)
1040 {
1041         struct nct1008_data *data;
1042         int err;
1043         int i;
1044         int mask = 0;
1045         char nct_int_name[THERMAL_NAME_LENGTH];
1046         char nct_ext_name[THERMAL_NAME_LENGTH];
1047
1048         data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
1049         if (!data)
1050                 return -ENOMEM;
1051
1052         data->client = client;
1053         data->chip = id->driver_data;
1054         memcpy(&data->plat_data, client->dev.platform_data,
1055                 sizeof(struct nct1008_platform_data));
1056         i2c_set_clientdata(client, data);
1057
1058         nct1008_power_control(data, true);
1059         /* extended range recommended steps 1 through 4 taken care
1060          * in nct1008_configure_sensor function */
1061         err = nct1008_configure_sensor(data);   /* sensor is in standby */
1062         if (err < 0) {
1063                 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
1064                         __FILE__, __func__, __LINE__);
1065                 goto error;
1066         }
1067
1068         err = nct1008_configure_irq(data);
1069         if (err < 0) {
1070                 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
1071                         __FILE__, __func__, __LINE__);
1072                 goto error;
1073         }
1074         dev_info(&client->dev, "%s: initialized\n", __func__);
1075
1076         /* extended range recommended step 5 is in nct1008_enable function */
1077         err = nct1008_enable(client);           /* sensor is running */
1078         if (err < 0) {
1079                 dev_err(&client->dev, "Error: %s, line=%d, error=%d\n",
1080                         __func__, __LINE__, err);
1081                 goto error;
1082         }
1083
1084         /* register sysfs hooks */
1085         err = sysfs_create_group(&client->dev.kobj, &nct1008_attr_group);
1086         if (err < 0) {
1087                 dev_err(&client->dev, "\n sysfs create err=%d ", err);
1088                 goto error;
1089         }
1090
1091         err = nct1008_debuginit(data);
1092         if (err < 0)
1093                 err = 0; /* without debugfs we may continue */
1094
1095 #ifdef CONFIG_THERMAL
1096         for (i = 0; i < data->plat_data.num_trips; i++)
1097                 mask |= (1 << i);
1098
1099         if (data->plat_data.loc_name) {
1100                 strcpy(nct_int_name, "nct_int_");
1101                 strcpy(nct_ext_name, "nct_ext_");
1102                 strncat(nct_int_name, data->plat_data.loc_name,
1103                         (THERMAL_NAME_LENGTH - strlen("nct_int_")) - 1);
1104                 strncat(nct_ext_name, data->plat_data.loc_name,
1105                         (THERMAL_NAME_LENGTH - strlen("nct_ext_")) - 1);
1106         } else {
1107                 strcpy(nct_int_name, "nct_int");
1108                 strcpy(nct_ext_name, "nct_ext");
1109         }
1110
1111         data->nct_int = thermal_zone_device_register(nct_int_name,
1112                                                 0,
1113                                                 0x0,
1114                                                 data,
1115                                                 &nct_int_ops,
1116                                                 NULL,
1117                                                 2000,
1118                                                 0);
1119         if (IS_ERR_OR_NULL(data->nct_int))
1120                 goto error;
1121
1122         data->nct_ext = thermal_zone_device_register(nct_ext_name,
1123                                         data->plat_data.num_trips,
1124                                         mask,
1125                                         data,
1126                                         &nct_ext_ops,
1127                                         NULL,
1128                                         data->plat_data.passive_delay,
1129                                         0);
1130         if (IS_ERR_OR_NULL(data->nct_ext)) {
1131                 thermal_zone_device_unregister(data->nct_int);
1132                 data->nct_int = NULL;
1133                 goto error;
1134         }
1135
1136         nct1008_update(data);
1137 #endif
1138
1139         return 0;
1140
1141 error:
1142         dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
1143         nct1008_power_control(data, false);
1144         if (data->nct_reg)
1145                 regulator_put(data->nct_reg);
1146         kfree(data);
1147         return err;
1148 }
1149
1150 static int __devexit nct1008_remove(struct i2c_client *client)
1151 {
1152         struct nct1008_data *data = i2c_get_clientdata(client);
1153
1154         if (data->dent)
1155                 debugfs_remove(data->dent);
1156
1157         free_irq(data->client->irq, data);
1158         cancel_work_sync(&data->work);
1159         sysfs_remove_group(&client->dev.kobj, &nct1008_attr_group);
1160         nct1008_power_control(data, false);
1161         if (data->nct_reg)
1162                 regulator_put(data->nct_reg);
1163
1164         kfree(data);
1165
1166         return 0;
1167 }
1168
1169 static void nct1008_shutdown(struct i2c_client *client)
1170 {
1171         struct nct1008_data *data = i2c_get_clientdata(client);
1172
1173         if (client->irq)
1174                 disable_irq(client->irq);
1175
1176         cancel_work_sync(&data->work);
1177
1178         data->shutdown_complete = 1;
1179 }
1180
1181 #ifdef CONFIG_PM
1182 static int nct1008_suspend(struct device *dev)
1183 {
1184         struct i2c_client *client = to_i2c_client(dev);
1185         int err;
1186         struct nct1008_data *data = i2c_get_clientdata(client);
1187
1188         disable_irq(client->irq);
1189         err = nct1008_disable(client);
1190         nct1008_power_control(data, false);
1191         return err;
1192 }
1193
1194 static int nct1008_resume(struct device *dev)
1195 {
1196         struct i2c_client *client = to_i2c_client(dev);
1197         int err;
1198         struct nct1008_data *data = i2c_get_clientdata(client);
1199
1200         nct1008_power_control(data, true);
1201         nct1008_configure_sensor(data);
1202         err = nct1008_enable(client);
1203         if (err < 0) {
1204                 dev_err(&client->dev, "Error: %s, error=%d\n",
1205                         __func__, err);
1206                 return err;
1207         }
1208         nct1008_update(data);
1209         enable_irq(client->irq);
1210
1211         return 0;
1212 }
1213
1214 static const struct dev_pm_ops nct1008_pm_ops = {
1215         .suspend        = nct1008_suspend,
1216         .resume         = nct1008_resume,
1217 };
1218
1219 #endif
1220
1221 static const struct i2c_device_id nct1008_id[] = {
1222         { "nct1008", NCT1008 },
1223         { "nct72", NCT72},
1224         {}
1225 };
1226 MODULE_DEVICE_TABLE(i2c, nct1008_id);
1227
1228 static struct i2c_driver nct1008_driver = {
1229         .driver = {
1230                 .name   = "nct1008_nct72",
1231 #ifdef CONFIG_PM
1232                 .pm     = &nct1008_pm_ops,
1233 #endif
1234         },
1235         .probe          = nct1008_probe,
1236         .remove         = __devexit_p(nct1008_remove),
1237         .id_table       = nct1008_id,
1238         .shutdown       = nct1008_shutdown,
1239 };
1240
1241 static int __init nct1008_init(void)
1242 {
1243         return i2c_add_driver(&nct1008_driver);
1244 }
1245
1246 static void __exit nct1008_exit(void)
1247 {
1248         i2c_del_driver(&nct1008_driver);
1249 }
1250
1251 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008/NCT72");
1252 MODULE_LICENSE("GPL");
1253
1254 module_init(nct1008_init);
1255 module_exit(nct1008_exit);