xref: /openbmc/u-boot/drivers/gpio/mxc_gpio.c (revision 3bddafaa)
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 }
137