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) 405fae8b86SMika Westerberg #define BYT_TRIG_NEG BIT(26) 415fae8b86SMika Westerberg #define BYT_TRIG_POS BIT(25) 425fae8b86SMika Westerberg #define BYT_TRIG_LVL BIT(24) 43658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN BIT(20) 449291c65bSHans de Goede #define BYT_GLITCH_FILTER_EN BIT(19) 459291c65bSHans de Goede #define BYT_GLITCH_F_SLOW_CLK BIT(17) 469291c65bSHans de Goede #define BYT_GLITCH_F_FAST_CLK BIT(16) 475fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT 9 485fae8b86SMika Westerberg #define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT) 495fae8b86SMika Westerberg #define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) 505fae8b86SMika Westerberg #define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT) 515fae8b86SMika Westerberg #define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT) 525fae8b86SMika Westerberg #define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT) 535fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_SHIFT 7 545fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_MASK (3 << BYT_PULL_ASSIGN_SHIFT) 555fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT) 565fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT) 575fae8b86SMika Westerberg #define BYT_PIN_MUX 0x07 585fae8b86SMika Westerberg 595fae8b86SMika Westerberg /* BYT_VAL_REG register bits */ 605fae8b86SMika Westerberg #define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ 615fae8b86SMika Westerberg #define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ 625fae8b86SMika Westerberg #define BYT_LEVEL BIT(0) 635fae8b86SMika Westerberg 645fae8b86SMika Westerberg #define BYT_DIR_MASK (BIT(1) | BIT(2)) 655fae8b86SMika Westerberg #define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24)) 665fae8b86SMika Westerberg 67fcc18debSMika Westerberg #define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \ 68fcc18debSMika Westerberg BYT_PIN_MUX) 69fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) 70fcc18debSMika Westerberg 71658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */ 72658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_MASK 0x7 73658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US 1 74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US 2 75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US 3 76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS 4 77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS 5 78658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS 6 79658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS 7 80658b476cSCristina Ciocan 815fae8b86SMika Westerberg #define BYT_NGPIO_SCORE 102 825fae8b86SMika Westerberg #define BYT_NGPIO_NCORE 28 835fae8b86SMika Westerberg #define BYT_NGPIO_SUS 44 845fae8b86SMika Westerberg 855fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID "1" 865fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID "2" 875fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID "3" 885fae8b86SMika Westerberg 89c501d0b1SCristina Ciocan /* 90c501d0b1SCristina Ciocan * This is the function value most pins have for GPIO muxing. If the value 91c501d0b1SCristina Ciocan * differs from the default one, it must be explicitly mentioned. Otherwise, the 92c501d0b1SCristina Ciocan * pin control implementation will set the muxing value to default GPIO if it 93c501d0b1SCristina Ciocan * does not find a match for the requested function. 94c501d0b1SCristina Ciocan */ 95c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX 0 96a705f9c1SAndy Shevchenko #define BYT_ALTER_GPIO_MUX 1 97c501d0b1SCristina Ciocan 98c8f5c4c7SCristina Ciocan struct byt_gpio_pin_context { 99c8f5c4c7SCristina Ciocan u32 conf0; 100c8f5c4c7SCristina Ciocan u32 val; 101c8f5c4c7SCristina Ciocan }; 1025fae8b86SMika Westerberg 103c8f5c4c7SCristina Ciocan struct byt_community { 104c8f5c4c7SCristina Ciocan unsigned int pin_base; 105c8f5c4c7SCristina Ciocan size_t npins; 106c8f5c4c7SCristina Ciocan const unsigned int *pad_map; 107c8f5c4c7SCristina Ciocan void __iomem *reg_base; 108c8f5c4c7SCristina Ciocan }; 109c8f5c4c7SCristina Ciocan 110c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map) \ 111c8f5c4c7SCristina Ciocan { \ 112c8f5c4c7SCristina Ciocan .pin_base = (p), \ 113c8f5c4c7SCristina Ciocan .npins = (n), \ 114c8f5c4c7SCristina Ciocan .pad_map = (map),\ 115c8f5c4c7SCristina Ciocan } 116c8f5c4c7SCristina Ciocan 117c8f5c4c7SCristina Ciocan struct byt_pinctrl_soc_data { 118c8f5c4c7SCristina Ciocan const char *uid; 119c8f5c4c7SCristina Ciocan const struct pinctrl_pin_desc *pins; 120c8f5c4c7SCristina Ciocan size_t npins; 1214f010b93SAndy Shevchenko const struct intel_pingroup *groups; 122c8f5c4c7SCristina Ciocan size_t ngroups; 1234f010b93SAndy Shevchenko const struct intel_function *functions; 124c8f5c4c7SCristina Ciocan size_t nfunctions; 125c8f5c4c7SCristina Ciocan const struct byt_community *communities; 126c8f5c4c7SCristina Ciocan size_t ncommunities; 127c8f5c4c7SCristina Ciocan }; 128c8f5c4c7SCristina Ciocan 12971e6ca61SCristina Ciocan struct byt_gpio { 13071e6ca61SCristina Ciocan struct gpio_chip chip; 13171e6ca61SCristina Ciocan struct platform_device *pdev; 13271e6ca61SCristina Ciocan struct pinctrl_dev *pctl_dev; 13371e6ca61SCristina Ciocan struct pinctrl_desc pctl_desc; 13471e6ca61SCristina Ciocan raw_spinlock_t lock; 13571e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data; 13671e6ca61SCristina Ciocan struct byt_community *communities_copy; 13771e6ca61SCristina Ciocan struct byt_gpio_pin_context *saved_context; 13871e6ca61SCristina Ciocan }; 13971e6ca61SCristina Ciocan 140c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ 141c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = { 142c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "SATA_GP0"), 143c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "SATA_GP1"), 144c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "SATA_LED#"), 145c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "PCIE_CLKREQ0"), 146c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "PCIE_CLKREQ1"), 147c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "PCIE_CLKREQ2"), 148c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "PCIE_CLKREQ3"), 149c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "SD3_WP"), 150c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "HDA_RST"), 151c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "HDA_SYNC"), 152c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "HDA_CLK"), 153c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "HDA_SDO"), 154c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "HDA_SDI0"), 155c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "HDA_SDI1"), 156c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_S0_SC14"), 157c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_S0_SC15"), 158c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "MMC1_CLK"), 159c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "MMC1_D0"), 160c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "MMC1_D1"), 161c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "MMC1_D2"), 162c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "MMC1_D3"), 163c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "MMC1_D4"), 164c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "MMC1_D5"), 165c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "MMC1_D6"), 166c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "MMC1_D7"), 167c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "MMC1_CMD"), 168c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "MMC1_RST"), 169c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "SD2_CLK"), 170c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "SD2_D0"), 171c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "SD2_D1"), 172c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "SD2_D2"), 173c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "SD2_D3_CD"), 174c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "SD2_CMD"), 175c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "SD3_CLK"), 176c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "SD3_D0"), 177c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "SD3_D1"), 178c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "SD3_D2"), 179c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "SD3_D3"), 180c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "SD3_CD"), 181c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "SD3_CMD"), 182c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "SD3_1P8EN"), 183c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "SD3_PWREN#"), 184c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "ILB_LPC_AD0"), 185c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "ILB_LPC_AD1"), 186c8f5c4c7SCristina Ciocan PINCTRL_PIN(44, "ILB_LPC_AD2"), 187c8f5c4c7SCristina Ciocan PINCTRL_PIN(45, "ILB_LPC_AD3"), 188c8f5c4c7SCristina Ciocan PINCTRL_PIN(46, "ILB_LPC_FRAME"), 189c8f5c4c7SCristina Ciocan PINCTRL_PIN(47, "ILB_LPC_CLK0"), 190c8f5c4c7SCristina Ciocan PINCTRL_PIN(48, "ILB_LPC_CLK1"), 191c8f5c4c7SCristina Ciocan PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), 192c8f5c4c7SCristina Ciocan PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), 193c8f5c4c7SCristina Ciocan PINCTRL_PIN(51, "PCU_SMB_DATA"), 194c8f5c4c7SCristina Ciocan PINCTRL_PIN(52, "PCU_SMB_CLK"), 195c8f5c4c7SCristina Ciocan PINCTRL_PIN(53, "PCU_SMB_ALERT"), 196c8f5c4c7SCristina Ciocan PINCTRL_PIN(54, "ILB_8254_SPKR"), 197c8f5c4c7SCristina Ciocan PINCTRL_PIN(55, "GPIO_S0_SC55"), 198c8f5c4c7SCristina Ciocan PINCTRL_PIN(56, "GPIO_S0_SC56"), 199c8f5c4c7SCristina Ciocan PINCTRL_PIN(57, "GPIO_S0_SC57"), 200c8f5c4c7SCristina Ciocan PINCTRL_PIN(58, "GPIO_S0_SC58"), 201c8f5c4c7SCristina Ciocan PINCTRL_PIN(59, "GPIO_S0_SC59"), 202c8f5c4c7SCristina Ciocan PINCTRL_PIN(60, "GPIO_S0_SC60"), 203c8f5c4c7SCristina Ciocan PINCTRL_PIN(61, "GPIO_S0_SC61"), 204c8f5c4c7SCristina Ciocan PINCTRL_PIN(62, "LPE_I2S2_CLK"), 205c8f5c4c7SCristina Ciocan PINCTRL_PIN(63, "LPE_I2S2_FRM"), 206c8f5c4c7SCristina Ciocan PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), 207c8f5c4c7SCristina Ciocan PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), 208c8f5c4c7SCristina Ciocan PINCTRL_PIN(66, "SIO_SPI_CS"), 209c8f5c4c7SCristina Ciocan PINCTRL_PIN(67, "SIO_SPI_MISO"), 210c8f5c4c7SCristina Ciocan PINCTRL_PIN(68, "SIO_SPI_MOSI"), 211c8f5c4c7SCristina Ciocan PINCTRL_PIN(69, "SIO_SPI_CLK"), 212c8f5c4c7SCristina Ciocan PINCTRL_PIN(70, "SIO_UART1_RXD"), 213c8f5c4c7SCristina Ciocan PINCTRL_PIN(71, "SIO_UART1_TXD"), 214c8f5c4c7SCristina Ciocan PINCTRL_PIN(72, "SIO_UART1_RTS"), 215c8f5c4c7SCristina Ciocan PINCTRL_PIN(73, "SIO_UART1_CTS"), 216c8f5c4c7SCristina Ciocan PINCTRL_PIN(74, "SIO_UART2_RXD"), 217c8f5c4c7SCristina Ciocan PINCTRL_PIN(75, "SIO_UART2_TXD"), 218c8f5c4c7SCristina Ciocan PINCTRL_PIN(76, "SIO_UART2_RTS"), 219c8f5c4c7SCristina Ciocan PINCTRL_PIN(77, "SIO_UART2_CTS"), 220c8f5c4c7SCristina Ciocan PINCTRL_PIN(78, "SIO_I2C0_DATA"), 221c8f5c4c7SCristina Ciocan PINCTRL_PIN(79, "SIO_I2C0_CLK"), 222c8f5c4c7SCristina Ciocan PINCTRL_PIN(80, "SIO_I2C1_DATA"), 223c8f5c4c7SCristina Ciocan PINCTRL_PIN(81, "SIO_I2C1_CLK"), 224c8f5c4c7SCristina Ciocan PINCTRL_PIN(82, "SIO_I2C2_DATA"), 225c8f5c4c7SCristina Ciocan PINCTRL_PIN(83, "SIO_I2C2_CLK"), 226c8f5c4c7SCristina Ciocan PINCTRL_PIN(84, "SIO_I2C3_DATA"), 227c8f5c4c7SCristina Ciocan PINCTRL_PIN(85, "SIO_I2C3_CLK"), 228c8f5c4c7SCristina Ciocan PINCTRL_PIN(86, "SIO_I2C4_DATA"), 229c8f5c4c7SCristina Ciocan PINCTRL_PIN(87, "SIO_I2C4_CLK"), 230c8f5c4c7SCristina Ciocan PINCTRL_PIN(88, "SIO_I2C5_DATA"), 231c8f5c4c7SCristina Ciocan PINCTRL_PIN(89, "SIO_I2C5_CLK"), 232c8f5c4c7SCristina Ciocan PINCTRL_PIN(90, "SIO_I2C6_DATA"), 233c8f5c4c7SCristina Ciocan PINCTRL_PIN(91, "SIO_I2C6_CLK"), 234c8f5c4c7SCristina Ciocan PINCTRL_PIN(92, "GPIO_S0_SC92"), 235c8f5c4c7SCristina Ciocan PINCTRL_PIN(93, "GPIO_S0_SC93"), 236c8f5c4c7SCristina Ciocan PINCTRL_PIN(94, "SIO_PWM0"), 237c8f5c4c7SCristina Ciocan PINCTRL_PIN(95, "SIO_PWM1"), 238c8f5c4c7SCristina Ciocan PINCTRL_PIN(96, "PMC_PLT_CLK0"), 239c8f5c4c7SCristina Ciocan PINCTRL_PIN(97, "PMC_PLT_CLK1"), 240c8f5c4c7SCristina Ciocan PINCTRL_PIN(98, "PMC_PLT_CLK2"), 241c8f5c4c7SCristina Ciocan PINCTRL_PIN(99, "PMC_PLT_CLK3"), 242c8f5c4c7SCristina Ciocan PINCTRL_PIN(100, "PMC_PLT_CLK4"), 243c8f5c4c7SCristina Ciocan PINCTRL_PIN(101, "PMC_PLT_CLK5"), 244c8f5c4c7SCristina Ciocan }; 2455fae8b86SMika Westerberg 246c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { 247c8f5c4c7SCristina Ciocan 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 248c8f5c4c7SCristina Ciocan 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, 249c8f5c4c7SCristina Ciocan 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, 250c8f5c4c7SCristina Ciocan 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 251c8f5c4c7SCristina Ciocan 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, 252c8f5c4c7SCristina Ciocan 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, 253c8f5c4c7SCristina Ciocan 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 254c8f5c4c7SCristina Ciocan 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, 255c8f5c4c7SCristina Ciocan 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 256c8f5c4c7SCristina Ciocan 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, 257c8f5c4c7SCristina Ciocan 97, 100, 2585fae8b86SMika Westerberg }; 2595fae8b86SMika Westerberg 260c8f5c4c7SCristina Ciocan /* SCORE groups */ 261c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; 262c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; 263c8f5c4c7SCristina Ciocan 264c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 }; 265c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 }; 266c8f5c4c7SCristina Ciocan 267c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; 268c8f5c4c7SCristina Ciocan 269c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; 270c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; 271c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; 272c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; 273c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; 274c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; 275c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; 276c8f5c4c7SCristina Ciocan 277c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; 278c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; 279c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; 280c8f5c4c7SCristina Ciocan 281c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = { 282c8f5c4c7SCristina Ciocan 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 283c8f5c4c7SCristina Ciocan }; 2844f010b93SAndy Shevchenko static const unsigned int byt_score_sdcard_mux_values[] = { 285c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 286c8f5c4c7SCristina Ciocan }; 287c8f5c4c7SCristina Ciocan 288c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; 289c8f5c4c7SCristina Ciocan 290c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = { 291c8f5c4c7SCristina Ciocan 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 292c8f5c4c7SCristina Ciocan }; 293c8f5c4c7SCristina Ciocan 294c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = { 295c8f5c4c7SCristina Ciocan 42, 43, 44, 45, 46, 47, 48, 49, 50, 296c8f5c4c7SCristina Ciocan }; 297c8f5c4c7SCristina Ciocan 298c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; 299c8f5c4c7SCristina Ciocan 300c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 }; 301c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 }; 302c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 }; 303b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 }; 304b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 }; 305b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 }; 306c8f5c4c7SCristina Ciocan 307c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; 308c8f5c4c7SCristina Ciocan 3094f010b93SAndy Shevchenko static const struct intel_pingroup byt_score_groups[] = { 3104f010b93SAndy Shevchenko PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1), 3114f010b93SAndy Shevchenko PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1), 3124f010b93SAndy Shevchenko PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1), 3134f010b93SAndy Shevchenko PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1), 3144f010b93SAndy Shevchenko PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1), 3154f010b93SAndy Shevchenko PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1), 3164f010b93SAndy Shevchenko PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1), 3174f010b93SAndy Shevchenko PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1), 3184f010b93SAndy Shevchenko PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1), 3194f010b93SAndy Shevchenko PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1), 3204f010b93SAndy Shevchenko PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1), 3214f010b93SAndy Shevchenko PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1), 3224f010b93SAndy Shevchenko PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1), 3234f010b93SAndy Shevchenko PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1), 3244f010b93SAndy Shevchenko PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1), 3254f010b93SAndy Shevchenko PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values), 3264f010b93SAndy Shevchenko PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1), 3274f010b93SAndy Shevchenko PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1), 3284f010b93SAndy Shevchenko PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1), 3294f010b93SAndy Shevchenko PIN_GROUP("sata_grp", byt_score_sata_pins, 1), 3304f010b93SAndy Shevchenko PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1), 3314f010b93SAndy Shevchenko PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1), 3324f010b93SAndy Shevchenko PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1), 3334f010b93SAndy Shevchenko PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1), 3344f010b93SAndy Shevchenko PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1), 3354f010b93SAndy Shevchenko PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1), 3364f010b93SAndy Shevchenko PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1), 337c8f5c4c7SCristina Ciocan }; 338c8f5c4c7SCristina Ciocan 339c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = { 340c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", 341c8f5c4c7SCristina Ciocan }; 342c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = { 343c8f5c4c7SCristina Ciocan "pwm0_grp", "pwm1_grp", 344c8f5c4c7SCristina Ciocan }; 345c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = { 346c8f5c4c7SCristina Ciocan "ssp0_grp", "ssp1_grp", "ssp2_grp", 347c8f5c4c7SCristina Ciocan }; 348c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; 349c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = { 350c8f5c4c7SCristina Ciocan "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", 351c8f5c4c7SCristina Ciocan "i2c6_grp", 352c8f5c4c7SCristina Ciocan }; 353c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; 354c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" }; 355c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" }; 356c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" }; 357c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" }; 358c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = { 359c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 360c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", 361c8f5c4c7SCristina Ciocan }; 362c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" }; 363c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = { 364c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", 365c8f5c4c7SCristina Ciocan "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", 366c8f5c4c7SCristina Ciocan "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", 367c8f5c4c7SCristina Ciocan "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", 368c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 369c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", 370c8f5c4c7SCristina Ciocan }; 371c8f5c4c7SCristina Ciocan 3724f010b93SAndy Shevchenko static const struct intel_function byt_score_functions[] = { 373c8f5c4c7SCristina Ciocan FUNCTION("uart", byt_score_uart_groups), 374c8f5c4c7SCristina Ciocan FUNCTION("pwm", byt_score_pwm_groups), 375c8f5c4c7SCristina Ciocan FUNCTION("ssp", byt_score_ssp_groups), 376c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_score_spi_groups), 377c8f5c4c7SCristina Ciocan FUNCTION("i2c", byt_score_i2c_groups), 378c8f5c4c7SCristina Ciocan FUNCTION("sdcard", byt_score_sdcard_groups), 379c8f5c4c7SCristina Ciocan FUNCTION("sdio", byt_score_sdio_groups), 380c8f5c4c7SCristina Ciocan FUNCTION("emmc", byt_score_emmc_groups), 381c8f5c4c7SCristina Ciocan FUNCTION("lpc", byt_score_lpc_groups), 382c8f5c4c7SCristina Ciocan FUNCTION("sata", byt_score_sata_groups), 383c8f5c4c7SCristina Ciocan FUNCTION("plt_clk", byt_score_plt_clk_groups), 384c8f5c4c7SCristina Ciocan FUNCTION("smbus", byt_score_smbus_groups), 385c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_score_gpio_groups), 386c8f5c4c7SCristina Ciocan }; 387c8f5c4c7SCristina Ciocan 388c8f5c4c7SCristina Ciocan static const struct byt_community byt_score_communities[] = { 389c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), 390c8f5c4c7SCristina Ciocan }; 391c8f5c4c7SCristina Ciocan 392c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_score_soc_data = { 393c8f5c4c7SCristina Ciocan .uid = BYT_SCORE_ACPI_UID, 394c8f5c4c7SCristina Ciocan .pins = byt_score_pins, 395c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_score_pins), 396c8f5c4c7SCristina Ciocan .groups = byt_score_groups, 397c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_score_groups), 398c8f5c4c7SCristina Ciocan .functions = byt_score_functions, 399c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_score_functions), 400c8f5c4c7SCristina Ciocan .communities = byt_score_communities, 401c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_score_communities), 402c8f5c4c7SCristina Ciocan }; 403c8f5c4c7SCristina Ciocan 404c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */ 405c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = { 406c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_S50"), 407c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_S51"), 408c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_S52"), 409c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_S53"), 410c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_S54"), 411c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_S55"), 412c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_S56"), 413c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_S57"), 414c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_S58"), 415c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_S59"), 416c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_S510"), 417c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), 418c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "PMC_SUSCLK0"), 419c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_S513"), 420c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "USB_ULPI_RST"), 421c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), 422c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "PMC_PWRBTN"), 423c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_S517"), 424c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "PMC_SUS_STAT"), 425c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "USB_OC0"), 426c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "USB_OC1"), 427c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "PCU_SPI_CS1"), 428c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_S522"), 429c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_S523"), 430c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_S524"), 431c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_S525"), 432c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_S526"), 433c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_S527"), 434c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "GPIO_S528"), 435c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "GPIO_S529"), 436c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "GPIO_S530"), 437c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "USB_ULPI_CLK"), 438c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "USB_ULPI_DATA0"), 439c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "USB_ULPI_DATA1"), 440c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "USB_ULPI_DATA2"), 441c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "USB_ULPI_DATA3"), 442c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "USB_ULPI_DATA4"), 443c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "USB_ULPI_DATA5"), 444c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "USB_ULPI_DATA6"), 445c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "USB_ULPI_DATA7"), 446c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "USB_ULPI_DIR"), 447c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "USB_ULPI_NXT"), 448c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "USB_ULPI_STP"), 449c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "USB_ULPI_REFCLK"), 450c8f5c4c7SCristina Ciocan }; 451c8f5c4c7SCristina Ciocan 452c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 453c8f5c4c7SCristina Ciocan 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 454c8f5c4c7SCristina Ciocan 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, 455c8f5c4c7SCristina Ciocan 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 456c8f5c4c7SCristina Ciocan 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, 457c8f5c4c7SCristina Ciocan 52, 53, 59, 40, 458c8f5c4c7SCristina Ciocan }; 459c8f5c4c7SCristina Ciocan 460c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; 4614f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 }; 4624f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 }; 463c8f5c4c7SCristina Ciocan 464c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = { 465c8f5c4c7SCristina Ciocan 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 466c8f5c4c7SCristina Ciocan }; 4674f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_mode_values[] = { 468c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 469c8f5c4c7SCristina Ciocan }; 4704f010b93SAndy Shevchenko static const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = { 4714f010b93SAndy Shevchenko 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 472c8f5c4c7SCristina Ciocan }; 473c8f5c4c7SCristina Ciocan 474c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; 4754f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 }; 4764f010b93SAndy Shevchenko static const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 }; 477c8f5c4c7SCristina Ciocan 4784f010b93SAndy Shevchenko static const struct intel_pingroup byt_sus_groups[] = { 4794f010b93SAndy Shevchenko PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values), 4804f010b93SAndy Shevchenko PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values), 4814f010b93SAndy Shevchenko PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values), 4824f010b93SAndy Shevchenko PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values), 4834f010b93SAndy Shevchenko PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values), 4844f010b93SAndy Shevchenko PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values), 485c8f5c4c7SCristina Ciocan }; 486c8f5c4c7SCristina Ciocan 487c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = { 488c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp", 489c8f5c4c7SCristina Ciocan }; 490c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; 491c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = { 4924f010b93SAndy Shevchenko "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio", 493c8f5c4c7SCristina Ciocan }; 494c8f5c4c7SCristina Ciocan 4954f010b93SAndy Shevchenko static const struct intel_function byt_sus_functions[] = { 496c8f5c4c7SCristina Ciocan FUNCTION("usb", byt_sus_usb_groups), 497c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_sus_spi_groups), 498c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_sus_gpio_groups), 499c8f5c4c7SCristina Ciocan }; 500c8f5c4c7SCristina Ciocan 501c8f5c4c7SCristina Ciocan static const struct byt_community byt_sus_communities[] = { 502c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), 503c8f5c4c7SCristina Ciocan }; 504c8f5c4c7SCristina Ciocan 505c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_sus_soc_data = { 506c8f5c4c7SCristina Ciocan .uid = BYT_SUS_ACPI_UID, 507c8f5c4c7SCristina Ciocan .pins = byt_sus_pins, 508c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_sus_pins), 509c8f5c4c7SCristina Ciocan .groups = byt_sus_groups, 510c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_sus_groups), 511c8f5c4c7SCristina Ciocan .functions = byt_sus_functions, 512c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_sus_functions), 513c8f5c4c7SCristina Ciocan .communities = byt_sus_communities, 514c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_sus_communities), 515c8f5c4c7SCristina Ciocan }; 516c8f5c4c7SCristina Ciocan 517c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = { 518c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_NCORE0"), 519c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_NCORE1"), 520c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_NCORE2"), 521c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_NCORE3"), 522c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_NCORE4"), 523c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_NCORE5"), 524c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_NCORE6"), 525c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_NCORE7"), 526c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_NCORE8"), 527c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_NCORE9"), 528c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_NCORE10"), 529c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "GPIO_NCORE11"), 530c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "GPIO_NCORE12"), 531c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_NCORE13"), 532c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_NCORE14"), 533c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_NCORE15"), 534c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "GPIO_NCORE16"), 535c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_NCORE17"), 536c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "GPIO_NCORE18"), 537c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "GPIO_NCORE19"), 538c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "GPIO_NCORE20"), 539c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "GPIO_NCORE21"), 540c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_NCORE22"), 541c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_NCORE23"), 542c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_NCORE24"), 543c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_NCORE25"), 544c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_NCORE26"), 545c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_NCORE27"), 546c8f5c4c7SCristina Ciocan }; 547c8f5c4c7SCristina Ciocan 548939330d7SAndy Shevchenko static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 549c8f5c4c7SCristina Ciocan 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 550c8f5c4c7SCristina Ciocan 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, 551c8f5c4c7SCristina Ciocan 3, 6, 10, 13, 2, 5, 9, 7, 552c8f5c4c7SCristina Ciocan }; 553c8f5c4c7SCristina Ciocan 554c8f5c4c7SCristina Ciocan static const struct byt_community byt_ncore_communities[] = { 555c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), 556c8f5c4c7SCristina Ciocan }; 557c8f5c4c7SCristina Ciocan 558c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_ncore_soc_data = { 559c8f5c4c7SCristina Ciocan .uid = BYT_NCORE_ACPI_UID, 560c8f5c4c7SCristina Ciocan .pins = byt_ncore_pins, 561c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_ncore_pins), 562c8f5c4c7SCristina Ciocan .communities = byt_ncore_communities, 563c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_ncore_communities), 564c8f5c4c7SCristina Ciocan }; 565c8f5c4c7SCristina Ciocan 566c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data *byt_soc_data[] = { 567c8f5c4c7SCristina Ciocan &byt_score_soc_data, 568c8f5c4c7SCristina Ciocan &byt_sus_soc_data, 569c8f5c4c7SCristina Ciocan &byt_ncore_soc_data, 570166d6e2aSAndy Shevchenko NULL 571c8f5c4c7SCristina Ciocan }; 572c8f5c4c7SCristina Ciocan 573c501d0b1SCristina Ciocan static struct byt_community *byt_get_community(struct byt_gpio *vg, 574c501d0b1SCristina Ciocan unsigned int pin) 575c501d0b1SCristina Ciocan { 576c501d0b1SCristina Ciocan struct byt_community *comm; 577c501d0b1SCristina Ciocan int i; 578c501d0b1SCristina Ciocan 579c501d0b1SCristina Ciocan for (i = 0; i < vg->soc_data->ncommunities; i++) { 580c501d0b1SCristina Ciocan comm = vg->communities_copy + i; 581c501d0b1SCristina Ciocan if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) 582c501d0b1SCristina Ciocan return comm; 583c501d0b1SCristina Ciocan } 584c501d0b1SCristina Ciocan 585c501d0b1SCristina Ciocan return NULL; 586c501d0b1SCristina Ciocan } 587c501d0b1SCristina Ciocan 588c501d0b1SCristina Ciocan static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, 5895fae8b86SMika Westerberg int reg) 5905fae8b86SMika Westerberg { 591c501d0b1SCristina Ciocan struct byt_community *comm = byt_get_community(vg, offset); 5921b89970dSAndy Shevchenko u32 reg_offset; 5935fae8b86SMika Westerberg 594c501d0b1SCristina Ciocan if (!comm) 595c501d0b1SCristina Ciocan return NULL; 596c501d0b1SCristina Ciocan 597c501d0b1SCristina Ciocan offset -= comm->pin_base; 5981b89970dSAndy Shevchenko switch (reg) { 5991b89970dSAndy Shevchenko case BYT_INT_STAT_REG: 6005fae8b86SMika Westerberg reg_offset = (offset / 32) * 4; 6011b89970dSAndy Shevchenko break; 6021b89970dSAndy Shevchenko case BYT_DEBOUNCE_REG: 6031b89970dSAndy Shevchenko reg_offset = 0; 6041b89970dSAndy Shevchenko break; 6051b89970dSAndy Shevchenko default: 606c501d0b1SCristina Ciocan reg_offset = comm->pad_map[offset] * 16; 6071b89970dSAndy Shevchenko break; 6081b89970dSAndy Shevchenko } 6095fae8b86SMika Westerberg 610c501d0b1SCristina Ciocan return comm->reg_base + reg_offset + reg; 6115fae8b86SMika Westerberg } 6125fae8b86SMika Westerberg 613c501d0b1SCristina Ciocan static int byt_get_groups_count(struct pinctrl_dev *pctldev) 61495f0972cSMika Westerberg { 615c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 616c501d0b1SCristina Ciocan 617c501d0b1SCristina Ciocan return vg->soc_data->ngroups; 618c501d0b1SCristina Ciocan } 619c501d0b1SCristina Ciocan 620c501d0b1SCristina Ciocan static const char *byt_get_group_name(struct pinctrl_dev *pctldev, 621c501d0b1SCristina Ciocan unsigned int selector) 622c501d0b1SCristina Ciocan { 623c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 624c501d0b1SCristina Ciocan 625c501d0b1SCristina Ciocan return vg->soc_data->groups[selector].name; 626c501d0b1SCristina Ciocan } 627c501d0b1SCristina Ciocan 628c501d0b1SCristina Ciocan static int byt_get_group_pins(struct pinctrl_dev *pctldev, 629c501d0b1SCristina Ciocan unsigned int selector, 630c501d0b1SCristina Ciocan const unsigned int **pins, 631c501d0b1SCristina Ciocan unsigned int *num_pins) 632c501d0b1SCristina Ciocan { 633c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 634c501d0b1SCristina Ciocan 635c501d0b1SCristina Ciocan *pins = vg->soc_data->groups[selector].pins; 636c501d0b1SCristina Ciocan *num_pins = vg->soc_data->groups[selector].npins; 637c501d0b1SCristina Ciocan 638c501d0b1SCristina Ciocan return 0; 639c501d0b1SCristina Ciocan } 640c501d0b1SCristina Ciocan 641c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = { 642c501d0b1SCristina Ciocan .get_groups_count = byt_get_groups_count, 643c501d0b1SCristina Ciocan .get_group_name = byt_get_group_name, 644c501d0b1SCristina Ciocan .get_group_pins = byt_get_group_pins, 645c501d0b1SCristina Ciocan }; 646c501d0b1SCristina Ciocan 647c501d0b1SCristina Ciocan static int byt_get_functions_count(struct pinctrl_dev *pctldev) 648c501d0b1SCristina Ciocan { 649c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 650c501d0b1SCristina Ciocan 651c501d0b1SCristina Ciocan return vg->soc_data->nfunctions; 652c501d0b1SCristina Ciocan } 653c501d0b1SCristina Ciocan 654c501d0b1SCristina Ciocan static const char *byt_get_function_name(struct pinctrl_dev *pctldev, 655c501d0b1SCristina Ciocan unsigned int selector) 656c501d0b1SCristina Ciocan { 657c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 658c501d0b1SCristina Ciocan 659c501d0b1SCristina Ciocan return vg->soc_data->functions[selector].name; 660c501d0b1SCristina Ciocan } 661c501d0b1SCristina Ciocan 662c501d0b1SCristina Ciocan static int byt_get_function_groups(struct pinctrl_dev *pctldev, 663c501d0b1SCristina Ciocan unsigned int selector, 664c501d0b1SCristina Ciocan const char * const **groups, 665c501d0b1SCristina Ciocan unsigned int *num_groups) 666c501d0b1SCristina Ciocan { 667c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 668c501d0b1SCristina Ciocan 669c501d0b1SCristina Ciocan *groups = vg->soc_data->functions[selector].groups; 670c501d0b1SCristina Ciocan *num_groups = vg->soc_data->functions[selector].ngroups; 671c501d0b1SCristina Ciocan 672c501d0b1SCristina Ciocan return 0; 673c501d0b1SCristina Ciocan } 674c501d0b1SCristina Ciocan 675c501d0b1SCristina Ciocan static void byt_set_group_simple_mux(struct byt_gpio *vg, 6764f010b93SAndy Shevchenko const struct intel_pingroup group, 6774f010b93SAndy Shevchenko unsigned int func) 678c501d0b1SCristina Ciocan { 679c501d0b1SCristina Ciocan unsigned long flags; 680c501d0b1SCristina Ciocan int i; 681c501d0b1SCristina Ciocan 682c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 683c501d0b1SCristina Ciocan 684c501d0b1SCristina Ciocan for (i = 0; i < group.npins; i++) { 685c501d0b1SCristina Ciocan void __iomem *padcfg0; 686c501d0b1SCristina Ciocan u32 value; 687c501d0b1SCristina Ciocan 688c501d0b1SCristina Ciocan padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 689c501d0b1SCristina Ciocan if (!padcfg0) { 690c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 691c501d0b1SCristina Ciocan "Group %s, pin %i not muxed (no padcfg0)\n", 692c501d0b1SCristina Ciocan group.name, i); 693c501d0b1SCristina Ciocan continue; 694c501d0b1SCristina Ciocan } 695c501d0b1SCristina Ciocan 696c501d0b1SCristina Ciocan value = readl(padcfg0); 697c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 698c501d0b1SCristina Ciocan value |= func; 699c501d0b1SCristina Ciocan writel(value, padcfg0); 700c501d0b1SCristina Ciocan } 701c501d0b1SCristina Ciocan 702c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 703c501d0b1SCristina Ciocan } 704c501d0b1SCristina Ciocan 705c501d0b1SCristina Ciocan static void byt_set_group_mixed_mux(struct byt_gpio *vg, 7064f010b93SAndy Shevchenko const struct intel_pingroup group, 7074f010b93SAndy Shevchenko const unsigned int *func) 708c501d0b1SCristina Ciocan { 709c501d0b1SCristina Ciocan unsigned long flags; 710c501d0b1SCristina Ciocan int i; 711c501d0b1SCristina Ciocan 712c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 713c501d0b1SCristina Ciocan 714c501d0b1SCristina Ciocan for (i = 0; i < group.npins; i++) { 715c501d0b1SCristina Ciocan void __iomem *padcfg0; 716c501d0b1SCristina Ciocan u32 value; 717c501d0b1SCristina Ciocan 718c501d0b1SCristina Ciocan padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 719c501d0b1SCristina Ciocan if (!padcfg0) { 720c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 721c501d0b1SCristina Ciocan "Group %s, pin %i not muxed (no padcfg0)\n", 722c501d0b1SCristina Ciocan group.name, i); 723c501d0b1SCristina Ciocan continue; 724c501d0b1SCristina Ciocan } 725c501d0b1SCristina Ciocan 726c501d0b1SCristina Ciocan value = readl(padcfg0); 727c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 728c501d0b1SCristina Ciocan value |= func[i]; 729c501d0b1SCristina Ciocan writel(value, padcfg0); 730c501d0b1SCristina Ciocan } 731c501d0b1SCristina Ciocan 732c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 733c501d0b1SCristina Ciocan } 734c501d0b1SCristina Ciocan 735c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 736c501d0b1SCristina Ciocan unsigned int group_selector) 737c501d0b1SCristina Ciocan { 738c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 7394f010b93SAndy Shevchenko const struct intel_function func = vg->soc_data->functions[func_selector]; 7404f010b93SAndy Shevchenko const struct intel_pingroup group = vg->soc_data->groups[group_selector]; 741c501d0b1SCristina Ciocan 7424f010b93SAndy Shevchenko if (group.modes) 7434f010b93SAndy Shevchenko byt_set_group_mixed_mux(vg, group, group.modes); 7444f010b93SAndy Shevchenko else if (!strcmp(func.name, "gpio")) 745c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); 746c501d0b1SCristina Ciocan else 7474f010b93SAndy Shevchenko byt_set_group_simple_mux(vg, group, group.mode); 748c501d0b1SCristina Ciocan 749c501d0b1SCristina Ciocan return 0; 750c501d0b1SCristina Ciocan } 751c501d0b1SCristina Ciocan 752939330d7SAndy Shevchenko static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned int offset) 753c501d0b1SCristina Ciocan { 754c501d0b1SCristina Ciocan /* SCORE pin 92-93 */ 755c501d0b1SCristina Ciocan if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) && 756c501d0b1SCristina Ciocan offset >= 92 && offset <= 93) 757a705f9c1SAndy Shevchenko return BYT_ALTER_GPIO_MUX; 758c501d0b1SCristina Ciocan 759c501d0b1SCristina Ciocan /* SUS pin 11-21 */ 760c501d0b1SCristina Ciocan if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) && 761c501d0b1SCristina Ciocan offset >= 11 && offset <= 21) 762a705f9c1SAndy Shevchenko return BYT_ALTER_GPIO_MUX; 763c501d0b1SCristina Ciocan 764a705f9c1SAndy Shevchenko return BYT_DEFAULT_GPIO_MUX; 765c501d0b1SCristina Ciocan } 766c501d0b1SCristina Ciocan 767c501d0b1SCristina Ciocan static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) 768c501d0b1SCristina Ciocan { 769c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 77095f0972cSMika Westerberg unsigned long flags; 77195f0972cSMika Westerberg u32 value; 77295f0972cSMika Westerberg 77378e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 77495f0972cSMika Westerberg value = readl(reg); 77595f0972cSMika Westerberg value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); 77695f0972cSMika Westerberg writel(value, reg); 77778e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 77895f0972cSMika Westerberg } 77995f0972cSMika Westerberg 780c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, 781c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 782c501d0b1SCristina Ciocan unsigned int offset) 7835fae8b86SMika Westerberg { 784c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 785c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 786f8323b6bSMika Westerberg u32 value, gpio_mux; 78739ce8150SMika Westerberg unsigned long flags; 78839ce8150SMika Westerberg 78978e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 7905fae8b86SMika Westerberg 7915fae8b86SMika Westerberg /* 7925fae8b86SMika Westerberg * In most cases, func pin mux 000 means GPIO function. 7935fae8b86SMika Westerberg * But, some pins may have func pin mux 001 represents 794f8323b6bSMika Westerberg * GPIO function. 795f8323b6bSMika Westerberg * 796f8323b6bSMika Westerberg * Because there are devices out there where some pins were not 797f8323b6bSMika Westerberg * configured correctly we allow changing the mux value from 798f8323b6bSMika Westerberg * request (but print out warning about that). 7995fae8b86SMika Westerberg */ 8005fae8b86SMika Westerberg value = readl(reg) & BYT_PIN_MUX; 801f8323b6bSMika Westerberg gpio_mux = byt_get_gpio_mux(vg, offset); 802b5894d12SHans de Goede if (gpio_mux != value) { 803f8323b6bSMika Westerberg value = readl(reg) & ~BYT_PIN_MUX; 804f8323b6bSMika Westerberg value |= gpio_mux; 805f8323b6bSMika Westerberg writel(value, reg); 806f8323b6bSMika Westerberg 807b5894d12SHans de Goede dev_warn(&vg->pdev->dev, FW_BUG 808f8323b6bSMika Westerberg "pin %u forcibly re-configured as GPIO\n", offset); 8095fae8b86SMika Westerberg } 8105fae8b86SMika Westerberg 81178e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 81239ce8150SMika Westerberg 8135fae8b86SMika Westerberg pm_runtime_get(&vg->pdev->dev); 8145fae8b86SMika Westerberg 8155fae8b86SMika Westerberg return 0; 8165fae8b86SMika Westerberg } 8175fae8b86SMika Westerberg 818c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, 819c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 820c501d0b1SCristina Ciocan unsigned int offset) 821c501d0b1SCristina Ciocan { 822c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 823c501d0b1SCristina Ciocan 824c501d0b1SCristina Ciocan byt_gpio_clear_triggering(vg, offset); 825c501d0b1SCristina Ciocan pm_runtime_put(&vg->pdev->dev); 826c501d0b1SCristina Ciocan } 827c501d0b1SCristina Ciocan 828c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, 829c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 830c501d0b1SCristina Ciocan unsigned int offset, 831c501d0b1SCristina Ciocan bool input) 832c501d0b1SCristina Ciocan { 833c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 834c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 835c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 836c501d0b1SCristina Ciocan unsigned long flags; 837c501d0b1SCristina Ciocan u32 value; 838c501d0b1SCristina Ciocan 839c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 840c501d0b1SCristina Ciocan 841c501d0b1SCristina Ciocan value = readl(val_reg); 842c501d0b1SCristina Ciocan value &= ~BYT_DIR_MASK; 843c501d0b1SCristina Ciocan if (input) 844c501d0b1SCristina Ciocan value |= BYT_OUTPUT_EN; 845c501d0b1SCristina Ciocan else 846c501d0b1SCristina Ciocan /* 847c501d0b1SCristina Ciocan * Before making any direction modifications, do a check if gpio 848c501d0b1SCristina Ciocan * is set for direct IRQ. On baytrail, setting GPIO to output 849c501d0b1SCristina Ciocan * does not make sense, so let's at least warn the caller before 850c501d0b1SCristina Ciocan * they shoot themselves in the foot. 851c501d0b1SCristina Ciocan */ 852c501d0b1SCristina Ciocan WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, 853c501d0b1SCristina Ciocan "Potential Error: Setting GPIO with direct_irq_en to output"); 854c501d0b1SCristina Ciocan writel(value, val_reg); 855c501d0b1SCristina Ciocan 856c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 857c501d0b1SCristina Ciocan 858c501d0b1SCristina Ciocan return 0; 859c501d0b1SCristina Ciocan } 860c501d0b1SCristina Ciocan 861c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = { 862c501d0b1SCristina Ciocan .get_functions_count = byt_get_functions_count, 863c501d0b1SCristina Ciocan .get_function_name = byt_get_function_name, 864c501d0b1SCristina Ciocan .get_function_groups = byt_get_function_groups, 865c501d0b1SCristina Ciocan .set_mux = byt_set_mux, 866c501d0b1SCristina Ciocan .gpio_request_enable = byt_gpio_request_enable, 867c501d0b1SCristina Ciocan .gpio_disable_free = byt_gpio_disable_free, 868c501d0b1SCristina Ciocan .gpio_set_direction = byt_gpio_set_direction, 869c501d0b1SCristina Ciocan }; 870c501d0b1SCristina Ciocan 871c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength) 872c501d0b1SCristina Ciocan { 873c501d0b1SCristina Ciocan switch (reg & BYT_PULL_STR_MASK) { 874c501d0b1SCristina Ciocan case BYT_PULL_STR_2K: 875c501d0b1SCristina Ciocan *strength = 2000; 876c501d0b1SCristina Ciocan break; 877c501d0b1SCristina Ciocan case BYT_PULL_STR_10K: 878c501d0b1SCristina Ciocan *strength = 10000; 879c501d0b1SCristina Ciocan break; 880c501d0b1SCristina Ciocan case BYT_PULL_STR_20K: 881c501d0b1SCristina Ciocan *strength = 20000; 882c501d0b1SCristina Ciocan break; 883c501d0b1SCristina Ciocan case BYT_PULL_STR_40K: 884c501d0b1SCristina Ciocan *strength = 40000; 885c501d0b1SCristina Ciocan break; 886c501d0b1SCristina Ciocan } 887c501d0b1SCristina Ciocan } 888c501d0b1SCristina Ciocan 889c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength) 890c501d0b1SCristina Ciocan { 891c501d0b1SCristina Ciocan *reg &= ~BYT_PULL_STR_MASK; 892c501d0b1SCristina Ciocan 893c501d0b1SCristina Ciocan switch (strength) { 894c501d0b1SCristina Ciocan case 2000: 895c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_2K; 896c501d0b1SCristina Ciocan break; 897c501d0b1SCristina Ciocan case 10000: 898c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_10K; 899c501d0b1SCristina Ciocan break; 900c501d0b1SCristina Ciocan case 20000: 901c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_20K; 902c501d0b1SCristina Ciocan break; 903c501d0b1SCristina Ciocan case 40000: 904c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_40K; 905c501d0b1SCristina Ciocan break; 906c501d0b1SCristina Ciocan default: 907c501d0b1SCristina Ciocan return -EINVAL; 908c501d0b1SCristina Ciocan } 909c501d0b1SCristina Ciocan 910c501d0b1SCristina Ciocan return 0; 911c501d0b1SCristina Ciocan } 912c501d0b1SCristina Ciocan 913c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, 914c501d0b1SCristina Ciocan unsigned long *config) 915c501d0b1SCristina Ciocan { 916c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 917c501d0b1SCristina Ciocan enum pin_config_param param = pinconf_to_config_param(*config); 918c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 919c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 92004ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 921c501d0b1SCristina Ciocan unsigned long flags; 922658b476cSCristina Ciocan u32 conf, pull, val, debounce; 923c501d0b1SCristina Ciocan u16 arg = 0; 924c501d0b1SCristina Ciocan 925c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 926c501d0b1SCristina Ciocan conf = readl(conf_reg); 927c501d0b1SCristina Ciocan pull = conf & BYT_PULL_ASSIGN_MASK; 928c501d0b1SCristina Ciocan val = readl(val_reg); 929c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 930c501d0b1SCristina Ciocan 931c501d0b1SCristina Ciocan switch (param) { 932c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 933c501d0b1SCristina Ciocan if (pull) 934c501d0b1SCristina Ciocan return -EINVAL; 935c501d0b1SCristina Ciocan break; 936c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 937c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 938c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) 939c501d0b1SCristina Ciocan return -EINVAL; 940c501d0b1SCristina Ciocan 941c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 942c501d0b1SCristina Ciocan 943c501d0b1SCristina Ciocan break; 944c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 945c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 946c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) 947c501d0b1SCristina Ciocan return -EINVAL; 948c501d0b1SCristina Ciocan 949c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 950c501d0b1SCristina Ciocan 951c501d0b1SCristina Ciocan break; 952658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 953658b476cSCristina Ciocan if (!(conf & BYT_DEBOUNCE_EN)) 954658b476cSCristina Ciocan return -EINVAL; 955658b476cSCristina Ciocan 956658b476cSCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 95704ff5a09SAndy Shevchenko debounce = readl(db_reg); 958658b476cSCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 959658b476cSCristina Ciocan 960658b476cSCristina Ciocan switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { 961658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_375US: 962658b476cSCristina Ciocan arg = 375; 963658b476cSCristina Ciocan break; 964658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_750US: 965658b476cSCristina Ciocan arg = 750; 966658b476cSCristina Ciocan break; 967658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_1500US: 968658b476cSCristina Ciocan arg = 1500; 969658b476cSCristina Ciocan break; 970658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_3MS: 971658b476cSCristina Ciocan arg = 3000; 972658b476cSCristina Ciocan break; 973658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_6MS: 974658b476cSCristina Ciocan arg = 6000; 975658b476cSCristina Ciocan break; 976658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_12MS: 977658b476cSCristina Ciocan arg = 12000; 978658b476cSCristina Ciocan break; 979658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_24MS: 980658b476cSCristina Ciocan arg = 24000; 981658b476cSCristina Ciocan break; 982658b476cSCristina Ciocan default: 983658b476cSCristina Ciocan return -EINVAL; 984658b476cSCristina Ciocan } 985658b476cSCristina Ciocan 986658b476cSCristina Ciocan break; 987c501d0b1SCristina Ciocan default: 988c501d0b1SCristina Ciocan return -ENOTSUPP; 989c501d0b1SCristina Ciocan } 990c501d0b1SCristina Ciocan 991c501d0b1SCristina Ciocan *config = pinconf_to_config_packed(param, arg); 992c501d0b1SCristina Ciocan 993c501d0b1SCristina Ciocan return 0; 994c501d0b1SCristina Ciocan } 995c501d0b1SCristina Ciocan 996c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, 997c501d0b1SCristina Ciocan unsigned int offset, 998c501d0b1SCristina Ciocan unsigned long *configs, 999c501d0b1SCristina Ciocan unsigned int num_configs) 1000c501d0b1SCristina Ciocan { 1001c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1002c501d0b1SCristina Ciocan unsigned int param, arg; 1003c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1004c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 100504ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 1006c501d0b1SCristina Ciocan unsigned long flags; 1007658b476cSCristina Ciocan u32 conf, val, debounce; 1008c501d0b1SCristina Ciocan int i, ret = 0; 1009c501d0b1SCristina Ciocan 1010c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1011c501d0b1SCristina Ciocan 1012c501d0b1SCristina Ciocan conf = readl(conf_reg); 1013c501d0b1SCristina Ciocan val = readl(val_reg); 1014c501d0b1SCristina Ciocan 1015c501d0b1SCristina Ciocan for (i = 0; i < num_configs; i++) { 1016c501d0b1SCristina Ciocan param = pinconf_to_config_param(configs[i]); 1017c501d0b1SCristina Ciocan arg = pinconf_to_config_argument(configs[i]); 1018c501d0b1SCristina Ciocan 1019c501d0b1SCristina Ciocan switch (param) { 1020c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 1021c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1022c501d0b1SCristina Ciocan break; 1023c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 1024c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1025c501d0b1SCristina Ciocan if (arg == 1) 1026c501d0b1SCristina Ciocan arg = 2000; 1027c501d0b1SCristina Ciocan 1028c501d0b1SCristina Ciocan /* 1029c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1030c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1031c501d0b1SCristina Ciocan */ 1032c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1033c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1034c501d0b1SCristina Ciocan writel(val, val_reg); 1035c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 1036c501d0b1SCristina Ciocan "pin %u forcibly set to input mode\n", 1037c501d0b1SCristina Ciocan offset); 1038c501d0b1SCristina Ciocan } 1039c501d0b1SCristina Ciocan 1040c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1041c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_DOWN; 1042c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1043c501d0b1SCristina Ciocan 1044c501d0b1SCristina Ciocan break; 1045c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 1046c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1047c501d0b1SCristina Ciocan if (arg == 1) 1048c501d0b1SCristina Ciocan arg = 2000; 1049c501d0b1SCristina Ciocan 1050c501d0b1SCristina Ciocan /* 1051c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1052c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1053c501d0b1SCristina Ciocan */ 1054c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1055c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1056c501d0b1SCristina Ciocan writel(val, val_reg); 1057c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 1058c501d0b1SCristina Ciocan "pin %u forcibly set to input mode\n", 1059c501d0b1SCristina Ciocan offset); 1060c501d0b1SCristina Ciocan } 1061c501d0b1SCristina Ciocan 1062c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1063c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_UP; 1064c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1065c501d0b1SCristina Ciocan 1066c501d0b1SCristina Ciocan break; 1067658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 106804ff5a09SAndy Shevchenko debounce = readl(db_reg); 106904ff5a09SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 1070658b476cSCristina Ciocan 1071827e1579SAndy Shevchenko if (arg) 1072827e1579SAndy Shevchenko conf |= BYT_DEBOUNCE_EN; 1073827e1579SAndy Shevchenko else 1074827e1579SAndy Shevchenko conf &= ~BYT_DEBOUNCE_EN; 1075827e1579SAndy Shevchenko 1076658b476cSCristina Ciocan switch (arg) { 1077658b476cSCristina Ciocan case 375: 107804ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_375US; 1079658b476cSCristina Ciocan break; 1080658b476cSCristina Ciocan case 750: 108104ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_750US; 1082658b476cSCristina Ciocan break; 1083658b476cSCristina Ciocan case 1500: 108404ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_1500US; 1085658b476cSCristina Ciocan break; 1086658b476cSCristina Ciocan case 3000: 108704ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_3MS; 1088658b476cSCristina Ciocan break; 1089658b476cSCristina Ciocan case 6000: 109004ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_6MS; 1091658b476cSCristina Ciocan break; 1092658b476cSCristina Ciocan case 12000: 109304ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_12MS; 1094658b476cSCristina Ciocan break; 1095658b476cSCristina Ciocan case 24000: 109604ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_24MS; 1097658b476cSCristina Ciocan break; 1098658b476cSCristina Ciocan default: 1099827e1579SAndy Shevchenko if (arg) 1100658b476cSCristina Ciocan ret = -EINVAL; 1101827e1579SAndy Shevchenko break; 1102658b476cSCristina Ciocan } 1103658b476cSCristina Ciocan 110404ff5a09SAndy Shevchenko if (!ret) 110504ff5a09SAndy Shevchenko writel(debounce, db_reg); 1106658b476cSCristina Ciocan break; 1107c501d0b1SCristina Ciocan default: 1108c501d0b1SCristina Ciocan ret = -ENOTSUPP; 1109c501d0b1SCristina Ciocan } 1110c501d0b1SCristina Ciocan 1111c501d0b1SCristina Ciocan if (ret) 1112c501d0b1SCristina Ciocan break; 1113c501d0b1SCristina Ciocan } 1114c501d0b1SCristina Ciocan 1115c501d0b1SCristina Ciocan if (!ret) 1116c501d0b1SCristina Ciocan writel(conf, conf_reg); 1117c501d0b1SCristina Ciocan 1118c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1119c501d0b1SCristina Ciocan 1120c501d0b1SCristina Ciocan return ret; 1121c501d0b1SCristina Ciocan } 1122c501d0b1SCristina Ciocan 1123c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = { 1124c501d0b1SCristina Ciocan .is_generic = true, 1125c501d0b1SCristina Ciocan .pin_config_get = byt_pin_config_get, 1126c501d0b1SCristina Ciocan .pin_config_set = byt_pin_config_set, 1127c501d0b1SCristina Ciocan }; 1128c501d0b1SCristina Ciocan 1129c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = { 1130c501d0b1SCristina Ciocan .pctlops = &byt_pinctrl_ops, 1131c501d0b1SCristina Ciocan .pmxops = &byt_pinmux_ops, 1132c501d0b1SCristina Ciocan .confops = &byt_pinconf_ops, 1133c501d0b1SCristina Ciocan .owner = THIS_MODULE, 1134c501d0b1SCristina Ciocan }; 1135c501d0b1SCristina Ciocan 1136939330d7SAndy Shevchenko static int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) 11375fae8b86SMika Westerberg { 1138bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1139c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 114039ce8150SMika Westerberg unsigned long flags; 114139ce8150SMika Westerberg u32 val; 114239ce8150SMika Westerberg 114378e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 114439ce8150SMika Westerberg val = readl(reg); 114578e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 114639ce8150SMika Westerberg 11473bde8771SLinus Walleij return !!(val & BYT_LEVEL); 11485fae8b86SMika Westerberg } 11495fae8b86SMika Westerberg 1150939330d7SAndy Shevchenko static void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 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 old_val; 11565fae8b86SMika Westerberg 115786e3ef81SCristina Ciocan if (!reg) 115886e3ef81SCristina Ciocan return; 115986e3ef81SCristina Ciocan 116078e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 11615fae8b86SMika Westerberg old_val = readl(reg); 11625fae8b86SMika Westerberg if (value) 11635fae8b86SMika Westerberg writel(old_val | BYT_LEVEL, reg); 11645fae8b86SMika Westerberg else 11655fae8b86SMika Westerberg writel(old_val & ~BYT_LEVEL, reg); 116678e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 11675fae8b86SMika Westerberg } 11685fae8b86SMika Westerberg 116986e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 11705fae8b86SMika Westerberg { 1171bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1172c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 11735fae8b86SMika Westerberg unsigned long flags; 11745fae8b86SMika Westerberg u32 value; 11755fae8b86SMika Westerberg 117686e3ef81SCristina Ciocan if (!reg) 117786e3ef81SCristina Ciocan return -EINVAL; 117886e3ef81SCristina Ciocan 117978e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 118086e3ef81SCristina Ciocan value = readl(reg); 118178e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 11825fae8b86SMika Westerberg 118386e3ef81SCristina Ciocan if (!(value & BYT_OUTPUT_EN)) 11841c5fb66aSLinus Walleij return 0; 118586e3ef81SCristina Ciocan if (!(value & BYT_INPUT_EN)) 11861c5fb66aSLinus Walleij return 1; 118786e3ef81SCristina Ciocan 118886e3ef81SCristina Ciocan return -EINVAL; 11895fae8b86SMika Westerberg } 11905fae8b86SMika Westerberg 119186e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 11925fae8b86SMika Westerberg { 119386e3ef81SCristina Ciocan return pinctrl_gpio_direction_input(chip->base + offset); 119486e3ef81SCristina Ciocan } 11955fae8b86SMika Westerberg 119686e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip, 119786e3ef81SCristina Ciocan unsigned int offset, int value) 119886e3ef81SCristina Ciocan { 119986e3ef81SCristina Ciocan int ret = pinctrl_gpio_direction_output(chip->base + offset); 12005fae8b86SMika Westerberg 120186e3ef81SCristina Ciocan if (ret) 120286e3ef81SCristina Ciocan return ret; 120386e3ef81SCristina Ciocan 120486e3ef81SCristina Ciocan byt_gpio_set(chip, offset, value); 12055fae8b86SMika Westerberg 12065fae8b86SMika Westerberg return 0; 12075fae8b86SMika Westerberg } 12085fae8b86SMika Westerberg 12095fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 12105fae8b86SMika Westerberg { 1211bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 12125fae8b86SMika Westerberg int i; 121386e3ef81SCristina Ciocan u32 conf0, val; 12145fae8b86SMika Westerberg 121586e3ef81SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 121686e3ef81SCristina Ciocan const struct byt_community *comm; 12175fae8b86SMika Westerberg const char *pull_str = NULL; 12185fae8b86SMika Westerberg const char *pull = NULL; 121986e3ef81SCristina Ciocan void __iomem *reg; 122078e1c896SMika Westerberg unsigned long flags; 12215fae8b86SMika Westerberg const char *label; 122286e3ef81SCristina Ciocan unsigned int pin; 122378e1c896SMika Westerberg 122478e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 122586e3ef81SCristina Ciocan pin = vg->soc_data->pins[i].number; 122686e3ef81SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 122786e3ef81SCristina Ciocan if (!reg) { 122886e3ef81SCristina Ciocan seq_printf(s, 122986e3ef81SCristina Ciocan "Could not retrieve pin %i conf0 reg\n", 123086e3ef81SCristina Ciocan pin); 123122bbd21bSDan Carpenter raw_spin_unlock_irqrestore(&vg->lock, flags); 123286e3ef81SCristina Ciocan continue; 123386e3ef81SCristina Ciocan } 123486e3ef81SCristina Ciocan conf0 = readl(reg); 123586e3ef81SCristina Ciocan 123686e3ef81SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 123786e3ef81SCristina Ciocan if (!reg) { 123886e3ef81SCristina Ciocan seq_printf(s, 123986e3ef81SCristina Ciocan "Could not retrieve pin %i val reg\n", pin); 124022bbd21bSDan Carpenter raw_spin_unlock_irqrestore(&vg->lock, flags); 124122bbd21bSDan Carpenter continue; 124286e3ef81SCristina Ciocan } 124386e3ef81SCristina Ciocan val = readl(reg); 124478e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 12455fae8b86SMika Westerberg 124686e3ef81SCristina Ciocan comm = byt_get_community(vg, pin); 124786e3ef81SCristina Ciocan if (!comm) { 124886e3ef81SCristina Ciocan seq_printf(s, 124986e3ef81SCristina Ciocan "Could not get community for pin %i\n", pin); 125086e3ef81SCristina Ciocan continue; 125186e3ef81SCristina Ciocan } 12525fae8b86SMika Westerberg label = gpiochip_is_requested(chip, i); 12535fae8b86SMika Westerberg if (!label) 12545fae8b86SMika Westerberg label = "Unrequested"; 12555fae8b86SMika Westerberg 12565fae8b86SMika Westerberg switch (conf0 & BYT_PULL_ASSIGN_MASK) { 12575fae8b86SMika Westerberg case BYT_PULL_ASSIGN_UP: 12585fae8b86SMika Westerberg pull = "up"; 12595fae8b86SMika Westerberg break; 12605fae8b86SMika Westerberg case BYT_PULL_ASSIGN_DOWN: 12615fae8b86SMika Westerberg pull = "down"; 12625fae8b86SMika Westerberg break; 12635fae8b86SMika Westerberg } 12645fae8b86SMika Westerberg 12655fae8b86SMika Westerberg switch (conf0 & BYT_PULL_STR_MASK) { 12665fae8b86SMika Westerberg case BYT_PULL_STR_2K: 12675fae8b86SMika Westerberg pull_str = "2k"; 12685fae8b86SMika Westerberg break; 12695fae8b86SMika Westerberg case BYT_PULL_STR_10K: 12705fae8b86SMika Westerberg pull_str = "10k"; 12715fae8b86SMika Westerberg break; 12725fae8b86SMika Westerberg case BYT_PULL_STR_20K: 12735fae8b86SMika Westerberg pull_str = "20k"; 12745fae8b86SMika Westerberg break; 12755fae8b86SMika Westerberg case BYT_PULL_STR_40K: 12765fae8b86SMika Westerberg pull_str = "40k"; 12775fae8b86SMika Westerberg break; 12785fae8b86SMika Westerberg } 12795fae8b86SMika Westerberg 12805fae8b86SMika Westerberg seq_printf(s, 12815fae8b86SMika Westerberg " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", 128286e3ef81SCristina Ciocan pin, 12835fae8b86SMika Westerberg label, 12845fae8b86SMika Westerberg val & BYT_INPUT_EN ? " " : "in", 12855fae8b86SMika Westerberg val & BYT_OUTPUT_EN ? " " : "out", 12865fae8b86SMika Westerberg val & BYT_LEVEL ? "hi" : "lo", 12873655a1caSAlexander Stein comm->pad_map[i], comm->pad_map[i] * 16, 12885fae8b86SMika Westerberg conf0 & 0x7, 12895fae8b86SMika Westerberg conf0 & BYT_TRIG_NEG ? " fall" : " ", 12905fae8b86SMika Westerberg conf0 & BYT_TRIG_POS ? " rise" : " ", 12915fae8b86SMika Westerberg conf0 & BYT_TRIG_LVL ? " level" : " "); 12925fae8b86SMika Westerberg 12935fae8b86SMika Westerberg if (pull && pull_str) 12945fae8b86SMika Westerberg seq_printf(s, " %-4s %-3s", pull, pull_str); 12955fae8b86SMika Westerberg else 12965fae8b86SMika Westerberg seq_puts(s, " "); 12975fae8b86SMika Westerberg 12985fae8b86SMika Westerberg if (conf0 & BYT_IODEN) 12995fae8b86SMika Westerberg seq_puts(s, " open-drain"); 13005fae8b86SMika Westerberg 13015fae8b86SMika Westerberg seq_puts(s, "\n"); 13025fae8b86SMika Westerberg } 13035fae8b86SMika Westerberg } 13045fae8b86SMika Westerberg 130586e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = { 130686e3ef81SCristina Ciocan .owner = THIS_MODULE, 130786e3ef81SCristina Ciocan .request = gpiochip_generic_request, 130886e3ef81SCristina Ciocan .free = gpiochip_generic_free, 130986e3ef81SCristina Ciocan .get_direction = byt_gpio_get_direction, 131086e3ef81SCristina Ciocan .direction_input = byt_gpio_direction_input, 131186e3ef81SCristina Ciocan .direction_output = byt_gpio_direction_output, 131286e3ef81SCristina Ciocan .get = byt_gpio_get, 131386e3ef81SCristina Ciocan .set = byt_gpio_set, 131486e3ef81SCristina Ciocan .dbg_show = byt_gpio_dbg_show, 131586e3ef81SCristina Ciocan }; 131686e3ef81SCristina Ciocan 131731e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d) 131831e4329fSMika Westerberg { 131931e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1320bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(gc); 1321939330d7SAndy Shevchenko unsigned int offset = irqd_to_hwirq(d); 132231e4329fSMika Westerberg void __iomem *reg; 132331e4329fSMika Westerberg 1324c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); 13259f573b98SCristina Ciocan if (!reg) 13269f573b98SCristina Ciocan return; 13279f573b98SCristina Ciocan 13289f573b98SCristina Ciocan raw_spin_lock(&vg->lock); 132931e4329fSMika Westerberg writel(BIT(offset % 32), reg); 133078e1c896SMika Westerberg raw_spin_unlock(&vg->lock); 133131e4329fSMika Westerberg } 133231e4329fSMika Westerberg 13339f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d) 13349f573b98SCristina Ciocan { 13359f573b98SCristina Ciocan struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 13369f573b98SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data(gc); 13379f573b98SCristina Ciocan 13389f573b98SCristina Ciocan byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); 13399f573b98SCristina Ciocan } 13409f573b98SCristina Ciocan 13415fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d) 13425fae8b86SMika Westerberg { 134331e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1344bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(gc); 1345939330d7SAndy Shevchenko unsigned int offset = irqd_to_hwirq(d); 134631e4329fSMika Westerberg unsigned long flags; 134731e4329fSMika Westerberg void __iomem *reg; 134831e4329fSMika Westerberg u32 value; 134931e4329fSMika Westerberg 1350c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 13519f573b98SCristina Ciocan if (!reg) 13529f573b98SCristina Ciocan return; 135378e1c896SMika Westerberg 135478e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 135531e4329fSMika Westerberg value = readl(reg); 135631e4329fSMika Westerberg 135731e4329fSMika Westerberg switch (irqd_get_trigger_type(d)) { 135831e4329fSMika Westerberg case IRQ_TYPE_LEVEL_HIGH: 135931e4329fSMika Westerberg value |= BYT_TRIG_LVL; 1360399476bdSGustavo A. R. Silva /* fall through */ 136131e4329fSMika Westerberg case IRQ_TYPE_EDGE_RISING: 136231e4329fSMika Westerberg value |= BYT_TRIG_POS; 136331e4329fSMika Westerberg break; 136431e4329fSMika Westerberg case IRQ_TYPE_LEVEL_LOW: 136531e4329fSMika Westerberg value |= BYT_TRIG_LVL; 1366399476bdSGustavo A. R. Silva /* fall through */ 136731e4329fSMika Westerberg case IRQ_TYPE_EDGE_FALLING: 136831e4329fSMika Westerberg value |= BYT_TRIG_NEG; 136931e4329fSMika Westerberg break; 137031e4329fSMika Westerberg case IRQ_TYPE_EDGE_BOTH: 137131e4329fSMika Westerberg value |= (BYT_TRIG_NEG | BYT_TRIG_POS); 137231e4329fSMika Westerberg break; 137331e4329fSMika Westerberg } 137431e4329fSMika Westerberg 137531e4329fSMika Westerberg writel(value, reg); 137631e4329fSMika Westerberg 137778e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 13785fae8b86SMika Westerberg } 13795fae8b86SMika Westerberg 13809f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type) 13815fae8b86SMika Westerberg { 13829f573b98SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); 13839f573b98SCristina Ciocan u32 offset = irqd_to_hwirq(d); 13849f573b98SCristina Ciocan u32 value; 13859f573b98SCristina Ciocan unsigned long flags; 13869f573b98SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 138731e4329fSMika Westerberg 13889f573b98SCristina Ciocan if (!reg || offset >= vg->chip.ngpio) 13899f573b98SCristina Ciocan return -EINVAL; 13909f573b98SCristina Ciocan 13919f573b98SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 13929f573b98SCristina Ciocan value = readl(reg); 13939f573b98SCristina Ciocan 13949f573b98SCristina Ciocan WARN(value & BYT_DIRECT_IRQ_EN, 13959f573b98SCristina Ciocan "Bad pad config for io mode, force direct_irq_en bit clearing"); 13969f573b98SCristina Ciocan 13979f573b98SCristina Ciocan /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits 13989f573b98SCristina Ciocan * are used to indicate high and low level triggering 13999f573b98SCristina Ciocan */ 14009f573b98SCristina Ciocan value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | 14019f573b98SCristina Ciocan BYT_TRIG_LVL); 14029291c65bSHans de Goede /* Enable glitch filtering */ 14039291c65bSHans de Goede value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK | 14049291c65bSHans de Goede BYT_GLITCH_F_FAST_CLK; 14059f573b98SCristina Ciocan 14069f573b98SCristina Ciocan writel(value, reg); 14079f573b98SCristina Ciocan 14089f573b98SCristina Ciocan if (type & IRQ_TYPE_EDGE_BOTH) 14099f573b98SCristina Ciocan irq_set_handler_locked(d, handle_edge_irq); 14109f573b98SCristina Ciocan else if (type & IRQ_TYPE_LEVEL_MASK) 14119f573b98SCristina Ciocan irq_set_handler_locked(d, handle_level_irq); 14129f573b98SCristina Ciocan 14139f573b98SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 14149f573b98SCristina Ciocan 14159f573b98SCristina Ciocan return 0; 14165fae8b86SMika Westerberg } 14175fae8b86SMika Westerberg 14185fae8b86SMika Westerberg static struct irq_chip byt_irqchip = { 14195fae8b86SMika Westerberg .name = "BYT-GPIO", 142031e4329fSMika Westerberg .irq_ack = byt_irq_ack, 14215fae8b86SMika Westerberg .irq_mask = byt_irq_mask, 14225fae8b86SMika Westerberg .irq_unmask = byt_irq_unmask, 14235fae8b86SMika Westerberg .irq_set_type = byt_irq_type, 14245fae8b86SMika Westerberg .flags = IRQCHIP_SKIP_SET_WAKE, 14255fae8b86SMika Westerberg }; 14265fae8b86SMika Westerberg 142771e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc) 142871e6ca61SCristina Ciocan { 142971e6ca61SCristina Ciocan struct irq_data *data = irq_desc_get_irq_data(desc); 143071e6ca61SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data( 143171e6ca61SCristina Ciocan irq_desc_get_handler_data(desc)); 143271e6ca61SCristina Ciocan struct irq_chip *chip = irq_data_get_irq_chip(data); 143371e6ca61SCristina Ciocan u32 base, pin; 143471e6ca61SCristina Ciocan void __iomem *reg; 143571e6ca61SCristina Ciocan unsigned long pending; 143671e6ca61SCristina Ciocan unsigned int virq; 143771e6ca61SCristina Ciocan 143871e6ca61SCristina Ciocan /* check from GPIO controller which pin triggered the interrupt */ 143971e6ca61SCristina Ciocan for (base = 0; base < vg->chip.ngpio; base += 32) { 144071e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 144171e6ca61SCristina Ciocan 144271e6ca61SCristina Ciocan if (!reg) { 144371e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 144471e6ca61SCristina Ciocan "Pin %i: could not retrieve interrupt status register\n", 144571e6ca61SCristina Ciocan base); 144671e6ca61SCristina Ciocan continue; 144771e6ca61SCristina Ciocan } 144871e6ca61SCristina Ciocan 1449cdca06e4SAlexander Stein raw_spin_lock(&vg->lock); 145071e6ca61SCristina Ciocan pending = readl(reg); 1451cdca06e4SAlexander Stein raw_spin_unlock(&vg->lock); 145271e6ca61SCristina Ciocan for_each_set_bit(pin, &pending, 32) { 1453f0fbe7bcSThierry Reding virq = irq_find_mapping(vg->chip.irq.domain, base + pin); 145471e6ca61SCristina Ciocan generic_handle_irq(virq); 145571e6ca61SCristina Ciocan } 145671e6ca61SCristina Ciocan } 145771e6ca61SCristina Ciocan chip->irq_eoi(data); 145871e6ca61SCristina Ciocan } 145971e6ca61SCristina Ciocan 14605fae8b86SMika Westerberg static void byt_gpio_irq_init_hw(struct byt_gpio *vg) 14615fae8b86SMika Westerberg { 146249c03096SAndy Shevchenko struct gpio_chip *gc = &vg->chip; 146349c03096SAndy Shevchenko struct device *dev = &vg->pdev->dev; 14645fae8b86SMika Westerberg void __iomem *reg; 14655fae8b86SMika Westerberg u32 base, value; 146695f0972cSMika Westerberg int i; 146795f0972cSMika Westerberg 146895f0972cSMika Westerberg /* 146995f0972cSMika Westerberg * Clear interrupt triggers for all pins that are GPIOs and 147095f0972cSMika Westerberg * do not use direct IRQ mode. This will prevent spurious 147195f0972cSMika Westerberg * interrupts from misconfigured pins. 147295f0972cSMika Westerberg */ 147371e6ca61SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 147471e6ca61SCristina Ciocan unsigned int pin = vg->soc_data->pins[i].number; 147571e6ca61SCristina Ciocan 147671e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 147771e6ca61SCristina Ciocan if (!reg) { 147871e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 147971e6ca61SCristina Ciocan "Pin %i: could not retrieve conf0 register\n", 148071e6ca61SCristina Ciocan i); 148171e6ca61SCristina Ciocan continue; 148271e6ca61SCristina Ciocan } 148371e6ca61SCristina Ciocan 148471e6ca61SCristina Ciocan value = readl(reg); 148549c03096SAndy Shevchenko if (value & BYT_DIRECT_IRQ_EN) { 1486dc7b0387SThierry Reding clear_bit(i, gc->irq.valid_mask); 148749c03096SAndy Shevchenko dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i); 148849c03096SAndy Shevchenko } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { 148995f0972cSMika Westerberg byt_gpio_clear_triggering(vg, i); 149049c03096SAndy Shevchenko dev_dbg(dev, "disabling GPIO %d\n", i); 149195f0972cSMika Westerberg } 149295f0972cSMika Westerberg } 14935fae8b86SMika Westerberg 14945fae8b86SMika Westerberg /* clear interrupt status trigger registers */ 149571e6ca61SCristina Ciocan for (base = 0; base < vg->soc_data->npins; base += 32) { 1496c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 149771e6ca61SCristina Ciocan 149871e6ca61SCristina Ciocan if (!reg) { 149971e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 150071e6ca61SCristina Ciocan "Pin %i: could not retrieve irq status reg\n", 150171e6ca61SCristina Ciocan base); 150271e6ca61SCristina Ciocan continue; 150371e6ca61SCristina Ciocan } 150471e6ca61SCristina Ciocan 15055fae8b86SMika Westerberg writel(0xffffffff, reg); 15065fae8b86SMika Westerberg /* make sure trigger bits are cleared, if not then a pin 15075fae8b86SMika Westerberg might be misconfigured in bios */ 15085fae8b86SMika Westerberg value = readl(reg); 15095fae8b86SMika Westerberg if (value) 15105fae8b86SMika Westerberg dev_err(&vg->pdev->dev, 1511973232e2SAlexander Stein "GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n", 1512973232e2SAlexander Stein base / 32, value); 15135fae8b86SMika Westerberg } 15145fae8b86SMika Westerberg } 15155fae8b86SMika Westerberg 151671e6ca61SCristina Ciocan static int byt_gpio_probe(struct byt_gpio *vg) 15175fae8b86SMika Westerberg { 15185fae8b86SMika Westerberg struct gpio_chip *gc; 151971e6ca61SCristina Ciocan struct resource *irq_rc; 15205fae8b86SMika Westerberg int ret; 15215fae8b86SMika Westerberg 152271e6ca61SCristina Ciocan /* Set up gpio chip */ 152371e6ca61SCristina Ciocan vg->chip = byt_gpio_chip; 15245fae8b86SMika Westerberg gc = &vg->chip; 152571e6ca61SCristina Ciocan gc->label = dev_name(&vg->pdev->dev); 15265fae8b86SMika Westerberg gc->base = -1; 15275fae8b86SMika Westerberg gc->can_sleep = false; 152871e6ca61SCristina Ciocan gc->parent = &vg->pdev->dev; 152971e6ca61SCristina Ciocan gc->ngpio = vg->soc_data->npins; 1530dc7b0387SThierry Reding gc->irq.need_valid_mask = true; 15315fae8b86SMika Westerberg 1532fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP 153371e6ca61SCristina Ciocan vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, 1534fcc18debSMika Westerberg sizeof(*vg->saved_context), GFP_KERNEL); 1535d6cb7722SAditya Pakki if (!vg->saved_context) 1536d6cb7722SAditya Pakki return -ENOMEM; 1537fcc18debSMika Westerberg #endif 15380612413fSAndy Shevchenko ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg); 15395fae8b86SMika Westerberg if (ret) { 154071e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n"); 15415fae8b86SMika Westerberg return ret; 15425fae8b86SMika Westerberg } 15435fae8b86SMika Westerberg 154471e6ca61SCristina Ciocan ret = gpiochip_add_pin_range(&vg->chip, dev_name(&vg->pdev->dev), 154571e6ca61SCristina Ciocan 0, 0, vg->soc_data->npins); 154671e6ca61SCristina Ciocan if (ret) { 154771e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed to add GPIO pin range\n"); 15480612413fSAndy Shevchenko return ret; 154971e6ca61SCristina Ciocan } 155071e6ca61SCristina Ciocan 15515fae8b86SMika Westerberg /* set up interrupts */ 155271e6ca61SCristina Ciocan irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0); 15535fae8b86SMika Westerberg if (irq_rc && irq_rc->start) { 15545fae8b86SMika Westerberg byt_gpio_irq_init_hw(vg); 15555fae8b86SMika Westerberg ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0, 15563ae02c14SAndy Shevchenko handle_bad_irq, IRQ_TYPE_NONE); 15575fae8b86SMika Westerberg if (ret) { 155871e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed to add irqchip\n"); 15590612413fSAndy Shevchenko return ret; 15605fae8b86SMika Westerberg } 15615fae8b86SMika Westerberg 15625fae8b86SMika Westerberg gpiochip_set_chained_irqchip(gc, &byt_irqchip, 15635fae8b86SMika Westerberg (unsigned)irq_rc->start, 15645fae8b86SMika Westerberg byt_gpio_irq_handler); 15655fae8b86SMika Westerberg } 15665fae8b86SMika Westerberg 156771e6ca61SCristina Ciocan return ret; 156871e6ca61SCristina Ciocan } 156971e6ca61SCristina Ciocan 157071e6ca61SCristina Ciocan static int byt_set_soc_data(struct byt_gpio *vg, 157171e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data) 157271e6ca61SCristina Ciocan { 157371e6ca61SCristina Ciocan int i; 157471e6ca61SCristina Ciocan 157571e6ca61SCristina Ciocan vg->soc_data = soc_data; 157671e6ca61SCristina Ciocan vg->communities_copy = devm_kcalloc(&vg->pdev->dev, 157771e6ca61SCristina Ciocan soc_data->ncommunities, 157871e6ca61SCristina Ciocan sizeof(*vg->communities_copy), 157971e6ca61SCristina Ciocan GFP_KERNEL); 158071e6ca61SCristina Ciocan if (!vg->communities_copy) 158171e6ca61SCristina Ciocan return -ENOMEM; 158271e6ca61SCristina Ciocan 158371e6ca61SCristina Ciocan for (i = 0; i < soc_data->ncommunities; i++) { 158471e6ca61SCristina Ciocan struct byt_community *comm = vg->communities_copy + i; 158571e6ca61SCristina Ciocan struct resource *mem_rc; 158671e6ca61SCristina Ciocan 158771e6ca61SCristina Ciocan *comm = vg->soc_data->communities[i]; 158871e6ca61SCristina Ciocan 158971e6ca61SCristina Ciocan mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0); 159071e6ca61SCristina Ciocan comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc); 159171e6ca61SCristina Ciocan if (IS_ERR(comm->reg_base)) 159271e6ca61SCristina Ciocan return PTR_ERR(comm->reg_base); 159371e6ca61SCristina Ciocan } 159471e6ca61SCristina Ciocan 159571e6ca61SCristina Ciocan return 0; 159671e6ca61SCristina Ciocan } 159771e6ca61SCristina Ciocan 159871e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = { 159971e6ca61SCristina Ciocan { "INT33B2", (kernel_ulong_t)byt_soc_data }, 160071e6ca61SCristina Ciocan { "INT33FC", (kernel_ulong_t)byt_soc_data }, 160171e6ca61SCristina Ciocan { } 160271e6ca61SCristina Ciocan }; 160371e6ca61SCristina Ciocan 160471e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev) 160571e6ca61SCristina Ciocan { 160671e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data = NULL; 160771e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data **soc_table; 160871e6ca61SCristina Ciocan struct acpi_device *acpi_dev; 160971e6ca61SCristina Ciocan struct byt_gpio *vg; 161071e6ca61SCristina Ciocan int i, ret; 161171e6ca61SCristina Ciocan 161271e6ca61SCristina Ciocan acpi_dev = ACPI_COMPANION(&pdev->dev); 161371e6ca61SCristina Ciocan if (!acpi_dev) 161471e6ca61SCristina Ciocan return -ENODEV; 161571e6ca61SCristina Ciocan 161661db6c9dSAndy Shevchenko soc_table = (const struct byt_pinctrl_soc_data **)device_get_match_data(&pdev->dev); 161771e6ca61SCristina Ciocan 161871e6ca61SCristina Ciocan for (i = 0; soc_table[i]; i++) { 161971e6ca61SCristina Ciocan if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) { 162071e6ca61SCristina Ciocan soc_data = soc_table[i]; 162171e6ca61SCristina Ciocan break; 162271e6ca61SCristina Ciocan } 162371e6ca61SCristina Ciocan } 162471e6ca61SCristina Ciocan 162571e6ca61SCristina Ciocan if (!soc_data) 162671e6ca61SCristina Ciocan return -ENODEV; 162771e6ca61SCristina Ciocan 162871e6ca61SCristina Ciocan vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL); 162971e6ca61SCristina Ciocan if (!vg) 163071e6ca61SCristina Ciocan return -ENOMEM; 163171e6ca61SCristina Ciocan 163271e6ca61SCristina Ciocan vg->pdev = pdev; 163371e6ca61SCristina Ciocan ret = byt_set_soc_data(vg, soc_data); 163471e6ca61SCristina Ciocan if (ret) { 163571e6ca61SCristina Ciocan dev_err(&pdev->dev, "failed to set soc data\n"); 163671e6ca61SCristina Ciocan return ret; 163771e6ca61SCristina Ciocan } 163871e6ca61SCristina Ciocan 163971e6ca61SCristina Ciocan vg->pctl_desc = byt_pinctrl_desc; 164071e6ca61SCristina Ciocan vg->pctl_desc.name = dev_name(&pdev->dev); 164171e6ca61SCristina Ciocan vg->pctl_desc.pins = vg->soc_data->pins; 164271e6ca61SCristina Ciocan vg->pctl_desc.npins = vg->soc_data->npins; 164371e6ca61SCristina Ciocan 16440612413fSAndy Shevchenko vg->pctl_dev = devm_pinctrl_register(&pdev->dev, &vg->pctl_desc, vg); 164571e6ca61SCristina Ciocan if (IS_ERR(vg->pctl_dev)) { 164671e6ca61SCristina Ciocan dev_err(&pdev->dev, "failed to register pinctrl driver\n"); 164771e6ca61SCristina Ciocan return PTR_ERR(vg->pctl_dev); 164871e6ca61SCristina Ciocan } 164971e6ca61SCristina Ciocan 1650a171bc51SVille Syrjälä raw_spin_lock_init(&vg->lock); 1651a171bc51SVille Syrjälä 165271e6ca61SCristina Ciocan ret = byt_gpio_probe(vg); 16530612413fSAndy Shevchenko if (ret) 165471e6ca61SCristina Ciocan return ret; 165571e6ca61SCristina Ciocan 165671e6ca61SCristina Ciocan platform_set_drvdata(pdev, vg); 165771e6ca61SCristina Ciocan pm_runtime_enable(&pdev->dev); 165871e6ca61SCristina Ciocan 165971e6ca61SCristina Ciocan return 0; 166071e6ca61SCristina Ciocan } 166171e6ca61SCristina Ciocan 1662fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP 1663fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev) 1664fcc18debSMika Westerberg { 1665d481de47SWolfram Sang struct byt_gpio *vg = dev_get_drvdata(dev); 1666fcc18debSMika Westerberg int i; 1667fcc18debSMika Westerberg 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 1688fcc18debSMika Westerberg return 0; 1689fcc18debSMika Westerberg } 1690fcc18debSMika Westerberg 1691fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev) 1692fcc18debSMika Westerberg { 1693d481de47SWolfram Sang struct byt_gpio *vg = dev_get_drvdata(dev); 1694fcc18debSMika Westerberg int i; 1695fcc18debSMika Westerberg 169671e6ca61SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 1697fcc18debSMika Westerberg void __iomem *reg; 1698fcc18debSMika Westerberg u32 value; 169971e6ca61SCristina Ciocan unsigned int pin = vg->soc_data->pins[i].number; 1700fcc18debSMika Westerberg 170171e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 170271e6ca61SCristina Ciocan if (!reg) { 170371e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 170471e6ca61SCristina Ciocan "Pin %i: could not retrieve conf0 register\n", 170571e6ca61SCristina Ciocan i); 170671e6ca61SCristina Ciocan continue; 170771e6ca61SCristina Ciocan } 1708fcc18debSMika Westerberg value = readl(reg); 1709fcc18debSMika Westerberg if ((value & BYT_CONF0_RESTORE_MASK) != 1710fcc18debSMika Westerberg vg->saved_context[i].conf0) { 1711fcc18debSMika Westerberg value &= ~BYT_CONF0_RESTORE_MASK; 1712fcc18debSMika Westerberg value |= vg->saved_context[i].conf0; 1713fcc18debSMika Westerberg writel(value, reg); 1714fcc18debSMika Westerberg dev_info(dev, "restored pin %d conf0 %#08x", i, value); 1715fcc18debSMika Westerberg } 1716fcc18debSMika Westerberg 171771e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 1718fcc18debSMika Westerberg value = readl(reg); 1719fcc18debSMika Westerberg if ((value & BYT_VAL_RESTORE_MASK) != 1720fcc18debSMika Westerberg vg->saved_context[i].val) { 1721fcc18debSMika Westerberg u32 v; 1722fcc18debSMika Westerberg 1723fcc18debSMika Westerberg v = value & ~BYT_VAL_RESTORE_MASK; 1724fcc18debSMika Westerberg v |= vg->saved_context[i].val; 1725fcc18debSMika Westerberg if (v != value) { 1726fcc18debSMika Westerberg writel(v, reg); 1727fcc18debSMika Westerberg dev_dbg(dev, "restored pin %d val %#08x\n", 1728fcc18debSMika Westerberg i, v); 1729fcc18debSMika Westerberg } 1730fcc18debSMika Westerberg } 1731fcc18debSMika Westerberg } 1732fcc18debSMika Westerberg 1733fcc18debSMika Westerberg return 0; 1734fcc18debSMika Westerberg } 1735fcc18debSMika Westerberg #endif 1736fcc18debSMika Westerberg 1737ec879f12SMika Westerberg #ifdef CONFIG_PM 17385fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev) 17395fae8b86SMika Westerberg { 17405fae8b86SMika Westerberg return 0; 17415fae8b86SMika Westerberg } 17425fae8b86SMika Westerberg 17435fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev) 17445fae8b86SMika Westerberg { 17455fae8b86SMika Westerberg return 0; 17465fae8b86SMika Westerberg } 1747ec879f12SMika Westerberg #endif 17485fae8b86SMika Westerberg 17495fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = { 1750fcc18debSMika Westerberg SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) 1751fcc18debSMika Westerberg SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, 1752fcc18debSMika Westerberg NULL) 17535fae8b86SMika Westerberg }; 17545fae8b86SMika Westerberg 17555fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = { 175671e6ca61SCristina Ciocan .probe = byt_pinctrl_probe, 17575fae8b86SMika Westerberg .driver = { 17585fae8b86SMika Westerberg .name = "byt_gpio", 17595fae8b86SMika Westerberg .pm = &byt_gpio_pm_ops, 1760360943a8SPaul Gortmaker .suppress_bind_attrs = true, 1761360943a8SPaul Gortmaker 17625fae8b86SMika Westerberg .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match), 17635fae8b86SMika Westerberg }, 17645fae8b86SMika Westerberg }; 17655fae8b86SMika Westerberg 17665fae8b86SMika Westerberg static int __init byt_gpio_init(void) 17675fae8b86SMika Westerberg { 17685fae8b86SMika Westerberg return platform_driver_register(&byt_gpio_driver); 17695fae8b86SMika Westerberg } 17705fae8b86SMika Westerberg subsys_initcall(byt_gpio_init); 1771