Skip to content

Commit dc98691

Browse files
michalsieronmbolivar-nordic
authored andcommitted
drivers: i2s: i2s_litex: Calculate offsets from DT
To support both 8-bit and 32-bit Control/Status register variants, register offsets need to be calculated from device tree. Updated register data in device tree to the 32-bit CSR variant. Renamed defines to be similar to other LiteX drivers. Changed frequencies in clock-outputs nodes, so i2s/litex sample works. Signed-off-by: Michal Sieron <[email protected]>
1 parent 17a2c6d commit dc98691

File tree

3 files changed

+64
-51
lines changed

3 files changed

+64
-51
lines changed

drivers/i2s/i2s_litex.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ LOG_MODULE_REGISTER(i2s_litex);
2727
*/
2828
static void i2s_enable(uintptr_t reg)
2929
{
30-
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_REG_OFFSET);
30+
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_OFFSET);
3131

32-
litex_write8(reg_data | I2S_ENABLE, reg + I2S_CONTROL_REG_OFFSET);
32+
litex_write8(reg_data | I2S_ENABLE, reg + I2S_CONTROL_OFFSET);
3333
}
3434

3535
/**
@@ -39,9 +39,9 @@ static void i2s_enable(uintptr_t reg)
3939
*/
4040
static void i2s_disable(uintptr_t reg)
4141
{
42-
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_REG_OFFSET);
42+
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_OFFSET);
4343

44-
litex_write8(reg_data & ~(I2S_ENABLE), reg + I2S_CONTROL_REG_OFFSET);
44+
litex_write8(reg_data & ~(I2S_ENABLE), reg + I2S_CONTROL_OFFSET);
4545
}
4646

4747
/**
@@ -51,9 +51,9 @@ static void i2s_disable(uintptr_t reg)
5151
*/
5252
static void i2s_reset_fifo(uintptr_t reg)
5353
{
54-
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_REG_OFFSET);
54+
uint8_t reg_data = litex_read8(reg + I2S_CONTROL_OFFSET);
5555

56-
litex_write8(reg_data | I2S_FIFO_RESET, reg + I2S_CONTROL_REG_OFFSET);
56+
litex_write8(reg_data | I2S_FIFO_RESET, reg + I2S_CONTROL_OFFSET);
5757
}
5858

5959
/**
@@ -66,7 +66,7 @@ static void i2s_reset_fifo(uintptr_t reg)
6666
*/
6767
static i2s_fmt_t i2s_get_foramt(uintptr_t reg)
6868
{
69-
uint8_t reg_data = litex_read32(reg + I2S_CONFIG_REG_OFFSET);
69+
uint8_t reg_data = litex_read32(reg + I2S_CONFIG_OFFSET);
7070

7171
reg_data &= I2S_CONF_FORMAT_MASK;
7272
if (reg_data == LITEX_I2S_STANDARD) {
@@ -86,7 +86,7 @@ static i2s_fmt_t i2s_get_foramt(uintptr_t reg)
8686
*/
8787
static uint32_t i2s_get_sample_width(uintptr_t reg)
8888
{
89-
uint32_t reg_data = litex_read32(reg + I2S_CONFIG_REG_OFFSET);
89+
uint32_t reg_data = litex_read32(reg + I2S_CONFIG_OFFSET);
9090

9191
reg_data &= I2S_CONF_SAMPLE_WIDTH_MASK;
9292
return reg_data >> I2S_CONF_SAMPLE_WIDTH_OFFSET;
@@ -101,7 +101,7 @@ static uint32_t i2s_get_sample_width(uintptr_t reg)
101101
*/
102102
static uint32_t i2s_get_audio_freq(uintptr_t reg)
103103
{
104-
uint32_t reg_data = litex_read32(reg + I2S_CONFIG_REG_OFFSET);
104+
uint32_t reg_data = litex_read32(reg + I2S_CONFIG_OFFSET);
105105

106106
reg_data &= I2S_CONF_LRCK_MASK;
107107
return reg_data >> I2S_CONF_LRCK_FREQ_OFFSET;
@@ -117,9 +117,9 @@ static void i2s_irq_enable(uintptr_t reg, int irq_type)
117117
{
118118
__ASSERT_NO_MSG(irq_type == I2S_EV_READY || irq_type == I2S_EV_ERROR);
119119

120-
uint8_t reg_data = litex_read8(reg + I2S_EV_ENABLE_REG_OFFSET);
120+
uint8_t reg_data = litex_read8(reg + I2S_EV_ENABLE_OFFSET);
121121

122-
litex_write8(reg_data | irq_type, reg + I2S_EV_ENABLE_REG_OFFSET);
122+
litex_write8(reg_data | irq_type, reg + I2S_EV_ENABLE_OFFSET);
123123
}
124124

125125
/**
@@ -132,9 +132,9 @@ static void i2s_irq_disable(uintptr_t reg, int irq_type)
132132
{
133133
__ASSERT_NO_MSG(irq_type == I2S_EV_READY || irq_type == I2S_EV_ERROR);
134134

135-
uint8_t reg_data = litex_read8(reg + I2S_EV_ENABLE_REG_OFFSET);
135+
uint8_t reg_data = litex_read8(reg + I2S_EV_ENABLE_OFFSET);
136136

137-
litex_write8(reg_data & ~(irq_type), reg + I2S_EV_ENABLE_REG_OFFSET);
137+
litex_write8(reg_data & ~(irq_type), reg + I2S_EV_ENABLE_OFFSET);
138138
}
139139

140140
/**
@@ -144,9 +144,9 @@ static void i2s_irq_disable(uintptr_t reg, int irq_type)
144144
*/
145145
static void i2s_clear_pending_irq(uintptr_t reg)
146146
{
147-
uint8_t reg_data = litex_read8(reg + I2S_EV_PENDING_REG_OFFSET);
147+
uint8_t reg_data = litex_read8(reg + I2S_EV_PENDING_OFFSET);
148148

149-
litex_write8(reg_data, reg + I2S_EV_PENDING_REG_OFFSET);
149+
litex_write8(reg_data, reg + I2S_EV_PENDING_OFFSET);
150150
}
151151

152152
/**
@@ -323,18 +323,16 @@ static int i2s_litex_configure(const struct device *dev, enum i2s_dir dir,
323323
struct i2s_litex_data *const dev_data = dev->data;
324324
const struct i2s_litex_cfg *const cfg = dev->config;
325325
struct stream *stream;
326-
int channels_concatenated;
326+
int channels_concatenated = litex_read8(cfg->base + I2S_STATUS_OFFSET);
327327
int dev_audio_freq = i2s_get_audio_freq(cfg->base);
328328
int channel_div;
329329

330330
if (dir == I2S_DIR_RX) {
331331
stream = &dev_data->rx;
332-
channels_concatenated = litex_read8(I2S_RX_STATUS_REG) &
333-
I2S_RX_STAT_CHANNEL_CONCATENATED_MASK;
332+
channels_concatenated &= I2S_RX_STAT_CHANNEL_CONCATENATED_MASK;
334333
} else if (dir == I2S_DIR_TX) {
335334
stream = &dev_data->tx;
336-
channels_concatenated = litex_read8(I2S_TX_STATUS_REG) &
337-
I2S_TX_STAT_CHANNEL_CONCATENATED_MASK;
335+
channels_concatenated &= I2S_TX_STAT_CHANNEL_CONCATENATED_MASK;
338336
} else if (dir == I2S_DIR_BOTH) {
339337
return -ENOSYS;
340338
} else {
@@ -612,7 +610,7 @@ static const struct i2s_driver_api i2s_litex_driver_api = {
612610
static void i2s_litex_irq_config_func_##dir(const struct device *dev); \
613611
\
614612
static struct i2s_litex_cfg i2s_litex_cfg_##dir = { \
615-
.base = DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_##dir), control), \
613+
.base = DT_REG_ADDR(DT_NODELABEL(i2s_##dir)), \
616614
.fifo_base = \
617615
DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_##dir), fifo), \
618616
.fifo_depth = DT_PROP(DT_NODELABEL(i2s_##dir), fifo_depth), \

drivers/i2s/i2s_litex.h

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@
1111
#include <zephyr/drivers/i2s.h>
1212
#include <zephyr/devicetree.h>
1313

14-
/* i2s register offsets*/
15-
#define I2S_EV_STATUS_REG_OFFSET 0x0
16-
#define I2S_EV_PENDING_REG_OFFSET 0x4
17-
#define I2S_EV_ENABLE_REG_OFFSET 0x8
18-
#define I2S_CONTROL_REG_OFFSET 0xc
19-
#define I2S_STATUS_REG_OFFSET 0x10
20-
#define I2S_CONFIG_REG_OFFSET 0x20
21-
2214
/* i2s configuration mask*/
2315
#define I2S_CONF_FORMAT_OFFSET 0
2416
#define I2S_CONF_SAMPLE_WIDTH_OFFSET 2
@@ -36,14 +28,6 @@
3628
#define I2S_EV_READY (1 << 0)
3729
#define I2S_EV_ERROR (1 << 1)
3830
/* i2s rx*/
39-
#define I2S_RX_BASE_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), control)
40-
#define I2S_RX_EV_STATUS_REG (I2S_RX_BASE_ADDR + I2S_EV_STATUS_REG_OFFSET)
41-
#define I2S_RX_EV_PENDING_REG (I2S_RX_BASE_ADDR + I2S_EV_PENDING_REG_OFFSET)
42-
#define I2S_RX_EV_ENABLE_REG (I2S_RX_BASE_ADDR + I2S_EV_ENABLE_REG_OFFSET)
43-
#define I2S_RX_CONTROL_REG (I2S_RX_BASE_ADDR + I2S_CONTROL_REG_OFFSET)
44-
#define I2S_RX_STATUS_REG (I2S_RX_BASE_ADDR + I2S_STATUS_REG_OFFSET)
45-
#define I2S_RX_CONFIG_REG (I2S_RX_BASE_ADDR + I2S_CONFIG_REG_OFFSET)
46-
4731
#define I2S_RX_STAT_CHANNEL_CONCATENATED_OFFSET 31
4832
#define I2S_RX_STAT_CHANNEL_CONCATENATED_MASK \
4933
(0x1 << I2S_RX_STAT_CHANNEL_CONCATENATED_OFFSET)
@@ -52,21 +36,28 @@
5236
#define I2S_RX_FIFO_DEPTH DT_PROP(DT_NODELABEL(i2s_rx), fifo_depth)
5337

5438
/* i2s tx*/
55-
#define I2S_TX_BASE_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_tx), control)
56-
#define I2S_TX_EV_STATUS_REG (I2S_RX_BASE_ADDR + I2S_EV_STATUS_REG_OFFSET)
57-
#define I2S_TX_EV_PENDING_REG (I2S_TX_BASE_ADDR + I2S_EV_PENDING_REG_OFFSET)
58-
#define I2S_TX_EV_ENABLE_REG (I2S_TX_BASE_ADDR + I2S_EV_ENABLE_REG_OFFSET)
59-
#define I2S_TX_CONTROL_REG (I2S_TX_BASE_ADDR + I2S_CONTROL_REG_OFFSET)
60-
#define I2S_TX_STATUS_REG (I2S_TX_BASE_ADDR + I2S_STATUS_REG_OFFSET)
61-
#define I2S_TX_CONFIG_REG (I2S_TX_BASE_ADDR + I2S_CONFIG_REG_OFFSET)
62-
6339
#define I2S_TX_STAT_CHANNEL_CONCATENATED_OFFSET 24
6440
#define I2S_TX_STAT_CHANNEL_CONCATENATED_MASK \
6541
(0x1 << I2S_TX_STAT_CHANNEL_CONCATENATED_OFFSET)
6642

6743
#define I2S_TX_FIFO_ADDR DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_tx), fifo)
6844
#define I2S_TX_FIFO_DEPTH DT_PROP(DT_NODELABEL(i2s_tx), fifo_depth)
6945

46+
/* i2s register offsets (they are the same for all i2s nodes, both rx and tx) */
47+
#define I2S_BASE_ADDR DT_REG_ADDR(DT_NODELABEL(i2s_rx))
48+
#define I2S_EV_STATUS_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_status) \
49+
- I2S_BASE_ADDR)
50+
#define I2S_EV_PENDING_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_pending) \
51+
- I2S_BASE_ADDR)
52+
#define I2S_EV_ENABLE_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), ev_enable) \
53+
- I2S_BASE_ADDR)
54+
#define I2S_CONTROL_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_ctl) \
55+
- I2S_BASE_ADDR)
56+
#define I2S_STATUS_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_stat) \
57+
- I2S_BASE_ADDR)
58+
#define I2S_CONFIG_OFFSET (DT_REG_ADDR_BY_NAME(DT_NODELABEL(i2s_rx), rx_conf) \
59+
- I2S_BASE_ADDR)
60+
7061
enum litex_i2s_fmt {
7162
LITEX_I2S_STANDARD = 1,
7263
LITEX_I2S_LEFT_JUSTIFIED = 2,

dts/riscv/riscv32-litex-vexriscv.dtsi

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,24 +219,48 @@
219219
};
220220
i2s_rx: i2s_rx@e000a800 {
221221
compatible = "litex,i2s";
222-
reg = <0xe000a800 0x20 0xb1000000 0x40000>;
222+
reg = <0xe000a800 0x4
223+
0xe000a804 0x4
224+
0xe000a808 0x4
225+
0xe000a80c 0x4
226+
0xe000a810 0x4
227+
0xe000a814 0x4
228+
0xb1000000 0x40000>;
223229
interrupt-parent = <&intc0>;
224230
interrupts = <6 2>;
225231
#address-cells = <1>;
226232
#size-cells = <0>;
227-
reg-names = "control", "fifo";
233+
reg-names = "ev_status",
234+
"ev_pending",
235+
"ev_enable",
236+
"rx_ctl",
237+
"rx_stat",
238+
"rx_conf",
239+
"fifo";
228240
fifo_depth = <256>;
229241
label = "i2s_rx";
230242
status = "disabled";
231243
};
232244
i2s_tx: i2s_tx@e000b000 {
233245
compatible = "litex,i2s";
234-
reg = <0xe000b000 0x20 0xb2000000 0x40000>;
246+
reg = <0xe000b000 0x4
247+
0xe000b004 0x4
248+
0xe000b008 0x4
249+
0xe000b00c 0x4
250+
0xe000b010 0x4
251+
0xe000b014 0x4
252+
0xb2000000 0x40000>;
235253
interrupt-parent = <&intc0>;
236254
interrupts = <7 2>;
237255
#address-cells = <1>;
238256
#size-cells = <0>;
239-
reg-names = "control", "fifo";
257+
reg-names = "ev_status",
258+
"ev_pending",
259+
"ev_enable",
260+
"tx_ctl",
261+
"tx_stat",
262+
"tx_conf",
263+
"fifo";
240264
fifo_depth = <256>;
241265
label = "i2s_tx";
242266
status = "disabled";
@@ -249,7 +273,7 @@
249273
reg = <0>;
250274
compatible = "litex,clkout";
251275
clock-output-names = "CLK_0";
252-
litex,clock-frequency = <100000000>;
276+
litex,clock-frequency = <11289600>;
253277
litex,clock-phase = <0>;
254278
litex,clock-duty-num = <1>;
255279
litex,clock-duty-den = <2>;
@@ -262,7 +286,7 @@
262286
reg = <1>;
263287
compatible = "litex,clkout";
264288
clock-output-names = "CLK_1";
265-
litex,clock-frequency = <100000000>;
289+
litex,clock-frequency = <22579200>;
266290
litex,clock-phase = <0>;
267291
litex,clock-duty-num = <1>;
268292
litex,clock-duty-den = <2>;

0 commit comments

Comments
 (0)