[U-Boot] [PATCH 11/21] sunxi: gpio: Add support for AXP gpios to the dm gpio code

Simon Glass sjg at chromium.org
Sat Apr 25 01:24:21 CEST 2015


Hi Hans,

On 24 April 2015 at 07:48, Hans de Goede <hdegoede at redhat.com> wrote:
> This really should be part of the axp pmic driver, but that is not converted
> yet to device-model, and the upstream kernel does not support axp gpios
> yet so there is no devicetree binding for them yet.
>
> So for now bolt on the axp gpio support to the SoC's own gpio support like
> we've been doing for the non dm case. This allows boards using axp gpios
> to be converted to dm.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>  arch/arm/include/asm/arch-sunxi/gpio.h |  6 ++--
>  drivers/gpio/sunxi_gpio.c              | 64 +++++++++++++++++++++++++++++-----
>  2 files changed, 60 insertions(+), 10 deletions(-)

This doesn't seem like a good idea. The device tree binding is just an
I2C one isn't it? Is the real problem that you are trying to convert
to driver model without converting to device tree? For I2C at least,
that is not supported.

>
> diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
> index c9bfb4c..cbb3328 100644
> --- a/arch/arm/include/asm/arch-sunxi/gpio.h
> +++ b/arch/arm/include/asm/arch-sunxi/gpio.h
> @@ -204,8 +204,10 @@ enum sunxi_gpio_number {
>  #define SUNXI_GPIO_PULL_DOWN   2
>
>  /* Virtual AXP0 GPIOs */
> -#define SUNXI_GPIO_AXP0_VBUS_DETECT    8
> -#define SUNXI_GPIO_AXP0_VBUS_ENABLE    9
> +#define SUNXI_GPIO_AXP0_PREFIX "AXP0-"
> +#define SUNXI_GPIO_AXP0_VBUS_DETECT    4
> +#define SUNXI_GPIO_AXP0_VBUS_ENABLE    5
> +#define SUNXI_GPIO_AXP0_GPIO_COUNT     6
>
>  void sunxi_gpio_set_cfgbank(struct sunxi_gpio *pio, int bank_offset, u32 val);
>  void sunxi_gpio_set_cfgpin(u32 pin, u32 val);
> diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
> index 0774b70..38d72b7 100644
> --- a/drivers/gpio/sunxi_gpio.c
> +++ b/drivers/gpio/sunxi_gpio.c
> @@ -126,7 +126,7 @@ int sunxi_name_to_gpio(const char *name)
>         char *eptr;
>
>  #ifdef AXP_GPIO
> -       if (strncasecmp(name, "AXP0-", 5) == 0) {
> +       if (strncasecmp(name, SUNXI_GPIO_AXP0_PREFIX, 5) == 0) {
>                 name += 5;
>                 if (strcmp(name, "VBUS-DETECT") == 0)
>                         return SUNXI_GPIO_AXP0_START +
> @@ -172,12 +172,56 @@ int sunxi_name_to_gpio_bank(const char *name)
>  }
>
>  #ifdef CONFIG_DM_GPIO
> +
> +#ifdef AXP_GPIO
> +/* FIXME this should be part of the axp drivers */
> +static const struct dm_gpio_ops gpio_axp_ops = {
> +       .direction_input        = axp_gpio_direction_input,
> +       .direction_output       = axp_gpio_direction_output,
> +       .get_value              = axp_gpio_get_value,
> +       .set_value              = axp_gpio_set_value,
> +};
> +
> +static int gpio_axp_probe(struct udevice *dev)
> +{
> +       struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> +
> +       /* Tell the uclass how many GPIOs we have */
> +       uc_priv->bank_name = strdup(SUNXI_GPIO_AXP0_PREFIX);
> +       uc_priv->gpio_count = SUNXI_GPIO_AXP0_GPIO_COUNT;
> +
> +       return 0;
> +}
> +
> +struct driver gpio_axp_driver = {
> +       .name   = "gpio_axp",
> +       .id     = UCLASS_GPIO,
> +       .ops    = &gpio_axp_ops,
> +       .probe  = gpio_axp_probe,
> +};
> +#endif
> +
>  /* TODO(sjg at chromium.org): Remove this function and use device tree */
>  int sunxi_name_to_gpio(const char *name)
>  {
>         unsigned int gpio;
>         int ret;
> -
> +#ifdef AXP_GPIO
> +       char lookup[8];
> +
> +       if (strncasecmp(name, SUNXI_GPIO_AXP0_PREFIX, 5) == 0) {
> +               int len = strlen(SUNXI_GPIO_AXP0_PREFIX);
> +               if (strcmp(name + len, "VBUS-DETECT") == 0) {
> +                       sprintf(lookup, SUNXI_GPIO_AXP0_PREFIX "%d",
> +                               SUNXI_GPIO_AXP0_VBUS_DETECT);
> +                       name = lookup;
> +               } else if (strcmp(name + len, "VBUS-ENABLE") == 0) {
> +                       sprintf(lookup, "AXP0-%d\n",
> +                               SUNXI_GPIO_AXP0_VBUS_ENABLE);
> +                       name = lookup;
> +               }
> +       }
> +#endif
>         ret = gpio_lookup_name(name, NULL, NULL, &gpio);
>
>         return ret ? ret : gpio;
> @@ -222,7 +266,7 @@ static int sunxi_gpio_set_value(struct udevice *dev, unsigned offset,
>         struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
>         u32 num = GPIO_NUM(offset);
>
> -       clrsetbits_le32(&plat->regs->dat, 1 << num, value ? (1 << num) : 0);
> +;      clrsetbits_le32(&plat->regs->dat, 1 << num, value ? (1 << num) : 0);
>         return 0;
>  }
>
> @@ -289,21 +333,19 @@ static int gpio_sunxi_probe(struct udevice *dev)
>   */
>  static int gpio_sunxi_bind(struct udevice *parent)
>  {
> -       struct sunxi_gpio_platdata *plat = parent->platdata;
> +       struct sunxi_gpio_platdata *plat;
>         struct sunxi_gpio_reg *ctlr;
> +       struct udevice *dev;
>         int bank;
>         int ret;
>
>         /* If this is a child device, there is nothing to do here */
> -       if (plat)
> +       if (parent->platdata)
>                 return 0;
>
>         ctlr = (struct sunxi_gpio_reg *)fdtdec_get_addr(gd->fdt_blob,
>                                                    parent->of_offset, "reg");
>         for (bank = 0; bank < SUNXI_GPIO_BANKS; bank++) {
> -               struct sunxi_gpio_platdata *plat;
> -               struct udevice *dev;
> -
>                 plat = calloc(1, sizeof(*plat));
>                 if (!plat)
>                         return -ENOMEM;
> @@ -318,6 +360,12 @@ static int gpio_sunxi_bind(struct udevice *parent)
>                 dev->of_offset = parent->of_offset;
>         }
>
> +#ifdef AXP_GPIO
> +       /* FIXME this should be a child of the axp device */
> +       ret = device_bind(parent, &gpio_axp_driver, "AXP", NULL, -1, &dev);
> +       if (ret)
> +               return ret;
> +#endif
>         return 0;
>  }
>
> --
> 2.3.5
>

Regards,
Simon


More information about the U-Boot mailing list