diff options
author | Johan Palsson <johan.palsson@stericsson.com> | 2011-08-25 12:27:06 +0530 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-09-19 16:00:09 +0200 |
commit | 83177878674c623a2aefb37c1ceb10ea48116e41 (patch) | |
tree | 68659ba413c93d3f99dff2e3ec2b3d2e1aec0148 /drivers/hwmon | |
parent | 9b336751fe35a39d1ad67654027c78839c75e21a (diff) |
hwmon: ab8500: Add support to monitor battery temp
ST-Ericsson ID: CR339643
ST-Ericsson Linux next: ER282986
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: Ib6ad58e7a702fe976a1d66fef0ce9d1782a1f8d2
Signed-off-by: Huan DUAN <huan.duan@stericsson.com>
Signed-off-by: Johan Palsson <johan.palsson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/25108
Reviewed-by: QATEST
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/ab8500.c | 107 |
1 files changed, 79 insertions, 28 deletions
diff --git a/drivers/hwmon/ab8500.c b/drivers/hwmon/ab8500.c index 1cfab4948e4..7469ffaa6cb 100644 --- a/drivers/hwmon/ab8500.c +++ b/drivers/hwmon/ab8500.c @@ -38,6 +38,7 @@ #include <linux/jiffies.h> #include <linux/mutex.h> #include <linux/mfd/ab8500/gpadc.h> +#include <linux/mfd/ab8500/bm.h> #include <linux/pm.h> /* @@ -50,13 +51,17 @@ #define NUM_SENSORS 5 -/* The driver monitors GPADC - ADC_AUX1 and ADC_AUX2 */ -#define NUM_MONITORED_SENSORS 2 +/* + * The driver monitors GPADC - ADC_AUX1, ADC_AUX2, BTEMP_BALL + * and BAT_CTRL. + */ +#define NUM_MONITORED_SENSORS 4 struct ab8500_temp { struct platform_device *pdev; struct device *hwmon_dev; struct ab8500_gpadc *gpadc; + struct ab8500_btemp *btemp; u8 gpadc_addr[NUM_SENSORS]; unsigned long min[NUM_SENSORS]; unsigned long max[NUM_SENSORS]; @@ -131,10 +136,21 @@ static void gpadc_monitor(struct work_struct *work) && data->min[i] == 0) continue; - val = ab8500_gpadc_convert(data->gpadc, data->gpadc_addr[i]); - if (val < 0) { - dev_err(&data->pdev->dev, "GPADC read failed\n"); - continue; + /* + * Special treatment for the BAT_CTRL node, since this + * temperature measurement is more complex than just + * an ADC readout + */ + if (data->gpadc_addr[i] == BAT_CTRL) { + val = ab8500_btemp_get_batctrl_temp(data->btemp); + } else { + val = ab8500_gpadc_convert(data->gpadc, + data->gpadc_addr[i]); + if (val < 0) { + dev_err(&data->pdev->dev, + "GPADC read failed\n"); + continue; + } } mutex_lock(&data->lock); @@ -322,11 +338,11 @@ static ssize_t show_label(struct device *dev, name = "bat_temp"; break; case 4: - name = "ab8500"; - break; - case 5: name = "bat_ctrl"; break; + case 5: + name = "ab8500"; + break; default: return -EINVAL; } @@ -342,9 +358,18 @@ static ssize_t show_input(struct device *dev, /* hwmon attr index starts at 1, thus "attr->index-1" below */ u8 gpadc_addr = data->gpadc_addr[attr->index - 1]; - val = ab8500_gpadc_convert(data->gpadc, gpadc_addr); - if (val < 0) - dev_err(&data->pdev->dev, "GPADC read failed\n"); + /* + * Special treatment for the BAT_CTRL node, since this + * temperature measurement is more complex than just + * an ADC readout + */ + if (gpadc_addr == BAT_CTRL) { + val = ab8500_btemp_get_batctrl_temp(data->btemp); + } else { + val = ab8500_gpadc_convert(data->gpadc, gpadc_addr); + if (val < 0) + dev_err(&data->pdev->dev, "GPADC read failed\n"); + } return sprintf(buf, "%d\n", val); } @@ -546,15 +571,31 @@ static SENSOR_DEVICE_ATTR(temp2_max_hyst_alarm, S_IRUGO, /* GPADC - BTEMP_BALL */ static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_label, NULL, 3); static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_input, NULL, 3); +static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min, set_min, 3); +static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max, set_max, 3); +static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IWUSR | S_IRUGO, + show_max_hyst, set_max_hyst, 3); +static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_min_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_max_alarm, NULL, 3); +static SENSOR_DEVICE_ATTR(temp3_max_hyst_alarm, S_IRUGO, + show_max_hyst_alarm, NULL, 3); -/* AB8500 */ +/* GPADC - BAT_CTRL */ static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_label, NULL, 4); -static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO, - show_crit_alarm, NULL, 4); +static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_input, NULL, 4); +static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_min, set_min, 4); +static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_max, set_max, 4); +static SENSOR_DEVICE_ATTR(temp4_max_hyst, S_IWUSR | S_IRUGO, + show_max_hyst, set_max_hyst, 4); +static SENSOR_DEVICE_ATTR(temp4_min_alarm, S_IRUGO, show_min_alarm, NULL, 4); +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 - BAT_CTRL */ +/* AB8500 */ 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_crit_alarm, S_IRUGO, + show_crit_alarm, NULL, 5); static struct attribute *ab8500_temp_attributes[] = { &sensor_dev_attr_temp_power_off_delay.dev_attr.attr, @@ -581,12 +622,24 @@ static struct attribute *ab8500_temp_attributes[] = { /* GPADC - BTEMP_BALL */ &sensor_dev_attr_temp3_label.dev_attr.attr, &sensor_dev_attr_temp3_input.dev_attr.attr, - /* AB8500 */ - &sensor_dev_attr_temp4_label.dev_attr.attr, - &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_min.dev_attr.attr, + &sensor_dev_attr_temp3_max.dev_attr.attr, + &sensor_dev_attr_temp3_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp3_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp3_max_hyst_alarm.dev_attr.attr, /* GPADC - BAT_CTRL */ + &sensor_dev_attr_temp4_label.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp4_min.dev_attr.attr, + &sensor_dev_attr_temp4_max.dev_attr.attr, + &sensor_dev_attr_temp4_max_hyst.dev_attr.attr, + &sensor_dev_attr_temp4_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp4_max_hyst_alarm.dev_attr.attr, + /* AB8500 */ &sensor_dev_attr_temp5_label.dev_attr.attr, - &sensor_dev_attr_temp5_input.dev_attr.attr, + &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr, NULL }; @@ -605,9 +658,9 @@ static irqreturn_t ab8500_temp_irq_handler(int irq, void *irq_data) * used for AB8500 thermal warning from HW. */ mutex_lock(&data->lock); - data->crit_alarm[3] = 1; + data->crit_alarm[4] = 1; mutex_unlock(&data->lock); - sysfs_notify(&pdev->dev.kobj, NULL, "temp4_crit_alarm"); + sysfs_notify(&pdev->dev.kobj, NULL, "temp5_crit_alarm"); dev_info(&pdev->dev, "AB8500 thermal warning, power off in %lu s\n", data->power_off_delay); delay_in_jiffies = msecs_to_jiffies(data->power_off_delay); @@ -645,6 +698,7 @@ static int __devinit ab8500_temp_probe(struct platform_device *pdev) goto exit; data->gpadc = ab8500_gpadc_get(); + data->btemp = ab8500_btemp_get(); data->hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(data->hwmon_dev)) { @@ -665,21 +719,18 @@ static int __devinit ab8500_temp_probe(struct platform_device *pdev) * GPADC - ADC_AUX2, connected to NTC R2150 near DB8500 on HREF * Hence, temp#_min/max/max_hyst refer to millivolts and not * millidegrees + * This is not the case for BAT_CTRL where millidegrees is used * * HREF HW does not support reading AB8500 temperature. BUT an * AB8500 IRQ will be launched if die crit temp limit is reached. * - * Also: - * Battery temperature (BatTemp and BatCtrl) thresholds will - * not be exposed via hwmon. - * * Make sure indexes correspond to the attribute indexes * used when calling SENSOR_DEVICE_ATRR */ data->gpadc_addr[0] = ADC_AUX1; data->gpadc_addr[1] = ADC_AUX2; data->gpadc_addr[2] = BTEMP_BALL; - data->gpadc_addr[4] = BAT_CTRL; + data->gpadc_addr[3] = BAT_CTRL; mutex_init(&data->lock); data->pdev = pdev; data->power_off_delay = DEFAULT_POWER_OFF_DELAY; |