xref: /rk3399_ARM-atf/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c (revision 536c2492456758d2fe7e28b11ece9001c4d79cc0)
19901dcf6SCaesar Wang /*
29901dcf6SCaesar Wang  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
39901dcf6SCaesar Wang  *
49901dcf6SCaesar Wang  * Redistribution and use in source and binary forms, with or without
59901dcf6SCaesar Wang  * modification, are permitted provided that the following conditions are met:
69901dcf6SCaesar Wang  *
79901dcf6SCaesar Wang  * Redistributions of source code must retain the above copyright notice, this
89901dcf6SCaesar Wang  * list of conditions and the following disclaimer.
99901dcf6SCaesar Wang  *
109901dcf6SCaesar Wang  * Redistributions in binary form must reproduce the above copyright notice,
119901dcf6SCaesar Wang  * this list of conditions and the following disclaimer in the documentation
129901dcf6SCaesar Wang  * and/or other materials provided with the distribution.
139901dcf6SCaesar Wang  *
149901dcf6SCaesar Wang  * Neither the name of ARM nor the names of its contributors may be used
159901dcf6SCaesar Wang  * to endorse or promote products derived from this software without specific
169901dcf6SCaesar Wang  * prior written permission.
179901dcf6SCaesar Wang  *
189901dcf6SCaesar Wang  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
199901dcf6SCaesar Wang  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
209901dcf6SCaesar Wang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
219901dcf6SCaesar Wang  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
229901dcf6SCaesar Wang  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
239901dcf6SCaesar Wang  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
249901dcf6SCaesar Wang  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
259901dcf6SCaesar Wang  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
269901dcf6SCaesar Wang  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
279901dcf6SCaesar Wang  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
289901dcf6SCaesar Wang  * POSSIBILITY OF SUCH DAMAGE.
299901dcf6SCaesar Wang  */
309901dcf6SCaesar Wang #include <assert.h>
319901dcf6SCaesar Wang #include <debug.h>
329901dcf6SCaesar Wang #include <delay_timer.h>
339901dcf6SCaesar Wang #include <errno.h>
349901dcf6SCaesar Wang #include <gpio.h>
359901dcf6SCaesar Wang #include <mmio.h>
369901dcf6SCaesar Wang #include <platform.h>
379901dcf6SCaesar Wang #include <platform_def.h>
389901dcf6SCaesar Wang #include <plat_private.h>
399901dcf6SCaesar Wang #include <soc.h>
409901dcf6SCaesar Wang 
419901dcf6SCaesar Wang uint32_t gpio_port[] = {
429901dcf6SCaesar Wang 	GPIO0_BASE,
439901dcf6SCaesar Wang 	GPIO1_BASE,
449901dcf6SCaesar Wang 	GPIO2_BASE,
459901dcf6SCaesar Wang 	GPIO3_BASE,
469901dcf6SCaesar Wang 	GPIO4_BASE,
479901dcf6SCaesar Wang };
489901dcf6SCaesar Wang 
499901dcf6SCaesar Wang #define SWPORTA_DR	0x00
509901dcf6SCaesar Wang #define SWPORTA_DDR	0x04
519901dcf6SCaesar Wang #define EXT_PORTA	0x50
529901dcf6SCaesar Wang 
539901dcf6SCaesar Wang #define PMU_GPIO_PORT0	0
549901dcf6SCaesar Wang #define PMU_GPIO_PORT1	1
55*536c2492SCaesar Wang #define GPIO_PORT2	2
56*536c2492SCaesar Wang #define GPIO_PORT3	3
57*536c2492SCaesar Wang #define GPIO_PORT4	4
589901dcf6SCaesar Wang 
599901dcf6SCaesar Wang #define PMU_GRF_GPIO0A_P	0x40
609901dcf6SCaesar Wang #define GRF_GPIO2A_P		0xe040
619901dcf6SCaesar Wang #define GPIO_P_MASK		0x03
629901dcf6SCaesar Wang 
63*536c2492SCaesar Wang #define GET_GPIO_PORT(pin)	(pin / 32)
64*536c2492SCaesar Wang #define GET_GPIO_NUM(pin)	(pin % 32)
65*536c2492SCaesar Wang #define GET_GPIO_BANK(pin)	((pin % 32) / 8)
66*536c2492SCaesar Wang #define GET_GPIO_ID(pin)	((pin % 32) % 8)
67*536c2492SCaesar Wang 
68*536c2492SCaesar Wang /* returns old clock state, enables clock, in order to do GPIO access */
69*536c2492SCaesar Wang static int gpio_get_clock(uint32_t gpio_number)
709901dcf6SCaesar Wang {
71*536c2492SCaesar Wang 	uint32_t port = GET_GPIO_PORT(gpio_number);
72*536c2492SCaesar Wang 	uint32_t clock_state = 0;
739901dcf6SCaesar Wang 
749901dcf6SCaesar Wang 	assert(port < 5);
759901dcf6SCaesar Wang 
769901dcf6SCaesar Wang 	switch (port) {
77*536c2492SCaesar Wang 	case PMU_GPIO_PORT0:
78*536c2492SCaesar Wang 		clock_state = (mmio_read_32(PMUCRU_BASE +
79*536c2492SCaesar Wang 					    CRU_PMU_CLKGATE_CON(1)) >>
80*536c2492SCaesar Wang 					    PCLK_GPIO0_GATE_SHIFT) & 0x01;
819901dcf6SCaesar Wang 		mmio_write_32(PMUCRU_BASE + CRU_PMU_CLKGATE_CON(1),
82*536c2492SCaesar Wang 			      BITS_WITH_WMASK(0, CLK_GATE_MASK,
839901dcf6SCaesar Wang 					      PCLK_GPIO0_GATE_SHIFT));
849901dcf6SCaesar Wang 		break;
85*536c2492SCaesar Wang 	case PMU_GPIO_PORT1:
86*536c2492SCaesar Wang 		clock_state = (mmio_read_32(PMUCRU_BASE +
87*536c2492SCaesar Wang 					    CRU_PMU_CLKGATE_CON(1)) >>
88*536c2492SCaesar Wang 					    PCLK_GPIO1_GATE_SHIFT) & 0x01;
899901dcf6SCaesar Wang 		mmio_write_32(PMUCRU_BASE + CRU_PMU_CLKGATE_CON(1),
90*536c2492SCaesar Wang 			      BITS_WITH_WMASK(0, CLK_GATE_MASK,
919901dcf6SCaesar Wang 					      PCLK_GPIO1_GATE_SHIFT));
929901dcf6SCaesar Wang 		break;
93*536c2492SCaesar Wang 	case GPIO_PORT2:
94*536c2492SCaesar Wang 		clock_state = (mmio_read_32(CRU_BASE +
95*536c2492SCaesar Wang 					    CRU_CLKGATE_CON(31)) >>
96*536c2492SCaesar Wang 					    PCLK_GPIO2_GATE_SHIFT) & 0x01;
979901dcf6SCaesar Wang 		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31),
98*536c2492SCaesar Wang 			      BITS_WITH_WMASK(0, CLK_GATE_MASK,
999901dcf6SCaesar Wang 					      PCLK_GPIO2_GATE_SHIFT));
1009901dcf6SCaesar Wang 		break;
101*536c2492SCaesar Wang 	case GPIO_PORT3:
102*536c2492SCaesar Wang 		clock_state = (mmio_read_32(CRU_BASE +
103*536c2492SCaesar Wang 					    CRU_CLKGATE_CON(31)) >>
104*536c2492SCaesar Wang 					    PCLK_GPIO3_GATE_SHIFT) & 0x01;
1059901dcf6SCaesar Wang 		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31),
106*536c2492SCaesar Wang 			      BITS_WITH_WMASK(0, CLK_GATE_MASK,
107*536c2492SCaesar Wang 					      PCLK_GPIO3_GATE_SHIFT));
108*536c2492SCaesar Wang 		break;
109*536c2492SCaesar Wang 	case GPIO_PORT4:
110*536c2492SCaesar Wang 		clock_state = (mmio_read_32(CRU_BASE +
111*536c2492SCaesar Wang 					    CRU_CLKGATE_CON(31)) >>
112*536c2492SCaesar Wang 					    PCLK_GPIO4_GATE_SHIFT) & 0x01;
113*536c2492SCaesar Wang 		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31),
114*536c2492SCaesar Wang 			      BITS_WITH_WMASK(0, CLK_GATE_MASK,
115*536c2492SCaesar Wang 					      PCLK_GPIO4_GATE_SHIFT));
116*536c2492SCaesar Wang 		break;
117*536c2492SCaesar Wang 	default:
118*536c2492SCaesar Wang 		break;
119*536c2492SCaesar Wang 	}
120*536c2492SCaesar Wang 
121*536c2492SCaesar Wang 	return clock_state;
122*536c2492SCaesar Wang }
123*536c2492SCaesar Wang 
124*536c2492SCaesar Wang /* restores old state of gpio clock */
125*536c2492SCaesar Wang void gpio_put_clock(uint32_t gpio_number, uint32_t clock_state)
126*536c2492SCaesar Wang {
127*536c2492SCaesar Wang 	uint32_t port = GET_GPIO_PORT(gpio_number);
128*536c2492SCaesar Wang 
129*536c2492SCaesar Wang 	switch (port) {
130*536c2492SCaesar Wang 	case PMU_GPIO_PORT0:
131*536c2492SCaesar Wang 		mmio_write_32(PMUCRU_BASE + CRU_PMU_CLKGATE_CON(1),
132*536c2492SCaesar Wang 			      BITS_WITH_WMASK(clock_state, CLK_GATE_MASK,
133*536c2492SCaesar Wang 					      PCLK_GPIO0_GATE_SHIFT));
134*536c2492SCaesar Wang 		break;
135*536c2492SCaesar Wang 	case PMU_GPIO_PORT1:
136*536c2492SCaesar Wang 		mmio_write_32(PMUCRU_BASE + CRU_PMU_CLKGATE_CON(1),
137*536c2492SCaesar Wang 			      BITS_WITH_WMASK(clock_state, CLK_GATE_MASK,
138*536c2492SCaesar Wang 					      PCLK_GPIO1_GATE_SHIFT));
139*536c2492SCaesar Wang 		break;
140*536c2492SCaesar Wang 	case GPIO_PORT2:
141*536c2492SCaesar Wang 		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31),
142*536c2492SCaesar Wang 			      BITS_WITH_WMASK(clock_state, CLK_GATE_MASK,
143*536c2492SCaesar Wang 					      PCLK_GPIO2_GATE_SHIFT));
144*536c2492SCaesar Wang 		break;
145*536c2492SCaesar Wang 	case GPIO_PORT3:
146*536c2492SCaesar Wang 		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31),
147*536c2492SCaesar Wang 			      BITS_WITH_WMASK(clock_state, CLK_GATE_MASK,
1489901dcf6SCaesar Wang 					      PCLK_GPIO3_GATE_SHIFT));
1499901dcf6SCaesar Wang 
1509901dcf6SCaesar Wang 		break;
151*536c2492SCaesar Wang 	case GPIO_PORT4:
1529901dcf6SCaesar Wang 		mmio_write_32(CRU_BASE + CRU_CLKGATE_CON(31),
153*536c2492SCaesar Wang 			      BITS_WITH_WMASK(clock_state, CLK_GATE_MASK,
1549901dcf6SCaesar Wang 					      PCLK_GPIO4_GATE_SHIFT));
1559901dcf6SCaesar Wang 		break;
1569901dcf6SCaesar Wang 	default:
1579901dcf6SCaesar Wang 		break;
1589901dcf6SCaesar Wang 	}
1599901dcf6SCaesar Wang }
1609901dcf6SCaesar Wang 
161*536c2492SCaesar Wang static int get_pull(int gpio)
1629901dcf6SCaesar Wang {
163*536c2492SCaesar Wang 	uint32_t port = GET_GPIO_PORT(gpio);
164*536c2492SCaesar Wang 	uint32_t bank = GET_GPIO_BANK(gpio);
165*536c2492SCaesar Wang 	uint32_t id = GET_GPIO_ID(gpio);
166*536c2492SCaesar Wang 	uint32_t val, clock_state;
1679901dcf6SCaesar Wang 
168*536c2492SCaesar Wang 	assert((port < 5) && (bank < 4));
1699901dcf6SCaesar Wang 
170*536c2492SCaesar Wang 	clock_state = gpio_get_clock(gpio);
171*536c2492SCaesar Wang 
172*536c2492SCaesar Wang 	if (port == PMU_GPIO_PORT0 || port == PMU_GPIO_PORT1) {
173*536c2492SCaesar Wang 		val = mmio_read_32(PMUGRF_BASE + PMU_GRF_GPIO0A_P +
174*536c2492SCaesar Wang 				   port * 16 + bank * 4);
175*536c2492SCaesar Wang 		val = (val >> (id * 2)) & GPIO_P_MASK;
176*536c2492SCaesar Wang 	} else {
177*536c2492SCaesar Wang 		val = mmio_read_32(GRF_BASE + GRF_GPIO2A_P +
178*536c2492SCaesar Wang 				   (port - 2) * 16 + bank * 4);
179*536c2492SCaesar Wang 		val = (val >> (id * 2)) & GPIO_P_MASK;
180*536c2492SCaesar Wang 	}
181*536c2492SCaesar Wang 	gpio_put_clock(gpio, clock_state);
1829901dcf6SCaesar Wang 
1839901dcf6SCaesar Wang 	/*
1849901dcf6SCaesar Wang 	 * in gpio0a, gpio0b, gpio2c, gpio2d,
1859901dcf6SCaesar Wang 	 * 00: Z
1869901dcf6SCaesar Wang 	 * 01: pull down
1879901dcf6SCaesar Wang 	 * 10: Z
1889901dcf6SCaesar Wang 	 * 11: pull up
1899901dcf6SCaesar Wang 	 * different with other gpio, so need to correct it
1909901dcf6SCaesar Wang 	 */
191*536c2492SCaesar Wang 	if (((port == 0) && (bank < 2)) || ((port == 2) && (bank > 1))) {
192*536c2492SCaesar Wang 		if (val == 3)
193*536c2492SCaesar Wang 			val = GPIO_PULL_UP;
194*536c2492SCaesar Wang 		else if (val == 1)
195*536c2492SCaesar Wang 			val = GPIO_PULL_DOWN;
196*536c2492SCaesar Wang 		else
197*536c2492SCaesar Wang 			val = 0;
198*536c2492SCaesar Wang 	}
199*536c2492SCaesar Wang 
200*536c2492SCaesar Wang 	return val;
201*536c2492SCaesar Wang }
202*536c2492SCaesar Wang 
203*536c2492SCaesar Wang static void set_pull(int gpio, int pull)
204*536c2492SCaesar Wang {
205*536c2492SCaesar Wang 	uint32_t port = GET_GPIO_PORT(gpio);
206*536c2492SCaesar Wang 	uint32_t bank = GET_GPIO_BANK(gpio);
207*536c2492SCaesar Wang 	uint32_t id = GET_GPIO_ID(gpio);
208*536c2492SCaesar Wang 	uint32_t clock_state;
209*536c2492SCaesar Wang 
210*536c2492SCaesar Wang 	assert((port < 5) && (bank < 4));
211*536c2492SCaesar Wang 
212*536c2492SCaesar Wang 	clock_state = gpio_get_clock(gpio);
213*536c2492SCaesar Wang 
214*536c2492SCaesar Wang 	/*
215*536c2492SCaesar Wang 	 * in gpio0a, gpio0b, gpio2c, gpio2d,
216*536c2492SCaesar Wang 	 * 00: Z
217*536c2492SCaesar Wang 	 * 01: pull down
218*536c2492SCaesar Wang 	 * 10: Z
219*536c2492SCaesar Wang 	 * 11: pull up
220*536c2492SCaesar Wang 	 * different with other gpio, so need to correct it
221*536c2492SCaesar Wang 	 */
222*536c2492SCaesar Wang 	if (((port == 0) && (bank < 2)) || ((port == 2) && (bank > 1))) {
2239901dcf6SCaesar Wang 		if (pull == GPIO_PULL_UP)
2249901dcf6SCaesar Wang 			pull = 3;
2259901dcf6SCaesar Wang 		else if (pull == GPIO_PULL_DOWN)
2269901dcf6SCaesar Wang 			pull = 1;
2279901dcf6SCaesar Wang 		else
2289901dcf6SCaesar Wang 			pull = 0;
2299901dcf6SCaesar Wang 	}
2309901dcf6SCaesar Wang 
2319901dcf6SCaesar Wang 	if (port == PMU_GPIO_PORT0 || port == PMU_GPIO_PORT1) {
2329901dcf6SCaesar Wang 		mmio_write_32(PMUGRF_BASE + PMU_GRF_GPIO0A_P +
2339901dcf6SCaesar Wang 			      port * 16 + bank * 4,
2349901dcf6SCaesar Wang 			      BITS_WITH_WMASK(pull, GPIO_P_MASK, id * 2));
2359901dcf6SCaesar Wang 	} else {
2369901dcf6SCaesar Wang 		mmio_write_32(GRF_BASE + GRF_GPIO2A_P +
2379901dcf6SCaesar Wang 			      (port - 2) * 16 + bank * 4,
2389901dcf6SCaesar Wang 			      BITS_WITH_WMASK(pull, GPIO_P_MASK, id * 2));
2399901dcf6SCaesar Wang 	}
240*536c2492SCaesar Wang 	gpio_put_clock(gpio, clock_state);
2419901dcf6SCaesar Wang }
2429901dcf6SCaesar Wang 
2439901dcf6SCaesar Wang static void set_direction(int gpio, int direction)
2449901dcf6SCaesar Wang {
245*536c2492SCaesar Wang 	uint32_t port = GET_GPIO_PORT(gpio);
246*536c2492SCaesar Wang 	uint32_t num = GET_GPIO_NUM(gpio);
247*536c2492SCaesar Wang 	uint32_t clock_state;
2489901dcf6SCaesar Wang 
2499901dcf6SCaesar Wang 	assert((port < 5) && (num < 32));
2509901dcf6SCaesar Wang 
251*536c2492SCaesar Wang 	clock_state = gpio_get_clock(gpio);
2529901dcf6SCaesar Wang 
2539901dcf6SCaesar Wang 	/*
2549901dcf6SCaesar Wang 	 * in gpio.h
2559901dcf6SCaesar Wang 	 * #define GPIO_DIR_OUT	0
2569901dcf6SCaesar Wang 	 * #define GPIO_DIR_IN	1
2579901dcf6SCaesar Wang 	 * but rk3399 gpio direction 1: output, 0: input
2589901dcf6SCaesar Wang 	 * so need to revert direction value
2599901dcf6SCaesar Wang 	 */
2609901dcf6SCaesar Wang 	mmio_setbits_32(gpio_port[port] + SWPORTA_DDR, !direction << num);
261*536c2492SCaesar Wang 	gpio_put_clock(gpio, clock_state);
2629901dcf6SCaesar Wang }
2639901dcf6SCaesar Wang 
2649901dcf6SCaesar Wang static int get_direction(int gpio)
2659901dcf6SCaesar Wang {
266*536c2492SCaesar Wang 	uint32_t port = GET_GPIO_PORT(gpio);
267*536c2492SCaesar Wang 	uint32_t num = GET_GPIO_NUM(gpio);
268*536c2492SCaesar Wang 	int direction, clock_state;
2699901dcf6SCaesar Wang 
2709901dcf6SCaesar Wang 	assert((port < 5) && (num < 32));
2719901dcf6SCaesar Wang 
272*536c2492SCaesar Wang 	clock_state = gpio_get_clock(gpio);
2739901dcf6SCaesar Wang 
2749901dcf6SCaesar Wang 	/*
2759901dcf6SCaesar Wang 	 * in gpio.h
2769901dcf6SCaesar Wang 	 * #define GPIO_DIR_OUT	0
2779901dcf6SCaesar Wang 	 * #define GPIO_DIR_IN	1
2789901dcf6SCaesar Wang 	 * but rk3399 gpio direction 1: output, 0: input
2799901dcf6SCaesar Wang 	 * so need to revert direction value
2809901dcf6SCaesar Wang 	 */
2819901dcf6SCaesar Wang 	direction = !((mmio_read_32(gpio_port[port] +
2829901dcf6SCaesar Wang 				    SWPORTA_DDR) >> num) & 0x1);
283*536c2492SCaesar Wang 	gpio_put_clock(gpio, clock_state);
2849901dcf6SCaesar Wang 
2859901dcf6SCaesar Wang 	return direction;
2869901dcf6SCaesar Wang }
2879901dcf6SCaesar Wang 
2889901dcf6SCaesar Wang static int get_value(int gpio)
2899901dcf6SCaesar Wang {
290*536c2492SCaesar Wang 	uint32_t port = GET_GPIO_PORT(gpio);
291*536c2492SCaesar Wang 	uint32_t num = GET_GPIO_NUM(gpio);
292*536c2492SCaesar Wang 	int value, clock_state;
2939901dcf6SCaesar Wang 
2949901dcf6SCaesar Wang 	assert((port < 5) && (num < 32));
2959901dcf6SCaesar Wang 
296*536c2492SCaesar Wang 	clock_state = gpio_get_clock(gpio);
2979901dcf6SCaesar Wang 	value = (mmio_read_32(gpio_port[port] + EXT_PORTA) >> num) & 0x1;
298*536c2492SCaesar Wang 	gpio_put_clock(gpio, clock_state);
2999901dcf6SCaesar Wang 
3009901dcf6SCaesar Wang 	return value;
3019901dcf6SCaesar Wang }
3029901dcf6SCaesar Wang 
3039901dcf6SCaesar Wang static void set_value(int gpio, int value)
3049901dcf6SCaesar Wang {
305*536c2492SCaesar Wang 	uint32_t port = GET_GPIO_PORT(gpio);
306*536c2492SCaesar Wang 	uint32_t num = GET_GPIO_NUM(gpio);
307*536c2492SCaesar Wang 	uint32_t clock_state;
3089901dcf6SCaesar Wang 
3099901dcf6SCaesar Wang 	assert((port < 5) && (num < 32));
3109901dcf6SCaesar Wang 
311*536c2492SCaesar Wang 	clock_state = gpio_get_clock(gpio);
3129901dcf6SCaesar Wang 	mmio_clrsetbits_32(gpio_port[port] + SWPORTA_DR, 1 << num,
3139901dcf6SCaesar Wang 							 !!value << num);
314*536c2492SCaesar Wang 	gpio_put_clock(gpio, clock_state);
3159901dcf6SCaesar Wang }
3169901dcf6SCaesar Wang 
3179901dcf6SCaesar Wang const gpio_ops_t rk3399_gpio_ops = {
3189901dcf6SCaesar Wang 	.get_direction = get_direction,
3199901dcf6SCaesar Wang 	.set_direction = set_direction,
3209901dcf6SCaesar Wang 	.get_value = get_value,
3219901dcf6SCaesar Wang 	.set_value = set_value,
3229901dcf6SCaesar Wang 	.set_pull = set_pull,
323*536c2492SCaesar Wang 	.get_pull = get_pull,
3249901dcf6SCaesar Wang };
3259901dcf6SCaesar Wang 
3269901dcf6SCaesar Wang void plat_rockchip_gpio_init(void)
3279901dcf6SCaesar Wang {
3289901dcf6SCaesar Wang 	gpio_init(&rk3399_gpio_ops);
3299901dcf6SCaesar Wang }
330