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