Re: [PATCH v2 13/17] power: supply: axp20x_usb_power: Add support for AXP192

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Tue, Jun 07, 2022 at 04:53:20PM +0100, Aidan MacDonald wrote:
> The AXP192 is mostly the same as the AXP202 but has a different
> current limit.
> 
> Signed-off-by: Aidan MacDonald <aidanmacdonald.0x0@xxxxxxxxx>
> ---

Acked-by: Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx>

-- Sebastian

>  drivers/power/supply/axp20x_usb_power.c | 80 +++++++++++++++++++++----
>  1 file changed, 69 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
> index a1e6d1d44808..03145374ae72 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,24 @@ 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 = 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 +200,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 +236,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 +279,20 @@ 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
> +			/* Other chips do not have an OTG status register */
> +			break;
>  
> -			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,24 @@ 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)
> +{
> +	int val = AXP192_VBUS_CLIMIT_EN;
> +	const int mask = AXP192_VBUS_CLIMIT_EN | AXP192_VBUS_CLIMIT_100mA;
> +
> +	switch (intval) {
> +	case 100000:
> +		val |= AXP192_VBUS_CLIMIT_100mA;
> +		fallthrough;
> +	case 500000:
> +		return regmap_update_bits(power->regmap,
> +					  AXP20X_VBUS_IPSOUT_MGMT, mask, val);
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  static int axp813_usb_power_set_current_max(struct axp20x_usb_power *power,
>  					    int intval)
>  {
> @@ -383,6 +428,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 +516,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 +655,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 +714,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
> 

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux