-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path0086-i2s-phytium-Support-for-24bit-and-32bit-format.patch
186 lines (172 loc) · 7.35 KB
/
0086-i2s-phytium-Support-for-24bit-and-32bit-format.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
From 29017b388fd926bf7344fc1f4aa9df437a2be663 Mon Sep 17 00:00:00 2001
From: Zhou Zheng <[email protected]>
Date: Mon, 17 Jun 2024 19:33:07 +0800
Subject: [PATCH 086/150] i2s: phytium: Support for 24bit and 32bit format
According to dma controller requirement, configure the DMA length
as 0 for 24bit and 32 bit audio format.
Signed-off-by: Zhou Zheng <[email protected]>
Signed-off-by: Wang Yinfeng <[email protected]>
Signed-off-by: Chen Baozi <[email protected]>
Change-Id: I9249f7931b953d79147a301bf2aed9ac6b8c42a4
Signed-off-by: Andrew Powers-Holmes <[email protected]>
---
sound/soc/phytium/phytium_i2s.c | 82 +++++++++++++++++++++------------
1 file changed, 52 insertions(+), 30 deletions(-)
diff --git a/sound/soc/phytium/phytium_i2s.c b/sound/soc/phytium/phytium_i2s.c
index 6457e428cfe2..efaa70704753 100644
--- a/sound/soc/phytium/phytium_i2s.c
+++ b/sound/soc/phytium/phytium_i2s.c
@@ -548,6 +548,25 @@ static int phytium_pcm_hw_params(struct snd_soc_component *component,
azx_dev->core.period_bytes = 0;
azx_dev->core.format_val = 0;
+ switch (params_format(hw_params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ azx_dev->core.format_val = 2;
+ break;
+
+ case SNDRV_PCM_FORMAT_S24_LE:
+ azx_dev->core.format_val = 0;
+ break;
+
+ case SNDRV_PCM_FORMAT_S32_LE:
+ azx_dev->core.format_val = 0;
+ break;
+
+ default:
+ dev_err(dev->dev, "phytium-i2s: unsupported PCM fmt");
+ return -EINVAL;
+ }
+
+
ret = chip->ops->substream_alloc_pages(chip, substream,
params_buffer_bytes(hw_params));
@@ -683,11 +702,9 @@ int snd_i2s_stream_set_params(struct i2s_stream *azx_dev,
period_bytes = snd_pcm_lib_period_bytes(substream);
if (bufsize != azx_dev->bufsize ||
period_bytes != azx_dev->period_bytes ||
- format_val != azx_dev->format_val ||
runtime->no_period_wakeup != azx_dev->no_period_wakeup) {
azx_dev->bufsize = bufsize;
azx_dev->period_bytes = period_bytes;
- azx_dev->format_val = format_val;
azx_dev->no_period_wakeup = runtime->no_period_wakeup;
err = snd_i2s_stream_setup_periods(azx_dev);
if (err < 0)
@@ -713,23 +730,23 @@ int snd_i2s_stream_setup(struct i2s_stream *azx_dev, int pcie, u32 paddr)
i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(0), (u32)azx_dev->bdl.addr);
i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(0), upper_32_bits(azx_dev->bdl.addr));
if (pcie)
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), 0x1c8);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), 0x1c0);
else
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), paddr + 0x1c8);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(0), paddr + 0x1c0);
i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CBL(0), azx_dev->bufsize);
i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_LVI(0), azx_dev->frags - 1);
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(0), 0x2);//0x2
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(0), 0x0);//0x0
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(0), azx_dev->format_val << 2);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(0), 0x0);
} else {
i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(1), (u32)azx_dev->bdl.addr);
i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(1), upper_32_bits(azx_dev->bdl.addr));
if (pcie)
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), 0x1c0);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), 0x1c8);
else
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), paddr + 0x1c0);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DEV_ADDR(1), paddr + 0x1c8);
i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CBL(1), azx_dev->bufsize);
i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_LVI(1), azx_dev->frags - 1);
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(1), 0x8);//0x8
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DSIZE(1), azx_dev->format_val);
i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_DLENTH(1), 0x0);
}
@@ -786,9 +803,9 @@ static int phytium_pcm_prepare(struct snd_soc_component *component,
void snd_i2s_stream_clear(struct i2s_stream *azx_dev)
{
if (azx_dev->direction == SNDRV_PCM_STREAM_PLAYBACK)
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0x0);
- else
i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(1), 0x0);
+ else
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0x0);
azx_dev->running = false;
}
@@ -801,9 +818,9 @@ void snd_i2s_stream_stop(struct i2s_stream *azx_dev)
void snd_i2s_stream_start(struct i2s_stream *azx_dev, bool fresh_start)
{
if (azx_dev->direction == SNDRV_PCM_STREAM_PLAYBACK)
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0x1);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(1), 0x1);
else
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(1), 0x5);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0x5);
azx_dev->running = true;
}
@@ -872,19 +889,6 @@ void snd_i2s_stream_cleanup(struct i2s_stream *azx_dev)
if (azx_dev->sd_addr) {
if (azx_dev->direction == SNDRV_PCM_STREAM_PLAYBACK) {
- mask = i2s_read_reg(azx_dev->sd_addr, DMA_MASK_INT);
- mask &= ~BIT(0);
- i2s_write_reg(azx_dev->sd_addr, DMA_MASK_INT, mask);
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0);
- while (cnt--) {
- if (i2s_read_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0)) == 0)
- break;
- }
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 2);
- i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0);
- i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(0), 0);
- i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(0), 0);
- } else {
mask = i2s_read_reg(azx_dev->sd_addr, DMA_MASK_INT);
mask &= ~BIT(1);
i2s_write_reg(azx_dev->sd_addr, DMA_MASK_INT, mask);
@@ -897,6 +901,21 @@ void snd_i2s_stream_cleanup(struct i2s_stream *azx_dev)
i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(1), 0);
i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(1), 0);
i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(1), 0);
+ i2s_write_reg(azx_dev->sd_addr, DMA_STS, azx_dev->sd_int_sta_mask);
+ } else {
+ mask = i2s_read_reg(azx_dev->sd_addr, DMA_MASK_INT);
+ mask &= ~BIT(0);
+ i2s_write_reg(azx_dev->sd_addr, DMA_MASK_INT, mask);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0);
+ while (cnt--) {
+ if (i2s_read_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0)) == 0)
+ break;
+ }
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 2);
+ i2s_write_reg(azx_dev->sd_addr, DMA_CHALX_CTL(0), 0);
+ i2s_write_reg(azx_dev->sd_addr, DMA_BDLPL(0), 0);
+ i2s_write_reg(azx_dev->sd_addr, DMA_BDLPU(0), 0);
+ i2s_write_reg(azx_dev->sd_addr, DMA_STS, azx_dev->sd_int_sta_mask);
}
}
}
@@ -926,9 +945,12 @@ static snd_pcm_uframes_t phytium_pcm_pointer(struct snd_soc_component *component
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct i2s_phytium *dev = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
- int stream = substream->stream;
+ u32 pos = 0;
- u32 pos = i2s_read_reg(dev->regs_db, DMA_LPIB(stream));
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ pos = i2s_read_reg(dev->regs_db, DMA_LPIB(1));
+ else
+ pos = i2s_read_reg(dev->regs_db, DMA_LPIB(0));
return bytes_to_frames(substream->runtime, pos);
}
@@ -1090,9 +1112,9 @@ void snd_i2s_stream_init(struct i2sc_bus *bus, struct i2s_stream *azx_dev,
azx_dev->sd_addr = bus->remap_addr;
if (idx == 0)
- azx_dev->sd_int_sta_mask = 1 << idx;
- else
azx_dev->sd_int_sta_mask = 1 << 8;
+ else
+ azx_dev->sd_int_sta_mask = 1;
azx_dev->index = idx;
azx_dev->direction = direction;
--
2.47.0