Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-04 Thread Baolin Wang
Hi,

On 3 July 2017 at 16:53, Charles Keepax  wrote:
> On Mon, Jul 03, 2017 at 02:07:15PM +0800, Baolin Wang wrote:
>> Integrate with the newly added USB charger interface to limit the current
>> we draw from the USB input based on the input device configuration
>> identified by the USB stack, allowing us to charge more quickly from high
>> current inputs without drawing more current than specified from others.
>>
>> Signed-off-by: Mark Brown 
>> Signed-off-by: Baolin Wang 
>> ---
> 
>>  /*
>>   *   Battery properties
>>   */
>> @@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device 
>> *pdev)
>>   }
>>   }
>>
>> + power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
>> +  "usb-phy", 0);
>> + if (IS_ERR(power->usb_phy)) {
>> + ret = PTR_ERR(power->usb_phy);
>> + dev_err(>dev, "Failed to find USB phy: %d\n", ret);
>> + goto err_bat_irq;
>> + }
>> +
>
> We should probably update the binding documentation for this as
> well: mfd/wm831x.txt

Yes, I will update the binding documentation.

>
> Also I am not sure this needs to be implemented now, but what is
> the plan regarding pdata systems? Generally the driver supports
> both and it would be nice to know there is a way forward for that
> even if we don't implement it yet.

OK, I'll modify this in next version. Thanks.

-- 
Baolin.wang
Best Regards


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-04 Thread Baolin Wang
Hi,

On 3 July 2017 at 16:53, Charles Keepax  wrote:
> On Mon, Jul 03, 2017 at 02:07:15PM +0800, Baolin Wang wrote:
>> Integrate with the newly added USB charger interface to limit the current
>> we draw from the USB input based on the input device configuration
>> identified by the USB stack, allowing us to charge more quickly from high
>> current inputs without drawing more current than specified from others.
>>
>> Signed-off-by: Mark Brown 
>> Signed-off-by: Baolin Wang 
>> ---
> 
>>  /*
>>   *   Battery properties
>>   */
>> @@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device 
>> *pdev)
>>   }
>>   }
>>
>> + power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
>> +  "usb-phy", 0);
>> + if (IS_ERR(power->usb_phy)) {
>> + ret = PTR_ERR(power->usb_phy);
>> + dev_err(>dev, "Failed to find USB phy: %d\n", ret);
>> + goto err_bat_irq;
>> + }
>> +
>
> We should probably update the binding documentation for this as
> well: mfd/wm831x.txt

Yes, I will update the binding documentation.

>
> Also I am not sure this needs to be implemented now, but what is
> the plan regarding pdata systems? Generally the driver supports
> both and it would be nice to know there is a way forward for that
> even if we don't implement it yet.

OK, I'll modify this in next version. Thanks.

-- 
Baolin.wang
Best Regards


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-04 Thread Baolin Wang
Hi,

On 3 July 2017 at 23:50, Sebastian Reichel
 wrote:
> Hi,
>
> On Mon, Jul 03, 2017 at 02:07:15PM +0800, Baolin Wang wrote:
>> Integrate with the newly added USB charger interface to limit the current
>> we draw from the USB input based on the input device configuration
>> identified by the USB stack, allowing us to charge more quickly from high
>> current inputs without drawing more current than specified from others.
>>
>> Signed-off-by: Mark Brown 
>> Signed-off-by: Baolin Wang 
>
> Missing DT binding documentation, otherwise fine with me.
> Would be nice to convert existing drivers:
>
> $ git grep -l extcon -- drivers/power/supply
> drivers/power/supply/axp288_charger.c
> drivers/power/supply/bq24190_charger.c
> drivers/power/supply/charger-manager.c
> drivers/power/supply/qcom_smbb.c

I'll create new patches with adding the DT binding documentation if
there are no objections for USB phy modification, moreover I will help
to convert these drivers you listed. Thanks.

>
> -- Sebastian
>
>> ---
>>  drivers/power/supply/wm831x_power.c |   61 
>> +++
>>  1 file changed, 61 insertions(+)
>>
>> diff --git a/drivers/power/supply/wm831x_power.c 
>> b/drivers/power/supply/wm831x_power.c
>> index 7082301..3e3480708 100644
>> --- a/drivers/power/supply/wm831x_power.c
>> +++ b/drivers/power/supply/wm831x_power.c
>> @@ -13,6 +13,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  #include 
>>  #include 
>> @@ -31,6 +32,8 @@ struct wm831x_power {
>>   char usb_name[20];
>>   char battery_name[20];
>>   bool have_battery;
>> + struct usb_phy *usb_phy;
>> + struct notifier_block usb_notify;
>>  };
>>
>>  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
>> @@ -125,6 +128,43 @@ static int wm831x_usb_get_prop(struct power_supply *psy,
>>   POWER_SUPPLY_PROP_VOLTAGE_NOW,
>>  };
>>
>> +/* In milliamps */
>> +static const unsigned int wm831x_usb_limits[] = {
>> + 0,
>> + 2,
>> + 100,
>> + 500,
>> + 900,
>> + 1500,
>> + 1800,
>> + 550,
>> +};
>> +
>> +static int wm831x_usb_limit_change(struct notifier_block *nb,
>> +unsigned long limit, void *data)
>> +{
>> + struct wm831x_power *wm831x_power = container_of(nb,
>> +  struct wm831x_power,
>> +  usb_notify);
>> + unsigned int i, best;
>> +
>> + /* Find the highest supported limit */
>> + best = 0;
>> + for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
>> + if (limit >= wm831x_usb_limits[i] &&
>> + wm831x_usb_limits[best] < wm831x_usb_limits[i])
>> + best = i;
>> + }
>> +
>> + dev_dbg(wm831x_power->wm831x->dev,
>> + "Limiting USB current to %umA", wm831x_usb_limits[best]);
>> +
>> + wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
>> + WM831X_USB_ILIM_MASK, best);
>> +
>> + return 0;
>> +}
>> +
>>  /*
>>   *   Battery properties
>>   */
>> @@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device 
>> *pdev)
>>   }
>>   }
>>
>> + power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
>> +  "usb-phy", 0);
>> + if (IS_ERR(power->usb_phy)) {
>> + ret = PTR_ERR(power->usb_phy);
>> + dev_err(>dev, "Failed to find USB phy: %d\n", ret);
>> + goto err_bat_irq;
>> + }
>> +
>> + power->usb_notify.notifier_call = wm831x_usb_limit_change;
>> + ret = usb_register_notifier(power->usb_phy,
>> + >usb_notify);
>> + if (ret) {
>> + dev_err(>dev, "Failed to register notifier: %d\n", ret);
>> + goto err_bat_irq;
>> + }
>> +
>>   return ret;
>>
>>  err_bat_irq:
>> @@ -637,6 +693,11 @@ static int wm831x_power_remove(struct platform_device 
>> *pdev)
>>   struct wm831x *wm831x = wm831x_power->wm831x;
>>   int irq, i;
>>
>> + if (wm831x_power->usb_phy) {
>> + usb_unregister_notifier(wm831x_power->usb_phy,
>> + _power->usb_notify);
>> + }
>> +
>>   for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
>>   irq = wm831x_irq(wm831x,
>>platform_get_irq_byname(pdev,
>> --
>> 1.7.9.5
>>



-- 
Baolin.wang
Best Regards


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-04 Thread Baolin Wang
Hi,

On 3 July 2017 at 23:50, Sebastian Reichel
 wrote:
> Hi,
>
> On Mon, Jul 03, 2017 at 02:07:15PM +0800, Baolin Wang wrote:
>> Integrate with the newly added USB charger interface to limit the current
>> we draw from the USB input based on the input device configuration
>> identified by the USB stack, allowing us to charge more quickly from high
>> current inputs without drawing more current than specified from others.
>>
>> Signed-off-by: Mark Brown 
>> Signed-off-by: Baolin Wang 
>
> Missing DT binding documentation, otherwise fine with me.
> Would be nice to convert existing drivers:
>
> $ git grep -l extcon -- drivers/power/supply
> drivers/power/supply/axp288_charger.c
> drivers/power/supply/bq24190_charger.c
> drivers/power/supply/charger-manager.c
> drivers/power/supply/qcom_smbb.c

I'll create new patches with adding the DT binding documentation if
there are no objections for USB phy modification, moreover I will help
to convert these drivers you listed. Thanks.

>
> -- Sebastian
>
>> ---
>>  drivers/power/supply/wm831x_power.c |   61 
>> +++
>>  1 file changed, 61 insertions(+)
>>
>> diff --git a/drivers/power/supply/wm831x_power.c 
>> b/drivers/power/supply/wm831x_power.c
>> index 7082301..3e3480708 100644
>> --- a/drivers/power/supply/wm831x_power.c
>> +++ b/drivers/power/supply/wm831x_power.c
>> @@ -13,6 +13,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  #include 
>>  #include 
>> @@ -31,6 +32,8 @@ struct wm831x_power {
>>   char usb_name[20];
>>   char battery_name[20];
>>   bool have_battery;
>> + struct usb_phy *usb_phy;
>> + struct notifier_block usb_notify;
>>  };
>>
>>  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
>> @@ -125,6 +128,43 @@ static int wm831x_usb_get_prop(struct power_supply *psy,
>>   POWER_SUPPLY_PROP_VOLTAGE_NOW,
>>  };
>>
>> +/* In milliamps */
>> +static const unsigned int wm831x_usb_limits[] = {
>> + 0,
>> + 2,
>> + 100,
>> + 500,
>> + 900,
>> + 1500,
>> + 1800,
>> + 550,
>> +};
>> +
>> +static int wm831x_usb_limit_change(struct notifier_block *nb,
>> +unsigned long limit, void *data)
>> +{
>> + struct wm831x_power *wm831x_power = container_of(nb,
>> +  struct wm831x_power,
>> +  usb_notify);
>> + unsigned int i, best;
>> +
>> + /* Find the highest supported limit */
>> + best = 0;
>> + for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
>> + if (limit >= wm831x_usb_limits[i] &&
>> + wm831x_usb_limits[best] < wm831x_usb_limits[i])
>> + best = i;
>> + }
>> +
>> + dev_dbg(wm831x_power->wm831x->dev,
>> + "Limiting USB current to %umA", wm831x_usb_limits[best]);
>> +
>> + wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
>> + WM831X_USB_ILIM_MASK, best);
>> +
>> + return 0;
>> +}
>> +
>>  /*
>>   *   Battery properties
>>   */
>> @@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device 
>> *pdev)
>>   }
>>   }
>>
>> + power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
>> +  "usb-phy", 0);
>> + if (IS_ERR(power->usb_phy)) {
>> + ret = PTR_ERR(power->usb_phy);
>> + dev_err(>dev, "Failed to find USB phy: %d\n", ret);
>> + goto err_bat_irq;
>> + }
>> +
>> + power->usb_notify.notifier_call = wm831x_usb_limit_change;
>> + ret = usb_register_notifier(power->usb_phy,
>> + >usb_notify);
>> + if (ret) {
>> + dev_err(>dev, "Failed to register notifier: %d\n", ret);
>> + goto err_bat_irq;
>> + }
>> +
>>   return ret;
>>
>>  err_bat_irq:
>> @@ -637,6 +693,11 @@ static int wm831x_power_remove(struct platform_device 
>> *pdev)
>>   struct wm831x *wm831x = wm831x_power->wm831x;
>>   int irq, i;
>>
>> + if (wm831x_power->usb_phy) {
>> + usb_unregister_notifier(wm831x_power->usb_phy,
>> + _power->usb_notify);
>> + }
>> +
>>   for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
>>   irq = wm831x_irq(wm831x,
>>platform_get_irq_byname(pdev,
>> --
>> 1.7.9.5
>>



-- 
Baolin.wang
Best Regards


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-03 Thread Sebastian Reichel
Hi,

On Mon, Jul 03, 2017 at 02:07:15PM +0800, Baolin Wang wrote:
> Integrate with the newly added USB charger interface to limit the current
> we draw from the USB input based on the input device configuration
> identified by the USB stack, allowing us to charge more quickly from high
> current inputs without drawing more current than specified from others.
> 
> Signed-off-by: Mark Brown 
> Signed-off-by: Baolin Wang 

Missing DT binding documentation, otherwise fine with me.
Would be nice to convert existing drivers:

$ git grep -l extcon -- drivers/power/supply
drivers/power/supply/axp288_charger.c
drivers/power/supply/bq24190_charger.c
drivers/power/supply/charger-manager.c
drivers/power/supply/qcom_smbb.c

-- Sebastian

> ---
>  drivers/power/supply/wm831x_power.c |   61 
> +++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/drivers/power/supply/wm831x_power.c 
> b/drivers/power/supply/wm831x_power.c
> index 7082301..3e3480708 100644
> --- a/drivers/power/supply/wm831x_power.c
> +++ b/drivers/power/supply/wm831x_power.c
> @@ -13,6 +13,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -31,6 +32,8 @@ struct wm831x_power {
>   char usb_name[20];
>   char battery_name[20];
>   bool have_battery;
> + struct usb_phy *usb_phy;
> + struct notifier_block usb_notify;
>  };
>  
>  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
> @@ -125,6 +128,43 @@ static int wm831x_usb_get_prop(struct power_supply *psy,
>   POWER_SUPPLY_PROP_VOLTAGE_NOW,
>  };
>  
> +/* In milliamps */
> +static const unsigned int wm831x_usb_limits[] = {
> + 0,
> + 2,
> + 100,
> + 500,
> + 900,
> + 1500,
> + 1800,
> + 550,
> +};
> +
> +static int wm831x_usb_limit_change(struct notifier_block *nb,
> +unsigned long limit, void *data)
> +{
> + struct wm831x_power *wm831x_power = container_of(nb,
> +  struct wm831x_power,
> +  usb_notify);
> + unsigned int i, best;
> +
> + /* Find the highest supported limit */
> + best = 0;
> + for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
> + if (limit >= wm831x_usb_limits[i] &&
> + wm831x_usb_limits[best] < wm831x_usb_limits[i])
> + best = i;
> + }
> +
> + dev_dbg(wm831x_power->wm831x->dev,
> + "Limiting USB current to %umA", wm831x_usb_limits[best]);
> +
> + wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
> + WM831X_USB_ILIM_MASK, best);
> +
> + return 0;
> +}
> +
>  /*
>   *   Battery properties
>   */
> @@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device 
> *pdev)
>   }
>   }
>  
> + power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
> +  "usb-phy", 0);
> + if (IS_ERR(power->usb_phy)) {
> + ret = PTR_ERR(power->usb_phy);
> + dev_err(>dev, "Failed to find USB phy: %d\n", ret);
> + goto err_bat_irq;
> + }
> +
> + power->usb_notify.notifier_call = wm831x_usb_limit_change;
> + ret = usb_register_notifier(power->usb_phy,
> + >usb_notify);
> + if (ret) {
> + dev_err(>dev, "Failed to register notifier: %d\n", ret);
> + goto err_bat_irq;
> + }
> +
>   return ret;
>  
>  err_bat_irq:
> @@ -637,6 +693,11 @@ static int wm831x_power_remove(struct platform_device 
> *pdev)
>   struct wm831x *wm831x = wm831x_power->wm831x;
>   int irq, i;
>  
> + if (wm831x_power->usb_phy) {
> + usb_unregister_notifier(wm831x_power->usb_phy,
> + _power->usb_notify);
> + }
> +
>   for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
>   irq = wm831x_irq(wm831x, 
>platform_get_irq_byname(pdev,
> -- 
> 1.7.9.5
> 


signature.asc
Description: PGP signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-03 Thread Sebastian Reichel
Hi,

On Mon, Jul 03, 2017 at 02:07:15PM +0800, Baolin Wang wrote:
> Integrate with the newly added USB charger interface to limit the current
> we draw from the USB input based on the input device configuration
> identified by the USB stack, allowing us to charge more quickly from high
> current inputs without drawing more current than specified from others.
> 
> Signed-off-by: Mark Brown 
> Signed-off-by: Baolin Wang 

Missing DT binding documentation, otherwise fine with me.
Would be nice to convert existing drivers:

$ git grep -l extcon -- drivers/power/supply
drivers/power/supply/axp288_charger.c
drivers/power/supply/bq24190_charger.c
drivers/power/supply/charger-manager.c
drivers/power/supply/qcom_smbb.c

-- Sebastian

> ---
>  drivers/power/supply/wm831x_power.c |   61 
> +++
>  1 file changed, 61 insertions(+)
> 
> diff --git a/drivers/power/supply/wm831x_power.c 
> b/drivers/power/supply/wm831x_power.c
> index 7082301..3e3480708 100644
> --- a/drivers/power/supply/wm831x_power.c
> +++ b/drivers/power/supply/wm831x_power.c
> @@ -13,6 +13,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -31,6 +32,8 @@ struct wm831x_power {
>   char usb_name[20];
>   char battery_name[20];
>   bool have_battery;
> + struct usb_phy *usb_phy;
> + struct notifier_block usb_notify;
>  };
>  
>  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
> @@ -125,6 +128,43 @@ static int wm831x_usb_get_prop(struct power_supply *psy,
>   POWER_SUPPLY_PROP_VOLTAGE_NOW,
>  };
>  
> +/* In milliamps */
> +static const unsigned int wm831x_usb_limits[] = {
> + 0,
> + 2,
> + 100,
> + 500,
> + 900,
> + 1500,
> + 1800,
> + 550,
> +};
> +
> +static int wm831x_usb_limit_change(struct notifier_block *nb,
> +unsigned long limit, void *data)
> +{
> + struct wm831x_power *wm831x_power = container_of(nb,
> +  struct wm831x_power,
> +  usb_notify);
> + unsigned int i, best;
> +
> + /* Find the highest supported limit */
> + best = 0;
> + for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
> + if (limit >= wm831x_usb_limits[i] &&
> + wm831x_usb_limits[best] < wm831x_usb_limits[i])
> + best = i;
> + }
> +
> + dev_dbg(wm831x_power->wm831x->dev,
> + "Limiting USB current to %umA", wm831x_usb_limits[best]);
> +
> + wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
> + WM831X_USB_ILIM_MASK, best);
> +
> + return 0;
> +}
> +
>  /*
>   *   Battery properties
>   */
> @@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device 
> *pdev)
>   }
>   }
>  
> + power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
> +  "usb-phy", 0);
> + if (IS_ERR(power->usb_phy)) {
> + ret = PTR_ERR(power->usb_phy);
> + dev_err(>dev, "Failed to find USB phy: %d\n", ret);
> + goto err_bat_irq;
> + }
> +
> + power->usb_notify.notifier_call = wm831x_usb_limit_change;
> + ret = usb_register_notifier(power->usb_phy,
> + >usb_notify);
> + if (ret) {
> + dev_err(>dev, "Failed to register notifier: %d\n", ret);
> + goto err_bat_irq;
> + }
> +
>   return ret;
>  
>  err_bat_irq:
> @@ -637,6 +693,11 @@ static int wm831x_power_remove(struct platform_device 
> *pdev)
>   struct wm831x *wm831x = wm831x_power->wm831x;
>   int irq, i;
>  
> + if (wm831x_power->usb_phy) {
> + usb_unregister_notifier(wm831x_power->usb_phy,
> + _power->usb_notify);
> + }
> +
>   for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
>   irq = wm831x_irq(wm831x, 
>platform_get_irq_byname(pdev,
> -- 
> 1.7.9.5
> 


signature.asc
Description: PGP signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-03 Thread Charles Keepax
On Mon, Jul 03, 2017 at 02:07:15PM +0800, Baolin Wang wrote:
> Integrate with the newly added USB charger interface to limit the current
> we draw from the USB input based on the input device configuration
> identified by the USB stack, allowing us to charge more quickly from high
> current inputs without drawing more current than specified from others.
> 
> Signed-off-by: Mark Brown 
> Signed-off-by: Baolin Wang 
> ---

>  /*
>   *   Battery properties
>   */
> @@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device 
> *pdev)
>   }
>   }
>  
> + power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
> +  "usb-phy", 0);
> + if (IS_ERR(power->usb_phy)) {
> + ret = PTR_ERR(power->usb_phy);
> + dev_err(>dev, "Failed to find USB phy: %d\n", ret);
> + goto err_bat_irq;
> + }
> +

We should probably update the binding documentation for this as
well: mfd/wm831x.txt

Also I am not sure this needs to be implemented now, but what is
the plan regarding pdata systems? Generally the driver supports
both and it would be nice to know there is a way forward for that
even if we don't implement it yet.

Thanks,
Charles


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-03 Thread Charles Keepax
On Mon, Jul 03, 2017 at 02:07:15PM +0800, Baolin Wang wrote:
> Integrate with the newly added USB charger interface to limit the current
> we draw from the USB input based on the input device configuration
> identified by the USB stack, allowing us to charge more quickly from high
> current inputs without drawing more current than specified from others.
> 
> Signed-off-by: Mark Brown 
> Signed-off-by: Baolin Wang 
> ---

>  /*
>   *   Battery properties
>   */
> @@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device 
> *pdev)
>   }
>   }
>  
> + power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
> +  "usb-phy", 0);
> + if (IS_ERR(power->usb_phy)) {
> + ret = PTR_ERR(power->usb_phy);
> + dev_err(>dev, "Failed to find USB phy: %d\n", ret);
> + goto err_bat_irq;
> + }
> +

We should probably update the binding documentation for this as
well: mfd/wm831x.txt

Also I am not sure this needs to be implemented now, but what is
the plan regarding pdata systems? Generally the driver supports
both and it would be nice to know there is a way forward for that
even if we don't implement it yet.

Thanks,
Charles


[PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-03 Thread Baolin Wang
Integrate with the newly added USB charger interface to limit the current
we draw from the USB input based on the input device configuration
identified by the USB stack, allowing us to charge more quickly from high
current inputs without drawing more current than specified from others.

Signed-off-by: Mark Brown 
Signed-off-by: Baolin Wang 
---
 drivers/power/supply/wm831x_power.c |   61 +++
 1 file changed, 61 insertions(+)

diff --git a/drivers/power/supply/wm831x_power.c 
b/drivers/power/supply/wm831x_power.c
index 7082301..3e3480708 100644
--- a/drivers/power/supply/wm831x_power.c
+++ b/drivers/power/supply/wm831x_power.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+   struct usb_phy *usb_phy;
+   struct notifier_block usb_notify;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,43 @@ static int wm831x_usb_get_prop(struct power_supply *psy,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
+/* In milliamps */
+static const unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   unsigned int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit >= wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %umA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+
 /*
  * Battery properties
  */
@@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
 
+   power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
+"usb-phy", 0);
+   if (IS_ERR(power->usb_phy)) {
+   ret = PTR_ERR(power->usb_phy);
+   dev_err(>dev, "Failed to find USB phy: %d\n", ret);
+   goto err_bat_irq;
+   }
+
+   power->usb_notify.notifier_call = wm831x_usb_limit_change;
+   ret = usb_register_notifier(power->usb_phy,
+   >usb_notify);
+   if (ret) {
+   dev_err(>dev, "Failed to register notifier: %d\n", ret);
+   goto err_bat_irq;
+   }
+
return ret;
 
 err_bat_irq:
@@ -637,6 +693,11 @@ static int wm831x_power_remove(struct platform_device 
*pdev)
struct wm831x *wm831x = wm831x_power->wm831x;
int irq, i;
 
+   if (wm831x_power->usb_phy) {
+   usb_unregister_notifier(wm831x_power->usb_phy,
+   _power->usb_notify);
+   }
+
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x, 
 platform_get_irq_byname(pdev,
-- 
1.7.9.5



[PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2017-07-03 Thread Baolin Wang
Integrate with the newly added USB charger interface to limit the current
we draw from the USB input based on the input device configuration
identified by the USB stack, allowing us to charge more quickly from high
current inputs without drawing more current than specified from others.

Signed-off-by: Mark Brown 
Signed-off-by: Baolin Wang 
---
 drivers/power/supply/wm831x_power.c |   61 +++
 1 file changed, 61 insertions(+)

diff --git a/drivers/power/supply/wm831x_power.c 
b/drivers/power/supply/wm831x_power.c
index 7082301..3e3480708 100644
--- a/drivers/power/supply/wm831x_power.c
+++ b/drivers/power/supply/wm831x_power.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+   struct usb_phy *usb_phy;
+   struct notifier_block usb_notify;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,43 @@ static int wm831x_usb_get_prop(struct power_supply *psy,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
+/* In milliamps */
+static const unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   unsigned int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit >= wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %umA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+
 /*
  * Battery properties
  */
@@ -607,6 +647,22 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
 
+   power->usb_phy = devm_usb_get_phy_by_phandle(>dev,
+"usb-phy", 0);
+   if (IS_ERR(power->usb_phy)) {
+   ret = PTR_ERR(power->usb_phy);
+   dev_err(>dev, "Failed to find USB phy: %d\n", ret);
+   goto err_bat_irq;
+   }
+
+   power->usb_notify.notifier_call = wm831x_usb_limit_change;
+   ret = usb_register_notifier(power->usb_phy,
+   >usb_notify);
+   if (ret) {
+   dev_err(>dev, "Failed to register notifier: %d\n", ret);
+   goto err_bat_irq;
+   }
+
return ret;
 
 err_bat_irq:
@@ -637,6 +693,11 @@ static int wm831x_power_remove(struct platform_device 
*pdev)
struct wm831x *wm831x = wm831x_power->wm831x;
int irq, i;
 
+   if (wm831x_power->usb_phy) {
+   usb_unregister_notifier(wm831x_power->usb_phy,
+   _power->usb_notify);
+   }
+
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x, 
 platform_get_irq_byname(pdev,
-- 
1.7.9.5



Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-20 Thread Baolin Wang
On 20 August 2015 at 17:02, David Laight  wrote:
> From: Baolin Wang
>> Sent: 14 August 2015 10:48
>> +/* In miliamps */
>
> Spelling police: "milliamps"
>

Hi David,

I'll correct it in next patch series. Thanks for your comments.

>> +static unsigned int wm831x_usb_limits[] = {
>> + 0,
>> + 2,
>> + 100,
>> + 500,
>> + 900,
>> + 1500,
>> + 1800,
>> + 550,
>> +};
>
> David
>



-- 
Baolin.wang
Best Regards
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-20 Thread David Laight
From: Baolin Wang
> Sent: 14 August 2015 10:48
> +/* In miliamps */

Spelling police: "milliamps"

> +static unsigned int wm831x_usb_limits[] = {
> + 0,
> + 2,
> + 100,
> + 500,
> + 900,
> + 1500,
> + 1800,
> + 550,
> +};

David

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-20 Thread David Laight
From: Baolin Wang
 Sent: 14 August 2015 10:48
 +/* In miliamps */

Spelling police: milliamps

 +static unsigned int wm831x_usb_limits[] = {
 + 0,
 + 2,
 + 100,
 + 500,
 + 900,
 + 1500,
 + 1800,
 + 550,
 +};

David

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-20 Thread Baolin Wang
On 20 August 2015 at 17:02, David Laight david.lai...@aculab.com wrote:
 From: Baolin Wang
 Sent: 14 August 2015 10:48
 +/* In miliamps */

 Spelling police: milliamps


Hi David,

I'll correct it in next patch series. Thanks for your comments.

 +static unsigned int wm831x_usb_limits[] = {
 + 0,
 + 2,
 + 100,
 + 500,
 + 900,
 + 1500,
 + 1800,
 + 550,
 +};

 David




-- 
Baolin.wang
Best Regards
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-19 Thread Mark Brown
On Wed, Aug 19, 2015 at 08:02:37AM +0800, Peter Chen wrote:

> Below code may be correct for the goal you expressed.

>for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
>if (limit >= wm831x_usb_limits[i] &&
>wm831x_usb_limits[best] < wm831x_usb_limits[i])
>best = i;
>}

Yes, that's right.


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-19 Thread Mark Brown
On Wed, Aug 19, 2015 at 08:02:37AM +0800, Peter Chen wrote:

 Below code may be correct for the goal you expressed.

for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
if (limit = wm831x_usb_limits[i] 
wm831x_usb_limits[best]  wm831x_usb_limits[i])
best = i;
}

Yes, that's right.


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-18 Thread Peter Chen
On Tue, Aug 18, 2015 at 09:12:00AM -0700, Mark Brown wrote:
> On Tue, Aug 18, 2015 at 01:20:12PM +0800, Peter Chen wrote:
> 
> > ok, I just had suspected below function's correctness, after looking
> > it again, it always set 1800 as charging limit, does it be expected?
> 
> > +   /* Find the highest supported limit */
> > +   best = 0;
> > +   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
> > +   if (limit < wm831x_usb_limits[i] &&
> 

+/* In miliamps */
+static unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit < wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %dmA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+

> The above check is intended to ensure that we don't go over the limit
> that was passed in in the callback.  The goal is to select the highest
> option that is less than the limit passed in.

Please correct me if I was wrong, If there is SDP (PC), the current
limit is 500mA, then when the i = 4, (500 < 900) && (0 < 900) is true,
the best is 4. When the i goes to 5, (500 < 1500) && (900 < 1500) is
true, the best is 5. At last, the best will be 1800, which is not our
expectation.

Below code may be correct for the goal you expressed.

   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
   if (limit >= wm831x_usb_limits[i] &&
   wm831x_usb_limits[best] < wm831x_usb_limits[i])
   best = i;
   }

-- 

Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-18 Thread Mark Brown
On Tue, Aug 18, 2015 at 01:20:12PM +0800, Peter Chen wrote:

> ok, I just had suspected below function's correctness, after looking
> it again, it always set 1800 as charging limit, does it be expected?

> +   /* Find the highest supported limit */
> +   best = 0;
> +   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
> +   if (limit < wm831x_usb_limits[i] &&

The above check is intended to ensure that we don't go over the limit
that was passed in in the callback.  The goal is to select the highest
option that is less than the limit passed in.


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-18 Thread Felipe Balbi
On Mon, Aug 17, 2015 at 10:04:05PM -0700, Mark Brown wrote:
> On Mon, Aug 17, 2015 at 06:58:16PM -0500, Felipe Balbi wrote:
> > On Mon, Aug 17, 2015 at 10:26:23AM -0700, Mark Brown wrote:
> > > On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
> > > > On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:
> 
> > > > > + if (wm831x_pdata && wm831x_pdata->usb_gadget) {
> 
> > > > Where the wm831x_pdata->usb_gadget is initialized?
> 
> > > It's platform data, it will be initialised by whatever registers the
> > > platform data.
> 
> > passing pointers through pdata ?
> 
> It's a char * to a name, not a pointer to struct.

aha, fair enough.

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-18 Thread Peter Chen
On Mon, Aug 17, 2015 at 10:26:23AM -0700, Mark Brown wrote:
> On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
> > On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:
> 
> > > + 1500,
> > > + 1800,
> > > + 550,
> > > +};
> 
> > Why 550 is the last, but not 1800?
> 
> You'd have to ask the hardware engineers who designed the chip.  I
> suspect it's because 550 was added at a late stage in the design process
> but I'm basically just guessing there.

ok, I just had suspected below function's correctness, after looking
it again, it always set 1800 as charging limit, does it be expected?

+/* In miliamps */
+static unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit < wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %dmA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+

> 
> > >   */
> > > @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
> > > *pdev)
> > >   }
> > >   }
> 
> > > + if (wm831x_pdata && wm831x_pdata->usb_gadget) {
> 
> > Where the wm831x_pdata->usb_gadget is initialized?
> 
> It's platform data, it will be initialised by whatever registers the
> platform data.

Get it, I just do not find in this patch set, thanks.

-- 

Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-18 Thread Peter Chen
On Mon, Aug 17, 2015 at 10:26:23AM -0700, Mark Brown wrote:
 On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
  On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:
 
   + 1500,
   + 1800,
   + 550,
   +};
 
  Why 550 is the last, but not 1800?
 
 You'd have to ask the hardware engineers who designed the chip.  I
 suspect it's because 550 was added at a late stage in the design process
 but I'm basically just guessing there.

ok, I just had suspected below function's correctness, after looking
it again, it always set 1800 as charging limit, does it be expected?

+/* In miliamps */
+static unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit  wm831x_usb_limits[i] 
+   wm831x_usb_limits[best]  wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power-wm831x-dev,
+   Limiting USB current to %dmA, wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power-wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+

 
 */
   @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
   *pdev)
 }
 }
 
   + if (wm831x_pdata  wm831x_pdata-usb_gadget) {
 
  Where the wm831x_pdata-usb_gadget is initialized?
 
 It's platform data, it will be initialised by whatever registers the
 platform data.

Get it, I just do not find in this patch set, thanks.

-- 

Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-18 Thread Peter Chen
On Tue, Aug 18, 2015 at 09:12:00AM -0700, Mark Brown wrote:
 On Tue, Aug 18, 2015 at 01:20:12PM +0800, Peter Chen wrote:
 
  ok, I just had suspected below function's correctness, after looking
  it again, it always set 1800 as charging limit, does it be expected?
 
  +   /* Find the highest supported limit */
  +   best = 0;
  +   for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
  +   if (limit  wm831x_usb_limits[i] 
 

+/* In miliamps */
+static unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit  wm831x_usb_limits[i] 
+   wm831x_usb_limits[best]  wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power-wm831x-dev,
+   Limiting USB current to %dmA, wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power-wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+

 The above check is intended to ensure that we don't go over the limit
 that was passed in in the callback.  The goal is to select the highest
 option that is less than the limit passed in.

Please correct me if I was wrong, If there is SDP (PC), the current
limit is 500mA, then when the i = 4, (500  900)  (0  900) is true,
the best is 4. When the i goes to 5, (500  1500)  (900  1500) is
true, the best is 5. At last, the best will be 1800, which is not our
expectation.

Below code may be correct for the goal you expressed.

   for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
   if (limit = wm831x_usb_limits[i] 
   wm831x_usb_limits[best]  wm831x_usb_limits[i])
   best = i;
   }

-- 

Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-18 Thread Felipe Balbi
On Mon, Aug 17, 2015 at 10:04:05PM -0700, Mark Brown wrote:
 On Mon, Aug 17, 2015 at 06:58:16PM -0500, Felipe Balbi wrote:
  On Mon, Aug 17, 2015 at 10:26:23AM -0700, Mark Brown wrote:
   On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:
 
 + if (wm831x_pdata  wm831x_pdata-usb_gadget) {
 
Where the wm831x_pdata-usb_gadget is initialized?
 
   It's platform data, it will be initialised by whatever registers the
   platform data.
 
  passing pointers through pdata ?
 
 It's a char * to a name, not a pointer to struct.

aha, fair enough.

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-18 Thread Mark Brown
On Tue, Aug 18, 2015 at 01:20:12PM +0800, Peter Chen wrote:

 ok, I just had suspected below function's correctness, after looking
 it again, it always set 1800 as charging limit, does it be expected?

 +   /* Find the highest supported limit */
 +   best = 0;
 +   for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
 +   if (limit  wm831x_usb_limits[i] 

The above check is intended to ensure that we don't go over the limit
that was passed in in the callback.  The goal is to select the highest
option that is less than the limit passed in.


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-17 Thread Mark Brown
On Mon, Aug 17, 2015 at 06:58:16PM -0500, Felipe Balbi wrote:
> On Mon, Aug 17, 2015 at 10:26:23AM -0700, Mark Brown wrote:
> > On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
> > > On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:

> > > > +   if (wm831x_pdata && wm831x_pdata->usb_gadget) {

> > > Where the wm831x_pdata->usb_gadget is initialized?

> > It's platform data, it will be initialised by whatever registers the
> > platform data.

> passing pointers through pdata ?

It's a char * to a name, not a pointer to struct.


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-17 Thread Felipe Balbi
On Mon, Aug 17, 2015 at 10:26:23AM -0700, Mark Brown wrote:
> On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
> > On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:
> 
> > > + 1500,
> > > + 1800,
> > > + 550,
> > > +};
> 
> > Why 550 is the last, but not 1800?
> 
> You'd have to ask the hardware engineers who designed the chip.  I
> suspect it's because 550 was added at a late stage in the design process
> but I'm basically just guessing there.
> 
> > >   */
> > > @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
> > > *pdev)
> > >   }
> > >   }
> 
> > > + if (wm831x_pdata && wm831x_pdata->usb_gadget) {
> 
> > Where the wm831x_pdata->usb_gadget is initialized?
> 
> It's platform data, it will be initialised by whatever registers the
> platform data.

passing pointers through pdata ?

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-17 Thread Mark Brown
On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
> On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:

> > +   1500,
> > +   1800,
> > +   550,
> > +};

> Why 550 is the last, but not 1800?

You'd have to ask the hardware engineers who designed the chip.  I
suspect it's because 550 was added at a late stage in the design process
but I'm basically just guessing there.

> >   */
> > @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
> > *pdev)
> > }
> > }

> > +   if (wm831x_pdata && wm831x_pdata->usb_gadget) {

> Where the wm831x_pdata->usb_gadget is initialized?

It's platform data, it will be initialised by whatever registers the
platform data.


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-17 Thread Felipe Balbi
On Mon, Aug 17, 2015 at 10:26:23AM -0700, Mark Brown wrote:
 On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
  On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:
 
   + 1500,
   + 1800,
   + 550,
   +};
 
  Why 550 is the last, but not 1800?
 
 You'd have to ask the hardware engineers who designed the chip.  I
 suspect it's because 550 was added at a late stage in the design process
 but I'm basically just guessing there.
 
 */
   @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
   *pdev)
 }
 }
 
   + if (wm831x_pdata  wm831x_pdata-usb_gadget) {
 
  Where the wm831x_pdata-usb_gadget is initialized?
 
 It's platform data, it will be initialised by whatever registers the
 platform data.

passing pointers through pdata ?

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-17 Thread Mark Brown
On Mon, Aug 17, 2015 at 06:58:16PM -0500, Felipe Balbi wrote:
 On Mon, Aug 17, 2015 at 10:26:23AM -0700, Mark Brown wrote:
  On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
   On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:

+   if (wm831x_pdata  wm831x_pdata-usb_gadget) {

   Where the wm831x_pdata-usb_gadget is initialized?

  It's platform data, it will be initialised by whatever registers the
  platform data.

 passing pointers through pdata ?

It's a char * to a name, not a pointer to struct.


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-17 Thread Mark Brown
On Mon, Aug 17, 2015 at 09:07:08AM +0800, Peter Chen wrote:
 On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:

  +   1500,
  +   1800,
  +   550,
  +};

 Why 550 is the last, but not 1800?

You'd have to ask the hardware engineers who designed the chip.  I
suspect it's because 550 was added at a late stage in the design process
but I'm basically just guessing there.

*/
  @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
  *pdev)
  }
  }

  +   if (wm831x_pdata  wm831x_pdata-usb_gadget) {

 Where the wm831x_pdata-usb_gadget is initialized?

It's platform data, it will be initialised by whatever registers the
platform data.


signature.asc
Description: Digital signature


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-16 Thread Peter Chen
On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:
> Integrate with the newly added USB charger interface to limit the current
> we draw from the USB input based on the input device configuration
> identified by the USB stack, allowing us to charge more quickly from high
> current inputs without drawing more current than specified from others.
> 
> Signed-off-by: Mark Brown 
> Signed-off-by: Baolin Wang 
> ---
>  drivers/power/wm831x_power.c |   69 
> ++
>  include/linux/mfd/wm831x/pdata.h |3 ++
>  2 files changed, 72 insertions(+)
> 
> diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
> index db11ae6..72c661f 100644
> --- a/drivers/power/wm831x_power.c
> +++ b/drivers/power/wm831x_power.c
> @@ -13,6 +13,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -31,6 +32,8 @@ struct wm831x_power {
>   char usb_name[20];
>   char battery_name[20];
>   bool have_battery;
> + struct usb_charger *usb_charger;
> + struct notifier_block usb_notify;
>  };
>  
>  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
> @@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
>   POWER_SUPPLY_PROP_VOLTAGE_NOW,
>  };
>  
> +/* In miliamps */
> +static unsigned int wm831x_usb_limits[] = {
> + 0,
> + 2,
> + 100,
> + 500,
> + 900,
> + 1500,
> + 1800,
> + 550,
> +};

Why 550 is the last, but not 1800?

> +
> +static int wm831x_usb_limit_change(struct notifier_block *nb,
> +unsigned long limit, void *data)
> +{
> + struct wm831x_power *wm831x_power = container_of(nb,
> +  struct wm831x_power,
> +  usb_notify);
> + int i, best;
> +
> + /* Find the highest supported limit */
> + best = 0;
> + for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
> + if (limit < wm831x_usb_limits[i] &&
> + wm831x_usb_limits[best] < wm831x_usb_limits[i])
> + best = i;
> + }
> +
> + dev_dbg(wm831x_power->wm831x->dev,
> + "Limiting USB current to %dmA", wm831x_usb_limits[best]);
> +
> + wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
> + WM831X_USB_ILIM_MASK, best);
> +
> + return 0;
> +}
> +
>  /*
>   *   Battery properties
>   */
> @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
> *pdev)
>   }
>   }
>  
> + if (wm831x_pdata && wm831x_pdata->usb_gadget) {

Where the wm831x_pdata->usb_gadget is initialized?

> + power->usb_charger =
> + usb_charger_find_by_name(wm831x_pdata->usb_gadget);
> + if (IS_ERR(power->usb_charger)) {
> + ret = PTR_ERR(power->usb_charger);
> + dev_err(>dev,
> + "Failed to find USB gadget: %d\n", ret);
> + goto err_bat_irq;
> + }
> +
> + power->usb_notify.notifier_call = wm831x_usb_limit_change;
> +
> + ret = usb_charger_register_notify(power->usb_charger,
> +   >usb_notify);
> + if (ret != 0) {
> + dev_err(>dev,
> + "Failed to register notifier: %d\n", ret);
> + goto err_usb_charger;
> + }
> + }
> +
>   return ret;
>  
> +err_usb_charger:
> + usb_charger_put(power->usb_charger);
>  err_bat_irq:
>   --i;
>   for (; i >= 0; i--) {
> @@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device 
> *pdev)
>   struct wm831x *wm831x = wm831x_power->wm831x;
>   int irq, i;
>  
> + if (wm831x_power->usb_charger) {
> + usb_charger_unregister_notify(wm831x_power->usb_charger,
> +   _power->usb_notify);
> + usb_charger_put(wm831x_power->usb_charger);
> + }
> +
>   for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
>   irq = wm831x_irq(wm831x, 
>platform_get_irq_byname(pdev,
> diff --git a/include/linux/mfd/wm831x/pdata.h 
> b/include/linux/mfd/wm831x/pdata.h
> index dcc9631..5af8399 100644
> --- a/include/linux/mfd/wm831x/pdata.h
> +++ b/include/linux/mfd/wm831x/pdata.h
> @@ -126,6 +126,9 @@ struct wm831x_pdata {
>   /** The driver should initiate a power off sequence during shutdown */
>   bool soft_shutdown;
>  
> + /** dev_name of USB charger gadget to integrate with */
> + const char *usb_gadget;
> +
>   int irq_base;
>   int gpio_base;
>   int gpio_defaults[WM831X_GPIO_NUM];
> -- 
> 1.7.9.5
> 


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-16 Thread Peter Chen
On Fri, Aug 14, 2015 at 05:47:46PM +0800, Baolin Wang wrote:
 Integrate with the newly added USB charger interface to limit the current
 we draw from the USB input based on the input device configuration
 identified by the USB stack, allowing us to charge more quickly from high
 current inputs without drawing more current than specified from others.
 
 Signed-off-by: Mark Brown broo...@kernel.org
 Signed-off-by: Baolin Wang baolin.w...@linaro.org
 ---
  drivers/power/wm831x_power.c |   69 
 ++
  include/linux/mfd/wm831x/pdata.h |3 ++
  2 files changed, 72 insertions(+)
 
 diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
 index db11ae6..72c661f 100644
 --- a/drivers/power/wm831x_power.c
 +++ b/drivers/power/wm831x_power.c
 @@ -13,6 +13,7 @@
  #include linux/platform_device.h
  #include linux/power_supply.h
  #include linux/slab.h
 +#include linux/usb/usb_charger.h
  
  #include linux/mfd/wm831x/core.h
  #include linux/mfd/wm831x/auxadc.h
 @@ -31,6 +32,8 @@ struct wm831x_power {
   char usb_name[20];
   char battery_name[20];
   bool have_battery;
 + struct usb_charger *usb_charger;
 + struct notifier_block usb_notify;
  };
  
  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
 @@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
   POWER_SUPPLY_PROP_VOLTAGE_NOW,
  };
  
 +/* In miliamps */
 +static unsigned int wm831x_usb_limits[] = {
 + 0,
 + 2,
 + 100,
 + 500,
 + 900,
 + 1500,
 + 1800,
 + 550,
 +};

Why 550 is the last, but not 1800?

 +
 +static int wm831x_usb_limit_change(struct notifier_block *nb,
 +unsigned long limit, void *data)
 +{
 + struct wm831x_power *wm831x_power = container_of(nb,
 +  struct wm831x_power,
 +  usb_notify);
 + int i, best;
 +
 + /* Find the highest supported limit */
 + best = 0;
 + for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
 + if (limit  wm831x_usb_limits[i] 
 + wm831x_usb_limits[best]  wm831x_usb_limits[i])
 + best = i;
 + }
 +
 + dev_dbg(wm831x_power-wm831x-dev,
 + Limiting USB current to %dmA, wm831x_usb_limits[best]);
 +
 + wm831x_set_bits(wm831x_power-wm831x, WM831X_POWER_STATE,
 + WM831X_USB_ILIM_MASK, best);
 +
 + return 0;
 +}
 +
  /*
   *   Battery properties
   */
 @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
 *pdev)
   }
   }
  
 + if (wm831x_pdata  wm831x_pdata-usb_gadget) {

Where the wm831x_pdata-usb_gadget is initialized?

 + power-usb_charger =
 + usb_charger_find_by_name(wm831x_pdata-usb_gadget);
 + if (IS_ERR(power-usb_charger)) {
 + ret = PTR_ERR(power-usb_charger);
 + dev_err(pdev-dev,
 + Failed to find USB gadget: %d\n, ret);
 + goto err_bat_irq;
 + }
 +
 + power-usb_notify.notifier_call = wm831x_usb_limit_change;
 +
 + ret = usb_charger_register_notify(power-usb_charger,
 +   power-usb_notify);
 + if (ret != 0) {
 + dev_err(pdev-dev,
 + Failed to register notifier: %d\n, ret);
 + goto err_usb_charger;
 + }
 + }
 +
   return ret;
  
 +err_usb_charger:
 + usb_charger_put(power-usb_charger);
  err_bat_irq:
   --i;
   for (; i = 0; i--) {
 @@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device 
 *pdev)
   struct wm831x *wm831x = wm831x_power-wm831x;
   int irq, i;
  
 + if (wm831x_power-usb_charger) {
 + usb_charger_unregister_notify(wm831x_power-usb_charger,
 +   wm831x_power-usb_notify);
 + usb_charger_put(wm831x_power-usb_charger);
 + }
 +
   for (i = 0; i  ARRAY_SIZE(wm831x_bat_irqs); i++) {
   irq = wm831x_irq(wm831x, 
platform_get_irq_byname(pdev,
 diff --git a/include/linux/mfd/wm831x/pdata.h 
 b/include/linux/mfd/wm831x/pdata.h
 index dcc9631..5af8399 100644
 --- a/include/linux/mfd/wm831x/pdata.h
 +++ b/include/linux/mfd/wm831x/pdata.h
 @@ -126,6 +126,9 @@ struct wm831x_pdata {
   /** The driver should initiate a power off sequence during shutdown */
   bool soft_shutdown;
  
 + /** dev_name of USB charger gadget to integrate with */
 + const char *usb_gadget;
 +
   int irq_base;
   int gpio_base;
   int gpio_defaults[WM831X_GPIO_NUM];
 -- 
 

Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-14 Thread Lee Jones
On Fri, 14 Aug 2015, Baolin Wang wrote:

> Integrate with the newly added USB charger interface to limit the current
> we draw from the USB input based on the input device configuration
> identified by the USB stack, allowing us to charge more quickly from high
> current inputs without drawing more current than specified from others.
> 
> Signed-off-by: Mark Brown 
> Signed-off-by: Baolin Wang 
> ---
>  drivers/power/wm831x_power.c |   69 
> ++
>  include/linux/mfd/wm831x/pdata.h |3 ++

Acked-by: Lee Jones 

>  2 files changed, 72 insertions(+)
> 
> diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
> index db11ae6..72c661f 100644
> --- a/drivers/power/wm831x_power.c
> +++ b/drivers/power/wm831x_power.c
> @@ -13,6 +13,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -31,6 +32,8 @@ struct wm831x_power {
>   char usb_name[20];
>   char battery_name[20];
>   bool have_battery;
> + struct usb_charger *usb_charger;
> + struct notifier_block usb_notify;
>  };
>  
>  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
> @@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
>   POWER_SUPPLY_PROP_VOLTAGE_NOW,
>  };
>  
> +/* In miliamps */
> +static unsigned int wm831x_usb_limits[] = {
> + 0,
> + 2,
> + 100,
> + 500,
> + 900,
> + 1500,
> + 1800,
> + 550,
> +};
> +
> +static int wm831x_usb_limit_change(struct notifier_block *nb,
> +unsigned long limit, void *data)
> +{
> + struct wm831x_power *wm831x_power = container_of(nb,
> +  struct wm831x_power,
> +  usb_notify);
> + int i, best;
> +
> + /* Find the highest supported limit */
> + best = 0;
> + for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
> + if (limit < wm831x_usb_limits[i] &&
> + wm831x_usb_limits[best] < wm831x_usb_limits[i])
> + best = i;
> + }
> +
> + dev_dbg(wm831x_power->wm831x->dev,
> + "Limiting USB current to %dmA", wm831x_usb_limits[best]);
> +
> + wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
> + WM831X_USB_ILIM_MASK, best);
> +
> + return 0;
> +}
> +
>  /*
>   *   Battery properties
>   */
> @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
> *pdev)
>   }
>   }
>  
> + if (wm831x_pdata && wm831x_pdata->usb_gadget) {
> + power->usb_charger =
> + usb_charger_find_by_name(wm831x_pdata->usb_gadget);
> + if (IS_ERR(power->usb_charger)) {
> + ret = PTR_ERR(power->usb_charger);
> + dev_err(>dev,
> + "Failed to find USB gadget: %d\n", ret);
> + goto err_bat_irq;
> + }
> +
> + power->usb_notify.notifier_call = wm831x_usb_limit_change;
> +
> + ret = usb_charger_register_notify(power->usb_charger,
> +   >usb_notify);
> + if (ret != 0) {
> + dev_err(>dev,
> + "Failed to register notifier: %d\n", ret);
> + goto err_usb_charger;
> + }
> + }
> +
>   return ret;
>  
> +err_usb_charger:
> + usb_charger_put(power->usb_charger);
>  err_bat_irq:
>   --i;
>   for (; i >= 0; i--) {
> @@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device 
> *pdev)
>   struct wm831x *wm831x = wm831x_power->wm831x;
>   int irq, i;
>  
> + if (wm831x_power->usb_charger) {
> + usb_charger_unregister_notify(wm831x_power->usb_charger,
> +   _power->usb_notify);
> + usb_charger_put(wm831x_power->usb_charger);
> + }
> +
>   for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
>   irq = wm831x_irq(wm831x, 
>platform_get_irq_byname(pdev,
> diff --git a/include/linux/mfd/wm831x/pdata.h 
> b/include/linux/mfd/wm831x/pdata.h
> index dcc9631..5af8399 100644
> --- a/include/linux/mfd/wm831x/pdata.h
> +++ b/include/linux/mfd/wm831x/pdata.h
> @@ -126,6 +126,9 @@ struct wm831x_pdata {
>   /** The driver should initiate a power off sequence during shutdown */
>   bool soft_shutdown;
>  
> + /** dev_name of USB charger gadget to integrate with */
> + const char *usb_gadget;
> +
>   int irq_base;
>   int gpio_base;
>   int gpio_defaults[WM831X_GPIO_NUM];

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs

[PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-14 Thread Baolin Wang
Integrate with the newly added USB charger interface to limit the current
we draw from the USB input based on the input device configuration
identified by the USB stack, allowing us to charge more quickly from high
current inputs without drawing more current than specified from others.

Signed-off-by: Mark Brown 
Signed-off-by: Baolin Wang 
---
 drivers/power/wm831x_power.c |   69 ++
 include/linux/mfd/wm831x/pdata.h |3 ++
 2 files changed, 72 insertions(+)

diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index db11ae6..72c661f 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+   struct usb_charger *usb_charger;
+   struct notifier_block usb_notify;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
+/* In miliamps */
+static unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit < wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %dmA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+
 /*
  * Battery properties
  */
@@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
 
+   if (wm831x_pdata && wm831x_pdata->usb_gadget) {
+   power->usb_charger =
+   usb_charger_find_by_name(wm831x_pdata->usb_gadget);
+   if (IS_ERR(power->usb_charger)) {
+   ret = PTR_ERR(power->usb_charger);
+   dev_err(>dev,
+   "Failed to find USB gadget: %d\n", ret);
+   goto err_bat_irq;
+   }
+
+   power->usb_notify.notifier_call = wm831x_usb_limit_change;
+
+   ret = usb_charger_register_notify(power->usb_charger,
+ >usb_notify);
+   if (ret != 0) {
+   dev_err(>dev,
+   "Failed to register notifier: %d\n", ret);
+   goto err_usb_charger;
+   }
+   }
+
return ret;
 
+err_usb_charger:
+   usb_charger_put(power->usb_charger);
 err_bat_irq:
--i;
for (; i >= 0; i--) {
@@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device 
*pdev)
struct wm831x *wm831x = wm831x_power->wm831x;
int irq, i;
 
+   if (wm831x_power->usb_charger) {
+   usb_charger_unregister_notify(wm831x_power->usb_charger,
+ _power->usb_notify);
+   usb_charger_put(wm831x_power->usb_charger);
+   }
+
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x, 
 platform_get_irq_byname(pdev,
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
index dcc9631..5af8399 100644
--- a/include/linux/mfd/wm831x/pdata.h
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -126,6 +126,9 @@ struct wm831x_pdata {
/** The driver should initiate a power off sequence during shutdown */
bool soft_shutdown;
 
+   /** dev_name of USB charger gadget to integrate with */
+   const char *usb_gadget;
+
int irq_base;
int gpio_base;
int gpio_defaults[WM831X_GPIO_NUM];
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-14 Thread Lee Jones
On Fri, 14 Aug 2015, Baolin Wang wrote:

 Integrate with the newly added USB charger interface to limit the current
 we draw from the USB input based on the input device configuration
 identified by the USB stack, allowing us to charge more quickly from high
 current inputs without drawing more current than specified from others.
 
 Signed-off-by: Mark Brown broo...@kernel.org
 Signed-off-by: Baolin Wang baolin.w...@linaro.org
 ---
  drivers/power/wm831x_power.c |   69 
 ++
  include/linux/mfd/wm831x/pdata.h |3 ++

Acked-by: Lee Jones lee.jo...@linaro.org

  2 files changed, 72 insertions(+)
 
 diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
 index db11ae6..72c661f 100644
 --- a/drivers/power/wm831x_power.c
 +++ b/drivers/power/wm831x_power.c
 @@ -13,6 +13,7 @@
  #include linux/platform_device.h
  #include linux/power_supply.h
  #include linux/slab.h
 +#include linux/usb/usb_charger.h
  
  #include linux/mfd/wm831x/core.h
  #include linux/mfd/wm831x/auxadc.h
 @@ -31,6 +32,8 @@ struct wm831x_power {
   char usb_name[20];
   char battery_name[20];
   bool have_battery;
 + struct usb_charger *usb_charger;
 + struct notifier_block usb_notify;
  };
  
  static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
 @@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
   POWER_SUPPLY_PROP_VOLTAGE_NOW,
  };
  
 +/* In miliamps */
 +static unsigned int wm831x_usb_limits[] = {
 + 0,
 + 2,
 + 100,
 + 500,
 + 900,
 + 1500,
 + 1800,
 + 550,
 +};
 +
 +static int wm831x_usb_limit_change(struct notifier_block *nb,
 +unsigned long limit, void *data)
 +{
 + struct wm831x_power *wm831x_power = container_of(nb,
 +  struct wm831x_power,
 +  usb_notify);
 + int i, best;
 +
 + /* Find the highest supported limit */
 + best = 0;
 + for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
 + if (limit  wm831x_usb_limits[i] 
 + wm831x_usb_limits[best]  wm831x_usb_limits[i])
 + best = i;
 + }
 +
 + dev_dbg(wm831x_power-wm831x-dev,
 + Limiting USB current to %dmA, wm831x_usb_limits[best]);
 +
 + wm831x_set_bits(wm831x_power-wm831x, WM831X_POWER_STATE,
 + WM831X_USB_ILIM_MASK, best);
 +
 + return 0;
 +}
 +
  /*
   *   Battery properties
   */
 @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device 
 *pdev)
   }
   }
  
 + if (wm831x_pdata  wm831x_pdata-usb_gadget) {
 + power-usb_charger =
 + usb_charger_find_by_name(wm831x_pdata-usb_gadget);
 + if (IS_ERR(power-usb_charger)) {
 + ret = PTR_ERR(power-usb_charger);
 + dev_err(pdev-dev,
 + Failed to find USB gadget: %d\n, ret);
 + goto err_bat_irq;
 + }
 +
 + power-usb_notify.notifier_call = wm831x_usb_limit_change;
 +
 + ret = usb_charger_register_notify(power-usb_charger,
 +   power-usb_notify);
 + if (ret != 0) {
 + dev_err(pdev-dev,
 + Failed to register notifier: %d\n, ret);
 + goto err_usb_charger;
 + }
 + }
 +
   return ret;
  
 +err_usb_charger:
 + usb_charger_put(power-usb_charger);
  err_bat_irq:
   --i;
   for (; i = 0; i--) {
 @@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device 
 *pdev)
   struct wm831x *wm831x = wm831x_power-wm831x;
   int irq, i;
  
 + if (wm831x_power-usb_charger) {
 + usb_charger_unregister_notify(wm831x_power-usb_charger,
 +   wm831x_power-usb_notify);
 + usb_charger_put(wm831x_power-usb_charger);
 + }
 +
   for (i = 0; i  ARRAY_SIZE(wm831x_bat_irqs); i++) {
   irq = wm831x_irq(wm831x, 
platform_get_irq_byname(pdev,
 diff --git a/include/linux/mfd/wm831x/pdata.h 
 b/include/linux/mfd/wm831x/pdata.h
 index dcc9631..5af8399 100644
 --- a/include/linux/mfd/wm831x/pdata.h
 +++ b/include/linux/mfd/wm831x/pdata.h
 @@ -126,6 +126,9 @@ struct wm831x_pdata {
   /** The driver should initiate a power off sequence during shutdown */
   bool soft_shutdown;
  
 + /** dev_name of USB charger gadget to integrate with */
 + const char *usb_gadget;
 +
   int irq_base;
   int gpio_base;
   int gpio_defaults[WM831X_GPIO_NUM];

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ 

[PATCH v2 3/3] power: wm831x_power: Support USB charger current limit management

2015-08-14 Thread Baolin Wang
Integrate with the newly added USB charger interface to limit the current
we draw from the USB input based on the input device configuration
identified by the USB stack, allowing us to charge more quickly from high
current inputs without drawing more current than specified from others.

Signed-off-by: Mark Brown broo...@kernel.org
Signed-off-by: Baolin Wang baolin.w...@linaro.org
---
 drivers/power/wm831x_power.c |   69 ++
 include/linux/mfd/wm831x/pdata.h |3 ++
 2 files changed, 72 insertions(+)

diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index db11ae6..72c661f 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -13,6 +13,7 @@
 #include linux/platform_device.h
 #include linux/power_supply.h
 #include linux/slab.h
+#include linux/usb/usb_charger.h
 
 #include linux/mfd/wm831x/core.h
 #include linux/mfd/wm831x/auxadc.h
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+   struct usb_charger *usb_charger;
+   struct notifier_block usb_notify;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
+/* In miliamps */
+static unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i  ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit  wm831x_usb_limits[i] 
+   wm831x_usb_limits[best]  wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power-wm831x-dev,
+   Limiting USB current to %dmA, wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power-wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+
 /*
  * Battery properties
  */
@@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
 
+   if (wm831x_pdata  wm831x_pdata-usb_gadget) {
+   power-usb_charger =
+   usb_charger_find_by_name(wm831x_pdata-usb_gadget);
+   if (IS_ERR(power-usb_charger)) {
+   ret = PTR_ERR(power-usb_charger);
+   dev_err(pdev-dev,
+   Failed to find USB gadget: %d\n, ret);
+   goto err_bat_irq;
+   }
+
+   power-usb_notify.notifier_call = wm831x_usb_limit_change;
+
+   ret = usb_charger_register_notify(power-usb_charger,
+ power-usb_notify);
+   if (ret != 0) {
+   dev_err(pdev-dev,
+   Failed to register notifier: %d\n, ret);
+   goto err_usb_charger;
+   }
+   }
+
return ret;
 
+err_usb_charger:
+   usb_charger_put(power-usb_charger);
 err_bat_irq:
--i;
for (; i = 0; i--) {
@@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device 
*pdev)
struct wm831x *wm831x = wm831x_power-wm831x;
int irq, i;
 
+   if (wm831x_power-usb_charger) {
+   usb_charger_unregister_notify(wm831x_power-usb_charger,
+ wm831x_power-usb_notify);
+   usb_charger_put(wm831x_power-usb_charger);
+   }
+
for (i = 0; i  ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x, 
 platform_get_irq_byname(pdev,
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
index dcc9631..5af8399 100644
--- a/include/linux/mfd/wm831x/pdata.h
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -126,6 +126,9 @@ struct wm831x_pdata {
/** The driver should initiate a power off sequence during shutdown */
bool soft_shutdown;
 
+   /** dev_name of USB charger gadget to integrate with */
+   const char *usb_gadget;
+
int irq_base;
int gpio_base;
int gpio_defaults[WM831X_GPIO_NUM];
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo