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:
Ondrej Jirman
2023-08-06 02:55:22 +02:00
committed by Mauro (mdrjr) Ribeiro
parent 9072f9d428
commit f0cdf126ed

View File

@@ -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, &reg);
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;
}