1 /*
2  * Copyright (c) 2020 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _I2S_LITEI2S__H
8 #define _I2S_LITEI2S__H
9 
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/i2s.h>
12 #include <zephyr/devicetree.h>
13 #include <zephyr/kernel.h>
14 
15 /* i2s configuration mask*/
16 #define I2S_CONF_FORMAT_OFFSET 0
17 #define I2S_CONF_SAMPLE_WIDTH_OFFSET 2
18 #define I2S_CONF_LRCK_FREQ_OFFSET 8
19 #define I2S_CONF_FORMAT_MASK (0x3 << I2S_CONF_FORMAT_OFFSET)
20 #define I2S_CONF_SAMPLE_WIDTH_MASK (0x3f << I2S_CONF_SAMPLE_WIDTH_OFFSET)
21 #define I2S_CONF_LRCK_MASK (0xffffff << I2S_CONF_LRCK_FREQ_OFFSET)
22 
23 /* i2s control register options*/
24 #define I2S_ENABLE (1 << 0)
25 #define I2S_FIFO_RESET (1 << 1)
26 /* i2s event*/
27 #define I2S_EV_ENABLE (1 << 0)
28 /* i2s event types*/
29 #define I2S_EV_READY (1 << 0)
30 #define I2S_EV_ERROR (1 << 1)
31 /* i2s rx*/
32 #define I2S_RX_STAT_CHANNEL_CONCATENATED_OFFSET 31
33 #define I2S_RX_STAT_CHANNEL_CONCATENATED_MASK                                  \
34 	(0x1 << I2S_RX_STAT_CHANNEL_CONCATENATED_OFFSET)
35 
36 #define I2S_RX_FIFO_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), fifo)
37 #define I2S_RX_FIFO_DEPTH DT_PROP(DT_NODELABEL(i2s_rx), fifo_depth)
38 
39 /* i2s tx*/
40 #define I2S_TX_STAT_CHANNEL_CONCATENATED_OFFSET 24
41 #define I2S_TX_STAT_CHANNEL_CONCATENATED_MASK                                  \
42 	(0x1 << I2S_TX_STAT_CHANNEL_CONCATENATED_OFFSET)
43 
44 #define I2S_TX_FIFO_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_tx), fifo)
45 #define I2S_TX_FIFO_DEPTH DT_PROP(DT_NODELABEL(i2s_tx), fifo_depth)
46 
47 /* i2s register offsets (they are the same for all i2s nodes, both rx and tx) */
48 #define I2S_BASE_ADDR		DT_REG_ADDR(DT_NODELABEL(i2s_rx))
49 #define I2S_EV_STATUS_OFFSET	(DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_status) \
50 					- I2S_BASE_ADDR)
51 #define I2S_EV_PENDING_OFFSET	(DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_pending) \
52 					- I2S_BASE_ADDR)
53 #define I2S_EV_ENABLE_OFFSET	(DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_enable) \
54 					- I2S_BASE_ADDR)
55 #define I2S_CONTROL_OFFSET	(DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_ctl) \
56 					- I2S_BASE_ADDR)
57 #define I2S_STATUS_OFFSET	(DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_stat) \
58 					- I2S_BASE_ADDR)
59 #define I2S_CONFIG_OFFSET	(DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_conf) \
60 					- I2S_BASE_ADDR)
61 
62 enum litex_i2s_fmt {
63 	LITEX_I2S_STANDARD = 1,
64 	LITEX_I2S_LEFT_JUSTIFIED = 2,
65 };
66 
67 struct queue_item {
68 	void *mem_block;
69 	size_t size;
70 };
71 
72 /* Minimal ring buffer implementation */
73 struct ring_buf {
74 	struct queue_item *buf;
75 	uint16_t len;
76 	uint16_t head;
77 	uint16_t tail;
78 };
79 
80 struct stream {
81 	int32_t state;
82 	struct k_sem sem;
83 	struct i2s_config cfg;
84 	struct ring_buf mem_block_queue;
85 	void *mem_block;
86 };
87 
88 /* Device run time data */
89 struct i2s_litex_data {
90 	struct stream rx;
91 	struct stream tx;
92 };
93 
94 /* Device const configuration */
95 struct i2s_litex_cfg {
96 	uint32_t base;
97 	uint32_t fifo_base;
98 	uint16_t fifo_depth;
99 	void (*irq_config)(const struct device *dev);
100 };
101 
102 #endif /* _I2S_LITEI2S__H */
103