pinctrl: add support for MediaTek MT7628
This patch adds pinctrl support for mt7628, with a file for common pinmux functions and a file for mt7628 which has additional support for pinconf. Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
This commit is contained in:
parent
43405e009b
commit
3fad441c54
@ -269,6 +269,7 @@ source "drivers/pinctrl/exynos/Kconfig"
|
||||
source "drivers/pinctrl/mediatek/Kconfig"
|
||||
source "drivers/pinctrl/meson/Kconfig"
|
||||
source "drivers/pinctrl/mscc/Kconfig"
|
||||
source "drivers/pinctrl/mtmips/Kconfig"
|
||||
source "drivers/pinctrl/mvebu/Kconfig"
|
||||
source "drivers/pinctrl/nxp/Kconfig"
|
||||
source "drivers/pinctrl/renesas/Kconfig"
|
||||
|
@ -9,6 +9,7 @@ obj-y += nxp/
|
||||
obj-$(CONFIG_$(SPL_)PINCTRL_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
|
||||
obj-$(CONFIG_ARCH_ATH79) += ath79/
|
||||
obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
|
||||
obj-$(CONFIG_ARCH_RMOBILE) += renesas/
|
||||
obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
|
||||
|
||||
|
13
drivers/pinctrl/mtmips/Kconfig
Normal file
13
drivers/pinctrl/mtmips/Kconfig
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
config PINCTRL_MTMIPS
|
||||
depends on ARCH_MTMIPS
|
||||
bool
|
||||
|
||||
config PINCTRL_MT7628
|
||||
bool "MediaTek MT7628 pin control driver"
|
||||
select PINCTRL_MTMIPS
|
||||
depends on SOC_MT7628 && PINCTRL_GENERIC
|
||||
help
|
||||
Support pin multiplexing control on MediaTek MT7628.
|
||||
The driver is controlled by a device tree node which contains
|
||||
the pin mux functions for each available pin groups.
|
7
drivers/pinctrl/mtmips/Makefile
Normal file
7
drivers/pinctrl/mtmips/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# Core
|
||||
obj-$(CONFIG_PINCTRL_MTMIPS) += pinctrl-mtmips-common.o
|
||||
|
||||
# SoC Drivers
|
||||
obj-$(CONFIG_PINCTRL_MT7628) += pinctrl-mt7628.o
|
585
drivers/pinctrl/mtmips/pinctrl-mt7628.c
Normal file
585
drivers/pinctrl/mtmips/pinctrl-mt7628.c
Normal file
@ -0,0 +1,585 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "pinctrl-mtmips-common.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define AGPIO_OFS 0
|
||||
#define GPIOMODE1_OFS 0x24
|
||||
#define GPIOMODE2_OFS 0x28
|
||||
|
||||
#define EPHY4_1_PAD_SHIFT 17
|
||||
#define EPHY4_1_PAD_MASK 0x0f
|
||||
#define EPHY0_SHIFT 16
|
||||
#define RF_OLT_MODE_SHIFT 12
|
||||
#define N9_EINT_SRC_SHIFT 9
|
||||
#define WLED_OD_SHIFT 8
|
||||
#define REF_CLKO_PAD_SHIFT 4
|
||||
#define I2S_CLK_PAD_SHIFT 3
|
||||
#define I2S_WS_PAD_SHIFT 2
|
||||
#define I2S_SDO_PAD_SHIFT 1
|
||||
#define I2S_SDI_PAD_SHIFT 0
|
||||
|
||||
#define GM4_MASK 3
|
||||
|
||||
#define P4LED_K_SHIFT 26
|
||||
#define P3LED_K_SHIFT 24
|
||||
#define P2LED_K_SHIFT 22
|
||||
#define P1LED_K_SHIFT 20
|
||||
#define P0LED_K_SHIFT 18
|
||||
#define WLED_K_SHIFT 16
|
||||
#define P4LED_A_SHIFT 10
|
||||
#define P3LED_A_SHIFT 8
|
||||
#define P2LED_A_SHIFT 6
|
||||
#define P1LED_A_SHIFT 4
|
||||
#define P0LED_A_SHIFT 2
|
||||
#define WLED_A_SHIFT 0
|
||||
|
||||
#define PWM1_SHIFT 30
|
||||
#define PWM0_SHIFT 28
|
||||
#define UART2_SHIFT 26
|
||||
#define UART1_SHIFT 24
|
||||
#define I2C_SHIFT 20
|
||||
#define REFCLK_SHIFT 18
|
||||
#define PERST_SHIFT 16
|
||||
#define ESD_SHIFT 15
|
||||
#define WDT_SHIFT 14
|
||||
#define SPI_SHIFT 12
|
||||
#define SDMODE_SHIFT 10
|
||||
#define UART0_SHIFT 8
|
||||
#define I2S_SHIFT 6
|
||||
#define SPI_CS1_SHIFT 4
|
||||
#define SPIS_SHIFT 2
|
||||
#define GPIO0_SHIFT 0
|
||||
|
||||
#define PAD_PU_G0_REG 0x00
|
||||
#define PAD_PU_G1_REG 0x04
|
||||
#define PAD_PD_G0_REG 0x10
|
||||
#define PAD_PD_G1_REG 0x14
|
||||
#define PAD_SR_G0_REG 0x20
|
||||
#define PAD_SR_G1_REG 0x24
|
||||
#define PAD_SMT_G0_REG 0x30
|
||||
#define PAD_SMT_G1_REG 0x34
|
||||
#define PAD_E2_G0_REG 0x40
|
||||
#define PAD_E2_G1_REG 0x44
|
||||
#define PAD_E4_G0_REG 0x50
|
||||
#define PAD_E4_G1_REG 0x54
|
||||
#define PAD_E8_G0_REG 0x60
|
||||
#define PAD_E8_G1_REG 0x64
|
||||
|
||||
#define PIN_CONFIG_DRIVE_STRENGTH_28 (PIN_CONFIG_END + 1)
|
||||
#define PIN_CONFIG_DRIVE_STRENGTH_4G (PIN_CONFIG_END + 2)
|
||||
|
||||
struct mt7628_pinctrl_priv {
|
||||
struct mtmips_pinctrl_priv mp;
|
||||
|
||||
void __iomem *pcbase;
|
||||
};
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINMUX)
|
||||
static const struct mtmips_pmx_func ephy4_1_pad_grp[] = {
|
||||
FUNC("digital", 0xf),
|
||||
FUNC("analog", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func ephy0_grp[] = {
|
||||
FUNC("disable", 1),
|
||||
FUNC("enable", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func rf_olt_grp[] = {
|
||||
FUNC("enable", 1),
|
||||
FUNC("disable", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func n9_eint_src_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("utif", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func wlen_od_grp[] = {
|
||||
FUNC("enable", 1),
|
||||
FUNC("disable", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func ref_clko_grp[] = {
|
||||
FUNC("digital", 1),
|
||||
FUNC("analog", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func i2s_clk_grp[] = {
|
||||
FUNC("digital", 1),
|
||||
FUNC("analog", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func i2s_ws_grp[] = {
|
||||
FUNC("digital", 1),
|
||||
FUNC("analog", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func i2s_sdo_grp[] = {
|
||||
FUNC("digital", 1),
|
||||
FUNC("analog", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func i2s_sdi_grp[] = {
|
||||
FUNC("digital", 1),
|
||||
FUNC("analog", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func pwm1_grp[] = {
|
||||
FUNC("sdxc d6", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("pwm1", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func pwm0_grp[] = {
|
||||
FUNC("sdxc d7", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("pwm0", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func uart2_grp[] = {
|
||||
FUNC("sdxc d5 d4", 3),
|
||||
FUNC("pwm", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("uart2", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func uart1_grp[] = {
|
||||
FUNC("sw_r", 3),
|
||||
FUNC("pwm", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("uart1", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func i2c_grp[] = {
|
||||
FUNC("-", 3),
|
||||
FUNC("debug", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("i2c", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func refclk_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("refclk", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func perst_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("perst", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func esd_grp[] = {
|
||||
FUNC("router", 1),
|
||||
FUNC("iot", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func wdt_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("wdt", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func spi_grp[] = {
|
||||
FUNC("gpio", 1),
|
||||
FUNC("spi", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func sd_mode_grp[] = {
|
||||
FUNC("n9 jtag", 3),
|
||||
FUNC("utif1", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("sdxc", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func uart0_grp[] = {
|
||||
FUNC("-", 3),
|
||||
FUNC("-", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("uart0", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func i2s_grp[] = {
|
||||
FUNC("antenna", 3),
|
||||
FUNC("pcm", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("i2s", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func spi_cs1_grp[] = {
|
||||
FUNC("-", 3),
|
||||
FUNC("refclk", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("spi cs1", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func spis_grp[] = {
|
||||
FUNC("pwm_uart2", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("spis", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func gpio0_grp[] = {
|
||||
FUNC("perst", 3),
|
||||
FUNC("refclk", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("gpio0", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func wled_a_grp[] = {
|
||||
FUNC("-", 3),
|
||||
FUNC("-", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p0led_a_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("rsvd", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p1led_a_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p2led_a_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p3led_a_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p4led_a_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func wled_k_grp[] = {
|
||||
FUNC("-", 3),
|
||||
FUNC("-", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p0led_k_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("rsvd", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p1led_k_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p2led_k_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p3led_k_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_func p4led_k_grp[] = {
|
||||
FUNC("jtag", 3),
|
||||
FUNC("utif", 2),
|
||||
FUNC("gpio", 1),
|
||||
FUNC("led", 0),
|
||||
};
|
||||
|
||||
static const struct mtmips_pmx_group mt7628_pinmux_data[] = {
|
||||
GRP("ephy4_1_pad", ephy4_1_pad_grp, AGPIO_OFS, EPHY4_1_PAD_SHIFT,
|
||||
EPHY4_1_PAD_MASK),
|
||||
GRP("ephy0", ephy0_grp, AGPIO_OFS, EPHY0_SHIFT, 1),
|
||||
GRP("rf_olt", rf_olt_grp, AGPIO_OFS, RF_OLT_MODE_SHIFT, 1),
|
||||
GRP("n9_eint_src", n9_eint_src_grp, AGPIO_OFS, N9_EINT_SRC_SHIFT, 1),
|
||||
GRP("wlen_od", wlen_od_grp, AGPIO_OFS, WLED_OD_SHIFT, 1),
|
||||
GRP("ref_clko_pad", ref_clko_grp, AGPIO_OFS, REF_CLKO_PAD_SHIFT, 1),
|
||||
GRP("i2s_clk_pad", i2s_clk_grp, AGPIO_OFS, I2S_CLK_PAD_SHIFT, 1),
|
||||
GRP("i2s_ws_pad", i2s_ws_grp, AGPIO_OFS, I2S_WS_PAD_SHIFT, 1),
|
||||
GRP("i2s_sdo_pad", i2s_sdo_grp, AGPIO_OFS, I2S_SDO_PAD_SHIFT, 1),
|
||||
GRP("i2s_sdi_pad", i2s_sdi_grp, AGPIO_OFS, I2S_SDI_PAD_SHIFT, 1),
|
||||
GRP("pwm1", pwm1_grp, GPIOMODE1_OFS, PWM1_SHIFT, GM4_MASK),
|
||||
GRP("pwm0", pwm0_grp, GPIOMODE1_OFS, PWM0_SHIFT, GM4_MASK),
|
||||
GRP("uart2", uart2_grp, GPIOMODE1_OFS, UART2_SHIFT, GM4_MASK),
|
||||
GRP("uart1", uart1_grp, GPIOMODE1_OFS, UART1_SHIFT, GM4_MASK),
|
||||
GRP("i2c", i2c_grp, GPIOMODE1_OFS, I2C_SHIFT, GM4_MASK),
|
||||
GRP("refclk", refclk_grp, GPIOMODE1_OFS, REFCLK_SHIFT, 1),
|
||||
GRP("perst", perst_grp, GPIOMODE1_OFS, PERST_SHIFT, 1),
|
||||
GRP("sd router", esd_grp, GPIOMODE1_OFS, ESD_SHIFT, 1),
|
||||
GRP("wdt", wdt_grp, GPIOMODE1_OFS, WDT_SHIFT, 1),
|
||||
GRP("spi", spi_grp, GPIOMODE1_OFS, SPI_SHIFT, 1),
|
||||
GRP("sdmode", sd_mode_grp, GPIOMODE1_OFS, SDMODE_SHIFT, GM4_MASK),
|
||||
GRP("uart0", uart0_grp, GPIOMODE1_OFS, UART0_SHIFT, GM4_MASK),
|
||||
GRP("i2s", i2s_grp, GPIOMODE1_OFS, I2S_SHIFT, GM4_MASK),
|
||||
GRP("spi cs1", spi_cs1_grp, GPIOMODE1_OFS, SPI_CS1_SHIFT, GM4_MASK),
|
||||
GRP("spis", spis_grp, GPIOMODE1_OFS, SPIS_SHIFT, GM4_MASK),
|
||||
GRP("gpio0", gpio0_grp, GPIOMODE1_OFS, GPIO0_SHIFT, GM4_MASK),
|
||||
GRP("wled_a", wled_a_grp, GPIOMODE2_OFS, WLED_A_SHIFT, GM4_MASK),
|
||||
GRP("p0led_a", p0led_a_grp, GPIOMODE2_OFS, P0LED_A_SHIFT, GM4_MASK),
|
||||
GRP("p1led_a", p1led_a_grp, GPIOMODE2_OFS, P1LED_A_SHIFT, GM4_MASK),
|
||||
GRP("p2led_a", p2led_a_grp, GPIOMODE2_OFS, P2LED_A_SHIFT, GM4_MASK),
|
||||
GRP("p3led_a", p3led_a_grp, GPIOMODE2_OFS, P3LED_A_SHIFT, GM4_MASK),
|
||||
GRP("p4led_a", p4led_a_grp, GPIOMODE2_OFS, P4LED_A_SHIFT, GM4_MASK),
|
||||
GRP("wled_k", wled_k_grp, GPIOMODE2_OFS, WLED_K_SHIFT, GM4_MASK),
|
||||
GRP("p0led_k", p0led_k_grp, GPIOMODE2_OFS, P0LED_K_SHIFT, GM4_MASK),
|
||||
GRP("p1led_k", p1led_k_grp, GPIOMODE2_OFS, P1LED_K_SHIFT, GM4_MASK),
|
||||
GRP("p2led_k", p2led_k_grp, GPIOMODE2_OFS, P2LED_K_SHIFT, GM4_MASK),
|
||||
GRP("p3led_k", p3led_k_grp, GPIOMODE2_OFS, P3LED_K_SHIFT, GM4_MASK),
|
||||
GRP("p4led_k", p4led_k_grp, GPIOMODE2_OFS, P4LED_K_SHIFT, GM4_MASK),
|
||||
};
|
||||
|
||||
static int mt7628_get_groups_count(struct udevice *dev)
|
||||
{
|
||||
return ARRAY_SIZE(mt7628_pinmux_data);
|
||||
}
|
||||
|
||||
static const char *mt7628_get_group_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
return mt7628_pinmux_data[selector].name;
|
||||
}
|
||||
#endif /* CONFIG_IS_ENABLED(PINMUX) */
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
static const struct pinconf_param mt7628_conf_params[] = {
|
||||
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
|
||||
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
|
||||
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
|
||||
{ "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
|
||||
{ "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
|
||||
{ "drive-strength-28", PIN_CONFIG_DRIVE_STRENGTH_28, 0 },
|
||||
{ "drive-strength-4g", PIN_CONFIG_DRIVE_STRENGTH_4G, 0 },
|
||||
{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
|
||||
};
|
||||
|
||||
static const char *const mt7628_pins[] = {
|
||||
"i2s_sdi",
|
||||
"i2s_sdo",
|
||||
"i2s_ws",
|
||||
"i2s_clk",
|
||||
"i2s_sclk",
|
||||
"i2c_sd",
|
||||
"spi_cs1",
|
||||
"spi_clk",
|
||||
"spi_mosi",
|
||||
"spi_miso",
|
||||
"spi_cs0",
|
||||
"gpio0",
|
||||
"uart0_txd",
|
||||
"uart0_rxd",
|
||||
"spis_cs",
|
||||
"spis_clk",
|
||||
"spis_miso",
|
||||
"spis_mosi",
|
||||
"pwm_ch0",
|
||||
"pwm_ch1",
|
||||
"uart2_txd",
|
||||
"uart2_rxd",
|
||||
"sd_wp",
|
||||
"sd_cd",
|
||||
"sd_d1",
|
||||
"sd_d0",
|
||||
"sd_clk",
|
||||
"sd_cmd",
|
||||
"sd_d3",
|
||||
"sd_d2",
|
||||
"ephy_led4_k",
|
||||
"ephy_led3_k",
|
||||
"ephy_led2_k",
|
||||
"ephy_led1_k",
|
||||
"ephy_led0_k",
|
||||
"wled_k",
|
||||
"perst_n",
|
||||
"co_clko",
|
||||
"wdt",
|
||||
"ephy_led4_a",
|
||||
"ephy_led3_a",
|
||||
"ephy_led2_a",
|
||||
"ephy_led1_a",
|
||||
"ephy_led0_a",
|
||||
"wled_a",
|
||||
"uart1_txd",
|
||||
"uart1_rxd",
|
||||
};
|
||||
|
||||
static const u32 mt7628_drv_strength_28_tbl[] = {2, 4, 6, 8};
|
||||
static const u32 mt7628_drv_strength_4g_tbl[] = {4, 8, 12, 16};
|
||||
|
||||
static int mt7628_set_drv_strength(void __iomem *base, u32 val, u32 bit,
|
||||
const u32 tbl[], u32 reg_lo, u32 reg_hi)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
if (tbl[i] == val)
|
||||
break;
|
||||
|
||||
if (i >= 4)
|
||||
return -EINVAL;
|
||||
|
||||
clrsetbits_32(base + reg_lo, BIT(bit), (i & 1) << bit);
|
||||
clrsetbits_32(base + reg_hi, BIT(bit), ((i >> 1) & 1) << bit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7628_get_pins_count(struct udevice *dev)
|
||||
{
|
||||
return ARRAY_SIZE(mt7628_pins);
|
||||
}
|
||||
|
||||
static const char *mt7628_get_pin_name(struct udevice *dev,
|
||||
unsigned int selector)
|
||||
{
|
||||
return mt7628_pins[selector];
|
||||
}
|
||||
|
||||
static int mt7628_pinconf_set(struct udevice *dev, unsigned int pin_selector,
|
||||
unsigned int param, unsigned int argument)
|
||||
{
|
||||
struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
u32 offs, bit;
|
||||
int ret = 0;
|
||||
|
||||
offs = (pin_selector / 32) * 4;
|
||||
bit = pin_selector % 32;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_BIAS_DISABLE:
|
||||
clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
|
||||
clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
setbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
|
||||
clrbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
clrbits_32(priv->pcbase + offs + PAD_PU_G0_REG, BIT(bit));
|
||||
setbits_32(priv->pcbase + offs + PAD_PD_G0_REG, BIT(bit));
|
||||
break;
|
||||
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
|
||||
clrsetbits_32(priv->pcbase + offs + PAD_SMT_G0_REG,
|
||||
BIT(bit), (!!argument) << bit);
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH_28:
|
||||
ret = mt7628_set_drv_strength(priv->pcbase + offs, argument,
|
||||
bit, mt7628_drv_strength_28_tbl,
|
||||
PAD_E2_G0_REG, PAD_E4_G0_REG);
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_STRENGTH_4G:
|
||||
ret = mt7628_set_drv_strength(priv->pcbase + offs, argument,
|
||||
bit, mt7628_drv_strength_4g_tbl,
|
||||
PAD_E4_G0_REG, PAD_E8_G0_REG);
|
||||
break;
|
||||
case PIN_CONFIG_SLEW_RATE:
|
||||
clrsetbits_32(priv->pcbase + offs + PAD_SR_G0_REG,
|
||||
BIT(bit), (!!argument) << bit);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mt7628_pinctrl_probe(struct udevice *dev)
|
||||
{
|
||||
struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
int ret = 0;
|
||||
|
||||
#if CONFIG_IS_ENABLED(PINMUX)
|
||||
ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7628_pinmux_data),
|
||||
mt7628_pinmux_data);
|
||||
#endif /* CONFIG_IS_ENABLED(PINMUX) */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mt7628_pinctrl_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct mt7628_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0);
|
||||
|
||||
if (!priv->mp.base)
|
||||
return -EINVAL;
|
||||
|
||||
priv->pcbase = (void __iomem *)dev_remap_addr_index(dev, 1);
|
||||
|
||||
if (!priv->pcbase)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinctrl_ops mt7628_pinctrl_ops = {
|
||||
#if CONFIG_IS_ENABLED(PINMUX)
|
||||
.get_groups_count = mt7628_get_groups_count,
|
||||
.get_group_name = mt7628_get_group_name,
|
||||
.get_functions_count = mtmips_get_functions_count,
|
||||
.get_function_name = mtmips_get_function_name,
|
||||
.pinmux_group_set = mtmips_pinmux_group_set,
|
||||
#endif /* CONFIG_IS_ENABLED(PINMUX) */
|
||||
#if CONFIG_IS_ENABLED(PINCONF)
|
||||
.pinconf_num_params = ARRAY_SIZE(mt7628_conf_params),
|
||||
.pinconf_params = mt7628_conf_params,
|
||||
.get_pins_count = mt7628_get_pins_count,
|
||||
.get_pin_name = mt7628_get_pin_name,
|
||||
.pinconf_set = mt7628_pinconf_set,
|
||||
#endif /* CONFIG_IS_ENABLED(PINCONF) */
|
||||
.set_state = pinctrl_generic_set_state,
|
||||
};
|
||||
|
||||
static const struct udevice_id mt7628_pinctrl_ids[] = {
|
||||
{ .compatible = "mediatek,mt7628-pinctrl" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mt7628_pinctrl) = {
|
||||
.name = "mt7628-pinctrl",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = mt7628_pinctrl_ids,
|
||||
.ofdata_to_platdata = mt7628_pinctrl_ofdata_to_platdata,
|
||||
.ops = &mt7628_pinctrl_ops,
|
||||
.probe = mt7628_pinctrl_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mt7628_pinctrl_priv),
|
||||
};
|
87
drivers/pinctrl/mtmips/pinctrl-mtmips-common.c
Normal file
87
drivers/pinctrl/mtmips/pinctrl-mtmips-common.c
Normal file
@ -0,0 +1,87 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "pinctrl-mtmips-common.h"
|
||||
|
||||
static void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv,
|
||||
u32 reg, u32 shift, u32 mask, u32 value)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(priv->base + reg);
|
||||
val &= ~(mask << shift);
|
||||
val |= value << shift;
|
||||
writel(val, priv->base + reg);
|
||||
}
|
||||
|
||||
int mtmips_get_functions_count(struct udevice *dev)
|
||||
{
|
||||
struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
return priv->nfuncs;
|
||||
}
|
||||
|
||||
const char *mtmips_get_function_name(struct udevice *dev, unsigned int selector)
|
||||
{
|
||||
struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
return priv->funcs[selector]->name;
|
||||
}
|
||||
|
||||
int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector,
|
||||
unsigned int func_selector)
|
||||
{
|
||||
struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct mtmips_pmx_group *grp = &priv->groups[group_selector];
|
||||
const struct mtmips_pmx_func *func = priv->funcs[func_selector];
|
||||
int i;
|
||||
|
||||
if (!grp->nfuncs)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < grp->nfuncs; i++) {
|
||||
if (!strcmp(grp->funcs[i].name, func->name)) {
|
||||
mtmips_pinctrl_reg_set(priv, grp->reg, grp->shift,
|
||||
grp->mask, grp->funcs[i].value);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups,
|
||||
const struct mtmips_pmx_group *groups)
|
||||
{
|
||||
int i, j, n;
|
||||
|
||||
priv->ngroups = ngroups;
|
||||
priv->groups = groups;
|
||||
|
||||
priv->nfuncs = 0;
|
||||
|
||||
for (i = 0; i < ngroups; i++)
|
||||
priv->nfuncs += groups[i].nfuncs;
|
||||
|
||||
priv->funcs = malloc(priv->nfuncs * sizeof(*priv->funcs));
|
||||
if (!priv->funcs)
|
||||
return -ENOMEM;
|
||||
|
||||
n = 0;
|
||||
|
||||
for (i = 0; i < ngroups; i++) {
|
||||
for (j = 0; j < groups[i].nfuncs; j++)
|
||||
priv->funcs[n++] = &groups[i].funcs[j];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
53
drivers/pinctrl/mtmips/pinctrl-mtmips-common.h
Normal file
53
drivers/pinctrl/mtmips/pinctrl-mtmips-common.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2019 MediaTek Inc. All Rights Reserved.
|
||||
*
|
||||
* Author: Weijie Gao <weijie.gao@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _PINCTRL_MTMIPS_COMMON_H_
|
||||
#define _PINCTRL_MTMIPS_COMMON_H_
|
||||
|
||||
#include <common.h>
|
||||
|
||||
struct mtmips_pmx_func {
|
||||
const char *name;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct mtmips_pmx_group {
|
||||
const char *name;
|
||||
|
||||
u32 reg;
|
||||
u32 shift;
|
||||
char mask;
|
||||
|
||||
int nfuncs;
|
||||
const struct mtmips_pmx_func *funcs;
|
||||
};
|
||||
|
||||
struct mtmips_pinctrl_priv {
|
||||
void __iomem *base;
|
||||
|
||||
u32 ngroups;
|
||||
const struct mtmips_pmx_group *groups;
|
||||
|
||||
u32 nfuncs;
|
||||
const struct mtmips_pmx_func **funcs;
|
||||
};
|
||||
|
||||
#define FUNC(name, value) { name, value }
|
||||
|
||||
#define GRP(_name, _funcs, _reg, _shift, _mask) \
|
||||
{ .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \
|
||||
.funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs) }
|
||||
|
||||
int mtmips_get_functions_count(struct udevice *dev);
|
||||
const char *mtmips_get_function_name(struct udevice *dev,
|
||||
unsigned int selector);
|
||||
int mtmips_pinmux_group_set(struct udevice *dev, unsigned int group_selector,
|
||||
unsigned int func_selector);
|
||||
int mtmips_pinctrl_probe(struct mtmips_pinctrl_priv *priv, u32 ngroups,
|
||||
const struct mtmips_pmx_group *groups);
|
||||
|
||||
#endif /* _PINCTRL_MTMIPS_COMMON_H_ */
|
Loading…
Reference in New Issue
Block a user