aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/at91_can.c
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2011-04-16 18:08:45 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2011-06-06 08:50:57 -0400
commit6388b39614208d63661607f45157e3326548eb62 (patch)
tree2108330f6931dfaec98cf3fc936bf62ede0db72f /drivers/net/can/at91_can.c
parent07a648e668aa7f7c94d41d8d2e4ad53b609e391d (diff)
can: at91_can: add support for the AT91SAM9X5 SOCs
The AT91SAM9X5 SOCs have a similar CAN core, but they only have 8 compared to 16 mailboxes on the AT91SAM9263 SOC. Another difference is that the bits defining the state of the CAN core are cleared on read, thus the driver has to derive the state by looking at the error counters. Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can/at91_can.c')
-rw-r--r--drivers/net/can/at91_can.c69
1 files changed, 55 insertions, 14 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 2b972812b2d1..121ede663e20 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -127,6 +127,7 @@ enum at91_mb_mode {
127 127
128enum at91_devtype { 128enum at91_devtype {
129 AT91_DEVTYPE_SAM9263, 129 AT91_DEVTYPE_SAM9263,
130 AT91_DEVTYPE_SAM9X5,
130}; 131};
131 132
132struct at91_devtype_data { 133struct at91_devtype_data {
@@ -163,6 +164,12 @@ static const struct at91_devtype_data at91_devtype_data[] __devinitconst = {
163 .rx_last = 11, 164 .rx_last = 11,
164 .tx_shift = 2, 165 .tx_shift = 2,
165 }, 166 },
167 [AT91_DEVTYPE_SAM9X5] = {
168 .rx_first = 0,
169 .rx_split = 4,
170 .rx_last = 5,
171 .tx_shift = 1,
172 },
166}; 173};
167 174
168static struct can_bittiming_const at91_bittiming_const = { 175static struct can_bittiming_const at91_bittiming_const = {
@@ -184,6 +191,7 @@ static inline int at91_is_sam##_model(const struct at91_priv *priv) \
184} 191}
185 192
186AT91_IS(9263); 193AT91_IS(9263);
194AT91_IS(9X5);
187 195
188static inline unsigned int get_mb_rx_first(const struct at91_priv *priv) 196static inline unsigned int get_mb_rx_first(const struct at91_priv *priv)
189{ 197{
@@ -991,6 +999,29 @@ static void at91_irq_err_state(struct net_device *dev,
991 at91_write(priv, AT91_IER, reg_ier); 999 at91_write(priv, AT91_IER, reg_ier);
992} 1000}
993 1001
1002static int at91_get_state_by_bec(const struct net_device *dev,
1003 enum can_state *state)
1004{
1005 struct can_berr_counter bec;
1006 int err;
1007
1008 err = at91_get_berr_counter(dev, &bec);
1009 if (err)
1010 return err;
1011
1012 if (bec.txerr < 96 && bec.rxerr < 96)
1013 *state = CAN_STATE_ERROR_ACTIVE;
1014 else if (bec.txerr < 128 && bec.rxerr < 128)
1015 *state = CAN_STATE_ERROR_WARNING;
1016 else if (bec.txerr < 256 && bec.rxerr < 256)
1017 *state = CAN_STATE_ERROR_PASSIVE;
1018 else
1019 *state = CAN_STATE_BUS_OFF;
1020
1021 return 0;
1022}
1023
1024
994static void at91_irq_err(struct net_device *dev) 1025static void at91_irq_err(struct net_device *dev)
995{ 1026{
996 struct at91_priv *priv = netdev_priv(dev); 1027 struct at91_priv *priv = netdev_priv(dev);
@@ -998,21 +1029,28 @@ static void at91_irq_err(struct net_device *dev)
998 struct can_frame *cf; 1029 struct can_frame *cf;
999 enum can_state new_state; 1030 enum can_state new_state;
1000 u32 reg_sr; 1031 u32 reg_sr;
1032 int err;
1001 1033
1002 reg_sr = at91_read(priv, AT91_SR); 1034 if (at91_is_sam9263(priv)) {
1003 1035 reg_sr = at91_read(priv, AT91_SR);
1004 /* we need to look at the unmasked reg_sr */ 1036
1005 if (unlikely(reg_sr & AT91_IRQ_BOFF)) 1037 /* we need to look at the unmasked reg_sr */
1006 new_state = CAN_STATE_BUS_OFF; 1038 if (unlikely(reg_sr & AT91_IRQ_BOFF))
1007 else if (unlikely(reg_sr & AT91_IRQ_ERRP)) 1039 new_state = CAN_STATE_BUS_OFF;
1008 new_state = CAN_STATE_ERROR_PASSIVE; 1040 else if (unlikely(reg_sr & AT91_IRQ_ERRP))
1009 else if (unlikely(reg_sr & AT91_IRQ_WARN)) 1041 new_state = CAN_STATE_ERROR_PASSIVE;
1010 new_state = CAN_STATE_ERROR_WARNING; 1042 else if (unlikely(reg_sr & AT91_IRQ_WARN))
1011 else if (likely(reg_sr & AT91_IRQ_ERRA)) 1043 new_state = CAN_STATE_ERROR_WARNING;
1012 new_state = CAN_STATE_ERROR_ACTIVE; 1044 else if (likely(reg_sr & AT91_IRQ_ERRA))
1013 else { 1045 new_state = CAN_STATE_ERROR_ACTIVE;
1014 netdev_err(dev, "BUG! hardware in undefined state\n"); 1046 else {
1015 return; 1047 netdev_err(dev, "BUG! hardware in undefined state\n");
1048 return;
1049 }
1050 } else {
1051 err = at91_get_state_by_bec(dev, &new_state);
1052 if (err)
1053 return;
1016 } 1054 }
1017 1055
1018 /* state hasn't changed */ 1056 /* state hasn't changed */
@@ -1330,6 +1368,9 @@ static const struct platform_device_id at91_can_id_table[] = {
1330 .name = "at91_can", 1368 .name = "at91_can",
1331 .driver_data = AT91_DEVTYPE_SAM9263, 1369 .driver_data = AT91_DEVTYPE_SAM9263,
1332 }, { 1370 }, {
1371 .name = "at91sam9x5_can",
1372 .driver_data = AT91_DEVTYPE_SAM9X5,
1373 }, {
1333 /* sentinel */ 1374 /* sentinel */
1334 } 1375 }
1335}; 1376};