• Home
  • Raw
  • Download

Lines Matching +full:can +full:- +full:transceiver

1 /* CAN bus driver for Holt HI3110 CAN Controller with SPI Interface
5 * Based on Microchip 251x CAN Controller (mcp251x) Linux kernel driver
10 * Based on CAN bus driver for the CCAN controller written by
11 * - Sascha Hauer, Marc Kleine-Budde, Pengutronix
12 * - Simon Kallweit, intefo AG
15 * This program is free software; you can redistribute it and/or modify
20 #include <linux/can/core.h>
21 #include <linux/can/dev.h>
22 #include <linux/can/led.h>
27 #include <linux/dma-mapping.h>
153 struct can_priv can; member
180 struct regulator *transceiver; member
188 if (priv->tx_skb || priv->tx_len) in hi3110_clean()
189 net->stats.tx_errors++; in hi3110_clean()
190 if (priv->tx_skb) in hi3110_clean()
191 dev_kfree_skb(priv->tx_skb); in hi3110_clean()
192 if (priv->tx_len) in hi3110_clean()
193 can_free_echo_skb(priv->net, 0); in hi3110_clean()
194 priv->tx_skb = NULL; in hi3110_clean()
195 priv->tx_len = 0; in hi3110_clean()
214 .tx_buf = priv->spi_tx_buf, in hi3110_spi_trans()
215 .rx_buf = priv->spi_rx_buf, in hi3110_spi_trans()
225 t.tx_dma = priv->spi_tx_dma; in hi3110_spi_trans()
226 t.rx_dma = priv->spi_rx_dma; in hi3110_spi_trans()
235 dev_err(&spi->dev, "spi transfer failed: ret = %d\n", ret); in hi3110_spi_trans()
243 priv->spi_tx_buf[0] = command; in hi3110_cmd()
244 dev_dbg(&spi->dev, "hi3110_cmd: %02X\n", command); in hi3110_cmd()
254 priv->spi_tx_buf[0] = command; in hi3110_read()
256 val = priv->spi_rx_buf[1]; in hi3110_read()
265 priv->spi_tx_buf[0] = reg; in hi3110_write()
266 priv->spi_tx_buf[1] = val; in hi3110_write()
274 priv->spi_tx_buf[0] = HI3110_WRITE_FIFO; in hi3110_hw_tx_frame()
275 memcpy(priv->spi_tx_buf + 1, buf, len); in hi3110_hw_tx_frame()
285 if (frame->can_id & CAN_EFF_FLAG) { in hi3110_hw_tx()
287 buf[HI3110_FIFO_ID_OFF] = (frame->can_id & CAN_EFF_MASK) >> 21; in hi3110_hw_tx()
289 (((frame->can_id & CAN_EFF_MASK) >> 13) & 0xe0) | in hi3110_hw_tx()
291 (((frame->can_id & CAN_EFF_MASK) >> 15) & 0x07); in hi3110_hw_tx()
293 (frame->can_id & CAN_EFF_MASK) >> 7; in hi3110_hw_tx()
295 ((frame->can_id & CAN_EFF_MASK) << 1) | in hi3110_hw_tx()
296 ((frame->can_id & CAN_RTR_FLAG) ? 1 : 0); in hi3110_hw_tx()
298 buf[HI3110_FIFO_EXT_DLC_OFF] = frame->can_dlc; in hi3110_hw_tx()
301 frame->data, frame->can_dlc); in hi3110_hw_tx()
303 hi3110_hw_tx_frame(spi, buf, HI3110_TX_EXT_BUF_LEN - in hi3110_hw_tx()
304 (HI3110_CAN_MAX_DATA_LEN - frame->can_dlc)); in hi3110_hw_tx()
307 buf[HI3110_FIFO_ID_OFF] = (frame->can_id & CAN_SFF_MASK) >> 3; in hi3110_hw_tx()
309 ((frame->can_id & CAN_SFF_MASK) << 5) | in hi3110_hw_tx()
310 ((frame->can_id & CAN_RTR_FLAG) ? (1 << 4) : 0); in hi3110_hw_tx()
312 buf[HI3110_FIFO_STD_DLC_OFF] = frame->can_dlc; in hi3110_hw_tx()
315 frame->data, frame->can_dlc); in hi3110_hw_tx()
317 hi3110_hw_tx_frame(spi, buf, HI3110_TX_STD_BUF_LEN - in hi3110_hw_tx()
318 (HI3110_CAN_MAX_DATA_LEN - frame->can_dlc)); in hi3110_hw_tx()
326 priv->spi_tx_buf[0] = HI3110_READ_FIFO_WOTIME; in hi3110_hw_rx_frame()
328 memcpy(buf, priv->spi_rx_buf + 1, HI3110_RX_BUF_LEN - 1); in hi3110_hw_rx_frame()
336 u8 buf[HI3110_RX_BUF_LEN - 1]; in hi3110_hw_rx()
338 skb = alloc_can_skb(priv->net, &frame); in hi3110_hw_rx()
340 priv->net->stats.rx_dropped++; in hi3110_hw_rx()
346 /* IDE is recessive (1), indicating extended 29-bit frame */ in hi3110_hw_rx()
347 frame->can_id = CAN_EFF_FLAG; in hi3110_hw_rx()
348 frame->can_id |= in hi3110_hw_rx()
355 /* IDE is dominant (0), frame indicating standard 11-bit */ in hi3110_hw_rx()
356 frame->can_id = in hi3110_hw_rx()
362 frame->can_dlc = get_can_dlc(buf[HI3110_FIFO_WOTIME_DLC_OFF] & 0x0F); in hi3110_hw_rx()
365 frame->can_id |= CAN_RTR_FLAG; in hi3110_hw_rx()
367 memcpy(frame->data, buf + HI3110_FIFO_WOTIME_DAT_OFF, in hi3110_hw_rx()
368 frame->can_dlc); in hi3110_hw_rx()
370 priv->net->stats.rx_packets++; in hi3110_hw_rx()
371 priv->net->stats.rx_bytes += frame->can_dlc; in hi3110_hw_rx()
373 can_led_event(priv->net, CAN_LED_EVENT_RX); in hi3110_hw_rx()
387 struct spi_device *spi = priv->spi; in hi3110_hard_start_xmit()
389 if (priv->tx_skb || priv->tx_len) { in hi3110_hard_start_xmit()
390 dev_err(&spi->dev, "hard_xmit called while tx busy\n"); in hi3110_hard_start_xmit()
398 priv->tx_skb = skb; in hi3110_hard_start_xmit()
399 queue_work(priv->wq, &priv->tx_work); in hi3110_hard_start_xmit()
412 priv->can.state = CAN_STATE_ERROR_ACTIVE; in hi3110_do_set_mode()
413 priv->restart_tx = 1; in hi3110_do_set_mode()
414 if (priv->can.restart_ms == 0) in hi3110_do_set_mode()
415 priv->after_suspend = HI3110_AFTER_SUSPEND_RESTART; in hi3110_do_set_mode()
416 queue_work(priv->wq, &priv->restart_work); in hi3110_do_set_mode()
419 return -EOPNOTSUPP; in hi3110_do_set_mode()
429 struct spi_device *spi = priv->spi; in hi3110_get_berr_counter()
431 mutex_lock(&priv->hi3110_lock); in hi3110_get_berr_counter()
432 bec->txerr = hi3110_read(spi, HI3110_READ_TEC); in hi3110_get_berr_counter()
433 bec->rxerr = hi3110_read(spi, HI3110_READ_REC); in hi3110_get_berr_counter()
434 mutex_unlock(&priv->hi3110_lock); in hi3110_get_berr_counter()
450 if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) in hi3110_set_normal_mode()
452 else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) in hi3110_set_normal_mode()
463 return -EBUSY; in hi3110_set_normal_mode()
465 priv->can.state = CAN_STATE_ERROR_ACTIVE; in hi3110_set_normal_mode()
472 struct can_bittiming *bt = &priv->can.bittiming; in hi3110_do_set_bittiming()
473 struct spi_device *spi = priv->spi; in hi3110_do_set_bittiming()
476 ((bt->sjw - 1) << HI3110_BTR0_SJW_SHIFT) | in hi3110_do_set_bittiming()
477 ((bt->brp - 1) << HI3110_BTR0_BRP_SHIFT)); in hi3110_do_set_bittiming()
480 (priv->can.ctrlmode & in hi3110_do_set_bittiming()
483 ((bt->phase_seg1 + bt->prop_seg - 1) in hi3110_do_set_bittiming()
485 ((bt->phase_seg2 - 1) << HI3110_BTR1_TSEG2_SHIFT)); in hi3110_do_set_bittiming()
487 dev_dbg(&spi->dev, "BT: 0x%02x 0x%02x\n", in hi3110_do_set_bittiming()
517 return -ENODEV; in hi3110_hw_reset()
538 dev_dbg(&spi->dev, "statf: %02X\n", statf); in hi3110_hw_probe()
541 return -ENODEV; in hi3110_hw_probe()
560 struct spi_device *spi = priv->spi; in hi3110_stop()
564 priv->force_quit = 1; in hi3110_stop()
565 free_irq(spi->irq, priv); in hi3110_stop()
566 destroy_workqueue(priv->wq); in hi3110_stop()
567 priv->wq = NULL; in hi3110_stop()
569 mutex_lock(&priv->hi3110_lock); in hi3110_stop()
580 hi3110_power_enable(priv->transceiver, 0); in hi3110_stop()
582 priv->can.state = CAN_STATE_STOPPED; in hi3110_stop()
584 mutex_unlock(&priv->hi3110_lock); in hi3110_stop()
595 struct spi_device *spi = priv->spi; in hi3110_tx_work_handler()
596 struct net_device *net = priv->net; in hi3110_tx_work_handler()
599 mutex_lock(&priv->hi3110_lock); in hi3110_tx_work_handler()
600 if (priv->tx_skb) { in hi3110_tx_work_handler()
601 if (priv->can.state == CAN_STATE_BUS_OFF) { in hi3110_tx_work_handler()
604 frame = (struct can_frame *)priv->tx_skb->data; in hi3110_tx_work_handler()
606 priv->tx_len = 1 + frame->can_dlc; in hi3110_tx_work_handler()
607 can_put_echo_skb(priv->tx_skb, net, 0); in hi3110_tx_work_handler()
608 priv->tx_skb = NULL; in hi3110_tx_work_handler()
611 mutex_unlock(&priv->hi3110_lock); in hi3110_tx_work_handler()
618 struct spi_device *spi = priv->spi; in hi3110_restart_work_handler()
619 struct net_device *net = priv->net; in hi3110_restart_work_handler()
621 mutex_lock(&priv->hi3110_lock); in hi3110_restart_work_handler()
622 if (priv->after_suspend) { in hi3110_restart_work_handler()
625 if (priv->after_suspend & HI3110_AFTER_SUSPEND_RESTART) { in hi3110_restart_work_handler()
627 } else if (priv->after_suspend & HI3110_AFTER_SUSPEND_UP) { in hi3110_restart_work_handler()
635 priv->after_suspend = 0; in hi3110_restart_work_handler()
636 priv->force_quit = 0; in hi3110_restart_work_handler()
639 if (priv->restart_tx) { in hi3110_restart_work_handler()
640 priv->restart_tx = 0; in hi3110_restart_work_handler()
647 mutex_unlock(&priv->hi3110_lock); in hi3110_restart_work_handler()
653 struct spi_device *spi = priv->spi; in hi3110_can_ist()
654 struct net_device *net = priv->net; in hi3110_can_ist()
656 mutex_lock(&priv->hi3110_lock); in hi3110_can_ist()
658 while (!priv->force_quit) { in hi3110_can_ist()
669 /* Update can state */ in hi3110_can_ist()
679 if (new_state != priv->can.state) { in hi3110_can_ist()
691 cf->data[6] = txerr; in hi3110_can_ist()
692 cf->data[7] = rxerr; in hi3110_can_ist()
700 if (priv->can.restart_ms == 0) { in hi3110_can_ist()
701 priv->force_quit = 1; in hi3110_can_ist()
710 (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { in hi3110_can_ist()
720 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; in hi3110_can_ist()
721 priv->can.can_stats.bus_error++; in hi3110_can_ist()
722 priv->net->stats.rx_errors++; in hi3110_can_ist()
724 cf->data[2] |= CAN_ERR_PROT_BIT; in hi3110_can_ist()
726 cf->data[2] |= CAN_ERR_PROT_FORM; in hi3110_can_ist()
728 cf->data[2] |= CAN_ERR_PROT_STUFF; in hi3110_can_ist()
730 cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; in hi3110_can_ist()
732 cf->data[3] |= CAN_ERR_PROT_LOC_ACK; in hi3110_can_ist()
734 cf->data[6] = hi3110_read(spi, HI3110_READ_TEC); in hi3110_can_ist()
735 cf->data[7] = hi3110_read(spi, HI3110_READ_REC); in hi3110_can_ist()
736 netdev_dbg(priv->net, "Bus Error\n"); in hi3110_can_ist()
741 if (priv->tx_len && statf & HI3110_STAT_TXMTY) { in hi3110_can_ist()
742 net->stats.tx_packets++; in hi3110_can_ist()
743 net->stats.tx_bytes += priv->tx_len - 1; in hi3110_can_ist()
745 if (priv->tx_len) { in hi3110_can_ist()
747 priv->tx_len = 0; in hi3110_can_ist()
755 mutex_unlock(&priv->hi3110_lock); in hi3110_can_ist()
762 struct spi_device *spi = priv->spi; in hi3110_open()
770 mutex_lock(&priv->hi3110_lock); in hi3110_open()
771 hi3110_power_enable(priv->transceiver, 1); in hi3110_open()
773 priv->force_quit = 0; in hi3110_open()
774 priv->tx_skb = NULL; in hi3110_open()
775 priv->tx_len = 0; in hi3110_open()
777 ret = request_threaded_irq(spi->irq, NULL, hi3110_can_ist, in hi3110_open()
780 dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq); in hi3110_open()
784 priv->wq = alloc_workqueue("hi3110_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM, in hi3110_open()
786 if (!priv->wq) { in hi3110_open()
787 ret = -ENOMEM; in hi3110_open()
790 INIT_WORK(&priv->tx_work, hi3110_tx_work_handler); in hi3110_open()
791 INIT_WORK(&priv->restart_work, hi3110_restart_work_handler); in hi3110_open()
807 mutex_unlock(&priv->hi3110_lock); in hi3110_open()
812 destroy_workqueue(priv->wq); in hi3110_open()
814 free_irq(spi->irq, priv); in hi3110_open()
817 hi3110_power_enable(priv->transceiver, 0); in hi3110_open()
819 mutex_unlock(&priv->hi3110_lock); in hi3110_open()
850 &spi->dev); in hi3110_can_probe()
856 clk = devm_clk_get(&spi->dev, NULL); in hi3110_can_probe()
858 dev_err(&spi->dev, "no CAN clock source defined\n"); in hi3110_can_probe()
865 return -ERANGE; in hi3110_can_probe()
867 /* Allocate can/net device */ in hi3110_can_probe()
870 return -ENOMEM; in hi3110_can_probe()
878 net->netdev_ops = &hi3110_netdev_ops; in hi3110_can_probe()
879 net->flags |= IFF_ECHO; in hi3110_can_probe()
882 priv->can.bittiming_const = &hi3110_bittiming_const; in hi3110_can_probe()
883 priv->can.do_set_mode = hi3110_do_set_mode; in hi3110_can_probe()
884 priv->can.do_get_berr_counter = hi3110_get_berr_counter; in hi3110_can_probe()
885 priv->can.clock.freq = freq / 2; in hi3110_can_probe()
886 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | in hi3110_can_probe()
892 priv->model = (enum hi3110_model)of_id->data; in hi3110_can_probe()
894 priv->model = spi_get_device_id(spi)->driver_data; in hi3110_can_probe()
895 priv->net = net; in hi3110_can_probe()
896 priv->clk = clk; in hi3110_can_probe()
901 spi->bits_per_word = 8; in hi3110_can_probe()
906 priv->power = devm_regulator_get_optional(&spi->dev, "vdd"); in hi3110_can_probe()
907 priv->transceiver = devm_regulator_get_optional(&spi->dev, "xceiver"); in hi3110_can_probe()
908 if ((PTR_ERR(priv->power) == -EPROBE_DEFER) || in hi3110_can_probe()
909 (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) { in hi3110_can_probe()
910 ret = -EPROBE_DEFER; in hi3110_can_probe()
914 ret = hi3110_power_enable(priv->power, 1); in hi3110_can_probe()
918 priv->spi = spi; in hi3110_can_probe()
919 mutex_init(&priv->hi3110_lock); in hi3110_can_probe()
923 spi->dev.coherent_dma_mask = ~0; in hi3110_can_probe()
928 priv->spi_tx_buf = dmam_alloc_coherent(&spi->dev, in hi3110_can_probe()
930 &priv->spi_tx_dma, in hi3110_can_probe()
933 if (priv->spi_tx_buf) { in hi3110_can_probe()
934 priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2)); in hi3110_can_probe()
935 priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma + in hi3110_can_probe()
938 /* Fall back to non-DMA */ in hi3110_can_probe()
943 /* Allocate non-DMA buffers */ in hi3110_can_probe()
945 priv->spi_tx_buf = devm_kzalloc(&spi->dev, HI3110_RX_BUF_LEN, in hi3110_can_probe()
947 if (!priv->spi_tx_buf) { in hi3110_can_probe()
948 ret = -ENOMEM; in hi3110_can_probe()
951 priv->spi_rx_buf = devm_kzalloc(&spi->dev, HI3110_RX_BUF_LEN, in hi3110_can_probe()
954 if (!priv->spi_rx_buf) { in hi3110_can_probe()
955 ret = -ENOMEM; in hi3110_can_probe()
960 SET_NETDEV_DEV(net, &spi->dev); in hi3110_can_probe()
964 if (ret == -ENODEV) in hi3110_can_probe()
965 dev_err(&spi->dev, "Cannot initialize %x. Wrong wiring?\n", in hi3110_can_probe()
966 priv->model); in hi3110_can_probe()
976 netdev_info(net, "%x successfully initialized.\n", priv->model); in hi3110_can_probe()
981 hi3110_power_enable(priv->power, 0); in hi3110_can_probe()
990 dev_err(&spi->dev, "Probe failed, err=%d\n", -ret); in hi3110_can_probe()
997 struct net_device *net = priv->net; in hi3110_can_remove()
1001 hi3110_power_enable(priv->power, 0); in hi3110_can_remove()
1003 if (!IS_ERR(priv->clk)) in hi3110_can_remove()
1004 clk_disable_unprepare(priv->clk); in hi3110_can_remove()
1015 struct net_device *net = priv->net; in hi3110_can_suspend()
1017 priv->force_quit = 1; in hi3110_can_suspend()
1018 disable_irq(spi->irq); in hi3110_can_suspend()
1027 hi3110_power_enable(priv->transceiver, 0); in hi3110_can_suspend()
1028 priv->after_suspend = HI3110_AFTER_SUSPEND_UP; in hi3110_can_suspend()
1030 priv->after_suspend = HI3110_AFTER_SUSPEND_DOWN; in hi3110_can_suspend()
1033 if (!IS_ERR_OR_NULL(priv->power)) { in hi3110_can_suspend()
1034 regulator_disable(priv->power); in hi3110_can_suspend()
1035 priv->after_suspend |= HI3110_AFTER_SUSPEND_POWER; in hi3110_can_suspend()
1046 if (priv->after_suspend & HI3110_AFTER_SUSPEND_POWER) in hi3110_can_resume()
1047 hi3110_power_enable(priv->power, 1); in hi3110_can_resume()
1049 if (priv->after_suspend & HI3110_AFTER_SUSPEND_UP) { in hi3110_can_resume()
1050 hi3110_power_enable(priv->transceiver, 1); in hi3110_can_resume()
1051 queue_work(priv->wq, &priv->restart_work); in hi3110_can_resume()
1053 priv->after_suspend = 0; in hi3110_can_resume()
1056 priv->force_quit = 0; in hi3110_can_resume()
1057 enable_irq(spi->irq); in hi3110_can_resume()
1078 MODULE_DESCRIPTION("Holt HI-3110 CAN driver");