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 if (!client->dev.of_node)
396 nct1008_setup_shutdown_warning(data);
400 dev_err(dev, " %s: failed to set temperature-overheat\n", __func__);
404 static ssize_t nct1008_show_temp_alert(struct device *dev,
405 struct device_attribute *attr,
408 struct i2c_client *client = to_i2c_client(dev);
409 struct nct1008_platform_data *pdata = client->dev.platform_data;
411 s16 temp_hi, temp_lo;
412 /* External Temperature Throttling hi-limit */
413 value = nct1008_read_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
416 temp_hi = value_to_temperature(pdata->extended_range, value);
418 /* External Temperature Throttling lo-limit */
419 value = nct1008_read_reg(client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
422 temp_lo = value_to_temperature(pdata->extended_range, value);
424 return snprintf(buf, MAX_STR_PRINT, "lo:%d hi:%d\n", temp_lo, temp_hi);
426 dev_err(dev, "%s: failed to read temperature-alert\n", __func__);
427 return snprintf(buf, MAX_STR_PRINT, " Rd alert Error\n");
430 static ssize_t nct1008_set_temp_alert(struct device *dev,
431 struct device_attribute *attr,
432 const char *buf, size_t count)
437 struct i2c_client *client = to_i2c_client(dev);
438 struct nct1008_platform_data *pdata = client->dev.platform_data;
440 if (strict_strtol(buf, 0, &num)) {
441 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
445 if (((int)num < NCT1008_MIN_TEMP) || ((int)num >= NCT1008_MAX_TEMP)) {
446 dev_err(dev, "\n file: %s, line=%d return %s() ", __FILE__,
451 /* External Temperature Throttling limit */
452 value = temperature_to_value(pdata->extended_range, (s16)num);
453 err = nct1008_write_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR, value);
457 /* Local Temperature Throttling limit */
458 err = nct1008_write_reg(client, LOC_TEMP_HI_LIMIT_WR, value);
464 dev_err(dev, "%s: failed to set temperature-alert "
469 static ssize_t nct1008_show_sensor_temp(int sensor, struct device *dev,
470 struct device_attribute *attr, char *buf)
472 struct i2c_client *client = to_i2c_client(dev);
473 struct nct1008_platform_data *pdata = client->dev.platform_data;
478 if (!dev || !buf || !attr)
481 /* When reading the full external temperature value, read the
482 * LSB first. This causes the MSB to be locked (that is, the
483 * ADC does not write to it) until it is read */
484 data_lo = nct1008_read_reg(client, NCT_REG(sensor, TEMP_RD_LO));
486 dev_err(&client->dev, "%s: failed to read "
487 "ext_temperature, i2c error=%d\n", __func__, data_lo);
491 data = nct1008_read_reg(client, NCT_REG(sensor, TEMP_RD_HI));
493 dev_err(&client->dev, "%s: failed to read "
494 "ext_temperature, i2c error=%d\n", __func__, data);
498 temp_value = value_to_temperature(pdata->extended_range, data);
500 return snprintf(buf, MAX_STR_PRINT, "%d.%d\n", temp_value,
501 (25 * (data_lo >> 6)));
503 return snprintf(buf, MAX_STR_PRINT, "Error read ext temperature\n");
506 static ssize_t pr_reg(struct nct1008_data *nct, char *buf, int max_s,
507 const char *reg_name, int offset)
511 ret = nct1008_read_reg(nct->client, offset);
513 sz += snprintf(buf + sz, PAGE_SIZE - sz,
514 "%20s 0x%02x 0x%02x 0x%02x\n",
515 reg_name, nct->client->addr, offset, ret);
517 sz += snprintf(buf + sz, PAGE_SIZE - sz,
518 "%s: line=%d, i2c ** read error=%d **\n",
519 __func__, __LINE__, ret);
523 static ssize_t nct1008_show_regs(struct device *dev,
524 struct device_attribute *attr, char *buf)
526 struct i2c_client *client = to_i2c_client(dev);
527 struct nct1008_data *nct = i2c_get_clientdata(client);
528 char *name = nct->chip == NCT72 ? "nct72" : "nct1008";
531 sz += snprintf(buf + sz, PAGE_SIZE - sz,
532 "%s Registers\n", name);
533 sz += snprintf(buf + sz, PAGE_SIZE - sz,
534 "---------------------------------------\n");
535 sz += snprintf(buf + sz, PAGE_SIZE - sz, "%20s %4s %4s %s\n",
536 "Register Name ", "Addr", "Reg", "Value");
537 sz += snprintf(buf + sz, PAGE_SIZE - sz, "%20s %4s %4s %s\n",
538 "--------------------", "----", "----", "-----");
539 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
540 "Status ", STATUS_RD);
541 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
542 "Configuration ", CONFIG_RD);
543 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
544 "Conversion Rate ", CONV_RATE_RD);
545 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
546 "Hysteresis ", THERM_HYSTERESIS);
547 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
548 "Consecutive Alert ", COSECUTIVE_ALERT);
549 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
550 "Local Temp Value ", LOC_TEMP_RD);
551 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
552 "Local Temp Hi Limit ", LOC_TEMP_HI_LIMIT_RD);
553 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
554 "Local Temp Lo Limit ", LOC_TEMP_LO_LIMIT_RD);
555 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
556 "Local Therm Limit ", LOC_THERM_LIMIT);
557 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
558 "Ext Temp Value Hi ", EXT_TEMP_HI_RD);
559 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
560 "Ext Temp Value Lo ", EXT_TEMP_LO_RD);
561 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
562 "Ext Temp Hi Limit Hi", EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
563 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
564 "Ext Temp Hi Limit Lo", EXT_TEMP_HI_LIMIT_LO_BYTE);
565 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
566 "Ext Temp Lo Limit Hi", EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
567 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
568 "Ext Temp Lo Limit Lo", EXT_TEMP_LO_LIMIT_LO_BYTE);
569 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
570 "Ext Temp Offset Hi ", OFFSET_WR);
571 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
572 "Ext Temp Offset Lo ", OFFSET_QUARTER_WR);
573 sz += pr_reg(nct, buf+sz, PAGE_SIZE-sz,
574 "Ext Therm Limit ", EXT_THERM_LIMIT_WR);
579 static ssize_t nct1008_set_offsets(struct device *dev,
580 struct device_attribute *attr,
581 const char *buf, size_t count)
583 struct i2c_client *client = to_i2c_client(dev);
584 struct nct1008_data *nct = i2c_get_clientdata(client);
585 int index, temp, off;
589 sscanf(buf, "[%u] %u %d", &index, &temp, &off);
591 if (index >= ARRAY_SIZE(nct->sensors[EXT].offset_table)) {
592 pr_info("%s: invalid index [%d]\n", __func__, index);
595 nct->sensors[EXT].offset_table[index].temp = temp;
596 nct->sensors[EXT].offset_table[index].offset = off;
602 static ssize_t nct1008_show_offsets(struct device *dev,
603 struct device_attribute *attr, char *buf)
605 struct i2c_client *client = to_i2c_client(dev);
606 struct nct1008_data *nct = i2c_get_clientdata(client);
607 char *name = nct->chip == NCT72 ? "nct72" : "nct1008";
610 sz += snprintf(buf + sz, PAGE_SIZE - sz,
611 "%s offsets table\n", name);
612 sz += snprintf(buf + sz, PAGE_SIZE - sz,
613 "%2s %4s %s\n", " #", "temp", "offset");
614 sz += snprintf(buf + sz, PAGE_SIZE - sz,
615 "%2s %4s %s\n", "--", "----", "------");
617 for (i = 0; i < ARRAY_SIZE(nct->sensors[EXT].offset_table); i++)
618 sz += snprintf(buf + sz, PAGE_SIZE - sz,
620 i, nct->sensors[EXT].offset_table[i].temp,
621 nct->sensors[EXT].offset_table[i].offset);
626 /* This function is used by the system to show the temperature. */
627 static ssize_t nct1008_show_ext_temp(struct device *dev,
628 struct device_attribute *attr,
631 return nct1008_show_sensor_temp(EXT, dev, attr, buf);
634 static DEVICE_ATTR(temperature, S_IRUGO, nct1008_show_temp, NULL);
635 static DEVICE_ATTR(temperature_overheat, (S_IRUGO | (S_IWUSR | S_IWGRP)),
636 nct1008_show_temp_overheat, nct1008_set_temp_overheat);
637 static DEVICE_ATTR(temperature_alert, (S_IRUGO | (S_IWUSR | S_IWGRP)),
638 nct1008_show_temp_alert, nct1008_set_temp_alert);
639 static DEVICE_ATTR(ext_temperature, S_IRUGO, nct1008_show_ext_temp, NULL);
640 static DEVICE_ATTR(registers, S_IRUGO, nct1008_show_regs, NULL);
641 static DEVICE_ATTR(offsets, (S_IRUGO | (S_IWUSR | S_IWGRP)),
642 nct1008_show_offsets, nct1008_set_offsets);
644 static struct attribute *nct1008_attributes[] = {
645 &dev_attr_temperature.attr,
646 &dev_attr_temperature_overheat.attr,
647 &dev_attr_temperature_alert.attr,
648 &dev_attr_ext_temperature.attr,
649 &dev_attr_registers.attr,
650 &dev_attr_offsets.attr,
654 static const struct attribute_group nct1008_attr_group = {
655 .attrs = nct1008_attributes,
658 static const unsigned long THERM_WARN_RANGE_HIGH_OFFSET = 3000;
659 static unsigned long nct1008_shutdown_warning_cur_state;
660 static long shutdown_warn_saved_temp;
662 static int nct1008_shutdown_warning_get_max_state(
663 struct thermal_cooling_device *cdev,
664 unsigned long *max_state)
666 /* A state for every 250mC */
667 *max_state = THERM_WARN_RANGE_HIGH_OFFSET / 250;
671 static int nct1008_shutdown_warning_get_cur_state(
672 struct thermal_cooling_device *cdev,
673 unsigned long *cur_state)
675 struct nct1008_data *data = cdev->devdata;
676 long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
679 if (nct1008_get_temp_common(EXT, data, &temp))
682 if (temp >= (limit - THERM_WARN_RANGE_HIGH_OFFSET))
683 *cur_state = nct1008_shutdown_warning_cur_state;
690 static int nct1008_shutdown_warning_set_cur_state(
691 struct thermal_cooling_device *cdev,
692 unsigned long cur_state)
694 struct nct1008_data *data = cdev->devdata;
695 long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
698 if (nct1008_get_temp_common(EXT, data, &temp))
703 if ((temp >= (limit - THERM_WARN_RANGE_HIGH_OFFSET)) &&
704 (temp != shutdown_warn_saved_temp)) {
705 pr_warn("NCT%s: Warning: chip temperature (%ld.%02ldC) is %s SHUTDOWN limit (%c%ldC).\n",
706 (data->chip == NCT72) ? "72" : "1008",
707 temp / 1000, (temp % 1000) / 10,
708 temp > limit ? "above" :
709 temp == limit ? "at" : "near",
710 temp > limit ? '>' : '<', limit / 1000);
711 shutdown_warn_saved_temp = temp;
715 nct1008_shutdown_warning_cur_state = cur_state;
719 static struct thermal_cooling_device_ops nct1008_shutdown_warning_ops = {
720 .get_max_state = nct1008_shutdown_warning_get_max_state,
721 .get_cur_state = nct1008_shutdown_warning_get_cur_state,
722 .set_cur_state = nct1008_shutdown_warning_set_cur_state,
725 static int nct1008_thermal_set_limits(int sensor,
726 struct nct1008_data *data,
732 bool extended_range = data->plat_data.extended_range;
733 long lo_limit = MILLICELSIUS_TO_CELSIUS(lo_limit_milli);
734 long hi_limit = MILLICELSIUS_TO_CELSIUS(hi_limit_milli);
736 if (lo_limit >= hi_limit)
739 if (data->sensors[sensor].current_lo_limit != lo_limit) {
740 value = temperature_to_value(extended_range, lo_limit);
741 pr_debug("%s: set lo_limit %ld\n", __func__, lo_limit);
742 err = nct1008_write_reg(data->client,
743 NCT_REG(sensor, TEMP_LO_LIMIT_WR), value);
747 data->sensors[sensor].current_lo_limit = lo_limit;
750 if (data->sensors[sensor].current_hi_limit != hi_limit) {
751 value = temperature_to_value(extended_range, hi_limit);
752 pr_debug("%s: set hi_limit %ld\n", __func__, hi_limit);
753 err = nct1008_write_reg(data->client,
754 NCT_REG(sensor, TEMP_HI_LIMIT_WR), value);
758 data->sensors[sensor].current_hi_limit = hi_limit;
762 pr_debug("NCT1008: LOC-sensor limits set to %ld - %ld\n",
768 #ifdef CONFIG_THERMAL
769 static void nct1008_update(int sensor, struct nct1008_data *data)
771 struct thermal_zone_device *thz;
772 long low_temp, high_temp;
773 struct thermal_trip_info *trip_state;
774 long temp, trip_temp, hysteresis_temp;
776 enum thermal_trip_type trip_type;
777 low_temp = 0, high_temp = NCT1008_MAX_TEMP * 1000;
778 thz = data->sensors[sensor].thz;
783 thermal_zone_device_update(thz);
785 temp = thz->temperature;
787 for (count = 0; count < thz->trips; count++) {
788 trip_state = &data->plat_data.sensors[sensor].trips[count];
789 thz->ops->get_trip_temp(thz, count, &trip_temp);
790 thz->ops->get_trip_type(thz, count, &trip_type);
791 thz->ops->get_trip_hyst(thz, count, &hysteresis_temp);
792 hysteresis_temp = trip_temp - hysteresis_temp;
793 if ((trip_type == THERMAL_TRIP_PASSIVE) &&
794 !trip_state->tripped)
795 hysteresis_temp = trip_temp;
797 if ((trip_temp > temp) && (trip_temp < high_temp))
798 high_temp = trip_temp;
800 if ((hysteresis_temp < temp) && (hysteresis_temp > low_temp))
801 low_temp = hysteresis_temp;
804 nct1008_thermal_set_limits(sensor, data, low_temp, high_temp);
807 static int nct1008_ext_get_temp(struct thermal_zone_device *thz, long *temp)
809 struct nct1008_data *data = thz->devdata;
811 return nct1008_get_temp_common(EXT, data, temp);
814 static int nct1008_ext_get_temp_as_sensor(void *data, long *temp)
816 return nct1008_get_temp_common(EXT, (struct nct1008_data *) data, temp);
819 static int nct1008_ext_bind(struct thermal_zone_device *thz,
820 struct thermal_cooling_device *cdev)
822 struct nct1008_data *data = thz->devdata;
824 struct nct1008_sensor_platform_data *sensor;
826 sensor = &data->plat_data.sensors[EXT];
828 for (i = 0; i < sensor->num_trips; i++) {
829 if (!strcmp(sensor->trips[i].cdev_type, cdev->type))
830 thermal_zone_bind_cooling_device(thz, i, cdev,
831 sensor->trips[i].upper,
832 sensor->trips[i].lower);
839 static int nct1008_unbind(int sensor,
840 struct thermal_zone_device *thz,
841 struct thermal_cooling_device *cdev)
843 struct nct1008_data *data = thz->devdata;
846 struct nct1008_sensor_platform_data *sensor_data;
848 sensor_data = &data->plat_data.sensors[sensor];
850 for (i = 0; i < sensor_data->num_trips; i++) {
851 if (!strcmp(sensor_data->trips[i].cdev_type, cdev->type))
852 thermal_zone_unbind_cooling_device(thz, i, cdev);
857 /* Helper function that is called in order to unbind external sensor from the
859 static inline int nct1008_ext_unbind(struct thermal_zone_device *thz,
860 struct thermal_cooling_device *cdev)
862 return nct1008_unbind(EXT, thz, cdev);
865 /* Helper function that is called in order to unbind local sensor from the
867 static inline int nct1008_loc_unbind(struct thermal_zone_device *thz,
868 struct thermal_cooling_device *cdev)
870 return nct1008_unbind(LOC, thz, cdev);
873 /* This function reads the temperature value set for the given trip point. */
874 static int nct1008_get_trip_temp(int sensor,
875 struct thermal_zone_device *thz,
876 int trip, long *temp)
878 struct nct1008_data *data = thz->devdata;
879 struct thermal_trip_info *trip_state =
880 &data->plat_data.sensors[sensor].trips[trip];
882 *temp = trip_state->trip_temp;
884 if (trip_state->trip_type != THERMAL_TRIP_PASSIVE)
887 if (thz->temperature >= *temp) {
888 trip_state->tripped = true;
889 } else if (trip_state->tripped) {
890 *temp -= trip_state->hysteresis;
891 if (thz->temperature < *temp)
892 trip_state->tripped = false;
898 /* This function reads the temperature value set for the given trip point for
900 static inline int nct1008_loc_get_trip_temp(struct thermal_zone_device *thz,
901 int trip, long *temp)
903 return nct1008_get_trip_temp(LOC, thz, trip, temp);
906 /* This function reads the temperature value set for the given trip point for
907 the remote sensor. */
908 static inline int nct1008_ext_get_trip_temp(struct thermal_zone_device *thz,
909 int trip, long *temp)
911 return nct1008_get_trip_temp(EXT, thz, trip, temp);
914 /* This function allows setting trip point temperature for the sensor
916 static int nct1008_set_trip_temp(int sensor,
917 struct thermal_zone_device *thz,
920 struct nct1008_data *data = thz->devdata;
922 data->plat_data.sensors[sensor].trips[trip].trip_temp = temp;
923 nct1008_update(sensor, data);
927 /* This function allows setting trip point temperature for the local sensor. */
928 static inline int nct1008_loc_set_trip_temp(struct thermal_zone_device *thz,
931 return nct1008_set_trip_temp(LOC, thz, trip, temp);
934 /* This function allows setting trip point temperature for the external
936 static inline int nct1008_ext_set_trip_temp(struct thermal_zone_device *thz,
939 return nct1008_set_trip_temp(EXT, thz, trip, temp);
942 static int nct1008_loc_trip_update(void *of_data, int trip)
944 struct nct1008_data *data = (struct nct1008_data *)of_data;
946 nct1008_update(LOC, data);
951 static int nct1008_ext_trip_update(void *of_data, int trip)
953 struct nct1008_data *data = (struct nct1008_data *)of_data;
955 nct1008_update(EXT, data);
960 /* This function return the trip point type for the sensor specified. */
961 static int nct1008_get_trip_type(int sensor,
962 struct thermal_zone_device *thz,
964 enum thermal_trip_type *type)
966 struct nct1008_data *data = thz->devdata;
968 *type = data->plat_data.sensors[sensor].trips[trip].trip_type;
972 /* This function return the trip point type for the local sensor. */
973 static inline int nct1008_loc_get_trip_type(struct thermal_zone_device *thz,
975 enum thermal_trip_type *type)
977 return nct1008_get_trip_type(LOC, thz, trip, type);
980 /* This function return the trip point type for the external sensor. */
981 static inline int nct1008_ext_get_trip_type(struct thermal_zone_device *thz,
983 enum thermal_trip_type *type)
985 return nct1008_get_trip_type(EXT, thz, trip, type);
988 static int nct1008_get_trip_hyst(int sensor, struct thermal_zone_device *thz,
992 struct nct1008_data *data = thz->devdata;
994 *hyst = data->plat_data.sensors[sensor].trips[trip].hysteresis;
998 static inline int nct1008_loc_get_trip_hyst(struct thermal_zone_device *thz,
1002 return nct1008_get_trip_hyst(LOC, thz, trip, hyst);
1005 static inline int nct1008_ext_get_trip_hyst(struct thermal_zone_device *thz,
1009 return nct1008_get_trip_hyst(EXT, thz, trip, hyst);
1012 /* This function returns value of trend for the temperature change, depending
1013 on the trip point type. */
1014 static int nct1008_get_trend(struct thermal_zone_device *thz,
1016 enum thermal_trend *trend)
1018 long trip_temp, trip_hyst;
1019 enum thermal_trip_type trip_type;
1021 thz->ops->get_trip_temp(thz, trip, &trip_temp);
1022 thz->ops->get_trip_type(thz, trip, &trip_type);
1023 thz->ops->get_trip_hyst(thz, trip, &trip_hyst);
1025 switch (trip_type) {
1026 case THERMAL_TRIP_ACTIVE:
1027 if (thz->temperature >= trip_temp)
1028 *trend = THERMAL_TREND_RAISING;
1030 *trend = THERMAL_TREND_DROPPING;
1032 case THERMAL_TRIP_PASSIVE:
1033 if (thz->temperature > thz->last_temperature)
1034 *trend = THERMAL_TREND_RAISING;
1035 else if (thz->temperature < (thz->last_temperature - trip_hyst))
1036 *trend = THERMAL_TREND_DROPPING;
1038 *trend = THERMAL_TREND_STABLE;
1047 static int nct1008_get_trend_as_sensor(int sensor,
1048 struct nct1008_data *data,
1051 struct thermal_zone_device *thz = data->sensors[sensor].thz;
1053 return thz->temperature - thz->last_temperature;
1056 /* Helper function to get trend for the local sensor. */
1057 static inline int nct1008_loc_get_trend_as_sensor(void *data,
1060 return nct1008_get_trend_as_sensor(LOC,
1061 (struct nct1008_data *) data, trend);
1064 static inline int nct1008_ext_get_trend_as_sensor(void *data,
1067 return nct1008_get_trend_as_sensor
1068 (EXT, (struct nct1008_data *) data, trend);
1072 /* Helper function to get temperature of the local sensor. */
1073 static int nct1008_loc_get_temp(struct thermal_zone_device *thz, long *temp)
1075 struct nct1008_data *data = thz->devdata;
1077 return nct1008_get_temp_common(LOC, data, temp);
1080 static int nct1008_loc_get_temp_as_sensor(void *data, long *temp)
1082 return nct1008_get_temp_common(LOC, (struct nct1008_data *) data, temp);
1084 /* Helper function to bind local sensor with the cooling device specified. */
1085 static int nct1008_loc_bind(struct thermal_zone_device *thz,
1086 struct thermal_cooling_device *cdev)
1088 struct nct1008_data *data = thz->devdata;
1090 struct nct1008_sensor_platform_data *sensor_data;
1092 pr_debug("NCT1008: LOC-sensor bind %s, %s attempt\n",
1093 thz->type, cdev->type);
1095 sensor_data = &data->plat_data.sensors[LOC];
1097 for (i = 0; i < sensor_data->num_trips; i++) {
1098 if (!strcmp(sensor_data->trips[i].cdev_type, cdev->type)) {
1099 thermal_zone_bind_cooling_device(thz, i, cdev,
1100 sensor_data->trips[i].upper,
1101 sensor_data->trips[i].lower);
1109 static struct thermal_zone_device_ops nct_loc_ops = {
1110 .get_temp = nct1008_loc_get_temp,
1111 .bind = nct1008_loc_bind,
1112 .unbind = nct1008_loc_unbind,
1113 .get_trip_type = nct1008_loc_get_trip_type,
1114 .get_trip_temp = nct1008_loc_get_trip_temp,
1115 .get_trip_hyst = nct1008_loc_get_trip_hyst,
1116 .set_trip_temp = nct1008_loc_set_trip_temp,
1117 .get_trend = nct1008_get_trend,
1120 static struct thermal_zone_device_ops nct_ext_ops = {
1121 .get_temp = nct1008_ext_get_temp,
1122 .bind = nct1008_ext_bind,
1123 .unbind = nct1008_ext_unbind,
1124 .get_trip_type = nct1008_ext_get_trip_type,
1125 .get_trip_temp = nct1008_ext_get_trip_temp,
1126 .get_trip_hyst = nct1008_ext_get_trip_hyst,
1127 .set_trip_temp = nct1008_ext_set_trip_temp,
1128 .get_trend = nct1008_get_trend,
1131 static void nct1008_update(nct1008_sensors sensor, struct nct1008_data *data)
1134 #endif /* CONFIG_THERMAL */
1136 static int nct1008_enable(struct i2c_client *client)
1138 struct nct1008_data *data = i2c_get_clientdata(client);
1141 err = nct1008_write_reg(client, CONFIG_WR, data->config);
1143 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
1144 __func__, __LINE__, err);
1148 static int nct1008_disable(struct i2c_client *client)
1150 struct nct1008_data *data = i2c_get_clientdata(client);
1153 err = nct1008_write_reg(client, CONFIG_WR,
1154 data->config | STANDBY_BIT);
1156 dev_err(&client->dev, "%s, line=%d, i2c write error=%d\n",
1157 __func__, __LINE__, err);
1161 static void nct1008_work_func(struct work_struct *work)
1163 struct nct1008_data *data = container_of(work, struct nct1008_data,
1169 mutex_lock(&data->mutex);
1170 if (data->stop_workqueue) {
1171 mutex_unlock(&data->mutex);
1174 mutex_unlock(&data->mutex);
1176 err = nct1008_disable(data->client);
1180 intr_status = nct1008_read_reg(data->client, STATUS_RD);
1181 pr_debug("NCT1008: interruption (0x%08x)\n", intr_status);
1183 if (intr_status & (LOC_LO_BIT | LOC_HI_BIT)) {
1184 pr_debug("NCT1008: LOC-sensor is not within limits\n");
1185 nct1008_update(LOC, data);
1188 if (intr_status & (EXT_LO_BIT | EXT_HI_BIT))
1189 nct1008_update(EXT, data);
1191 /* Initiate one-shot conversion */
1192 nct1008_write_reg(data->client, ONE_SHOT, 0x1);
1194 /* Give hardware necessary time to finish conversion */
1195 ts = ns_to_timespec(MAX_CONV_TIME_ONESHOT_MS * 1000 * 1000);
1196 hrtimer_nanosleep(&ts, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC);
1198 nct1008_read_reg(data->client, STATUS_RD);
1200 nct1008_enable(data->client);
1202 enable_irq(data->client->irq);
1205 static irqreturn_t nct1008_irq(int irq, void *dev_id)
1207 struct nct1008_data *data = dev_id;
1209 disable_irq_nosync(irq);
1210 queue_work(data->workqueue, &data->work);
1215 static void nct1008_power_control(struct nct1008_data *data, bool is_enable)
1219 mutex_lock(&data->mutex);
1220 if (!data->nct_reg) {
1221 data->nct_reg = regulator_get(&data->client->dev, "vdd");
1222 if (IS_ERR_OR_NULL(data->nct_reg)) {
1223 if (PTR_ERR(data->nct_reg) == -ENODEV)
1224 dev_info(&data->client->dev,
1225 "no regulator found for vdd."
1226 " Assuming vdd is always powered");
1228 dev_warn(&data->client->dev, "Error [%ld] in "
1229 "getting the regulator handle for"
1230 " vdd\n", PTR_ERR(data->nct_reg));
1231 data->nct_reg = NULL;
1232 mutex_unlock(&data->mutex);
1237 ret = regulator_enable(data->nct_reg);
1239 ret = regulator_disable(data->nct_reg);
1242 dev_err(&data->client->dev, "Error in %s rail vdd_nct%s, "
1243 "error %d\n", (is_enable) ? "enabling" : "disabling",
1244 (data->chip == NCT72) ? "72" : "1008",
1247 dev_info(&data->client->dev, "success in %s rail vdd_nct%s\n",
1248 (is_enable) ? "enabling" : "disabling",
1249 (data->chip == NCT72) ? "72" : "1008");
1250 data->nct_disabled = !is_enable;
1251 mutex_unlock(&data->mutex);
1254 static void nct1008_setup_shutdown_warning(struct nct1008_data *data)
1256 static struct thermal_cooling_device *cdev;
1257 long limit = data->plat_data.sensors[EXT].shutdown_limit * 1000;
1258 long warn_temp = limit - THERM_WARN_RANGE_HIGH_OFFSET;
1260 struct nct1008_sensor_platform_data *sensor_data;
1263 thermal_cooling_device_unregister(cdev);
1264 cdev = thermal_cooling_device_register("shutdown_warning", data,
1265 &nct1008_shutdown_warning_ops);
1266 if (IS_ERR_OR_NULL(cdev)) {
1271 sensor_data = &data->plat_data.sensors[EXT];
1273 for (i = 0; i < sensor_data->num_trips; i++) {
1274 if (!strcmp(sensor_data->trips[i].cdev_type,
1275 "shutdown_warning")) {
1276 sensor_data->trips[i].trip_temp = warn_temp;
1277 nct1008_update(EXT, data);
1282 pr_info("NCT%s: Enabled overheat logging at %ld.%02ldC\n",
1283 (data->chip == NCT72) ? "72" : "1008",
1284 warn_temp / 1000, (warn_temp % 1000) / 10);
1287 static int nct1008_configure_sensor(struct nct1008_data *data)
1289 struct i2c_client *client = data->client;
1290 struct nct1008_platform_data *pdata = client->dev.platform_data;
1295 bool ext_err = false;
1297 if (!pdata || !pdata->supported_hwrev)
1300 ret = nct1008_read_reg(data->client, STATUS_RD);
1302 pr_info("NCT%s: ERR: remote sensor circuit is open (0x%02x)\n",
1303 (data->chip == NCT72) ? "72" : "1008", ret);
1304 ext_err = true; /* flag the error */
1307 /* Initially place in Standby */
1308 ret = nct1008_write_reg(client, CONFIG_WR, STANDBY_BIT);
1312 /* Local temperature h/w shutdown limit */
1313 value = temperature_to_value(pdata->extended_range,
1314 pdata->sensors[LOC].shutdown_limit);
1315 ret = nct1008_write_reg(client, LOC_THERM_LIMIT, value);
1319 /* set extended range mode if needed */
1320 if (pdata->extended_range)
1321 data->config |= EXTENDED_RANGE_BIT;
1322 data->config &= ~(THERM2_BIT | ALERT_BIT);
1324 ret = nct1008_write_reg(client, CONFIG_WR, data->config | STANDBY_BIT);
1328 /* Temperature conversion rate */
1329 ret = nct1008_write_reg(client, CONV_RATE_WR, pdata->conv_rate);
1333 data->conv_period_ms = conv_period_ms_table[pdata->conv_rate];
1335 /* Setup local hi and lo limits. */
1336 ret = nct1008_write_reg(client, LOC_TEMP_HI_LIMIT_WR, NCT1008_MAX_TEMP);
1340 ret = nct1008_write_reg(client, LOC_TEMP_LO_LIMIT_WR, 0);
1344 /* Initiate one-shot conversion */
1345 nct1008_write_reg(data->client, ONE_SHOT, 0x1);
1347 /* Give hardware necessary time to finish conversion */
1348 msleep(MAX_CONV_TIME_ONESHOT_MS);
1350 /* read initial temperature */
1351 ret = nct1008_read_reg(client, LOC_TEMP_RD);
1357 temp = value_to_temperature(pdata->extended_range, value);
1358 dev_dbg(&client->dev, "\n initial local temp = %d ", temp);
1361 return ext_err; /* skip configuration of EXT sensor */
1363 /* External temperature h/w shutdown limit. */
1364 value = temperature_to_value(pdata->extended_range,
1365 pdata->sensors[EXT].shutdown_limit);
1366 ret = nct1008_write_reg(client, EXT_THERM_LIMIT_WR, value);
1370 /* Setup external hi and lo limits */
1371 ret = nct1008_write_reg(client, EXT_TEMP_LO_LIMIT_HI_BYTE_WR, 0);
1374 ret = nct1008_write_reg(client, EXT_TEMP_HI_LIMIT_HI_BYTE_WR,
1379 ret = nct1008_read_reg(client, EXT_TEMP_LO_RD);
1385 temp2 = (value >> 6);
1386 ret = nct1008_read_reg(client, EXT_TEMP_HI_RD);
1392 temp = value_to_temperature(pdata->extended_range, value);
1395 dev_dbg(&client->dev, "\n initial ext temp = %d.%d deg",
1398 dev_dbg(&client->dev, "\n initial ext temp = %d.0 deg", temp);
1400 /* Remote channel offset */
1401 ret = nct1008_write_reg(client, OFFSET_WR, pdata->offset / 4);
1405 /* Remote channel offset fraction (quarters) */
1406 ret = nct1008_write_reg(client, OFFSET_QUARTER_WR,
1407 (pdata->offset % 4) << 6);
1411 /* Reset current hi/lo limit values with register values */
1412 ret = nct1008_read_reg(data->client, EXT_TEMP_LO_LIMIT_HI_BYTE_RD);
1417 data->sensors[EXT].current_lo_limit =
1418 value_to_temperature(pdata->extended_range, value);
1420 ret = nct1008_read_reg(data->client, EXT_TEMP_HI_LIMIT_HI_BYTE_RD);
1426 data->sensors[EXT].current_hi_limit =
1427 value_to_temperature(pdata->extended_range, value);
1429 ret = nct1008_read_reg(data->client, LOC_TEMP_LO_LIMIT_RD);
1435 data->sensors[LOC].current_lo_limit =
1436 value_to_temperature(pdata->extended_range, value);
1438 value = nct1008_read_reg(data->client, LOC_TEMP_HI_LIMIT_RD);
1444 data->sensors[LOC].current_hi_limit =
1445 value_to_temperature(pdata->extended_range, value);
1447 if (!client->dev.of_node)
1448 nct1008_setup_shutdown_warning(data);
1452 dev_err(&client->dev, "\n exit %s, err=%d ", __func__, ret);
1456 static int nct1008_configure_irq(struct nct1008_data *data)
1458 data->workqueue = create_singlethread_workqueue((data->chip == NCT72) \
1459 ? "nct72" : "nct1008");
1461 INIT_WORK(&data->work, nct1008_work_func);
1463 if (data->client->irq < 0)
1466 return request_irq(data->client->irq, nct1008_irq,
1468 (data->chip == NCT72) ? "nct72" : "nct1008",
1472 static struct nct1008_platform_data *nct1008_dt_parse(struct i2c_client *client)
1474 struct device_node *np = client->dev.of_node;
1475 struct device_node *child_sensor;
1476 struct nct1008_platform_data *pdata;
1478 unsigned int proc, index = 0;
1480 dev_err(&client->dev,
1481 "Cannot found the DT node\n");
1485 dev_info(&client->dev, "starting parse dt\n");
1486 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1488 dev_err(&client->dev,
1489 "Parse DT fails at malloc pdata\n");
1493 pdata->loc_name = of_get_property(np, "sensor-name", NULL);
1494 if (pdata->loc_name == NULL) {
1495 dev_err(&client->dev,
1496 "Cannot found the name\n");
1500 if (client->irq == 0)
1503 if (of_property_read_u32(np, "conv-rate", &proc))
1505 pdata->conv_rate = proc;
1507 if (of_property_read_u32(np, "supported-hwrev", &proc))
1509 pdata->supported_hwrev = (bool) proc;
1511 if (of_property_read_u32(np, "extended-rage", &proc))
1513 pdata->extended_range = (bool) proc;
1515 if (of_property_read_u32(np, "offset", &proc))
1517 pdata->offset = proc;
1519 if (of_property_read_bool(np, "temp-alert-gpio")) {
1520 nct72_gpio = of_get_named_gpio(
1521 np, "temp-alert-gpio", 0);
1522 if (gpio_request(nct72_gpio, "temp_alert") < 0)
1523 dev_err(&client->dev,
1524 "%s gpio request error\n", __FILE__);
1525 if (gpio_direction_input(nct72_gpio) < 0) {
1526 dev_err(&client->dev,
1527 "%s gpio direction_input fail\n", __FILE__);
1528 gpio_free(nct72_gpio);
1532 for_each_child_of_node(np, child_sensor) {
1533 if (of_property_read_u32(child_sensor, "shutdown-limit", &proc))
1535 pdata->sensors[index].shutdown_limit = proc;
1538 of_property_read_u32(child_sensor, "suspend_limit_hi", &proc);
1539 pdata->sensors[index].suspend_limit_hi = proc;
1540 of_property_read_u32(child_sensor, "suspend_limit_lo", &proc);
1541 pdata->sensors[index].suspend_limit_lo = proc;
1545 dev_info(&client->dev, "success parsing dt\n");
1546 client->dev.platform_data = pdata;
1550 dev_err(&client->dev, "Parsing device tree data error.\n");
1555 * Manufacturer(OnSemi) recommended sequence for
1556 * Extended Range mode is as follows
1557 * 1. Place in Standby
1558 * 2. Scale the THERM and ALERT limits
1559 * appropriately(for Extended Range mode).
1560 * 3. Enable Extended Range mode.
1561 * ALERT mask/THERM2 mode may be done here
1562 * as these are not critical
1563 * 4. Set Conversion Rate as required
1564 * 5. Take device out of Standby
1568 * function nct1008_probe takes care of initial configuration
1570 static int nct1008_probe(struct i2c_client *client,
1571 const struct i2c_device_id *id)
1573 struct nct1008_data *data;
1574 struct nct1008_platform_data *pdata;
1575 struct thermal_zone_device *zone_device;
1579 char nct_loc_name[THERMAL_NAME_LENGTH];
1580 char nct_ext_name[THERMAL_NAME_LENGTH];
1582 struct nct1008_sensor_platform_data *sensor_data;
1583 struct thermal_of_sensor_ops loc_sops = {
1584 .get_temp = nct1008_loc_get_temp_as_sensor,
1585 .get_trend = nct1008_loc_get_trend_as_sensor,
1586 .trip_update = nct1008_loc_trip_update,
1589 struct thermal_of_sensor_ops ext_sops = {
1590 .get_temp = nct1008_ext_get_temp_as_sensor,
1591 .get_trend = nct1008_ext_get_trend_as_sensor,
1592 .trip_update = nct1008_ext_trip_update,
1595 if (client->dev.of_node) {
1596 dev_info(&client->dev, "find device tree node, parsing dt\n");
1597 pdata = nct1008_dt_parse(client);
1598 if (IS_ERR(pdata)) {
1599 err = PTR_ERR(pdata);
1600 dev_err(&client->dev,
1601 "Parsing of node failed, %d\n", err);
1606 data = kzalloc(sizeof(struct nct1008_data), GFP_KERNEL);
1610 data->client = client;
1611 data->chip = id->driver_data;
1612 memcpy(&data->plat_data, client->dev.platform_data,
1613 sizeof(struct nct1008_platform_data));
1615 i2c_set_clientdata(client, data);
1616 mutex_init(&data->mutex);
1618 nct1008_power_control(data, true);
1619 if (!data->nct_reg) {
1620 /* power up failure */
1624 /* extended range recommended steps 1 through 4 taken care
1625 * in nct1008_configure_sensor function */
1626 err = nct1008_configure_sensor(data); /* sensor is in standby */
1629 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
1630 __FILE__, __func__, __LINE__);
1634 err = nct1008_configure_irq(data);
1636 dev_err(&client->dev, "\n error file: %s : %s(), line=%d ",
1637 __FILE__, __func__, __LINE__);
1640 dev_info(&client->dev, "%s: initialized\n", __func__);
1642 /* extended range recommended step 5 is in nct1008_enable function */
1643 err = nct1008_enable(client); /* sensor is running */
1645 dev_err(&client->dev, "Error: %s, line=%d, error=%d\n",
1646 __func__, __LINE__, err);
1650 /* register sysfs hooks */
1651 err = sysfs_create_group(&client->dev.kobj, &nct1008_attr_group);
1653 dev_err(&client->dev, "\n sysfs create err=%d ", err);
1657 #ifdef CONFIG_THERMAL
1658 if (data->plat_data.loc_name) {
1659 strcpy(nct_loc_name, "Tboard_");
1660 strcpy(nct_ext_name, "Tdiode_");
1661 strncat(nct_loc_name, data->plat_data.loc_name,
1662 (THERMAL_NAME_LENGTH - strlen("Tboard_")) - 1);
1663 strncat(nct_ext_name, data->plat_data.loc_name,
1664 (THERMAL_NAME_LENGTH - strlen("Tdiode_")) - 1);
1666 strcpy(nct_loc_name, "Tboard");
1667 strcpy(nct_ext_name, "Tdiode");
1670 if (client->dev.of_node) {
1671 /* Config for the Local sensor. */
1673 thermal_zone_of_sensor_register2(&client->dev, LOC,
1676 if (!IS_ERR_OR_NULL(zone_device))
1677 data->sensors[LOC].thz = zone_device;
1679 /* register External sensor if connection is good */
1681 thermal_zone_of_sensor_register2(&client->dev, EXT,
1683 if (!IS_ERR_OR_NULL(zone_device))
1684 data->sensors[EXT].thz = zone_device;
1686 sensor_data = &data->plat_data.sensors[LOC];
1688 /* Config for the Local sensor. */
1690 for (i = 0; i < sensor_data->num_trips; i++)
1691 if (data->plat_data.sensors[LOC].trips[i].mask)
1694 data->sensors[LOC].thz =
1695 thermal_zone_device_register(nct_loc_name,
1696 sensor_data->num_trips,
1704 /* Config for the External sensor. */
1706 for (i = 0; i < data->plat_data.sensors[EXT].num_trips; i++)
1707 if (data->plat_data.sensors[EXT].trips[i].mask > 0)
1710 /* register External sensor if connection is good */
1711 data->sensors[EXT].thz = ext_err ? NULL :
1712 thermal_zone_device_register(nct_ext_name,
1713 data->plat_data.sensors[EXT].num_trips,
1717 data->plat_data.sensors[EXT].tzp,
1718 data->plat_data.sensors[EXT].passive_delay,
1719 data->plat_data.sensors[EXT].polling_delay);
1722 if (!IS_ERR_OR_NULL(data->sensors[LOC].thz)) {
1723 nct1008_update(LOC, data);
1726 if (!IS_ERR_OR_NULL(data->sensors[EXT].thz)) {
1727 nct1008_update(EXT, data);
1728 shutdown_warn_saved_temp = data->sensors[EXT].thz->temperature;
1735 dev_err(&client->dev, "\n exit %s, err=%d ", __func__, err);
1736 nct1008_power_control(data, false);
1738 mutex_destroy(&data->mutex);
1740 regulator_put(data->nct_reg);
1745 static int nct1008_remove(struct i2c_client *client)
1747 struct nct1008_data *data = i2c_get_clientdata(client);
1749 mutex_lock(&data->mutex);
1750 data->stop_workqueue = 1;
1751 mutex_unlock(&data->mutex);
1753 cancel_work_sync(&data->work);
1754 free_irq(data->client->irq, data);
1755 sysfs_remove_group(&client->dev.kobj, &nct1008_attr_group);
1756 nct1008_power_control(data, false);
1759 regulator_put(data->nct_reg);
1761 mutex_destroy(&data->mutex);
1767 static void nct1008_shutdown(struct i2c_client *client)
1769 struct nct1008_data *data = i2c_get_clientdata(client);
1771 mutex_lock(&data->mutex);
1772 data->stop_workqueue = 1;
1773 mutex_unlock(&data->mutex);
1775 if (data->sensors[LOC].thz) {
1776 if (client->dev.of_node)
1777 thermal_zone_of_sensor_unregister
1778 (&(client->dev), data->sensors[LOC].thz);
1780 thermal_zone_device_unregister(data->sensors[LOC].thz);
1781 data->sensors[LOC].thz = NULL;
1783 if (data->sensors[EXT].thz) {
1784 if (client->dev.of_node)
1785 thermal_zone_of_sensor_unregister
1786 (&(client->dev), data->sensors[EXT].thz);
1788 thermal_zone_device_unregister(data->sensors[EXT].thz);
1789 data->sensors[EXT].thz = NULL;
1792 cancel_work_sync(&data->work);
1795 disable_irq(client->irq);
1797 mutex_lock(&data->mutex);
1798 data->nct_disabled = 1;
1799 mutex_unlock(&data->mutex);
1802 #ifdef CONFIG_PM_SLEEP
1803 static int nct1008_suspend_powerdown(struct device *dev)
1805 struct i2c_client *client = to_i2c_client(dev);
1807 struct nct1008_data *data = i2c_get_clientdata(client);
1809 mutex_lock(&data->mutex);
1810 data->stop_workqueue = 1;
1811 mutex_unlock(&data->mutex);
1812 cancel_work_sync(&data->work);
1813 disable_irq(client->irq);
1814 err = nct1008_disable(client);
1815 nct1008_power_control(data, false);
1819 static int nct1008_suspend_wakeup(struct device *dev)
1821 struct i2c_client *client = to_i2c_client(dev);
1823 struct nct1008_data *data = i2c_get_clientdata(client);
1826 struct nct1008_sensor_platform_data *sensor_data;
1828 for (sensor_nr = 0; sensor_nr < SENSORS_COUNT; sensor_nr++) {
1829 sensor_data = &data->plat_data.sensors[sensor_nr];
1831 err = nct1008_get_temp_common(sensor_nr, data, &temp);
1836 if (temp > sensor_data->suspend_limit_lo)
1837 err = nct1008_thermal_set_limits(sensor_nr, data,
1838 sensor_data->suspend_limit_lo,
1839 NCT1008_MAX_TEMP * 1000);
1841 err = nct1008_thermal_set_limits(sensor_nr, data,
1842 NCT1008_MIN_TEMP * 1000,
1843 sensor_data->suspend_limit_hi);
1849 /* Enable NCT wake. */
1850 err = enable_irq_wake(client->irq);
1852 dev_err(&client->dev, "Error: %s, error=%d. failed to enable NCT wakeup\n",
1857 dev_err(&client->dev, "\n error in file=: %s %s() line=%d: "
1858 "error=%d. Can't set correct LP1 alarm limits or set wakeup irq, "
1859 "shutting down device", __FILE__, __func__, __LINE__, err);
1861 return nct1008_suspend_powerdown(dev);
1864 static int nct1008_suspend(struct device *dev)
1866 struct i2c_client *client = to_i2c_client(dev);
1867 struct nct1008_data *data = i2c_get_clientdata(client);
1869 if (data->plat_data.suspend_with_wakeup &&
1870 data->plat_data.suspend_with_wakeup())
1871 return nct1008_suspend_wakeup(dev);
1873 return nct1008_suspend_powerdown(dev);
1877 static int nct1008_resume_wakeup(struct device *dev)
1880 struct i2c_client *client = to_i2c_client(dev);
1882 err = disable_irq_wake(client->irq);
1884 dev_err(&client->dev, "Error: %s, error=%d. failed to disable NCT "
1885 "wakeup\n", __func__, err);
1889 /* NCT wasn't powered down, so IRQ is still enabled. */
1890 /* Disable it before calling update */
1891 disable_irq(client->irq);
1896 static int nct1008_resume_powerdown(struct device *dev)
1898 struct i2c_client *client = to_i2c_client(dev);
1900 struct nct1008_data *data = i2c_get_clientdata(client);
1902 nct1008_power_control(data, true);
1903 nct1008_configure_sensor(data);
1904 err = nct1008_enable(client);
1906 dev_err(&client->dev, "Error: %s, error=%d\n",
1914 static int nct1008_resume(struct device *dev)
1916 struct i2c_client *client = to_i2c_client(dev);
1918 struct nct1008_data *data = i2c_get_clientdata(client);
1920 if (data->plat_data.suspend_with_wakeup &&
1921 data->plat_data.suspend_with_wakeup())
1922 err = nct1008_resume_wakeup(dev);
1924 err = nct1008_resume_powerdown(dev);
1929 nct1008_update(LOC, data);
1930 nct1008_update(EXT, data);
1931 mutex_lock(&data->mutex);
1932 data->stop_workqueue = 0;
1933 mutex_unlock(&data->mutex);
1934 enable_irq(client->irq);
1939 static const struct dev_pm_ops nct1008_pm_ops = {
1940 .suspend = nct1008_suspend,
1941 .resume = nct1008_resume,
1946 static const struct i2c_device_id nct1008_id[] = {
1947 { "nct1008", NCT1008 },
1951 MODULE_DEVICE_TABLE(i2c, nct1008_id);
1953 static const struct of_device_id nct1008_of_match[] = {
1954 {.compatible = "onsemi,nct72", },
1958 static struct i2c_driver nct1008_driver = {
1960 .name = "nct1008_nct72",
1961 #ifdef CONFIG_PM_SLEEP
1962 .pm = &nct1008_pm_ops,
1964 .of_match_table = nct1008_of_match,
1966 .probe = nct1008_probe,
1967 .remove = nct1008_remove,
1968 .id_table = nct1008_id,
1969 .shutdown = nct1008_shutdown,
1972 static int __init nct1008_sync_thz(struct device *dev, void *unused)
1974 struct nct1008_data *data = dev_get_drvdata(dev);
1975 if (data->sensors[LOC].thz)
1976 thermal_zone_device_update(data->sensors[LOC].thz);
1977 if (data->sensors[EXT].thz)
1978 thermal_zone_device_update(data->sensors[EXT].thz);
1982 static int __init nct1008_sync(void)
1984 return driver_for_each_device(
1985 &nct1008_driver.driver, NULL, NULL, nct1008_sync_thz);
1987 late_initcall_sync(nct1008_sync);
1989 static int __init nct1008_init(void)
1991 return i2c_add_driver(&nct1008_driver);
1994 static void __exit nct1008_exit(void)
1996 i2c_del_driver(&nct1008_driver);
1999 MODULE_DESCRIPTION("Temperature sensor driver for OnSemi NCT1008/NCT72");
2000 MODULE_LICENSE("GPL");
2002 module_init(nct1008_init);
2003 module_exit(nct1008_exit);