diff options
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/supply/Kconfig | 28 | ||||
-rw-r--r-- | drivers/power/supply/Makefile | 4 | ||||
-rw-r--r-- | drivers/power/supply/ds2760_battery.c | 8 | ||||
-rw-r--r-- | drivers/power/supply/pda_power.c | 520 | ||||
-rw-r--r-- | drivers/power/supply/s3c_adc_battery.c | 453 | ||||
-rw-r--r-- | drivers/power/supply/tosa_battery.c | 512 | ||||
-rw-r--r-- | drivers/power/supply/z2_battery.c | 318 |
7 files changed, 0 insertions, 1843 deletions
diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 0bbfe6a7ce4d..e2f8dfcdd2a9 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -28,15 +28,6 @@ config POWER_SUPPLY_HWMON Say 'Y' here if you want power supplies to have hwmon sysfs interface too. - -config PDA_POWER - tristate "Generic PDA/phone power driver" - depends on !S390 - help - Say Y here to enable generic power driver for PDAs and phones with - one or two external power supplies (AC/USB) connected to main and - backup batteries, and optional builtin charger. - config APM_POWER tristate "APM emulation for class batteries" depends on APM_EMULATION @@ -195,13 +186,6 @@ config BATTERY_SAMSUNG_SDI Say Y to enable support for Samsung SDI battery data. These batteries are used in Samsung mobile phones. -config BATTERY_TOSA - tristate "Sharp SL-6000 (tosa) battery" - depends on MACH_TOSA && MFD_TC6393XB && TOUCHSCREEN_WM97XX - help - Say Y to enable support for the battery on the Sharp Zaurus - SL-6000 (tosa) models. - config BATTERY_COLLIE tristate "Sharp SL-5500 (collie) battery" depends on SA1100_COLLIE && MCP_UCB1200 @@ -422,18 +406,6 @@ config BATTERY_MAX1721X Say Y here to enable support for the MAX17211/MAX17215 standalone battery gas-gauge. -config BATTERY_Z2 - tristate "Z2 battery driver" - depends on I2C && MACH_ZIPIT2 - help - Say Y to include support for the battery on the Zipit Z2. - -config BATTERY_S3C_ADC - tristate "Battery driver for Samsung ADC based monitoring" - depends on S3C_ADC - help - Say Y here to enable support for iPAQ h1930/h1940/rx1950 battery - config BATTERY_TWL4030_MADC tristate "TWL4030 MADC battery driver" depends on TWL4030_MADC diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index 0ee8653e882e..8cb3c7f5c111 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_POWER_SUPPLY) += power_supply.o obj-$(CONFIG_POWER_SUPPLY_HWMON) += power_supply_hwmon.o obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o -obj-$(CONFIG_PDA_POWER) += pda_power.o obj-$(CONFIG_APM_POWER) += apm_power.o obj-$(CONFIG_AXP20X_POWER) += axp20x_usb_power.o obj-$(CONFIG_IP5XXX_POWER) += ip5xxx_power.o @@ -36,7 +35,6 @@ obj-$(CONFIG_BATTERY_LEGO_EV3) += lego_ev3_battery.o obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o obj-$(CONFIG_BATTERY_SAMSUNG_SDI) += samsung-sdi-battery.o -obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o obj-$(CONFIG_BATTERY_INGENIC) += ingenic-battery.o obj-$(CONFIG_BATTERY_IPAQ_MICRO) += ipaq_micro_battery.o @@ -54,10 +52,8 @@ obj-$(CONFIG_BATTERY_DA9150) += da9150-fg.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o obj-$(CONFIG_BATTERY_MAX1721X) += max1721x_battery.o -obj-$(CONFIG_BATTERY_Z2) += z2_battery.o obj-$(CONFIG_BATTERY_RT5033) += rt5033_battery.o obj-$(CONFIG_CHARGER_RT9455) += rt9455_charger.o -obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o diff --git a/drivers/power/supply/ds2760_battery.c b/drivers/power/supply/ds2760_battery.c index 5f50da524f41..40fba31be174 100644 --- a/drivers/power/supply/ds2760_battery.c +++ b/drivers/power/supply/ds2760_battery.c @@ -227,20 +227,12 @@ static int rated_capacities[] = { 920, /* NEC */ 1440, /* Samsung */ 1440, /* BYD */ -#ifdef CONFIG_MACH_H4700 - 1800, /* HP iPAQ hx4700 3.7V 1800mAh (359113-001) */ -#else 1440, /* Lishen */ -#endif 1440, /* NEC */ 2880, /* Samsung */ 2880, /* BYD */ 2880, /* Lishen */ 2880, /* NEC */ -#ifdef CONFIG_MACH_H4700 - 0, - 3600, /* HP iPAQ hx4700 3.7V 3600mAh (359114-001) */ -#endif }; /* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C diff --git a/drivers/power/supply/pda_power.c b/drivers/power/supply/pda_power.c deleted file mode 100644 index 03a37fd6be27..000000000000 --- a/drivers/power/supply/pda_power.c +++ /dev/null @@ -1,520 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Common power driver for PDAs and phones with one or two external - * power supplies (AC/USB) connected to main and backup batteries, - * and optional builtin charger. - * - * Copyright © 2007 Anton Vorontsov <cbou@mail.ru> - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/err.h> -#include <linux/interrupt.h> -#include <linux/notifier.h> -#include <linux/power_supply.h> -#include <linux/pda_power.h> -#include <linux/regulator/consumer.h> -#include <linux/timer.h> -#include <linux/jiffies.h> -#include <linux/usb/otg.h> - -static inline unsigned int get_irq_flags(struct resource *res) -{ - return IRQF_SHARED | (res->flags & IRQF_TRIGGER_MASK); -} - -static struct device *dev; -static struct pda_power_pdata *pdata; -static struct resource *ac_irq, *usb_irq; -static struct delayed_work charger_work; -static struct delayed_work polling_work; -static struct delayed_work supply_work; -static int polling; -static struct power_supply *pda_psy_ac, *pda_psy_usb; - -#if IS_ENABLED(CONFIG_USB_PHY) -static struct usb_phy *transceiver; -static struct notifier_block otg_nb; -#endif - -static struct regulator *ac_draw; - -enum { - PDA_PSY_OFFLINE = 0, - PDA_PSY_ONLINE = 1, - PDA_PSY_TO_CHANGE, -}; -static int new_ac_status = -1; -static int new_usb_status = -1; -static int ac_status = -1; -static int usb_status = -1; - -static int pda_power_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - if (psy->desc->type == POWER_SUPPLY_TYPE_MAINS) - val->intval = pdata->is_ac_online ? - pdata->is_ac_online() : 0; - else - val->intval = pdata->is_usb_online ? - pdata->is_usb_online() : 0; - break; - default: - return -EINVAL; - } - return 0; -} - -static enum power_supply_property pda_power_props[] = { - POWER_SUPPLY_PROP_ONLINE, -}; - -static char *pda_power_supplied_to[] = { - "main-battery", - "backup-battery", -}; - -static const struct power_supply_desc pda_psy_ac_desc = { - .name = "ac", - .type = POWER_SUPPLY_TYPE_MAINS, - .properties = pda_power_props, - .num_properties = ARRAY_SIZE(pda_power_props), - .get_property = pda_power_get_property, -}; - -static const struct power_supply_desc pda_psy_usb_desc = { - .name = "usb", - .type = POWER_SUPPLY_TYPE_USB, - .properties = pda_power_props, - .num_properties = ARRAY_SIZE(pda_power_props), - .get_property = pda_power_get_property, -}; - -static void update_status(void) -{ - if (pdata->is_ac_online) - new_ac_status = !!pdata->is_ac_online(); - - if (pdata->is_usb_online) - new_usb_status = !!pdata->is_usb_online(); -} - -static void update_charger(void) -{ - static int regulator_enabled; - int max_uA = pdata->ac_max_uA; - - if (pdata->set_charge) { - if (new_ac_status > 0) { - dev_dbg(dev, "charger on (AC)\n"); - pdata->set_charge(PDA_POWER_CHARGE_AC); - } else if (new_usb_status > 0) { - dev_dbg(dev, "charger on (USB)\n"); - pdata->set_charge(PDA_POWER_CHARGE_USB); - } else { - dev_dbg(dev, "charger off\n"); - pdata->set_charge(0); - } - } else if (ac_draw) { - if (new_ac_status > 0) { - regulator_set_current_limit(ac_draw, max_uA, max_uA); - if (!regulator_enabled) { - dev_dbg(dev, "charger on (AC)\n"); - WARN_ON(regulator_enable(ac_draw)); - regulator_enabled = 1; - } - } else { - if (regulator_enabled) { - dev_dbg(dev, "charger off\n"); - WARN_ON(regulator_disable(ac_draw)); - regulator_enabled = 0; - } - } - } -} - -static void supply_work_func(struct work_struct *work) -{ - if (ac_status == PDA_PSY_TO_CHANGE) { - ac_status = new_ac_status; - power_supply_changed(pda_psy_ac); - } - - if (usb_status == PDA_PSY_TO_CHANGE) { - usb_status = new_usb_status; - power_supply_changed(pda_psy_usb); - } -} - -static void psy_changed(void) -{ - update_charger(); - - /* - * Okay, charger set. Now wait a bit before notifying supplicants, - * charge power should stabilize. - */ - cancel_delayed_work(&supply_work); - schedule_delayed_work(&supply_work, - msecs_to_jiffies(pdata->wait_for_charger)); -} - -static void charger_work_func(struct work_struct *work) -{ - update_status(); - psy_changed(); -} - -static irqreturn_t power_changed_isr(int irq, void *power_supply) -{ - if (power_supply == pda_psy_ac) - ac_status = PDA_PSY_TO_CHANGE; - else if (power_supply == pda_psy_usb) - usb_status = PDA_PSY_TO_CHANGE; - else - return IRQ_NONE; - - /* - * Wait a bit before reading ac/usb line status and setting charger, - * because ac/usb status readings may lag from irq. - */ - cancel_delayed_work(&charger_work); - schedule_delayed_work(&charger_work, - msecs_to_jiffies(pdata->wait_for_status)); - - return IRQ_HANDLED; -} - -static void polling_work_func(struct work_struct *work) -{ - int changed = 0; - - dev_dbg(dev, "polling...\n"); - - update_status(); - - if (!ac_irq && new_ac_status != ac_status) { - ac_status = PDA_PSY_TO_CHANGE; - changed = 1; - } - - if (!usb_irq && new_usb_status != usb_status) { - usb_status = PDA_PSY_TO_CHANGE; - changed = 1; - } - - if (changed) - psy_changed(); - - cancel_delayed_work(&polling_work); - schedule_delayed_work(&polling_work, - msecs_to_jiffies(pdata->polling_interval)); -} - -#if IS_ENABLED(CONFIG_USB_PHY) -static int otg_is_usb_online(void) -{ - return (transceiver->last_event == USB_EVENT_VBUS || - transceiver->last_event == USB_EVENT_ENUMERATED); -} - -static int otg_is_ac_online(void) -{ - return (transceiver->last_event == USB_EVENT_CHARGER); -} - -static int otg_handle_notification(struct notifier_block *nb, - unsigned long event, void *unused) -{ - switch (event) { - case USB_EVENT_CHARGER: - ac_status = PDA_PSY_TO_CHANGE; - break; - case USB_EVENT_VBUS: - case USB_EVENT_ENUMERATED: - usb_status = PDA_PSY_TO_CHANGE; - break; - case USB_EVENT_NONE: - ac_status = PDA_PSY_TO_CHANGE; - usb_status = PDA_PSY_TO_CHANGE; - break; - default: - return NOTIFY_OK; - } - - /* - * Wait a bit before reading ac/usb line status and setting charger, - * because ac/usb status readings may lag from irq. - */ - cancel_delayed_work(&charger_work); - schedule_delayed_work(&charger_work, - msecs_to_jiffies(pdata->wait_for_status)); - - return NOTIFY_OK; -} -#endif - -static int pda_power_probe(struct platform_device *pdev) -{ - struct power_supply_config psy_cfg = {}; - int ret = 0; - - dev = &pdev->dev; - - if (pdev->id != -1) { - dev_err(dev, "it's meaningless to register several " - "pda_powers; use id = -1\n"); - ret = -EINVAL; - goto wrongid; - } - - pdata = pdev->dev.platform_data; - - if (pdata->init) { - ret = pdata->init(dev); - if (ret < 0) - goto init_failed; - } - - ac_draw = regulator_get(dev, "ac_draw"); - if (IS_ERR(ac_draw)) { - dev_dbg(dev, "couldn't get ac_draw regulator\n"); - ac_draw = NULL; - } - - update_status(); - update_charger(); - - if (!pdata->wait_for_status) - pdata->wait_for_status = 500; - - if (!pdata->wait_for_charger) - pdata->wait_for_charger = 500; - - if (!pdata->polling_interval) - pdata->polling_interval = 2000; - - if (!pdata->ac_max_uA) - pdata->ac_max_uA = 500000; - - INIT_DELAYED_WORK(&charger_work, charger_work_func); - INIT_DELAYED_WORK(&supply_work, supply_work_func); - - ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); - usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); - - if (pdata->supplied_to) { - psy_cfg.supplied_to = pdata->supplied_to; - psy_cfg.num_supplicants = pdata->num_supplicants; - } else { - psy_cfg.supplied_to = pda_power_supplied_to; - psy_cfg.num_supplicants = ARRAY_SIZE(pda_power_supplied_to); - } - -#if IS_ENABLED(CONFIG_USB_PHY) - transceiver = usb_get_phy(USB_PHY_TYPE_USB2); - if (!IS_ERR_OR_NULL(transceiver)) { - if (!pdata->is_usb_online) - pdata->is_usb_online = otg_is_usb_online; - if (!pdata->is_ac_online) - pdata->is_ac_online = otg_is_ac_online; - } -#endif - - if (pdata->is_ac_online) { - pda_psy_ac = power_supply_register(&pdev->dev, - &pda_psy_ac_desc, &psy_cfg); - if (IS_ERR(pda_psy_ac)) { - dev_err(dev, "failed to register %s power supply\n", - pda_psy_ac_desc.name); - ret = PTR_ERR(pda_psy_ac); - goto ac_supply_failed; - } - - if (ac_irq) { - ret = request_irq(ac_irq->start, power_changed_isr, - get_irq_flags(ac_irq), ac_irq->name, - pda_psy_ac); - if (ret) { - dev_err(dev, "request ac irq failed\n"); - goto ac_irq_failed; - } - } else { - polling = 1; - } - } - - if (pdata->is_usb_online) { - pda_psy_usb = power_supply_register(&pdev->dev, - &pda_psy_usb_desc, - &psy_cfg); - if (IS_ERR(pda_psy_usb)) { - dev_err(dev, "failed to register %s power supply\n", - pda_psy_usb_desc.name); - ret = PTR_ERR(pda_psy_usb); - goto usb_supply_failed; - } - - if (usb_irq) { - ret = request_irq(usb_irq->start, power_changed_isr, - get_irq_flags(usb_irq), - usb_irq->name, pda_psy_usb); - if (ret) { - dev_err(dev, "request usb irq failed\n"); - goto usb_irq_failed; - } - } else { - polling = 1; - } - } - -#if IS_ENABLED(CONFIG_USB_PHY) - if (!IS_ERR_OR_NULL(transceiver) && pdata->use_otg_notifier) { - otg_nb.notifier_call = otg_handle_notification; - ret = usb_register_notifier(transceiver, &otg_nb); - if (ret) { - dev_err(dev, "failure to register otg notifier\n"); - goto otg_reg_notifier_failed; - } - polling = 0; - } -#endif - - if (polling) { - dev_dbg(dev, "will poll for status\n"); - INIT_DELAYED_WORK(&polling_work, polling_work_func); - cancel_delayed_work(&polling_work); - schedule_delayed_work(&polling_work, - msecs_to_jiffies(pdata->polling_interval)); - } - - if (ac_irq || usb_irq) - device_init_wakeup(&pdev->dev, 1); - - return 0; - -#if IS_ENABLED(CONFIG_USB_PHY) -otg_reg_notifier_failed: - if (pdata->is_usb_online && usb_irq) - free_irq(usb_irq->start, pda_psy_usb); -#endif -usb_irq_failed: - if (pdata->is_usb_online) - power_supply_unregister(pda_psy_usb); -usb_supply_failed: - if (pdata->is_ac_online && ac_irq) - free_irq(ac_irq->start, pda_psy_ac); -#if IS_ENABLED(CONFIG_USB_PHY) - if (!IS_ERR_OR_NULL(transceiver)) - usb_put_phy(transceiver); -#endif -ac_irq_failed: - if (pdata->is_ac_online) - power_supply_unregister(pda_psy_ac); -ac_supply_failed: - if (ac_draw) { - regulator_put(ac_draw); - ac_draw = NULL; - } - if (pdata->exit) - pdata->exit(dev); -init_failed: -wrongid: - return ret; -} - -static int pda_power_remove(struct platform_device *pdev) -{ -#if IS_ENABLED(CONFIG_USB_PHY) - if (!IS_ERR_OR_NULL(transceiver) && pdata->use_otg_notifier) - usb_unregister_notifier(transceiver, &otg_nb); -#endif - if (pdata->is_usb_online && usb_irq) - free_irq(usb_irq->start, pda_psy_usb); - if (pdata->is_ac_online && ac_irq) - free_irq(ac_irq->start, pda_psy_ac); - - if (polling) - cancel_delayed_work_sync(&polling_work); - cancel_delayed_work_sync(&charger_work); - cancel_delayed_work_sync(&supply_work); - - if (pdata->is_usb_online) - power_supply_unregister(pda_psy_usb); - if (pdata->is_ac_online) - power_supply_unregister(pda_psy_ac); -#if IS_ENABLED(CONFIG_USB_PHY) - if (!IS_ERR_OR_NULL(transceiver)) - usb_put_phy(transceiver); -#endif - if (ac_draw) { - regulator_put(ac_draw); - ac_draw = NULL; - } - if (pdata->exit) - pdata->exit(dev); - - return 0; -} - -#ifdef CONFIG_PM -static int ac_wakeup_enabled; -static int usb_wakeup_enabled; - -static int pda_power_suspend(struct platform_device *pdev, pm_message_t state) -{ - if (pdata->suspend) { - int ret = pdata->suspend(state); - - if (ret) - return ret; - } - - if (device_may_wakeup(&pdev->dev)) { - if (ac_irq) - ac_wakeup_enabled = !enable_irq_wake(ac_irq->start); - if (usb_irq) - usb_wakeup_enabled = !enable_irq_wake(usb_irq->start); - } - - return 0; -} - -static int pda_power_resume(struct platform_device *pdev) -{ - if (device_may_wakeup(&pdev->dev)) { - if (usb_irq && usb_wakeup_enabled) - disable_irq_wake(usb_irq->start); - if (ac_irq && ac_wakeup_enabled) - disable_irq_wake(ac_irq->start); - } - - if (pdata->resume) - return pdata->resume(); - - return 0; -} -#else -#define pda_power_suspend NULL -#define pda_power_resume NULL -#endif /* CONFIG_PM */ - -static struct platform_driver pda_power_pdrv = { - .driver = { - .name = "pda-power", - }, - .probe = pda_power_probe, - .remove = pda_power_remove, - .suspend = pda_power_suspend, - .resume = pda_power_resume, -}; - -module_platform_driver(pda_power_pdrv); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>"); -MODULE_ALIAS("platform:pda-power"); diff --git a/drivers/power/supply/s3c_adc_battery.c b/drivers/power/supply/s3c_adc_battery.c deleted file mode 100644 index 68d31a3bee48..000000000000 --- a/drivers/power/supply/s3c_adc_battery.c +++ /dev/null @@ -1,453 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// iPAQ h1930/h1940/rx1950 battery controller driver -// Copyright (c) Vasily Khoruzhick -// Based on h1940_battery.c by Arnaud Patard - -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/power_supply.h> -#include <linux/leds.h> -#include <linux/gpio/consumer.h> -#include <linux/err.h> -#include <linux/timer.h> -#include <linux/jiffies.h> -#include <linux/s3c_adc_battery.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/module.h> - -#include <linux/soc/samsung/s3c-adc.h> - -#define BAT_POLL_INTERVAL 10000 /* ms */ -#define JITTER_DELAY 500 /* ms */ - -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; - int level; - int status; - int cable_plugged:1; -}; - -static struct delayed_work bat_work; - -static void s3c_adc_bat_ext_power_changed(struct power_supply *psy) -{ - schedule_delayed_work(&bat_work, - msecs_to_jiffies(JITTER_DELAY)); -} - -static int gather_samples(struct s3c_adc_client *client, int num, int channel) -{ - int value, i; - - /* default to 1 if nothing is set */ - if (num < 1) - num = 1; - - value = 0; - for (i = 0; i < num; i++) - value += s3c_adc_read(client, channel); - value /= num; - - return value; -} - -static enum power_supply_property s3c_adc_backup_bat_props[] = { - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_VOLTAGE_MIN, - POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, -}; - -static int s3c_adc_backup_bat_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct s3c_adc_bat *bat = power_supply_get_drvdata(psy); - - if (!bat) { - dev_err(&psy->dev, "%s: no battery infos ?!\n", __func__); - return -EINVAL; - } - - if (bat->volt_value < 0 || - jiffies_to_msecs(jiffies - bat->timestamp) > - BAT_POLL_INTERVAL) { - bat->volt_value = gather_samples(bat->client, - bat->pdata->backup_volt_samples, - bat->pdata->backup_volt_channel); - bat->volt_value *= bat->pdata->backup_volt_mult; - bat->timestamp = jiffies; - } - - switch (psp) { - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = bat->volt_value; - return 0; - case POWER_SUPPLY_PROP_VOLTAGE_MIN: - val->intval = bat->pdata->backup_volt_min; - return 0; - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: - val->intval = bat->pdata->backup_volt_max; - return 0; - default: - return -EINVAL; - } -} - -static const struct power_supply_desc backup_bat_desc = { - .name = "backup-battery", - .type = POWER_SUPPLY_TYPE_BATTERY, - .properties = s3c_adc_backup_bat_props, - .num_properties = ARRAY_SIZE(s3c_adc_backup_bat_props), - .get_property = s3c_adc_backup_bat_get_property, - .use_for_apm = 1, -}; - -static struct s3c_adc_bat backup_bat; - -static enum power_supply_property s3c_adc_main_bat_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, - POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN, - POWER_SUPPLY_PROP_CHARGE_NOW, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, -}; - -static int calc_full_volt(int volt_val, int cur_val, int impedance) -{ - return volt_val + cur_val * impedance / 1000; -} - -static int charge_finished(struct s3c_adc_bat *bat) -{ - return gpiod_get_value(bat->charge_finished); -} - -static int s3c_adc_bat_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct s3c_adc_bat *bat = power_supply_get_drvdata(psy); - - int new_level; - int full_volt; - const struct s3c_adc_bat_thresh *lut; - unsigned int lut_size; - - if (!bat) { - dev_err(&psy->dev, "no battery infos ?!\n"); - return -EINVAL; - } - - lut = bat->pdata->lut_noac; - lut_size = bat->pdata->lut_noac_cnt; - - if (bat->volt_value < 0 || bat->cur_value < 0 || - jiffies_to_msecs(jiffies - bat->timestamp) > - BAT_POLL_INTERVAL) { - bat->volt_value = gather_samples(bat->client, - bat->pdata->volt_samples, - bat->pdata->volt_channel) * bat->pdata->volt_mult; - bat->cur_value = gather_samples(bat->client, - bat->pdata->current_samples, - bat->pdata->current_channel) * bat->pdata->current_mult; - bat->timestamp = jiffies; - } - - if (bat->cable_plugged && - (!bat->charge_finished || - !charge_finished(bat))) { - lut = bat->pdata->lut_acin; - lut_size = bat->pdata->lut_acin_cnt; - } - - new_level = 100000; - full_volt = calc_full_volt((bat->volt_value / 1000), - (bat->cur_value / 1000), bat->pdata->internal_impedance); - - if (full_volt < calc_full_volt(lut->volt, lut->cur, - bat->pdata->internal_impedance)) { - lut_size--; - while (lut_size--) { - int lut_volt1; - int lut_volt2; - - lut_volt1 = calc_full_volt(lut[0].volt, lut[0].cur, - bat->pdata->internal_impedance); - lut_volt2 = calc_full_volt(lut[1].volt, lut[1].cur, - bat->pdata->internal_impedance); - if (full_volt < lut_volt1 && full_volt >= lut_volt2) { - new_level = (lut[1].level + - (lut[0].level - lut[1].level) * - (full_volt - lut_volt2) / - (lut_volt1 - lut_volt2)) * 1000; - break; - } - new_level = lut[1].level * 1000; - lut++; - } - } - - bat->level = new_level; - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - if (!bat->charge_finished) - val->intval = bat->level == 100000 ? - POWER_SUPPLY_STATUS_FULL : bat->status; - else - val->intval = bat->status; - return 0; - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: - val->intval = 100000; - return 0; - case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: - val->intval = 0; - return 0; - case POWER_SUPPLY_PROP_CHARGE_NOW: - val->intval = bat->level; - return 0; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = bat->volt_value; - return 0; - case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = bat->cur_value; - return 0; - default: - return -EINVAL; - } -} - -static const struct power_supply_desc main_bat_desc = { - .name = "main-battery", - .type = POWER_SUPPLY_TYPE_BATTERY, - .properties = s3c_adc_main_bat_props, - .num_properties = ARRAY_SIZE(s3c_adc_main_bat_props), - .get_property = s3c_adc_bat_get_property, - .external_power_changed = s3c_adc_bat_ext_power_changed, - .use_for_apm = 1, -}; - -static struct s3c_adc_bat main_bat; - -static void s3c_adc_bat_work(struct work_struct *work) -{ - struct s3c_adc_bat *bat = &main_bat; - int is_charged; - int is_plugged; - static int was_plugged; - - is_plugged = power_supply_am_i_supplied(bat->psy); - bat->cable_plugged = is_plugged; - if (is_plugged != was_plugged) { - was_plugged = is_plugged; - if (is_plugged) { - if (bat->pdata->enable_charger) - bat->pdata->enable_charger(); - bat->status = POWER_SUPPLY_STATUS_CHARGING; - } else { - if (bat->pdata->disable_charger) - bat->pdata->disable_charger(); - bat->status = POWER_SUPPLY_STATUS_DISCHARGING; - } - } else { - if (bat->charge_finished && is_plugged) { - is_charged = charge_finished(&main_bat); - if (is_charged) { - if (bat->pdata->disable_charger) - bat->pdata->disable_charger(); - bat->status = POWER_SUPPLY_STATUS_FULL; - } else { - if (bat->pdata->enable_charger) - bat->pdata->enable_charger(); - bat->status = POWER_SUPPLY_STATUS_CHARGING; - } - } - } - - power_supply_changed(bat->psy); -} - -static irqreturn_t s3c_adc_bat_charged(int irq, void *dev_id) -{ - schedule_delayed_work(&bat_work, - msecs_to_jiffies(JITTER_DELAY)); - return IRQ_HANDLED; -} - -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); - if (IS_ERR(client)) { - dev_err(&pdev->dev, "cannot register adc\n"); - return PTR_ERR(client); - } - - 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; - main_bat.status = POWER_SUPPLY_STATUS_DISCHARGING; - psy_cfg.drv_data = &main_bat; - - main_bat.psy = power_supply_register(&pdev->dev, &main_bat_desc, &psy_cfg); - if (IS_ERR(main_bat.psy)) { - ret = PTR_ERR(main_bat.psy); - goto err_reg_main; - } - if (pdata->backup_volt_mult) { - const struct power_supply_config backup_psy_cfg - = { .drv_data = &backup_bat, }; - - 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, - &backup_psy_cfg); - if (IS_ERR(backup_bat.psy)) { - ret = PTR_ERR(backup_bat.psy); - goto err_reg_backup; - } - } - - INIT_DELAYED_WORK(&bat_work, s3c_adc_bat_work); - - if (gpiod) { - ret = request_irq(gpiod_to_irq(gpiod), - s3c_adc_bat_charged, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "battery charged", NULL); - if (ret) - goto err_irq; - } - - if (pdata->init) { - ret = pdata->init(); - if (ret) - goto err_platform; - } - - dev_info(&pdev->dev, "successfully loaded\n"); - device_init_wakeup(&pdev->dev, 1); - - /* Schedule timer to check current status */ - schedule_delayed_work(&bat_work, - msecs_to_jiffies(JITTER_DELAY)); - - return 0; - -err_platform: - if (gpiod) - free_irq(gpiod_to_irq(gpiod), NULL); -err_irq: - if (pdata->backup_volt_mult) - power_supply_unregister(backup_bat.psy); -err_reg_backup: - power_supply_unregister(main_bat.psy); -err_reg_main: - return ret; -} - -static int s3c_adc_bat_remove(struct platform_device *pdev) -{ - struct s3c_adc_client *client = platform_get_drvdata(pdev); - struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data; - - power_supply_unregister(main_bat.psy); - if (pdata->backup_volt_mult) - power_supply_unregister(backup_bat.psy); - - s3c_adc_release(client); - - if (main_bat.charge_finished) - free_irq(gpiod_to_irq(main_bat.charge_finished), NULL); - - cancel_delayed_work_sync(&bat_work); - - if (pdata->exit) - pdata->exit(); - - return 0; -} - -#ifdef CONFIG_PM -static int s3c_adc_bat_suspend(struct platform_device *pdev, - pm_message_t state) -{ - if (main_bat.charge_finished) { - if (device_may_wakeup(&pdev->dev)) - enable_irq_wake( - gpiod_to_irq(main_bat.charge_finished)); - else { - disable_irq(gpiod_to_irq(main_bat.charge_finished)); - main_bat.pdata->disable_charger(); - } - } - - return 0; -} - -static int s3c_adc_bat_resume(struct platform_device *pdev) -{ - if (main_bat.charge_finished) { - if (device_may_wakeup(&pdev->dev)) - disable_irq_wake( - gpiod_to_irq(main_bat.charge_finished)); - else - enable_irq(gpiod_to_irq(main_bat.charge_finished)); - } - - /* Schedule timer to check current status */ - schedule_delayed_work(&bat_work, - msecs_to_jiffies(JITTER_DELAY)); - - return 0; -} -#else -#define s3c_adc_bat_suspend NULL -#define s3c_adc_bat_resume NULL -#endif - -static struct platform_driver s3c_adc_bat_driver = { - .driver = { - .name = "s3c-adc-battery", - }, - .probe = s3c_adc_bat_probe, - .remove = s3c_adc_bat_remove, - .suspend = s3c_adc_bat_suspend, - .resume = s3c_adc_bat_resume, -}; - -module_platform_driver(s3c_adc_bat_driver); - -MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>"); -MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controller driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/power/supply/tosa_battery.c b/drivers/power/supply/tosa_battery.c deleted file mode 100644 index 73d4aca4c386..000000000000 --- a/drivers/power/supply/tosa_battery.c +++ /dev/null @@ -1,512 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Battery and Power Management code for the Sharp SL-6000x - * - * Copyright (c) 2005 Dirk Opfer - * Copyright (c) 2008 Dmitry Baryshkov - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/power_supply.h> -#include <linux/wm97xx.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <linux/gpio/consumer.h> - -#include <asm/mach-types.h> - -static DEFINE_MUTEX(bat_lock); /* protects gpio pins */ -static struct work_struct bat_work; - -struct tosa_bat { - int status; - struct power_supply *psy; - int full_chrg; - - struct mutex work_lock; /* protects data */ - - bool (*is_present)(struct tosa_bat *bat); - struct gpio_desc *gpiod_full; - struct gpio_desc *gpiod_charge_off; - - int technology; - - struct gpio_desc *gpiod_bat; - int adc_bat; - int adc_bat_divider; - int bat_max; - int bat_min; - - struct gpio_desc *gpiod_temp; - int adc_temp; - int adc_temp_divider; -}; - -static struct gpio_desc *jacket_detect; -static struct tosa_bat tosa_bat_main; -static struct tosa_bat tosa_bat_jacket; - -static unsigned long tosa_read_bat(struct tosa_bat *bat) -{ - unsigned long value = 0; - - if (!bat->gpiod_bat || bat->adc_bat < 0) - return 0; - - mutex_lock(&bat_lock); - gpiod_set_value(bat->gpiod_bat, 1); - msleep(5); - value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent), - bat->adc_bat); - gpiod_set_value(bat->gpiod_bat, 0); - mutex_unlock(&bat_lock); - - value = value * 1000000 / bat->adc_bat_divider; - - return value; -} - -static unsigned long tosa_read_temp(struct tosa_bat *bat) -{ - unsigned long value = 0; - - if (!bat->gpiod_temp || bat->adc_temp < 0) - return 0; - - mutex_lock(&bat_lock); - gpiod_set_value(bat->gpiod_temp, 1); - msleep(5); - value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent), - bat->adc_temp); - gpiod_set_value(bat->gpiod_temp, 0); - mutex_unlock(&bat_lock); - - value = value * 10000 / bat->adc_temp_divider; - - return value; -} - -static int tosa_bat_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - int ret = 0; - struct tosa_bat *bat = power_supply_get_drvdata(psy); - - if (bat->is_present && !bat->is_present(bat) - && psp != POWER_SUPPLY_PROP_PRESENT) { - return -ENODEV; - } - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - val->intval = bat->status; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = bat->technology; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = tosa_read_bat(bat); - break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - if (bat->full_chrg == -1) - val->intval = bat->bat_max; - else - val->intval = bat->full_chrg; - break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: - val->intval = bat->bat_max; - break; - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - val->intval = bat->bat_min; - break; - case POWER_SUPPLY_PROP_TEMP: - val->intval = tosa_read_temp(bat); - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = bat->is_present ? bat->is_present(bat) : 1; - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -static bool tosa_jacket_bat_is_present(struct tosa_bat *bat) -{ - return gpiod_get_value(jacket_detect) == 0; -} - -static void tosa_bat_external_power_changed(struct power_supply *psy) -{ - schedule_work(&bat_work); -} - -static irqreturn_t tosa_bat_gpio_isr(int irq, void *data) -{ - pr_info("tosa_bat_gpio irq\n"); - schedule_work(&bat_work); - return IRQ_HANDLED; -} - -static void tosa_bat_update(struct tosa_bat *bat) -{ - int old; - struct power_supply *psy = bat->psy; - - mutex_lock(&bat->work_lock); - - old = bat->status; - - if (bat->is_present && !bat->is_present(bat)) { - printk(KERN_NOTICE "%s not present\n", psy->desc->name); - bat->status = POWER_SUPPLY_STATUS_UNKNOWN; - bat->full_chrg = -1; - } else if (power_supply_am_i_supplied(psy)) { - if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) { - gpiod_set_value(bat->gpiod_charge_off, 0); - mdelay(15); - } - - if (gpiod_get_value(bat->gpiod_full)) { - if (old == POWER_SUPPLY_STATUS_CHARGING || - bat->full_chrg == -1) - bat->full_chrg = tosa_read_bat(bat); - - gpiod_set_value(bat->gpiod_charge_off, 1); - bat->status = POWER_SUPPLY_STATUS_FULL; - } else { - gpiod_set_value(bat->gpiod_charge_off, 0); - bat->status = POWER_SUPPLY_STATUS_CHARGING; - } - } else { - gpiod_set_value(bat->gpiod_charge_off, 1); - bat->status = POWER_SUPPLY_STATUS_DISCHARGING; - } - - if (old != bat->status) - power_supply_changed(psy); - - mutex_unlock(&bat->work_lock); -} - -static void tosa_bat_work(struct work_struct *work) -{ - tosa_bat_update(&tosa_bat_main); - tosa_bat_update(&tosa_bat_jacket); -} - - -static enum power_supply_property tosa_bat_main_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_VOLTAGE_MAX, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_TEMP, - POWER_SUPPLY_PROP_PRESENT, -}; - -static enum power_supply_property tosa_bat_bu_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, - POWER_SUPPLY_PROP_PRESENT, -}; - -static const struct power_supply_desc tosa_bat_main_desc = { - .name = "main-battery", - .type = POWER_SUPPLY_TYPE_BATTERY, - .properties = tosa_bat_main_props, - .num_properties = ARRAY_SIZE(tosa_bat_main_props), - .get_property = tosa_bat_get_property, - .external_power_changed = tosa_bat_external_power_changed, - .use_for_apm = 1, -}; - -static const struct power_supply_desc tosa_bat_jacket_desc = { - .name = "jacket-battery", - .type = POWER_SUPPLY_TYPE_BATTERY, - .properties = tosa_bat_main_props, - .num_properties = ARRAY_SIZE(tosa_bat_main_props), - .get_property = tosa_bat_get_property, - .external_power_changed = tosa_bat_external_power_changed, -}; - -static const struct power_supply_desc tosa_bat_bu_desc = { - .name = "backup-battery", - .type = POWER_SUPPLY_TYPE_BATTERY, - .properties = tosa_bat_bu_props, - .num_properties = ARRAY_SIZE(tosa_bat_bu_props), - .get_property = tosa_bat_get_property, - .external_power_changed = tosa_bat_external_power_changed, -}; - -static struct tosa_bat tosa_bat_main = { - .status = POWER_SUPPLY_STATUS_DISCHARGING, - .full_chrg = -1, - .psy = NULL, - - .gpiod_full = NULL, - .gpiod_charge_off = NULL, - - .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, - - .gpiod_bat = NULL, - .adc_bat = WM97XX_AUX_ID3, - .adc_bat_divider = 414, - .bat_max = 4310000, - .bat_min = 1551 * 1000000 / 414, - - .gpiod_temp = NULL, - .adc_temp = WM97XX_AUX_ID2, - .adc_temp_divider = 10000, -}; - -static struct tosa_bat tosa_bat_jacket = { - .status = POWER_SUPPLY_STATUS_DISCHARGING, - .full_chrg = -1, - .psy = NULL, - - .is_present = tosa_jacket_bat_is_present, - .gpiod_full = NULL, - .gpiod_charge_off = NULL, - - .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, - - .gpiod_bat = NULL, - .adc_bat = WM97XX_AUX_ID3, - .adc_bat_divider = 414, - .bat_max = 4310000, - .bat_min = 1551 * 1000000 / 414, - - .gpiod_temp = NULL, - .adc_temp = WM97XX_AUX_ID2, - .adc_temp_divider = 10000, -}; - -static struct tosa_bat tosa_bat_bu = { - .status = POWER_SUPPLY_STATUS_UNKNOWN, - .full_chrg = -1, - .psy = NULL, - - .gpiod_full = NULL, - .gpiod_charge_off = NULL, - - .technology = POWER_SUPPLY_TECHNOLOGY_LiMn, - - .gpiod_bat = NULL, - .adc_bat = WM97XX_AUX_ID4, - .adc_bat_divider = 1266, - - .gpiod_temp = NULL, - .adc_temp = -1, - .adc_temp_divider = -1, -}; - -#ifdef CONFIG_PM -static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state) -{ - /* flush all pending status updates */ - flush_work(&bat_work); - return 0; -} - -static int tosa_bat_resume(struct platform_device *dev) -{ - /* things may have changed while we were away */ - schedule_work(&bat_work); - return 0; -} -#else -#define tosa_bat_suspend NULL -#define tosa_bat_resume NULL -#endif - -static int tosa_bat_probe(struct platform_device *pdev) -{ - int ret; - struct power_supply_config main_psy_cfg = {}, - jacket_psy_cfg = {}, - bu_psy_cfg = {}; - struct device *dev = &pdev->dev; - struct gpio_desc *dummy; - - if (!machine_is_tosa()) - return -ENODEV; - - /* Main charging control GPIOs */ - tosa_bat_main.gpiod_charge_off = devm_gpiod_get(dev, "main charge off", GPIOD_OUT_HIGH); - if (IS_ERR(tosa_bat_main.gpiod_charge_off)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_charge_off), - "no main charger GPIO\n"); - tosa_bat_jacket.gpiod_charge_off = devm_gpiod_get(dev, "jacket charge off", GPIOD_OUT_HIGH); - if (IS_ERR(tosa_bat_jacket.gpiod_charge_off)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_charge_off), - "no jacket charger GPIO\n"); - - /* Per-battery output check (routes battery voltage to ADC) */ - tosa_bat_main.gpiod_bat = devm_gpiod_get(dev, "main battery", GPIOD_OUT_LOW); - if (IS_ERR(tosa_bat_main.gpiod_bat)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_bat), - "no main battery GPIO\n"); - tosa_bat_jacket.gpiod_bat = devm_gpiod_get(dev, "jacket battery", GPIOD_OUT_LOW); - if (IS_ERR(tosa_bat_jacket.gpiod_bat)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_bat), - "no jacket battery GPIO\n"); - tosa_bat_bu.gpiod_bat = devm_gpiod_get(dev, "backup battery", GPIOD_OUT_LOW); - if (IS_ERR(tosa_bat_bu.gpiod_bat)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_bu.gpiod_bat), - "no backup battery GPIO\n"); - - /* Battery full detect GPIOs (using PXA SoC GPIOs) */ - tosa_bat_main.gpiod_full = devm_gpiod_get(dev, "main battery full", GPIOD_IN); - if (IS_ERR(tosa_bat_main.gpiod_full)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_full), - "no main battery full GPIO\n"); - tosa_bat_jacket.gpiod_full = devm_gpiod_get(dev, "jacket battery full", GPIOD_IN); - if (IS_ERR(tosa_bat_jacket.gpiod_full)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_full), - "no jacket battery full GPIO\n"); - - /* Battery temperature GPIOs (routes thermistor voltage to ADC) */ - tosa_bat_main.gpiod_temp = devm_gpiod_get(dev, "main battery temp", GPIOD_OUT_LOW); - if (IS_ERR(tosa_bat_main.gpiod_temp)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_temp), - "no main battery temp GPIO\n"); - tosa_bat_jacket.gpiod_temp = devm_gpiod_get(dev, "jacket battery temp", GPIOD_OUT_LOW); - if (IS_ERR(tosa_bat_jacket.gpiod_temp)) - return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_temp), - "no jacket battery temp GPIO\n"); - - /* Jacket detect GPIO */ - jacket_detect = devm_gpiod_get(dev, "jacket detect", GPIOD_IN); - if (IS_ERR(jacket_detect)) - return dev_err_probe(dev, PTR_ERR(jacket_detect), - "no jacket detect GPIO\n"); - - /* Battery low indication GPIOs (not used, we just request them) */ - dummy = devm_gpiod_get(dev, "main battery low", GPIOD_IN); - if (IS_ERR(dummy)) - return dev_err_probe(dev, PTR_ERR(dummy), - "no main battery low GPIO\n"); - dummy = devm_gpiod_get(dev, "jacket battery low", GPIOD_IN); - if (IS_ERR(dummy)) - return dev_err_probe(dev, PTR_ERR(dummy), - "no jacket battery low GPIO\n"); - - /* Battery switch GPIO (not used just requested) */ - dummy = devm_gpiod_get(dev, "battery switch", GPIOD_OUT_LOW); - if (IS_ERR(dummy)) - return dev_err_probe(dev, PTR_ERR(dummy), - "no battery switch GPIO\n"); - - mutex_init(&tosa_bat_main.work_lock); - mutex_init(&tosa_bat_jacket.work_lock); - - INIT_WORK(&bat_work, tosa_bat_work); - - main_psy_cfg.drv_data = &tosa_bat_main; - tosa_bat_main.psy = power_supply_register(dev, - &tosa_bat_main_desc, - &main_psy_cfg); - if (IS_ERR(tosa_bat_main.psy)) { - ret = PTR_ERR(tosa_bat_main.psy); - goto err_psy_reg_main; - } - - jacket_psy_cfg.drv_data = &tosa_bat_jacket; - tosa_bat_jacket.psy = power_supply_register(dev, - &tosa_bat_jacket_desc, - &jacket_psy_cfg); - if (IS_ERR(tosa_bat_jacket.psy)) { - ret = PTR_ERR(tosa_bat_jacket.psy); - goto err_psy_reg_jacket; - } - - bu_psy_cfg.drv_data = &tosa_bat_bu; - tosa_bat_bu.psy = power_supply_register(dev, &tosa_bat_bu_desc, - &bu_psy_cfg); - if (IS_ERR(tosa_bat_bu.psy)) { - ret = PTR_ERR(tosa_bat_bu.psy); - goto err_psy_reg_bu; - } - - ret = request_irq(gpiod_to_irq(tosa_bat_main.gpiod_full), - tosa_bat_gpio_isr, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "main full", &tosa_bat_main); - if (ret) - goto err_req_main; - - ret = request_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full), - tosa_bat_gpio_isr, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "jacket full", &tosa_bat_jacket); - if (ret) - goto err_req_jacket; - - ret = request_irq(gpiod_to_irq(jacket_detect), - tosa_bat_gpio_isr, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - "jacket detect", &tosa_bat_jacket); - if (!ret) { - schedule_work(&bat_work); - return 0; - } - - free_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full), &tosa_bat_jacket); -err_req_jacket: - free_irq(gpiod_to_irq(tosa_bat_main.gpiod_full), &tosa_bat_main); -err_req_main: - power_supply_unregister(tosa_bat_bu.psy); -err_psy_reg_bu: - power_supply_unregister(tosa_bat_jacket.psy); -err_psy_reg_jacket: - power_supply_unregister(tosa_bat_main.psy); -err_psy_reg_main: - - /* see comment in tosa_bat_remove */ - cancel_work_sync(&bat_work); - - return ret; -} - -static int tosa_bat_remove(struct platform_device *dev) -{ - free_irq(gpiod_to_irq(jacket_detect), &tosa_bat_jacket); - free_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full), &tosa_bat_jacket); - free_irq(gpiod_to_irq(tosa_bat_main.gpiod_full), &tosa_bat_main); - - power_supply_unregister(tosa_bat_bu.psy); - power_supply_unregister(tosa_bat_jacket.psy); - power_supply_unregister(tosa_bat_main.psy); - - /* - * 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); - return 0; -} - -static struct platform_driver tosa_bat_driver = { - .driver.name = "wm97xx-battery", - .driver.owner = THIS_MODULE, - .probe = tosa_bat_probe, - .remove = tosa_bat_remove, - .suspend = tosa_bat_suspend, - .resume = tosa_bat_resume, -}; - -module_platform_driver(tosa_bat_driver); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Dmitry Baryshkov"); -MODULE_DESCRIPTION("Tosa battery driver"); -MODULE_ALIAS("platform:wm97xx-battery"); diff --git a/drivers/power/supply/z2_battery.c b/drivers/power/supply/z2_battery.c deleted file mode 100644 index 0ba4a590a0a5..000000000000 --- a/drivers/power/supply/z2_battery.c +++ /dev/null @@ -1,318 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Battery measurement code for Zipit Z2 - * - * Copyright (C) 2009 Peter Edwards <sweetlilmre@gmail.com> - */ - -#include <linux/module.h> -#include <linux/gpio/consumer.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/power_supply.h> -#include <linux/slab.h> -#include <linux/z2_battery.h> - -#define Z2_DEFAULT_NAME "Z2" - -struct z2_charger { - struct z2_battery_info *info; - struct gpio_desc *charge_gpiod; - int bat_status; - struct i2c_client *client; - struct power_supply *batt_ps; - struct power_supply_desc batt_ps_desc; - struct mutex work_lock; - struct work_struct bat_work; -}; - -static unsigned long z2_read_bat(struct z2_charger *charger) -{ - int data; - data = i2c_smbus_read_byte_data(charger->client, - charger->info->batt_I2C_reg); - if (data < 0) - return 0; - - return data * charger->info->batt_mult / charger->info->batt_div; -} - -static int z2_batt_get_property(struct power_supply *batt_ps, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct z2_charger *charger = power_supply_get_drvdata(batt_ps); - struct z2_battery_info *info = charger->info; - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - val->intval = charger->bat_status; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = info->batt_tech; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - if (info->batt_I2C_reg >= 0) - val->intval = z2_read_bat(charger); - else - return -EINVAL; - break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX: - if (info->max_voltage >= 0) - val->intval = info->max_voltage; - else - return -EINVAL; - break; - case POWER_SUPPLY_PROP_VOLTAGE_MIN: - if (info->min_voltage >= 0) - val->intval = info->min_voltage; - else - return -EINVAL; - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = 1; - break; - default: - return -EINVAL; - } - - return 0; -} - -static void z2_batt_ext_power_changed(struct power_supply *batt_ps) -{ - struct z2_charger *charger = power_supply_get_drvdata(batt_ps); - - schedule_work(&charger->bat_work); -} - -static void z2_batt_update(struct z2_charger *charger) -{ - int old_status = charger->bat_status; - - mutex_lock(&charger->work_lock); - - charger->bat_status = charger->charge_gpiod ? - (gpiod_get_value(charger->charge_gpiod) ? - POWER_SUPPLY_STATUS_CHARGING : - POWER_SUPPLY_STATUS_DISCHARGING) : - POWER_SUPPLY_STATUS_UNKNOWN; - - if (old_status != charger->bat_status) { - pr_debug("%s: %i -> %i\n", charger->batt_ps->desc->name, - old_status, - charger->bat_status); - power_supply_changed(charger->batt_ps); - } - - mutex_unlock(&charger->work_lock); -} - -static void z2_batt_work(struct work_struct *work) -{ - struct z2_charger *charger; - charger = container_of(work, struct z2_charger, bat_work); - z2_batt_update(charger); -} - -static irqreturn_t z2_charge_switch_irq(int irq, void *devid) -{ - struct z2_charger *charger = devid; - schedule_work(&charger->bat_work); - return IRQ_HANDLED; -} - -static int z2_batt_ps_init(struct z2_charger *charger, int props) -{ - int i = 0; - enum power_supply_property *prop; - struct z2_battery_info *info = charger->info; - - if (charger->charge_gpiod) - props++; /* POWER_SUPPLY_PROP_STATUS */ - if (info->batt_tech >= 0) - props++; /* POWER_SUPPLY_PROP_TECHNOLOGY */ - if (info->batt_I2C_reg >= 0) - props++; /* POWER_SUPPLY_PROP_VOLTAGE_NOW */ - if (info->max_voltage >= 0) - props++; /* POWER_SUPPLY_PROP_VOLTAGE_MAX */ - if (info->min_voltage >= 0) - props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */ - - prop = kcalloc(props, sizeof(*prop), GFP_KERNEL); - if (!prop) - return -ENOMEM; - - prop[i++] = POWER_SUPPLY_PROP_PRESENT; - if (charger->charge_gpiod) - prop[i++] = POWER_SUPPLY_PROP_STATUS; - if (info->batt_tech >= 0) - prop[i++] = POWER_SUPPLY_PROP_TECHNOLOGY; - if (info->batt_I2C_reg >= 0) - prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_NOW; - if (info->max_voltage >= 0) - prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MAX; - if (info->min_voltage >= 0) - prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MIN; - - if (!info->batt_name) { - dev_info(&charger->client->dev, - "Please consider setting proper battery " - "name in platform definition file, falling " - "back to name \" Z2_DEFAULT_NAME \"\n"); - charger->batt_ps_desc.name = Z2_DEFAULT_NAME; - } else - charger->batt_ps_desc.name = info->batt_name; - - charger->batt_ps_desc.properties = prop; - charger->batt_ps_desc.num_properties = props; - charger->batt_ps_desc.type = POWER_SUPPLY_TYPE_BATTERY; - charger->batt_ps_desc.get_property = z2_batt_get_property; - charger->batt_ps_desc.external_power_changed = - z2_batt_ext_power_changed; - charger->batt_ps_desc.use_for_apm = 1; - - return 0; -} - -static int z2_batt_probe(struct i2c_client *client) -{ - int ret = 0; - int props = 1; /* POWER_SUPPLY_PROP_PRESENT */ - struct z2_charger *charger; - struct z2_battery_info *info = client->dev.platform_data; - struct power_supply_config psy_cfg = {}; - - if (info == NULL) { - dev_err(&client->dev, - "Please set platform device platform_data" - " to a valid z2_battery_info pointer!\n"); - return -EINVAL; - } - - charger = kzalloc(sizeof(*charger), GFP_KERNEL); - if (charger == NULL) - return -ENOMEM; - - charger->bat_status = POWER_SUPPLY_STATUS_UNKNOWN; - charger->info = info; - charger->client = client; - i2c_set_clientdata(client, charger); - psy_cfg.drv_data = charger; - - mutex_init(&charger->work_lock); - - charger->charge_gpiod = devm_gpiod_get_optional(&client->dev, - NULL, GPIOD_IN); - if (IS_ERR(charger->charge_gpiod)) { - ret = dev_err_probe(&client->dev, - PTR_ERR(charger->charge_gpiod), - "failed to get charge GPIO\n"); - goto err; - } - - if (charger->charge_gpiod) { - gpiod_set_consumer_name(charger->charge_gpiod, "BATT CHRG"); - - irq_set_irq_type(gpiod_to_irq(charger->charge_gpiod), - IRQ_TYPE_EDGE_BOTH); - ret = request_irq(gpiod_to_irq(charger->charge_gpiod), - z2_charge_switch_irq, 0, - "AC Detect", charger); - if (ret) - goto err; - } - - ret = z2_batt_ps_init(charger, props); - if (ret) - goto err3; - - INIT_WORK(&charger->bat_work, z2_batt_work); - - charger->batt_ps = power_supply_register(&client->dev, - &charger->batt_ps_desc, - &psy_cfg); - if (IS_ERR(charger->batt_ps)) { - ret = PTR_ERR(charger->batt_ps); - goto err4; - } - - schedule_work(&charger->bat_work); - - return 0; - -err4: - kfree(charger->batt_ps_desc.properties); -err3: - if (charger->charge_gpiod) - free_irq(gpiod_to_irq(charger->charge_gpiod), charger); -err: - kfree(charger); - return ret; -} - -static void z2_batt_remove(struct i2c_client *client) -{ - struct z2_charger *charger = i2c_get_clientdata(client); - - cancel_work_sync(&charger->bat_work); - power_supply_unregister(charger->batt_ps); - - kfree(charger->batt_ps_desc.properties); - if (charger->charge_gpiod) - free_irq(gpiod_to_irq(charger->charge_gpiod), charger); - - kfree(charger); -} - -#ifdef CONFIG_PM -static int z2_batt_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct z2_charger *charger = i2c_get_clientdata(client); - - flush_work(&charger->bat_work); - return 0; -} - -static int z2_batt_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct z2_charger *charger = i2c_get_clientdata(client); - - schedule_work(&charger->bat_work); - return 0; -} - -static const struct dev_pm_ops z2_battery_pm_ops = { - .suspend = z2_batt_suspend, - .resume = z2_batt_resume, -}; - -#define Z2_BATTERY_PM_OPS (&z2_battery_pm_ops) - -#else -#define Z2_BATTERY_PM_OPS (NULL) -#endif - -static const struct i2c_device_id z2_batt_id[] = { - { "aer915", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, z2_batt_id); - -static struct i2c_driver z2_batt_driver = { - .driver = { - .name = "z2-battery", - .pm = Z2_BATTERY_PM_OPS - }, - .probe_new = z2_batt_probe, - .remove = z2_batt_remove, - .id_table = z2_batt_id, -}; -module_i2c_driver(z2_batt_driver); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Peter Edwards <sweetlilmre@gmail.com>"); -MODULE_DESCRIPTION("Zipit Z2 battery driver"); |