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