-
Notifications
You must be signed in to change notification settings - Fork 4
/
mcasp-dsd.patch
173 lines (152 loc) · 4.6 KB
/
mcasp-dsd.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
diff '--color=auto' -Naur linux-5.4_old/sound/soc/ti/davinci-mcasp.c linux-5.4/sound/soc/ti/davinci-mcasp.c
--- linux-5.4_old/sound/soc/ti/davinci-mcasp.c 2019-11-25 01:32:01.000000000 +0100
+++ linux-5.4/sound/soc/ti/davinci-mcasp.c 2019-12-05 22:08:52.358966990 +0100
@@ -810,13 +810,13 @@
}
static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
- int period_words, int channels)
+ int period_words, int channels, bool dsd_mode)
{
struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream];
int i;
u8 tx_ser = 0;
u8 rx_ser = 0;
- u8 slots = mcasp->tdm_slots;
+ u8 slots = dsd_mode ? 1 : mcasp->tdm_slots;
u8 max_active_serializers = (channels + slots - 1) / slots;
u8 max_rx_serializers, max_tx_serializers;
int active_serializers, numevt;
@@ -934,13 +934,14 @@
}
static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream,
- int channels)
+ int channels, bool dsd_mode)
{
int i, active_slots;
int total_slots;
int active_serializers;
u32 mask = 0;
u32 busel = 0;
+ u32 mod;
total_slots = mcasp->tdm_slots;
@@ -979,11 +980,19 @@
if (!mcasp->dat_port)
busel = TXSEL;
+ if (dsd_mode) {
+ mask = 1;
+ busel = 0;
+ mod = 0;
+ } else {
+ mod = total_slots;
+ }
+
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
- FSXMOD(total_slots), FSXMOD(0x1FF));
+ FSXMOD(mod), FSXMOD(0x1FF));
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
@@ -996,7 +1005,7 @@
*/
if (mcasp_is_synchronous(mcasp) && !mcasp->channels)
mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
- FSXMOD(total_slots), FSXMOD(0x1FF));
+ FSXMOD(mod), FSXMOD(0x1FF));
}
return 0;
@@ -1159,12 +1168,28 @@
return fifo_use / substream->runtime->channels;
}
+static int is_dsd(snd_pcm_format_t format)
+{
+ switch (format) {
+ case SNDRV_PCM_FORMAT_DSD_U8:
+ case SNDRV_PCM_FORMAT_DSD_U16_LE:
+ case SNDRV_PCM_FORMAT_DSD_U32_LE:
+ return 1;
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+}
+
static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *cpu_dai)
{
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
int word_length;
+ bool dsd_mode = is_dsd(params_format(params));
int channels = params_channels(params);
int period_size = params_period_size(params);
int ret;
@@ -1172,11 +1197,13 @@
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_U8:
case SNDRV_PCM_FORMAT_S8:
+ case SNDRV_PCM_FORMAT_DSD_U8:
word_length = 8;
break;
case SNDRV_PCM_FORMAT_U16_LE:
case SNDRV_PCM_FORMAT_S16_LE:
+ case SNDRV_PCM_FORMAT_DSD_U16_LE:
word_length = 16;
break;
@@ -1192,6 +1219,7 @@
case SNDRV_PCM_FORMAT_U32_LE:
case SNDRV_PCM_FORMAT_S32_LE:
+ case SNDRV_PCM_FORMAT_DSD_U32_LE:
word_length = 32;
break;
@@ -1221,7 +1249,7 @@
}
ret = mcasp_common_hw_param(mcasp, substream->stream,
- period_size * channels, channels);
+ period_size * channels, channels, dsd_mode);
if (ret)
return ret;
@@ -1229,7 +1257,7 @@
ret = mcasp_dit_hw_param(mcasp, params_rate(params));
else
ret = mcasp_i2s_hw_param(mcasp, substream->stream,
- channels);
+ channels, dsd_mode);
if (ret)
return ret;
@@ -1238,7 +1266,7 @@
if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) {
mcasp->channels = channels;
- if (!mcasp->max_format_width)
+ if (!mcasp->max_format_width && !dsd_mode)
mcasp->max_format_width = word_length;
}
@@ -1316,7 +1344,7 @@
static const unsigned int davinci_mcasp_dai_rates[] = {
8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
- 88200, 96000, 176400, 192000,
+ 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000,
};
#define DAVINCI_MAX_RATE_ERROR_PPM 1000
@@ -1583,7 +1611,7 @@
return 0;
}
-#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000
+#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_KNOT
#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_U8 | \
@@ -1594,7 +1622,10 @@
SNDRV_PCM_FMTBIT_S24_3LE | \
SNDRV_PCM_FMTBIT_U24_3LE | \
SNDRV_PCM_FMTBIT_S32_LE | \
- SNDRV_PCM_FMTBIT_U32_LE)
+ SNDRV_PCM_FMTBIT_U32_LE | \
+ SNDRV_PCM_FMTBIT_DSD_U8 | \
+ SNDRV_PCM_FMTBIT_DSD_U16_LE | \
+ SNDRV_PCM_FMTBIT_DSD_U32_LE)
static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
{