From 7776bcd241e08e13ef009926c6dea84dc3b2f8ff Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 3 Nov 2020 00:48:44 +0100 Subject: power: supply: s3c-adc-battery: Convert to GPIO descriptors This converts the S3C ADC battery to use GPIO descriptors instead of a global GPIO number for the charging completed GPIO. Using the pattern from the GPIO charger we name this GPIO line "charge-status" in the board file. Cc: linux-samsung-soc@vger.kernel.org Cc: Sergiy Kibrik Signed-off-by: Linus Walleij Signed-off-by: Sebastian Reichel --- arch/arm/mach-s3c/mach-h1940.c | 12 ++++++++++-- arch/arm/mach-s3c/mach-rx1950.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-s3c/mach-h1940.c b/arch/arm/mach-s3c/mach-h1940.c index 53d51aa83200..8a43ed1c4c4d 100644 --- a/arch/arm/mach-s3c/mach-h1940.c +++ b/arch/arm/mach-s3c/mach-h1940.c @@ -297,6 +297,15 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = { { .volt = 3841, .cur = 0, .level = 0}, }; +static struct gpiod_lookup_table h1940_bat_gpio_table = { + .dev_id = "s3c-adc-battery", + .table = { + /* Charge status S3C2410_GPF(3) */ + GPIO_LOOKUP("GPIOF", 3, "charge-status", GPIO_ACTIVE_LOW), + { }, + }, +}; + static int h1940_bat_init(void) { int ret; @@ -330,8 +339,6 @@ static struct s3c_adc_bat_pdata h1940_bat_cfg = { .exit = h1940_bat_exit, .enable_charger = h1940_enable_charger, .disable_charger = h1940_disable_charger, - .gpio_charge_finished = S3C2410_GPF(3), - .gpio_inverted = 1, .lut_noac = bat_lut_noac, .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac), .lut_acin = bat_lut_acin, @@ -720,6 +727,7 @@ static void __init h1940_init(void) s3c24xx_fb_set_platdata(&h1940_fb_info); gpiod_add_lookup_table(&h1940_mmc_gpio_table); gpiod_add_lookup_table(&h1940_audio_gpio_table); + gpiod_add_lookup_table(&h1940_bat_gpio_table); /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE); diff --git a/arch/arm/mach-s3c/mach-rx1950.c b/arch/arm/mach-s3c/mach-rx1950.c index b9758f0a9a14..6e19add158a9 100644 --- a/arch/arm/mach-s3c/mach-rx1950.c +++ b/arch/arm/mach-s3c/mach-rx1950.c @@ -206,6 +206,15 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = { { .volt = 3820, .cur = 0, .level = 0}, }; +static struct gpiod_lookup_table rx1950_bat_gpio_table = { + .dev_id = "s3c-adc-battery", + .table = { + /* Charge status S3C2410_GPF(3) */ + GPIO_LOOKUP("GPIOF", 3, "charge-status", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static int rx1950_bat_init(void) { int ret; @@ -331,7 +340,6 @@ static struct s3c_adc_bat_pdata rx1950_bat_cfg = { .exit = rx1950_bat_exit, .enable_charger = rx1950_enable_charger, .disable_charger = rx1950_disable_charger, - .gpio_charge_finished = S3C2410_GPF(3), .lut_noac = bat_lut_noac, .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac), .lut_acin = bat_lut_acin, @@ -840,6 +848,7 @@ static void __init rx1950_init_machine(void) pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup)); gpiod_add_lookup_table(&rx1950_audio_gpio_table); + gpiod_add_lookup_table(&rx1950_bat_gpio_table); /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE); -- cgit v1.2.3 From ba940ed83218f034f728184439c7e87795237752 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 30 Oct 2020 15:34:01 +0100 Subject: power: supply: collie_battery: Convert to GPIO descriptors This converts the Collie battery driver to use GPIO descriptors. We use a mixture of 3 GPIOs defined in the machine and 3 GPIOs requested directly from the ucb1x00 chip. Cc: Robert Jarzmik Cc: Dmitry Eremin-Solenikov Signed-off-by: Linus Walleij Signed-off-by: Sebastian Reichel --- arch/arm/mach-sa1100/collie.c | 21 +++++ drivers/power/supply/collie_battery.c | 151 ++++++++++++++++++++++++---------- 2 files changed, 130 insertions(+), 42 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index bd3a52fd09ce..d4e89a02c8c8 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -98,6 +98,26 @@ static struct mcp_plat_data collie_mcp_data = { .codec_pdata = &collie_ucb1x00_data, }; +/* Battery management GPIOs */ +static struct gpiod_lookup_table collie_battery_gpiod_table = { + /* the MCP codec mcp0 has the ucb1x00 as attached device */ + .dev_id = "ucb1x00", + .table = { + /* This is found on the main GPIO on the SA1100 */ + GPIO_LOOKUP("gpio", COLLIE_GPIO_CO, + "main battery full", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio", COLLIE_GPIO_MAIN_BAT_LOW, + "main battery low", GPIO_ACTIVE_HIGH), + /* + * This is GPIO 0 on the Scoop expander, which is registered + * from common/scoop.c with this gpio chip label. + */ + GPIO_LOOKUP("sharp-scoop", 0, + "main charge on", GPIO_ACTIVE_HIGH), + { }, + }, +}; + static int collie_ir_startup(struct device *dev) { int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA"); @@ -395,6 +415,7 @@ static void __init collie_init(void) platform_scoop_config = &collie_pcmcia_config; gpiod_add_lookup_table(&collie_power_gpiod_table); + gpiod_add_lookup_table(&collie_battery_gpiod_table); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) { diff --git a/drivers/power/supply/collie_battery.c b/drivers/power/supply/collie_battery.c index cbd588e9e233..7fb9b549f2de 100644 --- a/drivers/power/supply/collie_battery.c +++ b/drivers/power/supply/collie_battery.c @@ -12,7 +12,9 @@ #include #include #include -#include +#include +#include +#include #include #include @@ -31,18 +33,18 @@ struct collie_bat { struct mutex work_lock; /* protects data */ bool (*is_present)(struct collie_bat *bat); - int gpio_full; - int gpio_charge_on; + struct gpio_desc *gpio_full; + struct gpio_desc *gpio_charge_on; int technology; - int gpio_bat; + struct gpio_desc *gpio_bat; int adc_bat; int adc_bat_divider; int bat_max; int bat_min; - int gpio_temp; + struct gpio_desc *gpio_temp; int adc_temp; int adc_temp_divider; }; @@ -53,15 +55,15 @@ static unsigned long collie_read_bat(struct collie_bat *bat) { unsigned long value = 0; - if (bat->gpio_bat < 0 || bat->adc_bat < 0) + if (!bat->gpio_bat || bat->adc_bat < 0) return 0; mutex_lock(&bat_lock); - gpio_set_value(bat->gpio_bat, 1); + gpiod_set_value(bat->gpio_bat, 1); msleep(5); ucb1x00_adc_enable(ucb); value = ucb1x00_adc_read(ucb, bat->adc_bat, UCB_SYNC); ucb1x00_adc_disable(ucb); - gpio_set_value(bat->gpio_bat, 0); + gpiod_set_value(bat->gpio_bat, 0); mutex_unlock(&bat_lock); value = value * 1000000 / bat->adc_bat_divider; @@ -71,16 +73,16 @@ static unsigned long collie_read_bat(struct collie_bat *bat) static unsigned long collie_read_temp(struct collie_bat *bat) { unsigned long value = 0; - if (bat->gpio_temp < 0 || bat->adc_temp < 0) + if (!bat->gpio_temp || bat->adc_temp < 0) return 0; mutex_lock(&bat_lock); - gpio_set_value(bat->gpio_temp, 1); + gpiod_set_value(bat->gpio_temp, 1); msleep(5); ucb1x00_adc_enable(ucb); value = ucb1x00_adc_read(ucb, bat->adc_temp, UCB_SYNC); ucb1x00_adc_disable(ucb); - gpio_set_value(bat->gpio_temp, 0); + gpiod_set_value(bat->gpio_temp, 0); mutex_unlock(&bat_lock); value = value * 10000 / bat->adc_temp_divider; @@ -162,23 +164,23 @@ static void collie_bat_update(struct collie_bat *bat) bat->full_chrg = -1; } else if (power_supply_am_i_supplied(psy)) { if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) { - gpio_set_value(bat->gpio_charge_on, 1); + gpiod_set_value(bat->gpio_charge_on, 1); mdelay(15); } - if (gpio_get_value(bat->gpio_full)) { + if (gpiod_get_value(bat->gpio_full)) { if (old == POWER_SUPPLY_STATUS_CHARGING || bat->full_chrg == -1) bat->full_chrg = collie_read_bat(bat); - gpio_set_value(bat->gpio_charge_on, 0); + gpiod_set_value(bat->gpio_charge_on, 0); bat->status = POWER_SUPPLY_STATUS_FULL; } else { - gpio_set_value(bat->gpio_charge_on, 1); + gpiod_set_value(bat->gpio_charge_on, 1); bat->status = POWER_SUPPLY_STATUS_CHARGING; } } else { - gpio_set_value(bat->gpio_charge_on, 0); + gpiod_set_value(bat->gpio_charge_on, 0); bat->status = POWER_SUPPLY_STATUS_DISCHARGING; } @@ -230,18 +232,18 @@ static struct collie_bat collie_bat_main = { .full_chrg = -1, .psy = NULL, - .gpio_full = COLLIE_GPIO_CO, - .gpio_charge_on = COLLIE_GPIO_CHARGE_ON, + .gpio_full = NULL, + .gpio_charge_on = NULL, .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, - .gpio_bat = COLLIE_GPIO_MBAT_ON, + .gpio_bat = NULL, .adc_bat = UCB_ADC_INP_AD1, .adc_bat_divider = 155, .bat_max = 4310000, .bat_min = 1551 * 1000000 / 414, - .gpio_temp = COLLIE_GPIO_TMP_ON, + .gpio_temp = NULL, .adc_temp = UCB_ADC_INP_AD0, .adc_temp_divider = 10000, }; @@ -260,30 +262,24 @@ static struct collie_bat collie_bat_bu = { .full_chrg = -1, .psy = NULL, - .gpio_full = -1, - .gpio_charge_on = -1, + .gpio_full = NULL, + .gpio_charge_on = NULL, .technology = POWER_SUPPLY_TECHNOLOGY_LiMn, - .gpio_bat = COLLIE_GPIO_BBAT_ON, + .gpio_bat = NULL, .adc_bat = UCB_ADC_INP_AD1, .adc_bat_divider = 155, .bat_max = 3000000, .bat_min = 1900000, - .gpio_temp = -1, + .gpio_temp = NULL, .adc_temp = -1, .adc_temp_divider = -1, }; -static struct gpio collie_batt_gpios[] = { - { COLLIE_GPIO_CO, GPIOF_IN, "main battery full" }, - { COLLIE_GPIO_MAIN_BAT_LOW, GPIOF_IN, "main battery low" }, - { COLLIE_GPIO_CHARGE_ON, GPIOF_OUT_INIT_LOW, "main charge on" }, - { COLLIE_GPIO_MBAT_ON, GPIOF_OUT_INIT_LOW, "main battery" }, - { COLLIE_GPIO_TMP_ON, GPIOF_OUT_INIT_LOW, "main battery temp" }, - { COLLIE_GPIO_BBAT_ON, GPIOF_OUT_INIT_LOW, "backup battery" }, -}; +/* Obtained but unused GPIO */ +static struct gpio_desc *collie_mbat_low; #ifdef CONFIG_PM static int wakeup_enabled; @@ -295,7 +291,7 @@ static int collie_bat_suspend(struct ucb1x00_dev *dev) if (device_may_wakeup(&dev->ucb->dev) && collie_bat_main.status == POWER_SUPPLY_STATUS_CHARGING) - wakeup_enabled = !enable_irq_wake(gpio_to_irq(COLLIE_GPIO_CO)); + wakeup_enabled = !enable_irq_wake(gpiod_to_irq(collie_bat_main.gpio_full)); else wakeup_enabled = 0; @@ -305,7 +301,7 @@ static int collie_bat_suspend(struct ucb1x00_dev *dev) static int collie_bat_resume(struct ucb1x00_dev *dev) { if (wakeup_enabled) - disable_irq_wake(gpio_to_irq(COLLIE_GPIO_CO)); + disable_irq_wake(gpiod_to_irq(collie_bat_main.gpio_full)); /* things may have changed while we were away */ schedule_work(&bat_work); @@ -320,16 +316,71 @@ static int collie_bat_probe(struct ucb1x00_dev *dev) { int ret; struct power_supply_config psy_main_cfg = {}, psy_bu_cfg = {}; + struct gpio_chip *gc = &dev->ucb->gpio; if (!machine_is_collie()) return -ENODEV; ucb = dev->ucb; - ret = gpio_request_array(collie_batt_gpios, - ARRAY_SIZE(collie_batt_gpios)); - if (ret) - return ret; + /* Obtain all the main battery GPIOs */ + collie_bat_main.gpio_full = gpiod_get(&dev->ucb->dev, + "main battery full", + GPIOD_IN); + if (IS_ERR(collie_bat_main.gpio_full)) + return PTR_ERR(collie_bat_main.gpio_full); + + collie_mbat_low = gpiod_get(&dev->ucb->dev, + "main battery low", + GPIOD_IN); + if (IS_ERR(collie_mbat_low)) { + ret = PTR_ERR(collie_mbat_low); + goto err_put_gpio_full; + } + + collie_bat_main.gpio_charge_on = gpiod_get(&dev->ucb->dev, + "main charge on", + GPIOD_OUT_LOW); + if (IS_ERR(collie_bat_main.gpio_charge_on)) { + ret = PTR_ERR(collie_bat_main.gpio_charge_on); + goto err_put_mbat_low; + } + + /* COLLIE_GPIO_MBAT_ON = GPIO 7 on the UCB (TC35143) */ + collie_bat_main.gpio_bat = gpiochip_request_own_desc(gc, + 7, + "main battery", + GPIO_ACTIVE_HIGH, + GPIOD_OUT_LOW); + if (IS_ERR(collie_bat_main.gpio_bat)) { + ret = PTR_ERR(collie_bat_main.gpio_bat); + goto err_put_gpio_charge_on; + } + + /* COLLIE_GPIO_TMP_ON = GPIO 9 on the UCB (TC35143) */ + collie_bat_main.gpio_temp = gpiochip_request_own_desc(gc, + 9, + "main battery temp", + GPIO_ACTIVE_HIGH, + GPIOD_OUT_LOW); + if (IS_ERR(collie_bat_main.gpio_temp)) { + ret = PTR_ERR(collie_bat_main.gpio_temp); + goto err_free_gpio_bat; + } + + /* + * Obtain the backup battery COLLIE_GPIO_BBAT_ON which is + * GPIO 8 on the UCB (TC35143) + */ + collie_bat_bu.gpio_bat = gpiochip_request_own_desc(gc, + 8, + "backup battery", + GPIO_ACTIVE_HIGH, + GPIOD_OUT_LOW); + if (IS_ERR(collie_bat_bu.gpio_bat)) { + ret = PTR_ERR(collie_bat_bu.gpio_bat); + goto err_free_gpio_temp; + } mutex_init(&collie_bat_main.work_lock); @@ -370,27 +421,43 @@ err_irq: err_psy_reg_bu: power_supply_unregister(collie_bat_main.psy); err_psy_reg_main: - /* see comment in collie_bat_remove */ cancel_work_sync(&bat_work); - gpio_free_array(collie_batt_gpios, ARRAY_SIZE(collie_batt_gpios)); + gpiochip_free_own_desc(collie_bat_bu.gpio_bat); +err_free_gpio_temp: + gpiochip_free_own_desc(collie_bat_main.gpio_temp); +err_free_gpio_bat: + gpiochip_free_own_desc(collie_bat_main.gpio_bat); +err_put_gpio_charge_on: + gpiod_put(collie_bat_main.gpio_charge_on); +err_put_mbat_low: + gpiod_put(collie_mbat_low); +err_put_gpio_full: + gpiod_put(collie_bat_main.gpio_full); + return ret; } static void collie_bat_remove(struct ucb1x00_dev *dev) { free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main); - power_supply_unregister(collie_bat_bu.psy); power_supply_unregister(collie_bat_main.psy); + /* These are obtained from the machine */ + gpiod_put(collie_bat_main.gpio_full); + gpiod_put(collie_mbat_low); + gpiod_put(collie_bat_main.gpio_charge_on); + /* These are directly from the UCB so let's free them */ + gpiochip_free_own_desc(collie_bat_main.gpio_bat); + gpiochip_free_own_desc(collie_bat_main.gpio_temp); + gpiochip_free_own_desc(collie_bat_bu.gpio_bat); /* * Now cancel the bat_work. We won't get any more schedules, * since all sources (isr and external_power_changed) are * unregistered now. */ cancel_work_sync(&bat_work); - gpio_free_array(collie_batt_gpios, ARRAY_SIZE(collie_batt_gpios)); } static struct ucb1x00_driver collie_bat_driver = { -- cgit v1.2.3