Lines Matching +full:fifo +full:- +full:read +full:- +full:threshold

5  * SPDX-License-Identifier: Apache-2.0
20 #include "i2c-priv.h"
123 #define M_RX_FIFO_MAX_THLD_VALUE (TX_RX_FIFO_SIZE - 1)
140 * max target read per interrupt is set to 10 bytes.
151 #define DEV_CFG(dev) ((struct iproc_i2c_config *)(dev)->config)
152 #define DEV_DATA(dev) ((struct iproc_i2c_data *)(dev)->data)
153 #define DEV_BASE(dev) ((DEV_CFG(dev))->base)
215 return -EINVAL; in iproc_i2c_target_set_address()
231 struct i2c_target_config *target_config = dd->target_cfg; in iproc_i2c_target_init()
250 ret = iproc_i2c_target_set_address(dev, target_config->address); in iproc_i2c_target_init()
258 /* Enable interrupt register to indicate a valid byte in receive fifo */ in iproc_i2c_target_init()
260 /* Enable interrupt register to indicate target Rx FIFO Full */ in iproc_i2c_target_init()
262 /* Enable interrupt register to indicate a Master read transaction */ in iproc_i2c_target_init()
266 dd->target_int_mask = val; in iproc_i2c_target_init()
280 return -EBUSY; in iproc_i2c_check_target_status()
288 LOG_ERR("Master aborted read transaction"); in iproc_i2c_check_target_status()
291 /* re-initialize i2c for recovery */ in iproc_i2c_check_target_status()
296 return -ETIMEDOUT; in iproc_i2c_check_target_status()
305 struct i2c_target_config *target_cfg = dd->target_cfg; in iproc_i2c_target_read()
318 target_cfg->callbacks->write_requested(target_cfg); in iproc_i2c_target_read()
319 dd->rx_start_rcvd = true; in iproc_i2c_target_read()
320 dd->target_read_complete = false; in iproc_i2c_target_read()
321 } else if ((rx_status == I2C_TARGET_RX_DATA) && dd->rx_start_rcvd) { in iproc_i2c_target_read()
323 target_cfg->callbacks->write_received(target_cfg, rx_data); in iproc_i2c_target_read()
324 } else if ((rx_status == I2C_TARGET_RX_END) && dd->rx_start_rcvd) { in iproc_i2c_target_read()
326 if (dd->target_rx_only) { in iproc_i2c_target_read()
327 target_cfg->callbacks->write_received(target_cfg, rx_data); in iproc_i2c_target_read()
329 target_cfg->callbacks->stop(target_cfg); in iproc_i2c_target_read()
331 dd->rx_start_rcvd = false; in iproc_i2c_target_read()
332 dd->target_read_complete = true; in iproc_i2c_target_read()
347 if (!dd->target_rx_only && dd->target_read_complete) { in iproc_i2c_target_rx()
349 * In case of single byte master-read request, in iproc_i2c_target_rx()
356 * eeprom or other backend target driver read pointer twice. in iproc_i2c_target_rx()
358 dd->tx_underrun = 0; in iproc_i2c_target_rx()
359 dd->target_int_mask |= BIT(IE_S_TX_UNDERRUN_SHIFT); in iproc_i2c_target_rx()
366 sys_write32(dd->target_int_mask, base + IE_OFFSET); in iproc_i2c_target_rx()
372 struct i2c_target_config *target_cfg = dd->target_cfg; in iproc_i2c_target_isr()
383 val &= ~dd->target_int_mask; in iproc_i2c_target_isr()
387 /* Master-write-read request */ in iproc_i2c_target_isr()
388 dd->target_rx_only = false; in iproc_i2c_target_isr()
390 /* Master-write request only */ in iproc_i2c_target_isr()
391 dd->target_rx_only = true; in iproc_i2c_target_isr()
408 dd->tx_underrun++; in iproc_i2c_target_isr()
409 if (dd->tx_underrun == 1) { in iproc_i2c_target_isr()
410 /* Start of SMBUS for Master Read */ in iproc_i2c_target_isr()
411 target_cfg->callbacks->read_requested(target_cfg, &data); in iproc_i2c_target_isr()
413 /* Master read other than start */ in iproc_i2c_target_isr()
414 target_cfg->callbacks->read_processed(target_cfg, &data); in iproc_i2c_target_isr()
425 /* Stop received from master in case of master read transaction */ in iproc_i2c_target_isr()
428 * Disable interrupt for TX FIFO becomes empty and in iproc_i2c_target_isr()
431 dd->target_int_mask &= ~BIT(IE_S_TX_UNDERRUN_SHIFT); in iproc_i2c_target_isr()
432 sys_write32(dd->target_int_mask, base + IE_OFFSET); in iproc_i2c_target_isr()
434 /* End of SMBUS for Master Read */ in iproc_i2c_target_isr()
446 target_cfg->callbacks->stop(target_cfg); in iproc_i2c_target_isr()
452 if (!dd->target_rx_only) { in iproc_i2c_target_isr()
464 if (dd->target_cfg) { in iproc_i2c_target_register()
466 return -EBUSY; in iproc_i2c_target_register()
470 dd->target_cfg = target_config; in iproc_i2c_target_register()
488 if (!dd->target_cfg) { in iproc_i2c_target_unregister()
489 return -EINVAL; in iproc_i2c_target_unregister()
500 dd->target_cfg = NULL; in iproc_i2c_target_unregister()
513 /* flush TX/RX FIFOs and set RX FIFO threshold to zero */ in iproc_i2c_common_init()
541 rc = -EAGAIN; in iproc_i2c_check_status()
546 rc = -ENXIO; in iproc_i2c_check_status()
551 rc = -ENXIO; in iproc_i2c_check_status()
556 rc = -ETIMEDOUT; in iproc_i2c_check_status()
560 LOG_ERR("FIFO Under-run"); in iproc_i2c_check_status()
561 rc = -ENXIO; in iproc_i2c_check_status()
565 LOG_ERR("RX FIFO full"); in iproc_i2c_check_status()
566 rc = -ETIMEDOUT; in iproc_i2c_check_status()
574 rc = -EIO; in iproc_i2c_check_status()
592 LOG_ERR("10-bit addressing not supported"); in iproc_i2c_configure()
593 return -ENOTSUP; in iproc_i2c_configure()
605 return -ENOTSUP; in iproc_i2c_configure()
615 struct i2c_msg *msg = dd->msg; in iproc_i2c_read_valid_bytes()
618 /* Read valid data from RX FIFO */ in iproc_i2c_read_valid_bytes()
619 while (dd->rx_bytes < msg->len) { in iproc_i2c_read_valid_bytes()
622 /* rx fifo empty */ in iproc_i2c_read_valid_bytes()
627 msg->buf[dd->rx_bytes] = (val >> M_RX_DATA_SHIFT) & M_RX_DATA_MASK; in iproc_i2c_read_valid_bytes()
628 dd->rx_bytes++; in iproc_i2c_read_valid_bytes()
636 struct i2c_msg *msg = dd->msg; in iproc_i2c_data_recv()
641 bytes_left = msg->len - dd->rx_bytes; in iproc_i2c_data_recv()
645 } else if (bytes_left < dd->thld_bytes) { in iproc_i2c_data_recv()
646 /* set bytes left as threshold */ in iproc_i2c_data_recv()
651 dd->thld_bytes = bytes_left; in iproc_i2c_data_recv()
654 * if bytes_left >= dd->thld_bytes, no need to change the THRESHOLD. in iproc_i2c_data_recv()
655 * It will remain as dd->thld_bytes itself in iproc_i2c_data_recv()
670 return -EBUSY; in iproc_i2c_transfer_one()
674 msg->flags, msg->len, msg->buf[0]); in iproc_i2c_transfer_one()
677 dd->msg = msg; in iproc_i2c_transfer_one()
679 addr = dev_addr << 1 | (msg->flags & I2C_MSG_READ ? 1 : 0); in iproc_i2c_transfer_one()
682 tx_bytes = MIN(msg->len, (TX_RX_FIFO_SIZE - 1)); in iproc_i2c_transfer_one()
683 if (!(msg->flags & I2C_MSG_READ)) { in iproc_i2c_transfer_one()
684 /* Fill master TX fifo */ in iproc_i2c_transfer_one()
686 val = msg->buf[i]; in iproc_i2c_transfer_one()
688 if (i == msg->len - 1) { in iproc_i2c_transfer_one()
694 dd->tx_bytes = tx_bytes; in iproc_i2c_transfer_one()
704 if (!(msg->flags & I2C_MSG_READ) && (msg->len > dd->tx_bytes)) { in iproc_i2c_transfer_one()
713 if (msg->len == 0) { in iproc_i2c_transfer_one()
714 /* SMBUS QUICK Command (Read/Write) */ in iproc_i2c_transfer_one()
716 } else if (msg->flags & I2C_MSG_READ) { in iproc_i2c_transfer_one()
719 dd->rx_bytes = 0; in iproc_i2c_transfer_one()
721 /* SMBUS Block Read Command */ in iproc_i2c_transfer_one()
723 val |= msg->len; in iproc_i2c_transfer_one()
725 if (msg->len > M_RX_FIFO_MAX_THLD_VALUE) { in iproc_i2c_transfer_one()
726 dd->thld_bytes = M_RX_FIFO_THLD_VALUE; in iproc_i2c_transfer_one()
728 dd->thld_bytes = msg->len; in iproc_i2c_transfer_one()
731 /* set threshold value */ in iproc_i2c_transfer_one()
734 tmp |= dd->thld_bytes << M_FIFO_RX_THLD_SHIFT; in iproc_i2c_transfer_one()
737 /* enable the RX threshold interrupt */ in iproc_i2c_transfer_one()
749 rc = k_sem_take(&dd->device_sync_sem, K_MSEC(I2C_TIMEOUT_MSEC)); in iproc_i2c_transfer_one()
774 return -EINVAL; in iproc_i2c_transfer_multi()
777 /* pre-check all msgs */ in iproc_i2c_transfer_multi()
779 if (!msgs_chk->buf) { in iproc_i2c_transfer_multi()
781 return -EINVAL; in iproc_i2c_transfer_multi()
784 if (I2C_MSG_ADDR_10_BITS & msgs_chk->flags) { in iproc_i2c_transfer_multi()
785 LOG_ERR("10-bit addressing not supported"); in iproc_i2c_transfer_multi()
786 return -ENOTSUP; in iproc_i2c_transfer_multi()
804 struct i2c_msg *msg = dd->msg; in iproc_i2c_send_data()
805 uint32_t tx_bytes = msg->len - dd->tx_bytes; in iproc_i2c_send_data()
807 /* can only fill up to the FIFO size */ in iproc_i2c_send_data()
811 uint32_t idx = dd->tx_bytes + i; in iproc_i2c_send_data()
813 uint32_t val = msg->buf[idx]; in iproc_i2c_send_data()
816 if (idx == (msg->len - 1)) { in iproc_i2c_send_data()
823 * disable TX FIFO underrun interrupt in iproc_i2c_send_data()
830 /* load data into TX FIFO */ in iproc_i2c_send_data()
835 dd->tx_bytes += tx_bytes; in iproc_i2c_send_data()
842 /* TX FIFO is empty and we have more data to send */ in iproc_i2c_master_isr()
847 /* RX FIFO threshold is reached and data needs to be read out */ in iproc_i2c_master_isr()
854 k_sem_give(&dd->device_sync_sem); in iproc_i2c_master_isr()
893 uint32_t bitrate = config->bitrate; in iproc_i2c_init()
896 k_sem_init(&dd->device_sync_sem, 0, 1); in iproc_i2c_init()
903 if (dd->target_cfg == NULL) { in iproc_i2c_init()
912 config->irq_config_func(dev); in iproc_i2c_init()