diff options
Diffstat (limited to 'drivers/net/can/mcp251x.c')
-rw-r--r-- | drivers/net/can/mcp251x.c | 111 |
1 files changed, 82 insertions, 29 deletions
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index b11a0cb5ed81..330140ee266d 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
@@ -38,14 +38,14 @@ | |||
38 | * static struct mcp251x_platform_data mcp251x_info = { | 38 | * static struct mcp251x_platform_data mcp251x_info = { |
39 | * .oscillator_frequency = 8000000, | 39 | * .oscillator_frequency = 8000000, |
40 | * .board_specific_setup = &mcp251x_setup, | 40 | * .board_specific_setup = &mcp251x_setup, |
41 | * .model = CAN_MCP251X_MCP2510, | ||
42 | * .power_enable = mcp251x_power_enable, | 41 | * .power_enable = mcp251x_power_enable, |
43 | * .transceiver_enable = NULL, | 42 | * .transceiver_enable = NULL, |
44 | * }; | 43 | * }; |
45 | * | 44 | * |
46 | * static struct spi_board_info spi_board_info[] = { | 45 | * static struct spi_board_info spi_board_info[] = { |
47 | * { | 46 | * { |
48 | * .modalias = "mcp251x", | 47 | * .modalias = "mcp2510", |
48 | * // or "mcp2515" depending on your controller | ||
49 | * .platform_data = &mcp251x_info, | 49 | * .platform_data = &mcp251x_info, |
50 | * .irq = IRQ_EINT13, | 50 | * .irq = IRQ_EINT13, |
51 | * .max_speed_hz = 2*1000*1000, | 51 | * .max_speed_hz = 2*1000*1000, |
@@ -125,6 +125,9 @@ | |||
125 | # define CANINTF_TX0IF 0x04 | 125 | # define CANINTF_TX0IF 0x04 |
126 | # define CANINTF_RX1IF 0x02 | 126 | # define CANINTF_RX1IF 0x02 |
127 | # define CANINTF_RX0IF 0x01 | 127 | # define CANINTF_RX0IF 0x01 |
128 | # define CANINTF_RX (CANINTF_RX0IF | CANINTF_RX1IF) | ||
129 | # define CANINTF_TX (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF) | ||
130 | # define CANINTF_ERR (CANINTF_ERRIF) | ||
128 | #define EFLG 0x2d | 131 | #define EFLG 0x2d |
129 | # define EFLG_EWARN 0x01 | 132 | # define EFLG_EWARN 0x01 |
130 | # define EFLG_RXWAR 0x02 | 133 | # define EFLG_RXWAR 0x02 |
@@ -166,6 +169,7 @@ | |||
166 | # define RXBSIDH_SHIFT 3 | 169 | # define RXBSIDH_SHIFT 3 |
167 | #define RXBSIDL(n) (((n) * 0x10) + 0x60 + RXBSIDL_OFF) | 170 | #define RXBSIDL(n) (((n) * 0x10) + 0x60 + RXBSIDL_OFF) |
168 | # define RXBSIDL_IDE 0x08 | 171 | # define RXBSIDL_IDE 0x08 |
172 | # define RXBSIDL_SRR 0x10 | ||
169 | # define RXBSIDL_EID 3 | 173 | # define RXBSIDL_EID 3 |
170 | # define RXBSIDL_SHIFT 5 | 174 | # define RXBSIDL_SHIFT 5 |
171 | #define RXBEID8(n) (((n) * 0x10) + 0x60 + RXBEID8_OFF) | 175 | #define RXBEID8(n) (((n) * 0x10) + 0x60 + RXBEID8_OFF) |
@@ -222,10 +226,16 @@ static struct can_bittiming_const mcp251x_bittiming_const = { | |||
222 | .brp_inc = 1, | 226 | .brp_inc = 1, |
223 | }; | 227 | }; |
224 | 228 | ||
229 | enum mcp251x_model { | ||
230 | CAN_MCP251X_MCP2510 = 0x2510, | ||
231 | CAN_MCP251X_MCP2515 = 0x2515, | ||
232 | }; | ||
233 | |||
225 | struct mcp251x_priv { | 234 | struct mcp251x_priv { |
226 | struct can_priv can; | 235 | struct can_priv can; |
227 | struct net_device *net; | 236 | struct net_device *net; |
228 | struct spi_device *spi; | 237 | struct spi_device *spi; |
238 | enum mcp251x_model model; | ||
229 | 239 | ||
230 | struct mutex mcp_lock; /* SPI device lock */ | 240 | struct mutex mcp_lock; /* SPI device lock */ |
231 | 241 | ||
@@ -250,6 +260,16 @@ struct mcp251x_priv { | |||
250 | int restart_tx; | 260 | int restart_tx; |
251 | }; | 261 | }; |
252 | 262 | ||
263 | #define MCP251X_IS(_model) \ | ||
264 | static inline int mcp251x_is_##_model(struct spi_device *spi) \ | ||
265 | { \ | ||
266 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); \ | ||
267 | return priv->model == CAN_MCP251X_MCP##_model; \ | ||
268 | } | ||
269 | |||
270 | MCP251X_IS(2510); | ||
271 | MCP251X_IS(2515); | ||
272 | |||
253 | static void mcp251x_clean(struct net_device *net) | 273 | static void mcp251x_clean(struct net_device *net) |
254 | { | 274 | { |
255 | struct mcp251x_priv *priv = netdev_priv(net); | 275 | struct mcp251x_priv *priv = netdev_priv(net); |
@@ -319,6 +339,20 @@ static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg) | |||
319 | return val; | 339 | return val; |
320 | } | 340 | } |
321 | 341 | ||
342 | static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg, | ||
343 | uint8_t *v1, uint8_t *v2) | ||
344 | { | ||
345 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); | ||
346 | |||
347 | priv->spi_tx_buf[0] = INSTRUCTION_READ; | ||
348 | priv->spi_tx_buf[1] = reg; | ||
349 | |||
350 | mcp251x_spi_trans(spi, 4); | ||
351 | |||
352 | *v1 = priv->spi_rx_buf[2]; | ||
353 | *v2 = priv->spi_rx_buf[3]; | ||
354 | } | ||
355 | |||
322 | static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val) | 356 | static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val) |
323 | { | 357 | { |
324 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); | 358 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); |
@@ -346,10 +380,9 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg, | |||
346 | static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, | 380 | static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, |
347 | int len, int tx_buf_idx) | 381 | int len, int tx_buf_idx) |
348 | { | 382 | { |
349 | struct mcp251x_platform_data *pdata = spi->dev.platform_data; | ||
350 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); | 383 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); |
351 | 384 | ||
352 | if (pdata->model == CAN_MCP251X_MCP2510) { | 385 | if (mcp251x_is_2510(spi)) { |
353 | int i; | 386 | int i; |
354 | 387 | ||
355 | for (i = 1; i < TXBDAT_OFF + len; i++) | 388 | for (i = 1; i < TXBDAT_OFF + len; i++) |
@@ -392,9 +425,8 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, | |||
392 | int buf_idx) | 425 | int buf_idx) |
393 | { | 426 | { |
394 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); | 427 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); |
395 | struct mcp251x_platform_data *pdata = spi->dev.platform_data; | ||
396 | 428 | ||
397 | if (pdata->model == CAN_MCP251X_MCP2510) { | 429 | if (mcp251x_is_2510(spi)) { |
398 | int i, len; | 430 | int i, len; |
399 | 431 | ||
400 | for (i = 1; i < RXBDAT_OFF; i++) | 432 | for (i = 1; i < RXBDAT_OFF; i++) |
@@ -444,6 +476,8 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) | |||
444 | frame->can_id = | 476 | frame->can_id = |
445 | (buf[RXBSIDH_OFF] << RXBSIDH_SHIFT) | | 477 | (buf[RXBSIDH_OFF] << RXBSIDH_SHIFT) | |
446 | (buf[RXBSIDL_OFF] >> RXBSIDL_SHIFT); | 478 | (buf[RXBSIDL_OFF] >> RXBSIDL_SHIFT); |
479 | if (buf[RXBSIDL_OFF] & RXBSIDL_SRR) | ||
480 | frame->can_id |= CAN_RTR_FLAG; | ||
447 | } | 481 | } |
448 | /* Data length */ | 482 | /* Data length */ |
449 | frame->can_dlc = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK); | 483 | frame->can_dlc = get_can_dlc(buf[RXBDLC_OFF] & RXBDLC_LEN_MASK); |
@@ -451,7 +485,7 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) | |||
451 | 485 | ||
452 | priv->net->stats.rx_packets++; | 486 | priv->net->stats.rx_packets++; |
453 | priv->net->stats.rx_bytes += frame->can_dlc; | 487 | priv->net->stats.rx_bytes += frame->can_dlc; |
454 | netif_rx(skb); | 488 | netif_rx_ni(skb); |
455 | } | 489 | } |
456 | 490 | ||
457 | static void mcp251x_hw_sleep(struct spi_device *spi) | 491 | static void mcp251x_hw_sleep(struct spi_device *spi) |
@@ -674,9 +708,9 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1) | |||
674 | 708 | ||
675 | skb = alloc_can_err_skb(net, &frame); | 709 | skb = alloc_can_err_skb(net, &frame); |
676 | if (skb) { | 710 | if (skb) { |
677 | frame->can_id = can_id; | 711 | frame->can_id |= can_id; |
678 | frame->data[1] = data1; | 712 | frame->data[1] = data1; |
679 | netif_rx(skb); | 713 | netif_rx_ni(skb); |
680 | } else { | 714 | } else { |
681 | dev_err(&net->dev, | 715 | dev_err(&net->dev, |
682 | "cannot allocate error skb\n"); | 716 | "cannot allocate error skb\n"); |
@@ -754,24 +788,42 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) | |||
754 | mutex_lock(&priv->mcp_lock); | 788 | mutex_lock(&priv->mcp_lock); |
755 | while (!priv->force_quit) { | 789 | while (!priv->force_quit) { |
756 | enum can_state new_state; | 790 | enum can_state new_state; |
757 | u8 intf = mcp251x_read_reg(spi, CANINTF); | 791 | u8 intf, eflag; |
758 | u8 eflag; | 792 | u8 clear_intf = 0; |
759 | int can_id = 0, data1 = 0; | 793 | int can_id = 0, data1 = 0; |
760 | 794 | ||
795 | mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); | ||
796 | |||
797 | /* mask out flags we don't care about */ | ||
798 | intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR; | ||
799 | |||
800 | /* receive buffer 0 */ | ||
761 | if (intf & CANINTF_RX0IF) { | 801 | if (intf & CANINTF_RX0IF) { |
762 | mcp251x_hw_rx(spi, 0); | 802 | mcp251x_hw_rx(spi, 0); |
763 | /* Free one buffer ASAP */ | 803 | /* |
764 | mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF, | 804 | * Free one buffer ASAP |
765 | 0x00); | 805 | * (The MCP2515 does this automatically.) |
806 | */ | ||
807 | if (mcp251x_is_2510(spi)) | ||
808 | mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00); | ||
766 | } | 809 | } |
767 | 810 | ||
768 | if (intf & CANINTF_RX1IF) | 811 | /* receive buffer 1 */ |
812 | if (intf & CANINTF_RX1IF) { | ||
769 | mcp251x_hw_rx(spi, 1); | 813 | mcp251x_hw_rx(spi, 1); |
814 | /* the MCP2515 does this automatically */ | ||
815 | if (mcp251x_is_2510(spi)) | ||
816 | clear_intf |= CANINTF_RX1IF; | ||
817 | } | ||
770 | 818 | ||
771 | mcp251x_write_bits(spi, CANINTF, intf, 0x00); | 819 | /* any error or tx interrupt we need to clear? */ |
820 | if (intf & (CANINTF_ERR | CANINTF_TX)) | ||
821 | clear_intf |= intf & (CANINTF_ERR | CANINTF_TX); | ||
822 | if (clear_intf) | ||
823 | mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00); | ||
772 | 824 | ||
773 | eflag = mcp251x_read_reg(spi, EFLG); | 825 | if (eflag) |
774 | mcp251x_write_reg(spi, EFLG, 0x00); | 826 | mcp251x_write_bits(spi, EFLG, eflag, 0x00); |
775 | 827 | ||
776 | /* Update can state */ | 828 | /* Update can state */ |
777 | if (eflag & EFLG_TXBO) { | 829 | if (eflag & EFLG_TXBO) { |
@@ -816,10 +868,14 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) | |||
816 | if (intf & CANINTF_ERRIF) { | 868 | if (intf & CANINTF_ERRIF) { |
817 | /* Handle overflow counters */ | 869 | /* Handle overflow counters */ |
818 | if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) { | 870 | if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) { |
819 | if (eflag & EFLG_RX0OVR) | 871 | if (eflag & EFLG_RX0OVR) { |
820 | net->stats.rx_over_errors++; | 872 | net->stats.rx_over_errors++; |
821 | if (eflag & EFLG_RX1OVR) | 873 | net->stats.rx_errors++; |
874 | } | ||
875 | if (eflag & EFLG_RX1OVR) { | ||
822 | net->stats.rx_over_errors++; | 876 | net->stats.rx_over_errors++; |
877 | net->stats.rx_errors++; | ||
878 | } | ||
823 | can_id |= CAN_ERR_CRTL; | 879 | can_id |= CAN_ERR_CRTL; |
824 | data1 |= CAN_ERR_CRTL_RX_OVERFLOW; | 880 | data1 |= CAN_ERR_CRTL_RX_OVERFLOW; |
825 | } | 881 | } |
@@ -838,7 +894,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) | |||
838 | if (intf == 0) | 894 | if (intf == 0) |
839 | break; | 895 | break; |
840 | 896 | ||
841 | if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) { | 897 | if (intf & CANINTF_TX) { |
842 | net->stats.tx_packets++; | 898 | net->stats.tx_packets++; |
843 | net->stats.tx_bytes += priv->tx_len - 1; | 899 | net->stats.tx_bytes += priv->tx_len - 1; |
844 | if (priv->tx_len) { | 900 | if (priv->tx_len) { |
@@ -875,7 +931,8 @@ static int mcp251x_open(struct net_device *net) | |||
875 | priv->tx_len = 0; | 931 | priv->tx_len = 0; |
876 | 932 | ||
877 | ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist, | 933 | ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist, |
878 | IRQF_TRIGGER_FALLING, DEVICE_NAME, priv); | 934 | pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING, |
935 | DEVICE_NAME, priv); | ||
879 | if (ret) { | 936 | if (ret) { |
880 | dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq); | 937 | dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq); |
881 | if (pdata->transceiver_enable) | 938 | if (pdata->transceiver_enable) |
@@ -884,7 +941,7 @@ static int mcp251x_open(struct net_device *net) | |||
884 | goto open_unlock; | 941 | goto open_unlock; |
885 | } | 942 | } |
886 | 943 | ||
887 | priv->wq = create_freezeable_workqueue("mcp251x_wq"); | 944 | priv->wq = create_freezable_workqueue("mcp251x_wq"); |
888 | INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); | 945 | INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler); |
889 | INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); | 946 | INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler); |
890 | 947 | ||
@@ -921,16 +978,12 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) | |||
921 | struct net_device *net; | 978 | struct net_device *net; |
922 | struct mcp251x_priv *priv; | 979 | struct mcp251x_priv *priv; |
923 | struct mcp251x_platform_data *pdata = spi->dev.platform_data; | 980 | struct mcp251x_platform_data *pdata = spi->dev.platform_data; |
924 | int model = spi_get_device_id(spi)->driver_data; | ||
925 | int ret = -ENODEV; | 981 | int ret = -ENODEV; |
926 | 982 | ||
927 | if (!pdata) | 983 | if (!pdata) |
928 | /* Platform data is required for osc freq */ | 984 | /* Platform data is required for osc freq */ |
929 | goto error_out; | 985 | goto error_out; |
930 | 986 | ||
931 | if (model) | ||
932 | pdata->model = model; | ||
933 | |||
934 | /* Allocate can/net device */ | 987 | /* Allocate can/net device */ |
935 | net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); | 988 | net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); |
936 | if (!net) { | 989 | if (!net) { |
@@ -947,6 +1000,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) | |||
947 | priv->can.clock.freq = pdata->oscillator_frequency / 2; | 1000 | priv->can.clock.freq = pdata->oscillator_frequency / 2; |
948 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | | 1001 | priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | |
949 | CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; | 1002 | CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; |
1003 | priv->model = spi_get_device_id(spi)->driver_data; | ||
950 | priv->net = net; | 1004 | priv->net = net; |
951 | dev_set_drvdata(&spi->dev, priv); | 1005 | dev_set_drvdata(&spi->dev, priv); |
952 | 1006 | ||
@@ -1120,8 +1174,7 @@ static int mcp251x_can_resume(struct spi_device *spi) | |||
1120 | #define mcp251x_can_resume NULL | 1174 | #define mcp251x_can_resume NULL |
1121 | #endif | 1175 | #endif |
1122 | 1176 | ||
1123 | static struct spi_device_id mcp251x_id_table[] = { | 1177 | static const struct spi_device_id mcp251x_id_table[] = { |
1124 | { "mcp251x", 0 /* Use pdata.model */ }, | ||
1125 | { "mcp2510", CAN_MCP251X_MCP2510 }, | 1178 | { "mcp2510", CAN_MCP251X_MCP2510 }, |
1126 | { "mcp2515", CAN_MCP251X_MCP2515 }, | 1179 | { "mcp2515", CAN_MCP251X_MCP2515 }, |
1127 | { }, | 1180 | { }, |