diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Makefile | 10 | ||||
-rw-r--r-- | drivers/gpio/axp_gpio.c | 75 | ||||
-rw-r--r-- | drivers/gpio/msm_gpio.c | 53 | ||||
-rw-r--r-- | drivers/gpio/sunxi_gpio.c | 12 |
4 files changed, 76 insertions, 74 deletions
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index d426d3a2d7b..d64c14db5cf 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_DM_74X164) += 74x164_gpio.o endif obj-$(CONFIG_$(PHASE_)DM_GPIO) += gpio-uclass.o -obj-$(CONFIG_$(XPL_)DM_PCA953X) += pca953x_gpio.o +obj-$(CONFIG_$(PHASE_)DM_PCA953X) += pca953x_gpio.o obj-$(CONFIG_ADI_GPIO) += gpio-adi-adsp.o obj-$(CONFIG_ASPEED_GPIO) += gpio-aspeed.o @@ -59,12 +59,12 @@ obj-$(CONFIG_VYBRID_GPIO) += vybrid_gpio.o obj-$(CONFIG_HIKEY_GPIO) += hi6220_gpio.o obj-$(CONFIG_HSDK_CREG_GPIO) += hsdk-creg-gpio.o obj-$(CONFIG_IMX_RGPIO2P) += imx_rgpio2p.o -obj-$(CONFIG_$(XPL_)PALMAS_GPIO) += palmas_gpio.o +obj-$(CONFIG_$(PHASE_)PALMAS_GPIO) += palmas_gpio.o obj-$(CONFIG_PIC32_GPIO) += pic32_gpio.o obj-$(CONFIG_OCTEON_GPIO) += octeon_gpio.o obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o obj-$(CONFIG_MSM_GPIO) += msm_gpio.o -obj-$(CONFIG_$(XPL_)PCF8575_GPIO) += pcf8575_gpio.o +obj-$(CONFIG_$(PHASE_)PCF8575_GPIO) += pcf8575_gpio.o obj-$(CONFIG_$(PHASE_)QCOM_PMIC_GPIO) += qcom_pmic_gpio.o obj-$(CONFIG_MT7620_GPIO) += mt7620_gpio.o obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o @@ -73,11 +73,11 @@ obj-$(CONFIG_NX_GPIO) += nx_gpio.o obj-$(CONFIG_SIFIVE_GPIO) += sifive-gpio.o obj-$(CONFIG_NOMADIK_GPIO) += nmk_gpio.o obj-$(CONFIG_MAX7320_GPIO) += max7320_gpio.o -obj-$(CONFIG_$(XPL_)MAX77663_GPIO) += max77663_gpio.o +obj-$(CONFIG_$(PHASE_)MAX77663_GPIO) += max77663_gpio.o obj-$(CONFIG_SL28CPLD_GPIO) += sl28cpld-gpio.o obj-$(CONFIG_ADP5588_GPIO) += adp5588_gpio.o obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN) += zynqmp_gpio_modepin.o obj-$(CONFIG_SLG7XL45106_I2C_GPO) += gpio_slg7xl45106.o obj-$(CONFIG_FTGPIO010) += ftgpio010.o -obj-$(CONFIG_$(SPL_)ADP5585_GPIO) += adp5585_gpio.o +obj-$(CONFIG_$(PHASE_)ADP5585_GPIO) += adp5585_gpio.o obj-$(CONFIG_RZG2L_GPIO) += rzg2l-gpio.o diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c index 6e632c8fc73..181c53bfe72 100644 --- a/drivers/gpio/axp_gpio.c +++ b/drivers/gpio/axp_gpio.c @@ -15,6 +15,9 @@ #include <errno.h> #include <sunxi_gpio.h> +#define AXP_GPIO_PREFIX "AXP0-" +#define AXP_GPIO_COUNT 4 + static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val); static u8 axp_get_gpio_ctrl_reg(unsigned pin) @@ -46,28 +49,14 @@ static int axp_gpio_direction_input(struct udevice *dev, unsigned pin) static int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val) { - __maybe_unused int ret; u8 reg; - switch (pin) { -#ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC - /* Only available on later PMICs */ - case SUNXI_GPIO_AXP0_VBUS_ENABLE: - ret = pmic_bus_clrbits(AXP_MISC_CTRL, - AXP_MISC_CTRL_N_VBUSEN_FUNC); - if (ret) - return ret; - - return axp_gpio_set_value(dev, pin, val); -#endif - default: - reg = axp_get_gpio_ctrl_reg(pin); - if (reg == 0) - return -EINVAL; + reg = axp_get_gpio_ctrl_reg(pin); + if (reg == 0) + return -EINVAL; - return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH : - AXP_GPIO_CTRL_OUTPUT_LOW); - } + return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH : + AXP_GPIO_CTRL_OUTPUT_LOW); } static int axp_gpio_get_value(struct udevice *dev, unsigned pin) @@ -75,25 +64,16 @@ static int axp_gpio_get_value(struct udevice *dev, unsigned pin) u8 reg, val, mask; int ret; - switch (pin) { -#ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC - /* Only available on later PMICs */ - case SUNXI_GPIO_AXP0_VBUS_ENABLE: - ret = pmic_bus_read(AXP_VBUS_IPSOUT, &val); - mask = AXP_VBUS_IPSOUT_DRIVEBUS; - break; -#endif - default: - reg = axp_get_gpio_ctrl_reg(pin); - if (reg == 0) - return -EINVAL; + reg = axp_get_gpio_ctrl_reg(pin); + if (reg == 0) + return -EINVAL; - ret = pmic_bus_read(AXP_GPIO_STATE, &val); - mask = 1 << (pin + AXP_GPIO_STATE_OFFSET); - } + ret = pmic_bus_read(AXP_GPIO_STATE, &val); if (ret) return ret; + mask = 1 << (pin + AXP_GPIO_STATE_OFFSET); + return (val & mask) ? 1 : 0; } @@ -101,25 +81,12 @@ static int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val) { u8 reg; - switch (pin) { -#ifdef AXP_MISC_CTRL_N_VBUSEN_FUNC - /* Only available on later PMICs */ - case SUNXI_GPIO_AXP0_VBUS_ENABLE: - if (val) - return pmic_bus_setbits(AXP_VBUS_IPSOUT, - AXP_VBUS_IPSOUT_DRIVEBUS); - else - return pmic_bus_clrbits(AXP_VBUS_IPSOUT, - AXP_VBUS_IPSOUT_DRIVEBUS); -#endif - default: - reg = axp_get_gpio_ctrl_reg(pin); - if (reg == 0) - return -EINVAL; + reg = axp_get_gpio_ctrl_reg(pin); + if (reg == 0) + return -EINVAL; - return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH : - AXP_GPIO_CTRL_OUTPUT_LOW); - } + return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH : + AXP_GPIO_CTRL_OUTPUT_LOW); } static const struct dm_gpio_ops gpio_axp_ops = { @@ -134,8 +101,8 @@ 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; + uc_priv->bank_name = AXP_GPIO_PREFIX; + uc_priv->gpio_count = AXP_GPIO_COUNT; return 0; } diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c index cea073b3297..6783fc756f4 100644 --- a/drivers/gpio/msm_gpio.c +++ b/drivers/gpio/msm_gpio.c @@ -151,6 +151,9 @@ static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio, static int msm_gpio_set_flags(struct udevice *dev, unsigned int gpio, ulong flags) { + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) + return -EPERM; + if (flags & GPIOD_IS_OUT_ACTIVE) { return msm_gpio_direction_output(dev, gpio, 1); } else if (flags & GPIOD_IS_OUT) { @@ -172,12 +175,19 @@ static int msm_gpio_get_value_special(struct msm_gpio_bank *priv, unsigned int g const struct msm_special_pin_data *data; if (!priv->pin_data->special_pins_data) - return 0; + return -EINVAL; data = &priv->pin_data->special_pins_data[offset]; - if (!data->io_reg || data->in_bit >= 31) - return 0; + if (!data->io_reg) + return -EINVAL; + + if (data->in_bit >= 31) { + if (data->out_bit >= 31) + return -EINVAL; + + return !!(readl(priv->base + data->io_reg) >> data->out_bit); + } return !!(readl(priv->base + data->io_reg) >> data->in_bit); } @@ -186,19 +196,54 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio) { struct msm_gpio_bank *priv = dev_get_priv(dev); + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) + return -EPERM; + if (qcom_is_special_pin(priv->pin_data, gpio)) return msm_gpio_get_value_special(priv, gpio); return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN); } +static int msm_gpio_get_function_special(struct msm_gpio_bank *priv, + unsigned int gpio) +{ + unsigned int offset = gpio - priv->pin_data->special_pins_start; + const struct msm_special_pin_data *data; + + if (!priv->pin_data->special_pins_data) + return GPIOF_UNKNOWN; + + data = &priv->pin_data->special_pins_data[offset]; + + /* No I/O fields, cannot control/read the I/O value */ + if (!data->io_reg || (data->out_bit >= 31 && data->in_bit >= 31)) + return GPIOF_FUNC; + + /* No Output-Enable register, cannot control I/O direction */ + if (!data->ctl_reg || data->oe_bit >= 31) { + if (data->out_bit >= 31) + return GPIOF_INPUT; + else + return GPIOF_OUTPUT; + } + + if (readl(priv->base + data->ctl_reg) & BIT(data->oe_bit)) + return GPIOF_OUTPUT; + + return GPIOF_INPUT; +} + static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio) { struct msm_gpio_bank *priv = dev_get_priv(dev); + if (msm_pinctrl_is_reserved(dev_get_parent(dev), gpio)) + return GPIOF_UNKNOWN; + /* Always NOP for special pins, assume they're in the correct state */ if (qcom_is_special_pin(priv->pin_data, gpio)) - return 0; + return msm_gpio_get_function_special(priv, gpio); if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE) return GPIOF_OUTPUT; diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 2ca4960f17a..094c45a6927 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -244,17 +244,7 @@ int sunxi_name_to_gpio(const char *name) int sunxi_name_to_gpio(const char *name) { unsigned int gpio; - int ret; -#if !defined CONFIG_XPL_BUILD && defined CONFIG_AXP_GPIO - char lookup[8]; - - if (strcasecmp(name, "AXP0-VBUS-ENABLE") == 0) { - sprintf(lookup, SUNXI_GPIO_AXP0_PREFIX "%d", - SUNXI_GPIO_AXP0_VBUS_ENABLE); - name = lookup; - } -#endif - ret = gpio_lookup_name(name, NULL, NULL, &gpio); + int ret = gpio_lookup_name(name, NULL, NULL, &gpio); return ret ? ret : gpio; } |