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