+++ /dev/null
-From 5dea9e48e2a2bd39524e21c1a743f08edd8e4ef6 Mon Sep 17 00:00:00 2001
-From: Maxime Ripard <maxime@cerno.tech>
-Date: Wed, 28 Apr 2021 15:29:13 +0200
-Subject: [PATCH] snd: iec958: split status creation and fill
-
-In some situations, like a codec probe, we need to provide an IEC status
-default but don't have access to the sampling rate and width yet since
-no stream has been configured yet.
-
-Each and every driver has its own default, whereas the core iec958 code
-also has some buried in the snd_pcm_create_iec958_consumer functions.
-
-Let's split these functions in two to provide a default that doesn't
-rely on the sampling rate and width, and another function to fill them
-when available.
-
-Signed-off-by: Maxime Ripard <maxime@cerno.tech>
----
- include/sound/pcm_iec958.h | 8 +++
- sound/core/pcm_iec958.c | 129 +++++++++++++++++++++++++------------
- 2 files changed, 95 insertions(+), 42 deletions(-)
-
---- a/include/sound/pcm_iec958.h
-+++ b/include/sound/pcm_iec958.h
-@@ -4,6 +4,14 @@
-
- #include <linux/types.h>
-
-+int snd_pcm_create_iec958_consumer_default(u8 *cs, size_t len);
-+
-+int snd_pcm_fill_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
-+ size_t len);
-+
-+int snd_pcm_fill_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
-+ u8 *cs, size_t len);
-+
- int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
- size_t len);
-
---- a/sound/core/pcm_iec958.c
-+++ b/sound/core/pcm_iec958.c
-@@ -9,41 +9,68 @@
- #include <sound/pcm_params.h>
- #include <sound/pcm_iec958.h>
-
--static int create_iec958_consumer(uint rate, uint sample_width,
-- u8 *cs, size_t len)
-+int snd_pcm_create_iec958_consumer_default(u8 *cs, size_t len)
- {
-- unsigned int fs, ws;
--
- if (len < 4)
- return -EINVAL;
-
-- switch (rate) {
-- case 32000:
-- fs = IEC958_AES3_CON_FS_32000;
-- break;
-- case 44100:
-- fs = IEC958_AES3_CON_FS_44100;
-- break;
-- case 48000:
-- fs = IEC958_AES3_CON_FS_48000;
-- break;
-- case 88200:
-- fs = IEC958_AES3_CON_FS_88200;
-- break;
-- case 96000:
-- fs = IEC958_AES3_CON_FS_96000;
-- break;
-- case 176400:
-- fs = IEC958_AES3_CON_FS_176400;
-- break;
-- case 192000:
-- fs = IEC958_AES3_CON_FS_192000;
-- break;
-- default:
-+ memset(cs, 0, len);
-+
-+ cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE;
-+ cs[1] = IEC958_AES1_CON_GENERAL;
-+ cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC;
-+ cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | IEC958_AES3_CON_FS_NOTID;
-+
-+ if (len > 4)
-+ cs[4] = IEC958_AES4_CON_WORDLEN_NOTID;
-+
-+ return len;
-+}
-+EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_default);
-+
-+static int fill_iec958_consumer(uint rate, uint sample_width,
-+ u8 *cs, size_t len)
-+{
-+ if (len < 4)
- return -EINVAL;
-+
-+ if ((cs[3] & IEC958_AES3_CON_FS) == IEC958_AES3_CON_FS_NOTID) {
-+ unsigned int fs;
-+
-+ switch (rate) {
-+ case 32000:
-+ fs = IEC958_AES3_CON_FS_32000;
-+ break;
-+ case 44100:
-+ fs = IEC958_AES3_CON_FS_44100;
-+ break;
-+ case 48000:
-+ fs = IEC958_AES3_CON_FS_48000;
-+ break;
-+ case 88200:
-+ fs = IEC958_AES3_CON_FS_88200;
-+ break;
-+ case 96000:
-+ fs = IEC958_AES3_CON_FS_96000;
-+ break;
-+ case 176400:
-+ fs = IEC958_AES3_CON_FS_176400;
-+ break;
-+ case 192000:
-+ fs = IEC958_AES3_CON_FS_192000;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ cs[3] &= ~IEC958_AES3_CON_FS;
-+ cs[3] |= fs;
- }
-
-- if (len > 4) {
-+ if (len > 4 &&
-+ (cs[4] & IEC958_AES4_CON_WORDLEN) == IEC958_AES4_CON_WORDLEN_NOTID) {
-+ unsigned int ws;
-+
- switch (sample_width) {
- case 16:
- ws = IEC958_AES4_CON_WORDLEN_20_16;
-@@ -64,20 +91,29 @@ static int create_iec958_consumer(uint r
- default:
- return -EINVAL;
- }
-- }
-
-- memset(cs, 0, len);
-+ cs[4] &= ~IEC958_AES4_CON_WORDLEN;
-+ cs[4] |= ws;
-+ }
-
-- cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE;
-- cs[1] = IEC958_AES1_CON_GENERAL;
-- cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC;
-- cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | fs;
-+ return len;
-+}
-
-- if (len > 4)
-- cs[4] = ws;
-+int snd_pcm_fill_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
-+ u8 *cs, size_t len)
-+{
-+ return fill_iec958_consumer(params_rate(params), params_width(params), cs, len);
-+}
-+EXPORT_SYMBOL(snd_pcm_fill_iec958_consumer_hw_params);
-
-- return len;
-+int snd_pcm_fill_iec958_consumer(struct snd_pcm_runtime *runtime,
-+ u8 *cs, size_t len)
-+{
-+ return fill_iec958_consumer(runtime->rate,
-+ snd_pcm_format_width(runtime->format),
-+ cs, len);
- }
-+EXPORT_SYMBOL(snd_pcm_fill_iec958_consumer);
-
- /**
- * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
-@@ -95,9 +131,13 @@ static int create_iec958_consumer(uint r
- int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
- size_t len)
- {
-- return create_iec958_consumer(runtime->rate,
-- snd_pcm_format_width(runtime->format),
-- cs, len);
-+ int ret;
-+
-+ ret = snd_pcm_create_iec958_consumer_default(cs, len);
-+ if (ret < 0)
-+ return ret;
-+
-+ return snd_pcm_fill_iec958_consumer(runtime, cs, len);
- }
- EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);
-
-@@ -117,7 +157,12 @@ EXPORT_SYMBOL(snd_pcm_create_iec958_cons
- int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
- u8 *cs, size_t len)
- {
-- return create_iec958_consumer(params_rate(params), params_width(params),
-- cs, len);
-+ int ret;
-+
-+ ret = snd_pcm_create_iec958_consumer_default(cs, len);
-+ if (ret < 0)
-+ return ret;
-+
-+ return fill_iec958_consumer(params_rate(params), params_width(params), cs, len);
- }
- EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params);