1 /*
2  * Copyright (c) 2024 Ambiq Micro Inc. <www.ambiq.com>
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <zephyr/device.h>
7 #include <zephyr/drivers/gpio.h>
8 #include <zephyr/drivers/mspi.h>
9 #include <zephyr/drivers/mspi_emul.h>
10 #include <zephyr/ztest.h>
11 
12 #define TEST_MSPI_REINIT    1
13 
14 /* add else if for other SoC platforms */
15 #if defined(CONFIG_SOC_POSIX)
16 typedef struct mspi_timing_cfg mspi_timing_cfg;
17 typedef enum mspi_timing_param mspi_timing_param;
18 #elif defined(CONFIG_SOC_FAMILY_AMBIQ)
19 #include "mspi_ambiq.h"
20 typedef struct mspi_ambiq_timing_cfg mspi_timing_cfg;
21 typedef enum mspi_ambiq_timing_param mspi_timing_param;
22 #endif
23 
24 #define MSPI_BUS_NODE       DT_ALIAS(mspi0)
25 
26 static const struct device *mspi_devices[] = {
27 	DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, DEVICE_DT_GET, (,))
28 };
29 
30 static struct gpio_dt_spec ce_gpios[] = MSPI_CE_GPIOS_DT_SPEC_GET(MSPI_BUS_NODE);
31 
32 #if TEST_MSPI_REINIT
33 struct mspi_cfg hardware_cfg = {
34 	.channel_num              = 0,
35 	.op_mode                  = DT_ENUM_IDX_OR(MSPI_BUS_NODE, op_mode, MSPI_OP_MODE_CONTROLLER),
36 	.duplex                   = DT_ENUM_IDX_OR(MSPI_BUS_NODE, duplex, MSPI_HALF_DUPLEX),
37 	.dqs_support              = DT_PROP_OR(MSPI_BUS_NODE, dqs_support, false),
38 	.ce_group                 = ce_gpios,
39 	.num_ce_gpios             = ARRAY_SIZE(ce_gpios),
40 	.num_periph               = DT_CHILD_NUM(MSPI_BUS_NODE),
41 	.max_freq                 = DT_PROP(MSPI_BUS_NODE, clock_frequency),
42 	.re_init                  = true,
43 };
44 #endif
45 
46 
47 static struct mspi_dev_id dev_id[] = {
48 	DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, MSPI_DEVICE_ID_DT, (,))
49 };
50 
51 static struct mspi_dev_cfg device_cfg[] = {
52 	DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, MSPI_DEVICE_CONFIG_DT, (,))
53 };
54 
55 #if CONFIG_MSPI_XIP
56 static struct mspi_xip_cfg xip_cfg[] = {
57 	DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, MSPI_XIP_CONFIG_DT, (,))
58 };
59 #endif
60 
61 #if CONFIG_MSPI_SCRAMBLE
62 static struct mspi_scramble_cfg scramble_cfg[] = {
63 	DT_FOREACH_CHILD_STATUS_OKAY_SEP(MSPI_BUS_NODE, MSPI_SCRAMBLE_CONFIG_DT, (,))
64 };
65 #endif
66 
ZTEST(mspi_api,test_mspi_api)67 ZTEST(mspi_api, test_mspi_api)
68 {
69 	int ret = 0;
70 	const struct device *mspi_bus = DEVICE_DT_GET(MSPI_BUS_NODE);
71 
72 	zassert_true(device_is_ready(mspi_bus), "mspi_bus is not ready");
73 
74 #if TEST_MSPI_REINIT
75 	const struct mspi_dt_spec spec = {
76 		.bus    = mspi_bus,
77 		.config = hardware_cfg,
78 	};
79 
80 	ret = mspi_config(&spec);
81 	zassert_equal(ret, 0, "mspi_config failed.");
82 #endif
83 
84 	for (int dev_idx = 0; dev_idx < ARRAY_SIZE(mspi_devices); ++dev_idx) {
85 
86 		zassert_true(device_is_ready(mspi_devices[dev_idx]), "mspi_device is not ready");
87 
88 		ret = mspi_dev_config(mspi_bus, &dev_id[dev_idx],
89 				      MSPI_DEVICE_CONFIG_ALL, &device_cfg[dev_idx]);
90 		zassert_equal(ret, 0, "mspi_dev_config failed.");
91 
92 #if CONFIG_MSPI_XIP
93 		ret = mspi_xip_config(mspi_bus, &dev_id[dev_idx], &xip_cfg[dev_idx]);
94 		zassert_equal(ret, 0, "mspi_xip_config failed.");
95 #endif
96 
97 #if CONFIG_MSPI_SCRAMBLE
98 		ret = mspi_scramble_config(mspi_bus, &dev_id[dev_idx], &scramble_cfg[dev_idx]);
99 		zassert_equal(ret, 0, "mspi_scramble_config failed.");
100 #endif
101 
102 #if CONFIG_MSPI_TIMING
103 		mspi_timing_cfg timing_cfg;
104 		mspi_timing_param timing_cfg_mask = 0;
105 
106 		ret = mspi_timing_config(mspi_bus, &dev_id[dev_idx], timing_cfg_mask, &timing_cfg);
107 		zassert_equal(ret, 0, "mspi_timing_config failed.");
108 #endif
109 
110 		ret = mspi_register_callback(mspi_bus, &dev_id[dev_idx],
111 					     MSPI_BUS_XFER_COMPLETE, NULL, NULL);
112 		if (ret == -ENOTSUP) {
113 			printf("mspi_register_callback not supported.\n");
114 		} else {
115 			zassert_equal(ret, 0, "mspi_register_callback failed.");
116 		}
117 
118 		ret = mspi_get_channel_status(mspi_bus, 0);
119 		zassert_equal(ret, 0, "mspi_get_channel_status failed.");
120 
121 	}
122 }
123 
124 ZTEST_SUITE(mspi_api, NULL, NULL, NULL, NULL, NULL);
125