Merge tag 'meminit-v5.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees...
[linux-block.git] / drivers / pinctrl / pinctrl-ingenic.c
CommitLineData
af873fce 1// SPDX-License-Identifier: GPL-2.0-only
b5c23aa4
PC
2/*
3 * Ingenic SoCs pinctrl driver
4 *
5 * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
b5c23aa4
PC
6 */
7
8#include <linux/compiler.h>
28d6eeb4 9#include <linux/gpio/driver.h>
b5c23aa4
PC
10#include <linux/interrupt.h>
11#include <linux/io.h>
12#include <linux/of_device.h>
e72394e2 13#include <linux/of_irq.h>
b5c23aa4
PC
14#include <linux/of_platform.h>
15#include <linux/pinctrl/pinctrl.h>
16#include <linux/pinctrl/pinmux.h>
17#include <linux/pinctrl/pinconf.h>
18#include <linux/pinctrl/pinconf-generic.h>
19#include <linux/platform_device.h>
20#include <linux/regmap.h>
21#include <linux/slab.h>
22
23#include "core.h"
24#include "pinconf.h"
25#include "pinmux.h"
26
e72394e2
PC
27#define GPIO_PIN 0x00
28#define GPIO_MSK 0x20
29
b5c23aa4
PC
30#define JZ4740_GPIO_DATA 0x10
31#define JZ4740_GPIO_PULL_DIS 0x30
32#define JZ4740_GPIO_FUNC 0x40
33#define JZ4740_GPIO_SELECT 0x50
34#define JZ4740_GPIO_DIR 0x60
35#define JZ4740_GPIO_TRIG 0x70
36#define JZ4740_GPIO_FLAG 0x80
37
38#define JZ4770_GPIO_INT 0x10
b5c23aa4
PC
39#define JZ4770_GPIO_PAT1 0x30
40#define JZ4770_GPIO_PAT0 0x40
41#define JZ4770_GPIO_FLAG 0x50
42#define JZ4770_GPIO_PEN 0x70
43
44#define REG_SET(x) ((x) + 0x4)
45#define REG_CLEAR(x) ((x) + 0x8)
46
47#define PINS_PER_GPIO_CHIP 32
48
49enum jz_version {
50 ID_JZ4740,
f2a96765 51 ID_JZ4725B,
b5c23aa4
PC
52 ID_JZ4770,
53 ID_JZ4780,
54};
55
56struct ingenic_chip_info {
57 unsigned int num_chips;
58
59 const struct group_desc *groups;
60 unsigned int num_groups;
61
62 const struct function_desc *functions;
63 unsigned int num_functions;
64
65 const u32 *pull_ups, *pull_downs;
66};
67
68struct ingenic_pinctrl {
69 struct device *dev;
70 struct regmap *map;
71 struct pinctrl_dev *pctl;
72 struct pinctrl_pin_desc *pdesc;
73 enum jz_version version;
74
75 const struct ingenic_chip_info *info;
76};
77
e72394e2
PC
78struct ingenic_gpio_chip {
79 struct ingenic_pinctrl *jzpc;
80 struct gpio_chip gc;
81 struct irq_chip irq_chip;
82 unsigned int irq, reg_base;
83};
84
b5c23aa4
PC
85static const u32 jz4740_pull_ups[4] = {
86 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
87};
88
89static const u32 jz4740_pull_downs[4] = {
90 0x00000000, 0x00000000, 0x00000000, 0x00000000,
91};
92
93static int jz4740_mmc_1bit_pins[] = { 0x69, 0x68, 0x6a, };
94static int jz4740_mmc_4bit_pins[] = { 0x6b, 0x6c, 0x6d, };
95static int jz4740_uart0_data_pins[] = { 0x7a, 0x79, };
96static int jz4740_uart0_hwflow_pins[] = { 0x7e, 0x7f, };
97static int jz4740_uart1_data_pins[] = { 0x7e, 0x7f, };
98static int jz4740_lcd_8bit_pins[] = {
99 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x52, 0x53, 0x54,
100};
101static int jz4740_lcd_16bit_pins[] = {
102 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x55,
103};
104static int jz4740_lcd_18bit_pins[] = { 0x50, 0x51, };
105static int jz4740_lcd_18bit_tft_pins[] = { 0x56, 0x57, 0x31, 0x32, };
106static int jz4740_nand_cs1_pins[] = { 0x39, };
107static int jz4740_nand_cs2_pins[] = { 0x3a, };
108static int jz4740_nand_cs3_pins[] = { 0x3b, };
109static int jz4740_nand_cs4_pins[] = { 0x3c, };
110static int jz4740_pwm_pwm0_pins[] = { 0x77, };
111static int jz4740_pwm_pwm1_pins[] = { 0x78, };
112static int jz4740_pwm_pwm2_pins[] = { 0x79, };
113static int jz4740_pwm_pwm3_pins[] = { 0x7a, };
114static int jz4740_pwm_pwm4_pins[] = { 0x7b, };
115static int jz4740_pwm_pwm5_pins[] = { 0x7c, };
116static int jz4740_pwm_pwm6_pins[] = { 0x7e, };
117static int jz4740_pwm_pwm7_pins[] = { 0x7f, };
118
119static int jz4740_mmc_1bit_funcs[] = { 0, 0, 0, };
120static int jz4740_mmc_4bit_funcs[] = { 0, 0, 0, };
121static int jz4740_uart0_data_funcs[] = { 1, 1, };
122static int jz4740_uart0_hwflow_funcs[] = { 1, 1, };
123static int jz4740_uart1_data_funcs[] = { 2, 2, };
124static int jz4740_lcd_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
125static int jz4740_lcd_16bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, };
126static int jz4740_lcd_18bit_funcs[] = { 0, 0, };
127static int jz4740_lcd_18bit_tft_funcs[] = { 0, 0, 0, 0, };
128static int jz4740_nand_cs1_funcs[] = { 0, };
129static int jz4740_nand_cs2_funcs[] = { 0, };
130static int jz4740_nand_cs3_funcs[] = { 0, };
131static int jz4740_nand_cs4_funcs[] = { 0, };
132static int jz4740_pwm_pwm0_funcs[] = { 0, };
133static int jz4740_pwm_pwm1_funcs[] = { 0, };
134static int jz4740_pwm_pwm2_funcs[] = { 0, };
135static int jz4740_pwm_pwm3_funcs[] = { 0, };
136static int jz4740_pwm_pwm4_funcs[] = { 0, };
137static int jz4740_pwm_pwm5_funcs[] = { 0, };
138static int jz4740_pwm_pwm6_funcs[] = { 0, };
139static int jz4740_pwm_pwm7_funcs[] = { 0, };
140
141#define INGENIC_PIN_GROUP(name, id) \
142 { \
143 name, \
144 id##_pins, \
145 ARRAY_SIZE(id##_pins), \
146 id##_funcs, \
147 }
148
149static const struct group_desc jz4740_groups[] = {
150 INGENIC_PIN_GROUP("mmc-1bit", jz4740_mmc_1bit),
151 INGENIC_PIN_GROUP("mmc-4bit", jz4740_mmc_4bit),
152 INGENIC_PIN_GROUP("uart0-data", jz4740_uart0_data),
153 INGENIC_PIN_GROUP("uart0-hwflow", jz4740_uart0_hwflow),
154 INGENIC_PIN_GROUP("uart1-data", jz4740_uart1_data),
155 INGENIC_PIN_GROUP("lcd-8bit", jz4740_lcd_8bit),
156 INGENIC_PIN_GROUP("lcd-16bit", jz4740_lcd_16bit),
157 INGENIC_PIN_GROUP("lcd-18bit", jz4740_lcd_18bit),
158 INGENIC_PIN_GROUP("lcd-18bit-tft", jz4740_lcd_18bit_tft),
159 { "lcd-no-pins", },
160 INGENIC_PIN_GROUP("nand-cs1", jz4740_nand_cs1),
161 INGENIC_PIN_GROUP("nand-cs2", jz4740_nand_cs2),
162 INGENIC_PIN_GROUP("nand-cs3", jz4740_nand_cs3),
163 INGENIC_PIN_GROUP("nand-cs4", jz4740_nand_cs4),
164 INGENIC_PIN_GROUP("pwm0", jz4740_pwm_pwm0),
165 INGENIC_PIN_GROUP("pwm1", jz4740_pwm_pwm1),
166 INGENIC_PIN_GROUP("pwm2", jz4740_pwm_pwm2),
167 INGENIC_PIN_GROUP("pwm3", jz4740_pwm_pwm3),
168 INGENIC_PIN_GROUP("pwm4", jz4740_pwm_pwm4),
169 INGENIC_PIN_GROUP("pwm5", jz4740_pwm_pwm5),
170 INGENIC_PIN_GROUP("pwm6", jz4740_pwm_pwm6),
171 INGENIC_PIN_GROUP("pwm7", jz4740_pwm_pwm7),
172};
173
174static const char *jz4740_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
175static const char *jz4740_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
176static const char *jz4740_uart1_groups[] = { "uart1-data", };
177static const char *jz4740_lcd_groups[] = {
178 "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-18bit-tft", "lcd-no-pins",
179};
180static const char *jz4740_nand_groups[] = {
181 "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
182};
183static const char *jz4740_pwm0_groups[] = { "pwm0", };
184static const char *jz4740_pwm1_groups[] = { "pwm1", };
185static const char *jz4740_pwm2_groups[] = { "pwm2", };
186static const char *jz4740_pwm3_groups[] = { "pwm3", };
187static const char *jz4740_pwm4_groups[] = { "pwm4", };
188static const char *jz4740_pwm5_groups[] = { "pwm5", };
189static const char *jz4740_pwm6_groups[] = { "pwm6", };
190static const char *jz4740_pwm7_groups[] = { "pwm7", };
191
192static const struct function_desc jz4740_functions[] = {
193 { "mmc", jz4740_mmc_groups, ARRAY_SIZE(jz4740_mmc_groups), },
194 { "uart0", jz4740_uart0_groups, ARRAY_SIZE(jz4740_uart0_groups), },
195 { "uart1", jz4740_uart1_groups, ARRAY_SIZE(jz4740_uart1_groups), },
196 { "lcd", jz4740_lcd_groups, ARRAY_SIZE(jz4740_lcd_groups), },
197 { "nand", jz4740_nand_groups, ARRAY_SIZE(jz4740_nand_groups), },
198 { "pwm0", jz4740_pwm0_groups, ARRAY_SIZE(jz4740_pwm0_groups), },
199 { "pwm1", jz4740_pwm1_groups, ARRAY_SIZE(jz4740_pwm1_groups), },
200 { "pwm2", jz4740_pwm2_groups, ARRAY_SIZE(jz4740_pwm2_groups), },
201 { "pwm3", jz4740_pwm3_groups, ARRAY_SIZE(jz4740_pwm3_groups), },
202 { "pwm4", jz4740_pwm4_groups, ARRAY_SIZE(jz4740_pwm4_groups), },
203 { "pwm5", jz4740_pwm5_groups, ARRAY_SIZE(jz4740_pwm5_groups), },
204 { "pwm6", jz4740_pwm6_groups, ARRAY_SIZE(jz4740_pwm6_groups), },
205 { "pwm7", jz4740_pwm7_groups, ARRAY_SIZE(jz4740_pwm7_groups), },
206};
207
208static const struct ingenic_chip_info jz4740_chip_info = {
209 .num_chips = 4,
210 .groups = jz4740_groups,
211 .num_groups = ARRAY_SIZE(jz4740_groups),
212 .functions = jz4740_functions,
213 .num_functions = ARRAY_SIZE(jz4740_functions),
214 .pull_ups = jz4740_pull_ups,
215 .pull_downs = jz4740_pull_downs,
216};
217
f2a96765
PC
218static int jz4725b_mmc0_1bit_pins[] = { 0x48, 0x49, 0x5c, };
219static int jz4725b_mmc0_4bit_pins[] = { 0x5d, 0x5b, 0x56, };
220static int jz4725b_mmc1_1bit_pins[] = { 0x7a, 0x7b, 0x7c, };
221static int jz4725b_mmc1_4bit_pins[] = { 0x7d, 0x7e, 0x7f, };
222static int jz4725b_uart_data_pins[] = { 0x4c, 0x4d, };
223static int jz4725b_nand_cs1_pins[] = { 0x55, };
224static int jz4725b_nand_cs2_pins[] = { 0x56, };
225static int jz4725b_nand_cs3_pins[] = { 0x57, };
226static int jz4725b_nand_cs4_pins[] = { 0x58, };
227static int jz4725b_nand_cle_ale_pins[] = { 0x48, 0x49 };
228static int jz4725b_nand_fre_fwe_pins[] = { 0x5c, 0x5d };
229static int jz4725b_pwm_pwm0_pins[] = { 0x4a, };
230static int jz4725b_pwm_pwm1_pins[] = { 0x4b, };
231static int jz4725b_pwm_pwm2_pins[] = { 0x4c, };
232static int jz4725b_pwm_pwm3_pins[] = { 0x4d, };
233static int jz4725b_pwm_pwm4_pins[] = { 0x4e, };
234static int jz4725b_pwm_pwm5_pins[] = { 0x4f, };
a3240f09
PC
235static int jz4725b_lcd_8bit_pins[] = {
236 0x72, 0x73, 0x74,
237 0x60, 0x61, 0x62, 0x63,
238 0x64, 0x65, 0x66, 0x67,
239};
240static int jz4725b_lcd_16bit_pins[] = {
241 0x68, 0x69, 0x6a, 0x6b,
242 0x6c, 0x6d, 0x6e, 0x6f,
243};
244static int jz4725b_lcd_18bit_pins[] = { 0x70, 0x71, };
245static int jz4725b_lcd_24bit_pins[] = { 0x76, 0x77, 0x78, 0x79, };
246static int jz4725b_lcd_special_pins[] = { 0x76, 0x77, 0x78, 0x79, };
247static int jz4725b_lcd_generic_pins[] = { 0x75, };
f2a96765
PC
248
249static int jz4725b_mmc0_1bit_funcs[] = { 1, 1, 1, };
250static int jz4725b_mmc0_4bit_funcs[] = { 1, 0, 1, };
251static int jz4725b_mmc1_1bit_funcs[] = { 0, 0, 0, };
252static int jz4725b_mmc1_4bit_funcs[] = { 0, 0, 0, };
253static int jz4725b_uart_data_funcs[] = { 1, 1, };
254static int jz4725b_nand_cs1_funcs[] = { 0, };
255static int jz4725b_nand_cs2_funcs[] = { 0, };
256static int jz4725b_nand_cs3_funcs[] = { 0, };
257static int jz4725b_nand_cs4_funcs[] = { 0, };
258static int jz4725b_nand_cle_ale_funcs[] = { 0, 0, };
259static int jz4725b_nand_fre_fwe_funcs[] = { 0, 0, };
260static int jz4725b_pwm_pwm0_funcs[] = { 0, };
261static int jz4725b_pwm_pwm1_funcs[] = { 0, };
262static int jz4725b_pwm_pwm2_funcs[] = { 0, };
263static int jz4725b_pwm_pwm3_funcs[] = { 0, };
264static int jz4725b_pwm_pwm4_funcs[] = { 0, };
265static int jz4725b_pwm_pwm5_funcs[] = { 0, };
a3240f09
PC
266static int jz4725b_lcd_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
267static int jz4725b_lcd_16bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
268static int jz4725b_lcd_18bit_funcs[] = { 0, 0, };
269static int jz4725b_lcd_24bit_funcs[] = { 1, 1, 1, 1, };
270static int jz4725b_lcd_special_funcs[] = { 0, 0, 0, 0, };
271static int jz4725b_lcd_generic_funcs[] = { 0, };
f2a96765
PC
272
273static const struct group_desc jz4725b_groups[] = {
274 INGENIC_PIN_GROUP("mmc0-1bit", jz4725b_mmc0_1bit),
275 INGENIC_PIN_GROUP("mmc0-4bit", jz4725b_mmc0_4bit),
276 INGENIC_PIN_GROUP("mmc1-1bit", jz4725b_mmc1_1bit),
277 INGENIC_PIN_GROUP("mmc1-4bit", jz4725b_mmc1_4bit),
278 INGENIC_PIN_GROUP("uart-data", jz4725b_uart_data),
279 INGENIC_PIN_GROUP("nand-cs1", jz4725b_nand_cs1),
280 INGENIC_PIN_GROUP("nand-cs2", jz4725b_nand_cs2),
281 INGENIC_PIN_GROUP("nand-cs3", jz4725b_nand_cs3),
282 INGENIC_PIN_GROUP("nand-cs4", jz4725b_nand_cs4),
283 INGENIC_PIN_GROUP("nand-cle-ale", jz4725b_nand_cle_ale),
284 INGENIC_PIN_GROUP("nand-fre-fwe", jz4725b_nand_fre_fwe),
285 INGENIC_PIN_GROUP("pwm0", jz4725b_pwm_pwm0),
286 INGENIC_PIN_GROUP("pwm1", jz4725b_pwm_pwm1),
287 INGENIC_PIN_GROUP("pwm2", jz4725b_pwm_pwm2),
288 INGENIC_PIN_GROUP("pwm3", jz4725b_pwm_pwm3),
289 INGENIC_PIN_GROUP("pwm4", jz4725b_pwm_pwm4),
290 INGENIC_PIN_GROUP("pwm5", jz4725b_pwm_pwm5),
a3240f09
PC
291 INGENIC_PIN_GROUP("lcd-8bit", jz4725b_lcd_8bit),
292 INGENIC_PIN_GROUP("lcd-16bit", jz4725b_lcd_16bit),
293 INGENIC_PIN_GROUP("lcd-18bit", jz4725b_lcd_18bit),
294 INGENIC_PIN_GROUP("lcd-24bit", jz4725b_lcd_24bit),
295 INGENIC_PIN_GROUP("lcd-special", jz4725b_lcd_special),
296 INGENIC_PIN_GROUP("lcd-generic", jz4725b_lcd_generic),
f2a96765
PC
297};
298
299static const char *jz4725b_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", };
300static const char *jz4725b_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
301static const char *jz4725b_uart_groups[] = { "uart-data", };
302static const char *jz4725b_nand_groups[] = {
303 "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
304 "nand-cle-ale", "nand-fre-fwe",
305};
306static const char *jz4725b_pwm0_groups[] = { "pwm0", };
307static const char *jz4725b_pwm1_groups[] = { "pwm1", };
308static const char *jz4725b_pwm2_groups[] = { "pwm2", };
309static const char *jz4725b_pwm3_groups[] = { "pwm3", };
310static const char *jz4725b_pwm4_groups[] = { "pwm4", };
311static const char *jz4725b_pwm5_groups[] = { "pwm5", };
a3240f09
PC
312static const char *jz4725b_lcd_groups[] = {
313 "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit",
314 "lcd-special", "lcd-generic",
315};
f2a96765
PC
316
317static const struct function_desc jz4725b_functions[] = {
318 { "mmc0", jz4725b_mmc0_groups, ARRAY_SIZE(jz4725b_mmc0_groups), },
319 { "mmc1", jz4725b_mmc1_groups, ARRAY_SIZE(jz4725b_mmc1_groups), },
320 { "uart", jz4725b_uart_groups, ARRAY_SIZE(jz4725b_uart_groups), },
321 { "nand", jz4725b_nand_groups, ARRAY_SIZE(jz4725b_nand_groups), },
322 { "pwm0", jz4725b_pwm0_groups, ARRAY_SIZE(jz4725b_pwm0_groups), },
323 { "pwm1", jz4725b_pwm1_groups, ARRAY_SIZE(jz4725b_pwm1_groups), },
324 { "pwm2", jz4725b_pwm2_groups, ARRAY_SIZE(jz4725b_pwm2_groups), },
325 { "pwm3", jz4725b_pwm3_groups, ARRAY_SIZE(jz4725b_pwm3_groups), },
326 { "pwm4", jz4725b_pwm4_groups, ARRAY_SIZE(jz4725b_pwm4_groups), },
327 { "pwm5", jz4725b_pwm5_groups, ARRAY_SIZE(jz4725b_pwm5_groups), },
a3240f09 328 { "lcd", jz4725b_lcd_groups, ARRAY_SIZE(jz4725b_lcd_groups), },
f2a96765
PC
329};
330
331static const struct ingenic_chip_info jz4725b_chip_info = {
332 .num_chips = 4,
333 .groups = jz4725b_groups,
334 .num_groups = ARRAY_SIZE(jz4725b_groups),
335 .functions = jz4725b_functions,
336 .num_functions = ARRAY_SIZE(jz4725b_functions),
337 .pull_ups = jz4740_pull_ups,
338 .pull_downs = jz4740_pull_downs,
339};
340
b5c23aa4
PC
341static const u32 jz4770_pull_ups[6] = {
342 0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
343};
344
345static const u32 jz4770_pull_downs[6] = {
346 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0,
347};
348
349static int jz4770_uart0_data_pins[] = { 0xa0, 0xa3, };
350static int jz4770_uart0_hwflow_pins[] = { 0xa1, 0xa2, };
351static int jz4770_uart1_data_pins[] = { 0x7a, 0x7c, };
352static int jz4770_uart1_hwflow_pins[] = { 0x7b, 0x7d, };
ff656e47
ZY
353static int jz4770_uart2_data_pins[] = { 0x5c, 0x5e, };
354static int jz4770_uart2_hwflow_pins[] = { 0x5d, 0x5f, };
b5c23aa4
PC
355static int jz4770_uart3_data_pins[] = { 0x6c, 0x85, };
356static int jz4770_uart3_hwflow_pins[] = { 0x88, 0x89, };
b5c23aa4 357static int jz4770_mmc0_1bit_a_pins[] = { 0x12, 0x13, 0x14, };
ff656e47 358static int jz4770_mmc0_4bit_a_pins[] = { 0x15, 0x16, 0x17, };
b5c23aa4 359static int jz4770_mmc0_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
ff656e47
ZY
360static int jz4770_mmc0_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
361static int jz4770_mmc0_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
b5c23aa4 362static int jz4770_mmc1_1bit_d_pins[] = { 0x78, 0x79, 0x74, };
ff656e47 363static int jz4770_mmc1_4bit_d_pins[] = { 0x75, 0x76, 0x77, };
b5c23aa4 364static int jz4770_mmc1_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
ff656e47
ZY
365static int jz4770_mmc1_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
366static int jz4770_mmc1_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
5de1a73e
ZY
367static int jz4770_mmc2_1bit_b_pins[] = { 0x3c, 0x3d, 0x34, };
368static int jz4770_mmc2_4bit_b_pins[] = { 0x35, 0x3e, 0x3f, };
369static int jz4770_mmc2_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
370static int jz4770_mmc2_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
371static int jz4770_mmc2_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
ff656e47 372static int jz4770_nemc_8bit_data_pins[] = {
b5c23aa4
PC
373 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
374};
ff656e47
ZY
375static int jz4770_nemc_16bit_data_pins[] = {
376 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
377};
b5c23aa4
PC
378static int jz4770_nemc_cle_ale_pins[] = { 0x20, 0x21, };
379static int jz4770_nemc_addr_pins[] = { 0x22, 0x23, 0x24, 0x25, };
380static int jz4770_nemc_rd_we_pins[] = { 0x10, 0x11, };
381static int jz4770_nemc_frd_fwe_pins[] = { 0x12, 0x13, };
5de1a73e 382static int jz4770_nemc_wait_pins[] = { 0x1b, };
b5c23aa4
PC
383static int jz4770_nemc_cs1_pins[] = { 0x15, };
384static int jz4770_nemc_cs2_pins[] = { 0x16, };
385static int jz4770_nemc_cs3_pins[] = { 0x17, };
386static int jz4770_nemc_cs4_pins[] = { 0x18, };
387static int jz4770_nemc_cs5_pins[] = { 0x19, };
388static int jz4770_nemc_cs6_pins[] = { 0x1a, };
ff656e47
ZY
389static int jz4770_i2c0_pins[] = { 0x7e, 0x7f, };
390static int jz4770_i2c1_pins[] = { 0x9e, 0x9f, };
b5c23aa4 391static int jz4770_i2c2_pins[] = { 0xb0, 0xb1, };
ff656e47
ZY
392static int jz4770_cim_8bit_pins[] = {
393 0x26, 0x27, 0x28, 0x29,
394 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
395};
396static int jz4770_cim_12bit_pins[] = {
397 0x32, 0x33, 0xb0, 0xb1,
b5c23aa4 398};
ff656e47 399static int jz4770_lcd_24bit_pins[] = {
b5c23aa4
PC
400 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
401 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
402 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
ff656e47 403 0x58, 0x59, 0x5a, 0x5b,
b5c23aa4
PC
404};
405static int jz4770_pwm_pwm0_pins[] = { 0x80, };
406static int jz4770_pwm_pwm1_pins[] = { 0x81, };
407static int jz4770_pwm_pwm2_pins[] = { 0x82, };
408static int jz4770_pwm_pwm3_pins[] = { 0x83, };
409static int jz4770_pwm_pwm4_pins[] = { 0x84, };
410static int jz4770_pwm_pwm5_pins[] = { 0x85, };
411static int jz4770_pwm_pwm6_pins[] = { 0x6a, };
412static int jz4770_pwm_pwm7_pins[] = { 0x6b, };
5de1a73e
ZY
413static int jz4770_mac_rmii_pins[] = {
414 0xa9, 0xab, 0xaa, 0xac, 0xa5, 0xa4, 0xad, 0xae, 0xa6, 0xa8,
415};
416static int jz4770_mac_mii_pins[] = { 0xa7, 0xaf, };
b5c23aa4
PC
417
418static int jz4770_uart0_data_funcs[] = { 0, 0, };
419static int jz4770_uart0_hwflow_funcs[] = { 0, 0, };
420static int jz4770_uart1_data_funcs[] = { 0, 0, };
421static int jz4770_uart1_hwflow_funcs[] = { 0, 0, };
ff656e47
ZY
422static int jz4770_uart2_data_funcs[] = { 0, 0, };
423static int jz4770_uart2_hwflow_funcs[] = { 0, 0, };
b5c23aa4
PC
424static int jz4770_uart3_data_funcs[] = { 0, 1, };
425static int jz4770_uart3_hwflow_funcs[] = { 0, 0, };
b5c23aa4 426static int jz4770_mmc0_1bit_a_funcs[] = { 1, 1, 0, };
ff656e47 427static int jz4770_mmc0_4bit_a_funcs[] = { 1, 1, 1, };
b5c23aa4 428static int jz4770_mmc0_1bit_e_funcs[] = { 0, 0, 0, };
ff656e47
ZY
429static int jz4770_mmc0_4bit_e_funcs[] = { 0, 0, 0, };
430static int jz4770_mmc0_8bit_e_funcs[] = { 0, 0, 0, 0, };
b5c23aa4 431static int jz4770_mmc1_1bit_d_funcs[] = { 0, 0, 0, };
ff656e47 432static int jz4770_mmc1_4bit_d_funcs[] = { 0, 0, 0, };
b5c23aa4 433static int jz4770_mmc1_1bit_e_funcs[] = { 1, 1, 1, };
ff656e47
ZY
434static int jz4770_mmc1_4bit_e_funcs[] = { 1, 1, 1, };
435static int jz4770_mmc1_8bit_e_funcs[] = { 1, 1, 1, 1, };
5de1a73e
ZY
436static int jz4770_mmc2_1bit_b_funcs[] = { 0, 0, 0, };
437static int jz4770_mmc2_4bit_b_funcs[] = { 0, 0, 0, };
438static int jz4770_mmc2_1bit_e_funcs[] = { 2, 2, 2, };
439static int jz4770_mmc2_4bit_e_funcs[] = { 2, 2, 2, };
440static int jz4770_mmc2_8bit_e_funcs[] = { 2, 2, 2, 2, };
ff656e47
ZY
441static int jz4770_nemc_8bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
442static int jz4770_nemc_16bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
b5c23aa4
PC
443static int jz4770_nemc_cle_ale_funcs[] = { 0, 0, };
444static int jz4770_nemc_addr_funcs[] = { 0, 0, 0, 0, };
445static int jz4770_nemc_rd_we_funcs[] = { 0, 0, };
446static int jz4770_nemc_frd_fwe_funcs[] = { 0, 0, };
5de1a73e 447static int jz4770_nemc_wait_funcs[] = { 0, };
b5c23aa4
PC
448static int jz4770_nemc_cs1_funcs[] = { 0, };
449static int jz4770_nemc_cs2_funcs[] = { 0, };
450static int jz4770_nemc_cs3_funcs[] = { 0, };
451static int jz4770_nemc_cs4_funcs[] = { 0, };
452static int jz4770_nemc_cs5_funcs[] = { 0, };
453static int jz4770_nemc_cs6_funcs[] = { 0, };
454static int jz4770_i2c0_funcs[] = { 0, 0, };
455static int jz4770_i2c1_funcs[] = { 0, 0, };
456static int jz4770_i2c2_funcs[] = { 2, 2, };
ff656e47
ZY
457static int jz4770_cim_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
458static int jz4770_cim_12bit_funcs[] = { 0, 0, 0, 0, };
459static int jz4770_lcd_24bit_funcs[] = {
460 0, 0, 0, 0, 0, 0, 0, 0,
b5c23aa4
PC
461 0, 0, 0, 0, 0, 0, 0, 0,
462 0, 0, 0, 0, 0, 0, 0, 0,
ff656e47 463 0, 0, 0, 0,
b5c23aa4
PC
464};
465static int jz4770_pwm_pwm0_funcs[] = { 0, };
466static int jz4770_pwm_pwm1_funcs[] = { 0, };
467static int jz4770_pwm_pwm2_funcs[] = { 0, };
468static int jz4770_pwm_pwm3_funcs[] = { 0, };
469static int jz4770_pwm_pwm4_funcs[] = { 0, };
470static int jz4770_pwm_pwm5_funcs[] = { 0, };
471static int jz4770_pwm_pwm6_funcs[] = { 0, };
472static int jz4770_pwm_pwm7_funcs[] = { 0, };
5de1a73e
ZY
473static int jz4770_mac_rmii_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
474static int jz4770_mac_mii_funcs[] = { 0, 0, };
b5c23aa4
PC
475
476static const struct group_desc jz4770_groups[] = {
477 INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
478 INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow),
479 INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data),
480 INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow),
481 INGENIC_PIN_GROUP("uart2-data", jz4770_uart2_data),
482 INGENIC_PIN_GROUP("uart2-hwflow", jz4770_uart2_hwflow),
483 INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data),
484 INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow),
b5c23aa4 485 INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a),
ff656e47 486 INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a),
b5c23aa4 487 INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e),
ff656e47
ZY
488 INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e),
489 INGENIC_PIN_GROUP("mmc0-8bit-e", jz4770_mmc0_8bit_e),
b5c23aa4 490 INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d),
ff656e47 491 INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d),
b5c23aa4 492 INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e),
ff656e47
ZY
493 INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e),
494 INGENIC_PIN_GROUP("mmc1-8bit-e", jz4770_mmc1_8bit_e),
5de1a73e
ZY
495 INGENIC_PIN_GROUP("mmc2-1bit-b", jz4770_mmc2_1bit_b),
496 INGENIC_PIN_GROUP("mmc2-4bit-b", jz4770_mmc2_4bit_b),
497 INGENIC_PIN_GROUP("mmc2-1bit-e", jz4770_mmc2_1bit_e),
498 INGENIC_PIN_GROUP("mmc2-4bit-e", jz4770_mmc2_4bit_e),
499 INGENIC_PIN_GROUP("mmc2-8bit-e", jz4770_mmc2_8bit_e),
ff656e47
ZY
500 INGENIC_PIN_GROUP("nemc-8bit-data", jz4770_nemc_8bit_data),
501 INGENIC_PIN_GROUP("nemc-16bit-data", jz4770_nemc_16bit_data),
b5c23aa4
PC
502 INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale),
503 INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr),
504 INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we),
505 INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe),
5de1a73e 506 INGENIC_PIN_GROUP("nemc-wait", jz4770_nemc_wait),
b5c23aa4
PC
507 INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1),
508 INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2),
509 INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3),
510 INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4),
511 INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5),
512 INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6),
513 INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0),
514 INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1),
515 INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2),
ff656e47
ZY
516 INGENIC_PIN_GROUP("cim-data-8bit", jz4770_cim_8bit),
517 INGENIC_PIN_GROUP("cim-data-12bit", jz4770_cim_12bit),
518 INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit),
b5c23aa4
PC
519 { "lcd-no-pins", },
520 INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0),
521 INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1),
522 INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2),
523 INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3),
524 INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4),
525 INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5),
526 INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6),
527 INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
5de1a73e
ZY
528 INGENIC_PIN_GROUP("mac-rmii", jz4770_mac_rmii),
529 INGENIC_PIN_GROUP("mac-mii", jz4770_mac_mii),
b5c23aa4
PC
530};
531
532static const char *jz4770_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
533static const char *jz4770_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
534static const char *jz4770_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
535static const char *jz4770_uart3_groups[] = { "uart3-data", "uart3-hwflow", };
b5c23aa4 536static const char *jz4770_mmc0_groups[] = {
ff656e47
ZY
537 "mmc0-1bit-a", "mmc0-4bit-a",
538 "mmc0-1bit-e", "mmc0-4bit-e", "mmc0-8bit-e",
b5c23aa4
PC
539};
540static const char *jz4770_mmc1_groups[] = {
ff656e47
ZY
541 "mmc1-1bit-d", "mmc1-4bit-d",
542 "mmc1-1bit-e", "mmc1-4bit-e", "mmc1-8bit-e",
b5c23aa4 543};
5de1a73e
ZY
544static const char *jz4770_mmc2_groups[] = {
545 "mmc2-1bit-b", "mmc2-4bit-b",
546 "mmc2-1bit-e", "mmc2-4bit-e", "mmc2-8bit-e",
547};
b5c23aa4 548static const char *jz4770_nemc_groups[] = {
ff656e47 549 "nemc-8bit-data", "nemc-16bit-data", "nemc-cle-ale",
5de1a73e 550 "nemc-addr", "nemc-rd-we", "nemc-frd-fwe", "nemc-wait",
b5c23aa4
PC
551};
552static const char *jz4770_cs1_groups[] = { "nemc-cs1", };
ff656e47
ZY
553static const char *jz4770_cs2_groups[] = { "nemc-cs2", };
554static const char *jz4770_cs3_groups[] = { "nemc-cs3", };
555static const char *jz4770_cs4_groups[] = { "nemc-cs4", };
556static const char *jz4770_cs5_groups[] = { "nemc-cs5", };
b5c23aa4
PC
557static const char *jz4770_cs6_groups[] = { "nemc-cs6", };
558static const char *jz4770_i2c0_groups[] = { "i2c0-data", };
559static const char *jz4770_i2c1_groups[] = { "i2c1-data", };
560static const char *jz4770_i2c2_groups[] = { "i2c2-data", };
ff656e47
ZY
561static const char *jz4770_cim_groups[] = { "cim-data-8bit", "cim-data-12bit", };
562static const char *jz4770_lcd_groups[] = { "lcd-24bit", "lcd-no-pins", };
b5c23aa4
PC
563static const char *jz4770_pwm0_groups[] = { "pwm0", };
564static const char *jz4770_pwm1_groups[] = { "pwm1", };
565static const char *jz4770_pwm2_groups[] = { "pwm2", };
566static const char *jz4770_pwm3_groups[] = { "pwm3", };
567static const char *jz4770_pwm4_groups[] = { "pwm4", };
568static const char *jz4770_pwm5_groups[] = { "pwm5", };
569static const char *jz4770_pwm6_groups[] = { "pwm6", };
570static const char *jz4770_pwm7_groups[] = { "pwm7", };
5de1a73e 571static const char *jz4770_mac_groups[] = { "mac-rmii", "mac-mii", };
b5c23aa4
PC
572
573static const struct function_desc jz4770_functions[] = {
574 { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
575 { "uart1", jz4770_uart1_groups, ARRAY_SIZE(jz4770_uart1_groups), },
576 { "uart2", jz4770_uart2_groups, ARRAY_SIZE(jz4770_uart2_groups), },
577 { "uart3", jz4770_uart3_groups, ARRAY_SIZE(jz4770_uart3_groups), },
b5c23aa4
PC
578 { "mmc0", jz4770_mmc0_groups, ARRAY_SIZE(jz4770_mmc0_groups), },
579 { "mmc1", jz4770_mmc1_groups, ARRAY_SIZE(jz4770_mmc1_groups), },
5de1a73e 580 { "mmc2", jz4770_mmc2_groups, ARRAY_SIZE(jz4770_mmc2_groups), },
b5c23aa4
PC
581 { "nemc", jz4770_nemc_groups, ARRAY_SIZE(jz4770_nemc_groups), },
582 { "nemc-cs1", jz4770_cs1_groups, ARRAY_SIZE(jz4770_cs1_groups), },
ff656e47
ZY
583 { "nemc-cs2", jz4770_cs2_groups, ARRAY_SIZE(jz4770_cs2_groups), },
584 { "nemc-cs3", jz4770_cs3_groups, ARRAY_SIZE(jz4770_cs3_groups), },
585 { "nemc-cs4", jz4770_cs4_groups, ARRAY_SIZE(jz4770_cs4_groups), },
586 { "nemc-cs5", jz4770_cs5_groups, ARRAY_SIZE(jz4770_cs5_groups), },
b5c23aa4
PC
587 { "nemc-cs6", jz4770_cs6_groups, ARRAY_SIZE(jz4770_cs6_groups), },
588 { "i2c0", jz4770_i2c0_groups, ARRAY_SIZE(jz4770_i2c0_groups), },
589 { "i2c1", jz4770_i2c1_groups, ARRAY_SIZE(jz4770_i2c1_groups), },
590 { "i2c2", jz4770_i2c2_groups, ARRAY_SIZE(jz4770_i2c2_groups), },
b5c23aa4
PC
591 { "cim", jz4770_cim_groups, ARRAY_SIZE(jz4770_cim_groups), },
592 { "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), },
593 { "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), },
594 { "pwm1", jz4770_pwm1_groups, ARRAY_SIZE(jz4770_pwm1_groups), },
595 { "pwm2", jz4770_pwm2_groups, ARRAY_SIZE(jz4770_pwm2_groups), },
596 { "pwm3", jz4770_pwm3_groups, ARRAY_SIZE(jz4770_pwm3_groups), },
597 { "pwm4", jz4770_pwm4_groups, ARRAY_SIZE(jz4770_pwm4_groups), },
598 { "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
599 { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
600 { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
5de1a73e 601 { "mac", jz4770_mac_groups, ARRAY_SIZE(jz4770_mac_groups), },
b5c23aa4
PC
602};
603
604static const struct ingenic_chip_info jz4770_chip_info = {
605 .num_chips = 6,
606 .groups = jz4770_groups,
607 .num_groups = ARRAY_SIZE(jz4770_groups),
608 .functions = jz4770_functions,
609 .num_functions = ARRAY_SIZE(jz4770_functions),
610 .pull_ups = jz4770_pull_ups,
611 .pull_downs = jz4770_pull_downs,
612};
613
ff656e47
ZY
614static int jz4780_uart2_data_pins[] = { 0x66, 0x67, };
615static int jz4780_uart2_hwflow_pins[] = { 0x65, 0x64, };
616static int jz4780_uart4_data_pins[] = { 0x54, 0x4a, };
617static int jz4780_mmc0_8bit_a_pins[] = { 0x04, 0x05, 0x06, 0x07, 0x18, };
618static int jz4780_i2c3_pins[] = { 0x6a, 0x6b, };
619static int jz4780_i2c4_e_pins[] = { 0x8c, 0x8d, };
620static int jz4780_i2c4_f_pins[] = { 0xb9, 0xb8, };
621
622static int jz4780_uart2_data_funcs[] = { 1, 1, };
623static int jz4780_uart2_hwflow_funcs[] = { 1, 1, };
624static int jz4780_uart4_data_funcs[] = { 2, 2, };
625static int jz4780_mmc0_8bit_a_funcs[] = { 1, 1, 1, 1, 1, };
626static int jz4780_i2c3_funcs[] = { 1, 1, };
627static int jz4780_i2c4_e_funcs[] = { 1, 1, };
628static int jz4780_i2c4_f_funcs[] = { 1, 1, };
629
630static const struct group_desc jz4780_groups[] = {
631 INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
632 INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow),
633 INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data),
634 INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow),
635 INGENIC_PIN_GROUP("uart2-data", jz4780_uart2_data),
636 INGENIC_PIN_GROUP("uart2-hwflow", jz4780_uart2_hwflow),
637 INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data),
638 INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow),
639 INGENIC_PIN_GROUP("uart4-data", jz4780_uart4_data),
640 INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a),
641 INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a),
642 INGENIC_PIN_GROUP("mmc0-8bit-a", jz4780_mmc0_8bit_a),
643 INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e),
644 INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e),
645 INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d),
646 INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d),
647 INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e),
648 INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e),
5de1a73e
ZY
649 INGENIC_PIN_GROUP("mmc2-1bit-b", jz4770_mmc2_1bit_b),
650 INGENIC_PIN_GROUP("mmc2-4bit-b", jz4770_mmc2_4bit_b),
651 INGENIC_PIN_GROUP("mmc2-1bit-e", jz4770_mmc2_1bit_e),
652 INGENIC_PIN_GROUP("mmc2-4bit-e", jz4770_mmc2_4bit_e),
ff656e47
ZY
653 INGENIC_PIN_GROUP("nemc-data", jz4770_nemc_8bit_data),
654 INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale),
655 INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr),
656 INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we),
657 INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe),
5de1a73e 658 INGENIC_PIN_GROUP("nemc-wait", jz4770_nemc_wait),
ff656e47
ZY
659 INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1),
660 INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2),
661 INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3),
662 INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4),
663 INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5),
664 INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6),
665 INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0),
666 INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1),
667 INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2),
668 INGENIC_PIN_GROUP("i2c3-data", jz4780_i2c3),
669 INGENIC_PIN_GROUP("i2c4-data-e", jz4780_i2c4_e),
670 INGENIC_PIN_GROUP("i2c4-data-f", jz4780_i2c4_f),
671 INGENIC_PIN_GROUP("cim-data", jz4770_cim_8bit),
672 INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit),
673 { "lcd-no-pins", },
674 INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0),
675 INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1),
676 INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2),
677 INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3),
678 INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4),
679 INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5),
680 INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6),
681 INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
682};
683
684static const char *jz4780_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
685static const char *jz4780_uart4_groups[] = { "uart4-data", };
686static const char *jz4780_mmc0_groups[] = {
687 "mmc0-1bit-a", "mmc0-4bit-a", "mmc0-8bit-a",
688 "mmc0-1bit-e", "mmc0-4bit-e",
689};
690static const char *jz4780_mmc1_groups[] = {
691 "mmc1-1bit-d", "mmc1-4bit-d", "mmc1-1bit-e", "mmc1-4bit-e",
692};
5de1a73e
ZY
693static const char *jz4780_mmc2_groups[] = {
694 "mmc2-1bit-b", "mmc2-4bit-b", "mmc2-1bit-e", "mmc2-4bit-e",
695};
ff656e47
ZY
696static const char *jz4780_nemc_groups[] = {
697 "nemc-data", "nemc-cle-ale", "nemc-addr",
5de1a73e 698 "nemc-rd-we", "nemc-frd-fwe", "nemc-wait",
ff656e47
ZY
699};
700static const char *jz4780_i2c3_groups[] = { "i2c3-data", };
701static const char *jz4780_i2c4_groups[] = { "i2c4-data-e", "i2c4-data-f", };
702static const char *jz4780_cim_groups[] = { "cim-data", };
703
704static const struct function_desc jz4780_functions[] = {
705 { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
706 { "uart1", jz4770_uart1_groups, ARRAY_SIZE(jz4770_uart1_groups), },
707 { "uart2", jz4780_uart2_groups, ARRAY_SIZE(jz4780_uart2_groups), },
708 { "uart3", jz4770_uart3_groups, ARRAY_SIZE(jz4770_uart3_groups), },
709 { "uart4", jz4780_uart4_groups, ARRAY_SIZE(jz4780_uart4_groups), },
710 { "mmc0", jz4780_mmc0_groups, ARRAY_SIZE(jz4780_mmc0_groups), },
711 { "mmc1", jz4780_mmc1_groups, ARRAY_SIZE(jz4780_mmc1_groups), },
5de1a73e 712 { "mmc2", jz4780_mmc2_groups, ARRAY_SIZE(jz4780_mmc2_groups), },
ff656e47
ZY
713 { "nemc", jz4780_nemc_groups, ARRAY_SIZE(jz4780_nemc_groups), },
714 { "nemc-cs1", jz4770_cs1_groups, ARRAY_SIZE(jz4770_cs1_groups), },
715 { "nemc-cs2", jz4770_cs2_groups, ARRAY_SIZE(jz4770_cs2_groups), },
716 { "nemc-cs3", jz4770_cs3_groups, ARRAY_SIZE(jz4770_cs3_groups), },
717 { "nemc-cs4", jz4770_cs4_groups, ARRAY_SIZE(jz4770_cs4_groups), },
718 { "nemc-cs5", jz4770_cs5_groups, ARRAY_SIZE(jz4770_cs5_groups), },
719 { "nemc-cs6", jz4770_cs6_groups, ARRAY_SIZE(jz4770_cs6_groups), },
720 { "i2c0", jz4770_i2c0_groups, ARRAY_SIZE(jz4770_i2c0_groups), },
721 { "i2c1", jz4770_i2c1_groups, ARRAY_SIZE(jz4770_i2c1_groups), },
722 { "i2c2", jz4770_i2c2_groups, ARRAY_SIZE(jz4770_i2c2_groups), },
723 { "i2c3", jz4780_i2c3_groups, ARRAY_SIZE(jz4780_i2c3_groups), },
724 { "i2c4", jz4780_i2c4_groups, ARRAY_SIZE(jz4780_i2c4_groups), },
725 { "cim", jz4780_cim_groups, ARRAY_SIZE(jz4780_cim_groups), },
726 { "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), },
727 { "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), },
728 { "pwm1", jz4770_pwm1_groups, ARRAY_SIZE(jz4770_pwm1_groups), },
729 { "pwm2", jz4770_pwm2_groups, ARRAY_SIZE(jz4770_pwm2_groups), },
730 { "pwm3", jz4770_pwm3_groups, ARRAY_SIZE(jz4770_pwm3_groups), },
731 { "pwm4", jz4770_pwm4_groups, ARRAY_SIZE(jz4770_pwm4_groups), },
732 { "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
733 { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
734 { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
735};
736
737static const struct ingenic_chip_info jz4780_chip_info = {
738 .num_chips = 6,
739 .groups = jz4780_groups,
740 .num_groups = ARRAY_SIZE(jz4780_groups),
741 .functions = jz4780_functions,
742 .num_functions = ARRAY_SIZE(jz4780_functions),
743 .pull_ups = jz4770_pull_ups,
744 .pull_downs = jz4770_pull_downs,
745};
746
b71c1844 747static u32 ingenic_gpio_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg)
e72394e2
PC
748{
749 unsigned int val;
750
751 regmap_read(jzgc->jzpc->map, jzgc->reg_base + reg, &val);
752
753 return (u32) val;
754}
755
b71c1844 756static void ingenic_gpio_set_bit(struct ingenic_gpio_chip *jzgc,
e72394e2
PC
757 u8 reg, u8 offset, bool set)
758{
759 if (set)
760 reg = REG_SET(reg);
761 else
762 reg = REG_CLEAR(reg);
763
764 regmap_write(jzgc->jzpc->map, jzgc->reg_base + reg, BIT(offset));
765}
766
767static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc,
768 u8 offset)
769{
b71c1844 770 unsigned int val = ingenic_gpio_read_reg(jzgc, GPIO_PIN);
e72394e2
PC
771
772 return !!(val & BIT(offset));
773}
774
775static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc,
776 u8 offset, int value)
777{
778 if (jzgc->jzpc->version >= ID_JZ4770)
b71c1844 779 ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
e72394e2 780 else
b71c1844 781 ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
e72394e2
PC
782}
783
784static void irq_set_type(struct ingenic_gpio_chip *jzgc,
785 u8 offset, unsigned int type)
786{
787 u8 reg1, reg2;
788
789 if (jzgc->jzpc->version >= ID_JZ4770) {
790 reg1 = JZ4770_GPIO_PAT1;
791 reg2 = JZ4770_GPIO_PAT0;
792 } else {
793 reg1 = JZ4740_GPIO_TRIG;
794 reg2 = JZ4740_GPIO_DIR;
795 }
796
797 switch (type) {
798 case IRQ_TYPE_EDGE_RISING:
b71c1844
ZY
799 ingenic_gpio_set_bit(jzgc, reg2, offset, true);
800 ingenic_gpio_set_bit(jzgc, reg1, offset, true);
e72394e2
PC
801 break;
802 case IRQ_TYPE_EDGE_FALLING:
b71c1844
ZY
803 ingenic_gpio_set_bit(jzgc, reg2, offset, false);
804 ingenic_gpio_set_bit(jzgc, reg1, offset, true);
e72394e2
PC
805 break;
806 case IRQ_TYPE_LEVEL_HIGH:
b71c1844
ZY
807 ingenic_gpio_set_bit(jzgc, reg2, offset, true);
808 ingenic_gpio_set_bit(jzgc, reg1, offset, false);
e72394e2
PC
809 break;
810 case IRQ_TYPE_LEVEL_LOW:
811 default:
b71c1844
ZY
812 ingenic_gpio_set_bit(jzgc, reg2, offset, false);
813 ingenic_gpio_set_bit(jzgc, reg1, offset, false);
e72394e2
PC
814 break;
815 }
816}
817
818static void ingenic_gpio_irq_mask(struct irq_data *irqd)
819{
820 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
821 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
822
b71c1844 823 ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
e72394e2
PC
824}
825
826static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
827{
828 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
829 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
830
b71c1844 831 ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
e72394e2
PC
832}
833
834static void ingenic_gpio_irq_enable(struct irq_data *irqd)
835{
836 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
837 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
838 int irq = irqd->hwirq;
839
840 if (jzgc->jzpc->version >= ID_JZ4770)
b71c1844 841 ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
e72394e2 842 else
b71c1844 843 ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
e72394e2
PC
844
845 ingenic_gpio_irq_unmask(irqd);
846}
847
848static void ingenic_gpio_irq_disable(struct irq_data *irqd)
849{
850 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
851 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
852 int irq = irqd->hwirq;
853
854 ingenic_gpio_irq_mask(irqd);
855
856 if (jzgc->jzpc->version >= ID_JZ4770)
b71c1844 857 ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
e72394e2 858 else
b71c1844 859 ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
e72394e2
PC
860}
861
862static void ingenic_gpio_irq_ack(struct irq_data *irqd)
863{
864 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
865 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
866 int irq = irqd->hwirq;
867 bool high;
868
869 if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) {
870 /*
871 * Switch to an interrupt for the opposite edge to the one that
872 * triggered the interrupt being ACKed.
873 */
874 high = ingenic_gpio_get_value(jzgc, irq);
875 if (high)
876 irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
877 else
878 irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
879 }
880
881 if (jzgc->jzpc->version >= ID_JZ4770)
b71c1844 882 ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
e72394e2 883 else
b71c1844 884 ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
e72394e2
PC
885}
886
887static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
888{
889 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
890 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
891
892 switch (type) {
893 case IRQ_TYPE_EDGE_BOTH:
894 case IRQ_TYPE_EDGE_RISING:
895 case IRQ_TYPE_EDGE_FALLING:
896 irq_set_handler_locked(irqd, handle_edge_irq);
897 break;
898 case IRQ_TYPE_LEVEL_HIGH:
899 case IRQ_TYPE_LEVEL_LOW:
900 irq_set_handler_locked(irqd, handle_level_irq);
901 break;
902 default:
903 irq_set_handler_locked(irqd, handle_bad_irq);
904 }
905
906 if (type == IRQ_TYPE_EDGE_BOTH) {
907 /*
908 * The hardware does not support interrupts on both edges. The
909 * best we can do is to set up a single-edge interrupt and then
910 * switch to the opposing edge when ACKing the interrupt.
911 */
912 bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq);
913
914 type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
915 }
916
917 irq_set_type(jzgc, irqd->hwirq, type);
918 return 0;
919}
920
921static int ingenic_gpio_irq_set_wake(struct irq_data *irqd, unsigned int on)
922{
923 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
924 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
925
926 return irq_set_irq_wake(jzgc->irq, on);
927}
928
929static void ingenic_gpio_irq_handler(struct irq_desc *desc)
930{
931 struct gpio_chip *gc = irq_desc_get_handler_data(desc);
932 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
933 struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data);
934 unsigned long flag, i;
935
936 chained_irq_enter(irq_chip, desc);
937
938 if (jzgc->jzpc->version >= ID_JZ4770)
b71c1844 939 flag = ingenic_gpio_read_reg(jzgc, JZ4770_GPIO_FLAG);
e72394e2 940 else
b71c1844 941 flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG);
e72394e2
PC
942
943 for_each_set_bit(i, &flag, 32)
944 generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
945 chained_irq_exit(irq_chip, desc);
946}
947
948static void ingenic_gpio_set(struct gpio_chip *gc,
949 unsigned int offset, int value)
950{
951 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
952
953 ingenic_gpio_set_value(jzgc, offset, value);
954}
955
956static int ingenic_gpio_get(struct gpio_chip *gc, unsigned int offset)
957{
958 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
959
960 return (int) ingenic_gpio_get_value(jzgc, offset);
961}
962
963static int ingenic_gpio_direction_input(struct gpio_chip *gc,
964 unsigned int offset)
965{
966 return pinctrl_gpio_direction_input(gc->base + offset);
967}
968
969static int ingenic_gpio_direction_output(struct gpio_chip *gc,
970 unsigned int offset, int value)
971{
972 ingenic_gpio_set(gc, offset, value);
973 return pinctrl_gpio_direction_output(gc->base + offset);
974}
975
b5c23aa4
PC
976static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
977 unsigned int pin, u8 reg, bool set)
978{
979 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
980 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
981
982 regmap_write(jzpc->map, offt * 0x100 +
983 (set ? REG_SET(reg) : REG_CLEAR(reg)), BIT(idx));
984}
985
986static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
987 unsigned int pin, u8 reg)
988{
989 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
990 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
991 unsigned int val;
992
993 regmap_read(jzpc->map, offt * 0x100 + reg, &val);
994
995 return val & BIT(idx);
996}
997
ebd66514
PC
998static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
999{
1000 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1001 struct ingenic_pinctrl *jzpc = jzgc->jzpc;
1002 unsigned int pin = gc->base + offset;
1003
1004 if (jzpc->version >= ID_JZ4770)
1005 return ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1);
1006
1007 if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT))
1008 return true;
1009
1010 return !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR);
1011}
1012
5bf7b849 1013static const struct pinctrl_ops ingenic_pctlops = {
b5c23aa4
PC
1014 .get_groups_count = pinctrl_generic_get_group_count,
1015 .get_group_name = pinctrl_generic_get_group_name,
1016 .get_group_pins = pinctrl_generic_get_group_pins,
1017 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
1018 .dt_free_map = pinconf_generic_dt_free_map,
1019};
1020
1021static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
1022 int pin, int func)
1023{
1024 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1025 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1026
1027 dev_dbg(jzpc->dev, "set pin P%c%u to function %u\n",
1028 'A' + offt, idx, func);
1029
1030 if (jzpc->version >= ID_JZ4770) {
1031 ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
e72394e2 1032 ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
b5c23aa4
PC
1033 ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
1034 ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
1035 } else {
1036 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
1037 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
1038 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
1039 }
1040
1041 return 0;
1042}
1043
1044static int ingenic_pinmux_set_mux(struct pinctrl_dev *pctldev,
1045 unsigned int selector, unsigned int group)
1046{
1047 struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1048 struct function_desc *func;
1049 struct group_desc *grp;
1050 unsigned int i;
1051
1052 func = pinmux_generic_get_function(pctldev, selector);
1053 if (!func)
1054 return -EINVAL;
1055
1056 grp = pinctrl_generic_get_group(pctldev, group);
1057 if (!grp)
1058 return -EINVAL;
1059
1060 dev_dbg(pctldev->dev, "enable function %s group %s\n",
1061 func->name, grp->name);
1062
1063 for (i = 0; i < grp->num_pins; i++) {
1064 int *pin_modes = grp->data;
1065
1066 ingenic_pinmux_set_pin_fn(jzpc, grp->pins[i], pin_modes[i]);
1067 }
1068
1069 return 0;
1070}
1071
1072static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
1073 struct pinctrl_gpio_range *range,
1074 unsigned int pin, bool input)
1075{
1076 struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1077 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1078 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1079
1080 dev_dbg(pctldev->dev, "set pin P%c%u to %sput\n",
1081 'A' + offt, idx, input ? "in" : "out");
1082
1083 if (jzpc->version >= ID_JZ4770) {
1084 ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
e72394e2 1085 ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
b5c23aa4
PC
1086 ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
1087 } else {
1088 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
0084a786 1089 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, !input);
b5c23aa4
PC
1090 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
1091 }
1092
1093 return 0;
1094}
1095
5bf7b849 1096static const struct pinmux_ops ingenic_pmxops = {
b5c23aa4
PC
1097 .get_functions_count = pinmux_generic_get_function_count,
1098 .get_function_name = pinmux_generic_get_function_name,
1099 .get_function_groups = pinmux_generic_get_function_groups,
1100 .set_mux = ingenic_pinmux_set_mux,
1101 .gpio_set_direction = ingenic_pinmux_gpio_set_direction,
1102};
1103
1104static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
1105 unsigned int pin, unsigned long *config)
1106{
1107 struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1108 enum pin_config_param param = pinconf_to_config_param(*config);
1109 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1110 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1111 bool pull;
1112
1113 if (jzpc->version >= ID_JZ4770)
1114 pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
1115 else
1116 pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
1117
1118 switch (param) {
1119 case PIN_CONFIG_BIAS_DISABLE:
1120 if (pull)
1121 return -EINVAL;
1122 break;
1123
1124 case PIN_CONFIG_BIAS_PULL_UP:
1125 if (!pull || !(jzpc->info->pull_ups[offt] & BIT(idx)))
1126 return -EINVAL;
1127 break;
1128
1129 case PIN_CONFIG_BIAS_PULL_DOWN:
1130 if (!pull || !(jzpc->info->pull_downs[offt] & BIT(idx)))
1131 return -EINVAL;
1132 break;
1133
1134 default:
1135 return -ENOTSUPP;
1136 }
1137
1138 *config = pinconf_to_config_packed(param, 1);
1139 return 0;
1140}
1141
1142static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
1143 unsigned int pin, bool enabled)
1144{
1145 if (jzpc->version >= ID_JZ4770)
1146 ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !enabled);
1147 else
1148 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
1149}
1150
1151static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
1152 unsigned long *configs, unsigned int num_configs)
1153{
1154 struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1155 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1156 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1157 unsigned int cfg;
1158
1159 for (cfg = 0; cfg < num_configs; cfg++) {
1160 switch (pinconf_to_config_param(configs[cfg])) {
1161 case PIN_CONFIG_BIAS_DISABLE:
1162 case PIN_CONFIG_BIAS_PULL_UP:
1163 case PIN_CONFIG_BIAS_PULL_DOWN:
1164 continue;
1165 default:
1166 return -ENOTSUPP;
1167 }
1168 }
1169
1170 for (cfg = 0; cfg < num_configs; cfg++) {
1171 switch (pinconf_to_config_param(configs[cfg])) {
1172 case PIN_CONFIG_BIAS_DISABLE:
1173 dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
1174 'A' + offt, idx);
1175 ingenic_set_bias(jzpc, pin, false);
1176 break;
1177
1178 case PIN_CONFIG_BIAS_PULL_UP:
1179 if (!(jzpc->info->pull_ups[offt] & BIT(idx)))
1180 return -EINVAL;
1181 dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
1182 'A' + offt, idx);
1183 ingenic_set_bias(jzpc, pin, true);
1184 break;
1185
1186 case PIN_CONFIG_BIAS_PULL_DOWN:
1187 if (!(jzpc->info->pull_downs[offt] & BIT(idx)))
1188 return -EINVAL;
1189 dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
1190 'A' + offt, idx);
1191 ingenic_set_bias(jzpc, pin, true);
1192 break;
1193
1194 default:
1195 unreachable();
1196 }
1197 }
1198
1199 return 0;
1200}
1201
1202static int ingenic_pinconf_group_get(struct pinctrl_dev *pctldev,
1203 unsigned int group, unsigned long *config)
1204{
1205 const unsigned int *pins;
1206 unsigned int i, npins, old = 0;
1207 int ret;
1208
1209 ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
1210 if (ret)
1211 return ret;
1212
1213 for (i = 0; i < npins; i++) {
1214 if (ingenic_pinconf_get(pctldev, pins[i], config))
1215 return -ENOTSUPP;
1216
1217 /* configs do not match between two pins */
1218 if (i && (old != *config))
1219 return -ENOTSUPP;
1220
1221 old = *config;
1222 }
1223
1224 return 0;
1225}
1226
1227static int ingenic_pinconf_group_set(struct pinctrl_dev *pctldev,
1228 unsigned int group, unsigned long *configs,
1229 unsigned int num_configs)
1230{
1231 const unsigned int *pins;
1232 unsigned int i, npins;
1233 int ret;
1234
1235 ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
1236 if (ret)
1237 return ret;
1238
1239 for (i = 0; i < npins; i++) {
1240 ret = ingenic_pinconf_set(pctldev,
1241 pins[i], configs, num_configs);
1242 if (ret)
1243 return ret;
1244 }
1245
1246 return 0;
1247}
1248
5bf7b849 1249static const struct pinconf_ops ingenic_confops = {
b5c23aa4
PC
1250 .is_generic = true,
1251 .pin_config_get = ingenic_pinconf_get,
1252 .pin_config_set = ingenic_pinconf_set,
1253 .pin_config_group_get = ingenic_pinconf_group_get,
1254 .pin_config_group_set = ingenic_pinconf_group_set,
1255};
1256
1257static const struct regmap_config ingenic_pinctrl_regmap_config = {
1258 .reg_bits = 32,
1259 .val_bits = 32,
1260 .reg_stride = 4,
1261};
1262
1263static const struct of_device_id ingenic_pinctrl_of_match[] = {
1264 { .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
f2a96765 1265 { .compatible = "ingenic,jz4725b-pinctrl", .data = (void *)ID_JZ4725B },
b5c23aa4
PC
1266 { .compatible = "ingenic,jz4770-pinctrl", .data = (void *) ID_JZ4770 },
1267 { .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
1268 {},
1269};
1270
e72394e2
PC
1271static const struct of_device_id ingenic_gpio_of_match[] __initconst = {
1272 { .compatible = "ingenic,jz4740-gpio", },
1273 { .compatible = "ingenic,jz4770-gpio", },
1274 { .compatible = "ingenic,jz4780-gpio", },
1275 {},
1276};
1277
1278static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
1279 struct device_node *node)
1280{
1281 struct ingenic_gpio_chip *jzgc;
1282 struct device *dev = jzpc->dev;
1283 unsigned int bank;
1284 int err;
1285
1286 err = of_property_read_u32(node, "reg", &bank);
1287 if (err) {
1288 dev_err(dev, "Cannot read \"reg\" property: %i\n", err);
1289 return err;
1290 }
1291
1292 jzgc = devm_kzalloc(dev, sizeof(*jzgc), GFP_KERNEL);
1293 if (!jzgc)
1294 return -ENOMEM;
1295
1296 jzgc->jzpc = jzpc;
1297 jzgc->reg_base = bank * 0x100;
1298
1299 jzgc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "GPIO%c", 'A' + bank);
1300 if (!jzgc->gc.label)
1301 return -ENOMEM;
1302
1303 /* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
1304 * ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
1305 * <linux/gpio/consumer.h> INSTEAD.
1306 */
1307 jzgc->gc.base = bank * 32;
1308
1309 jzgc->gc.ngpio = 32;
1310 jzgc->gc.parent = dev;
1311 jzgc->gc.of_node = node;
1312 jzgc->gc.owner = THIS_MODULE;
1313
1314 jzgc->gc.set = ingenic_gpio_set;
1315 jzgc->gc.get = ingenic_gpio_get;
1316 jzgc->gc.direction_input = ingenic_gpio_direction_input;
1317 jzgc->gc.direction_output = ingenic_gpio_direction_output;
ebd66514 1318 jzgc->gc.get_direction = ingenic_gpio_get_direction;
e72394e2
PC
1319
1320 if (of_property_read_bool(node, "gpio-ranges")) {
1321 jzgc->gc.request = gpiochip_generic_request;
1322 jzgc->gc.free = gpiochip_generic_free;
1323 }
1324
1325 err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
1326 if (err)
1327 return err;
1328
1329 jzgc->irq = irq_of_parse_and_map(node, 0);
1330 if (!jzgc->irq)
1331 return -EINVAL;
1332
1333 jzgc->irq_chip.name = jzgc->gc.label;
1334 jzgc->irq_chip.irq_enable = ingenic_gpio_irq_enable;
1335 jzgc->irq_chip.irq_disable = ingenic_gpio_irq_disable;
1336 jzgc->irq_chip.irq_unmask = ingenic_gpio_irq_unmask;
1337 jzgc->irq_chip.irq_mask = ingenic_gpio_irq_mask;
1338 jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
1339 jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
1340 jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
1341 jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
1342
1343 err = gpiochip_irqchip_add(&jzgc->gc, &jzgc->irq_chip, 0,
1344 handle_level_irq, IRQ_TYPE_NONE);
1345 if (err)
1346 return err;
1347
1348 gpiochip_set_chained_irqchip(&jzgc->gc, &jzgc->irq_chip,
1349 jzgc->irq, ingenic_gpio_irq_handler);
1350 return 0;
1351}
1352
4717b11f 1353static int __init ingenic_pinctrl_probe(struct platform_device *pdev)
b5c23aa4
PC
1354{
1355 struct device *dev = &pdev->dev;
1356 struct ingenic_pinctrl *jzpc;
1357 struct pinctrl_desc *pctl_desc;
1358 void __iomem *base;
1359 const struct platform_device_id *id = platform_get_device_id(pdev);
1360 const struct of_device_id *of_id = of_match_device(
1361 ingenic_pinctrl_of_match, dev);
1362 const struct ingenic_chip_info *chip_info;
e72394e2 1363 struct device_node *node;
b5c23aa4
PC
1364 unsigned int i;
1365 int err;
1366
1367 jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
1368 if (!jzpc)
1369 return -ENOMEM;
1370
1371 base = devm_ioremap_resource(dev,
1372 platform_get_resource(pdev, IORESOURCE_MEM, 0));
119fcf47 1373 if (IS_ERR(base))
b5c23aa4 1374 return PTR_ERR(base);
b5c23aa4
PC
1375
1376 jzpc->map = devm_regmap_init_mmio(dev, base,
1377 &ingenic_pinctrl_regmap_config);
1378 if (IS_ERR(jzpc->map)) {
1379 dev_err(dev, "Failed to create regmap\n");
1380 return PTR_ERR(jzpc->map);
1381 }
1382
1383 jzpc->dev = dev;
1384
1385 if (of_id)
1386 jzpc->version = (enum jz_version)of_id->data;
1387 else
1388 jzpc->version = (enum jz_version)id->driver_data;
1389
ff656e47
ZY
1390 if (jzpc->version >= ID_JZ4780)
1391 chip_info = &jz4780_chip_info;
1392 else if (jzpc->version >= ID_JZ4770)
b5c23aa4 1393 chip_info = &jz4770_chip_info;
f2a96765
PC
1394 else if (jzpc->version >= ID_JZ4725B)
1395 chip_info = &jz4725b_chip_info;
b5c23aa4
PC
1396 else
1397 chip_info = &jz4740_chip_info;
1398 jzpc->info = chip_info;
1399
1400 pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
1401 if (!pctl_desc)
1402 return -ENOMEM;
1403
1404 /* fill in pinctrl_desc structure */
1405 pctl_desc->name = dev_name(dev);
1406 pctl_desc->owner = THIS_MODULE;
1407 pctl_desc->pctlops = &ingenic_pctlops;
1408 pctl_desc->pmxops = &ingenic_pmxops;
1409 pctl_desc->confops = &ingenic_confops;
1410 pctl_desc->npins = chip_info->num_chips * PINS_PER_GPIO_CHIP;
a86854d0
KC
1411 pctl_desc->pins = jzpc->pdesc = devm_kcalloc(&pdev->dev,
1412 pctl_desc->npins, sizeof(*jzpc->pdesc), GFP_KERNEL);
b5c23aa4
PC
1413 if (!jzpc->pdesc)
1414 return -ENOMEM;
1415
1416 for (i = 0; i < pctl_desc->npins; i++) {
1417 jzpc->pdesc[i].number = i;
1418 jzpc->pdesc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
1419 'A' + (i / PINS_PER_GPIO_CHIP),
1420 i % PINS_PER_GPIO_CHIP);
1421 }
1422
1423 jzpc->pctl = devm_pinctrl_register(dev, pctl_desc, jzpc);
e7f4c4bf 1424 if (IS_ERR(jzpc->pctl)) {
b5c23aa4 1425 dev_err(dev, "Failed to register pinctrl\n");
e7f4c4bf 1426 return PTR_ERR(jzpc->pctl);
b5c23aa4
PC
1427 }
1428
1429 for (i = 0; i < chip_info->num_groups; i++) {
1430 const struct group_desc *group = &chip_info->groups[i];
1431
1432 err = pinctrl_generic_add_group(jzpc->pctl, group->name,
1433 group->pins, group->num_pins, group->data);
823dd71f 1434 if (err < 0) {
b5c23aa4
PC
1435 dev_err(dev, "Failed to register group %s\n",
1436 group->name);
1437 return err;
1438 }
1439 }
1440
1441 for (i = 0; i < chip_info->num_functions; i++) {
1442 const struct function_desc *func = &chip_info->functions[i];
1443
1444 err = pinmux_generic_add_function(jzpc->pctl, func->name,
1445 func->group_names, func->num_group_names,
1446 func->data);
823dd71f 1447 if (err < 0) {
b5c23aa4
PC
1448 dev_err(dev, "Failed to register function %s\n",
1449 func->name);
1450 return err;
1451 }
1452 }
1453
1454 dev_set_drvdata(dev, jzpc->map);
1455
e72394e2
PC
1456 for_each_child_of_node(dev->of_node, node) {
1457 if (of_match_node(ingenic_gpio_of_match, node)) {
1458 err = ingenic_gpio_probe(jzpc, node);
1459 if (err)
1460 return err;
b5c23aa4
PC
1461 }
1462 }
1463
1464 return 0;
1465}
1466
1467static const struct platform_device_id ingenic_pinctrl_ids[] = {
1468 { "jz4740-pinctrl", ID_JZ4740 },
f2a96765 1469 { "jz4725b-pinctrl", ID_JZ4725B },
b5c23aa4
PC
1470 { "jz4770-pinctrl", ID_JZ4770 },
1471 { "jz4780-pinctrl", ID_JZ4780 },
1472 {},
1473};
1474
1475static struct platform_driver ingenic_pinctrl_driver = {
1476 .driver = {
1477 .name = "pinctrl-ingenic",
1478 .of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
b5c23aa4 1479 },
b5c23aa4
PC
1480 .id_table = ingenic_pinctrl_ids,
1481};
1482
1483static int __init ingenic_pinctrl_drv_register(void)
1484{
4717b11f
PC
1485 return platform_driver_probe(&ingenic_pinctrl_driver,
1486 ingenic_pinctrl_probe);
b5c23aa4 1487}
556a36a7 1488subsys_initcall(ingenic_pinctrl_drv_register);