lkml.org 
[lkml]   [2022]   [Jun]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: [PATCH v4 11/15] power: supply: axp20x_usb_power: Add support for AXP192
    On Wed, Jun 29, 2022 at 4:30 PM Aidan MacDonald
    <aidanmacdonald.0x0@gmail.com> wrote:
    >
    > The AXP192's USB power supply is similar to the AXP202 but it has
    > different USB current limits and a different offset for the VBUS
    > status register.

    Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

    > Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
    > Reviewed-by: Chen-Yu Tsai <wens@csie.org>
    > Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@gmail.com>
    > ---
    > drivers/power/supply/axp20x_usb_power.c | 84 +++++++++++++++++++++----
    > 1 file changed, 73 insertions(+), 11 deletions(-)
    >
    > diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
    > index a1e6d1d44808..f83e2ed6d507 100644
    > --- a/drivers/power/supply/axp20x_usb_power.c
    > +++ b/drivers/power/supply/axp20x_usb_power.c
    > @@ -48,6 +48,9 @@
    > #define AXP813_VBUS_CLIMIT_2000mA 2
    > #define AXP813_VBUS_CLIMIT_2500mA 3
    >
    > +#define AXP192_VBUS_CLIMIT_EN BIT(1)
    > +#define AXP192_VBUS_CLIMIT_100mA BIT(0)
    > +
    > #define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
    > #define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
    >
    > @@ -121,6 +124,25 @@ static void axp20x_usb_power_poll_vbus(struct work_struct *work)
    > mod_delayed_work(system_power_efficient_wq, &power->vbus_detect, DEBOUNCE_TIME);
    > }
    >
    > +static int axp192_get_current_max(struct axp20x_usb_power *power, int *val)
    > +{
    > + unsigned int v;
    > + int ret;
    > +
    > + ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
    > + if (ret)
    > + return ret;
    > +
    > + if (!(v & AXP192_VBUS_CLIMIT_EN))
    > + *val = -1;
    > + else if (v & AXP192_VBUS_CLIMIT_100mA)
    > + *val = 100000;
    > + else
    > + *val = 500000;
    > +
    > + return 0;
    > +}
    > +
    > static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val)
    > {
    > unsigned int v;
    > @@ -179,7 +201,7 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
    > enum power_supply_property psp, union power_supply_propval *val)
    > {
    > struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
    > - unsigned int input, v;
    > + unsigned int input, v, reg;
    > int ret;
    >
    > switch (psp) {
    > @@ -215,6 +237,8 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
    > case POWER_SUPPLY_PROP_CURRENT_MAX:
    > if (power->axp20x_id == AXP813_ID)
    > return axp813_get_current_max(power, &val->intval);
    > + else if (power->axp20x_id == AXP192_ID)
    > + return axp192_get_current_max(power, &val->intval);
    > return axp20x_get_current_max(power, &val->intval);
    > case POWER_SUPPLY_PROP_CURRENT_NOW:
    > if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
    > @@ -256,16 +280,19 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
    >
    > val->intval = POWER_SUPPLY_HEALTH_GOOD;
    >
    > - if (power->axp20x_id == AXP202_ID) {
    > - ret = regmap_read(power->regmap,
    > - AXP20X_USB_OTG_STATUS, &v);
    > - if (ret)
    > - return ret;
    > + if (power->axp20x_id == AXP192_ID)
    > + reg = AXP192_USB_OTG_STATUS;
    > + else if (power->axp20x_id == AXP202_ID)
    > + reg = AXP20X_USB_OTG_STATUS;
    > + else
    > + break; /* Other chips lack the OTG status register */
    >
    > - if (!(v & AXP20X_USB_STATUS_VBUS_VALID))
    > - val->intval =
    > - POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
    > - }
    > + ret = regmap_read(power->regmap, reg, &v);
    > + if (ret)
    > + return ret;
    > +
    > + if (!(v & AXP20X_USB_STATUS_VBUS_VALID))
    > + val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
    > break;
    > case POWER_SUPPLY_PROP_PRESENT:
    > val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_PRESENT);
    > @@ -316,6 +343,28 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
    > return -EINVAL;
    > }
    >
    > +static int axp192_usb_power_set_current_max(struct axp20x_usb_power *power,
    > + int intval)
    > +{
    > + const unsigned int mask = AXP192_VBUS_CLIMIT_EN |
    > + AXP192_VBUS_CLIMIT_100mA;
    > + unsigned int val;
    > +
    > + switch (intval) {
    > + case 100000:
    > + val = AXP192_VBUS_CLIMIT_EN | AXP192_VBUS_CLIMIT_100mA;
    > + break;
    > + case 500000:
    > + val = AXP192_VBUS_CLIMIT_EN;
    > + break;
    > + default:
    > + return -EINVAL;
    > + }
    > +
    > + return regmap_update_bits(power->regmap,
    > + AXP20X_VBUS_IPSOUT_MGMT, mask, val);
    > +}
    > +
    > static int axp813_usb_power_set_current_max(struct axp20x_usb_power *power,
    > int intval)
    > {
    > @@ -383,6 +432,9 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
    > if (power->axp20x_id == AXP813_ID)
    > return axp813_usb_power_set_current_max(power,
    > val->intval);
    > + else if (power->axp20x_id == AXP192_ID)
    > + return axp192_usb_power_set_current_max(power,
    > + val->intval);
    > return axp20x_usb_power_set_current_max(power, val->intval);
    >
    > default:
    > @@ -468,6 +520,13 @@ struct axp_data {
    > enum axp20x_variants axp20x_id;
    > };
    >
    > +static const struct axp_data axp192_data = {
    > + .power_desc = &axp20x_usb_power_desc,
    > + .irq_names = axp20x_irq_names,
    > + .num_irq_names = ARRAY_SIZE(axp20x_irq_names),
    > + .axp20x_id = AXP192_ID,
    > +};
    > +
    > static const struct axp_data axp202_data = {
    > .power_desc = &axp20x_usb_power_desc,
    > .irq_names = axp20x_irq_names,
    > @@ -600,7 +659,7 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
    > if (ret)
    > return ret;
    >
    > - if (power->axp20x_id == AXP202_ID) {
    > + if (power->axp20x_id == AXP192_ID || power->axp20x_id == AXP202_ID) {
    > /* Enable vbus valid checking */
    > ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON,
    > AXP20X_VBUS_MON_VBUS_VALID,
    > @@ -659,6 +718,9 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
    >
    > static const struct of_device_id axp20x_usb_power_match[] = {
    > {
    > + .compatible = "x-powers,axp192-usb-power-supply",
    > + .data = &axp192_data,
    > + }, {
    > .compatible = "x-powers,axp202-usb-power-supply",
    > .data = &axp202_data,
    > }, {
    > --
    > 2.35.1
    >


    --
    With Best Regards,
    Andy Shevchenko

    \
     
     \ /
      Last update: 2022-06-30 10:01    [W:4.736 / U:0.188 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site