Loading Documentation/devicetree/bindings/mfd/ab8500.txt +119 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,18 @@ Required child device properties: - compatible : "stericsson,ab8500-[bm|btemp|charger|fg|gpadc|gpio|ponkey| pwm|regulator|rtc|sysctrl|usb]"; A few child devices require ADC channels from the GPADC node. Those follow the standard bindings from iio/iio-bindings.txt and iio/adc/adc.txt abx500-temp : io-channels "aux1" and "aux2" for measuring external temperatures. ab8500-fg : io-channel "main_bat_v" for measuring main battery voltage, ab8500-btemp : io-channels "btemp_ball" and "bat_ctrl" for measuring the battery voltage. ab8500-charger : io-channels "main_charger_v", "main_charger_c", "vbus_v", "usb_charger_c" for measuring voltage and current of the different charging supplies. Optional child device properties: - interrupts : contains the device IRQ(s) using the 2-cell format (see above) - interrupt-names : contains names of IRQ resource in the order in which they were Loading Loading @@ -102,6 +114,113 @@ ab8500 { 39 0x4>; interrupt-names = "HW_CONV_END", "SW_CONV_END"; vddadc-supply = <&ab8500_ldo_tvout_reg>; #address-cells = <1>; #size-cells = <0>; #io-channel-cells = <1>; /* GPADC channels */ bat_ctrl: channel@1 { reg = <0x01>; }; btemp_ball: channel@2 { reg = <0x02>; }; main_charger_v: channel@3 { reg = <0x03>; }; acc_detect1: channel@4 { reg = <0x04>; }; acc_detect2: channel@5 { reg = <0x05>; }; adc_aux1: channel@6 { reg = <0x06>; }; adc_aux2: channel@7 { reg = <0x07>; }; main_batt_v: channel@8 { reg = <0x08>; }; vbus_v: channel@9 { reg = <0x09>; }; main_charger_c: channel@a { reg = <0x0a>; }; usb_charger_c: channel@b { reg = <0x0b>; }; bk_bat_v: channel@c { reg = <0x0c>; }; die_temp: channel@d { reg = <0x0d>; }; usb_id: channel@e { reg = <0x0e>; }; xtal_temp: channel@12 { reg = <0x12>; }; vbat_true_meas: channel@13 { reg = <0x13>; }; bat_ctrl_and_ibat: channel@1c { reg = <0x1c>; }; vbat_meas_and_ibat: channel@1d { reg = <0x1d>; }; vbat_true_meas_and_ibat: channel@1e { reg = <0x1e>; }; bat_temp_and_ibat: channel@1f { reg = <0x1f>; }; }; ab8500_temp { compatible = "stericsson,abx500-temp"; io-channels = <&gpadc 0x06>, <&gpadc 0x07>; io-channel-name = "aux1", "aux2"; }; ab8500_battery: ab8500_battery { stericsson,battery-type = "LIPO"; thermistor-on-batctrl; }; ab8500_fg { compatible = "stericsson,ab8500-fg"; battery = <&ab8500_battery>; io-channels = <&gpadc 0x08>; io-channel-name = "main_bat_v"; }; ab8500_btemp { compatible = "stericsson,ab8500-btemp"; battery = <&ab8500_battery>; io-channels = <&gpadc 0x02>, <&gpadc 0x01>; io-channel-name = "btemp_ball", "bat_ctrl"; }; ab8500_charger { compatible = "stericsson,ab8500-charger"; battery = <&ab8500_battery>; vddadc-supply = <&ab8500_ldo_tvout_reg>; io-channels = <&gpadc 0x03>, <&gpadc 0x0a>, <&gpadc 0x09>, <&gpadc 0x0b>; io-channel-name = "main_charger_v", "main_charger_c", "vbus_v", "usb_charger_c"; }; ab8500-usb { Loading MAINTAINERS +1 −0 Original line number Diff line number Diff line Loading @@ -2005,6 +2005,7 @@ F: drivers/dma/ste_dma40* F: drivers/hwspinlock/u8500_hsem.c F: drivers/i2c/busses/i2c-nomadik.c F: drivers/i2c/busses/i2c-stu300.c F: drivers/iio/adc/ab8500-gpadc.c F: drivers/mfd/ab3100* F: drivers/mfd/ab8500* F: drivers/mfd/abx500* Loading drivers/hwmon/Kconfig +2 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,8 @@ comment "Native drivers" config SENSORS_AB8500 tristate "AB8500 thermal monitoring" depends on AB8500_GPADC && AB8500_BM depends on AB8500_GPADC && AB8500_BM && (IIO = y) default n help If you say yes here you get support for the thermal sensor part of the AB8500 chip. The driver includes thermal management for Loading drivers/hwmon/ab8500.c +41 −24 Original line number Diff line number Diff line Loading @@ -17,19 +17,23 @@ #include <linux/hwmon-sysfs.h> #include <linux/mfd/abx500.h> #include <linux/mfd/abx500/ab8500-bm.h> #include <linux/mfd/abx500/ab8500-gpadc.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/power/ab8500.h> #include <linux/reboot.h> #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/iio/consumer.h> #include "abx500.h" #define DEFAULT_POWER_OFF_DELAY (HZ * 10) #define THERMAL_VCC 1800 #define PULL_UP_RESISTOR 47000 /* Number of monitored sensors should not greater than NUM_SENSORS */ #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 { Loading @@ -40,7 +44,8 @@ struct ab8500_gpadc_cfg { }; struct ab8500_temp { struct ab8500_gpadc *gpadc; struct iio_channel *aux1; struct iio_channel *aux2; struct ab8500_btemp *btemp; struct delayed_work power_off_work; struct ab8500_gpadc_cfg cfg; Loading Loading @@ -82,15 +87,21 @@ static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor, int *temp) int voltage, ret; struct ab8500_temp *ab8500_data = data->plat_data; if (sensor == BAT_CTRL) { *temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp); } else if (sensor == BTEMP_BALL) { if (sensor == AB8500_SENSOR_BTEMP_BALL) { *temp = ab8500_btemp_get_temp(ab8500_data->btemp); } else { voltage = ab8500_gpadc_convert(ab8500_data->gpadc, sensor); if (voltage < 0) return voltage; } else if (sensor == AB8500_SENSOR_BAT_CTRL) { *temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp); } else if (sensor == AB8500_SENSOR_AUX1) { 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); if (ret < 0) return ret; Loading Loading @@ -164,10 +175,6 @@ int abx500_hwmon_init(struct abx500_temp *data) if (!ab8500_data) 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(); if (IS_ERR(ab8500_data->btemp)) return PTR_ERR(ab8500_data->btemp); Loading @@ -181,15 +188,25 @@ int abx500_hwmon_init(struct abx500_temp *data) ab8500_data->cfg.tbl_sz = ab8500_temp_tbl_a_size; 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); } /* * ADC_AUX1 and ADC_AUX2, connected to external NTC * BTEMP_BALL and BAT_CTRL, fixed usage */ 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->gpadc_addr[0] = AB8500_SENSOR_AUX1; data->gpadc_addr[1] = AB8500_SENSOR_AUX2; data->gpadc_addr[2] = AB8500_SENSOR_BTEMP_BALL; data->gpadc_addr[3] = AB8500_SENSOR_BAT_CTRL; data->monitored_sensors = NUM_MONITORED_SENSORS; data->ops.read_sensor = ab8500_read_sensor; Loading drivers/iio/adc/Kconfig +10 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,16 @@ menu "Analog to digital converters" config AB8500_GPADC bool "ST-Ericsson AB8500 GPADC driver" depends on AB8500_CORE && REGULATOR_AB8500 default y help AB8500 Analog Baseband, mixed signal integrated circuit GPADC (General Purpose Analog to Digital Converter) driver used to monitor internal voltages, convert accessory and battery, AC (charger, mains) and USB voltages integral to the U8500 platform. config AD_SIGMA_DELTA tristate select IIO_BUFFER Loading Loading
Documentation/devicetree/bindings/mfd/ab8500.txt +119 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,18 @@ Required child device properties: - compatible : "stericsson,ab8500-[bm|btemp|charger|fg|gpadc|gpio|ponkey| pwm|regulator|rtc|sysctrl|usb]"; A few child devices require ADC channels from the GPADC node. Those follow the standard bindings from iio/iio-bindings.txt and iio/adc/adc.txt abx500-temp : io-channels "aux1" and "aux2" for measuring external temperatures. ab8500-fg : io-channel "main_bat_v" for measuring main battery voltage, ab8500-btemp : io-channels "btemp_ball" and "bat_ctrl" for measuring the battery voltage. ab8500-charger : io-channels "main_charger_v", "main_charger_c", "vbus_v", "usb_charger_c" for measuring voltage and current of the different charging supplies. Optional child device properties: - interrupts : contains the device IRQ(s) using the 2-cell format (see above) - interrupt-names : contains names of IRQ resource in the order in which they were Loading Loading @@ -102,6 +114,113 @@ ab8500 { 39 0x4>; interrupt-names = "HW_CONV_END", "SW_CONV_END"; vddadc-supply = <&ab8500_ldo_tvout_reg>; #address-cells = <1>; #size-cells = <0>; #io-channel-cells = <1>; /* GPADC channels */ bat_ctrl: channel@1 { reg = <0x01>; }; btemp_ball: channel@2 { reg = <0x02>; }; main_charger_v: channel@3 { reg = <0x03>; }; acc_detect1: channel@4 { reg = <0x04>; }; acc_detect2: channel@5 { reg = <0x05>; }; adc_aux1: channel@6 { reg = <0x06>; }; adc_aux2: channel@7 { reg = <0x07>; }; main_batt_v: channel@8 { reg = <0x08>; }; vbus_v: channel@9 { reg = <0x09>; }; main_charger_c: channel@a { reg = <0x0a>; }; usb_charger_c: channel@b { reg = <0x0b>; }; bk_bat_v: channel@c { reg = <0x0c>; }; die_temp: channel@d { reg = <0x0d>; }; usb_id: channel@e { reg = <0x0e>; }; xtal_temp: channel@12 { reg = <0x12>; }; vbat_true_meas: channel@13 { reg = <0x13>; }; bat_ctrl_and_ibat: channel@1c { reg = <0x1c>; }; vbat_meas_and_ibat: channel@1d { reg = <0x1d>; }; vbat_true_meas_and_ibat: channel@1e { reg = <0x1e>; }; bat_temp_and_ibat: channel@1f { reg = <0x1f>; }; }; ab8500_temp { compatible = "stericsson,abx500-temp"; io-channels = <&gpadc 0x06>, <&gpadc 0x07>; io-channel-name = "aux1", "aux2"; }; ab8500_battery: ab8500_battery { stericsson,battery-type = "LIPO"; thermistor-on-batctrl; }; ab8500_fg { compatible = "stericsson,ab8500-fg"; battery = <&ab8500_battery>; io-channels = <&gpadc 0x08>; io-channel-name = "main_bat_v"; }; ab8500_btemp { compatible = "stericsson,ab8500-btemp"; battery = <&ab8500_battery>; io-channels = <&gpadc 0x02>, <&gpadc 0x01>; io-channel-name = "btemp_ball", "bat_ctrl"; }; ab8500_charger { compatible = "stericsson,ab8500-charger"; battery = <&ab8500_battery>; vddadc-supply = <&ab8500_ldo_tvout_reg>; io-channels = <&gpadc 0x03>, <&gpadc 0x0a>, <&gpadc 0x09>, <&gpadc 0x0b>; io-channel-name = "main_charger_v", "main_charger_c", "vbus_v", "usb_charger_c"; }; ab8500-usb { Loading
MAINTAINERS +1 −0 Original line number Diff line number Diff line Loading @@ -2005,6 +2005,7 @@ F: drivers/dma/ste_dma40* F: drivers/hwspinlock/u8500_hsem.c F: drivers/i2c/busses/i2c-nomadik.c F: drivers/i2c/busses/i2c-stu300.c F: drivers/iio/adc/ab8500-gpadc.c F: drivers/mfd/ab3100* F: drivers/mfd/ab8500* F: drivers/mfd/abx500* Loading
drivers/hwmon/Kconfig +2 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,8 @@ comment "Native drivers" config SENSORS_AB8500 tristate "AB8500 thermal monitoring" depends on AB8500_GPADC && AB8500_BM depends on AB8500_GPADC && AB8500_BM && (IIO = y) default n help If you say yes here you get support for the thermal sensor part of the AB8500 chip. The driver includes thermal management for Loading
drivers/hwmon/ab8500.c +41 −24 Original line number Diff line number Diff line Loading @@ -17,19 +17,23 @@ #include <linux/hwmon-sysfs.h> #include <linux/mfd/abx500.h> #include <linux/mfd/abx500/ab8500-bm.h> #include <linux/mfd/abx500/ab8500-gpadc.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/power/ab8500.h> #include <linux/reboot.h> #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/iio/consumer.h> #include "abx500.h" #define DEFAULT_POWER_OFF_DELAY (HZ * 10) #define THERMAL_VCC 1800 #define PULL_UP_RESISTOR 47000 /* Number of monitored sensors should not greater than NUM_SENSORS */ #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 { Loading @@ -40,7 +44,8 @@ struct ab8500_gpadc_cfg { }; struct ab8500_temp { struct ab8500_gpadc *gpadc; struct iio_channel *aux1; struct iio_channel *aux2; struct ab8500_btemp *btemp; struct delayed_work power_off_work; struct ab8500_gpadc_cfg cfg; Loading Loading @@ -82,15 +87,21 @@ static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor, int *temp) int voltage, ret; struct ab8500_temp *ab8500_data = data->plat_data; if (sensor == BAT_CTRL) { *temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp); } else if (sensor == BTEMP_BALL) { if (sensor == AB8500_SENSOR_BTEMP_BALL) { *temp = ab8500_btemp_get_temp(ab8500_data->btemp); } else { voltage = ab8500_gpadc_convert(ab8500_data->gpadc, sensor); if (voltage < 0) return voltage; } else if (sensor == AB8500_SENSOR_BAT_CTRL) { *temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp); } else if (sensor == AB8500_SENSOR_AUX1) { 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); if (ret < 0) return ret; Loading Loading @@ -164,10 +175,6 @@ int abx500_hwmon_init(struct abx500_temp *data) if (!ab8500_data) 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(); if (IS_ERR(ab8500_data->btemp)) return PTR_ERR(ab8500_data->btemp); Loading @@ -181,15 +188,25 @@ int abx500_hwmon_init(struct abx500_temp *data) ab8500_data->cfg.tbl_sz = ab8500_temp_tbl_a_size; 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); } /* * ADC_AUX1 and ADC_AUX2, connected to external NTC * BTEMP_BALL and BAT_CTRL, fixed usage */ 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->gpadc_addr[0] = AB8500_SENSOR_AUX1; data->gpadc_addr[1] = AB8500_SENSOR_AUX2; data->gpadc_addr[2] = AB8500_SENSOR_BTEMP_BALL; data->gpadc_addr[3] = AB8500_SENSOR_BAT_CTRL; data->monitored_sensors = NUM_MONITORED_SENSORS; data->ops.read_sensor = ab8500_read_sensor; Loading
drivers/iio/adc/Kconfig +10 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,16 @@ menu "Analog to digital converters" config AB8500_GPADC bool "ST-Ericsson AB8500 GPADC driver" depends on AB8500_CORE && REGULATOR_AB8500 default y help AB8500 Analog Baseband, mixed signal integrated circuit GPADC (General Purpose Analog to Digital Converter) driver used to monitor internal voltages, convert accessory and battery, AC (charger, mains) and USB voltages integral to the U8500 platform. config AD_SIGMA_DELTA tristate select IIO_BUFFER Loading