15fae8b86SMika Westerberg /* 25fae8b86SMika Westerberg * Pinctrl GPIO driver for Intel Baytrail 35fae8b86SMika Westerberg * Copyright (c) 2012-2013, Intel Corporation. 45fae8b86SMika Westerberg * 55fae8b86SMika Westerberg * Author: Mathias Nyman <mathias.nyman@linux.intel.com> 65fae8b86SMika Westerberg * 75fae8b86SMika Westerberg * This program is free software; you can redistribute it and/or modify it 85fae8b86SMika Westerberg * under the terms and conditions of the GNU General Public License, 95fae8b86SMika Westerberg * version 2, as published by the Free Software Foundation. 105fae8b86SMika Westerberg * 115fae8b86SMika Westerberg * This program is distributed in the hope it will be useful, but WITHOUT 125fae8b86SMika Westerberg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 135fae8b86SMika Westerberg * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 145fae8b86SMika Westerberg * more details. 155fae8b86SMika Westerberg */ 165fae8b86SMika Westerberg 175fae8b86SMika Westerberg #include <linux/kernel.h> 185fae8b86SMika Westerberg #include <linux/init.h> 195fae8b86SMika Westerberg #include <linux/types.h> 205fae8b86SMika Westerberg #include <linux/bitops.h> 215fae8b86SMika Westerberg #include <linux/interrupt.h> 2286e3ef81SCristina Ciocan #include <linux/gpio.h> 23bf9a5c96SLinus Walleij #include <linux/gpio/driver.h> 245fae8b86SMika Westerberg #include <linux/acpi.h> 255fae8b86SMika Westerberg #include <linux/platform_device.h> 265fae8b86SMika Westerberg #include <linux/seq_file.h> 275fae8b86SMika Westerberg #include <linux/io.h> 285fae8b86SMika Westerberg #include <linux/pm_runtime.h> 295fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h> 30c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h> 31c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h> 32c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h> 335fae8b86SMika Westerberg 345fae8b86SMika Westerberg /* memory mapped register offsets */ 355fae8b86SMika Westerberg #define BYT_CONF0_REG 0x000 365fae8b86SMika Westerberg #define BYT_CONF1_REG 0x004 375fae8b86SMika Westerberg #define BYT_VAL_REG 0x008 385fae8b86SMika Westerberg #define BYT_DFT_REG 0x00c 395fae8b86SMika Westerberg #define BYT_INT_STAT_REG 0x800 40658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG 0x9d0 415fae8b86SMika Westerberg 425fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */ 435fae8b86SMika Westerberg #define BYT_IODEN BIT(31) 445fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN BIT(27) 455fae8b86SMika Westerberg #define BYT_TRIG_NEG BIT(26) 465fae8b86SMika Westerberg #define BYT_TRIG_POS BIT(25) 475fae8b86SMika Westerberg #define BYT_TRIG_LVL BIT(24) 48658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN BIT(20) 495fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT 9 505fae8b86SMika Westerberg #define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT) 515fae8b86SMika Westerberg #define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) 525fae8b86SMika Westerberg #define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT) 535fae8b86SMika Westerberg #define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT) 545fae8b86SMika Westerberg #define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT) 555fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_SHIFT 7 565fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_MASK (3 << BYT_PULL_ASSIGN_SHIFT) 575fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT) 585fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT) 595fae8b86SMika Westerberg #define BYT_PIN_MUX 0x07 605fae8b86SMika Westerberg 615fae8b86SMika Westerberg /* BYT_VAL_REG register bits */ 625fae8b86SMika Westerberg #define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ 635fae8b86SMika Westerberg #define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ 645fae8b86SMika Westerberg #define BYT_LEVEL BIT(0) 655fae8b86SMika Westerberg 665fae8b86SMika Westerberg #define BYT_DIR_MASK (BIT(1) | BIT(2)) 675fae8b86SMika Westerberg #define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24)) 685fae8b86SMika Westerberg 69fcc18debSMika Westerberg #define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \ 70fcc18debSMika Westerberg BYT_PIN_MUX) 71fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) 72fcc18debSMika Westerberg 73658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */ 74658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_MASK 0x7 75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US 1 76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US 2 77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US 3 78658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS 4 79658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS 5 80658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS 6 81658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS 7 82658b476cSCristina Ciocan 835fae8b86SMika Westerberg #define BYT_NGPIO_SCORE 102 845fae8b86SMika Westerberg #define BYT_NGPIO_NCORE 28 855fae8b86SMika Westerberg #define BYT_NGPIO_SUS 44 865fae8b86SMika Westerberg 875fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID "1" 885fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID "2" 895fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID "3" 905fae8b86SMika Westerberg 91c501d0b1SCristina Ciocan /* 92c501d0b1SCristina Ciocan * This is the function value most pins have for GPIO muxing. If the value 93c501d0b1SCristina Ciocan * differs from the default one, it must be explicitly mentioned. Otherwise, the 94c501d0b1SCristina Ciocan * pin control implementation will set the muxing value to default GPIO if it 95c501d0b1SCristina Ciocan * does not find a match for the requested function. 96c501d0b1SCristina Ciocan */ 97c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX 0 98c501d0b1SCristina Ciocan 99c8f5c4c7SCristina Ciocan struct byt_gpio_pin_context { 100c8f5c4c7SCristina Ciocan u32 conf0; 101c8f5c4c7SCristina Ciocan u32 val; 102c8f5c4c7SCristina Ciocan }; 1035fae8b86SMika Westerberg 104c8f5c4c7SCristina Ciocan struct byt_simple_func_mux { 105c8f5c4c7SCristina Ciocan const char *name; 106c8f5c4c7SCristina Ciocan unsigned short func; 107c8f5c4c7SCristina Ciocan }; 108c8f5c4c7SCristina Ciocan 109c8f5c4c7SCristina Ciocan struct byt_mixed_func_mux { 110c8f5c4c7SCristina Ciocan const char *name; 111c8f5c4c7SCristina Ciocan const unsigned short *func_values; 112c8f5c4c7SCristina Ciocan }; 113c8f5c4c7SCristina Ciocan 114c8f5c4c7SCristina Ciocan struct byt_pingroup { 115c8f5c4c7SCristina Ciocan const char *name; 116c8f5c4c7SCristina Ciocan const unsigned int *pins; 117c8f5c4c7SCristina Ciocan size_t npins; 118c8f5c4c7SCristina Ciocan unsigned short has_simple_funcs; 119c8f5c4c7SCristina Ciocan union { 120c8f5c4c7SCristina Ciocan const struct byt_simple_func_mux *simple_funcs; 121c8f5c4c7SCristina Ciocan const struct byt_mixed_func_mux *mixed_funcs; 122c8f5c4c7SCristina Ciocan }; 123c8f5c4c7SCristina Ciocan size_t nfuncs; 124c8f5c4c7SCristina Ciocan }; 125c8f5c4c7SCristina Ciocan 126c8f5c4c7SCristina Ciocan struct byt_function { 127c8f5c4c7SCristina Ciocan const char *name; 128c8f5c4c7SCristina Ciocan const char * const *groups; 129c8f5c4c7SCristina Ciocan size_t ngroups; 130c8f5c4c7SCristina Ciocan }; 131c8f5c4c7SCristina Ciocan 132c8f5c4c7SCristina Ciocan struct byt_community { 133c8f5c4c7SCristina Ciocan unsigned int pin_base; 134c8f5c4c7SCristina Ciocan size_t npins; 135c8f5c4c7SCristina Ciocan const unsigned int *pad_map; 136c8f5c4c7SCristina Ciocan void __iomem *reg_base; 137c8f5c4c7SCristina Ciocan }; 138c8f5c4c7SCristina Ciocan 139c8f5c4c7SCristina Ciocan #define SIMPLE_FUNC(n, f) \ 140c8f5c4c7SCristina Ciocan { \ 141c8f5c4c7SCristina Ciocan .name = (n), \ 142c8f5c4c7SCristina Ciocan .func = (f), \ 143c8f5c4c7SCristina Ciocan } 144c8f5c4c7SCristina Ciocan #define MIXED_FUNC(n, f) \ 145c8f5c4c7SCristina Ciocan { \ 146c8f5c4c7SCristina Ciocan .name = (n), \ 147c8f5c4c7SCristina Ciocan .func_values = (f), \ 148c8f5c4c7SCristina Ciocan } 149c8f5c4c7SCristina Ciocan 150c8f5c4c7SCristina Ciocan #define PIN_GROUP_SIMPLE(n, p, f) \ 151c8f5c4c7SCristina Ciocan { \ 152c8f5c4c7SCristina Ciocan .name = (n), \ 153c8f5c4c7SCristina Ciocan .pins = (p), \ 154c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE((p)), \ 155c8f5c4c7SCristina Ciocan .has_simple_funcs = 1, \ 156bbccb9c7SAndrew Morton { \ 157c8f5c4c7SCristina Ciocan .simple_funcs = (f), \ 158bbccb9c7SAndrew Morton }, \ 159c8f5c4c7SCristina Ciocan .nfuncs = ARRAY_SIZE((f)), \ 160c8f5c4c7SCristina Ciocan } 161c8f5c4c7SCristina Ciocan #define PIN_GROUP_MIXED(n, p, f) \ 162c8f5c4c7SCristina Ciocan { \ 163c8f5c4c7SCristina Ciocan .name = (n), \ 164c8f5c4c7SCristina Ciocan .pins = (p), \ 165c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE((p)), \ 166c8f5c4c7SCristina Ciocan .has_simple_funcs = 0, \ 167bbccb9c7SAndrew Morton { \ 168c8f5c4c7SCristina Ciocan .mixed_funcs = (f), \ 169bbccb9c7SAndrew Morton }, \ 170c8f5c4c7SCristina Ciocan .nfuncs = ARRAY_SIZE((f)), \ 171c8f5c4c7SCristina Ciocan } 172c8f5c4c7SCristina Ciocan 173c8f5c4c7SCristina Ciocan #define FUNCTION(n, g) \ 174c8f5c4c7SCristina Ciocan { \ 175c8f5c4c7SCristina Ciocan .name = (n), \ 176c8f5c4c7SCristina Ciocan .groups = (g), \ 177c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE((g)), \ 178c8f5c4c7SCristina Ciocan } 179c8f5c4c7SCristina Ciocan 180c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map) \ 181c8f5c4c7SCristina Ciocan { \ 182c8f5c4c7SCristina Ciocan .pin_base = (p), \ 183c8f5c4c7SCristina Ciocan .npins = (n), \ 184c8f5c4c7SCristina Ciocan .pad_map = (map),\ 185c8f5c4c7SCristina Ciocan } 186c8f5c4c7SCristina Ciocan 187c8f5c4c7SCristina Ciocan struct byt_pinctrl_soc_data { 188c8f5c4c7SCristina Ciocan const char *uid; 189c8f5c4c7SCristina Ciocan const struct pinctrl_pin_desc *pins; 190c8f5c4c7SCristina Ciocan size_t npins; 191c8f5c4c7SCristina Ciocan const struct byt_pingroup *groups; 192c8f5c4c7SCristina Ciocan size_t ngroups; 193c8f5c4c7SCristina Ciocan const struct byt_function *functions; 194c8f5c4c7SCristina Ciocan size_t nfunctions; 195c8f5c4c7SCristina Ciocan const struct byt_community *communities; 196c8f5c4c7SCristina Ciocan size_t ncommunities; 197c8f5c4c7SCristina Ciocan }; 198c8f5c4c7SCristina Ciocan 19971e6ca61SCristina Ciocan struct byt_gpio { 20071e6ca61SCristina Ciocan struct gpio_chip chip; 20171e6ca61SCristina Ciocan struct platform_device *pdev; 20271e6ca61SCristina Ciocan struct pinctrl_dev *pctl_dev; 20371e6ca61SCristina Ciocan struct pinctrl_desc pctl_desc; 20471e6ca61SCristina Ciocan raw_spinlock_t lock; 20571e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data; 20671e6ca61SCristina Ciocan struct byt_community *communities_copy; 20771e6ca61SCristina Ciocan struct byt_gpio_pin_context *saved_context; 20871e6ca61SCristina Ciocan }; 20971e6ca61SCristina Ciocan 210c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ 211c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = { 212c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "SATA_GP0"), 213c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "SATA_GP1"), 214c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "SATA_LED#"), 215c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "PCIE_CLKREQ0"), 216c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "PCIE_CLKREQ1"), 217c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "PCIE_CLKREQ2"), 218c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "PCIE_CLKREQ3"), 219c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "SD3_WP"), 220c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "HDA_RST"), 221c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "HDA_SYNC"), 222c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "HDA_CLK"), 223c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "HDA_SDO"), 224c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "HDA_SDI0"), 225c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "HDA_SDI1"), 226c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_S0_SC14"), 227c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_S0_SC15"), 228c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "MMC1_CLK"), 229c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "MMC1_D0"), 230c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "MMC1_D1"), 231c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "MMC1_D2"), 232c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "MMC1_D3"), 233c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "MMC1_D4"), 234c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "MMC1_D5"), 235c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "MMC1_D6"), 236c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "MMC1_D7"), 237c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "MMC1_CMD"), 238c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "MMC1_RST"), 239c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "SD2_CLK"), 240c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "SD2_D0"), 241c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "SD2_D1"), 242c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "SD2_D2"), 243c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "SD2_D3_CD"), 244c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "SD2_CMD"), 245c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "SD3_CLK"), 246c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "SD3_D0"), 247c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "SD3_D1"), 248c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "SD3_D2"), 249c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "SD3_D3"), 250c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "SD3_CD"), 251c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "SD3_CMD"), 252c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "SD3_1P8EN"), 253c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "SD3_PWREN#"), 254c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "ILB_LPC_AD0"), 255c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "ILB_LPC_AD1"), 256c8f5c4c7SCristina Ciocan PINCTRL_PIN(44, "ILB_LPC_AD2"), 257c8f5c4c7SCristina Ciocan PINCTRL_PIN(45, "ILB_LPC_AD3"), 258c8f5c4c7SCristina Ciocan PINCTRL_PIN(46, "ILB_LPC_FRAME"), 259c8f5c4c7SCristina Ciocan PINCTRL_PIN(47, "ILB_LPC_CLK0"), 260c8f5c4c7SCristina Ciocan PINCTRL_PIN(48, "ILB_LPC_CLK1"), 261c8f5c4c7SCristina Ciocan PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), 262c8f5c4c7SCristina Ciocan PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), 263c8f5c4c7SCristina Ciocan PINCTRL_PIN(51, "PCU_SMB_DATA"), 264c8f5c4c7SCristina Ciocan PINCTRL_PIN(52, "PCU_SMB_CLK"), 265c8f5c4c7SCristina Ciocan PINCTRL_PIN(53, "PCU_SMB_ALERT"), 266c8f5c4c7SCristina Ciocan PINCTRL_PIN(54, "ILB_8254_SPKR"), 267c8f5c4c7SCristina Ciocan PINCTRL_PIN(55, "GPIO_S0_SC55"), 268c8f5c4c7SCristina Ciocan PINCTRL_PIN(56, "GPIO_S0_SC56"), 269c8f5c4c7SCristina Ciocan PINCTRL_PIN(57, "GPIO_S0_SC57"), 270c8f5c4c7SCristina Ciocan PINCTRL_PIN(58, "GPIO_S0_SC58"), 271c8f5c4c7SCristina Ciocan PINCTRL_PIN(59, "GPIO_S0_SC59"), 272c8f5c4c7SCristina Ciocan PINCTRL_PIN(60, "GPIO_S0_SC60"), 273c8f5c4c7SCristina Ciocan PINCTRL_PIN(61, "GPIO_S0_SC61"), 274c8f5c4c7SCristina Ciocan PINCTRL_PIN(62, "LPE_I2S2_CLK"), 275c8f5c4c7SCristina Ciocan PINCTRL_PIN(63, "LPE_I2S2_FRM"), 276c8f5c4c7SCristina Ciocan PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), 277c8f5c4c7SCristina Ciocan PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), 278c8f5c4c7SCristina Ciocan PINCTRL_PIN(66, "SIO_SPI_CS"), 279c8f5c4c7SCristina Ciocan PINCTRL_PIN(67, "SIO_SPI_MISO"), 280c8f5c4c7SCristina Ciocan PINCTRL_PIN(68, "SIO_SPI_MOSI"), 281c8f5c4c7SCristina Ciocan PINCTRL_PIN(69, "SIO_SPI_CLK"), 282c8f5c4c7SCristina Ciocan PINCTRL_PIN(70, "SIO_UART1_RXD"), 283c8f5c4c7SCristina Ciocan PINCTRL_PIN(71, "SIO_UART1_TXD"), 284c8f5c4c7SCristina Ciocan PINCTRL_PIN(72, "SIO_UART1_RTS"), 285c8f5c4c7SCristina Ciocan PINCTRL_PIN(73, "SIO_UART1_CTS"), 286c8f5c4c7SCristina Ciocan PINCTRL_PIN(74, "SIO_UART2_RXD"), 287c8f5c4c7SCristina Ciocan PINCTRL_PIN(75, "SIO_UART2_TXD"), 288c8f5c4c7SCristina Ciocan PINCTRL_PIN(76, "SIO_UART2_RTS"), 289c8f5c4c7SCristina Ciocan PINCTRL_PIN(77, "SIO_UART2_CTS"), 290c8f5c4c7SCristina Ciocan PINCTRL_PIN(78, "SIO_I2C0_DATA"), 291c8f5c4c7SCristina Ciocan PINCTRL_PIN(79, "SIO_I2C0_CLK"), 292c8f5c4c7SCristina Ciocan PINCTRL_PIN(80, "SIO_I2C1_DATA"), 293c8f5c4c7SCristina Ciocan PINCTRL_PIN(81, "SIO_I2C1_CLK"), 294c8f5c4c7SCristina Ciocan PINCTRL_PIN(82, "SIO_I2C2_DATA"), 295c8f5c4c7SCristina Ciocan PINCTRL_PIN(83, "SIO_I2C2_CLK"), 296c8f5c4c7SCristina Ciocan PINCTRL_PIN(84, "SIO_I2C3_DATA"), 297c8f5c4c7SCristina Ciocan PINCTRL_PIN(85, "SIO_I2C3_CLK"), 298c8f5c4c7SCristina Ciocan PINCTRL_PIN(86, "SIO_I2C4_DATA"), 299c8f5c4c7SCristina Ciocan PINCTRL_PIN(87, "SIO_I2C4_CLK"), 300c8f5c4c7SCristina Ciocan PINCTRL_PIN(88, "SIO_I2C5_DATA"), 301c8f5c4c7SCristina Ciocan PINCTRL_PIN(89, "SIO_I2C5_CLK"), 302c8f5c4c7SCristina Ciocan PINCTRL_PIN(90, "SIO_I2C6_DATA"), 303c8f5c4c7SCristina Ciocan PINCTRL_PIN(91, "SIO_I2C6_CLK"), 304c8f5c4c7SCristina Ciocan PINCTRL_PIN(92, "GPIO_S0_SC92"), 305c8f5c4c7SCristina Ciocan PINCTRL_PIN(93, "GPIO_S0_SC93"), 306c8f5c4c7SCristina Ciocan PINCTRL_PIN(94, "SIO_PWM0"), 307c8f5c4c7SCristina Ciocan PINCTRL_PIN(95, "SIO_PWM1"), 308c8f5c4c7SCristina Ciocan PINCTRL_PIN(96, "PMC_PLT_CLK0"), 309c8f5c4c7SCristina Ciocan PINCTRL_PIN(97, "PMC_PLT_CLK1"), 310c8f5c4c7SCristina Ciocan PINCTRL_PIN(98, "PMC_PLT_CLK2"), 311c8f5c4c7SCristina Ciocan PINCTRL_PIN(99, "PMC_PLT_CLK3"), 312c8f5c4c7SCristina Ciocan PINCTRL_PIN(100, "PMC_PLT_CLK4"), 313c8f5c4c7SCristina Ciocan PINCTRL_PIN(101, "PMC_PLT_CLK5"), 314c8f5c4c7SCristina Ciocan }; 3155fae8b86SMika Westerberg 316c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { 317c8f5c4c7SCristina Ciocan 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 318c8f5c4c7SCristina Ciocan 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, 319c8f5c4c7SCristina Ciocan 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, 320c8f5c4c7SCristina Ciocan 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 321c8f5c4c7SCristina Ciocan 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, 322c8f5c4c7SCristina Ciocan 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, 323c8f5c4c7SCristina Ciocan 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 324c8f5c4c7SCristina Ciocan 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, 325c8f5c4c7SCristina Ciocan 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 326c8f5c4c7SCristina Ciocan 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, 327c8f5c4c7SCristina Ciocan 97, 100, 3285fae8b86SMika Westerberg }; 3295fae8b86SMika Westerberg 330c8f5c4c7SCristina Ciocan /* SCORE groups */ 331c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; 332c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; 333c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_uart_mux[] = { 334c8f5c4c7SCristina Ciocan SIMPLE_FUNC("uart", 1), 335c8f5c4c7SCristina Ciocan }; 336c8f5c4c7SCristina Ciocan 337c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 }; 338c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 }; 339c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_pwm_mux[] = { 340c8f5c4c7SCristina Ciocan SIMPLE_FUNC("pwm", 1), 341c8f5c4c7SCristina Ciocan }; 342c8f5c4c7SCristina Ciocan 343c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; 344c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_spi_mux[] = { 345c8f5c4c7SCristina Ciocan SIMPLE_FUNC("spi", 1), 346c8f5c4c7SCristina Ciocan }; 347c8f5c4c7SCristina Ciocan 348c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; 349c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; 350c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; 351c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; 352c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; 353c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; 354c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; 355c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_i2c_mux[] = { 356c8f5c4c7SCristina Ciocan SIMPLE_FUNC("i2c", 1), 357c8f5c4c7SCristina Ciocan }; 358c8f5c4c7SCristina Ciocan 359c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; 360c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; 361c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; 362c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_ssp_mux[] = { 363c8f5c4c7SCristina Ciocan SIMPLE_FUNC("ssp", 1), 364c8f5c4c7SCristina Ciocan }; 365c8f5c4c7SCristina Ciocan 366c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = { 367c8f5c4c7SCristina Ciocan 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 368c8f5c4c7SCristina Ciocan }; 369c8f5c4c7SCristina Ciocan static const unsigned short byt_score_sdcard_mux_values[] = { 370c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 371c8f5c4c7SCristina Ciocan }; 372c8f5c4c7SCristina Ciocan static const struct byt_mixed_func_mux byt_score_sdcard_mux[] = { 373c8f5c4c7SCristina Ciocan MIXED_FUNC("sdcard", byt_score_sdcard_mux_values), 374c8f5c4c7SCristina Ciocan }; 375c8f5c4c7SCristina Ciocan 376c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; 377c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_sdio_mux[] = { 378c8f5c4c7SCristina Ciocan SIMPLE_FUNC("sdio", 1), 379c8f5c4c7SCristina Ciocan }; 380c8f5c4c7SCristina Ciocan 381c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = { 382c8f5c4c7SCristina Ciocan 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 383c8f5c4c7SCristina Ciocan }; 384c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_emmc_mux[] = { 385c8f5c4c7SCristina Ciocan SIMPLE_FUNC("emmc", 1), 386c8f5c4c7SCristina Ciocan }; 387c8f5c4c7SCristina Ciocan 388c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = { 389c8f5c4c7SCristina Ciocan 42, 43, 44, 45, 46, 47, 48, 49, 50, 390c8f5c4c7SCristina Ciocan }; 391c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_lpc_mux[] = { 392c8f5c4c7SCristina Ciocan SIMPLE_FUNC("lpc", 1), 393c8f5c4c7SCristina Ciocan }; 394c8f5c4c7SCristina Ciocan 395c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; 396c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_sata_mux[] = { 397c8f5c4c7SCristina Ciocan SIMPLE_FUNC("sata", 1), 398c8f5c4c7SCristina Ciocan }; 399c8f5c4c7SCristina Ciocan 400c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 }; 401c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 }; 402c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 }; 403b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 99 }; 404b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 100 }; 405b41aa4f8SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 101 }; 406c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_plt_clk_mux[] = { 407c8f5c4c7SCristina Ciocan SIMPLE_FUNC("plt_clk", 1), 408c8f5c4c7SCristina Ciocan }; 409c8f5c4c7SCristina Ciocan 410c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; 411c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_smbus_mux[] = { 412c8f5c4c7SCristina Ciocan SIMPLE_FUNC("smbus", 1), 413c8f5c4c7SCristina Ciocan }; 414c8f5c4c7SCristina Ciocan 415c8f5c4c7SCristina Ciocan static const struct byt_pingroup byt_score_groups[] = { 416c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("uart1_grp", 417c8f5c4c7SCristina Ciocan byt_score_uart1_pins, byt_score_uart_mux), 418c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("uart2_grp", 419c8f5c4c7SCristina Ciocan byt_score_uart2_pins, byt_score_uart_mux), 420c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pwm0_grp", 421c8f5c4c7SCristina Ciocan byt_score_pwm0_pins, byt_score_pwm_mux), 422c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pwm1_grp", 423c8f5c4c7SCristina Ciocan byt_score_pwm1_pins, byt_score_pwm_mux), 424c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp2_grp", 425c8f5c4c7SCristina Ciocan byt_score_ssp2_pins, byt_score_pwm_mux), 426c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sio_spi_grp", 427c8f5c4c7SCristina Ciocan byt_score_sio_spi_pins, byt_score_spi_mux), 428c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c5_grp", 429c8f5c4c7SCristina Ciocan byt_score_i2c5_pins, byt_score_i2c_mux), 430c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c6_grp", 431c8f5c4c7SCristina Ciocan byt_score_i2c6_pins, byt_score_i2c_mux), 432c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c4_grp", 433c8f5c4c7SCristina Ciocan byt_score_i2c4_pins, byt_score_i2c_mux), 434c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c3_grp", 435c8f5c4c7SCristina Ciocan byt_score_i2c3_pins, byt_score_i2c_mux), 436c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c2_grp", 437c8f5c4c7SCristina Ciocan byt_score_i2c2_pins, byt_score_i2c_mux), 438c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c1_grp", 439c8f5c4c7SCristina Ciocan byt_score_i2c1_pins, byt_score_i2c_mux), 440c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c0_grp", 441c8f5c4c7SCristina Ciocan byt_score_i2c0_pins, byt_score_i2c_mux), 442c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp0_grp", 443c8f5c4c7SCristina Ciocan byt_score_ssp0_pins, byt_score_ssp_mux), 444c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp1_grp", 445c8f5c4c7SCristina Ciocan byt_score_ssp1_pins, byt_score_ssp_mux), 446c8f5c4c7SCristina Ciocan PIN_GROUP_MIXED("sdcard_grp", 447c8f5c4c7SCristina Ciocan byt_score_sdcard_pins, byt_score_sdcard_mux), 448c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sdio_grp", 449c8f5c4c7SCristina Ciocan byt_score_sdio_pins, byt_score_sdio_mux), 450c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("emmc_grp", 451c8f5c4c7SCristina Ciocan byt_score_emmc_pins, byt_score_emmc_mux), 452c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("lpc_grp", 453c8f5c4c7SCristina Ciocan byt_score_ilb_lpc_pins, byt_score_lpc_mux), 454c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sata_grp", 455c8f5c4c7SCristina Ciocan byt_score_sata_pins, byt_score_sata_mux), 456c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk0_grp", 457c8f5c4c7SCristina Ciocan byt_score_plt_clk0_pins, byt_score_plt_clk_mux), 458c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk1_grp", 459c8f5c4c7SCristina Ciocan byt_score_plt_clk1_pins, byt_score_plt_clk_mux), 460c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk2_grp", 461c8f5c4c7SCristina Ciocan byt_score_plt_clk2_pins, byt_score_plt_clk_mux), 462c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk3_grp", 463c8f5c4c7SCristina Ciocan byt_score_plt_clk3_pins, byt_score_plt_clk_mux), 464c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk4_grp", 465c8f5c4c7SCristina Ciocan byt_score_plt_clk4_pins, byt_score_plt_clk_mux), 466c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk5_grp", 467c8f5c4c7SCristina Ciocan byt_score_plt_clk5_pins, byt_score_plt_clk_mux), 468c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("smbus_grp", 469c8f5c4c7SCristina Ciocan byt_score_smbus_pins, byt_score_smbus_mux), 470c8f5c4c7SCristina Ciocan }; 471c8f5c4c7SCristina Ciocan 472c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = { 473c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", 474c8f5c4c7SCristina Ciocan }; 475c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = { 476c8f5c4c7SCristina Ciocan "pwm0_grp", "pwm1_grp", 477c8f5c4c7SCristina Ciocan }; 478c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = { 479c8f5c4c7SCristina Ciocan "ssp0_grp", "ssp1_grp", "ssp2_grp", 480c8f5c4c7SCristina Ciocan }; 481c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; 482c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = { 483c8f5c4c7SCristina Ciocan "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", 484c8f5c4c7SCristina Ciocan "i2c6_grp", 485c8f5c4c7SCristina Ciocan }; 486c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; 487c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" }; 488c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" }; 489c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" }; 490c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" }; 491c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = { 492c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 493c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", 494c8f5c4c7SCristina Ciocan }; 495c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" }; 496c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = { 497c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", 498c8f5c4c7SCristina Ciocan "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", 499c8f5c4c7SCristina Ciocan "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", 500c8f5c4c7SCristina Ciocan "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", 501c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 502c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", 503c8f5c4c7SCristina Ciocan 504c8f5c4c7SCristina Ciocan }; 505c8f5c4c7SCristina Ciocan 506c8f5c4c7SCristina Ciocan static const struct byt_function byt_score_functions[] = { 507c8f5c4c7SCristina Ciocan FUNCTION("uart", byt_score_uart_groups), 508c8f5c4c7SCristina Ciocan FUNCTION("pwm", byt_score_pwm_groups), 509c8f5c4c7SCristina Ciocan FUNCTION("ssp", byt_score_ssp_groups), 510c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_score_spi_groups), 511c8f5c4c7SCristina Ciocan FUNCTION("i2c", byt_score_i2c_groups), 512c8f5c4c7SCristina Ciocan FUNCTION("sdcard", byt_score_sdcard_groups), 513c8f5c4c7SCristina Ciocan FUNCTION("sdio", byt_score_sdio_groups), 514c8f5c4c7SCristina Ciocan FUNCTION("emmc", byt_score_emmc_groups), 515c8f5c4c7SCristina Ciocan FUNCTION("lpc", byt_score_lpc_groups), 516c8f5c4c7SCristina Ciocan FUNCTION("sata", byt_score_sata_groups), 517c8f5c4c7SCristina Ciocan FUNCTION("plt_clk", byt_score_plt_clk_groups), 518c8f5c4c7SCristina Ciocan FUNCTION("smbus", byt_score_smbus_groups), 519c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_score_gpio_groups), 520c8f5c4c7SCristina Ciocan }; 521c8f5c4c7SCristina Ciocan 522c8f5c4c7SCristina Ciocan static const struct byt_community byt_score_communities[] = { 523c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), 524c8f5c4c7SCristina Ciocan }; 525c8f5c4c7SCristina Ciocan 526c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_score_soc_data = { 527c8f5c4c7SCristina Ciocan .uid = BYT_SCORE_ACPI_UID, 528c8f5c4c7SCristina Ciocan .pins = byt_score_pins, 529c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_score_pins), 530c8f5c4c7SCristina Ciocan .groups = byt_score_groups, 531c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_score_groups), 532c8f5c4c7SCristina Ciocan .functions = byt_score_functions, 533c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_score_functions), 534c8f5c4c7SCristina Ciocan .communities = byt_score_communities, 535c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_score_communities), 536c8f5c4c7SCristina Ciocan }; 537c8f5c4c7SCristina Ciocan 538c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */ 539c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = { 540c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_S50"), 541c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_S51"), 542c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_S52"), 543c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_S53"), 544c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_S54"), 545c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_S55"), 546c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_S56"), 547c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_S57"), 548c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_S58"), 549c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_S59"), 550c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_S510"), 551c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), 552c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "PMC_SUSCLK0"), 553c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_S513"), 554c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "USB_ULPI_RST"), 555c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), 556c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "PMC_PWRBTN"), 557c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_S517"), 558c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "PMC_SUS_STAT"), 559c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "USB_OC0"), 560c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "USB_OC1"), 561c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "PCU_SPI_CS1"), 562c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_S522"), 563c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_S523"), 564c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_S524"), 565c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_S525"), 566c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_S526"), 567c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_S527"), 568c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "GPIO_S528"), 569c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "GPIO_S529"), 570c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "GPIO_S530"), 571c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "USB_ULPI_CLK"), 572c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "USB_ULPI_DATA0"), 573c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "USB_ULPI_DATA1"), 574c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "USB_ULPI_DATA2"), 575c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "USB_ULPI_DATA3"), 576c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "USB_ULPI_DATA4"), 577c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "USB_ULPI_DATA5"), 578c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "USB_ULPI_DATA6"), 579c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "USB_ULPI_DATA7"), 580c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "USB_ULPI_DIR"), 581c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "USB_ULPI_NXT"), 582c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "USB_ULPI_STP"), 583c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "USB_ULPI_REFCLK"), 584c8f5c4c7SCristina Ciocan }; 585c8f5c4c7SCristina Ciocan 586c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 587c8f5c4c7SCristina Ciocan 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 588c8f5c4c7SCristina Ciocan 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, 589c8f5c4c7SCristina Ciocan 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 590c8f5c4c7SCristina Ciocan 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, 591c8f5c4c7SCristina Ciocan 52, 53, 59, 40, 592c8f5c4c7SCristina Ciocan }; 593c8f5c4c7SCristina Ciocan 594c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; 595c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_sus_usb_oc_mux[] = { 596c8f5c4c7SCristina Ciocan SIMPLE_FUNC("usb", 0), 597c8f5c4c7SCristina Ciocan SIMPLE_FUNC("gpio", 1), 598c8f5c4c7SCristina Ciocan }; 599c8f5c4c7SCristina Ciocan 600c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = { 601c8f5c4c7SCristina Ciocan 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 602c8f5c4c7SCristina Ciocan }; 603c8f5c4c7SCristina Ciocan static const unsigned short byt_sus_usb_ulpi_mode_values[] = { 604c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 605c8f5c4c7SCristina Ciocan }; 606c8f5c4c7SCristina Ciocan static const unsigned short byt_sus_usb_ulpi_gpio_mode_values[] = { 607c8f5c4c7SCristina Ciocan 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 608c8f5c4c7SCristina Ciocan }; 609c8f5c4c7SCristina Ciocan static const struct byt_mixed_func_mux byt_sus_usb_ulpi_mux[] = { 610c8f5c4c7SCristina Ciocan MIXED_FUNC("usb", byt_sus_usb_ulpi_mode_values), 611c8f5c4c7SCristina Ciocan MIXED_FUNC("gpio", byt_sus_usb_ulpi_gpio_mode_values), 612c8f5c4c7SCristina Ciocan }; 613c8f5c4c7SCristina Ciocan 614c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; 615c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_sus_pcu_spi_mux[] = { 616c8f5c4c7SCristina Ciocan SIMPLE_FUNC("spi", 0), 617c8f5c4c7SCristina Ciocan SIMPLE_FUNC("gpio", 1), 618c8f5c4c7SCristina Ciocan }; 619c8f5c4c7SCristina Ciocan 620c8f5c4c7SCristina Ciocan static const struct byt_pingroup byt_sus_groups[] = { 621c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("usb_oc_grp", 622c8f5c4c7SCristina Ciocan byt_sus_usb_over_current_pins, byt_sus_usb_oc_mux), 623c8f5c4c7SCristina Ciocan PIN_GROUP_MIXED("usb_ulpi_grp", 624c8f5c4c7SCristina Ciocan byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mux), 625c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pcu_spi_grp", 626c8f5c4c7SCristina Ciocan byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mux), 627c8f5c4c7SCristina Ciocan }; 628c8f5c4c7SCristina Ciocan 629c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = { 630c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp", 631c8f5c4c7SCristina Ciocan }; 632c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; 633c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = { 634c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp", "pcu_spi_grp", 635c8f5c4c7SCristina Ciocan }; 636c8f5c4c7SCristina Ciocan 637c8f5c4c7SCristina Ciocan static const struct byt_function byt_sus_functions[] = { 638c8f5c4c7SCristina Ciocan FUNCTION("usb", byt_sus_usb_groups), 639c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_sus_spi_groups), 640c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_sus_gpio_groups), 641c8f5c4c7SCristina Ciocan }; 642c8f5c4c7SCristina Ciocan 643c8f5c4c7SCristina Ciocan static const struct byt_community byt_sus_communities[] = { 644c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), 645c8f5c4c7SCristina Ciocan }; 646c8f5c4c7SCristina Ciocan 647c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_sus_soc_data = { 648c8f5c4c7SCristina Ciocan .uid = BYT_SUS_ACPI_UID, 649c8f5c4c7SCristina Ciocan .pins = byt_sus_pins, 650c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_sus_pins), 651c8f5c4c7SCristina Ciocan .groups = byt_sus_groups, 652c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_sus_groups), 653c8f5c4c7SCristina Ciocan .functions = byt_sus_functions, 654c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_sus_functions), 655c8f5c4c7SCristina Ciocan .communities = byt_sus_communities, 656c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_sus_communities), 657c8f5c4c7SCristina Ciocan }; 658c8f5c4c7SCristina Ciocan 659c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = { 660c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_NCORE0"), 661c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_NCORE1"), 662c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_NCORE2"), 663c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_NCORE3"), 664c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_NCORE4"), 665c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_NCORE5"), 666c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_NCORE6"), 667c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_NCORE7"), 668c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_NCORE8"), 669c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_NCORE9"), 670c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_NCORE10"), 671c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "GPIO_NCORE11"), 672c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "GPIO_NCORE12"), 673c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_NCORE13"), 674c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_NCORE14"), 675c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_NCORE15"), 676c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "GPIO_NCORE16"), 677c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_NCORE17"), 678c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "GPIO_NCORE18"), 679c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "GPIO_NCORE19"), 680c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "GPIO_NCORE20"), 681c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "GPIO_NCORE21"), 682c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_NCORE22"), 683c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_NCORE23"), 684c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_NCORE24"), 685c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_NCORE25"), 686c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_NCORE26"), 687c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_NCORE27"), 688c8f5c4c7SCristina Ciocan }; 689c8f5c4c7SCristina Ciocan 690c8f5c4c7SCristina Ciocan static unsigned const byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 691c8f5c4c7SCristina Ciocan 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 692c8f5c4c7SCristina Ciocan 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, 693c8f5c4c7SCristina Ciocan 3, 6, 10, 13, 2, 5, 9, 7, 694c8f5c4c7SCristina Ciocan }; 695c8f5c4c7SCristina Ciocan 696c8f5c4c7SCristina Ciocan static const struct byt_community byt_ncore_communities[] = { 697c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), 698c8f5c4c7SCristina Ciocan }; 699c8f5c4c7SCristina Ciocan 700c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_ncore_soc_data = { 701c8f5c4c7SCristina Ciocan .uid = BYT_NCORE_ACPI_UID, 702c8f5c4c7SCristina Ciocan .pins = byt_ncore_pins, 703c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_ncore_pins), 704c8f5c4c7SCristina Ciocan .communities = byt_ncore_communities, 705c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_ncore_communities), 706c8f5c4c7SCristina Ciocan }; 707c8f5c4c7SCristina Ciocan 708c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data *byt_soc_data[] = { 709c8f5c4c7SCristina Ciocan &byt_score_soc_data, 710c8f5c4c7SCristina Ciocan &byt_sus_soc_data, 711c8f5c4c7SCristina Ciocan &byt_ncore_soc_data, 712c8f5c4c7SCristina Ciocan NULL, 713c8f5c4c7SCristina Ciocan }; 714c8f5c4c7SCristina Ciocan 715c501d0b1SCristina Ciocan static struct byt_community *byt_get_community(struct byt_gpio *vg, 716c501d0b1SCristina Ciocan unsigned int pin) 717c501d0b1SCristina Ciocan { 718c501d0b1SCristina Ciocan struct byt_community *comm; 719c501d0b1SCristina Ciocan int i; 720c501d0b1SCristina Ciocan 721c501d0b1SCristina Ciocan for (i = 0; i < vg->soc_data->ncommunities; i++) { 722c501d0b1SCristina Ciocan comm = vg->communities_copy + i; 723c501d0b1SCristina Ciocan if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) 724c501d0b1SCristina Ciocan return comm; 725c501d0b1SCristina Ciocan } 726c501d0b1SCristina Ciocan 727c501d0b1SCristina Ciocan return NULL; 728c501d0b1SCristina Ciocan } 729c501d0b1SCristina Ciocan 730c501d0b1SCristina Ciocan static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, 7315fae8b86SMika Westerberg int reg) 7325fae8b86SMika Westerberg { 733c501d0b1SCristina Ciocan struct byt_community *comm = byt_get_community(vg, offset); 7341b89970dSAndy Shevchenko u32 reg_offset; 7355fae8b86SMika Westerberg 736c501d0b1SCristina Ciocan if (!comm) 737c501d0b1SCristina Ciocan return NULL; 738c501d0b1SCristina Ciocan 739c501d0b1SCristina Ciocan offset -= comm->pin_base; 7401b89970dSAndy Shevchenko switch (reg) { 7411b89970dSAndy Shevchenko case BYT_INT_STAT_REG: 7425fae8b86SMika Westerberg reg_offset = (offset / 32) * 4; 7431b89970dSAndy Shevchenko break; 7441b89970dSAndy Shevchenko case BYT_DEBOUNCE_REG: 7451b89970dSAndy Shevchenko reg_offset = 0; 7461b89970dSAndy Shevchenko break; 7471b89970dSAndy Shevchenko default: 748c501d0b1SCristina Ciocan reg_offset = comm->pad_map[offset] * 16; 7491b89970dSAndy Shevchenko break; 7501b89970dSAndy Shevchenko } 7515fae8b86SMika Westerberg 752c501d0b1SCristina Ciocan return comm->reg_base + reg_offset + reg; 7535fae8b86SMika Westerberg } 7545fae8b86SMika Westerberg 755c501d0b1SCristina Ciocan static int byt_get_groups_count(struct pinctrl_dev *pctldev) 75695f0972cSMika Westerberg { 757c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 758c501d0b1SCristina Ciocan 759c501d0b1SCristina Ciocan return vg->soc_data->ngroups; 760c501d0b1SCristina Ciocan } 761c501d0b1SCristina Ciocan 762c501d0b1SCristina Ciocan static const char *byt_get_group_name(struct pinctrl_dev *pctldev, 763c501d0b1SCristina Ciocan unsigned int selector) 764c501d0b1SCristina Ciocan { 765c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 766c501d0b1SCristina Ciocan 767c501d0b1SCristina Ciocan return vg->soc_data->groups[selector].name; 768c501d0b1SCristina Ciocan } 769c501d0b1SCristina Ciocan 770c501d0b1SCristina Ciocan static int byt_get_group_pins(struct pinctrl_dev *pctldev, 771c501d0b1SCristina Ciocan unsigned int selector, 772c501d0b1SCristina Ciocan const unsigned int **pins, 773c501d0b1SCristina Ciocan unsigned int *num_pins) 774c501d0b1SCristina Ciocan { 775c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 776c501d0b1SCristina Ciocan 777c501d0b1SCristina Ciocan *pins = vg->soc_data->groups[selector].pins; 778c501d0b1SCristina Ciocan *num_pins = vg->soc_data->groups[selector].npins; 779c501d0b1SCristina Ciocan 780c501d0b1SCristina Ciocan return 0; 781c501d0b1SCristina Ciocan } 782c501d0b1SCristina Ciocan 783c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = { 784c501d0b1SCristina Ciocan .get_groups_count = byt_get_groups_count, 785c501d0b1SCristina Ciocan .get_group_name = byt_get_group_name, 786c501d0b1SCristina Ciocan .get_group_pins = byt_get_group_pins, 787c501d0b1SCristina Ciocan }; 788c501d0b1SCristina Ciocan 789c501d0b1SCristina Ciocan static int byt_get_functions_count(struct pinctrl_dev *pctldev) 790c501d0b1SCristina Ciocan { 791c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 792c501d0b1SCristina Ciocan 793c501d0b1SCristina Ciocan return vg->soc_data->nfunctions; 794c501d0b1SCristina Ciocan } 795c501d0b1SCristina Ciocan 796c501d0b1SCristina Ciocan static const char *byt_get_function_name(struct pinctrl_dev *pctldev, 797c501d0b1SCristina Ciocan unsigned int selector) 798c501d0b1SCristina Ciocan { 799c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 800c501d0b1SCristina Ciocan 801c501d0b1SCristina Ciocan return vg->soc_data->functions[selector].name; 802c501d0b1SCristina Ciocan } 803c501d0b1SCristina Ciocan 804c501d0b1SCristina Ciocan static int byt_get_function_groups(struct pinctrl_dev *pctldev, 805c501d0b1SCristina Ciocan unsigned int selector, 806c501d0b1SCristina Ciocan const char * const **groups, 807c501d0b1SCristina Ciocan unsigned int *num_groups) 808c501d0b1SCristina Ciocan { 809c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 810c501d0b1SCristina Ciocan 811c501d0b1SCristina Ciocan *groups = vg->soc_data->functions[selector].groups; 812c501d0b1SCristina Ciocan *num_groups = vg->soc_data->functions[selector].ngroups; 813c501d0b1SCristina Ciocan 814c501d0b1SCristina Ciocan return 0; 815c501d0b1SCristina Ciocan } 816c501d0b1SCristina Ciocan 817c501d0b1SCristina Ciocan static int byt_get_group_simple_mux(const struct byt_pingroup group, 818c501d0b1SCristina Ciocan const char *func_name, 819c501d0b1SCristina Ciocan unsigned short *func) 820c501d0b1SCristina Ciocan { 821c501d0b1SCristina Ciocan int i; 822c501d0b1SCristina Ciocan 823c501d0b1SCristina Ciocan for (i = 0; i < group.nfuncs; i++) { 824c501d0b1SCristina Ciocan if (!strcmp(group.simple_funcs[i].name, func_name)) { 825c501d0b1SCristina Ciocan *func = group.simple_funcs[i].func; 826c501d0b1SCristina Ciocan return 0; 827c501d0b1SCristina Ciocan } 828c501d0b1SCristina Ciocan } 829c501d0b1SCristina Ciocan 830c501d0b1SCristina Ciocan return 1; 831c501d0b1SCristina Ciocan } 832c501d0b1SCristina Ciocan 833c501d0b1SCristina Ciocan static int byt_get_group_mixed_mux(const struct byt_pingroup group, 834c501d0b1SCristina Ciocan const char *func_name, 835c501d0b1SCristina Ciocan const unsigned short **func) 836c501d0b1SCristina Ciocan { 837c501d0b1SCristina Ciocan int i; 838c501d0b1SCristina Ciocan 839c501d0b1SCristina Ciocan for (i = 0; i < group.nfuncs; i++) { 840c501d0b1SCristina Ciocan if (!strcmp(group.mixed_funcs[i].name, func_name)) { 841c501d0b1SCristina Ciocan *func = group.mixed_funcs[i].func_values; 842c501d0b1SCristina Ciocan return 0; 843c501d0b1SCristina Ciocan } 844c501d0b1SCristina Ciocan } 845c501d0b1SCristina Ciocan 846c501d0b1SCristina Ciocan return 1; 847c501d0b1SCristina Ciocan } 848c501d0b1SCristina Ciocan 849c501d0b1SCristina Ciocan static void byt_set_group_simple_mux(struct byt_gpio *vg, 850c501d0b1SCristina Ciocan const struct byt_pingroup group, 851c501d0b1SCristina Ciocan unsigned short func) 852c501d0b1SCristina Ciocan { 853c501d0b1SCristina Ciocan unsigned long flags; 854c501d0b1SCristina Ciocan int i; 855c501d0b1SCristina Ciocan 856c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 857c501d0b1SCristina Ciocan 858c501d0b1SCristina Ciocan for (i = 0; i < group.npins; i++) { 859c501d0b1SCristina Ciocan void __iomem *padcfg0; 860c501d0b1SCristina Ciocan u32 value; 861c501d0b1SCristina Ciocan 862c501d0b1SCristina Ciocan padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 863c501d0b1SCristina Ciocan if (!padcfg0) { 864c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 865c501d0b1SCristina Ciocan "Group %s, pin %i not muxed (no padcfg0)\n", 866c501d0b1SCristina Ciocan group.name, i); 867c501d0b1SCristina Ciocan continue; 868c501d0b1SCristina Ciocan } 869c501d0b1SCristina Ciocan 870c501d0b1SCristina Ciocan value = readl(padcfg0); 871c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 872c501d0b1SCristina Ciocan value |= func; 873c501d0b1SCristina Ciocan writel(value, padcfg0); 874c501d0b1SCristina Ciocan } 875c501d0b1SCristina Ciocan 876c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 877c501d0b1SCristina Ciocan } 878c501d0b1SCristina Ciocan 879c501d0b1SCristina Ciocan static void byt_set_group_mixed_mux(struct byt_gpio *vg, 880c501d0b1SCristina Ciocan const struct byt_pingroup group, 881c501d0b1SCristina Ciocan const unsigned short *func) 882c501d0b1SCristina Ciocan { 883c501d0b1SCristina Ciocan unsigned long flags; 884c501d0b1SCristina Ciocan int i; 885c501d0b1SCristina Ciocan 886c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 887c501d0b1SCristina Ciocan 888c501d0b1SCristina Ciocan for (i = 0; i < group.npins; i++) { 889c501d0b1SCristina Ciocan void __iomem *padcfg0; 890c501d0b1SCristina Ciocan u32 value; 891c501d0b1SCristina Ciocan 892c501d0b1SCristina Ciocan padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 893c501d0b1SCristina Ciocan if (!padcfg0) { 894c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 895c501d0b1SCristina Ciocan "Group %s, pin %i not muxed (no padcfg0)\n", 896c501d0b1SCristina Ciocan group.name, i); 897c501d0b1SCristina Ciocan continue; 898c501d0b1SCristina Ciocan } 899c501d0b1SCristina Ciocan 900c501d0b1SCristina Ciocan value = readl(padcfg0); 901c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 902c501d0b1SCristina Ciocan value |= func[i]; 903c501d0b1SCristina Ciocan writel(value, padcfg0); 904c501d0b1SCristina Ciocan } 905c501d0b1SCristina Ciocan 906c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 907c501d0b1SCristina Ciocan } 908c501d0b1SCristina Ciocan 909c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 910c501d0b1SCristina Ciocan unsigned int group_selector) 911c501d0b1SCristina Ciocan { 912c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 913c501d0b1SCristina Ciocan const struct byt_function func = vg->soc_data->functions[func_selector]; 914c501d0b1SCristina Ciocan const struct byt_pingroup group = vg->soc_data->groups[group_selector]; 915c501d0b1SCristina Ciocan const unsigned short *mixed_func; 916c501d0b1SCristina Ciocan unsigned short simple_func; 917c501d0b1SCristina Ciocan int ret = 1; 918c501d0b1SCristina Ciocan 919c501d0b1SCristina Ciocan if (group.has_simple_funcs) 920c501d0b1SCristina Ciocan ret = byt_get_group_simple_mux(group, func.name, &simple_func); 921c501d0b1SCristina Ciocan else 922c501d0b1SCristina Ciocan ret = byt_get_group_mixed_mux(group, func.name, &mixed_func); 923c501d0b1SCristina Ciocan 924c501d0b1SCristina Ciocan if (ret) 925c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); 926c501d0b1SCristina Ciocan else if (group.has_simple_funcs) 927c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, simple_func); 928c501d0b1SCristina Ciocan else 929c501d0b1SCristina Ciocan byt_set_group_mixed_mux(vg, group, mixed_func); 930c501d0b1SCristina Ciocan 931c501d0b1SCristina Ciocan return 0; 932c501d0b1SCristina Ciocan } 933c501d0b1SCristina Ciocan 934c501d0b1SCristina Ciocan static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) 935c501d0b1SCristina Ciocan { 936c501d0b1SCristina Ciocan /* SCORE pin 92-93 */ 937c501d0b1SCristina Ciocan if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) && 938c501d0b1SCristina Ciocan offset >= 92 && offset <= 93) 939c501d0b1SCristina Ciocan return 1; 940c501d0b1SCristina Ciocan 941c501d0b1SCristina Ciocan /* SUS pin 11-21 */ 942c501d0b1SCristina Ciocan if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) && 943c501d0b1SCristina Ciocan offset >= 11 && offset <= 21) 944c501d0b1SCristina Ciocan return 1; 945c501d0b1SCristina Ciocan 946c501d0b1SCristina Ciocan return 0; 947c501d0b1SCristina Ciocan } 948c501d0b1SCristina Ciocan 949c501d0b1SCristina Ciocan static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) 950c501d0b1SCristina Ciocan { 951c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 95295f0972cSMika Westerberg unsigned long flags; 95395f0972cSMika Westerberg u32 value; 95495f0972cSMika Westerberg 95578e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 95695f0972cSMika Westerberg value = readl(reg); 95795f0972cSMika Westerberg value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); 95895f0972cSMika Westerberg writel(value, reg); 95978e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 96095f0972cSMika Westerberg } 96195f0972cSMika Westerberg 962c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, 963c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 964c501d0b1SCristina Ciocan unsigned int offset) 9655fae8b86SMika Westerberg { 966c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 967c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 968f8323b6bSMika Westerberg u32 value, gpio_mux; 96939ce8150SMika Westerberg unsigned long flags; 97039ce8150SMika Westerberg 97178e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 9725fae8b86SMika Westerberg 9735fae8b86SMika Westerberg /* 9745fae8b86SMika Westerberg * In most cases, func pin mux 000 means GPIO function. 9755fae8b86SMika Westerberg * But, some pins may have func pin mux 001 represents 976f8323b6bSMika Westerberg * GPIO function. 977f8323b6bSMika Westerberg * 978f8323b6bSMika Westerberg * Because there are devices out there where some pins were not 979f8323b6bSMika Westerberg * configured correctly we allow changing the mux value from 980f8323b6bSMika Westerberg * request (but print out warning about that). 9815fae8b86SMika Westerberg */ 9825fae8b86SMika Westerberg value = readl(reg) & BYT_PIN_MUX; 983f8323b6bSMika Westerberg gpio_mux = byt_get_gpio_mux(vg, offset); 984b5894d12SHans de Goede if (gpio_mux != value) { 985f8323b6bSMika Westerberg value = readl(reg) & ~BYT_PIN_MUX; 986f8323b6bSMika Westerberg value |= gpio_mux; 987f8323b6bSMika Westerberg writel(value, reg); 988f8323b6bSMika Westerberg 989b5894d12SHans de Goede dev_warn(&vg->pdev->dev, FW_BUG 990f8323b6bSMika Westerberg "pin %u forcibly re-configured as GPIO\n", offset); 9915fae8b86SMika Westerberg } 9925fae8b86SMika Westerberg 99378e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 99439ce8150SMika Westerberg 9955fae8b86SMika Westerberg pm_runtime_get(&vg->pdev->dev); 9965fae8b86SMika Westerberg 9975fae8b86SMika Westerberg return 0; 9985fae8b86SMika Westerberg } 9995fae8b86SMika Westerberg 1000c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, 1001c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 1002c501d0b1SCristina Ciocan unsigned int offset) 1003c501d0b1SCristina Ciocan { 1004c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1005c501d0b1SCristina Ciocan 1006c501d0b1SCristina Ciocan byt_gpio_clear_triggering(vg, offset); 1007c501d0b1SCristina Ciocan pm_runtime_put(&vg->pdev->dev); 1008c501d0b1SCristina Ciocan } 1009c501d0b1SCristina Ciocan 1010c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, 1011c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 1012c501d0b1SCristina Ciocan unsigned int offset, 1013c501d0b1SCristina Ciocan bool input) 1014c501d0b1SCristina Ciocan { 1015c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1016c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 1017c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1018c501d0b1SCristina Ciocan unsigned long flags; 1019c501d0b1SCristina Ciocan u32 value; 1020c501d0b1SCristina Ciocan 1021c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1022c501d0b1SCristina Ciocan 1023c501d0b1SCristina Ciocan value = readl(val_reg); 1024c501d0b1SCristina Ciocan value &= ~BYT_DIR_MASK; 1025c501d0b1SCristina Ciocan if (input) 1026c501d0b1SCristina Ciocan value |= BYT_OUTPUT_EN; 1027c501d0b1SCristina Ciocan else 1028c501d0b1SCristina Ciocan /* 1029c501d0b1SCristina Ciocan * Before making any direction modifications, do a check if gpio 1030c501d0b1SCristina Ciocan * is set for direct IRQ. On baytrail, setting GPIO to output 1031c501d0b1SCristina Ciocan * does not make sense, so let's at least warn the caller before 1032c501d0b1SCristina Ciocan * they shoot themselves in the foot. 1033c501d0b1SCristina Ciocan */ 1034c501d0b1SCristina Ciocan WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, 1035c501d0b1SCristina Ciocan "Potential Error: Setting GPIO with direct_irq_en to output"); 1036c501d0b1SCristina Ciocan writel(value, val_reg); 1037c501d0b1SCristina Ciocan 1038c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1039c501d0b1SCristina Ciocan 1040c501d0b1SCristina Ciocan return 0; 1041c501d0b1SCristina Ciocan } 1042c501d0b1SCristina Ciocan 1043c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = { 1044c501d0b1SCristina Ciocan .get_functions_count = byt_get_functions_count, 1045c501d0b1SCristina Ciocan .get_function_name = byt_get_function_name, 1046c501d0b1SCristina Ciocan .get_function_groups = byt_get_function_groups, 1047c501d0b1SCristina Ciocan .set_mux = byt_set_mux, 1048c501d0b1SCristina Ciocan .gpio_request_enable = byt_gpio_request_enable, 1049c501d0b1SCristina Ciocan .gpio_disable_free = byt_gpio_disable_free, 1050c501d0b1SCristina Ciocan .gpio_set_direction = byt_gpio_set_direction, 1051c501d0b1SCristina Ciocan }; 1052c501d0b1SCristina Ciocan 1053c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength) 1054c501d0b1SCristina Ciocan { 1055c501d0b1SCristina Ciocan switch (reg & BYT_PULL_STR_MASK) { 1056c501d0b1SCristina Ciocan case BYT_PULL_STR_2K: 1057c501d0b1SCristina Ciocan *strength = 2000; 1058c501d0b1SCristina Ciocan break; 1059c501d0b1SCristina Ciocan case BYT_PULL_STR_10K: 1060c501d0b1SCristina Ciocan *strength = 10000; 1061c501d0b1SCristina Ciocan break; 1062c501d0b1SCristina Ciocan case BYT_PULL_STR_20K: 1063c501d0b1SCristina Ciocan *strength = 20000; 1064c501d0b1SCristina Ciocan break; 1065c501d0b1SCristina Ciocan case BYT_PULL_STR_40K: 1066c501d0b1SCristina Ciocan *strength = 40000; 1067c501d0b1SCristina Ciocan break; 1068c501d0b1SCristina Ciocan } 1069c501d0b1SCristina Ciocan } 1070c501d0b1SCristina Ciocan 1071c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength) 1072c501d0b1SCristina Ciocan { 1073c501d0b1SCristina Ciocan *reg &= ~BYT_PULL_STR_MASK; 1074c501d0b1SCristina Ciocan 1075c501d0b1SCristina Ciocan switch (strength) { 1076c501d0b1SCristina Ciocan case 2000: 1077c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_2K; 1078c501d0b1SCristina Ciocan break; 1079c501d0b1SCristina Ciocan case 10000: 1080c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_10K; 1081c501d0b1SCristina Ciocan break; 1082c501d0b1SCristina Ciocan case 20000: 1083c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_20K; 1084c501d0b1SCristina Ciocan break; 1085c501d0b1SCristina Ciocan case 40000: 1086c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_40K; 1087c501d0b1SCristina Ciocan break; 1088c501d0b1SCristina Ciocan default: 1089c501d0b1SCristina Ciocan return -EINVAL; 1090c501d0b1SCristina Ciocan } 1091c501d0b1SCristina Ciocan 1092c501d0b1SCristina Ciocan return 0; 1093c501d0b1SCristina Ciocan } 1094c501d0b1SCristina Ciocan 1095c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, 1096c501d0b1SCristina Ciocan unsigned long *config) 1097c501d0b1SCristina Ciocan { 1098c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1099c501d0b1SCristina Ciocan enum pin_config_param param = pinconf_to_config_param(*config); 1100c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1101c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 110204ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 1103c501d0b1SCristina Ciocan unsigned long flags; 1104658b476cSCristina Ciocan u32 conf, pull, val, debounce; 1105c501d0b1SCristina Ciocan u16 arg = 0; 1106c501d0b1SCristina Ciocan 1107c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1108c501d0b1SCristina Ciocan conf = readl(conf_reg); 1109c501d0b1SCristina Ciocan pull = conf & BYT_PULL_ASSIGN_MASK; 1110c501d0b1SCristina Ciocan val = readl(val_reg); 1111c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1112c501d0b1SCristina Ciocan 1113c501d0b1SCristina Ciocan switch (param) { 1114c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 1115c501d0b1SCristina Ciocan if (pull) 1116c501d0b1SCristina Ciocan return -EINVAL; 1117c501d0b1SCristina Ciocan break; 1118c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 1119c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 1120c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) 1121c501d0b1SCristina Ciocan return -EINVAL; 1122c501d0b1SCristina Ciocan 1123c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 1124c501d0b1SCristina Ciocan 1125c501d0b1SCristina Ciocan break; 1126c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 1127c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 1128c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) 1129c501d0b1SCristina Ciocan return -EINVAL; 1130c501d0b1SCristina Ciocan 1131c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 1132c501d0b1SCristina Ciocan 1133c501d0b1SCristina Ciocan break; 1134658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 1135658b476cSCristina Ciocan if (!(conf & BYT_DEBOUNCE_EN)) 1136658b476cSCristina Ciocan return -EINVAL; 1137658b476cSCristina Ciocan 1138658b476cSCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 113904ff5a09SAndy Shevchenko debounce = readl(db_reg); 1140658b476cSCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1141658b476cSCristina Ciocan 1142658b476cSCristina Ciocan switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { 1143658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_375US: 1144658b476cSCristina Ciocan arg = 375; 1145658b476cSCristina Ciocan break; 1146658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_750US: 1147658b476cSCristina Ciocan arg = 750; 1148658b476cSCristina Ciocan break; 1149658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_1500US: 1150658b476cSCristina Ciocan arg = 1500; 1151658b476cSCristina Ciocan break; 1152658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_3MS: 1153658b476cSCristina Ciocan arg = 3000; 1154658b476cSCristina Ciocan break; 1155658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_6MS: 1156658b476cSCristina Ciocan arg = 6000; 1157658b476cSCristina Ciocan break; 1158658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_12MS: 1159658b476cSCristina Ciocan arg = 12000; 1160658b476cSCristina Ciocan break; 1161658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_24MS: 1162658b476cSCristina Ciocan arg = 24000; 1163658b476cSCristina Ciocan break; 1164658b476cSCristina Ciocan default: 1165658b476cSCristina Ciocan return -EINVAL; 1166658b476cSCristina Ciocan } 1167658b476cSCristina Ciocan 1168658b476cSCristina Ciocan break; 1169c501d0b1SCristina Ciocan default: 1170c501d0b1SCristina Ciocan return -ENOTSUPP; 1171c501d0b1SCristina Ciocan } 1172c501d0b1SCristina Ciocan 1173c501d0b1SCristina Ciocan *config = pinconf_to_config_packed(param, arg); 1174c501d0b1SCristina Ciocan 1175c501d0b1SCristina Ciocan return 0; 1176c501d0b1SCristina Ciocan } 1177c501d0b1SCristina Ciocan 1178c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, 1179c501d0b1SCristina Ciocan unsigned int offset, 1180c501d0b1SCristina Ciocan unsigned long *configs, 1181c501d0b1SCristina Ciocan unsigned int num_configs) 1182c501d0b1SCristina Ciocan { 1183c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1184c501d0b1SCristina Ciocan unsigned int param, arg; 1185c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1186c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 118704ff5a09SAndy Shevchenko void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 1188c501d0b1SCristina Ciocan unsigned long flags; 1189658b476cSCristina Ciocan u32 conf, val, debounce; 1190c501d0b1SCristina Ciocan int i, ret = 0; 1191c501d0b1SCristina Ciocan 1192c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1193c501d0b1SCristina Ciocan 1194c501d0b1SCristina Ciocan conf = readl(conf_reg); 1195c501d0b1SCristina Ciocan val = readl(val_reg); 1196c501d0b1SCristina Ciocan 1197c501d0b1SCristina Ciocan for (i = 0; i < num_configs; i++) { 1198c501d0b1SCristina Ciocan param = pinconf_to_config_param(configs[i]); 1199c501d0b1SCristina Ciocan arg = pinconf_to_config_argument(configs[i]); 1200c501d0b1SCristina Ciocan 1201c501d0b1SCristina Ciocan switch (param) { 1202c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 1203c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1204c501d0b1SCristina Ciocan break; 1205c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 1206c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1207c501d0b1SCristina Ciocan if (arg == 1) 1208c501d0b1SCristina Ciocan arg = 2000; 1209c501d0b1SCristina Ciocan 1210c501d0b1SCristina Ciocan /* 1211c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1212c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1213c501d0b1SCristina Ciocan */ 1214c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1215c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1216c501d0b1SCristina Ciocan writel(val, val_reg); 1217c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 1218c501d0b1SCristina Ciocan "pin %u forcibly set to input mode\n", 1219c501d0b1SCristina Ciocan offset); 1220c501d0b1SCristina Ciocan } 1221c501d0b1SCristina Ciocan 1222c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1223c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_DOWN; 1224c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1225c501d0b1SCristina Ciocan 1226c501d0b1SCristina Ciocan break; 1227c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 1228c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1229c501d0b1SCristina Ciocan if (arg == 1) 1230c501d0b1SCristina Ciocan arg = 2000; 1231c501d0b1SCristina Ciocan 1232c501d0b1SCristina Ciocan /* 1233c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1234c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1235c501d0b1SCristina Ciocan */ 1236c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1237c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1238c501d0b1SCristina Ciocan writel(val, val_reg); 1239c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 1240c501d0b1SCristina Ciocan "pin %u forcibly set to input mode\n", 1241c501d0b1SCristina Ciocan offset); 1242c501d0b1SCristina Ciocan } 1243c501d0b1SCristina Ciocan 1244c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1245c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_UP; 1246c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1247c501d0b1SCristina Ciocan 1248c501d0b1SCristina Ciocan break; 1249658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 125004ff5a09SAndy Shevchenko debounce = readl(db_reg); 125104ff5a09SAndy Shevchenko debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 1252658b476cSCristina Ciocan 1253827e1579SAndy Shevchenko if (arg) 1254827e1579SAndy Shevchenko conf |= BYT_DEBOUNCE_EN; 1255827e1579SAndy Shevchenko else 1256827e1579SAndy Shevchenko conf &= ~BYT_DEBOUNCE_EN; 1257827e1579SAndy Shevchenko 1258658b476cSCristina Ciocan switch (arg) { 1259658b476cSCristina Ciocan case 375: 126004ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_375US; 1261658b476cSCristina Ciocan break; 1262658b476cSCristina Ciocan case 750: 126304ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_750US; 1264658b476cSCristina Ciocan break; 1265658b476cSCristina Ciocan case 1500: 126604ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_1500US; 1267658b476cSCristina Ciocan break; 1268658b476cSCristina Ciocan case 3000: 126904ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_3MS; 1270658b476cSCristina Ciocan break; 1271658b476cSCristina Ciocan case 6000: 127204ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_6MS; 1273658b476cSCristina Ciocan break; 1274658b476cSCristina Ciocan case 12000: 127504ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_12MS; 1276658b476cSCristina Ciocan break; 1277658b476cSCristina Ciocan case 24000: 127804ff5a09SAndy Shevchenko debounce |= BYT_DEBOUNCE_PULSE_24MS; 1279658b476cSCristina Ciocan break; 1280658b476cSCristina Ciocan default: 1281827e1579SAndy Shevchenko if (arg) 1282658b476cSCristina Ciocan ret = -EINVAL; 1283827e1579SAndy Shevchenko break; 1284658b476cSCristina Ciocan } 1285658b476cSCristina Ciocan 128604ff5a09SAndy Shevchenko if (!ret) 128704ff5a09SAndy Shevchenko writel(debounce, db_reg); 1288658b476cSCristina Ciocan break; 1289c501d0b1SCristina Ciocan default: 1290c501d0b1SCristina Ciocan ret = -ENOTSUPP; 1291c501d0b1SCristina Ciocan } 1292c501d0b1SCristina Ciocan 1293c501d0b1SCristina Ciocan if (ret) 1294c501d0b1SCristina Ciocan break; 1295c501d0b1SCristina Ciocan } 1296c501d0b1SCristina Ciocan 1297c501d0b1SCristina Ciocan if (!ret) 1298c501d0b1SCristina Ciocan writel(conf, conf_reg); 1299c501d0b1SCristina Ciocan 1300c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1301c501d0b1SCristina Ciocan 1302c501d0b1SCristina Ciocan return ret; 1303c501d0b1SCristina Ciocan } 1304c501d0b1SCristina Ciocan 1305c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = { 1306c501d0b1SCristina Ciocan .is_generic = true, 1307c501d0b1SCristina Ciocan .pin_config_get = byt_pin_config_get, 1308c501d0b1SCristina Ciocan .pin_config_set = byt_pin_config_set, 1309c501d0b1SCristina Ciocan }; 1310c501d0b1SCristina Ciocan 1311c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = { 1312c501d0b1SCristina Ciocan .pctlops = &byt_pinctrl_ops, 1313c501d0b1SCristina Ciocan .pmxops = &byt_pinmux_ops, 1314c501d0b1SCristina Ciocan .confops = &byt_pinconf_ops, 1315c501d0b1SCristina Ciocan .owner = THIS_MODULE, 1316c501d0b1SCristina Ciocan }; 1317c501d0b1SCristina Ciocan 13185fae8b86SMika Westerberg static int byt_gpio_get(struct gpio_chip *chip, unsigned offset) 13195fae8b86SMika Westerberg { 1320bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1321c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 132239ce8150SMika Westerberg unsigned long flags; 132339ce8150SMika Westerberg u32 val; 132439ce8150SMika Westerberg 132578e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 132639ce8150SMika Westerberg val = readl(reg); 132778e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 132839ce8150SMika Westerberg 13293bde8771SLinus Walleij return !!(val & BYT_LEVEL); 13305fae8b86SMika Westerberg } 13315fae8b86SMika Westerberg 13325fae8b86SMika Westerberg static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 13335fae8b86SMika Westerberg { 1334bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1335c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 13365fae8b86SMika Westerberg unsigned long flags; 13375fae8b86SMika Westerberg u32 old_val; 13385fae8b86SMika Westerberg 133986e3ef81SCristina Ciocan if (!reg) 134086e3ef81SCristina Ciocan return; 134186e3ef81SCristina Ciocan 134278e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 13435fae8b86SMika Westerberg old_val = readl(reg); 13445fae8b86SMika Westerberg if (value) 13455fae8b86SMika Westerberg writel(old_val | BYT_LEVEL, reg); 13465fae8b86SMika Westerberg else 13475fae8b86SMika Westerberg writel(old_val & ~BYT_LEVEL, reg); 134878e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 13495fae8b86SMika Westerberg } 13505fae8b86SMika Westerberg 135186e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 13525fae8b86SMika Westerberg { 1353bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1354c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 13555fae8b86SMika Westerberg unsigned long flags; 13565fae8b86SMika Westerberg u32 value; 13575fae8b86SMika Westerberg 135886e3ef81SCristina Ciocan if (!reg) 135986e3ef81SCristina Ciocan return -EINVAL; 136086e3ef81SCristina Ciocan 136178e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 136286e3ef81SCristina Ciocan value = readl(reg); 136378e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 13645fae8b86SMika Westerberg 136586e3ef81SCristina Ciocan if (!(value & BYT_OUTPUT_EN)) 136686e3ef81SCristina Ciocan return GPIOF_DIR_OUT; 136786e3ef81SCristina Ciocan if (!(value & BYT_INPUT_EN)) 136886e3ef81SCristina Ciocan return GPIOF_DIR_IN; 136986e3ef81SCristina Ciocan 137086e3ef81SCristina Ciocan return -EINVAL; 13715fae8b86SMika Westerberg } 13725fae8b86SMika Westerberg 137386e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 13745fae8b86SMika Westerberg { 137586e3ef81SCristina Ciocan return pinctrl_gpio_direction_input(chip->base + offset); 137686e3ef81SCristina Ciocan } 13775fae8b86SMika Westerberg 137886e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip, 137986e3ef81SCristina Ciocan unsigned int offset, int value) 138086e3ef81SCristina Ciocan { 138186e3ef81SCristina Ciocan int ret = pinctrl_gpio_direction_output(chip->base + offset); 13825fae8b86SMika Westerberg 138386e3ef81SCristina Ciocan if (ret) 138486e3ef81SCristina Ciocan return ret; 138586e3ef81SCristina Ciocan 138686e3ef81SCristina Ciocan byt_gpio_set(chip, offset, value); 13875fae8b86SMika Westerberg 13885fae8b86SMika Westerberg return 0; 13895fae8b86SMika Westerberg } 13905fae8b86SMika Westerberg 13915fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 13925fae8b86SMika Westerberg { 1393bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 13945fae8b86SMika Westerberg int i; 139586e3ef81SCristina Ciocan u32 conf0, val; 13965fae8b86SMika Westerberg 139786e3ef81SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 139886e3ef81SCristina Ciocan const struct byt_community *comm; 13995fae8b86SMika Westerberg const char *pull_str = NULL; 14005fae8b86SMika Westerberg const char *pull = NULL; 140186e3ef81SCristina Ciocan void __iomem *reg; 140278e1c896SMika Westerberg unsigned long flags; 14035fae8b86SMika Westerberg const char *label; 140486e3ef81SCristina Ciocan unsigned int pin; 140578e1c896SMika Westerberg 140678e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 140786e3ef81SCristina Ciocan pin = vg->soc_data->pins[i].number; 140886e3ef81SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 140986e3ef81SCristina Ciocan if (!reg) { 141086e3ef81SCristina Ciocan seq_printf(s, 141186e3ef81SCristina Ciocan "Could not retrieve pin %i conf0 reg\n", 141286e3ef81SCristina Ciocan pin); 141322bbd21bSDan Carpenter raw_spin_unlock_irqrestore(&vg->lock, flags); 141486e3ef81SCristina Ciocan continue; 141586e3ef81SCristina Ciocan } 141686e3ef81SCristina Ciocan conf0 = readl(reg); 141786e3ef81SCristina Ciocan 141886e3ef81SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 141986e3ef81SCristina Ciocan if (!reg) { 142086e3ef81SCristina Ciocan seq_printf(s, 142186e3ef81SCristina Ciocan "Could not retrieve pin %i val reg\n", pin); 142222bbd21bSDan Carpenter raw_spin_unlock_irqrestore(&vg->lock, flags); 142322bbd21bSDan Carpenter continue; 142486e3ef81SCristina Ciocan } 142586e3ef81SCristina Ciocan val = readl(reg); 142678e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 14275fae8b86SMika Westerberg 142886e3ef81SCristina Ciocan comm = byt_get_community(vg, pin); 142986e3ef81SCristina Ciocan if (!comm) { 143086e3ef81SCristina Ciocan seq_printf(s, 143186e3ef81SCristina Ciocan "Could not get community for pin %i\n", pin); 143286e3ef81SCristina Ciocan continue; 143386e3ef81SCristina Ciocan } 14345fae8b86SMika Westerberg label = gpiochip_is_requested(chip, i); 14355fae8b86SMika Westerberg if (!label) 14365fae8b86SMika Westerberg label = "Unrequested"; 14375fae8b86SMika Westerberg 14385fae8b86SMika Westerberg switch (conf0 & BYT_PULL_ASSIGN_MASK) { 14395fae8b86SMika Westerberg case BYT_PULL_ASSIGN_UP: 14405fae8b86SMika Westerberg pull = "up"; 14415fae8b86SMika Westerberg break; 14425fae8b86SMika Westerberg case BYT_PULL_ASSIGN_DOWN: 14435fae8b86SMika Westerberg pull = "down"; 14445fae8b86SMika Westerberg break; 14455fae8b86SMika Westerberg } 14465fae8b86SMika Westerberg 14475fae8b86SMika Westerberg switch (conf0 & BYT_PULL_STR_MASK) { 14485fae8b86SMika Westerberg case BYT_PULL_STR_2K: 14495fae8b86SMika Westerberg pull_str = "2k"; 14505fae8b86SMika Westerberg break; 14515fae8b86SMika Westerberg case BYT_PULL_STR_10K: 14525fae8b86SMika Westerberg pull_str = "10k"; 14535fae8b86SMika Westerberg break; 14545fae8b86SMika Westerberg case BYT_PULL_STR_20K: 14555fae8b86SMika Westerberg pull_str = "20k"; 14565fae8b86SMika Westerberg break; 14575fae8b86SMika Westerberg case BYT_PULL_STR_40K: 14585fae8b86SMika Westerberg pull_str = "40k"; 14595fae8b86SMika Westerberg break; 14605fae8b86SMika Westerberg } 14615fae8b86SMika Westerberg 14625fae8b86SMika Westerberg seq_printf(s, 14635fae8b86SMika Westerberg " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", 146486e3ef81SCristina Ciocan pin, 14655fae8b86SMika Westerberg label, 14665fae8b86SMika Westerberg val & BYT_INPUT_EN ? " " : "in", 14675fae8b86SMika Westerberg val & BYT_OUTPUT_EN ? " " : "out", 14685fae8b86SMika Westerberg val & BYT_LEVEL ? "hi" : "lo", 14693655a1caSAlexander Stein comm->pad_map[i], comm->pad_map[i] * 16, 14705fae8b86SMika Westerberg conf0 & 0x7, 14715fae8b86SMika Westerberg conf0 & BYT_TRIG_NEG ? " fall" : " ", 14725fae8b86SMika Westerberg conf0 & BYT_TRIG_POS ? " rise" : " ", 14735fae8b86SMika Westerberg conf0 & BYT_TRIG_LVL ? " level" : " "); 14745fae8b86SMika Westerberg 14755fae8b86SMika Westerberg if (pull && pull_str) 14765fae8b86SMika Westerberg seq_printf(s, " %-4s %-3s", pull, pull_str); 14775fae8b86SMika Westerberg else 14785fae8b86SMika Westerberg seq_puts(s, " "); 14795fae8b86SMika Westerberg 14805fae8b86SMika Westerberg if (conf0 & BYT_IODEN) 14815fae8b86SMika Westerberg seq_puts(s, " open-drain"); 14825fae8b86SMika Westerberg 14835fae8b86SMika Westerberg seq_puts(s, "\n"); 14845fae8b86SMika Westerberg } 14855fae8b86SMika Westerberg } 14865fae8b86SMika Westerberg 148786e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = { 148886e3ef81SCristina Ciocan .owner = THIS_MODULE, 148986e3ef81SCristina Ciocan .request = gpiochip_generic_request, 149086e3ef81SCristina Ciocan .free = gpiochip_generic_free, 149186e3ef81SCristina Ciocan .get_direction = byt_gpio_get_direction, 149286e3ef81SCristina Ciocan .direction_input = byt_gpio_direction_input, 149386e3ef81SCristina Ciocan .direction_output = byt_gpio_direction_output, 149486e3ef81SCristina Ciocan .get = byt_gpio_get, 149586e3ef81SCristina Ciocan .set = byt_gpio_set, 149686e3ef81SCristina Ciocan .dbg_show = byt_gpio_dbg_show, 149786e3ef81SCristina Ciocan }; 149886e3ef81SCristina Ciocan 149931e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d) 150031e4329fSMika Westerberg { 150131e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1502bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(gc); 150331e4329fSMika Westerberg unsigned offset = irqd_to_hwirq(d); 150431e4329fSMika Westerberg void __iomem *reg; 150531e4329fSMika Westerberg 1506c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); 15079f573b98SCristina Ciocan if (!reg) 15089f573b98SCristina Ciocan return; 15099f573b98SCristina Ciocan 15109f573b98SCristina Ciocan raw_spin_lock(&vg->lock); 151131e4329fSMika Westerberg writel(BIT(offset % 32), reg); 151278e1c896SMika Westerberg raw_spin_unlock(&vg->lock); 151331e4329fSMika Westerberg } 151431e4329fSMika Westerberg 15159f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d) 15169f573b98SCristina Ciocan { 15179f573b98SCristina Ciocan struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 15189f573b98SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data(gc); 15199f573b98SCristina Ciocan 15209f573b98SCristina Ciocan byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); 15219f573b98SCristina Ciocan } 15229f573b98SCristina Ciocan 15235fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d) 15245fae8b86SMika Westerberg { 152531e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1526bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(gc); 152731e4329fSMika Westerberg unsigned offset = irqd_to_hwirq(d); 152831e4329fSMika Westerberg unsigned long flags; 152931e4329fSMika Westerberg void __iomem *reg; 153031e4329fSMika Westerberg u32 value; 153131e4329fSMika Westerberg 1532c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 15339f573b98SCristina Ciocan if (!reg) 15349f573b98SCristina Ciocan return; 153578e1c896SMika Westerberg 153678e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 153731e4329fSMika Westerberg value = readl(reg); 153831e4329fSMika Westerberg 153931e4329fSMika Westerberg switch (irqd_get_trigger_type(d)) { 154031e4329fSMika Westerberg case IRQ_TYPE_LEVEL_HIGH: 154131e4329fSMika Westerberg value |= BYT_TRIG_LVL; 154231e4329fSMika Westerberg case IRQ_TYPE_EDGE_RISING: 154331e4329fSMika Westerberg value |= BYT_TRIG_POS; 154431e4329fSMika Westerberg break; 154531e4329fSMika Westerberg case IRQ_TYPE_LEVEL_LOW: 154631e4329fSMika Westerberg value |= BYT_TRIG_LVL; 154731e4329fSMika Westerberg case IRQ_TYPE_EDGE_FALLING: 154831e4329fSMika Westerberg value |= BYT_TRIG_NEG; 154931e4329fSMika Westerberg break; 155031e4329fSMika Westerberg case IRQ_TYPE_EDGE_BOTH: 155131e4329fSMika Westerberg value |= (BYT_TRIG_NEG | BYT_TRIG_POS); 155231e4329fSMika Westerberg break; 155331e4329fSMika Westerberg } 155431e4329fSMika Westerberg 155531e4329fSMika Westerberg writel(value, reg); 155631e4329fSMika Westerberg 155778e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 15585fae8b86SMika Westerberg } 15595fae8b86SMika Westerberg 15609f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type) 15615fae8b86SMika Westerberg { 15629f573b98SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); 15639f573b98SCristina Ciocan u32 offset = irqd_to_hwirq(d); 15649f573b98SCristina Ciocan u32 value; 15659f573b98SCristina Ciocan unsigned long flags; 15669f573b98SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 156731e4329fSMika Westerberg 15689f573b98SCristina Ciocan if (!reg || offset >= vg->chip.ngpio) 15699f573b98SCristina Ciocan return -EINVAL; 15709f573b98SCristina Ciocan 15719f573b98SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 15729f573b98SCristina Ciocan value = readl(reg); 15739f573b98SCristina Ciocan 15749f573b98SCristina Ciocan WARN(value & BYT_DIRECT_IRQ_EN, 15759f573b98SCristina Ciocan "Bad pad config for io mode, force direct_irq_en bit clearing"); 15769f573b98SCristina Ciocan 15779f573b98SCristina Ciocan /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits 15789f573b98SCristina Ciocan * are used to indicate high and low level triggering 15799f573b98SCristina Ciocan */ 15809f573b98SCristina Ciocan value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | 15819f573b98SCristina Ciocan BYT_TRIG_LVL); 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