bq24735_charger: add status property to view/enable/disable charging

Add possibility to disable/re-enable charging via sysfs.

Signed-off-by: Peter Rosin <peda@axentia.se>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
This commit is contained in:
Peter Rosin 2016-01-12 21:30:59 +01:00 committed by Sebastian Reichel
parent 7a1b92ca6a
commit 5b7a018739

View file

@ -48,6 +48,8 @@ struct bq24735 {
struct power_supply_desc charger_desc;
struct i2c_client *client;
struct bq24735_platform *pdata;
struct mutex lock;
bool charging;
};
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[] = {
POWER_SUPPLY_PROP_STATUS,
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,
u16 value)
{
@ -174,16 +190,30 @@ static bool bq24735_charger_is_present(struct bq24735 *charger)
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)
{
struct power_supply *psy = devid;
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);
else
bq24735_disable_charging(charger);
mutex_unlock(&charger->lock);
power_supply_changed(psy);
return IRQ_HANDLED;
@ -199,6 +229,19 @@ static int bq24735_charger_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_ONLINE:
val->intval = bq24735_charger_is_present(charger) ? 1 : 0;
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;
}
@ -206,6 +249,46 @@ static int bq24735_charger_get_property(struct power_supply *psy,
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:
return -EINVAL;
}
power_supply_changed(psy);
break;
default:
return -EPERM;
}
return 0;
}
static struct bq24735_platform *bq24735_parse_dt_data(struct i2c_client *client)
{
struct bq24735_platform *pdata;
@ -255,6 +338,8 @@ static int bq24735_charger_probe(struct i2c_client *client,
if (!charger)
return -ENOMEM;
mutex_init(&charger->lock);
charger->charging = true;
charger->pdata = client->dev.platform_data;
if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node)
@ -285,6 +370,9 @@ static int bq24735_charger_probe(struct i2c_client *client,
supply_desc->properties = bq24735_charger_properties;
supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties);
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.num_supplicants = charger->pdata->num_supplicants;