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