1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Pinctrl driver for Rockchip RK628
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 2019, Fuzhou Rockchip Electronics Co., Ltd
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Author: Weixin Zhou <zwx@rock-chips.com>
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Based on the pinctrl-rk805/pinctrl-rockchip driver
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/gpio/driver.h>
13*4882a593Smuzhiyun #include <linux/kernel.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/of.h>
16*4882a593Smuzhiyun #include <linux/of_device.h>
17*4882a593Smuzhiyun #include <linux/platform_device.h>
18*4882a593Smuzhiyun #include <linux/pinctrl/consumer.h>
19*4882a593Smuzhiyun #include <linux/pinctrl/machine.h>
20*4882a593Smuzhiyun #include <linux/pinctrl/pinctrl.h>
21*4882a593Smuzhiyun #include <linux/pinctrl/pinconf-generic.h>
22*4882a593Smuzhiyun #include <linux/pinctrl/pinconf.h>
23*4882a593Smuzhiyun #include <linux/pinctrl/pinmux.h>
24*4882a593Smuzhiyun #include <linux/pm.h>
25*4882a593Smuzhiyun #include <linux/slab.h>
26*4882a593Smuzhiyun #include <linux/clk.h>
27*4882a593Smuzhiyun #include <linux/interrupt.h>
28*4882a593Smuzhiyun #include <linux/regmap.h>
29*4882a593Smuzhiyun #include <linux/mfd/rk628.h>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include "core.h"
32*4882a593Smuzhiyun #include "pinconf.h"
33*4882a593Smuzhiyun #include "pinctrl-utils.h"
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #define GPIO0_BASE 0xD0000
36*4882a593Smuzhiyun #define GPIO1_BASE 0xE0000
37*4882a593Smuzhiyun #define GPIO2_BASE 0xF0000
38*4882a593Smuzhiyun #define GPIO3_BASE 0x100000
39*4882a593Smuzhiyun #define GPIO_MAX_REGISTER (GPIO3_BASE + GPIO_VER_ID)
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun /* GPIO control registers */
42*4882a593Smuzhiyun #define GPIO_SWPORT_DR_L 0x00
43*4882a593Smuzhiyun #define GPIO_SWPORT_DR_H 0x04
44*4882a593Smuzhiyun #define GPIO_SWPORT_DDR_L 0x08
45*4882a593Smuzhiyun #define GPIO_SWPORT_DDR_H 0x0c
46*4882a593Smuzhiyun #define GPIO_INTEN_L 0x10
47*4882a593Smuzhiyun #define GPIO_INTEN_H 0x14
48*4882a593Smuzhiyun #define GPIO_INTMASK_L 0x18
49*4882a593Smuzhiyun #define GPIO_INTMASK_H 0x1c
50*4882a593Smuzhiyun #define GPIO_INTTYPE_L 0x20
51*4882a593Smuzhiyun #define GPIO_INTTYPE_H 0x24
52*4882a593Smuzhiyun #define GPIO_INT_POLARITY_L 0x28
53*4882a593Smuzhiyun #define GPIO_INT_POLARITY_H 0x2c
54*4882a593Smuzhiyun #define GPIO_INT_BOTHEDGE_L 0x30
55*4882a593Smuzhiyun #define GPIO_INT_BOTHEDGE_H 0x34
56*4882a593Smuzhiyun #define GPIO_DEBOUNCE_L 0x38
57*4882a593Smuzhiyun #define GPIO_DEBOUNCE_H 0x3c
58*4882a593Smuzhiyun #define GPIO_DBCLK_DIV_EN_L 0x40
59*4882a593Smuzhiyun #define GPIO_DBCLK_DIV_EN_H 0x44
60*4882a593Smuzhiyun #define GPIO_INT_STATUS 0x50
61*4882a593Smuzhiyun #define GPIO_INT_RAWSTATUS 0x58
62*4882a593Smuzhiyun #define GPIO_PORTS_EOI_L 0x60
63*4882a593Smuzhiyun #define GPIO_PORTS_EOI_H 0x64
64*4882a593Smuzhiyun #define GPIO_EXT_PORT 0x70
65*4882a593Smuzhiyun #define GPIO_VER_ID 0x78
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun #define GPIO_REG_LOW 0x0
68*4882a593Smuzhiyun #define GPIO_REG_HIGH 0x1
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /* GPIO control registers */
71*4882a593Smuzhiyun #define GPIO_INTMASK 0x34
72*4882a593Smuzhiyun #define GPIO_PORTS_EOI 0x4c
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun #define BANK_OFFSET 32
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun #define IRQ_CHIP(fname) \
77*4882a593Smuzhiyun [IRQCHIP_##fname] = { \
78*4882a593Smuzhiyun .name = "rk628-"#fname, \
79*4882a593Smuzhiyun .irq_bus_lock = rk628_irq_lock, \
80*4882a593Smuzhiyun .irq_bus_sync_unlock = rk628_irq_sync_unlock,\
81*4882a593Smuzhiyun .irq_disable = rk628_irq_disable, \
82*4882a593Smuzhiyun .irq_enable = rk628_irq_enable, \
83*4882a593Smuzhiyun .irq_set_type = rk628_irq_set_type, \
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun struct rk628_pin_function {
87*4882a593Smuzhiyun const char *name;
88*4882a593Smuzhiyun const char **groups;
89*4882a593Smuzhiyun unsigned int ngroups;
90*4882a593Smuzhiyun int mux_option;
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun struct rk628_pin_group {
94*4882a593Smuzhiyun const char *name;
95*4882a593Smuzhiyun const unsigned int pins[1];
96*4882a593Smuzhiyun unsigned int npins;
97*4882a593Smuzhiyun int iomux_base;
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun struct rk628_pin_bank {
101*4882a593Smuzhiyun char *name;
102*4882a593Smuzhiyun u32 reg_base;
103*4882a593Smuzhiyun u32 nr_pins;
104*4882a593Smuzhiyun struct device_node *of_node;
105*4882a593Smuzhiyun struct pinctrl_gpio_range grange;
106*4882a593Smuzhiyun struct gpio_chip gpio_chip;
107*4882a593Smuzhiyun struct clk *clk;
108*4882a593Smuzhiyun struct rk628_pctrl_info *pci;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun struct irq_chip irq_chip;
111*4882a593Smuzhiyun struct irq_domain *domain;
112*4882a593Smuzhiyun int irq;
113*4882a593Smuzhiyun struct mutex lock;
114*4882a593Smuzhiyun unsigned int mask_regs[2];
115*4882a593Smuzhiyun unsigned int polarity_regs[2];
116*4882a593Smuzhiyun unsigned int level_regs[2];
117*4882a593Smuzhiyun unsigned int bothedge_regs[2];
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun struct rk628_pctrl_info {
121*4882a593Smuzhiyun struct device *dev;
122*4882a593Smuzhiyun struct pinctrl_dev *pctl;
123*4882a593Smuzhiyun struct pinctrl_desc pinctrl_desc;
124*4882a593Smuzhiyun const struct rk628_pin_function *functions;
125*4882a593Smuzhiyun unsigned int num_functions;
126*4882a593Smuzhiyun const struct rk628_pin_group *groups;
127*4882a593Smuzhiyun int num_groups;
128*4882a593Smuzhiyun const struct pinctrl_pin_desc *pins;
129*4882a593Smuzhiyun unsigned int num_pins;
130*4882a593Smuzhiyun struct regmap *regmap;
131*4882a593Smuzhiyun struct regmap *grf_regmap;
132*4882a593Smuzhiyun struct rk628_pin_bank *pin_banks;
133*4882a593Smuzhiyun u32 nr_banks;
134*4882a593Smuzhiyun };
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun enum rk628_pinmux_option {
137*4882a593Smuzhiyun PINMUX_FUNC0,
138*4882a593Smuzhiyun PINMUX_FUNC1,
139*4882a593Smuzhiyun };
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun #define PINCTRL_GROUP(a, b, c, d) { .name = a, .pins = b, .npins = c, .iomux_base = d}
142*4882a593Smuzhiyun #define PINCTRL_BANK(a, b, c) { .name = a, .reg_base = b, .nr_pins = c}
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun enum rk628_functions {
145*4882a593Smuzhiyun MUX_GPIO,
146*4882a593Smuzhiyun };
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun static const char *gpio_groups[] = {
149*4882a593Smuzhiyun "gpio0a0", "gpio0a1", "gpio0a2", "gpio0a3", "gpio0a4", "gpio0a5",
150*4882a593Smuzhiyun "gpio0a6", "gpio0a7", "gpio0b0", "gpio0b1", "gpio0b2", "gpio0b3",
151*4882a593Smuzhiyun "gpio1a0", "gpio1a1", "gpio1a2", "gpio1a3", "gpio1a4", "gpio1a5",
152*4882a593Smuzhiyun "gpio1a6", "gpio1a7", "gpio1b0", "gpio1b1", "gpio1b2", "gpio1b3",
153*4882a593Smuzhiyun "gpio1b4", "gpio1b5",
154*4882a593Smuzhiyun "gpio2a0", "gpio2a1", "gpio2a2", "gpio2a3", "gpio2a4", "gpio2a5",
155*4882a593Smuzhiyun "gpio2a6", "gpio2a7", "gpio2b0", "gpio2b1", "gpio2b2", "gpio2b3",
156*4882a593Smuzhiyun "gpio2b4", "gpio2b5", "gpio2b6", "gpio2b7", "gpio2c0", "gpio2c1",
157*4882a593Smuzhiyun "gpio2c3", "gpio2c4", "gpio2c5", "gpio2c6", "gpio2c7", "gpio1a0",
158*4882a593Smuzhiyun "gpio3a1", "gpio3a2", "gpio3a3", "gpio3a4", "gpio3a5", "gpio3a6",
159*4882a593Smuzhiyun "gpio3a7", "gpio3b0", "gpio3b1", "gpio3b2", "gpio3b3", "gpio3b4",
160*4882a593Smuzhiyun };
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun static struct rk628_pin_function rk628_functions[] = {
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun .name = "gpio",
165*4882a593Smuzhiyun .groups = gpio_groups,
166*4882a593Smuzhiyun .ngroups = ARRAY_SIZE(gpio_groups),
167*4882a593Smuzhiyun },
168*4882a593Smuzhiyun };
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun enum {
171*4882a593Smuzhiyun GPIO_HIGH_Z,
172*4882a593Smuzhiyun GPIO_PULL_UP,
173*4882a593Smuzhiyun GPIO_PULL_DOWN,
174*4882a593Smuzhiyun };
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun enum {
177*4882a593Smuzhiyun GPIO0_A0 = BANK_OFFSET * 0,
178*4882a593Smuzhiyun GPIO0_A1,
179*4882a593Smuzhiyun GPIO0_A2,
180*4882a593Smuzhiyun GPIO0_A3,
181*4882a593Smuzhiyun GPIO0_A4,
182*4882a593Smuzhiyun GPIO0_A5,
183*4882a593Smuzhiyun GPIO0_A6,
184*4882a593Smuzhiyun GPIO0_A7,
185*4882a593Smuzhiyun GPIO0_B0,
186*4882a593Smuzhiyun GPIO0_B1,
187*4882a593Smuzhiyun GPIO0_B2,
188*4882a593Smuzhiyun GPIO0_B3,
189*4882a593Smuzhiyun GPIO1_A0 = BANK_OFFSET * 1,
190*4882a593Smuzhiyun GPIO1_A1,
191*4882a593Smuzhiyun GPIO1_A2,
192*4882a593Smuzhiyun GPIO1_A3,
193*4882a593Smuzhiyun GPIO1_A4,
194*4882a593Smuzhiyun GPIO1_A5,
195*4882a593Smuzhiyun GPIO1_A6,
196*4882a593Smuzhiyun GPIO1_A7,
197*4882a593Smuzhiyun GPIO1_B0,
198*4882a593Smuzhiyun GPIO1_B1,
199*4882a593Smuzhiyun GPIO1_B2,
200*4882a593Smuzhiyun GPIO1_B3,
201*4882a593Smuzhiyun GPIO1_B4,
202*4882a593Smuzhiyun GPIO1_B5,
203*4882a593Smuzhiyun GPIO2_A0 = BANK_OFFSET * 2,
204*4882a593Smuzhiyun GPIO2_A1,
205*4882a593Smuzhiyun GPIO2_A2,
206*4882a593Smuzhiyun GPIO2_A3,
207*4882a593Smuzhiyun GPIO2_A4,
208*4882a593Smuzhiyun GPIO2_A5,
209*4882a593Smuzhiyun GPIO2_A6,
210*4882a593Smuzhiyun GPIO2_A7,
211*4882a593Smuzhiyun GPIO2_B0,
212*4882a593Smuzhiyun GPIO2_B1,
213*4882a593Smuzhiyun GPIO2_B2,
214*4882a593Smuzhiyun GPIO2_B3,
215*4882a593Smuzhiyun GPIO2_B4,
216*4882a593Smuzhiyun GPIO2_B5,
217*4882a593Smuzhiyun GPIO2_B6,
218*4882a593Smuzhiyun GPIO2_B7,
219*4882a593Smuzhiyun GPIO2_C0,
220*4882a593Smuzhiyun GPIO2_C1,
221*4882a593Smuzhiyun GPIO2_C2,
222*4882a593Smuzhiyun GPIO2_C3,
223*4882a593Smuzhiyun GPIO2_C4,
224*4882a593Smuzhiyun GPIO2_C5,
225*4882a593Smuzhiyun GPIO2_C6,
226*4882a593Smuzhiyun GPIO2_C7,
227*4882a593Smuzhiyun GPIO3_A0 = BANK_OFFSET * 3,
228*4882a593Smuzhiyun GPIO3_A1,
229*4882a593Smuzhiyun GPIO3_A2,
230*4882a593Smuzhiyun GPIO3_A3,
231*4882a593Smuzhiyun GPIO3_A4,
232*4882a593Smuzhiyun GPIO3_A5,
233*4882a593Smuzhiyun GPIO3_A6,
234*4882a593Smuzhiyun GPIO3_A7,
235*4882a593Smuzhiyun GPIO3_B0,
236*4882a593Smuzhiyun GPIO3_B1,
237*4882a593Smuzhiyun GPIO3_B2,
238*4882a593Smuzhiyun GPIO3_B3,
239*4882a593Smuzhiyun GPIO3_B4,
240*4882a593Smuzhiyun I2SM_SCK = BANK_OFFSET * 4 + 2,
241*4882a593Smuzhiyun I2SM_D,
242*4882a593Smuzhiyun I2SM_LR,
243*4882a593Smuzhiyun RXDDC_SCL,
244*4882a593Smuzhiyun RXDDC_SDA,
245*4882a593Smuzhiyun HDMIRX_CE,
246*4882a593Smuzhiyun };
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun static struct pinctrl_pin_desc rk628_pins_desc[] = {
249*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_A0, "gpio0a0"),
250*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_A1, "gpio0a1"),
251*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_A2, "gpio0a2"),
252*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_A3, "gpio0a3"),
253*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_A4, "gpio0a4"),
254*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_A5, "gpio0a5"),
255*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_A6, "gpio0a6"),
256*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_A7, "gpio0a7"),
257*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_B0, "gpio0b0"),
258*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_B1, "gpio0b1"),
259*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_B2, "gpio0b2"),
260*4882a593Smuzhiyun PINCTRL_PIN(GPIO0_B3, "gpio0b3"),
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_A0, "gpio1a0"),
263*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_A1, "gpio1a1"),
264*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_A2, "gpio1a2"),
265*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_A3, "gpio1a3"),
266*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_A4, "gpio1a4"),
267*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_A5, "gpio1a5"),
268*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_A6, "gpio1a6"),
269*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_A7, "gpio1a7"),
270*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_B0, "gpio1b0"),
271*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_B1, "gpio1b1"),
272*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_B2, "gpio1b2"),
273*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_B3, "gpio1b3"),
274*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_B4, "gpio1b4"),
275*4882a593Smuzhiyun PINCTRL_PIN(GPIO1_B5, "gpio1b5"),
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_A0, "gpio2a0"),
278*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_A1, "gpio2a1"),
279*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_A2, "gpio2a2"),
280*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_A3, "gpio2a3"),
281*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_A4, "gpio2a4"),
282*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_A5, "gpio2a5"),
283*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_A6, "gpio2a6"),
284*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_A7, "gpio2a7"),
285*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_B0, "gpio2b0"),
286*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_B1, "gpio2b1"),
287*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_B2, "gpio2b2"),
288*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_B3, "gpio2b3"),
289*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_B4, "gpio2b4"),
290*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_B5, "gpio2b5"),
291*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_B6, "gpio2b6"),
292*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_B7, "gpio2b7"),
293*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_C0, "gpio2c0"),
294*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_C1, "gpio2c1"),
295*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_C2, "gpio2c2"),
296*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_C3, "gpio2c3"),
297*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_C4, "gpio2c4"),
298*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_C5, "gpio2c5"),
299*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_C6, "gpio2c6"),
300*4882a593Smuzhiyun PINCTRL_PIN(GPIO2_C7, "gpio2c7"),
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_A0, "gpio3a0"),
303*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_A1, "gpio3a1"),
304*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_A2, "gpio3a2"),
305*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_A3, "gpio3a3"),
306*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_A4, "gpio3a4"),
307*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_A5, "gpio3a5"),
308*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_A6, "gpio3a6"),
309*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_A7, "gpio3a7"),
310*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_B0, "gpio3b0"),
311*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_B1, "gpio3b1"),
312*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_B2, "gpio3b2"),
313*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_B3, "gpio3b3"),
314*4882a593Smuzhiyun PINCTRL_PIN(GPIO3_B4, "gpio3b4"),
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun PINCTRL_PIN(I2SM_SCK, "i2sm_sck"),
317*4882a593Smuzhiyun PINCTRL_PIN(I2SM_D, "i2sm_d"),
318*4882a593Smuzhiyun PINCTRL_PIN(I2SM_LR, "i2sm_lr"),
319*4882a593Smuzhiyun PINCTRL_PIN(RXDDC_SCL, "rxddc_scl"),
320*4882a593Smuzhiyun PINCTRL_PIN(RXDDC_SDA, "rxddc_sda"),
321*4882a593Smuzhiyun PINCTRL_PIN(HDMIRX_CE, "hdmirx_cec"),
322*4882a593Smuzhiyun };
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun static const struct rk628_pin_group rk628_pin_groups[] = {
325*4882a593Smuzhiyun PINCTRL_GROUP("gpio0a0", { GPIO0_A0 }, 1, GRF_GPIO0AB_SEL_CON),
326*4882a593Smuzhiyun PINCTRL_GROUP("gpio0a1", { GPIO0_A1 }, 1, GRF_GPIO0AB_SEL_CON),
327*4882a593Smuzhiyun PINCTRL_GROUP("gpio0a2", { GPIO0_A2 }, 1, GRF_GPIO0AB_SEL_CON),
328*4882a593Smuzhiyun PINCTRL_GROUP("gpio0a3", { GPIO0_A3 }, 1, GRF_GPIO0AB_SEL_CON),
329*4882a593Smuzhiyun PINCTRL_GROUP("gpio0a4", { GPIO0_A4 }, 1, GRF_GPIO0AB_SEL_CON),
330*4882a593Smuzhiyun PINCTRL_GROUP("gpio0a5", { GPIO0_A5 }, 1, GRF_GPIO0AB_SEL_CON),
331*4882a593Smuzhiyun PINCTRL_GROUP("gpio0a6", { GPIO0_A6 }, 1, GRF_GPIO0AB_SEL_CON),
332*4882a593Smuzhiyun PINCTRL_GROUP("gpio0a7", { GPIO0_A7 }, 1, GRF_GPIO0AB_SEL_CON),
333*4882a593Smuzhiyun PINCTRL_GROUP("gpio0b0", { GPIO0_B0 }, 1, GRF_GPIO0AB_SEL_CON),
334*4882a593Smuzhiyun PINCTRL_GROUP("gpio0b1", { GPIO0_B1 }, 1, GRF_GPIO0AB_SEL_CON),
335*4882a593Smuzhiyun PINCTRL_GROUP("gpio0b2", { GPIO0_B2 }, 1, GRF_GPIO0AB_SEL_CON),
336*4882a593Smuzhiyun PINCTRL_GROUP("gpio0b3", { GPIO0_B3 }, 1, GRF_GPIO0AB_SEL_CON),
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun PINCTRL_GROUP("gpio1a0", { GPIO1_A0 }, 1, GRF_GPIO1AB_SEL_CON),
339*4882a593Smuzhiyun PINCTRL_GROUP("gpio1a1", { GPIO1_A1 }, 1, GRF_GPIO1AB_SEL_CON),
340*4882a593Smuzhiyun PINCTRL_GROUP("gpio1a2", { GPIO1_A2 }, 1, GRF_GPIO1AB_SEL_CON),
341*4882a593Smuzhiyun PINCTRL_GROUP("gpio1a3", { GPIO1_A3 }, 1, GRF_GPIO1AB_SEL_CON),
342*4882a593Smuzhiyun PINCTRL_GROUP("gpio1a4", { GPIO1_A4 }, 1, GRF_GPIO1AB_SEL_CON),
343*4882a593Smuzhiyun PINCTRL_GROUP("gpio1a5", { GPIO1_A5 }, 1, GRF_GPIO1AB_SEL_CON),
344*4882a593Smuzhiyun PINCTRL_GROUP("gpio1a6", { GPIO1_A6 }, 1, GRF_GPIO1AB_SEL_CON),
345*4882a593Smuzhiyun PINCTRL_GROUP("gpio1a7", { GPIO1_A7 }, 1, GRF_GPIO1AB_SEL_CON),
346*4882a593Smuzhiyun PINCTRL_GROUP("gpio1b0", { GPIO1_B0 }, 1, GRF_GPIO1AB_SEL_CON),
347*4882a593Smuzhiyun PINCTRL_GROUP("gpio1b1", { GPIO1_B1 }, 1, GRF_GPIO1AB_SEL_CON),
348*4882a593Smuzhiyun PINCTRL_GROUP("gpio1b2", { GPIO1_B2 }, 1, GRF_GPIO1AB_SEL_CON),
349*4882a593Smuzhiyun PINCTRL_GROUP("gpio1b3", { GPIO1_B3 }, 1, GRF_GPIO1AB_SEL_CON),
350*4882a593Smuzhiyun PINCTRL_GROUP("gpio1b4", { GPIO1_B4 }, 1, GRF_GPIO1AB_SEL_CON),
351*4882a593Smuzhiyun PINCTRL_GROUP("gpio1b5", { GPIO1_B5 }, 1, GRF_GPIO1AB_SEL_CON),
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun PINCTRL_GROUP("gpio2a0", { GPIO2_A0 }, 1, GRF_GPIO2AB_SEL_CON),
354*4882a593Smuzhiyun PINCTRL_GROUP("gpio2a1", { GPIO2_A1 }, 1, GRF_GPIO2AB_SEL_CON),
355*4882a593Smuzhiyun PINCTRL_GROUP("gpio2a2", { GPIO2_A2 }, 1, GRF_GPIO2AB_SEL_CON),
356*4882a593Smuzhiyun PINCTRL_GROUP("gpio2a3", { GPIO2_A3 }, 1, GRF_GPIO2AB_SEL_CON),
357*4882a593Smuzhiyun PINCTRL_GROUP("gpio2a4", { GPIO2_A4 }, 1, GRF_GPIO2AB_SEL_CON),
358*4882a593Smuzhiyun PINCTRL_GROUP("gpio2a5", { GPIO2_A5 }, 1, GRF_GPIO2AB_SEL_CON),
359*4882a593Smuzhiyun PINCTRL_GROUP("gpio2a6", { GPIO2_A6 }, 1, GRF_GPIO2AB_SEL_CON),
360*4882a593Smuzhiyun PINCTRL_GROUP("gpio2a7", { GPIO2_A7 }, 1, GRF_GPIO2AB_SEL_CON),
361*4882a593Smuzhiyun PINCTRL_GROUP("gpio2b0", { GPIO2_B0 }, 1, GRF_GPIO2AB_SEL_CON),
362*4882a593Smuzhiyun PINCTRL_GROUP("gpio2b1", { GPIO2_B1 }, 1, GRF_GPIO2AB_SEL_CON),
363*4882a593Smuzhiyun PINCTRL_GROUP("gpio2b2", { GPIO2_B2 }, 1, GRF_GPIO2AB_SEL_CON),
364*4882a593Smuzhiyun PINCTRL_GROUP("gpio2b3", { GPIO2_B3 }, 1, GRF_GPIO2AB_SEL_CON),
365*4882a593Smuzhiyun PINCTRL_GROUP("gpio2b4", { GPIO2_B4 }, 1, GRF_GPIO2AB_SEL_CON),
366*4882a593Smuzhiyun PINCTRL_GROUP("gpio2b5", { GPIO2_B5 }, 1, GRF_GPIO2AB_SEL_CON),
367*4882a593Smuzhiyun PINCTRL_GROUP("gpio2b6", { GPIO2_B6 }, 1, GRF_GPIO2AB_SEL_CON),
368*4882a593Smuzhiyun PINCTRL_GROUP("gpio2b7", { GPIO2_B7 }, 1, GRF_GPIO2AB_SEL_CON),
369*4882a593Smuzhiyun PINCTRL_GROUP("gpio2c0", { GPIO2_C0 }, 1, GRF_GPIO2C_SEL_CON),
370*4882a593Smuzhiyun PINCTRL_GROUP("gpio2c1", { GPIO2_C1 }, 1, GRF_GPIO2C_SEL_CON),
371*4882a593Smuzhiyun PINCTRL_GROUP("gpio2c2", { GPIO2_C2 }, 1, GRF_GPIO2C_SEL_CON),
372*4882a593Smuzhiyun PINCTRL_GROUP("gpio2c3", { GPIO2_C3 }, 1, GRF_GPIO2C_SEL_CON),
373*4882a593Smuzhiyun PINCTRL_GROUP("gpio2c4", { GPIO2_C4 }, 1, GRF_GPIO2C_SEL_CON),
374*4882a593Smuzhiyun PINCTRL_GROUP("gpio2c5", { GPIO2_C5 }, 1, GRF_GPIO2C_SEL_CON),
375*4882a593Smuzhiyun PINCTRL_GROUP("gpio2c6", { GPIO2_C6 }, 1, GRF_GPIO2C_SEL_CON),
376*4882a593Smuzhiyun PINCTRL_GROUP("gpio2c7", { GPIO2_C7 }, 1, GRF_GPIO2C_SEL_CON),
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun PINCTRL_GROUP("gpio3a0", { GPIO3_A0 }, 1, GRF_GPIO3AB_SEL_CON),
379*4882a593Smuzhiyun PINCTRL_GROUP("gpio3a1", { GPIO3_A1 }, 1, GRF_GPIO3AB_SEL_CON),
380*4882a593Smuzhiyun PINCTRL_GROUP("gpio3a2", { GPIO3_A2 }, 1, GRF_GPIO3AB_SEL_CON),
381*4882a593Smuzhiyun PINCTRL_GROUP("gpio3a3", { GPIO3_A3 }, 1, GRF_GPIO3AB_SEL_CON),
382*4882a593Smuzhiyun PINCTRL_GROUP("gpio3a4", { GPIO3_A4 }, 1, GRF_GPIO3AB_SEL_CON),
383*4882a593Smuzhiyun PINCTRL_GROUP("gpio3a5", { GPIO3_A5 }, 1, GRF_GPIO3AB_SEL_CON),
384*4882a593Smuzhiyun PINCTRL_GROUP("gpio3a6", { GPIO3_A6 }, 1, GRF_GPIO3AB_SEL_CON),
385*4882a593Smuzhiyun PINCTRL_GROUP("gpio3a7", { GPIO3_A7 }, 1, GRF_GPIO3AB_SEL_CON),
386*4882a593Smuzhiyun PINCTRL_GROUP("gpio3b0", { GPIO3_B0 }, 1, GRF_GPIO3AB_SEL_CON),
387*4882a593Smuzhiyun PINCTRL_GROUP("gpio3b1", { GPIO3_B1 }, 1, GRF_GPIO3AB_SEL_CON),
388*4882a593Smuzhiyun PINCTRL_GROUP("gpio3b2", { GPIO3_B2 }, 1, GRF_GPIO3AB_SEL_CON),
389*4882a593Smuzhiyun PINCTRL_GROUP("gpio3b3", { GPIO3_B3 }, 1, GRF_GPIO3AB_SEL_CON),
390*4882a593Smuzhiyun PINCTRL_GROUP("gpio3b4", { GPIO3_B4 }, 1, GRF_GPIO3AB_SEL_CON),
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun PINCTRL_GROUP("i2sm_sck", { I2SM_SCK }, 1, GRF_SYSTEM_CON3),
393*4882a593Smuzhiyun PINCTRL_GROUP("i2sm_d", { I2SM_D }, 1, GRF_SYSTEM_CON3),
394*4882a593Smuzhiyun PINCTRL_GROUP("i2sm_lr", { I2SM_LR }, 1, GRF_SYSTEM_CON3),
395*4882a593Smuzhiyun PINCTRL_GROUP("rxddc_scl", { RXDDC_SCL }, 1, GRF_SYSTEM_CON3),
396*4882a593Smuzhiyun PINCTRL_GROUP("rxddc_sda", { RXDDC_SDA }, 1, GRF_SYSTEM_CON3),
397*4882a593Smuzhiyun PINCTRL_GROUP("hdmirx_cec", { HDMIRX_CE }, 1, GRF_SYSTEM_CON3),
398*4882a593Smuzhiyun };
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun static struct rk628_pin_bank rk628_pin_banks[] = {
401*4882a593Smuzhiyun PINCTRL_BANK("rk628-gpio0", GPIO0_BASE, 12),
402*4882a593Smuzhiyun PINCTRL_BANK("rk628-gpio1", GPIO1_BASE, 14),
403*4882a593Smuzhiyun PINCTRL_BANK("rk628-gpio2", GPIO2_BASE, 24),
404*4882a593Smuzhiyun PINCTRL_BANK("rk628-gpio3", GPIO3_BASE, 13),
405*4882a593Smuzhiyun };
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun /* generic gpio chip */
rk628_gpio_get(struct gpio_chip * chip,unsigned int offset)408*4882a593Smuzhiyun static int rk628_gpio_get(struct gpio_chip *chip, unsigned int offset)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun struct rk628_pin_bank *bank = gpiochip_get_data(chip);
411*4882a593Smuzhiyun struct rk628_pctrl_info *pci = bank->pci;
412*4882a593Smuzhiyun int data_reg, val, ret;
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun data_reg = bank->reg_base + GPIO_EXT_PORT;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun clk_enable(bank->clk);
417*4882a593Smuzhiyun ret = regmap_read(pci->regmap, data_reg, &val);
418*4882a593Smuzhiyun if (ret)
419*4882a593Smuzhiyun dev_err(pci->dev, "%s: regmap read failed!\n", __func__);
420*4882a593Smuzhiyun clk_disable(bank->clk);
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun val >>= offset;
423*4882a593Smuzhiyun val &= 1;
424*4882a593Smuzhiyun dev_dbg(pci->dev, "%s bank->name=%s dir_reg=0x%x offset=%x value=%x\n",
425*4882a593Smuzhiyun __func__, bank->name, data_reg, offset, val);
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun return val;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
rk628_gpio_set(struct gpio_chip * chip,unsigned int offset,int value)430*4882a593Smuzhiyun static void rk628_gpio_set(struct gpio_chip *chip,
431*4882a593Smuzhiyun unsigned int offset,
432*4882a593Smuzhiyun int value)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun struct rk628_pin_bank *bank = gpiochip_get_data(chip);
435*4882a593Smuzhiyun struct rk628_pctrl_info *pci = bank->pci;
436*4882a593Smuzhiyun int data_reg, val, ret;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun if (offset / 16) {
439*4882a593Smuzhiyun data_reg = bank->reg_base + GPIO_SWPORT_DR_H;
440*4882a593Smuzhiyun offset -= 16;
441*4882a593Smuzhiyun } else {
442*4882a593Smuzhiyun data_reg = bank->reg_base + GPIO_SWPORT_DR_L;
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun if (value)
445*4882a593Smuzhiyun val = BIT(offset + 16) | BIT(offset);
446*4882a593Smuzhiyun else
447*4882a593Smuzhiyun val = BIT(offset + 16) | (0xffff & ~BIT(offset));
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun clk_enable(bank->clk);
450*4882a593Smuzhiyun ret = regmap_write(pci->regmap, data_reg, val);
451*4882a593Smuzhiyun if (ret)
452*4882a593Smuzhiyun pr_err("%s: regmap write failed! bank->name=%s data_reg=0x%x offset=%d\n",
453*4882a593Smuzhiyun __func__, bank->name, data_reg, offset);
454*4882a593Smuzhiyun clk_disable(bank->clk);
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun
rk628_gpio_direction_input(struct gpio_chip * chip,unsigned int offset)457*4882a593Smuzhiyun static int rk628_gpio_direction_input(struct gpio_chip *chip,
458*4882a593Smuzhiyun unsigned int offset)
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun return pinctrl_gpio_direction_input(chip->base + offset);
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun
rk628_gpio_direction_output(struct gpio_chip * chip,unsigned int offset,int value)463*4882a593Smuzhiyun static int rk628_gpio_direction_output(struct gpio_chip *chip,
464*4882a593Smuzhiyun unsigned int offset,
465*4882a593Smuzhiyun int value)
466*4882a593Smuzhiyun {
467*4882a593Smuzhiyun rk628_gpio_set(chip, offset, value);
468*4882a593Smuzhiyun return pinctrl_gpio_direction_output(chip->base + offset);
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
rk628_gpio_get_direction(struct gpio_chip * chip,unsigned int offset)471*4882a593Smuzhiyun static int rk628_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun struct rk628_pin_bank *bank = gpiochip_get_data(chip);
474*4882a593Smuzhiyun struct rk628_pctrl_info *pci = bank->pci;
475*4882a593Smuzhiyun int dir_reg, val, ret;
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun if (offset / 16) {
478*4882a593Smuzhiyun dir_reg = bank->reg_base + GPIO_SWPORT_DDR_H;
479*4882a593Smuzhiyun offset -= 16;
480*4882a593Smuzhiyun } else {
481*4882a593Smuzhiyun dir_reg = bank->reg_base + GPIO_SWPORT_DDR_L;
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun clk_enable(bank->clk);
485*4882a593Smuzhiyun ret = regmap_read(pci->regmap, dir_reg, &val);
486*4882a593Smuzhiyun if (ret)
487*4882a593Smuzhiyun dev_err(pci->dev, "%s: regmap read failed!\n", __func__);
488*4882a593Smuzhiyun clk_disable(bank->clk);
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun val = BIT(offset) & val;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun return !val;
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun
rk628_gpio_to_irq(struct gpio_chip * gc,unsigned offset)495*4882a593Smuzhiyun static int rk628_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
496*4882a593Smuzhiyun {
497*4882a593Smuzhiyun struct rk628_pin_bank *bank = gpiochip_get_data(gc);
498*4882a593Smuzhiyun int virq;
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun if (!bank->domain)
501*4882a593Smuzhiyun return -ENXIO;
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun virq = irq_create_mapping(bank->domain, offset);
504*4882a593Smuzhiyun if (!virq)
505*4882a593Smuzhiyun pr_err("map interruptr fail, bank->irq=%d\n", bank->irq);
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun return (virq) ? : -ENXIO;
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun static struct gpio_chip rk628_gpiolib_chip = {
511*4882a593Smuzhiyun .label = "rk628-gpio",
512*4882a593Smuzhiyun .request = gpiochip_generic_request,
513*4882a593Smuzhiyun .free = gpiochip_generic_free,
514*4882a593Smuzhiyun .get_direction = rk628_gpio_get_direction,
515*4882a593Smuzhiyun .get = rk628_gpio_get,
516*4882a593Smuzhiyun .set = rk628_gpio_set,
517*4882a593Smuzhiyun .direction_input = rk628_gpio_direction_input,
518*4882a593Smuzhiyun .direction_output = rk628_gpio_direction_output,
519*4882a593Smuzhiyun .to_irq = rk628_gpio_to_irq,
520*4882a593Smuzhiyun .can_sleep = true,
521*4882a593Smuzhiyun .base = -1,
522*4882a593Smuzhiyun .owner = THIS_MODULE,
523*4882a593Smuzhiyun };
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun /* generic pinctrl */
rk628_pinctrl_get_groups_count(struct pinctrl_dev * pctldev)526*4882a593Smuzhiyun static int rk628_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
527*4882a593Smuzhiyun {
528*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun return pci->num_groups;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun
rk628_pinctrl_get_group_name(struct pinctrl_dev * pctldev,unsigned int group)533*4882a593Smuzhiyun static const char *rk628_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
534*4882a593Smuzhiyun unsigned int group)
535*4882a593Smuzhiyun {
536*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun return pci->groups[group].name;
539*4882a593Smuzhiyun }
540*4882a593Smuzhiyun
rk628_pinctrl_get_group_pins(struct pinctrl_dev * pctldev,unsigned int group,const unsigned int ** pins,unsigned int * num_pins)541*4882a593Smuzhiyun static int rk628_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
542*4882a593Smuzhiyun unsigned int group,
543*4882a593Smuzhiyun const unsigned int **pins,
544*4882a593Smuzhiyun unsigned int *num_pins)
545*4882a593Smuzhiyun {
546*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun *pins = pci->groups[group].pins;
549*4882a593Smuzhiyun *num_pins = pci->groups[group].npins;
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun return 0;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun static const struct pinctrl_ops rk628_pinctrl_ops = {
555*4882a593Smuzhiyun .get_groups_count = rk628_pinctrl_get_groups_count,
556*4882a593Smuzhiyun .get_group_name = rk628_pinctrl_get_group_name,
557*4882a593Smuzhiyun .get_group_pins = rk628_pinctrl_get_group_pins,
558*4882a593Smuzhiyun .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
559*4882a593Smuzhiyun .dt_free_map = pinctrl_utils_free_map,
560*4882a593Smuzhiyun };
561*4882a593Smuzhiyun
rk628_pinctrl_get_funcs_count(struct pinctrl_dev * pctldev)562*4882a593Smuzhiyun static int rk628_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
563*4882a593Smuzhiyun {
564*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun return pci->num_functions;
567*4882a593Smuzhiyun }
568*4882a593Smuzhiyun
rk628_pinctrl_get_func_name(struct pinctrl_dev * pctldev,unsigned int function)569*4882a593Smuzhiyun static const char *rk628_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
570*4882a593Smuzhiyun unsigned int function)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun return pci->functions[function].name;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun
rk628_pinctrl_get_func_groups(struct pinctrl_dev * pctldev,unsigned int function,const char * const ** groups,unsigned int * const num_groups)577*4882a593Smuzhiyun static int rk628_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
578*4882a593Smuzhiyun unsigned int function,
579*4882a593Smuzhiyun const char *const **groups,
580*4882a593Smuzhiyun unsigned int *const num_groups)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun *groups = pci->functions[function].groups;
585*4882a593Smuzhiyun *num_groups = pci->functions[function].ngroups;
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun return 0;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
rk628_calc_mux_offset(struct rk628_pctrl_info * pci,int mux,int reg,int offset)590*4882a593Smuzhiyun static int rk628_calc_mux_offset(struct rk628_pctrl_info *pci, int mux, int reg, int offset)
591*4882a593Smuzhiyun {
592*4882a593Smuzhiyun int val = 0, orig;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun switch (reg) {
595*4882a593Smuzhiyun case GRF_SYSTEM_CON3:
596*4882a593Smuzhiyun regmap_read(pci->grf_regmap, reg, &orig);
597*4882a593Smuzhiyun if (mux)
598*4882a593Smuzhiyun val = BIT(offset) | orig;
599*4882a593Smuzhiyun else
600*4882a593Smuzhiyun val = ~BIT(offset) & orig;
601*4882a593Smuzhiyun break;
602*4882a593Smuzhiyun case GRF_GPIO0AB_SEL_CON:
603*4882a593Smuzhiyun if (offset >= 4 && offset < 8) {
604*4882a593Smuzhiyun offset += offset - 4;
605*4882a593Smuzhiyun val = 0x3 << (offset + 16) | (mux ? BIT(offset) : 0);
606*4882a593Smuzhiyun } else if (offset > 7) {
607*4882a593Smuzhiyun offset += 4;
608*4882a593Smuzhiyun val = BIT(offset + 16) | (mux ? BIT(offset) : 0);
609*4882a593Smuzhiyun } else {
610*4882a593Smuzhiyun val = BIT(offset + 16) | (mux ? BIT(offset) : 0);
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun break;
613*4882a593Smuzhiyun case GRF_GPIO1AB_SEL_CON:
614*4882a593Smuzhiyun if (offset == 13)
615*4882a593Smuzhiyun offset++;
616*4882a593Smuzhiyun if (offset > 11)
617*4882a593Smuzhiyun val = 0x3 << (offset + 16) | (mux ? BIT(offset) : 0);
618*4882a593Smuzhiyun else
619*4882a593Smuzhiyun val = BIT(offset + 16) | (mux ? BIT(offset) : 0);
620*4882a593Smuzhiyun break;
621*4882a593Smuzhiyun case GRF_GPIO2AB_SEL_CON:
622*4882a593Smuzhiyun val = BIT(offset + 16) | (mux ? BIT(offset) : 0);
623*4882a593Smuzhiyun break;
624*4882a593Smuzhiyun case GRF_GPIO2C_SEL_CON:
625*4882a593Smuzhiyun offset -= 16;
626*4882a593Smuzhiyun val = 0x3 << ((offset*2) + 16) | (mux ? BIT(offset*2) : 0);
627*4882a593Smuzhiyun break;
628*4882a593Smuzhiyun case GRF_GPIO3AB_SEL_CON:
629*4882a593Smuzhiyun if (offset > 11)
630*4882a593Smuzhiyun val = 0x3 << (offset + 16) | (mux ? BIT(offset) : 0);
631*4882a593Smuzhiyun else
632*4882a593Smuzhiyun val = BIT(offset + 16) | (mux ? BIT(offset) : 0);
633*4882a593Smuzhiyun break;
634*4882a593Smuzhiyun default:
635*4882a593Smuzhiyun break;
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun return val;
639*4882a593Smuzhiyun }
640*4882a593Smuzhiyun
rk628_pinctrl_set_mux(struct pinctrl_dev * pctldev,unsigned int func_selector,unsigned int group_selector)641*4882a593Smuzhiyun static int rk628_pinctrl_set_mux(struct pinctrl_dev *pctldev,
642*4882a593Smuzhiyun unsigned int func_selector,
643*4882a593Smuzhiyun unsigned int group_selector)
644*4882a593Smuzhiyun {
645*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
646*4882a593Smuzhiyun int ret, val;
647*4882a593Smuzhiyun int mux = pci->functions[func_selector].mux_option;
648*4882a593Smuzhiyun int offset = pci->groups[group_selector].pins[0] % BANK_OFFSET;
649*4882a593Smuzhiyun int reg = pci->groups[group_selector].iomux_base;
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun dev_dbg(pci->dev, "functions[%d]:%s mux=%s\n",
652*4882a593Smuzhiyun func_selector, pci->functions[func_selector].name,
653*4882a593Smuzhiyun mux ? "func" : "gpio");
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun val = rk628_calc_mux_offset(pci, mux, reg, offset);
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun dev_dbg(pci->dev, "groups[%d]:%s pin-number=%d reg=0x%x write-val=0x%8x\n",
658*4882a593Smuzhiyun group_selector,
659*4882a593Smuzhiyun pci->groups[group_selector].name,
660*4882a593Smuzhiyun pci->groups[group_selector].pins[0],
661*4882a593Smuzhiyun reg, val);
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun ret = regmap_write(pci->grf_regmap, reg, val);
664*4882a593Smuzhiyun if (ret)
665*4882a593Smuzhiyun dev_err(pci->dev, "%s regmap write failed!\n", __func__);
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun return ret;
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun
rk628_pmx_gpio_set_direction(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned int offset,bool input)670*4882a593Smuzhiyun static int rk628_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
671*4882a593Smuzhiyun struct pinctrl_gpio_range *range,
672*4882a593Smuzhiyun unsigned int offset, bool input)
673*4882a593Smuzhiyun {
674*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
675*4882a593Smuzhiyun struct gpio_chip *chip;
676*4882a593Smuzhiyun struct rk628_pin_bank *bank;
677*4882a593Smuzhiyun int pin_offset, dir_reg, val, ret;
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun chip = range->gc;
680*4882a593Smuzhiyun bank = gpiochip_get_data(chip);
681*4882a593Smuzhiyun pin_offset = offset - range->pin_base;
682*4882a593Smuzhiyun
683*4882a593Smuzhiyun if (pin_offset / 16) {
684*4882a593Smuzhiyun dir_reg = bank->reg_base + GPIO_SWPORT_DDR_H;
685*4882a593Smuzhiyun pin_offset -= 16;
686*4882a593Smuzhiyun } else {
687*4882a593Smuzhiyun dir_reg = bank->reg_base + GPIO_SWPORT_DDR_L;
688*4882a593Smuzhiyun }
689*4882a593Smuzhiyun if (input)
690*4882a593Smuzhiyun val = BIT(pin_offset + 16) | (0xffff & ~BIT(pin_offset));
691*4882a593Smuzhiyun else
692*4882a593Smuzhiyun val = BIT(pin_offset + 16) | BIT(pin_offset);
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun clk_enable(bank->clk);
695*4882a593Smuzhiyun ret = regmap_write(pci->regmap, dir_reg, val);
696*4882a593Smuzhiyun if (ret)
697*4882a593Smuzhiyun dev_err(pci->dev, "regmap update failed!\n");
698*4882a593Smuzhiyun clk_disable(bank->clk);
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun return 0;
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun static const struct pinmux_ops rk628_pinmux_ops = {
704*4882a593Smuzhiyun .get_functions_count = rk628_pinctrl_get_funcs_count,
705*4882a593Smuzhiyun .get_function_name = rk628_pinctrl_get_func_name,
706*4882a593Smuzhiyun .get_function_groups = rk628_pinctrl_get_func_groups,
707*4882a593Smuzhiyun .set_mux = rk628_pinctrl_set_mux,
708*4882a593Smuzhiyun .gpio_set_direction = rk628_pmx_gpio_set_direction,
709*4882a593Smuzhiyun };
710*4882a593Smuzhiyun
rk628_pinconf_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)711*4882a593Smuzhiyun static int rk628_pinconf_get(struct pinctrl_dev *pctldev,
712*4882a593Smuzhiyun unsigned int pin, unsigned long *config)
713*4882a593Smuzhiyun {
714*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
715*4882a593Smuzhiyun enum pin_config_param param = pinconf_to_config_param(*config);
716*4882a593Smuzhiyun u32 arg = 0;
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun pr_err("no support %s\n", __func__);
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun switch (param) {
721*4882a593Smuzhiyun case PIN_CONFIG_OUTPUT:
722*4882a593Smuzhiyun break;
723*4882a593Smuzhiyun default:
724*4882a593Smuzhiyun dev_err(pci->dev, "Properties not supported\n");
725*4882a593Smuzhiyun return -ENOTSUPP;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun *config = pinconf_to_config_packed(param, (u16)arg);
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun return 0;
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun
rk628_set_slew_rate(struct rk628_pctrl_info * pci,int pin,int speed)733*4882a593Smuzhiyun static int rk628_set_slew_rate(struct rk628_pctrl_info *pci, int pin, int speed)
734*4882a593Smuzhiyun {
735*4882a593Smuzhiyun int gpio = pin;
736*4882a593Smuzhiyun
737*4882a593Smuzhiyun /* gpio0b_sl(0-3) gpio1b_sl(0-3 -5) gpio3a_sl(4-7)*/
738*4882a593Smuzhiyun char valid_gpio[] = {
739*4882a593Smuzhiyun 8,
740*4882a593Smuzhiyun 9,
741*4882a593Smuzhiyun 10,
742*4882a593Smuzhiyun 11,
743*4882a593Smuzhiyun 32 + 8,
744*4882a593Smuzhiyun 32 + 9,
745*4882a593Smuzhiyun 32 + 10,
746*4882a593Smuzhiyun 32 + 11,
747*4882a593Smuzhiyun 32 + 12,
748*4882a593Smuzhiyun 32 + 13,
749*4882a593Smuzhiyun -1, -1,
750*4882a593Smuzhiyun 96 + 4,
751*4882a593Smuzhiyun 96 + 5,
752*4882a593Smuzhiyun 96 + 6,
753*4882a593Smuzhiyun 96 + 7
754*4882a593Smuzhiyun };
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun int val, ret, offset = 0xff;
758*4882a593Smuzhiyun u32 i;
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun for (i = 0; i < sizeof(valid_gpio); i++) {
761*4882a593Smuzhiyun if (gpio == valid_gpio[i]) {
762*4882a593Smuzhiyun offset = i;
763*4882a593Smuzhiyun break;
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun }
766*4882a593Smuzhiyun
767*4882a593Smuzhiyun if (offset == 0xff) {
768*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support set slew rate\n", pin);
769*4882a593Smuzhiyun return -EINVAL;
770*4882a593Smuzhiyun }
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun if (speed)
773*4882a593Smuzhiyun val = BIT(offset + 16) | BIT(offset);
774*4882a593Smuzhiyun else
775*4882a593Smuzhiyun val = BIT(offset + 16);
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun dev_dbg(pci->dev, " offset=%d 0x%x\n", offset, val);
778*4882a593Smuzhiyun
779*4882a593Smuzhiyun ret = regmap_write(pci->grf_regmap, GRF_GPIO_SR_CON, val);
780*4882a593Smuzhiyun if (ret)
781*4882a593Smuzhiyun dev_err(pci->dev, "%s:regmap write failed! pin%u\n",
782*4882a593Smuzhiyun __func__, pin);
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun return ret;
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun
rk628_calc_pull_reg_and_value(struct rk628_pctrl_info * pci,int pin,int pull,int * reg,int * val)787*4882a593Smuzhiyun static int rk628_calc_pull_reg_and_value(struct rk628_pctrl_info *pci,
788*4882a593Smuzhiyun int pin,
789*4882a593Smuzhiyun int pull,
790*4882a593Smuzhiyun int *reg,
791*4882a593Smuzhiyun int *val)
792*4882a593Smuzhiyun {
793*4882a593Smuzhiyun struct pinctrl_gpio_range *range = pinctrl_find_gpio_range_from_pin(pci->pctl, pin);
794*4882a593Smuzhiyun int gpio2_regs[] = { GRF_GPIO2A_P_CON, GRF_GPIO2B_P_CON, GRF_GPIO2C_P_CON };
795*4882a593Smuzhiyun int gpio3_regs[] = { GRF_GPIO3A_P_CON, GRF_GPIO3B_P_CON };
796*4882a593Smuzhiyun int valid_pinnum[] = { 8, 8, 24, 13 };
797*4882a593Smuzhiyun int offset = pin - range->pin_base;
798*4882a593Smuzhiyun
799*4882a593Smuzhiyun switch (range->id) {
800*4882a593Smuzhiyun case 0:
801*4882a593Smuzhiyun if (pull == GPIO_PULL_UP) {
802*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support pull up!\n",
803*4882a593Smuzhiyun pin);
804*4882a593Smuzhiyun return -EINVAL;
805*4882a593Smuzhiyun }
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun if (offset == 2) {
808*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support pull!\n",
809*4882a593Smuzhiyun pin);
810*4882a593Smuzhiyun return -EINVAL;
811*4882a593Smuzhiyun }
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun if (offset < valid_pinnum[range->id]) {
814*4882a593Smuzhiyun *val = 0x3 << (2 * offset + 16) | pull << (2 * offset);
815*4882a593Smuzhiyun *reg = GRF_GPIO0A_P_CON;
816*4882a593Smuzhiyun dev_dbg(pci->dev, "pin%u reg=0x%8x val=0x%8x\n",
817*4882a593Smuzhiyun pin, *reg, *val);
818*4882a593Smuzhiyun return 0;
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun break;
821*4882a593Smuzhiyun case 1:
822*4882a593Smuzhiyun if (pull == GPIO_PULL_UP) {
823*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support pull up!\n",
824*4882a593Smuzhiyun pin);
825*4882a593Smuzhiyun return -EINVAL;
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun if (offset == 2) {
829*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support pull!\n",
830*4882a593Smuzhiyun pin);
831*4882a593Smuzhiyun return -EINVAL;
832*4882a593Smuzhiyun }
833*4882a593Smuzhiyun
834*4882a593Smuzhiyun if (offset < valid_pinnum[range->id]) {
835*4882a593Smuzhiyun *val = 0x3 << (2 * offset + 16) | pull << (2 * offset);
836*4882a593Smuzhiyun *reg = GRF_GPIO1A_P_CON;
837*4882a593Smuzhiyun dev_dbg(pci->dev, "pin%u reg=0x%8x val=0x%8x\n",
838*4882a593Smuzhiyun pin, *reg, *val);
839*4882a593Smuzhiyun return 0;
840*4882a593Smuzhiyun }
841*4882a593Smuzhiyun break;
842*4882a593Smuzhiyun case 2:
843*4882a593Smuzhiyun if (pull == GPIO_PULL_UP)
844*4882a593Smuzhiyun pull = GPIO_PULL_DOWN;
845*4882a593Smuzhiyun else if (pull == GPIO_PULL_DOWN)
846*4882a593Smuzhiyun pull = GPIO_PULL_UP;
847*4882a593Smuzhiyun
848*4882a593Smuzhiyun if (offset < valid_pinnum[range->id]) {
849*4882a593Smuzhiyun *reg = gpio2_regs[offset / 8];
850*4882a593Smuzhiyun offset = offset % 8;
851*4882a593Smuzhiyun *val = 0x3 << (2 * offset + 16) | pull << (2 * offset);
852*4882a593Smuzhiyun dev_dbg(pci->dev, "pin%u reg=0x%8x val=0x%8x\n",
853*4882a593Smuzhiyun pin, *reg, *val);
854*4882a593Smuzhiyun return 0;
855*4882a593Smuzhiyun }
856*4882a593Smuzhiyun break;
857*4882a593Smuzhiyun case 3:
858*4882a593Smuzhiyun if (pull == GPIO_PULL_UP && (offset == 2 || offset == 11 || offset == 12)) {
859*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support pull up!\n",
860*4882a593Smuzhiyun pin);
861*4882a593Smuzhiyun return -EINVAL;
862*4882a593Smuzhiyun } else if (pull == GPIO_PULL_DOWN && (offset == 9 || offset == 10)) {
863*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support pull down!\n",
864*4882a593Smuzhiyun pin);
865*4882a593Smuzhiyun return -EINVAL;
866*4882a593Smuzhiyun }
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun if (offset == 0 || offset == 1 || offset == 3 || offset == 8) {
869*4882a593Smuzhiyun if (pull == GPIO_PULL_UP)
870*4882a593Smuzhiyun pull = GPIO_PULL_DOWN;
871*4882a593Smuzhiyun else if (pull == GPIO_PULL_DOWN)
872*4882a593Smuzhiyun pull = GPIO_PULL_UP;
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun if ((offset > 7 && offset < valid_pinnum[range->id]) || offset < 4) {
876*4882a593Smuzhiyun *reg = gpio3_regs[offset / 8];
877*4882a593Smuzhiyun offset = offset % 8;
878*4882a593Smuzhiyun *val = 0x3 << (2 * offset + 16) | pull << (2 * offset);
879*4882a593Smuzhiyun dev_dbg(pci->dev, "pin%u reg=0x%8x val=0x%8x\n",
880*4882a593Smuzhiyun pin, *reg, *val);
881*4882a593Smuzhiyun return 0;
882*4882a593Smuzhiyun }
883*4882a593Smuzhiyun break;
884*4882a593Smuzhiyun default:
885*4882a593Smuzhiyun break;
886*4882a593Smuzhiyun }
887*4882a593Smuzhiyun
888*4882a593Smuzhiyun return -EINVAL;
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun
rk628_calc_strength_reg_and_value(struct rk628_pctrl_info * pci,int pin,int strength,int * reg,int * val)891*4882a593Smuzhiyun static int rk628_calc_strength_reg_and_value(struct rk628_pctrl_info *pci,
892*4882a593Smuzhiyun int pin,
893*4882a593Smuzhiyun int strength,
894*4882a593Smuzhiyun int *reg,
895*4882a593Smuzhiyun int *val)
896*4882a593Smuzhiyun {
897*4882a593Smuzhiyun struct pinctrl_gpio_range *range = pinctrl_find_gpio_range_from_pin(pci->pctl, pin);
898*4882a593Smuzhiyun int valid_pinnum[] = { 8, 8, 24, 9 };
899*4882a593Smuzhiyun int gpio_regs[][6] = {
900*4882a593Smuzhiyun { GRF_GPIO0B_D_CON
901*4882a593Smuzhiyun },
902*4882a593Smuzhiyun { GRF_GPIO1B_D_CON
903*4882a593Smuzhiyun },
904*4882a593Smuzhiyun {
905*4882a593Smuzhiyun GRF_GPIO2A_D0_CON, GRF_GPIO2A_D1_CON,
906*4882a593Smuzhiyun GRF_GPIO2B_D0_CON, GRF_GPIO2B_D1_CON,
907*4882a593Smuzhiyun GRF_GPIO2C_D0_CON, GRF_GPIO2C_D1_CON
908*4882a593Smuzhiyun },
909*4882a593Smuzhiyun {
910*4882a593Smuzhiyun GRF_GPIO3A_D0_CON, GRF_GPIO3A_D1_CON,
911*4882a593Smuzhiyun GRF_GPIO3B_D_CON
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun };
914*4882a593Smuzhiyun int offset = pin - range->pin_base;
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun switch (range->id) {
917*4882a593Smuzhiyun case 0:
918*4882a593Smuzhiyun case 1:
919*4882a593Smuzhiyun if (offset < valid_pinnum[range->id]) {
920*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support driver strength settings!\n",
921*4882a593Smuzhiyun pin);
922*4882a593Smuzhiyun return -EINVAL;
923*4882a593Smuzhiyun }
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun offset -= valid_pinnum[range->id];
926*4882a593Smuzhiyun
927*4882a593Smuzhiyun *val = 0x3 << (2 * offset + 16) | strength << (2 * offset);
928*4882a593Smuzhiyun *reg = gpio_regs[range->id][0];
929*4882a593Smuzhiyun dev_dbg(pci->dev, "pin%u reg=0x%8x val=0x%8x\n",
930*4882a593Smuzhiyun pin, *reg, *val);
931*4882a593Smuzhiyun return 0;
932*4882a593Smuzhiyun case 2:
933*4882a593Smuzhiyun case 3:
934*4882a593Smuzhiyun if (offset < valid_pinnum[range->id]) {
935*4882a593Smuzhiyun *reg = gpio_regs[range->id][offset / 4];
936*4882a593Smuzhiyun offset = offset % 4;
937*4882a593Smuzhiyun *val = 0x7 << (4 * offset + 16) | strength << (4 * offset);
938*4882a593Smuzhiyun dev_dbg(pci->dev, "pin%u reg=0x%8x val=0x%8x\n",
939*4882a593Smuzhiyun pin, *reg, *val);
940*4882a593Smuzhiyun return 0;
941*4882a593Smuzhiyun }
942*4882a593Smuzhiyun break;
943*4882a593Smuzhiyun default:
944*4882a593Smuzhiyun break;
945*4882a593Smuzhiyun }
946*4882a593Smuzhiyun
947*4882a593Smuzhiyun return -EINVAL;
948*4882a593Smuzhiyun }
949*4882a593Smuzhiyun
rk628_calc_schmitt_reg_and_value(struct rk628_pctrl_info * pci,int pin,int enable,int * reg,int * val)950*4882a593Smuzhiyun static int rk628_calc_schmitt_reg_and_value(struct rk628_pctrl_info *pci,
951*4882a593Smuzhiyun int pin,
952*4882a593Smuzhiyun int enable,
953*4882a593Smuzhiyun int *reg,
954*4882a593Smuzhiyun int *val)
955*4882a593Smuzhiyun {
956*4882a593Smuzhiyun struct pinctrl_gpio_range *range = pinctrl_find_gpio_range_from_pin(pci->pctl, pin);
957*4882a593Smuzhiyun int gpio2_regs[] = {GRF_GPIO2A_SMT, GRF_GPIO2B_SMT, GRF_GPIO2C_SMT};
958*4882a593Smuzhiyun int gpio3_reg = GRF_GPIO3AB_SMT;
959*4882a593Smuzhiyun int valid_pinnum[] = { 0, 0, 24, 9 };
960*4882a593Smuzhiyun int offset = pin - range->pin_base;
961*4882a593Smuzhiyun
962*4882a593Smuzhiyun switch (range->id) {
963*4882a593Smuzhiyun case 0:
964*4882a593Smuzhiyun case 1:
965*4882a593Smuzhiyun break;
966*4882a593Smuzhiyun case 2:
967*4882a593Smuzhiyun if (offset < valid_pinnum[range->id]) {
968*4882a593Smuzhiyun *reg = gpio2_regs[offset / 8];
969*4882a593Smuzhiyun offset = offset % 8;
970*4882a593Smuzhiyun *val = BIT(offset + 16) | enable << (offset);
971*4882a593Smuzhiyun dev_dbg(pci->dev, "pin%u reg=0x%8x val=0x%8x\n",
972*4882a593Smuzhiyun pin, *reg, *val);
973*4882a593Smuzhiyun return 0;
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun break;
976*4882a593Smuzhiyun case 3:
977*4882a593Smuzhiyun if (offset == 0 || offset == 1 || offset == 3 || offset == 8) {
978*4882a593Smuzhiyun *reg = gpio3_reg;
979*4882a593Smuzhiyun *val = BIT(offset + 16) | enable << (offset);
980*4882a593Smuzhiyun dev_dbg(pci->dev, "pin%u reg=0x%8x val=0x%8x\n",
981*4882a593Smuzhiyun pin, *reg, *val);
982*4882a593Smuzhiyun return 0;
983*4882a593Smuzhiyun }
984*4882a593Smuzhiyun break;
985*4882a593Smuzhiyun default:
986*4882a593Smuzhiyun break;
987*4882a593Smuzhiyun }
988*4882a593Smuzhiyun
989*4882a593Smuzhiyun dev_err(pci->dev, "pin%u don't support schmitt settings!\n",
990*4882a593Smuzhiyun pin);
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun return -ENOTSUPP;
993*4882a593Smuzhiyun }
994*4882a593Smuzhiyun
rk628_set_pull(struct rk628_pctrl_info * pci,int pin,int pull)995*4882a593Smuzhiyun static int rk628_set_pull(struct rk628_pctrl_info *pci, int pin, int pull)
996*4882a593Smuzhiyun {
997*4882a593Smuzhiyun int ret, reg, val;
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun ret = rk628_calc_pull_reg_and_value(pci, pin, pull, ®, &val);
1000*4882a593Smuzhiyun if (ret) {
1001*4882a593Smuzhiyun dev_err(pci->dev, "pin%u can not find reg or not support!\n", pin);
1002*4882a593Smuzhiyun return ret;
1003*4882a593Smuzhiyun }
1004*4882a593Smuzhiyun
1005*4882a593Smuzhiyun ret = regmap_write(pci->grf_regmap, reg, val);
1006*4882a593Smuzhiyun
1007*4882a593Smuzhiyun if (ret)
1008*4882a593Smuzhiyun dev_err(pci->dev, "%s:regmap write failed! pin%u\n",
1009*4882a593Smuzhiyun __func__, pin);
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun return ret;
1012*4882a593Smuzhiyun }
1013*4882a593Smuzhiyun
rk628_set_drive_perpin(struct rk628_pctrl_info * pci,int pin,int strength)1014*4882a593Smuzhiyun static int rk628_set_drive_perpin(struct rk628_pctrl_info *pci, int pin, int strength)
1015*4882a593Smuzhiyun {
1016*4882a593Smuzhiyun int ret, reg, val;
1017*4882a593Smuzhiyun
1018*4882a593Smuzhiyun ret = rk628_calc_strength_reg_and_value(pci, pin, strength, ®, &val);
1019*4882a593Smuzhiyun if (ret) {
1020*4882a593Smuzhiyun dev_err(pci->dev, "pin%u can not find reg or not support!\n", pin);
1021*4882a593Smuzhiyun return ret;
1022*4882a593Smuzhiyun }
1023*4882a593Smuzhiyun
1024*4882a593Smuzhiyun ret = regmap_write(pci->grf_regmap, reg, val);
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun if (ret)
1027*4882a593Smuzhiyun dev_err(pci->dev, "%s:regmap write failed! pin%u\n",
1028*4882a593Smuzhiyun __func__, pin);
1029*4882a593Smuzhiyun
1030*4882a593Smuzhiyun return ret;
1031*4882a593Smuzhiyun }
1032*4882a593Smuzhiyun
rk628_set_schmitt(struct rk628_pctrl_info * pci,int pin,int enable)1033*4882a593Smuzhiyun static int rk628_set_schmitt(struct rk628_pctrl_info *pci, int pin, int enable)
1034*4882a593Smuzhiyun {
1035*4882a593Smuzhiyun int ret, reg, val;
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun ret = rk628_calc_schmitt_reg_and_value(pci, pin, enable, ®, &val);
1038*4882a593Smuzhiyun if (ret) {
1039*4882a593Smuzhiyun dev_err(pci->dev, "pin%u can not find reg or not support!\n", pin);
1040*4882a593Smuzhiyun return ret;
1041*4882a593Smuzhiyun }
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun ret = regmap_write(pci->grf_regmap, reg, val);
1044*4882a593Smuzhiyun
1045*4882a593Smuzhiyun if (ret)
1046*4882a593Smuzhiyun dev_err(pci->dev, "%s:regmap write failed! pin%u\n",
1047*4882a593Smuzhiyun __func__, pin);
1048*4882a593Smuzhiyun
1049*4882a593Smuzhiyun return ret;
1050*4882a593Smuzhiyun }
1051*4882a593Smuzhiyun
rk628_pinconf_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned int num_configs)1052*4882a593Smuzhiyun static int rk628_pinconf_set(struct pinctrl_dev *pctldev,
1053*4882a593Smuzhiyun unsigned int pin, unsigned long *configs,
1054*4882a593Smuzhiyun unsigned int num_configs)
1055*4882a593Smuzhiyun {
1056*4882a593Smuzhiyun struct rk628_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
1057*4882a593Smuzhiyun enum pin_config_param param;
1058*4882a593Smuzhiyun u32 i, arg = 0;
1059*4882a593Smuzhiyun
1060*4882a593Smuzhiyun for (i = 0; i < num_configs; i++) {
1061*4882a593Smuzhiyun param = pinconf_to_config_param(configs[i]);
1062*4882a593Smuzhiyun arg = pinconf_to_config_argument(configs[i]);
1063*4882a593Smuzhiyun
1064*4882a593Smuzhiyun switch (param) {
1065*4882a593Smuzhiyun case PIN_CONFIG_DRIVE_STRENGTH:
1066*4882a593Smuzhiyun rk628_set_drive_perpin(pci, pin, arg);
1067*4882a593Smuzhiyun break;
1068*4882a593Smuzhiyun case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
1069*4882a593Smuzhiyun rk628_set_pull(pci, pin, GPIO_HIGH_Z);
1070*4882a593Smuzhiyun break;
1071*4882a593Smuzhiyun case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
1072*4882a593Smuzhiyun dev_err(pci->dev,
1073*4882a593Smuzhiyun "PIN_CONFIG_BIAS_PULL_PIN_DEFAULT not supported\n");
1074*4882a593Smuzhiyun break;
1075*4882a593Smuzhiyun case PIN_CONFIG_BIAS_PULL_UP:
1076*4882a593Smuzhiyun rk628_set_pull(pci, pin, GPIO_PULL_UP);
1077*4882a593Smuzhiyun break;
1078*4882a593Smuzhiyun case PIN_CONFIG_BIAS_PULL_DOWN:
1079*4882a593Smuzhiyun rk628_set_pull(pci, pin, GPIO_PULL_DOWN);
1080*4882a593Smuzhiyun break;
1081*4882a593Smuzhiyun case PIN_CONFIG_SLEW_RATE:
1082*4882a593Smuzhiyun rk628_set_slew_rate(pci, pin, arg);
1083*4882a593Smuzhiyun break;
1084*4882a593Smuzhiyun case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
1085*4882a593Smuzhiyun rk628_set_schmitt(pci, pin, arg);
1086*4882a593Smuzhiyun break;
1087*4882a593Smuzhiyun case PIN_CONFIG_OUTPUT:
1088*4882a593Smuzhiyun {
1089*4882a593Smuzhiyun struct pinctrl_gpio_range *range = pinctrl_find_gpio_range_from_pin(pci->pctl, pin);
1090*4882a593Smuzhiyun
1091*4882a593Smuzhiyun rk628_gpio_direction_output(range->gc, pin - range->pin_base, arg);
1092*4882a593Smuzhiyun break;
1093*4882a593Smuzhiyun }
1094*4882a593Smuzhiyun default:
1095*4882a593Smuzhiyun dev_err(pci->dev, "Properties not supported param=%d\n", param);
1096*4882a593Smuzhiyun break;
1097*4882a593Smuzhiyun }
1098*4882a593Smuzhiyun }
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun return 0;
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun
1103*4882a593Smuzhiyun static const struct pinconf_ops rk628_pinconf_ops = {
1104*4882a593Smuzhiyun .pin_config_get = rk628_pinconf_get,
1105*4882a593Smuzhiyun .pin_config_set = rk628_pinconf_set,
1106*4882a593Smuzhiyun };
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun static struct pinctrl_desc rk628_pinctrl_desc = {
1109*4882a593Smuzhiyun .name = "rk628-pinctrl",
1110*4882a593Smuzhiyun .pctlops = &rk628_pinctrl_ops,
1111*4882a593Smuzhiyun .pmxops = &rk628_pinmux_ops,
1112*4882a593Smuzhiyun .confops = &rk628_pinconf_ops,
1113*4882a593Smuzhiyun .owner = THIS_MODULE,
1114*4882a593Smuzhiyun };
1115*4882a593Smuzhiyun
rk628_pinctrl_create_function(struct device * dev,struct rk628_pctrl_info * pci,struct device_node * func_np,struct rk628_pin_function * func)1116*4882a593Smuzhiyun static int rk628_pinctrl_create_function(struct device *dev,
1117*4882a593Smuzhiyun struct rk628_pctrl_info *pci,
1118*4882a593Smuzhiyun struct device_node *func_np,
1119*4882a593Smuzhiyun struct rk628_pin_function *func)
1120*4882a593Smuzhiyun {
1121*4882a593Smuzhiyun int npins;
1122*4882a593Smuzhiyun int ret;
1123*4882a593Smuzhiyun int i;
1124*4882a593Smuzhiyun char *func_sel[6] = {
1125*4882a593Smuzhiyun "vop_dclk0", "i2sm0_input", "rxdcc_input0", "hdmirx_cec0",
1126*4882a593Smuzhiyun "force_jtag_dis", "uart_iomux_dis",
1127*4882a593Smuzhiyun };
1128*4882a593Smuzhiyun
1129*4882a593Smuzhiyun if (of_property_read_string(func_np, "function", &func->name))
1130*4882a593Smuzhiyun return -1;
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun func->mux_option = PINMUX_FUNC1;
1133*4882a593Smuzhiyun /* for signals input select */
1134*4882a593Smuzhiyun for (i = 0; i < 6; i++) {
1135*4882a593Smuzhiyun if (!strcmp(func_sel[i], func->name))
1136*4882a593Smuzhiyun func->mux_option = PINMUX_FUNC0;
1137*4882a593Smuzhiyun }
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun dev_dbg(dev, "%s func->name=%s\n", __func__, func->name);
1140*4882a593Smuzhiyun npins = of_property_count_strings(func_np, "pins");
1141*4882a593Smuzhiyun if (npins < 1) {
1142*4882a593Smuzhiyun dev_err(dev, "invalid pin list in %s node", func_np->name);
1143*4882a593Smuzhiyun return -EINVAL;
1144*4882a593Smuzhiyun }
1145*4882a593Smuzhiyun
1146*4882a593Smuzhiyun func->groups = devm_kzalloc(dev, npins * sizeof(char *), GFP_KERNEL);
1147*4882a593Smuzhiyun if (!func->groups)
1148*4882a593Smuzhiyun return -ENOMEM;
1149*4882a593Smuzhiyun
1150*4882a593Smuzhiyun for (i = 0; i < npins; ++i) {
1151*4882a593Smuzhiyun const char *gname;
1152*4882a593Smuzhiyun
1153*4882a593Smuzhiyun ret = of_property_read_string_index(func_np,
1154*4882a593Smuzhiyun "pins", i, &gname);
1155*4882a593Smuzhiyun if (ret) {
1156*4882a593Smuzhiyun dev_err(dev,
1157*4882a593Smuzhiyun "failed to read pin name %d from %s node\n",
1158*4882a593Smuzhiyun i, func_np->name);
1159*4882a593Smuzhiyun return ret;
1160*4882a593Smuzhiyun }
1161*4882a593Smuzhiyun dev_dbg(dev, "%s func->groups[%d]=%s\n", __func__, i, gname);
1162*4882a593Smuzhiyun
1163*4882a593Smuzhiyun func->groups[i] = gname;
1164*4882a593Smuzhiyun }
1165*4882a593Smuzhiyun
1166*4882a593Smuzhiyun func->ngroups = npins;
1167*4882a593Smuzhiyun return 0;
1168*4882a593Smuzhiyun }
1169*4882a593Smuzhiyun
rk628_pinctrl_parse_gpiobank(struct device * dev,struct rk628_pctrl_info * pci)1170*4882a593Smuzhiyun static int rk628_pinctrl_parse_gpiobank(struct device *dev,
1171*4882a593Smuzhiyun struct rk628_pctrl_info *pci)
1172*4882a593Smuzhiyun {
1173*4882a593Smuzhiyun struct device_node *dev_np = dev->of_node;
1174*4882a593Smuzhiyun struct device_node *cfg_np;
1175*4882a593Smuzhiyun struct rk628_pin_bank *bank;
1176*4882a593Smuzhiyun u32 i, count = 0;
1177*4882a593Smuzhiyun
1178*4882a593Smuzhiyun for_each_child_of_node(dev_np, cfg_np) {
1179*4882a593Smuzhiyun if (of_get_child_count(cfg_np))
1180*4882a593Smuzhiyun continue;
1181*4882a593Smuzhiyun if (!of_find_property(cfg_np, "gpio-controller", NULL))
1182*4882a593Smuzhiyun continue;
1183*4882a593Smuzhiyun bank = pci->pin_banks;
1184*4882a593Smuzhiyun for (i = 0; i < pci->nr_banks; ++i, ++bank) {
1185*4882a593Smuzhiyun if (strcmp(bank->name, cfg_np->name))
1186*4882a593Smuzhiyun continue;
1187*4882a593Smuzhiyun bank->of_node = cfg_np;
1188*4882a593Smuzhiyun count++;
1189*4882a593Smuzhiyun bank->clk = devm_get_clk_from_child(dev,
1190*4882a593Smuzhiyun bank->of_node,
1191*4882a593Smuzhiyun "pclk");
1192*4882a593Smuzhiyun if (IS_ERR(bank->clk))
1193*4882a593Smuzhiyun return PTR_ERR(bank->clk);
1194*4882a593Smuzhiyun clk_prepare(bank->clk);
1195*4882a593Smuzhiyun break;
1196*4882a593Smuzhiyun }
1197*4882a593Smuzhiyun if (count == pci->nr_banks)
1198*4882a593Smuzhiyun break;
1199*4882a593Smuzhiyun }
1200*4882a593Smuzhiyun
1201*4882a593Smuzhiyun return 0;
1202*4882a593Smuzhiyun }
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun static struct rk628_pin_function *
rk628_pinctrl_create_functions(struct device * dev,struct rk628_pctrl_info * pci,unsigned int * cnt)1205*4882a593Smuzhiyun rk628_pinctrl_create_functions(struct device *dev,
1206*4882a593Smuzhiyun struct rk628_pctrl_info *pci,
1207*4882a593Smuzhiyun unsigned int *cnt)
1208*4882a593Smuzhiyun {
1209*4882a593Smuzhiyun struct rk628_pin_function *functions, *func;
1210*4882a593Smuzhiyun struct device_node *dev_np = dev->of_node;
1211*4882a593Smuzhiyun struct device_node *cfg_np;
1212*4882a593Smuzhiyun unsigned int func_cnt = 0;
1213*4882a593Smuzhiyun const char *func_name;
1214*4882a593Smuzhiyun int ret;
1215*4882a593Smuzhiyun
1216*4882a593Smuzhiyun /*
1217*4882a593Smuzhiyun * Iterate over all the child nodes of the pin controller node
1218*4882a593Smuzhiyun * and create pin groups and pin function lists.
1219*4882a593Smuzhiyun */
1220*4882a593Smuzhiyun for_each_child_of_node(dev_np, cfg_np) {
1221*4882a593Smuzhiyun if (!of_get_child_count(cfg_np)) {
1222*4882a593Smuzhiyun if (!of_find_property(cfg_np, "function", NULL))
1223*4882a593Smuzhiyun continue;
1224*4882a593Smuzhiyun if (!of_property_read_string(cfg_np,
1225*4882a593Smuzhiyun "function", &func_name)) {
1226*4882a593Smuzhiyun if (!strncmp("gpio", func_name, 4))
1227*4882a593Smuzhiyun continue;
1228*4882a593Smuzhiyun }
1229*4882a593Smuzhiyun dev_dbg(dev, "%s: count=%d %s\n",
1230*4882a593Smuzhiyun __func__, func_cnt, func_name);
1231*4882a593Smuzhiyun ++func_cnt;
1232*4882a593Smuzhiyun continue;
1233*4882a593Smuzhiyun }
1234*4882a593Smuzhiyun }
1235*4882a593Smuzhiyun
1236*4882a593Smuzhiyun ++func_cnt;
1237*4882a593Smuzhiyun dev_dbg(dev, "total_count=%d, count %d for gpio function.\n",
1238*4882a593Smuzhiyun func_cnt, func_cnt - 1);
1239*4882a593Smuzhiyun functions = devm_kzalloc(dev, func_cnt * sizeof(*functions),
1240*4882a593Smuzhiyun GFP_KERNEL);
1241*4882a593Smuzhiyun if (!functions)
1242*4882a593Smuzhiyun return ERR_PTR(-ENOMEM);
1243*4882a593Smuzhiyun
1244*4882a593Smuzhiyun func = functions;
1245*4882a593Smuzhiyun
1246*4882a593Smuzhiyun /*
1247*4882a593Smuzhiyun * Iterate over all the child nodes of the pin controller node
1248*4882a593Smuzhiyun * and create pin groups and pin function lists.
1249*4882a593Smuzhiyun */
1250*4882a593Smuzhiyun func_cnt = 0;
1251*4882a593Smuzhiyun for_each_child_of_node(dev_np, cfg_np) {
1252*4882a593Smuzhiyun if (!of_get_child_count(cfg_np)) {
1253*4882a593Smuzhiyun if (!of_property_read_string(cfg_np,
1254*4882a593Smuzhiyun "function", &func_name)) {
1255*4882a593Smuzhiyun if (!strncmp("gpio", func_name, 4))
1256*4882a593Smuzhiyun continue;
1257*4882a593Smuzhiyun }
1258*4882a593Smuzhiyun ret = rk628_pinctrl_create_function(dev, pci,
1259*4882a593Smuzhiyun cfg_np, func);
1260*4882a593Smuzhiyun if (!ret) {
1261*4882a593Smuzhiyun ++func;
1262*4882a593Smuzhiyun ++func_cnt;
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun continue;
1265*4882a593Smuzhiyun }
1266*4882a593Smuzhiyun }
1267*4882a593Smuzhiyun
1268*4882a593Smuzhiyun /* init gpio func */
1269*4882a593Smuzhiyun *(func) = rk628_functions[MUX_GPIO];
1270*4882a593Smuzhiyun func->mux_option = PINMUX_FUNC0;
1271*4882a593Smuzhiyun
1272*4882a593Smuzhiyun dev_dbg(dev, "count %d is for %s function\n", func_cnt, func->name);
1273*4882a593Smuzhiyun ++func;
1274*4882a593Smuzhiyun ++func_cnt;
1275*4882a593Smuzhiyun *cnt = func_cnt;
1276*4882a593Smuzhiyun return functions;
1277*4882a593Smuzhiyun }
1278*4882a593Smuzhiyun
rk628_pinctrl_parse_dt(struct platform_device * pdev,struct rk628_pctrl_info * pci)1279*4882a593Smuzhiyun static int rk628_pinctrl_parse_dt(struct platform_device *pdev,
1280*4882a593Smuzhiyun struct rk628_pctrl_info *pci)
1281*4882a593Smuzhiyun {
1282*4882a593Smuzhiyun struct device *dev = &pdev->dev;
1283*4882a593Smuzhiyun struct rk628_pin_function *functions;
1284*4882a593Smuzhiyun unsigned int func_cnt = 0;
1285*4882a593Smuzhiyun int ret;
1286*4882a593Smuzhiyun
1287*4882a593Smuzhiyun ret = rk628_pinctrl_parse_gpiobank(dev, pci);
1288*4882a593Smuzhiyun if (ret)
1289*4882a593Smuzhiyun return ret;
1290*4882a593Smuzhiyun
1291*4882a593Smuzhiyun functions = rk628_pinctrl_create_functions(dev, pci, &func_cnt);
1292*4882a593Smuzhiyun if (IS_ERR(functions)) {
1293*4882a593Smuzhiyun dev_err(dev, "failed to parse pin functions\n");
1294*4882a593Smuzhiyun return PTR_ERR(functions);
1295*4882a593Smuzhiyun }
1296*4882a593Smuzhiyun
1297*4882a593Smuzhiyun pci->functions = functions;
1298*4882a593Smuzhiyun pci->num_functions = func_cnt;
1299*4882a593Smuzhiyun return 0;
1300*4882a593Smuzhiyun }
1301*4882a593Smuzhiyun
1302*4882a593Smuzhiyun static const struct regmap_range rk628_pinctrl_readable_ranges[] = {
1303*4882a593Smuzhiyun regmap_reg_range(GPIO0_BASE, GPIO0_BASE + GPIO_VER_ID),
1304*4882a593Smuzhiyun regmap_reg_range(GPIO1_BASE, GPIO1_BASE + GPIO_VER_ID),
1305*4882a593Smuzhiyun regmap_reg_range(GPIO2_BASE, GPIO2_BASE + GPIO_VER_ID),
1306*4882a593Smuzhiyun regmap_reg_range(GPIO3_BASE, GPIO3_BASE + GPIO_VER_ID),
1307*4882a593Smuzhiyun };
1308*4882a593Smuzhiyun
1309*4882a593Smuzhiyun static const struct regmap_access_table rk628_pinctrl_readable_table = {
1310*4882a593Smuzhiyun .yes_ranges = rk628_pinctrl_readable_ranges,
1311*4882a593Smuzhiyun .n_yes_ranges = ARRAY_SIZE(rk628_pinctrl_readable_ranges),
1312*4882a593Smuzhiyun };
1313*4882a593Smuzhiyun
1314*4882a593Smuzhiyun static const struct regmap_config rk628_pinctrl_regmap_config = {
1315*4882a593Smuzhiyun .name = "pinctrl",
1316*4882a593Smuzhiyun .reg_bits = 32,
1317*4882a593Smuzhiyun .val_bits = 32,
1318*4882a593Smuzhiyun .reg_stride = 4,
1319*4882a593Smuzhiyun .max_register = GPIO_MAX_REGISTER,
1320*4882a593Smuzhiyun .reg_format_endian = REGMAP_ENDIAN_LITTLE,
1321*4882a593Smuzhiyun .val_format_endian = REGMAP_ENDIAN_LITTLE,
1322*4882a593Smuzhiyun .rd_table = &rk628_pinctrl_readable_table,
1323*4882a593Smuzhiyun };
1324*4882a593Smuzhiyun
rk628_irq_enable(struct irq_data * d)1325*4882a593Smuzhiyun static void rk628_irq_enable(struct irq_data *d)
1326*4882a593Smuzhiyun {
1327*4882a593Smuzhiyun struct rk628_pin_bank *bank = irq_data_get_irq_chip_data(d);
1328*4882a593Smuzhiyun unsigned long hwirq = d->hwirq;
1329*4882a593Smuzhiyun u32 offset;
1330*4882a593Smuzhiyun
1331*4882a593Smuzhiyun if (hwirq / 16) {
1332*4882a593Smuzhiyun hwirq = hwirq - 16;
1333*4882a593Smuzhiyun offset = GPIO_REG_HIGH;
1334*4882a593Smuzhiyun } else {
1335*4882a593Smuzhiyun offset = GPIO_REG_LOW;
1336*4882a593Smuzhiyun }
1337*4882a593Smuzhiyun
1338*4882a593Smuzhiyun bank->mask_regs[offset] |= BIT(hwirq);
1339*4882a593Smuzhiyun }
1340*4882a593Smuzhiyun
rk628_irq_disable(struct irq_data * d)1341*4882a593Smuzhiyun static void rk628_irq_disable(struct irq_data *d)
1342*4882a593Smuzhiyun {
1343*4882a593Smuzhiyun struct rk628_pin_bank *bank = irq_data_get_irq_chip_data(d);
1344*4882a593Smuzhiyun unsigned long hwirq = d->hwirq;
1345*4882a593Smuzhiyun u32 offset;
1346*4882a593Smuzhiyun
1347*4882a593Smuzhiyun if (hwirq / 16) {
1348*4882a593Smuzhiyun hwirq = hwirq - 16;
1349*4882a593Smuzhiyun offset = GPIO_REG_HIGH;
1350*4882a593Smuzhiyun } else {
1351*4882a593Smuzhiyun offset = GPIO_REG_LOW;
1352*4882a593Smuzhiyun }
1353*4882a593Smuzhiyun
1354*4882a593Smuzhiyun bank->mask_regs[offset] &= ~BIT(hwirq);
1355*4882a593Smuzhiyun }
1356*4882a593Smuzhiyun
rk628_irq_set_type(struct irq_data * d,unsigned int type)1357*4882a593Smuzhiyun static int rk628_irq_set_type(struct irq_data *d, unsigned int type)
1358*4882a593Smuzhiyun {
1359*4882a593Smuzhiyun struct rk628_pin_bank *bank = irq_data_get_irq_chip_data(d);
1360*4882a593Smuzhiyun struct rk628_pctrl_info *pci = bank->pci;
1361*4882a593Smuzhiyun unsigned long hwirq = d->hwirq;
1362*4882a593Smuzhiyun u32 offset;
1363*4882a593Smuzhiyun
1364*4882a593Smuzhiyun if (hwirq / 16) {
1365*4882a593Smuzhiyun hwirq = hwirq - 16;
1366*4882a593Smuzhiyun offset = GPIO_REG_HIGH;
1367*4882a593Smuzhiyun } else {
1368*4882a593Smuzhiyun offset = GPIO_REG_LOW;
1369*4882a593Smuzhiyun }
1370*4882a593Smuzhiyun
1371*4882a593Smuzhiyun switch (type) {
1372*4882a593Smuzhiyun case IRQ_TYPE_EDGE_BOTH:
1373*4882a593Smuzhiyun bank->bothedge_regs[offset] |= BIT(hwirq);
1374*4882a593Smuzhiyun break;
1375*4882a593Smuzhiyun case IRQ_TYPE_EDGE_RISING:
1376*4882a593Smuzhiyun bank->bothedge_regs[offset] &= ~BIT(hwirq);
1377*4882a593Smuzhiyun bank->level_regs[offset] |= BIT(hwirq);
1378*4882a593Smuzhiyun bank->polarity_regs[offset] |= BIT(hwirq);
1379*4882a593Smuzhiyun break;
1380*4882a593Smuzhiyun case IRQ_TYPE_EDGE_FALLING:
1381*4882a593Smuzhiyun bank->bothedge_regs[offset] &= ~BIT(hwirq);
1382*4882a593Smuzhiyun bank->level_regs[offset] |= BIT(hwirq);
1383*4882a593Smuzhiyun bank->polarity_regs[offset] &= ~BIT(hwirq);
1384*4882a593Smuzhiyun break;
1385*4882a593Smuzhiyun case IRQ_TYPE_LEVEL_HIGH:
1386*4882a593Smuzhiyun bank->bothedge_regs[offset] &= ~BIT(hwirq);
1387*4882a593Smuzhiyun bank->level_regs[offset] &= ~BIT(hwirq);
1388*4882a593Smuzhiyun bank->polarity_regs[offset] |= BIT(hwirq);
1389*4882a593Smuzhiyun break;
1390*4882a593Smuzhiyun case IRQ_TYPE_LEVEL_LOW:
1391*4882a593Smuzhiyun bank->bothedge_regs[offset] &= ~BIT(hwirq);
1392*4882a593Smuzhiyun bank->level_regs[offset] &= ~BIT(hwirq);
1393*4882a593Smuzhiyun bank->polarity_regs[offset] &= ~BIT(hwirq);
1394*4882a593Smuzhiyun break;
1395*4882a593Smuzhiyun default:
1396*4882a593Smuzhiyun dev_err(pci->dev, "irq type invalid!\n");
1397*4882a593Smuzhiyun return -EINVAL;
1398*4882a593Smuzhiyun }
1399*4882a593Smuzhiyun
1400*4882a593Smuzhiyun return 0;
1401*4882a593Smuzhiyun }
1402*4882a593Smuzhiyun
rk628_irq_lock(struct irq_data * d)1403*4882a593Smuzhiyun static void rk628_irq_lock(struct irq_data *d)
1404*4882a593Smuzhiyun {
1405*4882a593Smuzhiyun struct rk628_pin_bank *bank = irq_data_get_irq_chip_data(d);
1406*4882a593Smuzhiyun
1407*4882a593Smuzhiyun mutex_lock(&bank->lock);
1408*4882a593Smuzhiyun clk_enable(bank->clk);
1409*4882a593Smuzhiyun }
1410*4882a593Smuzhiyun
rk628_irq_sync_unlock(struct irq_data * d)1411*4882a593Smuzhiyun static void rk628_irq_sync_unlock(struct irq_data *d)
1412*4882a593Smuzhiyun {
1413*4882a593Smuzhiyun struct rk628_pin_bank *bank = irq_data_get_irq_chip_data(d);
1414*4882a593Smuzhiyun struct rk628_pctrl_info *pci = bank->pci;
1415*4882a593Smuzhiyun int ret;
1416*4882a593Smuzhiyun unsigned long hwirq = d->hwirq;
1417*4882a593Smuzhiyun u32 offset, inten, level, polarity, bothedge;
1418*4882a593Smuzhiyun
1419*4882a593Smuzhiyun if (hwirq / 16) {
1420*4882a593Smuzhiyun hwirq = hwirq - 16;
1421*4882a593Smuzhiyun offset = GPIO_REG_HIGH;
1422*4882a593Smuzhiyun } else {
1423*4882a593Smuzhiyun offset = GPIO_REG_LOW;
1424*4882a593Smuzhiyun }
1425*4882a593Smuzhiyun
1426*4882a593Smuzhiyun inten = (bank->reg_base + GPIO_INTEN_L + ((offset) * 4));
1427*4882a593Smuzhiyun level = (bank->reg_base + GPIO_INTTYPE_L + ((offset) * 4));
1428*4882a593Smuzhiyun polarity = (bank->reg_base + GPIO_INT_POLARITY_L + ((offset) * 4));
1429*4882a593Smuzhiyun bothedge = (bank->reg_base + GPIO_INT_BOTHEDGE_L + ((offset) * 4));
1430*4882a593Smuzhiyun
1431*4882a593Smuzhiyun ret = regmap_write(pci->regmap, level,
1432*4882a593Smuzhiyun bank->level_regs[offset] | BIT(hwirq + 16));
1433*4882a593Smuzhiyun if (ret)
1434*4882a593Smuzhiyun dev_err(pci->dev, "regmap read failed! reg=0x%x irq=%d\n",
1435*4882a593Smuzhiyun level, d->irq);
1436*4882a593Smuzhiyun
1437*4882a593Smuzhiyun ret = regmap_write(pci->regmap, polarity,
1438*4882a593Smuzhiyun bank->polarity_regs[offset] | BIT(hwirq + 16));
1439*4882a593Smuzhiyun if (ret)
1440*4882a593Smuzhiyun dev_err(pci->dev, "regmap read failed! reg=0x%x irq=%d\n",
1441*4882a593Smuzhiyun polarity, d->irq);
1442*4882a593Smuzhiyun
1443*4882a593Smuzhiyun ret = regmap_write(pci->regmap, bothedge,
1444*4882a593Smuzhiyun bank->bothedge_regs[offset] | BIT(hwirq + 16));
1445*4882a593Smuzhiyun if (ret)
1446*4882a593Smuzhiyun dev_err(pci->dev, "regmap read failed! reg=0x%x irq=%d\n",
1447*4882a593Smuzhiyun bothedge, d->irq);
1448*4882a593Smuzhiyun
1449*4882a593Smuzhiyun ret = regmap_write(pci->regmap, inten,
1450*4882a593Smuzhiyun bank->mask_regs[offset] | BIT(hwirq + 16));
1451*4882a593Smuzhiyun if (ret)
1452*4882a593Smuzhiyun dev_err(pci->dev, "regmap read failed! reg=0x%x irq=%d\n",
1453*4882a593Smuzhiyun inten, d->irq);
1454*4882a593Smuzhiyun
1455*4882a593Smuzhiyun clk_disable(bank->clk);
1456*4882a593Smuzhiyun mutex_unlock(&bank->lock);
1457*4882a593Smuzhiyun }
1458*4882a593Smuzhiyun
1459*4882a593Smuzhiyun enum rk628_irqchip {
1460*4882a593Smuzhiyun IRQCHIP_gpio0,
1461*4882a593Smuzhiyun IRQCHIP_gpio1,
1462*4882a593Smuzhiyun IRQCHIP_gpio2,
1463*4882a593Smuzhiyun IRQCHIP_gpio3,
1464*4882a593Smuzhiyun };
1465*4882a593Smuzhiyun
1466*4882a593Smuzhiyun static const struct irq_chip rk628_irq_chip[] = {
1467*4882a593Smuzhiyun IRQ_CHIP(gpio0),
1468*4882a593Smuzhiyun IRQ_CHIP(gpio1),
1469*4882a593Smuzhiyun IRQ_CHIP(gpio2),
1470*4882a593Smuzhiyun IRQ_CHIP(gpio3),
1471*4882a593Smuzhiyun };
1472*4882a593Smuzhiyun
rk628_irq_map(struct irq_domain * h,unsigned int virq,irq_hw_number_t hw)1473*4882a593Smuzhiyun static int rk628_irq_map(struct irq_domain *h, unsigned int virq,
1474*4882a593Smuzhiyun irq_hw_number_t hw)
1475*4882a593Smuzhiyun {
1476*4882a593Smuzhiyun struct rk628_pin_bank *bank = h->host_data;
1477*4882a593Smuzhiyun
1478*4882a593Smuzhiyun irq_set_chip_data(virq, bank);
1479*4882a593Smuzhiyun irq_set_chip(virq, &bank->irq_chip);
1480*4882a593Smuzhiyun irq_set_nested_thread(virq, 1);
1481*4882a593Smuzhiyun irq_set_noprobe(virq);
1482*4882a593Smuzhiyun
1483*4882a593Smuzhiyun return 0;
1484*4882a593Smuzhiyun }
1485*4882a593Smuzhiyun
1486*4882a593Smuzhiyun static const struct irq_domain_ops rk628_domain_ops = {
1487*4882a593Smuzhiyun .map = rk628_irq_map,
1488*4882a593Smuzhiyun .xlate = irq_domain_xlate_twocell,
1489*4882a593Smuzhiyun };
1490*4882a593Smuzhiyun
rk628_irq_demux_thread(int irq,void * d)1491*4882a593Smuzhiyun static irqreturn_t rk628_irq_demux_thread(int irq, void *d)
1492*4882a593Smuzhiyun {
1493*4882a593Smuzhiyun struct rk628_pin_bank *bank = d;
1494*4882a593Smuzhiyun struct rk628_pctrl_info *pci = bank->pci;
1495*4882a593Smuzhiyun int ret;
1496*4882a593Smuzhiyun u32 pend, low_bit, high_bit;
1497*4882a593Smuzhiyun
1498*4882a593Smuzhiyun clk_enable(bank->clk);
1499*4882a593Smuzhiyun
1500*4882a593Smuzhiyun ret = regmap_read(pci->regmap, bank->reg_base + GPIO_INT_STATUS, &pend);
1501*4882a593Smuzhiyun if (ret)
1502*4882a593Smuzhiyun dev_err(pci->dev, "regmap read failed! line=%d\n", __LINE__);
1503*4882a593Smuzhiyun
1504*4882a593Smuzhiyun low_bit = pend & 0x0000ffff;
1505*4882a593Smuzhiyun high_bit = (pend >> 16);
1506*4882a593Smuzhiyun ret = regmap_write(pci->regmap, bank->reg_base + GPIO_PORTS_EOI_L,
1507*4882a593Smuzhiyun (low_bit << 16) | low_bit);
1508*4882a593Smuzhiyun if (ret)
1509*4882a593Smuzhiyun dev_err(pci->dev, "regmap read failed! line=%d\n", __LINE__);
1510*4882a593Smuzhiyun
1511*4882a593Smuzhiyun ret = regmap_write(pci->regmap, bank->reg_base + GPIO_PORTS_EOI_H,
1512*4882a593Smuzhiyun (high_bit << 16) | high_bit);
1513*4882a593Smuzhiyun if (ret)
1514*4882a593Smuzhiyun dev_err(pci->dev, "regmap read failed! line=%d\n", __LINE__);
1515*4882a593Smuzhiyun
1516*4882a593Smuzhiyun while (pend) {
1517*4882a593Smuzhiyun unsigned int irq, virq;
1518*4882a593Smuzhiyun
1519*4882a593Smuzhiyun irq = __ffs(pend);
1520*4882a593Smuzhiyun pend &= ~BIT(irq);
1521*4882a593Smuzhiyun virq = irq_linear_revmap(bank->domain, irq);
1522*4882a593Smuzhiyun
1523*4882a593Smuzhiyun if (!virq) {
1524*4882a593Smuzhiyun dev_err(pci->dev, "unmapped irq %d\n", irq);
1525*4882a593Smuzhiyun continue;
1526*4882a593Smuzhiyun }
1527*4882a593Smuzhiyun
1528*4882a593Smuzhiyun handle_nested_irq(virq);
1529*4882a593Smuzhiyun }
1530*4882a593Smuzhiyun clk_disable(bank->clk);
1531*4882a593Smuzhiyun
1532*4882a593Smuzhiyun return IRQ_HANDLED;
1533*4882a593Smuzhiyun }
1534*4882a593Smuzhiyun
rk628_interrupts_register(struct platform_device * pdev,struct rk628_pctrl_info * pci)1535*4882a593Smuzhiyun static int rk628_interrupts_register(struct platform_device *pdev,
1536*4882a593Smuzhiyun struct rk628_pctrl_info *pci)
1537*4882a593Smuzhiyun {
1538*4882a593Smuzhiyun struct rk628_pin_bank *bank = pci->pin_banks;
1539*4882a593Smuzhiyun int ret;
1540*4882a593Smuzhiyun u32 i;
1541*4882a593Smuzhiyun
1542*4882a593Smuzhiyun for (i = 0; i < pci->nr_banks; ++i, ++bank) {
1543*4882a593Smuzhiyun mutex_init(&bank->lock);
1544*4882a593Smuzhiyun ret = clk_enable(bank->clk);
1545*4882a593Smuzhiyun if (ret) {
1546*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to enable clock for bank %s\n",
1547*4882a593Smuzhiyun bank->name);
1548*4882a593Smuzhiyun continue;
1549*4882a593Smuzhiyun }
1550*4882a593Smuzhiyun
1551*4882a593Smuzhiyun bank->irq = platform_get_irq(pdev, i);
1552*4882a593Smuzhiyun bank->irq_chip = rk628_irq_chip[i];
1553*4882a593Smuzhiyun bank->domain = irq_domain_add_linear(bank->of_node,
1554*4882a593Smuzhiyun bank->nr_pins,
1555*4882a593Smuzhiyun &rk628_domain_ops,
1556*4882a593Smuzhiyun bank);
1557*4882a593Smuzhiyun if (!bank->domain) {
1558*4882a593Smuzhiyun dev_warn(&pdev->dev,
1559*4882a593Smuzhiyun "could not initialize irq domain for bank %s\n",
1560*4882a593Smuzhiyun bank->name);
1561*4882a593Smuzhiyun clk_disable(bank->clk);
1562*4882a593Smuzhiyun continue;
1563*4882a593Smuzhiyun }
1564*4882a593Smuzhiyun
1565*4882a593Smuzhiyun ret = request_threaded_irq(bank->irq, NULL,
1566*4882a593Smuzhiyun rk628_irq_demux_thread,
1567*4882a593Smuzhiyun IRQF_ONESHOT,
1568*4882a593Smuzhiyun bank->name, bank);
1569*4882a593Smuzhiyun if (ret != 0) {
1570*4882a593Smuzhiyun dev_err(&pdev->dev,
1571*4882a593Smuzhiyun "Failed to request IRQ %d for %s: %d\n",
1572*4882a593Smuzhiyun bank->irq, bank->name, ret);
1573*4882a593Smuzhiyun }
1574*4882a593Smuzhiyun
1575*4882a593Smuzhiyun clk_disable(bank->clk);
1576*4882a593Smuzhiyun }
1577*4882a593Smuzhiyun
1578*4882a593Smuzhiyun return 0;
1579*4882a593Smuzhiyun }
1580*4882a593Smuzhiyun
rk628_gpiolib_register(struct platform_device * pdev,struct rk628_pctrl_info * pci)1581*4882a593Smuzhiyun static int rk628_gpiolib_register(struct platform_device *pdev,
1582*4882a593Smuzhiyun struct rk628_pctrl_info *pci)
1583*4882a593Smuzhiyun {
1584*4882a593Smuzhiyun struct rk628_pin_bank *bank = pci->pin_banks;
1585*4882a593Smuzhiyun struct gpio_chip *gc;
1586*4882a593Smuzhiyun int ret = 0, i;
1587*4882a593Smuzhiyun
1588*4882a593Smuzhiyun for (i = 0; i < pci->nr_banks; ++i, ++bank) {
1589*4882a593Smuzhiyun bank->gpio_chip = rk628_gpiolib_chip;
1590*4882a593Smuzhiyun bank->pci = pci;
1591*4882a593Smuzhiyun gc = &bank->gpio_chip;
1592*4882a593Smuzhiyun gc->base = -1;
1593*4882a593Smuzhiyun gc->ngpio = bank->nr_pins;
1594*4882a593Smuzhiyun gc->parent = &pdev->dev;
1595*4882a593Smuzhiyun gc->of_node = bank->of_node;
1596*4882a593Smuzhiyun gc->label = bank->name;
1597*4882a593Smuzhiyun
1598*4882a593Smuzhiyun ret = devm_gpiochip_add_data(&pdev->dev, gc, bank);
1599*4882a593Smuzhiyun if (ret) {
1600*4882a593Smuzhiyun dev_err(&pdev->dev,
1601*4882a593Smuzhiyun "failed to register gpio_chip %s, error code: %d\n",
1602*4882a593Smuzhiyun gc->label, ret);
1603*4882a593Smuzhiyun }
1604*4882a593Smuzhiyun }
1605*4882a593Smuzhiyun
1606*4882a593Smuzhiyun return ret;
1607*4882a593Smuzhiyun }
1608*4882a593Smuzhiyun
rk628_pinctrl_probe(struct platform_device * pdev)1609*4882a593Smuzhiyun static int rk628_pinctrl_probe(struct platform_device *pdev)
1610*4882a593Smuzhiyun {
1611*4882a593Smuzhiyun struct rk628 *rk628 = dev_get_drvdata(pdev->dev.parent);
1612*4882a593Smuzhiyun struct device *dev = &pdev->dev;
1613*4882a593Smuzhiyun struct rk628_pctrl_info *pci;
1614*4882a593Smuzhiyun int ret;
1615*4882a593Smuzhiyun u32 bank;
1616*4882a593Smuzhiyun struct rk628_pin_bank *pin_bank;
1617*4882a593Smuzhiyun
1618*4882a593Smuzhiyun pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
1619*4882a593Smuzhiyun if (!pci)
1620*4882a593Smuzhiyun return -ENOMEM;
1621*4882a593Smuzhiyun
1622*4882a593Smuzhiyun pci->dev = &pdev->dev;
1623*4882a593Smuzhiyun pci->grf_regmap = rk628->grf;
1624*4882a593Smuzhiyun
1625*4882a593Smuzhiyun pci->pinctrl_desc = rk628_pinctrl_desc;
1626*4882a593Smuzhiyun pci->groups = rk628_pin_groups;
1627*4882a593Smuzhiyun pci->num_groups = ARRAY_SIZE(rk628_pin_groups);
1628*4882a593Smuzhiyun pci->pinctrl_desc.pins = rk628_pins_desc;
1629*4882a593Smuzhiyun pci->pinctrl_desc.npins = ARRAY_SIZE(rk628_pins_desc);
1630*4882a593Smuzhiyun pci->pin_banks = rk628_pin_banks;
1631*4882a593Smuzhiyun pci->nr_banks = ARRAY_SIZE(rk628_pin_banks),
1632*4882a593Smuzhiyun
1633*4882a593Smuzhiyun platform_set_drvdata(pdev, pci);
1634*4882a593Smuzhiyun
1635*4882a593Smuzhiyun ret = rk628_pinctrl_parse_dt(pdev, pci);
1636*4882a593Smuzhiyun if (ret < 0)
1637*4882a593Smuzhiyun return ret;
1638*4882a593Smuzhiyun
1639*4882a593Smuzhiyun pci->regmap = devm_regmap_init_i2c(rk628->client,
1640*4882a593Smuzhiyun &rk628_pinctrl_regmap_config);
1641*4882a593Smuzhiyun if (IS_ERR(pci->regmap)) {
1642*4882a593Smuzhiyun ret = PTR_ERR(pci->regmap);
1643*4882a593Smuzhiyun dev_err(dev, "failed to allocate register map: %d\n", ret);
1644*4882a593Smuzhiyun return ret;
1645*4882a593Smuzhiyun }
1646*4882a593Smuzhiyun
1647*4882a593Smuzhiyun /* Add gpiochip */
1648*4882a593Smuzhiyun ret = rk628_gpiolib_register(pdev, pci);
1649*4882a593Smuzhiyun if (ret < 0) {
1650*4882a593Smuzhiyun dev_err(&pdev->dev, "Couldn't add gpiochip\n");
1651*4882a593Smuzhiyun return ret;
1652*4882a593Smuzhiyun }
1653*4882a593Smuzhiyun
1654*4882a593Smuzhiyun /* Add pinctrl */
1655*4882a593Smuzhiyun pci->pctl = devm_pinctrl_register(&pdev->dev, &pci->pinctrl_desc, pci);
1656*4882a593Smuzhiyun if (IS_ERR(pci->pctl)) {
1657*4882a593Smuzhiyun dev_err(&pdev->dev, "Couldn't add pinctrl\n");
1658*4882a593Smuzhiyun return PTR_ERR(pci->pctl);
1659*4882a593Smuzhiyun }
1660*4882a593Smuzhiyun
1661*4882a593Smuzhiyun for (bank = 0; bank < pci->nr_banks; ++bank) {
1662*4882a593Smuzhiyun pin_bank = &pci->pin_banks[bank];
1663*4882a593Smuzhiyun pin_bank->grange.name = pin_bank->name;
1664*4882a593Smuzhiyun pin_bank->grange.id = bank;
1665*4882a593Smuzhiyun pin_bank->grange.pin_base = BANK_OFFSET * bank;
1666*4882a593Smuzhiyun pin_bank->grange.base = pin_bank->gpio_chip.base;
1667*4882a593Smuzhiyun pin_bank->grange.npins = pin_bank->gpio_chip.ngpio;
1668*4882a593Smuzhiyun pin_bank->grange.gc = &pin_bank->gpio_chip;
1669*4882a593Smuzhiyun pinctrl_add_gpio_range(pci->pctl, &pin_bank->grange);
1670*4882a593Smuzhiyun }
1671*4882a593Smuzhiyun
1672*4882a593Smuzhiyun rk628_interrupts_register(pdev, pci);
1673*4882a593Smuzhiyun
1674*4882a593Smuzhiyun return 0;
1675*4882a593Smuzhiyun }
1676*4882a593Smuzhiyun
1677*4882a593Smuzhiyun static const struct of_device_id rk628_pinctrl_dt_match[] = {
1678*4882a593Smuzhiyun { .compatible = "rockchip,rk628-pinctrl" },
1679*4882a593Smuzhiyun {},
1680*4882a593Smuzhiyun };
1681*4882a593Smuzhiyun
1682*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rk628_pinctrl_dt_match);
1683*4882a593Smuzhiyun
1684*4882a593Smuzhiyun static struct platform_driver rk628_pinctrl_driver = {
1685*4882a593Smuzhiyun .probe = rk628_pinctrl_probe,
1686*4882a593Smuzhiyun .driver = {
1687*4882a593Smuzhiyun .name = "rk628-pinctrl",
1688*4882a593Smuzhiyun .of_match_table = of_match_ptr(rk628_pinctrl_dt_match),
1689*4882a593Smuzhiyun },
1690*4882a593Smuzhiyun };
1691*4882a593Smuzhiyun
1692*4882a593Smuzhiyun module_platform_driver(rk628_pinctrl_driver);
1693*4882a593Smuzhiyun
1694*4882a593Smuzhiyun MODULE_DESCRIPTION("RK628 pin control and GPIO driver");
1695*4882a593Smuzhiyun MODULE_AUTHOR("Weixin Zhou <zwx@rock-chips.com>");
1696*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1697