14cb8df37SCharles Keepax // SPDX-License-Identifier: GPL-2.0-only
2218d72a7SRichard Fitzgerald /*
3218d72a7SRichard Fitzgerald * Pinctrl for Cirrus Logic Madera codecs
4218d72a7SRichard Fitzgerald *
5218d72a7SRichard Fitzgerald * Copyright (C) 2016-2018 Cirrus Logic
6218d72a7SRichard Fitzgerald */
7218d72a7SRichard Fitzgerald
8218d72a7SRichard Fitzgerald #include <linux/err.h>
9218d72a7SRichard Fitzgerald #include <linux/module.h>
10218d72a7SRichard Fitzgerald #include <linux/platform_device.h>
11ce852837SAndy Shevchenko #include <linux/property.h>
12218d72a7SRichard Fitzgerald #include <linux/regmap.h>
13*65f9d858SAndy Shevchenko #include <linux/seq_file.h>
14218d72a7SRichard Fitzgerald #include <linux/slab.h>
15ce852837SAndy Shevchenko
1687eff9afSVladimir Zapolskiy #include <linux/pinctrl/machine.h>
17*65f9d858SAndy Shevchenko #include <linux/pinctrl/pinconf-generic.h>
18*65f9d858SAndy Shevchenko #include <linux/pinctrl/pinconf.h>
19218d72a7SRichard Fitzgerald #include <linux/pinctrl/pinctrl.h>
20218d72a7SRichard Fitzgerald #include <linux/pinctrl/pinmux.h>
21218d72a7SRichard Fitzgerald
22218d72a7SRichard Fitzgerald #include <linux/mfd/madera/core.h>
23218d72a7SRichard Fitzgerald #include <linux/mfd/madera/registers.h>
24218d72a7SRichard Fitzgerald
25218d72a7SRichard Fitzgerald #include "../pinctrl-utils.h"
26218d72a7SRichard Fitzgerald
27218d72a7SRichard Fitzgerald #include "pinctrl-madera.h"
28218d72a7SRichard Fitzgerald
29218d72a7SRichard Fitzgerald /*
30218d72a7SRichard Fitzgerald * Use pin GPIO names for consistency
31218d72a7SRichard Fitzgerald * NOTE: IDs are zero-indexed for coding convenience
32218d72a7SRichard Fitzgerald */
33218d72a7SRichard Fitzgerald static const struct pinctrl_pin_desc madera_pins[] = {
34218d72a7SRichard Fitzgerald PINCTRL_PIN(0, "gpio1"),
35218d72a7SRichard Fitzgerald PINCTRL_PIN(1, "gpio2"),
36218d72a7SRichard Fitzgerald PINCTRL_PIN(2, "gpio3"),
37218d72a7SRichard Fitzgerald PINCTRL_PIN(3, "gpio4"),
38218d72a7SRichard Fitzgerald PINCTRL_PIN(4, "gpio5"),
39218d72a7SRichard Fitzgerald PINCTRL_PIN(5, "gpio6"),
40218d72a7SRichard Fitzgerald PINCTRL_PIN(6, "gpio7"),
41218d72a7SRichard Fitzgerald PINCTRL_PIN(7, "gpio8"),
42218d72a7SRichard Fitzgerald PINCTRL_PIN(8, "gpio9"),
43218d72a7SRichard Fitzgerald PINCTRL_PIN(9, "gpio10"),
44218d72a7SRichard Fitzgerald PINCTRL_PIN(10, "gpio11"),
45218d72a7SRichard Fitzgerald PINCTRL_PIN(11, "gpio12"),
46218d72a7SRichard Fitzgerald PINCTRL_PIN(12, "gpio13"),
47218d72a7SRichard Fitzgerald PINCTRL_PIN(13, "gpio14"),
48218d72a7SRichard Fitzgerald PINCTRL_PIN(14, "gpio15"),
49218d72a7SRichard Fitzgerald PINCTRL_PIN(15, "gpio16"),
50218d72a7SRichard Fitzgerald PINCTRL_PIN(16, "gpio17"),
51218d72a7SRichard Fitzgerald PINCTRL_PIN(17, "gpio18"),
52218d72a7SRichard Fitzgerald PINCTRL_PIN(18, "gpio19"),
53218d72a7SRichard Fitzgerald PINCTRL_PIN(19, "gpio20"),
54218d72a7SRichard Fitzgerald PINCTRL_PIN(20, "gpio21"),
55218d72a7SRichard Fitzgerald PINCTRL_PIN(21, "gpio22"),
56218d72a7SRichard Fitzgerald PINCTRL_PIN(22, "gpio23"),
57218d72a7SRichard Fitzgerald PINCTRL_PIN(23, "gpio24"),
58218d72a7SRichard Fitzgerald PINCTRL_PIN(24, "gpio25"),
59218d72a7SRichard Fitzgerald PINCTRL_PIN(25, "gpio26"),
60218d72a7SRichard Fitzgerald PINCTRL_PIN(26, "gpio27"),
61218d72a7SRichard Fitzgerald PINCTRL_PIN(27, "gpio28"),
62218d72a7SRichard Fitzgerald PINCTRL_PIN(28, "gpio29"),
63218d72a7SRichard Fitzgerald PINCTRL_PIN(29, "gpio30"),
64218d72a7SRichard Fitzgerald PINCTRL_PIN(30, "gpio31"),
65218d72a7SRichard Fitzgerald PINCTRL_PIN(31, "gpio32"),
66218d72a7SRichard Fitzgerald PINCTRL_PIN(32, "gpio33"),
67218d72a7SRichard Fitzgerald PINCTRL_PIN(33, "gpio34"),
68218d72a7SRichard Fitzgerald PINCTRL_PIN(34, "gpio35"),
69218d72a7SRichard Fitzgerald PINCTRL_PIN(35, "gpio36"),
70218d72a7SRichard Fitzgerald PINCTRL_PIN(36, "gpio37"),
71218d72a7SRichard Fitzgerald PINCTRL_PIN(37, "gpio38"),
72218d72a7SRichard Fitzgerald PINCTRL_PIN(38, "gpio39"),
73218d72a7SRichard Fitzgerald PINCTRL_PIN(39, "gpio40"),
74218d72a7SRichard Fitzgerald };
75218d72a7SRichard Fitzgerald
76218d72a7SRichard Fitzgerald /*
77218d72a7SRichard Fitzgerald * All single-pin functions can be mapped to any GPIO, however pinmux applies
78218d72a7SRichard Fitzgerald * functions to pin groups and only those groups declared as supporting that
79218d72a7SRichard Fitzgerald * function. To make this work we must put each pin in its own dummy group so
80218d72a7SRichard Fitzgerald * that the functions can be described as applying to all pins.
81218d72a7SRichard Fitzgerald * Since these do not correspond to anything in the actual hardware - they are
82218d72a7SRichard Fitzgerald * merely an adaptation to pinctrl's view of the world - we use the same name
83218d72a7SRichard Fitzgerald * as the pin to avoid confusion when comparing with datasheet instructions
84218d72a7SRichard Fitzgerald */
85218d72a7SRichard Fitzgerald static const char * const madera_pin_single_group_names[] = {
86218d72a7SRichard Fitzgerald "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
87218d72a7SRichard Fitzgerald "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
88218d72a7SRichard Fitzgerald "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
89218d72a7SRichard Fitzgerald "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
90218d72a7SRichard Fitzgerald "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
91218d72a7SRichard Fitzgerald "gpio36", "gpio37", "gpio38", "gpio39", "gpio40",
92218d72a7SRichard Fitzgerald };
93218d72a7SRichard Fitzgerald
94218d72a7SRichard Fitzgerald /* set of pin numbers for single-pin groups, zero-indexed */
95218d72a7SRichard Fitzgerald static const unsigned int madera_pin_single_group_pins[] = {
96218d72a7SRichard Fitzgerald 0, 1, 2, 3, 4, 5, 6,
97218d72a7SRichard Fitzgerald 7, 8, 9, 10, 11, 12, 13,
98218d72a7SRichard Fitzgerald 14, 15, 16, 17, 18, 19, 20,
99218d72a7SRichard Fitzgerald 21, 22, 23, 24, 25, 26, 27,
100218d72a7SRichard Fitzgerald 28, 29, 30, 31, 32, 33, 34,
101218d72a7SRichard Fitzgerald 35, 36, 37, 38, 39,
102218d72a7SRichard Fitzgerald };
103218d72a7SRichard Fitzgerald
104218d72a7SRichard Fitzgerald static const char * const madera_aif1_group_names[] = { "aif1" };
105218d72a7SRichard Fitzgerald static const char * const madera_aif2_group_names[] = { "aif2" };
106218d72a7SRichard Fitzgerald static const char * const madera_aif3_group_names[] = { "aif3" };
107218d72a7SRichard Fitzgerald static const char * const madera_aif4_group_names[] = { "aif4" };
108218d72a7SRichard Fitzgerald static const char * const madera_mif1_group_names[] = { "mif1" };
109218d72a7SRichard Fitzgerald static const char * const madera_mif2_group_names[] = { "mif2" };
110218d72a7SRichard Fitzgerald static const char * const madera_mif3_group_names[] = { "mif3" };
111218d72a7SRichard Fitzgerald static const char * const madera_dmic3_group_names[] = { "dmic3" };
112218d72a7SRichard Fitzgerald static const char * const madera_dmic4_group_names[] = { "dmic4" };
113218d72a7SRichard Fitzgerald static const char * const madera_dmic5_group_names[] = { "dmic5" };
114218d72a7SRichard Fitzgerald static const char * const madera_dmic6_group_names[] = { "dmic6" };
115218d72a7SRichard Fitzgerald static const char * const madera_spk1_group_names[] = { "pdmspk1" };
116218d72a7SRichard Fitzgerald static const char * const madera_spk2_group_names[] = { "pdmspk2" };
117218d72a7SRichard Fitzgerald
118218d72a7SRichard Fitzgerald /*
119218d72a7SRichard Fitzgerald * alt-functions always apply to a single pin group, other functions always
120218d72a7SRichard Fitzgerald * apply to all pins
121218d72a7SRichard Fitzgerald */
122218d72a7SRichard Fitzgerald static const struct {
123218d72a7SRichard Fitzgerald const char *name;
124218d72a7SRichard Fitzgerald const char * const *group_names;
125218d72a7SRichard Fitzgerald u32 func;
126218d72a7SRichard Fitzgerald } madera_mux_funcs[] = {
127218d72a7SRichard Fitzgerald {
128218d72a7SRichard Fitzgerald .name = "aif1",
129218d72a7SRichard Fitzgerald .group_names = madera_aif1_group_names,
130218d72a7SRichard Fitzgerald .func = 0x000
131218d72a7SRichard Fitzgerald },
132218d72a7SRichard Fitzgerald {
133218d72a7SRichard Fitzgerald .name = "aif2",
134218d72a7SRichard Fitzgerald .group_names = madera_aif2_group_names,
135218d72a7SRichard Fitzgerald .func = 0x000
136218d72a7SRichard Fitzgerald },
137218d72a7SRichard Fitzgerald {
138218d72a7SRichard Fitzgerald .name = "aif3",
139218d72a7SRichard Fitzgerald .group_names = madera_aif3_group_names,
140218d72a7SRichard Fitzgerald .func = 0x000
141218d72a7SRichard Fitzgerald },
142218d72a7SRichard Fitzgerald {
143218d72a7SRichard Fitzgerald .name = "aif4",
144218d72a7SRichard Fitzgerald .group_names = madera_aif4_group_names,
145218d72a7SRichard Fitzgerald .func = 0x000
146218d72a7SRichard Fitzgerald },
147218d72a7SRichard Fitzgerald {
148218d72a7SRichard Fitzgerald .name = "mif1",
149218d72a7SRichard Fitzgerald .group_names = madera_mif1_group_names,
150218d72a7SRichard Fitzgerald .func = 0x000
151218d72a7SRichard Fitzgerald },
152218d72a7SRichard Fitzgerald {
153218d72a7SRichard Fitzgerald .name = "mif2",
154218d72a7SRichard Fitzgerald .group_names = madera_mif2_group_names,
155218d72a7SRichard Fitzgerald .func = 0x000
156218d72a7SRichard Fitzgerald },
157218d72a7SRichard Fitzgerald {
158218d72a7SRichard Fitzgerald .name = "mif3",
159218d72a7SRichard Fitzgerald .group_names = madera_mif3_group_names,
160218d72a7SRichard Fitzgerald .func = 0x000
161218d72a7SRichard Fitzgerald },
162218d72a7SRichard Fitzgerald {
163218d72a7SRichard Fitzgerald .name = "dmic3",
164218d72a7SRichard Fitzgerald .group_names = madera_dmic3_group_names,
165218d72a7SRichard Fitzgerald .func = 0x000
166218d72a7SRichard Fitzgerald },
167218d72a7SRichard Fitzgerald {
168218d72a7SRichard Fitzgerald .name = "dmic4",
169218d72a7SRichard Fitzgerald .group_names = madera_dmic4_group_names,
170218d72a7SRichard Fitzgerald .func = 0x000
171218d72a7SRichard Fitzgerald },
172218d72a7SRichard Fitzgerald {
173218d72a7SRichard Fitzgerald .name = "dmic5",
174218d72a7SRichard Fitzgerald .group_names = madera_dmic5_group_names,
175218d72a7SRichard Fitzgerald .func = 0x000
176218d72a7SRichard Fitzgerald },
177218d72a7SRichard Fitzgerald {
178218d72a7SRichard Fitzgerald .name = "dmic6",
179218d72a7SRichard Fitzgerald .group_names = madera_dmic6_group_names,
180218d72a7SRichard Fitzgerald .func = 0x000
181218d72a7SRichard Fitzgerald },
182218d72a7SRichard Fitzgerald {
183218d72a7SRichard Fitzgerald .name = "pdmspk1",
184218d72a7SRichard Fitzgerald .group_names = madera_spk1_group_names,
185218d72a7SRichard Fitzgerald .func = 0x000
186218d72a7SRichard Fitzgerald },
187218d72a7SRichard Fitzgerald {
188218d72a7SRichard Fitzgerald .name = "pdmspk2",
189218d72a7SRichard Fitzgerald .group_names = madera_spk2_group_names,
190218d72a7SRichard Fitzgerald .func = 0x000
191218d72a7SRichard Fitzgerald },
192218d72a7SRichard Fitzgerald {
193218d72a7SRichard Fitzgerald .name = "io",
194218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
195218d72a7SRichard Fitzgerald .func = 0x001
196218d72a7SRichard Fitzgerald },
197218d72a7SRichard Fitzgerald {
198218d72a7SRichard Fitzgerald .name = "dsp-gpio",
199218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
200218d72a7SRichard Fitzgerald .func = 0x002
201218d72a7SRichard Fitzgerald },
202218d72a7SRichard Fitzgerald {
203218d72a7SRichard Fitzgerald .name = "irq1",
204218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
205218d72a7SRichard Fitzgerald .func = 0x003
206218d72a7SRichard Fitzgerald },
207218d72a7SRichard Fitzgerald {
208218d72a7SRichard Fitzgerald .name = "irq2",
209218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
210218d72a7SRichard Fitzgerald .func = 0x004
211218d72a7SRichard Fitzgerald },
212218d72a7SRichard Fitzgerald {
213218d72a7SRichard Fitzgerald .name = "fll1-clk",
214218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
215218d72a7SRichard Fitzgerald .func = 0x010
216218d72a7SRichard Fitzgerald },
217218d72a7SRichard Fitzgerald {
218218d72a7SRichard Fitzgerald .name = "fll2-clk",
219218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
220218d72a7SRichard Fitzgerald .func = 0x011
221218d72a7SRichard Fitzgerald },
222218d72a7SRichard Fitzgerald {
223218d72a7SRichard Fitzgerald .name = "fll3-clk",
224218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
225218d72a7SRichard Fitzgerald .func = 0x012
226218d72a7SRichard Fitzgerald },
227218d72a7SRichard Fitzgerald {
228218d72a7SRichard Fitzgerald .name = "fllao-clk",
229218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
230218d72a7SRichard Fitzgerald .func = 0x013
231218d72a7SRichard Fitzgerald },
232218d72a7SRichard Fitzgerald {
233218d72a7SRichard Fitzgerald .name = "fll1-lock",
234218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
235218d72a7SRichard Fitzgerald .func = 0x018
236218d72a7SRichard Fitzgerald },
237218d72a7SRichard Fitzgerald {
238218d72a7SRichard Fitzgerald .name = "fll2-lock",
239218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
240218d72a7SRichard Fitzgerald .func = 0x019
241218d72a7SRichard Fitzgerald },
242218d72a7SRichard Fitzgerald {
243218d72a7SRichard Fitzgerald .name = "fll3-lock",
244218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
245218d72a7SRichard Fitzgerald .func = 0x01a
246218d72a7SRichard Fitzgerald },
247218d72a7SRichard Fitzgerald {
248218d72a7SRichard Fitzgerald .name = "fllao-lock",
249218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
250218d72a7SRichard Fitzgerald .func = 0x01b
251218d72a7SRichard Fitzgerald },
252218d72a7SRichard Fitzgerald {
253218d72a7SRichard Fitzgerald .name = "opclk",
254218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
255218d72a7SRichard Fitzgerald .func = 0x040
256218d72a7SRichard Fitzgerald },
257218d72a7SRichard Fitzgerald {
258218d72a7SRichard Fitzgerald .name = "opclk-async",
259218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
260218d72a7SRichard Fitzgerald .func = 0x041
261218d72a7SRichard Fitzgerald },
262218d72a7SRichard Fitzgerald {
263218d72a7SRichard Fitzgerald .name = "pwm1",
264218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
265218d72a7SRichard Fitzgerald .func = 0x048
266218d72a7SRichard Fitzgerald },
267218d72a7SRichard Fitzgerald {
268218d72a7SRichard Fitzgerald .name = "pwm2",
269218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
270218d72a7SRichard Fitzgerald .func = 0x049
271218d72a7SRichard Fitzgerald },
272218d72a7SRichard Fitzgerald {
273218d72a7SRichard Fitzgerald .name = "spdif",
274218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
275218d72a7SRichard Fitzgerald .func = 0x04c
276218d72a7SRichard Fitzgerald },
277218d72a7SRichard Fitzgerald {
278218d72a7SRichard Fitzgerald .name = "asrc1-in1-lock",
279218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
280218d72a7SRichard Fitzgerald .func = 0x088
281218d72a7SRichard Fitzgerald },
282218d72a7SRichard Fitzgerald {
283218d72a7SRichard Fitzgerald .name = "asrc1-in2-lock",
284218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
285218d72a7SRichard Fitzgerald .func = 0x089
286218d72a7SRichard Fitzgerald },
287218d72a7SRichard Fitzgerald {
288218d72a7SRichard Fitzgerald .name = "asrc2-in1-lock",
289218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
290218d72a7SRichard Fitzgerald .func = 0x08a
291218d72a7SRichard Fitzgerald },
292218d72a7SRichard Fitzgerald {
293218d72a7SRichard Fitzgerald .name = "asrc2-in2-lock",
294218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
295218d72a7SRichard Fitzgerald .func = 0x08b
296218d72a7SRichard Fitzgerald },
297218d72a7SRichard Fitzgerald {
298218d72a7SRichard Fitzgerald .name = "spkl-short-circuit",
299218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
300218d72a7SRichard Fitzgerald .func = 0x0b6
301218d72a7SRichard Fitzgerald },
302218d72a7SRichard Fitzgerald {
303218d72a7SRichard Fitzgerald .name = "spkr-short-circuit",
304218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
305218d72a7SRichard Fitzgerald .func = 0x0b7
306218d72a7SRichard Fitzgerald },
307218d72a7SRichard Fitzgerald {
308218d72a7SRichard Fitzgerald .name = "spk-shutdown",
309218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
310218d72a7SRichard Fitzgerald .func = 0x0e0
311218d72a7SRichard Fitzgerald },
312218d72a7SRichard Fitzgerald {
313218d72a7SRichard Fitzgerald .name = "spk-overheat-shutdown",
314218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
315218d72a7SRichard Fitzgerald .func = 0x0e1
316218d72a7SRichard Fitzgerald },
317218d72a7SRichard Fitzgerald {
318218d72a7SRichard Fitzgerald .name = "spk-overheat-warn",
319218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
320218d72a7SRichard Fitzgerald .func = 0x0e2
321218d72a7SRichard Fitzgerald },
322218d72a7SRichard Fitzgerald {
323218d72a7SRichard Fitzgerald .name = "timer1-sts",
324218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
325218d72a7SRichard Fitzgerald .func = 0x140
326218d72a7SRichard Fitzgerald },
327218d72a7SRichard Fitzgerald {
328218d72a7SRichard Fitzgerald .name = "timer2-sts",
329218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
330218d72a7SRichard Fitzgerald .func = 0x141
331218d72a7SRichard Fitzgerald },
332218d72a7SRichard Fitzgerald {
333218d72a7SRichard Fitzgerald .name = "timer3-sts",
334218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
335218d72a7SRichard Fitzgerald .func = 0x142
336218d72a7SRichard Fitzgerald },
337218d72a7SRichard Fitzgerald {
338218d72a7SRichard Fitzgerald .name = "timer4-sts",
339218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
340218d72a7SRichard Fitzgerald .func = 0x143
341218d72a7SRichard Fitzgerald },
342218d72a7SRichard Fitzgerald {
343218d72a7SRichard Fitzgerald .name = "timer5-sts",
344218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
345218d72a7SRichard Fitzgerald .func = 0x144
346218d72a7SRichard Fitzgerald },
347218d72a7SRichard Fitzgerald {
348218d72a7SRichard Fitzgerald .name = "timer6-sts",
349218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
350218d72a7SRichard Fitzgerald .func = 0x145
351218d72a7SRichard Fitzgerald },
352218d72a7SRichard Fitzgerald {
353218d72a7SRichard Fitzgerald .name = "timer7-sts",
354218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
355218d72a7SRichard Fitzgerald .func = 0x146
356218d72a7SRichard Fitzgerald },
357218d72a7SRichard Fitzgerald {
358218d72a7SRichard Fitzgerald .name = "timer8-sts",
359218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
360218d72a7SRichard Fitzgerald .func = 0x147
361218d72a7SRichard Fitzgerald },
362218d72a7SRichard Fitzgerald {
363218d72a7SRichard Fitzgerald .name = "log1-fifo-ne",
364218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
365218d72a7SRichard Fitzgerald .func = 0x150
366218d72a7SRichard Fitzgerald },
367218d72a7SRichard Fitzgerald {
368218d72a7SRichard Fitzgerald .name = "log2-fifo-ne",
369218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
370218d72a7SRichard Fitzgerald .func = 0x151
371218d72a7SRichard Fitzgerald },
372218d72a7SRichard Fitzgerald {
373218d72a7SRichard Fitzgerald .name = "log3-fifo-ne",
374218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
375218d72a7SRichard Fitzgerald .func = 0x152
376218d72a7SRichard Fitzgerald },
377218d72a7SRichard Fitzgerald {
378218d72a7SRichard Fitzgerald .name = "log4-fifo-ne",
379218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
380218d72a7SRichard Fitzgerald .func = 0x153
381218d72a7SRichard Fitzgerald },
382218d72a7SRichard Fitzgerald {
383218d72a7SRichard Fitzgerald .name = "log5-fifo-ne",
384218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
385218d72a7SRichard Fitzgerald .func = 0x154
386218d72a7SRichard Fitzgerald },
387218d72a7SRichard Fitzgerald {
388218d72a7SRichard Fitzgerald .name = "log6-fifo-ne",
389218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
390218d72a7SRichard Fitzgerald .func = 0x155
391218d72a7SRichard Fitzgerald },
392218d72a7SRichard Fitzgerald {
393218d72a7SRichard Fitzgerald .name = "log7-fifo-ne",
394218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
395218d72a7SRichard Fitzgerald .func = 0x156
396218d72a7SRichard Fitzgerald },
397218d72a7SRichard Fitzgerald {
398218d72a7SRichard Fitzgerald .name = "log8-fifo-ne",
399218d72a7SRichard Fitzgerald .group_names = madera_pin_single_group_names,
400218d72a7SRichard Fitzgerald .func = 0x157
401218d72a7SRichard Fitzgerald },
402a1db8da7SCharles Keepax {
403a1db8da7SCharles Keepax .name = "aux-pdm-clk",
404a1db8da7SCharles Keepax .group_names = madera_pin_single_group_names,
405a1db8da7SCharles Keepax .func = 0x280
406a1db8da7SCharles Keepax },
407a1db8da7SCharles Keepax {
408a1db8da7SCharles Keepax .name = "aux-pdm-dat",
409a1db8da7SCharles Keepax .group_names = madera_pin_single_group_names,
410a1db8da7SCharles Keepax .func = 0x281
411a1db8da7SCharles Keepax },
412218d72a7SRichard Fitzgerald };
413218d72a7SRichard Fitzgerald
madera_pin_make_drv_str(struct madera_pin_private * priv,unsigned int milliamps)414218d72a7SRichard Fitzgerald static u16 madera_pin_make_drv_str(struct madera_pin_private *priv,
415218d72a7SRichard Fitzgerald unsigned int milliamps)
416218d72a7SRichard Fitzgerald {
417218d72a7SRichard Fitzgerald switch (milliamps) {
418218d72a7SRichard Fitzgerald case 4:
419218d72a7SRichard Fitzgerald return 0;
420218d72a7SRichard Fitzgerald case 8:
421218d72a7SRichard Fitzgerald return 2 << MADERA_GP1_DRV_STR_SHIFT;
422218d72a7SRichard Fitzgerald default:
423218d72a7SRichard Fitzgerald break;
424218d72a7SRichard Fitzgerald }
425218d72a7SRichard Fitzgerald
426218d72a7SRichard Fitzgerald dev_warn(priv->dev, "%u mA not a valid drive strength", milliamps);
427218d72a7SRichard Fitzgerald
428218d72a7SRichard Fitzgerald return 0;
429218d72a7SRichard Fitzgerald }
430218d72a7SRichard Fitzgerald
madera_pin_unmake_drv_str(struct madera_pin_private * priv,u16 regval)431218d72a7SRichard Fitzgerald static unsigned int madera_pin_unmake_drv_str(struct madera_pin_private *priv,
432218d72a7SRichard Fitzgerald u16 regval)
433218d72a7SRichard Fitzgerald {
434218d72a7SRichard Fitzgerald regval = (regval & MADERA_GP1_DRV_STR_MASK) >> MADERA_GP1_DRV_STR_SHIFT;
435218d72a7SRichard Fitzgerald
436218d72a7SRichard Fitzgerald switch (regval) {
437218d72a7SRichard Fitzgerald case 0:
438218d72a7SRichard Fitzgerald return 4;
439218d72a7SRichard Fitzgerald case 2:
440218d72a7SRichard Fitzgerald return 8;
441218d72a7SRichard Fitzgerald default:
442218d72a7SRichard Fitzgerald return 0;
443218d72a7SRichard Fitzgerald }
444218d72a7SRichard Fitzgerald }
445218d72a7SRichard Fitzgerald
madera_get_groups_count(struct pinctrl_dev * pctldev)446218d72a7SRichard Fitzgerald static int madera_get_groups_count(struct pinctrl_dev *pctldev)
447218d72a7SRichard Fitzgerald {
448218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
449218d72a7SRichard Fitzgerald
450218d72a7SRichard Fitzgerald /* Number of alt function groups plus number of single-pin groups */
451218d72a7SRichard Fitzgerald return priv->chip->n_pin_groups + priv->chip->n_pins;
452218d72a7SRichard Fitzgerald }
453218d72a7SRichard Fitzgerald
madera_get_group_name(struct pinctrl_dev * pctldev,unsigned int selector)454218d72a7SRichard Fitzgerald static const char *madera_get_group_name(struct pinctrl_dev *pctldev,
455218d72a7SRichard Fitzgerald unsigned int selector)
456218d72a7SRichard Fitzgerald {
457218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
458218d72a7SRichard Fitzgerald
459218d72a7SRichard Fitzgerald if (selector < priv->chip->n_pin_groups)
460218d72a7SRichard Fitzgerald return priv->chip->pin_groups[selector].name;
461218d72a7SRichard Fitzgerald
462218d72a7SRichard Fitzgerald selector -= priv->chip->n_pin_groups;
463218d72a7SRichard Fitzgerald return madera_pin_single_group_names[selector];
464218d72a7SRichard Fitzgerald }
465218d72a7SRichard Fitzgerald
madera_get_group_pins(struct pinctrl_dev * pctldev,unsigned int selector,const unsigned int ** pins,unsigned int * num_pins)466218d72a7SRichard Fitzgerald static int madera_get_group_pins(struct pinctrl_dev *pctldev,
467218d72a7SRichard Fitzgerald unsigned int selector,
468218d72a7SRichard Fitzgerald const unsigned int **pins,
469218d72a7SRichard Fitzgerald unsigned int *num_pins)
470218d72a7SRichard Fitzgerald {
471218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
472218d72a7SRichard Fitzgerald
473218d72a7SRichard Fitzgerald if (selector < priv->chip->n_pin_groups) {
474218d72a7SRichard Fitzgerald *pins = priv->chip->pin_groups[selector].pins;
475218d72a7SRichard Fitzgerald *num_pins = priv->chip->pin_groups[selector].n_pins;
476218d72a7SRichard Fitzgerald } else {
477218d72a7SRichard Fitzgerald /* return the dummy group for a single pin */
478218d72a7SRichard Fitzgerald selector -= priv->chip->n_pin_groups;
479218d72a7SRichard Fitzgerald *pins = &madera_pin_single_group_pins[selector];
480218d72a7SRichard Fitzgerald *num_pins = 1;
481218d72a7SRichard Fitzgerald }
482218d72a7SRichard Fitzgerald return 0;
483218d72a7SRichard Fitzgerald }
484218d72a7SRichard Fitzgerald
madera_pin_dbg_show_fn(struct madera_pin_private * priv,struct seq_file * s,unsigned int pin,unsigned int fn)485218d72a7SRichard Fitzgerald static void madera_pin_dbg_show_fn(struct madera_pin_private *priv,
486218d72a7SRichard Fitzgerald struct seq_file *s,
487218d72a7SRichard Fitzgerald unsigned int pin, unsigned int fn)
488218d72a7SRichard Fitzgerald {
489218d72a7SRichard Fitzgerald const struct madera_pin_chip *chip = priv->chip;
490218d72a7SRichard Fitzgerald int i, g_pin;
491218d72a7SRichard Fitzgerald
492218d72a7SRichard Fitzgerald if (fn != 0) {
493218d72a7SRichard Fitzgerald for (i = 0; i < ARRAY_SIZE(madera_mux_funcs); ++i) {
494218d72a7SRichard Fitzgerald if (madera_mux_funcs[i].func == fn) {
495218d72a7SRichard Fitzgerald seq_printf(s, " FN=%s",
496218d72a7SRichard Fitzgerald madera_mux_funcs[i].name);
497218d72a7SRichard Fitzgerald return;
498218d72a7SRichard Fitzgerald }
499218d72a7SRichard Fitzgerald }
500218d72a7SRichard Fitzgerald return; /* ignore unknown function values */
501218d72a7SRichard Fitzgerald }
502218d72a7SRichard Fitzgerald
503218d72a7SRichard Fitzgerald /* alt function */
504218d72a7SRichard Fitzgerald for (i = 0; i < chip->n_pin_groups; ++i) {
505218d72a7SRichard Fitzgerald for (g_pin = 0; g_pin < chip->pin_groups[i].n_pins; ++g_pin) {
506218d72a7SRichard Fitzgerald if (chip->pin_groups[i].pins[g_pin] == pin) {
507218d72a7SRichard Fitzgerald seq_printf(s, " FN=%s",
508218d72a7SRichard Fitzgerald chip->pin_groups[i].name);
509218d72a7SRichard Fitzgerald return;
510218d72a7SRichard Fitzgerald }
511218d72a7SRichard Fitzgerald }
512218d72a7SRichard Fitzgerald }
513218d72a7SRichard Fitzgerald }
514218d72a7SRichard Fitzgerald
madera_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int pin)515218d72a7SRichard Fitzgerald static void __maybe_unused madera_pin_dbg_show(struct pinctrl_dev *pctldev,
516218d72a7SRichard Fitzgerald struct seq_file *s,
517218d72a7SRichard Fitzgerald unsigned int pin)
518218d72a7SRichard Fitzgerald {
519218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
520218d72a7SRichard Fitzgerald unsigned int conf[2];
521218d72a7SRichard Fitzgerald unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
522218d72a7SRichard Fitzgerald unsigned int fn;
523218d72a7SRichard Fitzgerald int ret;
524218d72a7SRichard Fitzgerald
525218d72a7SRichard Fitzgerald ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
526218d72a7SRichard Fitzgerald if (ret)
527218d72a7SRichard Fitzgerald return;
528218d72a7SRichard Fitzgerald
529218d72a7SRichard Fitzgerald ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
530218d72a7SRichard Fitzgerald if (ret)
531218d72a7SRichard Fitzgerald return;
532218d72a7SRichard Fitzgerald
533218d72a7SRichard Fitzgerald seq_printf(s, "%04x:%04x", conf[0], conf[1]);
534218d72a7SRichard Fitzgerald
535218d72a7SRichard Fitzgerald fn = (conf[0] & MADERA_GP1_FN_MASK) >> MADERA_GP1_FN_SHIFT;
536218d72a7SRichard Fitzgerald madera_pin_dbg_show_fn(priv, s, pin, fn);
537218d72a7SRichard Fitzgerald
538218d72a7SRichard Fitzgerald /* State of direction bit is only relevant if function==1 */
539218d72a7SRichard Fitzgerald if (fn == 1) {
540218d72a7SRichard Fitzgerald if (conf[1] & MADERA_GP1_DIR_MASK)
541218d72a7SRichard Fitzgerald seq_puts(s, " IN");
542218d72a7SRichard Fitzgerald else
543218d72a7SRichard Fitzgerald seq_puts(s, " OUT");
544218d72a7SRichard Fitzgerald }
545218d72a7SRichard Fitzgerald
546218d72a7SRichard Fitzgerald if (conf[1] & MADERA_GP1_PU_MASK)
547218d72a7SRichard Fitzgerald seq_puts(s, " PU");
548218d72a7SRichard Fitzgerald
549218d72a7SRichard Fitzgerald if (conf[1] & MADERA_GP1_PD_MASK)
550218d72a7SRichard Fitzgerald seq_puts(s, " PD");
551218d72a7SRichard Fitzgerald
552218d72a7SRichard Fitzgerald if (conf[0] & MADERA_GP1_DB_MASK)
553218d72a7SRichard Fitzgerald seq_puts(s, " DB");
554218d72a7SRichard Fitzgerald
555218d72a7SRichard Fitzgerald if (conf[0] & MADERA_GP1_OP_CFG_MASK)
556218d72a7SRichard Fitzgerald seq_puts(s, " OD");
557218d72a7SRichard Fitzgerald else
558218d72a7SRichard Fitzgerald seq_puts(s, " CMOS");
559218d72a7SRichard Fitzgerald
560218d72a7SRichard Fitzgerald seq_printf(s, " DRV=%umA", madera_pin_unmake_drv_str(priv, conf[1]));
561218d72a7SRichard Fitzgerald
562218d72a7SRichard Fitzgerald if (conf[0] & MADERA_GP1_IP_CFG_MASK)
563218d72a7SRichard Fitzgerald seq_puts(s, " SCHMITT");
564218d72a7SRichard Fitzgerald }
565218d72a7SRichard Fitzgerald
566218d72a7SRichard Fitzgerald static const struct pinctrl_ops madera_pin_group_ops = {
567218d72a7SRichard Fitzgerald .get_groups_count = madera_get_groups_count,
568218d72a7SRichard Fitzgerald .get_group_name = madera_get_group_name,
569218d72a7SRichard Fitzgerald .get_group_pins = madera_get_group_pins,
570218d72a7SRichard Fitzgerald #if IS_ENABLED(CONFIG_OF)
571218d72a7SRichard Fitzgerald .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
572218d72a7SRichard Fitzgerald .dt_free_map = pinctrl_utils_free_map,
573218d72a7SRichard Fitzgerald #endif
574218d72a7SRichard Fitzgerald #if IS_ENABLED(CONFIG_DEBUG_FS)
575218d72a7SRichard Fitzgerald .pin_dbg_show = madera_pin_dbg_show,
576218d72a7SRichard Fitzgerald #endif
577218d72a7SRichard Fitzgerald };
578218d72a7SRichard Fitzgerald
madera_mux_get_funcs_count(struct pinctrl_dev * pctldev)579218d72a7SRichard Fitzgerald static int madera_mux_get_funcs_count(struct pinctrl_dev *pctldev)
580218d72a7SRichard Fitzgerald {
581218d72a7SRichard Fitzgerald return ARRAY_SIZE(madera_mux_funcs);
582218d72a7SRichard Fitzgerald }
583218d72a7SRichard Fitzgerald
madera_mux_get_func_name(struct pinctrl_dev * pctldev,unsigned int selector)584218d72a7SRichard Fitzgerald static const char *madera_mux_get_func_name(struct pinctrl_dev *pctldev,
585218d72a7SRichard Fitzgerald unsigned int selector)
586218d72a7SRichard Fitzgerald {
587218d72a7SRichard Fitzgerald return madera_mux_funcs[selector].name;
588218d72a7SRichard Fitzgerald }
589218d72a7SRichard Fitzgerald
madera_mux_get_groups(struct pinctrl_dev * pctldev,unsigned int selector,const char * const ** groups,unsigned int * const num_groups)590218d72a7SRichard Fitzgerald static int madera_mux_get_groups(struct pinctrl_dev *pctldev,
591218d72a7SRichard Fitzgerald unsigned int selector,
592218d72a7SRichard Fitzgerald const char * const **groups,
593218d72a7SRichard Fitzgerald unsigned int * const num_groups)
594218d72a7SRichard Fitzgerald {
595218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
596218d72a7SRichard Fitzgerald
597218d72a7SRichard Fitzgerald *groups = madera_mux_funcs[selector].group_names;
598218d72a7SRichard Fitzgerald
599218d72a7SRichard Fitzgerald if (madera_mux_funcs[selector].func == 0) {
600218d72a7SRichard Fitzgerald /* alt func always maps to a single group */
601218d72a7SRichard Fitzgerald *num_groups = 1;
602218d72a7SRichard Fitzgerald } else {
603218d72a7SRichard Fitzgerald /* other funcs map to all available gpio pins */
604218d72a7SRichard Fitzgerald *num_groups = priv->chip->n_pins;
605218d72a7SRichard Fitzgerald }
606218d72a7SRichard Fitzgerald
607218d72a7SRichard Fitzgerald return 0;
608218d72a7SRichard Fitzgerald }
609218d72a7SRichard Fitzgerald
madera_mux_set_mux(struct pinctrl_dev * pctldev,unsigned int selector,unsigned int group)610218d72a7SRichard Fitzgerald static int madera_mux_set_mux(struct pinctrl_dev *pctldev,
611218d72a7SRichard Fitzgerald unsigned int selector,
612218d72a7SRichard Fitzgerald unsigned int group)
613218d72a7SRichard Fitzgerald {
614218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
615218d72a7SRichard Fitzgerald struct madera *madera = priv->madera;
616218d72a7SRichard Fitzgerald const struct madera_pin_groups *pin_group = priv->chip->pin_groups;
617218d72a7SRichard Fitzgerald unsigned int n_chip_groups = priv->chip->n_pin_groups;
618218d72a7SRichard Fitzgerald const char *func_name = madera_mux_funcs[selector].name;
619218d72a7SRichard Fitzgerald unsigned int reg;
6204fe81669SGustavo A. R. Silva int i, ret = 0;
621218d72a7SRichard Fitzgerald
622218d72a7SRichard Fitzgerald dev_dbg(priv->dev, "%s selecting %u (%s) for group %u (%s)\n",
623218d72a7SRichard Fitzgerald __func__, selector, func_name, group,
624218d72a7SRichard Fitzgerald madera_get_group_name(pctldev, group));
625218d72a7SRichard Fitzgerald
626218d72a7SRichard Fitzgerald if (madera_mux_funcs[selector].func == 0) {
627218d72a7SRichard Fitzgerald /* alt func pin assignments are codec-specific */
628218d72a7SRichard Fitzgerald for (i = 0; i < n_chip_groups; ++i) {
629218d72a7SRichard Fitzgerald if (strcmp(func_name, pin_group->name) == 0)
630218d72a7SRichard Fitzgerald break;
631218d72a7SRichard Fitzgerald
632218d72a7SRichard Fitzgerald ++pin_group;
633218d72a7SRichard Fitzgerald }
634218d72a7SRichard Fitzgerald
635218d72a7SRichard Fitzgerald if (i == n_chip_groups)
636218d72a7SRichard Fitzgerald return -EINVAL;
637218d72a7SRichard Fitzgerald
638218d72a7SRichard Fitzgerald for (i = 0; i < pin_group->n_pins; ++i) {
639218d72a7SRichard Fitzgerald reg = MADERA_GPIO1_CTRL_1 + (2 * pin_group->pins[i]);
640218d72a7SRichard Fitzgerald
641218d72a7SRichard Fitzgerald dev_dbg(priv->dev, "%s setting 0x%x func bits to 0\n",
642218d72a7SRichard Fitzgerald __func__, reg);
643218d72a7SRichard Fitzgerald
644218d72a7SRichard Fitzgerald ret = regmap_update_bits(madera->regmap, reg,
645218d72a7SRichard Fitzgerald MADERA_GP1_FN_MASK, 0);
646218d72a7SRichard Fitzgerald if (ret)
647218d72a7SRichard Fitzgerald break;
648218d72a7SRichard Fitzgerald
649218d72a7SRichard Fitzgerald }
650218d72a7SRichard Fitzgerald } else {
651218d72a7SRichard Fitzgerald /*
652218d72a7SRichard Fitzgerald * for other funcs the group will be the gpio number and will
653218d72a7SRichard Fitzgerald * be offset by the number of chip-specific functions at the
654218d72a7SRichard Fitzgerald * start of the group list
655218d72a7SRichard Fitzgerald */
656218d72a7SRichard Fitzgerald group -= n_chip_groups;
657218d72a7SRichard Fitzgerald reg = MADERA_GPIO1_CTRL_1 + (2 * group);
658218d72a7SRichard Fitzgerald
659218d72a7SRichard Fitzgerald dev_dbg(priv->dev, "%s setting 0x%x func bits to 0x%x\n",
660218d72a7SRichard Fitzgerald __func__, reg, madera_mux_funcs[selector].func);
661218d72a7SRichard Fitzgerald
662218d72a7SRichard Fitzgerald ret = regmap_update_bits(madera->regmap,
663218d72a7SRichard Fitzgerald reg,
664218d72a7SRichard Fitzgerald MADERA_GP1_FN_MASK,
665218d72a7SRichard Fitzgerald madera_mux_funcs[selector].func);
666218d72a7SRichard Fitzgerald }
667218d72a7SRichard Fitzgerald
668218d72a7SRichard Fitzgerald if (ret)
669218d72a7SRichard Fitzgerald dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
670218d72a7SRichard Fitzgerald
671218d72a7SRichard Fitzgerald return ret;
672218d72a7SRichard Fitzgerald }
673218d72a7SRichard Fitzgerald
madera_gpio_set_direction(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned int offset,bool input)674218d72a7SRichard Fitzgerald static int madera_gpio_set_direction(struct pinctrl_dev *pctldev,
675218d72a7SRichard Fitzgerald struct pinctrl_gpio_range *range,
676218d72a7SRichard Fitzgerald unsigned int offset,
677218d72a7SRichard Fitzgerald bool input)
678218d72a7SRichard Fitzgerald {
679218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
680218d72a7SRichard Fitzgerald struct madera *madera = priv->madera;
681218d72a7SRichard Fitzgerald unsigned int reg = MADERA_GPIO1_CTRL_2 + (2 * offset);
682218d72a7SRichard Fitzgerald unsigned int val;
683218d72a7SRichard Fitzgerald int ret;
684218d72a7SRichard Fitzgerald
685218d72a7SRichard Fitzgerald if (input)
686218d72a7SRichard Fitzgerald val = MADERA_GP1_DIR;
687218d72a7SRichard Fitzgerald else
688218d72a7SRichard Fitzgerald val = 0;
689218d72a7SRichard Fitzgerald
690218d72a7SRichard Fitzgerald ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_DIR_MASK, val);
691218d72a7SRichard Fitzgerald if (ret)
692218d72a7SRichard Fitzgerald dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
693218d72a7SRichard Fitzgerald
694218d72a7SRichard Fitzgerald return ret;
695218d72a7SRichard Fitzgerald }
696218d72a7SRichard Fitzgerald
madera_gpio_request_enable(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned int offset)697218d72a7SRichard Fitzgerald static int madera_gpio_request_enable(struct pinctrl_dev *pctldev,
698218d72a7SRichard Fitzgerald struct pinctrl_gpio_range *range,
699218d72a7SRichard Fitzgerald unsigned int offset)
700218d72a7SRichard Fitzgerald {
701218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
702218d72a7SRichard Fitzgerald struct madera *madera = priv->madera;
703218d72a7SRichard Fitzgerald unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
704218d72a7SRichard Fitzgerald int ret;
705218d72a7SRichard Fitzgerald
706218d72a7SRichard Fitzgerald /* put the pin into GPIO mode */
707218d72a7SRichard Fitzgerald ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
708218d72a7SRichard Fitzgerald if (ret)
709218d72a7SRichard Fitzgerald dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
710218d72a7SRichard Fitzgerald
711218d72a7SRichard Fitzgerald return ret;
712218d72a7SRichard Fitzgerald }
713218d72a7SRichard Fitzgerald
madera_gpio_disable_free(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned int offset)714218d72a7SRichard Fitzgerald static void madera_gpio_disable_free(struct pinctrl_dev *pctldev,
715218d72a7SRichard Fitzgerald struct pinctrl_gpio_range *range,
716218d72a7SRichard Fitzgerald unsigned int offset)
717218d72a7SRichard Fitzgerald {
718218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
719218d72a7SRichard Fitzgerald struct madera *madera = priv->madera;
720218d72a7SRichard Fitzgerald unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * offset);
721218d72a7SRichard Fitzgerald int ret;
722218d72a7SRichard Fitzgerald
723218d72a7SRichard Fitzgerald /* disable GPIO by setting to GPIO IN */
724218d72a7SRichard Fitzgerald madera_gpio_set_direction(pctldev, range, offset, true);
725218d72a7SRichard Fitzgerald
726218d72a7SRichard Fitzgerald ret = regmap_update_bits(madera->regmap, reg, MADERA_GP1_FN_MASK, 1);
727218d72a7SRichard Fitzgerald if (ret)
728218d72a7SRichard Fitzgerald dev_err(priv->dev, "Failed to write to 0x%x (%d)\n", reg, ret);
729218d72a7SRichard Fitzgerald }
730218d72a7SRichard Fitzgerald
731218d72a7SRichard Fitzgerald static const struct pinmux_ops madera_pin_mux_ops = {
732218d72a7SRichard Fitzgerald .get_functions_count = madera_mux_get_funcs_count,
733218d72a7SRichard Fitzgerald .get_function_name = madera_mux_get_func_name,
734218d72a7SRichard Fitzgerald .get_function_groups = madera_mux_get_groups,
735218d72a7SRichard Fitzgerald .set_mux = madera_mux_set_mux,
736218d72a7SRichard Fitzgerald .gpio_request_enable = madera_gpio_request_enable,
737218d72a7SRichard Fitzgerald .gpio_disable_free = madera_gpio_disable_free,
738218d72a7SRichard Fitzgerald .gpio_set_direction = madera_gpio_set_direction,
739218d72a7SRichard Fitzgerald .strict = true, /* GPIO and other functions are exclusive */
740218d72a7SRichard Fitzgerald };
741218d72a7SRichard Fitzgerald
madera_pin_conf_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)742218d72a7SRichard Fitzgerald static int madera_pin_conf_get(struct pinctrl_dev *pctldev, unsigned int pin,
743218d72a7SRichard Fitzgerald unsigned long *config)
744218d72a7SRichard Fitzgerald {
745218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
746218d72a7SRichard Fitzgerald unsigned int param = pinconf_to_config_param(*config);
747218d72a7SRichard Fitzgerald unsigned int result = 0;
748218d72a7SRichard Fitzgerald unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
749218d72a7SRichard Fitzgerald unsigned int conf[2];
750218d72a7SRichard Fitzgerald int ret;
751218d72a7SRichard Fitzgerald
752218d72a7SRichard Fitzgerald ret = regmap_read(priv->madera->regmap, reg, &conf[0]);
753218d72a7SRichard Fitzgerald if (!ret)
754218d72a7SRichard Fitzgerald ret = regmap_read(priv->madera->regmap, reg + 1, &conf[1]);
755218d72a7SRichard Fitzgerald
756218d72a7SRichard Fitzgerald if (ret) {
757218d72a7SRichard Fitzgerald dev_err(priv->dev, "Failed to read GP%d conf (%d)\n",
758218d72a7SRichard Fitzgerald pin + 1, ret);
759218d72a7SRichard Fitzgerald return ret;
760218d72a7SRichard Fitzgerald }
761218d72a7SRichard Fitzgerald
762218d72a7SRichard Fitzgerald switch (param) {
763218d72a7SRichard Fitzgerald case PIN_CONFIG_BIAS_BUS_HOLD:
764218d72a7SRichard Fitzgerald conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
765218d72a7SRichard Fitzgerald if (conf[1] == (MADERA_GP1_PU | MADERA_GP1_PD))
766218d72a7SRichard Fitzgerald result = 1;
767218d72a7SRichard Fitzgerald break;
768218d72a7SRichard Fitzgerald case PIN_CONFIG_BIAS_DISABLE:
769218d72a7SRichard Fitzgerald conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
770218d72a7SRichard Fitzgerald if (!conf[1])
771218d72a7SRichard Fitzgerald result = 1;
772218d72a7SRichard Fitzgerald break;
773218d72a7SRichard Fitzgerald case PIN_CONFIG_BIAS_PULL_DOWN:
774218d72a7SRichard Fitzgerald conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
775218d72a7SRichard Fitzgerald if (conf[1] == MADERA_GP1_PD_MASK)
776218d72a7SRichard Fitzgerald result = 1;
777218d72a7SRichard Fitzgerald break;
778218d72a7SRichard Fitzgerald case PIN_CONFIG_BIAS_PULL_UP:
779218d72a7SRichard Fitzgerald conf[1] &= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
780218d72a7SRichard Fitzgerald if (conf[1] == MADERA_GP1_PU_MASK)
781218d72a7SRichard Fitzgerald result = 1;
782218d72a7SRichard Fitzgerald break;
783218d72a7SRichard Fitzgerald case PIN_CONFIG_DRIVE_OPEN_DRAIN:
784218d72a7SRichard Fitzgerald if (conf[0] & MADERA_GP1_OP_CFG_MASK)
785218d72a7SRichard Fitzgerald result = 1;
786218d72a7SRichard Fitzgerald break;
787218d72a7SRichard Fitzgerald case PIN_CONFIG_DRIVE_PUSH_PULL:
788218d72a7SRichard Fitzgerald if (!(conf[0] & MADERA_GP1_OP_CFG_MASK))
789218d72a7SRichard Fitzgerald result = 1;
790218d72a7SRichard Fitzgerald break;
791218d72a7SRichard Fitzgerald case PIN_CONFIG_DRIVE_STRENGTH:
792218d72a7SRichard Fitzgerald result = madera_pin_unmake_drv_str(priv, conf[1]);
793218d72a7SRichard Fitzgerald break;
794218d72a7SRichard Fitzgerald case PIN_CONFIG_INPUT_DEBOUNCE:
795218d72a7SRichard Fitzgerald if (conf[0] & MADERA_GP1_DB_MASK)
796218d72a7SRichard Fitzgerald result = 1;
797218d72a7SRichard Fitzgerald break;
798218d72a7SRichard Fitzgerald case PIN_CONFIG_INPUT_ENABLE:
799218d72a7SRichard Fitzgerald if (conf[0] & MADERA_GP1_DIR_MASK)
800218d72a7SRichard Fitzgerald result = 1;
801218d72a7SRichard Fitzgerald break;
802218d72a7SRichard Fitzgerald case PIN_CONFIG_INPUT_SCHMITT:
803218d72a7SRichard Fitzgerald case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
804218d72a7SRichard Fitzgerald if (conf[0] & MADERA_GP1_IP_CFG_MASK)
805218d72a7SRichard Fitzgerald result = 1;
806218d72a7SRichard Fitzgerald break;
807218d72a7SRichard Fitzgerald case PIN_CONFIG_OUTPUT:
808218d72a7SRichard Fitzgerald if ((conf[1] & MADERA_GP1_DIR_MASK) &&
809218d72a7SRichard Fitzgerald (conf[0] & MADERA_GP1_LVL_MASK))
810218d72a7SRichard Fitzgerald result = 1;
811218d72a7SRichard Fitzgerald break;
812218d72a7SRichard Fitzgerald default:
813d2f7a822SRichard Fitzgerald return -ENOTSUPP;
814218d72a7SRichard Fitzgerald }
815218d72a7SRichard Fitzgerald
816218d72a7SRichard Fitzgerald *config = pinconf_to_config_packed(param, result);
817218d72a7SRichard Fitzgerald
818218d72a7SRichard Fitzgerald return 0;
819218d72a7SRichard Fitzgerald }
820218d72a7SRichard Fitzgerald
madera_pin_conf_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned int num_configs)821218d72a7SRichard Fitzgerald static int madera_pin_conf_set(struct pinctrl_dev *pctldev, unsigned int pin,
822218d72a7SRichard Fitzgerald unsigned long *configs, unsigned int num_configs)
823218d72a7SRichard Fitzgerald {
824218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
825218d72a7SRichard Fitzgerald u16 conf[2] = {0, 0};
826218d72a7SRichard Fitzgerald u16 mask[2] = {0, 0};
827218d72a7SRichard Fitzgerald unsigned int reg = MADERA_GPIO1_CTRL_1 + (2 * pin);
828218d72a7SRichard Fitzgerald unsigned int val;
829218d72a7SRichard Fitzgerald int ret;
830218d72a7SRichard Fitzgerald
831218d72a7SRichard Fitzgerald while (num_configs) {
832218d72a7SRichard Fitzgerald dev_dbg(priv->dev, "%s config 0x%lx\n", __func__, *configs);
833218d72a7SRichard Fitzgerald
834218d72a7SRichard Fitzgerald switch (pinconf_to_config_param(*configs)) {
835218d72a7SRichard Fitzgerald case PIN_CONFIG_BIAS_BUS_HOLD:
836218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
837218d72a7SRichard Fitzgerald conf[1] |= MADERA_GP1_PU | MADERA_GP1_PD;
838218d72a7SRichard Fitzgerald break;
839218d72a7SRichard Fitzgerald case PIN_CONFIG_BIAS_DISABLE:
840218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
841218d72a7SRichard Fitzgerald conf[1] &= ~(MADERA_GP1_PU | MADERA_GP1_PD);
842218d72a7SRichard Fitzgerald break;
843218d72a7SRichard Fitzgerald case PIN_CONFIG_BIAS_PULL_DOWN:
844218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
845218d72a7SRichard Fitzgerald conf[1] |= MADERA_GP1_PD;
846218d72a7SRichard Fitzgerald conf[1] &= ~MADERA_GP1_PU;
847218d72a7SRichard Fitzgerald break;
848218d72a7SRichard Fitzgerald case PIN_CONFIG_BIAS_PULL_UP:
849218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_PU_MASK | MADERA_GP1_PD_MASK;
850218d72a7SRichard Fitzgerald conf[1] |= MADERA_GP1_PU;
851218d72a7SRichard Fitzgerald conf[1] &= ~MADERA_GP1_PD;
852218d72a7SRichard Fitzgerald break;
853218d72a7SRichard Fitzgerald case PIN_CONFIG_DRIVE_OPEN_DRAIN:
854218d72a7SRichard Fitzgerald mask[0] |= MADERA_GP1_OP_CFG_MASK;
855218d72a7SRichard Fitzgerald conf[0] |= MADERA_GP1_OP_CFG;
856218d72a7SRichard Fitzgerald break;
857218d72a7SRichard Fitzgerald case PIN_CONFIG_DRIVE_PUSH_PULL:
858218d72a7SRichard Fitzgerald mask[0] |= MADERA_GP1_OP_CFG_MASK;
859218d72a7SRichard Fitzgerald conf[0] &= ~MADERA_GP1_OP_CFG;
860218d72a7SRichard Fitzgerald break;
861218d72a7SRichard Fitzgerald case PIN_CONFIG_DRIVE_STRENGTH:
862218d72a7SRichard Fitzgerald val = pinconf_to_config_argument(*configs);
863218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_DRV_STR_MASK;
864218d72a7SRichard Fitzgerald conf[1] &= ~MADERA_GP1_DRV_STR_MASK;
865218d72a7SRichard Fitzgerald conf[1] |= madera_pin_make_drv_str(priv, val);
866218d72a7SRichard Fitzgerald break;
867218d72a7SRichard Fitzgerald case PIN_CONFIG_INPUT_DEBOUNCE:
868218d72a7SRichard Fitzgerald mask[0] |= MADERA_GP1_DB_MASK;
869218d72a7SRichard Fitzgerald
870218d72a7SRichard Fitzgerald /*
871218d72a7SRichard Fitzgerald * we can't configure debounce time per-pin so value
872218d72a7SRichard Fitzgerald * is just a flag
873218d72a7SRichard Fitzgerald */
874218d72a7SRichard Fitzgerald val = pinconf_to_config_argument(*configs);
875218d72a7SRichard Fitzgerald if (val)
876218d72a7SRichard Fitzgerald conf[0] |= MADERA_GP1_DB;
877218d72a7SRichard Fitzgerald else
878218d72a7SRichard Fitzgerald conf[0] &= ~MADERA_GP1_DB;
879218d72a7SRichard Fitzgerald break;
880218d72a7SRichard Fitzgerald case PIN_CONFIG_INPUT_ENABLE:
881218d72a7SRichard Fitzgerald val = pinconf_to_config_argument(*configs);
882218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_DIR_MASK;
883218d72a7SRichard Fitzgerald if (val)
884218d72a7SRichard Fitzgerald conf[1] |= MADERA_GP1_DIR;
885218d72a7SRichard Fitzgerald else
886218d72a7SRichard Fitzgerald conf[1] &= ~MADERA_GP1_DIR;
887218d72a7SRichard Fitzgerald break;
888218d72a7SRichard Fitzgerald case PIN_CONFIG_INPUT_SCHMITT:
889218d72a7SRichard Fitzgerald val = pinconf_to_config_argument(*configs);
890218d72a7SRichard Fitzgerald mask[0] |= MADERA_GP1_IP_CFG;
891218d72a7SRichard Fitzgerald if (val)
892218d72a7SRichard Fitzgerald conf[0] |= MADERA_GP1_IP_CFG;
893218d72a7SRichard Fitzgerald else
894218d72a7SRichard Fitzgerald conf[0] &= ~MADERA_GP1_IP_CFG;
895218d72a7SRichard Fitzgerald
896218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_DIR_MASK;
897218d72a7SRichard Fitzgerald conf[1] |= MADERA_GP1_DIR;
898218d72a7SRichard Fitzgerald break;
899218d72a7SRichard Fitzgerald case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
900218d72a7SRichard Fitzgerald mask[0] |= MADERA_GP1_IP_CFG;
901218d72a7SRichard Fitzgerald conf[0] |= MADERA_GP1_IP_CFG;
902218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_DIR_MASK;
903218d72a7SRichard Fitzgerald conf[1] |= MADERA_GP1_DIR;
904218d72a7SRichard Fitzgerald break;
905218d72a7SRichard Fitzgerald case PIN_CONFIG_OUTPUT:
906218d72a7SRichard Fitzgerald val = pinconf_to_config_argument(*configs);
907218d72a7SRichard Fitzgerald mask[0] |= MADERA_GP1_LVL_MASK;
908218d72a7SRichard Fitzgerald if (val)
909218d72a7SRichard Fitzgerald conf[0] |= MADERA_GP1_LVL;
910218d72a7SRichard Fitzgerald else
911218d72a7SRichard Fitzgerald conf[0] &= ~MADERA_GP1_LVL;
912218d72a7SRichard Fitzgerald
913218d72a7SRichard Fitzgerald mask[1] |= MADERA_GP1_DIR_MASK;
914218d72a7SRichard Fitzgerald conf[1] &= ~MADERA_GP1_DIR;
915218d72a7SRichard Fitzgerald break;
916218d72a7SRichard Fitzgerald default:
917d2f7a822SRichard Fitzgerald return -ENOTSUPP;
918218d72a7SRichard Fitzgerald }
919218d72a7SRichard Fitzgerald
920218d72a7SRichard Fitzgerald ++configs;
921218d72a7SRichard Fitzgerald --num_configs;
922218d72a7SRichard Fitzgerald }
923218d72a7SRichard Fitzgerald
924218d72a7SRichard Fitzgerald dev_dbg(priv->dev,
925218d72a7SRichard Fitzgerald "%s gpio%d 0x%x:0x%x 0x%x:0x%x\n",
926218d72a7SRichard Fitzgerald __func__, pin + 1, reg, conf[0], reg + 1, conf[1]);
927218d72a7SRichard Fitzgerald
928218d72a7SRichard Fitzgerald ret = regmap_update_bits(priv->madera->regmap, reg, mask[0], conf[0]);
929218d72a7SRichard Fitzgerald if (ret)
930218d72a7SRichard Fitzgerald goto err;
931218d72a7SRichard Fitzgerald
932218d72a7SRichard Fitzgerald ++reg;
933218d72a7SRichard Fitzgerald ret = regmap_update_bits(priv->madera->regmap, reg, mask[1], conf[1]);
934218d72a7SRichard Fitzgerald if (ret)
935218d72a7SRichard Fitzgerald goto err;
936218d72a7SRichard Fitzgerald
937218d72a7SRichard Fitzgerald return 0;
938218d72a7SRichard Fitzgerald
939218d72a7SRichard Fitzgerald err:
940218d72a7SRichard Fitzgerald dev_err(priv->dev,
941218d72a7SRichard Fitzgerald "Failed to write GPIO%d conf (%d) reg 0x%x\n",
942218d72a7SRichard Fitzgerald pin + 1, ret, reg);
943218d72a7SRichard Fitzgerald
944218d72a7SRichard Fitzgerald return ret;
945218d72a7SRichard Fitzgerald }
946218d72a7SRichard Fitzgerald
madera_pin_conf_group_set(struct pinctrl_dev * pctldev,unsigned int selector,unsigned long * configs,unsigned int num_configs)947218d72a7SRichard Fitzgerald static int madera_pin_conf_group_set(struct pinctrl_dev *pctldev,
948218d72a7SRichard Fitzgerald unsigned int selector,
949218d72a7SRichard Fitzgerald unsigned long *configs,
950218d72a7SRichard Fitzgerald unsigned int num_configs)
951218d72a7SRichard Fitzgerald {
952218d72a7SRichard Fitzgerald struct madera_pin_private *priv = pinctrl_dev_get_drvdata(pctldev);
953218d72a7SRichard Fitzgerald const struct madera_pin_groups *pin_group;
954218d72a7SRichard Fitzgerald unsigned int n_groups = priv->chip->n_pin_groups;
955218d72a7SRichard Fitzgerald int i, ret;
956218d72a7SRichard Fitzgerald
957218d72a7SRichard Fitzgerald dev_dbg(priv->dev, "%s setting group %s\n", __func__,
958218d72a7SRichard Fitzgerald madera_get_group_name(pctldev, selector));
959218d72a7SRichard Fitzgerald
960218d72a7SRichard Fitzgerald if (selector >= n_groups) {
961218d72a7SRichard Fitzgerald /* group is a single pin, convert to pin number and set */
962218d72a7SRichard Fitzgerald return madera_pin_conf_set(pctldev,
963218d72a7SRichard Fitzgerald selector - n_groups,
964218d72a7SRichard Fitzgerald configs,
965218d72a7SRichard Fitzgerald num_configs);
966218d72a7SRichard Fitzgerald } else {
967218d72a7SRichard Fitzgerald pin_group = &priv->chip->pin_groups[selector];
968218d72a7SRichard Fitzgerald
969218d72a7SRichard Fitzgerald for (i = 0; i < pin_group->n_pins; ++i) {
970218d72a7SRichard Fitzgerald ret = madera_pin_conf_set(pctldev,
971218d72a7SRichard Fitzgerald pin_group->pins[i],
972218d72a7SRichard Fitzgerald configs,
973218d72a7SRichard Fitzgerald num_configs);
974218d72a7SRichard Fitzgerald if (ret)
975218d72a7SRichard Fitzgerald return ret;
976218d72a7SRichard Fitzgerald }
977218d72a7SRichard Fitzgerald }
978218d72a7SRichard Fitzgerald
979218d72a7SRichard Fitzgerald return 0;
980218d72a7SRichard Fitzgerald }
981218d72a7SRichard Fitzgerald
982218d72a7SRichard Fitzgerald static const struct pinconf_ops madera_pin_conf_ops = {
98325cb9e5aSRichard Fitzgerald .is_generic = true,
984218d72a7SRichard Fitzgerald .pin_config_get = madera_pin_conf_get,
985218d72a7SRichard Fitzgerald .pin_config_set = madera_pin_conf_set,
986218d72a7SRichard Fitzgerald .pin_config_group_set = madera_pin_conf_group_set,
987218d72a7SRichard Fitzgerald };
988218d72a7SRichard Fitzgerald
989218d72a7SRichard Fitzgerald static struct pinctrl_desc madera_pin_desc = {
990218d72a7SRichard Fitzgerald .name = "madera-pinctrl",
991218d72a7SRichard Fitzgerald .pins = madera_pins,
992218d72a7SRichard Fitzgerald .pctlops = &madera_pin_group_ops,
993218d72a7SRichard Fitzgerald .pmxops = &madera_pin_mux_ops,
994218d72a7SRichard Fitzgerald .confops = &madera_pin_conf_ops,
995218d72a7SRichard Fitzgerald .owner = THIS_MODULE,
996218d72a7SRichard Fitzgerald };
997218d72a7SRichard Fitzgerald
madera_pin_probe(struct platform_device * pdev)998218d72a7SRichard Fitzgerald static int madera_pin_probe(struct platform_device *pdev)
999218d72a7SRichard Fitzgerald {
1000218d72a7SRichard Fitzgerald struct madera *madera = dev_get_drvdata(pdev->dev.parent);
1001f134b851SCharles Keepax const struct madera_pdata *pdata = &madera->pdata;
1002218d72a7SRichard Fitzgerald struct madera_pin_private *priv;
1003218d72a7SRichard Fitzgerald int ret;
1004218d72a7SRichard Fitzgerald
1005218d72a7SRichard Fitzgerald BUILD_BUG_ON(ARRAY_SIZE(madera_pin_single_group_names) !=
1006218d72a7SRichard Fitzgerald ARRAY_SIZE(madera_pin_single_group_pins));
1007218d72a7SRichard Fitzgerald
1008218d72a7SRichard Fitzgerald dev_dbg(&pdev->dev, "%s\n", __func__);
1009218d72a7SRichard Fitzgerald
1010ce852837SAndy Shevchenko device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent));
1011ce852837SAndy Shevchenko
1012218d72a7SRichard Fitzgerald priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1013218d72a7SRichard Fitzgerald if (!priv)
1014218d72a7SRichard Fitzgerald return -ENOMEM;
1015218d72a7SRichard Fitzgerald
1016218d72a7SRichard Fitzgerald priv->dev = &pdev->dev;
1017218d72a7SRichard Fitzgerald priv->madera = madera;
1018218d72a7SRichard Fitzgerald
1019218d72a7SRichard Fitzgerald switch (madera->type) {
1020b0bca3e4SRichard Fitzgerald case CS47L15:
1021b0bca3e4SRichard Fitzgerald if (IS_ENABLED(CONFIG_PINCTRL_CS47L15))
1022b0bca3e4SRichard Fitzgerald priv->chip = &cs47l15_pin_chip;
1023b0bca3e4SRichard Fitzgerald break;
1024218d72a7SRichard Fitzgerald case CS47L35:
1025218d72a7SRichard Fitzgerald if (IS_ENABLED(CONFIG_PINCTRL_CS47L35))
1026218d72a7SRichard Fitzgerald priv->chip = &cs47l35_pin_chip;
1027218d72a7SRichard Fitzgerald break;
1028218d72a7SRichard Fitzgerald case CS47L85:
1029218d72a7SRichard Fitzgerald case WM1840:
1030218d72a7SRichard Fitzgerald if (IS_ENABLED(CONFIG_PINCTRL_CS47L85))
1031218d72a7SRichard Fitzgerald priv->chip = &cs47l85_pin_chip;
1032218d72a7SRichard Fitzgerald break;
1033218d72a7SRichard Fitzgerald case CS47L90:
1034218d72a7SRichard Fitzgerald case CS47L91:
1035218d72a7SRichard Fitzgerald if (IS_ENABLED(CONFIG_PINCTRL_CS47L90))
1036218d72a7SRichard Fitzgerald priv->chip = &cs47l90_pin_chip;
1037218d72a7SRichard Fitzgerald break;
1038a1db8da7SCharles Keepax case CS42L92:
1039a1db8da7SCharles Keepax case CS47L92:
1040a1db8da7SCharles Keepax case CS47L93:
1041a1db8da7SCharles Keepax if (IS_ENABLED(CONFIG_PINCTRL_CS47L92))
1042a1db8da7SCharles Keepax priv->chip = &cs47l92_pin_chip;
1043a1db8da7SCharles Keepax break;
1044218d72a7SRichard Fitzgerald default:
1045218d72a7SRichard Fitzgerald break;
1046218d72a7SRichard Fitzgerald }
1047218d72a7SRichard Fitzgerald
1048218d72a7SRichard Fitzgerald if (!priv->chip)
1049218d72a7SRichard Fitzgerald return -ENODEV;
1050218d72a7SRichard Fitzgerald
1051218d72a7SRichard Fitzgerald madera_pin_desc.npins = priv->chip->n_pins;
1052218d72a7SRichard Fitzgerald
1053218d72a7SRichard Fitzgerald ret = devm_pinctrl_register_and_init(&pdev->dev,
1054218d72a7SRichard Fitzgerald &madera_pin_desc,
1055218d72a7SRichard Fitzgerald priv,
1056218d72a7SRichard Fitzgerald &priv->pctl);
1057218d72a7SRichard Fitzgerald if (ret) {
1058218d72a7SRichard Fitzgerald dev_err(priv->dev, "Failed pinctrl register (%d)\n", ret);
1059218d72a7SRichard Fitzgerald return ret;
1060218d72a7SRichard Fitzgerald }
1061218d72a7SRichard Fitzgerald
1062218d72a7SRichard Fitzgerald /* if the configuration is provided through pdata, apply it */
1063f134b851SCharles Keepax if (pdata->gpio_configs) {
1064218d72a7SRichard Fitzgerald ret = pinctrl_register_mappings(pdata->gpio_configs,
1065218d72a7SRichard Fitzgerald pdata->n_gpio_configs);
1066218d72a7SRichard Fitzgerald if (ret) {
1067218d72a7SRichard Fitzgerald dev_err(priv->dev,
1068218d72a7SRichard Fitzgerald "Failed to register pdata mappings (%d)\n",
1069218d72a7SRichard Fitzgerald ret);
1070218d72a7SRichard Fitzgerald return ret;
1071218d72a7SRichard Fitzgerald }
1072218d72a7SRichard Fitzgerald }
1073218d72a7SRichard Fitzgerald
1074218d72a7SRichard Fitzgerald ret = pinctrl_enable(priv->pctl);
1075218d72a7SRichard Fitzgerald if (ret) {
1076218d72a7SRichard Fitzgerald dev_err(priv->dev, "Failed to enable pinctrl (%d)\n", ret);
1077218d72a7SRichard Fitzgerald return ret;
1078218d72a7SRichard Fitzgerald }
1079218d72a7SRichard Fitzgerald
10803567ee83SCharles Keepax platform_set_drvdata(pdev, priv);
10813567ee83SCharles Keepax
1082218d72a7SRichard Fitzgerald dev_dbg(priv->dev, "pinctrl probed ok\n");
1083218d72a7SRichard Fitzgerald
1084218d72a7SRichard Fitzgerald return 0;
1085218d72a7SRichard Fitzgerald }
1086218d72a7SRichard Fitzgerald
madera_pin_remove(struct platform_device * pdev)10873567ee83SCharles Keepax static int madera_pin_remove(struct platform_device *pdev)
10883567ee83SCharles Keepax {
10893567ee83SCharles Keepax struct madera_pin_private *priv = platform_get_drvdata(pdev);
10903567ee83SCharles Keepax
10913567ee83SCharles Keepax if (priv->madera->pdata.gpio_configs)
10923567ee83SCharles Keepax pinctrl_unregister_mappings(priv->madera->pdata.gpio_configs);
10933567ee83SCharles Keepax
10943567ee83SCharles Keepax return 0;
10953567ee83SCharles Keepax }
10963567ee83SCharles Keepax
1097218d72a7SRichard Fitzgerald static struct platform_driver madera_pin_driver = {
1098218d72a7SRichard Fitzgerald .probe = madera_pin_probe,
10993567ee83SCharles Keepax .remove = madera_pin_remove,
1100218d72a7SRichard Fitzgerald .driver = {
1101218d72a7SRichard Fitzgerald .name = "madera-pinctrl",
1102218d72a7SRichard Fitzgerald },
1103218d72a7SRichard Fitzgerald };
1104218d72a7SRichard Fitzgerald
1105218d72a7SRichard Fitzgerald module_platform_driver(madera_pin_driver);
1106218d72a7SRichard Fitzgerald
1107218d72a7SRichard Fitzgerald MODULE_DESCRIPTION("Madera pinctrl driver");
1108218d72a7SRichard Fitzgerald MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
1109218d72a7SRichard Fitzgerald MODULE_LICENSE("GPL v2");
1110