From e83f0920de7882d09816c57a1e78e253cc3dcd7c Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Mon, 12 Feb 2018 12:21:11 +0100 Subject: can: mfd: apalis-tk1: v1.1 frequency adjustments and various fixes Signed-off-by: Dominik Sliwa Acked-by: Marcel Ziswiler --- arch/arm/boot/dts/tegra124-apalis-eval.dts | 12 +-- arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts | 10 +-- drivers/mfd/apalis-tk1-k20-ezp.h | 2 +- drivers/mfd/apalis-tk1-k20.c | 96 +++++++++++++++++++--- drivers/net/can/apalis-tk1-k20-can.c | 104 +++++++++++++----------- include/linux/mfd/apalis-tk1-k20.h | 41 ++++++---- 6 files changed, 176 insertions(+), 89 deletions(-) diff --git a/arch/arm/boot/dts/tegra124-apalis-eval.dts b/arch/arm/boot/dts/tegra124-apalis-eval.dts index 0931a3ba2d7a..722104fe655e 100644 --- a/arch/arm/boot/dts/tegra124-apalis-eval.dts +++ b/arch/arm/boot/dts/tegra124-apalis-eval.dts @@ -136,24 +136,24 @@ /* SPI2: MCU SPI */ spi@7000d600 { status = "okay"; - spi-max-frequency = <12000000>; + spi-max-frequency = <102000000>; nvidia,polling-mode; nvidia,boost-reg-access; k20mcu: apalis-tk1-k20@1 { compatible = "toradex,apalis-tk1-k20"; reg = <1>; - spi-max-frequency = <6000000>; + spi-max-frequency = <6120000>; interrupt-parent =<&gpio>; - interrupts = ; + interrupts = , + , /* INT3 CAN0 */ + ; /* INT4 CAN1 */ rst-gpio = <&gpio TEGRA_GPIO(BB, 6) GPIO_ACTIVE_HIGH>; /* GPIO based CS used to enter K20 EzPort mode */ ezport-cs-gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>; /* extra INT lines between K20 and TK1 */ int2-gpio = <&gpio TEGRA_GPIO(J, 2) GPIO_ACTIVE_HIGH>; - int3-gpio = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_HIGH>; - int4-gpio = <&gpio TEGRA_GPIO(J, 0) GPIO_ACTIVE_HIGH>; toradex,apalis-tk1-k20-uses-adc; toradex,apalis-tk1-k20-uses-can; @@ -174,7 +174,7 @@ spidev2: spidev@2 { compatible = "spidev"; reg = <2>; - spi-max-frequency = <2000000>; + spi-max-frequency = <4080000>; }; }; diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts index 941428269903..a5d2bd304738 100644 --- a/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts +++ b/arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts @@ -143,17 +143,17 @@ k20mcu: apalis-tk1-k20@1 { compatible = "toradex,apalis-tk1-k20"; reg = <1>; - spi-max-frequency = <10200000>; + spi-max-frequency = <6120000>; interrupt-parent =<&gpio>; - interrupts = ; + interrupts = , + , /* INT3 CAN0 */ + ; /* INT4 CAN1 */ rst-gpio = <&gpio TEGRA_GPIO(BB, 6) GPIO_ACTIVE_HIGH>; /* GPIO based CS used to enter K20 EzPort mode */ ezport-cs-gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>; /* extra INT lines between K20 and TK1 */ int2-gpio = <&gpio TEGRA_GPIO(J, 2) GPIO_ACTIVE_HIGH>; - int3-gpio = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_HIGH>; - int4-gpio = <&gpio TEGRA_GPIO(J, 0) GPIO_ACTIVE_HIGH>; toradex,apalis-tk1-k20-uses-adc; toradex,apalis-tk1-k20-uses-can; @@ -174,7 +174,7 @@ spidev2: spidev@2 { compatible = "spidev"; reg = <2>; - spi-max-frequency = <3500000>; + spi-max-frequency = <4080000>; }; }; diff --git a/drivers/mfd/apalis-tk1-k20-ezp.h b/drivers/mfd/apalis-tk1-k20-ezp.h index 922d55dcfe16..e89d6adbe471 100644 --- a/drivers/mfd/apalis-tk1-k20-ezp.h +++ b/drivers/mfd/apalis-tk1-k20-ezp.h @@ -37,7 +37,7 @@ #define APALIS_TK1_K20_EZP_STA_WEF BIT(6) #define APALIS_TK1_K20_EZP_STA_FS BIT(7) -#define APALIS_TK1_K20_EZP_MAX_SPEED 3500000 +#define APALIS_TK1_K20_EZP_MAX_SPEED 4080000 #define APALIS_TK1_K20_EZP_MAX_DATA 32 #define APALIS_TK1_K20_EZP_WRITE_SIZE 32 diff --git a/drivers/mfd/apalis-tk1-k20.c b/drivers/mfd/apalis-tk1-k20.c index 1ab5542af0d1..e794bda6fde7 100644 --- a/drivers/mfd/apalis-tk1-k20.c +++ b/drivers/mfd/apalis-tk1-k20.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -67,7 +68,8 @@ static int apalis_tk1_k20_spi_read(void *context, const void *reg, size_t reg_size, void *val, size_t val_size) { unsigned char w[APALIS_TK1_K20_MAX_BULK] = {APALIS_TK1_K20_READ_INST, - *((unsigned char *) reg), val_size, 0x00, 0x00}; + *((unsigned char *) reg), val_size, 0x00, 0x00, 0x00, + 0x00}; unsigned char r[APALIS_TK1_K20_MAX_BULK]; unsigned char *p = val; struct device *dev = context; @@ -75,7 +77,7 @@ static int apalis_tk1_k20_spi_read(void *context, const void *reg, struct spi_transfer t = { .tx_buf = w, .rx_buf = r, - .len = 6, + .len = 8, .cs_change = 0, .delay_usecs = 0, }; @@ -91,11 +93,35 @@ static int apalis_tk1_k20_spi_read(void *context, const void *reg, spi_message_init(&m); spi_message_add_tail(&t, &m); ret = spi_sync(spi, &m); - *p = ((unsigned char *)t.rx_buf)[5]; + + for (int i = 3; i < 7; i++ ) + { + if (((unsigned char *)t.rx_buf)[i] == 0x55) { + *p = ((unsigned char *)t.rx_buf)[i + 1]; + return ret; + } + } + + for (int j = 0; j < APALIS_TK1_MAX_RETRY_CNT; j++) { + udelay(250 * j * j); + t.tx_buf = w; + t.rx_buf = r; + spi_message_init(&m); + spi_message_add_tail(&t, &m); + ret = spi_sync(spi, &m); + for (int i = 3; i < 7; i++ ) + { + if (((unsigned char *)t.rx_buf)[i] == 0x55) { + *p = ((unsigned char *)t.rx_buf)[i + 1]; + return ret; + } + } + } + ret = -EIO; #ifdef CONFIG_V12_K20_HSMODE } else if ((val_size > 1) && (val_size < APALIS_TK1_K20_MAX_BULK)) { - t.len = 3; + t.len = 5; w[0] = APALIS_TK1_K20_BULK_READ_INST; spi_message_init(&m); spi_message_add_tail(&t, &m); @@ -135,8 +161,9 @@ static int apalis_tk1_k20_spi_write(void *context, const void *data, #ifdef CONFIG_V12_K20_HSMODE } else if ((count > 2) && (count < APALIS_TK1_K20_MAX_BULK)) { out_data[0] = APALIS_TK1_K20_BULK_WRITE_INST; - out_data[1] = count - 1; - memcpy(&out_data[2], data, count); + out_data[1] = ((uint8_t *)data)[0]; + out_data[2] = count - 1; + memcpy(&out_data[3], &((uint8_t *)data)[1], count - 1); ret = spi_write(spi, out_data, count + 2); #endif } else { @@ -239,7 +266,14 @@ EXPORT_SYMBOL(apalis_tk1_k20_reg_rmw); int apalis_tk1_k20_irq_mask(struct apalis_tk1_k20_regmap *apalis_tk1_k20, int irq) { - int virq = regmap_irq_get_virq(apalis_tk1_k20->irq_data, irq); + int virq = -1; + if (irq != APALIS_TK1_K20_CAN1_IRQ && irq != APALIS_TK1_K20_CAN0_IRQ) { + virq = regmap_irq_get_virq(apalis_tk1_k20->irq_data, irq); + + } else { + virq = (irq == APALIS_TK1_K20_CAN0_IRQ) ? + apalis_tk1_k20->can0_irq:apalis_tk1_k20->can1_irq; + } disable_irq_nosync(virq); @@ -250,7 +284,14 @@ EXPORT_SYMBOL(apalis_tk1_k20_irq_mask); int apalis_tk1_k20_irq_unmask(struct apalis_tk1_k20_regmap *apalis_tk1_k20, int irq) { - int virq = regmap_irq_get_virq(apalis_tk1_k20->irq_data, irq); + int virq = -1; + if (irq != APALIS_TK1_K20_CAN1_IRQ && irq != APALIS_TK1_K20_CAN0_IRQ) { + virq = regmap_irq_get_virq(apalis_tk1_k20->irq_data, irq); + + } else { + virq = (irq == APALIS_TK1_K20_CAN0_IRQ) ? + apalis_tk1_k20->can0_irq:apalis_tk1_k20->can1_irq; + } enable_irq(virq); @@ -296,17 +337,33 @@ EXPORT_SYMBOL(apalis_tk1_k20_irq_status); int apalis_tk1_k20_irq_request(struct apalis_tk1_k20_regmap *apalis_tk1_k20, int irq, irq_handler_t handler, const char *name, void *dev) { - int virq = regmap_irq_get_virq(apalis_tk1_k20->irq_data, irq); - - return devm_request_threaded_irq(apalis_tk1_k20->dev, virq, NULL, - handler, IRQF_ONESHOT, name, dev); + int virq = -1; + int irq_flags = IRQF_ONESHOT; + if (irq != APALIS_TK1_K20_CAN1_IRQ && irq != APALIS_TK1_K20_CAN0_IRQ) { + virq = regmap_irq_get_virq(apalis_tk1_k20->irq_data, irq); + irq_flags = IRQF_ONESHOT; + } else { + virq = (irq == APALIS_TK1_K20_CAN0_IRQ) ? + apalis_tk1_k20->can0_irq:apalis_tk1_k20->can1_irq; + irq_flags = IRQF_ONESHOT | IRQF_TRIGGER_FALLING | + IRQF_TRIGGER_RISING; + } + return devm_request_threaded_irq(apalis_tk1_k20->dev, virq, + NULL, handler, irq_flags, name, dev); } EXPORT_SYMBOL(apalis_tk1_k20_irq_request); int apalis_tk1_k20_irq_free(struct apalis_tk1_k20_regmap *apalis_tk1_k20, int irq, void *dev) { - int virq = regmap_irq_get_virq(apalis_tk1_k20->irq_data, irq); + int virq = -1; + if (irq != APALIS_TK1_K20_CAN1_IRQ && irq != APALIS_TK1_K20_CAN0_IRQ) { + virq = regmap_irq_get_virq(apalis_tk1_k20->irq_data, irq); + + } else { + virq = (irq == APALIS_TK1_K20_CAN0_IRQ) ? + apalis_tk1_k20->can0_irq:apalis_tk1_k20->can1_irq; + } devm_free_irq(apalis_tk1_k20->dev, virq, dev); @@ -844,6 +901,19 @@ int apalis_tk1_k20_dev_init(struct device *dev) if (apalis_tk1_k20_probe_flags_dt(apalis_tk1_k20) < 0 && pdata) apalis_tk1_k20->flags = pdata->flags; + if (apalis_tk1_k20->flags & APALIS_TK1_K20_USES_CAN) { + apalis_tk1_k20->can0_irq = irq_of_parse_and_map( + apalis_tk1_k20->dev->of_node, 1); + apalis_tk1_k20->can1_irq = irq_of_parse_and_map( + apalis_tk1_k20->dev->of_node, 2); + if (apalis_tk1_k20->can0_irq == 0 || + apalis_tk1_k20->can1_irq == 0) { + apalis_tk1_k20->flags &= ~APALIS_TK1_K20_USES_CAN; + dev_err(apalis_tk1_k20->dev, + "Missing CAN interrupts.\n"); + } + } + if (pdata) { if (apalis_tk1_k20->flags & APALIS_TK1_K20_USES_TSC) apalis_tk1_k20_add_subdevice_pdata(apalis_tk1_k20, diff --git a/drivers/net/can/apalis-tk1-k20-can.c b/drivers/net/can/apalis-tk1-k20-can.c index c32a70181ac1..53f64189a7fb 100644 --- a/drivers/net/can/apalis-tk1-k20-can.c +++ b/drivers/net/can/apalis-tk1-k20-can.c @@ -34,22 +34,20 @@ #define CAN_FRAME_MAX_LEN 8 #define CAN_HEADER_MAX_LEN 5 #define CAN_TRANSFER_BUF_LEN (CAN_HEADER_MAX_LEN + CAN_FRAME_MAX_LEN) -#define CAN_FRAME_MAX_BITS 128 -#define CAN_MAX_CONTINUOUS_READ 8 -#define MB_DLC_OFF 0 -#define MB_EID_OFF 1 +#define MB_DLC_OFF 4 +#define MB_EID_OFF 0 #define MB_RTR_SHIFT 4 #define MB_IDE_SHIFT 5 #define MB_DLC_MASK 0xF #define MB_EID_LEN 4 #define CANCTRL_MODMASK 0x03 -#define CANCTRL_INTMASK 0x38 #define CANCTRL_INTEN BIT(2) #define CANINTF_RX BIT(3) #define CANINTF_TX BIT(4) #define CANINTF_ERR BIT(5) +#define CANCTRL_INTMASK (CANINTF_RX | CANINTF_TX | CANINTF_ERR) #define EFLG_EWARN 0x01 #define EFLG_RXWAR 0x02 @@ -140,42 +138,50 @@ static void apalis_tk1_k20_can_hw_tx(struct net_device *net, + CAN_HEADER_MAX_LEN, tx_buf_idx); } -static void apalis_tk1_k20_can_hw_rx_frame(struct net_device *net, u8 *buf, - int buf_idx) +static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) { struct apalis_tk1_k20_priv *priv = netdev_priv(net); + struct sk_buff *skb; + struct can_frame *frame; + u8 buf[CAN_TRANSFER_BUF_LEN * APALIS_TK1_MAX_CAN_DMA_XREF]; + u32 frame_available = 0; apalis_tk1_k20_lock(priv->apalis_tk1_k20); - + apalis_tk1_k20_reg_read(priv->apalis_tk1_k20, + APALIS_TK1_K20_CAN_IN_BUF_CNT + + APALIS_TK1_K20_CAN_DEV_OFFSET( + priv->pdata->id), &frame_available); + frame_available = min(frame_available, APALIS_TK1_MAX_CAN_DMA_XREF); apalis_tk1_k20_reg_read_bulk(priv->apalis_tk1_k20, APALIS_TK1_K20_CAN_IN_BUF + APALIS_TK1_K20_CAN_DEV_OFFSET( priv->pdata->id), buf, - CAN_TRANSFER_BUF_LEN); + CAN_TRANSFER_BUF_LEN * frame_available); apalis_tk1_k20_unlock(priv->apalis_tk1_k20); -} - -static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx) -{ - struct apalis_tk1_k20_priv *priv = netdev_priv(net); - struct sk_buff *skb; - struct can_frame *frame; - skb = alloc_can_skb(priv->net, &frame); - if (!skb) { - dev_err(&net->dev, "cannot allocate RX skb\n"); - priv->net->stats.rx_dropped++; - return; - } + for (int i = 0; i < frame_available; i++) { + skb = alloc_can_skb(priv->net, &frame); + if (!skb) { + dev_err(&net->dev, "cannot allocate RX skb\n"); + priv->net->stats.rx_dropped++; + return; + } + memcpy(&frame->can_id, &buf[i * CAN_TRANSFER_BUF_LEN] + + MB_EID_OFF, MB_EID_LEN); + /* Data length */ + frame->can_dlc = get_can_dlc(buf[i * CAN_TRANSFER_BUF_LEN + + MB_DLC_OFF]); + memcpy(frame->data, &buf[i * CAN_TRANSFER_BUF_LEN] + + CAN_HEADER_MAX_LEN, frame->can_dlc); - apalis_tk1_k20_can_hw_rx_frame(net, (unsigned char *)frame, buf_idx); + priv->net->stats.rx_packets++; + priv->net->stats.rx_bytes += frame->can_dlc; - priv->net->stats.rx_packets++; - priv->net->stats.rx_bytes += frame->can_dlc; + can_led_event(priv->net, CAN_LED_EVENT_RX); - can_led_event(priv->net, CAN_LED_EVENT_RX); + netif_rx_ni(skb); + } - netif_rx_ni(skb); } @@ -503,10 +509,9 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) { struct apalis_tk1_k20_priv *priv = dev_id; struct net_device *net = priv->net; - int max_continuous_read = CAN_MAX_CONTINUOUS_READ; mutex_lock(&priv->apalis_tk1_k20_can_lock); - while (!priv->force_quit && max_continuous_read) { + while (!priv->force_quit) { enum can_state new_state; int ret; u32 intf, eflag; @@ -525,39 +530,37 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) break; } - max_continuous_read--; - intf &= CANCTRL_INTMASK; /* receive */ if (intf & CANINTF_RX) apalis_tk1_k20_can_hw_rx(net, 0); - /* any error or TX interrupt we need to clear? */ - if (intf & (CANINTF_ERR | CANINTF_TX)) - clear_intf |= intf & (CANINTF_ERR | CANINTF_TX); + /* any error interrupt we need to clear? */ + if (intf & CANINTF_ERR) + clear_intf |= intf & CANINTF_ERR; apalis_tk1_k20_lock(priv->apalis_tk1_k20); if (clear_intf) - ret = apalis_tk1_k20_reg_rmw(priv->apalis_tk1_k20, - APALIS_TK1_K20_CANREG + - APALIS_TK1_K20_CAN_DEV_OFFSET( - priv->pdata->id), - CANCTRL_INTMASK, 0x00); + ret = apalis_tk1_k20_reg_write(priv->apalis_tk1_k20, + APALIS_TK1_K20_CANREG_CLR + + APALIS_TK1_K20_CAN_DEV_OFFSET( + priv->pdata->id),clear_intf); if (ret) { apalis_tk1_k20_unlock(priv->apalis_tk1_k20); dev_err(&net->dev, "Communication error\n"); break; } - ret = apalis_tk1_k20_reg_read(priv->apalis_tk1_k20, - APALIS_TK1_K20_CANERR + - APALIS_TK1_K20_CAN_DEV_OFFSET( - priv->pdata->id), &eflag); - apalis_tk1_k20_unlock(priv->apalis_tk1_k20); - if (ret) { - dev_err(&net->dev, "Communication error\n"); - break; - } + /* Update can state */ if (intf & CANINTF_ERR) { + ret = apalis_tk1_k20_reg_read(priv->apalis_tk1_k20, + APALIS_TK1_K20_CANERR + + APALIS_TK1_K20_CAN_DEV_OFFSET( + priv->pdata->id), &eflag); + apalis_tk1_k20_unlock(priv->apalis_tk1_k20); + if (ret) { + dev_err(&net->dev, "Communication error\n"); + break; + } if (eflag & EFLG_TXBO) { new_state = CAN_STATE_BUS_OFF; can_id |= CAN_ERR_BUSOFF; @@ -581,6 +584,9 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) new_state = CAN_STATE_ERROR_ACTIVE; } } + else { + apalis_tk1_k20_unlock(priv->apalis_tk1_k20); + } /* Update can state statistics */ switch (priv->can.state) { @@ -630,6 +636,8 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id) priv->tx_len = 0; } netif_wake_queue(net); + if (!(intf & (CANINTF_RX | CANINTF_ERR))) + break; } } mutex_unlock(&priv->apalis_tk1_k20_can_lock); diff --git a/include/linux/mfd/apalis-tk1-k20.h b/include/linux/mfd/apalis-tk1-k20.h index ca9025d63cb1..ba2afdc8dbc4 100644 --- a/include/linux/mfd/apalis-tk1-k20.h +++ b/include/linux/mfd/apalis-tk1-k20.h @@ -22,12 +22,12 @@ #define APALIS_TK1_K20_BULK_WRITE_INST 0x3C #define APALIS_TK1_K20_BULK_READ_INST 0xC3 -#define APALIS_TK1_K20_MAX_BULK (32) +#define APALIS_TK1_K20_MAX_BULK (250) /* General registers*/ #define APALIS_TK1_K20_STAREG 0x00 /* general status register RO */ #define APALIS_TK1_K20_REVREG 0x01 /* FW revision register RO*/ -#define APALIS_TK1_K20_IRQREG 0x02 /* IRQ status RW(write of 1 will reset the bit) */ +#define APALIS_TK1_K20_IRQREG 0x02 /* IRQ status RO(reset of read) */ #define APALIS_TK1_K20_CTRREG 0x03 /* general control register RW */ #define APALIS_TK1_K20_MSQREG 0x04 /* IRQ mask register RW */ @@ -35,21 +35,22 @@ /* CAN Registers */ #define APALIS_TK1_K20_CANREG 0x10 /* CAN0 control & status register RW */ -#define APALIS_TK1_K20_CANERR 0x11 /* CAN0 error register RW */ -#define APALIS_TK1_K20_CAN_BAUD_REG 0x12 /* CAN0 baud set register RW */ -#define APALIS_TK1_K20_CAN_BIT_1 0x13 /* CAN0 bit timing register 1 RW */ -#define APALIS_TK1_K20_CAN_BIT_2 0x14 /* CAN0 bit timing register 2 RW */ -#define APALIS_TK1_K20_CAN_IN_BUF_CNT 0x15 /* CAN0 IN received data count RO */ -#define APALIS_TK1_K20_CAN_IN_BUF 0x16 /* CAN0 IN RO */ +#define APALIS_TK1_K20_CANREG_CLR 0x11 /* CAN0 CANREG clear register WO */ +#define APALIS_TK1_K20_CANERR 0x12 /* CAN0 error register RW */ +#define APALIS_TK1_K20_CAN_BAUD_REG 0x13 /* CAN0 baud set register RW */ +#define APALIS_TK1_K20_CAN_BIT_1 0x14 /* CAN0 bit timing register 1 RW */ +#define APALIS_TK1_K20_CAN_BIT_2 0x15 /* CAN0 bit timing register 2 RW */ +#define APALIS_TK1_K20_CAN_IN_BUF_CNT 0x16 /* CAN0 IN received data count RO */ +#define APALIS_TK1_K20_CAN_IN_BUF 0x17 /* CAN0 IN RO */ /* buffer size is 13 bytes */ -#define APALIS_TK1_K20_CAN_IN_BUF_END 0x22 /* CAN0 IN RO */ -#define APALIS_TK1_K20_CAN_OUT_BUF_CNT 0x23 /* CAN0 OUT data Count WO */ -#define APALIS_TK1_K20_CAN_OUT_BUF 0x26 /* CAN0 OUT WO */ +#define APALIS_TK1_K20_CAN_IN_BUF_END 0x23 /* CAN0 IN RO */ +#define APALIS_TK1_K20_CAN_OUT_BUF 0x24 /* CAN0 OUT WO */ /* buffer size is 13 bytes */ #define APALIS_TK1_K20_CAN_OUT_BUF_END (APALIS_TK1_K20_CAN_OUT_BUF + 13 - 1)/* CAN OUT BUF END */ -#define APALIS_TK1_K20_CAN_DEV_OFFSET(x) (x ? 0x30 : 0) +#define APALIS_TK1_K20_CAN_OFFSET 0x30 +#define APALIS_TK1_K20_CAN_DEV_OFFSET(x) (x ? APALIS_TK1_K20_CAN_OFFSET : 0) -/* 0x33-0x3F Reserved */ +/* 0x30-0x3F Reserved */ /* 0x40-0x62 CAN1 registers same layout as CAN0*/ /* 0x63-0x6F Reserved */ @@ -106,7 +107,7 @@ #define APALIS_TK1_K20_TSC_IRQ 4 #define APALIS_TK1_K20_GPIO_IRQ 5 -#define APALIS_TK1_K20_FW_VER 0x0C +#define APALIS_TK1_K20_FW_VER 0x0D #define FW_MINOR (APALIS_TK1_K20_FW_VER & 0x0F) #define FW_MAJOR ((APALIS_TK1_K20_FW_VER & 0xF0) >> 4) @@ -118,9 +119,15 @@ #define APALIS_TK1_K20_IRQ_REG_CNT 1 #define APALIS_TK1_K20_IRQ_PER_REG 8 -#define APALIS_TK1_CAN_CLK_UNIT 6250 +#define APALIS_TK1_CAN_CLK_UNIT 6250u -#define APALIS_TK1_K20_MAX_SPI_SPEED 12000000 +#define APALIS_TK1_CAN_CLK_UNIT 6250u + +#define APALIS_TK1_MAX_CAN_DMA_XREF 19u + +#define APALIS_TK1_MAX_RETRY_CNT 4 + +#define APALIS_TK1_K20_MAX_SPI_SPEED 6120000 struct apalis_tk1_k20_regmap { struct regmap *regmap; @@ -130,6 +137,8 @@ struct apalis_tk1_k20_regmap { struct regmap_irq irqs[APALIS_TK1_K20_IRQ_REG_CNT * APALIS_TK1_K20_IRQ_PER_REG]; struct regmap_irq_chip irq_chip; struct regmap_irq_chip_data *irq_data; + int can0_irq; + int can1_irq; struct mutex lock; int irq; -- cgit v1.2.3