xref: /arm-trusted-firmware/plat/mediatek/mt8183/drivers/gpio/mtgpio.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2019, MediaTek Inc. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <common/debug.h>
9*91f16700Schasinglulu #include <drivers/delay_timer.h>
10*91f16700Schasinglulu #include <gpio/mtgpio.h>
11*91f16700Schasinglulu #include <gpio/mtgpio_cfg.h>
12*91f16700Schasinglulu #include <drivers/gpio.h>
13*91f16700Schasinglulu #include <mcucfg.h>
14*91f16700Schasinglulu #include <lib/mmio.h>
15*91f16700Schasinglulu #include <platform_def.h>
16*91f16700Schasinglulu #include <spm.h>
17*91f16700Schasinglulu #include <stdbool.h>
18*91f16700Schasinglulu 
19*91f16700Schasinglulu /******************************************************************************
20*91f16700Schasinglulu  *Macro Definition
21*91f16700Schasinglulu  ******************************************************************************/
22*91f16700Schasinglulu #define GPIO_MODE_BITS		4
23*91f16700Schasinglulu #define MAX_GPIO_MODE_PER_REG	8
24*91f16700Schasinglulu #define MAX_GPIO_REG_BITS	32
25*91f16700Schasinglulu #define DIR_BASE		(GPIO_BASE + 0x000)
26*91f16700Schasinglulu #define DOUT_BASE		(GPIO_BASE + 0x100)
27*91f16700Schasinglulu #define DIN_BASE		(GPIO_BASE + 0x200)
28*91f16700Schasinglulu #define MODE_BASE		(GPIO_BASE + 0x300)
29*91f16700Schasinglulu #define SET			0x4
30*91f16700Schasinglulu #define CLR			0x8
31*91f16700Schasinglulu #define PULLEN_ADDR_OFFSET	0x060
32*91f16700Schasinglulu #define PULLSEL_ADDR_OFFSET	0x080
33*91f16700Schasinglulu 
34*91f16700Schasinglulu void mt_set_gpio_dir_chip(uint32_t pin, int dir)
35*91f16700Schasinglulu {
36*91f16700Schasinglulu 	uint32_t pos, bit;
37*91f16700Schasinglulu 
38*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
39*91f16700Schasinglulu 	assert(dir < GPIO_DIR_MAX);
40*91f16700Schasinglulu 
41*91f16700Schasinglulu 	pos = pin / MAX_GPIO_REG_BITS;
42*91f16700Schasinglulu 	bit = pin % MAX_GPIO_REG_BITS;
43*91f16700Schasinglulu 
44*91f16700Schasinglulu 	if (dir == GPIO_DIR_IN)
45*91f16700Schasinglulu 		mmio_write_32(DIR_BASE + 0x10 * pos + CLR, 1U << bit);
46*91f16700Schasinglulu 	else
47*91f16700Schasinglulu 		mmio_write_32(DIR_BASE + 0x10 * pos + SET, 1U << bit);
48*91f16700Schasinglulu }
49*91f16700Schasinglulu 
50*91f16700Schasinglulu int mt_get_gpio_dir_chip(uint32_t pin)
51*91f16700Schasinglulu {
52*91f16700Schasinglulu 	uint32_t pos, bit;
53*91f16700Schasinglulu 	uint32_t reg;
54*91f16700Schasinglulu 
55*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
56*91f16700Schasinglulu 
57*91f16700Schasinglulu 	pos = pin / MAX_GPIO_REG_BITS;
58*91f16700Schasinglulu 	bit = pin % MAX_GPIO_REG_BITS;
59*91f16700Schasinglulu 
60*91f16700Schasinglulu 	reg = mmio_read_32(DIR_BASE + 0x10 * pos);
61*91f16700Schasinglulu 	return (((reg & (1U << bit)) != 0) ? GPIO_DIR_OUT : GPIO_DIR_IN);
62*91f16700Schasinglulu }
63*91f16700Schasinglulu 
64*91f16700Schasinglulu void mt_set_gpio_out_chip(uint32_t pin, int output)
65*91f16700Schasinglulu {
66*91f16700Schasinglulu 	uint32_t pos, bit;
67*91f16700Schasinglulu 
68*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
69*91f16700Schasinglulu 	assert(output < GPIO_OUT_MAX);
70*91f16700Schasinglulu 
71*91f16700Schasinglulu 	pos = pin / MAX_GPIO_REG_BITS;
72*91f16700Schasinglulu 	bit = pin % MAX_GPIO_REG_BITS;
73*91f16700Schasinglulu 
74*91f16700Schasinglulu 	if (output == GPIO_OUT_ZERO)
75*91f16700Schasinglulu 		mmio_write_32(DOUT_BASE + 0x10 * pos + CLR, 1U << bit);
76*91f16700Schasinglulu 	else
77*91f16700Schasinglulu 		mmio_write_32(DOUT_BASE + 0x10 * pos + SET, 1U << bit);
78*91f16700Schasinglulu }
79*91f16700Schasinglulu 
80*91f16700Schasinglulu int mt_get_gpio_out_chip(uint32_t pin)
81*91f16700Schasinglulu {
82*91f16700Schasinglulu 	uint32_t pos, bit;
83*91f16700Schasinglulu 	uint32_t reg;
84*91f16700Schasinglulu 
85*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
86*91f16700Schasinglulu 
87*91f16700Schasinglulu 	pos = pin / MAX_GPIO_REG_BITS;
88*91f16700Schasinglulu 	bit = pin % MAX_GPIO_REG_BITS;
89*91f16700Schasinglulu 
90*91f16700Schasinglulu 	reg = mmio_read_32(DOUT_BASE + 0x10 * pos);
91*91f16700Schasinglulu 	return (((reg & (1U << bit)) != 0) ? 1 : 0);
92*91f16700Schasinglulu }
93*91f16700Schasinglulu 
94*91f16700Schasinglulu int mt_get_gpio_in_chip(uint32_t pin)
95*91f16700Schasinglulu {
96*91f16700Schasinglulu 	uint32_t pos, bit;
97*91f16700Schasinglulu 	uint32_t reg;
98*91f16700Schasinglulu 
99*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
100*91f16700Schasinglulu 
101*91f16700Schasinglulu 	pos = pin / MAX_GPIO_REG_BITS;
102*91f16700Schasinglulu 	bit = pin % MAX_GPIO_REG_BITS;
103*91f16700Schasinglulu 
104*91f16700Schasinglulu 	reg = mmio_read_32(DIN_BASE + 0x10 * pos);
105*91f16700Schasinglulu 	return (((reg & (1U << bit)) != 0) ? 1 : 0);
106*91f16700Schasinglulu }
107*91f16700Schasinglulu 
108*91f16700Schasinglulu void mt_set_gpio_mode_chip(uint32_t pin, int mode)
109*91f16700Schasinglulu {
110*91f16700Schasinglulu 	uint32_t pos, bit;
111*91f16700Schasinglulu 	uint32_t data;
112*91f16700Schasinglulu 	uint32_t mask;
113*91f16700Schasinglulu 
114*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
115*91f16700Schasinglulu 	assert(mode < GPIO_MODE_MAX);
116*91f16700Schasinglulu 
117*91f16700Schasinglulu 	mask = (1U << GPIO_MODE_BITS) - 1;
118*91f16700Schasinglulu 
119*91f16700Schasinglulu 	mode = mode & mask;
120*91f16700Schasinglulu 	pos = pin / MAX_GPIO_MODE_PER_REG;
121*91f16700Schasinglulu 	bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS;
122*91f16700Schasinglulu 
123*91f16700Schasinglulu 	data = mmio_read_32(MODE_BASE + 0x10 * pos);
124*91f16700Schasinglulu 	data &= (~(mask << bit));
125*91f16700Schasinglulu 	data |= (mode << bit);
126*91f16700Schasinglulu 	mmio_write_32(MODE_BASE + 0x10 * pos, data);
127*91f16700Schasinglulu }
128*91f16700Schasinglulu 
129*91f16700Schasinglulu int mt_get_gpio_mode_chip(uint32_t pin)
130*91f16700Schasinglulu {
131*91f16700Schasinglulu 	uint32_t pos, bit;
132*91f16700Schasinglulu 	uint32_t data;
133*91f16700Schasinglulu 	uint32_t mask;
134*91f16700Schasinglulu 
135*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
136*91f16700Schasinglulu 
137*91f16700Schasinglulu 	mask = (1U << GPIO_MODE_BITS) - 1;
138*91f16700Schasinglulu 
139*91f16700Schasinglulu 	pos = pin / MAX_GPIO_MODE_PER_REG;
140*91f16700Schasinglulu 	bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS;
141*91f16700Schasinglulu 
142*91f16700Schasinglulu 	data = mmio_read_32(MODE_BASE + 0x10 * pos);
143*91f16700Schasinglulu 	return (data >> bit) & mask;
144*91f16700Schasinglulu }
145*91f16700Schasinglulu 
146*91f16700Schasinglulu int32_t gpio_get_pull_iocfg(uint32_t pin)
147*91f16700Schasinglulu {
148*91f16700Schasinglulu 	switch (pin) {
149*91f16700Schasinglulu 	case 0 ... 10:
150*91f16700Schasinglulu 		return IOCFG_5_BASE;
151*91f16700Schasinglulu 	case 11 ... 12:
152*91f16700Schasinglulu 		return IOCFG_0_BASE;
153*91f16700Schasinglulu 	case 13 ... 28:
154*91f16700Schasinglulu 		return IOCFG_1_BASE;
155*91f16700Schasinglulu 	case 43 ... 49:
156*91f16700Schasinglulu 		return IOCFG_2_BASE;
157*91f16700Schasinglulu 	case 50 ... 60:
158*91f16700Schasinglulu 		return IOCFG_3_BASE;
159*91f16700Schasinglulu 	case 61 ... 88:
160*91f16700Schasinglulu 		return IOCFG_4_BASE;
161*91f16700Schasinglulu 	case 89 ... 90:
162*91f16700Schasinglulu 		return IOCFG_5_BASE;
163*91f16700Schasinglulu 	case 95 ... 106:
164*91f16700Schasinglulu 		return IOCFG_5_BASE;
165*91f16700Schasinglulu 	case 107 ... 121:
166*91f16700Schasinglulu 		return IOCFG_6_BASE;
167*91f16700Schasinglulu 	case 134 ... 160:
168*91f16700Schasinglulu 		return IOCFG_0_BASE;
169*91f16700Schasinglulu 	case 161 ... 166:
170*91f16700Schasinglulu 		return IOCFG_1_BASE;
171*91f16700Schasinglulu 	case 167 ... 176:
172*91f16700Schasinglulu 		return IOCFG_3_BASE;
173*91f16700Schasinglulu 	case 177 ... 179:
174*91f16700Schasinglulu 		return IOCFG_5_BASE;
175*91f16700Schasinglulu 	default:
176*91f16700Schasinglulu 		return -1;
177*91f16700Schasinglulu 	}
178*91f16700Schasinglulu }
179*91f16700Schasinglulu 
180*91f16700Schasinglulu int32_t gpio_get_pupd_iocfg(uint32_t pin)
181*91f16700Schasinglulu {
182*91f16700Schasinglulu 	const int32_t offset = 0x0c0;
183*91f16700Schasinglulu 
184*91f16700Schasinglulu 	switch (pin) {
185*91f16700Schasinglulu 	case 29 ... 34:
186*91f16700Schasinglulu 		return IOCFG_1_BASE + offset;
187*91f16700Schasinglulu 	case 35 ... 42:
188*91f16700Schasinglulu 		return IOCFG_2_BASE + offset;
189*91f16700Schasinglulu 	case 91 ... 94:
190*91f16700Schasinglulu 		return IOCFG_5_BASE + offset;
191*91f16700Schasinglulu 	case 122 ... 133:
192*91f16700Schasinglulu 		return IOCFG_7_BASE + offset;
193*91f16700Schasinglulu 	default:
194*91f16700Schasinglulu 		return -1;
195*91f16700Schasinglulu 	}
196*91f16700Schasinglulu }
197*91f16700Schasinglulu 
198*91f16700Schasinglulu int gpio_get_pupd_offset(uint32_t pin)
199*91f16700Schasinglulu {
200*91f16700Schasinglulu 	switch (pin) {
201*91f16700Schasinglulu 	case 29 ... 34:
202*91f16700Schasinglulu 		return (pin - 29) * 4 % 32;
203*91f16700Schasinglulu 	case 35 ... 42:
204*91f16700Schasinglulu 		return (pin - 35) * 4 % 32;
205*91f16700Schasinglulu 	case 91 ... 94:
206*91f16700Schasinglulu 		return (pin - 91) * 4 % 32;
207*91f16700Schasinglulu 	case 122 ... 129:
208*91f16700Schasinglulu 		return (pin - 122) * 4 % 32;
209*91f16700Schasinglulu 	case 130 ... 133:
210*91f16700Schasinglulu 		return (pin - 130) * 4 % 32;
211*91f16700Schasinglulu 	default:
212*91f16700Schasinglulu 		return -1;
213*91f16700Schasinglulu 	}
214*91f16700Schasinglulu }
215*91f16700Schasinglulu 
216*91f16700Schasinglulu void mt_set_gpio_pull_enable_chip(uint32_t pin, int en)
217*91f16700Schasinglulu {
218*91f16700Schasinglulu 	int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
219*91f16700Schasinglulu 	int pupd_addr = gpio_get_pupd_iocfg(pin);
220*91f16700Schasinglulu 	int pupd_offset = gpio_get_pupd_offset(pin);
221*91f16700Schasinglulu 
222*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
223*91f16700Schasinglulu 
224*91f16700Schasinglulu 	assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
225*91f16700Schasinglulu 		(pupd_offset == (int8_t)-1)));
226*91f16700Schasinglulu 
227*91f16700Schasinglulu 	if (en == GPIO_PULL_DISABLE) {
228*91f16700Schasinglulu 		if (PULL_offset[pin].offset == (int8_t)-1)
229*91f16700Schasinglulu 			mmio_clrbits_32(pupd_addr, 3U << pupd_offset);
230*91f16700Schasinglulu 		else
231*91f16700Schasinglulu 			mmio_clrbits_32(pullen_addr,
232*91f16700Schasinglulu 					1U << PULL_offset[pin].offset);
233*91f16700Schasinglulu 	} else if (en == GPIO_PULL_ENABLE) {
234*91f16700Schasinglulu 		if (PULL_offset[pin].offset == (int8_t)-1) {
235*91f16700Schasinglulu 			/* For PUPD+R0+R1 Type, mt_set_gpio_pull_enable
236*91f16700Schasinglulu 			 * does not know
237*91f16700Schasinglulu 			 * which one between PU and PD shall be enabled.
238*91f16700Schasinglulu 			 * Use R0 to guarantee at one resistor is set when lk
239*91f16700Schasinglulu 			 * apply default setting
240*91f16700Schasinglulu 			 */
241*91f16700Schasinglulu 			mmio_setbits_32(pupd_addr, 1U << pupd_offset);
242*91f16700Schasinglulu 			mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 1));
243*91f16700Schasinglulu 		} else {
244*91f16700Schasinglulu 			/* For PULLEN + PULLSEL Type */
245*91f16700Schasinglulu 			mmio_setbits_32(pullen_addr,
246*91f16700Schasinglulu 					1U << PULL_offset[pin].offset);
247*91f16700Schasinglulu 		}
248*91f16700Schasinglulu 	} else if (en == GPIO_PULL_ENABLE_R0) {
249*91f16700Schasinglulu 		assert(!(pupd_offset == (int8_t)-1));
250*91f16700Schasinglulu 		mmio_setbits_32(pupd_addr, 1U << pupd_offset);
251*91f16700Schasinglulu 		mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 1));
252*91f16700Schasinglulu 	} else if (en == GPIO_PULL_ENABLE_R1) {
253*91f16700Schasinglulu 		assert(!(pupd_offset == (int8_t)-1));
254*91f16700Schasinglulu 
255*91f16700Schasinglulu 		mmio_clrbits_32(pupd_addr, 1U << pupd_offset);
256*91f16700Schasinglulu 		mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 1));
257*91f16700Schasinglulu 	} else if (en == GPIO_PULL_ENABLE_R0R1) {
258*91f16700Schasinglulu 		assert(!(pupd_offset == (int8_t)-1));
259*91f16700Schasinglulu 		mmio_setbits_32(pupd_addr, 3U << pupd_offset);
260*91f16700Schasinglulu 	}
261*91f16700Schasinglulu }
262*91f16700Schasinglulu 
263*91f16700Schasinglulu int mt_get_gpio_pull_enable_chip(uint32_t pin)
264*91f16700Schasinglulu {
265*91f16700Schasinglulu 	uint32_t reg;
266*91f16700Schasinglulu 
267*91f16700Schasinglulu 	int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
268*91f16700Schasinglulu 	int pupd_addr = gpio_get_pupd_iocfg(pin);
269*91f16700Schasinglulu 	int pupd_offset = gpio_get_pupd_offset(pin);
270*91f16700Schasinglulu 
271*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
272*91f16700Schasinglulu 
273*91f16700Schasinglulu 	assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
274*91f16700Schasinglulu 		(pupd_offset == (int8_t)-1)));
275*91f16700Schasinglulu 
276*91f16700Schasinglulu 	if (PULL_offset[pin].offset == (int8_t)-1) {
277*91f16700Schasinglulu 		reg = mmio_read_32(pupd_addr);
278*91f16700Schasinglulu 		return ((reg & (3U << pupd_offset)) ? 1 : 0);
279*91f16700Schasinglulu 	} else if (pupd_offset == (int8_t)-1) {
280*91f16700Schasinglulu 		reg = mmio_read_32(pullen_addr);
281*91f16700Schasinglulu 		return ((reg & (1U << PULL_offset[pin].offset)) ? 1 : 0);
282*91f16700Schasinglulu 	}
283*91f16700Schasinglulu 
284*91f16700Schasinglulu 	return -ERINVAL;
285*91f16700Schasinglulu }
286*91f16700Schasinglulu 
287*91f16700Schasinglulu void mt_set_gpio_pull_select_chip(uint32_t pin, int sel)
288*91f16700Schasinglulu {
289*91f16700Schasinglulu 	int pullsel_addr = gpio_get_pull_iocfg(pin) + PULLSEL_ADDR_OFFSET;
290*91f16700Schasinglulu 	int pupd_addr = gpio_get_pupd_iocfg(pin);
291*91f16700Schasinglulu 	int pupd_offset = gpio_get_pupd_offset(pin);
292*91f16700Schasinglulu 
293*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
294*91f16700Schasinglulu 
295*91f16700Schasinglulu 	assert(!((PULL_offset[pin].offset == (int8_t) -1) &&
296*91f16700Schasinglulu 		(pupd_offset == (int8_t)-1)));
297*91f16700Schasinglulu 
298*91f16700Schasinglulu 	if (sel == GPIO_PULL_NONE) {
299*91f16700Schasinglulu 		/*  Regard No PULL as PULL disable + pull down */
300*91f16700Schasinglulu 		mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_DISABLE);
301*91f16700Schasinglulu 		if (PULL_offset[pin].offset == (int8_t)-1)
302*91f16700Schasinglulu 			mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 2));
303*91f16700Schasinglulu 		else
304*91f16700Schasinglulu 			mmio_clrbits_32(pullsel_addr,
305*91f16700Schasinglulu 					1U << PULL_offset[pin].offset);
306*91f16700Schasinglulu 	} else if (sel == GPIO_PULL_UP) {
307*91f16700Schasinglulu 		mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_ENABLE);
308*91f16700Schasinglulu 		if (PULL_offset[pin].offset == (int8_t)-1)
309*91f16700Schasinglulu 			mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 2));
310*91f16700Schasinglulu 		else
311*91f16700Schasinglulu 			mmio_setbits_32(pullsel_addr,
312*91f16700Schasinglulu 					1U << PULL_offset[pin].offset);
313*91f16700Schasinglulu 	} else if (sel == GPIO_PULL_DOWN) {
314*91f16700Schasinglulu 		mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_ENABLE);
315*91f16700Schasinglulu 		if (PULL_offset[pin].offset == -1)
316*91f16700Schasinglulu 			mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 2));
317*91f16700Schasinglulu 		else
318*91f16700Schasinglulu 			mmio_clrbits_32(pullsel_addr,
319*91f16700Schasinglulu 					1U << PULL_offset[pin].offset);
320*91f16700Schasinglulu 	}
321*91f16700Schasinglulu }
322*91f16700Schasinglulu 
323*91f16700Schasinglulu /* get pull-up or pull-down, regardless of resistor value */
324*91f16700Schasinglulu int mt_get_gpio_pull_select_chip(uint32_t pin)
325*91f16700Schasinglulu {
326*91f16700Schasinglulu 	uint32_t reg;
327*91f16700Schasinglulu 
328*91f16700Schasinglulu 	int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
329*91f16700Schasinglulu 	int pullsel_addr = gpio_get_pull_iocfg(pin) + PULLSEL_ADDR_OFFSET;
330*91f16700Schasinglulu 	int pupd_addr = gpio_get_pupd_iocfg(pin);
331*91f16700Schasinglulu 	int pupd_offset = gpio_get_pupd_offset(pin);
332*91f16700Schasinglulu 
333*91f16700Schasinglulu 	assert(pin < MAX_GPIO_PIN);
334*91f16700Schasinglulu 
335*91f16700Schasinglulu 	assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
336*91f16700Schasinglulu 		(pupd_offset == (int8_t)-1)));
337*91f16700Schasinglulu 
338*91f16700Schasinglulu 	if (PULL_offset[pin].offset == (int8_t)-1) {
339*91f16700Schasinglulu 		reg = mmio_read_32(pupd_addr);
340*91f16700Schasinglulu 		if (reg & (3U << pupd_offset)) {
341*91f16700Schasinglulu 			reg = mmio_read_32(pupd_addr);
342*91f16700Schasinglulu 			/* Reg value: 0 for PU, 1 for PD -->
343*91f16700Schasinglulu 			 * reverse return value */
344*91f16700Schasinglulu 			return ((reg & (1U << (pupd_offset + 2))) ?
345*91f16700Schasinglulu 					GPIO_PULL_DOWN : GPIO_PULL_UP);
346*91f16700Schasinglulu 		} else {
347*91f16700Schasinglulu 			return GPIO_PULL_NONE;
348*91f16700Schasinglulu 		}
349*91f16700Schasinglulu 	} else if (pupd_offset == (int8_t)-1) {
350*91f16700Schasinglulu 		reg = mmio_read_32(pullen_addr);
351*91f16700Schasinglulu 		if ((reg & (1U << PULL_offset[pin].offset))) {
352*91f16700Schasinglulu 			reg = mmio_read_32(pullsel_addr);
353*91f16700Schasinglulu 			return ((reg & (1U << PULL_offset[pin].offset)) ?
354*91f16700Schasinglulu 					GPIO_PULL_UP : GPIO_PULL_DOWN);
355*91f16700Schasinglulu 		} else {
356*91f16700Schasinglulu 			return GPIO_PULL_NONE;
357*91f16700Schasinglulu 		}
358*91f16700Schasinglulu 	}
359*91f16700Schasinglulu 
360*91f16700Schasinglulu 	return -ERINVAL;
361*91f16700Schasinglulu }
362*91f16700Schasinglulu 
363*91f16700Schasinglulu void mt_set_gpio_dir(int gpio, int direction)
364*91f16700Schasinglulu {
365*91f16700Schasinglulu 	mt_set_gpio_dir_chip((uint32_t)gpio, direction);
366*91f16700Schasinglulu }
367*91f16700Schasinglulu 
368*91f16700Schasinglulu int mt_get_gpio_dir(int gpio)
369*91f16700Schasinglulu {
370*91f16700Schasinglulu 	uint32_t pin;
371*91f16700Schasinglulu 
372*91f16700Schasinglulu 	pin = (uint32_t)gpio;
373*91f16700Schasinglulu 	return mt_get_gpio_dir_chip(pin);
374*91f16700Schasinglulu }
375*91f16700Schasinglulu 
376*91f16700Schasinglulu void mt_set_gpio_pull(int gpio, int pull)
377*91f16700Schasinglulu {
378*91f16700Schasinglulu 	uint32_t pin;
379*91f16700Schasinglulu 
380*91f16700Schasinglulu 	pin = (uint32_t)gpio;
381*91f16700Schasinglulu 	mt_set_gpio_pull_select_chip(pin, pull);
382*91f16700Schasinglulu }
383*91f16700Schasinglulu 
384*91f16700Schasinglulu int mt_get_gpio_pull(int gpio)
385*91f16700Schasinglulu {
386*91f16700Schasinglulu 	uint32_t pin;
387*91f16700Schasinglulu 
388*91f16700Schasinglulu 	pin = (uint32_t)gpio;
389*91f16700Schasinglulu 	return mt_get_gpio_pull_select_chip(pin);
390*91f16700Schasinglulu }
391*91f16700Schasinglulu 
392*91f16700Schasinglulu void mt_set_gpio_out(int gpio, int value)
393*91f16700Schasinglulu {
394*91f16700Schasinglulu 	uint32_t pin;
395*91f16700Schasinglulu 
396*91f16700Schasinglulu 	pin = (uint32_t)gpio;
397*91f16700Schasinglulu 	mt_set_gpio_out_chip(pin, value);
398*91f16700Schasinglulu }
399*91f16700Schasinglulu 
400*91f16700Schasinglulu int mt_get_gpio_out(int gpio)
401*91f16700Schasinglulu {
402*91f16700Schasinglulu 	uint32_t pin;
403*91f16700Schasinglulu 
404*91f16700Schasinglulu 	pin = (uint32_t)gpio;
405*91f16700Schasinglulu 	return mt_get_gpio_out_chip(pin);
406*91f16700Schasinglulu }
407*91f16700Schasinglulu 
408*91f16700Schasinglulu int mt_get_gpio_in(int gpio)
409*91f16700Schasinglulu {
410*91f16700Schasinglulu 	uint32_t pin;
411*91f16700Schasinglulu 
412*91f16700Schasinglulu 	pin = (uint32_t)gpio;
413*91f16700Schasinglulu 	return mt_get_gpio_in_chip(pin);
414*91f16700Schasinglulu }
415*91f16700Schasinglulu 
416*91f16700Schasinglulu void mt_set_gpio_mode(int gpio, int mode)
417*91f16700Schasinglulu {
418*91f16700Schasinglulu 	uint32_t pin;
419*91f16700Schasinglulu 
420*91f16700Schasinglulu 	pin = (uint32_t)gpio;
421*91f16700Schasinglulu 	mt_set_gpio_mode_chip(pin, mode);
422*91f16700Schasinglulu }
423*91f16700Schasinglulu 
424*91f16700Schasinglulu int mt_get_gpio_mode(int gpio)
425*91f16700Schasinglulu {
426*91f16700Schasinglulu 	uint32_t pin;
427*91f16700Schasinglulu 
428*91f16700Schasinglulu 	pin = (uint32_t)gpio;
429*91f16700Schasinglulu 	return mt_get_gpio_mode_chip(pin);
430*91f16700Schasinglulu }
431*91f16700Schasinglulu 
432*91f16700Schasinglulu const gpio_ops_t mtgpio_ops = {
433*91f16700Schasinglulu 	 .get_direction = mt_get_gpio_dir,
434*91f16700Schasinglulu 	 .set_direction = mt_set_gpio_dir,
435*91f16700Schasinglulu 	 .get_value = mt_get_gpio_in,
436*91f16700Schasinglulu 	 .set_value = mt_set_gpio_out,
437*91f16700Schasinglulu 	 .set_pull = mt_set_gpio_pull,
438*91f16700Schasinglulu 	 .get_pull = mt_get_gpio_pull,
439*91f16700Schasinglulu };
440