2 * drivers/misc/nct1008.c
4 * Driver for NCT1008, temperature monitoring device from ON Semiconductors
6 * Copyright (c) 2010-2011, NVIDIA Corporation.
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.
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
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.
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>
35 #define DRIVER_NAME "nct1008"
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
44 #define LOCAL_TEMP_HI_LIMIT_RD 0x05
45 #define LOCAL_TEMP_LO_LIMIT_RD 0x06
47 #define EXT_TEMP_HI_LIMIT_HI_BYTE_RD 0x07
48 #define EXT_TEMP_LO_LIMIT_HI_BYTE_RD 0x08
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
57 #define OFFSET_WR 0x11
58 #define OFFSET_QUARTER_WR 0x12
59 #define EXT_THERM_LIMIT_WR 0x19
60 #define LOCAL_THERM_LIMIT_WR 0x20
61 #define THERM_HYSTERESIS_WR 0x21
63 /* Configuration Register Bits */
64 #define EXTENDED_RANGE_BIT BIT(2)
65 #define THERM2_BIT BIT(5)
66 #define STANDBY_BIT BIT(6)
67 #define ALERT_BIT BIT(7)
69 /* Max Temperature Measurements */
70 #define EXTENDED_RANGE_OFFSET 64U
71 #define STANDARD_RANGE_MAX 127U
72 #define EXTENDED_RANGE_MAX (150U + EXTENDED_RANGE_OFFSET)
74 #define NCT1008_MIN_TEMP -64
75 #define NCT1008_MAX_TEMP 191
77 #define MAX_STR_PRINT 50
79 #define MAX_CONV_TIME_ONESHOT_MS (52)
80 #define CELSIUS_TO_MILLICELSIUS(x) ((x)*1000)
81 #define MILLICELSIUS_TO_CELSIUS(x) ((x)/1000)
84 static int conv_period_ms_table[] =
85 {16000, 8000, 4000, 2000, 1000, 500, 250, 125, 63, 32, 16};
87 static inline s8 value_to_temperature(bool extended, u8 value)
89 return extended ? (s8)(value - EXTENDED_RANGE_OFFSET) : (s8)value;
92 static inline u8 temperature_to_value(bool extended, s8 temp)
94 return extended ? (u8)(temp + EXTENDED_RANGE_OFFSET) : (u8)temp;
97 static int nct1008_get_temp(struct device *dev, long *pTemp)
99 struct i2c_client *client = to_i2c_client(dev);
100 struct nct1008_platform_data *pdata = client->dev.platform_data;
105 long temp_local_milli;
108 /* Read Local Temp */
109 value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
112 temp_local = value_to_temperature(pdata->ext_range, value);
113 temp_local_milli = CELSIUS_TO_MILLICELSIUS(temp_local);
115 /* Read External Temp */
116 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
119 temp_ext_lo = (value >> 6);
121 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
124 temp_ext_hi = value_to_temperature(pdata->ext_range, value);
126 temp_ext_milli = CELSIUS_TO_MILLICELSIUS(temp_ext_hi) +
129 /* Return max between Local and External Temp */
130 *pTemp = max(temp_local_milli, temp_ext_milli);
132 dev_dbg(dev, "\n %s: ret temp=%ldC ", __func__, *pTemp);
135 dev_err(&client->dev, "\n error in file=: %s %s() line=%d: "
136 "error=%d ", __FILE__, __func__, __LINE__, value);
140 static ssize_t nct1008_show_temp(struct device *dev,
141 struct device_attribute *attr, char *buf)
143 struct i2c_client *client = to_i2c_client(dev);
144 struct nct1008_platform_data *pdata = client->dev.platform_data;
150 if (!dev || !buf || !attr)
153 value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
156 temp1 = value_to_temperature(pdata->ext_range, value);
158 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
161 temp2 = (value >> 6);
162 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
165 temp = value_to_temperature(pdata->ext_range, value);
167 return snprintf(buf, MAX_STR_PRINT, "%d %d.%d\n",
168 temp1, temp, temp2 * 25);
171 return snprintf(buf, MAX_STR_PRINT,
172 "Error read local/ext temperature\n");
175 static ssize_t nct1008_show_temp_overheat(struct device *dev,
176 struct device_attribute *attr,
179 struct i2c_client *client = to_i2c_client(dev);
180 struct nct1008_platform_data *pdata = client->dev.platform_data;
184 /* Local temperature h/w shutdown limit */
185 value = i2c_smbus_read_byte_data(client, LOCAL_THERM_LIMIT_WR);
188 temp = value_to_temperature(pdata->ext_range, value);
190 /* External temperature h/w shutdown limit */
191 value = i2c_smbus_read_byte_data(client, EXT_THERM_LIMIT_WR);
194 temp2 = value_to_temperature(pdata->ext_range, value);
196 return snprintf(buf, MAX_STR_PRINT, "%d %d\n", temp, temp2);
198 dev_err(dev, "%s: failed to read temperature-overheat "
200 return snprintf(buf, MAX_STR_PRINT, " Rd overheat Error\n");
203 static ssize_t nct1008_set_temp_overheat(struct device *dev,
204 struct device_attribute *attr,
205 const char *buf, size_t count)
211 struct i2c_client *client = to_i2c_client(dev);
212 struct nct1008_platform_data *pdata = client->dev.platform_data;
213 char bufTemp[MAX_STR_PRINT];
214 char bufOverheat[MAX_STR_PRINT];
217 if (strict_strtol(buf, 0, &num)) {
218 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
222 if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
223 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
227 /* check for system power down */
228 err = nct1008_get_temp(dev, &currTemp);
232 currTemp = MILLICELSIUS_TO_CELSIUS(currTemp);
234 if (currTemp >= (int)num) {
235 ret = nct1008_show_temp(dev, attr, bufTemp);
236 ret = nct1008_show_temp_overheat(dev, attr, bufOverheat);
237 dev_err(dev, "\nCurrent temp: %s ", bufTemp);
238 dev_err(dev, "\nOld overheat limit: %s ", bufOverheat);
239 dev_err(dev, "\nReset from overheat: curr temp=%ld, "
240 "new overheat temp=%d\n\n", currTemp, (int)num);
243 /* External temperature h/w shutdown limit */
244 temp = temperature_to_value(pdata->ext_range, (s8)num);
245 err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, temp);
249 /* Local temperature h/w shutdown limit */
250 temp = temperature_to_value(pdata->ext_range, (s8)num);
251 err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, temp);
256 dev_err(dev, " %s: failed to set temperature-overheat\n", __func__);
260 static ssize_t nct1008_show_temp_alert(struct device *dev,
261 struct device_attribute *attr,
264 struct i2c_client *client = to_i2c_client(dev);
265 struct nct1008_platform_data *pdata = client->dev.platform_data;
268 /* External Temperature Throttling hi-limit */
269 value = i2c_smbus_read_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
272 temp_hi = value_to_temperature(pdata->ext_range, value);
274 /* External Temperature Throttling lo-limit */
275 value = i2c_smbus_read_byte_data(client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
278 temp_lo = value_to_temperature(pdata->ext_range, value);
280 return snprintf(buf, MAX_STR_PRINT, "lo:%d hi:%d\n", temp_lo, temp_hi);
282 dev_err(dev, "%s: failed to read temperature-alert\n", __func__);
283 return snprintf(buf, MAX_STR_PRINT, " Rd alert Error\n");
286 static ssize_t nct1008_set_temp_alert(struct device *dev,
287 struct device_attribute *attr,
288 const char *buf, size_t count)
293 struct i2c_client *client = to_i2c_client(dev);
294 struct nct1008_platform_data *pdata = client->dev.platform_data;
296 if (strict_strtol(buf, 0, &num)) {
297 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
301 if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
302 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
307 /* External Temperature Throttling limit */
308 value = temperature_to_value(pdata->ext_range, (s8)num);
309 err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
314 /* Local Temperature Throttling limit */
315 err = i2c_smbus_write_byte_data(client, LOCAL_TEMP_HI_LIMIT_WR,
322 dev_err(dev, "%s: failed to set temperature-alert "
327 static ssize_t nct1008_show_ext_temp(struct device *dev,
328 struct device_attribute *attr, char *buf)
330 struct i2c_client *client = to_i2c_client(dev);
331 struct nct1008_platform_data *pdata = client->dev.platform_data;
336 if (!dev || !buf || !attr)
339 /* When reading the full external temperature value, read the
340 * LSB first. This causes the MSB to be locked (that is, the
341 * ADC does not write to it) until it is read */
342 data_lo = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
344 dev_err(&client->dev, "%s: failed to read "
345 "ext_temperature, i2c error=%d\n", __func__, data_lo);
349 data = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
351 dev_err(&client->dev, "%s: failed to read "
352 "ext_temperature, i2c error=%d\n", __func__, data);
356 temp_value = value_to_temperature(pdata->ext_range, data);
358 return snprintf(buf, MAX_STR_PRINT, "%d.%d\n", temp_value,
359 (25 * (data_lo >> 6)));
361 return snprintf(buf, MAX_STR_PRINT, "Error read ext temperature\n");
364 static DEVICE_ATTR(temperature, S_IRUGO, nct1008_show_temp, NULL);
365 static DEVICE_ATTR(temperature_overheat, (S_IRUGO | (S_IWUSR | S_IWGRP)),
366 nct1008_show_temp_overheat, nct1008_set_temp_overheat);
367 static DEVICE_ATTR(temperature_alert, (S_IRUGO | (S_IWUSR | S_IWGRP)),
368 nct1008_show_temp_alert, nct1008_set_temp_alert);
369 static DEVICE_ATTR(ext_temperature, S_IRUGO, nct1008_show_ext_temp, NULL);
371 static struct attribute *nct1008_attributes[] = {
372 &dev_attr_temperature.attr,
373 &dev_attr_temperature_overheat.attr,
374 &dev_attr_temperature_alert.attr,
375 &dev_attr_ext_temperature.attr,
379 static const struct attribute_group nct1008_attr_group = {
380 .attrs = nct1008_attributes,
383 #ifdef CONFIG_DEBUG_FS
384 #include <linux/debugfs.h>
385 #include <linux/seq_file.h>
386 static void print_reg(const char *reg_name, struct seq_file *s,
389 struct nct1008_data *nct_data = s->private;
392 ret = i2c_smbus_read_byte_data(nct_data->client,
395 seq_printf(s, "Reg %s Addr = 0x%02x Reg 0x%02x "
396 "Value 0x%02x\n", reg_name,
397 nct_data->client->addr,
400 seq_printf(s, "%s: line=%d, i2c read error=%d\n",
401 __func__, __LINE__, ret);
404 static int dbg_nct1008_show(struct seq_file *s, void *unused)
406 seq_printf(s, "nct1008 Registers\n");
407 seq_printf(s, "------------------\n");
408 print_reg("Local Temp Value ", s, 0x00);
409 print_reg("Ext Temp Value Hi ", s, 0x01);
410 print_reg("Status ", s, 0x02);
411 print_reg("Configuration ", s, 0x03);
412 print_reg("Conversion Rate ", s, 0x04);
413 print_reg("Local Temp Hi Limit ", s, 0x05);
414 print_reg("Local Temp Lo Limit ", s, 0x06);
415 print_reg("Ext Temp Hi Limit Hi", s, 0x07);
416 print_reg("Ext Temp Hi Limit Lo", s, 0x13);
417 print_reg("Ext Temp Lo Limit Hi", s, 0x08);
418 print_reg("Ext Temp Lo Limit Lo", s, 0x14);
419 print_reg("Ext Temp Value Lo ", s, 0x10);
420 print_reg("Ext Temp Offset Hi ", s, 0x11);
421 print_reg("Ext Temp Offset Lo ", s, 0x12);
422 print_reg("Ext THERM Limit ", s, 0x19);
423 print_reg("Local THERM Limit ", s, 0x20);
424 print_reg("THERM Hysteresis ", s, 0x21);
425 print_reg("Consecutive ALERT ", s, 0x22);
429 static int dbg_nct1008_open(struct inode *inode, struct file *file)
431 return single_open(file, dbg_nct1008_show, inode->i_private);
434 static const struct file_operations debug_fops = {
435 .open = dbg_nct1008_open,
438 .release = single_release,
441 static int __init nct1008_debuginit(struct nct1008_data *nct)
445 d = debugfs_create_file("nct1008", S_IRUGO, NULL,
446 (void *)nct, &debug_fops);
447 if ((!d) || IS_ERR(d)) {
448 dev_err(&nct->client->dev, "Error: %s debugfs_create_file"
449 " returned an error\n", __func__);
453 if (d == ERR_PTR(-ENODEV)) {
454 dev_err(&nct->client->dev, "Error: %s debugfs not supported "
455 "error=-ENODEV\n", __func__);
464 static int __init nct1008_debuginit(struct nct1008_data *nct)
470 static int nct1008_enable(struct i2c_client *client)
472 struct nct1008_data *data = i2c_get_clientdata(client);
475 err = i2c_smbus_write_byte_data(client, CONFIG_WR,
476 data->config & ~STANDBY_BIT);
478 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
479 __func__, __LINE__, err);
483 static int nct1008_disable(struct i2c_client *client)
485 struct nct1008_data *data = i2c_get_clientdata(client);
488 err = i2c_smbus_write_byte_data(client, CONFIG_WR,
489 data->config | STANDBY_BIT);
491 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
492 __func__, __LINE__, err);
496 static int nct1008_within_limits(struct nct1008_data *data)
500 intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD);
502 return !(intr_status & (BIT(3) | BIT(4)));
505 static void nct1008_work_func(struct work_struct *work)
507 struct nct1008_data *data = container_of(work, struct nct1008_data,
512 nct1008_disable(data->client);
514 if (data->alert_func)
515 if (!nct1008_within_limits(data))
516 data->alert_func(data->alert_data);
518 /* Initiate one-shot conversion */
519 i2c_smbus_write_byte_data(data->client, ONE_SHOT, 0x1);
521 /* Give hardware necessary time to finish conversion */
522 ts = ns_to_timespec(MAX_CONV_TIME_ONESHOT_MS * 1000 * 1000);
523 hrtimer_nanosleep(&ts, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
525 intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD);
527 nct1008_enable(data->client);
529 enable_irq(data->client->irq);
532 static irqreturn_t nct1008_irq(int irq, void *dev_id)
534 struct nct1008_data *data = dev_id;
536 disable_irq_nosync(irq);
537 queue_work(data->workqueue, &data->work);
542 static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
545 if (!data->nct_reg) {
546 data->nct_reg = regulator_get(&data->client->dev, "vdd");
547 if (IS_ERR_OR_NULL(data->nct_reg)) {
548 if (PTR_ERR(data->nct_reg) == -ENODEV)
549 dev_info(&data->client->dev,
550 "no regulator found for vdd."
551 " Assuming vdd is always powered");
553 dev_warn(&data->client->dev, "Error [%ld] in "
554 "getting the regulator handle for"
555 " vdd\n", PTR_ERR(data->nct_reg));
556 data->nct_reg = NULL;
561 ret = regulator_enable(data->nct_reg);
563 ret = regulator_disable(data->nct_reg);
566 dev_err(&data->client->dev, "Error in %s rail vdd_nct1008, "
567 "error %d\n", (is_enable) ? "enabling" : "disabling",
570 dev_info(&data->client->dev, "success in %s rail vdd_nct1008\n",
571 (is_enable) ? "enabling" : "disabling");
574 static int __devinit nct1008_configure_sensor(struct nct1008_data* data)
576 struct i2c_client *client = data->client;
577 struct nct1008_platform_data *pdata = client->dev.platform_data;
583 if (!pdata || !pdata->supported_hwrev)
586 /* Place in Standby */
587 data->config = STANDBY_BIT;
588 err = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
592 /* External temperature h/w shutdown limit */
593 value = temperature_to_value(pdata->ext_range, NCT1008_MAX_TEMP);
594 err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, value);
598 /* Local temperature h/w shutdown limit */
599 value = temperature_to_value(pdata->ext_range, NCT1008_MAX_TEMP);
600 err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, value);
604 /* set extended range mode if needed */
605 if (pdata->ext_range)
606 data->config |= EXTENDED_RANGE_BIT;
607 data->config &= ~(THERM2_BIT | ALERT_BIT);
609 err = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
613 /* Temperature conversion rate */
614 err = i2c_smbus_write_byte_data(client, CONV_RATE_WR, pdata->conv_rate);
618 data->conv_period_ms = conv_period_ms_table[pdata->conv_rate];
620 /* Setup local hi and lo limits */
621 err = i2c_smbus_write_byte_data(client,
622 LOCAL_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
626 err = i2c_smbus_write_byte_data(client,
627 LOCAL_TEMP_LO_LIMIT_WR, 0);
631 /* Setup external hi and lo limits */
632 err = i2c_smbus_write_byte_data(client,
633 EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
636 err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
641 /* read initial temperature */
642 value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
647 temp = value_to_temperature(pdata->ext_range, value);
648 dev_dbg(&client->dev, "\n initial local temp = %d ", temp);
650 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
655 temp2 = (value >> 6);
656 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
661 temp = value_to_temperature(pdata->ext_range, value);
664 dev_dbg(&client->dev, "\n initial ext temp = %d.%d deg",
667 dev_dbg(&client->dev, "\n initial ext temp = %d.0 deg", temp);
669 /* Remote channel offset */
670 err = i2c_smbus_write_byte_data(client, OFFSET_WR, pdata->offset / 4);
674 /* Remote channel offset fraction (quarters) */
675 err = i2c_smbus_write_byte_data(client, OFFSET_QUARTER_WR,
676 (pdata->offset % 4) << 6);
680 /* register sysfs hooks */
681 err = sysfs_create_group(&client->dev.kobj, &nct1008_attr_group);
683 dev_err(&client->dev, "\n sysfs create err=%d ", err);
689 dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
693 static int __devinit nct1008_configure_irq(struct nct1008_data *data)
695 data->workqueue = create_singlethread_workqueue("nct1008");
697 INIT_WORK(&data->work, nct1008_work_func);
699 if (data->client->irq < 0)
702 return request_irq(data->client->irq, nct1008_irq,
707 int nct1008_thermal_get_temp(struct nct1008_data *data, long *temp)
709 return nct1008_get_temp(&data->client->dev, temp);
712 int nct1008_thermal_get_temp_low(struct nct1008_data *data, long *temp)
718 int nct1008_thermal_set_limits(struct nct1008_data *data,
724 bool extended_range = data->plat_data.ext_range;
725 long lo_limit = MILLICELSIUS_TO_CELSIUS(lo_limit_milli);
726 long hi_limit = MILLICELSIUS_TO_CELSIUS(hi_limit_milli);
728 if (lo_limit >= hi_limit)
731 if (data->current_lo_limit != lo_limit) {
732 value = temperature_to_value(extended_range, lo_limit);
733 pr_debug("%s: set lo_limit %ld\n", __func__, lo_limit);
734 err = i2c_smbus_write_byte_data(data->client,
735 EXT_TEMP_LO_LIMIT_HI_BYTE_WR, value);
739 data->current_lo_limit = lo_limit;
742 if (data->current_hi_limit != hi_limit) {
743 value = temperature_to_value(extended_range, hi_limit);
744 pr_debug("%s: set hi_limit %ld\n", __func__, hi_limit);
745 err = i2c_smbus_write_byte_data(data->client,
746 EXT_TEMP_HI_LIMIT_HI_BYTE_WR, value);
750 data->current_hi_limit = hi_limit;
756 int nct1008_thermal_set_alert(struct nct1008_data *data,
757 void (*alert_func)(void *),
760 data->alert_data = alert_data;
761 data->alert_func = alert_func;
766 int nct1008_thermal_set_shutdown_temp(struct nct1008_data *data,
767 long shutdown_temp_milli)
769 struct i2c_client *client = data->client;
770 struct nct1008_platform_data *pdata = client->dev.platform_data;
775 shutdown_temp = MILLICELSIUS_TO_CELSIUS(shutdown_temp_milli);
777 /* External temperature h/w shutdown limit */
778 value = temperature_to_value(pdata->ext_range, shutdown_temp);
779 err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, value);
783 /* Local temperature h/w shutdown limit */
784 value = temperature_to_value(pdata->ext_range, shutdown_temp);
785 err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, value);
793 * Manufacturer(OnSemi) recommended sequence for
794 * Extended Range mode is as follows
795 * 1. Place in Standby
796 * 2. Scale the THERM and ALERT limits
797 * appropriately(for Extended Range mode).
798 * 3. Enable Extended Range mode.
799 * ALERT mask/THERM2 mode may be done here
800 * as these are not critical
801 * 4. Set Conversion Rate as required
802 * 5. Take device out of Standby
806 * function nct1008_probe takes care of initial configuration
808 static int __devinit nct1008_probe(struct i2c_client *client,
809 const struct i2c_device_id *id)
811 struct nct1008_data *data;
815 data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
819 data->client = client;
820 memcpy(&data->plat_data, client->dev.platform_data,
821 sizeof(struct nct1008_platform_data));
822 i2c_set_clientdata(client, data);
824 nct1008_power_control(data, true);
825 /* extended range recommended steps 1 through 4 taken care
826 * in nct1008_configure_sensor function */
827 err = nct1008_configure_sensor(data); /* sensor is in standby */
829 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
830 __FILE__, __func__, __LINE__);
834 err = nct1008_configure_irq(data);
836 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
837 __FILE__, __func__, __LINE__);
840 dev_info(&client->dev, "%s: initialized\n", __func__);
842 /* extended range recommended step 5 is in nct1008_enable function */
843 err = nct1008_enable(client); /* sensor is running */
845 dev_err(&client->dev, "Error: %s, line=%d, error=%d\n",
846 __func__, __LINE__, err);
850 err = nct1008_debuginit(data);
852 err = 0; /* without debugfs we may continue */
854 /* notify callback that probe is done */
855 if (data->plat_data.probe_callback)
856 data->plat_data.probe_callback(data);
861 dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
862 nct1008_power_control(data, false);
864 regulator_put(data->nct_reg);
869 static int __devexit nct1008_remove(struct i2c_client *client)
871 struct nct1008_data *data = i2c_get_clientdata(client);
874 debugfs_remove(data->dent);
876 free_irq(data->client->irq, data);
877 cancel_work_sync(&data->work);
878 sysfs_remove_group(&client->dev.kobj, &nct1008_attr_group);
879 nct1008_power_control(data, false);
881 regulator_put(data->nct_reg);
889 static int nct1008_suspend(struct i2c_client *client, pm_message_t state)
893 disable_irq(client->irq);
894 err = nct1008_disable(client);
898 static int nct1008_resume(struct i2c_client *client)
900 struct nct1008_data *data = i2c_get_clientdata(client);
903 err = nct1008_enable(client);
905 dev_err(&client->dev, "Error: %s, error=%d\n",
909 enable_irq(client->irq);
915 static const struct i2c_device_id nct1008_id[] = {
919 MODULE_DEVICE_TABLE(i2c, nct1008_id);
921 static struct i2c_driver nct1008_driver = {
925 .probe = nct1008_probe,
926 .remove = __devexit_p(nct1008_remove),
927 .id_table = nct1008_id,
929 .suspend = nct1008_suspend,
930 .resume = nct1008_resume,
934 static int __init nct1008_init(void)
936 return i2c_add_driver(&nct1008_driver);
939 static void __exit nct1008_exit(void)
941 i2c_del_driver(&nct1008_driver);
944 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008");
945 MODULE_LICENSE("GPL");
947 module_init(nct1008_init);
948 module_exit(nct1008_exit);