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>
16e0da3842SAndy Shevchenko #include <linux/types.h>
17e0da3842SAndy Shevchenko #include <linux/platform_device.h>
185fae8b86SMika Westerberg #include <linux/pm_runtime.h>
1961db6c9dSAndy Shevchenko #include <linux/property.h>
20e0da3842SAndy Shevchenko #include <linux/seq_file.h>
2161db6c9dSAndy Shevchenko 
225fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h>
23c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h>
24c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h>
25c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h>
265fae8b86SMika Westerberg 
274f010b93SAndy Shevchenko #include "pinctrl-intel.h"
284f010b93SAndy Shevchenko 
295fae8b86SMika Westerberg /* memory mapped register offsets */
305fae8b86SMika Westerberg #define BYT_CONF0_REG		0x000
315fae8b86SMika Westerberg #define BYT_CONF1_REG		0x004
325fae8b86SMika Westerberg #define BYT_VAL_REG		0x008
335fae8b86SMika Westerberg #define BYT_DFT_REG		0x00c
345fae8b86SMika Westerberg #define BYT_INT_STAT_REG	0x800
35658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG	0x9d0
365fae8b86SMika Westerberg 
375fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */
385fae8b86SMika Westerberg #define BYT_IODEN		BIT(31)
395fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN	BIT(27)
40eb0a2daaSAndy Shevchenko #define BYT_TRIG_MASK		GENMASK(26, 24)
415fae8b86SMika Westerberg #define BYT_TRIG_NEG		BIT(26)
425fae8b86SMika Westerberg #define BYT_TRIG_POS		BIT(25)
435fae8b86SMika Westerberg #define BYT_TRIG_LVL		BIT(24)
44658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN		BIT(20)
459291c65bSHans de Goede #define BYT_GLITCH_FILTER_EN	BIT(19)
469291c65bSHans de Goede #define BYT_GLITCH_F_SLOW_CLK	BIT(17)
479291c65bSHans de Goede #define BYT_GLITCH_F_FAST_CLK	BIT(16)
485fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT	9
49eb0a2daaSAndy Shevchenko #define BYT_PULL_STR_MASK	GENMASK(10, 9)
505fae8b86SMika Westerberg #define BYT_PULL_STR_2K		(0 << BYT_PULL_STR_SHIFT)
515fae8b86SMika Westerberg #define BYT_PULL_STR_10K	(1 << BYT_PULL_STR_SHIFT)
525fae8b86SMika Westerberg #define BYT_PULL_STR_20K	(2 << BYT_PULL_STR_SHIFT)
535fae8b86SMika Westerberg #define BYT_PULL_STR_40K	(3 << BYT_PULL_STR_SHIFT)
545fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_SHIFT	7
55eb0a2daaSAndy Shevchenko #define BYT_PULL_ASSIGN_MASK	GENMASK(8, 7)
565fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_UP	(1 << BYT_PULL_ASSIGN_SHIFT)
575fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_DOWN	(2 << BYT_PULL_ASSIGN_SHIFT)
58eb0a2daaSAndy Shevchenko #define BYT_PIN_MUX		GENMASK(2, 0)
595fae8b86SMika Westerberg 
605fae8b86SMika Westerberg /* BYT_VAL_REG register bits */
61eb0a2daaSAndy Shevchenko #define BYT_DIR_MASK		GENMASK(2, 1)
625fae8b86SMika Westerberg #define BYT_INPUT_EN		BIT(2)  /* 0: input enabled (active low)*/
635fae8b86SMika Westerberg #define BYT_OUTPUT_EN		BIT(1)  /* 0: output enabled (active low)*/
645fae8b86SMika Westerberg #define BYT_LEVEL		BIT(0)
655fae8b86SMika Westerberg 
66eb0a2daaSAndy Shevchenko #define BYT_CONF0_RESTORE_MASK	(BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX)
67fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK	(BYT_DIR_MASK | BYT_LEVEL)
68fcc18debSMika Westerberg 
69658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */
70eb0a2daaSAndy Shevchenko #define BYT_DEBOUNCE_PULSE_MASK		GENMASK(2, 0)
71658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US	1
72658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US	2
73658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US	3
74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS		4
75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS		5
76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS		6
77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS		7
78658b476cSCristina Ciocan 
795fae8b86SMika Westerberg #define BYT_NGPIO_SCORE		102
805fae8b86SMika Westerberg #define BYT_NGPIO_NCORE		28
815fae8b86SMika Westerberg #define BYT_NGPIO_SUS		44
825fae8b86SMika Westerberg 
835fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID	"1"
845fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID	"2"
855fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID	"3"
865fae8b86SMika Westerberg 
87c501d0b1SCristina Ciocan /*
88c501d0b1SCristina Ciocan  * This is the function value most pins have for GPIO muxing. If the value
89c501d0b1SCristina Ciocan  * differs from the default one, it must be explicitly mentioned. Otherwise, the
90c501d0b1SCristina Ciocan  * pin control implementation will set the muxing value to default GPIO if it
91c501d0b1SCristina Ciocan  * does not find a match for the requested function.
92c501d0b1SCristina Ciocan  */
93c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX	0
94a705f9c1SAndy Shevchenko #define BYT_ALTER_GPIO_MUX	1
95c501d0b1SCristina Ciocan 
96c8f5c4c7SCristina Ciocan struct byt_gpio_pin_context {
97c8f5c4c7SCristina Ciocan 	u32 conf0;
98c8f5c4c7SCristina Ciocan 	u32 val;
99c8f5c4c7SCristina Ciocan };
1005fae8b86SMika Westerberg 
101c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map)		\
102c8f5c4c7SCristina Ciocan 	{				\
103c8f5c4c7SCristina Ciocan 		.pin_base	= (p),	\
104c8f5c4c7SCristina Ciocan 		.npins		= (n),	\
105c8f5c4c7SCristina Ciocan 		.pad_map	= (map),\
106c8f5c4c7SCristina Ciocan 	}
107c8f5c4c7SCristina Ciocan 
10871e6ca61SCristina Ciocan struct byt_gpio {
10971e6ca61SCristina Ciocan 	struct gpio_chip chip;
110539d8bdeSAndy Shevchenko 	struct irq_chip irqchip;
11171e6ca61SCristina Ciocan 	struct platform_device *pdev;
11271e6ca61SCristina Ciocan 	struct pinctrl_dev *pctl_dev;
11371e6ca61SCristina Ciocan 	struct pinctrl_desc pctl_desc;
11434e65670SAndy Shevchenko 	const struct intel_pinctrl_soc_data *soc_data;
11534e65670SAndy Shevchenko 	struct intel_community *communities_copy;
11671e6ca61SCristina Ciocan 	struct byt_gpio_pin_context *saved_context;
11771e6ca61SCristina Ciocan };
11871e6ca61SCristina Ciocan 
119c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */
120c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = {
121c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "SATA_GP0"),
122c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "SATA_GP1"),
123c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "SATA_LED#"),
124c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "PCIE_CLKREQ0"),
125c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "PCIE_CLKREQ1"),
126c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "PCIE_CLKREQ2"),
127c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "PCIE_CLKREQ3"),
128c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "SD3_WP"),
129c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "HDA_RST"),
130c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "HDA_SYNC"),
131c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "HDA_CLK"),
132c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "HDA_SDO"),
133c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "HDA_SDI0"),
134c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "HDA_SDI1"),
135c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "GPIO_S0_SC14"),
136c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "GPIO_S0_SC15"),
137c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "MMC1_CLK"),
138c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "MMC1_D0"),
139c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "MMC1_D1"),
140c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "MMC1_D2"),
141c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "MMC1_D3"),
142c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "MMC1_D4"),
143c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "MMC1_D5"),
144c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "MMC1_D6"),
145c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "MMC1_D7"),
146c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "MMC1_CMD"),
147c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "MMC1_RST"),
148c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "SD2_CLK"),
149c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(28, "SD2_D0"),
150c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(29, "SD2_D1"),
151c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(30, "SD2_D2"),
152c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(31, "SD2_D3_CD"),
153c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(32, "SD2_CMD"),
154c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(33, "SD3_CLK"),
155c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(34, "SD3_D0"),
156c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(35, "SD3_D1"),
157c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(36, "SD3_D2"),
158c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(37, "SD3_D3"),
159c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(38, "SD3_CD"),
160c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(39, "SD3_CMD"),
161c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(40, "SD3_1P8EN"),
162c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(41, "SD3_PWREN#"),
163c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(42, "ILB_LPC_AD0"),
164c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(43, "ILB_LPC_AD1"),
165c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(44, "ILB_LPC_AD2"),
166c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(45, "ILB_LPC_AD3"),
167c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(46, "ILB_LPC_FRAME"),
168c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(47, "ILB_LPC_CLK0"),
169c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(48, "ILB_LPC_CLK1"),
170c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(49, "ILB_LPC_CLKRUN"),
171c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(50, "ILB_LPC_SERIRQ"),
172c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(51, "PCU_SMB_DATA"),
173c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(52, "PCU_SMB_CLK"),
174c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(53, "PCU_SMB_ALERT"),
175c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(54, "ILB_8254_SPKR"),
176c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(55, "GPIO_S0_SC55"),
177c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(56, "GPIO_S0_SC56"),
178c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(57, "GPIO_S0_SC57"),
179c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(58, "GPIO_S0_SC58"),
180c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(59, "GPIO_S0_SC59"),
181c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(60, "GPIO_S0_SC60"),
182c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(61, "GPIO_S0_SC61"),
183c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(62, "LPE_I2S2_CLK"),
184c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(63, "LPE_I2S2_FRM"),
185c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(64, "LPE_I2S2_DATAIN"),
186c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"),
187c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(66, "SIO_SPI_CS"),
188c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(67, "SIO_SPI_MISO"),
189c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(68, "SIO_SPI_MOSI"),
190c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(69, "SIO_SPI_CLK"),
191c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(70, "SIO_UART1_RXD"),
192c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(71, "SIO_UART1_TXD"),
193c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(72, "SIO_UART1_RTS"),
194c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(73, "SIO_UART1_CTS"),
195c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(74, "SIO_UART2_RXD"),
196c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(75, "SIO_UART2_TXD"),
197c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(76, "SIO_UART2_RTS"),
198c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(77, "SIO_UART2_CTS"),
199c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(78, "SIO_I2C0_DATA"),
200c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(79, "SIO_I2C0_CLK"),
201c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(80, "SIO_I2C1_DATA"),
202c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(81, "SIO_I2C1_CLK"),
203c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(82, "SIO_I2C2_DATA"),
204c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(83, "SIO_I2C2_CLK"),
205c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(84, "SIO_I2C3_DATA"),
206c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(85, "SIO_I2C3_CLK"),
207c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(86, "SIO_I2C4_DATA"),
208c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(87, "SIO_I2C4_CLK"),
209c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(88, "SIO_I2C5_DATA"),
210c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(89, "SIO_I2C5_CLK"),
211c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(90, "SIO_I2C6_DATA"),
212c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(91, "SIO_I2C6_CLK"),
213c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(92, "GPIO_S0_SC92"),
214c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(93, "GPIO_S0_SC93"),
215c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(94, "SIO_PWM0"),
216c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(95, "SIO_PWM1"),
217c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(96, "PMC_PLT_CLK0"),
218c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(97, "PMC_PLT_CLK1"),
219c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(98, "PMC_PLT_CLK2"),
220c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(99, "PMC_PLT_CLK3"),
221c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(100, "PMC_PLT_CLK4"),
222c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(101, "PMC_PLT_CLK5"),
223c8f5c4c7SCristina Ciocan };
2245fae8b86SMika Westerberg 
225c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = {
226c8f5c4c7SCristina Ciocan 	85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
227c8f5c4c7SCristina Ciocan 	36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
228c8f5c4c7SCristina Ciocan 	54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
229c8f5c4c7SCristina Ciocan 	52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
230c8f5c4c7SCristina Ciocan 	95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
231c8f5c4c7SCristina Ciocan 	86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
232c8f5c4c7SCristina Ciocan 	80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
233c8f5c4c7SCristina Ciocan 	2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
234c8f5c4c7SCristina Ciocan 	31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
235c8f5c4c7SCristina Ciocan 	24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
236c8f5c4c7SCristina Ciocan 	97, 100,
2375fae8b86SMika Westerberg };
2385fae8b86SMika Westerberg 
239c8f5c4c7SCristina Ciocan /* SCORE groups */
240c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 };
241c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 };
242c8f5c4c7SCristina Ciocan 
243c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 };
244c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 };
245c8f5c4c7SCristina Ciocan 
246c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 };
247c8f5c4c7SCristina Ciocan 
248c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 };
249c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 };
250c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 };
251c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 };
252c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 };
253c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 };
254c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 };
255c8f5c4c7SCristina Ciocan 
256c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 };
257c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 };
258c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 };
259c8f5c4c7SCristina Ciocan 
260c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = {
261c8f5c4c7SCristina Ciocan 	7, 33, 34, 35, 36, 37, 38, 39, 40, 41,
262c8f5c4c7SCristina Ciocan };
2634f010b93SAndy Shevchenko static const unsigned int byt_score_sdcard_mux_values[] = {
264c8f5c4c7SCristina Ciocan 	2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
265c8f5c4c7SCristina Ciocan };
266c8f5c4c7SCristina Ciocan 
267c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 };
268c8f5c4c7SCristina Ciocan 
269c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = {
270c8f5c4c7SCristina Ciocan 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
271c8f5c4c7SCristina Ciocan };
272c8f5c4c7SCristina Ciocan 
273c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = {
274c8f5c4c7SCristina Ciocan 	42, 43, 44, 45, 46, 47, 48, 49, 50,
275c8f5c4c7SCristina Ciocan };
276c8f5c4c7SCristina Ciocan 
277c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 };
278c8f5c4c7SCristina Ciocan 
279c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 };
280c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 };
281c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 };
282b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 };
283b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 };
284b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
285c8f5c4c7SCristina Ciocan 
286c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
287c8f5c4c7SCristina Ciocan 
2884f010b93SAndy Shevchenko static const struct intel_pingroup byt_score_groups[] = {
2894f010b93SAndy Shevchenko 	PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1),
2904f010b93SAndy Shevchenko 	PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1),
2914f010b93SAndy Shevchenko 	PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1),
2924f010b93SAndy Shevchenko 	PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1),
2934f010b93SAndy Shevchenko 	PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1),
2944f010b93SAndy Shevchenko 	PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1),
2954f010b93SAndy Shevchenko 	PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1),
2964f010b93SAndy Shevchenko 	PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1),
2974f010b93SAndy Shevchenko 	PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1),
2984f010b93SAndy Shevchenko 	PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1),
2994f010b93SAndy Shevchenko 	PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1),
3004f010b93SAndy Shevchenko 	PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1),
3014f010b93SAndy Shevchenko 	PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1),
3024f010b93SAndy Shevchenko 	PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1),
3034f010b93SAndy Shevchenko 	PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1),
3044f010b93SAndy Shevchenko 	PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
3054f010b93SAndy Shevchenko 	PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1),
3064f010b93SAndy Shevchenko 	PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1),
3074f010b93SAndy Shevchenko 	PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1),
3084f010b93SAndy Shevchenko 	PIN_GROUP("sata_grp", byt_score_sata_pins, 1),
3094f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
3104f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
3114f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
3124f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
3134f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
3144f010b93SAndy Shevchenko 	PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
3154f010b93SAndy Shevchenko 	PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1),
316c8f5c4c7SCristina Ciocan };
317c8f5c4c7SCristina Ciocan 
318c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = {
319c8f5c4c7SCristina Ciocan 	"uart1_grp", "uart2_grp",
320c8f5c4c7SCristina Ciocan };
321c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = {
322c8f5c4c7SCristina Ciocan 	"pwm0_grp", "pwm1_grp",
323c8f5c4c7SCristina Ciocan };
324c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = {
325c8f5c4c7SCristina Ciocan 	"ssp0_grp", "ssp1_grp", "ssp2_grp",
326c8f5c4c7SCristina Ciocan };
327c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" };
328c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = {
329c8f5c4c7SCristina Ciocan 	"i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp",
330c8f5c4c7SCristina Ciocan 	"i2c6_grp",
331c8f5c4c7SCristina Ciocan };
332c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" };
333c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" };
334c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" };
335c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" };
336c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" };
337c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = {
338c8f5c4c7SCristina Ciocan 	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
339c8f5c4c7SCristina Ciocan 	"plt_clk4_grp", "plt_clk5_grp",
340c8f5c4c7SCristina Ciocan };
341c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
342c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = {
343c8f5c4c7SCristina Ciocan 	"uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
344c8f5c4c7SCristina Ciocan 	"ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
345c8f5c4c7SCristina Ciocan 	"i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
346c8f5c4c7SCristina Ciocan 	"sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
347c8f5c4c7SCristina Ciocan 	"plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
348c8f5c4c7SCristina Ciocan 	"plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
349c8f5c4c7SCristina Ciocan };
350c8f5c4c7SCristina Ciocan 
3514f010b93SAndy Shevchenko static const struct intel_function byt_score_functions[] = {
352c8f5c4c7SCristina Ciocan 	FUNCTION("uart", byt_score_uart_groups),
353c8f5c4c7SCristina Ciocan 	FUNCTION("pwm", byt_score_pwm_groups),
354c8f5c4c7SCristina Ciocan 	FUNCTION("ssp", byt_score_ssp_groups),
355c8f5c4c7SCristina Ciocan 	FUNCTION("spi", byt_score_spi_groups),
356c8f5c4c7SCristina Ciocan 	FUNCTION("i2c", byt_score_i2c_groups),
357c8f5c4c7SCristina Ciocan 	FUNCTION("sdcard", byt_score_sdcard_groups),
358c8f5c4c7SCristina Ciocan 	FUNCTION("sdio", byt_score_sdio_groups),
359c8f5c4c7SCristina Ciocan 	FUNCTION("emmc", byt_score_emmc_groups),
360c8f5c4c7SCristina Ciocan 	FUNCTION("lpc", byt_score_lpc_groups),
361c8f5c4c7SCristina Ciocan 	FUNCTION("sata", byt_score_sata_groups),
362c8f5c4c7SCristina Ciocan 	FUNCTION("plt_clk", byt_score_plt_clk_groups),
363c8f5c4c7SCristina Ciocan 	FUNCTION("smbus", byt_score_smbus_groups),
364c8f5c4c7SCristina Ciocan 	FUNCTION("gpio", byt_score_gpio_groups),
365c8f5c4c7SCristina Ciocan };
366c8f5c4c7SCristina Ciocan 
36734e65670SAndy Shevchenko static const struct intel_community byt_score_communities[] = {
368c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
369c8f5c4c7SCristina Ciocan };
370c8f5c4c7SCristina Ciocan 
37134e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_score_soc_data = {
372c8f5c4c7SCristina Ciocan 	.uid		= BYT_SCORE_ACPI_UID,
373c8f5c4c7SCristina Ciocan 	.pins		= byt_score_pins,
374c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_score_pins),
375c8f5c4c7SCristina Ciocan 	.groups		= byt_score_groups,
376c8f5c4c7SCristina Ciocan 	.ngroups	= ARRAY_SIZE(byt_score_groups),
377c8f5c4c7SCristina Ciocan 	.functions	= byt_score_functions,
378c8f5c4c7SCristina Ciocan 	.nfunctions	= ARRAY_SIZE(byt_score_functions),
379c8f5c4c7SCristina Ciocan 	.communities	= byt_score_communities,
380c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_score_communities),
381c8f5c4c7SCristina Ciocan };
382c8f5c4c7SCristina Ciocan 
383c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>]  */
384c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = {
385c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(0, "GPIO_S50"),
386c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(1, "GPIO_S51"),
387c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(2, "GPIO_S52"),
388c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(3, "GPIO_S53"),
389c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(4, "GPIO_S54"),
390c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(5, "GPIO_S55"),
391c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(6, "GPIO_S56"),
392c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(7, "GPIO_S57"),
393c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(8, "GPIO_S58"),
394c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(9, "GPIO_S59"),
395c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(10, "GPIO_S510"),
396c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(11, "PMC_SUSPWRDNACK"),
397c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(12, "PMC_SUSCLK0"),
398c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(13, "GPIO_S513"),
399c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(14, "USB_ULPI_RST"),
400c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"),
401c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(16, "PMC_PWRBTN"),
402c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(17, "GPIO_S517"),
403c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(18, "PMC_SUS_STAT"),
404c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(19, "USB_OC0"),
405c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(20, "USB_OC1"),
406c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(21, "PCU_SPI_CS1"),
407c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(22, "GPIO_S522"),
408c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(23, "GPIO_S523"),
409c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(24, "GPIO_S524"),
410c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(25, "GPIO_S525"),
411c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(26, "GPIO_S526"),
412c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(27, "GPIO_S527"),
413c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(28, "GPIO_S528"),
414c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(29, "GPIO_S529"),
415c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(30, "GPIO_S530"),
416c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(31, "USB_ULPI_CLK"),
417c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(32, "USB_ULPI_DATA0"),
418c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(33, "USB_ULPI_DATA1"),
419c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(34, "USB_ULPI_DATA2"),
420c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(35, "USB_ULPI_DATA3"),
421c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(36, "USB_ULPI_DATA4"),
422c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(37, "USB_ULPI_DATA5"),
423c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(38, "USB_ULPI_DATA6"),
424c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(39, "USB_ULPI_DATA7"),
425c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(40, "USB_ULPI_DIR"),
426c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(41, "USB_ULPI_NXT"),
427c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(42, "USB_ULPI_STP"),
428c8f5c4c7SCristina Ciocan 	PINCTRL_PIN(43, "USB_ULPI_REFCLK"),
429c8f5c4c7SCristina Ciocan };
430c8f5c4c7SCristina Ciocan 
431c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = {
432c8f5c4c7SCristina Ciocan 	29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
433c8f5c4c7SCristina Ciocan 	18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
434c8f5c4c7SCristina Ciocan 	0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
435c8f5c4c7SCristina Ciocan 	26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
436c8f5c4c7SCristina Ciocan 	52, 53, 59, 40,
437c8f5c4c7SCristina Ciocan };
438c8f5c4c7SCristina Ciocan 
439c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 };
4404f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 };
4414f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 };
442c8f5c4c7SCristina Ciocan 
443c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = {
444c8f5c4c7SCristina Ciocan 	14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
445c8f5c4c7SCristina Ciocan };
4464f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_mode_values[] = {
447c8f5c4c7SCristina Ciocan 	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
448c8f5c4c7SCristina Ciocan };
4494f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = {
4504f010b93SAndy Shevchenko 	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
451c8f5c4c7SCristina Ciocan };
452c8f5c4c7SCristina Ciocan 
453c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 };
4544f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 };
4554f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 };
456c8f5c4c7SCristina Ciocan 
4574f010b93SAndy Shevchenko static const struct intel_pingroup byt_sus_groups[] = {
4584f010b93SAndy Shevchenko 	PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values),
4594f010b93SAndy Shevchenko 	PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values),
4604f010b93SAndy Shevchenko 	PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values),
4614f010b93SAndy Shevchenko 	PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values),
4624f010b93SAndy Shevchenko 	PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values),
4634f010b93SAndy Shevchenko 	PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values),
464c8f5c4c7SCristina Ciocan };
465c8f5c4c7SCristina Ciocan 
466c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = {
467c8f5c4c7SCristina Ciocan 	"usb_oc_grp", "usb_ulpi_grp",
468c8f5c4c7SCristina Ciocan };
469c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" };
470c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = {
4714f010b93SAndy Shevchenko 	"usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio",
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),
478c8f5c4c7SCristina Ciocan };
479c8f5c4c7SCristina Ciocan 
48034e65670SAndy Shevchenko static const struct intel_community byt_sus_communities[] = {
481c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
482c8f5c4c7SCristina Ciocan };
483c8f5c4c7SCristina Ciocan 
48434e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
485c8f5c4c7SCristina Ciocan 	.uid		= BYT_SUS_ACPI_UID,
486c8f5c4c7SCristina Ciocan 	.pins		= byt_sus_pins,
487c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_sus_pins),
488c8f5c4c7SCristina Ciocan 	.groups		= byt_sus_groups,
489c8f5c4c7SCristina Ciocan 	.ngroups	= ARRAY_SIZE(byt_sus_groups),
490c8f5c4c7SCristina Ciocan 	.functions	= byt_sus_functions,
491c8f5c4c7SCristina Ciocan 	.nfunctions	= ARRAY_SIZE(byt_sus_functions),
492c8f5c4c7SCristina Ciocan 	.communities	= byt_sus_communities,
493c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_sus_communities),
494c8f5c4c7SCristina Ciocan };
495c8f5c4c7SCristina Ciocan 
496c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = {
497b30b736aSAndy Shevchenko 	PINCTRL_PIN(0, "HV_DDI0_HPD"),
498b30b736aSAndy Shevchenko 	PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"),
499b30b736aSAndy Shevchenko 	PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"),
500b30b736aSAndy Shevchenko 	PINCTRL_PIN(3, "PANEL0_VDDEN"),
501b30b736aSAndy Shevchenko 	PINCTRL_PIN(4, "PANEL0_BKLTEN"),
502b30b736aSAndy Shevchenko 	PINCTRL_PIN(5, "PANEL0_BKLTCTL"),
503b30b736aSAndy Shevchenko 	PINCTRL_PIN(6, "HV_DDI1_HPD"),
504b30b736aSAndy Shevchenko 	PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"),
505b30b736aSAndy Shevchenko 	PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"),
506b30b736aSAndy Shevchenko 	PINCTRL_PIN(9, "PANEL1_VDDEN"),
507b30b736aSAndy Shevchenko 	PINCTRL_PIN(10, "PANEL1_BKLTEN"),
508b30b736aSAndy Shevchenko 	PINCTRL_PIN(11, "PANEL1_BKLTCTL"),
509b30b736aSAndy Shevchenko 	PINCTRL_PIN(12, "GP_INTD_DSI_TE1"),
510b30b736aSAndy Shevchenko 	PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"),
511b30b736aSAndy Shevchenko 	PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"),
512b30b736aSAndy Shevchenko 	PINCTRL_PIN(15, "GP_CAMERASB00"),
513b30b736aSAndy Shevchenko 	PINCTRL_PIN(16, "GP_CAMERASB01"),
514b30b736aSAndy Shevchenko 	PINCTRL_PIN(17, "GP_CAMERASB02"),
515b30b736aSAndy Shevchenko 	PINCTRL_PIN(18, "GP_CAMERASB03"),
516b30b736aSAndy Shevchenko 	PINCTRL_PIN(19, "GP_CAMERASB04"),
517b30b736aSAndy Shevchenko 	PINCTRL_PIN(20, "GP_CAMERASB05"),
518b30b736aSAndy Shevchenko 	PINCTRL_PIN(21, "GP_CAMERASB06"),
519b30b736aSAndy Shevchenko 	PINCTRL_PIN(22, "GP_CAMERASB07"),
520b30b736aSAndy Shevchenko 	PINCTRL_PIN(23, "GP_CAMERASB08"),
521b30b736aSAndy Shevchenko 	PINCTRL_PIN(24, "GP_CAMERASB09"),
522b30b736aSAndy Shevchenko 	PINCTRL_PIN(25, "GP_CAMERASB10"),
523b30b736aSAndy Shevchenko 	PINCTRL_PIN(26, "GP_CAMERASB11"),
524b30b736aSAndy Shevchenko 	PINCTRL_PIN(27, "GP_INTD_DSI_TE2"),
525c8f5c4c7SCristina Ciocan };
526c8f5c4c7SCristina Ciocan 
527939330d7SAndy Shevchenko static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
528c8f5c4c7SCristina Ciocan 	19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
529c8f5c4c7SCristina Ciocan 	14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
530c8f5c4c7SCristina Ciocan 	3, 6, 10, 13, 2, 5, 9, 7,
531c8f5c4c7SCristina Ciocan };
532c8f5c4c7SCristina Ciocan 
53334e65670SAndy Shevchenko static const struct intel_community byt_ncore_communities[] = {
534c8f5c4c7SCristina Ciocan 	COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
535c8f5c4c7SCristina Ciocan };
536c8f5c4c7SCristina Ciocan 
53734e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
538c8f5c4c7SCristina Ciocan 	.uid		= BYT_NCORE_ACPI_UID,
539c8f5c4c7SCristina Ciocan 	.pins		= byt_ncore_pins,
540c8f5c4c7SCristina Ciocan 	.npins		= ARRAY_SIZE(byt_ncore_pins),
541c8f5c4c7SCristina Ciocan 	.communities	= byt_ncore_communities,
542c8f5c4c7SCristina Ciocan 	.ncommunities	= ARRAY_SIZE(byt_ncore_communities),
543c8f5c4c7SCristina Ciocan };
544c8f5c4c7SCristina Ciocan 
54534e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data *byt_soc_data[] = {
546c8f5c4c7SCristina Ciocan 	&byt_score_soc_data,
547c8f5c4c7SCristina Ciocan 	&byt_sus_soc_data,
548c8f5c4c7SCristina Ciocan 	&byt_ncore_soc_data,
549166d6e2aSAndy Shevchenko 	NULL
550c8f5c4c7SCristina Ciocan };
551c8f5c4c7SCristina Ciocan 
55240ecab55SHans de Goede static DEFINE_RAW_SPINLOCK(byt_lock);
55340ecab55SHans de Goede 
55434e65670SAndy Shevchenko static struct intel_community *byt_get_community(struct byt_gpio *vg,
555c501d0b1SCristina Ciocan 						 unsigned int pin)
556c501d0b1SCristina Ciocan {
55734e65670SAndy Shevchenko 	struct intel_community *comm;
558c501d0b1SCristina Ciocan 	int i;
559c501d0b1SCristina Ciocan 
560c501d0b1SCristina Ciocan 	for (i = 0; i < vg->soc_data->ncommunities; i++) {
561c501d0b1SCristina Ciocan 		comm = vg->communities_copy + i;
562c501d0b1SCristina Ciocan 		if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base)
563c501d0b1SCristina Ciocan 			return comm;
564c501d0b1SCristina Ciocan 	}
565c501d0b1SCristina Ciocan 
566c501d0b1SCristina Ciocan 	return NULL;
567c501d0b1SCristina Ciocan }
568c501d0b1SCristina Ciocan 
569c501d0b1SCristina Ciocan static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset,
5705fae8b86SMika Westerberg 				  int reg)
5715fae8b86SMika Westerberg {
57234e65670SAndy Shevchenko 	struct intel_community *comm = byt_get_community(vg, offset);
5731b89970dSAndy Shevchenko 	u32 reg_offset;
5745fae8b86SMika Westerberg 
575c501d0b1SCristina Ciocan 	if (!comm)
576c501d0b1SCristina Ciocan 		return NULL;
577c501d0b1SCristina Ciocan 
578c501d0b1SCristina Ciocan 	offset -= comm->pin_base;
5791b89970dSAndy Shevchenko 	switch (reg) {
5801b89970dSAndy Shevchenko 	case BYT_INT_STAT_REG:
5815fae8b86SMika Westerberg 		reg_offset = (offset / 32) * 4;
5821b89970dSAndy Shevchenko 		break;
5831b89970dSAndy Shevchenko 	case BYT_DEBOUNCE_REG:
5841b89970dSAndy Shevchenko 		reg_offset = 0;
5851b89970dSAndy Shevchenko 		break;
5861b89970dSAndy Shevchenko 	default:
587c501d0b1SCristina Ciocan 		reg_offset = comm->pad_map[offset] * 16;
5881b89970dSAndy Shevchenko 		break;
5891b89970dSAndy Shevchenko 	}
5905fae8b86SMika Westerberg 
59134e65670SAndy Shevchenko 	return comm->pad_regs + reg_offset + reg;
5925fae8b86SMika Westerberg }
5935fae8b86SMika Westerberg 
594c501d0b1SCristina Ciocan static int byt_get_groups_count(struct pinctrl_dev *pctldev)
59595f0972cSMika Westerberg {
596c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
597c501d0b1SCristina Ciocan 
598c501d0b1SCristina Ciocan 	return vg->soc_data->ngroups;
599c501d0b1SCristina Ciocan }
600c501d0b1SCristina Ciocan 
601c501d0b1SCristina Ciocan static const char *byt_get_group_name(struct pinctrl_dev *pctldev,
602c501d0b1SCristina Ciocan 				      unsigned int selector)
603c501d0b1SCristina Ciocan {
604c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
605c501d0b1SCristina Ciocan 
606c501d0b1SCristina Ciocan 	return vg->soc_data->groups[selector].name;
607c501d0b1SCristina Ciocan }
608c501d0b1SCristina Ciocan 
609c501d0b1SCristina Ciocan static int byt_get_group_pins(struct pinctrl_dev *pctldev,
610c501d0b1SCristina Ciocan 			      unsigned int selector,
611c501d0b1SCristina Ciocan 			      const unsigned int **pins,
612c501d0b1SCristina Ciocan 			      unsigned int *num_pins)
613c501d0b1SCristina Ciocan {
614c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
615c501d0b1SCristina Ciocan 
616c501d0b1SCristina Ciocan 	*pins		= vg->soc_data->groups[selector].pins;
617c501d0b1SCristina Ciocan 	*num_pins	= vg->soc_data->groups[selector].npins;
618c501d0b1SCristina Ciocan 
619c501d0b1SCristina Ciocan 	return 0;
620c501d0b1SCristina Ciocan }
621c501d0b1SCristina Ciocan 
622c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = {
623c501d0b1SCristina Ciocan 	.get_groups_count	= byt_get_groups_count,
624c501d0b1SCristina Ciocan 	.get_group_name		= byt_get_group_name,
625c501d0b1SCristina Ciocan 	.get_group_pins		= byt_get_group_pins,
626c501d0b1SCristina Ciocan };
627c501d0b1SCristina Ciocan 
628c501d0b1SCristina Ciocan static int byt_get_functions_count(struct pinctrl_dev *pctldev)
629c501d0b1SCristina Ciocan {
630c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
631c501d0b1SCristina Ciocan 
632c501d0b1SCristina Ciocan 	return vg->soc_data->nfunctions;
633c501d0b1SCristina Ciocan }
634c501d0b1SCristina Ciocan 
635c501d0b1SCristina Ciocan static const char *byt_get_function_name(struct pinctrl_dev *pctldev,
636c501d0b1SCristina Ciocan 					 unsigned int selector)
637c501d0b1SCristina Ciocan {
638c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
639c501d0b1SCristina Ciocan 
640c501d0b1SCristina Ciocan 	return vg->soc_data->functions[selector].name;
641c501d0b1SCristina Ciocan }
642c501d0b1SCristina Ciocan 
643c501d0b1SCristina Ciocan static int byt_get_function_groups(struct pinctrl_dev *pctldev,
644c501d0b1SCristina Ciocan 				   unsigned int selector,
645c501d0b1SCristina Ciocan 				   const char * const **groups,
646c501d0b1SCristina Ciocan 				   unsigned int *num_groups)
647c501d0b1SCristina Ciocan {
648c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
649c501d0b1SCristina Ciocan 
650c501d0b1SCristina Ciocan 	*groups		= vg->soc_data->functions[selector].groups;
651c501d0b1SCristina Ciocan 	*num_groups	= vg->soc_data->functions[selector].ngroups;
652c501d0b1SCristina Ciocan 
653c501d0b1SCristina Ciocan 	return 0;
654c501d0b1SCristina Ciocan }
655c501d0b1SCristina Ciocan 
656c501d0b1SCristina Ciocan static void byt_set_group_simple_mux(struct byt_gpio *vg,
6574f010b93SAndy Shevchenko 				     const struct intel_pingroup group,
6584f010b93SAndy Shevchenko 				     unsigned int func)
659c501d0b1SCristina Ciocan {
660c501d0b1SCristina Ciocan 	unsigned long flags;
661c501d0b1SCristina Ciocan 	int i;
662c501d0b1SCristina Ciocan 
66340ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
664c501d0b1SCristina Ciocan 
665c501d0b1SCristina Ciocan 	for (i = 0; i < group.npins; i++) {
666c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
667c501d0b1SCristina Ciocan 		u32 value;
668c501d0b1SCristina Ciocan 
669c501d0b1SCristina Ciocan 		padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
670c501d0b1SCristina Ciocan 		if (!padcfg0) {
671c501d0b1SCristina Ciocan 			dev_warn(&vg->pdev->dev,
672c501d0b1SCristina Ciocan 				 "Group %s, pin %i not muxed (no padcfg0)\n",
673c501d0b1SCristina Ciocan 				 group.name, i);
674c501d0b1SCristina Ciocan 			continue;
675c501d0b1SCristina Ciocan 		}
676c501d0b1SCristina Ciocan 
677c501d0b1SCristina Ciocan 		value = readl(padcfg0);
678c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
679c501d0b1SCristina Ciocan 		value |= func;
680c501d0b1SCristina Ciocan 		writel(value, padcfg0);
681c501d0b1SCristina Ciocan 	}
682c501d0b1SCristina Ciocan 
68340ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
684c501d0b1SCristina Ciocan }
685c501d0b1SCristina Ciocan 
686c501d0b1SCristina Ciocan static void byt_set_group_mixed_mux(struct byt_gpio *vg,
6874f010b93SAndy Shevchenko 				    const struct intel_pingroup group,
6884f010b93SAndy Shevchenko 				    const unsigned int *func)
689c501d0b1SCristina Ciocan {
690c501d0b1SCristina Ciocan 	unsigned long flags;
691c501d0b1SCristina Ciocan 	int i;
692c501d0b1SCristina Ciocan 
69340ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
694c501d0b1SCristina Ciocan 
695c501d0b1SCristina Ciocan 	for (i = 0; i < group.npins; i++) {
696c501d0b1SCristina Ciocan 		void __iomem *padcfg0;
697c501d0b1SCristina Ciocan 		u32 value;
698c501d0b1SCristina Ciocan 
699c501d0b1SCristina Ciocan 		padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG);
700c501d0b1SCristina Ciocan 		if (!padcfg0) {
701c501d0b1SCristina Ciocan 			dev_warn(&vg->pdev->dev,
702c501d0b1SCristina Ciocan 				 "Group %s, pin %i not muxed (no padcfg0)\n",
703c501d0b1SCristina Ciocan 				 group.name, i);
704c501d0b1SCristina Ciocan 			continue;
705c501d0b1SCristina Ciocan 		}
706c501d0b1SCristina Ciocan 
707c501d0b1SCristina Ciocan 		value = readl(padcfg0);
708c501d0b1SCristina Ciocan 		value &= ~BYT_PIN_MUX;
709c501d0b1SCristina Ciocan 		value |= func[i];
710c501d0b1SCristina Ciocan 		writel(value, padcfg0);
711c501d0b1SCristina Ciocan 	}
712c501d0b1SCristina Ciocan 
71340ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
714c501d0b1SCristina Ciocan }
715c501d0b1SCristina Ciocan 
716c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
717c501d0b1SCristina Ciocan 		       unsigned int group_selector)
718c501d0b1SCristina Ciocan {
719c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev);
7204f010b93SAndy Shevchenko 	const struct intel_function func = vg->soc_data->functions[func_selector];
7214f010b93SAndy Shevchenko 	const struct intel_pingroup group = vg->soc_data->groups[group_selector];
722c501d0b1SCristina Ciocan 
7234f010b93SAndy Shevchenko 	if (group.modes)
7244f010b93SAndy Shevchenko 		byt_set_group_mixed_mux(vg, group, group.modes);
7254f010b93SAndy Shevchenko 	else if (!strcmp(func.name, "gpio"))
726c501d0b1SCristina Ciocan 		byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
727c501d0b1SCristina Ciocan 	else
7284f010b93SAndy Shevchenko 		byt_set_group_simple_mux(vg, group, group.mode);
729c501d0b1SCristina Ciocan 
730c501d0b1SCristina Ciocan 	return 0;
731c501d0b1SCristina Ciocan }
732c501d0b1SCristina Ciocan 
733939330d7SAndy Shevchenko static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned int offset)
734c501d0b1SCristina Ciocan {
735c501d0b1SCristina Ciocan 	/* SCORE pin 92-93 */
736c501d0b1SCristina Ciocan 	if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) &&
737c501d0b1SCristina Ciocan 	    offset >= 92 && offset <= 93)
738a705f9c1SAndy Shevchenko 		return BYT_ALTER_GPIO_MUX;
739c501d0b1SCristina Ciocan 
740c501d0b1SCristina Ciocan 	/* SUS pin 11-21 */
741c501d0b1SCristina Ciocan 	if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) &&
742c501d0b1SCristina Ciocan 	    offset >= 11 && offset <= 21)
743a705f9c1SAndy Shevchenko 		return BYT_ALTER_GPIO_MUX;
744c501d0b1SCristina Ciocan 
745a705f9c1SAndy Shevchenko 	return BYT_DEFAULT_GPIO_MUX;
746c501d0b1SCristina Ciocan }
747c501d0b1SCristina Ciocan 
748c501d0b1SCristina Ciocan static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset)
749c501d0b1SCristina Ciocan {
750c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
75195f0972cSMika Westerberg 	unsigned long flags;
75295f0972cSMika Westerberg 	u32 value;
75395f0972cSMika Westerberg 
75440ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
75595f0972cSMika Westerberg 	value = readl(reg);
75695f0972cSMika Westerberg 	value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
75795f0972cSMika Westerberg 	writel(value, reg);
75840ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
75995f0972cSMika Westerberg }
76095f0972cSMika Westerberg 
761c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
762c501d0b1SCristina Ciocan 				   struct pinctrl_gpio_range *range,
763c501d0b1SCristina Ciocan 				   unsigned int offset)
7645fae8b86SMika Westerberg {
765c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
766c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
767f8323b6bSMika Westerberg 	u32 value, gpio_mux;
76839ce8150SMika Westerberg 	unsigned long flags;
76939ce8150SMika Westerberg 
77040ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
7715fae8b86SMika Westerberg 
7725fae8b86SMika Westerberg 	/*
7735fae8b86SMika Westerberg 	 * In most cases, func pin mux 000 means GPIO function.
7745fae8b86SMika Westerberg 	 * But, some pins may have func pin mux 001 represents
775f8323b6bSMika Westerberg 	 * GPIO function.
776f8323b6bSMika Westerberg 	 *
777f8323b6bSMika Westerberg 	 * Because there are devices out there where some pins were not
778f8323b6bSMika Westerberg 	 * configured correctly we allow changing the mux value from
779f8323b6bSMika Westerberg 	 * request (but print out warning about that).
7805fae8b86SMika Westerberg 	 */
7815fae8b86SMika Westerberg 	value = readl(reg) & BYT_PIN_MUX;
782f8323b6bSMika Westerberg 	gpio_mux = byt_get_gpio_mux(vg, offset);
783b5894d12SHans de Goede 	if (gpio_mux != value) {
784f8323b6bSMika Westerberg 		value = readl(reg) & ~BYT_PIN_MUX;
785f8323b6bSMika Westerberg 		value |= gpio_mux;
786f8323b6bSMika Westerberg 		writel(value, reg);
787f8323b6bSMika Westerberg 
788b5894d12SHans de Goede 		dev_warn(&vg->pdev->dev, FW_BUG
789f8323b6bSMika Westerberg 			 "pin %u forcibly re-configured as GPIO\n", offset);
7905fae8b86SMika Westerberg 	}
7915fae8b86SMika Westerberg 
79240ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
79339ce8150SMika Westerberg 
7945fae8b86SMika Westerberg 	pm_runtime_get(&vg->pdev->dev);
7955fae8b86SMika Westerberg 
7965fae8b86SMika Westerberg 	return 0;
7975fae8b86SMika Westerberg }
7985fae8b86SMika Westerberg 
799c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
800c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
801c501d0b1SCristina Ciocan 				  unsigned int offset)
802c501d0b1SCristina Ciocan {
803c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
804c501d0b1SCristina Ciocan 
805c501d0b1SCristina Ciocan 	byt_gpio_clear_triggering(vg, offset);
806c501d0b1SCristina Ciocan 	pm_runtime_put(&vg->pdev->dev);
807c501d0b1SCristina Ciocan }
808c501d0b1SCristina Ciocan 
809c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
810c501d0b1SCristina Ciocan 				  struct pinctrl_gpio_range *range,
811c501d0b1SCristina Ciocan 				  unsigned int offset,
812c501d0b1SCristina Ciocan 				  bool input)
813c501d0b1SCristina Ciocan {
814c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
815c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
816c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
817c501d0b1SCristina Ciocan 	unsigned long flags;
818c501d0b1SCristina Ciocan 	u32 value;
819c501d0b1SCristina Ciocan 
82040ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
821c501d0b1SCristina Ciocan 
822c501d0b1SCristina Ciocan 	value = readl(val_reg);
823c501d0b1SCristina Ciocan 	value &= ~BYT_DIR_MASK;
824c501d0b1SCristina Ciocan 	if (input)
825c501d0b1SCristina Ciocan 		value |= BYT_OUTPUT_EN;
826c501d0b1SCristina Ciocan 	else
827c501d0b1SCristina Ciocan 		/*
828c501d0b1SCristina Ciocan 		 * Before making any direction modifications, do a check if gpio
829c501d0b1SCristina Ciocan 		 * is set for direct IRQ.  On baytrail, setting GPIO to output
830c501d0b1SCristina Ciocan 		 * does not make sense, so let's at least warn the caller before
831c501d0b1SCristina Ciocan 		 * they shoot themselves in the foot.
832c501d0b1SCristina Ciocan 		 */
833c501d0b1SCristina Ciocan 		WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN,
834c501d0b1SCristina Ciocan 		     "Potential Error: Setting GPIO with direct_irq_en to output");
835c501d0b1SCristina Ciocan 	writel(value, val_reg);
836c501d0b1SCristina Ciocan 
83740ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
838c501d0b1SCristina Ciocan 
839c501d0b1SCristina Ciocan 	return 0;
840c501d0b1SCristina Ciocan }
841c501d0b1SCristina Ciocan 
842c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = {
843c501d0b1SCristina Ciocan 	.get_functions_count	= byt_get_functions_count,
844c501d0b1SCristina Ciocan 	.get_function_name	= byt_get_function_name,
845c501d0b1SCristina Ciocan 	.get_function_groups	= byt_get_function_groups,
846c501d0b1SCristina Ciocan 	.set_mux		= byt_set_mux,
847c501d0b1SCristina Ciocan 	.gpio_request_enable	= byt_gpio_request_enable,
848c501d0b1SCristina Ciocan 	.gpio_disable_free	= byt_gpio_disable_free,
849c501d0b1SCristina Ciocan 	.gpio_set_direction	= byt_gpio_set_direction,
850c501d0b1SCristina Ciocan };
851c501d0b1SCristina Ciocan 
852c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength)
853c501d0b1SCristina Ciocan {
854c501d0b1SCristina Ciocan 	switch (reg & BYT_PULL_STR_MASK) {
855c501d0b1SCristina Ciocan 	case BYT_PULL_STR_2K:
856c501d0b1SCristina Ciocan 		*strength = 2000;
857c501d0b1SCristina Ciocan 		break;
858c501d0b1SCristina Ciocan 	case BYT_PULL_STR_10K:
859c501d0b1SCristina Ciocan 		*strength = 10000;
860c501d0b1SCristina Ciocan 		break;
861c501d0b1SCristina Ciocan 	case BYT_PULL_STR_20K:
862c501d0b1SCristina Ciocan 		*strength = 20000;
863c501d0b1SCristina Ciocan 		break;
864c501d0b1SCristina Ciocan 	case BYT_PULL_STR_40K:
865c501d0b1SCristina Ciocan 		*strength = 40000;
866c501d0b1SCristina Ciocan 		break;
867c501d0b1SCristina Ciocan 	}
868c501d0b1SCristina Ciocan }
869c501d0b1SCristina Ciocan 
870c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength)
871c501d0b1SCristina Ciocan {
872c501d0b1SCristina Ciocan 	*reg &= ~BYT_PULL_STR_MASK;
873c501d0b1SCristina Ciocan 
874c501d0b1SCristina Ciocan 	switch (strength) {
875c501d0b1SCristina Ciocan 	case 2000:
876c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_2K;
877c501d0b1SCristina Ciocan 		break;
878c501d0b1SCristina Ciocan 	case 10000:
879c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_10K;
880c501d0b1SCristina Ciocan 		break;
881c501d0b1SCristina Ciocan 	case 20000:
882c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_20K;
883c501d0b1SCristina Ciocan 		break;
884c501d0b1SCristina Ciocan 	case 40000:
885c501d0b1SCristina Ciocan 		*reg |= BYT_PULL_STR_40K;
886c501d0b1SCristina Ciocan 		break;
887c501d0b1SCristina Ciocan 	default:
888c501d0b1SCristina Ciocan 		return -EINVAL;
889c501d0b1SCristina Ciocan 	}
890c501d0b1SCristina Ciocan 
891c501d0b1SCristina Ciocan 	return 0;
892c501d0b1SCristina Ciocan }
893c501d0b1SCristina Ciocan 
894c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
895c501d0b1SCristina Ciocan 			      unsigned long *config)
896c501d0b1SCristina Ciocan {
897c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
898c501d0b1SCristina Ciocan 	enum pin_config_param param = pinconf_to_config_param(*config);
899c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
900c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
90104ff5a09SAndy Shevchenko 	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
902c501d0b1SCristina Ciocan 	unsigned long flags;
903658b476cSCristina Ciocan 	u32 conf, pull, val, debounce;
904c501d0b1SCristina Ciocan 	u16 arg = 0;
905c501d0b1SCristina Ciocan 
90640ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
907c501d0b1SCristina Ciocan 	conf = readl(conf_reg);
908c501d0b1SCristina Ciocan 	pull = conf & BYT_PULL_ASSIGN_MASK;
909c501d0b1SCristina Ciocan 	val = readl(val_reg);
91040ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
911c501d0b1SCristina Ciocan 
912c501d0b1SCristina Ciocan 	switch (param) {
913c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_DISABLE:
914c501d0b1SCristina Ciocan 		if (pull)
915c501d0b1SCristina Ciocan 			return -EINVAL;
916c501d0b1SCristina Ciocan 		break;
917c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_PULL_DOWN:
918c501d0b1SCristina Ciocan 		/* Pull assignment is only applicable in input mode */
919c501d0b1SCristina Ciocan 		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN)
920c501d0b1SCristina Ciocan 			return -EINVAL;
921c501d0b1SCristina Ciocan 
922c501d0b1SCristina Ciocan 		byt_get_pull_strength(conf, &arg);
923c501d0b1SCristina Ciocan 
924c501d0b1SCristina Ciocan 		break;
925c501d0b1SCristina Ciocan 	case PIN_CONFIG_BIAS_PULL_UP:
926c501d0b1SCristina Ciocan 		/* Pull assignment is only applicable in input mode */
927c501d0b1SCristina Ciocan 		if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP)
928c501d0b1SCristina Ciocan 			return -EINVAL;
929c501d0b1SCristina Ciocan 
930c501d0b1SCristina Ciocan 		byt_get_pull_strength(conf, &arg);
931c501d0b1SCristina Ciocan 
932c501d0b1SCristina Ciocan 		break;
933658b476cSCristina Ciocan 	case PIN_CONFIG_INPUT_DEBOUNCE:
934658b476cSCristina Ciocan 		if (!(conf & BYT_DEBOUNCE_EN))
935658b476cSCristina Ciocan 			return -EINVAL;
936658b476cSCristina Ciocan 
93740ecab55SHans de Goede 		raw_spin_lock_irqsave(&byt_lock, flags);
93804ff5a09SAndy Shevchenko 		debounce = readl(db_reg);
93940ecab55SHans de Goede 		raw_spin_unlock_irqrestore(&byt_lock, flags);
940658b476cSCristina Ciocan 
941658b476cSCristina Ciocan 		switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
942658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_375US:
943658b476cSCristina Ciocan 			arg = 375;
944658b476cSCristina Ciocan 			break;
945658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_750US:
946658b476cSCristina Ciocan 			arg = 750;
947658b476cSCristina Ciocan 			break;
948658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_1500US:
949658b476cSCristina Ciocan 			arg = 1500;
950658b476cSCristina Ciocan 			break;
951658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_3MS:
952658b476cSCristina Ciocan 			arg = 3000;
953658b476cSCristina Ciocan 			break;
954658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_6MS:
955658b476cSCristina Ciocan 			arg = 6000;
956658b476cSCristina Ciocan 			break;
957658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_12MS:
958658b476cSCristina Ciocan 			arg = 12000;
959658b476cSCristina Ciocan 			break;
960658b476cSCristina Ciocan 		case BYT_DEBOUNCE_PULSE_24MS:
961658b476cSCristina Ciocan 			arg = 24000;
962658b476cSCristina Ciocan 			break;
963658b476cSCristina Ciocan 		default:
964658b476cSCristina Ciocan 			return -EINVAL;
965658b476cSCristina Ciocan 		}
966658b476cSCristina Ciocan 
967658b476cSCristina Ciocan 		break;
968c501d0b1SCristina Ciocan 	default:
969c501d0b1SCristina Ciocan 		return -ENOTSUPP;
970c501d0b1SCristina Ciocan 	}
971c501d0b1SCristina Ciocan 
972c501d0b1SCristina Ciocan 	*config = pinconf_to_config_packed(param, arg);
973c501d0b1SCristina Ciocan 
974c501d0b1SCristina Ciocan 	return 0;
975c501d0b1SCristina Ciocan }
976c501d0b1SCristina Ciocan 
977c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
978c501d0b1SCristina Ciocan 			      unsigned int offset,
979c501d0b1SCristina Ciocan 			      unsigned long *configs,
980c501d0b1SCristina Ciocan 			      unsigned int num_configs)
981c501d0b1SCristina Ciocan {
982c501d0b1SCristina Ciocan 	struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
983c501d0b1SCristina Ciocan 	unsigned int param, arg;
984c501d0b1SCristina Ciocan 	void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
985c501d0b1SCristina Ciocan 	void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
98604ff5a09SAndy Shevchenko 	void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
987c501d0b1SCristina Ciocan 	unsigned long flags;
988658b476cSCristina Ciocan 	u32 conf, val, debounce;
989c501d0b1SCristina Ciocan 	int i, ret = 0;
990c501d0b1SCristina Ciocan 
99140ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
992c501d0b1SCristina Ciocan 
993c501d0b1SCristina Ciocan 	conf = readl(conf_reg);
994c501d0b1SCristina Ciocan 	val = readl(val_reg);
995c501d0b1SCristina Ciocan 
996c501d0b1SCristina Ciocan 	for (i = 0; i < num_configs; i++) {
997c501d0b1SCristina Ciocan 		param = pinconf_to_config_param(configs[i]);
998c501d0b1SCristina Ciocan 		arg = pinconf_to_config_argument(configs[i]);
999c501d0b1SCristina Ciocan 
1000c501d0b1SCristina Ciocan 		switch (param) {
1001c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_DISABLE:
1002c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1003c501d0b1SCristina Ciocan 			break;
1004c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_DOWN:
1005c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
1006c501d0b1SCristina Ciocan 			if (arg == 1)
1007c501d0b1SCristina Ciocan 				arg = 2000;
1008c501d0b1SCristina Ciocan 
1009c501d0b1SCristina Ciocan 			/*
1010c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
1011c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
1012c501d0b1SCristina Ciocan 			 */
1013c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
1014c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
1015c501d0b1SCristina Ciocan 				writel(val, val_reg);
1016c501d0b1SCristina Ciocan 				dev_warn(&vg->pdev->dev,
1017c501d0b1SCristina Ciocan 					 "pin %u forcibly set to input mode\n",
1018c501d0b1SCristina Ciocan 					 offset);
1019c501d0b1SCristina Ciocan 			}
1020c501d0b1SCristina Ciocan 
1021c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1022c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_DOWN;
1023c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
1024c501d0b1SCristina Ciocan 
1025c501d0b1SCristina Ciocan 			break;
1026c501d0b1SCristina Ciocan 		case PIN_CONFIG_BIAS_PULL_UP:
1027c501d0b1SCristina Ciocan 			/* Set default strength value in case none is given */
1028c501d0b1SCristina Ciocan 			if (arg == 1)
1029c501d0b1SCristina Ciocan 				arg = 2000;
1030c501d0b1SCristina Ciocan 
1031c501d0b1SCristina Ciocan 			/*
1032c501d0b1SCristina Ciocan 			 * Pull assignment is only applicable in input mode. If
1033c501d0b1SCristina Ciocan 			 * chip is not in input mode, set it and warn about it.
1034c501d0b1SCristina Ciocan 			 */
1035c501d0b1SCristina Ciocan 			if (val & BYT_INPUT_EN) {
1036c501d0b1SCristina Ciocan 				val &= ~BYT_INPUT_EN;
1037c501d0b1SCristina Ciocan 				writel(val, val_reg);
1038c501d0b1SCristina Ciocan 				dev_warn(&vg->pdev->dev,
1039c501d0b1SCristina Ciocan 					 "pin %u forcibly set to input mode\n",
1040c501d0b1SCristina Ciocan 					 offset);
1041c501d0b1SCristina Ciocan 			}
1042c501d0b1SCristina Ciocan 
1043c501d0b1SCristina Ciocan 			conf &= ~BYT_PULL_ASSIGN_MASK;
1044c501d0b1SCristina Ciocan 			conf |= BYT_PULL_ASSIGN_UP;
1045c501d0b1SCristina Ciocan 			ret = byt_set_pull_strength(&conf, arg);
1046c501d0b1SCristina Ciocan 
1047c501d0b1SCristina Ciocan 			break;
1048658b476cSCristina Ciocan 		case PIN_CONFIG_INPUT_DEBOUNCE:
104904ff5a09SAndy Shevchenko 			debounce = readl(db_reg);
105004ff5a09SAndy Shevchenko 			debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
1051658b476cSCristina Ciocan 
1052827e1579SAndy Shevchenko 			if (arg)
1053827e1579SAndy Shevchenko 				conf |= BYT_DEBOUNCE_EN;
1054827e1579SAndy Shevchenko 			else
1055827e1579SAndy Shevchenko 				conf &= ~BYT_DEBOUNCE_EN;
1056827e1579SAndy Shevchenko 
1057658b476cSCristina Ciocan 			switch (arg) {
1058658b476cSCristina Ciocan 			case 375:
105904ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_375US;
1060658b476cSCristina Ciocan 				break;
1061658b476cSCristina Ciocan 			case 750:
106204ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_750US;
1063658b476cSCristina Ciocan 				break;
1064658b476cSCristina Ciocan 			case 1500:
106504ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_1500US;
1066658b476cSCristina Ciocan 				break;
1067658b476cSCristina Ciocan 			case 3000:
106804ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_3MS;
1069658b476cSCristina Ciocan 				break;
1070658b476cSCristina Ciocan 			case 6000:
107104ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_6MS;
1072658b476cSCristina Ciocan 				break;
1073658b476cSCristina Ciocan 			case 12000:
107404ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_12MS;
1075658b476cSCristina Ciocan 				break;
1076658b476cSCristina Ciocan 			case 24000:
107704ff5a09SAndy Shevchenko 				debounce |= BYT_DEBOUNCE_PULSE_24MS;
1078658b476cSCristina Ciocan 				break;
1079658b476cSCristina Ciocan 			default:
1080827e1579SAndy Shevchenko 				if (arg)
1081658b476cSCristina Ciocan 					ret = -EINVAL;
1082827e1579SAndy Shevchenko 				break;
1083658b476cSCristina Ciocan 			}
1084658b476cSCristina Ciocan 
108504ff5a09SAndy Shevchenko 			if (!ret)
108604ff5a09SAndy Shevchenko 				writel(debounce, db_reg);
1087658b476cSCristina Ciocan 			break;
1088c501d0b1SCristina Ciocan 		default:
1089c501d0b1SCristina Ciocan 			ret = -ENOTSUPP;
1090c501d0b1SCristina Ciocan 		}
1091c501d0b1SCristina Ciocan 
1092c501d0b1SCristina Ciocan 		if (ret)
1093c501d0b1SCristina Ciocan 			break;
1094c501d0b1SCristina Ciocan 	}
1095c501d0b1SCristina Ciocan 
1096c501d0b1SCristina Ciocan 	if (!ret)
1097c501d0b1SCristina Ciocan 		writel(conf, conf_reg);
1098c501d0b1SCristina Ciocan 
109940ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1100c501d0b1SCristina Ciocan 
1101c501d0b1SCristina Ciocan 	return ret;
1102c501d0b1SCristina Ciocan }
1103c501d0b1SCristina Ciocan 
1104c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = {
1105c501d0b1SCristina Ciocan 	.is_generic	= true,
1106c501d0b1SCristina Ciocan 	.pin_config_get	= byt_pin_config_get,
1107c501d0b1SCristina Ciocan 	.pin_config_set	= byt_pin_config_set,
1108c501d0b1SCristina Ciocan };
1109c501d0b1SCristina Ciocan 
1110c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = {
1111c501d0b1SCristina Ciocan 	.pctlops	= &byt_pinctrl_ops,
1112c501d0b1SCristina Ciocan 	.pmxops		= &byt_pinmux_ops,
1113c501d0b1SCristina Ciocan 	.confops	= &byt_pinconf_ops,
1114c501d0b1SCristina Ciocan 	.owner		= THIS_MODULE,
1115c501d0b1SCristina Ciocan };
1116c501d0b1SCristina Ciocan 
1117939330d7SAndy Shevchenko static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
11185fae8b86SMika Westerberg {
1119bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(chip);
1120c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
112139ce8150SMika Westerberg 	unsigned long flags;
112239ce8150SMika Westerberg 	u32 val;
112339ce8150SMika Westerberg 
112440ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
112539ce8150SMika Westerberg 	val = readl(reg);
112640ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
112739ce8150SMika Westerberg 
11283bde8771SLinus Walleij 	return !!(val & BYT_LEVEL);
11295fae8b86SMika Westerberg }
11305fae8b86SMika Westerberg 
1131939330d7SAndy Shevchenko static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
11325fae8b86SMika Westerberg {
1133bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(chip);
1134c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
11355fae8b86SMika Westerberg 	unsigned long flags;
11365fae8b86SMika Westerberg 	u32 old_val;
11375fae8b86SMika Westerberg 
113886e3ef81SCristina Ciocan 	if (!reg)
113986e3ef81SCristina Ciocan 		return;
114086e3ef81SCristina Ciocan 
114140ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
11425fae8b86SMika Westerberg 	old_val = readl(reg);
11435fae8b86SMika Westerberg 	if (value)
11445fae8b86SMika Westerberg 		writel(old_val | BYT_LEVEL, reg);
11455fae8b86SMika Westerberg 	else
11465fae8b86SMika Westerberg 		writel(old_val & ~BYT_LEVEL, reg);
114740ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
11485fae8b86SMika Westerberg }
11495fae8b86SMika Westerberg 
115086e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
11515fae8b86SMika Westerberg {
1152bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(chip);
1153c501d0b1SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
11545fae8b86SMika Westerberg 	unsigned long flags;
11555fae8b86SMika Westerberg 	u32 value;
11565fae8b86SMika Westerberg 
115786e3ef81SCristina Ciocan 	if (!reg)
115886e3ef81SCristina Ciocan 		return -EINVAL;
115986e3ef81SCristina Ciocan 
116040ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
116186e3ef81SCristina Ciocan 	value = readl(reg);
116240ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
11635fae8b86SMika Westerberg 
116486e3ef81SCristina Ciocan 	if (!(value & BYT_OUTPUT_EN))
11651c5fb66aSLinus Walleij 		return 0;
116686e3ef81SCristina Ciocan 	if (!(value & BYT_INPUT_EN))
11671c5fb66aSLinus Walleij 		return 1;
116886e3ef81SCristina Ciocan 
116986e3ef81SCristina Ciocan 	return -EINVAL;
11705fae8b86SMika Westerberg }
11715fae8b86SMika Westerberg 
117286e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
11735fae8b86SMika Westerberg {
117486e3ef81SCristina Ciocan 	return pinctrl_gpio_direction_input(chip->base + offset);
117586e3ef81SCristina Ciocan }
11765fae8b86SMika Westerberg 
117786e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip,
117886e3ef81SCristina Ciocan 				     unsigned int offset, int value)
117986e3ef81SCristina Ciocan {
118086e3ef81SCristina Ciocan 	int ret = pinctrl_gpio_direction_output(chip->base + offset);
11815fae8b86SMika Westerberg 
118286e3ef81SCristina Ciocan 	if (ret)
118386e3ef81SCristina Ciocan 		return ret;
118486e3ef81SCristina Ciocan 
118586e3ef81SCristina Ciocan 	byt_gpio_set(chip, offset, value);
11865fae8b86SMika Westerberg 
11875fae8b86SMika Westerberg 	return 0;
11885fae8b86SMika Westerberg }
11895fae8b86SMika Westerberg 
11905fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
11915fae8b86SMika Westerberg {
1192bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(chip);
11935fae8b86SMika Westerberg 	int i;
119486e3ef81SCristina Ciocan 	u32 conf0, val;
11955fae8b86SMika Westerberg 
119686e3ef81SCristina Ciocan 	for (i = 0; i < vg->soc_data->npins; i++) {
119734e65670SAndy Shevchenko 		const struct intel_community *comm;
11985fae8b86SMika Westerberg 		const char *pull_str = NULL;
11995fae8b86SMika Westerberg 		const char *pull = NULL;
120086e3ef81SCristina Ciocan 		void __iomem *reg;
120178e1c896SMika Westerberg 		unsigned long flags;
12025fae8b86SMika Westerberg 		const char *label;
120386e3ef81SCristina Ciocan 		unsigned int pin;
120478e1c896SMika Westerberg 
120540ecab55SHans de Goede 		raw_spin_lock_irqsave(&byt_lock, flags);
120686e3ef81SCristina Ciocan 		pin = vg->soc_data->pins[i].number;
120786e3ef81SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
120886e3ef81SCristina Ciocan 		if (!reg) {
120986e3ef81SCristina Ciocan 			seq_printf(s,
121086e3ef81SCristina Ciocan 				   "Could not retrieve pin %i conf0 reg\n",
121186e3ef81SCristina Ciocan 				   pin);
121240ecab55SHans de Goede 			raw_spin_unlock_irqrestore(&byt_lock, flags);
121386e3ef81SCristina Ciocan 			continue;
121486e3ef81SCristina Ciocan 		}
121586e3ef81SCristina Ciocan 		conf0 = readl(reg);
121686e3ef81SCristina Ciocan 
121786e3ef81SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
121886e3ef81SCristina Ciocan 		if (!reg) {
121986e3ef81SCristina Ciocan 			seq_printf(s,
122086e3ef81SCristina Ciocan 				   "Could not retrieve pin %i val reg\n", pin);
122140ecab55SHans de Goede 			raw_spin_unlock_irqrestore(&byt_lock, flags);
122222bbd21bSDan Carpenter 			continue;
122386e3ef81SCristina Ciocan 		}
122486e3ef81SCristina Ciocan 		val = readl(reg);
122540ecab55SHans de Goede 		raw_spin_unlock_irqrestore(&byt_lock, flags);
12265fae8b86SMika Westerberg 
122786e3ef81SCristina Ciocan 		comm = byt_get_community(vg, pin);
122886e3ef81SCristina Ciocan 		if (!comm) {
122986e3ef81SCristina Ciocan 			seq_printf(s,
123086e3ef81SCristina Ciocan 				   "Could not get community for pin %i\n", pin);
123186e3ef81SCristina Ciocan 			continue;
123286e3ef81SCristina Ciocan 		}
12335fae8b86SMika Westerberg 		label = gpiochip_is_requested(chip, i);
12345fae8b86SMika Westerberg 		if (!label)
12355fae8b86SMika Westerberg 			label = "Unrequested";
12365fae8b86SMika Westerberg 
12375fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_ASSIGN_MASK) {
12385fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_UP:
12395fae8b86SMika Westerberg 			pull = "up";
12405fae8b86SMika Westerberg 			break;
12415fae8b86SMika Westerberg 		case BYT_PULL_ASSIGN_DOWN:
12425fae8b86SMika Westerberg 			pull = "down";
12435fae8b86SMika Westerberg 			break;
12445fae8b86SMika Westerberg 		}
12455fae8b86SMika Westerberg 
12465fae8b86SMika Westerberg 		switch (conf0 & BYT_PULL_STR_MASK) {
12475fae8b86SMika Westerberg 		case BYT_PULL_STR_2K:
12485fae8b86SMika Westerberg 			pull_str = "2k";
12495fae8b86SMika Westerberg 			break;
12505fae8b86SMika Westerberg 		case BYT_PULL_STR_10K:
12515fae8b86SMika Westerberg 			pull_str = "10k";
12525fae8b86SMika Westerberg 			break;
12535fae8b86SMika Westerberg 		case BYT_PULL_STR_20K:
12545fae8b86SMika Westerberg 			pull_str = "20k";
12555fae8b86SMika Westerberg 			break;
12565fae8b86SMika Westerberg 		case BYT_PULL_STR_40K:
12575fae8b86SMika Westerberg 			pull_str = "40k";
12585fae8b86SMika Westerberg 			break;
12595fae8b86SMika Westerberg 		}
12605fae8b86SMika Westerberg 
12615fae8b86SMika Westerberg 		seq_printf(s,
12625fae8b86SMika Westerberg 			   " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
126386e3ef81SCristina Ciocan 			   pin,
12645fae8b86SMika Westerberg 			   label,
12655fae8b86SMika Westerberg 			   val & BYT_INPUT_EN ? "  " : "in",
12665fae8b86SMika Westerberg 			   val & BYT_OUTPUT_EN ? "   " : "out",
12675fae8b86SMika Westerberg 			   val & BYT_LEVEL ? "hi" : "lo",
12683655a1caSAlexander Stein 			   comm->pad_map[i], comm->pad_map[i] * 16,
12695fae8b86SMika Westerberg 			   conf0 & 0x7,
12705fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_NEG ? " fall" : "     ",
12715fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_POS ? " rise" : "     ",
12725fae8b86SMika Westerberg 			   conf0 & BYT_TRIG_LVL ? " level" : "      ");
12735fae8b86SMika Westerberg 
12745fae8b86SMika Westerberg 		if (pull && pull_str)
12755fae8b86SMika Westerberg 			seq_printf(s, " %-4s %-3s", pull, pull_str);
12765fae8b86SMika Westerberg 		else
12775fae8b86SMika Westerberg 			seq_puts(s, "          ");
12785fae8b86SMika Westerberg 
12795fae8b86SMika Westerberg 		if (conf0 & BYT_IODEN)
12805fae8b86SMika Westerberg 			seq_puts(s, " open-drain");
12815fae8b86SMika Westerberg 
12825fae8b86SMika Westerberg 		seq_puts(s, "\n");
12835fae8b86SMika Westerberg 	}
12845fae8b86SMika Westerberg }
12855fae8b86SMika Westerberg 
128686e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = {
128786e3ef81SCristina Ciocan 	.owner			= THIS_MODULE,
128886e3ef81SCristina Ciocan 	.request		= gpiochip_generic_request,
128986e3ef81SCristina Ciocan 	.free			= gpiochip_generic_free,
129086e3ef81SCristina Ciocan 	.get_direction		= byt_gpio_get_direction,
129186e3ef81SCristina Ciocan 	.direction_input	= byt_gpio_direction_input,
129286e3ef81SCristina Ciocan 	.direction_output	= byt_gpio_direction_output,
129386e3ef81SCristina Ciocan 	.get			= byt_gpio_get,
129486e3ef81SCristina Ciocan 	.set			= byt_gpio_set,
129586e3ef81SCristina Ciocan 	.dbg_show		= byt_gpio_dbg_show,
129686e3ef81SCristina Ciocan };
129786e3ef81SCristina Ciocan 
129831e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d)
129931e4329fSMika Westerberg {
130031e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1301bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(gc);
1302939330d7SAndy Shevchenko 	unsigned int offset = irqd_to_hwirq(d);
130331e4329fSMika Westerberg 	void __iomem *reg;
130431e4329fSMika Westerberg 
1305c501d0b1SCristina Ciocan 	reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG);
13069f573b98SCristina Ciocan 	if (!reg)
13079f573b98SCristina Ciocan 		return;
13089f573b98SCristina Ciocan 
130940ecab55SHans de Goede 	raw_spin_lock(&byt_lock);
131031e4329fSMika Westerberg 	writel(BIT(offset % 32), reg);
131140ecab55SHans de Goede 	raw_spin_unlock(&byt_lock);
131231e4329fSMika Westerberg }
131331e4329fSMika Westerberg 
13149f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d)
13159f573b98SCristina Ciocan {
13169f573b98SCristina Ciocan 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
13179f573b98SCristina Ciocan 	struct byt_gpio *vg = gpiochip_get_data(gc);
13189f573b98SCristina Ciocan 
13199f573b98SCristina Ciocan 	byt_gpio_clear_triggering(vg, irqd_to_hwirq(d));
13209f573b98SCristina Ciocan }
13219f573b98SCristina Ciocan 
13225fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d)
13235fae8b86SMika Westerberg {
132431e4329fSMika Westerberg 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
1325bf9a5c96SLinus Walleij 	struct byt_gpio *vg = gpiochip_get_data(gc);
1326939330d7SAndy Shevchenko 	unsigned int offset = irqd_to_hwirq(d);
132731e4329fSMika Westerberg 	unsigned long flags;
132831e4329fSMika Westerberg 	void __iomem *reg;
132931e4329fSMika Westerberg 	u32 value;
133031e4329fSMika Westerberg 
1331c501d0b1SCristina Ciocan 	reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
13329f573b98SCristina Ciocan 	if (!reg)
13339f573b98SCristina Ciocan 		return;
133478e1c896SMika Westerberg 
133540ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
133631e4329fSMika Westerberg 	value = readl(reg);
133731e4329fSMika Westerberg 
133831e4329fSMika Westerberg 	switch (irqd_get_trigger_type(d)) {
133931e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_HIGH:
134031e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
1341399476bdSGustavo A. R. Silva 		/* fall through */
134231e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_RISING:
134331e4329fSMika Westerberg 		value |= BYT_TRIG_POS;
134431e4329fSMika Westerberg 		break;
134531e4329fSMika Westerberg 	case IRQ_TYPE_LEVEL_LOW:
134631e4329fSMika Westerberg 		value |= BYT_TRIG_LVL;
1347399476bdSGustavo A. R. Silva 		/* fall through */
134831e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_FALLING:
134931e4329fSMika Westerberg 		value |= BYT_TRIG_NEG;
135031e4329fSMika Westerberg 		break;
135131e4329fSMika Westerberg 	case IRQ_TYPE_EDGE_BOTH:
135231e4329fSMika Westerberg 		value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
135331e4329fSMika Westerberg 		break;
135431e4329fSMika Westerberg 	}
135531e4329fSMika Westerberg 
135631e4329fSMika Westerberg 	writel(value, reg);
135731e4329fSMika Westerberg 
135840ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
13595fae8b86SMika Westerberg }
13605fae8b86SMika Westerberg 
13619f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type)
13625fae8b86SMika Westerberg {
13639f573b98SCristina Ciocan 	struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
13649f573b98SCristina Ciocan 	u32 offset = irqd_to_hwirq(d);
13659f573b98SCristina Ciocan 	u32 value;
13669f573b98SCristina Ciocan 	unsigned long flags;
13679f573b98SCristina Ciocan 	void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
136831e4329fSMika Westerberg 
13699f573b98SCristina Ciocan 	if (!reg || offset >= vg->chip.ngpio)
13709f573b98SCristina Ciocan 		return -EINVAL;
13719f573b98SCristina Ciocan 
137240ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
13739f573b98SCristina Ciocan 	value = readl(reg);
13749f573b98SCristina Ciocan 
13759f573b98SCristina Ciocan 	WARN(value & BYT_DIRECT_IRQ_EN,
13769f573b98SCristina Ciocan 	     "Bad pad config for io mode, force direct_irq_en bit clearing");
13779f573b98SCristina Ciocan 
13789f573b98SCristina Ciocan 	/* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
13799f573b98SCristina Ciocan 	 * are used to indicate high and low level triggering
13809f573b98SCristina Ciocan 	 */
13819f573b98SCristina Ciocan 	value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
13829f573b98SCristina Ciocan 		   BYT_TRIG_LVL);
13839291c65bSHans de Goede 	/* Enable glitch filtering */
13849291c65bSHans de Goede 	value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK |
13859291c65bSHans de Goede 		 BYT_GLITCH_F_FAST_CLK;
13869f573b98SCristina Ciocan 
13879f573b98SCristina Ciocan 	writel(value, reg);
13889f573b98SCristina Ciocan 
13899f573b98SCristina Ciocan 	if (type & IRQ_TYPE_EDGE_BOTH)
13909f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_edge_irq);
13919f573b98SCristina Ciocan 	else if (type & IRQ_TYPE_LEVEL_MASK)
13929f573b98SCristina Ciocan 		irq_set_handler_locked(d, handle_level_irq);
13939f573b98SCristina Ciocan 
139440ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
13959f573b98SCristina Ciocan 
13969f573b98SCristina Ciocan 	return 0;
13975fae8b86SMika Westerberg }
13985fae8b86SMika Westerberg 
139971e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc)
140071e6ca61SCristina Ciocan {
140171e6ca61SCristina Ciocan 	struct irq_data *data = irq_desc_get_irq_data(desc);
140271e6ca61SCristina Ciocan 	struct byt_gpio *vg = gpiochip_get_data(
140371e6ca61SCristina Ciocan 				irq_desc_get_handler_data(desc));
140471e6ca61SCristina Ciocan 	struct irq_chip *chip = irq_data_get_irq_chip(data);
140571e6ca61SCristina Ciocan 	u32 base, pin;
140671e6ca61SCristina Ciocan 	void __iomem *reg;
140771e6ca61SCristina Ciocan 	unsigned long pending;
140871e6ca61SCristina Ciocan 	unsigned int virq;
140971e6ca61SCristina Ciocan 
141071e6ca61SCristina Ciocan 	/* check from GPIO controller which pin triggered the interrupt */
141171e6ca61SCristina Ciocan 	for (base = 0; base < vg->chip.ngpio; base += 32) {
141271e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
141371e6ca61SCristina Ciocan 
141471e6ca61SCristina Ciocan 		if (!reg) {
141571e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
141671e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve interrupt status register\n",
141771e6ca61SCristina Ciocan 				 base);
141871e6ca61SCristina Ciocan 			continue;
141971e6ca61SCristina Ciocan 		}
142071e6ca61SCristina Ciocan 
142140ecab55SHans de Goede 		raw_spin_lock(&byt_lock);
142271e6ca61SCristina Ciocan 		pending = readl(reg);
142340ecab55SHans de Goede 		raw_spin_unlock(&byt_lock);
142471e6ca61SCristina Ciocan 		for_each_set_bit(pin, &pending, 32) {
1425f0fbe7bcSThierry Reding 			virq = irq_find_mapping(vg->chip.irq.domain, base + pin);
142671e6ca61SCristina Ciocan 			generic_handle_irq(virq);
142771e6ca61SCristina Ciocan 		}
142871e6ca61SCristina Ciocan 	}
142971e6ca61SCristina Ciocan 	chip->irq_eoi(data);
143071e6ca61SCristina Ciocan }
143171e6ca61SCristina Ciocan 
14325fbe5b58SLinus Walleij static void byt_init_irq_valid_mask(struct gpio_chip *chip,
14335fbe5b58SLinus Walleij 				    unsigned long *valid_mask,
14345fbe5b58SLinus Walleij 				    unsigned int ngpios)
14355fbe5b58SLinus Walleij {
1436ca8a958eSAndy Shevchenko 	struct byt_gpio *vg = gpiochip_get_data(chip);
143749c03096SAndy Shevchenko 	struct device *dev = &vg->pdev->dev;
14385fae8b86SMika Westerberg 	void __iomem *reg;
1439e70982b3SAndy Shevchenko 	u32 value;
144095f0972cSMika Westerberg 	int i;
144195f0972cSMika Westerberg 
144295f0972cSMika Westerberg 	/*
144395f0972cSMika Westerberg 	 * Clear interrupt triggers for all pins that are GPIOs and
144495f0972cSMika Westerberg 	 * do not use direct IRQ mode. This will prevent spurious
144595f0972cSMika Westerberg 	 * interrupts from misconfigured pins.
144695f0972cSMika Westerberg 	 */
144771e6ca61SCristina Ciocan 	for (i = 0; i < vg->soc_data->npins; i++) {
144871e6ca61SCristina Ciocan 		unsigned int pin = vg->soc_data->pins[i].number;
144971e6ca61SCristina Ciocan 
145071e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
145171e6ca61SCristina Ciocan 		if (!reg) {
145271e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
145371e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
145471e6ca61SCristina Ciocan 				 i);
145571e6ca61SCristina Ciocan 			continue;
145671e6ca61SCristina Ciocan 		}
145771e6ca61SCristina Ciocan 
145871e6ca61SCristina Ciocan 		value = readl(reg);
145949c03096SAndy Shevchenko 		if (value & BYT_DIRECT_IRQ_EN) {
1460e70982b3SAndy Shevchenko 			clear_bit(i, valid_mask);
146149c03096SAndy Shevchenko 			dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i);
146249c03096SAndy Shevchenko 		} else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
146395f0972cSMika Westerberg 			byt_gpio_clear_triggering(vg, i);
146449c03096SAndy Shevchenko 			dev_dbg(dev, "disabling GPIO %d\n", i);
146595f0972cSMika Westerberg 		}
146695f0972cSMika Westerberg 	}
1467e70982b3SAndy Shevchenko }
1468e70982b3SAndy Shevchenko 
1469e70982b3SAndy Shevchenko static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
1470e70982b3SAndy Shevchenko {
1471e70982b3SAndy Shevchenko 	struct byt_gpio *vg = gpiochip_get_data(chip);
1472e70982b3SAndy Shevchenko 	void __iomem *reg;
1473e70982b3SAndy Shevchenko 	u32 base, value;
14745fae8b86SMika Westerberg 
14755fae8b86SMika Westerberg 	/* clear interrupt status trigger registers */
147671e6ca61SCristina Ciocan 	for (base = 0; base < vg->soc_data->npins; base += 32) {
1477c501d0b1SCristina Ciocan 		reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
147871e6ca61SCristina Ciocan 
147971e6ca61SCristina Ciocan 		if (!reg) {
148071e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
148171e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve irq status reg\n",
148271e6ca61SCristina Ciocan 				 base);
148371e6ca61SCristina Ciocan 			continue;
148471e6ca61SCristina Ciocan 		}
148571e6ca61SCristina Ciocan 
14865fae8b86SMika Westerberg 		writel(0xffffffff, reg);
14875fae8b86SMika Westerberg 		/* make sure trigger bits are cleared, if not then a pin
14885fae8b86SMika Westerberg 		   might be misconfigured in bios */
14895fae8b86SMika Westerberg 		value = readl(reg);
14905fae8b86SMika Westerberg 		if (value)
14915fae8b86SMika Westerberg 			dev_err(&vg->pdev->dev,
1492973232e2SAlexander Stein 				"GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n",
1493973232e2SAlexander Stein 				base / 32, value);
14945fae8b86SMika Westerberg 	}
1495ca8a958eSAndy Shevchenko 
1496ca8a958eSAndy Shevchenko 	return 0;
14975fae8b86SMika Westerberg }
14985fae8b86SMika Westerberg 
1499ed3c1564SAndy Shevchenko static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
1500ed3c1564SAndy Shevchenko {
1501ed3c1564SAndy Shevchenko 	struct byt_gpio *vg = gpiochip_get_data(chip);
1502ed3c1564SAndy Shevchenko 	struct device *dev = &vg->pdev->dev;
1503ed3c1564SAndy Shevchenko 	int ret;
1504ed3c1564SAndy Shevchenko 
1505ed3c1564SAndy Shevchenko 	ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc_data->npins);
1506ed3c1564SAndy Shevchenko 	if (ret)
1507ed3c1564SAndy Shevchenko 		dev_err(dev, "failed to add GPIO pin range\n");
1508ed3c1564SAndy Shevchenko 
1509ed3c1564SAndy Shevchenko 	return ret;
1510ed3c1564SAndy Shevchenko }
1511ed3c1564SAndy Shevchenko 
151271e6ca61SCristina Ciocan static int byt_gpio_probe(struct byt_gpio *vg)
15135fae8b86SMika Westerberg {
15145fae8b86SMika Westerberg 	struct gpio_chip *gc;
151571e6ca61SCristina Ciocan 	struct resource *irq_rc;
15165fae8b86SMika Westerberg 	int ret;
15175fae8b86SMika Westerberg 
151871e6ca61SCristina Ciocan 	/* Set up gpio chip */
151971e6ca61SCristina Ciocan 	vg->chip	= byt_gpio_chip;
15205fae8b86SMika Westerberg 	gc		= &vg->chip;
152171e6ca61SCristina Ciocan 	gc->label	= dev_name(&vg->pdev->dev);
15225fae8b86SMika Westerberg 	gc->base	= -1;
15235fae8b86SMika Westerberg 	gc->can_sleep	= false;
1524ed3c1564SAndy Shevchenko 	gc->add_pin_ranges = byt_gpio_add_pin_ranges;
152571e6ca61SCristina Ciocan 	gc->parent	= &vg->pdev->dev;
152671e6ca61SCristina Ciocan 	gc->ngpio	= vg->soc_data->npins;
15275fae8b86SMika Westerberg 
1528fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
152971e6ca61SCristina Ciocan 	vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio,
1530fcc18debSMika Westerberg 				       sizeof(*vg->saved_context), GFP_KERNEL);
1531d6cb7722SAditya Pakki 	if (!vg->saved_context)
1532d6cb7722SAditya Pakki 		return -ENOMEM;
1533fcc18debSMika Westerberg #endif
15345fae8b86SMika Westerberg 
15355fae8b86SMika Westerberg 	/* set up interrupts  */
153671e6ca61SCristina Ciocan 	irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0);
15375fae8b86SMika Westerberg 	if (irq_rc && irq_rc->start) {
1538ca8a958eSAndy Shevchenko 		struct gpio_irq_chip *girq;
1539ca8a958eSAndy Shevchenko 
1540539d8bdeSAndy Shevchenko 		vg->irqchip.name = "BYT-GPIO",
1541539d8bdeSAndy Shevchenko 		vg->irqchip.irq_ack = byt_irq_ack,
1542539d8bdeSAndy Shevchenko 		vg->irqchip.irq_mask = byt_irq_mask,
1543539d8bdeSAndy Shevchenko 		vg->irqchip.irq_unmask = byt_irq_unmask,
1544539d8bdeSAndy Shevchenko 		vg->irqchip.irq_set_type = byt_irq_type,
1545539d8bdeSAndy Shevchenko 		vg->irqchip.flags = IRQCHIP_SKIP_SET_WAKE,
1546539d8bdeSAndy Shevchenko 
1547ca8a958eSAndy Shevchenko 		girq = &gc->irq;
1548539d8bdeSAndy Shevchenko 		girq->chip = &vg->irqchip;
1549ca8a958eSAndy Shevchenko 		girq->init_hw = byt_gpio_irq_init_hw;
1550ab68b220SAndy Shevchenko 		girq->init_valid_mask = byt_init_irq_valid_mask;
1551ca8a958eSAndy Shevchenko 		girq->parent_handler = byt_gpio_irq_handler;
1552ca8a958eSAndy Shevchenko 		girq->num_parents = 1;
1553ca8a958eSAndy Shevchenko 		girq->parents = devm_kcalloc(&vg->pdev->dev, girq->num_parents,
1554ca8a958eSAndy Shevchenko 					     sizeof(*girq->parents), GFP_KERNEL);
1555ca8a958eSAndy Shevchenko 		if (!girq->parents)
1556ca8a958eSAndy Shevchenko 			return -ENOMEM;
1557ca8a958eSAndy Shevchenko 		girq->parents[0] = (unsigned int)irq_rc->start;
1558ca8a958eSAndy Shevchenko 		girq->default_type = IRQ_TYPE_NONE;
1559ca8a958eSAndy Shevchenko 		girq->handler = handle_bad_irq;
15605fae8b86SMika Westerberg 	}
15615fae8b86SMika Westerberg 
1562ca8a958eSAndy Shevchenko 	ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg);
1563ca8a958eSAndy Shevchenko 	if (ret) {
1564ca8a958eSAndy Shevchenko 		dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n");
1565ca8a958eSAndy Shevchenko 		return ret;
15665fae8b86SMika Westerberg 	}
15675fae8b86SMika Westerberg 
156871e6ca61SCristina Ciocan 	return ret;
156971e6ca61SCristina Ciocan }
157071e6ca61SCristina Ciocan 
157171e6ca61SCristina Ciocan static int byt_set_soc_data(struct byt_gpio *vg,
157234e65670SAndy Shevchenko 			    const struct intel_pinctrl_soc_data *soc_data)
157371e6ca61SCristina Ciocan {
157471e6ca61SCristina Ciocan 	int i;
157571e6ca61SCristina Ciocan 
157671e6ca61SCristina Ciocan 	vg->soc_data = soc_data;
157771e6ca61SCristina Ciocan 	vg->communities_copy = devm_kcalloc(&vg->pdev->dev,
157871e6ca61SCristina Ciocan 					    soc_data->ncommunities,
157971e6ca61SCristina Ciocan 					    sizeof(*vg->communities_copy),
158071e6ca61SCristina Ciocan 					    GFP_KERNEL);
158171e6ca61SCristina Ciocan 	if (!vg->communities_copy)
158271e6ca61SCristina Ciocan 		return -ENOMEM;
158371e6ca61SCristina Ciocan 
158471e6ca61SCristina Ciocan 	for (i = 0; i < soc_data->ncommunities; i++) {
158534e65670SAndy Shevchenko 		struct intel_community *comm = vg->communities_copy + i;
158671e6ca61SCristina Ciocan 
158771e6ca61SCristina Ciocan 		*comm = vg->soc_data->communities[i];
158871e6ca61SCristina Ciocan 
158934e65670SAndy Shevchenko 		comm->pad_regs = devm_platform_ioremap_resource(vg->pdev, 0);
159034e65670SAndy Shevchenko 		if (IS_ERR(comm->pad_regs))
159134e65670SAndy Shevchenko 			return PTR_ERR(comm->pad_regs);
159271e6ca61SCristina Ciocan 	}
159371e6ca61SCristina Ciocan 
159471e6ca61SCristina Ciocan 	return 0;
159571e6ca61SCristina Ciocan }
159671e6ca61SCristina Ciocan 
159771e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = {
159871e6ca61SCristina Ciocan 	{ "INT33B2", (kernel_ulong_t)byt_soc_data },
159971e6ca61SCristina Ciocan 	{ "INT33FC", (kernel_ulong_t)byt_soc_data },
160071e6ca61SCristina Ciocan 	{ }
160171e6ca61SCristina Ciocan };
160271e6ca61SCristina Ciocan 
160371e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev)
160471e6ca61SCristina Ciocan {
160534e65670SAndy Shevchenko 	const struct intel_pinctrl_soc_data *soc_data = NULL;
160634e65670SAndy Shevchenko 	const struct intel_pinctrl_soc_data **soc_table;
160771e6ca61SCristina Ciocan 	struct acpi_device *acpi_dev;
160871e6ca61SCristina Ciocan 	struct byt_gpio *vg;
160971e6ca61SCristina Ciocan 	int i, ret;
161071e6ca61SCristina Ciocan 
161171e6ca61SCristina Ciocan 	acpi_dev = ACPI_COMPANION(&pdev->dev);
161271e6ca61SCristina Ciocan 	if (!acpi_dev)
161371e6ca61SCristina Ciocan 		return -ENODEV;
161471e6ca61SCristina Ciocan 
161534e65670SAndy Shevchenko 	soc_table = (const struct intel_pinctrl_soc_data **)device_get_match_data(&pdev->dev);
161671e6ca61SCristina Ciocan 
161771e6ca61SCristina Ciocan 	for (i = 0; soc_table[i]; i++) {
161871e6ca61SCristina Ciocan 		if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) {
161971e6ca61SCristina Ciocan 			soc_data = soc_table[i];
162071e6ca61SCristina Ciocan 			break;
162171e6ca61SCristina Ciocan 		}
162271e6ca61SCristina Ciocan 	}
162371e6ca61SCristina Ciocan 
162471e6ca61SCristina Ciocan 	if (!soc_data)
162571e6ca61SCristina Ciocan 		return -ENODEV;
162671e6ca61SCristina Ciocan 
162771e6ca61SCristina Ciocan 	vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL);
162871e6ca61SCristina Ciocan 	if (!vg)
162971e6ca61SCristina Ciocan 		return -ENOMEM;
163071e6ca61SCristina Ciocan 
163171e6ca61SCristina Ciocan 	vg->pdev = pdev;
163271e6ca61SCristina Ciocan 	ret = byt_set_soc_data(vg, soc_data);
163371e6ca61SCristina Ciocan 	if (ret) {
163471e6ca61SCristina Ciocan 		dev_err(&pdev->dev, "failed to set soc data\n");
163571e6ca61SCristina Ciocan 		return ret;
163671e6ca61SCristina Ciocan 	}
163771e6ca61SCristina Ciocan 
163871e6ca61SCristina Ciocan 	vg->pctl_desc		= byt_pinctrl_desc;
163971e6ca61SCristina Ciocan 	vg->pctl_desc.name	= dev_name(&pdev->dev);
164071e6ca61SCristina Ciocan 	vg->pctl_desc.pins	= vg->soc_data->pins;
164171e6ca61SCristina Ciocan 	vg->pctl_desc.npins	= vg->soc_data->npins;
164271e6ca61SCristina Ciocan 
16430612413fSAndy Shevchenko 	vg->pctl_dev = devm_pinctrl_register(&pdev->dev, &vg->pctl_desc, vg);
164471e6ca61SCristina Ciocan 	if (IS_ERR(vg->pctl_dev)) {
164571e6ca61SCristina Ciocan 		dev_err(&pdev->dev, "failed to register pinctrl driver\n");
164671e6ca61SCristina Ciocan 		return PTR_ERR(vg->pctl_dev);
164771e6ca61SCristina Ciocan 	}
164871e6ca61SCristina Ciocan 
164971e6ca61SCristina Ciocan 	ret = byt_gpio_probe(vg);
16500612413fSAndy Shevchenko 	if (ret)
165171e6ca61SCristina Ciocan 		return ret;
165271e6ca61SCristina Ciocan 
165371e6ca61SCristina Ciocan 	platform_set_drvdata(pdev, vg);
165471e6ca61SCristina Ciocan 	pm_runtime_enable(&pdev->dev);
165571e6ca61SCristina Ciocan 
165671e6ca61SCristina Ciocan 	return 0;
165771e6ca61SCristina Ciocan }
165871e6ca61SCristina Ciocan 
1659fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
1660fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev)
1661fcc18debSMika Westerberg {
1662d481de47SWolfram Sang 	struct byt_gpio *vg = dev_get_drvdata(dev);
166340ecab55SHans de Goede 	unsigned long flags;
1664fcc18debSMika Westerberg 	int i;
1665fcc18debSMika Westerberg 
166640ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
166740ecab55SHans de Goede 
166871e6ca61SCristina Ciocan 	for (i = 0; i < vg->soc_data->npins; i++) {
1669fcc18debSMika Westerberg 		void __iomem *reg;
1670fcc18debSMika Westerberg 		u32 value;
167171e6ca61SCristina Ciocan 		unsigned int pin = vg->soc_data->pins[i].number;
1672fcc18debSMika Westerberg 
167371e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
167471e6ca61SCristina Ciocan 		if (!reg) {
167571e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
167671e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
167771e6ca61SCristina Ciocan 				 i);
167871e6ca61SCristina Ciocan 			continue;
167971e6ca61SCristina Ciocan 		}
1680fcc18debSMika Westerberg 		value = readl(reg) & BYT_CONF0_RESTORE_MASK;
1681fcc18debSMika Westerberg 		vg->saved_context[i].conf0 = value;
1682fcc18debSMika Westerberg 
168371e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1684fcc18debSMika Westerberg 		value = readl(reg) & BYT_VAL_RESTORE_MASK;
1685fcc18debSMika Westerberg 		vg->saved_context[i].val = value;
1686fcc18debSMika Westerberg 	}
1687fcc18debSMika Westerberg 
168840ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1689fcc18debSMika Westerberg 	return 0;
1690fcc18debSMika Westerberg }
1691fcc18debSMika Westerberg 
1692fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev)
1693fcc18debSMika Westerberg {
1694d481de47SWolfram Sang 	struct byt_gpio *vg = dev_get_drvdata(dev);
169540ecab55SHans de Goede 	unsigned long flags;
1696fcc18debSMika Westerberg 	int i;
1697fcc18debSMika Westerberg 
169840ecab55SHans de Goede 	raw_spin_lock_irqsave(&byt_lock, flags);
169940ecab55SHans de Goede 
170071e6ca61SCristina Ciocan 	for (i = 0; i < vg->soc_data->npins; i++) {
1701fcc18debSMika Westerberg 		void __iomem *reg;
1702fcc18debSMika Westerberg 		u32 value;
170371e6ca61SCristina Ciocan 		unsigned int pin = vg->soc_data->pins[i].number;
1704fcc18debSMika Westerberg 
170571e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
170671e6ca61SCristina Ciocan 		if (!reg) {
170771e6ca61SCristina Ciocan 			dev_warn(&vg->pdev->dev,
170871e6ca61SCristina Ciocan 				 "Pin %i: could not retrieve conf0 register\n",
170971e6ca61SCristina Ciocan 				 i);
171071e6ca61SCristina Ciocan 			continue;
171171e6ca61SCristina Ciocan 		}
1712fcc18debSMika Westerberg 		value = readl(reg);
1713fcc18debSMika Westerberg 		if ((value & BYT_CONF0_RESTORE_MASK) !=
1714fcc18debSMika Westerberg 		     vg->saved_context[i].conf0) {
1715fcc18debSMika Westerberg 			value &= ~BYT_CONF0_RESTORE_MASK;
1716fcc18debSMika Westerberg 			value |= vg->saved_context[i].conf0;
1717fcc18debSMika Westerberg 			writel(value, reg);
1718fcc18debSMika Westerberg 			dev_info(dev, "restored pin %d conf0 %#08x", i, value);
1719fcc18debSMika Westerberg 		}
1720fcc18debSMika Westerberg 
172171e6ca61SCristina Ciocan 		reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
1722fcc18debSMika Westerberg 		value = readl(reg);
1723fcc18debSMika Westerberg 		if ((value & BYT_VAL_RESTORE_MASK) !=
1724fcc18debSMika Westerberg 		     vg->saved_context[i].val) {
1725fcc18debSMika Westerberg 			u32 v;
1726fcc18debSMika Westerberg 
1727fcc18debSMika Westerberg 			v = value & ~BYT_VAL_RESTORE_MASK;
1728fcc18debSMika Westerberg 			v |= vg->saved_context[i].val;
1729fcc18debSMika Westerberg 			if (v != value) {
1730fcc18debSMika Westerberg 				writel(v, reg);
1731fcc18debSMika Westerberg 				dev_dbg(dev, "restored pin %d val %#08x\n",
1732fcc18debSMika Westerberg 					i, v);
1733fcc18debSMika Westerberg 			}
1734fcc18debSMika Westerberg 		}
1735fcc18debSMika Westerberg 	}
1736fcc18debSMika Westerberg 
173740ecab55SHans de Goede 	raw_spin_unlock_irqrestore(&byt_lock, flags);
1738fcc18debSMika Westerberg 	return 0;
1739fcc18debSMika Westerberg }
1740fcc18debSMika Westerberg #endif
1741fcc18debSMika Westerberg 
1742ec879f12SMika Westerberg #ifdef CONFIG_PM
17435fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev)
17445fae8b86SMika Westerberg {
17455fae8b86SMika Westerberg 	return 0;
17465fae8b86SMika Westerberg }
17475fae8b86SMika Westerberg 
17485fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev)
17495fae8b86SMika Westerberg {
17505fae8b86SMika Westerberg 	return 0;
17515fae8b86SMika Westerberg }
1752ec879f12SMika Westerberg #endif
17535fae8b86SMika Westerberg 
17545fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = {
1755fcc18debSMika Westerberg 	SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
1756fcc18debSMika Westerberg 	SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume,
1757fcc18debSMika Westerberg 			   NULL)
17585fae8b86SMika Westerberg };
17595fae8b86SMika Westerberg 
17605fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = {
176171e6ca61SCristina Ciocan 	.probe          = byt_pinctrl_probe,
17625fae8b86SMika Westerberg 	.driver         = {
17635fae8b86SMika Westerberg 		.name			= "byt_gpio",
17645fae8b86SMika Westerberg 		.pm			= &byt_gpio_pm_ops,
1765360943a8SPaul Gortmaker 		.suppress_bind_attrs	= true,
1766360943a8SPaul Gortmaker 
17675fae8b86SMika Westerberg 		.acpi_match_table = ACPI_PTR(byt_gpio_acpi_match),
17685fae8b86SMika Westerberg 	},
17695fae8b86SMika Westerberg };
17705fae8b86SMika Westerberg 
17715fae8b86SMika Westerberg static int __init byt_gpio_init(void)
17725fae8b86SMika Westerberg {
17735fae8b86SMika Westerberg 	return platform_driver_register(&byt_gpio_driver);
17745fae8b86SMika Westerberg }
17755fae8b86SMika Westerberg subsys_initcall(byt_gpio_init);
1776