[U-Boot] [RFC PATCH] rockchip: tinker: Add automatic board discovery
Michael Trimarchi
michael at amarulasolutions.com
Mon Nov 18 21:36:04 UTC 2019
Hi
On Mon, Nov 18, 2019 at 04:55:02PM +0530, Jagan Teki wrote:
> On Sun, Nov 17, 2019 at 3:47 PM Michael Trimarchi
> <michael at amarulasolutions.com> wrote:
> >
> > Add a way to detect board id and pcb id.
> >
> > Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
> > ---
> > arch/arm/dts/rk3288-tinker.dtsi | 33 ++++++++
> > board/rockchip/tinker_rk3288/tinker-rk3288.c | 83 ++++++++++++++++++++
> > 2 files changed, 116 insertions(+)
> >
> > diff --git a/arch/arm/dts/rk3288-tinker.dtsi b/arch/arm/dts/rk3288-tinker.dtsi
This is a way better
>From 86cb476c82b0c5506ddd9fe2b9ec7126f3801e5c Mon Sep 17 00:00:00 2001
From: Michael Trimarchi <michael at amarulasolutions.com>
Date: Sun, 17 Nov 2019 11:11:59 +0100
Subject: [PATCH] rockchip: tinker: Add automatic board discovery
Add a way to detect board id and pcb id.
Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
---
arch/arm/dts/rk3288-tinker.dtsi | 32 ++++++
arch/arm/mach-rockchip/rk3288/Kconfig | 4 +-
drivers/board/Kconfig | 5 +
drivers/board/Makefile | 1 +
drivers/board/tinker.c | 148 ++++++++++++++++++++++++++
drivers/board/tinker.h | 16 +++
6 files changed, 205 insertions(+), 1 deletion(-)
create mode 100644 drivers/board/tinker.c
create mode 100644 drivers/board/tinker.h
diff --git a/arch/arm/dts/rk3288-tinker.dtsi b/arch/arm/dts/rk3288-tinker.dtsi
index 2f816af47f..2704b18243 100644
--- a/arch/arm/dts/rk3288-tinker.dtsi
+++ b/arch/arm/dts/rk3288-tinker.dtsi
@@ -53,6 +53,26 @@
#clock-cells = <0>;
};
+ board_info: board-info {
+ compatible = "asus,board_tinker";
+ pinctrl-names = "default";
+ pinctrl-0 = <&board_pins>;
+
+ ver-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH
+ &gpio2 9 GPIO_ACTIVE_HIGH
+ &gpio2 10 GPIO_ACTIVE_HIGH>;
+
+ board-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH
+ &gpio2 2 GPIO_ACTIVE_HIGH
+ &gpio2 3 GPIO_ACTIVE_HIGH>;
+ };
+
+ board_control: board-control {
+ tinker,sdp = <&gpio6 5 GPIO_ACTIVE_HIGH>;
+ tinker,usblimit = <&gpio6 6 GPIO_ACTIVE_HIGH>;
+ tinker,maskemmc = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+ };
+
gpio-keys {
compatible = "gpio-keys";
autorepeat;
@@ -461,6 +481,7 @@
};
&pinctrl {
+
pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
drive-strength = <8>;
};
@@ -482,6 +503,17 @@
};
};
+ board {
+ board_pins: board_pins {
+ rockchip,pins = <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, /* project id 0 */
+ <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, /* project id 1 */
+ <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, /* project id 2 */
+ <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>, /* pcb id 0 */
+ <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>, /* pcb id 1 */
+ <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; /* pcb id 2 */
+ };
+ };
+
eth_phy {
eth_phy_pwr: eth-phy-pwr {
rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index afb62fca78..a08cffd74f 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -123,7 +123,9 @@ config TARGET_ROCK2
config TARGET_TINKER_RK3288
bool "Tinker-RK3288"
- select BOARD_LATE_INIT
+ select BOARD_LATE_INIT
+ select BOARD
+ select BOARD_TINKER
select TPL
help
Tinker is a RK3288-based development board with 2 USB ports, HDMI,
diff --git a/drivers/board/Kconfig b/drivers/board/Kconfig
index 2a3fc9c049..5ab60c3f00 100644
--- a/drivers/board/Kconfig
+++ b/drivers/board/Kconfig
@@ -19,4 +19,9 @@ config BOARD_SANDBOX
help
Support querying device information for the Sandbox boards.
+config BOARD_TINKER
+ bool "Enable board driver for Tinker board"
+ help
+ Support querying device information for the Tinker boards.
+
endif
diff --git a/drivers/board/Makefile b/drivers/board/Makefile
index c8dab4fa0b..20378e4186 100644
--- a/drivers/board/Makefile
+++ b/drivers/board/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_BOARD) += board-uclass.o
obj-$(CONFIG_BOARD_GAZERBEAM) += gazerbeam.o
obj-$(CONFIG_BOARD_SANDBOX) += sandbox.o
+obj-$(CONFIG_BOARD_TINKER) += tinker.o
diff --git a/drivers/board/tinker.c b/drivers/board/tinker.c
new file mode 100644
index 0000000000..129835e3ce
--- /dev/null
+++ b/drivers/board/tinker.c
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019
+ * Michael Trimarchi, Amarula Solutions Sro , michael at amarulasolutions.com
+ *
+ */
+#include <common.h>
+#include <dm.h>
+#include <board.h>
+#include <asm/gpio.h>
+
+#include "tinker.h"
+
+/**
+ * struct board_tinker_priv - Private data structure for the tinker board
+ * driver.
+ * @pcbid_gpios: GPIOs for the board's hardware variant GPIOs
+ * @projectid_gpios: GPIOs for the board's hardware version GPIOs
+ * @board_id: Container for the board's hardware variant
+ * @hwversion: Container for the board's hardware version
+ */
+struct board_tinker_priv {
+ struct gpio_desc ver_gpios[3];
+ struct gpio_desc board_gpios[3];
+ int board_id;
+ int hwversion;
+};
+
+/**
+ * _read_hwversion() - Read the hardware version from the board.
+ * @dev: The board device for which to read the hardware version.
+ *
+ * The hardware version read from the board (from hard-wired GPIOs) is stored
+ * in the private data structure of the driver to be used by other driver
+ * methods.
+ *
+ * Return: 0 if OK, -ve on error.
+ */
+static int _read_hwversion(struct udevice *dev)
+{
+ struct board_tinker_priv *priv = dev_get_priv(dev);
+ int res;
+
+ res = gpio_request_list_by_name(dev, "ver-gpios", priv->ver_gpios,
+ ARRAY_SIZE(priv->ver_gpios),
+ GPIOD_IS_IN);
+ if (res < 0) {
+ debug("%s: Error getting GPIO list 'ver-gpios' (err = %d)\n",
+ dev->name, res);
+ return -ENODEV;
+ }
+
+ res = dm_gpio_get_values_as_int(priv->ver_gpios,
+ ARRAY_SIZE(priv->ver_gpios));
+ if (res < 0) {
+ debug("%s: Error reading HW version from expander (err = %d)\n",
+ dev->name, res);
+ return res;
+ }
+
+ priv->hwversion = res;
+
+ res = gpio_request_list_by_name(dev, "board-gpios", priv->board_gpios,
+ ARRAY_SIZE(priv->board_gpios),
+ GPIOD_IS_IN);
+ if (res < 0) {
+ debug("%s: Error getting GPIO list 'ver-gpios' (err = %d)\n",
+ dev->name, res);
+ return -ENODEV;
+ }
+
+ res = dm_gpio_get_values_as_int(priv->board_gpios,
+ ARRAY_SIZE(priv->board_gpios));
+ if (res < 0) {
+ debug("%s: Error reading HW version from expander (err = %d)\n",
+ dev->name, res);
+ return res;
+ }
+
+
+ priv->board_id = res;
+
+ res = gpio_free_list(dev, priv->board_gpios, ARRAY_SIZE(priv->board_gpios));
+ if (res < 0) {
+ debug("%s: Error freeing HW version GPIO list (err = %d)\n",
+ dev->name, res);
+ return res;
+ }
+
+ return 0;
+}
+
+static int board_tinker_detect(struct udevice *dev)
+{
+ int res;
+
+ res = _read_hwversion(dev);
+ if (res) {
+ debug("%s: Error reading hardware version (err = %d)\n",
+ dev->name, res);
+ return res;
+ }
+
+ return 0;
+}
+
+static int board_tinker_get_int(struct udevice *dev, int id, int *val)
+{
+ struct board_tinker_priv *priv = dev_get_priv(dev);
+
+ switch (id) {
+ case BOARD_HWVERSION:
+ *val = priv->hwversion;
+ break;
+ case BOARD_VARIANT:
+ *val = priv->board_id;
+ break;
+ default:
+ debug("%s: Integer value %d unknown\n", dev->name, id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id board_tinker_ids[] = {
+ { .compatible = "asus,board_tinker" },
+ { /* sentinel */ }
+};
+
+static const struct board_ops board_tinker_ops = {
+ .detect = board_tinker_detect,
+ .get_int = board_tinker_get_int,
+};
+
+static int board_tinker_probe(struct udevice *dev)
+{
+ return 0;
+}
+
+U_BOOT_DRIVER(board_tinker) = {
+ .name = "board_tinker",
+ .id = UCLASS_BOARD,
+ .of_match = board_tinker_ids,
+ .ops = &board_tinker_ops,
+ .priv_auto_alloc_size = sizeof(struct board_tinker_priv),
+ .probe = board_tinker_probe,
+};
diff --git a/drivers/board/tinker.h b/drivers/board/tinker.h
new file mode 100644
index 0000000000..817ec5282c
--- /dev/null
+++ b/drivers/board/tinker.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019
+ * Michael Trimarchi, Amarula Solutions Sro , michael at amarulasolutions.com
+ *
+ */
+
+enum {
+ BOARD_VARIANT,
+ BOARD_HWVERSION,
+};
+
+enum {
+ VAR_TINKER,
+ VAR_TINKERS,
+};
--
2.17.1
> > index 2f816af47f..67a0374050 100644
> > --- a/arch/arm/dts/rk3288-tinker.dtsi
> > +++ b/arch/arm/dts/rk3288-tinker.dtsi
> > @@ -53,6 +53,21 @@
> > #clock-cells = <0>;
> > };
> >
> > + board_info: board-info {
> > + tinker,pcbid0 = <&gpio2 8 GPIO_ACTIVE_HIGH>;
> > + tinker,pcbid1 = <&gpio2 9 GPIO_ACTIVE_HIGH>;
> > + tinker,pcbid2 = <&gpio2 10 GPIO_ACTIVE_HIGH>;
> > + tinker,pid0 = <&gpio2 1 GPIO_ACTIVE_HIGH>;
> > + tinker,pid1 = <&gpio2 2 GPIO_ACTIVE_HIGH>;
> > + tinker,pid2 = <&gpio2 3 GPIO_ACTIVE_HIGH>;
> > + };
> > +
> > + board_control: board-control {
> > + tinker,sdp = <&gpio6 5 GPIO_ACTIVE_HIGH>;
> > + tinker,usblimit = <&gpio6 6 GPIO_ACTIVE_HIGH>;
> > + tinker,maskemmc = <&gpio6 7 GPIO_ACTIVE_HIGH>;
> > + };
> > +
>
> Need to move this into -u-boot.dtsi
>
> > gpio-keys {
> > compatible = "gpio-keys";
> > autorepeat;
> > @@ -461,6 +476,10 @@
> > };
> >
> > &pinctrl {
> > + /* Pins that are not explicitely used by any devices */
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&tinker_pin_hog>;
> > +
> > pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
> > drive-strength = <8>;
> > };
> > @@ -482,6 +501,20 @@
> > };
> > };
> >
> > + hog {
> > + tinker_pin_hog: tinker-pin-hog {
> > + rockchip,pins = <2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>, /* project id 0 */
> > + <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>, /* project id 1 */
> > + <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>, /* project id 2 */
> > + <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>, /* pcb id 0 */
> > + <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>, /* pcb id 1 */
> > + <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>, /* pcb id 2 */
> > + <6 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>, /* sdp detect */
> > + <6 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>, /* current limit */
> > + <6 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; /* emmc mask */
> > + };
> > + };
> > +
>
> hog node is legacy representation, so we need to have a proper node to
> define these.
>
> > eth_phy {
> > eth_phy_pwr: eth-phy-pwr {
> > rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
> > diff --git a/board/rockchip/tinker_rk3288/tinker-rk3288.c b/board/rockchip/tinker_rk3288/tinker-rk3288.c
> > index 7a0c3c997d..7c65521f55 100644
> > --- a/board/rockchip/tinker_rk3288/tinker-rk3288.c
> > +++ b/board/rockchip/tinker_rk3288/tinker-rk3288.c
> > @@ -5,12 +5,26 @@
> >
> > #include <common.h>
> > #include <dm.h>
> > +#include <dm/device-internal.h>
> > +#include <asm/gpio.h>
> > +#include <dt-bindings/pinctrl/rockchip.h>
> > #include <env.h>
> > #include <i2c_eeprom.h>
> > #include <netdev.h>
> > #include <asm/arch-rockchip/bootrom.h>
> > #include <asm/io.h>
> >
> > +enum project_id {
> > + tinker_board_s = 0,
> > + tinker_board = 7,
> > +};
> > +
> > +enum pcb_id {
> > + SR,
> > + ER,
> > + PR,
> > +};
> > +
> > static int get_ethaddr_from_eeprom(u8 *addr)
> > {
> > int ret;
> > @@ -23,10 +37,14 @@ static int get_ethaddr_from_eeprom(u8 *addr)
> > return i2c_eeprom_read(dev, 0, addr, 6);
> > }
> >
> > +int detect_board_init(void);
>
> Mark this function as static.
>
> > +
> > int rk3288_board_late_init(void)
> > {
> > u8 ethaddr[6];
> >
> > + detect_board_init();
> > +
> > if (get_ethaddr_from_eeprom(ethaddr))
> > return 0;
> >
> > @@ -45,3 +63,68 @@ int mmc_get_env_dev(void)
> >
> > return 1;
> > }
> > +
> > +int detect_board_init(void)
> > +{
> > + int ret = 0, i;
> > + ofnode node;
> > + struct udevice *gpio_dev2 = NULL;
> > + struct udevice *gpio_dev6 = NULL;
> > + struct gpio_desc pcbid[3];
> > + struct gpio_desc pid[3];
> > + enum project_id prjid;
> > + char gpio_name[64];
> > + enum pcb_id pcbversion;
> > +
> > + debug("%s: detect boad\n", __func__);
> > +
> > + if (uclass_get_device_by_name(UCLASS_GPIO, "gpio2 at ff790000", &gpio_dev2) ||
> > + uclass_get_device_by_name(UCLASS_GPIO, "gpio6 at ff7d0000", &gpio_dev6)) {
> > + printf("Could not get GPIO device.\n");
> > + return -EINVAL;
> > + }
> > +
> > + ret = device_probe(gpio_dev2);
> > + if (ret)
> > + pr_err("%s - probe failed: %d\n", gpio_dev2->name, ret);
> > +
> > + ret = device_probe(gpio_dev6);
> > + if (ret)
> > + pr_err("%s - probe failed: %d\n", gpio_dev6->name, ret);
> > +
> > + node = ofnode_path("/board-info");
> > + if (!ofnode_valid(node)) {
> > + pr_err("%s: no /board-info node?\n", __func__);
> > + return -EINVAL;
> > + }
> > +
> > + for (i = 0; i < 3; i++) {
> > + snprintf(gpio_name, 64, "tinker,pid%d", i);
> > + if (gpio_request_by_name_nodev(node, gpio_name, 0,
> > + &pid[i], GPIOD_IS_IN)) {
> > + printf("Failed to request %s\n", gpio_name);
> > + continue;
> > + }
> > + }
> > +
> > + for (i = 0; i < 3; i++) {
> > + snprintf(gpio_name, 64, "tinker,pcbid%d", i);
> > + if (gpio_request_by_name_nodev(node, gpio_name, 0,
> > + &pcbid[i], GPIOD_IS_IN)) {
> > + printf("Failed to request %s\n", gpio_name);
> > + continue;
> > + }
> > + }
> > +
> > + prjid = dm_gpio_get_value(&pid[0]) | \
> > + dm_gpio_get_value(&pid[1]) << 1 | \
> > + dm_gpio_get_value(&pid[2]) << 2;
> > + pcbversion = dm_gpio_get_value(&pcbid[0]) | \
> > + dm_gpio_get_value(&pcbid[1]) << 1 | \
> > + dm_gpio_get_value(&pcbid[2]) << 2;
> > +
> > + printf("Detect %s rev %d\n",
> > + prjid == tinker_board ? "Tinker" : "Tinker S", pcbversion);
>
> I can see the output on my tinker as
> Detect Tinker rev 2
>
> But the back side of PCB show REV 1.2 any clue?
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
More information about the U-Boot
mailing list