blob: aacd3b88b2ad7f409e11c12e33a77aceeb1c1f2e [file] [log] [blame]
Thomas Gleixneraf873fc2019-05-28 09:57:21 -07001// SPDX-License-Identifier: GPL-2.0-only
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002/*
3 * Ingenic SoCs pinctrl driver
4 *
5 * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
Zhou Yanjie5d215952019-07-14 11:53:56 +08006 * Copyright (c) 2019 Zhou Yanjie <zhouyanjie@zoho.com>
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02007 */
8
9#include <linux/compiler.h>
Linus Walleij28d6eeb2018-08-29 13:39:54 +020010#include <linux/gpio/driver.h>
Paul Cercueilb5c23aa2017-05-12 18:52:56 +020011#include <linux/interrupt.h>
12#include <linux/io.h>
13#include <linux/of_device.h>
Paul Cercueile72394e2018-08-21 18:42:32 +020014#include <linux/of_irq.h>
Paul Cercueilb5c23aa2017-05-12 18:52:56 +020015#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
Paul Cercueile72394e2018-08-21 18:42:32 +020028#define GPIO_PIN 0x00
29#define GPIO_MSK 0x20
30
Paul Cercueilb5c23aa2017-05-12 18:52:56 +020031#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
Zhou Yanjie0257595a2019-07-14 11:53:52 +080039#define JZ4760_GPIO_INT 0x10
40#define JZ4760_GPIO_PAT1 0x30
41#define JZ4760_GPIO_PAT0 0x40
42#define JZ4760_GPIO_FLAG 0x50
43#define JZ4760_GPIO_PEN 0x70
Paul Cercueilb5c23aa2017-05-12 18:52:56 +020044
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +080045#define X1000_GPIO_PZ_BASE 0x700
46#define X1000_GPIO_PZ_GID2LD 0x7f0
47
Paul Cercueilb5c23aa2017-05-12 18:52:56 +020048#define REG_SET(x) ((x) + 0x4)
49#define REG_CLEAR(x) ((x) + 0x8)
50
51#define PINS_PER_GPIO_CHIP 32
52
53enum jz_version {
54 ID_JZ4740,
Paul Cercueilf2a96762018-08-21 18:42:34 +020055 ID_JZ4725B,
Zhou Yanjie0257595a2019-07-14 11:53:52 +080056 ID_JZ4760,
57 ID_JZ4760B,
Paul Cercueilb5c23aa2017-05-12 18:52:56 +020058 ID_JZ4770,
59 ID_JZ4780,
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +080060 ID_X1000,
61 ID_X1000E,
Zhou Yanjie5d215952019-07-14 11:53:56 +080062 ID_X1500,
Paul Cercueilb5c23aa2017-05-12 18:52:56 +020063};
64
65struct ingenic_chip_info {
66 unsigned int num_chips;
67
68 const struct group_desc *groups;
69 unsigned int num_groups;
70
71 const struct function_desc *functions;
72 unsigned int num_functions;
73
74 const u32 *pull_ups, *pull_downs;
75};
76
77struct ingenic_pinctrl {
78 struct device *dev;
79 struct regmap *map;
80 struct pinctrl_dev *pctl;
81 struct pinctrl_pin_desc *pdesc;
82 enum jz_version version;
83
84 const struct ingenic_chip_info *info;
85};
86
Paul Cercueile72394e2018-08-21 18:42:32 +020087struct ingenic_gpio_chip {
88 struct ingenic_pinctrl *jzpc;
89 struct gpio_chip gc;
90 struct irq_chip irq_chip;
91 unsigned int irq, reg_base;
92};
93
Paul Cercueilb5c23aa2017-05-12 18:52:56 +020094static const u32 jz4740_pull_ups[4] = {
95 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
96};
97
98static const u32 jz4740_pull_downs[4] = {
99 0x00000000, 0x00000000, 0x00000000, 0x00000000,
100};
101
102static int jz4740_mmc_1bit_pins[] = { 0x69, 0x68, 0x6a, };
103static int jz4740_mmc_4bit_pins[] = { 0x6b, 0x6c, 0x6d, };
104static int jz4740_uart0_data_pins[] = { 0x7a, 0x79, };
105static int jz4740_uart0_hwflow_pins[] = { 0x7e, 0x7f, };
106static int jz4740_uart1_data_pins[] = { 0x7e, 0x7f, };
107static int jz4740_lcd_8bit_pins[] = {
108 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x52, 0x53, 0x54,
109};
110static int jz4740_lcd_16bit_pins[] = {
111 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x55,
112};
113static int jz4740_lcd_18bit_pins[] = { 0x50, 0x51, };
114static int jz4740_lcd_18bit_tft_pins[] = { 0x56, 0x57, 0x31, 0x32, };
115static int jz4740_nand_cs1_pins[] = { 0x39, };
116static int jz4740_nand_cs2_pins[] = { 0x3a, };
117static int jz4740_nand_cs3_pins[] = { 0x3b, };
118static int jz4740_nand_cs4_pins[] = { 0x3c, };
119static int jz4740_pwm_pwm0_pins[] = { 0x77, };
120static int jz4740_pwm_pwm1_pins[] = { 0x78, };
121static int jz4740_pwm_pwm2_pins[] = { 0x79, };
122static int jz4740_pwm_pwm3_pins[] = { 0x7a, };
123static int jz4740_pwm_pwm4_pins[] = { 0x7b, };
124static int jz4740_pwm_pwm5_pins[] = { 0x7c, };
125static int jz4740_pwm_pwm6_pins[] = { 0x7e, };
126static int jz4740_pwm_pwm7_pins[] = { 0x7f, };
127
128static int jz4740_mmc_1bit_funcs[] = { 0, 0, 0, };
129static int jz4740_mmc_4bit_funcs[] = { 0, 0, 0, };
130static int jz4740_uart0_data_funcs[] = { 1, 1, };
131static int jz4740_uart0_hwflow_funcs[] = { 1, 1, };
132static int jz4740_uart1_data_funcs[] = { 2, 2, };
133static int jz4740_lcd_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
134static int jz4740_lcd_16bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, };
135static int jz4740_lcd_18bit_funcs[] = { 0, 0, };
136static int jz4740_lcd_18bit_tft_funcs[] = { 0, 0, 0, 0, };
137static int jz4740_nand_cs1_funcs[] = { 0, };
138static int jz4740_nand_cs2_funcs[] = { 0, };
139static int jz4740_nand_cs3_funcs[] = { 0, };
140static int jz4740_nand_cs4_funcs[] = { 0, };
141static int jz4740_pwm_pwm0_funcs[] = { 0, };
142static int jz4740_pwm_pwm1_funcs[] = { 0, };
143static int jz4740_pwm_pwm2_funcs[] = { 0, };
144static int jz4740_pwm_pwm3_funcs[] = { 0, };
145static int jz4740_pwm_pwm4_funcs[] = { 0, };
146static int jz4740_pwm_pwm5_funcs[] = { 0, };
147static int jz4740_pwm_pwm6_funcs[] = { 0, };
148static int jz4740_pwm_pwm7_funcs[] = { 0, };
149
150#define INGENIC_PIN_GROUP(name, id) \
151 { \
152 name, \
153 id##_pins, \
154 ARRAY_SIZE(id##_pins), \
155 id##_funcs, \
156 }
157
158static const struct group_desc jz4740_groups[] = {
159 INGENIC_PIN_GROUP("mmc-1bit", jz4740_mmc_1bit),
160 INGENIC_PIN_GROUP("mmc-4bit", jz4740_mmc_4bit),
161 INGENIC_PIN_GROUP("uart0-data", jz4740_uart0_data),
162 INGENIC_PIN_GROUP("uart0-hwflow", jz4740_uart0_hwflow),
163 INGENIC_PIN_GROUP("uart1-data", jz4740_uart1_data),
164 INGENIC_PIN_GROUP("lcd-8bit", jz4740_lcd_8bit),
165 INGENIC_PIN_GROUP("lcd-16bit", jz4740_lcd_16bit),
166 INGENIC_PIN_GROUP("lcd-18bit", jz4740_lcd_18bit),
167 INGENIC_PIN_GROUP("lcd-18bit-tft", jz4740_lcd_18bit_tft),
168 { "lcd-no-pins", },
169 INGENIC_PIN_GROUP("nand-cs1", jz4740_nand_cs1),
170 INGENIC_PIN_GROUP("nand-cs2", jz4740_nand_cs2),
171 INGENIC_PIN_GROUP("nand-cs3", jz4740_nand_cs3),
172 INGENIC_PIN_GROUP("nand-cs4", jz4740_nand_cs4),
173 INGENIC_PIN_GROUP("pwm0", jz4740_pwm_pwm0),
174 INGENIC_PIN_GROUP("pwm1", jz4740_pwm_pwm1),
175 INGENIC_PIN_GROUP("pwm2", jz4740_pwm_pwm2),
176 INGENIC_PIN_GROUP("pwm3", jz4740_pwm_pwm3),
177 INGENIC_PIN_GROUP("pwm4", jz4740_pwm_pwm4),
178 INGENIC_PIN_GROUP("pwm5", jz4740_pwm_pwm5),
179 INGENIC_PIN_GROUP("pwm6", jz4740_pwm_pwm6),
180 INGENIC_PIN_GROUP("pwm7", jz4740_pwm_pwm7),
181};
182
183static const char *jz4740_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
184static const char *jz4740_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
185static const char *jz4740_uart1_groups[] = { "uart1-data", };
186static const char *jz4740_lcd_groups[] = {
187 "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-18bit-tft", "lcd-no-pins",
188};
189static const char *jz4740_nand_groups[] = {
190 "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
191};
192static const char *jz4740_pwm0_groups[] = { "pwm0", };
193static const char *jz4740_pwm1_groups[] = { "pwm1", };
194static const char *jz4740_pwm2_groups[] = { "pwm2", };
195static const char *jz4740_pwm3_groups[] = { "pwm3", };
196static const char *jz4740_pwm4_groups[] = { "pwm4", };
197static const char *jz4740_pwm5_groups[] = { "pwm5", };
198static const char *jz4740_pwm6_groups[] = { "pwm6", };
199static const char *jz4740_pwm7_groups[] = { "pwm7", };
200
201static const struct function_desc jz4740_functions[] = {
202 { "mmc", jz4740_mmc_groups, ARRAY_SIZE(jz4740_mmc_groups), },
203 { "uart0", jz4740_uart0_groups, ARRAY_SIZE(jz4740_uart0_groups), },
204 { "uart1", jz4740_uart1_groups, ARRAY_SIZE(jz4740_uart1_groups), },
205 { "lcd", jz4740_lcd_groups, ARRAY_SIZE(jz4740_lcd_groups), },
206 { "nand", jz4740_nand_groups, ARRAY_SIZE(jz4740_nand_groups), },
207 { "pwm0", jz4740_pwm0_groups, ARRAY_SIZE(jz4740_pwm0_groups), },
208 { "pwm1", jz4740_pwm1_groups, ARRAY_SIZE(jz4740_pwm1_groups), },
209 { "pwm2", jz4740_pwm2_groups, ARRAY_SIZE(jz4740_pwm2_groups), },
210 { "pwm3", jz4740_pwm3_groups, ARRAY_SIZE(jz4740_pwm3_groups), },
211 { "pwm4", jz4740_pwm4_groups, ARRAY_SIZE(jz4740_pwm4_groups), },
212 { "pwm5", jz4740_pwm5_groups, ARRAY_SIZE(jz4740_pwm5_groups), },
213 { "pwm6", jz4740_pwm6_groups, ARRAY_SIZE(jz4740_pwm6_groups), },
214 { "pwm7", jz4740_pwm7_groups, ARRAY_SIZE(jz4740_pwm7_groups), },
215};
216
217static const struct ingenic_chip_info jz4740_chip_info = {
218 .num_chips = 4,
219 .groups = jz4740_groups,
220 .num_groups = ARRAY_SIZE(jz4740_groups),
221 .functions = jz4740_functions,
222 .num_functions = ARRAY_SIZE(jz4740_functions),
223 .pull_ups = jz4740_pull_ups,
224 .pull_downs = jz4740_pull_downs,
225};
226
Paul Cercueilf2a96762018-08-21 18:42:34 +0200227static int jz4725b_mmc0_1bit_pins[] = { 0x48, 0x49, 0x5c, };
228static int jz4725b_mmc0_4bit_pins[] = { 0x5d, 0x5b, 0x56, };
229static int jz4725b_mmc1_1bit_pins[] = { 0x7a, 0x7b, 0x7c, };
230static int jz4725b_mmc1_4bit_pins[] = { 0x7d, 0x7e, 0x7f, };
231static int jz4725b_uart_data_pins[] = { 0x4c, 0x4d, };
232static int jz4725b_nand_cs1_pins[] = { 0x55, };
233static int jz4725b_nand_cs2_pins[] = { 0x56, };
234static int jz4725b_nand_cs3_pins[] = { 0x57, };
235static int jz4725b_nand_cs4_pins[] = { 0x58, };
236static int jz4725b_nand_cle_ale_pins[] = { 0x48, 0x49 };
237static int jz4725b_nand_fre_fwe_pins[] = { 0x5c, 0x5d };
238static int jz4725b_pwm_pwm0_pins[] = { 0x4a, };
239static int jz4725b_pwm_pwm1_pins[] = { 0x4b, };
240static int jz4725b_pwm_pwm2_pins[] = { 0x4c, };
241static int jz4725b_pwm_pwm3_pins[] = { 0x4d, };
242static int jz4725b_pwm_pwm4_pins[] = { 0x4e, };
243static int jz4725b_pwm_pwm5_pins[] = { 0x4f, };
Paul Cercueila3240f02019-02-07 10:55:36 -0300244static int jz4725b_lcd_8bit_pins[] = {
245 0x72, 0x73, 0x74,
246 0x60, 0x61, 0x62, 0x63,
247 0x64, 0x65, 0x66, 0x67,
248};
249static int jz4725b_lcd_16bit_pins[] = {
250 0x68, 0x69, 0x6a, 0x6b,
251 0x6c, 0x6d, 0x6e, 0x6f,
252};
253static int jz4725b_lcd_18bit_pins[] = { 0x70, 0x71, };
254static int jz4725b_lcd_24bit_pins[] = { 0x76, 0x77, 0x78, 0x79, };
255static int jz4725b_lcd_special_pins[] = { 0x76, 0x77, 0x78, 0x79, };
256static int jz4725b_lcd_generic_pins[] = { 0x75, };
Paul Cercueilf2a96762018-08-21 18:42:34 +0200257
258static int jz4725b_mmc0_1bit_funcs[] = { 1, 1, 1, };
259static int jz4725b_mmc0_4bit_funcs[] = { 1, 0, 1, };
260static int jz4725b_mmc1_1bit_funcs[] = { 0, 0, 0, };
261static int jz4725b_mmc1_4bit_funcs[] = { 0, 0, 0, };
262static int jz4725b_uart_data_funcs[] = { 1, 1, };
263static int jz4725b_nand_cs1_funcs[] = { 0, };
264static int jz4725b_nand_cs2_funcs[] = { 0, };
265static int jz4725b_nand_cs3_funcs[] = { 0, };
266static int jz4725b_nand_cs4_funcs[] = { 0, };
267static int jz4725b_nand_cle_ale_funcs[] = { 0, 0, };
268static int jz4725b_nand_fre_fwe_funcs[] = { 0, 0, };
269static int jz4725b_pwm_pwm0_funcs[] = { 0, };
270static int jz4725b_pwm_pwm1_funcs[] = { 0, };
271static int jz4725b_pwm_pwm2_funcs[] = { 0, };
272static int jz4725b_pwm_pwm3_funcs[] = { 0, };
273static int jz4725b_pwm_pwm4_funcs[] = { 0, };
274static int jz4725b_pwm_pwm5_funcs[] = { 0, };
Paul Cercueila3240f02019-02-07 10:55:36 -0300275static int jz4725b_lcd_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
276static int jz4725b_lcd_16bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
277static int jz4725b_lcd_18bit_funcs[] = { 0, 0, };
278static int jz4725b_lcd_24bit_funcs[] = { 1, 1, 1, 1, };
279static int jz4725b_lcd_special_funcs[] = { 0, 0, 0, 0, };
280static int jz4725b_lcd_generic_funcs[] = { 0, };
Paul Cercueilf2a96762018-08-21 18:42:34 +0200281
282static const struct group_desc jz4725b_groups[] = {
283 INGENIC_PIN_GROUP("mmc0-1bit", jz4725b_mmc0_1bit),
284 INGENIC_PIN_GROUP("mmc0-4bit", jz4725b_mmc0_4bit),
285 INGENIC_PIN_GROUP("mmc1-1bit", jz4725b_mmc1_1bit),
286 INGENIC_PIN_GROUP("mmc1-4bit", jz4725b_mmc1_4bit),
287 INGENIC_PIN_GROUP("uart-data", jz4725b_uart_data),
288 INGENIC_PIN_GROUP("nand-cs1", jz4725b_nand_cs1),
289 INGENIC_PIN_GROUP("nand-cs2", jz4725b_nand_cs2),
290 INGENIC_PIN_GROUP("nand-cs3", jz4725b_nand_cs3),
291 INGENIC_PIN_GROUP("nand-cs4", jz4725b_nand_cs4),
292 INGENIC_PIN_GROUP("nand-cle-ale", jz4725b_nand_cle_ale),
293 INGENIC_PIN_GROUP("nand-fre-fwe", jz4725b_nand_fre_fwe),
294 INGENIC_PIN_GROUP("pwm0", jz4725b_pwm_pwm0),
295 INGENIC_PIN_GROUP("pwm1", jz4725b_pwm_pwm1),
296 INGENIC_PIN_GROUP("pwm2", jz4725b_pwm_pwm2),
297 INGENIC_PIN_GROUP("pwm3", jz4725b_pwm_pwm3),
298 INGENIC_PIN_GROUP("pwm4", jz4725b_pwm_pwm4),
299 INGENIC_PIN_GROUP("pwm5", jz4725b_pwm_pwm5),
Paul Cercueila3240f02019-02-07 10:55:36 -0300300 INGENIC_PIN_GROUP("lcd-8bit", jz4725b_lcd_8bit),
301 INGENIC_PIN_GROUP("lcd-16bit", jz4725b_lcd_16bit),
302 INGENIC_PIN_GROUP("lcd-18bit", jz4725b_lcd_18bit),
303 INGENIC_PIN_GROUP("lcd-24bit", jz4725b_lcd_24bit),
304 INGENIC_PIN_GROUP("lcd-special", jz4725b_lcd_special),
305 INGENIC_PIN_GROUP("lcd-generic", jz4725b_lcd_generic),
Paul Cercueilf2a96762018-08-21 18:42:34 +0200306};
307
308static const char *jz4725b_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", };
309static const char *jz4725b_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
310static const char *jz4725b_uart_groups[] = { "uart-data", };
311static const char *jz4725b_nand_groups[] = {
312 "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
313 "nand-cle-ale", "nand-fre-fwe",
314};
315static const char *jz4725b_pwm0_groups[] = { "pwm0", };
316static const char *jz4725b_pwm1_groups[] = { "pwm1", };
317static const char *jz4725b_pwm2_groups[] = { "pwm2", };
318static const char *jz4725b_pwm3_groups[] = { "pwm3", };
319static const char *jz4725b_pwm4_groups[] = { "pwm4", };
320static const char *jz4725b_pwm5_groups[] = { "pwm5", };
Paul Cercueila3240f02019-02-07 10:55:36 -0300321static const char *jz4725b_lcd_groups[] = {
322 "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-24bit",
323 "lcd-special", "lcd-generic",
324};
Paul Cercueilf2a96762018-08-21 18:42:34 +0200325
326static const struct function_desc jz4725b_functions[] = {
327 { "mmc0", jz4725b_mmc0_groups, ARRAY_SIZE(jz4725b_mmc0_groups), },
328 { "mmc1", jz4725b_mmc1_groups, ARRAY_SIZE(jz4725b_mmc1_groups), },
329 { "uart", jz4725b_uart_groups, ARRAY_SIZE(jz4725b_uart_groups), },
330 { "nand", jz4725b_nand_groups, ARRAY_SIZE(jz4725b_nand_groups), },
331 { "pwm0", jz4725b_pwm0_groups, ARRAY_SIZE(jz4725b_pwm0_groups), },
332 { "pwm1", jz4725b_pwm1_groups, ARRAY_SIZE(jz4725b_pwm1_groups), },
333 { "pwm2", jz4725b_pwm2_groups, ARRAY_SIZE(jz4725b_pwm2_groups), },
334 { "pwm3", jz4725b_pwm3_groups, ARRAY_SIZE(jz4725b_pwm3_groups), },
335 { "pwm4", jz4725b_pwm4_groups, ARRAY_SIZE(jz4725b_pwm4_groups), },
336 { "pwm5", jz4725b_pwm5_groups, ARRAY_SIZE(jz4725b_pwm5_groups), },
Paul Cercueila3240f02019-02-07 10:55:36 -0300337 { "lcd", jz4725b_lcd_groups, ARRAY_SIZE(jz4725b_lcd_groups), },
Paul Cercueilf2a96762018-08-21 18:42:34 +0200338};
339
340static const struct ingenic_chip_info jz4725b_chip_info = {
341 .num_chips = 4,
342 .groups = jz4725b_groups,
343 .num_groups = ARRAY_SIZE(jz4725b_groups),
344 .functions = jz4725b_functions,
345 .num_functions = ARRAY_SIZE(jz4725b_functions),
346 .pull_ups = jz4740_pull_ups,
347 .pull_downs = jz4740_pull_downs,
348};
349
Zhou Yanjie0257595a2019-07-14 11:53:52 +0800350static const u32 jz4760_pull_ups[6] = {
351 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0xfffff00f,
352};
353
354static const u32 jz4760_pull_downs[6] = {
355 0x00000000, 0x00030c00, 0x00000000, 0x00003000, 0x00000483, 0x00000ff0,
356};
357
358static int jz4760_uart0_data_pins[] = { 0xa0, 0xa3, };
359static int jz4760_uart0_hwflow_pins[] = { 0xa1, 0xa2, };
360static int jz4760_uart1_data_pins[] = { 0x7a, 0x7c, };
361static int jz4760_uart1_hwflow_pins[] = { 0x7b, 0x7d, };
362static int jz4760_uart2_data_pins[] = { 0x5c, 0x5e, };
363static int jz4760_uart2_hwflow_pins[] = { 0x5d, 0x5f, };
364static int jz4760_uart3_data_pins[] = { 0x6c, 0x85, };
365static int jz4760_uart3_hwflow_pins[] = { 0x88, 0x89, };
366static int jz4760_mmc0_1bit_a_pins[] = { 0x12, 0x13, 0x14, };
367static int jz4760_mmc0_4bit_a_pins[] = { 0x15, 0x16, 0x17, };
368static int jz4760_mmc0_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
369static int jz4760_mmc0_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
370static int jz4760_mmc0_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
371static int jz4760_mmc1_1bit_d_pins[] = { 0x78, 0x79, 0x74, };
372static int jz4760_mmc1_4bit_d_pins[] = { 0x75, 0x76, 0x77, };
373static int jz4760_mmc1_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
374static int jz4760_mmc1_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
375static int jz4760_mmc1_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
376static int jz4760_mmc2_1bit_b_pins[] = { 0x3c, 0x3d, 0x34, };
377static int jz4760_mmc2_4bit_b_pins[] = { 0x35, 0x3e, 0x3f, };
378static int jz4760_mmc2_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
379static int jz4760_mmc2_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
380static int jz4760_mmc2_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
381static int jz4760_nemc_8bit_data_pins[] = {
382 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
383};
384static int jz4760_nemc_16bit_data_pins[] = {
385 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
386};
387static int jz4760_nemc_cle_ale_pins[] = { 0x20, 0x21, };
388static int jz4760_nemc_addr_pins[] = { 0x22, 0x23, 0x24, 0x25, };
389static int jz4760_nemc_rd_we_pins[] = { 0x10, 0x11, };
390static int jz4760_nemc_frd_fwe_pins[] = { 0x12, 0x13, };
391static int jz4760_nemc_wait_pins[] = { 0x1b, };
392static int jz4760_nemc_cs1_pins[] = { 0x15, };
393static int jz4760_nemc_cs2_pins[] = { 0x16, };
394static int jz4760_nemc_cs3_pins[] = { 0x17, };
395static int jz4760_nemc_cs4_pins[] = { 0x18, };
396static int jz4760_nemc_cs5_pins[] = { 0x19, };
397static int jz4760_nemc_cs6_pins[] = { 0x1a, };
398static int jz4760_i2c0_pins[] = { 0x7e, 0x7f, };
399static int jz4760_i2c1_pins[] = { 0x9e, 0x9f, };
400static int jz4760_cim_pins[] = {
401 0x26, 0x27, 0x28, 0x29,
402 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
403};
404static int jz4760_lcd_24bit_pins[] = {
405 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
406 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
407 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
408 0x58, 0x59, 0x5a, 0x5b,
409};
410static int jz4760_pwm_pwm0_pins[] = { 0x80, };
411static int jz4760_pwm_pwm1_pins[] = { 0x81, };
412static int jz4760_pwm_pwm2_pins[] = { 0x82, };
413static int jz4760_pwm_pwm3_pins[] = { 0x83, };
414static int jz4760_pwm_pwm4_pins[] = { 0x84, };
415static int jz4760_pwm_pwm5_pins[] = { 0x85, };
416static int jz4760_pwm_pwm6_pins[] = { 0x6a, };
417static int jz4760_pwm_pwm7_pins[] = { 0x6b, };
418
419static int jz4760_uart0_data_funcs[] = { 0, 0, };
420static int jz4760_uart0_hwflow_funcs[] = { 0, 0, };
421static int jz4760_uart1_data_funcs[] = { 0, 0, };
422static int jz4760_uart1_hwflow_funcs[] = { 0, 0, };
423static int jz4760_uart2_data_funcs[] = { 0, 0, };
424static int jz4760_uart2_hwflow_funcs[] = { 0, 0, };
425static int jz4760_uart3_data_funcs[] = { 0, 1, };
426static int jz4760_uart3_hwflow_funcs[] = { 0, 0, };
427static int jz4760_mmc0_1bit_a_funcs[] = { 1, 1, 0, };
428static int jz4760_mmc0_4bit_a_funcs[] = { 1, 1, 1, };
429static int jz4760_mmc0_1bit_e_funcs[] = { 0, 0, 0, };
430static int jz4760_mmc0_4bit_e_funcs[] = { 0, 0, 0, };
431static int jz4760_mmc0_8bit_e_funcs[] = { 0, 0, 0, 0, };
432static int jz4760_mmc1_1bit_d_funcs[] = { 0, 0, 0, };
433static int jz4760_mmc1_4bit_d_funcs[] = { 0, 0, 0, };
434static int jz4760_mmc1_1bit_e_funcs[] = { 1, 1, 1, };
435static int jz4760_mmc1_4bit_e_funcs[] = { 1, 1, 1, };
436static int jz4760_mmc1_8bit_e_funcs[] = { 1, 1, 1, 1, };
437static int jz4760_mmc2_1bit_b_funcs[] = { 0, 0, 0, };
438static int jz4760_mmc2_4bit_b_funcs[] = { 0, 0, 0, };
439static int jz4760_mmc2_1bit_e_funcs[] = { 2, 2, 2, };
440static int jz4760_mmc2_4bit_e_funcs[] = { 2, 2, 2, };
441static int jz4760_mmc2_8bit_e_funcs[] = { 2, 2, 2, 2, };
442static int jz4760_nemc_8bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
443static int jz4760_nemc_16bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
444static int jz4760_nemc_cle_ale_funcs[] = { 0, 0, };
445static int jz4760_nemc_addr_funcs[] = { 0, 0, 0, 0, };
446static int jz4760_nemc_rd_we_funcs[] = { 0, 0, };
447static int jz4760_nemc_frd_fwe_funcs[] = { 0, 0, };
448static int jz4760_nemc_wait_funcs[] = { 0, };
449static int jz4760_nemc_cs1_funcs[] = { 0, };
450static int jz4760_nemc_cs2_funcs[] = { 0, };
451static int jz4760_nemc_cs3_funcs[] = { 0, };
452static int jz4760_nemc_cs4_funcs[] = { 0, };
453static int jz4760_nemc_cs5_funcs[] = { 0, };
454static int jz4760_nemc_cs6_funcs[] = { 0, };
455static int jz4760_i2c0_funcs[] = { 0, 0, };
456static int jz4760_i2c1_funcs[] = { 0, 0, };
457static int jz4760_cim_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
458static int jz4760_lcd_24bit_funcs[] = {
459 0, 0, 0, 0, 0, 0, 0, 0,
460 0, 0, 0, 0, 0, 0, 0, 0,
461 0, 0, 0, 0, 0, 0, 0, 0,
462 0, 0, 0, 0,
463};
464static int jz4760_pwm_pwm0_funcs[] = { 0, };
465static int jz4760_pwm_pwm1_funcs[] = { 0, };
466static int jz4760_pwm_pwm2_funcs[] = { 0, };
467static int jz4760_pwm_pwm3_funcs[] = { 0, };
468static int jz4760_pwm_pwm4_funcs[] = { 0, };
469static int jz4760_pwm_pwm5_funcs[] = { 0, };
470static int jz4760_pwm_pwm6_funcs[] = { 0, };
471static int jz4760_pwm_pwm7_funcs[] = { 0, };
472
473static const struct group_desc jz4760_groups[] = {
474 INGENIC_PIN_GROUP("uart0-data", jz4760_uart0_data),
475 INGENIC_PIN_GROUP("uart0-hwflow", jz4760_uart0_hwflow),
476 INGENIC_PIN_GROUP("uart1-data", jz4760_uart1_data),
477 INGENIC_PIN_GROUP("uart1-hwflow", jz4760_uart1_hwflow),
478 INGENIC_PIN_GROUP("uart2-data", jz4760_uart2_data),
479 INGENIC_PIN_GROUP("uart2-hwflow", jz4760_uart2_hwflow),
480 INGENIC_PIN_GROUP("uart3-data", jz4760_uart3_data),
481 INGENIC_PIN_GROUP("uart3-hwflow", jz4760_uart3_hwflow),
482 INGENIC_PIN_GROUP("mmc0-1bit-a", jz4760_mmc0_1bit_a),
483 INGENIC_PIN_GROUP("mmc0-4bit-a", jz4760_mmc0_4bit_a),
484 INGENIC_PIN_GROUP("mmc0-1bit-e", jz4760_mmc0_1bit_e),
485 INGENIC_PIN_GROUP("mmc0-4bit-e", jz4760_mmc0_4bit_e),
486 INGENIC_PIN_GROUP("mmc0-8bit-e", jz4760_mmc0_8bit_e),
487 INGENIC_PIN_GROUP("mmc1-1bit-d", jz4760_mmc1_1bit_d),
488 INGENIC_PIN_GROUP("mmc1-4bit-d", jz4760_mmc1_4bit_d),
489 INGENIC_PIN_GROUP("mmc1-1bit-e", jz4760_mmc1_1bit_e),
490 INGENIC_PIN_GROUP("mmc1-4bit-e", jz4760_mmc1_4bit_e),
491 INGENIC_PIN_GROUP("mmc1-8bit-e", jz4760_mmc1_8bit_e),
492 INGENIC_PIN_GROUP("mmc2-1bit-b", jz4760_mmc2_1bit_b),
493 INGENIC_PIN_GROUP("mmc2-4bit-b", jz4760_mmc2_4bit_b),
494 INGENIC_PIN_GROUP("mmc2-1bit-e", jz4760_mmc2_1bit_e),
495 INGENIC_PIN_GROUP("mmc2-4bit-e", jz4760_mmc2_4bit_e),
496 INGENIC_PIN_GROUP("mmc2-8bit-e", jz4760_mmc2_8bit_e),
497 INGENIC_PIN_GROUP("nemc-8bit-data", jz4760_nemc_8bit_data),
498 INGENIC_PIN_GROUP("nemc-16bit-data", jz4760_nemc_16bit_data),
499 INGENIC_PIN_GROUP("nemc-cle-ale", jz4760_nemc_cle_ale),
500 INGENIC_PIN_GROUP("nemc-addr", jz4760_nemc_addr),
501 INGENIC_PIN_GROUP("nemc-rd-we", jz4760_nemc_rd_we),
502 INGENIC_PIN_GROUP("nemc-frd-fwe", jz4760_nemc_frd_fwe),
503 INGENIC_PIN_GROUP("nemc-wait", jz4760_nemc_wait),
504 INGENIC_PIN_GROUP("nemc-cs1", jz4760_nemc_cs1),
505 INGENIC_PIN_GROUP("nemc-cs2", jz4760_nemc_cs2),
506 INGENIC_PIN_GROUP("nemc-cs3", jz4760_nemc_cs3),
507 INGENIC_PIN_GROUP("nemc-cs4", jz4760_nemc_cs4),
508 INGENIC_PIN_GROUP("nemc-cs5", jz4760_nemc_cs5),
509 INGENIC_PIN_GROUP("nemc-cs6", jz4760_nemc_cs6),
510 INGENIC_PIN_GROUP("i2c0-data", jz4760_i2c0),
511 INGENIC_PIN_GROUP("i2c1-data", jz4760_i2c1),
512 INGENIC_PIN_GROUP("cim-data", jz4760_cim),
513 INGENIC_PIN_GROUP("lcd-24bit", jz4760_lcd_24bit),
514 { "lcd-no-pins", },
515 INGENIC_PIN_GROUP("pwm0", jz4760_pwm_pwm0),
516 INGENIC_PIN_GROUP("pwm1", jz4760_pwm_pwm1),
517 INGENIC_PIN_GROUP("pwm2", jz4760_pwm_pwm2),
518 INGENIC_PIN_GROUP("pwm3", jz4760_pwm_pwm3),
519 INGENIC_PIN_GROUP("pwm4", jz4760_pwm_pwm4),
520 INGENIC_PIN_GROUP("pwm5", jz4760_pwm_pwm5),
521 INGENIC_PIN_GROUP("pwm6", jz4760_pwm_pwm6),
522 INGENIC_PIN_GROUP("pwm7", jz4760_pwm_pwm7),
523};
524
525static const char *jz4760_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
526static const char *jz4760_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
527static const char *jz4760_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
528static const char *jz4760_uart3_groups[] = { "uart3-data", "uart3-hwflow", };
529static const char *jz4760_mmc0_groups[] = {
530 "mmc0-1bit-a", "mmc0-4bit-a",
531 "mmc0-1bit-e", "mmc0-4bit-e", "mmc0-8bit-e",
532};
533static const char *jz4760_mmc1_groups[] = {
534 "mmc1-1bit-d", "mmc1-4bit-d",
535 "mmc1-1bit-e", "mmc1-4bit-e", "mmc1-8bit-e",
536};
537static const char *jz4760_mmc2_groups[] = {
538 "mmc2-1bit-b", "mmc2-4bit-b",
539 "mmc2-1bit-e", "mmc2-4bit-e", "mmc2-8bit-e",
540};
541static const char *jz4760_nemc_groups[] = {
542 "nemc-8bit-data", "nemc-16bit-data", "nemc-cle-ale",
543 "nemc-addr", "nemc-rd-we", "nemc-frd-fwe", "nemc-wait",
544};
545static const char *jz4760_cs1_groups[] = { "nemc-cs1", };
546static const char *jz4760_cs2_groups[] = { "nemc-cs2", };
547static const char *jz4760_cs3_groups[] = { "nemc-cs3", };
548static const char *jz4760_cs4_groups[] = { "nemc-cs4", };
549static const char *jz4760_cs5_groups[] = { "nemc-cs5", };
550static const char *jz4760_cs6_groups[] = { "nemc-cs6", };
551static const char *jz4760_i2c0_groups[] = { "i2c0-data", };
552static const char *jz4760_i2c1_groups[] = { "i2c1-data", };
553static const char *jz4760_cim_groups[] = { "cim-data", };
554static const char *jz4760_lcd_groups[] = { "lcd-24bit", "lcd-no-pins", };
555static const char *jz4760_pwm0_groups[] = { "pwm0", };
556static const char *jz4760_pwm1_groups[] = { "pwm1", };
557static const char *jz4760_pwm2_groups[] = { "pwm2", };
558static const char *jz4760_pwm3_groups[] = { "pwm3", };
559static const char *jz4760_pwm4_groups[] = { "pwm4", };
560static const char *jz4760_pwm5_groups[] = { "pwm5", };
561static const char *jz4760_pwm6_groups[] = { "pwm6", };
562static const char *jz4760_pwm7_groups[] = { "pwm7", };
563
564static const struct function_desc jz4760_functions[] = {
565 { "uart0", jz4760_uart0_groups, ARRAY_SIZE(jz4760_uart0_groups), },
566 { "uart1", jz4760_uart1_groups, ARRAY_SIZE(jz4760_uart1_groups), },
567 { "uart2", jz4760_uart2_groups, ARRAY_SIZE(jz4760_uart2_groups), },
568 { "uart3", jz4760_uart3_groups, ARRAY_SIZE(jz4760_uart3_groups), },
569 { "mmc0", jz4760_mmc0_groups, ARRAY_SIZE(jz4760_mmc0_groups), },
570 { "mmc1", jz4760_mmc1_groups, ARRAY_SIZE(jz4760_mmc1_groups), },
571 { "mmc2", jz4760_mmc2_groups, ARRAY_SIZE(jz4760_mmc2_groups), },
572 { "nemc", jz4760_nemc_groups, ARRAY_SIZE(jz4760_nemc_groups), },
573 { "nemc-cs1", jz4760_cs1_groups, ARRAY_SIZE(jz4760_cs1_groups), },
574 { "nemc-cs2", jz4760_cs2_groups, ARRAY_SIZE(jz4760_cs2_groups), },
575 { "nemc-cs3", jz4760_cs3_groups, ARRAY_SIZE(jz4760_cs3_groups), },
576 { "nemc-cs4", jz4760_cs4_groups, ARRAY_SIZE(jz4760_cs4_groups), },
577 { "nemc-cs5", jz4760_cs5_groups, ARRAY_SIZE(jz4760_cs5_groups), },
578 { "nemc-cs6", jz4760_cs6_groups, ARRAY_SIZE(jz4760_cs6_groups), },
579 { "i2c0", jz4760_i2c0_groups, ARRAY_SIZE(jz4760_i2c0_groups), },
580 { "i2c1", jz4760_i2c1_groups, ARRAY_SIZE(jz4760_i2c1_groups), },
581 { "cim", jz4760_cim_groups, ARRAY_SIZE(jz4760_cim_groups), },
582 { "lcd", jz4760_lcd_groups, ARRAY_SIZE(jz4760_lcd_groups), },
583 { "pwm0", jz4760_pwm0_groups, ARRAY_SIZE(jz4760_pwm0_groups), },
584 { "pwm1", jz4760_pwm1_groups, ARRAY_SIZE(jz4760_pwm1_groups), },
585 { "pwm2", jz4760_pwm2_groups, ARRAY_SIZE(jz4760_pwm2_groups), },
586 { "pwm3", jz4760_pwm3_groups, ARRAY_SIZE(jz4760_pwm3_groups), },
587 { "pwm4", jz4760_pwm4_groups, ARRAY_SIZE(jz4760_pwm4_groups), },
588 { "pwm5", jz4760_pwm5_groups, ARRAY_SIZE(jz4760_pwm5_groups), },
589 { "pwm6", jz4760_pwm6_groups, ARRAY_SIZE(jz4760_pwm6_groups), },
590 { "pwm7", jz4760_pwm7_groups, ARRAY_SIZE(jz4760_pwm7_groups), },
591};
592
593static const struct ingenic_chip_info jz4760_chip_info = {
594 .num_chips = 6,
595 .groups = jz4760_groups,
596 .num_groups = ARRAY_SIZE(jz4760_groups),
597 .functions = jz4760_functions,
598 .num_functions = ARRAY_SIZE(jz4760_functions),
599 .pull_ups = jz4760_pull_ups,
600 .pull_downs = jz4760_pull_downs,
601};
602
603static const struct ingenic_chip_info jz4760b_chip_info = {
604 .num_chips = 6,
605 .groups = jz4760_groups,
606 .num_groups = ARRAY_SIZE(jz4760_groups),
607 .functions = jz4760_functions,
608 .num_functions = ARRAY_SIZE(jz4760_functions),
609 .pull_ups = jz4760_pull_ups,
610 .pull_downs = jz4760_pull_downs,
611};
612
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200613static const u32 jz4770_pull_ups[6] = {
614 0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
615};
616
617static const u32 jz4770_pull_downs[6] = {
618 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0,
619};
620
621static int jz4770_uart0_data_pins[] = { 0xa0, 0xa3, };
622static int jz4770_uart0_hwflow_pins[] = { 0xa1, 0xa2, };
623static int jz4770_uart1_data_pins[] = { 0x7a, 0x7c, };
624static int jz4770_uart1_hwflow_pins[] = { 0x7b, 0x7d, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800625static int jz4770_uart2_data_pins[] = { 0x5c, 0x5e, };
626static int jz4770_uart2_hwflow_pins[] = { 0x5d, 0x5f, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200627static int jz4770_uart3_data_pins[] = { 0x6c, 0x85, };
628static int jz4770_uart3_hwflow_pins[] = { 0x88, 0x89, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200629static int jz4770_mmc0_1bit_a_pins[] = { 0x12, 0x13, 0x14, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800630static int jz4770_mmc0_4bit_a_pins[] = { 0x15, 0x16, 0x17, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200631static int jz4770_mmc0_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800632static int jz4770_mmc0_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
633static int jz4770_mmc0_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200634static int jz4770_mmc1_1bit_d_pins[] = { 0x78, 0x79, 0x74, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800635static int jz4770_mmc1_4bit_d_pins[] = { 0x75, 0x76, 0x77, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200636static int jz4770_mmc1_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800637static int jz4770_mmc1_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
638static int jz4770_mmc1_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800639static int jz4770_mmc2_1bit_b_pins[] = { 0x3c, 0x3d, 0x34, };
640static int jz4770_mmc2_4bit_b_pins[] = { 0x35, 0x3e, 0x3f, };
641static int jz4770_mmc2_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, };
642static int jz4770_mmc2_4bit_e_pins[] = { 0x95, 0x96, 0x97, };
643static int jz4770_mmc2_8bit_e_pins[] = { 0x98, 0x99, 0x9a, 0x9b, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800644static int jz4770_nemc_8bit_data_pins[] = {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200645 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
646};
Zhou Yanjieff656e42019-01-28 23:19:57 +0800647static int jz4770_nemc_16bit_data_pins[] = {
648 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
649};
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200650static int jz4770_nemc_cle_ale_pins[] = { 0x20, 0x21, };
651static int jz4770_nemc_addr_pins[] = { 0x22, 0x23, 0x24, 0x25, };
652static int jz4770_nemc_rd_we_pins[] = { 0x10, 0x11, };
653static int jz4770_nemc_frd_fwe_pins[] = { 0x12, 0x13, };
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800654static int jz4770_nemc_wait_pins[] = { 0x1b, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200655static int jz4770_nemc_cs1_pins[] = { 0x15, };
656static int jz4770_nemc_cs2_pins[] = { 0x16, };
657static int jz4770_nemc_cs3_pins[] = { 0x17, };
658static int jz4770_nemc_cs4_pins[] = { 0x18, };
659static int jz4770_nemc_cs5_pins[] = { 0x19, };
660static int jz4770_nemc_cs6_pins[] = { 0x1a, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800661static int jz4770_i2c0_pins[] = { 0x7e, 0x7f, };
662static int jz4770_i2c1_pins[] = { 0x9e, 0x9f, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200663static int jz4770_i2c2_pins[] = { 0xb0, 0xb1, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800664static int jz4770_cim_8bit_pins[] = {
665 0x26, 0x27, 0x28, 0x29,
666 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200667};
Zhou Yanjieff656e42019-01-28 23:19:57 +0800668static int jz4770_cim_12bit_pins[] = {
669 0x32, 0x33, 0xb0, 0xb1,
670};
671static int jz4770_lcd_24bit_pins[] = {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200672 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
673 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
674 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
Zhou Yanjieff656e42019-01-28 23:19:57 +0800675 0x58, 0x59, 0x5a, 0x5b,
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200676};
677static int jz4770_pwm_pwm0_pins[] = { 0x80, };
678static int jz4770_pwm_pwm1_pins[] = { 0x81, };
679static int jz4770_pwm_pwm2_pins[] = { 0x82, };
680static int jz4770_pwm_pwm3_pins[] = { 0x83, };
681static int jz4770_pwm_pwm4_pins[] = { 0x84, };
682static int jz4770_pwm_pwm5_pins[] = { 0x85, };
683static int jz4770_pwm_pwm6_pins[] = { 0x6a, };
684static int jz4770_pwm_pwm7_pins[] = { 0x6b, };
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800685static int jz4770_mac_rmii_pins[] = {
686 0xa9, 0xab, 0xaa, 0xac, 0xa5, 0xa4, 0xad, 0xae, 0xa6, 0xa8,
687};
688static int jz4770_mac_mii_pins[] = { 0xa7, 0xaf, };
Paul Cercueilae75b532019-11-19 16:52:11 +0100689static int jz4770_otg_pins[] = { 0x8a, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200690
691static int jz4770_uart0_data_funcs[] = { 0, 0, };
692static int jz4770_uart0_hwflow_funcs[] = { 0, 0, };
693static int jz4770_uart1_data_funcs[] = { 0, 0, };
694static int jz4770_uart1_hwflow_funcs[] = { 0, 0, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800695static int jz4770_uart2_data_funcs[] = { 0, 0, };
696static int jz4770_uart2_hwflow_funcs[] = { 0, 0, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200697static int jz4770_uart3_data_funcs[] = { 0, 1, };
698static int jz4770_uart3_hwflow_funcs[] = { 0, 0, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200699static int jz4770_mmc0_1bit_a_funcs[] = { 1, 1, 0, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800700static int jz4770_mmc0_4bit_a_funcs[] = { 1, 1, 1, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200701static int jz4770_mmc0_1bit_e_funcs[] = { 0, 0, 0, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800702static int jz4770_mmc0_4bit_e_funcs[] = { 0, 0, 0, };
703static int jz4770_mmc0_8bit_e_funcs[] = { 0, 0, 0, 0, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200704static int jz4770_mmc1_1bit_d_funcs[] = { 0, 0, 0, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800705static int jz4770_mmc1_4bit_d_funcs[] = { 0, 0, 0, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200706static int jz4770_mmc1_1bit_e_funcs[] = { 1, 1, 1, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800707static int jz4770_mmc1_4bit_e_funcs[] = { 1, 1, 1, };
708static int jz4770_mmc1_8bit_e_funcs[] = { 1, 1, 1, 1, };
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800709static int jz4770_mmc2_1bit_b_funcs[] = { 0, 0, 0, };
710static int jz4770_mmc2_4bit_b_funcs[] = { 0, 0, 0, };
711static int jz4770_mmc2_1bit_e_funcs[] = { 2, 2, 2, };
712static int jz4770_mmc2_4bit_e_funcs[] = { 2, 2, 2, };
713static int jz4770_mmc2_8bit_e_funcs[] = { 2, 2, 2, 2, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800714static int jz4770_nemc_8bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
715static int jz4770_nemc_16bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200716static int jz4770_nemc_cle_ale_funcs[] = { 0, 0, };
717static int jz4770_nemc_addr_funcs[] = { 0, 0, 0, 0, };
718static int jz4770_nemc_rd_we_funcs[] = { 0, 0, };
719static int jz4770_nemc_frd_fwe_funcs[] = { 0, 0, };
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800720static int jz4770_nemc_wait_funcs[] = { 0, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200721static int jz4770_nemc_cs1_funcs[] = { 0, };
722static int jz4770_nemc_cs2_funcs[] = { 0, };
723static int jz4770_nemc_cs3_funcs[] = { 0, };
724static int jz4770_nemc_cs4_funcs[] = { 0, };
725static int jz4770_nemc_cs5_funcs[] = { 0, };
726static int jz4770_nemc_cs6_funcs[] = { 0, };
727static int jz4770_i2c0_funcs[] = { 0, 0, };
728static int jz4770_i2c1_funcs[] = { 0, 0, };
729static int jz4770_i2c2_funcs[] = { 2, 2, };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800730static int jz4770_cim_8bit_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
731static int jz4770_cim_12bit_funcs[] = { 0, 0, 0, 0, };
732static int jz4770_lcd_24bit_funcs[] = {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200733 0, 0, 0, 0, 0, 0, 0, 0,
734 0, 0, 0, 0, 0, 0, 0, 0,
Zhou Yanjieff656e42019-01-28 23:19:57 +0800735 0, 0, 0, 0, 0, 0, 0, 0,
736 0, 0, 0, 0,
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200737};
738static int jz4770_pwm_pwm0_funcs[] = { 0, };
739static int jz4770_pwm_pwm1_funcs[] = { 0, };
740static int jz4770_pwm_pwm2_funcs[] = { 0, };
741static int jz4770_pwm_pwm3_funcs[] = { 0, };
742static int jz4770_pwm_pwm4_funcs[] = { 0, };
743static int jz4770_pwm_pwm5_funcs[] = { 0, };
744static int jz4770_pwm_pwm6_funcs[] = { 0, };
745static int jz4770_pwm_pwm7_funcs[] = { 0, };
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800746static int jz4770_mac_rmii_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
747static int jz4770_mac_mii_funcs[] = { 0, 0, };
Paul Cercueilae75b532019-11-19 16:52:11 +0100748static int jz4770_otg_funcs[] = { 0, };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200749
750static const struct group_desc jz4770_groups[] = {
751 INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
752 INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow),
753 INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data),
754 INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow),
755 INGENIC_PIN_GROUP("uart2-data", jz4770_uart2_data),
756 INGENIC_PIN_GROUP("uart2-hwflow", jz4770_uart2_hwflow),
757 INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data),
758 INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200759 INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a),
Zhou Yanjieff656e42019-01-28 23:19:57 +0800760 INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200761 INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e),
Zhou Yanjieff656e42019-01-28 23:19:57 +0800762 INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e),
763 INGENIC_PIN_GROUP("mmc0-8bit-e", jz4770_mmc0_8bit_e),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200764 INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d),
Zhou Yanjieff656e42019-01-28 23:19:57 +0800765 INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200766 INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e),
Zhou Yanjieff656e42019-01-28 23:19:57 +0800767 INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e),
768 INGENIC_PIN_GROUP("mmc1-8bit-e", jz4770_mmc1_8bit_e),
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800769 INGENIC_PIN_GROUP("mmc2-1bit-b", jz4770_mmc2_1bit_b),
770 INGENIC_PIN_GROUP("mmc2-4bit-b", jz4770_mmc2_4bit_b),
771 INGENIC_PIN_GROUP("mmc2-1bit-e", jz4770_mmc2_1bit_e),
772 INGENIC_PIN_GROUP("mmc2-4bit-e", jz4770_mmc2_4bit_e),
773 INGENIC_PIN_GROUP("mmc2-8bit-e", jz4770_mmc2_8bit_e),
Zhou Yanjieff656e42019-01-28 23:19:57 +0800774 INGENIC_PIN_GROUP("nemc-8bit-data", jz4770_nemc_8bit_data),
775 INGENIC_PIN_GROUP("nemc-16bit-data", jz4770_nemc_16bit_data),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200776 INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale),
777 INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr),
778 INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we),
779 INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe),
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800780 INGENIC_PIN_GROUP("nemc-wait", jz4770_nemc_wait),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200781 INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1),
782 INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2),
783 INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3),
784 INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4),
785 INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5),
786 INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6),
787 INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0),
788 INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1),
789 INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2),
Zhou Yanjieff656e42019-01-28 23:19:57 +0800790 INGENIC_PIN_GROUP("cim-data-8bit", jz4770_cim_8bit),
791 INGENIC_PIN_GROUP("cim-data-12bit", jz4770_cim_12bit),
792 INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200793 { "lcd-no-pins", },
794 INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0),
795 INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1),
796 INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2),
797 INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3),
798 INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4),
799 INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5),
800 INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6),
801 INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800802 INGENIC_PIN_GROUP("mac-rmii", jz4770_mac_rmii),
803 INGENIC_PIN_GROUP("mac-mii", jz4770_mac_mii),
Paul Cercueilae75b532019-11-19 16:52:11 +0100804 INGENIC_PIN_GROUP("otg-vbus", jz4770_otg),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200805};
806
807static const char *jz4770_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
808static const char *jz4770_uart1_groups[] = { "uart1-data", "uart1-hwflow", };
809static const char *jz4770_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
810static const char *jz4770_uart3_groups[] = { "uart3-data", "uart3-hwflow", };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200811static const char *jz4770_mmc0_groups[] = {
Zhou Yanjieff656e42019-01-28 23:19:57 +0800812 "mmc0-1bit-a", "mmc0-4bit-a",
813 "mmc0-1bit-e", "mmc0-4bit-e", "mmc0-8bit-e",
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200814};
815static const char *jz4770_mmc1_groups[] = {
Zhou Yanjieff656e42019-01-28 23:19:57 +0800816 "mmc1-1bit-d", "mmc1-4bit-d",
817 "mmc1-1bit-e", "mmc1-4bit-e", "mmc1-8bit-e",
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200818};
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800819static const char *jz4770_mmc2_groups[] = {
820 "mmc2-1bit-b", "mmc2-4bit-b",
821 "mmc2-1bit-e", "mmc2-4bit-e", "mmc2-8bit-e",
822};
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200823static const char *jz4770_nemc_groups[] = {
Zhou Yanjieff656e42019-01-28 23:19:57 +0800824 "nemc-8bit-data", "nemc-16bit-data", "nemc-cle-ale",
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800825 "nemc-addr", "nemc-rd-we", "nemc-frd-fwe", "nemc-wait",
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200826};
827static const char *jz4770_cs1_groups[] = { "nemc-cs1", };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800828static const char *jz4770_cs2_groups[] = { "nemc-cs2", };
829static const char *jz4770_cs3_groups[] = { "nemc-cs3", };
830static const char *jz4770_cs4_groups[] = { "nemc-cs4", };
831static const char *jz4770_cs5_groups[] = { "nemc-cs5", };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200832static const char *jz4770_cs6_groups[] = { "nemc-cs6", };
833static const char *jz4770_i2c0_groups[] = { "i2c0-data", };
834static const char *jz4770_i2c1_groups[] = { "i2c1-data", };
835static const char *jz4770_i2c2_groups[] = { "i2c2-data", };
Zhou Yanjieff656e42019-01-28 23:19:57 +0800836static const char *jz4770_cim_groups[] = { "cim-data-8bit", "cim-data-12bit", };
837static const char *jz4770_lcd_groups[] = { "lcd-24bit", "lcd-no-pins", };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200838static const char *jz4770_pwm0_groups[] = { "pwm0", };
839static const char *jz4770_pwm1_groups[] = { "pwm1", };
840static const char *jz4770_pwm2_groups[] = { "pwm2", };
841static const char *jz4770_pwm3_groups[] = { "pwm3", };
842static const char *jz4770_pwm4_groups[] = { "pwm4", };
843static const char *jz4770_pwm5_groups[] = { "pwm5", };
844static const char *jz4770_pwm6_groups[] = { "pwm6", };
845static const char *jz4770_pwm7_groups[] = { "pwm7", };
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800846static const char *jz4770_mac_groups[] = { "mac-rmii", "mac-mii", };
Paul Cercueilae75b532019-11-19 16:52:11 +0100847static const char *jz4770_otg_groups[] = { "otg-vbus", };
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200848
849static const struct function_desc jz4770_functions[] = {
850 { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
851 { "uart1", jz4770_uart1_groups, ARRAY_SIZE(jz4770_uart1_groups), },
852 { "uart2", jz4770_uart2_groups, ARRAY_SIZE(jz4770_uart2_groups), },
853 { "uart3", jz4770_uart3_groups, ARRAY_SIZE(jz4770_uart3_groups), },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200854 { "mmc0", jz4770_mmc0_groups, ARRAY_SIZE(jz4770_mmc0_groups), },
855 { "mmc1", jz4770_mmc1_groups, ARRAY_SIZE(jz4770_mmc1_groups), },
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800856 { "mmc2", jz4770_mmc2_groups, ARRAY_SIZE(jz4770_mmc2_groups), },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200857 { "nemc", jz4770_nemc_groups, ARRAY_SIZE(jz4770_nemc_groups), },
858 { "nemc-cs1", jz4770_cs1_groups, ARRAY_SIZE(jz4770_cs1_groups), },
Zhou Yanjieff656e42019-01-28 23:19:57 +0800859 { "nemc-cs2", jz4770_cs2_groups, ARRAY_SIZE(jz4770_cs2_groups), },
860 { "nemc-cs3", jz4770_cs3_groups, ARRAY_SIZE(jz4770_cs3_groups), },
861 { "nemc-cs4", jz4770_cs4_groups, ARRAY_SIZE(jz4770_cs4_groups), },
862 { "nemc-cs5", jz4770_cs5_groups, ARRAY_SIZE(jz4770_cs5_groups), },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200863 { "nemc-cs6", jz4770_cs6_groups, ARRAY_SIZE(jz4770_cs6_groups), },
864 { "i2c0", jz4770_i2c0_groups, ARRAY_SIZE(jz4770_i2c0_groups), },
865 { "i2c1", jz4770_i2c1_groups, ARRAY_SIZE(jz4770_i2c1_groups), },
866 { "i2c2", jz4770_i2c2_groups, ARRAY_SIZE(jz4770_i2c2_groups), },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200867 { "cim", jz4770_cim_groups, ARRAY_SIZE(jz4770_cim_groups), },
868 { "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), },
869 { "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), },
870 { "pwm1", jz4770_pwm1_groups, ARRAY_SIZE(jz4770_pwm1_groups), },
871 { "pwm2", jz4770_pwm2_groups, ARRAY_SIZE(jz4770_pwm2_groups), },
872 { "pwm3", jz4770_pwm3_groups, ARRAY_SIZE(jz4770_pwm3_groups), },
873 { "pwm4", jz4770_pwm4_groups, ARRAY_SIZE(jz4770_pwm4_groups), },
874 { "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
875 { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
876 { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800877 { "mac", jz4770_mac_groups, ARRAY_SIZE(jz4770_mac_groups), },
Paul Cercueilae75b532019-11-19 16:52:11 +0100878 { "otg", jz4770_otg_groups, ARRAY_SIZE(jz4770_otg_groups), },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +0200879};
880
881static const struct ingenic_chip_info jz4770_chip_info = {
882 .num_chips = 6,
883 .groups = jz4770_groups,
884 .num_groups = ARRAY_SIZE(jz4770_groups),
885 .functions = jz4770_functions,
886 .num_functions = ARRAY_SIZE(jz4770_functions),
887 .pull_ups = jz4770_pull_ups,
888 .pull_downs = jz4770_pull_downs,
889};
890
Zhou Yanjieff656e42019-01-28 23:19:57 +0800891static int jz4780_uart2_data_pins[] = { 0x66, 0x67, };
892static int jz4780_uart2_hwflow_pins[] = { 0x65, 0x64, };
893static int jz4780_uart4_data_pins[] = { 0x54, 0x4a, };
894static int jz4780_mmc0_8bit_a_pins[] = { 0x04, 0x05, 0x06, 0x07, 0x18, };
895static int jz4780_i2c3_pins[] = { 0x6a, 0x6b, };
896static int jz4780_i2c4_e_pins[] = { 0x8c, 0x8d, };
897static int jz4780_i2c4_f_pins[] = { 0xb9, 0xb8, };
898
899static int jz4780_uart2_data_funcs[] = { 1, 1, };
900static int jz4780_uart2_hwflow_funcs[] = { 1, 1, };
901static int jz4780_uart4_data_funcs[] = { 2, 2, };
902static int jz4780_mmc0_8bit_a_funcs[] = { 1, 1, 1, 1, 1, };
903static int jz4780_i2c3_funcs[] = { 1, 1, };
904static int jz4780_i2c4_e_funcs[] = { 1, 1, };
905static int jz4780_i2c4_f_funcs[] = { 1, 1, };
906
907static const struct group_desc jz4780_groups[] = {
908 INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data),
909 INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow),
910 INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data),
911 INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow),
912 INGENIC_PIN_GROUP("uart2-data", jz4780_uart2_data),
913 INGENIC_PIN_GROUP("uart2-hwflow", jz4780_uart2_hwflow),
914 INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data),
915 INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow),
916 INGENIC_PIN_GROUP("uart4-data", jz4780_uart4_data),
917 INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a),
918 INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a),
919 INGENIC_PIN_GROUP("mmc0-8bit-a", jz4780_mmc0_8bit_a),
920 INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e),
921 INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e),
922 INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d),
923 INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d),
924 INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e),
925 INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e),
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800926 INGENIC_PIN_GROUP("mmc2-1bit-b", jz4770_mmc2_1bit_b),
927 INGENIC_PIN_GROUP("mmc2-4bit-b", jz4770_mmc2_4bit_b),
928 INGENIC_PIN_GROUP("mmc2-1bit-e", jz4770_mmc2_1bit_e),
929 INGENIC_PIN_GROUP("mmc2-4bit-e", jz4770_mmc2_4bit_e),
Zhou Yanjieff656e42019-01-28 23:19:57 +0800930 INGENIC_PIN_GROUP("nemc-data", jz4770_nemc_8bit_data),
931 INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale),
932 INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr),
933 INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we),
934 INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe),
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800935 INGENIC_PIN_GROUP("nemc-wait", jz4770_nemc_wait),
Zhou Yanjieff656e42019-01-28 23:19:57 +0800936 INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1),
937 INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2),
938 INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3),
939 INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4),
940 INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5),
941 INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6),
942 INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0),
943 INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1),
944 INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2),
945 INGENIC_PIN_GROUP("i2c3-data", jz4780_i2c3),
946 INGENIC_PIN_GROUP("i2c4-data-e", jz4780_i2c4_e),
947 INGENIC_PIN_GROUP("i2c4-data-f", jz4780_i2c4_f),
948 INGENIC_PIN_GROUP("cim-data", jz4770_cim_8bit),
949 INGENIC_PIN_GROUP("lcd-24bit", jz4770_lcd_24bit),
950 { "lcd-no-pins", },
951 INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0),
952 INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1),
953 INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2),
954 INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3),
955 INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4),
956 INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5),
957 INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6),
958 INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7),
959};
960
961static const char *jz4780_uart2_groups[] = { "uart2-data", "uart2-hwflow", };
962static const char *jz4780_uart4_groups[] = { "uart4-data", };
963static const char *jz4780_mmc0_groups[] = {
964 "mmc0-1bit-a", "mmc0-4bit-a", "mmc0-8bit-a",
965 "mmc0-1bit-e", "mmc0-4bit-e",
966};
967static const char *jz4780_mmc1_groups[] = {
968 "mmc1-1bit-d", "mmc1-4bit-d", "mmc1-1bit-e", "mmc1-4bit-e",
969};
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800970static const char *jz4780_mmc2_groups[] = {
971 "mmc2-1bit-b", "mmc2-4bit-b", "mmc2-1bit-e", "mmc2-4bit-e",
972};
Zhou Yanjieff656e42019-01-28 23:19:57 +0800973static const char *jz4780_nemc_groups[] = {
974 "nemc-data", "nemc-cle-ale", "nemc-addr",
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800975 "nemc-rd-we", "nemc-frd-fwe", "nemc-wait",
Zhou Yanjieff656e42019-01-28 23:19:57 +0800976};
977static const char *jz4780_i2c3_groups[] = { "i2c3-data", };
978static const char *jz4780_i2c4_groups[] = { "i2c4-data-e", "i2c4-data-f", };
979static const char *jz4780_cim_groups[] = { "cim-data", };
980
981static const struct function_desc jz4780_functions[] = {
982 { "uart0", jz4770_uart0_groups, ARRAY_SIZE(jz4770_uart0_groups), },
983 { "uart1", jz4770_uart1_groups, ARRAY_SIZE(jz4770_uart1_groups), },
984 { "uart2", jz4780_uart2_groups, ARRAY_SIZE(jz4780_uart2_groups), },
985 { "uart3", jz4770_uart3_groups, ARRAY_SIZE(jz4770_uart3_groups), },
986 { "uart4", jz4780_uart4_groups, ARRAY_SIZE(jz4780_uart4_groups), },
987 { "mmc0", jz4780_mmc0_groups, ARRAY_SIZE(jz4780_mmc0_groups), },
988 { "mmc1", jz4780_mmc1_groups, ARRAY_SIZE(jz4780_mmc1_groups), },
Zhou Yanjie5de1a732019-01-28 23:19:58 +0800989 { "mmc2", jz4780_mmc2_groups, ARRAY_SIZE(jz4780_mmc2_groups), },
Zhou Yanjieff656e42019-01-28 23:19:57 +0800990 { "nemc", jz4780_nemc_groups, ARRAY_SIZE(jz4780_nemc_groups), },
991 { "nemc-cs1", jz4770_cs1_groups, ARRAY_SIZE(jz4770_cs1_groups), },
992 { "nemc-cs2", jz4770_cs2_groups, ARRAY_SIZE(jz4770_cs2_groups), },
993 { "nemc-cs3", jz4770_cs3_groups, ARRAY_SIZE(jz4770_cs3_groups), },
994 { "nemc-cs4", jz4770_cs4_groups, ARRAY_SIZE(jz4770_cs4_groups), },
995 { "nemc-cs5", jz4770_cs5_groups, ARRAY_SIZE(jz4770_cs5_groups), },
996 { "nemc-cs6", jz4770_cs6_groups, ARRAY_SIZE(jz4770_cs6_groups), },
997 { "i2c0", jz4770_i2c0_groups, ARRAY_SIZE(jz4770_i2c0_groups), },
998 { "i2c1", jz4770_i2c1_groups, ARRAY_SIZE(jz4770_i2c1_groups), },
999 { "i2c2", jz4770_i2c2_groups, ARRAY_SIZE(jz4770_i2c2_groups), },
1000 { "i2c3", jz4780_i2c3_groups, ARRAY_SIZE(jz4780_i2c3_groups), },
1001 { "i2c4", jz4780_i2c4_groups, ARRAY_SIZE(jz4780_i2c4_groups), },
1002 { "cim", jz4780_cim_groups, ARRAY_SIZE(jz4780_cim_groups), },
1003 { "lcd", jz4770_lcd_groups, ARRAY_SIZE(jz4770_lcd_groups), },
1004 { "pwm0", jz4770_pwm0_groups, ARRAY_SIZE(jz4770_pwm0_groups), },
1005 { "pwm1", jz4770_pwm1_groups, ARRAY_SIZE(jz4770_pwm1_groups), },
1006 { "pwm2", jz4770_pwm2_groups, ARRAY_SIZE(jz4770_pwm2_groups), },
1007 { "pwm3", jz4770_pwm3_groups, ARRAY_SIZE(jz4770_pwm3_groups), },
1008 { "pwm4", jz4770_pwm4_groups, ARRAY_SIZE(jz4770_pwm4_groups), },
1009 { "pwm5", jz4770_pwm5_groups, ARRAY_SIZE(jz4770_pwm5_groups), },
1010 { "pwm6", jz4770_pwm6_groups, ARRAY_SIZE(jz4770_pwm6_groups), },
1011 { "pwm7", jz4770_pwm7_groups, ARRAY_SIZE(jz4770_pwm7_groups), },
1012};
1013
1014static const struct ingenic_chip_info jz4780_chip_info = {
1015 .num_chips = 6,
1016 .groups = jz4780_groups,
1017 .num_groups = ARRAY_SIZE(jz4780_groups),
1018 .functions = jz4780_functions,
1019 .num_functions = ARRAY_SIZE(jz4780_functions),
1020 .pull_ups = jz4770_pull_ups,
1021 .pull_downs = jz4770_pull_downs,
1022};
1023
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001024static const u32 x1000_pull_ups[4] = {
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001025 0xffffffff, 0xfdffffff, 0x0dffffff, 0x0000003f,
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001026};
1027
1028static const u32 x1000_pull_downs[4] = {
1029 0x00000000, 0x02000000, 0x02000000, 0x00000000,
1030};
1031
1032static int x1000_uart0_data_pins[] = { 0x4a, 0x4b, };
1033static int x1000_uart0_hwflow_pins[] = { 0x4c, 0x4d, };
1034static int x1000_uart1_data_a_pins[] = { 0x04, 0x05, };
1035static int x1000_uart1_data_d_pins[] = { 0x62, 0x63, };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001036static int x1000_uart1_hwflow_pins[] = { 0x64, 0x65, };
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001037static int x1000_uart2_data_a_pins[] = { 0x02, 0x03, };
1038static int x1000_uart2_data_d_pins[] = { 0x65, 0x64, };
1039static int x1000_mmc0_1bit_pins[] = { 0x18, 0x19, 0x17, };
1040static int x1000_mmc0_4bit_pins[] = { 0x16, 0x15, 0x14, };
1041static int x1000_mmc0_8bit_pins[] = { 0x13, 0x12, 0x11, 0x10, };
1042static int x1000_mmc1_1bit_pins[] = { 0x40, 0x41, 0x42, };
1043static int x1000_mmc1_4bit_pins[] = { 0x43, 0x44, 0x45, };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001044static int x1000_emc_8bit_data_pins[] = {
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001045 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1046};
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001047static int x1000_emc_16bit_data_pins[] = {
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001048 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1049};
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001050static int x1000_emc_addr_pins[] = {
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001051 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
1052 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
1053};
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001054static int x1000_emc_rd_we_pins[] = { 0x30, 0x31, };
1055static int x1000_emc_wait_pins[] = { 0x34, };
1056static int x1000_emc_cs1_pins[] = { 0x32, };
1057static int x1000_emc_cs2_pins[] = { 0x33, };
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001058static int x1000_i2c0_pins[] = { 0x38, 0x37, };
1059static int x1000_i2c1_a_pins[] = { 0x01, 0x00, };
1060static int x1000_i2c1_c_pins[] = { 0x5b, 0x5a, };
1061static int x1000_i2c2_pins[] = { 0x61, 0x60, };
1062static int x1000_cim_pins[] = {
1063 0x08, 0x09, 0x0a, 0x0b,
1064 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c,
1065};
1066static int x1000_lcd_8bit_pins[] = {
1067 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1068 0x30, 0x31, 0x32, 0x33, 0x34,
1069};
1070static int x1000_lcd_16bit_pins[] = {
1071 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1072};
1073static int x1000_pwm_pwm0_pins[] = { 0x59, };
1074static int x1000_pwm_pwm1_pins[] = { 0x5a, };
1075static int x1000_pwm_pwm2_pins[] = { 0x5b, };
1076static int x1000_pwm_pwm3_pins[] = { 0x26, };
1077static int x1000_pwm_pwm4_pins[] = { 0x58, };
1078static int x1000_mac_pins[] = {
1079 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x26,
1080};
1081
1082static int x1000_uart0_data_funcs[] = { 0, 0, };
1083static int x1000_uart0_hwflow_funcs[] = { 0, 0, };
1084static int x1000_uart1_data_a_funcs[] = { 2, 2, };
1085static int x1000_uart1_data_d_funcs[] = { 1, 1, };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001086static int x1000_uart1_hwflow_funcs[] = { 1, 1, };
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001087static int x1000_uart2_data_a_funcs[] = { 2, 2, };
1088static int x1000_uart2_data_d_funcs[] = { 0, 0, };
1089static int x1000_mmc0_1bit_funcs[] = { 1, 1, 1, };
1090static int x1000_mmc0_4bit_funcs[] = { 1, 1, 1, };
1091static int x1000_mmc0_8bit_funcs[] = { 1, 1, 1, 1, 1, };
1092static int x1000_mmc1_1bit_funcs[] = { 0, 0, 0, };
1093static int x1000_mmc1_4bit_funcs[] = { 0, 0, 0, };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001094static int x1000_emc_8bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
1095static int x1000_emc_16bit_data_funcs[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
1096static int x1000_emc_addr_funcs[] = {
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001097 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1098};
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001099static int x1000_emc_rd_we_funcs[] = { 0, 0, };
1100static int x1000_emc_wait_funcs[] = { 0, };
1101static int x1000_emc_cs1_funcs[] = { 0, };
1102static int x1000_emc_cs2_funcs[] = { 0, };
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001103static int x1000_i2c0_funcs[] = { 0, 0, };
1104static int x1000_i2c1_a_funcs[] = { 2, 2, };
1105static int x1000_i2c1_c_funcs[] = { 0, 0, };
1106static int x1000_i2c2_funcs[] = { 1, 1, };
1107static int x1000_cim_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
1108static int x1000_lcd_8bit_funcs[] = {
1109 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1110};
1111static int x1000_lcd_16bit_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, };
1112static int x1000_pwm_pwm0_funcs[] = { 0, };
1113static int x1000_pwm_pwm1_funcs[] = { 1, };
1114static int x1000_pwm_pwm2_funcs[] = { 1, };
1115static int x1000_pwm_pwm3_funcs[] = { 2, };
1116static int x1000_pwm_pwm4_funcs[] = { 0, };
1117static int x1000_mac_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
1118
1119static const struct group_desc x1000_groups[] = {
1120 INGENIC_PIN_GROUP("uart0-data", x1000_uart0_data),
1121 INGENIC_PIN_GROUP("uart0-hwflow", x1000_uart0_hwflow),
1122 INGENIC_PIN_GROUP("uart1-data-a", x1000_uart1_data_a),
1123 INGENIC_PIN_GROUP("uart1-data-d", x1000_uart1_data_d),
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001124 INGENIC_PIN_GROUP("uart1-hwflow", x1000_uart1_hwflow),
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001125 INGENIC_PIN_GROUP("uart2-data-a", x1000_uart2_data_a),
1126 INGENIC_PIN_GROUP("uart2-data-d", x1000_uart2_data_d),
1127 INGENIC_PIN_GROUP("mmc0-1bit", x1000_mmc0_1bit),
1128 INGENIC_PIN_GROUP("mmc0-4bit", x1000_mmc0_4bit),
1129 INGENIC_PIN_GROUP("mmc0-8bit", x1000_mmc0_8bit),
1130 INGENIC_PIN_GROUP("mmc1-1bit", x1000_mmc1_1bit),
1131 INGENIC_PIN_GROUP("mmc1-4bit", x1000_mmc1_4bit),
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001132 INGENIC_PIN_GROUP("emc-8bit-data", x1000_emc_8bit_data),
1133 INGENIC_PIN_GROUP("emc-16bit-data", x1000_emc_16bit_data),
1134 INGENIC_PIN_GROUP("emc-addr", x1000_emc_addr),
1135 INGENIC_PIN_GROUP("emc-rd-we", x1000_emc_rd_we),
1136 INGENIC_PIN_GROUP("emc-wait", x1000_emc_wait),
1137 INGENIC_PIN_GROUP("emc-cs1", x1000_emc_cs1),
1138 INGENIC_PIN_GROUP("emc-cs2", x1000_emc_cs2),
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001139 INGENIC_PIN_GROUP("i2c0-data", x1000_i2c0),
1140 INGENIC_PIN_GROUP("i2c1-data-a", x1000_i2c1_a),
1141 INGENIC_PIN_GROUP("i2c1-data-c", x1000_i2c1_c),
1142 INGENIC_PIN_GROUP("i2c2-data", x1000_i2c2),
1143 INGENIC_PIN_GROUP("cim-data", x1000_cim),
1144 INGENIC_PIN_GROUP("lcd-8bit", x1000_lcd_8bit),
1145 INGENIC_PIN_GROUP("lcd-16bit", x1000_lcd_16bit),
1146 { "lcd-no-pins", },
1147 INGENIC_PIN_GROUP("pwm0", x1000_pwm_pwm0),
1148 INGENIC_PIN_GROUP("pwm1", x1000_pwm_pwm1),
1149 INGENIC_PIN_GROUP("pwm2", x1000_pwm_pwm2),
1150 INGENIC_PIN_GROUP("pwm3", x1000_pwm_pwm3),
1151 INGENIC_PIN_GROUP("pwm4", x1000_pwm_pwm4),
1152 INGENIC_PIN_GROUP("mac", x1000_mac),
1153};
1154
1155static const char *x1000_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
1156static const char *x1000_uart1_groups[] = {
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001157 "uart1-data-a", "uart1-data-d", "uart1-hwflow",
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001158};
1159static const char *x1000_uart2_groups[] = { "uart2-data-a", "uart2-data-d", };
1160static const char *x1000_mmc0_groups[] = {
1161 "mmc0-1bit", "mmc0-4bit", "mmc0-8bit",
1162};
1163static const char *x1000_mmc1_groups[] = {
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001164 "mmc1-1bit", "mmc1-4bit",
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001165};
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001166static const char *x1000_emc_groups[] = {
1167 "emc-8bit-data", "emc-16bit-data",
1168 "emc-addr", "emc-rd-we", "emc-wait",
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001169};
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001170static const char *x1000_cs1_groups[] = { "emc-cs1", };
1171static const char *x1000_cs2_groups[] = { "emc-cs2", };
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001172static const char *x1000_i2c0_groups[] = { "i2c0-data", };
1173static const char *x1000_i2c1_groups[] = { "i2c1-data-a", "i2c1-data-c", };
1174static const char *x1000_i2c2_groups[] = { "i2c2-data", };
1175static const char *x1000_cim_groups[] = { "cim-data", };
1176static const char *x1000_lcd_groups[] = {
1177 "lcd-8bit", "lcd-16bit", "lcd-no-pins",
1178};
1179static const char *x1000_pwm0_groups[] = { "pwm0", };
1180static const char *x1000_pwm1_groups[] = { "pwm1", };
1181static const char *x1000_pwm2_groups[] = { "pwm2", };
1182static const char *x1000_pwm3_groups[] = { "pwm3", };
1183static const char *x1000_pwm4_groups[] = { "pwm4", };
1184static const char *x1000_mac_groups[] = { "mac", };
1185
1186static const struct function_desc x1000_functions[] = {
1187 { "uart0", x1000_uart0_groups, ARRAY_SIZE(x1000_uart0_groups), },
1188 { "uart1", x1000_uart1_groups, ARRAY_SIZE(x1000_uart1_groups), },
1189 { "uart2", x1000_uart2_groups, ARRAY_SIZE(x1000_uart2_groups), },
1190 { "mmc0", x1000_mmc0_groups, ARRAY_SIZE(x1000_mmc0_groups), },
1191 { "mmc1", x1000_mmc1_groups, ARRAY_SIZE(x1000_mmc1_groups), },
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001192 { "emc", x1000_emc_groups, ARRAY_SIZE(x1000_emc_groups), },
1193 { "emc-cs1", x1000_cs1_groups, ARRAY_SIZE(x1000_cs1_groups), },
1194 { "emc-cs2", x1000_cs2_groups, ARRAY_SIZE(x1000_cs2_groups), },
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001195 { "i2c0", x1000_i2c0_groups, ARRAY_SIZE(x1000_i2c0_groups), },
1196 { "i2c1", x1000_i2c1_groups, ARRAY_SIZE(x1000_i2c1_groups), },
1197 { "i2c2", x1000_i2c2_groups, ARRAY_SIZE(x1000_i2c2_groups), },
1198 { "cim", x1000_cim_groups, ARRAY_SIZE(x1000_cim_groups), },
1199 { "lcd", x1000_lcd_groups, ARRAY_SIZE(x1000_lcd_groups), },
1200 { "pwm0", x1000_pwm0_groups, ARRAY_SIZE(x1000_pwm0_groups), },
1201 { "pwm1", x1000_pwm1_groups, ARRAY_SIZE(x1000_pwm1_groups), },
1202 { "pwm2", x1000_pwm2_groups, ARRAY_SIZE(x1000_pwm2_groups), },
1203 { "pwm3", x1000_pwm3_groups, ARRAY_SIZE(x1000_pwm3_groups), },
1204 { "pwm4", x1000_pwm4_groups, ARRAY_SIZE(x1000_pwm4_groups), },
1205 { "mac", x1000_mac_groups, ARRAY_SIZE(x1000_mac_groups), },
1206};
1207
1208static const struct ingenic_chip_info x1000_chip_info = {
1209 .num_chips = 4,
1210 .groups = x1000_groups,
1211 .num_groups = ARRAY_SIZE(x1000_groups),
1212 .functions = x1000_functions,
1213 .num_functions = ARRAY_SIZE(x1000_functions),
1214 .pull_ups = x1000_pull_ups,
1215 .pull_downs = x1000_pull_downs,
1216};
1217
1218static const struct ingenic_chip_info x1000e_chip_info = {
1219 .num_chips = 4,
1220 .groups = x1000_groups,
1221 .num_groups = ARRAY_SIZE(x1000_groups),
1222 .functions = x1000_functions,
1223 .num_functions = ARRAY_SIZE(x1000_functions),
1224 .pull_ups = x1000_pull_ups,
1225 .pull_downs = x1000_pull_downs,
1226};
1227
Zhou Yanjie5d215952019-07-14 11:53:56 +08001228static int x1500_uart0_data_pins[] = { 0x4a, 0x4b, };
1229static int x1500_uart0_hwflow_pins[] = { 0x4c, 0x4d, };
1230static int x1500_uart1_data_a_pins[] = { 0x04, 0x05, };
1231static int x1500_uart1_data_d_pins[] = { 0x62, 0x63, };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001232static int x1500_uart1_hwflow_pins[] = { 0x64, 0x65, };
Zhou Yanjie5d215952019-07-14 11:53:56 +08001233static int x1500_uart2_data_a_pins[] = { 0x02, 0x03, };
1234static int x1500_uart2_data_d_pins[] = { 0x65, 0x64, };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001235static int x1500_mmc_1bit_pins[] = { 0x18, 0x19, 0x17, };
1236static int x1500_mmc_4bit_pins[] = { 0x16, 0x15, 0x14, };
Zhou Yanjie5d215952019-07-14 11:53:56 +08001237static int x1500_i2c0_pins[] = { 0x38, 0x37, };
1238static int x1500_i2c1_a_pins[] = { 0x01, 0x00, };
1239static int x1500_i2c1_c_pins[] = { 0x5b, 0x5a, };
1240static int x1500_i2c2_pins[] = { 0x61, 0x60, };
1241static int x1500_cim_pins[] = {
1242 0x08, 0x09, 0x0a, 0x0b,
1243 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c,
1244};
1245static int x1500_pwm_pwm0_pins[] = { 0x59, };
1246static int x1500_pwm_pwm1_pins[] = { 0x5a, };
1247static int x1500_pwm_pwm2_pins[] = { 0x5b, };
1248static int x1500_pwm_pwm3_pins[] = { 0x26, };
1249static int x1500_pwm_pwm4_pins[] = { 0x58, };
1250
1251static int x1500_uart0_data_funcs[] = { 0, 0, };
1252static int x1500_uart0_hwflow_funcs[] = { 0, 0, };
1253static int x1500_uart1_data_a_funcs[] = { 2, 2, };
1254static int x1500_uart1_data_d_funcs[] = { 1, 1, };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001255static int x1500_uart1_hwflow_funcs[] = { 1, 1, };
Zhou Yanjie5d215952019-07-14 11:53:56 +08001256static int x1500_uart2_data_a_funcs[] = { 2, 2, };
1257static int x1500_uart2_data_d_funcs[] = { 0, 0, };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001258static int x1500_mmc_1bit_funcs[] = { 1, 1, 1, };
1259static int x1500_mmc_4bit_funcs[] = { 1, 1, 1, };
Zhou Yanjie5d215952019-07-14 11:53:56 +08001260static int x1500_i2c0_funcs[] = { 0, 0, };
1261static int x1500_i2c1_a_funcs[] = { 2, 2, };
1262static int x1500_i2c1_c_funcs[] = { 0, 0, };
1263static int x1500_i2c2_funcs[] = { 1, 1, };
1264static int x1500_cim_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, };
1265static int x1500_pwm_pwm0_funcs[] = { 0, };
1266static int x1500_pwm_pwm1_funcs[] = { 1, };
1267static int x1500_pwm_pwm2_funcs[] = { 1, };
1268static int x1500_pwm_pwm3_funcs[] = { 2, };
1269static int x1500_pwm_pwm4_funcs[] = { 0, };
1270
1271static const struct group_desc x1500_groups[] = {
1272 INGENIC_PIN_GROUP("uart0-data", x1500_uart0_data),
1273 INGENIC_PIN_GROUP("uart0-hwflow", x1500_uart0_hwflow),
1274 INGENIC_PIN_GROUP("uart1-data-a", x1500_uart1_data_a),
1275 INGENIC_PIN_GROUP("uart1-data-d", x1500_uart1_data_d),
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001276 INGENIC_PIN_GROUP("uart1-hwflow", x1500_uart1_hwflow),
Zhou Yanjie5d215952019-07-14 11:53:56 +08001277 INGENIC_PIN_GROUP("uart2-data-a", x1500_uart2_data_a),
1278 INGENIC_PIN_GROUP("uart2-data-d", x1500_uart2_data_d),
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001279 INGENIC_PIN_GROUP("mmc-1bit", x1500_mmc_1bit),
1280 INGENIC_PIN_GROUP("mmc-4bit", x1500_mmc_4bit),
Zhou Yanjie5d215952019-07-14 11:53:56 +08001281 INGENIC_PIN_GROUP("i2c0-data", x1500_i2c0),
1282 INGENIC_PIN_GROUP("i2c1-data-a", x1500_i2c1_a),
1283 INGENIC_PIN_GROUP("i2c1-data-c", x1500_i2c1_c),
1284 INGENIC_PIN_GROUP("i2c2-data", x1500_i2c2),
1285 INGENIC_PIN_GROUP("cim-data", x1500_cim),
1286 { "lcd-no-pins", },
1287 INGENIC_PIN_GROUP("pwm0", x1500_pwm_pwm0),
1288 INGENIC_PIN_GROUP("pwm1", x1500_pwm_pwm1),
1289 INGENIC_PIN_GROUP("pwm2", x1500_pwm_pwm2),
1290 INGENIC_PIN_GROUP("pwm3", x1500_pwm_pwm3),
1291 INGENIC_PIN_GROUP("pwm4", x1500_pwm_pwm4),
1292};
1293
1294static const char *x1500_uart0_groups[] = { "uart0-data", "uart0-hwflow", };
1295static const char *x1500_uart1_groups[] = {
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001296 "uart1-data-a", "uart1-data-d", "uart1-hwflow",
Zhou Yanjie5d215952019-07-14 11:53:56 +08001297};
1298static const char *x1500_uart2_groups[] = { "uart2-data-a", "uart2-data-d", };
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001299static const char *x1500_mmc_groups[] = { "mmc-1bit", "mmc-4bit", };
Zhou Yanjie5d215952019-07-14 11:53:56 +08001300static const char *x1500_i2c0_groups[] = { "i2c0-data", };
1301static const char *x1500_i2c1_groups[] = { "i2c1-data-a", "i2c1-data-c", };
1302static const char *x1500_i2c2_groups[] = { "i2c2-data", };
1303static const char *x1500_cim_groups[] = { "cim-data", };
1304static const char *x1500_lcd_groups[] = { "lcd-no-pins", };
1305static const char *x1500_pwm0_groups[] = { "pwm0", };
1306static const char *x1500_pwm1_groups[] = { "pwm1", };
1307static const char *x1500_pwm2_groups[] = { "pwm2", };
1308static const char *x1500_pwm3_groups[] = { "pwm3", };
1309static const char *x1500_pwm4_groups[] = { "pwm4", };
1310
1311static const struct function_desc x1500_functions[] = {
1312 { "uart0", x1500_uart0_groups, ARRAY_SIZE(x1500_uart0_groups), },
1313 { "uart1", x1500_uart1_groups, ARRAY_SIZE(x1500_uart1_groups), },
1314 { "uart2", x1500_uart2_groups, ARRAY_SIZE(x1500_uart2_groups), },
周琰杰 (Zhou Yanjie)b4a93722019-12-16 00:21:00 +08001315 { "mmc", x1500_mmc_groups, ARRAY_SIZE(x1500_mmc_groups), },
Zhou Yanjie5d215952019-07-14 11:53:56 +08001316 { "i2c0", x1500_i2c0_groups, ARRAY_SIZE(x1500_i2c0_groups), },
1317 { "i2c1", x1500_i2c1_groups, ARRAY_SIZE(x1500_i2c1_groups), },
1318 { "i2c2", x1500_i2c2_groups, ARRAY_SIZE(x1500_i2c2_groups), },
1319 { "cim", x1500_cim_groups, ARRAY_SIZE(x1500_cim_groups), },
1320 { "lcd", x1500_lcd_groups, ARRAY_SIZE(x1500_lcd_groups), },
1321 { "pwm0", x1500_pwm0_groups, ARRAY_SIZE(x1500_pwm0_groups), },
1322 { "pwm1", x1500_pwm1_groups, ARRAY_SIZE(x1500_pwm1_groups), },
1323 { "pwm2", x1500_pwm2_groups, ARRAY_SIZE(x1500_pwm2_groups), },
1324 { "pwm3", x1500_pwm3_groups, ARRAY_SIZE(x1500_pwm3_groups), },
1325 { "pwm4", x1500_pwm4_groups, ARRAY_SIZE(x1500_pwm4_groups), },
1326};
1327
1328static const struct ingenic_chip_info x1500_chip_info = {
1329 .num_chips = 4,
1330 .groups = x1500_groups,
1331 .num_groups = ARRAY_SIZE(x1500_groups),
1332 .functions = x1500_functions,
1333 .num_functions = ARRAY_SIZE(x1500_functions),
1334 .pull_ups = x1000_pull_ups,
1335 .pull_downs = x1000_pull_downs,
1336};
1337
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001338static u32 ingenic_gpio_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg)
Paul Cercueile72394e2018-08-21 18:42:32 +02001339{
1340 unsigned int val;
1341
1342 regmap_read(jzgc->jzpc->map, jzgc->reg_base + reg, &val);
1343
1344 return (u32) val;
1345}
1346
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001347static void ingenic_gpio_set_bit(struct ingenic_gpio_chip *jzgc,
Paul Cercueile72394e2018-08-21 18:42:32 +02001348 u8 reg, u8 offset, bool set)
1349{
1350 if (set)
1351 reg = REG_SET(reg);
1352 else
1353 reg = REG_CLEAR(reg);
1354
1355 regmap_write(jzgc->jzpc->map, jzgc->reg_base + reg, BIT(offset));
1356}
1357
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001358static void ingenic_gpio_shadow_set_bit(struct ingenic_gpio_chip *jzgc,
1359 u8 reg, u8 offset, bool set)
1360{
1361 if (set)
1362 reg = REG_SET(reg);
1363 else
1364 reg = REG_CLEAR(reg);
1365
1366 regmap_write(jzgc->jzpc->map, X1000_GPIO_PZ_BASE + reg, BIT(offset));
1367}
1368
1369static void ingenic_gpio_shadow_set_bit_load(struct ingenic_gpio_chip *jzgc)
1370{
1371 regmap_write(jzgc->jzpc->map, X1000_GPIO_PZ_GID2LD,
1372 jzgc->gc.base / PINS_PER_GPIO_CHIP);
1373}
1374
Paul Cercueile72394e2018-08-21 18:42:32 +02001375static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc,
1376 u8 offset)
1377{
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001378 unsigned int val = ingenic_gpio_read_reg(jzgc, GPIO_PIN);
Paul Cercueile72394e2018-08-21 18:42:32 +02001379
1380 return !!(val & BIT(offset));
1381}
1382
1383static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc,
1384 u8 offset, int value)
1385{
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001386 if (jzgc->jzpc->version >= ID_JZ4760)
1387 ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_PAT0, offset, !!value);
Paul Cercueile72394e2018-08-21 18:42:32 +02001388 else
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001389 ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
Paul Cercueile72394e2018-08-21 18:42:32 +02001390}
1391
1392static void irq_set_type(struct ingenic_gpio_chip *jzgc,
1393 u8 offset, unsigned int type)
1394{
1395 u8 reg1, reg2;
1396
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001397 if (jzgc->jzpc->version >= ID_JZ4760) {
1398 reg1 = JZ4760_GPIO_PAT1;
1399 reg2 = JZ4760_GPIO_PAT0;
Paul Cercueile72394e2018-08-21 18:42:32 +02001400 } else {
1401 reg1 = JZ4740_GPIO_TRIG;
1402 reg2 = JZ4740_GPIO_DIR;
1403 }
1404
1405 switch (type) {
1406 case IRQ_TYPE_EDGE_RISING:
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001407 if (jzgc->jzpc->version >= ID_X1000) {
1408 ingenic_gpio_shadow_set_bit(jzgc, reg2, offset, true);
1409 ingenic_gpio_shadow_set_bit(jzgc, reg1, offset, true);
1410 ingenic_gpio_shadow_set_bit_load(jzgc);
1411 } else {
1412 ingenic_gpio_set_bit(jzgc, reg2, offset, true);
1413 ingenic_gpio_set_bit(jzgc, reg1, offset, true);
1414 }
Paul Cercueile72394e2018-08-21 18:42:32 +02001415 break;
1416 case IRQ_TYPE_EDGE_FALLING:
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001417 if (jzgc->jzpc->version >= ID_X1000) {
1418 ingenic_gpio_shadow_set_bit(jzgc, reg2, offset, false);
1419 ingenic_gpio_shadow_set_bit(jzgc, reg1, offset, true);
1420 ingenic_gpio_shadow_set_bit_load(jzgc);
1421 } else {
1422 ingenic_gpio_set_bit(jzgc, reg2, offset, false);
1423 ingenic_gpio_set_bit(jzgc, reg1, offset, true);
1424 }
Paul Cercueile72394e2018-08-21 18:42:32 +02001425 break;
1426 case IRQ_TYPE_LEVEL_HIGH:
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001427 if (jzgc->jzpc->version >= ID_X1000) {
1428 ingenic_gpio_shadow_set_bit(jzgc, reg2, offset, true);
1429 ingenic_gpio_shadow_set_bit(jzgc, reg1, offset, false);
1430 ingenic_gpio_shadow_set_bit_load(jzgc);
1431 } else {
1432 ingenic_gpio_set_bit(jzgc, reg2, offset, true);
1433 ingenic_gpio_set_bit(jzgc, reg1, offset, false);
1434 }
Paul Cercueile72394e2018-08-21 18:42:32 +02001435 break;
1436 case IRQ_TYPE_LEVEL_LOW:
1437 default:
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001438 if (jzgc->jzpc->version >= ID_X1000) {
1439 ingenic_gpio_shadow_set_bit(jzgc, reg2, offset, false);
1440 ingenic_gpio_shadow_set_bit(jzgc, reg1, offset, false);
1441 ingenic_gpio_shadow_set_bit_load(jzgc);
1442 } else {
1443 ingenic_gpio_set_bit(jzgc, reg2, offset, false);
1444 ingenic_gpio_set_bit(jzgc, reg1, offset, false);
1445 }
Paul Cercueile72394e2018-08-21 18:42:32 +02001446 break;
1447 }
1448}
1449
1450static void ingenic_gpio_irq_mask(struct irq_data *irqd)
1451{
1452 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
1453 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1454
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001455 ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, true);
Paul Cercueile72394e2018-08-21 18:42:32 +02001456}
1457
1458static void ingenic_gpio_irq_unmask(struct irq_data *irqd)
1459{
1460 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
1461 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1462
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001463 ingenic_gpio_set_bit(jzgc, GPIO_MSK, irqd->hwirq, false);
Paul Cercueile72394e2018-08-21 18:42:32 +02001464}
1465
1466static void ingenic_gpio_irq_enable(struct irq_data *irqd)
1467{
1468 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
1469 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1470 int irq = irqd->hwirq;
1471
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001472 if (jzgc->jzpc->version >= ID_JZ4760)
1473 ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, true);
Paul Cercueile72394e2018-08-21 18:42:32 +02001474 else
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001475 ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
Paul Cercueile72394e2018-08-21 18:42:32 +02001476
1477 ingenic_gpio_irq_unmask(irqd);
1478}
1479
1480static void ingenic_gpio_irq_disable(struct irq_data *irqd)
1481{
1482 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
1483 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1484 int irq = irqd->hwirq;
1485
1486 ingenic_gpio_irq_mask(irqd);
1487
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001488 if (jzgc->jzpc->version >= ID_JZ4760)
1489 ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, false);
Paul Cercueile72394e2018-08-21 18:42:32 +02001490 else
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001491 ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
Paul Cercueile72394e2018-08-21 18:42:32 +02001492}
1493
1494static void ingenic_gpio_irq_ack(struct irq_data *irqd)
1495{
1496 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
1497 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1498 int irq = irqd->hwirq;
1499 bool high;
1500
1501 if (irqd_get_trigger_type(irqd) == IRQ_TYPE_EDGE_BOTH) {
1502 /*
1503 * Switch to an interrupt for the opposite edge to the one that
1504 * triggered the interrupt being ACKed.
1505 */
1506 high = ingenic_gpio_get_value(jzgc, irq);
1507 if (high)
1508 irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
1509 else
1510 irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
1511 }
1512
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001513 if (jzgc->jzpc->version >= ID_JZ4760)
1514 ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_FLAG, irq, false);
Paul Cercueile72394e2018-08-21 18:42:32 +02001515 else
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001516 ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
Paul Cercueile72394e2018-08-21 18:42:32 +02001517}
1518
1519static int ingenic_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
1520{
1521 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
1522 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1523
1524 switch (type) {
1525 case IRQ_TYPE_EDGE_BOTH:
1526 case IRQ_TYPE_EDGE_RISING:
1527 case IRQ_TYPE_EDGE_FALLING:
1528 irq_set_handler_locked(irqd, handle_edge_irq);
1529 break;
1530 case IRQ_TYPE_LEVEL_HIGH:
1531 case IRQ_TYPE_LEVEL_LOW:
1532 irq_set_handler_locked(irqd, handle_level_irq);
1533 break;
1534 default:
1535 irq_set_handler_locked(irqd, handle_bad_irq);
1536 }
1537
1538 if (type == IRQ_TYPE_EDGE_BOTH) {
1539 /*
1540 * The hardware does not support interrupts on both edges. The
1541 * best we can do is to set up a single-edge interrupt and then
1542 * switch to the opposing edge when ACKing the interrupt.
1543 */
1544 bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq);
1545
1546 type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
1547 }
1548
1549 irq_set_type(jzgc, irqd->hwirq, type);
1550 return 0;
1551}
1552
1553static int ingenic_gpio_irq_set_wake(struct irq_data *irqd, unsigned int on)
1554{
1555 struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
1556 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1557
1558 return irq_set_irq_wake(jzgc->irq, on);
1559}
1560
1561static void ingenic_gpio_irq_handler(struct irq_desc *desc)
1562{
1563 struct gpio_chip *gc = irq_desc_get_handler_data(desc);
1564 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1565 struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data);
1566 unsigned long flag, i;
1567
1568 chained_irq_enter(irq_chip, desc);
1569
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001570 if (jzgc->jzpc->version >= ID_JZ4760)
1571 flag = ingenic_gpio_read_reg(jzgc, JZ4760_GPIO_FLAG);
Paul Cercueile72394e2018-08-21 18:42:32 +02001572 else
Zhou Yanjieb71c1842019-01-28 23:19:59 +08001573 flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG);
Paul Cercueile72394e2018-08-21 18:42:32 +02001574
1575 for_each_set_bit(i, &flag, 32)
1576 generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
1577 chained_irq_exit(irq_chip, desc);
1578}
1579
1580static void ingenic_gpio_set(struct gpio_chip *gc,
1581 unsigned int offset, int value)
1582{
1583 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1584
1585 ingenic_gpio_set_value(jzgc, offset, value);
1586}
1587
1588static int ingenic_gpio_get(struct gpio_chip *gc, unsigned int offset)
1589{
1590 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1591
1592 return (int) ingenic_gpio_get_value(jzgc, offset);
1593}
1594
1595static int ingenic_gpio_direction_input(struct gpio_chip *gc,
1596 unsigned int offset)
1597{
1598 return pinctrl_gpio_direction_input(gc->base + offset);
1599}
1600
1601static int ingenic_gpio_direction_output(struct gpio_chip *gc,
1602 unsigned int offset, int value)
1603{
1604 ingenic_gpio_set(gc, offset, value);
1605 return pinctrl_gpio_direction_output(gc->base + offset);
1606}
1607
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001608static inline void ingenic_config_pin(struct ingenic_pinctrl *jzpc,
1609 unsigned int pin, u8 reg, bool set)
1610{
1611 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1612 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1613
1614 regmap_write(jzpc->map, offt * 0x100 +
1615 (set ? REG_SET(reg) : REG_CLEAR(reg)), BIT(idx));
1616}
1617
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001618static inline void ingenic_shadow_config_pin(struct ingenic_pinctrl *jzpc,
1619 unsigned int pin, u8 reg, bool set)
1620{
1621 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1622
1623 regmap_write(jzpc->map, X1000_GPIO_PZ_BASE +
1624 (set ? REG_SET(reg) : REG_CLEAR(reg)), BIT(idx));
1625}
1626
1627static inline void ingenic_shadow_config_pin_load(struct ingenic_pinctrl *jzpc,
1628 unsigned int pin)
1629{
1630 regmap_write(jzpc->map, X1000_GPIO_PZ_GID2LD, pin / PINS_PER_GPIO_CHIP);
1631}
1632
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001633static inline bool ingenic_get_pin_config(struct ingenic_pinctrl *jzpc,
1634 unsigned int pin, u8 reg)
1635{
1636 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1637 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1638 unsigned int val;
1639
1640 regmap_read(jzpc->map, offt * 0x100 + reg, &val);
1641
1642 return val & BIT(idx);
1643}
1644
Paul Cercueilebd66512018-08-21 18:42:33 +02001645static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
1646{
1647 struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
1648 struct ingenic_pinctrl *jzpc = jzgc->jzpc;
1649 unsigned int pin = gc->base + offset;
1650
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001651 if (jzpc->version >= ID_JZ4760)
1652 return ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1);
Paul Cercueilebd66512018-08-21 18:42:33 +02001653
1654 if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT))
1655 return true;
1656
1657 return !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_DIR);
1658}
1659
Julia Lawall5bf7b842017-08-10 12:06:23 +02001660static const struct pinctrl_ops ingenic_pctlops = {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001661 .get_groups_count = pinctrl_generic_get_group_count,
1662 .get_group_name = pinctrl_generic_get_group_name,
1663 .get_group_pins = pinctrl_generic_get_group_pins,
1664 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
1665 .dt_free_map = pinconf_generic_dt_free_map,
1666};
1667
1668static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
1669 int pin, int func)
1670{
1671 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1672 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1673
1674 dev_dbg(jzpc->dev, "set pin P%c%u to function %u\n",
1675 'A' + offt, idx, func);
1676
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001677 if (jzpc->version >= ID_X1000) {
1678 ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
1679 ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, false);
1680 ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2);
1681 ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1);
1682 ingenic_shadow_config_pin_load(jzpc, pin);
1683 } else if (jzpc->version >= ID_JZ4760) {
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001684 ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
Paul Cercueile72394e2018-08-21 18:42:32 +02001685 ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001686 ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2);
1687 ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001688 } else {
1689 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
1690 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
1691 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
1692 }
1693
1694 return 0;
1695}
1696
1697static int ingenic_pinmux_set_mux(struct pinctrl_dev *pctldev,
1698 unsigned int selector, unsigned int group)
1699{
1700 struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1701 struct function_desc *func;
1702 struct group_desc *grp;
1703 unsigned int i;
1704
1705 func = pinmux_generic_get_function(pctldev, selector);
1706 if (!func)
1707 return -EINVAL;
1708
1709 grp = pinctrl_generic_get_group(pctldev, group);
1710 if (!grp)
1711 return -EINVAL;
1712
1713 dev_dbg(pctldev->dev, "enable function %s group %s\n",
1714 func->name, grp->name);
1715
1716 for (i = 0; i < grp->num_pins; i++) {
1717 int *pin_modes = grp->data;
1718
1719 ingenic_pinmux_set_pin_fn(jzpc, grp->pins[i], pin_modes[i]);
1720 }
1721
1722 return 0;
1723}
1724
1725static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
1726 struct pinctrl_gpio_range *range,
1727 unsigned int pin, bool input)
1728{
1729 struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1730 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1731 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1732
1733 dev_dbg(pctldev->dev, "set pin P%c%u to %sput\n",
1734 'A' + offt, idx, input ? "in" : "out");
1735
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001736 if (jzpc->version >= ID_X1000) {
1737 ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
1738 ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, true);
1739 ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input);
1740 ingenic_shadow_config_pin_load(jzpc, pin);
1741 } else if (jzpc->version >= ID_JZ4760) {
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001742 ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
Paul Cercueile72394e2018-08-21 18:42:32 +02001743 ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001744 ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001745 } else {
1746 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
Paul Cercueil0084a782018-06-27 13:49:02 +02001747 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, !input);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001748 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, false);
1749 }
1750
1751 return 0;
1752}
1753
Julia Lawall5bf7b842017-08-10 12:06:23 +02001754static const struct pinmux_ops ingenic_pmxops = {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001755 .get_functions_count = pinmux_generic_get_function_count,
1756 .get_function_name = pinmux_generic_get_function_name,
1757 .get_function_groups = pinmux_generic_get_function_groups,
1758 .set_mux = ingenic_pinmux_set_mux,
1759 .gpio_set_direction = ingenic_pinmux_gpio_set_direction,
1760};
1761
1762static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
1763 unsigned int pin, unsigned long *config)
1764{
1765 struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1766 enum pin_config_param param = pinconf_to_config_param(*config);
1767 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1768 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
1769 bool pull;
1770
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001771 if (jzpc->version >= ID_JZ4760)
1772 pull = !ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PEN);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001773 else
1774 pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
1775
1776 switch (param) {
1777 case PIN_CONFIG_BIAS_DISABLE:
1778 if (pull)
1779 return -EINVAL;
1780 break;
1781
1782 case PIN_CONFIG_BIAS_PULL_UP:
1783 if (!pull || !(jzpc->info->pull_ups[offt] & BIT(idx)))
1784 return -EINVAL;
1785 break;
1786
1787 case PIN_CONFIG_BIAS_PULL_DOWN:
1788 if (!pull || !(jzpc->info->pull_downs[offt] & BIT(idx)))
1789 return -EINVAL;
1790 break;
1791
1792 default:
1793 return -ENOTSUPP;
1794 }
1795
1796 *config = pinconf_to_config_packed(param, 1);
1797 return 0;
1798}
1799
1800static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
1801 unsigned int pin, bool enabled)
1802{
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001803 if (jzpc->version >= ID_JZ4760)
1804 ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PEN, !enabled);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001805 else
1806 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled);
1807}
1808
Paul Cercueil7009d042019-11-19 16:52:10 +01001809static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc,
1810 unsigned int pin, bool high)
1811{
Paul Cercueil9e655272019-12-10 17:44:46 +01001812 if (jzpc->version >= ID_JZ4760)
Paul Cercueil7009d042019-11-19 16:52:10 +01001813 ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, high);
1814 else
1815 ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high);
1816}
1817
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001818static int ingenic_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
1819 unsigned long *configs, unsigned int num_configs)
1820{
1821 struct ingenic_pinctrl *jzpc = pinctrl_dev_get_drvdata(pctldev);
1822 unsigned int idx = pin % PINS_PER_GPIO_CHIP;
1823 unsigned int offt = pin / PINS_PER_GPIO_CHIP;
Paul Cercueil7009d042019-11-19 16:52:10 +01001824 unsigned int cfg, arg;
1825 int ret;
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001826
1827 for (cfg = 0; cfg < num_configs; cfg++) {
1828 switch (pinconf_to_config_param(configs[cfg])) {
1829 case PIN_CONFIG_BIAS_DISABLE:
1830 case PIN_CONFIG_BIAS_PULL_UP:
1831 case PIN_CONFIG_BIAS_PULL_DOWN:
Paul Cercueil7009d042019-11-19 16:52:10 +01001832 case PIN_CONFIG_OUTPUT:
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001833 continue;
1834 default:
1835 return -ENOTSUPP;
1836 }
1837 }
1838
1839 for (cfg = 0; cfg < num_configs; cfg++) {
Paul Cercueil7009d042019-11-19 16:52:10 +01001840 arg = pinconf_to_config_argument(configs[cfg]);
1841
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001842 switch (pinconf_to_config_param(configs[cfg])) {
1843 case PIN_CONFIG_BIAS_DISABLE:
1844 dev_dbg(jzpc->dev, "disable pull-over for pin P%c%u\n",
1845 'A' + offt, idx);
1846 ingenic_set_bias(jzpc, pin, false);
1847 break;
1848
1849 case PIN_CONFIG_BIAS_PULL_UP:
1850 if (!(jzpc->info->pull_ups[offt] & BIT(idx)))
1851 return -EINVAL;
1852 dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
1853 'A' + offt, idx);
1854 ingenic_set_bias(jzpc, pin, true);
1855 break;
1856
1857 case PIN_CONFIG_BIAS_PULL_DOWN:
1858 if (!(jzpc->info->pull_downs[offt] & BIT(idx)))
1859 return -EINVAL;
1860 dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
1861 'A' + offt, idx);
1862 ingenic_set_bias(jzpc, pin, true);
1863 break;
1864
Paul Cercueil7009d042019-11-19 16:52:10 +01001865 case PIN_CONFIG_OUTPUT:
1866 ret = pinctrl_gpio_direction_output(pin);
1867 if (ret)
1868 return ret;
1869
1870 ingenic_set_output_level(jzpc, pin, arg);
1871 break;
1872
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001873 default:
1874 unreachable();
1875 }
1876 }
1877
1878 return 0;
1879}
1880
1881static int ingenic_pinconf_group_get(struct pinctrl_dev *pctldev,
1882 unsigned int group, unsigned long *config)
1883{
1884 const unsigned int *pins;
1885 unsigned int i, npins, old = 0;
1886 int ret;
1887
1888 ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
1889 if (ret)
1890 return ret;
1891
1892 for (i = 0; i < npins; i++) {
1893 if (ingenic_pinconf_get(pctldev, pins[i], config))
1894 return -ENOTSUPP;
1895
1896 /* configs do not match between two pins */
1897 if (i && (old != *config))
1898 return -ENOTSUPP;
1899
1900 old = *config;
1901 }
1902
1903 return 0;
1904}
1905
1906static int ingenic_pinconf_group_set(struct pinctrl_dev *pctldev,
1907 unsigned int group, unsigned long *configs,
1908 unsigned int num_configs)
1909{
1910 const unsigned int *pins;
1911 unsigned int i, npins;
1912 int ret;
1913
1914 ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
1915 if (ret)
1916 return ret;
1917
1918 for (i = 0; i < npins; i++) {
1919 ret = ingenic_pinconf_set(pctldev,
1920 pins[i], configs, num_configs);
1921 if (ret)
1922 return ret;
1923 }
1924
1925 return 0;
1926}
1927
Julia Lawall5bf7b842017-08-10 12:06:23 +02001928static const struct pinconf_ops ingenic_confops = {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001929 .is_generic = true,
1930 .pin_config_get = ingenic_pinconf_get,
1931 .pin_config_set = ingenic_pinconf_set,
1932 .pin_config_group_get = ingenic_pinconf_group_get,
1933 .pin_config_group_set = ingenic_pinconf_group_set,
1934};
1935
1936static const struct regmap_config ingenic_pinctrl_regmap_config = {
1937 .reg_bits = 32,
1938 .val_bits = 32,
1939 .reg_stride = 4,
1940};
1941
1942static const struct of_device_id ingenic_pinctrl_of_match[] = {
1943 { .compatible = "ingenic,jz4740-pinctrl", .data = (void *) ID_JZ4740 },
Paul Cercueilf2a96762018-08-21 18:42:34 +02001944 { .compatible = "ingenic,jz4725b-pinctrl", .data = (void *)ID_JZ4725B },
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001945 { .compatible = "ingenic,jz4760-pinctrl", .data = (void *) ID_JZ4760 },
1946 { .compatible = "ingenic,jz4760b-pinctrl", .data = (void *) ID_JZ4760B },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001947 { .compatible = "ingenic,jz4770-pinctrl", .data = (void *) ID_JZ4770 },
1948 { .compatible = "ingenic,jz4780-pinctrl", .data = (void *) ID_JZ4780 },
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001949 { .compatible = "ingenic,x1000-pinctrl", .data = (void *) ID_X1000 },
1950 { .compatible = "ingenic,x1000e-pinctrl", .data = (void *) ID_X1000E },
Zhou Yanjie5d215952019-07-14 11:53:56 +08001951 { .compatible = "ingenic,x1500-pinctrl", .data = (void *) ID_X1500 },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02001952 {},
1953};
1954
Paul Cercueile72394e2018-08-21 18:42:32 +02001955static const struct of_device_id ingenic_gpio_of_match[] __initconst = {
1956 { .compatible = "ingenic,jz4740-gpio", },
Zhou Yanjie0257595a2019-07-14 11:53:52 +08001957 { .compatible = "ingenic,jz4760-gpio", },
Paul Cercueile72394e2018-08-21 18:42:32 +02001958 { .compatible = "ingenic,jz4770-gpio", },
1959 { .compatible = "ingenic,jz4780-gpio", },
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08001960 { .compatible = "ingenic,x1000-gpio", },
Paul Cercueile72394e2018-08-21 18:42:32 +02001961 {},
1962};
1963
1964static int __init ingenic_gpio_probe(struct ingenic_pinctrl *jzpc,
1965 struct device_node *node)
1966{
1967 struct ingenic_gpio_chip *jzgc;
1968 struct device *dev = jzpc->dev;
Linus Walleij142b8762019-10-01 15:32:09 +02001969 struct gpio_irq_chip *girq;
Paul Cercueile72394e2018-08-21 18:42:32 +02001970 unsigned int bank;
1971 int err;
1972
1973 err = of_property_read_u32(node, "reg", &bank);
1974 if (err) {
1975 dev_err(dev, "Cannot read \"reg\" property: %i\n", err);
1976 return err;
1977 }
1978
1979 jzgc = devm_kzalloc(dev, sizeof(*jzgc), GFP_KERNEL);
1980 if (!jzgc)
1981 return -ENOMEM;
1982
1983 jzgc->jzpc = jzpc;
1984 jzgc->reg_base = bank * 0x100;
1985
1986 jzgc->gc.label = devm_kasprintf(dev, GFP_KERNEL, "GPIO%c", 'A' + bank);
1987 if (!jzgc->gc.label)
1988 return -ENOMEM;
1989
1990 /* DO NOT EXPAND THIS: FOR BACKWARD GPIO NUMBERSPACE COMPATIBIBILITY
1991 * ONLY: WORK TO TRANSITION CONSUMERS TO USE THE GPIO DESCRIPTOR API IN
1992 * <linux/gpio/consumer.h> INSTEAD.
1993 */
1994 jzgc->gc.base = bank * 32;
1995
1996 jzgc->gc.ngpio = 32;
1997 jzgc->gc.parent = dev;
1998 jzgc->gc.of_node = node;
1999 jzgc->gc.owner = THIS_MODULE;
2000
2001 jzgc->gc.set = ingenic_gpio_set;
2002 jzgc->gc.get = ingenic_gpio_get;
2003 jzgc->gc.direction_input = ingenic_gpio_direction_input;
2004 jzgc->gc.direction_output = ingenic_gpio_direction_output;
Paul Cercueilebd66512018-08-21 18:42:33 +02002005 jzgc->gc.get_direction = ingenic_gpio_get_direction;
Paul Cercueile72394e2018-08-21 18:42:32 +02002006
2007 if (of_property_read_bool(node, "gpio-ranges")) {
2008 jzgc->gc.request = gpiochip_generic_request;
2009 jzgc->gc.free = gpiochip_generic_free;
2010 }
2011
Paul Cercueile72394e2018-08-21 18:42:32 +02002012 jzgc->irq = irq_of_parse_and_map(node, 0);
2013 if (!jzgc->irq)
2014 return -EINVAL;
2015
2016 jzgc->irq_chip.name = jzgc->gc.label;
2017 jzgc->irq_chip.irq_enable = ingenic_gpio_irq_enable;
2018 jzgc->irq_chip.irq_disable = ingenic_gpio_irq_disable;
2019 jzgc->irq_chip.irq_unmask = ingenic_gpio_irq_unmask;
2020 jzgc->irq_chip.irq_mask = ingenic_gpio_irq_mask;
2021 jzgc->irq_chip.irq_ack = ingenic_gpio_irq_ack;
2022 jzgc->irq_chip.irq_set_type = ingenic_gpio_irq_set_type;
2023 jzgc->irq_chip.irq_set_wake = ingenic_gpio_irq_set_wake;
2024 jzgc->irq_chip.flags = IRQCHIP_MASK_ON_SUSPEND;
2025
Linus Walleij142b8762019-10-01 15:32:09 +02002026 girq = &jzgc->gc.irq;
2027 girq->chip = &jzgc->irq_chip;
2028 girq->parent_handler = ingenic_gpio_irq_handler;
2029 girq->num_parents = 1;
2030 girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
2031 GFP_KERNEL);
2032 if (!girq->parents)
2033 return -ENOMEM;
2034 girq->parents[0] = jzgc->irq;
2035 girq->default_type = IRQ_TYPE_NONE;
2036 girq->handler = handle_level_irq;
2037
2038 err = devm_gpiochip_add_data(dev, &jzgc->gc, jzgc);
Paul Cercueile72394e2018-08-21 18:42:32 +02002039 if (err)
2040 return err;
2041
Paul Cercueile72394e2018-08-21 18:42:32 +02002042 return 0;
2043}
2044
Paul Cercueil4717b112018-08-21 18:42:31 +02002045static int __init ingenic_pinctrl_probe(struct platform_device *pdev)
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002046{
2047 struct device *dev = &pdev->dev;
2048 struct ingenic_pinctrl *jzpc;
2049 struct pinctrl_desc *pctl_desc;
2050 void __iomem *base;
2051 const struct platform_device_id *id = platform_get_device_id(pdev);
2052 const struct of_device_id *of_id = of_match_device(
2053 ingenic_pinctrl_of_match, dev);
2054 const struct ingenic_chip_info *chip_info;
Paul Cercueile72394e2018-08-21 18:42:32 +02002055 struct device_node *node;
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002056 unsigned int i;
2057 int err;
2058
2059 jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
2060 if (!jzpc)
2061 return -ENOMEM;
2062
2063 base = devm_ioremap_resource(dev,
2064 platform_get_resource(pdev, IORESOURCE_MEM, 0));
Wei Yongjun119fcf42018-01-17 11:29:17 +00002065 if (IS_ERR(base))
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002066 return PTR_ERR(base);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002067
2068 jzpc->map = devm_regmap_init_mmio(dev, base,
2069 &ingenic_pinctrl_regmap_config);
2070 if (IS_ERR(jzpc->map)) {
2071 dev_err(dev, "Failed to create regmap\n");
2072 return PTR_ERR(jzpc->map);
2073 }
2074
2075 jzpc->dev = dev;
2076
2077 if (of_id)
2078 jzpc->version = (enum jz_version)of_id->data;
2079 else
2080 jzpc->version = (enum jz_version)id->driver_data;
2081
Zhou Yanjie5d215952019-07-14 11:53:56 +08002082 if (jzpc->version >= ID_X1500)
2083 chip_info = &x1500_chip_info;
2084 else if (jzpc->version >= ID_X1000E)
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08002085 chip_info = &x1000e_chip_info;
2086 else if (jzpc->version >= ID_X1000)
2087 chip_info = &x1000_chip_info;
2088 else if (jzpc->version >= ID_JZ4780)
Zhou Yanjieff656e42019-01-28 23:19:57 +08002089 chip_info = &jz4780_chip_info;
2090 else if (jzpc->version >= ID_JZ4770)
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002091 chip_info = &jz4770_chip_info;
Zhou Yanjie0257595a2019-07-14 11:53:52 +08002092 else if (jzpc->version >= ID_JZ4760B)
2093 chip_info = &jz4760b_chip_info;
2094 else if (jzpc->version >= ID_JZ4760)
2095 chip_info = &jz4760_chip_info;
Paul Cercueilf2a96762018-08-21 18:42:34 +02002096 else if (jzpc->version >= ID_JZ4725B)
2097 chip_info = &jz4725b_chip_info;
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002098 else
2099 chip_info = &jz4740_chip_info;
2100 jzpc->info = chip_info;
2101
2102 pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
2103 if (!pctl_desc)
2104 return -ENOMEM;
2105
2106 /* fill in pinctrl_desc structure */
2107 pctl_desc->name = dev_name(dev);
2108 pctl_desc->owner = THIS_MODULE;
2109 pctl_desc->pctlops = &ingenic_pctlops;
2110 pctl_desc->pmxops = &ingenic_pmxops;
2111 pctl_desc->confops = &ingenic_confops;
2112 pctl_desc->npins = chip_info->num_chips * PINS_PER_GPIO_CHIP;
Kees Cooka86854d2018-06-12 14:07:58 -07002113 pctl_desc->pins = jzpc->pdesc = devm_kcalloc(&pdev->dev,
2114 pctl_desc->npins, sizeof(*jzpc->pdesc), GFP_KERNEL);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002115 if (!jzpc->pdesc)
2116 return -ENOMEM;
2117
2118 for (i = 0; i < pctl_desc->npins; i++) {
2119 jzpc->pdesc[i].number = i;
2120 jzpc->pdesc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
2121 'A' + (i / PINS_PER_GPIO_CHIP),
2122 i % PINS_PER_GPIO_CHIP);
2123 }
2124
2125 jzpc->pctl = devm_pinctrl_register(dev, pctl_desc, jzpc);
Dan Carpentere7f4c4b2017-06-14 12:12:09 +03002126 if (IS_ERR(jzpc->pctl)) {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002127 dev_err(dev, "Failed to register pinctrl\n");
Dan Carpentere7f4c4b2017-06-14 12:12:09 +03002128 return PTR_ERR(jzpc->pctl);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002129 }
2130
2131 for (i = 0; i < chip_info->num_groups; i++) {
2132 const struct group_desc *group = &chip_info->groups[i];
2133
2134 err = pinctrl_generic_add_group(jzpc->pctl, group->name,
2135 group->pins, group->num_pins, group->data);
Paul Burton823dd712018-08-25 10:53:28 -07002136 if (err < 0) {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002137 dev_err(dev, "Failed to register group %s\n",
2138 group->name);
2139 return err;
2140 }
2141 }
2142
2143 for (i = 0; i < chip_info->num_functions; i++) {
2144 const struct function_desc *func = &chip_info->functions[i];
2145
2146 err = pinmux_generic_add_function(jzpc->pctl, func->name,
2147 func->group_names, func->num_group_names,
2148 func->data);
Paul Burton823dd712018-08-25 10:53:28 -07002149 if (err < 0) {
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002150 dev_err(dev, "Failed to register function %s\n",
2151 func->name);
2152 return err;
2153 }
2154 }
2155
2156 dev_set_drvdata(dev, jzpc->map);
2157
Paul Cercueile72394e2018-08-21 18:42:32 +02002158 for_each_child_of_node(dev->of_node, node) {
2159 if (of_match_node(ingenic_gpio_of_match, node)) {
2160 err = ingenic_gpio_probe(jzpc, node);
2161 if (err)
2162 return err;
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002163 }
2164 }
2165
2166 return 0;
2167}
2168
2169static const struct platform_device_id ingenic_pinctrl_ids[] = {
2170 { "jz4740-pinctrl", ID_JZ4740 },
Paul Cercueilf2a96762018-08-21 18:42:34 +02002171 { "jz4725b-pinctrl", ID_JZ4725B },
Zhou Yanjie0257595a2019-07-14 11:53:52 +08002172 { "jz4760-pinctrl", ID_JZ4760 },
2173 { "jz4760b-pinctrl", ID_JZ4760B },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002174 { "jz4770-pinctrl", ID_JZ4770 },
2175 { "jz4780-pinctrl", ID_JZ4780 },
Zhou Yanjiefe1ad5e2019-07-14 11:53:54 +08002176 { "x1000-pinctrl", ID_X1000 },
2177 { "x1000e-pinctrl", ID_X1000E },
Zhou Yanjie5d215952019-07-14 11:53:56 +08002178 { "x1500-pinctrl", ID_X1500 },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002179 {},
2180};
2181
2182static struct platform_driver ingenic_pinctrl_driver = {
2183 .driver = {
2184 .name = "pinctrl-ingenic",
2185 .of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002186 },
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002187 .id_table = ingenic_pinctrl_ids,
2188};
2189
2190static int __init ingenic_pinctrl_drv_register(void)
2191{
Paul Cercueil4717b112018-08-21 18:42:31 +02002192 return platform_driver_probe(&ingenic_pinctrl_driver,
2193 ingenic_pinctrl_probe);
Paul Cercueilb5c23aa2017-05-12 18:52:56 +02002194}
Paul Cercueil556a36a2018-08-21 18:42:30 +02002195subsys_initcall(ingenic_pinctrl_drv_register);