162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Pinctrl GPIO driver for Intel Baytrail 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2012-2013, Intel Corporation 662306a36Sopenharmony_ci * Author: Mathias Nyman <mathias.nyman@linux.intel.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/acpi.h> 1062306a36Sopenharmony_ci#include <linux/bitops.h> 1162306a36Sopenharmony_ci#include <linux/gpio/driver.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/interrupt.h> 1462306a36Sopenharmony_ci#include <linux/io.h> 1562306a36Sopenharmony_ci#include <linux/kernel.h> 1662306a36Sopenharmony_ci#include <linux/module.h> 1762306a36Sopenharmony_ci#include <linux/types.h> 1862306a36Sopenharmony_ci#include <linux/platform_device.h> 1962306a36Sopenharmony_ci#include <linux/pm_runtime.h> 2062306a36Sopenharmony_ci#include <linux/property.h> 2162306a36Sopenharmony_ci#include <linux/seq_file.h> 2262306a36Sopenharmony_ci#include <linux/string_helpers.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#include <linux/pinctrl/pinctrl.h> 2562306a36Sopenharmony_ci#include <linux/pinctrl/pinmux.h> 2662306a36Sopenharmony_ci#include <linux/pinctrl/pinconf.h> 2762306a36Sopenharmony_ci#include <linux/pinctrl/pinconf-generic.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#include "pinctrl-intel.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* memory mapped register offsets */ 3262306a36Sopenharmony_ci#define BYT_CONF0_REG 0x000 3362306a36Sopenharmony_ci#define BYT_CONF1_REG 0x004 3462306a36Sopenharmony_ci#define BYT_VAL_REG 0x008 3562306a36Sopenharmony_ci#define BYT_DFT_REG 0x00c 3662306a36Sopenharmony_ci#define BYT_INT_STAT_REG 0x800 3762306a36Sopenharmony_ci#define BYT_DIRECT_IRQ_REG 0x980 3862306a36Sopenharmony_ci#define BYT_DEBOUNCE_REG 0x9d0 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* BYT_CONF0_REG register bits */ 4162306a36Sopenharmony_ci#define BYT_IODEN BIT(31) 4262306a36Sopenharmony_ci#define BYT_DIRECT_IRQ_EN BIT(27) 4362306a36Sopenharmony_ci#define BYT_TRIG_MASK GENMASK(26, 24) 4462306a36Sopenharmony_ci#define BYT_TRIG_NEG BIT(26) 4562306a36Sopenharmony_ci#define BYT_TRIG_POS BIT(25) 4662306a36Sopenharmony_ci#define BYT_TRIG_LVL BIT(24) 4762306a36Sopenharmony_ci#define BYT_DEBOUNCE_EN BIT(20) 4862306a36Sopenharmony_ci#define BYT_GLITCH_FILTER_EN BIT(19) 4962306a36Sopenharmony_ci#define BYT_GLITCH_F_SLOW_CLK BIT(17) 5062306a36Sopenharmony_ci#define BYT_GLITCH_F_FAST_CLK BIT(16) 5162306a36Sopenharmony_ci#define BYT_PULL_STR_SHIFT 9 5262306a36Sopenharmony_ci#define BYT_PULL_STR_MASK GENMASK(10, 9) 5362306a36Sopenharmony_ci#define BYT_PULL_STR_2K (0 << BYT_PULL_STR_SHIFT) 5462306a36Sopenharmony_ci#define BYT_PULL_STR_10K (1 << BYT_PULL_STR_SHIFT) 5562306a36Sopenharmony_ci#define BYT_PULL_STR_20K (2 << BYT_PULL_STR_SHIFT) 5662306a36Sopenharmony_ci#define BYT_PULL_STR_40K (3 << BYT_PULL_STR_SHIFT) 5762306a36Sopenharmony_ci#define BYT_PULL_ASSIGN_MASK GENMASK(8, 7) 5862306a36Sopenharmony_ci#define BYT_PULL_ASSIGN_DOWN BIT(8) 5962306a36Sopenharmony_ci#define BYT_PULL_ASSIGN_UP BIT(7) 6062306a36Sopenharmony_ci#define BYT_PIN_MUX GENMASK(2, 0) 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* BYT_VAL_REG register bits */ 6362306a36Sopenharmony_ci#define BYT_DIR_MASK GENMASK(2, 1) 6462306a36Sopenharmony_ci#define BYT_INPUT_EN BIT(2) /* 0: input enabled (active low)*/ 6562306a36Sopenharmony_ci#define BYT_OUTPUT_EN BIT(1) /* 0: output enabled (active low)*/ 6662306a36Sopenharmony_ci#define BYT_LEVEL BIT(0) 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#define BYT_CONF0_RESTORE_MASK (BYT_DIRECT_IRQ_EN | BYT_TRIG_MASK | BYT_PIN_MUX) 6962306a36Sopenharmony_ci#define BYT_VAL_RESTORE_MASK (BYT_DIR_MASK | BYT_LEVEL) 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* BYT_DEBOUNCE_REG bits */ 7262306a36Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_MASK GENMASK(2, 0) 7362306a36Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_375US 1 7462306a36Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_750US 2 7562306a36Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_1500US 3 7662306a36Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_3MS 4 7762306a36Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_6MS 5 7862306a36Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_12MS 6 7962306a36Sopenharmony_ci#define BYT_DEBOUNCE_PULSE_24MS 7 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci#define BYT_NGPIO_SCORE 102 8262306a36Sopenharmony_ci#define BYT_NGPIO_NCORE 28 8362306a36Sopenharmony_ci#define BYT_NGPIO_SUS 44 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#define BYT_SCORE_ACPI_UID "1" 8662306a36Sopenharmony_ci#define BYT_NCORE_ACPI_UID "2" 8762306a36Sopenharmony_ci#define BYT_SUS_ACPI_UID "3" 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci/* 9062306a36Sopenharmony_ci * This is the function value most pins have for GPIO muxing. If the value 9162306a36Sopenharmony_ci * differs from the default one, it must be explicitly mentioned. Otherwise, the 9262306a36Sopenharmony_ci * pin control implementation will set the muxing value to default GPIO if it 9362306a36Sopenharmony_ci * does not find a match for the requested function. 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_ci#define BYT_DEFAULT_GPIO_MUX 0 9662306a36Sopenharmony_ci#define BYT_ALTER_GPIO_MUX 1 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistruct intel_pad_context { 9962306a36Sopenharmony_ci u32 conf0; 10062306a36Sopenharmony_ci u32 val; 10162306a36Sopenharmony_ci}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#define COMMUNITY(p, n, map) \ 10462306a36Sopenharmony_ci { \ 10562306a36Sopenharmony_ci .pin_base = (p), \ 10662306a36Sopenharmony_ci .npins = (n), \ 10762306a36Sopenharmony_ci .pad_map = (map),\ 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/* SCORE pins, aka GPIOC_<pin_no> or GPIO_S0_SC[<pin_no>] */ 11162306a36Sopenharmony_cistatic const struct pinctrl_pin_desc byt_score_pins[] = { 11262306a36Sopenharmony_ci PINCTRL_PIN(0, "SATA_GP0"), 11362306a36Sopenharmony_ci PINCTRL_PIN(1, "SATA_GP1"), 11462306a36Sopenharmony_ci PINCTRL_PIN(2, "SATA_LED#"), 11562306a36Sopenharmony_ci PINCTRL_PIN(3, "PCIE_CLKREQ0"), 11662306a36Sopenharmony_ci PINCTRL_PIN(4, "PCIE_CLKREQ1"), 11762306a36Sopenharmony_ci PINCTRL_PIN(5, "PCIE_CLKREQ2"), 11862306a36Sopenharmony_ci PINCTRL_PIN(6, "PCIE_CLKREQ3"), 11962306a36Sopenharmony_ci PINCTRL_PIN(7, "SD3_WP"), 12062306a36Sopenharmony_ci PINCTRL_PIN(8, "HDA_RST"), 12162306a36Sopenharmony_ci PINCTRL_PIN(9, "HDA_SYNC"), 12262306a36Sopenharmony_ci PINCTRL_PIN(10, "HDA_CLK"), 12362306a36Sopenharmony_ci PINCTRL_PIN(11, "HDA_SDO"), 12462306a36Sopenharmony_ci PINCTRL_PIN(12, "HDA_SDI0"), 12562306a36Sopenharmony_ci PINCTRL_PIN(13, "HDA_SDI1"), 12662306a36Sopenharmony_ci PINCTRL_PIN(14, "GPIO_S0_SC14"), 12762306a36Sopenharmony_ci PINCTRL_PIN(15, "GPIO_S0_SC15"), 12862306a36Sopenharmony_ci PINCTRL_PIN(16, "MMC1_CLK"), 12962306a36Sopenharmony_ci PINCTRL_PIN(17, "MMC1_D0"), 13062306a36Sopenharmony_ci PINCTRL_PIN(18, "MMC1_D1"), 13162306a36Sopenharmony_ci PINCTRL_PIN(19, "MMC1_D2"), 13262306a36Sopenharmony_ci PINCTRL_PIN(20, "MMC1_D3"), 13362306a36Sopenharmony_ci PINCTRL_PIN(21, "MMC1_D4"), 13462306a36Sopenharmony_ci PINCTRL_PIN(22, "MMC1_D5"), 13562306a36Sopenharmony_ci PINCTRL_PIN(23, "MMC1_D6"), 13662306a36Sopenharmony_ci PINCTRL_PIN(24, "MMC1_D7"), 13762306a36Sopenharmony_ci PINCTRL_PIN(25, "MMC1_CMD"), 13862306a36Sopenharmony_ci PINCTRL_PIN(26, "MMC1_RST"), 13962306a36Sopenharmony_ci PINCTRL_PIN(27, "SD2_CLK"), 14062306a36Sopenharmony_ci PINCTRL_PIN(28, "SD2_D0"), 14162306a36Sopenharmony_ci PINCTRL_PIN(29, "SD2_D1"), 14262306a36Sopenharmony_ci PINCTRL_PIN(30, "SD2_D2"), 14362306a36Sopenharmony_ci PINCTRL_PIN(31, "SD2_D3_CD"), 14462306a36Sopenharmony_ci PINCTRL_PIN(32, "SD2_CMD"), 14562306a36Sopenharmony_ci PINCTRL_PIN(33, "SD3_CLK"), 14662306a36Sopenharmony_ci PINCTRL_PIN(34, "SD3_D0"), 14762306a36Sopenharmony_ci PINCTRL_PIN(35, "SD3_D1"), 14862306a36Sopenharmony_ci PINCTRL_PIN(36, "SD3_D2"), 14962306a36Sopenharmony_ci PINCTRL_PIN(37, "SD3_D3"), 15062306a36Sopenharmony_ci PINCTRL_PIN(38, "SD3_CD"), 15162306a36Sopenharmony_ci PINCTRL_PIN(39, "SD3_CMD"), 15262306a36Sopenharmony_ci PINCTRL_PIN(40, "SD3_1P8EN"), 15362306a36Sopenharmony_ci PINCTRL_PIN(41, "SD3_PWREN#"), 15462306a36Sopenharmony_ci PINCTRL_PIN(42, "ILB_LPC_AD0"), 15562306a36Sopenharmony_ci PINCTRL_PIN(43, "ILB_LPC_AD1"), 15662306a36Sopenharmony_ci PINCTRL_PIN(44, "ILB_LPC_AD2"), 15762306a36Sopenharmony_ci PINCTRL_PIN(45, "ILB_LPC_AD3"), 15862306a36Sopenharmony_ci PINCTRL_PIN(46, "ILB_LPC_FRAME"), 15962306a36Sopenharmony_ci PINCTRL_PIN(47, "ILB_LPC_CLK0"), 16062306a36Sopenharmony_ci PINCTRL_PIN(48, "ILB_LPC_CLK1"), 16162306a36Sopenharmony_ci PINCTRL_PIN(49, "ILB_LPC_CLKRUN"), 16262306a36Sopenharmony_ci PINCTRL_PIN(50, "ILB_LPC_SERIRQ"), 16362306a36Sopenharmony_ci PINCTRL_PIN(51, "PCU_SMB_DATA"), 16462306a36Sopenharmony_ci PINCTRL_PIN(52, "PCU_SMB_CLK"), 16562306a36Sopenharmony_ci PINCTRL_PIN(53, "PCU_SMB_ALERT"), 16662306a36Sopenharmony_ci PINCTRL_PIN(54, "ILB_8254_SPKR"), 16762306a36Sopenharmony_ci PINCTRL_PIN(55, "GPIO_S0_SC55"), 16862306a36Sopenharmony_ci PINCTRL_PIN(56, "GPIO_S0_SC56"), 16962306a36Sopenharmony_ci PINCTRL_PIN(57, "GPIO_S0_SC57"), 17062306a36Sopenharmony_ci PINCTRL_PIN(58, "GPIO_S0_SC58"), 17162306a36Sopenharmony_ci PINCTRL_PIN(59, "GPIO_S0_SC59"), 17262306a36Sopenharmony_ci PINCTRL_PIN(60, "GPIO_S0_SC60"), 17362306a36Sopenharmony_ci PINCTRL_PIN(61, "GPIO_S0_SC61"), 17462306a36Sopenharmony_ci PINCTRL_PIN(62, "LPE_I2S2_CLK"), 17562306a36Sopenharmony_ci PINCTRL_PIN(63, "LPE_I2S2_FRM"), 17662306a36Sopenharmony_ci PINCTRL_PIN(64, "LPE_I2S2_DATAIN"), 17762306a36Sopenharmony_ci PINCTRL_PIN(65, "LPE_I2S2_DATAOUT"), 17862306a36Sopenharmony_ci PINCTRL_PIN(66, "SIO_SPI_CS"), 17962306a36Sopenharmony_ci PINCTRL_PIN(67, "SIO_SPI_MISO"), 18062306a36Sopenharmony_ci PINCTRL_PIN(68, "SIO_SPI_MOSI"), 18162306a36Sopenharmony_ci PINCTRL_PIN(69, "SIO_SPI_CLK"), 18262306a36Sopenharmony_ci PINCTRL_PIN(70, "SIO_UART1_RXD"), 18362306a36Sopenharmony_ci PINCTRL_PIN(71, "SIO_UART1_TXD"), 18462306a36Sopenharmony_ci PINCTRL_PIN(72, "SIO_UART1_RTS"), 18562306a36Sopenharmony_ci PINCTRL_PIN(73, "SIO_UART1_CTS"), 18662306a36Sopenharmony_ci PINCTRL_PIN(74, "SIO_UART2_RXD"), 18762306a36Sopenharmony_ci PINCTRL_PIN(75, "SIO_UART2_TXD"), 18862306a36Sopenharmony_ci PINCTRL_PIN(76, "SIO_UART2_RTS"), 18962306a36Sopenharmony_ci PINCTRL_PIN(77, "SIO_UART2_CTS"), 19062306a36Sopenharmony_ci PINCTRL_PIN(78, "SIO_I2C0_DATA"), 19162306a36Sopenharmony_ci PINCTRL_PIN(79, "SIO_I2C0_CLK"), 19262306a36Sopenharmony_ci PINCTRL_PIN(80, "SIO_I2C1_DATA"), 19362306a36Sopenharmony_ci PINCTRL_PIN(81, "SIO_I2C1_CLK"), 19462306a36Sopenharmony_ci PINCTRL_PIN(82, "SIO_I2C2_DATA"), 19562306a36Sopenharmony_ci PINCTRL_PIN(83, "SIO_I2C2_CLK"), 19662306a36Sopenharmony_ci PINCTRL_PIN(84, "SIO_I2C3_DATA"), 19762306a36Sopenharmony_ci PINCTRL_PIN(85, "SIO_I2C3_CLK"), 19862306a36Sopenharmony_ci PINCTRL_PIN(86, "SIO_I2C4_DATA"), 19962306a36Sopenharmony_ci PINCTRL_PIN(87, "SIO_I2C4_CLK"), 20062306a36Sopenharmony_ci PINCTRL_PIN(88, "SIO_I2C5_DATA"), 20162306a36Sopenharmony_ci PINCTRL_PIN(89, "SIO_I2C5_CLK"), 20262306a36Sopenharmony_ci PINCTRL_PIN(90, "SIO_I2C6_DATA"), 20362306a36Sopenharmony_ci PINCTRL_PIN(91, "SIO_I2C6_CLK"), 20462306a36Sopenharmony_ci PINCTRL_PIN(92, "GPIO_S0_SC92"), 20562306a36Sopenharmony_ci PINCTRL_PIN(93, "GPIO_S0_SC93"), 20662306a36Sopenharmony_ci PINCTRL_PIN(94, "SIO_PWM0"), 20762306a36Sopenharmony_ci PINCTRL_PIN(95, "SIO_PWM1"), 20862306a36Sopenharmony_ci PINCTRL_PIN(96, "PMC_PLT_CLK0"), 20962306a36Sopenharmony_ci PINCTRL_PIN(97, "PMC_PLT_CLK1"), 21062306a36Sopenharmony_ci PINCTRL_PIN(98, "PMC_PLT_CLK2"), 21162306a36Sopenharmony_ci PINCTRL_PIN(99, "PMC_PLT_CLK3"), 21262306a36Sopenharmony_ci PINCTRL_PIN(100, "PMC_PLT_CLK4"), 21362306a36Sopenharmony_ci PINCTRL_PIN(101, "PMC_PLT_CLK5"), 21462306a36Sopenharmony_ci}; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistatic const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = { 21762306a36Sopenharmony_ci 85, 89, 93, 96, 99, 102, 98, 101, 34, 37, 21862306a36Sopenharmony_ci 36, 38, 39, 35, 40, 84, 62, 61, 64, 59, 21962306a36Sopenharmony_ci 54, 56, 60, 55, 63, 57, 51, 50, 53, 47, 22062306a36Sopenharmony_ci 52, 49, 48, 43, 46, 41, 45, 42, 58, 44, 22162306a36Sopenharmony_ci 95, 105, 70, 68, 67, 66, 69, 71, 65, 72, 22262306a36Sopenharmony_ci 86, 90, 88, 92, 103, 77, 79, 83, 78, 81, 22362306a36Sopenharmony_ci 80, 82, 13, 12, 15, 14, 17, 18, 19, 16, 22462306a36Sopenharmony_ci 2, 1, 0, 4, 6, 7, 9, 8, 33, 32, 22562306a36Sopenharmony_ci 31, 30, 29, 27, 25, 28, 26, 23, 21, 20, 22662306a36Sopenharmony_ci 24, 22, 5, 3, 10, 11, 106, 87, 91, 104, 22762306a36Sopenharmony_ci 97, 100, 22862306a36Sopenharmony_ci}; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci/* SCORE groups */ 23162306a36Sopenharmony_cistatic const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 }; 23262306a36Sopenharmony_cistatic const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 }; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic const unsigned int byt_score_pwm0_pins[] = { 94 }; 23562306a36Sopenharmony_cistatic const unsigned int byt_score_pwm1_pins[] = { 95 }; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic const unsigned int byt_score_sio_spi_pins[] = { 66, 67, 68, 69 }; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic const unsigned int byt_score_i2c5_pins[] = { 88, 89 }; 24062306a36Sopenharmony_cistatic const unsigned int byt_score_i2c6_pins[] = { 90, 91 }; 24162306a36Sopenharmony_cistatic const unsigned int byt_score_i2c4_pins[] = { 86, 87 }; 24262306a36Sopenharmony_cistatic const unsigned int byt_score_i2c3_pins[] = { 84, 85 }; 24362306a36Sopenharmony_cistatic const unsigned int byt_score_i2c2_pins[] = { 82, 83 }; 24462306a36Sopenharmony_cistatic const unsigned int byt_score_i2c1_pins[] = { 80, 81 }; 24562306a36Sopenharmony_cistatic const unsigned int byt_score_i2c0_pins[] = { 78, 79 }; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic const unsigned int byt_score_ssp0_pins[] = { 8, 9, 10, 11 }; 24862306a36Sopenharmony_cistatic const unsigned int byt_score_ssp1_pins[] = { 12, 13, 14, 15 }; 24962306a36Sopenharmony_cistatic const unsigned int byt_score_ssp2_pins[] = { 62, 63, 64, 65 }; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistatic const unsigned int byt_score_sdcard_pins[] = { 25262306a36Sopenharmony_ci 7, 33, 34, 35, 36, 37, 38, 39, 40, 41, 25362306a36Sopenharmony_ci}; 25462306a36Sopenharmony_cistatic const unsigned int byt_score_sdcard_mux_values[] = { 25562306a36Sopenharmony_ci 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25662306a36Sopenharmony_ci}; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic const unsigned int byt_score_sdio_pins[] = { 27, 28, 29, 30, 31, 32 }; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic const unsigned int byt_score_emmc_pins[] = { 26162306a36Sopenharmony_ci 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26262306a36Sopenharmony_ci}; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistatic const unsigned int byt_score_ilb_lpc_pins[] = { 26562306a36Sopenharmony_ci 42, 43, 44, 45, 46, 47, 48, 49, 50, 26662306a36Sopenharmony_ci}; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_cistatic const unsigned int byt_score_sata_pins[] = { 0, 1, 2 }; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic const unsigned int byt_score_plt_clk0_pins[] = { 96 }; 27162306a36Sopenharmony_cistatic const unsigned int byt_score_plt_clk1_pins[] = { 97 }; 27262306a36Sopenharmony_cistatic const unsigned int byt_score_plt_clk2_pins[] = { 98 }; 27362306a36Sopenharmony_cistatic const unsigned int byt_score_plt_clk3_pins[] = { 99 }; 27462306a36Sopenharmony_cistatic const unsigned int byt_score_plt_clk4_pins[] = { 100 }; 27562306a36Sopenharmony_cistatic const unsigned int byt_score_plt_clk5_pins[] = { 101 }; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 }; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic const struct intel_pingroup byt_score_groups[] = { 28062306a36Sopenharmony_ci PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1), 28162306a36Sopenharmony_ci PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1), 28262306a36Sopenharmony_ci PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1), 28362306a36Sopenharmony_ci PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1), 28462306a36Sopenharmony_ci PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1), 28562306a36Sopenharmony_ci PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1), 28662306a36Sopenharmony_ci PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1), 28762306a36Sopenharmony_ci PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1), 28862306a36Sopenharmony_ci PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1), 28962306a36Sopenharmony_ci PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1), 29062306a36Sopenharmony_ci PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1), 29162306a36Sopenharmony_ci PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1), 29262306a36Sopenharmony_ci PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1), 29362306a36Sopenharmony_ci PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1), 29462306a36Sopenharmony_ci PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1), 29562306a36Sopenharmony_ci PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values), 29662306a36Sopenharmony_ci PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1), 29762306a36Sopenharmony_ci PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1), 29862306a36Sopenharmony_ci PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1), 29962306a36Sopenharmony_ci PIN_GROUP("sata_grp", byt_score_sata_pins, 1), 30062306a36Sopenharmony_ci PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1), 30162306a36Sopenharmony_ci PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1), 30262306a36Sopenharmony_ci PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1), 30362306a36Sopenharmony_ci PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1), 30462306a36Sopenharmony_ci PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1), 30562306a36Sopenharmony_ci PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1), 30662306a36Sopenharmony_ci PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1), 30762306a36Sopenharmony_ci}; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_cistatic const char * const byt_score_uart_groups[] = { 31062306a36Sopenharmony_ci "uart1_grp", "uart2_grp", 31162306a36Sopenharmony_ci}; 31262306a36Sopenharmony_cistatic const char * const byt_score_pwm_groups[] = { 31362306a36Sopenharmony_ci "pwm0_grp", "pwm1_grp", 31462306a36Sopenharmony_ci}; 31562306a36Sopenharmony_cistatic const char * const byt_score_ssp_groups[] = { 31662306a36Sopenharmony_ci "ssp0_grp", "ssp1_grp", "ssp2_grp", 31762306a36Sopenharmony_ci}; 31862306a36Sopenharmony_cistatic const char * const byt_score_spi_groups[] = { "sio_spi_grp" }; 31962306a36Sopenharmony_cistatic const char * const byt_score_i2c_groups[] = { 32062306a36Sopenharmony_ci "i2c0_grp", "i2c1_grp", "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", 32162306a36Sopenharmony_ci "i2c6_grp", 32262306a36Sopenharmony_ci}; 32362306a36Sopenharmony_cistatic const char * const byt_score_sdcard_groups[] = { "sdcard_grp" }; 32462306a36Sopenharmony_cistatic const char * const byt_score_sdio_groups[] = { "sdio_grp" }; 32562306a36Sopenharmony_cistatic const char * const byt_score_emmc_groups[] = { "emmc_grp" }; 32662306a36Sopenharmony_cistatic const char * const byt_score_lpc_groups[] = { "lpc_grp" }; 32762306a36Sopenharmony_cistatic const char * const byt_score_sata_groups[] = { "sata_grp" }; 32862306a36Sopenharmony_cistatic const char * const byt_score_plt_clk_groups[] = { 32962306a36Sopenharmony_ci "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 33062306a36Sopenharmony_ci "plt_clk4_grp", "plt_clk5_grp", 33162306a36Sopenharmony_ci}; 33262306a36Sopenharmony_cistatic const char * const byt_score_smbus_groups[] = { "smbus_grp" }; 33362306a36Sopenharmony_cistatic const char * const byt_score_gpio_groups[] = { 33462306a36Sopenharmony_ci "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp", 33562306a36Sopenharmony_ci "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp", 33662306a36Sopenharmony_ci "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp", 33762306a36Sopenharmony_ci "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp", 33862306a36Sopenharmony_ci "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp", 33962306a36Sopenharmony_ci "plt_clk4_grp", "plt_clk5_grp", "smbus_grp", 34062306a36Sopenharmony_ci}; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_cistatic const struct intel_function byt_score_functions[] = { 34362306a36Sopenharmony_ci FUNCTION("uart", byt_score_uart_groups), 34462306a36Sopenharmony_ci FUNCTION("pwm", byt_score_pwm_groups), 34562306a36Sopenharmony_ci FUNCTION("ssp", byt_score_ssp_groups), 34662306a36Sopenharmony_ci FUNCTION("spi", byt_score_spi_groups), 34762306a36Sopenharmony_ci FUNCTION("i2c", byt_score_i2c_groups), 34862306a36Sopenharmony_ci FUNCTION("sdcard", byt_score_sdcard_groups), 34962306a36Sopenharmony_ci FUNCTION("sdio", byt_score_sdio_groups), 35062306a36Sopenharmony_ci FUNCTION("emmc", byt_score_emmc_groups), 35162306a36Sopenharmony_ci FUNCTION("lpc", byt_score_lpc_groups), 35262306a36Sopenharmony_ci FUNCTION("sata", byt_score_sata_groups), 35362306a36Sopenharmony_ci FUNCTION("plt_clk", byt_score_plt_clk_groups), 35462306a36Sopenharmony_ci FUNCTION("smbus", byt_score_smbus_groups), 35562306a36Sopenharmony_ci FUNCTION("gpio", byt_score_gpio_groups), 35662306a36Sopenharmony_ci}; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_cistatic const struct intel_community byt_score_communities[] = { 35962306a36Sopenharmony_ci COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), 36062306a36Sopenharmony_ci}; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_cistatic const struct intel_pinctrl_soc_data byt_score_soc_data = { 36362306a36Sopenharmony_ci .uid = BYT_SCORE_ACPI_UID, 36462306a36Sopenharmony_ci .pins = byt_score_pins, 36562306a36Sopenharmony_ci .npins = ARRAY_SIZE(byt_score_pins), 36662306a36Sopenharmony_ci .groups = byt_score_groups, 36762306a36Sopenharmony_ci .ngroups = ARRAY_SIZE(byt_score_groups), 36862306a36Sopenharmony_ci .functions = byt_score_functions, 36962306a36Sopenharmony_ci .nfunctions = ARRAY_SIZE(byt_score_functions), 37062306a36Sopenharmony_ci .communities = byt_score_communities, 37162306a36Sopenharmony_ci .ncommunities = ARRAY_SIZE(byt_score_communities), 37262306a36Sopenharmony_ci}; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci/* SUS pins, aka GPIOS_<pin_no> or GPIO_S5[<pin_no>] */ 37562306a36Sopenharmony_cistatic const struct pinctrl_pin_desc byt_sus_pins[] = { 37662306a36Sopenharmony_ci PINCTRL_PIN(0, "GPIO_S50"), 37762306a36Sopenharmony_ci PINCTRL_PIN(1, "GPIO_S51"), 37862306a36Sopenharmony_ci PINCTRL_PIN(2, "GPIO_S52"), 37962306a36Sopenharmony_ci PINCTRL_PIN(3, "GPIO_S53"), 38062306a36Sopenharmony_ci PINCTRL_PIN(4, "GPIO_S54"), 38162306a36Sopenharmony_ci PINCTRL_PIN(5, "GPIO_S55"), 38262306a36Sopenharmony_ci PINCTRL_PIN(6, "GPIO_S56"), 38362306a36Sopenharmony_ci PINCTRL_PIN(7, "GPIO_S57"), 38462306a36Sopenharmony_ci PINCTRL_PIN(8, "GPIO_S58"), 38562306a36Sopenharmony_ci PINCTRL_PIN(9, "GPIO_S59"), 38662306a36Sopenharmony_ci PINCTRL_PIN(10, "GPIO_S510"), 38762306a36Sopenharmony_ci PINCTRL_PIN(11, "PMC_SUSPWRDNACK"), 38862306a36Sopenharmony_ci PINCTRL_PIN(12, "PMC_SUSCLK0"), 38962306a36Sopenharmony_ci PINCTRL_PIN(13, "GPIO_S513"), 39062306a36Sopenharmony_ci PINCTRL_PIN(14, "USB_ULPI_RST"), 39162306a36Sopenharmony_ci PINCTRL_PIN(15, "PMC_WAKE_PCIE0#"), 39262306a36Sopenharmony_ci PINCTRL_PIN(16, "PMC_PWRBTN"), 39362306a36Sopenharmony_ci PINCTRL_PIN(17, "GPIO_S517"), 39462306a36Sopenharmony_ci PINCTRL_PIN(18, "PMC_SUS_STAT"), 39562306a36Sopenharmony_ci PINCTRL_PIN(19, "USB_OC0"), 39662306a36Sopenharmony_ci PINCTRL_PIN(20, "USB_OC1"), 39762306a36Sopenharmony_ci PINCTRL_PIN(21, "PCU_SPI_CS1"), 39862306a36Sopenharmony_ci PINCTRL_PIN(22, "GPIO_S522"), 39962306a36Sopenharmony_ci PINCTRL_PIN(23, "GPIO_S523"), 40062306a36Sopenharmony_ci PINCTRL_PIN(24, "GPIO_S524"), 40162306a36Sopenharmony_ci PINCTRL_PIN(25, "GPIO_S525"), 40262306a36Sopenharmony_ci PINCTRL_PIN(26, "GPIO_S526"), 40362306a36Sopenharmony_ci PINCTRL_PIN(27, "GPIO_S527"), 40462306a36Sopenharmony_ci PINCTRL_PIN(28, "GPIO_S528"), 40562306a36Sopenharmony_ci PINCTRL_PIN(29, "GPIO_S529"), 40662306a36Sopenharmony_ci PINCTRL_PIN(30, "GPIO_S530"), 40762306a36Sopenharmony_ci PINCTRL_PIN(31, "USB_ULPI_CLK"), 40862306a36Sopenharmony_ci PINCTRL_PIN(32, "USB_ULPI_DATA0"), 40962306a36Sopenharmony_ci PINCTRL_PIN(33, "USB_ULPI_DATA1"), 41062306a36Sopenharmony_ci PINCTRL_PIN(34, "USB_ULPI_DATA2"), 41162306a36Sopenharmony_ci PINCTRL_PIN(35, "USB_ULPI_DATA3"), 41262306a36Sopenharmony_ci PINCTRL_PIN(36, "USB_ULPI_DATA4"), 41362306a36Sopenharmony_ci PINCTRL_PIN(37, "USB_ULPI_DATA5"), 41462306a36Sopenharmony_ci PINCTRL_PIN(38, "USB_ULPI_DATA6"), 41562306a36Sopenharmony_ci PINCTRL_PIN(39, "USB_ULPI_DATA7"), 41662306a36Sopenharmony_ci PINCTRL_PIN(40, "USB_ULPI_DIR"), 41762306a36Sopenharmony_ci PINCTRL_PIN(41, "USB_ULPI_NXT"), 41862306a36Sopenharmony_ci PINCTRL_PIN(42, "USB_ULPI_STP"), 41962306a36Sopenharmony_ci PINCTRL_PIN(43, "USB_ULPI_REFCLK"), 42062306a36Sopenharmony_ci}; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cistatic const unsigned int byt_sus_pins_map[BYT_NGPIO_SUS] = { 42362306a36Sopenharmony_ci 29, 33, 30, 31, 32, 34, 36, 35, 38, 37, 42462306a36Sopenharmony_ci 18, 7, 11, 20, 17, 1, 8, 10, 19, 12, 42562306a36Sopenharmony_ci 0, 2, 23, 39, 28, 27, 22, 21, 24, 25, 42662306a36Sopenharmony_ci 26, 51, 56, 54, 49, 55, 48, 57, 50, 58, 42762306a36Sopenharmony_ci 52, 53, 59, 40, 42862306a36Sopenharmony_ci}; 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_cistatic const unsigned int byt_sus_usb_over_current_pins[] = { 19, 20 }; 43162306a36Sopenharmony_cistatic const unsigned int byt_sus_usb_over_current_mode_values[] = { 0, 0 }; 43262306a36Sopenharmony_cistatic const unsigned int byt_sus_usb_over_current_gpio_mode_values[] = { 1, 1 }; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_cistatic const unsigned int byt_sus_usb_ulpi_pins[] = { 43562306a36Sopenharmony_ci 14, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 43662306a36Sopenharmony_ci}; 43762306a36Sopenharmony_cistatic const unsigned int byt_sus_usb_ulpi_mode_values[] = { 43862306a36Sopenharmony_ci 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 43962306a36Sopenharmony_ci}; 44062306a36Sopenharmony_cistatic const unsigned int byt_sus_usb_ulpi_gpio_mode_values[] = { 44162306a36Sopenharmony_ci 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44262306a36Sopenharmony_ci}; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic const unsigned int byt_sus_pcu_spi_pins[] = { 21 }; 44562306a36Sopenharmony_cistatic const unsigned int byt_sus_pcu_spi_mode_values[] = { 0 }; 44662306a36Sopenharmony_cistatic const unsigned int byt_sus_pcu_spi_gpio_mode_values[] = { 1 }; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_cistatic const unsigned int byt_sus_pmu_clk1_pins[] = { 5 }; 44962306a36Sopenharmony_cistatic const unsigned int byt_sus_pmu_clk2_pins[] = { 6 }; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_cistatic const struct intel_pingroup byt_sus_groups[] = { 45262306a36Sopenharmony_ci PIN_GROUP("usb_oc_grp", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_mode_values), 45362306a36Sopenharmony_ci PIN_GROUP("usb_ulpi_grp", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_mode_values), 45462306a36Sopenharmony_ci PIN_GROUP("pcu_spi_grp", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_mode_values), 45562306a36Sopenharmony_ci PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values), 45662306a36Sopenharmony_ci PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values), 45762306a36Sopenharmony_ci PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values), 45862306a36Sopenharmony_ci PIN_GROUP("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1), 45962306a36Sopenharmony_ci PIN_GROUP("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1), 46062306a36Sopenharmony_ci}; 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_cistatic const char * const byt_sus_usb_groups[] = { 46362306a36Sopenharmony_ci "usb_oc_grp", "usb_ulpi_grp", 46462306a36Sopenharmony_ci}; 46562306a36Sopenharmony_cistatic const char * const byt_sus_spi_groups[] = { "pcu_spi_grp" }; 46662306a36Sopenharmony_cistatic const char * const byt_sus_pmu_clk_groups[] = { 46762306a36Sopenharmony_ci "pmu_clk1_grp", "pmu_clk2_grp", 46862306a36Sopenharmony_ci}; 46962306a36Sopenharmony_cistatic const char * const byt_sus_gpio_groups[] = { 47062306a36Sopenharmony_ci "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio", 47162306a36Sopenharmony_ci "pmu_clk1_grp", "pmu_clk2_grp", 47262306a36Sopenharmony_ci}; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_cistatic const struct intel_function byt_sus_functions[] = { 47562306a36Sopenharmony_ci FUNCTION("usb", byt_sus_usb_groups), 47662306a36Sopenharmony_ci FUNCTION("spi", byt_sus_spi_groups), 47762306a36Sopenharmony_ci FUNCTION("gpio", byt_sus_gpio_groups), 47862306a36Sopenharmony_ci FUNCTION("pmu_clk", byt_sus_pmu_clk_groups), 47962306a36Sopenharmony_ci}; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistatic const struct intel_community byt_sus_communities[] = { 48262306a36Sopenharmony_ci COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), 48362306a36Sopenharmony_ci}; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_cistatic const struct intel_pinctrl_soc_data byt_sus_soc_data = { 48662306a36Sopenharmony_ci .uid = BYT_SUS_ACPI_UID, 48762306a36Sopenharmony_ci .pins = byt_sus_pins, 48862306a36Sopenharmony_ci .npins = ARRAY_SIZE(byt_sus_pins), 48962306a36Sopenharmony_ci .groups = byt_sus_groups, 49062306a36Sopenharmony_ci .ngroups = ARRAY_SIZE(byt_sus_groups), 49162306a36Sopenharmony_ci .functions = byt_sus_functions, 49262306a36Sopenharmony_ci .nfunctions = ARRAY_SIZE(byt_sus_functions), 49362306a36Sopenharmony_ci .communities = byt_sus_communities, 49462306a36Sopenharmony_ci .ncommunities = ARRAY_SIZE(byt_sus_communities), 49562306a36Sopenharmony_ci}; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_cistatic const struct pinctrl_pin_desc byt_ncore_pins[] = { 49862306a36Sopenharmony_ci PINCTRL_PIN(0, "HV_DDI0_HPD"), 49962306a36Sopenharmony_ci PINCTRL_PIN(1, "HV_DDI0_DDC_SDA"), 50062306a36Sopenharmony_ci PINCTRL_PIN(2, "HV_DDI0_DDC_SCL"), 50162306a36Sopenharmony_ci PINCTRL_PIN(3, "PANEL0_VDDEN"), 50262306a36Sopenharmony_ci PINCTRL_PIN(4, "PANEL0_BKLTEN"), 50362306a36Sopenharmony_ci PINCTRL_PIN(5, "PANEL0_BKLTCTL"), 50462306a36Sopenharmony_ci PINCTRL_PIN(6, "HV_DDI1_HPD"), 50562306a36Sopenharmony_ci PINCTRL_PIN(7, "HV_DDI1_DDC_SDA"), 50662306a36Sopenharmony_ci PINCTRL_PIN(8, "HV_DDI1_DDC_SCL"), 50762306a36Sopenharmony_ci PINCTRL_PIN(9, "PANEL1_VDDEN"), 50862306a36Sopenharmony_ci PINCTRL_PIN(10, "PANEL1_BKLTEN"), 50962306a36Sopenharmony_ci PINCTRL_PIN(11, "PANEL1_BKLTCTL"), 51062306a36Sopenharmony_ci PINCTRL_PIN(12, "GP_INTD_DSI_TE1"), 51162306a36Sopenharmony_ci PINCTRL_PIN(13, "HV_DDI2_DDC_SDA"), 51262306a36Sopenharmony_ci PINCTRL_PIN(14, "HV_DDI2_DDC_SCL"), 51362306a36Sopenharmony_ci PINCTRL_PIN(15, "GP_CAMERASB00"), 51462306a36Sopenharmony_ci PINCTRL_PIN(16, "GP_CAMERASB01"), 51562306a36Sopenharmony_ci PINCTRL_PIN(17, "GP_CAMERASB02"), 51662306a36Sopenharmony_ci PINCTRL_PIN(18, "GP_CAMERASB03"), 51762306a36Sopenharmony_ci PINCTRL_PIN(19, "GP_CAMERASB04"), 51862306a36Sopenharmony_ci PINCTRL_PIN(20, "GP_CAMERASB05"), 51962306a36Sopenharmony_ci PINCTRL_PIN(21, "GP_CAMERASB06"), 52062306a36Sopenharmony_ci PINCTRL_PIN(22, "GP_CAMERASB07"), 52162306a36Sopenharmony_ci PINCTRL_PIN(23, "GP_CAMERASB08"), 52262306a36Sopenharmony_ci PINCTRL_PIN(24, "GP_CAMERASB09"), 52362306a36Sopenharmony_ci PINCTRL_PIN(25, "GP_CAMERASB10"), 52462306a36Sopenharmony_ci PINCTRL_PIN(26, "GP_CAMERASB11"), 52562306a36Sopenharmony_ci PINCTRL_PIN(27, "GP_INTD_DSI_TE2"), 52662306a36Sopenharmony_ci}; 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_cistatic const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 52962306a36Sopenharmony_ci 19, 18, 17, 20, 21, 22, 24, 25, 23, 16, 53062306a36Sopenharmony_ci 14, 15, 12, 26, 27, 1, 4, 8, 11, 0, 53162306a36Sopenharmony_ci 3, 6, 10, 13, 2, 5, 9, 7, 53262306a36Sopenharmony_ci}; 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_cistatic const struct intel_community byt_ncore_communities[] = { 53562306a36Sopenharmony_ci COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), 53662306a36Sopenharmony_ci}; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_cistatic const struct intel_pinctrl_soc_data byt_ncore_soc_data = { 53962306a36Sopenharmony_ci .uid = BYT_NCORE_ACPI_UID, 54062306a36Sopenharmony_ci .pins = byt_ncore_pins, 54162306a36Sopenharmony_ci .npins = ARRAY_SIZE(byt_ncore_pins), 54262306a36Sopenharmony_ci .communities = byt_ncore_communities, 54362306a36Sopenharmony_ci .ncommunities = ARRAY_SIZE(byt_ncore_communities), 54462306a36Sopenharmony_ci}; 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_cistatic const struct intel_pinctrl_soc_data *byt_soc_data[] = { 54762306a36Sopenharmony_ci &byt_score_soc_data, 54862306a36Sopenharmony_ci &byt_sus_soc_data, 54962306a36Sopenharmony_ci &byt_ncore_soc_data, 55062306a36Sopenharmony_ci NULL 55162306a36Sopenharmony_ci}; 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_cistatic DEFINE_RAW_SPINLOCK(byt_lock); 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_cistatic void __iomem *byt_gpio_reg(struct intel_pinctrl *vg, unsigned int offset, 55662306a36Sopenharmony_ci int reg) 55762306a36Sopenharmony_ci{ 55862306a36Sopenharmony_ci struct intel_community *comm = intel_get_community(vg, offset); 55962306a36Sopenharmony_ci u32 reg_offset; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci if (!comm) 56262306a36Sopenharmony_ci return NULL; 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci offset -= comm->pin_base; 56562306a36Sopenharmony_ci switch (reg) { 56662306a36Sopenharmony_ci case BYT_INT_STAT_REG: 56762306a36Sopenharmony_ci reg_offset = (offset / 32) * 4; 56862306a36Sopenharmony_ci break; 56962306a36Sopenharmony_ci case BYT_DEBOUNCE_REG: 57062306a36Sopenharmony_ci reg_offset = 0; 57162306a36Sopenharmony_ci break; 57262306a36Sopenharmony_ci default: 57362306a36Sopenharmony_ci reg_offset = comm->pad_map[offset] * 16; 57462306a36Sopenharmony_ci break; 57562306a36Sopenharmony_ci } 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci return comm->pad_regs + reg_offset + reg; 57862306a36Sopenharmony_ci} 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_cistatic const struct pinctrl_ops byt_pinctrl_ops = { 58162306a36Sopenharmony_ci .get_groups_count = intel_get_groups_count, 58262306a36Sopenharmony_ci .get_group_name = intel_get_group_name, 58362306a36Sopenharmony_ci .get_group_pins = intel_get_group_pins, 58462306a36Sopenharmony_ci}; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_cistatic void byt_set_group_simple_mux(struct intel_pinctrl *vg, 58762306a36Sopenharmony_ci const struct intel_pingroup group, 58862306a36Sopenharmony_ci unsigned int func) 58962306a36Sopenharmony_ci{ 59062306a36Sopenharmony_ci unsigned long flags; 59162306a36Sopenharmony_ci int i; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci for (i = 0; i < group.grp.npins; i++) { 59662306a36Sopenharmony_ci void __iomem *padcfg0; 59762306a36Sopenharmony_ci u32 value; 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG); 60062306a36Sopenharmony_ci if (!padcfg0) { 60162306a36Sopenharmony_ci dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n", 60262306a36Sopenharmony_ci group.grp.name, i); 60362306a36Sopenharmony_ci continue; 60462306a36Sopenharmony_ci } 60562306a36Sopenharmony_ci 60662306a36Sopenharmony_ci value = readl(padcfg0); 60762306a36Sopenharmony_ci value &= ~BYT_PIN_MUX; 60862306a36Sopenharmony_ci value |= func; 60962306a36Sopenharmony_ci writel(value, padcfg0); 61062306a36Sopenharmony_ci } 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 61362306a36Sopenharmony_ci} 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_cistatic void byt_set_group_mixed_mux(struct intel_pinctrl *vg, 61662306a36Sopenharmony_ci const struct intel_pingroup group, 61762306a36Sopenharmony_ci const unsigned int *func) 61862306a36Sopenharmony_ci{ 61962306a36Sopenharmony_ci unsigned long flags; 62062306a36Sopenharmony_ci int i; 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci for (i = 0; i < group.grp.npins; i++) { 62562306a36Sopenharmony_ci void __iomem *padcfg0; 62662306a36Sopenharmony_ci u32 value; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci padcfg0 = byt_gpio_reg(vg, group.grp.pins[i], BYT_CONF0_REG); 62962306a36Sopenharmony_ci if (!padcfg0) { 63062306a36Sopenharmony_ci dev_warn(vg->dev, "Group %s, pin %i not muxed (can't retrieve CONF0)\n", 63162306a36Sopenharmony_ci group.grp.name, i); 63262306a36Sopenharmony_ci continue; 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci value = readl(padcfg0); 63662306a36Sopenharmony_ci value &= ~BYT_PIN_MUX; 63762306a36Sopenharmony_ci value |= func[i]; 63862306a36Sopenharmony_ci writel(value, padcfg0); 63962306a36Sopenharmony_ci } 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 64262306a36Sopenharmony_ci} 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_cistatic int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, 64562306a36Sopenharmony_ci unsigned int group_selector) 64662306a36Sopenharmony_ci{ 64762306a36Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctldev); 64862306a36Sopenharmony_ci const struct intel_function func = vg->soc->functions[func_selector]; 64962306a36Sopenharmony_ci const struct intel_pingroup group = vg->soc->groups[group_selector]; 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci if (group.modes) 65262306a36Sopenharmony_ci byt_set_group_mixed_mux(vg, group, group.modes); 65362306a36Sopenharmony_ci else if (!strcmp(func.func.name, "gpio")) 65462306a36Sopenharmony_ci byt_set_group_simple_mux(vg, group, BYT_DEFAULT_GPIO_MUX); 65562306a36Sopenharmony_ci else 65662306a36Sopenharmony_ci byt_set_group_simple_mux(vg, group, group.mode); 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci return 0; 65962306a36Sopenharmony_ci} 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_cistatic u32 byt_get_gpio_mux(struct intel_pinctrl *vg, unsigned int offset) 66262306a36Sopenharmony_ci{ 66362306a36Sopenharmony_ci /* SCORE pin 92-93 */ 66462306a36Sopenharmony_ci if (!strcmp(vg->soc->uid, BYT_SCORE_ACPI_UID) && 66562306a36Sopenharmony_ci offset >= 92 && offset <= 93) 66662306a36Sopenharmony_ci return BYT_ALTER_GPIO_MUX; 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci /* SUS pin 11-21 */ 66962306a36Sopenharmony_ci if (!strcmp(vg->soc->uid, BYT_SUS_ACPI_UID) && 67062306a36Sopenharmony_ci offset >= 11 && offset <= 21) 67162306a36Sopenharmony_ci return BYT_ALTER_GPIO_MUX; 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci return BYT_DEFAULT_GPIO_MUX; 67462306a36Sopenharmony_ci} 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_cistatic void byt_gpio_clear_triggering(struct intel_pinctrl *vg, unsigned int offset) 67762306a36Sopenharmony_ci{ 67862306a36Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 67962306a36Sopenharmony_ci unsigned long flags; 68062306a36Sopenharmony_ci u32 value; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 68362306a36Sopenharmony_ci value = readl(reg); 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */ 68662306a36Sopenharmony_ci if (!(value & BYT_DIRECT_IRQ_EN)) 68762306a36Sopenharmony_ci value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci writel(value, reg); 69062306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 69162306a36Sopenharmony_ci} 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_cistatic int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, 69462306a36Sopenharmony_ci struct pinctrl_gpio_range *range, 69562306a36Sopenharmony_ci unsigned int offset) 69662306a36Sopenharmony_ci{ 69762306a36Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 69862306a36Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 69962306a36Sopenharmony_ci u32 value, gpio_mux; 70062306a36Sopenharmony_ci unsigned long flags; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_ci /* 70562306a36Sopenharmony_ci * In most cases, func pin mux 000 means GPIO function. 70662306a36Sopenharmony_ci * But, some pins may have func pin mux 001 represents 70762306a36Sopenharmony_ci * GPIO function. 70862306a36Sopenharmony_ci * 70962306a36Sopenharmony_ci * Because there are devices out there where some pins were not 71062306a36Sopenharmony_ci * configured correctly we allow changing the mux value from 71162306a36Sopenharmony_ci * request (but print out warning about that). 71262306a36Sopenharmony_ci */ 71362306a36Sopenharmony_ci value = readl(reg) & BYT_PIN_MUX; 71462306a36Sopenharmony_ci gpio_mux = byt_get_gpio_mux(vg, offset); 71562306a36Sopenharmony_ci if (gpio_mux != value) { 71662306a36Sopenharmony_ci value = readl(reg) & ~BYT_PIN_MUX; 71762306a36Sopenharmony_ci value |= gpio_mux; 71862306a36Sopenharmony_ci writel(value, reg); 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci dev_warn(vg->dev, FW_BUG "Pin %i: forcibly re-configured as GPIO\n", offset); 72162306a36Sopenharmony_ci } 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci pm_runtime_get(vg->dev); 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci return 0; 72862306a36Sopenharmony_ci} 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_cistatic void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev, 73162306a36Sopenharmony_ci struct pinctrl_gpio_range *range, 73262306a36Sopenharmony_ci unsigned int offset) 73362306a36Sopenharmony_ci{ 73462306a36Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci byt_gpio_clear_triggering(vg, offset); 73762306a36Sopenharmony_ci pm_runtime_put(vg->dev); 73862306a36Sopenharmony_ci} 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_cistatic void byt_gpio_direct_irq_check(struct intel_pinctrl *vg, 74162306a36Sopenharmony_ci unsigned int offset) 74262306a36Sopenharmony_ci{ 74362306a36Sopenharmony_ci void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci /* 74662306a36Sopenharmony_ci * Before making any direction modifications, do a check if gpio is set 74762306a36Sopenharmony_ci * for direct IRQ. On Bay Trail, setting GPIO to output does not make 74862306a36Sopenharmony_ci * sense, so let's at least inform the caller before they shoot 74962306a36Sopenharmony_ci * themselves in the foot. 75062306a36Sopenharmony_ci */ 75162306a36Sopenharmony_ci if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) 75262306a36Sopenharmony_ci dev_info_once(vg->dev, 75362306a36Sopenharmony_ci "Potential Error: Pin %i: forcibly set GPIO with DIRECT_IRQ_EN to output\n", 75462306a36Sopenharmony_ci offset); 75562306a36Sopenharmony_ci} 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_cistatic int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, 75862306a36Sopenharmony_ci struct pinctrl_gpio_range *range, 75962306a36Sopenharmony_ci unsigned int offset, 76062306a36Sopenharmony_ci bool input) 76162306a36Sopenharmony_ci{ 76262306a36Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 76362306a36Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 76462306a36Sopenharmony_ci unsigned long flags; 76562306a36Sopenharmony_ci u32 value; 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci value = readl(val_reg); 77062306a36Sopenharmony_ci value &= ~BYT_DIR_MASK; 77162306a36Sopenharmony_ci if (input) 77262306a36Sopenharmony_ci value |= BYT_OUTPUT_EN; 77362306a36Sopenharmony_ci else 77462306a36Sopenharmony_ci byt_gpio_direct_irq_check(vg, offset); 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_ci writel(value, val_reg); 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci return 0; 78162306a36Sopenharmony_ci} 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_cistatic const struct pinmux_ops byt_pinmux_ops = { 78462306a36Sopenharmony_ci .get_functions_count = intel_get_functions_count, 78562306a36Sopenharmony_ci .get_function_name = intel_get_function_name, 78662306a36Sopenharmony_ci .get_function_groups = intel_get_function_groups, 78762306a36Sopenharmony_ci .set_mux = byt_set_mux, 78862306a36Sopenharmony_ci .gpio_request_enable = byt_gpio_request_enable, 78962306a36Sopenharmony_ci .gpio_disable_free = byt_gpio_disable_free, 79062306a36Sopenharmony_ci .gpio_set_direction = byt_gpio_set_direction, 79162306a36Sopenharmony_ci}; 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_cistatic void byt_get_pull_strength(u32 reg, u16 *strength) 79462306a36Sopenharmony_ci{ 79562306a36Sopenharmony_ci switch (reg & BYT_PULL_STR_MASK) { 79662306a36Sopenharmony_ci case BYT_PULL_STR_2K: 79762306a36Sopenharmony_ci *strength = 2000; 79862306a36Sopenharmony_ci break; 79962306a36Sopenharmony_ci case BYT_PULL_STR_10K: 80062306a36Sopenharmony_ci *strength = 10000; 80162306a36Sopenharmony_ci break; 80262306a36Sopenharmony_ci case BYT_PULL_STR_20K: 80362306a36Sopenharmony_ci *strength = 20000; 80462306a36Sopenharmony_ci break; 80562306a36Sopenharmony_ci case BYT_PULL_STR_40K: 80662306a36Sopenharmony_ci *strength = 40000; 80762306a36Sopenharmony_ci break; 80862306a36Sopenharmony_ci } 80962306a36Sopenharmony_ci} 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_cistatic int byt_set_pull_strength(u32 *reg, u16 strength) 81262306a36Sopenharmony_ci{ 81362306a36Sopenharmony_ci *reg &= ~BYT_PULL_STR_MASK; 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci switch (strength) { 81662306a36Sopenharmony_ci case 2000: 81762306a36Sopenharmony_ci *reg |= BYT_PULL_STR_2K; 81862306a36Sopenharmony_ci break; 81962306a36Sopenharmony_ci case 10000: 82062306a36Sopenharmony_ci *reg |= BYT_PULL_STR_10K; 82162306a36Sopenharmony_ci break; 82262306a36Sopenharmony_ci case 20000: 82362306a36Sopenharmony_ci *reg |= BYT_PULL_STR_20K; 82462306a36Sopenharmony_ci break; 82562306a36Sopenharmony_ci case 40000: 82662306a36Sopenharmony_ci *reg |= BYT_PULL_STR_40K; 82762306a36Sopenharmony_ci break; 82862306a36Sopenharmony_ci default: 82962306a36Sopenharmony_ci return -EINVAL; 83062306a36Sopenharmony_ci } 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci return 0; 83362306a36Sopenharmony_ci} 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_cistatic int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset, 83662306a36Sopenharmony_ci unsigned long *config) 83762306a36Sopenharmony_ci{ 83862306a36Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 83962306a36Sopenharmony_ci enum pin_config_param param = pinconf_to_config_param(*config); 84062306a36Sopenharmony_ci void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 84162306a36Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 84262306a36Sopenharmony_ci void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 84362306a36Sopenharmony_ci unsigned long flags; 84462306a36Sopenharmony_ci u32 conf, pull, val, debounce; 84562306a36Sopenharmony_ci u16 arg = 0; 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 84862306a36Sopenharmony_ci conf = readl(conf_reg); 84962306a36Sopenharmony_ci pull = conf & BYT_PULL_ASSIGN_MASK; 85062306a36Sopenharmony_ci val = readl(val_reg); 85162306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci switch (param) { 85462306a36Sopenharmony_ci case PIN_CONFIG_BIAS_DISABLE: 85562306a36Sopenharmony_ci if (pull) 85662306a36Sopenharmony_ci return -EINVAL; 85762306a36Sopenharmony_ci break; 85862306a36Sopenharmony_ci case PIN_CONFIG_BIAS_PULL_DOWN: 85962306a36Sopenharmony_ci /* Pull assignment is only applicable in input mode */ 86062306a36Sopenharmony_ci if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_DOWN) 86162306a36Sopenharmony_ci return -EINVAL; 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci byt_get_pull_strength(conf, &arg); 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_ci break; 86662306a36Sopenharmony_ci case PIN_CONFIG_BIAS_PULL_UP: 86762306a36Sopenharmony_ci /* Pull assignment is only applicable in input mode */ 86862306a36Sopenharmony_ci if ((val & BYT_INPUT_EN) || pull != BYT_PULL_ASSIGN_UP) 86962306a36Sopenharmony_ci return -EINVAL; 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci byt_get_pull_strength(conf, &arg); 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci break; 87462306a36Sopenharmony_ci case PIN_CONFIG_INPUT_DEBOUNCE: 87562306a36Sopenharmony_ci if (!(conf & BYT_DEBOUNCE_EN)) 87662306a36Sopenharmony_ci return -EINVAL; 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 87962306a36Sopenharmony_ci debounce = readl(db_reg); 88062306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { 88362306a36Sopenharmony_ci case BYT_DEBOUNCE_PULSE_375US: 88462306a36Sopenharmony_ci arg = 375; 88562306a36Sopenharmony_ci break; 88662306a36Sopenharmony_ci case BYT_DEBOUNCE_PULSE_750US: 88762306a36Sopenharmony_ci arg = 750; 88862306a36Sopenharmony_ci break; 88962306a36Sopenharmony_ci case BYT_DEBOUNCE_PULSE_1500US: 89062306a36Sopenharmony_ci arg = 1500; 89162306a36Sopenharmony_ci break; 89262306a36Sopenharmony_ci case BYT_DEBOUNCE_PULSE_3MS: 89362306a36Sopenharmony_ci arg = 3000; 89462306a36Sopenharmony_ci break; 89562306a36Sopenharmony_ci case BYT_DEBOUNCE_PULSE_6MS: 89662306a36Sopenharmony_ci arg = 6000; 89762306a36Sopenharmony_ci break; 89862306a36Sopenharmony_ci case BYT_DEBOUNCE_PULSE_12MS: 89962306a36Sopenharmony_ci arg = 12000; 90062306a36Sopenharmony_ci break; 90162306a36Sopenharmony_ci case BYT_DEBOUNCE_PULSE_24MS: 90262306a36Sopenharmony_ci arg = 24000; 90362306a36Sopenharmony_ci break; 90462306a36Sopenharmony_ci default: 90562306a36Sopenharmony_ci return -EINVAL; 90662306a36Sopenharmony_ci } 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci break; 90962306a36Sopenharmony_ci default: 91062306a36Sopenharmony_ci return -ENOTSUPP; 91162306a36Sopenharmony_ci } 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci *config = pinconf_to_config_packed(param, arg); 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci return 0; 91662306a36Sopenharmony_ci} 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_cistatic int byt_pin_config_set(struct pinctrl_dev *pctl_dev, 91962306a36Sopenharmony_ci unsigned int offset, 92062306a36Sopenharmony_ci unsigned long *configs, 92162306a36Sopenharmony_ci unsigned int num_configs) 92262306a36Sopenharmony_ci{ 92362306a36Sopenharmony_ci struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); 92462306a36Sopenharmony_ci void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); 92562306a36Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 92662306a36Sopenharmony_ci void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); 92762306a36Sopenharmony_ci u32 conf, val, db_pulse, debounce; 92862306a36Sopenharmony_ci enum pin_config_param param; 92962306a36Sopenharmony_ci unsigned long flags; 93062306a36Sopenharmony_ci int i, ret = 0; 93162306a36Sopenharmony_ci u32 arg; 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci conf = readl(conf_reg); 93662306a36Sopenharmony_ci val = readl(val_reg); 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_ci for (i = 0; i < num_configs; i++) { 93962306a36Sopenharmony_ci param = pinconf_to_config_param(configs[i]); 94062306a36Sopenharmony_ci arg = pinconf_to_config_argument(configs[i]); 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_ci switch (param) { 94362306a36Sopenharmony_ci case PIN_CONFIG_BIAS_DISABLE: 94462306a36Sopenharmony_ci conf &= ~BYT_PULL_ASSIGN_MASK; 94562306a36Sopenharmony_ci break; 94662306a36Sopenharmony_ci case PIN_CONFIG_BIAS_PULL_DOWN: 94762306a36Sopenharmony_ci /* Set default strength value in case none is given */ 94862306a36Sopenharmony_ci if (arg == 1) 94962306a36Sopenharmony_ci arg = 2000; 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci /* 95262306a36Sopenharmony_ci * Pull assignment is only applicable in input mode. If 95362306a36Sopenharmony_ci * chip is not in input mode, set it and warn about it. 95462306a36Sopenharmony_ci */ 95562306a36Sopenharmony_ci if (val & BYT_INPUT_EN) { 95662306a36Sopenharmony_ci val &= ~BYT_INPUT_EN; 95762306a36Sopenharmony_ci writel(val, val_reg); 95862306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset); 95962306a36Sopenharmony_ci } 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci conf &= ~BYT_PULL_ASSIGN_MASK; 96262306a36Sopenharmony_ci conf |= BYT_PULL_ASSIGN_DOWN; 96362306a36Sopenharmony_ci ret = byt_set_pull_strength(&conf, arg); 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci break; 96662306a36Sopenharmony_ci case PIN_CONFIG_BIAS_PULL_UP: 96762306a36Sopenharmony_ci /* Set default strength value in case none is given */ 96862306a36Sopenharmony_ci if (arg == 1) 96962306a36Sopenharmony_ci arg = 2000; 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci /* 97262306a36Sopenharmony_ci * Pull assignment is only applicable in input mode. If 97362306a36Sopenharmony_ci * chip is not in input mode, set it and warn about it. 97462306a36Sopenharmony_ci */ 97562306a36Sopenharmony_ci if (val & BYT_INPUT_EN) { 97662306a36Sopenharmony_ci val &= ~BYT_INPUT_EN; 97762306a36Sopenharmony_ci writel(val, val_reg); 97862306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: forcibly set to input mode\n", offset); 97962306a36Sopenharmony_ci } 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_ci conf &= ~BYT_PULL_ASSIGN_MASK; 98262306a36Sopenharmony_ci conf |= BYT_PULL_ASSIGN_UP; 98362306a36Sopenharmony_ci ret = byt_set_pull_strength(&conf, arg); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci break; 98662306a36Sopenharmony_ci case PIN_CONFIG_INPUT_DEBOUNCE: 98762306a36Sopenharmony_ci if (arg) { 98862306a36Sopenharmony_ci conf |= BYT_DEBOUNCE_EN; 98962306a36Sopenharmony_ci } else { 99062306a36Sopenharmony_ci conf &= ~BYT_DEBOUNCE_EN; 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci /* 99362306a36Sopenharmony_ci * No need to update the pulse value. 99462306a36Sopenharmony_ci * Debounce is going to be disabled. 99562306a36Sopenharmony_ci */ 99662306a36Sopenharmony_ci break; 99762306a36Sopenharmony_ci } 99862306a36Sopenharmony_ci 99962306a36Sopenharmony_ci switch (arg) { 100062306a36Sopenharmony_ci case 375: 100162306a36Sopenharmony_ci db_pulse = BYT_DEBOUNCE_PULSE_375US; 100262306a36Sopenharmony_ci break; 100362306a36Sopenharmony_ci case 750: 100462306a36Sopenharmony_ci db_pulse = BYT_DEBOUNCE_PULSE_750US; 100562306a36Sopenharmony_ci break; 100662306a36Sopenharmony_ci case 1500: 100762306a36Sopenharmony_ci db_pulse = BYT_DEBOUNCE_PULSE_1500US; 100862306a36Sopenharmony_ci break; 100962306a36Sopenharmony_ci case 3000: 101062306a36Sopenharmony_ci db_pulse = BYT_DEBOUNCE_PULSE_3MS; 101162306a36Sopenharmony_ci break; 101262306a36Sopenharmony_ci case 6000: 101362306a36Sopenharmony_ci db_pulse = BYT_DEBOUNCE_PULSE_6MS; 101462306a36Sopenharmony_ci break; 101562306a36Sopenharmony_ci case 12000: 101662306a36Sopenharmony_ci db_pulse = BYT_DEBOUNCE_PULSE_12MS; 101762306a36Sopenharmony_ci break; 101862306a36Sopenharmony_ci case 24000: 101962306a36Sopenharmony_ci db_pulse = BYT_DEBOUNCE_PULSE_24MS; 102062306a36Sopenharmony_ci break; 102162306a36Sopenharmony_ci default: 102262306a36Sopenharmony_ci if (arg) 102362306a36Sopenharmony_ci ret = -EINVAL; 102462306a36Sopenharmony_ci break; 102562306a36Sopenharmony_ci } 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci if (ret) 102862306a36Sopenharmony_ci break; 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_ci debounce = readl(db_reg); 103162306a36Sopenharmony_ci debounce = (debounce & ~BYT_DEBOUNCE_PULSE_MASK) | db_pulse; 103262306a36Sopenharmony_ci writel(debounce, db_reg); 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci break; 103562306a36Sopenharmony_ci default: 103662306a36Sopenharmony_ci ret = -ENOTSUPP; 103762306a36Sopenharmony_ci } 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_ci if (ret) 104062306a36Sopenharmony_ci break; 104162306a36Sopenharmony_ci } 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci if (!ret) 104462306a36Sopenharmony_ci writel(conf, conf_reg); 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_ci return ret; 104962306a36Sopenharmony_ci} 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_cistatic const struct pinconf_ops byt_pinconf_ops = { 105262306a36Sopenharmony_ci .is_generic = true, 105362306a36Sopenharmony_ci .pin_config_get = byt_pin_config_get, 105462306a36Sopenharmony_ci .pin_config_set = byt_pin_config_set, 105562306a36Sopenharmony_ci}; 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_cistatic const struct pinctrl_desc byt_pinctrl_desc = { 105862306a36Sopenharmony_ci .pctlops = &byt_pinctrl_ops, 105962306a36Sopenharmony_ci .pmxops = &byt_pinmux_ops, 106062306a36Sopenharmony_ci .confops = &byt_pinconf_ops, 106162306a36Sopenharmony_ci .owner = THIS_MODULE, 106262306a36Sopenharmony_ci}; 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_cistatic int byt_gpio_get(struct gpio_chip *chip, unsigned int offset) 106562306a36Sopenharmony_ci{ 106662306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 106762306a36Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 106862306a36Sopenharmony_ci unsigned long flags; 106962306a36Sopenharmony_ci u32 val; 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 107262306a36Sopenharmony_ci val = readl(reg); 107362306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci return !!(val & BYT_LEVEL); 107662306a36Sopenharmony_ci} 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_cistatic void byt_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 107962306a36Sopenharmony_ci{ 108062306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 108162306a36Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 108262306a36Sopenharmony_ci unsigned long flags; 108362306a36Sopenharmony_ci u32 old_val; 108462306a36Sopenharmony_ci 108562306a36Sopenharmony_ci if (!reg) 108662306a36Sopenharmony_ci return; 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 108962306a36Sopenharmony_ci old_val = readl(reg); 109062306a36Sopenharmony_ci if (value) 109162306a36Sopenharmony_ci writel(old_val | BYT_LEVEL, reg); 109262306a36Sopenharmony_ci else 109362306a36Sopenharmony_ci writel(old_val & ~BYT_LEVEL, reg); 109462306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 109562306a36Sopenharmony_ci} 109662306a36Sopenharmony_ci 109762306a36Sopenharmony_cistatic int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 109862306a36Sopenharmony_ci{ 109962306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 110062306a36Sopenharmony_ci void __iomem *reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 110162306a36Sopenharmony_ci unsigned long flags; 110262306a36Sopenharmony_ci u32 value; 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ci if (!reg) 110562306a36Sopenharmony_ci return -EINVAL; 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 110862306a36Sopenharmony_ci value = readl(reg); 110962306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 111062306a36Sopenharmony_ci 111162306a36Sopenharmony_ci if (!(value & BYT_OUTPUT_EN)) 111262306a36Sopenharmony_ci return GPIO_LINE_DIRECTION_OUT; 111362306a36Sopenharmony_ci if (!(value & BYT_INPUT_EN)) 111462306a36Sopenharmony_ci return GPIO_LINE_DIRECTION_IN; 111562306a36Sopenharmony_ci 111662306a36Sopenharmony_ci return -EINVAL; 111762306a36Sopenharmony_ci} 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_cistatic int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 112062306a36Sopenharmony_ci{ 112162306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 112262306a36Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 112362306a36Sopenharmony_ci unsigned long flags; 112462306a36Sopenharmony_ci u32 reg; 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci reg = readl(val_reg); 112962306a36Sopenharmony_ci reg &= ~BYT_DIR_MASK; 113062306a36Sopenharmony_ci reg |= BYT_OUTPUT_EN; 113162306a36Sopenharmony_ci writel(reg, val_reg); 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 113462306a36Sopenharmony_ci return 0; 113562306a36Sopenharmony_ci} 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci/* 113862306a36Sopenharmony_ci * Note despite the temptation this MUST NOT be converted into a call to 113962306a36Sopenharmony_ci * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this 114062306a36Sopenharmony_ci * MUST be done as a single BYT_VAL_REG register write. 114162306a36Sopenharmony_ci * See the commit message of the commit adding this comment for details. 114262306a36Sopenharmony_ci */ 114362306a36Sopenharmony_cistatic int byt_gpio_direction_output(struct gpio_chip *chip, 114462306a36Sopenharmony_ci unsigned int offset, int value) 114562306a36Sopenharmony_ci{ 114662306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 114762306a36Sopenharmony_ci void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); 114862306a36Sopenharmony_ci unsigned long flags; 114962306a36Sopenharmony_ci u32 reg; 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_ci byt_gpio_direct_irq_check(vg, offset); 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci reg = readl(val_reg); 115662306a36Sopenharmony_ci reg &= ~BYT_DIR_MASK; 115762306a36Sopenharmony_ci if (value) 115862306a36Sopenharmony_ci reg |= BYT_LEVEL; 115962306a36Sopenharmony_ci else 116062306a36Sopenharmony_ci reg &= ~BYT_LEVEL; 116162306a36Sopenharmony_ci 116262306a36Sopenharmony_ci writel(reg, val_reg); 116362306a36Sopenharmony_ci 116462306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 116562306a36Sopenharmony_ci return 0; 116662306a36Sopenharmony_ci} 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_cistatic void byt_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 116962306a36Sopenharmony_ci{ 117062306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 117162306a36Sopenharmony_ci int i; 117262306a36Sopenharmony_ci u32 conf0, val; 117362306a36Sopenharmony_ci 117462306a36Sopenharmony_ci for (i = 0; i < vg->soc->npins; i++) { 117562306a36Sopenharmony_ci const struct intel_community *comm; 117662306a36Sopenharmony_ci void __iomem *conf_reg, *val_reg; 117762306a36Sopenharmony_ci const char *pull_str = NULL; 117862306a36Sopenharmony_ci const char *pull = NULL; 117962306a36Sopenharmony_ci unsigned long flags; 118062306a36Sopenharmony_ci const char *label; 118162306a36Sopenharmony_ci unsigned int pin; 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci pin = vg->soc->pins[i].number; 118462306a36Sopenharmony_ci 118562306a36Sopenharmony_ci conf_reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 118662306a36Sopenharmony_ci if (!conf_reg) { 118762306a36Sopenharmony_ci seq_printf(s, "Pin %i: can't retrieve CONF0\n", pin); 118862306a36Sopenharmony_ci continue; 118962306a36Sopenharmony_ci } 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci val_reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 119262306a36Sopenharmony_ci if (!val_reg) { 119362306a36Sopenharmony_ci seq_printf(s, "Pin %i: can't retrieve VAL\n", pin); 119462306a36Sopenharmony_ci continue; 119562306a36Sopenharmony_ci } 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 119862306a36Sopenharmony_ci conf0 = readl(conf_reg); 119962306a36Sopenharmony_ci val = readl(val_reg); 120062306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci comm = intel_get_community(vg, pin); 120362306a36Sopenharmony_ci if (!comm) { 120462306a36Sopenharmony_ci seq_printf(s, "Pin %i: can't retrieve community\n", pin); 120562306a36Sopenharmony_ci continue; 120662306a36Sopenharmony_ci } 120762306a36Sopenharmony_ci label = gpiochip_is_requested(chip, i); 120862306a36Sopenharmony_ci if (!label) 120962306a36Sopenharmony_ci label = "Unrequested"; 121062306a36Sopenharmony_ci 121162306a36Sopenharmony_ci switch (conf0 & BYT_PULL_ASSIGN_MASK) { 121262306a36Sopenharmony_ci case BYT_PULL_ASSIGN_UP: 121362306a36Sopenharmony_ci pull = "up"; 121462306a36Sopenharmony_ci break; 121562306a36Sopenharmony_ci case BYT_PULL_ASSIGN_DOWN: 121662306a36Sopenharmony_ci pull = "down"; 121762306a36Sopenharmony_ci break; 121862306a36Sopenharmony_ci } 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_ci switch (conf0 & BYT_PULL_STR_MASK) { 122162306a36Sopenharmony_ci case BYT_PULL_STR_2K: 122262306a36Sopenharmony_ci pull_str = "2k"; 122362306a36Sopenharmony_ci break; 122462306a36Sopenharmony_ci case BYT_PULL_STR_10K: 122562306a36Sopenharmony_ci pull_str = "10k"; 122662306a36Sopenharmony_ci break; 122762306a36Sopenharmony_ci case BYT_PULL_STR_20K: 122862306a36Sopenharmony_ci pull_str = "20k"; 122962306a36Sopenharmony_ci break; 123062306a36Sopenharmony_ci case BYT_PULL_STR_40K: 123162306a36Sopenharmony_ci pull_str = "40k"; 123262306a36Sopenharmony_ci break; 123362306a36Sopenharmony_ci } 123462306a36Sopenharmony_ci 123562306a36Sopenharmony_ci seq_printf(s, 123662306a36Sopenharmony_ci " gpio-%-3d (%-20.20s) %s %s %s pad-%-3d offset:0x%03x mux:%d %s%s%s", 123762306a36Sopenharmony_ci pin, 123862306a36Sopenharmony_ci label, 123962306a36Sopenharmony_ci val & BYT_INPUT_EN ? " " : "in", 124062306a36Sopenharmony_ci val & BYT_OUTPUT_EN ? " " : "out", 124162306a36Sopenharmony_ci str_hi_lo(val & BYT_LEVEL), 124262306a36Sopenharmony_ci comm->pad_map[i], comm->pad_map[i] * 16, 124362306a36Sopenharmony_ci conf0 & 0x7, 124462306a36Sopenharmony_ci conf0 & BYT_TRIG_NEG ? " fall" : " ", 124562306a36Sopenharmony_ci conf0 & BYT_TRIG_POS ? " rise" : " ", 124662306a36Sopenharmony_ci conf0 & BYT_TRIG_LVL ? " level" : " "); 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci if (pull && pull_str) 124962306a36Sopenharmony_ci seq_printf(s, " %-4s %-3s", pull, pull_str); 125062306a36Sopenharmony_ci else 125162306a36Sopenharmony_ci seq_puts(s, " "); 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_ci if (conf0 & BYT_IODEN) 125462306a36Sopenharmony_ci seq_puts(s, " open-drain"); 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_ci seq_puts(s, "\n"); 125762306a36Sopenharmony_ci } 125862306a36Sopenharmony_ci} 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_cistatic const struct gpio_chip byt_gpio_chip = { 126162306a36Sopenharmony_ci .owner = THIS_MODULE, 126262306a36Sopenharmony_ci .request = gpiochip_generic_request, 126362306a36Sopenharmony_ci .free = gpiochip_generic_free, 126462306a36Sopenharmony_ci .get_direction = byt_gpio_get_direction, 126562306a36Sopenharmony_ci .direction_input = byt_gpio_direction_input, 126662306a36Sopenharmony_ci .direction_output = byt_gpio_direction_output, 126762306a36Sopenharmony_ci .get = byt_gpio_get, 126862306a36Sopenharmony_ci .set = byt_gpio_set, 126962306a36Sopenharmony_ci .set_config = gpiochip_generic_config, 127062306a36Sopenharmony_ci .dbg_show = byt_gpio_dbg_show, 127162306a36Sopenharmony_ci}; 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_cistatic void byt_irq_ack(struct irq_data *d) 127462306a36Sopenharmony_ci{ 127562306a36Sopenharmony_ci struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 127662306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(gc); 127762306a36Sopenharmony_ci irq_hw_number_t hwirq = irqd_to_hwirq(d); 127862306a36Sopenharmony_ci void __iomem *reg; 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci reg = byt_gpio_reg(vg, hwirq, BYT_INT_STAT_REG); 128162306a36Sopenharmony_ci if (!reg) 128262306a36Sopenharmony_ci return; 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci raw_spin_lock(&byt_lock); 128562306a36Sopenharmony_ci writel(BIT(hwirq % 32), reg); 128662306a36Sopenharmony_ci raw_spin_unlock(&byt_lock); 128762306a36Sopenharmony_ci} 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_cistatic void byt_irq_mask(struct irq_data *d) 129062306a36Sopenharmony_ci{ 129162306a36Sopenharmony_ci struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 129262306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(gc); 129362306a36Sopenharmony_ci irq_hw_number_t hwirq = irqd_to_hwirq(d); 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci byt_gpio_clear_triggering(vg, hwirq); 129662306a36Sopenharmony_ci gpiochip_disable_irq(gc, hwirq); 129762306a36Sopenharmony_ci} 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_cistatic void byt_irq_unmask(struct irq_data *d) 130062306a36Sopenharmony_ci{ 130162306a36Sopenharmony_ci struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 130262306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(gc); 130362306a36Sopenharmony_ci irq_hw_number_t hwirq = irqd_to_hwirq(d); 130462306a36Sopenharmony_ci unsigned long flags; 130562306a36Sopenharmony_ci void __iomem *reg; 130662306a36Sopenharmony_ci u32 value; 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci gpiochip_enable_irq(gc, hwirq); 130962306a36Sopenharmony_ci 131062306a36Sopenharmony_ci reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG); 131162306a36Sopenharmony_ci if (!reg) 131262306a36Sopenharmony_ci return; 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 131562306a36Sopenharmony_ci value = readl(reg); 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci switch (irqd_get_trigger_type(d)) { 131862306a36Sopenharmony_ci case IRQ_TYPE_LEVEL_HIGH: 131962306a36Sopenharmony_ci value |= BYT_TRIG_LVL; 132062306a36Sopenharmony_ci fallthrough; 132162306a36Sopenharmony_ci case IRQ_TYPE_EDGE_RISING: 132262306a36Sopenharmony_ci value |= BYT_TRIG_POS; 132362306a36Sopenharmony_ci break; 132462306a36Sopenharmony_ci case IRQ_TYPE_LEVEL_LOW: 132562306a36Sopenharmony_ci value |= BYT_TRIG_LVL; 132662306a36Sopenharmony_ci fallthrough; 132762306a36Sopenharmony_ci case IRQ_TYPE_EDGE_FALLING: 132862306a36Sopenharmony_ci value |= BYT_TRIG_NEG; 132962306a36Sopenharmony_ci break; 133062306a36Sopenharmony_ci case IRQ_TYPE_EDGE_BOTH: 133162306a36Sopenharmony_ci value |= (BYT_TRIG_NEG | BYT_TRIG_POS); 133262306a36Sopenharmony_ci break; 133362306a36Sopenharmony_ci } 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci writel(value, reg); 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 133862306a36Sopenharmony_ci} 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_cistatic int byt_irq_type(struct irq_data *d, unsigned int type) 134162306a36Sopenharmony_ci{ 134262306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(irq_data_get_irq_chip_data(d)); 134362306a36Sopenharmony_ci irq_hw_number_t hwirq = irqd_to_hwirq(d); 134462306a36Sopenharmony_ci u32 value; 134562306a36Sopenharmony_ci unsigned long flags; 134662306a36Sopenharmony_ci void __iomem *reg; 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci reg = byt_gpio_reg(vg, hwirq, BYT_CONF0_REG); 134962306a36Sopenharmony_ci if (!reg) 135062306a36Sopenharmony_ci return -EINVAL; 135162306a36Sopenharmony_ci 135262306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 135362306a36Sopenharmony_ci value = readl(reg); 135462306a36Sopenharmony_ci 135562306a36Sopenharmony_ci WARN(value & BYT_DIRECT_IRQ_EN, 135662306a36Sopenharmony_ci "Bad pad config for IO mode, force DIRECT_IRQ_EN bit clearing"); 135762306a36Sopenharmony_ci 135862306a36Sopenharmony_ci /* For level trigges the BYT_TRIG_POS and BYT_TRIG_NEG bits 135962306a36Sopenharmony_ci * are used to indicate high and low level triggering 136062306a36Sopenharmony_ci */ 136162306a36Sopenharmony_ci value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | BYT_TRIG_NEG | 136262306a36Sopenharmony_ci BYT_TRIG_LVL); 136362306a36Sopenharmony_ci /* Enable glitch filtering */ 136462306a36Sopenharmony_ci value |= BYT_GLITCH_FILTER_EN | BYT_GLITCH_F_SLOW_CLK | 136562306a36Sopenharmony_ci BYT_GLITCH_F_FAST_CLK; 136662306a36Sopenharmony_ci 136762306a36Sopenharmony_ci writel(value, reg); 136862306a36Sopenharmony_ci 136962306a36Sopenharmony_ci if (type & IRQ_TYPE_EDGE_BOTH) 137062306a36Sopenharmony_ci irq_set_handler_locked(d, handle_edge_irq); 137162306a36Sopenharmony_ci else if (type & IRQ_TYPE_LEVEL_MASK) 137262306a36Sopenharmony_ci irq_set_handler_locked(d, handle_level_irq); 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 137562306a36Sopenharmony_ci 137662306a36Sopenharmony_ci return 0; 137762306a36Sopenharmony_ci} 137862306a36Sopenharmony_ci 137962306a36Sopenharmony_cistatic const struct irq_chip byt_gpio_irq_chip = { 138062306a36Sopenharmony_ci .name = "BYT-GPIO", 138162306a36Sopenharmony_ci .irq_ack = byt_irq_ack, 138262306a36Sopenharmony_ci .irq_mask = byt_irq_mask, 138362306a36Sopenharmony_ci .irq_unmask = byt_irq_unmask, 138462306a36Sopenharmony_ci .irq_set_type = byt_irq_type, 138562306a36Sopenharmony_ci .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_SET_TYPE_MASKED | IRQCHIP_IMMUTABLE, 138662306a36Sopenharmony_ci GPIOCHIP_IRQ_RESOURCE_HELPERS, 138762306a36Sopenharmony_ci}; 138862306a36Sopenharmony_ci 138962306a36Sopenharmony_cistatic void byt_gpio_irq_handler(struct irq_desc *desc) 139062306a36Sopenharmony_ci{ 139162306a36Sopenharmony_ci struct irq_data *data = irq_desc_get_irq_data(desc); 139262306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(irq_desc_get_handler_data(desc)); 139362306a36Sopenharmony_ci struct irq_chip *chip = irq_data_get_irq_chip(data); 139462306a36Sopenharmony_ci u32 base, pin; 139562306a36Sopenharmony_ci void __iomem *reg; 139662306a36Sopenharmony_ci unsigned long pending; 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci /* check from GPIO controller which pin triggered the interrupt */ 139962306a36Sopenharmony_ci for (base = 0; base < vg->chip.ngpio; base += 32) { 140062306a36Sopenharmony_ci reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 140162306a36Sopenharmony_ci 140262306a36Sopenharmony_ci if (!reg) { 140362306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base); 140462306a36Sopenharmony_ci continue; 140562306a36Sopenharmony_ci } 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci raw_spin_lock(&byt_lock); 140862306a36Sopenharmony_ci pending = readl(reg); 140962306a36Sopenharmony_ci raw_spin_unlock(&byt_lock); 141062306a36Sopenharmony_ci for_each_set_bit(pin, &pending, 32) 141162306a36Sopenharmony_ci generic_handle_domain_irq(vg->chip.irq.domain, base + pin); 141262306a36Sopenharmony_ci } 141362306a36Sopenharmony_ci chip->irq_eoi(data); 141462306a36Sopenharmony_ci} 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_cistatic bool byt_direct_irq_sanity_check(struct intel_pinctrl *vg, int pin, u32 conf0) 141762306a36Sopenharmony_ci{ 141862306a36Sopenharmony_ci int direct_irq, ioapic_direct_irq_base; 141962306a36Sopenharmony_ci u8 *match, direct_irq_mux[16]; 142062306a36Sopenharmony_ci u32 trig; 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_ci memcpy_fromio(direct_irq_mux, vg->communities->pad_regs + BYT_DIRECT_IRQ_REG, 142362306a36Sopenharmony_ci sizeof(direct_irq_mux)); 142462306a36Sopenharmony_ci match = memchr(direct_irq_mux, pin, sizeof(direct_irq_mux)); 142562306a36Sopenharmony_ci if (!match) { 142662306a36Sopenharmony_ci dev_warn(vg->dev, FW_BUG "Pin %i: DIRECT_IRQ_EN set but no IRQ assigned, clearing\n", pin); 142762306a36Sopenharmony_ci return false; 142862306a36Sopenharmony_ci } 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci direct_irq = match - direct_irq_mux; 143162306a36Sopenharmony_ci /* Base IO-APIC pin numbers come from atom-e3800-family-datasheet.pdf */ 143262306a36Sopenharmony_ci ioapic_direct_irq_base = (vg->communities->npins == BYT_NGPIO_SCORE) ? 51 : 67; 143362306a36Sopenharmony_ci dev_dbg(vg->dev, "Pin %i: uses direct IRQ %d (IO-APIC %d)\n", pin, 143462306a36Sopenharmony_ci direct_irq, direct_irq + ioapic_direct_irq_base); 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_ci /* 143762306a36Sopenharmony_ci * Testing has shown that the way direct IRQs work is that the combination of the 143862306a36Sopenharmony_ci * direct-irq-en flag and the direct IRQ mux connect the output of the GPIO's IRQ 143962306a36Sopenharmony_ci * trigger block, which normally sets the status flag in the IRQ status reg at 144062306a36Sopenharmony_ci * 0x800, to one of the IO-APIC pins according to the mux registers. 144162306a36Sopenharmony_ci * 144262306a36Sopenharmony_ci * This means that: 144362306a36Sopenharmony_ci * 1. The TRIG_MASK bits must be set to configure the GPIO's IRQ trigger block 144462306a36Sopenharmony_ci * 2. The TRIG_LVL bit *must* be set, so that the GPIO's input value is directly 144562306a36Sopenharmony_ci * passed (1:1 or inverted) to the IO-APIC pin, if TRIG_LVL is not set, 144662306a36Sopenharmony_ci * selecting edge mode operation then on the first edge the IO-APIC pin goes 144762306a36Sopenharmony_ci * high, but since no write-to-clear write will be done to the IRQ status reg 144862306a36Sopenharmony_ci * at 0x800, the detected edge condition will never get cleared. 144962306a36Sopenharmony_ci */ 145062306a36Sopenharmony_ci trig = conf0 & BYT_TRIG_MASK; 145162306a36Sopenharmony_ci if (trig != (BYT_TRIG_POS | BYT_TRIG_LVL) && 145262306a36Sopenharmony_ci trig != (BYT_TRIG_NEG | BYT_TRIG_LVL)) { 145362306a36Sopenharmony_ci dev_warn(vg->dev, 145462306a36Sopenharmony_ci FW_BUG "Pin %i: DIRECT_IRQ_EN set without trigger (CONF0: %#08x), clearing\n", 145562306a36Sopenharmony_ci pin, conf0); 145662306a36Sopenharmony_ci return false; 145762306a36Sopenharmony_ci } 145862306a36Sopenharmony_ci 145962306a36Sopenharmony_ci return true; 146062306a36Sopenharmony_ci} 146162306a36Sopenharmony_ci 146262306a36Sopenharmony_cistatic void byt_init_irq_valid_mask(struct gpio_chip *chip, 146362306a36Sopenharmony_ci unsigned long *valid_mask, 146462306a36Sopenharmony_ci unsigned int ngpios) 146562306a36Sopenharmony_ci{ 146662306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 146762306a36Sopenharmony_ci void __iomem *reg; 146862306a36Sopenharmony_ci u32 value; 146962306a36Sopenharmony_ci int i; 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci /* 147262306a36Sopenharmony_ci * Clear interrupt triggers for all pins that are GPIOs and 147362306a36Sopenharmony_ci * do not use direct IRQ mode. This will prevent spurious 147462306a36Sopenharmony_ci * interrupts from misconfigured pins. 147562306a36Sopenharmony_ci */ 147662306a36Sopenharmony_ci for (i = 0; i < vg->soc->npins; i++) { 147762306a36Sopenharmony_ci unsigned int pin = vg->soc->pins[i].number; 147862306a36Sopenharmony_ci 147962306a36Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 148062306a36Sopenharmony_ci if (!reg) { 148162306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: could not retrieve CONF0\n", i); 148262306a36Sopenharmony_ci continue; 148362306a36Sopenharmony_ci } 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci value = readl(reg); 148662306a36Sopenharmony_ci if (value & BYT_DIRECT_IRQ_EN) { 148762306a36Sopenharmony_ci if (byt_direct_irq_sanity_check(vg, i, value)) { 148862306a36Sopenharmony_ci clear_bit(i, valid_mask); 148962306a36Sopenharmony_ci } else { 149062306a36Sopenharmony_ci value &= ~(BYT_DIRECT_IRQ_EN | BYT_TRIG_POS | 149162306a36Sopenharmony_ci BYT_TRIG_NEG | BYT_TRIG_LVL); 149262306a36Sopenharmony_ci writel(value, reg); 149362306a36Sopenharmony_ci } 149462306a36Sopenharmony_ci } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { 149562306a36Sopenharmony_ci byt_gpio_clear_triggering(vg, i); 149662306a36Sopenharmony_ci dev_dbg(vg->dev, "disabling GPIO %d\n", i); 149762306a36Sopenharmony_ci } 149862306a36Sopenharmony_ci } 149962306a36Sopenharmony_ci} 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_cistatic int byt_gpio_irq_init_hw(struct gpio_chip *chip) 150262306a36Sopenharmony_ci{ 150362306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 150462306a36Sopenharmony_ci void __iomem *reg; 150562306a36Sopenharmony_ci u32 base, value; 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ci /* clear interrupt status trigger registers */ 150862306a36Sopenharmony_ci for (base = 0; base < vg->soc->npins; base += 32) { 150962306a36Sopenharmony_ci reg = byt_gpio_reg(vg, base, BYT_INT_STAT_REG); 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci if (!reg) { 151262306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: can't retrieve INT_STAT%u\n", base / 32, base); 151362306a36Sopenharmony_ci continue; 151462306a36Sopenharmony_ci } 151562306a36Sopenharmony_ci 151662306a36Sopenharmony_ci writel(0xffffffff, reg); 151762306a36Sopenharmony_ci /* make sure trigger bits are cleared, if not then a pin 151862306a36Sopenharmony_ci might be misconfigured in bios */ 151962306a36Sopenharmony_ci value = readl(reg); 152062306a36Sopenharmony_ci if (value) 152162306a36Sopenharmony_ci dev_err(vg->dev, 152262306a36Sopenharmony_ci "GPIO interrupt error, pins misconfigured. INT_STAT%u: %#08x\n", 152362306a36Sopenharmony_ci base / 32, value); 152462306a36Sopenharmony_ci } 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci return 0; 152762306a36Sopenharmony_ci} 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_cistatic int byt_gpio_add_pin_ranges(struct gpio_chip *chip) 153062306a36Sopenharmony_ci{ 153162306a36Sopenharmony_ci struct intel_pinctrl *vg = gpiochip_get_data(chip); 153262306a36Sopenharmony_ci struct device *dev = vg->dev; 153362306a36Sopenharmony_ci int ret; 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ci ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins); 153662306a36Sopenharmony_ci if (ret) 153762306a36Sopenharmony_ci dev_err(dev, "failed to add GPIO pin range\n"); 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci return ret; 154062306a36Sopenharmony_ci} 154162306a36Sopenharmony_ci 154262306a36Sopenharmony_cistatic int byt_gpio_probe(struct intel_pinctrl *vg) 154362306a36Sopenharmony_ci{ 154462306a36Sopenharmony_ci struct platform_device *pdev = to_platform_device(vg->dev); 154562306a36Sopenharmony_ci struct gpio_chip *gc; 154662306a36Sopenharmony_ci int irq, ret; 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci /* Set up gpio chip */ 154962306a36Sopenharmony_ci vg->chip = byt_gpio_chip; 155062306a36Sopenharmony_ci gc = &vg->chip; 155162306a36Sopenharmony_ci gc->label = dev_name(vg->dev); 155262306a36Sopenharmony_ci gc->base = -1; 155362306a36Sopenharmony_ci gc->can_sleep = false; 155462306a36Sopenharmony_ci gc->add_pin_ranges = byt_gpio_add_pin_ranges; 155562306a36Sopenharmony_ci gc->parent = vg->dev; 155662306a36Sopenharmony_ci gc->ngpio = vg->soc->npins; 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 155962306a36Sopenharmony_ci vg->context.pads = devm_kcalloc(vg->dev, gc->ngpio, sizeof(*vg->context.pads), 156062306a36Sopenharmony_ci GFP_KERNEL); 156162306a36Sopenharmony_ci if (!vg->context.pads) 156262306a36Sopenharmony_ci return -ENOMEM; 156362306a36Sopenharmony_ci#endif 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ci /* set up interrupts */ 156662306a36Sopenharmony_ci irq = platform_get_irq_optional(pdev, 0); 156762306a36Sopenharmony_ci if (irq > 0) { 156862306a36Sopenharmony_ci struct gpio_irq_chip *girq; 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_ci girq = &gc->irq; 157162306a36Sopenharmony_ci gpio_irq_chip_set_chip(girq, &byt_gpio_irq_chip); 157262306a36Sopenharmony_ci girq->init_hw = byt_gpio_irq_init_hw; 157362306a36Sopenharmony_ci girq->init_valid_mask = byt_init_irq_valid_mask; 157462306a36Sopenharmony_ci girq->parent_handler = byt_gpio_irq_handler; 157562306a36Sopenharmony_ci girq->num_parents = 1; 157662306a36Sopenharmony_ci girq->parents = devm_kcalloc(vg->dev, girq->num_parents, 157762306a36Sopenharmony_ci sizeof(*girq->parents), GFP_KERNEL); 157862306a36Sopenharmony_ci if (!girq->parents) 157962306a36Sopenharmony_ci return -ENOMEM; 158062306a36Sopenharmony_ci girq->parents[0] = irq; 158162306a36Sopenharmony_ci girq->default_type = IRQ_TYPE_NONE; 158262306a36Sopenharmony_ci girq->handler = handle_bad_irq; 158362306a36Sopenharmony_ci } 158462306a36Sopenharmony_ci 158562306a36Sopenharmony_ci ret = devm_gpiochip_add_data(vg->dev, gc, vg); 158662306a36Sopenharmony_ci if (ret) { 158762306a36Sopenharmony_ci dev_err(vg->dev, "failed adding byt-gpio chip\n"); 158862306a36Sopenharmony_ci return ret; 158962306a36Sopenharmony_ci } 159062306a36Sopenharmony_ci 159162306a36Sopenharmony_ci return ret; 159262306a36Sopenharmony_ci} 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_cistatic int byt_set_soc_data(struct intel_pinctrl *vg, 159562306a36Sopenharmony_ci const struct intel_pinctrl_soc_data *soc) 159662306a36Sopenharmony_ci{ 159762306a36Sopenharmony_ci struct platform_device *pdev = to_platform_device(vg->dev); 159862306a36Sopenharmony_ci int i; 159962306a36Sopenharmony_ci 160062306a36Sopenharmony_ci vg->soc = soc; 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci vg->ncommunities = vg->soc->ncommunities; 160362306a36Sopenharmony_ci vg->communities = devm_kcalloc(vg->dev, vg->ncommunities, 160462306a36Sopenharmony_ci sizeof(*vg->communities), GFP_KERNEL); 160562306a36Sopenharmony_ci if (!vg->communities) 160662306a36Sopenharmony_ci return -ENOMEM; 160762306a36Sopenharmony_ci 160862306a36Sopenharmony_ci for (i = 0; i < vg->soc->ncommunities; i++) { 160962306a36Sopenharmony_ci struct intel_community *comm = vg->communities + i; 161062306a36Sopenharmony_ci 161162306a36Sopenharmony_ci *comm = vg->soc->communities[i]; 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_ci comm->pad_regs = devm_platform_ioremap_resource(pdev, 0); 161462306a36Sopenharmony_ci if (IS_ERR(comm->pad_regs)) 161562306a36Sopenharmony_ci return PTR_ERR(comm->pad_regs); 161662306a36Sopenharmony_ci } 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci return 0; 161962306a36Sopenharmony_ci} 162062306a36Sopenharmony_ci 162162306a36Sopenharmony_cistatic const struct acpi_device_id byt_gpio_acpi_match[] = { 162262306a36Sopenharmony_ci { "INT33B2", (kernel_ulong_t)byt_soc_data }, 162362306a36Sopenharmony_ci { "INT33FC", (kernel_ulong_t)byt_soc_data }, 162462306a36Sopenharmony_ci { } 162562306a36Sopenharmony_ci}; 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_cistatic int byt_pinctrl_probe(struct platform_device *pdev) 162862306a36Sopenharmony_ci{ 162962306a36Sopenharmony_ci const struct intel_pinctrl_soc_data *soc_data; 163062306a36Sopenharmony_ci struct device *dev = &pdev->dev; 163162306a36Sopenharmony_ci struct intel_pinctrl *vg; 163262306a36Sopenharmony_ci int ret; 163362306a36Sopenharmony_ci 163462306a36Sopenharmony_ci soc_data = intel_pinctrl_get_soc_data(pdev); 163562306a36Sopenharmony_ci if (IS_ERR(soc_data)) 163662306a36Sopenharmony_ci return PTR_ERR(soc_data); 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci vg = devm_kzalloc(dev, sizeof(*vg), GFP_KERNEL); 163962306a36Sopenharmony_ci if (!vg) 164062306a36Sopenharmony_ci return -ENOMEM; 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci vg->dev = dev; 164362306a36Sopenharmony_ci ret = byt_set_soc_data(vg, soc_data); 164462306a36Sopenharmony_ci if (ret) { 164562306a36Sopenharmony_ci dev_err(dev, "failed to set soc data\n"); 164662306a36Sopenharmony_ci return ret; 164762306a36Sopenharmony_ci } 164862306a36Sopenharmony_ci 164962306a36Sopenharmony_ci vg->pctldesc = byt_pinctrl_desc; 165062306a36Sopenharmony_ci vg->pctldesc.name = dev_name(dev); 165162306a36Sopenharmony_ci vg->pctldesc.pins = vg->soc->pins; 165262306a36Sopenharmony_ci vg->pctldesc.npins = vg->soc->npins; 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ci vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg); 165562306a36Sopenharmony_ci if (IS_ERR(vg->pctldev)) { 165662306a36Sopenharmony_ci dev_err(dev, "failed to register pinctrl driver\n"); 165762306a36Sopenharmony_ci return PTR_ERR(vg->pctldev); 165862306a36Sopenharmony_ci } 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_ci ret = byt_gpio_probe(vg); 166162306a36Sopenharmony_ci if (ret) 166262306a36Sopenharmony_ci return ret; 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci platform_set_drvdata(pdev, vg); 166562306a36Sopenharmony_ci pm_runtime_enable(dev); 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci return 0; 166862306a36Sopenharmony_ci} 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_cistatic int byt_gpio_suspend(struct device *dev) 167162306a36Sopenharmony_ci{ 167262306a36Sopenharmony_ci struct intel_pinctrl *vg = dev_get_drvdata(dev); 167362306a36Sopenharmony_ci unsigned long flags; 167462306a36Sopenharmony_ci int i; 167562306a36Sopenharmony_ci 167662306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 167762306a36Sopenharmony_ci 167862306a36Sopenharmony_ci for (i = 0; i < vg->soc->npins; i++) { 167962306a36Sopenharmony_ci void __iomem *reg; 168062306a36Sopenharmony_ci u32 value; 168162306a36Sopenharmony_ci unsigned int pin = vg->soc->pins[i].number; 168262306a36Sopenharmony_ci 168362306a36Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 168462306a36Sopenharmony_ci if (!reg) { 168562306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i); 168662306a36Sopenharmony_ci continue; 168762306a36Sopenharmony_ci } 168862306a36Sopenharmony_ci value = readl(reg) & BYT_CONF0_RESTORE_MASK; 168962306a36Sopenharmony_ci vg->context.pads[i].conf0 = value; 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 169262306a36Sopenharmony_ci if (!reg) { 169362306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i); 169462306a36Sopenharmony_ci continue; 169562306a36Sopenharmony_ci } 169662306a36Sopenharmony_ci value = readl(reg) & BYT_VAL_RESTORE_MASK; 169762306a36Sopenharmony_ci vg->context.pads[i].val = value; 169862306a36Sopenharmony_ci } 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 170162306a36Sopenharmony_ci return 0; 170262306a36Sopenharmony_ci} 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_cistatic int byt_gpio_resume(struct device *dev) 170562306a36Sopenharmony_ci{ 170662306a36Sopenharmony_ci struct intel_pinctrl *vg = dev_get_drvdata(dev); 170762306a36Sopenharmony_ci unsigned long flags; 170862306a36Sopenharmony_ci int i; 170962306a36Sopenharmony_ci 171062306a36Sopenharmony_ci raw_spin_lock_irqsave(&byt_lock, flags); 171162306a36Sopenharmony_ci 171262306a36Sopenharmony_ci for (i = 0; i < vg->soc->npins; i++) { 171362306a36Sopenharmony_ci void __iomem *reg; 171462306a36Sopenharmony_ci u32 value; 171562306a36Sopenharmony_ci unsigned int pin = vg->soc->pins[i].number; 171662306a36Sopenharmony_ci 171762306a36Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); 171862306a36Sopenharmony_ci if (!reg) { 171962306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: can't retrieve CONF0\n", i); 172062306a36Sopenharmony_ci continue; 172162306a36Sopenharmony_ci } 172262306a36Sopenharmony_ci value = readl(reg); 172362306a36Sopenharmony_ci if ((value & BYT_CONF0_RESTORE_MASK) != 172462306a36Sopenharmony_ci vg->context.pads[i].conf0) { 172562306a36Sopenharmony_ci value &= ~BYT_CONF0_RESTORE_MASK; 172662306a36Sopenharmony_ci value |= vg->context.pads[i].conf0; 172762306a36Sopenharmony_ci writel(value, reg); 172862306a36Sopenharmony_ci dev_info(dev, "restored pin %d CONF0 %#08x", i, value); 172962306a36Sopenharmony_ci } 173062306a36Sopenharmony_ci 173162306a36Sopenharmony_ci reg = byt_gpio_reg(vg, pin, BYT_VAL_REG); 173262306a36Sopenharmony_ci if (!reg) { 173362306a36Sopenharmony_ci dev_warn(vg->dev, "Pin %i: can't retrieve VAL\n", i); 173462306a36Sopenharmony_ci continue; 173562306a36Sopenharmony_ci } 173662306a36Sopenharmony_ci value = readl(reg); 173762306a36Sopenharmony_ci if ((value & BYT_VAL_RESTORE_MASK) != 173862306a36Sopenharmony_ci vg->context.pads[i].val) { 173962306a36Sopenharmony_ci u32 v; 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci v = value & ~BYT_VAL_RESTORE_MASK; 174262306a36Sopenharmony_ci v |= vg->context.pads[i].val; 174362306a36Sopenharmony_ci if (v != value) { 174462306a36Sopenharmony_ci writel(v, reg); 174562306a36Sopenharmony_ci dev_dbg(dev, "restored pin %d VAL %#08x\n", i, v); 174662306a36Sopenharmony_ci } 174762306a36Sopenharmony_ci } 174862306a36Sopenharmony_ci } 174962306a36Sopenharmony_ci 175062306a36Sopenharmony_ci raw_spin_unlock_irqrestore(&byt_lock, flags); 175162306a36Sopenharmony_ci return 0; 175262306a36Sopenharmony_ci} 175362306a36Sopenharmony_ci 175462306a36Sopenharmony_cistatic int byt_gpio_runtime_suspend(struct device *dev) 175562306a36Sopenharmony_ci{ 175662306a36Sopenharmony_ci return 0; 175762306a36Sopenharmony_ci} 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_cistatic int byt_gpio_runtime_resume(struct device *dev) 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci return 0; 176262306a36Sopenharmony_ci} 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_cistatic const struct dev_pm_ops byt_gpio_pm_ops = { 176562306a36Sopenharmony_ci LATE_SYSTEM_SLEEP_PM_OPS(byt_gpio_suspend, byt_gpio_resume) 176662306a36Sopenharmony_ci RUNTIME_PM_OPS(byt_gpio_runtime_suspend, byt_gpio_runtime_resume, NULL) 176762306a36Sopenharmony_ci}; 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_cistatic struct platform_driver byt_gpio_driver = { 177062306a36Sopenharmony_ci .probe = byt_pinctrl_probe, 177162306a36Sopenharmony_ci .driver = { 177262306a36Sopenharmony_ci .name = "byt_gpio", 177362306a36Sopenharmony_ci .pm = pm_ptr(&byt_gpio_pm_ops), 177462306a36Sopenharmony_ci .acpi_match_table = byt_gpio_acpi_match, 177562306a36Sopenharmony_ci .suppress_bind_attrs = true, 177662306a36Sopenharmony_ci }, 177762306a36Sopenharmony_ci}; 177862306a36Sopenharmony_ci 177962306a36Sopenharmony_cistatic int __init byt_gpio_init(void) 178062306a36Sopenharmony_ci{ 178162306a36Sopenharmony_ci return platform_driver_register(&byt_gpio_driver); 178262306a36Sopenharmony_ci} 178362306a36Sopenharmony_cisubsys_initcall(byt_gpio_init); 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ciMODULE_IMPORT_NS(PINCTRL_INTEL); 1786