power: bq24257: Allow input current limit sysfs access
This patch allows reading and writing of the input current limit through the power supply's input_current_limit sysfs property. This allows userspace to see what charger was detected (if the D+/D- USB signal- based charger type detection is enabled) and to re-configure the maximum current drawn from the external supply at runtime based on system-level knowledge or user input. Note that upon charger disconnection and re-connection the limit configured through firmware becomes active again (or the D+/D- USB signal-based charger detection will be run again). Signed-off-by: Andreas Dannenberg <dannenberg@ti.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Signed-off-by: Sebastian Reichel <sre@kernel.org>
This commit is contained in:
parent
138606ffe4
commit
0cfbfde65a
|
@ -267,6 +267,47 @@ enum bq24257_fault {
|
||||||
FAULT_INPUT_LDO_LOW,
|
FAULT_INPUT_LDO_LOW,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int bq24257_get_input_current_limit(struct bq24257_device *bq,
|
||||||
|
union power_supply_propval *val)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = bq24257_field_read(bq, F_IILIMIT);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The "External ILIM" and "Production & Test" modes are not exposed
|
||||||
|
* through this driver and not being covered by the lookup table.
|
||||||
|
* Should such a mode have become active let's return an error rather
|
||||||
|
* than exceeding the bounds of the lookup table and returning
|
||||||
|
* garbage.
|
||||||
|
*/
|
||||||
|
if (ret >= BQ24257_IILIMIT_MAP_SIZE)
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
val->intval = bq24257_iilimit_map[ret];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bq24257_set_input_current_limit(struct bq24257_device *bq,
|
||||||
|
const union power_supply_propval *val)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Address the case where the user manually sets an input current limit
|
||||||
|
* while the charger auto-detection mechanism is is active. In this
|
||||||
|
* case we want to abort and go straight to the user-specified value.
|
||||||
|
*/
|
||||||
|
if (bq->iilimit_autoset_enable)
|
||||||
|
cancel_delayed_work_sync(&bq->iilimit_setup_work);
|
||||||
|
|
||||||
|
return bq24257_field_write(bq, F_IILIMIT,
|
||||||
|
bq24257_find_idx(val->intval,
|
||||||
|
bq24257_iilimit_map,
|
||||||
|
BQ24257_IILIMIT_MAP_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
static int bq24257_power_supply_get_property(struct power_supply *psy,
|
static int bq24257_power_supply_get_property(struct power_supply *psy,
|
||||||
enum power_supply_property psp,
|
enum power_supply_property psp,
|
||||||
union power_supply_propval *val)
|
union power_supply_propval *val)
|
||||||
|
@ -351,6 +392,9 @@ static int bq24257_power_supply_get_property(struct power_supply *psy,
|
||||||
val->intval = bq24257_iterm_map[bq->init_data.iterm];
|
val->intval = bq24257_iterm_map[bq->init_data.iterm];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||||
|
return bq24257_get_input_current_limit(bq, val);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -358,6 +402,31 @@ static int bq24257_power_supply_get_property(struct power_supply *psy,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bq24257_power_supply_set_property(struct power_supply *psy,
|
||||||
|
enum power_supply_property prop,
|
||||||
|
const union power_supply_propval *val)
|
||||||
|
{
|
||||||
|
struct bq24257_device *bq = power_supply_get_drvdata(psy);
|
||||||
|
|
||||||
|
switch (prop) {
|
||||||
|
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||||
|
return bq24257_set_input_current_limit(bq, val);
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bq24257_power_supply_property_is_writeable(struct power_supply *psy,
|
||||||
|
enum power_supply_property psp)
|
||||||
|
{
|
||||||
|
switch (psp) {
|
||||||
|
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int bq24257_get_chip_state(struct bq24257_device *bq,
|
static int bq24257_get_chip_state(struct bq24257_device *bq,
|
||||||
struct bq24257_state *state)
|
struct bq24257_state *state)
|
||||||
{
|
{
|
||||||
|
@ -559,13 +628,14 @@ static void bq24257_handle_state_change(struct bq24257_device *bq,
|
||||||
ret = bq24257_field_write(bq, F_DPDM_EN, 1);
|
ret = bq24257_field_write(bq, F_DPDM_EN, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* reset input current limit */
|
|
||||||
ret = bq24257_field_write(bq, F_IILIMIT,
|
|
||||||
bq->init_data.iilimit);
|
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* When power is removed always return to the default input
|
||||||
|
* current limit as configured during probe.
|
||||||
|
*/
|
||||||
|
ret = bq24257_field_write(bq, F_IILIMIT, bq->init_data.iilimit);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
} else if (!old_state.power_good) {
|
} else if (!old_state.power_good) {
|
||||||
dev_dbg(bq->dev, "Power inserted\n");
|
dev_dbg(bq->dev, "Power inserted\n");
|
||||||
|
|
||||||
|
@ -682,6 +752,7 @@ static enum power_supply_property bq24257_power_supply_props[] = {
|
||||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
|
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
|
||||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
|
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
|
||||||
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
|
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
|
||||||
|
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *bq24257_charger_supplied_to[] = {
|
static char *bq24257_charger_supplied_to[] = {
|
||||||
|
@ -694,6 +765,8 @@ static const struct power_supply_desc bq24257_power_supply_desc = {
|
||||||
.properties = bq24257_power_supply_props,
|
.properties = bq24257_power_supply_props,
|
||||||
.num_properties = ARRAY_SIZE(bq24257_power_supply_props),
|
.num_properties = ARRAY_SIZE(bq24257_power_supply_props),
|
||||||
.get_property = bq24257_power_supply_get_property,
|
.get_property = bq24257_power_supply_get_property,
|
||||||
|
.set_property = bq24257_power_supply_set_property,
|
||||||
|
.property_is_writeable = bq24257_power_supply_property_is_writeable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t bq24257_show_ovp_voltage(struct device *dev,
|
static ssize_t bq24257_show_ovp_voltage(struct device *dev,
|
||||||
|
|
Loading…
Reference in a new issue