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