1875a92b3SAndy Shevchenko // SPDX-License-Identifier: GPL-2.0 25fae8b86SMika Westerberg /* 35fae8b86SMika Westerberg * Pinctrl GPIO driver for Intel Baytrail 45fae8b86SMika Westerberg * 5875a92b3SAndy Shevchenko * Copyright (c) 2012-2013, Intel Corporation 65fae8b86SMika Westerberg * Author: Mathias Nyman <mathias.nyman@linux.intel.com> 75fae8b86SMika Westerberg */ 85fae8b86SMika Westerberg 95fae8b86SMika Westerberg #include <linux/acpi.h> 10e0da3842SAndy Shevchenko #include <linux/bitops.h> 11e0da3842SAndy Shevchenko #include <linux/gpio/driver.h> 12e0da3842SAndy Shevchenko #include <linux/init.h> 13e0da3842SAndy Shevchenko #include <linux/interrupt.h> 145fae8b86SMika Westerberg #include <linux/io.h> 15e0da3842SAndy Shevchenko #include <linux/kernel.h> 16e0da3842SAndy Shevchenko #include <linux/types.h> 17e0da3842SAndy Shevchenko #include <linux/platform_device.h> 185fae8b86SMika Westerberg #include <linux/pm_runtime.h> 1961db6c9dSAndy Shevchenko #include <linux/property.h> 20e0da3842SAndy Shevchenko #include <linux/seq_file.h> 21c518d31bSAndy Shevchenko #include <linux/string_helpers.h> 2261db6c9dSAndy Shevchenko 235fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h> 24c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h> 25c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h> 26c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h> 275fae8b86SMika Westerberg 284f010b93SAndy Shevchenko #include "pinctrl-intel.h" 294f010b93SAndy Shevchenko 305fae8b86SMika Westerberg /* memory mapped register offsets */ 315fae8b86SMika Westerberg #define BYT_CONF0_REG 0x000 325fae8b86SMika Westerberg #define BYT_CONF1_REG 0x004 335fae8b86SMika Westerberg #define BYT_VAL_REG 0x008 345fae8b86SMika Westerberg #define BYT_DFT_REG 0x00c 355fae8b86SMika Westerberg #define BYT_INT_STAT_REG 0x800 36689e0088SHans de Goede #define BYT_DIRECT_IRQ_REG 0x980 37658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG 0x9d0 385fae8b86SMika Westerberg 395fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */ 405fae8b86SMika Westerberg #define BYT_IODEN BIT(31) 415fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN BIT(27) 42eb0a2daaSAndy Shevchenko #define BYT_TRIG_MASK GENMASK(26, 24) 435fae8b86SMika Westerberg #define BYT_TRIG_NEG BIT(26) 445fae8b86SMika Westerberg #define BYT_TRIG_POS BIT(25) 455fae8b86SMika Westerberg #define BYT_TRIG_LVL BIT(24) 46658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN BIT(20) 479291c65bSHans de Goede #define BYT_GLITCH_FILTER_EN BIT(19) 489291c65bSHans de Goede #define BYT_GLITCH_F_SLOW_CLK BIT(17) 499291c65bSHans de Goede #define BYT_GLITCH_F_FAST_CLK BIT(16) 505fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT 9 51eb0a2daaSAndy Shevchenko #define BYT_PULL_STR_MASK GENMASK(10, 9) 525fae8b86SMika Westerberg #define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) 535fae8b86SMika Westerberg #define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT) 545fae8b86SMika Westerberg #define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT) 555fae8b86SMika Westerberg #define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT) 56eb0a2daaSAndy Shevchenko #define BYT_PULL_ASSIGN_MASK GENMASK(8, 7) 579d712086SAndy Shevchenko #define BYT_PULL_ASSIGN_DOWN BIT(8) 589d712086SAndy Shevchenko #define BYT_PULL_ASSIGN_UP BIT(7) 59eb0a2daaSAndy Shevchenko #define BYT_PIN_MUX GENMASK(2, 0) 605fae8b86SMika Westerberg 615fae8b86SMika Westerberg /* BYT_VAL_REG register bits */ 62eb0a2daaSAndy Shevchenko #define BYT_DIR_MASK GENMASK(2, 1) 635fae8b86SMika Westerberg #define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ 645fae8b86SMika Westerberg #define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ 655fae8b86SMika Westerberg #define BYT_LEVEL BIT(0) 665fae8b86SMika Westerberg 67eb0a2daaSAndy Shevchenko #define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX) 68fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) 69fcc18debSMika Westerberg 70658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */ 71eb0a2daaSAndy Shevchenko #define BYT_DEBOUNCE_PULSE_MASK GENMASK(2, 0) 72658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US 1 73658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US 2 74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US 3 75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS 4 76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS 5 77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS 6 78658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS 7 79658b476cSCristina Ciocan 805fae8b86SMika Westerberg #define BYT_NGPIO_SCORE 102 815fae8b86SMika Westerberg #define BYT_NGPIO_NCORE 28 825fae8b86SMika Westerberg #define BYT_NGPIO_SUS 44 835fae8b86SMika Westerberg 845fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID "1" 855fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID "2" 865fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID "3" 875fae8b86SMika Westerberg 88c501d0b1SCristina Ciocan /* 89c501d0b1SCristina Ciocan * This is the function value most pins have for GPIO muxing. If the value 90c501d0b1SCristina Ciocan * differs from the default one, it must be explicitly mentioned. Otherwise, the 91c501d0b1SCristina Ciocan * pin control implementation will set the muxing value to default GPIO if it 92c501d0b1SCristina Ciocan * does not find a match for the requested function. 93c501d0b1SCristina Ciocan */ 94c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX 0 95a705f9c1SAndy Shevchenko #define BYT_ALTER_GPIO_MUX 1 96c501d0b1SCristina Ciocan 975d33e0ebSAndy Shevchenko struct intel_pad_context { 98c8f5c4c7SCristina Ciocan u32 conf0; 99c8f5c4c7SCristina Ciocan u32 val; 100c8f5c4c7SCristina Ciocan }; 1015fae8b86SMika Westerberg 102c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map) \ 103c8f5c4c7SCristina Ciocan { \ 104c8f5c4c7SCristina Ciocan .pin_base = (p), \ 105c8f5c4c7SCristina Ciocan .npins = (n), \ 106c8f5c4c7SCristina Ciocan .pad_map = (map),\ 107c8f5c4c7SCristina Ciocan } 108c8f5c4c7SCristina Ciocan 109c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ 110c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = { 111c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "SATA_GP0"), 112c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "SATA_GP1"), 113c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "SATA_LED#"), 114c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "PCIE_CLKREQ0"), 115c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "PCIE_CLKREQ1"), 116c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "PCIE_CLKREQ2"), 117c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "PCIE_CLKREQ3"), 118c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "SD3_WP"), 119c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "HDA_RST"), 120c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "HDA_SYNC"), 121c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "HDA_CLK"), 122c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "HDA_SDO"), 123c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "HDA_SDI0"), 124c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "HDA_SDI1"), 125c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_S0_SC14"), 126c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_S0_SC15"), 127c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "MMC1_CLK"), 128c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "MMC1_D0"), 129c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "MMC1_D1"), 130c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "MMC1_D2"), 131c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "MMC1_D3"), 132c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "MMC1_D4"), 133c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "MMC1_D5"), 134c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "MMC1_D6"), 135c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "MMC1_D7"), 136c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "MMC1_CMD"), 137c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "MMC1_RST"), 138c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "SD2_CLK"), 139c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "SD2_D0"), 140c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "SD2_D1"), 141c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "SD2_D2"), 142c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "SD2_D3_CD"), 143c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "SD2_CMD"), 144c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "SD3_CLK"), 145c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "SD3_D0"), 146c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "SD3_D1"), 147c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "SD3_D2"), 148c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "SD3_D3"), 149c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "SD3_CD"), 150c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "SD3_CMD"), 151c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "SD3_1P8EN"), 152c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "SD3_PWREN#"), 153c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "ILB_LPC_AD0"), 154c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "ILB_LPC_AD1"), 155c8f5c4c7SCristina Ciocan PINCTRL_PIN(44, "ILB_LPC_AD2"), 156c8f5c4c7SCristina Ciocan PINCTRL_PIN(45, "ILB_LPC_AD3"), 157c8f5c4c7SCristina Ciocan PINCTRL_PIN(46, "ILB_LPC_FRAME"), 158c8f5c4c7SCristina Ciocan PINCTRL_PIN(47, "ILB_LPC_CLK0"), 159c8f5c4c7SCristina Ciocan PINCTRL_PIN(48, "ILB_LPC_CLK1"), 160c8f5c4c7SCristina Ciocan PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), 161c8f5c4c7SCristina Ciocan PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), 162c8f5c4c7SCristina Ciocan PINCTRL_PIN(51, "PCU_SMB_DATA"), 163c8f5c4c7SCristina Ciocan PINCTRL_PIN(52, "PCU_SMB_CLK"), 164c8f5c4c7SCristina Ciocan PINCTRL_PIN(53, "PCU_SMB_ALERT"), 165c8f5c4c7SCristina Ciocan PINCTRL_PIN(54, "ILB_8254_SPKR"), 166c8f5c4c7SCristina Ciocan PINCTRL_PIN(55, "GPIO_S0_SC55"), 167c8f5c4c7SCristina Ciocan PINCTRL_PIN(56, "GPIO_S0_SC56"), 168c8f5c4c7SCristina Ciocan PINCTRL_PIN(57, "GPIO_S0_SC57"), 169c8f5c4c7SCristina Ciocan PINCTRL_PIN(58, "GPIO_S0_SC58"), 170c8f5c4c7SCristina Ciocan PINCTRL_PIN(59, "GPIO_S0_SC59"), 171c8f5c4c7SCristina Ciocan PINCTRL_PIN(60, "GPIO_S0_SC60"), 172c8f5c4c7SCristina Ciocan PINCTRL_PIN(61, "GPIO_S0_SC61"), 173c8f5c4c7SCristina Ciocan PINCTRL_PIN(62, "LPE_I2S2_CLK"), 174c8f5c4c7SCristina Ciocan PINCTRL_PIN(63, "LPE_I2S2_FRM"), 175c8f5c4c7SCristina Ciocan PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), 176c8f5c4c7SCristina Ciocan PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), 177c8f5c4c7SCristina Ciocan PINCTRL_PIN(66, "SIO_SPI_CS"), 178c8f5c4c7SCristina Ciocan PINCTRL_PIN(67, "SIO_SPI_MISO"), 179c8f5c4c7SCristina Ciocan PINCTRL_PIN(68, "SIO_SPI_MOSI"), 180c8f5c4c7SCristina Ciocan PINCTRL_PIN(69, "SIO_SPI_CLK"), 181c8f5c4c7SCristina Ciocan PINCTRL_PIN(70, "SIO_UART1_RXD"), 182c8f5c4c7SCristina Ciocan PINCTRL_PIN(71, "SIO_UART1_TXD"), 183c8f5c4c7SCristina Ciocan PINCTRL_PIN(72, "SIO_UART1_RTS"), 184c8f5c4c7SCristina Ciocan PINCTRL_PIN(73, "SIO_UART1_CTS"), 185c8f5c4c7SCristina Ciocan PINCTRL_PIN(74, "SIO_UART2_RXD"), 186c8f5c4c7SCristina Ciocan PINCTRL_PIN(75, "SIO_UART2_TXD"), 187c8f5c4c7SCristina Ciocan PINCTRL_PIN(76, "SIO_UART2_RTS"), 188c8f5c4c7SCristina Ciocan PINCTRL_PIN(77, "SIO_UART2_CTS"), 189c8f5c4c7SCristina Ciocan PINCTRL_PIN(78, "SIO_I2C0_DATA"), 190c8f5c4c7SCristina Ciocan PINCTRL_PIN(79, "SIO_I2C0_CLK"), 191c8f5c4c7SCristina Ciocan PINCTRL_PIN(80, "SIO_I2C1_DATA"), 192c8f5c4c7SCristina Ciocan PINCTRL_PIN(81, "SIO_I2C1_CLK"), 193c8f5c4c7SCristina Ciocan PINCTRL_PIN(82, "SIO_I2C2_DATA"), 194c8f5c4c7SCristina Ciocan PINCTRL_PIN(83, "SIO_I2C2_CLK"), 195c8f5c4c7SCristina Ciocan PINCTRL_PIN(84, "SIO_I2C3_DATA"), 196c8f5c4c7SCristina Ciocan PINCTRL_PIN(85, "SIO_I2C3_CLK"), 197c8f5c4c7SCristina Ciocan PINCTRL_PIN(86, "SIO_I2C4_DATA"), 198c8f5c4c7SCristina Ciocan PINCTRL_PIN(87, "SIO_I2C4_CLK"), 199c8f5c4c7SCristina Ciocan PINCTRL_PIN(88, "SIO_I2C5_DATA"), 200c8f5c4c7SCristina Ciocan PINCTRL_PIN(89, "SIO_I2C5_CLK"), 201c8f5c4c7SCristina Ciocan PINCTRL_PIN(90, "SIO_I2C6_DATA"), 202c8f5c4c7SCristina Ciocan PINCTRL_PIN(91, "SIO_I2C6_CLK"), 203c8f5c4c7SCristina Ciocan PINCTRL_PIN(92, "GPIO_S0_SC92"), 204c8f5c4c7SCristina Ciocan PINCTRL_PIN(93, "GPIO_S0_SC93"), 205c8f5c4c7SCristina Ciocan PINCTRL_PIN(94, "SIO_PWM0"), 206c8f5c4c7SCristina Ciocan PINCTRL_PIN(95, "SIO_PWM1"), 207c8f5c4c7SCristina Ciocan PINCTRL_PIN(96, "PMC_PLT_CLK0"), 208c8f5c4c7SCristina Ciocan PINCTRL_PIN(97, "PMC_PLT_CLK1"), 209c8f5c4c7SCristina Ciocan PINCTRL_PIN(98, "PMC_PLT_CLK2"), 210c8f5c4c7SCristina Ciocan PINCTRL_PIN(99, "PMC_PLT_CLK3"), 211c8f5c4c7SCristina Ciocan PINCTRL_PIN(100, "PMC_PLT_CLK4"), 212c8f5c4c7SCristina Ciocan PINCTRL_PIN(101, "PMC_PLT_CLK5"), 213c8f5c4c7SCristina Ciocan }; 2145fae8b86SMika Westerberg 215c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { 216c8f5c4c7SCristina Ciocan 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 217c8f5c4c7SCristina Ciocan 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, 218c8f5c4c7SCristina Ciocan 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, 219c8f5c4c7SCristina Ciocan 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 220c8f5c4c7SCristina Ciocan 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, 221c8f5c4c7SCristina Ciocan 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, 222c8f5c4c7SCristina Ciocan 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 223c8f5c4c7SCristina Ciocan 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, 224c8f5c4c7SCristina Ciocan 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 225c8f5c4c7SCristina Ciocan 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, 226c8f5c4c7SCristina Ciocan 97, 100, 2275fae8b86SMika Westerberg }; 2285fae8b86SMika Westerberg 229c8f5c4c7SCristina Ciocan /* SCORE groups */ 230c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; 231c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; 232c8f5c4c7SCristina Ciocan 233c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 }; 234c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 }; 235c8f5c4c7SCristina Ciocan 236c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; 237c8f5c4c7SCristina Ciocan 238c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; 239c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; 240c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; 241c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; 242c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; 243c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; 244c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; 245c8f5c4c7SCristina Ciocan 246c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; 247c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; 248c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; 249c8f5c4c7SCristina Ciocan 250c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = { 251c8f5c4c7SCristina Ciocan 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 252c8f5c4c7SCristina Ciocan }; 2534f010b93SAndy Shevchenko static const unsigned int byt_score_sdcard_mux_values[] = { 254c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 255c8f5c4c7SCristina Ciocan }; 256c8f5c4c7SCristina Ciocan 257c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; 258c8f5c4c7SCristina Ciocan 259c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = { 260c8f5c4c7SCristina Ciocan 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 261c8f5c4c7SCristina Ciocan }; 262c8f5c4c7SCristina Ciocan 263c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = { 264c8f5c4c7SCristina Ciocan 42, 43, 44, 45, 46, 47, 48, 49, 50, 265c8f5c4c7SCristina Ciocan }; 266c8f5c4c7SCristina Ciocan 267c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; 268c8f5c4c7SCristina Ciocan 269c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 }; 270c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 }; 271c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 }; 272b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 }; 273b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 }; 274b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 }; 275c8f5c4c7SCristina Ciocan 276c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; 277c8f5c4c7SCristina Ciocan 2784f010b93SAndy Shevchenko static const struct intel_pingroup byt_score_groups[] = { 2794f010b93SAndy Shevchenko PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1), 2804f010b93SAndy Shevchenko PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1), 2814f010b93SAndy Shevchenko PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1), 2824f010b93SAndy Shevchenko PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1), 2834f010b93SAndy Shevchenko PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1), 2844f010b93SAndy Shevchenko PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1), 2854f010b93SAndy Shevchenko PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1), 2864f010b93SAndy Shevchenko PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1), 2874f010b93SAndy Shevchenko PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1), 2884f010b93SAndy Shevchenko PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1), 2894f010b93SAndy Shevchenko PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1), 2904f010b93SAndy Shevchenko PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1), 2914f010b93SAndy Shevchenko PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1), 2924f010b93SAndy Shevchenko PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1), 2934f010b93SAndy Shevchenko PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1), 2944f010b93SAndy Shevchenko PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values), 2954f010b93SAndy Shevchenko PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1), 2964f010b93SAndy Shevchenko PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1), 2974f010b93SAndy Shevchenko PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1), 2984f010b93SAndy Shevchenko PIN_GROUP("sata_grp", byt_score_sata_pins, 1), 2994f010b93SAndy Shevchenko PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1), 3004f010b93SAndy Shevchenko PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1), 3014f010b93SAndy Shevchenko PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1), 3024f010b93SAndy Shevchenko PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1), 3034f010b93SAndy Shevchenko PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1), 3044f010b93SAndy Shevchenko PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1), 3054f010b93SAndy Shevchenko PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1), 306c8f5c4c7SCristina Ciocan }; 307c8f5c4c7SCristina Ciocan 308c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = { 309c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", 310c8f5c4c7SCristina Ciocan }; 311c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = { 312c8f5c4c7SCristina Ciocan "pwm0_grp", "pwm1_grp", 313c8f5c4c7SCristina Ciocan }; 314c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = { 315c8f5c4c7SCristina Ciocan "ssp0_grp", "ssp1_grp", "ssp2_grp", 316c8f5c4c7SCristina Ciocan }; 317c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; 318c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = { 319c8f5c4c7SCristina Ciocan "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", 320c8f5c4c7SCristina Ciocan "i2c6_grp", 321c8f5c4c7SCristina Ciocan }; 322c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; 323c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" }; 324c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" }; 325c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" }; 326c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" }; 327c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = { 328c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 329c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", 330c8f5c4c7SCristina Ciocan }; 331c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" }; 332c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = { 333c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", 334c8f5c4c7SCristina Ciocan "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", 335c8f5c4c7SCristina Ciocan "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", 336c8f5c4c7SCristina Ciocan "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", 337c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 338c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", 339c8f5c4c7SCristina Ciocan }; 340c8f5c4c7SCristina Ciocan 3414f010b93SAndy Shevchenko static const struct intel_function byt_score_functions[] = { 342c8f5c4c7SCristina Ciocan FUNCTION("uart", byt_score_uart_groups), 343c8f5c4c7SCristina Ciocan FUNCTION("pwm", byt_score_pwm_groups), 344c8f5c4c7SCristina Ciocan FUNCTION("ssp", byt_score_ssp_groups), 345c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_score_spi_groups), 346c8f5c4c7SCristina Ciocan FUNCTION("i2c", byt_score_i2c_groups), 347c8f5c4c7SCristina Ciocan FUNCTION("sdcard", byt_score_sdcard_groups), 348c8f5c4c7SCristina Ciocan FUNCTION("sdio", byt_score_sdio_groups), 349c8f5c4c7SCristina Ciocan FUNCTION("emmc", byt_score_emmc_groups), 350c8f5c4c7SCristina Ciocan FUNCTION("lpc", byt_score_lpc_groups), 351c8f5c4c7SCristina Ciocan FUNCTION("sata", byt_score_sata_groups), 352c8f5c4c7SCristina Ciocan FUNCTION("plt_clk", byt_score_plt_clk_groups), 353c8f5c4c7SCristina Ciocan FUNCTION("smbus", byt_score_smbus_groups), 354c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_score_gpio_groups), 355c8f5c4c7SCristina Ciocan }; 356c8f5c4c7SCristina Ciocan 35734e65670SAndy Shevchenko static const struct intel_community byt_score_communities[] = { 358c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), 359c8f5c4c7SCristina Ciocan }; 360c8f5c4c7SCristina Ciocan 36134e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_score_soc_data = { 362c8f5c4c7SCristina Ciocan .uid = BYT_SCORE_ACPI_UID, 363c8f5c4c7SCristina Ciocan .pins = byt_score_pins, 364c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_score_pins), 365c8f5c4c7SCristina Ciocan .groups = byt_score_groups, 366c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_score_groups), 367c8f5c4c7SCristina Ciocan .functions = byt_score_functions, 368c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_score_functions), 369c8f5c4c7SCristina Ciocan .communities = byt_score_communities, 370c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_score_communities), 371c8f5c4c7SCristina Ciocan }; 372c8f5c4c7SCristina Ciocan 373c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */ 374c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = { 375c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_S50"), 376c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_S51"), 377c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_S52"), 378c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_S53"), 379c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_S54"), 380c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_S55"), 381c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_S56"), 382c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_S57"), 383c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_S58"), 384c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_S59"), 385c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_S510"), 386c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), 387c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "PMC_SUSCLK0"), 388c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_S513"), 389c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "USB_ULPI_RST"), 390c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), 391c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "PMC_PWRBTN"), 392c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_S517"), 393c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "PMC_SUS_STAT"), 394c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "USB_OC0"), 395c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "USB_OC1"), 396c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "PCU_SPI_CS1"), 397c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_S522"), 398c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_S523"), 399c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_S524"), 400c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_S525"), 401c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_S526"), 402c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_S527"), 403c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "GPIO_S528"), 404c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "GPIO_S529"), 405c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "GPIO_S530"), 406c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "USB_ULPI_CLK"), 407c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "USB_ULPI_DATA0"), 408c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "USB_ULPI_DATA1"), 409c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "USB_ULPI_DATA2"), 410c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "USB_ULPI_DATA3"), 411c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "USB_ULPI_DATA4"), 412c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "USB_ULPI_DATA5"), 413c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "USB_ULPI_DATA6"), 414c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "USB_ULPI_DATA7"), 415c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "USB_ULPI_DIR"), 416c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "USB_ULPI_NXT"), 417c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "USB_ULPI_STP"), 418c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "USB_ULPI_REFCLK"), 419c8f5c4c7SCristina Ciocan }; 420c8f5c4c7SCristina Ciocan 421c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 422c8f5c4c7SCristina Ciocan 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 423c8f5c4c7SCristina Ciocan 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, 424c8f5c4c7SCristina Ciocan 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 425c8f5c4c7SCristina Ciocan 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, 426c8f5c4c7SCristina Ciocan 52, 53, 59, 40, 427c8f5c4c7SCristina Ciocan }; 428c8f5c4c7SCristina Ciocan 429c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; 4304f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 }; 4314f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 }; 432c8f5c4c7SCristina Ciocan 433c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = { 434c8f5c4c7SCristina Ciocan 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 435c8f5c4c7SCristina Ciocan }; 4364f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_mode_values[] = { 437c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 438c8f5c4c7SCristina Ciocan }; 4394f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = { 4404f010b93SAndy Shevchenko 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 441c8f5c4c7SCristina Ciocan }; 442c8f5c4c7SCristina Ciocan 443c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; 4444f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 }; 4454f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 }; 446c8f5c4c7SCristina Ciocan 4472f46d7f7SHans de Goede static const unsigned int byt_sus_pmu_clk1_pins[] = { 5 }; 4482f46d7f7SHans de Goede static const unsigned int byt_sus_pmu_clk2_pins[] = { 6 }; 4492f46d7f7SHans de Goede 4504f010b93SAndy Shevchenko static const struct intel_pingroup byt_sus_groups[] = { 4514f010b93SAndy Shevchenko PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values), 4524f010b93SAndy Shevchenko PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values), 4534f010b93SAndy Shevchenko PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values), 4544f010b93SAndy Shevchenko PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values), 4554f010b93SAndy Shevchenko PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values), 4564f010b93SAndy Shevchenko PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values), 4572f46d7f7SHans de Goede PIN_GROUP("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1), 4582f46d7f7SHans de Goede PIN_GROUP("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1), 459c8f5c4c7SCristina Ciocan }; 460c8f5c4c7SCristina Ciocan 461c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = { 462c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp", 463c8f5c4c7SCristina Ciocan }; 464c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; 4652f46d7f7SHans de Goede static const char * const byt_sus_pmu_clk_groups[] = { 4662f46d7f7SHans de Goede "pmu_clk1_grp", "pmu_clk2_grp", 4672f46d7f7SHans de Goede }; 468c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = { 4694f010b93SAndy Shevchenko "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio", 4702f46d7f7SHans de Goede "pmu_clk1_grp", "pmu_clk2_grp", 471c8f5c4c7SCristina Ciocan }; 472c8f5c4c7SCristina Ciocan 4734f010b93SAndy Shevchenko static const struct intel_function byt_sus_functions[] = { 474c8f5c4c7SCristina Ciocan FUNCTION("usb", byt_sus_usb_groups), 475c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_sus_spi_groups), 476c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_sus_gpio_groups), 4772f46d7f7SHans de Goede FUNCTION("pmu_clk", byt_sus_pmu_clk_groups), 478c8f5c4c7SCristina Ciocan }; 479c8f5c4c7SCristina Ciocan 48034e65670SAndy Shevchenko static const struct intel_community byt_sus_communities[] = { 481c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), 482c8f5c4c7SCristina Ciocan }; 483c8f5c4c7SCristina Ciocan 48434e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_sus_soc_data = { 485c8f5c4c7SCristina Ciocan .uid = BYT_SUS_ACPI_UID, 486c8f5c4c7SCristina Ciocan .pins = byt_sus_pins, 487c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_sus_pins), 488c8f5c4c7SCristina Ciocan .groups = byt_sus_groups, 489c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_sus_groups), 490c8f5c4c7SCristina Ciocan .functions = byt_sus_functions, 491c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_sus_functions), 492c8f5c4c7SCristina Ciocan .communities = byt_sus_communities, 493c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_sus_communities), 494c8f5c4c7SCristina Ciocan }; 495c8f5c4c7SCristina Ciocan 496c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = { 497b30b736aSAndy Shevchenko PINCTRL_PIN(0, "HV_DDI0_HPD"), 498b30b736aSAndy Shevchenko PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"), 499b30b736aSAndy Shevchenko PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"), 500b30b736aSAndy Shevchenko PINCTRL_PIN(3, "PANEL0_VDDEN"), 501b30b736aSAndy Shevchenko PINCTRL_PIN(4, "PANEL0_BKLTEN"), 502b30b736aSAndy Shevchenko PINCTRL_PIN(5, "PANEL0_BKLTCTL"), 503b30b736aSAndy Shevchenko PINCTRL_PIN(6, "HV_DDI1_HPD"), 504b30b736aSAndy Shevchenko PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"), 505b30b736aSAndy Shevchenko PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"), 506b30b736aSAndy Shevchenko PINCTRL_PIN(9, "PANEL1_VDDEN"), 507b30b736aSAndy Shevchenko PINCTRL_PIN(10, "PANEL1_BKLTEN"), 508b30b736aSAndy Shevchenko PINCTRL_PIN(11, "PANEL1_BKLTCTL"), 509b30b736aSAndy Shevchenko PINCTRL_PIN(12, "GP_INTD_DSI_TE1"), 510b30b736aSAndy Shevchenko PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"), 511b30b736aSAndy Shevchenko PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"), 512b30b736aSAndy Shevchenko PINCTRL_PIN(15, "GP_CAMERASB00"), 513b30b736aSAndy Shevchenko PINCTRL_PIN(16, "GP_CAMERASB01"), 514b30b736aSAndy Shevchenko PINCTRL_PIN(17, "GP_CAMERASB02"), 515b30b736aSAndy Shevchenko PINCTRL_PIN(18, "GP_CAMERASB03"), 516b30b736aSAndy Shevchenko PINCTRL_PIN(19, "GP_CAMERASB04"), 517b30b736aSAndy Shevchenko PINCTRL_PIN(20, "GP_CAMERASB05"), 518b30b736aSAndy Shevchenko PINCTRL_PIN(21, "GP_CAMERASB06"), 519b30b736aSAndy Shevchenko PINCTRL_PIN(22, "GP_CAMERASB07"), 520b30b736aSAndy Shevchenko PINCTRL_PIN(23, "GP_CAMERASB08"), 521b30b736aSAndy Shevchenko PINCTRL_PIN(24, "GP_CAMERASB09"), 522b30b736aSAndy Shevchenko PINCTRL_PIN(25, "GP_CAMERASB10"), 523b30b736aSAndy Shevchenko PINCTRL_PIN(26, "GP_CAMERASB11"), 524b30b736aSAndy Shevchenko PINCTRL_PIN(27, "GP_INTD_DSI_TE2"), 525c8f5c4c7SCristina Ciocan }; 526c8f5c4c7SCristina Ciocan 527939330d7SAndy Shevchenko static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 528c8f5c4c7SCristina Ciocan 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 529c8f5c4c7SCristina Ciocan 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, 530c8f5c4c7SCristina Ciocan 3, 6, 10, 13, 2, 5, 9, 7, 531c8f5c4c7SCristina Ciocan }; 532c8f5c4c7SCristina Ciocan 53334e65670SAndy Shevchenko static const struct intel_community byt_ncore_communities[] = { 534c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), 535c8f5c4c7SCristina Ciocan }; 536c8f5c4c7SCristina Ciocan 53734e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data byt_ncore_soc_data = { 538c8f5c4c7SCristina Ciocan .uid = BYT_NCORE_ACPI_UID, 539c8f5c4c7SCristina Ciocan .pins = byt_ncore_pins, 540c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_ncore_pins), 541c8f5c4c7SCristina Ciocan .communities = byt_ncore_communities, 542c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_ncore_communities), 543c8f5c4c7SCristina Ciocan }; 544c8f5c4c7SCristina Ciocan 54534e65670SAndy Shevchenko static const struct intel_pinctrl_soc_data *byt_soc_data[] = { 546c8f5c4c7SCristina Ciocan &byt_score_soc_data, 547c8f5c4c7SCristina Ciocan &byt_sus_soc_data, 548c8f5c4c7SCristina Ciocan &byt_ncore_soc_data, 549166d6e2aSAndy Shevchenko NULL 550c8f5c4c7SCristina Ciocan }; 551c8f5c4c7SCristina Ciocan 55240ecab55SHans de Goede static DEFINE_RAW_SPINLOCK(byt_lock); 55340ecab55SHans de Goede 5545d33e0ebSAndy Shevchenko static struct intel_community *byt_get_community(struct intel_pinctrl *vg, 555c501d0b1SCristina Ciocan unsigned int pin) 556c501d0b1SCristina Ciocan { 55734e65670SAndy Shevchenko struct intel_community *comm; 558c501d0b1SCristina Ciocan int i; 559c501d0b1SCristina Ciocan 5605d33e0ebSAndy Shevchenko for (i = 0; i < vg->ncommunities; i++) { 5615d33e0ebSAndy Shevchenko comm = vg->communities + i; 562c501d0b1SCristina Ciocan if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) 563c501d0b1SCristina Ciocan return comm; 564c501d0b1SCristina Ciocan } 565c501d0b1SCristina Ciocan 566c501d0b1SCristina Ciocan return NULL; 567c501d0b1SCristina Ciocan } 568c501d0b1SCristina Ciocan 5695d33e0ebSAndy Shevchenko static void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset, 5705fae8b86SMika Westerberg int reg) 5715fae8b86SMika Westerberg { 57234e65670SAndy Shevchenko struct intel_community *comm = byt_get_community(vg, offset); 5731b89970dSAndy Shevchenko u32 reg_offset; 5745fae8b86SMika Westerberg 575c501d0b1SCristina Ciocan if (!comm) 576c501d0b1SCristina Ciocan return NULL; 577c501d0b1SCristina Ciocan 578c501d0b1SCristina Ciocan offset -= comm->pin_base; 5791b89970dSAndy Shevchenko switch (reg) { 5801b89970dSAndy Shevchenko case BYT_INT_STAT_REG: 5815fae8b86SMika Westerberg reg_offset = (offset / 32) * 4; 5821b89970dSAndy Shevchenko break; 5831b89970dSAndy Shevchenko case BYT_DEBOUNCE_REG: 5841b89970dSAndy Shevchenko reg_offset = 0; 5851b89970dSAndy Shevchenko break; 5861b89970dSAndy Shevchenko default: 587c501d0b1SCristina Ciocan reg_offset = comm->pad_map[offset] * 16; 5881b89970dSAndy Shevchenko break; 5891b89970dSAndy Shevchenko } 5905fae8b86SMika Westerberg 59134e65670SAndy Shevchenko return comm->pad_regs + reg_offset + reg; 5925fae8b86SMika Westerberg } 5935fae8b86SMika Westerberg 594c501d0b1SCristina Ciocan static int byt_get_groups_count(struct pinctrl_dev *pctldev) 59595f0972cSMika Westerberg { 5965d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 597c501d0b1SCristina Ciocan 5985d33e0ebSAndy Shevchenko return vg->soc->ngroups; 599c501d0b1SCristina Ciocan } 600c501d0b1SCristina Ciocan 601c501d0b1SCristina Ciocan static const char *byt_get_group_name(struct pinctrl_dev *pctldev, 602c501d0b1SCristina Ciocan unsigned int selector) 603c501d0b1SCristina Ciocan { 6045d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 605c501d0b1SCristina Ciocan 606770f53d4SAndy Shevchenko return vg->soc->groups[selector].grp.name; 607c501d0b1SCristina Ciocan } 608c501d0b1SCristina Ciocan 609c501d0b1SCristina Ciocan static int byt_get_group_pins(struct pinctrl_dev *pctldev, 610c501d0b1SCristina Ciocan unsigned int selector, 611c501d0b1SCristina Ciocan const unsigned int **pins, 612c501d0b1SCristina Ciocan unsigned int *num_pins) 613c501d0b1SCristina Ciocan { 6145d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 615c501d0b1SCristina Ciocan 616770f53d4SAndy Shevchenko *pins = vg->soc->groups[selector].grp.pins; 617770f53d4SAndy Shevchenko *num_pins = vg->soc->groups[selector].grp.npins; 618c501d0b1SCristina Ciocan 619c501d0b1SCristina Ciocan return 0; 620c501d0b1SCristina Ciocan } 621c501d0b1SCristina Ciocan 622c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = { 623c501d0b1SCristina Ciocan .get_groups_count = byt_get_groups_count, 624c501d0b1SCristina Ciocan .get_group_name = byt_get_group_name, 625c501d0b1SCristina Ciocan .get_group_pins = byt_get_group_pins, 626c501d0b1SCristina Ciocan }; 627c501d0b1SCristina Ciocan 628c501d0b1SCristina Ciocan static int byt_get_functions_count(struct pinctrl_dev *pctldev) 629c501d0b1SCristina Ciocan { 6305d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 631c501d0b1SCristina Ciocan 6325d33e0ebSAndy Shevchenko return vg->soc->nfunctions; 633c501d0b1SCristina Ciocan } 634c501d0b1SCristina Ciocan 635c501d0b1SCristina Ciocan static const char *byt_get_function_name(struct pinctrl_dev *pctldev, 636c501d0b1SCristina Ciocan unsigned int selector) 637c501d0b1SCristina Ciocan { 6385d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 639c501d0b1SCristina Ciocan 640988ac1a4SAndy Shevchenko return vg->soc->functions[selector].func.name; 641c501d0b1SCristina Ciocan } 642c501d0b1SCristina Ciocan 643c501d0b1SCristina Ciocan static int byt_get_function_groups(struct pinctrl_dev *pctldev, 644c501d0b1SCristina Ciocan unsigned int selector, 645c501d0b1SCristina Ciocan const char * const **groups, 646988ac1a4SAndy Shevchenko unsigned int *ngroups) 647c501d0b1SCristina Ciocan { 6485d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 649c501d0b1SCristina Ciocan 650988ac1a4SAndy Shevchenko *groups = vg->soc->functions[selector].func.groups; 651988ac1a4SAndy Shevchenko *ngroups = vg->soc->functions[selector].func.ngroups; 652c501d0b1SCristina Ciocan 653c501d0b1SCristina Ciocan return 0; 654c501d0b1SCristina Ciocan } 655c501d0b1SCristina Ciocan 6565d33e0ebSAndy Shevchenko static void byt_set_group_simple_mux(struct intel_pinctrl *vg, 6574f010b93SAndy Shevchenko const struct intel_pingroup group, 6584f010b93SAndy Shevchenko unsigned int func) 659c501d0b1SCristina Ciocan { 660c501d0b1SCristina Ciocan unsigned long flags; 661c501d0b1SCristina Ciocan int i; 662c501d0b1SCristina Ciocan 66340ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 664c501d0b1SCristina Ciocan 665770f53d4SAndy Shevchenko for (i = 0; i < group.grp.npins; i++) { 666c501d0b1SCristina Ciocan void __iomem *padcfg0; 667c501d0b1SCristina Ciocan u32 value; 668c501d0b1SCristina Ciocan 669770f53d4SAndy Shevchenko padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG); 670c501d0b1SCristina Ciocan if (!padcfg0) { 671b9e18434SAndy Shevchenko dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n", 672770f53d4SAndy Shevchenko group.grp.name, i); 673c501d0b1SCristina Ciocan continue; 674c501d0b1SCristina Ciocan } 675c501d0b1SCristina Ciocan 676c501d0b1SCristina Ciocan value = readl(padcfg0); 677c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 678c501d0b1SCristina Ciocan value |= func; 679c501d0b1SCristina Ciocan writel(value, padcfg0); 680c501d0b1SCristina Ciocan } 681c501d0b1SCristina Ciocan 68240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 683c501d0b1SCristina Ciocan } 684c501d0b1SCristina Ciocan 6855d33e0ebSAndy Shevchenko static void byt_set_group_mixed_mux(struct intel_pinctrl *vg, 6864f010b93SAndy Shevchenko const struct intel_pingroup group, 6874f010b93SAndy Shevchenko const unsigned int *func) 688c501d0b1SCristina Ciocan { 689c501d0b1SCristina Ciocan unsigned long flags; 690c501d0b1SCristina Ciocan int i; 691c501d0b1SCristina Ciocan 69240ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 693c501d0b1SCristina Ciocan 694770f53d4SAndy Shevchenko for (i = 0; i < group.grp.npins; i++) { 695c501d0b1SCristina Ciocan void __iomem *padcfg0; 696c501d0b1SCristina Ciocan u32 value; 697c501d0b1SCristina Ciocan 698770f53d4SAndy Shevchenko padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG); 699c501d0b1SCristina Ciocan if (!padcfg0) { 700b9e18434SAndy Shevchenko dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n", 701770f53d4SAndy Shevchenko group.grp.name, i); 702c501d0b1SCristina Ciocan continue; 703c501d0b1SCristina Ciocan } 704c501d0b1SCristina Ciocan 705c501d0b1SCristina Ciocan value = readl(padcfg0); 706c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 707c501d0b1SCristina Ciocan value |= func[i]; 708c501d0b1SCristina Ciocan writel(value, padcfg0); 709c501d0b1SCristina Ciocan } 710c501d0b1SCristina Ciocan 71140ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 712c501d0b1SCristina Ciocan } 713c501d0b1SCristina Ciocan 714c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 715c501d0b1SCristina Ciocan unsigned int group_selector) 716c501d0b1SCristina Ciocan { 7175d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 7185d33e0ebSAndy Shevchenko const struct intel_function func = vg->soc->functions[func_selector]; 7195d33e0ebSAndy Shevchenko const struct intel_pingroup group = vg->soc->groups[group_selector]; 720c501d0b1SCristina Ciocan 7214f010b93SAndy Shevchenko if (group.modes) 7224f010b93SAndy Shevchenko byt_set_group_mixed_mux(vg, group, group.modes); 723988ac1a4SAndy Shevchenko else if (!strcmp(func.func.name, "gpio")) 724c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); 725c501d0b1SCristina Ciocan else 7264f010b93SAndy Shevchenko byt_set_group_simple_mux(vg, group, group.mode); 727c501d0b1SCristina Ciocan 728c501d0b1SCristina Ciocan return 0; 729c501d0b1SCristina Ciocan } 730c501d0b1SCristina Ciocan 7315d33e0ebSAndy Shevchenko static u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset) 732c501d0b1SCristina Ciocan { 733c501d0b1SCristina Ciocan /* SCORE pin 92-93 */ 7345d33e0ebSAndy Shevchenko if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) && 735c501d0b1SCristina Ciocan offset >= 92 && offset <= 93) 736a705f9c1SAndy Shevchenko return BYT_ALTER_GPIO_MUX; 737c501d0b1SCristina Ciocan 738c501d0b1SCristina Ciocan /* SUS pin 11-21 */ 7395d33e0ebSAndy Shevchenko if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) && 740c501d0b1SCristina Ciocan offset >= 11 && offset <= 21) 741a705f9c1SAndy Shevchenko return BYT_ALTER_GPIO_MUX; 742c501d0b1SCristina Ciocan 743a705f9c1SAndy Shevchenko return BYT_DEFAULT_GPIO_MUX; 744c501d0b1SCristina Ciocan } 745c501d0b1SCristina Ciocan 7465d33e0ebSAndy Shevchenko static void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset) 747c501d0b1SCristina Ciocan { 748c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 74995f0972cSMika Westerberg unsigned long flags; 75095f0972cSMika Westerberg u32 value; 75195f0972cSMika Westerberg 75240ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 75395f0972cSMika Westerberg value = readl(reg); 754a2368059SHans de Goede 755a2368059SHans de Goede /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */ 756a2368059SHans de Goede if (value & BYT_DIRECT_IRQ_EN) 757a2368059SHans de Goede /* nothing to do */ ; 758a2368059SHans de Goede else 75995f0972cSMika Westerberg value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); 760a2368059SHans de Goede 76195f0972cSMika Westerberg writel(value, reg); 76240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 76395f0972cSMika Westerberg } 76495f0972cSMika Westerberg 765c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, 766c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 767c501d0b1SCristina Ciocan unsigned int offset) 7685fae8b86SMika Westerberg { 7695d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 770c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 771f8323b6bSMika Westerberg u32 value, gpio_mux; 77239ce8150SMika Westerberg unsigned long flags; 77339ce8150SMika Westerberg 77440ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 7755fae8b86SMika Westerberg 7765fae8b86SMika Westerberg /* 7775fae8b86SMika Westerberg * In most cases, func pin mux 000 means GPIO function. 7785fae8b86SMika Westerberg * But, some pins may have func pin mux 001 represents 779f8323b6bSMika Westerberg * GPIO function. 780f8323b6bSMika Westerberg * 781f8323b6bSMika Westerberg * Because there are devices out there where some pins were not 782f8323b6bSMika Westerberg * configured correctly we allow changing the mux value from 783f8323b6bSMika Westerberg * request (but print out warning about that). 7845fae8b86SMika Westerberg */ 7855fae8b86SMika Westerberg value = readl(reg) & BYT_PIN_MUX; 786f8323b6bSMika Westerberg gpio_mux = byt_get_gpio_mux(vg, offset); 787b5894d12SHans de Goede if (gpio_mux != value) { 788f8323b6bSMika Westerberg value = readl(reg) & ~BYT_PIN_MUX; 789f8323b6bSMika Westerberg value |= gpio_mux; 790f8323b6bSMika Westerberg writel(value, reg); 791f8323b6bSMika Westerberg 792b9e18434SAndy Shevchenko dev_warn(vg->dev, FW_BUG "Pin %i: forcibly re-configured as GPIO\n", offset); 7935fae8b86SMika Westerberg } 7945fae8b86SMika Westerberg 79540ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 79639ce8150SMika Westerberg 797990ec243SAndy Shevchenko pm_runtime_get(vg->dev); 7985fae8b86SMika Westerberg 7995fae8b86SMika Westerberg return 0; 8005fae8b86SMika Westerberg } 8015fae8b86SMika Westerberg 802c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, 803c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 804c501d0b1SCristina Ciocan unsigned int offset) 805c501d0b1SCristina Ciocan { 8065d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 807c501d0b1SCristina Ciocan 808c501d0b1SCristina Ciocan byt_gpio_clear_triggering(vg, offset); 809990ec243SAndy Shevchenko pm_runtime_put(vg->dev); 810c501d0b1SCristina Ciocan } 811c501d0b1SCristina Ciocan 812156abe29SHans de Goede static void byt_gpio_direct_irq_check(struct intel_pinctrl *vg, 813156abe29SHans de Goede unsigned int offset) 814156abe29SHans de Goede { 815156abe29SHans de Goede void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 816156abe29SHans de Goede 817156abe29SHans de Goede /* 818156abe29SHans de Goede * Before making any direction modifications, do a check if gpio is set 819156abe29SHans de Goede * for direct IRQ. On Bay Trail, setting GPIO to output does not make 820156abe29SHans de Goede * sense, so let's at least inform the caller before they shoot 821156abe29SHans de Goede * themselves in the foot. 822156abe29SHans de Goede */ 823156abe29SHans de Goede if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) 824b9e18434SAndy Shevchenko dev_info_once(vg->dev, 825b9e18434SAndy Shevchenko "Potential Error: Pin %i: forcibly set GPIO with DIRECT_IRQ_EN to output\n", 826b9e18434SAndy Shevchenko offset); 827156abe29SHans de Goede } 828156abe29SHans de Goede 829c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, 830c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 831c501d0b1SCristina Ciocan unsigned int offset, 832c501d0b1SCristina Ciocan bool input) 833c501d0b1SCristina Ciocan { 8345d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 835c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 836c501d0b1SCristina Ciocan unsigned long flags; 837c501d0b1SCristina Ciocan u32 value; 838c501d0b1SCristina Ciocan 83940ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 840c501d0b1SCristina Ciocan 841c501d0b1SCristina Ciocan value = readl(val_reg); 842c501d0b1SCristina Ciocan value &= ~BYT_DIR_MASK; 843c501d0b1SCristina Ciocan if (input) 844c501d0b1SCristina Ciocan value |= BYT_OUTPUT_EN; 845156abe29SHans de Goede else 846156abe29SHans de Goede byt_gpio_direct_irq_check(vg, offset); 847e2b74419SHans de Goede 848c501d0b1SCristina Ciocan writel(value, val_reg); 849c501d0b1SCristina Ciocan 85040ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 851c501d0b1SCristina Ciocan 852c501d0b1SCristina Ciocan return 0; 853c501d0b1SCristina Ciocan } 854c501d0b1SCristina Ciocan 855c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = { 856c501d0b1SCristina Ciocan .get_functions_count = byt_get_functions_count, 857c501d0b1SCristina Ciocan .get_function_name = byt_get_function_name, 858c501d0b1SCristina Ciocan .get_function_groups = byt_get_function_groups, 859c501d0b1SCristina Ciocan .set_mux = byt_set_mux, 860c501d0b1SCristina Ciocan .gpio_request_enable = byt_gpio_request_enable, 861c501d0b1SCristina Ciocan .gpio_disable_free = byt_gpio_disable_free, 862c501d0b1SCristina Ciocan .gpio_set_direction = byt_gpio_set_direction, 863c501d0b1SCristina Ciocan }; 864c501d0b1SCristina Ciocan 865c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength) 866c501d0b1SCristina Ciocan { 867c501d0b1SCristina Ciocan switch (reg & BYT_PULL_STR_MASK) { 868c501d0b1SCristina Ciocan case BYT_PULL_STR_2K: 869c501d0b1SCristina Ciocan *strength = 2000; 870c501d0b1SCristina Ciocan break; 871c501d0b1SCristina Ciocan case BYT_PULL_STR_10K: 872c501d0b1SCristina Ciocan *strength = 10000; 873c501d0b1SCristina Ciocan break; 874c501d0b1SCristina Ciocan case BYT_PULL_STR_20K: 875c501d0b1SCristina Ciocan *strength = 20000; 876c501d0b1SCristina Ciocan break; 877c501d0b1SCristina Ciocan case BYT_PULL_STR_40K: 878c501d0b1SCristina Ciocan *strength = 40000; 879c501d0b1SCristina Ciocan break; 880c501d0b1SCristina Ciocan } 881c501d0b1SCristina Ciocan } 882c501d0b1SCristina Ciocan 883c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength) 884c501d0b1SCristina Ciocan { 885c501d0b1SCristina Ciocan *reg &= ~BYT_PULL_STR_MASK; 886c501d0b1SCristina Ciocan 887c501d0b1SCristina Ciocan switch (strength) { 888c501d0b1SCristina Ciocan case 2000: 889c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_2K; 890c501d0b1SCristina Ciocan break; 891c501d0b1SCristina Ciocan case 10000: 892c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_10K; 893c501d0b1SCristina Ciocan break; 894c501d0b1SCristina Ciocan case 20000: 895c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_20K; 896c501d0b1SCristina Ciocan break; 897c501d0b1SCristina Ciocan case 40000: 898c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_40K; 899c501d0b1SCristina Ciocan break; 900c501d0b1SCristina Ciocan default: 901c501d0b1SCristina Ciocan return -EINVAL; 902c501d0b1SCristina Ciocan } 903c501d0b1SCristina Ciocan 904c501d0b1SCristina Ciocan return 0; 905c501d0b1SCristina Ciocan } 906c501d0b1SCristina Ciocan 907c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, 908c501d0b1SCristina Ciocan unsigned long *config) 909c501d0b1SCristina Ciocan { 9105d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 911c501d0b1SCristina Ciocan enum pin_config_param param = pinconf_to_config_param(*config); 912c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 913c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 91404ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 915c501d0b1SCristina Ciocan unsigned long flags; 916658b476cSCristina Ciocan u32 conf, pull, val, debounce; 917c501d0b1SCristina Ciocan u16 arg = 0; 918c501d0b1SCristina Ciocan 91940ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 920c501d0b1SCristina Ciocan conf = readl(conf_reg); 921c501d0b1SCristina Ciocan pull = conf & BYT_PULL_ASSIGN_MASK; 922c501d0b1SCristina Ciocan val = readl(val_reg); 92340ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 924c501d0b1SCristina Ciocan 925c501d0b1SCristina Ciocan switch (param) { 926c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 927c501d0b1SCristina Ciocan if (pull) 928c501d0b1SCristina Ciocan return -EINVAL; 929c501d0b1SCristina Ciocan break; 930c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 931c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 932c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) 933c501d0b1SCristina Ciocan return -EINVAL; 934c501d0b1SCristina Ciocan 935c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 936c501d0b1SCristina Ciocan 937c501d0b1SCristina Ciocan break; 938c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 939c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 940c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) 941c501d0b1SCristina Ciocan return -EINVAL; 942c501d0b1SCristina Ciocan 943c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 944c501d0b1SCristina Ciocan 945c501d0b1SCristina Ciocan break; 946658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 947658b476cSCristina Ciocan if (!(conf & BYT_DEBOUNCE_EN)) 948658b476cSCristina Ciocan return -EINVAL; 949658b476cSCristina Ciocan 95040ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 95104ff5a09SAndy Shevchenko debounce = readl(db_reg); 95240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 953658b476cSCristina Ciocan 954658b476cSCristina Ciocan switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { 955658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_375US: 956658b476cSCristina Ciocan arg = 375; 957658b476cSCristina Ciocan break; 958658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_750US: 959658b476cSCristina Ciocan arg = 750; 960658b476cSCristina Ciocan break; 961658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_1500US: 962658b476cSCristina Ciocan arg = 1500; 963658b476cSCristina Ciocan break; 964658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_3MS: 965658b476cSCristina Ciocan arg = 3000; 966658b476cSCristina Ciocan break; 967658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_6MS: 968658b476cSCristina Ciocan arg = 6000; 969658b476cSCristina Ciocan break; 970658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_12MS: 971658b476cSCristina Ciocan arg = 12000; 972658b476cSCristina Ciocan break; 973658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_24MS: 974658b476cSCristina Ciocan arg = 24000; 975658b476cSCristina Ciocan break; 976658b476cSCristina Ciocan default: 977658b476cSCristina Ciocan return -EINVAL; 978658b476cSCristina Ciocan } 979658b476cSCristina Ciocan 980658b476cSCristina Ciocan break; 981c501d0b1SCristina Ciocan default: 982c501d0b1SCristina Ciocan return -ENOTSUPP; 983c501d0b1SCristina Ciocan } 984c501d0b1SCristina Ciocan 985c501d0b1SCristina Ciocan *config = pinconf_to_config_packed(param, arg); 986c501d0b1SCristina Ciocan 987c501d0b1SCristina Ciocan return 0; 988c501d0b1SCristina Ciocan } 989c501d0b1SCristina Ciocan 990c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, 991c501d0b1SCristina Ciocan unsigned int offset, 992c501d0b1SCristina Ciocan unsigned long *configs, 993c501d0b1SCristina Ciocan unsigned int num_configs) 994c501d0b1SCristina Ciocan { 9955d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 996c501d0b1SCristina Ciocan unsigned int param, arg; 997c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 998c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 99904ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 1000c501d0b1SCristina Ciocan unsigned long flags; 1001658b476cSCristina Ciocan u32 conf, val, debounce; 1002c501d0b1SCristina Ciocan int i, ret = 0; 1003c501d0b1SCristina Ciocan 100440ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 1005c501d0b1SCristina Ciocan 1006c501d0b1SCristina Ciocan conf = readl(conf_reg); 1007c501d0b1SCristina Ciocan val = readl(val_reg); 1008c501d0b1SCristina Ciocan 1009c501d0b1SCristina Ciocan for (i = 0; i < num_configs; i++) { 1010c501d0b1SCristina Ciocan param = pinconf_to_config_param(configs[i]); 1011c501d0b1SCristina Ciocan arg = pinconf_to_config_argument(configs[i]); 1012c501d0b1SCristina Ciocan 1013c501d0b1SCristina Ciocan switch (param) { 1014c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 1015c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1016c501d0b1SCristina Ciocan break; 1017c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 1018c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1019c501d0b1SCristina Ciocan if (arg == 1) 1020c501d0b1SCristina Ciocan arg = 2000; 1021c501d0b1SCristina Ciocan 1022c501d0b1SCristina Ciocan /* 1023c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1024c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1025c501d0b1SCristina Ciocan */ 1026c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1027c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1028c501d0b1SCristina Ciocan writel(val, val_reg); 1029b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset); 1030c501d0b1SCristina Ciocan } 1031c501d0b1SCristina Ciocan 1032c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1033c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_DOWN; 1034c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1035c501d0b1SCristina Ciocan 1036c501d0b1SCristina Ciocan break; 1037c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 1038c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1039c501d0b1SCristina Ciocan if (arg == 1) 1040c501d0b1SCristina Ciocan arg = 2000; 1041c501d0b1SCristina Ciocan 1042c501d0b1SCristina Ciocan /* 1043c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1044c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1045c501d0b1SCristina Ciocan */ 1046c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1047c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1048c501d0b1SCristina Ciocan writel(val, val_reg); 1049b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset); 1050c501d0b1SCristina Ciocan } 1051c501d0b1SCristina Ciocan 1052c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1053c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_UP; 1054c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1055c501d0b1SCristina Ciocan 1056c501d0b1SCristina Ciocan break; 1057658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 105804ff5a09SAndy Shevchenko debounce = readl(db_reg); 1059658b476cSCristina Ciocan 1060827e1579SAndy Shevchenko if (arg) 1061827e1579SAndy Shevchenko conf |= BYT_DEBOUNCE_EN; 1062827e1579SAndy Shevchenko else 1063827e1579SAndy Shevchenko conf &= ~BYT_DEBOUNCE_EN; 1064827e1579SAndy Shevchenko 1065658b476cSCristina Ciocan switch (arg) { 1066658b476cSCristina Ciocan case 375: 10675f714771SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 106804ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_375US; 1069658b476cSCristina Ciocan break; 1070658b476cSCristina Ciocan case 750: 10715f714771SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 107204ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_750US; 1073658b476cSCristina Ciocan break; 1074658b476cSCristina Ciocan case 1500: 10755f714771SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 107604ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_1500US; 1077658b476cSCristina Ciocan break; 1078658b476cSCristina Ciocan case 3000: 10795f714771SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 108004ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_3MS; 1081658b476cSCristina Ciocan break; 1082658b476cSCristina Ciocan case 6000: 10835f714771SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 108404ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_6MS; 1085658b476cSCristina Ciocan break; 1086658b476cSCristina Ciocan case 12000: 10875f714771SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 108804ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_12MS; 1089658b476cSCristina Ciocan break; 1090658b476cSCristina Ciocan case 24000: 10915f714771SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 109204ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_24MS; 1093658b476cSCristina Ciocan break; 1094658b476cSCristina Ciocan default: 1095827e1579SAndy Shevchenko if (arg) 1096658b476cSCristina Ciocan ret = -EINVAL; 1097827e1579SAndy Shevchenko break; 1098658b476cSCristina Ciocan } 1099658b476cSCristina Ciocan 110004ff5a09SAndy Shevchenko if (!ret) 110104ff5a09SAndy Shevchenko writel(debounce, db_reg); 1102658b476cSCristina Ciocan break; 1103c501d0b1SCristina Ciocan default: 1104c501d0b1SCristina Ciocan ret = -ENOTSUPP; 1105c501d0b1SCristina Ciocan } 1106c501d0b1SCristina Ciocan 1107c501d0b1SCristina Ciocan if (ret) 1108c501d0b1SCristina Ciocan break; 1109c501d0b1SCristina Ciocan } 1110c501d0b1SCristina Ciocan 1111c501d0b1SCristina Ciocan if (!ret) 1112c501d0b1SCristina Ciocan writel(conf, conf_reg); 1113c501d0b1SCristina Ciocan 111440ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 1115c501d0b1SCristina Ciocan 1116c501d0b1SCristina Ciocan return ret; 1117c501d0b1SCristina Ciocan } 1118c501d0b1SCristina Ciocan 1119c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = { 1120c501d0b1SCristina Ciocan .is_generic = true, 1121c501d0b1SCristina Ciocan .pin_config_get = byt_pin_config_get, 1122c501d0b1SCristina Ciocan .pin_config_set = byt_pin_config_set, 1123c501d0b1SCristina Ciocan }; 1124c501d0b1SCristina Ciocan 1125c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = { 1126c501d0b1SCristina Ciocan .pctlops = &byt_pinctrl_ops, 1127c501d0b1SCristina Ciocan .pmxops = &byt_pinmux_ops, 1128c501d0b1SCristina Ciocan .confops = &byt_pinconf_ops, 1129c501d0b1SCristina Ciocan .owner = THIS_MODULE, 1130c501d0b1SCristina Ciocan }; 1131c501d0b1SCristina Ciocan 1132939330d7SAndy Shevchenko static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) 11335fae8b86SMika Westerberg { 11345d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip); 1135c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 113639ce8150SMika Westerberg unsigned long flags; 113739ce8150SMika Westerberg u32 val; 113839ce8150SMika Westerberg 113940ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 114039ce8150SMika Westerberg val = readl(reg); 114140ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 114239ce8150SMika Westerberg 11433bde8771SLinus Walleij return !!(val & BYT_LEVEL); 11445fae8b86SMika Westerberg } 11455fae8b86SMika Westerberg 1146939330d7SAndy Shevchenko static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 11475fae8b86SMika Westerberg { 11485d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip); 1149c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 11505fae8b86SMika Westerberg unsigned long flags; 11515fae8b86SMika Westerberg u32 old_val; 11525fae8b86SMika Westerberg 115386e3ef81SCristina Ciocan if (!reg) 115486e3ef81SCristina Ciocan return; 115586e3ef81SCristina Ciocan 115640ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 11575fae8b86SMika Westerberg old_val = readl(reg); 11585fae8b86SMika Westerberg if (value) 11595fae8b86SMika Westerberg writel(old_val | BYT_LEVEL, reg); 11605fae8b86SMika Westerberg else 11615fae8b86SMika Westerberg writel(old_val & ~BYT_LEVEL, reg); 116240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 11635fae8b86SMika Westerberg } 11645fae8b86SMika Westerberg 116586e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 11665fae8b86SMika Westerberg { 11675d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip); 1168c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 11695fae8b86SMika Westerberg unsigned long flags; 11705fae8b86SMika Westerberg u32 value; 11715fae8b86SMika Westerberg 117286e3ef81SCristina Ciocan if (!reg) 117386e3ef81SCristina Ciocan return -EINVAL; 117486e3ef81SCristina Ciocan 117540ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 117686e3ef81SCristina Ciocan value = readl(reg); 117740ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 11785fae8b86SMika Westerberg 117986e3ef81SCristina Ciocan if (!(value & BYT_OUTPUT_EN)) 1180faf86c0cSMatti Vaittinen return GPIO_LINE_DIRECTION_OUT; 118186e3ef81SCristina Ciocan if (!(value & BYT_INPUT_EN)) 1182faf86c0cSMatti Vaittinen return GPIO_LINE_DIRECTION_IN; 118386e3ef81SCristina Ciocan 118486e3ef81SCristina Ciocan return -EINVAL; 11855fae8b86SMika Westerberg } 11865fae8b86SMika Westerberg 118786e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 11885fae8b86SMika Westerberg { 1189156abe29SHans de Goede struct intel_pinctrl *vg = gpiochip_get_data(chip); 1190156abe29SHans de Goede void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 1191156abe29SHans de Goede unsigned long flags; 1192156abe29SHans de Goede u32 reg; 1193156abe29SHans de Goede 1194156abe29SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 1195156abe29SHans de Goede 1196156abe29SHans de Goede reg = readl(val_reg); 1197156abe29SHans de Goede reg &= ~BYT_DIR_MASK; 1198156abe29SHans de Goede reg |= BYT_OUTPUT_EN; 1199156abe29SHans de Goede writel(reg, val_reg); 1200156abe29SHans de Goede 1201156abe29SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 1202156abe29SHans de Goede return 0; 120386e3ef81SCristina Ciocan } 12045fae8b86SMika Westerberg 1205156abe29SHans de Goede /* 1206156abe29SHans de Goede * Note despite the temptation this MUST NOT be converted into a call to 1207156abe29SHans de Goede * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this 1208156abe29SHans de Goede * MUST be done as a single BYT_VAL_REG register write. 1209156abe29SHans de Goede * See the commit message of the commit adding this comment for details. 1210156abe29SHans de Goede */ 121186e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip, 121286e3ef81SCristina Ciocan unsigned int offset, int value) 121386e3ef81SCristina Ciocan { 1214156abe29SHans de Goede struct intel_pinctrl *vg = gpiochip_get_data(chip); 1215156abe29SHans de Goede void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 1216156abe29SHans de Goede unsigned long flags; 1217156abe29SHans de Goede u32 reg; 12185fae8b86SMika Westerberg 1219156abe29SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 122086e3ef81SCristina Ciocan 1221156abe29SHans de Goede byt_gpio_direct_irq_check(vg, offset); 12225fae8b86SMika Westerberg 1223156abe29SHans de Goede reg = readl(val_reg); 1224156abe29SHans de Goede reg &= ~BYT_DIR_MASK; 1225156abe29SHans de Goede if (value) 1226156abe29SHans de Goede reg |= BYT_LEVEL; 1227156abe29SHans de Goede else 1228156abe29SHans de Goede reg &= ~BYT_LEVEL; 1229156abe29SHans de Goede 1230156abe29SHans de Goede writel(reg, val_reg); 1231156abe29SHans de Goede 1232156abe29SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 12335fae8b86SMika Westerberg return 0; 12345fae8b86SMika Westerberg } 12355fae8b86SMika Westerberg 12365fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 12375fae8b86SMika Westerberg { 12385d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip); 12395fae8b86SMika Westerberg int i; 124086e3ef81SCristina Ciocan u32 conf0, val; 12415fae8b86SMika Westerberg 12425d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->npins; i++) { 124334e65670SAndy Shevchenko const struct intel_community *comm; 12445a9fa4c2SRaag Jadav void __iomem *conf_reg, *val_reg; 12455fae8b86SMika Westerberg const char *pull_str = NULL; 12465fae8b86SMika Westerberg const char *pull = NULL; 124778e1c896SMika Westerberg unsigned long flags; 12485fae8b86SMika Westerberg const char *label; 124986e3ef81SCristina Ciocan unsigned int pin; 125078e1c896SMika Westerberg 12515d33e0ebSAndy Shevchenko pin = vg->soc->pins[i].number; 125286e3ef81SCristina Ciocan 12535a9fa4c2SRaag Jadav conf_reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 12545a9fa4c2SRaag Jadav if (!conf_reg) { 12555a9fa4c2SRaag Jadav seq_printf(s, "Pin %i: can't retrieve CONF0\n", pin); 125622bbd21bSDan Carpenter continue; 125786e3ef81SCristina Ciocan } 12585a9fa4c2SRaag Jadav 12595a9fa4c2SRaag Jadav val_reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 12605a9fa4c2SRaag Jadav if (!val_reg) { 12615a9fa4c2SRaag Jadav seq_printf(s, "Pin %i: can't retrieve VAL\n", pin); 12625a9fa4c2SRaag Jadav continue; 12635a9fa4c2SRaag Jadav } 12645a9fa4c2SRaag Jadav 12655a9fa4c2SRaag Jadav raw_spin_lock_irqsave(&byt_lock, flags); 12665a9fa4c2SRaag Jadav conf0 = readl(conf_reg); 12675a9fa4c2SRaag Jadav val = readl(val_reg); 126840ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 12695fae8b86SMika Westerberg 127086e3ef81SCristina Ciocan comm = byt_get_community(vg, pin); 127186e3ef81SCristina Ciocan if (!comm) { 1272b9e18434SAndy Shevchenko seq_printf(s, "Pin %i: can't retrieve community\n", pin); 127386e3ef81SCristina Ciocan continue; 127486e3ef81SCristina Ciocan } 12755fae8b86SMika Westerberg label = gpiochip_is_requested(chip, i); 12765fae8b86SMika Westerberg if (!label) 12775fae8b86SMika Westerberg label = "Unrequested"; 12785fae8b86SMika Westerberg 12795fae8b86SMika Westerberg switch (conf0 & BYT_PULL_ASSIGN_MASK) { 12805fae8b86SMika Westerberg case BYT_PULL_ASSIGN_UP: 12815fae8b86SMika Westerberg pull = "up"; 12825fae8b86SMika Westerberg break; 12835fae8b86SMika Westerberg case BYT_PULL_ASSIGN_DOWN: 12845fae8b86SMika Westerberg pull = "down"; 12855fae8b86SMika Westerberg break; 12865fae8b86SMika Westerberg } 12875fae8b86SMika Westerberg 12885fae8b86SMika Westerberg switch (conf0 & BYT_PULL_STR_MASK) { 12895fae8b86SMika Westerberg case BYT_PULL_STR_2K: 12905fae8b86SMika Westerberg pull_str = "2k"; 12915fae8b86SMika Westerberg break; 12925fae8b86SMika Westerberg case BYT_PULL_STR_10K: 12935fae8b86SMika Westerberg pull_str = "10k"; 12945fae8b86SMika Westerberg break; 12955fae8b86SMika Westerberg case BYT_PULL_STR_20K: 12965fae8b86SMika Westerberg pull_str = "20k"; 12975fae8b86SMika Westerberg break; 12985fae8b86SMika Westerberg case BYT_PULL_STR_40K: 12995fae8b86SMika Westerberg pull_str = "40k"; 13005fae8b86SMika Westerberg break; 13015fae8b86SMika Westerberg } 13025fae8b86SMika Westerberg 13035fae8b86SMika Westerberg seq_printf(s, 13045fae8b86SMika Westerberg " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", 130586e3ef81SCristina Ciocan pin, 13065fae8b86SMika Westerberg label, 13075fae8b86SMika Westerberg val & BYT_INPUT_EN ? " " : "in", 13085fae8b86SMika Westerberg val & BYT_OUTPUT_EN ? " " : "out", 1309c518d31bSAndy Shevchenko str_hi_lo(val & BYT_LEVEL), 13103655a1caSAlexander Stein comm->pad_map[i], comm->pad_map[i] * 16, 13115fae8b86SMika Westerberg conf0 & 0x7, 13125fae8b86SMika Westerberg conf0 & BYT_TRIG_NEG ? " fall" : " ", 13135fae8b86SMika Westerberg conf0 & BYT_TRIG_POS ? " rise" : " ", 13145fae8b86SMika Westerberg conf0 & BYT_TRIG_LVL ? " level" : " "); 13155fae8b86SMika Westerberg 13165fae8b86SMika Westerberg if (pull && pull_str) 13175fae8b86SMika Westerberg seq_printf(s, " %-4s %-3s", pull, pull_str); 13185fae8b86SMika Westerberg else 13195fae8b86SMika Westerberg seq_puts(s, " "); 13205fae8b86SMika Westerberg 13215fae8b86SMika Westerberg if (conf0 & BYT_IODEN) 13225fae8b86SMika Westerberg seq_puts(s, " open-drain"); 13235fae8b86SMika Westerberg 13245fae8b86SMika Westerberg seq_puts(s, "\n"); 13255fae8b86SMika Westerberg } 13265fae8b86SMika Westerberg } 13275fae8b86SMika Westerberg 132886e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = { 132986e3ef81SCristina Ciocan .owner = THIS_MODULE, 133086e3ef81SCristina Ciocan .request = gpiochip_generic_request, 133186e3ef81SCristina Ciocan .free = gpiochip_generic_free, 133286e3ef81SCristina Ciocan .get_direction = byt_gpio_get_direction, 133386e3ef81SCristina Ciocan .direction_input = byt_gpio_direction_input, 133486e3ef81SCristina Ciocan .direction_output = byt_gpio_direction_output, 133586e3ef81SCristina Ciocan .get = byt_gpio_get, 133686e3ef81SCristina Ciocan .set = byt_gpio_set, 1337ccd025eaSAndy Shevchenko .set_config = gpiochip_generic_config, 133886e3ef81SCristina Ciocan .dbg_show = byt_gpio_dbg_show, 133986e3ef81SCristina Ciocan }; 134086e3ef81SCristina Ciocan 134131e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d) 134231e4329fSMika Westerberg { 134331e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 13445d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(gc); 13456d209b42SAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 134631e4329fSMika Westerberg void __iomem *reg; 134731e4329fSMika Westerberg 13486d209b42SAndy Shevchenko reg = byt_gpio_reg(vg, hwirq, BYT_INT_STAT_REG); 13499f573b98SCristina Ciocan if (!reg) 13509f573b98SCristina Ciocan return; 13519f573b98SCristina Ciocan 135240ecab55SHans de Goede raw_spin_lock(&byt_lock); 13536d209b42SAndy Shevchenko writel(BIT(hwirq % 32), reg); 135440ecab55SHans de Goede raw_spin_unlock(&byt_lock); 135531e4329fSMika Westerberg } 135631e4329fSMika Westerberg 13579f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d) 13589f573b98SCristina Ciocan { 13599f573b98SCristina Ciocan struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 13605d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(gc); 13616d209b42SAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 13629f573b98SCristina Ciocan 13636d209b42SAndy Shevchenko byt_gpio_clear_triggering(vg, hwirq); 13646d209b42SAndy Shevchenko gpiochip_disable_irq(gc, hwirq); 13659f573b98SCristina Ciocan } 13669f573b98SCristina Ciocan 13675fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d) 13685fae8b86SMika Westerberg { 136931e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 13705d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(gc); 13716d209b42SAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 137231e4329fSMika Westerberg unsigned long flags; 137331e4329fSMika Westerberg void __iomem *reg; 137431e4329fSMika Westerberg u32 value; 137531e4329fSMika Westerberg 13766d209b42SAndy Shevchenko gpiochip_enable_irq(gc, hwirq); 13776d209b42SAndy Shevchenko 13786d209b42SAndy Shevchenko reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG); 13799f573b98SCristina Ciocan if (!reg) 13809f573b98SCristina Ciocan return; 138178e1c896SMika Westerberg 138240ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 138331e4329fSMika Westerberg value = readl(reg); 138431e4329fSMika Westerberg 138531e4329fSMika Westerberg switch (irqd_get_trigger_type(d)) { 138631e4329fSMika Westerberg case IRQ_TYPE_LEVEL_HIGH: 138731e4329fSMika Westerberg value |= BYT_TRIG_LVL; 13880a093020SGustavo A. R. Silva fallthrough; 138931e4329fSMika Westerberg case IRQ_TYPE_EDGE_RISING: 139031e4329fSMika Westerberg value |= BYT_TRIG_POS; 139131e4329fSMika Westerberg break; 139231e4329fSMika Westerberg case IRQ_TYPE_LEVEL_LOW: 139331e4329fSMika Westerberg value |= BYT_TRIG_LVL; 13940a093020SGustavo A. R. Silva fallthrough; 139531e4329fSMika Westerberg case IRQ_TYPE_EDGE_FALLING: 139631e4329fSMika Westerberg value |= BYT_TRIG_NEG; 139731e4329fSMika Westerberg break; 139831e4329fSMika Westerberg case IRQ_TYPE_EDGE_BOTH: 139931e4329fSMika Westerberg value |= (BYT_TRIG_NEG | BYT_TRIG_POS); 140031e4329fSMika Westerberg break; 140131e4329fSMika Westerberg } 140231e4329fSMika Westerberg 140331e4329fSMika Westerberg writel(value, reg); 140431e4329fSMika Westerberg 140540ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 14065fae8b86SMika Westerberg } 14075fae8b86SMika Westerberg 14089f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type) 14095fae8b86SMika Westerberg { 14105d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); 14116d209b42SAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 14129f573b98SCristina Ciocan u32 value; 14139f573b98SCristina Ciocan unsigned long flags; 14146d209b42SAndy Shevchenko void __iomem *reg; 141531e4329fSMika Westerberg 14166d209b42SAndy Shevchenko reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG); 14176d209b42SAndy Shevchenko if (!reg) 14189f573b98SCristina Ciocan return -EINVAL; 14199f573b98SCristina Ciocan 142040ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 14219f573b98SCristina Ciocan value = readl(reg); 14229f573b98SCristina Ciocan 14239f573b98SCristina Ciocan WARN(value & BYT_DIRECT_IRQ_EN, 1424b9e18434SAndy Shevchenko "Bad pad config for IO mode, force DIRECT_IRQ_EN bit clearing"); 14259f573b98SCristina Ciocan 14269f573b98SCristina Ciocan /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits 14279f573b98SCristina Ciocan * are used to indicate high and low level triggering 14289f573b98SCristina Ciocan */ 14299f573b98SCristina Ciocan value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | 14309f573b98SCristina Ciocan BYT_TRIG_LVL); 14319291c65bSHans de Goede /* Enable glitch filtering */ 14329291c65bSHans de Goede value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK | 14339291c65bSHans de Goede BYT_GLITCH_F_FAST_CLK; 14349f573b98SCristina Ciocan 14359f573b98SCristina Ciocan writel(value, reg); 14369f573b98SCristina Ciocan 14379f573b98SCristina Ciocan if (type & IRQ_TYPE_EDGE_BOTH) 14389f573b98SCristina Ciocan irq_set_handler_locked(d, handle_edge_irq); 14399f573b98SCristina Ciocan else if (type & IRQ_TYPE_LEVEL_MASK) 14409f573b98SCristina Ciocan irq_set_handler_locked(d, handle_level_irq); 14419f573b98SCristina Ciocan 144240ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 14439f573b98SCristina Ciocan 14449f573b98SCristina Ciocan return 0; 14455fae8b86SMika Westerberg } 14465fae8b86SMika Westerberg 14476d209b42SAndy Shevchenko static const struct irq_chip byt_gpio_irq_chip = { 14486d209b42SAndy Shevchenko .name = "BYT-GPIO", 14496d209b42SAndy Shevchenko .irq_ack = byt_irq_ack, 14506d209b42SAndy Shevchenko .irq_mask = byt_irq_mask, 14516d209b42SAndy Shevchenko .irq_unmask = byt_irq_unmask, 14526d209b42SAndy Shevchenko .irq_set_type = byt_irq_type, 14536d209b42SAndy Shevchenko .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE, 14546d209b42SAndy Shevchenko GPIOCHIP_IRQ_RESOURCE_HELPERS, 14556d209b42SAndy Shevchenko }; 14566d209b42SAndy Shevchenko 145771e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc) 145871e6ca61SCristina Ciocan { 145971e6ca61SCristina Ciocan struct irq_data *data = irq_desc_get_irq_data(desc); 14605d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc)); 146171e6ca61SCristina Ciocan struct irq_chip *chip = irq_data_get_irq_chip(data); 146271e6ca61SCristina Ciocan u32 base, pin; 146371e6ca61SCristina Ciocan void __iomem *reg; 146471e6ca61SCristina Ciocan unsigned long pending; 146571e6ca61SCristina Ciocan 146671e6ca61SCristina Ciocan /* check from GPIO controller which pin triggered the interrupt */ 146771e6ca61SCristina Ciocan for (base = 0; base < vg->chip.ngpio; base += 32) { 146871e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 146971e6ca61SCristina Ciocan 147071e6ca61SCristina Ciocan if (!reg) { 1471b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base); 147271e6ca61SCristina Ciocan continue; 147371e6ca61SCristina Ciocan } 147471e6ca61SCristina Ciocan 147540ecab55SHans de Goede raw_spin_lock(&byt_lock); 147671e6ca61SCristina Ciocan pending = readl(reg); 147740ecab55SHans de Goede raw_spin_unlock(&byt_lock); 1478a9cb09b7SMarc Zyngier for_each_set_bit(pin, &pending, 32) 1479a9cb09b7SMarc Zyngier generic_handle_domain_irq(vg->chip.irq.domain, base + pin); 148071e6ca61SCristina Ciocan } 148171e6ca61SCristina Ciocan chip->irq_eoi(data); 148271e6ca61SCristina Ciocan } 148371e6ca61SCristina Ciocan 1484689e0088SHans de Goede static bool byt_direct_irq_sanity_check(struct intel_pinctrl *vg, int pin, u32 conf0) 1485689e0088SHans de Goede { 1486689e0088SHans de Goede int direct_irq, ioapic_direct_irq_base; 1487689e0088SHans de Goede u8 *match, direct_irq_mux[16]; 1488689e0088SHans de Goede u32 trig; 1489689e0088SHans de Goede 1490689e0088SHans de Goede memcpy_fromio(direct_irq_mux, vg->communities->pad_regs + BYT_DIRECT_IRQ_REG, 1491689e0088SHans de Goede sizeof(direct_irq_mux)); 1492689e0088SHans de Goede match = memchr(direct_irq_mux, pin, sizeof(direct_irq_mux)); 1493689e0088SHans de Goede if (!match) { 1494b9e18434SAndy Shevchenko dev_warn(vg->dev, FW_BUG "Pin %i: DIRECT_IRQ_EN set but no IRQ assigned, clearing\n", pin); 1495689e0088SHans de Goede return false; 1496689e0088SHans de Goede } 1497689e0088SHans de Goede 1498689e0088SHans de Goede direct_irq = match - direct_irq_mux; 1499689e0088SHans de Goede /* Base IO-APIC pin numbers come from atom-e3800-family-datasheet.pdf */ 1500689e0088SHans de Goede ioapic_direct_irq_base = (vg->communities->npins == BYT_NGPIO_SCORE) ? 51 : 67; 1501689e0088SHans de Goede dev_dbg(vg->dev, "Pin %i: uses direct IRQ %d (IO-APIC %d)\n", pin, 1502689e0088SHans de Goede direct_irq, direct_irq + ioapic_direct_irq_base); 1503689e0088SHans de Goede 1504689e0088SHans de Goede /* 1505689e0088SHans de Goede * Testing has shown that the way direct IRQs work is that the combination of the 1506689e0088SHans de Goede * direct-irq-en flag and the direct IRQ mux connect the output of the GPIO's IRQ 1507689e0088SHans de Goede * trigger block, which normally sets the status flag in the IRQ status reg at 1508689e0088SHans de Goede * 0x800, to one of the IO-APIC pins according to the mux registers. 1509689e0088SHans de Goede * 1510689e0088SHans de Goede * This means that: 1511689e0088SHans de Goede * 1. The TRIG_MASK bits must be set to configure the GPIO's IRQ trigger block 1512689e0088SHans de Goede * 2. The TRIG_LVL bit *must* be set, so that the GPIO's input value is directly 1513689e0088SHans de Goede * passed (1:1 or inverted) to the IO-APIC pin, if TRIG_LVL is not set, 1514689e0088SHans de Goede * selecting edge mode operation then on the first edge the IO-APIC pin goes 1515689e0088SHans de Goede * high, but since no write-to-clear write will be done to the IRQ status reg 1516689e0088SHans de Goede * at 0x800, the detected edge condition will never get cleared. 1517689e0088SHans de Goede */ 1518689e0088SHans de Goede trig = conf0 & BYT_TRIG_MASK; 1519689e0088SHans de Goede if (trig != (BYT_TRIG_POS | BYT_TRIG_LVL) && 1520689e0088SHans de Goede trig != (BYT_TRIG_NEG | BYT_TRIG_LVL)) { 1521b9e18434SAndy Shevchenko dev_warn(vg->dev, 1522b9e18434SAndy Shevchenko FW_BUG "Pin %i: DIRECT_IRQ_EN set without trigger (CONF0: %#08x), clearing\n", 1523689e0088SHans de Goede pin, conf0); 1524689e0088SHans de Goede return false; 1525689e0088SHans de Goede } 1526689e0088SHans de Goede 1527689e0088SHans de Goede return true; 1528689e0088SHans de Goede } 1529689e0088SHans de Goede 15305fbe5b58SLinus Walleij static void byt_init_irq_valid_mask(struct gpio_chip *chip, 15315fbe5b58SLinus Walleij unsigned long *valid_mask, 15325fbe5b58SLinus Walleij unsigned int ngpios) 15335fbe5b58SLinus Walleij { 15345d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip); 15355fae8b86SMika Westerberg void __iomem *reg; 1536e70982b3SAndy Shevchenko u32 value; 153795f0972cSMika Westerberg int i; 153895f0972cSMika Westerberg 153995f0972cSMika Westerberg /* 154095f0972cSMika Westerberg * Clear interrupt triggers for all pins that are GPIOs and 154195f0972cSMika Westerberg * do not use direct IRQ mode. This will prevent spurious 154295f0972cSMika Westerberg * interrupts from misconfigured pins. 154395f0972cSMika Westerberg */ 15445d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->npins; i++) { 15455d33e0ebSAndy Shevchenko unsigned int pin = vg->soc->pins[i].number; 154671e6ca61SCristina Ciocan 154771e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 154871e6ca61SCristina Ciocan if (!reg) { 1549b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: could not retrieve CONF0\n", i); 155071e6ca61SCristina Ciocan continue; 155171e6ca61SCristina Ciocan } 155271e6ca61SCristina Ciocan 155371e6ca61SCristina Ciocan value = readl(reg); 155449c03096SAndy Shevchenko if (value & BYT_DIRECT_IRQ_EN) { 1555689e0088SHans de Goede if (byt_direct_irq_sanity_check(vg, i, value)) { 1556e70982b3SAndy Shevchenko clear_bit(i, valid_mask); 1557689e0088SHans de Goede } else { 1558689e0088SHans de Goede value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | 1559689e0088SHans de Goede BYT_TRIG_NEG | BYT_TRIG_LVL); 1560689e0088SHans de Goede writel(value, reg); 1561689e0088SHans de Goede } 156249c03096SAndy Shevchenko } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { 156395f0972cSMika Westerberg byt_gpio_clear_triggering(vg, i); 1564990ec243SAndy Shevchenko dev_dbg(vg->dev, "disabling GPIO %d\n", i); 156595f0972cSMika Westerberg } 156695f0972cSMika Westerberg } 1567e70982b3SAndy Shevchenko } 1568e70982b3SAndy Shevchenko 1569e70982b3SAndy Shevchenko static int byt_gpio_irq_init_hw(struct gpio_chip *chip) 1570e70982b3SAndy Shevchenko { 15715d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip); 1572e70982b3SAndy Shevchenko void __iomem *reg; 1573e70982b3SAndy Shevchenko u32 base, value; 15745fae8b86SMika Westerberg 15755fae8b86SMika Westerberg /* clear interrupt status trigger registers */ 15765d33e0ebSAndy Shevchenko for (base = 0; base < vg->soc->npins; base += 32) { 1577c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 157871e6ca61SCristina Ciocan 157971e6ca61SCristina Ciocan if (!reg) { 1580b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base); 158171e6ca61SCristina Ciocan continue; 158271e6ca61SCristina Ciocan } 158371e6ca61SCristina Ciocan 15845fae8b86SMika Westerberg writel(0xffffffff, reg); 15855fae8b86SMika Westerberg /* make sure trigger bits are cleared, if not then a pin 15865fae8b86SMika Westerberg might be misconfigured in bios */ 15875fae8b86SMika Westerberg value = readl(reg); 15885fae8b86SMika Westerberg if (value) 1589990ec243SAndy Shevchenko dev_err(vg->dev, 1590b9e18434SAndy Shevchenko "GPIO interrupt error, pins misconfigured. INT_STAT%u: %#08x\n", 1591973232e2SAlexander Stein base / 32, value); 15925fae8b86SMika Westerberg } 1593ca8a958eSAndy Shevchenko 1594ca8a958eSAndy Shevchenko return 0; 15955fae8b86SMika Westerberg } 15965fae8b86SMika Westerberg 1597ed3c1564SAndy Shevchenko static int byt_gpio_add_pin_ranges(struct gpio_chip *chip) 1598ed3c1564SAndy Shevchenko { 15995d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = gpiochip_get_data(chip); 1600990ec243SAndy Shevchenko struct device *dev = vg->dev; 1601ed3c1564SAndy Shevchenko int ret; 1602ed3c1564SAndy Shevchenko 16035d33e0ebSAndy Shevchenko ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins); 1604ed3c1564SAndy Shevchenko if (ret) 1605ed3c1564SAndy Shevchenko dev_err(dev, "failed to add GPIO pin range\n"); 1606ed3c1564SAndy Shevchenko 1607ed3c1564SAndy Shevchenko return ret; 1608ed3c1564SAndy Shevchenko } 1609ed3c1564SAndy Shevchenko 16105d33e0ebSAndy Shevchenko static int byt_gpio_probe(struct intel_pinctrl *vg) 16115fae8b86SMika Westerberg { 1612990ec243SAndy Shevchenko struct platform_device *pdev = to_platform_device(vg->dev); 16135fae8b86SMika Westerberg struct gpio_chip *gc; 1614f86a1bb5SAndy Shevchenko int irq, ret; 16155fae8b86SMika Westerberg 161671e6ca61SCristina Ciocan /* Set up gpio chip */ 161771e6ca61SCristina Ciocan vg->chip = byt_gpio_chip; 16185fae8b86SMika Westerberg gc = &vg->chip; 1619990ec243SAndy Shevchenko gc->label = dev_name(vg->dev); 16205fae8b86SMika Westerberg gc->base = -1; 16215fae8b86SMika Westerberg gc->can_sleep = false; 1622ed3c1564SAndy Shevchenko gc->add_pin_ranges = byt_gpio_add_pin_ranges; 1623990ec243SAndy Shevchenko gc->parent = vg->dev; 16245d33e0ebSAndy Shevchenko gc->ngpio = vg->soc->npins; 16255fae8b86SMika Westerberg 1626fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP 16275d33e0ebSAndy Shevchenko vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads), 16285d33e0ebSAndy Shevchenko GFP_KERNEL); 16295d33e0ebSAndy Shevchenko if (!vg->context.pads) 1630d6cb7722SAditya Pakki return -ENOMEM; 1631fcc18debSMika Westerberg #endif 16325fae8b86SMika Westerberg 16335fae8b86SMika Westerberg /* set up interrupts */ 1634f86a1bb5SAndy Shevchenko irq = platform_get_irq_optional(pdev, 0); 1635f86a1bb5SAndy Shevchenko if (irq > 0) { 1636ca8a958eSAndy Shevchenko struct gpio_irq_chip *girq; 1637ca8a958eSAndy Shevchenko 1638ca8a958eSAndy Shevchenko girq = &gc->irq; 16396d209b42SAndy Shevchenko gpio_irq_chip_set_chip(girq, &byt_gpio_irq_chip); 1640ca8a958eSAndy Shevchenko girq->init_hw = byt_gpio_irq_init_hw; 1641ab68b220SAndy Shevchenko girq->init_valid_mask = byt_init_irq_valid_mask; 1642ca8a958eSAndy Shevchenko girq->parent_handler = byt_gpio_irq_handler; 1643ca8a958eSAndy Shevchenko girq->num_parents = 1; 1644990ec243SAndy Shevchenko girq->parents = devm_kcalloc(vg->dev, girq->num_parents, 1645ca8a958eSAndy Shevchenko sizeof(*girq->parents), GFP_KERNEL); 1646ca8a958eSAndy Shevchenko if (!girq->parents) 1647ca8a958eSAndy Shevchenko return -ENOMEM; 1648f86a1bb5SAndy Shevchenko girq->parents[0] = irq; 1649ca8a958eSAndy Shevchenko girq->default_type = IRQ_TYPE_NONE; 1650ca8a958eSAndy Shevchenko girq->handler = handle_bad_irq; 16515fae8b86SMika Westerberg } 16525fae8b86SMika Westerberg 1653990ec243SAndy Shevchenko ret = devm_gpiochip_add_data(vg->dev, gc, vg); 1654ca8a958eSAndy Shevchenko if (ret) { 1655990ec243SAndy Shevchenko dev_err(vg->dev, "failed adding byt-gpio chip\n"); 1656ca8a958eSAndy Shevchenko return ret; 16575fae8b86SMika Westerberg } 16585fae8b86SMika Westerberg 165971e6ca61SCristina Ciocan return ret; 166071e6ca61SCristina Ciocan } 166171e6ca61SCristina Ciocan 16625d33e0ebSAndy Shevchenko static int byt_set_soc_data(struct intel_pinctrl *vg, 16635d33e0ebSAndy Shevchenko const struct intel_pinctrl_soc_data *soc) 166471e6ca61SCristina Ciocan { 1665990ec243SAndy Shevchenko struct platform_device *pdev = to_platform_device(vg->dev); 166671e6ca61SCristina Ciocan int i; 166771e6ca61SCristina Ciocan 16685d33e0ebSAndy Shevchenko vg->soc = soc; 16695d33e0ebSAndy Shevchenko 16705d33e0ebSAndy Shevchenko vg->ncommunities = vg->soc->ncommunities; 16715d33e0ebSAndy Shevchenko vg->communities = devm_kcalloc(vg->dev, vg->ncommunities, 16725d33e0ebSAndy Shevchenko sizeof(*vg->communities), GFP_KERNEL); 16735d33e0ebSAndy Shevchenko if (!vg->communities) 167471e6ca61SCristina Ciocan return -ENOMEM; 167571e6ca61SCristina Ciocan 16765d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->ncommunities; i++) { 16775d33e0ebSAndy Shevchenko struct intel_community *comm = vg->communities + i; 167871e6ca61SCristina Ciocan 16795d33e0ebSAndy Shevchenko *comm = vg->soc->communities[i]; 168071e6ca61SCristina Ciocan 1681990ec243SAndy Shevchenko comm->pad_regs = devm_platform_ioremap_resource(pdev, 0); 168234e65670SAndy Shevchenko if (IS_ERR(comm->pad_regs)) 168334e65670SAndy Shevchenko return PTR_ERR(comm->pad_regs); 168471e6ca61SCristina Ciocan } 168571e6ca61SCristina Ciocan 168671e6ca61SCristina Ciocan return 0; 168771e6ca61SCristina Ciocan } 168871e6ca61SCristina Ciocan 168971e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = { 169071e6ca61SCristina Ciocan { "INT33B2", (kernel_ulong_t)byt_soc_data }, 169171e6ca61SCristina Ciocan { "INT33FC", (kernel_ulong_t)byt_soc_data }, 169271e6ca61SCristina Ciocan { } 169371e6ca61SCristina Ciocan }; 169471e6ca61SCristina Ciocan 169571e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev) 169671e6ca61SCristina Ciocan { 1697ce7793e9SAndy Shevchenko const struct intel_pinctrl_soc_data *soc_data; 16982c02af70SAndy Shevchenko struct device *dev = &pdev->dev; 16995d33e0ebSAndy Shevchenko struct intel_pinctrl *vg; 1700ce7793e9SAndy Shevchenko int ret; 170171e6ca61SCristina Ciocan 1702ce7793e9SAndy Shevchenko soc_data = intel_pinctrl_get_soc_data(pdev); 1703ce7793e9SAndy Shevchenko if (IS_ERR(soc_data)) 1704ce7793e9SAndy Shevchenko return PTR_ERR(soc_data); 170571e6ca61SCristina Ciocan 17062c02af70SAndy Shevchenko vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL); 170771e6ca61SCristina Ciocan if (!vg) 170871e6ca61SCristina Ciocan return -ENOMEM; 170971e6ca61SCristina Ciocan 17102c02af70SAndy Shevchenko vg->dev = dev; 171171e6ca61SCristina Ciocan ret = byt_set_soc_data(vg, soc_data); 171271e6ca61SCristina Ciocan if (ret) { 17132c02af70SAndy Shevchenko dev_err(dev, "failed to set soc data\n"); 171471e6ca61SCristina Ciocan return ret; 171571e6ca61SCristina Ciocan } 171671e6ca61SCristina Ciocan 17175d33e0ebSAndy Shevchenko vg->pctldesc = byt_pinctrl_desc; 17185d33e0ebSAndy Shevchenko vg->pctldesc.name = dev_name(dev); 17195d33e0ebSAndy Shevchenko vg->pctldesc.pins = vg->soc->pins; 17205d33e0ebSAndy Shevchenko vg->pctldesc.npins = vg->soc->npins; 172171e6ca61SCristina Ciocan 17225d33e0ebSAndy Shevchenko vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg); 17235d33e0ebSAndy Shevchenko if (IS_ERR(vg->pctldev)) { 17242c02af70SAndy Shevchenko dev_err(dev, "failed to register pinctrl driver\n"); 17255d33e0ebSAndy Shevchenko return PTR_ERR(vg->pctldev); 172671e6ca61SCristina Ciocan } 172771e6ca61SCristina Ciocan 172871e6ca61SCristina Ciocan ret = byt_gpio_probe(vg); 17290612413fSAndy Shevchenko if (ret) 173071e6ca61SCristina Ciocan return ret; 173171e6ca61SCristina Ciocan 173271e6ca61SCristina Ciocan platform_set_drvdata(pdev, vg); 17332c02af70SAndy Shevchenko pm_runtime_enable(dev); 173471e6ca61SCristina Ciocan 173571e6ca61SCristina Ciocan return 0; 173671e6ca61SCristina Ciocan } 173771e6ca61SCristina Ciocan 1738fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP 1739fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev) 1740fcc18debSMika Westerberg { 17415d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = dev_get_drvdata(dev); 174240ecab55SHans de Goede unsigned long flags; 1743fcc18debSMika Westerberg int i; 1744fcc18debSMika Westerberg 174540ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 174640ecab55SHans de Goede 17475d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->npins; i++) { 1748fcc18debSMika Westerberg void __iomem *reg; 1749fcc18debSMika Westerberg u32 value; 17505d33e0ebSAndy Shevchenko unsigned int pin = vg->soc->pins[i].number; 1751fcc18debSMika Westerberg 175271e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 175371e6ca61SCristina Ciocan if (!reg) { 1754b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i); 175571e6ca61SCristina Ciocan continue; 175671e6ca61SCristina Ciocan } 1757fcc18debSMika Westerberg value = readl(reg) & BYT_CONF0_RESTORE_MASK; 17585d33e0ebSAndy Shevchenko vg->context.pads[i].conf0 = value; 1759fcc18debSMika Westerberg 176071e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 1761*9d49882eSRaag Jadav if (!reg) { 1762*9d49882eSRaag Jadav dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i); 1763*9d49882eSRaag Jadav continue; 1764*9d49882eSRaag Jadav } 1765fcc18debSMika Westerberg value = readl(reg) & BYT_VAL_RESTORE_MASK; 17665d33e0ebSAndy Shevchenko vg->context.pads[i].val = value; 1767fcc18debSMika Westerberg } 1768fcc18debSMika Westerberg 176940ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 1770fcc18debSMika Westerberg return 0; 1771fcc18debSMika Westerberg } 1772fcc18debSMika Westerberg 1773fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev) 1774fcc18debSMika Westerberg { 17755d33e0ebSAndy Shevchenko struct intel_pinctrl *vg = dev_get_drvdata(dev); 177640ecab55SHans de Goede unsigned long flags; 1777fcc18debSMika Westerberg int i; 1778fcc18debSMika Westerberg 177940ecab55SHans de Goede raw_spin_lock_irqsave(&byt_lock, flags); 178040ecab55SHans de Goede 17815d33e0ebSAndy Shevchenko for (i = 0; i < vg->soc->npins; i++) { 1782fcc18debSMika Westerberg void __iomem *reg; 1783fcc18debSMika Westerberg u32 value; 17845d33e0ebSAndy Shevchenko unsigned int pin = vg->soc->pins[i].number; 1785fcc18debSMika Westerberg 178671e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 178771e6ca61SCristina Ciocan if (!reg) { 1788b9e18434SAndy Shevchenko dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i); 178971e6ca61SCristina Ciocan continue; 179071e6ca61SCristina Ciocan } 1791fcc18debSMika Westerberg value = readl(reg); 1792fcc18debSMika Westerberg if ((value & BYT_CONF0_RESTORE_MASK) != 17935d33e0ebSAndy Shevchenko vg->context.pads[i].conf0) { 1794fcc18debSMika Westerberg value &= ~BYT_CONF0_RESTORE_MASK; 17955d33e0ebSAndy Shevchenko value |= vg->context.pads[i].conf0; 1796fcc18debSMika Westerberg writel(value, reg); 1797b9e18434SAndy Shevchenko dev_info(dev, "restored pin %d CONF0 %#08x", i, value); 1798fcc18debSMika Westerberg } 1799fcc18debSMika Westerberg 180071e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 1801*9d49882eSRaag Jadav if (!reg) { 1802*9d49882eSRaag Jadav dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i); 1803*9d49882eSRaag Jadav continue; 1804*9d49882eSRaag Jadav } 1805fcc18debSMika Westerberg value = readl(reg); 1806fcc18debSMika Westerberg if ((value & BYT_VAL_RESTORE_MASK) != 18075d33e0ebSAndy Shevchenko vg->context.pads[i].val) { 1808fcc18debSMika Westerberg u32 v; 1809fcc18debSMika Westerberg 1810fcc18debSMika Westerberg v = value & ~BYT_VAL_RESTORE_MASK; 18115d33e0ebSAndy Shevchenko v |= vg->context.pads[i].val; 1812fcc18debSMika Westerberg if (v != value) { 1813fcc18debSMika Westerberg writel(v, reg); 1814b9e18434SAndy Shevchenko dev_dbg(dev, "restored pin %d VAL %#08x\n", i, v); 1815fcc18debSMika Westerberg } 1816fcc18debSMika Westerberg } 1817fcc18debSMika Westerberg } 1818fcc18debSMika Westerberg 181940ecab55SHans de Goede raw_spin_unlock_irqrestore(&byt_lock, flags); 1820fcc18debSMika Westerberg return 0; 1821fcc18debSMika Westerberg } 1822fcc18debSMika Westerberg #endif 1823fcc18debSMika Westerberg 1824ec879f12SMika Westerberg #ifdef CONFIG_PM 18255fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev) 18265fae8b86SMika Westerberg { 18275fae8b86SMika Westerberg return 0; 18285fae8b86SMika Westerberg } 18295fae8b86SMika Westerberg 18305fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev) 18315fae8b86SMika Westerberg { 18325fae8b86SMika Westerberg return 0; 18335fae8b86SMika Westerberg } 1834ec879f12SMika Westerberg #endif 18355fae8b86SMika Westerberg 18365fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = { 1837fcc18debSMika Westerberg SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) 1838fcc18debSMika Westerberg SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, 1839fcc18debSMika Westerberg NULL) 18405fae8b86SMika Westerberg }; 18415fae8b86SMika Westerberg 18425fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = { 184371e6ca61SCristina Ciocan .probe = byt_pinctrl_probe, 18445fae8b86SMika Westerberg .driver = { 18455fae8b86SMika Westerberg .name = "byt_gpio", 18465fae8b86SMika Westerberg .pm = &byt_gpio_pm_ops, 1847e87daf0bSAndy Shevchenko .acpi_match_table = byt_gpio_acpi_match, 1848360943a8SPaul Gortmaker .suppress_bind_attrs = true, 18495fae8b86SMika Westerberg }, 18505fae8b86SMika Westerberg }; 18515fae8b86SMika Westerberg 18525fae8b86SMika Westerberg static int __init byt_gpio_init(void) 18535fae8b86SMika Westerberg { 18545fae8b86SMika Westerberg return platform_driver_register(&byt_gpio_driver); 18555fae8b86SMika Westerberg } 18565fae8b86SMika Westerberg subsys_initcall(byt_gpio_init); 1857