From c671d5c9c8303a965e97635d97384f2a7880ed7a Mon Sep 17 00:00:00 2001 From: Rajagopala V Date: Thu, 25 Aug 2011 13:27:42 +0530 Subject: abx500: hwmon: temperature monitor support for AB5500 Includes support for xtal temp, pcb temp and die temp monitoring ST-Ericsson Linux next: NA ST-Ericsson ID: WP257616 & WP351655 ST-Ericsson FOSS-OUT ID: NA Change-Id: I7668fb36df957b66929bfd13a4b6ad0386036aa1 Signed-off-by: Rajagopala V Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/28139 Reviewed-by: QATEST Reviewed-by: Srinidhi KASAGAR --- drivers/hwmon/ab5500.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 drivers/hwmon/ab5500.c (limited to 'drivers/hwmon/ab5500.c') diff --git a/drivers/hwmon/ab5500.c b/drivers/hwmon/ab5500.c new file mode 100644 index 00000000000..f229d103ec1 --- /dev/null +++ b/drivers/hwmon/ab5500.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * Author: Martin Persson for + * ST-Ericsson. + * License terms: GNU Gereral Public License (GPL) version 2 + * + * Note: + * + * If/when the AB5500 thermal warning temperature is reached (threshold + * 125C cannot be changed by SW), an interrupt is set and the driver + * notifies user space via a sysfs event. If a shut down is not + * triggered by user space and temperature reaches beyond critical + * limit(130C) pm_power off is called. + * + * If/when AB5500 thermal shutdown temperature is reached a hardware + * shutdown of the AB5500 will occur. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "abx500.h" + +/* AB5500 driver monitors GPADC - XTAL_TEMP, PCB_TEMP, + * BTEMP_BALL, BAT_CTRL and DIE_TEMP + */ +#define NUM_MONITORED_SENSORS 5 + +#define SHUTDOWN_AUTO_MIN_LIMIT -25 +#define SHUTDOWN_AUTO_MAX_LIMIT 130 + +static int ab5500_output_convert(int val, u8 sensor) +{ + int res = val; + /* GPADC returns die temperature in Celsius + * convert it to millidegree celsius + */ + if (sensor == DIE_TEMP) + res = val * 1000; + + return res; +} + +static int ab5500_read_sensor(struct abx500_temp *data, u8 sensor) +{ + /* + * TODO: Add support for BAT_CTRL node, since this + * temperature measurement is more complex than just + * an ADC readout + */ + int val = ab5500_gpadc_convert(data->ab5500_gpadc, sensor); + if (val < 0) + return val; + else + return ab5500_output_convert(val, sensor); +} + +static ssize_t ab5500_show_name(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + return sprintf(buf, "ab5500\n"); +} + +static ssize_t ab5500_show_label(struct device *dev, + struct device_attribute *devattr, + char *buf) +{ + char *name; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + int index = attr->index; + + /* + * Make sure these labels correspond to the attribute indexes + * used when calling SENSOR_DEVICE_ATRR. + * Temperature sensors outside ab8500 (read via GPADC) are marked + * with prefix ext_ + */ + switch (index) { + case 1: + name = "xtal_temp"; + break; + case 2: + name = "pcb_temp"; + break; + case 3: + name = "bat_temp"; + break; + case 4: + name = "bat_ctrl"; + break; + case 5: + name = "ab5500"; + break; + default: + return -EINVAL; + } + return sprintf(buf, "%s\n", name); +} + +static int temp_shutdown_trig(int mux) +{ + pm_power_off(); + return 0; +} + +static int ab5500_temp_shutdown_auto(struct abx500_temp *data) +{ + int ret; + struct adc_auto_input *auto_ip; + + auto_ip = kzalloc(sizeof(struct adc_auto_input), GFP_KERNEL); + if (!auto_ip) { + dev_err(&data->pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + auto_ip->mux = DIE_TEMP; + auto_ip->freq = MS500; + auto_ip->min = SHUTDOWN_AUTO_MIN_LIMIT; + auto_ip->max = SHUTDOWN_AUTO_MAX_LIMIT; + auto_ip->auto_adc_callback = temp_shutdown_trig; + data->gpadc_auto = auto_ip; + ret = ab5500_gpadc_convert_auto(data->ab5500_gpadc, + data->gpadc_auto); + if (ret < 0) + kfree(auto_ip); + + return ret; +} + +static int ab5500_temp_irq_handler(int irq, struct abx500_temp *data) +{ + /* + * Make sure the magic numbers below corresponds to the node + * used for AB5500 thermal warning from HW. + */ + mutex_lock(&data->lock); + data->crit_alarm[4] = 1; + mutex_unlock(&data->lock); + sysfs_notify(&data->pdev->dev.kobj, NULL, "temp5_crit_alarm"); + dev_info(&data->pdev->dev, "ABX500 thermal warning," + " power off system now!\n"); + return 0; +} + +int __init abx500_hwmon_init(struct abx500_temp *data) +{ + int err; + + data->ab5500_gpadc = ab5500_gpadc_get("ab5500-adc.0"); + if (IS_ERR(data->ab5500_gpadc)) + return PTR_ERR(data->ab5500_gpadc); + + err = ab5500_temp_shutdown_auto(data); + if (err < 0) { + dev_err(&data->pdev->dev, "Failed to register" + " auto trigger(%d)\n", err); + return err; + } + + /* + * Setup HW defined data. + * + * Reference hardware (HREF): + * + * XTAL_TEMP, PCB_TEMP, BTEMP_BALL refer to millivolts and + * BAT_CTRL and DIE_TEMP refer to millidegrees + * + * Make sure indexes correspond to the attribute indexes + * used when calling SENSOR_DEVICE_ATRR + */ + data->gpadc_addr[0] = XTAL_TEMP; + data->gpadc_addr[1] = PCB_TEMP; + data->gpadc_addr[2] = BTEMP_BALL; + data->gpadc_addr[3] = BAT_CTRL; + data->gpadc_addr[4] = DIE_TEMP; + data->monitored_sensors = NUM_MONITORED_SENSORS; + + data->ops.read_sensor = ab5500_read_sensor; + data->ops.irq_handler = ab5500_temp_irq_handler; + data->ops.show_name = ab5500_show_name; + data->ops.show_label = ab5500_show_label; + + return 0; +} -- cgit v1.2.3 From 185086eac879aecc2604621a092c1795f37acab5 Mon Sep 17 00:00:00 2001 From: Rajagopala V Date: Thu, 25 Aug 2011 13:31:50 +0530 Subject: hwmon: ab5500: support for battery temp monitor add support for battery temperature monitor ST-Ericsson Linux next: NA ST-Ericsson ID: WP257616 ST-Ericsson FOSS-OUT ID: NA Change-Id: I344947ed41b4dd0a49abcb28e57b7b3c697dc57d Signed-off-by: Rajagopala V Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/28233 Reviewed-by: Arun MURTHY Reviewed-by: QATEST Reviewed-by: Srinidhi KASAGAR --- drivers/hwmon/ab5500.c | 14 ++++++++++++-- drivers/hwmon/abx500.h | 2 ++ drivers/power/ab5500_btemp.c | 11 +++++++++++ include/linux/mfd/abx500/ab5500-bm.h | 10 ++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) (limited to 'drivers/hwmon/ab5500.c') diff --git a/drivers/hwmon/ab5500.c b/drivers/hwmon/ab5500.c index f229d103ec1..79540c9a79b 100644 --- a/drivers/hwmon/ab5500.c +++ b/drivers/hwmon/ab5500.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "abx500.h" /* AB5500 driver monitors GPADC - XTAL_TEMP, PCB_TEMP, @@ -47,12 +48,17 @@ static int ab5500_output_convert(int val, u8 sensor) static int ab5500_read_sensor(struct abx500_temp *data, u8 sensor) { + int val; /* - * TODO: Add support for BAT_CTRL node, since this + * Special treatment for BAT_CTRL node, since this * temperature measurement is more complex than just * an ADC readout */ - int val = ab5500_gpadc_convert(data->ab5500_gpadc, sensor); + if (sensor == BAT_CTRL) + val = ab5500_btemp_get_batctrl_temp(data->ab5500_btemp); + else + val = ab5500_gpadc_convert(data->ab5500_gpadc, sensor); + if (val < 0) return val; else @@ -156,6 +162,10 @@ int __init abx500_hwmon_init(struct abx500_temp *data) if (IS_ERR(data->ab5500_gpadc)) return PTR_ERR(data->ab5500_gpadc); + data->ab5500_btemp = ab5500_btemp_get(); + if (IS_ERR(data->ab5500_btemp)) + return PTR_ERR(data->ab5500_btemp); + err = ab5500_temp_shutdown_auto(data); if (err < 0) { dev_err(&data->pdev->dev, "Failed to register" diff --git a/drivers/hwmon/abx500.h b/drivers/hwmon/abx500.h index 1d41aa191fe..77ae7cbd5c1 100644 --- a/drivers/hwmon/abx500.h +++ b/drivers/hwmon/abx500.h @@ -12,6 +12,7 @@ struct ab8500_gpadc; struct ab5500_gpadc; struct ab8500_btemp; +struct ab5500_btemp; struct adc_auto_input; struct abx500_temp; @@ -63,6 +64,7 @@ struct abx500_temp { struct ab8500_gpadc *ab8500_gpadc; struct ab5500_gpadc *ab5500_gpadc; struct ab8500_btemp *ab8500_btemp; + struct ab5500_btemp *ab5500_btemp; struct adc_auto_input *gpadc_auto; struct abx500_temp_ops ops; u8 gpadc_addr[NUM_SENSORS]; diff --git a/drivers/power/ab5500_btemp.c b/drivers/power/ab5500_btemp.c index 04ad6bbb7ac..2e2a5054a58 100644 --- a/drivers/power/ab5500_btemp.c +++ b/drivers/power/ab5500_btemp.c @@ -109,6 +109,17 @@ struct ab5500_btemp *ab5500_btemp_get(void) return di; } +/** + * ab5500_btemp_get_batctrl_temp() - get the temperature + * @di: pointer to the ab5500_btemp structure + * + * Returns the batctrl temperature in millidegrees + */ +int ab5500_btemp_get_batctrl_temp(struct ab5500_btemp *di) +{ + return di->bat_temp * 1000; +} + /** * ab5500_btemp_batctrl_volt_to_res() - convert batctrl voltage to resistance * @di: pointer to the ab5500_btemp structure diff --git a/include/linux/mfd/abx500/ab5500-bm.h b/include/linux/mfd/abx500/ab5500-bm.h index b9800cd8c19..1bb22614b27 100644 --- a/include/linux/mfd/abx500/ab5500-bm.h +++ b/include/linux/mfd/abx500/ab5500-bm.h @@ -100,9 +100,19 @@ #ifdef CONFIG_AB5500_BM void ab5500_charger_usb_state_changed(u8 bm_usb_state, u16 mA); +struct ab5500_btemp *ab5500_btemp_get(void); +int ab5500_btemp_get_batctrl_temp(struct ab5500_btemp *btemp); #else static void ab5500_charger_usb_state_changed(u8 bm_usb_state, u16 mA) { } +inline struct ab5500_btemp *ab5500_btemp_get(void) +{ + return 0; +} +inline int ab5500_btemp_get_batctrl_temp(struct ab5500_btemp *btemp) +{ + return 0; +} #endif #endif /* _AB5500_BM_H */ -- cgit v1.2.3 From 5b1715283ca5ed88398a426ca0ca10c5489afae1 Mon Sep 17 00:00:00 2001 From: Rajagopala V Date: Mon, 26 Sep 2011 18:05:36 +0530 Subject: abx500: support for ab5500 die temp monitoring add support for ab5500 die temperature monitoring as hardware supports reading input temperature ST-Ericsson Linux next: NA ST-Ericsson ID: 339643 ST-Ericsson FOSS-OUT ID: NA Change-Id: I26db88645c4e627829211366bdc1df22ad8ac067 Signed-off-by: Rajagopala V Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/31981 Reviewed-by: Srinidhi KASAGAR --- drivers/hwmon/ab5500.c | 6 ++++++ drivers/hwmon/ab8500.c | 22 ++++++++++++++++------ drivers/hwmon/abx500.c | 25 ++++++++++++++++++++++++- drivers/hwmon/abx500.h | 2 ++ 4 files changed, 48 insertions(+), 7 deletions(-) (limited to 'drivers/hwmon/ab5500.c') diff --git a/drivers/hwmon/ab5500.c b/drivers/hwmon/ab5500.c index 79540c9a79b..7352e07ffde 100644 --- a/drivers/hwmon/ab5500.c +++ b/drivers/hwmon/ab5500.c @@ -139,6 +139,11 @@ static int ab5500_temp_shutdown_auto(struct abx500_temp *data) return ret; } +static int ab5500_is_visible(struct attribute *attr, int n) +{ + return attr->mode; +} + static int ab5500_temp_irq_handler(int irq, struct abx500_temp *data) { /* @@ -195,6 +200,7 @@ int __init abx500_hwmon_init(struct abx500_temp *data) data->ops.irq_handler = ab5500_temp_irq_handler; data->ops.show_name = ab5500_show_name; data->ops.show_label = ab5500_show_label; + data->ops.is_visible = ab5500_is_visible; return 0; } diff --git a/drivers/hwmon/ab8500.c b/drivers/hwmon/ab8500.c index db601e3158d..00647240137 100644 --- a/drivers/hwmon/ab8500.c +++ b/drivers/hwmon/ab8500.c @@ -41,13 +41,8 @@ static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor) * Special treatment for the BAT_CTRL node, since this * temperature measurement is more complex than just * an ADC readout - * - * DIE_TEMP input temperature reading is not supported - * in AB8500 */ - if (sensor == DIE_TEMP) - val = 0; - else if (sensor == BAT_CTRL) + if (sensor == BAT_CTRL) val = ab8500_btemp_get_batctrl_temp(data->ab8500_btemp); else val = ab8500_gpadc_convert(data->ab8500_gpadc, sensor); @@ -107,6 +102,20 @@ static ssize_t ab8500_show_label(struct device *dev, return sprintf(buf, "%s\n", name); } +static int ab8500_is_visible(struct attribute *attr, int n) +{ + if (!strcmp(attr->name, "temp5_input") || + !strcmp(attr->name, "temp5_min") || + !strcmp(attr->name, "temp5_max") || + !strcmp(attr->name, "temp5_max_hyst") || + !strcmp(attr->name, "temp5_min_alarm") || + !strcmp(attr->name, "temp5_max_alarm") || + !strcmp(attr->name, "temp5_max_hyst_alarm")) + return 0; + + return attr->mode; +} + static int ab8500_temp_irq_handler(int irq, struct abx500_temp *data) { unsigned long delay_in_jiffies; @@ -168,6 +177,7 @@ int __init abx500_hwmon_init(struct abx500_temp *data) data->ops.irq_handler = ab8500_temp_irq_handler; data->ops.show_name = ab8500_show_name; data->ops.show_label = ab8500_show_label; + data->ops.is_visible = ab8500_is_visible; return 0; } diff --git a/drivers/hwmon/abx500.c b/drivers/hwmon/abx500.c index 68da2d03dbd..b26a13e8438 100644 --- a/drivers/hwmon/abx500.c +++ b/drivers/hwmon/abx500.c @@ -436,6 +436,14 @@ static ssize_t show_crit_alarm(struct device *dev, return sprintf(buf, "%ld\n", data->crit_alarm[attr->index - 1]); } +static mode_t abx500_attrs_visible(struct kobject *kobj, + struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct abx500_temp *data = dev_get_drvdata(dev); + return data->ops.is_visible(a, n); +} + static SENSOR_DEVICE_ATTR(temp_monitor_delay, S_IRUGO | S_IWUSR, show_temp_monitor_delay, set_temp_monitor_delay, 0); static SENSOR_DEVICE_ATTR(temp_power_off_delay, S_IRUGO | S_IWUSR, @@ -493,9 +501,17 @@ static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_max_alarm, NULL, 4); static SENSOR_DEVICE_ATTR(temp4_max_hyst_alarm, S_IRUGO, show_max_hyst_alarm, NULL, 4); -/* GPADC - SENSOR4 */ +/* GPADC - SENSOR5 */ static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, show_label, NULL, 5); static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_input, NULL, 5); +static SENSOR_DEVICE_ATTR(temp5_min, S_IWUSR | S_IRUGO, show_min, set_min, 4); +static SENSOR_DEVICE_ATTR(temp5_max, S_IWUSR | S_IRUGO, show_max, set_max, 4); +static SENSOR_DEVICE_ATTR(temp5_max_hyst, S_IWUSR | S_IRUGO, + show_max_hyst, set_max_hyst, 4); +static SENSOR_DEVICE_ATTR(temp5_min_alarm, S_IRUGO, show_min_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp5_max_alarm, S_IRUGO, show_max_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp5_max_hyst_alarm, S_IRUGO, + show_max_hyst_alarm, NULL, 4); static SENSOR_DEVICE_ATTR(temp5_crit_alarm, S_IRUGO, show_crit_alarm, NULL, 5); @@ -542,12 +558,19 @@ struct attribute *abx500_temp_attributes[] = { /* GPADC SENSOR5*/ &sensor_dev_attr_temp5_label.dev_attr.attr, &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp5_min.dev_attr.attr, + &sensor_dev_attr_temp5_max.dev_attr.attr, + &sensor_dev_attr_temp5_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp5_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp5_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp5_max_hyst_alarm.dev_attr.attr, &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, NULL }; static const struct attribute_group abx500_temp_group = { .attrs = abx500_temp_attributes, + .is_visible = abx500_attrs_visible, }; static irqreturn_t abx500_temp_irq_handler(int irq, void *irq_data) diff --git a/drivers/hwmon/abx500.h b/drivers/hwmon/abx500.h index 77ae7cbd5c1..65a9a8238ba 100644 --- a/drivers/hwmon/abx500.h +++ b/drivers/hwmon/abx500.h @@ -22,6 +22,7 @@ struct abx500_temp; * @irq_handler: irq handler * @show_name: hwmon device name * @show_label: hwmon attribute label + * @is_visible: is attribute visible */ struct abx500_temp_ops { int (*read_sensor)(struct abx500_temp *, u8); @@ -30,6 +31,7 @@ struct abx500_temp_ops { struct device_attribute *, char *); ssize_t (*show_label) (struct device *, struct device_attribute *, char *); + int (*is_visible)(struct attribute *, int); }; /** -- cgit v1.2.3 From 086d306e1f3574d055df43de7384189ef31f03e6 Mon Sep 17 00:00:00 2001 From: Robert Marklund Date: Wed, 28 Sep 2011 09:48:38 +0200 Subject: hwmon: Make all ux500 mach build at once Alter the hwmon driver so we can build both the MACH_U5500 and the U8500 at the same time. Change-Id: I2ff9665427c1c33181552e7e51074c5eca3f1473 Signed-off-by: Robert Marklund --- drivers/hwmon/ab5500.c | 3 ++- drivers/hwmon/ab8500.c | 3 ++- drivers/hwmon/abx500.c | 7 ++++++- drivers/hwmon/abx500.h | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/hwmon/ab5500.c') diff --git a/drivers/hwmon/ab5500.c b/drivers/hwmon/ab5500.c index 7352e07ffde..0122f315ac6 100644 --- a/drivers/hwmon/ab5500.c +++ b/drivers/hwmon/ab5500.c @@ -25,6 +25,7 @@ #include #include #include "abx500.h" +#include /* AB5500 driver monitors GPADC - XTAL_TEMP, PCB_TEMP, * BTEMP_BALL, BAT_CTRL and DIE_TEMP @@ -159,7 +160,7 @@ static int ab5500_temp_irq_handler(int irq, struct abx500_temp *data) return 0; } -int __init abx500_hwmon_init(struct abx500_temp *data) +int __init ab5500_hwmon_init(struct abx500_temp *data) { int err; diff --git a/drivers/hwmon/ab8500.c b/drivers/hwmon/ab8500.c index 00647240137..8204af594a9 100644 --- a/drivers/hwmon/ab8500.c +++ b/drivers/hwmon/ab8500.c @@ -25,6 +25,7 @@ #include #include #include "abx500.h" +#include #define DEFAULT_POWER_OFF_DELAY 10000 @@ -136,7 +137,7 @@ static int ab8500_temp_irq_handler(int irq, struct abx500_temp *data) return 0; } -int __init abx500_hwmon_init(struct abx500_temp *data) +int __init ab8500_hwmon_init(struct abx500_temp *data) { data->ab8500_gpadc = ab8500_gpadc_get(); if (IS_ERR(data->ab8500_gpadc)) diff --git a/drivers/hwmon/abx500.c b/drivers/hwmon/abx500.c index b26a13e8438..de4e6280b4b 100644 --- a/drivers/hwmon/abx500.c +++ b/drivers/hwmon/abx500.c @@ -36,6 +36,8 @@ #include #include #include +#include + #include "abx500.h" #define DEFAULT_MONITOR_DELAY 1000 @@ -610,7 +612,10 @@ static int __devinit abx500_temp_probe(struct platform_device *pdev) mutex_init(&data->lock); /* Chip specific initialization */ - err = abx500_hwmon_init(data); + if (!machine_is_u5500()) + err = ab8500_hwmon_init(data); + else + err = ab5500_hwmon_init(data); if (err < 0) { dev_err(&pdev->dev, "abx500 init failed"); goto exit; diff --git a/drivers/hwmon/abx500.h b/drivers/hwmon/abx500.h index 65a9a8238ba..9fe28dac28f 100644 --- a/drivers/hwmon/abx500.h +++ b/drivers/hwmon/abx500.h @@ -89,6 +89,7 @@ struct abx500_temp { int monitored_sensors; }; -int abx500_hwmon_init(struct abx500_temp *data) __init; +int ab8500_hwmon_init(struct abx500_temp *data) __init; +int ab5500_hwmon_init(struct abx500_temp *data) __init; #endif /* _ABX500_H */ -- cgit v1.2.3 From b341172c469db547de725da483a86df54659436d Mon Sep 17 00:00:00 2001 From: Rajagopala V Date: Thu, 10 Nov 2011 17:57:52 +0530 Subject: u5500:hwmon: Fix ab5500 die temp auto trigger GPADC voltage decreases as temperature increases. So pass min and max values accordingly to monitor ab5500 internal die temperature. ST-Ericsson Linux next: NA ST-Ericsson ID: 372448 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I9743bcbeb3f27baaba9b49867b656135c2d2d70e Signed-off-by: Rajagopala V Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/37297 Reviewed-by: QABUILD Reviewed-by: QATOOLS Reviewed-by: Srinidhi KASAGAR Reviewed-by: Vijaya Kumar K-1 Reviewed-by: Arun MURTHY --- drivers/hwmon/ab5500.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/hwmon/ab5500.c') diff --git a/drivers/hwmon/ab5500.c b/drivers/hwmon/ab5500.c index 0122f315ac6..cafadeba51c 100644 --- a/drivers/hwmon/ab5500.c +++ b/drivers/hwmon/ab5500.c @@ -128,8 +128,13 @@ static int ab5500_temp_shutdown_auto(struct abx500_temp *data) auto_ip->mux = DIE_TEMP; auto_ip->freq = MS500; - auto_ip->min = SHUTDOWN_AUTO_MIN_LIMIT; - auto_ip->max = SHUTDOWN_AUTO_MAX_LIMIT; + /* + * As per product specification, voltage decreases as + * temperature increases. Hence the min and max values + * should be passed in reverse order. + */ + auto_ip->min = SHUTDOWN_AUTO_MAX_LIMIT; + auto_ip->max = SHUTDOWN_AUTO_MIN_LIMIT; auto_ip->auto_adc_callback = temp_shutdown_trig; data->gpadc_auto = auto_ip; ret = ab5500_gpadc_convert_auto(data->ab5500_gpadc, -- cgit v1.2.3