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/kernel.h> 105fae8b86SMika Westerberg #include <linux/init.h> 115fae8b86SMika Westerberg #include <linux/types.h> 125fae8b86SMika Westerberg #include <linux/bitops.h> 135fae8b86SMika Westerberg #include <linux/interrupt.h> 1486e3ef81SCristina Ciocan #include <linux/gpio.h> 15bf9a5c96SLinus Walleij #include <linux/gpio/driver.h> 165fae8b86SMika Westerberg #include <linux/acpi.h> 175fae8b86SMika Westerberg #include <linux/platform_device.h> 185fae8b86SMika Westerberg #include <linux/seq_file.h> 195fae8b86SMika Westerberg #include <linux/io.h> 205fae8b86SMika Westerberg #include <linux/pm_runtime.h> 215fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h> 22c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h> 23c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h> 24c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h> 255fae8b86SMika Westerberg 265fae8b86SMika Westerberg /* memory mapped register offsets */ 275fae8b86SMika Westerberg #define BYT_CONF0_REG 0x000 285fae8b86SMika Westerberg #define BYT_CONF1_REG 0x004 295fae8b86SMika Westerberg #define BYT_VAL_REG 0x008 305fae8b86SMika Westerberg #define BYT_DFT_REG 0x00c 315fae8b86SMika Westerberg #define BYT_INT_STAT_REG 0x800 32658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG 0x9d0 335fae8b86SMika Westerberg 345fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */ 355fae8b86SMika Westerberg #define BYT_IODEN BIT(31) 365fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN BIT(27) 375fae8b86SMika Westerberg #define BYT_TRIG_NEG BIT(26) 385fae8b86SMika Westerberg #define BYT_TRIG_POS BIT(25) 395fae8b86SMika Westerberg #define BYT_TRIG_LVL BIT(24) 40658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN BIT(20) 419291c65bSHans de Goede #define BYT_GLITCH_FILTER_EN BIT(19) 429291c65bSHans de Goede #define BYT_GLITCH_F_SLOW_CLK BIT(17) 439291c65bSHans de Goede #define BYT_GLITCH_F_FAST_CLK BIT(16) 445fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT 9 455fae8b86SMika Westerberg #define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT) 465fae8b86SMika Westerberg #define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) 475fae8b86SMika Westerberg #define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT) 485fae8b86SMika Westerberg #define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT) 495fae8b86SMika Westerberg #define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT) 505fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_SHIFT 7 515fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_MASK (3 << BYT_PULL_ASSIGN_SHIFT) 525fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT) 535fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT) 545fae8b86SMika Westerberg #define BYT_PIN_MUX 0x07 555fae8b86SMika Westerberg 565fae8b86SMika Westerberg /* BYT_VAL_REG register bits */ 575fae8b86SMika Westerberg #define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ 585fae8b86SMika Westerberg #define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ 595fae8b86SMika Westerberg #define BYT_LEVEL BIT(0) 605fae8b86SMika Westerberg 615fae8b86SMika Westerberg #define BYT_DIR_MASK (BIT(1) | BIT(2)) 625fae8b86SMika Westerberg #define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24)) 635fae8b86SMika Westerberg 64fcc18debSMika Westerberg #define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \ 65fcc18debSMika Westerberg BYT_PIN_MUX) 66fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) 67fcc18debSMika Westerberg 68658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */ 69658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_MASK 0x7 70658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US 1 71658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US 2 72658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US 3 73658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS 4 74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS 5 75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS 6 76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS 7 77658b476cSCristina Ciocan 785fae8b86SMika Westerberg #define BYT_NGPIO_SCORE 102 795fae8b86SMika Westerberg #define BYT_NGPIO_NCORE 28 805fae8b86SMika Westerberg #define BYT_NGPIO_SUS 44 815fae8b86SMika Westerberg 825fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID "1" 835fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID "2" 845fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID "3" 855fae8b86SMika Westerberg 86c501d0b1SCristina Ciocan /* 87c501d0b1SCristina Ciocan * This is the function value most pins have for GPIO muxing. If the value 88c501d0b1SCristina Ciocan * differs from the default one, it must be explicitly mentioned. Otherwise, the 89c501d0b1SCristina Ciocan * pin control implementation will set the muxing value to default GPIO if it 90c501d0b1SCristina Ciocan * does not find a match for the requested function. 91c501d0b1SCristina Ciocan */ 92c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX 0 93c501d0b1SCristina Ciocan 94c8f5c4c7SCristina Ciocan struct byt_gpio_pin_context { 95c8f5c4c7SCristina Ciocan u32 conf0; 96c8f5c4c7SCristina Ciocan u32 val; 97c8f5c4c7SCristina Ciocan }; 985fae8b86SMika Westerberg 99c8f5c4c7SCristina Ciocan struct byt_simple_func_mux { 100c8f5c4c7SCristina Ciocan const char *name; 101c8f5c4c7SCristina Ciocan unsigned short func; 102c8f5c4c7SCristina Ciocan }; 103c8f5c4c7SCristina Ciocan 104c8f5c4c7SCristina Ciocan struct byt_mixed_func_mux { 105c8f5c4c7SCristina Ciocan const char *name; 106c8f5c4c7SCristina Ciocan const unsigned short *func_values; 107c8f5c4c7SCristina Ciocan }; 108c8f5c4c7SCristina Ciocan 109c8f5c4c7SCristina Ciocan struct byt_pingroup { 110c8f5c4c7SCristina Ciocan const char *name; 111c8f5c4c7SCristina Ciocan const unsigned int *pins; 112c8f5c4c7SCristina Ciocan size_t npins; 113c8f5c4c7SCristina Ciocan unsigned short has_simple_funcs; 114c8f5c4c7SCristina Ciocan union { 115c8f5c4c7SCristina Ciocan const struct byt_simple_func_mux *simple_funcs; 116c8f5c4c7SCristina Ciocan const struct byt_mixed_func_mux *mixed_funcs; 117c8f5c4c7SCristina Ciocan }; 118c8f5c4c7SCristina Ciocan size_t nfuncs; 119c8f5c4c7SCristina Ciocan }; 120c8f5c4c7SCristina Ciocan 121c8f5c4c7SCristina Ciocan struct byt_function { 122c8f5c4c7SCristina Ciocan const char *name; 123c8f5c4c7SCristina Ciocan const char * const *groups; 124c8f5c4c7SCristina Ciocan size_t ngroups; 125c8f5c4c7SCristina Ciocan }; 126c8f5c4c7SCristina Ciocan 127c8f5c4c7SCristina Ciocan struct byt_community { 128c8f5c4c7SCristina Ciocan unsigned int pin_base; 129c8f5c4c7SCristina Ciocan size_t npins; 130c8f5c4c7SCristina Ciocan const unsigned int *pad_map; 131c8f5c4c7SCristina Ciocan void __iomem *reg_base; 132c8f5c4c7SCristina Ciocan }; 133c8f5c4c7SCristina Ciocan 134c8f5c4c7SCristina Ciocan #define SIMPLE_FUNC(n, f) \ 135c8f5c4c7SCristina Ciocan { \ 136c8f5c4c7SCristina Ciocan .name = (n), \ 137c8f5c4c7SCristina Ciocan .func = (f), \ 138c8f5c4c7SCristina Ciocan } 139c8f5c4c7SCristina Ciocan #define MIXED_FUNC(n, f) \ 140c8f5c4c7SCristina Ciocan { \ 141c8f5c4c7SCristina Ciocan .name = (n), \ 142c8f5c4c7SCristina Ciocan .func_values = (f), \ 143c8f5c4c7SCristina Ciocan } 144c8f5c4c7SCristina Ciocan 145c8f5c4c7SCristina Ciocan #define PIN_GROUP_SIMPLE(n, p, f) \ 146c8f5c4c7SCristina Ciocan { \ 147c8f5c4c7SCristina Ciocan .name = (n), \ 148c8f5c4c7SCristina Ciocan .pins = (p), \ 149c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE((p)), \ 150c8f5c4c7SCristina Ciocan .has_simple_funcs = 1, \ 151bbccb9c7SAndrew Morton { \ 152c8f5c4c7SCristina Ciocan .simple_funcs = (f), \ 153bbccb9c7SAndrew Morton }, \ 154c8f5c4c7SCristina Ciocan .nfuncs = ARRAY_SIZE((f)), \ 155c8f5c4c7SCristina Ciocan } 156c8f5c4c7SCristina Ciocan #define PIN_GROUP_MIXED(n, p, f) \ 157c8f5c4c7SCristina Ciocan { \ 158c8f5c4c7SCristina Ciocan .name = (n), \ 159c8f5c4c7SCristina Ciocan .pins = (p), \ 160c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE((p)), \ 161c8f5c4c7SCristina Ciocan .has_simple_funcs = 0, \ 162bbccb9c7SAndrew Morton { \ 163c8f5c4c7SCristina Ciocan .mixed_funcs = (f), \ 164bbccb9c7SAndrew Morton }, \ 165c8f5c4c7SCristina Ciocan .nfuncs = ARRAY_SIZE((f)), \ 166c8f5c4c7SCristina Ciocan } 167c8f5c4c7SCristina Ciocan 168c8f5c4c7SCristina Ciocan #define FUNCTION(n, g) \ 169c8f5c4c7SCristina Ciocan { \ 170c8f5c4c7SCristina Ciocan .name = (n), \ 171c8f5c4c7SCristina Ciocan .groups = (g), \ 172c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE((g)), \ 173c8f5c4c7SCristina Ciocan } 174c8f5c4c7SCristina Ciocan 175c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map) \ 176c8f5c4c7SCristina Ciocan { \ 177c8f5c4c7SCristina Ciocan .pin_base = (p), \ 178c8f5c4c7SCristina Ciocan .npins = (n), \ 179c8f5c4c7SCristina Ciocan .pad_map = (map),\ 180c8f5c4c7SCristina Ciocan } 181c8f5c4c7SCristina Ciocan 182c8f5c4c7SCristina Ciocan struct byt_pinctrl_soc_data { 183c8f5c4c7SCristina Ciocan const char *uid; 184c8f5c4c7SCristina Ciocan const struct pinctrl_pin_desc *pins; 185c8f5c4c7SCristina Ciocan size_t npins; 186c8f5c4c7SCristina Ciocan const struct byt_pingroup *groups; 187c8f5c4c7SCristina Ciocan size_t ngroups; 188c8f5c4c7SCristina Ciocan const struct byt_function *functions; 189c8f5c4c7SCristina Ciocan size_t nfunctions; 190c8f5c4c7SCristina Ciocan const struct byt_community *communities; 191c8f5c4c7SCristina Ciocan size_t ncommunities; 192c8f5c4c7SCristina Ciocan }; 193c8f5c4c7SCristina Ciocan 19471e6ca61SCristina Ciocan struct byt_gpio { 19571e6ca61SCristina Ciocan struct gpio_chip chip; 19671e6ca61SCristina Ciocan struct platform_device *pdev; 19771e6ca61SCristina Ciocan struct pinctrl_dev *pctl_dev; 19871e6ca61SCristina Ciocan struct pinctrl_desc pctl_desc; 19971e6ca61SCristina Ciocan raw_spinlock_t lock; 20071e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data; 20171e6ca61SCristina Ciocan struct byt_community *communities_copy; 20271e6ca61SCristina Ciocan struct byt_gpio_pin_context *saved_context; 20371e6ca61SCristina Ciocan }; 20471e6ca61SCristina Ciocan 205c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ 206c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = { 207c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "SATA_GP0"), 208c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "SATA_GP1"), 209c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "SATA_LED#"), 210c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "PCIE_CLKREQ0"), 211c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "PCIE_CLKREQ1"), 212c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "PCIE_CLKREQ2"), 213c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "PCIE_CLKREQ3"), 214c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "SD3_WP"), 215c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "HDA_RST"), 216c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "HDA_SYNC"), 217c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "HDA_CLK"), 218c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "HDA_SDO"), 219c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "HDA_SDI0"), 220c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "HDA_SDI1"), 221c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_S0_SC14"), 222c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_S0_SC15"), 223c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "MMC1_CLK"), 224c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "MMC1_D0"), 225c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "MMC1_D1"), 226c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "MMC1_D2"), 227c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "MMC1_D3"), 228c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "MMC1_D4"), 229c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "MMC1_D5"), 230c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "MMC1_D6"), 231c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "MMC1_D7"), 232c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "MMC1_CMD"), 233c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "MMC1_RST"), 234c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "SD2_CLK"), 235c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "SD2_D0"), 236c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "SD2_D1"), 237c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "SD2_D2"), 238c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "SD2_D3_CD"), 239c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "SD2_CMD"), 240c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "SD3_CLK"), 241c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "SD3_D0"), 242c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "SD3_D1"), 243c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "SD3_D2"), 244c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "SD3_D3"), 245c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "SD3_CD"), 246c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "SD3_CMD"), 247c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "SD3_1P8EN"), 248c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "SD3_PWREN#"), 249c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "ILB_LPC_AD0"), 250c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "ILB_LPC_AD1"), 251c8f5c4c7SCristina Ciocan PINCTRL_PIN(44, "ILB_LPC_AD2"), 252c8f5c4c7SCristina Ciocan PINCTRL_PIN(45, "ILB_LPC_AD3"), 253c8f5c4c7SCristina Ciocan PINCTRL_PIN(46, "ILB_LPC_FRAME"), 254c8f5c4c7SCristina Ciocan PINCTRL_PIN(47, "ILB_LPC_CLK0"), 255c8f5c4c7SCristina Ciocan PINCTRL_PIN(48, "ILB_LPC_CLK1"), 256c8f5c4c7SCristina Ciocan PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), 257c8f5c4c7SCristina Ciocan PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), 258c8f5c4c7SCristina Ciocan PINCTRL_PIN(51, "PCU_SMB_DATA"), 259c8f5c4c7SCristina Ciocan PINCTRL_PIN(52, "PCU_SMB_CLK"), 260c8f5c4c7SCristina Ciocan PINCTRL_PIN(53, "PCU_SMB_ALERT"), 261c8f5c4c7SCristina Ciocan PINCTRL_PIN(54, "ILB_8254_SPKR"), 262c8f5c4c7SCristina Ciocan PINCTRL_PIN(55, "GPIO_S0_SC55"), 263c8f5c4c7SCristina Ciocan PINCTRL_PIN(56, "GPIO_S0_SC56"), 264c8f5c4c7SCristina Ciocan PINCTRL_PIN(57, "GPIO_S0_SC57"), 265c8f5c4c7SCristina Ciocan PINCTRL_PIN(58, "GPIO_S0_SC58"), 266c8f5c4c7SCristina Ciocan PINCTRL_PIN(59, "GPIO_S0_SC59"), 267c8f5c4c7SCristina Ciocan PINCTRL_PIN(60, "GPIO_S0_SC60"), 268c8f5c4c7SCristina Ciocan PINCTRL_PIN(61, "GPIO_S0_SC61"), 269c8f5c4c7SCristina Ciocan PINCTRL_PIN(62, "LPE_I2S2_CLK"), 270c8f5c4c7SCristina Ciocan PINCTRL_PIN(63, "LPE_I2S2_FRM"), 271c8f5c4c7SCristina Ciocan PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), 272c8f5c4c7SCristina Ciocan PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), 273c8f5c4c7SCristina Ciocan PINCTRL_PIN(66, "SIO_SPI_CS"), 274c8f5c4c7SCristina Ciocan PINCTRL_PIN(67, "SIO_SPI_MISO"), 275c8f5c4c7SCristina Ciocan PINCTRL_PIN(68, "SIO_SPI_MOSI"), 276c8f5c4c7SCristina Ciocan PINCTRL_PIN(69, "SIO_SPI_CLK"), 277c8f5c4c7SCristina Ciocan PINCTRL_PIN(70, "SIO_UART1_RXD"), 278c8f5c4c7SCristina Ciocan PINCTRL_PIN(71, "SIO_UART1_TXD"), 279c8f5c4c7SCristina Ciocan PINCTRL_PIN(72, "SIO_UART1_RTS"), 280c8f5c4c7SCristina Ciocan PINCTRL_PIN(73, "SIO_UART1_CTS"), 281c8f5c4c7SCristina Ciocan PINCTRL_PIN(74, "SIO_UART2_RXD"), 282c8f5c4c7SCristina Ciocan PINCTRL_PIN(75, "SIO_UART2_TXD"), 283c8f5c4c7SCristina Ciocan PINCTRL_PIN(76, "SIO_UART2_RTS"), 284c8f5c4c7SCristina Ciocan PINCTRL_PIN(77, "SIO_UART2_CTS"), 285c8f5c4c7SCristina Ciocan PINCTRL_PIN(78, "SIO_I2C0_DATA"), 286c8f5c4c7SCristina Ciocan PINCTRL_PIN(79, "SIO_I2C0_CLK"), 287c8f5c4c7SCristina Ciocan PINCTRL_PIN(80, "SIO_I2C1_DATA"), 288c8f5c4c7SCristina Ciocan PINCTRL_PIN(81, "SIO_I2C1_CLK"), 289c8f5c4c7SCristina Ciocan PINCTRL_PIN(82, "SIO_I2C2_DATA"), 290c8f5c4c7SCristina Ciocan PINCTRL_PIN(83, "SIO_I2C2_CLK"), 291c8f5c4c7SCristina Ciocan PINCTRL_PIN(84, "SIO_I2C3_DATA"), 292c8f5c4c7SCristina Ciocan PINCTRL_PIN(85, "SIO_I2C3_CLK"), 293c8f5c4c7SCristina Ciocan PINCTRL_PIN(86, "SIO_I2C4_DATA"), 294c8f5c4c7SCristina Ciocan PINCTRL_PIN(87, "SIO_I2C4_CLK"), 295c8f5c4c7SCristina Ciocan PINCTRL_PIN(88, "SIO_I2C5_DATA"), 296c8f5c4c7SCristina Ciocan PINCTRL_PIN(89, "SIO_I2C5_CLK"), 297c8f5c4c7SCristina Ciocan PINCTRL_PIN(90, "SIO_I2C6_DATA"), 298c8f5c4c7SCristina Ciocan PINCTRL_PIN(91, "SIO_I2C6_CLK"), 299c8f5c4c7SCristina Ciocan PINCTRL_PIN(92, "GPIO_S0_SC92"), 300c8f5c4c7SCristina Ciocan PINCTRL_PIN(93, "GPIO_S0_SC93"), 301c8f5c4c7SCristina Ciocan PINCTRL_PIN(94, "SIO_PWM0"), 302c8f5c4c7SCristina Ciocan PINCTRL_PIN(95, "SIO_PWM1"), 303c8f5c4c7SCristina Ciocan PINCTRL_PIN(96, "PMC_PLT_CLK0"), 304c8f5c4c7SCristina Ciocan PINCTRL_PIN(97, "PMC_PLT_CLK1"), 305c8f5c4c7SCristina Ciocan PINCTRL_PIN(98, "PMC_PLT_CLK2"), 306c8f5c4c7SCristina Ciocan PINCTRL_PIN(99, "PMC_PLT_CLK3"), 307c8f5c4c7SCristina Ciocan PINCTRL_PIN(100, "PMC_PLT_CLK4"), 308c8f5c4c7SCristina Ciocan PINCTRL_PIN(101, "PMC_PLT_CLK5"), 309c8f5c4c7SCristina Ciocan }; 3105fae8b86SMika Westerberg 311c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { 312c8f5c4c7SCristina Ciocan 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 313c8f5c4c7SCristina Ciocan 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, 314c8f5c4c7SCristina Ciocan 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, 315c8f5c4c7SCristina Ciocan 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 316c8f5c4c7SCristina Ciocan 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, 317c8f5c4c7SCristina Ciocan 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, 318c8f5c4c7SCristina Ciocan 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 319c8f5c4c7SCristina Ciocan 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, 320c8f5c4c7SCristina Ciocan 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 321c8f5c4c7SCristina Ciocan 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, 322c8f5c4c7SCristina Ciocan 97, 100, 3235fae8b86SMika Westerberg }; 3245fae8b86SMika Westerberg 325c8f5c4c7SCristina Ciocan /* SCORE groups */ 326c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; 327c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; 328c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_uart_mux[] = { 329c8f5c4c7SCristina Ciocan SIMPLE_FUNC("uart", 1), 330c8f5c4c7SCristina Ciocan }; 331c8f5c4c7SCristina Ciocan 332c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 }; 333c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 }; 334c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_pwm_mux[] = { 335c8f5c4c7SCristina Ciocan SIMPLE_FUNC("pwm", 1), 336c8f5c4c7SCristina Ciocan }; 337c8f5c4c7SCristina Ciocan 338c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; 339c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_spi_mux[] = { 340c8f5c4c7SCristina Ciocan SIMPLE_FUNC("spi", 1), 341c8f5c4c7SCristina Ciocan }; 342c8f5c4c7SCristina Ciocan 343c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; 344c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; 345c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; 346c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; 347c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; 348c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; 349c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; 350c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_i2c_mux[] = { 351c8f5c4c7SCristina Ciocan SIMPLE_FUNC("i2c", 1), 352c8f5c4c7SCristina Ciocan }; 353c8f5c4c7SCristina Ciocan 354c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; 355c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; 356c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; 357c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_ssp_mux[] = { 358c8f5c4c7SCristina Ciocan SIMPLE_FUNC("ssp", 1), 359c8f5c4c7SCristina Ciocan }; 360c8f5c4c7SCristina Ciocan 361c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = { 362c8f5c4c7SCristina Ciocan 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 363c8f5c4c7SCristina Ciocan }; 364c8f5c4c7SCristina Ciocan static const unsigned short byt_score_sdcard_mux_values[] = { 365c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 366c8f5c4c7SCristina Ciocan }; 367c8f5c4c7SCristina Ciocan static const struct byt_mixed_func_mux byt_score_sdcard_mux[] = { 368c8f5c4c7SCristina Ciocan MIXED_FUNC("sdcard", byt_score_sdcard_mux_values), 369c8f5c4c7SCristina Ciocan }; 370c8f5c4c7SCristina Ciocan 371c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; 372c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_sdio_mux[] = { 373c8f5c4c7SCristina Ciocan SIMPLE_FUNC("sdio", 1), 374c8f5c4c7SCristina Ciocan }; 375c8f5c4c7SCristina Ciocan 376c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = { 377c8f5c4c7SCristina Ciocan 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 378c8f5c4c7SCristina Ciocan }; 379c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_emmc_mux[] = { 380c8f5c4c7SCristina Ciocan SIMPLE_FUNC("emmc", 1), 381c8f5c4c7SCristina Ciocan }; 382c8f5c4c7SCristina Ciocan 383c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = { 384c8f5c4c7SCristina Ciocan 42, 43, 44, 45, 46, 47, 48, 49, 50, 385c8f5c4c7SCristina Ciocan }; 386c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_lpc_mux[] = { 387c8f5c4c7SCristina Ciocan SIMPLE_FUNC("lpc", 1), 388c8f5c4c7SCristina Ciocan }; 389c8f5c4c7SCristina Ciocan 390c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; 391c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_sata_mux[] = { 392c8f5c4c7SCristina Ciocan SIMPLE_FUNC("sata", 1), 393c8f5c4c7SCristina Ciocan }; 394c8f5c4c7SCristina Ciocan 395c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 }; 396c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 }; 397c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 }; 398b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 }; 399b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 }; 400b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 }; 401c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_plt_clk_mux[] = { 402c8f5c4c7SCristina Ciocan SIMPLE_FUNC("plt_clk", 1), 403c8f5c4c7SCristina Ciocan }; 404c8f5c4c7SCristina Ciocan 405c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; 406c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_smbus_mux[] = { 407c8f5c4c7SCristina Ciocan SIMPLE_FUNC("smbus", 1), 408c8f5c4c7SCristina Ciocan }; 409c8f5c4c7SCristina Ciocan 410c8f5c4c7SCristina Ciocan static const struct byt_pingroup byt_score_groups[] = { 411c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("uart1_grp", 412c8f5c4c7SCristina Ciocan byt_score_uart1_pins, byt_score_uart_mux), 413c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("uart2_grp", 414c8f5c4c7SCristina Ciocan byt_score_uart2_pins, byt_score_uart_mux), 415c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pwm0_grp", 416c8f5c4c7SCristina Ciocan byt_score_pwm0_pins, byt_score_pwm_mux), 417c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pwm1_grp", 418c8f5c4c7SCristina Ciocan byt_score_pwm1_pins, byt_score_pwm_mux), 419c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp2_grp", 420c8f5c4c7SCristina Ciocan byt_score_ssp2_pins, byt_score_pwm_mux), 421c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sio_spi_grp", 422c8f5c4c7SCristina Ciocan byt_score_sio_spi_pins, byt_score_spi_mux), 423c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c5_grp", 424c8f5c4c7SCristina Ciocan byt_score_i2c5_pins, byt_score_i2c_mux), 425c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c6_grp", 426c8f5c4c7SCristina Ciocan byt_score_i2c6_pins, byt_score_i2c_mux), 427c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c4_grp", 428c8f5c4c7SCristina Ciocan byt_score_i2c4_pins, byt_score_i2c_mux), 429c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c3_grp", 430c8f5c4c7SCristina Ciocan byt_score_i2c3_pins, byt_score_i2c_mux), 431c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c2_grp", 432c8f5c4c7SCristina Ciocan byt_score_i2c2_pins, byt_score_i2c_mux), 433c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c1_grp", 434c8f5c4c7SCristina Ciocan byt_score_i2c1_pins, byt_score_i2c_mux), 435c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c0_grp", 436c8f5c4c7SCristina Ciocan byt_score_i2c0_pins, byt_score_i2c_mux), 437c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp0_grp", 438c8f5c4c7SCristina Ciocan byt_score_ssp0_pins, byt_score_ssp_mux), 439c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp1_grp", 440c8f5c4c7SCristina Ciocan byt_score_ssp1_pins, byt_score_ssp_mux), 441c8f5c4c7SCristina Ciocan PIN_GROUP_MIXED("sdcard_grp", 442c8f5c4c7SCristina Ciocan byt_score_sdcard_pins, byt_score_sdcard_mux), 443c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sdio_grp", 444c8f5c4c7SCristina Ciocan byt_score_sdio_pins, byt_score_sdio_mux), 445c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("emmc_grp", 446c8f5c4c7SCristina Ciocan byt_score_emmc_pins, byt_score_emmc_mux), 447c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("lpc_grp", 448c8f5c4c7SCristina Ciocan byt_score_ilb_lpc_pins, byt_score_lpc_mux), 449c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sata_grp", 450c8f5c4c7SCristina Ciocan byt_score_sata_pins, byt_score_sata_mux), 451c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk0_grp", 452c8f5c4c7SCristina Ciocan byt_score_plt_clk0_pins, byt_score_plt_clk_mux), 453c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk1_grp", 454c8f5c4c7SCristina Ciocan byt_score_plt_clk1_pins, byt_score_plt_clk_mux), 455c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk2_grp", 456c8f5c4c7SCristina Ciocan byt_score_plt_clk2_pins, byt_score_plt_clk_mux), 457c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk3_grp", 458c8f5c4c7SCristina Ciocan byt_score_plt_clk3_pins, byt_score_plt_clk_mux), 459c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk4_grp", 460c8f5c4c7SCristina Ciocan byt_score_plt_clk4_pins, byt_score_plt_clk_mux), 461c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk5_grp", 462c8f5c4c7SCristina Ciocan byt_score_plt_clk5_pins, byt_score_plt_clk_mux), 463c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("smbus_grp", 464c8f5c4c7SCristina Ciocan byt_score_smbus_pins, byt_score_smbus_mux), 465c8f5c4c7SCristina Ciocan }; 466c8f5c4c7SCristina Ciocan 467c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = { 468c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", 469c8f5c4c7SCristina Ciocan }; 470c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = { 471c8f5c4c7SCristina Ciocan "pwm0_grp", "pwm1_grp", 472c8f5c4c7SCristina Ciocan }; 473c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = { 474c8f5c4c7SCristina Ciocan "ssp0_grp", "ssp1_grp", "ssp2_grp", 475c8f5c4c7SCristina Ciocan }; 476c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; 477c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = { 478c8f5c4c7SCristina Ciocan "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", 479c8f5c4c7SCristina Ciocan "i2c6_grp", 480c8f5c4c7SCristina Ciocan }; 481c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; 482c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" }; 483c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" }; 484c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" }; 485c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" }; 486c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = { 487c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 488c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", 489c8f5c4c7SCristina Ciocan }; 490c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" }; 491c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = { 492c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", 493c8f5c4c7SCristina Ciocan "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", 494c8f5c4c7SCristina Ciocan "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", 495c8f5c4c7SCristina Ciocan "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", 496c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 497c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", 498c8f5c4c7SCristina Ciocan 499c8f5c4c7SCristina Ciocan }; 500c8f5c4c7SCristina Ciocan 501c8f5c4c7SCristina Ciocan static const struct byt_function byt_score_functions[] = { 502c8f5c4c7SCristina Ciocan FUNCTION("uart", byt_score_uart_groups), 503c8f5c4c7SCristina Ciocan FUNCTION("pwm", byt_score_pwm_groups), 504c8f5c4c7SCristina Ciocan FUNCTION("ssp", byt_score_ssp_groups), 505c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_score_spi_groups), 506c8f5c4c7SCristina Ciocan FUNCTION("i2c", byt_score_i2c_groups), 507c8f5c4c7SCristina Ciocan FUNCTION("sdcard", byt_score_sdcard_groups), 508c8f5c4c7SCristina Ciocan FUNCTION("sdio", byt_score_sdio_groups), 509c8f5c4c7SCristina Ciocan FUNCTION("emmc", byt_score_emmc_groups), 510c8f5c4c7SCristina Ciocan FUNCTION("lpc", byt_score_lpc_groups), 511c8f5c4c7SCristina Ciocan FUNCTION("sata", byt_score_sata_groups), 512c8f5c4c7SCristina Ciocan FUNCTION("plt_clk", byt_score_plt_clk_groups), 513c8f5c4c7SCristina Ciocan FUNCTION("smbus", byt_score_smbus_groups), 514c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_score_gpio_groups), 515c8f5c4c7SCristina Ciocan }; 516c8f5c4c7SCristina Ciocan 517c8f5c4c7SCristina Ciocan static const struct byt_community byt_score_communities[] = { 518c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), 519c8f5c4c7SCristina Ciocan }; 520c8f5c4c7SCristina Ciocan 521c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_score_soc_data = { 522c8f5c4c7SCristina Ciocan .uid = BYT_SCORE_ACPI_UID, 523c8f5c4c7SCristina Ciocan .pins = byt_score_pins, 524c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_score_pins), 525c8f5c4c7SCristina Ciocan .groups = byt_score_groups, 526c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_score_groups), 527c8f5c4c7SCristina Ciocan .functions = byt_score_functions, 528c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_score_functions), 529c8f5c4c7SCristina Ciocan .communities = byt_score_communities, 530c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_score_communities), 531c8f5c4c7SCristina Ciocan }; 532c8f5c4c7SCristina Ciocan 533c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */ 534c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = { 535c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_S50"), 536c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_S51"), 537c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_S52"), 538c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_S53"), 539c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_S54"), 540c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_S55"), 541c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_S56"), 542c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_S57"), 543c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_S58"), 544c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_S59"), 545c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_S510"), 546c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), 547c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "PMC_SUSCLK0"), 548c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_S513"), 549c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "USB_ULPI_RST"), 550c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), 551c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "PMC_PWRBTN"), 552c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_S517"), 553c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "PMC_SUS_STAT"), 554c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "USB_OC0"), 555c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "USB_OC1"), 556c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "PCU_SPI_CS1"), 557c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_S522"), 558c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_S523"), 559c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_S524"), 560c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_S525"), 561c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_S526"), 562c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_S527"), 563c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "GPIO_S528"), 564c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "GPIO_S529"), 565c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "GPIO_S530"), 566c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "USB_ULPI_CLK"), 567c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "USB_ULPI_DATA0"), 568c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "USB_ULPI_DATA1"), 569c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "USB_ULPI_DATA2"), 570c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "USB_ULPI_DATA3"), 571c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "USB_ULPI_DATA4"), 572c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "USB_ULPI_DATA5"), 573c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "USB_ULPI_DATA6"), 574c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "USB_ULPI_DATA7"), 575c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "USB_ULPI_DIR"), 576c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "USB_ULPI_NXT"), 577c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "USB_ULPI_STP"), 578c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "USB_ULPI_REFCLK"), 579c8f5c4c7SCristina Ciocan }; 580c8f5c4c7SCristina Ciocan 581c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 582c8f5c4c7SCristina Ciocan 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 583c8f5c4c7SCristina Ciocan 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, 584c8f5c4c7SCristina Ciocan 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 585c8f5c4c7SCristina Ciocan 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, 586c8f5c4c7SCristina Ciocan 52, 53, 59, 40, 587c8f5c4c7SCristina Ciocan }; 588c8f5c4c7SCristina Ciocan 589c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; 590c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_sus_usb_oc_mux[] = { 591c8f5c4c7SCristina Ciocan SIMPLE_FUNC("usb", 0), 592c8f5c4c7SCristina Ciocan SIMPLE_FUNC("gpio", 1), 593c8f5c4c7SCristina Ciocan }; 594c8f5c4c7SCristina Ciocan 595c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = { 596c8f5c4c7SCristina Ciocan 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 597c8f5c4c7SCristina Ciocan }; 598c8f5c4c7SCristina Ciocan static const unsigned short byt_sus_usb_ulpi_mode_values[] = { 599c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 600c8f5c4c7SCristina Ciocan }; 601c8f5c4c7SCristina Ciocan static const unsigned short byt_sus_usb_ulpi_gpio_mode_values[] = { 602c8f5c4c7SCristina Ciocan 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 603c8f5c4c7SCristina Ciocan }; 604c8f5c4c7SCristina Ciocan static const struct byt_mixed_func_mux byt_sus_usb_ulpi_mux[] = { 605c8f5c4c7SCristina Ciocan MIXED_FUNC("usb", byt_sus_usb_ulpi_mode_values), 606c8f5c4c7SCristina Ciocan MIXED_FUNC("gpio", byt_sus_usb_ulpi_gpio_mode_values), 607c8f5c4c7SCristina Ciocan }; 608c8f5c4c7SCristina Ciocan 609c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; 610c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_sus_pcu_spi_mux[] = { 611c8f5c4c7SCristina Ciocan SIMPLE_FUNC("spi", 0), 612c8f5c4c7SCristina Ciocan SIMPLE_FUNC("gpio", 1), 613c8f5c4c7SCristina Ciocan }; 614c8f5c4c7SCristina Ciocan 615c8f5c4c7SCristina Ciocan static const struct byt_pingroup byt_sus_groups[] = { 616c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("usb_oc_grp", 617c8f5c4c7SCristina Ciocan byt_sus_usb_over_current_pins, byt_sus_usb_oc_mux), 618c8f5c4c7SCristina Ciocan PIN_GROUP_MIXED("usb_ulpi_grp", 619c8f5c4c7SCristina Ciocan byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mux), 620c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pcu_spi_grp", 621c8f5c4c7SCristina Ciocan byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mux), 622c8f5c4c7SCristina Ciocan }; 623c8f5c4c7SCristina Ciocan 624c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = { 625c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp", 626c8f5c4c7SCristina Ciocan }; 627c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; 628c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = { 629c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp", "pcu_spi_grp", 630c8f5c4c7SCristina Ciocan }; 631c8f5c4c7SCristina Ciocan 632c8f5c4c7SCristina Ciocan static const struct byt_function byt_sus_functions[] = { 633c8f5c4c7SCristina Ciocan FUNCTION("usb", byt_sus_usb_groups), 634c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_sus_spi_groups), 635c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_sus_gpio_groups), 636c8f5c4c7SCristina Ciocan }; 637c8f5c4c7SCristina Ciocan 638c8f5c4c7SCristina Ciocan static const struct byt_community byt_sus_communities[] = { 639c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), 640c8f5c4c7SCristina Ciocan }; 641c8f5c4c7SCristina Ciocan 642c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_sus_soc_data = { 643c8f5c4c7SCristina Ciocan .uid = BYT_SUS_ACPI_UID, 644c8f5c4c7SCristina Ciocan .pins = byt_sus_pins, 645c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_sus_pins), 646c8f5c4c7SCristina Ciocan .groups = byt_sus_groups, 647c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_sus_groups), 648c8f5c4c7SCristina Ciocan .functions = byt_sus_functions, 649c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_sus_functions), 650c8f5c4c7SCristina Ciocan .communities = byt_sus_communities, 651c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_sus_communities), 652c8f5c4c7SCristina Ciocan }; 653c8f5c4c7SCristina Ciocan 654c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = { 655c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_NCORE0"), 656c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_NCORE1"), 657c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_NCORE2"), 658c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_NCORE3"), 659c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_NCORE4"), 660c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_NCORE5"), 661c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_NCORE6"), 662c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_NCORE7"), 663c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_NCORE8"), 664c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_NCORE9"), 665c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_NCORE10"), 666c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "GPIO_NCORE11"), 667c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "GPIO_NCORE12"), 668c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_NCORE13"), 669c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_NCORE14"), 670c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_NCORE15"), 671c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "GPIO_NCORE16"), 672c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_NCORE17"), 673c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "GPIO_NCORE18"), 674c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "GPIO_NCORE19"), 675c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "GPIO_NCORE20"), 676c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "GPIO_NCORE21"), 677c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_NCORE22"), 678c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_NCORE23"), 679c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_NCORE24"), 680c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_NCORE25"), 681c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_NCORE26"), 682c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_NCORE27"), 683c8f5c4c7SCristina Ciocan }; 684c8f5c4c7SCristina Ciocan 685c8f5c4c7SCristina Ciocan static unsigned const byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 686c8f5c4c7SCristina Ciocan 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 687c8f5c4c7SCristina Ciocan 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, 688c8f5c4c7SCristina Ciocan 3, 6, 10, 13, 2, 5, 9, 7, 689c8f5c4c7SCristina Ciocan }; 690c8f5c4c7SCristina Ciocan 691c8f5c4c7SCristina Ciocan static const struct byt_community byt_ncore_communities[] = { 692c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), 693c8f5c4c7SCristina Ciocan }; 694c8f5c4c7SCristina Ciocan 695c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_ncore_soc_data = { 696c8f5c4c7SCristina Ciocan .uid = BYT_NCORE_ACPI_UID, 697c8f5c4c7SCristina Ciocan .pins = byt_ncore_pins, 698c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_ncore_pins), 699c8f5c4c7SCristina Ciocan .communities = byt_ncore_communities, 700c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_ncore_communities), 701c8f5c4c7SCristina Ciocan }; 702c8f5c4c7SCristina Ciocan 703c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data *byt_soc_data[] = { 704c8f5c4c7SCristina Ciocan &byt_score_soc_data, 705c8f5c4c7SCristina Ciocan &byt_sus_soc_data, 706c8f5c4c7SCristina Ciocan &byt_ncore_soc_data, 707c8f5c4c7SCristina Ciocan NULL, 708c8f5c4c7SCristina Ciocan }; 709c8f5c4c7SCristina Ciocan 710c501d0b1SCristina Ciocan static struct byt_community *byt_get_community(struct byt_gpio *vg, 711c501d0b1SCristina Ciocan unsigned int pin) 712c501d0b1SCristina Ciocan { 713c501d0b1SCristina Ciocan struct byt_community *comm; 714c501d0b1SCristina Ciocan int i; 715c501d0b1SCristina Ciocan 716c501d0b1SCristina Ciocan for (i = 0; i < vg->soc_data->ncommunities; i++) { 717c501d0b1SCristina Ciocan comm = vg->communities_copy + i; 718c501d0b1SCristina Ciocan if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) 719c501d0b1SCristina Ciocan return comm; 720c501d0b1SCristina Ciocan } 721c501d0b1SCristina Ciocan 722c501d0b1SCristina Ciocan return NULL; 723c501d0b1SCristina Ciocan } 724c501d0b1SCristina Ciocan 725c501d0b1SCristina Ciocan static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, 7265fae8b86SMika Westerberg int reg) 7275fae8b86SMika Westerberg { 728c501d0b1SCristina Ciocan struct byt_community *comm = byt_get_community(vg, offset); 7291b89970dSAndy Shevchenko u32 reg_offset; 7305fae8b86SMika Westerberg 731c501d0b1SCristina Ciocan if (!comm) 732c501d0b1SCristina Ciocan return NULL; 733c501d0b1SCristina Ciocan 734c501d0b1SCristina Ciocan offset -= comm->pin_base; 7351b89970dSAndy Shevchenko switch (reg) { 7361b89970dSAndy Shevchenko case BYT_INT_STAT_REG: 7375fae8b86SMika Westerberg reg_offset = (offset / 32) * 4; 7381b89970dSAndy Shevchenko break; 7391b89970dSAndy Shevchenko case BYT_DEBOUNCE_REG: 7401b89970dSAndy Shevchenko reg_offset = 0; 7411b89970dSAndy Shevchenko break; 7421b89970dSAndy Shevchenko default: 743c501d0b1SCristina Ciocan reg_offset = comm->pad_map[offset] * 16; 7441b89970dSAndy Shevchenko break; 7451b89970dSAndy Shevchenko } 7465fae8b86SMika Westerberg 747c501d0b1SCristina Ciocan return comm->reg_base + reg_offset + reg; 7485fae8b86SMika Westerberg } 7495fae8b86SMika Westerberg 750c501d0b1SCristina Ciocan static int byt_get_groups_count(struct pinctrl_dev *pctldev) 75195f0972cSMika Westerberg { 752c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 753c501d0b1SCristina Ciocan 754c501d0b1SCristina Ciocan return vg->soc_data->ngroups; 755c501d0b1SCristina Ciocan } 756c501d0b1SCristina Ciocan 757c501d0b1SCristina Ciocan static const char *byt_get_group_name(struct pinctrl_dev *pctldev, 758c501d0b1SCristina Ciocan unsigned int selector) 759c501d0b1SCristina Ciocan { 760c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 761c501d0b1SCristina Ciocan 762c501d0b1SCristina Ciocan return vg->soc_data->groups[selector].name; 763c501d0b1SCristina Ciocan } 764c501d0b1SCristina Ciocan 765c501d0b1SCristina Ciocan static int byt_get_group_pins(struct pinctrl_dev *pctldev, 766c501d0b1SCristina Ciocan unsigned int selector, 767c501d0b1SCristina Ciocan const unsigned int **pins, 768c501d0b1SCristina Ciocan unsigned int *num_pins) 769c501d0b1SCristina Ciocan { 770c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 771c501d0b1SCristina Ciocan 772c501d0b1SCristina Ciocan *pins = vg->soc_data->groups[selector].pins; 773c501d0b1SCristina Ciocan *num_pins = vg->soc_data->groups[selector].npins; 774c501d0b1SCristina Ciocan 775c501d0b1SCristina Ciocan return 0; 776c501d0b1SCristina Ciocan } 777c501d0b1SCristina Ciocan 778c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = { 779c501d0b1SCristina Ciocan .get_groups_count = byt_get_groups_count, 780c501d0b1SCristina Ciocan .get_group_name = byt_get_group_name, 781c501d0b1SCristina Ciocan .get_group_pins = byt_get_group_pins, 782c501d0b1SCristina Ciocan }; 783c501d0b1SCristina Ciocan 784c501d0b1SCristina Ciocan static int byt_get_functions_count(struct pinctrl_dev *pctldev) 785c501d0b1SCristina Ciocan { 786c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 787c501d0b1SCristina Ciocan 788c501d0b1SCristina Ciocan return vg->soc_data->nfunctions; 789c501d0b1SCristina Ciocan } 790c501d0b1SCristina Ciocan 791c501d0b1SCristina Ciocan static const char *byt_get_function_name(struct pinctrl_dev *pctldev, 792c501d0b1SCristina Ciocan unsigned int selector) 793c501d0b1SCristina Ciocan { 794c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 795c501d0b1SCristina Ciocan 796c501d0b1SCristina Ciocan return vg->soc_data->functions[selector].name; 797c501d0b1SCristina Ciocan } 798c501d0b1SCristina Ciocan 799c501d0b1SCristina Ciocan static int byt_get_function_groups(struct pinctrl_dev *pctldev, 800c501d0b1SCristina Ciocan unsigned int selector, 801c501d0b1SCristina Ciocan const char * const **groups, 802c501d0b1SCristina Ciocan unsigned int *num_groups) 803c501d0b1SCristina Ciocan { 804c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 805c501d0b1SCristina Ciocan 806c501d0b1SCristina Ciocan *groups = vg->soc_data->functions[selector].groups; 807c501d0b1SCristina Ciocan *num_groups = vg->soc_data->functions[selector].ngroups; 808c501d0b1SCristina Ciocan 809c501d0b1SCristina Ciocan return 0; 810c501d0b1SCristina Ciocan } 811c501d0b1SCristina Ciocan 812c501d0b1SCristina Ciocan static int byt_get_group_simple_mux(const struct byt_pingroup group, 813c501d0b1SCristina Ciocan const char *func_name, 814c501d0b1SCristina Ciocan unsigned short *func) 815c501d0b1SCristina Ciocan { 816c501d0b1SCristina Ciocan int i; 817c501d0b1SCristina Ciocan 818c501d0b1SCristina Ciocan for (i = 0; i < group.nfuncs; i++) { 819c501d0b1SCristina Ciocan if (!strcmp(group.simple_funcs[i].name, func_name)) { 820c501d0b1SCristina Ciocan *func = group.simple_funcs[i].func; 821c501d0b1SCristina Ciocan return 0; 822c501d0b1SCristina Ciocan } 823c501d0b1SCristina Ciocan } 824c501d0b1SCristina Ciocan 825c501d0b1SCristina Ciocan return 1; 826c501d0b1SCristina Ciocan } 827c501d0b1SCristina Ciocan 828c501d0b1SCristina Ciocan static int byt_get_group_mixed_mux(const struct byt_pingroup group, 829c501d0b1SCristina Ciocan const char *func_name, 830c501d0b1SCristina Ciocan const unsigned short **func) 831c501d0b1SCristina Ciocan { 832c501d0b1SCristina Ciocan int i; 833c501d0b1SCristina Ciocan 834c501d0b1SCristina Ciocan for (i = 0; i < group.nfuncs; i++) { 835c501d0b1SCristina Ciocan if (!strcmp(group.mixed_funcs[i].name, func_name)) { 836c501d0b1SCristina Ciocan *func = group.mixed_funcs[i].func_values; 837c501d0b1SCristina Ciocan return 0; 838c501d0b1SCristina Ciocan } 839c501d0b1SCristina Ciocan } 840c501d0b1SCristina Ciocan 841c501d0b1SCristina Ciocan return 1; 842c501d0b1SCristina Ciocan } 843c501d0b1SCristina Ciocan 844c501d0b1SCristina Ciocan static void byt_set_group_simple_mux(struct byt_gpio *vg, 845c501d0b1SCristina Ciocan const struct byt_pingroup group, 846c501d0b1SCristina Ciocan unsigned short func) 847c501d0b1SCristina Ciocan { 848c501d0b1SCristina Ciocan unsigned long flags; 849c501d0b1SCristina Ciocan int i; 850c501d0b1SCristina Ciocan 851c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 852c501d0b1SCristina Ciocan 853c501d0b1SCristina Ciocan for (i = 0; i < group.npins; i++) { 854c501d0b1SCristina Ciocan void __iomem *padcfg0; 855c501d0b1SCristina Ciocan u32 value; 856c501d0b1SCristina Ciocan 857c501d0b1SCristina Ciocan padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 858c501d0b1SCristina Ciocan if (!padcfg0) { 859c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 860c501d0b1SCristina Ciocan "Group %s, pin %i not muxed (no padcfg0)\n", 861c501d0b1SCristina Ciocan group.name, i); 862c501d0b1SCristina Ciocan continue; 863c501d0b1SCristina Ciocan } 864c501d0b1SCristina Ciocan 865c501d0b1SCristina Ciocan value = readl(padcfg0); 866c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 867c501d0b1SCristina Ciocan value |= func; 868c501d0b1SCristina Ciocan writel(value, padcfg0); 869c501d0b1SCristina Ciocan } 870c501d0b1SCristina Ciocan 871c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 872c501d0b1SCristina Ciocan } 873c501d0b1SCristina Ciocan 874c501d0b1SCristina Ciocan static void byt_set_group_mixed_mux(struct byt_gpio *vg, 875c501d0b1SCristina Ciocan const struct byt_pingroup group, 876c501d0b1SCristina Ciocan const unsigned short *func) 877c501d0b1SCristina Ciocan { 878c501d0b1SCristina Ciocan unsigned long flags; 879c501d0b1SCristina Ciocan int i; 880c501d0b1SCristina Ciocan 881c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 882c501d0b1SCristina Ciocan 883c501d0b1SCristina Ciocan for (i = 0; i < group.npins; i++) { 884c501d0b1SCristina Ciocan void __iomem *padcfg0; 885c501d0b1SCristina Ciocan u32 value; 886c501d0b1SCristina Ciocan 887c501d0b1SCristina Ciocan padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 888c501d0b1SCristina Ciocan if (!padcfg0) { 889c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 890c501d0b1SCristina Ciocan "Group %s, pin %i not muxed (no padcfg0)\n", 891c501d0b1SCristina Ciocan group.name, i); 892c501d0b1SCristina Ciocan continue; 893c501d0b1SCristina Ciocan } 894c501d0b1SCristina Ciocan 895c501d0b1SCristina Ciocan value = readl(padcfg0); 896c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 897c501d0b1SCristina Ciocan value |= func[i]; 898c501d0b1SCristina Ciocan writel(value, padcfg0); 899c501d0b1SCristina Ciocan } 900c501d0b1SCristina Ciocan 901c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 902c501d0b1SCristina Ciocan } 903c501d0b1SCristina Ciocan 904c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 905c501d0b1SCristina Ciocan unsigned int group_selector) 906c501d0b1SCristina Ciocan { 907c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 908c501d0b1SCristina Ciocan const struct byt_function func = vg->soc_data->functions[func_selector]; 909c501d0b1SCristina Ciocan const struct byt_pingroup group = vg->soc_data->groups[group_selector]; 910c501d0b1SCristina Ciocan const unsigned short *mixed_func; 911c501d0b1SCristina Ciocan unsigned short simple_func; 912c501d0b1SCristina Ciocan int ret = 1; 913c501d0b1SCristina Ciocan 914c501d0b1SCristina Ciocan if (group.has_simple_funcs) 915c501d0b1SCristina Ciocan ret = byt_get_group_simple_mux(group, func.name, &simple_func); 916c501d0b1SCristina Ciocan else 917c501d0b1SCristina Ciocan ret = byt_get_group_mixed_mux(group, func.name, &mixed_func); 918c501d0b1SCristina Ciocan 919c501d0b1SCristina Ciocan if (ret) 920c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); 921c501d0b1SCristina Ciocan else if (group.has_simple_funcs) 922c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, simple_func); 923c501d0b1SCristina Ciocan else 924c501d0b1SCristina Ciocan byt_set_group_mixed_mux(vg, group, mixed_func); 925c501d0b1SCristina Ciocan 926c501d0b1SCristina Ciocan return 0; 927c501d0b1SCristina Ciocan } 928c501d0b1SCristina Ciocan 929c501d0b1SCristina Ciocan static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) 930c501d0b1SCristina Ciocan { 931c501d0b1SCristina Ciocan /* SCORE pin 92-93 */ 932c501d0b1SCristina Ciocan if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) && 933c501d0b1SCristina Ciocan offset >= 92 && offset <= 93) 934c501d0b1SCristina Ciocan return 1; 935c501d0b1SCristina Ciocan 936c501d0b1SCristina Ciocan /* SUS pin 11-21 */ 937c501d0b1SCristina Ciocan if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) && 938c501d0b1SCristina Ciocan offset >= 11 && offset <= 21) 939c501d0b1SCristina Ciocan return 1; 940c501d0b1SCristina Ciocan 941c501d0b1SCristina Ciocan return 0; 942c501d0b1SCristina Ciocan } 943c501d0b1SCristina Ciocan 944c501d0b1SCristina Ciocan static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) 945c501d0b1SCristina Ciocan { 946c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 94795f0972cSMika Westerberg unsigned long flags; 94895f0972cSMika Westerberg u32 value; 94995f0972cSMika Westerberg 95078e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 95195f0972cSMika Westerberg value = readl(reg); 95295f0972cSMika Westerberg value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); 95395f0972cSMika Westerberg writel(value, reg); 95478e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 95595f0972cSMika Westerberg } 95695f0972cSMika Westerberg 957c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, 958c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 959c501d0b1SCristina Ciocan unsigned int offset) 9605fae8b86SMika Westerberg { 961c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 962c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 963f8323b6bSMika Westerberg u32 value, gpio_mux; 96439ce8150SMika Westerberg unsigned long flags; 96539ce8150SMika Westerberg 96678e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 9675fae8b86SMika Westerberg 9685fae8b86SMika Westerberg /* 9695fae8b86SMika Westerberg * In most cases, func pin mux 000 means GPIO function. 9705fae8b86SMika Westerberg * But, some pins may have func pin mux 001 represents 971f8323b6bSMika Westerberg * GPIO function. 972f8323b6bSMika Westerberg * 973f8323b6bSMika Westerberg * Because there are devices out there where some pins were not 974f8323b6bSMika Westerberg * configured correctly we allow changing the mux value from 975f8323b6bSMika Westerberg * request (but print out warning about that). 9765fae8b86SMika Westerberg */ 9775fae8b86SMika Westerberg value = readl(reg) & BYT_PIN_MUX; 978f8323b6bSMika Westerberg gpio_mux = byt_get_gpio_mux(vg, offset); 979b5894d12SHans de Goede if (gpio_mux != value) { 980f8323b6bSMika Westerberg value = readl(reg) & ~BYT_PIN_MUX; 981f8323b6bSMika Westerberg value |= gpio_mux; 982f8323b6bSMika Westerberg writel(value, reg); 983f8323b6bSMika Westerberg 984b5894d12SHans de Goede dev_warn(&vg->pdev->dev, FW_BUG 985f8323b6bSMika Westerberg "pin %u forcibly re-configured as GPIO\n", offset); 9865fae8b86SMika Westerberg } 9875fae8b86SMika Westerberg 98878e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 98939ce8150SMika Westerberg 9905fae8b86SMika Westerberg pm_runtime_get(&vg->pdev->dev); 9915fae8b86SMika Westerberg 9925fae8b86SMika Westerberg return 0; 9935fae8b86SMika Westerberg } 9945fae8b86SMika Westerberg 995c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, 996c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 997c501d0b1SCristina Ciocan unsigned int offset) 998c501d0b1SCristina Ciocan { 999c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1000c501d0b1SCristina Ciocan 1001c501d0b1SCristina Ciocan byt_gpio_clear_triggering(vg, offset); 1002c501d0b1SCristina Ciocan pm_runtime_put(&vg->pdev->dev); 1003c501d0b1SCristina Ciocan } 1004c501d0b1SCristina Ciocan 1005c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, 1006c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 1007c501d0b1SCristina Ciocan unsigned int offset, 1008c501d0b1SCristina Ciocan bool input) 1009c501d0b1SCristina Ciocan { 1010c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1011c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 1012c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1013c501d0b1SCristina Ciocan unsigned long flags; 1014c501d0b1SCristina Ciocan u32 value; 1015c501d0b1SCristina Ciocan 1016c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1017c501d0b1SCristina Ciocan 1018c501d0b1SCristina Ciocan value = readl(val_reg); 1019c501d0b1SCristina Ciocan value &= ~BYT_DIR_MASK; 1020c501d0b1SCristina Ciocan if (input) 1021c501d0b1SCristina Ciocan value |= BYT_OUTPUT_EN; 1022c501d0b1SCristina Ciocan else 1023c501d0b1SCristina Ciocan /* 1024c501d0b1SCristina Ciocan * Before making any direction modifications, do a check if gpio 1025c501d0b1SCristina Ciocan * is set for direct IRQ. On baytrail, setting GPIO to output 1026c501d0b1SCristina Ciocan * does not make sense, so let's at least warn the caller before 1027c501d0b1SCristina Ciocan * they shoot themselves in the foot. 1028c501d0b1SCristina Ciocan */ 1029c501d0b1SCristina Ciocan WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, 1030c501d0b1SCristina Ciocan "Potential Error: Setting GPIO with direct_irq_en to output"); 1031c501d0b1SCristina Ciocan writel(value, val_reg); 1032c501d0b1SCristina Ciocan 1033c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1034c501d0b1SCristina Ciocan 1035c501d0b1SCristina Ciocan return 0; 1036c501d0b1SCristina Ciocan } 1037c501d0b1SCristina Ciocan 1038c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = { 1039c501d0b1SCristina Ciocan .get_functions_count = byt_get_functions_count, 1040c501d0b1SCristina Ciocan .get_function_name = byt_get_function_name, 1041c501d0b1SCristina Ciocan .get_function_groups = byt_get_function_groups, 1042c501d0b1SCristina Ciocan .set_mux = byt_set_mux, 1043c501d0b1SCristina Ciocan .gpio_request_enable = byt_gpio_request_enable, 1044c501d0b1SCristina Ciocan .gpio_disable_free = byt_gpio_disable_free, 1045c501d0b1SCristina Ciocan .gpio_set_direction = byt_gpio_set_direction, 1046c501d0b1SCristina Ciocan }; 1047c501d0b1SCristina Ciocan 1048c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength) 1049c501d0b1SCristina Ciocan { 1050c501d0b1SCristina Ciocan switch (reg & BYT_PULL_STR_MASK) { 1051c501d0b1SCristina Ciocan case BYT_PULL_STR_2K: 1052c501d0b1SCristina Ciocan *strength = 2000; 1053c501d0b1SCristina Ciocan break; 1054c501d0b1SCristina Ciocan case BYT_PULL_STR_10K: 1055c501d0b1SCristina Ciocan *strength = 10000; 1056c501d0b1SCristina Ciocan break; 1057c501d0b1SCristina Ciocan case BYT_PULL_STR_20K: 1058c501d0b1SCristina Ciocan *strength = 20000; 1059c501d0b1SCristina Ciocan break; 1060c501d0b1SCristina Ciocan case BYT_PULL_STR_40K: 1061c501d0b1SCristina Ciocan *strength = 40000; 1062c501d0b1SCristina Ciocan break; 1063c501d0b1SCristina Ciocan } 1064c501d0b1SCristina Ciocan } 1065c501d0b1SCristina Ciocan 1066c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength) 1067c501d0b1SCristina Ciocan { 1068c501d0b1SCristina Ciocan *reg &= ~BYT_PULL_STR_MASK; 1069c501d0b1SCristina Ciocan 1070c501d0b1SCristina Ciocan switch (strength) { 1071c501d0b1SCristina Ciocan case 2000: 1072c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_2K; 1073c501d0b1SCristina Ciocan break; 1074c501d0b1SCristina Ciocan case 10000: 1075c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_10K; 1076c501d0b1SCristina Ciocan break; 1077c501d0b1SCristina Ciocan case 20000: 1078c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_20K; 1079c501d0b1SCristina Ciocan break; 1080c501d0b1SCristina Ciocan case 40000: 1081c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_40K; 1082c501d0b1SCristina Ciocan break; 1083c501d0b1SCristina Ciocan default: 1084c501d0b1SCristina Ciocan return -EINVAL; 1085c501d0b1SCristina Ciocan } 1086c501d0b1SCristina Ciocan 1087c501d0b1SCristina Ciocan return 0; 1088c501d0b1SCristina Ciocan } 1089c501d0b1SCristina Ciocan 1090c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, 1091c501d0b1SCristina Ciocan unsigned long *config) 1092c501d0b1SCristina Ciocan { 1093c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1094c501d0b1SCristina Ciocan enum pin_config_param param = pinconf_to_config_param(*config); 1095c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1096c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 109704ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 1098c501d0b1SCristina Ciocan unsigned long flags; 1099658b476cSCristina Ciocan u32 conf, pull, val, debounce; 1100c501d0b1SCristina Ciocan u16 arg = 0; 1101c501d0b1SCristina Ciocan 1102c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1103c501d0b1SCristina Ciocan conf = readl(conf_reg); 1104c501d0b1SCristina Ciocan pull = conf & BYT_PULL_ASSIGN_MASK; 1105c501d0b1SCristina Ciocan val = readl(val_reg); 1106c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1107c501d0b1SCristina Ciocan 1108c501d0b1SCristina Ciocan switch (param) { 1109c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 1110c501d0b1SCristina Ciocan if (pull) 1111c501d0b1SCristina Ciocan return -EINVAL; 1112c501d0b1SCristina Ciocan break; 1113c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 1114c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 1115c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) 1116c501d0b1SCristina Ciocan return -EINVAL; 1117c501d0b1SCristina Ciocan 1118c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 1119c501d0b1SCristina Ciocan 1120c501d0b1SCristina Ciocan break; 1121c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 1122c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 1123c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) 1124c501d0b1SCristina Ciocan return -EINVAL; 1125c501d0b1SCristina Ciocan 1126c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 1127c501d0b1SCristina Ciocan 1128c501d0b1SCristina Ciocan break; 1129658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 1130658b476cSCristina Ciocan if (!(conf & BYT_DEBOUNCE_EN)) 1131658b476cSCristina Ciocan return -EINVAL; 1132658b476cSCristina Ciocan 1133658b476cSCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 113404ff5a09SAndy Shevchenko debounce = readl(db_reg); 1135658b476cSCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1136658b476cSCristina Ciocan 1137658b476cSCristina Ciocan switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { 1138658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_375US: 1139658b476cSCristina Ciocan arg = 375; 1140658b476cSCristina Ciocan break; 1141658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_750US: 1142658b476cSCristina Ciocan arg = 750; 1143658b476cSCristina Ciocan break; 1144658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_1500US: 1145658b476cSCristina Ciocan arg = 1500; 1146658b476cSCristina Ciocan break; 1147658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_3MS: 1148658b476cSCristina Ciocan arg = 3000; 1149658b476cSCristina Ciocan break; 1150658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_6MS: 1151658b476cSCristina Ciocan arg = 6000; 1152658b476cSCristina Ciocan break; 1153658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_12MS: 1154658b476cSCristina Ciocan arg = 12000; 1155658b476cSCristina Ciocan break; 1156658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_24MS: 1157658b476cSCristina Ciocan arg = 24000; 1158658b476cSCristina Ciocan break; 1159658b476cSCristina Ciocan default: 1160658b476cSCristina Ciocan return -EINVAL; 1161658b476cSCristina Ciocan } 1162658b476cSCristina Ciocan 1163658b476cSCristina Ciocan break; 1164c501d0b1SCristina Ciocan default: 1165c501d0b1SCristina Ciocan return -ENOTSUPP; 1166c501d0b1SCristina Ciocan } 1167c501d0b1SCristina Ciocan 1168c501d0b1SCristina Ciocan *config = pinconf_to_config_packed(param, arg); 1169c501d0b1SCristina Ciocan 1170c501d0b1SCristina Ciocan return 0; 1171c501d0b1SCristina Ciocan } 1172c501d0b1SCristina Ciocan 1173c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, 1174c501d0b1SCristina Ciocan unsigned int offset, 1175c501d0b1SCristina Ciocan unsigned long *configs, 1176c501d0b1SCristina Ciocan unsigned int num_configs) 1177c501d0b1SCristina Ciocan { 1178c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1179c501d0b1SCristina Ciocan unsigned int param, arg; 1180c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1181c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 118204ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 1183c501d0b1SCristina Ciocan unsigned long flags; 1184658b476cSCristina Ciocan u32 conf, val, debounce; 1185c501d0b1SCristina Ciocan int i, ret = 0; 1186c501d0b1SCristina Ciocan 1187c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1188c501d0b1SCristina Ciocan 1189c501d0b1SCristina Ciocan conf = readl(conf_reg); 1190c501d0b1SCristina Ciocan val = readl(val_reg); 1191c501d0b1SCristina Ciocan 1192c501d0b1SCristina Ciocan for (i = 0; i < num_configs; i++) { 1193c501d0b1SCristina Ciocan param = pinconf_to_config_param(configs[i]); 1194c501d0b1SCristina Ciocan arg = pinconf_to_config_argument(configs[i]); 1195c501d0b1SCristina Ciocan 1196c501d0b1SCristina Ciocan switch (param) { 1197c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 1198c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1199c501d0b1SCristina Ciocan break; 1200c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 1201c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1202c501d0b1SCristina Ciocan if (arg == 1) 1203c501d0b1SCristina Ciocan arg = 2000; 1204c501d0b1SCristina Ciocan 1205c501d0b1SCristina Ciocan /* 1206c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1207c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1208c501d0b1SCristina Ciocan */ 1209c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1210c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1211c501d0b1SCristina Ciocan writel(val, val_reg); 1212c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 1213c501d0b1SCristina Ciocan "pin %u forcibly set to input mode\n", 1214c501d0b1SCristina Ciocan offset); 1215c501d0b1SCristina Ciocan } 1216c501d0b1SCristina Ciocan 1217c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1218c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_DOWN; 1219c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1220c501d0b1SCristina Ciocan 1221c501d0b1SCristina Ciocan break; 1222c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 1223c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1224c501d0b1SCristina Ciocan if (arg == 1) 1225c501d0b1SCristina Ciocan arg = 2000; 1226c501d0b1SCristina Ciocan 1227c501d0b1SCristina Ciocan /* 1228c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1229c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1230c501d0b1SCristina Ciocan */ 1231c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1232c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1233c501d0b1SCristina Ciocan writel(val, val_reg); 1234c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 1235c501d0b1SCristina Ciocan "pin %u forcibly set to input mode\n", 1236c501d0b1SCristina Ciocan offset); 1237c501d0b1SCristina Ciocan } 1238c501d0b1SCristina Ciocan 1239c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1240c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_UP; 1241c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1242c501d0b1SCristina Ciocan 1243c501d0b1SCristina Ciocan break; 1244658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 124504ff5a09SAndy Shevchenko debounce = readl(db_reg); 124604ff5a09SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 1247658b476cSCristina Ciocan 1248827e1579SAndy Shevchenko if (arg) 1249827e1579SAndy Shevchenko conf |= BYT_DEBOUNCE_EN; 1250827e1579SAndy Shevchenko else 1251827e1579SAndy Shevchenko conf &= ~BYT_DEBOUNCE_EN; 1252827e1579SAndy Shevchenko 1253658b476cSCristina Ciocan switch (arg) { 1254658b476cSCristina Ciocan case 375: 125504ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_375US; 1256658b476cSCristina Ciocan break; 1257658b476cSCristina Ciocan case 750: 125804ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_750US; 1259658b476cSCristina Ciocan break; 1260658b476cSCristina Ciocan case 1500: 126104ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_1500US; 1262658b476cSCristina Ciocan break; 1263658b476cSCristina Ciocan case 3000: 126404ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_3MS; 1265658b476cSCristina Ciocan break; 1266658b476cSCristina Ciocan case 6000: 126704ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_6MS; 1268658b476cSCristina Ciocan break; 1269658b476cSCristina Ciocan case 12000: 127004ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_12MS; 1271658b476cSCristina Ciocan break; 1272658b476cSCristina Ciocan case 24000: 127304ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_24MS; 1274658b476cSCristina Ciocan break; 1275658b476cSCristina Ciocan default: 1276827e1579SAndy Shevchenko if (arg) 1277658b476cSCristina Ciocan ret = -EINVAL; 1278827e1579SAndy Shevchenko break; 1279658b476cSCristina Ciocan } 1280658b476cSCristina Ciocan 128104ff5a09SAndy Shevchenko if (!ret) 128204ff5a09SAndy Shevchenko writel(debounce, db_reg); 1283658b476cSCristina Ciocan break; 1284c501d0b1SCristina Ciocan default: 1285c501d0b1SCristina Ciocan ret = -ENOTSUPP; 1286c501d0b1SCristina Ciocan } 1287c501d0b1SCristina Ciocan 1288c501d0b1SCristina Ciocan if (ret) 1289c501d0b1SCristina Ciocan break; 1290c501d0b1SCristina Ciocan } 1291c501d0b1SCristina Ciocan 1292c501d0b1SCristina Ciocan if (!ret) 1293c501d0b1SCristina Ciocan writel(conf, conf_reg); 1294c501d0b1SCristina Ciocan 1295c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1296c501d0b1SCristina Ciocan 1297c501d0b1SCristina Ciocan return ret; 1298c501d0b1SCristina Ciocan } 1299c501d0b1SCristina Ciocan 1300c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = { 1301c501d0b1SCristina Ciocan .is_generic = true, 1302c501d0b1SCristina Ciocan .pin_config_get = byt_pin_config_get, 1303c501d0b1SCristina Ciocan .pin_config_set = byt_pin_config_set, 1304c501d0b1SCristina Ciocan }; 1305c501d0b1SCristina Ciocan 1306c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = { 1307c501d0b1SCristina Ciocan .pctlops = &byt_pinctrl_ops, 1308c501d0b1SCristina Ciocan .pmxops = &byt_pinmux_ops, 1309c501d0b1SCristina Ciocan .confops = &byt_pinconf_ops, 1310c501d0b1SCristina Ciocan .owner = THIS_MODULE, 1311c501d0b1SCristina Ciocan }; 1312c501d0b1SCristina Ciocan 13135fae8b86SMika Westerberg static int byt_gpio_get(struct gpio_chip *chip, unsigned offset) 13145fae8b86SMika Westerberg { 1315bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1316c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 131739ce8150SMika Westerberg unsigned long flags; 131839ce8150SMika Westerberg u32 val; 131939ce8150SMika Westerberg 132078e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 132139ce8150SMika Westerberg val = readl(reg); 132278e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 132339ce8150SMika Westerberg 13243bde8771SLinus Walleij return !!(val & BYT_LEVEL); 13255fae8b86SMika Westerberg } 13265fae8b86SMika Westerberg 13275fae8b86SMika Westerberg static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 13285fae8b86SMika Westerberg { 1329bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1330c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 13315fae8b86SMika Westerberg unsigned long flags; 13325fae8b86SMika Westerberg u32 old_val; 13335fae8b86SMika Westerberg 133486e3ef81SCristina Ciocan if (!reg) 133586e3ef81SCristina Ciocan return; 133686e3ef81SCristina Ciocan 133778e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 13385fae8b86SMika Westerberg old_val = readl(reg); 13395fae8b86SMika Westerberg if (value) 13405fae8b86SMika Westerberg writel(old_val | BYT_LEVEL, reg); 13415fae8b86SMika Westerberg else 13425fae8b86SMika Westerberg writel(old_val & ~BYT_LEVEL, reg); 134378e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 13445fae8b86SMika Westerberg } 13455fae8b86SMika Westerberg 134686e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 13475fae8b86SMika Westerberg { 1348bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1349c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 13505fae8b86SMika Westerberg unsigned long flags; 13515fae8b86SMika Westerberg u32 value; 13525fae8b86SMika Westerberg 135386e3ef81SCristina Ciocan if (!reg) 135486e3ef81SCristina Ciocan return -EINVAL; 135586e3ef81SCristina Ciocan 135678e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 135786e3ef81SCristina Ciocan value = readl(reg); 135878e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 13595fae8b86SMika Westerberg 136086e3ef81SCristina Ciocan if (!(value & BYT_OUTPUT_EN)) 136186e3ef81SCristina Ciocan return GPIOF_DIR_OUT; 136286e3ef81SCristina Ciocan if (!(value & BYT_INPUT_EN)) 136386e3ef81SCristina Ciocan return GPIOF_DIR_IN; 136486e3ef81SCristina Ciocan 136586e3ef81SCristina Ciocan return -EINVAL; 13665fae8b86SMika Westerberg } 13675fae8b86SMika Westerberg 136886e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 13695fae8b86SMika Westerberg { 137086e3ef81SCristina Ciocan return pinctrl_gpio_direction_input(chip->base + offset); 137186e3ef81SCristina Ciocan } 13725fae8b86SMika Westerberg 137386e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip, 137486e3ef81SCristina Ciocan unsigned int offset, int value) 137586e3ef81SCristina Ciocan { 137686e3ef81SCristina Ciocan int ret = pinctrl_gpio_direction_output(chip->base + offset); 13775fae8b86SMika Westerberg 137886e3ef81SCristina Ciocan if (ret) 137986e3ef81SCristina Ciocan return ret; 138086e3ef81SCristina Ciocan 138186e3ef81SCristina Ciocan byt_gpio_set(chip, offset, value); 13825fae8b86SMika Westerberg 13835fae8b86SMika Westerberg return 0; 13845fae8b86SMika Westerberg } 13855fae8b86SMika Westerberg 13865fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 13875fae8b86SMika Westerberg { 1388bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 13895fae8b86SMika Westerberg int i; 139086e3ef81SCristina Ciocan u32 conf0, val; 13915fae8b86SMika Westerberg 139286e3ef81SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 139386e3ef81SCristina Ciocan const struct byt_community *comm; 13945fae8b86SMika Westerberg const char *pull_str = NULL; 13955fae8b86SMika Westerberg const char *pull = NULL; 139686e3ef81SCristina Ciocan void __iomem *reg; 139778e1c896SMika Westerberg unsigned long flags; 13985fae8b86SMika Westerberg const char *label; 139986e3ef81SCristina Ciocan unsigned int pin; 140078e1c896SMika Westerberg 140178e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 140286e3ef81SCristina Ciocan pin = vg->soc_data->pins[i].number; 140386e3ef81SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 140486e3ef81SCristina Ciocan if (!reg) { 140586e3ef81SCristina Ciocan seq_printf(s, 140686e3ef81SCristina Ciocan "Could not retrieve pin %i conf0 reg\n", 140786e3ef81SCristina Ciocan pin); 140822bbd21bSDan Carpenter raw_spin_unlock_irqrestore(&vg->lock, flags); 140986e3ef81SCristina Ciocan continue; 141086e3ef81SCristina Ciocan } 141186e3ef81SCristina Ciocan conf0 = readl(reg); 141286e3ef81SCristina Ciocan 141386e3ef81SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 141486e3ef81SCristina Ciocan if (!reg) { 141586e3ef81SCristina Ciocan seq_printf(s, 141686e3ef81SCristina Ciocan "Could not retrieve pin %i val reg\n", pin); 141722bbd21bSDan Carpenter raw_spin_unlock_irqrestore(&vg->lock, flags); 141822bbd21bSDan Carpenter continue; 141986e3ef81SCristina Ciocan } 142086e3ef81SCristina Ciocan val = readl(reg); 142178e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 14225fae8b86SMika Westerberg 142386e3ef81SCristina Ciocan comm = byt_get_community(vg, pin); 142486e3ef81SCristina Ciocan if (!comm) { 142586e3ef81SCristina Ciocan seq_printf(s, 142686e3ef81SCristina Ciocan "Could not get community for pin %i\n", pin); 142786e3ef81SCristina Ciocan continue; 142886e3ef81SCristina Ciocan } 14295fae8b86SMika Westerberg label = gpiochip_is_requested(chip, i); 14305fae8b86SMika Westerberg if (!label) 14315fae8b86SMika Westerberg label = "Unrequested"; 14325fae8b86SMika Westerberg 14335fae8b86SMika Westerberg switch (conf0 & BYT_PULL_ASSIGN_MASK) { 14345fae8b86SMika Westerberg case BYT_PULL_ASSIGN_UP: 14355fae8b86SMika Westerberg pull = "up"; 14365fae8b86SMika Westerberg break; 14375fae8b86SMika Westerberg case BYT_PULL_ASSIGN_DOWN: 14385fae8b86SMika Westerberg pull = "down"; 14395fae8b86SMika Westerberg break; 14405fae8b86SMika Westerberg } 14415fae8b86SMika Westerberg 14425fae8b86SMika Westerberg switch (conf0 & BYT_PULL_STR_MASK) { 14435fae8b86SMika Westerberg case BYT_PULL_STR_2K: 14445fae8b86SMika Westerberg pull_str = "2k"; 14455fae8b86SMika Westerberg break; 14465fae8b86SMika Westerberg case BYT_PULL_STR_10K: 14475fae8b86SMika Westerberg pull_str = "10k"; 14485fae8b86SMika Westerberg break; 14495fae8b86SMika Westerberg case BYT_PULL_STR_20K: 14505fae8b86SMika Westerberg pull_str = "20k"; 14515fae8b86SMika Westerberg break; 14525fae8b86SMika Westerberg case BYT_PULL_STR_40K: 14535fae8b86SMika Westerberg pull_str = "40k"; 14545fae8b86SMika Westerberg break; 14555fae8b86SMika Westerberg } 14565fae8b86SMika Westerberg 14575fae8b86SMika Westerberg seq_printf(s, 14585fae8b86SMika Westerberg " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", 145986e3ef81SCristina Ciocan pin, 14605fae8b86SMika Westerberg label, 14615fae8b86SMika Westerberg val & BYT_INPUT_EN ? " " : "in", 14625fae8b86SMika Westerberg val & BYT_OUTPUT_EN ? " " : "out", 14635fae8b86SMika Westerberg val & BYT_LEVEL ? "hi" : "lo", 14643655a1caSAlexander Stein comm->pad_map[i], comm->pad_map[i] * 16, 14655fae8b86SMika Westerberg conf0 & 0x7, 14665fae8b86SMika Westerberg conf0 & BYT_TRIG_NEG ? " fall" : " ", 14675fae8b86SMika Westerberg conf0 & BYT_TRIG_POS ? " rise" : " ", 14685fae8b86SMika Westerberg conf0 & BYT_TRIG_LVL ? " level" : " "); 14695fae8b86SMika Westerberg 14705fae8b86SMika Westerberg if (pull && pull_str) 14715fae8b86SMika Westerberg seq_printf(s, " %-4s %-3s", pull, pull_str); 14725fae8b86SMika Westerberg else 14735fae8b86SMika Westerberg seq_puts(s, " "); 14745fae8b86SMika Westerberg 14755fae8b86SMika Westerberg if (conf0 & BYT_IODEN) 14765fae8b86SMika Westerberg seq_puts(s, " open-drain"); 14775fae8b86SMika Westerberg 14785fae8b86SMika Westerberg seq_puts(s, "\n"); 14795fae8b86SMika Westerberg } 14805fae8b86SMika Westerberg } 14815fae8b86SMika Westerberg 148286e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = { 148386e3ef81SCristina Ciocan .owner = THIS_MODULE, 148486e3ef81SCristina Ciocan .request = gpiochip_generic_request, 148586e3ef81SCristina Ciocan .free = gpiochip_generic_free, 148686e3ef81SCristina Ciocan .get_direction = byt_gpio_get_direction, 148786e3ef81SCristina Ciocan .direction_input = byt_gpio_direction_input, 148886e3ef81SCristina Ciocan .direction_output = byt_gpio_direction_output, 148986e3ef81SCristina Ciocan .get = byt_gpio_get, 149086e3ef81SCristina Ciocan .set = byt_gpio_set, 149186e3ef81SCristina Ciocan .dbg_show = byt_gpio_dbg_show, 149286e3ef81SCristina Ciocan }; 149386e3ef81SCristina Ciocan 149431e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d) 149531e4329fSMika Westerberg { 149631e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1497bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(gc); 149831e4329fSMika Westerberg unsigned offset = irqd_to_hwirq(d); 149931e4329fSMika Westerberg void __iomem *reg; 150031e4329fSMika Westerberg 1501c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); 15029f573b98SCristina Ciocan if (!reg) 15039f573b98SCristina Ciocan return; 15049f573b98SCristina Ciocan 15059f573b98SCristina Ciocan raw_spin_lock(&vg->lock); 150631e4329fSMika Westerberg writel(BIT(offset % 32), reg); 150778e1c896SMika Westerberg raw_spin_unlock(&vg->lock); 150831e4329fSMika Westerberg } 150931e4329fSMika Westerberg 15109f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d) 15119f573b98SCristina Ciocan { 15129f573b98SCristina Ciocan struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 15139f573b98SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data(gc); 15149f573b98SCristina Ciocan 15159f573b98SCristina Ciocan byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); 15169f573b98SCristina Ciocan } 15179f573b98SCristina Ciocan 15185fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d) 15195fae8b86SMika Westerberg { 152031e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1521bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(gc); 152231e4329fSMika Westerberg unsigned offset = irqd_to_hwirq(d); 152331e4329fSMika Westerberg unsigned long flags; 152431e4329fSMika Westerberg void __iomem *reg; 152531e4329fSMika Westerberg u32 value; 152631e4329fSMika Westerberg 1527c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 15289f573b98SCristina Ciocan if (!reg) 15299f573b98SCristina Ciocan return; 153078e1c896SMika Westerberg 153178e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 153231e4329fSMika Westerberg value = readl(reg); 153331e4329fSMika Westerberg 153431e4329fSMika Westerberg switch (irqd_get_trigger_type(d)) { 153531e4329fSMika Westerberg case IRQ_TYPE_LEVEL_HIGH: 153631e4329fSMika Westerberg value |= BYT_TRIG_LVL; 1537399476bdSGustavo A. R. Silva /* fall through */ 153831e4329fSMika Westerberg case IRQ_TYPE_EDGE_RISING: 153931e4329fSMika Westerberg value |= BYT_TRIG_POS; 154031e4329fSMika Westerberg break; 154131e4329fSMika Westerberg case IRQ_TYPE_LEVEL_LOW: 154231e4329fSMika Westerberg value |= BYT_TRIG_LVL; 1543399476bdSGustavo A. R. Silva /* fall through */ 154431e4329fSMika Westerberg case IRQ_TYPE_EDGE_FALLING: 154531e4329fSMika Westerberg value |= BYT_TRIG_NEG; 154631e4329fSMika Westerberg break; 154731e4329fSMika Westerberg case IRQ_TYPE_EDGE_BOTH: 154831e4329fSMika Westerberg value |= (BYT_TRIG_NEG | BYT_TRIG_POS); 154931e4329fSMika Westerberg break; 155031e4329fSMika Westerberg } 155131e4329fSMika Westerberg 155231e4329fSMika Westerberg writel(value, reg); 155331e4329fSMika Westerberg 155478e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 15555fae8b86SMika Westerberg } 15565fae8b86SMika Westerberg 15579f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type) 15585fae8b86SMika Westerberg { 15599f573b98SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); 15609f573b98SCristina Ciocan u32 offset = irqd_to_hwirq(d); 15619f573b98SCristina Ciocan u32 value; 15629f573b98SCristina Ciocan unsigned long flags; 15639f573b98SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 156431e4329fSMika Westerberg 15659f573b98SCristina Ciocan if (!reg || offset >= vg->chip.ngpio) 15669f573b98SCristina Ciocan return -EINVAL; 15679f573b98SCristina Ciocan 15689f573b98SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 15699f573b98SCristina Ciocan value = readl(reg); 15709f573b98SCristina Ciocan 15719f573b98SCristina Ciocan WARN(value & BYT_DIRECT_IRQ_EN, 15729f573b98SCristina Ciocan "Bad pad config for io mode, force direct_irq_en bit clearing"); 15739f573b98SCristina Ciocan 15749f573b98SCristina Ciocan /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits 15759f573b98SCristina Ciocan * are used to indicate high and low level triggering 15769f573b98SCristina Ciocan */ 15779f573b98SCristina Ciocan value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | 15789f573b98SCristina Ciocan BYT_TRIG_LVL); 15799291c65bSHans de Goede /* Enable glitch filtering */ 15809291c65bSHans de Goede value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK | 15819291c65bSHans de Goede BYT_GLITCH_F_FAST_CLK; 15829f573b98SCristina Ciocan 15839f573b98SCristina Ciocan writel(value, reg); 15849f573b98SCristina Ciocan 15859f573b98SCristina Ciocan if (type & IRQ_TYPE_EDGE_BOTH) 15869f573b98SCristina Ciocan irq_set_handler_locked(d, handle_edge_irq); 15879f573b98SCristina Ciocan else if (type & IRQ_TYPE_LEVEL_MASK) 15889f573b98SCristina Ciocan irq_set_handler_locked(d, handle_level_irq); 15899f573b98SCristina Ciocan 15909f573b98SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 15919f573b98SCristina Ciocan 15929f573b98SCristina Ciocan return 0; 15935fae8b86SMika Westerberg } 15945fae8b86SMika Westerberg 15955fae8b86SMika Westerberg static struct irq_chip byt_irqchip = { 15965fae8b86SMika Westerberg .name = "BYT-GPIO", 159731e4329fSMika Westerberg .irq_ack = byt_irq_ack, 15985fae8b86SMika Westerberg .irq_mask = byt_irq_mask, 15995fae8b86SMika Westerberg .irq_unmask = byt_irq_unmask, 16005fae8b86SMika Westerberg .irq_set_type = byt_irq_type, 16015fae8b86SMika Westerberg .flags = IRQCHIP_SKIP_SET_WAKE, 16025fae8b86SMika Westerberg }; 16035fae8b86SMika Westerberg 160471e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc) 160571e6ca61SCristina Ciocan { 160671e6ca61SCristina Ciocan struct irq_data *data = irq_desc_get_irq_data(desc); 160771e6ca61SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data( 160871e6ca61SCristina Ciocan irq_desc_get_handler_data(desc)); 160971e6ca61SCristina Ciocan struct irq_chip *chip = irq_data_get_irq_chip(data); 161071e6ca61SCristina Ciocan u32 base, pin; 161171e6ca61SCristina Ciocan void __iomem *reg; 161271e6ca61SCristina Ciocan unsigned long pending; 161371e6ca61SCristina Ciocan unsigned int virq; 161471e6ca61SCristina Ciocan 161571e6ca61SCristina Ciocan /* check from GPIO controller which pin triggered the interrupt */ 161671e6ca61SCristina Ciocan for (base = 0; base < vg->chip.ngpio; base += 32) { 161771e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 161871e6ca61SCristina Ciocan 161971e6ca61SCristina Ciocan if (!reg) { 162071e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 162171e6ca61SCristina Ciocan "Pin %i: could not retrieve interrupt status register\n", 162271e6ca61SCristina Ciocan base); 162371e6ca61SCristina Ciocan continue; 162471e6ca61SCristina Ciocan } 162571e6ca61SCristina Ciocan 1626cdca06e4SAlexander Stein raw_spin_lock(&vg->lock); 162771e6ca61SCristina Ciocan pending = readl(reg); 1628cdca06e4SAlexander Stein raw_spin_unlock(&vg->lock); 162971e6ca61SCristina Ciocan for_each_set_bit(pin, &pending, 32) { 1630f0fbe7bcSThierry Reding virq = irq_find_mapping(vg->chip.irq.domain, base + pin); 163171e6ca61SCristina Ciocan generic_handle_irq(virq); 163271e6ca61SCristina Ciocan } 163371e6ca61SCristina Ciocan } 163471e6ca61SCristina Ciocan chip->irq_eoi(data); 163571e6ca61SCristina Ciocan } 163671e6ca61SCristina Ciocan 16375fae8b86SMika Westerberg static void byt_gpio_irq_init_hw(struct byt_gpio *vg) 16385fae8b86SMika Westerberg { 163949c03096SAndy Shevchenko struct gpio_chip *gc = &vg->chip; 164049c03096SAndy Shevchenko struct device *dev = &vg->pdev->dev; 16415fae8b86SMika Westerberg void __iomem *reg; 16425fae8b86SMika Westerberg u32 base, value; 164395f0972cSMika Westerberg int i; 164495f0972cSMika Westerberg 164595f0972cSMika Westerberg /* 164695f0972cSMika Westerberg * Clear interrupt triggers for all pins that are GPIOs and 164795f0972cSMika Westerberg * do not use direct IRQ mode. This will prevent spurious 164895f0972cSMika Westerberg * interrupts from misconfigured pins. 164995f0972cSMika Westerberg */ 165071e6ca61SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 165171e6ca61SCristina Ciocan unsigned int pin = vg->soc_data->pins[i].number; 165271e6ca61SCristina Ciocan 165371e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 165471e6ca61SCristina Ciocan if (!reg) { 165571e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 165671e6ca61SCristina Ciocan "Pin %i: could not retrieve conf0 register\n", 165771e6ca61SCristina Ciocan i); 165871e6ca61SCristina Ciocan continue; 165971e6ca61SCristina Ciocan } 166071e6ca61SCristina Ciocan 166171e6ca61SCristina Ciocan value = readl(reg); 166249c03096SAndy Shevchenko if (value & BYT_DIRECT_IRQ_EN) { 1663dc7b0387SThierry Reding clear_bit(i, gc->irq.valid_mask); 166449c03096SAndy Shevchenko dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i); 166549c03096SAndy Shevchenko } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { 166695f0972cSMika Westerberg byt_gpio_clear_triggering(vg, i); 166749c03096SAndy Shevchenko dev_dbg(dev, "disabling GPIO %d\n", i); 166895f0972cSMika Westerberg } 166995f0972cSMika Westerberg } 16705fae8b86SMika Westerberg 16715fae8b86SMika Westerberg /* clear interrupt status trigger registers */ 167271e6ca61SCristina Ciocan for (base = 0; base < vg->soc_data->npins; base += 32) { 1673c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 167471e6ca61SCristina Ciocan 167571e6ca61SCristina Ciocan if (!reg) { 167671e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 167771e6ca61SCristina Ciocan "Pin %i: could not retrieve irq status reg\n", 167871e6ca61SCristina Ciocan base); 167971e6ca61SCristina Ciocan continue; 168071e6ca61SCristina Ciocan } 168171e6ca61SCristina Ciocan 16825fae8b86SMika Westerberg writel(0xffffffff, reg); 16835fae8b86SMika Westerberg /* make sure trigger bits are cleared, if not then a pin 16845fae8b86SMika Westerberg might be misconfigured in bios */ 16855fae8b86SMika Westerberg value = readl(reg); 16865fae8b86SMika Westerberg if (value) 16875fae8b86SMika Westerberg dev_err(&vg->pdev->dev, 16885fae8b86SMika Westerberg "GPIO interrupt error, pins misconfigured\n"); 16895fae8b86SMika Westerberg } 16905fae8b86SMika Westerberg } 16915fae8b86SMika Westerberg 169271e6ca61SCristina Ciocan static int byt_gpio_probe(struct byt_gpio *vg) 16935fae8b86SMika Westerberg { 16945fae8b86SMika Westerberg struct gpio_chip *gc; 169571e6ca61SCristina Ciocan struct resource *irq_rc; 16965fae8b86SMika Westerberg int ret; 16975fae8b86SMika Westerberg 169871e6ca61SCristina Ciocan /* Set up gpio chip */ 169971e6ca61SCristina Ciocan vg->chip = byt_gpio_chip; 17005fae8b86SMika Westerberg gc = &vg->chip; 170171e6ca61SCristina Ciocan gc->label = dev_name(&vg->pdev->dev); 17025fae8b86SMika Westerberg gc->base = -1; 17035fae8b86SMika Westerberg gc->can_sleep = false; 170471e6ca61SCristina Ciocan gc->parent = &vg->pdev->dev; 170571e6ca61SCristina Ciocan gc->ngpio = vg->soc_data->npins; 1706dc7b0387SThierry Reding gc->irq.need_valid_mask = true; 17075fae8b86SMika Westerberg 1708fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP 170971e6ca61SCristina Ciocan vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, 1710fcc18debSMika Westerberg sizeof(*vg->saved_context), GFP_KERNEL); 1711fcc18debSMika Westerberg #endif 17120612413fSAndy Shevchenko ret = devm_gpiochip_add_data(&vg->pdev->dev, gc, vg); 17135fae8b86SMika Westerberg if (ret) { 171471e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n"); 17155fae8b86SMika Westerberg return ret; 17165fae8b86SMika Westerberg } 17175fae8b86SMika Westerberg 171871e6ca61SCristina Ciocan ret = gpiochip_add_pin_range(&vg->chip, dev_name(&vg->pdev->dev), 171971e6ca61SCristina Ciocan 0, 0, vg->soc_data->npins); 172071e6ca61SCristina Ciocan if (ret) { 172171e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed to add GPIO pin range\n"); 17220612413fSAndy Shevchenko return ret; 172371e6ca61SCristina Ciocan } 172471e6ca61SCristina Ciocan 17255fae8b86SMika Westerberg /* set up interrupts */ 172671e6ca61SCristina Ciocan irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0); 17275fae8b86SMika Westerberg if (irq_rc && irq_rc->start) { 17285fae8b86SMika Westerberg byt_gpio_irq_init_hw(vg); 17295fae8b86SMika Westerberg ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0, 17303ae02c14SAndy Shevchenko handle_bad_irq, IRQ_TYPE_NONE); 17315fae8b86SMika Westerberg if (ret) { 173271e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed to add irqchip\n"); 17330612413fSAndy Shevchenko return ret; 17345fae8b86SMika Westerberg } 17355fae8b86SMika Westerberg 17365fae8b86SMika Westerberg gpiochip_set_chained_irqchip(gc, &byt_irqchip, 17375fae8b86SMika Westerberg (unsigned)irq_rc->start, 17385fae8b86SMika Westerberg byt_gpio_irq_handler); 17395fae8b86SMika Westerberg } 17405fae8b86SMika Westerberg 174171e6ca61SCristina Ciocan return ret; 174271e6ca61SCristina Ciocan } 174371e6ca61SCristina Ciocan 174471e6ca61SCristina Ciocan static int byt_set_soc_data(struct byt_gpio *vg, 174571e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data) 174671e6ca61SCristina Ciocan { 174771e6ca61SCristina Ciocan int i; 174871e6ca61SCristina Ciocan 174971e6ca61SCristina Ciocan vg->soc_data = soc_data; 175071e6ca61SCristina Ciocan vg->communities_copy = devm_kcalloc(&vg->pdev->dev, 175171e6ca61SCristina Ciocan soc_data->ncommunities, 175271e6ca61SCristina Ciocan sizeof(*vg->communities_copy), 175371e6ca61SCristina Ciocan GFP_KERNEL); 175471e6ca61SCristina Ciocan if (!vg->communities_copy) 175571e6ca61SCristina Ciocan return -ENOMEM; 175671e6ca61SCristina Ciocan 175771e6ca61SCristina Ciocan for (i = 0; i < soc_data->ncommunities; i++) { 175871e6ca61SCristina Ciocan struct byt_community *comm = vg->communities_copy + i; 175971e6ca61SCristina Ciocan struct resource *mem_rc; 176071e6ca61SCristina Ciocan 176171e6ca61SCristina Ciocan *comm = vg->soc_data->communities[i]; 176271e6ca61SCristina Ciocan 176371e6ca61SCristina Ciocan mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0); 176471e6ca61SCristina Ciocan comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc); 176571e6ca61SCristina Ciocan if (IS_ERR(comm->reg_base)) 176671e6ca61SCristina Ciocan return PTR_ERR(comm->reg_base); 176771e6ca61SCristina Ciocan } 176871e6ca61SCristina Ciocan 176971e6ca61SCristina Ciocan return 0; 177071e6ca61SCristina Ciocan } 177171e6ca61SCristina Ciocan 177271e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = { 177371e6ca61SCristina Ciocan { "INT33B2", (kernel_ulong_t)byt_soc_data }, 177471e6ca61SCristina Ciocan { "INT33FC", (kernel_ulong_t)byt_soc_data }, 177571e6ca61SCristina Ciocan { } 177671e6ca61SCristina Ciocan }; 177771e6ca61SCristina Ciocan MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); 177871e6ca61SCristina Ciocan 177971e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev) 178071e6ca61SCristina Ciocan { 178171e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data = NULL; 178271e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data **soc_table; 178371e6ca61SCristina Ciocan const struct acpi_device_id *acpi_id; 178471e6ca61SCristina Ciocan struct acpi_device *acpi_dev; 178571e6ca61SCristina Ciocan struct byt_gpio *vg; 178671e6ca61SCristina Ciocan int i, ret; 178771e6ca61SCristina Ciocan 178871e6ca61SCristina Ciocan acpi_dev = ACPI_COMPANION(&pdev->dev); 178971e6ca61SCristina Ciocan if (!acpi_dev) 179071e6ca61SCristina Ciocan return -ENODEV; 179171e6ca61SCristina Ciocan 179271e6ca61SCristina Ciocan acpi_id = acpi_match_device(byt_gpio_acpi_match, &pdev->dev); 179371e6ca61SCristina Ciocan if (!acpi_id) 179471e6ca61SCristina Ciocan return -ENODEV; 179571e6ca61SCristina Ciocan 179671e6ca61SCristina Ciocan soc_table = (const struct byt_pinctrl_soc_data **)acpi_id->driver_data; 179771e6ca61SCristina Ciocan 179871e6ca61SCristina Ciocan for (i = 0; soc_table[i]; i++) { 179971e6ca61SCristina Ciocan if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) { 180071e6ca61SCristina Ciocan soc_data = soc_table[i]; 180171e6ca61SCristina Ciocan break; 180271e6ca61SCristina Ciocan } 180371e6ca61SCristina Ciocan } 180471e6ca61SCristina Ciocan 180571e6ca61SCristina Ciocan if (!soc_data) 180671e6ca61SCristina Ciocan return -ENODEV; 180771e6ca61SCristina Ciocan 180871e6ca61SCristina Ciocan vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL); 180971e6ca61SCristina Ciocan if (!vg) 181071e6ca61SCristina Ciocan return -ENOMEM; 181171e6ca61SCristina Ciocan 181271e6ca61SCristina Ciocan vg->pdev = pdev; 181371e6ca61SCristina Ciocan ret = byt_set_soc_data(vg, soc_data); 181471e6ca61SCristina Ciocan if (ret) { 181571e6ca61SCristina Ciocan dev_err(&pdev->dev, "failed to set soc data\n"); 181671e6ca61SCristina Ciocan return ret; 181771e6ca61SCristina Ciocan } 181871e6ca61SCristina Ciocan 181971e6ca61SCristina Ciocan vg->pctl_desc = byt_pinctrl_desc; 182071e6ca61SCristina Ciocan vg->pctl_desc.name = dev_name(&pdev->dev); 182171e6ca61SCristina Ciocan vg->pctl_desc.pins = vg->soc_data->pins; 182271e6ca61SCristina Ciocan vg->pctl_desc.npins = vg->soc_data->npins; 182371e6ca61SCristina Ciocan 18240612413fSAndy Shevchenko vg->pctl_dev = devm_pinctrl_register(&pdev->dev, &vg->pctl_desc, vg); 182571e6ca61SCristina Ciocan if (IS_ERR(vg->pctl_dev)) { 182671e6ca61SCristina Ciocan dev_err(&pdev->dev, "failed to register pinctrl driver\n"); 182771e6ca61SCristina Ciocan return PTR_ERR(vg->pctl_dev); 182871e6ca61SCristina Ciocan } 182971e6ca61SCristina Ciocan 1830a171bc51SVille Syrjälä raw_spin_lock_init(&vg->lock); 1831a171bc51SVille Syrjälä 183271e6ca61SCristina Ciocan ret = byt_gpio_probe(vg); 18330612413fSAndy Shevchenko if (ret) 183471e6ca61SCristina Ciocan return ret; 183571e6ca61SCristina Ciocan 183671e6ca61SCristina Ciocan platform_set_drvdata(pdev, vg); 183771e6ca61SCristina Ciocan pm_runtime_enable(&pdev->dev); 183871e6ca61SCristina Ciocan 183971e6ca61SCristina Ciocan return 0; 184071e6ca61SCristina Ciocan } 184171e6ca61SCristina Ciocan 1842fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP 1843fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev) 1844fcc18debSMika Westerberg { 1845fcc18debSMika Westerberg struct platform_device *pdev = to_platform_device(dev); 1846fcc18debSMika Westerberg struct byt_gpio *vg = platform_get_drvdata(pdev); 1847fcc18debSMika Westerberg int i; 1848fcc18debSMika Westerberg 184971e6ca61SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 1850fcc18debSMika Westerberg void __iomem *reg; 1851fcc18debSMika Westerberg u32 value; 185271e6ca61SCristina Ciocan unsigned int pin = vg->soc_data->pins[i].number; 1853fcc18debSMika Westerberg 185471e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 185571e6ca61SCristina Ciocan if (!reg) { 185671e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 185771e6ca61SCristina Ciocan "Pin %i: could not retrieve conf0 register\n", 185871e6ca61SCristina Ciocan i); 185971e6ca61SCristina Ciocan continue; 186071e6ca61SCristina Ciocan } 1861fcc18debSMika Westerberg value = readl(reg) & BYT_CONF0_RESTORE_MASK; 1862fcc18debSMika Westerberg vg->saved_context[i].conf0 = value; 1863fcc18debSMika Westerberg 186471e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 1865fcc18debSMika Westerberg value = readl(reg) & BYT_VAL_RESTORE_MASK; 1866fcc18debSMika Westerberg vg->saved_context[i].val = value; 1867fcc18debSMika Westerberg } 1868fcc18debSMika Westerberg 1869fcc18debSMika Westerberg return 0; 1870fcc18debSMika Westerberg } 1871fcc18debSMika Westerberg 1872fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev) 1873fcc18debSMika Westerberg { 1874fcc18debSMika Westerberg struct platform_device *pdev = to_platform_device(dev); 1875fcc18debSMika Westerberg struct byt_gpio *vg = platform_get_drvdata(pdev); 1876fcc18debSMika Westerberg int i; 1877fcc18debSMika Westerberg 187871e6ca61SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 1879fcc18debSMika Westerberg void __iomem *reg; 1880fcc18debSMika Westerberg u32 value; 188171e6ca61SCristina Ciocan unsigned int pin = vg->soc_data->pins[i].number; 1882fcc18debSMika Westerberg 188371e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 188471e6ca61SCristina Ciocan if (!reg) { 188571e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 188671e6ca61SCristina Ciocan "Pin %i: could not retrieve conf0 register\n", 188771e6ca61SCristina Ciocan i); 188871e6ca61SCristina Ciocan continue; 188971e6ca61SCristina Ciocan } 1890fcc18debSMika Westerberg value = readl(reg); 1891fcc18debSMika Westerberg if ((value & BYT_CONF0_RESTORE_MASK) != 1892fcc18debSMika Westerberg vg->saved_context[i].conf0) { 1893fcc18debSMika Westerberg value &= ~BYT_CONF0_RESTORE_MASK; 1894fcc18debSMika Westerberg value |= vg->saved_context[i].conf0; 1895fcc18debSMika Westerberg writel(value, reg); 1896fcc18debSMika Westerberg dev_info(dev, "restored pin %d conf0 %#08x", i, value); 1897fcc18debSMika Westerberg } 1898fcc18debSMika Westerberg 189971e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 1900fcc18debSMika Westerberg value = readl(reg); 1901fcc18debSMika Westerberg if ((value & BYT_VAL_RESTORE_MASK) != 1902fcc18debSMika Westerberg vg->saved_context[i].val) { 1903fcc18debSMika Westerberg u32 v; 1904fcc18debSMika Westerberg 1905fcc18debSMika Westerberg v = value & ~BYT_VAL_RESTORE_MASK; 1906fcc18debSMika Westerberg v |= vg->saved_context[i].val; 1907fcc18debSMika Westerberg if (v != value) { 1908fcc18debSMika Westerberg writel(v, reg); 1909fcc18debSMika Westerberg dev_dbg(dev, "restored pin %d val %#08x\n", 1910fcc18debSMika Westerberg i, v); 1911fcc18debSMika Westerberg } 1912fcc18debSMika Westerberg } 1913fcc18debSMika Westerberg } 1914fcc18debSMika Westerberg 1915fcc18debSMika Westerberg return 0; 1916fcc18debSMika Westerberg } 1917fcc18debSMika Westerberg #endif 1918fcc18debSMika Westerberg 1919ec879f12SMika Westerberg #ifdef CONFIG_PM 19205fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev) 19215fae8b86SMika Westerberg { 19225fae8b86SMika Westerberg return 0; 19235fae8b86SMika Westerberg } 19245fae8b86SMika Westerberg 19255fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev) 19265fae8b86SMika Westerberg { 19275fae8b86SMika Westerberg return 0; 19285fae8b86SMika Westerberg } 1929ec879f12SMika Westerberg #endif 19305fae8b86SMika Westerberg 19315fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = { 1932fcc18debSMika Westerberg SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) 1933fcc18debSMika Westerberg SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, 1934fcc18debSMika Westerberg NULL) 19355fae8b86SMika Westerberg }; 19365fae8b86SMika Westerberg 19375fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = { 193871e6ca61SCristina Ciocan .probe = byt_pinctrl_probe, 19395fae8b86SMika Westerberg .driver = { 19405fae8b86SMika Westerberg .name = "byt_gpio", 19415fae8b86SMika Westerberg .pm = &byt_gpio_pm_ops, 1942360943a8SPaul Gortmaker .suppress_bind_attrs = true, 1943360943a8SPaul Gortmaker 19445fae8b86SMika Westerberg .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match), 19455fae8b86SMika Westerberg }, 19465fae8b86SMika Westerberg }; 19475fae8b86SMika Westerberg 19485fae8b86SMika Westerberg static int __init byt_gpio_init(void) 19495fae8b86SMika Westerberg { 19505fae8b86SMika Westerberg return platform_driver_register(&byt_gpio_driver); 19515fae8b86SMika Westerberg } 19525fae8b86SMika Westerberg subsys_initcall(byt_gpio_init); 1953