From: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
To: Michael Haas <haas-bdq14YP6qtSV9CzYT+GlPGD2FQJk+8+b@public.gmane.org>
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
pawel.moll-5wv7dgnIgG8@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org,
galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
wens-jdAy2FN1RRM@public.gmane.org,
lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
bonbons-ud5FBsm0p/xEiooADzr8i9i2O/JbrIOy@public.gmane.org,
hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
Subject: Re: [PATCH 1/4] power: Add an axp20x-ac-power driver
Date: Mon, 4 Apr 2016 14:38:51 -0700 [thread overview]
Message-ID: <20160404213851.GQ4227@lukather> (raw)
In-Reply-To: <1459689307-8501-1-git-send-email-haas-bdq14YP6qtSV9CzYT+GlPGD2FQJk+8+b@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 10993 bytes --]
Hi,
On Sun, Apr 03, 2016 at 03:15:04PM +0200, 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.
>
> My only change to Bruno's axp20x_ac_power.c is the additional
> check on a possible short-circuit between ACIN and VBUS. In this
> case, axp20x-ac-power-supply refuses to attach itself to the device
> and axp20x-usb-power-supply must be used.
>
> [0] http://permalink.gmane.org/gmane.comp.hardware.netbook.arm.sunxi/17980
>
> Signed-off-by: Michael Haas <haas-bdq14YP6qtSV9CzYT+GlPGD2FQJk+8+b@public.gmane.org>
> ---
> drivers/mfd/axp20x.c | 11 +++
> drivers/power/Makefile | 2 +-
> drivers/power/axp20x_ac_power.c | 212 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 224 insertions(+), 1 deletion(-)
> create mode 100644 drivers/power/axp20x_ac_power.c
>
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index a57d6e9..9351c0e 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -178,6 +178,12 @@ static struct resource axp288_power_button_resources[] = {
> },
> };
>
> +static struct resource axp20x_ac_power_supply_resources[] = {
> + DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
> + DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
> + DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
> +};
> +
> static struct resource axp288_fuel_gauge_resources[] = {
> {
> .start = AXP288_IRQ_QWBTU,
> @@ -440,6 +446,11 @@ static struct mfd_cell axp20x_cells[] = {
> .of_compatible = "x-powers,axp202-usb-power-supply",
> .num_resources = ARRAY_SIZE(axp20x_usb_power_supply_resources),
> .resources = axp20x_usb_power_supply_resources,
> + }, {
> + .name = "axp20x-ac-power-supply",
> + .of_compatible = "x-powers,axp202-ac-power-supply",
> + .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources),
> + .resources = axp20x_ac_power_supply_resources,
> },
> };
>
These changes should be in a separate patch.
> 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
> 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 0000000..c5bcbeb
> --- /dev/null
> +++ b/drivers/power/axp20x_ac_power.c
> @@ -0,0 +1,212 @@
> +/*
> + * AXP20x PMIC AC power driver
> + *
> + * Copyright 2014-2015 Bruno Prémont <bonbons-ud5FBsm0p/xEiooADzr8i9i2O/JbrIOy@public.gmane.org>
> + *
> + * 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 <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/mfd/axp20x.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/power_supply.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +#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_SEL BIT(0)
> +
> +/* Fields of AXP20X_ADC_EN1 */
> +#define AXP20X_ADC_EN1_ACIN_VOLT BIT(5)
> +#define AXP20X_ADC_EN1_ACIN_CURR BIT(4)
That should probably be defined in the global header, next to the
registers.
> +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)
The alignment is supposed to be on the opening parentheses
> +{
> + 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 */
> + 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 irqreturn_t axp20x_irq_ac_over_v(int irq, void *devid)
> +{
> + struct axp20x_ac_power *power = devid;
> +
> + dev_warn(&power->supply->dev, "IRQ#%d AC over voltage\n", irq);
> + power_supply_changed(power->supply);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t axp20x_irq_ac_plugin(int irq, void *devid)
> +{
> + struct axp20x_ac_power *power = devid;
> +
> + dev_info(&power->supply->dev, "IRQ#%d AC connected\n", irq);
> + power_supply_changed(power->supply);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t axp20x_irq_ac_removal(int irq, void *devid)
> +{
> + struct axp20x_ac_power *power = devid;
> +
> + dev_info(&power->supply->dev, "IRQ#%d AC disconnected\n", irq);
> + power_supply_changed(power->supply);
> +
> + return IRQ_HANDLED;
> +}
Logging in the interrupt handler is usually a bad idea, for several
reasons:
- If you have a console, it's going to be output on the console,
which might take quite some time. And you don't want to take
quite some time in the interrupt handler.
- printk might not even work in the interrupt context in some
scenarios.
Removing that handler, you can register the same interrupt handler on
all the interrupts.
> +static int axp20x_ac_power_probe(struct platform_device *pdev)
> +{
> + struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> + struct power_supply_config psy_cfg = {};
> + struct axp20x_ac_power *power;
> + static const char * const irq_names[] = { "ACIN_PLUGIN",
> + "ACIN_REMOVAL", "ACIN_OVER_V" };
> + irqreturn_t (*irq_funcs[])(int, void *) = { axp20x_irq_ac_plugin,
> + axp20x_irq_ac_removal, axp20x_irq_ac_over_v };
> + int i, irq, r, input;
> +
> + if (!of_device_is_available(pdev->dev.of_node))
> + return -ENODEV;
That's useless. If the device is not available, you're not going to be
probed in the first place.
> + power = devm_kzalloc(&pdev->dev, sizeof(*power), GFP_KERNEL);
> + if (!power)
> + return -ENOMEM;
> +
> + power->regmap = axp20x->regmap;
> +
> + r = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &input);
> + if (r < 0)
> + return r;
> +
> + if (!!(input & AXP20X_PWR_STATUS_AC_VBUS_SHORT)) {
> + dev_err(&pdev->dev, "AC is connected to VBUS. Use axp20x_usb_power-supply driver instead!");
> + return -ENODEV;
> + }
Can't that change over time? Can't we support both drivers at the same time?
> + /* Enable ac voltage and current measurement */
> + r = regmap_update_bits(power->regmap, AXP20X_ADC_EN1,
> + AXP20X_ADC_EN1_ACIN_CURR | AXP20X_ADC_EN1_ACIN_VOLT,
> + AXP20X_ADC_EN1_ACIN_CURR | AXP20X_ADC_EN1_ACIN_VOLT);
> + if (r)
> + return r;
> +
> + psy_cfg.of_node = pdev->dev.of_node;
> + psy_cfg.drv_data = power;
> +
> + 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,
> + irq_funcs[i], 0, DRVNAME, power);
> + if (r < 0)
> + dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n",
> + irq_names[i], r);
> + }
> +
> + return 0;
> +}
> +
> +static const struct of_device_id axp20x_ac_power_match[] = {
> + { .compatible = "x-powers,axp202-ac-power-supply" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, axp20x_ac_power_match);
> +
> +static struct platform_driver axp20x_ac_power_driver = {
> + .probe = axp20x_ac_power_probe,
> + .driver = {
> + .name = DRVNAME,
> + .of_match_table = axp20x_ac_power_match,
> + },
> +};
> +
> +module_platform_driver(axp20x_ac_power_driver);
> +
> +MODULE_AUTHOR("Bruno Prémont <bonbons-ud5FBsm0p/xEiooADzr8i9i2O/JbrIOy@public.gmane.org>");
> +MODULE_DESCRIPTION("AXP20x PMIC AC power supply status driver");
> +MODULE_LICENSE("GPL");
> --
> 2.8.0
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
--
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+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
next prev parent reply other threads:[~2016-04-04 21:38 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-03 13:15 [PATCH 1/4] power: Add an axp20x-ac-power driver Michael Haas
[not found] ` <1459689307-8501-1-git-send-email-haas-bdq14YP6qtSV9CzYT+GlPGD2FQJk+8+b@public.gmane.org>
2016-04-03 13:15 ` [PATCH 2/4] ARM: dts: axp209: Add ac_power_supply child node to the ax209 node Michael Haas
2016-04-03 13:15 ` [PATCH 3/4] ARM: dts: Add binding documentation for AXP20x pmic ac power supply Michael Haas
[not found] ` <1459689307-8501-3-git-send-email-haas-bdq14YP6qtSV9CzYT+GlPGD2FQJk+8+b@public.gmane.org>
2016-04-07 17:57 ` Rob Herring
2016-04-03 13:15 ` [PATCH 4/4] ARM: dts: sunxi: add ac-power to A20 OLinuXino Lime2 board Michael Haas
2016-04-04 21:38 ` Maxime Ripard [this message]
2016-04-05 5:11 ` [PATCH 1/4] power: Add an axp20x-ac-power driver Michael Haas
[not found] ` <570348E6.5060107-bdq14YP6qtSV9CzYT+GlPGD2FQJk+8+b@public.gmane.org>
2016-04-05 6:05 ` Chen-Yu Tsai
[not found] ` <CAGb2v66fsdSMCULLtuFC=YEkdOOQRLh2knjjFvatbJhaKu9KWg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-04-06 6:26 ` Michael Haas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160404213851.GQ4227@lukather \
--to=maxime.ripard-wi1+55scjutkeb57/3fjtnbpr1lh4cv8@public.gmane.org \
--cc=bonbons-ud5FBsm0p/xEiooADzr8i9i2O/JbrIOy@public.gmane.org \
--cc=dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org \
--cc=galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
--cc=haas-bdq14YP6qtSV9CzYT+GlPGD2FQJk+8+b@public.gmane.org \
--cc=hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org \
--cc=lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
--cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
--cc=pawel.moll-5wv7dgnIgG8@public.gmane.org \
--cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=sre-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=wens-jdAy2FN1RRM@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.