All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] Generic HDMI codec: Add channel mapping control
@ 2016-12-19 11:08 Arnaud Pouliquen
  2016-12-19 11:08 ` [PATCH v3 1/4] DRM: add help to get ELD speaker allocation Arnaud Pouliquen
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Arnaud Pouliquen @ 2016-12-19 11:08 UTC (permalink / raw)
  To: alsa-devel, dri-devel
  Cc: Takashi Iwai, lgirdwood, Jyri Sarha, Takashi Sakamoto,
	David Airlie, broonie, Daniel Vetter

Aim of this patch is to add  'Playback Channel Map' control to export 
audio capabilities in term of HDMI sink speakers allocation.

V3:
 - "ASoC: hdmi-codec: add channel mapping control":
     => Minor fixes:
         - select stereo speaker config by default if HDMI cable unplugged
         - fix compilation warning. 
 - "DRM: add help to get ELD speaker allocation"
     => No delta vs V2.
 - "ALSA pcm: allow non constant snd_pcm_chmap_elem"
     => No delta vs V2.
 - "ASoC: core: add optional pcm_new callback for DAI driver"
     => No delta vs V2.

V2:
In this version I use chmap helper functions from pcm_lib.c. 
It is quite tricky to use it from ASoC due to the relation chip of the controls
with the pcm runtime.
After several tries, my conclusion is that it must be handled in ASoC DAI driver.
Main reason is that the DAI driver can not provide snd_pcm_chmap struct
through kcontrol structure. But this induces that soc-core provides pcm runtime
structure to DAI driver during probe.

Base on this conclusion. I reworked my patches by adding 2 
new patches in patch-set
1)  ALSA pcm: allow non constant snd_pcm_chmap_elem
   This patch allows to handle non constant channel mapping. As ELD
   information can change during runtime it is mandatory to properly 
   handle the feature.
   In term of compatibility with legacy it should be straightforward,
   as update just consists in suppressing the 'const' constraint.

2)  ASoC: core: add optional pcm_new callback for DAI driver
    This is the only way i found to be able to use 
    snd_pcm_add_chmap_ctls and associated controls helper functions.
    From my point of view, this is the more simple way to add relationship
    between DAI and associated pcm devices.
   Notice that this patch, if accepted, makes the following one obsolete,
   as it also answer to the associated topic:
  [PATCH v5 0/2] ALSA controls management using index/device/sub-devices fields
  (http://www.spinics.net/lists/alsa-devel/msg57639.html).

If you estimate that this it not reasonable i will come back to my first version.

V1:
This patch follows discussion initiate here: 
[RFC] ASOC: HDMI audio info frame speaker allocation
http://www.spinics.net/lists/alsa-devel/msg57363.html

The code is fully inspired from HDA driver.
On hw_param, HDMI sink speaker capabilities are exported via TLV ops
and  a CEA allocation is choson, based on ELD information and the number of
channels requested by user.

Mains differences with HDA implementation are:
 - Control is read only
 - Channel swap is not supported. Consequence is that unused channel in
   the mid of CEA audio infoframe channel mapping are considered as
   active.
   example for channel allocation 0x02: FL, FR, 0, FC)
	This configuration is only available for a 4 channels stream.
  - Channel allocation table has been reordered and HDMI 2.0 is not
    supported.

Arnaud Pouliquen (4):
  DRM: add help to get ELD speaker allocation
  ALSA pcm: allow non constant snd_pcm_chmap_elem
  ASoC: core: add optional pcm_new callback for DAI driver
  ASoC: hdmi-codec: add channel mapping control

 include/drm/drm_edid.h        |  13 ++
 include/sound/pcm.h           |   4 +-
 include/sound/soc-dai.h       |   3 +
 sound/core/pcm_lib.c          |   6 +-
 sound/soc/codecs/hdmi-codec.c | 313 +++++++++++++++++++++++++++++++++++++++++-
 sound/soc/soc-core.c          |  28 ++++
 6 files changed, 361 insertions(+), 6 deletions(-)

-- 
1.9.1

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

* [PATCH v3 1/4] DRM: add help to get ELD speaker allocation
  2016-12-19 11:08 [PATCH v3 0/4] Generic HDMI codec: Add channel mapping control Arnaud Pouliquen
@ 2016-12-19 11:08 ` Arnaud Pouliquen
  2016-12-20 14:07   ` Jani Nikula
  2016-12-19 11:08 ` [PATCH v3 2/4] ALSA pcm: allow non constant snd_pcm_chmap_elem Arnaud Pouliquen
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Arnaud Pouliquen @ 2016-12-19 11:08 UTC (permalink / raw)
  To: alsa-devel, dri-devel
  Cc: Takashi Iwai, lgirdwood, Jyri Sarha, Takashi Sakamoto,
	David Airlie, broonie, Daniel Vetter

Add helper to allow users to retrieve the speaker allocations without
knowledge of the ELD structure.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
---
 include/drm/drm_edid.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index c3a7d44..de93543 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -248,6 +248,7 @@ struct detailed_timing {
 # define DRM_ELD_AUD_SYNCH_DELAY_MAX	0xfa	/* 500 ms */
 
 #define DRM_ELD_SPEAKER			7
+# define DRM_ELD_SPEAKER_MASK		0x7f
 # define DRM_ELD_SPEAKER_RLRC		(1 << 6)
 # define DRM_ELD_SPEAKER_FLRC		(1 << 5)
 # define DRM_ELD_SPEAKER_RC		(1 << 4)
@@ -415,6 +416,18 @@ static inline int drm_eld_size(const uint8_t *eld)
 }
 
 /**
+ * drm_eld_get_spk_alloc - Get speaker allocation
+ * @eld: pointer to an ELD memory structure
+ *
+ * The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER
+ * field definitions to identify speakers.
+ */
+static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
+{
+	return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;
+}
+
+/**
  * drm_eld_get_conn_type - Get device type hdmi/dp connected
  * @eld: pointer to an ELD memory structure
  *
-- 
1.9.1

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

* [PATCH v3 2/4] ALSA pcm: allow non constant snd_pcm_chmap_elem
  2016-12-19 11:08 [PATCH v3 0/4] Generic HDMI codec: Add channel mapping control Arnaud Pouliquen
  2016-12-19 11:08 ` [PATCH v3 1/4] DRM: add help to get ELD speaker allocation Arnaud Pouliquen
@ 2016-12-19 11:08 ` Arnaud Pouliquen
  2016-12-19 16:31   ` [alsa-devel] " kbuild test robot
  2016-12-19 11:08 ` [PATCH v3 3/4] ASoC: core: add optional pcm_new callback for DAI driver Arnaud Pouliquen
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Arnaud Pouliquen @ 2016-12-19 11:08 UTC (permalink / raw)
  To: alsa-devel, dri-devel
  Cc: Takashi Iwai, lgirdwood, Jyri Sarha, Takashi Sakamoto,
	David Airlie, broonie, Daniel Vetter

For HDMI, channel mapping can be retrieved from ELD. In this case mapping
can change during runtime (plug/unplug).
This patch removes the 'const' property of the struct chmap.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
---
 include/sound/pcm.h  | 4 ++--
 sound/core/pcm_lib.c | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index af1fb37..3b459a3 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -1355,7 +1355,7 @@ struct snd_pcm_chmap {
 	struct snd_pcm *pcm;	/* assigned PCM instance */
 	int stream;		/* PLAYBACK or CAPTURE */
 	struct snd_kcontrol *kctl;
-	const struct snd_pcm_chmap_elem *chmap;
+	struct snd_pcm_chmap_elem *chmap;
 	unsigned int max_channels;
 	unsigned int channel_mask;	/* optional: active channels bitmask */
 	void *private_data;	/* optional: private data pointer */
@@ -1387,7 +1387,7 @@ struct snd_pcm_chmap {
 #define SND_PCM_CHMAP_MASK_2468	(SND_PCM_CHMAP_MASK_246 | (1U << 8))
 
 int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
-			   const struct snd_pcm_chmap_elem *chmap,
+			   struct snd_pcm_chmap_elem *chmap,
 			   int max_channels,
 			   unsigned long private_value,
 			   struct snd_pcm_chmap **info_ret);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index bb12615..252a498 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -2489,7 +2489,7 @@ static int pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
 	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	struct snd_pcm_substream *substream;
-	const struct snd_pcm_chmap_elem *map;
+	struct snd_pcm_chmap_elem *map;
 
 	if (snd_BUG_ON(!info->chmap))
 		return -EINVAL;
@@ -2519,7 +2519,7 @@ static int pcm_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
 			     unsigned int size, unsigned int __user *tlv)
 {
 	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
-	const struct snd_pcm_chmap_elem *map;
+	struct snd_pcm_chmap_elem *map;
 	unsigned int __user *dst;
 	int c, count = 0;
 
@@ -2578,7 +2578,7 @@ static void pcm_chmap_ctl_private_free(struct snd_kcontrol *kcontrol)
  * Return: Zero if successful, or a negative error value.
  */
 int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
-			   const struct snd_pcm_chmap_elem *chmap,
+			   struct snd_pcm_chmap_elem *chmap,
 			   int max_channels,
 			   unsigned long private_value,
 			   struct snd_pcm_chmap **info_ret)
-- 
1.9.1

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

* [PATCH v3 3/4] ASoC: core: add optional pcm_new callback for DAI driver
  2016-12-19 11:08 [PATCH v3 0/4] Generic HDMI codec: Add channel mapping control Arnaud Pouliquen
  2016-12-19 11:08 ` [PATCH v3 1/4] DRM: add help to get ELD speaker allocation Arnaud Pouliquen
  2016-12-19 11:08 ` [PATCH v3 2/4] ALSA pcm: allow non constant snd_pcm_chmap_elem Arnaud Pouliquen
@ 2016-12-19 11:08 ` Arnaud Pouliquen
  2016-12-19 11:08 ` [PATCH v3 4/4] ASoC: hdmi-codec: add channel mapping control Arnaud Pouliquen
  2016-12-19 19:49 ` [PATCH v3 0/4] Generic HDMI codec: Add " Takashi Sakamoto
  4 siblings, 0 replies; 9+ messages in thread
From: Arnaud Pouliquen @ 2016-12-19 11:08 UTC (permalink / raw)
  To: alsa-devel, dri-devel
  Cc: Takashi Iwai, lgirdwood, Jyri Sarha, Takashi Sakamoto,
	David Airlie, broonie, Daniel Vetter

During probe, DAIs can need to perform some actions that request
the knowledge of the pcm runtime handle.
The callback is called during DAIs linking, after PCM device creation.
For instance this can be used to add relationship between a DAI pcm
control and the pcm device.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
---
 include/sound/soc-dai.h |  3 +++
 sound/soc/soc-core.c    | 28 ++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 964b7de..1c8b579 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -231,6 +231,9 @@ struct snd_soc_dai_driver {
 	int (*resume)(struct snd_soc_dai *dai);
 	/* compress dai */
 	int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
+	/* Optional Callback used at pcm creation*/
+	int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
+		       struct snd_soc_dai *dai);
 	/* DAI is also used for the control bus */
 	bool bus_control;
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c0bbcd9..b8c5813 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1552,6 +1552,27 @@ static int soc_probe_dai(struct snd_soc_dai *dai, int order)
 	return 0;
 }
 
+static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais,
+				struct snd_soc_pcm_runtime *rtd)
+{
+	int i, ret = 0;
+
+	for (i = 0; i < num_dais; ++i) {
+		struct snd_soc_dai_driver *drv = dais[i]->driver;
+
+		if (!rtd->dai_link->no_pcm && drv->pcm_new)
+			ret = drv->pcm_new(rtd, dais[i]);
+		if (ret < 0) {
+			dev_err(dais[i]->dev,
+				"ASoC: Failed to bind %s with pcm device\n",
+				dais[i]->name);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int soc_link_dai_widgets(struct snd_soc_card *card,
 				struct snd_soc_dai_link *dai_link,
 				struct snd_soc_pcm_runtime *rtd)
@@ -1663,6 +1684,13 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
 				       dai_link->stream_name, ret);
 				return ret;
 			}
+			ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
+			if (ret < 0)
+				return ret;
+			ret = soc_link_dai_pcm_new(rtd->codec_dais,
+						   rtd->num_codecs, rtd);
+			if (ret < 0)
+				return ret;
 		} else {
 			INIT_DELAYED_WORK(&rtd->delayed_work,
 						codec2codec_close_delayed_work);
-- 
1.9.1

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

* [PATCH v3 4/4] ASoC: hdmi-codec: add channel mapping control
  2016-12-19 11:08 [PATCH v3 0/4] Generic HDMI codec: Add channel mapping control Arnaud Pouliquen
                   ` (2 preceding siblings ...)
  2016-12-19 11:08 ` [PATCH v3 3/4] ASoC: core: add optional pcm_new callback for DAI driver Arnaud Pouliquen
@ 2016-12-19 11:08 ` Arnaud Pouliquen
  2016-12-19 19:49 ` [PATCH v3 0/4] Generic HDMI codec: Add " Takashi Sakamoto
  4 siblings, 0 replies; 9+ messages in thread
From: Arnaud Pouliquen @ 2016-12-19 11:08 UTC (permalink / raw)
  To: alsa-devel, dri-devel
  Cc: Takashi Iwai, lgirdwood, Jyri Sarha, Takashi Sakamoto,
	David Airlie, broonie, Daniel Vetter

Add user interface to provide channel mapping.
In a first step this control is read only.

As TLV type, the control provides all configuration available for
HDMI sink(ELD), and provides current channel mapping selected by codec
based on ELD and number of channels specified by user on open.
When control is called before the number of the channel is specified
(i.e. hw_params is set), it returns all channels set to UNKNOWN.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
---
 sound/soc/codecs/hdmi-codec.c | 313 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 312 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index 90b5948..e2ccc2b 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -18,6 +18,7 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/tlv.h>
 #include <sound/pcm_drm_eld.h>
 #include <sound/hdmi-codec.h>
 #include <sound/pcm_iec958.h>
@@ -33,6 +34,124 @@ struct hdmi_device {
 LIST_HEAD(hdmi_device_list);
 
 #define DAI_NAME_SIZE 16
+#define HDMI_MAX_SPEAKERS  8
+
+struct hdmi_codec_channel_map_table {
+	unsigned char map;	/* ALSA API channel map position */
+	unsigned long spk_mask;		/* speaker position bit mask */
+};
+
+/*
+ * CEA speaker placement for HDMI 1.4:
+ *
+ *  FL  FLC   FC   FRC   FR   FRW
+ *
+ *                                  LFE
+ *
+ *  RL  RLC   RC   RRC   RR
+ *
+ *  Speaker placement has to be extended to support HDMI 2.0
+ */
+enum hdmi_codec_cea_spk_placement {
+	FL  = BIT(0),	/* Front Left           */
+	FC  = BIT(1),	/* Front Center         */
+	FR  = BIT(2),	/* Front Right          */
+	FLC = BIT(3),	/* Front Left Center    */
+	FRC = BIT(4),	/* Front Right Center   */
+	RL  = BIT(5),	/* Rear Left            */
+	RC  = BIT(6),	/* Rear Center          */
+	RR  = BIT(7),	/* Rear Right           */
+	RLC = BIT(8),	/* Rear Left Center     */
+	RRC = BIT(9),	/* Rear Right Center    */
+	LFE = BIT(10),	/* Low Frequency Effect */
+};
+
+static const struct hdmi_codec_channel_map_table hdmi_codec_map_table[] = {
+	{ SNDRV_CHMAP_FL,	FL },
+	{ SNDRV_CHMAP_FR,	FR },
+	{ SNDRV_CHMAP_RL,	RL },
+	{ SNDRV_CHMAP_RR,	RR },
+	{ SNDRV_CHMAP_LFE,	LFE },
+	{ SNDRV_CHMAP_FC,	FC },
+	{ SNDRV_CHMAP_RLC,	RLC },
+	{ SNDRV_CHMAP_RRC,	RRC },
+	{ SNDRV_CHMAP_RC,	RC },
+	{ SNDRV_CHMAP_FLC,	FLC },
+	{ SNDRV_CHMAP_FRC,	FRC },
+	{} /* terminator */
+};
+
+/*
+ * cea Speaker allocation structure
+ */
+struct hdmi_codec_cea_spk_alloc {
+	const int ca_id;
+	const unsigned long speakers[HDMI_MAX_SPEAKERS];
+
+	/* Derived values, computed during init */
+	unsigned int channels;
+	unsigned long spks_mask;
+	unsigned long spk_na_mask;
+};
+
+/* default HDMI channel maps is stereo */
+const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
+	{ }
+};
+
+/*
+ * hdmi_codec_channel_alloc: speaker configuration available for CEA
+ *
+ * This is an ordered list!
+ * The preceding ones have better chances to be selected by
+ * hdmi_codec_get_ch_alloc_table_idx().
+ */
+static struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
+{ .ca_id = 0x00,  .speakers = {   0,    0,   0,   0,   0,    0,  FR,  FL } },
+/* 2.1 */
+{ .ca_id = 0x01,  .speakers = {   0,    0,   0,   0,   0,  LFE,  FR,  FL } },
+/* Dolby Surround */
+{ .ca_id = 0x02,  .speakers = {   0,    0,   0,   0,  FC,    0,  FR,  FL } },
+/* surround51 */
+{ .ca_id = 0x0b,  .speakers = {   0,    0,  RR,  RL,  FC,  LFE,  FR,  FL } },
+/* surround40 */
+{ .ca_id = 0x08,  .speakers = {   0,    0,  RR,  RL,   0,    0,  FR,  FL } },
+/* surround41 */
+{ .ca_id = 0x09,  .speakers = {   0,    0,  RR,  RL,   0,  LFE,  FR,  FL } },
+/* surround50 */
+{ .ca_id = 0x0a,  .speakers = {   0,    0,  RR,  RL,  FC,    0,  FR,  FL } },
+/* 6.1 */
+{ .ca_id = 0x0f,  .speakers = {   0,   RC,  RR,  RL,  FC,  LFE,  FR,  FL } },
+/* surround71 */
+{ .ca_id = 0x13,  .speakers = { RRC,  RLC,  RR,  RL,  FC,  LFE,  FR,  FL } },
+
+{ .ca_id = 0x03,  .speakers = {   0,    0,   0,   0,  FC,  LFE,  FR,  FL } },
+{ .ca_id = 0x04,  .speakers = {   0,    0,   0,  RC,   0,    0,  FR,  FL } },
+{ .ca_id = 0x05,  .speakers = {   0,    0,   0,  RC,   0,  LFE,  FR,  FL } },
+{ .ca_id = 0x06,  .speakers = {   0,    0,   0,  RC,  FC,    0,  FR,  FL } },
+{ .ca_id = 0x07,  .speakers = {   0,    0,   0,  RC,  FC,  LFE,  FR,  FL } },
+{ .ca_id = 0x0c,  .speakers = {   0,   RC,  RR,  RL,   0,    0,  FR,  FL } },
+{ .ca_id = 0x0d,  .speakers = {   0,   RC,  RR,  RL,   0,  LFE,  FR,  FL } },
+{ .ca_id = 0x0e,  .speakers = {   0,   RC,  RR,  RL,  FC,    0,  FR,  FL } },
+{ .ca_id = 0x10,  .speakers = { RRC,  RLC,  RR,  RL,   0,    0,  FR,  FL } },
+{ .ca_id = 0x11,  .speakers = { RRC,  RLC,  RR,  RL,   0,  LFE,  FR,  FL } },
+{ .ca_id = 0x12,  .speakers = { RRC,  RLC,  RR,  RL,  FC,    0,  FR,  FL } },
+{ .ca_id = 0x14,  .speakers = { FRC,  FLC,   0,   0,   0,    0,  FR,  FL } },
+{ .ca_id = 0x15,  .speakers = { FRC,  FLC,   0,   0,   0,  LFE,  FR,  FL } },
+{ .ca_id = 0x16,  .speakers = { FRC,  FLC,   0,   0,  FC,    0,  FR,  FL } },
+{ .ca_id = 0x17,  .speakers = { FRC,  FLC,   0,   0,  FC,  LFE,  FR,  FL } },
+{ .ca_id = 0x18,  .speakers = { FRC,  FLC,   0,  RC,   0,    0,  FR,  FL } },
+{ .ca_id = 0x19,  .speakers = { FRC,  FLC,   0,  RC,   0,  LFE,  FR,  FL } },
+{ .ca_id = 0x1a,  .speakers = { FRC,  FLC,   0,  RC,  FC,    0,  FR,  FL } },
+{ .ca_id = 0x1b,  .speakers = { FRC,  FLC,   0,  RC,  FC,  LFE,  FR,  FL } },
+{ .ca_id = 0x1c,  .speakers = { FRC,  FLC,  RR,  RL,   0,    0,  FR,  FL } },
+{ .ca_id = 0x1d,  .speakers = { FRC,  FLC,  RR,  RL,   0,  LFE,  FR,  FL } },
+{ .ca_id = 0x1e,  .speakers = { FRC,  FLC,  RR,  RL,  FC,    0,  FR,  FL } },
+{ .ca_id = 0x1f,  .speakers = { FRC,  FLC,  RR,  RL,  FC,  LFE,  FR,  FL } },
+};
+
 struct hdmi_codec_priv {
 	struct hdmi_codec_pdata hcd;
 	struct snd_soc_dai_driver *daidrv;
@@ -41,6 +160,8 @@ struct hdmi_codec_priv {
 	struct snd_pcm_substream *current_stream;
 	struct snd_pcm_hw_constraint_list ratec;
 	uint8_t eld[MAX_ELD_BYTES];
+	struct snd_pcm_chmap_elem *chmap_tlv;
+	struct snd_pcm_chmap *chmap_info;
 };
 
 static const struct snd_soc_dapm_widget hdmi_widgets[] = {
@@ -79,6 +200,148 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
+{
+	int i;
+	const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
+		[0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
+		[4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
+	};
+	unsigned long spk_mask = 0;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) {
+		if (spk_alloc & (1 << i))
+			spk_mask |= hdmi_codec_eld_spk_alloc_bits[i];
+	}
+
+	return spk_mask;
+}
+
+/* From speaker bit mask to ALSA API channel position */
+static int snd_hdac_spk_to_chmap(int spk)
+{
+	const struct hdmi_codec_channel_map_table *t = hdmi_codec_map_table;
+
+	for (; t->map; t++) {
+		if (t->spk_mask == spk)
+			return t->map;
+	}
+
+	return 0;
+}
+
+/**
+ * hdmi_codec_cea_init_channel_alloc:
+ * Compute derived values in hdmi_codec_channel_alloc[].
+ * spk_na_mask is used to store unused channels in mid of the channel
+ * allocations. These particular channels are then considered as active channels
+ * For instance:
+ *    CA_ID 0x02: CA =  (FL, FR, 0, FC) => spk_na_mask = 0x04, channels = 4
+ *    CA_ID 0x04: CA =  (FL, FR, 0, 0, RC) => spk_na_mask = 0x03C, channels = 5
+ */
+static void hdmi_codec_cea_init_channel_alloc(void)
+{
+	int i, j, k, last;
+	struct hdmi_codec_cea_spk_alloc *p;
+
+	/* Test if not already done by another instance */
+	if (hdmi_codec_channel_alloc[0].channels)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++) {
+		p = hdmi_codec_channel_alloc + i;
+		p->spks_mask = 0;
+		p->spk_na_mask = 0;
+		last = HDMI_MAX_SPEAKERS;
+		for (j = 0, k = 7; j < HDMI_MAX_SPEAKERS; j++, k--) {
+			if (p->speakers[j]) {
+				p->spks_mask |= p->speakers[j];
+				if (last == HDMI_MAX_SPEAKERS)
+					last = j;
+			} else if (last != HDMI_MAX_SPEAKERS) {
+				p->spk_na_mask |= 1 << k;
+			}
+		}
+		p->channels = 8 - last;
+	}
+}
+
+static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp,
+					     unsigned char channels)
+{
+	int i;
+	u8 spk_alloc;
+	unsigned long spk_mask;
+	struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
+
+	spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
+	spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) {
+		/* If spk_alloc == 0, HDMI is unplugged return stereo config*/
+		if (!spk_alloc && cap->ca_id == 0)
+			return i;
+		if (cap->channels != channels)
+			continue;
+		if (!(cap->spks_mask == (spk_mask & cap->spks_mask)))
+			continue;
+		return i;
+	}
+
+	return -EINVAL;
+}
+
+static void hdmi_cea_alloc_to_tlv_spks(struct hdmi_codec_cea_spk_alloc *cap,
+				       unsigned char *chmap)
+{
+	int count = 0;
+	int c, spk;
+
+	/* Detect unused channels in cea caps, tag them as N/A channel in TLV */
+	for (c = 0; c < HDMI_MAX_SPEAKERS; c++) {
+		spk = cap->speakers[7 - c];
+		if (cap->spk_na_mask & BIT(c))
+			chmap[count++] = SNDRV_CHMAP_NA;
+		else
+			chmap[count++] = snd_hdac_spk_to_chmap(spk);
+	}
+}
+
+static void hdmi_cea_alloc_to_tlv_chmap(struct hdmi_codec_priv *hcp,
+					struct hdmi_codec_cea_spk_alloc *cap)
+{
+	unsigned int chs, count = 0;
+	struct snd_pcm_chmap *info = hcp->chmap_info;
+	struct snd_pcm_chmap_elem *chmap = info->chmap;
+	unsigned long max_chs = info->max_channels;
+	int num_ca = ARRAY_SIZE(hdmi_codec_channel_alloc);
+	int spk_alloc, spk_mask;
+
+	spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
+	spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
+
+	for (chs = 2; chs <= max_chs; chs++) {
+		int i;
+		struct hdmi_codec_cea_spk_alloc *cap;
+
+		cap = hdmi_codec_channel_alloc;
+		for (i = 0; i < num_ca; i++, cap++) {
+			if (cap->channels != chs)
+				continue;
+
+			if (!(cap->spks_mask == (spk_mask & cap->spks_mask)))
+				continue;
+
+			chmap[count].channels = cap->channels;
+			hdmi_cea_alloc_to_tlv_spks(cap, chmap[count].map);
+			count++;
+		}
+	}
+
+	/* Force last one to 0 to indicate end of available allocations */
+	chmap[count].channels = 0;
+}
+
 static const struct snd_kcontrol_new hdmi_controls[] = {
 	{
 		.access = SNDRV_CTL_ELEM_ACCESS_READ |
@@ -173,7 +436,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
 			.dig_subframe = { 0 },
 		}
 	};
-	int ret;
+	int ret, idx;
 
 	dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
 		params_width(params), params_rate(params),
@@ -200,6 +463,16 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
 	hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
 	hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
 
+	/* Select a channel allocation that matches with ELD and pcm channels */
+	idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels);
+	if (idx < 0) {
+		dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
+			idx);
+		return idx;
+	}
+	hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
+	hdmi_cea_alloc_to_tlv_chmap(hcp, &hdmi_codec_channel_alloc[idx]);
+
 	hp.sample_width = params_width(params);
 	hp.sample_rate = params_rate(params);
 	hp.channels = params_channels(params);
@@ -328,6 +601,36 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
 			 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
 			 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
 
+static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
+			      struct snd_soc_dai *dai)
+{
+	struct snd_soc_dai_driver *drv = dai->driver;
+	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
+	int ret;
+
+	dev_dbg(dai->dev, "%s()\n", __func__);
+
+	ret =  snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				      NULL, drv->playback.channels_max, 0,
+				      &hcp->chmap_info);
+	if (ret < 0)
+		return ret;
+
+	hcp->chmap_tlv = devm_kcalloc(dai->dev,
+				      ARRAY_SIZE(hdmi_codec_channel_alloc),
+				      sizeof(*hcp->chmap_tlv), GFP_KERNEL);
+	if (!hcp->chmap_tlv)
+		return -ENOMEM;
+
+	/* Initialize mapping to stereo as default config supported */
+	memcpy(hcp->chmap_tlv, hdmi_codec_stereo_chmaps,
+	       ARRAY_SIZE(hdmi_codec_stereo_chmaps) * sizeof(*hcp->chmap_tlv));
+
+	hcp->chmap_info->chmap = hcp->chmap_tlv;
+
+	return 0;
+}
+
 static struct snd_soc_dai_driver hdmi_i2s_dai = {
 	.id = DAI_ID_I2S,
 	.playback = {
@@ -339,6 +642,7 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
 		.sig_bits = 24,
 	},
 	.ops = &hdmi_dai_ops,
+	.pcm_new = hdmi_codec_pcm_new,
 };
 
 static const struct snd_soc_dai_driver hdmi_spdif_dai = {
@@ -351,6 +655,7 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
 		.formats = SPDIF_FORMATS,
 	},
 	.ops = &hdmi_dai_ops,
+	.pcm_new = hdmi_codec_pcm_new,
 };
 
 static char hdmi_dai_name[][DAI_NAME_SIZE] = {
@@ -465,6 +770,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
 		hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++];
 	}
 
+	hdmi_codec_cea_init_channel_alloc();
+
 	ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv,
 				     dai_count);
 	if (ret) {
@@ -479,6 +786,10 @@ static int hdmi_codec_probe(struct platform_device *pdev)
 
 static int hdmi_codec_remove(struct platform_device *pdev)
 {
+	struct hdmi_codec_priv *hcp;
+
+	hcp = dev_get_drvdata(&pdev->dev);
+	kfree(hcp->chmap_info);
 	snd_soc_unregister_codec(&pdev->dev);
 	return 0;
 }
-- 
1.9.1

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

* Re: [alsa-devel] [PATCH v3 2/4] ALSA pcm: allow non constant snd_pcm_chmap_elem
  2016-12-19 11:08 ` [PATCH v3 2/4] ALSA pcm: allow non constant snd_pcm_chmap_elem Arnaud Pouliquen
@ 2016-12-19 16:31   ` kbuild test robot
  2016-12-19 17:16     ` Arnaud Pouliquen
  0 siblings, 1 reply; 9+ messages in thread
From: kbuild test robot @ 2016-12-19 16:31 UTC (permalink / raw)
  To: Arnaud Pouliquen
  Cc: alsa-devel, dri-devel, lgirdwood, Jyri Sarha, Takashi Sakamoto,
	broonie, kbuild-all, Daniel Vetter

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

Hi Arnaud,

[auto build test WARNING on asoc/for-next]
[also build test WARNING on v4.9 next-20161219]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Arnaud-Pouliquen/Generic-HDMI-codec-Add-channel-mapping-control/20161219-235923
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
config: x86_64-acpi-redef (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   sound/pci/atiixp.c: In function 'snd_atiixp_pcm_new':
>> sound/pci/atiixp.c:1298:10: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
             snd_pcm_alt_chmaps, chip->max_channels, 0,
             ^~~~~~~~~~~~~~~~~~
   In file included from sound/pci/atiixp.c:31:0:
   include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
    int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
        ^~~~~~~~~~~~~~~~~~~~~~
--
   sound/pci/cmipci.c: In function 'snd_cmipci_pcm_spdif_new':
>> sound/pci/cmipci.c:1966:10: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
             snd_pcm_alt_chmaps, cm->max_channels, 0,
             ^~~~~~~~~~~~~~~~~~
   In file included from sound/pci/cmipci.c:35:0:
   include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
    int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
        ^~~~~~~~~~~~~~~~~~~~~~
--
   sound/pci/ens1370.c: In function 'snd_ensoniq_pcm':
>> sound/pci/ens1370.c:1297:10: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
             surround_map, 2, 0, NULL);
             ^~~~~~~~~~~~
   In file included from sound/pci/ens1370.c:41:0:
   include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
    int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
        ^~~~~~~~~~~~~~~~~~~~~~
   sound/pci/ens1370.c: In function 'snd_ensoniq_pcm2':
   sound/pci/ens1370.c:1329:10: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
             snd_pcm_std_chmaps, 2, 0, NULL);
             ^~~~~~~~~~~~~~~~~~
   In file included from sound/pci/ens1370.c:41:0:
   include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
    int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
        ^~~~~~~~~~~~~~~~~~~~~~
--
   In file included from sound/pci/au88x0/au8810.c:9:0:
   sound/pci/au88x0/au88x0_pcm.c: In function 'snd_vortex_new_pcm':
>> sound/pci/au88x0/au88x0_pcm.c:659:11: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
              snd_pcm_std_chmaps,
              ^~~~~~~~~~~~~~~~~~
   In file included from sound/pci/au88x0/au88x0.h:23:0,
                    from sound/pci/au88x0/au8810.c:2:
   include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
    int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
        ^~~~~~~~~~~~~~~~~~~~~~
   In file included from sound/pci/au88x0/au8810.c:9:0:
   sound/pci/au88x0/au88x0_pcm.c:665:11: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
              snd_pcm_std_chmaps, 2, 0, NULL);
              ^~~~~~~~~~~~~~~~~~
   In file included from sound/pci/au88x0/au88x0.h:23:0,
                    from sound/pci/au88x0/au8810.c:2:
   include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
    int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
        ^~~~~~~~~~~~~~~~~~~~~~
--
   sound/pci/ca0106/ca0106_main.c: In function 'snd_ca0106_pcm':
>> sound/pci/ca0106/ca0106_main.c:1424:63: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
     err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
                                                                  ^~~
   In file included from sound/pci/ca0106/ca0106_main.c:147:0:
   include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
    int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
        ^~~~~~~~~~~~~~~~~~~~~~

vim +1298 sound/pci/atiixp.c

^1da177e Linus Torvalds 2005-04-16  1282  	/* PCM #0: analog I/O */
74ee4ff1 Takashi Iwai   2005-11-17  1283  	err = snd_pcm_new(chip->card, "ATI IXP AC97",
74ee4ff1 Takashi Iwai   2005-11-17  1284  			  ATI_PCMDEV_ANALOG, 1, 1, &pcm);
^1da177e Linus Torvalds 2005-04-16  1285  	if (err < 0)
^1da177e Linus Torvalds 2005-04-16  1286  		return err;
^1da177e Linus Torvalds 2005-04-16  1287  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
^1da177e Linus Torvalds 2005-04-16  1288  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
^1da177e Linus Torvalds 2005-04-16  1289  	pcm->private_data = chip;
^1da177e Linus Torvalds 2005-04-16  1290  	strcpy(pcm->name, "ATI IXP AC97");
^1da177e Linus Torvalds 2005-04-16  1291  	chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
^1da177e Linus Torvalds 2005-04-16  1292  
^1da177e Linus Torvalds 2005-04-16  1293  	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
74ee4ff1 Takashi Iwai   2005-11-17  1294  					      snd_dma_pci_data(chip->pci),
74ee4ff1 Takashi Iwai   2005-11-17  1295  					      64*1024, 128*1024);
^1da177e Linus Torvalds 2005-04-16  1296  
e36e3b86 Takashi Iwai   2012-08-03  1297  	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
e36e3b86 Takashi Iwai   2012-08-03 @1298  				     snd_pcm_alt_chmaps, chip->max_channels, 0,
e36e3b86 Takashi Iwai   2012-08-03  1299  				     &chmap);
e36e3b86 Takashi Iwai   2012-08-03  1300  	if (err < 0)
e36e3b86 Takashi Iwai   2012-08-03  1301  		return err;
e36e3b86 Takashi Iwai   2012-08-03  1302  	chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
e36e3b86 Takashi Iwai   2012-08-03  1303  	chip->ac97[0]->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
e36e3b86 Takashi Iwai   2012-08-03  1304  
^1da177e Linus Torvalds 2005-04-16  1305  	/* no SPDIF support on codec? */
^1da177e Linus Torvalds 2005-04-16  1306  	if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates)

:::::: The code at line 1298 was first introduced by commit
:::::: e36e3b86c78cee9c7435eb33e0ef8a788193e812 ALSA: Implement channel maps for standard onboard AC97 drivers

:::::: TO: Takashi Iwai <tiwai@suse.de>
:::::: CC: Takashi Iwai <tiwai@suse.de>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28671 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v3 2/4] ALSA pcm: allow non constant snd_pcm_chmap_elem
  2016-12-19 16:31   ` [alsa-devel] " kbuild test robot
@ 2016-12-19 17:16     ` Arnaud Pouliquen
  0 siblings, 0 replies; 9+ messages in thread
From: Arnaud Pouliquen @ 2016-12-19 17:16 UTC (permalink / raw)
  Cc: alsa-devel, Takashi Iwai, dri-devel, lgirdwood, Jyri Sarha,
	Takashi Sakamoto, David Airlie, broonie, kbuild-all,
	Daniel Vetter


I had a doubt...this confirms that my arm compiler is too permissive :(
This patch in pcm_lib has to be abandoned.
I will propose a V4 with one/some constant table(s) defined in hdmi-codec...

Regards
Arnaud


On 12/19/2016 05:31 PM, kbuild test robot wrote:
> Hi Arnaud,
> 
> [auto build test WARNING on asoc/for-next]
> [also build test WARNING on v4.9 next-20161219]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Arnaud-Pouliquen/Generic-HDMI-codec-Add-channel-mapping-control/20161219-235923
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
> config: x86_64-acpi-redef (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=x86_64 
> 
> All warnings (new ones prefixed by >>):
> 
>    sound/pci/atiixp.c: In function 'snd_atiixp_pcm_new':
>>> sound/pci/atiixp.c:1298:10: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
>              snd_pcm_alt_chmaps, chip->max_channels, 0,
>              ^~~~~~~~~~~~~~~~~~
>    In file included from sound/pci/atiixp.c:31:0:
>    include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
>     int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
>         ^~~~~~~~~~~~~~~~~~~~~~
> --
>    sound/pci/cmipci.c: In function 'snd_cmipci_pcm_spdif_new':
>>> sound/pci/cmipci.c:1966:10: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
>              snd_pcm_alt_chmaps, cm->max_channels, 0,
>              ^~~~~~~~~~~~~~~~~~
>    In file included from sound/pci/cmipci.c:35:0:
>    include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
>     int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
>         ^~~~~~~~~~~~~~~~~~~~~~
> --
>    sound/pci/ens1370.c: In function 'snd_ensoniq_pcm':
>>> sound/pci/ens1370.c:1297:10: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
>              surround_map, 2, 0, NULL);
>              ^~~~~~~~~~~~
>    In file included from sound/pci/ens1370.c:41:0:
>    include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
>     int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
>         ^~~~~~~~~~~~~~~~~~~~~~
>    sound/pci/ens1370.c: In function 'snd_ensoniq_pcm2':
>    sound/pci/ens1370.c:1329:10: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
>              snd_pcm_std_chmaps, 2, 0, NULL);
>              ^~~~~~~~~~~~~~~~~~
>    In file included from sound/pci/ens1370.c:41:0:
>    include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
>     int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
>         ^~~~~~~~~~~~~~~~~~~~~~
> --
>    In file included from sound/pci/au88x0/au8810.c:9:0:
>    sound/pci/au88x0/au88x0_pcm.c: In function 'snd_vortex_new_pcm':
>>> sound/pci/au88x0/au88x0_pcm.c:659:11: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
>               snd_pcm_std_chmaps,
>               ^~~~~~~~~~~~~~~~~~
>    In file included from sound/pci/au88x0/au88x0.h:23:0,
>                     from sound/pci/au88x0/au8810.c:2:
>    include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
>     int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
>         ^~~~~~~~~~~~~~~~~~~~~~
>    In file included from sound/pci/au88x0/au8810.c:9:0:
>    sound/pci/au88x0/au88x0_pcm.c:665:11: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
>               snd_pcm_std_chmaps, 2, 0, NULL);
>               ^~~~~~~~~~~~~~~~~~
>    In file included from sound/pci/au88x0/au88x0.h:23:0,
>                     from sound/pci/au88x0/au8810.c:2:
>    include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
>     int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
>         ^~~~~~~~~~~~~~~~~~~~~~
> --
>    sound/pci/ca0106/ca0106_main.c: In function 'snd_ca0106_pcm':
>>> sound/pci/ca0106/ca0106_main.c:1424:63: warning: passing argument 3 of 'snd_pcm_add_chmap_ctls' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
>      err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
>                                                                   ^~~
>    In file included from sound/pci/ca0106/ca0106_main.c:147:0:
>    include/sound/pcm.h:1389:5: note: expected 'struct snd_pcm_chmap_elem *' but argument is of type 'const struct snd_pcm_chmap_elem *'
>     int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
>         ^~~~~~~~~~~~~~~~~~~~~~
> 
> vim +1298 sound/pci/atiixp.c
> 
> ^1da177e Linus Torvalds 2005-04-16  1282  	/* PCM #0: analog I/O */
> 74ee4ff1 Takashi Iwai   2005-11-17  1283  	err = snd_pcm_new(chip->card, "ATI IXP AC97",
> 74ee4ff1 Takashi Iwai   2005-11-17  1284  			  ATI_PCMDEV_ANALOG, 1, 1, &pcm);
> ^1da177e Linus Torvalds 2005-04-16  1285  	if (err < 0)
> ^1da177e Linus Torvalds 2005-04-16  1286  		return err;
> ^1da177e Linus Torvalds 2005-04-16  1287  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
> ^1da177e Linus Torvalds 2005-04-16  1288  	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
> ^1da177e Linus Torvalds 2005-04-16  1289  	pcm->private_data = chip;
> ^1da177e Linus Torvalds 2005-04-16  1290  	strcpy(pcm->name, "ATI IXP AC97");
> ^1da177e Linus Torvalds 2005-04-16  1291  	chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
> ^1da177e Linus Torvalds 2005-04-16  1292  
> ^1da177e Linus Torvalds 2005-04-16  1293  	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
> 74ee4ff1 Takashi Iwai   2005-11-17  1294  					      snd_dma_pci_data(chip->pci),
> 74ee4ff1 Takashi Iwai   2005-11-17  1295  					      64*1024, 128*1024);
> ^1da177e Linus Torvalds 2005-04-16  1296  
> e36e3b86 Takashi Iwai   2012-08-03  1297  	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
> e36e3b86 Takashi Iwai   2012-08-03 @1298  				     snd_pcm_alt_chmaps, chip->max_channels, 0,
> e36e3b86 Takashi Iwai   2012-08-03  1299  				     &chmap);
> e36e3b86 Takashi Iwai   2012-08-03  1300  	if (err < 0)
> e36e3b86 Takashi Iwai   2012-08-03  1301  		return err;
> e36e3b86 Takashi Iwai   2012-08-03  1302  	chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
> e36e3b86 Takashi Iwai   2012-08-03  1303  	chip->ac97[0]->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
> e36e3b86 Takashi Iwai   2012-08-03  1304  
> ^1da177e Linus Torvalds 2005-04-16  1305  	/* no SPDIF support on codec? */
> ^1da177e Linus Torvalds 2005-04-16  1306  	if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates)
> 
> :::::: The code at line 1298 was first introduced by commit
> :::::: e36e3b86c78cee9c7435eb33e0ef8a788193e812 ALSA: Implement channel maps for standard onboard AC97 drivers
> 
> :::::: TO: Takashi Iwai <tiwai@suse.de>
> :::::: CC: Takashi Iwai <tiwai@suse.de>
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
> 

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

* Re: [PATCH v3 0/4] Generic HDMI codec: Add channel mapping control
  2016-12-19 11:08 [PATCH v3 0/4] Generic HDMI codec: Add channel mapping control Arnaud Pouliquen
                   ` (3 preceding siblings ...)
  2016-12-19 11:08 ` [PATCH v3 4/4] ASoC: hdmi-codec: add channel mapping control Arnaud Pouliquen
@ 2016-12-19 19:49 ` Takashi Sakamoto
  4 siblings, 0 replies; 9+ messages in thread
From: Takashi Sakamoto @ 2016-12-19 19:49 UTC (permalink / raw)
  To: Arnaud Pouliquen, alsa-devel, dri-devel
  Cc: Takashi Iwai, lgirdwood, Jyri Sarha, David Airlie, broonie,
	Daniel Vetter

Hi,

On Dec 19 2016 20:08, Arnaud Pouliquen wrote:
> Aim of this patch is to add  'Playback Channel Map' control to export
> audio capabilities in term of HDMI sink speakers allocation.
>
> V3:
>  - "ASoC: hdmi-codec: add channel mapping control":
>      => Minor fixes:
>          - select stereo speaker config by default if HDMI cable unplugged
>          - fix compilation warning.
>  - "DRM: add help to get ELD speaker allocation"
>      => No delta vs V2.
>  - "ALSA pcm: allow non constant snd_pcm_chmap_elem"
>      => No delta vs V2.
>  - "ASoC: core: add optional pcm_new callback for DAI driver"
>      => No delta vs V2.
>
> V2:
> In this version I use chmap helper functions from pcm_lib.c.
> It is quite tricky to use it from ASoC due to the relation chip of the controls
> with the pcm runtime.
> After several tries, my conclusion is that it must be handled in ASoC DAI driver.
> Main reason is that the DAI driver can not provide snd_pcm_chmap struct
> through kcontrol structure. But this induces that soc-core provides pcm runtime
> structure to DAI driver during probe.
>
> Base on this conclusion. I reworked my patches by adding 2
> new patches in patch-set
> 1)  ALSA pcm: allow non constant snd_pcm_chmap_elem
>    This patch allows to handle non constant channel mapping. As ELD
>    information can change during runtime it is mandatory to properly
>    handle the feature.
>    In term of compatibility with legacy it should be straightforward,
>    as update just consists in suppressing the 'const' constraint.
>
> 2)  ASoC: core: add optional pcm_new callback for DAI driver
>     This is the only way i found to be able to use
>     snd_pcm_add_chmap_ctls and associated controls helper functions.
>     From my point of view, this is the more simple way to add relationship
>     between DAI and associated pcm devices.
>    Notice that this patch, if accepted, makes the following one obsolete,
>    as it also answer to the associated topic:
>   [PATCH v5 0/2] ALSA controls management using index/device/sub-devices fields
>   (http://www.spinics.net/lists/alsa-devel/msg57639.html).
>
> If you estimate that this it not reasonable i will come back to my first version.
>
> V1:
> This patch follows discussion initiate here:
> [RFC] ASOC: HDMI audio info frame speaker allocation
> http://www.spinics.net/lists/alsa-devel/msg57363.html
>
> The code is fully inspired from HDA driver.
> On hw_param, HDMI sink speaker capabilities are exported via TLV ops
> and  a CEA allocation is choson, based on ELD information and the number of
> channels requested by user.
>
> Mains differences with HDA implementation are:
>  - Control is read only
>  - Channel swap is not supported. Consequence is that unused channel in
>    the mid of CEA audio infoframe channel mapping are considered as
>    active.
>    example for channel allocation 0x02: FL, FR, 0, FC)
> 	This configuration is only available for a 4 channels stream.
>   - Channel allocation table has been reordered and HDMI 2.0 is not
>     supported.
>
> Arnaud Pouliquen (4):
>   DRM: add help to get ELD speaker allocation
>   ALSA pcm: allow non constant snd_pcm_chmap_elem
>   ASoC: core: add optional pcm_new callback for DAI driver
>   ASoC: hdmi-codec: add channel mapping control
>
>  include/drm/drm_edid.h        |  13 ++
>  include/sound/pcm.h           |   4 +-
>  include/sound/soc-dai.h       |   3 +
>  sound/core/pcm_lib.c          |   6 +-
>  sound/soc/codecs/hdmi-codec.c | 313 +++++++++++++++++++++++++++++++++++++++++-
>  sound/soc/soc-core.c          |  28 ++++
>  6 files changed, 361 insertions(+), 6 deletions(-)

I'm sorry but please drop me from CC list. I'd like not to be involved 
into this kind of new integration within merge window of next Linux 
kernel, as I said to you.


Regards

Takashi Sakamoto

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

* Re: [PATCH v3 1/4] DRM: add help to get ELD speaker allocation
  2016-12-19 11:08 ` [PATCH v3 1/4] DRM: add help to get ELD speaker allocation Arnaud Pouliquen
@ 2016-12-20 14:07   ` Jani Nikula
  0 siblings, 0 replies; 9+ messages in thread
From: Jani Nikula @ 2016-12-20 14:07 UTC (permalink / raw)
  To: Arnaud Pouliquen, alsa-devel, dri-devel
  Cc: Daniel Vetter, broonie, lgirdwood, Jyri Sarha, Takashi Sakamoto

On Mon, 19 Dec 2016, Arnaud Pouliquen <arnaud.pouliquen@st.com> wrote:
> Add helper to allow users to retrieve the speaker allocations without
> knowledge of the ELD structure.
>
> Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>

I've already replied with my Reviewed-by, please take care to include
them.

Reviewed-by: Jani Nikula <jani.nikula@intel.com>


> ---
>  include/drm/drm_edid.h | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
>
> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
> index c3a7d44..de93543 100644
> --- a/include/drm/drm_edid.h
> +++ b/include/drm/drm_edid.h
> @@ -248,6 +248,7 @@ struct detailed_timing {
>  # define DRM_ELD_AUD_SYNCH_DELAY_MAX	0xfa	/* 500 ms */
>  
>  #define DRM_ELD_SPEAKER			7
> +# define DRM_ELD_SPEAKER_MASK		0x7f
>  # define DRM_ELD_SPEAKER_RLRC		(1 << 6)
>  # define DRM_ELD_SPEAKER_FLRC		(1 << 5)
>  # define DRM_ELD_SPEAKER_RC		(1 << 4)
> @@ -415,6 +416,18 @@ static inline int drm_eld_size(const uint8_t *eld)
>  }
>  
>  /**
> + * drm_eld_get_spk_alloc - Get speaker allocation
> + * @eld: pointer to an ELD memory structure
> + *
> + * The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER
> + * field definitions to identify speakers.
> + */
> +static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
> +{
> +	return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;
> +}
> +
> +/**
>   * drm_eld_get_conn_type - Get device type hdmi/dp connected
>   * @eld: pointer to an ELD memory structure
>   *

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

end of thread, other threads:[~2016-12-20 14:07 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-19 11:08 [PATCH v3 0/4] Generic HDMI codec: Add channel mapping control Arnaud Pouliquen
2016-12-19 11:08 ` [PATCH v3 1/4] DRM: add help to get ELD speaker allocation Arnaud Pouliquen
2016-12-20 14:07   ` Jani Nikula
2016-12-19 11:08 ` [PATCH v3 2/4] ALSA pcm: allow non constant snd_pcm_chmap_elem Arnaud Pouliquen
2016-12-19 16:31   ` [alsa-devel] " kbuild test robot
2016-12-19 17:16     ` Arnaud Pouliquen
2016-12-19 11:08 ` [PATCH v3 3/4] ASoC: core: add optional pcm_new callback for DAI driver Arnaud Pouliquen
2016-12-19 11:08 ` [PATCH v3 4/4] ASoC: hdmi-codec: add channel mapping control Arnaud Pouliquen
2016-12-19 19:49 ` [PATCH v3 0/4] Generic HDMI codec: Add " Takashi Sakamoto

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.