xref: /openbmc/u-boot/drivers/gpio/atmel_pio4.c (revision 46ed9381)
1 /*
2  * Atmel PIO4 device driver
3  *
4  * Copyright (C) 2015 Atmel Corporation
5  *		 Wenyou.Yang <wenyou.yang@atmel.com>
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 #include <common.h>
10 #include <dm.h>
11 #include <asm/arch/hardware.h>
12 #include <mach/gpio.h>
13 #include <mach/atmel_pio4.h>
14 
15 static struct atmel_pio4_port *atmel_pio4_port_base(u32 port)
16 {
17 	struct atmel_pio4_port *base = NULL;
18 
19 	switch (port) {
20 	case AT91_PIO_PORTA:
21 		base = (struct atmel_pio4_port *)ATMEL_BASE_PIOA;
22 		break;
23 	case AT91_PIO_PORTB:
24 		base = (struct atmel_pio4_port *)ATMEL_BASE_PIOB;
25 		break;
26 	case AT91_PIO_PORTC:
27 		base = (struct atmel_pio4_port *)ATMEL_BASE_PIOC;
28 		break;
29 	case AT91_PIO_PORTD:
30 		base = (struct atmel_pio4_port *)ATMEL_BASE_PIOD;
31 		break;
32 	default:
33 		printf("Error: Atmel PIO4: Failed to get PIO base of port#%d!\n",
34 		       port);
35 		break;
36 	}
37 
38 	return base;
39 }
40 
41 static int atmel_pio4_config_io_func(u32 port, u32 pin,
42 				     u32 func, u32 use_pullup)
43 {
44 	struct atmel_pio4_port *port_base;
45 	u32 reg, mask;
46 
47 	if (pin >= ATMEL_PIO_NPINS_PER_BANK)
48 		return -ENODEV;
49 
50 	port_base = atmel_pio4_port_base(port);
51 	if (!port_base)
52 		return -ENODEV;
53 
54 	mask = 1 << pin;
55 	reg = func;
56 	reg |= use_pullup ? ATMEL_PIO_PUEN_MASK : 0;
57 
58 	writel(mask, &port_base->mskr);
59 	writel(reg, &port_base->cfgr);
60 
61 	return 0;
62 }
63 
64 int atmel_pio4_set_gpio(u32 port, u32 pin, u32 use_pullup)
65 {
66 	return atmel_pio4_config_io_func(port, pin,
67 					 ATMEL_PIO_CFGR_FUNC_GPIO,
68 					 use_pullup);
69 }
70 
71 int atmel_pio4_set_a_periph(u32 port, u32 pin, u32 use_pullup)
72 {
73 	return atmel_pio4_config_io_func(port, pin,
74 					 ATMEL_PIO_CFGR_FUNC_PERIPH_A,
75 					 use_pullup);
76 }
77 
78 int atmel_pio4_set_b_periph(u32 port, u32 pin, u32 use_pullup)
79 {
80 	return atmel_pio4_config_io_func(port, pin,
81 					 ATMEL_PIO_CFGR_FUNC_PERIPH_B,
82 					 use_pullup);
83 }
84 
85 int atmel_pio4_set_c_periph(u32 port, u32 pin, u32 use_pullup)
86 {
87 	return atmel_pio4_config_io_func(port, pin,
88 					 ATMEL_PIO_CFGR_FUNC_PERIPH_C,
89 					 use_pullup);
90 }
91 
92 int atmel_pio4_set_d_periph(u32 port, u32 pin, u32 use_pullup)
93 {
94 	return atmel_pio4_config_io_func(port, pin,
95 					 ATMEL_PIO_CFGR_FUNC_PERIPH_D,
96 					 use_pullup);
97 }
98 
99 int atmel_pio4_set_e_periph(u32 port, u32 pin, u32 use_pullup)
100 {
101 	return atmel_pio4_config_io_func(port, pin,
102 					 ATMEL_PIO_CFGR_FUNC_PERIPH_E,
103 					 use_pullup);
104 }
105 
106 int atmel_pio4_set_f_periph(u32 port, u32 pin, u32 use_pullup)
107 {
108 	return atmel_pio4_config_io_func(port, pin,
109 					 ATMEL_PIO_CFGR_FUNC_PERIPH_F,
110 					 use_pullup);
111 }
112 
113 int atmel_pio4_set_g_periph(u32 port, u32 pin, u32 use_pullup)
114 {
115 	return atmel_pio4_config_io_func(port, pin,
116 					 ATMEL_PIO_CFGR_FUNC_PERIPH_G,
117 					 use_pullup);
118 }
119 
120 int atmel_pio4_set_pio_output(u32 port, u32 pin, u32 value)
121 {
122 	struct atmel_pio4_port *port_base;
123 	u32 reg, mask;
124 
125 	if (pin >= ATMEL_PIO_NPINS_PER_BANK)
126 		return -ENODEV;
127 
128 	port_base = atmel_pio4_port_base(port);
129 	if (!port_base)
130 		return -ENODEV;
131 
132 	mask = 0x01 << pin;
133 	reg = ATMEL_PIO_CFGR_FUNC_GPIO | ATMEL_PIO_DIR_MASK;
134 
135 	writel(mask, &port_base->mskr);
136 	writel(reg, &port_base->cfgr);
137 
138 	if (value)
139 		writel(mask, &port_base->sodr);
140 	else
141 		writel(mask, &port_base->codr);
142 
143 	return 0;
144 }
145 
146 int atmel_pio4_get_pio_input(u32 port, u32 pin)
147 {
148 	struct atmel_pio4_port *port_base;
149 	u32 reg, mask;
150 
151 	if (pin >= ATMEL_PIO_NPINS_PER_BANK)
152 		return -ENODEV;
153 
154 	port_base = atmel_pio4_port_base(port);
155 	if (!port_base)
156 		return -ENODEV;
157 
158 	mask = 0x01 << pin;
159 	reg = ATMEL_PIO_CFGR_FUNC_GPIO;
160 
161 	writel(mask, &port_base->mskr);
162 	writel(reg, &port_base->cfgr);
163 
164 	return (readl(&port_base->pdsr) & mask) ? 1 : 0;
165 }
166 
167 #ifdef CONFIG_DM_GPIO
168 static int atmel_pio4_direction_input(struct udevice *dev, unsigned offset)
169 {
170 	struct at91_port_platdata *plat = dev_get_platdata(dev);
171 	struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
172 	u32 mask = 0x01 << offset;
173 	u32 reg = ATMEL_PIO_CFGR_FUNC_GPIO;
174 
175 	writel(mask, &port_base->mskr);
176 	writel(reg, &port_base->cfgr);
177 
178 	return 0;
179 }
180 
181 static int atmel_pio4_direction_output(struct udevice *dev,
182 				       unsigned offset, int value)
183 {
184 	struct at91_port_platdata *plat = dev_get_platdata(dev);
185 	struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
186 	u32 mask = 0x01 << offset;
187 	u32 reg = ATMEL_PIO_CFGR_FUNC_GPIO | ATMEL_PIO_DIR_MASK;
188 
189 	writel(mask, &port_base->mskr);
190 	writel(reg, &port_base->cfgr);
191 
192 	if (value)
193 		writel(mask, &port_base->sodr);
194 	else
195 		writel(mask, &port_base->codr);
196 
197 	return 0;
198 }
199 
200 static int atmel_pio4_get_value(struct udevice *dev, unsigned offset)
201 {
202 	struct at91_port_platdata *plat = dev_get_platdata(dev);
203 	struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
204 	u32 mask = 0x01 << offset;
205 
206 	return (readl(&port_base->pdsr) & mask) ? 1 : 0;
207 }
208 
209 static int atmel_pio4_set_value(struct udevice *dev,
210 				unsigned offset, int value)
211 {
212 	struct at91_port_platdata *plat = dev_get_platdata(dev);
213 	struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
214 	u32 mask = 0x01 << offset;
215 
216 	if (value)
217 		writel(mask, &port_base->sodr);
218 	else
219 		writel(mask, &port_base->codr);
220 
221 	return 0;
222 }
223 
224 static int atmel_pio4_get_function(struct udevice *dev, unsigned offset)
225 {
226 	struct at91_port_platdata *plat = dev_get_platdata(dev);
227 	struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
228 	u32 mask = 0x01 << offset;
229 
230 	writel(mask, &port_base->mskr);
231 
232 	return (readl(&port_base->cfgr) &
233 		ATMEL_PIO_DIR_MASK) ? GPIOF_OUTPUT : GPIOF_INPUT;
234 }
235 
236 static const struct dm_gpio_ops atmel_pio4_ops = {
237 	.direction_input	= atmel_pio4_direction_input,
238 	.direction_output	= atmel_pio4_direction_output,
239 	.get_value		= atmel_pio4_get_value,
240 	.set_value		= atmel_pio4_set_value,
241 	.get_function		= atmel_pio4_get_function,
242 };
243 
244 static int atmel_pio4_probe(struct udevice *dev)
245 {
246 	struct at91_port_platdata *plat = dev_get_platdata(dev);
247 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
248 
249 	uc_priv->bank_name = plat->bank_name;
250 	uc_priv->gpio_count = ATMEL_PIO_NPINS_PER_BANK;
251 
252 	return 0;
253 }
254 
255 U_BOOT_DRIVER(gpio_atmel_pio4) = {
256 	.name	= "gpio_atmel_pio4",
257 	.id	= UCLASS_GPIO,
258 	.ops	= &atmel_pio4_ops,
259 	.probe	= atmel_pio4_probe,
260 };
261 #endif
262