18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Pinctrl GPIO driver for Intel Baytrail 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2012-2013, Intel Corporation 68c2ecf20Sopenharmony_ci * Author: Mathias Nyman <mathias.nyman@linux.intel.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/acpi.h> 108c2ecf20Sopenharmony_ci#include <linux/bitops.h> 118c2ecf20Sopenharmony_ci#include <linux/gpio/driver.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 148c2ecf20Sopenharmony_ci#include <linux/io.h> 158c2ecf20Sopenharmony_ci#include <linux/kernel.h> 168c2ecf20Sopenharmony_ci#include <linux/types.h> 178c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 188c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h> 198c2ecf20Sopenharmony_ci#include <linux/property.h> 208c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinctrl.h> 238c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinmux.h> 248c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinconf.h> 258c2ecf20Sopenharmony_ci#include <linux/pinctrl/pinconf-generic.h> 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#include "pinctrl-intel.h" 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* memory mapped register offsets */ 308c2ecf20Sopenharmony_ci#define BYT_CONF0_REG 0x000 318c2ecf20Sopenharmony_ci#define BYT_CONF1_REG 0x004 328c2ecf20Sopenharmony_ci#define BYT_VAL_REG 0x008 338c2ecf20Sopenharmony_ci#define BYT_DFT_REG 0x00c 348c2ecf20Sopenharmony_ci#define BYT_INT_STAT_REG 0x800 358c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_REG 0x9d0 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* BYT_CONF0_REG register bits */ 388c2ecf20Sopenharmony_ci#define BYT_IODEN BIT(31) 398c2ecf20Sopenharmony_ci#define BYT_DIRECT_IRQ_EN BIT(27) 408c2ecf20Sopenharmony_ci#define BYT_TRIG_MASK GENMASK(26, 24) 418c2ecf20Sopenharmony_ci#define BYT_TRIG_NEG BIT(26) 428c2ecf20Sopenharmony_ci#define BYT_TRIG_POS BIT(25) 438c2ecf20Sopenharmony_ci#define BYT_TRIG_LVL BIT(24) 448c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_EN BIT(20) 458c2ecf20Sopenharmony_ci#define BYT_GLITCH_FILTER_EN BIT(19) 468c2ecf20Sopenharmony_ci#define BYT_GLITCH_F_SLOW_CLK BIT(17) 478c2ecf20Sopenharmony_ci#define BYT_GLITCH_F_FAST_CLK BIT(16) 488c2ecf20Sopenharmony_ci#define BYT_PULL_STR_SHIFT 9 498c2ecf20Sopenharmony_ci#define BYT_PULL_STR_MASK GENMASK(10, 9) 508c2ecf20Sopenharmony_ci#define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) 518c2ecf20Sopenharmony_ci#define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT) 528c2ecf20Sopenharmony_ci#define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT) 538c2ecf20Sopenharmony_ci#define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT) 548c2ecf20Sopenharmony_ci#define BYT_PULL_ASSIGN_SHIFT 7 558c2ecf20Sopenharmony_ci#define BYT_PULL_ASSIGN_MASK GENMASK(8, 7) 568c2ecf20Sopenharmony_ci#define BYT_PULL_ASSIGN_UP (1 << BYT_PULL_ASSIGN_SHIFT) 578c2ecf20Sopenharmony_ci#define BYT_PULL_ASSIGN_DOWN (2 << BYT_PULL_ASSIGN_SHIFT) 588c2ecf20Sopenharmony_ci#define BYT_PIN_MUX GENMASK(2, 0) 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci/* BYT_VAL_REG register bits */ 618c2ecf20Sopenharmony_ci#define BYT_DIR_MASK GENMASK(2, 1) 628c2ecf20Sopenharmony_ci#define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ 638c2ecf20Sopenharmony_ci#define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ 648c2ecf20Sopenharmony_ci#define BYT_LEVEL BIT(0) 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX) 678c2ecf20Sopenharmony_ci#define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci/* BYT_DEBOUNCE_REG bits */ 708c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_MASK GENMASK(2, 0) 718c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_375US 1 728c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_750US 2 738c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_1500US 3 748c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_3MS 4 758c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_6MS 5 768c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_12MS 6 778c2ecf20Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_24MS 7 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci#define BYT_NGPIO_SCORE 102 808c2ecf20Sopenharmony_ci#define BYT_NGPIO_NCORE 28 818c2ecf20Sopenharmony_ci#define BYT_NGPIO_SUS 44 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define BYT_SCORE_ACPI_UID "1" 848c2ecf20Sopenharmony_ci#define BYT_NCORE_ACPI_UID "2" 858c2ecf20Sopenharmony_ci#define BYT_SUS_ACPI_UID "3" 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* 888c2ecf20Sopenharmony_ci * This is the function value most pins have for GPIO muxing. If the value 898c2ecf20Sopenharmony_ci * differs from the default one, it must be explicitly mentioned. Otherwise, the 908c2ecf20Sopenharmony_ci * pin control implementation will set the muxing value to default GPIO if it 918c2ecf20Sopenharmony_ci * does not find a match for the requested function. 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_ci#define BYT_DEFAULT_GPIO_MUX 0 948c2ecf20Sopenharmony_ci#define BYT_ALTER_GPIO_MUX 1 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistruct intel_pad_context { 978c2ecf20Sopenharmony_ci u32 conf0; 988c2ecf20Sopenharmony_ci u32 val; 998c2ecf20Sopenharmony_ci}; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci#define COMMUNITY(p, n, map) \ 1028c2ecf20Sopenharmony_ci { \ 1038c2ecf20Sopenharmony_ci .pin_base = (p), \ 1048c2ecf20Sopenharmony_ci .npins = (n), \ 1058c2ecf20Sopenharmony_ci .pad_map = (map),\ 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ 1098c2ecf20Sopenharmony_cistatic const struct pinctrl_pin_desc byt_score_pins[] = { 1108c2ecf20Sopenharmony_ci PINCTRL_PIN(0, "SATA_GP0"), 1118c2ecf20Sopenharmony_ci PINCTRL_PIN(1, "SATA_GP1"), 1128c2ecf20Sopenharmony_ci PINCTRL_PIN(2, "SATA_LED#"), 1138c2ecf20Sopenharmony_ci PINCTRL_PIN(3, "PCIE_CLKREQ0"), 1148c2ecf20Sopenharmony_ci PINCTRL_PIN(4, "PCIE_CLKREQ1"), 1158c2ecf20Sopenharmony_ci PINCTRL_PIN(5, "PCIE_CLKREQ2"), 1168c2ecf20Sopenharmony_ci PINCTRL_PIN(6, "PCIE_CLKREQ3"), 1178c2ecf20Sopenharmony_ci PINCTRL_PIN(7, "SD3_WP"), 1188c2ecf20Sopenharmony_ci PINCTRL_PIN(8, "HDA_RST"), 1198c2ecf20Sopenharmony_ci PINCTRL_PIN(9, "HDA_SYNC"), 1208c2ecf20Sopenharmony_ci PINCTRL_PIN(10, "HDA_CLK"), 1218c2ecf20Sopenharmony_ci PINCTRL_PIN(11, "HDA_SDO"), 1228c2ecf20Sopenharmony_ci PINCTRL_PIN(12, "HDA_SDI0"), 1238c2ecf20Sopenharmony_ci PINCTRL_PIN(13, "HDA_SDI1"), 1248c2ecf20Sopenharmony_ci PINCTRL_PIN(14, "GPIO_S0_SC14"), 1258c2ecf20Sopenharmony_ci PINCTRL_PIN(15, "GPIO_S0_SC15"), 1268c2ecf20Sopenharmony_ci PINCTRL_PIN(16, "MMC1_CLK"), 1278c2ecf20Sopenharmony_ci PINCTRL_PIN(17, "MMC1_D0"), 1288c2ecf20Sopenharmony_ci PINCTRL_PIN(18, "MMC1_D1"), 1298c2ecf20Sopenharmony_ci PINCTRL_PIN(19, "MMC1_D2"), 1308c2ecf20Sopenharmony_ci PINCTRL_PIN(20, "MMC1_D3"), 1318c2ecf20Sopenharmony_ci PINCTRL_PIN(21, "MMC1_D4"), 1328c2ecf20Sopenharmony_ci PINCTRL_PIN(22, "MMC1_D5"), 1338c2ecf20Sopenharmony_ci PINCTRL_PIN(23, "MMC1_D6"), 1348c2ecf20Sopenharmony_ci PINCTRL_PIN(24, "MMC1_D7"), 1358c2ecf20Sopenharmony_ci PINCTRL_PIN(25, "MMC1_CMD"), 1368c2ecf20Sopenharmony_ci PINCTRL_PIN(26, "MMC1_RST"), 1378c2ecf20Sopenharmony_ci PINCTRL_PIN(27, "SD2_CLK"), 1388c2ecf20Sopenharmony_ci PINCTRL_PIN(28, "SD2_D0"), 1398c2ecf20Sopenharmony_ci PINCTRL_PIN(29, "SD2_D1"), 1408c2ecf20Sopenharmony_ci PINCTRL_PIN(30, "SD2_D2"), 1418c2ecf20Sopenharmony_ci PINCTRL_PIN(31, "SD2_D3_CD"), 1428c2ecf20Sopenharmony_ci PINCTRL_PIN(32, "SD2_CMD"), 1438c2ecf20Sopenharmony_ci PINCTRL_PIN(33, "SD3_CLK"), 1448c2ecf20Sopenharmony_ci PINCTRL_PIN(34, "SD3_D0"), 1458c2ecf20Sopenharmony_ci PINCTRL_PIN(35, "SD3_D1"), 1468c2ecf20Sopenharmony_ci PINCTRL_PIN(36, "SD3_D2"), 1478c2ecf20Sopenharmony_ci PINCTRL_PIN(37, "SD3_D3"), 1488c2ecf20Sopenharmony_ci PINCTRL_PIN(38, "SD3_CD"), 1498c2ecf20Sopenharmony_ci PINCTRL_PIN(39, "SD3_CMD"), 1508c2ecf20Sopenharmony_ci PINCTRL_PIN(40, "SD3_1P8EN"), 1518c2ecf20Sopenharmony_ci PINCTRL_PIN(41, "SD3_PWREN#"), 1528c2ecf20Sopenharmony_ci PINCTRL_PIN(42, "ILB_LPC_AD0"), 1538c2ecf20Sopenharmony_ci PINCTRL_PIN(43, "ILB_LPC_AD1"), 1548c2ecf20Sopenharmony_ci PINCTRL_PIN(44, "ILB_LPC_AD2"), 1558c2ecf20Sopenharmony_ci PINCTRL_PIN(45, "ILB_LPC_AD3"), 1568c2ecf20Sopenharmony_ci PINCTRL_PIN(46, "ILB_LPC_FRAME"), 1578c2ecf20Sopenharmony_ci PINCTRL_PIN(47, "ILB_LPC_CLK0"), 1588c2ecf20Sopenharmony_ci PINCTRL_PIN(48, "ILB_LPC_CLK1"), 1598c2ecf20Sopenharmony_ci PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), 1608c2ecf20Sopenharmony_ci PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), 1618c2ecf20Sopenharmony_ci PINCTRL_PIN(51, "PCU_SMB_DATA"), 1628c2ecf20Sopenharmony_ci PINCTRL_PIN(52, "PCU_SMB_CLK"), 1638c2ecf20Sopenharmony_ci PINCTRL_PIN(53, "PCU_SMB_ALERT"), 1648c2ecf20Sopenharmony_ci PINCTRL_PIN(54, "ILB_8254_SPKR"), 1658c2ecf20Sopenharmony_ci PINCTRL_PIN(55, "GPIO_S0_SC55"), 1668c2ecf20Sopenharmony_ci PINCTRL_PIN(56, "GPIO_S0_SC56"), 1678c2ecf20Sopenharmony_ci PINCTRL_PIN(57, "GPIO_S0_SC57"), 1688c2ecf20Sopenharmony_ci PINCTRL_PIN(58, "GPIO_S0_SC58"), 1698c2ecf20Sopenharmony_ci PINCTRL_PIN(59, "GPIO_S0_SC59"), 1708c2ecf20Sopenharmony_ci PINCTRL_PIN(60, "GPIO_S0_SC60"), 1718c2ecf20Sopenharmony_ci PINCTRL_PIN(61, "GPIO_S0_SC61"), 1728c2ecf20Sopenharmony_ci PINCTRL_PIN(62, "LPE_I2S2_CLK"), 1738c2ecf20Sopenharmony_ci PINCTRL_PIN(63, "LPE_I2S2_FRM"), 1748c2ecf20Sopenharmony_ci PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), 1758c2ecf20Sopenharmony_ci PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), 1768c2ecf20Sopenharmony_ci PINCTRL_PIN(66, "SIO_SPI_CS"), 1778c2ecf20Sopenharmony_ci PINCTRL_PIN(67, "SIO_SPI_MISO"), 1788c2ecf20Sopenharmony_ci PINCTRL_PIN(68, "SIO_SPI_MOSI"), 1798c2ecf20Sopenharmony_ci PINCTRL_PIN(69, "SIO_SPI_CLK"), 1808c2ecf20Sopenharmony_ci PINCTRL_PIN(70, "SIO_UART1_RXD"), 1818c2ecf20Sopenharmony_ci PINCTRL_PIN(71, "SIO_UART1_TXD"), 1828c2ecf20Sopenharmony_ci PINCTRL_PIN(72, "SIO_UART1_RTS"), 1838c2ecf20Sopenharmony_ci PINCTRL_PIN(73, "SIO_UART1_CTS"), 1848c2ecf20Sopenharmony_ci PINCTRL_PIN(74, "SIO_UART2_RXD"), 1858c2ecf20Sopenharmony_ci PINCTRL_PIN(75, "SIO_UART2_TXD"), 1868c2ecf20Sopenharmony_ci PINCTRL_PIN(76, "SIO_UART2_RTS"), 1878c2ecf20Sopenharmony_ci PINCTRL_PIN(77, "SIO_UART2_CTS"), 1888c2ecf20Sopenharmony_ci PINCTRL_PIN(78, "SIO_I2C0_DATA"), 1898c2ecf20Sopenharmony_ci PINCTRL_PIN(79, "SIO_I2C0_CLK"), 1908c2ecf20Sopenharmony_ci PINCTRL_PIN(80, "SIO_I2C1_DATA"), 1918c2ecf20Sopenharmony_ci PINCTRL_PIN(81, "SIO_I2C1_CLK"), 1928c2ecf20Sopenharmony_ci PINCTRL_PIN(82, "SIO_I2C2_DATA"), 1938c2ecf20Sopenharmony_ci PINCTRL_PIN(83, "SIO_I2C2_CLK"), 1948c2ecf20Sopenharmony_ci PINCTRL_PIN(84, "SIO_I2C3_DATA"), 1958c2ecf20Sopenharmony_ci PINCTRL_PIN(85, "SIO_I2C3_CLK"), 1968c2ecf20Sopenharmony_ci PINCTRL_PIN(86, "SIO_I2C4_DATA"), 1978c2ecf20Sopenharmony_ci PINCTRL_PIN(87, "SIO_I2C4_CLK"), 1988c2ecf20Sopenharmony_ci PINCTRL_PIN(88, "SIO_I2C5_DATA"), 1998c2ecf20Sopenharmony_ci PINCTRL_PIN(89, "SIO_I2C5_CLK"), 2008c2ecf20Sopenharmony_ci PINCTRL_PIN(90, "SIO_I2C6_DATA"), 2018c2ecf20Sopenharmony_ci PINCTRL_PIN(91, "SIO_I2C6_CLK"), 2028c2ecf20Sopenharmony_ci PINCTRL_PIN(92, "GPIO_S0_SC92"), 2038c2ecf20Sopenharmony_ci PINCTRL_PIN(93, "GPIO_S0_SC93"), 2048c2ecf20Sopenharmony_ci PINCTRL_PIN(94, "SIO_PWM0"), 2058c2ecf20Sopenharmony_ci PINCTRL_PIN(95, "SIO_PWM1"), 2068c2ecf20Sopenharmony_ci PINCTRL_PIN(96, "PMC_PLT_CLK0"), 2078c2ecf20Sopenharmony_ci PINCTRL_PIN(97, "PMC_PLT_CLK1"), 2088c2ecf20Sopenharmony_ci PINCTRL_PIN(98, "PMC_PLT_CLK2"), 2098c2ecf20Sopenharmony_ci PINCTRL_PIN(99, "PMC_PLT_CLK3"), 2108c2ecf20Sopenharmony_ci PINCTRL_PIN(100, "PMC_PLT_CLK4"), 2118c2ecf20Sopenharmony_ci PINCTRL_PIN(101, "PMC_PLT_CLK5"), 2128c2ecf20Sopenharmony_ci}; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { 2158c2ecf20Sopenharmony_ci 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 2168c2ecf20Sopenharmony_ci 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, 2178c2ecf20Sopenharmony_ci 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, 2188c2ecf20Sopenharmony_ci 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 2198c2ecf20Sopenharmony_ci 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, 2208c2ecf20Sopenharmony_ci 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, 2218c2ecf20Sopenharmony_ci 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 2228c2ecf20Sopenharmony_ci 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, 2238c2ecf20Sopenharmony_ci 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 2248c2ecf20Sopenharmony_ci 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, 2258c2ecf20Sopenharmony_ci 97, 100, 2268c2ecf20Sopenharmony_ci}; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci/* SCORE groups */ 2298c2ecf20Sopenharmony_cistatic const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; 2308c2ecf20Sopenharmony_cistatic const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic const unsigned int byt_score_pwm0_pins[] = { 94 }; 2338c2ecf20Sopenharmony_cistatic const unsigned int byt_score_pwm1_pins[] = { 95 }; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_cistatic const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; 2388c2ecf20Sopenharmony_cistatic const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; 2398c2ecf20Sopenharmony_cistatic const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; 2408c2ecf20Sopenharmony_cistatic const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; 2418c2ecf20Sopenharmony_cistatic const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; 2428c2ecf20Sopenharmony_cistatic const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; 2438c2ecf20Sopenharmony_cistatic const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_cistatic const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; 2468c2ecf20Sopenharmony_cistatic const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; 2478c2ecf20Sopenharmony_cistatic const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic const unsigned int byt_score_sdcard_pins[] = { 2508c2ecf20Sopenharmony_ci 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 2518c2ecf20Sopenharmony_ci}; 2528c2ecf20Sopenharmony_cistatic const unsigned int byt_score_sdcard_mux_values[] = { 2538c2ecf20Sopenharmony_ci 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2548c2ecf20Sopenharmony_ci}; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_cistatic const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_cistatic const unsigned int byt_score_emmc_pins[] = { 2598c2ecf20Sopenharmony_ci 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 2608c2ecf20Sopenharmony_ci}; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_cistatic const unsigned int byt_score_ilb_lpc_pins[] = { 2638c2ecf20Sopenharmony_ci 42, 43, 44, 45, 46, 47, 48, 49, 50, 2648c2ecf20Sopenharmony_ci}; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_cistatic const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic const unsigned int byt_score_plt_clk0_pins[] = { 96 }; 2698c2ecf20Sopenharmony_cistatic const unsigned int byt_score_plt_clk1_pins[] = { 97 }; 2708c2ecf20Sopenharmony_cistatic const unsigned int byt_score_plt_clk2_pins[] = { 98 }; 2718c2ecf20Sopenharmony_cistatic const unsigned int byt_score_plt_clk3_pins[] = { 99 }; 2728c2ecf20Sopenharmony_cistatic const unsigned int byt_score_plt_clk4_pins[] = { 100 }; 2738c2ecf20Sopenharmony_cistatic const unsigned int byt_score_plt_clk5_pins[] = { 101 }; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic const struct intel_pingroup byt_score_groups[] = { 2788c2ecf20Sopenharmony_ci PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1), 2798c2ecf20Sopenharmony_ci PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1), 2808c2ecf20Sopenharmony_ci PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1), 2818c2ecf20Sopenharmony_ci PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1), 2828c2ecf20Sopenharmony_ci PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1), 2838c2ecf20Sopenharmony_ci PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1), 2848c2ecf20Sopenharmony_ci PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1), 2858c2ecf20Sopenharmony_ci PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1), 2868c2ecf20Sopenharmony_ci PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1), 2878c2ecf20Sopenharmony_ci PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1), 2888c2ecf20Sopenharmony_ci PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1), 2898c2ecf20Sopenharmony_ci PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1), 2908c2ecf20Sopenharmony_ci PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1), 2918c2ecf20Sopenharmony_ci PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1), 2928c2ecf20Sopenharmony_ci PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1), 2938c2ecf20Sopenharmony_ci PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values), 2948c2ecf20Sopenharmony_ci PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1), 2958c2ecf20Sopenharmony_ci PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1), 2968c2ecf20Sopenharmony_ci PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1), 2978c2ecf20Sopenharmony_ci PIN_GROUP("sata_grp", byt_score_sata_pins, 1), 2988c2ecf20Sopenharmony_ci PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1), 2998c2ecf20Sopenharmony_ci PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1), 3008c2ecf20Sopenharmony_ci PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1), 3018c2ecf20Sopenharmony_ci PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1), 3028c2ecf20Sopenharmony_ci PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1), 3038c2ecf20Sopenharmony_ci PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1), 3048c2ecf20Sopenharmony_ci PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1), 3058c2ecf20Sopenharmony_ci}; 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_cistatic const char * const byt_score_uart_groups[] = { 3088c2ecf20Sopenharmony_ci "uart1_grp", "uart2_grp", 3098c2ecf20Sopenharmony_ci}; 3108c2ecf20Sopenharmony_cistatic const char * const byt_score_pwm_groups[] = { 3118c2ecf20Sopenharmony_ci "pwm0_grp", "pwm1_grp", 3128c2ecf20Sopenharmony_ci}; 3138c2ecf20Sopenharmony_cistatic const char * const byt_score_ssp_groups[] = { 3148c2ecf20Sopenharmony_ci "ssp0_grp", "ssp1_grp", "ssp2_grp", 3158c2ecf20Sopenharmony_ci}; 3168c2ecf20Sopenharmony_cistatic const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; 3178c2ecf20Sopenharmony_cistatic const char * const byt_score_i2c_groups[] = { 3188c2ecf20Sopenharmony_ci "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", 3198c2ecf20Sopenharmony_ci "i2c6_grp", 3208c2ecf20Sopenharmony_ci}; 3218c2ecf20Sopenharmony_cistatic const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; 3228c2ecf20Sopenharmony_cistatic const char * const byt_score_sdio_groups[] = { "sdio_grp" }; 3238c2ecf20Sopenharmony_cistatic const char * const byt_score_emmc_groups[] = { "emmc_grp" }; 3248c2ecf20Sopenharmony_cistatic const char * const byt_score_lpc_groups[] = { "lpc_grp" }; 3258c2ecf20Sopenharmony_cistatic const char * const byt_score_sata_groups[] = { "sata_grp" }; 3268c2ecf20Sopenharmony_cistatic const char * const byt_score_plt_clk_groups[] = { 3278c2ecf20Sopenharmony_ci "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 3288c2ecf20Sopenharmony_ci "plt_clk4_grp", "plt_clk5_grp", 3298c2ecf20Sopenharmony_ci}; 3308c2ecf20Sopenharmony_cistatic const char * const byt_score_smbus_groups[] = { "smbus_grp" }; 3318c2ecf20Sopenharmony_cistatic const char * const byt_score_gpio_groups[] = { 3328c2ecf20Sopenharmony_ci "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", 3338c2ecf20Sopenharmony_ci "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", 3348c2ecf20Sopenharmony_ci "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", 3358c2ecf20Sopenharmony_ci "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", 3368c2ecf20Sopenharmony_ci "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 3378c2ecf20Sopenharmony_ci "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", 3388c2ecf20Sopenharmony_ci}; 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic const struct intel_function byt_score_functions[] = { 3418c2ecf20Sopenharmony_ci FUNCTION("uart", byt_score_uart_groups), 3428c2ecf20Sopenharmony_ci FUNCTION("pwm", byt_score_pwm_groups), 3438c2ecf20Sopenharmony_ci FUNCTION("ssp", byt_score_ssp_groups), 3448c2ecf20Sopenharmony_ci FUNCTION("spi", byt_score_spi_groups), 3458c2ecf20Sopenharmony_ci FUNCTION("i2c", byt_score_i2c_groups), 3468c2ecf20Sopenharmony_ci FUNCTION("sdcard", byt_score_sdcard_groups), 3478c2ecf20Sopenharmony_ci FUNCTION("sdio", byt_score_sdio_groups), 3488c2ecf20Sopenharmony_ci FUNCTION("emmc", byt_score_emmc_groups), 3498c2ecf20Sopenharmony_ci FUNCTION("lpc", byt_score_lpc_groups), 3508c2ecf20Sopenharmony_ci FUNCTION("sata", byt_score_sata_groups), 3518c2ecf20Sopenharmony_ci FUNCTION("plt_clk", byt_score_plt_clk_groups), 3528c2ecf20Sopenharmony_ci FUNCTION("smbus", byt_score_smbus_groups), 3538c2ecf20Sopenharmony_ci FUNCTION("gpio", byt_score_gpio_groups), 3548c2ecf20Sopenharmony_ci}; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_cistatic const struct intel_community byt_score_communities[] = { 3578c2ecf20Sopenharmony_ci COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), 3588c2ecf20Sopenharmony_ci}; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_cistatic const struct intel_pinctrl_soc_data byt_score_soc_data = { 3618c2ecf20Sopenharmony_ci .uid = BYT_SCORE_ACPI_UID, 3628c2ecf20Sopenharmony_ci .pins = byt_score_pins, 3638c2ecf20Sopenharmony_ci .npins = ARRAY_SIZE(byt_score_pins), 3648c2ecf20Sopenharmony_ci .groups = byt_score_groups, 3658c2ecf20Sopenharmony_ci .ngroups = ARRAY_SIZE(byt_score_groups), 3668c2ecf20Sopenharmony_ci .functions = byt_score_functions, 3678c2ecf20Sopenharmony_ci .nfunctions = ARRAY_SIZE(byt_score_functions), 3688c2ecf20Sopenharmony_ci .communities = byt_score_communities, 3698c2ecf20Sopenharmony_ci .ncommunities = ARRAY_SIZE(byt_score_communities), 3708c2ecf20Sopenharmony_ci}; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci/* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */ 3738c2ecf20Sopenharmony_cistatic const struct pinctrl_pin_desc byt_sus_pins[] = { 3748c2ecf20Sopenharmony_ci PINCTRL_PIN(0, "GPIO_S50"), 3758c2ecf20Sopenharmony_ci PINCTRL_PIN(1, "GPIO_S51"), 3768c2ecf20Sopenharmony_ci PINCTRL_PIN(2, "GPIO_S52"), 3778c2ecf20Sopenharmony_ci PINCTRL_PIN(3, "GPIO_S53"), 3788c2ecf20Sopenharmony_ci PINCTRL_PIN(4, "GPIO_S54"), 3798c2ecf20Sopenharmony_ci PINCTRL_PIN(5, "GPIO_S55"), 3808c2ecf20Sopenharmony_ci PINCTRL_PIN(6, "GPIO_S56"), 3818c2ecf20Sopenharmony_ci PINCTRL_PIN(7, "GPIO_S57"), 3828c2ecf20Sopenharmony_ci PINCTRL_PIN(8, "GPIO_S58"), 3838c2ecf20Sopenharmony_ci PINCTRL_PIN(9, "GPIO_S59"), 3848c2ecf20Sopenharmony_ci PINCTRL_PIN(10, "GPIO_S510"), 3858c2ecf20Sopenharmony_ci PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), 3868c2ecf20Sopenharmony_ci PINCTRL_PIN(12, "PMC_SUSCLK0"), 3878c2ecf20Sopenharmony_ci PINCTRL_PIN(13, "GPIO_S513"), 3888c2ecf20Sopenharmony_ci PINCTRL_PIN(14, "USB_ULPI_RST"), 3898c2ecf20Sopenharmony_ci PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), 3908c2ecf20Sopenharmony_ci PINCTRL_PIN(16, "PMC_PWRBTN"), 3918c2ecf20Sopenharmony_ci PINCTRL_PIN(17, "GPIO_S517"), 3928c2ecf20Sopenharmony_ci PINCTRL_PIN(18, "PMC_SUS_STAT"), 3938c2ecf20Sopenharmony_ci PINCTRL_PIN(19, "USB_OC0"), 3948c2ecf20Sopenharmony_ci PINCTRL_PIN(20, "USB_OC1"), 3958c2ecf20Sopenharmony_ci PINCTRL_PIN(21, "PCU_SPI_CS1"), 3968c2ecf20Sopenharmony_ci PINCTRL_PIN(22, "GPIO_S522"), 3978c2ecf20Sopenharmony_ci PINCTRL_PIN(23, "GPIO_S523"), 3988c2ecf20Sopenharmony_ci PINCTRL_PIN(24, "GPIO_S524"), 3998c2ecf20Sopenharmony_ci PINCTRL_PIN(25, "GPIO_S525"), 4008c2ecf20Sopenharmony_ci PINCTRL_PIN(26, "GPIO_S526"), 4018c2ecf20Sopenharmony_ci PINCTRL_PIN(27, "GPIO_S527"), 4028c2ecf20Sopenharmony_ci PINCTRL_PIN(28, "GPIO_S528"), 4038c2ecf20Sopenharmony_ci PINCTRL_PIN(29, "GPIO_S529"), 4048c2ecf20Sopenharmony_ci PINCTRL_PIN(30, "GPIO_S530"), 4058c2ecf20Sopenharmony_ci PINCTRL_PIN(31, "USB_ULPI_CLK"), 4068c2ecf20Sopenharmony_ci PINCTRL_PIN(32, "USB_ULPI_DATA0"), 4078c2ecf20Sopenharmony_ci PINCTRL_PIN(33, "USB_ULPI_DATA1"), 4088c2ecf20Sopenharmony_ci PINCTRL_PIN(34, "USB_ULPI_DATA2"), 4098c2ecf20Sopenharmony_ci PINCTRL_PIN(35, "USB_ULPI_DATA3"), 4108c2ecf20Sopenharmony_ci PINCTRL_PIN(36, "USB_ULPI_DATA4"), 4118c2ecf20Sopenharmony_ci PINCTRL_PIN(37, "USB_ULPI_DATA5"), 4128c2ecf20Sopenharmony_ci PINCTRL_PIN(38, "USB_ULPI_DATA6"), 4138c2ecf20Sopenharmony_ci PINCTRL_PIN(39, "USB_ULPI_DATA7"), 4148c2ecf20Sopenharmony_ci PINCTRL_PIN(40, "USB_ULPI_DIR"), 4158c2ecf20Sopenharmony_ci PINCTRL_PIN(41, "USB_ULPI_NXT"), 4168c2ecf20Sopenharmony_ci PINCTRL_PIN(42, "USB_ULPI_STP"), 4178c2ecf20Sopenharmony_ci PINCTRL_PIN(43, "USB_ULPI_REFCLK"), 4188c2ecf20Sopenharmony_ci}; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 4218c2ecf20Sopenharmony_ci 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 4228c2ecf20Sopenharmony_ci 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, 4238c2ecf20Sopenharmony_ci 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 4248c2ecf20Sopenharmony_ci 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, 4258c2ecf20Sopenharmony_ci 52, 53, 59, 40, 4268c2ecf20Sopenharmony_ci}; 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; 4298c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 }; 4308c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 }; 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_usb_ulpi_pins[] = { 4338c2ecf20Sopenharmony_ci 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 4348c2ecf20Sopenharmony_ci}; 4358c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_usb_ulpi_mode_values[] = { 4368c2ecf20Sopenharmony_ci 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4378c2ecf20Sopenharmony_ci}; 4388c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = { 4398c2ecf20Sopenharmony_ci 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4408c2ecf20Sopenharmony_ci}; 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; 4438c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 }; 4448c2ecf20Sopenharmony_cistatic const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 }; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_cistatic const struct intel_pingroup byt_sus_groups[] = { 4478c2ecf20Sopenharmony_ci PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values), 4488c2ecf20Sopenharmony_ci PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values), 4498c2ecf20Sopenharmony_ci PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values), 4508c2ecf20Sopenharmony_ci PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values), 4518c2ecf20Sopenharmony_ci PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values), 4528c2ecf20Sopenharmony_ci PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values), 4538c2ecf20Sopenharmony_ci}; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_cistatic const char * const byt_sus_usb_groups[] = { 4568c2ecf20Sopenharmony_ci "usb_oc_grp", "usb_ulpi_grp", 4578c2ecf20Sopenharmony_ci}; 4588c2ecf20Sopenharmony_cistatic const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; 4598c2ecf20Sopenharmony_cistatic const char * const byt_sus_gpio_groups[] = { 4608c2ecf20Sopenharmony_ci "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio", 4618c2ecf20Sopenharmony_ci}; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_cistatic const struct intel_function byt_sus_functions[] = { 4648c2ecf20Sopenharmony_ci FUNCTION("usb", byt_sus_usb_groups), 4658c2ecf20Sopenharmony_ci FUNCTION("spi", byt_sus_spi_groups), 4668c2ecf20Sopenharmony_ci FUNCTION("gpio", byt_sus_gpio_groups), 4678c2ecf20Sopenharmony_ci}; 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_cistatic const struct intel_community byt_sus_communities[] = { 4708c2ecf20Sopenharmony_ci COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), 4718c2ecf20Sopenharmony_ci}; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_cistatic const struct intel_pinctrl_soc_data byt_sus_soc_data = { 4748c2ecf20Sopenharmony_ci .uid = BYT_SUS_ACPI_UID, 4758c2ecf20Sopenharmony_ci .pins = byt_sus_pins, 4768c2ecf20Sopenharmony_ci .npins = ARRAY_SIZE(byt_sus_pins), 4778c2ecf20Sopenharmony_ci .groups = byt_sus_groups, 4788c2ecf20Sopenharmony_ci .ngroups = ARRAY_SIZE(byt_sus_groups), 4798c2ecf20Sopenharmony_ci .functions = byt_sus_functions, 4808c2ecf20Sopenharmony_ci .nfunctions = ARRAY_SIZE(byt_sus_functions), 4818c2ecf20Sopenharmony_ci .communities = byt_sus_communities, 4828c2ecf20Sopenharmony_ci .ncommunities = ARRAY_SIZE(byt_sus_communities), 4838c2ecf20Sopenharmony_ci}; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_cistatic const struct pinctrl_pin_desc byt_ncore_pins[] = { 4868c2ecf20Sopenharmony_ci PINCTRL_PIN(0, "HV_DDI0_HPD"), 4878c2ecf20Sopenharmony_ci PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"), 4888c2ecf20Sopenharmony_ci PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"), 4898c2ecf20Sopenharmony_ci PINCTRL_PIN(3, "PANEL0_VDDEN"), 4908c2ecf20Sopenharmony_ci PINCTRL_PIN(4, "PANEL0_BKLTEN"), 4918c2ecf20Sopenharmony_ci PINCTRL_PIN(5, "PANEL0_BKLTCTL"), 4928c2ecf20Sopenharmony_ci PINCTRL_PIN(6, "HV_DDI1_HPD"), 4938c2ecf20Sopenharmony_ci PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"), 4948c2ecf20Sopenharmony_ci PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"), 4958c2ecf20Sopenharmony_ci PINCTRL_PIN(9, "PANEL1_VDDEN"), 4968c2ecf20Sopenharmony_ci PINCTRL_PIN(10, "PANEL1_BKLTEN"), 4978c2ecf20Sopenharmony_ci PINCTRL_PIN(11, "PANEL1_BKLTCTL"), 4988c2ecf20Sopenharmony_ci PINCTRL_PIN(12, "GP_INTD_DSI_TE1"), 4998c2ecf20Sopenharmony_ci PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"), 5008c2ecf20Sopenharmony_ci PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"), 5018c2ecf20Sopenharmony_ci PINCTRL_PIN(15, "GP_CAMERASB00"), 5028c2ecf20Sopenharmony_ci PINCTRL_PIN(16, "GP_CAMERASB01"), 5038c2ecf20Sopenharmony_ci PINCTRL_PIN(17, "GP_CAMERASB02"), 5048c2ecf20Sopenharmony_ci PINCTRL_PIN(18, "GP_CAMERASB03"), 5058c2ecf20Sopenharmony_ci PINCTRL_PIN(19, "GP_CAMERASB04"), 5068c2ecf20Sopenharmony_ci PINCTRL_PIN(20, "GP_CAMERASB05"), 5078c2ecf20Sopenharmony_ci PINCTRL_PIN(21, "GP_CAMERASB06"), 5088c2ecf20Sopenharmony_ci PINCTRL_PIN(22, "GP_CAMERASB07"), 5098c2ecf20Sopenharmony_ci PINCTRL_PIN(23, "GP_CAMERASB08"), 5108c2ecf20Sopenharmony_ci PINCTRL_PIN(24, "GP_CAMERASB09"), 5118c2ecf20Sopenharmony_ci PINCTRL_PIN(25, "GP_CAMERASB10"), 5128c2ecf20Sopenharmony_ci PINCTRL_PIN(26, "GP_CAMERASB11"), 5138c2ecf20Sopenharmony_ci PINCTRL_PIN(27, "GP_INTD_DSI_TE2"), 5148c2ecf20Sopenharmony_ci}; 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_cistatic const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 5178c2ecf20Sopenharmony_ci 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 5188c2ecf20Sopenharmony_ci 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, 5198c2ecf20Sopenharmony_ci 3, 6, 10, 13, 2, 5, 9, 7, 5208c2ecf20Sopenharmony_ci}; 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_cistatic const struct intel_community byt_ncore_communities[] = { 5238c2ecf20Sopenharmony_ci COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), 5248c2ecf20Sopenharmony_ci}; 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_cistatic const struct intel_pinctrl_soc_data byt_ncore_soc_data = { 5278c2ecf20Sopenharmony_ci .uid = BYT_NCORE_ACPI_UID, 5288c2ecf20Sopenharmony_ci .pins = byt_ncore_pins, 5298c2ecf20Sopenharmony_ci .npins = ARRAY_SIZE(byt_ncore_pins), 5308c2ecf20Sopenharmony_ci .communities = byt_ncore_communities, 5318c2ecf20Sopenharmony_ci .ncommunities = ARRAY_SIZE(byt_ncore_communities), 5328c2ecf20Sopenharmony_ci}; 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_cistatic const struct intel_pinctrl_soc_data *byt_soc_data[] = { 5358c2ecf20Sopenharmony_ci &byt_score_soc_data, 5368c2ecf20Sopenharmony_ci &byt_sus_soc_data, 5378c2ecf20Sopenharmony_ci &byt_ncore_soc_data, 5388c2ecf20Sopenharmony_ci NULL 5398c2ecf20Sopenharmony_ci}; 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(byt_lock); 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_cistatic struct intel_community *byt_get_community(struct intel_pinctrl *vg, 5448c2ecf20Sopenharmony_ci unsigned int pin) 5458c2ecf20Sopenharmony_ci{ 5468c2ecf20Sopenharmony_ci struct intel_community *comm; 5478c2ecf20Sopenharmony_ci int i; 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci for (i = 0; i < vg->ncommunities; i++) { 5508c2ecf20Sopenharmony_ci comm = vg->communities + i; 5518c2ecf20Sopenharmony_ci if (pin < comm->pin_base + comm->npins && pin >= comm->pin_base) 5528c2ecf20Sopenharmony_ci return comm; 5538c2ecf20Sopenharmony_ci } 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci return NULL; 5568c2ecf20Sopenharmony_ci} 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_cistatic void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset, 5598c2ecf20Sopenharmony_ci int reg) 5608c2ecf20Sopenharmony_ci{ 5618c2ecf20Sopenharmony_ci struct intel_community *comm = byt_get_community(vg, offset); 5628c2ecf20Sopenharmony_ci u32 reg_offset; 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci if (!comm) 5658c2ecf20Sopenharmony_ci return NULL; 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_ci offset -= comm->pin_base; 5688c2ecf20Sopenharmony_ci switch (reg) { 5698c2ecf20Sopenharmony_ci case BYT_INT_STAT_REG: 5708c2ecf20Sopenharmony_ci reg_offset = (offset / 32) * 4; 5718c2ecf20Sopenharmony_ci break; 5728c2ecf20Sopenharmony_ci case BYT_DEBOUNCE_REG: 5738c2ecf20Sopenharmony_ci reg_offset = 0; 5748c2ecf20Sopenharmony_ci break; 5758c2ecf20Sopenharmony_ci default: 5768c2ecf20Sopenharmony_ci reg_offset = comm->pad_map[offset] * 16; 5778c2ecf20Sopenharmony_ci break; 5788c2ecf20Sopenharmony_ci } 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci return comm->pad_regs + reg_offset + reg; 5818c2ecf20Sopenharmony_ci} 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_cistatic int byt_get_groups_count(struct pinctrl_dev *pctldev) 5848c2ecf20Sopenharmony_ci{ 5858c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci return vg->soc->ngroups; 5888c2ecf20Sopenharmony_ci} 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_cistatic const char *byt_get_group_name(struct pinctrl_dev *pctldev, 5918c2ecf20Sopenharmony_ci unsigned int selector) 5928c2ecf20Sopenharmony_ci{ 5938c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci return vg->soc->groups[selector].name; 5968c2ecf20Sopenharmony_ci} 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_cistatic int byt_get_group_pins(struct pinctrl_dev *pctldev, 5998c2ecf20Sopenharmony_ci unsigned int selector, 6008c2ecf20Sopenharmony_ci const unsigned int **pins, 6018c2ecf20Sopenharmony_ci unsigned int *num_pins) 6028c2ecf20Sopenharmony_ci{ 6038c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci *pins = vg->soc->groups[selector].pins; 6068c2ecf20Sopenharmony_ci *num_pins = vg->soc->groups[selector].npins; 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci return 0; 6098c2ecf20Sopenharmony_ci} 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_cistatic const struct pinctrl_ops byt_pinctrl_ops = { 6128c2ecf20Sopenharmony_ci .get_groups_count = byt_get_groups_count, 6138c2ecf20Sopenharmony_ci .get_group_name = byt_get_group_name, 6148c2ecf20Sopenharmony_ci .get_group_pins = byt_get_group_pins, 6158c2ecf20Sopenharmony_ci}; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_cistatic int byt_get_functions_count(struct pinctrl_dev *pctldev) 6188c2ecf20Sopenharmony_ci{ 6198c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci return vg->soc->nfunctions; 6228c2ecf20Sopenharmony_ci} 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_cistatic const char *byt_get_function_name(struct pinctrl_dev *pctldev, 6258c2ecf20Sopenharmony_ci unsigned int selector) 6268c2ecf20Sopenharmony_ci{ 6278c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci return vg->soc->functions[selector].name; 6308c2ecf20Sopenharmony_ci} 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_cistatic int byt_get_function_groups(struct pinctrl_dev *pctldev, 6338c2ecf20Sopenharmony_ci unsigned int selector, 6348c2ecf20Sopenharmony_ci const char * const **groups, 6358c2ecf20Sopenharmony_ci unsigned int *num_groups) 6368c2ecf20Sopenharmony_ci{ 6378c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci *groups = vg->soc->functions[selector].groups; 6408c2ecf20Sopenharmony_ci *num_groups = vg->soc->functions[selector].ngroups; 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci return 0; 6438c2ecf20Sopenharmony_ci} 6448c2ecf20Sopenharmony_ci 6458c2ecf20Sopenharmony_cistatic void byt_set_group_simple_mux(struct intel_pinctrl *vg, 6468c2ecf20Sopenharmony_ci const struct intel_pingroup group, 6478c2ecf20Sopenharmony_ci unsigned int func) 6488c2ecf20Sopenharmony_ci{ 6498c2ecf20Sopenharmony_ci unsigned long flags; 6508c2ecf20Sopenharmony_ci int i; 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci for (i = 0; i < group.npins; i++) { 6558c2ecf20Sopenharmony_ci void __iomem *padcfg0; 6568c2ecf20Sopenharmony_ci u32 value; 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 6598c2ecf20Sopenharmony_ci if (!padcfg0) { 6608c2ecf20Sopenharmony_ci dev_warn(vg->dev, 6618c2ecf20Sopenharmony_ci "Group %s, pin %i not muxed (no padcfg0)\n", 6628c2ecf20Sopenharmony_ci group.name, i); 6638c2ecf20Sopenharmony_ci continue; 6648c2ecf20Sopenharmony_ci } 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci value = readl(padcfg0); 6678c2ecf20Sopenharmony_ci value &= ~BYT_PIN_MUX; 6688c2ecf20Sopenharmony_ci value |= func; 6698c2ecf20Sopenharmony_ci writel(value, padcfg0); 6708c2ecf20Sopenharmony_ci } 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 6738c2ecf20Sopenharmony_ci} 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_cistatic void byt_set_group_mixed_mux(struct intel_pinctrl *vg, 6768c2ecf20Sopenharmony_ci const struct intel_pingroup group, 6778c2ecf20Sopenharmony_ci const unsigned int *func) 6788c2ecf20Sopenharmony_ci{ 6798c2ecf20Sopenharmony_ci unsigned long flags; 6808c2ecf20Sopenharmony_ci int i; 6818c2ecf20Sopenharmony_ci 6828c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 6838c2ecf20Sopenharmony_ci 6848c2ecf20Sopenharmony_ci for (i = 0; i < group.npins; i++) { 6858c2ecf20Sopenharmony_ci void __iomem *padcfg0; 6868c2ecf20Sopenharmony_ci u32 value; 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_ci padcfg0 = byt_gpio_reg(vg, group.pins[i], BYT_CONF0_REG); 6898c2ecf20Sopenharmony_ci if (!padcfg0) { 6908c2ecf20Sopenharmony_ci dev_warn(vg->dev, 6918c2ecf20Sopenharmony_ci "Group %s, pin %i not muxed (no padcfg0)\n", 6928c2ecf20Sopenharmony_ci group.name, i); 6938c2ecf20Sopenharmony_ci continue; 6948c2ecf20Sopenharmony_ci } 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci value = readl(padcfg0); 6978c2ecf20Sopenharmony_ci value &= ~BYT_PIN_MUX; 6988c2ecf20Sopenharmony_ci value |= func[i]; 6998c2ecf20Sopenharmony_ci writel(value, padcfg0); 7008c2ecf20Sopenharmony_ci } 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 7038c2ecf20Sopenharmony_ci} 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_cistatic int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 7068c2ecf20Sopenharmony_ci unsigned int group_selector) 7078c2ecf20Sopenharmony_ci{ 7088c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 7098c2ecf20Sopenharmony_ci const struct intel_function func = vg->soc->functions[func_selector]; 7108c2ecf20Sopenharmony_ci const struct intel_pingroup group = vg->soc->groups[group_selector]; 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci if (group.modes) 7138c2ecf20Sopenharmony_ci byt_set_group_mixed_mux(vg, group, group.modes); 7148c2ecf20Sopenharmony_ci else if (!strcmp(func.name, "gpio")) 7158c2ecf20Sopenharmony_ci byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); 7168c2ecf20Sopenharmony_ci else 7178c2ecf20Sopenharmony_ci byt_set_group_simple_mux(vg, group, group.mode); 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci return 0; 7208c2ecf20Sopenharmony_ci} 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_cistatic u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset) 7238c2ecf20Sopenharmony_ci{ 7248c2ecf20Sopenharmony_ci /* SCORE pin 92-93 */ 7258c2ecf20Sopenharmony_ci if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) && 7268c2ecf20Sopenharmony_ci offset >= 92 && offset <= 93) 7278c2ecf20Sopenharmony_ci return BYT_ALTER_GPIO_MUX; 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci /* SUS pin 11-21 */ 7308c2ecf20Sopenharmony_ci if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) && 7318c2ecf20Sopenharmony_ci offset >= 11 && offset <= 21) 7328c2ecf20Sopenharmony_ci return BYT_ALTER_GPIO_MUX; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci return BYT_DEFAULT_GPIO_MUX; 7358c2ecf20Sopenharmony_ci} 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_cistatic void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset) 7388c2ecf20Sopenharmony_ci{ 7398c2ecf20Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 7408c2ecf20Sopenharmony_ci unsigned long flags; 7418c2ecf20Sopenharmony_ci u32 value; 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 7448c2ecf20Sopenharmony_ci value = readl(reg); 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_ci /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */ 7478c2ecf20Sopenharmony_ci if (value & BYT_DIRECT_IRQ_EN) 7488c2ecf20Sopenharmony_ci /* nothing to do */ ; 7498c2ecf20Sopenharmony_ci else 7508c2ecf20Sopenharmony_ci value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_ci writel(value, reg); 7538c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 7548c2ecf20Sopenharmony_ci} 7558c2ecf20Sopenharmony_ci 7568c2ecf20Sopenharmony_cistatic int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, 7578c2ecf20Sopenharmony_ci struct pinctrl_gpio_range *range, 7588c2ecf20Sopenharmony_ci unsigned int offset) 7598c2ecf20Sopenharmony_ci{ 7608c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 7618c2ecf20Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 7628c2ecf20Sopenharmony_ci u32 value, gpio_mux; 7638c2ecf20Sopenharmony_ci unsigned long flags; 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci /* 7688c2ecf20Sopenharmony_ci * In most cases, func pin mux 000 means GPIO function. 7698c2ecf20Sopenharmony_ci * But, some pins may have func pin mux 001 represents 7708c2ecf20Sopenharmony_ci * GPIO function. 7718c2ecf20Sopenharmony_ci * 7728c2ecf20Sopenharmony_ci * Because there are devices out there where some pins were not 7738c2ecf20Sopenharmony_ci * configured correctly we allow changing the mux value from 7748c2ecf20Sopenharmony_ci * request (but print out warning about that). 7758c2ecf20Sopenharmony_ci */ 7768c2ecf20Sopenharmony_ci value = readl(reg) & BYT_PIN_MUX; 7778c2ecf20Sopenharmony_ci gpio_mux = byt_get_gpio_mux(vg, offset); 7788c2ecf20Sopenharmony_ci if (gpio_mux != value) { 7798c2ecf20Sopenharmony_ci value = readl(reg) & ~BYT_PIN_MUX; 7808c2ecf20Sopenharmony_ci value |= gpio_mux; 7818c2ecf20Sopenharmony_ci writel(value, reg); 7828c2ecf20Sopenharmony_ci 7838c2ecf20Sopenharmony_ci dev_warn(vg->dev, FW_BUG "pin %u forcibly re-configured as GPIO\n", offset); 7848c2ecf20Sopenharmony_ci } 7858c2ecf20Sopenharmony_ci 7868c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci pm_runtime_get(vg->dev); 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_ci return 0; 7918c2ecf20Sopenharmony_ci} 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_cistatic void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, 7948c2ecf20Sopenharmony_ci struct pinctrl_gpio_range *range, 7958c2ecf20Sopenharmony_ci unsigned int offset) 7968c2ecf20Sopenharmony_ci{ 7978c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 7988c2ecf20Sopenharmony_ci 7998c2ecf20Sopenharmony_ci byt_gpio_clear_triggering(vg, offset); 8008c2ecf20Sopenharmony_ci pm_runtime_put(vg->dev); 8018c2ecf20Sopenharmony_ci} 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_cistatic void byt_gpio_direct_irq_check(struct intel_pinctrl *vg, 8048c2ecf20Sopenharmony_ci unsigned int offset) 8058c2ecf20Sopenharmony_ci{ 8068c2ecf20Sopenharmony_ci void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci /* 8098c2ecf20Sopenharmony_ci * Before making any direction modifications, do a check if gpio is set 8108c2ecf20Sopenharmony_ci * for direct IRQ. On Bay Trail, setting GPIO to output does not make 8118c2ecf20Sopenharmony_ci * sense, so let's at least inform the caller before they shoot 8128c2ecf20Sopenharmony_ci * themselves in the foot. 8138c2ecf20Sopenharmony_ci */ 8148c2ecf20Sopenharmony_ci if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) 8158c2ecf20Sopenharmony_ci dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); 8168c2ecf20Sopenharmony_ci} 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_cistatic int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, 8198c2ecf20Sopenharmony_ci struct pinctrl_gpio_range *range, 8208c2ecf20Sopenharmony_ci unsigned int offset, 8218c2ecf20Sopenharmony_ci bool input) 8228c2ecf20Sopenharmony_ci{ 8238c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 8248c2ecf20Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 8258c2ecf20Sopenharmony_ci unsigned long flags; 8268c2ecf20Sopenharmony_ci u32 value; 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci value = readl(val_reg); 8318c2ecf20Sopenharmony_ci value &= ~BYT_DIR_MASK; 8328c2ecf20Sopenharmony_ci if (input) 8338c2ecf20Sopenharmony_ci value |= BYT_OUTPUT_EN; 8348c2ecf20Sopenharmony_ci else 8358c2ecf20Sopenharmony_ci byt_gpio_direct_irq_check(vg, offset); 8368c2ecf20Sopenharmony_ci 8378c2ecf20Sopenharmony_ci writel(value, val_reg); 8388c2ecf20Sopenharmony_ci 8398c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci return 0; 8428c2ecf20Sopenharmony_ci} 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_cistatic const struct pinmux_ops byt_pinmux_ops = { 8458c2ecf20Sopenharmony_ci .get_functions_count = byt_get_functions_count, 8468c2ecf20Sopenharmony_ci .get_function_name = byt_get_function_name, 8478c2ecf20Sopenharmony_ci .get_function_groups = byt_get_function_groups, 8488c2ecf20Sopenharmony_ci .set_mux = byt_set_mux, 8498c2ecf20Sopenharmony_ci .gpio_request_enable = byt_gpio_request_enable, 8508c2ecf20Sopenharmony_ci .gpio_disable_free = byt_gpio_disable_free, 8518c2ecf20Sopenharmony_ci .gpio_set_direction = byt_gpio_set_direction, 8528c2ecf20Sopenharmony_ci}; 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_cistatic void byt_get_pull_strength(u32 reg, u16 *strength) 8558c2ecf20Sopenharmony_ci{ 8568c2ecf20Sopenharmony_ci switch (reg & BYT_PULL_STR_MASK) { 8578c2ecf20Sopenharmony_ci case BYT_PULL_STR_2K: 8588c2ecf20Sopenharmony_ci *strength = 2000; 8598c2ecf20Sopenharmony_ci break; 8608c2ecf20Sopenharmony_ci case BYT_PULL_STR_10K: 8618c2ecf20Sopenharmony_ci *strength = 10000; 8628c2ecf20Sopenharmony_ci break; 8638c2ecf20Sopenharmony_ci case BYT_PULL_STR_20K: 8648c2ecf20Sopenharmony_ci *strength = 20000; 8658c2ecf20Sopenharmony_ci break; 8668c2ecf20Sopenharmony_ci case BYT_PULL_STR_40K: 8678c2ecf20Sopenharmony_ci *strength = 40000; 8688c2ecf20Sopenharmony_ci break; 8698c2ecf20Sopenharmony_ci } 8708c2ecf20Sopenharmony_ci} 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_cistatic int byt_set_pull_strength(u32 *reg, u16 strength) 8738c2ecf20Sopenharmony_ci{ 8748c2ecf20Sopenharmony_ci *reg &= ~BYT_PULL_STR_MASK; 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_ci switch (strength) { 8778c2ecf20Sopenharmony_ci case 2000: 8788c2ecf20Sopenharmony_ci *reg |= BYT_PULL_STR_2K; 8798c2ecf20Sopenharmony_ci break; 8808c2ecf20Sopenharmony_ci case 10000: 8818c2ecf20Sopenharmony_ci *reg |= BYT_PULL_STR_10K; 8828c2ecf20Sopenharmony_ci break; 8838c2ecf20Sopenharmony_ci case 20000: 8848c2ecf20Sopenharmony_ci *reg |= BYT_PULL_STR_20K; 8858c2ecf20Sopenharmony_ci break; 8868c2ecf20Sopenharmony_ci case 40000: 8878c2ecf20Sopenharmony_ci *reg |= BYT_PULL_STR_40K; 8888c2ecf20Sopenharmony_ci break; 8898c2ecf20Sopenharmony_ci default: 8908c2ecf20Sopenharmony_ci return -EINVAL; 8918c2ecf20Sopenharmony_ci } 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci return 0; 8948c2ecf20Sopenharmony_ci} 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_cistatic int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, 8978c2ecf20Sopenharmony_ci unsigned long *config) 8988c2ecf20Sopenharmony_ci{ 8998c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 9008c2ecf20Sopenharmony_ci enum pin_config_param param = pinconf_to_config_param(*config); 9018c2ecf20Sopenharmony_ci void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 9028c2ecf20Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 9038c2ecf20Sopenharmony_ci void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 9048c2ecf20Sopenharmony_ci unsigned long flags; 9058c2ecf20Sopenharmony_ci u32 conf, pull, val, debounce; 9068c2ecf20Sopenharmony_ci u16 arg = 0; 9078c2ecf20Sopenharmony_ci 9088c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 9098c2ecf20Sopenharmony_ci conf = readl(conf_reg); 9108c2ecf20Sopenharmony_ci pull = conf & BYT_PULL_ASSIGN_MASK; 9118c2ecf20Sopenharmony_ci val = readl(val_reg); 9128c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_ci switch (param) { 9158c2ecf20Sopenharmony_ci case PIN_CONFIG_BIAS_DISABLE: 9168c2ecf20Sopenharmony_ci if (pull) 9178c2ecf20Sopenharmony_ci return -EINVAL; 9188c2ecf20Sopenharmony_ci break; 9198c2ecf20Sopenharmony_ci case PIN_CONFIG_BIAS_PULL_DOWN: 9208c2ecf20Sopenharmony_ci /* Pull assignment is only applicable in input mode */ 9218c2ecf20Sopenharmony_ci if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) 9228c2ecf20Sopenharmony_ci return -EINVAL; 9238c2ecf20Sopenharmony_ci 9248c2ecf20Sopenharmony_ci byt_get_pull_strength(conf, &arg); 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci break; 9278c2ecf20Sopenharmony_ci case PIN_CONFIG_BIAS_PULL_UP: 9288c2ecf20Sopenharmony_ci /* Pull assignment is only applicable in input mode */ 9298c2ecf20Sopenharmony_ci if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) 9308c2ecf20Sopenharmony_ci return -EINVAL; 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ci byt_get_pull_strength(conf, &arg); 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ci break; 9358c2ecf20Sopenharmony_ci case PIN_CONFIG_INPUT_DEBOUNCE: 9368c2ecf20Sopenharmony_ci if (!(conf & BYT_DEBOUNCE_EN)) 9378c2ecf20Sopenharmony_ci return -EINVAL; 9388c2ecf20Sopenharmony_ci 9398c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 9408c2ecf20Sopenharmony_ci debounce = readl(db_reg); 9418c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { 9448c2ecf20Sopenharmony_ci case BYT_DEBOUNCE_PULSE_375US: 9458c2ecf20Sopenharmony_ci arg = 375; 9468c2ecf20Sopenharmony_ci break; 9478c2ecf20Sopenharmony_ci case BYT_DEBOUNCE_PULSE_750US: 9488c2ecf20Sopenharmony_ci arg = 750; 9498c2ecf20Sopenharmony_ci break; 9508c2ecf20Sopenharmony_ci case BYT_DEBOUNCE_PULSE_1500US: 9518c2ecf20Sopenharmony_ci arg = 1500; 9528c2ecf20Sopenharmony_ci break; 9538c2ecf20Sopenharmony_ci case BYT_DEBOUNCE_PULSE_3MS: 9548c2ecf20Sopenharmony_ci arg = 3000; 9558c2ecf20Sopenharmony_ci break; 9568c2ecf20Sopenharmony_ci case BYT_DEBOUNCE_PULSE_6MS: 9578c2ecf20Sopenharmony_ci arg = 6000; 9588c2ecf20Sopenharmony_ci break; 9598c2ecf20Sopenharmony_ci case BYT_DEBOUNCE_PULSE_12MS: 9608c2ecf20Sopenharmony_ci arg = 12000; 9618c2ecf20Sopenharmony_ci break; 9628c2ecf20Sopenharmony_ci case BYT_DEBOUNCE_PULSE_24MS: 9638c2ecf20Sopenharmony_ci arg = 24000; 9648c2ecf20Sopenharmony_ci break; 9658c2ecf20Sopenharmony_ci default: 9668c2ecf20Sopenharmony_ci return -EINVAL; 9678c2ecf20Sopenharmony_ci } 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci break; 9708c2ecf20Sopenharmony_ci default: 9718c2ecf20Sopenharmony_ci return -ENOTSUPP; 9728c2ecf20Sopenharmony_ci } 9738c2ecf20Sopenharmony_ci 9748c2ecf20Sopenharmony_ci *config = pinconf_to_config_packed(param, arg); 9758c2ecf20Sopenharmony_ci 9768c2ecf20Sopenharmony_ci return 0; 9778c2ecf20Sopenharmony_ci} 9788c2ecf20Sopenharmony_ci 9798c2ecf20Sopenharmony_cistatic int byt_pin_config_set(struct pinctrl_dev *pctl_dev, 9808c2ecf20Sopenharmony_ci unsigned int offset, 9818c2ecf20Sopenharmony_ci unsigned long *configs, 9828c2ecf20Sopenharmony_ci unsigned int num_configs) 9838c2ecf20Sopenharmony_ci{ 9848c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 9858c2ecf20Sopenharmony_ci unsigned int param, arg; 9868c2ecf20Sopenharmony_ci void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 9878c2ecf20Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 9888c2ecf20Sopenharmony_ci void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 9898c2ecf20Sopenharmony_ci unsigned long flags; 9908c2ecf20Sopenharmony_ci u32 conf, val, debounce; 9918c2ecf20Sopenharmony_ci int i, ret = 0; 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_ci conf = readl(conf_reg); 9968c2ecf20Sopenharmony_ci val = readl(val_reg); 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci for (i = 0; i < num_configs; i++) { 9998c2ecf20Sopenharmony_ci param = pinconf_to_config_param(configs[i]); 10008c2ecf20Sopenharmony_ci arg = pinconf_to_config_argument(configs[i]); 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci switch (param) { 10038c2ecf20Sopenharmony_ci case PIN_CONFIG_BIAS_DISABLE: 10048c2ecf20Sopenharmony_ci conf &= ~BYT_PULL_ASSIGN_MASK; 10058c2ecf20Sopenharmony_ci break; 10068c2ecf20Sopenharmony_ci case PIN_CONFIG_BIAS_PULL_DOWN: 10078c2ecf20Sopenharmony_ci /* Set default strength value in case none is given */ 10088c2ecf20Sopenharmony_ci if (arg == 1) 10098c2ecf20Sopenharmony_ci arg = 2000; 10108c2ecf20Sopenharmony_ci 10118c2ecf20Sopenharmony_ci /* 10128c2ecf20Sopenharmony_ci * Pull assignment is only applicable in input mode. If 10138c2ecf20Sopenharmony_ci * chip is not in input mode, set it and warn about it. 10148c2ecf20Sopenharmony_ci */ 10158c2ecf20Sopenharmony_ci if (val & BYT_INPUT_EN) { 10168c2ecf20Sopenharmony_ci val &= ~BYT_INPUT_EN; 10178c2ecf20Sopenharmony_ci writel(val, val_reg); 10188c2ecf20Sopenharmony_ci dev_warn(vg->dev, 10198c2ecf20Sopenharmony_ci "pin %u forcibly set to input mode\n", 10208c2ecf20Sopenharmony_ci offset); 10218c2ecf20Sopenharmony_ci } 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci conf &= ~BYT_PULL_ASSIGN_MASK; 10248c2ecf20Sopenharmony_ci conf |= BYT_PULL_ASSIGN_DOWN; 10258c2ecf20Sopenharmony_ci ret = byt_set_pull_strength(&conf, arg); 10268c2ecf20Sopenharmony_ci 10278c2ecf20Sopenharmony_ci break; 10288c2ecf20Sopenharmony_ci case PIN_CONFIG_BIAS_PULL_UP: 10298c2ecf20Sopenharmony_ci /* Set default strength value in case none is given */ 10308c2ecf20Sopenharmony_ci if (arg == 1) 10318c2ecf20Sopenharmony_ci arg = 2000; 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_ci /* 10348c2ecf20Sopenharmony_ci * Pull assignment is only applicable in input mode. If 10358c2ecf20Sopenharmony_ci * chip is not in input mode, set it and warn about it. 10368c2ecf20Sopenharmony_ci */ 10378c2ecf20Sopenharmony_ci if (val & BYT_INPUT_EN) { 10388c2ecf20Sopenharmony_ci val &= ~BYT_INPUT_EN; 10398c2ecf20Sopenharmony_ci writel(val, val_reg); 10408c2ecf20Sopenharmony_ci dev_warn(vg->dev, 10418c2ecf20Sopenharmony_ci "pin %u forcibly set to input mode\n", 10428c2ecf20Sopenharmony_ci offset); 10438c2ecf20Sopenharmony_ci } 10448c2ecf20Sopenharmony_ci 10458c2ecf20Sopenharmony_ci conf &= ~BYT_PULL_ASSIGN_MASK; 10468c2ecf20Sopenharmony_ci conf |= BYT_PULL_ASSIGN_UP; 10478c2ecf20Sopenharmony_ci ret = byt_set_pull_strength(&conf, arg); 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_ci break; 10508c2ecf20Sopenharmony_ci case PIN_CONFIG_INPUT_DEBOUNCE: 10518c2ecf20Sopenharmony_ci debounce = readl(db_reg); 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci if (arg) 10548c2ecf20Sopenharmony_ci conf |= BYT_DEBOUNCE_EN; 10558c2ecf20Sopenharmony_ci else 10568c2ecf20Sopenharmony_ci conf &= ~BYT_DEBOUNCE_EN; 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci switch (arg) { 10598c2ecf20Sopenharmony_ci case 375: 10608c2ecf20Sopenharmony_ci debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 10618c2ecf20Sopenharmony_ci debounce |= BYT_DEBOUNCE_PULSE_375US; 10628c2ecf20Sopenharmony_ci break; 10638c2ecf20Sopenharmony_ci case 750: 10648c2ecf20Sopenharmony_ci debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 10658c2ecf20Sopenharmony_ci debounce |= BYT_DEBOUNCE_PULSE_750US; 10668c2ecf20Sopenharmony_ci break; 10678c2ecf20Sopenharmony_ci case 1500: 10688c2ecf20Sopenharmony_ci debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 10698c2ecf20Sopenharmony_ci debounce |= BYT_DEBOUNCE_PULSE_1500US; 10708c2ecf20Sopenharmony_ci break; 10718c2ecf20Sopenharmony_ci case 3000: 10728c2ecf20Sopenharmony_ci debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 10738c2ecf20Sopenharmony_ci debounce |= BYT_DEBOUNCE_PULSE_3MS; 10748c2ecf20Sopenharmony_ci break; 10758c2ecf20Sopenharmony_ci case 6000: 10768c2ecf20Sopenharmony_ci debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 10778c2ecf20Sopenharmony_ci debounce |= BYT_DEBOUNCE_PULSE_6MS; 10788c2ecf20Sopenharmony_ci break; 10798c2ecf20Sopenharmony_ci case 12000: 10808c2ecf20Sopenharmony_ci debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 10818c2ecf20Sopenharmony_ci debounce |= BYT_DEBOUNCE_PULSE_12MS; 10828c2ecf20Sopenharmony_ci break; 10838c2ecf20Sopenharmony_ci case 24000: 10848c2ecf20Sopenharmony_ci debounce &= ~BYT_DEBOUNCE_PULSE_MASK; 10858c2ecf20Sopenharmony_ci debounce |= BYT_DEBOUNCE_PULSE_24MS; 10868c2ecf20Sopenharmony_ci break; 10878c2ecf20Sopenharmony_ci default: 10888c2ecf20Sopenharmony_ci if (arg) 10898c2ecf20Sopenharmony_ci ret = -EINVAL; 10908c2ecf20Sopenharmony_ci break; 10918c2ecf20Sopenharmony_ci } 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci if (!ret) 10948c2ecf20Sopenharmony_ci writel(debounce, db_reg); 10958c2ecf20Sopenharmony_ci break; 10968c2ecf20Sopenharmony_ci default: 10978c2ecf20Sopenharmony_ci ret = -ENOTSUPP; 10988c2ecf20Sopenharmony_ci } 10998c2ecf20Sopenharmony_ci 11008c2ecf20Sopenharmony_ci if (ret) 11018c2ecf20Sopenharmony_ci break; 11028c2ecf20Sopenharmony_ci } 11038c2ecf20Sopenharmony_ci 11048c2ecf20Sopenharmony_ci if (!ret) 11058c2ecf20Sopenharmony_ci writel(conf, conf_reg); 11068c2ecf20Sopenharmony_ci 11078c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ci return ret; 11108c2ecf20Sopenharmony_ci} 11118c2ecf20Sopenharmony_ci 11128c2ecf20Sopenharmony_cistatic const struct pinconf_ops byt_pinconf_ops = { 11138c2ecf20Sopenharmony_ci .is_generic = true, 11148c2ecf20Sopenharmony_ci .pin_config_get = byt_pin_config_get, 11158c2ecf20Sopenharmony_ci .pin_config_set = byt_pin_config_set, 11168c2ecf20Sopenharmony_ci}; 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_cistatic const struct pinctrl_desc byt_pinctrl_desc = { 11198c2ecf20Sopenharmony_ci .pctlops = &byt_pinctrl_ops, 11208c2ecf20Sopenharmony_ci .pmxops = &byt_pinmux_ops, 11218c2ecf20Sopenharmony_ci .confops = &byt_pinconf_ops, 11228c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 11238c2ecf20Sopenharmony_ci}; 11248c2ecf20Sopenharmony_ci 11258c2ecf20Sopenharmony_cistatic int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) 11268c2ecf20Sopenharmony_ci{ 11278c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 11288c2ecf20Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 11298c2ecf20Sopenharmony_ci unsigned long flags; 11308c2ecf20Sopenharmony_ci u32 val; 11318c2ecf20Sopenharmony_ci 11328c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 11338c2ecf20Sopenharmony_ci val = readl(reg); 11348c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 11358c2ecf20Sopenharmony_ci 11368c2ecf20Sopenharmony_ci return !!(val & BYT_LEVEL); 11378c2ecf20Sopenharmony_ci} 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_cistatic void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 11408c2ecf20Sopenharmony_ci{ 11418c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 11428c2ecf20Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 11438c2ecf20Sopenharmony_ci unsigned long flags; 11448c2ecf20Sopenharmony_ci u32 old_val; 11458c2ecf20Sopenharmony_ci 11468c2ecf20Sopenharmony_ci if (!reg) 11478c2ecf20Sopenharmony_ci return; 11488c2ecf20Sopenharmony_ci 11498c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 11508c2ecf20Sopenharmony_ci old_val = readl(reg); 11518c2ecf20Sopenharmony_ci if (value) 11528c2ecf20Sopenharmony_ci writel(old_val | BYT_LEVEL, reg); 11538c2ecf20Sopenharmony_ci else 11548c2ecf20Sopenharmony_ci writel(old_val & ~BYT_LEVEL, reg); 11558c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 11568c2ecf20Sopenharmony_ci} 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_cistatic int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 11598c2ecf20Sopenharmony_ci{ 11608c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 11618c2ecf20Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 11628c2ecf20Sopenharmony_ci unsigned long flags; 11638c2ecf20Sopenharmony_ci u32 value; 11648c2ecf20Sopenharmony_ci 11658c2ecf20Sopenharmony_ci if (!reg) 11668c2ecf20Sopenharmony_ci return -EINVAL; 11678c2ecf20Sopenharmony_ci 11688c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 11698c2ecf20Sopenharmony_ci value = readl(reg); 11708c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 11718c2ecf20Sopenharmony_ci 11728c2ecf20Sopenharmony_ci if (!(value & BYT_OUTPUT_EN)) 11738c2ecf20Sopenharmony_ci return GPIO_LINE_DIRECTION_OUT; 11748c2ecf20Sopenharmony_ci if (!(value & BYT_INPUT_EN)) 11758c2ecf20Sopenharmony_ci return GPIO_LINE_DIRECTION_IN; 11768c2ecf20Sopenharmony_ci 11778c2ecf20Sopenharmony_ci return -EINVAL; 11788c2ecf20Sopenharmony_ci} 11798c2ecf20Sopenharmony_ci 11808c2ecf20Sopenharmony_cistatic int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 11818c2ecf20Sopenharmony_ci{ 11828c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 11838c2ecf20Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 11848c2ecf20Sopenharmony_ci unsigned long flags; 11858c2ecf20Sopenharmony_ci u32 reg; 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 11888c2ecf20Sopenharmony_ci 11898c2ecf20Sopenharmony_ci reg = readl(val_reg); 11908c2ecf20Sopenharmony_ci reg &= ~BYT_DIR_MASK; 11918c2ecf20Sopenharmony_ci reg |= BYT_OUTPUT_EN; 11928c2ecf20Sopenharmony_ci writel(reg, val_reg); 11938c2ecf20Sopenharmony_ci 11948c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 11958c2ecf20Sopenharmony_ci return 0; 11968c2ecf20Sopenharmony_ci} 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci/* 11998c2ecf20Sopenharmony_ci * Note despite the temptation this MUST NOT be converted into a call to 12008c2ecf20Sopenharmony_ci * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this 12018c2ecf20Sopenharmony_ci * MUST be done as a single BYT_VAL_REG register write. 12028c2ecf20Sopenharmony_ci * See the commit message of the commit adding this comment for details. 12038c2ecf20Sopenharmony_ci */ 12048c2ecf20Sopenharmony_cistatic int byt_gpio_direction_output(struct gpio_chip *chip, 12058c2ecf20Sopenharmony_ci unsigned int offset, int value) 12068c2ecf20Sopenharmony_ci{ 12078c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 12088c2ecf20Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 12098c2ecf20Sopenharmony_ci unsigned long flags; 12108c2ecf20Sopenharmony_ci u32 reg; 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 12138c2ecf20Sopenharmony_ci 12148c2ecf20Sopenharmony_ci byt_gpio_direct_irq_check(vg, offset); 12158c2ecf20Sopenharmony_ci 12168c2ecf20Sopenharmony_ci reg = readl(val_reg); 12178c2ecf20Sopenharmony_ci reg &= ~BYT_DIR_MASK; 12188c2ecf20Sopenharmony_ci if (value) 12198c2ecf20Sopenharmony_ci reg |= BYT_LEVEL; 12208c2ecf20Sopenharmony_ci else 12218c2ecf20Sopenharmony_ci reg &= ~BYT_LEVEL; 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_ci writel(reg, val_reg); 12248c2ecf20Sopenharmony_ci 12258c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 12268c2ecf20Sopenharmony_ci return 0; 12278c2ecf20Sopenharmony_ci} 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_cistatic void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 12308c2ecf20Sopenharmony_ci{ 12318c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 12328c2ecf20Sopenharmony_ci int i; 12338c2ecf20Sopenharmony_ci u32 conf0, val; 12348c2ecf20Sopenharmony_ci 12358c2ecf20Sopenharmony_ci for (i = 0; i < vg->soc->npins; i++) { 12368c2ecf20Sopenharmony_ci const struct intel_community *comm; 12378c2ecf20Sopenharmony_ci const char *pull_str = NULL; 12388c2ecf20Sopenharmony_ci const char *pull = NULL; 12398c2ecf20Sopenharmony_ci void __iomem *reg; 12408c2ecf20Sopenharmony_ci unsigned long flags; 12418c2ecf20Sopenharmony_ci const char *label; 12428c2ecf20Sopenharmony_ci unsigned int pin; 12438c2ecf20Sopenharmony_ci 12448c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 12458c2ecf20Sopenharmony_ci pin = vg->soc->pins[i].number; 12468c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 12478c2ecf20Sopenharmony_ci if (!reg) { 12488c2ecf20Sopenharmony_ci seq_printf(s, 12498c2ecf20Sopenharmony_ci "Could not retrieve pin %i conf0 reg\n", 12508c2ecf20Sopenharmony_ci pin); 12518c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 12528c2ecf20Sopenharmony_ci continue; 12538c2ecf20Sopenharmony_ci } 12548c2ecf20Sopenharmony_ci conf0 = readl(reg); 12558c2ecf20Sopenharmony_ci 12568c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 12578c2ecf20Sopenharmony_ci if (!reg) { 12588c2ecf20Sopenharmony_ci seq_printf(s, 12598c2ecf20Sopenharmony_ci "Could not retrieve pin %i val reg\n", pin); 12608c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 12618c2ecf20Sopenharmony_ci continue; 12628c2ecf20Sopenharmony_ci } 12638c2ecf20Sopenharmony_ci val = readl(reg); 12648c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 12658c2ecf20Sopenharmony_ci 12668c2ecf20Sopenharmony_ci comm = byt_get_community(vg, pin); 12678c2ecf20Sopenharmony_ci if (!comm) { 12688c2ecf20Sopenharmony_ci seq_printf(s, 12698c2ecf20Sopenharmony_ci "Could not get community for pin %i\n", pin); 12708c2ecf20Sopenharmony_ci continue; 12718c2ecf20Sopenharmony_ci } 12728c2ecf20Sopenharmony_ci label = gpiochip_is_requested(chip, i); 12738c2ecf20Sopenharmony_ci if (!label) 12748c2ecf20Sopenharmony_ci label = "Unrequested"; 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_ci switch (conf0 & BYT_PULL_ASSIGN_MASK) { 12778c2ecf20Sopenharmony_ci case BYT_PULL_ASSIGN_UP: 12788c2ecf20Sopenharmony_ci pull = "up"; 12798c2ecf20Sopenharmony_ci break; 12808c2ecf20Sopenharmony_ci case BYT_PULL_ASSIGN_DOWN: 12818c2ecf20Sopenharmony_ci pull = "down"; 12828c2ecf20Sopenharmony_ci break; 12838c2ecf20Sopenharmony_ci } 12848c2ecf20Sopenharmony_ci 12858c2ecf20Sopenharmony_ci switch (conf0 & BYT_PULL_STR_MASK) { 12868c2ecf20Sopenharmony_ci case BYT_PULL_STR_2K: 12878c2ecf20Sopenharmony_ci pull_str = "2k"; 12888c2ecf20Sopenharmony_ci break; 12898c2ecf20Sopenharmony_ci case BYT_PULL_STR_10K: 12908c2ecf20Sopenharmony_ci pull_str = "10k"; 12918c2ecf20Sopenharmony_ci break; 12928c2ecf20Sopenharmony_ci case BYT_PULL_STR_20K: 12938c2ecf20Sopenharmony_ci pull_str = "20k"; 12948c2ecf20Sopenharmony_ci break; 12958c2ecf20Sopenharmony_ci case BYT_PULL_STR_40K: 12968c2ecf20Sopenharmony_ci pull_str = "40k"; 12978c2ecf20Sopenharmony_ci break; 12988c2ecf20Sopenharmony_ci } 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci seq_printf(s, 13018c2ecf20Sopenharmony_ci " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", 13028c2ecf20Sopenharmony_ci pin, 13038c2ecf20Sopenharmony_ci label, 13048c2ecf20Sopenharmony_ci val & BYT_INPUT_EN ? " " : "in", 13058c2ecf20Sopenharmony_ci val & BYT_OUTPUT_EN ? " " : "out", 13068c2ecf20Sopenharmony_ci val & BYT_LEVEL ? "hi" : "lo", 13078c2ecf20Sopenharmony_ci comm->pad_map[i], comm->pad_map[i] * 16, 13088c2ecf20Sopenharmony_ci conf0 & 0x7, 13098c2ecf20Sopenharmony_ci conf0 & BYT_TRIG_NEG ? " fall" : " ", 13108c2ecf20Sopenharmony_ci conf0 & BYT_TRIG_POS ? " rise" : " ", 13118c2ecf20Sopenharmony_ci conf0 & BYT_TRIG_LVL ? " level" : " "); 13128c2ecf20Sopenharmony_ci 13138c2ecf20Sopenharmony_ci if (pull && pull_str) 13148c2ecf20Sopenharmony_ci seq_printf(s, " %-4s %-3s", pull, pull_str); 13158c2ecf20Sopenharmony_ci else 13168c2ecf20Sopenharmony_ci seq_puts(s, " "); 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci if (conf0 & BYT_IODEN) 13198c2ecf20Sopenharmony_ci seq_puts(s, " open-drain"); 13208c2ecf20Sopenharmony_ci 13218c2ecf20Sopenharmony_ci seq_puts(s, "\n"); 13228c2ecf20Sopenharmony_ci } 13238c2ecf20Sopenharmony_ci} 13248c2ecf20Sopenharmony_ci 13258c2ecf20Sopenharmony_cistatic const struct gpio_chip byt_gpio_chip = { 13268c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 13278c2ecf20Sopenharmony_ci .request = gpiochip_generic_request, 13288c2ecf20Sopenharmony_ci .free = gpiochip_generic_free, 13298c2ecf20Sopenharmony_ci .get_direction = byt_gpio_get_direction, 13308c2ecf20Sopenharmony_ci .direction_input = byt_gpio_direction_input, 13318c2ecf20Sopenharmony_ci .direction_output = byt_gpio_direction_output, 13328c2ecf20Sopenharmony_ci .get = byt_gpio_get, 13338c2ecf20Sopenharmony_ci .set = byt_gpio_set, 13348c2ecf20Sopenharmony_ci .set_config = gpiochip_generic_config, 13358c2ecf20Sopenharmony_ci .dbg_show = byt_gpio_dbg_show, 13368c2ecf20Sopenharmony_ci}; 13378c2ecf20Sopenharmony_ci 13388c2ecf20Sopenharmony_cistatic void byt_irq_ack(struct irq_data *d) 13398c2ecf20Sopenharmony_ci{ 13408c2ecf20Sopenharmony_ci struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 13418c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(gc); 13428c2ecf20Sopenharmony_ci unsigned int offset = irqd_to_hwirq(d); 13438c2ecf20Sopenharmony_ci void __iomem *reg; 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, offset, BYT_INT_STAT_REG); 13468c2ecf20Sopenharmony_ci if (!reg) 13478c2ecf20Sopenharmony_ci return; 13488c2ecf20Sopenharmony_ci 13498c2ecf20Sopenharmony_ci raw_spin_lock(&byt_lock); 13508c2ecf20Sopenharmony_ci writel(BIT(offset % 32), reg); 13518c2ecf20Sopenharmony_ci raw_spin_unlock(&byt_lock); 13528c2ecf20Sopenharmony_ci} 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_cistatic void byt_irq_mask(struct irq_data *d) 13558c2ecf20Sopenharmony_ci{ 13568c2ecf20Sopenharmony_ci struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 13578c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(gc); 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci byt_gpio_clear_triggering(vg, irqd_to_hwirq(d)); 13608c2ecf20Sopenharmony_ci} 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_cistatic void byt_irq_unmask(struct irq_data *d) 13638c2ecf20Sopenharmony_ci{ 13648c2ecf20Sopenharmony_ci struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 13658c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(gc); 13668c2ecf20Sopenharmony_ci unsigned int offset = irqd_to_hwirq(d); 13678c2ecf20Sopenharmony_ci unsigned long flags; 13688c2ecf20Sopenharmony_ci void __iomem *reg; 13698c2ecf20Sopenharmony_ci u32 value; 13708c2ecf20Sopenharmony_ci 13718c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 13728c2ecf20Sopenharmony_ci if (!reg) 13738c2ecf20Sopenharmony_ci return; 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 13768c2ecf20Sopenharmony_ci value = readl(reg); 13778c2ecf20Sopenharmony_ci 13788c2ecf20Sopenharmony_ci switch (irqd_get_trigger_type(d)) { 13798c2ecf20Sopenharmony_ci case IRQ_TYPE_LEVEL_HIGH: 13808c2ecf20Sopenharmony_ci value |= BYT_TRIG_LVL; 13818c2ecf20Sopenharmony_ci fallthrough; 13828c2ecf20Sopenharmony_ci case IRQ_TYPE_EDGE_RISING: 13838c2ecf20Sopenharmony_ci value |= BYT_TRIG_POS; 13848c2ecf20Sopenharmony_ci break; 13858c2ecf20Sopenharmony_ci case IRQ_TYPE_LEVEL_LOW: 13868c2ecf20Sopenharmony_ci value |= BYT_TRIG_LVL; 13878c2ecf20Sopenharmony_ci fallthrough; 13888c2ecf20Sopenharmony_ci case IRQ_TYPE_EDGE_FALLING: 13898c2ecf20Sopenharmony_ci value |= BYT_TRIG_NEG; 13908c2ecf20Sopenharmony_ci break; 13918c2ecf20Sopenharmony_ci case IRQ_TYPE_EDGE_BOTH: 13928c2ecf20Sopenharmony_ci value |= (BYT_TRIG_NEG | BYT_TRIG_POS); 13938c2ecf20Sopenharmony_ci break; 13948c2ecf20Sopenharmony_ci } 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci writel(value, reg); 13978c2ecf20Sopenharmony_ci 13988c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 13998c2ecf20Sopenharmony_ci} 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_cistatic int byt_irq_type(struct irq_data *d, unsigned int type) 14028c2ecf20Sopenharmony_ci{ 14038c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); 14048c2ecf20Sopenharmony_ci u32 offset = irqd_to_hwirq(d); 14058c2ecf20Sopenharmony_ci u32 value; 14068c2ecf20Sopenharmony_ci unsigned long flags; 14078c2ecf20Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 14088c2ecf20Sopenharmony_ci 14098c2ecf20Sopenharmony_ci if (!reg || offset >= vg->chip.ngpio) 14108c2ecf20Sopenharmony_ci return -EINVAL; 14118c2ecf20Sopenharmony_ci 14128c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 14138c2ecf20Sopenharmony_ci value = readl(reg); 14148c2ecf20Sopenharmony_ci 14158c2ecf20Sopenharmony_ci WARN(value & BYT_DIRECT_IRQ_EN, 14168c2ecf20Sopenharmony_ci "Bad pad config for io mode, force direct_irq_en bit clearing"); 14178c2ecf20Sopenharmony_ci 14188c2ecf20Sopenharmony_ci /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits 14198c2ecf20Sopenharmony_ci * are used to indicate high and low level triggering 14208c2ecf20Sopenharmony_ci */ 14218c2ecf20Sopenharmony_ci value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | 14228c2ecf20Sopenharmony_ci BYT_TRIG_LVL); 14238c2ecf20Sopenharmony_ci /* Enable glitch filtering */ 14248c2ecf20Sopenharmony_ci value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK | 14258c2ecf20Sopenharmony_ci BYT_GLITCH_F_FAST_CLK; 14268c2ecf20Sopenharmony_ci 14278c2ecf20Sopenharmony_ci writel(value, reg); 14288c2ecf20Sopenharmony_ci 14298c2ecf20Sopenharmony_ci if (type & IRQ_TYPE_EDGE_BOTH) 14308c2ecf20Sopenharmony_ci irq_set_handler_locked(d, handle_edge_irq); 14318c2ecf20Sopenharmony_ci else if (type & IRQ_TYPE_LEVEL_MASK) 14328c2ecf20Sopenharmony_ci irq_set_handler_locked(d, handle_level_irq); 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 14358c2ecf20Sopenharmony_ci 14368c2ecf20Sopenharmony_ci return 0; 14378c2ecf20Sopenharmony_ci} 14388c2ecf20Sopenharmony_ci 14398c2ecf20Sopenharmony_cistatic void byt_gpio_irq_handler(struct irq_desc *desc) 14408c2ecf20Sopenharmony_ci{ 14418c2ecf20Sopenharmony_ci struct irq_data *data = irq_desc_get_irq_data(desc); 14428c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc)); 14438c2ecf20Sopenharmony_ci struct irq_chip *chip = irq_data_get_irq_chip(data); 14448c2ecf20Sopenharmony_ci u32 base, pin; 14458c2ecf20Sopenharmony_ci void __iomem *reg; 14468c2ecf20Sopenharmony_ci unsigned long pending; 14478c2ecf20Sopenharmony_ci unsigned int virq; 14488c2ecf20Sopenharmony_ci 14498c2ecf20Sopenharmony_ci /* check from GPIO controller which pin triggered the interrupt */ 14508c2ecf20Sopenharmony_ci for (base = 0; base < vg->chip.ngpio; base += 32) { 14518c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 14528c2ecf20Sopenharmony_ci 14538c2ecf20Sopenharmony_ci if (!reg) { 14548c2ecf20Sopenharmony_ci dev_warn(vg->dev, 14558c2ecf20Sopenharmony_ci "Pin %i: could not retrieve interrupt status register\n", 14568c2ecf20Sopenharmony_ci base); 14578c2ecf20Sopenharmony_ci continue; 14588c2ecf20Sopenharmony_ci } 14598c2ecf20Sopenharmony_ci 14608c2ecf20Sopenharmony_ci raw_spin_lock(&byt_lock); 14618c2ecf20Sopenharmony_ci pending = readl(reg); 14628c2ecf20Sopenharmony_ci raw_spin_unlock(&byt_lock); 14638c2ecf20Sopenharmony_ci for_each_set_bit(pin, &pending, 32) { 14648c2ecf20Sopenharmony_ci virq = irq_find_mapping(vg->chip.irq.domain, base + pin); 14658c2ecf20Sopenharmony_ci generic_handle_irq(virq); 14668c2ecf20Sopenharmony_ci } 14678c2ecf20Sopenharmony_ci } 14688c2ecf20Sopenharmony_ci chip->irq_eoi(data); 14698c2ecf20Sopenharmony_ci} 14708c2ecf20Sopenharmony_ci 14718c2ecf20Sopenharmony_cistatic void byt_init_irq_valid_mask(struct gpio_chip *chip, 14728c2ecf20Sopenharmony_ci unsigned long *valid_mask, 14738c2ecf20Sopenharmony_ci unsigned int ngpios) 14748c2ecf20Sopenharmony_ci{ 14758c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 14768c2ecf20Sopenharmony_ci void __iomem *reg; 14778c2ecf20Sopenharmony_ci u32 value; 14788c2ecf20Sopenharmony_ci int i; 14798c2ecf20Sopenharmony_ci 14808c2ecf20Sopenharmony_ci /* 14818c2ecf20Sopenharmony_ci * Clear interrupt triggers for all pins that are GPIOs and 14828c2ecf20Sopenharmony_ci * do not use direct IRQ mode. This will prevent spurious 14838c2ecf20Sopenharmony_ci * interrupts from misconfigured pins. 14848c2ecf20Sopenharmony_ci */ 14858c2ecf20Sopenharmony_ci for (i = 0; i < vg->soc->npins; i++) { 14868c2ecf20Sopenharmony_ci unsigned int pin = vg->soc->pins[i].number; 14878c2ecf20Sopenharmony_ci 14888c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 14898c2ecf20Sopenharmony_ci if (!reg) { 14908c2ecf20Sopenharmony_ci dev_warn(vg->dev, 14918c2ecf20Sopenharmony_ci "Pin %i: could not retrieve conf0 register\n", 14928c2ecf20Sopenharmony_ci i); 14938c2ecf20Sopenharmony_ci continue; 14948c2ecf20Sopenharmony_ci } 14958c2ecf20Sopenharmony_ci 14968c2ecf20Sopenharmony_ci value = readl(reg); 14978c2ecf20Sopenharmony_ci if (value & BYT_DIRECT_IRQ_EN) { 14988c2ecf20Sopenharmony_ci clear_bit(i, valid_mask); 14998c2ecf20Sopenharmony_ci dev_dbg(vg->dev, "excluding GPIO %d from IRQ domain\n", i); 15008c2ecf20Sopenharmony_ci } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { 15018c2ecf20Sopenharmony_ci byt_gpio_clear_triggering(vg, i); 15028c2ecf20Sopenharmony_ci dev_dbg(vg->dev, "disabling GPIO %d\n", i); 15038c2ecf20Sopenharmony_ci } 15048c2ecf20Sopenharmony_ci } 15058c2ecf20Sopenharmony_ci} 15068c2ecf20Sopenharmony_ci 15078c2ecf20Sopenharmony_cistatic int byt_gpio_irq_init_hw(struct gpio_chip *chip) 15088c2ecf20Sopenharmony_ci{ 15098c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 15108c2ecf20Sopenharmony_ci void __iomem *reg; 15118c2ecf20Sopenharmony_ci u32 base, value; 15128c2ecf20Sopenharmony_ci 15138c2ecf20Sopenharmony_ci /* clear interrupt status trigger registers */ 15148c2ecf20Sopenharmony_ci for (base = 0; base < vg->soc->npins; base += 32) { 15158c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 15168c2ecf20Sopenharmony_ci 15178c2ecf20Sopenharmony_ci if (!reg) { 15188c2ecf20Sopenharmony_ci dev_warn(vg->dev, 15198c2ecf20Sopenharmony_ci "Pin %i: could not retrieve irq status reg\n", 15208c2ecf20Sopenharmony_ci base); 15218c2ecf20Sopenharmony_ci continue; 15228c2ecf20Sopenharmony_ci } 15238c2ecf20Sopenharmony_ci 15248c2ecf20Sopenharmony_ci writel(0xffffffff, reg); 15258c2ecf20Sopenharmony_ci /* make sure trigger bits are cleared, if not then a pin 15268c2ecf20Sopenharmony_ci might be misconfigured in bios */ 15278c2ecf20Sopenharmony_ci value = readl(reg); 15288c2ecf20Sopenharmony_ci if (value) 15298c2ecf20Sopenharmony_ci dev_err(vg->dev, 15308c2ecf20Sopenharmony_ci "GPIO interrupt error, pins misconfigured. INT_STAT%u: 0x%08x\n", 15318c2ecf20Sopenharmony_ci base / 32, value); 15328c2ecf20Sopenharmony_ci } 15338c2ecf20Sopenharmony_ci 15348c2ecf20Sopenharmony_ci return 0; 15358c2ecf20Sopenharmony_ci} 15368c2ecf20Sopenharmony_ci 15378c2ecf20Sopenharmony_cistatic int byt_gpio_add_pin_ranges(struct gpio_chip *chip) 15388c2ecf20Sopenharmony_ci{ 15398c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 15408c2ecf20Sopenharmony_ci struct device *dev = vg->dev; 15418c2ecf20Sopenharmony_ci int ret; 15428c2ecf20Sopenharmony_ci 15438c2ecf20Sopenharmony_ci ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins); 15448c2ecf20Sopenharmony_ci if (ret) 15458c2ecf20Sopenharmony_ci dev_err(dev, "failed to add GPIO pin range\n"); 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_ci return ret; 15488c2ecf20Sopenharmony_ci} 15498c2ecf20Sopenharmony_ci 15508c2ecf20Sopenharmony_cistatic int byt_gpio_probe(struct intel_pinctrl *vg) 15518c2ecf20Sopenharmony_ci{ 15528c2ecf20Sopenharmony_ci struct platform_device *pdev = to_platform_device(vg->dev); 15538c2ecf20Sopenharmony_ci struct gpio_chip *gc; 15548c2ecf20Sopenharmony_ci int irq, ret; 15558c2ecf20Sopenharmony_ci 15568c2ecf20Sopenharmony_ci /* Set up gpio chip */ 15578c2ecf20Sopenharmony_ci vg->chip = byt_gpio_chip; 15588c2ecf20Sopenharmony_ci gc = &vg->chip; 15598c2ecf20Sopenharmony_ci gc->label = dev_name(vg->dev); 15608c2ecf20Sopenharmony_ci gc->base = -1; 15618c2ecf20Sopenharmony_ci gc->can_sleep = false; 15628c2ecf20Sopenharmony_ci gc->add_pin_ranges = byt_gpio_add_pin_ranges; 15638c2ecf20Sopenharmony_ci gc->parent = vg->dev; 15648c2ecf20Sopenharmony_ci gc->ngpio = vg->soc->npins; 15658c2ecf20Sopenharmony_ci 15668c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 15678c2ecf20Sopenharmony_ci vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads), 15688c2ecf20Sopenharmony_ci GFP_KERNEL); 15698c2ecf20Sopenharmony_ci if (!vg->context.pads) 15708c2ecf20Sopenharmony_ci return -ENOMEM; 15718c2ecf20Sopenharmony_ci#endif 15728c2ecf20Sopenharmony_ci 15738c2ecf20Sopenharmony_ci /* set up interrupts */ 15748c2ecf20Sopenharmony_ci irq = platform_get_irq_optional(pdev, 0); 15758c2ecf20Sopenharmony_ci if (irq > 0) { 15768c2ecf20Sopenharmony_ci struct gpio_irq_chip *girq; 15778c2ecf20Sopenharmony_ci 15788c2ecf20Sopenharmony_ci vg->irqchip.name = "BYT-GPIO", 15798c2ecf20Sopenharmony_ci vg->irqchip.irq_ack = byt_irq_ack, 15808c2ecf20Sopenharmony_ci vg->irqchip.irq_mask = byt_irq_mask, 15818c2ecf20Sopenharmony_ci vg->irqchip.irq_unmask = byt_irq_unmask, 15828c2ecf20Sopenharmony_ci vg->irqchip.irq_set_type = byt_irq_type, 15838c2ecf20Sopenharmony_ci vg->irqchip.flags = IRQCHIP_SKIP_SET_WAKE, 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ci girq = &gc->irq; 15868c2ecf20Sopenharmony_ci girq->chip = &vg->irqchip; 15878c2ecf20Sopenharmony_ci girq->init_hw = byt_gpio_irq_init_hw; 15888c2ecf20Sopenharmony_ci girq->init_valid_mask = byt_init_irq_valid_mask; 15898c2ecf20Sopenharmony_ci girq->parent_handler = byt_gpio_irq_handler; 15908c2ecf20Sopenharmony_ci girq->num_parents = 1; 15918c2ecf20Sopenharmony_ci girq->parents = devm_kcalloc(vg->dev, girq->num_parents, 15928c2ecf20Sopenharmony_ci sizeof(*girq->parents), GFP_KERNEL); 15938c2ecf20Sopenharmony_ci if (!girq->parents) 15948c2ecf20Sopenharmony_ci return -ENOMEM; 15958c2ecf20Sopenharmony_ci girq->parents[0] = irq; 15968c2ecf20Sopenharmony_ci girq->default_type = IRQ_TYPE_NONE; 15978c2ecf20Sopenharmony_ci girq->handler = handle_bad_irq; 15988c2ecf20Sopenharmony_ci } 15998c2ecf20Sopenharmony_ci 16008c2ecf20Sopenharmony_ci ret = devm_gpiochip_add_data(vg->dev, gc, vg); 16018c2ecf20Sopenharmony_ci if (ret) { 16028c2ecf20Sopenharmony_ci dev_err(vg->dev, "failed adding byt-gpio chip\n"); 16038c2ecf20Sopenharmony_ci return ret; 16048c2ecf20Sopenharmony_ci } 16058c2ecf20Sopenharmony_ci 16068c2ecf20Sopenharmony_ci return ret; 16078c2ecf20Sopenharmony_ci} 16088c2ecf20Sopenharmony_ci 16098c2ecf20Sopenharmony_cistatic int byt_set_soc_data(struct intel_pinctrl *vg, 16108c2ecf20Sopenharmony_ci const struct intel_pinctrl_soc_data *soc) 16118c2ecf20Sopenharmony_ci{ 16128c2ecf20Sopenharmony_ci struct platform_device *pdev = to_platform_device(vg->dev); 16138c2ecf20Sopenharmony_ci int i; 16148c2ecf20Sopenharmony_ci 16158c2ecf20Sopenharmony_ci vg->soc = soc; 16168c2ecf20Sopenharmony_ci 16178c2ecf20Sopenharmony_ci vg->ncommunities = vg->soc->ncommunities; 16188c2ecf20Sopenharmony_ci vg->communities = devm_kcalloc(vg->dev, vg->ncommunities, 16198c2ecf20Sopenharmony_ci sizeof(*vg->communities), GFP_KERNEL); 16208c2ecf20Sopenharmony_ci if (!vg->communities) 16218c2ecf20Sopenharmony_ci return -ENOMEM; 16228c2ecf20Sopenharmony_ci 16238c2ecf20Sopenharmony_ci for (i = 0; i < vg->soc->ncommunities; i++) { 16248c2ecf20Sopenharmony_ci struct intel_community *comm = vg->communities + i; 16258c2ecf20Sopenharmony_ci 16268c2ecf20Sopenharmony_ci *comm = vg->soc->communities[i]; 16278c2ecf20Sopenharmony_ci 16288c2ecf20Sopenharmony_ci comm->pad_regs = devm_platform_ioremap_resource(pdev, 0); 16298c2ecf20Sopenharmony_ci if (IS_ERR(comm->pad_regs)) 16308c2ecf20Sopenharmony_ci return PTR_ERR(comm->pad_regs); 16318c2ecf20Sopenharmony_ci } 16328c2ecf20Sopenharmony_ci 16338c2ecf20Sopenharmony_ci return 0; 16348c2ecf20Sopenharmony_ci} 16358c2ecf20Sopenharmony_ci 16368c2ecf20Sopenharmony_cistatic const struct acpi_device_id byt_gpio_acpi_match[] = { 16378c2ecf20Sopenharmony_ci { "INT33B2", (kernel_ulong_t)byt_soc_data }, 16388c2ecf20Sopenharmony_ci { "INT33FC", (kernel_ulong_t)byt_soc_data }, 16398c2ecf20Sopenharmony_ci { } 16408c2ecf20Sopenharmony_ci}; 16418c2ecf20Sopenharmony_ci 16428c2ecf20Sopenharmony_cistatic int byt_pinctrl_probe(struct platform_device *pdev) 16438c2ecf20Sopenharmony_ci{ 16448c2ecf20Sopenharmony_ci const struct intel_pinctrl_soc_data *soc_data; 16458c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 16468c2ecf20Sopenharmony_ci struct intel_pinctrl *vg; 16478c2ecf20Sopenharmony_ci int ret; 16488c2ecf20Sopenharmony_ci 16498c2ecf20Sopenharmony_ci soc_data = intel_pinctrl_get_soc_data(pdev); 16508c2ecf20Sopenharmony_ci if (IS_ERR(soc_data)) 16518c2ecf20Sopenharmony_ci return PTR_ERR(soc_data); 16528c2ecf20Sopenharmony_ci 16538c2ecf20Sopenharmony_ci vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL); 16548c2ecf20Sopenharmony_ci if (!vg) 16558c2ecf20Sopenharmony_ci return -ENOMEM; 16568c2ecf20Sopenharmony_ci 16578c2ecf20Sopenharmony_ci vg->dev = dev; 16588c2ecf20Sopenharmony_ci ret = byt_set_soc_data(vg, soc_data); 16598c2ecf20Sopenharmony_ci if (ret) { 16608c2ecf20Sopenharmony_ci dev_err(dev, "failed to set soc data\n"); 16618c2ecf20Sopenharmony_ci return ret; 16628c2ecf20Sopenharmony_ci } 16638c2ecf20Sopenharmony_ci 16648c2ecf20Sopenharmony_ci vg->pctldesc = byt_pinctrl_desc; 16658c2ecf20Sopenharmony_ci vg->pctldesc.name = dev_name(dev); 16668c2ecf20Sopenharmony_ci vg->pctldesc.pins = vg->soc->pins; 16678c2ecf20Sopenharmony_ci vg->pctldesc.npins = vg->soc->npins; 16688c2ecf20Sopenharmony_ci 16698c2ecf20Sopenharmony_ci vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg); 16708c2ecf20Sopenharmony_ci if (IS_ERR(vg->pctldev)) { 16718c2ecf20Sopenharmony_ci dev_err(dev, "failed to register pinctrl driver\n"); 16728c2ecf20Sopenharmony_ci return PTR_ERR(vg->pctldev); 16738c2ecf20Sopenharmony_ci } 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_ci ret = byt_gpio_probe(vg); 16768c2ecf20Sopenharmony_ci if (ret) 16778c2ecf20Sopenharmony_ci return ret; 16788c2ecf20Sopenharmony_ci 16798c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, vg); 16808c2ecf20Sopenharmony_ci pm_runtime_enable(dev); 16818c2ecf20Sopenharmony_ci 16828c2ecf20Sopenharmony_ci return 0; 16838c2ecf20Sopenharmony_ci} 16848c2ecf20Sopenharmony_ci 16858c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 16868c2ecf20Sopenharmony_cistatic int byt_gpio_suspend(struct device *dev) 16878c2ecf20Sopenharmony_ci{ 16888c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = dev_get_drvdata(dev); 16898c2ecf20Sopenharmony_ci unsigned long flags; 16908c2ecf20Sopenharmony_ci int i; 16918c2ecf20Sopenharmony_ci 16928c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 16938c2ecf20Sopenharmony_ci 16948c2ecf20Sopenharmony_ci for (i = 0; i < vg->soc->npins; i++) { 16958c2ecf20Sopenharmony_ci void __iomem *reg; 16968c2ecf20Sopenharmony_ci u32 value; 16978c2ecf20Sopenharmony_ci unsigned int pin = vg->soc->pins[i].number; 16988c2ecf20Sopenharmony_ci 16998c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 17008c2ecf20Sopenharmony_ci if (!reg) { 17018c2ecf20Sopenharmony_ci dev_warn(vg->dev, 17028c2ecf20Sopenharmony_ci "Pin %i: could not retrieve conf0 register\n", 17038c2ecf20Sopenharmony_ci i); 17048c2ecf20Sopenharmony_ci continue; 17058c2ecf20Sopenharmony_ci } 17068c2ecf20Sopenharmony_ci value = readl(reg) & BYT_CONF0_RESTORE_MASK; 17078c2ecf20Sopenharmony_ci vg->context.pads[i].conf0 = value; 17088c2ecf20Sopenharmony_ci 17098c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 17108c2ecf20Sopenharmony_ci value = readl(reg) & BYT_VAL_RESTORE_MASK; 17118c2ecf20Sopenharmony_ci vg->context.pads[i].val = value; 17128c2ecf20Sopenharmony_ci } 17138c2ecf20Sopenharmony_ci 17148c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 17158c2ecf20Sopenharmony_ci return 0; 17168c2ecf20Sopenharmony_ci} 17178c2ecf20Sopenharmony_ci 17188c2ecf20Sopenharmony_cistatic int byt_gpio_resume(struct device *dev) 17198c2ecf20Sopenharmony_ci{ 17208c2ecf20Sopenharmony_ci struct intel_pinctrl *vg = dev_get_drvdata(dev); 17218c2ecf20Sopenharmony_ci unsigned long flags; 17228c2ecf20Sopenharmony_ci int i; 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 17258c2ecf20Sopenharmony_ci 17268c2ecf20Sopenharmony_ci for (i = 0; i < vg->soc->npins; i++) { 17278c2ecf20Sopenharmony_ci void __iomem *reg; 17288c2ecf20Sopenharmony_ci u32 value; 17298c2ecf20Sopenharmony_ci unsigned int pin = vg->soc->pins[i].number; 17308c2ecf20Sopenharmony_ci 17318c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 17328c2ecf20Sopenharmony_ci if (!reg) { 17338c2ecf20Sopenharmony_ci dev_warn(vg->dev, 17348c2ecf20Sopenharmony_ci "Pin %i: could not retrieve conf0 register\n", 17358c2ecf20Sopenharmony_ci i); 17368c2ecf20Sopenharmony_ci continue; 17378c2ecf20Sopenharmony_ci } 17388c2ecf20Sopenharmony_ci value = readl(reg); 17398c2ecf20Sopenharmony_ci if ((value & BYT_CONF0_RESTORE_MASK) != 17408c2ecf20Sopenharmony_ci vg->context.pads[i].conf0) { 17418c2ecf20Sopenharmony_ci value &= ~BYT_CONF0_RESTORE_MASK; 17428c2ecf20Sopenharmony_ci value |= vg->context.pads[i].conf0; 17438c2ecf20Sopenharmony_ci writel(value, reg); 17448c2ecf20Sopenharmony_ci dev_info(dev, "restored pin %d conf0 %#08x", i, value); 17458c2ecf20Sopenharmony_ci } 17468c2ecf20Sopenharmony_ci 17478c2ecf20Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 17488c2ecf20Sopenharmony_ci value = readl(reg); 17498c2ecf20Sopenharmony_ci if ((value & BYT_VAL_RESTORE_MASK) != 17508c2ecf20Sopenharmony_ci vg->context.pads[i].val) { 17518c2ecf20Sopenharmony_ci u32 v; 17528c2ecf20Sopenharmony_ci 17538c2ecf20Sopenharmony_ci v = value & ~BYT_VAL_RESTORE_MASK; 17548c2ecf20Sopenharmony_ci v |= vg->context.pads[i].val; 17558c2ecf20Sopenharmony_ci if (v != value) { 17568c2ecf20Sopenharmony_ci writel(v, reg); 17578c2ecf20Sopenharmony_ci dev_dbg(dev, "restored pin %d val %#08x\n", 17588c2ecf20Sopenharmony_ci i, v); 17598c2ecf20Sopenharmony_ci } 17608c2ecf20Sopenharmony_ci } 17618c2ecf20Sopenharmony_ci } 17628c2ecf20Sopenharmony_ci 17638c2ecf20Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 17648c2ecf20Sopenharmony_ci return 0; 17658c2ecf20Sopenharmony_ci} 17668c2ecf20Sopenharmony_ci#endif 17678c2ecf20Sopenharmony_ci 17688c2ecf20Sopenharmony_ci#ifdef CONFIG_PM 17698c2ecf20Sopenharmony_cistatic int byt_gpio_runtime_suspend(struct device *dev) 17708c2ecf20Sopenharmony_ci{ 17718c2ecf20Sopenharmony_ci return 0; 17728c2ecf20Sopenharmony_ci} 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_cistatic int byt_gpio_runtime_resume(struct device *dev) 17758c2ecf20Sopenharmony_ci{ 17768c2ecf20Sopenharmony_ci return 0; 17778c2ecf20Sopenharmony_ci} 17788c2ecf20Sopenharmony_ci#endif 17798c2ecf20Sopenharmony_ci 17808c2ecf20Sopenharmony_cistatic const struct dev_pm_ops byt_gpio_pm_ops = { 17818c2ecf20Sopenharmony_ci SET_LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) 17828c2ecf20Sopenharmony_ci SET_RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, 17838c2ecf20Sopenharmony_ci NULL) 17848c2ecf20Sopenharmony_ci}; 17858c2ecf20Sopenharmony_ci 17868c2ecf20Sopenharmony_cistatic struct platform_driver byt_gpio_driver = { 17878c2ecf20Sopenharmony_ci .probe = byt_pinctrl_probe, 17888c2ecf20Sopenharmony_ci .driver = { 17898c2ecf20Sopenharmony_ci .name = "byt_gpio", 17908c2ecf20Sopenharmony_ci .pm = &byt_gpio_pm_ops, 17918c2ecf20Sopenharmony_ci .acpi_match_table = byt_gpio_acpi_match, 17928c2ecf20Sopenharmony_ci .suppress_bind_attrs = true, 17938c2ecf20Sopenharmony_ci }, 17948c2ecf20Sopenharmony_ci}; 17958c2ecf20Sopenharmony_ci 17968c2ecf20Sopenharmony_cistatic int __init byt_gpio_init(void) 17978c2ecf20Sopenharmony_ci{ 17988c2ecf20Sopenharmony_ci return platform_driver_register(&byt_gpio_driver); 17998c2ecf20Sopenharmony_ci} 18008c2ecf20Sopenharmony_cisubsys_initcall(byt_gpio_init); 1801