drivers: misc: ti-st: apply wl12xx patch from TI
[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/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/regulator/consumer.h>
34
35 #define DRIVER_NAME "nct1008"
36
37 /* Register Addresses */
38 #define LOCAL_TEMP_RD                   0x00
39 #define EXT_TEMP_RD_HI                  0x01
40 #define EXT_TEMP_RD_LO                  0x10
41 #define STATUS_RD                       0x02
42 #define CONFIG_RD                       0x03
43
44 #define LOCAL_TEMP_HI_LIMIT_RD          0x05
45 #define LOCAL_TEMP_LO_LIMIT_RD          0x06
46
47 #define EXT_TEMP_HI_LIMIT_HI_BYTE_RD    0x07
48 #define EXT_TEMP_LO_LIMIT_HI_BYTE_RD    0x08
49
50 #define CONFIG_WR                       0x09
51 #define CONV_RATE_WR                    0x0A
52 #define LOCAL_TEMP_HI_LIMIT_WR          0x0B
53 #define LOCAL_TEMP_LO_LIMIT_WR          0x0C
54 #define EXT_TEMP_HI_LIMIT_HI_BYTE_WR    0x0D
55 #define EXT_TEMP_LO_LIMIT_HI_BYTE_WR    0x0E
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 MIN_SLEEP_MSEC                  20
79 #define CELSIUS_TO_MILLICELSIUS(x) ((x)*1000)
80 #define MILLICELSIUS_TO_CELSIUS(x) ((x)/1000)
81
82 static inline s8 value_to_temperature(bool extended, u8 value)
83 {
84         return extended ? (s8)(value - EXTENDED_RANGE_OFFSET) : (s8)value;
85 }
86
87 static inline u8 temperature_to_value(bool extended, s8 temp)
88 {
89         return extended ? (u8)(temp + EXTENDED_RANGE_OFFSET) : (u8)temp;
90 }
91
92 static int nct1008_get_temp(struct device *dev, long *pTemp)
93 {
94         struct i2c_client *client = to_i2c_client(dev);
95         struct nct1008_platform_data *pdata = client->dev.platform_data;
96         s8 temp_local;
97         u8 temp_ext_lo;
98         s8 temp_ext_hi;
99         long temp_ext_milli;
100         long temp_local_milli;
101         u8 value;
102
103         /* Read Local Temp */
104         value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
105         if (value < 0)
106                 goto error;
107         temp_local = value_to_temperature(pdata->ext_range, value);
108         temp_local_milli = CELSIUS_TO_MILLICELSIUS(temp_local);
109
110         /* Read External Temp */
111         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
112         if (value < 0)
113                 goto error;
114         temp_ext_lo = (value >> 6);
115
116         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
117         if (value < 0)
118                 goto error;
119         temp_ext_hi = value_to_temperature(pdata->ext_range, value);
120
121         temp_ext_milli = CELSIUS_TO_MILLICELSIUS(temp_ext_hi) +
122                                 temp_ext_lo * 250;
123
124         /* Return max between Local and External Temp */
125         *pTemp = max(temp_local_milli, temp_ext_milli);
126
127         dev_dbg(dev, "\n %s: ret temp=%ldC ", __func__, *pTemp);
128         return 0;
129 error:
130         dev_err(&client->dev, "\n error in file=: %s %s() line=%d: "
131                 "error=%d ", __FILE__, __func__, __LINE__, value);
132         return value;
133 }
134
135 static ssize_t nct1008_show_temp(struct device *dev,
136         struct device_attribute *attr, char *buf)
137 {
138         struct i2c_client *client = to_i2c_client(dev);
139         struct nct1008_platform_data *pdata = client->dev.platform_data;
140         s8 temp1 = 0;
141         s8 temp = 0;
142         u8 temp2 = 0;
143         int value = 0;
144
145         if (!dev || !buf || !attr)
146                 return -EINVAL;
147
148         value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
149         if (value < 0)
150                 goto error;
151         temp1 = value_to_temperature(pdata->ext_range, value);
152
153         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
154         if (value < 0)
155                 goto error;
156         temp2 = (value >> 6);
157         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
158         if (value < 0)
159                 goto error;
160         temp = value_to_temperature(pdata->ext_range, value);
161
162         return snprintf(buf, MAX_STR_PRINT, "%d %d.%d\n",
163                 temp1, temp, temp2 * 25);
164
165 error:
166         return snprintf(buf, MAX_STR_PRINT,
167                 "Error read local/ext temperature\n");
168 }
169
170 static ssize_t nct1008_show_temp_overheat(struct device *dev,
171                                 struct device_attribute *attr,
172                                 char *buf)
173 {
174         struct i2c_client *client = to_i2c_client(dev);
175         struct nct1008_platform_data *pdata = client->dev.platform_data;
176         int value;
177         s8 temp, temp2;
178
179         /* Local temperature h/w shutdown limit */
180         value = i2c_smbus_read_byte_data(client, LOCAL_THERM_LIMIT_WR);
181         if (value < 0)
182                 goto error;
183         temp = value_to_temperature(pdata->ext_range, value);
184
185         /* External temperature h/w shutdown limit */
186         value = i2c_smbus_read_byte_data(client, EXT_THERM_LIMIT_WR);
187         if (value < 0)
188                 goto error;
189         temp2 = value_to_temperature(pdata->ext_range, value);
190
191         return snprintf(buf, MAX_STR_PRINT, "%d %d\n", temp, temp2);
192 error:
193         dev_err(dev, "%s: failed to read temperature-overheat "
194                 "\n", __func__);
195         return snprintf(buf, MAX_STR_PRINT, " Rd overheat Error\n");
196 }
197
198 static ssize_t nct1008_set_temp_overheat(struct device *dev,
199                         struct device_attribute *attr,
200                         const char *buf, size_t count)
201 {
202         long int num;
203         int err;
204         u8 temp;
205         long currTemp;
206         struct i2c_client *client = to_i2c_client(dev);
207         struct nct1008_platform_data *pdata = client->dev.platform_data;
208         char bufTemp[MAX_STR_PRINT];
209         char bufOverheat[MAX_STR_PRINT];
210         unsigned int ret;
211
212         if (strict_strtol(buf, 0, &num)) {
213                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
214                         __LINE__, __func__);
215                 return -EINVAL;
216         }
217         if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
218                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
219                         __LINE__, __func__);
220                 return -EINVAL;
221         }
222         /* check for system power down */
223         err = nct1008_get_temp(dev, &currTemp);
224         if (err)
225                 goto error;
226
227         currTemp = MILLICELSIUS_TO_CELSIUS(currTemp);
228
229         if (currTemp >= (int)num) {
230                 ret = nct1008_show_temp(dev, attr, bufTemp);
231                 ret = nct1008_show_temp_overheat(dev, attr, bufOverheat);
232                 dev_err(dev, "\nCurrent temp: %s ", bufTemp);
233                 dev_err(dev, "\nOld overheat limit: %s ", bufOverheat);
234                 dev_err(dev, "\nReset from overheat: curr temp=%ld, "
235                         "new overheat temp=%d\n\n", currTemp, (int)num);
236         }
237
238         /* External temperature h/w shutdown limit */
239         temp = temperature_to_value(pdata->ext_range, (s8)num);
240         err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, temp);
241         if (err < 0)
242                 goto error;
243
244         /* Local temperature h/w shutdown limit */
245         temp = temperature_to_value(pdata->ext_range, (s8)num);
246         err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, temp);
247         if (err < 0)
248                 goto error;
249         return count;
250 error:
251         dev_err(dev, " %s: failed to set temperature-overheat\n", __func__);
252         return err;
253 }
254
255 static ssize_t nct1008_show_temp_alert(struct device *dev,
256                                 struct device_attribute *attr,
257                                 char *buf)
258 {
259         struct i2c_client *client = to_i2c_client(dev);
260         struct nct1008_platform_data *pdata = client->dev.platform_data;
261         int value;
262         s8 temp_hi, temp_lo;
263         /* External Temperature Throttling hi-limit */
264         value = i2c_smbus_read_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
265         if (value < 0)
266                 goto error;
267         temp_hi = value_to_temperature(pdata->ext_range, value);
268
269         /* External Temperature Throttling lo-limit */
270         value = i2c_smbus_read_byte_data(client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
271         if (value < 0)
272                 goto error;
273         temp_lo = value_to_temperature(pdata->ext_range, value);
274
275         return snprintf(buf, MAX_STR_PRINT, "lo:%d hi:%d\n", temp_lo, temp_hi);
276 error:
277         dev_err(dev, "%s: failed to read temperature-alert\n", __func__);
278         return snprintf(buf, MAX_STR_PRINT, " Rd alert Error\n");
279 }
280
281 static ssize_t nct1008_set_temp_alert(struct device *dev,
282                         struct device_attribute *attr,
283                         const char *buf, size_t count)
284 {
285         long int num;
286         int value;
287         int err;
288         struct i2c_client *client = to_i2c_client(dev);
289         struct nct1008_platform_data *pdata = client->dev.platform_data;
290
291         if (strict_strtol(buf, 0, &num)) {
292                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
293                         __LINE__, __func__);
294                 return -EINVAL;
295         }
296         if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
297                 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
298                         __LINE__, __func__);
299                 return -EINVAL;
300         }
301
302         /* External Temperature Throttling limit */
303         value = temperature_to_value(pdata->ext_range, (s8)num);
304         err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
305                 value);
306         if (err < 0)
307                 goto error;
308
309         /* Local Temperature Throttling limit */
310         err = i2c_smbus_write_byte_data(client, LOCAL_TEMP_HI_LIMIT_WR,
311                 value);
312         if (err < 0)
313                 goto error;
314
315         return count;
316 error:
317         dev_err(dev, "%s: failed to set temperature-alert "
318                 "\n", __func__);
319         return err;
320 }
321
322 static ssize_t nct1008_show_ext_temp(struct device *dev,
323         struct device_attribute *attr, char *buf)
324 {
325         struct i2c_client *client = to_i2c_client(dev);
326         struct nct1008_platform_data *pdata = client->dev.platform_data;
327         s8 temp_value;
328         int data = 0;
329         int data_lo;
330
331         if (!dev || !buf || !attr)
332                 return -EINVAL;
333
334         /* When reading the full external temperature value, read the
335          * LSB first. This causes the MSB to be locked (that is, the
336          * ADC does not write to it) until it is read */
337         data_lo = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
338         if (data_lo < 0) {
339                 dev_err(&client->dev, "%s: failed to read "
340                         "ext_temperature, i2c error=%d\n", __func__, data_lo);
341                 goto error;
342         }
343
344         data = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
345         if (data < 0) {
346                 dev_err(&client->dev, "%s: failed to read "
347                         "ext_temperature, i2c error=%d\n", __func__, data);
348                 goto error;
349         }
350
351         temp_value = value_to_temperature(pdata->ext_range, data);
352
353         return snprintf(buf, MAX_STR_PRINT, "%d.%d\n", temp_value,
354                 (25 * (data_lo >> 6)));
355 error:
356         return snprintf(buf, MAX_STR_PRINT, "Error read ext temperature\n");
357 }
358
359 static DEVICE_ATTR(temperature, S_IRUGO, nct1008_show_temp, NULL);
360 static DEVICE_ATTR(temperature_overheat, (S_IRUGO | (S_IWUSR | S_IWGRP)),
361                 nct1008_show_temp_overheat, nct1008_set_temp_overheat);
362 static DEVICE_ATTR(temperature_alert, (S_IRUGO | (S_IWUSR | S_IWGRP)),
363                 nct1008_show_temp_alert, nct1008_set_temp_alert);
364 static DEVICE_ATTR(ext_temperature, S_IRUGO, nct1008_show_ext_temp, NULL);
365
366 static struct attribute *nct1008_attributes[] = {
367         &dev_attr_temperature.attr,
368         &dev_attr_temperature_overheat.attr,
369         &dev_attr_temperature_alert.attr,
370         &dev_attr_ext_temperature.attr,
371         NULL
372 };
373
374 static const struct attribute_group nct1008_attr_group = {
375         .attrs = nct1008_attributes,
376 };
377
378 #ifdef CONFIG_DEBUG_FS
379 #include <linux/debugfs.h>
380 #include <linux/seq_file.h>
381 static void print_reg(const char *reg_name, struct seq_file *s,
382                 int offset)
383 {
384         struct nct1008_data *nct_data = s->private;
385         int ret;
386
387         ret = i2c_smbus_read_byte_data(nct_data->client,
388                 offset);
389         if (ret >= 0)
390                 seq_printf(s, "Reg %s Addr = 0x%02x Reg 0x%02x "
391                 "Value 0x%02x\n", reg_name,
392                 nct_data->client->addr,
393                         offset, ret);
394         else
395                 seq_printf(s, "%s: line=%d, i2c read error=%d\n",
396                 __func__, __LINE__, ret);
397 }
398
399 static int dbg_nct1008_show(struct seq_file *s, void *unused)
400 {
401         seq_printf(s, "nct1008 Registers\n");
402         seq_printf(s, "------------------\n");
403         print_reg("Local Temp Value    ",     s, 0x00);
404         print_reg("Ext Temp Value Hi   ",     s, 0x01);
405         print_reg("Status              ",     s, 0x02);
406         print_reg("Configuration       ",     s, 0x03);
407         print_reg("Conversion Rate     ",     s, 0x04);
408         print_reg("Local Temp Hi Limit ",     s, 0x05);
409         print_reg("Local Temp Lo Limit ",     s, 0x06);
410         print_reg("Ext Temp Hi Limit Hi",     s, 0x07);
411         print_reg("Ext Temp Hi Limit Lo",     s, 0x13);
412         print_reg("Ext Temp Lo Limit Hi",     s, 0x08);
413         print_reg("Ext Temp Lo Limit Lo",     s, 0x14);
414         print_reg("Ext Temp Value Lo   ",     s, 0x10);
415         print_reg("Ext Temp Offset Hi  ",     s, 0x11);
416         print_reg("Ext Temp Offset Lo  ",     s, 0x12);
417         print_reg("Ext THERM Limit     ",     s, 0x19);
418         print_reg("Local THERM Limit   ",     s, 0x20);
419         print_reg("THERM Hysteresis    ",     s, 0x21);
420         print_reg("Consecutive ALERT   ",     s, 0x22);
421         return 0;
422 }
423
424 static int dbg_nct1008_open(struct inode *inode, struct file *file)
425 {
426         return single_open(file, dbg_nct1008_show, inode->i_private);
427 }
428
429 static const struct file_operations debug_fops = {
430         .open           = dbg_nct1008_open,
431         .read           = seq_read,
432         .llseek         = seq_lseek,
433         .release        = single_release,
434 };
435
436 static int __init nct1008_debuginit(struct nct1008_data *nct)
437 {
438         int err = 0;
439         struct dentry *d;
440         d = debugfs_create_file("nct1008", S_IRUGO, NULL,
441                         (void *)nct, &debug_fops);
442         if ((!d) || IS_ERR(d)) {
443                 dev_err(&nct->client->dev, "Error: %s debugfs_create_file"
444                         " returned an error\n", __func__);
445                 err = -ENOENT;
446                 goto end;
447         }
448         if (d == ERR_PTR(-ENODEV)) {
449                 dev_err(&nct->client->dev, "Error: %s debugfs not supported "
450                         "error=-ENODEV\n", __func__);
451                 err = -ENODEV;
452         } else {
453                 nct->dent = d;
454         }
455 end:
456         return err;
457 }
458 #else
459 static int __init nct1008_debuginit(struct nct1008_data *nct)
460 {
461         return 0;
462 }
463 #endif
464
465 static int nct1008_enable(struct i2c_client *client)
466 {
467         struct nct1008_data *data = i2c_get_clientdata(client);
468         int err;
469
470         err = i2c_smbus_write_byte_data(client, CONFIG_WR,
471                                   data->config & ~STANDBY_BIT);
472         if (err < 0)
473                 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
474                 __func__, __LINE__, err);
475         return err;
476 }
477
478 static int nct1008_disable(struct i2c_client *client)
479 {
480         struct nct1008_data *data = i2c_get_clientdata(client);
481         int err;
482
483         err = i2c_smbus_write_byte_data(client, CONFIG_WR,
484                                   data->config | STANDBY_BIT);
485         if (err < 0)
486                 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
487                 __func__, __LINE__, err);
488         return err;
489 }
490
491 static int nct1008_disable_alert(struct nct1008_data *data)
492 {
493         struct i2c_client *client = data->client;
494         int ret = 0;
495         int val;
496
497         /*
498          * Disable ALERT# output, because these chips don't implement
499          * SMBus alert correctly; they should only hold the alert line
500          * low briefly.
501          */
502         val = i2c_smbus_read_byte_data(data->client, CONFIG_RD);
503         if (val < 0) {
504                 dev_err(&client->dev, "%s, line=%d, disable alert failed ... "
505                         "i2c read error=%d\n", __func__, __LINE__, val);
506                 return val;
507         }
508         data->config = val | ALERT_BIT;
509         ret = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
510         if (ret)
511                 dev_err(&client->dev, "%s: fail to disable alert, i2c "
512                         "write error=%d#\n", __func__, ret);
513
514         return ret;
515 }
516
517 static int nct1008_enable_alert(struct nct1008_data *data)
518 {
519         int val;
520         int ret;
521
522         val = i2c_smbus_read_byte_data(data->client, CONFIG_RD);
523         if (val < 0) {
524                 dev_err(&data->client->dev, "%s, line=%d, enable alert "
525                         "failed ... i2c read error=%d\n", __func__,
526                         __LINE__, val);
527                 return val;
528         }
529         val &= ~(ALERT_BIT | THERM2_BIT);
530         ret = i2c_smbus_write_byte_data(data->client, CONFIG_WR, val);
531         if (ret) {
532                 dev_err(&data->client->dev, "%s: fail to enable alert, i2c "
533                         "write error=%d\n", __func__, ret);
534                 return ret;
535         }
536
537         return ret;
538 }
539
540 static void nct1008_work_func(struct work_struct *work)
541 {
542         struct nct1008_data *data = container_of(work, struct nct1008_data,
543                                                 work);
544         int err = 0;
545         int intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD);
546
547         if (intr_status < 0) {
548                 dev_err(&data->client->dev, "%s, line=%d, i2c read error=%d\n",
549                         __func__, __LINE__, intr_status);
550                 return;
551         }
552
553         intr_status &= (BIT(3) | BIT(4));
554         if (!intr_status)
555                 return;
556
557         if (data->alert_func) {
558                 err = nct1008_disable_alert(data);
559                 if (err) {
560                         dev_err(&data->client->dev,
561                                 "%s: disable alert fail(error=%d)\n",
562                                 __func__, err);
563                         return;
564                 }
565
566                 data->alert_func(data->alert_data);
567
568                 nct1008_enable_alert(data);
569         }
570
571
572         if (err)
573                 dev_err(&data->client->dev, "%s: fail(error=%d)\n", __func__,
574                         err);
575         else
576                 pr_debug("%s: done\n", __func__);
577 }
578
579 static irqreturn_t nct1008_irq(int irq, void *dev_id)
580 {
581         struct nct1008_data *data = dev_id;
582
583         schedule_work(&data->work);
584         return IRQ_HANDLED;
585 }
586
587 static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
588 {
589         int ret;
590         if (!data->nct_reg) {
591                 data->nct_reg = regulator_get(&data->client->dev, "vdd");
592                 if (IS_ERR_OR_NULL(data->nct_reg)) {
593                         dev_warn(&data->client->dev, "Error [%d] in"
594                                 "getting the regulator handle for vdd "
595                                 "of %s\n", (int)data->nct_reg,
596                                 dev_name(&data->client->dev));
597                         data->nct_reg = NULL;
598                         return;
599                 }
600         }
601         if (is_enable)
602                 ret = regulator_enable(data->nct_reg);
603         else
604                 ret = regulator_disable(data->nct_reg);
605
606         if (ret < 0)
607                 dev_err(&data->client->dev, "Error in %s rail vdd_nct1008, "
608                         "error %d\n", (is_enable) ? "enabling" : "disabling",
609                         ret);
610         else
611                 dev_info(&data->client->dev, "success in %s rail vdd_nct1008\n",
612                         (is_enable) ? "enabling" : "disabling");
613 }
614
615 static int __devinit nct1008_configure_sensor(struct nct1008_data* data)
616 {
617         struct i2c_client *client = data->client;
618         struct nct1008_platform_data *pdata = client->dev.platform_data;
619         u8 value;
620         s8 temp;
621         u8 temp2;
622         int err;
623
624         if (!pdata || !pdata->supported_hwrev)
625                 return -ENODEV;
626
627         /* Place in Standby */
628         data->config = STANDBY_BIT;
629         err = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
630         if (err)
631                 goto error;
632
633         /* External temperature h/w shutdown limit */
634         value = temperature_to_value(pdata->ext_range, NCT1008_MAX_TEMP);
635         err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, value);
636         if (err)
637                 goto error;
638
639         /* Local temperature h/w shutdown limit */
640         value = temperature_to_value(pdata->ext_range, NCT1008_MAX_TEMP);
641         err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, value);
642         if (err)
643                 goto error;
644
645         /* set extended range mode if needed */
646         if (pdata->ext_range)
647                 data->config |= EXTENDED_RANGE_BIT;
648         data->config &= ~(THERM2_BIT | ALERT_BIT);
649
650         err = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
651         if (err)
652                 goto error;
653
654         /* Temperature conversion rate */
655         err = i2c_smbus_write_byte_data(client, CONV_RATE_WR, pdata->conv_rate);
656         if (err)
657                 goto error;
658
659         /* Setup local hi and lo limits */
660         err = i2c_smbus_write_byte_data(client,
661                 LOCAL_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
662         if (err)
663                 goto error;
664
665         err = i2c_smbus_write_byte_data(client,
666                 LOCAL_TEMP_LO_LIMIT_WR, 0);
667         if (err)
668                 goto error;
669
670         /* Setup external hi and lo limits */
671         err = i2c_smbus_write_byte_data(client,
672                 EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
673         if (err)
674                 goto error;
675         err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
676                         NCT1008_MAX_TEMP);
677         if (err)
678                 goto error;
679
680         /* read initial temperature */
681         value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
682         if (value < 0) {
683                 err = value;
684                 goto error;
685         }
686         temp = value_to_temperature(pdata->ext_range, value);
687         dev_dbg(&client->dev, "\n initial local temp = %d ", temp);
688
689         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
690         if (value < 0) {
691                 err = value;
692                 goto error;
693         }
694         temp2 = (value >> 6);
695         value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
696         if (value < 0) {
697                 err = value;
698                 goto error;
699         }
700         temp = value_to_temperature(pdata->ext_range, value);
701
702         if (temp2 > 0)
703                 dev_dbg(&client->dev, "\n initial ext temp = %d.%d deg",
704                                 temp, temp2 * 25);
705         else
706                 dev_dbg(&client->dev, "\n initial ext temp = %d.0 deg", temp);
707
708         /* Remote channel offset */
709         err = i2c_smbus_write_byte_data(client, OFFSET_WR, pdata->offset / 4);
710         if (err < 0)
711                 goto error;
712
713         /* Remote channel offset fraction (quarters) */
714         err = i2c_smbus_write_byte_data(client, OFFSET_QUARTER_WR,
715                                         (pdata->offset % 4) << 6);
716         if (err < 0)
717                 goto error;
718
719         /* register sysfs hooks */
720         err = sysfs_create_group(&client->dev.kobj, &nct1008_attr_group);
721         if (err < 0) {
722                 dev_err(&client->dev, "\n sysfs create err=%d ", err);
723                 goto error;
724         }
725
726         return 0;
727 error:
728         dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
729         return err;
730 }
731
732 static int __devinit nct1008_configure_irq(struct nct1008_data *data)
733 {
734         INIT_WORK(&data->work, nct1008_work_func);
735
736         if (data->client->irq < 0)
737                 return 0;
738         else
739                 return request_irq(data->client->irq, nct1008_irq,
740                         IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
741                         DRIVER_NAME, data);
742 }
743
744 static unsigned int get_ext_mode_delay_ms(unsigned int conv_rate)
745 {
746         switch (conv_rate) {
747         case 0:
748                 return 16000;
749         case 1:
750                 return 8000;
751         case 2:
752                 return 4000;
753         case 3:
754                 return 2000;
755         case 4:
756                 return 1000;
757         case 5:
758                 return 500;
759         case 6:
760                 return 250;
761         case 7:
762                 return 125;
763         case 9:
764                 return 32;
765         case 10:
766                 return 16;
767         case 8:
768         default:
769                 return 63;
770         }
771 }
772
773 int nct1008_thermal_get_temp(struct nct1008_data *data, long *temp)
774 {
775         return nct1008_get_temp(&data->client->dev, temp);
776 }
777
778 int nct1008_thermal_get_temp_low(struct nct1008_data *data, long *temp)
779 {
780         *temp = 0;
781         return 0;
782 }
783
784 int nct1008_thermal_set_limits(struct nct1008_data *data,
785                                 long lo_limit_milli,
786                                 long hi_limit_milli)
787 {
788         int err;
789         u8 value;
790         bool extended_range = data->plat_data.ext_range;
791         long lo_limit = MILLICELSIUS_TO_CELSIUS(lo_limit_milli);
792         long hi_limit = MILLICELSIUS_TO_CELSIUS(hi_limit_milli);
793
794         if (lo_limit >= hi_limit)
795                 return -EINVAL;
796
797         if (data->current_lo_limit == lo_limit &&
798                 data->current_hi_limit == hi_limit)
799                 return 0;
800
801         if (data->current_lo_limit != lo_limit) {
802                 value = temperature_to_value(extended_range, lo_limit);
803                 pr_debug("%s: set lo_limit %ld\n", __func__, lo_limit);
804                 err = i2c_smbus_write_byte_data(data->client,
805                                 EXT_TEMP_LO_LIMIT_HI_BYTE_WR, value);
806                 if (err)
807                         return err;
808
809                 data->current_lo_limit = lo_limit;
810         }
811
812         if (data->current_hi_limit != hi_limit) {
813                 value = temperature_to_value(extended_range, hi_limit);
814                 pr_debug("%s: set hi_limit %ld\n", __func__, hi_limit);
815                 err = i2c_smbus_write_byte_data(data->client,
816                                 EXT_TEMP_HI_LIMIT_HI_BYTE_WR, value);
817                 if (err)
818                         return err;
819
820                 data->current_hi_limit = hi_limit;
821         }
822
823         return 0;
824 }
825
826 int nct1008_thermal_set_alert(struct nct1008_data *data,
827                                 void (*alert_func)(void *),
828                                 void *alert_data)
829 {
830         data->alert_data = alert_data;
831         data->alert_func = alert_func;
832
833         return 0;
834 }
835
836 int nct1008_thermal_set_shutdown_temp(struct nct1008_data *data,
837                                         long shutdown_temp_milli)
838 {
839         struct i2c_client *client = data->client;
840         struct nct1008_platform_data *pdata = client->dev.platform_data;
841         int err;
842         u8 value;
843         long shutdown_temp;
844
845         shutdown_temp = MILLICELSIUS_TO_CELSIUS(shutdown_temp_milli);
846
847         /* External temperature h/w shutdown limit */
848         value = temperature_to_value(pdata->ext_range, shutdown_temp);
849         err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, value);
850         if (err)
851                 return err;
852
853         /* Local temperature h/w shutdown limit */
854         value = temperature_to_value(pdata->ext_range, shutdown_temp);
855         err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, value);
856         if (err)
857                 return err;
858
859         return 0;
860 }
861
862 /*
863  * Manufacturer(OnSemi) recommended sequence for
864  * Extended Range mode is as follows
865  * 1. Place in Standby
866  * 2. Scale the THERM and ALERT limits
867  *      appropriately(for Extended Range mode).
868  * 3. Enable Extended Range mode.
869  *      ALERT mask/THERM2 mode may be done here
870  *      as these are not critical
871  * 4. Set Conversion Rate as required
872  * 5. Take device out of Standby
873  */
874
875 /*
876  * function nct1008_probe takes care of initial configuration
877  */
878 static int __devinit nct1008_probe(struct i2c_client *client,
879                                 const struct i2c_device_id *id)
880 {
881         struct nct1008_data *data;
882         int err;
883         unsigned int delay;
884
885         data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
886         if (!data)
887                 return -ENOMEM;
888
889         data->client = client;
890         memcpy(&data->plat_data, client->dev.platform_data,
891                 sizeof(struct nct1008_platform_data));
892         i2c_set_clientdata(client, data);
893
894         nct1008_power_control(data, true);
895         /* extended range recommended steps 1 through 4 taken care
896          * in nct1008_configure_sensor function */
897         err = nct1008_configure_sensor(data);   /* sensor is in standby */
898         if (err < 0) {
899                 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
900                         __FILE__, __func__, __LINE__);
901                 goto error;
902         }
903
904         err = nct1008_configure_irq(data);
905         if (err < 0) {
906                 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
907                         __FILE__, __func__, __LINE__);
908                 goto error;
909         }
910         dev_info(&client->dev, "%s: initialized\n", __func__);
911
912         /* extended range recommended step 5 is in nct1008_enable function */
913         err = nct1008_enable(client);           /* sensor is running */
914         if (err < 0) {
915                 dev_err(&client->dev, "Error: %s, line=%d, error=%d\n",
916                         __func__, __LINE__, err);
917                 goto error;
918         }
919
920         err = nct1008_debuginit(data);
921         if (err < 0)
922                 err = 0; /* without debugfs we may continue */
923
924         /* switch to extended mode reports correct temperature
925          * from next measurement cycle */
926         if (data->plat_data.ext_range) {
927                 delay = get_ext_mode_delay_ms(
928                         data->plat_data.conv_rate);
929                 msleep(delay); /* 63msec for default conv rate 0x8 */
930         }
931
932         /* notify callback that probe is done */
933         if (data->plat_data.probe_callback)
934                 data->plat_data.probe_callback(data);
935
936         return 0;
937
938 error:
939         dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
940         nct1008_power_control(data, false);
941         if (data->nct_reg)
942                 regulator_put(data->nct_reg);
943         kfree(data);
944         return err;
945 }
946
947 static int __devexit nct1008_remove(struct i2c_client *client)
948 {
949         struct nct1008_data *data = i2c_get_clientdata(client);
950
951         if (data->dent)
952                 debugfs_remove(data->dent);
953
954         free_irq(data->client->irq, data);
955         cancel_work_sync(&data->work);
956         sysfs_remove_group(&client->dev.kobj, &nct1008_attr_group);
957         nct1008_power_control(data, false);
958         if (data->nct_reg)
959                 regulator_put(data->nct_reg);
960
961         kfree(data);
962
963         return 0;
964 }
965
966 #ifdef CONFIG_PM
967 static int nct1008_suspend(struct i2c_client *client, pm_message_t state)
968 {
969         int err;
970
971         disable_irq(client->irq);
972         err = nct1008_disable(client);
973         return err;
974 }
975
976 static int nct1008_resume(struct i2c_client *client)
977 {
978         struct nct1008_data *data = i2c_get_clientdata(client);
979         int err;
980
981         err = nct1008_enable(client);
982         if (err < 0) {
983                 dev_err(&client->dev, "Error: %s, error=%d\n",
984                         __func__, err);
985                 return err;
986         }
987         enable_irq(client->irq);
988         schedule_work(&data->work);
989
990         return 0;
991 }
992 #endif
993
994 static const struct i2c_device_id nct1008_id[] = {
995         { DRIVER_NAME, 0 },
996         { }
997 };
998 MODULE_DEVICE_TABLE(i2c, nct1008_id);
999
1000 static struct i2c_driver nct1008_driver = {
1001         .driver = {
1002                 .name   = DRIVER_NAME,
1003         },
1004         .probe          = nct1008_probe,
1005         .remove         = __devexit_p(nct1008_remove),
1006         .id_table       = nct1008_id,
1007 #ifdef CONFIG_PM
1008         .suspend        = nct1008_suspend,
1009         .resume         = nct1008_resume,
1010 #endif
1011 };
1012
1013 static int __init nct1008_init(void)
1014 {
1015         return i2c_add_driver(&nct1008_driver);
1016 }
1017
1018 static void __exit nct1008_exit(void)
1019 {
1020         i2c_del_driver(&nct1008_driver);
1021 }
1022
1023 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008");
1024 MODULE_LICENSE("GPL");
1025
1026 module_init(nct1008_init);
1027 module_exit(nct1008_exit);