2 * drivers/misc/nct1008.c
4 * Driver for NCT1008, temperature monitoring device from ON Semiconductors
6 * Copyright (c) 2010-2016, NVIDIA CORPORATION. All rights reserved.
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/of_gpio.h>
33 #include <linux/delay.h>
34 #include <linux/thermal.h>
35 #include <linux/regulator/consumer.h>
37 /* Register Addresses used in this module. */
38 #define LOC_TEMP_RD 0x00
39 #define EXT_TEMP_HI_RD 0x01
40 #define STATUS_RD 0x02
41 #define CONFIG_RD 0x03
42 #define CONV_RATE_RD 0x04
43 #define LOC_TEMP_HI_LIMIT_RD 0x05
44 #define LOC_TEMP_LO_LIMIT_RD 0x06
45 #define EXT_TEMP_HI_LIMIT_HI_BYTE_RD 0x07
46 #define EXT_TEMP_LO_LIMIT_HI_BYTE_RD 0x08
47 #define CONFIG_WR 0x09
48 #define CONV_RATE_WR 0x0A
49 #define LOC_TEMP_HI_LIMIT_WR 0x0B
50 #define LOC_TEMP_LO_LIMIT_WR 0x0C
51 #define EXT_TEMP_HI_LIMIT_HI_BYTE_WR 0x0D
52 #define EXT_TEMP_LO_LIMIT_HI_BYTE_WR 0x0E
54 #define EXT_TEMP_LO_RD 0x10
55 #define OFFSET_WR 0x11
56 #define OFFSET_QUARTER_WR 0x12
57 #define EXT_TEMP_HI_LIMIT_LO_BYTE 0x13
58 #define EXT_TEMP_LO_LIMIT_LO_BYTE 0x14
63 #define EXT_THERM_LIMIT_WR 0x19
70 #define LOC_THERM_LIMIT 0x20
71 #define THERM_HYSTERESIS 0x21
72 #define COSECUTIVE_ALERT 0x22
74 /* Set of register types that are sensor dependant. */
75 enum nct1008_sensor_reg_types {
76 TEMP_HI_LIMIT, TEMP_LO_LIMIT,
77 TEMP_HI_LIMIT_RD, TEMP_LO_LIMIT_RD,
78 TEMP_HI_LIMIT_WR, TEMP_LO_LIMIT_WR,
79 TEMP_RD_LO, TEMP_RD_HI,
81 REGS_COUNT /* This has to be the last element! */
84 /* Mapping from register type on a given sensor to hardware specific address. */
85 static int nct1008_sensor_regs[SENSORS_COUNT][REGS_COUNT] = {
87 [TEMP_HI_LIMIT_RD] = LOC_TEMP_HI_LIMIT_RD,
88 [TEMP_HI_LIMIT_WR] = LOC_TEMP_HI_LIMIT_WR,
89 [TEMP_LO_LIMIT_RD] = LOC_TEMP_LO_LIMIT_RD,
90 [TEMP_LO_LIMIT_WR] = LOC_TEMP_LO_LIMIT_WR,
93 [TEMP_HI_LIMIT_RD] = EXT_TEMP_HI_LIMIT_HI_BYTE_RD,
94 [TEMP_HI_LIMIT_WR] = EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
95 [TEMP_LO_LIMIT_RD] = EXT_TEMP_LO_LIMIT_HI_BYTE_RD,
96 [TEMP_LO_LIMIT_WR] = EXT_TEMP_LO_LIMIT_HI_BYTE_WR,
97 [TEMP_RD_LO] = EXT_TEMP_LO_RD,
98 [TEMP_RD_HI] = EXT_TEMP_HI_RD,
102 /* Accessor to the sensor specific registers. */
103 #define NCT_REG(x, y) nct1008_sensor_regs[x][y]
105 /* Configuration register bits. */
106 #define EXTENDED_RANGE_BIT BIT(2)
107 #define THERM2_BIT BIT(5)
108 #define STANDBY_BIT BIT(6)
109 #define ALERT_BIT BIT(7)
111 /* Status register trip point bits. */
112 #define EXT_LO_BIT BIT(3) /* External Sensor has tripped 'temp <= LOW' */
113 #define EXT_HI_BIT BIT(4) /* External Sensor has tripped 'temp > HIGH' */
114 #define LOC_LO_BIT BIT(5) /* Local Sensor has tripped 'temp <= LOW' */
115 #define LOC_HI_BIT BIT(6) /* Local Sensor has tripped 'temp > HIGH' */
118 #define EXTENDED_RANGE_OFFSET 64U
119 #define STANDARD_RANGE_MAX 127U
120 #define EXTENDED_RANGE_MAX (150U + EXTENDED_RANGE_OFFSET)
122 #define NCT1008_MIN_TEMP (-64)
123 #define NCT1008_MAX_TEMP 191
124 #define NCT1008_MAX_TEMP_MILLI 191750
126 #define MAX_STR_PRINT 50
127 #define MAX_CONV_TIME_ONESHOT_MS 52
129 #define CELSIUS_TO_MILLICELSIUS(x) ((x)*1000)
130 #define MILLICELSIUS_TO_CELSIUS(x) ((x)/1000)
132 struct nct1008_adjust_offset_table {
137 struct nct1008_sensor_data {
138 struct nct1008_adjust_offset_table offset_table[16];
139 struct thermal_zone_device *thz;
140 long current_hi_limit;
141 long current_lo_limit;
145 struct nct1008_data {
146 struct workqueue_struct *workqueue;
147 struct work_struct work;
148 struct i2c_client *client;
149 struct nct1008_platform_data plat_data;
152 enum nct1008_chip chip;
153 struct regulator *nct_reg;
158 struct nct1008_sensor_data sensors[SENSORS_COUNT];
161 static int conv_period_ms_table[] =
162 {16000, 8000, 4000, 2000, 1000, 500, 250, 125, 63, 32, 16};
164 static void nct1008_setup_shutdown_warning(struct nct1008_data *data);
166 static inline s16 value_to_temperature(bool extended, u8 value)
168 return extended ? (s16)(value - EXTENDED_RANGE_OFFSET) : (s16)value;
171 static inline u8 temperature_to_value(bool extended, s16 temp)
173 return extended ? (u8)(temp + EXTENDED_RANGE_OFFSET) : (u8)temp;
176 static int nct1008_write_reg(struct i2c_client *client, u8 reg, u16 value)
179 struct nct1008_data *data = i2c_get_clientdata(client);
181 mutex_lock(&data->mutex);
182 if (data && data->nct_disabled) {
183 mutex_unlock(&data->mutex);
187 ret = i2c_smbus_write_byte_data(client, reg, value);
188 mutex_unlock(&data->mutex);
191 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
196 static int nct1008_read_reg(struct i2c_client *client, u8 reg)
199 struct nct1008_data *data = i2c_get_clientdata(client);
200 mutex_lock(&data->mutex);
201 if (data && data->nct_disabled) {
202 mutex_unlock(&data->mutex);
206 ret = i2c_smbus_read_byte_data(client, reg);
207 mutex_unlock(&data->mutex);
210 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
215 static int nct1008_get_temp_common(int sensor,
216 struct nct1008_data *data,
219 struct i2c_client *client = data->client;
220 struct nct1008_platform_data *pdata = client->dev.platform_data;
221 struct nct1008_sensor_data *sensorp;
229 if (!((sensor == EXT) || (sensor == LOC)))
232 /* Read External Temp */
234 ret = nct1008_read_reg(client, NCT_REG(sensor, TEMP_RD_LO));
240 temp_lo = (value >> 6);
242 ret = nct1008_read_reg(client, EXT_TEMP_HI_RD);
248 temp_hi = value_to_temperature(pdata->extended_range, value);
249 temp_milli = CELSIUS_TO_MILLICELSIUS(temp_hi) + temp_lo * 250;
251 sensorp = &data->sensors[sensor];
252 for (i = 0; i < ARRAY_SIZE(sensorp->offset_table); i++) {
254 (sensorp->offset_table[i].temp * 1000)) {
255 off = sensorp->offset_table[i].offset * 1000;
262 } else if (sensor == LOC) {
263 value = nct1008_read_reg(client, LOC_TEMP_RD);
266 temp_hi = value_to_temperature(pdata->extended_range, value);
267 temp_milli = CELSIUS_TO_MILLICELSIUS(temp_hi);
270 if (temp_milli > NCT1008_MAX_TEMP_MILLI)
274 data->sensors[sensor].temp = temp_milli;
279 static ssize_t nct1008_show_temp(struct device *dev,
280 struct device_attribute *attr, char *buf)
282 struct i2c_client *client = to_i2c_client(dev);
283 struct nct1008_platform_data *pdata = client->dev.platform_data;
289 if (!dev || !buf || !attr)
292 value = nct1008_read_reg(client, LOC_TEMP_RD);
295 temp1 = value_to_temperature(pdata->extended_range, value);
297 value = nct1008_read_reg(client, EXT_TEMP_LO_RD);
300 temp2 = (value >> 6);
301 value = nct1008_read_reg(client, EXT_TEMP_HI_RD);
304 temp = value_to_temperature(pdata->extended_range, value);
306 return snprintf(buf, MAX_STR_PRINT, "%d %d.%d\n",
307 temp1, temp, temp2 * 25);
310 return snprintf(buf, MAX_STR_PRINT,
311 "Error read local/ext temperature\n");
314 static ssize_t nct1008_show_temp_overheat(struct device *dev,
315 struct device_attribute *attr,
318 struct i2c_client *client = to_i2c_client(dev);
319 struct nct1008_platform_data *pdata = client->dev.platform_data;
323 /* Local temperature h/w shutdown limit */
324 value = nct1008_read_reg(client, LOC_THERM_LIMIT);
327 temp = value_to_temperature(pdata->extended_range, value);
329 /* External temperature h/w shutdown limit */
330 value = nct1008_read_reg(client, EXT_THERM_LIMIT_WR);
333 temp2 = value_to_temperature(pdata->extended_range, value);
335 return snprintf(buf, MAX_STR_PRINT, "%d %d\n", temp, temp2);
337 dev_err(dev, "%s: failed to read temperature-overheat "
339 return snprintf(buf, MAX_STR_PRINT, " Rd overheat Error\n");
342 static ssize_t nct1008_set_temp_overheat(struct device *dev,
343 struct device_attribute *attr,
344 const char *buf, size_t count)
350 struct i2c_client *client = to_i2c_client(dev);
351 struct nct1008_data *data = i2c_get_clientdata(client);
352 char bufTemp[MAX_STR_PRINT];
353 char bufOverheat[MAX_STR_PRINT];
356 if (strict_strtol(buf, 0, &num)) {
357 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
361 if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
362 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
366 /* check for system power down */
367 err = nct1008_get_temp_common(EXT, data, &curr_temp);
371 curr_temp = MILLICELSIUS_TO_CELSIUS(curr_temp);
373 if (curr_temp >= (int)num) {
374 ret = nct1008_show_temp(dev, attr, bufTemp);
375 ret = nct1008_show_temp_overheat(dev, attr, bufOverheat);
376 dev_err(dev, "\nCurrent temp: %s ", bufTemp);
377 dev_err(dev, "\nOld overheat limit: %s ", bufOverheat);
378 dev_err(dev, "\nReset from overheat: curr temp=%ld, new overheat temp=%d\n\n",
379 curr_temp, (int)num);
382 /* External temperature h/w shutdown limit */
383 temp = temperature_to_value(data->plat_data.extended_range, (s16)num);
384 err = nct1008_write_reg(client, EXT_THERM_LIMIT_WR, temp);
388 /* Local temperature h/w shutdown limit */
389 temp = temperature_to_value(data->plat_data.extended_range, (s16)num);
390 err = nct1008_write_reg(client, LOC_THERM_LIMIT, temp);
394 data->plat_data.sensors[EXT].shutdown_limit = num;
395 nct1008_setup_shutdown_warning(data);
399 dev_err(dev, " %s: failed to set temperature-overheat\n", __func__);
403 static ssize_t nct1008_show_temp_alert(struct device *dev,
404 struct device_attribute *attr,
407 struct i2c_client *client = to_i2c_client(dev);
408 struct nct1008_platform_data *pdata = client->dev.platform_data;
410 s16 temp_hi, temp_lo;
411 /* External Temperature Throttling hi-limit */
412 value = nct1008_read_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
415 temp_hi = value_to_temperature(pdata->extended_range, value);
417 /* External Temperature Throttling lo-limit */
418 value = nct1008_read_reg(client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
421 temp_lo = value_to_temperature(pdata->extended_range, value);
423 return snprintf(buf, MAX_STR_PRINT, "lo:%d hi:%d\n", temp_lo, temp_hi);
425 dev_err(dev, "%s: failed to read temperature-alert\n", __func__);
426 return snprintf(buf, MAX_STR_PRINT, " Rd alert Error\n");
429 static ssize_t nct1008_set_temp_alert(struct device *dev,
430 struct device_attribute *attr,
431 const char *buf, size_t count)
436 struct i2c_client *client = to_i2c_client(dev);
437 struct nct1008_platform_data *pdata = client->dev.platform_data;
439 if (strict_strtol(buf, 0, &num)) {
440 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
444 if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
445 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
450 /* External Temperature Throttling limit */
451 value = temperature_to_value(pdata->extended_range, (s16)num);
452 err = nct1008_write_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR, value);
456 /* Local Temperature Throttling limit */
457 err = nct1008_write_reg(client, LOC_TEMP_HI_LIMIT_WR, value);
463 dev_err(dev, "%s: failed to set temperature-alert "
468 static ssize_t nct1008_show_sensor_temp(int sensor, struct device *dev,
469 struct device_attribute *attr, char *buf)
471 struct i2c_client *client = to_i2c_client(dev);
472 struct nct1008_platform_data *pdata = client->dev.platform_data;
477 if (!dev || !buf || !attr)
480 /* When reading the full external temperature value, read the
481 * LSB first. This causes the MSB to be locked (that is, the
482 * ADC does not write to it) until it is read */
483 data_lo = nct1008_read_reg(client, NCT_REG(sensor, TEMP_RD_LO));
485 dev_err(&client->dev, "%s: failed to read "
486 "ext_temperature, i2c error=%d\n", __func__, data_lo);
490 data = nct1008_read_reg(client, NCT_REG(sensor, TEMP_RD_HI));
492 dev_err(&client->dev, "%s: failed to read "
493 "ext_temperature, i2c error=%d\n", __func__, data);
497 temp_value = value_to_temperature(pdata->extended_range, data);
499 return snprintf(buf, MAX_STR_PRINT, "%d.%d\n", temp_value,
500 (25 * (data_lo >> 6)));
502 return snprintf(buf, MAX_STR_PRINT, "Error read ext temperature\n");
505 static ssize_t pr_reg(struct nct1008_data *nct, char *buf, int max_s,
506 const char *reg_name, int offset)
510 ret = nct1008_read_reg(nct->client, offset);
512 sz += snprintf(buf + sz, PAGE_SIZE - sz,
513 "%20s 0x%02x 0x%02x 0x%02x\n",
514 reg_name, nct->client->addr, offset, ret);
516 sz += snprintf(buf + sz, PAGE_SIZE - sz,
517 "%s: line=%d, i2c ** read error=%d **\n",
518 __func__, __LINE__, ret);
522 static ssize_t nct1008_show_regs(struct device *dev,
523 struct device_attribute *attr, char *buf)
525 struct i2c_client *client = to_i2c_client(dev);
526 struct nct1008_data *nct = i2c_get_clientdata(client);
527 char *name = nct->chip == NCT72 ? "nct72" : "nct1008";
530 sz += snprintf(buf + sz, PAGE_SIZE - sz,
531 "%s Registers\n", name);
532 sz += snprintf(buf + sz, PAGE_SIZE - sz,
533 "---------------------------------------\n");
534 sz += snprintf(buf + sz, PAGE_SIZE - sz, "%20s %4s %4s %s\n",
535 "Register Name ", "Addr", "Reg", "Value");
536 sz += snprintf(buf + sz, PAGE_SIZE - sz, "%20s %4s %4s %s\n",
537 "--------------------", "----", "----", "-----");
538 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
539 "Status ", STATUS_RD);
540 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
541 "Configuration ", CONFIG_RD);
542 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
543 "Conversion Rate ", CONV_RATE_RD);
544 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
545 "Hysteresis ", THERM_HYSTERESIS);
546 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
547 "Consecutive Alert ", COSECUTIVE_ALERT);
548 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
549 "Local Temp Value ", LOC_TEMP_RD);
550 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
551 "Local Temp Hi Limit ", LOC_TEMP_HI_LIMIT_RD);
552 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
553 "Local Temp Lo Limit ", LOC_TEMP_LO_LIMIT_RD);
554 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
555 "Local Therm Limit ", LOC_THERM_LIMIT);
556 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
557 "Ext Temp Value Hi ", EXT_TEMP_HI_RD);
558 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
559 "Ext Temp Value Lo ", EXT_TEMP_LO_RD);
560 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
561 "Ext Temp Hi Limit Hi", EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
562 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
563 "Ext Temp Hi Limit Lo", EXT_TEMP_HI_LIMIT_LO_BYTE);
564 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
565 "Ext Temp Lo Limit Hi", EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
566 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
567 "Ext Temp Lo Limit Lo", EXT_TEMP_LO_LIMIT_LO_BYTE);
568 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
569 "Ext Temp Offset Hi ", OFFSET_WR);
570 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
571 "Ext Temp Offset Lo ", OFFSET_QUARTER_WR);
572 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
573 "Ext Therm Limit ", EXT_THERM_LIMIT_WR);
578 static ssize_t nct1008_set_offsets(struct device *dev,
579 struct device_attribute *attr,
580 const char *buf, size_t count)
582 struct i2c_client *client = to_i2c_client(dev);
583 struct nct1008_data *nct = i2c_get_clientdata(client);
584 int index, temp, off;
588 sscanf(buf, "[%u] %u %d", &index, &temp, &off);
590 if (index >= ARRAY_SIZE(nct->sensors[EXT].offset_table)) {
591 pr_info("%s: invalid index [%d]\n", __func__, index);
594 nct->sensors[EXT].offset_table[index].temp = temp;
595 nct->sensors[EXT].offset_table[index].offset = off;
601 static ssize_t nct1008_show_offsets(struct device *dev,
602 struct device_attribute *attr, char *buf)
604 struct i2c_client *client = to_i2c_client(dev);
605 struct nct1008_data *nct = i2c_get_clientdata(client);
606 char *name = nct->chip == NCT72 ? "nct72" : "nct1008";
609 sz += snprintf(buf + sz, PAGE_SIZE - sz,
610 "%s offsets table\n", name);
611 sz += snprintf(buf + sz, PAGE_SIZE - sz,
612 "%2s %4s %s\n", " #", "temp", "offset");
613 sz += snprintf(buf + sz, PAGE_SIZE - sz,
614 "%2s %4s %s\n", "--", "----", "------");
616 for (i = 0; i < ARRAY_SIZE(nct->sensors[EXT].offset_table); i++)
617 sz += snprintf(buf + sz, PAGE_SIZE - sz,
619 i, nct->sensors[EXT].offset_table[i].temp,
620 nct->sensors[EXT].offset_table[i].offset);
625 /* This function is used by the system to show the temperature. */
626 static ssize_t nct1008_show_ext_temp(struct device *dev,
627 struct device_attribute *attr,
630 return nct1008_show_sensor_temp(EXT, dev, attr, buf);
633 static DEVICE_ATTR(temperature, S_IRUGO, nct1008_show_temp, NULL);
634 static DEVICE_ATTR(temperature_overheat, (S_IRUGO | (S_IWUSR | S_IWGRP)),
635 nct1008_show_temp_overheat, nct1008_set_temp_overheat);
636 static DEVICE_ATTR(temperature_alert, (S_IRUGO | (S_IWUSR | S_IWGRP)),
637 nct1008_show_temp_alert, nct1008_set_temp_alert);
638 static DEVICE_ATTR(ext_temperature, S_IRUGO, nct1008_show_ext_temp, NULL);
639 static DEVICE_ATTR(registers, S_IRUGO, nct1008_show_regs, NULL);
640 static DEVICE_ATTR(offsets, (S_IRUGO | (S_IWUSR | S_IWGRP)),
641 nct1008_show_offsets, nct1008_set_offsets);
643 static struct attribute *nct1008_attributes[] = {
644 &dev_attr_temperature.attr,
645 &dev_attr_temperature_overheat.attr,
646 &dev_attr_temperature_alert.attr,
647 &dev_attr_ext_temperature.attr,
648 &dev_attr_registers.attr,
649 &dev_attr_offsets.attr,
653 static const struct attribute_group nct1008_attr_group = {
654 .attrs = nct1008_attributes,
657 static const unsigned long THERM_WARN_RANGE_HIGH_OFFSET = 3000;
658 static unsigned long nct1008_shutdown_warning_cur_state;
659 static long shutdown_warn_saved_temp;
661 static int nct1008_shutdown_warning_get_max_state(
662 struct thermal_cooling_device *cdev,
663 unsigned long *max_state)
665 /* A state for every 250mC */
666 *max_state = THERM_WARN_RANGE_HIGH_OFFSET / 250;
670 static int nct1008_shutdown_warning_get_cur_state(
671 struct thermal_cooling_device *cdev,
672 unsigned long *cur_state)
674 struct nct1008_data *data = cdev->devdata;
675 long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
678 if (nct1008_get_temp_common(EXT, data, &temp))
681 if (temp >= (limit - THERM_WARN_RANGE_HIGH_OFFSET))
682 *cur_state = nct1008_shutdown_warning_cur_state;
689 static int nct1008_shutdown_warning_set_cur_state(
690 struct thermal_cooling_device *cdev,
691 unsigned long cur_state)
693 struct nct1008_data *data = cdev->devdata;
694 long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
697 if (nct1008_get_temp_common(EXT, data, &temp))
702 if ((temp >= (limit - THERM_WARN_RANGE_HIGH_OFFSET)) &&
703 (temp != shutdown_warn_saved_temp)) {
704 pr_warn("NCT%s: Warning: chip temperature (%ld.%02ldC) is %s SHUTDOWN limit (%c%ldC).\n",
705 (data->chip == NCT72) ? "72" : "1008",
706 temp / 1000, (temp % 1000) / 10,
707 temp > limit ? "above" :
708 temp == limit ? "at" : "near",
709 temp > limit ? '>' : '<', limit / 1000);
710 shutdown_warn_saved_temp = temp;
714 nct1008_shutdown_warning_cur_state = cur_state;
718 static struct thermal_cooling_device_ops nct1008_shutdown_warning_ops = {
719 .get_max_state = nct1008_shutdown_warning_get_max_state,
720 .get_cur_state = nct1008_shutdown_warning_get_cur_state,
721 .set_cur_state = nct1008_shutdown_warning_set_cur_state,
724 static int nct1008_thermal_set_limits(int sensor,
725 struct nct1008_data *data,
731 bool extended_range = data->plat_data.extended_range;
732 long lo_limit = MILLICELSIUS_TO_CELSIUS(lo_limit_milli);
733 long hi_limit = MILLICELSIUS_TO_CELSIUS(hi_limit_milli);
735 if (lo_limit >= hi_limit)
738 if (data->sensors[sensor].current_lo_limit != lo_limit) {
739 value = temperature_to_value(extended_range, lo_limit);
740 pr_debug("%s: set lo_limit %ld\n", __func__, lo_limit);
741 err = nct1008_write_reg(data->client,
742 NCT_REG(sensor, TEMP_LO_LIMIT_WR), value);
746 data->sensors[sensor].current_lo_limit = lo_limit;
749 if (data->sensors[sensor].current_hi_limit != hi_limit) {
750 value = temperature_to_value(extended_range, hi_limit);
751 pr_debug("%s: set hi_limit %ld\n", __func__, hi_limit);
752 err = nct1008_write_reg(data->client,
753 NCT_REG(sensor, TEMP_HI_LIMIT_WR), value);
757 data->sensors[sensor].current_hi_limit = hi_limit;
761 pr_debug("NCT1008: LOC-sensor limits set to %ld - %ld\n",
767 #ifdef CONFIG_THERMAL
768 static void nct1008_update(int sensor, struct nct1008_data *data)
770 struct thermal_zone_device *thz;
771 long low_temp, high_temp;
772 struct thermal_trip_info *trip_state;
773 long temp, trip_temp, hysteresis_temp;
775 enum thermal_trip_type trip_type;
776 low_temp = 0, high_temp = NCT1008_MAX_TEMP * 1000;
777 thz = data->sensors[sensor].thz;
782 thermal_zone_device_update(thz);
784 temp = thz->temperature;
786 for (count = 0; count < thz->trips; count++) {
787 trip_state = &data->plat_data.sensors[sensor].trips[count];
788 thz->ops->get_trip_temp(thz, count, &trip_temp);
789 thz->ops->get_trip_type(thz, count, &trip_type);
790 thz->ops->get_trip_hyst(thz, count, &hysteresis_temp);
791 hysteresis_temp = trip_temp - hysteresis_temp;
792 if ((trip_type == THERMAL_TRIP_PASSIVE) &&
793 !trip_state->tripped)
794 hysteresis_temp = trip_temp;
796 if ((trip_temp > temp) && (trip_temp < high_temp))
797 high_temp = trip_temp;
799 if ((hysteresis_temp < temp) && (hysteresis_temp > low_temp))
800 low_temp = hysteresis_temp;
803 nct1008_thermal_set_limits(sensor, data, low_temp, high_temp);
806 static int nct1008_ext_get_temp(struct thermal_zone_device *thz, long *temp)
808 struct nct1008_data *data = thz->devdata;
810 return nct1008_get_temp_common(EXT, data, temp);
813 static int nct1008_ext_get_temp_as_sensor(void *data, long *temp)
815 return nct1008_get_temp_common(EXT, (struct nct1008_data *) data, temp);
818 static int nct1008_ext_bind(struct thermal_zone_device *thz,
819 struct thermal_cooling_device *cdev)
821 struct nct1008_data *data = thz->devdata;
823 struct nct1008_sensor_platform_data *sensor;
825 sensor = &data->plat_data.sensors[EXT];
827 for (i = 0; i < sensor->num_trips; i++) {
828 if (!strcmp(sensor->trips[i].cdev_type, cdev->type))
829 thermal_zone_bind_cooling_device(thz, i, cdev,
830 sensor->trips[i].upper,
831 sensor->trips[i].lower);
838 static int nct1008_unbind(int sensor,
839 struct thermal_zone_device *thz,
840 struct thermal_cooling_device *cdev)
842 struct nct1008_data *data = thz->devdata;
845 struct nct1008_sensor_platform_data *sensor_data;
847 sensor_data = &data->plat_data.sensors[sensor];
849 for (i = 0; i < sensor_data->num_trips; i++) {
850 if (!strcmp(sensor_data->trips[i].cdev_type, cdev->type))
851 thermal_zone_unbind_cooling_device(thz, i, cdev);
856 /* Helper function that is called in order to unbind external sensor from the
858 static inline int nct1008_ext_unbind(struct thermal_zone_device *thz,
859 struct thermal_cooling_device *cdev)
861 return nct1008_unbind(EXT, thz, cdev);
864 /* Helper function that is called in order to unbind local sensor from the
866 static inline int nct1008_loc_unbind(struct thermal_zone_device *thz,
867 struct thermal_cooling_device *cdev)
869 return nct1008_unbind(LOC, thz, cdev);
872 /* This function reads the temperature value set for the given trip point. */
873 static int nct1008_get_trip_temp(int sensor,
874 struct thermal_zone_device *thz,
875 int trip, long *temp)
877 struct nct1008_data *data = thz->devdata;
878 struct thermal_trip_info *trip_state =
879 &data->plat_data.sensors[sensor].trips[trip];
881 *temp = trip_state->trip_temp;
883 if (trip_state->trip_type != THERMAL_TRIP_PASSIVE)
886 if (thz->temperature >= *temp) {
887 trip_state->tripped = true;
888 } else if (trip_state->tripped) {
889 *temp -= trip_state->hysteresis;
890 if (thz->temperature < *temp)
891 trip_state->tripped = false;
897 /* This function reads the temperature value set for the given trip point for
899 static inline int nct1008_loc_get_trip_temp(struct thermal_zone_device *thz,
900 int trip, long *temp)
902 return nct1008_get_trip_temp(LOC, thz, trip, temp);
905 /* This function reads the temperature value set for the given trip point for
906 the remote sensor. */
907 static inline int nct1008_ext_get_trip_temp(struct thermal_zone_device *thz,
908 int trip, long *temp)
910 return nct1008_get_trip_temp(EXT, thz, trip, temp);
913 /* This function allows setting trip point temperature for the sensor
915 static int nct1008_set_trip_temp(int sensor,
916 struct thermal_zone_device *thz,
919 struct nct1008_data *data = thz->devdata;
921 data->plat_data.sensors[sensor].trips[trip].trip_temp = temp;
922 nct1008_update(sensor, data);
926 /* This function allows setting trip point temperature for the local sensor. */
927 static inline int nct1008_loc_set_trip_temp(struct thermal_zone_device *thz,
930 return nct1008_set_trip_temp(LOC, thz, trip, temp);
933 /* This function allows setting trip point temperature for the external
935 static inline int nct1008_ext_set_trip_temp(struct thermal_zone_device *thz,
938 return nct1008_set_trip_temp(EXT, thz, trip, temp);
941 static int nct1008_loc_trip_update(void *of_data, int trip)
943 struct nct1008_data *data = (struct nct1008_data *)of_data;
945 nct1008_update(LOC, data);
950 static int nct1008_ext_trip_update(void *of_data, int trip)
952 struct nct1008_data *data = (struct nct1008_data *)of_data;
954 nct1008_update(EXT, data);
959 /* This function return the trip point type for the sensor specified. */
960 static int nct1008_get_trip_type(int sensor,
961 struct thermal_zone_device *thz,
963 enum thermal_trip_type *type)
965 struct nct1008_data *data = thz->devdata;
967 *type = data->plat_data.sensors[sensor].trips[trip].trip_type;
971 /* This function return the trip point type for the local sensor. */
972 static inline int nct1008_loc_get_trip_type(struct thermal_zone_device *thz,
974 enum thermal_trip_type *type)
976 return nct1008_get_trip_type(LOC, thz, trip, type);
979 /* This function return the trip point type for the external sensor. */
980 static inline int nct1008_ext_get_trip_type(struct thermal_zone_device *thz,
982 enum thermal_trip_type *type)
984 return nct1008_get_trip_type(EXT, thz, trip, type);
987 static int nct1008_get_trip_hyst(int sensor, struct thermal_zone_device *thz,
991 struct nct1008_data *data = thz->devdata;
993 *hyst = data->plat_data.sensors[sensor].trips[trip].hysteresis;
997 static inline int nct1008_loc_get_trip_hyst(struct thermal_zone_device *thz,
1001 return nct1008_get_trip_hyst(LOC, thz, trip, hyst);
1004 static inline int nct1008_ext_get_trip_hyst(struct thermal_zone_device *thz,
1008 return nct1008_get_trip_hyst(EXT, thz, trip, hyst);
1011 /* This function returns value of trend for the temperature change, depending
1012 on the trip point type. */
1013 static int nct1008_get_trend(struct thermal_zone_device *thz,
1015 enum thermal_trend *trend)
1017 long trip_temp, trip_hyst;
1018 enum thermal_trip_type trip_type;
1020 thz->ops->get_trip_temp(thz, trip, &trip_temp);
1021 thz->ops->get_trip_type(thz, trip, &trip_type);
1022 thz->ops->get_trip_hyst(thz, trip, &trip_hyst);
1024 switch (trip_type) {
1025 case THERMAL_TRIP_ACTIVE:
1026 if (thz->temperature >= trip_temp)
1027 *trend = THERMAL_TREND_RAISING;
1029 *trend = THERMAL_TREND_DROPPING;
1031 case THERMAL_TRIP_PASSIVE:
1032 if (thz->temperature > thz->last_temperature)
1033 *trend = THERMAL_TREND_RAISING;
1034 else if (thz->temperature < (thz->last_temperature - trip_hyst))
1035 *trend = THERMAL_TREND_DROPPING;
1037 *trend = THERMAL_TREND_STABLE;
1046 static int nct1008_get_trend_as_sensor(int sensor,
1047 struct nct1008_data *data,
1050 struct thermal_zone_device *thz = data->sensors[sensor].thz;
1052 return thz->temperature - thz->last_temperature;
1055 /* Helper function to get trend for the local sensor. */
1056 static inline int nct1008_loc_get_trend_as_sensor(void *data,
1059 return nct1008_get_trend_as_sensor(LOC,
1060 (struct nct1008_data *) data, trend);
1063 static inline int nct1008_ext_get_trend_as_sensor(void *data,
1066 return nct1008_get_trend_as_sensor
1067 (EXT, (struct nct1008_data *) data, trend);
1071 /* Helper function to get temperature of the local sensor. */
1072 static int nct1008_loc_get_temp(struct thermal_zone_device *thz, long *temp)
1074 struct nct1008_data *data = thz->devdata;
1076 return nct1008_get_temp_common(LOC, data, temp);
1079 static int nct1008_loc_get_temp_as_sensor(void *data, long *temp)
1081 return nct1008_get_temp_common(LOC, (struct nct1008_data *) data, temp);
1083 /* Helper function to bind local sensor with the cooling device specified. */
1084 static int nct1008_loc_bind(struct thermal_zone_device *thz,
1085 struct thermal_cooling_device *cdev)
1087 struct nct1008_data *data = thz->devdata;
1089 struct nct1008_sensor_platform_data *sensor_data;
1091 pr_debug("NCT1008: LOC-sensor bind %s, %s attempt\n",
1092 thz->type, cdev->type);
1094 sensor_data = &data->plat_data.sensors[LOC];
1096 for (i = 0; i < sensor_data->num_trips; i++) {
1097 if (!strcmp(sensor_data->trips[i].cdev_type, cdev->type)) {
1098 thermal_zone_bind_cooling_device(thz, i, cdev,
1099 sensor_data->trips[i].upper,
1100 sensor_data->trips[i].lower);
1108 static struct thermal_zone_device_ops nct_loc_ops = {
1109 .get_temp = nct1008_loc_get_temp,
1110 .bind = nct1008_loc_bind,
1111 .unbind = nct1008_loc_unbind,
1112 .get_trip_type = nct1008_loc_get_trip_type,
1113 .get_trip_temp = nct1008_loc_get_trip_temp,
1114 .get_trip_hyst = nct1008_loc_get_trip_hyst,
1115 .set_trip_temp = nct1008_loc_set_trip_temp,
1116 .get_trend = nct1008_get_trend,
1119 static struct thermal_zone_device_ops nct_ext_ops = {
1120 .get_temp = nct1008_ext_get_temp,
1121 .bind = nct1008_ext_bind,
1122 .unbind = nct1008_ext_unbind,
1123 .get_trip_type = nct1008_ext_get_trip_type,
1124 .get_trip_temp = nct1008_ext_get_trip_temp,
1125 .get_trip_hyst = nct1008_ext_get_trip_hyst,
1126 .set_trip_temp = nct1008_ext_set_trip_temp,
1127 .get_trend = nct1008_get_trend,
1130 static void nct1008_update(nct1008_sensors sensor, struct nct1008_data *data)
1133 #endif /* CONFIG_THERMAL */
1135 static int nct1008_enable(struct i2c_client *client)
1137 struct nct1008_data *data = i2c_get_clientdata(client);
1140 err = nct1008_write_reg(client, CONFIG_WR, data->config);
1142 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
1143 __func__, __LINE__, err);
1147 static int nct1008_disable(struct i2c_client *client)
1149 struct nct1008_data *data = i2c_get_clientdata(client);
1152 err = nct1008_write_reg(client, CONFIG_WR,
1153 data->config | STANDBY_BIT);
1155 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
1156 __func__, __LINE__, err);
1160 static void nct1008_work_func(struct work_struct *work)
1162 struct nct1008_data *data = container_of(work, struct nct1008_data,
1168 mutex_lock(&data->mutex);
1169 if (data->stop_workqueue) {
1170 mutex_unlock(&data->mutex);
1173 mutex_unlock(&data->mutex);
1175 err = nct1008_disable(data->client);
1179 intr_status = nct1008_read_reg(data->client, STATUS_RD);
1180 pr_debug("NCT1008: interruption (0x%08x)\n", intr_status);
1182 if (intr_status & (LOC_LO_BIT | LOC_HI_BIT)) {
1183 pr_debug("NCT1008: LOC-sensor is not within limits\n");
1184 nct1008_update(LOC, data);
1187 if (intr_status & (EXT_LO_BIT | EXT_HI_BIT))
1188 nct1008_update(EXT, data);
1190 /* Initiate one-shot conversion */
1191 nct1008_write_reg(data->client, ONE_SHOT, 0x1);
1193 /* Give hardware necessary time to finish conversion */
1194 ts = ns_to_timespec(MAX_CONV_TIME_ONESHOT_MS * 1000 * 1000);
1195 hrtimer_nanosleep(&ts, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
1197 nct1008_read_reg(data->client, STATUS_RD);
1199 nct1008_enable(data->client);
1201 enable_irq(data->client->irq);
1204 static irqreturn_t nct1008_irq(int irq, void *dev_id)
1206 struct nct1008_data *data = dev_id;
1208 disable_irq_nosync(irq);
1209 queue_work(data->workqueue, &data->work);
1214 static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
1218 mutex_lock(&data->mutex);
1219 if (!data->nct_reg) {
1220 data->nct_reg = regulator_get(&data->client->dev, "vdd");
1221 if (IS_ERR_OR_NULL(data->nct_reg)) {
1222 if (PTR_ERR(data->nct_reg) == -ENODEV)
1223 dev_info(&data->client->dev,
1224 "no regulator found for vdd."
1225 " Assuming vdd is always powered");
1227 dev_warn(&data->client->dev, "Error [%ld] in "
1228 "getting the regulator handle for"
1229 " vdd\n", PTR_ERR(data->nct_reg));
1230 data->nct_reg = NULL;
1231 mutex_unlock(&data->mutex);
1236 ret = regulator_enable(data->nct_reg);
1238 ret = regulator_disable(data->nct_reg);
1241 dev_err(&data->client->dev, "Error in %s rail vdd_nct%s, "
1242 "error %d\n", (is_enable) ? "enabling" : "disabling",
1243 (data->chip == NCT72) ? "72" : "1008",
1246 dev_info(&data->client->dev, "success in %s rail vdd_nct%s\n",
1247 (is_enable) ? "enabling" : "disabling",
1248 (data->chip == NCT72) ? "72" : "1008");
1249 data->nct_disabled = !is_enable;
1250 mutex_unlock(&data->mutex);
1253 static void nct1008_setup_shutdown_warning(struct nct1008_data *data)
1255 static struct thermal_cooling_device *cdev;
1256 long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
1257 long warn_temp = limit - THERM_WARN_RANGE_HIGH_OFFSET;
1259 struct nct1008_sensor_platform_data *sensor_data;
1262 thermal_cooling_device_unregister(cdev);
1263 cdev = thermal_cooling_device_register("shutdown_warning", data,
1264 &nct1008_shutdown_warning_ops);
1265 if (IS_ERR_OR_NULL(cdev)) {
1270 sensor_data = &data->plat_data.sensors[EXT];
1272 for (i = 0; i < sensor_data->num_trips; i++) {
1273 if (!strcmp(sensor_data->trips[i].cdev_type,
1274 "shutdown_warning")) {
1275 sensor_data->trips[i].trip_temp = warn_temp;
1276 nct1008_update(EXT, data);
1281 pr_info("NCT%s: Enabled overheat logging at %ld.%02ldC\n",
1282 (data->chip == NCT72) ? "72" : "1008",
1283 warn_temp / 1000, (warn_temp % 1000) / 10);
1286 static int nct1008_configure_sensor(struct nct1008_data *data)
1288 struct i2c_client *client = data->client;
1289 struct nct1008_platform_data *pdata = client->dev.platform_data;
1294 bool ext_err = false;
1296 if (!pdata || !pdata->supported_hwrev)
1299 ret = nct1008_read_reg(data->client, STATUS_RD);
1301 pr_info("NCT%s: ERR: remote sensor circuit is open (0x%02x)\n",
1302 (data->chip == NCT72) ? "72" : "1008", ret);
1303 ext_err = true; /* flag the error */
1306 /* Initially place in Standby */
1307 ret = nct1008_write_reg(client, CONFIG_WR, STANDBY_BIT);
1311 /* Local temperature h/w shutdown limit */
1312 value = temperature_to_value(pdata->extended_range,
1313 pdata->sensors[LOC].shutdown_limit);
1314 ret = nct1008_write_reg(client, LOC_THERM_LIMIT, value);
1318 /* set extended range mode if needed */
1319 if (pdata->extended_range)
1320 data->config |= EXTENDED_RANGE_BIT;
1321 data->config &= ~(THERM2_BIT | ALERT_BIT);
1323 ret = nct1008_write_reg(client, CONFIG_WR, data->config | STANDBY_BIT);
1327 /* Temperature conversion rate */
1328 ret = nct1008_write_reg(client, CONV_RATE_WR, pdata->conv_rate);
1332 data->conv_period_ms = conv_period_ms_table[pdata->conv_rate];
1334 /* Setup local hi and lo limits. */
1335 ret = nct1008_write_reg(client, LOC_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
1339 ret = nct1008_write_reg(client, LOC_TEMP_LO_LIMIT_WR, 0);
1343 /* Initiate one-shot conversion */
1344 nct1008_write_reg(data->client, ONE_SHOT, 0x1);
1346 /* Give hardware necessary time to finish conversion */
1347 msleep(MAX_CONV_TIME_ONESHOT_MS);
1349 /* read initial temperature */
1350 ret = nct1008_read_reg(client, LOC_TEMP_RD);
1356 temp = value_to_temperature(pdata->extended_range, value);
1357 dev_dbg(&client->dev, "\n initial local temp = %d ", temp);
1360 return ext_err; /* skip configuration of EXT sensor */
1362 /* External temperature h/w shutdown limit. */
1363 value = temperature_to_value(pdata->extended_range,
1364 pdata->sensors[EXT].shutdown_limit);
1365 ret = nct1008_write_reg(client, EXT_THERM_LIMIT_WR, value);
1369 /* Setup external hi and lo limits */
1370 ret = nct1008_write_reg(client, EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
1373 ret = nct1008_write_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
1378 ret = nct1008_read_reg(client, EXT_TEMP_LO_RD);
1384 temp2 = (value >> 6);
1385 ret = nct1008_read_reg(client, EXT_TEMP_HI_RD);
1391 temp = value_to_temperature(pdata->extended_range, value);
1394 dev_dbg(&client->dev, "\n initial ext temp = %d.%d deg",
1397 dev_dbg(&client->dev, "\n initial ext temp = %d.0 deg", temp);
1399 /* Remote channel offset */
1400 ret = nct1008_write_reg(client, OFFSET_WR, pdata->offset / 4);
1404 /* Remote channel offset fraction (quarters) */
1405 ret = nct1008_write_reg(client, OFFSET_QUARTER_WR,
1406 (pdata->offset % 4) << 6);
1410 /* Reset current hi/lo limit values with register values */
1411 ret = nct1008_read_reg(data->client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
1416 data->sensors[EXT].current_lo_limit =
1417 value_to_temperature(pdata->extended_range, value);
1419 ret = nct1008_read_reg(data->client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
1425 data->sensors[EXT].current_hi_limit =
1426 value_to_temperature(pdata->extended_range, value);
1428 ret = nct1008_read_reg(data->client, LOC_TEMP_LO_LIMIT_RD);
1434 data->sensors[LOC].current_lo_limit =
1435 value_to_temperature(pdata->extended_range, value);
1437 value = nct1008_read_reg(data->client, LOC_TEMP_HI_LIMIT_RD);
1443 data->sensors[LOC].current_hi_limit =
1444 value_to_temperature(pdata->extended_range, value);
1446 nct1008_setup_shutdown_warning(data);
1450 dev_err(&client->dev, "\n exit %s, err=%d ", __func__, ret);
1454 static int nct1008_configure_irq(struct nct1008_data *data)
1456 data->workqueue = create_singlethread_workqueue((data->chip == NCT72) \
1457 ? "nct72" : "nct1008");
1459 INIT_WORK(&data->work, nct1008_work_func);
1461 if (data->client->irq < 0)
1464 return request_irq(data->client->irq, nct1008_irq,
1466 (data->chip == NCT72) ? "nct72" : "nct1008",
1470 static struct nct1008_platform_data *nct1008_dt_parse(struct i2c_client *client)
1472 struct device_node *np = client->dev.of_node;
1473 struct device_node *child_sensor;
1474 struct nct1008_platform_data *pdata;
1476 unsigned int proc, index = 0;
1478 dev_err(&client->dev,
1479 "Cannot found the DT node\n");
1483 dev_info(&client->dev, "starting parse dt\n");
1484 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1486 dev_err(&client->dev,
1487 "Parse DT fails at malloc pdata\n");
1491 pdata->loc_name = of_get_property(np, "sensor-name", NULL);
1492 if (pdata->loc_name == NULL) {
1493 dev_err(&client->dev,
1494 "Cannot found the name\n");
1498 if (client->irq == 0)
1501 if (of_property_read_u32(np, "conv-rate", &proc))
1503 pdata->conv_rate = proc;
1505 if (of_property_read_u32(np, "supported-hwrev", &proc))
1507 pdata->supported_hwrev = (bool) proc;
1509 if (of_property_read_u32(np, "extended-rage", &proc))
1511 pdata->extended_range = (bool) proc;
1513 if (of_property_read_u32(np, "offset", &proc))
1515 pdata->offset = proc;
1517 if (of_property_read_bool(np, "temp-alert-gpio")) {
1518 nct72_gpio = of_get_named_gpio(
1519 np, "temp-alert-gpio", 0);
1520 if (gpio_request(nct72_gpio, "temp_alert") < 0)
1521 dev_err(&client->dev,
1522 "%s gpio request error\n", __FILE__);
1523 if (gpio_direction_input(nct72_gpio) < 0) {
1524 dev_err(&client->dev,
1525 "%s gpio direction_input fail\n", __FILE__);
1526 gpio_free(nct72_gpio);
1530 for_each_child_of_node(np, child_sensor) {
1531 if (of_property_read_u32(child_sensor, "shutdown-limit", &proc))
1533 pdata->sensors[index].shutdown_limit = proc;
1536 of_property_read_u32(child_sensor, "suspend_limit_hi", &proc);
1537 pdata->sensors[index].suspend_limit_hi = proc;
1538 of_property_read_u32(child_sensor, "suspend_limit_lo", &proc);
1539 pdata->sensors[index].suspend_limit_lo = proc;
1543 dev_info(&client->dev, "success parsing dt\n");
1544 client->dev.platform_data = pdata;
1548 dev_err(&client->dev, "Parsing device tree data error.\n");
1553 * Manufacturer(OnSemi) recommended sequence for
1554 * Extended Range mode is as follows
1555 * 1. Place in Standby
1556 * 2. Scale the THERM and ALERT limits
1557 * appropriately(for Extended Range mode).
1558 * 3. Enable Extended Range mode.
1559 * ALERT mask/THERM2 mode may be done here
1560 * as these are not critical
1561 * 4. Set Conversion Rate as required
1562 * 5. Take device out of Standby
1566 * function nct1008_probe takes care of initial configuration
1568 static int nct1008_probe(struct i2c_client *client,
1569 const struct i2c_device_id *id)
1571 struct nct1008_data *data;
1572 struct nct1008_platform_data *pdata;
1573 struct thermal_zone_device *zone_device;
1577 char nct_loc_name[THERMAL_NAME_LENGTH];
1578 char nct_ext_name[THERMAL_NAME_LENGTH];
1580 struct nct1008_sensor_platform_data *sensor_data;
1581 struct thermal_of_sensor_ops loc_sops = {
1582 .get_temp = nct1008_loc_get_temp_as_sensor,
1583 .get_trend = nct1008_loc_get_trend_as_sensor,
1584 .trip_update = nct1008_loc_trip_update,
1587 struct thermal_of_sensor_ops ext_sops = {
1588 .get_temp = nct1008_ext_get_temp_as_sensor,
1589 .get_trend = nct1008_ext_get_trend_as_sensor,
1590 .trip_update = nct1008_ext_trip_update,
1593 if (client->dev.of_node) {
1594 dev_info(&client->dev, "find device tree node, parsing dt\n");
1595 pdata = nct1008_dt_parse(client);
1596 if (IS_ERR(pdata)) {
1597 err = PTR_ERR(pdata);
1598 dev_err(&client->dev,
1599 "Parsing of node failed, %d\n", err);
1604 data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
1608 data->client = client;
1609 data->chip = id->driver_data;
1610 memcpy(&data->plat_data, client->dev.platform_data,
1611 sizeof(struct nct1008_platform_data));
1613 i2c_set_clientdata(client, data);
1614 mutex_init(&data->mutex);
1616 nct1008_power_control(data, true);
1617 if (!data->nct_reg) {
1618 /* power up failure */
1622 /* extended range recommended steps 1 through 4 taken care
1623 * in nct1008_configure_sensor function */
1624 err = nct1008_configure_sensor(data); /* sensor is in standby */
1627 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
1628 __FILE__, __func__, __LINE__);
1632 err = nct1008_configure_irq(data);
1634 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
1635 __FILE__, __func__, __LINE__);
1638 dev_info(&client->dev, "%s: initialized\n", __func__);
1640 /* extended range recommended step 5 is in nct1008_enable function */
1641 err = nct1008_enable(client); /* sensor is running */
1643 dev_err(&client->dev, "Error: %s, line=%d, error=%d\n",
1644 __func__, __LINE__, err);
1648 /* register sysfs hooks */
1649 err = sysfs_create_group(&client->dev.kobj, &nct1008_attr_group);
1651 dev_err(&client->dev, "\n sysfs create err=%d ", err);
1655 #ifdef CONFIG_THERMAL
1656 if (data->plat_data.loc_name) {
1657 strcpy(nct_loc_name, "Tboard_");
1658 strcpy(nct_ext_name, "Tdiode_");
1659 strncat(nct_loc_name, data->plat_data.loc_name,
1660 (THERMAL_NAME_LENGTH - strlen("Tboard_")) - 1);
1661 strncat(nct_ext_name, data->plat_data.loc_name,
1662 (THERMAL_NAME_LENGTH - strlen("Tdiode_")) - 1);
1664 strcpy(nct_loc_name, "Tboard");
1665 strcpy(nct_ext_name, "Tdiode");
1668 if (client->dev.of_node) {
1669 /* Config for the Local sensor. */
1671 thermal_zone_of_sensor_register2(&client->dev, LOC,
1674 if (!IS_ERR_OR_NULL(zone_device))
1675 data->sensors[LOC].thz = zone_device;
1677 /* register External sensor if connection is good */
1679 thermal_zone_of_sensor_register2(&client->dev, EXT,
1681 if (!IS_ERR_OR_NULL(zone_device))
1682 data->sensors[EXT].thz = zone_device;
1684 sensor_data = &data->plat_data.sensors[LOC];
1686 /* Config for the Local sensor. */
1688 for (i = 0; i < sensor_data->num_trips; i++)
1689 if (data->plat_data.sensors[LOC].trips[i].mask)
1692 data->sensors[LOC].thz =
1693 thermal_zone_device_register(nct_loc_name,
1694 sensor_data->num_trips,
1702 /* Config for the External sensor. */
1704 for (i = 0; i < data->plat_data.sensors[EXT].num_trips; i++)
1705 if (data->plat_data.sensors[EXT].trips[i].mask > 0)
1708 /* register External sensor if connection is good */
1709 data->sensors[EXT].thz = ext_err ? NULL :
1710 thermal_zone_device_register(nct_ext_name,
1711 data->plat_data.sensors[EXT].num_trips,
1715 data->plat_data.sensors[EXT].tzp,
1716 data->plat_data.sensors[EXT].passive_delay,
1717 data->plat_data.sensors[EXT].polling_delay);
1720 if (!IS_ERR_OR_NULL(data->sensors[LOC].thz)) {
1721 nct1008_update(LOC, data);
1724 if (!IS_ERR_OR_NULL(data->sensors[EXT].thz)) {
1725 nct1008_update(EXT, data);
1726 shutdown_warn_saved_temp = data->sensors[EXT].thz->temperature;
1733 dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
1734 nct1008_power_control(data, false);
1736 mutex_destroy(&data->mutex);
1738 regulator_put(data->nct_reg);
1743 static int nct1008_remove(struct i2c_client *client)
1745 struct nct1008_data *data = i2c_get_clientdata(client);
1747 mutex_lock(&data->mutex);
1748 data->stop_workqueue = 1;
1749 mutex_unlock(&data->mutex);
1751 cancel_work_sync(&data->work);
1752 free_irq(data->client->irq, data);
1753 sysfs_remove_group(&client->dev.kobj, &nct1008_attr_group);
1754 nct1008_power_control(data, false);
1757 regulator_put(data->nct_reg);
1759 mutex_destroy(&data->mutex);
1765 static void nct1008_shutdown(struct i2c_client *client)
1767 struct nct1008_data *data = i2c_get_clientdata(client);
1769 mutex_lock(&data->mutex);
1770 data->stop_workqueue = 1;
1771 mutex_unlock(&data->mutex);
1773 if (data->sensors[LOC].thz) {
1774 if (client->dev.of_node)
1775 thermal_zone_of_sensor_unregister
1776 (&(client->dev), data->sensors[LOC].thz);
1778 thermal_zone_device_unregister(data->sensors[LOC].thz);
1779 data->sensors[LOC].thz = NULL;
1781 if (data->sensors[EXT].thz) {
1782 if (client->dev.of_node)
1783 thermal_zone_of_sensor_unregister
1784 (&(client->dev), data->sensors[EXT].thz);
1786 thermal_zone_device_unregister(data->sensors[EXT].thz);
1787 data->sensors[EXT].thz = NULL;
1790 cancel_work_sync(&data->work);
1793 disable_irq(client->irq);
1795 mutex_lock(&data->mutex);
1796 data->nct_disabled = 1;
1797 mutex_unlock(&data->mutex);
1800 #ifdef CONFIG_PM_SLEEP
1801 static int nct1008_suspend_powerdown(struct device *dev)
1803 struct i2c_client *client = to_i2c_client(dev);
1805 struct nct1008_data *data = i2c_get_clientdata(client);
1807 mutex_lock(&data->mutex);
1808 data->stop_workqueue = 1;
1809 mutex_unlock(&data->mutex);
1810 cancel_work_sync(&data->work);
1811 disable_irq(client->irq);
1812 err = nct1008_disable(client);
1813 nct1008_power_control(data, false);
1817 static int nct1008_suspend_wakeup(struct device *dev)
1819 struct i2c_client *client = to_i2c_client(dev);
1821 struct nct1008_data *data = i2c_get_clientdata(client);
1824 struct nct1008_sensor_platform_data *sensor_data;
1826 for (sensor_nr = 0; sensor_nr < SENSORS_COUNT; sensor_nr++) {
1827 sensor_data = &data->plat_data.sensors[sensor_nr];
1829 err = nct1008_get_temp_common(sensor_nr, data, &temp);
1834 if (temp > sensor_data->suspend_limit_lo)
1835 err = nct1008_thermal_set_limits(sensor_nr, data,
1836 sensor_data->suspend_limit_lo,
1837 NCT1008_MAX_TEMP * 1000);
1839 err = nct1008_thermal_set_limits(sensor_nr, data,
1840 NCT1008_MIN_TEMP * 1000,
1841 sensor_data->suspend_limit_hi);
1847 /* Enable NCT wake. */
1848 err = enable_irq_wake(client->irq);
1850 dev_err(&client->dev, "Error: %s, error=%d. failed to enable NCT wakeup\n",
1855 dev_err(&client->dev, "\n error in file=: %s %s() line=%d: "
1856 "error=%d. Can't set correct LP1 alarm limits or set wakeup irq, "
1857 "shutting down device", __FILE__, __func__, __LINE__, err);
1859 return nct1008_suspend_powerdown(dev);
1862 static int nct1008_suspend(struct device *dev)
1864 struct i2c_client *client = to_i2c_client(dev);
1865 struct nct1008_data *data = i2c_get_clientdata(client);
1867 if (data->plat_data.suspend_with_wakeup &&
1868 data->plat_data.suspend_with_wakeup())
1869 return nct1008_suspend_wakeup(dev);
1871 return nct1008_suspend_powerdown(dev);
1875 static int nct1008_resume_wakeup(struct device *dev)
1878 struct i2c_client *client = to_i2c_client(dev);
1880 err = disable_irq_wake(client->irq);
1882 dev_err(&client->dev, "Error: %s, error=%d. failed to disable NCT "
1883 "wakeup\n", __func__, err);
1887 /* NCT wasn't powered down, so IRQ is still enabled. */
1888 /* Disable it before calling update */
1889 disable_irq(client->irq);
1894 static int nct1008_resume_powerdown(struct device *dev)
1896 struct i2c_client *client = to_i2c_client(dev);
1898 struct nct1008_data *data = i2c_get_clientdata(client);
1900 nct1008_power_control(data, true);
1901 nct1008_configure_sensor(data);
1902 err = nct1008_enable(client);
1904 dev_err(&client->dev, "Error: %s, error=%d\n",
1912 static int nct1008_resume(struct device *dev)
1914 struct i2c_client *client = to_i2c_client(dev);
1916 struct nct1008_data *data = i2c_get_clientdata(client);
1918 if (data->plat_data.suspend_with_wakeup &&
1919 data->plat_data.suspend_with_wakeup())
1920 err = nct1008_resume_wakeup(dev);
1922 err = nct1008_resume_powerdown(dev);
1927 nct1008_update(LOC, data);
1928 nct1008_update(EXT, data);
1929 mutex_lock(&data->mutex);
1930 data->stop_workqueue = 0;
1931 mutex_unlock(&data->mutex);
1932 enable_irq(client->irq);
1937 static const struct dev_pm_ops nct1008_pm_ops = {
1938 .suspend = nct1008_suspend,
1939 .resume = nct1008_resume,
1944 static const struct i2c_device_id nct1008_id[] = {
1945 { "nct1008", NCT1008 },
1949 MODULE_DEVICE_TABLE(i2c, nct1008_id);
1951 static const struct of_device_id nct1008_of_match[] = {
1952 {.compatible = "onsemi,nct72", },
1956 static struct i2c_driver nct1008_driver = {
1958 .name = "nct1008_nct72",
1959 #ifdef CONFIG_PM_SLEEP
1960 .pm = &nct1008_pm_ops,
1962 .of_match_table = nct1008_of_match,
1964 .probe = nct1008_probe,
1965 .remove = nct1008_remove,
1966 .id_table = nct1008_id,
1967 .shutdown = nct1008_shutdown,
1970 static int __init nct1008_sync_thz(struct device *dev, void *unused)
1972 struct nct1008_data *data = dev_get_drvdata(dev);
1973 if (data->sensors[LOC].thz)
1974 thermal_zone_device_update(data->sensors[LOC].thz);
1975 if (data->sensors[EXT].thz)
1976 thermal_zone_device_update(data->sensors[EXT].thz);
1980 static int __init nct1008_sync(void)
1982 return driver_for_each_device(
1983 &nct1008_driver.driver, NULL, NULL, nct1008_sync_thz);
1985 late_initcall_sync(nct1008_sync);
1987 static int __init nct1008_init(void)
1989 return i2c_add_driver(&nct1008_driver);
1992 static void __exit nct1008_exit(void)
1994 i2c_del_driver(&nct1008_driver);
1997 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008/NCT72");
1998 MODULE_LICENSE("GPL");
2000 module_init(nct1008_init);
2001 module_exit(nct1008_exit);