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/mutex.h>
26 #include <linux/module.h>
27 #include <linux/i2c.h>
28 #include <linux/slab.h>
29 #include <linux/err.h>
30 #include <linux/gpio.h>
31 #include <linux/device.h>
32 #include <linux/nct1008.h>
33 #include <linux/delay.h>
34 #include <linux/regulator/consumer.h>
36 #define DRIVER_NAME "nct1008"
38 /* Register Addresses */
39 #define LOCAL_TEMP_RD 0x00
40 #define EXT_TEMP_RD_HI 0x01
41 #define EXT_TEMP_RD_LO 0x10
42 #define STATUS_RD 0x02
43 #define CONFIG_RD 0x03
45 #define LOCAL_TEMP_HI_LIMIT_RD 0x05
46 #define LOCAL_TEMP_LO_LIMIT_RD 0x06
48 #define EXT_TEMP_HI_LIMIT_HI_BYTE_RD 0x07
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
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)
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)
73 #define NCT1008_MIN_TEMP -64
74 #define NCT1008_MAX_TEMP 191
76 #define MAX_STR_PRINT 50
79 struct work_struct work;
80 struct i2c_client *client;
81 struct nct1008_platform_data plat_data;
87 void (*alarm_fn)(bool raised);
88 struct regulator *nct_reg;
91 static inline s8 value_to_temperature(bool extended, u8 value)
93 return extended ? (s8)(value - EXTENDED_RANGE_OFFSET) : (s8)value;
96 static inline u8 temperature_to_value(bool extended, s8 temp)
98 return extended ? (u8)(temp + EXTENDED_RANGE_OFFSET) : (u8)temp;
101 static int nct1008_get_temp(struct device *dev, u8 *pTemp)
103 struct i2c_client *client = to_i2c_client(dev);
104 struct nct1008_platform_data *pdata = client->dev.platform_data;
109 value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
112 temp1 = value_to_temperature(pdata->ext_range, value);
114 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
117 temp2 = (value >> 6);
118 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
121 temp = value_to_temperature(pdata->ext_range, value);
123 *pTemp = max((int)temp1, (int)temp + 1);
125 *pTemp = max(temp1, temp);
127 dev_dbg(dev, "\n %s: ret temp=%dC ", __func__, *pTemp);
130 dev_err(&client->dev, "\n error in file=: %s %s() line=%d: "
131 "error=%d ", __FILE__, __func__, __LINE__, value);
135 static ssize_t nct1008_show_temp(struct device *dev,
136 struct device_attribute *attr, char *buf)
138 struct i2c_client *client = to_i2c_client(dev);
139 struct nct1008_platform_data *pdata = client->dev.platform_data;
145 if (!dev || !buf || !attr)
148 value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
151 temp1 = value_to_temperature(pdata->ext_range, value);
153 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
156 temp2 = (value >> 6);
157 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
160 temp = value_to_temperature(pdata->ext_range, value);
162 return snprintf(buf, MAX_STR_PRINT, "%d %d.%d\n",
163 temp1, temp, temp2 * 25);
166 return snprintf(buf, MAX_STR_PRINT,
167 "Error read local/ext temperature\n");
170 static ssize_t nct1008_show_temp_overheat(struct device *dev,
171 struct device_attribute *attr,
174 struct i2c_client *client = to_i2c_client(dev);
175 struct nct1008_platform_data *pdata = client->dev.platform_data;
179 /* Local temperature h/w shutdown limit */
180 value = i2c_smbus_read_byte_data(client, LOCAL_THERM_LIMIT_WR);
183 temp = value_to_temperature(pdata->ext_range, value);
185 /* External temperature h/w shutdown limit */
186 value = i2c_smbus_read_byte_data(client, EXT_THERM_LIMIT_WR);
189 temp2 = value_to_temperature(pdata->ext_range, value);
191 return snprintf(buf, MAX_STR_PRINT, "%d %d\n", temp, temp2);
193 dev_err(dev, "%s: failed to read temperature-overheat "
195 return snprintf(buf, MAX_STR_PRINT, " Rd overheat Error\n");
198 static ssize_t nct1008_set_temp_overheat(struct device *dev,
199 struct device_attribute *attr,
200 const char *buf, size_t count)
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];
212 if (strict_strtol(buf, 0, &num)) {
213 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
217 if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
218 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
222 /* check for system power down */
223 err = nct1008_get_temp(dev, &currTemp);
227 if (currTemp >= (int)num) {
228 ret = nct1008_show_temp(dev, attr, bufTemp);
229 ret = nct1008_show_temp_overheat(dev, attr, bufOverheat);
230 dev_err(dev, "\nCurrent temp: %s ", bufTemp);
231 dev_err(dev, "\nOld overheat limit: %s ", bufOverheat);
232 dev_err(dev, "\nReset from overheat: curr temp=%d, "
233 "new overheat temp=%d\n\n", currTemp, (int)num);
236 /* External temperature h/w shutdown limit */
237 temp = temperature_to_value(pdata->ext_range, (s8)num);
238 err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, temp);
242 /* Local temperature h/w shutdown limit */
243 temp = temperature_to_value(pdata->ext_range, (s8)num);
244 err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, temp);
249 dev_err(dev, " %s: failed to set temperature-overheat\n", __func__);
253 static ssize_t nct1008_show_temp_alert(struct device *dev,
254 struct device_attribute *attr,
257 struct i2c_client *client = to_i2c_client(dev);
258 struct nct1008_platform_data *pdata = client->dev.platform_data;
261 /* External Temperature Throttling limit */
262 value = i2c_smbus_read_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
265 temp2 = value_to_temperature(pdata->ext_range, value);
267 /* Local Temperature Throttling limit */
268 value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_HI_LIMIT_RD);
271 temp = value_to_temperature(pdata->ext_range, value);
273 return snprintf(buf, MAX_STR_PRINT, "%d %d\n", temp, temp2);
275 dev_err(dev, "%s: failed to read temperature-overheat "
277 return snprintf(buf, MAX_STR_PRINT, " Rd overheat Error\n");
280 static ssize_t nct1008_set_temp_alert(struct device *dev,
281 struct device_attribute *attr,
282 const char *buf, size_t count)
287 struct i2c_client *client = to_i2c_client(dev);
288 struct nct1008_platform_data *pdata = client->dev.platform_data;
290 if (strict_strtol(buf, 0, &num)) {
291 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
295 if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
296 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
301 /* External Temperature Throttling limit */
302 value = temperature_to_value(pdata->ext_range, (s8)num);
303 err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
308 /* Local Temperature Throttling limit */
309 err = i2c_smbus_write_byte_data(client, LOCAL_TEMP_HI_LIMIT_WR,
316 dev_err(dev, "%s: failed to set temperature-alert "
321 static ssize_t nct1008_show_ext_temp(struct device *dev,
322 struct device_attribute *attr, char *buf)
324 struct i2c_client *client = to_i2c_client(dev);
325 struct nct1008_platform_data *pdata = client->dev.platform_data;
330 if (!dev || !buf || !attr)
333 /* When reading the full external temperature value, read the
334 * LSB first. This causes the MSB to be locked (that is, the
335 * ADC does not write to it) until it is read */
336 data_lo = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
338 dev_err(&client->dev, "%s: failed to read "
339 "ext_temperature, i2c error=%d\n", __func__, data_lo);
343 data = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
345 dev_err(&client->dev, "%s: failed to read "
346 "ext_temperature, i2c error=%d\n", __func__, data);
350 temp_value = value_to_temperature(pdata->ext_range, data);
352 return snprintf(buf, MAX_STR_PRINT, "%d.%d\n", temp_value,
353 (25 * (data_lo >> 6)));
355 return snprintf(buf, MAX_STR_PRINT, "Error read ext temperature\n");
358 static DEVICE_ATTR(temperature, S_IRUGO, nct1008_show_temp, NULL);
359 static DEVICE_ATTR(temperature_overheat, (S_IRUGO | (S_IWUSR | S_IWGRP)),
360 nct1008_show_temp_overheat, nct1008_set_temp_overheat);
361 static DEVICE_ATTR(temperature_alert, (S_IRUGO | (S_IWUSR | S_IWGRP)),
362 nct1008_show_temp_alert, nct1008_set_temp_alert);
363 static DEVICE_ATTR(ext_temperature, S_IRUGO, nct1008_show_ext_temp, NULL);
365 static struct attribute *nct1008_attributes[] = {
366 &dev_attr_temperature.attr,
367 &dev_attr_temperature_overheat.attr,
368 &dev_attr_temperature_alert.attr,
369 &dev_attr_ext_temperature.attr,
373 static const struct attribute_group nct1008_attr_group = {
374 .attrs = nct1008_attributes,
377 #ifdef CONFIG_DEBUG_FS
378 #include <linux/debugfs.h>
379 #include <linux/seq_file.h>
380 static void print_reg(const char *reg_name, struct seq_file *s,
383 struct nct1008_data *nct_data = s->private;
386 ret = i2c_smbus_read_byte_data(nct_data->client,
389 seq_printf(s, "Reg %s Addr = 0x%02x Reg 0x%02x "
390 "Value 0x%02x\n", reg_name,
391 nct_data->client->addr,
394 seq_printf(s, "%s: line=%d, i2c read error=%d\n",
395 __func__, __LINE__, ret);
398 static int dbg_nct1008_show(struct seq_file *s, void *unused)
400 seq_printf(s, "nct1008 Registers\n");
401 seq_printf(s, "------------------\n");
402 print_reg("Local Temp Value ", s, 0x00);
403 print_reg("Ext Temp Value Hi ", s, 0x01);
404 print_reg("Status ", s, 0x02);
405 print_reg("Configuration ", s, 0x03);
406 print_reg("Conversion Rate ", s, 0x04);
407 print_reg("Local Temp Hi Limit ", s, 0x05);
408 print_reg("Local Temp Lo Limit ", s, 0x06);
409 print_reg("Ext Temp Hi Limit Hi", s, 0x07);
410 print_reg("Ext Temp Hi Limit Lo", s, 0x13);
411 print_reg("Ext Temp Lo Limit Hi", s, 0x08);
412 print_reg("Ext Temp Lo Limit Lo", s, 0x14);
413 print_reg("Ext Temp Value Lo ", s, 0x10);
414 print_reg("Ext Temp Offset Hi ", s, 0x11);
415 print_reg("Ext Temp Offset Lo ", s, 0x12);
416 print_reg("Ext THERM Limit ", s, 0x19);
417 print_reg("Local THERM Limit ", s, 0x20);
418 print_reg("THERM Hysteresis ", s, 0x21);
419 print_reg("Consecutive ALERT ", s, 0x22);
423 static int dbg_nct1008_open(struct inode *inode, struct file *file)
425 return single_open(file, dbg_nct1008_show, inode->i_private);
428 static const struct file_operations debug_fops = {
429 .open = dbg_nct1008_open,
432 .release = single_release,
435 static int __init nct1008_debuginit(struct nct1008_data *nct)
439 d = debugfs_create_file("nct1008", S_IRUGO, NULL,
440 (void *)nct, &debug_fops);
441 if ((!d) || IS_ERR(d)) {
442 dev_err(&nct->client->dev, "Error: %s debugfs_create_file"
443 " returned an error\n", __func__);
447 if (d == ERR_PTR(-ENODEV)) {
448 dev_err(&nct->client->dev, "Error: %s debugfs not supported "
449 "error=-ENODEV\n", __func__);
458 static int __init nct1008_debuginit(struct nct1008_data *nct)
464 static int nct1008_enable(struct i2c_client *client)
466 struct nct1008_data *data = i2c_get_clientdata(client);
469 err = i2c_smbus_write_byte_data(client, CONFIG_WR,
470 data->config & ~STANDBY_BIT);
472 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
473 __func__, __LINE__, err);
477 static int nct1008_disable(struct i2c_client *client)
479 struct nct1008_data *data = i2c_get_clientdata(client);
482 err = i2c_smbus_write_byte_data(client, CONFIG_WR,
483 data->config | STANDBY_BIT);
485 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
486 __func__, __LINE__, err);
490 static int nct1008_disable_alert(struct nct1008_data *data)
492 struct i2c_client *client = data->client;
497 * Disable ALERT# output, because these chips don't implement
498 * SMBus alert correctly; they should only hold the alert line
501 val = i2c_smbus_read_byte_data(data->client, CONFIG_RD);
503 dev_err(&client->dev, "%s, line=%d, disable alert failed ... "
504 "i2c read error=%d\n", __func__, __LINE__, val);
507 data->config = val | ALERT_BIT;
508 ret = i2c_smbus_write_byte_data(client, CONFIG_WR, val | ALERT_BIT);
510 dev_err(&client->dev, "%s: fail to disable alert, i2c "
511 "write error=%d#\n", __func__, ret);
516 static int nct1008_enable_alert(struct nct1008_data *data)
521 val = i2c_smbus_read_byte_data(data->client, CONFIG_RD);
523 dev_err(&data->client->dev, "%s, line=%d, enable alert "
524 "failed ... i2c read error=%d\n", __func__,
528 val &= ~(ALERT_BIT | THERM2_BIT);
529 ret = i2c_smbus_write_byte_data(data->client, CONFIG_WR, val);
531 dev_err(&data->client->dev, "%s: fail to enable alert, i2c "
532 "write error=%d\n", __func__, ret);
539 static bool throttle_enb;
540 static void therm_throttle(struct nct1008_data *data, bool enable)
542 if (!data->alarm_fn) {
543 dev_err(&data->client->dev, "system too hot. no way to "
548 if (throttle_enb != enable) {
549 mutex_lock(&data->mutex);
550 data->alarm_fn(enable);
551 throttle_enb = enable;
552 mutex_unlock(&data->mutex);
556 #define ALERT_HYSTERESIS 3
557 static int edp_thermal_zone_val = -1;
558 static int current_hi_limit = -1;
559 static int current_lo_limit = -1;
561 static void nct1008_work_func(struct work_struct *work)
563 struct nct1008_data *data = container_of(work, struct nct1008_data,
565 bool extended_range = data->plat_data.ext_range;
566 u8 temperature, value;
568 int nentries = data->limits_sz;
569 int lo_limit = 0, hi_limit = 0;
572 intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD);
573 if (intr_status < 0) {
574 dev_err(&data->client->dev, "%s, line=%d, i2c read error=%d\n",
575 __func__, __LINE__, intr_status);
579 err = nct1008_get_temp(&data->client->dev, &temperature);
581 dev_err(&data->client->dev, "%s: get temp fail(%d)", __func__,
586 intr_status &= (BIT(3) | BIT(4));
590 err = nct1008_disable_alert(data);
592 dev_err(&data->client->dev, "%s: disable alert fail(error=%d)\n",
597 if (temperature < data->limits[0]) {
599 hi_limit = data->limits[0];
600 } else if (temperature >= data->limits[nentries-1]) {
601 lo_limit = data->limits[nentries-1] - ALERT_HYSTERESIS;
602 hi_limit = data->plat_data.shutdown_ext_limit;
604 for (i = 0; (i + 1) < nentries; i++) {
605 if (temperature >= data->limits[i] &&
606 temperature < data->limits[i + 1]) {
607 lo_limit = data->limits[i] - ALERT_HYSTERESIS;
608 hi_limit = data->limits[i + 1];
614 if (temperature >= data->plat_data.throttling_ext_limit) {
615 /* start throttling */
616 therm_throttle(data, true);
617 } else if (temperature <=
618 (data->plat_data.throttling_ext_limit - ALERT_HYSTERESIS)) {
619 /* switch off throttling */
620 therm_throttle(data, false);
623 if (lo_limit == hi_limit) {
628 if (current_lo_limit == lo_limit && current_hi_limit == hi_limit)
631 if (current_lo_limit != lo_limit) {
632 value = temperature_to_value(extended_range, lo_limit);
633 pr_debug("%s: %d\n", __func__, value);
634 err = i2c_smbus_write_byte_data(data->client,
635 EXT_TEMP_LO_LIMIT_HI_BYTE_WR, value);
639 current_lo_limit = lo_limit;
642 if (current_hi_limit != hi_limit) {
643 value = temperature_to_value(extended_range, hi_limit);
644 pr_debug("%s: %d\n", __func__, value);
645 err = i2c_smbus_write_byte_data(data->client,
646 EXT_TEMP_HI_LIMIT_HI_BYTE_WR, value);
650 current_hi_limit = hi_limit;
653 /* inform edp governor */
654 if (edp_thermal_zone_val != temperature)
656 * FIXME: Move this direct tegra_ function call to be called
657 * via a pointer in 'struct nct1008_data' (like 'alarm_fn')
659 tegra_edp_update_thermal_zone(temperature);
661 edp_thermal_zone_val = temperature;
664 nct1008_enable_alert(data);
667 dev_err(&data->client->dev, "%s: fail(error=%d)\n", __func__,
670 pr_debug("%s: done\n", __func__);
673 static irqreturn_t nct1008_irq(int irq, void *dev_id)
675 struct nct1008_data *data = dev_id;
677 schedule_work(&data->work);
681 static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
684 if (!data->nct_reg) {
685 data->nct_reg = regulator_get(&data->client->dev, "vdd");
686 if (IS_ERR_OR_NULL(data->nct_reg)) {
687 dev_warn(&data->client->dev, "Error [%d] in"
688 "getting the regulator handle for vdd "
689 "of %s\n", (int)data->nct_reg,
690 dev_name(&data->client->dev));
691 data->nct_reg = NULL;
696 ret = regulator_enable(data->nct_reg);
698 ret = regulator_disable(data->nct_reg);
701 dev_err(&data->client->dev, "Error in %s rail vdd_nct1008, "
702 "error %d\n", (is_enable) ? "enabling" : "disabling",
705 dev_info(&data->client->dev, "success in %s rail vdd_nct1008\n",
706 (is_enable) ? "enabling" : "disabling");
709 static int __devinit nct1008_configure_sensor(struct nct1008_data* data)
711 struct i2c_client *client = data->client;
712 struct nct1008_platform_data *pdata = client->dev.platform_data;
719 if (!pdata || !pdata->supported_hwrev)
722 /* Place in Standby */
723 data->config = STANDBY_BIT;
724 err = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
728 /* External temperature h/w shutdown limit */
729 value = temperature_to_value(pdata->ext_range,
730 pdata->shutdown_ext_limit);
731 err = i2c_smbus_write_byte_data(client, EXT_THERM_LIMIT_WR, value);
735 /* Local temperature h/w shutdown limit */
736 value = temperature_to_value(pdata->ext_range,
737 pdata->shutdown_local_limit);
738 err = i2c_smbus_write_byte_data(client, LOCAL_THERM_LIMIT_WR, value);
742 /* set extended range mode if needed */
743 if (pdata->ext_range)
744 data->config |= EXTENDED_RANGE_BIT;
745 if (pdata->thermal_zones_sz)
746 data->config &= ~(THERM2_BIT | ALERT_BIT);
748 data->config |= (ALERT_BIT | THERM2_BIT);
750 err = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config);
754 /* Temperature conversion rate */
755 err = i2c_smbus_write_byte_data(client, CONV_RATE_WR, pdata->conv_rate);
759 if (pdata->thermal_zones_sz) {
760 data->limits = pdata->thermal_zones;
761 data->limits_sz = pdata->thermal_zones_sz;
764 hi_limit = pdata->thermal_zones[0];
766 err = i2c_smbus_write_byte_data(client,
767 EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
771 err = i2c_smbus_write_byte_data(client,
772 LOCAL_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
776 err = i2c_smbus_write_byte_data(client,
777 LOCAL_TEMP_LO_LIMIT_WR, 0);
782 * External Temperature Throttling limit:
783 * Applies when 'Thermal Zones' are not specified.
785 hi_limit = pdata->throttling_ext_limit;
788 value = temperature_to_value(pdata->ext_range, hi_limit);
789 err = i2c_smbus_write_byte_data(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
794 /* read initial temperature */
795 value = i2c_smbus_read_byte_data(client, LOCAL_TEMP_RD);
800 temp = value_to_temperature(pdata->ext_range, value);
801 dev_dbg(&client->dev, "\n initial local temp = %d ", temp);
803 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_LO);
808 temp2 = (value >> 6);
809 value = i2c_smbus_read_byte_data(client, EXT_TEMP_RD_HI);
814 temp = value_to_temperature(pdata->ext_range, value);
817 dev_dbg(&client->dev, "\n initial ext temp = %d.%d deg",
820 dev_dbg(&client->dev, "\n initial ext temp = %d.0 deg", temp);
822 /* Remote channel offset */
823 err = i2c_smbus_write_byte_data(client, OFFSET_WR, pdata->offset / 4);
827 /* Remote channel offset fraction (quarters) */
828 err = i2c_smbus_write_byte_data(client, OFFSET_QUARTER_WR,
829 (pdata->offset % 4) << 6);
833 /* THERM hysteresis */
834 err = i2c_smbus_write_byte_data(client, THERM_HYSTERESIS_WR,
839 /* register sysfs hooks */
840 err = sysfs_create_group(&client->dev.kobj, &nct1008_attr_group);
842 dev_err(&client->dev, "\n sysfs create err=%d ", err);
846 data->alarm_fn = pdata->alarm_fn;
849 dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
853 static int __devinit nct1008_configure_irq(struct nct1008_data *data)
855 INIT_WORK(&data->work, nct1008_work_func);
857 if (data->client->irq < 0)
860 return request_irq(data->client->irq, nct1008_irq,
861 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
865 static unsigned int get_ext_mode_delay_ms(unsigned int conv_rate)
895 * Manufacturer(OnSemi) recommended sequence for
896 * Extended Range mode is as follows
897 * 1. Place in Standby
898 * 2. Scale the THERM and ALERT limits
899 * appropriately(for Extended Range mode).
900 * 3. Enable Extended Range mode.
901 * ALERT mask/THERM2 mode may be done here
902 * as these are not critical
903 * 4. Set Conversion Rate as required
904 * 5. Take device out of Standby
908 * function nct1008_probe takes care of initial configuration
910 static int __devinit nct1008_probe(struct i2c_client *client,
911 const struct i2c_device_id *id)
913 struct nct1008_data *data;
918 data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
923 data->client = client;
924 memcpy(&data->plat_data, client->dev.platform_data,
925 sizeof(struct nct1008_platform_data));
926 i2c_set_clientdata(client, data);
927 mutex_init(&data->mutex);
929 nct1008_power_control(data, true);
930 /* extended range recommended steps 1 through 4 taken care
931 * in nct1008_configure_sensor function */
932 err = nct1008_configure_sensor(data); /* sensor is in standby */
934 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
935 __FILE__, __func__, __LINE__);
939 err = nct1008_configure_irq(data);
941 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
942 __FILE__, __func__, __LINE__);
945 dev_info(&client->dev, "%s: initialized\n", __func__);
947 /* extended range recommended step 5 is in nct1008_enable function */
948 err = nct1008_enable(client); /* sensor is running */
950 dev_err(&client->dev, "Error: %s, line=%d, error=%d\n",
951 __func__, __LINE__, err);
955 err = nct1008_debuginit(data);
957 err = 0; /* without debugfs we may continue */
959 /* switch to extended mode reports correct temperature
960 * from next measurement cycle */
961 if (data->plat_data.ext_range) {
962 delay = get_ext_mode_delay_ms(
963 data->plat_data.conv_rate);
964 msleep(delay); /* 63msec for default conv rate 0x8 */
966 err = nct1008_get_temp(&data->client->dev, &temperature);
968 dev_err(&data->client->dev, "%s: get temp fail(%d)",
970 return 0; /*do not fail init on the 1st read */
973 tegra_edp_update_thermal_zone(temperature);
977 dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
978 nct1008_power_control(data, false);
980 regulator_put(data->nct_reg);
985 static int __devexit nct1008_remove(struct i2c_client *client)
987 struct nct1008_data *data = i2c_get_clientdata(client);
990 debugfs_remove(data->dent);
991 free_irq(data->client->irq, data);
992 cancel_work_sync(&data->work);
993 sysfs_remove_group(&client->dev.kobj, &nct1008_attr_group);
994 nct1008_power_control(data, false);
996 regulator_put(data->nct_reg);
1003 static int nct1008_suspend(struct i2c_client *client, pm_message_t state)
1007 disable_irq(client->irq);
1008 err = nct1008_disable(client);
1012 static int nct1008_resume(struct i2c_client *client)
1014 struct nct1008_data *data = i2c_get_clientdata(client);
1017 err = nct1008_enable(client);
1019 dev_err(&client->dev, "Error: %s, error=%d\n",
1023 enable_irq(client->irq);
1024 schedule_work(&data->work);
1030 static const struct i2c_device_id nct1008_id[] = {
1034 MODULE_DEVICE_TABLE(i2c, nct1008_id);
1036 static struct i2c_driver nct1008_driver = {
1038 .name = DRIVER_NAME,
1040 .probe = nct1008_probe,
1041 .remove = __devexit_p(nct1008_remove),
1042 .id_table = nct1008_id,
1044 .suspend = nct1008_suspend,
1045 .resume = nct1008_resume,
1049 static int __init nct1008_init(void)
1051 return i2c_add_driver(&nct1008_driver);
1054 static void __exit nct1008_exit(void)
1056 i2c_del_driver(&nct1008_driver);
1059 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008");
1060 MODULE_LICENSE("GPL");
1062 module_init(nct1008_init);
1063 module_exit(nct1008_exit);