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@xxxxxxxxxxxxxxx Cc: Sergiy Kibrik <sakib@xxxxxxxxxxxxx> Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> --- arch/arm/mach-s3c/mach-h1940.c | 12 +++++- arch/arm/mach-s3c/mach-rx1950.c | 11 ++++- drivers/power/supply/s3c_adc_battery.c | 57 +++++++++++++------------- include/linux/s3c_adc_battery.h | 3 -- 4 files changed, 49 insertions(+), 34 deletions(-) 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); diff --git a/drivers/power/supply/s3c_adc_battery.c b/drivers/power/supply/s3c_adc_battery.c index 60b7f41ab063..a2addc24ee8b 100644 --- a/drivers/power/supply/s3c_adc_battery.c +++ b/drivers/power/supply/s3c_adc_battery.c @@ -13,7 +13,7 @@ #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/leds.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/err.h> #include <linux/timer.h> #include <linux/jiffies.h> @@ -31,6 +31,7 @@ struct s3c_adc_bat { struct power_supply *psy; struct s3c_adc_client *client; struct s3c_adc_bat_pdata *pdata; + struct gpio_desc *charge_finished; int volt_value; int cur_value; unsigned int timestamp; @@ -132,9 +133,7 @@ static int calc_full_volt(int volt_val, int cur_val, int impedance) static int charge_finished(struct s3c_adc_bat *bat) { - return bat->pdata->gpio_inverted ? - !gpio_get_value(bat->pdata->gpio_charge_finished) : - gpio_get_value(bat->pdata->gpio_charge_finished); + return gpiod_get_value(bat->charge_finished); } static int s3c_adc_bat_get_property(struct power_supply *psy, @@ -169,7 +168,7 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, } if (bat->cable_plugged && - ((bat->pdata->gpio_charge_finished < 0) || + (!bat->charge_finished || !charge_finished(bat))) { lut = bat->pdata->lut_acin; lut_size = bat->pdata->lut_acin_cnt; @@ -206,7 +205,7 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_STATUS: - if (bat->pdata->gpio_charge_finished < 0) + if (!bat->charge_finished) val->intval = bat->level == 100000 ? POWER_SUPPLY_STATUS_FULL : bat->status; else @@ -265,7 +264,7 @@ static void s3c_adc_bat_work(struct work_struct *work) bat->status = POWER_SUPPLY_STATUS_DISCHARGING; } } else { - if ((bat->pdata->gpio_charge_finished >= 0) && is_plugged) { + if (bat->charge_finished && is_plugged) { is_charged = charge_finished(&main_bat); if (is_charged) { if (bat->pdata->disable_charger) @@ -294,6 +293,7 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) struct s3c_adc_client *client; struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; struct power_supply_config psy_cfg = {}; + struct gpio_desc *gpiod; int ret; client = s3c_adc_register(pdev, NULL, NULL, 0); @@ -304,8 +304,17 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) platform_set_drvdata(pdev, client); + gpiod = devm_gpiod_get_optional(&pdev->dev, "charge-status", GPIOD_IN); + if (IS_ERR(gpiod)) { + /* Could be probe deferral etc */ + ret = PTR_ERR(gpiod); + dev_err(&pdev->dev, "no GPIO %d\n", ret); + return ret; + } + main_bat.client = client; main_bat.pdata = pdata; + main_bat.charge_finished = gpiod; main_bat.volt_value = -1; main_bat.cur_value = -1; main_bat.cable_plugged = 0; @@ -323,6 +332,7 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) backup_bat.client = client; backup_bat.pdata = pdev->dev.platform_data; + backup_bat.charge_finished = gpiod; backup_bat.volt_value = -1; backup_bat.psy = power_supply_register(&pdev->dev, &backup_bat_desc, @@ -335,12 +345,8 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&bat_work, s3c_adc_bat_work); - if (pdata->gpio_charge_finished >= 0) { - ret = gpio_request(pdata->gpio_charge_finished, "charged"); - if (ret) - goto err_gpio; - - ret = request_irq(gpio_to_irq(pdata->gpio_charge_finished), + if (gpiod) { + ret = request_irq(gpiod_to_irq(gpiod), s3c_adc_bat_charged, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "battery charged", NULL); @@ -364,12 +370,9 @@ static int s3c_adc_bat_probe(struct platform_device *pdev) return 0; err_platform: - if (pdata->gpio_charge_finished >= 0) - free_irq(gpio_to_irq(pdata->gpio_charge_finished), NULL); + if (gpiod) + free_irq(gpiod_to_irq(gpiod), NULL); err_irq: - if (pdata->gpio_charge_finished >= 0) - gpio_free(pdata->gpio_charge_finished); -err_gpio: if (pdata->backup_volt_mult) power_supply_unregister(backup_bat.psy); err_reg_backup: @@ -389,10 +392,8 @@ static int s3c_adc_bat_remove(struct platform_device *pdev) s3c_adc_release(client); - if (pdata->gpio_charge_finished >= 0) { - free_irq(gpio_to_irq(pdata->gpio_charge_finished), NULL); - gpio_free(pdata->gpio_charge_finished); - } + if (main_bat.charge_finished) + free_irq(gpiod_to_irq(main_bat.charge_finished), NULL); cancel_delayed_work(&bat_work); @@ -408,12 +409,12 @@ static int s3c_adc_bat_suspend(struct platform_device *pdev, { struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; - if (pdata->gpio_charge_finished >= 0) { + if (main_bat.charge_finished) { if (device_may_wakeup(&pdev->dev)) enable_irq_wake( - gpio_to_irq(pdata->gpio_charge_finished)); + gpiod_to_irq(main_bat.charge_finished)); else { - disable_irq(gpio_to_irq(pdata->gpio_charge_finished)); + disable_irq(gpiod_to_irq(main_bat.charge_finished)); main_bat.pdata->disable_charger(); } } @@ -425,12 +426,12 @@ static int s3c_adc_bat_resume(struct platform_device *pdev) { struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; - if (pdata->gpio_charge_finished >= 0) { + if (main_bat.charge_finished) { if (device_may_wakeup(&pdev->dev)) disable_irq_wake( - gpio_to_irq(pdata->gpio_charge_finished)); + gpiod_to_irq(main_bat.charge_finished)); else - enable_irq(gpio_to_irq(pdata->gpio_charge_finished)); + enable_irq(gpiod_to_irq(main_bat.charge_finished)); } /* Schedule timer to check current status */ diff --git a/include/linux/s3c_adc_battery.h b/include/linux/s3c_adc_battery.h index 833871dcf6fd..57f982c375f8 100644 --- a/include/linux/s3c_adc_battery.h +++ b/include/linux/s3c_adc_battery.h @@ -14,9 +14,6 @@ struct s3c_adc_bat_pdata { void (*enable_charger)(void); void (*disable_charger)(void); - int gpio_charge_finished; - int gpio_inverted; - const struct s3c_adc_bat_thresh *lut_noac; unsigned int lut_noac_cnt; const struct s3c_adc_bat_thresh *lut_acin; -- 2.26.2