2023-08-08 17:02:30

by larry.lai

[permalink] [raw]
Subject: [PATCH V5 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA

The UP Squared board <http://www.upboard.com> implements certain
features (pin control) through an on-board FPGA.

Reported-by: kernel test robot <[email protected]>
Signed-off-by: Gary Wang <[email protected]>
Signed-off-by: larry.lai <[email protected]>
---
PATCH V4 -> PATCH V5
(1) Fixed kernel test robot compiler warning.
(2) Synchronizing upboard github to v1.0.5 tag.
RFC 2023/04/25 -> PATCH V4
(1) Fixed kernel test robot compiler warning.
(2) Remove mistakes with wrong Reviewed-by tags.
RFC 2022/11/23 -> RFC 2023/04/25
(1) Refer 2022/12/08 Andy Shevchenko review, cleaned up coding style and
addressed review comments.
PATCH V3 -> RFC 2022/11/23:
(1) Refer 2022/11/09 Linus Walleij review, cleaned up coding style and
addressed review comments.
PATCH V2 -> V3:
There's no change.
PATCH V1 -> V2:
(1) Synchronized with upboard github to rc2
(2) Refer 2022/10/19 Mark Brown and Andy Shevchenko review, we removed
the regmap and acpi patches and implement in upboard pinctrl driver.
(3) Refer 2022/10/19 Andy Shevchenko review, fixed the coding style
issues, removed using gpio_xxxx API and removed including <linux/gpio.h>.
---
---
drivers/pinctrl/Kconfig | 14 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-upboard.c | 1377 +++++++++++++++++++++++++++++
3 files changed, 1392 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-upboard.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 1cf74b0c42e5..cc8dae75289b 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -483,6 +483,20 @@ config PINCTRL_THUNDERBAY
rate control and direction control. This module will be
called as pinctrl-thunderbay.

+config PINCTRL_UPBOARD
+ tristate "UP board FPGA pin controller"
+ depends on (X86 && ACPI) || COMPILE_TEST
+ depends on MFD_INTEL_UPBOARD_FPGA
+ select GENERIC_PINCONF
+ select PINMUX
+ select PINCONF
+ help
+ Pin controller for the FPGA GPIO lines on UP boards. Due to the
+ hardware layout, these are meant to be controlled in tandem with their
+ corresponding Intel SoC GPIOs.
+ To compile this driver as a module, choose M here: the module
+ will be called pinctrl-upboard.
+
config PINCTRL_ZYNQ
bool "Pinctrl driver for Xilinx Zynq"
depends on ARCH_ZYNQ
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index e76f5cdc64b0..c366706d36e7 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o
obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o
obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_THUNDERBAY) += pinctrl-thunderbay.o
+obj-$(CONFIG_PINCTRL_UPBOARD) += pinctrl-upboard.o
obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o

diff --git a/drivers/pinctrl/pinctrl-upboard.c b/drivers/pinctrl/pinctrl-upboard.c
new file mode 100644
index 000000000000..ce59b6d5d100
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-upboard.c
@@ -0,0 +1,1377 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * UP Board HAT pin controller driver
+ * remapping native pin to RPI pin and set CPLD pin dir
+ *
+ * Copyright (c) AAEON. All rights reserved.
+ *
+ * Authors: Gary Wang <[email protected]>
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/mfd/upboard-fpga.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+
+#include "core.h"
+#include "intel/pinctrl-intel.h"
+
+/* for older kernel lost DIRECTION_IN/OUT definition */
+#ifndef GPIO_LINE_DIRECTION_IN
+#define GPIO_LINE_DIRECTION_IN 1
+#define GPIO_LINE_DIRECTION_OUT 0
+#endif
+
+/* Offset from regs */
+#define REVID 0x000
+#define REVID_SHIFT 16
+#define REVID_MASK GENMASK(31, 16)
+#define PADBAR 0x00c
+
+/* Offset from pad_regs */
+#define PADCFG0 0x000
+#define PADCFG0_RXEVCFG_SHIFT 25
+#define PADCFG0_RXEVCFG_MASK GENMASK(26, 25)
+#define PADCFG0_RXEVCFG_LEVEL 0
+#define PADCFG0_RXEVCFG_EDGE 1
+#define PADCFG0_RXEVCFG_DISABLED 2
+#define PADCFG0_RXEVCFG_EDGE_BOTH 3
+#define PADCFG0_PREGFRXSEL BIT(24)
+#define PADCFG0_RXINV BIT(23)
+#define PADCFG0_GPIROUTIOXAPIC BIT(20)
+#define PADCFG0_GPIROUTSCI BIT(19)
+#define PADCFG0_GPIROUTSMI BIT(18)
+#define PADCFG0_GPIROUTNMI BIT(17)
+#define PADCFG0_PMODE_SHIFT 10
+#define PADCFG0_PMODE_MASK GENMASK(13, 10)
+#define PADCFG0_PMODE_GPIO 0
+#define PADCFG0_GPIORXDIS BIT(9)
+#define PADCFG0_GPIOTXDIS BIT(8)
+#define PADCFG0_GPIORXSTATE BIT(1)
+#define PADCFG0_GPIOTXSTATE BIT(0)
+
+#define PADCFG1 0x004
+#define PADCFG1_TERM_UP BIT(13)
+#define PADCFG1_TERM_SHIFT 10
+#define PADCFG1_TERM_MASK GENMASK(12, 10)
+#define PADCFG1_TERM_20K BIT(2)
+#define PADCFG1_TERM_5K BIT(1)
+#define PADCFG1_TERM_1K BIT(0)
+#define PADCFG1_TERM_833 (BIT(1) | BIT(0))
+
+#define PADCFG2 0x008
+#define PADCFG2_DEBEN BIT(0)
+#define PADCFG2_DEBOUNCE_SHIFT 1
+#define PADCFG2_DEBOUNCE_MASK GENMASK(4, 1)
+
+#define DEBOUNCE_PERIOD_NSEC 31250
+
+/* Additional features supported by the hardware */
+#define PINCTRL_FEATURE_DEBOUNCE BIT(0)
+#define PINCTRL_FEATURE_1K_PD BIT(1)
+
+#define BOARD_UP_CHT01 0
+#define BOARD_UP_APL01 1
+#define BOARD_UP_UPCORE 2
+#define BOARD_UP_CORE_PLUS 3
+#define BOARD_AIOT_IP6801 4
+#define BOARD_UP_WHL01 5
+#define BOARD_UP_ISH 7
+#define BOARD_UPN_APL 8
+#define BOARD_UP_APL03 9
+#define BOARD_UPX_WHLite 10
+#define BOARD_UPX_TGL 11
+#define BOARD_UPX_EDGE_WHL2 12
+#define BOARD_UPN_EHL01 13
+#define BOARD_UPS_EHL01 BOARD_UPN_EHL01
+#define BOARD_UPX_ADLP01 15
+#define BOARD_UPN_ADLN01 16
+#define BOARD_UPS_ADLP01 BOARD_UPX_ADLP01
+#define BOARD_UP_ADLN01 BOARD_UPN_ADLN01
+
+struct upboard_pin {
+ struct regmap_field *funcbit;
+ struct regmap_field *enbit;
+ struct regmap_field *dirbit;
+ /* native pin controllers: number, base, irq */
+ unsigned int gpio;
+ unsigned int base;
+ int irq;
+ void __iomem *regs;
+};
+
+struct upboard_pinctrl {
+ struct gpio_chip chip;
+ struct device *dev;
+ struct pinctrl_dev *pctldev;
+ struct pinctrl_desc *pctldesc;
+ struct upboard_pin *pins;
+ struct regmap *regmap;
+ const unsigned int *rpi_mapping;
+ int ident;
+};
+
+enum upboard_func0_fpgabit {
+ UPFPGA_I2C0_EN = 8,
+ UPFPGA_I2C1_EN = 9,
+ UPFPGA_CEC0_EN = 12,
+ UPFPGA_ADC0_EN = 14,
+};
+
+static const struct reg_field upboard_i2c0_reg =
+ REG_FIELD(UPFPGA_REG_FUNC_EN0, UPFPGA_I2C0_EN, UPFPGA_I2C0_EN);
+
+static const struct reg_field upboard_i2c1_reg =
+ REG_FIELD(UPFPGA_REG_FUNC_EN0, UPFPGA_I2C1_EN, UPFPGA_I2C1_EN);
+
+static const struct reg_field upboard_adc0_reg =
+ REG_FIELD(UPFPGA_REG_FUNC_EN0, UPFPGA_ADC0_EN, UPFPGA_ADC0_EN);
+
+/* Pin group information */
+struct upboard_pingroup {
+ const char *name;
+ const unsigned int *pins;
+ size_t npins;
+};
+
+/* Pin function information */
+struct upboard_function {
+ const char *name;
+ const char * const *groups;
+ size_t ngroups;
+};
+
+#define UPBOARD_BIT_TO_PIN(r, bit) \
+ ((r) * UPFPGA_REGISTER_SIZE + (bit))
+
+/*
+ * UP board data
+ */
+
+#define UPBOARD_UP_BIT_TO_PIN(r, id) (UPBOARD_BIT_TO_PIN(r, UPFPGA_UP_##id))
+
+#define UPBOARD_UP_PIN_ANON(r, bit) \
+ { \
+ .number = UPBOARD_BIT_TO_PIN(r, bit), \
+ }
+
+#define UPBOARD_UP_PIN_NAME(r, id) \
+ { \
+ .number = UPBOARD_UP_BIT_TO_PIN(r, id), \
+ .name = #id, \
+ }
+
+#define UPBOARD_UP_PIN_FUNC(r, id, data) \
+ { \
+ .number = UPBOARD_UP_BIT_TO_PIN(r, id), \
+ .name = #id, \
+ .drv_data = (void *)(data), \
+ }
+
+#define UPBOARD_PIN_GROUP(n, p) \
+ { \
+ .name = (n), \
+ .pins = (p), \
+ .npins = ARRAY_SIZE((p)), \
+ }
+
+#define FUNCTION(n, g) \
+ { \
+ .name = (n), \
+ .groups = (g), \
+ .ngroups = ARRAY_SIZE((g)), \
+ }
+
+enum upboard_up_reg1_fpgabit {
+ UPFPGA_UP_I2C1_SDA,
+ UPFPGA_UP_I2C1_SCL,
+ UPFPGA_UP_ADC0,
+ UPFPGA_UP_GPIO17,
+ UPFPGA_UP_GPIO27,
+ UPFPGA_UP_GPIO22,
+ UPFPGA_UP_SPI_MOSI,
+ UPFPGA_UP_SPI_MISO,
+ UPFPGA_UP_SPI_CLK,
+ UPFPGA_UP_I2C0_SDA,
+ UPFPGA_UP_GPIO5,
+ UPFPGA_UP_GPIO6,
+ UPFPGA_UP_PWM1,
+ UPFPGA_UP_I2S_FRM,
+ UPFPGA_UP_GPIO26,
+ UPFPGA_UP_UART1_TX,
+};
+
+enum upboard_up_reg2_fpgabit {
+ UPFPGA_UP_UART1_RX,
+ UPFPGA_UP_I2S_CLK,
+ UPFPGA_UP_GPIO23,
+ UPFPGA_UP_GPIO24,
+ UPFPGA_UP_GPIO25,
+ UPFPGA_UP_SPI_CS0,
+ UPFPGA_UP_SPI_CS1,
+ UPFPGA_UP_I2C0_SCL,
+ UPFPGA_UP_PWM0,
+ UPFPGA_UP_GPIO16,
+ UPFPGA_UP_I2S_DIN,
+ UPFPGA_UP_I2S_DOUT,
+};
+
+#define UPFPGA_UP_UART1_RTS UPFPGA_UP_GPIO17
+#define UPFPGA_UP_UART1_CTS UPFPGA_UP_GPIO16
+
+static struct pinctrl_pin_desc upboard_up_pins[] = {
+ UPBOARD_UP_PIN_FUNC(0, I2C1_SDA, &upboard_i2c1_reg),
+ UPBOARD_UP_PIN_FUNC(0, I2C1_SCL, &upboard_i2c1_reg),
+ UPBOARD_UP_PIN_FUNC(0, ADC0, &upboard_adc0_reg),
+ UPBOARD_UP_PIN_NAME(0, UART1_RTS),
+ UPBOARD_UP_PIN_NAME(0, GPIO27),
+ UPBOARD_UP_PIN_NAME(0, GPIO22),
+ UPBOARD_UP_PIN_NAME(0, SPI_MOSI),
+ UPBOARD_UP_PIN_NAME(0, SPI_MISO),
+ UPBOARD_UP_PIN_NAME(0, SPI_CLK),
+ UPBOARD_UP_PIN_FUNC(0, I2C0_SDA, &upboard_i2c0_reg),
+ UPBOARD_UP_PIN_NAME(0, GPIO5),
+ UPBOARD_UP_PIN_NAME(0, GPIO6),
+ UPBOARD_UP_PIN_NAME(0, PWM1),
+ UPBOARD_UP_PIN_NAME(0, I2S_FRM),
+ UPBOARD_UP_PIN_NAME(0, GPIO26),
+ UPBOARD_UP_PIN_NAME(0, UART1_TX),
+ /* register 1 */
+ UPBOARD_UP_PIN_NAME(1, UART1_RX),
+ UPBOARD_UP_PIN_NAME(1, I2S_CLK),
+ UPBOARD_UP_PIN_NAME(1, GPIO23),
+ UPBOARD_UP_PIN_NAME(1, GPIO24),
+ UPBOARD_UP_PIN_NAME(1, GPIO25),
+ UPBOARD_UP_PIN_NAME(1, SPI_CS0),
+ UPBOARD_UP_PIN_NAME(1, SPI_CS1),
+ UPBOARD_UP_PIN_FUNC(1, I2C0_SCL, &upboard_i2c0_reg),
+ UPBOARD_UP_PIN_NAME(1, PWM0),
+ UPBOARD_UP_PIN_NAME(1, UART1_CTS),
+ UPBOARD_UP_PIN_NAME(1, I2S_DIN),
+ UPBOARD_UP_PIN_NAME(1, I2S_DOUT),
+};
+
+static const unsigned int upboard_up_rpi_mapping[] = {
+ UPBOARD_UP_BIT_TO_PIN(0, I2C0_SDA),
+ UPBOARD_UP_BIT_TO_PIN(1, I2C0_SCL),
+ UPBOARD_UP_BIT_TO_PIN(0, I2C1_SDA),
+ UPBOARD_UP_BIT_TO_PIN(0, I2C1_SCL),
+ UPBOARD_UP_BIT_TO_PIN(0, ADC0),
+ UPBOARD_UP_BIT_TO_PIN(0, GPIO5),
+ UPBOARD_UP_BIT_TO_PIN(0, GPIO6),
+ UPBOARD_UP_BIT_TO_PIN(1, SPI_CS1),
+ UPBOARD_UP_BIT_TO_PIN(1, SPI_CS0),
+ UPBOARD_UP_BIT_TO_PIN(0, SPI_MISO),
+ UPBOARD_UP_BIT_TO_PIN(0, SPI_MOSI),
+ UPBOARD_UP_BIT_TO_PIN(0, SPI_CLK),
+ UPBOARD_UP_BIT_TO_PIN(1, PWM0),
+ UPBOARD_UP_BIT_TO_PIN(0, PWM1),
+ UPBOARD_UP_BIT_TO_PIN(0, UART1_TX),
+ UPBOARD_UP_BIT_TO_PIN(1, UART1_RX),
+ UPBOARD_UP_BIT_TO_PIN(1, GPIO16),
+ UPBOARD_UP_BIT_TO_PIN(0, GPIO17),
+ UPBOARD_UP_BIT_TO_PIN(1, I2S_CLK),
+ UPBOARD_UP_BIT_TO_PIN(0, I2S_FRM),
+ UPBOARD_UP_BIT_TO_PIN(1, I2S_DIN),
+ UPBOARD_UP_BIT_TO_PIN(1, I2S_DOUT),
+ UPBOARD_UP_BIT_TO_PIN(0, GPIO22),
+ UPBOARD_UP_BIT_TO_PIN(1, GPIO23),
+ UPBOARD_UP_BIT_TO_PIN(1, GPIO24),
+ UPBOARD_UP_BIT_TO_PIN(1, GPIO25),
+ UPBOARD_UP_BIT_TO_PIN(0, GPIO26),
+ UPBOARD_UP_BIT_TO_PIN(0, GPIO27),
+};
+
+static const unsigned int uart1_pins[] = { 14, 15, 16, 17 };
+static const unsigned int uart2_pins[] = { 25, 27 };
+static const unsigned int i2c0_pins[] = { 0, 1 };
+static const unsigned int i2c1_pins[] = { 2, 3 };
+static const unsigned int spi2_pins[] = { 8, 9, 10, 11 };
+static const unsigned int i2s0_pins[] = { 18, 19, 20, 21 };
+static const unsigned int pwm0_pins[] = { 12 };
+static const unsigned int pwm1_pins[] = { 13 };
+static const unsigned int adc0_pins[] = { 4 };
+
+static const struct upboard_pingroup pin_groups[] = {
+ UPBOARD_PIN_GROUP("uart1_grp", uart1_pins),
+ UPBOARD_PIN_GROUP("uart2_grp", uart2_pins),
+ UPBOARD_PIN_GROUP("i2c0_grp", i2c0_pins),
+ UPBOARD_PIN_GROUP("i2c1_grp", i2c1_pins),
+ UPBOARD_PIN_GROUP("spi2_grp", spi2_pins),
+ UPBOARD_PIN_GROUP("i2s0_grp", i2s0_pins),
+ UPBOARD_PIN_GROUP("pwm0_grp", pwm0_pins),
+ UPBOARD_PIN_GROUP("pwm1_grp", pwm1_pins),
+ UPBOARD_PIN_GROUP("adc0_grp", adc0_pins),
+};
+
+static const char * const uart1_groups[] = { "uart1_grp" };
+static const char * const uart2_groups[] = { "uart2_grp" };
+static const char * const i2c0_groups[] = { "i2c0_grp" };
+static const char * const i2c1_groups[] = { "i2c1_grp" };
+static const char * const spi2_groups[] = { "spi2_grp" };
+static const char * const i2s0_groups[] = { "i2s0_grp" };
+static const char * const pwm0_groups[] = { "pwm0_grp" };
+static const char * const pwm1_groups[] = { "pwm1_grp" };
+static const char * const adc0_groups[] = { "adc0_grp" };
+
+static const struct upboard_function pin_functions[] = {
+ FUNCTION("uart1", uart1_groups),
+ FUNCTION("uart2", uart2_groups),
+ FUNCTION("i2c0", i2c0_groups),
+ FUNCTION("i2c1", i2c1_groups),
+ FUNCTION("spi2", spi2_groups),
+ FUNCTION("i2s0", i2s0_groups),
+ FUNCTION("pwm0", pwm0_groups),
+ FUNCTION("pwm1", pwm1_groups),
+ FUNCTION("adc0", adc0_groups),
+};
+
+/*
+ * UP^2 board data
+ */
+
+#define UPBOARD_UP2_BIT_TO_PIN(r, id) (UPBOARD_BIT_TO_PIN(r, UPFPGA_UP2_##id))
+
+#define UPBOARD_UP2_PIN_MUX(r, bit, data) \
+ { \
+ .number = UPBOARD_BIT_TO_PIN(r, bit), \
+ .name = "PINMUX", \
+ .drv_data = (void *)(data), \
+ }
+
+#define UPBOARD_UP2_PIN_NAME(r, id) \
+ { \
+ .number = UPBOARD_UP2_BIT_TO_PIN(r, id), \
+ .name = #id, \
+ }
+
+#define UPBOARD_UP2_PIN_FUNC(r, id, data) \
+ { \
+ .number = UPBOARD_UP2_BIT_TO_PIN(r, id), \
+ .name = #id, \
+ .drv_data = (void *)(data), \
+ }
+
+enum upboard_up2_reg0_fpgabit {
+ UPFPGA_UP2_UART1_TXD,
+ UPFPGA_UP2_UART1_RXD,
+ UPFPGA_UP2_UART1_RTS,
+ UPFPGA_UP2_UART1_CTS,
+ UPFPGA_UP2_GPIO3_ADC0,
+ UPFPGA_UP2_GPIO5_ADC2,
+ UPFPGA_UP2_GPIO6_ADC3,
+ UPFPGA_UP2_GPIO11,
+ UPFPGA_UP2_EXHAT_LVDS1n,
+ UPFPGA_UP2_EXHAT_LVDS1p,
+ UPFPGA_UP2_SPI2_TXD,
+ UPFPGA_UP2_SPI2_RXD,
+ UPFPGA_UP2_SPI2_FS1,
+ UPFPGA_UP2_SPI2_FS0,
+ UPFPGA_UP2_SPI2_CLK,
+ UPFPGA_UP2_SPI1_TXD,
+};
+
+enum upboard_up2_reg1_fpgabit {
+ UPFPGA_UP2_SPI1_RXD,
+ UPFPGA_UP2_SPI1_FS1,
+ UPFPGA_UP2_SPI1_FS0,
+ UPFPGA_UP2_SPI1_CLK,
+ UPFPGA_UP2_BIT20,
+ UPFPGA_UP2_BIT21,
+ UPFPGA_UP2_BIT22,
+ UPFPGA_UP2_BIT23,
+ UPFPGA_UP2_PWM1,
+ UPFPGA_UP2_PWM0,
+ UPFPGA_UP2_EXHAT_LVDS0n,
+ UPFPGA_UP2_EXHAT_LVDS0p,
+ UPFPGA_UP2_I2C0_SCL,
+ UPFPGA_UP2_I2C0_SDA,
+ UPFPGA_UP2_I2C1_SCL,
+ UPFPGA_UP2_I2C1_SDA,
+};
+
+enum upboard_up2_reg2_fpgabit {
+ UPFPGA_UP2_EXHAT_LVDS3n,
+ UPFPGA_UP2_EXHAT_LVDS3p,
+ UPFPGA_UP2_EXHAT_LVDS4n,
+ UPFPGA_UP2_EXHAT_LVDS4p,
+ UPFPGA_UP2_EXHAT_LVDS5n,
+ UPFPGA_UP2_EXHAT_LVDS5p,
+ UPFPGA_UP2_I2S_SDO,
+ UPFPGA_UP2_I2S_SDI,
+ UPFPGA_UP2_I2S_WS_SYNC,
+ UPFPGA_UP2_I2S_BCLK,
+ UPFPGA_UP2_EXHAT_LVDS6n,
+ UPFPGA_UP2_EXHAT_LVDS6p,
+ UPFPGA_UP2_EXHAT_LVDS7n,
+ UPFPGA_UP2_EXHAT_LVDS7p,
+ UPFPGA_UP2_EXHAT_LVDS2n,
+ UPFPGA_UP2_EXHAT_LVDS2p,
+};
+
+static struct pinctrl_pin_desc upboard_up2_pins[] = {
+ UPBOARD_UP2_PIN_NAME(0, UART1_TXD),
+ UPBOARD_UP2_PIN_NAME(0, UART1_RXD),
+ UPBOARD_UP2_PIN_NAME(0, UART1_RTS),
+ UPBOARD_UP2_PIN_NAME(0, UART1_CTS),
+ UPBOARD_UP2_PIN_NAME(0, GPIO3_ADC0),
+ UPBOARD_UP2_PIN_NAME(0, GPIO5_ADC2),
+ UPBOARD_UP2_PIN_NAME(0, GPIO6_ADC3),
+ UPBOARD_UP2_PIN_NAME(0, GPIO11),
+ UPBOARD_UP2_PIN_NAME(0, EXHAT_LVDS1n),
+ UPBOARD_UP2_PIN_NAME(0, EXHAT_LVDS1p),
+ UPBOARD_UP2_PIN_NAME(0, SPI2_TXD),
+ UPBOARD_UP2_PIN_NAME(0, SPI2_RXD),
+ UPBOARD_UP2_PIN_NAME(0, SPI2_FS1),
+ UPBOARD_UP2_PIN_NAME(0, SPI2_FS0),
+ UPBOARD_UP2_PIN_NAME(0, SPI2_CLK),
+ UPBOARD_UP2_PIN_NAME(0, SPI1_TXD),
+ UPBOARD_UP2_PIN_NAME(1, SPI1_RXD),
+ UPBOARD_UP2_PIN_NAME(1, SPI1_FS1),
+ UPBOARD_UP2_PIN_NAME(1, SPI1_FS0),
+ UPBOARD_UP2_PIN_NAME(1, SPI1_CLK),
+ UPBOARD_UP2_PIN_MUX(1, 4, &upboard_i2c0_reg),
+ UPBOARD_UP2_PIN_MUX(1, 5, &upboard_i2c0_reg),
+ UPBOARD_UP2_PIN_MUX(1, 6, &upboard_i2c1_reg),
+ UPBOARD_UP2_PIN_MUX(1, 7, &upboard_i2c1_reg),
+ UPBOARD_UP2_PIN_NAME(1, PWM1),
+ UPBOARD_UP2_PIN_NAME(1, PWM0),
+ UPBOARD_UP2_PIN_NAME(1, EXHAT_LVDS0n),
+ UPBOARD_UP2_PIN_NAME(1, EXHAT_LVDS0p),
+ UPBOARD_UP2_PIN_FUNC(1, I2C0_SCL, &upboard_i2c0_reg),
+ UPBOARD_UP2_PIN_FUNC(1, I2C0_SDA, &upboard_i2c0_reg),
+ UPBOARD_UP2_PIN_FUNC(1, I2C1_SCL, &upboard_i2c1_reg),
+ UPBOARD_UP2_PIN_FUNC(1, I2C1_SDA, &upboard_i2c1_reg),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS3n),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS3p),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS4n),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS4p),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS5n),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS5p),
+ UPBOARD_UP2_PIN_NAME(2, I2S_SDO),
+ UPBOARD_UP2_PIN_NAME(2, I2S_SDI),
+ UPBOARD_UP2_PIN_NAME(2, I2S_WS_SYNC),
+ UPBOARD_UP2_PIN_NAME(2, I2S_BCLK),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS6n),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS6p),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS7n),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS7p),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS2n),
+ UPBOARD_UP2_PIN_NAME(2, EXHAT_LVDS2p),
+};
+
+static const unsigned int upboard_up2_rpi_mapping[] = {
+ UPBOARD_UP2_BIT_TO_PIN(1, I2C0_SDA),
+ UPBOARD_UP2_BIT_TO_PIN(1, I2C0_SCL),
+ UPBOARD_UP2_BIT_TO_PIN(1, I2C1_SDA),
+ UPBOARD_UP2_BIT_TO_PIN(1, I2C1_SCL),
+ UPBOARD_UP2_BIT_TO_PIN(0, GPIO3_ADC0),
+ UPBOARD_UP2_BIT_TO_PIN(0, GPIO11),
+ UPBOARD_UP2_BIT_TO_PIN(0, SPI2_CLK),
+ UPBOARD_UP2_BIT_TO_PIN(1, SPI1_FS1),
+ UPBOARD_UP2_BIT_TO_PIN(1, SPI1_FS0),
+ UPBOARD_UP2_BIT_TO_PIN(1, SPI1_RXD),
+ UPBOARD_UP2_BIT_TO_PIN(0, SPI1_TXD),
+ UPBOARD_UP2_BIT_TO_PIN(1, SPI1_CLK),
+ UPBOARD_UP2_BIT_TO_PIN(1, PWM0),
+ UPBOARD_UP2_BIT_TO_PIN(1, PWM1),
+ UPBOARD_UP2_BIT_TO_PIN(0, UART1_TXD),
+ UPBOARD_UP2_BIT_TO_PIN(0, UART1_RXD),
+ UPBOARD_UP2_BIT_TO_PIN(0, UART1_CTS),
+ UPBOARD_UP2_BIT_TO_PIN(0, UART1_RTS),
+ UPBOARD_UP2_BIT_TO_PIN(2, I2S_BCLK),
+ UPBOARD_UP2_BIT_TO_PIN(2, I2S_WS_SYNC),
+ UPBOARD_UP2_BIT_TO_PIN(2, I2S_SDI),
+ UPBOARD_UP2_BIT_TO_PIN(2, I2S_SDO),
+ UPBOARD_UP2_BIT_TO_PIN(0, GPIO6_ADC3),
+ UPBOARD_UP2_BIT_TO_PIN(0, SPI2_FS1),
+ UPBOARD_UP2_BIT_TO_PIN(0, SPI2_RXD),
+ UPBOARD_UP2_BIT_TO_PIN(0, SPI2_TXD),
+ UPBOARD_UP2_BIT_TO_PIN(0, SPI2_FS0),
+ UPBOARD_UP2_BIT_TO_PIN(0, GPIO5_ADC2),
+};
+
+/*
+ * UP Core board + CREX carrier board data
+ */
+
+#define UPBOARD_UPCORE_CREX_BIT_TO_PIN(r, id) \
+ (UPBOARD_BIT_TO_PIN(r, UPFPGA_UPCORE_CREX_##id))
+
+#define UPBOARD_UPCORE_CREX_PIN_ANON(r, bit) \
+ { \
+ .number = UPBOARD_BIT_TO_PIN(r, bit), \
+ }
+
+#define UPBOARD_UPCORE_CREX_PIN_NAME(r, id) \
+ { \
+ .number = UPBOARD_UPCORE_CREX_BIT_TO_PIN(r, id), \
+ .name = #id, \
+ }
+
+#define UPBOARD_UPCORE_CREX_PIN_FUNC(r, id, data) \
+ { \
+ .number = UPBOARD_UPCORE_CREX_BIT_TO_PIN(r, id), \
+ .name = #id, \
+ .drv_data = (void *)(data), \
+ }
+
+enum upboard_upcore_crex_reg1_fpgabit {
+ UPFPGA_UPCORE_CREX_I2C0_SDA,
+ UPFPGA_UPCORE_CREX_I2C0_SCL,
+ UPFPGA_UPCORE_CREX_I2C1_SDA,
+ UPFPGA_UPCORE_CREX_I2C1_SCL,
+ UPFPGA_UPCORE_CREX_SPI2_CS0,
+ UPFPGA_UPCORE_CREX_SPI2_CS1,
+ UPFPGA_UPCORE_CREX_SPI2_MOSI,
+ UPFPGA_UPCORE_CREX_SPI2_MISO,
+ UPFPGA_UPCORE_CREX_SPI2_CLK,
+ UPFPGA_UPCORE_CREX_UART1_TXD,
+ UPFPGA_UPCORE_CREX_UART1_RXD,
+ UPFPGA_UPCORE_CREX_PWM0,
+ UPFPGA_UPCORE_CREX_PWM1,
+ UPFPGA_UPCORE_CREX_I2S2_FRM,
+ UPFPGA_UPCORE_CREX_I2S2_CLK,
+ UPFPGA_UPCORE_CREX_I2S2_RX,
+};
+
+enum upboard_upcore_crex_reg2_fpgabit {
+ UPFPGA_UPCORE_CREX_I2S2_TX,
+ UPFPGA_UPCORE_CREX_GPIO0,
+ UPFPGA_UPCORE_CREX_GPIO2,
+ UPFPGA_UPCORE_CREX_GPIO3,
+ UPFPGA_UPCORE_CREX_GPIO4,
+ UPFPGA_UPCORE_CREX_GPIO9,
+};
+
+static struct pinctrl_pin_desc upboard_upcore_crex_pins[] = {
+ UPBOARD_UPCORE_CREX_PIN_FUNC(0, I2C0_SDA, &upboard_i2c0_reg),
+ UPBOARD_UPCORE_CREX_PIN_FUNC(0, I2C0_SCL, &upboard_i2c0_reg),
+ UPBOARD_UPCORE_CREX_PIN_FUNC(0, I2C1_SDA, &upboard_i2c1_reg),
+ UPBOARD_UPCORE_CREX_PIN_FUNC(0, I2C1_SCL, &upboard_i2c1_reg),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_CS0),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_CS1),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_MOSI),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_MISO),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, SPI2_CLK),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, UART1_TXD),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, UART1_RXD),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, PWM0),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, PWM1),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, I2S2_FRM),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, I2S2_CLK),
+ UPBOARD_UPCORE_CREX_PIN_NAME(0, I2S2_RX),
+ /* register 1 */
+ UPBOARD_UPCORE_CREX_PIN_NAME(1, I2S2_TX),
+ UPBOARD_UPCORE_CREX_PIN_NAME(1, GPIO0),
+ UPBOARD_UPCORE_CREX_PIN_FUNC(1, GPIO2, &upboard_adc0_reg),
+ UPBOARD_UPCORE_CREX_PIN_NAME(1, GPIO3),
+ UPBOARD_UPCORE_CREX_PIN_NAME(1, GPIO4),
+ UPBOARD_UPCORE_CREX_PIN_NAME(1, GPIO9),
+};
+
+static unsigned int upboard_upcore_crex_rpi_mapping[] = {
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2C0_SDA),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2C0_SCL),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2C1_SDA),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2C1_SCL),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO0),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO2),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO3),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_CS1),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_CS0),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_MISO),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_MOSI),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, SPI2_CLK),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, PWM0),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, PWM1),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, UART1_TXD),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, UART1_RXD),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO9),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, GPIO4),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2S2_CLK),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2S2_FRM),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(0, I2S2_RX),
+ UPBOARD_UPCORE_CREX_BIT_TO_PIN(1, I2S2_TX),
+};
+
+/*
+ * UP Core board + CRST02 carrier board data
+ */
+
+#define upboard_upcore_crst02_pins upboard_upcore_crex_pins
+#define upboard_upcore_crst02_rpi_mapping upboard_upcore_crex_rpi_mapping
+
+static int upboard_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
+ unsigned int group)
+{
+ return 0;
+}
+
+static int upboard_fpga_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin)
+{
+ const struct pin_desc * const pd = pin_desc_get(pctldev, pin);
+ const struct upboard_pin *p;
+ int ret;
+
+ p = pd->drv_data;
+ if (p->funcbit) {
+ ret = regmap_field_write(p->funcbit, 0);
+ if (ret)
+ return ret;
+ }
+
+ if (p->enbit) {
+ ret = regmap_field_write(p->enbit, 1);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int upboard_fpga_request_free(struct pinctrl_dev *pctldev,
+ unsigned int pin)
+{
+ const struct pin_desc * const pd = pin_desc_get(pctldev, pin);
+ const struct upboard_pin *p;
+ int ret;
+
+ p = pd->drv_data;
+ if (p->funcbit) {
+ ret = regmap_field_write(p->funcbit, 1);
+ if (ret)
+ return ret;
+ }
+
+ if (p->enbit) {
+ ret = regmap_field_write(p->enbit, 0);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int upboard_fpga_set_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin, bool input)
+{
+ const struct pin_desc * const pd = pin_desc_get(pctldev, pin);
+ const struct upboard_pin *p;
+
+ p = pd->drv_data;
+
+ return regmap_field_write(p->dirbit, input);
+}
+
+static int upboard_get_functions_count(struct pinctrl_dev *pctldev)
+{
+ return 0;
+}
+
+static const char *upboard_get_function_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ return NULL;
+}
+
+static int upboard_get_function_groups(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const char * const **groups,
+ unsigned int *num_groups)
+{
+ *groups = NULL;
+ *num_groups = 0;
+ return 0;
+}
+
+static const struct pinmux_ops upboard_pinmux_ops = {
+ .get_functions_count = upboard_get_functions_count,
+ .get_function_groups = upboard_get_function_groups,
+ .get_function_name = upboard_get_function_name,
+ .set_mux = upboard_set_mux,
+ .gpio_request_enable = upboard_fpga_request_enable,
+ .gpio_set_direction = upboard_fpga_set_direction,
+};
+
+static int upboard_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ return 0;
+}
+
+static const char *upboard_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int selector)
+{
+ return NULL;
+}
+
+static void upboard_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int pin)
+{
+ struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+ void __iomem *padcfg;
+ u32 cfg0, cfg1, mode;
+ int locked;
+
+ if (pctrl->pins[pin].regs == NULL)
+ return;
+
+ cfg0 = readl(pctrl->pins[pin].regs);
+ cfg1 = readl(pctrl->pins[pin].regs + PADCFG1);
+
+ mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
+ if (mode == PADCFG0_PMODE_GPIO)
+ seq_puts(s, "GPIO ");
+ else
+ seq_printf(s, "mode %d ", mode);
+
+ seq_printf(s, "0x%08x 0x%08x", cfg0, cfg1);
+
+ /* Dump the additional PADCFG registers if available */
+ padcfg = pctrl->pins[pin].regs + PADCFG2;
+ if (padcfg)
+ seq_printf(s, " 0x%08x", readl(padcfg));
+
+ seq_printf(s, " 0x%08x", pctrl->pins[pin].regs);
+}
+
+static const struct pinctrl_ops upboard_pinctrl_ops = {
+ .get_groups_count = upboard_get_groups_count,
+ .get_group_name = upboard_get_group_name,
+ .pin_dbg_show = upboard_pin_dbg_show,
+};
+
+static struct pinctrl_desc upboard_up_pinctrl_desc = {
+ .pins = upboard_up_pins,
+ .npins = ARRAY_SIZE(upboard_up_pins),
+ .pctlops = &upboard_pinctrl_ops,
+ .pmxops = &upboard_pinmux_ops,
+ .owner = THIS_MODULE,
+};
+
+static struct pinctrl_desc upboard_up2_pinctrl_desc = {
+ .pins = upboard_up2_pins,
+ .npins = ARRAY_SIZE(upboard_up2_pins),
+ .pctlops = &upboard_pinctrl_ops,
+ .pmxops = &upboard_pinmux_ops,
+ .owner = THIS_MODULE,
+};
+
+static struct pinctrl_desc upboard_upcore_crex_pinctrl_desc = {
+ .pins = upboard_upcore_crex_pins,
+ .npins = ARRAY_SIZE(upboard_upcore_crex_pins),
+ .pctlops = &upboard_pinctrl_ops,
+ .pmxops = &upboard_pinmux_ops,
+ .owner = THIS_MODULE,
+};
+
+static struct pinctrl_desc upboard_upcore_crst02_pinctrl_desc = {
+ .pins = upboard_upcore_crst02_pins,
+ .npins = ARRAY_SIZE(upboard_upcore_crst02_pins),
+ .pctlops = &upboard_pinctrl_ops,
+ .pmxops = &upboard_pinmux_ops,
+ .owner = THIS_MODULE,
+};
+
+static void upboard_alt_func_enable(struct gpio_chip *gc, const char *name, int id)
+{
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ int offset[pctrl->pctldesc->npins];
+ int i, cnt;
+
+ /* find all pins */
+ for (i = 0, cnt = 0; i < pctrl->pctldesc->npins; i++) {
+ if (strstr(pctrl->pctldesc->pins[i].name, name))
+ offset[cnt++] = i;
+ }
+
+ /* change to alternate function */
+ for (i = 0; i < cnt; i++) {
+ if (pctrl->pins[offset[i]].regs == NULL)
+ continue;
+ bool input = false;
+ int mode = 0; /* default GPIO */
+ unsigned int val = readl(pctrl->pins[offset[i]].regs);
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2C") ||
+ strstr(pctrl->pctldesc->pins[offset[i]].name, "PINMUX")) {
+ mode = 1;
+ switch (id) {
+ case BOARD_UPN_ADLN01:
+ case BOARD_UPX_ADLP01:
+ mode = 2;
+ break;
+ default:
+ break;
+ }
+
+ val |= mode<<PADCFG0_PMODE_SHIFT;
+ writel(val, pctrl->pins[offset[i]].regs);
+ upboard_fpga_request_free(pctrl->pctldev, offset[i]);
+ continue;
+ }
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "UART")) {
+ mode = 1;
+ switch (id) {
+ case BOARD_UPN_EHL01:
+ mode = 4;
+ break;
+ case BOARD_UPN_ADLN01:
+ case BOARD_UPX_ADLP01:
+ mode = 2;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SPI")) {
+ mode = 1;
+ switch (id) {
+ case BOARD_UP_WHL01:
+ mode = 3;
+ break;
+ case BOARD_UPN_ADLN01:
+ case BOARD_UPX_ADLP01:
+ mode = 7;
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MOSI")) {
+ val &= ~PADCFG0_GPIOTXDIS;
+ val |= PADCFG0_GPIORXDIS;
+ }
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO"))
+ val |= PADCFG0_GPIORXDIS;
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CLK")) {
+ val &= ~PADCFG0_GPIOTXDIS;
+ val |= PADCFG0_GPIORXDIS;
+ }
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS0"))
+ val |= PADCFG0_GPIORXDIS;
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS1"))
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2S")) {
+ mode = 1;
+ switch (id) {
+ case BOARD_UPX_ADLP01:
+ mode = 4;
+ break;
+ default:
+ break;
+ }
+ }
+
+ val |= mode<<PADCFG0_PMODE_SHIFT;
+ writel(val, pctrl->pins[offset[i]].regs);
+
+ /* input pins */
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "RX"))
+ input = true;
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CTS"))
+ input = true;
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "ADC")) {
+ input = true;
+ if (id == BOARD_UP_APL01)
+ upboard_fpga_request_enable(pctrl->pctldev, NULL, offset[i]);
+ else
+ upboard_fpga_request_free(pctrl->pctldev, offset[i]);
+ }
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO"))
+ input = true;
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "DIN"))
+ input = true;
+
+ if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SDI"))
+ input = true;
+
+ upboard_fpga_set_direction(pctrl->pctldev, NULL, offset[i], input);
+ }
+}
+
+static int upboard_rpi_to_native_gpio(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ unsigned int pin = pctrl->rpi_mapping[gpio];
+ struct pinctrl_gpio_range *range;
+
+ range = pinctrl_find_gpio_range_from_pin(pctrl->pctldev, pin);
+ if (!range)
+ return -ENODEV;
+
+ return range->base;
+}
+
+static int upboard_gpio_request(struct gpio_chip *gc, unsigned int offset)
+{
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ unsigned int pin = pctrl->rpi_mapping[offset];
+ int gpio = upboard_rpi_to_native_gpio(gc, offset);
+
+ upboard_fpga_request_enable(pctrl->pctldev, NULL, pin);
+ return pinctrl_gpio_request(gpio);
+}
+
+static void upboard_gpio_free(struct gpio_chip *gc, unsigned int offset)
+{
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ int gpio = upboard_rpi_to_native_gpio(gc, offset);
+ unsigned int pin = pctrl->rpi_mapping[offset];
+
+ pinctrl_gpio_free(gpio);
+
+ upboard_alt_func_enable(gc, pctrl->pctldesc->pins[pin].name, pctrl->ident);
+}
+
+static int upboard_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ unsigned int pin = pctrl->rpi_mapping[offset];
+
+ if (!pctrl->pins[pin].regs)
+ return -EINVAL;
+
+ unsigned int padcfg0 = readl(pctrl->pins[pin].regs);
+
+ if (padcfg0 & PADCFG0_GPIOTXDIS)
+ return GPIO_LINE_DIRECTION_IN;
+
+ return GPIO_LINE_DIRECTION_OUT;
+}
+
+static int upboard_gpio_get(struct gpio_chip *gc, unsigned int offset)
+{
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ unsigned int pin = pctrl->rpi_mapping[offset];
+ int gpio = upboard_rpi_to_native_gpio(gc, offset);
+
+ if (gpio < 0)
+ return gpio;
+
+ /* APL03 board open drain GPIO */
+ if (pctrl->ident == BOARD_UP_APL03) {
+ int val = 0;
+
+ switch (pin) {
+ case 0:
+ case 1:
+ case 9:
+ case 23:
+ val = readl(pctrl->pins[pin].regs);
+ return val & 0x00000003;
+ default:
+ break;
+ }
+ }
+
+ return gpiod_get_value(gpio_to_desc(gpio));
+}
+
+static void upboard_gpio_set(struct gpio_chip *gc, unsigned int offset,
+ int value)
+{
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ unsigned int pin = pctrl->rpi_mapping[offset];
+ int gpio = upboard_rpi_to_native_gpio(gc, offset);
+
+ if (gpio < 0)
+ return;
+
+ /* APL03 board open drain GPIO */
+ if (pctrl->ident == BOARD_UP_APL03) {
+ int val = 0;
+
+ switch (pin) {
+ case 0:
+ case 1:
+ case 9:
+ case 23:
+ val = readl(pctrl->pins[pin].regs);
+
+ if (value)
+ val |= PADCFG0_GPIOTXDIS;
+ else
+ val &= ~PADCFG0_GPIOTXDIS;
+
+ writel(val, pctrl->pins[pin].regs);
+ break;
+ default:
+ break;
+ }
+ }
+
+ gpiod_set_value(gpio_to_desc(gpio), value);
+}
+
+static int upboard_gpio_direction_input(struct gpio_chip *gc,
+ unsigned int offset)
+{
+ int gpio = upboard_rpi_to_native_gpio(gc, offset);
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ unsigned int pin = pctrl->rpi_mapping[offset];
+
+ upboard_fpga_set_direction(pctrl->pctldev, NULL, pin, true);
+
+ return pinctrl_gpio_direction_input(gpio);
+}
+
+static int upboard_gpio_direction_output(struct gpio_chip *gc,
+ unsigned int offset, int value)
+{
+ int gpio = upboard_rpi_to_native_gpio(gc, offset);
+ struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
+ unsigned int pin = pctrl->rpi_mapping[offset];
+
+ upboard_fpga_set_direction(pctrl->pctldev, NULL, pin, false);
+
+ return pinctrl_gpio_direction_output(gpio);
+}
+
+static void __iomem *upboard_get_regs(struct gpio_chip *gc, unsigned int gpio, unsigned int reg)
+{
+ struct platform_device *pdev = to_platform_device(gc->parent);
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct intel_pinctrl *pctrl = gpiochip_get_data(gc);
+ size_t nregs;
+ void __iomem *base = NULL;
+ u32 offset, value;
+ int pin = gpio-gc->base;
+
+ /* check Intel pin controller for all platform */
+ if (pctrl->ncommunities > 1) {
+ int i, j, offset = 0;
+
+ pin = -1;
+ for (i = 0; i < pctrl->ncommunities; i++) {
+ struct intel_community *community = &pctrl->communities[i];
+
+ for (j = 0; j < community->ngpps ; j++) {
+ struct intel_padgroup gpps = community->gpps[j];
+
+ if (gpio < gc->base + gpps.gpio_base + gpps.size) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM,
+ community->barno);
+ pin = gpio-gc->base-gpps.gpio_base +
+ offset-community->pin_base;
+ break;
+ }
+
+ offset += gpps.size;
+ }
+
+ if (pin != -1)
+ break;
+ }
+ }
+
+ base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (base == NULL)
+ return base;
+
+ offset = readl(base + PADBAR);
+ value = readl(base + REVID);
+
+ if (((value & REVID_MASK) >> REVID_SHIFT) >= 0x94)
+ nregs = 4;
+ else
+ nregs = 2;
+
+ return base + offset + reg + pin * nregs * 4;
+}
+
+int upboard_acpi_node_pin_mapping(struct upboard_fpga *fpga,
+ struct upboard_pinctrl *pctrl,
+ const char *propname,
+ const char *pinctl_name,
+ unsigned int pin_offset)
+{
+ struct gpio_descs *descs;
+ int ret, i;
+
+ descs = devm_gpiod_get_array(fpga->dev, propname, GPIOD_ASIS);
+ if (IS_ERR(descs)) {
+ ret = PTR_ERR(descs);
+ if (ret != -EPROBE_DEFER)
+ dev_err(fpga->dev, "Failed to get %s gpios", propname);
+
+ return ret;
+ }
+
+ for (i = 0; i < descs->ndescs; i++) {
+ struct gpio_desc *desc = descs->desc[i];
+ struct gpio_chip *gc = gpiod_to_chip(desc);
+
+ pctrl->pins[i].gpio = desc_to_gpio(desc);
+ pctrl->pins[i].base = gc->base;
+ pctrl->pins[i].irq = gpiod_to_irq(desc);
+ pctrl->pins[i].regs =
+ upboard_get_regs(gc,
+ desc_to_gpio(desc) - gc->base,
+ PADCFG0);
+
+ /* The GPIOs may not be contiguous, so add them 1-by-1 */
+ ret = gpiochip_add_pin_range(gpiod_to_chip(desc), pinctl_name,
+ desc_to_gpio(desc) - gc->base,
+ pin_offset + i, 1);
+ if (ret)
+ return ret;
+ }
+
+ /* dispose acpi resource */
+ devm_gpiod_put_array(fpga->dev, descs);
+
+ return ret;
+}
+
+static struct gpio_chip upboard_gpio_chip = {
+ .label = "Raspberry Pi compatible UP GPIO",
+ .base = 0,
+ .request = upboard_gpio_request,
+ .free = upboard_gpio_free,
+ .get = upboard_gpio_get,
+ .set = upboard_gpio_set,
+ .get_direction = upboard_gpio_get_direction,
+ .direction_input = upboard_gpio_direction_input,
+ .direction_output = upboard_gpio_direction_output,
+ .owner = THIS_MODULE,
+};
+
+/* DMI Matches for older bios without fpga initialization */
+static const struct dmi_system_id upboard_dmi_table[] __initconst = {
+ {
+ .ident = BOARD_UP_APL03,
+ .matches = { /* UP 4000 */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-APL03"),
+ },
+ },
+ {
+ .ident = BOARD_UP_WHL01,
+ .matches = { /* UPX WHL */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-WHL01"),
+ },
+ },
+ {
+ .ident = BOARD_UPX_TGL,
+ .matches = { /* UP i11 */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPX-TGL01"),
+ },
+ },
+ {
+ .ident = BOARD_UPN_EHL01,
+ .matches = { /* UP 6000 */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-EHL01"),
+ },
+ },
+ {
+ .ident = BOARD_UPS_EHL01,
+ .matches = { /* UP squared v2 */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPS-EHL01"),
+ },
+ },
+ {
+ .ident = BOARD_UPX_ADLP01,
+ .matches = { /* UP Xtreme i12 */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPX-ADLP01"),
+ },
+ },
+ {
+ .ident = BOARD_UPN_ADLN01,
+ .matches = { /* UP 7000 */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-ADLN01"),
+ },
+ },
+ {
+ .ident = BOARD_UPS_ADLP01,
+ .matches = { /* UP Squared i12 */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPS-ADLP01"),
+ },
+ },
+ {
+ .ident = BOARD_UP_ADLN01,
+ .matches = { /* UP 7000 */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-ADLN01"),
+ },
+ },
+ { } /* Terminating entry */
+};
+
+static int __init upboard_pinctrl_probe(struct platform_device *pdev)
+{
+ struct upboard_fpga * const fpga = dev_get_drvdata(pdev->dev.parent);
+ struct acpi_device * const adev = ACPI_COMPANION(&pdev->dev);
+ struct pinctrl_desc *pctldesc;
+ struct upboard_pinctrl *pctrl;
+ struct upboard_pin *pins;
+ const struct dmi_system_id *system_id;
+ const char *hid;
+ const unsigned int *rpi_mapping;
+ unsigned int ngpio;
+ int ret;
+ int i;
+
+ if (!fpga)
+ return -EINVAL;
+
+ if (!adev)
+ return -ENODEV;
+
+ /* set pin desc and rpi GPIO mapping table by HID */
+ hid = acpi_device_hid(adev);
+ if (!strcmp(hid, "AANT0F00") || !strcmp(hid, "AANT0F04") ||
+ !strcmp(hid, "AANT0000")) {
+ pctldesc = &upboard_up_pinctrl_desc;
+ rpi_mapping = upboard_up_rpi_mapping;
+ ngpio = ARRAY_SIZE(upboard_up_rpi_mapping);
+ } else if (!strcmp(hid, "AANT0F01")) {
+ pctldesc = &upboard_up2_pinctrl_desc;
+ rpi_mapping = upboard_up2_rpi_mapping;
+ ngpio = ARRAY_SIZE(upboard_up2_rpi_mapping);
+ } else if (!strcmp(hid, "AANT0F02")) {
+ pctldesc = &upboard_upcore_crex_pinctrl_desc;
+ rpi_mapping = upboard_upcore_crex_rpi_mapping;
+ ngpio = ARRAY_SIZE(upboard_upcore_crex_rpi_mapping);
+ } else if (!strcmp(hid, "AANT0F03")) {
+ pctldesc = &upboard_upcore_crst02_pinctrl_desc;
+ rpi_mapping = upboard_upcore_crst02_rpi_mapping;
+ ngpio = ARRAY_SIZE(upboard_upcore_crst02_rpi_mapping);
+ } else
+ return -ENODEV;
+
+ pctldesc->name = dev_name(&pdev->dev);
+
+ pins = devm_kcalloc(&pdev->dev, pctldesc->npins, sizeof(*pins), GFP_KERNEL);
+ if (!pins)
+ return -ENOMEM;
+
+ /* initialise pins */
+ for (i = 0; i < pctldesc->npins; i++) {
+ struct upboard_pin *pin = &pins[i];
+ struct pinctrl_pin_desc *pd = (struct pinctrl_pin_desc *) &pctldesc->pins[i];
+ struct reg_field fldconf = {0};
+ unsigned int regoff = (pd->number / UPFPGA_REGISTER_SIZE);
+ unsigned int lsb = pd->number % UPFPGA_REGISTER_SIZE;
+
+ pin->funcbit = NULL;
+
+ if (pd->drv_data) {
+ fldconf = *(struct reg_field *)pd->drv_data;
+
+ pin->funcbit = devm_regmap_field_alloc(&pdev->dev,
+ fpga->regmap,
+ fldconf);
+ if (IS_ERR(pin->funcbit))
+ return PTR_ERR(pin->funcbit);
+ }
+
+ fldconf.reg = UPFPGA_REG_GPIO_EN0 + regoff;
+ fldconf.lsb = lsb;
+ fldconf.msb = lsb;
+
+ pin->enbit = devm_regmap_field_alloc(&pdev->dev,
+ fpga->regmap,
+ fldconf);
+ if (IS_ERR(pin->enbit))
+ return PTR_ERR(pin->enbit);
+
+ fldconf.reg = UPFPGA_REG_GPIO_DIR0 + regoff;
+ fldconf.lsb = lsb;
+ fldconf.msb = lsb;
+
+ pin->dirbit = devm_regmap_field_alloc(&pdev->dev,
+ fpga->regmap,
+ fldconf);
+ if (IS_ERR(pin->dirbit))
+ return PTR_ERR(pin->dirbit);
+
+ pd->drv_data = pin;
+ }
+
+ /* create a new pinctrl device and register it */
+ pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+ if (!pctrl)
+ return -ENOMEM;
+
+ pctrl->rpi_mapping = rpi_mapping;
+ pctrl->chip = upboard_gpio_chip;
+ pctrl->pctldesc = pctldesc;
+ pctrl->chip.parent = &pdev->dev;
+ pctrl->chip.ngpio = ngpio;
+ pctrl->pins = pins;
+
+ ret = devm_gpiochip_add_data(&pdev->dev, &pctrl->chip, pctrl);
+ if (ret)
+ return ret;
+
+ pctrl->pctldev = devm_pinctrl_register(&pdev->dev, pctldesc, pctrl);
+ if (IS_ERR(pctrl->pctldev))
+ return PTR_ERR(pctrl->pctldev);
+
+ /* add acpi pin mapping according to external-gpios key */
+ ret = upboard_acpi_node_pin_mapping(fpga, pctrl,
+ "external",
+ dev_name(&pdev->dev),
+ 0);
+ if (ret)
+ return ret;
+
+ /* check for special board versions that require register patches */
+ system_id = dmi_first_match(upboard_dmi_table);
+ if (system_id)
+ pctrl->ident = system_id->ident;
+ else
+ pctrl->ident = BOARD_UP_APL03;
+
+ upboard_alt_func_enable(&pctrl->chip, "I2C", pctrl->ident);
+ upboard_alt_func_enable(&pctrl->chip, "SPI", pctrl->ident);
+ upboard_alt_func_enable(&pctrl->chip, "UART", pctrl->ident);
+ upboard_alt_func_enable(&pctrl->chip, "I2S", pctrl->ident);
+ upboard_alt_func_enable(&pctrl->chip, "PWM", pctrl->ident);
+ upboard_alt_func_enable(&pctrl->chip, "ADC", pctrl->ident);
+
+ return ret;
+}
+
+static struct platform_driver upboard_pinctrl_driver = {
+ .driver = {
+ .name = "upboard-pinctrl",
+ },
+};
+module_platform_driver_probe(upboard_pinctrl_driver, upboard_pinctrl_probe);
+
+MODULE_AUTHOR("Gary Wang <[email protected]>");
+MODULE_DESCRIPTION("UP Board HAT pin controller driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:upboard-pinctrl");
--
2.17.1



2023-08-10 05:48:16

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH V5 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA

Hi larry.lai,

kernel test robot noticed the following build warnings:

[auto build test WARNING on lee-mfd/for-mfd-fixes]
[also build test WARNING on pavel-leds/for-next]
[cannot apply to lee-mfd/for-mfd-next linusw-pinctrl/devel linusw-pinctrl/for-next linus/master v6.5-rc5 next-20230809]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/larry-lai/pinctrl-Add-support-pin-control-for-UP-board-CPLD-FPGA/20230809-013857
base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-fixes
patch link: https://lore.kernel.org/r/20230808145601.9401-3-larry.lai%40yunjingtech.com
patch subject: [PATCH V5 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA
config: i386-allyesconfig (https://download.01.org/0day-ci/archive/20230810/[email protected]/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce: (https://download.01.org/0day-ci/archive/20230810/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_pin_dbg_show':
drivers/pinctrl/pinctrl-upboard.c:737:17: error: implicit declaration of function 'seq_puts' [-Werror=implicit-function-declaration]
737 | seq_puts(s, "GPIO ");
| ^~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:739:17: error: implicit declaration of function 'seq_printf'; did you mean 'bstr_printf'? [-Werror=implicit-function-declaration]
739 | seq_printf(s, "mode %d ", mode);
| ^~~~~~~~~~
| bstr_printf
>> drivers/pinctrl/pinctrl-upboard.c:727:13: warning: unused variable 'locked' [-Wunused-variable]
727 | int locked;
| ^~~~~~
drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_alt_func_enable':
>> drivers/pinctrl/pinctrl-upboard.c:792:9: warning: ISO C90 forbids variable length array 'offset' [-Wvla]
792 | int offset[pctrl->pctldesc->npins];
| ^~~
>> drivers/pinctrl/pinctrl-upboard.c:805:17: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
805 | bool input = false;
| ^~~~
drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_gpio_request':
drivers/pinctrl/pinctrl-upboard.c:936:16: error: implicit declaration of function 'pinctrl_gpio_request'; did you mean 'upboard_gpio_request'? [-Werror=implicit-function-declaration]
936 | return pinctrl_gpio_request(gpio);
| ^~~~~~~~~~~~~~~~~~~~
| upboard_gpio_request
drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_gpio_free':
drivers/pinctrl/pinctrl-upboard.c:945:9: error: implicit declaration of function 'pinctrl_gpio_free' [-Werror=implicit-function-declaration]
945 | pinctrl_gpio_free(gpio);
| ^~~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_gpio_get_direction':
drivers/pinctrl/pinctrl-upboard.c:958:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
958 | unsigned int padcfg0 = readl(pctrl->pins[pin].regs);
| ^~~~~~~~
drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_gpio_direction_input':
drivers/pinctrl/pinctrl-upboard.c:1039:16: error: implicit declaration of function 'pinctrl_gpio_direction_input'; did you mean 'upboard_gpio_direction_input'? [-Werror=implicit-function-declaration]
1039 | return pinctrl_gpio_direction_input(gpio);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| upboard_gpio_direction_input
drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_gpio_direction_output':
drivers/pinctrl/pinctrl-upboard.c:1051:16: error: implicit declaration of function 'pinctrl_gpio_direction_output'; did you mean 'upboard_gpio_direction_output'? [-Werror=implicit-function-declaration]
1051 | return pinctrl_gpio_direction_output(gpio);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| upboard_gpio_direction_output
drivers/pinctrl/pinctrl-upboard.c: At top level:
>> drivers/pinctrl/pinctrl-upboard.c:1106:5: warning: no previous prototype for 'upboard_acpi_node_pin_mapping' [-Wmissing-prototypes]
1106 | int upboard_acpi_node_pin_mapping(struct upboard_fpga *fpga,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/pinctrl/pinctrl-upboard.c:91:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
91 | #define BOARD_UP_APL03 9
| ^
drivers/pinctrl/pinctrl-upboard.c:1166:26: note: in expansion of macro 'BOARD_UP_APL03'
1166 | .ident = BOARD_UP_APL03,
| ^~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:91:49: note: (near initialization for 'upboard_dmi_table[0].ident')
91 | #define BOARD_UP_APL03 9
| ^
drivers/pinctrl/pinctrl-upboard.c:1166:26: note: in expansion of macro 'BOARD_UP_APL03'
1166 | .ident = BOARD_UP_APL03,
| ^~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:88:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
88 | #define BOARD_UP_WHL01 5
| ^
drivers/pinctrl/pinctrl-upboard.c:1173:26: note: in expansion of macro 'BOARD_UP_WHL01'
1173 | .ident = BOARD_UP_WHL01,
| ^~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:88:49: note: (near initialization for 'upboard_dmi_table[1].ident')
88 | #define BOARD_UP_WHL01 5
| ^
drivers/pinctrl/pinctrl-upboard.c:1173:26: note: in expansion of macro 'BOARD_UP_WHL01'
1173 | .ident = BOARD_UP_WHL01,
| ^~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:93:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
93 | #define BOARD_UPX_TGL 11
| ^~
drivers/pinctrl/pinctrl-upboard.c:1180:26: note: in expansion of macro 'BOARD_UPX_TGL'
1180 | .ident = BOARD_UPX_TGL,
| ^~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:93:49: note: (near initialization for 'upboard_dmi_table[2].ident')
93 | #define BOARD_UPX_TGL 11
| ^~
drivers/pinctrl/pinctrl-upboard.c:1180:26: note: in expansion of macro 'BOARD_UPX_TGL'
1180 | .ident = BOARD_UPX_TGL,
| ^~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:95:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
95 | #define BOARD_UPN_EHL01 13
| ^~
drivers/pinctrl/pinctrl-upboard.c:1187:26: note: in expansion of macro 'BOARD_UPN_EHL01'
1187 | .ident = BOARD_UPN_EHL01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:95:49: note: (near initialization for 'upboard_dmi_table[3].ident')
95 | #define BOARD_UPN_EHL01 13
| ^~
drivers/pinctrl/pinctrl-upboard.c:1187:26: note: in expansion of macro 'BOARD_UPN_EHL01'
1187 | .ident = BOARD_UPN_EHL01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:95:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
95 | #define BOARD_UPN_EHL01 13
| ^~
drivers/pinctrl/pinctrl-upboard.c:96:49: note: in expansion of macro 'BOARD_UPN_EHL01'
96 | #define BOARD_UPS_EHL01 BOARD_UPN_EHL01
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:1194:26: note: in expansion of macro 'BOARD_UPS_EHL01'
1194 | .ident = BOARD_UPS_EHL01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:95:49: note: (near initialization for 'upboard_dmi_table[4].ident')
95 | #define BOARD_UPN_EHL01 13
| ^~
drivers/pinctrl/pinctrl-upboard.c:96:49: note: in expansion of macro 'BOARD_UPN_EHL01'
96 | #define BOARD_UPS_EHL01 BOARD_UPN_EHL01
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:1194:26: note: in expansion of macro 'BOARD_UPS_EHL01'
1194 | .ident = BOARD_UPS_EHL01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:97:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
97 | #define BOARD_UPX_ADLP01 15
| ^~
drivers/pinctrl/pinctrl-upboard.c:1201:26: note: in expansion of macro 'BOARD_UPX_ADLP01'
1201 | .ident = BOARD_UPX_ADLP01,
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:97:49: note: (near initialization for 'upboard_dmi_table[5].ident')
97 | #define BOARD_UPX_ADLP01 15
| ^~
drivers/pinctrl/pinctrl-upboard.c:1201:26: note: in expansion of macro 'BOARD_UPX_ADLP01'
1201 | .ident = BOARD_UPX_ADLP01,
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:98:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
98 | #define BOARD_UPN_ADLN01 16
| ^~
drivers/pinctrl/pinctrl-upboard.c:1208:26: note: in expansion of macro 'BOARD_UPN_ADLN01'
1208 | .ident = BOARD_UPN_ADLN01,
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:98:49: note: (near initialization for 'upboard_dmi_table[6].ident')
98 | #define BOARD_UPN_ADLN01 16
| ^~
drivers/pinctrl/pinctrl-upboard.c:1208:26: note: in expansion of macro 'BOARD_UPN_ADLN01'
1208 | .ident = BOARD_UPN_ADLN01,
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:97:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
97 | #define BOARD_UPX_ADLP01 15
| ^~
drivers/pinctrl/pinctrl-upboard.c:99:49: note: in expansion of macro 'BOARD_UPX_ADLP01'
99 | #define BOARD_UPS_ADLP01 BOARD_UPX_ADLP01
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:1215:26: note: in expansion of macro 'BOARD_UPS_ADLP01'
1215 | .ident = BOARD_UPS_ADLP01,
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:97:49: note: (near initialization for 'upboard_dmi_table[7].ident')
97 | #define BOARD_UPX_ADLP01 15
| ^~
drivers/pinctrl/pinctrl-upboard.c:99:49: note: in expansion of macro 'BOARD_UPX_ADLP01'
99 | #define BOARD_UPS_ADLP01 BOARD_UPX_ADLP01
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:1215:26: note: in expansion of macro 'BOARD_UPS_ADLP01'
1215 | .ident = BOARD_UPS_ADLP01,
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:98:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
98 | #define BOARD_UPN_ADLN01 16
| ^~
drivers/pinctrl/pinctrl-upboard.c:100:49: note: in expansion of macro 'BOARD_UPN_ADLN01'
100 | #define BOARD_UP_ADLN01 BOARD_UPN_ADLN01
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:1222:26: note: in expansion of macro 'BOARD_UP_ADLN01'
1222 | .ident = BOARD_UP_ADLN01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:98:49: note: (near initialization for 'upboard_dmi_table[8].ident')
98 | #define BOARD_UPN_ADLN01 16
| ^~
drivers/pinctrl/pinctrl-upboard.c:100:49: note: in expansion of macro 'BOARD_UPN_ADLN01'
100 | #define BOARD_UP_ADLN01 BOARD_UPN_ADLN01
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:1222:26: note: in expansion of macro 'BOARD_UP_ADLN01'
1222 | .ident = BOARD_UP_ADLN01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_pinctrl_probe':
>> drivers/pinctrl/pinctrl-upboard.c:1353:30: warning: assignment to 'int' from 'const char *' makes integer from pointer without a cast [-Wint-conversion]
1353 | pctrl->ident = system_id->ident;
| ^
drivers/pinctrl/pinctrl-upboard.c: At top level:
>> drivers/pinctrl/pinctrl-upboard.c:327:38: warning: 'pin_functions' defined but not used [-Wunused-const-variable=]
327 | static const struct upboard_function pin_functions[] = {
| ^~~~~~~~~~~~~
>> drivers/pinctrl/pinctrl-upboard.c:305:38: warning: 'pin_groups' defined but not used [-Wunused-const-variable=]
305 | static const struct upboard_pingroup pin_groups[] = {
| ^~~~~~~~~~
cc1: some warnings being treated as errors


vim +/locked +727 drivers/pinctrl/pinctrl-upboard.c

720
721 static void upboard_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
722 unsigned int pin)
723 {
724 struct upboard_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
725 void __iomem *padcfg;
726 u32 cfg0, cfg1, mode;
> 727 int locked;
728
729 if (pctrl->pins[pin].regs == NULL)
730 return;
731
732 cfg0 = readl(pctrl->pins[pin].regs);
733 cfg1 = readl(pctrl->pins[pin].regs + PADCFG1);
734
735 mode = (cfg0 & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
736 if (mode == PADCFG0_PMODE_GPIO)
> 737 seq_puts(s, "GPIO ");
738 else
> 739 seq_printf(s, "mode %d ", mode);
740
741 seq_printf(s, "0x%08x 0x%08x", cfg0, cfg1);
742
743 /* Dump the additional PADCFG registers if available */
744 padcfg = pctrl->pins[pin].regs + PADCFG2;
745 if (padcfg)
746 seq_printf(s, " 0x%08x", readl(padcfg));
747
748 seq_printf(s, " 0x%08x", pctrl->pins[pin].regs);
749 }
750
751 static const struct pinctrl_ops upboard_pinctrl_ops = {
752 .get_groups_count = upboard_get_groups_count,
753 .get_group_name = upboard_get_group_name,
754 .pin_dbg_show = upboard_pin_dbg_show,
755 };
756
757 static struct pinctrl_desc upboard_up_pinctrl_desc = {
758 .pins = upboard_up_pins,
759 .npins = ARRAY_SIZE(upboard_up_pins),
760 .pctlops = &upboard_pinctrl_ops,
761 .pmxops = &upboard_pinmux_ops,
762 .owner = THIS_MODULE,
763 };
764
765 static struct pinctrl_desc upboard_up2_pinctrl_desc = {
766 .pins = upboard_up2_pins,
767 .npins = ARRAY_SIZE(upboard_up2_pins),
768 .pctlops = &upboard_pinctrl_ops,
769 .pmxops = &upboard_pinmux_ops,
770 .owner = THIS_MODULE,
771 };
772
773 static struct pinctrl_desc upboard_upcore_crex_pinctrl_desc = {
774 .pins = upboard_upcore_crex_pins,
775 .npins = ARRAY_SIZE(upboard_upcore_crex_pins),
776 .pctlops = &upboard_pinctrl_ops,
777 .pmxops = &upboard_pinmux_ops,
778 .owner = THIS_MODULE,
779 };
780
781 static struct pinctrl_desc upboard_upcore_crst02_pinctrl_desc = {
782 .pins = upboard_upcore_crst02_pins,
783 .npins = ARRAY_SIZE(upboard_upcore_crst02_pins),
784 .pctlops = &upboard_pinctrl_ops,
785 .pmxops = &upboard_pinmux_ops,
786 .owner = THIS_MODULE,
787 };
788
789 static void upboard_alt_func_enable(struct gpio_chip *gc, const char *name, int id)
790 {
791 struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
> 792 int offset[pctrl->pctldesc->npins];
793 int i, cnt;
794
795 /* find all pins */
796 for (i = 0, cnt = 0; i < pctrl->pctldesc->npins; i++) {
797 if (strstr(pctrl->pctldesc->pins[i].name, name))
798 offset[cnt++] = i;
799 }
800
801 /* change to alternate function */
802 for (i = 0; i < cnt; i++) {
803 if (pctrl->pins[offset[i]].regs == NULL)
804 continue;
> 805 bool input = false;
806 int mode = 0; /* default GPIO */
807 unsigned int val = readl(pctrl->pins[offset[i]].regs);
808
809 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2C") ||
810 strstr(pctrl->pctldesc->pins[offset[i]].name, "PINMUX")) {
811 mode = 1;
812 switch (id) {
813 case BOARD_UPN_ADLN01:
814 case BOARD_UPX_ADLP01:
815 mode = 2;
816 break;
817 default:
818 break;
819 }
820
821 val |= mode<<PADCFG0_PMODE_SHIFT;
822 writel(val, pctrl->pins[offset[i]].regs);
823 upboard_fpga_request_free(pctrl->pctldev, offset[i]);
824 continue;
825 }
826
827 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "UART")) {
828 mode = 1;
829 switch (id) {
830 case BOARD_UPN_EHL01:
831 mode = 4;
832 break;
833 case BOARD_UPN_ADLN01:
834 case BOARD_UPX_ADLP01:
835 mode = 2;
836 break;
837 default:
838 break;
839 }
840 }
841
842 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SPI")) {
843 mode = 1;
844 switch (id) {
845 case BOARD_UP_WHL01:
846 mode = 3;
847 break;
848 case BOARD_UPN_ADLN01:
849 case BOARD_UPX_ADLP01:
850 mode = 7;
851 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MOSI")) {
852 val &= ~PADCFG0_GPIOTXDIS;
853 val |= PADCFG0_GPIORXDIS;
854 }
855
856 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO"))
857 val |= PADCFG0_GPIORXDIS;
858
859 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CLK")) {
860 val &= ~PADCFG0_GPIOTXDIS;
861 val |= PADCFG0_GPIORXDIS;
862 }
863 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS0"))
864 val |= PADCFG0_GPIORXDIS;
865
866 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS1"))
867 continue;
868 break;
869 default:
870 break;
871 }
872 }
873
874 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2S")) {
875 mode = 1;
876 switch (id) {
877 case BOARD_UPX_ADLP01:
878 mode = 4;
879 break;
880 default:
881 break;
882 }
883 }
884
885 val |= mode<<PADCFG0_PMODE_SHIFT;
886 writel(val, pctrl->pins[offset[i]].regs);
887
888 /* input pins */
889 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "RX"))
890 input = true;
891
892 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CTS"))
893 input = true;
894
895 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "ADC")) {
896 input = true;
897 if (id == BOARD_UP_APL01)
898 upboard_fpga_request_enable(pctrl->pctldev, NULL, offset[i]);
899 else
900 upboard_fpga_request_free(pctrl->pctldev, offset[i]);
901 }
902
903 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO"))
904 input = true;
905
906 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "DIN"))
907 input = true;
908
909 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SDI"))
910 input = true;
911
912 upboard_fpga_set_direction(pctrl->pctldev, NULL, offset[i], input);
913 }
914 }
915

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2023-08-10 13:39:21

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH V5 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA

Hi Larry,

thanks for your patch!

I would really like Andy to look at this, because ACPI and I'm not good at
ACPI.

On Tue, Aug 8, 2023 at 4:57 PM larry.lai <[email protected]> wrote:

> The UP Squared board <http://www.upboard.com> implements certain
> features (pin control) through an on-board FPGA.
>
> Reported-by: kernel test robot <[email protected]>
> Signed-off-by: Gary Wang <[email protected]>
> Signed-off-by: larry.lai <[email protected]>
(...)

> + if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2C") ||
> + strstr(pctrl->pctldesc->pins[offset[i]].name, "PINMUX")) {

I think there is something like match a string list in the kernel,
Andy will know.

> +static int upboard_gpio_get(struct gpio_chip *gc, unsigned int offset)
> +{
> + struct upboard_pinctrl *pctrl = container_of(gc, struct upboard_pinctrl, chip);
> + unsigned int pin = pctrl->rpi_mapping[offset];
> + int gpio = upboard_rpi_to_native_gpio(gc, offset);
> +
> + if (gpio < 0)
> + return gpio;
> +
> + /* APL03 board open drain GPIO */
> + if (pctrl->ident == BOARD_UP_APL03) {
> + int val = 0;
> +
> + switch (pin) {
> + case 0:
> + case 1:
> + case 9:
> + case 23:
> + val = readl(pctrl->pins[pin].regs);
> + return val & 0x00000003;
> + default:
> + break;
> + }
> + }
> +
> + return gpiod_get_value(gpio_to_desc(gpio));

I don't really like this construction bouncing us back into the global GPIO
numberspace to get to the descriptor of the corresponding native GPIO.
gpio_to_desc() is an uglyhack and shall not be used.

You need to come up with something better here: request all the underlying
GPIO descriptors with gpiod_get(dev, .. ASIS) and store them in an array.
Look in e.g.
drivers/gpio/gpio-aggregator.c
drivers/gpio/gpio-latch.c
for examples of how we do this in other drivers.

The underlying GPIO lines need to be specified somehow, in worst case
using descriptor tables.

> +/* DMI Matches for older bios without fpga initialization */
> +static const struct dmi_system_id upboard_dmi_table[] __initconst = {
> + {
> + .ident = BOARD_U

A DMI table OK....

> +static struct platform_driver upboard_pinctrl_driver = {
> + .driver = {
> + .name = "upboard-pinctrl",
> + },
> +};
> +module_platform_driver_probe(upboard_pinctrl_driver, upboard_pinctrl_probe);

OK I don't know ACPI, but what I've seen the DMI table is supposed
to be used for some kind of lookup, such as checking in .init if the
device is there, so I don't get this. Also doesn't ACPI drivers use
the ACPI bus?

Yours,
Linus Walleij