summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/tegra124-apalis-eval.dts12
-rw-r--r--arch/arm/boot/dts/tegra124-apalis-v1.2-eval.dts10
-rw-r--r--drivers/mfd/apalis-tk1-k20-ezp.h2
-rw-r--r--drivers/mfd/apalis-tk1-k20.c96
-rw-r--r--drivers/net/can/apalis-tk1-k20-can.c104
-rw-r--r--include/linux/mfd/apalis-tk1-k20.h41
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 = <TEGRA_GPIO(K, 2) IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <TEGRA_GPIO(K, 2) IRQ_TYPE_EDGE_FALLING>,
+ <TEGRA_GPIO(I, 5) IRQ_TYPE_EDGE_FALLING>, /* INT3 CAN0 */
+ <TEGRA_GPIO(J, 0) IRQ_TYPE_EDGE_FALLING>; /* 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 = <TEGRA_GPIO(K, 2) IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <TEGRA_GPIO(K, 2) IRQ_TYPE_EDGE_FALLING>,
+ <TEGRA_GPIO(I, 5) IRQ_TYPE_EDGE_FALLING>, /* INT3 CAN0 */
+ <TEGRA_GPIO(J, 0) IRQ_TYPE_EDGE_FALLING>; /* 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 <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
#include <linux/err.h>
#include <linux/firmware.h>
#include <linux/spi/spi.h>
@@ -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;