[linux-sunxi] Re: [PATCH v4 1/4] power: Add an axp20x-ac-power driver

2016-05-14 Thread Michael Haas
On 05/09/2016 06:33 PM, Chen-Yu Tsai wrote:

>> +
>> +   power->supply = devm_power_supply_register(&pdev->dev,
>> +   &axp20x_ac_power_desc, &psy_cfg);
>> +   if (IS_ERR(power->supply))
>> +   return PTR_ERR(power->supply);
>> +
>> +   /* Request irqs after registering, as irqs may trigger immediately */
>> +   for (i = 0; i < ARRAY_SIZE(irq_names); i++) {
>> +   irq = platform_get_irq_byname(pdev, irq_names[i]);
>> +   if (irq < 0) {
>> +   dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
>> +irq_names[i], irq);
>> +   continue;
>> +   }
>> +   irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq);
>> +   r = devm_request_any_context_irq(&pdev->dev, irq,
>> +   axp20x_irq_ac_handler, 0, DRVNAME, power);
>> +   if (r < 0)
>> +   dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n",
>> +irq_names[i], r);
> 
> Won't missing IRQs hinder the usage of this driver / hardware?
> A power supply isn't much use if the system isn't told when
> it's gone.
> 

That's a good point. The real question is: how would you handle missing
IRQs? I have looked at other uses of devm_request_any_context_irq, e.g.
in rtc-pm8xxx.c [0]. These other users often return an error code in the
probe function. That doesn't help the system, though: it still won't
notice if the power is unplugged in addition to missing the driver
completely.

It's probably best to provide the remaining (functional) parts of the
driver (reading from /sys/class..) even if the IRQs cannot be
registered. The code is pretty much the same in  the axp20x-usb-power.

Michael

[0] http://lxr.free-electrons.com/source/drivers/rtc/rtc-pm8xxx.c#L490

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] Re: [PATCH v4 1/4] power: Add an axp20x-ac-power driver

2016-05-09 Thread Chen-Yu Tsai
On Fri, May 6, 2016 at 1:19 PM, Michael Haas  wrote:
> This adds a driver for the ac power_supply bits of the axp20x
> PMICs.
>
> This submission is taken directly from Bruno Prémonts 2015 RFC [0].
> The original RFC contains drivers for AC, battery and backup
> battery. This commit only adds the AC driver for now.
>
> [0] http://permalink.gmane.org/gmane.comp.hardware.netbook.arm.sunxi/17980
>
> Signed-off-by: Michael Haas 
> ---
>  drivers/power/Makefile  |   2 +-
>  drivers/power/axp20x_ac_power.c | 181 
> 
>  2 files changed, 182 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/power/axp20x_ac_power.c
>
> diff --git a/drivers/power/Makefile b/drivers/power/Makefile
> index e46b75d..3a785cc 100644
> --- a/drivers/power/Makefile
> +++ b/drivers/power/Makefile
> @@ -9,7 +9,7 @@ obj-$(CONFIG_GENERIC_ADC_BATTERY)   += 
> generic-adc-battery.o
>
>  obj-$(CONFIG_PDA_POWER)+= pda_power.o
>  obj-$(CONFIG_APM_POWER)+= apm_power.o
> -obj-$(CONFIG_AXP20X_POWER) += axp20x_usb_power.o
> +obj-$(CONFIG_AXP20X_POWER) += axp20x_usb_power.o axp20x_ac_power.o

Sort the file names please.

>  obj-$(CONFIG_MAX8925_POWER)+= max8925_power.o
>  obj-$(CONFIG_WM831X_BACKUP)+= wm831x_backup.o
>  obj-$(CONFIG_WM831X_POWER) += wm831x_power.o
> diff --git a/drivers/power/axp20x_ac_power.c b/drivers/power/axp20x_ac_power.c
> new file mode 100644
> index 000..0d1ca0e
> --- /dev/null
> +++ b/drivers/power/axp20x_ac_power.c
> @@ -0,0 +1,181 @@
> +/*
> + * AXP20x PMIC AC power driver
> + *
> + * Copyright 2014-2015 Bruno Prémont 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under  the terms of the GNU General  Public License as published by the
> + * Free Software Foundation;  either version 2 of the License, or (at your
> + * option) any later version.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define DRVNAME "axp20x-ac-power"
> +
> +
> +/* Fields of AXP20X_PWR_INPUT_STATUS */
> +#define AXP20X_PWR_STATUS_AC_PRESENT BIT(7)
> +#define AXP20X_PWR_STATUS_AC_AVAILABLE   BIT(6)

> +#define AXP20X_PWR_STATUS_AC_VBUS_SHORT  BIT(1)
> +#define AXP20X_PWR_STATUS_AC_VBUS_SELBIT(0)

These 2 aren't used anymore. Please remove them.

> +
> +/* Fields of AXP20X_ADC_EN1 */
> +#define AXP20X_ADC_EN1_ACIN_VOLT BIT(5)
> +#define AXP20X_ADC_EN1_ACIN_CURR BIT(4)
> +
> +
> +struct axp20x_ac_power {
> +   struct regmap *regmap;
> +   struct power_supply *supply;
> +};
> +
> +static int axp20x_ac_power_get_property(struct power_supply *psy,
> +   enum power_supply_property psp,
> +   union power_supply_propval *val)
> +{
> +   struct axp20x_ac_power *power = power_supply_get_drvdata(psy);
> +   unsigned int input;
> +   int r;
> +
> +   switch (psp) {
> +   case POWER_SUPPLY_PROP_VOLTAGE_NOW:
> +   r = axp20x_read_variable_width(power->regmap,
> +  AXP20X_ACIN_V_ADC_H, 12);
> +   if (r < 0)
> +   return r;
> +
> +   val->intval = r * 1700; /* 1 step = 1.7 mV */
> +   return 0;
> +   case POWER_SUPPLY_PROP_CURRENT_NOW:
> +   r = axp20x_read_variable_width(power->regmap,
> +  AXP20X_ACIN_I_ADC_H, 12);
> +   if (r < 0)
> +   return r;
> +
> +   val->intval = r * 375; /* 1 step = 0.375 mA */

The step for ACIN is 0.625 mA. 0.375 is for VBUS.

> +   return 0;
> +   default:
> +   break;
> +   }
> +
> +   /* All the properties below need the input-status reg value */
> +   r = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &input);
> +   if (r)
> +   return r;
> +
> +   switch (psp) {
> +   case POWER_SUPPLY_PROP_PRESENT:
> +   val->intval = !!(input & AXP20X_PWR_STATUS_AC_PRESENT);
> +   break;
> +   case POWER_SUPPLY_PROP_ONLINE:
> +   val->intval = !!(input & AXP20X_PWR_STATUS_AC_AVAILABLE);
> +   break;
> +   default:
> +   return -EINVAL;
> +   }
> +
> +   return 0;
> +}
> +
> +static enum power_supply_property axp20x_ac_power_properties[] = {
> +   POWER_SUPPLY_PROP_PRESENT,
> +   POWER_SUPPLY_PROP_ONLINE,
> +   POWER_SUPPLY_PROP_VOLTAGE_NOW,
> +   POWER_SUPPLY_PROP_CURRENT_NOW,
> +};
> +
> +static const struct power_supply_desc axp20x_ac_power_desc = {
> +   .name = "axp20x-ac",
> +   .type = POWER_SUPPLY_TYPE_MAINS,
> +   .properties = axp20x_ac_power_properties,
> +   .num_properties = ARRAY_SIZE(axp20x_ac_power_properties),
> +   .get_property = axp20x_ac_power_get_property,
> +};
> +
> +static ir