1 /*
2  * Copyright (c) 2024, Ambiq Micro Inc. <www.ambiq.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Public APIs for MSPI driver
10  * @since 3.7
11  * @version 0.1.0
12  */
13 
14 #ifndef ZEPHYR_INCLUDE_MSPI_H_
15 #define ZEPHYR_INCLUDE_MSPI_H_
16 
17 #include <errno.h>
18 
19 #include <zephyr/sys/__assert.h>
20 #include <zephyr/types.h>
21 #include <zephyr/kernel.h>
22 #include <zephyr/device.h>
23 #include <zephyr/drivers/gpio.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /**
30  * @brief MSPI Driver APIs
31  * @defgroup mspi_interface MSPI Driver APIs
32  * @ingroup io_interfaces
33  * @{
34  */
35 
36 /**
37  * @brief MSPI operational mode
38  */
39 enum mspi_op_mode {
40 	MSPI_OP_MODE_CONTROLLER     = 0,
41 	MSPI_OP_MODE_PERIPHERAL     = 1,
42 };
43 
44 /**
45  * @brief MSPI duplex mode
46  */
47 enum mspi_duplex {
48 	MSPI_HALF_DUPLEX            = 0,
49 	MSPI_FULL_DUPLEX            = 1,
50 };
51 
52 /**
53  * @brief MSPI I/O mode capabilities
54  * Postfix like 1_4_4 stands for the number of lines used for
55  * command, address and data phases.
56  * Mode with no postfix has the same number of lines for all phases.
57  */
58 enum mspi_io_mode {
59 	MSPI_IO_MODE_SINGLE         = 0,
60 	MSPI_IO_MODE_DUAL           = 1,
61 	MSPI_IO_MODE_DUAL_1_1_2     = 2,
62 	MSPI_IO_MODE_DUAL_1_2_2     = 3,
63 	MSPI_IO_MODE_QUAD           = 4,
64 	MSPI_IO_MODE_QUAD_1_1_4     = 5,
65 	MSPI_IO_MODE_QUAD_1_4_4     = 6,
66 	MSPI_IO_MODE_OCTAL          = 7,
67 	MSPI_IO_MODE_OCTAL_1_1_8    = 8,
68 	MSPI_IO_MODE_OCTAL_1_8_8    = 9,
69 	MSPI_IO_MODE_HEX            = 10,
70 	MSPI_IO_MODE_HEX_8_8_16     = 11,
71 	MSPI_IO_MODE_HEX_8_16_16    = 12,
72 	MSPI_IO_MODE_MAX,
73 };
74 
75 /**
76  * @brief MSPI data rate capabilities
77  * SINGLE stands for single data rate for all phases.
78  * DUAL stands for dual data rate for all phases.
79  * S_S_D stands for single data rate for command and address phases but
80  * dual data rate for data phase.
81  * S_D_D stands for single data rate for command phase but dual data rate
82  * for address and data phases.
83  */
84 enum mspi_data_rate {
85 	MSPI_DATA_RATE_SINGLE       = 0,
86 	MSPI_DATA_RATE_S_S_D        = 1,
87 	MSPI_DATA_RATE_S_D_D        = 2,
88 	MSPI_DATA_RATE_DUAL         = 3,
89 	MSPI_DATA_RATE_MAX,
90 };
91 
92 /**
93  * @brief MSPI Polarity & Phase Modes
94  */
95 enum mspi_cpp_mode {
96 	MSPI_CPP_MODE_0             = 0,
97 	MSPI_CPP_MODE_1             = 1,
98 	MSPI_CPP_MODE_2             = 2,
99 	MSPI_CPP_MODE_3             = 3,
100 };
101 
102 /**
103  * @brief MSPI Endian
104  */
105 enum mspi_endian {
106 	MSPI_XFER_LITTLE_ENDIAN     = 0,
107 	MSPI_XFER_BIG_ENDIAN        = 1,
108 };
109 
110 /**
111  * @brief MSPI chip enable polarity
112  */
113 enum mspi_ce_polarity {
114 	MSPI_CE_ACTIVE_LOW          = 0,
115 	MSPI_CE_ACTIVE_HIGH         = 1,
116 };
117 
118 /**
119  * @brief MSPI bus event.
120  * This is a  preliminary list of events. I encourage the community
121  * to fill it up.
122  */
123 enum mspi_bus_event {
124 	MSPI_BUS_RESET              = 0,
125 	MSPI_BUS_ERROR              = 1,
126 	MSPI_BUS_XFER_COMPLETE      = 2,
127 	MSPI_BUS_EVENT_MAX,
128 };
129 
130 /**
131  * @brief MSPI bus event callback mask
132  * This is a  preliminary list same as mspi_bus_event. I encourage the
133  * community to fill it up.
134  */
135 enum mspi_bus_event_cb_mask {
136 	MSPI_BUS_NO_CB              = 0,
137 	MSPI_BUS_RESET_CB           = BIT(0),
138 	MSPI_BUS_ERROR_CB           = BIT(1),
139 	MSPI_BUS_XFER_COMPLETE_CB   = BIT(2),
140 };
141 
142 /**
143  * @brief MSPI transfer modes
144  */
145 enum mspi_xfer_mode {
146 	MSPI_PIO,
147 	MSPI_DMA,
148 };
149 
150 /**
151  * @brief MSPI transfer directions
152  */
153 enum mspi_xfer_direction {
154 	MSPI_RX,
155 	MSPI_TX,
156 };
157 
158 /**
159  * @brief MSPI controller device specific configuration mask
160  */
161 enum mspi_dev_cfg_mask {
162 	MSPI_DEVICE_CONFIG_NONE         = 0,
163 	MSPI_DEVICE_CONFIG_CE_NUM       = BIT(0),
164 	MSPI_DEVICE_CONFIG_FREQUENCY    = BIT(1),
165 	MSPI_DEVICE_CONFIG_IO_MODE      = BIT(2),
166 	MSPI_DEVICE_CONFIG_DATA_RATE    = BIT(3),
167 	MSPI_DEVICE_CONFIG_CPP          = BIT(4),
168 	MSPI_DEVICE_CONFIG_ENDIAN       = BIT(5),
169 	MSPI_DEVICE_CONFIG_CE_POL       = BIT(6),
170 	MSPI_DEVICE_CONFIG_DQS          = BIT(7),
171 	MSPI_DEVICE_CONFIG_RX_DUMMY     = BIT(8),
172 	MSPI_DEVICE_CONFIG_TX_DUMMY     = BIT(9),
173 	MSPI_DEVICE_CONFIG_READ_CMD     = BIT(10),
174 	MSPI_DEVICE_CONFIG_WRITE_CMD    = BIT(11),
175 	MSPI_DEVICE_CONFIG_CMD_LEN      = BIT(12),
176 	MSPI_DEVICE_CONFIG_ADDR_LEN     = BIT(13),
177 	MSPI_DEVICE_CONFIG_MEM_BOUND    = BIT(14),
178 	MSPI_DEVICE_CONFIG_BREAK_TIME   = BIT(15),
179 	MSPI_DEVICE_CONFIG_ALL          = BIT_MASK(16),
180 };
181 
182 /**
183  * @brief MSPI XIP access permissions
184  */
185 enum mspi_xip_permit {
186 	MSPI_XIP_READ_WRITE     = 0,
187 	MSPI_XIP_READ_ONLY      = 1,
188 };
189 
190 /**
191  * @brief MSPI Configure API
192  * @defgroup mspi_configure_api MSPI Configure API
193  * @{
194  */
195 
196 /**
197  * @brief Stub for timing parameter
198  */
199 enum mspi_timing_param {
200 	MSPI_TIMING_PARAM_DUMMY
201 };
202 
203 /**
204  * @brief Stub for struct timing_cfg
205  */
206 struct mspi_timing_cfg {
207 #ifdef __cplusplus
208 	/* For C++ compatibility. */
209 	uint8_t dummy;
210 #endif
211 };
212 
213 /**
214  * @brief MSPI device ID
215  * The controller can identify its devices and determine whether the access is
216  * allowed in a multiple device scheme.
217  */
218 struct mspi_dev_id {
219 	/** @brief device gpio ce */
220 	struct gpio_dt_spec     ce;
221 	/** @brief device index on DT */
222 	uint16_t                dev_idx;
223 };
224 
225 /**
226  * @brief MSPI controller configuration
227  */
228 struct mspi_cfg {
229 	/** @brief mspi channel number */
230 	uint8_t                 channel_num;
231 	/** @brief Configure operation mode */
232 	enum mspi_op_mode       op_mode;
233 	/** @brief Configure duplex mode */
234 	enum mspi_duplex        duplex;
235 	/** @brief DQS support flag */
236 	bool                    dqs_support;
237 	/** @brief Software managed multi peripheral enable */
238 	bool                    sw_multi_periph;
239 	/** @brief GPIO chip select lines (optional) */
240 	struct gpio_dt_spec     *ce_group;
241 	/** @brief GPIO chip-select line numbers (optional) */
242 	uint32_t                num_ce_gpios;
243 	/** @brief Peripheral number from 0 to host controller peripheral limit. */
244 	uint32_t                num_periph;
245 	/** @brief Maximum supported frequency in MHz */
246 	uint32_t                max_freq;
247 	/** @brief Whether to re-initialize controller */
248 	bool                    re_init;
249 };
250 
251 /**
252  * @brief MSPI DT information
253  */
254 struct mspi_dt_spec {
255 	/** @brief MSPI bus */
256 	const struct device     *bus;
257 	/** @brief MSPI hardware specific configuration */
258 	struct mspi_cfg         config;
259 };
260 
261 /**
262  * @brief MSPI controller device specific configuration
263  */
264 struct mspi_dev_cfg {
265 	/** @brief Configure CE0 or CE1 or more */
266 	uint8_t                 ce_num;
267 	/** @brief Configure frequency */
268 	uint32_t                freq;
269 	/** @brief Configure I/O mode */
270 	enum mspi_io_mode       io_mode;
271 	/** @brief Configure data rate */
272 	enum mspi_data_rate     data_rate;
273 	/** @brief Configure clock polarity and phase */
274 	enum mspi_cpp_mode      cpp;
275 	/** @brief Configure transfer endian */
276 	enum mspi_endian        endian;
277 	/** @brief Configure chip enable polarity */
278 	enum mspi_ce_polarity   ce_polarity;
279 	/** @brief Configure DQS mode */
280 	bool                    dqs_enable;
281 	/** @brief Configure number of clock cycles between
282 	 * addr and data in RX direction
283 	 */
284 	uint16_t                rx_dummy;
285 	/** @brief Configure number of clock cycles between
286 	 * addr and data in TX direction
287 	 */
288 	uint16_t                tx_dummy;
289 	/** @brief Configure read command       */
290 	uint32_t                read_cmd;
291 	/** @brief Configure write command      */
292 	uint32_t                write_cmd;
293 	/** @brief Configure command length     */
294 	uint8_t                 cmd_length;
295 	/** @brief Configure address length     */
296 	uint8_t                 addr_length;
297 	/** @brief Configure memory boundary    */
298 	uint32_t                mem_boundary;
299 	/** @brief Configure the time to break up a transfer into 2 */
300 	uint32_t                time_to_break;
301 };
302 
303 /**
304  * @brief MSPI controller XIP configuration
305  */
306 struct mspi_xip_cfg {
307 	/** @brief XIP enable */
308 	bool                    enable;
309 	/** @brief XIP region start address =
310 	 * hardware default + address offset
311 	 */
312 	uint32_t                address_offset;
313 	/** @brief XIP region size */
314 	uint32_t                size;
315 	/** @brief XIP access permission */
316 	enum mspi_xip_permit    permission;
317 };
318 
319 /**
320  * @brief MSPI controller scramble configuration
321  */
322 struct mspi_scramble_cfg {
323 	/** @brief scramble enable */
324 	bool                    enable;
325 	/** @brief scramble region start address =
326 	 * hardware default + address offset
327 	 */
328 	uint32_t                address_offset;
329 	/** @brief scramble region size */
330 	uint32_t                size;
331 };
332 
333 /** @} */
334 
335 /**
336  * @brief MSPI Transfer API
337  * @defgroup mspi_transfer_api MSPI Transfer API
338  * @{
339  */
340 
341 /**
342  * @brief MSPI Chip Select control structure
343  *
344  * This can be used to control a CE line via a GPIO line, instead of
345  * using the controller inner CE logic.
346  *
347  */
348 struct mspi_ce_control {
349 	/**
350 	 * @brief GPIO devicetree specification of CE GPIO.
351 	 * The device pointer can be set to NULL to fully inhibit CE control if
352 	 * necessary. The GPIO flags GPIO_ACTIVE_LOW/GPIO_ACTIVE_HIGH should be
353 	 * the same as in MSPI configuration.
354 	 */
355 	struct gpio_dt_spec         gpio;
356 	/**
357 	 * @brief Delay to wait.
358 	 * In microseconds before starting the
359 	 * transmission and before releasing the CE line.
360 	 */
361 	uint32_t                    delay;
362 };
363 
364 /**
365  * @brief MSPI peripheral xfer packet format
366  */
367 struct mspi_xfer_packet {
368 	/** @brief  Direction (Transmit/Receive) */
369 	enum mspi_xfer_direction    dir;
370 	/** @brief  Bus event callback masks     */
371 	enum mspi_bus_event_cb_mask cb_mask;
372 	/** @brief  Transfer command             */
373 	uint32_t                    cmd;
374 	/** @brief  Transfer Address             */
375 	uint32_t                    address;
376 	/** @brief  Number of bytes to transfer  */
377 	uint32_t                    num_bytes;
378 	/** @brief  Data Buffer                  */
379 	uint8_t                     *data_buf;
380 };
381 
382 /**
383  * @brief MSPI peripheral xfer format
384  * This includes transfer related settings that may
385  * require configuring the hardware.
386  */
387 struct mspi_xfer {
388 	/** @brief  Async or sync transfer       */
389 	bool                        async;
390 	/** @brief  Transfer Mode                */
391 	enum mspi_xfer_mode         xfer_mode;
392 	/** @brief  Configure TX dummy cycles    */
393 	uint16_t                    tx_dummy;
394 	/** @brief  Configure RX dummy cycles    */
395 	uint16_t                    rx_dummy;
396 	/** @brief  Configure command length     */
397 	uint8_t                     cmd_length;
398 	/** @brief  Configure address length     */
399 	uint8_t                     addr_length;
400 	/** @brief  Hold CE active after xfer    */
401 	bool                        hold_ce;
402 	/** @brief  Software CE control          */
403 	struct mspi_ce_control      ce_sw_ctrl;
404 	/** @brief  Priority 0 = Low (best effort)
405 	 *                   1 = High (service immediately)
406 	 */
407 	uint8_t                     priority;
408 	/** @brief  Transfer packets             */
409 	const struct mspi_xfer_packet *packets;
410 	/** @brief  Number of transfer packets   */
411 	uint32_t                    num_packet;
412 	/** @brief  Transfer timeout value       */
413 	uint32_t                    timeout;
414 };
415 
416 /** @} */
417 
418 /**
419  * @brief MSPI callback API
420  * @defgroup mspi_callback_api MSPI callback API
421  * @{
422  */
423 
424 /**
425  * @brief MSPI event data
426  */
427 struct mspi_event_data {
428 	/** @brief Pointer to the bus controller */
429 	const struct device         *controller;
430 	/** @brief Pointer to the peripheral device ID */
431 	const struct mspi_dev_id    *dev_id;
432 	/** @brief Pointer to a transfer packet */
433 	const struct mspi_xfer_packet *packet;
434 	/** @brief MSPI event status */
435 	uint32_t                    status;
436 	/** @brief Packet index */
437 	uint32_t                    packet_idx;
438 };
439 
440 /**
441  * @brief MSPI event
442  */
443 struct mspi_event {
444 	/** Event type */
445 	enum mspi_bus_event         evt_type;
446 	/** Data associated to the event */
447 	struct mspi_event_data      evt_data;
448 };
449 
450 /**
451  * @brief MSPI callback context
452  */
453 struct mspi_callback_context {
454 	/** @brief MSPI event  */
455 	struct mspi_event           mspi_evt;
456 	/** @brief user defined context */
457 	void                        *ctx;
458 };
459 
460 /**
461  * @typedef mspi_callback_handler_t
462  * @brief Define the application callback handler function signature.
463  *
464  * @param mspi_cb_ctx Pointer to the MSPI callback context
465  *
466  */
467 typedef void (*mspi_callback_handler_t)(struct mspi_callback_context *mspi_cb_ctx, ...);
468 
469 /** @} */
470 
471 /**
472  * MSPI driver API definition and system call entry points
473  */
474 typedef int (*mspi_api_config)(const struct mspi_dt_spec *spec);
475 
476 typedef int (*mspi_api_dev_config)(const struct device *controller,
477 				   const struct mspi_dev_id *dev_id,
478 				   const enum mspi_dev_cfg_mask param_mask,
479 				   const struct mspi_dev_cfg *cfg);
480 
481 typedef int (*mspi_api_get_channel_status)(const struct device *controller, uint8_t ch);
482 
483 typedef int (*mspi_api_transceive)(const struct device *controller,
484 				   const struct mspi_dev_id *dev_id,
485 				   const struct mspi_xfer *req);
486 
487 typedef int (*mspi_api_register_callback)(const struct device *controller,
488 					  const struct mspi_dev_id *dev_id,
489 					  const enum mspi_bus_event evt_type,
490 					  mspi_callback_handler_t cb,
491 					  struct mspi_callback_context *ctx);
492 
493 typedef int (*mspi_api_xip_config)(const struct device *controller,
494 				   const struct mspi_dev_id *dev_id,
495 				   const struct mspi_xip_cfg *xip_cfg);
496 
497 typedef int (*mspi_api_scramble_config)(const struct device *controller,
498 					const struct mspi_dev_id *dev_id,
499 					const struct mspi_scramble_cfg *scramble_cfg);
500 
501 typedef int (*mspi_api_timing_config)(const struct device *controller,
502 				      const struct mspi_dev_id *dev_id, const uint32_t param_mask,
503 				      void *timing_cfg);
504 
505 __subsystem struct mspi_driver_api {
506 	mspi_api_config                config;
507 	mspi_api_dev_config            dev_config;
508 	mspi_api_get_channel_status    get_channel_status;
509 	mspi_api_transceive            transceive;
510 	mspi_api_register_callback     register_callback;
511 	mspi_api_xip_config            xip_config;
512 	mspi_api_scramble_config       scramble_config;
513 	mspi_api_timing_config         timing_config;
514 };
515 
516 /**
517  * @addtogroup mspi_configure_api
518  * @{
519  */
520 
521 /**
522  * @brief Configure a MSPI controller.
523  *
524  * This routine provides a generic interface to override MSPI controller
525  * capabilities.
526  *
527  * In the controller driver, one may implement this API to initialize or
528  * re-initialize their controller hardware. Additional SoC platform specific
529  * settings that are not in struct mspi_cfg may be added to one's own
530  * binding(xxx,mspi-controller.yaml) so that one may derive the settings from
531  * DTS and configure it in this API. In general, these settings should not
532  * change during run-time. The bindings for @see mspi_cfg can be found in
533  * mspi-controller.yaml.
534  *
535  * @param spec Pointer to MSPI DT information.
536  *
537  * @retval 0 If successful.
538  * @retval -EIO General input / output error, failed to configure device.
539  * @retval -EINVAL invalid capabilities, failed to configure device.
540  * @retval -ENOTSUP capability not supported by MSPI peripheral.
541  */
542 __syscall int mspi_config(const struct mspi_dt_spec *spec);
543 
z_impl_mspi_config(const struct mspi_dt_spec * spec)544 static inline int z_impl_mspi_config(const struct mspi_dt_spec *spec)
545 {
546 	const struct mspi_driver_api *api = (const struct mspi_driver_api *)spec->bus->api;
547 
548 	return api->config(spec);
549 }
550 
551 /**
552  * @brief Configure a MSPI controller with device specific parameters.
553  *
554  * This routine provides a generic interface to override MSPI controller
555  * device specific settings that should be derived from device datasheets.
556  *
557  * With @see mspi_dev_id defined as the device index and CE GPIO from device
558  * tree, the API supports multiple devices on the same controller instance.
559  * It is up to the controller driver implementation whether to support device
560  * switching either by software or by hardware or not at all. If by software,
561  * the switching should be done in this API's implementation.
562  * The implementation may also support individual parameter configurations
563  * specified by @see mspi_dev_cfg_mask.
564  * The settings within @see mspi_dev_cfg don't typically change once the mode
565  * of operation is determined after the device initialization.
566  * The bindings for @see mspi_dev_cfg can be found in mspi-device.yaml.
567  *
568  * @param controller Pointer to the device structure for the driver instance.
569  * @param dev_id Pointer to the device ID structure from a device.
570  * @param param_mask Macro definition of what to be configured in cfg.
571  * @param cfg The device runtime configuration for the MSPI controller.
572  *
573  * @retval 0 If successful.
574  * @retval -EIO General input / output error, failed to configure device.
575  * @retval -EINVAL invalid capabilities, failed to configure device.
576  * @retval -ENOTSUP capability not supported by MSPI peripheral.
577  */
578 __syscall int mspi_dev_config(const struct device *controller,
579 			      const struct mspi_dev_id *dev_id,
580 			      const enum mspi_dev_cfg_mask param_mask,
581 			      const struct mspi_dev_cfg *cfg);
582 
z_impl_mspi_dev_config(const struct device * controller,const struct mspi_dev_id * dev_id,const enum mspi_dev_cfg_mask param_mask,const struct mspi_dev_cfg * cfg)583 static inline int z_impl_mspi_dev_config(const struct device *controller,
584 					 const struct mspi_dev_id *dev_id,
585 					 const enum mspi_dev_cfg_mask param_mask,
586 					 const struct mspi_dev_cfg *cfg)
587 {
588 	const struct mspi_driver_api *api = (const struct mspi_driver_api *)controller->api;
589 
590 	return api->dev_config(controller, dev_id, param_mask, cfg);
591 }
592 
593 /**
594  * @brief Query to see if it a channel is ready.
595  *
596  * This routine allows to check if logical channel is ready before use.
597  * Note that queries for channels not supported will always return false.
598  *
599  * @param controller Pointer to the device structure for the driver instance.
600  * @param ch the MSPI channel for which status is to be retrieved.
601  *
602  * @retval 0 If MSPI channel is ready.
603  */
604 __syscall int mspi_get_channel_status(const struct device *controller, uint8_t ch);
605 
z_impl_mspi_get_channel_status(const struct device * controller,uint8_t ch)606 static inline int z_impl_mspi_get_channel_status(const struct device *controller, uint8_t ch)
607 {
608 	const struct mspi_driver_api *api = (const struct mspi_driver_api *)controller->api;
609 
610 	return api->get_channel_status(controller, ch);
611 }
612 
613 /** @} */
614 
615 /**
616  * @addtogroup mspi_transfer_api
617  * @{
618  */
619 
620 /**
621  * @brief Transfer request over MSPI.
622  *
623  * This routines provides a generic interface to transfer a request
624  * synchronously/asynchronously.
625  *
626  * The @see mspi_xfer allows for dynamically changing the transfer related
627  * settings once the mode of operation is determined and configured.
628  * The API supports bulk transfers with different starting addresses and sizes
629  * with @see mspi_xfer_packet. However, it is up to the controller
630  * implementation whether to support scatter IO and callback management.
631  * The controller can determine which user callback to trigger based on
632  * @see mspi_bus_event_cb_mask upon completion of each async/sync transfer
633  * if the callback had been registered. Or not to trigger any callback at all
634  * with MSPI_BUS_NO_CB even if the callbacks are already registered.
635  *
636  * @param controller Pointer to the device structure for the driver instance.
637  * @param dev_id Pointer to the device ID structure from a device.
638  * @param req Content of the request and request specific settings.
639  *
640  * @retval 0 If successful.
641  * @retval -ENOTSUP
642  * @retval -EIO General input / output error, failed to send over the bus.
643  */
644 __syscall int mspi_transceive(const struct device *controller,
645 			      const struct mspi_dev_id *dev_id,
646 			      const struct mspi_xfer *req);
647 
z_impl_mspi_transceive(const struct device * controller,const struct mspi_dev_id * dev_id,const struct mspi_xfer * req)648 static inline int z_impl_mspi_transceive(const struct device *controller,
649 					 const struct mspi_dev_id *dev_id,
650 					 const struct mspi_xfer *req)
651 {
652 	const struct mspi_driver_api *api = (const struct mspi_driver_api *)controller->api;
653 
654 	if (!api->transceive) {
655 		return -ENOTSUP;
656 	}
657 
658 	return api->transceive(controller, dev_id, req);
659 }
660 
661 /** @} */
662 
663 /**
664  * @addtogroup mspi_configure_api
665  * @{
666  */
667 
668 /**
669  * @brief Configure a MSPI XIP settings.
670  *
671  * This routine provides a generic interface to configure the XIP feature.
672  *
673  * @param controller Pointer to the device structure for the driver instance.
674  * @param dev_id Pointer to the device ID structure from a device.
675  * @param cfg The controller XIP configuration for MSPI.
676  *
677  * @retval 0 If successful.
678  * @retval -EIO General input / output error, failed to configure device.
679  * @retval -EINVAL invalid capabilities, failed to configure device.
680  * @retval -ENOTSUP capability not supported by MSPI peripheral.
681  */
682 __syscall int mspi_xip_config(const struct device *controller,
683 			      const struct mspi_dev_id *dev_id,
684 			      const struct mspi_xip_cfg *cfg);
685 
z_impl_mspi_xip_config(const struct device * controller,const struct mspi_dev_id * dev_id,const struct mspi_xip_cfg * cfg)686 static inline int z_impl_mspi_xip_config(const struct device *controller,
687 					 const struct mspi_dev_id *dev_id,
688 					 const struct mspi_xip_cfg *cfg)
689 {
690 	const struct mspi_driver_api *api = (const struct mspi_driver_api *)controller->api;
691 
692 	if (!api->xip_config) {
693 		return -ENOTSUP;
694 	}
695 
696 	return api->xip_config(controller, dev_id, cfg);
697 }
698 
699 /**
700  * @brief Configure a MSPI scrambling settings.
701  *
702  * This routine provides a generic interface to configure the scrambling
703  * feature.
704  *
705  * @param controller Pointer to the device structure for the driver instance.
706  * @param dev_id Pointer to the device ID structure from a device.
707  * @param cfg The controller scramble configuration for MSPI.
708  *
709  * @retval 0 If successful.
710  * @retval -EIO General input / output error, failed to configure device.
711  * @retval -EINVAL invalid capabilities, failed to configure device.
712  * @retval -ENOTSUP capability not supported by MSPI peripheral.
713  */
714 __syscall int mspi_scramble_config(const struct device *controller,
715 				   const struct mspi_dev_id *dev_id,
716 				   const struct mspi_scramble_cfg *cfg);
717 
z_impl_mspi_scramble_config(const struct device * controller,const struct mspi_dev_id * dev_id,const struct mspi_scramble_cfg * cfg)718 static inline int z_impl_mspi_scramble_config(const struct device *controller,
719 					      const struct mspi_dev_id *dev_id,
720 					      const struct mspi_scramble_cfg *cfg)
721 {
722 	const struct mspi_driver_api *api = (const struct mspi_driver_api *)controller->api;
723 
724 	if (!api->scramble_config) {
725 		return -ENOTSUP;
726 	}
727 
728 	return api->scramble_config(controller, dev_id, cfg);
729 }
730 
731 /**
732  * @brief Configure a MSPI timing settings.
733  *
734  * This routine provides a generic interface to configure MSPI controller
735  * timing if necessary.
736  *
737  * @param controller Pointer to the device structure for the driver instance.
738  * @param dev_id Pointer to the device ID structure from a device.
739  * @param param_mask The macro definition of what should be configured in cfg.
740  * @param cfg The controller timing configuration for MSPI.
741  *
742  * @retval 0 If successful.
743  * @retval -EIO General input / output error, failed to configure device.
744  * @retval -EINVAL invalid capabilities, failed to configure device.
745  * @retval -ENOTSUP capability not supported by MSPI peripheral.
746  */
747 __syscall int mspi_timing_config(const struct device *controller,
748 				 const struct mspi_dev_id *dev_id,
749 				 const uint32_t param_mask, void *cfg);
750 
z_impl_mspi_timing_config(const struct device * controller,const struct mspi_dev_id * dev_id,const uint32_t param_mask,void * cfg)751 static inline int z_impl_mspi_timing_config(const struct device *controller,
752 					    const struct mspi_dev_id *dev_id,
753 					    const uint32_t param_mask, void *cfg)
754 {
755 	const struct mspi_driver_api *api = (const struct mspi_driver_api *)controller->api;
756 
757 	if (!api->timing_config) {
758 		return -ENOTSUP;
759 	}
760 
761 	return api->timing_config(controller, dev_id, param_mask, cfg);
762 }
763 
764 /** @} */
765 
766 /**
767  * @addtogroup mspi_callback_api
768  * @{
769  */
770 
771 /**
772  * @brief Register the mspi callback functions.
773  *
774  * This routines provides a generic interface to register mspi callback functions.
775  * In generally it should be called before mspi_transceive.
776  *
777  * @param controller Pointer to the device structure for the driver instance.
778  * @param dev_id Pointer to the device ID structure from a device.
779  * @param evt_type The event type associated the callback.
780  * @param cb Pointer to the user implemented callback function.
781  * @param ctx Pointer to the callback context.
782  *
783  * @retval 0 If successful.
784  * @retval -ENOTSUP
785  */
mspi_register_callback(const struct device * controller,const struct mspi_dev_id * dev_id,const enum mspi_bus_event evt_type,mspi_callback_handler_t cb,struct mspi_callback_context * ctx)786 static inline int mspi_register_callback(const struct device *controller,
787 					 const struct mspi_dev_id *dev_id,
788 					 const enum mspi_bus_event evt_type,
789 					 mspi_callback_handler_t cb,
790 					 struct mspi_callback_context *ctx)
791 {
792 	const struct mspi_driver_api *api = (const struct mspi_driver_api *)controller->api;
793 
794 	if (!api->register_callback) {
795 		return -ENOTSUP;
796 	}
797 
798 	return api->register_callback(controller, dev_id, evt_type, cb, ctx);
799 }
800 
801 /** @} */
802 
803 #ifdef __cplusplus
804 }
805 #endif
806 
807 #include <zephyr/drivers/mspi/devicetree.h>
808 
809 /**
810  * @}
811  */
812 #include <zephyr/syscalls/mspi.h>
813 #endif /* ZEPHYR_INCLUDE_MSPI_H_ */
814