hwmon: ab8500: Convert to IIO ADC

This switches the AB8500 hardware monitor driver to using
the standard IIO ADC channel lookup and conversion routines.

Acked-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Linus Walleij 2019-10-11 09:18:02 +02:00 committed by Jonathan Cameron
parent 1e82623c3c
commit d17e86cb16
2 changed files with 43 additions and 25 deletions

View File

@ -40,7 +40,8 @@ comment "Native drivers"
config SENSORS_AB8500 config SENSORS_AB8500
tristate "AB8500 thermal monitoring" tristate "AB8500 thermal monitoring"
depends on AB8500_GPADC && AB8500_BM depends on AB8500_GPADC && AB8500_BM && (IIO = y)
default n
help help
If you say yes here you get support for the thermal sensor part If you say yes here you get support for the thermal sensor part
of the AB8500 chip. The driver includes thermal management for of the AB8500 chip. The driver includes thermal management for

View File

@ -17,20 +17,24 @@
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/mfd/abx500.h> #include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500-bm.h> #include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/mfd/abx500/ab8500-gpadc.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/power/ab8500.h> #include <linux/power/ab8500.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/iio/consumer.h>
#include "abx500.h" #include "abx500.h"
#define DEFAULT_POWER_OFF_DELAY (HZ * 10) #define DEFAULT_POWER_OFF_DELAY (HZ * 10)
#define THERMAL_VCC 1800 #define THERMAL_VCC 1800
#define PULL_UP_RESISTOR 47000 #define PULL_UP_RESISTOR 47000
/* Number of monitored sensors should not greater than NUM_SENSORS */
#define NUM_MONITORED_SENSORS 4 #define AB8500_SENSOR_AUX1 0
#define AB8500_SENSOR_AUX2 1
#define AB8500_SENSOR_BTEMP_BALL 2
#define AB8500_SENSOR_BAT_CTRL 3
#define NUM_MONITORED_SENSORS 4
struct ab8500_gpadc_cfg { struct ab8500_gpadc_cfg {
const struct abx500_res_to_temp *temp_tbl; const struct abx500_res_to_temp *temp_tbl;
@ -40,7 +44,8 @@ struct ab8500_gpadc_cfg {
}; };
struct ab8500_temp { struct ab8500_temp {
struct ab8500_gpadc *gpadc; struct iio_channel *aux1;
struct iio_channel *aux2;
struct ab8500_btemp *btemp; struct ab8500_btemp *btemp;
struct delayed_work power_off_work; struct delayed_work power_off_work;
struct ab8500_gpadc_cfg cfg; struct ab8500_gpadc_cfg cfg;
@ -82,15 +87,21 @@ static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor, int *temp)
int voltage, ret; int voltage, ret;
struct ab8500_temp *ab8500_data = data->plat_data; struct ab8500_temp *ab8500_data = data->plat_data;
if (sensor == BAT_CTRL) { if (sensor == AB8500_SENSOR_BTEMP_BALL) {
*temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp);
} else if (sensor == BTEMP_BALL) {
*temp = ab8500_btemp_get_temp(ab8500_data->btemp); *temp = ab8500_btemp_get_temp(ab8500_data->btemp);
} else { } else if (sensor == AB8500_SENSOR_BAT_CTRL) {
voltage = ab8500_gpadc_convert(ab8500_data->gpadc, sensor); *temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp);
if (voltage < 0) } else if (sensor == AB8500_SENSOR_AUX1) {
return voltage; ret = iio_read_channel_processed(ab8500_data->aux1, &voltage);
if (ret < 0)
return ret;
ret = ab8500_voltage_to_temp(&ab8500_data->cfg, voltage, temp);
if (ret < 0)
return ret;
} else if (sensor == AB8500_SENSOR_AUX2) {
ret = iio_read_channel_processed(ab8500_data->aux2, &voltage);
if (ret < 0)
return ret;
ret = ab8500_voltage_to_temp(&ab8500_data->cfg, voltage, temp); ret = ab8500_voltage_to_temp(&ab8500_data->cfg, voltage, temp);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -164,10 +175,6 @@ int abx500_hwmon_init(struct abx500_temp *data)
if (!ab8500_data) if (!ab8500_data)
return -ENOMEM; return -ENOMEM;
ab8500_data->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
if (IS_ERR(ab8500_data->gpadc))
return PTR_ERR(ab8500_data->gpadc);
ab8500_data->btemp = ab8500_btemp_get(); ab8500_data->btemp = ab8500_btemp_get();
if (IS_ERR(ab8500_data->btemp)) if (IS_ERR(ab8500_data->btemp))
return PTR_ERR(ab8500_data->btemp); return PTR_ERR(ab8500_data->btemp);
@ -181,15 +188,25 @@ int abx500_hwmon_init(struct abx500_temp *data)
ab8500_data->cfg.tbl_sz = ab8500_temp_tbl_a_size; ab8500_data->cfg.tbl_sz = ab8500_temp_tbl_a_size;
data->plat_data = ab8500_data; data->plat_data = ab8500_data;
ab8500_data->aux1 = devm_iio_channel_get(&data->pdev->dev, "aux1");
if (IS_ERR(ab8500_data->aux1)) {
if (PTR_ERR(ab8500_data->aux1) == -ENODEV)
return -EPROBE_DEFER;
dev_err(&data->pdev->dev, "failed to get AUX1 ADC channel\n");
return PTR_ERR(ab8500_data->aux1);
}
ab8500_data->aux2 = devm_iio_channel_get(&data->pdev->dev, "aux2");
if (IS_ERR(ab8500_data->aux2)) {
if (PTR_ERR(ab8500_data->aux2) == -ENODEV)
return -EPROBE_DEFER;
dev_err(&data->pdev->dev, "failed to get AUX2 ADC channel\n");
return PTR_ERR(ab8500_data->aux2);
}
/* data->gpadc_addr[0] = AB8500_SENSOR_AUX1;
* ADC_AUX1 and ADC_AUX2, connected to external NTC data->gpadc_addr[1] = AB8500_SENSOR_AUX2;
* BTEMP_BALL and BAT_CTRL, fixed usage data->gpadc_addr[2] = AB8500_SENSOR_BTEMP_BALL;
*/ data->gpadc_addr[3] = AB8500_SENSOR_BAT_CTRL;
data->gpadc_addr[0] = ADC_AUX1;
data->gpadc_addr[1] = ADC_AUX2;
data->gpadc_addr[2] = BTEMP_BALL;
data->gpadc_addr[3] = BAT_CTRL;
data->monitored_sensors = NUM_MONITORED_SENSORS; data->monitored_sensors = NUM_MONITORED_SENSORS;
data->ops.read_sensor = ab8500_read_sensor; data->ops.read_sensor = ab8500_read_sensor;