1 // SPDX-License-Identifier: GPL-2.0+
11 #include <asm/global_data.h>
14 #include <mach/gpio.h>
16 DECLARE_GLOBAL_DATA_PTR;
19 #define GPIO_OE_DISABLE (0x0 << 9)
20 #define GPIO_OE_ENABLE (0x1 << 9)
21 #define GPIO_OE_MASK (0x1 << 9)
23 /* GPIO_IN_OUT register shifts. */
27 struct msm_gpio_bank {
29 const struct msm_pin_data *pin_data;
32 #define GPIO_CONFIG_REG(dev, x) \
33 (qcom_pin_offset(((struct msm_gpio_bank *)dev_get_priv(dev))->pin_data->pin_offsets, x))
35 #define GPIO_IN_OUT_REG(dev, x) \
36 (GPIO_CONFIG_REG(dev, x) + 0x4)
38 static int msm_gpio_direction_input(struct udevice *dev, unsigned int gpio)
40 struct msm_gpio_bank *priv = dev_get_priv(dev);
43 clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
44 GPIO_OE_MASK, GPIO_OE_DISABLE);
49 static int msm_gpio_set_value(struct udevice *dev, unsigned int gpio, int value)
51 struct msm_gpio_bank *priv = dev_get_priv(dev);
55 writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
60 static int msm_gpio_direction_output(struct udevice *dev, unsigned int gpio,
63 struct msm_gpio_bank *priv = dev_get_priv(dev);
67 writel(value << GPIO_OUT, priv->base + GPIO_IN_OUT_REG(dev, gpio));
68 /* switch direction */
69 clrsetbits_le32(priv->base + GPIO_CONFIG_REG(dev, gpio),
70 GPIO_OE_MASK, GPIO_OE_ENABLE);
75 static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio)
77 struct msm_gpio_bank *priv = dev_get_priv(dev);
79 return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN);
82 static int msm_gpio_get_function(struct udevice *dev, unsigned int gpio)
84 struct msm_gpio_bank *priv = dev_get_priv(dev);
86 if (readl(priv->base + GPIO_CONFIG_REG(dev, gpio)) & GPIO_OE_ENABLE)
92 static const struct dm_gpio_ops gpio_msm_ops = {
93 .direction_input = msm_gpio_direction_input,
94 .direction_output = msm_gpio_direction_output,
95 .get_value = msm_gpio_get_value,
96 .set_value = msm_gpio_set_value,
97 .get_function = msm_gpio_get_function,
100 static int msm_gpio_probe(struct udevice *dev)
102 struct msm_gpio_bank *priv = dev_get_priv(dev);
104 priv->base = dev_read_addr(dev);
105 priv->pin_data = (struct msm_pin_data *)dev_get_driver_data(dev);
107 return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
110 static int msm_gpio_of_to_plat(struct udevice *dev)
112 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
113 const struct msm_pin_data *pin_data = (struct msm_pin_data *)dev_get_driver_data(dev);
115 /* Get the pin count from the pinctrl driver */
116 uc_priv->gpio_count = pin_data->pin_count;
117 uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
118 "gpio-bank-name", NULL);
119 if (uc_priv->bank_name == NULL)
120 uc_priv->bank_name = "soc";
125 U_BOOT_DRIVER(gpio_msm) = {
128 .of_to_plat = msm_gpio_of_to_plat,
129 .probe = msm_gpio_probe,
130 .ops = &gpio_msm_ops,
131 .flags = DM_UC_FLAG_SEQ_ALIAS,
132 .priv_auto = sizeof(struct msm_gpio_bank),