1 From 5dea9e48e2a2bd39524e21c1a743f08edd8e4ef6 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime@cerno.tech>
3 Date: Wed, 28 Apr 2021 15:29:13 +0200
4 Subject: [PATCH] snd: iec958: split status creation and fill
6 In some situations, like a codec probe, we need to provide an IEC status
7 default but don't have access to the sampling rate and width yet since
8 no stream has been configured yet.
10 Each and every driver has its own default, whereas the core iec958 code
11 also has some buried in the snd_pcm_create_iec958_consumer functions.
13 Let's split these functions in two to provide a default that doesn't
14 rely on the sampling rate and width, and another function to fill them
17 Signed-off-by: Maxime Ripard <maxime@cerno.tech>
19 include/sound/pcm_iec958.h | 8 +++
20 sound/core/pcm_iec958.c | 129 +++++++++++++++++++++++++------------
21 2 files changed, 95 insertions(+), 42 deletions(-)
23 --- a/include/sound/pcm_iec958.h
24 +++ b/include/sound/pcm_iec958.h
27 #include <linux/types.h>
29 +int snd_pcm_create_iec958_consumer_default(u8 *cs, size_t len);
31 +int snd_pcm_fill_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
34 +int snd_pcm_fill_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
35 + u8 *cs, size_t len);
37 int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
40 --- a/sound/core/pcm_iec958.c
41 +++ b/sound/core/pcm_iec958.c
43 #include <sound/pcm_params.h>
44 #include <sound/pcm_iec958.h>
46 -static int create_iec958_consumer(uint rate, uint sample_width,
48 +int snd_pcm_create_iec958_consumer_default(u8 *cs, size_t len)
50 - unsigned int fs, ws;
57 - fs = IEC958_AES3_CON_FS_32000;
60 - fs = IEC958_AES3_CON_FS_44100;
63 - fs = IEC958_AES3_CON_FS_48000;
66 - fs = IEC958_AES3_CON_FS_88200;
69 - fs = IEC958_AES3_CON_FS_96000;
72 - fs = IEC958_AES3_CON_FS_176400;
75 - fs = IEC958_AES3_CON_FS_192000;
80 + cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE;
81 + cs[1] = IEC958_AES1_CON_GENERAL;
82 + cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC;
83 + cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | IEC958_AES3_CON_FS_NOTID;
86 + cs[4] = IEC958_AES4_CON_WORDLEN_NOTID;
90 +EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_default);
92 +static int fill_iec958_consumer(uint rate, uint sample_width,
98 + if ((cs[3] & IEC958_AES3_CON_FS) == IEC958_AES3_CON_FS_NOTID) {
103 + fs = IEC958_AES3_CON_FS_32000;
106 + fs = IEC958_AES3_CON_FS_44100;
109 + fs = IEC958_AES3_CON_FS_48000;
112 + fs = IEC958_AES3_CON_FS_88200;
115 + fs = IEC958_AES3_CON_FS_96000;
118 + fs = IEC958_AES3_CON_FS_176400;
121 + fs = IEC958_AES3_CON_FS_192000;
127 + cs[3] &= ~IEC958_AES3_CON_FS;
133 + (cs[4] & IEC958_AES4_CON_WORDLEN) == IEC958_AES4_CON_WORDLEN_NOTID) {
136 switch (sample_width) {
138 ws = IEC958_AES4_CON_WORDLEN_20_16;
139 @@ -64,20 +91,29 @@ static int create_iec958_consumer(uint r
145 - memset(cs, 0, len);
146 + cs[4] &= ~IEC958_AES4_CON_WORDLEN;
150 - cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE;
151 - cs[1] = IEC958_AES1_CON_GENERAL;
152 - cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC;
153 - cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | fs;
159 +int snd_pcm_fill_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
160 + u8 *cs, size_t len)
162 + return fill_iec958_consumer(params_rate(params), params_width(params), cs, len);
164 +EXPORT_SYMBOL(snd_pcm_fill_iec958_consumer_hw_params);
167 +int snd_pcm_fill_iec958_consumer(struct snd_pcm_runtime *runtime,
168 + u8 *cs, size_t len)
170 + return fill_iec958_consumer(runtime->rate,
171 + snd_pcm_format_width(runtime->format),
174 +EXPORT_SYMBOL(snd_pcm_fill_iec958_consumer);
177 * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
178 @@ -95,9 +131,13 @@ static int create_iec958_consumer(uint r
179 int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
182 - return create_iec958_consumer(runtime->rate,
183 - snd_pcm_format_width(runtime->format),
187 + ret = snd_pcm_create_iec958_consumer_default(cs, len);
191 + return snd_pcm_fill_iec958_consumer(runtime, cs, len);
193 EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);
195 @@ -117,7 +157,12 @@ EXPORT_SYMBOL(snd_pcm_create_iec958_cons
196 int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
199 - return create_iec958_consumer(params_rate(params), params_width(params),
203 + ret = snd_pcm_create_iec958_consumer_default(cs, len);
207 + return fill_iec958_consumer(params_rate(params), params_width(params), cs, len);
209 EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params);