summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards/protonic-imx6/board.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boards/protonic-imx6/board.c')
-rw-r--r--arch/arm/boards/protonic-imx6/board.c150
1 files changed, 118 insertions, 32 deletions
diff --git a/arch/arm/boards/protonic-imx6/board.c b/arch/arm/boards/protonic-imx6/board.c
index 6eb31a4bc4..9b2a00c6c3 100644
--- a/arch/arm/boards/protonic-imx6/board.c
+++ b/arch/arm/boards/protonic-imx6/board.c
@@ -5,6 +5,7 @@
#include <bbu.h>
#include <common.h>
+#include <deep-probe.h>
#include <environment.h>
#include <fcntl.h>
#include <gpio.h>
@@ -50,6 +51,8 @@ enum {
HW_TYPE_LANMCU = 23,
HW_TYPE_PLYBAS = 24,
HW_TYPE_VICTGO = 28,
+ HW_TYPE_JOZACP = 30,
+ HW_TYPE_JOZACPP = 31,
};
enum prt_imx6_kvg_pw_mode {
@@ -70,6 +73,7 @@ struct prt_machine_data {
unsigned int hw_rev;
unsigned int i2c_addr;
unsigned int i2c_adapter;
+ unsigned int emmc_usdhc;
unsigned int flags;
int (*init)(struct prt_imx6_priv *priv);
};
@@ -82,6 +86,7 @@ struct prt_imx6_priv {
const char *name;
struct poller_async poller;
unsigned int usb_delay;
+ unsigned int no_usb_check;
};
struct prti6q_rfid_contents {
@@ -136,7 +141,7 @@ static int prt_imx6_read_rfid(struct prt_imx6_priv *priv, void *buf,
/* 0x6000 user storage in the RFID tag */
ret = i2c_read_reg(&cl, 0x6000 | I2C_ADDR_16_BIT, buf, size);
if (ret < 0) {
- dev_err(dev, "Failed to read the RFID: %i\n", ret);
+ dev_err(dev, "Failed to read the RFID: %pe\n", ERR_PTR(ret));
return ret;
}
@@ -171,6 +176,9 @@ static int prt_imx6_set_mac(struct prt_imx6_priv *priv,
return -ENODEV;
}
+ if (!of_device_is_available(node))
+ return 0;
+
if (!is_valid_ether_addr(&rfid->mac[0])) {
unsigned char ethaddr_str[sizeof("xx:xx:xx:xx:xx:xx")];
@@ -340,7 +348,7 @@ static void prt_imx6_check_usb_boot(void *data)
second_word++;
if (strncmp(second_word, "usb", 3) == 0) {
- bootsrc = usbdisk;
+ bootsrc = "usb";
} else if (strncmp(second_word, "recovery", 8) == 0) {
bootsrc = "recovery";
} else {
@@ -375,16 +383,20 @@ static int prt_imx6_env_init(struct prt_imx6_priv *priv)
if (ret)
goto exit_env_init;
- if (dcfg->flags & PRT_IMX6_USB_LONG_DELAY)
- priv->usb_delay = 4;
- else
- priv->usb_delay = 1;
-
- /* the usb_delay value is used for poller_call_async() */
- delay = basprintf("%d", priv->usb_delay);
- ret = setenv("global.autoboot_timeout", delay);
- if (ret)
- goto exit_env_init;
+ if (priv->no_usb_check) {
+ set_autoboot_state(AUTOBOOT_BOOT);
+ } else {
+ if (dcfg->flags & PRT_IMX6_USB_LONG_DELAY)
+ priv->usb_delay = 4;
+ else
+ priv->usb_delay = 1;
+
+ /* the usb_delay value is used for poller_call_async() */
+ delay = basprintf("%d", priv->usb_delay);
+ ret = setenv("global.autoboot_timeout", delay);
+ if (ret)
+ goto exit_env_init;
+ }
if (dcfg->flags & PRT_IMX6_BOOTCHOOSER)
bootsrc = "bootchooser";
@@ -399,7 +411,7 @@ static int prt_imx6_env_init(struct prt_imx6_priv *priv)
return 0;
exit_env_init:
- dev_err(dev, "Failed to set env: %i\n", ret);
+ dev_err(dev, "Failed to set env: %pe\n", ERR_PTR(ret));
return ret;
}
@@ -408,6 +420,7 @@ static int prt_imx6_bbu(struct prt_imx6_priv *priv)
{
const struct prt_machine_data *dcfg = priv->dcfg;
u32 emmc_flags = 0;
+ char *devicefile;
int ret;
if (dcfg->flags & PRT_IMX6_BOOTSRC_SPI_NOR) {
@@ -419,18 +432,19 @@ static int prt_imx6_bbu(struct prt_imx6_priv *priv)
emmc_flags = BBU_HANDLER_FLAG_DEFAULT;
}
- ret = imx6_bbu_internal_mmcboot_register_handler("eMMC", "/dev/mmc2",
- emmc_flags);
- if (ret)
+ devicefile = basprintf("mmc%d", dcfg->emmc_usdhc);
+ if (!devicefile) {
+ ret = -ENOMEM;
goto exit_bbu;
-
- ret = imx6_bbu_internal_mmc_register_handler("SD", "/dev/mmc0", 0);
+ }
+ ret = imx6_bbu_internal_mmcboot_register_handler("eMMC", devicefile,
+ emmc_flags);
if (ret)
goto exit_bbu;
return 0;
exit_bbu:
- dev_err(priv->dev, "Failed to register bbu: %i\n", ret);
+ dev_err(priv->dev, "Failed to register bbu: %pe\n", ERR_PTR(ret));
return ret;
}
@@ -451,14 +465,16 @@ static int prt_imx6_devices_init(void)
prt_imx6_env_init(priv);
- ret = poller_async_register(&priv->poller, "usb-boot");
- if (ret) {
- dev_err(priv->dev, "can't setup poller\n");
- return ret;
- }
+ if (!priv->no_usb_check) {
+ ret = poller_async_register(&priv->poller, "usb-boot");
+ if (ret) {
+ dev_err(priv->dev, "can't setup poller\n");
+ return ret;
+ }
- poller_call_async(&priv->poller, priv->usb_delay * SECOND,
- &prt_imx6_check_usb_boot, priv);
+ poller_call_async(&priv->poller, priv->usb_delay * SECOND,
+ &prt_imx6_check_usb_boot, priv);
+ }
return 0;
}
@@ -503,7 +519,7 @@ static int prt_imx6_yaco_set_kvg_power_mode(struct prt_imx6_priv *priv,
return 0;
exit_yaco_set_kvg_power_mode:
- dev_err(dev, "Failed to set YaCO pw mode: %i", ret);
+ dev_err(dev, "Failed to set YaCO pw mode: %pe", ERR_PTR(ret));
return ret;
}
@@ -611,6 +627,22 @@ static int prt_imx6_init_kvg_yaco(struct prt_imx6_priv *priv)
return prt_imx6_init_kvg_power(priv, PW_MODE_KVG_WITH_YACO);
}
+#define GPIO_KEY_F6 (0xe0 + 5)
+#define GPIO_KEY_CYCLE (0xe0 + 2)
+
+static int prt_imx6_init_prtvt7(struct prt_imx6_priv *priv)
+{
+ /* This function relies heavely on the gpio-pca9539 driver */
+
+ gpio_direction_input(GPIO_KEY_F6);
+ gpio_direction_input(GPIO_KEY_CYCLE);
+
+ if (gpio_get_value(GPIO_KEY_CYCLE) && gpio_get_value(GPIO_KEY_F6))
+ priv->no_usb_check = 1;
+
+ return 0;
+}
+
static int prt_imx6_rfid_fixup(struct prt_imx6_priv *priv,
struct device_node *root)
{
@@ -672,7 +704,7 @@ free_eeprom:
free_alias:
kfree(alias);
exit_error:
- dev_err(priv->dev, "Failed to apply fixup: %i\n", ret);
+ dev_err(priv->dev, "Failed to apply fixup: %pe\n", ERR_PTR(ret));
return ret;
}
@@ -693,7 +725,7 @@ static int prt_imx6_of_fixup(struct device_node *root, void *data)
return 0;
exit_of_fixups:
- dev_err(priv->dev, "Failed to apply OF fixups: %i\n", ret);
+ dev_err(priv->dev, "Failed to apply OF fixups: %pe\n", ERR_PTR(ret));
return ret;
}
@@ -701,8 +733,17 @@ static int prt_imx6_get_id(struct prt_imx6_priv *priv)
{
struct gpio gpios_type[] = GPIO_HW_TYPE_ID;
struct gpio gpios_rev[] = GPIO_HW_REV_ID;
+ struct device_node *gpio_np = NULL;
int ret;
+ gpio_np = of_find_node_by_name(NULL, "gpio@20a0000");
+ if (!gpio_np)
+ return -ENODEV;
+
+ ret = of_device_ensure_probed(gpio_np);
+ if (ret)
+ return ret;
+
ret = gpio_array_to_id(gpios_type, ARRAY_SIZE(gpios_type), &priv->hw_id);
if (ret)
goto exit_get_id;
@@ -713,7 +754,7 @@ static int prt_imx6_get_id(struct prt_imx6_priv *priv)
return 0;
exit_get_id:
- dev_err(priv->dev, "Failed to read gpio ID: %i\n", ret);
+ dev_err(priv->dev, "Failed to read gpio ID: %pe\n", ERR_PTR(ret));
return ret;
}
@@ -808,6 +849,7 @@ static const struct prt_machine_data prt_imx6_cfg_alti6p[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_EMMC,
}, {
.hw_id = UINT_MAX
@@ -820,6 +862,7 @@ static const struct prt_machine_data prt_imx6_cfg_victgo[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.init = prt_imx6_init_victgo,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
@@ -833,12 +876,14 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1[] = {
.hw_rev = 0,
.i2c_addr = 0x50,
.i2c_adapter = 1,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
.hw_id = HW_TYPE_VICUT1,
.hw_rev = 1,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.init = prt_imx6_init_kvg_yaco,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
@@ -846,6 +891,7 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1[] = {
.hw_rev = 1,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.init = prt_imx6_init_kvg_new,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
@@ -859,12 +905,14 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1q[] = {
.hw_rev = 0,
.i2c_addr = 0x50,
.i2c_adapter = 1,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
.hw_id = HW_TYPE_VICUT1,
.hw_rev = 1,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.init = prt_imx6_init_kvg_yaco,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
@@ -872,6 +920,7 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1q[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.init = prt_imx6_init_kvg_yaco,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
@@ -879,6 +928,7 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1q[] = {
.hw_rev = 1,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.init = prt_imx6_init_kvg_new,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
@@ -892,6 +942,7 @@ static const struct prt_machine_data prt_imx6_cfg_vicutp[] = {
.hw_rev = 1,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.init = prt_imx6_init_kvg_new,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
@@ -905,6 +956,7 @@ static const struct prt_machine_data prt_imx6_cfg_lanmcu[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER,
}, {
.hw_id = UINT_MAX
@@ -917,6 +969,7 @@ static const struct prt_machine_data prt_imx6_cfg_plybas[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR | PRT_IMX6_USB_LONG_DELAY,
}, {
.hw_id = UINT_MAX
@@ -929,6 +982,7 @@ static const struct prt_machine_data prt_imx6_cfg_plym2m[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR | PRT_IMX6_USB_LONG_DELAY,
}, {
.hw_id = UINT_MAX
@@ -941,8 +995,9 @@ static const struct prt_machine_data prt_imx6_cfg_prti6g[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 1,
.init = prt_imx6_init_prti6g,
- .flags = PRT_IMX6_BOOTSRC_EMMC,
+ .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER,
}, {
.hw_id = UINT_MAX
},
@@ -954,12 +1009,14 @@ static const struct prt_machine_data prt_imx6_cfg_prti6q[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 2,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
.hw_id = HW_TYPE_PRTI6Q,
.hw_rev = 1,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
.hw_id = UINT_MAX
@@ -972,6 +1029,7 @@ static const struct prt_machine_data prt_imx6_cfg_prtmvt[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
.hw_id = UINT_MAX
@@ -984,6 +1042,7 @@ static const struct prt_machine_data prt_imx6_cfg_prtrvt[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_SPI_NOR,
}, {
.hw_id = UINT_MAX
@@ -996,7 +1055,10 @@ static const struct prt_machine_data prt_imx6_cfg_prtvt7[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
- .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER,
+ .emmc_usdhc = 2,
+ .init = prt_imx6_init_prtvt7,
+ .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER |
+ PRT_IMX6_USB_LONG_DELAY,
}, {
.hw_id = UINT_MAX
},
@@ -1008,6 +1070,7 @@ static const struct prt_machine_data prt_imx6_cfg_prtwd2[] = {
.hw_rev = 0,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_EMMC,
}, {
.hw_id = UINT_MAX
@@ -1020,12 +1083,33 @@ static const struct prt_machine_data prt_imx6_cfg_prtwd3[] = {
.hw_rev = 2,
.i2c_addr = 0x51,
.i2c_adapter = 0,
+ .emmc_usdhc = 2,
.flags = PRT_IMX6_BOOTSRC_EMMC,
}, {
.hw_id = UINT_MAX
},
};
+static const struct prt_machine_data prt_imx6_cfg_jozacp[] = {
+ {
+ .hw_id = HW_TYPE_JOZACP,
+ .hw_rev = 1,
+ .i2c_addr = 0x51,
+ .i2c_adapter = 0,
+ .emmc_usdhc = 0,
+ .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER,
+ }, {
+ .hw_id = HW_TYPE_JOZACPP,
+ .hw_rev = 1,
+ .i2c_addr = 0x51,
+ .i2c_adapter = 0,
+ .emmc_usdhc = 0,
+ .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER,
+ }, {
+ .hw_id = UINT_MAX
+ },
+};
+
static const struct of_device_id prt_imx6_of_match[] = {
{ .compatible = "alt,alti6p", .data = &prt_imx6_cfg_alti6p },
{ .compatible = "kvg,victgo", .data = &prt_imx6_cfg_victgo },
@@ -1042,8 +1126,10 @@ static const struct of_device_id prt_imx6_of_match[] = {
{ .compatible = "prt,prtvt7", .data = &prt_imx6_cfg_prtvt7 },
{ .compatible = "prt,prtwd2", .data = &prt_imx6_cfg_prtwd2 },
{ .compatible = "prt,prtwd3", .data = &prt_imx6_cfg_prtwd3 },
+ { .compatible = "joz,jozacp", .data = &prt_imx6_cfg_jozacp },
{ /* sentinel */ },
};
+BAREBOX_DEEP_PROBE_ENABLE(prt_imx6_of_match);
static struct driver_d prt_imx6_board_driver = {
.name = "board-protonic-imx6",