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/module.h> 195fae8b86SMika Westerberg #include <linux/init.h> 205fae8b86SMika Westerberg #include <linux/types.h> 215fae8b86SMika Westerberg #include <linux/bitops.h> 225fae8b86SMika Westerberg #include <linux/interrupt.h> 2386e3ef81SCristina Ciocan #include <linux/gpio.h> 24bf9a5c96SLinus Walleij #include <linux/gpio/driver.h> 255fae8b86SMika Westerberg #include <linux/acpi.h> 265fae8b86SMika Westerberg #include <linux/platform_device.h> 275fae8b86SMika Westerberg #include <linux/seq_file.h> 285fae8b86SMika Westerberg #include <linux/io.h> 295fae8b86SMika Westerberg #include <linux/pm_runtime.h> 305fae8b86SMika Westerberg #include <linux/pinctrl/pinctrl.h> 31c501d0b1SCristina Ciocan #include <linux/pinctrl/pinmux.h> 32c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf.h> 33c501d0b1SCristina Ciocan #include <linux/pinctrl/pinconf-generic.h> 345fae8b86SMika Westerberg 355fae8b86SMika Westerberg /* memory mapped register offsets */ 365fae8b86SMika Westerberg #define BYT_CONF0_REG 0x000 375fae8b86SMika Westerberg #define BYT_CONF1_REG 0x004 385fae8b86SMika Westerberg #define BYT_VAL_REG 0x008 395fae8b86SMika Westerberg #define BYT_DFT_REG 0x00c 405fae8b86SMika Westerberg #define BYT_INT_STAT_REG 0x800 41658b476cSCristina Ciocan #define BYT_DEBOUNCE_REG 0x9d0 425fae8b86SMika Westerberg 435fae8b86SMika Westerberg /* BYT_CONF0_REG register bits */ 445fae8b86SMika Westerberg #define BYT_IODEN BIT(31) 455fae8b86SMika Westerberg #define BYT_DIRECT_IRQ_EN BIT(27) 465fae8b86SMika Westerberg #define BYT_TRIG_NEG BIT(26) 475fae8b86SMika Westerberg #define BYT_TRIG_POS BIT(25) 485fae8b86SMika Westerberg #define BYT_TRIG_LVL BIT(24) 49658b476cSCristina Ciocan #define BYT_DEBOUNCE_EN BIT(20) 505fae8b86SMika Westerberg #define BYT_PULL_STR_SHIFT 9 515fae8b86SMika Westerberg #define BYT_PULL_STR_MASK (3 << BYT_PULL_STR_SHIFT) 525fae8b86SMika Westerberg #define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) 535fae8b86SMika Westerberg #define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT) 545fae8b86SMika Westerberg #define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT) 555fae8b86SMika Westerberg #define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT) 565fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_SHIFT 7 575fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_MASK (3 << BYT_PULL_ASSIGN_SHIFT) 585fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT) 595fae8b86SMika Westerberg #define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT) 605fae8b86SMika Westerberg #define BYT_PIN_MUX 0x07 615fae8b86SMika Westerberg 625fae8b86SMika Westerberg /* BYT_VAL_REG register bits */ 635fae8b86SMika Westerberg #define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ 645fae8b86SMika Westerberg #define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ 655fae8b86SMika Westerberg #define BYT_LEVEL BIT(0) 665fae8b86SMika Westerberg 675fae8b86SMika Westerberg #define BYT_DIR_MASK (BIT(1) | BIT(2)) 685fae8b86SMika Westerberg #define BYT_TRIG_MASK (BIT(26) | BIT(25) | BIT(24)) 695fae8b86SMika Westerberg 70fcc18debSMika Westerberg #define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | \ 71fcc18debSMika Westerberg BYT_PIN_MUX) 72fcc18debSMika Westerberg #define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) 73fcc18debSMika Westerberg 74658b476cSCristina Ciocan /* BYT_DEBOUNCE_REG bits */ 75658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_MASK 0x7 76658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_375US 1 77658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_750US 2 78658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_1500US 3 79658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_3MS 4 80658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_6MS 5 81658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_12MS 6 82658b476cSCristina Ciocan #define BYT_DEBOUNCE_PULSE_24MS 7 83658b476cSCristina Ciocan 845fae8b86SMika Westerberg #define BYT_NGPIO_SCORE 102 855fae8b86SMika Westerberg #define BYT_NGPIO_NCORE 28 865fae8b86SMika Westerberg #define BYT_NGPIO_SUS 44 875fae8b86SMika Westerberg 885fae8b86SMika Westerberg #define BYT_SCORE_ACPI_UID "1" 895fae8b86SMika Westerberg #define BYT_NCORE_ACPI_UID "2" 905fae8b86SMika Westerberg #define BYT_SUS_ACPI_UID "3" 915fae8b86SMika Westerberg 92c501d0b1SCristina Ciocan /* 93c501d0b1SCristina Ciocan * This is the function value most pins have for GPIO muxing. If the value 94c501d0b1SCristina Ciocan * differs from the default one, it must be explicitly mentioned. Otherwise, the 95c501d0b1SCristina Ciocan * pin control implementation will set the muxing value to default GPIO if it 96c501d0b1SCristina Ciocan * does not find a match for the requested function. 97c501d0b1SCristina Ciocan */ 98c501d0b1SCristina Ciocan #define BYT_DEFAULT_GPIO_MUX 0 99c501d0b1SCristina Ciocan 100c8f5c4c7SCristina Ciocan struct byt_gpio_pin_context { 101c8f5c4c7SCristina Ciocan u32 conf0; 102c8f5c4c7SCristina Ciocan u32 val; 103c8f5c4c7SCristina Ciocan }; 1045fae8b86SMika Westerberg 105c8f5c4c7SCristina Ciocan struct byt_simple_func_mux { 106c8f5c4c7SCristina Ciocan const char *name; 107c8f5c4c7SCristina Ciocan unsigned short func; 108c8f5c4c7SCristina Ciocan }; 109c8f5c4c7SCristina Ciocan 110c8f5c4c7SCristina Ciocan struct byt_mixed_func_mux { 111c8f5c4c7SCristina Ciocan const char *name; 112c8f5c4c7SCristina Ciocan const unsigned short *func_values; 113c8f5c4c7SCristina Ciocan }; 114c8f5c4c7SCristina Ciocan 115c8f5c4c7SCristina Ciocan struct byt_pingroup { 116c8f5c4c7SCristina Ciocan const char *name; 117c8f5c4c7SCristina Ciocan const unsigned int *pins; 118c8f5c4c7SCristina Ciocan size_t npins; 119c8f5c4c7SCristina Ciocan unsigned short has_simple_funcs; 120c8f5c4c7SCristina Ciocan union { 121c8f5c4c7SCristina Ciocan const struct byt_simple_func_mux *simple_funcs; 122c8f5c4c7SCristina Ciocan const struct byt_mixed_func_mux *mixed_funcs; 123c8f5c4c7SCristina Ciocan }; 124c8f5c4c7SCristina Ciocan size_t nfuncs; 125c8f5c4c7SCristina Ciocan }; 126c8f5c4c7SCristina Ciocan 127c8f5c4c7SCristina Ciocan struct byt_function { 128c8f5c4c7SCristina Ciocan const char *name; 129c8f5c4c7SCristina Ciocan const char * const *groups; 130c8f5c4c7SCristina Ciocan size_t ngroups; 131c8f5c4c7SCristina Ciocan }; 132c8f5c4c7SCristina Ciocan 133c8f5c4c7SCristina Ciocan struct byt_community { 134c8f5c4c7SCristina Ciocan unsigned int pin_base; 135c8f5c4c7SCristina Ciocan size_t npins; 136c8f5c4c7SCristina Ciocan const unsigned int *pad_map; 137c8f5c4c7SCristina Ciocan void __iomem *reg_base; 138c8f5c4c7SCristina Ciocan }; 139c8f5c4c7SCristina Ciocan 140c8f5c4c7SCristina Ciocan #define SIMPLE_FUNC(n, f) \ 141c8f5c4c7SCristina Ciocan { \ 142c8f5c4c7SCristina Ciocan .name = (n), \ 143c8f5c4c7SCristina Ciocan .func = (f), \ 144c8f5c4c7SCristina Ciocan } 145c8f5c4c7SCristina Ciocan #define MIXED_FUNC(n, f) \ 146c8f5c4c7SCristina Ciocan { \ 147c8f5c4c7SCristina Ciocan .name = (n), \ 148c8f5c4c7SCristina Ciocan .func_values = (f), \ 149c8f5c4c7SCristina Ciocan } 150c8f5c4c7SCristina Ciocan 151c8f5c4c7SCristina Ciocan #define PIN_GROUP_SIMPLE(n, p, f) \ 152c8f5c4c7SCristina Ciocan { \ 153c8f5c4c7SCristina Ciocan .name = (n), \ 154c8f5c4c7SCristina Ciocan .pins = (p), \ 155c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE((p)), \ 156c8f5c4c7SCristina Ciocan .has_simple_funcs = 1, \ 157bbccb9c7SAndrew Morton { \ 158c8f5c4c7SCristina Ciocan .simple_funcs = (f), \ 159bbccb9c7SAndrew Morton }, \ 160c8f5c4c7SCristina Ciocan .nfuncs = ARRAY_SIZE((f)), \ 161c8f5c4c7SCristina Ciocan } 162c8f5c4c7SCristina Ciocan #define PIN_GROUP_MIXED(n, p, f) \ 163c8f5c4c7SCristina Ciocan { \ 164c8f5c4c7SCristina Ciocan .name = (n), \ 165c8f5c4c7SCristina Ciocan .pins = (p), \ 166c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE((p)), \ 167c8f5c4c7SCristina Ciocan .has_simple_funcs = 0, \ 168bbccb9c7SAndrew Morton { \ 169c8f5c4c7SCristina Ciocan .mixed_funcs = (f), \ 170bbccb9c7SAndrew Morton }, \ 171c8f5c4c7SCristina Ciocan .nfuncs = ARRAY_SIZE((f)), \ 172c8f5c4c7SCristina Ciocan } 173c8f5c4c7SCristina Ciocan 174c8f5c4c7SCristina Ciocan #define FUNCTION(n, g) \ 175c8f5c4c7SCristina Ciocan { \ 176c8f5c4c7SCristina Ciocan .name = (n), \ 177c8f5c4c7SCristina Ciocan .groups = (g), \ 178c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE((g)), \ 179c8f5c4c7SCristina Ciocan } 180c8f5c4c7SCristina Ciocan 181c8f5c4c7SCristina Ciocan #define COMMUNITY(p, n, map) \ 182c8f5c4c7SCristina Ciocan { \ 183c8f5c4c7SCristina Ciocan .pin_base = (p), \ 184c8f5c4c7SCristina Ciocan .npins = (n), \ 185c8f5c4c7SCristina Ciocan .pad_map = (map),\ 186c8f5c4c7SCristina Ciocan } 187c8f5c4c7SCristina Ciocan 188c8f5c4c7SCristina Ciocan struct byt_pinctrl_soc_data { 189c8f5c4c7SCristina Ciocan const char *uid; 190c8f5c4c7SCristina Ciocan const struct pinctrl_pin_desc *pins; 191c8f5c4c7SCristina Ciocan size_t npins; 192c8f5c4c7SCristina Ciocan const struct byt_pingroup *groups; 193c8f5c4c7SCristina Ciocan size_t ngroups; 194c8f5c4c7SCristina Ciocan const struct byt_function *functions; 195c8f5c4c7SCristina Ciocan size_t nfunctions; 196c8f5c4c7SCristina Ciocan const struct byt_community *communities; 197c8f5c4c7SCristina Ciocan size_t ncommunities; 198c8f5c4c7SCristina Ciocan }; 199c8f5c4c7SCristina Ciocan 20071e6ca61SCristina Ciocan struct byt_gpio { 20171e6ca61SCristina Ciocan struct gpio_chip chip; 20271e6ca61SCristina Ciocan struct platform_device *pdev; 20371e6ca61SCristina Ciocan struct pinctrl_dev *pctl_dev; 20471e6ca61SCristina Ciocan struct pinctrl_desc pctl_desc; 20571e6ca61SCristina Ciocan raw_spinlock_t lock; 20671e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data; 20771e6ca61SCristina Ciocan struct byt_community *communities_copy; 20871e6ca61SCristina Ciocan struct byt_gpio_pin_context *saved_context; 20971e6ca61SCristina Ciocan }; 21071e6ca61SCristina Ciocan 211c8f5c4c7SCristina Ciocan /* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ 212c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_score_pins[] = { 213c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "SATA_GP0"), 214c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "SATA_GP1"), 215c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "SATA_LED#"), 216c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "PCIE_CLKREQ0"), 217c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "PCIE_CLKREQ1"), 218c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "PCIE_CLKREQ2"), 219c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "PCIE_CLKREQ3"), 220c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "SD3_WP"), 221c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "HDA_RST"), 222c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "HDA_SYNC"), 223c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "HDA_CLK"), 224c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "HDA_SDO"), 225c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "HDA_SDI0"), 226c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "HDA_SDI1"), 227c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_S0_SC14"), 228c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_S0_SC15"), 229c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "MMC1_CLK"), 230c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "MMC1_D0"), 231c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "MMC1_D1"), 232c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "MMC1_D2"), 233c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "MMC1_D3"), 234c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "MMC1_D4"), 235c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "MMC1_D5"), 236c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "MMC1_D6"), 237c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "MMC1_D7"), 238c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "MMC1_CMD"), 239c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "MMC1_RST"), 240c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "SD2_CLK"), 241c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "SD2_D0"), 242c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "SD2_D1"), 243c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "SD2_D2"), 244c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "SD2_D3_CD"), 245c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "SD2_CMD"), 246c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "SD3_CLK"), 247c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "SD3_D0"), 248c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "SD3_D1"), 249c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "SD3_D2"), 250c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "SD3_D3"), 251c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "SD3_CD"), 252c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "SD3_CMD"), 253c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "SD3_1P8EN"), 254c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "SD3_PWREN#"), 255c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "ILB_LPC_AD0"), 256c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "ILB_LPC_AD1"), 257c8f5c4c7SCristina Ciocan PINCTRL_PIN(44, "ILB_LPC_AD2"), 258c8f5c4c7SCristina Ciocan PINCTRL_PIN(45, "ILB_LPC_AD3"), 259c8f5c4c7SCristina Ciocan PINCTRL_PIN(46, "ILB_LPC_FRAME"), 260c8f5c4c7SCristina Ciocan PINCTRL_PIN(47, "ILB_LPC_CLK0"), 261c8f5c4c7SCristina Ciocan PINCTRL_PIN(48, "ILB_LPC_CLK1"), 262c8f5c4c7SCristina Ciocan PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), 263c8f5c4c7SCristina Ciocan PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), 264c8f5c4c7SCristina Ciocan PINCTRL_PIN(51, "PCU_SMB_DATA"), 265c8f5c4c7SCristina Ciocan PINCTRL_PIN(52, "PCU_SMB_CLK"), 266c8f5c4c7SCristina Ciocan PINCTRL_PIN(53, "PCU_SMB_ALERT"), 267c8f5c4c7SCristina Ciocan PINCTRL_PIN(54, "ILB_8254_SPKR"), 268c8f5c4c7SCristina Ciocan PINCTRL_PIN(55, "GPIO_S0_SC55"), 269c8f5c4c7SCristina Ciocan PINCTRL_PIN(56, "GPIO_S0_SC56"), 270c8f5c4c7SCristina Ciocan PINCTRL_PIN(57, "GPIO_S0_SC57"), 271c8f5c4c7SCristina Ciocan PINCTRL_PIN(58, "GPIO_S0_SC58"), 272c8f5c4c7SCristina Ciocan PINCTRL_PIN(59, "GPIO_S0_SC59"), 273c8f5c4c7SCristina Ciocan PINCTRL_PIN(60, "GPIO_S0_SC60"), 274c8f5c4c7SCristina Ciocan PINCTRL_PIN(61, "GPIO_S0_SC61"), 275c8f5c4c7SCristina Ciocan PINCTRL_PIN(62, "LPE_I2S2_CLK"), 276c8f5c4c7SCristina Ciocan PINCTRL_PIN(63, "LPE_I2S2_FRM"), 277c8f5c4c7SCristina Ciocan PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), 278c8f5c4c7SCristina Ciocan PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), 279c8f5c4c7SCristina Ciocan PINCTRL_PIN(66, "SIO_SPI_CS"), 280c8f5c4c7SCristina Ciocan PINCTRL_PIN(67, "SIO_SPI_MISO"), 281c8f5c4c7SCristina Ciocan PINCTRL_PIN(68, "SIO_SPI_MOSI"), 282c8f5c4c7SCristina Ciocan PINCTRL_PIN(69, "SIO_SPI_CLK"), 283c8f5c4c7SCristina Ciocan PINCTRL_PIN(70, "SIO_UART1_RXD"), 284c8f5c4c7SCristina Ciocan PINCTRL_PIN(71, "SIO_UART1_TXD"), 285c8f5c4c7SCristina Ciocan PINCTRL_PIN(72, "SIO_UART1_RTS"), 286c8f5c4c7SCristina Ciocan PINCTRL_PIN(73, "SIO_UART1_CTS"), 287c8f5c4c7SCristina Ciocan PINCTRL_PIN(74, "SIO_UART2_RXD"), 288c8f5c4c7SCristina Ciocan PINCTRL_PIN(75, "SIO_UART2_TXD"), 289c8f5c4c7SCristina Ciocan PINCTRL_PIN(76, "SIO_UART2_RTS"), 290c8f5c4c7SCristina Ciocan PINCTRL_PIN(77, "SIO_UART2_CTS"), 291c8f5c4c7SCristina Ciocan PINCTRL_PIN(78, "SIO_I2C0_DATA"), 292c8f5c4c7SCristina Ciocan PINCTRL_PIN(79, "SIO_I2C0_CLK"), 293c8f5c4c7SCristina Ciocan PINCTRL_PIN(80, "SIO_I2C1_DATA"), 294c8f5c4c7SCristina Ciocan PINCTRL_PIN(81, "SIO_I2C1_CLK"), 295c8f5c4c7SCristina Ciocan PINCTRL_PIN(82, "SIO_I2C2_DATA"), 296c8f5c4c7SCristina Ciocan PINCTRL_PIN(83, "SIO_I2C2_CLK"), 297c8f5c4c7SCristina Ciocan PINCTRL_PIN(84, "SIO_I2C3_DATA"), 298c8f5c4c7SCristina Ciocan PINCTRL_PIN(85, "SIO_I2C3_CLK"), 299c8f5c4c7SCristina Ciocan PINCTRL_PIN(86, "SIO_I2C4_DATA"), 300c8f5c4c7SCristina Ciocan PINCTRL_PIN(87, "SIO_I2C4_CLK"), 301c8f5c4c7SCristina Ciocan PINCTRL_PIN(88, "SIO_I2C5_DATA"), 302c8f5c4c7SCristina Ciocan PINCTRL_PIN(89, "SIO_I2C5_CLK"), 303c8f5c4c7SCristina Ciocan PINCTRL_PIN(90, "SIO_I2C6_DATA"), 304c8f5c4c7SCristina Ciocan PINCTRL_PIN(91, "SIO_I2C6_CLK"), 305c8f5c4c7SCristina Ciocan PINCTRL_PIN(92, "GPIO_S0_SC92"), 306c8f5c4c7SCristina Ciocan PINCTRL_PIN(93, "GPIO_S0_SC93"), 307c8f5c4c7SCristina Ciocan PINCTRL_PIN(94, "SIO_PWM0"), 308c8f5c4c7SCristina Ciocan PINCTRL_PIN(95, "SIO_PWM1"), 309c8f5c4c7SCristina Ciocan PINCTRL_PIN(96, "PMC_PLT_CLK0"), 310c8f5c4c7SCristina Ciocan PINCTRL_PIN(97, "PMC_PLT_CLK1"), 311c8f5c4c7SCristina Ciocan PINCTRL_PIN(98, "PMC_PLT_CLK2"), 312c8f5c4c7SCristina Ciocan PINCTRL_PIN(99, "PMC_PLT_CLK3"), 313c8f5c4c7SCristina Ciocan PINCTRL_PIN(100, "PMC_PLT_CLK4"), 314c8f5c4c7SCristina Ciocan PINCTRL_PIN(101, "PMC_PLT_CLK5"), 315c8f5c4c7SCristina Ciocan }; 3165fae8b86SMika Westerberg 317c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { 318c8f5c4c7SCristina Ciocan 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 319c8f5c4c7SCristina Ciocan 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, 320c8f5c4c7SCristina Ciocan 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, 321c8f5c4c7SCristina Ciocan 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 322c8f5c4c7SCristina Ciocan 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, 323c8f5c4c7SCristina Ciocan 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, 324c8f5c4c7SCristina Ciocan 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 325c8f5c4c7SCristina Ciocan 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, 326c8f5c4c7SCristina Ciocan 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 327c8f5c4c7SCristina Ciocan 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, 328c8f5c4c7SCristina Ciocan 97, 100, 3295fae8b86SMika Westerberg }; 3305fae8b86SMika Westerberg 331c8f5c4c7SCristina Ciocan /* SCORE groups */ 332c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; 333c8f5c4c7SCristina Ciocan static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; 334c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_uart_mux[] = { 335c8f5c4c7SCristina Ciocan SIMPLE_FUNC("uart", 1), 336c8f5c4c7SCristina Ciocan }; 337c8f5c4c7SCristina Ciocan 338c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm0_pins[] = { 94 }; 339c8f5c4c7SCristina Ciocan static const unsigned int byt_score_pwm1_pins[] = { 95 }; 340c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_pwm_mux[] = { 341c8f5c4c7SCristina Ciocan SIMPLE_FUNC("pwm", 1), 342c8f5c4c7SCristina Ciocan }; 343c8f5c4c7SCristina Ciocan 344c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; 345c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_spi_mux[] = { 346c8f5c4c7SCristina Ciocan SIMPLE_FUNC("spi", 1), 347c8f5c4c7SCristina Ciocan }; 348c8f5c4c7SCristina Ciocan 349c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; 350c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; 351c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; 352c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; 353c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; 354c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; 355c8f5c4c7SCristina Ciocan static const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; 356c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_i2c_mux[] = { 357c8f5c4c7SCristina Ciocan SIMPLE_FUNC("i2c", 1), 358c8f5c4c7SCristina Ciocan }; 359c8f5c4c7SCristina Ciocan 360c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; 361c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; 362c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; 363c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_ssp_mux[] = { 364c8f5c4c7SCristina Ciocan SIMPLE_FUNC("ssp", 1), 365c8f5c4c7SCristina Ciocan }; 366c8f5c4c7SCristina Ciocan 367c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdcard_pins[] = { 368c8f5c4c7SCristina Ciocan 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 369c8f5c4c7SCristina Ciocan }; 370c8f5c4c7SCristina Ciocan static const unsigned short byt_score_sdcard_mux_values[] = { 371c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 372c8f5c4c7SCristina Ciocan }; 373c8f5c4c7SCristina Ciocan static const struct byt_mixed_func_mux byt_score_sdcard_mux[] = { 374c8f5c4c7SCristina Ciocan MIXED_FUNC("sdcard", byt_score_sdcard_mux_values), 375c8f5c4c7SCristina Ciocan }; 376c8f5c4c7SCristina Ciocan 377c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; 378c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_sdio_mux[] = { 379c8f5c4c7SCristina Ciocan SIMPLE_FUNC("sdio", 1), 380c8f5c4c7SCristina Ciocan }; 381c8f5c4c7SCristina Ciocan 382c8f5c4c7SCristina Ciocan static const unsigned int byt_score_emmc_pins[] = { 383c8f5c4c7SCristina Ciocan 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 384c8f5c4c7SCristina Ciocan }; 385c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_emmc_mux[] = { 386c8f5c4c7SCristina Ciocan SIMPLE_FUNC("emmc", 1), 387c8f5c4c7SCristina Ciocan }; 388c8f5c4c7SCristina Ciocan 389c8f5c4c7SCristina Ciocan static const unsigned int byt_score_ilb_lpc_pins[] = { 390c8f5c4c7SCristina Ciocan 42, 43, 44, 45, 46, 47, 48, 49, 50, 391c8f5c4c7SCristina Ciocan }; 392c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_lpc_mux[] = { 393c8f5c4c7SCristina Ciocan SIMPLE_FUNC("lpc", 1), 394c8f5c4c7SCristina Ciocan }; 395c8f5c4c7SCristina Ciocan 396c8f5c4c7SCristina Ciocan static const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; 397c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_sata_mux[] = { 398c8f5c4c7SCristina Ciocan SIMPLE_FUNC("sata", 1), 399c8f5c4c7SCristina Ciocan }; 400c8f5c4c7SCristina Ciocan 401c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk0_pins[] = { 96 }; 402c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk1_pins[] = { 97 }; 403c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk2_pins[] = { 98 }; 404c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk4_pins[] = { 99 }; 405c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk5_pins[] = { 100 }; 406c8f5c4c7SCristina Ciocan static const unsigned int byt_score_plt_clk3_pins[] = { 101 }; 407c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_plt_clk_mux[] = { 408c8f5c4c7SCristina Ciocan SIMPLE_FUNC("plt_clk", 1), 409c8f5c4c7SCristina Ciocan }; 410c8f5c4c7SCristina Ciocan 411c8f5c4c7SCristina Ciocan static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; 412c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_score_smbus_mux[] = { 413c8f5c4c7SCristina Ciocan SIMPLE_FUNC("smbus", 1), 414c8f5c4c7SCristina Ciocan }; 415c8f5c4c7SCristina Ciocan 416c8f5c4c7SCristina Ciocan static const struct byt_pingroup byt_score_groups[] = { 417c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("uart1_grp", 418c8f5c4c7SCristina Ciocan byt_score_uart1_pins, byt_score_uart_mux), 419c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("uart2_grp", 420c8f5c4c7SCristina Ciocan byt_score_uart2_pins, byt_score_uart_mux), 421c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pwm0_grp", 422c8f5c4c7SCristina Ciocan byt_score_pwm0_pins, byt_score_pwm_mux), 423c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pwm1_grp", 424c8f5c4c7SCristina Ciocan byt_score_pwm1_pins, byt_score_pwm_mux), 425c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp2_grp", 426c8f5c4c7SCristina Ciocan byt_score_ssp2_pins, byt_score_pwm_mux), 427c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sio_spi_grp", 428c8f5c4c7SCristina Ciocan byt_score_sio_spi_pins, byt_score_spi_mux), 429c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c5_grp", 430c8f5c4c7SCristina Ciocan byt_score_i2c5_pins, byt_score_i2c_mux), 431c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c6_grp", 432c8f5c4c7SCristina Ciocan byt_score_i2c6_pins, byt_score_i2c_mux), 433c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c4_grp", 434c8f5c4c7SCristina Ciocan byt_score_i2c4_pins, byt_score_i2c_mux), 435c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c3_grp", 436c8f5c4c7SCristina Ciocan byt_score_i2c3_pins, byt_score_i2c_mux), 437c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c2_grp", 438c8f5c4c7SCristina Ciocan byt_score_i2c2_pins, byt_score_i2c_mux), 439c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c1_grp", 440c8f5c4c7SCristina Ciocan byt_score_i2c1_pins, byt_score_i2c_mux), 441c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("i2c0_grp", 442c8f5c4c7SCristina Ciocan byt_score_i2c0_pins, byt_score_i2c_mux), 443c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp0_grp", 444c8f5c4c7SCristina Ciocan byt_score_ssp0_pins, byt_score_ssp_mux), 445c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("ssp1_grp", 446c8f5c4c7SCristina Ciocan byt_score_ssp1_pins, byt_score_ssp_mux), 447c8f5c4c7SCristina Ciocan PIN_GROUP_MIXED("sdcard_grp", 448c8f5c4c7SCristina Ciocan byt_score_sdcard_pins, byt_score_sdcard_mux), 449c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sdio_grp", 450c8f5c4c7SCristina Ciocan byt_score_sdio_pins, byt_score_sdio_mux), 451c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("emmc_grp", 452c8f5c4c7SCristina Ciocan byt_score_emmc_pins, byt_score_emmc_mux), 453c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("lpc_grp", 454c8f5c4c7SCristina Ciocan byt_score_ilb_lpc_pins, byt_score_lpc_mux), 455c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("sata_grp", 456c8f5c4c7SCristina Ciocan byt_score_sata_pins, byt_score_sata_mux), 457c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk0_grp", 458c8f5c4c7SCristina Ciocan byt_score_plt_clk0_pins, byt_score_plt_clk_mux), 459c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk1_grp", 460c8f5c4c7SCristina Ciocan byt_score_plt_clk1_pins, byt_score_plt_clk_mux), 461c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk2_grp", 462c8f5c4c7SCristina Ciocan byt_score_plt_clk2_pins, byt_score_plt_clk_mux), 463c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk3_grp", 464c8f5c4c7SCristina Ciocan byt_score_plt_clk3_pins, byt_score_plt_clk_mux), 465c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk4_grp", 466c8f5c4c7SCristina Ciocan byt_score_plt_clk4_pins, byt_score_plt_clk_mux), 467c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("plt_clk5_grp", 468c8f5c4c7SCristina Ciocan byt_score_plt_clk5_pins, byt_score_plt_clk_mux), 469c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("smbus_grp", 470c8f5c4c7SCristina Ciocan byt_score_smbus_pins, byt_score_smbus_mux), 471c8f5c4c7SCristina Ciocan }; 472c8f5c4c7SCristina Ciocan 473c8f5c4c7SCristina Ciocan static const char * const byt_score_uart_groups[] = { 474c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", 475c8f5c4c7SCristina Ciocan }; 476c8f5c4c7SCristina Ciocan static const char * const byt_score_pwm_groups[] = { 477c8f5c4c7SCristina Ciocan "pwm0_grp", "pwm1_grp", 478c8f5c4c7SCristina Ciocan }; 479c8f5c4c7SCristina Ciocan static const char * const byt_score_ssp_groups[] = { 480c8f5c4c7SCristina Ciocan "ssp0_grp", "ssp1_grp", "ssp2_grp", 481c8f5c4c7SCristina Ciocan }; 482c8f5c4c7SCristina Ciocan static const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; 483c8f5c4c7SCristina Ciocan static const char * const byt_score_i2c_groups[] = { 484c8f5c4c7SCristina Ciocan "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", 485c8f5c4c7SCristina Ciocan "i2c6_grp", 486c8f5c4c7SCristina Ciocan }; 487c8f5c4c7SCristina Ciocan static const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; 488c8f5c4c7SCristina Ciocan static const char * const byt_score_sdio_groups[] = { "sdio_grp" }; 489c8f5c4c7SCristina Ciocan static const char * const byt_score_emmc_groups[] = { "emmc_grp" }; 490c8f5c4c7SCristina Ciocan static const char * const byt_score_lpc_groups[] = { "lpc_grp" }; 491c8f5c4c7SCristina Ciocan static const char * const byt_score_sata_groups[] = { "sata_grp" }; 492c8f5c4c7SCristina Ciocan static const char * const byt_score_plt_clk_groups[] = { 493c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 494c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", 495c8f5c4c7SCristina Ciocan }; 496c8f5c4c7SCristina Ciocan static const char * const byt_score_smbus_groups[] = { "smbus_grp" }; 497c8f5c4c7SCristina Ciocan static const char * const byt_score_gpio_groups[] = { 498c8f5c4c7SCristina Ciocan "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", 499c8f5c4c7SCristina Ciocan "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", 500c8f5c4c7SCristina Ciocan "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", 501c8f5c4c7SCristina Ciocan "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", 502c8f5c4c7SCristina Ciocan "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 503c8f5c4c7SCristina Ciocan "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", 504c8f5c4c7SCristina Ciocan 505c8f5c4c7SCristina Ciocan }; 506c8f5c4c7SCristina Ciocan 507c8f5c4c7SCristina Ciocan static const struct byt_function byt_score_functions[] = { 508c8f5c4c7SCristina Ciocan FUNCTION("uart", byt_score_uart_groups), 509c8f5c4c7SCristina Ciocan FUNCTION("pwm", byt_score_pwm_groups), 510c8f5c4c7SCristina Ciocan FUNCTION("ssp", byt_score_ssp_groups), 511c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_score_spi_groups), 512c8f5c4c7SCristina Ciocan FUNCTION("i2c", byt_score_i2c_groups), 513c8f5c4c7SCristina Ciocan FUNCTION("sdcard", byt_score_sdcard_groups), 514c8f5c4c7SCristina Ciocan FUNCTION("sdio", byt_score_sdio_groups), 515c8f5c4c7SCristina Ciocan FUNCTION("emmc", byt_score_emmc_groups), 516c8f5c4c7SCristina Ciocan FUNCTION("lpc", byt_score_lpc_groups), 517c8f5c4c7SCristina Ciocan FUNCTION("sata", byt_score_sata_groups), 518c8f5c4c7SCristina Ciocan FUNCTION("plt_clk", byt_score_plt_clk_groups), 519c8f5c4c7SCristina Ciocan FUNCTION("smbus", byt_score_smbus_groups), 520c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_score_gpio_groups), 521c8f5c4c7SCristina Ciocan }; 522c8f5c4c7SCristina Ciocan 523c8f5c4c7SCristina Ciocan static const struct byt_community byt_score_communities[] = { 524c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), 525c8f5c4c7SCristina Ciocan }; 526c8f5c4c7SCristina Ciocan 527c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_score_soc_data = { 528c8f5c4c7SCristina Ciocan .uid = BYT_SCORE_ACPI_UID, 529c8f5c4c7SCristina Ciocan .pins = byt_score_pins, 530c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_score_pins), 531c8f5c4c7SCristina Ciocan .groups = byt_score_groups, 532c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_score_groups), 533c8f5c4c7SCristina Ciocan .functions = byt_score_functions, 534c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_score_functions), 535c8f5c4c7SCristina Ciocan .communities = byt_score_communities, 536c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_score_communities), 537c8f5c4c7SCristina Ciocan }; 538c8f5c4c7SCristina Ciocan 539c8f5c4c7SCristina Ciocan /* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */ 540c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_sus_pins[] = { 541c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_S50"), 542c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_S51"), 543c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_S52"), 544c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_S53"), 545c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_S54"), 546c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_S55"), 547c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_S56"), 548c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_S57"), 549c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_S58"), 550c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_S59"), 551c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_S510"), 552c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), 553c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "PMC_SUSCLK0"), 554c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_S513"), 555c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "USB_ULPI_RST"), 556c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), 557c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "PMC_PWRBTN"), 558c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_S517"), 559c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "PMC_SUS_STAT"), 560c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "USB_OC0"), 561c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "USB_OC1"), 562c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "PCU_SPI_CS1"), 563c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_S522"), 564c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_S523"), 565c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_S524"), 566c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_S525"), 567c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_S526"), 568c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_S527"), 569c8f5c4c7SCristina Ciocan PINCTRL_PIN(28, "GPIO_S528"), 570c8f5c4c7SCristina Ciocan PINCTRL_PIN(29, "GPIO_S529"), 571c8f5c4c7SCristina Ciocan PINCTRL_PIN(30, "GPIO_S530"), 572c8f5c4c7SCristina Ciocan PINCTRL_PIN(31, "USB_ULPI_CLK"), 573c8f5c4c7SCristina Ciocan PINCTRL_PIN(32, "USB_ULPI_DATA0"), 574c8f5c4c7SCristina Ciocan PINCTRL_PIN(33, "USB_ULPI_DATA1"), 575c8f5c4c7SCristina Ciocan PINCTRL_PIN(34, "USB_ULPI_DATA2"), 576c8f5c4c7SCristina Ciocan PINCTRL_PIN(35, "USB_ULPI_DATA3"), 577c8f5c4c7SCristina Ciocan PINCTRL_PIN(36, "USB_ULPI_DATA4"), 578c8f5c4c7SCristina Ciocan PINCTRL_PIN(37, "USB_ULPI_DATA5"), 579c8f5c4c7SCristina Ciocan PINCTRL_PIN(38, "USB_ULPI_DATA6"), 580c8f5c4c7SCristina Ciocan PINCTRL_PIN(39, "USB_ULPI_DATA7"), 581c8f5c4c7SCristina Ciocan PINCTRL_PIN(40, "USB_ULPI_DIR"), 582c8f5c4c7SCristina Ciocan PINCTRL_PIN(41, "USB_ULPI_NXT"), 583c8f5c4c7SCristina Ciocan PINCTRL_PIN(42, "USB_ULPI_STP"), 584c8f5c4c7SCristina Ciocan PINCTRL_PIN(43, "USB_ULPI_REFCLK"), 585c8f5c4c7SCristina Ciocan }; 586c8f5c4c7SCristina Ciocan 587c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 588c8f5c4c7SCristina Ciocan 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 589c8f5c4c7SCristina Ciocan 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, 590c8f5c4c7SCristina Ciocan 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 591c8f5c4c7SCristina Ciocan 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, 592c8f5c4c7SCristina Ciocan 52, 53, 59, 40, 593c8f5c4c7SCristina Ciocan }; 594c8f5c4c7SCristina Ciocan 595c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; 596c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_sus_usb_oc_mux[] = { 597c8f5c4c7SCristina Ciocan SIMPLE_FUNC("usb", 0), 598c8f5c4c7SCristina Ciocan SIMPLE_FUNC("gpio", 1), 599c8f5c4c7SCristina Ciocan }; 600c8f5c4c7SCristina Ciocan 601c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_usb_ulpi_pins[] = { 602c8f5c4c7SCristina Ciocan 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 603c8f5c4c7SCristina Ciocan }; 604c8f5c4c7SCristina Ciocan static const unsigned short byt_sus_usb_ulpi_mode_values[] = { 605c8f5c4c7SCristina Ciocan 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 606c8f5c4c7SCristina Ciocan }; 607c8f5c4c7SCristina Ciocan static const unsigned short byt_sus_usb_ulpi_gpio_mode_values[] = { 608c8f5c4c7SCristina Ciocan 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 609c8f5c4c7SCristina Ciocan }; 610c8f5c4c7SCristina Ciocan static const struct byt_mixed_func_mux byt_sus_usb_ulpi_mux[] = { 611c8f5c4c7SCristina Ciocan MIXED_FUNC("usb", byt_sus_usb_ulpi_mode_values), 612c8f5c4c7SCristina Ciocan MIXED_FUNC("gpio", byt_sus_usb_ulpi_gpio_mode_values), 613c8f5c4c7SCristina Ciocan }; 614c8f5c4c7SCristina Ciocan 615c8f5c4c7SCristina Ciocan static const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; 616c8f5c4c7SCristina Ciocan static const struct byt_simple_func_mux byt_sus_pcu_spi_mux[] = { 617c8f5c4c7SCristina Ciocan SIMPLE_FUNC("spi", 0), 618c8f5c4c7SCristina Ciocan SIMPLE_FUNC("gpio", 1), 619c8f5c4c7SCristina Ciocan }; 620c8f5c4c7SCristina Ciocan 621c8f5c4c7SCristina Ciocan static const struct byt_pingroup byt_sus_groups[] = { 622c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("usb_oc_grp", 623c8f5c4c7SCristina Ciocan byt_sus_usb_over_current_pins, byt_sus_usb_oc_mux), 624c8f5c4c7SCristina Ciocan PIN_GROUP_MIXED("usb_ulpi_grp", 625c8f5c4c7SCristina Ciocan byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mux), 626c8f5c4c7SCristina Ciocan PIN_GROUP_SIMPLE("pcu_spi_grp", 627c8f5c4c7SCristina Ciocan byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mux), 628c8f5c4c7SCristina Ciocan }; 629c8f5c4c7SCristina Ciocan 630c8f5c4c7SCristina Ciocan static const char * const byt_sus_usb_groups[] = { 631c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp", 632c8f5c4c7SCristina Ciocan }; 633c8f5c4c7SCristina Ciocan static const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; 634c8f5c4c7SCristina Ciocan static const char * const byt_sus_gpio_groups[] = { 635c8f5c4c7SCristina Ciocan "usb_oc_grp", "usb_ulpi_grp", "pcu_spi_grp", 636c8f5c4c7SCristina Ciocan }; 637c8f5c4c7SCristina Ciocan 638c8f5c4c7SCristina Ciocan static const struct byt_function byt_sus_functions[] = { 639c8f5c4c7SCristina Ciocan FUNCTION("usb", byt_sus_usb_groups), 640c8f5c4c7SCristina Ciocan FUNCTION("spi", byt_sus_spi_groups), 641c8f5c4c7SCristina Ciocan FUNCTION("gpio", byt_sus_gpio_groups), 642c8f5c4c7SCristina Ciocan }; 643c8f5c4c7SCristina Ciocan 644c8f5c4c7SCristina Ciocan static const struct byt_community byt_sus_communities[] = { 645c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), 646c8f5c4c7SCristina Ciocan }; 647c8f5c4c7SCristina Ciocan 648c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_sus_soc_data = { 649c8f5c4c7SCristina Ciocan .uid = BYT_SUS_ACPI_UID, 650c8f5c4c7SCristina Ciocan .pins = byt_sus_pins, 651c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_sus_pins), 652c8f5c4c7SCristina Ciocan .groups = byt_sus_groups, 653c8f5c4c7SCristina Ciocan .ngroups = ARRAY_SIZE(byt_sus_groups), 654c8f5c4c7SCristina Ciocan .functions = byt_sus_functions, 655c8f5c4c7SCristina Ciocan .nfunctions = ARRAY_SIZE(byt_sus_functions), 656c8f5c4c7SCristina Ciocan .communities = byt_sus_communities, 657c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_sus_communities), 658c8f5c4c7SCristina Ciocan }; 659c8f5c4c7SCristina Ciocan 660c8f5c4c7SCristina Ciocan static const struct pinctrl_pin_desc byt_ncore_pins[] = { 661c8f5c4c7SCristina Ciocan PINCTRL_PIN(0, "GPIO_NCORE0"), 662c8f5c4c7SCristina Ciocan PINCTRL_PIN(1, "GPIO_NCORE1"), 663c8f5c4c7SCristina Ciocan PINCTRL_PIN(2, "GPIO_NCORE2"), 664c8f5c4c7SCristina Ciocan PINCTRL_PIN(3, "GPIO_NCORE3"), 665c8f5c4c7SCristina Ciocan PINCTRL_PIN(4, "GPIO_NCORE4"), 666c8f5c4c7SCristina Ciocan PINCTRL_PIN(5, "GPIO_NCORE5"), 667c8f5c4c7SCristina Ciocan PINCTRL_PIN(6, "GPIO_NCORE6"), 668c8f5c4c7SCristina Ciocan PINCTRL_PIN(7, "GPIO_NCORE7"), 669c8f5c4c7SCristina Ciocan PINCTRL_PIN(8, "GPIO_NCORE8"), 670c8f5c4c7SCristina Ciocan PINCTRL_PIN(9, "GPIO_NCORE9"), 671c8f5c4c7SCristina Ciocan PINCTRL_PIN(10, "GPIO_NCORE10"), 672c8f5c4c7SCristina Ciocan PINCTRL_PIN(11, "GPIO_NCORE11"), 673c8f5c4c7SCristina Ciocan PINCTRL_PIN(12, "GPIO_NCORE12"), 674c8f5c4c7SCristina Ciocan PINCTRL_PIN(13, "GPIO_NCORE13"), 675c8f5c4c7SCristina Ciocan PINCTRL_PIN(14, "GPIO_NCORE14"), 676c8f5c4c7SCristina Ciocan PINCTRL_PIN(15, "GPIO_NCORE15"), 677c8f5c4c7SCristina Ciocan PINCTRL_PIN(16, "GPIO_NCORE16"), 678c8f5c4c7SCristina Ciocan PINCTRL_PIN(17, "GPIO_NCORE17"), 679c8f5c4c7SCristina Ciocan PINCTRL_PIN(18, "GPIO_NCORE18"), 680c8f5c4c7SCristina Ciocan PINCTRL_PIN(19, "GPIO_NCORE19"), 681c8f5c4c7SCristina Ciocan PINCTRL_PIN(20, "GPIO_NCORE20"), 682c8f5c4c7SCristina Ciocan PINCTRL_PIN(21, "GPIO_NCORE21"), 683c8f5c4c7SCristina Ciocan PINCTRL_PIN(22, "GPIO_NCORE22"), 684c8f5c4c7SCristina Ciocan PINCTRL_PIN(23, "GPIO_NCORE23"), 685c8f5c4c7SCristina Ciocan PINCTRL_PIN(24, "GPIO_NCORE24"), 686c8f5c4c7SCristina Ciocan PINCTRL_PIN(25, "GPIO_NCORE25"), 687c8f5c4c7SCristina Ciocan PINCTRL_PIN(26, "GPIO_NCORE26"), 688c8f5c4c7SCristina Ciocan PINCTRL_PIN(27, "GPIO_NCORE27"), 689c8f5c4c7SCristina Ciocan }; 690c8f5c4c7SCristina Ciocan 691c8f5c4c7SCristina Ciocan static unsigned const byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 692c8f5c4c7SCristina Ciocan 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 693c8f5c4c7SCristina Ciocan 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, 694c8f5c4c7SCristina Ciocan 3, 6, 10, 13, 2, 5, 9, 7, 695c8f5c4c7SCristina Ciocan }; 696c8f5c4c7SCristina Ciocan 697c8f5c4c7SCristina Ciocan static const struct byt_community byt_ncore_communities[] = { 698c8f5c4c7SCristina Ciocan COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), 699c8f5c4c7SCristina Ciocan }; 700c8f5c4c7SCristina Ciocan 701c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data byt_ncore_soc_data = { 702c8f5c4c7SCristina Ciocan .uid = BYT_NCORE_ACPI_UID, 703c8f5c4c7SCristina Ciocan .pins = byt_ncore_pins, 704c8f5c4c7SCristina Ciocan .npins = ARRAY_SIZE(byt_ncore_pins), 705c8f5c4c7SCristina Ciocan .communities = byt_ncore_communities, 706c8f5c4c7SCristina Ciocan .ncommunities = ARRAY_SIZE(byt_ncore_communities), 707c8f5c4c7SCristina Ciocan }; 708c8f5c4c7SCristina Ciocan 709c8f5c4c7SCristina Ciocan static const struct byt_pinctrl_soc_data *byt_soc_data[] = { 710c8f5c4c7SCristina Ciocan &byt_score_soc_data, 711c8f5c4c7SCristina Ciocan &byt_sus_soc_data, 712c8f5c4c7SCristina Ciocan &byt_ncore_soc_data, 713c8f5c4c7SCristina Ciocan NULL, 714c8f5c4c7SCristina Ciocan }; 715c8f5c4c7SCristina Ciocan 716c501d0b1SCristina Ciocan static struct byt_community *byt_get_community(struct byt_gpio *vg, 717c501d0b1SCristina Ciocan unsigned int pin) 718c501d0b1SCristina Ciocan { 719c501d0b1SCristina Ciocan struct byt_community *comm; 720c501d0b1SCristina Ciocan int i; 721c501d0b1SCristina Ciocan 722c501d0b1SCristina Ciocan for (i = 0; i < vg->soc_data->ncommunities; i++) { 723c501d0b1SCristina Ciocan comm = vg->communities_copy + i; 724c501d0b1SCristina Ciocan if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) 725c501d0b1SCristina Ciocan return comm; 726c501d0b1SCristina Ciocan } 727c501d0b1SCristina Ciocan 728c501d0b1SCristina Ciocan return NULL; 729c501d0b1SCristina Ciocan } 730c501d0b1SCristina Ciocan 731c501d0b1SCristina Ciocan static void __iomem *byt_gpio_reg(struct byt_gpio *vg, unsigned int offset, 7325fae8b86SMika Westerberg int reg) 7335fae8b86SMika Westerberg { 734c501d0b1SCristina Ciocan struct byt_community *comm = byt_get_community(vg, offset); 735c501d0b1SCristina Ciocan u32 reg_offset = 0; 7365fae8b86SMika Westerberg 737c501d0b1SCristina Ciocan if (!comm) 738c501d0b1SCristina Ciocan return NULL; 739c501d0b1SCristina Ciocan 740c501d0b1SCristina Ciocan offset -= comm->pin_base; 7415fae8b86SMika Westerberg if (reg == BYT_INT_STAT_REG) 7425fae8b86SMika Westerberg reg_offset = (offset / 32) * 4; 7435fae8b86SMika Westerberg else 744c501d0b1SCristina Ciocan reg_offset = comm->pad_map[offset] * 16; 7455fae8b86SMika Westerberg 746c501d0b1SCristina Ciocan return comm->reg_base + reg_offset + reg; 7475fae8b86SMika Westerberg } 7485fae8b86SMika Westerberg 749c501d0b1SCristina Ciocan static int byt_get_groups_count(struct pinctrl_dev *pctldev) 75095f0972cSMika Westerberg { 751c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 752c501d0b1SCristina Ciocan 753c501d0b1SCristina Ciocan return vg->soc_data->ngroups; 754c501d0b1SCristina Ciocan } 755c501d0b1SCristina Ciocan 756c501d0b1SCristina Ciocan static const char *byt_get_group_name(struct pinctrl_dev *pctldev, 757c501d0b1SCristina Ciocan unsigned int selector) 758c501d0b1SCristina Ciocan { 759c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 760c501d0b1SCristina Ciocan 761c501d0b1SCristina Ciocan return vg->soc_data->groups[selector].name; 762c501d0b1SCristina Ciocan } 763c501d0b1SCristina Ciocan 764c501d0b1SCristina Ciocan static int byt_get_group_pins(struct pinctrl_dev *pctldev, 765c501d0b1SCristina Ciocan unsigned int selector, 766c501d0b1SCristina Ciocan const unsigned int **pins, 767c501d0b1SCristina Ciocan unsigned int *num_pins) 768c501d0b1SCristina Ciocan { 769c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 770c501d0b1SCristina Ciocan 771c501d0b1SCristina Ciocan *pins = vg->soc_data->groups[selector].pins; 772c501d0b1SCristina Ciocan *num_pins = vg->soc_data->groups[selector].npins; 773c501d0b1SCristina Ciocan 774c501d0b1SCristina Ciocan return 0; 775c501d0b1SCristina Ciocan } 776c501d0b1SCristina Ciocan 777c501d0b1SCristina Ciocan static const struct pinctrl_ops byt_pinctrl_ops = { 778c501d0b1SCristina Ciocan .get_groups_count = byt_get_groups_count, 779c501d0b1SCristina Ciocan .get_group_name = byt_get_group_name, 780c501d0b1SCristina Ciocan .get_group_pins = byt_get_group_pins, 781c501d0b1SCristina Ciocan }; 782c501d0b1SCristina Ciocan 783c501d0b1SCristina Ciocan static int byt_get_functions_count(struct pinctrl_dev *pctldev) 784c501d0b1SCristina Ciocan { 785c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 786c501d0b1SCristina Ciocan 787c501d0b1SCristina Ciocan return vg->soc_data->nfunctions; 788c501d0b1SCristina Ciocan } 789c501d0b1SCristina Ciocan 790c501d0b1SCristina Ciocan static const char *byt_get_function_name(struct pinctrl_dev *pctldev, 791c501d0b1SCristina Ciocan unsigned int selector) 792c501d0b1SCristina Ciocan { 793c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 794c501d0b1SCristina Ciocan 795c501d0b1SCristina Ciocan return vg->soc_data->functions[selector].name; 796c501d0b1SCristina Ciocan } 797c501d0b1SCristina Ciocan 798c501d0b1SCristina Ciocan static int byt_get_function_groups(struct pinctrl_dev *pctldev, 799c501d0b1SCristina Ciocan unsigned int selector, 800c501d0b1SCristina Ciocan const char * const **groups, 801c501d0b1SCristina Ciocan unsigned int *num_groups) 802c501d0b1SCristina Ciocan { 803c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 804c501d0b1SCristina Ciocan 805c501d0b1SCristina Ciocan *groups = vg->soc_data->functions[selector].groups; 806c501d0b1SCristina Ciocan *num_groups = vg->soc_data->functions[selector].ngroups; 807c501d0b1SCristina Ciocan 808c501d0b1SCristina Ciocan return 0; 809c501d0b1SCristina Ciocan } 810c501d0b1SCristina Ciocan 811c501d0b1SCristina Ciocan static int byt_get_group_simple_mux(const struct byt_pingroup group, 812c501d0b1SCristina Ciocan const char *func_name, 813c501d0b1SCristina Ciocan unsigned short *func) 814c501d0b1SCristina Ciocan { 815c501d0b1SCristina Ciocan int i; 816c501d0b1SCristina Ciocan 817c501d0b1SCristina Ciocan for (i = 0; i < group.nfuncs; i++) { 818c501d0b1SCristina Ciocan if (!strcmp(group.simple_funcs[i].name, func_name)) { 819c501d0b1SCristina Ciocan *func = group.simple_funcs[i].func; 820c501d0b1SCristina Ciocan return 0; 821c501d0b1SCristina Ciocan } 822c501d0b1SCristina Ciocan } 823c501d0b1SCristina Ciocan 824c501d0b1SCristina Ciocan return 1; 825c501d0b1SCristina Ciocan } 826c501d0b1SCristina Ciocan 827c501d0b1SCristina Ciocan static int byt_get_group_mixed_mux(const struct byt_pingroup group, 828c501d0b1SCristina Ciocan const char *func_name, 829c501d0b1SCristina Ciocan const unsigned short **func) 830c501d0b1SCristina Ciocan { 831c501d0b1SCristina Ciocan int i; 832c501d0b1SCristina Ciocan 833c501d0b1SCristina Ciocan for (i = 0; i < group.nfuncs; i++) { 834c501d0b1SCristina Ciocan if (!strcmp(group.mixed_funcs[i].name, func_name)) { 835c501d0b1SCristina Ciocan *func = group.mixed_funcs[i].func_values; 836c501d0b1SCristina Ciocan return 0; 837c501d0b1SCristina Ciocan } 838c501d0b1SCristina Ciocan } 839c501d0b1SCristina Ciocan 840c501d0b1SCristina Ciocan return 1; 841c501d0b1SCristina Ciocan } 842c501d0b1SCristina Ciocan 843c501d0b1SCristina Ciocan static void byt_set_group_simple_mux(struct byt_gpio *vg, 844c501d0b1SCristina Ciocan const struct byt_pingroup group, 845c501d0b1SCristina Ciocan unsigned short func) 846c501d0b1SCristina Ciocan { 847c501d0b1SCristina Ciocan unsigned long flags; 848c501d0b1SCristina Ciocan int i; 849c501d0b1SCristina Ciocan 850c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 851c501d0b1SCristina Ciocan 852c501d0b1SCristina Ciocan for (i = 0; i < group.npins; i++) { 853c501d0b1SCristina Ciocan void __iomem *padcfg0; 854c501d0b1SCristina Ciocan u32 value; 855c501d0b1SCristina Ciocan 856c501d0b1SCristina Ciocan padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 857c501d0b1SCristina Ciocan if (!padcfg0) { 858c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 859c501d0b1SCristina Ciocan "Group %s, pin %i not muxed (no padcfg0)\n", 860c501d0b1SCristina Ciocan group.name, i); 861c501d0b1SCristina Ciocan continue; 862c501d0b1SCristina Ciocan } 863c501d0b1SCristina Ciocan 864c501d0b1SCristina Ciocan value = readl(padcfg0); 865c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 866c501d0b1SCristina Ciocan value |= func; 867c501d0b1SCristina Ciocan writel(value, padcfg0); 868c501d0b1SCristina Ciocan } 869c501d0b1SCristina Ciocan 870c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 871c501d0b1SCristina Ciocan } 872c501d0b1SCristina Ciocan 873c501d0b1SCristina Ciocan static void byt_set_group_mixed_mux(struct byt_gpio *vg, 874c501d0b1SCristina Ciocan const struct byt_pingroup group, 875c501d0b1SCristina Ciocan const unsigned short *func) 876c501d0b1SCristina Ciocan { 877c501d0b1SCristina Ciocan unsigned long flags; 878c501d0b1SCristina Ciocan int i; 879c501d0b1SCristina Ciocan 880c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 881c501d0b1SCristina Ciocan 882c501d0b1SCristina Ciocan for (i = 0; i < group.npins; i++) { 883c501d0b1SCristina Ciocan void __iomem *padcfg0; 884c501d0b1SCristina Ciocan u32 value; 885c501d0b1SCristina Ciocan 886c501d0b1SCristina Ciocan padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 887c501d0b1SCristina Ciocan if (!padcfg0) { 888c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 889c501d0b1SCristina Ciocan "Group %s, pin %i not muxed (no padcfg0)\n", 890c501d0b1SCristina Ciocan group.name, i); 891c501d0b1SCristina Ciocan continue; 892c501d0b1SCristina Ciocan } 893c501d0b1SCristina Ciocan 894c501d0b1SCristina Ciocan value = readl(padcfg0); 895c501d0b1SCristina Ciocan value &= ~BYT_PIN_MUX; 896c501d0b1SCristina Ciocan value |= func[i]; 897c501d0b1SCristina Ciocan writel(value, padcfg0); 898c501d0b1SCristina Ciocan } 899c501d0b1SCristina Ciocan 900c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 901c501d0b1SCristina Ciocan } 902c501d0b1SCristina Ciocan 903c501d0b1SCristina Ciocan static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 904c501d0b1SCristina Ciocan unsigned int group_selector) 905c501d0b1SCristina Ciocan { 906c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctldev); 907c501d0b1SCristina Ciocan const struct byt_function func = vg->soc_data->functions[func_selector]; 908c501d0b1SCristina Ciocan const struct byt_pingroup group = vg->soc_data->groups[group_selector]; 909c501d0b1SCristina Ciocan const unsigned short *mixed_func; 910c501d0b1SCristina Ciocan unsigned short simple_func; 911c501d0b1SCristina Ciocan int ret = 1; 912c501d0b1SCristina Ciocan 913c501d0b1SCristina Ciocan if (group.has_simple_funcs) 914c501d0b1SCristina Ciocan ret = byt_get_group_simple_mux(group, func.name, &simple_func); 915c501d0b1SCristina Ciocan else 916c501d0b1SCristina Ciocan ret = byt_get_group_mixed_mux(group, func.name, &mixed_func); 917c501d0b1SCristina Ciocan 918c501d0b1SCristina Ciocan if (ret) 919c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); 920c501d0b1SCristina Ciocan else if (group.has_simple_funcs) 921c501d0b1SCristina Ciocan byt_set_group_simple_mux(vg, group, simple_func); 922c501d0b1SCristina Ciocan else 923c501d0b1SCristina Ciocan byt_set_group_mixed_mux(vg, group, mixed_func); 924c501d0b1SCristina Ciocan 925c501d0b1SCristina Ciocan return 0; 926c501d0b1SCristina Ciocan } 927c501d0b1SCristina Ciocan 928c501d0b1SCristina Ciocan static u32 byt_get_gpio_mux(struct byt_gpio *vg, unsigned offset) 929c501d0b1SCristina Ciocan { 930c501d0b1SCristina Ciocan /* SCORE pin 92-93 */ 931c501d0b1SCristina Ciocan if (!strcmp(vg->soc_data->uid, BYT_SCORE_ACPI_UID) && 932c501d0b1SCristina Ciocan offset >= 92 && offset <= 93) 933c501d0b1SCristina Ciocan return 1; 934c501d0b1SCristina Ciocan 935c501d0b1SCristina Ciocan /* SUS pin 11-21 */ 936c501d0b1SCristina Ciocan if (!strcmp(vg->soc_data->uid, BYT_SUS_ACPI_UID) && 937c501d0b1SCristina Ciocan offset >= 11 && offset <= 21) 938c501d0b1SCristina Ciocan return 1; 939c501d0b1SCristina Ciocan 940c501d0b1SCristina Ciocan return 0; 941c501d0b1SCristina Ciocan } 942c501d0b1SCristina Ciocan 943c501d0b1SCristina Ciocan static void byt_gpio_clear_triggering(struct byt_gpio *vg, unsigned int offset) 944c501d0b1SCristina Ciocan { 945c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 94695f0972cSMika Westerberg unsigned long flags; 94795f0972cSMika Westerberg u32 value; 94895f0972cSMika Westerberg 94978e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 95095f0972cSMika Westerberg value = readl(reg); 95195f0972cSMika Westerberg value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); 95295f0972cSMika Westerberg writel(value, reg); 95378e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 95495f0972cSMika Westerberg } 95595f0972cSMika Westerberg 956c501d0b1SCristina Ciocan static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, 957c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 958c501d0b1SCristina Ciocan unsigned int offset) 9595fae8b86SMika Westerberg { 960c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 961c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 962f8323b6bSMika Westerberg u32 value, gpio_mux; 96339ce8150SMika Westerberg unsigned long flags; 96439ce8150SMika Westerberg 96578e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 9665fae8b86SMika Westerberg 9675fae8b86SMika Westerberg /* 9685fae8b86SMika Westerberg * In most cases, func pin mux 000 means GPIO function. 9695fae8b86SMika Westerberg * But, some pins may have func pin mux 001 represents 970f8323b6bSMika Westerberg * GPIO function. 971f8323b6bSMika Westerberg * 972f8323b6bSMika Westerberg * Because there are devices out there where some pins were not 973f8323b6bSMika Westerberg * configured correctly we allow changing the mux value from 974f8323b6bSMika Westerberg * request (but print out warning about that). 9755fae8b86SMika Westerberg */ 9765fae8b86SMika Westerberg value = readl(reg) & BYT_PIN_MUX; 977f8323b6bSMika Westerberg gpio_mux = byt_get_gpio_mux(vg, offset); 978f8323b6bSMika Westerberg if (WARN_ON(gpio_mux != value)) { 979f8323b6bSMika Westerberg value = readl(reg) & ~BYT_PIN_MUX; 980f8323b6bSMika Westerberg value |= gpio_mux; 981f8323b6bSMika Westerberg writel(value, reg); 982f8323b6bSMika Westerberg 983f8323b6bSMika Westerberg dev_warn(&vg->pdev->dev, 984f8323b6bSMika Westerberg "pin %u forcibly re-configured as GPIO\n", offset); 9855fae8b86SMika Westerberg } 9865fae8b86SMika Westerberg 98778e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 98839ce8150SMika Westerberg 9895fae8b86SMika Westerberg pm_runtime_get(&vg->pdev->dev); 9905fae8b86SMika Westerberg 9915fae8b86SMika Westerberg return 0; 9925fae8b86SMika Westerberg } 9935fae8b86SMika Westerberg 994c501d0b1SCristina Ciocan static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, 995c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 996c501d0b1SCristina Ciocan unsigned int offset) 997c501d0b1SCristina Ciocan { 998c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 999c501d0b1SCristina Ciocan 1000c501d0b1SCristina Ciocan byt_gpio_clear_triggering(vg, offset); 1001c501d0b1SCristina Ciocan pm_runtime_put(&vg->pdev->dev); 1002c501d0b1SCristina Ciocan } 1003c501d0b1SCristina Ciocan 1004c501d0b1SCristina Ciocan static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, 1005c501d0b1SCristina Ciocan struct pinctrl_gpio_range *range, 1006c501d0b1SCristina Ciocan unsigned int offset, 1007c501d0b1SCristina Ciocan bool input) 1008c501d0b1SCristina Ciocan { 1009c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1010c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 1011c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1012c501d0b1SCristina Ciocan unsigned long flags; 1013c501d0b1SCristina Ciocan u32 value; 1014c501d0b1SCristina Ciocan 1015c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1016c501d0b1SCristina Ciocan 1017c501d0b1SCristina Ciocan value = readl(val_reg); 1018c501d0b1SCristina Ciocan value &= ~BYT_DIR_MASK; 1019c501d0b1SCristina Ciocan if (input) 1020c501d0b1SCristina Ciocan value |= BYT_OUTPUT_EN; 1021c501d0b1SCristina Ciocan else 1022c501d0b1SCristina Ciocan /* 1023c501d0b1SCristina Ciocan * Before making any direction modifications, do a check if gpio 1024c501d0b1SCristina Ciocan * is set for direct IRQ. On baytrail, setting GPIO to output 1025c501d0b1SCristina Ciocan * does not make sense, so let's at least warn the caller before 1026c501d0b1SCristina Ciocan * they shoot themselves in the foot. 1027c501d0b1SCristina Ciocan */ 1028c501d0b1SCristina Ciocan WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, 1029c501d0b1SCristina Ciocan "Potential Error: Setting GPIO with direct_irq_en to output"); 1030c501d0b1SCristina Ciocan writel(value, val_reg); 1031c501d0b1SCristina Ciocan 1032c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1033c501d0b1SCristina Ciocan 1034c501d0b1SCristina Ciocan return 0; 1035c501d0b1SCristina Ciocan } 1036c501d0b1SCristina Ciocan 1037c501d0b1SCristina Ciocan static const struct pinmux_ops byt_pinmux_ops = { 1038c501d0b1SCristina Ciocan .get_functions_count = byt_get_functions_count, 1039c501d0b1SCristina Ciocan .get_function_name = byt_get_function_name, 1040c501d0b1SCristina Ciocan .get_function_groups = byt_get_function_groups, 1041c501d0b1SCristina Ciocan .set_mux = byt_set_mux, 1042c501d0b1SCristina Ciocan .gpio_request_enable = byt_gpio_request_enable, 1043c501d0b1SCristina Ciocan .gpio_disable_free = byt_gpio_disable_free, 1044c501d0b1SCristina Ciocan .gpio_set_direction = byt_gpio_set_direction, 1045c501d0b1SCristina Ciocan }; 1046c501d0b1SCristina Ciocan 1047c501d0b1SCristina Ciocan static void byt_get_pull_strength(u32 reg, u16 *strength) 1048c501d0b1SCristina Ciocan { 1049c501d0b1SCristina Ciocan switch (reg & BYT_PULL_STR_MASK) { 1050c501d0b1SCristina Ciocan case BYT_PULL_STR_2K: 1051c501d0b1SCristina Ciocan *strength = 2000; 1052c501d0b1SCristina Ciocan break; 1053c501d0b1SCristina Ciocan case BYT_PULL_STR_10K: 1054c501d0b1SCristina Ciocan *strength = 10000; 1055c501d0b1SCristina Ciocan break; 1056c501d0b1SCristina Ciocan case BYT_PULL_STR_20K: 1057c501d0b1SCristina Ciocan *strength = 20000; 1058c501d0b1SCristina Ciocan break; 1059c501d0b1SCristina Ciocan case BYT_PULL_STR_40K: 1060c501d0b1SCristina Ciocan *strength = 40000; 1061c501d0b1SCristina Ciocan break; 1062c501d0b1SCristina Ciocan } 1063c501d0b1SCristina Ciocan } 1064c501d0b1SCristina Ciocan 1065c501d0b1SCristina Ciocan static int byt_set_pull_strength(u32 *reg, u16 strength) 1066c501d0b1SCristina Ciocan { 1067c501d0b1SCristina Ciocan *reg &= ~BYT_PULL_STR_MASK; 1068c501d0b1SCristina Ciocan 1069c501d0b1SCristina Ciocan switch (strength) { 1070c501d0b1SCristina Ciocan case 2000: 1071c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_2K; 1072c501d0b1SCristina Ciocan break; 1073c501d0b1SCristina Ciocan case 10000: 1074c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_10K; 1075c501d0b1SCristina Ciocan break; 1076c501d0b1SCristina Ciocan case 20000: 1077c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_20K; 1078c501d0b1SCristina Ciocan break; 1079c501d0b1SCristina Ciocan case 40000: 1080c501d0b1SCristina Ciocan *reg |= BYT_PULL_STR_40K; 1081c501d0b1SCristina Ciocan break; 1082c501d0b1SCristina Ciocan default: 1083c501d0b1SCristina Ciocan return -EINVAL; 1084c501d0b1SCristina Ciocan } 1085c501d0b1SCristina Ciocan 1086c501d0b1SCristina Ciocan return 0; 1087c501d0b1SCristina Ciocan } 1088c501d0b1SCristina Ciocan 1089c501d0b1SCristina Ciocan static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, 1090c501d0b1SCristina Ciocan unsigned long *config) 1091c501d0b1SCristina Ciocan { 1092c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1093c501d0b1SCristina Ciocan enum pin_config_param param = pinconf_to_config_param(*config); 1094c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1095c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 1096c501d0b1SCristina Ciocan unsigned long flags; 1097658b476cSCristina Ciocan u32 conf, pull, val, debounce; 1098c501d0b1SCristina Ciocan u16 arg = 0; 1099c501d0b1SCristina Ciocan 1100c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1101c501d0b1SCristina Ciocan conf = readl(conf_reg); 1102c501d0b1SCristina Ciocan pull = conf & BYT_PULL_ASSIGN_MASK; 1103c501d0b1SCristina Ciocan val = readl(val_reg); 1104c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1105c501d0b1SCristina Ciocan 1106c501d0b1SCristina Ciocan switch (param) { 1107c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 1108c501d0b1SCristina Ciocan if (pull) 1109c501d0b1SCristina Ciocan return -EINVAL; 1110c501d0b1SCristina Ciocan break; 1111c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 1112c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 1113c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) 1114c501d0b1SCristina Ciocan return -EINVAL; 1115c501d0b1SCristina Ciocan 1116c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 1117c501d0b1SCristina Ciocan 1118c501d0b1SCristina Ciocan break; 1119c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 1120c501d0b1SCristina Ciocan /* Pull assignment is only applicable in input mode */ 1121c501d0b1SCristina Ciocan if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) 1122c501d0b1SCristina Ciocan return -EINVAL; 1123c501d0b1SCristina Ciocan 1124c501d0b1SCristina Ciocan byt_get_pull_strength(conf, &arg); 1125c501d0b1SCristina Ciocan 1126c501d0b1SCristina Ciocan break; 1127658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 1128658b476cSCristina Ciocan if (!(conf & BYT_DEBOUNCE_EN)) 1129658b476cSCristina Ciocan return -EINVAL; 1130658b476cSCristina Ciocan 1131658b476cSCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1132658b476cSCristina Ciocan debounce = readl(byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG)); 1133658b476cSCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1134658b476cSCristina Ciocan 1135658b476cSCristina Ciocan switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { 1136658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_375US: 1137658b476cSCristina Ciocan arg = 375; 1138658b476cSCristina Ciocan break; 1139658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_750US: 1140658b476cSCristina Ciocan arg = 750; 1141658b476cSCristina Ciocan break; 1142658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_1500US: 1143658b476cSCristina Ciocan arg = 1500; 1144658b476cSCristina Ciocan break; 1145658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_3MS: 1146658b476cSCristina Ciocan arg = 3000; 1147658b476cSCristina Ciocan break; 1148658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_6MS: 1149658b476cSCristina Ciocan arg = 6000; 1150658b476cSCristina Ciocan break; 1151658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_12MS: 1152658b476cSCristina Ciocan arg = 12000; 1153658b476cSCristina Ciocan break; 1154658b476cSCristina Ciocan case BYT_DEBOUNCE_PULSE_24MS: 1155658b476cSCristina Ciocan arg = 24000; 1156658b476cSCristina Ciocan break; 1157658b476cSCristina Ciocan default: 1158658b476cSCristina Ciocan return -EINVAL; 1159658b476cSCristina Ciocan } 1160658b476cSCristina Ciocan 1161658b476cSCristina Ciocan break; 1162c501d0b1SCristina Ciocan default: 1163c501d0b1SCristina Ciocan return -ENOTSUPP; 1164c501d0b1SCristina Ciocan } 1165c501d0b1SCristina Ciocan 1166c501d0b1SCristina Ciocan *config = pinconf_to_config_packed(param, arg); 1167c501d0b1SCristina Ciocan 1168c501d0b1SCristina Ciocan return 0; 1169c501d0b1SCristina Ciocan } 1170c501d0b1SCristina Ciocan 1171c501d0b1SCristina Ciocan static int byt_pin_config_set(struct pinctrl_dev *pctl_dev, 1172c501d0b1SCristina Ciocan unsigned int offset, 1173c501d0b1SCristina Ciocan unsigned long *configs, 1174c501d0b1SCristina Ciocan unsigned int num_configs) 1175c501d0b1SCristina Ciocan { 1176c501d0b1SCristina Ciocan struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); 1177c501d0b1SCristina Ciocan unsigned int param, arg; 1178c501d0b1SCristina Ciocan void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 1179c501d0b1SCristina Ciocan void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 1180c501d0b1SCristina Ciocan unsigned long flags; 1181658b476cSCristina Ciocan u32 conf, val, debounce; 1182c501d0b1SCristina Ciocan int i, ret = 0; 1183c501d0b1SCristina Ciocan 1184c501d0b1SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 1185c501d0b1SCristina Ciocan 1186c501d0b1SCristina Ciocan conf = readl(conf_reg); 1187c501d0b1SCristina Ciocan val = readl(val_reg); 1188c501d0b1SCristina Ciocan 1189c501d0b1SCristina Ciocan for (i = 0; i < num_configs; i++) { 1190c501d0b1SCristina Ciocan param = pinconf_to_config_param(configs[i]); 1191c501d0b1SCristina Ciocan arg = pinconf_to_config_argument(configs[i]); 1192c501d0b1SCristina Ciocan 1193c501d0b1SCristina Ciocan switch (param) { 1194c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_DISABLE: 1195c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1196c501d0b1SCristina Ciocan break; 1197c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_DOWN: 1198c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1199c501d0b1SCristina Ciocan if (arg == 1) 1200c501d0b1SCristina Ciocan arg = 2000; 1201c501d0b1SCristina Ciocan 1202c501d0b1SCristina Ciocan /* 1203c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1204c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1205c501d0b1SCristina Ciocan */ 1206c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1207c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1208c501d0b1SCristina Ciocan writel(val, val_reg); 1209c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 1210c501d0b1SCristina Ciocan "pin %u forcibly set to input mode\n", 1211c501d0b1SCristina Ciocan offset); 1212c501d0b1SCristina Ciocan } 1213c501d0b1SCristina Ciocan 1214c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1215c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_DOWN; 1216c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1217c501d0b1SCristina Ciocan 1218c501d0b1SCristina Ciocan break; 1219c501d0b1SCristina Ciocan case PIN_CONFIG_BIAS_PULL_UP: 1220c501d0b1SCristina Ciocan /* Set default strength value in case none is given */ 1221c501d0b1SCristina Ciocan if (arg == 1) 1222c501d0b1SCristina Ciocan arg = 2000; 1223c501d0b1SCristina Ciocan 1224c501d0b1SCristina Ciocan /* 1225c501d0b1SCristina Ciocan * Pull assignment is only applicable in input mode. If 1226c501d0b1SCristina Ciocan * chip is not in input mode, set it and warn about it. 1227c501d0b1SCristina Ciocan */ 1228c501d0b1SCristina Ciocan if (val & BYT_INPUT_EN) { 1229c501d0b1SCristina Ciocan val &= ~BYT_INPUT_EN; 1230c501d0b1SCristina Ciocan writel(val, val_reg); 1231c501d0b1SCristina Ciocan dev_warn(&vg->pdev->dev, 1232c501d0b1SCristina Ciocan "pin %u forcibly set to input mode\n", 1233c501d0b1SCristina Ciocan offset); 1234c501d0b1SCristina Ciocan } 1235c501d0b1SCristina Ciocan 1236c501d0b1SCristina Ciocan conf &= ~BYT_PULL_ASSIGN_MASK; 1237c501d0b1SCristina Ciocan conf |= BYT_PULL_ASSIGN_UP; 1238c501d0b1SCristina Ciocan ret = byt_set_pull_strength(&conf, arg); 1239c501d0b1SCristina Ciocan 1240c501d0b1SCristina Ciocan break; 1241658b476cSCristina Ciocan case PIN_CONFIG_INPUT_DEBOUNCE: 1242658b476cSCristina Ciocan debounce = readl(byt_gpio_reg(vg, offset, 1243658b476cSCristina Ciocan BYT_DEBOUNCE_REG)); 1244658b476cSCristina Ciocan conf &= ~BYT_DEBOUNCE_PULSE_MASK; 1245658b476cSCristina Ciocan 1246658b476cSCristina Ciocan switch (arg) { 1247658b476cSCristina Ciocan case 375: 1248658b476cSCristina Ciocan conf |= BYT_DEBOUNCE_PULSE_375US; 1249658b476cSCristina Ciocan break; 1250658b476cSCristina Ciocan case 750: 1251658b476cSCristina Ciocan conf |= BYT_DEBOUNCE_PULSE_750US; 1252658b476cSCristina Ciocan break; 1253658b476cSCristina Ciocan case 1500: 1254658b476cSCristina Ciocan conf |= BYT_DEBOUNCE_PULSE_1500US; 1255658b476cSCristina Ciocan break; 1256658b476cSCristina Ciocan case 3000: 1257658b476cSCristina Ciocan conf |= BYT_DEBOUNCE_PULSE_3MS; 1258658b476cSCristina Ciocan break; 1259658b476cSCristina Ciocan case 6000: 1260658b476cSCristina Ciocan conf |= BYT_DEBOUNCE_PULSE_6MS; 1261658b476cSCristina Ciocan break; 1262658b476cSCristina Ciocan case 12000: 1263658b476cSCristina Ciocan conf |= BYT_DEBOUNCE_PULSE_12MS; 1264658b476cSCristina Ciocan break; 1265658b476cSCristina Ciocan case 24000: 1266658b476cSCristina Ciocan conf |= BYT_DEBOUNCE_PULSE_24MS; 1267658b476cSCristina Ciocan break; 1268658b476cSCristina Ciocan default: 1269658b476cSCristina Ciocan ret = -EINVAL; 1270658b476cSCristina Ciocan } 1271658b476cSCristina Ciocan 1272658b476cSCristina Ciocan break; 1273c501d0b1SCristina Ciocan default: 1274c501d0b1SCristina Ciocan ret = -ENOTSUPP; 1275c501d0b1SCristina Ciocan } 1276c501d0b1SCristina Ciocan 1277c501d0b1SCristina Ciocan if (ret) 1278c501d0b1SCristina Ciocan break; 1279c501d0b1SCristina Ciocan } 1280c501d0b1SCristina Ciocan 1281c501d0b1SCristina Ciocan if (!ret) 1282c501d0b1SCristina Ciocan writel(conf, conf_reg); 1283c501d0b1SCristina Ciocan 1284c501d0b1SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 1285c501d0b1SCristina Ciocan 1286c501d0b1SCristina Ciocan return ret; 1287c501d0b1SCristina Ciocan } 1288c501d0b1SCristina Ciocan 1289c501d0b1SCristina Ciocan static const struct pinconf_ops byt_pinconf_ops = { 1290c501d0b1SCristina Ciocan .is_generic = true, 1291c501d0b1SCristina Ciocan .pin_config_get = byt_pin_config_get, 1292c501d0b1SCristina Ciocan .pin_config_set = byt_pin_config_set, 1293c501d0b1SCristina Ciocan }; 1294c501d0b1SCristina Ciocan 1295c501d0b1SCristina Ciocan static const struct pinctrl_desc byt_pinctrl_desc = { 1296c501d0b1SCristina Ciocan .pctlops = &byt_pinctrl_ops, 1297c501d0b1SCristina Ciocan .pmxops = &byt_pinmux_ops, 1298c501d0b1SCristina Ciocan .confops = &byt_pinconf_ops, 1299c501d0b1SCristina Ciocan .owner = THIS_MODULE, 1300c501d0b1SCristina Ciocan }; 1301c501d0b1SCristina Ciocan 13025fae8b86SMika Westerberg static int byt_gpio_get(struct gpio_chip *chip, unsigned offset) 13035fae8b86SMika Westerberg { 1304bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1305c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 130639ce8150SMika Westerberg unsigned long flags; 130739ce8150SMika Westerberg u32 val; 130839ce8150SMika Westerberg 130978e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 131039ce8150SMika Westerberg val = readl(reg); 131178e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 131239ce8150SMika Westerberg 13133bde8771SLinus Walleij return !!(val & BYT_LEVEL); 13145fae8b86SMika Westerberg } 13155fae8b86SMika Westerberg 13165fae8b86SMika Westerberg static void byt_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 13175fae8b86SMika Westerberg { 1318bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1319c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 13205fae8b86SMika Westerberg unsigned long flags; 13215fae8b86SMika Westerberg u32 old_val; 13225fae8b86SMika Westerberg 132386e3ef81SCristina Ciocan if (!reg) 132486e3ef81SCristina Ciocan return; 132586e3ef81SCristina Ciocan 132678e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 13275fae8b86SMika Westerberg old_val = readl(reg); 13285fae8b86SMika Westerberg if (value) 13295fae8b86SMika Westerberg writel(old_val | BYT_LEVEL, reg); 13305fae8b86SMika Westerberg else 13315fae8b86SMika Westerberg writel(old_val & ~BYT_LEVEL, reg); 133278e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 13335fae8b86SMika Westerberg } 13345fae8b86SMika Westerberg 133586e3ef81SCristina Ciocan static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 13365fae8b86SMika Westerberg { 1337bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 1338c501d0b1SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 13395fae8b86SMika Westerberg unsigned long flags; 13405fae8b86SMika Westerberg u32 value; 13415fae8b86SMika Westerberg 134286e3ef81SCristina Ciocan if (!reg) 134386e3ef81SCristina Ciocan return -EINVAL; 134486e3ef81SCristina Ciocan 134578e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 134686e3ef81SCristina Ciocan value = readl(reg); 134778e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 13485fae8b86SMika Westerberg 134986e3ef81SCristina Ciocan if (!(value & BYT_OUTPUT_EN)) 135086e3ef81SCristina Ciocan return GPIOF_DIR_OUT; 135186e3ef81SCristina Ciocan if (!(value & BYT_INPUT_EN)) 135286e3ef81SCristina Ciocan return GPIOF_DIR_IN; 135386e3ef81SCristina Ciocan 135486e3ef81SCristina Ciocan return -EINVAL; 13555fae8b86SMika Westerberg } 13565fae8b86SMika Westerberg 135786e3ef81SCristina Ciocan static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 13585fae8b86SMika Westerberg { 135986e3ef81SCristina Ciocan return pinctrl_gpio_direction_input(chip->base + offset); 136086e3ef81SCristina Ciocan } 13615fae8b86SMika Westerberg 136286e3ef81SCristina Ciocan static int byt_gpio_direction_output(struct gpio_chip *chip, 136386e3ef81SCristina Ciocan unsigned int offset, int value) 136486e3ef81SCristina Ciocan { 136586e3ef81SCristina Ciocan int ret = pinctrl_gpio_direction_output(chip->base + offset); 13665fae8b86SMika Westerberg 136786e3ef81SCristina Ciocan if (ret) 136886e3ef81SCristina Ciocan return ret; 136986e3ef81SCristina Ciocan 137086e3ef81SCristina Ciocan byt_gpio_set(chip, offset, value); 13715fae8b86SMika Westerberg 13725fae8b86SMika Westerberg return 0; 13735fae8b86SMika Westerberg } 13745fae8b86SMika Westerberg 13755fae8b86SMika Westerberg static void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 13765fae8b86SMika Westerberg { 1377bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(chip); 13785fae8b86SMika Westerberg int i; 137986e3ef81SCristina Ciocan u32 conf0, val; 13805fae8b86SMika Westerberg 138186e3ef81SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 138286e3ef81SCristina Ciocan const struct byt_community *comm; 13835fae8b86SMika Westerberg const char *pull_str = NULL; 13845fae8b86SMika Westerberg const char *pull = NULL; 138586e3ef81SCristina Ciocan void __iomem *reg; 138678e1c896SMika Westerberg unsigned long flags; 13875fae8b86SMika Westerberg const char *label; 138886e3ef81SCristina Ciocan unsigned int pin; 138978e1c896SMika Westerberg 139078e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 139186e3ef81SCristina Ciocan pin = vg->soc_data->pins[i].number; 139286e3ef81SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 139386e3ef81SCristina Ciocan if (!reg) { 139486e3ef81SCristina Ciocan seq_printf(s, 139586e3ef81SCristina Ciocan "Could not retrieve pin %i conf0 reg\n", 139686e3ef81SCristina Ciocan pin); 139722bbd21bSDan Carpenter raw_spin_unlock_irqrestore(&vg->lock, flags); 139886e3ef81SCristina Ciocan continue; 139986e3ef81SCristina Ciocan } 140086e3ef81SCristina Ciocan conf0 = readl(reg); 140186e3ef81SCristina Ciocan 140286e3ef81SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 140386e3ef81SCristina Ciocan if (!reg) { 140486e3ef81SCristina Ciocan seq_printf(s, 140586e3ef81SCristina Ciocan "Could not retrieve pin %i val reg\n", pin); 140622bbd21bSDan Carpenter raw_spin_unlock_irqrestore(&vg->lock, flags); 140722bbd21bSDan Carpenter continue; 140886e3ef81SCristina Ciocan } 140986e3ef81SCristina Ciocan val = readl(reg); 141078e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 14115fae8b86SMika Westerberg 141286e3ef81SCristina Ciocan comm = byt_get_community(vg, pin); 141386e3ef81SCristina Ciocan if (!comm) { 141486e3ef81SCristina Ciocan seq_printf(s, 141586e3ef81SCristina Ciocan "Could not get community for pin %i\n", pin); 141686e3ef81SCristina Ciocan continue; 141786e3ef81SCristina Ciocan } 14185fae8b86SMika Westerberg label = gpiochip_is_requested(chip, i); 14195fae8b86SMika Westerberg if (!label) 14205fae8b86SMika Westerberg label = "Unrequested"; 14215fae8b86SMika Westerberg 14225fae8b86SMika Westerberg switch (conf0 & BYT_PULL_ASSIGN_MASK) { 14235fae8b86SMika Westerberg case BYT_PULL_ASSIGN_UP: 14245fae8b86SMika Westerberg pull = "up"; 14255fae8b86SMika Westerberg break; 14265fae8b86SMika Westerberg case BYT_PULL_ASSIGN_DOWN: 14275fae8b86SMika Westerberg pull = "down"; 14285fae8b86SMika Westerberg break; 14295fae8b86SMika Westerberg } 14305fae8b86SMika Westerberg 14315fae8b86SMika Westerberg switch (conf0 & BYT_PULL_STR_MASK) { 14325fae8b86SMika Westerberg case BYT_PULL_STR_2K: 14335fae8b86SMika Westerberg pull_str = "2k"; 14345fae8b86SMika Westerberg break; 14355fae8b86SMika Westerberg case BYT_PULL_STR_10K: 14365fae8b86SMika Westerberg pull_str = "10k"; 14375fae8b86SMika Westerberg break; 14385fae8b86SMika Westerberg case BYT_PULL_STR_20K: 14395fae8b86SMika Westerberg pull_str = "20k"; 14405fae8b86SMika Westerberg break; 14415fae8b86SMika Westerberg case BYT_PULL_STR_40K: 14425fae8b86SMika Westerberg pull_str = "40k"; 14435fae8b86SMika Westerberg break; 14445fae8b86SMika Westerberg } 14455fae8b86SMika Westerberg 14465fae8b86SMika Westerberg seq_printf(s, 14475fae8b86SMika Westerberg " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", 144886e3ef81SCristina Ciocan pin, 14495fae8b86SMika Westerberg label, 14505fae8b86SMika Westerberg val & BYT_INPUT_EN ? " " : "in", 14515fae8b86SMika Westerberg val & BYT_OUTPUT_EN ? " " : "out", 14525fae8b86SMika Westerberg val & BYT_LEVEL ? "hi" : "lo", 145386e3ef81SCristina Ciocan comm->pad_map[i], comm->pad_map[i] * 32, 14545fae8b86SMika Westerberg conf0 & 0x7, 14555fae8b86SMika Westerberg conf0 & BYT_TRIG_NEG ? " fall" : " ", 14565fae8b86SMika Westerberg conf0 & BYT_TRIG_POS ? " rise" : " ", 14575fae8b86SMika Westerberg conf0 & BYT_TRIG_LVL ? " level" : " "); 14585fae8b86SMika Westerberg 14595fae8b86SMika Westerberg if (pull && pull_str) 14605fae8b86SMika Westerberg seq_printf(s, " %-4s %-3s", pull, pull_str); 14615fae8b86SMika Westerberg else 14625fae8b86SMika Westerberg seq_puts(s, " "); 14635fae8b86SMika Westerberg 14645fae8b86SMika Westerberg if (conf0 & BYT_IODEN) 14655fae8b86SMika Westerberg seq_puts(s, " open-drain"); 14665fae8b86SMika Westerberg 14675fae8b86SMika Westerberg seq_puts(s, "\n"); 14685fae8b86SMika Westerberg } 14695fae8b86SMika Westerberg } 14705fae8b86SMika Westerberg 147186e3ef81SCristina Ciocan static const struct gpio_chip byt_gpio_chip = { 147286e3ef81SCristina Ciocan .owner = THIS_MODULE, 147386e3ef81SCristina Ciocan .request = gpiochip_generic_request, 147486e3ef81SCristina Ciocan .free = gpiochip_generic_free, 147586e3ef81SCristina Ciocan .get_direction = byt_gpio_get_direction, 147686e3ef81SCristina Ciocan .direction_input = byt_gpio_direction_input, 147786e3ef81SCristina Ciocan .direction_output = byt_gpio_direction_output, 147886e3ef81SCristina Ciocan .get = byt_gpio_get, 147986e3ef81SCristina Ciocan .set = byt_gpio_set, 148086e3ef81SCristina Ciocan .dbg_show = byt_gpio_dbg_show, 148186e3ef81SCristina Ciocan }; 148286e3ef81SCristina Ciocan 148331e4329fSMika Westerberg static void byt_irq_ack(struct irq_data *d) 148431e4329fSMika Westerberg { 148531e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1486bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(gc); 148731e4329fSMika Westerberg unsigned offset = irqd_to_hwirq(d); 148831e4329fSMika Westerberg void __iomem *reg; 148931e4329fSMika Westerberg 1490c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); 14919f573b98SCristina Ciocan if (!reg) 14929f573b98SCristina Ciocan return; 14939f573b98SCristina Ciocan 14949f573b98SCristina Ciocan raw_spin_lock(&vg->lock); 149531e4329fSMika Westerberg writel(BIT(offset % 32), reg); 149678e1c896SMika Westerberg raw_spin_unlock(&vg->lock); 149731e4329fSMika Westerberg } 149831e4329fSMika Westerberg 14999f573b98SCristina Ciocan static void byt_irq_mask(struct irq_data *d) 15009f573b98SCristina Ciocan { 15019f573b98SCristina Ciocan struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 15029f573b98SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data(gc); 15039f573b98SCristina Ciocan 15049f573b98SCristina Ciocan byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); 15059f573b98SCristina Ciocan } 15069f573b98SCristina Ciocan 15075fae8b86SMika Westerberg static void byt_irq_unmask(struct irq_data *d) 15085fae8b86SMika Westerberg { 150931e4329fSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1510bf9a5c96SLinus Walleij struct byt_gpio *vg = gpiochip_get_data(gc); 151131e4329fSMika Westerberg unsigned offset = irqd_to_hwirq(d); 151231e4329fSMika Westerberg unsigned long flags; 151331e4329fSMika Westerberg void __iomem *reg; 151431e4329fSMika Westerberg u32 value; 151531e4329fSMika Westerberg 1516c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 15179f573b98SCristina Ciocan if (!reg) 15189f573b98SCristina Ciocan return; 151978e1c896SMika Westerberg 152078e1c896SMika Westerberg raw_spin_lock_irqsave(&vg->lock, flags); 152131e4329fSMika Westerberg value = readl(reg); 152231e4329fSMika Westerberg 152331e4329fSMika Westerberg switch (irqd_get_trigger_type(d)) { 152431e4329fSMika Westerberg case IRQ_TYPE_LEVEL_HIGH: 152531e4329fSMika Westerberg value |= BYT_TRIG_LVL; 152631e4329fSMika Westerberg case IRQ_TYPE_EDGE_RISING: 152731e4329fSMika Westerberg value |= BYT_TRIG_POS; 152831e4329fSMika Westerberg break; 152931e4329fSMika Westerberg case IRQ_TYPE_LEVEL_LOW: 153031e4329fSMika Westerberg value |= BYT_TRIG_LVL; 153131e4329fSMika Westerberg case IRQ_TYPE_EDGE_FALLING: 153231e4329fSMika Westerberg value |= BYT_TRIG_NEG; 153331e4329fSMika Westerberg break; 153431e4329fSMika Westerberg case IRQ_TYPE_EDGE_BOTH: 153531e4329fSMika Westerberg value |= (BYT_TRIG_NEG | BYT_TRIG_POS); 153631e4329fSMika Westerberg break; 153731e4329fSMika Westerberg } 153831e4329fSMika Westerberg 153931e4329fSMika Westerberg writel(value, reg); 154031e4329fSMika Westerberg 154178e1c896SMika Westerberg raw_spin_unlock_irqrestore(&vg->lock, flags); 15425fae8b86SMika Westerberg } 15435fae8b86SMika Westerberg 15449f573b98SCristina Ciocan static int byt_irq_type(struct irq_data *d, unsigned int type) 15455fae8b86SMika Westerberg { 15469f573b98SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); 15479f573b98SCristina Ciocan u32 offset = irqd_to_hwirq(d); 15489f573b98SCristina Ciocan u32 value; 15499f573b98SCristina Ciocan unsigned long flags; 15509f573b98SCristina Ciocan void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 155131e4329fSMika Westerberg 15529f573b98SCristina Ciocan if (!reg || offset >= vg->chip.ngpio) 15539f573b98SCristina Ciocan return -EINVAL; 15549f573b98SCristina Ciocan 15559f573b98SCristina Ciocan raw_spin_lock_irqsave(&vg->lock, flags); 15569f573b98SCristina Ciocan value = readl(reg); 15579f573b98SCristina Ciocan 15589f573b98SCristina Ciocan WARN(value & BYT_DIRECT_IRQ_EN, 15599f573b98SCristina Ciocan "Bad pad config for io mode, force direct_irq_en bit clearing"); 15609f573b98SCristina Ciocan 15619f573b98SCristina Ciocan /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits 15629f573b98SCristina Ciocan * are used to indicate high and low level triggering 15639f573b98SCristina Ciocan */ 15649f573b98SCristina Ciocan value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | 15659f573b98SCristina Ciocan BYT_TRIG_LVL); 15669f573b98SCristina Ciocan 15679f573b98SCristina Ciocan writel(value, reg); 15689f573b98SCristina Ciocan 15699f573b98SCristina Ciocan if (type & IRQ_TYPE_EDGE_BOTH) 15709f573b98SCristina Ciocan irq_set_handler_locked(d, handle_edge_irq); 15719f573b98SCristina Ciocan else if (type & IRQ_TYPE_LEVEL_MASK) 15729f573b98SCristina Ciocan irq_set_handler_locked(d, handle_level_irq); 15739f573b98SCristina Ciocan 15749f573b98SCristina Ciocan raw_spin_unlock_irqrestore(&vg->lock, flags); 15759f573b98SCristina Ciocan 15769f573b98SCristina Ciocan return 0; 15775fae8b86SMika Westerberg } 15785fae8b86SMika Westerberg 15795fae8b86SMika Westerberg static struct irq_chip byt_irqchip = { 15805fae8b86SMika Westerberg .name = "BYT-GPIO", 158131e4329fSMika Westerberg .irq_ack = byt_irq_ack, 15825fae8b86SMika Westerberg .irq_mask = byt_irq_mask, 15835fae8b86SMika Westerberg .irq_unmask = byt_irq_unmask, 15845fae8b86SMika Westerberg .irq_set_type = byt_irq_type, 15855fae8b86SMika Westerberg .flags = IRQCHIP_SKIP_SET_WAKE, 15865fae8b86SMika Westerberg }; 15875fae8b86SMika Westerberg 158871e6ca61SCristina Ciocan static void byt_gpio_irq_handler(struct irq_desc *desc) 158971e6ca61SCristina Ciocan { 159071e6ca61SCristina Ciocan struct irq_data *data = irq_desc_get_irq_data(desc); 159171e6ca61SCristina Ciocan struct byt_gpio *vg = gpiochip_get_data( 159271e6ca61SCristina Ciocan irq_desc_get_handler_data(desc)); 159371e6ca61SCristina Ciocan struct irq_chip *chip = irq_data_get_irq_chip(data); 159471e6ca61SCristina Ciocan u32 base, pin; 159571e6ca61SCristina Ciocan void __iomem *reg; 159671e6ca61SCristina Ciocan unsigned long pending; 159771e6ca61SCristina Ciocan unsigned int virq; 159871e6ca61SCristina Ciocan 159971e6ca61SCristina Ciocan /* check from GPIO controller which pin triggered the interrupt */ 160071e6ca61SCristina Ciocan for (base = 0; base < vg->chip.ngpio; base += 32) { 160171e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 160271e6ca61SCristina Ciocan 160371e6ca61SCristina Ciocan if (!reg) { 160471e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 160571e6ca61SCristina Ciocan "Pin %i: could not retrieve interrupt status register\n", 160671e6ca61SCristina Ciocan base); 160771e6ca61SCristina Ciocan continue; 160871e6ca61SCristina Ciocan } 160971e6ca61SCristina Ciocan 161071e6ca61SCristina Ciocan pending = readl(reg); 161171e6ca61SCristina Ciocan for_each_set_bit(pin, &pending, 32) { 161271e6ca61SCristina Ciocan virq = irq_find_mapping(vg->chip.irqdomain, base + pin); 161371e6ca61SCristina Ciocan generic_handle_irq(virq); 161471e6ca61SCristina Ciocan } 161571e6ca61SCristina Ciocan } 161671e6ca61SCristina Ciocan chip->irq_eoi(data); 161771e6ca61SCristina Ciocan } 161871e6ca61SCristina Ciocan 16195fae8b86SMika Westerberg static void byt_gpio_irq_init_hw(struct byt_gpio *vg) 16205fae8b86SMika Westerberg { 16215fae8b86SMika Westerberg void __iomem *reg; 16225fae8b86SMika Westerberg u32 base, value; 162395f0972cSMika Westerberg int i; 162495f0972cSMika Westerberg 162595f0972cSMika Westerberg /* 162695f0972cSMika Westerberg * Clear interrupt triggers for all pins that are GPIOs and 162795f0972cSMika Westerberg * do not use direct IRQ mode. This will prevent spurious 162895f0972cSMika Westerberg * interrupts from misconfigured pins. 162995f0972cSMika Westerberg */ 163071e6ca61SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 163171e6ca61SCristina Ciocan unsigned int pin = vg->soc_data->pins[i].number; 163271e6ca61SCristina Ciocan 163371e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 163471e6ca61SCristina Ciocan if (!reg) { 163571e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 163671e6ca61SCristina Ciocan "Pin %i: could not retrieve conf0 register\n", 163771e6ca61SCristina Ciocan i); 163871e6ca61SCristina Ciocan continue; 163971e6ca61SCristina Ciocan } 164071e6ca61SCristina Ciocan 164171e6ca61SCristina Ciocan value = readl(reg); 164295f0972cSMika Westerberg if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i) && 164395f0972cSMika Westerberg !(value & BYT_DIRECT_IRQ_EN)) { 164495f0972cSMika Westerberg byt_gpio_clear_triggering(vg, i); 164595f0972cSMika Westerberg dev_dbg(&vg->pdev->dev, "disabling GPIO %d\n", i); 164695f0972cSMika Westerberg } 164795f0972cSMika Westerberg } 16485fae8b86SMika Westerberg 16495fae8b86SMika Westerberg /* clear interrupt status trigger registers */ 165071e6ca61SCristina Ciocan for (base = 0; base < vg->soc_data->npins; base += 32) { 1651c501d0b1SCristina Ciocan reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 165271e6ca61SCristina Ciocan 165371e6ca61SCristina Ciocan if (!reg) { 165471e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 165571e6ca61SCristina Ciocan "Pin %i: could not retrieve irq status reg\n", 165671e6ca61SCristina Ciocan base); 165771e6ca61SCristina Ciocan continue; 165871e6ca61SCristina Ciocan } 165971e6ca61SCristina Ciocan 16605fae8b86SMika Westerberg writel(0xffffffff, reg); 16615fae8b86SMika Westerberg /* make sure trigger bits are cleared, if not then a pin 16625fae8b86SMika Westerberg might be misconfigured in bios */ 16635fae8b86SMika Westerberg value = readl(reg); 16645fae8b86SMika Westerberg if (value) 16655fae8b86SMika Westerberg dev_err(&vg->pdev->dev, 16665fae8b86SMika Westerberg "GPIO interrupt error, pins misconfigured\n"); 16675fae8b86SMika Westerberg } 16685fae8b86SMika Westerberg } 16695fae8b86SMika Westerberg 167071e6ca61SCristina Ciocan static int byt_gpio_probe(struct byt_gpio *vg) 16715fae8b86SMika Westerberg { 16725fae8b86SMika Westerberg struct gpio_chip *gc; 167371e6ca61SCristina Ciocan struct resource *irq_rc; 16745fae8b86SMika Westerberg int ret; 16755fae8b86SMika Westerberg 167671e6ca61SCristina Ciocan /* Set up gpio chip */ 167771e6ca61SCristina Ciocan vg->chip = byt_gpio_chip; 16785fae8b86SMika Westerberg gc = &vg->chip; 167971e6ca61SCristina Ciocan gc->label = dev_name(&vg->pdev->dev); 16805fae8b86SMika Westerberg gc->base = -1; 16815fae8b86SMika Westerberg gc->can_sleep = false; 168271e6ca61SCristina Ciocan gc->parent = &vg->pdev->dev; 168371e6ca61SCristina Ciocan gc->ngpio = vg->soc_data->npins; 16845fae8b86SMika Westerberg 1685fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP 168671e6ca61SCristina Ciocan vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, 1687fcc18debSMika Westerberg sizeof(*vg->saved_context), GFP_KERNEL); 1688fcc18debSMika Westerberg #endif 1689bf9a5c96SLinus Walleij ret = gpiochip_add_data(gc, vg); 16905fae8b86SMika Westerberg if (ret) { 169171e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed adding byt-gpio chip\n"); 16925fae8b86SMika Westerberg return ret; 16935fae8b86SMika Westerberg } 16945fae8b86SMika Westerberg 169571e6ca61SCristina Ciocan ret = gpiochip_add_pin_range(&vg->chip, dev_name(&vg->pdev->dev), 169671e6ca61SCristina Ciocan 0, 0, vg->soc_data->npins); 169771e6ca61SCristina Ciocan if (ret) { 169871e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed to add GPIO pin range\n"); 169971e6ca61SCristina Ciocan goto fail; 170071e6ca61SCristina Ciocan } 170171e6ca61SCristina Ciocan 17025fae8b86SMika Westerberg /* set up interrupts */ 170371e6ca61SCristina Ciocan irq_rc = platform_get_resource(vg->pdev, IORESOURCE_IRQ, 0); 17045fae8b86SMika Westerberg if (irq_rc && irq_rc->start) { 17055fae8b86SMika Westerberg byt_gpio_irq_init_hw(vg); 17065fae8b86SMika Westerberg ret = gpiochip_irqchip_add(gc, &byt_irqchip, 0, 17075fae8b86SMika Westerberg handle_simple_irq, IRQ_TYPE_NONE); 17085fae8b86SMika Westerberg if (ret) { 170971e6ca61SCristina Ciocan dev_err(&vg->pdev->dev, "failed to add irqchip\n"); 171071e6ca61SCristina Ciocan goto fail; 17115fae8b86SMika Westerberg } 17125fae8b86SMika Westerberg 17135fae8b86SMika Westerberg gpiochip_set_chained_irqchip(gc, &byt_irqchip, 17145fae8b86SMika Westerberg (unsigned)irq_rc->start, 17155fae8b86SMika Westerberg byt_gpio_irq_handler); 17165fae8b86SMika Westerberg } 17175fae8b86SMika Westerberg 171871e6ca61SCristina Ciocan return ret; 171971e6ca61SCristina Ciocan 172071e6ca61SCristina Ciocan fail: 172171e6ca61SCristina Ciocan gpiochip_remove(&vg->chip); 172271e6ca61SCristina Ciocan 172371e6ca61SCristina Ciocan return ret; 172471e6ca61SCristina Ciocan } 172571e6ca61SCristina Ciocan 172671e6ca61SCristina Ciocan static int byt_set_soc_data(struct byt_gpio *vg, 172771e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data) 172871e6ca61SCristina Ciocan { 172971e6ca61SCristina Ciocan int i; 173071e6ca61SCristina Ciocan 173171e6ca61SCristina Ciocan vg->soc_data = soc_data; 173271e6ca61SCristina Ciocan vg->communities_copy = devm_kcalloc(&vg->pdev->dev, 173371e6ca61SCristina Ciocan soc_data->ncommunities, 173471e6ca61SCristina Ciocan sizeof(*vg->communities_copy), 173571e6ca61SCristina Ciocan GFP_KERNEL); 173671e6ca61SCristina Ciocan if (!vg->communities_copy) 173771e6ca61SCristina Ciocan return -ENOMEM; 173871e6ca61SCristina Ciocan 173971e6ca61SCristina Ciocan for (i = 0; i < soc_data->ncommunities; i++) { 174071e6ca61SCristina Ciocan struct byt_community *comm = vg->communities_copy + i; 174171e6ca61SCristina Ciocan struct resource *mem_rc; 174271e6ca61SCristina Ciocan 174371e6ca61SCristina Ciocan *comm = vg->soc_data->communities[i]; 174471e6ca61SCristina Ciocan 174571e6ca61SCristina Ciocan mem_rc = platform_get_resource(vg->pdev, IORESOURCE_MEM, 0); 174671e6ca61SCristina Ciocan comm->reg_base = devm_ioremap_resource(&vg->pdev->dev, mem_rc); 174771e6ca61SCristina Ciocan if (IS_ERR(comm->reg_base)) 174871e6ca61SCristina Ciocan return PTR_ERR(comm->reg_base); 174971e6ca61SCristina Ciocan } 175071e6ca61SCristina Ciocan 175171e6ca61SCristina Ciocan return 0; 175271e6ca61SCristina Ciocan } 175371e6ca61SCristina Ciocan 175471e6ca61SCristina Ciocan static const struct acpi_device_id byt_gpio_acpi_match[] = { 175571e6ca61SCristina Ciocan { "INT33B2", (kernel_ulong_t)byt_soc_data }, 175671e6ca61SCristina Ciocan { "INT33FC", (kernel_ulong_t)byt_soc_data }, 175771e6ca61SCristina Ciocan { } 175871e6ca61SCristina Ciocan }; 175971e6ca61SCristina Ciocan MODULE_DEVICE_TABLE(acpi, byt_gpio_acpi_match); 176071e6ca61SCristina Ciocan 176171e6ca61SCristina Ciocan static int byt_pinctrl_probe(struct platform_device *pdev) 176271e6ca61SCristina Ciocan { 176371e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data *soc_data = NULL; 176471e6ca61SCristina Ciocan const struct byt_pinctrl_soc_data **soc_table; 176571e6ca61SCristina Ciocan const struct acpi_device_id *acpi_id; 176671e6ca61SCristina Ciocan struct acpi_device *acpi_dev; 176771e6ca61SCristina Ciocan struct byt_gpio *vg; 176871e6ca61SCristina Ciocan int i, ret; 176971e6ca61SCristina Ciocan 177071e6ca61SCristina Ciocan acpi_dev = ACPI_COMPANION(&pdev->dev); 177171e6ca61SCristina Ciocan if (!acpi_dev) 177271e6ca61SCristina Ciocan return -ENODEV; 177371e6ca61SCristina Ciocan 177471e6ca61SCristina Ciocan acpi_id = acpi_match_device(byt_gpio_acpi_match, &pdev->dev); 177571e6ca61SCristina Ciocan if (!acpi_id) 177671e6ca61SCristina Ciocan return -ENODEV; 177771e6ca61SCristina Ciocan 177871e6ca61SCristina Ciocan soc_table = (const struct byt_pinctrl_soc_data **)acpi_id->driver_data; 177971e6ca61SCristina Ciocan 178071e6ca61SCristina Ciocan for (i = 0; soc_table[i]; i++) { 178171e6ca61SCristina Ciocan if (!strcmp(acpi_dev->pnp.unique_id, soc_table[i]->uid)) { 178271e6ca61SCristina Ciocan soc_data = soc_table[i]; 178371e6ca61SCristina Ciocan break; 178471e6ca61SCristina Ciocan } 178571e6ca61SCristina Ciocan } 178671e6ca61SCristina Ciocan 178771e6ca61SCristina Ciocan if (!soc_data) 178871e6ca61SCristina Ciocan return -ENODEV; 178971e6ca61SCristina Ciocan 179071e6ca61SCristina Ciocan vg = devm_kzalloc(&pdev->dev, sizeof(*vg), GFP_KERNEL); 179171e6ca61SCristina Ciocan if (!vg) 179271e6ca61SCristina Ciocan return -ENOMEM; 179371e6ca61SCristina Ciocan 179471e6ca61SCristina Ciocan vg->pdev = pdev; 179571e6ca61SCristina Ciocan ret = byt_set_soc_data(vg, soc_data); 179671e6ca61SCristina Ciocan if (ret) { 179771e6ca61SCristina Ciocan dev_err(&pdev->dev, "failed to set soc data\n"); 179871e6ca61SCristina Ciocan return ret; 179971e6ca61SCristina Ciocan } 180071e6ca61SCristina Ciocan 180171e6ca61SCristina Ciocan vg->pctl_desc = byt_pinctrl_desc; 180271e6ca61SCristina Ciocan vg->pctl_desc.name = dev_name(&pdev->dev); 180371e6ca61SCristina Ciocan vg->pctl_desc.pins = vg->soc_data->pins; 180471e6ca61SCristina Ciocan vg->pctl_desc.npins = vg->soc_data->npins; 180571e6ca61SCristina Ciocan 180671e6ca61SCristina Ciocan vg->pctl_dev = pinctrl_register(&vg->pctl_desc, &pdev->dev, vg); 180771e6ca61SCristina Ciocan if (IS_ERR(vg->pctl_dev)) { 180871e6ca61SCristina Ciocan dev_err(&pdev->dev, "failed to register pinctrl driver\n"); 180971e6ca61SCristina Ciocan return PTR_ERR(vg->pctl_dev); 181071e6ca61SCristina Ciocan } 181171e6ca61SCristina Ciocan 181271e6ca61SCristina Ciocan ret = byt_gpio_probe(vg); 181371e6ca61SCristina Ciocan if (ret) { 181471e6ca61SCristina Ciocan pinctrl_unregister(vg->pctl_dev); 181571e6ca61SCristina Ciocan return ret; 181671e6ca61SCristina Ciocan } 181771e6ca61SCristina Ciocan 181871e6ca61SCristina Ciocan platform_set_drvdata(pdev, vg); 181971e6ca61SCristina Ciocan raw_spin_lock_init(&vg->lock); 182071e6ca61SCristina Ciocan pm_runtime_enable(&pdev->dev); 182171e6ca61SCristina Ciocan 182271e6ca61SCristina Ciocan return 0; 182371e6ca61SCristina Ciocan } 182471e6ca61SCristina Ciocan 182571e6ca61SCristina Ciocan static int byt_pinctrl_remove(struct platform_device *pdev) 182671e6ca61SCristina Ciocan { 182771e6ca61SCristina Ciocan struct byt_gpio *vg = platform_get_drvdata(pdev); 182871e6ca61SCristina Ciocan 182971e6ca61SCristina Ciocan pm_runtime_disable(&pdev->dev); 183071e6ca61SCristina Ciocan gpiochip_remove(&vg->chip); 183171e6ca61SCristina Ciocan pinctrl_unregister(vg->pctl_dev); 18325fae8b86SMika Westerberg 18335fae8b86SMika Westerberg return 0; 18345fae8b86SMika Westerberg } 18355fae8b86SMika Westerberg 1836fcc18debSMika Westerberg #ifdef CONFIG_PM_SLEEP 1837fcc18debSMika Westerberg static int byt_gpio_suspend(struct device *dev) 1838fcc18debSMika Westerberg { 1839fcc18debSMika Westerberg struct platform_device *pdev = to_platform_device(dev); 1840fcc18debSMika Westerberg struct byt_gpio *vg = platform_get_drvdata(pdev); 1841fcc18debSMika Westerberg int i; 1842fcc18debSMika Westerberg 184371e6ca61SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 1844fcc18debSMika Westerberg void __iomem *reg; 1845fcc18debSMika Westerberg u32 value; 184671e6ca61SCristina Ciocan unsigned int pin = vg->soc_data->pins[i].number; 1847fcc18debSMika Westerberg 184871e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 184971e6ca61SCristina Ciocan if (!reg) { 185071e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 185171e6ca61SCristina Ciocan "Pin %i: could not retrieve conf0 register\n", 185271e6ca61SCristina Ciocan i); 185371e6ca61SCristina Ciocan continue; 185471e6ca61SCristina Ciocan } 1855fcc18debSMika Westerberg value = readl(reg) & BYT_CONF0_RESTORE_MASK; 1856fcc18debSMika Westerberg vg->saved_context[i].conf0 = value; 1857fcc18debSMika Westerberg 185871e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 1859fcc18debSMika Westerberg value = readl(reg) & BYT_VAL_RESTORE_MASK; 1860fcc18debSMika Westerberg vg->saved_context[i].val = value; 1861fcc18debSMika Westerberg } 1862fcc18debSMika Westerberg 1863fcc18debSMika Westerberg return 0; 1864fcc18debSMika Westerberg } 1865fcc18debSMika Westerberg 1866fcc18debSMika Westerberg static int byt_gpio_resume(struct device *dev) 1867fcc18debSMika Westerberg { 1868fcc18debSMika Westerberg struct platform_device *pdev = to_platform_device(dev); 1869fcc18debSMika Westerberg struct byt_gpio *vg = platform_get_drvdata(pdev); 1870fcc18debSMika Westerberg int i; 1871fcc18debSMika Westerberg 187271e6ca61SCristina Ciocan for (i = 0; i < vg->soc_data->npins; i++) { 1873fcc18debSMika Westerberg void __iomem *reg; 1874fcc18debSMika Westerberg u32 value; 187571e6ca61SCristina Ciocan unsigned int pin = vg->soc_data->pins[i].number; 1876fcc18debSMika Westerberg 187771e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 187871e6ca61SCristina Ciocan if (!reg) { 187971e6ca61SCristina Ciocan dev_warn(&vg->pdev->dev, 188071e6ca61SCristina Ciocan "Pin %i: could not retrieve conf0 register\n", 188171e6ca61SCristina Ciocan i); 188271e6ca61SCristina Ciocan continue; 188371e6ca61SCristina Ciocan } 1884fcc18debSMika Westerberg value = readl(reg); 1885fcc18debSMika Westerberg if ((value & BYT_CONF0_RESTORE_MASK) != 1886fcc18debSMika Westerberg vg->saved_context[i].conf0) { 1887fcc18debSMika Westerberg value &= ~BYT_CONF0_RESTORE_MASK; 1888fcc18debSMika Westerberg value |= vg->saved_context[i].conf0; 1889fcc18debSMika Westerberg writel(value, reg); 1890fcc18debSMika Westerberg dev_info(dev, "restored pin %d conf0 %#08x", i, value); 1891fcc18debSMika Westerberg } 1892fcc18debSMika Westerberg 189371e6ca61SCristina Ciocan reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 1894fcc18debSMika Westerberg value = readl(reg); 1895fcc18debSMika Westerberg if ((value & BYT_VAL_RESTORE_MASK) != 1896fcc18debSMika Westerberg vg->saved_context[i].val) { 1897fcc18debSMika Westerberg u32 v; 1898fcc18debSMika Westerberg 1899fcc18debSMika Westerberg v = value & ~BYT_VAL_RESTORE_MASK; 1900fcc18debSMika Westerberg v |= vg->saved_context[i].val; 1901fcc18debSMika Westerberg if (v != value) { 1902fcc18debSMika Westerberg writel(v, reg); 1903fcc18debSMika Westerberg dev_dbg(dev, "restored pin %d val %#08x\n", 1904fcc18debSMika Westerberg i, v); 1905fcc18debSMika Westerberg } 1906fcc18debSMika Westerberg } 1907fcc18debSMika Westerberg } 1908fcc18debSMika Westerberg 1909fcc18debSMika Westerberg return 0; 1910fcc18debSMika Westerberg } 1911fcc18debSMika Westerberg #endif 1912fcc18debSMika Westerberg 1913ec879f12SMika Westerberg #ifdef CONFIG_PM 19145fae8b86SMika Westerberg static int byt_gpio_runtime_suspend(struct device *dev) 19155fae8b86SMika Westerberg { 19165fae8b86SMika Westerberg return 0; 19175fae8b86SMika Westerberg } 19185fae8b86SMika Westerberg 19195fae8b86SMika Westerberg static int byt_gpio_runtime_resume(struct device *dev) 19205fae8b86SMika Westerberg { 19215fae8b86SMika Westerberg return 0; 19225fae8b86SMika Westerberg } 1923ec879f12SMika Westerberg #endif 19245fae8b86SMika Westerberg 19255fae8b86SMika Westerberg static const struct dev_pm_ops byt_gpio_pm_ops = { 1926fcc18debSMika Westerberg SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) 1927fcc18debSMika Westerberg SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, 1928fcc18debSMika Westerberg NULL) 19295fae8b86SMika Westerberg }; 19305fae8b86SMika Westerberg 19315fae8b86SMika Westerberg static struct platform_driver byt_gpio_driver = { 193271e6ca61SCristina Ciocan .probe = byt_pinctrl_probe, 193371e6ca61SCristina Ciocan .remove = byt_pinctrl_remove, 19345fae8b86SMika Westerberg .driver = { 19355fae8b86SMika Westerberg .name = "byt_gpio", 19365fae8b86SMika Westerberg .pm = &byt_gpio_pm_ops, 19375fae8b86SMika Westerberg .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match), 19385fae8b86SMika Westerberg }, 19395fae8b86SMika Westerberg }; 19405fae8b86SMika Westerberg 19415fae8b86SMika Westerberg static int __init byt_gpio_init(void) 19425fae8b86SMika Westerberg { 19435fae8b86SMika Westerberg return platform_driver_register(&byt_gpio_driver); 19445fae8b86SMika Westerberg } 19455fae8b86SMika Westerberg subsys_initcall(byt_gpio_init); 19465fae8b86SMika Westerberg 19475fae8b86SMika Westerberg static void __exit byt_gpio_exit(void) 19485fae8b86SMika Westerberg { 19495fae8b86SMika Westerberg platform_driver_unregister(&byt_gpio_driver); 19505fae8b86SMika Westerberg } 19515fae8b86SMika Westerberg module_exit(byt_gpio_exit); 1952