Lines Matching +full:mixed +full:- +full:mode
4 * SPDX-License-Identifier: Apache-2.0
24 #define RCAR_CAN_CTLR_BOM (3 << 11) /* Bus-Off Recovery Mode Bits */
25 #define RCAR_CAN_CTLR_BOM_ENT BIT(11) /* Automatic halt mode entry at bus-off entry */
30 #define RCAR_CAN_CTLR_MLM BIT(3) /* Message Lost Mode Select */
31 #define RCAR_CAN_CTLR_IDFM (3 << 1) /* ID Format Mode Select Bits */
32 #define RCAR_CAN_CTLR_IDFM_MIXED BIT(2) /* Mixed ID mode */
33 #define RCAR_CAN_CTLR_MBM BIT(0) /* Mailbox Mode select */
116 #define RCAR_CAN_ECSR_EDPM BIT(7) /* Error Display Mode Select */
127 #define RCAR_CAN_TCR_TSTE BIT(0) /* Test Mode Enable Bit*/
136 #define RCAR_CAN_EIFR_BORIF BIT(4) /* Bus-Off Recovery Detect Flag */
137 #define RCAR_CAN_EIFR_BOEIF BIT(3) /* Bus-Off Entry Detect Flag */
148 * mailbox 60 - 63 - Rx FIFO mailboxes
149 * mailbox 56 - 59 - Tx FIFO mailboxes
150 * non-FIFO mailboxes are not used
202 return sys_read16(config->reg_addr + offs); in can_rcar_read16()
208 sys_write16(value, config->reg_addr + offs); in can_rcar_write16()
213 struct can_rcar_data *data = dev->data; in can_rcar_tx_done()
216 tx_cb = &data->tx_cb[data->tx_tail]; in can_rcar_tx_done()
217 data->tx_tail++; in can_rcar_tx_done()
218 if (data->tx_tail >= RCAR_CAN_FIFO_DEPTH) { in can_rcar_tx_done()
219 data->tx_tail = 0; in can_rcar_tx_done()
222 data->tx_unsent--; in can_rcar_tx_done()
223 tx_cb->cb(dev, err, tx_cb->cb_arg); in can_rcar_tx_done()
224 k_sem_give(&data->tx_sem); in can_rcar_tx_done()
230 err_cnt->tx_err_cnt = sys_read8(config->reg_addr + RCAR_CAN_TECR); in can_rcar_get_error_count()
231 err_cnt->rx_err_cnt = sys_read8(config->reg_addr + RCAR_CAN_RECR); in can_rcar_get_error_count()
236 const struct can_rcar_cfg *config = dev->config; in can_rcar_state_change()
237 struct can_rcar_data *data = dev->data; in can_rcar_state_change()
238 const can_state_change_callback_t cb = data->common.state_change_cb; in can_rcar_state_change()
239 void *state_change_cb_data = data->common.state_change_cb_user_data; in can_rcar_state_change()
242 if (data->state == newstate) { in can_rcar_state_change()
246 LOG_DBG("Can state change new: %u old:%u\n", newstate, data->state); in can_rcar_state_change()
248 data->state = newstate; in can_rcar_state_change()
259 const struct can_rcar_cfg *config = dev->config; in can_rcar_error()
262 eifr = sys_read8(config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
266 ecsr = sys_read8(config->reg_addr + RCAR_CAN_ECSR); in can_rcar_error()
270 config->reg_addr + RCAR_CAN_ECSR); in can_rcar_error()
275 config->reg_addr + RCAR_CAN_ECSR); in can_rcar_error()
280 config->reg_addr + RCAR_CAN_ECSR); in can_rcar_error()
285 config->reg_addr + RCAR_CAN_ECSR); in can_rcar_error()
290 config->reg_addr + RCAR_CAN_ECSR); in can_rcar_error()
295 config->reg_addr + RCAR_CAN_ECSR); in can_rcar_error()
300 config->reg_addr + RCAR_CAN_ECSR); in can_rcar_error()
304 config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
310 config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
317 config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
321 LOG_DBG("Bus-off recovery interrupt\n"); in can_rcar_error()
322 sys_write8(RCAR_CAN_IER_ERSIE, config->reg_addr + RCAR_CAN_IER); in can_rcar_error()
325 config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
329 LOG_DBG("Bus-off entry interrupt\n"); in can_rcar_error()
330 sys_write8(RCAR_CAN_IER_ERSIE, config->reg_addr + RCAR_CAN_IER); in can_rcar_error()
333 config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
340 config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
345 config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
350 config->reg_addr + RCAR_CAN_EIFR); in can_rcar_error()
362 if ((frame->flags & CAN_FRAME_RTR) != 0U) { in can_rcar_rx_filter_isr()
368 if (data->rx_callback[i] == NULL) { in can_rcar_rx_filter_isr()
372 if (!can_frame_matches_filter(frame, &data->filter[i])) { in can_rcar_rx_filter_isr()
379 data->rx_callback[i](dev, &tmp_frame, data->rx_callback_arg[i]); in can_rcar_rx_filter_isr()
385 const struct can_rcar_cfg *config = dev->config; in can_rcar_rx_isr()
386 struct can_rcar_data *data = dev->data; in can_rcar_rx_isr()
391 val = sys_read32(config->reg_addr + RCAR_CAN_MB_60); in can_rcar_rx_isr()
399 frame.dlc = sys_read16(config->reg_addr + in can_rcar_rx_isr()
413 frame.data[i] = sys_read8(config->reg_addr + in can_rcar_rx_isr()
419 frame.timestamp = sys_read8(config->reg_addr + in can_rcar_rx_isr()
422 frame.timestamp |= sys_read8(config->reg_addr + in can_rcar_rx_isr()
426 sys_write8(0xff, config->reg_addr + RCAR_CAN_RFPCR); in can_rcar_rx_isr()
433 const struct can_rcar_cfg *config = dev->config; in can_rcar_isr()
434 struct can_rcar_data *data = dev->data; in can_rcar_isr()
437 isr = sys_read8(config->reg_addr + RCAR_CAN_ISR); in can_rcar_isr()
441 sys_write8(isr, config->reg_addr + RCAR_CAN_ISR); in can_rcar_isr()
447 unsent = sys_read8(config->reg_addr + RCAR_CAN_TFCR); in can_rcar_isr()
450 if (data->tx_unsent <= unsent) { in can_rcar_isr()
457 isr = sys_read8(config->reg_addr + RCAR_CAN_ISR); in can_rcar_isr()
459 sys_write8(isr, config->reg_addr + RCAR_CAN_ISR); in can_rcar_isr()
463 while (!(sys_read8(config->reg_addr + RCAR_CAN_RFCR) in can_rcar_isr()
468 isr = sys_read8(config->reg_addr + RCAR_CAN_ISR); in can_rcar_isr()
470 sys_write8(isr, config->reg_addr + RCAR_CAN_ISR); in can_rcar_isr()
488 return -EAGAIN; in can_rcar_leave_sleep_mode()
508 return -EAGAIN; in can_rcar_enter_reset_mode()
530 return -EAGAIN; in can_rcar_enter_halt_mode()
553 return -EAGAIN; in can_rcar_enter_operation_mode()
557 sys_write8(RCAR_CAN_RFCR_RFE, config->reg_addr + RCAR_CAN_RFCR); in can_rcar_enter_operation_mode()
558 sys_write8(RCAR_CAN_TFCR_TFE, config->reg_addr + RCAR_CAN_TFCR); in can_rcar_enter_operation_mode()
574 const struct can_rcar_cfg *config = dev->config; in can_rcar_start()
575 struct can_rcar_data *data = dev->data; in can_rcar_start()
578 if (data->common.started) { in can_rcar_start()
579 return -EALREADY; in can_rcar_start()
582 if (config->common.phy != NULL) { in can_rcar_start()
583 ret = can_transceiver_enable(config->common.phy, data->common.mode); in can_rcar_start()
590 k_mutex_lock(&data->inst_mutex, K_FOREVER); in can_rcar_start()
596 LOG_ERR("failed to enter operation mode (err %d)", ret); in can_rcar_start()
598 if (config->common.phy != NULL) { in can_rcar_start()
600 (void)can_transceiver_disable(config->common.phy); in can_rcar_start()
603 data->common.started = true; in can_rcar_start()
606 k_mutex_unlock(&data->inst_mutex); in can_rcar_start()
613 const struct can_rcar_cfg *config = dev->config; in can_rcar_stop()
614 struct can_rcar_data *data = dev->data; in can_rcar_stop()
617 if (!data->common.started) { in can_rcar_stop()
618 return -EALREADY; in can_rcar_stop()
621 k_mutex_lock(&data->inst_mutex, K_FOREVER); in can_rcar_stop()
625 LOG_ERR("failed to enter halt mode (err %d)", ret); in can_rcar_stop()
626 k_mutex_unlock(&data->inst_mutex); in can_rcar_stop()
630 data->common.started = false; in can_rcar_stop()
632 k_mutex_unlock(&data->inst_mutex); in can_rcar_stop()
634 if (config->common.phy != NULL) { in can_rcar_stop()
635 ret = can_transceiver_disable(config->common.phy); in can_rcar_stop()
643 sys_write8((uint8_t)~RCAR_CAN_TFCR_TFE, config->reg_addr + RCAR_CAN_TFCR); in can_rcar_stop()
644 sys_write8(RCAR_CAN_TFCR_TFE, config->reg_addr + RCAR_CAN_TFCR); in can_rcar_stop()
647 while (data->tx_unsent) { in can_rcar_stop()
648 can_rcar_tx_done(dev, -ENETDOWN); in can_rcar_stop()
654 static int can_rcar_set_mode(const struct device *dev, can_mode_t mode) in can_rcar_set_mode() argument
657 const struct can_rcar_cfg *config = dev->config; in can_rcar_set_mode()
658 struct can_rcar_data *data = dev->data; in can_rcar_set_mode()
666 if ((mode & ~(supported)) != 0) { in can_rcar_set_mode()
667 LOG_ERR("Unsupported mode: 0x%08x", mode); in can_rcar_set_mode()
668 return -ENOTSUP; in can_rcar_set_mode()
671 if (data->common.started) { in can_rcar_set_mode()
672 return -EBUSY; in can_rcar_set_mode()
675 k_mutex_lock(&data->inst_mutex, K_FOREVER); in can_rcar_set_mode()
677 if ((mode & (CAN_MODE_LOOPBACK | CAN_MODE_LISTENONLY)) == in can_rcar_set_mode()
680 ret = -ENOTSUP; in can_rcar_set_mode()
682 } else if ((mode & CAN_MODE_LOOPBACK) != 0) { in can_rcar_set_mode()
683 /* Loopback mode */ in can_rcar_set_mode()
685 } else if ((mode & CAN_MODE_LISTENONLY) != 0) { in can_rcar_set_mode()
686 /* Listen-only mode */ in can_rcar_set_mode()
689 /* Normal mode */ in can_rcar_set_mode()
693 sys_write8(tcr, config->reg_addr + RCAR_CAN_TCR); in can_rcar_set_mode()
698 if ((mode & CAN_MODE_MANUAL_RECOVERY) != 0U) { in can_rcar_set_mode()
699 /* Set entry to halt automatically at bus-off */ in can_rcar_set_mode()
702 /* Clear entry to halt automatically at bus-off */ in can_rcar_set_mode()
709 data->common.mode = mode; in can_rcar_set_mode()
712 k_mutex_unlock(&data->inst_mutex); in can_rcar_set_mode()
728 bcr = RCAR_CAN_BCR_TSEG1(timing->phase_seg1 + timing->prop_seg - 1) | in can_rcar_set_bittiming()
729 RCAR_CAN_BCR_BPR(timing->prescaler - 1) | in can_rcar_set_bittiming()
730 RCAR_CAN_BCR_SJW(timing->sjw - 1) | in can_rcar_set_bittiming()
731 RCAR_CAN_BCR_TSEG2(timing->phase_seg2 - 1); in can_rcar_set_bittiming()
733 /* Don't overwrite CLKR with 32-bit BCR access; CLKR has 8-bit access. in can_rcar_set_bittiming()
734 * All the registers are big-endian but they get byte-swapped on 32-bit in can_rcar_set_bittiming()
735 * read/write (but not on 8-bit, contrary to the manuals)... in can_rcar_set_bittiming()
738 config->reg_addr + RCAR_CAN_BCR); in can_rcar_set_bittiming()
744 const struct can_rcar_cfg *config = dev->config; in can_rcar_set_timing()
745 struct can_rcar_data *data = dev->data; in can_rcar_set_timing()
756 if (data->common.started) { in can_rcar_set_timing()
757 return -EBUSY; in can_rcar_set_timing()
760 k_mutex_lock(&data->inst_mutex, K_FOREVER); in can_rcar_set_timing()
762 /* Changing bittiming should be done in reset mode. in can_rcar_set_timing()
763 * Switching to reset mode is resetting loopback mode (TCR), in can_rcar_set_timing()
765 * Storing these reg values to restore them once back in halt mode. in can_rcar_set_timing()
768 regs[i].value = sys_read8(config->reg_addr + regs[i].address); in can_rcar_set_timing()
771 /* Switching to reset mode */ in can_rcar_set_timing()
780 /* Restoring registers must be done in halt mode */ in can_rcar_set_timing()
788 sys_write8(regs[i].value, config->reg_addr + regs[i].address); in can_rcar_set_timing()
792 k_mutex_unlock(&data->inst_mutex); in can_rcar_set_timing()
800 struct can_rcar_data *data = dev->data; in can_rcar_set_state_change_callback()
802 data->common.state_change_cb = cb; in can_rcar_set_state_change_callback()
803 data->common.state_change_cb_user_data = user_data; in can_rcar_set_state_change_callback()
809 const struct can_rcar_cfg *config = dev->config; in can_rcar_get_state()
810 struct can_rcar_data *data = dev->data; in can_rcar_get_state()
813 if (!data->common.started) { in can_rcar_get_state()
816 *state = data->state; in can_rcar_get_state()
830 const struct can_rcar_cfg *config = dev->config; in can_rcar_recover()
831 struct can_rcar_data *data = dev->data; in can_rcar_recover()
835 if (!data->common.started) { in can_rcar_recover()
836 return -ENETDOWN; in can_rcar_recover()
839 if ((data->common.mode & CAN_MODE_MANUAL_RECOVERY) == 0U) { in can_rcar_recover()
840 return -ENOTSUP; in can_rcar_recover()
843 if (data->state != CAN_STATE_BUS_OFF) { in can_rcar_recover()
847 if (k_mutex_lock(&data->inst_mutex, K_FOREVER)) { in can_rcar_recover()
848 return -EAGAIN; in can_rcar_recover()
852 while (data->state == CAN_STATE_BUS_OFF) { in can_rcar_recover()
859 k_uptime_ticks() - start_time >= timeout.ticks) { in can_rcar_recover()
860 ret = -EAGAIN; in can_rcar_recover()
866 k_mutex_unlock(&data->inst_mutex); in can_rcar_recover()
875 const struct can_rcar_cfg *config = dev->config; in can_rcar_send()
876 struct can_rcar_data *data = dev->data; in can_rcar_send()
885 , frame->dlc, dev->name in can_rcar_send()
886 , frame->id in can_rcar_send()
887 , (frame->flags & CAN_FRAME_IDE) != 0 ? in can_rcar_send()
889 , (frame->flags & CAN_FRAME_RTR) != 0 ? "yes" : "no"); in can_rcar_send()
891 if (frame->dlc > CAN_MAX_DLC) { in can_rcar_send()
893 frame->dlc, CAN_MAX_DLC); in can_rcar_send()
894 return -EINVAL; in can_rcar_send()
897 if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) { in can_rcar_send()
898 LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags); in can_rcar_send()
899 return -ENOTSUP; in can_rcar_send()
902 if (!data->common.started) { in can_rcar_send()
903 return -ENETDOWN; in can_rcar_send()
907 if (k_sem_take(&data->tx_sem, timeout) != 0) { in can_rcar_send()
908 return -EAGAIN; in can_rcar_send()
911 k_mutex_lock(&data->inst_mutex, K_FOREVER); in can_rcar_send()
912 tx_cb = &data->tx_cb[data->tx_head]; in can_rcar_send()
913 tx_cb->cb = callback; in can_rcar_send()
914 tx_cb->cb_arg = user_data; in can_rcar_send()
916 data->tx_head++; in can_rcar_send()
917 if (data->tx_head >= RCAR_CAN_FIFO_DEPTH) { in can_rcar_send()
918 data->tx_head = 0; in can_rcar_send()
921 if ((frame->flags & CAN_FRAME_IDE) != 0) { in can_rcar_send()
922 identifier = frame->id | RCAR_CAN_MB_IDE; in can_rcar_send()
924 identifier = frame->id << RCAR_CAN_MB_SID_SHIFT; in can_rcar_send()
927 if ((frame->flags & CAN_FRAME_RTR) != 0) { in can_rcar_send()
931 sys_write32(identifier, config->reg_addr + RCAR_CAN_MB_56); in can_rcar_send()
933 sys_write16(frame->dlc, config->reg_addr in can_rcar_send()
936 if ((frame->flags & CAN_FRAME_RTR) == 0) { in can_rcar_send()
937 for (i = 0; i < frame->dlc; i++) { in can_rcar_send()
938 sys_write8(frame->data[i], config->reg_addr in can_rcar_send()
944 data->tx_unsent++; in can_rcar_send()
945 /* Start Tx: increment the CPU-side pointer for the transmit FIFO in can_rcar_send()
948 sys_write8(0xff, config->reg_addr + RCAR_CAN_TFPCR); in can_rcar_send()
950 k_mutex_unlock(&data->inst_mutex); in can_rcar_send()
960 struct can_rcar_data *data = dev->data; in can_rcar_add_rx_filter_unlocked()
964 if (data->rx_callback[i] == NULL) { in can_rcar_add_rx_filter_unlocked()
965 data->rx_callback_arg[i] = cb_arg; in can_rcar_add_rx_filter_unlocked()
966 data->filter[i] = *filter; in can_rcar_add_rx_filter_unlocked()
968 data->rx_callback[i] = cb; in can_rcar_add_rx_filter_unlocked()
973 return -ENOSPC; in can_rcar_add_rx_filter_unlocked()
979 struct can_rcar_data *data = dev->data; in can_rcar_add_rx_filter()
982 if ((filter->flags & ~(CAN_FILTER_IDE)) != 0) { in can_rcar_add_rx_filter()
983 LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags); in can_rcar_add_rx_filter()
984 return -ENOTSUP; in can_rcar_add_rx_filter()
987 k_mutex_lock(&data->rx_mutex, K_FOREVER); in can_rcar_add_rx_filter()
989 k_mutex_unlock(&data->rx_mutex); in can_rcar_add_rx_filter()
995 struct can_rcar_data *data = dev->data; in can_rcar_remove_rx_filter()
1002 k_mutex_lock(&data->rx_mutex, K_FOREVER); in can_rcar_remove_rx_filter()
1004 data->rx_callback[filter_id] = NULL; in can_rcar_remove_rx_filter()
1005 k_mutex_unlock(&data->rx_mutex); in can_rcar_remove_rx_filter()
1010 const struct can_rcar_cfg *config = dev->config; in can_rcar_init()
1011 struct can_rcar_data *data = dev->data; in can_rcar_init()
1016 k_mutex_init(&data->inst_mutex); in can_rcar_init()
1017 k_mutex_init(&data->rx_mutex); in can_rcar_init()
1018 k_sem_init(&data->tx_sem, RCAR_CAN_FIFO_DEPTH, RCAR_CAN_FIFO_DEPTH); in can_rcar_init()
1020 data->tx_head = 0; in can_rcar_init()
1021 data->tx_tail = 0; in can_rcar_init()
1022 data->tx_unsent = 0; in can_rcar_init()
1024 memset(data->rx_callback, 0, sizeof(data->rx_callback)); in can_rcar_init()
1025 data->state = CAN_STATE_ERROR_ACTIVE; in can_rcar_init()
1026 data->common.state_change_cb = NULL; in can_rcar_init()
1027 data->common.state_change_cb_user_data = NULL; in can_rcar_init()
1029 if (config->common.phy != NULL) { in can_rcar_init()
1030 if (!device_is_ready(config->common.phy)) { in can_rcar_init()
1032 return -ENODEV; in can_rcar_init()
1036 if (!device_is_ready(config->clock_dev)) { in can_rcar_init()
1038 return -ENODEV; in can_rcar_init()
1042 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); in can_rcar_init()
1048 ret = clock_control_off(config->clock_dev, in can_rcar_init()
1049 (clock_control_subsys_t)&config->mod_clk); in can_rcar_init()
1054 ret = clock_control_on(config->clock_dev, in can_rcar_init()
1055 (clock_control_subsys_t)&config->mod_clk); in can_rcar_init()
1060 ret = clock_control_on(config->clock_dev, in can_rcar_init()
1061 (clock_control_subsys_t)&config->bus_clk); in can_rcar_init()
1067 __ASSERT(!ret, "Fail to set CAN controller to reset mode"); in can_rcar_init()
1073 __ASSERT(!ret, "Fail to leave CAN controller from sleep mode"); in can_rcar_init()
1078 ret = can_calc_timing(dev, &timing, config->common.bitrate, in can_rcar_init()
1079 config->common.sample_point); in can_rcar_init()
1080 if (ret == -EINVAL) { in can_rcar_init()
1082 return -EIO; in can_rcar_init()
1087 LOG_DBG("Sample-point err : %d", ret); in can_rcar_init()
1100 ctlr |= RCAR_CAN_CTLR_IDFM_MIXED; /* Select mixed ID mode */ in can_rcar_init()
1101 ctlr &= ~RCAR_CAN_CTLR_BOM_ENT; /* Clear entry to halt automatically at bus-off */ in can_rcar_init()
1102 ctlr |= RCAR_CAN_CTLR_MBM; /* Select FIFO mailbox mode */ in can_rcar_init()
1103 ctlr |= RCAR_CAN_CTLR_MLM; /* Overrun mode */ in can_rcar_init()
1104 ctlr &= ~RCAR_CAN_CTLR_SLPM; /* Clear CAN Sleep mode */ in can_rcar_init()
1108 sys_write32(0, config->reg_addr + RCAR_CAN_MKR8); in can_rcar_init()
1109 sys_write32(0, config->reg_addr + RCAR_CAN_MKR9); in can_rcar_init()
1110 /* In FIFO mailbox mode, write "0" to bits 24 to 31 */ in can_rcar_init()
1111 sys_write32(0, config->reg_addr + RCAR_CAN_MKIVLR0); in can_rcar_init()
1112 sys_write32(0, config->reg_addr + RCAR_CAN_MKIVLR1); in can_rcar_init()
1116 sys_write32(0, config->reg_addr + RCAR_CAN_FIDCR0); in can_rcar_init()
1118 config->reg_addr + RCAR_CAN_FIDCR1); in can_rcar_init()
1122 config->reg_addr + RCAR_CAN_MIER1); in can_rcar_init()
1125 config->reg_addr + RCAR_CAN_IER); in can_rcar_init()
1128 sys_write8(RCAR_CAN_ECSR_EDPM, config->reg_addr + RCAR_CAN_ECSR); in can_rcar_init()
1131 sys_write8(0xFF, config->reg_addr + RCAR_CAN_EIER); in can_rcar_init()
1133 config->init_func(dev); in can_rcar_init()
1140 const struct can_rcar_cfg *config = dev->config; in can_rcar_get_core_clock()
1142 *rate = config->bus_clk.rate; in can_rcar_get_core_clock()