power supply and reset changes for the v5.1 series
* at91-reset: add sam9x60 support * sc27xx: improve capacity logic * goldfish_battery: enhance driver by adding many new properties * isp1704: drop platform data and migrate to gpiod * misc. small fixes and improvements -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAlx+8LYACgkQ2O7X88g7 +prQew//RFv4KDosWXjxJ+2FgjYke8sjwf8oRN6CD2PyYdX0JY8O4fIucqGn6w+d Xvw/JBTpV+e3J8C0ZEYC7eN3wbgFh+pBI1TYa+gepMLsgv/uqGCuBGQPJoddkiLy AjTIDITBMDBJonQEmuxMxbA+FmnJ0FxLKOl6EInesDIU1UiEiMsmkDRU9gj88PQQ DplsADjw8L5ktGvjfj11HY/iTAaJwSPa3X0jhpBpiR6zJs2iqN4JHYunoTm7ss+i NSh19haS5E1yifRMmF8QTHXZB4KmaNGNSL2MFU7fwTP+tkZpn/MjWlTE57IuzT8v MIGVoXZMsvWDIaMc9SRnYaQ2rFD+A3Z8fkXm5KYZdjvNtDe2y7R+omWjAaHHUOME Nctj0qY4UcS4820LnZUsg8txsu7oDTpnh4GST5w9rBGtYqWrdAZ+B8e/a8bqO1Rt 2mUQdjIGSKzzamBJDswY26gFm0VozwND3WE8aKNFfFK2M6kkM1vqmqpV/QIpjBOY QzhbGf3vMJbqfwmyrBbmkLbjlY02XAmxM7h0wlwVLg2vGz/9LOf5ilpdHu2YxLHL OXB+RMQudgDou665Gc55PD5NwpJQGU2vImxIHjPUYrYOOwVfDci2MWyxxiFL+bEd Bk62pNOVmsPmXkRXp8+1e02nta/dwtle1oTGFtqRN7v3RynMTM4= =Etl6 -----END PGP SIGNATURE----- Merge tag 'for-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply Pull power supply and reset updates from Sebastian Reichel: "Nothing too fancy in the power-supply subsystem this time. There are less patches than usual, since I did not have enough time to review them in time. The good news is, that all patches have been in linux-next for more than two weeks and there are no complicated cross-subsystem patchsets this time! Summary: - at91-reset: add sam9x60 support - sc27xx: improve capacity logic - goldfish_battery: enhance driver by adding many new properties - isp1704: drop platform data and migrate to gpiod - misc small fixes and improvements" * tag 'for-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (25 commits) power: reset: at91-reset: add support for sam9x60 SoC dt-bindings: arm: atmel: add new sam9x60 reset controller binding dt-bindings: arm: atmel: add missing samx7 to reset controller max17042_battery: fix potential use-after-free on device remove power: supply: core: Add a field to support battery max voltage dt-bindings: power: supply: Add voltage-max-design-microvolt property bq27x00: use cached flags power: supply: ds2782: fix possible use-after-free on remove power: supply: bq25890: show max charge current/voltage as configured power: supply: sc27xx: Fix capacity saving function power: supply: sc27xx: Fix the incorrect formula when converting capacity to coulomb counter power: supply: sc27xx: Add one property to read charge voltage dt-bindings: power: sc27xx: Add one IIO channel to read charge voltage drivers: power: supply: goldfish_battery: Add support for reading more properties power: supply: charger-manager: Fix trivial language typos cpcap-charger: generate events for userspace power: supply: remove some duplicated includes power: twl4030: fix a missing check of return value drivers: power: supply: goldfish_battery: Use tabs for alignment drivers: power: supply: goldfish_battery: Fix alignment ...
This commit is contained in:
Коммит
1cabd3e0bd
|
@ -21,7 +21,8 @@ Its subnodes can be:
|
|||
|
||||
RSTC Reset Controller required properties:
|
||||
- compatible: Should be "atmel,<chip>-rstc".
|
||||
<chip> can be "at91sam9260" or "at91sam9g45" or "sama5d3"
|
||||
<chip> can be "at91sam9260", "at91sam9g45", "sama5d3" or "samx7"
|
||||
it also can be "microchip,sam9x60-rstc"
|
||||
- reg: Should contain registers location and length
|
||||
- clocks: phandle to input clock.
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ Required Properties:
|
|||
|
||||
Optional Properties:
|
||||
- voltage-min-design-microvolt: drained battery voltage
|
||||
- voltage-max-design-microvolt: fully charged battery voltage
|
||||
- energy-full-design-microwatt-hours: battery design energy
|
||||
- charge-full-design-microamp-hours: battery design capacity
|
||||
- precharge-current-microamp: current for pre-charge phase
|
||||
|
@ -48,6 +49,7 @@ Example:
|
|||
bat: battery {
|
||||
compatible = "simple-battery";
|
||||
voltage-min-design-microvolt = <3200000>;
|
||||
voltage-max-design-microvolt = <4200000>;
|
||||
energy-full-design-microwatt-hours = <5290000>;
|
||||
charge-full-design-microamp-hours = <1430000>;
|
||||
precharge-current-microamp = <256000>;
|
||||
|
|
|
@ -9,8 +9,8 @@ Required properties:
|
|||
"sprd,sc2731-fgu".
|
||||
- reg: The address offset of fuel gauge unit.
|
||||
- battery-detect-gpios: GPIO for battery detection.
|
||||
- io-channels: Specify the IIO ADC channel to get temperature.
|
||||
- io-channel-names: Should be "bat-temp".
|
||||
- io-channels: Specify the IIO ADC channels to get temperature and charge voltage.
|
||||
- io-channel-names: Should be "bat-temp" or "charge-vol".
|
||||
- nvmem-cells: A phandle to the calibration cells provided by eFuse device.
|
||||
- nvmem-cell-names: Should be "fgu_calib".
|
||||
- monitored-battery: Phandle of battery characteristics devicetree node.
|
||||
|
@ -47,8 +47,8 @@ Example:
|
|||
compatible = "sprd,sc2731-fgu";
|
||||
reg = <0xa00>;
|
||||
battery-detect-gpios = <&pmic_eic 9 GPIO_ACTIVE_HIGH>;
|
||||
io-channels = <&pmic_adc 5>;
|
||||
io-channel-names = "bat-temp";
|
||||
io-channels = <&pmic_adc 5>, <&pmic_adc 14>;
|
||||
io-channel-names = "bat-temp", "charge-vol";
|
||||
nvmem-cells = <&fgu_calib>;
|
||||
nvmem-cell-names = "fgu_calib";
|
||||
monitored-battery = <&bat>;
|
||||
|
|
|
@ -44,6 +44,9 @@ enum reset_type {
|
|||
RESET_TYPE_WATCHDOG = 2,
|
||||
RESET_TYPE_SOFTWARE = 3,
|
||||
RESET_TYPE_USER = 4,
|
||||
RESET_TYPE_CPU_FAIL = 6,
|
||||
RESET_TYPE_XTAL_FAIL = 7,
|
||||
RESET_TYPE_ULP2 = 8,
|
||||
};
|
||||
|
||||
static void __iomem *at91_ramc_base[2], *at91_rstc_base;
|
||||
|
@ -164,6 +167,15 @@ static void __init at91_reset_status(struct platform_device *pdev)
|
|||
case RESET_TYPE_USER:
|
||||
reason = "user reset";
|
||||
break;
|
||||
case RESET_TYPE_CPU_FAIL:
|
||||
reason = "CPU clock failure detection";
|
||||
break;
|
||||
case RESET_TYPE_XTAL_FAIL:
|
||||
reason = "32.768 kHz crystal failure detection";
|
||||
break;
|
||||
case RESET_TYPE_ULP2:
|
||||
reason = "ULP2 reset";
|
||||
break;
|
||||
default:
|
||||
reason = "unknown reset";
|
||||
break;
|
||||
|
@ -183,6 +195,7 @@ static const struct of_device_id at91_reset_of_match[] = {
|
|||
{ .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart },
|
||||
{ .compatible = "atmel,sama5d3-rstc", .data = sama5d3_restart },
|
||||
{ .compatible = "atmel,samx7-rstc", .data = samx7_restart },
|
||||
{ .compatible = "microchip,sam9x60-rstc", .data = samx7_restart },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, at91_reset_of_match);
|
||||
|
|
|
@ -307,22 +307,12 @@ static int fuel_gauge_debug_show(struct seq_file *s, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int debug_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, fuel_gauge_debug_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fg_debug_fops = {
|
||||
.open = debug_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
DEFINE_SHOW_ATTRIBUTE(fuel_gauge_debug);
|
||||
|
||||
static void fuel_gauge_create_debugfs(struct axp288_fg_info *info)
|
||||
{
|
||||
info->debug_file = debugfs_create_file("fuelgauge", 0666, NULL,
|
||||
info, &fg_debug_fops);
|
||||
info, &fuel_gauge_debug_fops);
|
||||
}
|
||||
|
||||
static void fuel_gauge_remove_debugfs(struct axp288_fg_info *info)
|
||||
|
|
|
@ -436,7 +436,7 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
|
|||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
|
||||
val->intval = bq25890_tables[TBL_ICHG].rt.max;
|
||||
val->intval = bq25890_find_val(bq->init_data.ichg, TBL_ICHG);
|
||||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
|
||||
|
@ -454,7 +454,7 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
|
|||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
|
||||
val->intval = bq25890_tables[TBL_VREG].rt.max;
|
||||
val->intval = bq25890_find_val(bq->init_data.vreg, TBL_VREG);
|
||||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
|
||||
|
|
|
@ -1555,27 +1555,14 @@ static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)
|
|||
return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read flag register.
|
||||
* Return < 0 if something fails.
|
||||
*/
|
||||
static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
|
||||
{
|
||||
int flags;
|
||||
bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
|
||||
|
||||
flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
|
||||
if (flags < 0) {
|
||||
dev_err(di->dev, "error reading flag register:%d\n", flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
/* Unlikely but important to return first */
|
||||
if (unlikely(bq27xxx_battery_overtemp(di, flags)))
|
||||
if (unlikely(bq27xxx_battery_overtemp(di, di->cache.flags)))
|
||||
return POWER_SUPPLY_HEALTH_OVERHEAT;
|
||||
if (unlikely(bq27xxx_battery_undertemp(di, flags)))
|
||||
if (unlikely(bq27xxx_battery_undertemp(di, di->cache.flags)))
|
||||
return POWER_SUPPLY_HEALTH_COLD;
|
||||
if (unlikely(bq27xxx_battery_dead(di, flags)))
|
||||
if (unlikely(bq27xxx_battery_dead(di, di->cache.flags)))
|
||||
return POWER_SUPPLY_HEALTH_DEAD;
|
||||
|
||||
return POWER_SUPPLY_HEALTH_GOOD;
|
||||
|
@ -1612,6 +1599,7 @@ void bq27xxx_battery_update(struct bq27xxx_device_info *di)
|
|||
cache.capacity = bq27xxx_battery_read_soc(di);
|
||||
if (di->regs[BQ27XXX_REG_AE] != INVALID_REG_ADDR)
|
||||
cache.energy = bq27xxx_battery_read_energy(di);
|
||||
di->cache.flags = cache.flags;
|
||||
cache.health = bq27xxx_battery_read_health(di);
|
||||
}
|
||||
if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* This driver enables to monitor battery health and control charger
|
||||
* during suspend-to-mem.
|
||||
* Charger manager depends on other devices. register this later than
|
||||
* Charger manager depends on other devices. Register this later than
|
||||
* the depending devices.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include <linux/thermal.h>
|
||||
|
||||
/*
|
||||
* Default termperature threshold for charging.
|
||||
* Default temperature threshold for charging.
|
||||
* Every temperature units are in tenth of centigrade.
|
||||
*/
|
||||
#define CM_DEFAULT_RECHARGE_TEMP_DIFF 50
|
||||
|
@ -356,7 +356,7 @@ static bool is_polling_required(struct charger_manager *cm)
|
|||
* Note that Charger Manager keeps the charger enabled regardless whether
|
||||
* the charger is charging or not (because battery is full or no external
|
||||
* power source exists) except when CM needs to disable chargers forcibly
|
||||
* bacause of emergency causes; when the battery is overheated or too cold.
|
||||
* because of emergency causes; when the battery is overheated or too cold.
|
||||
*/
|
||||
static int try_charger_enable(struct charger_manager *cm, bool enable)
|
||||
{
|
||||
|
@ -643,7 +643,7 @@ static int cm_check_thermal_status(struct charger_manager *cm)
|
|||
if (ret) {
|
||||
/* FIXME:
|
||||
* No information of battery temperature might
|
||||
* occur hazadous result. We have to handle it
|
||||
* occur hazardous result. We have to handle it
|
||||
* depending on battery type.
|
||||
*/
|
||||
dev_err(cm->dev, "Failed to get battery temperature\n");
|
||||
|
@ -693,7 +693,7 @@ static bool _cm_monitor(struct charger_manager *cm)
|
|||
uevent_notify(cm, default_event_names[temp_alrt]);
|
||||
|
||||
/*
|
||||
* Check whole charging duration and discharing duration
|
||||
* Check whole charging duration and discharging duration
|
||||
* after full-batt.
|
||||
*/
|
||||
} else if (!cm->emergency_stop && check_charging_duration(cm)) {
|
||||
|
@ -866,7 +866,7 @@ static void battout_handler(struct charger_manager *cm)
|
|||
}
|
||||
|
||||
/**
|
||||
* misc_event_handler - Handler for other evnets
|
||||
* misc_event_handler - Handler for other events
|
||||
* @cm: the Charger Manager representing the battery.
|
||||
* @type: the Charger Manager representing the battery.
|
||||
*/
|
||||
|
@ -1218,7 +1218,7 @@ static int charger_extcon_init(struct charger_manager *cm,
|
|||
}
|
||||
|
||||
/**
|
||||
* charger_manager_register_extcon - Register extcon device to recevie state
|
||||
* charger_manager_register_extcon - Register extcon device to receive state
|
||||
* of charger cable.
|
||||
* @cm: the Charger Manager representing the battery.
|
||||
*
|
||||
|
@ -1538,7 +1538,7 @@ static struct charger_desc *of_cm_parse_desc(struct device *dev)
|
|||
of_property_read_u32(np, "cm-discharging-max",
|
||||
&desc->discharging_max_duration_ms);
|
||||
|
||||
/* battery charger regualtors */
|
||||
/* battery charger regulators */
|
||||
desc->num_charger_regulators = of_get_child_count(np);
|
||||
if (desc->num_charger_regulators) {
|
||||
struct charger_regulator *chg_regs;
|
||||
|
@ -1801,7 +1801,7 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|||
|
||||
/*
|
||||
* Charger-manager have to check the charging state right after
|
||||
* tialization of charger-manager and then update current charging
|
||||
* initialization of charger-manager and then update current charging
|
||||
* state.
|
||||
*/
|
||||
cm_monitor();
|
||||
|
|
|
@ -458,6 +458,7 @@ static void cpcap_usb_detect(struct work_struct *work)
|
|||
goto out_err;
|
||||
}
|
||||
|
||||
power_supply_changed(ddata->usb);
|
||||
return;
|
||||
|
||||
out_err:
|
||||
|
|
|
@ -319,17 +319,17 @@ static void ds278x_power_supply_init(struct power_supply_desc *battery)
|
|||
static int ds278x_battery_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ds278x_info *info = i2c_get_clientdata(client);
|
||||
int id = info->id;
|
||||
|
||||
power_supply_unregister(info->battery);
|
||||
cancel_delayed_work_sync(&info->bat_work);
|
||||
kfree(info->battery_desc.name);
|
||||
kfree(info);
|
||||
|
||||
mutex_lock(&battery_lock);
|
||||
idr_remove(&battery_id, info->id);
|
||||
idr_remove(&battery_id, id);
|
||||
mutex_unlock(&battery_lock);
|
||||
|
||||
cancel_delayed_work(&info->bat_work);
|
||||
|
||||
kfree(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL
|
||||
/*
|
||||
* Power supply driver for the goldfish emulator
|
||||
*
|
||||
|
@ -5,15 +6,6 @@
|
|||
* Copyright (C) 2012 Intel, Inc.
|
||||
* Copyright (C) 2013 Intel, Inc.
|
||||
* Author: Mike Lockwood <lockwood@android.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -40,12 +32,6 @@ struct goldfish_battery_data {
|
|||
#define GOLDFISH_BATTERY_WRITE(data, addr, x) \
|
||||
(writel(x, data->reg_base + addr))
|
||||
|
||||
/*
|
||||
* Temporary variable used between goldfish_battery_probe() and
|
||||
* goldfish_battery_open().
|
||||
*/
|
||||
static struct goldfish_battery_data *battery_data;
|
||||
|
||||
enum {
|
||||
/* status register */
|
||||
BATTERY_INT_STATUS = 0x00,
|
||||
|
@ -57,6 +43,15 @@ enum {
|
|||
BATTERY_HEALTH = 0x10,
|
||||
BATTERY_PRESENT = 0x14,
|
||||
BATTERY_CAPACITY = 0x18,
|
||||
BATTERY_VOLTAGE = 0x1C,
|
||||
BATTERY_TEMP = 0x20,
|
||||
BATTERY_CHARGE_COUNTER = 0x24,
|
||||
BATTERY_VOLTAGE_MAX = 0x28,
|
||||
BATTERY_CURRENT_MAX = 0x2C,
|
||||
BATTERY_CURRENT_NOW = 0x30,
|
||||
BATTERY_CURRENT_AVG = 0x34,
|
||||
BATTERY_CHARGE_FULL_UAH = 0x38,
|
||||
BATTERY_CYCLE_COUNT = 0x40,
|
||||
|
||||
BATTERY_STATUS_CHANGED = 1U << 0,
|
||||
AC_STATUS_CHANGED = 1U << 1,
|
||||
|
@ -75,6 +70,12 @@ static int goldfish_ac_get_property(struct power_supply *psy,
|
|||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_AC_ONLINE);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_VOLTAGE_MAX);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_CURRENT_MAX);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
@ -105,6 +106,29 @@ static int goldfish_battery_get_property(struct power_supply *psy,
|
|||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_CAPACITY);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_VOLTAGE);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_TEMP:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_TEMP);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data,
|
||||
BATTERY_CHARGE_COUNTER);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_CURRENT_NOW);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_AVG:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_CURRENT_AVG);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_FULL:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data,
|
||||
BATTERY_CHARGE_FULL_UAH);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CYCLE_COUNT:
|
||||
val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_CYCLE_COUNT);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
@ -119,10 +143,19 @@ static enum power_supply_property goldfish_battery_props[] = {
|
|||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_TECHNOLOGY,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_TEMP,
|
||||
POWER_SUPPLY_PROP_CHARGE_COUNTER,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_AVG,
|
||||
POWER_SUPPLY_PROP_CHARGE_FULL,
|
||||
POWER_SUPPLY_PROP_CYCLE_COUNT,
|
||||
};
|
||||
|
||||
static enum power_supply_property goldfish_ac_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||
};
|
||||
|
||||
static irqreturn_t goldfish_battery_interrupt(int irq, void *dev_id)
|
||||
|
@ -193,7 +226,8 @@ static int goldfish_battery_probe(struct platform_device *pdev)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, data->irq, goldfish_battery_interrupt,
|
||||
ret = devm_request_irq(&pdev->dev, data->irq,
|
||||
goldfish_battery_interrupt,
|
||||
IRQF_SHARED, pdev->name, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -212,7 +246,6 @@ static int goldfish_battery_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
battery_data = data;
|
||||
|
||||
GOLDFISH_BATTERY_WRITE(data, BATTERY_INT_ENABLE, BATTERY_INT_MASK);
|
||||
return 0;
|
||||
|
@ -224,7 +257,6 @@ static int goldfish_battery_remove(struct platform_device *pdev)
|
|||
|
||||
power_supply_unregister(data->battery);
|
||||
power_supply_unregister(data->ac);
|
||||
battery_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,13 +30,12 @@
|
|||
#include <linux/power_supply.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/usb/ulpi.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/power/isp1704_charger.h>
|
||||
|
||||
/* Vendor specific Power Control register */
|
||||
#define ISP1704_PWR_CTRL 0x3d
|
||||
|
@ -60,6 +59,7 @@ struct isp1704_charger {
|
|||
struct device *dev;
|
||||
struct power_supply *psy;
|
||||
struct power_supply_desc psy_desc;
|
||||
struct gpio_desc *enable_gpio;
|
||||
struct usb_phy *phy;
|
||||
struct notifier_block nb;
|
||||
struct work_struct work;
|
||||
|
@ -81,18 +81,9 @@ static inline int isp1704_write(struct isp1704_charger *isp, u32 reg, u32 val)
|
|||
return usb_phy_io_write(isp->phy, val, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable/enable the power from the isp1704 if a function for it
|
||||
* has been provided with platform data.
|
||||
*/
|
||||
static void isp1704_charger_set_power(struct isp1704_charger *isp, bool on)
|
||||
{
|
||||
struct isp1704_charger_data *board = isp->dev->platform_data;
|
||||
|
||||
if (board && board->set_power)
|
||||
board->set_power(on);
|
||||
else if (board)
|
||||
gpio_set_value(board->enable_gpio, on);
|
||||
gpiod_set_value(isp->enable_gpio, on);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -405,46 +396,19 @@ static int isp1704_charger_probe(struct platform_device *pdev)
|
|||
int ret = -ENODEV;
|
||||
struct power_supply_config psy_cfg = {};
|
||||
|
||||
struct isp1704_charger_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
if (np) {
|
||||
int gpio = of_get_named_gpio(np, "nxp,enable-gpio", 0);
|
||||
|
||||
if (gpio < 0) {
|
||||
dev_err(&pdev->dev, "missing DT GPIO nxp,enable-gpio\n");
|
||||
return gpio;
|
||||
}
|
||||
|
||||
pdata = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct isp1704_charger_data), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
ret = -ENOMEM;
|
||||
goto fail0;
|
||||
}
|
||||
pdata->enable_gpio = gpio;
|
||||
|
||||
dev_info(&pdev->dev, "init gpio %d\n", pdata->enable_gpio);
|
||||
|
||||
ret = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio,
|
||||
GPIOF_OUT_INIT_HIGH, "isp1704_reset");
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "gpio request failed\n");
|
||||
goto fail0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "missing platform data!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
|
||||
if (!isp)
|
||||
return -ENOMEM;
|
||||
|
||||
if (np)
|
||||
isp->enable_gpio = devm_gpiod_get(&pdev->dev, "nxp,enable",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(isp->enable_gpio)) {
|
||||
ret = PTR_ERR(isp->enable_gpio);
|
||||
dev_err(&pdev->dev, "Could not get reset gpio: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pdev->dev.of_node)
|
||||
isp->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
|
||||
else
|
||||
isp->phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
|
||||
|
|
|
@ -995,6 +995,13 @@ static const struct power_supply_desc max17042_no_current_sense_psy_desc = {
|
|||
.num_properties = ARRAY_SIZE(max17042_battery_props) - 2,
|
||||
};
|
||||
|
||||
static void max17042_stop_work(void *data)
|
||||
{
|
||||
struct max17042_chip *chip = data;
|
||||
|
||||
cancel_work_sync(&chip->work);
|
||||
}
|
||||
|
||||
static int max17042_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
@ -1101,6 +1108,9 @@ static int max17042_probe(struct i2c_client *client,
|
|||
regmap_read(chip->regmap, MAX17042_STATUS, &val);
|
||||
if (val & STATUS_POR_BIT) {
|
||||
INIT_WORK(&chip->work, max17042_init_worker);
|
||||
ret = devm_add_action(&client->dev, max17042_stop_work, chip);
|
||||
if (ret)
|
||||
return ret;
|
||||
schedule_work(&chip->work);
|
||||
} else {
|
||||
chip->init_complete = 1;
|
||||
|
|
|
@ -156,8 +156,6 @@ static void power_supply_deferred_register_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/of.h>
|
||||
|
||||
static int __power_supply_populate_supplied_from(struct device *dev,
|
||||
void *data)
|
||||
{
|
||||
|
@ -575,6 +573,7 @@ int power_supply_get_battery_info(struct power_supply *psy,
|
|||
info->energy_full_design_uwh = -EINVAL;
|
||||
info->charge_full_design_uah = -EINVAL;
|
||||
info->voltage_min_design_uv = -EINVAL;
|
||||
info->voltage_max_design_uv = -EINVAL;
|
||||
info->precharge_current_ua = -EINVAL;
|
||||
info->charge_term_current_ua = -EINVAL;
|
||||
info->constant_charge_current_max_ua = -EINVAL;
|
||||
|
@ -615,6 +614,8 @@ int power_supply_get_battery_info(struct power_supply *psy,
|
|||
&info->charge_full_design_uah);
|
||||
of_property_read_u32(battery_np, "voltage-min-design-microvolt",
|
||||
&info->voltage_min_design_uv);
|
||||
of_property_read_u32(battery_np, "voltage-max-design-microvolt",
|
||||
&info->voltage_max_design_uv);
|
||||
of_property_read_u32(battery_np, "precharge-current-microamp",
|
||||
&info->precharge_current_ua);
|
||||
of_property_read_u32(battery_np, "charge-term-current-microamp",
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
* @lock: protect the structure
|
||||
* @gpiod: GPIO for battery detection
|
||||
* @channel: IIO channel to get battery temperature
|
||||
* @charge_chan: IIO channel to get charge voltage
|
||||
* @internal_resist: the battery internal resistance in mOhm
|
||||
* @total_cap: the total capacity of the battery in mAh
|
||||
* @init_cap: the initial capacity of the battery in mAh
|
||||
|
@ -92,6 +93,7 @@ struct sc27xx_fgu_data {
|
|||
struct mutex lock;
|
||||
struct gpio_desc *gpiod;
|
||||
struct iio_channel *channel;
|
||||
struct iio_channel *charge_chan;
|
||||
bool bat_present;
|
||||
int internal_resist;
|
||||
int total_cap;
|
||||
|
@ -169,10 +171,37 @@ static int sc27xx_fgu_save_boot_mode(struct sc27xx_fgu_data *data,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return regmap_update_bits(data->regmap,
|
||||
/*
|
||||
* Since the user area registers are put on power always-on region,
|
||||
* then these registers changing time will be a little long. Thus
|
||||
* here we should delay 200us to wait until values are updated
|
||||
* successfully according to the datasheet.
|
||||
*/
|
||||
udelay(200);
|
||||
|
||||
ret = regmap_update_bits(data->regmap,
|
||||
data->base + SC27XX_FGU_USER_AREA_SET,
|
||||
SC27XX_FGU_MODE_AREA_MASK,
|
||||
boot_mode << SC27XX_FGU_MODE_AREA_SHIFT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Since the user area registers are put on power always-on region,
|
||||
* then these registers changing time will be a little long. Thus
|
||||
* here we should delay 200us to wait until values are updated
|
||||
* successfully according to the datasheet.
|
||||
*/
|
||||
udelay(200);
|
||||
|
||||
/*
|
||||
* According to the datasheet, we should set the USER_AREA_CLEAR to 0 to
|
||||
* make the user area data available, otherwise we can not save the user
|
||||
* area data.
|
||||
*/
|
||||
return regmap_update_bits(data->regmap,
|
||||
data->base + SC27XX_FGU_USER_AREA_CLEAR,
|
||||
SC27XX_FGU_MODE_AREA_MASK, 0);
|
||||
}
|
||||
|
||||
static int sc27xx_fgu_save_last_cap(struct sc27xx_fgu_data *data, int cap)
|
||||
|
@ -186,9 +215,36 @@ static int sc27xx_fgu_save_last_cap(struct sc27xx_fgu_data *data, int cap)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
return regmap_update_bits(data->regmap,
|
||||
/*
|
||||
* Since the user area registers are put on power always-on region,
|
||||
* then these registers changing time will be a little long. Thus
|
||||
* here we should delay 200us to wait until values are updated
|
||||
* successfully according to the datasheet.
|
||||
*/
|
||||
udelay(200);
|
||||
|
||||
ret = regmap_update_bits(data->regmap,
|
||||
data->base + SC27XX_FGU_USER_AREA_SET,
|
||||
SC27XX_FGU_CAP_AREA_MASK, cap);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Since the user area registers are put on power always-on region,
|
||||
* then these registers changing time will be a little long. Thus
|
||||
* here we should delay 200us to wait until values are updated
|
||||
* successfully according to the datasheet.
|
||||
*/
|
||||
udelay(200);
|
||||
|
||||
/*
|
||||
* According to the datasheet, we should set the USER_AREA_CLEAR to 0 to
|
||||
* make the user area data available, otherwise we can not save the user
|
||||
* area data.
|
||||
*/
|
||||
return regmap_update_bits(data->regmap,
|
||||
data->base + SC27XX_FGU_USER_AREA_CLEAR,
|
||||
SC27XX_FGU_CAP_AREA_MASK, 0);
|
||||
}
|
||||
|
||||
static int sc27xx_fgu_read_last_cap(struct sc27xx_fgu_data *data, int *cap)
|
||||
|
@ -391,6 +447,18 @@ static int sc27xx_fgu_get_vbat_ocv(struct sc27xx_fgu_data *data, int *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sc27xx_fgu_get_charge_vol(struct sc27xx_fgu_data *data, int *val)
|
||||
{
|
||||
int ret, vol;
|
||||
|
||||
ret = iio_read_channel_processed(data->charge_chan, &vol);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*val = vol * 1000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sc27xx_fgu_get_temp(struct sc27xx_fgu_data *data, int *temp)
|
||||
{
|
||||
return iio_read_channel_processed(data->channel, temp);
|
||||
|
@ -502,6 +570,14 @@ static int sc27xx_fgu_get_property(struct power_supply *psy,
|
|||
val->intval = value;
|
||||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
|
||||
ret = sc27xx_fgu_get_charge_vol(data, &value);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
val->intval = value;
|
||||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
case POWER_SUPPLY_PROP_CURRENT_AVG:
|
||||
ret = sc27xx_fgu_get_current(data, &value);
|
||||
|
@ -567,6 +643,7 @@ static enum power_supply_property sc27xx_fgu_props[] = {
|
|||
POWER_SUPPLY_PROP_VOLTAGE_OCV,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_AVG,
|
||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc sc27xx_fgu_desc = {
|
||||
|
@ -708,7 +785,7 @@ static int sc27xx_fgu_cap_to_clbcnt(struct sc27xx_fgu_data *data, int capacity)
|
|||
* Convert current capacity (mAh) to coulomb counter according to the
|
||||
* formula: 1 mAh =3.6 coulomb.
|
||||
*/
|
||||
return DIV_ROUND_CLOSEST(cur_cap * 36, 10);
|
||||
return DIV_ROUND_CLOSEST(cur_cap * 36 * data->cur_1000ma_adc, 10);
|
||||
}
|
||||
|
||||
static int sc27xx_fgu_calibration(struct sc27xx_fgu_data *data)
|
||||
|
@ -907,6 +984,12 @@ static int sc27xx_fgu_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(data->channel);
|
||||
}
|
||||
|
||||
data->charge_chan = devm_iio_channel_get(&pdev->dev, "charge-vol");
|
||||
if (IS_ERR(data->charge_chan)) {
|
||||
dev_err(&pdev->dev, "failed to get charge IIO channel\n");
|
||||
return PTR_ERR(data->charge_chan);
|
||||
}
|
||||
|
||||
data->gpiod = devm_gpiod_get(&pdev->dev, "bat-detect", GPIOD_IN);
|
||||
if (IS_ERR(data->gpiod)) {
|
||||
dev_err(&pdev->dev, "failed to get battery detection GPIO\n");
|
||||
|
|
|
@ -809,7 +809,9 @@ static int twl4030_bci_get_property(struct power_supply *psy,
|
|||
is_charging = state & TWL4030_MSTATEC_AC;
|
||||
if (!is_charging) {
|
||||
u8 s;
|
||||
twl4030_bci_read(TWL4030_BCIMDEN, &s);
|
||||
ret = twl4030_bci_read(TWL4030_BCIMDEN, &s);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (psy->desc->type == POWER_SUPPLY_TYPE_USB)
|
||||
is_charging = s & 1;
|
||||
else
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* ISP1704 USB Charger Detection driver
|
||||
*
|
||||
* Copyright (C) 2011 Nokia Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __ISP1704_CHARGER_H
|
||||
#define __ISP1704_CHARGER_H
|
||||
|
||||
struct isp1704_charger_data {
|
||||
void (*set_power)(bool on);
|
||||
int enable_gpio;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -332,6 +332,7 @@ struct power_supply_battery_info {
|
|||
int energy_full_design_uwh; /* microWatt-hours */
|
||||
int charge_full_design_uah; /* microAmp-hours */
|
||||
int voltage_min_design_uv; /* microVolts */
|
||||
int voltage_max_design_uv; /* microVolts */
|
||||
int precharge_current_ua; /* microAmps */
|
||||
int charge_term_current_ua; /* microAmps */
|
||||
int constant_charge_current_max_ua; /* microAmps */
|
||||
|
|
Загрузка…
Ссылка в новой задаче