Lines Matching +full:pause +full:- +full:frame
4 * SPDX-License-Identifier: Apache-2.0
103 #define I3C_BUS_TLOW_PP_MIN_NS 24 /* T_LOW period in push-pull mode */
104 #define I3C_BUS_THigh_PP_MIN_NS 24 /* T_High period in push-pull mode */
105 #define I3C_BUS_TLOW_OD_MIN_NS 200 /* T_LOW period in open-drain mode */
107 #define PPBAUD_DIV_MAX (BIT(GET_FIELD_SZ(NPCX_I3C_MCONFIG_PPBAUD)) - 1) /* PPBAUD divider max */
163 uint8_t ppbaud; /* Push-Pull high period */
164 uint8_t pplow; /* Push-Pull low period */
165 uint8_t odhpp; /* Open-Drain high period */
166 uint8_t odbaud; /* Open-Drain low period */
259 struct npcx_i3c_data *const data = dev->data; in npcx_i3c_mutex_lock()
261 k_mutex_lock(&data->lock_mutex, K_FOREVER); in npcx_i3c_mutex_lock()
266 struct npcx_i3c_data *const data = dev->data; in npcx_i3c_mutex_unlock()
268 k_mutex_unlock(&data->lock_mutex); in npcx_i3c_mutex_unlock()
274 struct npcx_i3c_data *const data = dev->data; in i3c_ctrl_notify()
276 k_sem_give(&data->sync_sem); in i3c_ctrl_notify()
281 struct npcx_i3c_data *const data = dev->data; in i3c_ctrl_wait_completion()
283 return k_sem_take(&data->sync_sem, I3C_TRANS_TIMEOUT_MS); in i3c_ctrl_wait_completion()
288 struct npcx_i3c_data *const data = dev->data; in get_oper_state()
290 return data->oper_state; in get_oper_state()
296 struct npcx_i3c_data *const data = dev->data; in set_oper_state()
298 data->oper_state = state; in set_oper_state()
318 * -ETIMEDOUT: check status timeout.
322 if (WAIT_FOR(IS_BIT_SET(inst->MSTATUS, bit_offset), NPCX_I3C_CHK_TIMEOUT_US, NULL) == in npcx_i3c_status_wait_clear()
324 return -ETIMEDOUT; in npcx_i3c_status_wait_clear()
327 inst->MSTATUS = BIT(bit_offset); /* W1C */ in npcx_i3c_status_wait_clear()
334 return GET_FIELD(inst->MSTATUS, NPCX_I3C_MSTATUS_STATE); in npcx_i3c_state_get()
339 uint32_t intmask = inst->MINTSET; in npcx_i3c_interrupt_all_disable()
341 inst->MINTCLR = intmask; in npcx_i3c_interrupt_all_disable()
346 inst->MINTSET = mask; in npcx_i3c_interrupt_enable()
351 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_enable_target_interrupt()
352 struct i3c_reg *inst = config->base; in npcx_i3c_enable_target_interrupt()
355 inst->INTCLR = inst->INTSET; in npcx_i3c_enable_target_interrupt()
358 inst->STATUS = inst->STATUS; in npcx_i3c_enable_target_interrupt()
362 inst->INTSET = I3C_TGT_INTSET_MASK; in npcx_i3c_enable_target_interrupt()
363 inst->MINTSET |= BIT(NPCX_I3C_MINTSET_NOWCNTLR); /* I3C target is now controller */ in npcx_i3c_enable_target_interrupt()
367 inst->INTSET |= BIT(NPCX_I3C_INTSET_RXPEND); in npcx_i3c_enable_target_interrupt()
374 if (IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_ERRWARN)) { in npcx_i3c_has_error()
375 LOG_ERR("ERROR: MSTATUS 0x%08x MERRWARN 0x%08x", inst->MSTATUS, inst->MERRWARN); in npcx_i3c_has_error()
387 inst->MSTATUS = mask; in npcx_i3c_status_clear_all()
392 inst->MERRWARN = inst->MERRWARN; in npcx_i3c_errwarn_clear_all()
397 inst->MDATACTRL |= (BIT(NPCX_I3C_MDATACTRL_FLUSHTB) | BIT(NPCX_I3C_MDATACTRL_FLUSHFB)); in npcx_i3c_fifo_flush()
406 * -ETIMEDOUT check MCTRLDONE timeout.
407 * -ENOSYS invalid use of request.
411 inst->MCTRL = mctrl_val; in npcx_i3c_send_request()
414 return -ETIMEDOUT; in npcx_i3c_send_request()
418 if (IS_BIT_SET(inst->MERRWARN, NPCX_I3C_MERRWARN_INVERQ)) { in npcx_i3c_send_request()
419 LOG_ERR("%s: Invalid request, merrwarn: %#x", __func__, inst->MERRWARN); in npcx_i3c_send_request()
420 return -ENOSYS; in npcx_i3c_send_request()
473 * If op_tye is HDR-DDR, the read_sz must be the number of words.
512 if (IS_BIT_SET(inst->MERRWARN, NPCX_I3C_MERRWARN_NACK)) { in npcx_i3c_request_emit_start()
514 return -ENODEV; in npcx_i3c_request_emit_start()
528 * -ECANCELED i3c state not as expected.
529 * -ETIMEDOUT check MCTRLDONE timeout.
530 * -ENOSYS invalid use of request.
541 return -ECANCELED; in npcx_i3c_request_emit_stop()
565 return -EPERM; in npcx_i3c_request_hdr_exit()
592 case MSTATUS_STATE_MSGDDR: /* HDR-DDR */ in npcx_i3c_xfer_stop()
597 ret = -ENOTSUP; in npcx_i3c_xfer_stop()
653 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_device_find()
655 return i3c_dev_list_find(&config->common.dev_list, id); in npcx_i3c_device_find()
667 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_recover_bus()
668 struct i3c_reg *inst = config->base; in npcx_i3c_recover_bus()
680 while (IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_TGTSTART)) { in npcx_i3c_recover_bus()
681 inst->MSTATUS = BIT(NPCX_I3C_MSTATUS_TGTSTART); /* W1C */ in npcx_i3c_recover_bus()
686 if (WAIT_FOR(IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_COMPLETE), in npcx_i3c_recover_bus()
692 while (IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_RXPEND)) { in npcx_i3c_recover_bus()
699 * So pause a bit to let other targets initiates in npcx_i3c_recover_bus()
708 return -EBUSY; in npcx_i3c_recover_bus()
744 if (WAIT_FOR(!IS_BIT_SET(inst->MDATACTRL, NPCX_I3C_MDATACTRL_TXFULL), in npcx_i3c_xfer_write_fifo()
747 return -ETIMEDOUT; in npcx_i3c_xfer_write_fifo()
751 inst->MWDATAB = (uint32_t)buf[offset]; in npcx_i3c_xfer_write_fifo()
753 inst->MWDATABE = (uint32_t)buf[offset]; /* Set last byte */ in npcx_i3c_xfer_write_fifo()
757 remaining -= 1; in npcx_i3c_xfer_write_fifo()
783 if (IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_COMPLETE)) { in npcx_i3c_xfer_read_fifo()
790 if (IS_BIT_SET(inst->MERRWARN, NPCX_I3C_MERRWARN_TIMEOUT)) { in npcx_i3c_xfer_read_fifo()
794 inst->MERRWARN = inst->MERRWARN; in npcx_i3c_xfer_read_fifo()
796 return -EIO; in npcx_i3c_xfer_read_fifo()
800 if (IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_RXPEND)) { in npcx_i3c_xfer_read_fifo()
807 if (GET_FIELD(inst->MDATACTRL, NPCX_I3C_MDATACTRL_RXCOUNT) == 0) { in npcx_i3c_xfer_read_fifo()
811 buf[offset++] = (uint8_t)inst->MRDATAB; in npcx_i3c_xfer_read_fifo()
834 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_xfer_write_fifo_dma()
835 struct i3c_reg *i3c_inst = config->base; in npcx_i3c_xfer_write_fifo_dma()
836 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_xfer_write_fifo_dma()
841 /* Enable I3C MDMA write for one frame */ in npcx_i3c_xfer_write_fifo_dma()
842 SET_FIELD(i3c_inst->MDMACTRL, NPCX_I3C_MDMACTRL_DMATB, MDMA_DMATB_EN_ONE_FRAME); in npcx_i3c_xfer_write_fifo_dma()
843 i3c_inst->MINTSET |= BIT(NPCX_I3C_MINTCLR_COMPLETE); /* Enable I3C complete interrupt */ in npcx_i3c_xfer_write_fifo_dma()
846 mdma_inst->MDMA_TCNT1 = buf_sz; /* Set MDMA transfer count */ in npcx_i3c_xfer_write_fifo_dma()
847 mdma_inst->MDMA_SRCB1 = (uint32_t)buf; /* Set source address */ in npcx_i3c_xfer_write_fifo_dma()
848 mdma_inst->MDMA_CTL1 |= BIT(NPCX_MDMA_CTL_MDMAEN); /* Start DMA transfer */ in npcx_i3c_xfer_write_fifo_dma()
858 if (!IS_BIT_SET(mdma_inst->MDMA_CTL1, NPCX_MDMA_CTL_TC)) { in npcx_i3c_xfer_write_fifo_dma()
859 LOG_DBG("DMA busy, TC=%d", IS_BIT_SET(mdma_inst->MDMA_CTL1, NPCX_MDMA_CTL_TC)); in npcx_i3c_xfer_write_fifo_dma()
860 ret = -EBUSY; in npcx_i3c_xfer_write_fifo_dma()
864 mdma_inst->MDMA_CTL1 &= ~BIT(NPCX_MDMA_CTL_TC); /* Clear TC, W0C */ in npcx_i3c_xfer_write_fifo_dma()
865 ret = buf_sz - mdma_inst->MDMA_CTCNT1; /* Set transferred count */ in npcx_i3c_xfer_write_fifo_dma()
869 i3c_inst->MINTCLR |= BIT(NPCX_I3C_MINTCLR_COMPLETE); /* Disable I3C complete interrupt */ in npcx_i3c_xfer_write_fifo_dma()
880 * For read end, use the MDMA end-of-transfer interrupt(SIEN bit)
892 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_xfer_read_fifo_dma()
893 struct i3c_reg *i3c_inst = config->base; in npcx_i3c_xfer_read_fifo_dma()
894 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_xfer_read_fifo_dma()
900 SET_FIELD(i3c_inst->MDMACTRL, NPCX_I3C_MDMACTRL_DMAFB, MDMA_DMAFB_EN_MANUAL); in npcx_i3c_xfer_read_fifo_dma()
903 mdma_inst->MDMA_TCNT0 = buf_sz; /* Set MDMA transfer count */ in npcx_i3c_xfer_read_fifo_dma()
904 mdma_inst->MDMA_DSTB0 = (uint32_t)buf; /* Set destination address */ in npcx_i3c_xfer_read_fifo_dma()
905 mdma_inst->MDMA_CTL0 |= BIT(NPCX_MDMA_CTL_SIEN); /* Enable stop interrupt */ in npcx_i3c_xfer_read_fifo_dma()
906 mdma_inst->MDMA_CTL0 |= BIT(NPCX_MDMA_CTL_MDMAEN); /* Start DMA transfer */ in npcx_i3c_xfer_read_fifo_dma()
913 ret = buf_sz - mdma_inst->MDMA_CTCNT0; /* Set transferred count */ in npcx_i3c_xfer_read_fifo_dma()
917 mdma_inst->MDMA_CTL0 &= ~BIT(NPCX_MDMA_CTL_SIEN); /* Disable stop interrupt */ in npcx_i3c_xfer_read_fifo_dma()
919 SET_FIELD(i3c_inst->MDMACTRL, NPCX_I3C_MDMACTRL_DMAFB, MDMA_DMAFB_DISABLE); in npcx_i3c_xfer_read_fifo_dma()
928 * (Support SDR and HDR-DDR)
945 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_do_one_xfer_dma()
946 struct i3c_reg *inst = config->base; in npcx_i3c_do_one_xfer_dma()
954 /* Check HDR-DDR moves data by words */ in npcx_i3c_do_one_xfer_dma()
956 LOG_ERR("%s, HDR-DDR data length should be even, len=%#x", __func__, buf_sz); in npcx_i3c_do_one_xfer_dma()
957 return -EINVAL; in npcx_i3c_do_one_xfer_dma()
963 * For HDR-DDR mode read, RDTERM also includes one word (16 bits) for CRC. in npcx_i3c_do_one_xfer_dma()
965 * (1 word HDR-DDR command + 4 words data + 1 word for CRC) in npcx_i3c_do_one_xfer_dma()
977 /* Write the command code for the HDR-DDR message */ in npcx_i3c_do_one_xfer_dma()
978 inst->MWDATAB = hdr_cmd; in npcx_i3c_do_one_xfer_dma()
1007 ret = -EIO; in npcx_i3c_do_one_xfer_dma()
1077 if (WAIT_FOR(IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_COMPLETE), in npcx_i3c_do_one_xfer()
1081 ret = -ETIMEDOUT; in npcx_i3c_do_one_xfer()
1087 inst->MSTATUS = BIT(NPCX_I3C_MSTATUS_COMPLETE); /* W1C */ in npcx_i3c_do_one_xfer()
1092 ret = -EIO; in npcx_i3c_do_one_xfer()
1120 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_transfer()
1121 struct i3c_reg *inst = config->base; in npcx_i3c_transfer()
1122 struct npcx_i3c_data *data = dev->data; in npcx_i3c_transfer()
1131 return -EINVAL; in npcx_i3c_transfer()
1134 if (target->dynamic_addr == 0U) { in npcx_i3c_transfer()
1135 return -EINVAL; in npcx_i3c_transfer()
1145 return -ETIMEDOUT; in npcx_i3c_transfer()
1149 intmask = inst->MINTSET; in npcx_i3c_transfer()
1194 /* Current DMA not support multi-message write */ in npcx_i3c_transfer()
1196 LOG_ERR("I3C DMA transfer not support multi-message write"); in npcx_i3c_transfer()
1197 ret = -EINVAL; in npcx_i3c_transfer()
1205 /* Set emit start type SDR or HDR-DDR mode */ in npcx_i3c_transfer()
1231 } else if ((data->common.ctrl_config.supported_hdr & I3C_MSG_HDR_DDR) && in npcx_i3c_transfer()
1236 /* Check HDR-DDR moves data by words */ in npcx_i3c_transfer()
1238 LOG_ERR("HDR-DDR data length should be number of words , xfer " in npcx_i3c_transfer()
1241 ret = -EINVAL; in npcx_i3c_transfer()
1247 __func__, dev->name, data->common.ctrl_config.supported_hdr, in npcx_i3c_transfer()
1249 ret = -ENOTSUP; in npcx_i3c_transfer()
1255 xfered_len = npcx_i3c_do_one_xfer_dma(dev, target->dynamic_addr, op_type, in npcx_i3c_transfer()
1275 if ((i == num_msgs - 1) && (emit_stop == false)) { in npcx_i3c_transfer()
1301 * -EBUSY Bus is busy.
1302 * -EIO General input / output error.
1303 * -ENODEV If a provisioned ID does not match to any target devices
1305 * -ENOSPC No more free addresses can be assigned to target.
1306 * -ENOSYS Dynamic address assignment is not supported by
1311 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_do_daa()
1312 struct npcx_i3c_data *data = dev->data; in npcx_i3c_do_daa()
1313 struct i3c_reg *inst = config->base; in npcx_i3c_do_daa()
1328 return -ETIMEDOUT; in npcx_i3c_do_daa()
1334 intmask = inst->MINTSET; in npcx_i3c_do_daa()
1341 ret = -ETIMEDOUT; in npcx_i3c_do_daa()
1350 ret = -EIO; in npcx_i3c_do_daa()
1356 rx_count = GET_FIELD(inst->MDATACTRL, NPCX_I3C_MDATACTRL_RXCOUNT); in npcx_i3c_do_daa()
1360 rx_buf[i] = (uint8_t)inst->MRDATAB; in npcx_i3c_do_daa()
1364 ret = -EBADMSG; in npcx_i3c_do_daa()
1371 IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_BETWEEN)) { in npcx_i3c_do_daa()
1391 ret = i3c_dev_list_daa_addr_helper(&data->common.attached_dev.addr_slots, in npcx_i3c_do_daa()
1392 &config->common.dev_list, pid, false, in npcx_i3c_do_daa()
1402 dev->name, vendor_id, part_no, dyn_addr); in npcx_i3c_do_daa()
1405 target->dynamic_addr = dyn_addr; in npcx_i3c_do_daa()
1406 target->bcr = rx_buf[6]; in npcx_i3c_do_daa()
1407 target->dcr = rx_buf[7]; in npcx_i3c_do_daa()
1411 i3c_addr_slots_mark_i3c(&data->common.attached_dev.addr_slots, dyn_addr); in npcx_i3c_do_daa()
1419 if ((target != NULL) && (target->static_addr != 0U) && in npcx_i3c_do_daa()
1420 (dyn_addr != target->static_addr)) { in npcx_i3c_do_daa()
1421 i3c_addr_slots_mark_free(&data->common.attached_dev.addr_slots, in npcx_i3c_do_daa()
1426 inst->MWDATAB = dyn_addr; in npcx_i3c_do_daa()
1437 if (IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_NACKED)) { in npcx_i3c_do_daa()
1438 ret = -EFAULT; in npcx_i3c_do_daa()
1442 i3c_addr_slots_mark_free(&data->common.attached_dev.addr_slots, in npcx_i3c_do_daa()
1447 target->dynamic_addr = 0; in npcx_i3c_do_daa()
1455 } while ((!IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_COMPLETE)) && in npcx_i3c_do_daa()
1468 /* Re-Enable I3C IRQ sources. */ in npcx_i3c_do_daa()
1485 * -EBUSY Bus is busy.
1486 * -EIO General Input / output error.
1487 * -EINVAL Invalid valid set in the payload structure.
1488 * -ENOSYS Not implemented.
1492 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_do_ccc()
1494 struct i3c_reg *inst = config->base; in npcx_i3c_do_ccc()
1499 return -EINVAL; in npcx_i3c_do_ccc()
1505 intmask = inst->MINTSET; in npcx_i3c_do_ccc()
1511 LOG_DBG("CCC[0x%02x]", payload->ccc.id); in npcx_i3c_do_ccc()
1517 LOG_ERR("CCC[0x%02x] %s START error (%d)", payload->ccc.id, in npcx_i3c_do_ccc()
1526 xfered_len = npcx_i3c_xfer_write_fifo(inst, &payload->ccc.id, 1, payload->ccc.data_len > 0); in npcx_i3c_do_ccc()
1528 LOG_ERR("CCC[0x%02x] %s command error (%d)", payload->ccc.id, in npcx_i3c_do_ccc()
1536 if (payload->ccc.data_len > 0) { in npcx_i3c_do_ccc()
1539 xfered_len = npcx_i3c_xfer_write_fifo(inst, payload->ccc.data, in npcx_i3c_do_ccc()
1540 payload->ccc.data_len, false); in npcx_i3c_do_ccc()
1542 LOG_ERR("CCC[0x%02x] %s command payload error (%d)", payload->ccc.id, in npcx_i3c_do_ccc()
1551 payload->ccc.num_xfer = xfered_len; in npcx_i3c_do_ccc()
1555 if (WAIT_FOR(IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_COMPLETE), NPCX_I3C_CHK_TIMEOUT_US, in npcx_i3c_do_ccc()
1557 ret = -ETIMEDOUT; in npcx_i3c_do_ccc()
1562 inst->MSTATUS = BIT(NPCX_I3C_MSTATUS_COMPLETE); /* W1C */ in npcx_i3c_do_ccc()
1570 for (int idx = 0; idx < payload->targets.num_targets; idx++) { in npcx_i3c_do_ccc()
1572 &payload->targets.payloads[idx]; in npcx_i3c_do_ccc()
1574 bool is_read = (tgt_payload->rnw == 1U); in npcx_i3c_do_ccc()
1577 inst, tgt_payload->addr, NPCX_I3C_MCTRL_TYPE_I3C, tgt_payload->data, in npcx_i3c_do_ccc()
1578 tgt_payload->data_len, is_read, true, false, false); in npcx_i3c_do_ccc()
1580 LOG_ERR("CCC[0x%02x] target payload error (%d)", payload->ccc.id, in npcx_i3c_do_ccc()
1588 tgt_payload->num_xfer = xfered_len; in npcx_i3c_do_ccc()
1614 const struct device *dev = i3c_ibi_work->controller; in npcx_i3c_ibi_work()
1615 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_ibi_work()
1616 struct npcx_i3c_data *data = dev->data; in npcx_i3c_ibi_work()
1617 struct i3c_reg *inst = config->base; in npcx_i3c_ibi_work()
1622 k_sem_take(&data->ibi_lock_sem, K_FOREVER); in npcx_i3c_ibi_work()
1628 LOG_ERR("%s: MSTATUS 0x%08x MERRWARN 0x%08x", __func__, inst->MSTATUS, in npcx_i3c_ibi_work()
1629 inst->MERRWARN); in npcx_i3c_ibi_work()
1639 if (WAIT_FOR(IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_IBIWON), NPCX_I3C_CHK_TIMEOUT_US, in npcx_i3c_ibi_work()
1642 LOG_ERR("%s: MSTATUS 0x%08x MERRWARN 0x%08x", __func__, inst->MSTATUS, in npcx_i3c_ibi_work()
1643 inst->MERRWARN); in npcx_i3c_ibi_work()
1649 ibitype = GET_FIELD(inst->MSTATUS, NPCX_I3C_MSTATUS_IBITYPE); in npcx_i3c_ibi_work()
1650 ibiaddr = GET_FIELD(inst->MSTATUS, NPCX_I3C_MSTATUS_IBIADDR); in npcx_i3c_ibi_work()
1718 k_sem_give(&data->ibi_lock_sem); in npcx_i3c_ibi_work()
1720 /* Re-enable target initiated IBI interrupt. */ in npcx_i3c_ibi_work()
1721 inst->MINTSET = BIT(NPCX_I3C_MINTSET_TGTSTART); in npcx_i3c_ibi_work()
1732 for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) { in npcx_i3c_ibi_rules_setup()
1735 /* Extract the lower 6-bit of target address */ in npcx_i3c_ibi_rules_setup()
1736 addr_6bit = (uint32_t)data->ibi.addr[idx] & IBIRULES_ADDR_MSK; in npcx_i3c_ibi_rules_setup()
1745 if (!data->ibi.msb) { in npcx_i3c_ibi_rules_setup()
1750 if (!data->ibi.has_mandatory_byte) { in npcx_i3c_ibi_rules_setup()
1756 inst->IBIRULES = ibi_rules; in npcx_i3c_ibi_rules_setup()
1763 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_ibi_enable()
1764 struct npcx_i3c_data *data = dev->data; in npcx_i3c_ibi_enable()
1765 struct i3c_reg *inst = config->base; in npcx_i3c_ibi_enable()
1774 return -EINVAL; in npcx_i3c_ibi_enable()
1777 if (data->ibi.num_addr >= ARRAY_SIZE(data->ibi.addr)) { in npcx_i3c_ibi_enable()
1780 return -ENOMEM; in npcx_i3c_ibi_enable()
1784 for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) { in npcx_i3c_ibi_enable()
1785 if (data->ibi.addr[idx] == target->dynamic_addr) { in npcx_i3c_ibi_enable()
1787 return -EINVAL; in npcx_i3c_ibi_enable()
1792 inst->MINTCLR = BIT(NPCX_I3C_MINTCLR_TGTSTART); in npcx_i3c_ibi_enable()
1794 LOG_DBG("IBI enabling for 0x%02x (BCR 0x%02x)", target->dynamic_addr, target->bcr); in npcx_i3c_ibi_enable()
1796 msb = (target->dynamic_addr & BIT(6)) == BIT(6); /* Check addess(7-bit) MSB enable */ in npcx_i3c_ibi_enable()
1806 if (data->ibi.num_addr > 0) { in npcx_i3c_ibi_enable()
1811 * 2. Each address in entry only captures the lowest 6-bit. in npcx_i3c_ibi_enable()
1815 if ((has_mandatory_byte != data->ibi.has_mandatory_byte) || in npcx_i3c_ibi_enable()
1816 (msb != data->ibi.msb)) { in npcx_i3c_ibi_enable()
1817 ret = -EINVAL; in npcx_i3c_ibi_enable()
1825 for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) { in npcx_i3c_ibi_enable()
1826 if (data->ibi.addr[idx] == 0U) { in npcx_i3c_ibi_enable()
1831 if (idx >= ARRAY_SIZE(data->ibi.addr)) { in npcx_i3c_ibi_enable()
1832 ret = -ENOTSUP; in npcx_i3c_ibi_enable()
1841 data->ibi.has_mandatory_byte = has_mandatory_byte; in npcx_i3c_ibi_enable()
1842 data->ibi.msb = msb; in npcx_i3c_ibi_enable()
1847 data->ibi.addr[idx] = target->dynamic_addr; in npcx_i3c_ibi_enable()
1848 data->ibi.num_addr += 1U; in npcx_i3c_ibi_enable()
1856 LOG_ERR("Error sending IBI ENEC for 0x%02x (%d)", target->dynamic_addr, ret); in npcx_i3c_ibi_enable()
1860 if (data->ibi.num_addr > 0U) { in npcx_i3c_ibi_enable()
1866 inst->MINTSET = BIT(NPCX_I3C_MINTSET_TGTSTART); in npcx_i3c_ibi_enable()
1874 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_ibi_disable()
1875 struct npcx_i3c_data *data = dev->data; in npcx_i3c_ibi_disable()
1876 struct i3c_reg *inst = config->base; in npcx_i3c_ibi_disable()
1883 return -EINVAL; in npcx_i3c_ibi_disable()
1886 for (idx = 0; idx < ARRAY_SIZE(data->ibi.addr); idx++) { in npcx_i3c_ibi_disable()
1887 if (target->dynamic_addr == data->ibi.addr[idx]) { in npcx_i3c_ibi_disable()
1892 if (idx == ARRAY_SIZE(data->ibi.addr)) { in npcx_i3c_ibi_disable()
1894 return -ENODEV; in npcx_i3c_ibi_disable()
1898 inst->MINTCLR = BIT(NPCX_I3C_MINTCLR_TGTSTART); in npcx_i3c_ibi_disable()
1901 data->ibi.addr[idx] = 0U; in npcx_i3c_ibi_disable()
1902 data->ibi.num_addr -= 1U; in npcx_i3c_ibi_disable()
1908 LOG_ERR("Error sending IBI DISEC for 0x%02x (%d)", target->dynamic_addr, ret); in npcx_i3c_ibi_disable()
1913 if (data->ibi.num_addr > 0U) { in npcx_i3c_ibi_disable()
1918 inst->MINTSET = BIT(NPCX_I3C_MINTSET_TGTSTART); in npcx_i3c_ibi_disable()
1927 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_ibi_raise()
1928 struct i3c_reg *inst = config->base; in npcx_i3c_target_ibi_raise()
1929 struct npcx_i3c_data *data = dev->data; in npcx_i3c_target_ibi_raise()
1933 if ((request == NULL) || ((request->payload_len) && (request->payload == NULL))) { in npcx_i3c_target_ibi_raise()
1934 return -EINVAL; in npcx_i3c_target_ibi_raise()
1938 if (!IS_BIT_SET(inst->CONFIG, NPCX_I3C_CONFIG_TGTENA) || in npcx_i3c_target_ibi_raise()
1939 IS_BIT_SET(inst->STATUS, NPCX_I3C_STATUS_STHDR)) { in npcx_i3c_target_ibi_raise()
1940 return -EINVAL; in npcx_i3c_target_ibi_raise()
1943 switch (request->ibi_type) { in npcx_i3c_target_ibi_raise()
1945 if (IS_BIT_SET(inst->STATUS, NPCX_I3C_STATUS_IBIDIS)) { in npcx_i3c_target_ibi_raise()
1946 return -ENOTSUP; in npcx_i3c_target_ibi_raise()
1949 if (request->payload_len == 0) { in npcx_i3c_target_ibi_raise()
1951 request->payload_len); in npcx_i3c_target_ibi_raise()
1952 return -EINVAL; in npcx_i3c_target_ibi_raise()
1955 k_sem_take(&data->target_event_lock_sem, K_FOREVER); in npcx_i3c_target_ibi_raise()
1959 SET_FIELD(inst->CTRL, NPCX_I3C_CTRL_IBIDATA, request->payload[0]); in npcx_i3c_target_ibi_raise()
1962 if (request->payload_len > 1) { in npcx_i3c_target_ibi_raise()
1963 if (request->payload_len <= 32) { in npcx_i3c_target_ibi_raise()
1964 for (index = 1; index < (request->payload_len - 1); index++) { in npcx_i3c_target_ibi_raise()
1965 inst->WDATAB = request->payload[index]; in npcx_i3c_target_ibi_raise()
1968 inst->WDATABE = request->payload[index]; in npcx_i3c_target_ibi_raise()
1973 SET_FIELD(inst->IBIEXT1, NPCX_I3C_IBIEXT1_CNT, 0); in npcx_i3c_target_ibi_raise()
1974 inst->CTRL |= BIT(NPCX_I3C_CTRL_EXTDATA); in npcx_i3c_target_ibi_raise()
1977 SET_FIELD(inst->CTRL, NPCX_I3C_CTRL_EVENT, CTRL_EVENT_IBI); in npcx_i3c_target_ibi_raise()
1981 if (IS_BIT_SET(inst->STATUS, NPCX_I3C_STATUS_MRDIS)) { in npcx_i3c_target_ibi_raise()
1982 return -ENOTSUP; in npcx_i3c_target_ibi_raise()
1988 if (GET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_CTRENA) != MCONFIG_CTRENA_CAPABLE) { in npcx_i3c_target_ibi_raise()
1989 return -ENOTSUP; in npcx_i3c_target_ibi_raise()
1992 k_sem_take(&data->target_event_lock_sem, K_FOREVER); in npcx_i3c_target_ibi_raise()
1995 SET_FIELD(inst->CTRL, NPCX_I3C_CTRL_EVENT, CTRL_EVENT_CNTLR_REQ); in npcx_i3c_target_ibi_raise()
1999 if (IS_BIT_SET(inst->STATUS, NPCX_I3C_STATUS_HJDIS)) { in npcx_i3c_target_ibi_raise()
2000 return -ENOTSUP; in npcx_i3c_target_ibi_raise()
2003 k_sem_take(&data->target_event_lock_sem, K_FOREVER); in npcx_i3c_target_ibi_raise()
2006 inst->CONFIG &= ~BIT(NPCX_I3C_CONFIG_TGTENA); in npcx_i3c_target_ibi_raise()
2007 SET_FIELD(inst->CTRL, NPCX_I3C_CTRL_EVENT, CTRL_EVENT_HJ); in npcx_i3c_target_ibi_raise()
2008 inst->CONFIG |= BIT(NPCX_I3C_CONFIG_TGTENA); in npcx_i3c_target_ibi_raise()
2012 return -EINVAL; in npcx_i3c_target_ibi_raise()
2021 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_get_mdmafb_count()
2022 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_target_get_mdmafb_count()
2024 if (mdma_inst->MDMA_CTCNT0 < mdma_inst->MDMA_TCNT0) { in npcx_i3c_target_get_mdmafb_count()
2025 return (mdma_inst->MDMA_TCNT0 - mdma_inst->MDMA_CTCNT0); in npcx_i3c_target_get_mdmafb_count()
2033 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_get_mdmatb_count()
2034 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_target_get_mdmatb_count()
2036 if (mdma_inst->MDMA_CTCNT1 < mdma_inst->MDMA_TCNT1) { in npcx_i3c_target_get_mdmatb_count()
2037 return (mdma_inst->MDMA_TCNT1 - mdma_inst->MDMA_CTCNT1); in npcx_i3c_target_get_mdmatb_count()
2045 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_disable_mdmafb()
2046 struct i3c_reg *i3c_inst = config->base; in npcx_i3c_target_disable_mdmafb()
2047 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_target_disable_mdmafb()
2049 mdma_inst->MDMA_CTL0 &= ~BIT(NPCX_MDMA_CTL_MDMAEN); in npcx_i3c_target_disable_mdmafb()
2050 mdma_inst->MDMA_CTL0 &= ~BIT(NPCX_MDMA_CTL_TC); /* W0C */ in npcx_i3c_target_disable_mdmafb()
2051 mdma_inst->MDMA_CTL0 &= ~BIT(NPCX_MDMA_CTL_SIEN); in npcx_i3c_target_disable_mdmafb()
2052 SET_FIELD(i3c_inst->DMACTRL, NPCX_I3C_DMACTRL_DMAFB, MDMA_DMAFB_DISABLE); in npcx_i3c_target_disable_mdmafb()
2055 i3c_inst->CONFIG &= ~BIT(NPCX_I3C_CONFIG_MATCHSS); in npcx_i3c_target_disable_mdmafb()
2058 i3c_inst->DATACTRL |= BIT(NPCX_I3C_DATACTRL_FLUSHTB) | BIT(NPCX_I3C_DATACTRL_FLUSHFB); in npcx_i3c_target_disable_mdmafb()
2063 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_enable_mdmafb()
2064 struct i3c_reg *i3c_inst = config->base; in npcx_i3c_target_enable_mdmafb()
2065 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_target_enable_mdmafb()
2068 if (IS_BIT_SET(mdma_inst->MDMA_CTL0, NPCX_MDMA_CTL_MDMAEN) != 0) { in npcx_i3c_target_enable_mdmafb()
2069 mdma_inst->MDMA_CTL0 &= ~BIT(NPCX_MDMA_CTL_MDMAEN); in npcx_i3c_target_enable_mdmafb()
2076 i3c_inst->CONFIG |= BIT(NPCX_I3C_CONFIG_MATCHSS); in npcx_i3c_target_enable_mdmafb()
2078 SET_FIELD(i3c_inst->DMACTRL, NPCX_I3C_DMACTRL_DMAFB, MDMA_DMAFB_EN_MANUAL); in npcx_i3c_target_enable_mdmafb()
2081 mdma_inst->MDMA_TCNT0 = len; /* Set MDMA transfer count */ in npcx_i3c_target_enable_mdmafb()
2082 mdma_inst->MDMA_DSTB0 = (uint32_t)buf; /* Set destination address */ in npcx_i3c_target_enable_mdmafb()
2083 mdma_inst->MDMA_CTL0 &= ~BIT(NPCX_MDMA_CTL_TC); /* W0C */ in npcx_i3c_target_enable_mdmafb()
2084 mdma_inst->MDMA_CTL0 |= BIT(NPCX_MDMA_CTL_SIEN); /* Enable stop interrupt */ in npcx_i3c_target_enable_mdmafb()
2085 mdma_inst->MDMA_CTL0 |= BIT(NPCX_MDMA_CTL_MDMAEN); /* Start DMA transfer */ in npcx_i3c_target_enable_mdmafb()
2090 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_disable_mdmatb()
2091 struct i3c_reg *i3c_inst = config->base; in npcx_i3c_target_disable_mdmatb()
2092 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_target_disable_mdmatb()
2094 mdma_inst->MDMA_CTL1 &= ~BIT(NPCX_MDMA_CTL_MDMAEN); in npcx_i3c_target_disable_mdmatb()
2095 mdma_inst->MDMA_CTL1 &= ~BIT(NPCX_MDMA_CTL_TC); /* W0C */ in npcx_i3c_target_disable_mdmatb()
2096 mdma_inst->MDMA_CTL1 &= ~BIT(NPCX_MDMA_CTL_SIEN); in npcx_i3c_target_disable_mdmatb()
2097 SET_FIELD(i3c_inst->DMACTRL, NPCX_I3C_DMACTRL_DMATB, MDMA_DMATB_DISABLE); in npcx_i3c_target_disable_mdmatb()
2100 i3c_inst->CONFIG &= ~BIT(NPCX_I3C_CONFIG_MATCHSS); in npcx_i3c_target_disable_mdmatb()
2103 i3c_inst->DATACTRL |= BIT(NPCX_I3C_DATACTRL_FLUSHTB) | BIT(NPCX_I3C_DATACTRL_FLUSHFB); in npcx_i3c_target_disable_mdmatb()
2108 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_enable_mdmatb()
2109 struct i3c_reg *i3c_inst = config->base; in npcx_i3c_target_enable_mdmatb()
2110 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_target_enable_mdmatb()
2113 if (IS_BIT_SET(mdma_inst->MDMA_CTL1, NPCX_MDMA_CTL_MDMAEN) != 0) { in npcx_i3c_target_enable_mdmatb()
2114 mdma_inst->MDMA_CTL1 &= ~BIT(NPCX_MDMA_CTL_MDMAEN); in npcx_i3c_target_enable_mdmatb()
2119 i3c_inst->CONFIG |= BIT(NPCX_I3C_CONFIG_MATCHSS); in npcx_i3c_target_enable_mdmatb()
2121 /* Enable DMA only for one frame. in npcx_i3c_target_enable_mdmatb()
2127 * In HDR-DDR mode, DMATB is not automatically cleared. in npcx_i3c_target_enable_mdmatb()
2129 SET_FIELD(i3c_inst->DMACTRL, NPCX_I3C_DMACTRL_DMATB, MDMA_DMAFB_EN_ONE_FRAME); in npcx_i3c_target_enable_mdmatb()
2132 mdma_inst->MDMA_TCNT1 = len; /* Set MDMA transfer count */ in npcx_i3c_target_enable_mdmatb()
2133 mdma_inst->MDMA_SRCB1 = (uint32_t)buf; /* Set source address */ in npcx_i3c_target_enable_mdmatb()
2134 mdma_inst->MDMA_CTL1 &= ~BIT(NPCX_MDMA_CTL_TC); /* W0C */ in npcx_i3c_target_enable_mdmatb()
2135 mdma_inst->MDMA_CTL1 |= BIT(NPCX_MDMA_CTL_MDMAEN); /* Start DMA transfer */ in npcx_i3c_target_enable_mdmatb()
2140 struct npcx_i3c_data *data = dev->data; in npcx_i3c_target_rx_read()
2141 struct i3c_config_target *config_tgt = &data->config_target; in npcx_i3c_target_rx_read()
2144 npcx_i3c_target_enable_mdmafb(dev, data->mdma_rx_buf, config_tgt->max_read_len); in npcx_i3c_target_rx_read()
2149 * return: -EINVAL:
2152 * -EBUSY: in write request, wait for mdma done.
2157 struct npcx_i3c_data *data = dev->data; in npcx_i3c_target_xfer_end_handle()
2158 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_xfer_end_handle()
2159 struct i3c_reg *inst = config->base; in npcx_i3c_target_xfer_end_handle()
2160 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_target_xfer_end_handle()
2161 const struct i3c_target_callbacks *target_cb = data->target_config->callbacks; in npcx_i3c_target_xfer_end_handle()
2162 bool is_i3c_start = IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_START); in npcx_i3c_target_xfer_end_handle()
2163 bool is_i3c_stop = IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_STOP); in npcx_i3c_target_xfer_end_handle()
2171 return -EINVAL; in npcx_i3c_target_xfer_end_handle()
2177 return -EINVAL; in npcx_i3c_target_xfer_end_handle()
2188 if (WAIT_FOR((GET_FIELD(inst->DATACTRL, NPCX_I3C_DATACTRL_RXCOUNT) == 0), in npcx_i3c_target_xfer_end_handle()
2191 GET_FIELD(inst->DATACTRL, NPCX_I3C_DATACTRL_RXCOUNT)); in npcx_i3c_target_xfer_end_handle()
2192 ret = -EIO; in npcx_i3c_target_xfer_end_handle()
2198 cur_xfer_cnt = mdma_inst->MDMA_CTCNT0; in npcx_i3c_target_xfer_end_handle()
2203 if (cur_xfer_cnt != mdma_inst->MDMA_CTCNT0) { in npcx_i3c_target_xfer_end_handle()
2210 cur_xfer_cnt = mdma_inst->MDMA_CTCNT0; in npcx_i3c_target_xfer_end_handle()
2215 if (cur_xfer_cnt == mdma_inst->MDMA_CTCNT0) { in npcx_i3c_target_xfer_end_handle()
2217 if (target_cb && target_cb->buf_write_received_cb) { in npcx_i3c_target_xfer_end_handle()
2218 target_cb->buf_write_received_cb(data->target_config, data->mdma_rx_buf, in npcx_i3c_target_xfer_end_handle()
2225 ret = -EBUSY; in npcx_i3c_target_xfer_end_handle()
2229 /* Clear DA matched status and re-enable interrupt */ in npcx_i3c_target_xfer_end_handle()
2230 inst->STATUS = BIT(NPCX_I3C_STATUS_MATCHED); in npcx_i3c_target_xfer_end_handle()
2231 inst->INTSET = BIT(NPCX_I3C_INTSET_MATCHED); in npcx_i3c_target_xfer_end_handle()
2246 return -EINVAL; in npcx_i3c_target_tx_write()
2251 return -ENOSYS; in npcx_i3c_target_tx_write()
2260 return -ENOSYS; in npcx_i3c_target_tx_write()
2266 struct npcx_i3c_data *data = dev->data; in npcx_i3c_target_register()
2268 data->target_config = cfg; in npcx_i3c_target_register()
2275 struct npcx_i3c_data *data = dev->data; in npcx_i3c_target_unregister()
2277 data->target_config = NULL; in npcx_i3c_target_unregister()
2291 return -EINVAL; in npcx_i3c_get_scl_config()
2298 return -EINVAL; in npcx_i3c_get_scl_config()
2313 return -EINVAL; in npcx_i3c_get_scl_config()
2316 ppbaud = i3c_div - 1UL; in npcx_i3c_get_scl_config()
2323 return -EINVAL; in npcx_i3c_get_scl_config()
2334 odbaud = i3c_div - 2UL; in npcx_i3c_get_scl_config()
2341 return -EINVAL; in npcx_i3c_get_scl_config()
2344 cfg->pplow = 0; in npcx_i3c_get_scl_config()
2345 cfg->odhpp = 1; in npcx_i3c_get_scl_config()
2346 cfg->ppbaud = ppbaud; in npcx_i3c_get_scl_config()
2347 cfg->odbaud = odbaud; in npcx_i3c_get_scl_config()
2354 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_freq_init()
2355 struct npcx_i3c_data *data = dev->data; in npcx_i3c_freq_init()
2356 struct i3c_reg *inst = config->base; in npcx_i3c_freq_init()
2357 const struct device *const clk_dev = config->clock_dev; in npcx_i3c_freq_init()
2358 struct i3c_config_controller *ctrl_config = &data->common.ctrl_config; in npcx_i3c_freq_init()
2359 uint32_t scl_pp = ctrl_config->scl.i3c; in npcx_i3c_freq_init()
2360 uint32_t scl_od = config->clocks.i3c_od_scl_hz; in npcx_i3c_freq_init()
2365 ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t)&config->clock_subsys, in npcx_i3c_freq_init()
2369 return -EINVAL; in npcx_i3c_freq_init()
2377 LOG_DBG("hdr: %d", ctrl_config->supported_hdr); in npcx_i3c_freq_init()
2395 LOG_ERR("Unsupported MCLKD freq for %s.", dev->name); in npcx_i3c_freq_init()
2396 return -EINVAL; in npcx_i3c_freq_init()
2402 return -EINVAL; in npcx_i3c_freq_init()
2406 SET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_PPBAUD, timing_cfg.ppbaud); in npcx_i3c_freq_init()
2407 SET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_PPLOW, timing_cfg.pplow); in npcx_i3c_freq_init()
2408 SET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_ODBAUD, timing_cfg.odbaud); in npcx_i3c_freq_init()
2410 inst->MCONFIG |= BIT(NPCX_I3C_MCONFIG_ODHPP); in npcx_i3c_freq_init()
2412 inst->MCONFIG &= ~BIT(NPCX_I3C_MCONFIG_ODHPP); in npcx_i3c_freq_init()
2414 SET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_I2CBAUD, I3C_BUS_I2C_BAUD_RATE_FAST_MODE); in npcx_i3c_freq_init()
2416 LOG_DBG("ppbaud: %d", GET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_PPBAUD)); in npcx_i3c_freq_init()
2417 LOG_DBG("odbaud: %d", GET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_ODBAUD)); in npcx_i3c_freq_init()
2418 LOG_DBG("pplow: %d", GET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_PPLOW)); in npcx_i3c_freq_init()
2419 LOG_DBG("odhpp: %d", IS_BIT_SET(inst->MCONFIG, NPCX_I3C_MCONFIG_ODHPP)); in npcx_i3c_freq_init()
2420 LOG_DBG("i2cbaud: %d", GET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_I2CBAUD)); in npcx_i3c_freq_init()
2427 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_apply_cntlr_config()
2428 struct i3c_reg *inst = config->base; in npcx_i3c_apply_cntlr_config()
2429 const struct device *const clk_dev = config->clock_dev; in npcx_i3c_apply_cntlr_config()
2430 int idx_module = GET_MODULE_ID(config->instance_id); in npcx_i3c_apply_cntlr_config()
2443 return -EINVAL; in npcx_i3c_apply_cntlr_config()
2446 /* Enable external high-keeper */ in npcx_i3c_apply_cntlr_config()
2447 SET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_HKEEP, MCONFIG_HKEEP_EXT_SDA_SCL); in npcx_i3c_apply_cntlr_config()
2448 /* Enable open-drain stop */ in npcx_i3c_apply_cntlr_config()
2449 inst->MCONFIG |= BIT(NPCX_I3C_MCONFIG_ODSTOP); in npcx_i3c_apply_cntlr_config()
2451 inst->MCONFIG &= ~BIT(NPCX_I3C_MCONFIG_DISTO); in npcx_i3c_apply_cntlr_config()
2456 ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t)&config->ref_clk_subsys, in npcx_i3c_apply_cntlr_config()
2462 return -EINVAL; in npcx_i3c_apply_cntlr_config()
2468 SET_FIELD(inst->CONFIG, NPCX_I3C_CONFIG_BAMATCH, bamatch); in npcx_i3c_apply_cntlr_config()
2475 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_apply_target_config()
2476 struct npcx_i3c_data *data = dev->data; in npcx_i3c_apply_target_config()
2477 struct i3c_config_target *config_target = &data->config_target; in npcx_i3c_apply_target_config()
2478 struct i3c_reg *inst = config->base; in npcx_i3c_apply_target_config()
2479 const struct device *const clk_dev = config->clock_dev; in npcx_i3c_apply_target_config()
2482 int idx_module = GET_MODULE_ID(config->instance_id); in npcx_i3c_apply_target_config()
2490 ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t)&config->ref_clk_subsys, in npcx_i3c_apply_target_config()
2496 return -EINVAL; in npcx_i3c_apply_target_config()
2501 SET_FIELD(inst->CONFIG, NPCX_I3C_CONFIG_BAMATCH, bamatch); in npcx_i3c_apply_target_config()
2504 pid = config_target->pid; in npcx_i3c_apply_target_config()
2507 SET_FIELD(inst->VENDORID, NPCX_I3C_VENDORID_VID, (uint32_t)GET_PID_VENDOR_ID(pid)); in npcx_i3c_apply_target_config()
2510 if (config_target->pid_random) { in npcx_i3c_apply_target_config()
2511 inst->CONFIG |= BIT(NPCX_I3C_CONFIG_IDRAND); in npcx_i3c_apply_target_config()
2513 inst->CONFIG &= ~BIT(NPCX_I3C_CONFIG_IDRAND); in npcx_i3c_apply_target_config()
2517 inst->PARTNO = (uint32_t)GET_PID_PARTNO(pid); in npcx_i3c_apply_target_config()
2524 SET_FIELD(inst->IDEXT, NPCX_I3C_IDEXT_DCR, config_target->dcr); in npcx_i3c_apply_target_config()
2525 SET_FIELD(inst->IDEXT, NPCX_I3C_IDEXT_BCR, config_target->bcr); in npcx_i3c_apply_target_config()
2526 SET_FIELD(inst->CONFIG, NPCX_I3C_CONFIG_SADDR, config_target->static_addr); in npcx_i3c_apply_target_config()
2527 SET_FIELD(inst->CONFIG, NPCX_I3C_CONFIG_HDRCMD, CFG_HDRCMD_RD_FROM_FIFIO); in npcx_i3c_apply_target_config()
2528 SET_FIELD(inst->MAXLIMITS, NPCX_I3C_MAXLIMITS_MAXRD, (config_target->max_read_len) & 0xfff); in npcx_i3c_apply_target_config()
2529 SET_FIELD(inst->MAXLIMITS, NPCX_I3C_MAXLIMITS_MAXWR, in npcx_i3c_apply_target_config()
2530 (config_target->max_write_len) & 0xfff); in npcx_i3c_apply_target_config()
2533 inst->CONFIG &= ~BIT(NPCX_I3C_CONFIG_MATCHSS); in npcx_i3c_apply_target_config()
2543 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_dev_init()
2544 struct npcx_i3c_data *data = dev->data; in npcx_i3c_dev_init()
2545 struct i3c_reg *inst = config->base; in npcx_i3c_dev_init()
2546 struct i3c_config_controller *config_cntlr = &data->common.ctrl_config; in npcx_i3c_dev_init()
2547 struct i3c_config_target *config_target = &data->config_target; in npcx_i3c_dev_init()
2548 int idx_module = GET_MODULE_ID(config->instance_id); in npcx_i3c_dev_init()
2551 reset_line_toggle_dt(&config->reset); in npcx_i3c_dev_init()
2553 if (I3C_BCR_DEVICE_ROLE(config_target->bcr) == I3C_BCR_DEVICE_ROLE_I3C_CONTROLLER_CAPABLE) { in npcx_i3c_dev_init()
2557 if (config_cntlr->is_secondary) { in npcx_i3c_dev_init()
2559 SET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_CTRENA, MCONFIG_CTRENA_CAPABLE); in npcx_i3c_dev_init()
2560 inst->CONFIG |= BIT(NPCX_I3C_CONFIG_TGTENA); /* Target mode enable */ in npcx_i3c_dev_init()
2564 SET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_CTRENA, MCONFIG_CTRENA_ON); in npcx_i3c_dev_init()
2568 SET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_CTRENA, in npcx_i3c_dev_init()
2570 inst->CONFIG |= BIT(NPCX_I3C_CONFIG_TGTENA); /* Target mode enable */ in npcx_i3c_dev_init()
2576 struct npcx_i3c_data *dev_data = dev->data; in npcx_i3c_configure()
2582 return -EINVAL; in npcx_i3c_configure()
2591 if (config_cntlr->scl.i3c == 0U) { in npcx_i3c_configure()
2593 return -EINVAL; in npcx_i3c_configure()
2597 (void)memcpy(&dev_data->common.ctrl_config, config_cntlr, sizeof(*config_cntlr)); in npcx_i3c_configure()
2603 if (config_target->pid == 0) { in npcx_i3c_configure()
2605 return -EINVAL; in npcx_i3c_configure()
2613 return -EINVAL; in npcx_i3c_configure()
2618 struct npcx_i3c_data *data = dev->data; in npcx_i3c_config_get()
2621 return -EINVAL; in npcx_i3c_config_get()
2625 (void)memcpy(config, &data->common.ctrl_config, sizeof(data->common.ctrl_config)); in npcx_i3c_config_get()
2627 (void)memcpy(config, &data->config_target, sizeof(data->config_target)); in npcx_i3c_config_get()
2629 return -EINVAL; in npcx_i3c_config_get()
2637 struct npcx_i3c_data *data = dev->data; in npcx_i3c_target_isr()
2638 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_target_isr()
2639 struct i3c_config_target *config_tgt = &data->config_target; in npcx_i3c_target_isr()
2640 struct i3c_target_config *target_config = data->target_config; in npcx_i3c_target_isr()
2641 struct i3c_reg *inst = config->base; in npcx_i3c_target_isr()
2642 const struct i3c_target_callbacks *target_cb = data->target_config->callbacks; in npcx_i3c_target_isr()
2645 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_target_isr()
2648 if (IS_BIT_SET(mdma_inst->MDMA_CTL0, NPCX_MDMA_CTL_TC)) { in npcx_i3c_target_isr()
2655 if ((target_cb != NULL) && (target_cb->buf_write_received_cb != NULL)) { in npcx_i3c_target_isr()
2656 target_cb->buf_write_received_cb( in npcx_i3c_target_isr()
2657 data->target_config, data->mdma_rx_buf, in npcx_i3c_target_isr()
2663 data->oper_state); in npcx_i3c_target_isr()
2670 while (inst->INTMASKED) { in npcx_i3c_target_isr()
2672 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_STOP)) { in npcx_i3c_target_isr()
2674 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_START)) { in npcx_i3c_target_isr()
2675 inst->STATUS = BIT(NPCX_I3C_STATUS_START); in npcx_i3c_target_isr()
2691 inst->STATUS = BIT(NPCX_I3C_STATUS_STOP); in npcx_i3c_target_isr()
2695 if ((target_cb != NULL) && (target_cb->stop_cb != NULL)) { in npcx_i3c_target_isr()
2696 target_cb->stop_cb(data->target_config); in npcx_i3c_target_isr()
2699 /* Clear DA matched status and re-enable interrupt */ in npcx_i3c_target_isr()
2700 inst->STATUS = BIT(NPCX_I3C_STATUS_MATCHED); in npcx_i3c_target_isr()
2701 inst->INTSET = BIT(NPCX_I3C_INTSET_MATCHED); in npcx_i3c_target_isr()
2706 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_START)) { in npcx_i3c_target_isr()
2710 if (-EBUSY == npcx_i3c_target_xfer_end_handle(dev)) { in npcx_i3c_target_isr()
2715 inst->STATUS = BIT(NPCX_I3C_STATUS_START); in npcx_i3c_target_isr()
2718 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_TGTRST)) { in npcx_i3c_target_isr()
2719 inst->STATUS = BIT(NPCX_I3C_STATUS_TGTRST); in npcx_i3c_target_isr()
2723 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_ERRWARN)) { in npcx_i3c_target_isr()
2724 LOG_ERR("%s: Error %#x", __func__, inst->ERRWARN); in npcx_i3c_target_isr()
2725 inst->ERRWARN = inst->ERRWARN; in npcx_i3c_target_isr()
2729 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_MATCHED)) { in npcx_i3c_target_isr()
2732 if (IS_BIT_SET(inst->STATUS, NPCX_I3C_STATUS_STREQRD)) { in npcx_i3c_target_isr()
2743 (target_cb->buf_read_requested_cb != NULL)) { in npcx_i3c_target_isr()
2744 target_cb->buf_read_requested_cb( in npcx_i3c_target_isr()
2745 data->target_config, NULL, NULL, NULL); in npcx_i3c_target_isr()
2754 (target_cb->write_requested_cb != NULL)) { in npcx_i3c_target_isr()
2755 target_cb->write_requested_cb(data->target_config); in npcx_i3c_target_isr()
2767 if (IS_BIT_SET(inst->CONFIG, NPCX_I3C_CONFIG_MATCHSS)) { in npcx_i3c_target_isr()
2768 inst->INTCLR = BIT(NPCX_I3C_INTCLR_MATCHED); in npcx_i3c_target_isr()
2770 inst->STATUS = BIT(NPCX_I3C_STATUS_MATCHED); in npcx_i3c_target_isr()
2775 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_DACHG)) { in npcx_i3c_target_isr()
2776 inst->STATUS = BIT(NPCX_I3C_STATUS_DACHG); in npcx_i3c_target_isr()
2778 if (IS_BIT_SET(inst->DYNADDR, NPCX_I3C_DYNADDR_DAVALID)) { in npcx_i3c_target_isr()
2780 config_tgt->dynamic_addr = in npcx_i3c_target_isr()
2781 GET_FIELD(inst->DYNADDR, NPCX_I3C_DYNADDR_DADDR); in npcx_i3c_target_isr()
2787 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_CCC)) { in npcx_i3c_target_isr()
2788 inst->STATUS = BIT(NPCX_I3C_STATUS_CCC); in npcx_i3c_target_isr()
2792 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_HDRMATCH)) { in npcx_i3c_target_isr()
2793 inst->STATUS = BIT(NPCX_I3C_STATUS_HDRMATCH); in npcx_i3c_target_isr()
2797 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_CHANDLED)) { in npcx_i3c_target_isr()
2798 inst->STATUS = BIT(NPCX_I3C_STATUS_CHANDLED); in npcx_i3c_target_isr()
2801 /* Event requested. IBI, hot-join, bus control */ in npcx_i3c_target_isr()
2802 if (IS_BIT_SET(inst->INTMASKED, NPCX_I3C_INTMASKED_EVENT)) { in npcx_i3c_target_isr()
2803 inst->STATUS = BIT(NPCX_I3C_STATUS_EVENT); in npcx_i3c_target_isr()
2805 if (GET_FIELD(inst->STATUS, NPCX_I3C_STATUS_EVDET) == in npcx_i3c_target_isr()
2807 k_sem_give(&data->target_event_lock_sem); in npcx_i3c_target_isr()
2816 if (IS_BIT_SET(inst->MINTMASKED, NPCX_I3C_MINTMASKED_NOWCNTLR)) { in npcx_i3c_target_isr()
2817 inst->MSTATUS = BIT(NPCX_I3C_MSTATUS_NOWCNTLR); /* W1C */ in npcx_i3c_target_isr()
2818 inst->CONFIG &= ~BIT(NPCX_I3C_CONFIG_TGTENA); /* Disable target mode */ in npcx_i3c_target_isr()
2824 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_isr()
2825 struct i3c_reg *inst = config->base; in npcx_i3c_isr()
2827 if (IS_BIT_SET(inst->CONFIG, NPCX_I3C_CONFIG_TGTENA)) { in npcx_i3c_isr()
2833 struct mdma_reg *mdma_inst = config->mdma_base; in npcx_i3c_isr()
2836 if (IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_COMPLETE)) { in npcx_i3c_isr()
2837 inst->MSTATUS = BIT(NPCX_I3C_MSTATUS_COMPLETE); /* W1C */ in npcx_i3c_isr()
2847 if (IS_BIT_SET(mdma_inst->MDMA_CTL0, NPCX_MDMA_CTL_TC)) { in npcx_i3c_isr()
2848 mdma_inst->MDMA_CTL0 &= ~BIT(NPCX_MDMA_CTL_TC); /* W0C */ in npcx_i3c_isr()
2862 if (IS_BIT_SET(inst->MSTATUS, NPCX_I3C_MSTATUS_TGTSTART)) { in npcx_i3c_isr()
2866 inst->MINTCLR = BIT(NPCX_I3C_MINTCLR_TGTSTART); in npcx_i3c_isr()
2868 inst->MSTATUS = BIT(NPCX_I3C_MSTATUS_TGTSTART); in npcx_i3c_isr()
2874 inst->MINTSET = BIT(NPCX_I3C_MINTSET_TGTSTART); in npcx_i3c_isr()
2882 const struct npcx_i3c_config *config = dev->config; in npcx_i3c_init()
2883 struct npcx_i3c_data *data = dev->data; in npcx_i3c_init()
2884 struct i3c_config_controller *config_cntlr = &data->common.ctrl_config; in npcx_i3c_init()
2885 const struct device *const clk_dev = config->clock_dev; in npcx_i3c_init()
2886 struct i3c_reg *inst = config->base; in npcx_i3c_init()
2891 LOG_ERR("%s Clk device not ready", clk_dev->name); in npcx_i3c_init()
2892 return -ENODEV; in npcx_i3c_init()
2896 ret = clock_control_on(clk_dev, (clock_control_subsys_t)&config->clock_subsys); in npcx_i3c_init()
2903 ret = clock_control_on(clk_dev, (clock_control_subsys_t)&config->mdma_clk_subsys); in npcx_i3c_init()
2910 /* Apply pin-muxing */ in npcx_i3c_init()
2911 ret = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); in npcx_i3c_init()
2918 k_mutex_init(&data->lock_mutex); in npcx_i3c_init()
2919 k_sem_init(&data->sync_sem, 0, 1); in npcx_i3c_init()
2920 k_sem_init(&data->ibi_lock_sem, 1, 1); in npcx_i3c_init()
2921 k_sem_init(&data->target_lock_sem, 1, 1); in npcx_i3c_init()
2922 k_sem_init(&data->target_event_lock_sem, 1, 1); in npcx_i3c_init()
2931 config_cntlr->supported_hdr = I3C_MSG_HDR_DDR; /* HDR-DDR mode is supported. */ in npcx_i3c_init()
2932 config_cntlr->scl.i3c = config->clocks.i3c_pp_scl_hz; /* Set I3C frequency */ in npcx_i3c_init()
2937 if (GET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_CTRENA) == MCONFIG_CTRENA_ON) { in npcx_i3c_init()
2947 config->irq_config_func(dev); in npcx_i3c_init()
2953 if ((config->common.dev_list.num_i3c > 0) && in npcx_i3c_init()
2954 GET_FIELD(inst->MCONFIG, NPCX_I3C_MCONFIG_CTRENA) == MCONFIG_CTRENA_ON) { in npcx_i3c_init()
2956 ret = i3c_bus_init(dev, &config->common.dev_list); in npcx_i3c_init()