
At present the driver model GPIO API does not support pull-up/pull-down on input GPIOs. This is required in some cases.
Add this feature to the API with two new methods that drivers can optionally implement.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/gpio/gpio-uclass.c | 31 +++++++++++++++++++++++++++++++ include/asm-generic/gpio.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+)
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 4efda31..c4ba580 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -374,6 +374,37 @@ int dm_gpio_set_dir(struct gpio_desc *desc) return dm_gpio_set_dir_flags(desc, desc->flags); }
+int dm_gpio_set_pull(struct gpio_desc *desc, enum gpio_pull pull) +{ + struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); + int ret; + + ret = check_reserved(desc, "set_pull"); + if (ret) + return ret; + + if (!ops->set_pull) + return -ENOSYS; + + return ops->set_pull(desc->dev, desc->offset, pull); +} + +int dm_gpio_get_pull(struct gpio_desc *desc, unsigned offset) +{ + struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); + int ret; + + ret = check_reserved(desc, "get_pull"); + if (ret) + return ret; + + if (!ops->get_pull) + return -ENOSYS; + + return ops->get_pull(desc->dev, desc->offset); +} + + /** * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value * gpio: GPIO number diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 0af599f..db5504f 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -126,6 +126,13 @@ struct gpio_desc { */ };
+/* GPIO pull directions (used for input lines) */ +enum gpio_pull { + GPIO_PULL_NONE, + GPIO_PULL_DOWN, + GPIO_PULL_UP, +}; + /** * dm_gpio_is_valid() - Check if a GPIO is valid * @@ -276,6 +283,26 @@ struct dm_gpio_ops { */ int (*xlate)(struct udevice *dev, struct gpio_desc *desc, struct fdtdec_phandle_args *args); + + /** + * set_pull() - set pull direction + * + * @dev: Device to adjust + * @offset: GPIO offset within device + * @pull: New pull direction + * @return 0 if OK, -ve on error + */ + int (*set_pull)(struct udevice *dev, unsigned offset, + enum gpio_pull pull); + + /** + * get_pull() - get pull direction + * + * @dev: Device to check + * @offset: GPIO offset within device + * @return current pull direction or -ve on error + */ + int (*get_pull)(struct udevice *dev, unsigned offset); };
/** @@ -556,6 +583,25 @@ int dm_gpio_set_dir(struct gpio_desc *desc); int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
/** + * dm_gpio_set_pull() - set pull direction + * + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() + * @pull: New pull direction + * @return 0 if OK, -ve on error + */ +int dm_gpio_set_pull(struct gpio_desc *desc, enum gpio_pull pull); + +/** +* dm_gpio_get_pull() - get pull direction +* + * @desc: GPIO description containing device, offset and flags, + * previously returned by gpio_request_by_name() +* @return current pull direction or -ve on error +*/ +int dm_gpio_get_pull(struct gpio_desc *desc, unsigned offset); + +/** * gpio_get_number() - Get the global GPIO number of a GPIO * * This should only be used for debugging or interest. It returns the number