Lines Matching +full:mspi +full:- +full:endian

4  * SPDX-License-Identifier: Apache-2.0
6 * This driver creates fake MSPI buses which can contain emulated devices,
20 #include <zephyr/drivers/mspi.h>
46 /* common mspi hardware configurations */
60 /* local storage of mspi callback hanlder */
62 /* local storage of mspi callback context */
64 /* local mspi context */
69 * Verify if the device with dev_id is on this MSPI bus.
73 * @return 0 The device is on this MSPI bus.
74 * @return -ENODEV The device is not on this MSPI bus.
79 const struct mspi_emul_data *data = controller->data; in mspi_verify_device()
80 int device_index = data->mspicfg.num_periph; in mspi_verify_device()
83 if (data->mspicfg.num_ce_gpios != 0) { in mspi_verify_device()
84 for (int i = 0; i < data->mspicfg.num_periph; i++) { in mspi_verify_device()
85 if (dev_id->ce.port == data->mspicfg.ce_group[i].port && in mspi_verify_device()
86 dev_id->ce.pin == data->mspicfg.ce_group[i].pin && in mspi_verify_device()
87 dev_id->ce.dt_flags == data->mspicfg.ce_group[i].dt_flags) { in mspi_verify_device()
92 if (device_index >= data->mspicfg.num_periph || in mspi_verify_device()
93 device_index != dev_id->dev_idx) { in mspi_verify_device()
95 return -ENODEV; in mspi_verify_device()
98 if (dev_id->dev_idx >= data->mspicfg.num_periph) { in mspi_verify_device()
100 return -ENODEV; in mspi_verify_device()
108 * Check if the MSPI bus is busy.
110 * @param controller MSPI emulation controller device.
111 * @return true The MSPI bus is busy.
112 * @return false The MSPI bus is idle.
116 struct mspi_emul_data *data = controller->data; in mspi_is_inp()
118 return (k_sem_count_get(&data->ctx.lock) == 0); in mspi_is_inp()
122 * Lock MSPI context.
124 * @param ctx Pointer to the MSPI context.
126 * @param xfer Pointer to the MSPI transfer started by req.
127 * @param callback MSPI call back function pointer.
128 * @param callback_ctx Pointer to the mspi callback context.
140 if (k_sem_take(&ctx->lock, K_MSEC(xfer->timeout))) { in mspi_context_lock()
144 if (ctx->callback) { in mspi_context_lock()
146 if ((xfer->tx_dummy == ctx->xfer.tx_dummy) && in mspi_context_lock()
147 (xfer->rx_dummy == ctx->xfer.rx_dummy) && in mspi_context_lock()
148 (xfer->cmd_length == ctx->xfer.cmd_length) && in mspi_context_lock()
149 (xfer->addr_length == ctx->xfer.addr_length)) { in mspi_context_lock()
156 ctx->owner = req; in mspi_context_lock()
157 ctx->xfer = *xfer; in mspi_context_lock()
158 ctx->packets_done = 0; in mspi_context_lock()
159 ctx->asynchronous = ctx->xfer.async; in mspi_context_lock()
160 ctx->callback = callback; in mspi_context_lock()
161 ctx->callback_ctx = callback_ctx; in mspi_context_lock()
167 * release MSPI context.
169 * @param ctx Pointer to the MSPI context.
173 ctx->owner = NULL; in mspi_context_release()
174 k_sem_give(&ctx->lock); in mspi_context_release()
180 * @param controller Pointer to the MSPI controller instance.
181 * @param xfer Pointer to the MSPI transfer started by the request entity.
187 struct mspi_emul_data *data = controller->data; in mspi_xfer_config()
189 data->dev_cfg.cmd_length = xfer->cmd_length; in mspi_xfer_config()
190 data->dev_cfg.addr_length = xfer->addr_length; in mspi_xfer_config()
191 data->dev_cfg.tx_dummy = xfer->tx_dummy; in mspi_xfer_config()
192 data->dev_cfg.rx_dummy = xfer->rx_dummy; in mspi_xfer_config()
198 * Check and save dev_cfg to controller data->dev_cfg.
202 * @param dev_cfg The device runtime configuration for the MSPI controller.
203 * @return 0 MSPI device configuration successful.
204 * @return -Error MSPI device configuration fail.
210 struct mspi_emul_data *data = controller->data; in mspi_dev_cfg_check_save()
213 data->dev_cfg.ce_num = dev_cfg->ce_num; in mspi_dev_cfg_check_save()
217 if (dev_cfg->freq > MSPI_MAX_FREQ) { in mspi_dev_cfg_check_save()
219 return -ENOTSUP; in mspi_dev_cfg_check_save()
221 data->dev_cfg.freq = dev_cfg->freq; in mspi_dev_cfg_check_save()
225 if (dev_cfg->io_mode >= MSPI_IO_MODE_MAX) { in mspi_dev_cfg_check_save()
227 return -EINVAL; in mspi_dev_cfg_check_save()
229 data->dev_cfg.io_mode = dev_cfg->io_mode; in mspi_dev_cfg_check_save()
233 if (dev_cfg->data_rate >= MSPI_DATA_RATE_MAX) { in mspi_dev_cfg_check_save()
235 return -EINVAL; in mspi_dev_cfg_check_save()
237 data->dev_cfg.data_rate = dev_cfg->data_rate; in mspi_dev_cfg_check_save()
241 if (dev_cfg->cpp > MSPI_CPP_MODE_3) { in mspi_dev_cfg_check_save()
243 return -EINVAL; in mspi_dev_cfg_check_save()
245 data->dev_cfg.cpp = dev_cfg->cpp; in mspi_dev_cfg_check_save()
249 if (dev_cfg->endian > MSPI_XFER_BIG_ENDIAN) { in mspi_dev_cfg_check_save()
250 LOG_ERR("%u, Invalid endian.", __LINE__); in mspi_dev_cfg_check_save()
251 return -EINVAL; in mspi_dev_cfg_check_save()
253 data->dev_cfg.endian = dev_cfg->endian; in mspi_dev_cfg_check_save()
257 if (dev_cfg->ce_polarity > MSPI_CE_ACTIVE_HIGH) { in mspi_dev_cfg_check_save()
259 return -EINVAL; in mspi_dev_cfg_check_save()
261 data->dev_cfg.ce_polarity = dev_cfg->ce_polarity; in mspi_dev_cfg_check_save()
265 if (dev_cfg->dqs_enable && !data->mspicfg.dqs_support) { in mspi_dev_cfg_check_save()
267 return -ENOTSUP; in mspi_dev_cfg_check_save()
269 data->dev_cfg.dqs_enable = dev_cfg->dqs_enable; in mspi_dev_cfg_check_save()
273 data->dev_cfg.rx_dummy = dev_cfg->rx_dummy; in mspi_dev_cfg_check_save()
277 data->dev_cfg.tx_dummy = dev_cfg->tx_dummy; in mspi_dev_cfg_check_save()
281 data->dev_cfg.read_cmd = dev_cfg->read_cmd; in mspi_dev_cfg_check_save()
285 data->dev_cfg.write_cmd = dev_cfg->write_cmd; in mspi_dev_cfg_check_save()
289 data->dev_cfg.cmd_length = dev_cfg->cmd_length; in mspi_dev_cfg_check_save()
293 data->dev_cfg.addr_length = dev_cfg->addr_length; in mspi_dev_cfg_check_save()
297 data->dev_cfg.mem_boundary = dev_cfg->mem_boundary; in mspi_dev_cfg_check_save()
301 data->dev_cfg.time_to_break = dev_cfg->time_to_break; in mspi_dev_cfg_check_save()
310 * @param xfer Pointer to the MSPI transfer started by the request entity.
312 * @return -EINVAL invalid parameter detected.
316 if (xfer->xfer_mode > MSPI_DMA) { in mspi_xfer_check()
318 return -EINVAL; in mspi_xfer_check()
321 if (!xfer->packets || !xfer->num_packet) { in mspi_xfer_check()
323 return -EINVAL; in mspi_xfer_check()
326 for (int i = 0; i < xfer->num_packet; ++i) { in mspi_xfer_check()
328 if (!xfer->packets[i].data_buf || in mspi_xfer_check()
329 !xfer->packets[i].num_bytes) { in mspi_xfer_check()
331 return -EINVAL; in mspi_xfer_check()
334 if (xfer->packets[i].dir > MSPI_TX) { in mspi_xfer_check()
336 return -EINVAL; in mspi_xfer_check()
339 if (xfer->packets[i].cb_mask > MSPI_BUS_XFER_COMPLETE_CB) { in mspi_xfer_check()
341 return -EINVAL; in mspi_xfer_check()
350 * @param controller Pointer to MSPI controller instance.
358 struct mspi_emul_data *data = controller->data; in mspi_emul_find()
361 SYS_SLIST_FOR_EACH_NODE(&data->emuls, node) { in mspi_emul_find()
365 if (emul->dev_idx == dev_idx) { in mspi_emul_find()
376 * @param controller Pointer to MSPI controller instance.
383 struct mspi_emul_data *data = controller->data; in emul_mspi_trigger_event()
384 struct mspi_emul_context *ctx = &data->ctx; in emul_mspi_trigger_event()
391 if (ctx->callback && ctx->callback_ctx) { in emul_mspi_trigger_event()
393 struct mspi_event *evt = &ctx->callback_ctx->mspi_evt; in emul_mspi_trigger_event()
396 packet = &ctx->xfer.packets[ctx->packets_done]; in emul_mspi_trigger_event()
398 evt->evt_type = MSPI_BUS_XFER_COMPLETE; in emul_mspi_trigger_event()
399 evt->evt_data.controller = controller; in emul_mspi_trigger_event()
400 evt->evt_data.dev_id = ctx->owner; in emul_mspi_trigger_event()
401 evt->evt_data.packet = packet; in emul_mspi_trigger_event()
402 evt->evt_data.packet_idx = ctx->packets_done; in emul_mspi_trigger_event()
403 ctx->packets_done++; in emul_mspi_trigger_event()
405 if (packet->cb_mask == MSPI_BUS_XFER_COMPLETE_CB) { in emul_mspi_trigger_event()
406 cb = ctx->callback; in emul_mspi_trigger_event()
407 cb_context = ctx->callback_ctx; in emul_mspi_trigger_event()
417 cb = data->cbs[evt_type]; in emul_mspi_trigger_event()
418 cb_context = data->cb_ctxs[evt_type]; in emul_mspi_trigger_event()
422 LOG_ERR("%u, mspi callback type %u not registered.", __LINE__, evt_type); in emul_mspi_trigger_event()
423 return -EINVAL; in emul_mspi_trigger_event()
433 * @param spec Pointer to MSPI device tree spec.
435 * @return -Error if fail.
439 const struct mspi_cfg *config = &spec->config; in mspi_emul_config()
440 struct mspi_emul_data *data = spec->bus->data; in mspi_emul_config()
444 if (config->op_mode > MSPI_OP_MODE_PERIPHERAL) { in mspi_emul_config()
445 LOG_ERR("%u, Invalid MSPI OP mode.", __LINE__); in mspi_emul_config()
446 return -EINVAL; in mspi_emul_config()
449 if (config->max_freq > MSPI_MAX_FREQ) { in mspi_emul_config()
450 LOG_ERR("%u, Invalid MSPI Frequency", __LINE__); in mspi_emul_config()
451 return -ENOTSUP; in mspi_emul_config()
454 if (config->duplex > MSPI_FULL_DUPLEX) { in mspi_emul_config()
455 LOG_ERR("%u, Invalid MSPI duplexity.", __LINE__); in mspi_emul_config()
456 return -EINVAL; in mspi_emul_config()
459 if (config->num_periph > MSPI_MAX_DEVICE) { in mspi_emul_config()
460 LOG_ERR("%u, Invalid MSPI peripheral number.", __LINE__); in mspi_emul_config()
461 return -ENOTSUP; in mspi_emul_config()
464 if (config->num_ce_gpios != 0 && in mspi_emul_config()
465 config->num_ce_gpios != config->num_periph) { in mspi_emul_config()
467 return -EINVAL; in mspi_emul_config()
470 if (config->re_init) { in mspi_emul_config()
471 if (k_mutex_lock(&data->lock, K_MSEC(CONFIG_MSPI_COMPLETION_TIMEOUT_TOLERANCE))) { in mspi_emul_config()
473 return -EBUSY; in mspi_emul_config()
475 while (mspi_is_inp(spec->bus)) { in mspi_emul_config()
482 if (!k_sem_count_get(&data->ctx.lock)) { in mspi_emul_config()
483 data->ctx.owner = NULL; in mspi_emul_config()
484 k_sem_give(&data->ctx.lock); in mspi_emul_config()
487 if (config->re_init) { in mspi_emul_config()
488 k_mutex_unlock(&data->lock); in mspi_emul_config()
491 data->mspicfg = *config; in mspi_emul_config()
502 * @param dev_cfg The device runtime configuration for the MSPI controller.
505 * @retval -EINVAL invalid capabilities, failed to configure device.
506 * @retval -ENOTSUP capability not supported by MSPI peripheral.
513 struct mspi_emul_data *data = controller->data; in mspi_emul_dev_config()
516 if (data->dev_id != dev_id) { in mspi_emul_dev_config()
517 if (k_mutex_lock(&data->lock, K_MSEC(CONFIG_MSPI_COMPLETION_TIMEOUT_TOLERANCE))) { in mspi_emul_dev_config()
519 return -EBUSY; in mspi_emul_dev_config()
532 !data->mspicfg.sw_multi_periph) { in mspi_emul_dev_config()
535 if (data->dev_id != dev_id) { in mspi_emul_dev_config()
538 ret = -ENOTSUP; in mspi_emul_dev_config()
550 if (data->dev_id != dev_id) { in mspi_emul_dev_config()
555 ret = -EINVAL; in mspi_emul_dev_config()
559 data->dev_id = dev_id; in mspi_emul_dev_config()
563 k_mutex_unlock(&data->lock); in mspi_emul_dev_config()
572 * @param xip_cfg The controller XIP configuration for MSPI.
575 * @retval -ESTALE device ID don't match, need to call mspi_dev_config first.
581 struct mspi_emul_data *data = controller->data; in mspi_emul_xip_config()
584 if (dev_id != data->dev_id) { in mspi_emul_xip_config()
586 return -ESTALE; in mspi_emul_xip_config()
589 data->xip_cfg = *xip_cfg; in mspi_emul_xip_config()
598 * @param scramble_cfg The controller scramble configuration for MSPI.
601 * @retval -ESTALE device ID don't match, need to call mspi_dev_config first.
607 struct mspi_emul_data *data = controller->data; in mspi_emul_scramble_config()
613 if (dev_id != data->dev_id) { in mspi_emul_scramble_config()
615 return -ESTALE; in mspi_emul_scramble_config()
618 data->scramble_cfg = *scramble_cfg; in mspi_emul_scramble_config()
628 * @param timing_cfg The controller timing configuration for MSPI.
631 * @retval -ESTALE device ID don't match, need to call mspi_dev_config first.
632 * @retval -ENOTSUP param_mask value is not supported.
639 struct mspi_emul_data *data = controller->data; in mspi_emul_timing_config()
645 if (dev_id != data->dev_id) { in mspi_emul_timing_config()
647 return -ESTALE; in mspi_emul_timing_config()
651 data->timing_cfg = *(struct mspi_timing_cfg *)timing_cfg; in mspi_emul_timing_config()
654 return -ENOTSUP; in mspi_emul_timing_config()
667 * @retval -EBUSY MSPI bus is busy
671 struct mspi_emul_data *data = controller->data; in mspi_emul_get_channel_status()
676 return -EBUSY; in mspi_emul_get_channel_status()
679 k_mutex_unlock(&data->lock); in mspi_emul_get_channel_status()
680 data->dev_id = NULL; in mspi_emul_get_channel_status()
695 * @retval -ESTALE device ID don't match, need to call mspi_dev_config first.
696 * @retval -ENOTSUP evt_type not supported.
704 struct mspi_emul_data *data = controller->data; in mspi_emul_register_callback()
709 if (dev_id != data->dev_id) { in mspi_emul_register_callback()
711 return -ESTALE; in mspi_emul_register_callback()
716 return -ENOTSUP; in mspi_emul_register_callback()
719 data->cbs[evt_type] = cb; in mspi_emul_register_callback()
720 data->cb_ctxs[evt_type] = ctx; in mspi_emul_register_callback()
729 * @param xfer Pointer to the MSPI transfer started by dev_id.
732 * @retval -ESTALE device ID don't match, need to call mspi_dev_config first.
733 * @retval -Error transfer failed.
739 struct mspi_emul_data *data = controller->data; in mspi_emul_transceive()
740 struct mspi_emul_context *ctx = &data->ctx; in mspi_emul_transceive()
747 emul = mspi_emul_find(controller, dev_id->dev_idx); in mspi_emul_transceive()
750 return -EIO; in mspi_emul_transceive()
753 if (dev_id != data->dev_id) { in mspi_emul_transceive()
755 return -ESTALE; in mspi_emul_transceive()
763 __ASSERT_NO_MSG(emul->api); in mspi_emul_transceive()
764 __ASSERT_NO_MSG(emul->api->transceive); in mspi_emul_transceive()
766 if (xfer->async) { in mspi_emul_transceive()
767 cb = data->cbs[MSPI_BUS_XFER_COMPLETE]; in mspi_emul_transceive()
768 cb_ctx = data->cb_ctxs[MSPI_BUS_XFER_COMPLETE]; in mspi_emul_transceive()
787 ret = emul->api->transceive(emul->target, in mspi_emul_transceive()
788 ctx->xfer.packets, in mspi_emul_transceive()
789 ctx->xfer.num_packet, in mspi_emul_transceive()
790 ctx->asynchronous, MSPI_TIMEOUT_US); in mspi_emul_transceive()
801 * @param dev MSPI emulation controller.
807 struct mspi_emul_data *data = dev->data; in mspi_emul_init()
810 .config = data->mspicfg, in mspi_emul_init()
819 sys_slist_init(&data->emuls); in mspi_emul_init()
827 * @param dev MSPI emulation controller.
828 * @param emul MSPI emulation device.
834 struct mspi_emul_data *data = dev->data; in mspi_emul_register()
835 const char *name = emul->target->dev->name; in mspi_emul_register()
837 sys_slist_append(&data->emuls, &emul->node); in mspi_emul_register()
839 LOG_INF("Register emulator '%s', id:%x\n", name, emul->dev_idx); in mspi_emul_register()