alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity
@ 2023-09-18 13:39 Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 01/17] ALSA: pcm: Introduce MSBITS subformat interface Cezary Rojewski
                   ` (16 more replies)
  0 siblings, 17 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

Patchset aims to address format selection restrictions present currently
in the HDAudio library. Formats which we are concerned about are 20 and
24 valid bits per sample within 32 bit depth container. One may identify
them as S20_LE and S24_LE except that those, according to comments found
in include/uapi/sound/asound.h, are for LSB-aligned scenarios. HDAudio
streams expect MSB-aligned data, no matter if we are speaking of HOST
(SDxFMT) or LINK (PPLCxFMT) side - chapter 4.5.1 of the public HDAudio
specification. In short, S20_LE and S24_LE are invalid options.

Right now, given the implementation of snd_hdac_query_supported_pcm() 
within sound/hda/hdac_device.c, even if a codec responds with: "I
support all possible formats specified within HDAudio specification",
there will be no option to open a 20/32 or 24/32 stream. The kernel will
force the stream to be opened using the highest available bit depth.

After discussing subject initially with Jaroslav and Takashi, suggestion
was made to utilize 'subformat' option to address the problem. The
eye-opening discussion begun much earlier though, in 2019 [1].

Paired with PRs for alsa-utils [2] and alsa-lib [3].


Flow of changes:

The very first patch adds MSBITS subformat options to allow for granular
20/32, 24/32 and 32/32 format selection. The next three make sure
subformat is actually honored during runtime. Most of that code is based
on format-related API.

Follow up is upgrade to the hda stream-format interface - several
functions are added to make the granular format selection simple in the
HDAudio world. Core of the implementation is based on the existing
snd_hdac_calc_stream_format(). The next ten patches are straightforward
switch from one interface to another with cleanup of now-unsed function
as a finishing touch.

Last but not least - the avs-driver, on which the problem analyzed and
debugged, is updated to no longer acknowledge S24_LE as a valid format
option.

Results with skylake-driver and snd_hda_intel show status quo on our
RVPs. PR filed on SOF github shows promising results too [4].


Changes in v2:
- patch 01/17, introduced struct snd_pcm_subformat which task is to
  represent subformat-mask on per format basis. Expectation is that
  manipulated arrays of subformats always end with a sentinel entry
- patch 01/17, added snd_pcm_hw_copy() as the copying snd_pcm_hardware
  becomes non-trivial
- patch 02/17, added hw_rule that produces final subformat mask
  based on provided formats as suggested by Jaroslav
- patch 04/17, soc_pcm_hw_update_subformat() refactored as the subformat
  intersection becomes non-trivial
- relevant functions releasing resources occupied by hda_pcm and
  snd_pcm_runtime updated to also kfree() subformats
- except for 16/17, no changes to patches past 04/17, retaining acks for
  these

Changes in v1:
- fixed UBSAN due to missing snd_pcm_subformat_names[] entries for new
  subformats
- as HDMI stream capabilities are assigned on PCM open, patch 16/17 has
  been updated to ignore such codecs for now. A separate patchset will
  take care of this case
- params_bps() reworded to snd_pcm_hw_params_bps()
- fixed compilation issues in sof-driver, patch 13/17


[1]: https://lore.kernel.org/alsa-devel/20190905053302.9262-1-pawel.harlozinski@linux.intel.com/
[2]: https://github.com/alsa-project/alsa-utils/pull/228
[3]: https://github.com/alsa-project/alsa-lib/pull/342
[4]: https://github.com/thesofproject/linux/pull/4539

Cezary Rojewski (17):
  ALSA: pcm: Introduce MSBITS subformat interface
  ALSA: pcm: Honor subformat when configuring substream
  ALSA: hda: Honor subformat when querying PCMs
  ASoC: pcm: Honor subformat when configuring runtime
  ALSA: hda: Upgrade stream-format infrastructure
  ALSA: hda: Switch to new stream-format interface
  ALSA: hda/hdmi: Switch to new stream-format interface
  ALSA: hda/ca0132: Switch to new stream-format interface
  ASoC: codecs: hda: Switch to new stream-format interface
  ASoC: codecs: hdac_hda: Switch to new stream-format interface
  ASoC: codecs: hdac_hdmi: Switch to new stream-format interface
  ASoC: Intel Skylake: Switch to new stream-format interface
  ASoC: SOF: Intel: Switch to new stream-format interface
  ASoC: Intel: avs: Switch to new stream-format interface
  ALSA: hda: Drop snd_hdac_calc_stream_format()
  ASoC: Intel: avs: Kill S24_LE in HDAudio streaming
  ASoC: Intel: avs: Unhardcode HDAudio BE DAI drivers description

 include/sound/hda_codec.h         |   5 +-
 include/sound/hdaudio.h           |  14 +--
 include/sound/pcm.h               |  14 +++
 include/sound/pcm_params.h        |   2 +
 include/sound/soc.h               |   1 +
 include/uapi/sound/asound.h       |   7 +-
 sound/core/pcm.c                  |   4 +
 sound/core/pcm_lib.c              |  28 +++++
 sound/core/pcm_misc.c             |  51 ++++++++++
 sound/core/pcm_native.c           |  67 +++++++++++-
 sound/hda/hdac_device.c           | 163 ++++++++++++++++++++++--------
 sound/pci/hda/hda_codec.c         |   5 +
 sound/pci/hda/hda_controller.c    |  10 +-
 sound/pci/hda/patch_ca0132.c      |   3 +-
 sound/pci/hda/patch_hdmi.c        |   6 +-
 sound/soc/codecs/hda-dai.c        |   6 +-
 sound/soc/codecs/hda.c            |   2 +
 sound/soc/codecs/hdac_hda.c       |   8 +-
 sound/soc/codecs/hdac_hdmi.c      |  10 +-
 sound/soc/intel/avs/loader.c      |   4 +-
 sound/soc/intel/avs/path.c        |   2 +-
 sound/soc/intel/avs/pcm.c         |  54 ++++++++--
 sound/soc/intel/avs/probes.c      |   3 +-
 sound/soc/intel/avs/topology.c    |  19 +++-
 sound/soc/intel/skylake/skl-pcm.c |  11 +-
 sound/soc/soc-pcm.c               |  35 ++++++-
 sound/soc/sof/intel/hda-dai-ops.c |   5 +-
 tools/include/uapi/sound/asound.h |   7 +-
 28 files changed, 443 insertions(+), 103 deletions(-)


base-commit: 564ee9ac788b680e4ec4a6cb3a4a953dc61d5da8
-- 
2.25.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 01/17] ALSA: pcm: Introduce MSBITS subformat interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-21  6:25   ` Jaroslav Kysela
  2023-09-18 13:39 ` [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream Cezary Rojewski
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

Improve granularity of format selection for S32/U32 formats by adding
constants representing 20, 24 and MAX most significant bits.

To make it easy for drivers to utilize those constants, introduce
snd_pcm_subformat_width() and snd_pcm_hw_params_bps(). While the former
is self-explanatory, the latter returns the bit-per-sample value based
on format and subformat characteristics of the provided hw_params.
snd_pcm_hw_copy() helps with copying a hardware parameters space as with
introduction of subformats the operations becomes non-trivial.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 include/sound/pcm.h               | 14 +++++++++
 include/sound/pcm_params.h        |  2 ++
 include/uapi/sound/asound.h       |  7 +++--
 sound/core/pcm.c                  |  4 +++
 sound/core/pcm_lib.c              | 28 +++++++++++++++++
 sound/core/pcm_misc.c             | 51 +++++++++++++++++++++++++++++++
 tools/include/uapi/sound/asound.h |  7 +++--
 7 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 2a815373dac1..ddacfedba3ab 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -29,9 +29,15 @@
  *  Hardware (lowlevel) section
  */
 
+struct snd_pcm_subformat {
+	snd_pcm_format_t format;	/* SNDRV_PCM_FORMAT_* */
+	u32 mask;			/* Mask of SNDRV_PCM_SUBFMTBIT_* */
+};
+
 struct snd_pcm_hardware {
 	unsigned int info;		/* SNDRV_PCM_INFO_* */
 	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
+	struct snd_pcm_subformat *subformats;
 	unsigned int rates;		/* SNDRV_PCM_RATE_* */
 	unsigned int rate_min;		/* min rate */
 	unsigned int rate_max;		/* max rate */
@@ -217,6 +223,12 @@ struct snd_pcm_ops {
 #define SNDRV_PCM_FMTBIT_U20		SNDRV_PCM_FMTBIT_U20_BE
 #endif
 
+#define _SNDRV_PCM_SUBFMTBIT(fmt)	BIT((__force int)SNDRV_PCM_SUBFORMAT_##fmt)
+#define SNDRV_PCM_SUBFMTBIT_STD		_SNDRV_PCM_SUBFMTBIT(STD)
+#define SNDRV_PCM_SUBFMTBIT_MSBITS_MAX	_SNDRV_PCM_SUBFMTBIT(MSBITS_MAX)
+#define SNDRV_PCM_SUBFMTBIT_MSBITS_20	_SNDRV_PCM_SUBFMTBIT(MSBITS_20)
+#define SNDRV_PCM_SUBFMTBIT_MSBITS_24	_SNDRV_PCM_SUBFMTBIT(MSBITS_24)
+
 struct snd_pcm_file {
 	struct snd_pcm_substream *substream;
 	int no_compat_mmap;
@@ -1128,6 +1140,7 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format);		/* in bits */
 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
 const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format);
 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames);
+int snd_pcm_subformat_width(snd_pcm_subformat_t subformat);
 
 void snd_pcm_set_ops(struct snd_pcm * pcm, int direction,
 		     const struct snd_pcm_ops *ops);
@@ -1196,6 +1209,7 @@ snd_pcm_kernel_readv(struct snd_pcm_substream *substream,
 	return __snd_pcm_lib_xfer(substream, bufs, false, frames, true);
 }
 
+int snd_pcm_hw_copy(struct snd_pcm_hardware *hw, const struct snd_pcm_hardware *from);
 int snd_pcm_hw_limit_rates(struct snd_pcm_hardware *hw);
 
 static inline int
diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h
index ba184f49f7e1..df17c7d3e853 100644
--- a/include/sound/pcm_params.h
+++ b/include/sound/pcm_params.h
@@ -362,6 +362,8 @@ static inline int params_physical_width(const struct snd_pcm_hw_params *p)
 	return snd_pcm_format_physical_width(params_format(p));
 }
 
+int snd_pcm_hw_params_bps(const struct snd_pcm_hw_params *p);
+
 static inline void
 params_set_format(struct snd_pcm_hw_params *p, snd_pcm_format_t fmt)
 {
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
index f9939da41122..d5b9cfbd9cea 100644
--- a/include/uapi/sound/asound.h
+++ b/include/uapi/sound/asound.h
@@ -142,7 +142,7 @@ struct snd_hwdep_dsp_image {
  *                                                                           *
  *****************************************************************************/
 
-#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 15)
+#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 16)
 
 typedef unsigned long snd_pcm_uframes_t;
 typedef signed long snd_pcm_sframes_t;
@@ -267,7 +267,10 @@ typedef int __bitwise snd_pcm_format_t;
 
 typedef int __bitwise snd_pcm_subformat_t;
 #define	SNDRV_PCM_SUBFORMAT_STD		((__force snd_pcm_subformat_t) 0)
-#define	SNDRV_PCM_SUBFORMAT_LAST	SNDRV_PCM_SUBFORMAT_STD
+#define	SNDRV_PCM_SUBFORMAT_MSBITS_MAX	((__force snd_pcm_subformat_t) 1)
+#define	SNDRV_PCM_SUBFORMAT_MSBITS_20	((__force snd_pcm_subformat_t) 2)
+#define	SNDRV_PCM_SUBFORMAT_MSBITS_24	((__force snd_pcm_subformat_t) 3)
+#define	SNDRV_PCM_SUBFORMAT_LAST	SNDRV_PCM_SUBFORMAT_MSBITS_24
 
 #define SNDRV_PCM_INFO_MMAP		0x00000001	/* hardware supports mmap */
 #define SNDRV_PCM_INFO_MMAP_VALID	0x00000002	/* period data are valid during transfer */
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 20bb2d7c8d4b..74d7f244e81c 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -265,6 +265,9 @@ static const char * const snd_pcm_access_names[] = {
 
 static const char * const snd_pcm_subformat_names[] = {
 	SUBFORMAT(STD), 
+	SUBFORMAT(MSBITS_MAX),
+	SUBFORMAT(MSBITS_20),
+	SUBFORMAT(MSBITS_24),
 };
 
 static const char * const snd_pcm_tstamp_mode_names[] = {
@@ -999,6 +1002,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
 	free_pages_exact(runtime->control,
 		       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
 	kfree(runtime->hw_constraints.rules);
+	kfree(runtime->hw.subformats);
 	/* Avoid concurrent access to runtime via PCM timer interface */
 	if (substream->timer) {
 		spin_lock_irq(&substream->timer->lock);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a11cd7d6295f..05f649b0bf00 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1706,6 +1706,34 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
 }
 EXPORT_SYMBOL(snd_pcm_hw_param_last);
 
+/**
+ * snd_pcm_hw_params_bps - Get the number of bits per the sample.
+ * @p: hardware parameters
+ *
+ * Return: The number of bits per sample based on the format,
+ * subformat and msbits the specified hw params has.
+ */
+int snd_pcm_hw_params_bps(const struct snd_pcm_hw_params *p)
+{
+	snd_pcm_subformat_t subformat = params_subformat(p);
+	snd_pcm_format_t format = params_format(p);
+	int width;
+
+	switch (format) {
+	case SNDRV_PCM_FORMAT_S32_LE:
+	case SNDRV_PCM_FORMAT_U32_LE:
+	case SNDRV_PCM_FORMAT_S32_BE:
+	case SNDRV_PCM_FORMAT_U32_BE:
+		width = snd_pcm_subformat_width(subformat);
+		if (width)
+			return width;
+		fallthrough;
+	default:
+		return snd_pcm_format_width(format);
+	}
+}
+EXPORT_SYMBOL(snd_pcm_hw_params_bps);
+
 static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
 				   void *arg)
 {
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 5588b6a1ee8b..e468b9b82d0c 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -482,6 +482,57 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
 }
 EXPORT_SYMBOL(snd_pcm_format_set_silence);
 
+/**
+ * snd_pcm_subformat_width - return the bit-width of the subformat
+ * @subformat: the subformat to check
+ *
+ * Return: The bit-width of the subformat, or 0 if result is dependent
+ * on other parameters in the configuration space.
+ */
+int snd_pcm_subformat_width(snd_pcm_subformat_t subformat)
+{
+	switch (subformat) {
+	case SNDRV_PCM_SUBFORMAT_MSBITS_20:
+		return 20;
+	case SNDRV_PCM_SUBFORMAT_MSBITS_24:
+		return 24;
+	case SNDRV_PCM_SUBFORMAT_MSBITS_MAX:
+	case SNDRV_PCM_SUBFORMAT_STD:
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL(snd_pcm_subformat_width);
+
+/**
+ * snd_pcm_hw_copy - Copy information of one hardware parameters space into another.
+ * @hw: the space to copy the information into.
+ * @from: the space to copy the information from.
+ *
+ * Return: Zero on success, negative error code otherwise.
+ */
+int snd_pcm_hw_copy(struct snd_pcm_hardware *hw, const struct snd_pcm_hardware *from)
+{
+	struct snd_pcm_subformat *sf = NULL;
+	struct snd_pcm_subformat *pos;
+	u32 count = 1; /* At least a sentinel. */
+
+	if (from->subformats) {
+		for (pos = from->subformats; pos->mask; pos++)
+			count++;
+
+		sf = kmemdup(from->subformats, count * sizeof(*from->subformats), GFP_KERNEL);
+		if (!sf)
+			return -ENOMEM;
+		kfree(hw->subformats);
+	}
+
+	*hw = *from;
+	hw->subformats = sf;
+	return 0;
+}
+EXPORT_SYMBOL(snd_pcm_hw_copy);
+
 /**
  * snd_pcm_hw_limit_rates - determine rate_min/rate_max fields
  * @hw: the pcm hw instance
diff --git a/tools/include/uapi/sound/asound.h b/tools/include/uapi/sound/asound.h
index f9939da41122..d5b9cfbd9cea 100644
--- a/tools/include/uapi/sound/asound.h
+++ b/tools/include/uapi/sound/asound.h
@@ -142,7 +142,7 @@ struct snd_hwdep_dsp_image {
  *                                                                           *
  *****************************************************************************/
 
-#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 15)
+#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 16)
 
 typedef unsigned long snd_pcm_uframes_t;
 typedef signed long snd_pcm_sframes_t;
@@ -267,7 +267,10 @@ typedef int __bitwise snd_pcm_format_t;
 
 typedef int __bitwise snd_pcm_subformat_t;
 #define	SNDRV_PCM_SUBFORMAT_STD		((__force snd_pcm_subformat_t) 0)
-#define	SNDRV_PCM_SUBFORMAT_LAST	SNDRV_PCM_SUBFORMAT_STD
+#define	SNDRV_PCM_SUBFORMAT_MSBITS_MAX	((__force snd_pcm_subformat_t) 1)
+#define	SNDRV_PCM_SUBFORMAT_MSBITS_20	((__force snd_pcm_subformat_t) 2)
+#define	SNDRV_PCM_SUBFORMAT_MSBITS_24	((__force snd_pcm_subformat_t) 3)
+#define	SNDRV_PCM_SUBFORMAT_LAST	SNDRV_PCM_SUBFORMAT_MSBITS_24
 
 #define SNDRV_PCM_INFO_MMAP		0x00000001	/* hardware supports mmap */
 #define SNDRV_PCM_INFO_MMAP_VALID	0x00000002	/* period data are valid during transfer */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 01/17] ALSA: pcm: Introduce MSBITS subformat interface Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-21  6:41   ` Jaroslav Kysela
  2023-09-23 10:55   ` kernel test robot
  2023-09-18 13:39 ` [PATCH v2 03/17] ALSA: hda: Honor subformat when querying PCMs Cezary Rojewski
                   ` (14 subsequent siblings)
  16 siblings, 2 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

Substream value is currently hardcoded to SNDRV_PCM_SUBFORMAT_STD.
Update the constraint procedure so that subformat selection is not
ignored. Case STD is always supported as most PCMs do not care about
subformat.

Suggested-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/core/pcm_native.c | 67 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index bd9ddf412b46..2ea856e95fb2 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -479,6 +479,7 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
 {
 	const struct snd_interval *i;
 	const struct snd_mask *m;
+	struct snd_mask *sfmask;
 	int err;
 
 	if (!params->msbits) {
@@ -487,6 +488,23 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
 			params->msbits = snd_interval_value(i);
 	}
 
+	if (params->msbits) {
+		m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+		if (snd_mask_single(m)) {
+			snd_pcm_format_t format = (__force snd_pcm_format_t)snd_mask_min(m);
+
+			if (snd_pcm_format_linear(format) &&
+			    snd_pcm_format_width(format) != params->msbits) {
+				sfmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT);
+				snd_mask_reset(sfmask,
+					       (__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
+				if (snd_mask_empty(sfmask))
+					return -EINVAL;
+			}
+		}
+	}
+
 	if (!params->rate_den) {
 		i = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
 		if (snd_interval_single(i)) {
@@ -2483,6 +2501,52 @@ static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params,
 	return snd_interval_refine(hw_param_interval(params, rule->var), &t);
 }		
 
+static int snd_pcm_hw_rule_subformats(struct snd_pcm_hw_params *params,
+				      struct snd_pcm_hw_rule *rule)
+{
+	struct snd_mask *sfmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT);
+	struct snd_mask *fmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	struct snd_pcm_hardware *hw = rule->private;
+	struct snd_pcm_subformat *sf;
+	snd_pcm_format_t f;
+	struct snd_mask m;
+	bool found;
+
+	snd_mask_none(&m);
+	/* All PCMs support at least the default STD subformat. */
+	snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_STD);
+
+	if (!hw->subformats)
+		goto exit;
+
+	pcm_for_each_format(f) {
+		if (!snd_mask_test(fmask, f))
+			continue;
+
+		found = false;
+		for (sf = hw->subformats; sf->mask && !found; sf++) {
+			if (sf->format != f)
+				continue;
+			m.bits[0] |= sf->mask;
+			found = true;
+		}
+		if (!found && snd_pcm_format_linear(f))
+			snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
+	}
+exit:
+	return snd_mask_refine(sfmask, &m);
+}
+
+static int snd_pcm_hw_constraint_subformats(struct snd_pcm_runtime *runtime,
+					   unsigned int cond,
+					   struct snd_pcm_hardware *hw)
+{
+	return snd_pcm_hw_rule_add(runtime, cond, -1,
+				   snd_pcm_hw_rule_subformats, (void *)hw,
+				   SNDRV_PCM_HW_PARAM_SUBFORMAT,
+				   SNDRV_PCM_HW_PARAM_FORMAT, -1);
+}
+
 static int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -2634,8 +2698,7 @@ static int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
 	if (err < 0)
 		return err;
 
-	err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT,
-					 PARAM_MASK_BIT(SNDRV_PCM_SUBFORMAT_STD));
+	err = snd_pcm_hw_constraint_subformats(runtime, 0, hw);
 	if (err < 0)
 		return err;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 03/17] ALSA: hda: Honor subformat when querying PCMs
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 01/17] ALSA: pcm: Introduce MSBITS subformat interface Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 04/17] ASoC: pcm: Honor subformat when configuring runtime Cezary Rojewski
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

Update mechanism for querying supported PCMs to allow for granular
format selection when container size is 32 bits. Currently always the
highest bit depth is selected, regardless of how many actual formats
codec in question supports.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 include/sound/hda_codec.h    |  5 ++--
 include/sound/hdaudio.h      |  4 ++-
 sound/hda/hdac_device.c      | 52 ++++++++++++++++++++++--------------
 sound/pci/hda/hda_codec.c    |  5 ++++
 sound/pci/hda/patch_hdmi.c   |  1 +
 sound/soc/codecs/hdac_hdmi.c |  3 ++-
 6 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
index 5497dc9c396a..6db063d5a7fe 100644
--- a/include/sound/hda_codec.h
+++ b/include/sound/hda_codec.h
@@ -141,6 +141,7 @@ struct hda_pcm_stream {
 	hda_nid_t nid;	/* default NID to query rates/formats/bps, or set up */
 	u32 rates;	/* supported rates */
 	u64 formats;	/* supported formats (SNDRV_PCM_FMTBIT_) */
+	const struct snd_pcm_subformat *subformats;
 	unsigned int maxbps;	/* supported max. bit per sample */
 	const struct snd_pcm_chmap_elem *chmap; /* chmap to override */
 	struct hda_pcm_ops ops;
@@ -448,8 +449,8 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
 #define snd_hda_codec_cleanup_stream(codec, nid) \
 	__snd_hda_codec_cleanup_stream(codec, nid, 0)
 
-#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, bpsp) \
-	snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, bpsp)
+#define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, subfmtp, bpsp) \
+	snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, subfmtp, bpsp)
 #define snd_hda_is_supported_format(codec, nid, fmt) \
 	snd_hdac_is_supported_format(&(codec)->core, nid, fmt)
 
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 32c59053b48e..a2f10f7785bb 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -146,7 +146,9 @@ unsigned int snd_hdac_calc_stream_format(unsigned int rate,
 					 unsigned int maxbps,
 					 unsigned short spdif_ctls);
 int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
-				u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
+				 u32 *ratesp, u64 *formatsp,
+				 const struct snd_pcm_subformat **subformatsp,
+				 unsigned int *bpsp);
 bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
 				  unsigned int format);
 
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index bbf7bcdb449a..a2ce4ea809b3 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -817,15 +817,18 @@ static unsigned int query_stream_param(struct hdac_device *codec, hda_nid_t nid)
  * @nid: NID to query
  * @ratesp: the pointer to store the detected rate bitflags
  * @formatsp: the pointer to store the detected formats
+ * @subformatsp: the pointer to store the detected subformats
  * @bpsp: the pointer to store the detected format widths
  *
- * Queries the supported PCM rates and formats.  The NULL @ratesp, @formatsp
- * or @bsps argument is ignored.
+ * Queries the supported PCM rates and formats.  The NULL @ratesp, @formatsp,
+ * @subformatsp or @bpsp argument is ignored.
  *
  * Returns 0 if successful, otherwise a negative error code.
  */
 int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
-				 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
+				 u32 *ratesp, u64 *formatsp,
+				 const struct snd_pcm_subformat **subformatsp,
+				 unsigned int *bpsp)
 {
 	unsigned int i, val, wcaps;
 
@@ -848,9 +851,13 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
 		*ratesp = rates;
 	}
 
-	if (formatsp || bpsp) {
-		u64 formats = 0;
+	if (formatsp || subformatsp || bpsp) {
+		struct snd_pcm_subformat subformats[] = {
+			{ .format = SNDRV_PCM_FORMAT_S32_LE, },
+			{}
+		};
 		unsigned int streams, bps;
+		u64 formats = 0;
 
 		streams = query_stream_param(codec, nid);
 		if (!streams)
@@ -866,24 +873,24 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
 				formats |= SNDRV_PCM_FMTBIT_S16_LE;
 				bps = 16;
 			}
-			if (wcaps & AC_WCAP_DIGITAL) {
-				if (val & AC_SUPPCM_BITS_32)
+			if (val & AC_SUPPCM_BITS_20) {
+				formats |= SNDRV_PCM_FMTBIT_S32_LE;
+				subformats[0].mask |= SNDRV_PCM_SUBFMTBIT_MSBITS_20;
+				bps = 20;
+			}
+			if (val & AC_SUPPCM_BITS_24) {
+				formats |= SNDRV_PCM_FMTBIT_S32_LE;
+				subformats[0].mask |= SNDRV_PCM_SUBFMTBIT_MSBITS_24;
+				bps = 24;
+			}
+			if (val & AC_SUPPCM_BITS_32) {
+				if (wcaps & AC_WCAP_DIGITAL) {
 					formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
-				if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
+				} else {
 					formats |= SNDRV_PCM_FMTBIT_S32_LE;
-				if (val & AC_SUPPCM_BITS_24)
-					bps = 24;
-				else if (val & AC_SUPPCM_BITS_20)
-					bps = 20;
-			} else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
-					  AC_SUPPCM_BITS_32)) {
-				formats |= SNDRV_PCM_FMTBIT_S32_LE;
-				if (val & AC_SUPPCM_BITS_32)
+					subformats[0].mask |= SNDRV_PCM_SUBFMTBIT_MSBITS_MAX;
 					bps = 32;
-				else if (val & AC_SUPPCM_BITS_24)
-					bps = 24;
-				else if (val & AC_SUPPCM_BITS_20)
-					bps = 20;
+				}
 			}
 		}
 #if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */
@@ -911,6 +918,11 @@ int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
 		}
 		if (formatsp)
 			*formatsp = formats;
+		if (subformatsp) {
+			*subformatsp = kmemdup(subformats, sizeof(subformats), GFP_KERNEL);
+			if (!*subformatsp)
+				return -ENOMEM;
+		}
 		if (bpsp)
 			*bpsp = bps;
 	}
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 33af707a65ab..8cd2db528bbd 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -755,12 +755,15 @@ void snd_hda_codec_disconnect_pcms(struct hda_codec *codec)
 static void codec_release_pcms(struct hda_codec *codec)
 {
 	struct hda_pcm *pcm, *n;
+	int dir;
 
 	list_for_each_entry_safe(pcm, n, &codec->pcm_list_head, list) {
 		list_del(&pcm->list);
 		if (pcm->pcm)
 			snd_device_free(pcm->codec->card, pcm->pcm);
 		clear_bit(pcm->device, pcm->codec->bus->pcm_dev_bits);
+		for_each_pcm_streams(dir)
+			kfree(pcm->stream[dir].subformats);
 		kfree(pcm->name);
 		kfree(pcm);
 	}
@@ -3163,6 +3166,7 @@ static int set_pcm_default_values(struct hda_codec *codec,
 		err = snd_hda_query_supported_pcm(codec, info->nid,
 				info->rates ? NULL : &info->rates,
 				info->formats ? NULL : &info->formats,
+				info->subformats ? NULL : &info->subformats,
 				info->maxbps ? NULL : &info->maxbps);
 		if (err < 0)
 			return err;
@@ -3757,6 +3761,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
 			snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
 						    &mout->spdif_rates,
 						    &mout->spdif_formats,
+						    NULL,
 						    &mout->spdif_maxbps);
 		}
 		mutex_lock(&codec->spdif_mutex);
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 1cde2a69bdb4..687b8b8fd7ac 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1977,6 +1977,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
 	err = snd_hda_query_supported_pcm(codec, cvt_nid,
 					  &per_cvt->rates,
 					  &per_cvt->formats,
+					  NULL,
 					  &per_cvt->maxbps);
 	if (err < 0)
 		return err;
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index b9c5ffbfb5ba..3e4f632d8665 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -670,6 +670,7 @@ hdac_hdmi_query_cvt_params(struct hdac_device *hdev, struct hdac_hdmi_cvt *cvt)
 	err = snd_hdac_query_supported_pcm(hdev, cvt->nid,
 			&cvt->params.rates,
 			&cvt->params.formats,
+			NULL,
 			&cvt->params.maxbps);
 	if (err < 0)
 		dev_err(&hdev->dev,
@@ -1577,7 +1578,7 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdev,
 
 	list_for_each_entry(cvt, &hdmi->cvt_list, head) {
 		ret = snd_hdac_query_supported_pcm(hdev, cvt->nid,
-					&rates,	&formats, &bps);
+					&rates,	&formats, NULL, &bps);
 		if (ret)
 			return ret;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 04/17] ASoC: pcm: Honor subformat when configuring runtime
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (2 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 03/17] ALSA: hda: Honor subformat when querying PCMs Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-19 12:50   ` Mark Brown
  2023-09-21  6:57   ` Jaroslav Kysela
  2023-09-18 13:39 ` [PATCH v2 05/17] ALSA: hda: Upgrade stream-format infrastructure Cezary Rojewski
                   ` (12 subsequent siblings)
  16 siblings, 2 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

Subformat options are ignored when setting up hardware parameters and
assigning PCM stream capabilities. Account for them to allow for
granular format selection.

With introduction of subformats, copying hardware parameters becomes
a non-trivial operation. Implement a helper function to make things
simple.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 include/sound/soc.h |  1 +
 sound/soc/soc-pcm.c | 35 ++++++++++++++++++++++++++++++++---
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 81ed08c5c67d..0d3158a7715e 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -620,6 +620,7 @@ enum snd_soc_trigger_order {
 struct snd_soc_pcm_stream {
 	const char *stream_name;
 	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
+	const struct snd_pcm_subformat *subformats;
 	unsigned int rates;		/* SNDRV_PCM_RATE_* */
 	unsigned int rate_min;		/* min rate */
 	unsigned int rate_max;		/* max rate */
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 54704250c0a2..b57795feb5f8 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -336,9 +336,7 @@ bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
 int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
 	const struct snd_pcm_hardware *hw)
 {
-	substream->runtime->hw = *hw;
-
-	return 0;
+	return snd_pcm_hw_copy(&substream->runtime->hw, hw);
 }
 EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
 
@@ -554,6 +552,33 @@ static void soc_pcm_hw_update_format(struct snd_pcm_hardware *hw,
 	hw->formats &= p->formats;
 }
 
+static void soc_pcm_hw_update_subformat(struct snd_pcm_hardware *hw,
+					struct snd_soc_pcm_stream *p)
+{
+	const struct snd_pcm_subformat *sf2;
+	struct snd_pcm_subformat *sf1;
+	u32 last = 0;
+
+	if (!hw->subformats || !p->subformats)
+		return;
+
+	for (sf1 = hw->subformats; sf1->mask; sf1++)
+		last++;
+
+	for (sf1 = hw->subformats; sf1->mask; sf1++) {
+		for (sf2 = p->subformats; sf2->mask; sf2++) {
+			if (sf1->format != sf2->format)
+				continue;
+
+			sf1->mask &= sf2->mask;
+			if (!sf1->mask) {
+				swap(*sf1, hw->subformats[last]);
+				last--;
+			}
+		}
+	}
+}
+
 /**
  * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream
  * @rtd: ASoC PCM runtime
@@ -592,6 +617,7 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
 		soc_pcm_hw_update_chan(hw, cpu_stream);
 		soc_pcm_hw_update_rate(hw, cpu_stream);
 		soc_pcm_hw_update_format(hw, cpu_stream);
+		soc_pcm_hw_update_subformat(hw, cpu_stream);
 	}
 	cpu_chan_min = hw->channels_min;
 	cpu_chan_max = hw->channels_max;
@@ -613,6 +639,7 @@ int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
 		soc_pcm_hw_update_chan(hw, codec_stream);
 		soc_pcm_hw_update_rate(hw, codec_stream);
 		soc_pcm_hw_update_format(hw, codec_stream);
+		soc_pcm_hw_update_subformat(hw, codec_stream);
 	}
 
 	/* Verify both a valid CPU DAI and a valid CODEC DAI were found */
@@ -1698,6 +1725,7 @@ static void dpcm_runtime_setup_fe(struct snd_pcm_substream *substream)
 		soc_pcm_hw_update_rate(hw, cpu_stream);
 		soc_pcm_hw_update_chan(hw, cpu_stream);
 		soc_pcm_hw_update_format(hw, cpu_stream);
+		soc_pcm_hw_update_subformat(hw, cpu_stream);
 	}
 
 }
@@ -1735,6 +1763,7 @@ static void dpcm_runtime_setup_be_format(struct snd_pcm_substream *substream)
 			codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
 
 			soc_pcm_hw_update_format(hw, codec_stream);
+			soc_pcm_hw_update_subformat(hw, codec_stream);
 		}
 	}
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 05/17] ALSA: hda: Upgrade stream-format infrastructure
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (3 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 04/17] ASoC: pcm: Honor subformat when configuring runtime Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 06/17] ALSA: hda: Switch to new stream-format interface Cezary Rojewski
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

Introduce a set of functions that facilite SDxFMT-related calculations
in atomic manner:

snd_hdac_format_normalize() - format converter. S20_LE, S24_LE and their
unsigned and BE friends are invalid from HDAudio perspective but still
can be specified as function argument due to compatibility reasons.

snd_hdac_stream_format_bps() - obtain just the bits-per-sample value.
Does not ignore subformat and msbits parameters.

snd_hdac_stream_format() and snd_hdac_spdif_stream_format() - obtain the
SDxFMT value given the audio format parameters. The former is stripped
away of spdif-related information. Useful for users that do not care
about them.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 include/sound/hdaudio.h |   5 ++
 sound/hda/hdac_device.c | 124 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+)

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index a2f10f7785bb..589812c6f6ce 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -140,6 +140,11 @@ int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
 			     hda_nid_t *conn_list, int max_conns);
 int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
 			   hda_nid_t *start_id);
+unsigned int snd_hdac_stream_format_bps(snd_pcm_format_t format, snd_pcm_subformat_t subformat,
+					unsigned int maxbps);
+unsigned int snd_hdac_stream_format(unsigned int channels, unsigned int bps, unsigned int rate);
+unsigned int snd_hdac_spdif_stream_format(unsigned int channels, unsigned int bps,
+					  unsigned int rate, unsigned short spdif_ctls);
 unsigned int snd_hdac_calc_stream_format(unsigned int rate,
 					 unsigned int channels,
 					 snd_pcm_format_t format,
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index a2ce4ea809b3..ff5f45b95be4 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -13,6 +13,7 @@
 #include <sound/hdaudio.h>
 #include <sound/hda_regmap.h>
 #include <sound/pcm.h>
+#include <sound/pcm_params.h>
 #include "local.h"
 
 static void setup_fg_nodes(struct hdac_device *codec);
@@ -725,6 +726,129 @@ static const struct hda_rate_tbl rate_bits[] = {
 	{ 0 } /* terminator */
 };
 
+static snd_pcm_format_t snd_hdac_format_normalize(snd_pcm_format_t format)
+{
+	switch (format) {
+	case SNDRV_PCM_FORMAT_S20_LE:
+	case SNDRV_PCM_FORMAT_S24_LE:
+		return SNDRV_PCM_FORMAT_S32_LE;
+
+	case SNDRV_PCM_FORMAT_U20_LE:
+	case SNDRV_PCM_FORMAT_U24_LE:
+		return SNDRV_PCM_FORMAT_U32_LE;
+
+	case SNDRV_PCM_FORMAT_S20_BE:
+	case SNDRV_PCM_FORMAT_S24_BE:
+		return SNDRV_PCM_FORMAT_S32_BE;
+
+	case SNDRV_PCM_FORMAT_U20_BE:
+	case SNDRV_PCM_FORMAT_U24_BE:
+		return SNDRV_PCM_FORMAT_U32_BE;
+
+	default:
+		return format;
+	}
+}
+
+/**
+ * snd_hdac_stream_format_bps - obtain bits per sample value.
+ * @format:	the PCM format.
+ * @subformat:	the PCM subformat.
+ * @maxbps:	the maximum bits per sample.
+ *
+ * Return: The number of bits per sample.
+ */
+unsigned int snd_hdac_stream_format_bps(snd_pcm_format_t format, snd_pcm_subformat_t subformat,
+					unsigned int maxbps)
+{
+	struct snd_pcm_hw_params params;
+	unsigned int bps;
+
+	memset(&params, 0, sizeof(params));
+
+	params_set_format(&params, snd_hdac_format_normalize(format));
+	snd_mask_set(hw_param_mask(&params, SNDRV_PCM_HW_PARAM_SUBFORMAT),
+		     (__force unsigned int)subformat);
+
+	bps = snd_pcm_hw_params_bps(&params);
+	if (maxbps)
+		return min(bps, maxbps);
+	return bps;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_stream_format_bps);
+
+/**
+ * snd_hdac_stream_format - convert format parameters to SDxFMT value.
+ * @channels:	the number of channels.
+ * @bps:	bits per sample.
+ * @rate:	the sample rate.
+ *
+ * Return: The format bitset or zero if invalid.
+ */
+unsigned int snd_hdac_stream_format(unsigned int channels, unsigned int bps, unsigned int rate)
+{
+	unsigned int val = 0;
+	int i;
+
+	for (i = 0; rate_bits[i].hz; i++) {
+		if (rate_bits[i].hz == rate) {
+			val = rate_bits[i].hda_fmt;
+			break;
+		}
+	}
+
+	if (!rate_bits[i].hz)
+		return 0;
+
+	if (channels == 0 || channels > 8)
+		return 0;
+	val |= channels - 1;
+
+	switch (bps) {
+	case 8:
+		val |= AC_FMT_BITS_8;
+		break;
+	case 16:
+		val |= AC_FMT_BITS_16;
+		break;
+	case 20:
+		val |= AC_FMT_BITS_20;
+		break;
+	case 24:
+		val |= AC_FMT_BITS_24;
+		break;
+	case 32:
+		val |= AC_FMT_BITS_32;
+		break;
+	default:
+		return 0;
+	}
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_stream_format);
+
+/**
+ * snd_hdac_spdif_stream_format - convert format parameters to SDxFMT value.
+ * @channels:	the number of channels.
+ * @bps:	bits per sample.
+ * @rate:	the sample rate.
+ * @spdif_ctls:	HD-audio SPDIF status bits (0 if irrelevant).
+ *
+ * Return: The format bitset or zero if invalid.
+ */
+unsigned int snd_hdac_spdif_stream_format(unsigned int channels, unsigned int bps,
+					  unsigned int rate, unsigned short spdif_ctls)
+{
+	unsigned int val = snd_hdac_stream_format(channels, bps, rate);
+
+	if (val && spdif_ctls & AC_DIG1_NONAUDIO)
+		val |= AC_FMT_TYPE_NON_PCM;
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_spdif_stream_format);
+
 /**
  * snd_hdac_calc_stream_format - calculate the format bitset
  * @rate: the sample rate
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 06/17] ALSA: hda: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (4 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 05/17] ALSA: hda: Upgrade stream-format infrastructure Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 07/17] ALSA: hda/hdmi: " Cezary Rojewski
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/pci/hda/hda_controller.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 406779625fb5..0646ef0afd49 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -151,7 +151,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
 	struct azx_dev *azx_dev = get_azx_dev(substream);
 	struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	unsigned int format_val, stream_tag;
+	unsigned int format_val, stream_tag, bps;
 	int err;
 	struct hda_spdif_out *spdif =
 		snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
@@ -165,11 +165,9 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
 	}
 
 	snd_hdac_stream_reset(azx_stream(azx_dev));
-	format_val = snd_hdac_calc_stream_format(runtime->rate,
-						runtime->channels,
-						runtime->format,
-						hinfo->maxbps,
-						ctls);
+	bps = snd_hdac_stream_format_bps(runtime->format, SNDRV_PCM_SUBFORMAT_STD, hinfo->maxbps);
+
+	format_val = snd_hdac_spdif_stream_format(runtime->channels, bps, runtime->rate, ctls);
 	if (!format_val) {
 		dev_err(chip->card->dev,
 			"invalid format_val, rate=%d, ch=%d, format=%d\n",
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 07/17] ALSA: hda/hdmi: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (5 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 06/17] ALSA: hda: Switch to new stream-format interface Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 08/17] ALSA: hda/ca0132: " Cezary Rojewski
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/pci/hda/patch_hdmi.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 687b8b8fd7ac..dff2d7221982 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1655,7 +1655,6 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
 
 #define I915_SILENT_RATE		48000
 #define I915_SILENT_CHANNELS		2
-#define I915_SILENT_FORMAT		SNDRV_PCM_FORMAT_S16_LE
 #define I915_SILENT_FORMAT_BITS	16
 #define I915_SILENT_FMT_MASK		0xf
 
@@ -1668,8 +1667,8 @@ static void silent_stream_enable_i915(struct hda_codec *codec,
 				 per_pin->dev_id, I915_SILENT_RATE);
 
 	/* trigger silent stream generation in hw */
-	format = snd_hdac_calc_stream_format(I915_SILENT_RATE, I915_SILENT_CHANNELS,
-					     I915_SILENT_FORMAT, I915_SILENT_FORMAT_BITS, 0);
+	format = snd_hdac_stream_format(I915_SILENT_CHANNELS, I915_SILENT_FORMAT_BITS,
+					I915_SILENT_RATE);
 	snd_hda_codec_setup_stream(codec, per_pin->cvt_nid,
 				   I915_SILENT_FMT_MASK, I915_SILENT_FMT_MASK, format);
 	usleep_range(100, 200);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 08/17] ALSA: hda/ca0132: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (6 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 07/17] ALSA: hda/hdmi: " Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 09/17] ASoC: codecs: hda: " Cezary Rojewski
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/pci/hda/patch_ca0132.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 748a3c40966e..aa312441604f 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -3022,8 +3022,7 @@ static int dma_convert_to_hda_format(struct hda_codec *codec,
 {
 	unsigned int format_val;
 
-	format_val = snd_hdac_calc_stream_format(sample_rate,
-				channels, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
+	format_val = snd_hdac_stream_format(channels, 32, sample_rate);
 
 	if (hda_format)
 		*hda_format = (unsigned short)format_val;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 09/17] ASoC: codecs: hda: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (7 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 08/17] ALSA: hda/ca0132: " Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 10/17] ASoC: codecs: hdac_hda: " Cezary Rojewski
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

While at it, complete PCM stream initialization with subformat options.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/codecs/hda-dai.c | 6 ++++--
 sound/soc/codecs/hda.c     | 2 ++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/sound/soc/codecs/hda-dai.c b/sound/soc/codecs/hda-dai.c
index 5371ff086261..20b070c66c6f 100644
--- a/sound/soc/codecs/hda-dai.c
+++ b/sound/soc/codecs/hda-dai.c
@@ -76,13 +76,15 @@ static int hda_codec_dai_prepare(struct snd_pcm_substream *substream, struct snd
 	struct hdac_stream *stream;
 	struct hda_codec *codec;
 	unsigned int format;
+	unsigned int bps;
 	int ret;
 
 	codec = dev_to_hda_codec(dai->dev);
 	stream = substream->runtime->private_data;
 	stream_info = snd_soc_dai_get_dma_data(dai, substream);
-	format = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
-					     runtime->sample_bits, 0);
+
+	bps = snd_hdac_stream_format_bps(runtime->format, runtime->subformat, stream_info->maxbps);
+	format = snd_hdac_stream_format(runtime->channels, bps, runtime->rate);
 
 	ret = snd_hda_codec_prepare(codec, stream_info, stream->stream_tag, format, substream);
 	if (ret < 0) {
diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c
index d57b043d6bfe..d2117e36ddd1 100644
--- a/sound/soc/codecs/hda.c
+++ b/sound/soc/codecs/hda.c
@@ -52,6 +52,7 @@ static int hda_codec_create_dais(struct hda_codec *codec, int pcm_count,
 		stream->channels_max = pcm->stream[dir].channels_max;
 		stream->rates = pcm->stream[dir].rates;
 		stream->formats = pcm->stream[dir].formats;
+		stream->subformats = pcm->stream[dir].subformats;
 		stream->sig_bits = pcm->stream[dir].maxbps;
 
 capture_dais:
@@ -71,6 +72,7 @@ static int hda_codec_create_dais(struct hda_codec *codec, int pcm_count,
 		stream->channels_max = pcm->stream[dir].channels_max;
 		stream->rates = pcm->stream[dir].rates;
 		stream->formats = pcm->stream[dir].formats;
+		stream->subformats = pcm->stream[dir].subformats;
 		stream->sig_bits = pcm->stream[dir].maxbps;
 	}
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 10/17] ASoC: codecs: hdac_hda: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (8 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 09/17] ASoC: codecs: hda: " Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 11/17] ASoC: codecs: hdac_hdmi: " Cezary Rojewski
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/codecs/hdac_hda.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index be66853afbe2..7e308dac07d4 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -207,18 +207,16 @@ static int hdac_hda_dai_hw_params(struct snd_pcm_substream *substream,
 	struct hdac_hda_priv *hda_pvt;
 	unsigned int format_val;
 	unsigned int maxbps;
+	unsigned int bps;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		maxbps = dai->driver->playback.sig_bits;
 	else
 		maxbps = dai->driver->capture.sig_bits;
+	bps = snd_hdac_stream_format_bps(params_format(params), SNDRV_PCM_SUBFORMAT_STD, maxbps);
 
 	hda_pvt = snd_soc_component_get_drvdata(component);
-	format_val = snd_hdac_calc_stream_format(params_rate(params),
-						 params_channels(params),
-						 params_format(params),
-						 maxbps,
-						 0);
+	format_val = snd_hdac_stream_format(params_channels(params), bps, params_rate(params));
 	if (!format_val) {
 		dev_err(dai->dev,
 			"invalid format_val, rate=%d, ch=%d, format=%d, maxbps=%d\n",
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 11/17] ASoC: codecs: hdac_hdmi: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (9 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 10/17] ASoC: codecs: hdac_hda: " Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 12/17] ASoC: Intel Skylake: " Cezary Rojewski
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/codecs/hdac_hdmi.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 3e4f632d8665..824fb4862f22 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -468,13 +468,14 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
 	struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
 	struct hdac_hdmi_dai_port_map *dai_map;
 	struct hdac_hdmi_pcm *pcm;
+	unsigned int bps;
 	int format;
 
 	dai_map = &hdmi->dai_map[dai->id];
 
-	format = snd_hdac_calc_stream_format(params_rate(hparams),
-			params_channels(hparams), params_format(hparams),
-			dai->driver->playback.sig_bits, 0);
+	bps = snd_hdac_stream_format_bps(params_format(hparams), SNDRV_PCM_SUBFORMAT_STD,
+					 dai->driver->playback.sig_bits);
+	format = snd_hdac_stream_format(params_channels(hparams), bps, params_rate(hparams));
 
 	pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
 	if (!pcm)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 12/17] ASoC: Intel Skylake: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (10 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 11/17] ASoC: codecs: hdac_hdmi: " Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 13/17] ASoC: SOF: Intel: " Cezary Rojewski
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/skylake/skl-pcm.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index ac3dc8c63c26..4613a1335819 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -128,6 +128,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
 	unsigned int format_val;
 	struct hdac_stream *hstream;
 	struct hdac_ext_stream *stream;
+	unsigned int bps;
 	int err;
 
 	hstream = snd_hdac_get_stream(bus, params->stream,
@@ -138,8 +139,8 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params)
 	stream = stream_to_hdac_ext_stream(hstream);
 	snd_hdac_ext_stream_decouple(bus, stream, true);
 
-	format_val = snd_hdac_calc_stream_format(params->s_freq,
-			params->ch, params->format, params->host_bps, 0);
+	bps = snd_hdac_stream_format_bps(params->format, SNDRV_PCM_SUBFORMAT_STD, params->host_bps);
+	format_val = snd_hdac_stream_format(params->ch, bps, params->s_freq);
 
 	dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
 		format_val, params->s_freq, params->ch, params->format);
@@ -177,6 +178,7 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
 	struct hdac_ext_stream *stream;
 	struct hdac_ext_link *link;
 	unsigned char stream_tag;
+	unsigned int bps;
 
 	hstream = snd_hdac_get_stream(bus, params->stream,
 					params->link_dma_id + 1);
@@ -185,8 +187,9 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params)
 
 	stream = stream_to_hdac_ext_stream(hstream);
 	snd_hdac_ext_stream_decouple(bus, stream, true);
-	format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch,
-					params->format, params->link_bps, 0);
+
+	bps = snd_hdac_stream_format_bps(params->format, SNDRV_PCM_SUBFORMAT_STD, params->link_bps);
+	format_val = snd_hdac_stream_format(params->ch, bps, params->s_freq);
 
 	dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
 		format_val, params->s_freq, params->ch, params->format);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 13/17] ASoC: SOF: Intel: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (11 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 12/17] ASoC: Intel Skylake: " Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 14/17] ASoC: Intel: avs: " Cezary Rojewski
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/sof/intel/hda-dai-ops.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sof/intel/hda-dai-ops.c b/sound/soc/sof/intel/hda-dai-ops.c
index 494ced2b746e..fb5989888ff4 100644
--- a/sound/soc/sof/intel/hda-dai-ops.c
+++ b/sound/soc/sof/intel/hda-dai-ops.c
@@ -208,14 +208,15 @@ static unsigned int hda_calc_stream_format(struct snd_sof_dev *sdev,
 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
 	unsigned int link_bps;
 	unsigned int format_val;
+	unsigned int bps;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		link_bps = codec_dai->driver->playback.sig_bits;
 	else
 		link_bps = codec_dai->driver->capture.sig_bits;
+	bps = snd_hdac_stream_format_bps(params_format(params), SNDRV_PCM_SUBFORMAT_STD, link_bps);
 
-	format_val = snd_hdac_calc_stream_format(params_rate(params), params_channels(params),
-						 params_format(params), link_bps, 0);
+	format_val = snd_hdac_stream_format(params_channels(params), bps, params_rate(params));
 
 	dev_dbg(sdev->dev, "format_val=%#x, rate=%d, ch=%d, format=%d\n", format_val,
 		params_rate(params), params_channels(params), params_format(params));
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 14/17] ASoC: Intel: avs: Switch to new stream-format interface
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (12 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 13/17] ASoC: SOF: Intel: " Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 15/17] ALSA: hda: Drop snd_hdac_calc_stream_format() Cezary Rojewski
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To provide option for selecting different bit-per-sample than just the
maximum one, use the new format calculation mechanism.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/loader.c |  4 ++--
 sound/soc/intel/avs/path.c   |  2 +-
 sound/soc/intel/avs/pcm.c    | 19 ++++++++++++++-----
 sound/soc/intel/avs/probes.c |  3 +--
 4 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c
index 56bb0a59249d..2e3dd3d86b16 100644
--- a/sound/soc/intel/avs/loader.c
+++ b/sound/soc/intel/avs/loader.c
@@ -371,7 +371,7 @@ int avs_hda_load_basefw(struct avs_dev *adev, struct firmware *fw)
 	hstream = hdac_stream(estream);
 
 	/* code loading performed with default format */
-	sdfmt = snd_hdac_calc_stream_format(48000, 1, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
+	sdfmt = snd_hdac_stream_format(1, 32, 48000);
 	ret = snd_hdac_dsp_prepare(hstream, sdfmt, fw->size, &dmab);
 	if (ret < 0)
 		goto release_stream;
@@ -438,7 +438,7 @@ int avs_hda_load_library(struct avs_dev *adev, struct firmware *lib, u32 id)
 	stream = hdac_stream(estream);
 
 	/* code loading performed with default format */
-	sdfmt = snd_hdac_calc_stream_format(48000, 1, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
+	sdfmt = snd_hdac_stream_format(1, 32, 48000);
 	ret = snd_hdac_dsp_prepare(stream, sdfmt, lib->size, &dmab);
 	if (ret < 0)
 		goto release_stream;
diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index adbe23a47847..be9e455ee0a2 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -87,7 +87,7 @@ static bool avs_test_hw_params(struct snd_pcm_hw_params *params,
 	return (params_rate(params) == fmt->sampling_freq &&
 		params_channels(params) == fmt->num_channels &&
 		params_physical_width(params) == fmt->bit_depth &&
-		params_width(params) == fmt->valid_bit_depth);
+		snd_pcm_hw_params_bps(params) == fmt->valid_bit_depth);
 }
 
 static struct avs_tplg_path *
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 8565a530706d..2a8aa4e6ce67 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -335,20 +335,25 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn
 {
 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct hdac_ext_stream *link_stream = runtime->private_data;
+	struct snd_soc_pcm_stream *stream_info;
+	struct hdac_ext_stream *link_stream;
 	struct hdac_ext_link *link;
 	struct hda_codec *codec;
 	struct hdac_bus *bus;
 	unsigned int format_val;
+	unsigned int bps;
 	int ret;
 
+	link_stream = runtime->private_data;
 	if (link_stream->link_prepared)
 		return 0;
 
 	codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev);
 	bus = &codec->bus->core;
-	format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
-						 runtime->sample_bits, 0);
+	stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
+	bps = snd_hdac_stream_format_bps(runtime->format, runtime->subformat,
+					 stream_info->sig_bits);
+	format_val = snd_hdac_stream_format(runtime->channels, bps, runtime->rate);
 
 	snd_hdac_ext_stream_decouple(bus, link_stream, true);
 	snd_hdac_ext_stream_reset(link_stream);
@@ -601,11 +606,13 @@ static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_so
 static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_stream *stream_info;
 	struct avs_dma_data *data;
 	struct avs_dev *adev = to_avs_dev(dai->dev);
 	struct hdac_ext_stream *host_stream;
 	struct hdac_bus *bus;
 	unsigned int format_val;
+	unsigned int bps;
 	int ret;
 
 	data = snd_soc_dai_get_dma_data(dai, substream);
@@ -618,8 +625,10 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so
 	snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
 	snd_hdac_stream_reset(hdac_stream(host_stream));
 
-	format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format,
-						 runtime->sample_bits, 0);
+	stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
+	bps = snd_hdac_stream_format_bps(runtime->format, runtime->subformat,
+					 stream_info->sig_bits);
+	format_val = snd_hdac_stream_format(runtime->channels, bps, runtime->rate);
 
 	ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
 	if (ret < 0)
diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c
index 4cab8c6c4576..7d0aab3f2ada 100644
--- a/sound/soc/intel/avs/probes.c
+++ b/sound/soc/intel/avs/probes.c
@@ -140,8 +140,7 @@ static int avs_probe_compr_set_params(struct snd_compr_stream *cstream,
 	bps = snd_pcm_format_physical_width(format);
 	if (bps < 0)
 		return bps;
-	format_val = snd_hdac_calc_stream_format(params->codec.sample_rate, params->codec.ch_out,
-						 format, bps, 0);
+	format_val = snd_hdac_stream_format(params->codec.ch_out, bps, params->codec.sample_rate);
 	ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
 	if (ret < 0)
 		return ret;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 15/17] ALSA: hda: Drop snd_hdac_calc_stream_format()
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (13 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 14/17] ASoC: Intel: avs: " Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 15:11   ` kernel test robot
  2023-09-18 13:39 ` [PATCH v2 16/17] ASoC: Intel: avs: Kill S24_LE in HDAudio streaming Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 17/17] ASoC: Intel: avs: Unhardcode HDAudio BE DAI drivers description Cezary Rojewski
  16 siblings, 1 reply; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

There are no users of the function.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 include/sound/hdaudio.h |  5 ----
 sound/hda/hdac_device.c | 61 -----------------------------------------
 2 files changed, 66 deletions(-)

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 589812c6f6ce..b6e4529279f9 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -145,11 +145,6 @@ unsigned int snd_hdac_stream_format_bps(snd_pcm_format_t format, snd_pcm_subform
 unsigned int snd_hdac_stream_format(unsigned int channels, unsigned int bps, unsigned int rate);
 unsigned int snd_hdac_spdif_stream_format(unsigned int channels, unsigned int bps,
 					  unsigned int rate, unsigned short spdif_ctls);
-unsigned int snd_hdac_calc_stream_format(unsigned int rate,
-					 unsigned int channels,
-					 snd_pcm_format_t format,
-					 unsigned int maxbps,
-					 unsigned short spdif_ctls);
 int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
 				 u32 *ratesp, u64 *formatsp,
 				 const struct snd_pcm_subformat **subformatsp,
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index ff5f45b95be4..c1243315338e 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -849,67 +849,6 @@ unsigned int snd_hdac_spdif_stream_format(unsigned int channels, unsigned int bp
 }
 EXPORT_SYMBOL_GPL(snd_hdac_spdif_stream_format);
 
-/**
- * snd_hdac_calc_stream_format - calculate the format bitset
- * @rate: the sample rate
- * @channels: the number of channels
- * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
- * @maxbps: the max. bps
- * @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant)
- *
- * Calculate the format bitset from the given rate, channels and th PCM format.
- *
- * Return zero if invalid.
- */
-unsigned int snd_hdac_calc_stream_format(unsigned int rate,
-					 unsigned int channels,
-					 snd_pcm_format_t format,
-					 unsigned int maxbps,
-					 unsigned short spdif_ctls)
-{
-	int i;
-	unsigned int val = 0;
-
-	for (i = 0; rate_bits[i].hz; i++)
-		if (rate_bits[i].hz == rate) {
-			val = rate_bits[i].hda_fmt;
-			break;
-		}
-	if (!rate_bits[i].hz)
-		return 0;
-
-	if (channels == 0 || channels > 8)
-		return 0;
-	val |= channels - 1;
-
-	switch (snd_pcm_format_width(format)) {
-	case 8:
-		val |= AC_FMT_BITS_8;
-		break;
-	case 16:
-		val |= AC_FMT_BITS_16;
-		break;
-	case 20:
-	case 24:
-	case 32:
-		if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
-			val |= AC_FMT_BITS_32;
-		else if (maxbps >= 24)
-			val |= AC_FMT_BITS_24;
-		else
-			val |= AC_FMT_BITS_20;
-		break;
-	default:
-		return 0;
-	}
-
-	if (spdif_ctls & AC_DIG1_NONAUDIO)
-		val |= AC_FMT_TYPE_NON_PCM;
-
-	return val;
-}
-EXPORT_SYMBOL_GPL(snd_hdac_calc_stream_format);
-
 static unsigned int query_pcm_param(struct hdac_device *codec, hda_nid_t nid)
 {
 	unsigned int val = 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 16/17] ASoC: Intel: avs: Kill S24_LE in HDAudio streaming
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (14 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 15/17] ALSA: hda: Drop snd_hdac_calc_stream_format() Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  2023-09-18 13:39 ` [PATCH v2 17/17] ASoC: Intel: avs: Unhardcode HDAudio BE DAI drivers description Cezary Rojewski
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

Eliminate all occurrences of S24_LE within the HDAudio related pcm code,
both HOST and LINK side. Replace those with MSBITS subformats to allow
for granular selection when S32_LE is the format of choice.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/pcm.c      | 16 +++++++++++++---
 sound/soc/intel/avs/topology.c | 19 ++++++++++++++++++-
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 2a8aa4e6ce67..08855d4e0a37 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -1069,6 +1069,16 @@ static int avs_component_resume(struct snd_soc_component *component)
 	return avs_component_resume_prepare(component, false);
 }
 
+static struct snd_pcm_subformat avs_pcm_subformats[] = {
+	{
+		.format = SNDRV_PCM_FORMAT_S32_LE,
+		.mask = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
+			SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
+			SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
+	},
+	{}
+};
+
 static const struct snd_pcm_hardware avs_pcm_hardware = {
 	.info			= SNDRV_PCM_INFO_MMAP |
 				  SNDRV_PCM_INFO_MMAP_VALID |
@@ -1077,8 +1087,8 @@ static const struct snd_pcm_hardware avs_pcm_hardware = {
 				  SNDRV_PCM_INFO_RESUME |
 				  SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
 	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
-				  SNDRV_PCM_FMTBIT_S24_LE |
 				  SNDRV_PCM_FMTBIT_S32_LE,
+	.subformats		= avs_pcm_subformats,
 	.buffer_bytes_max	= AZX_MAX_BUF_SIZE,
 	.period_bytes_min	= 128,
 	.period_bytes_max	= AZX_MAX_BUF_SIZE / 2,
@@ -1308,16 +1318,16 @@ static const struct snd_soc_dai_driver hda_cpu_dai = {
 		.channels_max	= 8,
 		.rates		= SNDRV_PCM_RATE_8000_192000,
 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
-				  SNDRV_PCM_FMTBIT_S24_LE |
 				  SNDRV_PCM_FMTBIT_S32_LE,
+		.subformats	= avs_pcm_subformats,
 	},
 	.capture = {
 		.channels_min	= 1,
 		.channels_max	= 8,
 		.rates		= SNDRV_PCM_RATE_8000_192000,
 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
-				  SNDRV_PCM_FMTBIT_S24_LE |
 				  SNDRV_PCM_FMTBIT_S32_LE,
+		.subformats	= avs_pcm_subformats,
 	},
 };
 
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index 45d0eb2a8e71..f2545dcbf86e 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -1456,8 +1456,22 @@ static int avs_dai_load(struct snd_soc_component *comp, int index,
 			struct snd_soc_dai_driver *dai_drv, struct snd_soc_tplg_pcm *pcm,
 			struct snd_soc_dai *dai)
 {
-	if (pcm)
+	static struct snd_pcm_subformat fe_subformats[] = {
+		{
+			.format = SNDRV_PCM_FORMAT_S32_LE,
+			.mask = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
+				SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
+				SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
+		},
+		{}
+	};
+
+	if (pcm) {
 		dai_drv->ops = &avs_dai_fe_ops;
+		dai_drv->capture.subformats = fe_subformats;
+		dai_drv->playback.subformats = fe_subformats;
+	}
+
 	return 0;
 }
 
@@ -1476,6 +1490,9 @@ static int avs_link_load(struct snd_soc_component *comp, int index, struct snd_s
 		/* Open LINK (BE) pipes last and close them first to prevent xruns. */
 		link->trigger[0] = SND_SOC_DPCM_TRIGGER_PRE;
 		link->trigger[1] = SND_SOC_DPCM_TRIGGER_PRE;
+	} else {
+		/* Do not ignore codec capabilities. */
+		link->dpcm_merged_format = 1;
 	}
 
 	return 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 17/17] ASoC: Intel: avs: Unhardcode HDAudio BE DAI drivers description
  2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
                   ` (15 preceding siblings ...)
  2023-09-18 13:39 ` [PATCH v2 16/17] ASoC: Intel: avs: Kill S24_LE in HDAudio streaming Cezary Rojewski
@ 2023-09-18 13:39 ` Cezary Rojewski
  16 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-18 13:39 UTC (permalink / raw)
  To: broonie, tiwai, perex
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	Cezary Rojewski

To not expose more than in fact is supported by the codec, update CPU
DAI initialization procedure to rely on codec capabilities instead of
hardcoding them. This includes subformat which is currently ignored.

As capabilities for HDMI streams are initialized on PCM open, leave it
as is for now.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/intel/avs/pcm.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 08855d4e0a37..cca1a5b7764a 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -17,6 +17,7 @@
 #include "avs.h"
 #include "path.h"
 #include "topology.h"
+#include "../../codecs/hda.h"
 
 struct avs_dma_data {
 	struct avs_tplg_path_template *template;
@@ -1404,6 +1405,15 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
 				ret = -ENOMEM;
 				goto exit;
 			}
+
+			if (!hda_codec_is_display(codec)) {
+				dais[i].playback.formats = pcm->stream[0].formats;
+				dais[i].playback.subformats = pcm->stream[0].subformats;
+				dais[i].playback.rates = pcm->stream[0].rates;
+				dais[i].playback.channels_min = pcm->stream[0].channels_min;
+				dais[i].playback.channels_max = pcm->stream[0].channels_max;
+				dais[i].playback.sig_bits = pcm->stream[0].maxbps;
+			}
 		}
 
 		if (pcm->stream[1].substreams) {
@@ -1414,6 +1424,15 @@ static int avs_component_hda_probe(struct snd_soc_component *component)
 				ret = -ENOMEM;
 				goto exit;
 			}
+
+			if (!hda_codec_is_display(codec)) {
+				dais[i].capture.formats = pcm->stream[1].formats;
+				dais[i].capture.subformats = pcm->stream[1].subformats;
+				dais[i].capture.rates = pcm->stream[1].rates;
+				dais[i].capture.channels_min = pcm->stream[1].channels_min;
+				dais[i].capture.channels_max = pcm->stream[1].channels_max;
+				dais[i].capture.sig_bits = pcm->stream[1].maxbps;
+			}
 		}
 
 		dai = snd_soc_register_dai(component, &dais[i], false);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 15/17] ALSA: hda: Drop snd_hdac_calc_stream_format()
  2023-09-18 13:39 ` [PATCH v2 15/17] ALSA: hda: Drop snd_hdac_calc_stream_format() Cezary Rojewski
@ 2023-09-18 15:11   ` kernel test robot
  0 siblings, 0 replies; 26+ messages in thread
From: kernel test robot @ 2023-09-18 15:11 UTC (permalink / raw)
  To: Cezary Rojewski, broonie, tiwai, perex
  Cc: oe-kbuild-all, alsa-devel, amadeuszx.slawinski,
	pierre-louis.bossart, hdegoede, Cezary Rojewski

Hi Cezary,

kernel test robot noticed the following build errors:

[auto build test ERROR on 564ee9ac788b680e4ec4a6cb3a4a953dc61d5da8]

url:    https://github.com/intel-lab-lkp/linux/commits/Cezary-Rojewski/ALSA-pcm-Introduce-MSBITS-subformat-interface/20230918-214758
base:   564ee9ac788b680e4ec4a6cb3a4a953dc61d5da8
patch link:    https://lore.kernel.org/r/20230918133940.3676091-16-cezary.rojewski%40intel.com
patch subject: [PATCH v2 15/17] ALSA: hda: Drop snd_hdac_calc_stream_format()
config: arc-allmodconfig (https://download.01.org/0day-ci/archive/20230918/202309182301.K9lVpMbl-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230918/202309182301.K9lVpMbl-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309182301.K9lVpMbl-lkp@intel.com/

All errors (new ones prefixed by >>):

   sound/soc/sof/intel/hda-dai-ops.c: In function 'generic_calc_stream_format':
>> sound/soc/sof/intel/hda-dai-ops.c:243:22: error: implicit declaration of function 'snd_hdac_calc_stream_format'; did you mean 'hda_calc_stream_format'? [-Werror=implicit-function-declaration]
     243 |         format_val = snd_hdac_calc_stream_format(params_rate(params), params_channels(params),
         |                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                      hda_calc_stream_format
   cc1: some warnings being treated as errors


vim +243 sound/soc/sof/intel/hda-dai-ops.c

d1bf58474d17a7 Pierre-Louis Bossart 2023-06-02  236  
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  237  static unsigned int generic_calc_stream_format(struct snd_sof_dev *sdev,
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  238  					       struct snd_pcm_substream *substream,
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  239  					       struct snd_pcm_hw_params *params)
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  240  {
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  241  	unsigned int format_val;
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  242  
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07 @243  	format_val = snd_hdac_calc_stream_format(params_rate(params), params_channels(params),
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  244  						 params_format(params),
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  245  						 params_physical_width(params),
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  246  						 0);
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  247  
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  248  	dev_dbg(sdev->dev, "format_val=%#x, rate=%d, ch=%d, format=%d\n", format_val,
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  249  		params_rate(params), params_channels(params), params_format(params));
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  250  
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  251  	return format_val;
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  252  }
12547730e5b7c4 Pierre-Louis Bossart 2023-08-07  253  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 04/17] ASoC: pcm: Honor subformat when configuring runtime
  2023-09-18 13:39 ` [PATCH v2 04/17] ASoC: pcm: Honor subformat when configuring runtime Cezary Rojewski
@ 2023-09-19 12:50   ` Mark Brown
  2023-09-21  6:57   ` Jaroslav Kysela
  1 sibling, 0 replies; 26+ messages in thread
From: Mark Brown @ 2023-09-19 12:50 UTC (permalink / raw)
  To: Cezary Rojewski
  Cc: tiwai, perex, alsa-devel, amadeuszx.slawinski,
	pierre-louis.bossart, hdegoede

[-- Attachment #1: Type: text/plain, Size: 276 bytes --]

On Mon, Sep 18, 2023 at 03:39:27PM +0200, Cezary Rojewski wrote:
> Subformat options are ignored when setting up hardware parameters and
> assigning PCM stream capabilities. Account for them to allow for
> granular format selection.

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 01/17] ALSA: pcm: Introduce MSBITS subformat interface
  2023-09-18 13:39 ` [PATCH v2 01/17] ALSA: pcm: Introduce MSBITS subformat interface Cezary Rojewski
@ 2023-09-21  6:25   ` Jaroslav Kysela
  2023-11-14 20:09     ` Cezary Rojewski
  0 siblings, 1 reply; 26+ messages in thread
From: Jaroslav Kysela @ 2023-09-21  6:25 UTC (permalink / raw)
  To: Cezary Rojewski, broonie, tiwai
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede

On 18. 09. 23 15:39, Cezary Rojewski wrote:
> Improve granularity of format selection for S32/U32 formats by adding
> constants representing 20, 24 and MAX most significant bits.
> 
> To make it easy for drivers to utilize those constants, introduce
> snd_pcm_subformat_width() and snd_pcm_hw_params_bps(). While the former
> is self-explanatory, the latter returns the bit-per-sample value based
> on format and subformat characteristics of the provided hw_params.
> snd_pcm_hw_copy() helps with copying a hardware parameters space as with
> introduction of subformats the operations becomes non-trivial.
> 
> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>

...

>   struct snd_pcm_hardware {
>   	unsigned int info;		/* SNDRV_PCM_INFO_* */
>   	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
> +	struct snd_pcm_subformat *subformats;

I don't think that it's required to add subformats to the hardware template. 
The new constraint can handle subformat refining without the template 
modifications (pointer to map table is stored privately to this constraint).

Also, I miss the constraint handling here. Without the constraint, the new API 
is not functional and it does not make sense to split the constraint code to 
other patch.

> +int snd_pcm_hw_params_bps(const struct snd_pcm_hw_params *p);

This may be probably inline function. See bellow.

> +	kfree(runtime->hw.subformats);

Do we really need to do an assumption about allocations for this field? The 
driver may use a static structure. No problem, when this is not added to 
runtime->hw.

> +int snd_pcm_hw_params_bps(const struct snd_pcm_hw_params *p)
> +{
> +	snd_pcm_subformat_t subformat = params_subformat(p);
> +	snd_pcm_format_t format = params_format(p);
> +	int width;
> +
> +	switch (format) {
> +	case SNDRV_PCM_FORMAT_S32_LE:
> +	case SNDRV_PCM_FORMAT_U32_LE:
> +	case SNDRV_PCM_FORMAT_S32_BE:
> +	case SNDRV_PCM_FORMAT_U32_BE:
> +		width = snd_pcm_subformat_width(subformat);

This is not a correct implementation. The width should be returned for MAX 
subformat (== snd_pcm_format_width value). See bellow.

> +int snd_pcm_subformat_width(snd_pcm_subformat_t subformat)

This function should probably have two arguments - format + subformat to 
return the correct information. The MAX subformat should return 
snd_pcm_format_width value.

> +int snd_pcm_hw_copy(struct snd_pcm_hardware *hw, const struct snd_pcm_hardware *from)

This function is not required, if only the constraint function handles the 
subformat refining.

						Jaroslav

-- 
Jaroslav Kysela <perex@perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream
  2023-09-18 13:39 ` [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream Cezary Rojewski
@ 2023-09-21  6:41   ` Jaroslav Kysela
  2023-09-21  8:59     ` Cezary Rojewski
  2023-09-23 10:55   ` kernel test robot
  1 sibling, 1 reply; 26+ messages in thread
From: Jaroslav Kysela @ 2023-09-21  6:41 UTC (permalink / raw)
  To: Cezary Rojewski, broonie, tiwai
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede

On 18. 09. 23 15:39, Cezary Rojewski wrote:
> Substream value is currently hardcoded to SNDRV_PCM_SUBFORMAT_STD.
> Update the constraint procedure so that subformat selection is not
> ignored. Case STD is always supported as most PCMs do not care about
> subformat.
> 
> Suggested-by: Jaroslav Kysela <perex@perex.cz>

Better Co-developed mark. Also I would move whole code to the first patch. It 
does not make sense to split the mandatory code.

Another option is to increase the protocol version to the separate patch where 
all necessary code changes are applied (for MSBITS_MAX). But it may break 
backports, so the change should be aligned with the SUBFMT defines.

> +	struct snd_mask *sfmask;

m_rw -> sfmask renaming. I prefer universal name to allow easy reuse in future.

> +		for (sf = hw->subformats; sf->mask && !found; sf++) {

My proposal [1] defined SNDRV_PCM_FORMAT_CONSTRAINT_END value not relying to 
zero format (which is U8) and zero subformat to skip the MSBIT_MAX setting 
bellow. After some thought, if the driver sets SNDRV_PCM_SUBFORMAT_MSBITS_STD, 
the result will be similar, thus the mask can be zero and the code may be 
reduced. So no objection for this change.

> +		if (!found && snd_pcm_format_linear(f))
> +			snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
> +	}
> +exit:
> +	return snd_mask_refine(sfmask, &m);
> +}
> +
> +static int snd_pcm_hw_constraint_subformats(struct snd_pcm_runtime *runtime,
> +					   unsigned int cond,
> +					   struct snd_pcm_hardware *hw)
> +{

Because your change does not assume that this constraint is called from the 
drivers, the comments and EXPORT_SYMBOL() lines were removed from the original 
proposal [1]. I believe that the standalone constraint is better at this time 
- reduce code, the use of the subformat extension is not mandatory.

							Jaroslav

[1] https://lore.kernel.org/alsa-devel/20230912162526.7138-1-perex@perex.cz/
     https://lore.kernel.org/alsa-devel/20230913103716.67315-1-perex@perex.cz/

-- 
Jaroslav Kysela <perex@perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 04/17] ASoC: pcm: Honor subformat when configuring runtime
  2023-09-18 13:39 ` [PATCH v2 04/17] ASoC: pcm: Honor subformat when configuring runtime Cezary Rojewski
  2023-09-19 12:50   ` Mark Brown
@ 2023-09-21  6:57   ` Jaroslav Kysela
  1 sibling, 0 replies; 26+ messages in thread
From: Jaroslav Kysela @ 2023-09-21  6:57 UTC (permalink / raw)
  To: Cezary Rojewski, broonie, tiwai
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede

On 18. 09. 23 15:39, Cezary Rojewski wrote:
> Subformat options are ignored when setting up hardware parameters and
> assigning PCM stream capabilities. Account for them to allow for
> granular format selection.
> 
> With introduction of subformats, copying hardware parameters becomes
> a non-trivial operation. Implement a helper function to make things
> simple.
> 
> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>

>   struct snd_soc_pcm_stream {
>   	const char *stream_name;
>   	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
> +	const struct snd_pcm_subformat *subformats;

I don't think that this extension is mandatory. The whole patch can be skipped 
if the driver installs the subformat runtime constraint.

					Jaroslav

-- 
Jaroslav Kysela <perex@perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream
  2023-09-21  6:41   ` Jaroslav Kysela
@ 2023-09-21  8:59     ` Cezary Rojewski
  0 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-09-21  8:59 UTC (permalink / raw)
  To: Jaroslav Kysela, broonie, tiwai
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede

On 2023-09-21 8:41 AM, Jaroslav Kysela wrote:
> On 18. 09. 23 15:39, Cezary Rojewski wrote:
>> Substream value is currently hardcoded to SNDRV_PCM_SUBFORMAT_STD.
>> Update the constraint procedure so that subformat selection is not
>> ignored. Case STD is always supported as most PCMs do not care about
>> subformat.
>>
>> Suggested-by: Jaroslav Kysela <perex@perex.cz>
> 
> Better Co-developed mark. Also I would move whole code to the first 
> patch. It does not make sense to split the mandatory code.
> 
> Another option is to increase the protocol version to the separate patch 
> where all necessary code changes are applied (for MSBITS_MAX). But it 
> may break backports, so the change should be aligned with the SUBFMT 
> defines.

While most of my feedback is below, if we decide that "subformat as 
first class citizen" approach is good-to-go, this patch gets 
re-authorized in v3 as the input on the constraint part from your end is 
major.

>> +    struct snd_mask *sfmask;
> 
> m_rw -> sfmask renaming. I prefer universal name to allow easy reuse in 
> future.

Ack.

>> +        for (sf = hw->subformats; sf->mask && !found; sf++) {
> 
> My proposal [1] defined SNDRV_PCM_FORMAT_CONSTRAINT_END value not 
> relying to zero format (which is U8) and zero subformat to skip the 
> MSBIT_MAX setting bellow. After some thought, if the driver sets 
> SNDRV_PCM_SUBFORMAT_MSBITS_STD, the result will be similar, thus the 
> mask can be zero and the code may be reduced. So no objection for this 
> change.
> 
>> +        if (!found && snd_pcm_format_linear(f))
>> +            snd_mask_set(&m, (__force 
>> unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
>> +    }
>> +exit:
>> +    return snd_mask_refine(sfmask, &m);
>> +}
>> +
>> +static int snd_pcm_hw_constraint_subformats(struct snd_pcm_runtime 
>> *runtime,
>> +                       unsigned int cond,
>> +                       struct snd_pcm_hardware *hw)
>> +{
> 
> Because your change does not assume that this constraint is called from 
> the drivers, the comments and EXPORT_SYMBOL() lines were removed from 
> the original proposal [1]. I believe that the standalone constraint is 
> better at this time - reduce code, the use of the subformat extension is 
> not mandatory.

Thank you for thorough feedback, Jaroslav. This is much appreciated. 
Before I comment on the rest of the comments, let me provide a summary:
I believe that most of the subject comes down to: subformat as 
mainstream API -or- subformat as niche API.

If the general opinion of the developers is: let's go for the latter 
until we have more users, I have no problem with merging the patches 1 & 
2 and addressing most of the review in 1:1 fashion as indeed many parts 
of the proposed API lose their purpose.

My view is different as I'd like subformat to become mainstream. To be 
honest, the object that allowed it to happen has been suggested by you 
Jaroslav - the struct made of { format; mask; }. It allows to describe 
what subformat _is_ in explicit fashion and by being exposed in 
snd_pcm_hardware becomes standard part of the API. As previously 
suggested, I believe it could replace ->msbits in future too.


Question to the fellow developers: What's your take on the subject?


Kind regards,
Czarek

> [1] 
> https://lore.kernel.org/alsa-devel/20230912162526.7138-1-perex@perex.cz/
>      
> https://lore.kernel.org/alsa-devel/20230913103716.67315-1-perex@perex.cz/
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream
  2023-09-18 13:39 ` [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream Cezary Rojewski
  2023-09-21  6:41   ` Jaroslav Kysela
@ 2023-09-23 10:55   ` kernel test robot
  1 sibling, 0 replies; 26+ messages in thread
From: kernel test robot @ 2023-09-23 10:55 UTC (permalink / raw)
  To: Cezary Rojewski, broonie, tiwai, perex
  Cc: oe-kbuild-all, alsa-devel, amadeuszx.slawinski,
	pierre-louis.bossart, hdegoede, Cezary Rojewski

Hi Cezary,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 564ee9ac788b680e4ec4a6cb3a4a953dc61d5da8]

url:    https://github.com/intel-lab-lkp/linux/commits/Cezary-Rojewski/ALSA-pcm-Introduce-MSBITS-subformat-interface/20230918-214758
base:   564ee9ac788b680e4ec4a6cb3a4a953dc61d5da8
patch link:    https://lore.kernel.org/r/20230918133940.3676091-3-cezary.rojewski%40intel.com
patch subject: [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream
config: x86_64-randconfig-121-20230923 (https://download.01.org/0day-ci/archive/20230923/202309231825.17qi62Yr-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230923/202309231825.17qi62Yr-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309231825.17qi62Yr-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> sound/core/pcm_native.c:2523:43: sparse: sparse: incorrect type in argument 2 (different base types) @@     expected unsigned int val @@     got restricted snd_pcm_format_t [assigned] [usertype] f @@
   sound/core/pcm_native.c:2523:43: sparse:     expected unsigned int val
   sound/core/pcm_native.c:2523:43: sparse:     got restricted snd_pcm_format_t [assigned] [usertype] f
   sound/core/pcm_native.c:95:1: sparse: sparse: context imbalance in 'snd_pcm_group_lock' - different lock contexts for basic block
   sound/core/pcm_native.c:96:1: sparse: sparse: context imbalance in 'snd_pcm_group_unlock' - unexpected unlock
   sound/core/pcm_native.c:97:1: sparse: sparse: context imbalance in 'snd_pcm_group_lock_irq' - different lock contexts for basic block
   sound/core/pcm_native.c:98:1: sparse: sparse: context imbalance in 'snd_pcm_group_unlock_irq' - unexpected unlock
   sound/core/pcm_native.c:145:9: sparse: sparse: context imbalance in 'snd_pcm_stream_lock_nested' - different lock contexts for basic block
   sound/core/pcm_native.c:171:9: sparse: sparse: context imbalance in '_snd_pcm_stream_lock_irqsave' - different lock contexts for basic block
   sound/core/pcm_native.c:184:9: sparse: sparse: context imbalance in '_snd_pcm_stream_lock_irqsave_nested' - different lock contexts for basic block
   sound/core/pcm_native.c:201:39: sparse: sparse: context imbalance in 'snd_pcm_stream_unlock_irqrestore' - unexpected unlock
   sound/core/pcm_native.c:1279:44: sparse: sparse: context imbalance in 'snd_pcm_action_group' - unexpected unlock
   sound/core/pcm_native.c:1349:37: sparse: sparse: context imbalance in 'snd_pcm_stream_group_ref' - different lock contexts for basic block
   sound/core/pcm_native.c: note: in included file (through arch/x86/include/asm/uaccess.h, include/linux/uaccess.h, include/linux/sched/task.h, ...):
   arch/x86/include/asm/uaccess_64.h:88:24: sparse: sparse: cast removes address space '__user' of expression

vim +2523 sound/core/pcm_native.c

  2503	
  2504	static int snd_pcm_hw_rule_subformats(struct snd_pcm_hw_params *params,
  2505					      struct snd_pcm_hw_rule *rule)
  2506	{
  2507		struct snd_mask *sfmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT);
  2508		struct snd_mask *fmask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
  2509		struct snd_pcm_hardware *hw = rule->private;
  2510		struct snd_pcm_subformat *sf;
  2511		snd_pcm_format_t f;
  2512		struct snd_mask m;
  2513		bool found;
  2514	
  2515		snd_mask_none(&m);
  2516		/* All PCMs support at least the default STD subformat. */
  2517		snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_STD);
  2518	
  2519		if (!hw->subformats)
  2520			goto exit;
  2521	
  2522		pcm_for_each_format(f) {
> 2523			if (!snd_mask_test(fmask, f))
  2524				continue;
  2525	
  2526			found = false;
  2527			for (sf = hw->subformats; sf->mask && !found; sf++) {
  2528				if (sf->format != f)
  2529					continue;
  2530				m.bits[0] |= sf->mask;
  2531				found = true;
  2532			}
  2533			if (!found && snd_pcm_format_linear(f))
  2534				snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
  2535		}
  2536	exit:
  2537		return snd_mask_refine(sfmask, &m);
  2538	}
  2539	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 01/17] ALSA: pcm: Introduce MSBITS subformat interface
  2023-09-21  6:25   ` Jaroslav Kysela
@ 2023-11-14 20:09     ` Cezary Rojewski
  0 siblings, 0 replies; 26+ messages in thread
From: Cezary Rojewski @ 2023-11-14 20:09 UTC (permalink / raw)
  To: Jaroslav Kysela, broonie, tiwai
  Cc: alsa-devel, amadeuszx.slawinski, pierre-louis.bossart, hdegoede,
	linux-sound

On 2023-09-21 8:25 AM, Jaroslav Kysela wrote:
> On 18. 09. 23 15:39, Cezary Rojewski wrote:
>> Improve granularity of format selection for S32/U32 formats by adding
>> constants representing 20, 24 and MAX most significant bits.
>>
>> To make it easy for drivers to utilize those constants, introduce
>> snd_pcm_subformat_width() and snd_pcm_hw_params_bps(). While the former
>> is self-explanatory, the latter returns the bit-per-sample value based
>> on format and subformat characteristics of the provided hw_params.
>> snd_pcm_hw_copy() helps with copying a hardware parameters space as with
>> introduction of subformats the operations becomes non-trivial.
>>
>> Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
> 
> ...
> 
>>   struct snd_pcm_hardware {
>>       unsigned int info;        /* SNDRV_PCM_INFO_* */
>>       u64 formats;            /* SNDRV_PCM_FMTBIT_* */
>> +    struct snd_pcm_subformat *subformats;
> 
> I don't think that it's required to add subformats to the hardware 
> template. The new constraint can handle subformat refining without the 
> template modifications (pointer to map table is stored privately to this 
> constraint).

After iterating over the feedback, modified the field to u32 and all the 
handlers to acknowledge that it is S32_LE-specific. I agree with 
statement that we can expand on the API in the future if there's demand 
for it.

> Also, I miss the constraint handling here. Without the constraint, the 
> new API is not functional and it does not make sense to split the 
> constraint code to other patch.

Ack, merging the two.

>> +int snd_pcm_hw_params_bps(const struct snd_pcm_hw_params *p);
> 
> This may be probably inline function. See bellow.
> 
>> +    kfree(runtime->hw.subformats);
> 
> Do we really need to do an assumption about allocations for this field? 
> The driver may use a static structure. No problem, when this is not 
> added to runtime->hw.

This code is gone in v3 since there is no need to kfree() a u32.

>> +int snd_pcm_hw_params_bps(const struct snd_pcm_hw_params *p)
>> +{
>> +    snd_pcm_subformat_t subformat = params_subformat(p);
>> +    snd_pcm_format_t format = params_format(p);
>> +    int width;
>> +
>> +    switch (format) {
>> +    case SNDRV_PCM_FORMAT_S32_LE:
>> +    case SNDRV_PCM_FORMAT_U32_LE:
>> +    case SNDRV_PCM_FORMAT_S32_BE:
>> +    case SNDRV_PCM_FORMAT_U32_BE:
>> +        width = snd_pcm_subformat_width(subformat);
> 
> This is not a correct implementation. The width should be returned for 
> MAX subformat (== snd_pcm_format_width value). See bellow.

snd_pcm_subformat_width() returns 0 if subformat==MAX and fallthrough 
ensures snd_pcm_format_width() is returned in such case.

>> +int snd_pcm_subformat_width(snd_pcm_subformat_t subformat)
> 
> This function should probably have two arguments - format + subformat to 
> return the correct information. The MAX subformat should return 
> snd_pcm_format_width value.

My intention is to have two granular functions. One for obtaining 
subformat-width explicitly and the other for calculating bits-per-sample.

>> +int snd_pcm_hw_copy(struct snd_pcm_hardware *hw, const struct 
>> snd_pcm_hardware *from)
> 
> This function is not required, if only the constraint function handles 
> the subformat refining.

Ack, removing in v3.

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2023-11-14 20:11 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-18 13:39 [PATCH v2 00/17] ALSA/ASoC: hda: Address format selection limitations and ambiguity Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 01/17] ALSA: pcm: Introduce MSBITS subformat interface Cezary Rojewski
2023-09-21  6:25   ` Jaroslav Kysela
2023-11-14 20:09     ` Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 02/17] ALSA: pcm: Honor subformat when configuring substream Cezary Rojewski
2023-09-21  6:41   ` Jaroslav Kysela
2023-09-21  8:59     ` Cezary Rojewski
2023-09-23 10:55   ` kernel test robot
2023-09-18 13:39 ` [PATCH v2 03/17] ALSA: hda: Honor subformat when querying PCMs Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 04/17] ASoC: pcm: Honor subformat when configuring runtime Cezary Rojewski
2023-09-19 12:50   ` Mark Brown
2023-09-21  6:57   ` Jaroslav Kysela
2023-09-18 13:39 ` [PATCH v2 05/17] ALSA: hda: Upgrade stream-format infrastructure Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 06/17] ALSA: hda: Switch to new stream-format interface Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 07/17] ALSA: hda/hdmi: " Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 08/17] ALSA: hda/ca0132: " Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 09/17] ASoC: codecs: hda: " Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 10/17] ASoC: codecs: hdac_hda: " Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 11/17] ASoC: codecs: hdac_hdmi: " Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 12/17] ASoC: Intel Skylake: " Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 13/17] ASoC: SOF: Intel: " Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 14/17] ASoC: Intel: avs: " Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 15/17] ALSA: hda: Drop snd_hdac_calc_stream_format() Cezary Rojewski
2023-09-18 15:11   ` kernel test robot
2023-09-18 13:39 ` [PATCH v2 16/17] ASoC: Intel: avs: Kill S24_LE in HDAudio streaming Cezary Rojewski
2023-09-18 13:39 ` [PATCH v2 17/17] ASoC: Intel: avs: Unhardcode HDAudio BE DAI drivers description Cezary Rojewski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).