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