1 // SPDX-License-Identifier: GPL-2.0+
12 #include <asm/arch/imx-regs.h>
15 #include <dt-structs.h>
18 enum mxc_gpio_direction {
19 MXC_GPIO_DIRECTION_IN,
20 MXC_GPIO_DIRECTION_OUT,
23 #define GPIO_PER_BANK 32
25 struct mxc_gpio_plat {
26 #if CONFIG_IS_ENABLED(OF_PLATDATA)
27 /* Put this first since driver model will copy the data here */
28 struct dtd_gpio_mxc dtplat;
31 struct gpio_regs *regs;
34 struct mxc_bank_info {
35 struct gpio_regs *regs;
38 #if !CONFIG_IS_ENABLED(DM_GPIO)
39 #define GPIO_TO_PORT(n) ((n) / 32)
41 /* GPIO port description */
42 static unsigned long gpio_ports[] = {
43 [0] = GPIO1_BASE_ADDR,
44 [1] = GPIO2_BASE_ADDR,
45 [2] = GPIO3_BASE_ADDR,
46 #if defined(CONFIG_MX51) || \
47 defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
48 defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || \
49 defined(CONFIG_ARCH_IMX8) || defined(CONFIG_IMXRT1050)
50 [3] = GPIO4_BASE_ADDR,
52 #if defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
53 defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || \
54 defined(CONFIG_ARCH_IMX8) || defined(CONFIG_IMXRT1050)
55 [4] = GPIO5_BASE_ADDR,
56 #if !(defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) || \
57 defined(CONFIG_IMX8M) || defined(CONFIG_IMXRT1050))
58 [5] = GPIO6_BASE_ADDR,
61 #if defined(CONFIG_MX53) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
62 defined(CONFIG_ARCH_IMX8)
63 #if !(defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL))
64 [6] = GPIO7_BASE_ADDR,
67 #if defined(CONFIG_ARCH_IMX8)
68 [7] = GPIO8_BASE_ADDR,
72 static int mxc_gpio_direction(unsigned int gpio,
73 enum mxc_gpio_direction direction)
75 unsigned int port = GPIO_TO_PORT(gpio);
76 struct gpio_regs *regs;
79 if (port >= ARRAY_SIZE(gpio_ports))
84 regs = (struct gpio_regs *)gpio_ports[port];
86 l = readl(®s->gpio_dir);
89 case MXC_GPIO_DIRECTION_OUT:
92 case MXC_GPIO_DIRECTION_IN:
95 writel(l, ®s->gpio_dir);
100 int gpio_set_value(unsigned gpio, int value)
102 unsigned int port = GPIO_TO_PORT(gpio);
103 struct gpio_regs *regs;
106 if (port >= ARRAY_SIZE(gpio_ports))
111 regs = (struct gpio_regs *)gpio_ports[port];
113 l = readl(®s->gpio_dr);
118 writel(l, ®s->gpio_dr);
123 int gpio_get_value(unsigned gpio)
125 unsigned int port = GPIO_TO_PORT(gpio);
126 struct gpio_regs *regs;
129 if (port >= ARRAY_SIZE(gpio_ports))
134 regs = (struct gpio_regs *)gpio_ports[port];
136 val = (readl(®s->gpio_psr) >> gpio) & 0x01;
141 int gpio_request(unsigned gpio, const char *label)
143 unsigned int port = GPIO_TO_PORT(gpio);
144 if (port >= ARRAY_SIZE(gpio_ports))
149 int gpio_free(unsigned gpio)
154 int gpio_direction_input(unsigned gpio)
156 return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_IN);
159 int gpio_direction_output(unsigned gpio, int value)
161 int ret = gpio_set_value(gpio, value);
166 return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT);
170 #if CONFIG_IS_ENABLED(DM_GPIO)
172 static int mxc_gpio_is_output(struct gpio_regs *regs, int offset)
176 val = readl(®s->gpio_dir);
178 return val & (1 << offset) ? 1 : 0;
181 static void mxc_gpio_bank_direction(struct gpio_regs *regs, int offset,
182 enum mxc_gpio_direction direction)
186 l = readl(®s->gpio_dir);
189 case MXC_GPIO_DIRECTION_OUT:
192 case MXC_GPIO_DIRECTION_IN:
195 writel(l, ®s->gpio_dir);
198 static void mxc_gpio_bank_set_value(struct gpio_regs *regs, int offset,
203 l = readl(®s->gpio_dr);
208 writel(l, ®s->gpio_dr);
211 static int mxc_gpio_bank_get_value(struct gpio_regs *regs, int offset)
213 return (readl(®s->gpio_psr) >> offset) & 0x01;
216 /* set GPIO pin 'gpio' as an input */
217 static int mxc_gpio_direction_input(struct udevice *dev, unsigned offset)
219 struct mxc_bank_info *bank = dev_get_priv(dev);
221 /* Configure GPIO direction as input. */
222 mxc_gpio_bank_direction(bank->regs, offset, MXC_GPIO_DIRECTION_IN);
227 /* set GPIO pin 'gpio' as an output, with polarity 'value' */
228 static int mxc_gpio_direction_output(struct udevice *dev, unsigned offset,
231 struct mxc_bank_info *bank = dev_get_priv(dev);
233 /* Configure GPIO output value. */
234 mxc_gpio_bank_set_value(bank->regs, offset, value);
236 /* Configure GPIO direction as output. */
237 mxc_gpio_bank_direction(bank->regs, offset, MXC_GPIO_DIRECTION_OUT);
242 /* read GPIO IN value of pin 'gpio' */
243 static int mxc_gpio_get_value(struct udevice *dev, unsigned offset)
245 struct mxc_bank_info *bank = dev_get_priv(dev);
247 return mxc_gpio_bank_get_value(bank->regs, offset);
250 /* write GPIO OUT value to pin 'gpio' */
251 static int mxc_gpio_set_value(struct udevice *dev, unsigned offset,
254 struct mxc_bank_info *bank = dev_get_priv(dev);
256 mxc_gpio_bank_set_value(bank->regs, offset, value);
261 static int mxc_gpio_get_function(struct udevice *dev, unsigned offset)
263 struct mxc_bank_info *bank = dev_get_priv(dev);
265 /* GPIOF_FUNC is not implemented yet */
266 if (mxc_gpio_is_output(bank->regs, offset))
272 static const struct dm_gpio_ops gpio_mxc_ops = {
273 .direction_input = mxc_gpio_direction_input,
274 .direction_output = mxc_gpio_direction_output,
275 .get_value = mxc_gpio_get_value,
276 .set_value = mxc_gpio_set_value,
277 .get_function = mxc_gpio_get_function,
280 static int mxc_gpio_probe(struct udevice *dev)
282 struct mxc_bank_info *bank = dev_get_priv(dev);
283 struct mxc_gpio_plat *plat = dev_get_plat(dev);
284 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
288 #if CONFIG_IS_ENABLED(OF_PLATDATA)
289 struct dtd_gpio_mxc *dtplat = &plat->dtplat;
291 plat->regs = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
294 banknum = plat->bank_index;
295 if (IS_ENABLED(CONFIG_ARCH_IMX8))
296 sprintf(name, "GPIO%d_", banknum);
298 sprintf(name, "GPIO%d_", banknum + 1);
302 uc_priv->bank_name = str;
303 uc_priv->gpio_count = GPIO_PER_BANK;
304 bank->regs = plat->regs;
309 static int mxc_gpio_of_to_plat(struct udevice *dev)
311 struct mxc_gpio_plat *plat = dev_get_plat(dev);
312 if (!CONFIG_IS_ENABLED(OF_PLATDATA)) {
314 addr = dev_read_addr(dev);
315 if (addr == FDT_ADDR_T_NONE)
318 plat->regs = (struct gpio_regs *)addr;
320 plat->bank_index = dev_seq(dev);
325 static int mxc_gpio_bind(struct udevice *dev)
330 static const struct udevice_id mxc_gpio_ids[] = {
331 { .compatible = "fsl,imx35-gpio" },
335 U_BOOT_DRIVER(gpio_mxc) = {
338 .ops = &gpio_mxc_ops,
339 .probe = mxc_gpio_probe,
340 .of_to_plat = mxc_gpio_of_to_plat,
341 .plat_auto = sizeof(struct mxc_gpio_plat),
342 .priv_auto = sizeof(struct mxc_bank_info),
343 .of_match = mxc_gpio_ids,
344 .bind = mxc_gpio_bind,
347 DM_DRIVER_ALIAS(gpio_mxc, fsl_imx6q_gpio)
349 #if !CONFIG_IS_ENABLED(OF_CONTROL)
350 static const struct mxc_gpio_plat mxc_plat[] = {
351 { 0, (struct gpio_regs *)GPIO1_BASE_ADDR },
352 { 1, (struct gpio_regs *)GPIO2_BASE_ADDR },
353 { 2, (struct gpio_regs *)GPIO3_BASE_ADDR },
354 #if defined(CONFIG_MX51) || \
355 defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
356 defined(CONFIG_IMX8M) || defined(CONFIG_ARCH_IMX8)
357 { 3, (struct gpio_regs *)GPIO4_BASE_ADDR },
359 #if defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
360 defined(CONFIG_IMX8M) || defined(CONFIG_ARCH_IMX8)
361 { 4, (struct gpio_regs *)GPIO5_BASE_ADDR },
363 { 5, (struct gpio_regs *)GPIO6_BASE_ADDR },
366 #if defined(CONFIG_MX53) || defined(CONFIG_MX6) || defined(CONFIG_ARCH_IMX8)
367 { 6, (struct gpio_regs *)GPIO7_BASE_ADDR },
369 #if defined(CONFIG_ARCH_IMX8)
370 { 7, (struct gpio_regs *)GPIO8_BASE_ADDR },
374 U_BOOT_DRVINFOS(mxc_gpios) = {
375 { "gpio_mxc", &mxc_plat[0] },
376 { "gpio_mxc", &mxc_plat[1] },
377 { "gpio_mxc", &mxc_plat[2] },
378 #if defined(CONFIG_MX51) || \
379 defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
380 defined(CONFIG_IMX8M) || defined(CONFIG_ARCH_IMX8)
381 { "gpio_mxc", &mxc_plat[3] },
383 #if defined(CONFIG_MX53) || defined(CONFIG_MX6) || \
384 defined(CONFIG_IMX8M) || defined(CONFIG_ARCH_IMX8)
385 { "gpio_mxc", &mxc_plat[4] },
387 { "gpio_mxc", &mxc_plat[5] },
390 #if defined(CONFIG_MX53) || defined(CONFIG_MX6) || defined(CONFIG_ARCH_IMX8)
391 { "gpio_mxc", &mxc_plat[6] },
393 #if defined(CONFIG_ARCH_IMX8)
394 { "gpio_mxc", &mxc_plat[7] },