blob: 0ff7c55173da0e0a3dd4b16bab38ed68063d3153 [file] [log] [blame]
Andy Shevchenko875a92b2018-06-29 15:36:34 +03001// SPDX-License-Identifier: GPL-2.0
Mathias Nymana5d811b2013-06-18 14:33:02 +03002/*
3 * Pinctrl GPIO driver for Intel Baytrail
Mathias Nymana5d811b2013-06-18 14:33:02 +03004 *
Andy Shevchenko875a92b2018-06-29 15:36:34 +03005 * Copyright (c) 2012-2013, Intel Corporation
Mathias Nymana5d811b2013-06-18 14:33:02 +03006 * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
Mathias Nymana5d811b2013-06-18 14:33:02 +03007 */
8
Mathias Nymana5d811b2013-06-18 14:33:02 +03009#include <linux/acpi.h>
Andy Shevchenkoe0da3842018-09-04 14:26:20 +030010#include <linux/bitops.h>
11#include <linux/gpio/driver.h>
12#include <linux/init.h>
13#include <linux/interrupt.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030014#include <linux/io.h>
Andy Shevchenkoe0da3842018-09-04 14:26:20 +030015#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/platform_device.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030018#include <linux/pm_runtime.h>
Andy Shevchenko61db6c92018-08-30 19:27:39 +030019#include <linux/property.h>
Andy Shevchenkoe0da3842018-09-04 14:26:20 +030020#include <linux/seq_file.h>
Andy Shevchenko61db6c92018-08-30 19:27:39 +030021
Mathias Nymana5d811b2013-06-18 14:33:02 +030022#include <linux/pinctrl/pinctrl.h>
Cristina Ciocanc501d0b2016-04-01 14:00:03 +030023#include <linux/pinctrl/pinmux.h>
24#include <linux/pinctrl/pinconf.h>
25#include <linux/pinctrl/pinconf-generic.h>
Mathias Nymana5d811b2013-06-18 14:33:02 +030026
Andy Shevchenko4f010b92019-07-03 03:30:18 +030027#include "pinctrl-intel.h"
28
Mathias Nymana5d811b2013-06-18 14:33:02 +030029/* memory mapped register offsets */
30#define BYT_CONF0_REG 0x000
31#define BYT_CONF1_REG 0x004
32#define BYT_VAL_REG 0x008
33#define BYT_DFT_REG 0x00c
34#define BYT_INT_STAT_REG 0x800
Cristina Ciocan658b4762016-04-01 14:00:07 +030035#define BYT_DEBOUNCE_REG 0x9d0
Mathias Nymana5d811b2013-06-18 14:33:02 +030036
37/* BYT_CONF0_REG register bits */
Mika Westerberg3ff95882014-05-16 12:18:29 +030038#define BYT_IODEN BIT(31)
Eric Ernstff998352014-06-12 11:06:20 -070039#define BYT_DIRECT_IRQ_EN BIT(27)
Andy Shevchenkoeb0a2da2019-07-03 18:15:54 +030040#define BYT_TRIG_MASK GENMASK(26, 24)
Mathias Nymana5d811b2013-06-18 14:33:02 +030041#define BYT_TRIG_NEG BIT(26)
42#define BYT_TRIG_POS BIT(25)
43#define BYT_TRIG_LVL BIT(24)
Cristina Ciocan658b4762016-04-01 14:00:07 +030044#define BYT_DEBOUNCE_EN BIT(20)
Hans de Goede9291c652018-01-01 13:23:57 +010045#define BYT_GLITCH_FILTER_EN BIT(19)
46#define BYT_GLITCH_F_SLOW_CLK BIT(17)
47#define BYT_GLITCH_F_FAST_CLK BIT(16)
Mika Westerberg3ff95882014-05-16 12:18:29 +030048#define BYT_PULL_STR_SHIFT 9
Andy Shevchenkoeb0a2da2019-07-03 18:15:54 +030049#define BYT_PULL_STR_MASK GENMASK(10, 9)
Mika Westerberg3ff95882014-05-16 12:18:29 +030050#define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT)
51#define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT)
52#define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT)
53#define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT)
54#define BYT_PULL_ASSIGN_SHIFT 7
Andy Shevchenkoeb0a2da2019-07-03 18:15:54 +030055#define BYT_PULL_ASSIGN_MASK GENMASK(8, 7)
Mika Westerberg3ff95882014-05-16 12:18:29 +030056#define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT)
57#define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT)
Andy Shevchenkoeb0a2da2019-07-03 18:15:54 +030058#define BYT_PIN_MUX GENMASK(2, 0)
Mathias Nymana5d811b2013-06-18 14:33:02 +030059
60/* BYT_VAL_REG register bits */
Andy Shevchenkoeb0a2da2019-07-03 18:15:54 +030061#define BYT_DIR_MASK GENMASK(2, 1)
Mathias Nymana5d811b2013-06-18 14:33:02 +030062#define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/
63#define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/
64#define BYT_LEVEL BIT(0)
65
Andy Shevchenkoeb0a2da2019-07-03 18:15:54 +030066#define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX)
Mika Westerbergfcc18de2015-02-23 14:53:13 +020067#define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL)
68
Cristina Ciocan658b4762016-04-01 14:00:07 +030069/* BYT_DEBOUNCE_REG bits */
Andy Shevchenkoeb0a2da2019-07-03 18:15:54 +030070#define BYT_DEBOUNCE_PULSE_MASK GENMASK(2, 0)
Cristina Ciocan658b4762016-04-01 14:00:07 +030071#define BYT_DEBOUNCE_PULSE_375US 1
72#define BYT_DEBOUNCE_PULSE_750US 2
73#define BYT_DEBOUNCE_PULSE_1500US 3
74#define BYT_DEBOUNCE_PULSE_3MS 4
75#define BYT_DEBOUNCE_PULSE_6MS 5
76#define BYT_DEBOUNCE_PULSE_12MS 6
77#define BYT_DEBOUNCE_PULSE_24MS 7
78
Mathias Nymana5d811b2013-06-18 14:33:02 +030079#define BYT_NGPIO_SCORE 102
80#define BYT_NGPIO_NCORE 28
81#define BYT_NGPIO_SUS 44
82
Chew, Kean Ho42bd0072014-03-06 21:59:49 +080083#define BYT_SCORE_ACPI_UID "1"
84#define BYT_NCORE_ACPI_UID "2"
85#define BYT_SUS_ACPI_UID "3"
86
Cristina Ciocanc501d0b2016-04-01 14:00:03 +030087/*
88 * This is the function value most pins have for GPIO muxing. If the value
89 * differs from the default one, it must be explicitly mentioned. Otherwise, the
90 * pin control implementation will set the muxing value to default GPIO if it
91 * does not find a match for the requested function.
92 */
93#define BYT_DEFAULT_GPIO_MUX 0
Andy Shevchenkoa705f9c2019-07-03 03:30:17 +030094#define BYT_ALTER_GPIO_MUX 1
Cristina Ciocanc501d0b2016-04-01 14:00:03 +030095
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +020096struct intel_pad_context {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +030097 u32 conf0;
98 u32 val;
99};
Mathias Nymana5d811b2013-06-18 14:33:02 +0300100
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300101#define COMMUNITY(p, n, map) \
102 { \
103 .pin_base = (p), \
104 .npins = (n), \
105 .pad_map = (map),\
106 }
107
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300108/* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */
109static const struct pinctrl_pin_desc byt_score_pins[] = {
110 PINCTRL_PIN(0, "SATA_GP0"),
111 PINCTRL_PIN(1, "SATA_GP1"),
112 PINCTRL_PIN(2, "SATA_LED#"),
113 PINCTRL_PIN(3, "PCIE_CLKREQ0"),
114 PINCTRL_PIN(4, "PCIE_CLKREQ1"),
115 PINCTRL_PIN(5, "PCIE_CLKREQ2"),
116 PINCTRL_PIN(6, "PCIE_CLKREQ3"),
117 PINCTRL_PIN(7, "SD3_WP"),
118 PINCTRL_PIN(8, "HDA_RST"),
119 PINCTRL_PIN(9, "HDA_SYNC"),
120 PINCTRL_PIN(10, "HDA_CLK"),
121 PINCTRL_PIN(11, "HDA_SDO"),
122 PINCTRL_PIN(12, "HDA_SDI0"),
123 PINCTRL_PIN(13, "HDA_SDI1"),
124 PINCTRL_PIN(14, "GPIO_S0_SC14"),
125 PINCTRL_PIN(15, "GPIO_S0_SC15"),
126 PINCTRL_PIN(16, "MMC1_CLK"),
127 PINCTRL_PIN(17, "MMC1_D0"),
128 PINCTRL_PIN(18, "MMC1_D1"),
129 PINCTRL_PIN(19, "MMC1_D2"),
130 PINCTRL_PIN(20, "MMC1_D3"),
131 PINCTRL_PIN(21, "MMC1_D4"),
132 PINCTRL_PIN(22, "MMC1_D5"),
133 PINCTRL_PIN(23, "MMC1_D6"),
134 PINCTRL_PIN(24, "MMC1_D7"),
135 PINCTRL_PIN(25, "MMC1_CMD"),
136 PINCTRL_PIN(26, "MMC1_RST"),
137 PINCTRL_PIN(27, "SD2_CLK"),
138 PINCTRL_PIN(28, "SD2_D0"),
139 PINCTRL_PIN(29, "SD2_D1"),
140 PINCTRL_PIN(30, "SD2_D2"),
141 PINCTRL_PIN(31, "SD2_D3_CD"),
142 PINCTRL_PIN(32, "SD2_CMD"),
143 PINCTRL_PIN(33, "SD3_CLK"),
144 PINCTRL_PIN(34, "SD3_D0"),
145 PINCTRL_PIN(35, "SD3_D1"),
146 PINCTRL_PIN(36, "SD3_D2"),
147 PINCTRL_PIN(37, "SD3_D3"),
148 PINCTRL_PIN(38, "SD3_CD"),
149 PINCTRL_PIN(39, "SD3_CMD"),
150 PINCTRL_PIN(40, "SD3_1P8EN"),
151 PINCTRL_PIN(41, "SD3_PWREN#"),
152 PINCTRL_PIN(42, "ILB_LPC_AD0"),
153 PINCTRL_PIN(43, "ILB_LPC_AD1"),
154 PINCTRL_PIN(44, "ILB_LPC_AD2"),
155 PINCTRL_PIN(45, "ILB_LPC_AD3"),
156 PINCTRL_PIN(46, "ILB_LPC_FRAME"),
157 PINCTRL_PIN(47, "ILB_LPC_CLK0"),
158 PINCTRL_PIN(48, "ILB_LPC_CLK1"),
159 PINCTRL_PIN(49, "ILB_LPC_CLKRUN"),
160 PINCTRL_PIN(50, "ILB_LPC_SERIRQ"),
161 PINCTRL_PIN(51, "PCU_SMB_DATA"),
162 PINCTRL_PIN(52, "PCU_SMB_CLK"),
163 PINCTRL_PIN(53, "PCU_SMB_ALERT"),
164 PINCTRL_PIN(54, "ILB_8254_SPKR"),
165 PINCTRL_PIN(55, "GPIO_S0_SC55"),
166 PINCTRL_PIN(56, "GPIO_S0_SC56"),
167 PINCTRL_PIN(57, "GPIO_S0_SC57"),
168 PINCTRL_PIN(58, "GPIO_S0_SC58"),
169 PINCTRL_PIN(59, "GPIO_S0_SC59"),
170 PINCTRL_PIN(60, "GPIO_S0_SC60"),
171 PINCTRL_PIN(61, "GPIO_S0_SC61"),
172 PINCTRL_PIN(62, "LPE_I2S2_CLK"),
173 PINCTRL_PIN(63, "LPE_I2S2_FRM"),
174 PINCTRL_PIN(64, "LPE_I2S2_DATAIN"),
175 PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"),
176 PINCTRL_PIN(66, "SIO_SPI_CS"),
177 PINCTRL_PIN(67, "SIO_SPI_MISO"),
178 PINCTRL_PIN(68, "SIO_SPI_MOSI"),
179 PINCTRL_PIN(69, "SIO_SPI_CLK"),
180 PINCTRL_PIN(70, "SIO_UART1_RXD"),
181 PINCTRL_PIN(71, "SIO_UART1_TXD"),
182 PINCTRL_PIN(72, "SIO_UART1_RTS"),
183 PINCTRL_PIN(73, "SIO_UART1_CTS"),
184 PINCTRL_PIN(74, "SIO_UART2_RXD"),
185 PINCTRL_PIN(75, "SIO_UART2_TXD"),
186 PINCTRL_PIN(76, "SIO_UART2_RTS"),
187 PINCTRL_PIN(77, "SIO_UART2_CTS"),
188 PINCTRL_PIN(78, "SIO_I2C0_DATA"),
189 PINCTRL_PIN(79, "SIO_I2C0_CLK"),
190 PINCTRL_PIN(80, "SIO_I2C1_DATA"),
191 PINCTRL_PIN(81, "SIO_I2C1_CLK"),
192 PINCTRL_PIN(82, "SIO_I2C2_DATA"),
193 PINCTRL_PIN(83, "SIO_I2C2_CLK"),
194 PINCTRL_PIN(84, "SIO_I2C3_DATA"),
195 PINCTRL_PIN(85, "SIO_I2C3_CLK"),
196 PINCTRL_PIN(86, "SIO_I2C4_DATA"),
197 PINCTRL_PIN(87, "SIO_I2C4_CLK"),
198 PINCTRL_PIN(88, "SIO_I2C5_DATA"),
199 PINCTRL_PIN(89, "SIO_I2C5_CLK"),
200 PINCTRL_PIN(90, "SIO_I2C6_DATA"),
201 PINCTRL_PIN(91, "SIO_I2C6_CLK"),
202 PINCTRL_PIN(92, "GPIO_S0_SC92"),
203 PINCTRL_PIN(93, "GPIO_S0_SC93"),
204 PINCTRL_PIN(94, "SIO_PWM0"),
205 PINCTRL_PIN(95, "SIO_PWM1"),
206 PINCTRL_PIN(96, "PMC_PLT_CLK0"),
207 PINCTRL_PIN(97, "PMC_PLT_CLK1"),
208 PINCTRL_PIN(98, "PMC_PLT_CLK2"),
209 PINCTRL_PIN(99, "PMC_PLT_CLK3"),
210 PINCTRL_PIN(100, "PMC_PLT_CLK4"),
211 PINCTRL_PIN(101, "PMC_PLT_CLK5"),
212};
Mathias Nymana5d811b2013-06-18 14:33:02 +0300213
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300214static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = {
215 85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
216 36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
217 54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
218 52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
219 95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
220 86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
221 80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
222 2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
223 31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
224 24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
225 97, 100,
Mathias Nymana5d811b2013-06-18 14:33:02 +0300226};
227
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300228/* SCORE groups */
229static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 };
230static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300231
232static const unsigned int byt_score_pwm0_pins[] = { 94 };
233static const unsigned int byt_score_pwm1_pins[] = { 95 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300234
235static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300236
237static const unsigned int byt_score_i2c5_pins[] = { 88, 89 };
238static const unsigned int byt_score_i2c6_pins[] = { 90, 91 };
239static const unsigned int byt_score_i2c4_pins[] = { 86, 87 };
240static const unsigned int byt_score_i2c3_pins[] = { 84, 85 };
241static const unsigned int byt_score_i2c2_pins[] = { 82, 83 };
242static const unsigned int byt_score_i2c1_pins[] = { 80, 81 };
243static const unsigned int byt_score_i2c0_pins[] = { 78, 79 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300244
245static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 };
246static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 };
247static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300248
249static const unsigned int byt_score_sdcard_pins[] = {
250 7, 33, 34, 35, 36, 37, 38, 39, 40, 41,
251};
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300252static const unsigned int byt_score_sdcard_mux_values[] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300253 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
254};
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300255
256static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300257
258static const unsigned int byt_score_emmc_pins[] = {
259 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
260};
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300261
262static const unsigned int byt_score_ilb_lpc_pins[] = {
263 42, 43, 44, 45, 46, 47, 48, 49, 50,
264};
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300265
266static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300267
268static const unsigned int byt_score_plt_clk0_pins[] = { 96 };
269static const unsigned int byt_score_plt_clk1_pins[] = { 97 };
270static const unsigned int byt_score_plt_clk2_pins[] = { 98 };
Cristina Ciocanb41aa4f2016-06-22 14:17:19 +0300271static const unsigned int byt_score_plt_clk3_pins[] = { 99 };
272static const unsigned int byt_score_plt_clk4_pins[] = { 100 };
273static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300274
275static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300276
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300277static const struct intel_pingroup byt_score_groups[] = {
278 PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1),
279 PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1),
280 PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1),
281 PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1),
282 PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1),
283 PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1),
284 PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1),
285 PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1),
286 PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1),
287 PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1),
288 PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1),
289 PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1),
290 PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1),
291 PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1),
292 PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1),
293 PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
294 PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1),
295 PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1),
296 PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1),
297 PIN_GROUP("sata_grp", byt_score_sata_pins, 1),
298 PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
299 PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
300 PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
301 PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
302 PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
303 PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
304 PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1),
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300305};
306
307static const char * const byt_score_uart_groups[] = {
308 "uart1_grp", "uart2_grp",
309};
310static const char * const byt_score_pwm_groups[] = {
311 "pwm0_grp", "pwm1_grp",
312};
313static const char * const byt_score_ssp_groups[] = {
314 "ssp0_grp", "ssp1_grp", "ssp2_grp",
315};
316static const char * const byt_score_spi_groups[] = { "sio_spi_grp" };
317static const char * const byt_score_i2c_groups[] = {
318 "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp",
319 "i2c6_grp",
320};
321static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" };
322static const char * const byt_score_sdio_groups[] = { "sdio_grp" };
323static const char * const byt_score_emmc_groups[] = { "emmc_grp" };
324static const char * const byt_score_lpc_groups[] = { "lpc_grp" };
325static const char * const byt_score_sata_groups[] = { "sata_grp" };
326static const char * const byt_score_plt_clk_groups[] = {
327 "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
328 "plt_clk4_grp", "plt_clk5_grp",
329};
330static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
331static const char * const byt_score_gpio_groups[] = {
332 "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
333 "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
334 "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
335 "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
336 "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
337 "plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300338};
339
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300340static const struct intel_function byt_score_functions[] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300341 FUNCTION("uart", byt_score_uart_groups),
342 FUNCTION("pwm", byt_score_pwm_groups),
343 FUNCTION("ssp", byt_score_ssp_groups),
344 FUNCTION("spi", byt_score_spi_groups),
345 FUNCTION("i2c", byt_score_i2c_groups),
346 FUNCTION("sdcard", byt_score_sdcard_groups),
347 FUNCTION("sdio", byt_score_sdio_groups),
348 FUNCTION("emmc", byt_score_emmc_groups),
349 FUNCTION("lpc", byt_score_lpc_groups),
350 FUNCTION("sata", byt_score_sata_groups),
351 FUNCTION("plt_clk", byt_score_plt_clk_groups),
352 FUNCTION("smbus", byt_score_smbus_groups),
353 FUNCTION("gpio", byt_score_gpio_groups),
354};
355
Andy Shevchenko34e65672019-07-26 23:16:36 +0300356static const struct intel_community byt_score_communities[] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300357 COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
358};
359
Andy Shevchenko34e65672019-07-26 23:16:36 +0300360static const struct intel_pinctrl_soc_data byt_score_soc_data = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300361 .uid = BYT_SCORE_ACPI_UID,
362 .pins = byt_score_pins,
363 .npins = ARRAY_SIZE(byt_score_pins),
364 .groups = byt_score_groups,
365 .ngroups = ARRAY_SIZE(byt_score_groups),
366 .functions = byt_score_functions,
367 .nfunctions = ARRAY_SIZE(byt_score_functions),
368 .communities = byt_score_communities,
369 .ncommunities = ARRAY_SIZE(byt_score_communities),
370};
371
372/* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */
373static const struct pinctrl_pin_desc byt_sus_pins[] = {
374 PINCTRL_PIN(0, "GPIO_S50"),
375 PINCTRL_PIN(1, "GPIO_S51"),
376 PINCTRL_PIN(2, "GPIO_S52"),
377 PINCTRL_PIN(3, "GPIO_S53"),
378 PINCTRL_PIN(4, "GPIO_S54"),
379 PINCTRL_PIN(5, "GPIO_S55"),
380 PINCTRL_PIN(6, "GPIO_S56"),
381 PINCTRL_PIN(7, "GPIO_S57"),
382 PINCTRL_PIN(8, "GPIO_S58"),
383 PINCTRL_PIN(9, "GPIO_S59"),
384 PINCTRL_PIN(10, "GPIO_S510"),
385 PINCTRL_PIN(11, "PMC_SUSPWRDNACK"),
386 PINCTRL_PIN(12, "PMC_SUSCLK0"),
387 PINCTRL_PIN(13, "GPIO_S513"),
388 PINCTRL_PIN(14, "USB_ULPI_RST"),
389 PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"),
390 PINCTRL_PIN(16, "PMC_PWRBTN"),
391 PINCTRL_PIN(17, "GPIO_S517"),
392 PINCTRL_PIN(18, "PMC_SUS_STAT"),
393 PINCTRL_PIN(19, "USB_OC0"),
394 PINCTRL_PIN(20, "USB_OC1"),
395 PINCTRL_PIN(21, "PCU_SPI_CS1"),
396 PINCTRL_PIN(22, "GPIO_S522"),
397 PINCTRL_PIN(23, "GPIO_S523"),
398 PINCTRL_PIN(24, "GPIO_S524"),
399 PINCTRL_PIN(25, "GPIO_S525"),
400 PINCTRL_PIN(26, "GPIO_S526"),
401 PINCTRL_PIN(27, "GPIO_S527"),
402 PINCTRL_PIN(28, "GPIO_S528"),
403 PINCTRL_PIN(29, "GPIO_S529"),
404 PINCTRL_PIN(30, "GPIO_S530"),
405 PINCTRL_PIN(31, "USB_ULPI_CLK"),
406 PINCTRL_PIN(32, "USB_ULPI_DATA0"),
407 PINCTRL_PIN(33, "USB_ULPI_DATA1"),
408 PINCTRL_PIN(34, "USB_ULPI_DATA2"),
409 PINCTRL_PIN(35, "USB_ULPI_DATA3"),
410 PINCTRL_PIN(36, "USB_ULPI_DATA4"),
411 PINCTRL_PIN(37, "USB_ULPI_DATA5"),
412 PINCTRL_PIN(38, "USB_ULPI_DATA6"),
413 PINCTRL_PIN(39, "USB_ULPI_DATA7"),
414 PINCTRL_PIN(40, "USB_ULPI_DIR"),
415 PINCTRL_PIN(41, "USB_ULPI_NXT"),
416 PINCTRL_PIN(42, "USB_ULPI_STP"),
417 PINCTRL_PIN(43, "USB_ULPI_REFCLK"),
418};
419
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300420static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = {
421 29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
422 18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
423 0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
424 26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
425 52, 53, 59, 40,
426};
427
428static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 };
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300429static const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 };
430static const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300431
432static const unsigned int byt_sus_usb_ulpi_pins[] = {
433 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
434};
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300435static const unsigned int byt_sus_usb_ulpi_mode_values[] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300436 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
437};
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300438static const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = {
439 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300440};
441
442static const unsigned int byt_sus_pcu_spi_pins[] = { 21 };
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300443static const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 };
444static const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 };
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300445
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300446static const struct intel_pingroup byt_sus_groups[] = {
447 PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values),
448 PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values),
449 PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values),
450 PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values),
451 PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values),
452 PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values),
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300453};
454
455static const char * const byt_sus_usb_groups[] = {
456 "usb_oc_grp", "usb_ulpi_grp",
457};
458static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" };
459static const char * const byt_sus_gpio_groups[] = {
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300460 "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio",
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300461};
462
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300463static const struct intel_function byt_sus_functions[] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300464 FUNCTION("usb", byt_sus_usb_groups),
465 FUNCTION("spi", byt_sus_spi_groups),
466 FUNCTION("gpio", byt_sus_gpio_groups),
467};
468
Andy Shevchenko34e65672019-07-26 23:16:36 +0300469static const struct intel_community byt_sus_communities[] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300470 COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
471};
472
Andy Shevchenko34e65672019-07-26 23:16:36 +0300473static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300474 .uid = BYT_SUS_ACPI_UID,
475 .pins = byt_sus_pins,
476 .npins = ARRAY_SIZE(byt_sus_pins),
477 .groups = byt_sus_groups,
478 .ngroups = ARRAY_SIZE(byt_sus_groups),
479 .functions = byt_sus_functions,
480 .nfunctions = ARRAY_SIZE(byt_sus_functions),
481 .communities = byt_sus_communities,
482 .ncommunities = ARRAY_SIZE(byt_sus_communities),
483};
484
485static const struct pinctrl_pin_desc byt_ncore_pins[] = {
Andy Shevchenkob30b7362019-11-12 16:24:41 +0200486 PINCTRL_PIN(0, "HV_DDI0_HPD"),
487 PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"),
488 PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"),
489 PINCTRL_PIN(3, "PANEL0_VDDEN"),
490 PINCTRL_PIN(4, "PANEL0_BKLTEN"),
491 PINCTRL_PIN(5, "PANEL0_BKLTCTL"),
492 PINCTRL_PIN(6, "HV_DDI1_HPD"),
493 PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"),
494 PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"),
495 PINCTRL_PIN(9, "PANEL1_VDDEN"),
496 PINCTRL_PIN(10, "PANEL1_BKLTEN"),
497 PINCTRL_PIN(11, "PANEL1_BKLTCTL"),
498 PINCTRL_PIN(12, "GP_INTD_DSI_TE1"),
499 PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"),
500 PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"),
501 PINCTRL_PIN(15, "GP_CAMERASB00"),
502 PINCTRL_PIN(16, "GP_CAMERASB01"),
503 PINCTRL_PIN(17, "GP_CAMERASB02"),
504 PINCTRL_PIN(18, "GP_CAMERASB03"),
505 PINCTRL_PIN(19, "GP_CAMERASB04"),
506 PINCTRL_PIN(20, "GP_CAMERASB05"),
507 PINCTRL_PIN(21, "GP_CAMERASB06"),
508 PINCTRL_PIN(22, "GP_CAMERASB07"),
509 PINCTRL_PIN(23, "GP_CAMERASB08"),
510 PINCTRL_PIN(24, "GP_CAMERASB09"),
511 PINCTRL_PIN(25, "GP_CAMERASB10"),
512 PINCTRL_PIN(26, "GP_CAMERASB11"),
513 PINCTRL_PIN(27, "GP_INTD_DSI_TE2"),
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300514};
515
Andy Shevchenko939330d2018-09-26 17:50:27 +0300516static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300517 19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
518 14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
519 3, 6, 10, 13, 2, 5, 9, 7,
520};
521
Andy Shevchenko34e65672019-07-26 23:16:36 +0300522static const struct intel_community byt_ncore_communities[] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300523 COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
524};
525
Andy Shevchenko34e65672019-07-26 23:16:36 +0300526static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300527 .uid = BYT_NCORE_ACPI_UID,
528 .pins = byt_ncore_pins,
529 .npins = ARRAY_SIZE(byt_ncore_pins),
530 .communities = byt_ncore_communities,
531 .ncommunities = ARRAY_SIZE(byt_ncore_communities),
532};
533
Andy Shevchenko34e65672019-07-26 23:16:36 +0300534static const struct intel_pinctrl_soc_data *byt_soc_data[] = {
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300535 &byt_score_soc_data,
536 &byt_sus_soc_data,
537 &byt_ncore_soc_data,
Andy Shevchenko166d6e22018-10-17 19:16:31 +0300538 NULL
Cristina Ciocanc8f5c4c2016-04-01 14:00:02 +0300539};
540
Hans de Goede40ecab552019-11-19 16:46:41 +0100541static DEFINE_RAW_SPINLOCK(byt_lock);
542
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200543static struct intel_community *byt_get_community(struct intel_pinctrl *vg,
Andy Shevchenko34e65672019-07-26 23:16:36 +0300544 unsigned int pin)
Mathias Nymana5d811b2013-06-18 14:33:02 +0300545{
Andy Shevchenko34e65672019-07-26 23:16:36 +0300546 struct intel_community *comm;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300547 int i;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300548
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200549 for (i = 0; i < vg->ncommunities; i++) {
550 comm = vg->communities + i;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300551 if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
552 return comm;
553 }
554
555 return NULL;
556}
557
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200558static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset,
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300559 int reg)
560{
Andy Shevchenko34e65672019-07-26 23:16:36 +0300561 struct intel_community *comm = byt_get_community(vg, offset);
Andy Shevchenko1b899702017-01-26 19:24:08 +0200562 u32 reg_offset;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300563
564 if (!comm)
565 return NULL;
566
567 offset -= comm->pin_base;
Andy Shevchenko1b899702017-01-26 19:24:08 +0200568 switch (reg) {
569 case BYT_INT_STAT_REG:
Mathias Nymana5d811b2013-06-18 14:33:02 +0300570 reg_offset = (offset / 32) * 4;
Andy Shevchenko1b899702017-01-26 19:24:08 +0200571 break;
572 case BYT_DEBOUNCE_REG:
573 reg_offset = 0;
574 break;
575 default:
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300576 reg_offset = comm->pad_map[offset] * 16;
Andy Shevchenko1b899702017-01-26 19:24:08 +0200577 break;
578 }
Mathias Nymana5d811b2013-06-18 14:33:02 +0300579
Andy Shevchenko34e65672019-07-26 23:16:36 +0300580 return comm->pad_regs + reg_offset + reg;
Mathias Nymana5d811b2013-06-18 14:33:02 +0300581}
582
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300583static int byt_get_groups_count(struct pinctrl_dev *pctldev)
Mika Westerberg95f09722015-02-23 14:53:11 +0200584{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200585 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300586
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200587 return vg->soc->ngroups;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300588}
589
590static const char *byt_get_group_name(struct pinctrl_dev *pctldev,
591 unsigned int selector)
592{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200593 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300594
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200595 return vg->soc->groups[selector].name;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300596}
597
598static int byt_get_group_pins(struct pinctrl_dev *pctldev,
599 unsigned int selector,
600 const unsigned int **pins,
601 unsigned int *num_pins)
602{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200603 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300604
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200605 *pins = vg->soc->groups[selector].pins;
606 *num_pins = vg->soc->groups[selector].npins;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300607
608 return 0;
609}
610
611static const struct pinctrl_ops byt_pinctrl_ops = {
612 .get_groups_count = byt_get_groups_count,
613 .get_group_name = byt_get_group_name,
614 .get_group_pins = byt_get_group_pins,
615};
616
617static int byt_get_functions_count(struct pinctrl_dev *pctldev)
618{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200619 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300620
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200621 return vg->soc->nfunctions;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300622}
623
624static const char *byt_get_function_name(struct pinctrl_dev *pctldev,
625 unsigned int selector)
626{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200627 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300628
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200629 return vg->soc->functions[selector].name;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300630}
631
632static int byt_get_function_groups(struct pinctrl_dev *pctldev,
633 unsigned int selector,
634 const char * const **groups,
635 unsigned int *num_groups)
636{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200637 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300638
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200639 *groups = vg->soc->functions[selector].groups;
640 *num_groups = vg->soc->functions[selector].ngroups;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300641
642 return 0;
643}
644
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200645static void byt_set_group_simple_mux(struct intel_pinctrl *vg,
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300646 const struct intel_pingroup group,
647 unsigned int func)
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300648{
649 unsigned long flags;
650 int i;
651
Hans de Goede40ecab552019-11-19 16:46:41 +0100652 raw_spin_lock_irqsave(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300653
654 for (i = 0; i < group.npins; i++) {
655 void __iomem *padcfg0;
656 u32 value;
657
658 padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
659 if (!padcfg0) {
Andy Shevchenko990ec242019-11-25 17:56:41 +0200660 dev_warn(vg->dev,
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300661 "Group %s, pin %i not muxed (no padcfg0)\n",
662 group.name, i);
663 continue;
664 }
665
666 value = readl(padcfg0);
667 value &= ~BYT_PIN_MUX;
668 value |= func;
669 writel(value, padcfg0);
670 }
671
Hans de Goede40ecab552019-11-19 16:46:41 +0100672 raw_spin_unlock_irqrestore(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300673}
674
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200675static void byt_set_group_mixed_mux(struct intel_pinctrl *vg,
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300676 const struct intel_pingroup group,
677 const unsigned int *func)
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300678{
679 unsigned long flags;
680 int i;
681
Hans de Goede40ecab552019-11-19 16:46:41 +0100682 raw_spin_lock_irqsave(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300683
684 for (i = 0; i < group.npins; i++) {
685 void __iomem *padcfg0;
686 u32 value;
687
688 padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
689 if (!padcfg0) {
Andy Shevchenko990ec242019-11-25 17:56:41 +0200690 dev_warn(vg->dev,
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300691 "Group %s, pin %i not muxed (no padcfg0)\n",
692 group.name, i);
693 continue;
694 }
695
696 value = readl(padcfg0);
697 value &= ~BYT_PIN_MUX;
698 value |= func[i];
699 writel(value, padcfg0);
700 }
701
Hans de Goede40ecab552019-11-19 16:46:41 +0100702 raw_spin_unlock_irqrestore(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300703}
704
705static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
706 unsigned int group_selector)
707{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200708 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
709 const struct intel_function func = vg->soc->functions[func_selector];
710 const struct intel_pingroup group = vg->soc->groups[group_selector];
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300711
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300712 if (group.modes)
713 byt_set_group_mixed_mux(vg, group, group.modes);
714 else if (!strcmp(func.name, "gpio"))
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300715 byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300716 else
Andy Shevchenko4f010b92019-07-03 03:30:18 +0300717 byt_set_group_simple_mux(vg, group, group.mode);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300718
719 return 0;
720}
721
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200722static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset)
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300723{
724 /* SCORE pin 92-93 */
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200725 if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) &&
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300726 offset >= 92 && offset <= 93)
Andy Shevchenkoa705f9c2019-07-03 03:30:17 +0300727 return BYT_ALTER_GPIO_MUX;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300728
729 /* SUS pin 11-21 */
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200730 if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) &&
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300731 offset >= 11 && offset <= 21)
Andy Shevchenkoa705f9c2019-07-03 03:30:17 +0300732 return BYT_ALTER_GPIO_MUX;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300733
Andy Shevchenkoa705f9c2019-07-03 03:30:17 +0300734 return BYT_DEFAULT_GPIO_MUX;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300735}
736
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200737static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset)
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300738{
739 void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
Mika Westerberg95f09722015-02-23 14:53:11 +0200740 unsigned long flags;
741 u32 value;
742
Hans de Goede40ecab552019-11-19 16:46:41 +0100743 raw_spin_lock_irqsave(&byt_lock, flags);
Mika Westerberg95f09722015-02-23 14:53:11 +0200744 value = readl(reg);
Hans de Goedea2368052019-12-28 00:04:47 +0100745
746 /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
747 if (value & BYT_DIRECT_IRQ_EN)
748 /* nothing to do */ ;
749 else
750 value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
751
Mika Westerberg95f09722015-02-23 14:53:11 +0200752 writel(value, reg);
Hans de Goede40ecab552019-11-19 16:46:41 +0100753 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mika Westerberg95f09722015-02-23 14:53:11 +0200754}
755
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300756static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
757 struct pinctrl_gpio_range *range,
758 unsigned int offset)
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800759{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200760 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300761 void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
Mika Westerbergf8323b62015-02-23 14:53:10 +0200762 u32 value, gpio_mux;
Mika Westerberg39ce8152015-08-04 15:03:14 +0300763 unsigned long flags;
764
Hans de Goede40ecab552019-11-19 16:46:41 +0100765 raw_spin_lock_irqsave(&byt_lock, flags);
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800766
767 /*
768 * In most cases, func pin mux 000 means GPIO function.
769 * But, some pins may have func pin mux 001 represents
Mika Westerbergf8323b62015-02-23 14:53:10 +0200770 * GPIO function.
771 *
772 * Because there are devices out there where some pins were not
773 * configured correctly we allow changing the mux value from
774 * request (but print out warning about that).
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800775 */
776 value = readl(reg) & BYT_PIN_MUX;
Mika Westerbergf8323b62015-02-23 14:53:10 +0200777 gpio_mux = byt_get_gpio_mux(vg, offset);
Hans de Goedeb5894d12017-07-12 14:31:01 +0200778 if (gpio_mux != value) {
Mika Westerbergf8323b62015-02-23 14:53:10 +0200779 value = readl(reg) & ~BYT_PIN_MUX;
780 value |= gpio_mux;
781 writel(value, reg);
Mika Westerbergf8323b62015-02-23 14:53:10 +0200782
Andy Shevchenko990ec242019-11-25 17:56:41 +0200783 dev_warn(vg->dev, FW_BUG "pin %u forcibly re-configured as GPIO\n", offset);
Chew, Kean Ho42bd0072014-03-06 21:59:49 +0800784 }
Mathias Nymana5d811b2013-06-18 14:33:02 +0300785
Hans de Goede40ecab552019-11-19 16:46:41 +0100786 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mika Westerberg39ce8152015-08-04 15:03:14 +0300787
Andy Shevchenko990ec242019-11-25 17:56:41 +0200788 pm_runtime_get(vg->dev);
Mathias Nymana5d811b2013-06-18 14:33:02 +0300789
790 return 0;
791}
792
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300793static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
794 struct pinctrl_gpio_range *range,
795 unsigned int offset)
796{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200797 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300798
799 byt_gpio_clear_triggering(vg, offset);
Andy Shevchenko990ec242019-11-25 17:56:41 +0200800 pm_runtime_put(vg->dev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300801}
802
803static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
804 struct pinctrl_gpio_range *range,
805 unsigned int offset,
806 bool input)
807{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200808 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300809 void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
810 void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
811 unsigned long flags;
812 u32 value;
813
Hans de Goede40ecab552019-11-19 16:46:41 +0100814 raw_spin_lock_irqsave(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300815
816 value = readl(val_reg);
817 value &= ~BYT_DIR_MASK;
818 if (input)
819 value |= BYT_OUTPUT_EN;
Hans de Goedee2b74412020-01-01 15:52:43 +0100820 else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300821 /*
822 * Before making any direction modifications, do a check if gpio
823 * is set for direct IRQ. On baytrail, setting GPIO to output
Hans de Goedee2b74412020-01-01 15:52:43 +0100824 * does not make sense, so let's at least inform the caller before
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300825 * they shoot themselves in the foot.
826 */
Hans de Goedee2b74412020-01-01 15:52:43 +0100827 dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
828
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300829 writel(value, val_reg);
830
Hans de Goede40ecab552019-11-19 16:46:41 +0100831 raw_spin_unlock_irqrestore(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300832
833 return 0;
834}
835
836static const struct pinmux_ops byt_pinmux_ops = {
837 .get_functions_count = byt_get_functions_count,
838 .get_function_name = byt_get_function_name,
839 .get_function_groups = byt_get_function_groups,
840 .set_mux = byt_set_mux,
841 .gpio_request_enable = byt_gpio_request_enable,
842 .gpio_disable_free = byt_gpio_disable_free,
843 .gpio_set_direction = byt_gpio_set_direction,
844};
845
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300846static void byt_get_pull_strength(u32 reg, u16 *strength)
847{
848 switch (reg & BYT_PULL_STR_MASK) {
849 case BYT_PULL_STR_2K:
850 *strength = 2000;
851 break;
852 case BYT_PULL_STR_10K:
853 *strength = 10000;
854 break;
855 case BYT_PULL_STR_20K:
856 *strength = 20000;
857 break;
858 case BYT_PULL_STR_40K:
859 *strength = 40000;
860 break;
861 }
862}
863
864static int byt_set_pull_strength(u32 *reg, u16 strength)
865{
866 *reg &= ~BYT_PULL_STR_MASK;
867
868 switch (strength) {
869 case 2000:
870 *reg |= BYT_PULL_STR_2K;
871 break;
872 case 10000:
873 *reg |= BYT_PULL_STR_10K;
874 break;
875 case 20000:
876 *reg |= BYT_PULL_STR_20K;
877 break;
878 case 40000:
879 *reg |= BYT_PULL_STR_40K;
880 break;
881 default:
882 return -EINVAL;
883 }
884
885 return 0;
886}
887
888static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
889 unsigned long *config)
890{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200891 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300892 enum pin_config_param param = pinconf_to_config_param(*config);
893 void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
894 void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
Andy Shevchenko04ff5a02017-01-10 16:38:52 +0200895 void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300896 unsigned long flags;
Cristina Ciocan658b4762016-04-01 14:00:07 +0300897 u32 conf, pull, val, debounce;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300898 u16 arg = 0;
899
Hans de Goede40ecab552019-11-19 16:46:41 +0100900 raw_spin_lock_irqsave(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300901 conf = readl(conf_reg);
902 pull = conf & BYT_PULL_ASSIGN_MASK;
903 val = readl(val_reg);
Hans de Goede40ecab552019-11-19 16:46:41 +0100904 raw_spin_unlock_irqrestore(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300905
906 switch (param) {
907 case PIN_CONFIG_BIAS_DISABLE:
908 if (pull)
909 return -EINVAL;
910 break;
911 case PIN_CONFIG_BIAS_PULL_DOWN:
912 /* Pull assignment is only applicable in input mode */
913 if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN)
914 return -EINVAL;
915
916 byt_get_pull_strength(conf, &arg);
917
918 break;
919 case PIN_CONFIG_BIAS_PULL_UP:
920 /* Pull assignment is only applicable in input mode */
921 if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP)
922 return -EINVAL;
923
924 byt_get_pull_strength(conf, &arg);
925
926 break;
Cristina Ciocan658b4762016-04-01 14:00:07 +0300927 case PIN_CONFIG_INPUT_DEBOUNCE:
928 if (!(conf & BYT_DEBOUNCE_EN))
929 return -EINVAL;
930
Hans de Goede40ecab552019-11-19 16:46:41 +0100931 raw_spin_lock_irqsave(&byt_lock, flags);
Andy Shevchenko04ff5a02017-01-10 16:38:52 +0200932 debounce = readl(db_reg);
Hans de Goede40ecab552019-11-19 16:46:41 +0100933 raw_spin_unlock_irqrestore(&byt_lock, flags);
Cristina Ciocan658b4762016-04-01 14:00:07 +0300934
935 switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
936 case BYT_DEBOUNCE_PULSE_375US:
937 arg = 375;
938 break;
939 case BYT_DEBOUNCE_PULSE_750US:
940 arg = 750;
941 break;
942 case BYT_DEBOUNCE_PULSE_1500US:
943 arg = 1500;
944 break;
945 case BYT_DEBOUNCE_PULSE_3MS:
946 arg = 3000;
947 break;
948 case BYT_DEBOUNCE_PULSE_6MS:
949 arg = 6000;
950 break;
951 case BYT_DEBOUNCE_PULSE_12MS:
952 arg = 12000;
953 break;
954 case BYT_DEBOUNCE_PULSE_24MS:
955 arg = 24000;
956 break;
957 default:
958 return -EINVAL;
959 }
960
961 break;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300962 default:
963 return -ENOTSUPP;
964 }
965
966 *config = pinconf_to_config_packed(param, arg);
967
968 return 0;
969}
970
971static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
972 unsigned int offset,
973 unsigned long *configs,
974 unsigned int num_configs)
975{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +0200976 struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300977 unsigned int param, arg;
978 void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
979 void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
Andy Shevchenko04ff5a02017-01-10 16:38:52 +0200980 void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300981 unsigned long flags;
Cristina Ciocan658b4762016-04-01 14:00:07 +0300982 u32 conf, val, debounce;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300983 int i, ret = 0;
984
Hans de Goede40ecab552019-11-19 16:46:41 +0100985 raw_spin_lock_irqsave(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +0300986
987 conf = readl(conf_reg);
988 val = readl(val_reg);
989
990 for (i = 0; i < num_configs; i++) {
991 param = pinconf_to_config_param(configs[i]);
992 arg = pinconf_to_config_argument(configs[i]);
993
994 switch (param) {
995 case PIN_CONFIG_BIAS_DISABLE:
996 conf &= ~BYT_PULL_ASSIGN_MASK;
997 break;
998 case PIN_CONFIG_BIAS_PULL_DOWN:
999 /* Set default strength value in case none is given */
1000 if (arg == 1)
1001 arg = 2000;
1002
1003 /*
1004 * Pull assignment is only applicable in input mode. If
1005 * chip is not in input mode, set it and warn about it.
1006 */
1007 if (val & BYT_INPUT_EN) {
1008 val &= ~BYT_INPUT_EN;
1009 writel(val, val_reg);
Andy Shevchenko990ec242019-11-25 17:56:41 +02001010 dev_warn(vg->dev,
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001011 "pin %u forcibly set to input mode\n",
1012 offset);
1013 }
1014
1015 conf &= ~BYT_PULL_ASSIGN_MASK;
1016 conf |= BYT_PULL_ASSIGN_DOWN;
1017 ret = byt_set_pull_strength(&conf, arg);
1018
1019 break;
1020 case PIN_CONFIG_BIAS_PULL_UP:
1021 /* Set default strength value in case none is given */
1022 if (arg == 1)
1023 arg = 2000;
1024
1025 /*
1026 * Pull assignment is only applicable in input mode. If
1027 * chip is not in input mode, set it and warn about it.
1028 */
1029 if (val & BYT_INPUT_EN) {
1030 val &= ~BYT_INPUT_EN;
1031 writel(val, val_reg);
Andy Shevchenko990ec242019-11-25 17:56:41 +02001032 dev_warn(vg->dev,
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001033 "pin %u forcibly set to input mode\n",
1034 offset);
1035 }
1036
1037 conf &= ~BYT_PULL_ASSIGN_MASK;
1038 conf |= BYT_PULL_ASSIGN_UP;
1039 ret = byt_set_pull_strength(&conf, arg);
1040
1041 break;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001042 case PIN_CONFIG_INPUT_DEBOUNCE:
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001043 debounce = readl(db_reg);
1044 debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001045
Andy Shevchenko827e1572017-01-26 19:24:07 +02001046 if (arg)
1047 conf |= BYT_DEBOUNCE_EN;
1048 else
1049 conf &= ~BYT_DEBOUNCE_EN;
1050
Cristina Ciocan658b4762016-04-01 14:00:07 +03001051 switch (arg) {
1052 case 375:
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001053 debounce |= BYT_DEBOUNCE_PULSE_375US;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001054 break;
1055 case 750:
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001056 debounce |= BYT_DEBOUNCE_PULSE_750US;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001057 break;
1058 case 1500:
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001059 debounce |= BYT_DEBOUNCE_PULSE_1500US;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001060 break;
1061 case 3000:
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001062 debounce |= BYT_DEBOUNCE_PULSE_3MS;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001063 break;
1064 case 6000:
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001065 debounce |= BYT_DEBOUNCE_PULSE_6MS;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001066 break;
1067 case 12000:
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001068 debounce |= BYT_DEBOUNCE_PULSE_12MS;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001069 break;
1070 case 24000:
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001071 debounce |= BYT_DEBOUNCE_PULSE_24MS;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001072 break;
1073 default:
Andy Shevchenko827e1572017-01-26 19:24:07 +02001074 if (arg)
1075 ret = -EINVAL;
1076 break;
Cristina Ciocan658b4762016-04-01 14:00:07 +03001077 }
1078
Andy Shevchenko04ff5a02017-01-10 16:38:52 +02001079 if (!ret)
1080 writel(debounce, db_reg);
Cristina Ciocan658b4762016-04-01 14:00:07 +03001081 break;
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001082 default:
1083 ret = -ENOTSUPP;
1084 }
1085
1086 if (ret)
1087 break;
1088 }
1089
1090 if (!ret)
1091 writel(conf, conf_reg);
1092
Hans de Goede40ecab552019-11-19 16:46:41 +01001093 raw_spin_unlock_irqrestore(&byt_lock, flags);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001094
1095 return ret;
1096}
1097
1098static const struct pinconf_ops byt_pinconf_ops = {
1099 .is_generic = true,
1100 .pin_config_get = byt_pin_config_get,
1101 .pin_config_set = byt_pin_config_set,
1102};
1103
1104static const struct pinctrl_desc byt_pinctrl_desc = {
1105 .pctlops = &byt_pinctrl_ops,
1106 .pmxops = &byt_pinmux_ops,
1107 .confops = &byt_pinconf_ops,
1108 .owner = THIS_MODULE,
1109};
1110
Andy Shevchenko939330d2018-09-26 17:50:27 +03001111static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
Mathias Nymana5d811b2013-06-18 14:33:02 +03001112{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001113 struct intel_pinctrl *vg = gpiochip_get_data(chip);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001114 void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
Mika Westerberg39ce8152015-08-04 15:03:14 +03001115 unsigned long flags;
1116 u32 val;
1117
Hans de Goede40ecab552019-11-19 16:46:41 +01001118 raw_spin_lock_irqsave(&byt_lock, flags);
Mika Westerberg39ce8152015-08-04 15:03:14 +03001119 val = readl(reg);
Hans de Goede40ecab552019-11-19 16:46:41 +01001120 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mika Westerberg39ce8152015-08-04 15:03:14 +03001121
Linus Walleij3bde8772015-12-21 16:17:20 +01001122 return !!(val & BYT_LEVEL);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001123}
1124
Andy Shevchenko939330d2018-09-26 17:50:27 +03001125static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
Mathias Nymana5d811b2013-06-18 14:33:02 +03001126{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001127 struct intel_pinctrl *vg = gpiochip_get_data(chip);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001128 void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001129 unsigned long flags;
1130 u32 old_val;
1131
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001132 if (!reg)
1133 return;
1134
Hans de Goede40ecab552019-11-19 16:46:41 +01001135 raw_spin_lock_irqsave(&byt_lock, flags);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001136 old_val = readl(reg);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001137 if (value)
1138 writel(old_val | BYT_LEVEL, reg);
1139 else
1140 writel(old_val & ~BYT_LEVEL, reg);
Hans de Goede40ecab552019-11-19 16:46:41 +01001141 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001142}
1143
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001144static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
Mathias Nymana5d811b2013-06-18 14:33:02 +03001145{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001146 struct intel_pinctrl *vg = gpiochip_get_data(chip);
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001147 void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001148 unsigned long flags;
1149 u32 value;
1150
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001151 if (!reg)
1152 return -EINVAL;
1153
Hans de Goede40ecab552019-11-19 16:46:41 +01001154 raw_spin_lock_irqsave(&byt_lock, flags);
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001155 value = readl(reg);
Hans de Goede40ecab552019-11-19 16:46:41 +01001156 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001157
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001158 if (!(value & BYT_OUTPUT_EN))
Matti Vaittinenfaf86c02019-12-12 08:35:52 +02001159 return GPIO_LINE_DIRECTION_OUT;
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001160 if (!(value & BYT_INPUT_EN))
Matti Vaittinenfaf86c02019-12-12 08:35:52 +02001161 return GPIO_LINE_DIRECTION_IN;
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001162
1163 return -EINVAL;
Mathias Nymana5d811b2013-06-18 14:33:02 +03001164}
1165
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001166static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
Mathias Nymana5d811b2013-06-18 14:33:02 +03001167{
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001168 return pinctrl_gpio_direction_input(chip->base + offset);
1169}
Andy Shevchenko496940c2013-07-10 14:55:40 +03001170
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001171static int byt_gpio_direction_output(struct gpio_chip *chip,
1172 unsigned int offset, int value)
1173{
1174 int ret = pinctrl_gpio_direction_output(chip->base + offset);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001175
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001176 if (ret)
1177 return ret;
1178
1179 byt_gpio_set(chip, offset, value);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001180
1181 return 0;
1182}
1183
1184static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
1185{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001186 struct intel_pinctrl *vg = gpiochip_get_data(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001187 int i;
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001188 u32 conf0, val;
Mathias Nymana5d811b2013-06-18 14:33:02 +03001189
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001190 for (i = 0; i < vg->soc->npins; i++) {
Andy Shevchenko34e65672019-07-26 23:16:36 +03001191 const struct intel_community *comm;
Mika Westerberg3ff95882014-05-16 12:18:29 +03001192 const char *pull_str = NULL;
1193 const char *pull = NULL;
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001194 void __iomem *reg;
Mika Westerberg78e1c892015-08-17 16:03:17 +03001195 unsigned long flags;
Mathias Nymana4d8d6d2013-11-22 14:01:23 +02001196 const char *label;
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001197 unsigned int pin;
Mika Westerberg78e1c892015-08-17 16:03:17 +03001198
Hans de Goede40ecab552019-11-19 16:46:41 +01001199 raw_spin_lock_irqsave(&byt_lock, flags);
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001200 pin = vg->soc->pins[i].number;
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001201 reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
1202 if (!reg) {
1203 seq_printf(s,
1204 "Could not retrieve pin %i conf0 reg\n",
1205 pin);
Hans de Goede40ecab552019-11-19 16:46:41 +01001206 raw_spin_unlock_irqrestore(&byt_lock, flags);
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001207 continue;
1208 }
1209 conf0 = readl(reg);
1210
1211 reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1212 if (!reg) {
1213 seq_printf(s,
1214 "Could not retrieve pin %i val reg\n", pin);
Hans de Goede40ecab552019-11-19 16:46:41 +01001215 raw_spin_unlock_irqrestore(&byt_lock, flags);
Dan Carpenter22bbd212016-04-27 11:08:35 +03001216 continue;
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001217 }
1218 val = readl(reg);
Hans de Goede40ecab552019-11-19 16:46:41 +01001219 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001220
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001221 comm = byt_get_community(vg, pin);
1222 if (!comm) {
1223 seq_printf(s,
1224 "Could not get community for pin %i\n", pin);
1225 continue;
1226 }
Mathias Nymana4d8d6d2013-11-22 14:01:23 +02001227 label = gpiochip_is_requested(chip, i);
1228 if (!label)
1229 label = "Unrequested";
1230
Mika Westerberg3ff95882014-05-16 12:18:29 +03001231 switch (conf0 & BYT_PULL_ASSIGN_MASK) {
1232 case BYT_PULL_ASSIGN_UP:
1233 pull = "up";
1234 break;
1235 case BYT_PULL_ASSIGN_DOWN:
1236 pull = "down";
1237 break;
1238 }
1239
1240 switch (conf0 & BYT_PULL_STR_MASK) {
1241 case BYT_PULL_STR_2K:
1242 pull_str = "2k";
1243 break;
1244 case BYT_PULL_STR_10K:
1245 pull_str = "10k";
1246 break;
1247 case BYT_PULL_STR_20K:
1248 pull_str = "20k";
1249 break;
1250 case BYT_PULL_STR_40K:
1251 pull_str = "40k";
1252 break;
1253 }
1254
Mathias Nymana5d811b2013-06-18 14:33:02 +03001255 seq_printf(s,
Mika Westerberg3ff95882014-05-16 12:18:29 +03001256 " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001257 pin,
Mathias Nymana4d8d6d2013-11-22 14:01:23 +02001258 label,
Mathias Nymana5d811b2013-06-18 14:33:02 +03001259 val & BYT_INPUT_EN ? " " : "in",
1260 val & BYT_OUTPUT_EN ? " " : "out",
1261 val & BYT_LEVEL ? "hi" : "lo",
Alexander Stein3655a1ca2017-01-26 14:17:54 +01001262 comm->pad_map[i], comm->pad_map[i] * 16,
Mathias Nymana5d811b2013-06-18 14:33:02 +03001263 conf0 & 0x7,
Mika Westerberg3ff95882014-05-16 12:18:29 +03001264 conf0 & BYT_TRIG_NEG ? " fall" : " ",
1265 conf0 & BYT_TRIG_POS ? " rise" : " ",
1266 conf0 & BYT_TRIG_LVL ? " level" : " ");
1267
1268 if (pull && pull_str)
1269 seq_printf(s, " %-4s %-3s", pull, pull_str);
1270 else
1271 seq_puts(s, " ");
1272
1273 if (conf0 & BYT_IODEN)
1274 seq_puts(s, " open-drain");
1275
1276 seq_puts(s, "\n");
Mathias Nymana5d811b2013-06-18 14:33:02 +03001277 }
Mathias Nymana5d811b2013-06-18 14:33:02 +03001278}
1279
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001280static const struct gpio_chip byt_gpio_chip = {
1281 .owner = THIS_MODULE,
1282 .request = gpiochip_generic_request,
1283 .free = gpiochip_generic_free,
1284 .get_direction = byt_gpio_get_direction,
1285 .direction_input = byt_gpio_direction_input,
1286 .direction_output = byt_gpio_direction_output,
1287 .get = byt_gpio_get,
1288 .set = byt_gpio_set,
Andy Shevchenkoccd025e2019-12-11 19:32:54 +02001289 .set_config = gpiochip_generic_config,
Cristina Ciocan86e3ef812016-04-01 14:00:04 +03001290 .dbg_show = byt_gpio_dbg_show,
1291};
1292
Mika Westerberg31e43292015-02-23 14:53:12 +02001293static void byt_irq_ack(struct irq_data *d)
1294{
1295 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001296 struct intel_pinctrl *vg = gpiochip_get_data(gc);
Andy Shevchenko939330d2018-09-26 17:50:27 +03001297 unsigned int offset = irqd_to_hwirq(d);
Mika Westerberg31e43292015-02-23 14:53:12 +02001298 void __iomem *reg;
1299
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001300 reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG);
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001301 if (!reg)
1302 return;
1303
Hans de Goede40ecab552019-11-19 16:46:41 +01001304 raw_spin_lock(&byt_lock);
Mika Westerberg31e43292015-02-23 14:53:12 +02001305 writel(BIT(offset % 32), reg);
Hans de Goede40ecab552019-11-19 16:46:41 +01001306 raw_spin_unlock(&byt_lock);
Mika Westerberg31e43292015-02-23 14:53:12 +02001307}
1308
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001309static void byt_irq_mask(struct irq_data *d)
1310{
1311 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001312 struct intel_pinctrl *vg = gpiochip_get_data(gc);
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001313
1314 byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
1315}
1316
Mathias Nymana5d811b2013-06-18 14:33:02 +03001317static void byt_irq_unmask(struct irq_data *d)
1318{
Mika Westerberg31e43292015-02-23 14:53:12 +02001319 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001320 struct intel_pinctrl *vg = gpiochip_get_data(gc);
Andy Shevchenko939330d2018-09-26 17:50:27 +03001321 unsigned int offset = irqd_to_hwirq(d);
Mika Westerberg31e43292015-02-23 14:53:12 +02001322 unsigned long flags;
1323 void __iomem *reg;
1324 u32 value;
1325
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001326 reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001327 if (!reg)
1328 return;
Mika Westerberg78e1c892015-08-17 16:03:17 +03001329
Hans de Goede40ecab552019-11-19 16:46:41 +01001330 raw_spin_lock_irqsave(&byt_lock, flags);
Mika Westerberg31e43292015-02-23 14:53:12 +02001331 value = readl(reg);
1332
1333 switch (irqd_get_trigger_type(d)) {
1334 case IRQ_TYPE_LEVEL_HIGH:
1335 value |= BYT_TRIG_LVL;
Gustavo A. R. Silva399476b2018-07-05 10:51:27 -05001336 /* fall through */
Mika Westerberg31e43292015-02-23 14:53:12 +02001337 case IRQ_TYPE_EDGE_RISING:
1338 value |= BYT_TRIG_POS;
1339 break;
1340 case IRQ_TYPE_LEVEL_LOW:
1341 value |= BYT_TRIG_LVL;
Gustavo A. R. Silva399476b2018-07-05 10:51:27 -05001342 /* fall through */
Mika Westerberg31e43292015-02-23 14:53:12 +02001343 case IRQ_TYPE_EDGE_FALLING:
1344 value |= BYT_TRIG_NEG;
1345 break;
1346 case IRQ_TYPE_EDGE_BOTH:
1347 value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
1348 break;
1349 }
1350
1351 writel(value, reg);
1352
Hans de Goede40ecab552019-11-19 16:46:41 +01001353 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001354}
1355
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001356static int byt_irq_type(struct irq_data *d, unsigned int type)
Mathias Nymana5d811b2013-06-18 14:33:02 +03001357{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001358 struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001359 u32 offset = irqd_to_hwirq(d);
1360 u32 value;
1361 unsigned long flags;
1362 void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
Mika Westerberg31e43292015-02-23 14:53:12 +02001363
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001364 if (!reg || offset >= vg->chip.ngpio)
1365 return -EINVAL;
1366
Hans de Goede40ecab552019-11-19 16:46:41 +01001367 raw_spin_lock_irqsave(&byt_lock, flags);
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001368 value = readl(reg);
1369
1370 WARN(value & BYT_DIRECT_IRQ_EN,
1371 "Bad pad config for io mode, force direct_irq_en bit clearing");
1372
1373 /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
1374 * are used to indicate high and low level triggering
1375 */
1376 value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
1377 BYT_TRIG_LVL);
Hans de Goede9291c652018-01-01 13:23:57 +01001378 /* Enable glitch filtering */
1379 value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK |
1380 BYT_GLITCH_F_FAST_CLK;
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001381
1382 writel(value, reg);
1383
1384 if (type & IRQ_TYPE_EDGE_BOTH)
1385 irq_set_handler_locked(d, handle_edge_irq);
1386 else if (type & IRQ_TYPE_LEVEL_MASK)
1387 irq_set_handler_locked(d, handle_level_irq);
1388
Hans de Goede40ecab552019-11-19 16:46:41 +01001389 raw_spin_unlock_irqrestore(&byt_lock, flags);
Cristina Ciocan9f573b92016-04-01 14:00:05 +03001390
1391 return 0;
Mathias Nymana5d811b2013-06-18 14:33:02 +03001392}
1393
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001394static void byt_gpio_irq_handler(struct irq_desc *desc)
1395{
1396 struct irq_data *data = irq_desc_get_irq_data(desc);
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001397 struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc));
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001398 struct irq_chip *chip = irq_data_get_irq_chip(data);
1399 u32 base, pin;
1400 void __iomem *reg;
1401 unsigned long pending;
1402 unsigned int virq;
1403
1404 /* check from GPIO controller which pin triggered the interrupt */
1405 for (base = 0; base < vg->chip.ngpio; base += 32) {
1406 reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
1407
1408 if (!reg) {
Andy Shevchenko990ec242019-11-25 17:56:41 +02001409 dev_warn(vg->dev,
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001410 "Pin %i: could not retrieve interrupt status register\n",
1411 base);
1412 continue;
1413 }
1414
Hans de Goede40ecab552019-11-19 16:46:41 +01001415 raw_spin_lock(&byt_lock);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001416 pending = readl(reg);
Hans de Goede40ecab552019-11-19 16:46:41 +01001417 raw_spin_unlock(&byt_lock);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001418 for_each_set_bit(pin, &pending, 32) {
Thierry Redingf0fbe7b2017-11-07 19:15:47 +01001419 virq = irq_find_mapping(vg->chip.irq.domain, base + pin);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001420 generic_handle_irq(virq);
1421 }
1422 }
1423 chip->irq_eoi(data);
1424}
1425
Linus Walleij5fbe5b52019-09-04 16:01:04 +02001426static void byt_init_irq_valid_mask(struct gpio_chip *chip,
1427 unsigned long *valid_mask,
1428 unsigned int ngpios)
1429{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001430 struct intel_pinctrl *vg = gpiochip_get_data(chip);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001431 void __iomem *reg;
Andy Shevchenkoe70982b2019-11-05 16:23:24 +02001432 u32 value;
Mika Westerberg95f09722015-02-23 14:53:11 +02001433 int i;
1434
1435 /*
1436 * Clear interrupt triggers for all pins that are GPIOs and
1437 * do not use direct IRQ mode. This will prevent spurious
1438 * interrupts from misconfigured pins.
1439 */
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001440 for (i = 0; i < vg->soc->npins; i++) {
1441 unsigned int pin = vg->soc->pins[i].number;
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001442
1443 reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
1444 if (!reg) {
Andy Shevchenko990ec242019-11-25 17:56:41 +02001445 dev_warn(vg->dev,
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001446 "Pin %i: could not retrieve conf0 register\n",
1447 i);
1448 continue;
1449 }
1450
1451 value = readl(reg);
Andy Shevchenko49c03092017-01-11 15:49:00 +02001452 if (value & BYT_DIRECT_IRQ_EN) {
Andy Shevchenkoe70982b2019-11-05 16:23:24 +02001453 clear_bit(i, valid_mask);
Andy Shevchenko990ec242019-11-25 17:56:41 +02001454 dev_dbg(vg->dev, "excluding GPIO %d from IRQ domain\n", i);
Andy Shevchenko49c03092017-01-11 15:49:00 +02001455 } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
Mika Westerberg95f09722015-02-23 14:53:11 +02001456 byt_gpio_clear_triggering(vg, i);
Andy Shevchenko990ec242019-11-25 17:56:41 +02001457 dev_dbg(vg->dev, "disabling GPIO %d\n", i);
Mika Westerberg95f09722015-02-23 14:53:11 +02001458 }
1459 }
Andy Shevchenkoe70982b2019-11-05 16:23:24 +02001460}
1461
1462static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
1463{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001464 struct intel_pinctrl *vg = gpiochip_get_data(chip);
Andy Shevchenkoe70982b2019-11-05 16:23:24 +02001465 void __iomem *reg;
1466 u32 base, value;
Mathias Nymana5d811b2013-06-18 14:33:02 +03001467
1468 /* clear interrupt status trigger registers */
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001469 for (base = 0; base < vg->soc->npins; base += 32) {
Cristina Ciocanc501d0b2016-04-01 14:00:03 +03001470 reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001471
1472 if (!reg) {
Andy Shevchenko990ec242019-11-25 17:56:41 +02001473 dev_warn(vg->dev,
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001474 "Pin %i: could not retrieve irq status reg\n",
1475 base);
1476 continue;
1477 }
1478
Mathias Nymana5d811b2013-06-18 14:33:02 +03001479 writel(0xffffffff, reg);
1480 /* make sure trigger bits are cleared, if not then a pin
1481 might be misconfigured in bios */
1482 value = readl(reg);
1483 if (value)
Andy Shevchenko990ec242019-11-25 17:56:41 +02001484 dev_err(vg->dev,
Alexander Stein973232e2018-08-02 12:53:18 +02001485 "GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n",
1486 base / 32, value);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001487 }
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001488
1489 return 0;
Mathias Nymana5d811b2013-06-18 14:33:02 +03001490}
1491
Andy Shevchenkoed3c1562019-11-04 19:07:30 +02001492static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
1493{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001494 struct intel_pinctrl *vg = gpiochip_get_data(chip);
Andy Shevchenko990ec242019-11-25 17:56:41 +02001495 struct device *dev = vg->dev;
Andy Shevchenkoed3c1562019-11-04 19:07:30 +02001496 int ret;
1497
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001498 ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins);
Andy Shevchenkoed3c1562019-11-04 19:07:30 +02001499 if (ret)
1500 dev_err(dev, "failed to add GPIO pin range\n");
1501
1502 return ret;
1503}
1504
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001505static int byt_gpio_probe(struct intel_pinctrl *vg)
Mathias Nymana5d811b2013-06-18 14:33:02 +03001506{
Andy Shevchenko990ec242019-11-25 17:56:41 +02001507 struct platform_device *pdev = to_platform_device(vg->dev);
Mathias Nymana5d811b2013-06-18 14:33:02 +03001508 struct gpio_chip *gc;
Andy Shevchenkof86a1bb2020-04-14 19:13:37 +03001509 int irq, ret;
Mathias Nymana5d811b2013-06-18 14:33:02 +03001510
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001511 /* Set up gpio chip */
1512 vg->chip = byt_gpio_chip;
1513 gc = &vg->chip;
Andy Shevchenko990ec242019-11-25 17:56:41 +02001514 gc->label = dev_name(vg->dev);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001515 gc->base = -1;
1516 gc->can_sleep = false;
Andy Shevchenkoed3c1562019-11-04 19:07:30 +02001517 gc->add_pin_ranges = byt_gpio_add_pin_ranges;
Andy Shevchenko990ec242019-11-25 17:56:41 +02001518 gc->parent = vg->dev;
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001519 gc->ngpio = vg->soc->npins;
Mathias Nymana5d811b2013-06-18 14:33:02 +03001520
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001521#ifdef CONFIG_PM_SLEEP
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001522 vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads),
1523 GFP_KERNEL);
1524 if (!vg->context.pads)
Aditya Pakkid6cb7722019-03-12 10:05:52 -05001525 return -ENOMEM;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001526#endif
Jin Yao605a7bc2014-05-15 18:28:47 +03001527
Mika Westerberge1ee5c52014-07-25 09:54:47 +03001528 /* set up interrupts */
Andy Shevchenkof86a1bb2020-04-14 19:13:37 +03001529 irq = platform_get_irq_optional(pdev, 0);
1530 if (irq > 0) {
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001531 struct gpio_irq_chip *girq;
Mika Westerberge1ee5c52014-07-25 09:54:47 +03001532
Andy Shevchenko539d8bd2019-10-24 17:33:42 +03001533 vg->irqchip.name = "BYT-GPIO",
1534 vg->irqchip.irq_ack = byt_irq_ack,
1535 vg->irqchip.irq_mask = byt_irq_mask,
1536 vg->irqchip.irq_unmask = byt_irq_unmask,
1537 vg->irqchip.irq_set_type = byt_irq_type,
1538 vg->irqchip.flags = IRQCHIP_SKIP_SET_WAKE,
1539
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001540 girq = &gc->irq;
Andy Shevchenko539d8bd2019-10-24 17:33:42 +03001541 girq->chip = &vg->irqchip;
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001542 girq->init_hw = byt_gpio_irq_init_hw;
Andy Shevchenkoab68b222019-10-24 17:33:43 +03001543 girq->init_valid_mask = byt_init_irq_valid_mask;
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001544 girq->parent_handler = byt_gpio_irq_handler;
1545 girq->num_parents = 1;
Andy Shevchenko990ec242019-11-25 17:56:41 +02001546 girq->parents = devm_kcalloc(vg->dev, girq->num_parents,
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001547 sizeof(*girq->parents), GFP_KERNEL);
1548 if (!girq->parents)
1549 return -ENOMEM;
Andy Shevchenkof86a1bb2020-04-14 19:13:37 +03001550 girq->parents[0] = irq;
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001551 girq->default_type = IRQ_TYPE_NONE;
1552 girq->handler = handle_bad_irq;
1553 }
1554
Andy Shevchenko990ec242019-11-25 17:56:41 +02001555 ret = devm_gpiochip_add_data(vg->dev, gc, vg);
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001556 if (ret) {
Andy Shevchenko990ec242019-11-25 17:56:41 +02001557 dev_err(vg->dev, "failed adding byt-gpio chip\n");
Andy Shevchenkoca8a9582019-11-05 15:41:11 +02001558 return ret;
Mika Westerberge1ee5c52014-07-25 09:54:47 +03001559 }
1560
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001561 return ret;
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001562}
1563
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001564static int byt_set_soc_data(struct intel_pinctrl *vg,
1565 const struct intel_pinctrl_soc_data *soc)
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001566{
Andy Shevchenko990ec242019-11-25 17:56:41 +02001567 struct platform_device *pdev = to_platform_device(vg->dev);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001568 int i;
1569
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001570 vg->soc = soc;
1571
1572 vg->ncommunities = vg->soc->ncommunities;
1573 vg->communities = devm_kcalloc(vg->dev, vg->ncommunities,
1574 sizeof(*vg->communities), GFP_KERNEL);
1575 if (!vg->communities)
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001576 return -ENOMEM;
1577
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001578 for (i = 0; i < vg->soc->ncommunities; i++) {
1579 struct intel_community *comm = vg->communities + i;
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001580
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001581 *comm = vg->soc->communities[i];
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001582
Andy Shevchenko990ec242019-11-25 17:56:41 +02001583 comm->pad_regs = devm_platform_ioremap_resource(pdev, 0);
Andy Shevchenko34e65672019-07-26 23:16:36 +03001584 if (IS_ERR(comm->pad_regs))
1585 return PTR_ERR(comm->pad_regs);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001586 }
1587
1588 return 0;
1589}
1590
1591static const struct acpi_device_id byt_gpio_acpi_match[] = {
1592 { "INT33B2", (kernel_ulong_t)byt_soc_data },
1593 { "INT33FC", (kernel_ulong_t)byt_soc_data },
1594 { }
1595};
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001596
1597static int byt_pinctrl_probe(struct platform_device *pdev)
1598{
Andy Shevchenko34e65672019-07-26 23:16:36 +03001599 const struct intel_pinctrl_soc_data *soc_data = NULL;
1600 const struct intel_pinctrl_soc_data **soc_table;
Andy Shevchenko2c02af72019-11-25 18:34:43 +02001601 struct device *dev = &pdev->dev;
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001602 struct acpi_device *acpi_dev;
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001603 struct intel_pinctrl *vg;
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001604 int i, ret;
1605
Andy Shevchenko2c02af72019-11-25 18:34:43 +02001606 acpi_dev = ACPI_COMPANION(dev);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001607 if (!acpi_dev)
1608 return -ENODEV;
1609
Andy Shevchenko2c02af72019-11-25 18:34:43 +02001610 soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(dev);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001611
1612 for (i = 0; soc_table[i]; i++) {
1613 if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
1614 soc_data = soc_table[i];
1615 break;
1616 }
1617 }
1618
1619 if (!soc_data)
1620 return -ENODEV;
1621
Andy Shevchenko2c02af72019-11-25 18:34:43 +02001622 vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001623 if (!vg)
1624 return -ENOMEM;
1625
Andy Shevchenko2c02af72019-11-25 18:34:43 +02001626 vg->dev = dev;
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001627 ret = byt_set_soc_data(vg, soc_data);
1628 if (ret) {
Andy Shevchenko2c02af72019-11-25 18:34:43 +02001629 dev_err(dev, "failed to set soc data\n");
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001630 return ret;
1631 }
1632
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001633 vg->pctldesc = byt_pinctrl_desc;
1634 vg->pctldesc.name = dev_name(dev);
1635 vg->pctldesc.pins = vg->soc->pins;
1636 vg->pctldesc.npins = vg->soc->npins;
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001637
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001638 vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg);
1639 if (IS_ERR(vg->pctldev)) {
Andy Shevchenko2c02af72019-11-25 18:34:43 +02001640 dev_err(dev, "failed to register pinctrl driver\n");
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001641 return PTR_ERR(vg->pctldev);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001642 }
1643
1644 ret = byt_gpio_probe(vg);
Andy Shevchenko06124132017-01-10 22:11:39 +02001645 if (ret)
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001646 return ret;
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001647
1648 platform_set_drvdata(pdev, vg);
Andy Shevchenko2c02af72019-11-25 18:34:43 +02001649 pm_runtime_enable(dev);
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001650
1651 return 0;
1652}
1653
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001654#ifdef CONFIG_PM_SLEEP
1655static int byt_gpio_suspend(struct device *dev)
1656{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001657 struct intel_pinctrl *vg = dev_get_drvdata(dev);
Hans de Goede40ecab552019-11-19 16:46:41 +01001658 unsigned long flags;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001659 int i;
1660
Hans de Goede40ecab552019-11-19 16:46:41 +01001661 raw_spin_lock_irqsave(&byt_lock, flags);
1662
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001663 for (i = 0; i < vg->soc->npins; i++) {
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001664 void __iomem *reg;
1665 u32 value;
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001666 unsigned int pin = vg->soc->pins[i].number;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001667
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001668 reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
1669 if (!reg) {
Andy Shevchenko990ec242019-11-25 17:56:41 +02001670 dev_warn(vg->dev,
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001671 "Pin %i: could not retrieve conf0 register\n",
1672 i);
1673 continue;
1674 }
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001675 value = readl(reg) & BYT_CONF0_RESTORE_MASK;
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001676 vg->context.pads[i].conf0 = value;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001677
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001678 reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001679 value = readl(reg) & BYT_VAL_RESTORE_MASK;
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001680 vg->context.pads[i].val = value;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001681 }
1682
Hans de Goede40ecab552019-11-19 16:46:41 +01001683 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001684 return 0;
1685}
1686
1687static int byt_gpio_resume(struct device *dev)
1688{
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001689 struct intel_pinctrl *vg = dev_get_drvdata(dev);
Hans de Goede40ecab552019-11-19 16:46:41 +01001690 unsigned long flags;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001691 int i;
1692
Hans de Goede40ecab552019-11-19 16:46:41 +01001693 raw_spin_lock_irqsave(&byt_lock, flags);
1694
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001695 for (i = 0; i < vg->soc->npins; i++) {
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001696 void __iomem *reg;
1697 u32 value;
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001698 unsigned int pin = vg->soc->pins[i].number;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001699
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001700 reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
1701 if (!reg) {
Andy Shevchenko990ec242019-11-25 17:56:41 +02001702 dev_warn(vg->dev,
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001703 "Pin %i: could not retrieve conf0 register\n",
1704 i);
1705 continue;
1706 }
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001707 value = readl(reg);
1708 if ((value & BYT_CONF0_RESTORE_MASK) !=
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001709 vg->context.pads[i].conf0) {
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001710 value &= ~BYT_CONF0_RESTORE_MASK;
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001711 value |= vg->context.pads[i].conf0;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001712 writel(value, reg);
1713 dev_info(dev, "restored pin %d conf0 %#08x", i, value);
1714 }
1715
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001716 reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001717 value = readl(reg);
1718 if ((value & BYT_VAL_RESTORE_MASK) !=
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001719 vg->context.pads[i].val) {
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001720 u32 v;
1721
1722 v = value & ~BYT_VAL_RESTORE_MASK;
Andy Shevchenko5d33e0e2019-11-25 18:37:22 +02001723 v |= vg->context.pads[i].val;
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001724 if (v != value) {
1725 writel(v, reg);
1726 dev_dbg(dev, "restored pin %d val %#08x\n",
1727 i, v);
1728 }
1729 }
1730 }
1731
Hans de Goede40ecab552019-11-19 16:46:41 +01001732 raw_spin_unlock_irqrestore(&byt_lock, flags);
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001733 return 0;
1734}
1735#endif
1736
Mika Westerbergec879f12015-10-13 17:51:26 +03001737#ifdef CONFIG_PM
Mathias Nymana5d811b2013-06-18 14:33:02 +03001738static int byt_gpio_runtime_suspend(struct device *dev)
1739{
1740 return 0;
1741}
1742
1743static int byt_gpio_runtime_resume(struct device *dev)
1744{
1745 return 0;
1746}
Mika Westerbergec879f12015-10-13 17:51:26 +03001747#endif
Mathias Nymana5d811b2013-06-18 14:33:02 +03001748
1749static const struct dev_pm_ops byt_gpio_pm_ops = {
Mika Westerbergfcc18de2015-02-23 14:53:13 +02001750 SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
1751 SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
1752 NULL)
Mathias Nymana5d811b2013-06-18 14:33:02 +03001753};
1754
Mathias Nymana5d811b2013-06-18 14:33:02 +03001755static struct platform_driver byt_gpio_driver = {
Cristina Ciocan71e6ca62016-04-01 14:00:06 +03001756 .probe = byt_pinctrl_probe,
Mathias Nymana5d811b2013-06-18 14:33:02 +03001757 .driver = {
Paul Gortmaker360943a2016-06-06 22:43:01 -04001758 .name = "byt_gpio",
1759 .pm = &byt_gpio_pm_ops,
1760 .suppress_bind_attrs = true,
1761
Mathias Nymana5d811b2013-06-18 14:33:02 +03001762 .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
1763 },
1764};
1765
1766static int __init byt_gpio_init(void)
1767{
1768 return platform_driver_register(&byt_gpio_driver);
1769}
Mathias Nymana5d811b2013-06-18 14:33:02 +03001770subsys_initcall(byt_gpio_init);