Commit 9cc984e4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-v4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply

Pull power supply and reset changes from Sebastian Reichel:
 - add types for USB Type C and PD chargers
 - add act8945a charger driver
 - add ACPI/DT bindings for goldfish-battery
 - add support for versatile reset controller
 - misc fixes

* tag 'for-v4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (24 commits)
  power: pm2301-charger: use __maybe_unused to hide pm functions
  power: ipaq-micro-battery: use __maybe_unused to hide pm functions
  power_supply: 88pm860x_charger: do not pass NULL to power_supply_put
  jz4740-battery: Correct voltage change check
  power_supply: lp8788-charger: initialize boolean 'found'
  goldfish: Enable ACPI-based enumeration for goldfish battery
  power: goldfish_battery: add devicetree bindings
  power: act8945a: add charger driver for ACT8945A
  power: add documentation for ACT8945A's charger DT bindings
  ARM: dts: n900: Rename isp1704 to isp1707 to match correct name
  power_supply: bq27xxx_battery: Add of modalias and match table when CONFIG_OF is enabled
  power_supply: bq2415x_charger: Add of modalias and match table when CONFIG_OF is enabled
  power_supply: bq2415x_charger: Do not add acpi modalias when CONFIG_ACPI is not enabled
  power_supply: isp1704_charger: Add compatible of match for nxp,isp1707
  power_supply: isp1704_charger: Error messages when probe fail
  power_supply: Add types for USB Type C and PD chargers
  power: bq24735-charger: add 'ti,external-control' option
  power: bq24735-charger: document 'ti,external-control' option
  power: bq24735-charger: fix failed i2c with ac-detect
  power: reset: Fix dependencies for !HAS_IOMEM archs
  ...
parents b5b131c7 0df6e32b
Android Goldfish Battery
Android goldfish battery device generated by android emulator.
Required properties:
- compatible : should contain "google,goldfish-battery" to match emulator
- reg : <registers mapping>
- interrupts : <interrupt mapping>
Example:
goldfish_battery@9020000 {
compatible = "google,goldfish-battery";
reg = <0x9020000 0x1000>;
interrupts = <0x3>;
};
Device-Tree bindings for charger of Active-semi ACT8945A Multi-Function Device
Required properties:
- compatible: "active-semi,act8945a", please refer to ../mfd/act8945a.txt.
- active-semi,chglev-gpios: charge current level phandle with args
as described in ../gpio/gpio.txt.
Optional properties:
- active-semi,check-battery-temperature: boolean to check the battery
temperature or not.
- active-semi,input-voltage-threshold-microvolt: unit: mV;
Specifies the charger's input over-voltage threshold value;
The value can be: 6600, 7000, 7500, 8000; default: 6600
- active-semi,precondition-timeout: unit: minutes;
Specifies the charger's PRECONDITION safety timer setting value;
The value can be: 40, 60, 80, 0; If 0, it means to disable this timer;
default: 40.
- active-semi,total-timeout: unit: hours;
Specifies the charger's total safety timer setting value;
The value can be: 3, 4, 5, 0; If 0, it means to disable this timer;
default: 3.
Example:
pmic@5b {
compatible = "active-semi,act8945a";
reg = <0x5b>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_charger_chglev>;
active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>;
active-semi,input-voltage-threshold-microvolt = <6600>;
active-semi,precondition-timeout = <40>;
active-semi,total-timeout = <3>;
};
...@@ -22,6 +22,9 @@ Optional properties : ...@@ -22,6 +22,9 @@ Optional properties :
value must be between 128mA and 8.064A with a 128mA step resolution. The value must be between 128mA and 8.064A with a 128mA step resolution. The
POR value is 0x1000h. This number is in mA (e.g. 8064), see the spec for POR value is 0x1000h. This number is in mA (e.g. 8064), see the spec for
more information about the InputCurrent (0x3fh) register. more information about the InputCurrent (0x3fh) register.
- ti,external-control : Indicates that the charger is configured externally
and that the host should not attempt to enable/disable charging or set the
charge voltage/current.
Example: Example:
......
...@@ -107,8 +107,8 @@ proximity_sensor { ...@@ -107,8 +107,8 @@ proximity_sensor {
}; };
}; };
isp1704: isp1704 { isp1707: isp1707 {
compatible = "nxp,isp1704"; compatible = "nxp,isp1707";
nxp,enable-gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>; nxp,enable-gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>;
usb-phy = <&usb2_phy>; usb-phy = <&usb2_phy>;
}; };
...@@ -618,7 +618,7 @@ bq24150a: bq24150a@6b { ...@@ -618,7 +618,7 @@ bq24150a: bq24150a@6b {
ti,termination-current = <100>; ti,termination-current = <100>;
ti,resistor-sense = <68>; ti,resistor-sense = <68>;
ti,usb-charger-detection = <&isp1704>; ti,usb-charger-detection = <&isp1707>;
}; };
}; };
......
...@@ -435,7 +435,7 @@ static irqreturn_t pm860x_temp_handler(int irq, void *data) ...@@ -435,7 +435,7 @@ static irqreturn_t pm860x_temp_handler(int irq, void *data)
psy = power_supply_get_by_name(pm860x_supplied_to[0]); psy = power_supply_get_by_name(pm860x_supplied_to[0]);
if (!psy) if (!psy)
goto out; return IRQ_HANDLED;
ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &temp); ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &temp);
if (ret) if (ret)
goto out; goto out;
......
...@@ -75,6 +75,13 @@ config BATTERY_88PM860X ...@@ -75,6 +75,13 @@ config BATTERY_88PM860X
help help
Say Y here to enable battery monitor for Marvell 88PM860x chip. Say Y here to enable battery monitor for Marvell 88PM860x chip.
config BATTERY_ACT8945A
tristate "Active-semi ACT8945A charger driver"
depends on MFD_ACT8945A || COMPILE_TEST
help
Say Y here to enable support for power supply provided by
Active-semi ActivePath ACT8945A charger.
config BATTERY_DS2760 config BATTERY_DS2760
tristate "DS2760 battery driver (HP iPAQ & others)" tristate "DS2760 battery driver (HP iPAQ & others)"
depends on W1 && W1_SLAVE_DS2760 depends on W1 && W1_SLAVE_DS2760
......
...@@ -17,6 +17,7 @@ obj-$(CONFIG_WM8350_POWER) += wm8350_power.o ...@@ -17,6 +17,7 @@ obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
obj-$(CONFIG_TEST_POWER) += test_power.o obj-$(CONFIG_TEST_POWER) += test_power.o
obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o obj-$(CONFIG_BATTERY_88PM860X) += 88pm860x_battery.o
obj-$(CONFIG_BATTERY_ACT8945A) += act8945a_charger.o
obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o obj-$(CONFIG_BATTERY_DS2780) += ds2780_battery.o
obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o obj-$(CONFIG_BATTERY_DS2781) += ds2781_battery.o
......
/*
* Power supply driver for the Active-semi ACT8945A PMIC
*
* Copyright (C) 2015 Atmel Corporation
*
* Author: Wenyou Yang <wenyou.yang@atmel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/regmap.h>
static const char *act8945a_charger_model = "ACT8945A";
static const char *act8945a_charger_manufacturer = "Active-semi";
/**
* ACT8945A Charger Register Map
*/
/* 0x70: Reserved */
#define ACT8945A_APCH_CFG 0x71
#define ACT8945A_APCH_STATUS 0x78
#define ACT8945A_APCH_CTRL 0x79
#define ACT8945A_APCH_STATE 0x7A
/* ACT8945A_APCH_CFG */
#define APCH_CFG_OVPSET (0x3 << 0)
#define APCH_CFG_OVPSET_6V6 (0x0 << 0)
#define APCH_CFG_OVPSET_7V (0x1 << 0)
#define APCH_CFG_OVPSET_7V5 (0x2 << 0)
#define APCH_CFG_OVPSET_8V (0x3 << 0)
#define APCH_CFG_PRETIMO (0x3 << 2)
#define APCH_CFG_PRETIMO_40_MIN (0x0 << 2)
#define APCH_CFG_PRETIMO_60_MIN (0x1 << 2)
#define APCH_CFG_PRETIMO_80_MIN (0x2 << 2)
#define APCH_CFG_PRETIMO_DISABLED (0x3 << 2)
#define APCH_CFG_TOTTIMO (0x3 << 4)
#define APCH_CFG_TOTTIMO_3_HOUR (0x0 << 4)
#define APCH_CFG_TOTTIMO_4_HOUR (0x1 << 4)
#define APCH_CFG_TOTTIMO_5_HOUR (0x2 << 4)
#define APCH_CFG_TOTTIMO_DISABLED (0x3 << 4)
#define APCH_CFG_SUSCHG (0x1 << 7)
#define APCH_STATUS_CHGDAT BIT(0)
#define APCH_STATUS_INDAT BIT(1)
#define APCH_STATUS_TEMPDAT BIT(2)
#define APCH_STATUS_TIMRDAT BIT(3)
#define APCH_STATUS_CHGSTAT BIT(4)
#define APCH_STATUS_INSTAT BIT(5)
#define APCH_STATUS_TEMPSTAT BIT(6)
#define APCH_STATUS_TIMRSTAT BIT(7)
#define APCH_CTRL_CHGEOCOUT BIT(0)
#define APCH_CTRL_INDIS BIT(1)
#define APCH_CTRL_TEMPOUT BIT(2)
#define APCH_CTRL_TIMRPRE BIT(3)
#define APCH_CTRL_CHGEOCIN BIT(4)
#define APCH_CTRL_INCON BIT(5)
#define APCH_CTRL_TEMPIN BIT(6)
#define APCH_CTRL_TIMRTOT BIT(7)
#define APCH_STATE_ACINSTAT (0x1 << 1)
#define APCH_STATE_CSTATE (0x3 << 4)
#define APCH_STATE_CSTATE_SHIFT 4
#define APCH_STATE_CSTATE_DISABLED 0x00
#define APCH_STATE_CSTATE_EOC 0x01
#define APCH_STATE_CSTATE_FAST 0x02
#define APCH_STATE_CSTATE_PRE 0x03
struct act8945a_charger {
struct regmap *regmap;
bool battery_temperature;
};
static int act8945a_get_charger_state(struct regmap *regmap, int *val)
{
int ret;
unsigned int status, state;
ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
if (ret < 0)
return ret;
ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
if (ret < 0)
return ret;
state &= APCH_STATE_CSTATE;
state >>= APCH_STATE_CSTATE_SHIFT;
if (state == APCH_STATE_CSTATE_EOC) {
if (status & APCH_STATUS_CHGDAT)
*val = POWER_SUPPLY_STATUS_FULL;
else
*val = POWER_SUPPLY_STATUS_NOT_CHARGING;
} else if ((state == APCH_STATE_CSTATE_FAST) ||
(state == APCH_STATE_CSTATE_PRE)) {
*val = POWER_SUPPLY_STATUS_CHARGING;
} else {
*val = POWER_SUPPLY_STATUS_NOT_CHARGING;
}
return 0;
}
static int act8945a_get_charge_type(struct regmap *regmap, int *val)
{
int ret;
unsigned int state;
ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
if (ret < 0)
return ret;
state &= APCH_STATE_CSTATE;
state >>= APCH_STATE_CSTATE_SHIFT;
switch (state) {
case APCH_STATE_CSTATE_PRE:
*val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
break;
case APCH_STATE_CSTATE_FAST:
*val = POWER_SUPPLY_CHARGE_TYPE_FAST;
break;
case APCH_STATE_CSTATE_EOC:
case APCH_STATE_CSTATE_DISABLED:
default:
*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
}
return 0;
}
static int act8945a_get_battery_health(struct act8945a_charger *charger,
struct regmap *regmap, int *val)
{
int ret;
unsigned int status;
ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
if (ret < 0)
return ret;
if (charger->battery_temperature && !(status & APCH_STATUS_TEMPDAT))
*val = POWER_SUPPLY_HEALTH_OVERHEAT;
else if (!(status & APCH_STATUS_INDAT))
*val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
else if (status & APCH_STATUS_TIMRDAT)
*val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
else
*val = POWER_SUPPLY_HEALTH_GOOD;
return 0;
}
static enum power_supply_property act8945a_charger_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_CHARGE_TYPE,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER
};
static int act8945a_charger_get_property(struct power_supply *psy,
enum power_supply_property prop,
union power_supply_propval *val)
{
struct act8945a_charger *charger = power_supply_get_drvdata(psy);
struct regmap *regmap = charger->regmap;
int ret = 0;
switch (prop) {
case POWER_SUPPLY_PROP_STATUS:
ret = act8945a_get_charger_state(regmap, &val->intval);
break;
case POWER_SUPPLY_PROP_CHARGE_TYPE:
ret = act8945a_get_charge_type(regmap, &val->intval);
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_HEALTH:
ret = act8945a_get_battery_health(charger,
regmap, &val->intval);
break;
case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = act8945a_charger_model;
break;
case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = act8945a_charger_manufacturer;
break;
default:
return -EINVAL;
}
return ret;
}
static const struct power_supply_desc act8945a_charger_desc = {
.name = "act8945a-charger",
.type = POWER_SUPPLY_TYPE_BATTERY,
.get_property = act8945a_charger_get_property,
.properties = act8945a_charger_props,
.num_properties = ARRAY_SIZE(act8945a_charger_props),
};
#define DEFAULT_TOTAL_TIME_OUT 3
#define DEFAULT_PRE_TIME_OUT 40
#define DEFAULT_INPUT_OVP_THRESHOLD 6600
static int act8945a_charger_config(struct device *dev,
struct act8945a_charger *charger)
{
struct device_node *np = dev->of_node;
enum of_gpio_flags flags;
struct regmap *regmap = charger->regmap;
u32 total_time_out;
u32 pre_time_out;
u32 input_voltage_threshold;
int chglev_pin;
unsigned int value = 0;
if (!np) {
dev_err(dev, "no charger of node\n");
return -EINVAL;
}
charger->battery_temperature = of_property_read_bool(np,
"active-semi,check-battery-temperature");
chglev_pin = of_get_named_gpio_flags(np,
"active-semi,chglev-gpios", 0, &flags);
if (gpio_is_valid(chglev_pin)) {
gpio_set_value(chglev_pin,
((flags == OF_GPIO_ACTIVE_LOW) ? 0 : 1));
}
if (of_property_read_u32(np,
"active-semi,input-voltage-threshold-microvolt",
&input_voltage_threshold))
input_voltage_threshold = DEFAULT_INPUT_OVP_THRESHOLD;
if (of_property_read_u32(np,
"active-semi,precondition-timeout",
&pre_time_out))
pre_time_out = DEFAULT_PRE_TIME_OUT;
if (of_property_read_u32(np, "active-semi,total-timeout",
&total_time_out))
total_time_out = DEFAULT_TOTAL_TIME_OUT;
switch (input_voltage_threshold) {
case 8000:
value |= APCH_CFG_OVPSET_8V;
break;
case 7500:
value |= APCH_CFG_OVPSET_7V5;
break;
case 7000:
value |= APCH_CFG_OVPSET_7V;
break;
case 6600:
default:
value |= APCH_CFG_OVPSET_6V6;
break;
}
switch (pre_time_out) {
case 60:
value |= APCH_CFG_PRETIMO_60_MIN;
break;
case 80:
value |= APCH_CFG_PRETIMO_80_MIN;
break;
case 0:
value |= APCH_CFG_PRETIMO_DISABLED;
break;
case 40:
default:
value |= APCH_CFG_PRETIMO_40_MIN;
break;
}
switch (total_time_out) {
case 4:
value |= APCH_CFG_TOTTIMO_4_HOUR;
break;
case 5:
value |= APCH_CFG_TOTTIMO_5_HOUR;
break;
case 0:
value |= APCH_CFG_TOTTIMO_DISABLED;
break;
case 3:
default:
value |= APCH_CFG_TOTTIMO_3_HOUR;
break;
}
return regmap_write(regmap, ACT8945A_APCH_CFG, value);
}
static int act8945a_charger_probe(struct platform_device *pdev)
{
struct act8945a_charger *charger;
struct power_supply *psy;
struct power_supply_config psy_cfg = {};
int ret;
charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
if (!charger)
return -ENOMEM;
charger->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!charger->regmap) {
dev_err(&pdev->dev, "Parent did not provide regmap\n");
return -EINVAL;
}
ret = act8945a_charger_config(pdev->dev.parent, charger);
if (ret)
return ret;
psy_cfg.of_node = pdev->dev.parent->of_node;
psy_cfg.drv_data = charger;
psy = devm_power_supply_register(&pdev->dev,
&act8945a_charger_desc,
&psy_cfg);
if (IS_ERR(psy)) {
dev_err(&pdev->dev, "failed to register power supply\n");
return PTR_ERR(psy);
}
return 0;
}
static struct platform_driver act8945a_charger_driver = {
.driver = {
.name = "act8945a-charger",
},
.probe = act8945a_charger_probe,
};
module_platform_driver(act8945a_charger_driver);
MODULE_DESCRIPTION("Active-semi ACT8945A ActivePath charger driver");
MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
MODULE_LICENSE("GPL");
...@@ -1759,6 +1759,7 @@ static const struct i2c_device_id bq2415x_i2c_id_table[] = { ...@@ -1759,6 +1759,7 @@ static const struct i2c_device_id bq2415x_i2c_id_table[] = {
}; };
MODULE_DEVICE_TABLE(i2c, bq2415x_i2c_id_table); MODULE_DEVICE_TABLE(i2c, bq2415x_i2c_id_table);
#ifdef CONFIG_ACPI
static const struct acpi_device_id bq2415x_i2c_acpi_match[] = { static const struct acpi_device_id bq2415x_i2c_acpi_match[] = {
{ "BQ2415X", BQUNKNOWN }, { "BQ2415X", BQUNKNOWN },
{ "BQ241500", BQ24150 }, { "BQ241500", BQ24150 },
...@@ -1776,10 +1777,31 @@ static const struct acpi_device_id bq2415x_i2c_acpi_match[] = { ...@@ -1776,10 +1777,31 @@ static const struct acpi_device_id bq2415x_i2c_acpi_match[] = {
{}, {},
}; };
MODULE_DEVICE_TABLE(acpi, bq2415x_i2c_acpi_match); MODULE_DEVICE_TABLE(acpi, bq2415x_i2c_acpi_match);
#endif
#ifdef CONFIG_OF
static const struct of_device_id bq2415x_of_match_table[] = {
{ .compatible = "ti,bq24150" },
{ .compatible = "ti,bq24150a" },
{ .compatible = "ti,bq24151" },
{ .compatible = "ti,bq24151a" },
{ .compatible = "ti,bq24152" },
{ .compatible = "ti,bq24153" },
{ .compatible = "ti,bq24153a" },
{ .compatible = "ti,bq24155" },
{ .compatible = "ti,bq24156" },
{ .compatible = "ti,bq24156a" },
{ .compatible = "ti,bq24157s" },
{ .compatible = "ti,bq24158" },
{},
};
MODULE_DEVICE_TABLE(of, bq2415x_of_match_table);
#endif
static struct i2c_driver bq2415x_driver = { static struct i2c_driver bq2415x_driver = {
.driver = { .driver = {
.name = "bq2415x-charger", .name = "bq2415x-charger",
.of_match_table = of_match_ptr(bq2415x_of_match_table),
.acpi_match_table = ACPI_PTR(bq2415x_i2c_acpi_match), .acpi_match_table = ACPI_PTR(bq2415x_i2c_acpi_match),
}, },
.probe = bq2415x_probe, .probe = bq2415x_probe,
......
...@@ -48,6 +48,8 @@ struct bq24735 { ...@@ -48,6 +48,8 @@ struct bq24735 {
struct power_supply_desc charger_desc; struct power_supply_desc charger_desc;
struct i2c_client *client; struct i2c_client *client;
struct bq24735_platform *pdata; struct bq24735_platform *pdata;
struct mutex lock;
bool charging;
}; };
static inline struct bq24735 *to_bq24735(struct power_supply *psy) static inline struct bq24735 *to_bq24735(struct power_supply *psy)
...@@ -56,9 +58,23 @@ static inline struct bq24735 *to_bq24735(struct power_supply *psy) ...@@ -56,9 +58,23 @@ static inline struct bq24735 *to_bq24735(struct power_supply *psy)
} }
static enum power_supply_property bq24735_charger_properties[] = { static enum power_supply_property bq24735_charger_properties[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_ONLINE,
}; };
static int bq24735_charger_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
return 1;
default:
break;
}
return 0;
}
static inline int bq24735_write_word(struct i2c_client *client, u8 reg, static inline int bq24735_write_word(struct i2c_client *client, u8 reg,
u16 value) u16 value)
{ {
...@@ -90,6 +106,9 @@ static int bq24735_update_word(struct i2c_client *client, u8 reg, ...@@ -90,6 +106,9 @@ static int bq24735_update_word(struct i2c_client *client, u8 reg,
static inline int bq24735_enable_charging(struct bq24735 *charger) static inline int bq24735_enable_charging(struct bq24735 *charger)
{ {
if (charger->pdata->ext_control)
return 0;
return bq24735_update_word(charger->client, BQ24735_CHG_OPT, return bq24735_update_word(charger->client, BQ24735_CHG_OPT,
BQ24735_CHG_OPT_CHARGE_DISABLE, BQ24735_CHG_OPT_CHARGE_DISABLE,
~BQ24735_CHG_OPT_CHARGE_DISABLE); ~BQ24735_CHG_OPT_CHARGE_DISABLE);
...@@ -97,6 +116,9 @@ static inline int bq24735_enable_charging(struct bq24735 *charger) ...@@ -97,6 +116,9 @@ static inline int bq24735_enable_charging(struct bq24735 *charger)
static inline int bq24735_disable_charging(struct bq24735 *charger) static inline int bq24735_disable_charging(struct bq24735 *charger)
{ {
if (charger->pdata->ext_control)
return 0;
return bq24735_update_word(charger->client, BQ24735_CHG_OPT, return bq24735_update_word(charger->client, BQ24735_CHG_OPT,
BQ24735_CHG_OPT_CHARGE_DISABLE, BQ24735_CHG_OPT_CHARGE_DISABLE,
BQ24735_CHG_OPT_CHARGE_DISABLE); BQ24735_CHG_OPT_CHARGE_DISABLE);
...@@ -108,6 +130,9 @@ static int bq24735_config_charger(struct bq24735 *charger) ...@@ -108,6 +130,9 @@ static int bq24735_config_charger(struct bq24735 *charger)
int ret; int ret;
u16 value; u16 value;
if (pdata->ext_control)
return 0;
if (pdata->charge_current) { if (pdata->charge_current) {
value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK; value = pdata->charge_current & BQ24735_CHARGE_CURRENT_MASK;
...@@ -174,16 +199,30 @@ static bool bq24735_charger_is_present(struct bq24735 *charger) ...@@ -174,16 +199,30 @@ static bool bq24735_charger_is_present(struct bq24735 *charger)
return false; return false;
} }
static int bq24735_charger_is_charging(struct bq24735 *charger)
{
int ret = bq24735_read_word(charger->client, BQ24735_CHG_OPT);
if (ret < 0)
return ret;
return !(ret & BQ24735_CHG_OPT_CHARGE_DISABLE);
}
static irqreturn_t bq24735_charger_isr(int irq, void *devid) static irqreturn_t bq24735_charger_isr(int irq, void *devid)
{ {
struct power_supply *psy = devid; struct power_supply *psy = devid;
struct bq24735 *charger = to_bq24735(psy); struct bq24735 *charger = to_bq24735(psy);
if (bq24735_charger_is_present(charger)) mutex_lock(&charger->lock);
if (charger->charging && bq24735_charger_is_present(charger))
bq24735_enable_charging(charger); bq24735_enable_charging(charger);
else else
bq24735_disable_charging(charger); bq24735_disable_charging(charger);
mutex_unlock(&charger->lock);
power_supply_changed(psy); power_supply_changed(psy);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -199,9 +238,62 @@ static int bq24735_charger_get_property(struct power_supply *psy, ...@@ -199,9 +238,62 @@ static int bq24735_charger_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_ONLINE: case POWER_SUPPLY_PROP_ONLINE:
val->intval = bq24735_charger_is_present(charger) ? 1 : 0; val->intval = bq24735_charger_is_present(charger) ? 1 : 0;
break; break;
case POWER_SUPPLY_PROP_STATUS:
switch (bq24735_charger_is_charging(charger)) {
case 1:
val->intval = POWER_SUPPLY_STATUS_CHARGING;
break;
case 0:
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
break;
default:
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
break;
}
break;
default:
return -EINVAL;
}
return 0;
}
static int bq24735_charger_set_property(struct power_supply *psy,
enum power_supply_property psp,
const union power_supply_propval *val)
{
struct bq24735 *charger = to_bq24735(psy);
int ret;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
switch (val->intval) {
case POWER_SUPPLY_STATUS_CHARGING:
mutex_lock(&charger->lock);
charger->charging = true;
ret = bq24735_enable_charging(charger);
mutex_unlock(&charger->lock);
if (ret)
return ret;
bq24735_config_charger(charger);
break;
case POWER_SUPPLY_STATUS_DISCHARGING:
case POWER_SUPPLY_STATUS_NOT_CHARGING:
mutex_lock(&charger->lock);
charger->charging = false;
ret = bq24735_disable_charging(charger);
mutex_unlock(&charger->lock);
if (ret)
return ret;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
power_supply_changed(psy);
break;
default:
return -EPERM;
}
return 0; return 0;
} }
...@@ -239,6 +331,8 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client) ...@@ -239,6 +331,8 @@ static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
if (!ret) if (!ret)
pdata->input_current = val; pdata->input_current = val;
pdata->ext_control = of_property_read_bool(np, "ti,external-control");
return pdata; return pdata;
} }
...@@ -255,6 +349,8 @@ static int bq24735_charger_probe(struct i2c_client *client, ...@@ -255,6 +349,8 @@ static int bq24735_charger_probe(struct i2c_client *client,
if (!charger) if (!charger)
return -ENOMEM; return -ENOMEM;
mutex_init(&charger->lock);
charger->charging = true;
charger->pdata = client->dev.platform_data; charger->pdata = client->dev.platform_data;
if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node) if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node)
...@@ -285,6 +381,9 @@ static int bq24735_charger_probe(struct i2c_client *client, ...@@ -285,6 +381,9 @@ static int bq24735_charger_probe(struct i2c_client *client,
supply_desc->properties = bq24735_charger_properties; supply_desc->properties = bq24735_charger_properties;
supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties); supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties);
supply_desc->get_property = bq24735_charger_get_property; supply_desc->get_property = bq24735_charger_get_property;
supply_desc->set_property = bq24735_charger_set_property;
supply_desc->property_is_writeable =
bq24735_charger_property_is_writeable;
psy_cfg.supplied_to = charger->pdata->supplied_to; psy_cfg.supplied_to = charger->pdata->supplied_to;
psy_cfg.num_supplicants = charger->pdata->num_supplicants; psy_cfg.num_supplicants = charger->pdata->num_supplicants;
...@@ -293,6 +392,21 @@ static int bq24735_charger_probe(struct i2c_client *client, ...@@ -293,6 +392,21 @@ static int bq24735_charger_probe(struct i2c_client *client,
i2c_set_clientdata(client, charger); i2c_set_clientdata(client, charger);
if (gpio_is_valid(charger->pdata->status_gpio)) {
ret = devm_gpio_request(&client->dev,
charger->pdata->status_gpio,
name);
if (ret) {
dev_err(&client->dev,
"Failed GPIO request for GPIO %d: %d\n",
charger->pdata->status_gpio, ret);
}
charger->pdata->status_gpio_valid = !ret;
}
if (!charger->pdata->status_gpio_valid
|| bq24735_charger_is_present(charger)) {
ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID); ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "Failed to read manufacturer id : %d\n", dev_err(&client->dev, "Failed to read manufacturer id : %d\n",
...@@ -313,18 +427,6 @@ static int bq24735_charger_probe(struct i2c_client *client, ...@@ -313,18 +427,6 @@ static int bq24735_charger_probe(struct i2c_client *client,
"device id mismatch. 0x000b != 0x%04x\n", ret); "device id mismatch. 0x000b != 0x%04x\n", ret);
return -ENODEV; return -ENODEV;
} }
if (gpio_is_valid(charger->pdata->status_gpio)) {
ret = devm_gpio_request(&client->dev,
charger->pdata->status_gpio,
name);
if (ret) {
dev_err(&client->dev,
"Failed GPIO request for GPIO %d: %d\n",
charger->pdata->status_gpio, ret);
}
charger->pdata->status_gpio_valid = !ret;
} }
ret = bq24735_config_charger(charger); ret = bq24735_config_charger(charger);
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h>
#include <linux/power/bq27xxx_battery.h> #include <linux/power/bq27xxx_battery.h>
...@@ -1090,16 +1091,27 @@ static const struct platform_device_id bq27xxx_battery_platform_id_table[] = { ...@@ -1090,16 +1091,27 @@ static const struct platform_device_id bq27xxx_battery_platform_id_table[] = {
}; };
MODULE_DEVICE_TABLE(platform, bq27xxx_battery_platform_id_table); MODULE_DEVICE_TABLE(platform, bq27xxx_battery_platform_id_table);
#ifdef CONFIG_OF
static const struct of_device_id bq27xxx_battery_platform_of_match_table[] = {
{ .compatible = "ti,bq27000" },
{},
};
MODULE_DEVICE_TABLE(of, bq27xxx_battery_platform_of_match_table);
#endif
static struct platform_driver bq27xxx_battery_platform_driver = { static struct platform_driver bq27xxx_battery_platform_driver = {
.probe = bq27xxx_battery_platform_probe, .probe = bq27xxx_battery_platform_probe,
.remove = bq27xxx_battery_platform_remove, .remove = bq27xxx_battery_platform_remove,
.driver = { .driver = {
.name = "bq27000-battery", .name = "bq27000-battery",
.of_match_table = of_match_ptr(bq27xxx_battery_platform_of_match_table),
}, },
.id_table = bq27xxx_battery_platform_id_table, .id_table = bq27xxx_battery_platform_id_table,
}; };
module_platform_driver(bq27xxx_battery_platform_driver); module_platform_driver(bq27xxx_battery_platform_driver);
MODULE_ALIAS("platform:bq27000-battery");
MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
MODULE_DESCRIPTION("BQ27xxx battery monitor driver"); MODULE_DESCRIPTION("BQ27xxx battery monitor driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -166,9 +166,33 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = { ...@@ -166,9 +166,33 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
}; };
MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table); MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
#ifdef CONFIG_OF
static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
{ .compatible = "ti,bq27200" },
{ .compatible = "ti,bq27210" },
{ .compatible = "ti,bq27500" },
{ .compatible = "ti,bq27510" },
{ .compatible = "ti,bq27520" },
{ .compatible = "ti,bq27530" },
{ .compatible = "ti,bq27531" },
{ .compatible = "ti,bq27541" },
{ .compatible = "ti,bq27542" },
{ .compatible = "ti,bq27546" },
{ .compatible = "ti,bq27742" },
{ .compatible = "ti,bq27545" },
{ .compatible = "ti,bq27421" },
{ .compatible = "ti,bq27425" },
{ .compatible = "ti,bq27441" },
{ .compatible = "ti,bq27621" },
{},
};
MODULE_DEVICE_TABLE(of, bq27xxx_battery_i2c_of_match_table);
#endif
static struct i2c_driver bq27xxx_battery_i2c_driver = { static struct i2c_driver bq27xxx_battery_i2c_driver = {
.driver = { .driver = {
.name = "bq27xxx-battery", .name = "bq27xxx-battery",
.of_match_table = of_match_ptr(bq27xxx_battery_i2c_of_match_table),
}, },
.probe = bq27xxx_battery_i2c_probe, .probe = bq27xxx_battery_i2c_probe,
.remove = bq27xxx_battery_i2c_remove, .remove = bq27xxx_battery_i2c_remove,
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
static DEFINE_MUTEX(bat_lock); /* protects gpio pins */ static DEFINE_MUTEX(bat_lock); /* protects gpio pins */
static struct work_struct bat_work; static struct work_struct bat_work;
static struct ucb1x00 *ucb; static struct ucb1x00 *ucb;
static int wakeup_enabled;
struct collie_bat { struct collie_bat {
int status; int status;
...@@ -291,6 +290,8 @@ static struct gpio collie_batt_gpios[] = { ...@@ -291,6 +290,8 @@ static struct gpio collie_batt_gpios[] = {
}; };
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int wakeup_enabled;
static int collie_bat_suspend(struct ucb1x00_dev *dev) static int collie_bat_suspend(struct ucb1x00_dev *dev)
{ {
/* flush all pending status updates */ /* flush all pending status updates */
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/acpi.h>
struct goldfish_battery_data { struct goldfish_battery_data {
void __iomem *reg_base; void __iomem *reg_base;
...@@ -227,11 +228,25 @@ static int goldfish_battery_remove(struct platform_device *pdev) ...@@ -227,11 +228,25 @@ static int goldfish_battery_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id goldfish_battery_of_match[] = {
{ .compatible = "google,goldfish-battery", },
{},
};
MODULE_DEVICE_TABLE(of, goldfish_battery_of_match);
static const struct acpi_device_id goldfish_battery_acpi_match[] = {
{ "GFSH0001", 0 },
{ },
};
MODULE_DEVICE_TABLE(acpi, goldfish_battery_acpi_match);
static struct platform_driver goldfish_battery_device = { static struct platform_driver goldfish_battery_device = {
.probe = goldfish_battery_probe, .probe = goldfish_battery_probe,
.remove = goldfish_battery_remove, .remove = goldfish_battery_remove,
.driver = { .driver = {
.name = "goldfish-battery" .name = "goldfish-battery",
.of_match_table = goldfish_battery_of_match,
.acpi_match_table = ACPI_PTR(goldfish_battery_acpi_match),
} }
}; };
module_platform_driver(goldfish_battery_device); module_platform_driver(goldfish_battery_device);
......
...@@ -281,7 +281,7 @@ static int micro_batt_remove(struct platform_device *pdev) ...@@ -281,7 +281,7 @@ static int micro_batt_remove(struct platform_device *pdev)
return 0; return 0;
} }
static int micro_batt_suspend(struct device *dev) static int __maybe_unused micro_batt_suspend(struct device *dev)
{ {
struct micro_battery *mb = dev_get_drvdata(dev); struct micro_battery *mb = dev_get_drvdata(dev);
...@@ -289,7 +289,7 @@ static int micro_batt_suspend(struct device *dev) ...@@ -289,7 +289,7 @@ static int micro_batt_suspend(struct device *dev)
return 0; return 0;
} }
static int micro_batt_resume(struct device *dev) static int __maybe_unused micro_batt_resume(struct device *dev)
{ {
struct micro_battery *mb = dev_get_drvdata(dev); struct micro_battery *mb = dev_get_drvdata(dev);
......
...@@ -411,8 +411,10 @@ static int isp1704_charger_probe(struct platform_device *pdev) ...@@ -411,8 +411,10 @@ static int isp1704_charger_probe(struct platform_device *pdev)
if (np) { if (np) {
int gpio = of_get_named_gpio(np, "nxp,enable-gpio", 0); int gpio = of_get_named_gpio(np, "nxp,enable-gpio", 0);
if (gpio < 0) if (gpio < 0) {
dev_err(&pdev->dev, "missing DT GPIO nxp,enable-gpio\n");
return gpio; return gpio;
}
pdata = devm_kzalloc(&pdev->dev, pdata = devm_kzalloc(&pdev->dev,
sizeof(struct isp1704_charger_data), GFP_KERNEL); sizeof(struct isp1704_charger_data), GFP_KERNEL);
...@@ -422,9 +424,11 @@ static int isp1704_charger_probe(struct platform_device *pdev) ...@@ -422,9 +424,11 @@ static int isp1704_charger_probe(struct platform_device *pdev)
ret = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio, ret = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio,
GPIOF_OUT_INIT_HIGH, "isp1704_reset"); GPIOF_OUT_INIT_HIGH, "isp1704_reset");
if (ret) if (ret) {
dev_err(&pdev->dev, "gpio request failed\n");
goto fail0; goto fail0;
} }
}
if (!pdata) { if (!pdata) {
dev_err(&pdev->dev, "missing platform data!\n"); dev_err(&pdev->dev, "missing platform data!\n");
...@@ -443,6 +447,7 @@ static int isp1704_charger_probe(struct platform_device *pdev) ...@@ -443,6 +447,7 @@ static int isp1704_charger_probe(struct platform_device *pdev)
if (IS_ERR(isp->phy)) { if (IS_ERR(isp->phy)) {
ret = PTR_ERR(isp->phy); ret = PTR_ERR(isp->phy);
dev_err(&pdev->dev, "usb_get_phy failed\n");
goto fail0; goto fail0;
} }
...@@ -452,8 +457,10 @@ static int isp1704_charger_probe(struct platform_device *pdev) ...@@ -452,8 +457,10 @@ static int isp1704_charger_probe(struct platform_device *pdev)
isp1704_charger_set_power(isp, 1); isp1704_charger_set_power(isp, 1);
ret = isp1704_test_ulpi(isp); ret = isp1704_test_ulpi(isp);
if (ret < 0) if (ret < 0) {
dev_err(&pdev->dev, "isp1704_test_ulpi failed\n");
goto fail1; goto fail1;
}
isp->psy_desc.name = "isp1704"; isp->psy_desc.name = "isp1704";
isp->psy_desc.type = POWER_SUPPLY_TYPE_USB; isp->psy_desc.type = POWER_SUPPLY_TYPE_USB;
...@@ -466,6 +473,7 @@ static int isp1704_charger_probe(struct platform_device *pdev) ...@@ -466,6 +473,7 @@ static int isp1704_charger_probe(struct platform_device *pdev)
isp->psy = power_supply_register(isp->dev, &isp->psy_desc, &psy_cfg); isp->psy = power_supply_register(isp->dev, &isp->psy_desc, &psy_cfg);
if (IS_ERR(isp->psy)) { if (IS_ERR(isp->psy)) {
ret = PTR_ERR(isp->psy); ret = PTR_ERR(isp->psy);
dev_err(&pdev->dev, "power_supply_register failed\n");
goto fail1; goto fail1;
} }
...@@ -478,8 +486,10 @@ static int isp1704_charger_probe(struct platform_device *pdev) ...@@ -478,8 +486,10 @@ static int isp1704_charger_probe(struct platform_device *pdev)
isp->nb.notifier_call = isp1704_notifier_call; isp->nb.notifier_call = isp1704_notifier_call;
ret = usb_register_notifier(isp->phy, &isp->nb); ret = usb_register_notifier(isp->phy, &isp->nb);
if (ret) if (ret) {
dev_err(&pdev->dev, "usb_register_notifier failed\n");
goto fail2; goto fail2;
}
dev_info(isp->dev, "registered with product id %s\n", isp->model); dev_info(isp->dev, "registered with product id %s\n", isp->model);
...@@ -526,6 +536,7 @@ static int isp1704_charger_remove(struct platform_device *pdev) ...@@ -526,6 +536,7 @@ static int isp1704_charger_remove(struct platform_device *pdev)
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id omap_isp1704_of_match[] = { static const struct of_device_id omap_isp1704_of_match[] = {
{ .compatible = "nxp,isp1704", }, { .compatible = "nxp,isp1704", },
{ .compatible = "nxp,isp1707", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, omap_isp1704_of_match); MODULE_DEVICE_TABLE(of, omap_isp1704_of_match);
......
...@@ -208,7 +208,7 @@ static void jz_battery_update(struct jz_battery *jz_battery) ...@@ -208,7 +208,7 @@ static void jz_battery_update(struct jz_battery *jz_battery)
} }
voltage = jz_battery_read_voltage(jz_battery); voltage = jz_battery_read_voltage(jz_battery);
if (abs(voltage - jz_battery->voltage) < 50000) { if (voltage >= 0 && abs(voltage - jz_battery->voltage) > 50000) {
jz_battery->voltage = voltage; jz_battery->voltage = voltage;
has_changed = true; has_changed = true;
} }
......
...@@ -455,7 +455,7 @@ static void lp8788_charger_event(struct work_struct *work) ...@@ -455,7 +455,7 @@ static void lp8788_charger_event(struct work_struct *work)
static bool lp8788_find_irq_id(struct lp8788_charger *pchg, int virq, int *id) static bool lp8788_find_irq_id(struct lp8788_charger *pchg, int virq, int *id)
{ {
bool found; bool found = false;
int i; int i;
for (i = 0; i < pchg->num_irqs; i++) { for (i = 0; i < pchg->num_irqs; i++) {
......
...@@ -911,11 +911,7 @@ static struct pm2xxx_irq pm2xxx_charger_irq[] = { ...@@ -911,11 +911,7 @@ static struct pm2xxx_irq pm2xxx_charger_irq[] = {
{"PM2XXX_IRQ_INT", pm2xxx_irq_int}, {"PM2XXX_IRQ_INT", pm2xxx_irq_int},
}; };
#ifdef CONFIG_PM static int __maybe_unused pm2xxx_wall_charger_resume(struct device *dev)
#ifdef CONFIG_PM_SLEEP
static int pm2xxx_wall_charger_resume(struct device *dev)
{ {
struct i2c_client *i2c_client = to_i2c_client(dev); struct i2c_client *i2c_client = to_i2c_client(dev);
struct pm2xxx_charger *pm2; struct pm2xxx_charger *pm2;
...@@ -931,7 +927,7 @@ static int pm2xxx_wall_charger_resume(struct device *dev) ...@@ -931,7 +927,7 @@ static int pm2xxx_wall_charger_resume(struct device *dev)
return 0; return 0;
} }
static int pm2xxx_wall_charger_suspend(struct device *dev) static int __maybe_unused pm2xxx_wall_charger_suspend(struct device *dev)
{ {
struct i2c_client *i2c_client = to_i2c_client(dev); struct i2c_client *i2c_client = to_i2c_client(dev);
struct pm2xxx_charger *pm2; struct pm2xxx_charger *pm2;
...@@ -949,9 +945,7 @@ static int pm2xxx_wall_charger_suspend(struct device *dev) ...@@ -949,9 +945,7 @@ static int pm2xxx_wall_charger_suspend(struct device *dev)
return 0; return 0;
} }
#endif static int __maybe_unused pm2xxx_runtime_suspend(struct device *dev)
static int pm2xxx_runtime_suspend(struct device *dev)
{ {
struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
struct pm2xxx_charger *pm2; struct pm2xxx_charger *pm2;
...@@ -962,7 +956,7 @@ static int pm2xxx_runtime_suspend(struct device *dev) ...@@ -962,7 +956,7 @@ static int pm2xxx_runtime_suspend(struct device *dev)
return 0; return 0;
} }
static int pm2xxx_runtime_resume(struct device *dev) static int __maybe_unused pm2xxx_runtime_resume(struct device *dev)
{ {
struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
struct pm2xxx_charger *pm2; struct pm2xxx_charger *pm2;
...@@ -975,15 +969,11 @@ static int pm2xxx_runtime_resume(struct device *dev) ...@@ -975,15 +969,11 @@ static int pm2xxx_runtime_resume(struct device *dev)
return 0; return 0;
} }
static const struct dev_pm_ops pm2xxx_pm_ops = { static const struct dev_pm_ops pm2xxx_pm_ops __maybe_unused = {
SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend, SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend,
pm2xxx_wall_charger_resume) pm2xxx_wall_charger_resume)
SET_RUNTIME_PM_OPS(pm2xxx_runtime_suspend, pm2xxx_runtime_resume, NULL) SET_RUNTIME_PM_OPS(pm2xxx_runtime_suspend, pm2xxx_runtime_resume, NULL)
}; };
#define PM2XXX_PM_OPS (&pm2xxx_pm_ops)
#else
#define PM2XXX_PM_OPS NULL
#endif
static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
...@@ -1244,7 +1234,7 @@ static struct i2c_driver pm2xxx_charger_driver = { ...@@ -1244,7 +1234,7 @@ static struct i2c_driver pm2xxx_charger_driver = {
.remove = pm2xxx_wall_charger_remove, .remove = pm2xxx_wall_charger_remove,
.driver = { .driver = {
.name = "pm2xxx-wall_charger", .name = "pm2xxx-wall_charger",
.pm = PM2XXX_PM_OPS, .pm = IS_ENABLED(CONFIG_PM) ? &pm2xxx_pm_ops : NULL,
}, },
.id_table = pm2xxx_id, .id_table = pm2xxx_id,
}; };
......
...@@ -45,7 +45,8 @@ static ssize_t power_supply_show_property(struct device *dev, ...@@ -45,7 +45,8 @@ static ssize_t power_supply_show_property(struct device *dev,
char *buf) { char *buf) {
static char *type_text[] = { static char *type_text[] = {
"Unknown", "Battery", "UPS", "Mains", "USB", "Unknown", "Battery", "UPS", "Mains", "USB",
"USB_DCP", "USB_CDP", "USB_ACA" "USB_DCP", "USB_CDP", "USB_ACA", "USB_C",
"USB_PD", "USB_PD_DRP"
}; };
static char *status_text[] = { static char *status_text[] = {
"Unknown", "Charging", "Discharging", "Not charging", "Full" "Unknown", "Charging", "Discharging", "Not charging", "Full"
......
...@@ -148,6 +148,7 @@ config POWER_RESET_KEYSTONE ...@@ -148,6 +148,7 @@ config POWER_RESET_KEYSTONE
config POWER_RESET_SYSCON config POWER_RESET_SYSCON
bool "Generic SYSCON regmap reset driver" bool "Generic SYSCON regmap reset driver"
depends on OF depends on OF
depends on HAS_IOMEM
select MFD_SYSCON select MFD_SYSCON
help help
Reboot support for generic SYSCON mapped register reset. Reboot support for generic SYSCON mapped register reset.
...@@ -155,6 +156,7 @@ config POWER_RESET_SYSCON ...@@ -155,6 +156,7 @@ config POWER_RESET_SYSCON
config POWER_RESET_SYSCON_POWEROFF config POWER_RESET_SYSCON_POWEROFF
bool "Generic SYSCON regmap poweroff driver" bool "Generic SYSCON regmap poweroff driver"
depends on OF depends on OF
depends on HAS_IOMEM
select MFD_SYSCON select MFD_SYSCON
help help
Poweroff support for generic SYSCON mapped register poweroff. Poweroff support for generic SYSCON mapped register poweroff.
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
#define INTEGRATOR_HDR_LOCK_OFFSET 0x14 #define INTEGRATOR_HDR_LOCK_OFFSET 0x14
#define INTEGRATOR_CM_CTRL_RESET (1 << 3) #define INTEGRATOR_CM_CTRL_RESET (1 << 3)
#define REALVIEW_SYS_LOCK_OFFSET 0x20 #define VERSATILE_SYS_LOCK_OFFSET 0x20
#define REALVIEW_SYS_RESETCTL_OFFSET 0x40 #define VERSATILE_SYS_RESETCTL_OFFSET 0x40
/* Magic unlocking token used on all Versatile boards */ /* Magic unlocking token used on all Versatile boards */
#define VERSATILE_LOCK_VAL 0xA05F #define VERSATILE_LOCK_VAL 0xA05F
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
*/ */
enum versatile_reboot { enum versatile_reboot {
INTEGRATOR_REBOOT_CM, INTEGRATOR_REBOOT_CM,
VERSATILE_REBOOT_CM,
REALVIEW_REBOOT_EB, REALVIEW_REBOOT_EB,
REALVIEW_REBOOT_PB1176, REALVIEW_REBOOT_PB1176,
REALVIEW_REBOOT_PB11MP, REALVIEW_REBOOT_PB11MP,
...@@ -45,6 +46,10 @@ static const struct of_device_id versatile_reboot_of_match[] = { ...@@ -45,6 +46,10 @@ static const struct of_device_id versatile_reboot_of_match[] = {
.compatible = "arm,core-module-integrator", .compatible = "arm,core-module-integrator",
.data = (void *)INTEGRATOR_REBOOT_CM .data = (void *)INTEGRATOR_REBOOT_CM
}, },
{
.compatible = "arm,core-module-versatile",
.data = (void *)VERSATILE_REBOOT_CM,
},
{ {
.compatible = "arm,realview-eb-syscon", .compatible = "arm,realview-eb-syscon",
.data = (void *)REALVIEW_REBOOT_EB, .data = (void *)REALVIEW_REBOOT_EB,
...@@ -82,33 +87,43 @@ static int versatile_reboot(struct notifier_block *this, unsigned long mode, ...@@ -82,33 +87,43 @@ static int versatile_reboot(struct notifier_block *this, unsigned long mode,
INTEGRATOR_CM_CTRL_RESET, INTEGRATOR_CM_CTRL_RESET,
INTEGRATOR_CM_CTRL_RESET); INTEGRATOR_CM_CTRL_RESET);
break; break;
case VERSATILE_REBOOT_CM:
regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
VERSATILE_LOCK_VAL);
regmap_update_bits(syscon_regmap,
VERSATILE_SYS_RESETCTL_OFFSET,
0x0107,
0x0105);
regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
0);
break;
case REALVIEW_REBOOT_EB: case REALVIEW_REBOOT_EB:
regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
VERSATILE_LOCK_VAL); VERSATILE_LOCK_VAL);
regmap_write(syscon_regmap, regmap_write(syscon_regmap,
REALVIEW_SYS_RESETCTL_OFFSET, 0x0008); VERSATILE_SYS_RESETCTL_OFFSET, 0x0008);
break; break;
case REALVIEW_REBOOT_PB1176: case REALVIEW_REBOOT_PB1176:
regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
VERSATILE_LOCK_VAL); VERSATILE_LOCK_VAL);
regmap_write(syscon_regmap, regmap_write(syscon_regmap,
REALVIEW_SYS_RESETCTL_OFFSET, 0x0100); VERSATILE_SYS_RESETCTL_OFFSET, 0x0100);
break; break;
case REALVIEW_REBOOT_PB11MP: case REALVIEW_REBOOT_PB11MP:
case REALVIEW_REBOOT_PBA8: case REALVIEW_REBOOT_PBA8:
regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
VERSATILE_LOCK_VAL); VERSATILE_LOCK_VAL);
regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
0x0000); 0x0000);
regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
0x0004); 0x0004);
break; break;
case REALVIEW_REBOOT_PBX: case REALVIEW_REBOOT_PBX:
regmap_write(syscon_regmap, REALVIEW_SYS_LOCK_OFFSET, regmap_write(syscon_regmap, VERSATILE_SYS_LOCK_OFFSET,
VERSATILE_LOCK_VAL); VERSATILE_LOCK_VAL);
regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
0x00f0); 0x00f0);
regmap_write(syscon_regmap, REALVIEW_SYS_RESETCTL_OFFSET, regmap_write(syscon_regmap, VERSATILE_SYS_RESETCTL_OFFSET,
0x00f4); 0x00f4);
break; break;
} }
......
...@@ -32,6 +32,8 @@ struct bq24735_platform { ...@@ -32,6 +32,8 @@ struct bq24735_platform {
int status_gpio_active_low; int status_gpio_active_low;
bool status_gpio_valid; bool status_gpio_valid;
bool ext_control;
char **supplied_to; char **supplied_to;
size_t num_supplicants; size_t num_supplicants;
}; };
......
...@@ -163,6 +163,9 @@ enum power_supply_type { ...@@ -163,6 +163,9 @@ enum power_supply_type {
POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */ POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */
POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */ POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */
POWER_SUPPLY_TYPE_USB_ACA, /* Accessory Charger Adapters */ POWER_SUPPLY_TYPE_USB_ACA, /* Accessory Charger Adapters */
POWER_SUPPLY_TYPE_USB_TYPE_C, /* Type C Port */
POWER_SUPPLY_TYPE_USB_PD, /* Power Delivery Port */
POWER_SUPPLY_TYPE_USB_PD_DRP, /* PD Dual Role Port */
}; };
enum power_supply_notifier_events { enum power_supply_notifier_events {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment