1 /*
2  * Copyright (c) 2017 Piotr Mienkowski
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Public APIs for the I2S (Inter-IC Sound) bus drivers.
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_I2S_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_I2S_H_
14 
15 /**
16  * @defgroup i2s_interface I2S Interface
17  * @ingroup io_interfaces
18  * @brief I2S (Inter-IC Sound) Interface
19  *
20  * The I2S API provides support for the standard I2S interface standard as well
21  * as common non-standard extensions such as PCM Short/Long Frame Sync,
22  * Left/Right Justified Data Format.
23  * @{
24  */
25 
26 #include <zephyr/types.h>
27 #include <device.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /*
34  * The following #defines are used to configure the I2S controller.
35  */
36 
37 
38 typedef uint8_t i2s_fmt_t;
39 
40 /** Data Format bit field position. */
41 #define I2S_FMT_DATA_FORMAT_SHIFT           0
42 /** Data Format bit field mask. */
43 #define I2S_FMT_DATA_FORMAT_MASK            (0x7 << I2S_FMT_DATA_FORMAT_SHIFT)
44 
45 /** @brief Standard I2S Data Format.
46  *
47  * Serial data is transmitted in two's complement with the MSB first. Both
48  * Word Select (WS) and Serial Data (SD) signals are sampled on the rising edge
49  * of the clock signal (SCK). The MSB is always sent one clock period after the
50  * WS changes. Left channel data are sent first indicated by WS = 0, followed
51  * by right channel data indicated by WS = 1.
52  *
53  *        -. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-.
54  *     SCK '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '
55  *        -.                               .-------------------------------.
56  *     WS  '-------------------------------'                               '----
57  *        -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
58  *     SD  |   |MSB|   |...|   |LSB| x |...| x |MSB|   |...|   |LSB| x |...| x |
59  *        -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'
60  *             | Left channel                  | Right channel                 |
61  */
62 #define I2S_FMT_DATA_FORMAT_I2S             (0 << I2S_FMT_DATA_FORMAT_SHIFT)
63 
64 /** @brief PCM Short Frame Sync Data Format.
65  *
66  * Serial data is transmitted in two's complement with the MSB first. Both
67  * Word Select (WS) and Serial Data (SD) signals are sampled on the falling edge
68  * of the clock signal (SCK). The falling edge of the frame sync signal (WS)
69  * indicates the start of the PCM word. The frame sync is one clock cycle long.
70  * An arbitrary number of data words can be sent in one frame.
71  *
72  *          .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-.
73  *     SCK -' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-
74  *          .---.                                                       .---.
75  *     WS  -'   '-                                                     -'   '-
76  *         -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---
77  *     SD   |   |MSB|   |...|   |LSB|MSB|   |...|   |LSB|MSB|   |...|   |LSB|
78  *         -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---
79  *              | Word 1            | Word 2            | Word 3  |  Word n |
80  */
81 #define I2S_FMT_DATA_FORMAT_PCM_SHORT       (1 << I2S_FMT_DATA_FORMAT_SHIFT)
82 
83 /** @brief PCM Long Frame Sync Data Format.
84  *
85  * Serial data is transmitted in two's complement with the MSB first. Both
86  * Word Select (WS) and Serial Data (SD) signals are sampled on the falling edge
87  * of the clock signal (SCK). The rising edge of the frame sync signal (WS)
88  * indicates the start of the PCM word. The frame sync has an arbitrary length,
89  * however it has to fall before the start of the next frame. An arbitrary
90  * number of data words can be sent in one frame.
91  *
92  *          .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-.
93  *     SCK -' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-
94  *              .--- ---.    ---.        ---.                               .---
95  *     WS      -'       '-      '-          '-                             -'
96  *         -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---
97  *     SD   |   |MSB|   |...|   |LSB|MSB|   |...|   |LSB|MSB|   |...|   |LSB|
98  *         -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---
99  *              | Word 1            | Word 2            | Word 3  |  Word n |
100  */
101 #define I2S_FMT_DATA_FORMAT_PCM_LONG        (2 << I2S_FMT_DATA_FORMAT_SHIFT)
102 
103 /**
104  * @brief Left Justified Data Format.
105  *
106  * Serial data is transmitted in two's complement with the MSB first. Both
107  * Word Select (WS) and Serial Data (SD) signals are sampled on the rising edge
108  * of the clock signal (SCK). The bits within the data word are left justified
109  * such that the MSB is always sent in the clock period following the WS
110  * transition. Left channel data are sent first indicated by WS = 1, followed
111  * by right channel data indicated by WS = 0.
112  *
113  *          .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-.
114  *     SCK -' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-
115  *            .-------------------------------.                               .-
116  *     WS  ---'                               '-------------------------------'
117  *         ---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.-
118  *     SD     |MSB|   |...|   |LSB| x |...| x |MSB|   |...|   |LSB| x |...| x |
119  *         ---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'-
120  *            | Left channel                  | Right channel                 |
121  */
122 #define I2S_FMT_DATA_FORMAT_LEFT_JUSTIFIED  (3 << I2S_FMT_DATA_FORMAT_SHIFT)
123 
124 /**
125  * @brief Right Justified Data Format.
126  *
127  * Serial data is transmitted in two's complement with the MSB first. Both
128  * Word Select (WS) and Serial Data (SD) signals are sampled on the rising edge
129  * of the clock signal (SCK). The bits within the data word are right justified
130  * such that the LSB is always sent in the clock period preceding the WS
131  * transition. Left channel data are sent first indicated by WS = 1, followed
132  * by right channel data indicated by WS = 0.
133  *
134  *          .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-.
135  *     SCK -' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-
136  *            .-------------------------------.                               .-
137  *     WS  ---'                               '-------------------------------'
138  *         ---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.-
139  *     SD     | x |...| x |MSB|   |...|   |LSB| x |...| x |MSB|   |...|   |LSB|
140  *         ---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'-
141  *            | Left channel                  | Right channel                 |
142  */
143 #define I2S_FMT_DATA_FORMAT_RIGHT_JUSTIFIED (4 << I2S_FMT_DATA_FORMAT_SHIFT)
144 
145 /** Send MSB first */
146 #define I2S_FMT_DATA_ORDER_MSB              (0 << 3)
147 /** Send LSB first */
148 #define I2S_FMT_DATA_ORDER_LSB              BIT(3)
149 /** Invert bit ordering, send LSB first */
150 #define I2S_FMT_DATA_ORDER_INV              I2S_FMT_DATA_ORDER_LSB
151 
152 /** Data Format bit field position. */
153 #define I2S_FMT_CLK_FORMAT_SHIFT           4
154 /** Data Format bit field mask. */
155 #define I2S_FMT_CLK_FORMAT_MASK            (0x3 << I2S_FMT_CLK_FORMAT_SHIFT)
156 
157 /** Invert bit clock */
158 #define I2S_FMT_BIT_CLK_INV                 BIT(4)
159 /** Invert frame clock */
160 #define I2S_FMT_FRAME_CLK_INV               BIT(5)
161 
162 /** NF represents "Normal Frame" whereas IF represents "Inverted Frame"
163  *  NB represents "Normal Bit Clk" whereas IB represents "Inverted Bit clk"
164  */
165 #define I2S_FMT_CLK_NF_NB		(0 << I2S_FMT_CLK_FORMAT_SHIFT)
166 #define I2S_FMT_CLK_NF_IB		(1 << I2S_FMT_CLK_FORMAT_SHIFT)
167 #define I2S_FMT_CLK_IF_NB		(2 << I2S_FMT_CLK_FORMAT_SHIFT)
168 #define I2S_FMT_CLK_IF_IB		(3 << I2S_FMT_CLK_FORMAT_SHIFT)
169 
170 typedef uint8_t i2s_opt_t;
171 
172 /** Run bit clock continuously */
173 #define I2S_OPT_BIT_CLK_CONT                (0 << 0)
174 /** Run bit clock when sending data only */
175 #define I2S_OPT_BIT_CLK_GATED               BIT(0)
176 /** I2S driver is bit clock master */
177 #define I2S_OPT_BIT_CLK_MASTER              (0 << 1)
178 /** I2S driver is bit clock slave */
179 #define I2S_OPT_BIT_CLK_SLAVE               BIT(1)
180 /** I2S driver is frame clock master */
181 #define I2S_OPT_FRAME_CLK_MASTER            (0 << 2)
182 /** I2S driver is frame clock slave */
183 #define I2S_OPT_FRAME_CLK_SLAVE             BIT(2)
184 
185 /** @brief Loop back mode.
186  *
187  * In loop back mode RX input will be connected internally to TX output.
188  * This is used primarily for testing.
189  */
190 #define I2S_OPT_LOOPBACK                    BIT(7)
191 
192 /** @brief Ping pong mode
193  *
194  * In ping pong mode TX output will keep alternating between a ping buffer
195  * and a pong buffer. This is normally used in audio streams when one buffer
196  * is being populated while the other is being played (DMAed) and vice versa.
197  * So, in this mode, 2 sets of buffers fixed in size are used. Static Arrays
198  * are used to achieve this and hence they are never freed.
199  */
200 #define I2S_OPT_PINGPONG                    BIT(6)
201 
202 /**
203  * @brief I2C Direction
204  */
205 enum i2s_dir {
206 	/** Receive data */
207 	I2S_DIR_RX,
208 	/** Transmit data */
209 	I2S_DIR_TX,
210 	/** Both receive and transmit data */
211 	I2S_DIR_BOTH,
212 };
213 
214 /** Interface state */
215 enum i2s_state {
216 	/** @brief The interface is not ready.
217 	 *
218 	 * The interface was initialized but is not yet ready to receive /
219 	 * transmit data. Call i2s_configure() to configure interface and change
220 	 * its state to READY.
221 	 */
222 	I2S_STATE_NOT_READY,
223 	/** The interface is ready to receive / transmit data. */
224 	I2S_STATE_READY,
225 	/** The interface is receiving / transmitting data. */
226 	I2S_STATE_RUNNING,
227 	/** The interface is draining its transmit queue. */
228 	I2S_STATE_STOPPING,
229 	/** TX buffer underrun or RX buffer overrun has occurred. */
230 	I2S_STATE_ERROR,
231 };
232 
233 /** Trigger command */
234 enum i2s_trigger_cmd {
235 	/** @brief Start the transmission / reception of data.
236 	 *
237 	 * If I2S_DIR_TX is set some data has to be queued for transmission by
238 	 * the i2s_write() function. This trigger can be used in READY state
239 	 * only and changes the interface state to RUNNING.
240 	 */
241 	I2S_TRIGGER_START,
242 	/** @brief Stop the transmission / reception of data.
243 	 *
244 	 * Stop the transmission / reception of data at the end of the current
245 	 * memory block. This trigger can be used in RUNNING state only and at
246 	 * first changes the interface state to STOPPING. When the current TX /
247 	 * RX block is transmitted / received the state is changed to READY.
248 	 * Subsequent START trigger will resume transmission / reception where
249 	 * it stopped.
250 	 */
251 	I2S_TRIGGER_STOP,
252 	/** @brief Empty the transmit queue.
253 	 *
254 	 * Send all data in the transmit queue and stop the transmission.
255 	 * If the trigger is applied to the RX queue it has the same effect as
256 	 * I2S_TRIGGER_STOP. This trigger can be used in RUNNING state only and
257 	 * at first changes the interface state to STOPPING. When all TX blocks
258 	 * are transmitted the state is changed to READY.
259 	 */
260 	I2S_TRIGGER_DRAIN,
261 	/** @brief Discard the transmit / receive queue.
262 	 *
263 	 * Stop the transmission / reception immediately and discard the
264 	 * contents of the respective queue. This trigger can be used in any
265 	 * state other than NOT_READY and changes the interface state to READY.
266 	 */
267 	I2S_TRIGGER_DROP,
268 	/** @brief Prepare the queues after underrun/overrun error has occurred.
269 	 *
270 	 * This trigger can be used in ERROR state only and changes the
271 	 * interface state to READY.
272 	 */
273 	I2S_TRIGGER_PREPARE,
274 };
275 
276 /** @struct i2s_config
277  * @brief Interface configuration options.
278  *
279  * Memory slab pointed to by the mem_slab field has to be defined and
280  * initialized by the user. For I2S driver to function correctly number of
281  * memory blocks in a slab has to be at least 2 per queue. Size of the memory
282  * block should be multiple of frame_size where frame_size = (channels *
283  * word_size_bytes). As an example 16 bit word will occupy 2 bytes, 24 or 32
284  * bit word will occupy 4 bytes.
285  *
286  * Please check Zephyr Kernel Primer for more information on memory slabs.
287  *
288  * @remark When I2S data format is selected parameter channels is ignored,
289  * number of words in a frame is always 2.
290  *
291  * @param word_size Number of bits representing one data word.
292  * @param channels Number of words per frame.
293  * @param format Data stream format as defined by I2S_FMT_* constants.
294  * @param options Configuration options as defined by I2S_OPT_* constants.
295  * @param frame_clk_freq Frame clock (WS) frequency, this is sampling rate.
296  * @param mem_slab memory slab to store RX/TX data.
297  * @param block_size Size of one RX/TX memory block (buffer) in bytes.
298  * @param timeout Read/Write timeout. Number of milliseconds to wait in case TX
299  *        queue is full or RX queue is empty, or 0, or SYS_FOREVER_MS.
300  */
301 struct i2s_config {
302 	uint8_t word_size;
303 	uint8_t channels;
304 	i2s_fmt_t format;
305 	i2s_opt_t options;
306 	uint32_t frame_clk_freq;
307 	struct k_mem_slab *mem_slab;
308 	size_t block_size;
309 	int32_t timeout;
310 };
311 
312 /**
313  * @cond INTERNAL_HIDDEN
314  *
315  * For internal use only, skip these in public documentation.
316  */
317 __subsystem struct i2s_driver_api {
318 	int (*configure)(const struct device *dev, enum i2s_dir dir,
319 			 const struct i2s_config *cfg);
320 	const struct i2s_config *(*config_get)(const struct device *dev,
321 				  enum i2s_dir dir);
322 	int (*read)(const struct device *dev, void **mem_block, size_t *size);
323 	int (*write)(const struct device *dev, void *mem_block, size_t size);
324 	int (*trigger)(const struct device *dev, enum i2s_dir dir,
325 		       enum i2s_trigger_cmd cmd);
326 };
327 /**
328  * @endcond
329  */
330 
331 /**
332  * @brief Configure operation of a host I2S controller.
333  *
334  * The dir parameter specifies if Transmit (TX) or Receive (RX) direction
335  * will be configured by data provided via cfg parameter.
336  *
337  * The function can be called in NOT_READY or READY state only. If executed
338  * successfully the function will change the interface state to READY.
339  *
340  * If the function is called with the parameter cfg->frame_clk_freq set to 0
341  * the interface state will be changed to NOT_READY.
342  *
343  * @param dev Pointer to the device structure for the driver instance.
344  * @param dir Stream direction: RX, TX, or both, as defined by I2S_DIR_*.
345  *            The I2S_DIR_BOTH value may not be supported by some drivers.
346  *            For those, the RX and TX streams need to be configured separately.
347  * @param cfg Pointer to the structure containing configuration parameters.
348  *
349  * @retval 0 If successful.
350  * @retval -EINVAL Invalid argument.
351  * @retval -ENOSYS I2S_DIR_BOTH value is not supported.
352  */
353 __syscall int i2s_configure(const struct device *dev, enum i2s_dir dir,
354 			    const struct i2s_config *cfg);
355 
z_impl_i2s_configure(const struct device * dev,enum i2s_dir dir,const struct i2s_config * cfg)356 static inline int z_impl_i2s_configure(const struct device *dev,
357 				       enum i2s_dir dir,
358 				       const struct i2s_config *cfg)
359 {
360 	const struct i2s_driver_api *api =
361 		(const struct i2s_driver_api *)dev->api;
362 
363 	return api->configure(dev, dir, cfg);
364 }
365 
366 /**
367  * @brief Fetch configuration information of a host I2S controller
368  *
369  * @param dev Pointer to the device structure for the driver instance
370  * @param dir Stream direction: RX or TX as defined by I2S_DIR_*
371  * @retval Pointer to the structure containing configuration parameters,
372  *         or NULL if un-configured
373  */
i2s_config_get(const struct device * dev,enum i2s_dir dir)374 static inline const struct i2s_config *i2s_config_get(const struct device *dev,
375 						      enum i2s_dir dir)
376 {
377 	const struct i2s_driver_api *api =
378 		(const struct i2s_driver_api *)dev->api;
379 
380 	return api->config_get(dev, dir);
381 }
382 
383 /**
384  * @brief Read data from the RX queue.
385  *
386  * Data received by the I2S interface is stored in the RX queue consisting of
387  * memory blocks preallocated by this function from rx_mem_slab (as defined by
388  * i2s_configure). Ownership of the RX memory block is passed on to the user
389  * application which has to release it.
390  *
391  * The data is read in chunks equal to the size of the memory block. If the
392  * interface is in READY state the number of bytes read can be smaller.
393  *
394  * If there is no data in the RX queue the function will block waiting for
395  * the next RX memory block to fill in. This operation can timeout as defined
396  * by i2s_configure. If the timeout value is set to K_NO_WAIT the function
397  * is non-blocking.
398  *
399  * Reading from the RX queue is possible in any state other than NOT_READY.
400  * If the interface is in the ERROR state it is still possible to read all the
401  * valid data stored in RX queue. Afterwards the function will return -EIO
402  * error.
403  *
404  * @param dev Pointer to the device structure for the driver instance.
405  * @param mem_block Pointer to the RX memory block containing received data.
406  * @param size Pointer to the variable storing the number of bytes read.
407  *
408  * @retval 0 If successful.
409  * @retval -EIO The interface is in NOT_READY or ERROR state and there are no
410  *         more data blocks in the RX queue.
411  * @retval -EBUSY Returned without waiting.
412  * @retval -EAGAIN Waiting period timed out.
413  */
i2s_read(const struct device * dev,void ** mem_block,size_t * size)414 static inline int i2s_read(const struct device *dev, void **mem_block,
415 				 size_t *size)
416 {
417 	const struct i2s_driver_api *api =
418 		(const struct i2s_driver_api *)dev->api;
419 
420 	return api->read(dev, mem_block, size);
421 }
422 
423 /**
424  * @brief Read data from the RX queue into a provided buffer
425  *
426  * Data received by the I2S interface is stored in the RX queue consisting of
427  * memory blocks preallocated by this function from rx_mem_slab (as defined by
428  * i2s_configure). Calling this function removes one block from the queue
429  * which is copied into the provided buffer and then freed.
430  *
431  * The provided buffer must be large enough to contain a full memory block
432  * of data, which is parameterized for the channel via i2s_configure().
433  *
434  * This function is otherwise equivalent to i2s_read().
435  *
436  * @param dev Pointer to the device structure for the driver instance.
437  * @param buf Destination buffer for read data, which must be at least the
438  *            as large as the configured memory block size for the RX channel.
439  * @param size Pointer to the variable storing the number of bytes read.
440  *
441  * @retval 0 If successful.
442  * @retval -EIO The interface is in NOT_READY or ERROR state and there are no
443  *         more data blocks in the RX queue.
444  * @retval -EBUSY Returned without waiting.
445  * @retval -EAGAIN Waiting period timed out.
446  */
447 __syscall int i2s_buf_read(const struct device *dev, void *buf, size_t *size);
448 
449 /**
450  * @brief Write data to the TX queue.
451  *
452  * Data to be sent by the I2S interface is stored first in the TX queue. TX
453  * queue consists of memory blocks preallocated by the user from tx_mem_slab
454  * (as defined by i2s_configure). This function takes ownership of the memory
455  * block and will release it when all data are transmitted.
456  *
457  * If there are no free slots in the TX queue the function will block waiting
458  * for the next TX memory block to be send and removed from the queue. This
459  * operation can timeout as defined by i2s_configure. If the timeout value is
460  * set to K_NO_WAIT the function is non-blocking.
461  *
462  * Writing to the TX queue is only possible if the interface is in READY or
463  * RUNNING state.
464  *
465  * @param dev Pointer to the device structure for the driver instance.
466  * @param mem_block Pointer to the TX memory block containing data to be sent.
467  * @param size Number of bytes to write. This value has to be equal or smaller
468  *        than the size of the memory block.
469  *
470  * @retval 0 If successful.
471  * @retval -EIO The interface is not in READY or RUNNING state.
472  * @retval -EBUSY Returned without waiting.
473  * @retval -EAGAIN Waiting period timed out.
474  */
i2s_write(const struct device * dev,void * mem_block,size_t size)475 static inline int i2s_write(const struct device *dev, void *mem_block,
476 			    size_t size)
477 {
478 	const struct i2s_driver_api *api =
479 		(const struct i2s_driver_api *)dev->api;
480 
481 	return api->write(dev, mem_block, size);
482 }
483 
484 /**
485  * @brief Write data to the TX queue from a provided buffer
486  *
487  * This function acquires a memory block from the I2S channel TX queue
488  * and copies the provided data buffer into it. It is otherwise equivalent
489  * to i2s_write().
490  *
491  * @param dev Pointer to the device structure for the driver instance.
492  * @param buf Pointer to a buffer containing the data to transmit.
493  * @param size Number of bytes to write. This value has to be equal or smaller
494  *        than the size of the channel's TX memory block configuration.
495  *
496  * @retval 0 If successful.
497  * @retval -EIO The interface is not in READY or RUNNING state.
498  * @retval -EBUSY Returned without waiting.
499  * @retval -EAGAIN Waiting period timed out.
500  * @retval -ENOMEM No memory in TX slab queue.
501  * @retval -EINVAL Size parameter larger than TX queue memory block.
502  */
503 __syscall int i2s_buf_write(const struct device *dev, void *buf, size_t size);
504 
505 /**
506  * @brief Send a trigger command.
507  *
508  * @param dev Pointer to the device structure for the driver instance.
509  * @param dir Stream direction: RX, TX, or both, as defined by I2S_DIR_*.
510  *            The I2S_DIR_BOTH value may not be supported by some drivers.
511  *            For those, triggering need to be done separately for the RX
512  *            and TX streams.
513  * @param cmd Trigger command.
514  *
515  * @retval 0 If successful.
516  * @retval -EINVAL Invalid argument.
517  * @retval -EIO The trigger cannot be executed in the current state or a DMA
518  *         channel cannot be allocated.
519  * @retval -ENOMEM RX/TX memory block not available.
520  * @retval -ENOSYS I2S_DIR_BOTH value is not supported.
521  */
522 __syscall int i2s_trigger(const struct device *dev, enum i2s_dir dir,
523 			  enum i2s_trigger_cmd cmd);
524 
z_impl_i2s_trigger(const struct device * dev,enum i2s_dir dir,enum i2s_trigger_cmd cmd)525 static inline int z_impl_i2s_trigger(const struct device *dev,
526 				     enum i2s_dir dir,
527 				     enum i2s_trigger_cmd cmd)
528 {
529 	const struct i2s_driver_api *api =
530 		(const struct i2s_driver_api *)dev->api;
531 
532 	return api->trigger(dev, dir, cmd);
533 }
534 
535 /**
536  * @}
537  */
538 
539 #ifdef __cplusplus
540 }
541 #endif
542 
543 #include <syscalls/i2s.h>
544 
545 #endif /* ZEPHYR_INCLUDE_DRIVERS_I2S_H_ */
546