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