From 730847512490116aa0bc849cf8c6393f0d56952c Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Mon, 17 Dec 2018 01:53:00 +0100 Subject: apalis-tk1-mainline: mfd: k20: support fw 1.3 Signed-off-by: Dominik Sliwa Acked-by: Marcel Ziswiler --- ...s-tk1-mfd-k20-supporte-for-fw-version-1.2.patch | 550 -------------------- ...s-tk1-mfd-k20-supporte-for-fw-version-1.3.patch | 562 +++++++++++++++++++++ .../linux/linux-toradex-mainline_4.14.bb | 1 + 3 files changed, 563 insertions(+), 550 deletions(-) delete mode 100644 recipes-kernel/linux/linux-toradex-mainline-4.14/0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.2.patch create mode 100644 recipes-kernel/linux/linux-toradex-mainline-4.14/0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.3.patch diff --git a/recipes-kernel/linux/linux-toradex-mainline-4.14/0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.2.patch b/recipes-kernel/linux/linux-toradex-mainline-4.14/0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.2.patch deleted file mode 100644 index 69c4fee..0000000 --- a/recipes-kernel/linux/linux-toradex-mainline-4.14/0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.2.patch +++ /dev/null @@ -1,550 +0,0 @@ -From dd0ee137eb1f5f9906f6edd05c75aa05f0d0bc24 Mon Sep 17 00:00:00 2001 -From: Dominik Sliwa -Date: Tue, 11 Sep 2018 14:05:49 +0200 -Subject: [PATCH 33/33] apalis-tk1: mfd: k20: supporte for fw version 1.2 - -apalis-tk1: mfd: k20: add fw_ignore and fw_reload parameters - -Parameter fw_ignore disables fw version check. -Parameter fw_reload forces k20 firmware reflash via EzPort. - -Signed-off-by: Dominik Sliwa - -apalis-tk1: can: k20: change tx complete signaling - -In fw version 1.2 K20 CANINTF_TX now indicates TX in progress, -not TX completed. - -Signed-off-by: Dominik Sliwa - -apalis-tk1: mfd: k20: update supported fw version to 1.2 - -Signed-off-by: Dominik Sliwa ---- - drivers/mfd/apalis-tk1-k20.c | 214 +++++++++++++++++++-------------- - drivers/net/can/apalis-tk1-k20-can.c | 99 ++++++++++----- - include/linux/mfd/apalis-tk1-k20-api.h | 2 +- - 3 files changed, 195 insertions(+), 120 deletions(-) - -diff --git a/drivers/mfd/apalis-tk1-k20.c b/drivers/mfd/apalis-tk1-k20.c -index 913be65c33e6..38d52b6d2d88 100644 ---- a/drivers/mfd/apalis-tk1-k20.c -+++ b/drivers/mfd/apalis-tk1-k20.c -@@ -2,7 +2,7 @@ - * Copyright 2016-2017 Toradex AG - * Dominik Sliwa - * -- * based on an driver for MC13xxx by: -+ * based on a driver for MC13xxx by: - * Copyright 2009-2010 Pengutronix - * Uwe Kleine-Koenig - * -@@ -29,6 +29,16 @@ - #include "apalis-tk1-k20-ezp.h" - #define APALIS_TK1_K20_MAX_MSG 4 - -+static unsigned int fw_ignore = 0; -+module_param(fw_ignore , uint, 0); -+MODULE_PARM_DESC(fw_ignore, "Assume that K20 is running valid fw version. " -+ "Don't verify, don't erase, don't update"); -+ -+static unsigned int force_fw_reload = 0; -+module_param(force_fw_reload , uint, 0); -+MODULE_PARM_DESC(force_fw_reload, "Update K20 fw even when the same version" -+ " is already flashed."); -+ - static const struct spi_device_id apalis_tk1_k20_device_ids[] = { - { - .name = "apalis-tk1-k20", -@@ -142,7 +152,6 @@ static int apalis_tk1_k20_spi_write(void *context, const void *data, - uint8_t out_data[APALIS_TK1_K20_MAX_BULK]; - int ret; - -- - spi->mode = SPI_MODE_1; - - if (count == 2) { -@@ -704,18 +713,21 @@ static int apalis_tk1_k20_probe_gpios_dt( - apalis_tk1_k20->reset_gpio = of_get_named_gpio(np, "rst-gpio", 0); - if (apalis_tk1_k20->reset_gpio < 0) - return apalis_tk1_k20->reset_gpio; -+ - gpio_request(apalis_tk1_k20->reset_gpio, "apalis-tk1-k20-reset"); - gpio_direction_output(apalis_tk1_k20->reset_gpio, 1); - - apalis_tk1_k20->ezpcs_gpio = of_get_named_gpio(np, "ezport-cs-gpio", 0); - if (apalis_tk1_k20->ezpcs_gpio < 0) - return apalis_tk1_k20->ezpcs_gpio; -+ - gpio_request(apalis_tk1_k20->ezpcs_gpio, "apalis-tk1-k20-ezpcs"); - gpio_direction_output(apalis_tk1_k20->ezpcs_gpio, 1); - - apalis_tk1_k20->int2_gpio = of_get_named_gpio(np, "int2-gpio", 0); - if (apalis_tk1_k20->int2_gpio < 0) - return apalis_tk1_k20->int2_gpio; -+ - gpio_request(apalis_tk1_k20->int2_gpio, "apalis-tk1-k20-int2"); - gpio_direction_output(apalis_tk1_k20->int2_gpio, 1); - -@@ -734,13 +746,101 @@ static inline int apalis_tk1_k20_probe_gpios_dt( - } - #endif - -+int apalis_tk1_k20_fw_update(struct apalis_tk1_k20_regmap *apalis_tk1_k20, -+ uint32_t revision) { -+ int erase_only = 0; -+ -+ if ((request_firmware(&fw_entry, "apalis-tk1-k20.bin", apalis_tk1_k20->dev) < 0) -+ && (revision != APALIS_TK1_K20_FW_VER)) { -+ dev_err(apalis_tk1_k20->dev, -+ "Unsupported firmware version %d.%d and no local" \ -+ " firmware file available.\n", -+ (revision & 0xF0 >> 8), -+ (revision & 0x0F)); -+ return -ENOTSUPP; -+ } -+ -+ if ((fw_entry == NULL) && (revision != APALIS_TK1_K20_FW_VER)) { -+ dev_err(apalis_tk1_k20->dev, -+ "Unsupported firmware version %d.%d and no local" \ -+ " firmware file available.\n", -+ (revision & 0xF0 >> 8), -+ (revision & 0x0F)); -+ return -ENOTSUPP; -+ } -+ -+ if (fw_entry != NULL) { -+ if (fw_entry->size == 1) -+ erase_only = 1; -+ } -+ -+ if ((apalis_tk1_k20_get_fw_revision() != APALIS_TK1_K20_FW_VER) && -+ (revision != APALIS_TK1_K20_FW_VER) && !erase_only && -+ (fw_entry != NULL)) { -+ dev_err(apalis_tk1_k20->dev, -+ "Unsupported firmware version in both the device " \ -+ "as well as the local firmware file.\n"); -+ release_firmware(fw_entry); -+ return -ENOTSUPP; -+ } -+ -+ if ((revision != APALIS_TK1_K20_FW_VER) && !erase_only && -+ (!apalis_tk1_k20_fw_ezport_status()) && -+ (fw_entry != NULL)) { -+ dev_err(apalis_tk1_k20->dev, -+ "Unsupported firmware version in the device and the " \ -+ "local firmware file disables the EZ Port.\n"); -+ release_firmware(fw_entry); -+ return -ENOTSUPP; -+ } -+ -+ if (((revision != APALIS_TK1_K20_FW_VER) || erase_only -+ || force_fw_reload) && (fw_entry != NULL)) { -+ int i = 0; -+ while (apalis_tk1_k20_enter_ezport(apalis_tk1_k20) < 0 -+ && i++ < 5) { -+ msleep(50); -+ } -+ if (i >= 5) { -+ dev_err(apalis_tk1_k20->dev, -+ "Problem entering EZ port mode.\n"); -+ release_firmware(fw_entry); -+ return -EIO; -+ } -+ if (apalis_tk1_k20_erase_chip_ezport(apalis_tk1_k20) < 0) { -+ dev_err(apalis_tk1_k20->dev, -+ "Problem erasing the chip. Deferring...\n"); -+ release_firmware(fw_entry); -+ return -EPROBE_DEFER; -+ } -+ if (erase_only) { -+ dev_err(apalis_tk1_k20->dev, -+ "Chip fully erased.\n"); -+ release_firmware(fw_entry); -+ return -EIO; -+ } -+ if (apalis_tk1_k20_flash_chip_ezport(apalis_tk1_k20) < 0) { -+ dev_err(apalis_tk1_k20->dev, -+ "Problem flashing new firmware. Deferring...\n"); -+ release_firmware(fw_entry); -+ return -EPROBE_DEFER; -+ } -+ -+ return 1; -+ } -+ if (fw_entry != NULL) -+ release_firmware(fw_entry); -+ -+ return 0; -+ -+} -+ - int apalis_tk1_k20_dev_init(struct device *dev) - { - struct apalis_tk1_k20_platform_data *pdata = dev_get_platdata(dev); - struct apalis_tk1_k20_regmap *apalis_tk1_k20 = dev_get_drvdata(dev); - uint32_t revision = 0x00; - int ret, i; -- int erase_only = 0; - - apalis_tk1_k20->dev = dev; - -@@ -762,99 +862,21 @@ int apalis_tk1_k20_dev_init(struct device *dev) - &revision); - - #ifdef CONFIG_APALIS_TK1_K20_EZP -- if ((request_firmware(&fw_entry, "apalis-tk1-k20.bin", dev) < 0) -- && (revision != APALIS_TK1_K20_FW_VER)) { -- dev_err(apalis_tk1_k20->dev, -- "Unsupported firmware version %d.%d and no local" \ -- " firmware file available.\n", -- (revision & 0xF0 >> 8), -- (revision & 0x0F)); -- ret = -ENOTSUPP; -- goto bad; -- } - -- if ((fw_entry == NULL) && (revision != APALIS_TK1_K20_FW_VER)) { -- dev_err(apalis_tk1_k20->dev, -- "Unsupported firmware version %d.%d and no local" \ -- " firmware file available.\n", -- (revision & 0xF0 >> 8), -- (revision & 0x0F)); -- ret = -ENOTSUPP; -- goto bad; -- } -- -- if (fw_entry != NULL) { -- if (fw_entry->size == 1) -- erase_only = 1; -- } -- -- if ((apalis_tk1_k20_get_fw_revision() != APALIS_TK1_K20_FW_VER) && -- (revision != APALIS_TK1_K20_FW_VER) && !erase_only && -- (fw_entry != NULL)) { -- dev_err(apalis_tk1_k20->dev, -- "Unsupported firmware version in both the device " \ -- "as well as the local firmware file.\n"); -- release_firmware(fw_entry); -- ret = -ENOTSUPP; -- goto bad; -- } -- -- if ((revision != APALIS_TK1_K20_FW_VER) && !erase_only && -- (!apalis_tk1_k20_fw_ezport_status()) && -- (fw_entry != NULL)) { -- dev_err(apalis_tk1_k20->dev, -- "Unsupported firmware version in the device and the " \ -- "local firmware file disables the EZ Port.\n"); -- release_firmware(fw_entry); -- ret = -ENOTSUPP; -- goto bad; -- } -+ if (fw_ignore == 0) { -+ ret = apalis_tk1_k20_fw_update(apalis_tk1_k20, revision); - -- if (((revision != APALIS_TK1_K20_FW_VER) || erase_only) && -- (fw_entry != NULL)) { -- i = 0; -- while (apalis_tk1_k20_enter_ezport(apalis_tk1_k20) < 0 -- && i++ < 5) { -- msleep(50); -- } -- if (i >= 5) { -- dev_err(apalis_tk1_k20->dev, -- "Problem entering EZ port mode.\n"); -- release_firmware(fw_entry); -- ret = -EIO; -+ if (ret < 0) - goto bad; -- } -- if (apalis_tk1_k20_erase_chip_ezport(apalis_tk1_k20) < 0) { -- dev_err(apalis_tk1_k20->dev, -- "Problem erasing the chip.\n"); -- release_firmware(fw_entry); -- ret = -EPROBE_DEFER; -- goto bad; -- } -- if (erase_only) { -- dev_err(apalis_tk1_k20->dev, -- "Chip fully erased.\n"); -- release_firmware(fw_entry); -- ret = -EIO; -- goto bad; -- } -- if (apalis_tk1_k20_flash_chip_ezport(apalis_tk1_k20) < 0) { -- dev_err(apalis_tk1_k20->dev, -- "Problem flashing new firmware.\n"); -- release_firmware(fw_entry); -- ret = -EPROBE_DEFER; -- goto bad; -- } - } -- if (fw_entry != NULL) -- release_firmware(fw_entry); -- -- msleep(10); -- apalis_tk1_k20_reset_chip(apalis_tk1_k20); -- msleep(10); -+ if (ret) { -+ msleep(10); -+ apalis_tk1_k20_reset_chip(apalis_tk1_k20); -+ msleep(10); - -- ret = apalis_tk1_k20_reg_read(apalis_tk1_k20, APALIS_TK1_K20_REVREG, -- &revision); -+ ret = apalis_tk1_k20_reg_read(apalis_tk1_k20, APALIS_TK1_K20_REVREG, -+ &revision); -+ } - #endif /* CONFIG_APALIS_TK1_K20_EZP */ - - if (ret) { -@@ -862,7 +884,7 @@ int apalis_tk1_k20_dev_init(struct device *dev) - goto bad; - } - -- if (revision != APALIS_TK1_K20_FW_VER) { -+ if ((revision != APALIS_TK1_K20_FW_VER) && (fw_ignore == 0)) { - dev_err(apalis_tk1_k20->dev, - "Unsupported firmware version %d.%d.\n", - ((revision & 0xF0) >> 4), (revision & 0x0F)); -@@ -870,6 +892,14 @@ int apalis_tk1_k20_dev_init(struct device *dev) - goto bad; - } - -+ if (fw_ignore == 1) { -+ dev_err(apalis_tk1_k20->dev, "fw_ignore == 1. Detected " -+ "firmware %d.%d. Driver expected %d.%d\n", -+ ((revision & 0xF0) >> 4), (revision & 0x0F), -+ ((APALIS_TK1_K20_FW_VER & 0xF0) >> 4), -+ (APALIS_TK1_K20_FW_VER & 0x0F)); -+ } -+ - for (i = 0; i < ARRAY_SIZE(apalis_tk1_k20->irqs); i++) { - apalis_tk1_k20->irqs[i].reg_offset = i / - APALIS_TK1_K20_IRQ_PER_REG; -diff --git a/drivers/net/can/apalis-tk1-k20-can.c b/drivers/net/can/apalis-tk1-k20-can.c -index e24adbb35dfd..0c238b8062ca 100644 ---- a/drivers/net/can/apalis-tk1-k20-can.c -+++ b/drivers/net/can/apalis-tk1-k20-can.c -@@ -42,11 +42,12 @@ - #define MB_DLC_MASK 0xF - #define MB_EID_LEN 4 - --#define CANCTRL_MODMASK 0x03 --#define CANCTRL_INTEN BIT(2) --#define CANINTF_RX BIT(3) --#define CANINTF_TX BIT(4) --#define CANINTF_ERR BIT(5) -+#define CANCTRL_MODMASK (BIT(1) | BIT(0)) -+#define CANCTRL_INTEN BIT(2) -+#define CANINTF_RX BIT(3) -+#define CANINTF_TX BIT(4) -+#define CANINTF_ERR BIT(5) -+#define CANCTRL_ENABLE BIT(6) - #define CANCTRL_INTMASK (CANINTF_RX | CANINTF_TX | CANINTF_ERR) - - #define EFLG_EWARN 0x01 -@@ -95,6 +96,7 @@ struct apalis_tk1_k20_priv { - #define AFTER_SUSPEND_DOWN 2 - #define AFTER_SUSPEND_RESTART 4 - int restart_tx; -+ int tx_frame; - }; - - static void apalis_tk1_k20_can_clean(struct net_device *net) -@@ -123,6 +125,8 @@ static void apalis_tk1_k20_can_hw_tx_frame(struct net_device *net, u8 *buf, - + APALIS_TK1_K20_CAN_DEV_OFFSET( - priv->pdata->id), buf, len); - apalis_tk1_k20_unlock(priv->apalis_tk1_k20); -+ -+ priv->tx_frame = 1; - } - - static void apalis_tk1_k20_can_hw_tx(struct net_device *net, -@@ -233,11 +237,8 @@ static int apalis_tk1_k20_can_set_normal_mode(struct net_device *net) - struct apalis_tk1_k20_priv *priv = netdev_priv(net); - - apalis_tk1_k20_lock(priv->apalis_tk1_k20); -- /* Enable interrupts */ -- apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, APALIS_TK1_K20_CANREG -- + APALIS_TK1_K20_CAN_DEV_OFFSET( -- priv->pdata->id), -- CANCTRL_INTEN, CANCTRL_INTEN); -+ -+ priv->can.state = CAN_STATE_ERROR_ACTIVE; - - if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { - /* Put device into loopback mode */ -@@ -253,6 +254,14 @@ static int apalis_tk1_k20_can_set_normal_mode(struct net_device *net) - + APALIS_TK1_K20_CAN_DEV_OFFSET( - priv->pdata->id), CANCTRL_MODMASK, - CAN_CTRLMODE_LISTENONLY); -+ priv->can.state = CAN_STATE_ERROR_PASSIVE; -+ } else if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) { -+ /* Put device into triple sampling mode */ -+ apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, -+ APALIS_TK1_K20_CANREG -+ + APALIS_TK1_K20_CAN_DEV_OFFSET( -+ priv->pdata->id), CANCTRL_MODMASK, -+ 0x03); - } else { - /* Put device into normal mode */ - apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, -@@ -262,7 +271,28 @@ static int apalis_tk1_k20_can_set_normal_mode(struct net_device *net) - 0x00); - } - apalis_tk1_k20_unlock(priv->apalis_tk1_k20); -- priv->can.state = CAN_STATE_ERROR_ACTIVE; -+ -+ return 0; -+} -+ -+static int apalis_tk1_k20_can_enable(struct net_device *net, -+ bool enable) -+{ -+ struct apalis_tk1_k20_priv *priv = netdev_priv(net); -+ -+ apalis_tk1_k20_lock(priv->apalis_tk1_k20); -+ /* Enable interrupts */ -+ apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, APALIS_TK1_K20_CANREG -+ + APALIS_TK1_K20_CAN_DEV_OFFSET( -+ priv->pdata->id), -+ CANCTRL_INTEN, (enable) ? CANCTRL_INTEN:0); -+ /* Enable CAN */ -+ apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, APALIS_TK1_K20_CANREG -+ + APALIS_TK1_K20_CAN_DEV_OFFSET( -+ priv->pdata->id), -+ CANCTRL_ENABLE, (enable) ? CANCTRL_ENABLE:0); -+ apalis_tk1_k20_unlock(priv->apalis_tk1_k20); -+ - return 0; - } - -@@ -350,6 +380,8 @@ static int apalis_tk1_k20_can_stop(struct net_device *net) - destroy_workqueue(priv->wq); - priv->wq = NULL; - -+ apalis_tk1_k20_can_enable(net, false); -+ - mutex_lock(&priv->apalis_tk1_k20_can_lock); - apalis_tk1_k20_lock(priv->apalis_tk1_k20); - if (pdata->id == 0) -@@ -358,7 +390,7 @@ static int apalis_tk1_k20_can_stop(struct net_device *net) - if (pdata->id == 1) - apalis_tk1_k20_irq_mask(priv->apalis_tk1_k20, - APALIS_TK1_K20_CAN1_IRQ); -- /* Disable and clear pending interrupts */ -+ - priv->can.state = CAN_STATE_STOPPED; - apalis_tk1_k20_unlock(priv->apalis_tk1_k20); - mutex_unlock(&priv->apalis_tk1_k20_can_lock); -@@ -462,7 +494,7 @@ static int apalis_tk1_k20_can_resume(struct device *dev) - if (pdata->id == 1) - apalis_tk1_k20_irq_unmask(priv->apalis_tk1_k20, - APALIS_TK1_K20_CAN1_IRQ); -- /* Enable interrupts */ -+ - priv->can.state = CAN_STATE_STOPPED; - apalis_tk1_k20_unlock(priv->apalis_tk1_k20); - mutex_unlock(&priv->apalis_tk1_k20_can_lock); -@@ -519,6 +551,7 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) - u8 clear_intf = 0; - int can_id = 0, data1 = 0; - -+ - apalis_tk1_k20_lock(priv->apalis_tk1_k20); - ret = apalis_tk1_k20_reg_read(priv->apalis_tk1_k20, - APALIS_TK1_K20_CANREG -@@ -532,6 +565,25 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) - } - - intf &= CANCTRL_INTMASK; -+ -+ if (!(intf & CANINTF_TX) && -+ (priv->tx_frame == 1)) { -+ priv->tx_frame = 0; -+ net->stats.tx_packets++; -+ net->stats.tx_bytes += priv->tx_len - 1; -+ can_led_event(net, CAN_LED_EVENT_TX); -+ if (priv->tx_len) { -+ can_get_echo_skb(net, 0); -+ priv->tx_len = 0; -+ } -+ netif_wake_queue(net); -+ if (!(intf & (CANINTF_RX | CANINTF_ERR))) -+ break; -+ } -+ -+ if (intf == 0) -+ break; -+ - /* receive */ - if (intf & CANINTF_RX) - apalis_tk1_k20_can_hw_rx(net, 0); -@@ -625,21 +677,7 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) - break; - } - -- if (intf == 0) -- break; - -- if (intf & CANINTF_TX) { -- net->stats.tx_packets++; -- net->stats.tx_bytes += priv->tx_len - 1; -- can_led_event(net, CAN_LED_EVENT_TX); -- if (priv->tx_len) { -- can_get_echo_skb(net, 0); -- priv->tx_len = 0; -- } -- netif_wake_queue(net); -- if (!(intf & (CANINTF_RX | CANINTF_ERR))) -- break; -- } - } - mutex_unlock(&priv->apalis_tk1_k20_can_lock); - return IRQ_HANDLED; -@@ -662,6 +700,7 @@ static int apalis_tk1_k20_can_open(struct net_device *net) - priv->force_quit = 0; - priv->tx_skb = NULL; - priv->tx_len = 0; -+ priv->tx_frame = 0; - apalis_tk1_k20_lock(priv->apalis_tk1_k20); - if (pdata->id == 0) - ret = apalis_tk1_k20_irq_request(priv->apalis_tk1_k20, -@@ -701,6 +740,11 @@ static int apalis_tk1_k20_can_open(struct net_device *net) - apalis_tk1_k20_can_open_clean(net); - goto open_unlock; - } -+ ret = apalis_tk1_k20_can_enable(net, true); -+ if (ret) { -+ apalis_tk1_k20_can_open_clean(net); -+ goto open_unlock; -+ } - - can_led_event(net, CAN_LED_EVENT_OPEN); - -@@ -765,6 +809,7 @@ static int apalis_tk1_k20_can_probe(struct platform_device *pdev) - platform_set_drvdata(pdev, priv); - - ret = register_candev(net); -+ - if (ret) - goto error_probe; - -diff --git a/include/linux/mfd/apalis-tk1-k20-api.h b/include/linux/mfd/apalis-tk1-k20-api.h -index 199b433c3d96..112a79b6b4e8 100644 ---- a/include/linux/mfd/apalis-tk1-k20-api.h -+++ b/include/linux/mfd/apalis-tk1-k20-api.h -@@ -104,7 +104,7 @@ - #define APALIS_TK1_K20_TSC_IRQ 4 - #define APALIS_TK1_K20_GPIO_IRQ 5 - --#define APALIS_TK1_K20_FW_VER 0x11 -+#define APALIS_TK1_K20_FW_VER 0x12 - #define APALIS_TK1_K20_TESTER_FW_VER 0xFE - - #define FW_MINOR (APALIS_TK1_K20_FW_VER & 0x0F) --- -2.13.6 - diff --git a/recipes-kernel/linux/linux-toradex-mainline-4.14/0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.3.patch b/recipes-kernel/linux/linux-toradex-mainline-4.14/0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.3.patch new file mode 100644 index 0000000..f98a7bb --- /dev/null +++ b/recipes-kernel/linux/linux-toradex-mainline-4.14/0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.3.patch @@ -0,0 +1,562 @@ +From 0f4ef2cbf760bc5ec8a78918baaccd75f3bc7f44 Mon Sep 17 00:00:00 2001 +From: Dominik Sliwa +Date: Tue, 11 Sep 2018 14:05:49 +0200 +Subject: [PATCH 33/33] apalis-tk1: mfd: k20: supporte for fw version 1.2 + +apalis-tk1: mfd: k20: add fw_ignore and fw_reload parameters + +Parameter fw_ignore disables fw version check. +Parameter fw_reload forces k20 firmware reflash via EzPort. + +Signed-off-by: Dominik Sliwa + +apalis-tk1: can: k20: change tx complete signaling + +In fw version 1.2 K20 CANINTF_TX now indicates TX in progress, +not TX completed. + +Signed-off-by: Dominik Sliwa + +apalis-tk1: mfd: k20: update supported fw version to 1.2 + +Signed-off-by: Dominik Sliwa + +apalis-tk1: mfd: k20: release fw after flashing + +Previously fw was not released when K20 was flashed successfully + +Signed-off-by: Dominik Sliwa + +apalis-tk1: mfd: k20: extra cycles for fifo cleanup + +Signed-off-by: Dominik Sliwa + +apalis-tk1: mfd: k20: update supported fw version to 1.3 + +Signed-off-by: Dominik Sliwa +--- + drivers/mfd/apalis-tk1-k20.c | 168 ++++++++++++++----------- + drivers/net/can/apalis-tk1-k20-can.c | 99 +++++++++++---- + include/linux/mfd/apalis-tk1-k20-api.h | 2 +- + 3 files changed, 171 insertions(+), 98 deletions(-) + +diff --git a/drivers/mfd/apalis-tk1-k20.c b/drivers/mfd/apalis-tk1-k20.c +index 913be65c33e6..a6d1c1cdc0b6 100644 +--- a/drivers/mfd/apalis-tk1-k20.c ++++ b/drivers/mfd/apalis-tk1-k20.c +@@ -2,7 +2,7 @@ + * Copyright 2016-2017 Toradex AG + * Dominik Sliwa + * +- * based on an driver for MC13xxx by: ++ * based on a driver for MC13xxx by: + * Copyright 2009-2010 Pengutronix + * Uwe Kleine-Koenig + * +@@ -29,6 +29,16 @@ + #include "apalis-tk1-k20-ezp.h" + #define APALIS_TK1_K20_MAX_MSG 4 + ++static unsigned int fw_ignore = 0; ++module_param(fw_ignore , uint, 0); ++MODULE_PARM_DESC(fw_ignore, "Assume that K20 is running valid fw version. " ++ "Don't verify, don't erase, don't update"); ++ ++static unsigned int force_fw_reload = 0; ++module_param(force_fw_reload , uint, 0); ++MODULE_PARM_DESC(force_fw_reload, "Update K20 fw even when the same version" ++ " is already flashed."); ++ + static const struct spi_device_id apalis_tk1_k20_device_ids[] = { + { + .name = "apalis-tk1-k20", +@@ -115,7 +125,7 @@ static int apalis_tk1_k20_spi_read(void *context, const void *reg, + ret = -EIO; + + } else if ((val_size > 1) && (val_size < APALIS_TK1_K20_MAX_BULK)) { +- t.len = 5; ++ t.len = 12; + w[0] = APALIS_TK1_K20_BULK_READ_INST; + spi_message_init(&m); + spi_message_add_tail(&t, &m); +@@ -142,7 +152,6 @@ static int apalis_tk1_k20_spi_write(void *context, const void *data, + uint8_t out_data[APALIS_TK1_K20_MAX_BULK]; + int ret; + +- + spi->mode = SPI_MODE_1; + + if (count == 2) { +@@ -704,18 +713,21 @@ static int apalis_tk1_k20_probe_gpios_dt( + apalis_tk1_k20->reset_gpio = of_get_named_gpio(np, "rst-gpio", 0); + if (apalis_tk1_k20->reset_gpio < 0) + return apalis_tk1_k20->reset_gpio; ++ + gpio_request(apalis_tk1_k20->reset_gpio, "apalis-tk1-k20-reset"); + gpio_direction_output(apalis_tk1_k20->reset_gpio, 1); + + apalis_tk1_k20->ezpcs_gpio = of_get_named_gpio(np, "ezport-cs-gpio", 0); + if (apalis_tk1_k20->ezpcs_gpio < 0) + return apalis_tk1_k20->ezpcs_gpio; ++ + gpio_request(apalis_tk1_k20->ezpcs_gpio, "apalis-tk1-k20-ezpcs"); + gpio_direction_output(apalis_tk1_k20->ezpcs_gpio, 1); + + apalis_tk1_k20->int2_gpio = of_get_named_gpio(np, "int2-gpio", 0); + if (apalis_tk1_k20->int2_gpio < 0) + return apalis_tk1_k20->int2_gpio; ++ + gpio_request(apalis_tk1_k20->int2_gpio, "apalis-tk1-k20-int2"); + gpio_direction_output(apalis_tk1_k20->int2_gpio, 1); + +@@ -734,53 +746,28 @@ static inline int apalis_tk1_k20_probe_gpios_dt( + } + #endif + +-int apalis_tk1_k20_dev_init(struct device *dev) ++int apalis_tk1_k20_fw_update(struct apalis_tk1_k20_regmap *apalis_tk1_k20, ++ uint32_t revision) + { +- struct apalis_tk1_k20_platform_data *pdata = dev_get_platdata(dev); +- struct apalis_tk1_k20_regmap *apalis_tk1_k20 = dev_get_drvdata(dev); +- uint32_t revision = 0x00; +- int ret, i; + int erase_only = 0; + +- apalis_tk1_k20->dev = dev; +- +- ret = apalis_tk1_k20_probe_gpios_dt(apalis_tk1_k20); +- if ((ret < 0) && pdata) { +- if (pdata) { +- apalis_tk1_k20->ezpcs_gpio = pdata->ezpcs_gpio; +- apalis_tk1_k20->reset_gpio = pdata->reset_gpio; +- apalis_tk1_k20->int2_gpio = pdata->int2_gpio; +- } else { +- dev_err(dev, "Error claiming GPIOs\n"); +- ret = -EINVAL; +- goto bad; +- } +- } +- apalis_tk1_k20_reset_chip(apalis_tk1_k20); +- msleep(10); +- ret = apalis_tk1_k20_reg_read(apalis_tk1_k20, APALIS_TK1_K20_REVREG, +- &revision); +- +-#ifdef CONFIG_APALIS_TK1_K20_EZP +- if ((request_firmware(&fw_entry, "apalis-tk1-k20.bin", dev) < 0) ++ if ((request_firmware(&fw_entry, "apalis-tk1-k20.bin", ++ apalis_tk1_k20->dev) ++ < 0) + && (revision != APALIS_TK1_K20_FW_VER)) { + dev_err(apalis_tk1_k20->dev, +- "Unsupported firmware version %d.%d and no local" \ ++ "Unsupported firmware version %d.%d and no local" + " firmware file available.\n", +- (revision & 0xF0 >> 8), +- (revision & 0x0F)); +- ret = -ENOTSUPP; +- goto bad; ++ (revision & 0xF0 >> 8), (revision & 0x0F)); ++ return -ENOTSUPP; + } + + if ((fw_entry == NULL) && (revision != APALIS_TK1_K20_FW_VER)) { + dev_err(apalis_tk1_k20->dev, +- "Unsupported firmware version %d.%d and no local" \ ++ "Unsupported firmware version %d.%d and no local" + " firmware file available.\n", +- (revision & 0xF0 >> 8), +- (revision & 0x0F)); +- ret = -ENOTSUPP; +- goto bad; ++ (revision & 0xF0 >> 8), (revision & 0x0F)); ++ return -ENOTSUPP; + } + + if (fw_entry != NULL) { +@@ -788,73 +775,106 @@ int apalis_tk1_k20_dev_init(struct device *dev) + erase_only = 1; + } + +- if ((apalis_tk1_k20_get_fw_revision() != APALIS_TK1_K20_FW_VER) && +- (revision != APALIS_TK1_K20_FW_VER) && !erase_only && +- (fw_entry != NULL)) { ++ if ((apalis_tk1_k20_get_fw_revision() != APALIS_TK1_K20_FW_VER) ++ && (revision != APALIS_TK1_K20_FW_VER) && !erase_only ++ && (fw_entry != NULL)) { + dev_err(apalis_tk1_k20->dev, +- "Unsupported firmware version in both the device " \ ++ "Unsupported firmware version in both the device " + "as well as the local firmware file.\n"); + release_firmware(fw_entry); +- ret = -ENOTSUPP; +- goto bad; ++ return -ENOTSUPP; + } + +- if ((revision != APALIS_TK1_K20_FW_VER) && !erase_only && +- (!apalis_tk1_k20_fw_ezport_status()) && +- (fw_entry != NULL)) { ++ if ((revision != APALIS_TK1_K20_FW_VER) && !erase_only ++ && (!apalis_tk1_k20_fw_ezport_status()) && (fw_entry != NULL)) { + dev_err(apalis_tk1_k20->dev, +- "Unsupported firmware version in the device and the " \ ++ "Unsupported firmware version in the device and the " + "local firmware file disables the EZ Port.\n"); + release_firmware(fw_entry); +- ret = -ENOTSUPP; +- goto bad; ++ return -ENOTSUPP; + } + +- if (((revision != APALIS_TK1_K20_FW_VER) || erase_only) && +- (fw_entry != NULL)) { +- i = 0; ++ if (((revision != APALIS_TK1_K20_FW_VER) || erase_only ++ || force_fw_reload) ++ && (fw_entry != NULL)) { ++ int i = 0; + while (apalis_tk1_k20_enter_ezport(apalis_tk1_k20) < 0 +- && i++ < 5) { ++ && i++ < 5) { + msleep(50); + } + if (i >= 5) { + dev_err(apalis_tk1_k20->dev, + "Problem entering EZ port mode.\n"); + release_firmware(fw_entry); +- ret = -EIO; +- goto bad; ++ return -EIO; + } + if (apalis_tk1_k20_erase_chip_ezport(apalis_tk1_k20) < 0) { + dev_err(apalis_tk1_k20->dev, +- "Problem erasing the chip.\n"); ++ "Problem erasing the chip. Deferring...\n"); + release_firmware(fw_entry); +- ret = -EPROBE_DEFER; +- goto bad; ++ return -EPROBE_DEFER; + } + if (erase_only) { +- dev_err(apalis_tk1_k20->dev, +- "Chip fully erased.\n"); ++ dev_err(apalis_tk1_k20->dev, "Chip fully erased.\n"); + release_firmware(fw_entry); +- ret = -EIO; +- goto bad; ++ return -EIO; + } + if (apalis_tk1_k20_flash_chip_ezport(apalis_tk1_k20) < 0) { + dev_err(apalis_tk1_k20->dev, +- "Problem flashing new firmware.\n"); ++ "Problem flashing new firmware. Deferring...\n"); + release_firmware(fw_entry); +- ret = -EPROBE_DEFER; +- goto bad; ++ return -EPROBE_DEFER; + } + } ++ + if (fw_entry != NULL) + release_firmware(fw_entry); + +- msleep(10); ++ return 1; ++} ++ ++int apalis_tk1_k20_dev_init(struct device *dev) ++{ ++ struct apalis_tk1_k20_platform_data *pdata = dev_get_platdata(dev); ++ struct apalis_tk1_k20_regmap *apalis_tk1_k20 = dev_get_drvdata(dev); ++ uint32_t revision = 0x00; ++ int ret, i; ++ ++ apalis_tk1_k20->dev = dev; ++ ++ ret = apalis_tk1_k20_probe_gpios_dt(apalis_tk1_k20); ++ if ((ret < 0) && pdata) { ++ if (pdata) { ++ apalis_tk1_k20->ezpcs_gpio = pdata->ezpcs_gpio; ++ apalis_tk1_k20->reset_gpio = pdata->reset_gpio; ++ apalis_tk1_k20->int2_gpio = pdata->int2_gpio; ++ } else { ++ dev_err(dev, "Error claiming GPIOs\n"); ++ ret = -EINVAL; ++ goto bad; ++ } ++ } + apalis_tk1_k20_reset_chip(apalis_tk1_k20); + msleep(10); +- + ret = apalis_tk1_k20_reg_read(apalis_tk1_k20, APALIS_TK1_K20_REVREG, + &revision); ++ ++#ifdef CONFIG_APALIS_TK1_K20_EZP ++ ++ if (fw_ignore == 0) { ++ ret = apalis_tk1_k20_fw_update(apalis_tk1_k20, revision); ++ ++ if (ret < 0) ++ goto bad; ++ } ++ if (ret) { ++ msleep(10); ++ apalis_tk1_k20_reset_chip(apalis_tk1_k20); ++ msleep(10); ++ ++ ret = apalis_tk1_k20_reg_read(apalis_tk1_k20, APALIS_TK1_K20_REVREG, ++ &revision); ++ } + #endif /* CONFIG_APALIS_TK1_K20_EZP */ + + if (ret) { +@@ -862,7 +882,7 @@ int apalis_tk1_k20_dev_init(struct device *dev) + goto bad; + } + +- if (revision != APALIS_TK1_K20_FW_VER) { ++ if ((revision != APALIS_TK1_K20_FW_VER) && (fw_ignore == 0)) { + dev_err(apalis_tk1_k20->dev, + "Unsupported firmware version %d.%d.\n", + ((revision & 0xF0) >> 4), (revision & 0x0F)); +@@ -870,6 +890,14 @@ int apalis_tk1_k20_dev_init(struct device *dev) + goto bad; + } + ++ if (fw_ignore == 1) { ++ dev_err(apalis_tk1_k20->dev, "fw_ignore == 1. Detected " ++ "firmware %d.%d. Driver expected %d.%d\n", ++ ((revision & 0xF0) >> 4), (revision & 0x0F), ++ ((APALIS_TK1_K20_FW_VER & 0xF0) >> 4), ++ (APALIS_TK1_K20_FW_VER & 0x0F)); ++ } ++ + for (i = 0; i < ARRAY_SIZE(apalis_tk1_k20->irqs); i++) { + apalis_tk1_k20->irqs[i].reg_offset = i / + APALIS_TK1_K20_IRQ_PER_REG; +diff --git a/drivers/net/can/apalis-tk1-k20-can.c b/drivers/net/can/apalis-tk1-k20-can.c +index e24adbb35dfd..0c238b8062ca 100644 +--- a/drivers/net/can/apalis-tk1-k20-can.c ++++ b/drivers/net/can/apalis-tk1-k20-can.c +@@ -42,11 +42,12 @@ + #define MB_DLC_MASK 0xF + #define MB_EID_LEN 4 + +-#define CANCTRL_MODMASK 0x03 +-#define CANCTRL_INTEN BIT(2) +-#define CANINTF_RX BIT(3) +-#define CANINTF_TX BIT(4) +-#define CANINTF_ERR BIT(5) ++#define CANCTRL_MODMASK (BIT(1) | BIT(0)) ++#define CANCTRL_INTEN BIT(2) ++#define CANINTF_RX BIT(3) ++#define CANINTF_TX BIT(4) ++#define CANINTF_ERR BIT(5) ++#define CANCTRL_ENABLE BIT(6) + #define CANCTRL_INTMASK (CANINTF_RX | CANINTF_TX | CANINTF_ERR) + + #define EFLG_EWARN 0x01 +@@ -95,6 +96,7 @@ struct apalis_tk1_k20_priv { + #define AFTER_SUSPEND_DOWN 2 + #define AFTER_SUSPEND_RESTART 4 + int restart_tx; ++ int tx_frame; + }; + + static void apalis_tk1_k20_can_clean(struct net_device *net) +@@ -123,6 +125,8 @@ static void apalis_tk1_k20_can_hw_tx_frame(struct net_device *net, u8 *buf, + + APALIS_TK1_K20_CAN_DEV_OFFSET( + priv->pdata->id), buf, len); + apalis_tk1_k20_unlock(priv->apalis_tk1_k20); ++ ++ priv->tx_frame = 1; + } + + static void apalis_tk1_k20_can_hw_tx(struct net_device *net, +@@ -233,11 +237,8 @@ static int apalis_tk1_k20_can_set_normal_mode(struct net_device *net) + struct apalis_tk1_k20_priv *priv = netdev_priv(net); + + apalis_tk1_k20_lock(priv->apalis_tk1_k20); +- /* Enable interrupts */ +- apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, APALIS_TK1_K20_CANREG +- + APALIS_TK1_K20_CAN_DEV_OFFSET( +- priv->pdata->id), +- CANCTRL_INTEN, CANCTRL_INTEN); ++ ++ priv->can.state = CAN_STATE_ERROR_ACTIVE; + + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { + /* Put device into loopback mode */ +@@ -253,6 +254,14 @@ static int apalis_tk1_k20_can_set_normal_mode(struct net_device *net) + + APALIS_TK1_K20_CAN_DEV_OFFSET( + priv->pdata->id), CANCTRL_MODMASK, + CAN_CTRLMODE_LISTENONLY); ++ priv->can.state = CAN_STATE_ERROR_PASSIVE; ++ } else if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) { ++ /* Put device into triple sampling mode */ ++ apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, ++ APALIS_TK1_K20_CANREG ++ + APALIS_TK1_K20_CAN_DEV_OFFSET( ++ priv->pdata->id), CANCTRL_MODMASK, ++ 0x03); + } else { + /* Put device into normal mode */ + apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, +@@ -262,7 +271,28 @@ static int apalis_tk1_k20_can_set_normal_mode(struct net_device *net) + 0x00); + } + apalis_tk1_k20_unlock(priv->apalis_tk1_k20); +- priv->can.state = CAN_STATE_ERROR_ACTIVE; ++ ++ return 0; ++} ++ ++static int apalis_tk1_k20_can_enable(struct net_device *net, ++ bool enable) ++{ ++ struct apalis_tk1_k20_priv *priv = netdev_priv(net); ++ ++ apalis_tk1_k20_lock(priv->apalis_tk1_k20); ++ /* Enable interrupts */ ++ apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, APALIS_TK1_K20_CANREG ++ + APALIS_TK1_K20_CAN_DEV_OFFSET( ++ priv->pdata->id), ++ CANCTRL_INTEN, (enable) ? CANCTRL_INTEN:0); ++ /* Enable CAN */ ++ apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, APALIS_TK1_K20_CANREG ++ + APALIS_TK1_K20_CAN_DEV_OFFSET( ++ priv->pdata->id), ++ CANCTRL_ENABLE, (enable) ? CANCTRL_ENABLE:0); ++ apalis_tk1_k20_unlock(priv->apalis_tk1_k20); ++ + return 0; + } + +@@ -350,6 +380,8 @@ static int apalis_tk1_k20_can_stop(struct net_device *net) + destroy_workqueue(priv->wq); + priv->wq = NULL; + ++ apalis_tk1_k20_can_enable(net, false); ++ + mutex_lock(&priv->apalis_tk1_k20_can_lock); + apalis_tk1_k20_lock(priv->apalis_tk1_k20); + if (pdata->id == 0) +@@ -358,7 +390,7 @@ static int apalis_tk1_k20_can_stop(struct net_device *net) + if (pdata->id == 1) + apalis_tk1_k20_irq_mask(priv->apalis_tk1_k20, + APALIS_TK1_K20_CAN1_IRQ); +- /* Disable and clear pending interrupts */ ++ + priv->can.state = CAN_STATE_STOPPED; + apalis_tk1_k20_unlock(priv->apalis_tk1_k20); + mutex_unlock(&priv->apalis_tk1_k20_can_lock); +@@ -462,7 +494,7 @@ static int apalis_tk1_k20_can_resume(struct device *dev) + if (pdata->id == 1) + apalis_tk1_k20_irq_unmask(priv->apalis_tk1_k20, + APALIS_TK1_K20_CAN1_IRQ); +- /* Enable interrupts */ ++ + priv->can.state = CAN_STATE_STOPPED; + apalis_tk1_k20_unlock(priv->apalis_tk1_k20); + mutex_unlock(&priv->apalis_tk1_k20_can_lock); +@@ -519,6 +551,7 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) + u8 clear_intf = 0; + int can_id = 0, data1 = 0; + ++ + apalis_tk1_k20_lock(priv->apalis_tk1_k20); + ret = apalis_tk1_k20_reg_read(priv->apalis_tk1_k20, + APALIS_TK1_K20_CANREG +@@ -532,6 +565,25 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) + } + + intf &= CANCTRL_INTMASK; ++ ++ if (!(intf & CANINTF_TX) && ++ (priv->tx_frame == 1)) { ++ priv->tx_frame = 0; ++ net->stats.tx_packets++; ++ net->stats.tx_bytes += priv->tx_len - 1; ++ can_led_event(net, CAN_LED_EVENT_TX); ++ if (priv->tx_len) { ++ can_get_echo_skb(net, 0); ++ priv->tx_len = 0; ++ } ++ netif_wake_queue(net); ++ if (!(intf & (CANINTF_RX | CANINTF_ERR))) ++ break; ++ } ++ ++ if (intf == 0) ++ break; ++ + /* receive */ + if (intf & CANINTF_RX) + apalis_tk1_k20_can_hw_rx(net, 0); +@@ -625,21 +677,7 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) + break; + } + +- if (intf == 0) +- break; + +- if (intf & CANINTF_TX) { +- net->stats.tx_packets++; +- net->stats.tx_bytes += priv->tx_len - 1; +- can_led_event(net, CAN_LED_EVENT_TX); +- if (priv->tx_len) { +- can_get_echo_skb(net, 0); +- priv->tx_len = 0; +- } +- netif_wake_queue(net); +- if (!(intf & (CANINTF_RX | CANINTF_ERR))) +- break; +- } + } + mutex_unlock(&priv->apalis_tk1_k20_can_lock); + return IRQ_HANDLED; +@@ -662,6 +700,7 @@ static int apalis_tk1_k20_can_open(struct net_device *net) + priv->force_quit = 0; + priv->tx_skb = NULL; + priv->tx_len = 0; ++ priv->tx_frame = 0; + apalis_tk1_k20_lock(priv->apalis_tk1_k20); + if (pdata->id == 0) + ret = apalis_tk1_k20_irq_request(priv->apalis_tk1_k20, +@@ -701,6 +740,11 @@ static int apalis_tk1_k20_can_open(struct net_device *net) + apalis_tk1_k20_can_open_clean(net); + goto open_unlock; + } ++ ret = apalis_tk1_k20_can_enable(net, true); ++ if (ret) { ++ apalis_tk1_k20_can_open_clean(net); ++ goto open_unlock; ++ } + + can_led_event(net, CAN_LED_EVENT_OPEN); + +@@ -765,6 +809,7 @@ static int apalis_tk1_k20_can_probe(struct platform_device *pdev) + platform_set_drvdata(pdev, priv); + + ret = register_candev(net); ++ + if (ret) + goto error_probe; + +diff --git a/include/linux/mfd/apalis-tk1-k20-api.h b/include/linux/mfd/apalis-tk1-k20-api.h +index 199b433c3d96..75c7821ec43f 100644 +--- a/include/linux/mfd/apalis-tk1-k20-api.h ++++ b/include/linux/mfd/apalis-tk1-k20-api.h +@@ -104,7 +104,7 @@ + #define APALIS_TK1_K20_TSC_IRQ 4 + #define APALIS_TK1_K20_GPIO_IRQ 5 + +-#define APALIS_TK1_K20_FW_VER 0x11 ++#define APALIS_TK1_K20_FW_VER 0x13 + #define APALIS_TK1_K20_TESTER_FW_VER 0xFE + + #define FW_MINOR (APALIS_TK1_K20_FW_VER & 0x0F) +-- +2.19.2 + diff --git a/recipes-kernel/linux/linux-toradex-mainline_4.14.bb b/recipes-kernel/linux/linux-toradex-mainline_4.14.bb index 7abc4cf..0cf1cfc 100644 --- a/recipes-kernel/linux/linux-toradex-mainline_4.14.bb +++ b/recipes-kernel/linux/linux-toradex-mainline_4.14.bb @@ -49,6 +49,7 @@ GENERIC_PATCHES = " \ file://0030-apalis-tk1-enable-ddr52-mode-on-emmc.patch \ file://0031-apalis-tk1-force-fixed-ids-for-sdmmc-controllers.patch \ file://0032-apalis-tk1-fix-pcie-reset-for-reliable-gigabit-ether.patch \ + file://0033-apalis-tk1-mfd-k20-supporte-for-fw-version-1.3.patch \ " MACHINE_PATCHES = " \ " -- cgit v1.2.3