Hi Sean > The Fully-Programmable Input/Output Array (FPIOA) device controls pin > multiplexing on the K210. The FPIOA can remap any supported function to any > multifunctional IO pin. It can also perform basic GPIO functions, such as > reading the current value of a pin. > > Signed-off-by: Sean Anderson <sean...@gmail.com> > --- > > Changes in v5: > - New > > MAINTAINERS | 2 + > .../pinctrl/kendryte,k210-fpioa.txt | 116 +++ > drivers/pinctrl/Kconfig | 1 + > drivers/pinctrl/Makefile | 1 + > drivers/pinctrl/kendryte/Kconfig | 7 + > drivers/pinctrl/kendryte/Makefile | 1 + > drivers/pinctrl/kendryte/pinctrl.c | 663 ++++++++++++++++++ > drivers/pinctrl/kendryte/pinctrl.h | 325 +++++++++ > include/dt-bindings/pinctrl/k210-pinctrl.h | 12 + > 9 files changed, 1128 insertions(+) > create mode 100644 doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt > create mode 100644 drivers/pinctrl/kendryte/Kconfig > create mode 100644 drivers/pinctrl/kendryte/Makefile > create mode 100644 drivers/pinctrl/kendryte/pinctrl.c > create mode 100644 drivers/pinctrl/kendryte/pinctrl.h > create mode 100644 include/dt-bindings/pinctrl/k210-pinctrl.h >
Please checkpatch and fix total: 3 errors, 13 warnings, 5 checks, 1147 lines checked Thanks Rick > diff --git a/MAINTAINERS b/MAINTAINERS > index 8e9e0569ba..8725bcf9af 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -809,7 +809,9 @@ RISC-V KENDRYTE > M: Sean Anderson <sean...@gmail.com> > S: Maintained > F: doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt > +F: doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt > F: drivers/clk/kendryte/ > +F: drivers/pinctrl/kendryte/ > F: include/kendryte/ > > RNG > diff --git a/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt > b/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt > new file mode 100644 > index 0000000000..299ce65304 > --- /dev/null > +++ b/doc/device-tree-bindings/pinctrl/kendryte,k210-fpioa.txt > @@ -0,0 +1,116 @@ > +Kendryte K210 FPIOA > + > +This binding describes the Fully-Programmable Input/Output Array found on > +Kendryte K210 SoCs. Any of the 256 functions can be mapped to any of the 48 > +pins. > + > +Required properties: > +- compatible: should be "kendryte,k210-fpioa" > +- reg: address and length of the FPIOA registers > +- kendryte,sysctl: phandle to the "sysctl" register map node > +- kendryte,power-offset: offset in the register map of the power bank control > + register (in bytes) > + > +Configuration nodes > + > +Pin configuration nodes are documented in pinctrl-bindings.txt > + > +Valid values for pins, groups, and function names: > + > +pins: > + "IO_X", where X is a number from 0 to 47. > + > +groups: > + A0, A1, A2, B0, B1, B2, C0, C1 > + > +functions: > + JTAG_TCLK, JTAG_TDI, JTAG_TMS, JTAG_TDO, SPI0_D0, SPI0_D1, SPI0_D2, > + SPI0_D3, SPI0_D4, SPI0_D5, SPI0_D6, SPI0_D7, SPI0_SS0, SPI0_SS1, > + SPI0_SS2, SPI0_SS3, SPI0_ARB, SPI0_SCLK, UARTHS_RX, UARTHS_TX, RESV6, > + RESV7, CLK_SPI1, CLK_I2C1, GPIOHS0, GPIOHS1, GPIOHS2, GPIOHS3, > GPIOHS4, > + GPIOHS5, GPIOHS6, GPIOHS7, GPIOHS8, GPIOHS9, GPIOHS10, GPIOHS11, > + GPIOHS12, GPIOHS13, GPIOHS14, GPIOHS15, GPIOHS16, GPIOHS17, GPIOHS18, > + GPIOHS19, GPIOHS20, GPIOHS21, GPIOHS22, GPIOHS23, GPIOHS24, GPIOHS25, > + GPIOHS26, GPIOHS27, GPIOHS28, GPIOHS29, GPIOHS30, GPIOHS31, GPIO0, > + GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, UART1_RX, UART1_TX, > + UART2_RX, UART2_TX, UART3_RX, UART3_TX, SPI1_D0, SPI1_D1, SPI1_D2, > + SPI1_D3, SPI1_D4, SPI1_D5, SPI1_D6, SPI1_D7, SPI1_SS0, SPI1_SS1, > + SPI1_SS2, SPI1_SS3, SPI1_ARB, SPI1_SCLK, SPI2_D0, SPI2_SS, SPI2_SCLK, > + I2S0_MCLK, I2S0_SCLK, I2S0_WS, I2S0_IN_D0, I2S0_IN_D1, I2S0_IN_D2, > + I2S0_IN_D3, I2S0_OUT_D0, I2S0_OUT_D1, I2S0_OUT_D2, I2S0_OUT_D3, > + I2S1_MCLK, I2S1_SCLK, I2S1_WS, I2S1_IN_D0, I2S1_IN_D1, I2S1_IN_D2, > + I2S1_IN_D3, I2S1_OUT_D0, I2S1_OUT_D1, I2S1_OUT_D2, I2S1_OUT_D3, > + I2S2_MCLK, I2S2_SCLK, I2S2_WS, I2S2_IN_D0, I2S2_IN_D1, I2S2_IN_D2, > + I2S2_IN_D3, I2S2_OUT_D0, I2S2_OUT_D1, I2S2_OUT_D2, I2S2_OUT_D3, RESV0, > + RESV1, RESV2, RESV3, RESV4, RESV5, I2C0_SCLK, I2C0_SDA, I2C1_SCLK, > + I2C1_SDA, I2C2_SCLK, I2C2_SDA, DVP_XCLK, DVP_RST, DVP_PWDN, DVP_VSYNC, > + DVP_HREF, DVP_PCLK, DVP_D0, DVP_D1, DVP_D2, DVP_D3, DVP_D4, DVP_D5, > + DVP_D6, DVP_D7, SCCB_SCLK, SCCB_SDA, UART1_CTS, UART1_DSR, UART1_DCD, > + UART1_RI, UART1_SIR_IN, UART1_DTR, UART1_RTS, UART1_OUT2, UART1_OUT1, > + UART1_SIR_OUT, UART1_BAUD, UART1_RE, UART1_DE, UART1_RS485_EN, > + UART2_CTS, UART2_DSR, UART2_DCD, UART2_RI, UART2_SIR_IN, UART2_DTR, > + UART2_RTS, UART2_OUT2, UART2_OUT1, UART2_SIR_OUT, UART2_BAUD, > UART2_RE, > + UART2_DE, UART2_RS485_EN, UART3_CTS, UART3_DSR, UART3_DCD, UART3_RI, > + UART3_SIR_IN, UART3_DTR, UART3_RTS, UART3_OUT2, UART3_OUT1, > + UART3_SIR_OUT, UART3_BAUD, UART3_RE, UART3_DE, UART3_RS485_EN, > + TIMER0_TOGGLE1, TIMER0_TOGGLE2, TIMER0_TOGGLE3, TIMER0_TOGGLE4, > + TIMER1_TOGGLE1, TIMER1_TOGGLE2, TIMER1_TOGGLE3, TIMER1_TOGGLE4, > + TIMER2_TOGGLE1, TIMER2_TOGGLE2, TIMER2_TOGGLE3, TIMER2_TOGGLE4, > + CLK_SPI2, CLK_I2C2, INTERNAL0, INTERNAL1, INTERNAL2, INTERNAL3, > + INTERNAL4, INTERNAL5, INTERNAL6, INTERNAL7, INTERNAL8, INTERNAL9, > + INTERNAL10, INTERNAL11, INTERNAL12, INTERNAL13, INTERNAL14, > INTERNAL15, > + INTERNAL16, INTERNAL17, CONSTANT, INTERNAL18, DEBUG0, DEBUG1, DEBUG2, > + DEBUG3, DEBUG4, DEBUG5, DEBUG6, DEBUG7, DEBUG8, DEBUG9, DEBUG10, > + DEBUG11, DEBUG12, DEBUG13, DEBUG14, DEBUG15, DEBUG16, DEBUG17, > DEBUG18, > + DEBUG19, DEBUG20, DEBUG21, DEBUG22, DEBUG23, DEBUG24, DEBUG25, > DEBUG26, > + DEBUG27, DEBUG28, DEBUG29, DEBUG30, DEBUG31 > + > +Valid properties include: > + bias-disable, bias-pull-down, bias-pull-up, drive-strength, > + drive-strength-ua, input-enable, input-disable, input-schmitt-enable, > + input-schmitt-disable, power-source, output-low, output-high, > + output-enable, output-disable, slew-rate > + > +Notes on specific properties include: > +- bias-pull-up, -down, and -pin-default: The pull strength cannot be > configured. > +- drive-strength: There are 8 drive strength settings between 11 and 50 mA > +- power-source: Controls the output voltage of a bank of pins. Either > + K210_PC_POWER_1V8 or K210_PC_POWER_3V3 may be specified. This property > cannot > + be specified for individual pins. > +- slew-rate: Specifying this property reduces the slew rate > + > +Example: > +fpioa: pinmux@502B0000 { > + compatible = "kendryte,k210-fpioa"; > + reg = <0x502B0000 0x100>; > + kendryte,sysctl = <&sysctl>; > + kendryte,power-offset = <K210_SYSCTL_POWER_SEL>; > + > + fpioa_jtag: jtag { > + voltage { > + group = "A0"; > + power-source = <K210_PC_POWER_3V3>; > + }; > + tck { > + function = "JTAG_TCLK"; > + pins = "IO_0"; > + }; > + tdi { > + function = "JTAG_TDI"; > + pins = "IO_1"; > + }; > + tms { > + function = "JTAG_TMS"; > + pins = "IO_2"; > + }; > + tdo { > + function = "JTAG_TDO"; > + pins = "IO_3"; > + }; > + }; > + > + fpioa_isp: isp { > + function = "GPIOHS0"; > + pins = "IO_16"; > + }; > +}; > diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig > index 83e39b9de3..9ec56c7735 100644 > --- a/drivers/pinctrl/Kconfig > +++ b/drivers/pinctrl/Kconfig > @@ -289,6 +289,7 @@ endif > source "drivers/pinctrl/broadcom/Kconfig" > source "drivers/pinctrl/exynos/Kconfig" > source "drivers/pinctrl/intel/Kconfig" > +source "drivers/pinctrl/kendryte/Kconfig" > source "drivers/pinctrl/mediatek/Kconfig" > source "drivers/pinctrl/meson/Kconfig" > source "drivers/pinctrl/mscc/Kconfig" > diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile > index 4f662c4f6d..1fe66fed3c 100644 > --- a/drivers/pinctrl/Makefile > +++ b/drivers/pinctrl/Makefile > @@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o > obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ > obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o > obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/ > +obj-$(CONFIG_PINCTRL_K210) += kendryte/ > obj-$(CONFIG_PINCTRL_MESON) += meson/ > obj-$(CONFIG_PINCTRL_MTK) += mediatek/ > obj-$(CONFIG_PINCTRL_MSCC) += mscc/ > diff --git a/drivers/pinctrl/kendryte/Kconfig > b/drivers/pinctrl/kendryte/Kconfig > new file mode 100644 > index 0000000000..6fc10e9516 > --- /dev/null > +++ b/drivers/pinctrl/kendryte/Kconfig > @@ -0,0 +1,7 @@ > +config PINCTRL_K210 > + bool "Kendryte K210 Fully-Programmable Input/Output Array driver" > + depends on DM && PINCTRL_GENERIC > + help > + Support pin multiplexing on the K210. The "FPIOA" can remap any > + supported function to any multifunctional IO pin. It can also > perform > + basic GPIO functions, such as reading the current value of a pin. > diff --git a/drivers/pinctrl/kendryte/Makefile > b/drivers/pinctrl/kendryte/Makefile > new file mode 100644 > index 0000000000..1c10d7a929 > --- /dev/null > +++ b/drivers/pinctrl/kendryte/Makefile > @@ -0,0 +1 @@ > +obj-y += pinctrl.o > diff --git a/drivers/pinctrl/kendryte/pinctrl.c > b/drivers/pinctrl/kendryte/pinctrl.c > new file mode 100644 > index 0000000000..3f7de0e706 > --- /dev/null > +++ b/drivers/pinctrl/kendryte/pinctrl.c > @@ -0,0 +1,663 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2020 Sean Anderson <sean...@gmail.com> > + */ > + > +#include <common.h> > +#include <clk.h> > +#include <dm.h> > +#include <dm/pinctrl.h> > +#include <dt-bindings/pinctrl/k210-pinctrl.h> > +#include <mapmem.h> > +#include <regmap.h> > +#include <syscon.h> > +#include <asm/io.h> > +#include <linux/err.h> > +#include "pinctrl.h" > + > +struct k210_pc_priv { > + struct clk clk; > + struct k210_fpioa __iomem *fpioa; /* FPIOA register */ > + struct regmap *sysctl; /* Sysctl regmap */ > + u32 power_offset; /* Power bank register offset */ > +}; > + > +#define PIN(i) [i] = "IO_" #i > +static const char k210_pc_pin_names[][6] = { > + PIN(0), > + PIN(1), > + PIN(2), > + PIN(3), > + PIN(4), > + PIN(5), > + PIN(6), > + PIN(7), > + PIN(8), > + PIN(9), > + PIN(10), > + PIN(11), > + PIN(12), > + PIN(13), > + PIN(14), > + PIN(15), > + PIN(16), > + PIN(17), > + PIN(18), > + PIN(19), > + PIN(20), > + PIN(21), > + PIN(22), > + PIN(23), > + PIN(24), > + PIN(25), > + PIN(26), > + PIN(27), > + PIN(28), > + PIN(29), > + PIN(30), > + PIN(31), > + PIN(32), > + PIN(33), > + PIN(34), > + PIN(35), > + PIN(36), > + PIN(37), > + PIN(38), > + PIN(39), > + PIN(40), > + PIN(41), > + PIN(42), > + PIN(43), > + PIN(44), > + PIN(45), > + PIN(46), > + PIN(47), > +}; > +#undef PIN > + > +static int k210_pc_get_pins_count(struct udevice *dev) > +{ > + return ARRAY_SIZE(k210_pc_pin_names); > +}; > + > +static const char *k210_pc_get_pin_name(struct udevice *dev, unsigned > selector) > +{ > + return k210_pc_pin_names[selector]; > +} > + > +/* These are just power domains */ > +static const char k210_pc_group_names[][3] = { > + [0] = "A0", > + [1] = "A1", > + [2] = "A2", > + [3] = "B0", > + [4] = "B1", > + [5] = "B2", > + [6] = "C0", > + [7] = "C1", > +}; > + > +static int k210_pc_get_groups_count(struct udevice *dev) > +{ > + return ARRAY_SIZE(k210_pc_group_names); > +} > + > +static const char *k210_pc_get_group_name(struct udevice *dev, > + unsigned selector) > +{ > + return k210_pc_group_names[selector]; > +} > + > +enum k210_pc_mode_id { > + K210_PC_DEFAULT_DISABLED, > + K210_PC_DEFAULT_IN, > + K210_PC_DEFAULT_IN_TIE, > + K210_PC_DEFAULT_OUT, > + K210_PC_DEFAULT_I2C, > + K210_PC_DEFAULT_SPI, > + K210_PC_DEFAULT_GPIO, > + K210_PC_DEFAULT_INT13, > +}; > + > +#define DEFAULT(mode) [K210_PC_DEFAULT_##mode] = K210_PC_MODE_##mode > +static const u32 k210_pc_mode_id_to_mode[] = { > + [K210_PC_DEFAULT_DISABLED] = 0, > + DEFAULT(IN), > + [K210_PC_DEFAULT_IN_TIE] = K210_PC_MODE_IN, > + DEFAULT(OUT), > + DEFAULT(I2C), > + DEFAULT(SPI), > + DEFAULT(GPIO), > + [K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU, > +}; > +#undef DEFAULT > + > +/* This saves around 2K vs having a pointer+mode */ > +struct k210_pcf_info { > + char name[15]; > + u8 mode_id; > +}; > + > +#define FUNC(id, mode) [K210_PCF_##id] = { \ > + .name = #id, \ > + .mode_id = K210_PC_DEFAULT_##mode \ > +} > +static const struct k210_pcf_info k210_pcf_infos[] = { > + FUNC(JTAG_TCLK, IN), > + FUNC(JTAG_TDI, IN), > + FUNC(JTAG_TMS, IN), > + FUNC(JTAG_TDO, OUT), > + FUNC(SPI0_D0, SPI), > + FUNC(SPI0_D1, SPI), > + FUNC(SPI0_D2, SPI), > + FUNC(SPI0_D3, SPI), > + FUNC(SPI0_D4, SPI), > + FUNC(SPI0_D5, SPI), > + FUNC(SPI0_D6, SPI), > + FUNC(SPI0_D7, SPI), > + FUNC(SPI0_SS0, OUT), > + FUNC(SPI0_SS1, OUT), > + FUNC(SPI0_SS2, OUT), > + FUNC(SPI0_SS3, OUT), > + FUNC(SPI0_ARB, IN_TIE), > + FUNC(SPI0_SCLK, OUT), > + FUNC(UARTHS_RX, IN), > + FUNC(UARTHS_TX, OUT), > + FUNC(RESV6, IN), > + FUNC(RESV7, IN), > + FUNC(CLK_SPI1, OUT), > + FUNC(CLK_I2C1, OUT), > + FUNC(GPIOHS0, GPIO), > + FUNC(GPIOHS1, GPIO), > + FUNC(GPIOHS2, GPIO), > + FUNC(GPIOHS3, GPIO), > + FUNC(GPIOHS4, GPIO), > + FUNC(GPIOHS5, GPIO), > + FUNC(GPIOHS6, GPIO), > + FUNC(GPIOHS7, GPIO), > + FUNC(GPIOHS8, GPIO), > + FUNC(GPIOHS9, GPIO), > + FUNC(GPIOHS10, GPIO), > + FUNC(GPIOHS11, GPIO), > + FUNC(GPIOHS12, GPIO), > + FUNC(GPIOHS13, GPIO), > + FUNC(GPIOHS14, GPIO), > + FUNC(GPIOHS15, GPIO), > + FUNC(GPIOHS16, GPIO), > + FUNC(GPIOHS17, GPIO), > + FUNC(GPIOHS18, GPIO), > + FUNC(GPIOHS19, GPIO), > + FUNC(GPIOHS20, GPIO), > + FUNC(GPIOHS21, GPIO), > + FUNC(GPIOHS22, GPIO), > + FUNC(GPIOHS23, GPIO), > + FUNC(GPIOHS24, GPIO), > + FUNC(GPIOHS25, GPIO), > + FUNC(GPIOHS26, GPIO), > + FUNC(GPIOHS27, GPIO), > + FUNC(GPIOHS28, GPIO), > + FUNC(GPIOHS29, GPIO), > + FUNC(GPIOHS30, GPIO), > + FUNC(GPIOHS31, GPIO), > + FUNC(GPIO0, GPIO), > + FUNC(GPIO1, GPIO), > + FUNC(GPIO2, GPIO), > + FUNC(GPIO3, GPIO), > + FUNC(GPIO4, GPIO), > + FUNC(GPIO5, GPIO), > + FUNC(GPIO6, GPIO), > + FUNC(GPIO7, GPIO), > + FUNC(UART1_RX, IN), > + FUNC(UART1_TX, OUT), > + FUNC(UART2_RX, IN), > + FUNC(UART2_TX, OUT), > + FUNC(UART3_RX, IN), > + FUNC(UART3_TX, OUT), > + FUNC(SPI1_D0, SPI), > + FUNC(SPI1_D1, SPI), > + FUNC(SPI1_D2, SPI), > + FUNC(SPI1_D3, SPI), > + FUNC(SPI1_D4, SPI), > + FUNC(SPI1_D5, SPI), > + FUNC(SPI1_D6, SPI), > + FUNC(SPI1_D7, SPI), > + FUNC(SPI1_SS0, OUT), > + FUNC(SPI1_SS1, OUT), > + FUNC(SPI1_SS2, OUT), > + FUNC(SPI1_SS3, OUT), > + FUNC(SPI1_ARB, IN_TIE), > + FUNC(SPI1_SCLK, OUT), > + FUNC(SPI2_D0, SPI), > + FUNC(SPI2_SS, IN), > + FUNC(SPI2_SCLK, IN), > + FUNC(I2S0_MCLK, OUT), > + FUNC(I2S0_SCLK, OUT), > + FUNC(I2S0_WS, OUT), > + FUNC(I2S0_IN_D0, IN), > + FUNC(I2S0_IN_D1, IN), > + FUNC(I2S0_IN_D2, IN), > + FUNC(I2S0_IN_D3, IN), > + FUNC(I2S0_OUT_D0, OUT), > + FUNC(I2S0_OUT_D1, OUT), > + FUNC(I2S0_OUT_D2, OUT), > + FUNC(I2S0_OUT_D3, OUT), > + FUNC(I2S1_MCLK, OUT), > + FUNC(I2S1_SCLK, OUT), > + FUNC(I2S1_WS, OUT), > + FUNC(I2S1_IN_D0, IN), > + FUNC(I2S1_IN_D1, IN), > + FUNC(I2S1_IN_D2, IN), > + FUNC(I2S1_IN_D3, IN), > + FUNC(I2S1_OUT_D0, OUT), > + FUNC(I2S1_OUT_D1, OUT), > + FUNC(I2S1_OUT_D2, OUT), > + FUNC(I2S1_OUT_D3, OUT), > + FUNC(I2S2_MCLK, OUT), > + FUNC(I2S2_SCLK, OUT), > + FUNC(I2S2_WS, OUT), > + FUNC(I2S2_IN_D0, IN), > + FUNC(I2S2_IN_D1, IN), > + FUNC(I2S2_IN_D2, IN), > + FUNC(I2S2_IN_D3, IN), > + FUNC(I2S2_OUT_D0, OUT), > + FUNC(I2S2_OUT_D1, OUT), > + FUNC(I2S2_OUT_D2, OUT), > + FUNC(I2S2_OUT_D3, OUT), > + FUNC(RESV0, DISABLED), > + FUNC(RESV1, DISABLED), > + FUNC(RESV2, DISABLED), > + FUNC(RESV3, DISABLED), > + FUNC(RESV4, DISABLED), > + FUNC(RESV5, DISABLED), > + FUNC(I2C0_SCLK, I2C), > + FUNC(I2C0_SDA, I2C), > + FUNC(I2C1_SCLK, I2C), > + FUNC(I2C1_SDA, I2C), > + FUNC(I2C2_SCLK, I2C), > + FUNC(I2C2_SDA, I2C), > + FUNC(DVP_XCLK, OUT), > + FUNC(DVP_RST, OUT), > + FUNC(DVP_PWDN, OUT), > + FUNC(DVP_VSYNC, IN), > + FUNC(DVP_HREF, IN), > + FUNC(DVP_PCLK, IN), > + FUNC(DVP_D0, IN), > + FUNC(DVP_D1, IN), > + FUNC(DVP_D2, IN), > + FUNC(DVP_D3, IN), > + FUNC(DVP_D4, IN), > + FUNC(DVP_D5, IN), > + FUNC(DVP_D6, IN), > + FUNC(DVP_D7, IN), > + FUNC(SCCB_SCLK, I2C), > + FUNC(SCCB_SDA, I2C), > + FUNC(UART1_CTS, IN), > + FUNC(UART1_DSR, IN), > + FUNC(UART1_DCD, IN), > + FUNC(UART1_RI, IN), > + FUNC(UART1_SIR_IN, IN), > + FUNC(UART1_DTR, OUT), > + FUNC(UART1_RTS, OUT), > + FUNC(UART1_OUT2, OUT), > + FUNC(UART1_OUT1, OUT), > + FUNC(UART1_SIR_OUT, OUT), > + FUNC(UART1_BAUD, OUT), > + FUNC(UART1_RE, OUT), > + FUNC(UART1_DE, OUT), > + FUNC(UART1_RS485_EN, OUT), > + FUNC(UART2_CTS, IN), > + FUNC(UART2_DSR, IN), > + FUNC(UART2_DCD, IN), > + FUNC(UART2_RI, IN), > + FUNC(UART2_SIR_IN, IN), > + FUNC(UART2_DTR, OUT), > + FUNC(UART2_RTS, OUT), > + FUNC(UART2_OUT2, OUT), > + FUNC(UART2_OUT1, OUT), > + FUNC(UART2_SIR_OUT, OUT), > + FUNC(UART2_BAUD, OUT), > + FUNC(UART2_RE, OUT), > + FUNC(UART2_DE, OUT), > + FUNC(UART2_RS485_EN, OUT), > + FUNC(UART3_CTS, IN), > + FUNC(UART3_DSR, IN), > + FUNC(UART3_DCD, IN), > + FUNC(UART3_RI, IN), > + FUNC(UART3_SIR_IN, IN), > + FUNC(UART3_DTR, OUT), > + FUNC(UART3_RTS, OUT), > + FUNC(UART3_OUT2, OUT), > + FUNC(UART3_OUT1, OUT), > + FUNC(UART3_SIR_OUT, OUT), > + FUNC(UART3_BAUD, OUT), > + FUNC(UART3_RE, OUT), > + FUNC(UART3_DE, OUT), > + FUNC(UART3_RS485_EN, OUT), > + FUNC(TIMER0_TOGGLE1, OUT), > + FUNC(TIMER0_TOGGLE2, OUT), > + FUNC(TIMER0_TOGGLE3, OUT), > + FUNC(TIMER0_TOGGLE4, OUT), > + FUNC(TIMER1_TOGGLE1, OUT), > + FUNC(TIMER1_TOGGLE2, OUT), > + FUNC(TIMER1_TOGGLE3, OUT), > + FUNC(TIMER1_TOGGLE4, OUT), > + FUNC(TIMER2_TOGGLE1, OUT), > + FUNC(TIMER2_TOGGLE2, OUT), > + FUNC(TIMER2_TOGGLE3, OUT), > + FUNC(TIMER2_TOGGLE4, OUT), > + FUNC(CLK_SPI2, OUT), > + FUNC(CLK_I2C2, OUT), > + FUNC(INTERNAL0, OUT), > + FUNC(INTERNAL1, OUT), > + FUNC(INTERNAL2, OUT), > + FUNC(INTERNAL3, OUT), > + FUNC(INTERNAL4, OUT), > + FUNC(INTERNAL5, OUT), > + FUNC(INTERNAL6, OUT), > + FUNC(INTERNAL7, OUT), > + FUNC(INTERNAL8, OUT), > + FUNC(INTERNAL9, IN), > + FUNC(INTERNAL10, IN), > + FUNC(INTERNAL11, IN), > + FUNC(INTERNAL12, IN), > + FUNC(INTERNAL13, INT13), > + FUNC(INTERNAL14, I2C), > + FUNC(INTERNAL15, IN), > + FUNC(INTERNAL16, IN), > + FUNC(INTERNAL17, IN), > + FUNC(CONSTANT, DISABLED), > + FUNC(INTERNAL18, IN), > + FUNC(DEBUG0, OUT), > + FUNC(DEBUG1, OUT), > + FUNC(DEBUG2, OUT), > + FUNC(DEBUG3, OUT), > + FUNC(DEBUG4, OUT), > + FUNC(DEBUG5, OUT), > + FUNC(DEBUG6, OUT), > + FUNC(DEBUG7, OUT), > + FUNC(DEBUG8, OUT), > + FUNC(DEBUG9, OUT), > + FUNC(DEBUG10, OUT), > + FUNC(DEBUG11, OUT), > + FUNC(DEBUG12, OUT), > + FUNC(DEBUG13, OUT), > + FUNC(DEBUG14, OUT), > + FUNC(DEBUG15, OUT), > + FUNC(DEBUG16, OUT), > + FUNC(DEBUG17, OUT), > + FUNC(DEBUG18, OUT), > + FUNC(DEBUG19, OUT), > + FUNC(DEBUG20, OUT), > + FUNC(DEBUG21, OUT), > + FUNC(DEBUG22, OUT), > + FUNC(DEBUG23, OUT), > + FUNC(DEBUG24, OUT), > + FUNC(DEBUG25, OUT), > + FUNC(DEBUG26, OUT), > + FUNC(DEBUG27, OUT), > + FUNC(DEBUG28, OUT), > + FUNC(DEBUG29, OUT), > + FUNC(DEBUG30, OUT), > + FUNC(DEBUG31, OUT), > +}; > +#undef FUNC > + > +int k210_pc_get_functions_count(struct udevice *dev) > +{ > + return ARRAY_SIZE(k210_pcf_infos); > +} > + > +static const char *k210_pc_get_function_name(struct udevice *dev, > + unsigned selector) > +{ > + return k210_pcf_infos[selector].name; > +} > + > +static int k210_pc_pinmux_set(struct udevice *dev, unsigned pin_selector, > + unsigned func_selector) > +{ > + struct k210_pc_priv *priv = dev_get_priv(dev); > + const struct k210_pcf_info *info = &k210_pcf_infos[func_selector]; > + u32 mode = k210_pc_mode_id_to_mode[info->mode_id]; > + u32 val = func_selector | mode; > + > + log_debug("setting pin %s to %s with mode %.8x\n", > + k210_pc_pin_names[pin_selector], info->name, mode); > + writel(val, &priv->fpioa->pins[pin_selector]); > + return 0; > +} > + > +/* Max drive strength in uA */ > +static const int k210_pc_drive_strength[] = { > + [0] = 11200, > + [1] = 16800, > + [2] = 22300, > + [3] = 27800, > + [4] = 33300, > + [5] = 38700, > + [6] = 44100, > + [7] = 49500, > +}; > + > +static int k210_pc_get_drive(unsigned max_strength_ua) > +{ > + int i; > + > + for (i = K210_PC_DRIVE_MAX; i; i--) > + if (k210_pc_drive_strength[i] < max_strength_ua) > + return i; > + > + return -EINVAL; > +} > + > +static int k210_pc_pinconf_set(struct udevice *dev, unsigned pin_selector, > + unsigned param, unsigned argument) > +{ > + struct k210_pc_priv *priv = dev_get_priv(dev); > + u32 val = readl(&priv->fpioa->pins[pin_selector]); > + > + switch (param) { > + case PIN_CONFIG_BIAS_DISABLE: > + val &= ~K210_PC_BIAS_MASK; > + break; > + case PIN_CONFIG_BIAS_PULL_DOWN: > + if (argument) > + val |= K210_PC_PD; > + else > + return -EINVAL; > + break; > + case PIN_CONFIG_BIAS_PULL_UP: > + if (argument) > + val |= K210_PC_PD; > + else > + return -EINVAL; > + break; > + case PIN_CONFIG_DRIVE_STRENGTH: > + argument *= 1000; > + case PIN_CONFIG_DRIVE_STRENGTH_UA: { > + int drive = k210_pc_get_drive(argument); > + > + if (IS_ERR_VALUE(drive)) > + return drive; > + val &= ~K210_PC_DRIVE_MASK; > + val |= FIELD_PREP(K210_PC_DRIVE_MASK, drive); > + break; > + } > + case PIN_CONFIG_INPUT_ENABLE: > + if (argument) > + val |= K210_PC_IE; > + else > + val &= ~K210_PC_IE; > + break; > + case PIN_CONFIG_INPUT_SCHMITT: > + argument = 1; > + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: > + if (argument) > + val |= K210_PC_ST; > + else > + val &= ~K210_PC_ST; > + break; > + case PIN_CONFIG_OUTPUT: > + k210_pc_pinmux_set(dev, pin_selector, K210_PCF_CONSTANT); > + val = readl(&priv->fpioa->pins[pin_selector]); > + val |= K210_PC_MODE_OUT; > + > + if (!argument) > + val |= K210_PC_DO_INV; > + break; > + case PIN_CONFIG_OUTPUT_ENABLE: > + if (argument) > + val |= K210_PC_OE; > + else > + val &= ~K210_PC_OE; > + break; > + case PIN_CONFIG_SLEW_RATE: > + if (argument) > + val |= K210_PC_SL; > + else > + val &= ~K210_PC_SL; > + break; > + default: > + return -EINVAL; > + } > + > + writel(val, &priv->fpioa->pins[pin_selector]); > + return 0; > +} > + > +static int k210_pc_pinconf_group_set(struct udevice *dev, > + unsigned group_selector, unsigned param, > + unsigned argument) > +{ > + struct k210_pc_priv *priv = dev_get_priv(dev); > + > + if (param == PIN_CONFIG_POWER_SOURCE) { > + u32 bit = BIT(group_selector); > + > + regmap_update_bits(priv->sysctl, priv->power_offset, bit, > + argument ? bit : 0); > + } else { > + int i, ret; > + > + for (i = 0; i < 6; i++) { > + ret = k210_pc_pinconf_set(dev, group_selector * 6 + i, > + param, argument); > + if (ret) > + return ret; > + } > + } > + > + return 0; > +} > + > +static int k210_pc_get_pin_muxing(struct udevice *dev, unsigned int selector, > + char *buf, int size) > +{ > + struct k210_pc_priv *priv = dev_get_priv(dev); > + u32 val = readl(&priv->fpioa->pins[selector]); > + const struct k210_pcf_info *info = &k210_pcf_infos[val & > K210_PCF_MASK]; > + > + strncpy(buf, info->name, min((size_t)size, sizeof(info->name))); > + return 0; > +} > + > +static const struct pinconf_param k210_pc_pinconf_params[] = { > + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, > + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, > + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, > + { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, U32_MAX }, > + { "drive-strength-ua", PIN_CONFIG_DRIVE_STRENGTH_UA, U32_MAX }, > + { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, > + { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, > + { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, > + { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, > + { "power-source", PIN_CONFIG_POWER_SOURCE, K210_PC_POWER_1V8 }, > + { "output-low", PIN_CONFIG_OUTPUT, 0 }, > + { "output-high", PIN_CONFIG_OUTPUT, 1 }, > + { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 }, > + { "output-disable", PIN_CONFIG_OUTPUT_ENABLE, 0 }, > + { "slew-rate", PIN_CONFIG_SLEW_RATE, 1 }, > +}; > + > +static const struct pinctrl_ops k210_pc_pinctrl_ops = { > + .get_pins_count = k210_pc_get_pins_count, > + .get_pin_name = k210_pc_get_pin_name, > + .get_groups_count = k210_pc_get_groups_count, > + .get_group_name = k210_pc_get_group_name, > + .get_functions_count = k210_pc_get_functions_count, > + .get_function_name = k210_pc_get_function_name, > + .pinmux_set = k210_pc_pinmux_set, > + .pinconf_num_params = ARRAY_SIZE(k210_pc_pinconf_params), > + .pinconf_params = k210_pc_pinconf_params, > + .pinconf_set = k210_pc_pinconf_set, > + .pinconf_group_set = k210_pc_pinconf_group_set, > + .set_state = pinctrl_generic_set_state, > + .get_pin_muxing = k210_pc_get_pin_muxing, > +}; > + > +static int k210_pc_probe(struct udevice *dev) > +{ > + int ret, i, j; > + struct k210_pc_priv *priv = dev_get_priv(dev); > + > + priv->fpioa = dev_read_addr_ptr(dev); > + if (!priv->fpioa) > + return -EINVAL; > + > + ret = clk_get_by_index(dev, 0, &priv->clk); > + if (ret) > + return ret; > + > + ret = clk_enable(&priv->clk); > + if (ret && ret != -ENOSYS && ret != -ENOTSUPP) > + goto err; > + > + priv->sysctl = syscon_regmap_lookup_by_phandle(dev, > "kendryte,sysctl"); > + if (IS_ERR(priv->sysctl)) { > + ret = -ENODEV; > + goto err; > + } > + > + ret = dev_read_u32(dev, "kendryte,power-offset", &priv->power_offset); > + if (ret) > + goto err; > + > + log_debug("fpioa = %p sysctl = %p power offset = %x\n", priv->fpioa, > + (void *)priv->sysctl->ranges[0].start, priv->power_offset); > + > + /* Disable all pins */ > + for (i = 6; i < ARRAY_SIZE(k210_pc_pin_names); i++) > + k210_pc_pinmux_set(dev, i, K210_PCF_CONSTANT); > + > + /* Init input ties */ > + for (i = 0; i < ARRAY_SIZE(priv->fpioa->tie_en); i++) { > + u32 val = 0; > + > + for (j = 0; j < 32; j++) > + if (k210_pcf_infos[i * 32 + j].mode_id == > + K210_PC_DEFAULT_IN_TIE) > + val |= BIT(j); > + writel(val, &priv->fpioa->tie_en[i]); > + writel(val, &priv->fpioa->tie_val[i]); > + } > + > + return 0; > + > +err: > + clk_free(&priv->clk); > + return ret; > +} > + > +static const struct udevice_id k210_pc_ids[] = { > + { .compatible = "kendryte,k210-fpioa" }, > + { } > +}; > + > +U_BOOT_DRIVER(pinctrl_k210) = { > + .name = "pinctrl_k210", > + .id = UCLASS_PINCTRL, > + .of_match = k210_pc_ids, > + .probe = k210_pc_probe, > + .priv_auto_alloc_size = sizeof(struct k210_pc_priv), > + .ops = &k210_pc_pinctrl_ops, > +}; > diff --git a/drivers/pinctrl/kendryte/pinctrl.h > b/drivers/pinctrl/kendryte/pinctrl.h > new file mode 100644 > index 0000000000..de434700c3 > --- /dev/null > +++ b/drivers/pinctrl/kendryte/pinctrl.h > @@ -0,0 +1,325 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * Copyright (C) 2020 Sean Anderson <sean...@gmail.com> > + */ > + > +#ifndef K210_PINCTRL_H > +#define K210_PINCTRL_H > + > +#include <linux/bitfield.h> > + > +/* > + * Full list of PinCtrl Functions from > + * kendryte-standalone-sdk/lib/drivers/include/fpioa.h > + */ > +#define K210_PCF_SHIFT 0 > +#define K210_PCF_MASK GENMASK(7, 0) > +#define K210_PCF_JTAG_TCLK 0 /* JTAG Test Clock */ > +#define K210_PCF_JTAG_TDI 1 /* JTAG Test Data In */ > +#define K210_PCF_JTAG_TMS 2 /* JTAG Test Mode Select */ > +#define K210_PCF_JTAG_TDO 3 /* JTAG Test Data Out */ > +#define K210_PCF_SPI0_D0 4 /* SPI0 Data 0 */ > +#define K210_PCF_SPI0_D1 5 /* SPI0 Data 1 */ > +#define K210_PCF_SPI0_D2 6 /* SPI0 Data 2 */ > +#define K210_PCF_SPI0_D3 7 /* SPI0 Data 3 */ > +#define K210_PCF_SPI0_D4 8 /* SPI0 Data 4 */ > +#define K210_PCF_SPI0_D5 9 /* SPI0 Data 5 */ > +#define K210_PCF_SPI0_D6 10 /* SPI0 Data 6 */ > +#define K210_PCF_SPI0_D7 11 /* SPI0 Data 7 */ > +#define K210_PCF_SPI0_SS0 12 /* SPI0 Chip Select 0 */ > +#define K210_PCF_SPI0_SS1 13 /* SPI0 Chip Select 1 */ > +#define K210_PCF_SPI0_SS2 14 /* SPI0 Chip Select 2 */ > +#define K210_PCF_SPI0_SS3 15 /* SPI0 Chip Select 3 */ > +#define K210_PCF_SPI0_ARB 16 /* SPI0 Arbitration */ > +#define K210_PCF_SPI0_SCLK 17 /* SPI0 Serial Clock */ > +#define K210_PCF_UARTHS_RX 18 /* UART High speed Receiver */ > +#define K210_PCF_UARTHS_TX 19 /* UART High speed Transmitter */ > +#define K210_PCF_RESV6 20 /* Reserved function */ > +#define K210_PCF_RESV7 21 /* Reserved function */ > +#define K210_PCF_CLK_SPI1 22 /* Clock SPI1 */ > +#define K210_PCF_CLK_I2C1 23 /* Clock I2C1 */ > +#define K210_PCF_GPIOHS0 24 /* GPIO High speed 0 */ > +#define K210_PCF_GPIOHS1 25 /* GPIO High speed 1 */ > +#define K210_PCF_GPIOHS2 26 /* GPIO High speed 2 */ > +#define K210_PCF_GPIOHS3 27 /* GPIO High speed 3 */ > +#define K210_PCF_GPIOHS4 28 /* GPIO High speed 4 */ > +#define K210_PCF_GPIOHS5 29 /* GPIO High speed 5 */ > +#define K210_PCF_GPIOHS6 30 /* GPIO High speed 6 */ > +#define K210_PCF_GPIOHS7 31 /* GPIO High speed 7 */ > +#define K210_PCF_GPIOHS8 32 /* GPIO High speed 8 */ > +#define K210_PCF_GPIOHS9 33 /* GPIO High speed 9 */ > +#define K210_PCF_GPIOHS10 34 /* GPIO High speed 10 */ > +#define K210_PCF_GPIOHS11 35 /* GPIO High speed 11 */ > +#define K210_PCF_GPIOHS12 36 /* GPIO High speed 12 */ > +#define K210_PCF_GPIOHS13 37 /* GPIO High speed 13 */ > +#define K210_PCF_GPIOHS14 38 /* GPIO High speed 14 */ > +#define K210_PCF_GPIOHS15 39 /* GPIO High speed 15 */ > +#define K210_PCF_GPIOHS16 40 /* GPIO High speed 16 */ > +#define K210_PCF_GPIOHS17 41 /* GPIO High speed 17 */ > +#define K210_PCF_GPIOHS18 42 /* GPIO High speed 18 */ > +#define K210_PCF_GPIOHS19 43 /* GPIO High speed 19 */ > +#define K210_PCF_GPIOHS20 44 /* GPIO High speed 20 */ > +#define K210_PCF_GPIOHS21 45 /* GPIO High speed 21 */ > +#define K210_PCF_GPIOHS22 46 /* GPIO High speed 22 */ > +#define K210_PCF_GPIOHS23 47 /* GPIO High speed 23 */ > +#define K210_PCF_GPIOHS24 48 /* GPIO High speed 24 */ > +#define K210_PCF_GPIOHS25 49 /* GPIO High speed 25 */ > +#define K210_PCF_GPIOHS26 50 /* GPIO High speed 26 */ > +#define K210_PCF_GPIOHS27 51 /* GPIO High speed 27 */ > +#define K210_PCF_GPIOHS28 52 /* GPIO High speed 28 */ > +#define K210_PCF_GPIOHS29 53 /* GPIO High speed 29 */ > +#define K210_PCF_GPIOHS30 54 /* GPIO High speed 30 */ > +#define K210_PCF_GPIOHS31 55 /* GPIO High speed 31 */ > +#define K210_PCF_GPIO0 56 /* GPIO pin 0 */ > +#define K210_PCF_GPIO1 57 /* GPIO pin 1 */ > +#define K210_PCF_GPIO2 58 /* GPIO pin 2 */ > +#define K210_PCF_GPIO3 59 /* GPIO pin 3 */ > +#define K210_PCF_GPIO4 60 /* GPIO pin 4 */ > +#define K210_PCF_GPIO5 61 /* GPIO pin 5 */ > +#define K210_PCF_GPIO6 62 /* GPIO pin 6 */ > +#define K210_PCF_GPIO7 63 /* GPIO pin 7 */ > +#define K210_PCF_UART1_RX 64 /* UART1 Receiver */ > +#define K210_PCF_UART1_TX 65 /* UART1 Transmitter */ > +#define K210_PCF_UART2_RX 66 /* UART2 Receiver */ > +#define K210_PCF_UART2_TX 67 /* UART2 Transmitter */ > +#define K210_PCF_UART3_RX 68 /* UART3 Receiver */ > +#define K210_PCF_UART3_TX 69 /* UART3 Transmitter */ > +#define K210_PCF_SPI1_D0 70 /* SPI1 Data 0 */ > +#define K210_PCF_SPI1_D1 71 /* SPI1 Data 1 */ > +#define K210_PCF_SPI1_D2 72 /* SPI1 Data 2 */ > +#define K210_PCF_SPI1_D3 73 /* SPI1 Data 3 */ > +#define K210_PCF_SPI1_D4 74 /* SPI1 Data 4 */ > +#define K210_PCF_SPI1_D5 75 /* SPI1 Data 5 */ > +#define K210_PCF_SPI1_D6 76 /* SPI1 Data 6 */ > +#define K210_PCF_SPI1_D7 77 /* SPI1 Data 7 */ > +#define K210_PCF_SPI1_SS0 78 /* SPI1 Chip Select 0 */ > +#define K210_PCF_SPI1_SS1 79 /* SPI1 Chip Select 1 */ > +#define K210_PCF_SPI1_SS2 80 /* SPI1 Chip Select 2 */ > +#define K210_PCF_SPI1_SS3 81 /* SPI1 Chip Select 3 */ > +#define K210_PCF_SPI1_ARB 82 /* SPI1 Arbitration */ > +#define K210_PCF_SPI1_SCLK 83 /* SPI1 Serial Clock */ > +#define K210_PCF_SPI2_D0 84 /* SPI2 Data 0 */ > +#define K210_PCF_SPI2_SS 85 /* SPI2 Select */ > +#define K210_PCF_SPI2_SCLK 86 /* SPI2 Serial Clock */ > +#define K210_PCF_I2S0_MCLK 87 /* I2S0 Master Clock */ > +#define K210_PCF_I2S0_SCLK 88 /* I2S0 Serial Clock(BCLK) */ > +#define K210_PCF_I2S0_WS 89 /* I2S0 Word Select(LRCLK) */ > +#define K210_PCF_I2S0_IN_D0 90 /* I2S0 Serial Data Input 0 */ > +#define K210_PCF_I2S0_IN_D1 91 /* I2S0 Serial Data Input 1 */ > +#define K210_PCF_I2S0_IN_D2 92 /* I2S0 Serial Data Input 2 */ > +#define K210_PCF_I2S0_IN_D3 93 /* I2S0 Serial Data Input 3 */ > +#define K210_PCF_I2S0_OUT_D0 94 /* I2S0 Serial Data Output 0 */ > +#define K210_PCF_I2S0_OUT_D1 95 /* I2S0 Serial Data Output 1 */ > +#define K210_PCF_I2S0_OUT_D2 96 /* I2S0 Serial Data Output 2 */ > +#define K210_PCF_I2S0_OUT_D3 97 /* I2S0 Serial Data Output 3 */ > +#define K210_PCF_I2S1_MCLK 98 /* I2S1 Master Clock */ > +#define K210_PCF_I2S1_SCLK 99 /* I2S1 Serial Clock(BCLK) */ > +#define K210_PCF_I2S1_WS 100 /* I2S1 Word Select(LRCLK) */ > +#define K210_PCF_I2S1_IN_D0 101 /* I2S1 Serial Data Input 0 */ > +#define K210_PCF_I2S1_IN_D1 102 /* I2S1 Serial Data Input 1 */ > +#define K210_PCF_I2S1_IN_D2 103 /* I2S1 Serial Data Input 2 */ > +#define K210_PCF_I2S1_IN_D3 104 /* I2S1 Serial Data Input 3 */ > +#define K210_PCF_I2S1_OUT_D0 105 /* I2S1 Serial Data Output 0 */ > +#define K210_PCF_I2S1_OUT_D1 106 /* I2S1 Serial Data Output 1 */ > +#define K210_PCF_I2S1_OUT_D2 107 /* I2S1 Serial Data Output 2 */ > +#define K210_PCF_I2S1_OUT_D3 108 /* I2S1 Serial Data Output 3 */ > +#define K210_PCF_I2S2_MCLK 109 /* I2S2 Master Clock */ > +#define K210_PCF_I2S2_SCLK 110 /* I2S2 Serial Clock(BCLK) */ > +#define K210_PCF_I2S2_WS 111 /* I2S2 Word Select(LRCLK) */ > +#define K210_PCF_I2S2_IN_D0 112 /* I2S2 Serial Data Input 0 */ > +#define K210_PCF_I2S2_IN_D1 113 /* I2S2 Serial Data Input 1 */ > +#define K210_PCF_I2S2_IN_D2 114 /* I2S2 Serial Data Input 2 */ > +#define K210_PCF_I2S2_IN_D3 115 /* I2S2 Serial Data Input 3 */ > +#define K210_PCF_I2S2_OUT_D0 116 /* I2S2 Serial Data Output 0 */ > +#define K210_PCF_I2S2_OUT_D1 117 /* I2S2 Serial Data Output 1 */ > +#define K210_PCF_I2S2_OUT_D2 118 /* I2S2 Serial Data Output 2 */ > +#define K210_PCF_I2S2_OUT_D3 119 /* I2S2 Serial Data Output 3 */ > +#define K210_PCF_RESV0 120 /* Reserved function */ > +#define K210_PCF_RESV1 121 /* Reserved function */ > +#define K210_PCF_RESV2 122 /* Reserved function */ > +#define K210_PCF_RESV3 123 /* Reserved function */ > +#define K210_PCF_RESV4 124 /* Reserved function */ > +#define K210_PCF_RESV5 125 /* Reserved function */ > +#define K210_PCF_I2C0_SCLK 126 /* I2C0 Serial Clock */ > +#define K210_PCF_I2C0_SDA 127 /* I2C0 Serial Data */ > +#define K210_PCF_I2C1_SCLK 128 /* I2C1 Serial Clock */ > +#define K210_PCF_I2C1_SDA 129 /* I2C1 Serial Data */ > +#define K210_PCF_I2C2_SCLK 130 /* I2C2 Serial Clock */ > +#define K210_PCF_I2C2_SDA 131 /* I2C2 Serial Data */ > +#define K210_PCF_DVP_XCLK 132 /* DVP System Clock */ > +#define K210_PCF_DVP_RST 133 /* DVP System Reset */ > +#define K210_PCF_DVP_PWDN 134 /* DVP Power Down Mode */ > +#define K210_PCF_DVP_VSYNC 135 /* DVP Vertical Sync */ > +#define K210_PCF_DVP_HREF 136 /* DVP Horizontal Reference output */ > +#define K210_PCF_DVP_PCLK 137 /* Pixel Clock */ > +#define K210_PCF_DVP_D0 138 /* Data Bit 0 */ > +#define K210_PCF_DVP_D1 139 /* Data Bit 1 */ > +#define K210_PCF_DVP_D2 140 /* Data Bit 2 */ > +#define K210_PCF_DVP_D3 141 /* Data Bit 3 */ > +#define K210_PCF_DVP_D4 142 /* Data Bit 4 */ > +#define K210_PCF_DVP_D5 143 /* Data Bit 5 */ > +#define K210_PCF_DVP_D6 144 /* Data Bit 6 */ > +#define K210_PCF_DVP_D7 145 /* Data Bit 7 */ > +#define K210_PCF_SCCB_SCLK 146 /* Serial Camera Control Bus Clock */ > +#define K210_PCF_SCCB_SDA 147 /* Serial Camera Control Bus Data */ > +#define K210_PCF_UART1_CTS 148 /* UART1 Clear To Send */ > +#define K210_PCF_UART1_DSR 149 /* UART1 Data Set Ready */ > +#define K210_PCF_UART1_DCD 150 /* UART1 Data Carrier Detect */ > +#define K210_PCF_UART1_RI 151 /* UART1 Ring Indicator */ > +#define K210_PCF_UART1_SIR_IN 152 /* UART1 Serial Infrared Input */ > +#define K210_PCF_UART1_DTR 153 /* UART1 Data Terminal Ready */ > +#define K210_PCF_UART1_RTS 154 /* UART1 Request To Send */ > +#define K210_PCF_UART1_OUT2 155 /* UART1 User-designated Output 2 */ > +#define K210_PCF_UART1_OUT1 156 /* UART1 User-designated Output 1 */ > +#define K210_PCF_UART1_SIR_OUT 157 /* UART1 Serial Infrared Output */ > +#define K210_PCF_UART1_BAUD 158 /* UART1 Transmit Clock Output */ > +#define K210_PCF_UART1_RE 159 /* UART1 Receiver Output Enable */ > +#define K210_PCF_UART1_DE 160 /* UART1 Driver Output Enable */ > +#define K210_PCF_UART1_RS485_EN 161 /* UART1 RS485 Enable */ > +#define K210_PCF_UART2_CTS 162 /* UART2 Clear To Send */ > +#define K210_PCF_UART2_DSR 163 /* UART2 Data Set Ready */ > +#define K210_PCF_UART2_DCD 164 /* UART2 Data Carrier Detect */ > +#define K210_PCF_UART2_RI 165 /* UART2 Ring Indicator */ > +#define K210_PCF_UART2_SIR_IN 166 /* UART2 Serial Infrared Input */ > +#define K210_PCF_UART2_DTR 167 /* UART2 Data Terminal Ready */ > +#define K210_PCF_UART2_RTS 168 /* UART2 Request To Send */ > +#define K210_PCF_UART2_OUT2 169 /* UART2 User-designated Output 2 */ > +#define K210_PCF_UART2_OUT1 170 /* UART2 User-designated Output 1 */ > +#define K210_PCF_UART2_SIR_OUT 171 /* UART2 Serial Infrared Output */ > +#define K210_PCF_UART2_BAUD 172 /* UART2 Transmit Clock Output */ > +#define K210_PCF_UART2_RE 173 /* UART2 Receiver Output Enable */ > +#define K210_PCF_UART2_DE 174 /* UART2 Driver Output Enable */ > +#define K210_PCF_UART2_RS485_EN 175 /* UART2 RS485 Enable */ > +#define K210_PCF_UART3_CTS 176 /* UART3 Clear To Send */ > +#define K210_PCF_UART3_DSR 177 /* UART3 Data Set Ready */ > +#define K210_PCF_UART3_DCD 178 /* UART3 Data Carrier Detect */ > +#define K210_PCF_UART3_RI 179 /* UART3 Ring Indicator */ > +#define K210_PCF_UART3_SIR_IN 180 /* UART3 Serial Infrared Input */ > +#define K210_PCF_UART3_DTR 181 /* UART3 Data Terminal Ready */ > +#define K210_PCF_UART3_RTS 182 /* UART3 Request To Send */ > +#define K210_PCF_UART3_OUT2 183 /* UART3 User-designated Output 2 */ > +#define K210_PCF_UART3_OUT1 184 /* UART3 User-designated Output 1 */ > +#define K210_PCF_UART3_SIR_OUT 185 /* UART3 Serial Infrared Output */ > +#define K210_PCF_UART3_BAUD 186 /* UART3 Transmit Clock Output */ > +#define K210_PCF_UART3_RE 187 /* UART3 Receiver Output Enable */ > +#define K210_PCF_UART3_DE 188 /* UART3 Driver Output Enable */ > +#define K210_PCF_UART3_RS485_EN 189 /* UART3 RS485 Enable */ > +#define K210_PCF_TIMER0_TOGGLE1 190 /* TIMER0 Toggle Output 1 */ > +#define K210_PCF_TIMER0_TOGGLE2 191 /* TIMER0 Toggle Output 2 */ > +#define K210_PCF_TIMER0_TOGGLE3 192 /* TIMER0 Toggle Output 3 */ > +#define K210_PCF_TIMER0_TOGGLE4 193 /* TIMER0 Toggle Output 4 */ > +#define K210_PCF_TIMER1_TOGGLE1 194 /* TIMER1 Toggle Output 1 */ > +#define K210_PCF_TIMER1_TOGGLE2 195 /* TIMER1 Toggle Output 2 */ > +#define K210_PCF_TIMER1_TOGGLE3 196 /* TIMER1 Toggle Output 3 */ > +#define K210_PCF_TIMER1_TOGGLE4 197 /* TIMER1 Toggle Output 4 */ > +#define K210_PCF_TIMER2_TOGGLE1 198 /* TIMER2 Toggle Output 1 */ > +#define K210_PCF_TIMER2_TOGGLE2 199 /* TIMER2 Toggle Output 2 */ > +#define K210_PCF_TIMER2_TOGGLE3 200 /* TIMER2 Toggle Output 3 */ > +#define K210_PCF_TIMER2_TOGGLE4 201 /* TIMER2 Toggle Output 4 */ > +#define K210_PCF_CLK_SPI2 202 /* Clock SPI2 */ > +#define K210_PCF_CLK_I2C2 203 /* Clock I2C2 */ > +#define K210_PCF_INTERNAL0 204 /* Internal function signal 0 */ > +#define K210_PCF_INTERNAL1 205 /* Internal function signal 1 */ > +#define K210_PCF_INTERNAL2 206 /* Internal function signal 2 */ > +#define K210_PCF_INTERNAL3 207 /* Internal function signal 3 */ > +#define K210_PCF_INTERNAL4 208 /* Internal function signal 4 */ > +#define K210_PCF_INTERNAL5 209 /* Internal function signal 5 */ > +#define K210_PCF_INTERNAL6 210 /* Internal function signal 6 */ > +#define K210_PCF_INTERNAL7 211 /* Internal function signal 7 */ > +#define K210_PCF_INTERNAL8 212 /* Internal function signal 8 */ > +#define K210_PCF_INTERNAL9 213 /* Internal function signal 9 */ > +#define K210_PCF_INTERNAL10 214 /* Internal function signal 10 */ > +#define K210_PCF_INTERNAL11 215 /* Internal function signal 11 */ > +#define K210_PCF_INTERNAL12 216 /* Internal function signal 12 */ > +#define K210_PCF_INTERNAL13 217 /* Internal function signal 13 */ > +#define K210_PCF_INTERNAL14 218 /* Internal function signal 14 */ > +#define K210_PCF_INTERNAL15 219 /* Internal function signal 15 */ > +#define K210_PCF_INTERNAL16 220 /* Internal function signal 16 */ > +#define K210_PCF_INTERNAL17 221 /* Internal function signal 17 */ > +#define K210_PCF_CONSTANT 222 /* Constant function */ > +#define K210_PCF_INTERNAL18 223 /* Internal function signal 18 */ > +#define K210_PCF_DEBUG0 224 /* Debug function 0 */ > +#define K210_PCF_DEBUG1 225 /* Debug function 1 */ > +#define K210_PCF_DEBUG2 226 /* Debug function 2 */ > +#define K210_PCF_DEBUG3 227 /* Debug function 3 */ > +#define K210_PCF_DEBUG4 228 /* Debug function 4 */ > +#define K210_PCF_DEBUG5 229 /* Debug function 5 */ > +#define K210_PCF_DEBUG6 230 /* Debug function 6 */ > +#define K210_PCF_DEBUG7 231 /* Debug function 7 */ > +#define K210_PCF_DEBUG8 232 /* Debug function 8 */ > +#define K210_PCF_DEBUG9 233 /* Debug function 9 */ > +#define K210_PCF_DEBUG10 234 /* Debug function 10 */ > +#define K210_PCF_DEBUG11 235 /* Debug function 11 */ > +#define K210_PCF_DEBUG12 236 /* Debug function 12 */ > +#define K210_PCF_DEBUG13 237 /* Debug function 13 */ > +#define K210_PCF_DEBUG14 238 /* Debug function 14 */ > +#define K210_PCF_DEBUG15 239 /* Debug function 15 */ > +#define K210_PCF_DEBUG16 240 /* Debug function 16 */ > +#define K210_PCF_DEBUG17 241 /* Debug function 17 */ > +#define K210_PCF_DEBUG18 242 /* Debug function 18 */ > +#define K210_PCF_DEBUG19 243 /* Debug function 19 */ > +#define K210_PCF_DEBUG20 244 /* Debug function 20 */ > +#define K210_PCF_DEBUG21 245 /* Debug function 21 */ > +#define K210_PCF_DEBUG22 246 /* Debug function 22 */ > +#define K210_PCF_DEBUG23 247 /* Debug function 23 */ > +#define K210_PCF_DEBUG24 248 /* Debug function 24 */ > +#define K210_PCF_DEBUG25 249 /* Debug function 25 */ > +#define K210_PCF_DEBUG26 250 /* Debug function 26 */ > +#define K210_PCF_DEBUG27 251 /* Debug function 27 */ > +#define K210_PCF_DEBUG28 252 /* Debug function 28 */ > +#define K210_PCF_DEBUG29 253 /* Debug function 29 */ > +#define K210_PCF_DEBUG30 254 /* Debug function 30 */ > +#define K210_PCF_DEBUG31 255 /* Debug function 31 */ > + > +/* > + * The K210 only implements 8 drive levels, even though there is register > space > + * for 16 > + */ > +#define K210_PC_DRIVE_SHIFT 8 > +#define K210_PC_DRIVE_MASK GENMASK(11, 8) > +#define K210_PC_DRIVE_0 (0 << K210_PC_DRIVE_SHIFT) > +#define K210_PC_DRIVE_1 (1 << K210_PC_DRIVE_SHIFT) > +#define K210_PC_DRIVE_2 (2 << K210_PC_DRIVE_SHIFT) > +#define K210_PC_DRIVE_3 (3 << K210_PC_DRIVE_SHIFT) > +#define K210_PC_DRIVE_4 (4 << K210_PC_DRIVE_SHIFT) > +#define K210_PC_DRIVE_5 (5 << K210_PC_DRIVE_SHIFT) > +#define K210_PC_DRIVE_6 (6 << K210_PC_DRIVE_SHIFT) > +#define K210_PC_DRIVE_7 (7 << K210_PC_DRIVE_SHIFT) > +#define K210_PC_DRIVE_MAX 7 > + > +#define K210_PC_MODE_MASK GENMASK(23, 12) > +/* > + * output enabled == PC_OE & (PC_OE_INV ^ FUNCTION_OE) where FUNCTION_OE is a > + * physical signal from the function > + */ > +#define K210_PC_OE BIT(12) /* Output Enable */ > +#define K210_PC_OE_INV BIT(13) /* INVert function-controlled Output Enable > */ > +#define K210_PC_DO_OE BIT(14) /* set Data Out to the Output Enable signal > */ > +#define K210_PC_DO_INV BIT(15) /* INVert final Data Output */ > +#define K210_PC_PU BIT(16) /* Pull Up */ > +#define K210_PC_PD BIT(17) /* Pull Down */ > +/* Strong pull up not implemented on K210 */ > +#define K210_PC_SL BIT(19) /* reduce SLew rate to prevent overshoot */ > +/* Same semantics as OE above */ > +#define K210_PC_IE BIT(20) /* Input Enable */ > +#define K210_PC_IE_INV BIT(21) /* INVert function-controlled Input Enable > */ > +#define K210_PC_DI_INV BIT(22) /* INVert Data Input */ > +#define K210_PC_ST BIT(23) /* Schmitt Trigger */ > +#define K210_PC_DI BIT(31) /* raw Data Input */ > +#define K210_PC_BIAS_MASK (K210_PC_PU & K210_PC_PD) > + > +#define K210_PC_MODE_IN (K210_PC_IE | K210_PC_ST) > +#define K210_PC_MODE_OUT (K210_PC_DRIVE_7 | K210_PC_OE) > +#define K210_PC_MODE_I2C (K210_PC_MODE_IN | K210_PC_IE_INV | K210_PC_SL | \ > + K210_PC_OE | K210_PC_OE_INV | K210_PC_PU) > +#define K210_PC_MODE_SPI (K210_PC_MODE_IN | K210_PC_IE_INV | \ > + K210_PC_MODE_OUT | K210_PC_OE_INV) > +#define K210_PC_MODE_GPIO (K210_PC_MODE_IN | K210_PC_MODE_OUT) > + > +struct k210_fpioa { > + u32 pins[48]; > + u32 tie_en[8]; > + u32 tie_val[8]; > +}; > + > +#endif /* K210_PINCTRL_H */ > diff --git a/include/dt-bindings/pinctrl/k210-pinctrl.h > b/include/dt-bindings/pinctrl/k210-pinctrl.h > new file mode 100644 > index 0000000000..6d44ea765b > --- /dev/null > +++ b/include/dt-bindings/pinctrl/k210-pinctrl.h > @@ -0,0 +1,12 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * Copyright (C) 2020 Sean Anderson <sean...@gmail.com> > + */ > + > +#ifndef DT_K210_PINCTRL_H > +#define DT_K210_PINCTRL_H > + > +#define K210_PC_POWER_3V3 0 > +#define K210_PC_POWER_1V8 1 > + > +#endif /* DT_K210_PINCTRL_H */ > -- > 2.25.0 >