X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fgpio%2Fgpio-uclass.c;h=4559739d619c637d79495e349290b7ae93646de9;hb=ca75159d8abc085b39e3e468ca34ccb2940d2bf5;hp=4efda311a49e81c8470a23d88f62a09b07f0f5bc;hpb=7a1af7a79bd79ded6a78d0c1afdbc3353669e313;p=u-boot diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 4efda311a4..4559739d61 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -6,10 +6,12 @@ #include #include +#include #include #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -112,19 +114,33 @@ int gpio_lookup_name(const char *name, struct udevice **devp, return 0; } +int gpio_xlate_offs_flags(struct udevice *dev, + struct gpio_desc *desc, + struct fdtdec_phandle_args *args) +{ + if (args->args_count < 1) + return -EINVAL; + + desc->offset = args->args[0]; + + if (args->args_count < 2) + return 0; + + if (args->args[1] & GPIO_ACTIVE_LOW) + desc->flags = GPIOD_ACTIVE_LOW; + + return 0; +} + static int gpio_find_and_xlate(struct gpio_desc *desc, struct fdtdec_phandle_args *args) { struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); - /* Use the first argument as the offset by default */ - if (args->args_count > 0) - desc->offset = args->args[0]; + if (ops->xlate) + return ops->xlate(desc->dev, desc, args); else - desc->offset = -1; - desc->flags = 0; - - return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0; + return gpio_xlate_offs_flags(desc->dev, desc, args); } int dm_gpio_request(struct gpio_desc *desc, const char *label) @@ -154,6 +170,7 @@ int dm_gpio_request(struct gpio_desc *desc, const char *label) static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...) { +#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_USE_TINY_PRINTF) va_list args; char buf[40]; @@ -161,6 +178,9 @@ static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...) vscnprintf(buf, sizeof(buf), fmt, args); va_end(args); return dm_gpio_request(desc, buf); +#else + return dm_gpio_request(desc, fmt); +#endif } /** @@ -199,6 +219,7 @@ int gpio_request(unsigned gpio, const char *label) */ int gpio_requestf(unsigned gpio, const char *fmt, ...) { +#if !defined(CONFIG_SPL_BUILD) || !defined(CONFIG_USE_TINY_PRINTF) va_list args; char buf[40]; @@ -206,6 +227,9 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...) vscnprintf(buf, sizeof(buf), fmt, args); va_end(args); return gpio_request(gpio, buf); +#else + return gpio_request(gpio, fmt); +#endif } int _dm_gpio_free(struct udevice *dev, uint offset) @@ -248,10 +272,14 @@ int gpio_free(unsigned gpio) return _dm_gpio_free(desc.dev, desc.offset); } -static int check_reserved(struct gpio_desc *desc, const char *func) +static int check_reserved(const struct gpio_desc *desc, const char *func) { - struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev); + struct gpio_dev_priv *uc_priv; + + if (!dm_gpio_is_valid(desc)) + return -ENOENT; + uc_priv = dev_get_uclass_priv(desc->dev); if (!uc_priv->name[desc->offset]) { printf("%s: %s: error: gpio %s%d not reserved\n", desc->dev->name, func, @@ -311,7 +339,7 @@ int gpio_direction_output(unsigned gpio, int value) desc.offset, value); } -int dm_gpio_get_value(struct gpio_desc *desc) +int dm_gpio_get_value(const struct gpio_desc *desc) { int value; int ret; @@ -325,7 +353,7 @@ int dm_gpio_get_value(struct gpio_desc *desc) return desc->flags & GPIOD_ACTIVE_LOW ? !value : value; } -int dm_gpio_set_value(struct gpio_desc *desc, int value) +int dm_gpio_set_value(const struct gpio_desc *desc, int value) { int ret; @@ -339,6 +367,38 @@ int dm_gpio_set_value(struct gpio_desc *desc, int value) return 0; } +int dm_gpio_get_open_drain(struct gpio_desc *desc) +{ + struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); + int ret; + + ret = check_reserved(desc, "get_open_drain"); + if (ret) + return ret; + + if (ops->set_open_drain) + return ops->get_open_drain(desc->dev, desc->offset); + else + return -ENOSYS; +} + +int dm_gpio_set_open_drain(struct gpio_desc *desc, int value) +{ + struct dm_gpio_ops *ops = gpio_get_ops(desc->dev); + int ret; + + ret = check_reserved(desc, "set_open_drain"); + if (ret) + return ret; + + if (ops->set_open_drain) + ret = ops->set_open_drain(desc->dev, desc->offset, value); + else + return 0; /* feature not supported -> ignore setting */ + + return ret; +} + int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags) { struct udevice *dev = desc->dev; @@ -564,6 +624,24 @@ int gpio_get_values_as_int(const int *gpio_list) return vector; } +int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count) +{ + unsigned bitmask = 1; + unsigned vector = 0; + int ret, i; + + for (i = 0; i < count; i++) { + ret = dm_gpio_get_value(&desc_list[i]); + if (ret < 0) + return ret; + else if (ret) + vector |= bitmask; + bitmask <<= 1; + } + + return vector; +} + static int _gpio_request_by_name_nodev(const void *blob, int node, const char *list_name, int index, struct gpio_desc *desc, int flags, @@ -574,6 +652,7 @@ static int _gpio_request_by_name_nodev(const void *blob, int node, desc->dev = NULL; desc->offset = 0; + desc->flags = 0; ret = fdtdec_parse_phandle_with_args(blob, node, list_name, "#gpio-cells", 0, index, &args); if (ret) { @@ -735,7 +814,7 @@ static int gpio_renumber(struct udevice *removed_dev) return 0; } -int gpio_get_number(struct gpio_desc *desc) +int gpio_get_number(const struct gpio_desc *desc) { struct udevice *dev = desc->dev; struct gpio_dev_priv *uc_priv;