Message ID | 20200113103515.20879-15-patrick.delaunay@st.com |
---|---|
State | Accepted |
Commit | d2c07e56ab3ef0cec99335aa8dafbed691d23739 |
Headers | show |
Series | dm: add support of new binding in gpio and pincontrol | expand |
On Mon, 13 Jan 2020 at 03:35, Patrick Delaunay <patrick.delaunay at st.com> wrote: > > Add the ops for GPIO driver get_dir_flags(), allows to get dynamically > the current gpio configuration; it is used by the API function > dm_gpio_get_dir_flags(). > > When these optional ops are absent, the gpio uclass continues to use > the mandatory ops (direction_output, direction_input, get_value) and > value of desc->flags to manage only the main dir flags: > - GPIOD_IS_IN > - GPIOD_IS_OUT > - GPIOD_IS_OUT_ACTIVE > - GPIOD_ACTIVE_LOW > > Signed-off-by: Patrick Delaunay <patrick.delaunay at st.com> > --- > > This patch was part of v2 08/14 > = gpio: add ops for configuration with dir flags > > > Changes in v3: > - Split the previous patch [PATCH v2 08/14] to help review > > Changes in v2: > - change the proposed ops for pin config to set_dir_flags/get_dir_flags > - reused the existing API dm_gpio_set_dir_flags/dm_gpio_set_dir > - add a new API dm_gpio_get_dir_flags > > drivers/gpio/gpio-uclass.c | 31 +++++++++++++++++++++++++------ > include/asm-generic/gpio.h | 15 +++++++++++++++ > 2 files changed, 40 insertions(+), 6 deletions(-) Reviewed-by: Simon Glass <sjg at chromium.org> But please see below > diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h > index 4f7b43f163..ac30c3ee4e 100644 > --- a/include/asm-generic/gpio.h > +++ b/include/asm-generic/gpio.h > @@ -297,6 +297,21 @@ struct dm_gpio_ops { > */ > int (*xlate)(struct udevice *dev, struct gpio_desc *desc, > struct ofnode_phandle_args *args); > + > + /** > + * get_dir_flags() - Get GPIO dir flags > + * > + * This function return the GPIO direction flags used. returns used by what? This is too vague. > + * > + * This method is optional. Please expand this (perhaps in a follow-up patch) to explain what happens when not implemented. > + * > + * @dev: GPIO device > + * @offset: GPIO offset within that device > + * @flags: place to put the used direction flags by GPIO > + * @return 0 if OK, -ve on error > + */ > + int (*get_dir_flags)(struct udevice *dev, unsigned int offset, > + ulong *flags); > }; > > /** > -- > 2.17.1 >
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index e02ef29fed..89af37a4ea 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -613,19 +613,36 @@ int dm_gpio_set_dir(struct gpio_desc *desc) int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags) { - int ret; + struct udevice *dev = desc->dev; + int ret, value; + struct dm_gpio_ops *ops = gpio_get_ops(dev); ulong dir_flags; ret = check_reserved(desc, "get_dir_flags"); if (ret) return ret; - dir_flags = desc->flags; - /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */ - dir_flags &= ~GPIOD_IS_OUT_ACTIVE; - if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc)) - dir_flags |= GPIOD_IS_OUT_ACTIVE; + /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */ + if (ops->get_dir_flags) { + ret = ops->get_dir_flags(dev, desc->offset, &dir_flags); + if (ret) + return ret; + /* GPIOD_ACTIVE_LOW is saved in desc->flags */ + value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0; + if (desc->flags & GPIOD_ACTIVE_LOW) + value = !value; + dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE); + dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW); + if (value) + dir_flags |= GPIOD_IS_OUT_ACTIVE; + } else { + dir_flags = desc->flags; + /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */ + dir_flags &= ~GPIOD_IS_OUT_ACTIVE; + if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc)) + dir_flags |= GPIOD_IS_OUT_ACTIVE; + } *flags = dir_flags; return 0; @@ -1128,6 +1145,8 @@ static int gpio_post_bind(struct udevice *dev) ops->get_function += gd->reloc_off; if (ops->xlate) ops->xlate += gd->reloc_off; + if (ops->get_dir_flags) + ops->get_dir_flags += gd->reloc_off; reloc_done++; } diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 4f7b43f163..ac30c3ee4e 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -297,6 +297,21 @@ struct dm_gpio_ops { */ int (*xlate)(struct udevice *dev, struct gpio_desc *desc, struct ofnode_phandle_args *args); + + /** + * get_dir_flags() - Get GPIO dir flags + * + * This function return the GPIO direction flags used. + * + * This method is optional. + * + * @dev: GPIO device + * @offset: GPIO offset within that device + * @flags: place to put the used direction flags by GPIO + * @return 0 if OK, -ve on error + */ + int (*get_dir_flags)(struct udevice *dev, unsigned int offset, + ulong *flags); }; /**
Add the ops for GPIO driver get_dir_flags(), allows to get dynamically the current gpio configuration; it is used by the API function dm_gpio_get_dir_flags(). When these optional ops are absent, the gpio uclass continues to use the mandatory ops (direction_output, direction_input, get_value) and value of desc->flags to manage only the main dir flags: - GPIOD_IS_IN - GPIOD_IS_OUT - GPIOD_IS_OUT_ACTIVE - GPIOD_ACTIVE_LOW Signed-off-by: Patrick Delaunay <patrick.delaunay at st.com> --- This patch was part of v2 08/14 = gpio: add ops for configuration with dir flags Changes in v3: - Split the previous patch [PATCH v2 08/14] to help review Changes in v2: - change the proposed ops for pin config to set_dir_flags/get_dir_flags - reused the existing API dm_gpio_set_dir_flags/dm_gpio_set_dir - add a new API dm_gpio_get_dir_flags drivers/gpio/gpio-uclass.c | 31 +++++++++++++++++++++++++------ include/asm-generic/gpio.h | 15 +++++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-)