aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pinctrl/bcm/Kconfig13
-rw-r--r--drivers/pinctrl/bcm/Makefile5
-rw-r--r--drivers/pinctrl/bcm/pinctrl-cygnus-mux.c1022
3 files changed, 1038 insertions, 2 deletions
diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig
index bc6d048ac7bc..eb1320152a87 100644
--- a/drivers/pinctrl/bcm/Kconfig
+++ b/drivers/pinctrl/bcm/Kconfig
@@ -19,3 +19,16 @@ config PINCTRL_BCM2835
19 bool 19 bool
20 select PINMUX 20 select PINMUX
21 select PINCONF 21 select PINCONF
22
23config PINCTRL_CYGNUS_MUX
24 bool "Broadcom Cygnus IOMUX driver"
25 depends on (ARCH_BCM_CYGNUS || COMPILE_TEST)
26 select PINMUX
27 select GENERIC_PINCONF
28 default ARCH_BCM_CYGNUS
29 help
30 Say yes here to enable the Broadcom Cygnus IOMUX driver.
31
32 The Broadcom Cygnus IOMUX driver supports group based IOMUX
33 configuration, with the exception that certain individual pins
34 can be overrided to GPIO function
diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile
index 7ba80a383767..bb6beb66d962 100644
--- a/drivers/pinctrl/bcm/Makefile
+++ b/drivers/pinctrl/bcm/Makefile
@@ -1,4 +1,5 @@
1# Broadcom pinctrl support 1# Broadcom pinctrl support
2 2
3obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o 3obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o
4obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o 4obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
5obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o
diff --git a/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c b/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
new file mode 100644
index 000000000000..f9a9283caf81
--- /dev/null
+++ b/drivers/pinctrl/bcm/pinctrl-cygnus-mux.c
@@ -0,0 +1,1022 @@
1/* Copyright (C) 2014-2015 Broadcom Corporation
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License as
5 * published by the Free Software Foundation version 2.
6 *
7 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
8 * kind, whether express or implied; without even the implied warranty
9 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * This file contains the Cygnus IOMUX driver that supports group based PINMUX
13 * configuration. Although PINMUX configuration is mainly group based, the
14 * Cygnus IOMUX controller allows certain pins to be individually muxed to GPIO
15 * function, and therefore be controlled by the Cygnus ASIU GPIO controller
16 */
17
18#include <linux/err.h>
19#include <linux/io.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/slab.h>
23#include <linux/platform_device.h>
24#include <linux/pinctrl/pinctrl.h>
25#include <linux/pinctrl/pinmux.h>
26#include <linux/pinctrl/pinconf.h>
27#include <linux/pinctrl/pinconf-generic.h>
28#include "../core.h"
29#include "../pinctrl-utils.h"
30
31#define CYGNUS_NUM_IOMUX_REGS 8
32#define CYGNUS_NUM_MUX_PER_REG 8
33#define CYGNUS_NUM_IOMUX (CYGNUS_NUM_IOMUX_REGS * \
34 CYGNUS_NUM_MUX_PER_REG)
35
36/*
37 * Cygnus IOMUX register description
38 *
39 * @offset: register offset for mux configuration of a group
40 * @shift: bit shift for mux configuration of a group
41 * @alt: alternate function to set to
42 */
43struct cygnus_mux {
44 unsigned int offset;
45 unsigned int shift;
46 unsigned int alt;
47};
48
49/*
50 * Keep track of Cygnus IOMUX configuration and prevent double configuration
51 *
52 * @cygnus_mux: Cygnus IOMUX register description
53 * @is_configured: flag to indicate whether a mux setting has already been
54 * configured
55 */
56struct cygnus_mux_log {
57 struct cygnus_mux mux;
58 bool is_configured;
59};
60
61/*
62 * Group based IOMUX configuration
63 *
64 * @name: name of the group
65 * @pins: array of pins used by this group
66 * @num_pins: total number of pins used by this group
67 * @mux: Cygnus group based IOMUX configuration
68 */
69struct cygnus_pin_group {
70 const char *name;
71 const unsigned *pins;
72 unsigned num_pins;
73 struct cygnus_mux mux;
74};
75
76/*
77 * Cygnus mux function and supported pin groups
78 *
79 * @name: name of the function
80 * @groups: array of groups that can be supported by this function
81 * @num_groups: total number of groups that can be supported by this function
82 */
83struct cygnus_pin_function {
84 const char *name;
85 const char * const *groups;
86 unsigned num_groups;
87};
88
89/*
90 * Cygnus IOMUX pinctrl core
91 *
92 * @pctl: pointer to pinctrl_dev
93 * @dev: pointer to device
94 * @base0: first I/O register base of the Cygnus IOMUX controller
95 * @base1: second I/O register base
96 * @groups: pointer to array of groups
97 * @num_groups: total number of groups
98 * @functions: pointer to array of functions
99 * @num_functions: total number of functions
100 * @mux_log: pointer to the array of mux logs
101 * @lock: lock to protect register access
102 */
103struct cygnus_pinctrl {
104 struct pinctrl_dev *pctl;
105 struct device *dev;
106 void __iomem *base0;
107 void __iomem *base1;
108
109 const struct cygnus_pin_group *groups;
110 unsigned num_groups;
111
112 const struct cygnus_pin_function *functions;
113 unsigned num_functions;
114
115 struct cygnus_mux_log *mux_log;
116
117 spinlock_t lock;
118};
119
120/*
121 * Certain pins can be individually muxed to GPIO function
122 *
123 * @is_supported: flag to indicate GPIO mux is supported for this pin
124 * @offset: register offset for GPIO mux override of a pin
125 * @shift: bit shift for GPIO mux override of a pin
126 */
127struct cygnus_gpio_mux {
128 int is_supported;
129 unsigned int offset;
130 unsigned int shift;
131};
132
133/*
134 * Description of a pin in Cygnus
135 *
136 * @pin: pin number
137 * @name: pin name
138 * @gpio_mux: GPIO override related information
139 */
140struct cygnus_pin {
141 unsigned pin;
142 char *name;
143 struct cygnus_gpio_mux gpio_mux;
144};
145
146#define CYGNUS_PIN_DESC(p, n, i, o, s) \
147{ \
148 .pin = p, \
149 .name = n, \
150 .gpio_mux = { \
151 .is_supported = i, \
152 .offset = o, \
153 .shift = s, \
154 }, \
155}
156
157/*
158 * List of pins in Cygnus
159 */
160static struct cygnus_pin cygnus_pins[] = {
161 CYGNUS_PIN_DESC(0, "ext_device_reset_n", 0, 0, 0),
162 CYGNUS_PIN_DESC(1, "chip_mode0", 0, 0, 0),
163 CYGNUS_PIN_DESC(2, "chip_mode1", 0, 0, 0),
164 CYGNUS_PIN_DESC(3, "chip_mode2", 0, 0, 0),
165 CYGNUS_PIN_DESC(4, "chip_mode3", 0, 0, 0),
166 CYGNUS_PIN_DESC(5, "chip_mode4", 0, 0, 0),
167 CYGNUS_PIN_DESC(6, "bsc0_scl", 0, 0, 0),
168 CYGNUS_PIN_DESC(7, "bsc0_sda", 0, 0, 0),
169 CYGNUS_PIN_DESC(8, "bsc1_scl", 0, 0, 0),
170 CYGNUS_PIN_DESC(9, "bsc1_sda", 0, 0, 0),
171 CYGNUS_PIN_DESC(10, "d1w_dq", 1, 0x28, 0),
172 CYGNUS_PIN_DESC(11, "d1wowstz_l", 1, 0x4, 28),
173 CYGNUS_PIN_DESC(12, "gpio0", 0, 0, 0),
174 CYGNUS_PIN_DESC(13, "gpio1", 0, 0, 0),
175 CYGNUS_PIN_DESC(14, "gpio2", 0, 0, 0),
176 CYGNUS_PIN_DESC(15, "gpio3", 0, 0, 0),
177 CYGNUS_PIN_DESC(16, "gpio4", 0, 0, 0),
178 CYGNUS_PIN_DESC(17, "gpio5", 0, 0, 0),
179 CYGNUS_PIN_DESC(18, "gpio6", 0, 0, 0),
180 CYGNUS_PIN_DESC(19, "gpio7", 0, 0, 0),
181 CYGNUS_PIN_DESC(20, "gpio8", 0, 0, 0),
182 CYGNUS_PIN_DESC(21, "gpio9", 0, 0, 0),
183 CYGNUS_PIN_DESC(22, "gpio10", 0, 0, 0),
184 CYGNUS_PIN_DESC(23, "gpio11", 0, 0, 0),
185 CYGNUS_PIN_DESC(24, "gpio12", 0, 0, 0),
186 CYGNUS_PIN_DESC(25, "gpio13", 0, 0, 0),
187 CYGNUS_PIN_DESC(26, "gpio14", 0, 0, 0),
188 CYGNUS_PIN_DESC(27, "gpio15", 0, 0, 0),
189 CYGNUS_PIN_DESC(28, "gpio16", 0, 0, 0),
190 CYGNUS_PIN_DESC(29, "gpio17", 0, 0, 0),
191 CYGNUS_PIN_DESC(30, "gpio18", 0, 0, 0),
192 CYGNUS_PIN_DESC(31, "gpio19", 0, 0, 0),
193 CYGNUS_PIN_DESC(32, "gpio20", 0, 0, 0),
194 CYGNUS_PIN_DESC(33, "gpio21", 0, 0, 0),
195 CYGNUS_PIN_DESC(34, "gpio22", 0, 0, 0),
196 CYGNUS_PIN_DESC(35, "gpio23", 0, 0, 0),
197 CYGNUS_PIN_DESC(36, "mdc", 0, 0, 0),
198 CYGNUS_PIN_DESC(37, "mdio", 0, 0, 0),
199 CYGNUS_PIN_DESC(38, "pwm0", 1, 0x10, 30),
200 CYGNUS_PIN_DESC(39, "pwm1", 1, 0x10, 28),
201 CYGNUS_PIN_DESC(40, "pwm2", 1, 0x10, 26),
202 CYGNUS_PIN_DESC(41, "pwm3", 1, 0x10, 24),
203 CYGNUS_PIN_DESC(42, "sc0_clk", 1, 0x10, 22),
204 CYGNUS_PIN_DESC(43, "sc0_cmdvcc_l", 1, 0x10, 20),
205 CYGNUS_PIN_DESC(44, "sc0_detect", 1, 0x10, 18),
206 CYGNUS_PIN_DESC(45, "sc0_fcb", 1, 0x10, 16),
207 CYGNUS_PIN_DESC(46, "sc0_io", 1, 0x10, 14),
208 CYGNUS_PIN_DESC(47, "sc0_rst_l", 1, 0x10, 12),
209 CYGNUS_PIN_DESC(48, "sc1_clk", 1, 0x10, 10),
210 CYGNUS_PIN_DESC(49, "sc1_cmdvcc_l", 1, 0x10, 8),
211 CYGNUS_PIN_DESC(50, "sc1_detect", 1, 0x10, 6),
212 CYGNUS_PIN_DESC(51, "sc1_fcb", 1, 0x10, 4),
213 CYGNUS_PIN_DESC(52, "sc1_io", 1, 0x10, 2),
214 CYGNUS_PIN_DESC(53, "sc1_rst_l", 1, 0x10, 0),
215 CYGNUS_PIN_DESC(54, "spi0_clk", 1, 0x18, 10),
216 CYGNUS_PIN_DESC(55, "spi0_mosi", 1, 0x18, 6),
217 CYGNUS_PIN_DESC(56, "spi0_miso", 1, 0x18, 8),
218 CYGNUS_PIN_DESC(57, "spi0_ss", 1, 0x18, 4),
219 CYGNUS_PIN_DESC(58, "spi1_clk", 1, 0x18, 2),
220 CYGNUS_PIN_DESC(59, "spi1_mosi", 1, 0x1c, 30),
221 CYGNUS_PIN_DESC(60, "spi1_miso", 1, 0x18, 0),
222 CYGNUS_PIN_DESC(61, "spi1_ss", 1, 0x1c, 28),
223 CYGNUS_PIN_DESC(62, "spi2_clk", 1, 0x1c, 26),
224 CYGNUS_PIN_DESC(63, "spi2_mosi", 1, 0x1c, 22),
225 CYGNUS_PIN_DESC(64, "spi2_miso", 1, 0x1c, 24),
226 CYGNUS_PIN_DESC(65, "spi2_ss", 1, 0x1c, 20),
227 CYGNUS_PIN_DESC(66, "spi3_clk", 1, 0x1c, 18),
228 CYGNUS_PIN_DESC(67, "spi3_mosi", 1, 0x1c, 14),
229 CYGNUS_PIN_DESC(68, "spi3_miso", 1, 0x1c, 16),
230 CYGNUS_PIN_DESC(69, "spi3_ss", 1, 0x1c, 12),
231 CYGNUS_PIN_DESC(70, "uart0_cts", 1, 0x1c, 10),
232 CYGNUS_PIN_DESC(71, "uart0_rts", 1, 0x1c, 8),
233 CYGNUS_PIN_DESC(72, "uart0_rx", 1, 0x1c, 6),
234 CYGNUS_PIN_DESC(73, "uart0_tx", 1, 0x1c, 4),
235 CYGNUS_PIN_DESC(74, "uart1_cts", 1, 0x1c, 2),
236 CYGNUS_PIN_DESC(75, "uart1_dcd", 1, 0x1c, 0),
237 CYGNUS_PIN_DESC(76, "uart1_dsr", 1, 0x20, 14),
238 CYGNUS_PIN_DESC(77, "uart1_dtr", 1, 0x20, 12),
239 CYGNUS_PIN_DESC(78, "uart1_ri", 1, 0x20, 10),
240 CYGNUS_PIN_DESC(79, "uart1_rts", 1, 0x20, 8),
241 CYGNUS_PIN_DESC(80, "uart1_rx", 1, 0x20, 6),
242 CYGNUS_PIN_DESC(81, "uart1_tx", 1, 0x20, 4),
243 CYGNUS_PIN_DESC(82, "uart3_rx", 1, 0x20, 2),
244 CYGNUS_PIN_DESC(83, "uart3_tx", 1, 0x20, 0),
245 CYGNUS_PIN_DESC(84, "sdio1_clk_sdcard", 1, 0x14, 6),
246 CYGNUS_PIN_DESC(85, "sdio1_cmd", 1, 0x14, 4),
247 CYGNUS_PIN_DESC(86, "sdio1_data0", 1, 0x14, 2),
248 CYGNUS_PIN_DESC(87, "sdio1_data1", 1, 0x14, 0),
249 CYGNUS_PIN_DESC(88, "sdio1_data2", 1, 0x18, 30),
250 CYGNUS_PIN_DESC(89, "sdio1_data3", 1, 0x18, 28),
251 CYGNUS_PIN_DESC(90, "sdio1_wp_n", 1, 0x18, 24),
252 CYGNUS_PIN_DESC(91, "sdio1_card_rst", 1, 0x14, 10),
253 CYGNUS_PIN_DESC(92, "sdio1_led_on", 1, 0x18, 26),
254 CYGNUS_PIN_DESC(93, "sdio1_cd", 1, 0x14, 8),
255 CYGNUS_PIN_DESC(94, "sdio0_clk_sdcard", 1, 0x14, 26),
256 CYGNUS_PIN_DESC(95, "sdio0_cmd", 1, 0x14, 24),
257 CYGNUS_PIN_DESC(96, "sdio0_data0", 1, 0x14, 22),
258 CYGNUS_PIN_DESC(97, "sdio0_data1", 1, 0x14, 20),
259 CYGNUS_PIN_DESC(98, "sdio0_data2", 1, 0x14, 18),
260 CYGNUS_PIN_DESC(99, "sdio0_data3", 1, 0x14, 16),
261 CYGNUS_PIN_DESC(100, "sdio0_wp_n", 1, 0x14, 12),
262 CYGNUS_PIN_DESC(101, "sdio0_card_rst", 1, 0x14, 30),
263 CYGNUS_PIN_DESC(102, "sdio0_led_on", 1, 0x14, 14),
264 CYGNUS_PIN_DESC(103, "sdio0_cd", 1, 0x14, 28),
265 CYGNUS_PIN_DESC(104, "sflash_clk", 1, 0x18, 22),
266 CYGNUS_PIN_DESC(105, "sflash_cs_l", 1, 0x18, 20),
267 CYGNUS_PIN_DESC(106, "sflash_mosi", 1, 0x18, 14),
268 CYGNUS_PIN_DESC(107, "sflash_miso", 1, 0x18, 16),
269 CYGNUS_PIN_DESC(108, "sflash_wp_n", 1, 0x18, 12),
270 CYGNUS_PIN_DESC(109, "sflash_hold_n", 1, 0x18, 18),
271 CYGNUS_PIN_DESC(110, "nand_ale", 1, 0xc, 30),
272 CYGNUS_PIN_DESC(111, "nand_ce0_l", 1, 0xc, 28),
273 CYGNUS_PIN_DESC(112, "nand_ce1_l", 1, 0xc, 26),
274 CYGNUS_PIN_DESC(113, "nand_cle", 1, 0xc, 24),
275 CYGNUS_PIN_DESC(114, "nand_dq0", 1, 0xc, 22),
276 CYGNUS_PIN_DESC(115, "nand_dq1", 1, 0xc, 20),
277 CYGNUS_PIN_DESC(116, "nand_dq2", 1, 0xc, 18),
278 CYGNUS_PIN_DESC(117, "nand_dq3", 1, 0xc, 16),
279 CYGNUS_PIN_DESC(118, "nand_dq4", 1, 0xc, 14),
280 CYGNUS_PIN_DESC(119, "nand_dq5", 1, 0xc, 12),
281 CYGNUS_PIN_DESC(120, "nand_dq6", 1, 0xc, 10),
282 CYGNUS_PIN_DESC(121, "nand_dq7", 1, 0xc, 8),
283 CYGNUS_PIN_DESC(122, "nand_rb_l", 1, 0xc, 6),
284 CYGNUS_PIN_DESC(123, "nand_re_l", 1, 0xc, 4),
285 CYGNUS_PIN_DESC(124, "nand_we_l", 1, 0xc, 2),
286 CYGNUS_PIN_DESC(125, "nand_wp_l", 1, 0xc, 0),
287 CYGNUS_PIN_DESC(126, "lcd_clac", 1, 0x4, 26),
288 CYGNUS_PIN_DESC(127, "lcd_clcp", 1, 0x4, 24),
289 CYGNUS_PIN_DESC(128, "lcd_cld0", 1, 0x4, 22),
290 CYGNUS_PIN_DESC(129, "lcd_cld1", 1, 0x4, 0),
291 CYGNUS_PIN_DESC(130, "lcd_cld10", 1, 0x4, 20),
292 CYGNUS_PIN_DESC(131, "lcd_cld11", 1, 0x4, 18),
293 CYGNUS_PIN_DESC(132, "lcd_cld12", 1, 0x4, 16),
294 CYGNUS_PIN_DESC(133, "lcd_cld13", 1, 0x4, 14),
295 CYGNUS_PIN_DESC(134, "lcd_cld14", 1, 0x4, 12),
296 CYGNUS_PIN_DESC(135, "lcd_cld15", 1, 0x4, 10),
297 CYGNUS_PIN_DESC(136, "lcd_cld16", 1, 0x4, 8),
298 CYGNUS_PIN_DESC(137, "lcd_cld17", 1, 0x4, 6),
299 CYGNUS_PIN_DESC(138, "lcd_cld18", 1, 0x4, 4),
300 CYGNUS_PIN_DESC(139, "lcd_cld19", 1, 0x4, 2),
301 CYGNUS_PIN_DESC(140, "lcd_cld2", 1, 0x8, 22),
302 CYGNUS_PIN_DESC(141, "lcd_cld20", 1, 0x8, 30),
303 CYGNUS_PIN_DESC(142, "lcd_cld21", 1, 0x8, 28),
304 CYGNUS_PIN_DESC(143, "lcd_cld22", 1, 0x8, 26),
305 CYGNUS_PIN_DESC(144, "lcd_cld23", 1, 0x8, 24),
306 CYGNUS_PIN_DESC(145, "lcd_cld3", 1, 0x8, 20),
307 CYGNUS_PIN_DESC(146, "lcd_cld4", 1, 0x8, 18),
308 CYGNUS_PIN_DESC(147, "lcd_cld5", 1, 0x8, 16),
309 CYGNUS_PIN_DESC(148, "lcd_cld6", 1, 0x8, 14),
310 CYGNUS_PIN_DESC(149, "lcd_cld7", 1, 0x8, 12),
311 CYGNUS_PIN_DESC(150, "lcd_cld8", 1, 0x8, 10),
312 CYGNUS_PIN_DESC(151, "lcd_cld9", 1, 0x8, 8),
313 CYGNUS_PIN_DESC(152, "lcd_clfp", 1, 0x8, 6),
314 CYGNUS_PIN_DESC(153, "lcd_clle", 1, 0x8, 4),
315 CYGNUS_PIN_DESC(154, "lcd_cllp", 1, 0x8, 2),
316 CYGNUS_PIN_DESC(155, "lcd_clpower", 1, 0x8, 0),
317 CYGNUS_PIN_DESC(156, "camera_vsync", 1, 0x4, 30),
318 CYGNUS_PIN_DESC(157, "camera_trigger", 1, 0x0, 0),
319 CYGNUS_PIN_DESC(158, "camera_strobe", 1, 0x0, 2),
320 CYGNUS_PIN_DESC(159, "camera_standby", 1, 0x0, 4),
321 CYGNUS_PIN_DESC(160, "camera_reset_n", 1, 0x0, 6),
322 CYGNUS_PIN_DESC(161, "camera_pixdata9", 1, 0x0, 8),
323 CYGNUS_PIN_DESC(162, "camera_pixdata8", 1, 0x0, 10),
324 CYGNUS_PIN_DESC(163, "camera_pixdata7", 1, 0x0, 12),
325 CYGNUS_PIN_DESC(164, "camera_pixdata6", 1, 0x0, 14),
326 CYGNUS_PIN_DESC(165, "camera_pixdata5", 1, 0x0, 16),
327 CYGNUS_PIN_DESC(166, "camera_pixdata4", 1, 0x0, 18),
328 CYGNUS_PIN_DESC(167, "camera_pixdata3", 1, 0x0, 20),
329 CYGNUS_PIN_DESC(168, "camera_pixdata2", 1, 0x0, 22),
330 CYGNUS_PIN_DESC(169, "camera_pixdata1", 1, 0x0, 24),
331 CYGNUS_PIN_DESC(170, "camera_pixdata0", 1, 0x0, 26),
332 CYGNUS_PIN_DESC(171, "camera_pixclk", 1, 0x0, 28),
333 CYGNUS_PIN_DESC(172, "camera_hsync", 1, 0x0, 30),
334 CYGNUS_PIN_DESC(173, "camera_pll_ref_clk", 0, 0, 0),
335 CYGNUS_PIN_DESC(174, "usb_id_indication", 0, 0, 0),
336 CYGNUS_PIN_DESC(175, "usb_vbus_indication", 0, 0, 0),
337 CYGNUS_PIN_DESC(176, "gpio0_3p3", 0, 0, 0),
338 CYGNUS_PIN_DESC(177, "gpio1_3p3", 0, 0, 0),
339 CYGNUS_PIN_DESC(178, "gpio2_3p3", 0, 0, 0),
340 CYGNUS_PIN_DESC(179, "gpio3_3p3", 0, 0, 0),
341};
342
343/*
344 * List of groups of pins
345 */
346static const unsigned bsc1_pins[] = { 8, 9 };
347static const unsigned pcie_clkreq_pins[] = { 8, 9 };
348
349static const unsigned i2s2_0_pins[] = { 12 };
350static const unsigned i2s2_1_pins[] = { 13 };
351static const unsigned i2s2_2_pins[] = { 14 };
352static const unsigned i2s2_3_pins[] = { 15 };
353static const unsigned i2s2_4_pins[] = { 16 };
354
355static const unsigned pwm4_pins[] = { 17 };
356static const unsigned pwm5_pins[] = { 18 };
357
358static const unsigned key0_pins[] = { 20 };
359static const unsigned key1_pins[] = { 21 };
360static const unsigned key2_pins[] = { 22 };
361static const unsigned key3_pins[] = { 23 };
362static const unsigned key4_pins[] = { 24 };
363static const unsigned key5_pins[] = { 25 };
364
365static const unsigned key6_pins[] = { 26 };
366static const unsigned audio_dte0_pins[] = { 26 };
367
368static const unsigned key7_pins[] = { 27 };
369static const unsigned audio_dte1_pins[] = { 27 };
370
371static const unsigned key8_pins[] = { 28 };
372static const unsigned key9_pins[] = { 29 };
373static const unsigned key10_pins[] = { 30 };
374static const unsigned key11_pins[] = { 31 };
375static const unsigned key12_pins[] = { 32 };
376static const unsigned key13_pins[] = { 33 };
377
378static const unsigned key14_pins[] = { 34 };
379static const unsigned audio_dte2_pins[] = { 34 };
380
381static const unsigned key15_pins[] = { 35 };
382static const unsigned audio_dte3_pins[] = { 35 };
383
384static const unsigned pwm0_pins[] = { 38 };
385static const unsigned pwm1_pins[] = { 39 };
386static const unsigned pwm2_pins[] = { 40 };
387static const unsigned pwm3_pins[] = { 41 };
388
389static const unsigned sdio0_pins[] = { 94, 95, 96, 97, 98, 99 };
390
391static const unsigned smart_card0_pins[] = { 42, 43, 44, 46, 47 };
392static const unsigned i2s0_0_pins[] = { 42, 43, 44, 46 };
393static const unsigned spdif_pins[] = { 47 };
394
395static const unsigned smart_card1_pins[] = { 48, 49, 50, 52, 53 };
396static const unsigned i2s1_0_pins[] = { 48, 49, 50, 52 };
397
398static const unsigned spi0_pins[] = { 54, 55, 56, 57 };
399
400static const unsigned spi1_pins[] = { 58, 59, 60, 61 };
401
402static const unsigned spi2_pins[] = { 62, 63, 64, 65 };
403
404static const unsigned spi3_pins[] = { 66, 67, 68, 69 };
405static const unsigned sw_led0_0_pins[] = { 66, 67, 68, 69 };
406
407static const unsigned d1w_pins[] = { 10, 11 };
408static const unsigned uart4_pins[] = { 10, 11 };
409static const unsigned sw_led2_0_pins[] = { 10, 11 };
410
411static const unsigned lcd_pins[] = { 126, 127, 128, 129, 130, 131, 132, 133,
412 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,
413 148, 149, 150, 151, 152, 153, 154, 155 };
414static const unsigned sram_0_pins[] = { 126, 127, 128, 129, 130, 131, 132, 133,
415 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,
416 148, 149, 150, 151, 152, 153, 154, 155 };
417static const unsigned spi5_pins[] = { 141, 142, 143, 144 };
418
419static const unsigned uart0_pins[] = { 70, 71, 72, 73 };
420static const unsigned sw_led0_1_pins[] = { 70, 71, 72, 73 };
421
422static const unsigned uart1_dte_pins[] = { 75, 76, 77, 78 };
423static const unsigned uart2_pins[] = { 75, 76, 77, 78 };
424
425static const unsigned uart1_pins[] = { 74, 79, 80, 81 };
426
427static const unsigned uart3_pins[] = { 82, 83 };
428
429static const unsigned qspi_0_pins[] = { 104, 105, 106, 107 };
430
431static const unsigned nand_pins[] = { 110, 111, 112, 113, 114, 115, 116, 117,
432 118, 119, 120, 121, 122, 123, 124, 125 };
433
434static const unsigned sdio0_cd_pins[] = { 103 };
435
436static const unsigned sdio0_mmc_pins[] = { 100, 101, 102 };
437
438static const unsigned sdio1_data_0_pins[] = { 86, 87 };
439static const unsigned can0_pins[] = { 86, 87 };
440static const unsigned spi4_0_pins[] = { 86, 87 };
441
442static const unsigned sdio1_data_1_pins[] = { 88, 89 };
443static const unsigned can1_pins[] = { 88, 89 };
444static const unsigned spi4_1_pins[] = { 88, 89 };
445
446static const unsigned sdio1_cd_pins[] = { 93 };
447
448static const unsigned sdio1_led_pins[] = { 84, 85 };
449static const unsigned sw_led2_1_pins[] = { 84, 85 };
450
451static const unsigned sdio1_mmc_pins[] = { 90, 91, 92 };
452
453static const unsigned cam_led_pins[] = { 156, 157, 158, 159, 160 };
454static const unsigned sw_led1_pins[] = { 156, 157, 158, 159 };
455
456static const unsigned cam_0_pins[] = { 169, 170, 171, 169, 170 };
457
458static const unsigned cam_1_pins[] = { 161, 162, 163, 164, 165, 166, 167,
459 168 };
460static const unsigned sram_1_pins[] = { 161, 162, 163, 164, 165, 166, 167,
461 168 };
462
463static const unsigned qspi_1_pins[] = { 108, 109 };
464
465static const unsigned smart_card0_fcb_pins[] = { 45 };
466static const unsigned i2s0_1_pins[] = { 45 };
467
468static const unsigned smart_card1_fcb_pins[] = { 51 };
469static const unsigned i2s1_1_pins[] = { 51 };
470
471static const unsigned gpio0_3p3_pins[] = { 176 };
472static const unsigned usb0_oc_pins[] = { 176 };
473
474static const unsigned gpio1_3p3_pins[] = { 177 };
475static const unsigned usb1_oc_pins[] = { 177 };
476
477static const unsigned gpio2_3p3_pins[] = { 178 };
478static const unsigned usb2_oc_pins[] = { 178 };
479
480#define CYGNUS_PIN_GROUP(group_name, off, sh, al) \
481{ \
482 .name = __stringify(group_name) "_grp", \
483 .pins = group_name ## _pins, \
484 .num_pins = ARRAY_SIZE(group_name ## _pins), \
485 .mux = { \
486 .offset = off, \
487 .shift = sh, \
488 .alt = al, \
489 } \
490}
491
492/*
493 * List of Cygnus pin groups
494 */
495static const struct cygnus_pin_group cygnus_pin_groups[] = {
496 CYGNUS_PIN_GROUP(i2s2_0, 0x0, 0, 2),
497 CYGNUS_PIN_GROUP(i2s2_1, 0x0, 4, 2),
498 CYGNUS_PIN_GROUP(i2s2_2, 0x0, 8, 2),
499 CYGNUS_PIN_GROUP(i2s2_3, 0x0, 12, 2),
500 CYGNUS_PIN_GROUP(i2s2_4, 0x0, 16, 2),
501 CYGNUS_PIN_GROUP(pwm4, 0x0, 20, 0),
502 CYGNUS_PIN_GROUP(pwm5, 0x0, 24, 2),
503 CYGNUS_PIN_GROUP(key0, 0x4, 0, 1),
504 CYGNUS_PIN_GROUP(key1, 0x4, 4, 1),
505 CYGNUS_PIN_GROUP(key2, 0x4, 8, 1),
506 CYGNUS_PIN_GROUP(key3, 0x4, 12, 1),
507 CYGNUS_PIN_GROUP(key4, 0x4, 16, 1),
508 CYGNUS_PIN_GROUP(key5, 0x4, 20, 1),
509 CYGNUS_PIN_GROUP(key6, 0x4, 24, 1),
510 CYGNUS_PIN_GROUP(audio_dte0, 0x4, 24, 2),
511 CYGNUS_PIN_GROUP(key7, 0x4, 28, 1),
512 CYGNUS_PIN_GROUP(audio_dte1, 0x4, 28, 2),
513 CYGNUS_PIN_GROUP(key8, 0x8, 0, 1),
514 CYGNUS_PIN_GROUP(key9, 0x8, 4, 1),
515 CYGNUS_PIN_GROUP(key10, 0x8, 8, 1),
516 CYGNUS_PIN_GROUP(key11, 0x8, 12, 1),
517 CYGNUS_PIN_GROUP(key12, 0x8, 16, 1),
518 CYGNUS_PIN_GROUP(key13, 0x8, 20, 1),
519 CYGNUS_PIN_GROUP(key14, 0x8, 24, 1),
520 CYGNUS_PIN_GROUP(audio_dte2, 0x8, 24, 2),
521 CYGNUS_PIN_GROUP(key15, 0x8, 28, 1),
522 CYGNUS_PIN_GROUP(audio_dte3, 0x8, 28, 2),
523 CYGNUS_PIN_GROUP(pwm0, 0xc, 0, 0),
524 CYGNUS_PIN_GROUP(pwm1, 0xc, 4, 0),
525 CYGNUS_PIN_GROUP(pwm2, 0xc, 8, 0),
526 CYGNUS_PIN_GROUP(pwm3, 0xc, 12, 0),
527 CYGNUS_PIN_GROUP(sdio0, 0xc, 16, 0),
528 CYGNUS_PIN_GROUP(smart_card0, 0xc, 20, 0),
529 CYGNUS_PIN_GROUP(i2s0_0, 0xc, 20, 1),
530 CYGNUS_PIN_GROUP(spdif, 0xc, 20, 1),
531 CYGNUS_PIN_GROUP(smart_card1, 0xc, 24, 0),
532 CYGNUS_PIN_GROUP(i2s1_0, 0xc, 24, 1),
533 CYGNUS_PIN_GROUP(spi0, 0x10, 0, 0),
534 CYGNUS_PIN_GROUP(spi1, 0x10, 4, 0),
535 CYGNUS_PIN_GROUP(spi2, 0x10, 8, 0),
536 CYGNUS_PIN_GROUP(spi3, 0x10, 12, 0),
537 CYGNUS_PIN_GROUP(sw_led0_0, 0x10, 12, 2),
538 CYGNUS_PIN_GROUP(d1w, 0x10, 16, 0),
539 CYGNUS_PIN_GROUP(uart4, 0x10, 16, 1),
540 CYGNUS_PIN_GROUP(sw_led2_0, 0x10, 16, 2),
541 CYGNUS_PIN_GROUP(lcd, 0x10, 20, 0),
542 CYGNUS_PIN_GROUP(sram_0, 0x10, 20, 1),
543 CYGNUS_PIN_GROUP(spi5, 0x10, 20, 2),
544 CYGNUS_PIN_GROUP(uart0, 0x14, 0, 0),
545 CYGNUS_PIN_GROUP(sw_led0_1, 0x14, 0, 2),
546 CYGNUS_PIN_GROUP(uart1_dte, 0x14, 4, 0),
547 CYGNUS_PIN_GROUP(uart2, 0x14, 4, 1),
548 CYGNUS_PIN_GROUP(uart1, 0x14, 8, 0),
549 CYGNUS_PIN_GROUP(uart3, 0x14, 12, 0),
550 CYGNUS_PIN_GROUP(qspi_0, 0x14, 16, 0),
551 CYGNUS_PIN_GROUP(nand, 0x14, 20, 0),
552 CYGNUS_PIN_GROUP(sdio0_cd, 0x18, 0, 0),
553 CYGNUS_PIN_GROUP(sdio0_mmc, 0x18, 4, 0),
554 CYGNUS_PIN_GROUP(sdio1_data_0, 0x18, 8, 0),
555 CYGNUS_PIN_GROUP(can0, 0x18, 8, 1),
556 CYGNUS_PIN_GROUP(spi4_0, 0x18, 8, 2),
557 CYGNUS_PIN_GROUP(sdio1_data_1, 0x18, 12, 0),
558 CYGNUS_PIN_GROUP(can1, 0x18, 12, 1),
559 CYGNUS_PIN_GROUP(spi4_1, 0x18, 12, 2),
560 CYGNUS_PIN_GROUP(sdio1_cd, 0x18, 16, 0),
561 CYGNUS_PIN_GROUP(sdio1_led, 0x18, 20, 0),
562 CYGNUS_PIN_GROUP(sw_led2_1, 0x18, 20, 2),
563 CYGNUS_PIN_GROUP(sdio1_mmc, 0x18, 24, 0),
564 CYGNUS_PIN_GROUP(cam_led, 0x1c, 0, 0),
565 CYGNUS_PIN_GROUP(sw_led1, 0x1c, 0, 1),
566 CYGNUS_PIN_GROUP(cam_0, 0x1c, 4, 0),
567 CYGNUS_PIN_GROUP(cam_1, 0x1c, 8, 0),
568 CYGNUS_PIN_GROUP(sram_1, 0x1c, 8, 1),
569 CYGNUS_PIN_GROUP(qspi_1, 0x1c, 12, 0),
570 CYGNUS_PIN_GROUP(bsc1, 0x1c, 16, 0),
571 CYGNUS_PIN_GROUP(pcie_clkreq, 0x1c, 16, 1),
572 CYGNUS_PIN_GROUP(smart_card0_fcb, 0x20, 0, 0),
573 CYGNUS_PIN_GROUP(i2s0_1, 0x20, 0, 1),
574 CYGNUS_PIN_GROUP(smart_card1_fcb, 0x20, 4, 0),
575 CYGNUS_PIN_GROUP(i2s1_1, 0x20, 4, 1),
576 CYGNUS_PIN_GROUP(gpio0_3p3, 0x28, 0, 0),
577 CYGNUS_PIN_GROUP(usb0_oc, 0x28, 0, 1),
578 CYGNUS_PIN_GROUP(gpio1_3p3, 0x28, 4, 0),
579 CYGNUS_PIN_GROUP(usb1_oc, 0x28, 4, 1),
580 CYGNUS_PIN_GROUP(gpio2_3p3, 0x28, 8, 0),
581 CYGNUS_PIN_GROUP(usb2_oc, 0x28, 8, 1),
582};
583
584/*
585 * List of groups supported by functions
586 */
587static const char * const i2s0_grps[] = { "i2s0_0_grp", "i2s0_1_grp" };
588static const char * const i2s1_grps[] = { "i2s1_0_grp", "i2s1_1_grp" };
589static const char * const i2s2_grps[] = { "i2s2_0_grp", "i2s2_1_grp",
590 "i2s2_2_grp", "i2s2_3_grp", "i2s2_4_grp" };
591static const char * const spdif_grps[] = { "spdif_grp" };
592static const char * const pwm0_grps[] = { "pwm0_grp" };
593static const char * const pwm1_grps[] = { "pwm1_grp" };
594static const char * const pwm2_grps[] = { "pwm2_grp" };
595static const char * const pwm3_grps[] = { "pwm3_grp" };
596static const char * const pwm4_grps[] = { "pwm4_grp" };
597static const char * const pwm5_grps[] = { "pwm5_grp" };
598static const char * const key_grps[] = { "key0_grp", "key1_grp", "key2_grp",
599 "key3_grp", "key4_grp", "key5_grp", "key6_grp", "key7_grp", "key8_grp",
600 "key9_grp", "key10_grp", "key11_grp", "key12_grp", "key13_grp",
601 "key14_grp", "key15_grp" };
602static const char * const audio_dte_grps[] = { "audio_dte0_grp",
603 "audio_dte1_grp", "audio_dte2_grp", "audio_dte3_grp" };
604static const char * const smart_card0_grps[] = { "smart_card0_grp",
605 "smart_card0_fcb_grp" };
606static const char * const smart_card1_grps[] = { "smart_card1_grp",
607 "smart_card1_fcb_grp" };
608static const char * const spi0_grps[] = { "spi0_grp" };
609static const char * const spi1_grps[] = { "spi1_grp" };
610static const char * const spi2_grps[] = { "spi2_grp" };
611static const char * const spi3_grps[] = { "spi3_grp" };
612static const char * const spi4_grps[] = { "spi4_0_grp", "spi4_1_grp" };
613static const char * const spi5_grps[] = { "spi5_grp" };
614
615static const char * const sw_led0_grps[] = { "sw_led0_0_grp",
616 "sw_led0_1_grp" };
617static const char * const sw_led1_grps[] = { "sw_led1_grp" };
618static const char * const sw_led2_grps[] = { "sw_led2_0_grp",
619 "sw_led2_1_grp" };
620static const char * const d1w_grps[] = { "d1w_grp" };
621static const char * const lcd_grps[] = { "lcd_grp" };
622static const char * const sram_grps[] = { "sram_0_grp", "sram_1_grp" };
623
624static const char * const uart0_grps[] = { "uart0_grp" };
625static const char * const uart1_grps[] = { "uart1_grp", "uart1_dte_grp" };
626static const char * const uart2_grps[] = { "uart2_grp" };
627static const char * const uart3_grps[] = { "uart3_grp" };
628static const char * const uart4_grps[] = { "uart4_grp" };
629static const char * const qspi_grps[] = { "qspi_0_grp", "qspi_1_grp" };
630static const char * const nand_grps[] = { "nand_grp" };
631static const char * const sdio0_grps[] = { "sdio0_grp", "sdio0_cd_grp",
632 "sdio0_mmc_grp" };
633static const char * const sdio1_grps[] = { "sdio1_data_0_grp",
634 "sdio1_data_1_grp", "sdio1_cd_grp", "sdio1_led_grp", "sdio1_mmc_grp" };
635static const char * const can0_grps[] = { "can0_grp" };
636static const char * const can1_grps[] = { "can1_grp" };
637static const char * const cam_grps[] = { "cam_led_grp", "cam_0_grp",
638 "cam_1_grp" };
639static const char * const bsc1_grps[] = { "bsc1_grp" };
640static const char * const pcie_clkreq_grps[] = { "pcie_clkreq_grp" };
641static const char * const usb0_oc_grps[] = { "usb0_oc_grp" };
642static const char * const usb1_oc_grps[] = { "usb1_oc_grp" };
643static const char * const usb2_oc_grps[] = { "usb2_oc_grp" };
644
645#define CYGNUS_PIN_FUNCTION(func) \
646{ \
647 .name = #func, \
648 .groups = func ## _grps, \
649 .num_groups = ARRAY_SIZE(func ## _grps), \
650}
651
652/*
653 * List of supported functions in Cygnus
654 */
655static const struct cygnus_pin_function cygnus_pin_functions[] = {
656 CYGNUS_PIN_FUNCTION(i2s0),
657 CYGNUS_PIN_FUNCTION(i2s1),
658 CYGNUS_PIN_FUNCTION(i2s2),
659 CYGNUS_PIN_FUNCTION(spdif),
660 CYGNUS_PIN_FUNCTION(pwm0),
661 CYGNUS_PIN_FUNCTION(pwm1),
662 CYGNUS_PIN_FUNCTION(pwm2),
663 CYGNUS_PIN_FUNCTION(pwm3),
664 CYGNUS_PIN_FUNCTION(pwm4),
665 CYGNUS_PIN_FUNCTION(pwm5),
666 CYGNUS_PIN_FUNCTION(key),
667 CYGNUS_PIN_FUNCTION(audio_dte),
668 CYGNUS_PIN_FUNCTION(smart_card0),
669 CYGNUS_PIN_FUNCTION(smart_card1),
670 CYGNUS_PIN_FUNCTION(spi0),
671 CYGNUS_PIN_FUNCTION(spi1),
672 CYGNUS_PIN_FUNCTION(spi2),
673 CYGNUS_PIN_FUNCTION(spi3),
674 CYGNUS_PIN_FUNCTION(spi4),
675 CYGNUS_PIN_FUNCTION(spi5),
676 CYGNUS_PIN_FUNCTION(sw_led0),
677 CYGNUS_PIN_FUNCTION(sw_led1),
678 CYGNUS_PIN_FUNCTION(sw_led2),
679 CYGNUS_PIN_FUNCTION(d1w),
680 CYGNUS_PIN_FUNCTION(lcd),
681 CYGNUS_PIN_FUNCTION(sram),
682 CYGNUS_PIN_FUNCTION(uart0),
683 CYGNUS_PIN_FUNCTION(uart1),
684 CYGNUS_PIN_FUNCTION(uart2),
685 CYGNUS_PIN_FUNCTION(uart3),
686 CYGNUS_PIN_FUNCTION(uart4),
687 CYGNUS_PIN_FUNCTION(qspi),
688 CYGNUS_PIN_FUNCTION(nand),
689 CYGNUS_PIN_FUNCTION(sdio0),
690 CYGNUS_PIN_FUNCTION(sdio1),
691 CYGNUS_PIN_FUNCTION(can0),
692 CYGNUS_PIN_FUNCTION(can1),
693 CYGNUS_PIN_FUNCTION(cam),
694 CYGNUS_PIN_FUNCTION(bsc1),
695 CYGNUS_PIN_FUNCTION(pcie_clkreq),
696 CYGNUS_PIN_FUNCTION(usb0_oc),
697 CYGNUS_PIN_FUNCTION(usb1_oc),
698 CYGNUS_PIN_FUNCTION(usb2_oc),
699};
700
701static int cygnus_get_groups_count(struct pinctrl_dev *pctrl_dev)
702{
703 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
704
705 return pinctrl->num_groups;
706}
707
708static const char *cygnus_get_group_name(struct pinctrl_dev *pctrl_dev,
709 unsigned selector)
710{
711 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
712
713 return pinctrl->groups[selector].name;
714}
715
716static int cygnus_get_group_pins(struct pinctrl_dev *pctrl_dev,
717 unsigned selector, const unsigned **pins,
718 unsigned *num_pins)
719{
720 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
721
722 *pins = pinctrl->groups[selector].pins;
723 *num_pins = pinctrl->groups[selector].num_pins;
724
725 return 0;
726}
727
728static void cygnus_pin_dbg_show(struct pinctrl_dev *pctrl_dev,
729 struct seq_file *s, unsigned offset)
730{
731 seq_printf(s, " %s", dev_name(pctrl_dev->dev));
732}
733
734static const struct pinctrl_ops cygnus_pinctrl_ops = {
735 .get_groups_count = cygnus_get_groups_count,
736 .get_group_name = cygnus_get_group_name,
737 .get_group_pins = cygnus_get_group_pins,
738 .pin_dbg_show = cygnus_pin_dbg_show,
739 .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
740 .dt_free_map = pinctrl_utils_dt_free_map,
741};
742
743static int cygnus_get_functions_count(struct pinctrl_dev *pctrl_dev)
744{
745 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
746
747 return pinctrl->num_functions;
748}
749
750static const char *cygnus_get_function_name(struct pinctrl_dev *pctrl_dev,
751 unsigned selector)
752{
753 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
754
755 return pinctrl->functions[selector].name;
756}
757
758static int cygnus_get_function_groups(struct pinctrl_dev *pctrl_dev,
759 unsigned selector,
760 const char * const **groups,
761 unsigned * const num_groups)
762{
763 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
764
765 *groups = pinctrl->functions[selector].groups;
766 *num_groups = pinctrl->functions[selector].num_groups;
767
768 return 0;
769}
770
771static int cygnus_pinmux_set(struct cygnus_pinctrl *pinctrl,
772 const struct cygnus_pin_function *func,
773 const struct cygnus_pin_group *grp,
774 struct cygnus_mux_log *mux_log)
775{
776 const struct cygnus_mux *mux = &grp->mux;
777 int i;
778 u32 val, mask = 0x7;
779 unsigned long flags;
780
781 for (i = 0; i < CYGNUS_NUM_IOMUX; i++) {
782 if (mux->offset != mux_log[i].mux.offset ||
783 mux->shift != mux_log[i].mux.shift)
784 continue;
785
786 /* match found if we reach here */
787
788 /* if this is a new configuration, just do it! */
789 if (!mux_log[i].is_configured)
790 break;
791
792 /*
793 * IOMUX has been configured previously and one is trying to
794 * configure it to a different function
795 */
796 if (mux_log[i].mux.alt != mux->alt) {
797 dev_err(pinctrl->dev,
798 "double configuration error detected!\n");
799 dev_err(pinctrl->dev, "func:%s grp:%s\n",
800 func->name, grp->name);
801 return -EINVAL;
802 } else {
803 /*
804 * One tries to configure it to the same function.
805 * Just quit and don't bother
806 */
807 return 0;
808 }
809 }
810
811 mux_log[i].mux.alt = mux->alt;
812 mux_log[i].is_configured = true;
813
814 spin_lock_irqsave(&pinctrl->lock, flags);
815
816 val = readl(pinctrl->base0 + grp->mux.offset);
817 val &= ~(mask << grp->mux.shift);
818 val |= grp->mux.alt << grp->mux.shift;
819 writel(val, pinctrl->base0 + grp->mux.offset);
820
821 spin_unlock_irqrestore(&pinctrl->lock, flags);
822
823 return 0;
824}
825
826static int cygnus_pinmux_set_mux(struct pinctrl_dev *pctrl_dev,
827 unsigned func_select, unsigned grp_select)
828{
829 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
830 const struct cygnus_pin_function *func =
831 &pinctrl->functions[func_select];
832 const struct cygnus_pin_group *grp = &pinctrl->groups[grp_select];
833
834 dev_dbg(pctrl_dev->dev, "func:%u name:%s grp:%u name:%s\n",
835 func_select, func->name, grp_select, grp->name);
836
837 dev_dbg(pctrl_dev->dev, "offset:0x%08x shift:%u alt:%u\n",
838 grp->mux.offset, grp->mux.shift, grp->mux.alt);
839
840 return cygnus_pinmux_set(pinctrl, func, grp, pinctrl->mux_log);
841}
842
843static int cygnus_gpio_request_enable(struct pinctrl_dev *pctrl_dev,
844 struct pinctrl_gpio_range *range,
845 unsigned pin)
846{
847 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
848 const struct cygnus_gpio_mux *mux = pctrl_dev->desc->pins[pin].drv_data;
849 u32 val;
850 unsigned long flags;
851
852 /* not all pins support GPIO pinmux override */
853 if (!mux->is_supported)
854 return -ENOTSUPP;
855
856 spin_lock_irqsave(&pinctrl->lock, flags);
857
858 val = readl(pinctrl->base1 + mux->offset);
859 val |= 0x3 << mux->shift;
860 writel(val, pinctrl->base1 + mux->offset);
861
862 spin_unlock_irqrestore(&pinctrl->lock, flags);
863
864 dev_dbg(pctrl_dev->dev,
865 "gpio request enable pin=%u offset=0x%x shift=%u\n",
866 pin, mux->offset, mux->shift);
867
868 return 0;
869}
870
871static void cygnus_gpio_disable_free(struct pinctrl_dev *pctrl_dev,
872 struct pinctrl_gpio_range *range,
873 unsigned pin)
874{
875 struct cygnus_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
876 struct cygnus_gpio_mux *mux = pctrl_dev->desc->pins[pin].drv_data;
877 u32 val;
878 unsigned long flags;
879
880 if (!mux->is_supported)
881 return;
882
883 spin_lock_irqsave(&pinctrl->lock, flags);
884
885 val = readl(pinctrl->base1 + mux->offset);
886 val &= ~(0x3 << mux->shift);
887 writel(val, pinctrl->base1 + mux->offset);
888
889 spin_unlock_irqrestore(&pinctrl->lock, flags);
890
891 dev_err(pctrl_dev->dev,
892 "gpio disable free pin=%u offset=0x%x shift=%u\n",
893 pin, mux->offset, mux->shift);
894}
895
896static const struct pinmux_ops cygnus_pinmux_ops = {
897 .get_functions_count = cygnus_get_functions_count,
898 .get_function_name = cygnus_get_function_name,
899 .get_function_groups = cygnus_get_function_groups,
900 .set_mux = cygnus_pinmux_set_mux,
901 .gpio_request_enable = cygnus_gpio_request_enable,
902 .gpio_disable_free = cygnus_gpio_disable_free,
903};
904
905static struct pinctrl_desc cygnus_pinctrl_desc = {
906 .name = "cygnus-pinmux",
907 .pctlops = &cygnus_pinctrl_ops,
908 .pmxops = &cygnus_pinmux_ops,
909};
910
911static int cygnus_mux_log_init(struct cygnus_pinctrl *pinctrl)
912{
913 struct cygnus_mux_log *log;
914 unsigned int i, j;
915
916 pinctrl->mux_log = devm_kcalloc(pinctrl->dev, CYGNUS_NUM_IOMUX,
917 sizeof(struct cygnus_mux_log),
918 GFP_KERNEL);
919 if (!pinctrl->mux_log)
920 return -ENOMEM;
921
922 log = pinctrl->mux_log;
923 for (i = 0; i < CYGNUS_NUM_IOMUX_REGS; i++) {
924 for (j = 0; j < CYGNUS_NUM_MUX_PER_REG; j++) {
925 log = &pinctrl->mux_log[i * CYGNUS_NUM_MUX_PER_REG
926 + j];
927 log->mux.offset = i * 4;
928 log->mux.shift = j * 4;
929 log->mux.alt = 0;
930 log->is_configured = false;
931 }
932 }
933
934 return 0;
935}
936
937static int cygnus_pinmux_probe(struct platform_device *pdev)
938{
939 struct cygnus_pinctrl *pinctrl;
940 struct resource *res;
941 int i, ret;
942 struct pinctrl_pin_desc *pins;
943 unsigned num_pins = ARRAY_SIZE(cygnus_pins);
944
945 pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL);
946 if (!pinctrl)
947 return -ENOMEM;
948
949 pinctrl->dev = &pdev->dev;
950 platform_set_drvdata(pdev, pinctrl);
951 spin_lock_init(&pinctrl->lock);
952
953 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
954 pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res);
955 if (IS_ERR(pinctrl->base0)) {
956 dev_err(&pdev->dev, "unable to map I/O space\n");
957 return PTR_ERR(pinctrl->base0);
958 }
959
960 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
961 pinctrl->base1 = devm_ioremap_resource(&pdev->dev, res);
962 if (IS_ERR(pinctrl->base1)) {
963 dev_err(&pdev->dev, "unable to map I/O space\n");
964 return PTR_ERR(pinctrl->base1);
965 }
966
967 ret = cygnus_mux_log_init(pinctrl);
968 if (ret) {
969 dev_err(&pdev->dev, "unable to initialize IOMUX log\n");
970 return ret;
971 }
972
973 pins = devm_kcalloc(&pdev->dev, num_pins, sizeof(*pins), GFP_KERNEL);
974 if (!pins)
975 return -ENOMEM;
976
977 for (i = 0; i < num_pins; i++) {
978 pins[i].number = cygnus_pins[i].pin;
979 pins[i].name = cygnus_pins[i].name;
980 pins[i].drv_data = &cygnus_pins[i].gpio_mux;
981 }
982
983 pinctrl->groups = cygnus_pin_groups;
984 pinctrl->num_groups = ARRAY_SIZE(cygnus_pin_groups);
985 pinctrl->functions = cygnus_pin_functions;
986 pinctrl->num_functions = ARRAY_SIZE(cygnus_pin_functions);
987 cygnus_pinctrl_desc.pins = pins;
988 cygnus_pinctrl_desc.npins = num_pins;
989
990 pinctrl->pctl = pinctrl_register(&cygnus_pinctrl_desc, &pdev->dev,
991 pinctrl);
992 if (!pinctrl->pctl) {
993 dev_err(&pdev->dev, "unable to register Cygnus IOMUX pinctrl\n");
994 return -EINVAL;
995 }
996
997 return 0;
998}
999
1000static const struct of_device_id cygnus_pinmux_of_match[] = {
1001 { .compatible = "brcm,cygnus-pinmux" },
1002 { }
1003};
1004
1005static struct platform_driver cygnus_pinmux_driver = {
1006 .driver = {
1007 .name = "cygnus-pinmux",
1008 .of_match_table = cygnus_pinmux_of_match,
1009 .suppress_bind_attrs = true,
1010 },
1011 .probe = cygnus_pinmux_probe,
1012};
1013
1014static int __init cygnus_pinmux_init(void)
1015{
1016 return platform_driver_register(&cygnus_pinmux_driver);
1017}
1018arch_initcall(cygnus_pinmux_init);
1019
1020MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>");
1021MODULE_DESCRIPTION("Broadcom Cygnus IOMUX driver");
1022MODULE_LICENSE("GPL v2");