1875a92b3SAndy Shevchenko // SPDX-License-Identifier: GPL-2.0
25fae8b86SMika Westerberg /*
35fae8b86SMika Westerberg  * Pinctrl GPIO driver for Intel Baytrail
45fae8b86SMika Westerberg  *
5875a92b3SAndy Shevchenko  * Copyright (c) 2012-2013, Intel Corporation
65fae8b86SMika Westerberg  * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
75fae8b86SMika Westerberg  */
85fae8b86SMika Westerberg 
95fae8b86SMika Westerberg #include <linux/acpi.h>
10e0da3842SAndy Shevchenko #include <linux/bitops.h>
11e0da3842SAndy Shevchenko #include <linux/gpio/driver.h>
12e0da3842SAndy Shevchenko #include <linux/init.h>
13e0da3842SAndy Shevchenko #include <linux/interrupt.h>
145fae8b86SMika Westerberg #include <linux/io.h>
15e0da3842SAndy Shevchenko #include <linux/kernel.h>
16*4d01688fSRaag Jadav #include <linux/module.h>
17e0da3842SAndy Shevchenko #include <linux/types.h>
18e0da3842SAndy Shevchenko #include <linux/platform_device.h>
195fae8b86SMika Westerberg #include <linux/pm_runtime.h>
2061db6c9dSAndy Shevchenko #include <linux/property.h>
21e0da3842SAndy Shevchenko #include <linux/seq_file.h>
22c518d31bSAndy Shevchenko #include <linux/string_helpers.h>
2361db6c9dSAndy Shevchenko 
245fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h>
25c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h>
26c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h>
27c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h>
285fae8b86SMika Westerberg 
294f010b93SAndy Shevchenko #include "pinctrl-intel.h"
304f010b93SAndy Shevchenko 
315fae8b86SMika Westerberg /* memory mapped register offsets */
325fae8b86SMika Westerberg #define BYT_CONF0_REG		0x000
335fae8b86SMika Westerberg #define BYT_CONF1_REG		0x004
345fae8b86SMika Westerberg #define BYT_VAL_REG		0x008
355fae8b86SMika Westerberg #define BYT_DFT_REG		0x00c
365fae8b86SMika Westerberg #define BYT_INT_STAT_REG	0x800
37689e0088SHans de Goede #define BYT_DIRECT_IRQ_REG	0x980
38658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG	0x9d0
395fae8b86SMika Westerberg 
405fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */
415fae8b86SMika Westerberg #define BYT_IODEN		BIT(31)
425fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN	BIT(27)
43eb0a2daaSAndy Shevchenko #define BYT_TRIG_MASK		GENMASK(26, 24)
445fae8b86SMika Westerberg #define BYT_TRIG_NEG		BIT(26)
455fae8b86SMika Westerberg #define BYT_TRIG_POS		BIT(25)
465fae8b86SMika Westerberg #define BYT_TRIG_LVL		BIT(24)
47658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN		BIT(20)
489291c65bSHans de Goede #define BYT_GLITCH_FILTER_EN	BIT(19)
499291c65bSHans de Goede #define BYT_GLITCH_F_SLOW_CLK	BIT(17)
509291c65bSHans de Goede #define BYT_GLITCH_F_FAST_CLK	BIT(16)
515fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT	9
52eb0a2daaSAndy Shevchenko #define BYT_PULL_STR_MASK	GENMASK(10, 9)
535fae8b86SMika Westerberg #define BYT_PULL_STR_2K		(0 << BYT_PULL_STR_SHIFT)
545fae8b86SMika Westerberg #define BYT_PULL_STR_10K	(1 << BYT_PULL_STR_SHIFT)
555fae8b86SMika Westerberg #define BYT_PULL_STR_20K	(2 << BYT_PULL_STR_SHIFT)
565fae8b86SMika Westerberg #define BYT_PULL_STR_40K	(3 << BYT_PULL_STR_SHIFT)
57eb0a2daaSAndy Shevchenko #define BYT_PULL_ASSIGN_MASK	GENMASK(8, 7)
589d712086SAndy Shevchenko #define BYT_PULL_ASSIGN_DOWN	BIT(8)
599d712086SAndy Shevchenko #define BYT_PULL_ASSIGN_UP	BIT(7)
60eb0a2daaSAndy Shevchenko #define BYT_PIN_MUX		GENMASK(2, 0)
615fae8b86SMika Westerberg 
625fae8b86SMika Westerberg /* BYT_VAL_REG register bits */
63eb0a2daaSAndy Shevchenko #define BYT_DIR_MASK		GENMASK(2, 1)
645fae8b86SMika Westerberg #define BYT_INPUT_EN		BIT(2)  /* 0: input enabled (active low)*/
655fae8b86SMika Westerberg #define BYT_OUTPUT_EN		BIT(1)  /* 0: output enabled (active low)*/
665fae8b86SMika Westerberg #define BYT_LEVEL		BIT(0)
675fae8b86SMika Westerberg 
68eb0a2daaSAndy Shevchenko #define BYT_CONF0_RESTORE_MASK	(BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX)
69fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK	(BYT_DIR_MASK | BYT_LEVEL)
70fcc18debSMika Westerberg 
71658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */
72eb0a2daaSAndy Shevchenko #define BYT_DEBOUNCE_PULSE_MASK		GENMASK(2, 0)
73658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US	1
74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US	2
75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US	3
76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS		4
77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS		5
78658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS		6
79658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS		7
80658b476cSCristina Ciocan 
815fae8b86SMika Westerberg #define BYT_NGPIO_SCORE		102
825fae8b86SMika Westerberg #define BYT_NGPIO_NCORE		28
835fae8b86SMika Westerberg #define BYT_NGPIO_SUS		44
845fae8b86SMika Westerberg 
855fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID	"1"
865fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID	"2"
875fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID	"3"
885fae8b86SMika Westerberg 
89c501d0b1SCristina Ciocan /*
90c501d0b1SCristina Ciocan  * This is the function value most pins have for GPIO muxing. If the value
91c501d0b1SCristina Ciocan  * differs from the default one, it must be explicitly mentioned. Otherwise, the
92c501d0b1SCristina Ciocan  * pin control implementation will set the muxing value to default GPIO if it
93c501d0b1SCristina Ciocan  * does not find a match for the requested function.
94c501d0b1SCristina Ciocan  */
95c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX	0
96a705f9c1SAndy Shevchenko #define BYT_ALTER_GPIO_MUX	1
97c501d0b1SCristina Ciocan 
985d33e0ebSAndy Shevchenko struct intel_pad_context {
99c8f5c4c7SCristina Ciocan 	u32 conf0;
100c8f5c4c7SCristina Ciocan 	u32 val;
101c8f5c4c7SCristina Ciocan };
1025fae8b86SMika Westerberg 
103c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map)		\
104c8f5c4c7SCristina Ciocan 	{				\
105c8f5c4c7SCristina Ciocan 		.pin_base	= (p),	\
106c8f5c4c7SCristina Ciocan 		.npins		= (n),	\
107c8f5c4c7SCristina Ciocan 		.pad_map	= (map),\
108c8f5c4c7SCristina Ciocan 	}
109c8f5c4c7SCristina Ciocan 
110c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */
111c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = {
112c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "SATA_GP0"),
113c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "SATA_GP1"),
114c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "SATA_LED#"),
115c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "PCIE_CLKREQ0"),
116c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "PCIE_CLKREQ1"),
117c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "PCIE_CLKREQ2"),
118c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "PCIE_CLKREQ3"),
119c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "SD3_WP"),
120c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "HDA_RST"),
121c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "HDA_SYNC"),
122c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "HDA_CLK"),
123c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "HDA_SDO"),
124c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "HDA_SDI0"),
125c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "HDA_SDI1"),
126c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "GPIO_S0_SC14"),
127c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "GPIO_S0_SC15"),
128c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "MMC1_CLK"),
129c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "MMC1_D0"),
130c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "MMC1_D1"),
131c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "MMC1_D2"),
132c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "MMC1_D3"),
133c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "MMC1_D4"),
134c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "MMC1_D5"),
135c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "MMC1_D6"),
136c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "MMC1_D7"),
137c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "MMC1_CMD"),
138c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "MMC1_RST"),
139c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "SD2_CLK"),
140c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(28, "SD2_D0"),
141c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(29, "SD2_D1"),
142c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(30, "SD2_D2"),
143c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(31, "SD2_D3_CD"),
144c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(32, "SD2_CMD"),
145c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(33, "SD3_CLK"),
146c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(34, "SD3_D0"),
147c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(35, "SD3_D1"),
148c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(36, "SD3_D2"),
149c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(37, "SD3_D3"),
150c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(38, "SD3_CD"),
151c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(39, "SD3_CMD"),
152c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(40, "SD3_1P8EN"),
153c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(41, "SD3_PWREN#"),
154c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(42, "ILB_LPC_AD0"),
155c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(43, "ILB_LPC_AD1"),
156c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(44, "ILB_LPC_AD2"),
157c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(45, "ILB_LPC_AD3"),
158c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(46, "ILB_LPC_FRAME"),
159c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(47, "ILB_LPC_CLK0"),
160c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(48, "ILB_LPC_CLK1"),
161c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(49, "ILB_LPC_CLKRUN"),
162c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(50, "ILB_LPC_SERIRQ"),
163c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(51, "PCU_SMB_DATA"),
164c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(52, "PCU_SMB_CLK"),
165c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(53, "PCU_SMB_ALERT"),
166c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(54, "ILB_8254_SPKR"),
167c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(55, "GPIO_S0_SC55"),
168c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(56, "GPIO_S0_SC56"),
169c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(57, "GPIO_S0_SC57"),
170c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(58, "GPIO_S0_SC58"),
171c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(59, "GPIO_S0_SC59"),
172c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(60, "GPIO_S0_SC60"),
173c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(61, "GPIO_S0_SC61"),
174c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(62, "LPE_I2S2_CLK"),
175c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(63, "LPE_I2S2_FRM"),
176c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(64, "LPE_I2S2_DATAIN"),
177c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"),
178c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(66, "SIO_SPI_CS"),
179c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(67, "SIO_SPI_MISO"),
180c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(68, "SIO_SPI_MOSI"),
181c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(69, "SIO_SPI_CLK"),
182c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(70, "SIO_UART1_RXD"),
183c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(71, "SIO_UART1_TXD"),
184c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(72, "SIO_UART1_RTS"),
185c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(73, "SIO_UART1_CTS"),
186c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(74, "SIO_UART2_RXD"),
187c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(75, "SIO_UART2_TXD"),
188c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(76, "SIO_UART2_RTS"),
189c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(77, "SIO_UART2_CTS"),
190c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(78, "SIO_I2C0_DATA"),
191c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(79, "SIO_I2C0_CLK"),
192c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(80, "SIO_I2C1_DATA"),
193c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(81, "SIO_I2C1_CLK"),
194c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(82, "SIO_I2C2_DATA"),
195c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(83, "SIO_I2C2_CLK"),
196c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(84, "SIO_I2C3_DATA"),
197c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(85, "SIO_I2C3_CLK"),
198c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(86, "SIO_I2C4_DATA"),
199c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(87, "SIO_I2C4_CLK"),
200c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(88, "SIO_I2C5_DATA"),
201c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(89, "SIO_I2C5_CLK"),
202c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(90, "SIO_I2C6_DATA"),
203c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(91, "SIO_I2C6_CLK"),
204c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(92, "GPIO_S0_SC92"),
205c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(93, "GPIO_S0_SC93"),
206c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(94, "SIO_PWM0"),
207c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(95, "SIO_PWM1"),
208c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(96, "PMC_PLT_CLK0"),
209c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(97, "PMC_PLT_CLK1"),
210c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(98, "PMC_PLT_CLK2"),
211c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(99, "PMC_PLT_CLK3"),
212c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(100, "PMC_PLT_CLK4"),
213c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(101, "PMC_PLT_CLK5"),
214c8f5c4c7SCristina Ciocan };
2155fae8b86SMika Westerberg 
216c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = {
217c8f5c4c7SCristina Ciocan 	85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
218c8f5c4c7SCristina Ciocan 	36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
219c8f5c4c7SCristina Ciocan 	54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
220c8f5c4c7SCristina Ciocan 	52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
221c8f5c4c7SCristina Ciocan 	95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
222c8f5c4c7SCristina Ciocan 	86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
223c8f5c4c7SCristina Ciocan 	80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
224c8f5c4c7SCristina Ciocan 	2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
225c8f5c4c7SCristina Ciocan 	31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
226c8f5c4c7SCristina Ciocan 	24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
227c8f5c4c7SCristina Ciocan 	97, 100,
2285fae8b86SMika Westerberg };
2295fae8b86SMika Westerberg 
230c8f5c4c7SCristina Ciocan /* SCORE groups */
231c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 };
232c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 };
233c8f5c4c7SCristina Ciocan 
234c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 };
235c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 };
236c8f5c4c7SCristina Ciocan 
237c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 };
238c8f5c4c7SCristina Ciocan 
239c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 };
240c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 };
241c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 };
242c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 };
243c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 };
244c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 };
245c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 };
246c8f5c4c7SCristina Ciocan 
247c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 };
248c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 };
249c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 };
250c8f5c4c7SCristina Ciocan 
251c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = {
252c8f5c4c7SCristina Ciocan 	7, 33, 34, 35, 36, 37, 38, 39, 40, 41,
253c8f5c4c7SCristina Ciocan };
2544f010b93SAndy Shevchenko static const unsigned int byt_score_sdcard_mux_values[] = {
255c8f5c4c7SCristina Ciocan 	2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
256c8f5c4c7SCristina Ciocan };
257c8f5c4c7SCristina Ciocan 
258c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 };
259c8f5c4c7SCristina Ciocan 
260c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = {
261c8f5c4c7SCristina Ciocan 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
262c8f5c4c7SCristina Ciocan };
263c8f5c4c7SCristina Ciocan 
264c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = {
265c8f5c4c7SCristina Ciocan 	42, 43, 44, 45, 46, 47, 48, 49, 50,
266c8f5c4c7SCristina Ciocan };
267c8f5c4c7SCristina Ciocan 
268c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 };
269c8f5c4c7SCristina Ciocan 
270c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 };
271c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 };
272c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 };
273b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 };
274b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 };
275b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
276c8f5c4c7SCristina Ciocan 
277c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
278c8f5c4c7SCristina Ciocan 
2794f010b93SAndy Shevchenko static const struct intel_pingroup byt_score_groups[] = {
2804f010b93SAndy Shevchenko 	PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1),
2814f010b93SAndy Shevchenko 	PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1),
2824f010b93SAndy Shevchenko 	PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1),
2834f010b93SAndy Shevchenko 	PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1),
2844f010b93SAndy Shevchenko 	PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1),
2854f010b93SAndy Shevchenko 	PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1),
2864f010b93SAndy Shevchenko 	PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1),
2874f010b93SAndy Shevchenko 	PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1),
2884f010b93SAndy Shevchenko 	PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1),
2894f010b93SAndy Shevchenko 	PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1),
2904f010b93SAndy Shevchenko 	PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1),
2914f010b93SAndy Shevchenko 	PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1),
2924f010b93SAndy Shevchenko 	PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1),
2934f010b93SAndy Shevchenko 	PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1),
2944f010b93SAndy Shevchenko 	PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1),
2954f010b93SAndy Shevchenko 	PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
2964f010b93SAndy Shevchenko 	PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1),
2974f010b93SAndy Shevchenko 	PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1),
2984f010b93SAndy Shevchenko 	PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1),
2994f010b93SAndy Shevchenko 	PIN_GROUP("sata_grp", byt_score_sata_pins, 1),
3004f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
3014f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
3024f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
3034f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
3044f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
3054f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
3064f010b93SAndy Shevchenko 	PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1),
307c8f5c4c7SCristina Ciocan };
308c8f5c4c7SCristina Ciocan 
309c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = {
310c8f5c4c7SCristina Ciocan 	"uart1_grp", "uart2_grp",
311c8f5c4c7SCristina Ciocan };
312c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = {
313c8f5c4c7SCristina Ciocan 	"pwm0_grp", "pwm1_grp",
314c8f5c4c7SCristina Ciocan };
315c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = {
316c8f5c4c7SCristina Ciocan 	"ssp0_grp", "ssp1_grp", "ssp2_grp",
317c8f5c4c7SCristina Ciocan };
318c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" };
319c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = {
320c8f5c4c7SCristina Ciocan 	"i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp",
321c8f5c4c7SCristina Ciocan 	"i2c6_grp",
322c8f5c4c7SCristina Ciocan };
323c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" };
324c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" };
325c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" };
326c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" };
327c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" };
328c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = {
329c8f5c4c7SCristina Ciocan 	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
330c8f5c4c7SCristina Ciocan 	"plt_clk4_grp", "plt_clk5_grp",
331c8f5c4c7SCristina Ciocan };
332c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
333c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = {
334c8f5c4c7SCristina Ciocan 	"uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
335c8f5c4c7SCristina Ciocan 	"ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
336c8f5c4c7SCristina Ciocan 	"i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
337c8f5c4c7SCristina Ciocan 	"sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
338c8f5c4c7SCristina Ciocan 	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
339c8f5c4c7SCristina Ciocan 	"plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
340c8f5c4c7SCristina Ciocan };
341c8f5c4c7SCristina Ciocan 
3424f010b93SAndy Shevchenko static const struct intel_function byt_score_functions[] = {
343c8f5c4c7SCristina Ciocan 	FUNCTION("uart", byt_score_uart_groups),
344c8f5c4c7SCristina Ciocan 	FUNCTION("pwm", byt_score_pwm_groups),
345c8f5c4c7SCristina Ciocan 	FUNCTION("ssp", byt_score_ssp_groups),
346c8f5c4c7SCristina Ciocan 	FUNCTION("spi", byt_score_spi_groups),
347c8f5c4c7SCristina Ciocan 	FUNCTION("i2c", byt_score_i2c_groups),
348c8f5c4c7SCristina Ciocan 	FUNCTION("sdcard", byt_score_sdcard_groups),
349c8f5c4c7SCristina Ciocan 	FUNCTION("sdio", byt_score_sdio_groups),
350c8f5c4c7SCristina Ciocan 	FUNCTION("emmc", byt_score_emmc_groups),
351c8f5c4c7SCristina Ciocan 	FUNCTION("lpc", byt_score_lpc_groups),
352c8f5c4c7SCristina Ciocan 	FUNCTION("sata", byt_score_sata_groups),
353c8f5c4c7SCristina Ciocan 	FUNCTION("plt_clk", byt_score_plt_clk_groups),
354c8f5c4c7SCristina Ciocan 	FUNCTION("smbus", byt_score_smbus_groups),
355c8f5c4c7SCristina Ciocan 	FUNCTION("gpio", byt_score_gpio_groups),
356c8f5c4c7SCristina Ciocan };
357c8f5c4c7SCristina Ciocan 
35834e65670SAndy Shevchenko static const struct intel_community byt_score_communities[] = {
359c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
360c8f5c4c7SCristina Ciocan };
361c8f5c4c7SCristina Ciocan 
36234e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_score_soc_data = {
363c8f5c4c7SCristina Ciocan 	.uid		= BYT_SCORE_ACPI_UID,
364c8f5c4c7SCristina Ciocan 	.pins		= byt_score_pins,
365c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_score_pins),
366c8f5c4c7SCristina Ciocan 	.groups		= byt_score_groups,
367c8f5c4c7SCristina Ciocan 	.ngroups	= ARRAY_SIZE(byt_score_groups),
368c8f5c4c7SCristina Ciocan 	.functions	= byt_score_functions,
369c8f5c4c7SCristina Ciocan 	.nfunctions	= ARRAY_SIZE(byt_score_functions),
370c8f5c4c7SCristina Ciocan 	.communities	= byt_score_communities,
371c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_score_communities),
372c8f5c4c7SCristina Ciocan };
373c8f5c4c7SCristina Ciocan 
374c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>]  */
375c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = {
376c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "GPIO_S50"),
377c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "GPIO_S51"),
378c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "GPIO_S52"),
379c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "GPIO_S53"),
380c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "GPIO_S54"),
381c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "GPIO_S55"),
382c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "GPIO_S56"),
383c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "GPIO_S57"),
384c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "GPIO_S58"),
385c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "GPIO_S59"),
386c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "GPIO_S510"),
387c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "PMC_SUSPWRDNACK"),
388c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "PMC_SUSCLK0"),
389c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "GPIO_S513"),
390c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "USB_ULPI_RST"),
391c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"),
392c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "PMC_PWRBTN"),
393c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "GPIO_S517"),
394c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "PMC_SUS_STAT"),
395c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "USB_OC0"),
396c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "USB_OC1"),
397c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "PCU_SPI_CS1"),
398c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "GPIO_S522"),
399c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "GPIO_S523"),
400c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "GPIO_S524"),
401c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "GPIO_S525"),
402c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "GPIO_S526"),
403c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "GPIO_S527"),
404c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(28, "GPIO_S528"),
405c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(29, "GPIO_S529"),
406c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(30, "GPIO_S530"),
407c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(31, "USB_ULPI_CLK"),
408c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(32, "USB_ULPI_DATA0"),
409c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(33, "USB_ULPI_DATA1"),
410c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(34, "USB_ULPI_DATA2"),
411c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(35, "USB_ULPI_DATA3"),
412c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(36, "USB_ULPI_DATA4"),
413c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(37, "USB_ULPI_DATA5"),
414c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(38, "USB_ULPI_DATA6"),
415c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(39, "USB_ULPI_DATA7"),
416c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(40, "USB_ULPI_DIR"),
417c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(41, "USB_ULPI_NXT"),
418c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(42, "USB_ULPI_STP"),
419c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(43, "USB_ULPI_REFCLK"),
420c8f5c4c7SCristina Ciocan };
421c8f5c4c7SCristina Ciocan 
422c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = {
423c8f5c4c7SCristina Ciocan 	29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
424c8f5c4c7SCristina Ciocan 	18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
425c8f5c4c7SCristina Ciocan 	0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
426c8f5c4c7SCristina Ciocan 	26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
427c8f5c4c7SCristina Ciocan 	52, 53, 59, 40,
428c8f5c4c7SCristina Ciocan };
429c8f5c4c7SCristina Ciocan 
430c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 };
4314f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 };
4324f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 };
433c8f5c4c7SCristina Ciocan 
434c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = {
435c8f5c4c7SCristina Ciocan 	14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
436c8f5c4c7SCristina Ciocan };
4374f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_mode_values[] = {
438c8f5c4c7SCristina Ciocan 	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
439c8f5c4c7SCristina Ciocan };
4404f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = {
4414f010b93SAndy Shevchenko 	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
442c8f5c4c7SCristina Ciocan };
443c8f5c4c7SCristina Ciocan 
444c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 };
4454f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 };
4464f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 };
447c8f5c4c7SCristina Ciocan 
4482f46d7f7SHans de Goede static const unsigned int byt_sus_pmu_clk1_pins[] = { 5 };
4492f46d7f7SHans de Goede static const unsigned int byt_sus_pmu_clk2_pins[] = { 6 };
4502f46d7f7SHans de Goede 
4514f010b93SAndy Shevchenko static const struct intel_pingroup byt_sus_groups[] = {
4524f010b93SAndy Shevchenko 	PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values),
4534f010b93SAndy Shevchenko 	PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values),
4544f010b93SAndy Shevchenko 	PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values),
4554f010b93SAndy Shevchenko 	PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values),
4564f010b93SAndy Shevchenko 	PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values),
4574f010b93SAndy Shevchenko 	PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values),
4582f46d7f7SHans de Goede 	PIN_GROUP("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
4592f46d7f7SHans de Goede 	PIN_GROUP("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
460c8f5c4c7SCristina Ciocan };
461c8f5c4c7SCristina Ciocan 
462c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = {
463c8f5c4c7SCristina Ciocan 	"usb_oc_grp", "usb_ulpi_grp",
464c8f5c4c7SCristina Ciocan };
465c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" };
4662f46d7f7SHans de Goede static const char * const byt_sus_pmu_clk_groups[] = {
4672f46d7f7SHans de Goede 	"pmu_clk1_grp", "pmu_clk2_grp",
4682f46d7f7SHans de Goede };
469c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = {
4704f010b93SAndy Shevchenko 	"usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio",
4712f46d7f7SHans de Goede 	"pmu_clk1_grp", "pmu_clk2_grp",
472c8f5c4c7SCristina Ciocan };
473c8f5c4c7SCristina Ciocan 
4744f010b93SAndy Shevchenko static const struct intel_function byt_sus_functions[] = {
475c8f5c4c7SCristina Ciocan 	FUNCTION("usb", byt_sus_usb_groups),
476c8f5c4c7SCristina Ciocan 	FUNCTION("spi", byt_sus_spi_groups),
477c8f5c4c7SCristina Ciocan 	FUNCTION("gpio", byt_sus_gpio_groups),
4782f46d7f7SHans de Goede 	FUNCTION("pmu_clk", byt_sus_pmu_clk_groups),
479c8f5c4c7SCristina Ciocan };
480c8f5c4c7SCristina Ciocan 
48134e65670SAndy Shevchenko static const struct intel_community byt_sus_communities[] = {
482c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
483c8f5c4c7SCristina Ciocan };
484c8f5c4c7SCristina Ciocan 
48534e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
486c8f5c4c7SCristina Ciocan 	.uid		= BYT_SUS_ACPI_UID,
487c8f5c4c7SCristina Ciocan 	.pins		= byt_sus_pins,
488c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_sus_pins),
489c8f5c4c7SCristina Ciocan 	.groups		= byt_sus_groups,
490c8f5c4c7SCristina Ciocan 	.ngroups	= ARRAY_SIZE(byt_sus_groups),
491c8f5c4c7SCristina Ciocan 	.functions	= byt_sus_functions,
492c8f5c4c7SCristina Ciocan 	.nfunctions	= ARRAY_SIZE(byt_sus_functions),
493c8f5c4c7SCristina Ciocan 	.communities	= byt_sus_communities,
494c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_sus_communities),
495c8f5c4c7SCristina Ciocan };
496c8f5c4c7SCristina Ciocan 
497c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = {
498b30b736aSAndy Shevchenko 	PINCTRL_PIN(0, "HV_DDI0_HPD"),
499b30b736aSAndy Shevchenko 	PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"),
500b30b736aSAndy Shevchenko 	PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"),
501b30b736aSAndy Shevchenko 	PINCTRL_PIN(3, "PANEL0_VDDEN"),
502b30b736aSAndy Shevchenko 	PINCTRL_PIN(4, "PANEL0_BKLTEN"),
503b30b736aSAndy Shevchenko 	PINCTRL_PIN(5, "PANEL0_BKLTCTL"),
504b30b736aSAndy Shevchenko 	PINCTRL_PIN(6, "HV_DDI1_HPD"),
505b30b736aSAndy Shevchenko 	PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"),
506b30b736aSAndy Shevchenko 	PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"),
507b30b736aSAndy Shevchenko 	PINCTRL_PIN(9, "PANEL1_VDDEN"),
508b30b736aSAndy Shevchenko 	PINCTRL_PIN(10, "PANEL1_BKLTEN"),
509b30b736aSAndy Shevchenko 	PINCTRL_PIN(11, "PANEL1_BKLTCTL"),
510b30b736aSAndy Shevchenko 	PINCTRL_PIN(12, "GP_INTD_DSI_TE1"),
511b30b736aSAndy Shevchenko 	PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"),
512b30b736aSAndy Shevchenko 	PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"),
513b30b736aSAndy Shevchenko 	PINCTRL_PIN(15, "GP_CAMERASB00"),
514b30b736aSAndy Shevchenko 	PINCTRL_PIN(16, "GP_CAMERASB01"),
515b30b736aSAndy Shevchenko 	PINCTRL_PIN(17, "GP_CAMERASB02"),
516b30b736aSAndy Shevchenko 	PINCTRL_PIN(18, "GP_CAMERASB03"),
517b30b736aSAndy Shevchenko 	PINCTRL_PIN(19, "GP_CAMERASB04"),
518b30b736aSAndy Shevchenko 	PINCTRL_PIN(20, "GP_CAMERASB05"),
519b30b736aSAndy Shevchenko 	PINCTRL_PIN(21, "GP_CAMERASB06"),
520b30b736aSAndy Shevchenko 	PINCTRL_PIN(22, "GP_CAMERASB07"),
521b30b736aSAndy Shevchenko 	PINCTRL_PIN(23, "GP_CAMERASB08"),
522b30b736aSAndy Shevchenko 	PINCTRL_PIN(24, "GP_CAMERASB09"),
523b30b736aSAndy Shevchenko 	PINCTRL_PIN(25, "GP_CAMERASB10"),
524b30b736aSAndy Shevchenko 	PINCTRL_PIN(26, "GP_CAMERASB11"),
525b30b736aSAndy Shevchenko 	PINCTRL_PIN(27, "GP_INTD_DSI_TE2"),
526c8f5c4c7SCristina Ciocan };
527c8f5c4c7SCristina Ciocan 
528939330d7SAndy Shevchenko static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
529c8f5c4c7SCristina Ciocan 	19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
530c8f5c4c7SCristina Ciocan 	14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
531c8f5c4c7SCristina Ciocan 	3, 6, 10, 13, 2, 5, 9, 7,
532c8f5c4c7SCristina Ciocan };
533c8f5c4c7SCristina Ciocan 
53434e65670SAndy Shevchenko static const struct intel_community byt_ncore_communities[] = {
535c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
536c8f5c4c7SCristina Ciocan };
537c8f5c4c7SCristina Ciocan 
53834e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
539c8f5c4c7SCristina Ciocan 	.uid		= BYT_NCORE_ACPI_UID,
540c8f5c4c7SCristina Ciocan 	.pins		= byt_ncore_pins,
541c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_ncore_pins),
542c8f5c4c7SCristina Ciocan 	.communities	= byt_ncore_communities,
543c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_ncore_communities),
544c8f5c4c7SCristina Ciocan };
545c8f5c4c7SCristina Ciocan 
54634e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data *byt_soc_data[] = {
547c8f5c4c7SCristina Ciocan 	&byt_score_soc_data,
548c8f5c4c7SCristina Ciocan 	&byt_sus_soc_data,
549c8f5c4c7SCristina Ciocan 	&byt_ncore_soc_data,
550166d6e2aSAndy Shevchenko 	NULL
551c8f5c4c7SCristina Ciocan };
552c8f5c4c7SCristina Ciocan 
55340ecab55SHans de Goede static DEFINE_RAW_SPINLOCK(byt_lock);
55440ecab55SHans de Goede 
5555d33e0ebSAndy Shevchenko static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset,
5565fae8b86SMika Westerberg 				  int reg)
5575fae8b86SMika Westerberg {
558*4d01688fSRaag Jadav 	struct intel_community *comm = intel_get_community(vg, offset);
5591b89970dSAndy Shevchenko 	u32 reg_offset;
5605fae8b86SMika Westerberg 
561c501d0b1SCristina Ciocan 	if (!comm)
562c501d0b1SCristina Ciocan 		return NULL;
563c501d0b1SCristina Ciocan 
564c501d0b1SCristina Ciocan 	offset -= comm->pin_base;
5651b89970dSAndy Shevchenko 	switch (reg) {
5661b89970dSAndy Shevchenko 	case BYT_INT_STAT_REG:
5675fae8b86SMika Westerberg 		reg_offset = (offset / 32) * 4;
5681b89970dSAndy Shevchenko 		break;
5691b89970dSAndy Shevchenko 	case BYT_DEBOUNCE_REG:
5701b89970dSAndy Shevchenko 		reg_offset = 0;
5711b89970dSAndy Shevchenko 		break;
5721b89970dSAndy Shevchenko 	default:
573c501d0b1SCristina Ciocan 		reg_offset = comm->pad_map[offset] * 16;
5741b89970dSAndy Shevchenko 		break;
5751b89970dSAndy Shevchenko 	}
5765fae8b86SMika Westerberg 
57734e65670SAndy Shevchenko 	return comm->pad_regs + reg_offset + reg;
5785fae8b86SMika Westerberg }
5795fae8b86SMika Westerberg 
580c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = {
581*4d01688fSRaag Jadav 	.get_groups_count	= intel_get_groups_count,
582*4d01688fSRaag Jadav 	.get_group_name		= intel_get_group_name,
583*4d01688fSRaag Jadav 	.get_group_pins		= intel_get_group_pins,
584c501d0b1SCristina Ciocan };
585c501d0b1SCristina Ciocan 
5865d33e0ebSAndy Shevchenko static void byt_set_group_simple_mux(struct intel_pinctrl *vg,
5874f010b93SAndy Shevchenko 				     const struct intel_pingroup group,
5884f010b93SAndy Shevchenko 				     unsigned int func)
589c501d0b1SCristina Ciocan {
590c501d0b1SCristina Ciocan 	unsigned long flags;
591c501d0b1SCristina Ciocan 	int i;
592c501d0b1SCristina Ciocan 
59340ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
594c501d0b1SCristina Ciocan 
595770f53d4SAndy Shevchenko 	for (i = 0; i < group.grp.npins; i++) {
596c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
597c501d0b1SCristina Ciocan 		u32 value;
598c501d0b1SCristina Ciocan 
599770f53d4SAndy Shevchenko 		padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG);
600c501d0b1SCristina Ciocan 		if (!padcfg0) {
601b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n",
602770f53d4SAndy Shevchenko 				 group.grp.name, i);
603c501d0b1SCristina Ciocan 			continue;
604c501d0b1SCristina Ciocan 		}
605c501d0b1SCristina Ciocan 
606c501d0b1SCristina Ciocan 		value = readl(padcfg0);
607c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
608c501d0b1SCristina Ciocan 		value |= func;
609c501d0b1SCristina Ciocan 		writel(value, padcfg0);
610c501d0b1SCristina Ciocan 	}
611c501d0b1SCristina Ciocan 
61240ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
613c501d0b1SCristina Ciocan }
614c501d0b1SCristina Ciocan 
6155d33e0ebSAndy Shevchenko static void byt_set_group_mixed_mux(struct intel_pinctrl *vg,
6164f010b93SAndy Shevchenko 				    const struct intel_pingroup group,
6174f010b93SAndy Shevchenko 				    const unsigned int *func)
618c501d0b1SCristina Ciocan {
619c501d0b1SCristina Ciocan 	unsigned long flags;
620c501d0b1SCristina Ciocan 	int i;
621c501d0b1SCristina Ciocan 
62240ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
623c501d0b1SCristina Ciocan 
624770f53d4SAndy Shevchenko 	for (i = 0; i < group.grp.npins; i++) {
625c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
626c501d0b1SCristina Ciocan 		u32 value;
627c501d0b1SCristina Ciocan 
628770f53d4SAndy Shevchenko 		padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG);
629c501d0b1SCristina Ciocan 		if (!padcfg0) {
630b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n",
631770f53d4SAndy Shevchenko 				 group.grp.name, i);
632c501d0b1SCristina Ciocan 			continue;
633c501d0b1SCristina Ciocan 		}
634c501d0b1SCristina Ciocan 
635c501d0b1SCristina Ciocan 		value = readl(padcfg0);
636c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
637c501d0b1SCristina Ciocan 		value |= func[i];
638c501d0b1SCristina Ciocan 		writel(value, padcfg0);
639c501d0b1SCristina Ciocan 	}
640c501d0b1SCristina Ciocan 
64140ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
642c501d0b1SCristina Ciocan }
643c501d0b1SCristina Ciocan 
644c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
645c501d0b1SCristina Ciocan 		       unsigned int group_selector)
646c501d0b1SCristina Ciocan {
6475d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
6485d33e0ebSAndy Shevchenko 	const struct intel_function func = vg->soc->functions[func_selector];
6495d33e0ebSAndy Shevchenko 	const struct intel_pingroup group = vg->soc->groups[group_selector];
650c501d0b1SCristina Ciocan 
6514f010b93SAndy Shevchenko 	if (group.modes)
6524f010b93SAndy Shevchenko 		byt_set_group_mixed_mux(vg, group, group.modes);
653988ac1a4SAndy Shevchenko 	else if (!strcmp(func.func.name, "gpio"))
654c501d0b1SCristina Ciocan 		byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
655c501d0b1SCristina Ciocan 	else
6564f010b93SAndy Shevchenko 		byt_set_group_simple_mux(vg, group, group.mode);
657c501d0b1SCristina Ciocan 
658c501d0b1SCristina Ciocan 	return 0;
659c501d0b1SCristina Ciocan }
660c501d0b1SCristina Ciocan 
6615d33e0ebSAndy Shevchenko static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset)
662c501d0b1SCristina Ciocan {
663c501d0b1SCristina Ciocan 	/* SCORE pin 92-93 */
6645d33e0ebSAndy Shevchenko 	if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) &&
665c501d0b1SCristina Ciocan 	    offset >= 92 && offset <= 93)
666a705f9c1SAndy Shevchenko 		return BYT_ALTER_GPIO_MUX;
667c501d0b1SCristina Ciocan 
668c501d0b1SCristina Ciocan 	/* SUS pin 11-21 */
6695d33e0ebSAndy Shevchenko 	if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) &&
670c501d0b1SCristina Ciocan 	    offset >= 11 && offset <= 21)
671a705f9c1SAndy Shevchenko 		return BYT_ALTER_GPIO_MUX;
672c501d0b1SCristina Ciocan 
673a705f9c1SAndy Shevchenko 	return BYT_DEFAULT_GPIO_MUX;
674c501d0b1SCristina Ciocan }
675c501d0b1SCristina Ciocan 
6765d33e0ebSAndy Shevchenko static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset)
677c501d0b1SCristina Ciocan {
678c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
67995f0972cSMika Westerberg 	unsigned long flags;
68095f0972cSMika Westerberg 	u32 value;
68195f0972cSMika Westerberg 
68240ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
68395f0972cSMika Westerberg 	value = readl(reg);
684a2368059SHans de Goede 
685a2368059SHans de Goede 	/* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
686605ba256SRaag Jadav 	if (!(value & BYT_DIRECT_IRQ_EN))
68795f0972cSMika Westerberg 		value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
688a2368059SHans de Goede 
68995f0972cSMika Westerberg 	writel(value, reg);
69040ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
69195f0972cSMika Westerberg }
69295f0972cSMika Westerberg 
693c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
694c501d0b1SCristina Ciocan 				   struct pinctrl_gpio_range *range,
695c501d0b1SCristina Ciocan 				   unsigned int offset)
6965fae8b86SMika Westerberg {
6975d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
698c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
699f8323b6bSMika Westerberg 	u32 value, gpio_mux;
70039ce8150SMika Westerberg 	unsigned long flags;
70139ce8150SMika Westerberg 
70240ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
7035fae8b86SMika Westerberg 
7045fae8b86SMika Westerberg 	/*
7055fae8b86SMika Westerberg 	 * In most cases, func pin mux 000 means GPIO function.
7065fae8b86SMika Westerberg 	 * But, some pins may have func pin mux 001 represents
707f8323b6bSMika Westerberg 	 * GPIO function.
708f8323b6bSMika Westerberg 	 *
709f8323b6bSMika Westerberg 	 * Because there are devices out there where some pins were not
710f8323b6bSMika Westerberg 	 * configured correctly we allow changing the mux value from
711f8323b6bSMika Westerberg 	 * request (but print out warning about that).
7125fae8b86SMika Westerberg 	 */
7135fae8b86SMika Westerberg 	value = readl(reg) & BYT_PIN_MUX;
714f8323b6bSMika Westerberg 	gpio_mux = byt_get_gpio_mux(vg, offset);
715b5894d12SHans de Goede 	if (gpio_mux != value) {
716f8323b6bSMika Westerberg 		value = readl(reg) & ~BYT_PIN_MUX;
717f8323b6bSMika Westerberg 		value |= gpio_mux;
718f8323b6bSMika Westerberg 		writel(value, reg);
719f8323b6bSMika Westerberg 
720b9e18434SAndy Shevchenko 		dev_warn(vg->dev, FW_BUG "Pin %i: forcibly re-configured as GPIO\n", offset);
7215fae8b86SMika Westerberg 	}
7225fae8b86SMika Westerberg 
72340ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
72439ce8150SMika Westerberg 
725990ec243SAndy Shevchenko 	pm_runtime_get(vg->dev);
7265fae8b86SMika Westerberg 
7275fae8b86SMika Westerberg 	return 0;
7285fae8b86SMika Westerberg }
7295fae8b86SMika Westerberg 
730c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
731c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
732c501d0b1SCristina Ciocan 				  unsigned int offset)
733c501d0b1SCristina Ciocan {
7345d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
735c501d0b1SCristina Ciocan 
736c501d0b1SCristina Ciocan 	byt_gpio_clear_triggering(vg, offset);
737990ec243SAndy Shevchenko 	pm_runtime_put(vg->dev);
738c501d0b1SCristina Ciocan }
739c501d0b1SCristina Ciocan 
740156abe29SHans de Goede static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg,
741156abe29SHans de Goede 				      unsigned int offset)
742156abe29SHans de Goede {
743156abe29SHans de Goede 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
744156abe29SHans de Goede 
745156abe29SHans de Goede 	/*
746156abe29SHans de Goede 	 * Before making any direction modifications, do a check if gpio is set
747156abe29SHans de Goede 	 * for direct IRQ. On Bay Trail, setting GPIO to output does not make
748156abe29SHans de Goede 	 * sense, so let's at least inform the caller before they shoot
749156abe29SHans de Goede 	 * themselves in the foot.
750156abe29SHans de Goede 	 */
751156abe29SHans de Goede 	if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
752b9e18434SAndy Shevchenko 		dev_info_once(vg->dev,
753b9e18434SAndy Shevchenko 			      "Potential Error: Pin %i: forcibly set GPIO with DIRECT_IRQ_EN to output\n",
754b9e18434SAndy Shevchenko 			      offset);
755156abe29SHans de Goede }
756156abe29SHans de Goede 
757c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
758c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
759c501d0b1SCristina Ciocan 				  unsigned int offset,
760c501d0b1SCristina Ciocan 				  bool input)
761c501d0b1SCristina Ciocan {
7625d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
763c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
764c501d0b1SCristina Ciocan 	unsigned long flags;
765c501d0b1SCristina Ciocan 	u32 value;
766c501d0b1SCristina Ciocan 
76740ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
768c501d0b1SCristina Ciocan 
769c501d0b1SCristina Ciocan 	value = readl(val_reg);
770c501d0b1SCristina Ciocan 	value &= ~BYT_DIR_MASK;
771c501d0b1SCristina Ciocan 	if (input)
772c501d0b1SCristina Ciocan 		value |= BYT_OUTPUT_EN;
773156abe29SHans de Goede 	else
774156abe29SHans de Goede 		byt_gpio_direct_irq_check(vg, offset);
775e2b74419SHans de Goede 
776c501d0b1SCristina Ciocan 	writel(value, val_reg);
777c501d0b1SCristina Ciocan 
77840ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
779c501d0b1SCristina Ciocan 
780c501d0b1SCristina Ciocan 	return 0;
781c501d0b1SCristina Ciocan }
782c501d0b1SCristina Ciocan 
783c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = {
784*4d01688fSRaag Jadav 	.get_functions_count	= intel_get_functions_count,
785*4d01688fSRaag Jadav 	.get_function_name	= intel_get_function_name,
786*4d01688fSRaag Jadav 	.get_function_groups	= intel_get_function_groups,
787c501d0b1SCristina Ciocan 	.set_mux		= byt_set_mux,
788c501d0b1SCristina Ciocan 	.gpio_request_enable	= byt_gpio_request_enable,
789c501d0b1SCristina Ciocan 	.gpio_disable_free	= byt_gpio_disable_free,
790c501d0b1SCristina Ciocan 	.gpio_set_direction	= byt_gpio_set_direction,
791c501d0b1SCristina Ciocan };
792c501d0b1SCristina Ciocan 
793c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength)
794c501d0b1SCristina Ciocan {
795c501d0b1SCristina Ciocan 	switch (reg & BYT_PULL_STR_MASK) {
796c501d0b1SCristina Ciocan 	case BYT_PULL_STR_2K:
797c501d0b1SCristina Ciocan 		*strength = 2000;
798c501d0b1SCristina Ciocan 		break;
799c501d0b1SCristina Ciocan 	case BYT_PULL_STR_10K:
800c501d0b1SCristina Ciocan 		*strength = 10000;
801c501d0b1SCristina Ciocan 		break;
802c501d0b1SCristina Ciocan 	case BYT_PULL_STR_20K:
803c501d0b1SCristina Ciocan 		*strength = 20000;
804c501d0b1SCristina Ciocan 		break;
805c501d0b1SCristina Ciocan 	case BYT_PULL_STR_40K:
806c501d0b1SCristina Ciocan 		*strength = 40000;
807c501d0b1SCristina Ciocan 		break;
808c501d0b1SCristina Ciocan 	}
809c501d0b1SCristina Ciocan }
810c501d0b1SCristina Ciocan 
811c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength)
812c501d0b1SCristina Ciocan {
813c501d0b1SCristina Ciocan 	*reg &= ~BYT_PULL_STR_MASK;
814c501d0b1SCristina Ciocan 
815c501d0b1SCristina Ciocan 	switch (strength) {
816c501d0b1SCristina Ciocan 	case 2000:
817c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_2K;
818c501d0b1SCristina Ciocan 		break;
819c501d0b1SCristina Ciocan 	case 10000:
820c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_10K;
821c501d0b1SCristina Ciocan 		break;
822c501d0b1SCristina Ciocan 	case 20000:
823c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_20K;
824c501d0b1SCristina Ciocan 		break;
825c501d0b1SCristina Ciocan 	case 40000:
826c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_40K;
827c501d0b1SCristina Ciocan 		break;
828c501d0b1SCristina Ciocan 	default:
829c501d0b1SCristina Ciocan 		return -EINVAL;
830c501d0b1SCristina Ciocan 	}
831c501d0b1SCristina Ciocan 
832c501d0b1SCristina Ciocan 	return 0;
833c501d0b1SCristina Ciocan }
834c501d0b1SCristina Ciocan 
835c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
836c501d0b1SCristina Ciocan 			      unsigned long *config)
837c501d0b1SCristina Ciocan {
8385d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
839c501d0b1SCristina Ciocan 	enum pin_config_param param = pinconf_to_config_param(*config);
840c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
841c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
84204ff5a09SAndy Shevchenko 	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
843c501d0b1SCristina Ciocan 	unsigned long flags;
844658b476cSCristina Ciocan 	u32 conf, pull, val, debounce;
845c501d0b1SCristina Ciocan 	u16 arg = 0;
846c501d0b1SCristina Ciocan 
84740ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
848c501d0b1SCristina Ciocan 	conf = readl(conf_reg);
849c501d0b1SCristina Ciocan 	pull = conf & BYT_PULL_ASSIGN_MASK;
850c501d0b1SCristina Ciocan 	val = readl(val_reg);
85140ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
852c501d0b1SCristina Ciocan 
853c501d0b1SCristina Ciocan 	switch (param) {
854c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_DISABLE:
855c501d0b1SCristina Ciocan 		if (pull)
856c501d0b1SCristina Ciocan 			return -EINVAL;
857c501d0b1SCristina Ciocan 		break;
858c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_PULL_DOWN:
859c501d0b1SCristina Ciocan 		/* Pull assignment is only applicable in input mode */
860c501d0b1SCristina Ciocan 		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN)
861c501d0b1SCristina Ciocan 			return -EINVAL;
862c501d0b1SCristina Ciocan 
863c501d0b1SCristina Ciocan 		byt_get_pull_strength(conf, &arg);
864c501d0b1SCristina Ciocan 
865c501d0b1SCristina Ciocan 		break;
866c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_PULL_UP:
867c501d0b1SCristina Ciocan 		/* Pull assignment is only applicable in input mode */
868c501d0b1SCristina Ciocan 		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP)
869c501d0b1SCristina Ciocan 			return -EINVAL;
870c501d0b1SCristina Ciocan 
871c501d0b1SCristina Ciocan 		byt_get_pull_strength(conf, &arg);
872c501d0b1SCristina Ciocan 
873c501d0b1SCristina Ciocan 		break;
874658b476cSCristina Ciocan 	case PIN_CONFIG_INPUT_DEBOUNCE:
875658b476cSCristina Ciocan 		if (!(conf & BYT_DEBOUNCE_EN))
876658b476cSCristina Ciocan 			return -EINVAL;
877658b476cSCristina Ciocan 
87840ecab55SHans de Goede 		raw_spin_lock_irqsave(&byt_lock, flags);
87904ff5a09SAndy Shevchenko 		debounce = readl(db_reg);
88040ecab55SHans de Goede 		raw_spin_unlock_irqrestore(&byt_lock, flags);
881658b476cSCristina Ciocan 
882658b476cSCristina Ciocan 		switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
883658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_375US:
884658b476cSCristina Ciocan 			arg = 375;
885658b476cSCristina Ciocan 			break;
886658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_750US:
887658b476cSCristina Ciocan 			arg = 750;
888658b476cSCristina Ciocan 			break;
889658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_1500US:
890658b476cSCristina Ciocan 			arg = 1500;
891658b476cSCristina Ciocan 			break;
892658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_3MS:
893658b476cSCristina Ciocan 			arg = 3000;
894658b476cSCristina Ciocan 			break;
895658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_6MS:
896658b476cSCristina Ciocan 			arg = 6000;
897658b476cSCristina Ciocan 			break;
898658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_12MS:
899658b476cSCristina Ciocan 			arg = 12000;
900658b476cSCristina Ciocan 			break;
901658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_24MS:
902658b476cSCristina Ciocan 			arg = 24000;
903658b476cSCristina Ciocan 			break;
904658b476cSCristina Ciocan 		default:
905658b476cSCristina Ciocan 			return -EINVAL;
906658b476cSCristina Ciocan 		}
907658b476cSCristina Ciocan 
908658b476cSCristina Ciocan 		break;
909c501d0b1SCristina Ciocan 	default:
910c501d0b1SCristina Ciocan 		return -ENOTSUPP;
911c501d0b1SCristina Ciocan 	}
912c501d0b1SCristina Ciocan 
913c501d0b1SCristina Ciocan 	*config = pinconf_to_config_packed(param, arg);
914c501d0b1SCristina Ciocan 
915c501d0b1SCristina Ciocan 	return 0;
916c501d0b1SCristina Ciocan }
917c501d0b1SCristina Ciocan 
918c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
919c501d0b1SCristina Ciocan 			      unsigned int offset,
920c501d0b1SCristina Ciocan 			      unsigned long *configs,
921c501d0b1SCristina Ciocan 			      unsigned int num_configs)
922c501d0b1SCristina Ciocan {
9235d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
924c501d0b1SCristina Ciocan 	unsigned int param, arg;
925c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
926c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
92704ff5a09SAndy Shevchenko 	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
928c501d0b1SCristina Ciocan 	unsigned long flags;
929658b476cSCristina Ciocan 	u32 conf, val, debounce;
930c501d0b1SCristina Ciocan 	int i, ret = 0;
931c501d0b1SCristina Ciocan 
93240ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
933c501d0b1SCristina Ciocan 
934c501d0b1SCristina Ciocan 	conf = readl(conf_reg);
935c501d0b1SCristina Ciocan 	val = readl(val_reg);
936c501d0b1SCristina Ciocan 
937c501d0b1SCristina Ciocan 	for (i = 0; i < num_configs; i++) {
938c501d0b1SCristina Ciocan 		param = pinconf_to_config_param(configs[i]);
939c501d0b1SCristina Ciocan 		arg = pinconf_to_config_argument(configs[i]);
940c501d0b1SCristina Ciocan 
941c501d0b1SCristina Ciocan 		switch (param) {
942c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_DISABLE:
943c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
944c501d0b1SCristina Ciocan 			break;
945c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_DOWN:
946c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
947c501d0b1SCristina Ciocan 			if (arg == 1)
948c501d0b1SCristina Ciocan 				arg = 2000;
949c501d0b1SCristina Ciocan 
950c501d0b1SCristina Ciocan 			/*
951c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
952c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
953c501d0b1SCristina Ciocan 			 */
954c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
955c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
956c501d0b1SCristina Ciocan 				writel(val, val_reg);
957b9e18434SAndy Shevchenko 				dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
958c501d0b1SCristina Ciocan 			}
959c501d0b1SCristina Ciocan 
960c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
961c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_DOWN;
962c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
963c501d0b1SCristina Ciocan 
964c501d0b1SCristina Ciocan 			break;
965c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_UP:
966c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
967c501d0b1SCristina Ciocan 			if (arg == 1)
968c501d0b1SCristina Ciocan 				arg = 2000;
969c501d0b1SCristina Ciocan 
970c501d0b1SCristina Ciocan 			/*
971c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
972c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
973c501d0b1SCristina Ciocan 			 */
974c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
975c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
976c501d0b1SCristina Ciocan 				writel(val, val_reg);
977b9e18434SAndy Shevchenko 				dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
978c501d0b1SCristina Ciocan 			}
979c501d0b1SCristina Ciocan 
980c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
981c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_UP;
982c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
983c501d0b1SCristina Ciocan 
984c501d0b1SCristina Ciocan 			break;
985658b476cSCristina Ciocan 		case PIN_CONFIG_INPUT_DEBOUNCE:
98604ff5a09SAndy Shevchenko 			debounce = readl(db_reg);
987658b476cSCristina Ciocan 
988827e1579SAndy Shevchenko 			if (arg)
989827e1579SAndy Shevchenko 				conf |= BYT_DEBOUNCE_EN;
990827e1579SAndy Shevchenko 			else
991827e1579SAndy Shevchenko 				conf &= ~BYT_DEBOUNCE_EN;
992827e1579SAndy Shevchenko 
993658b476cSCristina Ciocan 			switch (arg) {
994658b476cSCristina Ciocan 			case 375:
9955f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
99604ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_375US;
997658b476cSCristina Ciocan 				break;
998658b476cSCristina Ciocan 			case 750:
9995f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
100004ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_750US;
1001658b476cSCristina Ciocan 				break;
1002658b476cSCristina Ciocan 			case 1500:
10035f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
100404ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_1500US;
1005658b476cSCristina Ciocan 				break;
1006658b476cSCristina Ciocan 			case 3000:
10075f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
100804ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_3MS;
1009658b476cSCristina Ciocan 				break;
1010658b476cSCristina Ciocan 			case 6000:
10115f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
101204ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_6MS;
1013658b476cSCristina Ciocan 				break;
1014658b476cSCristina Ciocan 			case 12000:
10155f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
101604ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_12MS;
1017658b476cSCristina Ciocan 				break;
1018658b476cSCristina Ciocan 			case 24000:
10195f714771SAndy Shevchenko 				debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
102004ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_24MS;
1021658b476cSCristina Ciocan 				break;
1022658b476cSCristina Ciocan 			default:
1023827e1579SAndy Shevchenko 				if (arg)
1024658b476cSCristina Ciocan 					ret = -EINVAL;
1025827e1579SAndy Shevchenko 				break;
1026658b476cSCristina Ciocan 			}
1027658b476cSCristina Ciocan 
102804ff5a09SAndy Shevchenko 			if (!ret)
102904ff5a09SAndy Shevchenko 				writel(debounce, db_reg);
1030658b476cSCristina Ciocan 			break;
1031c501d0b1SCristina Ciocan 		default:
1032c501d0b1SCristina Ciocan 			ret = -ENOTSUPP;
1033c501d0b1SCristina Ciocan 		}
1034c501d0b1SCristina Ciocan 
1035c501d0b1SCristina Ciocan 		if (ret)
1036c501d0b1SCristina Ciocan 			break;
1037c501d0b1SCristina Ciocan 	}
1038c501d0b1SCristina Ciocan 
1039c501d0b1SCristina Ciocan 	if (!ret)
1040c501d0b1SCristina Ciocan 		writel(conf, conf_reg);
1041c501d0b1SCristina Ciocan 
104240ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1043c501d0b1SCristina Ciocan 
1044c501d0b1SCristina Ciocan 	return ret;
1045c501d0b1SCristina Ciocan }
1046c501d0b1SCristina Ciocan 
1047c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = {
1048c501d0b1SCristina Ciocan 	.is_generic	= true,
1049c501d0b1SCristina Ciocan 	.pin_config_get	= byt_pin_config_get,
1050c501d0b1SCristina Ciocan 	.pin_config_set	= byt_pin_config_set,
1051c501d0b1SCristina Ciocan };
1052c501d0b1SCristina Ciocan 
1053c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = {
1054c501d0b1SCristina Ciocan 	.pctlops	= &byt_pinctrl_ops,
1055c501d0b1SCristina Ciocan 	.pmxops		= &byt_pinmux_ops,
1056c501d0b1SCristina Ciocan 	.confops	= &byt_pinconf_ops,
1057c501d0b1SCristina Ciocan 	.owner		= THIS_MODULE,
1058c501d0b1SCristina Ciocan };
1059c501d0b1SCristina Ciocan 
1060939330d7SAndy Shevchenko static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
10615fae8b86SMika Westerberg {
10625d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1063c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
106439ce8150SMika Westerberg 	unsigned long flags;
106539ce8150SMika Westerberg 	u32 val;
106639ce8150SMika Westerberg 
106740ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
106839ce8150SMika Westerberg 	val = readl(reg);
106940ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
107039ce8150SMika Westerberg 
10713bde8771SLinus Walleij 	return !!(val & BYT_LEVEL);
10725fae8b86SMika Westerberg }
10735fae8b86SMika Westerberg 
1074939330d7SAndy Shevchenko static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
10755fae8b86SMika Westerberg {
10765d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1077c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
10785fae8b86SMika Westerberg 	unsigned long flags;
10795fae8b86SMika Westerberg 	u32 old_val;
10805fae8b86SMika Westerberg 
108186e3ef81SCristina Ciocan 	if (!reg)
108286e3ef81SCristina Ciocan 		return;
108386e3ef81SCristina Ciocan 
108440ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
10855fae8b86SMika Westerberg 	old_val = readl(reg);
10865fae8b86SMika Westerberg 	if (value)
10875fae8b86SMika Westerberg 		writel(old_val | BYT_LEVEL, reg);
10885fae8b86SMika Westerberg 	else
10895fae8b86SMika Westerberg 		writel(old_val & ~BYT_LEVEL, reg);
109040ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
10915fae8b86SMika Westerberg }
10925fae8b86SMika Westerberg 
109386e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
10945fae8b86SMika Westerberg {
10955d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1096c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
10975fae8b86SMika Westerberg 	unsigned long flags;
10985fae8b86SMika Westerberg 	u32 value;
10995fae8b86SMika Westerberg 
110086e3ef81SCristina Ciocan 	if (!reg)
110186e3ef81SCristina Ciocan 		return -EINVAL;
110286e3ef81SCristina Ciocan 
110340ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
110486e3ef81SCristina Ciocan 	value = readl(reg);
110540ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
11065fae8b86SMika Westerberg 
110786e3ef81SCristina Ciocan 	if (!(value & BYT_OUTPUT_EN))
1108faf86c0cSMatti Vaittinen 		return GPIO_LINE_DIRECTION_OUT;
110986e3ef81SCristina Ciocan 	if (!(value & BYT_INPUT_EN))
1110faf86c0cSMatti Vaittinen 		return GPIO_LINE_DIRECTION_IN;
111186e3ef81SCristina Ciocan 
111286e3ef81SCristina Ciocan 	return -EINVAL;
11135fae8b86SMika Westerberg }
11145fae8b86SMika Westerberg 
111586e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
11165fae8b86SMika Westerberg {
1117156abe29SHans de Goede 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1118156abe29SHans de Goede 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1119156abe29SHans de Goede 	unsigned long flags;
1120156abe29SHans de Goede 	u32 reg;
1121156abe29SHans de Goede 
1122156abe29SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
1123156abe29SHans de Goede 
1124156abe29SHans de Goede 	reg = readl(val_reg);
1125156abe29SHans de Goede 	reg &= ~BYT_DIR_MASK;
1126156abe29SHans de Goede 	reg |= BYT_OUTPUT_EN;
1127156abe29SHans de Goede 	writel(reg, val_reg);
1128156abe29SHans de Goede 
1129156abe29SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1130156abe29SHans de Goede 	return 0;
113186e3ef81SCristina Ciocan }
11325fae8b86SMika Westerberg 
1133156abe29SHans de Goede /*
1134156abe29SHans de Goede  * Note despite the temptation this MUST NOT be converted into a call to
1135156abe29SHans de Goede  * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this
1136156abe29SHans de Goede  * MUST be done as a single BYT_VAL_REG register write.
1137156abe29SHans de Goede  * See the commit message of the commit adding this comment for details.
1138156abe29SHans de Goede  */
113986e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip,
114086e3ef81SCristina Ciocan 				     unsigned int offset, int value)
114186e3ef81SCristina Ciocan {
1142156abe29SHans de Goede 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1143156abe29SHans de Goede 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1144156abe29SHans de Goede 	unsigned long flags;
1145156abe29SHans de Goede 	u32 reg;
11465fae8b86SMika Westerberg 
1147156abe29SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
114886e3ef81SCristina Ciocan 
1149156abe29SHans de Goede 	byt_gpio_direct_irq_check(vg, offset);
11505fae8b86SMika Westerberg 
1151156abe29SHans de Goede 	reg = readl(val_reg);
1152156abe29SHans de Goede 	reg &= ~BYT_DIR_MASK;
1153156abe29SHans de Goede 	if (value)
1154156abe29SHans de Goede 		reg |= BYT_LEVEL;
1155156abe29SHans de Goede 	else
1156156abe29SHans de Goede 		reg &= ~BYT_LEVEL;
1157156abe29SHans de Goede 
1158156abe29SHans de Goede 	writel(reg, val_reg);
1159156abe29SHans de Goede 
1160156abe29SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
11615fae8b86SMika Westerberg 	return 0;
11625fae8b86SMika Westerberg }
11635fae8b86SMika Westerberg 
11645fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
11655fae8b86SMika Westerberg {
11665d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
11675fae8b86SMika Westerberg 	int i;
116886e3ef81SCristina Ciocan 	u32 conf0, val;
11695fae8b86SMika Westerberg 
11705d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
117134e65670SAndy Shevchenko 		const struct intel_community *comm;
11725a9fa4c2SRaag Jadav 		void __iomem *conf_reg, *val_reg;
11735fae8b86SMika Westerberg 		const char *pull_str = NULL;
11745fae8b86SMika Westerberg 		const char *pull = NULL;
117578e1c896SMika Westerberg 		unsigned long flags;
11765fae8b86SMika Westerberg 		const char *label;
117786e3ef81SCristina Ciocan 		unsigned int pin;
117878e1c896SMika Westerberg 
11795d33e0ebSAndy Shevchenko 		pin = vg->soc->pins[i].number;
118086e3ef81SCristina Ciocan 
11815a9fa4c2SRaag Jadav 		conf_reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
11825a9fa4c2SRaag Jadav 		if (!conf_reg) {
11835a9fa4c2SRaag Jadav 			seq_printf(s, "Pin %i: can't retrieve CONF0\n", pin);
118422bbd21bSDan Carpenter 			continue;
118586e3ef81SCristina Ciocan 		}
11865a9fa4c2SRaag Jadav 
11875a9fa4c2SRaag Jadav 		val_reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
11885a9fa4c2SRaag Jadav 		if (!val_reg) {
11895a9fa4c2SRaag Jadav 			seq_printf(s, "Pin %i: can't retrieve VAL\n", pin);
11905a9fa4c2SRaag Jadav 			continue;
11915a9fa4c2SRaag Jadav 		}
11925a9fa4c2SRaag Jadav 
11935a9fa4c2SRaag Jadav 		raw_spin_lock_irqsave(&byt_lock, flags);
11945a9fa4c2SRaag Jadav 		conf0 = readl(conf_reg);
11955a9fa4c2SRaag Jadav 		val = readl(val_reg);
119640ecab55SHans de Goede 		raw_spin_unlock_irqrestore(&byt_lock, flags);
11975fae8b86SMika Westerberg 
1198*4d01688fSRaag Jadav 		comm = intel_get_community(vg, pin);
119986e3ef81SCristina Ciocan 		if (!comm) {
1200b9e18434SAndy Shevchenko 			seq_printf(s, "Pin %i: can't retrieve community\n", pin);
120186e3ef81SCristina Ciocan 			continue;
120286e3ef81SCristina Ciocan 		}
12035fae8b86SMika Westerberg 		label = gpiochip_is_requested(chip, i);
12045fae8b86SMika Westerberg 		if (!label)
12055fae8b86SMika Westerberg 			label = "Unrequested";
12065fae8b86SMika Westerberg 
12075fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_ASSIGN_MASK) {
12085fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_UP:
12095fae8b86SMika Westerberg 			pull = "up";
12105fae8b86SMika Westerberg 			break;
12115fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_DOWN:
12125fae8b86SMika Westerberg 			pull = "down";
12135fae8b86SMika Westerberg 			break;
12145fae8b86SMika Westerberg 		}
12155fae8b86SMika Westerberg 
12165fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_STR_MASK) {
12175fae8b86SMika Westerberg 		case BYT_PULL_STR_2K:
12185fae8b86SMika Westerberg 			pull_str = "2k";
12195fae8b86SMika Westerberg 			break;
12205fae8b86SMika Westerberg 		case BYT_PULL_STR_10K:
12215fae8b86SMika Westerberg 			pull_str = "10k";
12225fae8b86SMika Westerberg 			break;
12235fae8b86SMika Westerberg 		case BYT_PULL_STR_20K:
12245fae8b86SMika Westerberg 			pull_str = "20k";
12255fae8b86SMika Westerberg 			break;
12265fae8b86SMika Westerberg 		case BYT_PULL_STR_40K:
12275fae8b86SMika Westerberg 			pull_str = "40k";
12285fae8b86SMika Westerberg 			break;
12295fae8b86SMika Westerberg 		}
12305fae8b86SMika Westerberg 
12315fae8b86SMika Westerberg 		seq_printf(s,
12325fae8b86SMika Westerberg 			   " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
123386e3ef81SCristina Ciocan 			   pin,
12345fae8b86SMika Westerberg 			   label,
12355fae8b86SMika Westerberg 			   val & BYT_INPUT_EN ? "  " : "in",
12365fae8b86SMika Westerberg 			   val & BYT_OUTPUT_EN ? "   " : "out",
1237c518d31bSAndy Shevchenko 			   str_hi_lo(val & BYT_LEVEL),
12383655a1caSAlexander Stein 			   comm->pad_map[i], comm->pad_map[i] * 16,
12395fae8b86SMika Westerberg 			   conf0 & 0x7,
12405fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_NEG ? " fall" : "     ",
12415fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_POS ? " rise" : "     ",
12425fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_LVL ? " level" : "      ");
12435fae8b86SMika Westerberg 
12445fae8b86SMika Westerberg 		if (pull && pull_str)
12455fae8b86SMika Westerberg 			seq_printf(s, " %-4s %-3s", pull, pull_str);
12465fae8b86SMika Westerberg 		else
12475fae8b86SMika Westerberg 			seq_puts(s, "          ");
12485fae8b86SMika Westerberg 
12495fae8b86SMika Westerberg 		if (conf0 & BYT_IODEN)
12505fae8b86SMika Westerberg 			seq_puts(s, " open-drain");
12515fae8b86SMika Westerberg 
12525fae8b86SMika Westerberg 		seq_puts(s, "\n");
12535fae8b86SMika Westerberg 	}
12545fae8b86SMika Westerberg }
12555fae8b86SMika Westerberg 
125686e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = {
125786e3ef81SCristina Ciocan 	.owner			= THIS_MODULE,
125886e3ef81SCristina Ciocan 	.request		= gpiochip_generic_request,
125986e3ef81SCristina Ciocan 	.free			= gpiochip_generic_free,
126086e3ef81SCristina Ciocan 	.get_direction		= byt_gpio_get_direction,
126186e3ef81SCristina Ciocan 	.direction_input	= byt_gpio_direction_input,
126286e3ef81SCristina Ciocan 	.direction_output	= byt_gpio_direction_output,
126386e3ef81SCristina Ciocan 	.get			= byt_gpio_get,
126486e3ef81SCristina Ciocan 	.set			= byt_gpio_set,
1265ccd025eaSAndy Shevchenko 	.set_config		= gpiochip_generic_config,
126686e3ef81SCristina Ciocan 	.dbg_show		= byt_gpio_dbg_show,
126786e3ef81SCristina Ciocan };
126886e3ef81SCristina Ciocan 
126931e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d)
127031e4329fSMika Westerberg {
127131e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
12725d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
12736d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
127431e4329fSMika Westerberg 	void __iomem *reg;
127531e4329fSMika Westerberg 
12766d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_INT_STAT_REG);
12779f573b98SCristina Ciocan 	if (!reg)
12789f573b98SCristina Ciocan 		return;
12799f573b98SCristina Ciocan 
128040ecab55SHans de Goede 	raw_spin_lock(&byt_lock);
12816d209b42SAndy Shevchenko 	writel(BIT(hwirq % 32), reg);
128240ecab55SHans de Goede 	raw_spin_unlock(&byt_lock);
128331e4329fSMika Westerberg }
128431e4329fSMika Westerberg 
12859f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d)
12869f573b98SCristina Ciocan {
12879f573b98SCristina Ciocan 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
12885d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
12896d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
12909f573b98SCristina Ciocan 
12916d209b42SAndy Shevchenko 	byt_gpio_clear_triggering(vg, hwirq);
12926d209b42SAndy Shevchenko 	gpiochip_disable_irq(gc, hwirq);
12939f573b98SCristina Ciocan }
12949f573b98SCristina Ciocan 
12955fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d)
12965fae8b86SMika Westerberg {
129731e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
12985d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(gc);
12996d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
130031e4329fSMika Westerberg 	unsigned long flags;
130131e4329fSMika Westerberg 	void __iomem *reg;
130231e4329fSMika Westerberg 	u32 value;
130331e4329fSMika Westerberg 
13046d209b42SAndy Shevchenko 	gpiochip_enable_irq(gc, hwirq);
13056d209b42SAndy Shevchenko 
13066d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
13079f573b98SCristina Ciocan 	if (!reg)
13089f573b98SCristina Ciocan 		return;
130978e1c896SMika Westerberg 
131040ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
131131e4329fSMika Westerberg 	value = readl(reg);
131231e4329fSMika Westerberg 
131331e4329fSMika Westerberg 	switch (irqd_get_trigger_type(d)) {
131431e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_HIGH:
131531e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
13160a093020SGustavo A. R. Silva 		fallthrough;
131731e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_RISING:
131831e4329fSMika Westerberg 		value |= BYT_TRIG_POS;
131931e4329fSMika Westerberg 		break;
132031e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_LOW:
132131e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
13220a093020SGustavo A. R. Silva 		fallthrough;
132331e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_FALLING:
132431e4329fSMika Westerberg 		value |= BYT_TRIG_NEG;
132531e4329fSMika Westerberg 		break;
132631e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_BOTH:
132731e4329fSMika Westerberg 		value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
132831e4329fSMika Westerberg 		break;
132931e4329fSMika Westerberg 	}
133031e4329fSMika Westerberg 
133131e4329fSMika Westerberg 	writel(value, reg);
133231e4329fSMika Westerberg 
133340ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
13345fae8b86SMika Westerberg }
13355fae8b86SMika Westerberg 
13369f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type)
13375fae8b86SMika Westerberg {
13385d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
13396d209b42SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
13409f573b98SCristina Ciocan 	u32 value;
13419f573b98SCristina Ciocan 	unsigned long flags;
13426d209b42SAndy Shevchenko 	void __iomem *reg;
134331e4329fSMika Westerberg 
13446d209b42SAndy Shevchenko 	reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
13456d209b42SAndy Shevchenko 	if (!reg)
13469f573b98SCristina Ciocan 		return -EINVAL;
13479f573b98SCristina Ciocan 
134840ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
13499f573b98SCristina Ciocan 	value = readl(reg);
13509f573b98SCristina Ciocan 
13519f573b98SCristina Ciocan 	WARN(value & BYT_DIRECT_IRQ_EN,
1352b9e18434SAndy Shevchenko 	     "Bad pad config for IO mode, force DIRECT_IRQ_EN bit clearing");
13539f573b98SCristina Ciocan 
13549f573b98SCristina Ciocan 	/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
13559f573b98SCristina Ciocan 	 * are used to indicate high and low level triggering
13569f573b98SCristina Ciocan 	 */
13579f573b98SCristina Ciocan 	value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
13589f573b98SCristina Ciocan 		   BYT_TRIG_LVL);
13599291c65bSHans de Goede 	/* Enable glitch filtering */
13609291c65bSHans de Goede 	value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK |
13619291c65bSHans de Goede 		 BYT_GLITCH_F_FAST_CLK;
13629f573b98SCristina Ciocan 
13639f573b98SCristina Ciocan 	writel(value, reg);
13649f573b98SCristina Ciocan 
13659f573b98SCristina Ciocan 	if (type & IRQ_TYPE_EDGE_BOTH)
13669f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_edge_irq);
13679f573b98SCristina Ciocan 	else if (type & IRQ_TYPE_LEVEL_MASK)
13689f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_level_irq);
13699f573b98SCristina Ciocan 
137040ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
13719f573b98SCristina Ciocan 
13729f573b98SCristina Ciocan 	return 0;
13735fae8b86SMika Westerberg }
13745fae8b86SMika Westerberg 
13756d209b42SAndy Shevchenko static const struct irq_chip byt_gpio_irq_chip = {
13766d209b42SAndy Shevchenko 	.name		= "BYT-GPIO",
13776d209b42SAndy Shevchenko 	.irq_ack	= byt_irq_ack,
13786d209b42SAndy Shevchenko 	.irq_mask	= byt_irq_mask,
13796d209b42SAndy Shevchenko 	.irq_unmask	= byt_irq_unmask,
13806d209b42SAndy Shevchenko 	.irq_set_type	= byt_irq_type,
13816d209b42SAndy Shevchenko 	.flags		= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE,
13826d209b42SAndy Shevchenko 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
13836d209b42SAndy Shevchenko };
13846d209b42SAndy Shevchenko 
138571e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc)
138671e6ca61SCristina Ciocan {
138771e6ca61SCristina Ciocan 	struct irq_data *data = irq_desc_get_irq_data(desc);
13885d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc));
138971e6ca61SCristina Ciocan 	struct irq_chip *chip = irq_data_get_irq_chip(data);
139071e6ca61SCristina Ciocan 	u32 base, pin;
139171e6ca61SCristina Ciocan 	void __iomem *reg;
139271e6ca61SCristina Ciocan 	unsigned long pending;
139371e6ca61SCristina Ciocan 
139471e6ca61SCristina Ciocan 	/* check from GPIO controller which pin triggered the interrupt */
139571e6ca61SCristina Ciocan 	for (base = 0; base < vg->chip.ngpio; base += 32) {
139671e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
139771e6ca61SCristina Ciocan 
139871e6ca61SCristina Ciocan 		if (!reg) {
1399b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base);
140071e6ca61SCristina Ciocan 			continue;
140171e6ca61SCristina Ciocan 		}
140271e6ca61SCristina Ciocan 
140340ecab55SHans de Goede 		raw_spin_lock(&byt_lock);
140471e6ca61SCristina Ciocan 		pending = readl(reg);
140540ecab55SHans de Goede 		raw_spin_unlock(&byt_lock);
1406a9cb09b7SMarc Zyngier 		for_each_set_bit(pin, &pending, 32)
1407a9cb09b7SMarc Zyngier 			generic_handle_domain_irq(vg->chip.irq.domain, base + pin);
140871e6ca61SCristina Ciocan 	}
140971e6ca61SCristina Ciocan 	chip->irq_eoi(data);
141071e6ca61SCristina Ciocan }
141171e6ca61SCristina Ciocan 
1412689e0088SHans de Goede static bool byt_direct_irq_sanity_check(struct intel_pinctrl *vg, int pin, u32 conf0)
1413689e0088SHans de Goede {
1414689e0088SHans de Goede 	int direct_irq, ioapic_direct_irq_base;
1415689e0088SHans de Goede 	u8 *match, direct_irq_mux[16];
1416689e0088SHans de Goede 	u32 trig;
1417689e0088SHans de Goede 
1418689e0088SHans de Goede 	memcpy_fromio(direct_irq_mux, vg->communities->pad_regs + BYT_DIRECT_IRQ_REG,
1419689e0088SHans de Goede 		      sizeof(direct_irq_mux));
1420689e0088SHans de Goede 	match = memchr(direct_irq_mux, pin, sizeof(direct_irq_mux));
1421689e0088SHans de Goede 	if (!match) {
1422b9e18434SAndy Shevchenko 		dev_warn(vg->dev, FW_BUG "Pin %i: DIRECT_IRQ_EN set but no IRQ assigned, clearing\n", pin);
1423689e0088SHans de Goede 		return false;
1424689e0088SHans de Goede 	}
1425689e0088SHans de Goede 
1426689e0088SHans de Goede 	direct_irq = match - direct_irq_mux;
1427689e0088SHans de Goede 	/* Base IO-APIC pin numbers come from atom-e3800-family-datasheet.pdf */
1428689e0088SHans de Goede 	ioapic_direct_irq_base = (vg->communities->npins == BYT_NGPIO_SCORE) ? 51 : 67;
1429689e0088SHans de Goede 	dev_dbg(vg->dev, "Pin %i: uses direct IRQ %d (IO-APIC %d)\n", pin,
1430689e0088SHans de Goede 		direct_irq, direct_irq + ioapic_direct_irq_base);
1431689e0088SHans de Goede 
1432689e0088SHans de Goede 	/*
1433689e0088SHans de Goede 	 * Testing has shown that the way direct IRQs work is that the combination of the
1434689e0088SHans de Goede 	 * direct-irq-en flag and the direct IRQ mux connect the output of the GPIO's IRQ
1435689e0088SHans de Goede 	 * trigger block, which normally sets the status flag in the IRQ status reg at
1436689e0088SHans de Goede 	 * 0x800, to one of the IO-APIC pins according to the mux registers.
1437689e0088SHans de Goede 	 *
1438689e0088SHans de Goede 	 * This means that:
1439689e0088SHans de Goede 	 * 1. The TRIG_MASK bits must be set to configure the GPIO's IRQ trigger block
1440689e0088SHans de Goede 	 * 2. The TRIG_LVL bit *must* be set, so that the GPIO's input value is directly
1441689e0088SHans de Goede 	 *    passed (1:1 or inverted) to the IO-APIC pin, if TRIG_LVL is not set,
1442689e0088SHans de Goede 	 *    selecting edge mode operation then on the first edge the IO-APIC pin goes
1443689e0088SHans de Goede 	 *    high, but since no write-to-clear write will be done to the IRQ status reg
1444689e0088SHans de Goede 	 *    at 0x800, the detected edge condition will never get cleared.
1445689e0088SHans de Goede 	 */
1446689e0088SHans de Goede 	trig = conf0 & BYT_TRIG_MASK;
1447689e0088SHans de Goede 	if (trig != (BYT_TRIG_POS | BYT_TRIG_LVL) &&
1448689e0088SHans de Goede 	    trig != (BYT_TRIG_NEG | BYT_TRIG_LVL)) {
1449b9e18434SAndy Shevchenko 		dev_warn(vg->dev,
1450b9e18434SAndy Shevchenko 			 FW_BUG "Pin %i: DIRECT_IRQ_EN set without trigger (CONF0: %#08x), clearing\n",
1451689e0088SHans de Goede 			 pin, conf0);
1452689e0088SHans de Goede 		return false;
1453689e0088SHans de Goede 	}
1454689e0088SHans de Goede 
1455689e0088SHans de Goede 	return true;
1456689e0088SHans de Goede }
1457689e0088SHans de Goede 
14585fbe5b58SLinus Walleij static void byt_init_irq_valid_mask(struct gpio_chip *chip,
14595fbe5b58SLinus Walleij 				    unsigned long *valid_mask,
14605fbe5b58SLinus Walleij 				    unsigned int ngpios)
14615fbe5b58SLinus Walleij {
14625d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
14635fae8b86SMika Westerberg 	void __iomem *reg;
1464e70982b3SAndy Shevchenko 	u32 value;
146595f0972cSMika Westerberg 	int i;
146695f0972cSMika Westerberg 
146795f0972cSMika Westerberg 	/*
146895f0972cSMika Westerberg 	 * Clear interrupt triggers for all pins that are GPIOs and
146995f0972cSMika Westerberg 	 * do not use direct IRQ mode. This will prevent spurious
147095f0972cSMika Westerberg 	 * interrupts from misconfigured pins.
147195f0972cSMika Westerberg 	 */
14725d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
14735d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
147471e6ca61SCristina Ciocan 
147571e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
147671e6ca61SCristina Ciocan 		if (!reg) {
1477b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: could not retrieve CONF0\n", i);
147871e6ca61SCristina Ciocan 			continue;
147971e6ca61SCristina Ciocan 		}
148071e6ca61SCristina Ciocan 
148171e6ca61SCristina Ciocan 		value = readl(reg);
148249c03096SAndy Shevchenko 		if (value & BYT_DIRECT_IRQ_EN) {
1483689e0088SHans de Goede 			if (byt_direct_irq_sanity_check(vg, i, value)) {
1484e70982b3SAndy Shevchenko 				clear_bit(i, valid_mask);
1485689e0088SHans de Goede 			} else {
1486689e0088SHans de Goede 				value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS |
1487689e0088SHans de Goede 					   BYT_TRIG_NEG | BYT_TRIG_LVL);
1488689e0088SHans de Goede 				writel(value, reg);
1489689e0088SHans de Goede 			}
149049c03096SAndy Shevchenko 		} else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
149195f0972cSMika Westerberg 			byt_gpio_clear_triggering(vg, i);
1492990ec243SAndy Shevchenko 			dev_dbg(vg->dev, "disabling GPIO %d\n", i);
149395f0972cSMika Westerberg 		}
149495f0972cSMika Westerberg 	}
1495e70982b3SAndy Shevchenko }
1496e70982b3SAndy Shevchenko 
1497e70982b3SAndy Shevchenko static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
1498e70982b3SAndy Shevchenko {
14995d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1500e70982b3SAndy Shevchenko 	void __iomem *reg;
1501e70982b3SAndy Shevchenko 	u32 base, value;
15025fae8b86SMika Westerberg 
15035fae8b86SMika Westerberg 	/* clear interrupt status trigger registers */
15045d33e0ebSAndy Shevchenko 	for (base = 0; base < vg->soc->npins; base += 32) {
1505c501d0b1SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
150671e6ca61SCristina Ciocan 
150771e6ca61SCristina Ciocan 		if (!reg) {
1508b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base);
150971e6ca61SCristina Ciocan 			continue;
151071e6ca61SCristina Ciocan 		}
151171e6ca61SCristina Ciocan 
15125fae8b86SMika Westerberg 		writel(0xffffffff, reg);
15135fae8b86SMika Westerberg 		/* make sure trigger bits are cleared, if not then a pin
15145fae8b86SMika Westerberg 		   might be misconfigured in bios */
15155fae8b86SMika Westerberg 		value = readl(reg);
15165fae8b86SMika Westerberg 		if (value)
1517990ec243SAndy Shevchenko 			dev_err(vg->dev,
1518b9e18434SAndy Shevchenko 				"GPIO interrupt error, pins misconfigured. INT_STAT%u: %#08x\n",
1519973232e2SAlexander Stein 				base / 32, value);
15205fae8b86SMika Westerberg 	}
1521ca8a958eSAndy Shevchenko 
1522ca8a958eSAndy Shevchenko 	return 0;
15235fae8b86SMika Westerberg }
15245fae8b86SMika Westerberg 
1525ed3c1564SAndy Shevchenko static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
1526ed3c1564SAndy Shevchenko {
15275d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = gpiochip_get_data(chip);
1528990ec243SAndy Shevchenko 	struct device *dev = vg->dev;
1529ed3c1564SAndy Shevchenko 	int ret;
1530ed3c1564SAndy Shevchenko 
15315d33e0ebSAndy Shevchenko 	ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins);
1532ed3c1564SAndy Shevchenko 	if (ret)
1533ed3c1564SAndy Shevchenko 		dev_err(dev, "failed to add GPIO pin range\n");
1534ed3c1564SAndy Shevchenko 
1535ed3c1564SAndy Shevchenko 	return ret;
1536ed3c1564SAndy Shevchenko }
1537ed3c1564SAndy Shevchenko 
15385d33e0ebSAndy Shevchenko static int byt_gpio_probe(struct intel_pinctrl *vg)
15395fae8b86SMika Westerberg {
1540990ec243SAndy Shevchenko 	struct platform_device *pdev = to_platform_device(vg->dev);
15415fae8b86SMika Westerberg 	struct gpio_chip *gc;
1542f86a1bb5SAndy Shevchenko 	int irq, ret;
15435fae8b86SMika Westerberg 
154471e6ca61SCristina Ciocan 	/* Set up gpio chip */
154571e6ca61SCristina Ciocan 	vg->chip	= byt_gpio_chip;
15465fae8b86SMika Westerberg 	gc		= &vg->chip;
1547990ec243SAndy Shevchenko 	gc->label	= dev_name(vg->dev);
15485fae8b86SMika Westerberg 	gc->base	= -1;
15495fae8b86SMika Westerberg 	gc->can_sleep	= false;
1550ed3c1564SAndy Shevchenko 	gc->add_pin_ranges = byt_gpio_add_pin_ranges;
1551990ec243SAndy Shevchenko 	gc->parent	= vg->dev;
15525d33e0ebSAndy Shevchenko 	gc->ngpio	= vg->soc->npins;
15535fae8b86SMika Westerberg 
1554fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
15555d33e0ebSAndy Shevchenko 	vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads),
15565d33e0ebSAndy Shevchenko 					GFP_KERNEL);
15575d33e0ebSAndy Shevchenko 	if (!vg->context.pads)
1558d6cb7722SAditya Pakki 		return -ENOMEM;
1559fcc18debSMika Westerberg #endif
15605fae8b86SMika Westerberg 
15615fae8b86SMika Westerberg 	/* set up interrupts  */
1562f86a1bb5SAndy Shevchenko 	irq = platform_get_irq_optional(pdev, 0);
1563f86a1bb5SAndy Shevchenko 	if (irq > 0) {
1564ca8a958eSAndy Shevchenko 		struct gpio_irq_chip *girq;
1565ca8a958eSAndy Shevchenko 
1566ca8a958eSAndy Shevchenko 		girq = &gc->irq;
15676d209b42SAndy Shevchenko 		gpio_irq_chip_set_chip(girq, &byt_gpio_irq_chip);
1568ca8a958eSAndy Shevchenko 		girq->init_hw = byt_gpio_irq_init_hw;
1569ab68b220SAndy Shevchenko 		girq->init_valid_mask = byt_init_irq_valid_mask;
1570ca8a958eSAndy Shevchenko 		girq->parent_handler = byt_gpio_irq_handler;
1571ca8a958eSAndy Shevchenko 		girq->num_parents = 1;
1572990ec243SAndy Shevchenko 		girq->parents = devm_kcalloc(vg->dev, girq->num_parents,
1573ca8a958eSAndy Shevchenko 					     sizeof(*girq->parents), GFP_KERNEL);
1574ca8a958eSAndy Shevchenko 		if (!girq->parents)
1575ca8a958eSAndy Shevchenko 			return -ENOMEM;
1576f86a1bb5SAndy Shevchenko 		girq->parents[0] = irq;
1577ca8a958eSAndy Shevchenko 		girq->default_type = IRQ_TYPE_NONE;
1578ca8a958eSAndy Shevchenko 		girq->handler = handle_bad_irq;
15795fae8b86SMika Westerberg 	}
15805fae8b86SMika Westerberg 
1581990ec243SAndy Shevchenko 	ret = devm_gpiochip_add_data(vg->dev, gc, vg);
1582ca8a958eSAndy Shevchenko 	if (ret) {
1583990ec243SAndy Shevchenko 		dev_err(vg->dev, "failed adding byt-gpio chip\n");
1584ca8a958eSAndy Shevchenko 		return ret;
15855fae8b86SMika Westerberg 	}
15865fae8b86SMika Westerberg 
158771e6ca61SCristina Ciocan 	return ret;
158871e6ca61SCristina Ciocan }
158971e6ca61SCristina Ciocan 
15905d33e0ebSAndy Shevchenko static int byt_set_soc_data(struct intel_pinctrl *vg,
15915d33e0ebSAndy Shevchenko 			    const struct intel_pinctrl_soc_data *soc)
159271e6ca61SCristina Ciocan {
1593990ec243SAndy Shevchenko 	struct platform_device *pdev = to_platform_device(vg->dev);
159471e6ca61SCristina Ciocan 	int i;
159571e6ca61SCristina Ciocan 
15965d33e0ebSAndy Shevchenko 	vg->soc = soc;
15975d33e0ebSAndy Shevchenko 
15985d33e0ebSAndy Shevchenko 	vg->ncommunities = vg->soc->ncommunities;
15995d33e0ebSAndy Shevchenko 	vg->communities = devm_kcalloc(vg->dev, vg->ncommunities,
16005d33e0ebSAndy Shevchenko 				       sizeof(*vg->communities), GFP_KERNEL);
16015d33e0ebSAndy Shevchenko 	if (!vg->communities)
160271e6ca61SCristina Ciocan 		return -ENOMEM;
160371e6ca61SCristina Ciocan 
16045d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->ncommunities; i++) {
16055d33e0ebSAndy Shevchenko 		struct intel_community *comm = vg->communities + i;
160671e6ca61SCristina Ciocan 
16075d33e0ebSAndy Shevchenko 		*comm = vg->soc->communities[i];
160871e6ca61SCristina Ciocan 
1609990ec243SAndy Shevchenko 		comm->pad_regs = devm_platform_ioremap_resource(pdev, 0);
161034e65670SAndy Shevchenko 		if (IS_ERR(comm->pad_regs))
161134e65670SAndy Shevchenko 			return PTR_ERR(comm->pad_regs);
161271e6ca61SCristina Ciocan 	}
161371e6ca61SCristina Ciocan 
161471e6ca61SCristina Ciocan 	return 0;
161571e6ca61SCristina Ciocan }
161671e6ca61SCristina Ciocan 
161771e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = {
161871e6ca61SCristina Ciocan 	{ "INT33B2", (kernel_ulong_t)byt_soc_data },
161971e6ca61SCristina Ciocan 	{ "INT33FC", (kernel_ulong_t)byt_soc_data },
162071e6ca61SCristina Ciocan 	{ }
162171e6ca61SCristina Ciocan };
162271e6ca61SCristina Ciocan 
162371e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev)
162471e6ca61SCristina Ciocan {
1625ce7793e9SAndy Shevchenko 	const struct intel_pinctrl_soc_data *soc_data;
16262c02af70SAndy Shevchenko 	struct device *dev = &pdev->dev;
16275d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg;
1628ce7793e9SAndy Shevchenko 	int ret;
162971e6ca61SCristina Ciocan 
1630ce7793e9SAndy Shevchenko 	soc_data = intel_pinctrl_get_soc_data(pdev);
1631ce7793e9SAndy Shevchenko 	if (IS_ERR(soc_data))
1632ce7793e9SAndy Shevchenko 		return PTR_ERR(soc_data);
163371e6ca61SCristina Ciocan 
16342c02af70SAndy Shevchenko 	vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL);
163571e6ca61SCristina Ciocan 	if (!vg)
163671e6ca61SCristina Ciocan 		return -ENOMEM;
163771e6ca61SCristina Ciocan 
16382c02af70SAndy Shevchenko 	vg->dev = dev;
163971e6ca61SCristina Ciocan 	ret = byt_set_soc_data(vg, soc_data);
164071e6ca61SCristina Ciocan 	if (ret) {
16412c02af70SAndy Shevchenko 		dev_err(dev, "failed to set soc data\n");
164271e6ca61SCristina Ciocan 		return ret;
164371e6ca61SCristina Ciocan 	}
164471e6ca61SCristina Ciocan 
16455d33e0ebSAndy Shevchenko 	vg->pctldesc		= byt_pinctrl_desc;
16465d33e0ebSAndy Shevchenko 	vg->pctldesc.name	= dev_name(dev);
16475d33e0ebSAndy Shevchenko 	vg->pctldesc.pins	= vg->soc->pins;
16485d33e0ebSAndy Shevchenko 	vg->pctldesc.npins	= vg->soc->npins;
164971e6ca61SCristina Ciocan 
16505d33e0ebSAndy Shevchenko 	vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg);
16515d33e0ebSAndy Shevchenko 	if (IS_ERR(vg->pctldev)) {
16522c02af70SAndy Shevchenko 		dev_err(dev, "failed to register pinctrl driver\n");
16535d33e0ebSAndy Shevchenko 		return PTR_ERR(vg->pctldev);
165471e6ca61SCristina Ciocan 	}
165571e6ca61SCristina Ciocan 
165671e6ca61SCristina Ciocan 	ret = byt_gpio_probe(vg);
16570612413fSAndy Shevchenko 	if (ret)
165871e6ca61SCristina Ciocan 		return ret;
165971e6ca61SCristina Ciocan 
166071e6ca61SCristina Ciocan 	platform_set_drvdata(pdev, vg);
16612c02af70SAndy Shevchenko 	pm_runtime_enable(dev);
166271e6ca61SCristina Ciocan 
166371e6ca61SCristina Ciocan 	return 0;
166471e6ca61SCristina Ciocan }
166571e6ca61SCristina Ciocan 
1666fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
1667fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev)
1668fcc18debSMika Westerberg {
16695d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = dev_get_drvdata(dev);
167040ecab55SHans de Goede 	unsigned long flags;
1671fcc18debSMika Westerberg 	int i;
1672fcc18debSMika Westerberg 
167340ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
167440ecab55SHans de Goede 
16755d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
1676fcc18debSMika Westerberg 		void __iomem *reg;
1677fcc18debSMika Westerberg 		u32 value;
16785d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
1679fcc18debSMika Westerberg 
168071e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
168171e6ca61SCristina Ciocan 		if (!reg) {
1682b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i);
168371e6ca61SCristina Ciocan 			continue;
168471e6ca61SCristina Ciocan 		}
1685fcc18debSMika Westerberg 		value = readl(reg) & BYT_CONF0_RESTORE_MASK;
16865d33e0ebSAndy Shevchenko 		vg->context.pads[i].conf0 = value;
1687fcc18debSMika Westerberg 
168871e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
16899d49882eSRaag Jadav 		if (!reg) {
16909d49882eSRaag Jadav 			dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i);
16919d49882eSRaag Jadav 			continue;
16929d49882eSRaag Jadav 		}
1693fcc18debSMika Westerberg 		value = readl(reg) & BYT_VAL_RESTORE_MASK;
16945d33e0ebSAndy Shevchenko 		vg->context.pads[i].val = value;
1695fcc18debSMika Westerberg 	}
1696fcc18debSMika Westerberg 
169740ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1698fcc18debSMika Westerberg 	return 0;
1699fcc18debSMika Westerberg }
1700fcc18debSMika Westerberg 
1701fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev)
1702fcc18debSMika Westerberg {
17035d33e0ebSAndy Shevchenko 	struct intel_pinctrl *vg = dev_get_drvdata(dev);
170440ecab55SHans de Goede 	unsigned long flags;
1705fcc18debSMika Westerberg 	int i;
1706fcc18debSMika Westerberg 
170740ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
170840ecab55SHans de Goede 
17095d33e0ebSAndy Shevchenko 	for (i = 0; i < vg->soc->npins; i++) {
1710fcc18debSMika Westerberg 		void __iomem *reg;
1711fcc18debSMika Westerberg 		u32 value;
17125d33e0ebSAndy Shevchenko 		unsigned int pin = vg->soc->pins[i].number;
1713fcc18debSMika Westerberg 
171471e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
171571e6ca61SCristina Ciocan 		if (!reg) {
1716b9e18434SAndy Shevchenko 			dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i);
171771e6ca61SCristina Ciocan 			continue;
171871e6ca61SCristina Ciocan 		}
1719fcc18debSMika Westerberg 		value = readl(reg);
1720fcc18debSMika Westerberg 		if ((value & BYT_CONF0_RESTORE_MASK) !=
17215d33e0ebSAndy Shevchenko 		     vg->context.pads[i].conf0) {
1722fcc18debSMika Westerberg 			value &= ~BYT_CONF0_RESTORE_MASK;
17235d33e0ebSAndy Shevchenko 			value |= vg->context.pads[i].conf0;
1724fcc18debSMika Westerberg 			writel(value, reg);
1725b9e18434SAndy Shevchenko 			dev_info(dev, "restored pin %d CONF0 %#08x", i, value);
1726fcc18debSMika Westerberg 		}
1727fcc18debSMika Westerberg 
172871e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
17299d49882eSRaag Jadav 		if (!reg) {
17309d49882eSRaag Jadav 			dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i);
17319d49882eSRaag Jadav 			continue;
17329d49882eSRaag Jadav 		}
1733fcc18debSMika Westerberg 		value = readl(reg);
1734fcc18debSMika Westerberg 		if ((value & BYT_VAL_RESTORE_MASK) !=
17355d33e0ebSAndy Shevchenko 		     vg->context.pads[i].val) {
1736fcc18debSMika Westerberg 			u32 v;
1737fcc18debSMika Westerberg 
1738fcc18debSMika Westerberg 			v = value & ~BYT_VAL_RESTORE_MASK;
17395d33e0ebSAndy Shevchenko 			v |= vg->context.pads[i].val;
1740fcc18debSMika Westerberg 			if (v != value) {
1741fcc18debSMika Westerberg 				writel(v, reg);
1742b9e18434SAndy Shevchenko 				dev_dbg(dev, "restored pin %d VAL %#08x\n", i, v);
1743fcc18debSMika Westerberg 			}
1744fcc18debSMika Westerberg 		}
1745fcc18debSMika Westerberg 	}
1746fcc18debSMika Westerberg 
174740ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1748fcc18debSMika Westerberg 	return 0;
1749fcc18debSMika Westerberg }
1750fcc18debSMika Westerberg #endif
1751fcc18debSMika Westerberg 
1752ec879f12SMika Westerberg #ifdef CONFIG_PM
17535fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev)
17545fae8b86SMika Westerberg {
17555fae8b86SMika Westerberg 	return 0;
17565fae8b86SMika Westerberg }
17575fae8b86SMika Westerberg 
17585fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev)
17595fae8b86SMika Westerberg {
17605fae8b86SMika Westerberg 	return 0;
17615fae8b86SMika Westerberg }
1762ec879f12SMika Westerberg #endif
17635fae8b86SMika Westerberg 
17645fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = {
1765fcc18debSMika Westerberg 	SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
1766fcc18debSMika Westerberg 	SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
1767fcc18debSMika Westerberg 			   NULL)
17685fae8b86SMika Westerberg };
17695fae8b86SMika Westerberg 
17705fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = {
177171e6ca61SCristina Ciocan 	.probe          = byt_pinctrl_probe,
17725fae8b86SMika Westerberg 	.driver         = {
17735fae8b86SMika Westerberg 		.name			= "byt_gpio",
17745fae8b86SMika Westerberg 		.pm			= &byt_gpio_pm_ops,
1775e87daf0bSAndy Shevchenko 		.acpi_match_table	= byt_gpio_acpi_match,
1776360943a8SPaul Gortmaker 		.suppress_bind_attrs	= true,
17775fae8b86SMika Westerberg 	},
17785fae8b86SMika Westerberg };
17795fae8b86SMika Westerberg 
17805fae8b86SMika Westerberg static int __init byt_gpio_init(void)
17815fae8b86SMika Westerberg {
17825fae8b86SMika Westerberg 	return platform_driver_register(&byt_gpio_driver);
17835fae8b86SMika Westerberg }
17845fae8b86SMika Westerberg subsys_initcall(byt_gpio_init);
1785*4d01688fSRaag Jadav 
1786*4d01688fSRaag Jadav MODULE_IMPORT_NS(PINCTRL_INTEL);
1787