diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2016-06-23 06:49:36 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-06-29 03:59:35 -0400 |
commit | 4e80c8f505741cbdef3e10862ea36057e8d85e7c (patch) | |
tree | 0be7bbd8d0782de936659baab556ef7b53ce4494 | |
parent | 11884b18ef0642e08f8a413e55c11d1cd6c62fee (diff) |
pinctrl: intel: Add Intel Merrifield pin controller support
This driver adds pinctrl support for Intel Merrifield. The IP block which is
called Family-Level Interface Shim is a separate entity in SoC. The GPIO driver
(gpio-intel-mid.c) will be updated accordingly to support pinctrl interface.
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/pinctrl/intel/Kconfig | 11 | ||||
-rw-r--r-- | drivers/pinctrl/intel/Makefile | 1 | ||||
-rw-r--r-- | drivers/pinctrl/intel/pinctrl-merrifield.c | 911 |
3 files changed, 923 insertions, 0 deletions
diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 1c74e038b7b0..00fb055a4897 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig | |||
@@ -29,6 +29,17 @@ config PINCTRL_CHERRYVIEW | |||
29 | Cherryview/Braswell pinctrl driver provides an interface that | 29 | Cherryview/Braswell pinctrl driver provides an interface that |
30 | allows configuring of SoC pins and using them as GPIOs. | 30 | allows configuring of SoC pins and using them as GPIOs. |
31 | 31 | ||
32 | config PINCTRL_MERRIFIELD | ||
33 | tristate "Intel Merrifield pinctrl driver" | ||
34 | depends on X86_INTEL_MID | ||
35 | select PINMUX | ||
36 | select PINCONF | ||
37 | select GENERIC_PINCONF | ||
38 | help | ||
39 | Merrifield Family-Level Interface Shim (FLIS) driver provides an | ||
40 | interface that allows configuring of SoC pins and using them as | ||
41 | GPIOs. | ||
42 | |||
32 | config PINCTRL_INTEL | 43 | config PINCTRL_INTEL |
33 | tristate | 44 | tristate |
34 | select PINMUX | 45 | select PINMUX |
diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile index 03bc68e3546c..30803078f09e 100644 --- a/drivers/pinctrl/intel/Makefile +++ b/drivers/pinctrl/intel/Makefile | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o | 3 | obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o |
4 | obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o | 4 | obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o |
5 | obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o | ||
5 | obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o | 6 | obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o |
6 | obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o | 7 | obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o |
7 | obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o | 8 | obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o |
diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c new file mode 100644 index 000000000000..eb4990ff26ca --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c | |||
@@ -0,0 +1,911 @@ | |||
1 | /* | ||
2 | * Intel Merrifield SoC pinctrl driver | ||
3 | * | ||
4 | * Copyright (C) 2016, Intel Corporation | ||
5 | * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/bitops.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/pinctrl/pinconf.h> | ||
17 | #include <linux/pinctrl/pinconf-generic.h> | ||
18 | #include <linux/pinctrl/pinctrl.h> | ||
19 | #include <linux/pinctrl/pinmux.h> | ||
20 | |||
21 | #include "pinctrl-intel.h" | ||
22 | |||
23 | #define MRFLD_FAMILY_NR 64 | ||
24 | #define MRFLD_FAMILY_LEN 0x400 | ||
25 | |||
26 | #define SLEW_OFFSET 0x000 | ||
27 | #define BUFCFG_OFFSET 0x100 | ||
28 | #define MISC_OFFSET 0x300 | ||
29 | |||
30 | #define BUFCFG_PINMODE_SHIFT 0 | ||
31 | #define BUFCFG_PINMODE_MASK GENMASK(2, 0) | ||
32 | #define BUFCFG_PINMODE_GPIO 0 | ||
33 | #define BUFCFG_PUPD_VAL_SHIFT 4 | ||
34 | #define BUFCFG_PUPD_VAL_MASK GENMASK(5, 4) | ||
35 | #define BUFCFG_PUPD_VAL_2K 0 | ||
36 | #define BUFCFG_PUPD_VAL_20K 1 | ||
37 | #define BUFCFG_PUPD_VAL_50K 2 | ||
38 | #define BUFCFG_PUPD_VAL_910 3 | ||
39 | #define BUFCFG_PU_EN BIT(8) | ||
40 | #define BUFCFG_PD_EN BIT(9) | ||
41 | #define BUFCFG_Px_EN_MASK GENMASK(9, 8) | ||
42 | #define BUFCFG_SLEWSEL BIT(10) | ||
43 | #define BUFCFG_OVINEN BIT(12) | ||
44 | #define BUFCFG_OVINEN_EN BIT(13) | ||
45 | #define BUFCFG_OVINEN_MASK GENMASK(13, 12) | ||
46 | #define BUFCFG_OVOUTEN BIT(14) | ||
47 | #define BUFCFG_OVOUTEN_EN BIT(15) | ||
48 | #define BUFCFG_OVOUTEN_MASK GENMASK(15, 14) | ||
49 | #define BUFCFG_INDATAOV_VAL BIT(16) | ||
50 | #define BUFCFG_INDATAOV_EN BIT(17) | ||
51 | #define BUFCFG_INDATAOV_MASK GENMASK(17, 16) | ||
52 | #define BUFCFG_OUTDATAOV_VAL BIT(18) | ||
53 | #define BUFCFG_OUTDATAOV_EN BIT(19) | ||
54 | #define BUFCFG_OUTDATAOV_MASK GENMASK(19, 18) | ||
55 | #define BUFCFG_OD_EN BIT(21) | ||
56 | |||
57 | /** | ||
58 | * struct mrfld_family - Intel pin family description | ||
59 | * @barno: MMIO BAR number where registers for this family reside | ||
60 | * @pin_base: Starting pin of pins in this family | ||
61 | * @npins: Number of pins in this family | ||
62 | * @protected: True if family is protected by access | ||
63 | * @regs: family specific common registers | ||
64 | */ | ||
65 | struct mrfld_family { | ||
66 | unsigned int barno; | ||
67 | unsigned int pin_base; | ||
68 | size_t npins; | ||
69 | bool protected; | ||
70 | void __iomem *regs; | ||
71 | }; | ||
72 | |||
73 | #define MRFLD_FAMILY(b, s, e) \ | ||
74 | { \ | ||
75 | .barno = (b), \ | ||
76 | .pin_base = (s), \ | ||
77 | .npins = (e) - (s) + 1, \ | ||
78 | } | ||
79 | |||
80 | #define MRFLD_FAMILY_PROTECTED(b, s, e) \ | ||
81 | { \ | ||
82 | .barno = (b), \ | ||
83 | .pin_base = (s), \ | ||
84 | .npins = (e) - (s) + 1, \ | ||
85 | .protected = true, \ | ||
86 | } | ||
87 | |||
88 | static const struct pinctrl_pin_desc mrfld_pins[] = { | ||
89 | /* Family 0: OCP2SSC (0 pins) */ | ||
90 | /* Family 1: ULPI (13 pins) */ | ||
91 | PINCTRL_PIN(0, "ULPI_CLK"), | ||
92 | PINCTRL_PIN(1, "ULPI_D0"), | ||
93 | PINCTRL_PIN(2, "ULPI_D1"), | ||
94 | PINCTRL_PIN(3, "ULPI_D2"), | ||
95 | PINCTRL_PIN(4, "ULPI_D3"), | ||
96 | PINCTRL_PIN(5, "ULPI_D4"), | ||
97 | PINCTRL_PIN(6, "ULPI_D5"), | ||
98 | PINCTRL_PIN(7, "ULPI_D6"), | ||
99 | PINCTRL_PIN(8, "ULPI_D7"), | ||
100 | PINCTRL_PIN(9, "ULPI_DIR"), | ||
101 | PINCTRL_PIN(10, "ULPI_NXT"), | ||
102 | PINCTRL_PIN(11, "ULPI_REFCLK"), | ||
103 | PINCTRL_PIN(12, "ULPI_STP"), | ||
104 | /* Family 2: eMMC (24 pins) */ | ||
105 | PINCTRL_PIN(13, "EMMC_CLK"), | ||
106 | PINCTRL_PIN(14, "EMMC_CMD"), | ||
107 | PINCTRL_PIN(15, "EMMC_D0"), | ||
108 | PINCTRL_PIN(16, "EMMC_D1"), | ||
109 | PINCTRL_PIN(17, "EMMC_D2"), | ||
110 | PINCTRL_PIN(18, "EMMC_D3"), | ||
111 | PINCTRL_PIN(19, "EMMC_D4"), | ||
112 | PINCTRL_PIN(20, "EMMC_D5"), | ||
113 | PINCTRL_PIN(21, "EMMC_D6"), | ||
114 | PINCTRL_PIN(22, "EMMC_D7"), | ||
115 | PINCTRL_PIN(23, "EMMC_RST_N"), | ||
116 | PINCTRL_PIN(24, "GP154"), | ||
117 | PINCTRL_PIN(25, "GP155"), | ||
118 | PINCTRL_PIN(26, "GP156"), | ||
119 | PINCTRL_PIN(27, "GP157"), | ||
120 | PINCTRL_PIN(28, "GP158"), | ||
121 | PINCTRL_PIN(29, "GP159"), | ||
122 | PINCTRL_PIN(30, "GP160"), | ||
123 | PINCTRL_PIN(31, "GP161"), | ||
124 | PINCTRL_PIN(32, "GP162"), | ||
125 | PINCTRL_PIN(33, "GP163"), | ||
126 | PINCTRL_PIN(34, "GP97"), | ||
127 | PINCTRL_PIN(35, "GP14"), | ||
128 | PINCTRL_PIN(36, "GP15"), | ||
129 | /* Family 3: SDIO (20 pins) */ | ||
130 | PINCTRL_PIN(37, "GP77_SD_CD"), | ||
131 | PINCTRL_PIN(38, "GP78_SD_CLK"), | ||
132 | PINCTRL_PIN(39, "GP79_SD_CMD"), | ||
133 | PINCTRL_PIN(40, "GP80_SD_D0"), | ||
134 | PINCTRL_PIN(41, "GP81_SD_D1"), | ||
135 | PINCTRL_PIN(42, "GP82_SD_D2"), | ||
136 | PINCTRL_PIN(43, "GP83_SD_D3"), | ||
137 | PINCTRL_PIN(44, "GP84_SD_LS_CLK_FB"), | ||
138 | PINCTRL_PIN(45, "GP85_SD_LS_CMD_DIR"), | ||
139 | PINCTRL_PIN(46, "GP86_SD_LVL_D_DIR"), | ||
140 | PINCTRL_PIN(47, "GP88_SD_LS_SEL"), | ||
141 | PINCTRL_PIN(48, "GP87_SD_PD"), | ||
142 | PINCTRL_PIN(49, "GP89_SD_WP"), | ||
143 | PINCTRL_PIN(50, "GP90_SDIO_CLK"), | ||
144 | PINCTRL_PIN(51, "GP91_SDIO_CMD"), | ||
145 | PINCTRL_PIN(52, "GP92_SDIO_D0"), | ||
146 | PINCTRL_PIN(53, "GP93_SDIO_D1"), | ||
147 | PINCTRL_PIN(54, "GP94_SDIO_D2"), | ||
148 | PINCTRL_PIN(55, "GP95_SDIO_D3"), | ||
149 | PINCTRL_PIN(56, "GP96_SDIO_PD"), | ||
150 | /* Family 4: HSI (8 pins) */ | ||
151 | PINCTRL_PIN(57, "HSI_ACDATA"), | ||
152 | PINCTRL_PIN(58, "HSI_ACFLAG"), | ||
153 | PINCTRL_PIN(59, "HSI_ACREADY"), | ||
154 | PINCTRL_PIN(60, "HSI_ACWAKE"), | ||
155 | PINCTRL_PIN(61, "HSI_CADATA"), | ||
156 | PINCTRL_PIN(62, "HSI_CAFLAG"), | ||
157 | PINCTRL_PIN(63, "HSI_CAREADY"), | ||
158 | PINCTRL_PIN(64, "HSI_CAWAKE"), | ||
159 | /* Family 5: SSP Audio (14 pins) */ | ||
160 | PINCTRL_PIN(65, "GP70"), | ||
161 | PINCTRL_PIN(66, "GP71"), | ||
162 | PINCTRL_PIN(67, "GP32_I2S_0_CLK"), | ||
163 | PINCTRL_PIN(68, "GP33_I2S_0_FS"), | ||
164 | PINCTRL_PIN(69, "GP34_I2S_0_RXD"), | ||
165 | PINCTRL_PIN(70, "GP35_I2S_0_TXD"), | ||
166 | PINCTRL_PIN(71, "GP36_I2S_1_CLK"), | ||
167 | PINCTRL_PIN(72, "GP37_I2S_1_FS"), | ||
168 | PINCTRL_PIN(73, "GP38_I2S_1_RXD"), | ||
169 | PINCTRL_PIN(74, "GP39_I2S_1_TXD"), | ||
170 | PINCTRL_PIN(75, "GP40_I2S_2_CLK"), | ||
171 | PINCTRL_PIN(76, "GP41_I2S_2_FS"), | ||
172 | PINCTRL_PIN(77, "GP42_I2S_2_RXD"), | ||
173 | PINCTRL_PIN(78, "GP43_I2S_2_TXD"), | ||
174 | /* Family 6: GP SSP (22 pins) */ | ||
175 | PINCTRL_PIN(79, "GP120_SPI_3_CLK"), | ||
176 | PINCTRL_PIN(80, "GP121_SPI_3_SS"), | ||
177 | PINCTRL_PIN(81, "GP122_SPI_3_RXD"), | ||
178 | PINCTRL_PIN(82, "GP123_SPI_3_TXD"), | ||
179 | PINCTRL_PIN(83, "GP102_SPI_4_CLK"), | ||
180 | PINCTRL_PIN(84, "GP103_SPI_4_SS_0"), | ||
181 | PINCTRL_PIN(85, "GP104_SPI_4_SS_1"), | ||
182 | PINCTRL_PIN(86, "GP105_SPI_4_SS_2"), | ||
183 | PINCTRL_PIN(87, "GP106_SPI_4_SS_3"), | ||
184 | PINCTRL_PIN(88, "GP107_SPI_4_RXD"), | ||
185 | PINCTRL_PIN(89, "GP108_SPI_4_TXD"), | ||
186 | PINCTRL_PIN(90, "GP109_SPI_5_CLK"), | ||
187 | PINCTRL_PIN(91, "GP110_SPI_5_SS_0"), | ||
188 | PINCTRL_PIN(92, "GP111_SPI_5_SS_1"), | ||
189 | PINCTRL_PIN(93, "GP112_SPI_5_SS_2"), | ||
190 | PINCTRL_PIN(94, "GP113_SPI_5_SS_3"), | ||
191 | PINCTRL_PIN(95, "GP114_SPI_5_RXD"), | ||
192 | PINCTRL_PIN(96, "GP115_SPI_5_TXD"), | ||
193 | PINCTRL_PIN(97, "GP116_SPI_6_CLK"), | ||
194 | PINCTRL_PIN(98, "GP117_SPI_6_SS"), | ||
195 | PINCTRL_PIN(99, "GP118_SPI_6_RXD"), | ||
196 | PINCTRL_PIN(100, "GP119_SPI_6_TXD"), | ||
197 | /* Family 7: I2C (14 pins) */ | ||
198 | PINCTRL_PIN(101, "GP19_I2C_1_SCL"), | ||
199 | PINCTRL_PIN(102, "GP20_I2C_1_SDA"), | ||
200 | PINCTRL_PIN(103, "GP21_I2C_2_SCL"), | ||
201 | PINCTRL_PIN(104, "GP22_I2C_2_SDA"), | ||
202 | PINCTRL_PIN(105, "GP17_I2C_3_SCL_HDMI"), | ||
203 | PINCTRL_PIN(106, "GP18_I2C_3_SDA_HDMI"), | ||
204 | PINCTRL_PIN(107, "GP23_I2C_4_SCL"), | ||
205 | PINCTRL_PIN(108, "GP24_I2C_4_SDA"), | ||
206 | PINCTRL_PIN(109, "GP25_I2C_5_SCL"), | ||
207 | PINCTRL_PIN(110, "GP26_I2C_5_SDA"), | ||
208 | PINCTRL_PIN(111, "GP27_I2C_6_SCL"), | ||
209 | PINCTRL_PIN(112, "GP28_I2C_6_SDA"), | ||
210 | PINCTRL_PIN(113, "GP29_I2C_7_SCL"), | ||
211 | PINCTRL_PIN(114, "GP30_I2C_7_SDA"), | ||
212 | /* Family 8: UART (12 pins) */ | ||
213 | PINCTRL_PIN(115, "GP124_UART_0_CTS"), | ||
214 | PINCTRL_PIN(116, "GP125_UART_0_RTS"), | ||
215 | PINCTRL_PIN(117, "GP126_UART_0_RX"), | ||
216 | PINCTRL_PIN(118, "GP127_UART_0_TX"), | ||
217 | PINCTRL_PIN(119, "GP128_UART_1_CTS"), | ||
218 | PINCTRL_PIN(120, "GP129_UART_1_RTS"), | ||
219 | PINCTRL_PIN(121, "GP130_UART_1_RX"), | ||
220 | PINCTRL_PIN(122, "GP131_UART_1_TX"), | ||
221 | PINCTRL_PIN(123, "GP132_UART_2_CTS"), | ||
222 | PINCTRL_PIN(124, "GP133_UART_2_RTS"), | ||
223 | PINCTRL_PIN(125, "GP134_UART_2_RX"), | ||
224 | PINCTRL_PIN(126, "GP135_UART_2_TX"), | ||
225 | /* Family 9: GPIO South (19 pins) */ | ||
226 | PINCTRL_PIN(127, "GP177"), | ||
227 | PINCTRL_PIN(128, "GP178"), | ||
228 | PINCTRL_PIN(129, "GP179"), | ||
229 | PINCTRL_PIN(130, "GP180"), | ||
230 | PINCTRL_PIN(131, "GP181"), | ||
231 | PINCTRL_PIN(132, "GP182_PWM2"), | ||
232 | PINCTRL_PIN(133, "GP183_PWM3"), | ||
233 | PINCTRL_PIN(134, "GP184"), | ||
234 | PINCTRL_PIN(135, "GP185"), | ||
235 | PINCTRL_PIN(136, "GP186"), | ||
236 | PINCTRL_PIN(137, "GP187"), | ||
237 | PINCTRL_PIN(138, "GP188"), | ||
238 | PINCTRL_PIN(139, "GP189"), | ||
239 | PINCTRL_PIN(140, "GP64_FAST_INT0"), | ||
240 | PINCTRL_PIN(141, "GP65_FAST_INT1"), | ||
241 | PINCTRL_PIN(142, "GP66_FAST_INT2"), | ||
242 | PINCTRL_PIN(143, "GP67_FAST_INT3"), | ||
243 | PINCTRL_PIN(144, "GP12_PWM0"), | ||
244 | PINCTRL_PIN(145, "GP13_PWM1"), | ||
245 | /* Family 10: Camera Sideband (12 pins) */ | ||
246 | PINCTRL_PIN(146, "GP0"), | ||
247 | PINCTRL_PIN(147, "GP1"), | ||
248 | PINCTRL_PIN(148, "GP2"), | ||
249 | PINCTRL_PIN(149, "GP3"), | ||
250 | PINCTRL_PIN(150, "GP4"), | ||
251 | PINCTRL_PIN(151, "GP5"), | ||
252 | PINCTRL_PIN(152, "GP6"), | ||
253 | PINCTRL_PIN(153, "GP7"), | ||
254 | PINCTRL_PIN(154, "GP8"), | ||
255 | PINCTRL_PIN(155, "GP9"), | ||
256 | PINCTRL_PIN(156, "GP10"), | ||
257 | PINCTRL_PIN(157, "GP11"), | ||
258 | /* Family 11: Clock (22 pins) */ | ||
259 | PINCTRL_PIN(158, "GP137"), | ||
260 | PINCTRL_PIN(159, "GP138"), | ||
261 | PINCTRL_PIN(160, "GP139"), | ||
262 | PINCTRL_PIN(161, "GP140"), | ||
263 | PINCTRL_PIN(162, "GP141"), | ||
264 | PINCTRL_PIN(163, "GP142"), | ||
265 | PINCTRL_PIN(164, "GP16_HDMI_HPD"), | ||
266 | PINCTRL_PIN(165, "GP68_DSI_A_TE"), | ||
267 | PINCTRL_PIN(166, "GP69_DSI_C_TE"), | ||
268 | PINCTRL_PIN(167, "OSC_CLK_CTRL0"), | ||
269 | PINCTRL_PIN(168, "OSC_CLK_CTRL1"), | ||
270 | PINCTRL_PIN(169, "OSC_CLK0"), | ||
271 | PINCTRL_PIN(170, "OSC_CLK1"), | ||
272 | PINCTRL_PIN(171, "OSC_CLK2"), | ||
273 | PINCTRL_PIN(172, "OSC_CLK3"), | ||
274 | PINCTRL_PIN(173, "OSC_CLK4"), | ||
275 | PINCTRL_PIN(174, "RESETOUT"), | ||
276 | PINCTRL_PIN(175, "PMODE"), | ||
277 | PINCTRL_PIN(176, "PRDY"), | ||
278 | PINCTRL_PIN(177, "PREQ"), | ||
279 | PINCTRL_PIN(178, "GP190"), | ||
280 | PINCTRL_PIN(179, "GP191"), | ||
281 | /* Family 12: MSIC (15 pins) */ | ||
282 | PINCTRL_PIN(180, "I2C_0_SCL"), | ||
283 | PINCTRL_PIN(181, "I2C_0_SDA"), | ||
284 | PINCTRL_PIN(182, "IERR"), | ||
285 | PINCTRL_PIN(183, "JTAG_TCK"), | ||
286 | PINCTRL_PIN(184, "JTAG_TDI"), | ||
287 | PINCTRL_PIN(185, "JTAG_TDO"), | ||
288 | PINCTRL_PIN(186, "JTAG_TMS"), | ||
289 | PINCTRL_PIN(187, "JTAG_TRST"), | ||
290 | PINCTRL_PIN(188, "PROCHOT"), | ||
291 | PINCTRL_PIN(189, "RTC_CLK"), | ||
292 | PINCTRL_PIN(190, "SVID_ALERT"), | ||
293 | PINCTRL_PIN(191, "SVID_CLK"), | ||
294 | PINCTRL_PIN(192, "SVID_D"), | ||
295 | PINCTRL_PIN(193, "THERMTRIP"), | ||
296 | PINCTRL_PIN(194, "STANDBY"), | ||
297 | /* Family 13: Keyboard (20 pins) */ | ||
298 | PINCTRL_PIN(195, "GP44"), | ||
299 | PINCTRL_PIN(196, "GP45"), | ||
300 | PINCTRL_PIN(197, "GP46"), | ||
301 | PINCTRL_PIN(198, "GP47"), | ||
302 | PINCTRL_PIN(199, "GP48"), | ||
303 | PINCTRL_PIN(200, "GP49"), | ||
304 | PINCTRL_PIN(201, "GP50"), | ||
305 | PINCTRL_PIN(202, "GP51"), | ||
306 | PINCTRL_PIN(203, "GP52"), | ||
307 | PINCTRL_PIN(204, "GP53"), | ||
308 | PINCTRL_PIN(205, "GP54"), | ||
309 | PINCTRL_PIN(206, "GP55"), | ||
310 | PINCTRL_PIN(207, "GP56"), | ||
311 | PINCTRL_PIN(208, "GP57"), | ||
312 | PINCTRL_PIN(209, "GP58"), | ||
313 | PINCTRL_PIN(210, "GP59"), | ||
314 | PINCTRL_PIN(211, "GP60"), | ||
315 | PINCTRL_PIN(212, "GP61"), | ||
316 | PINCTRL_PIN(213, "GP62"), | ||
317 | PINCTRL_PIN(214, "GP63"), | ||
318 | /* Family 14: GPIO North (13 pins) */ | ||
319 | PINCTRL_PIN(215, "GP164"), | ||
320 | PINCTRL_PIN(216, "GP165"), | ||
321 | PINCTRL_PIN(217, "GP166"), | ||
322 | PINCTRL_PIN(218, "GP167"), | ||
323 | PINCTRL_PIN(219, "GP168_MJTAG_TCK"), | ||
324 | PINCTRL_PIN(220, "GP169_MJTAG_TDI"), | ||
325 | PINCTRL_PIN(221, "GP170_MJTAG_TDO"), | ||
326 | PINCTRL_PIN(222, "GP171_MJTAG_TMS"), | ||
327 | PINCTRL_PIN(223, "GP172_MJTAG_TRST"), | ||
328 | PINCTRL_PIN(224, "GP173"), | ||
329 | PINCTRL_PIN(225, "GP174"), | ||
330 | PINCTRL_PIN(226, "GP175"), | ||
331 | PINCTRL_PIN(227, "GP176"), | ||
332 | /* Family 15: PTI (5 pins) */ | ||
333 | PINCTRL_PIN(228, "GP72_PTI_CLK"), | ||
334 | PINCTRL_PIN(229, "GP73_PTI_D0"), | ||
335 | PINCTRL_PIN(230, "GP74_PTI_D1"), | ||
336 | PINCTRL_PIN(231, "GP75_PTI_D2"), | ||
337 | PINCTRL_PIN(232, "GP76_PTI_D3"), | ||
338 | /* Family 16: USB3 (0 pins) */ | ||
339 | /* Family 17: HSIC (0 pins) */ | ||
340 | /* Family 18: Broadcast (0 pins) */ | ||
341 | }; | ||
342 | |||
343 | static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 }; | ||
344 | static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 }; | ||
345 | static const unsigned int mrfld_uart0_pins[] = { 124, 125, 126, 127 }; | ||
346 | static const unsigned int mrfld_uart1_pins[] = { 128, 129, 130, 131 }; | ||
347 | static const unsigned int mrfld_uart2_pins[] = { 132, 133, 134, 135 }; | ||
348 | static const unsigned int mrfld_pwm0_pins[] = { 144 }; | ||
349 | static const unsigned int mrfld_pwm1_pins[] = { 145 }; | ||
350 | static const unsigned int mrfld_pwm2_pins[] = { 132 }; | ||
351 | static const unsigned int mrfld_pwm3_pins[] = { 133 }; | ||
352 | |||
353 | static const struct intel_pingroup mrfld_groups[] = { | ||
354 | PIN_GROUP("sdio_grp", mrfld_sdio_pins, 1), | ||
355 | PIN_GROUP("spi5_grp", mrfld_spi5_pins, 1), | ||
356 | PIN_GROUP("uart0_grp", mrfld_uart0_pins, 1), | ||
357 | PIN_GROUP("uart1_grp", mrfld_uart1_pins, 1), | ||
358 | PIN_GROUP("uart2_grp", mrfld_uart2_pins, 1), | ||
359 | PIN_GROUP("pwm0_grp", mrfld_pwm0_pins, 1), | ||
360 | PIN_GROUP("pwm1_grp", mrfld_pwm1_pins, 1), | ||
361 | PIN_GROUP("pwm2_grp", mrfld_pwm2_pins, 1), | ||
362 | PIN_GROUP("pwm3_grp", mrfld_pwm3_pins, 1), | ||
363 | }; | ||
364 | |||
365 | static const char * const mrfld_sdio_groups[] = { "sdio_grp" }; | ||
366 | static const char * const mrfld_spi5_groups[] = { "spi5_grp" }; | ||
367 | static const char * const mrfld_uart0_groups[] = { "uart0_grp" }; | ||
368 | static const char * const mrfld_uart1_groups[] = { "uart1_grp" }; | ||
369 | static const char * const mrfld_uart2_groups[] = { "uart2_grp" }; | ||
370 | static const char * const mrfld_pwm0_groups[] = { "pwm0_grp" }; | ||
371 | static const char * const mrfld_pwm1_groups[] = { "pwm1_grp" }; | ||
372 | static const char * const mrfld_pwm2_groups[] = { "pwm2_grp" }; | ||
373 | static const char * const mrfld_pwm3_groups[] = { "pwm3_grp" }; | ||
374 | |||
375 | static const struct intel_function mrfld_functions[] = { | ||
376 | FUNCTION("sdio", mrfld_sdio_groups), | ||
377 | FUNCTION("spi5", mrfld_spi5_groups), | ||
378 | FUNCTION("uart0", mrfld_uart0_groups), | ||
379 | FUNCTION("uart1", mrfld_uart1_groups), | ||
380 | FUNCTION("uart2", mrfld_uart2_groups), | ||
381 | FUNCTION("pwm0", mrfld_pwm0_groups), | ||
382 | FUNCTION("pwm1", mrfld_pwm1_groups), | ||
383 | FUNCTION("pwm2", mrfld_pwm2_groups), | ||
384 | FUNCTION("pwm3", mrfld_pwm3_groups), | ||
385 | }; | ||
386 | |||
387 | static const struct mrfld_family mrfld_families[] = { | ||
388 | MRFLD_FAMILY(1, 0, 12), | ||
389 | MRFLD_FAMILY(2, 13, 36), | ||
390 | MRFLD_FAMILY(3, 37, 56), | ||
391 | MRFLD_FAMILY(4, 57, 64), | ||
392 | MRFLD_FAMILY(5, 65, 78), | ||
393 | MRFLD_FAMILY(6, 79, 100), | ||
394 | MRFLD_FAMILY_PROTECTED(7, 101, 114), | ||
395 | MRFLD_FAMILY(8, 115, 126), | ||
396 | MRFLD_FAMILY(9, 127, 145), | ||
397 | MRFLD_FAMILY(10, 146, 157), | ||
398 | MRFLD_FAMILY(11, 158, 179), | ||
399 | MRFLD_FAMILY_PROTECTED(12, 180, 194), | ||
400 | MRFLD_FAMILY(13, 195, 214), | ||
401 | MRFLD_FAMILY(14, 215, 227), | ||
402 | MRFLD_FAMILY(15, 228, 232), | ||
403 | }; | ||
404 | |||
405 | /** | ||
406 | * struct mrfld_pinctrl - Intel Merrifield pinctrl private structure | ||
407 | * @dev: Pointer to the device structure | ||
408 | * @lock: Lock to serialize register access | ||
409 | * @pctldesc: Pin controller description | ||
410 | * @pctldev: Pointer to the pin controller device | ||
411 | * @families: Array of families this pinctrl handles | ||
412 | * @nfamilies: Number of families in the array | ||
413 | * @functions: Array of functions | ||
414 | * @nfunctions: Number of functions in the array | ||
415 | * @groups: Array of pin groups | ||
416 | * @ngroups: Number of groups in the array | ||
417 | * @pins: Array of pins this pinctrl controls | ||
418 | * @npins: Number of pins in the array | ||
419 | */ | ||
420 | struct mrfld_pinctrl { | ||
421 | struct device *dev; | ||
422 | raw_spinlock_t lock; | ||
423 | struct pinctrl_desc pctldesc; | ||
424 | struct pinctrl_dev *pctldev; | ||
425 | |||
426 | /* Pin controller configuration */ | ||
427 | const struct mrfld_family *families; | ||
428 | size_t nfamilies; | ||
429 | const struct intel_function *functions; | ||
430 | size_t nfunctions; | ||
431 | const struct intel_pingroup *groups; | ||
432 | size_t ngroups; | ||
433 | const struct pinctrl_pin_desc *pins; | ||
434 | size_t npins; | ||
435 | }; | ||
436 | |||
437 | #define pin_to_bufno(f, p) ((p) - (f)->pin_base) | ||
438 | |||
439 | static const struct mrfld_family *mrfld_get_family(struct mrfld_pinctrl *mp, | ||
440 | unsigned int pin) | ||
441 | { | ||
442 | const struct mrfld_family *family; | ||
443 | unsigned int i; | ||
444 | |||
445 | for (i = 0; i < mp->nfamilies; i++) { | ||
446 | family = &mp->families[i]; | ||
447 | if (pin >= family->pin_base && | ||
448 | pin < family->pin_base + family->npins) | ||
449 | return family; | ||
450 | } | ||
451 | |||
452 | dev_warn(mp->dev, "failed to find family for pin %u\n", pin); | ||
453 | return NULL; | ||
454 | } | ||
455 | |||
456 | static bool mrfld_buf_available(struct mrfld_pinctrl *mp, unsigned int pin) | ||
457 | { | ||
458 | const struct mrfld_family *family; | ||
459 | |||
460 | family = mrfld_get_family(mp, pin); | ||
461 | if (!family) | ||
462 | return false; | ||
463 | |||
464 | return !family->protected; | ||
465 | } | ||
466 | |||
467 | static void __iomem *mrfld_get_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin) | ||
468 | { | ||
469 | const struct mrfld_family *family; | ||
470 | unsigned int bufno; | ||
471 | |||
472 | family = mrfld_get_family(mp, pin); | ||
473 | if (!family) | ||
474 | return NULL; | ||
475 | |||
476 | bufno = pin_to_bufno(family, pin); | ||
477 | return family->regs + BUFCFG_OFFSET + bufno * 4; | ||
478 | } | ||
479 | |||
480 | static int mrfld_get_groups_count(struct pinctrl_dev *pctldev) | ||
481 | { | ||
482 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
483 | |||
484 | return mp->ngroups; | ||
485 | } | ||
486 | |||
487 | static const char *mrfld_get_group_name(struct pinctrl_dev *pctldev, | ||
488 | unsigned int group) | ||
489 | { | ||
490 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
491 | |||
492 | return mp->groups[group].name; | ||
493 | } | ||
494 | |||
495 | static int mrfld_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, | ||
496 | const unsigned int **pins, unsigned int *npins) | ||
497 | { | ||
498 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
499 | |||
500 | *pins = mp->groups[group].pins; | ||
501 | *npins = mp->groups[group].npins; | ||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | static void mrfld_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, | ||
506 | unsigned int pin) | ||
507 | { | ||
508 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
509 | void __iomem *bufcfg; | ||
510 | u32 value, mode; | ||
511 | |||
512 | if (!mrfld_buf_available(mp, pin)) { | ||
513 | seq_puts(s, "not available"); | ||
514 | return; | ||
515 | } | ||
516 | |||
517 | bufcfg = mrfld_get_bufcfg(mp, pin); | ||
518 | value = readl(bufcfg); | ||
519 | |||
520 | mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT; | ||
521 | if (!mode) | ||
522 | seq_puts(s, "GPIO "); | ||
523 | else | ||
524 | seq_printf(s, "mode %d ", mode); | ||
525 | |||
526 | seq_printf(s, "0x%08x", value); | ||
527 | } | ||
528 | |||
529 | static const struct pinctrl_ops mrfld_pinctrl_ops = { | ||
530 | .get_groups_count = mrfld_get_groups_count, | ||
531 | .get_group_name = mrfld_get_group_name, | ||
532 | .get_group_pins = mrfld_get_group_pins, | ||
533 | .pin_dbg_show = mrfld_pin_dbg_show, | ||
534 | }; | ||
535 | |||
536 | static int mrfld_get_functions_count(struct pinctrl_dev *pctldev) | ||
537 | { | ||
538 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
539 | |||
540 | return mp->nfunctions; | ||
541 | } | ||
542 | |||
543 | static const char *mrfld_get_function_name(struct pinctrl_dev *pctldev, | ||
544 | unsigned int function) | ||
545 | { | ||
546 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
547 | |||
548 | return mp->functions[function].name; | ||
549 | } | ||
550 | |||
551 | static int mrfld_get_function_groups(struct pinctrl_dev *pctldev, | ||
552 | unsigned int function, | ||
553 | const char * const **groups, | ||
554 | unsigned int * const ngroups) | ||
555 | { | ||
556 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
557 | |||
558 | *groups = mp->functions[function].groups; | ||
559 | *ngroups = mp->functions[function].ngroups; | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static void mrfld_update_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin, | ||
564 | u32 bits, u32 mask) | ||
565 | { | ||
566 | void __iomem *bufcfg; | ||
567 | u32 value; | ||
568 | |||
569 | bufcfg = mrfld_get_bufcfg(mp, pin); | ||
570 | value = readl(bufcfg); | ||
571 | |||
572 | value &= ~mask; | ||
573 | value |= bits & mask; | ||
574 | |||
575 | writel(value, bufcfg); | ||
576 | } | ||
577 | |||
578 | static int mrfld_pinmux_set_mux(struct pinctrl_dev *pctldev, | ||
579 | unsigned int function, | ||
580 | unsigned int group) | ||
581 | { | ||
582 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
583 | const struct intel_pingroup *grp = &mp->groups[group]; | ||
584 | u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT; | ||
585 | u32 mask = BUFCFG_PINMODE_MASK; | ||
586 | unsigned long flags; | ||
587 | unsigned int i; | ||
588 | |||
589 | /* | ||
590 | * All pins in the groups needs to be accessible and writable | ||
591 | * before we can enable the mux for this group. | ||
592 | */ | ||
593 | for (i = 0; i < grp->npins; i++) { | ||
594 | if (!mrfld_buf_available(mp, grp->pins[i])) | ||
595 | return -EBUSY; | ||
596 | } | ||
597 | |||
598 | /* Now enable the mux setting for each pin in the group */ | ||
599 | raw_spin_lock_irqsave(&mp->lock, flags); | ||
600 | for (i = 0; i < grp->npins; i++) | ||
601 | mrfld_update_bufcfg(mp, grp->pins[i], bits, mask); | ||
602 | raw_spin_unlock_irqrestore(&mp->lock, flags); | ||
603 | |||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static int mrfld_gpio_request_enable(struct pinctrl_dev *pctldev, | ||
608 | struct pinctrl_gpio_range *range, | ||
609 | unsigned int pin) | ||
610 | { | ||
611 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
612 | u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT; | ||
613 | u32 mask = BUFCFG_PINMODE_MASK; | ||
614 | unsigned long flags; | ||
615 | |||
616 | if (!mrfld_buf_available(mp, pin)) | ||
617 | return -EBUSY; | ||
618 | |||
619 | raw_spin_lock_irqsave(&mp->lock, flags); | ||
620 | mrfld_update_bufcfg(mp, pin, bits, mask); | ||
621 | raw_spin_unlock_irqrestore(&mp->lock, flags); | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static const struct pinmux_ops mrfld_pinmux_ops = { | ||
627 | .get_functions_count = mrfld_get_functions_count, | ||
628 | .get_function_name = mrfld_get_function_name, | ||
629 | .get_function_groups = mrfld_get_function_groups, | ||
630 | .set_mux = mrfld_pinmux_set_mux, | ||
631 | .gpio_request_enable = mrfld_gpio_request_enable, | ||
632 | }; | ||
633 | |||
634 | static int mrfld_config_get(struct pinctrl_dev *pctldev, unsigned int pin, | ||
635 | unsigned long *config) | ||
636 | { | ||
637 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
638 | enum pin_config_param param = pinconf_to_config_param(*config); | ||
639 | u32 value, term; | ||
640 | u16 arg = 0; | ||
641 | |||
642 | if (!mrfld_buf_available(mp, pin)) | ||
643 | return -ENOTSUPP; | ||
644 | |||
645 | value = readl(mrfld_get_bufcfg(mp, pin)); | ||
646 | term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT; | ||
647 | |||
648 | switch (param) { | ||
649 | case PIN_CONFIG_BIAS_DISABLE: | ||
650 | if (value & BUFCFG_Px_EN_MASK) | ||
651 | return -EINVAL; | ||
652 | break; | ||
653 | |||
654 | case PIN_CONFIG_BIAS_PULL_UP: | ||
655 | if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN) | ||
656 | return -EINVAL; | ||
657 | |||
658 | switch (term) { | ||
659 | case BUFCFG_PUPD_VAL_910: | ||
660 | arg = 910; | ||
661 | break; | ||
662 | case BUFCFG_PUPD_VAL_2K: | ||
663 | arg = 2000; | ||
664 | break; | ||
665 | case BUFCFG_PUPD_VAL_20K: | ||
666 | arg = 20000; | ||
667 | break; | ||
668 | case BUFCFG_PUPD_VAL_50K: | ||
669 | arg = 50000; | ||
670 | break; | ||
671 | } | ||
672 | |||
673 | break; | ||
674 | |||
675 | case PIN_CONFIG_BIAS_PULL_DOWN: | ||
676 | if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN) | ||
677 | return -EINVAL; | ||
678 | |||
679 | switch (term) { | ||
680 | case BUFCFG_PUPD_VAL_910: | ||
681 | arg = 910; | ||
682 | break; | ||
683 | case BUFCFG_PUPD_VAL_2K: | ||
684 | arg = 2000; | ||
685 | break; | ||
686 | case BUFCFG_PUPD_VAL_20K: | ||
687 | arg = 20000; | ||
688 | break; | ||
689 | case BUFCFG_PUPD_VAL_50K: | ||
690 | arg = 50000; | ||
691 | break; | ||
692 | } | ||
693 | |||
694 | break; | ||
695 | |||
696 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: | ||
697 | if (!(value & BUFCFG_OD_EN)) | ||
698 | return -EINVAL; | ||
699 | break; | ||
700 | |||
701 | case PIN_CONFIG_SLEW_RATE: | ||
702 | if (!(value & BUFCFG_SLEWSEL)) | ||
703 | arg = 0; | ||
704 | else | ||
705 | arg = 1; | ||
706 | break; | ||
707 | |||
708 | default: | ||
709 | return -ENOTSUPP; | ||
710 | } | ||
711 | |||
712 | *config = pinconf_to_config_packed(param, arg); | ||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | static int mrfld_config_set_pin(struct mrfld_pinctrl *mp, unsigned int pin, | ||
717 | unsigned long config) | ||
718 | { | ||
719 | unsigned int param = pinconf_to_config_param(config); | ||
720 | unsigned int arg = pinconf_to_config_argument(config); | ||
721 | u32 bits = 0, mask = 0; | ||
722 | unsigned long flags; | ||
723 | |||
724 | switch (param) { | ||
725 | case PIN_CONFIG_BIAS_DISABLE: | ||
726 | mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; | ||
727 | break; | ||
728 | |||
729 | case PIN_CONFIG_BIAS_PULL_UP: | ||
730 | mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; | ||
731 | bits |= BUFCFG_PU_EN; | ||
732 | |||
733 | switch (arg) { | ||
734 | case 50000: | ||
735 | bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT; | ||
736 | break; | ||
737 | case 20000: | ||
738 | bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT; | ||
739 | break; | ||
740 | case 2000: | ||
741 | bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT; | ||
742 | break; | ||
743 | default: | ||
744 | return -EINVAL; | ||
745 | } | ||
746 | |||
747 | break; | ||
748 | |||
749 | case PIN_CONFIG_BIAS_PULL_DOWN: | ||
750 | mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; | ||
751 | bits |= BUFCFG_PD_EN; | ||
752 | |||
753 | switch (arg) { | ||
754 | case 50000: | ||
755 | bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT; | ||
756 | break; | ||
757 | case 20000: | ||
758 | bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT; | ||
759 | break; | ||
760 | case 2000: | ||
761 | bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT; | ||
762 | break; | ||
763 | default: | ||
764 | return -EINVAL; | ||
765 | } | ||
766 | |||
767 | break; | ||
768 | |||
769 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: | ||
770 | mask |= BUFCFG_OD_EN; | ||
771 | if (arg) | ||
772 | bits |= BUFCFG_OD_EN; | ||
773 | break; | ||
774 | |||
775 | case PIN_CONFIG_SLEW_RATE: | ||
776 | mask |= BUFCFG_SLEWSEL; | ||
777 | if (arg) | ||
778 | bits |= BUFCFG_SLEWSEL; | ||
779 | break; | ||
780 | } | ||
781 | |||
782 | raw_spin_lock_irqsave(&mp->lock, flags); | ||
783 | mrfld_update_bufcfg(mp, pin, bits, mask); | ||
784 | raw_spin_unlock_irqrestore(&mp->lock, flags); | ||
785 | |||
786 | return 0; | ||
787 | } | ||
788 | |||
789 | static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin, | ||
790 | unsigned long *configs, unsigned int nconfigs) | ||
791 | { | ||
792 | struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); | ||
793 | unsigned int i; | ||
794 | int ret; | ||
795 | |||
796 | for (i = 0; i < nconfigs; i++) { | ||
797 | switch (pinconf_to_config_param(configs[i])) { | ||
798 | case PIN_CONFIG_BIAS_DISABLE: | ||
799 | case PIN_CONFIG_BIAS_PULL_UP: | ||
800 | case PIN_CONFIG_BIAS_PULL_DOWN: | ||
801 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: | ||
802 | case PIN_CONFIG_SLEW_RATE: | ||
803 | ret = mrfld_config_set_pin(mp, pin, configs[i]); | ||
804 | if (ret) | ||
805 | return ret; | ||
806 | break; | ||
807 | |||
808 | default: | ||
809 | return -ENOTSUPP; | ||
810 | } | ||
811 | } | ||
812 | |||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | static const struct pinconf_ops mrfld_pinconf_ops = { | ||
817 | .is_generic = true, | ||
818 | .pin_config_get = mrfld_config_get, | ||
819 | .pin_config_set = mrfld_config_set, | ||
820 | }; | ||
821 | |||
822 | static const struct pinctrl_desc mrfld_pinctrl_desc = { | ||
823 | .pctlops = &mrfld_pinctrl_ops, | ||
824 | .pmxops = &mrfld_pinmux_ops, | ||
825 | .confops = &mrfld_pinconf_ops, | ||
826 | .owner = THIS_MODULE, | ||
827 | }; | ||
828 | |||
829 | static int mrfld_pinctrl_probe(struct platform_device *pdev) | ||
830 | { | ||
831 | struct mrfld_family *families; | ||
832 | struct mrfld_pinctrl *mp; | ||
833 | struct resource *mem; | ||
834 | void __iomem *regs; | ||
835 | size_t nfamilies; | ||
836 | unsigned int i; | ||
837 | |||
838 | mp = devm_kzalloc(&pdev->dev, sizeof(*mp), GFP_KERNEL); | ||
839 | if (!mp) | ||
840 | return -ENOMEM; | ||
841 | |||
842 | mp->dev = &pdev->dev; | ||
843 | raw_spin_lock_init(&mp->lock); | ||
844 | |||
845 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
846 | regs = devm_ioremap_resource(&pdev->dev, mem); | ||
847 | if (IS_ERR(regs)) | ||
848 | return PTR_ERR(regs); | ||
849 | |||
850 | /* | ||
851 | * Make a copy of the families which we can use to hold pointers | ||
852 | * to the registers. | ||
853 | */ | ||
854 | nfamilies = ARRAY_SIZE(mrfld_families), | ||
855 | families = devm_kmemdup(&pdev->dev, mrfld_families, | ||
856 | nfamilies * sizeof(mrfld_families), | ||
857 | GFP_KERNEL); | ||
858 | if (!families) | ||
859 | return -ENOMEM; | ||
860 | |||
861 | /* Splice memory resource by chunk per family */ | ||
862 | for (i = 0; i < nfamilies; i++) { | ||
863 | struct mrfld_family *family = &families[i]; | ||
864 | |||
865 | family->regs = regs + family->barno * MRFLD_FAMILY_LEN; | ||
866 | } | ||
867 | |||
868 | mp->families = families; | ||
869 | mp->nfamilies = nfamilies; | ||
870 | mp->functions = mrfld_functions; | ||
871 | mp->nfunctions = ARRAY_SIZE(mrfld_functions); | ||
872 | mp->groups = mrfld_groups; | ||
873 | mp->ngroups = ARRAY_SIZE(mrfld_groups); | ||
874 | mp->pctldesc = mrfld_pinctrl_desc; | ||
875 | mp->pctldesc.name = dev_name(&pdev->dev); | ||
876 | mp->pctldesc.pins = mrfld_pins; | ||
877 | mp->pctldesc.npins = ARRAY_SIZE(mrfld_pins); | ||
878 | |||
879 | mp->pctldev = devm_pinctrl_register(&pdev->dev, &mp->pctldesc, mp); | ||
880 | if (IS_ERR(mp->pctldev)) { | ||
881 | dev_err(&pdev->dev, "failed to register pinctrl driver\n"); | ||
882 | return PTR_ERR(mp->pctldev); | ||
883 | } | ||
884 | |||
885 | platform_set_drvdata(pdev, mp); | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | static struct platform_driver mrfld_pinctrl_driver = { | ||
890 | .probe = mrfld_pinctrl_probe, | ||
891 | .driver = { | ||
892 | .name = "pinctrl-merrifield", | ||
893 | }, | ||
894 | }; | ||
895 | |||
896 | static int __init mrfld_pinctrl_init(void) | ||
897 | { | ||
898 | return platform_driver_register(&mrfld_pinctrl_driver); | ||
899 | } | ||
900 | subsys_initcall(mrfld_pinctrl_init); | ||
901 | |||
902 | static void __exit mrfld_pinctrl_exit(void) | ||
903 | { | ||
904 | platform_driver_unregister(&mrfld_pinctrl_driver); | ||
905 | } | ||
906 | module_exit(mrfld_pinctrl_exit); | ||
907 | |||
908 | MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); | ||
909 | MODULE_DESCRIPTION("Intel Merrifield SoC pinctrl driver"); | ||
910 | MODULE_LICENSE("GPL v2"); | ||
911 | MODULE_ALIAS("platform:pinctrl-merrifield"); | ||