]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - rpmsg/rpmsg.git/blob - drivers/pinctrl/pinctrl-ingenic.c
Merge tag 'kbuild-fixes-v4.19-2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[rpmsg/rpmsg.git] / drivers / pinctrl / pinctrl-ingenic.c
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  */
9 #include <linux/compiler.h>
10 #include <linux/gpio.h>
11 #include <linux/interrupt.h>
12 #include <linux/io.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>
23 #include "core.h"
24 #include "pinconf.h"
25 #include "pinmux.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
47 enum jz_version {
48         ID_JZ4740,
49         ID_JZ4770,
50         ID_JZ4780,
51 };
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;
63 };
65 struct ingenic_pinctrl {
66         struct device *dev;
67         struct regmap *map;
68         struct pinctrl_dev *pctl;
69         struct pinctrl_pin_desc *pdesc;
70         enum jz_version version;
72         const struct ingenic_chip_info *info;
73 };
75 static const u32 jz4740_pull_ups[4] = {
76         0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
77 };
79 static const u32 jz4740_pull_downs[4] = {
80         0x00000000, 0x00000000, 0x00000000, 0x00000000,
81 };
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,
90 };
91 static int jz4740_lcd_16bit_pins[] = {
92         0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x55,
93 };
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)                     \
132         {                                               \
133                 name,                                   \
134                 id##_pins,                              \
135                 ARRAY_SIZE(id##_pins),                  \
136                 id##_funcs,                             \
137         }
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),
149         { "lcd-no-pins", },
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),
162 };
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",
169 };
170 static const char *jz4740_nand_groups[] = {
171         "nand-cs1", "nand-cs2", "nand-cs3", "nand-cs4",
172 };
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), },
196 };
198 static const struct ingenic_chip_info jz4740_chip_info = {
199         .num_chips = 4,
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,
206 };
208 static const u32 jz4770_pull_ups[6] = {
209         0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f,
210 };
212 static const u32 jz4770_pull_downs[6] = {
213         0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0,
214 };
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,
236 };
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,
255 };
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,
260         0x58, 0x59, 0x51,
261 };
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,
310         0, 0, 0,
311 };
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),
359         { "lcd-no-pins", },
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),
368 };
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",
378 };
379 static const char *jz4770_mmc1_groups[] = {
380         "mmc1-1bit-d", "mmc1-4bit-d", "mmc1-1bit-e", "mmc1-4bit-e",
381 };
382 static const char *jz4770_nemc_groups[] = {
383         "nemc-data", "nemc-cle-ale", "nemc-addr", "nemc-rd-we", "nemc-frd-fwe",
384 };
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), },
429 };
431 static const struct ingenic_chip_info jz4770_chip_info = {
432         .num_chips = 6,
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,
439 };
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;
456         unsigned int val;
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,
469 };
471 static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
472                 int pin, int func)
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);
485         } else {
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);
489         }
491         return 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;
500         unsigned int i;
502         func = pinmux_generic_get_function(pctldev, selector);
503         if (!func)
504                 return -EINVAL;
506         grp = pinctrl_generic_get_group(pctldev, group);
507         if (!grp)
508                 return -EINVAL;
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]);
517         }
519         return 0;
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);
537         } else {
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);
541         }
543         return 0;
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,
552 };
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;
561         bool pull;
563         if (jzpc->version >= ID_JZ4770)
564                 pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
565         else
566                 pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
568         switch (param) {
569         case PIN_CONFIG_BIAS_DISABLE:
570                 if (pull)
571                         return -EINVAL;
572                 break;
574         case PIN_CONFIG_BIAS_PULL_UP:
575                 if (!pull || !(jzpc->info->pull_ups[offt] & BIT(idx)))
576                         return -EINVAL;
577                 break;
579         case PIN_CONFIG_BIAS_PULL_DOWN:
580                 if (!pull || !(jzpc->info->pull_downs[offt] & BIT(idx)))
581                         return -EINVAL;
582                 break;
584         default:
585                 return -ENOTSUPP;
586         }
588         *config = pinconf_to_config_packed(param, 1);
589         return 0;
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);
597         else
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;
607         unsigned int cfg;
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:
614                         continue;
615                 default:
616                         return -ENOTSUPP;
617                 }
618         }
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",
624                                         'A' + offt, idx);
625                         ingenic_set_bias(jzpc, pin, false);
626                         break;
628                 case PIN_CONFIG_BIAS_PULL_UP:
629                         if (!(jzpc->info->pull_ups[offt] & BIT(idx)))
630                                 return -EINVAL;
631                         dev_dbg(jzpc->dev, "set pull-up for pin P%c%u\n",
632                                         'A' + offt, idx);
633                         ingenic_set_bias(jzpc, pin, true);
634                         break;
636                 case PIN_CONFIG_BIAS_PULL_DOWN:
637                         if (!(jzpc->info->pull_downs[offt] & BIT(idx)))
638                                 return -EINVAL;
639                         dev_dbg(jzpc->dev, "set pull-down for pin P%c%u\n",
640                                         'A' + offt, idx);
641                         ingenic_set_bias(jzpc, pin, true);
642                         break;
644                 default:
645                         unreachable();
646                 }
647         }
649         return 0;
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;
657         int ret;
659         ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
660         if (ret)
661                 return ret;
663         for (i = 0; i < npins; i++) {
664                 if (ingenic_pinconf_get(pctldev, pins[i], config))
665                         return -ENOTSUPP;
667                 /* configs do not match between two pins */
668                 if (i && (old != *config))
669                         return -ENOTSUPP;
671                 old = *config;
672         }
674         return 0;
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;
683         int ret;
685         ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins);
686         if (ret)
687                 return ret;
689         for (i = 0; i < npins; i++) {
690                 ret = ingenic_pinconf_set(pctldev,
691                                 pins[i], configs, num_configs);
692                 if (ret)
693                         return ret;
694         }
696         return 0;
699 static const struct pinconf_ops ingenic_confops = {
700         .is_generic = true,
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,
705 };
707 static const struct regmap_config ingenic_pinctrl_regmap_config = {
708         .reg_bits = 32,
709         .val_bits = 32,
710         .reg_stride = 4,
711 };
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 },
717         {},
718 };
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;
725         void __iomem *base;
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;
730         unsigned int i;
731         int err;
733         jzpc = devm_kzalloc(dev, sizeof(*jzpc), GFP_KERNEL);
734         if (!jzpc)
735                 return -ENOMEM;
737         base = devm_ioremap_resource(dev,
738                         platform_get_resource(pdev, IORESOURCE_MEM, 0));
739         if (IS_ERR(base))
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);
747         }
749         jzpc->dev = dev;
751         if (of_id)
752                 jzpc->version = (enum jz_version)of_id->data;
753         else
754                 jzpc->version = (enum jz_version)id->driver_data;
756         if (jzpc->version >= ID_JZ4770)
757                 chip_info = &jz4770_chip_info;
758         else
759                 chip_info = &jz4740_chip_info;
760         jzpc->info = chip_info;
762         pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
763         if (!pctl_desc)
764                 return -ENOMEM;
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_kcalloc(&pdev->dev,
774                         pctl_desc->npins, sizeof(*jzpc->pdesc), GFP_KERNEL);
775         if (!jzpc->pdesc)
776                 return -ENOMEM;
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);
783         }
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);
789         }
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);
796                 if (err < 0) {
797                         dev_err(dev, "Failed to register group %s\n",
798                                         group->name);
799                         return err;
800                 }
801         }
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,
808                                 func->data);
809                 if (err < 0) {
810                         dev_err(dev, "Failed to register function %s\n",
811                                         func->name);
812                         return err;
813                 }
814         }
816         dev_set_drvdata(dev, jzpc->map);
818         if (dev->of_node) {
819                 err = of_platform_populate(dev->of_node, NULL, NULL, dev);
820                 if (err) {
821                         dev_err(dev, "Failed to probe GPIO devices\n");
822                         return err;
823                 }
824         }
826         return 0;
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 },
833         {},
834 };
836 static struct platform_driver ingenic_pinctrl_driver = {
837         .driver = {
838                 .name = "pinctrl-ingenic",
839                 .of_match_table = of_match_ptr(ingenic_pinctrl_of_match),
840                 .suppress_bind_attrs = true,
841         },
842         .probe = ingenic_pinctrl_probe,
843         .id_table = ingenic_pinctrl_ids,
844 };
846 static int __init ingenic_pinctrl_drv_register(void)
848         return platform_driver_register(&ingenic_pinctrl_driver);
850 postcore_initcall(ingenic_pinctrl_drv_register);