mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
power: supply: rk817-charger: Add input current limit setting
This is useful for proper USB input current limiting. Signed-off-by: Ondrej Jirman <megi@xff.cz>
This commit is contained in:
committed by
Mauro (mdrjr) Ribeiro
parent
9072f9d428
commit
f0cdf126ed
@@ -556,11 +556,72 @@ static int rk817_bat_get_prop(struct power_supply *ps,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const int rk817_usb_input_current_limits[] = {
|
||||
1, 80000,
|
||||
0, 450000,
|
||||
2, 850000,
|
||||
3, 1500000,
|
||||
4, 1750000,
|
||||
5, 2000000,
|
||||
6, 2500000,
|
||||
7, 3000000,
|
||||
};
|
||||
|
||||
static int rk817_usb_set_input_current_max(struct rk817_charger *cg,
|
||||
int val)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
for (i = ARRAY_SIZE(rk817_usb_input_current_limits) / 2 - 1; i > 0; i--) {
|
||||
if (val >= rk817_usb_input_current_limits[2 * i + 1])
|
||||
break;
|
||||
}
|
||||
|
||||
dev_info(cg->dev, "applying input current limit %d mA\n",
|
||||
rk817_usb_input_current_limits[2 * i + 1] / 1000);
|
||||
|
||||
ret = regmap_write_bits(cg->rk808->regmap, RK817_PMIC_CHRG_IN,
|
||||
RK817_USB_ILIM_SEL,
|
||||
rk817_usb_input_current_limits[2 * i]);
|
||||
if (ret)
|
||||
dev_err(cg->dev,
|
||||
"USB input current limit setting failed (%d)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk817_usb_get_input_current_max(struct rk817_charger *cg,
|
||||
int *val)
|
||||
{
|
||||
unsigned reg;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(cg->rk808->regmap, RK817_PMIC_CHRG_IN, ®);
|
||||
if (ret) {
|
||||
dev_err(cg->dev,
|
||||
"USB input current limit getting failed (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
reg &= RK817_USB_ILIM_SEL;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(rk817_usb_input_current_limits) / 2; i++) {
|
||||
int r = rk817_usb_input_current_limits[2 * i];
|
||||
if (r == reg) {
|
||||
*val = rk817_usb_input_current_limits[2 * i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_chg_get_prop(struct power_supply *ps,
|
||||
enum power_supply_property prop,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct rk817_charger *charger = power_supply_get_drvdata(ps);
|
||||
int ret;
|
||||
|
||||
switch (prop) {
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
@@ -577,6 +638,11 @@ static int rk817_chg_get_prop(struct power_supply *ps,
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_AVG:
|
||||
val->intval = charger->charger_input_volt_avg_uv;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
ret = rk817_usb_get_input_current_max(charger, &val->intval);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
/*
|
||||
* While it's possible that other implementations could use different
|
||||
* USB types, the current implementation for this PMIC (the Odroid Go
|
||||
@@ -589,6 +655,25 @@ static int rk817_chg_get_prop(struct power_supply *ps,
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_chg_set_prop(struct power_supply *ps,
|
||||
enum power_supply_property prop,
|
||||
const union power_supply_propval *val)
|
||||
{
|
||||
struct rk817_charger *charger = power_supply_get_drvdata(ps);
|
||||
int ret;
|
||||
|
||||
switch (prop) {
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
ret = rk817_usb_set_input_current_max(charger, val->intval);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@@ -632,15 +717,6 @@ static irqreturn_t rk817_plug_out_isr(int irq, void *cg)
|
||||
regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_VLIM_EN,
|
||||
(0x01 << 7));
|
||||
|
||||
/*
|
||||
* Set average USB input current limit to 1.5A and enable USB current
|
||||
* input limit.
|
||||
*/
|
||||
regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
|
||||
RK817_USB_ILIM_SEL, 0x03);
|
||||
regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN,
|
||||
(0x01 << 3));
|
||||
|
||||
rk817_read_props(charger);
|
||||
|
||||
dev_dbg(charger->dev, "Power Cord Removed\n");
|
||||
@@ -648,6 +724,17 @@ static irqreturn_t rk817_plug_out_isr(int irq, void *cg)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int rk817_charger_prop_writeable(struct power_supply *psy,
|
||||
enum power_supply_property psp)
|
||||
{
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static enum power_supply_property rk817_bat_props[] = {
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
@@ -671,6 +758,7 @@ static enum power_supply_property rk817_chg_props[] = {
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_AVG,
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type rk817_usb_type[] = {
|
||||
@@ -693,7 +781,9 @@ static const struct power_supply_desc rk817_chg_desc = {
|
||||
.num_usb_types = ARRAY_SIZE(rk817_usb_type),
|
||||
.properties = rk817_chg_props,
|
||||
.num_properties = ARRAY_SIZE(rk817_chg_props),
|
||||
.property_is_writeable = rk817_charger_prop_writeable,
|
||||
.get_property = rk817_chg_get_prop,
|
||||
.set_property = rk817_chg_set_prop,
|
||||
};
|
||||
|
||||
static int rk817_read_battery_nvram_values(struct rk817_charger *charger)
|
||||
@@ -1025,10 +1115,6 @@ static int rk817_battery_init(struct rk817_charger *charger,
|
||||
* Set average USB input current limit to 1.5A and enable USB current
|
||||
* input limit.
|
||||
*/
|
||||
regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN,
|
||||
RK817_USB_ILIM_SEL, 0x03);
|
||||
regmap_write_bits(rk808->regmap, RK817_PMIC_CHRG_IN, RK817_USB_ILIM_EN,
|
||||
(0x01 << 3));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user