]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/gpio/mxc_gpio.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[thirdparty/u-boot.git] / drivers / gpio / mxc_gpio.c
CommitLineData
b30de3cc
GL
1/*
2 * Copyright (C) 2009
3 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
4 *
d8e0ca85
SB
5 * Copyright (C) 2011
6 * Stefano Babic, DENX Software Engineering, <sbabic@denx.de>
7 *
1a459660 8 * SPDX-License-Identifier: GPL-2.0+
b30de3cc
GL
9 */
10#include <common.h>
c4ea1424 11#include <asm/arch/imx-regs.h>
d8e0ca85 12#include <asm/gpio.h>
c4ea1424 13#include <asm/io.h>
e53bcd94 14#include <errno.h>
b30de3cc 15
d8e0ca85
SB
16enum mxc_gpio_direction {
17 MXC_GPIO_DIRECTION_IN,
18 MXC_GPIO_DIRECTION_OUT,
19};
20
8d28c211 21#define GPIO_TO_PORT(n) (n / 32)
d8e0ca85 22
b30de3cc
GL
23/* GPIO port description */
24static unsigned long gpio_ports[] = {
c4ea1424
SB
25 [0] = GPIO1_BASE_ADDR,
26 [1] = GPIO2_BASE_ADDR,
27 [2] = GPIO3_BASE_ADDR,
e71c39de 28#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
5ea6d7c8 29 defined(CONFIG_MX53) || defined(CONFIG_MX6)
c4ea1424
SB
30 [3] = GPIO4_BASE_ADDR,
31#endif
5ea6d7c8 32#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
01643ec1
LHR
33 [4] = GPIO5_BASE_ADDR,
34 [5] = GPIO6_BASE_ADDR,
e71c39de 35#endif
5ea6d7c8 36#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
01643ec1
LHR
37 [6] = GPIO7_BASE_ADDR,
38#endif
b30de3cc
GL
39};
40
d8e0ca85
SB
41static int mxc_gpio_direction(unsigned int gpio,
42 enum mxc_gpio_direction direction)
b30de3cc 43{
be282554 44 unsigned int port = GPIO_TO_PORT(gpio);
c4ea1424 45 struct gpio_regs *regs;
b30de3cc
GL
46 u32 l;
47
48 if (port >= ARRAY_SIZE(gpio_ports))
365d6070 49 return -1;
b30de3cc
GL
50
51 gpio &= 0x1f;
52
c4ea1424
SB
53 regs = (struct gpio_regs *)gpio_ports[port];
54
55 l = readl(&regs->gpio_dir);
56
b30de3cc 57 switch (direction) {
c4ea1424 58 case MXC_GPIO_DIRECTION_OUT:
b30de3cc
GL
59 l |= 1 << gpio;
60 break;
c4ea1424 61 case MXC_GPIO_DIRECTION_IN:
b30de3cc
GL
62 l &= ~(1 << gpio);
63 }
c4ea1424 64 writel(l, &regs->gpio_dir);
b30de3cc
GL
65
66 return 0;
67}
68
365d6070 69int gpio_set_value(unsigned gpio, int value)
b30de3cc 70{
be282554 71 unsigned int port = GPIO_TO_PORT(gpio);
c4ea1424 72 struct gpio_regs *regs;
b30de3cc
GL
73 u32 l;
74
75 if (port >= ARRAY_SIZE(gpio_ports))
365d6070 76 return -1;
b30de3cc
GL
77
78 gpio &= 0x1f;
79
c4ea1424
SB
80 regs = (struct gpio_regs *)gpio_ports[port];
81
82 l = readl(&regs->gpio_dr);
b30de3cc
GL
83 if (value)
84 l |= 1 << gpio;
85 else
86 l &= ~(1 << gpio);
c4ea1424 87 writel(l, &regs->gpio_dr);
365d6070
JH
88
89 return 0;
b30de3cc 90}
7d27cd08 91
365d6070 92int gpio_get_value(unsigned gpio)
7d27cd08 93{
be282554 94 unsigned int port = GPIO_TO_PORT(gpio);
c4ea1424 95 struct gpio_regs *regs;
365d6070 96 u32 val;
7d27cd08
SB
97
98 if (port >= ARRAY_SIZE(gpio_ports))
365d6070 99 return -1;
7d27cd08
SB
100
101 gpio &= 0x1f;
102
c4ea1424
SB
103 regs = (struct gpio_regs *)gpio_ports[port];
104
5dafa454 105 val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
7d27cd08 106
365d6070 107 return val;
7d27cd08 108}
d8e0ca85 109
365d6070 110int gpio_request(unsigned gpio, const char *label)
d8e0ca85 111{
be282554 112 unsigned int port = GPIO_TO_PORT(gpio);
d8e0ca85 113 if (port >= ARRAY_SIZE(gpio_ports))
365d6070 114 return -1;
d8e0ca85
SB
115 return 0;
116}
117
365d6070 118int gpio_free(unsigned gpio)
d8e0ca85 119{
365d6070 120 return 0;
d8e0ca85
SB
121}
122
365d6070 123int gpio_direction_input(unsigned gpio)
d8e0ca85 124{
365d6070 125 return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_IN);
d8e0ca85
SB
126}
127
365d6070 128int gpio_direction_output(unsigned gpio, int value)
d8e0ca85 129{
365d6070 130 int ret = mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT);
d8e0ca85
SB
131
132 if (ret < 0)
133 return ret;
134
d71c9c9f 135 return gpio_set_value(gpio, value);
d8e0ca85 136}