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