Lines Matching refs:i2c_bus
179 static inline void cdns_i2c_writereg(const struct cdns_i2c_data *i2c_bus, in cdns_i2c_writereg() argument
182 uintptr_t reg_address = (uintptr_t)(i2c_bus->membase) + offset; in cdns_i2c_writereg()
194 static inline uint32_t cdns_i2c_readreg(const struct cdns_i2c_data *i2c_bus, uintptr_t offset) in cdns_i2c_readreg() argument
196 uintptr_t reg_address = (uintptr_t)(i2c_bus->membase) + offset; in cdns_i2c_readreg()
205 static void cdns_i2c_enable_peripheral(struct cdns_i2c_data *i2c_bus) in cdns_i2c_enable_peripheral() argument
207 cdns_i2c_writereg(i2c_bus, i2c_bus->ctrl_reg, CDNS_I2C_CR_OFFSET); in cdns_i2c_enable_peripheral()
214 cdns_i2c_writereg(i2c_bus, CDNS_I2C_TIMEOUT_MAX, CDNS_I2C_TIME_OUT_OFFSET); in cdns_i2c_enable_peripheral()
315 static int32_t cdns_i2c_setclk(struct cdns_i2c_data *i2c_bus, uint32_t req_i2c_speed) in cdns_i2c_setclk() argument
323 ret = cdns_i2c_calc_divs(&fscl, i2c_bus->input_clk, &div_a, &div_b); in cdns_i2c_setclk()
327 i2c_bus->i2c_clk = fscl; /* Update true SCL value */ in cdns_i2c_setclk()
330 ctrl_reg = i2c_bus->ctrl_reg; in cdns_i2c_setclk()
334 i2c_bus->ctrl_reg = ctrl_reg; in cdns_i2c_setclk()
335 cdns_i2c_writereg(i2c_bus, ctrl_reg, CDNS_I2C_CR_OFFSET); in cdns_i2c_setclk()
355 struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data; in cdns_i2c_configure() local
358 (void)k_mutex_lock(&i2c_bus->bus_mutex, K_FOREVER); in cdns_i2c_configure()
378 ret = cdns_i2c_setclk(i2c_bus, i2c_speed); in cdns_i2c_configure()
386 i2c_bus->ctrl_reg |= CDNS_I2C_CR_MASTER_EN_MASK; in cdns_i2c_configure()
387 cdns_i2c_enable_peripheral(i2c_bus); in cdns_i2c_configure()
390 (void)k_mutex_unlock(&i2c_bus->bus_mutex); in cdns_i2c_configure()
405 struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data; in cdns_i2c_get_config() local
406 uint32_t bus_speed = i2c_bus->i2c_clk; in cdns_i2c_get_config()
434 static void cdns_i2c_clear_bus_hold(struct cdns_i2c_data *i2c_bus) in cdns_i2c_clear_bus_hold() argument
436 uint32_t reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET); in cdns_i2c_clear_bus_hold()
439 cdns_i2c_writereg(i2c_bus, reg & ~CDNS_I2C_CR_HOLD, CDNS_I2C_CR_OFFSET); in cdns_i2c_clear_bus_hold()
450 static inline bool cdns_is_fifo_hold_quirk(const struct cdns_i2c_data *i2c_bus, in cdns_is_fifo_hold_quirk() argument
453 return (hold_wrkaround && (i2c_bus->curr_recv_count == (i2c_bus->fifo_depth + 1U))); in cdns_is_fifo_hold_quirk()
461 static void cdns_i2c_master_handle_receive_interrupt(struct cdns_i2c_data *i2c_bus, in cdns_i2c_master_handle_receive_interrupt() argument
473 while ((cdns_i2c_readreg(i2c_bus, CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_RXDV) != 0U) { in cdns_i2c_master_handle_receive_interrupt()
475 if (i2c_bus->recv_count > 0U) { in cdns_i2c_master_handle_receive_interrupt()
476 *(i2c_bus->p_recv_buf) = (uint8_t)cdns_i2c_readreg(i2c_bus, in cdns_i2c_master_handle_receive_interrupt()
478 i2c_bus->p_recv_buf++; in cdns_i2c_master_handle_receive_interrupt()
479 i2c_bus->recv_count--; in cdns_i2c_master_handle_receive_interrupt()
480 i2c_bus->curr_recv_count--; in cdns_i2c_master_handle_receive_interrupt()
484 i2c_bus->err_status |= CDNS_I2C_IXR_TO; in cdns_i2c_master_handle_receive_interrupt()
489 if (cdns_is_fifo_hold_quirk(i2c_bus, in cdns_i2c_master_handle_receive_interrupt()
490 i2c_bus->recv_count > i2c_bus->curr_recv_count)) { in cdns_i2c_master_handle_receive_interrupt()
496 if (cdns_is_fifo_hold_quirk(i2c_bus, i2c_bus->recv_count > i2c_bus->curr_recv_count)) { in cdns_i2c_master_handle_receive_interrupt()
497 transfer_size = i2c_bus->recv_count - i2c_bus->fifo_depth; in cdns_i2c_master_handle_receive_interrupt()
499 if (transfer_size > i2c_bus->transfer_size) { in cdns_i2c_master_handle_receive_interrupt()
500 xfer_size = i2c_bus->transfer_size; in cdns_i2c_master_handle_receive_interrupt()
506 while (cdns_i2c_readreg(i2c_bus, CDNS_I2C_XFER_SIZE_OFFSET) != in cdns_i2c_master_handle_receive_interrupt()
507 (i2c_bus->curr_recv_count - i2c_bus->fifo_depth)) { in cdns_i2c_master_handle_receive_interrupt()
511 cdns_i2c_writereg(i2c_bus, xfer_size, CDNS_I2C_XFER_SIZE_OFFSET); in cdns_i2c_master_handle_receive_interrupt()
512 i2c_bus->curr_recv_count = xfer_size + i2c_bus->fifo_depth; in cdns_i2c_master_handle_receive_interrupt()
517 (i2c_bus->recv_count == 0U)) { in cdns_i2c_master_handle_receive_interrupt()
519 if (i2c_bus->bus_hold_flag == 0U) { in cdns_i2c_master_handle_receive_interrupt()
520 cdns_i2c_clear_bus_hold(i2c_bus); in cdns_i2c_master_handle_receive_interrupt()
523 (void)k_event_post(&i2c_bus->xfer_done, I2C_XFER_COMPLETION_EVENT); in cdns_i2c_master_handle_receive_interrupt()
532 static void cdns_i2c_master_handle_transmit_interrupt(struct cdns_i2c_data *i2c_bus, in cdns_i2c_master_handle_transmit_interrupt() argument
544 if (i2c_bus->send_count > 0U) { in cdns_i2c_master_handle_transmit_interrupt()
546 avail_bytes = i2c_bus->fifo_depth - cdns_i2c_readreg(i2c_bus, in cdns_i2c_master_handle_transmit_interrupt()
549 if (i2c_bus->send_count > avail_bytes) { in cdns_i2c_master_handle_transmit_interrupt()
552 bytes_to_send = i2c_bus->send_count; in cdns_i2c_master_handle_transmit_interrupt()
557 cdns_i2c_writereg(i2c_bus, *(i2c_bus->p_send_buf), CDNS_I2C_DATA_OFFSET); in cdns_i2c_master_handle_transmit_interrupt()
558 i2c_bus->p_send_buf++; in cdns_i2c_master_handle_transmit_interrupt()
559 i2c_bus->send_count--; in cdns_i2c_master_handle_transmit_interrupt()
564 (void)k_event_post(&i2c_bus->xfer_done, I2C_XFER_COMPLETION_EVENT); in cdns_i2c_master_handle_transmit_interrupt()
568 if ((i2c_bus->send_count == 0U) && (i2c_bus->bus_hold_flag == 0U)) { in cdns_i2c_master_handle_transmit_interrupt()
569 cdns_i2c_clear_bus_hold(i2c_bus); in cdns_i2c_master_handle_transmit_interrupt()
580 static void cdns_i2c_master_isr(struct cdns_i2c_data *i2c_bus) in cdns_i2c_master_isr() argument
585 isr_status = cdns_i2c_readreg(i2c_bus, CDNS_I2C_ISR_OFFSET); in cdns_i2c_master_isr()
588 cdns_i2c_writereg(i2c_bus, isr_status, CDNS_I2C_ISR_OFFSET); in cdns_i2c_master_isr()
591 i2c_bus->err_status = isr_status & CDNS_I2C_IXR_ERR_INTR_MASK; in cdns_i2c_master_isr()
595 (void)k_event_post(&i2c_bus->xfer_done, I2C_XFER_COMPLETION_EVENT); in cdns_i2c_master_isr()
600 if (i2c_bus->p_recv_buf != NULL) { in cdns_i2c_master_isr()
601 cdns_i2c_master_handle_receive_interrupt(i2c_bus, isr_status); in cdns_i2c_master_isr()
605 if (i2c_bus->p_recv_buf == NULL) { in cdns_i2c_master_isr()
606 cdns_i2c_master_handle_transmit_interrupt(i2c_bus, isr_status); in cdns_i2c_master_isr()
616 struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data; in cdns_i2c_isr() local
619 cdns_i2c_master_isr(i2c_bus); in cdns_i2c_isr()
627 static void cdns_i2c_mrecv(struct cdns_i2c_data *i2c_bus, uint16_t msg_addr) in cdns_i2c_mrecv() argument
635 i2c_bus->p_recv_buf = i2c_bus->p_msg->buf; in cdns_i2c_mrecv()
636 i2c_bus->recv_count = i2c_bus->p_msg->len; in cdns_i2c_mrecv()
637 i2c_bus->curr_recv_count = i2c_bus->recv_count; in cdns_i2c_mrecv()
640 ctrl_reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET); in cdns_i2c_mrecv()
644 if (i2c_bus->recv_count > i2c_bus->fifo_depth) { in cdns_i2c_mrecv()
648 cdns_i2c_writereg(i2c_bus, ctrl_reg, CDNS_I2C_CR_OFFSET); in cdns_i2c_mrecv()
651 isr_status = cdns_i2c_readreg(i2c_bus, CDNS_I2C_ISR_OFFSET); in cdns_i2c_mrecv()
652 cdns_i2c_writereg(i2c_bus, isr_status, CDNS_I2C_ISR_OFFSET); in cdns_i2c_mrecv()
655 if ((i2c_bus->recv_count) > (i2c_bus->transfer_size)) { in cdns_i2c_mrecv()
656 cdns_i2c_writereg(i2c_bus, i2c_bus->transfer_size, in cdns_i2c_mrecv()
658 i2c_bus->curr_recv_count = i2c_bus->transfer_size; in cdns_i2c_mrecv()
660 cdns_i2c_writereg(i2c_bus, i2c_bus->recv_count, CDNS_I2C_XFER_SIZE_OFFSET); in cdns_i2c_mrecv()
664 if ((i2c_bus->bus_hold_flag == 0U) && (i2c_bus->recv_count <= i2c_bus->fifo_depth)) { in cdns_i2c_mrecv()
680 cdns_i2c_writereg(i2c_bus, addr, CDNS_I2C_ADDR_OFFSET); in cdns_i2c_mrecv()
681 cdns_i2c_writereg(i2c_bus, ctrl_reg, CDNS_I2C_CR_OFFSET); in cdns_i2c_mrecv()
683 (void)cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET); in cdns_i2c_mrecv()
686 cdns_i2c_writereg(i2c_bus, addr, CDNS_I2C_ADDR_OFFSET); in cdns_i2c_mrecv()
690 cdns_i2c_writereg(i2c_bus, CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET); in cdns_i2c_mrecv()
698 static void cdns_i2c_msend(struct cdns_i2c_data *i2c_bus, uint16_t msg_addr) in cdns_i2c_msend() argument
706 i2c_bus->p_recv_buf = NULL; in cdns_i2c_msend()
707 i2c_bus->p_send_buf = i2c_bus->p_msg->buf; in cdns_i2c_msend()
708 i2c_bus->send_count = i2c_bus->p_msg->len; in cdns_i2c_msend()
711 ctrl_reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET); in cdns_i2c_msend()
716 if (i2c_bus->send_count > i2c_bus->fifo_depth) { in cdns_i2c_msend()
719 cdns_i2c_writereg(i2c_bus, ctrl_reg, CDNS_I2C_CR_OFFSET); in cdns_i2c_msend()
722 isr_status = cdns_i2c_readreg(i2c_bus, CDNS_I2C_ISR_OFFSET); in cdns_i2c_msend()
723 cdns_i2c_writereg(i2c_bus, isr_status, CDNS_I2C_ISR_OFFSET); in cdns_i2c_msend()
726 avail_bytes = i2c_bus->fifo_depth - cdns_i2c_readreg(i2c_bus, CDNS_I2C_XFER_SIZE_OFFSET); in cdns_i2c_msend()
727 bytes_to_send = (i2c_bus->send_count > avail_bytes) ? avail_bytes : i2c_bus->send_count; in cdns_i2c_msend()
731 cdns_i2c_writereg(i2c_bus, (*(i2c_bus->p_send_buf)), CDNS_I2C_DATA_OFFSET); in cdns_i2c_msend()
732 (i2c_bus->p_send_buf)++; in cdns_i2c_msend()
733 i2c_bus->send_count--; in cdns_i2c_msend()
738 if ((i2c_bus->bus_hold_flag == 0U) && (i2c_bus->send_count == 0U)) { in cdns_i2c_msend()
739 cdns_i2c_clear_bus_hold(i2c_bus); in cdns_i2c_msend()
743 cdns_i2c_writereg(i2c_bus, ((uint32_t)msg_addr & CDNS_I2C_ADDR_MASK), in cdns_i2c_msend()
747 cdns_i2c_writereg(i2c_bus, CDNS_I2C_ENABLED_INTR_MASK, CDNS_I2C_IER_OFFSET); in cdns_i2c_msend()
757 static void cdns_i2c_master_reset(struct cdns_i2c_data *i2c_bus) in cdns_i2c_master_reset() argument
762 cdns_i2c_writereg(i2c_bus, CDNS_I2C_IXR_ALL_INTR_MASK, CDNS_I2C_IDR_OFFSET); in cdns_i2c_master_reset()
765 regval = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET); in cdns_i2c_master_reset()
768 cdns_i2c_writereg(i2c_bus, regval, CDNS_I2C_CR_OFFSET); in cdns_i2c_master_reset()
771 cdns_i2c_writereg(i2c_bus, 0, CDNS_I2C_XFER_SIZE_OFFSET); in cdns_i2c_master_reset()
774 regval = cdns_i2c_readreg(i2c_bus, CDNS_I2C_ISR_OFFSET); in cdns_i2c_master_reset()
775 cdns_i2c_writereg(i2c_bus, regval, CDNS_I2C_ISR_OFFSET); in cdns_i2c_master_reset()
778 regval = cdns_i2c_readreg(i2c_bus, CDNS_I2C_SR_OFFSET); in cdns_i2c_master_reset()
779 cdns_i2c_writereg(i2c_bus, regval, CDNS_I2C_SR_OFFSET); in cdns_i2c_master_reset()
790 static int32_t cdns_i2c_process_msg(struct cdns_i2c_data *i2c_bus, struct i2c_msg *msg, in cdns_i2c_process_msg() argument
799 i2c_bus->p_msg = msg; in cdns_i2c_process_msg()
800 i2c_bus->err_status = 0U; in cdns_i2c_process_msg()
801 (void)k_event_clear(&i2c_bus->xfer_done, (uint32_t)I2C_XFER_COMPLETION_EVENT); in cdns_i2c_process_msg()
804 reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET); in cdns_i2c_process_msg()
808 cdns_i2c_writereg(i2c_bus, in cdns_i2c_process_msg()
815 cdns_i2c_writereg(i2c_bus, in cdns_i2c_process_msg()
823 cdns_i2c_mrecv(i2c_bus, addr); /* Receive data */ in cdns_i2c_process_msg()
825 cdns_i2c_msend(i2c_bus, addr); /* Send data */ in cdns_i2c_process_msg()
830 ((k_ticks_t)(i2c_bus->i2c_clk)); in cdns_i2c_process_msg()
837 events = k_event_wait(&i2c_bus->xfer_done, (uint32_t)I2C_XFER_COMPLETION_EVENT, in cdns_i2c_process_msg()
841 cdns_i2c_master_reset(i2c_bus); in cdns_i2c_process_msg()
847 cdns_i2c_writereg(i2c_bus, CDNS_I2C_IXR_ALL_INTR_MASK, CDNS_I2C_IDR_OFFSET); in cdns_i2c_process_msg()
850 if ((i2c_bus->err_status & CDNS_I2C_IXR_ARB_LOST) == CDNS_I2C_IXR_ARB_LOST) { in cdns_i2c_process_msg()
868 static bool cdns_i2c_wait_for_bus_free(struct cdns_i2c_data *i2c_bus, uint32_t timeout_us) in cdns_i2c_wait_for_bus_free() argument
875 reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_SR_OFFSET); in cdns_i2c_wait_for_bus_free()
903 static int32_t cdns_i2c_master_handle_repeated_start(struct cdns_i2c_data *i2c_bus, in cdns_i2c_master_handle_repeated_start() argument
911 i2c_bus->bus_hold_flag = 1; in cdns_i2c_master_handle_repeated_start()
912 reg = cdns_i2c_readreg(i2c_bus, CDNS_I2C_CR_OFFSET); in cdns_i2c_master_handle_repeated_start()
914 cdns_i2c_writereg(i2c_bus, reg, CDNS_I2C_CR_OFFSET); in cdns_i2c_master_handle_repeated_start()
925 static int32_t cdns_i2c_master_handle_transfer_error(struct cdns_i2c_data *i2c_bus) in cdns_i2c_master_handle_transfer_error() argument
930 cdns_i2c_master_reset(i2c_bus); in cdns_i2c_master_handle_transfer_error()
932 if ((i2c_bus->err_status & CDNS_I2C_IXR_NACK) != 0U) { in cdns_i2c_master_handle_transfer_error()
953 struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data; in cdns_i2c_master_transfer() local
958 (void)k_mutex_lock(&i2c_bus->bus_mutex, K_FOREVER); in cdns_i2c_master_transfer()
961 if (cdns_i2c_wait_for_bus_free(i2c_bus, CDNS_I2C_TIMEOUT_US) == false) { in cdns_i2c_master_transfer()
968 ret = cdns_i2c_master_handle_repeated_start(i2c_bus, msgs, num_msgs); in cdns_i2c_master_transfer()
978 i2c_bus->bus_hold_flag = 0; in cdns_i2c_master_transfer()
982 ret = cdns_i2c_process_msg(i2c_bus, msg_ptr, addr); in cdns_i2c_master_transfer()
988 if ((i2c_bus->err_status) != 0U) { in cdns_i2c_master_transfer()
989 ret = cdns_i2c_master_handle_transfer_error(i2c_bus); in cdns_i2c_master_transfer()
999 (void)k_mutex_unlock(&i2c_bus->bus_mutex); in cdns_i2c_master_transfer()
1013 struct cdns_i2c_data *i2c_bus = (struct cdns_i2c_data *)dev->data; in cdns_i2c_init() local
1016 (void)k_mutex_init(&i2c_bus->bus_mutex); in cdns_i2c_init()
1017 k_event_init(&i2c_bus->xfer_done); in cdns_i2c_init()
1020 i2c_bus->ctrl_reg = CDNS_I2C_CR_MASTER_EN_MASK; in cdns_i2c_init()
1021 i2c_bus->transfer_size = CDNS_I2C_TRANSFER_SIZE_DEFAULT; in cdns_i2c_init()
1024 ret = cdns_i2c_setclk(i2c_bus, i2c_bus->i2c_clk); in cdns_i2c_init()
1026 LOG_ERR("Invalid SCL clock: %u Hz", i2c_bus->i2c_clk); in cdns_i2c_init()
1035 cdns_i2c_enable_peripheral(i2c_bus); in cdns_i2c_init()
1037 LOG_INF("%u KHz mmio %08lx", i2c_bus->i2c_clk/1000U, i2c_bus->membase); in cdns_i2c_init()