The UP board <https://up-board.org/> is the computer board for
Professional Makers and Industrial Applications. We want to upstream
the UP board 40-pin GP-bus Kernel driver for giving the users better
experience on the software release. (not just download from UP board
github)
These patches are generated from the Linux kernel mainline tag v6.0.
This is the PATCH V6 and fixed kernel test robot compiler warning and
addressed Linus Walleij review comments.
larry.lai (3):
mfd: Add support for UP board CPLD/FPGA
pinctrl: Add support pin control for UP board CPLD/FPGA
leds: Add support for UP board CPLD onboard LEDS
drivers/leds/Kconfig | 10 +
drivers/leds/Makefile | 1 +
drivers/leds/leds-upboard.c | 79 ++
drivers/mfd/Kconfig | 12 +
drivers/mfd/Makefile | 1 +
drivers/mfd/upboard-fpga.c | 492 ++++++++++
drivers/pinctrl/Kconfig | 14 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-upboard.c | 1390 +++++++++++++++++++++++++++++
include/linux/mfd/upboard-fpga.h | 55 ++
10 files changed, 2055 insertions(+)
create mode 100644 drivers/leds/leds-upboard.c
create mode 100644 drivers/mfd/upboard-fpga.c
create mode 100644 drivers/pinctrl/pinctrl-upboard.c
create mode 100644 include/linux/mfd/upboard-fpga.h
base-commit: 4fe89d07dcc2804c8b562f6c7896a45643d34b2f
--
2.17.1
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 V5 -> PATCH V6
(1) Refer 2023/08/10 Linus Walleij review, cleaned up coding style and
addressed review comments.
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 | 1390 +++++++++++++++++++++++++++++
3 files changed, 1405 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..73d50a695aab
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-upboard.c
@@ -0,0 +1,1390 @@
+// 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/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/seq_file.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 18
+
+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_UP_ADLN01:
+ 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_UP_ADLN01:
+ 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);
+ int reg_val = readl(pctrl->pins[pin].regs);
+
+ if (gpio < 0)
+ return gpio;
+
+ /* APL03 board open drain GPIO */
+ if (pctrl->ident == BOARD_UP_APL03) {
+ switch (pin) {
+ case 0:
+ case 1:
+ case 9:
+ case 23:
+ return reg_val & 0x00000003;
+ default:
+ break;
+ }
+ }
+
+ if (!(reg_val & PADCFG0_GPIOTXDIS))
+ return !!(reg_val & PADCFG0_GPIOTXSTATE);
+
+ return !!(reg_val & PADCFG0_GPIORXSTATE);
+}
+
+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);
+ int reg_val = readl(pctrl->pins[pin].regs);
+
+ if (gpio < 0)
+ return;
+
+ /* APL03 board open drain GPIO */
+ if (pctrl->ident == BOARD_UP_APL03) {
+ switch (pin) {
+ case 0:
+ case 1:
+ case 9:
+ case 23:
+ if (value)
+ reg_val |= PADCFG0_GPIOTXDIS;
+ else
+ reg_val &= ~PADCFG0_GPIOTXDIS;
+
+ writel(reg_val, pctrl->pins[pin].regs);
+ return;
+ default:
+ break;
+ }
+ }
+ if (value)
+ reg_val |= PADCFG0_GPIOTXSTATE;
+ else
+ reg_val &= ~PADCFG0_GPIOTXSTATE;
+ writel(reg_val, pctrl->pins[pin].regs);
+}
+
+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 to assign pin mapping driver data */
+static const struct dmi_system_id upboard_dmi_table[] __initconst = {
+ {
+ .ident = BOARD_UP_APL01,
+ .matches = { /* UP SQUARED */
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UP-APL01"),
+ },
+ },
+ {
+ .ident = BOARD_UP_APL01,
+ .matches = { /* UP SQUARED Pro*/
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AAEON"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "UPN-APL01"),
+ },
+ },
+ {
+ .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 pinctrl_desc *pctldesc;
+ struct upboard_pinctrl *pctrl;
+ struct upboard_pin *pins;
+ const struct dmi_system_id *system_id;
+ const unsigned int *rpi_mapping;
+ unsigned int ngpio;
+ int ret;
+ int i;
+ /* default */
+ int board_id = BOARD_UP_APL03;
+
+ /* check board id to arrange driver data */
+ system_id = dmi_first_match(upboard_dmi_table);
+ if (system_id)
+ board_id = system_id->ident;
+ dev_info(&pdev->dev, "compatible upboard id %d", board_id);
+ switch (board_id) {
+ case BOARD_UP_APL01:
+ pctldesc = &upboard_up2_pinctrl_desc;
+ rpi_mapping = upboard_up2_rpi_mapping;
+ ngpio = ARRAY_SIZE(upboard_up2_rpi_mapping);
+ break;
+ case BOARD_UP_UPCORE:
+ pctldesc = &upboard_upcore_crex_pinctrl_desc;
+ rpi_mapping = upboard_upcore_crex_rpi_mapping;
+ ngpio = ARRAY_SIZE(upboard_upcore_crex_rpi_mapping);
+ break;
+ case BOARD_UP_CORE_PLUS:
+ pctldesc = &upboard_upcore_crst02_pinctrl_desc;
+ rpi_mapping = upboard_upcore_crst02_rpi_mapping;
+ ngpio = ARRAY_SIZE(upboard_upcore_crst02_rpi_mapping);
+ break;
+ default:
+ pctldesc = &upboard_up_pinctrl_desc;
+ rpi_mapping = upboard_up_rpi_mapping;
+ ngpio = ARRAY_SIZE(upboard_up_rpi_mapping);
+ break;
+ }
+
+ 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;
+ pctrl->ident = board_id;
+
+ 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;
+
+ 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);
+ upboard_alt_func_enable(&pctrl->chip, "PINMUX", 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
The UP boards come with a few FPGA-controlled onboard LEDs:
* UP Board: yellow, green, red
* UP Squared: blue, yellow, green, red
This patch depends on patch "mfd: Add support for UP board CPLD/FPGA".
Signed-off-by: Gary Wang <[email protected]>
Signed-off-by: larry.lai <[email protected]>
---
PATCH V4 -> PATCH V6 : There is no change.
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: Refer 2022/12/08 Lee Jones review,
cleaned up coding style.
PATCH V3 -> RFC 2022/11/23: Update the changes Copyright.
PATCH V1 -> V3: There is no change.
PATCH --> PATCH V1: Refer 2022/10/03 Andy Shevchenko review, cleaned up
coding style.
---
drivers/leds/Kconfig | 10 +++++
drivers/leds/Makefile | 1 +
drivers/leds/leds-upboard.c | 79 +++++++++++++++++++++++++++++++++++++
3 files changed, 90 insertions(+)
create mode 100644 drivers/leds/leds-upboard.c
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 499d0f215a8b..d9d533cb38ca 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -872,6 +872,16 @@ source "drivers/leds/flash/Kconfig"
comment "RGB LED drivers"
source "drivers/leds/rgb/Kconfig"
+config LEDS_UPBOARD
+ tristate "LED support for the UP board"
+ depends on LEDS_CLASS
+ depends on MFD_INTEL_UPBOARD_FPGA
+ help
+ This option enables support for the UP board LEDs.
+
+ To compile this driver as a module, choose M here: the module
+ will be called leds-upboard.
+
comment "LED Triggers"
source "drivers/leds/trigger/Kconfig"
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 4fd2f92cd198..e72956645646 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -83,6 +83,7 @@ obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o
obj-$(CONFIG_LEDS_TLC591XX) += leds-tlc591xx.o
obj-$(CONFIG_LEDS_TPS6105X) += leds-tps6105x.o
obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds-turris-omnia.o
+obj-$(CONFIG_LEDS_UPBOARD) += leds-upboard.o
obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
diff --git a/drivers/leds/leds-upboard.c b/drivers/leds/leds-upboard.c
new file mode 100644
index 000000000000..8a44afe8c526
--- /dev/null
+++ b/drivers/leds/leds-upboard.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * UP Board CPLD/FPGA based LED driver
+ *
+ * Copyright (c) AAEON. All rights reserved.
+ *
+ * Author: Gary Wang <[email protected]>
+ */
+
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/mfd/upboard-fpga.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct upboard_led {
+ struct regmap_field *field;
+ struct led_classdev cdev;
+ unsigned char bit;
+};
+
+static enum led_brightness upboard_led_brightness_get(struct led_classdev *cdev)
+{
+ struct upboard_led *led = container_of(cdev, struct upboard_led, cdev);
+ int brightness = 0;
+
+ regmap_field_read(led->field, &brightness);
+
+ return brightness;
+};
+
+static void upboard_led_brightness_set(struct led_classdev *cdev, enum led_brightness brightness)
+{
+ struct upboard_led *led = container_of(cdev, struct upboard_led, cdev);
+
+ regmap_field_write(led->field, brightness != LED_OFF);
+};
+
+static int __init upboard_led_probe(struct platform_device *pdev)
+{
+ struct upboard_fpga * const up_fpga = dev_get_drvdata(pdev->dev.parent);
+ struct reg_field fldconf = {
+ .reg = UPFPGA_REG_FUNC_EN0,
+ };
+ struct upboard_led_data * const pdata = pdev->dev.platform_data;
+ struct upboard_led *led;
+
+ led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
+ if (!led)
+ return -ENOMEM;
+
+ fldconf.lsb = pdata->bit;
+ fldconf.msb = pdata->bit;
+ led->field = devm_regmap_field_alloc(&pdev->dev, up_fpga->regmap, fldconf);
+ if (IS_ERR(led->field))
+ return PTR_ERR(led->field);
+
+ led->cdev.brightness_get = upboard_led_brightness_get;
+ led->cdev.brightness_set = upboard_led_brightness_set;
+ led->cdev.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "upboard:%s:",
+ pdata->colour);
+ if (!led->cdev.name)
+ return -ENOMEM;
+
+ return devm_led_classdev_register(&pdev->dev, &led->cdev);
+};
+
+static struct platform_driver upboard_led_driver = {
+ .driver = {
+ .name = "upboard-led",
+ },
+};
+module_platform_driver_probe(upboard_led_driver, upboard_led_probe);
+
+MODULE_AUTHOR("Gary Wang <[email protected]>");
+MODULE_DESCRIPTION("UP Board LED driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:upboard-led");
--
2.17.1
On Fri, Sep 15, 2023 at 5:12 AM 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]>
This v6 overall looks good to me!
Reviewed-by: Linus Walleij <[email protected]>
Can the patch be merged on its own?
> +#include "core.h"
> +#include "intel/pinctrl-intel.h"
Didn't notice this before. But if Andy is OK with it, I'm
OK with it, I guess there is a reason? Perhaps it warrants
a comment explaining why you do this?
Valid reasons:
- You are using Intel-specific HW features also found in this
FPGA
Invalid reasons:
- Using nifty macros or helpers, then either make them generic
or (if they are small) duplicate them.
If it was that thing I asked Andy to keep locally because I didn't
agree with its generic usefulness, maybe I should be told to
reconsider.
Yours,
Linus Walleij
Hi larry.lai,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 4fe89d07dcc2804c8b562f6c7896a45643d34b2f]
url: https://github.com/intel-lab-lkp/linux/commits/larry-lai/mfd-Add-support-for-UP-board-CPLD-FPGA/20230915-111244
base: 4fe89d07dcc2804c8b562f6c7896a45643d34b2f
patch link: https://lore.kernel.org/r/20230915031123.14515-3-larry.lai%40yunjingtech.com
patch subject: [PATCH V6 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20230916/[email protected]/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230916/[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:748:30: warning: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'void *' [-Wformat=]
748 | seq_printf(s, " 0x%08x", pctrl->pins[pin].regs);
| ~~~^ ~~~~~~~~~~~~~~~~~~~~~
| | |
| unsigned int void *
| %08p
>> 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_get_direction':
drivers/pinctrl/pinctrl-upboard.c:960:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
960 | unsigned int padcfg0 = readl(pctrl->pins[pin].regs);
| ^~~~~~~~
drivers/pinctrl/pinctrl-upboard.c: At top level:
>> drivers/pinctrl/pinctrl-upboard.c:1109:5: warning: no previous prototype for 'upboard_acpi_node_pin_mapping' [-Wmissing-prototypes]
1109 | int upboard_acpi_node_pin_mapping(struct upboard_fpga *fpga,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/pinctrl/pinctrl-upboard.c:84:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
84 | #define BOARD_UP_APL01 1
| ^
drivers/pinctrl/pinctrl-upboard.c:1170:26: note: in expansion of macro 'BOARD_UP_APL01'
1170 | .ident = BOARD_UP_APL01,
| ^~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:84:49: note: (near initialization for 'upboard_dmi_table[0].ident')
84 | #define BOARD_UP_APL01 1
| ^
drivers/pinctrl/pinctrl-upboard.c:1170:26: note: in expansion of macro 'BOARD_UP_APL01'
1170 | .ident = BOARD_UP_APL01,
| ^~~~~~~~~~~~~~
>> drivers/pinctrl/pinctrl-upboard.c:84:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
84 | #define BOARD_UP_APL01 1
| ^
drivers/pinctrl/pinctrl-upboard.c:1177:26: note: in expansion of macro 'BOARD_UP_APL01'
1177 | .ident = BOARD_UP_APL01,
| ^~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:84:49: note: (near initialization for 'upboard_dmi_table[1].ident')
84 | #define BOARD_UP_APL01 1
| ^
drivers/pinctrl/pinctrl-upboard.c:1177:26: note: in expansion of macro 'BOARD_UP_APL01'
1177 | .ident = BOARD_UP_APL01,
| ^~~~~~~~~~~~~~
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:1184:26: note: in expansion of macro 'BOARD_UP_APL03'
1184 | .ident = BOARD_UP_APL03,
| ^~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:91:49: note: (near initialization for 'upboard_dmi_table[2].ident')
91 | #define BOARD_UP_APL03 9
| ^
drivers/pinctrl/pinctrl-upboard.c:1184:26: note: in expansion of macro 'BOARD_UP_APL03'
1184 | .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:1191:26: note: in expansion of macro 'BOARD_UP_WHL01'
1191 | .ident = BOARD_UP_WHL01,
| ^~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:88:49: note: (near initialization for 'upboard_dmi_table[3].ident')
88 | #define BOARD_UP_WHL01 5
| ^
drivers/pinctrl/pinctrl-upboard.c:1191:26: note: in expansion of macro 'BOARD_UP_WHL01'
1191 | .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:1198:26: note: in expansion of macro 'BOARD_UPX_TGL'
1198 | .ident = BOARD_UPX_TGL,
| ^~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:93:49: note: (near initialization for 'upboard_dmi_table[4].ident')
93 | #define BOARD_UPX_TGL 11
| ^~
drivers/pinctrl/pinctrl-upboard.c:1198:26: note: in expansion of macro 'BOARD_UPX_TGL'
1198 | .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:1205:26: note: in expansion of macro 'BOARD_UPN_EHL01'
1205 | .ident = BOARD_UPN_EHL01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:95:49: note: (near initialization for 'upboard_dmi_table[5].ident')
95 | #define BOARD_UPN_EHL01 13
| ^~
drivers/pinctrl/pinctrl-upboard.c:1205:26: note: in expansion of macro 'BOARD_UPN_EHL01'
1205 | .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:1212:26: note: in expansion of macro 'BOARD_UPS_EHL01'
1212 | .ident = BOARD_UPS_EHL01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:95:49: note: (near initialization for 'upboard_dmi_table[6].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:1212:26: note: in expansion of macro 'BOARD_UPS_EHL01'
1212 | .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:1219:26: note: in expansion of macro 'BOARD_UPX_ADLP01'
1219 | .ident = BOARD_UPX_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:1219:26: note: in expansion of macro 'BOARD_UPX_ADLP01'
1219 | .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:1226:26: note: in expansion of macro 'BOARD_UPN_ADLN01'
1226 | .ident = BOARD_UPN_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:1226:26: note: in expansion of macro 'BOARD_UPN_ADLN01'
1226 | .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:1233:26: note: in expansion of macro 'BOARD_UPS_ADLP01'
1233 | .ident = BOARD_UPS_ADLP01,
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:97:49: note: (near initialization for 'upboard_dmi_table[9].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:1233:26: note: in expansion of macro 'BOARD_UPS_ADLP01'
1233 | .ident = BOARD_UPS_ADLP01,
| ^~~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:100:49: warning: initialization of 'const char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
100 | #define BOARD_UP_ADLN01 18
| ^~
drivers/pinctrl/pinctrl-upboard.c:1240:26: note: in expansion of macro 'BOARD_UP_ADLN01'
1240 | .ident = BOARD_UP_ADLN01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c:100:49: note: (near initialization for 'upboard_dmi_table[10].ident')
100 | #define BOARD_UP_ADLN01 18
| ^~
drivers/pinctrl/pinctrl-upboard.c:1240:26: note: in expansion of macro 'BOARD_UP_ADLN01'
1240 | .ident = BOARD_UP_ADLN01,
| ^~~~~~~~~~~~~~~
drivers/pinctrl/pinctrl-upboard.c: In function 'upboard_pinctrl_probe':
>> drivers/pinctrl/pinctrl-upboard.c:1266:26: warning: assignment to 'int' from 'const char *' makes integer from pointer without a cast [-Wint-conversion]
1266 | board_id = 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[] = {
| ^~~~~~~~~~
vim +748 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_UP_ADLN01:
834 case BOARD_UPN_ADLN01:
835 case BOARD_UPX_ADLP01:
836 mode = 2;
837 break;
838 default:
839 break;
840 }
841 }
842
843 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SPI")) {
844 mode = 1;
845 switch (id) {
846 case BOARD_UP_WHL01:
847 mode = 3;
848 break;
849 case BOARD_UP_ADLN01:
850 case BOARD_UPN_ADLN01:
851 case BOARD_UPX_ADLP01:
852 mode = 7;
853 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MOSI")) {
854 val &= ~PADCFG0_GPIOTXDIS;
855 val |= PADCFG0_GPIORXDIS;
856 }
857
858 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO"))
859 val |= PADCFG0_GPIORXDIS;
860
861 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CLK")) {
862 val &= ~PADCFG0_GPIOTXDIS;
863 val |= PADCFG0_GPIORXDIS;
864 }
865 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS0"))
866 val |= PADCFG0_GPIORXDIS;
867
868 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CS1"))
869 continue;
870 break;
871 default:
872 break;
873 }
874 }
875
876 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "I2S")) {
877 mode = 1;
878 switch (id) {
879 case BOARD_UPX_ADLP01:
880 mode = 4;
881 break;
882 default:
883 break;
884 }
885 }
886
887 val |= mode<<PADCFG0_PMODE_SHIFT;
888 writel(val, pctrl->pins[offset[i]].regs);
889
890 /* input pins */
891 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "RX"))
892 input = true;
893
894 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "CTS"))
895 input = true;
896
897 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "ADC")) {
898 input = true;
899 if (id == BOARD_UP_APL01)
900 upboard_fpga_request_enable(pctrl->pctldev, NULL, offset[i]);
901 else
902 upboard_fpga_request_free(pctrl->pctldev, offset[i]);
903 }
904
905 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "MISO"))
906 input = true;
907
908 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "DIN"))
909 input = true;
910
911 if (strstr(pctrl->pctldesc->pins[offset[i]].name, "SDI"))
912 input = true;
913
914 upboard_fpga_set_direction(pctrl->pctldev, NULL, offset[i], input);
915 }
916 }
917
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Linus,
Thank you for spending time to review the V6 patch, for your question, please kindly to check our comments with ">>" beginning.
Best Regards,
Larry
寄件者: Linus Walleij <[email protected]>
寄件日期: 2023年9月15日 下午 05:02
收件者: Larry Lai <[email protected]>
副本: [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Musa Lin <[email protected]>; Jack Chang <[email protected]>; Noah Hung <[email protected]>
主旨: Re: [PATCH V6 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA
On Fri, Sep 15, 2023 at 5:12 AM 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]>
This v6 overall looks good to me!
Reviewed-by: Linus Walleij <[email protected]>
Can the patch be merged on its own?
> +#include "core.h"
> +#include "intel/pinctrl-intel.h"
Didn't notice this before. But if Andy is OK with it, I'm
OK with it, I guess there is a reason? Perhaps it warrants
a comment explaining why you do this?
>>
Need struct intel_pinctrl gpp information to control dedicated Raspberry Pi compatible GPIOs.
These products (Up boards) are intel approves foundation kits.
Valid reasons:
- You are using Intel-specific HW features also found in this
FPGA
Invalid reasons:
- Using nifty macros or helpers, then either make them generic
or (if they are small) duplicate them.
If it was that thing I asked Andy to keep locally because I didn't
agree with its generic usefulness, maybe I should be told to
reconsider.
Yours,
Linus Walleij
On Tue, 19 Sep 2023, Larry Lai wrote:
> Hi Linus,
>
> Thank you for spending time to review the V6 patch, for your question, please kindly to check our comments with ">>" beginning.
I don't know about anyone else, but I'm finding this format hard to
read. A full conversation using this style would be impossible to
decipher.
Please can you configure your editor/client to quote and reply properly?
That way previous responses and your comments can be easily
differentiated.
> 寄件者: Linus Walleij <[email protected]>
> 寄件日期: 2023年9月15日 下午 05:02
> 收件者: Larry Lai <[email protected]>
> 副本: [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Musa Lin <[email protected]>; Jack Chang <[email protected]>; Noah Hung <[email protected]>
> 主旨: Re: [PATCH V6 2/3] pinctrl: Add support pin control for UP board CPLD/FPGA
Your client should automatically strip this from the mail body.
>
> On Fri, Sep 15, 2023 at 5:12 AM 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]>
>
> This v6 overall looks good to me!
> Reviewed-by: Linus Walleij <[email protected]>
>
> Can the patch be merged on its own?
>
> > +#include "core.h"
> > +#include "intel/pinctrl-intel.h"
>
> Didn't notice this before. But if Andy is OK with it, I'm
> OK with it, I guess there is a reason? Perhaps it warrants
> a comment explaining why you do this?
> >>
> Need struct intel_pinctrl gpp information to control dedicated Raspberry Pi compatible GPIOs.
> These products (Up boards) are intel approves foundation kits.
>
> Valid reasons:
> - You are using Intel-specific HW features also found in this
> FPGA
>
> Invalid reasons:
> - Using nifty macros or helpers, then either make them generic
> or (if they are small) duplicate them.
>
> If it was that thing I asked Andy to keep locally because I didn't
> agree with its generic usefulness, maybe I should be told to
> reconsider.
>
> Yours,
> Linus Walleij
--
Lee Jones [李琼斯]
Hi Linus,
Cause we replied the wrong email-format to you last time.(Lee informed
us that format is hard to read), so we send the comment again, thanks.
On 15/9/2023 17:02, Linus Walleij wrote:
> On Fri, Sep 15, 2023 at 5:12 AM 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]>
>
> This v6 overall looks good to me!
> Reviewed-by: Linus Walleij <[email protected]>
>
> Can the patch be merged on its own?
>
>> +#include "core.h"
>> +#include "intel/pinctrl-intel.h"
>
> Didn't notice this before. But if Andy is OK with it, I'm
> OK with it, I guess there is a reason? Perhaps it warrants
> a comment explaining why you do this?
Need struct intel_pinctrl gpp information to control dedicated Raspberry
Pi compatible GPIOs.
These products (Up boards) are Intel approves foundation kits.
>
> Valid reasons:
> - You are using Intel-specific HW features also found in this
> FPGA
>
> Invalid reasons:
> - Using nifty macros or helpers, then either make them generic
> or (if they are small) duplicate them.
>
> If it was that thing I asked Andy to keep locally because I didn't
> agree with its generic usefulness, maybe I should be told to
> reconsider.
>
> Yours,
> Linus Walleij