regulator: act8865: Add support for act8600 charger
This provides a way to monitor battery charge status via the power supply subsystem. Signed-off-by: Maarten ter Huurne <maarten@treewalker.org> Signed-off-by: Paul Cercueil <paul@crapouillou.net> Link: https://lore.kernel.org/r/20190723011418.29143-1-paul@crapouillou.net Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
d850c6f5fa
commit
2d09a79bf6
@ -16,6 +16,7 @@
|
|||||||
#include <linux/regulator/act8865.h>
|
#include <linux/regulator/act8865.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/power_supply.h>
|
||||||
#include <linux/regulator/of_regulator.h>
|
#include <linux/regulator/of_regulator.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
|
|
||||||
@ -118,6 +119,11 @@
|
|||||||
#define ACT8600_LDO10_ENA 0x40 /* ON - [6] */
|
#define ACT8600_LDO10_ENA 0x40 /* ON - [6] */
|
||||||
#define ACT8600_SUDCDC_VSEL_MASK 0xFF /* SUDCDC VSET - [7:0] */
|
#define ACT8600_SUDCDC_VSEL_MASK 0xFF /* SUDCDC VSET - [7:0] */
|
||||||
|
|
||||||
|
#define ACT8600_APCH_CHG_ACIN BIT(7)
|
||||||
|
#define ACT8600_APCH_CHG_USB BIT(6)
|
||||||
|
#define ACT8600_APCH_CSTATE0 BIT(5)
|
||||||
|
#define ACT8600_APCH_CSTATE1 BIT(4)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ACT8865 voltage number
|
* ACT8865 voltage number
|
||||||
*/
|
*/
|
||||||
@ -372,6 +378,75 @@ static void act8865_power_off(void)
|
|||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int act8600_charger_get_status(struct regmap *map)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
u8 state0, state1;
|
||||||
|
|
||||||
|
ret = regmap_read(map, ACT8600_APCH_STAT, &val);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
state0 = val & ACT8600_APCH_CSTATE0;
|
||||||
|
state1 = val & ACT8600_APCH_CSTATE1;
|
||||||
|
|
||||||
|
if (state0 && !state1)
|
||||||
|
return POWER_SUPPLY_STATUS_CHARGING;
|
||||||
|
if (!state0 && state1)
|
||||||
|
return POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||||
|
if (!state0 && !state1)
|
||||||
|
return POWER_SUPPLY_STATUS_DISCHARGING;
|
||||||
|
|
||||||
|
return POWER_SUPPLY_STATUS_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int act8600_charger_get_property(struct power_supply *psy,
|
||||||
|
enum power_supply_property psp, union power_supply_propval *val)
|
||||||
|
{
|
||||||
|
struct regmap *map = power_supply_get_drvdata(psy);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (psp) {
|
||||||
|
case POWER_SUPPLY_PROP_STATUS:
|
||||||
|
ret = act8600_charger_get_status(map);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
val->intval = ret;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum power_supply_property act8600_charger_properties[] = {
|
||||||
|
POWER_SUPPLY_PROP_STATUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct power_supply_desc act8600_charger_desc = {
|
||||||
|
.name = "act8600-charger",
|
||||||
|
.type = POWER_SUPPLY_TYPE_BATTERY,
|
||||||
|
.properties = act8600_charger_properties,
|
||||||
|
.num_properties = ARRAY_SIZE(act8600_charger_properties),
|
||||||
|
.get_property = act8600_charger_get_property,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int act8600_charger_probe(struct device *dev, struct regmap *regmap)
|
||||||
|
{
|
||||||
|
struct power_supply *charger;
|
||||||
|
struct power_supply_config cfg = {
|
||||||
|
.drv_data = regmap,
|
||||||
|
.of_node = dev->of_node,
|
||||||
|
};
|
||||||
|
|
||||||
|
charger = devm_power_supply_register(dev, &act8600_charger_desc, &cfg);
|
||||||
|
|
||||||
|
return IS_ERR(charger) ? PTR_ERR(charger) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int act8865_pmic_probe(struct i2c_client *client,
|
static int act8865_pmic_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *i2c_id)
|
const struct i2c_device_id *i2c_id)
|
||||||
{
|
{
|
||||||
@ -483,6 +558,15 @@ static int act8865_pmic_probe(struct i2c_client *client,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == ACT8600) {
|
||||||
|
ret = act8600_charger_probe(dev, act8865->regmap);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (ret != -EPROBE_DEFER)
|
||||||
|
dev_err(dev, "Failed to probe charger");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
i2c_set_clientdata(client, act8865);
|
i2c_set_clientdata(client, act8865);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user