2 * Ingenic SoCs pinctrl driver
4 * Copyright (c) 2017 Paul Cercueil <paul@crapouillou.net>
6 * License terms: GNU General Public License (GPL) version 2
9 #include <linux/compiler.h>
10 #include <linux/gpio.h>
11 #include <linux/interrupt.h>
13 #include <linux/of_device.h>
14 #include <linux/of_platform.h>
15 #include <linux/pinctrl/pinctrl.h>
16 #include <linux/pinctrl/pinmux.h>
17 #include <linux/pinctrl/pinconf.h>
18 #include <linux/pinctrl/pinconf-generic.h>
19 #include <linux/platform_device.h>
20 #include <linux/regmap.h>
21 #include <linux/slab.h>
27 #define JZ4740_GPIO_DATA 0x10
28 #define JZ4740_GPIO_PULL_DIS 0x30
29 #define JZ4740_GPIO_FUNC 0x40
30 #define JZ4740_GPIO_SELECT 0x50
31 #define JZ4740_GPIO_DIR 0x60
32 #define JZ4740_GPIO_TRIG 0x70
33 #define JZ4740_GPIO_FLAG 0x80
35 #define JZ4770_GPIO_INT 0x10
36 #define JZ4770_GPIO_MSK 0x20
37 #define JZ4770_GPIO_PAT1 0x30
38 #define JZ4770_GPIO_PAT0 0x40
39 #define JZ4770_GPIO_FLAG 0x50
40 #define JZ4770_GPIO_PEN 0x70
42 #define REG_SET(x) ((x) + 0x4)
43 #define REG_CLEAR(x) ((x) + 0x8)
45 #define PINS_PER_GPIO_CHIP 32
53 struct ingenic_chip_info
{
54 unsigned int num_chips
;
56 const struct group_desc
*groups
;
57 unsigned int num_groups
;
59 const struct function_desc
*functions
;
60 unsigned int num_functions
;
62 const u32
*pull_ups
, *pull_downs
;
65 struct ingenic_pinctrl
{
68 struct pinctrl_dev
*pctl
;
69 struct pinctrl_pin_desc
*pdesc
;
70 enum jz_version version
;
72 const struct ingenic_chip_info
*info
;
75 static const u32 jz4740_pull_ups
[4] = {
76 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
79 static const u32 jz4740_pull_downs
[4] = {
80 0x00000000, 0x00000000, 0x00000000, 0x00000000,
83 static int jz4740_mmc_1bit_pins
[] = { 0x69, 0x68, 0x6a, };
84 static int jz4740_mmc_4bit_pins
[] = { 0x6b, 0x6c, 0x6d, };
85 static int jz4740_uart0_data_pins
[] = { 0x7a, 0x79, };
86 static int jz4740_uart0_hwflow_pins
[] = { 0x7e, 0x7f, };
87 static int jz4740_uart1_data_pins
[] = { 0x7e, 0x7f, };
88 static int jz4740_lcd_8bit_pins
[] = {
89 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x52, 0x53, 0x54,
91 static int jz4740_lcd_16bit_pins
[] = {
92 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x55,
94 static int jz4740_lcd_18bit_pins
[] = { 0x50, 0x51, };
95 static int jz4740_lcd_18bit_tft_pins
[] = { 0x56, 0x57, 0x31, 0x32, };
96 static int jz4740_nand_cs1_pins
[] = { 0x39, };
97 static int jz4740_nand_cs2_pins
[] = { 0x3a, };
98 static int jz4740_nand_cs3_pins
[] = { 0x3b, };
99 static int jz4740_nand_cs4_pins
[] = { 0x3c, };
100 static int jz4740_pwm_pwm0_pins
[] = { 0x77, };
101 static int jz4740_pwm_pwm1_pins
[] = { 0x78, };
102 static int jz4740_pwm_pwm2_pins
[] = { 0x79, };
103 static int jz4740_pwm_pwm3_pins
[] = { 0x7a, };
104 static int jz4740_pwm_pwm4_pins
[] = { 0x7b, };
105 static int jz4740_pwm_pwm5_pins
[] = { 0x7c, };
106 static int jz4740_pwm_pwm6_pins
[] = { 0x7e, };
107 static int jz4740_pwm_pwm7_pins
[] = { 0x7f, };
109 static int jz4740_mmc_1bit_funcs
[] = { 0, 0, 0, };
110 static int jz4740_mmc_4bit_funcs
[] = { 0, 0, 0, };
111 static int jz4740_uart0_data_funcs
[] = { 1, 1, };
112 static int jz4740_uart0_hwflow_funcs
[] = { 1, 1, };
113 static int jz4740_uart1_data_funcs
[] = { 2, 2, };
114 static int jz4740_lcd_8bit_funcs
[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
115 static int jz4740_lcd_16bit_funcs
[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, };
116 static int jz4740_lcd_18bit_funcs
[] = { 0, 0, };
117 static int jz4740_lcd_18bit_tft_funcs
[] = { 0, 0, 0, 0, };
118 static int jz4740_nand_cs1_funcs
[] = { 0, };
119 static int jz4740_nand_cs2_funcs
[] = { 0, };
120 static int jz4740_nand_cs3_funcs
[] = { 0, };
121 static int jz4740_nand_cs4_funcs
[] = { 0, };
122 static int jz4740_pwm_pwm0_funcs
[] = { 0, };
123 static int jz4740_pwm_pwm1_funcs
[] = { 0, };
124 static int jz4740_pwm_pwm2_funcs
[] = { 0, };
125 static int jz4740_pwm_pwm3_funcs
[] = { 0, };
126 static int jz4740_pwm_pwm4_funcs
[] = { 0, };
127 static int jz4740_pwm_pwm5_funcs
[] = { 0, };
128 static int jz4740_pwm_pwm6_funcs
[] = { 0, };
129 static int jz4740_pwm_pwm7_funcs
[] = { 0, };
131 #define INGENIC_PIN_GROUP(name, id) \
135 ARRAY_SIZE(id##_pins), \
139 static const struct group_desc jz4740_groups
[] = {
140 INGENIC_PIN_GROUP("mmc-1bit", jz4740_mmc_1bit
),
141 INGENIC_PIN_GROUP("mmc-4bit", jz4740_mmc_4bit
),
142 INGENIC_PIN_GROUP("uart0-data", jz4740_uart0_data
),
143 INGENIC_PIN_GROUP("uart0-hwflow", jz4740_uart0_hwflow
),
144 INGENIC_PIN_GROUP("uart1-data", jz4740_uart1_data
),
145 INGENIC_PIN_GROUP("lcd-8bit", jz4740_lcd_8bit
),
146 INGENIC_PIN_GROUP("lcd-16bit", jz4740_lcd_16bit
),
147 INGENIC_PIN_GROUP("lcd-18bit", jz4740_lcd_18bit
),
148 INGENIC_PIN_GROUP("lcd-18bit-tft", jz4740_lcd_18bit_tft
),
150 INGENIC_PIN_GROUP("nand-cs1", jz4740_nand_cs1
),
151 INGENIC_PIN_GROUP("nand-cs2", jz4740_nand_cs2
),
152 INGENIC_PIN_GROUP("nand-cs3", jz4740_nand_cs3
),
153 INGENIC_PIN_GROUP("nand-cs4", jz4740_nand_cs4
),
154 INGENIC_PIN_GROUP("pwm0", jz4740_pwm_pwm0
),
155 INGENIC_PIN_GROUP("pwm1", jz4740_pwm_pwm1
),
156 INGENIC_PIN_GROUP("pwm2", jz4740_pwm_pwm2
),
157 INGENIC_PIN_GROUP("pwm3", jz4740_pwm_pwm3
),
158 INGENIC_PIN_GROUP("pwm4", jz4740_pwm_pwm4
),
159 INGENIC_PIN_GROUP("pwm5", jz4740_pwm_pwm5
),
160 INGENIC_PIN_GROUP("pwm6", jz4740_pwm_pwm6
),
161 INGENIC_PIN_GROUP("pwm7", jz4740_pwm_pwm7
),
164 static const char *jz4740_mmc_groups
[] = { "mmc-1bit", "mmc-4bit", };
165 static const char *jz4740_uart0_groups
[] = { "uart0-data", "uart0-hwflow", };
166 static const char *jz4740_uart1_groups
[] = { "uart1-data", };
167 static const char *jz4740_lcd_groups
[] = {
168 "lcd-8bit", "lcd-16bit", "lcd-18bit", "lcd-18bit-tft", "lcd-no-pins",
170 static const char *jz4740_nand_groups
[] = {
171 "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
173 static const char *jz4740_pwm0_groups
[] = { "pwm0", };
174 static const char *jz4740_pwm1_groups
[] = { "pwm1", };
175 static const char *jz4740_pwm2_groups
[] = { "pwm2", };
176 static const char *jz4740_pwm3_groups
[] = { "pwm3", };
177 static const char *jz4740_pwm4_groups
[] = { "pwm4", };
178 static const char *jz4740_pwm5_groups
[] = { "pwm5", };
179 static const char *jz4740_pwm6_groups
[] = { "pwm6", };
180 static const char *jz4740_pwm7_groups
[] = { "pwm7", };
182 static const struct function_desc jz4740_functions
[] = {
183 { "mmc", jz4740_mmc_groups
, ARRAY_SIZE(jz4740_mmc_groups
), },
184 { "uart0", jz4740_uart0_groups
, ARRAY_SIZE(jz4740_uart0_groups
), },
185 { "uart1", jz4740_uart1_groups
, ARRAY_SIZE(jz4740_uart1_groups
), },
186 { "lcd", jz4740_lcd_groups
, ARRAY_SIZE(jz4740_lcd_groups
), },
187 { "nand", jz4740_nand_groups
, ARRAY_SIZE(jz4740_nand_groups
), },
188 { "pwm0", jz4740_pwm0_groups
, ARRAY_SIZE(jz4740_pwm0_groups
), },
189 { "pwm1", jz4740_pwm1_groups
, ARRAY_SIZE(jz4740_pwm1_groups
), },
190 { "pwm2", jz4740_pwm2_groups
, ARRAY_SIZE(jz4740_pwm2_groups
), },
191 { "pwm3", jz4740_pwm3_groups
, ARRAY_SIZE(jz4740_pwm3_groups
), },
192 { "pwm4", jz4740_pwm4_groups
, ARRAY_SIZE(jz4740_pwm4_groups
), },
193 { "pwm5", jz4740_pwm5_groups
, ARRAY_SIZE(jz4740_pwm5_groups
), },
194 { "pwm6", jz4740_pwm6_groups
, ARRAY_SIZE(jz4740_pwm6_groups
), },
195 { "pwm7", jz4740_pwm7_groups
, ARRAY_SIZE(jz4740_pwm7_groups
), },
198 static const struct ingenic_chip_info jz4740_chip_info
= {
200 .groups
= jz4740_groups
,
201 .num_groups
= ARRAY_SIZE(jz4740_groups
),
202 .functions
= jz4740_functions
,
203 .num_functions
= ARRAY_SIZE(jz4740_functions
),
204 .pull_ups
= jz4740_pull_ups
,
205 .pull_downs
= jz4740_pull_downs
,
208 static const u32 jz4770_pull_ups
[6] = {
209 0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
212 static const u32 jz4770_pull_downs
[6] = {
213 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0,
216 static int jz4770_uart0_data_pins
[] = { 0xa0, 0xa3, };
217 static int jz4770_uart0_hwflow_pins
[] = { 0xa1, 0xa2, };
218 static int jz4770_uart1_data_pins
[] = { 0x7a, 0x7c, };
219 static int jz4770_uart1_hwflow_pins
[] = { 0x7b, 0x7d, };
220 static int jz4770_uart2_data_pins
[] = { 0x66, 0x67, };
221 static int jz4770_uart2_hwflow_pins
[] = { 0x65, 0x64, };
222 static int jz4770_uart3_data_pins
[] = { 0x6c, 0x85, };
223 static int jz4770_uart3_hwflow_pins
[] = { 0x88, 0x89, };
224 static int jz4770_uart4_data_pins
[] = { 0x54, 0x4a, };
225 static int jz4770_mmc0_8bit_a_pins
[] = { 0x04, 0x05, 0x06, 0x07, 0x18, };
226 static int jz4770_mmc0_4bit_a_pins
[] = { 0x15, 0x16, 0x17, };
227 static int jz4770_mmc0_1bit_a_pins
[] = { 0x12, 0x13, 0x14, };
228 static int jz4770_mmc0_4bit_e_pins
[] = { 0x95, 0x96, 0x97, };
229 static int jz4770_mmc0_1bit_e_pins
[] = { 0x9c, 0x9d, 0x94, };
230 static int jz4770_mmc1_4bit_d_pins
[] = { 0x75, 0x76, 0x77, };
231 static int jz4770_mmc1_1bit_d_pins
[] = { 0x78, 0x79, 0x74, };
232 static int jz4770_mmc1_4bit_e_pins
[] = { 0x95, 0x96, 0x97, };
233 static int jz4770_mmc1_1bit_e_pins
[] = { 0x9c, 0x9d, 0x94, };
234 static int jz4770_nemc_data_pins
[] = {
235 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
237 static int jz4770_nemc_cle_ale_pins
[] = { 0x20, 0x21, };
238 static int jz4770_nemc_addr_pins
[] = { 0x22, 0x23, 0x24, 0x25, };
239 static int jz4770_nemc_rd_we_pins
[] = { 0x10, 0x11, };
240 static int jz4770_nemc_frd_fwe_pins
[] = { 0x12, 0x13, };
241 static int jz4770_nemc_cs1_pins
[] = { 0x15, };
242 static int jz4770_nemc_cs2_pins
[] = { 0x16, };
243 static int jz4770_nemc_cs3_pins
[] = { 0x17, };
244 static int jz4770_nemc_cs4_pins
[] = { 0x18, };
245 static int jz4770_nemc_cs5_pins
[] = { 0x19, };
246 static int jz4770_nemc_cs6_pins
[] = { 0x1a, };
247 static int jz4770_i2c0_pins
[] = { 0x6e, 0x6f, };
248 static int jz4770_i2c1_pins
[] = { 0x8e, 0x8f, };
249 static int jz4770_i2c2_pins
[] = { 0xb0, 0xb1, };
250 static int jz4770_i2c3_pins
[] = { 0x6a, 0x6b, };
251 static int jz4770_i2c4_e_pins
[] = { 0x8c, 0x8d, };
252 static int jz4770_i2c4_f_pins
[] = { 0xb9, 0xb8, };
253 static int jz4770_cim_pins
[] = {
254 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
256 static int jz4770_lcd_32bit_pins
[] = {
257 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
258 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
259 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
262 static int jz4770_pwm_pwm0_pins
[] = { 0x80, };
263 static int jz4770_pwm_pwm1_pins
[] = { 0x81, };
264 static int jz4770_pwm_pwm2_pins
[] = { 0x82, };
265 static int jz4770_pwm_pwm3_pins
[] = { 0x83, };
266 static int jz4770_pwm_pwm4_pins
[] = { 0x84, };
267 static int jz4770_pwm_pwm5_pins
[] = { 0x85, };
268 static int jz4770_pwm_pwm6_pins
[] = { 0x6a, };
269 static int jz4770_pwm_pwm7_pins
[] = { 0x6b, };
271 static int jz4770_uart0_data_funcs
[] = { 0, 0, };
272 static int jz4770_uart0_hwflow_funcs
[] = { 0, 0, };
273 static int jz4770_uart1_data_funcs
[] = { 0, 0, };
274 static int jz4770_uart1_hwflow_funcs
[] = { 0, 0, };
275 static int jz4770_uart2_data_funcs
[] = { 1, 1, };
276 static int jz4770_uart2_hwflow_funcs
[] = { 1, 1, };
277 static int jz4770_uart3_data_funcs
[] = { 0, 1, };
278 static int jz4770_uart3_hwflow_funcs
[] = { 0, 0, };
279 static int jz4770_uart4_data_funcs
[] = { 2, 2, };
280 static int jz4770_mmc0_8bit_a_funcs
[] = { 1, 1, 1, 1, 1, };
281 static int jz4770_mmc0_4bit_a_funcs
[] = { 1, 1, 1, };
282 static int jz4770_mmc0_1bit_a_funcs
[] = { 1, 1, 0, };
283 static int jz4770_mmc0_4bit_e_funcs
[] = { 0, 0, 0, };
284 static int jz4770_mmc0_1bit_e_funcs
[] = { 0, 0, 0, };
285 static int jz4770_mmc1_4bit_d_funcs
[] = { 0, 0, 0, };
286 static int jz4770_mmc1_1bit_d_funcs
[] = { 0, 0, 0, };
287 static int jz4770_mmc1_4bit_e_funcs
[] = { 1, 1, 1, };
288 static int jz4770_mmc1_1bit_e_funcs
[] = { 1, 1, 1, };
289 static int jz4770_nemc_data_funcs
[] = { 0, 0, 0, 0, 0, 0, 0, 0, };
290 static int jz4770_nemc_cle_ale_funcs
[] = { 0, 0, };
291 static int jz4770_nemc_addr_funcs
[] = { 0, 0, 0, 0, };
292 static int jz4770_nemc_rd_we_funcs
[] = { 0, 0, };
293 static int jz4770_nemc_frd_fwe_funcs
[] = { 0, 0, };
294 static int jz4770_nemc_cs1_funcs
[] = { 0, };
295 static int jz4770_nemc_cs2_funcs
[] = { 0, };
296 static int jz4770_nemc_cs3_funcs
[] = { 0, };
297 static int jz4770_nemc_cs4_funcs
[] = { 0, };
298 static int jz4770_nemc_cs5_funcs
[] = { 0, };
299 static int jz4770_nemc_cs6_funcs
[] = { 0, };
300 static int jz4770_i2c0_funcs
[] = { 0, 0, };
301 static int jz4770_i2c1_funcs
[] = { 0, 0, };
302 static int jz4770_i2c2_funcs
[] = { 2, 2, };
303 static int jz4770_i2c3_funcs
[] = { 1, 1, };
304 static int jz4770_i2c4_e_funcs
[] = { 1, 1, };
305 static int jz4770_i2c4_f_funcs
[] = { 1, 1, };
306 static int jz4770_cim_funcs
[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
307 static int jz4770_lcd_32bit_funcs
[] = {
308 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0,
312 static int jz4770_pwm_pwm0_funcs
[] = { 0, };
313 static int jz4770_pwm_pwm1_funcs
[] = { 0, };
314 static int jz4770_pwm_pwm2_funcs
[] = { 0, };
315 static int jz4770_pwm_pwm3_funcs
[] = { 0, };
316 static int jz4770_pwm_pwm4_funcs
[] = { 0, };
317 static int jz4770_pwm_pwm5_funcs
[] = { 0, };
318 static int jz4770_pwm_pwm6_funcs
[] = { 0, };
319 static int jz4770_pwm_pwm7_funcs
[] = { 0, };
321 static const struct group_desc jz4770_groups
[] = {
322 INGENIC_PIN_GROUP("uart0-data", jz4770_uart0_data
),
323 INGENIC_PIN_GROUP("uart0-hwflow", jz4770_uart0_hwflow
),
324 INGENIC_PIN_GROUP("uart1-data", jz4770_uart1_data
),
325 INGENIC_PIN_GROUP("uart1-hwflow", jz4770_uart1_hwflow
),
326 INGENIC_PIN_GROUP("uart2-data", jz4770_uart2_data
),
327 INGENIC_PIN_GROUP("uart2-hwflow", jz4770_uart2_hwflow
),
328 INGENIC_PIN_GROUP("uart3-data", jz4770_uart3_data
),
329 INGENIC_PIN_GROUP("uart3-hwflow", jz4770_uart3_hwflow
),
330 INGENIC_PIN_GROUP("uart4-data", jz4770_uart4_data
),
331 INGENIC_PIN_GROUP("mmc0-8bit-a", jz4770_mmc0_8bit_a
),
332 INGENIC_PIN_GROUP("mmc0-4bit-a", jz4770_mmc0_4bit_a
),
333 INGENIC_PIN_GROUP("mmc0-1bit-a", jz4770_mmc0_1bit_a
),
334 INGENIC_PIN_GROUP("mmc0-4bit-e", jz4770_mmc0_4bit_e
),
335 INGENIC_PIN_GROUP("mmc0-1bit-e", jz4770_mmc0_1bit_e
),
336 INGENIC_PIN_GROUP("mmc1-4bit-d", jz4770_mmc1_4bit_d
),
337 INGENIC_PIN_GROUP("mmc1-1bit-d", jz4770_mmc1_1bit_d
),
338 INGENIC_PIN_GROUP("mmc1-4bit-e", jz4770_mmc1_4bit_e
),
339 INGENIC_PIN_GROUP("mmc1-1bit-e", jz4770_mmc1_1bit_e
),
340 INGENIC_PIN_GROUP("nemc-data", jz4770_nemc_data
),
341 INGENIC_PIN_GROUP("nemc-cle-ale", jz4770_nemc_cle_ale
),
342 INGENIC_PIN_GROUP("nemc-addr", jz4770_nemc_addr
),
343 INGENIC_PIN_GROUP("nemc-rd-we", jz4770_nemc_rd_we
),
344 INGENIC_PIN_GROUP("nemc-frd-fwe", jz4770_nemc_frd_fwe
),
345 INGENIC_PIN_GROUP("nemc-cs1", jz4770_nemc_cs1
),
346 INGENIC_PIN_GROUP("nemc-cs2", jz4770_nemc_cs2
),
347 INGENIC_PIN_GROUP("nemc-cs3", jz4770_nemc_cs3
),
348 INGENIC_PIN_GROUP("nemc-cs4", jz4770_nemc_cs4
),
349 INGENIC_PIN_GROUP("nemc-cs5", jz4770_nemc_cs5
),
350 INGENIC_PIN_GROUP("nemc-cs6", jz4770_nemc_cs6
),
351 INGENIC_PIN_GROUP("i2c0-data", jz4770_i2c0
),
352 INGENIC_PIN_GROUP("i2c1-data", jz4770_i2c1
),
353 INGENIC_PIN_GROUP("i2c2-data", jz4770_i2c2
),
354 INGENIC_PIN_GROUP("i2c3-data", jz4770_i2c3
),
355 INGENIC_PIN_GROUP("i2c4-data-e", jz4770_i2c4_e
),
356 INGENIC_PIN_GROUP("i2c4-data-f", jz4770_i2c4_f
),
357 INGENIC_PIN_GROUP("cim-data", jz4770_cim
),
358 INGENIC_PIN_GROUP("lcd-32bit", jz4770_lcd_32bit
),
360 INGENIC_PIN_GROUP("pwm0", jz4770_pwm_pwm0
),
361 INGENIC_PIN_GROUP("pwm1", jz4770_pwm_pwm1
),
362 INGENIC_PIN_GROUP("pwm2", jz4770_pwm_pwm2
),
363 INGENIC_PIN_GROUP("pwm3", jz4770_pwm_pwm3
),
364 INGENIC_PIN_GROUP("pwm4", jz4770_pwm_pwm4
),
365 INGENIC_PIN_GROUP("pwm5", jz4770_pwm_pwm5
),
366 INGENIC_PIN_GROUP("pwm6", jz4770_pwm_pwm6
),
367 INGENIC_PIN_GROUP("pwm7", jz4770_pwm_pwm7
),
370 static const char *jz4770_uart0_groups
[] = { "uart0-data", "uart0-hwflow", };
371 static const char *jz4770_uart1_groups
[] = { "uart1-data", "uart1-hwflow", };
372 static const char *jz4770_uart2_groups
[] = { "uart2-data", "uart2-hwflow", };
373 static const char *jz4770_uart3_groups
[] = { "uart3-data", "uart3-hwflow", };
374 static const char *jz4770_uart4_groups
[] = { "uart4-data", };
375 static const char *jz4770_mmc0_groups
[] = {
376 "mmc0-8bit-a", "mmc0-4bit-a", "mmc0-1bit-a",
377 "mmc0-1bit-e", "mmc0-4bit-e",
379 static const char *jz4770_mmc1_groups
[] = {
380 "mmc1-1bit-d", "mmc1-4bit-d", "mmc1-1bit-e", "mmc1-4bit-e",
382 static const char *jz4770_nemc_groups
[] = {
383 "nemc-data", "nemc-cle-ale", "nemc-addr", "nemc-rd-we", "nemc-frd-fwe",
385 static const char *jz4770_cs1_groups
[] = { "nemc-cs1", };
386 static const char *jz4770_cs6_groups
[] = { "nemc-cs6", };
387 static const char *jz4770_i2c0_groups
[] = { "i2c0-data", };
388 static const char *jz4770_i2c1_groups
[] = { "i2c1-data", };
389 static const char *jz4770_i2c2_groups
[] = { "i2c2-data", };
390 static const char *jz4770_i2c3_groups
[] = { "i2c3-data", };
391 static const char *jz4770_i2c4_groups
[] = { "i2c4-data-e", "i2c4-data-f", };
392 static const char *jz4770_cim_groups
[] = { "cim-data", };
393 static const char *jz4770_lcd_groups
[] = { "lcd-32bit", "lcd-no-pins", };
394 static const char *jz4770_pwm0_groups
[] = { "pwm0", };
395 static const char *jz4770_pwm1_groups
[] = { "pwm1", };
396 static const char *jz4770_pwm2_groups
[] = { "pwm2", };
397 static const char *jz4770_pwm3_groups
[] = { "pwm3", };
398 static const char *jz4770_pwm4_groups
[] = { "pwm4", };
399 static const char *jz4770_pwm5_groups
[] = { "pwm5", };
400 static const char *jz4770_pwm6_groups
[] = { "pwm6", };
401 static const char *jz4770_pwm7_groups
[] = { "pwm7", };
403 static const struct function_desc jz4770_functions
[] = {
404 { "uart0", jz4770_uart0_groups
, ARRAY_SIZE(jz4770_uart0_groups
), },
405 { "uart1", jz4770_uart1_groups
, ARRAY_SIZE(jz4770_uart1_groups
), },
406 { "uart2", jz4770_uart2_groups
, ARRAY_SIZE(jz4770_uart2_groups
), },
407 { "uart3", jz4770_uart3_groups
, ARRAY_SIZE(jz4770_uart3_groups
), },
408 { "uart4", jz4770_uart4_groups
, ARRAY_SIZE(jz4770_uart4_groups
), },
409 { "mmc0", jz4770_mmc0_groups
, ARRAY_SIZE(jz4770_mmc0_groups
), },
410 { "mmc1", jz4770_mmc1_groups
, ARRAY_SIZE(jz4770_mmc1_groups
), },
411 { "nemc", jz4770_nemc_groups
, ARRAY_SIZE(jz4770_nemc_groups
), },
412 { "nemc-cs1", jz4770_cs1_groups
, ARRAY_SIZE(jz4770_cs1_groups
), },
413 { "nemc-cs6", jz4770_cs6_groups
, ARRAY_SIZE(jz4770_cs6_groups
), },
414 { "i2c0", jz4770_i2c0_groups
, ARRAY_SIZE(jz4770_i2c0_groups
), },
415 { "i2c1", jz4770_i2c1_groups
, ARRAY_SIZE(jz4770_i2c1_groups
), },
416 { "i2c2", jz4770_i2c2_groups
, ARRAY_SIZE(jz4770_i2c2_groups
), },
417 { "i2c3", jz4770_i2c3_groups
, ARRAY_SIZE(jz4770_i2c3_groups
), },
418 { "i2c4", jz4770_i2c4_groups
, ARRAY_SIZE(jz4770_i2c4_groups
), },
419 { "cim", jz4770_cim_groups
, ARRAY_SIZE(jz4770_cim_groups
), },
420 { "lcd", jz4770_lcd_groups
, ARRAY_SIZE(jz4770_lcd_groups
), },
421 { "pwm0", jz4770_pwm0_groups
, ARRAY_SIZE(jz4770_pwm0_groups
), },
422 { "pwm1", jz4770_pwm1_groups
, ARRAY_SIZE(jz4770_pwm1_groups
), },
423 { "pwm2", jz4770_pwm2_groups
, ARRAY_SIZE(jz4770_pwm2_groups
), },
424 { "pwm3", jz4770_pwm3_groups
, ARRAY_SIZE(jz4770_pwm3_groups
), },
425 { "pwm4", jz4770_pwm4_groups
, ARRAY_SIZE(jz4770_pwm4_groups
), },
426 { "pwm5", jz4770_pwm5_groups
, ARRAY_SIZE(jz4770_pwm5_groups
), },
427 { "pwm6", jz4770_pwm6_groups
, ARRAY_SIZE(jz4770_pwm6_groups
), },
428 { "pwm7", jz4770_pwm7_groups
, ARRAY_SIZE(jz4770_pwm7_groups
), },
431 static const struct ingenic_chip_info jz4770_chip_info
= {
433 .groups
= jz4770_groups
,
434 .num_groups
= ARRAY_SIZE(jz4770_groups
),
435 .functions
= jz4770_functions
,
436 .num_functions
= ARRAY_SIZE(jz4770_functions
),
437 .pull_ups
= jz4770_pull_ups
,
438 .pull_downs
= jz4770_pull_downs
,
441 static inline void ingenic_config_pin(struct ingenic_pinctrl
*jzpc
,
442 unsigned int pin
, u8 reg
, bool set
)
444 unsigned int idx
= pin
% PINS_PER_GPIO_CHIP
;
445 unsigned int offt
= pin
/ PINS_PER_GPIO_CHIP
;
447 regmap_write(jzpc
->map
, offt
* 0x100 +
448 (set
? REG_SET(reg
) : REG_CLEAR(reg
)), BIT(idx
));
451 static inline bool ingenic_get_pin_config(struct ingenic_pinctrl
*jzpc
,
452 unsigned int pin
, u8 reg
)
454 unsigned int idx
= pin
% PINS_PER_GPIO_CHIP
;
455 unsigned int offt
= pin
/ PINS_PER_GPIO_CHIP
;
458 regmap_read(jzpc
->map
, offt
* 0x100 + reg
, &val
);
460 return val
& BIT(idx
);
463 static const struct pinctrl_ops ingenic_pctlops
= {
464 .get_groups_count
= pinctrl_generic_get_group_count
,
465 .get_group_name
= pinctrl_generic_get_group_name
,
466 .get_group_pins
= pinctrl_generic_get_group_pins
,
467 .dt_node_to_map
= pinconf_generic_dt_node_to_map_all
,
468 .dt_free_map
= pinconf_generic_dt_free_map
,
471 static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl
*jzpc
,
474 unsigned int idx
= pin
% PINS_PER_GPIO_CHIP
;
475 unsigned int offt
= pin
/ PINS_PER_GPIO_CHIP
;
477 dev_dbg(jzpc
->dev
, "set pin P%c%u to function %u\n",
478 'A' + offt
, idx
, func
);
480 if (jzpc
->version
>= ID_JZ4770
) {
481 ingenic_config_pin(jzpc
, pin
, JZ4770_GPIO_INT
, false);
482 ingenic_config_pin(jzpc
, pin
, JZ4770_GPIO_MSK
, false);
483 ingenic_config_pin(jzpc
, pin
, JZ4770_GPIO_PAT1
, func
& 0x2);
484 ingenic_config_pin(jzpc
, pin
, JZ4770_GPIO_PAT0
, func
& 0x1);
486 ingenic_config_pin(jzpc
, pin
, JZ4740_GPIO_FUNC
, true);
487 ingenic_config_pin(jzpc
, pin
, JZ4740_GPIO_TRIG
, func
& 0x2);
488 ingenic_config_pin(jzpc
, pin
, JZ4740_GPIO_SELECT
, func
> 0);
494 static int ingenic_pinmux_set_mux(struct pinctrl_dev
*pctldev
,
495 unsigned int selector
, unsigned int group
)
497 struct ingenic_pinctrl
*jzpc
= pinctrl_dev_get_drvdata(pctldev
);
498 struct function_desc
*func
;
499 struct group_desc
*grp
;
502 func
= pinmux_generic_get_function(pctldev
, selector
);
506 grp
= pinctrl_generic_get_group(pctldev
, group
);
510 dev_dbg(pctldev
->dev
, "enable function %s group %s\n",
511 func
->name
, grp
->name
);
513 for (i
= 0; i
< grp
->num_pins
; i
++) {
514 int *pin_modes
= grp
->data
;
516 ingenic_pinmux_set_pin_fn(jzpc
, grp
->pins
[i
], pin_modes
[i
]);
522 static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev
*pctldev
,
523 struct pinctrl_gpio_range
*range
,
524 unsigned int pin
, bool input
)
526 struct ingenic_pinctrl
*jzpc
= pinctrl_dev_get_drvdata(pctldev
);
527 unsigned int idx
= pin
% PINS_PER_GPIO_CHIP
;
528 unsigned int offt
= pin
/ PINS_PER_GPIO_CHIP
;
530 dev_dbg(pctldev
->dev
, "set pin P%c%u to %sput\n",
531 'A' + offt
, idx
, input
? "in" : "out");
533 if (jzpc
->version
>= ID_JZ4770
) {
534 ingenic_config_pin(jzpc
, pin
, JZ4770_GPIO_INT
, false);
535 ingenic_config_pin(jzpc
, pin
, JZ4770_GPIO_MSK
, true);
536 ingenic_config_pin(jzpc
, pin
, JZ4770_GPIO_PAT1
, input
);
538 ingenic_config_pin(jzpc
, pin
, JZ4740_GPIO_SELECT
, false);
539 ingenic_config_pin(jzpc
, pin
, JZ4740_GPIO_DIR
, input
);
540 ingenic_config_pin(jzpc
, pin
, JZ4740_GPIO_FUNC
, false);
546 static const struct pinmux_ops ingenic_pmxops
= {
547 .get_functions_count
= pinmux_generic_get_function_count
,
548 .get_function_name
= pinmux_generic_get_function_name
,
549 .get_function_groups
= pinmux_generic_get_function_groups
,
550 .set_mux
= ingenic_pinmux_set_mux
,
551 .gpio_set_direction
= ingenic_pinmux_gpio_set_direction
,
554 static int ingenic_pinconf_get(struct pinctrl_dev
*pctldev
,
555 unsigned int pin
, unsigned long *config
)
557 struct ingenic_pinctrl
*jzpc
= pinctrl_dev_get_drvdata(pctldev
);
558 enum pin_config_param param
= pinconf_to_config_param(*config
);
559 unsigned int idx
= pin
% PINS_PER_GPIO_CHIP
;
560 unsigned int offt
= pin
/ PINS_PER_GPIO_CHIP
;
563 if (jzpc
->version
>= ID_JZ4770
)
564 pull
= !ingenic_get_pin_config(jzpc
, pin
, JZ4770_GPIO_PEN
);
566 pull
= !ingenic_get_pin_config(jzpc
, pin
, JZ4740_GPIO_PULL_DIS
);
569 case PIN_CONFIG_BIAS_DISABLE
:
574 case PIN_CONFIG_BIAS_PULL_UP
:
575 if (!pull
|| !(jzpc
->info
->pull_ups
[offt
] & BIT(idx
)))
579 case PIN_CONFIG_BIAS_PULL_DOWN
:
580 if (!pull
|| !(jzpc
->info
->pull_downs
[offt
] & BIT(idx
)))
588 *config
= pinconf_to_config_packed(param
, 1);
592 static void ingenic_set_bias(struct ingenic_pinctrl
*jzpc
,
593 unsigned int pin
, bool enabled
)
595 if (jzpc
->version
>= ID_JZ4770
)
596 ingenic_config_pin(jzpc
, pin
, JZ4770_GPIO_PEN
, !enabled
);
598 ingenic_config_pin(jzpc
, pin
, JZ4740_GPIO_PULL_DIS
, !enabled
);
601 static int ingenic_pinconf_set(struct pinctrl_dev
*pctldev
, unsigned int pin
,
602 unsigned long *configs
, unsigned int num_configs
)
604 struct ingenic_pinctrl
*jzpc
= pinctrl_dev_get_drvdata(pctldev
);
605 unsigned int idx
= pin
% PINS_PER_GPIO_CHIP
;
606 unsigned int offt
= pin
/ PINS_PER_GPIO_CHIP
;
609 for (cfg
= 0; cfg
< num_configs
; cfg
++) {
610 switch (pinconf_to_config_param(configs
[cfg
])) {
611 case PIN_CONFIG_BIAS_DISABLE
:
612 case PIN_CONFIG_BIAS_PULL_UP
:
613 case PIN_CONFIG_BIAS_PULL_DOWN
:
620 for (cfg
= 0; cfg
< num_configs
; cfg
++) {
621 switch (pinconf_to_config_param(configs
[cfg
])) {
622 case PIN_CONFIG_BIAS_DISABLE
:
623 dev_dbg(jzpc
->dev
, "disable pull-over for pin P%c%u\n",
625 ingenic_set_bias(jzpc
, pin
, false);
628 case PIN_CONFIG_BIAS_PULL_UP
:
629 if (!(jzpc
->info
->pull_ups
[offt
] & BIT(idx
)))
631 dev_dbg(jzpc
->dev
, "set pull-up for pin P%c%u\n",
633 ingenic_set_bias(jzpc
, pin
, true);
636 case PIN_CONFIG_BIAS_PULL_DOWN
:
637 if (!(jzpc
->info
->pull_downs
[offt
] & BIT(idx
)))
639 dev_dbg(jzpc
->dev
, "set pull-down for pin P%c%u\n",
641 ingenic_set_bias(jzpc
, pin
, true);
652 static int ingenic_pinconf_group_get(struct pinctrl_dev
*pctldev
,
653 unsigned int group
, unsigned long *config
)
655 const unsigned int *pins
;
656 unsigned int i
, npins
, old
= 0;
659 ret
= pinctrl_generic_get_group_pins(pctldev
, group
, &pins
, &npins
);
663 for (i
= 0; i
< npins
; i
++) {
664 if (ingenic_pinconf_get(pctldev
, pins
[i
], config
))
667 /* configs do not match between two pins */
668 if (i
&& (old
!= *config
))
677 static int ingenic_pinconf_group_set(struct pinctrl_dev
*pctldev
,
678 unsigned int group
, unsigned long *configs
,
679 unsigned int num_configs
)
681 const unsigned int *pins
;
682 unsigned int i
, npins
;
685 ret
= pinctrl_generic_get_group_pins(pctldev
, group
, &pins
, &npins
);
689 for (i
= 0; i
< npins
; i
++) {
690 ret
= ingenic_pinconf_set(pctldev
,
691 pins
[i
], configs
, num_configs
);
699 static const struct pinconf_ops ingenic_confops
= {
701 .pin_config_get
= ingenic_pinconf_get
,
702 .pin_config_set
= ingenic_pinconf_set
,
703 .pin_config_group_get
= ingenic_pinconf_group_get
,
704 .pin_config_group_set
= ingenic_pinconf_group_set
,
707 static const struct regmap_config ingenic_pinctrl_regmap_config
= {
713 static const struct of_device_id ingenic_pinctrl_of_match
[] = {
714 { .compatible
= "ingenic,jz4740-pinctrl", .data
= (void *) ID_JZ4740
},
715 { .compatible
= "ingenic,jz4770-pinctrl", .data
= (void *) ID_JZ4770
},
716 { .compatible
= "ingenic,jz4780-pinctrl", .data
= (void *) ID_JZ4780
},
720 static int ingenic_pinctrl_probe(struct platform_device
*pdev
)
722 struct device
*dev
= &pdev
->dev
;
723 struct ingenic_pinctrl
*jzpc
;
724 struct pinctrl_desc
*pctl_desc
;
726 const struct platform_device_id
*id
= platform_get_device_id(pdev
);
727 const struct of_device_id
*of_id
= of_match_device(
728 ingenic_pinctrl_of_match
, dev
);
729 const struct ingenic_chip_info
*chip_info
;
733 jzpc
= devm_kzalloc(dev
, sizeof(*jzpc
), GFP_KERNEL
);
737 base
= devm_ioremap_resource(dev
,
738 platform_get_resource(pdev
, IORESOURCE_MEM
, 0));
740 return PTR_ERR(base
);
742 jzpc
->map
= devm_regmap_init_mmio(dev
, base
,
743 &ingenic_pinctrl_regmap_config
);
744 if (IS_ERR(jzpc
->map
)) {
745 dev_err(dev
, "Failed to create regmap\n");
746 return PTR_ERR(jzpc
->map
);
752 jzpc
->version
= (enum jz_version
)of_id
->data
;
754 jzpc
->version
= (enum jz_version
)id
->driver_data
;
756 if (jzpc
->version
>= ID_JZ4770
)
757 chip_info
= &jz4770_chip_info
;
759 chip_info
= &jz4740_chip_info
;
760 jzpc
->info
= chip_info
;
762 pctl_desc
= devm_kzalloc(&pdev
->dev
, sizeof(*pctl_desc
), GFP_KERNEL
);
766 /* fill in pinctrl_desc structure */
767 pctl_desc
->name
= dev_name(dev
);
768 pctl_desc
->owner
= THIS_MODULE
;
769 pctl_desc
->pctlops
= &ingenic_pctlops
;
770 pctl_desc
->pmxops
= &ingenic_pmxops
;
771 pctl_desc
->confops
= &ingenic_confops
;
772 pctl_desc
->npins
= chip_info
->num_chips
* PINS_PER_GPIO_CHIP
;
773 pctl_desc
->pins
= jzpc
->pdesc
= devm_kzalloc(&pdev
->dev
,
774 sizeof(*jzpc
->pdesc
) * pctl_desc
->npins
, GFP_KERNEL
);
778 for (i
= 0; i
< pctl_desc
->npins
; i
++) {
779 jzpc
->pdesc
[i
].number
= i
;
780 jzpc
->pdesc
[i
].name
= kasprintf(GFP_KERNEL
, "P%c%d",
781 'A' + (i
/ PINS_PER_GPIO_CHIP
),
782 i
% PINS_PER_GPIO_CHIP
);
785 jzpc
->pctl
= devm_pinctrl_register(dev
, pctl_desc
, jzpc
);
786 if (IS_ERR(jzpc
->pctl
)) {
787 dev_err(dev
, "Failed to register pinctrl\n");
788 return PTR_ERR(jzpc
->pctl
);
791 for (i
= 0; i
< chip_info
->num_groups
; i
++) {
792 const struct group_desc
*group
= &chip_info
->groups
[i
];
794 err
= pinctrl_generic_add_group(jzpc
->pctl
, group
->name
,
795 group
->pins
, group
->num_pins
, group
->data
);
797 dev_err(dev
, "Failed to register group %s\n",
803 for (i
= 0; i
< chip_info
->num_functions
; i
++) {
804 const struct function_desc
*func
= &chip_info
->functions
[i
];
806 err
= pinmux_generic_add_function(jzpc
->pctl
, func
->name
,
807 func
->group_names
, func
->num_group_names
,
810 dev_err(dev
, "Failed to register function %s\n",
816 dev_set_drvdata(dev
, jzpc
->map
);
819 err
= of_platform_populate(dev
->of_node
, NULL
, NULL
, dev
);
821 dev_err(dev
, "Failed to probe GPIO devices\n");
829 static const struct platform_device_id ingenic_pinctrl_ids
[] = {
830 { "jz4740-pinctrl", ID_JZ4740
},
831 { "jz4770-pinctrl", ID_JZ4770
},
832 { "jz4780-pinctrl", ID_JZ4780
},
836 static struct platform_driver ingenic_pinctrl_driver
= {
838 .name
= "pinctrl-ingenic",
839 .of_match_table
= of_match_ptr(ingenic_pinctrl_of_match
),
840 .suppress_bind_attrs
= true,
842 .probe
= ingenic_pinctrl_probe
,
843 .id_table
= ingenic_pinctrl_ids
,
846 static int __init
ingenic_pinctrl_drv_register(void)
848 return platform_driver_register(&ingenic_pinctrl_driver
);
850 postcore_initcall(ingenic_pinctrl_drv_register
);