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>
164d01688fSRaag Jadav #include <linux/module.h>
17e0da3842SAndy Shevchenko #include <linux/types.h>
18e0da3842SAndy Shevchenko #include <linux/platform_device.h>
195fae8b86SMika Westerberg #include <linux/pm_runtime.h>
2061db6c9dSAndy Shevchenko #include <linux/property.h>
21e0da3842SAndy Shevchenko #include <linux/seq_file.h>
22c518d31bSAndy Shevchenko #include <linux/string_helpers.h>
2361db6c9dSAndy Shevchenko
245fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h>
25c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h>
26c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h>
27c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h>
285fae8b86SMika Westerberg
294f010b93SAndy Shevchenko #include "pinctrl-intel.h"
304f010b93SAndy Shevchenko
315fae8b86SMika Westerberg /* memory mapped register offsets */
325fae8b86SMika Westerberg #define BYT_CONF0_REG 0x000
335fae8b86SMika Westerberg #define BYT_CONF1_REG 0x004
345fae8b86SMika Westerberg #define BYT_VAL_REG 0x008
355fae8b86SMika Westerberg #define BYT_DFT_REG 0x00c
365fae8b86SMika Westerberg #define BYT_INT_STAT_REG 0x800
37689e0088SHans de Goede #define BYT_DIRECT_IRQ_REG 0x980
38658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG 0x9d0
395fae8b86SMika Westerberg
405fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */
415fae8b86SMika Westerberg #define BYT_IODEN BIT(31)
425fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN BIT(27)
43eb0a2daaSAndy Shevchenko #define BYT_TRIG_MASK GENMASK(26, 24)
445fae8b86SMika Westerberg #define BYT_TRIG_NEG BIT(26)
455fae8b86SMika Westerberg #define BYT_TRIG_POS BIT(25)
465fae8b86SMika Westerberg #define BYT_TRIG_LVL BIT(24)
47658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN BIT(20)
489291c65bSHans de Goede #define BYT_GLITCH_FILTER_EN BIT(19)
499291c65bSHans de Goede #define BYT_GLITCH_F_SLOW_CLK BIT(17)
509291c65bSHans de Goede #define BYT_GLITCH_F_FAST_CLK BIT(16)
515fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT 9
52eb0a2daaSAndy Shevchenko #define BYT_PULL_STR_MASK GENMASK(10, 9)
535fae8b86SMika Westerberg #define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT)
545fae8b86SMika Westerberg #define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT)
555fae8b86SMika Westerberg #define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT)
565fae8b86SMika Westerberg #define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT)
57eb0a2daaSAndy Shevchenko #define BYT_PULL_ASSIGN_MASK GENMASK(8, 7)
589d712086SAndy Shevchenko #define BYT_PULL_ASSIGN_DOWN BIT(8)
599d712086SAndy Shevchenko #define BYT_PULL_ASSIGN_UP BIT(7)
60eb0a2daaSAndy Shevchenko #define BYT_PIN_MUX GENMASK(2, 0)
615fae8b86SMika Westerberg
625fae8b86SMika Westerberg /* BYT_VAL_REG register bits */
63eb0a2daaSAndy Shevchenko #define BYT_DIR_MASK GENMASK(2, 1)
645fae8b86SMika Westerberg #define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/
655fae8b86SMika Westerberg #define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/
665fae8b86SMika Westerberg #define BYT_LEVEL BIT(0)
675fae8b86SMika Westerberg
68eb0a2daaSAndy Shevchenko #define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX)
69fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL)
70fcc18debSMika Westerberg
71658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */
72eb0a2daaSAndy Shevchenko #define BYT_DEBOUNCE_PULSE_MASK GENMASK(2, 0)
73658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US 1
74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US 2
75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US 3
76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS 4
77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS 5
78658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS 6
79658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS 7
80658b476cSCristina Ciocan
815fae8b86SMika Westerberg #define BYT_NGPIO_SCORE 102
825fae8b86SMika Westerberg #define BYT_NGPIO_NCORE 28
835fae8b86SMika Westerberg #define BYT_NGPIO_SUS 44
845fae8b86SMika Westerberg
855fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID "1"
865fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID "2"
875fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID "3"
885fae8b86SMika Westerberg
89c501d0b1SCristina Ciocan /*
90c501d0b1SCristina Ciocan * This is the function value most pins have for GPIO muxing. If the value
91c501d0b1SCristina Ciocan * differs from the default one, it must be explicitly mentioned. Otherwise, the
92c501d0b1SCristina Ciocan * pin control implementation will set the muxing value to default GPIO if it
93c501d0b1SCristina Ciocan * does not find a match for the requested function.
94c501d0b1SCristina Ciocan */
95c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX 0
96a705f9c1SAndy Shevchenko #define BYT_ALTER_GPIO_MUX 1
97c501d0b1SCristina Ciocan
985d33e0ebSAndy Shevchenko struct intel_pad_context {
99c8f5c4c7SCristina Ciocan u32 conf0;
100c8f5c4c7SCristina Ciocan u32 val;
101c8f5c4c7SCristina Ciocan };
1025fae8b86SMika Westerberg
103c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map) \
104c8f5c4c7SCristina Ciocan { \
105c8f5c4c7SCristina Ciocan .pin_base = (p), \
106c8f5c4c7SCristina Ciocan .npins = (n), \
107c8f5c4c7SCristina Ciocan .pad_map = (map),\
108c8f5c4c7SCristina Ciocan }
109c8f5c4c7SCristina Ciocan
110c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */
111c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = {
112c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "SATA_GP0"),
113c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "SATA_GP1"),
114c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "SATA_LED#"),
115c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "PCIE_CLKREQ0"),
116c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "PCIE_CLKREQ1"),
117c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "PCIE_CLKREQ2"),
118c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "PCIE_CLKREQ3"),
119c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "SD3_WP"),
120c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "HDA_RST"),
121c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "HDA_SYNC"),
122c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "HDA_CLK"),
123c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "HDA_SDO"),
124c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "HDA_SDI0"),
125c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "HDA_SDI1"),
126c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_S0_SC14"),
127c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_S0_SC15"),
128c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "MMC1_CLK"),
129c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "MMC1_D0"),
130c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "MMC1_D1"),
131c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "MMC1_D2"),
132c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "MMC1_D3"),
133c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "MMC1_D4"),
134c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "MMC1_D5"),
135c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "MMC1_D6"),
136c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "MMC1_D7"),
137c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "MMC1_CMD"),
138c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "MMC1_RST"),
139c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "SD2_CLK"),
140c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "SD2_D0"),
141c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "SD2_D1"),
142c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "SD2_D2"),
143c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "SD2_D3_CD"),
144c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "SD2_CMD"),
145c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "SD3_CLK"),
146c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "SD3_D0"),
147c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "SD3_D1"),
148c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "SD3_D2"),
149c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "SD3_D3"),
150c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "SD3_CD"),
151c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "SD3_CMD"),
152c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "SD3_1P8EN"),
153c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "SD3_PWREN#"),
154c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "ILB_LPC_AD0"),
155c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "ILB_LPC_AD1"),
156c8f5c4c7SCristina Ciocan PINCTRL_PIN(44, "ILB_LPC_AD2"),
157c8f5c4c7SCristina Ciocan PINCTRL_PIN(45, "ILB_LPC_AD3"),
158c8f5c4c7SCristina Ciocan PINCTRL_PIN(46, "ILB_LPC_FRAME"),
159c8f5c4c7SCristina Ciocan PINCTRL_PIN(47, "ILB_LPC_CLK0"),
160c8f5c4c7SCristina Ciocan PINCTRL_PIN(48, "ILB_LPC_CLK1"),
161c8f5c4c7SCristina Ciocan PINCTRL_PIN(49, "ILB_LPC_CLKRUN"),
162c8f5c4c7SCristina Ciocan PINCTRL_PIN(50, "ILB_LPC_SERIRQ"),
163c8f5c4c7SCristina Ciocan PINCTRL_PIN(51, "PCU_SMB_DATA"),
164c8f5c4c7SCristina Ciocan PINCTRL_PIN(52, "PCU_SMB_CLK"),
165c8f5c4c7SCristina Ciocan PINCTRL_PIN(53, "PCU_SMB_ALERT"),
166c8f5c4c7SCristina Ciocan PINCTRL_PIN(54, "ILB_8254_SPKR"),
167c8f5c4c7SCristina Ciocan PINCTRL_PIN(55, "GPIO_S0_SC55"),
168c8f5c4c7SCristina Ciocan PINCTRL_PIN(56, "GPIO_S0_SC56"),
169c8f5c4c7SCristina Ciocan PINCTRL_PIN(57, "GPIO_S0_SC57"),
170c8f5c4c7SCristina Ciocan PINCTRL_PIN(58, "GPIO_S0_SC58"),
171c8f5c4c7SCristina Ciocan PINCTRL_PIN(59, "GPIO_S0_SC59"),
172c8f5c4c7SCristina Ciocan PINCTRL_PIN(60, "GPIO_S0_SC60"),
173c8f5c4c7SCristina Ciocan PINCTRL_PIN(61, "GPIO_S0_SC61"),
174c8f5c4c7SCristina Ciocan PINCTRL_PIN(62, "LPE_I2S2_CLK"),
175c8f5c4c7SCristina Ciocan PINCTRL_PIN(63, "LPE_I2S2_FRM"),
176c8f5c4c7SCristina Ciocan PINCTRL_PIN(64, "LPE_I2S2_DATAIN"),
177c8f5c4c7SCristina Ciocan PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"),
178c8f5c4c7SCristina Ciocan PINCTRL_PIN(66, "SIO_SPI_CS"),
179c8f5c4c7SCristina Ciocan PINCTRL_PIN(67, "SIO_SPI_MISO"),
180c8f5c4c7SCristina Ciocan PINCTRL_PIN(68, "SIO_SPI_MOSI"),
181c8f5c4c7SCristina Ciocan PINCTRL_PIN(69, "SIO_SPI_CLK"),
182c8f5c4c7SCristina Ciocan PINCTRL_PIN(70, "SIO_UART1_RXD"),
183c8f5c4c7SCristina Ciocan PINCTRL_PIN(71, "SIO_UART1_TXD"),
184c8f5c4c7SCristina Ciocan PINCTRL_PIN(72, "SIO_UART1_RTS"),
185c8f5c4c7SCristina Ciocan PINCTRL_PIN(73, "SIO_UART1_CTS"),
186c8f5c4c7SCristina Ciocan PINCTRL_PIN(74, "SIO_UART2_RXD"),
187c8f5c4c7SCristina Ciocan PINCTRL_PIN(75, "SIO_UART2_TXD"),
188c8f5c4c7SCristina Ciocan PINCTRL_PIN(76, "SIO_UART2_RTS"),
189c8f5c4c7SCristina Ciocan PINCTRL_PIN(77, "SIO_UART2_CTS"),
190c8f5c4c7SCristina Ciocan PINCTRL_PIN(78, "SIO_I2C0_DATA"),
191c8f5c4c7SCristina Ciocan PINCTRL_PIN(79, "SIO_I2C0_CLK"),
192c8f5c4c7SCristina Ciocan PINCTRL_PIN(80, "SIO_I2C1_DATA"),
193c8f5c4c7SCristina Ciocan PINCTRL_PIN(81, "SIO_I2C1_CLK"),
194c8f5c4c7SCristina Ciocan PINCTRL_PIN(82, "SIO_I2C2_DATA"),
195c8f5c4c7SCristina Ciocan PINCTRL_PIN(83, "SIO_I2C2_CLK"),
196c8f5c4c7SCristina Ciocan PINCTRL_PIN(84, "SIO_I2C3_DATA"),
197c8f5c4c7SCristina Ciocan PINCTRL_PIN(85, "SIO_I2C3_CLK"),
198c8f5c4c7SCristina Ciocan PINCTRL_PIN(86, "SIO_I2C4_DATA"),
199c8f5c4c7SCristina Ciocan PINCTRL_PIN(87, "SIO_I2C4_CLK"),
200c8f5c4c7SCristina Ciocan PINCTRL_PIN(88, "SIO_I2C5_DATA"),
201c8f5c4c7SCristina Ciocan PINCTRL_PIN(89, "SIO_I2C5_CLK"),
202c8f5c4c7SCristina Ciocan PINCTRL_PIN(90, "SIO_I2C6_DATA"),
203c8f5c4c7SCristina Ciocan PINCTRL_PIN(91, "SIO_I2C6_CLK"),
204c8f5c4c7SCristina Ciocan PINCTRL_PIN(92, "GPIO_S0_SC92"),
205c8f5c4c7SCristina Ciocan PINCTRL_PIN(93, "GPIO_S0_SC93"),
206c8f5c4c7SCristina Ciocan PINCTRL_PIN(94, "SIO_PWM0"),
207c8f5c4c7SCristina Ciocan PINCTRL_PIN(95, "SIO_PWM1"),
208c8f5c4c7SCristina Ciocan PINCTRL_PIN(96, "PMC_PLT_CLK0"),
209c8f5c4c7SCristina Ciocan PINCTRL_PIN(97, "PMC_PLT_CLK1"),
210c8f5c4c7SCristina Ciocan PINCTRL_PIN(98, "PMC_PLT_CLK2"),
211c8f5c4c7SCristina Ciocan PINCTRL_PIN(99, "PMC_PLT_CLK3"),
212c8f5c4c7SCristina Ciocan PINCTRL_PIN(100, "PMC_PLT_CLK4"),
213c8f5c4c7SCristina Ciocan PINCTRL_PIN(101, "PMC_PLT_CLK5"),
214c8f5c4c7SCristina Ciocan };
2155fae8b86SMika Westerberg
216c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = {
217c8f5c4c7SCristina Ciocan 85, 89, 93, 96, 99, 102, 98, 101, 34, 37,
218c8f5c4c7SCristina Ciocan 36, 38, 39, 35, 40, 84, 62, 61, 64, 59,
219c8f5c4c7SCristina Ciocan 54, 56, 60, 55, 63, 57, 51, 50, 53, 47,
220c8f5c4c7SCristina Ciocan 52, 49, 48, 43, 46, 41, 45, 42, 58, 44,
221c8f5c4c7SCristina Ciocan 95, 105, 70, 68, 67, 66, 69, 71, 65, 72,
222c8f5c4c7SCristina Ciocan 86, 90, 88, 92, 103, 77, 79, 83, 78, 81,
223c8f5c4c7SCristina Ciocan 80, 82, 13, 12, 15, 14, 17, 18, 19, 16,
224c8f5c4c7SCristina Ciocan 2, 1, 0, 4, 6, 7, 9, 8, 33, 32,
225c8f5c4c7SCristina Ciocan 31, 30, 29, 27, 25, 28, 26, 23, 21, 20,
226c8f5c4c7SCristina Ciocan 24, 22, 5, 3, 10, 11, 106, 87, 91, 104,
227c8f5c4c7SCristina Ciocan 97, 100,
2285fae8b86SMika Westerberg };
2295fae8b86SMika Westerberg
230c8f5c4c7SCristina Ciocan /* SCORE groups */
231c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 };
232c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 };
233c8f5c4c7SCristina Ciocan
234c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 };
235c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 };
236c8f5c4c7SCristina Ciocan
237c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 };
238c8f5c4c7SCristina Ciocan
239c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 };
240c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 };
241c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 };
242c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 };
243c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 };
244c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 };
245c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 };
246c8f5c4c7SCristina Ciocan
247c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 };
248c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 };
249c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 };
250c8f5c4c7SCristina Ciocan
251c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = {
252c8f5c4c7SCristina Ciocan 7, 33, 34, 35, 36, 37, 38, 39, 40, 41,
253c8f5c4c7SCristina Ciocan };
2544f010b93SAndy Shevchenko static const unsigned int byt_score_sdcard_mux_values[] = {
255c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
256c8f5c4c7SCristina Ciocan };
257c8f5c4c7SCristina Ciocan
258c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 };
259c8f5c4c7SCristina Ciocan
260c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = {
261c8f5c4c7SCristina Ciocan 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
262c8f5c4c7SCristina Ciocan };
263c8f5c4c7SCristina Ciocan
264c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = {
265c8f5c4c7SCristina Ciocan 42, 43, 44, 45, 46, 47, 48, 49, 50,
266c8f5c4c7SCristina Ciocan };
267c8f5c4c7SCristina Ciocan
268c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 };
269c8f5c4c7SCristina Ciocan
270c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 };
271c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 };
272c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 };
273b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 };
274b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 };
275b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
276c8f5c4c7SCristina Ciocan
277c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
278c8f5c4c7SCristina Ciocan
2794f010b93SAndy Shevchenko static const struct intel_pingroup byt_score_groups[] = {
280fc8cbe3aSHans de Goede PIN_GROUP_GPIO("uart1_grp", byt_score_uart1_pins, 1),
281fc8cbe3aSHans de Goede PIN_GROUP_GPIO("uart2_grp", byt_score_uart2_pins, 1),
282fc8cbe3aSHans de Goede PIN_GROUP_GPIO("pwm0_grp", byt_score_pwm0_pins, 1),
283fc8cbe3aSHans de Goede PIN_GROUP_GPIO("pwm1_grp", byt_score_pwm1_pins, 1),
284fc8cbe3aSHans de Goede PIN_GROUP_GPIO("ssp2_grp", byt_score_ssp2_pins, 1),
285fc8cbe3aSHans de Goede PIN_GROUP_GPIO("sio_spi_grp", byt_score_sio_spi_pins, 1),
286fc8cbe3aSHans de Goede PIN_GROUP_GPIO("i2c5_grp", byt_score_i2c5_pins, 1),
287fc8cbe3aSHans de Goede PIN_GROUP_GPIO("i2c6_grp", byt_score_i2c6_pins, 1),
288fc8cbe3aSHans de Goede PIN_GROUP_GPIO("i2c4_grp", byt_score_i2c4_pins, 1),
289fc8cbe3aSHans de Goede PIN_GROUP_GPIO("i2c3_grp", byt_score_i2c3_pins, 1),
290fc8cbe3aSHans de Goede PIN_GROUP_GPIO("i2c2_grp", byt_score_i2c2_pins, 1),
291fc8cbe3aSHans de Goede PIN_GROUP_GPIO("i2c1_grp", byt_score_i2c1_pins, 1),
292fc8cbe3aSHans de Goede PIN_GROUP_GPIO("i2c0_grp", byt_score_i2c0_pins, 1),
293fc8cbe3aSHans de Goede PIN_GROUP_GPIO("ssp0_grp", byt_score_ssp0_pins, 1),
294fc8cbe3aSHans de Goede PIN_GROUP_GPIO("ssp1_grp", byt_score_ssp1_pins, 1),
295fc8cbe3aSHans de Goede PIN_GROUP_GPIO("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
296fc8cbe3aSHans de Goede PIN_GROUP_GPIO("sdio_grp", byt_score_sdio_pins, 1),
297fc8cbe3aSHans de Goede PIN_GROUP_GPIO("emmc_grp", byt_score_emmc_pins, 1),
298fc8cbe3aSHans de Goede PIN_GROUP_GPIO("lpc_grp", byt_score_ilb_lpc_pins, 1),
299fc8cbe3aSHans de Goede PIN_GROUP_GPIO("sata_grp", byt_score_sata_pins, 1),
300fc8cbe3aSHans de Goede PIN_GROUP_GPIO("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
301fc8cbe3aSHans de Goede PIN_GROUP_GPIO("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
302fc8cbe3aSHans de Goede PIN_GROUP_GPIO("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
303fc8cbe3aSHans de Goede PIN_GROUP_GPIO("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
304fc8cbe3aSHans de Goede PIN_GROUP_GPIO("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
305fc8cbe3aSHans de Goede PIN_GROUP_GPIO("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
306fc8cbe3aSHans de Goede PIN_GROUP_GPIO("smbus_grp", byt_score_smbus_pins, 1),
307c8f5c4c7SCristina Ciocan };
308c8f5c4c7SCristina Ciocan
309c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = {
310c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp",
311c8f5c4c7SCristina Ciocan };
312c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = {
313c8f5c4c7SCristina Ciocan "pwm0_grp", "pwm1_grp",
314c8f5c4c7SCristina Ciocan };
315c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = {
316c8f5c4c7SCristina Ciocan "ssp0_grp", "ssp1_grp", "ssp2_grp",
317c8f5c4c7SCristina Ciocan };
318c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" };
319c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = {
320c8f5c4c7SCristina Ciocan "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp",
321c8f5c4c7SCristina Ciocan "i2c6_grp",
322c8f5c4c7SCristina Ciocan };
323c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" };
324c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" };
325c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" };
326c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" };
327c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" };
328c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = {
329c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
330c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp",
331c8f5c4c7SCristina Ciocan };
332c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
333c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = {
334fc8cbe3aSHans de Goede "uart1_grp_gpio", "uart2_grp_gpio", "pwm0_grp_gpio",
335fc8cbe3aSHans de Goede "pwm1_grp_gpio", "ssp0_grp_gpio", "ssp1_grp_gpio", "ssp2_grp_gpio",
336fc8cbe3aSHans de Goede "sio_spi_grp_gpio", "i2c0_grp_gpio", "i2c1_grp_gpio", "i2c2_grp_gpio",
337fc8cbe3aSHans de Goede "i2c3_grp_gpio", "i2c4_grp_gpio", "i2c5_grp_gpio", "i2c6_grp_gpio",
338fc8cbe3aSHans de Goede "sdcard_grp_gpio", "sdio_grp_gpio", "emmc_grp_gpio", "lpc_grp_gpio",
339fc8cbe3aSHans de Goede "sata_grp_gpio", "plt_clk0_grp_gpio", "plt_clk1_grp_gpio",
340fc8cbe3aSHans de Goede "plt_clk2_grp_gpio", "plt_clk3_grp_gpio", "plt_clk4_grp_gpio",
341fc8cbe3aSHans de Goede "plt_clk5_grp_gpio", "smbus_grp_gpio",
342c8f5c4c7SCristina Ciocan };
343c8f5c4c7SCristina Ciocan
3444f010b93SAndy Shevchenko static const struct intel_function byt_score_functions[] = {
345c8f5c4c7SCristina Ciocan FUNCTION("uart", byt_score_uart_groups),
346c8f5c4c7SCristina Ciocan FUNCTION("pwm", byt_score_pwm_groups),
347c8f5c4c7SCristina Ciocan FUNCTION("ssp", byt_score_ssp_groups),
348c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_score_spi_groups),
349c8f5c4c7SCristina Ciocan FUNCTION("i2c", byt_score_i2c_groups),
350c8f5c4c7SCristina Ciocan FUNCTION("sdcard", byt_score_sdcard_groups),
351c8f5c4c7SCristina Ciocan FUNCTION("sdio", byt_score_sdio_groups),
352c8f5c4c7SCristina Ciocan FUNCTION("emmc", byt_score_emmc_groups),
353c8f5c4c7SCristina Ciocan FUNCTION("lpc", byt_score_lpc_groups),
354c8f5c4c7SCristina Ciocan FUNCTION("sata", byt_score_sata_groups),
355c8f5c4c7SCristina Ciocan FUNCTION("plt_clk", byt_score_plt_clk_groups),
356c8f5c4c7SCristina Ciocan FUNCTION("smbus", byt_score_smbus_groups),
357c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_score_gpio_groups),
358c8f5c4c7SCristina Ciocan };
359c8f5c4c7SCristina Ciocan
36034e65670SAndy Shevchenko static const struct intel_community byt_score_communities[] = {
361c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map),
362c8f5c4c7SCristina Ciocan };
363c8f5c4c7SCristina Ciocan
36434e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_score_soc_data = {
365c8f5c4c7SCristina Ciocan .uid = BYT_SCORE_ACPI_UID,
366c8f5c4c7SCristina Ciocan .pins = byt_score_pins,
367c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_score_pins),
368c8f5c4c7SCristina Ciocan .groups = byt_score_groups,
369c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_score_groups),
370c8f5c4c7SCristina Ciocan .functions = byt_score_functions,
371c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_score_functions),
372c8f5c4c7SCristina Ciocan .communities = byt_score_communities,
373c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_score_communities),
374c8f5c4c7SCristina Ciocan };
375c8f5c4c7SCristina Ciocan
376c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */
377c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = {
378c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_S50"),
379c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_S51"),
380c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_S52"),
381c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_S53"),
382c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_S54"),
383c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_S55"),
384c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_S56"),
385c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_S57"),
386c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_S58"),
387c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_S59"),
388c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_S510"),
389c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "PMC_SUSPWRDNACK"),
390c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "PMC_SUSCLK0"),
391c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_S513"),
392c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "USB_ULPI_RST"),
393c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"),
394c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "PMC_PWRBTN"),
395c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_S517"),
396c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "PMC_SUS_STAT"),
397c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "USB_OC0"),
398c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "USB_OC1"),
399c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "PCU_SPI_CS1"),
400c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_S522"),
401c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_S523"),
402c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_S524"),
403c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_S525"),
404c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_S526"),
405c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_S527"),
406c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "GPIO_S528"),
407c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "GPIO_S529"),
408c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "GPIO_S530"),
409c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "USB_ULPI_CLK"),
410c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "USB_ULPI_DATA0"),
411c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "USB_ULPI_DATA1"),
412c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "USB_ULPI_DATA2"),
413c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "USB_ULPI_DATA3"),
414c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "USB_ULPI_DATA4"),
415c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "USB_ULPI_DATA5"),
416c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "USB_ULPI_DATA6"),
417c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "USB_ULPI_DATA7"),
418c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "USB_ULPI_DIR"),
419c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "USB_ULPI_NXT"),
420c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "USB_ULPI_STP"),
421c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "USB_ULPI_REFCLK"),
422c8f5c4c7SCristina Ciocan };
423c8f5c4c7SCristina Ciocan
424c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = {
425c8f5c4c7SCristina Ciocan 29, 33, 30, 31, 32, 34, 36, 35, 38, 37,
426c8f5c4c7SCristina Ciocan 18, 7, 11, 20, 17, 1, 8, 10, 19, 12,
427c8f5c4c7SCristina Ciocan 0, 2, 23, 39, 28, 27, 22, 21, 24, 25,
428c8f5c4c7SCristina Ciocan 26, 51, 56, 54, 49, 55, 48, 57, 50, 58,
429c8f5c4c7SCristina Ciocan 52, 53, 59, 40,
430c8f5c4c7SCristina Ciocan };
431c8f5c4c7SCristina Ciocan
432c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 };
4334f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 };
4344f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 };
435c8f5c4c7SCristina Ciocan
436c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = {
437c8f5c4c7SCristina Ciocan 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
438c8f5c4c7SCristina Ciocan };
4394f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_mode_values[] = {
440c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
441c8f5c4c7SCristina Ciocan };
4424f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = {
4434f010b93SAndy Shevchenko 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
444c8f5c4c7SCristina Ciocan };
445c8f5c4c7SCristina Ciocan
446c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 };
4474f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 };
4484f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 };
449c8f5c4c7SCristina Ciocan
4502f46d7f7SHans de Goede static const unsigned int byt_sus_pmu_clk1_pins[] = { 5 };
4512f46d7f7SHans de Goede static const unsigned int byt_sus_pmu_clk2_pins[] = { 6 };
4522f46d7f7SHans de Goede
4534f010b93SAndy Shevchenko static const struct intel_pingroup byt_sus_groups[] = {
4544f010b93SAndy Shevchenko PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values),
4554f010b93SAndy Shevchenko PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values),
4564f010b93SAndy Shevchenko PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values),
4574f010b93SAndy Shevchenko PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values),
4584f010b93SAndy Shevchenko PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values),
4594f010b93SAndy Shevchenko PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values),
460fc8cbe3aSHans de Goede PIN_GROUP_GPIO("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
461fc8cbe3aSHans de Goede PIN_GROUP_GPIO("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
462c8f5c4c7SCristina Ciocan };
463c8f5c4c7SCristina Ciocan
464c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = {
465c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp",
466c8f5c4c7SCristina Ciocan };
467c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" };
4682f46d7f7SHans de Goede static const char * const byt_sus_pmu_clk_groups[] = {
4692f46d7f7SHans de Goede "pmu_clk1_grp", "pmu_clk2_grp",
4702f46d7f7SHans de Goede };
471c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = {
4724f010b93SAndy Shevchenko "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio",
473fc8cbe3aSHans de Goede "pmu_clk1_grp_gpio", "pmu_clk2_grp_gpio",
474c8f5c4c7SCristina Ciocan };
475c8f5c4c7SCristina Ciocan
4764f010b93SAndy Shevchenko static const struct intel_function byt_sus_functions[] = {
477c8f5c4c7SCristina Ciocan FUNCTION("usb", byt_sus_usb_groups),
478c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_sus_spi_groups),
479c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_sus_gpio_groups),
4802f46d7f7SHans de Goede FUNCTION("pmu_clk", byt_sus_pmu_clk_groups),
481c8f5c4c7SCristina Ciocan };
482c8f5c4c7SCristina Ciocan
48334e65670SAndy Shevchenko static const struct intel_community byt_sus_communities[] = {
484c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map),
485c8f5c4c7SCristina Ciocan };
486c8f5c4c7SCristina Ciocan
48734e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_sus_soc_data = {
488c8f5c4c7SCristina Ciocan .uid = BYT_SUS_ACPI_UID,
489c8f5c4c7SCristina Ciocan .pins = byt_sus_pins,
490c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_sus_pins),
491c8f5c4c7SCristina Ciocan .groups = byt_sus_groups,
492c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_sus_groups),
493c8f5c4c7SCristina Ciocan .functions = byt_sus_functions,
494c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_sus_functions),
495c8f5c4c7SCristina Ciocan .communities = byt_sus_communities,
496c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_sus_communities),
497c8f5c4c7SCristina Ciocan };
498c8f5c4c7SCristina Ciocan
499c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = {
500b30b736aSAndy Shevchenko PINCTRL_PIN(0, "HV_DDI0_HPD"),
501b30b736aSAndy Shevchenko PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"),
502b30b736aSAndy Shevchenko PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"),
503b30b736aSAndy Shevchenko PINCTRL_PIN(3, "PANEL0_VDDEN"),
504b30b736aSAndy Shevchenko PINCTRL_PIN(4, "PANEL0_BKLTEN"),
505b30b736aSAndy Shevchenko PINCTRL_PIN(5, "PANEL0_BKLTCTL"),
506b30b736aSAndy Shevchenko PINCTRL_PIN(6, "HV_DDI1_HPD"),
507b30b736aSAndy Shevchenko PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"),
508b30b736aSAndy Shevchenko PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"),
509b30b736aSAndy Shevchenko PINCTRL_PIN(9, "PANEL1_VDDEN"),
510b30b736aSAndy Shevchenko PINCTRL_PIN(10, "PANEL1_BKLTEN"),
511b30b736aSAndy Shevchenko PINCTRL_PIN(11, "PANEL1_BKLTCTL"),
512b30b736aSAndy Shevchenko PINCTRL_PIN(12, "GP_INTD_DSI_TE1"),
513b30b736aSAndy Shevchenko PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"),
514b30b736aSAndy Shevchenko PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"),
515b30b736aSAndy Shevchenko PINCTRL_PIN(15, "GP_CAMERASB00"),
516b30b736aSAndy Shevchenko PINCTRL_PIN(16, "GP_CAMERASB01"),
517b30b736aSAndy Shevchenko PINCTRL_PIN(17, "GP_CAMERASB02"),
518b30b736aSAndy Shevchenko PINCTRL_PIN(18, "GP_CAMERASB03"),
519b30b736aSAndy Shevchenko PINCTRL_PIN(19, "GP_CAMERASB04"),
520b30b736aSAndy Shevchenko PINCTRL_PIN(20, "GP_CAMERASB05"),
521b30b736aSAndy Shevchenko PINCTRL_PIN(21, "GP_CAMERASB06"),
522b30b736aSAndy Shevchenko PINCTRL_PIN(22, "GP_CAMERASB07"),
523b30b736aSAndy Shevchenko PINCTRL_PIN(23, "GP_CAMERASB08"),
524b30b736aSAndy Shevchenko PINCTRL_PIN(24, "GP_CAMERASB09"),
525b30b736aSAndy Shevchenko PINCTRL_PIN(25, "GP_CAMERASB10"),
526b30b736aSAndy Shevchenko PINCTRL_PIN(26, "GP_CAMERASB11"),
527b30b736aSAndy Shevchenko PINCTRL_PIN(27, "GP_INTD_DSI_TE2"),
528c8f5c4c7SCristina Ciocan };
529c8f5c4c7SCristina Ciocan
530939330d7SAndy Shevchenko static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = {
531c8f5c4c7SCristina Ciocan 19, 18, 17, 20, 21, 22, 24, 25, 23, 16,
532c8f5c4c7SCristina Ciocan 14, 15, 12, 26, 27, 1, 4, 8, 11, 0,
533c8f5c4c7SCristina Ciocan 3, 6, 10, 13, 2, 5, 9, 7,
534c8f5c4c7SCristina Ciocan };
535c8f5c4c7SCristina Ciocan
53634e65670SAndy Shevchenko static const struct intel_community byt_ncore_communities[] = {
537c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map),
538c8f5c4c7SCristina Ciocan };
539c8f5c4c7SCristina Ciocan
54034e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_ncore_soc_data = {
541c8f5c4c7SCristina Ciocan .uid = BYT_NCORE_ACPI_UID,
542c8f5c4c7SCristina Ciocan .pins = byt_ncore_pins,
543c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_ncore_pins),
544c8f5c4c7SCristina Ciocan .communities = byt_ncore_communities,
545c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_ncore_communities),
546c8f5c4c7SCristina Ciocan };
547c8f5c4c7SCristina Ciocan
54834e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data *byt_soc_data[] = {
549c8f5c4c7SCristina Ciocan &byt_score_soc_data,
550c8f5c4c7SCristina Ciocan &byt_sus_soc_data,
551c8f5c4c7SCristina Ciocan &byt_ncore_soc_data,
552166d6e2aSAndy Shevchenko NULL
553c8f5c4c7SCristina Ciocan };
554c8f5c4c7SCristina Ciocan
55540ecab55SHans de Goede static DEFINE_RAW_SPINLOCK(byt_lock);
55640ecab55SHans de Goede
byt_gpio_reg(struct intel_pinctrl * vg,unsigned int offset,int reg)5575d33e0ebSAndy Shevchenko static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset,
5585fae8b86SMika Westerberg int reg)
5595fae8b86SMika Westerberg {
5604d01688fSRaag Jadav struct intel_community *comm = intel_get_community(vg, offset);
5611b89970dSAndy Shevchenko u32 reg_offset;
5625fae8b86SMika Westerberg
563c501d0b1SCristina Ciocan if (!comm)
564c501d0b1SCristina Ciocan return NULL;
565c501d0b1SCristina Ciocan
566c501d0b1SCristina Ciocan offset -= comm->pin_base;
5671b89970dSAndy Shevchenko switch (reg) {
5681b89970dSAndy Shevchenko case BYT_INT_STAT_REG:
5695fae8b86SMika Westerberg reg_offset = (offset / 32) * 4;
5701b89970dSAndy Shevchenko break;
5711b89970dSAndy Shevchenko case BYT_DEBOUNCE_REG:
5721b89970dSAndy Shevchenko reg_offset = 0;
5731b89970dSAndy Shevchenko break;
5741b89970dSAndy Shevchenko default:
575c501d0b1SCristina Ciocan reg_offset = comm->pad_map[offset] * 16;
5761b89970dSAndy Shevchenko break;
5771b89970dSAndy Shevchenko }
5785fae8b86SMika Westerberg
57934e65670SAndy Shevchenko return comm->pad_regs + reg_offset + reg;
5805fae8b86SMika Westerberg }
5815fae8b86SMika Westerberg
582c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = {
5834d01688fSRaag Jadav .get_groups_count = intel_get_groups_count,
5844d01688fSRaag Jadav .get_group_name = intel_get_group_name,
5854d01688fSRaag Jadav .get_group_pins = intel_get_group_pins,
586c501d0b1SCristina Ciocan };
587c501d0b1SCristina Ciocan
byt_set_group_simple_mux(struct intel_pinctrl * vg,const struct intel_pingroup group,unsigned int func)5885d33e0ebSAndy Shevchenko static void byt_set_group_simple_mux(struct intel_pinctrl *vg,
5894f010b93SAndy Shevchenko const struct intel_pingroup group,
5904f010b93SAndy Shevchenko unsigned int func)
591c501d0b1SCristina Ciocan {
592c501d0b1SCristina Ciocan unsigned long flags;
593c501d0b1SCristina Ciocan int i;
594c501d0b1SCristina Ciocan
59540ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
596c501d0b1SCristina Ciocan
597770f53d4SAndy Shevchenko for (i = 0; i < group.grp.npins; i++) {
598c501d0b1SCristina Ciocan void __iomem *padcfg0;
599c501d0b1SCristina Ciocan u32 value;
600c501d0b1SCristina Ciocan
601770f53d4SAndy Shevchenko padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG);
602c501d0b1SCristina Ciocan if (!padcfg0) {
603b9e18434SAndy Shevchenko dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n",
604770f53d4SAndy Shevchenko group.grp.name, i);
605c501d0b1SCristina Ciocan continue;
606c501d0b1SCristina Ciocan }
607c501d0b1SCristina Ciocan
608c501d0b1SCristina Ciocan value = readl(padcfg0);
609c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX;
610c501d0b1SCristina Ciocan value |= func;
611c501d0b1SCristina Ciocan writel(value, padcfg0);
612c501d0b1SCristina Ciocan }
613c501d0b1SCristina Ciocan
61440ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
615c501d0b1SCristina Ciocan }
616c501d0b1SCristina Ciocan
byt_set_group_mixed_mux(struct intel_pinctrl * vg,const struct intel_pingroup group,const unsigned int * func)6175d33e0ebSAndy Shevchenko static void byt_set_group_mixed_mux(struct intel_pinctrl *vg,
6184f010b93SAndy Shevchenko const struct intel_pingroup group,
6194f010b93SAndy Shevchenko const unsigned int *func)
620c501d0b1SCristina Ciocan {
621c501d0b1SCristina Ciocan unsigned long flags;
622c501d0b1SCristina Ciocan int i;
623c501d0b1SCristina Ciocan
62440ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
625c501d0b1SCristina Ciocan
626770f53d4SAndy Shevchenko for (i = 0; i < group.grp.npins; i++) {
627c501d0b1SCristina Ciocan void __iomem *padcfg0;
628c501d0b1SCristina Ciocan u32 value;
629c501d0b1SCristina Ciocan
630770f53d4SAndy Shevchenko padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG);
631c501d0b1SCristina Ciocan if (!padcfg0) {
632b9e18434SAndy Shevchenko dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n",
633770f53d4SAndy Shevchenko group.grp.name, i);
634c501d0b1SCristina Ciocan continue;
635c501d0b1SCristina Ciocan }
636c501d0b1SCristina Ciocan
637c501d0b1SCristina Ciocan value = readl(padcfg0);
638c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX;
639c501d0b1SCristina Ciocan value |= func[i];
640c501d0b1SCristina Ciocan writel(value, padcfg0);
641c501d0b1SCristina Ciocan }
642c501d0b1SCristina Ciocan
64340ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
644c501d0b1SCristina Ciocan }
645c501d0b1SCristina Ciocan
byt_set_mux(struct pinctrl_dev * pctldev,unsigned int func_selector,unsigned int group_selector)646c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
647c501d0b1SCristina Ciocan unsigned int group_selector)
648c501d0b1SCristina Ciocan {
6495d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev);
6505d33e0ebSAndy Shevchenko const struct intel_function func = vg->soc->functions[func_selector];
6515d33e0ebSAndy Shevchenko const struct intel_pingroup group = vg->soc->groups[group_selector];
652c501d0b1SCristina Ciocan
6534f010b93SAndy Shevchenko if (group.modes)
6544f010b93SAndy Shevchenko byt_set_group_mixed_mux(vg, group, group.modes);
655988ac1a4SAndy Shevchenko else if (!strcmp(func.func.name, "gpio"))
656c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX);
657c501d0b1SCristina Ciocan else
6584f010b93SAndy Shevchenko byt_set_group_simple_mux(vg, group, group.mode);
659c501d0b1SCristina Ciocan
660c501d0b1SCristina Ciocan return 0;
661c501d0b1SCristina Ciocan }
662c501d0b1SCristina Ciocan
byt_get_gpio_mux(struct intel_pinctrl * vg,unsigned int offset)6635d33e0ebSAndy Shevchenko static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset)
664c501d0b1SCristina Ciocan {
665c501d0b1SCristina Ciocan /* SCORE pin 92-93 */
6665d33e0ebSAndy Shevchenko if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) &&
667c501d0b1SCristina Ciocan offset >= 92 && offset <= 93)
668a705f9c1SAndy Shevchenko return BYT_ALTER_GPIO_MUX;
669c501d0b1SCristina Ciocan
670c501d0b1SCristina Ciocan /* SUS pin 11-21 */
6715d33e0ebSAndy Shevchenko if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) &&
672c501d0b1SCristina Ciocan offset >= 11 && offset <= 21)
673a705f9c1SAndy Shevchenko return BYT_ALTER_GPIO_MUX;
674c501d0b1SCristina Ciocan
675a705f9c1SAndy Shevchenko return BYT_DEFAULT_GPIO_MUX;
676c501d0b1SCristina Ciocan }
677c501d0b1SCristina Ciocan
byt_gpio_clear_triggering(struct intel_pinctrl * vg,unsigned int offset)6785d33e0ebSAndy Shevchenko static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset)
679c501d0b1SCristina Ciocan {
680c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
68195f0972cSMika Westerberg unsigned long flags;
68295f0972cSMika Westerberg u32 value;
68395f0972cSMika Westerberg
68440ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
68595f0972cSMika Westerberg value = readl(reg);
686a2368059SHans de Goede
687a2368059SHans de Goede /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */
688605ba256SRaag Jadav if (!(value & BYT_DIRECT_IRQ_EN))
68995f0972cSMika Westerberg value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL);
690a2368059SHans de Goede
69195f0972cSMika Westerberg writel(value, reg);
69240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
69395f0972cSMika Westerberg }
69495f0972cSMika Westerberg
byt_gpio_request_enable(struct pinctrl_dev * pctl_dev,struct pinctrl_gpio_range * range,unsigned int offset)695c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev,
696c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range,
697c501d0b1SCristina Ciocan unsigned int offset)
6985fae8b86SMika Westerberg {
6995d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
700c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
701f8323b6bSMika Westerberg u32 value, gpio_mux;
70239ce8150SMika Westerberg unsigned long flags;
70339ce8150SMika Westerberg
70440ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
7055fae8b86SMika Westerberg
7065fae8b86SMika Westerberg /*
7075fae8b86SMika Westerberg * In most cases, func pin mux 000 means GPIO function.
7085fae8b86SMika Westerberg * But, some pins may have func pin mux 001 represents
709f8323b6bSMika Westerberg * GPIO function.
710f8323b6bSMika Westerberg *
711f8323b6bSMika Westerberg * Because there are devices out there where some pins were not
712f8323b6bSMika Westerberg * configured correctly we allow changing the mux value from
713f8323b6bSMika Westerberg * request (but print out warning about that).
7145fae8b86SMika Westerberg */
7155fae8b86SMika Westerberg value = readl(reg) & BYT_PIN_MUX;
716f8323b6bSMika Westerberg gpio_mux = byt_get_gpio_mux(vg, offset);
717b5894d12SHans de Goede if (gpio_mux != value) {
718f8323b6bSMika Westerberg value = readl(reg) & ~BYT_PIN_MUX;
719f8323b6bSMika Westerberg value |= gpio_mux;
720f8323b6bSMika Westerberg writel(value, reg);
721f8323b6bSMika Westerberg
722b9e18434SAndy Shevchenko dev_warn(vg->dev, FW_BUG "Pin %i: forcibly re-configured as GPIO\n", offset);
7235fae8b86SMika Westerberg }
7245fae8b86SMika Westerberg
72540ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
72639ce8150SMika Westerberg
727990ec243SAndy Shevchenko pm_runtime_get(vg->dev);
7285fae8b86SMika Westerberg
7295fae8b86SMika Westerberg return 0;
7305fae8b86SMika Westerberg }
7315fae8b86SMika Westerberg
byt_gpio_disable_free(struct pinctrl_dev * pctl_dev,struct pinctrl_gpio_range * range,unsigned int offset)732c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
733c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range,
734c501d0b1SCristina Ciocan unsigned int offset)
735c501d0b1SCristina Ciocan {
7365d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
737c501d0b1SCristina Ciocan
738c501d0b1SCristina Ciocan byt_gpio_clear_triggering(vg, offset);
739990ec243SAndy Shevchenko pm_runtime_put(vg->dev);
740c501d0b1SCristina Ciocan }
741c501d0b1SCristina Ciocan
byt_gpio_direct_irq_check(struct intel_pinctrl * vg,unsigned int offset)742156abe29SHans de Goede static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg,
743156abe29SHans de Goede unsigned int offset)
744156abe29SHans de Goede {
745156abe29SHans de Goede void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
746156abe29SHans de Goede
747156abe29SHans de Goede /*
748156abe29SHans de Goede * Before making any direction modifications, do a check if gpio is set
749156abe29SHans de Goede * for direct IRQ. On Bay Trail, setting GPIO to output does not make
750156abe29SHans de Goede * sense, so let's at least inform the caller before they shoot
751156abe29SHans de Goede * themselves in the foot.
752156abe29SHans de Goede */
753156abe29SHans de Goede if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
754b9e18434SAndy Shevchenko dev_info_once(vg->dev,
755b9e18434SAndy Shevchenko "Potential Error: Pin %i: forcibly set GPIO with DIRECT_IRQ_EN to output\n",
756b9e18434SAndy Shevchenko offset);
757156abe29SHans de Goede }
758156abe29SHans de Goede
byt_gpio_set_direction(struct pinctrl_dev * pctl_dev,struct pinctrl_gpio_range * range,unsigned int offset,bool input)759c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
760c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range,
761c501d0b1SCristina Ciocan unsigned int offset,
762c501d0b1SCristina Ciocan bool input)
763c501d0b1SCristina Ciocan {
7645d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
765c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
766c501d0b1SCristina Ciocan unsigned long flags;
767c501d0b1SCristina Ciocan u32 value;
768c501d0b1SCristina Ciocan
76940ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
770c501d0b1SCristina Ciocan
771c501d0b1SCristina Ciocan value = readl(val_reg);
772c501d0b1SCristina Ciocan value &= ~BYT_DIR_MASK;
773c501d0b1SCristina Ciocan if (input)
774c501d0b1SCristina Ciocan value |= BYT_OUTPUT_EN;
775156abe29SHans de Goede else
776156abe29SHans de Goede byt_gpio_direct_irq_check(vg, offset);
777e2b74419SHans de Goede
778c501d0b1SCristina Ciocan writel(value, val_reg);
779c501d0b1SCristina Ciocan
78040ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
781c501d0b1SCristina Ciocan
782c501d0b1SCristina Ciocan return 0;
783c501d0b1SCristina Ciocan }
784c501d0b1SCristina Ciocan
785c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = {
7864d01688fSRaag Jadav .get_functions_count = intel_get_functions_count,
7874d01688fSRaag Jadav .get_function_name = intel_get_function_name,
7884d01688fSRaag Jadav .get_function_groups = intel_get_function_groups,
789c501d0b1SCristina Ciocan .set_mux = byt_set_mux,
790c501d0b1SCristina Ciocan .gpio_request_enable = byt_gpio_request_enable,
791c501d0b1SCristina Ciocan .gpio_disable_free = byt_gpio_disable_free,
792c501d0b1SCristina Ciocan .gpio_set_direction = byt_gpio_set_direction,
793c501d0b1SCristina Ciocan };
794c501d0b1SCristina Ciocan
byt_get_pull_strength(u32 reg,u16 * strength)795c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength)
796c501d0b1SCristina Ciocan {
797c501d0b1SCristina Ciocan switch (reg & BYT_PULL_STR_MASK) {
798c501d0b1SCristina Ciocan case BYT_PULL_STR_2K:
799c501d0b1SCristina Ciocan *strength = 2000;
800c501d0b1SCristina Ciocan break;
801c501d0b1SCristina Ciocan case BYT_PULL_STR_10K:
802c501d0b1SCristina Ciocan *strength = 10000;
803c501d0b1SCristina Ciocan break;
804c501d0b1SCristina Ciocan case BYT_PULL_STR_20K:
805c501d0b1SCristina Ciocan *strength = 20000;
806c501d0b1SCristina Ciocan break;
807c501d0b1SCristina Ciocan case BYT_PULL_STR_40K:
808c501d0b1SCristina Ciocan *strength = 40000;
809c501d0b1SCristina Ciocan break;
810c501d0b1SCristina Ciocan }
811c501d0b1SCristina Ciocan }
812c501d0b1SCristina Ciocan
byt_set_pull_strength(u32 * reg,u16 strength)813c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength)
814c501d0b1SCristina Ciocan {
815c501d0b1SCristina Ciocan *reg &= ~BYT_PULL_STR_MASK;
816c501d0b1SCristina Ciocan
817c501d0b1SCristina Ciocan switch (strength) {
818c501d0b1SCristina Ciocan case 2000:
819c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_2K;
820c501d0b1SCristina Ciocan break;
821c501d0b1SCristina Ciocan case 10000:
822c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_10K;
823c501d0b1SCristina Ciocan break;
824c501d0b1SCristina Ciocan case 20000:
825c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_20K;
826c501d0b1SCristina Ciocan break;
827c501d0b1SCristina Ciocan case 40000:
828c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_40K;
829c501d0b1SCristina Ciocan break;
830c501d0b1SCristina Ciocan default:
831c501d0b1SCristina Ciocan return -EINVAL;
832c501d0b1SCristina Ciocan }
833c501d0b1SCristina Ciocan
834c501d0b1SCristina Ciocan return 0;
835c501d0b1SCristina Ciocan }
836c501d0b1SCristina Ciocan
byt_pin_config_get(struct pinctrl_dev * pctl_dev,unsigned int offset,unsigned long * config)837c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
838c501d0b1SCristina Ciocan unsigned long *config)
839c501d0b1SCristina Ciocan {
8405d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
841c501d0b1SCristina Ciocan enum pin_config_param param = pinconf_to_config_param(*config);
842c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
843c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
84404ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
845c501d0b1SCristina Ciocan unsigned long flags;
846658b476cSCristina Ciocan u32 conf, pull, val, debounce;
847c501d0b1SCristina Ciocan u16 arg = 0;
848c501d0b1SCristina Ciocan
84940ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
850c501d0b1SCristina Ciocan conf = readl(conf_reg);
851c501d0b1SCristina Ciocan pull = conf & BYT_PULL_ASSIGN_MASK;
852c501d0b1SCristina Ciocan val = readl(val_reg);
85340ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
854c501d0b1SCristina Ciocan
855c501d0b1SCristina Ciocan switch (param) {
856c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE:
857c501d0b1SCristina Ciocan if (pull)
858c501d0b1SCristina Ciocan return -EINVAL;
859c501d0b1SCristina Ciocan break;
860c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN:
861c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */
862c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN)
863c501d0b1SCristina Ciocan return -EINVAL;
864c501d0b1SCristina Ciocan
865c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg);
866c501d0b1SCristina Ciocan
867c501d0b1SCristina Ciocan break;
868c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP:
869c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */
870c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP)
871c501d0b1SCristina Ciocan return -EINVAL;
872c501d0b1SCristina Ciocan
873c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg);
874c501d0b1SCristina Ciocan
875c501d0b1SCristina Ciocan break;
876658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE:
877658b476cSCristina Ciocan if (!(conf & BYT_DEBOUNCE_EN))
878658b476cSCristina Ciocan return -EINVAL;
879658b476cSCristina Ciocan
88040ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
88104ff5a09SAndy Shevchenko debounce = readl(db_reg);
88240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
883658b476cSCristina Ciocan
884658b476cSCristina Ciocan switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
885658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_375US:
886658b476cSCristina Ciocan arg = 375;
887658b476cSCristina Ciocan break;
888658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_750US:
889658b476cSCristina Ciocan arg = 750;
890658b476cSCristina Ciocan break;
891658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_1500US:
892658b476cSCristina Ciocan arg = 1500;
893658b476cSCristina Ciocan break;
894658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_3MS:
895658b476cSCristina Ciocan arg = 3000;
896658b476cSCristina Ciocan break;
897658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_6MS:
898658b476cSCristina Ciocan arg = 6000;
899658b476cSCristina Ciocan break;
900658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_12MS:
901658b476cSCristina Ciocan arg = 12000;
902658b476cSCristina Ciocan break;
903658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_24MS:
904658b476cSCristina Ciocan arg = 24000;
905658b476cSCristina Ciocan break;
906658b476cSCristina Ciocan default:
907658b476cSCristina Ciocan return -EINVAL;
908658b476cSCristina Ciocan }
909658b476cSCristina Ciocan
910658b476cSCristina Ciocan break;
911c501d0b1SCristina Ciocan default:
912c501d0b1SCristina Ciocan return -ENOTSUPP;
913c501d0b1SCristina Ciocan }
914c501d0b1SCristina Ciocan
915c501d0b1SCristina Ciocan *config = pinconf_to_config_packed(param, arg);
916c501d0b1SCristina Ciocan
917c501d0b1SCristina Ciocan return 0;
918c501d0b1SCristina Ciocan }
919c501d0b1SCristina Ciocan
byt_pin_config_set(struct pinctrl_dev * pctl_dev,unsigned int offset,unsigned long * configs,unsigned int num_configs)920c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
921c501d0b1SCristina Ciocan unsigned int offset,
922c501d0b1SCristina Ciocan unsigned long *configs,
923c501d0b1SCristina Ciocan unsigned int num_configs)
924c501d0b1SCristina Ciocan {
9255d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev);
926c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
927c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
92804ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
9294cfff5b7SRaag Jadav u32 conf, val, db_pulse, debounce;
9306eef17a3SAndy Shevchenko enum pin_config_param param;
931c501d0b1SCristina Ciocan unsigned long flags;
932c501d0b1SCristina Ciocan int i, ret = 0;
9336eef17a3SAndy Shevchenko u32 arg;
934c501d0b1SCristina Ciocan
93540ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
936c501d0b1SCristina Ciocan
937c501d0b1SCristina Ciocan conf = readl(conf_reg);
938c501d0b1SCristina Ciocan val = readl(val_reg);
939c501d0b1SCristina Ciocan
940c501d0b1SCristina Ciocan for (i = 0; i < num_configs; i++) {
941c501d0b1SCristina Ciocan param = pinconf_to_config_param(configs[i]);
942c501d0b1SCristina Ciocan arg = pinconf_to_config_argument(configs[i]);
943c501d0b1SCristina Ciocan
944c501d0b1SCristina Ciocan switch (param) {
945c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE:
946c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK;
947c501d0b1SCristina Ciocan break;
948c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN:
949c501d0b1SCristina Ciocan /* Set default strength value in case none is given */
950c501d0b1SCristina Ciocan if (arg == 1)
951c501d0b1SCristina Ciocan arg = 2000;
952c501d0b1SCristina Ciocan
953c501d0b1SCristina Ciocan /*
954c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If
955c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it.
956c501d0b1SCristina Ciocan */
957c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) {
958c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN;
959c501d0b1SCristina Ciocan writel(val, val_reg);
960b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
961c501d0b1SCristina Ciocan }
962c501d0b1SCristina Ciocan
963c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK;
964c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_DOWN;
965c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg);
966c501d0b1SCristina Ciocan
967c501d0b1SCristina Ciocan break;
968c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP:
969c501d0b1SCristina Ciocan /* Set default strength value in case none is given */
970c501d0b1SCristina Ciocan if (arg == 1)
971c501d0b1SCristina Ciocan arg = 2000;
972c501d0b1SCristina Ciocan
973c501d0b1SCristina Ciocan /*
974c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If
975c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it.
976c501d0b1SCristina Ciocan */
977c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) {
978c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN;
979c501d0b1SCristina Ciocan writel(val, val_reg);
980b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset);
981c501d0b1SCristina Ciocan }
982c501d0b1SCristina Ciocan
983c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK;
984c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_UP;
985c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg);
986c501d0b1SCristina Ciocan
987c501d0b1SCristina Ciocan break;
988658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE:
9899546f2aeSRaag Jadav if (arg) {
990827e1579SAndy Shevchenko conf |= BYT_DEBOUNCE_EN;
9919546f2aeSRaag Jadav } else {
992827e1579SAndy Shevchenko conf &= ~BYT_DEBOUNCE_EN;
993827e1579SAndy Shevchenko
9949546f2aeSRaag Jadav /*
9959546f2aeSRaag Jadav * No need to update the pulse value.
9969546f2aeSRaag Jadav * Debounce is going to be disabled.
9979546f2aeSRaag Jadav */
9989546f2aeSRaag Jadav break;
9999546f2aeSRaag Jadav }
10009546f2aeSRaag Jadav
1001658b476cSCristina Ciocan switch (arg) {
1002658b476cSCristina Ciocan case 375:
10034cfff5b7SRaag Jadav db_pulse = BYT_DEBOUNCE_PULSE_375US;
1004658b476cSCristina Ciocan break;
1005658b476cSCristina Ciocan case 750:
10064cfff5b7SRaag Jadav db_pulse = BYT_DEBOUNCE_PULSE_750US;
1007658b476cSCristina Ciocan break;
1008658b476cSCristina Ciocan case 1500:
10094cfff5b7SRaag Jadav db_pulse = BYT_DEBOUNCE_PULSE_1500US;
1010658b476cSCristina Ciocan break;
1011658b476cSCristina Ciocan case 3000:
10124cfff5b7SRaag Jadav db_pulse = BYT_DEBOUNCE_PULSE_3MS;
1013658b476cSCristina Ciocan break;
1014658b476cSCristina Ciocan case 6000:
10154cfff5b7SRaag Jadav db_pulse = BYT_DEBOUNCE_PULSE_6MS;
1016658b476cSCristina Ciocan break;
1017658b476cSCristina Ciocan case 12000:
10184cfff5b7SRaag Jadav db_pulse = BYT_DEBOUNCE_PULSE_12MS;
1019658b476cSCristina Ciocan break;
1020658b476cSCristina Ciocan case 24000:
10214cfff5b7SRaag Jadav db_pulse = BYT_DEBOUNCE_PULSE_24MS;
1022658b476cSCristina Ciocan break;
1023658b476cSCristina Ciocan default:
1024827e1579SAndy Shevchenko if (arg)
1025658b476cSCristina Ciocan ret = -EINVAL;
1026827e1579SAndy Shevchenko break;
1027658b476cSCristina Ciocan }
1028658b476cSCristina Ciocan
10294cfff5b7SRaag Jadav if (ret)
10304cfff5b7SRaag Jadav break;
10314cfff5b7SRaag Jadav
10324cfff5b7SRaag Jadav debounce = readl(db_reg);
10334cfff5b7SRaag Jadav debounce = (debounce & ~BYT_DEBOUNCE_PULSE_MASK) | db_pulse;
103404ff5a09SAndy Shevchenko writel(debounce, db_reg);
10354cfff5b7SRaag Jadav
1036658b476cSCristina Ciocan break;
1037c501d0b1SCristina Ciocan default:
1038c501d0b1SCristina Ciocan ret = -ENOTSUPP;
1039c501d0b1SCristina Ciocan }
1040c501d0b1SCristina Ciocan
1041c501d0b1SCristina Ciocan if (ret)
1042c501d0b1SCristina Ciocan break;
1043c501d0b1SCristina Ciocan }
1044c501d0b1SCristina Ciocan
1045c501d0b1SCristina Ciocan if (!ret)
1046c501d0b1SCristina Ciocan writel(conf, conf_reg);
1047c501d0b1SCristina Ciocan
104840ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
1049c501d0b1SCristina Ciocan
1050c501d0b1SCristina Ciocan return ret;
1051c501d0b1SCristina Ciocan }
1052c501d0b1SCristina Ciocan
1053c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = {
1054c501d0b1SCristina Ciocan .is_generic = true,
1055c501d0b1SCristina Ciocan .pin_config_get = byt_pin_config_get,
1056c501d0b1SCristina Ciocan .pin_config_set = byt_pin_config_set,
1057c501d0b1SCristina Ciocan };
1058c501d0b1SCristina Ciocan
1059c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = {
1060c501d0b1SCristina Ciocan .pctlops = &byt_pinctrl_ops,
1061c501d0b1SCristina Ciocan .pmxops = &byt_pinmux_ops,
1062c501d0b1SCristina Ciocan .confops = &byt_pinconf_ops,
1063c501d0b1SCristina Ciocan .owner = THIS_MODULE,
1064c501d0b1SCristina Ciocan };
1065c501d0b1SCristina Ciocan
byt_gpio_get(struct gpio_chip * chip,unsigned int offset)1066939330d7SAndy Shevchenko static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset)
10675fae8b86SMika Westerberg {
10685d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip);
1069c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
107039ce8150SMika Westerberg unsigned long flags;
107139ce8150SMika Westerberg u32 val;
107239ce8150SMika Westerberg
107340ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
107439ce8150SMika Westerberg val = readl(reg);
107540ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
107639ce8150SMika Westerberg
10773bde8771SLinus Walleij return !!(val & BYT_LEVEL);
10785fae8b86SMika Westerberg }
10795fae8b86SMika Westerberg
byt_gpio_set(struct gpio_chip * chip,unsigned int offset,int value)1080939330d7SAndy Shevchenko static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
10815fae8b86SMika Westerberg {
10825d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip);
1083c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
10845fae8b86SMika Westerberg unsigned long flags;
10855fae8b86SMika Westerberg u32 old_val;
10865fae8b86SMika Westerberg
108786e3ef81SCristina Ciocan if (!reg)
108886e3ef81SCristina Ciocan return;
108986e3ef81SCristina Ciocan
109040ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
10915fae8b86SMika Westerberg old_val = readl(reg);
10925fae8b86SMika Westerberg if (value)
10935fae8b86SMika Westerberg writel(old_val | BYT_LEVEL, reg);
10945fae8b86SMika Westerberg else
10955fae8b86SMika Westerberg writel(old_val & ~BYT_LEVEL, reg);
109640ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
10975fae8b86SMika Westerberg }
10985fae8b86SMika Westerberg
byt_gpio_get_direction(struct gpio_chip * chip,unsigned int offset)109986e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
11005fae8b86SMika Westerberg {
11015d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip);
1102c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
11035fae8b86SMika Westerberg unsigned long flags;
11045fae8b86SMika Westerberg u32 value;
11055fae8b86SMika Westerberg
110686e3ef81SCristina Ciocan if (!reg)
110786e3ef81SCristina Ciocan return -EINVAL;
110886e3ef81SCristina Ciocan
110940ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
111086e3ef81SCristina Ciocan value = readl(reg);
111140ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
11125fae8b86SMika Westerberg
111386e3ef81SCristina Ciocan if (!(value & BYT_OUTPUT_EN))
1114faf86c0cSMatti Vaittinen return GPIO_LINE_DIRECTION_OUT;
111586e3ef81SCristina Ciocan if (!(value & BYT_INPUT_EN))
1116faf86c0cSMatti Vaittinen return GPIO_LINE_DIRECTION_IN;
111786e3ef81SCristina Ciocan
111886e3ef81SCristina Ciocan return -EINVAL;
11195fae8b86SMika Westerberg }
11205fae8b86SMika Westerberg
byt_gpio_direction_input(struct gpio_chip * chip,unsigned int offset)112186e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
11225fae8b86SMika Westerberg {
1123156abe29SHans de Goede struct intel_pinctrl *vg = gpiochip_get_data(chip);
1124156abe29SHans de Goede void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1125156abe29SHans de Goede unsigned long flags;
1126156abe29SHans de Goede u32 reg;
1127156abe29SHans de Goede
1128156abe29SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
1129156abe29SHans de Goede
1130156abe29SHans de Goede reg = readl(val_reg);
1131156abe29SHans de Goede reg &= ~BYT_DIR_MASK;
1132156abe29SHans de Goede reg |= BYT_OUTPUT_EN;
1133156abe29SHans de Goede writel(reg, val_reg);
1134156abe29SHans de Goede
1135156abe29SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
1136156abe29SHans de Goede return 0;
113786e3ef81SCristina Ciocan }
11385fae8b86SMika Westerberg
1139156abe29SHans de Goede /*
1140156abe29SHans de Goede * Note despite the temptation this MUST NOT be converted into a call to
1141156abe29SHans de Goede * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this
1142156abe29SHans de Goede * MUST be done as a single BYT_VAL_REG register write.
1143156abe29SHans de Goede * See the commit message of the commit adding this comment for details.
1144156abe29SHans de Goede */
byt_gpio_direction_output(struct gpio_chip * chip,unsigned int offset,int value)114586e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip,
114686e3ef81SCristina Ciocan unsigned int offset, int value)
114786e3ef81SCristina Ciocan {
1148156abe29SHans de Goede struct intel_pinctrl *vg = gpiochip_get_data(chip);
1149156abe29SHans de Goede void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
1150156abe29SHans de Goede unsigned long flags;
1151156abe29SHans de Goede u32 reg;
11525fae8b86SMika Westerberg
1153156abe29SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
115486e3ef81SCristina Ciocan
1155156abe29SHans de Goede byt_gpio_direct_irq_check(vg, offset);
11565fae8b86SMika Westerberg
1157156abe29SHans de Goede reg = readl(val_reg);
1158156abe29SHans de Goede reg &= ~BYT_DIR_MASK;
1159156abe29SHans de Goede if (value)
1160156abe29SHans de Goede reg |= BYT_LEVEL;
1161156abe29SHans de Goede else
1162156abe29SHans de Goede reg &= ~BYT_LEVEL;
1163156abe29SHans de Goede
1164156abe29SHans de Goede writel(reg, val_reg);
1165156abe29SHans de Goede
1166156abe29SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
11675fae8b86SMika Westerberg return 0;
11685fae8b86SMika Westerberg }
11695fae8b86SMika Westerberg
byt_gpio_dbg_show(struct seq_file * s,struct gpio_chip * chip)11705fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
11715fae8b86SMika Westerberg {
11725d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip);
11735fae8b86SMika Westerberg int i;
117486e3ef81SCristina Ciocan u32 conf0, val;
11755fae8b86SMika Westerberg
11765d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->npins; i++) {
117734e65670SAndy Shevchenko const struct intel_community *comm;
11785a9fa4c2SRaag Jadav void __iomem *conf_reg, *val_reg;
11795fae8b86SMika Westerberg const char *pull_str = NULL;
11805fae8b86SMika Westerberg const char *pull = NULL;
118178e1c896SMika Westerberg unsigned long flags;
11825fae8b86SMika Westerberg const char *label;
118386e3ef81SCristina Ciocan unsigned int pin;
118478e1c896SMika Westerberg
11855d33e0ebSAndy Shevchenko pin = vg->soc->pins[i].number;
118686e3ef81SCristina Ciocan
11875a9fa4c2SRaag Jadav conf_reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
11885a9fa4c2SRaag Jadav if (!conf_reg) {
11895a9fa4c2SRaag Jadav seq_printf(s, "Pin %i: can't retrieve CONF0\n", pin);
119022bbd21bSDan Carpenter continue;
119186e3ef81SCristina Ciocan }
11925a9fa4c2SRaag Jadav
11935a9fa4c2SRaag Jadav val_reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
11945a9fa4c2SRaag Jadav if (!val_reg) {
11955a9fa4c2SRaag Jadav seq_printf(s, "Pin %i: can't retrieve VAL\n", pin);
11965a9fa4c2SRaag Jadav continue;
11975a9fa4c2SRaag Jadav }
11985a9fa4c2SRaag Jadav
11995a9fa4c2SRaag Jadav raw_spin_lock_irqsave(&byt_lock, flags);
12005a9fa4c2SRaag Jadav conf0 = readl(conf_reg);
12015a9fa4c2SRaag Jadav val = readl(val_reg);
120240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
12035fae8b86SMika Westerberg
12044d01688fSRaag Jadav comm = intel_get_community(vg, pin);
120586e3ef81SCristina Ciocan if (!comm) {
1206b9e18434SAndy Shevchenko seq_printf(s, "Pin %i: can't retrieve community\n", pin);
120786e3ef81SCristina Ciocan continue;
120886e3ef81SCristina Ciocan }
12095fae8b86SMika Westerberg label = gpiochip_is_requested(chip, i);
12105fae8b86SMika Westerberg if (!label)
12115fae8b86SMika Westerberg label = "Unrequested";
12125fae8b86SMika Westerberg
12135fae8b86SMika Westerberg switch (conf0 & BYT_PULL_ASSIGN_MASK) {
12145fae8b86SMika Westerberg case BYT_PULL_ASSIGN_UP:
12155fae8b86SMika Westerberg pull = "up";
12165fae8b86SMika Westerberg break;
12175fae8b86SMika Westerberg case BYT_PULL_ASSIGN_DOWN:
12185fae8b86SMika Westerberg pull = "down";
12195fae8b86SMika Westerberg break;
12205fae8b86SMika Westerberg }
12215fae8b86SMika Westerberg
12225fae8b86SMika Westerberg switch (conf0 & BYT_PULL_STR_MASK) {
12235fae8b86SMika Westerberg case BYT_PULL_STR_2K:
12245fae8b86SMika Westerberg pull_str = "2k";
12255fae8b86SMika Westerberg break;
12265fae8b86SMika Westerberg case BYT_PULL_STR_10K:
12275fae8b86SMika Westerberg pull_str = "10k";
12285fae8b86SMika Westerberg break;
12295fae8b86SMika Westerberg case BYT_PULL_STR_20K:
12305fae8b86SMika Westerberg pull_str = "20k";
12315fae8b86SMika Westerberg break;
12325fae8b86SMika Westerberg case BYT_PULL_STR_40K:
12335fae8b86SMika Westerberg pull_str = "40k";
12345fae8b86SMika Westerberg break;
12355fae8b86SMika Westerberg }
12365fae8b86SMika Westerberg
12375fae8b86SMika Westerberg seq_printf(s,
12385fae8b86SMika Westerberg " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s",
123986e3ef81SCristina Ciocan pin,
12405fae8b86SMika Westerberg label,
12415fae8b86SMika Westerberg val & BYT_INPUT_EN ? " " : "in",
12425fae8b86SMika Westerberg val & BYT_OUTPUT_EN ? " " : "out",
1243c518d31bSAndy Shevchenko str_hi_lo(val & BYT_LEVEL),
12443655a1caSAlexander Stein comm->pad_map[i], comm->pad_map[i] * 16,
12455fae8b86SMika Westerberg conf0 & 0x7,
12465fae8b86SMika Westerberg conf0 & BYT_TRIG_NEG ? " fall" : " ",
12475fae8b86SMika Westerberg conf0 & BYT_TRIG_POS ? " rise" : " ",
12485fae8b86SMika Westerberg conf0 & BYT_TRIG_LVL ? " level" : " ");
12495fae8b86SMika Westerberg
12505fae8b86SMika Westerberg if (pull && pull_str)
12515fae8b86SMika Westerberg seq_printf(s, " %-4s %-3s", pull, pull_str);
12525fae8b86SMika Westerberg else
12535fae8b86SMika Westerberg seq_puts(s, " ");
12545fae8b86SMika Westerberg
12555fae8b86SMika Westerberg if (conf0 & BYT_IODEN)
12565fae8b86SMika Westerberg seq_puts(s, " open-drain");
12575fae8b86SMika Westerberg
12585fae8b86SMika Westerberg seq_puts(s, "\n");
12595fae8b86SMika Westerberg }
12605fae8b86SMika Westerberg }
12615fae8b86SMika Westerberg
126286e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = {
126386e3ef81SCristina Ciocan .owner = THIS_MODULE,
126486e3ef81SCristina Ciocan .request = gpiochip_generic_request,
126586e3ef81SCristina Ciocan .free = gpiochip_generic_free,
126686e3ef81SCristina Ciocan .get_direction = byt_gpio_get_direction,
126786e3ef81SCristina Ciocan .direction_input = byt_gpio_direction_input,
126886e3ef81SCristina Ciocan .direction_output = byt_gpio_direction_output,
126986e3ef81SCristina Ciocan .get = byt_gpio_get,
127086e3ef81SCristina Ciocan .set = byt_gpio_set,
1271ccd025eaSAndy Shevchenko .set_config = gpiochip_generic_config,
127286e3ef81SCristina Ciocan .dbg_show = byt_gpio_dbg_show,
127386e3ef81SCristina Ciocan };
127486e3ef81SCristina Ciocan
byt_irq_ack(struct irq_data * d)127531e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d)
127631e4329fSMika Westerberg {
127731e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
12785d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(gc);
12796d209b42SAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d);
128031e4329fSMika Westerberg void __iomem *reg;
128131e4329fSMika Westerberg
12826d209b42SAndy Shevchenko reg = byt_gpio_reg(vg, hwirq, BYT_INT_STAT_REG);
12839f573b98SCristina Ciocan if (!reg)
12849f573b98SCristina Ciocan return;
12859f573b98SCristina Ciocan
128640ecab55SHans de Goede raw_spin_lock(&byt_lock);
12876d209b42SAndy Shevchenko writel(BIT(hwirq % 32), reg);
128840ecab55SHans de Goede raw_spin_unlock(&byt_lock);
128931e4329fSMika Westerberg }
129031e4329fSMika Westerberg
byt_irq_mask(struct irq_data * d)12919f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d)
12929f573b98SCristina Ciocan {
12939f573b98SCristina Ciocan struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
12945d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(gc);
12956d209b42SAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d);
12969f573b98SCristina Ciocan
12976d209b42SAndy Shevchenko byt_gpio_clear_triggering(vg, hwirq);
12986d209b42SAndy Shevchenko gpiochip_disable_irq(gc, hwirq);
12999f573b98SCristina Ciocan }
13009f573b98SCristina Ciocan
byt_irq_unmask(struct irq_data * d)13015fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d)
13025fae8b86SMika Westerberg {
130331e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
13045d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(gc);
13056d209b42SAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d);
130631e4329fSMika Westerberg unsigned long flags;
130731e4329fSMika Westerberg void __iomem *reg;
130831e4329fSMika Westerberg u32 value;
130931e4329fSMika Westerberg
13106d209b42SAndy Shevchenko gpiochip_enable_irq(gc, hwirq);
13116d209b42SAndy Shevchenko
13126d209b42SAndy Shevchenko reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
13139f573b98SCristina Ciocan if (!reg)
13149f573b98SCristina Ciocan return;
131578e1c896SMika Westerberg
131640ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
131731e4329fSMika Westerberg value = readl(reg);
131831e4329fSMika Westerberg
131931e4329fSMika Westerberg switch (irqd_get_trigger_type(d)) {
132031e4329fSMika Westerberg case IRQ_TYPE_LEVEL_HIGH:
132131e4329fSMika Westerberg value |= BYT_TRIG_LVL;
13220a093020SGustavo A. R. Silva fallthrough;
132331e4329fSMika Westerberg case IRQ_TYPE_EDGE_RISING:
132431e4329fSMika Westerberg value |= BYT_TRIG_POS;
132531e4329fSMika Westerberg break;
132631e4329fSMika Westerberg case IRQ_TYPE_LEVEL_LOW:
132731e4329fSMika Westerberg value |= BYT_TRIG_LVL;
13280a093020SGustavo A. R. Silva fallthrough;
132931e4329fSMika Westerberg case IRQ_TYPE_EDGE_FALLING:
133031e4329fSMika Westerberg value |= BYT_TRIG_NEG;
133131e4329fSMika Westerberg break;
133231e4329fSMika Westerberg case IRQ_TYPE_EDGE_BOTH:
133331e4329fSMika Westerberg value |= (BYT_TRIG_NEG | BYT_TRIG_POS);
133431e4329fSMika Westerberg break;
133531e4329fSMika Westerberg }
133631e4329fSMika Westerberg
133731e4329fSMika Westerberg writel(value, reg);
133831e4329fSMika Westerberg
133940ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
13405fae8b86SMika Westerberg }
13415fae8b86SMika Westerberg
byt_irq_type(struct irq_data * d,unsigned int type)13429f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type)
13435fae8b86SMika Westerberg {
13445d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d));
13456d209b42SAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d);
13469f573b98SCristina Ciocan u32 value;
13479f573b98SCristina Ciocan unsigned long flags;
13486d209b42SAndy Shevchenko void __iomem *reg;
134931e4329fSMika Westerberg
13506d209b42SAndy Shevchenko reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG);
13516d209b42SAndy Shevchenko if (!reg)
13529f573b98SCristina Ciocan return -EINVAL;
13539f573b98SCristina Ciocan
135440ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
13559f573b98SCristina Ciocan value = readl(reg);
13569f573b98SCristina Ciocan
13579f573b98SCristina Ciocan WARN(value & BYT_DIRECT_IRQ_EN,
1358b9e18434SAndy Shevchenko "Bad pad config for IO mode, force DIRECT_IRQ_EN bit clearing");
13599f573b98SCristina Ciocan
13609f573b98SCristina Ciocan /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits
13619f573b98SCristina Ciocan * are used to indicate high and low level triggering
13629f573b98SCristina Ciocan */
13639f573b98SCristina Ciocan value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG |
13649f573b98SCristina Ciocan BYT_TRIG_LVL);
13659291c65bSHans de Goede /* Enable glitch filtering */
13669291c65bSHans de Goede value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK |
13679291c65bSHans de Goede BYT_GLITCH_F_FAST_CLK;
13689f573b98SCristina Ciocan
13699f573b98SCristina Ciocan writel(value, reg);
13709f573b98SCristina Ciocan
13719f573b98SCristina Ciocan if (type & IRQ_TYPE_EDGE_BOTH)
13729f573b98SCristina Ciocan irq_set_handler_locked(d, handle_edge_irq);
13739f573b98SCristina Ciocan else if (type & IRQ_TYPE_LEVEL_MASK)
13749f573b98SCristina Ciocan irq_set_handler_locked(d, handle_level_irq);
13759f573b98SCristina Ciocan
137640ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
13779f573b98SCristina Ciocan
13789f573b98SCristina Ciocan return 0;
13795fae8b86SMika Westerberg }
13805fae8b86SMika Westerberg
13816d209b42SAndy Shevchenko static const struct irq_chip byt_gpio_irq_chip = {
13826d209b42SAndy Shevchenko .name = "BYT-GPIO",
13836d209b42SAndy Shevchenko .irq_ack = byt_irq_ack,
13846d209b42SAndy Shevchenko .irq_mask = byt_irq_mask,
13856d209b42SAndy Shevchenko .irq_unmask = byt_irq_unmask,
13866d209b42SAndy Shevchenko .irq_set_type = byt_irq_type,
13876d209b42SAndy Shevchenko .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE,
13886d209b42SAndy Shevchenko GPIOCHIP_IRQ_RESOURCE_HELPERS,
13896d209b42SAndy Shevchenko };
13906d209b42SAndy Shevchenko
byt_gpio_irq_handler(struct irq_desc * desc)139171e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc)
139271e6ca61SCristina Ciocan {
139371e6ca61SCristina Ciocan struct irq_data *data = irq_desc_get_irq_data(desc);
13945d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc));
139571e6ca61SCristina Ciocan struct irq_chip *chip = irq_data_get_irq_chip(data);
139671e6ca61SCristina Ciocan u32 base, pin;
139771e6ca61SCristina Ciocan void __iomem *reg;
139871e6ca61SCristina Ciocan unsigned long pending;
139971e6ca61SCristina Ciocan
140071e6ca61SCristina Ciocan /* check from GPIO controller which pin triggered the interrupt */
140171e6ca61SCristina Ciocan for (base = 0; base < vg->chip.ngpio; base += 32) {
140271e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
140371e6ca61SCristina Ciocan
140471e6ca61SCristina Ciocan if (!reg) {
1405b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base);
140671e6ca61SCristina Ciocan continue;
140771e6ca61SCristina Ciocan }
140871e6ca61SCristina Ciocan
140940ecab55SHans de Goede raw_spin_lock(&byt_lock);
141071e6ca61SCristina Ciocan pending = readl(reg);
141140ecab55SHans de Goede raw_spin_unlock(&byt_lock);
1412a9cb09b7SMarc Zyngier for_each_set_bit(pin, &pending, 32)
1413a9cb09b7SMarc Zyngier generic_handle_domain_irq(vg->chip.irq.domain, base + pin);
141471e6ca61SCristina Ciocan }
141571e6ca61SCristina Ciocan chip->irq_eoi(data);
141671e6ca61SCristina Ciocan }
141771e6ca61SCristina Ciocan
byt_direct_irq_sanity_check(struct intel_pinctrl * vg,int pin,u32 conf0)1418689e0088SHans de Goede static bool byt_direct_irq_sanity_check(struct intel_pinctrl *vg, int pin, u32 conf0)
1419689e0088SHans de Goede {
1420689e0088SHans de Goede int direct_irq, ioapic_direct_irq_base;
1421689e0088SHans de Goede u8 *match, direct_irq_mux[16];
1422689e0088SHans de Goede u32 trig;
1423689e0088SHans de Goede
1424689e0088SHans de Goede memcpy_fromio(direct_irq_mux, vg->communities->pad_regs + BYT_DIRECT_IRQ_REG,
1425689e0088SHans de Goede sizeof(direct_irq_mux));
1426689e0088SHans de Goede match = memchr(direct_irq_mux, pin, sizeof(direct_irq_mux));
1427689e0088SHans de Goede if (!match) {
1428b9e18434SAndy Shevchenko dev_warn(vg->dev, FW_BUG "Pin %i: DIRECT_IRQ_EN set but no IRQ assigned, clearing\n", pin);
1429689e0088SHans de Goede return false;
1430689e0088SHans de Goede }
1431689e0088SHans de Goede
1432689e0088SHans de Goede direct_irq = match - direct_irq_mux;
1433689e0088SHans de Goede /* Base IO-APIC pin numbers come from atom-e3800-family-datasheet.pdf */
1434689e0088SHans de Goede ioapic_direct_irq_base = (vg->communities->npins == BYT_NGPIO_SCORE) ? 51 : 67;
1435689e0088SHans de Goede dev_dbg(vg->dev, "Pin %i: uses direct IRQ %d (IO-APIC %d)\n", pin,
1436689e0088SHans de Goede direct_irq, direct_irq + ioapic_direct_irq_base);
1437689e0088SHans de Goede
1438689e0088SHans de Goede /*
1439689e0088SHans de Goede * Testing has shown that the way direct IRQs work is that the combination of the
1440689e0088SHans de Goede * direct-irq-en flag and the direct IRQ mux connect the output of the GPIO's IRQ
1441689e0088SHans de Goede * trigger block, which normally sets the status flag in the IRQ status reg at
1442689e0088SHans de Goede * 0x800, to one of the IO-APIC pins according to the mux registers.
1443689e0088SHans de Goede *
1444689e0088SHans de Goede * This means that:
1445689e0088SHans de Goede * 1. The TRIG_MASK bits must be set to configure the GPIO's IRQ trigger block
1446689e0088SHans de Goede * 2. The TRIG_LVL bit *must* be set, so that the GPIO's input value is directly
1447689e0088SHans de Goede * passed (1:1 or inverted) to the IO-APIC pin, if TRIG_LVL is not set,
1448689e0088SHans de Goede * selecting edge mode operation then on the first edge the IO-APIC pin goes
1449689e0088SHans de Goede * high, but since no write-to-clear write will be done to the IRQ status reg
1450689e0088SHans de Goede * at 0x800, the detected edge condition will never get cleared.
1451689e0088SHans de Goede */
1452689e0088SHans de Goede trig = conf0 & BYT_TRIG_MASK;
1453689e0088SHans de Goede if (trig != (BYT_TRIG_POS | BYT_TRIG_LVL) &&
1454689e0088SHans de Goede trig != (BYT_TRIG_NEG | BYT_TRIG_LVL)) {
1455b9e18434SAndy Shevchenko dev_warn(vg->dev,
1456b9e18434SAndy Shevchenko FW_BUG "Pin %i: DIRECT_IRQ_EN set without trigger (CONF0: %#08x), clearing\n",
1457689e0088SHans de Goede pin, conf0);
1458689e0088SHans de Goede return false;
1459689e0088SHans de Goede }
1460689e0088SHans de Goede
1461689e0088SHans de Goede return true;
1462689e0088SHans de Goede }
1463689e0088SHans de Goede
byt_init_irq_valid_mask(struct gpio_chip * chip,unsigned long * valid_mask,unsigned int ngpios)14645fbe5b58SLinus Walleij static void byt_init_irq_valid_mask(struct gpio_chip *chip,
14655fbe5b58SLinus Walleij unsigned long *valid_mask,
14665fbe5b58SLinus Walleij unsigned int ngpios)
14675fbe5b58SLinus Walleij {
14685d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip);
14695fae8b86SMika Westerberg void __iomem *reg;
1470e70982b3SAndy Shevchenko u32 value;
147195f0972cSMika Westerberg int i;
147295f0972cSMika Westerberg
147395f0972cSMika Westerberg /*
147495f0972cSMika Westerberg * Clear interrupt triggers for all pins that are GPIOs and
147595f0972cSMika Westerberg * do not use direct IRQ mode. This will prevent spurious
147695f0972cSMika Westerberg * interrupts from misconfigured pins.
147795f0972cSMika Westerberg */
14785d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->npins; i++) {
14795d33e0ebSAndy Shevchenko unsigned int pin = vg->soc->pins[i].number;
148071e6ca61SCristina Ciocan
148171e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
148271e6ca61SCristina Ciocan if (!reg) {
1483b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: could not retrieve CONF0\n", i);
148471e6ca61SCristina Ciocan continue;
148571e6ca61SCristina Ciocan }
148671e6ca61SCristina Ciocan
148771e6ca61SCristina Ciocan value = readl(reg);
148849c03096SAndy Shevchenko if (value & BYT_DIRECT_IRQ_EN) {
1489689e0088SHans de Goede if (byt_direct_irq_sanity_check(vg, i, value)) {
1490e70982b3SAndy Shevchenko clear_bit(i, valid_mask);
1491689e0088SHans de Goede } else {
1492689e0088SHans de Goede value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS |
1493689e0088SHans de Goede BYT_TRIG_NEG | BYT_TRIG_LVL);
1494689e0088SHans de Goede writel(value, reg);
1495689e0088SHans de Goede }
149649c03096SAndy Shevchenko } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) {
149795f0972cSMika Westerberg byt_gpio_clear_triggering(vg, i);
1498990ec243SAndy Shevchenko dev_dbg(vg->dev, "disabling GPIO %d\n", i);
149995f0972cSMika Westerberg }
150095f0972cSMika Westerberg }
1501e70982b3SAndy Shevchenko }
1502e70982b3SAndy Shevchenko
byt_gpio_irq_init_hw(struct gpio_chip * chip)1503e70982b3SAndy Shevchenko static int byt_gpio_irq_init_hw(struct gpio_chip *chip)
1504e70982b3SAndy Shevchenko {
15055d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip);
1506e70982b3SAndy Shevchenko void __iomem *reg;
1507e70982b3SAndy Shevchenko u32 base, value;
15085fae8b86SMika Westerberg
15095fae8b86SMika Westerberg /* clear interrupt status trigger registers */
15105d33e0ebSAndy Shevchenko for (base = 0; base < vg->soc->npins; base += 32) {
1511c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG);
151271e6ca61SCristina Ciocan
151371e6ca61SCristina Ciocan if (!reg) {
1514b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base);
151571e6ca61SCristina Ciocan continue;
151671e6ca61SCristina Ciocan }
151771e6ca61SCristina Ciocan
15185fae8b86SMika Westerberg writel(0xffffffff, reg);
15195fae8b86SMika Westerberg /* make sure trigger bits are cleared, if not then a pin
15205fae8b86SMika Westerberg might be misconfigured in bios */
15215fae8b86SMika Westerberg value = readl(reg);
15225fae8b86SMika Westerberg if (value)
1523990ec243SAndy Shevchenko dev_err(vg->dev,
1524b9e18434SAndy Shevchenko "GPIO interrupt error, pins misconfigured. INT_STAT%u: %#08x\n",
1525973232e2SAlexander Stein base / 32, value);
15265fae8b86SMika Westerberg }
1527ca8a958eSAndy Shevchenko
1528ca8a958eSAndy Shevchenko return 0;
15295fae8b86SMika Westerberg }
15305fae8b86SMika Westerberg
byt_gpio_add_pin_ranges(struct gpio_chip * chip)1531ed3c1564SAndy Shevchenko static int byt_gpio_add_pin_ranges(struct gpio_chip *chip)
1532ed3c1564SAndy Shevchenko {
15335d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip);
1534990ec243SAndy Shevchenko struct device *dev = vg->dev;
1535ed3c1564SAndy Shevchenko int ret;
1536ed3c1564SAndy Shevchenko
15375d33e0ebSAndy Shevchenko ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins);
1538ed3c1564SAndy Shevchenko if (ret)
1539ed3c1564SAndy Shevchenko dev_err(dev, "failed to add GPIO pin range\n");
1540ed3c1564SAndy Shevchenko
1541ed3c1564SAndy Shevchenko return ret;
1542ed3c1564SAndy Shevchenko }
1543ed3c1564SAndy Shevchenko
byt_gpio_probe(struct intel_pinctrl * vg)15445d33e0ebSAndy Shevchenko static int byt_gpio_probe(struct intel_pinctrl *vg)
15455fae8b86SMika Westerberg {
1546990ec243SAndy Shevchenko struct platform_device *pdev = to_platform_device(vg->dev);
15475fae8b86SMika Westerberg struct gpio_chip *gc;
1548f86a1bb5SAndy Shevchenko int irq, ret;
15495fae8b86SMika Westerberg
155071e6ca61SCristina Ciocan /* Set up gpio chip */
155171e6ca61SCristina Ciocan vg->chip = byt_gpio_chip;
15525fae8b86SMika Westerberg gc = &vg->chip;
1553990ec243SAndy Shevchenko gc->label = dev_name(vg->dev);
15545fae8b86SMika Westerberg gc->base = -1;
15555fae8b86SMika Westerberg gc->can_sleep = false;
1556ed3c1564SAndy Shevchenko gc->add_pin_ranges = byt_gpio_add_pin_ranges;
1557990ec243SAndy Shevchenko gc->parent = vg->dev;
15585d33e0ebSAndy Shevchenko gc->ngpio = vg->soc->npins;
15595fae8b86SMika Westerberg
1560fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP
15615d33e0ebSAndy Shevchenko vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads),
15625d33e0ebSAndy Shevchenko GFP_KERNEL);
15635d33e0ebSAndy Shevchenko if (!vg->context.pads)
1564d6cb7722SAditya Pakki return -ENOMEM;
1565fcc18debSMika Westerberg #endif
15665fae8b86SMika Westerberg
15675fae8b86SMika Westerberg /* set up interrupts */
1568f86a1bb5SAndy Shevchenko irq = platform_get_irq_optional(pdev, 0);
1569f86a1bb5SAndy Shevchenko if (irq > 0) {
1570ca8a958eSAndy Shevchenko struct gpio_irq_chip *girq;
1571ca8a958eSAndy Shevchenko
1572ca8a958eSAndy Shevchenko girq = &gc->irq;
15736d209b42SAndy Shevchenko gpio_irq_chip_set_chip(girq, &byt_gpio_irq_chip);
1574ca8a958eSAndy Shevchenko girq->init_hw = byt_gpio_irq_init_hw;
1575ab68b220SAndy Shevchenko girq->init_valid_mask = byt_init_irq_valid_mask;
1576ca8a958eSAndy Shevchenko girq->parent_handler = byt_gpio_irq_handler;
1577ca8a958eSAndy Shevchenko girq->num_parents = 1;
1578990ec243SAndy Shevchenko girq->parents = devm_kcalloc(vg->dev, girq->num_parents,
1579ca8a958eSAndy Shevchenko sizeof(*girq->parents), GFP_KERNEL);
1580ca8a958eSAndy Shevchenko if (!girq->parents)
1581ca8a958eSAndy Shevchenko return -ENOMEM;
1582f86a1bb5SAndy Shevchenko girq->parents[0] = irq;
1583ca8a958eSAndy Shevchenko girq->default_type = IRQ_TYPE_NONE;
1584ca8a958eSAndy Shevchenko girq->handler = handle_bad_irq;
15855fae8b86SMika Westerberg }
15865fae8b86SMika Westerberg
1587990ec243SAndy Shevchenko ret = devm_gpiochip_add_data(vg->dev, gc, vg);
1588ca8a958eSAndy Shevchenko if (ret) {
1589990ec243SAndy Shevchenko dev_err(vg->dev, "failed adding byt-gpio chip\n");
1590ca8a958eSAndy Shevchenko return ret;
15915fae8b86SMika Westerberg }
15925fae8b86SMika Westerberg
159371e6ca61SCristina Ciocan return ret;
159471e6ca61SCristina Ciocan }
159571e6ca61SCristina Ciocan
byt_set_soc_data(struct intel_pinctrl * vg,const struct intel_pinctrl_soc_data * soc)15965d33e0ebSAndy Shevchenko static int byt_set_soc_data(struct intel_pinctrl *vg,
15975d33e0ebSAndy Shevchenko const struct intel_pinctrl_soc_data *soc)
159871e6ca61SCristina Ciocan {
1599990ec243SAndy Shevchenko struct platform_device *pdev = to_platform_device(vg->dev);
160071e6ca61SCristina Ciocan int i;
160171e6ca61SCristina Ciocan
16025d33e0ebSAndy Shevchenko vg->soc = soc;
16035d33e0ebSAndy Shevchenko
16045d33e0ebSAndy Shevchenko vg->ncommunities = vg->soc->ncommunities;
16055d33e0ebSAndy Shevchenko vg->communities = devm_kcalloc(vg->dev, vg->ncommunities,
16065d33e0ebSAndy Shevchenko sizeof(*vg->communities), GFP_KERNEL);
16075d33e0ebSAndy Shevchenko if (!vg->communities)
160871e6ca61SCristina Ciocan return -ENOMEM;
160971e6ca61SCristina Ciocan
16105d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->ncommunities; i++) {
16115d33e0ebSAndy Shevchenko struct intel_community *comm = vg->communities + i;
161271e6ca61SCristina Ciocan
16135d33e0ebSAndy Shevchenko *comm = vg->soc->communities[i];
161471e6ca61SCristina Ciocan
1615990ec243SAndy Shevchenko comm->pad_regs = devm_platform_ioremap_resource(pdev, 0);
161634e65670SAndy Shevchenko if (IS_ERR(comm->pad_regs))
161734e65670SAndy Shevchenko return PTR_ERR(comm->pad_regs);
161871e6ca61SCristina Ciocan }
161971e6ca61SCristina Ciocan
162071e6ca61SCristina Ciocan return 0;
162171e6ca61SCristina Ciocan }
162271e6ca61SCristina Ciocan
162371e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = {
162471e6ca61SCristina Ciocan { "INT33B2", (kernel_ulong_t)byt_soc_data },
162571e6ca61SCristina Ciocan { "INT33FC", (kernel_ulong_t)byt_soc_data },
162671e6ca61SCristina Ciocan { }
162771e6ca61SCristina Ciocan };
162871e6ca61SCristina Ciocan
byt_pinctrl_probe(struct platform_device * pdev)162971e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev)
163071e6ca61SCristina Ciocan {
1631ce7793e9SAndy Shevchenko const struct intel_pinctrl_soc_data *soc_data;
16322c02af70SAndy Shevchenko struct device *dev = &pdev->dev;
16335d33e0ebSAndy Shevchenko struct intel_pinctrl *vg;
1634ce7793e9SAndy Shevchenko int ret;
163571e6ca61SCristina Ciocan
1636ce7793e9SAndy Shevchenko soc_data = intel_pinctrl_get_soc_data(pdev);
1637ce7793e9SAndy Shevchenko if (IS_ERR(soc_data))
1638ce7793e9SAndy Shevchenko return PTR_ERR(soc_data);
163971e6ca61SCristina Ciocan
16402c02af70SAndy Shevchenko vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL);
164171e6ca61SCristina Ciocan if (!vg)
164271e6ca61SCristina Ciocan return -ENOMEM;
164371e6ca61SCristina Ciocan
16442c02af70SAndy Shevchenko vg->dev = dev;
164571e6ca61SCristina Ciocan ret = byt_set_soc_data(vg, soc_data);
164671e6ca61SCristina Ciocan if (ret) {
16472c02af70SAndy Shevchenko dev_err(dev, "failed to set soc data\n");
164871e6ca61SCristina Ciocan return ret;
164971e6ca61SCristina Ciocan }
165071e6ca61SCristina Ciocan
16515d33e0ebSAndy Shevchenko vg->pctldesc = byt_pinctrl_desc;
16525d33e0ebSAndy Shevchenko vg->pctldesc.name = dev_name(dev);
16535d33e0ebSAndy Shevchenko vg->pctldesc.pins = vg->soc->pins;
16545d33e0ebSAndy Shevchenko vg->pctldesc.npins = vg->soc->npins;
165571e6ca61SCristina Ciocan
16565d33e0ebSAndy Shevchenko vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg);
16575d33e0ebSAndy Shevchenko if (IS_ERR(vg->pctldev)) {
16582c02af70SAndy Shevchenko dev_err(dev, "failed to register pinctrl driver\n");
16595d33e0ebSAndy Shevchenko return PTR_ERR(vg->pctldev);
166071e6ca61SCristina Ciocan }
166171e6ca61SCristina Ciocan
166271e6ca61SCristina Ciocan ret = byt_gpio_probe(vg);
16630612413fSAndy Shevchenko if (ret)
166471e6ca61SCristina Ciocan return ret;
166571e6ca61SCristina Ciocan
166671e6ca61SCristina Ciocan platform_set_drvdata(pdev, vg);
16672c02af70SAndy Shevchenko pm_runtime_enable(dev);
166871e6ca61SCristina Ciocan
166971e6ca61SCristina Ciocan return 0;
167071e6ca61SCristina Ciocan }
167171e6ca61SCristina Ciocan
byt_gpio_suspend(struct device * dev)1672fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev)
1673fcc18debSMika Westerberg {
16745d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = dev_get_drvdata(dev);
167540ecab55SHans de Goede unsigned long flags;
1676fcc18debSMika Westerberg int i;
1677fcc18debSMika Westerberg
167840ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
167940ecab55SHans de Goede
16805d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->npins; i++) {
1681fcc18debSMika Westerberg void __iomem *reg;
1682fcc18debSMika Westerberg u32 value;
16835d33e0ebSAndy Shevchenko unsigned int pin = vg->soc->pins[i].number;
1684fcc18debSMika Westerberg
168571e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
168671e6ca61SCristina Ciocan if (!reg) {
1687b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i);
168871e6ca61SCristina Ciocan continue;
168971e6ca61SCristina Ciocan }
1690fcc18debSMika Westerberg value = readl(reg) & BYT_CONF0_RESTORE_MASK;
16915d33e0ebSAndy Shevchenko vg->context.pads[i].conf0 = value;
1692fcc18debSMika Westerberg
169371e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
16949d49882eSRaag Jadav if (!reg) {
16959d49882eSRaag Jadav dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i);
16969d49882eSRaag Jadav continue;
16979d49882eSRaag Jadav }
1698fcc18debSMika Westerberg value = readl(reg) & BYT_VAL_RESTORE_MASK;
16995d33e0ebSAndy Shevchenko vg->context.pads[i].val = value;
1700fcc18debSMika Westerberg }
1701fcc18debSMika Westerberg
170240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
1703fcc18debSMika Westerberg return 0;
1704fcc18debSMika Westerberg }
1705fcc18debSMika Westerberg
byt_gpio_resume(struct device * dev)1706fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev)
1707fcc18debSMika Westerberg {
17085d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = dev_get_drvdata(dev);
170940ecab55SHans de Goede unsigned long flags;
1710fcc18debSMika Westerberg int i;
1711fcc18debSMika Westerberg
171240ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags);
171340ecab55SHans de Goede
17145d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->npins; i++) {
1715fcc18debSMika Westerberg void __iomem *reg;
1716fcc18debSMika Westerberg u32 value;
17175d33e0ebSAndy Shevchenko unsigned int pin = vg->soc->pins[i].number;
1718fcc18debSMika Westerberg
171971e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG);
172071e6ca61SCristina Ciocan if (!reg) {
1721b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i);
172271e6ca61SCristina Ciocan continue;
172371e6ca61SCristina Ciocan }
1724fcc18debSMika Westerberg value = readl(reg);
1725fcc18debSMika Westerberg if ((value & BYT_CONF0_RESTORE_MASK) !=
17265d33e0ebSAndy Shevchenko vg->context.pads[i].conf0) {
1727fcc18debSMika Westerberg value &= ~BYT_CONF0_RESTORE_MASK;
17285d33e0ebSAndy Shevchenko value |= vg->context.pads[i].conf0;
1729fcc18debSMika Westerberg writel(value, reg);
1730b9e18434SAndy Shevchenko dev_info(dev, "restored pin %d CONF0 %#08x", i, value);
1731fcc18debSMika Westerberg }
1732fcc18debSMika Westerberg
173371e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG);
17349d49882eSRaag Jadav if (!reg) {
17359d49882eSRaag Jadav dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i);
17369d49882eSRaag Jadav continue;
17379d49882eSRaag Jadav }
1738fcc18debSMika Westerberg value = readl(reg);
1739fcc18debSMika Westerberg if ((value & BYT_VAL_RESTORE_MASK) !=
17405d33e0ebSAndy Shevchenko vg->context.pads[i].val) {
1741fcc18debSMika Westerberg u32 v;
1742fcc18debSMika Westerberg
1743fcc18debSMika Westerberg v = value & ~BYT_VAL_RESTORE_MASK;
17445d33e0ebSAndy Shevchenko v |= vg->context.pads[i].val;
1745fcc18debSMika Westerberg if (v != value) {
1746fcc18debSMika Westerberg writel(v, reg);
1747b9e18434SAndy Shevchenko dev_dbg(dev, "restored pin %d VAL %#08x\n", i, v);
1748fcc18debSMika Westerberg }
1749fcc18debSMika Westerberg }
1750fcc18debSMika Westerberg }
1751fcc18debSMika Westerberg
175240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags);
1753fcc18debSMika Westerberg return 0;
1754fcc18debSMika Westerberg }
1755fcc18debSMika Westerberg
byt_gpio_runtime_suspend(struct device * dev)17565fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev)
17575fae8b86SMika Westerberg {
17585fae8b86SMika Westerberg return 0;
17595fae8b86SMika Westerberg }
17605fae8b86SMika Westerberg
byt_gpio_runtime_resume(struct device * dev)17615fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev)
17625fae8b86SMika Westerberg {
17635fae8b86SMika Westerberg return 0;
17645fae8b86SMika Westerberg }
17655fae8b86SMika Westerberg
17665fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = {
1767df660f66SAndy Shevchenko LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume)
1768df660f66SAndy Shevchenko RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, NULL)
17695fae8b86SMika Westerberg };
17705fae8b86SMika Westerberg
17715fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = {
177271e6ca61SCristina Ciocan .probe = byt_pinctrl_probe,
17735fae8b86SMika Westerberg .driver = {
17745fae8b86SMika Westerberg .name = "byt_gpio",
1775df660f66SAndy Shevchenko .pm = pm_ptr(&byt_gpio_pm_ops),
1776e87daf0bSAndy Shevchenko .acpi_match_table = byt_gpio_acpi_match,
1777360943a8SPaul Gortmaker .suppress_bind_attrs = true,
17785fae8b86SMika Westerberg },
17795fae8b86SMika Westerberg };
17805fae8b86SMika Westerberg
byt_gpio_init(void)17815fae8b86SMika Westerberg static int __init byt_gpio_init(void)
17825fae8b86SMika Westerberg {
17835fae8b86SMika Westerberg return platform_driver_register(&byt_gpio_driver);
17845fae8b86SMika Westerberg }
17855fae8b86SMika Westerberg subsys_initcall(byt_gpio_init);
17864d01688fSRaag Jadav
17874d01688fSRaag Jadav MODULE_IMPORT_NS(PINCTRL_INTEL);
1788