Blob Blame History Raw
From 6d843ba5d377961f6765466ba0cc362dd10f7557 Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Wed, 14 Jun 2017 12:37:39 +0100
Subject: [PATCH 01/39] topology: Add support for missing fields parser.

The alsa-lib topology parser is missing some fields for certain objects that
are part of the ABI. This patch adds the missing fields to the parser.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/topology/pcm.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 183 insertions(+)

diff --git a/src/topology/pcm.c b/src/topology/pcm.c
index daef20e4..0f4deb4f 100644
--- a/src/topology/pcm.c
+++ b/src/topology/pcm.c
@@ -383,6 +383,49 @@ int tplg_parse_stream_caps(snd_tplg_t *tplg,
 			tplg_dbg("\t\t%s: %d\n", id, sc->channels_max);
 			continue;
 		}
+
+		if (strcmp(id, "periods_min") == 0) {
+			sc->periods_min = atoi(val);
+			tplg_dbg("\t\t%s: %d\n", id, sc->periods_min);
+			continue;
+		}
+
+		if (strcmp(id, "periods_max") == 0) {
+			sc->periods_max = atoi(val);
+			tplg_dbg("\t\t%s: %d\n", id, sc->periods_max);
+			continue;
+		}
+
+		if (strcmp(id, "period_size_min") == 0) {
+			sc->period_size_min = atoi(val);
+			tplg_dbg("\t\t%s: %d\n", id, sc->period_size_min);
+			continue;
+		}
+
+		if (strcmp(id, "period_size_max") == 0) {
+			sc->period_size_max = atoi(val);
+			tplg_dbg("\t\t%s: %d\n", id, sc->period_size_max);
+			continue;
+		}
+
+		if (strcmp(id, "buffer_size_min") == 0) {
+			sc->buffer_size_min = atoi(val);
+			tplg_dbg("\t\t%s: %d\n", id, sc->buffer_size_min);
+			continue;
+		}
+
+		if (strcmp(id, "buffer_size_max") == 0) {
+			sc->buffer_size_max = atoi(val);
+			tplg_dbg("\t\t%s: %d\n", id, sc->buffer_size_max);
+			continue;
+		}
+
+		if (strcmp(id, "sig_bits") == 0) {
+			sc->sig_bits = atoi(val);
+			tplg_dbg("\t\t%s: %d\n", id, sc->sig_bits);
+			continue;
+		}
+
 	}
 
 	return 0;
@@ -572,6 +615,17 @@ int tplg_parse_pcm(snd_tplg_t *tplg,
 			continue;
 		}
 
+		if (strcmp(id, "compress") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			if (strcmp(val, "true") == 0)
+				pcm->compress = 1;
+
+			tplg_dbg("\t%s: %s\n", id, val);
+			continue;
+		}
+
 		if (strcmp(id, "dai") == 0) {
 			err = tplg_parse_compound(tplg, n,
 				tplg_parse_fe_dai, elem);
@@ -655,6 +709,26 @@ int tplg_parse_dai(snd_tplg_t *tplg,
 			continue;
 		}
 
+		if (strcmp(id, "playback") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			dai->playback = atoi(val);
+			tplg_dbg("\t%s: %d\n", id, dai->playback);
+			continue;
+		}
+
+
+		if (strcmp(id, "capture") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			dai->capture = atoi(val);
+			tplg_dbg("\t%s: %d\n", id, dai->capture);
+			continue;
+		}
+
+
 		/* stream capabilities */
 		if (strcmp(id, "pcm") == 0) {
 			err = tplg_parse_compound(tplg, n,
@@ -997,6 +1071,23 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
 			continue;
 		}
 
+		if (strcmp(id, "bclk_freq") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->bclk_rate = atoi(val);
+			continue;
+		}
+
+		if (strcmp(id, "bclk_invert") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			if (!strcmp(val, "true"))
+				hw_cfg->invert_bclk = true;
+			continue;
+		}
+
 		if (strcmp(id, "fsync") == 0) {
 			if (snd_config_get_string(n, &val) < 0)
 				return -EINVAL;
@@ -1005,6 +1096,98 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg,
 				hw_cfg->fsync_master = true;
 			continue;
 		}
+
+		if (strcmp(id, "fsync_invert") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			if (!strcmp(val, "true"))
+				hw_cfg->invert_fsync = true;
+			continue;
+		}
+
+		if (strcmp(id, "fsync_freq") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->fsync_rate = atoi(val);
+			continue;
+		}
+
+		if (strcmp(id, "mclk_freq") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->mclk_rate = atoi(val);
+			continue;
+		}
+
+		if (strcmp(id, "mclk") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			if (!strcmp(val, "master"))
+				hw_cfg->mclk_direction = true;
+			continue;
+		}
+
+		if (strcmp(id, "pm_gate_clocks") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			if (!strcmp(val, "true"))
+				hw_cfg->clock_gated = true;
+			continue;
+		}
+
+		if (strcmp(id, "tdm_slots") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->tdm_slots = atoi(val);
+			continue;
+		}
+
+		if (strcmp(id, "tdm_slot_width") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->tdm_slot_width = atoi(val);
+			continue;
+		}
+
+		if (strcmp(id, "tx_slots") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->tx_slots = atoi(val);
+			continue;
+		}
+
+		if (strcmp(id, "rx_slots") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->rx_slots = atoi(val);
+			continue;
+		}
+
+		if (strcmp(id, "tx_channels") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->tx_channels = atoi(val);
+			continue;
+		}
+
+		if (strcmp(id, "rx_channels") == 0) {
+			if (snd_config_get_string(n, &val) < 0)
+				return -EINVAL;
+
+			hw_cfg->rx_channels = atoi(val);
+			continue;
+		}
+
 	}
 
 	return 0;
-- 
2.13.5


From 89c96ad7fb0168411260196560892835d0adeddf Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Wed, 14 Jun 2017 12:37:40 +0100
Subject: [PATCH 02/39] topology: disable alsa-lib topology debug output by
 default.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/topology/tplg_local.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index 42e3201d..60af0177 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -22,7 +22,6 @@
 #include <sound/asoc.h>
 #include <sound/tlv.h>
 
-#define TPLG_DEBUG
 #ifdef TPLG_DEBUG
 #define tplg_dbg SNDERR
 #else
-- 
2.13.5


From c550a421a3ff5b11ccd4a506ae04fdc6c5347ae3 Mon Sep 17 00:00:00 2001
From: Guneshwor Singh <guneshwor.o.singh@intel.com>
Date: Tue, 20 Jun 2017 09:45:45 +0530
Subject: [PATCH 03/39] topology: Add parsing for rates from conf

In alsa-lib topology parser, rate_min and rate_max are parsed currently.
Add support to parse rates also.

Signed-off-by: Guneshwor Singh <guneshwor.o.singh@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/topology.h        |  1 +
 src/topology/pcm.c        | 71 +++++++++++++++++++++++++++++++++++++++++++++++
 src/topology/tplg_local.h | 20 +++++++++++++
 3 files changed, 92 insertions(+)

diff --git a/include/topology.h b/include/topology.h
index ccb3a004..42d23762 100644
--- a/include/topology.h
+++ b/include/topology.h
@@ -534,6 +534,7 @@ extern "C" {
  * SectionPCMCapabilities."name" {
  *
  *	formats "S24_LE,S16_LE"		# Supported formats
+ *	rates "48000"			# Supported rates
  *	rate_min "48000"		# Max supported sample rate
  *	rate_max "48000"		# Min supported sample rate
  *	channels_min "2"		# Min number of channels
diff --git a/src/topology/pcm.c b/src/topology/pcm.c
index 0f4deb4f..bb63142e 100644
--- a/src/topology/pcm.c
+++ b/src/topology/pcm.c
@@ -20,6 +20,26 @@
 #include "list.h"
 #include "tplg_local.h"
 
+#define RATE(v) [SND_PCM_RATE_##v] = #v
+
+static const char *const snd_pcm_rate_names[] = {
+	RATE(5512),
+	RATE(8000),
+	RATE(11025),
+	RATE(16000),
+	RATE(22050),
+	RATE(32000),
+	RATE(44100),
+	RATE(48000),
+	RATE(64000),
+	RATE(88200),
+	RATE(96000),
+	RATE(176400),
+	RATE(192000),
+	RATE(CONTINUOUS),
+	RATE(KNOT),
+};
+
 struct tplg_elem *lookup_pcm_dai_stream(struct list_head *base, const char* id)
 {
 	struct list_head *pos;
@@ -309,6 +329,42 @@ static int split_format(struct snd_soc_tplg_stream_caps *caps, char *str)
 	return 0;
 }
 
+static int get_rate_value(const char* name)
+{
+	int rate;
+	for (rate = 0; rate <= SND_PCM_RATE_LAST; rate++) {
+		if (snd_pcm_rate_names[rate] &&
+		    strcasecmp(name, snd_pcm_rate_names[rate]) == 0) {
+			return rate;
+		}
+	}
+
+	return SND_PCM_RATE_UNKNOWN;
+}
+
+static int split_rate(struct snd_soc_tplg_stream_caps *caps, char *str)
+{
+	char *s = NULL;
+	snd_pcm_rates_t rate;
+	int i = 0;
+
+	s = strtok(str, ",");
+	while (s) {
+		rate = get_rate_value(s);
+
+		if (rate == SND_PCM_RATE_UNKNOWN) {
+			SNDERR("error: unsupported stream rate %s\n", s);
+			return -EINVAL;
+		}
+
+		caps->rates |= 1 << rate;
+		s = strtok(NULL, ", ");
+		i++;
+	}
+
+	return 0;
+}
+
 /* Parse pcm stream capabilities */
 int tplg_parse_stream_caps(snd_tplg_t *tplg,
 	snd_config_t *cfg, void *private ATTRIBUTE_UNUSED)
@@ -360,6 +416,21 @@ int tplg_parse_stream_caps(snd_tplg_t *tplg,
 			continue;
 		}
 
+		if (strcmp(id, "rates") == 0) {
+			s = strdup(val);
+			if (!s)
+				return -ENOMEM;
+
+			err = split_rate(sc, s);
+			free(s);
+
+			if (err < 0)
+				return err;
+
+			tplg_dbg("\t\t%s: %s\n", id, val);
+			continue;
+		}
+
 		if (strcmp(id, "rate_min") == 0) {
 			sc->rate_min = atoi(val);
 			tplg_dbg("\t\t%s: %d\n", id, sc->rate_min);
diff --git a/src/topology/tplg_local.h b/src/topology/tplg_local.h
index 60af0177..af599145 100644
--- a/src/topology/tplg_local.h
+++ b/src/topology/tplg_local.h
@@ -37,6 +37,26 @@
 struct tplg_ref;
 struct tplg_elem;
 
+typedef enum _snd_pcm_rates {
+	SND_PCM_RATE_UNKNOWN = -1,
+	SND_PCM_RATE_5512 = 0,
+	SND_PCM_RATE_8000,
+	SND_PCM_RATE_11025,
+	SND_PCM_RATE_16000,
+	SND_PCM_RATE_22050,
+	SND_PCM_RATE_32000,
+	SND_PCM_RATE_44100,
+	SND_PCM_RATE_48000,
+	SND_PCM_RATE_64000,
+	SND_PCM_RATE_88200,
+	SND_PCM_RATE_96000,
+	SND_PCM_RATE_176400,
+	SND_PCM_RATE_192000,
+	SND_PCM_RATE_CONTINUOUS = 30,
+	SND_PCM_RATE_KNOT = 31,
+	SND_PCM_RATE_LAST = SND_PCM_RATE_KNOT,
+} snd_pcm_rates_t;
+
 struct snd_tplg {
 
 	/* opaque vendor data */
-- 
2.13.5


From 6c535573008e474c471c100c5bfa5383308020f3 Mon Sep 17 00:00:00 2001
From: Alexander Tsoy <alexander@tsoy.me>
Date: Sun, 18 Jun 2017 23:23:02 +0300
Subject: [PATCH 04/39] conf: USB-Audio: fix dsnoop args for Audiophile USB
 card

Fixes: a9b129955659 ("USB-Audio.conf: fix definition for M-Audio AudioP...")
Signed-off-by: Alexander Tsoy <alexander@tsoy.me>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/conf/cards/USB-Audio.conf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/conf/cards/USB-Audio.conf b/src/conf/cards/USB-Audio.conf
index e365f297..f72ef121 100644
--- a/src/conf/cards/USB-Audio.conf
+++ b/src/conf/cards/USB-Audio.conf
@@ -90,7 +90,7 @@ USB-Audio."Audiophile USB (tm)".pcm.default {
 		type plug
 		slave.pcm {
 			@func concat
-			strings [ "dsnoop:DEVICE=1,CARD=" $CARD ]
+			strings [ "dsnoop:DEV=1,CARD=" $CARD ]
 		}
 	}
 }
-- 
2.13.5


From c09e3b2d5b7fe893b99df3c87577936a3f386d99 Mon Sep 17 00:00:00 2001
From: Alexander Tsoy <alexander@tsoy.me>
Date: Sun, 18 Jun 2017 23:23:03 +0300
Subject: [PATCH 05/39] conf: USB-Audio: allow custom definitions for "default"
 devices

Fixes: a9b129955659 ("USB-Audio.conf: fix definition for M-Audio AudioP...")
Signed-off-by: Alexander Tsoy <alexander@tsoy.me>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/conf/cards/USB-Audio.conf | 77 ++++++++++++++++++++++++-------------------
 1 file changed, 44 insertions(+), 33 deletions(-)

diff --git a/src/conf/cards/USB-Audio.conf b/src/conf/cards/USB-Audio.conf
index f72ef121..cc8c718c 100644
--- a/src/conf/cards/USB-Audio.conf
+++ b/src/conf/cards/USB-Audio.conf
@@ -67,7 +67,7 @@ USB-Audio.pcm.iec958_2_device {
 }
 
 
-# If a device requires non-standard definitions for front, surround40,
+# If a device requires non-standard definitions for front, default, surround40,
 # surround51, surround71 or iec958, they can be defined here.
 
 # M-Audio AudioPhile USB:
@@ -125,13 +125,13 @@ USB-Audio."Audio Advantage MicroII".pcm.iec958 {
 	@args.AES2 { type integer }
 	@args.AES3 { type integer }
 
-    type hooks
-    slave.pcm {
+	type hooks
+	slave.pcm {
 		type hw
 		card $CARD
-    }
+	}
 
-    hooks.0 {
+	hooks.0 {
 		type ctl_elems
 		hook_args [
 			{
@@ -174,41 +174,52 @@ USB-Audio.pcm.front.0 {
 		card $CARD
 		device 0
 	}
-}	
+}
 
 USB-Audio.pcm.default {
 	@args [ CARD ]
 	@args.CARD { type string }
-	type asym
-	playback.pcm {
-		type plug
-		slave.pcm {
-			@func refer
-			name {
-				@func concat
-				strings [
-					"cards.USB-Audio.pcm.default_playback_dmix_"
-					{
-						@func refer
-						name {
-							@func concat
-							strings [
-								"cards.USB-Audio.pcm.use_dmix."
-								{ @func card_name card $CARD }
-							]
+	@func refer
+	name {
+		@func concat
+		strings [
+			"cards.USB-Audio."
+			{ @func card_name card $CARD }
+			".pcm.default:CARD=" $CARD
+		]
+	}
+	default {
+		type asym
+		playback.pcm {
+			type plug
+			slave.pcm {
+				@func refer
+				name {
+					@func concat
+					strings [
+						"cards.USB-Audio.pcm.default_playback_dmix_"
+						{
+							@func refer
+							name {
+								@func concat
+								strings [
+									"cards.USB-Audio.pcm.use_dmix."
+									{ @func card_name card $CARD }
+								]
+							}
+							default yes
 						}
-						default yes
-					}
-					":CARD=" $CARD
-				]
+						":CARD=" $CARD
+					]
+				}
 			}
 		}
-	}
-	capture.pcm {
-		type plug
-		slave.pcm {
-			@func concat
-			strings [ "dsnoop:" $CARD ]
+		capture.pcm {
+			type plug
+			slave.pcm {
+				@func concat
+				strings [ "dsnoop:" $CARD ]
+			}
 		}
 	}
 }
-- 
2.13.5


From f10bc243e42142c568d90f540e806aefb45d8bac Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 23 Jun 2017 22:09:23 +0900
Subject: [PATCH 06/39] pcm: obsolete 'mmap_emulation' parameter of
 snd_pcm_hw_open_fd()

A function, snd_pcm_hw_open_fd(), is just for internal use. This function
has an obsoleted parameter and we can remove it without any compatibility
issue.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_direct.c | 2 +-
 src/pcm/pcm_hw.c     | 6 ++----
 src/pcm/pcm_local.h  | 3 ++-
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 43702601..9fd376d8 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -1523,7 +1523,7 @@ int snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dm
 	int ret;
 	snd_pcm_t *spcm;
 
-	ret = snd_pcm_hw_open_fd(spcmp, client_name, dmix->hw_fd, 0, 0);
+	ret = snd_pcm_hw_open_fd(spcmp, client_name, dmix->hw_fd, 0);
 	if (ret < 0) {
 		SNDERR("unable to open hardware");
 		return ret;
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 30cd5d0f..f0efcde3 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -1410,15 +1410,13 @@ static const snd_pcm_fast_ops_t snd_pcm_hw_fast_ops_timer = {
  * \param pcmp Returns created PCM handle
  * \param name Name of PCM
  * \param fd File descriptor
- * \param mmap_emulation Obsoleted parameter
  * \param sync_ptr_ioctl Boolean flag for sync_ptr ioctl
  * \retval zero on success otherwise a negative error code
  * \warning Using of this function might be dangerous in the sense
  *          of compatibility reasons. The prototype might be freely
  *          changed in future.
  */
-int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
-		       int fd, int mmap_emulation ATTRIBUTE_UNUSED,
+int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd,
 		       int sync_ptr_ioctl)
 {
 	int ver, mode;
@@ -1615,7 +1613,7 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
 		}
 	}
 	snd_ctl_close(ctl);
-	return snd_pcm_hw_open_fd(pcmp, name, fd, 0, sync_ptr_ioctl);
+	return snd_pcm_hw_open_fd(pcmp, name, fd, sync_ptr_ioctl);
        _err:
 	snd_ctl_close(ctl);
 	return ret;
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index e4f65218..7600daa3 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -935,7 +935,8 @@ snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
 
 #define snd_pcm_conf_generic_id(id) _snd_conf_generic_id(id)
 
-int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd, int mmap_emulation, int sync_ptr_ioctl);
+int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd,
+		       int sync_ptr_ioctl);
 int __snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name,
 			     snd_pcm_t *slave, int close_slave);
 
-- 
2.13.5


From 8beab3eb8a4346f823cb42c507122f0abbf9025f Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 23 Jun 2017 22:09:24 +0900
Subject: [PATCH 07/39] pcm: minor code cleanup for ioctl call

When error occurs, return value from ioctl(2) is -1 and error code can
be got thread local variable, errno. It's OK just to check the return
value without any assignment.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index f0efcde3..de6fd1af 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -132,8 +132,7 @@ static int sync_ptr1(snd_pcm_hw_t *hw, unsigned int flags)
 {
 	int err;
 	hw->sync_ptr->flags = flags;
-	err = ioctl((hw)->fd, SNDRV_PCM_IOCTL_SYNC_PTR, (hw)->sync_ptr);
-	if (err < 0) {
+	if (ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, hw->sync_ptr) < 0) {
 		err = -errno;
 		SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
 		return err;
-- 
2.13.5


From 987788dbfe65ae7811868654ba11c05b4582955f Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 20 Jun 2017 12:39:23 +0200
Subject: [PATCH 08/39] pcm: hw: Remove superfluous call of
 snd_pcm_set_appl_ptr()

There is a call of snd_pcm_set_appl_ptr() in snd_pcm_hw_hw_params()
only for the capture direction.  This must be a leftover from the
ancient code.  Although it's harmless for now, it's superfluous and
confusing.  Let's kill it.

Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Tested-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index de6fd1af..a648d12c 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -329,14 +329,7 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 	params->info &= ~0xf0000000;
 	if (pcm->tstamp_type != SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY)
 		params->info |= SND_PCM_INFO_MONOTONIC;
-	err = sync_ptr(hw, 0);
-	if (err < 0)
-		return err;
-	if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
-		snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd,
-				     SNDRV_PCM_MMAP_OFFSET_CONTROL);
-	}
-	return 0;
+	return sync_ptr(hw, 0);
 }
 
 static void snd_pcm_hw_close_timer(snd_pcm_hw_t *hw)
-- 
2.13.5


From 2fbad9bc4ead7ea0c19529c4496080af9b8ab275 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Sun, 25 Jun 2017 13:41:19 +0900
Subject: [PATCH 09/39] pcm: hw: add helper functions to map/unmap
 status/control data for runtime of PCM substream

Handling mapping operation for status/control data includes some
supplemental operations for fallback mode. It's better to have helper
functions for this purpose.

This commit adds the helper functions.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 48 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 34 insertions(+), 14 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index a648d12c..abf4afe0 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <unistd.h>
+#include <stdbool.h>
 #include <signal.h>
 #include <string.h>
 #include <fcntl.h>
@@ -866,7 +867,7 @@ static snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_u
 	return xfern.result;
 }
 
-static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm)
+static int map_status_data(snd_pcm_t *pcm)
 {
 	snd_pcm_hw_t *hw = pcm->private_data;
 	struct snd_pcm_sync_ptr sync_ptr;
@@ -900,7 +901,7 @@ static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm)
 	return 0;
 }
 
-static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm)
+static int map_control_data(snd_pcm_t *pcm)
 {
 	snd_pcm_hw_t *hw = pcm->private_data;
 	void *ptr;
@@ -922,10 +923,28 @@ static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm)
 	return 0;
 }
 
-static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm)
+static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 {
 	snd_pcm_hw_t *hw = pcm->private_data;
 	int err;
+
+	hw->sync_ptr_ioctl = (int)force_fallback;
+
+	err = map_status_data(pcm);
+	if (err < 0)
+		return err;
+
+	err = map_control_data(pcm);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int unmap_status_data(snd_pcm_hw_t *hw)
+{
+	int err;
+
 	if (hw->sync_ptr_ioctl) {
 		free(hw->sync_ptr);
 		hw->sync_ptr = NULL;
@@ -939,10 +958,10 @@ static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm)
 	return 0;
 }
 
-static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm)
+static int unmap_control_data(snd_pcm_hw_t *hw)
 {
-	snd_pcm_hw_t *hw = pcm->private_data;
 	int err;
+
 	if (hw->sync_ptr_ioctl) {
 		free(hw->sync_ptr);
 		hw->sync_ptr = NULL;
@@ -956,6 +975,12 @@ static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm)
 	return 0;
 }
 
+static void unmap_status_and_control_data(snd_pcm_hw_t *hw)
+{
+	unmap_status_data(hw);
+	unmap_control_data(hw);
+}
+
 static int snd_pcm_hw_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 {
 	return 0;
@@ -974,8 +999,9 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm)
 		err = -errno;
 		SYSMSG("close failed (%i)\n", err);
 	}
-	snd_pcm_hw_munmap_status(pcm);
-	snd_pcm_hw_munmap_control(pcm);
+
+	unmap_status_and_control_data(hw);
+
 	free(hw);
 	return err;
 }
@@ -1484,7 +1510,6 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd,
 	hw->device = info.device;
 	hw->subdevice = info.subdevice;
 	hw->fd = fd;
-	hw->sync_ptr_ioctl = sync_ptr_ioctl;
 	/* no restriction */
 	hw->format = SND_PCM_FORMAT_UNKNOWN;
 	hw->rate = 0;
@@ -1508,12 +1533,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd,
 #endif
 	pcm->own_state_check = 1; /* skip the common state check */
 
-	ret = snd_pcm_hw_mmap_status(pcm);
-	if (ret < 0) {
-		snd_pcm_close(pcm);
-		return ret;
-	}
-	ret = snd_pcm_hw_mmap_control(pcm);
+	ret = map_status_and_control_data(pcm, !!sync_ptr_ioctl);
 	if (ret < 0) {
 		snd_pcm_close(pcm);
 		return ret;
-- 
2.13.5


From 812654881a370691fba3ecbd4c175c74c32b9eae Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Sun, 25 Jun 2017 13:41:20 +0900
Subject: [PATCH 10/39] pcm: hw: add an arrangement for initialization of
 appl_ptr/avail_min

Regardless of success/failure mapping of control/status data for runtime of
PCM substream, appl_ptr/avail_min parameters are initialized. In current
implementation, they are initialized in case-dependent, different places.
It's possible to collect them to one place.

This commit unifies relevant code in a place after all of trials for the
mappings are finished.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index abf4afe0..c60a521b 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -867,10 +867,8 @@ static snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_u
 	return xfern.result;
 }
 
-static int map_status_data(snd_pcm_t *pcm)
+static int map_status_data(snd_pcm_hw_t *hw)
 {
-	snd_pcm_hw_t *hw = pcm->private_data;
-	struct snd_pcm_sync_ptr sync_ptr;
 	void *ptr;
 	int err;
 	ptr = MAP_FAILED;
@@ -879,15 +877,6 @@ static int map_status_data(snd_pcm_t *pcm)
 			   PROT_READ, MAP_FILE|MAP_SHARED, 
 			   hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
 	if (ptr == MAP_FAILED || ptr == NULL) {
-		memset(&sync_ptr, 0, sizeof(sync_ptr));
-		sync_ptr.c.control.appl_ptr = 0;
-		sync_ptr.c.control.avail_min = 1;
-		err = ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, &sync_ptr);
-		if (err < 0) {
-			err = -errno;
-			SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
-			return err;
-		}
 		hw->sync_ptr = calloc(1, sizeof(struct snd_pcm_sync_ptr));
 		if (hw->sync_ptr == NULL)
 			return -ENOMEM;
@@ -897,13 +886,12 @@ static int map_status_data(snd_pcm_t *pcm)
 	} else {
 		hw->mmap_status = ptr;
 	}
-	snd_pcm_set_hw_ptr(pcm, &hw->mmap_status->hw_ptr, hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS + offsetof(struct snd_pcm_mmap_status, hw_ptr));
+
 	return 0;
 }
 
-static int map_control_data(snd_pcm_t *pcm)
+static int map_control_data(snd_pcm_hw_t *hw)
 {
-	snd_pcm_hw_t *hw = pcm->private_data;
 	void *ptr;
 	int err;
 	if (hw->sync_ptr == NULL) {
@@ -916,10 +904,8 @@ static int map_control_data(snd_pcm_t *pcm)
 			return err;
 		}
 		hw->mmap_control = ptr;
-	} else {
-		hw->mmap_control->avail_min = 1;
 	}
-	snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
+
 	return 0;
 }
 
@@ -930,14 +916,30 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 
 	hw->sync_ptr_ioctl = (int)force_fallback;
 
-	err = map_status_data(pcm);
+	err = map_status_data(hw);
 	if (err < 0)
 		return err;
 
-	err = map_control_data(pcm);
+	err = map_control_data(hw);
 	if (err < 0)
 		return err;
 
+	/* Initialize the data. */
+	hw->mmap_control->appl_ptr = 0;
+	hw->mmap_control->avail_min = 1;
+	snd_pcm_set_hw_ptr(pcm, &hw->mmap_status->hw_ptr, hw->fd,
+			   SNDRV_PCM_MMAP_OFFSET_STATUS +
+				offsetof(struct snd_pcm_mmap_status, hw_ptr));
+	snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd,
+			     SNDRV_PCM_MMAP_OFFSET_CONTROL);
+	if (hw->sync_ptr_ioctl) {
+		if (ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, hw->sync_ptr) < 0) {
+			err = -errno;
+			SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
+			return err;
+		}
+	}
+
 	return 0;
 }
 
-- 
2.13.5


From cb7503eba15714c40630d9e26bf7e5905ee3da50 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Sun, 25 Jun 2017 13:41:21 +0900
Subject: [PATCH 11/39] pcm: hw: deallocate fallback buffer when trials of
 unmapping finished

In current implementation, deallocation of fallback buffer is done at
several places.

This commit unifies these deallocations in one place.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 43 +++++++++++++++++--------------------------
 1 file changed, 17 insertions(+), 26 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index c60a521b..1d34956c 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -943,44 +943,35 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 	return 0;
 }
 
-static int unmap_status_data(snd_pcm_hw_t *hw)
+static void unmap_status_data(snd_pcm_hw_t *hw)
 {
-	int err;
-
-	if (hw->sync_ptr_ioctl) {
-		free(hw->sync_ptr);
-		hw->sync_ptr = NULL;
-	} else {
-		if (munmap((void*)hw->mmap_status, page_align(sizeof(*hw->mmap_status))) < 0) {
-			err = -errno;
-			SYSMSG("status munmap failed (%i)", err);
-			return err;
-		}
+	if (!hw->sync_ptr) {
+		if (munmap((void *)hw->mmap_status,
+			   page_align(sizeof(*hw->mmap_status))) < 0)
+			SYSMSG("status munmap failed (%u)", errno);
 	}
-	return 0;
 }
 
-static int unmap_control_data(snd_pcm_hw_t *hw)
+static void unmap_control_data(snd_pcm_hw_t *hw)
 {
-	int err;
-
-	if (hw->sync_ptr_ioctl) {
-		free(hw->sync_ptr);
-		hw->sync_ptr = NULL;
-	} else {
-		if (munmap(hw->mmap_control, page_align(sizeof(*hw->mmap_control))) < 0) {
-			err = -errno;
-			SYSMSG("control munmap failed (%i)", err);
-			return err;
-		}
+	if (!hw->sync_ptr) {
+		if (munmap((void *)hw->mmap_control,
+			   page_align(sizeof(*hw->mmap_control))) < 0)
+			SYSMSG("control munmap failed (%u)", errno);
 	}
-	return 0;
 }
 
 static void unmap_status_and_control_data(snd_pcm_hw_t *hw)
 {
 	unmap_status_data(hw);
 	unmap_control_data(hw);
+
+	if (hw->sync_ptr)
+		free(hw->sync_ptr);
+
+	hw->mmap_status = NULL;
+	hw->mmap_control = NULL;
+	hw->sync_ptr = NULL;
 }
 
 static int snd_pcm_hw_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-- 
2.13.5


From afadf61e44706880c32a854648645409c82dc0a2 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Sun, 25 Jun 2017 13:41:22 +0900
Subject: [PATCH 12/39] pcm: hw: allocate fallback buffer in advance of trials
 of mapping

When allowing failure of map operation for both of status/control data
for runtime of PCM substream, applications need to use fallback buffer
for an alternative ioctl. However, in current implementation, status
mapping is dominant to the allocation.

This commit moves code for the allocation outside of the mapping
operation for status data.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 1d34956c..a3d1f137 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -867,21 +867,18 @@ static snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_u
 	return xfern.result;
 }
 
-static int map_status_data(snd_pcm_hw_t *hw)
+static int map_status_data(snd_pcm_hw_t *hw, struct snd_pcm_sync_ptr *sync_ptr)
 {
 	void *ptr;
-	int err;
+
 	ptr = MAP_FAILED;
 	if (hw->sync_ptr_ioctl == 0)
 		ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_status)),
 			   PROT_READ, MAP_FILE|MAP_SHARED, 
 			   hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
 	if (ptr == MAP_FAILED || ptr == NULL) {
-		hw->sync_ptr = calloc(1, sizeof(struct snd_pcm_sync_ptr));
-		if (hw->sync_ptr == NULL)
-			return -ENOMEM;
-		hw->mmap_status = &hw->sync_ptr->s.status;
-		hw->mmap_control = &hw->sync_ptr->c.control;
+		hw->mmap_status = &sync_ptr->s.status;
+		hw->mmap_control = &sync_ptr->c.control;
 		hw->sync_ptr_ioctl = 1;
 	} else {
 		hw->mmap_status = ptr;
@@ -894,7 +891,7 @@ static int map_control_data(snd_pcm_hw_t *hw)
 {
 	void *ptr;
 	int err;
-	if (hw->sync_ptr == NULL) {
+	if (hw->sync_ptr_ioctl == 0) {
 		ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_control)),
 			   PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, 
 			   hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
@@ -912,11 +909,18 @@ static int map_control_data(snd_pcm_hw_t *hw)
 static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 {
 	snd_pcm_hw_t *hw = pcm->private_data;
+	struct snd_pcm_sync_ptr *sync_ptr;
 	int err;
 
+	/* Preparation for fallback to failure of mmap(2). */
+	sync_ptr = malloc(sizeof(*sync_ptr));
+	if (sync_ptr == NULL)
+		return -ENOMEM;
+	memset(sync_ptr, 0, sizeof(*sync_ptr));
+
 	hw->sync_ptr_ioctl = (int)force_fallback;
 
-	err = map_status_data(hw);
+	err = map_status_data(hw, sync_ptr);
 	if (err < 0)
 		return err;
 
@@ -924,6 +928,14 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 	if (err < 0)
 		return err;
 
+	/* Any fallback mode needs to keep the buffer. */
+	if (hw->sync_ptr_ioctl == 0) {
+		hw->sync_ptr = sync_ptr;
+	} else {
+		free(sync_ptr);
+		hw->sync_ptr = NULL;
+	}
+
 	/* Initialize the data. */
 	hw->mmap_control->appl_ptr = 0;
 	hw->mmap_control->avail_min = 1;
-- 
2.13.5


From 9c9e3d0822777b36d7c8cae21550b180d108a160 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Sun, 25 Jun 2017 13:41:23 +0900
Subject: [PATCH 13/39] pcm: hw: maintain fallback mode for status data mapping

In current implementation, results to map status/control data are not
maintained separately. It's handled as a fatal error that mapping of status
data is successful and mapping of control data is failed. However, it's
possible to handle this case by utilizing fallback buffer.

This commit adds a member into a local structure to maintain fallback mode
just for the mapping of status data as a preparation of later commit, in
which mapping results are maintained separately for each of status/control
data.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 78 ++++++++++++++++++++++++++++++++------------------------
 1 file changed, 44 insertions(+), 34 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index a3d1f137..78857941 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -91,10 +91,12 @@ typedef struct {
 	int version;
 	int fd;
 	int card, device, subdevice;
-	int sync_ptr_ioctl;
+
 	volatile struct snd_pcm_mmap_status * mmap_status;
 	struct snd_pcm_mmap_control *mmap_control;
+	bool mmap_status_fallbacked;
 	struct snd_pcm_sync_ptr *sync_ptr;
+
 	int period_event;
 	snd_timer_t *period_timer;
 	struct pollfd period_timer_pfd;
@@ -867,42 +869,53 @@ static snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_u
 	return xfern.result;
 }
 
-static int map_status_data(snd_pcm_hw_t *hw, struct snd_pcm_sync_ptr *sync_ptr)
+static bool map_status_data(snd_pcm_hw_t *hw, struct snd_pcm_sync_ptr *sync_ptr,
+			    bool force_fallback)
 {
-	void *ptr;
+	struct snd_pcm_mmap_status *mmap_status;
+	bool fallbacked;
+
+	mmap_status = MAP_FAILED;
+	if (!force_fallback) {
+		mmap_status = mmap(NULL, page_align(sizeof(*mmap_status)),
+				   PROT_READ, MAP_FILE|MAP_SHARED,
+				   hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
+	}
 
-	ptr = MAP_FAILED;
-	if (hw->sync_ptr_ioctl == 0)
-		ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_status)),
-			   PROT_READ, MAP_FILE|MAP_SHARED, 
-			   hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
-	if (ptr == MAP_FAILED || ptr == NULL) {
-		hw->mmap_status = &sync_ptr->s.status;
-		hw->mmap_control = &sync_ptr->c.control;
-		hw->sync_ptr_ioctl = 1;
+	if (mmap_status == MAP_FAILED || mmap_status == NULL) {
+		mmap_status = &sync_ptr->s.status;
+		fallbacked = true;
 	} else {
-		hw->mmap_status = ptr;
+		fallbacked = false;
 	}
 
-	return 0;
+	hw->mmap_status = mmap_status;
+
+	return fallbacked;
 }
 
-static int map_control_data(snd_pcm_hw_t *hw)
+static bool map_control_data(snd_pcm_hw_t *hw,
+			     struct snd_pcm_sync_ptr *sync_ptr,
+			     bool force_fallback)
 {
-	void *ptr;
+	struct snd_pcm_mmap_control *mmap_control;
 	int err;
-	if (hw->sync_ptr_ioctl == 0) {
-		ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_control)),
-			   PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, 
-			   hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
-		if (ptr == MAP_FAILED || ptr == NULL) {
+
+	if (!force_fallback) {
+		mmap_control = mmap(NULL, page_align(sizeof(*mmap_control)),
+				    PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
+				    hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
+		if (mmap_control == MAP_FAILED || mmap_control == NULL) {
 			err = -errno;
 			SYSMSG("control mmap failed (%i)", err);
 			return err;
 		}
-		hw->mmap_control = ptr;
+	} else {
+		mmap_control = &sync_ptr->c.control;
 	}
 
+	hw->mmap_control = mmap_control;
+
 	return 0;
 }
 
@@ -918,18 +931,14 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 		return -ENOMEM;
 	memset(sync_ptr, 0, sizeof(*sync_ptr));
 
-	hw->sync_ptr_ioctl = (int)force_fallback;
-
-	err = map_status_data(hw, sync_ptr);
-	if (err < 0)
-		return err;
-
-	err = map_control_data(hw);
+	hw->mmap_status_fallbacked =
+			map_status_data(hw, sync_ptr, force_fallback);
+	err = map_control_data(hw, sync_ptr, hw->mmap_status_fallbacked);
 	if (err < 0)
 		return err;
 
 	/* Any fallback mode needs to keep the buffer. */
-	if (hw->sync_ptr_ioctl == 0) {
+	if (hw->mmap_status_fallbacked == 0) {
 		hw->sync_ptr = sync_ptr;
 	} else {
 		free(sync_ptr);
@@ -944,7 +953,7 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 				offsetof(struct snd_pcm_mmap_status, hw_ptr));
 	snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd,
 			     SNDRV_PCM_MMAP_OFFSET_CONTROL);
-	if (hw->sync_ptr_ioctl) {
+	if (hw->mmap_status_fallbacked) {
 		if (ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, hw->sync_ptr) < 0) {
 			err = -errno;
 			SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
@@ -957,7 +966,7 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 
 static void unmap_status_data(snd_pcm_hw_t *hw)
 {
-	if (!hw->sync_ptr) {
+	if (!hw->mmap_status_fallbacked) {
 		if (munmap((void *)hw->mmap_status,
 			   page_align(sizeof(*hw->mmap_status))) < 0)
 			SYSMSG("status munmap failed (%u)", errno);
@@ -966,7 +975,7 @@ static void unmap_status_data(snd_pcm_hw_t *hw)
 
 static void unmap_control_data(snd_pcm_hw_t *hw)
 {
-	if (!hw->sync_ptr) {
+	if (!hw->mmap_status_fallbacked) {
 		if (munmap((void *)hw->mmap_control,
 			   page_align(sizeof(*hw->mmap_control))) < 0)
 			SYSMSG("control munmap failed (%u)", errno);
@@ -978,11 +987,12 @@ static void unmap_status_and_control_data(snd_pcm_hw_t *hw)
 	unmap_status_data(hw);
 	unmap_control_data(hw);
 
-	if (hw->sync_ptr)
+	if (hw->mmap_status_fallbacked)
 		free(hw->sync_ptr);
 
 	hw->mmap_status = NULL;
 	hw->mmap_control = NULL;
+	hw->mmap_status_fallbacked = false;
 	hw->sync_ptr = NULL;
 }
 
-- 
2.13.5


From 48bf3d3e964fbd34afd430632e8f2f5ca395d24c Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Sun, 25 Jun 2017 13:41:24 +0900
Subject: [PATCH 14/39] pcm: hw: maintain fallback mode for control data
 mapping independently

Currently, failures of status/control data mapping are handled dependently.
However, it's not sure that one of the operations is failed when another
is failed.

This commit adds a member into private data structure to maintain fallback
mode for control data mapping, independently of status data mapping. As a
result, we have four cases to handle status/control data:

1. both of status/control data are mapped.
Nothing changed. A structure with alias of 'snd_pcm_hw_t' already has two
members to point the mapped area and in application runtime they're used
to refer/set status/control data. No need to call ioctl(2) with
SNDRV_PCM_IOCTL_SYNC_PTR to issue/query the data.

2. both of status/control data are unmapped.
The two members point to allocated memory for fallback buffer. In
application runtime, the buffer is given as an argument for ioctl(2) with
SNDRV_PCM_IOCTL_SYNC_PTR to issue/query the data.

3. status data is mapped only.
One of the two members is used to point the mapped area. Another points to
allocated memory for fallback buffer. In application runtime, the buffer
is used as an argument to execute ioctl(2) with SNDRV_PCM_IOCTL_SYNC_PTR
for the latter data, but the former data is already synchronized.

4. control data is mapped only.
The same as the above.

In design of ALSA PCM interface, userspace applications are not expected
to map the status data as writable. On the other hand, expected to map
the control data as writable. In a focus on the differences, we could
achieve to reduce calls of the ioctl(2) in a case that one of the
status/control data is successfully mapped and another is failed (case 3
and 4). Especially, in current alsa-lib implementation, application
runtime queries state of runtime of PCM substream so often.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 78857941..5573fce2 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -95,6 +95,7 @@ typedef struct {
 	volatile struct snd_pcm_mmap_status * mmap_status;
 	struct snd_pcm_mmap_control *mmap_control;
 	bool mmap_status_fallbacked;
+	bool mmap_control_fallbacked;
 	struct snd_pcm_sync_ptr *sync_ptr;
 
 	int period_event;
@@ -143,9 +144,11 @@ static int sync_ptr1(snd_pcm_hw_t *hw, unsigned int flags)
 	return 0;
 }
 
-static inline int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
+static int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
 {
-	return hw->sync_ptr ? sync_ptr1(hw, flags) : 0;
+	if (hw->mmap_status_fallbacked || hw->mmap_control_fallbacked)
+		return sync_ptr1(hw, flags);
+	return 0;
 }
 
 static int snd_pcm_hw_clear_timer_queue(snd_pcm_hw_t *hw)
@@ -899,24 +902,24 @@ static bool map_control_data(snd_pcm_hw_t *hw,
 			     bool force_fallback)
 {
 	struct snd_pcm_mmap_control *mmap_control;
-	int err;
+	bool fallbacked;
 
 	if (!force_fallback) {
 		mmap_control = mmap(NULL, page_align(sizeof(*mmap_control)),
 				    PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
 				    hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
-		if (mmap_control == MAP_FAILED || mmap_control == NULL) {
-			err = -errno;
-			SYSMSG("control mmap failed (%i)", err);
-			return err;
-		}
-	} else {
+	}
+
+	if (mmap_control == MAP_FAILED || mmap_control == NULL) {
 		mmap_control = &sync_ptr->c.control;
+		fallbacked = true;
+	} else {
+		fallbacked = false;
 	}
 
 	hw->mmap_control = mmap_control;
 
-	return 0;
+	return fallbacked;
 }
 
 static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
@@ -933,12 +936,11 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 
 	hw->mmap_status_fallbacked =
 			map_status_data(hw, sync_ptr, force_fallback);
-	err = map_control_data(hw, sync_ptr, hw->mmap_status_fallbacked);
-	if (err < 0)
-		return err;
+	hw->mmap_control_fallbacked =
+			map_control_data(hw, sync_ptr, force_fallback);
 
 	/* Any fallback mode needs to keep the buffer. */
-	if (hw->mmap_status_fallbacked == 0) {
+	if (hw->mmap_status_fallbacked || hw->mmap_control_fallbacked) {
 		hw->sync_ptr = sync_ptr;
 	} else {
 		free(sync_ptr);
@@ -953,7 +955,7 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 				offsetof(struct snd_pcm_mmap_status, hw_ptr));
 	snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd,
 			     SNDRV_PCM_MMAP_OFFSET_CONTROL);
-	if (hw->mmap_status_fallbacked) {
+	if (hw->mmap_control_fallbacked) {
 		if (ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, hw->sync_ptr) < 0) {
 			err = -errno;
 			SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
@@ -975,7 +977,7 @@ static void unmap_status_data(snd_pcm_hw_t *hw)
 
 static void unmap_control_data(snd_pcm_hw_t *hw)
 {
-	if (!hw->mmap_status_fallbacked) {
+	if (!hw->mmap_control_fallbacked) {
 		if (munmap((void *)hw->mmap_control,
 			   page_align(sizeof(*hw->mmap_control))) < 0)
 			SYSMSG("control munmap failed (%u)", errno);
@@ -987,12 +989,13 @@ static void unmap_status_and_control_data(snd_pcm_hw_t *hw)
 	unmap_status_data(hw);
 	unmap_control_data(hw);
 
-	if (hw->mmap_status_fallbacked)
+	if (hw->mmap_status_fallbacked || hw->mmap_control_fallbacked)
 		free(hw->sync_ptr);
 
 	hw->mmap_status = NULL;
 	hw->mmap_control = NULL;
 	hw->mmap_status_fallbacked = false;
+	hw->mmap_control_fallbacked = false;
 	hw->sync_ptr = NULL;
 }
 
-- 
2.13.5


From 8ef3805f1b80a6c6059e0d9efd404fe32697db15 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 20 Jun 2017 14:21:20 +0200
Subject: [PATCH 15/39] pcm: hw: Call USER_PVERSION ioctl at open

Up from the new PCM protocol 2.0.14, user-space can inform the
protocol version it supports to kernel, so that the kernel may switch
its behavior depending on it.  Add this ioctl call in the PCM hw
plugin at opening.

The patch contains also the addition of SNDRV_PCM_INFO_SYNC_APPLPTR
carried from the upstream kernel commit 42f945970af9 ("ALSA: pcm: Add
the explicit appl_ptr sync support"), as well as the trivial change
(an addition of comma) to sync with the kernel asound.h.

Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Tested-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/asound.h |  6 ++++--
 src/pcm/pcm_hw.c       | 10 ++++++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/sound/asound.h b/include/sound/asound.h
index fb8d7d7e..1949923a 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -111,7 +111,7 @@ enum {
 	SNDRV_HWDEP_IFACE_FW_FIREFACE,	/* RME Fireface series */
 
 	/* Don't forget to change the following: */
-	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE,
+	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE
 };
 
 struct snd_hwdep_info {
@@ -152,7 +152,7 @@ struct snd_hwdep_dsp_image {
  *                                                                           *
  *****************************************************************************/
 
-#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 13)
+#define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 14)
 
 typedef unsigned long snd_pcm_uframes_t;
 typedef signed long snd_pcm_sframes_t;
@@ -268,6 +268,7 @@ typedef int __bitwise snd_pcm_subformat_t;
 #define SNDRV_PCM_INFO_MMAP_VALID	0x00000002	/* period data are valid during transfer */
 #define SNDRV_PCM_INFO_DOUBLE		0x00000004	/* Double buffering needed for PCM start/stop */
 #define SNDRV_PCM_INFO_BATCH		0x00000010	/* double buffering */
+#define SNDRV_PCM_INFO_SYNC_APPLPTR	0x00000020	/* need the explicit sync of appl_ptr update */
 #define SNDRV_PCM_INFO_INTERLEAVED	0x00000100	/* channels are interleaved */
 #define SNDRV_PCM_INFO_NONINTERLEAVED	0x00000200	/* channels are not interleaved */
 #define SNDRV_PCM_INFO_COMPLEX		0x00000400	/* complex frame organization (mmap only) */
@@ -563,6 +564,7 @@ enum {
 #define SNDRV_PCM_IOCTL_INFO		_IOR('A', 0x01, struct snd_pcm_info)
 #define SNDRV_PCM_IOCTL_TSTAMP		_IOW('A', 0x02, int)
 #define SNDRV_PCM_IOCTL_TTSTAMP		_IOW('A', 0x03, int)
+#define SNDRV_PCM_IOCTL_USER_PVERSION	_IOW('A', 0x04, int)
 #define SNDRV_PCM_IOCTL_HW_REFINE	_IOWR('A', 0x10, struct snd_pcm_hw_params)
 #define SNDRV_PCM_IOCTL_HW_PARAMS	_IOWR('A', 0x11, struct snd_pcm_hw_params)
 #define SNDRV_PCM_IOCTL_HW_FREE		_IO('A', 0x12)
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 5573fce2..64188b22 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -1494,6 +1494,16 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd,
 	if (SNDRV_PROTOCOL_INCOMPATIBLE(ver, SNDRV_PCM_VERSION_MAX))
 		return -SND_ERROR_INCOMPATIBLE_VERSION;
 
+	if (SNDRV_PROTOCOL_VERSION(2, 0, 14) <= ver) {
+		/* inform the protocol version we're supporting */
+		unsigned int user_ver = SNDRV_PCM_VERSION;
+		if (ioctl(fd, SNDRV_PCM_IOCTL_USER_PVERSION, &user_ver) < 0) {
+			ret = -errno;
+			SNDMSG("USER_PVERSION failed\n");
+			return ret;
+		}
+	}
+
 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
 	if (SNDRV_PROTOCOL_VERSION(2, 0, 9) <= ver) {
 		struct timespec timespec;
-- 
2.13.5


From ec16d21f86abbc23a56abeed0419a5a863ee5400 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 30 Jun 2017 19:50:00 +0900
Subject: [PATCH 16/39] pcm: hw: fix to initialize function local variable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit is to fix below warning.

pcm_hw.c: In function ‘snd1_pcm_hw_open_fd’:
pcm_hw.c:955:33: warning: ‘mmap_control’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  if (mmap_control == MAP_FAILED || mmap_control == NULL) {
                                 ^
pcm_hw.c:946:31: note: ‘mmap_control’ was declared here
  struct snd_pcm_mmap_control *mmap_control;
                               ^~~~~~~~~~~~

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 64188b22..e0931577 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -904,6 +904,7 @@ static bool map_control_data(snd_pcm_hw_t *hw,
 	struct snd_pcm_mmap_control *mmap_control;
 	bool fallbacked;
 
+	mmap_control = MAP_FAILED;
 	if (!force_fallback) {
 		mmap_control = mmap(NULL, page_align(sizeof(*mmap_control)),
 				    PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
-- 
2.13.5


From 84beecc71ec508feb32bdf3fd1655dc7d0badfac Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Fri, 30 Jun 2017 14:14:55 +0100
Subject: [PATCH 17/39] topology: Add support for new widget types

Add topology support for new DSP widget types. This allows the new
widgets to be added to the driver and firmware DAPM graphs.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/sound/asoc.h | 10 +++++++++-
 src/topology/dapm.c  |  8 ++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/include/sound/asoc.h b/include/sound/asoc.h
index 082c5429..0f5d9f9a 100644
--- a/include/sound/asoc.h
+++ b/include/sound/asoc.h
@@ -70,7 +70,15 @@
 #define SND_SOC_TPLG_DAPM_DAI_IN	13
 #define SND_SOC_TPLG_DAPM_DAI_OUT	14
 #define SND_SOC_TPLG_DAPM_DAI_LINK	15
-#define SND_SOC_TPLG_DAPM_LAST		SND_SOC_TPLG_DAPM_DAI_LINK
+#define SND_SOC_TPLG_DAPM_BUFFER	16
+#define SND_SOC_TPLG_DAPM_SCHEDULER	17
+#define SND_SOC_TPLG_DAPM_EFFECT	18
+#define SND_SOC_TPLG_DAPM_SIGGEN	19
+#define SND_SOC_TPLG_DAPM_SRC		20
+#define SND_SOC_TPLG_DAPM_ASRC		21
+#define SND_SOC_TPLG_DAPM_ENCODER	22
+#define SND_SOC_TPLG_DAPM_DECODER	23
+#define SND_SOC_TPLG_DAPM_LAST		SND_SOC_TPLG_DAPM_DECODER
 
 /* Header magic number and string sizes */
 #define SND_SOC_TPLG_MAGIC		0x41536F43 /* ASoC */
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
index 6af750b9..66892a66 100644
--- a/src/topology/dapm.c
+++ b/src/topology/dapm.c
@@ -38,6 +38,14 @@ static const struct map_elem widget_map[] = {
 	{"dai_in", SND_SOC_TPLG_DAPM_DAI_IN},
 	{"dai_out", SND_SOC_TPLG_DAPM_DAI_OUT},
 	{"dai_link", SND_SOC_TPLG_DAPM_DAI_LINK},
+	{"buffer", SND_SOC_TPLG_DAPM_BUFFER},
+	{"scheduler", SND_SOC_TPLG_DAPM_SCHEDULER},
+	{"effect", SND_SOC_TPLG_DAPM_EFFECT},
+	{"siggen", SND_SOC_TPLG_DAPM_SIGGEN},
+	{"src", SND_SOC_TPLG_DAPM_SRC},
+	{"asrc", SND_SOC_TPLG_DAPM_ASRC},
+	{"encoder", SND_SOC_TPLG_DAPM_ENCODER},
+	{"decoder", SND_SOC_TPLG_DAPM_DECODER},
 };
 
 static int lookup_widget(const char *w)
-- 
2.13.5


From 5c9582b8b428f3dbacb9e2fc32924f55c38efe8d Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Fri, 30 Jun 2017 14:14:56 +0100
Subject: [PATCH 18/39] topology: improve verbose output for block output.

Show index and full DAPm route in verbose output.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/topology/builder.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/topology/builder.c b/src/topology/builder.c
index ca5cbe1a..997df0c7 100644
--- a/src/topology/builder.c
+++ b/src/topology/builder.c
@@ -67,9 +67,10 @@ static int write_block_header(snd_tplg_t *tplg, unsigned int type,
 		exit(-EINVAL);
 	}
 
-	verbose(tplg, " header type %d size 0x%lx/%ld vendor %d "
-		"version %d\n", type, (long unsigned int)payload_size,
-		(long int)payload_size, vendor_type, version);
+	verbose(tplg, " header index %d type %d count %d size 0x%lx/%ld vendor %d "
+		"version %d\n", index, type, count,
+		(long unsigned int)payload_size, (long int)payload_size,
+		vendor_type, version);
 
 	tplg->next_hdr_pos += hdr.payload_size + sizeof(hdr);
 
@@ -119,8 +120,10 @@ static int write_elem_block(snd_tplg_t *tplg,
 					verbose(tplg, " %s '%s': write %d bytes\n",
 						obj_name, elem->id, elem->size);
 				else
-					verbose(tplg, " %s '%s': write %d bytes\n",
-						obj_name, elem->route->source, elem->size);
+					verbose(tplg, " %s '%s -> %s -> %s': write %d bytes\n",
+						obj_name, elem->route->source,
+						elem->route->control,
+						elem->route->sink, elem->size);
 
 				wsize = write(tplg->out_fd, elem->obj, elem->size);
 				if (wsize < 0) {
-- 
2.13.5


From 4396c83a4d572c32e88a6eb9d3f48240bf89da8e Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 30 Jun 2017 20:00:26 +0900
Subject: [PATCH 19/39] pcm: hw: minor refactoring for initialization of
 control data

At failure of control data mapping, alsa-lib goes to fallback mode. In
this mode, a buffer is kept in user space and executes ioctl(2) with
SNDRV_PCM_IOCTL_SYNC_PTR for the buffer to synchronize the control data.

In current implementation, no helper function is used for initialize
the control data. This commit use an proper helper function instead of
a direct call of ioctl(2).

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index e0931577..f03bc589 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -957,11 +957,9 @@ static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
 	snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd,
 			     SNDRV_PCM_MMAP_OFFSET_CONTROL);
 	if (hw->mmap_control_fallbacked) {
-		if (ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, hw->sync_ptr) < 0) {
-			err = -errno;
-			SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
+		err = sync_ptr1(hw, 0);
+		if (err < 0)
 			return err;
-		}
 	}
 
 	return 0;
-- 
2.13.5


From ce0905c3ca50e143cadf7b0b70f3049ef8024dab Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 30 Jun 2017 20:37:24 +0900
Subject: [PATCH 20/39] pcm: hw: add a helper function to query status/control
 data

When executing ioctl(2) with some commands, applications can request
ALSA PCM core to change appl_ptr in kernel space. Below is a list of
such operations:
 - SNDRV_PCM_IOCTL_PREPARE
 - SNDRV_PCM_IOCTL_RESET
 - SNDRV_PCM_IOCTL_REWIND
 - SNDRV_PCM_IOCTL_FORWARD
 - SNDRV_PCM_IOCTL_WRITEI_FRAMES
 - SNDRV_PCM_IOCTL_WRITEN_FRAMES
 - SNDRV_PCM_IOCTL_READI_FRAMES
 - SNDRV_PCM_IOCTL_READN_FRAMES

After these operations, the value of appl_ptr should be synchronized
between kernel/user spaces.

This commit adds a helper function to query status and control data
without issuing the control data just in fallback from failure of control
mapping.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 46 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index f03bc589..9963523c 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -151,6 +151,20 @@ static int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
 	return 0;
 }
 
+static int query_status_and_control_data(snd_pcm_hw_t *hw)
+{
+	if (!hw->mmap_control_fallbacked)
+		return 0;
+
+	/*
+	 * Query both of control/status data to avoid unexpected change of
+	 * control data in kernel space.
+	 */
+	return sync_ptr1(hw,
+			 SNDRV_PCM_SYNC_PTR_APPL |
+			 SNDRV_PCM_SYNC_PTR_AVAIL_MIN);
+}
+
 static int snd_pcm_hw_clear_timer_queue(snd_pcm_hw_t *hw)
 {
 	if (hw->period_timer_need_poll) {
@@ -601,7 +615,7 @@ static int snd_pcm_hw_prepare(snd_pcm_t *pcm)
 		SYSMSG("SNDRV_PCM_IOCTL_PREPARE failed (%i)", err);
 		return err;
 	}
-	return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
+	return query_status_and_control_data(hw);
 }
 
 static int snd_pcm_hw_reset(snd_pcm_t *pcm)
@@ -613,7 +627,7 @@ static int snd_pcm_hw_reset(snd_pcm_t *pcm)
 		SYSMSG("SNDRV_PCM_IOCTL_RESET failed (%i)", err);
 		return err;
 	}
-	return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
+	return query_status_and_control_data(hw);
 }
 
 static int snd_pcm_hw_start(snd_pcm_t *pcm)
@@ -688,7 +702,7 @@ static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t fra
 		SYSMSG("SNDRV_PCM_IOCTL_REWIND failed (%i)", err);
 		return err;
 	}
-	err = sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
+	err = query_status_and_control_data(hw);
 	if (err < 0)
 		return err;
 	return frames;
@@ -709,7 +723,7 @@ static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t fr
 			SYSMSG("SNDRV_PCM_IOCTL_FORWARD failed (%i)", err);
 			return err;
 		}
-		err = sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
+		err = query_status_and_control_data(hw);
 		if (err < 0)
 			return err;
 		return frames;
@@ -805,8 +819,10 @@ static snd_pcm_sframes_t snd_pcm_hw_writei(snd_pcm_t *pcm, const void *buffer, s
 	xferi.buf = (char*) buffer;
 	xferi.frames = size;
 	xferi.result = 0; /* make valgrind happy */
-	err = ioctl(fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &xferi);
-	err = err >= 0 ? sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL) : -errno;
+	if (ioctl(fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &xferi) < 0)
+		err = -errno;
+	else
+		err = query_status_and_control_data(hw);
 #ifdef DEBUG_RW
 	fprintf(stderr, "hw_writei: frames = %li, xferi.result = %li, err = %i\n", size, xferi.result, err);
 #endif
@@ -824,8 +840,10 @@ static snd_pcm_sframes_t snd_pcm_hw_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_
 	memset(&xfern, 0, sizeof(xfern)); /* make valgrind happy */
 	xfern.bufs = bufs;
 	xfern.frames = size;
-	err = ioctl(fd, SNDRV_PCM_IOCTL_WRITEN_FRAMES, &xfern);
-	err = err >= 0 ? sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL) : -errno;
+	if (ioctl(fd, SNDRV_PCM_IOCTL_WRITEN_FRAMES, &xfern) < 0)
+		err = -errno;
+	else
+		err = query_status_and_control_data(hw);
 #ifdef DEBUG_RW
 	fprintf(stderr, "hw_writen: frames = %li, result = %li, err = %i\n", size, xfern.result, err);
 #endif
@@ -843,8 +861,10 @@ static snd_pcm_sframes_t snd_pcm_hw_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_
 	xferi.buf = buffer;
 	xferi.frames = size;
 	xferi.result = 0; /* make valgrind happy */
-	err = ioctl(fd, SNDRV_PCM_IOCTL_READI_FRAMES, &xferi);
-	err = err >= 0 ? sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL) : -errno;
+	if (ioctl(fd, SNDRV_PCM_IOCTL_READI_FRAMES, &xferi) < 0)
+		err = -errno;
+	else
+		err = query_status_and_control_data(hw);
 #ifdef DEBUG_RW
 	fprintf(stderr, "hw_readi: frames = %li, result = %li, err = %i\n", size, xferi.result, err);
 #endif
@@ -862,8 +882,10 @@ static snd_pcm_sframes_t snd_pcm_hw_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_u
 	memset(&xfern, 0, sizeof(xfern)); /* make valgrind happy */
 	xfern.bufs = bufs;
 	xfern.frames = size;
-	err = ioctl(fd, SNDRV_PCM_IOCTL_READN_FRAMES, &xfern);
-	err = err >= 0 ? sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL) : -errno;
+	if (ioctl(fd, SNDRV_PCM_IOCTL_READN_FRAMES, &xfern) < 0)
+		err = -errno;
+	else
+		err = query_status_and_control_data(hw);
 #ifdef DEBUG_RW
 	fprintf(stderr, "hw_readn: frames = %li, result = %li, err = %i\n", size, xfern.result, err);
 #endif
-- 
2.13.5


From 78f3165a9e82d6f5e83e0e7075cdd96b49f9f401 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 30 Jun 2017 20:37:25 +0900
Subject: [PATCH 21/39] pcm: hw: add a helper function just to query status
 data

When mapping status data successfully, mapped page includes status data
for applications. In this case, applications have no need to call ioctl(2)
with SNDRV_PCM_IOCTL_SYNC_PTR. However, in current implementation, when
map of control data is unavailable, applications execute the ioctl(2).
This is inconvenient for some cases that applications require to query
status only.

This commit adds a helper function to query status data without issuing
the control in fallback mode from failure of status mmap.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 9963523c..38d975af 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -165,6 +165,20 @@ static int query_status_and_control_data(snd_pcm_hw_t *hw)
 			 SNDRV_PCM_SYNC_PTR_AVAIL_MIN);
 }
 
+static int query_status_data(snd_pcm_hw_t *hw)
+{
+	if (!hw->mmap_status_fallbacked)
+		return 0;
+
+	/*
+	 * Query both of control/status data to avoid unexpected change of
+	 * control data in kernel space.
+	 */
+	return sync_ptr1(hw,
+			 SNDRV_PCM_SYNC_PTR_APPL |
+			 SNDRV_PCM_SYNC_PTR_AVAIL_MIN);
+}
+
 static int snd_pcm_hw_clear_timer_queue(snd_pcm_hw_t *hw)
 {
 	if (hw->period_timer_need_poll) {
@@ -349,7 +363,7 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 	params->info &= ~0xf0000000;
 	if (pcm->tstamp_type != SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY)
 		params->info |= SND_PCM_INFO_MONOTONIC;
-	return sync_ptr(hw, 0);
+	return query_status_data(hw);
 }
 
 static void snd_pcm_hw_close_timer(snd_pcm_hw_t *hw)
@@ -556,7 +570,7 @@ static int snd_pcm_hw_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
 static snd_pcm_state_t snd_pcm_hw_state(snd_pcm_t *pcm)
 {
 	snd_pcm_hw_t *hw = pcm->private_data;
-	int err = sync_ptr(hw, 0);
+	int err = query_status_data(hw);
 	if (err < 0)
 		return err;
 	return (snd_pcm_state_t) hw->mmap_status->state;
@@ -1064,7 +1078,7 @@ static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
 	snd_pcm_hw_t *hw = pcm->private_data;
 	snd_pcm_uframes_t avail;
 
-	sync_ptr(hw, 0);
+	query_status_data(hw);
 	avail = snd_pcm_mmap_avail(pcm);
 	switch (FAST_PCM_STATE(hw)) {
 	case SNDRV_PCM_STATE_RUNNING:
-- 
2.13.5


From 8a3df40bce2ae3fd9e9dfdf979b2c672754e0b93 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 30 Jun 2017 20:37:26 +0900
Subject: [PATCH 22/39] pcm: hw: add a helper function to request hwsync
 without side-effects

SNDRV_PCM_IOCTL_SYNC_PTR command for ioctl(2) with
SNDRV_PCM_SYNC_PTR_HWSYNC flag has an effect to update hw_ptr.
This is an alternative of SNDRV_PCM_IOCTL_HWSYNC but caller can get
current status simultaneously.

This commit adds a helper function just to issue hwsync. To avoid
side-effect to change appl_ptr and avail_min, this commit uses
SNDRV_PCM_SYNC_PTR_APPL and SNDRV_PCM_SYNC_PTR_AVAIL_MIN flags.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 38d975af..8455baaf 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -151,6 +151,21 @@ static int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
 	return 0;
 }
 
+static int request_hwsync(snd_pcm_hw_t *hw)
+{
+	if (!hw->mmap_status_fallbacked)
+		return 0;
+
+	/*
+	 * Query both of control/status data to avoid unexpected change of
+	 * control data in kernel space.
+	 */
+	return sync_ptr1(hw,
+			 SNDRV_PCM_SYNC_PTR_HWSYNC |
+			 SNDRV_PCM_SYNC_PTR_APPL |
+			 SNDRV_PCM_SYNC_PTR_AVAIL_MIN);
+}
+
 static int query_status_and_control_data(snd_pcm_hw_t *hw)
 {
 	if (!hw->mmap_control_fallbacked)
@@ -593,8 +608,8 @@ static int snd_pcm_hw_hwsync(snd_pcm_t *pcm)
 	snd_pcm_hw_t *hw = pcm->private_data;
 	int fd = hw->fd, err;
 	if (SNDRV_PROTOCOL_VERSION(2, 0, 3) <= hw->version) {
-		if (hw->sync_ptr) {
-			err = sync_ptr1(hw, SNDRV_PCM_SYNC_PTR_HWSYNC);
+		if (hw->mmap_status_fallbacked) {
+			err = request_hwsync(hw);
 			if (err < 0)
 				return err;
 		} else {
-- 
2.13.5


From de9fe69e40e6b705aeae9aa8d1408736d4a1e563 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 30 Jun 2017 20:37:27 +0900
Subject: [PATCH 23/39] pcm: hw: add a helper function to issue appl_ptr
 without side-effects

After starting, PCM substream shift its state to running and applications
can move appl_ptr by several ways. When status and control data of runtime
of the PCM substream is not mapped, the applications should issue appl_ptr
to kernel land. In this case, when any PCM frames is handled by mmap
operation, the applications should issue appl_ptr to update.

This commit adds a helper function for this purpose. To avoid unexpected
change of avail_min, this commit uses a flag just to update appl_ptr.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 8455baaf..51512306 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -151,6 +151,15 @@ static int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
 	return 0;
 }
 
+static int issue_applptr(snd_pcm_hw_t *hw)
+{
+	if (!hw->mmap_control_fallbacked)
+		return 0;
+
+	/* Avoid unexpected change of avail_min in kernel space. */
+	return sync_ptr1(hw, SNDRV_PCM_SYNC_PTR_AVAIL_MIN);
+}
+
 static int request_hwsync(snd_pcm_hw_t *hw)
 {
 	if (!hw->mmap_status_fallbacked)
@@ -667,7 +676,7 @@ static int snd_pcm_hw_start(snd_pcm_t *pcm)
 	assert(pcm->stream != SND_PCM_STREAM_PLAYBACK ||
 	       snd_pcm_mmap_playback_hw_avail(pcm) > 0);
 #endif
-	sync_ptr(hw, 0);
+	issue_applptr(hw);
 	if (ioctl(hw->fd, SNDRV_PCM_IOCTL_START) < 0) {
 		err = -errno;
 		SYSMSG("SNDRV_PCM_IOCTL_START failed (%i)", err);
@@ -1081,7 +1090,7 @@ static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
 	snd_pcm_hw_t *hw = pcm->private_data;
 
 	snd_pcm_mmap_appl_forward(pcm, size);
-	sync_ptr(hw, 0);
+	issue_applptr(hw);
 #ifdef DEBUG_MMAP
 	fprintf(stderr, "appl_forward: hw_ptr = %li, appl_ptr = %li, size = %li\n", *pcm->hw.ptr, *pcm->appl.ptr, size);
 #endif
-- 
2.13.5


From cea81cbdc2e7be344a34992ad6adef451a759840 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 30 Jun 2017 20:37:28 +0900
Subject: [PATCH 24/39] pcm: hw: add a helper function to issue avail_min
 without side-effects

At present, applications can change avail_min parameter of PCM substream
by two ways; via mapped control data, and by executing ioctl(2) with
SNDRV_PCM_IOCTL_SYNC_PTR. The former is available in a case that the
applications map the data successfully.

When utilizing alsa-lib API, the above is done by a call of
'snd_pcm_sw_params()' to hw PCM plugin. In current implementation, this
call has an side-effect to issue appl_ptr unexpectedly.

This commit adds a helper function to issue avail_min without the
side-effect.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 51512306..9c8fc3f6 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -151,6 +151,15 @@ static int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
 	return 0;
 }
 
+static int issue_avail_min(snd_pcm_hw_t *hw)
+{
+	if (!hw->mmap_control_fallbacked)
+		return 0;
+
+	/* Avoid unexpected change of applptr in kernel space. */
+	return sync_ptr1(hw, SNDRV_PCM_SYNC_PTR_APPL);
+}
+
 static int issue_applptr(snd_pcm_hw_t *hw)
 {
 	if (!hw->mmap_control_fallbacked)
@@ -506,7 +515,7 @@ static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 	    params->silence_size == pcm->silence_size &&
 	    old_period_event == hw->period_event) {
 		hw->mmap_control->avail_min = params->avail_min;
-		return sync_ptr(hw, 0);
+		return issue_avail_min(hw);
 	}
 	if (params->tstamp_type == SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW &&
 	    hw->version < SNDRV_PROTOCOL_VERSION(2, 0, 12)) {
-- 
2.13.5


From a9ec1a6f687a6cb4f14d3f093c2ee020b610e12d Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Fri, 30 Jun 2017 20:37:29 +0900
Subject: [PATCH 25/39] pcm: hw: remove superfluous code to call of
 SNDRV_PCM_IOCTL_SYNC_PTR in snd_pcm_hw_forward()

SNDRV_PCM_IOCTL_SYNC_PTR command was introduced to PCM protocol/interface
in its version 2.0.7, however this command is used in a branch for the
newer version protocol/interface in snd_pcm_hw_forward().

This commit removes the superfluous code as a part of work for code
refactoring.

Fixes: eafb4925124b ("- added SYNC_PTR ioctl support for pcm_hw plugin")
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_hw.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 9c8fc3f6..16d45e74 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -144,13 +144,6 @@ static int sync_ptr1(snd_pcm_hw_t *hw, unsigned int flags)
 	return 0;
 }
 
-static int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
-{
-	if (hw->mmap_status_fallbacked || hw->mmap_control_fallbacked)
-		return sync_ptr1(hw, flags);
-	return 0;
-}
-
 static int issue_avail_min(snd_pcm_hw_t *hw)
 {
 	if (!hw->mmap_control_fallbacked)
@@ -777,9 +770,6 @@ static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t fr
 	} else {
 		snd_pcm_sframes_t avail;
 
-		err = sync_ptr(hw, SNDRV_PCM_SYNC_PTR_HWSYNC);
-		if (err < 0)
-			return err;
 		switch (FAST_PCM_STATE(hw)) {
 		case SNDRV_PCM_STATE_RUNNING:
 		case SNDRV_PCM_STATE_DRAINING:
@@ -797,9 +787,6 @@ static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t fr
 		if (frames > (snd_pcm_uframes_t)avail)
 			frames = avail;
 		snd_pcm_mmap_appl_forward(pcm, frames);
-		err = sync_ptr(hw, 0);
-		if (err < 0)
-			return err;
 		return frames;
 	}
 }
-- 
2.13.5


From 885c64bcc48f5734da964d2da2b9a5603d7b2c8b Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Wed, 12 Jul 2017 10:45:18 +0200
Subject: [PATCH 26/39] cleanup: fix poll.h includes

According POSIX[1] and linux manpage[2] the include is poll.h, not
sys/poll.h.

This fixes the he following compiler warning when build with musl libc:

  /usr/include/sys/poll.h:1:2: warning: #warning redirecting incorrect #include <sys/poll.h> to <poll.h> [-Wcpp]
   #warning redirecting incorrect #include <sys/poll.h> to <poll.h>
    ^~~~~~~

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 aserver/aserver.c         | 2 +-
 include/asoundlib-head.h  | 2 +-
 include/local.h           | 2 +-
 src/control/control.c     | 2 +-
 src/control/control_shm.c | 2 +-
 src/pcm/pcm.c             | 2 +-
 src/pcm/pcm_direct.c      | 2 +-
 src/pcm/pcm_mmap.c        | 2 +-
 src/pcm/pcm_share.c       | 2 +-
 src/pcm/pcm_shm.c         | 2 +-
 src/seq/seq.c             | 2 +-
 src/shmarea.c             | 2 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/aserver/aserver.c b/aserver/aserver.c
index ac20706b..46f731a4 100644
--- a/aserver/aserver.c
+++ b/aserver/aserver.c
@@ -20,7 +20,7 @@
 
 #include <sys/shm.h>
 #include <sys/socket.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/un.h>
 #include <sys/uio.h>
 #include <stdio.h>
diff --git a/include/asoundlib-head.h b/include/asoundlib-head.h
index 1ec611e5..21e32c6b 100644
--- a/include/asoundlib-head.h
+++ b/include/asoundlib-head.h
@@ -35,6 +35,6 @@
 #include <string.h>
 #include <fcntl.h>
 #include <assert.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <errno.h>
 #include <stdarg.h>
diff --git a/include/local.h b/include/local.h
index 317f2e32..6a43a473 100644
--- a/include/local.h
+++ b/include/local.h
@@ -47,7 +47,7 @@
 #error Header defining endianness not defined
 #endif
 #include <stdarg.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/types.h>
 #include <errno.h>
 #if defined(__linux__)
diff --git a/src/control/control.c b/src/control/control.c
index 134ba4c8..6439b294 100644
--- a/src/control/control.c
+++ b/src/control/control.c
@@ -90,7 +90,7 @@ against the original design.
 #include <string.h>
 #include <fcntl.h>
 #include <signal.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <stdbool.h>
 #include "control_local.h"
 
diff --git a/src/control/control_shm.c b/src/control/control_shm.c
index bd07d4af..9a2e268b 100644
--- a/src/control/control_shm.c
+++ b/src/control/control_shm.c
@@ -27,7 +27,7 @@
 #include <fcntl.h>
 #include <sys/shm.h>
 #include <sys/socket.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/un.h>
 #include <sys/uio.h>
 #include <sys/mman.h>
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index 200b10c2..2b4ce8ec 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -651,7 +651,7 @@ playback devices.
 #include <stdarg.h>
 #include <signal.h>
 #include <ctype.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/mman.h>
 #include <limits.h>
 #include "pcm_local.h"
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 9fd376d8..393083f5 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -30,7 +30,7 @@
 #include <grp.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/shm.h>
 #include <sys/sem.h>
 #include <sys/wait.h>
diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c
index 1948289c..4cf220a4 100644
--- a/src/pcm/pcm_mmap.c
+++ b/src/pcm/pcm_mmap.c
@@ -22,7 +22,7 @@
 #include <stdio.h>
 #include <malloc.h>
 #include <string.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/mman.h>
 #ifdef HAVE_SYS_SHM_H
 #include <sys/shm.h>
diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c
index 5d8aaf21..21a57fc6 100644
--- a/src/pcm/pcm_share.c
+++ b/src/pcm/pcm_share.c
@@ -34,7 +34,7 @@
 #include <signal.h>
 #include <math.h>
 #include <sys/socket.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <pthread.h>
 #include "pcm_local.h"
 
diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c
index a815ac6b..4ee958c1 100644
--- a/src/pcm/pcm_shm.c
+++ b/src/pcm/pcm_shm.c
@@ -36,7 +36,7 @@
 #include <sys/ioctl.h>
 #include <sys/shm.h>
 #include <sys/socket.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/un.h>
 #include <sys/mman.h>
 #include <netinet/in.h>
diff --git a/src/seq/seq.c b/src/seq/seq.c
index b206e2f8..d5ed1c6a 100644
--- a/src/seq/seq.c
+++ b/src/seq/seq.c
@@ -777,7 +777,7 @@ void event_filter(snd_seq_t *seq, snd_seq_event_t *ev)
 
 */
 
-#include <sys/poll.h>
+#include <poll.h>
 #include "seq_local.h"
 
 /****************************************************************************
diff --git a/src/shmarea.c b/src/shmarea.c
index 9843aa8b..eaa71f00 100644
--- a/src/shmarea.c
+++ b/src/shmarea.c
@@ -27,7 +27,7 @@
 #include <malloc.h>
 #include <string.h>
 #include <errno.h>
-#include <sys/poll.h>
+#include <poll.h>
 #include <sys/mman.h>
 #include <sys/shm.h>
 #include "list.h"
-- 
2.13.5


From adab355f35c8fcb424b1336043634cf9a6856515 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Fri, 14 Jul 2017 16:18:11 +0200
Subject: [PATCH 27/39] cleanup: Use uint*_t instead of u_int*_t everythwere

Use the standard uint{8,16,32,64}_t everywhere instead of the
non-standard u_int{8,16,32,64}_t.

This changes the types in the public headers and removes the u_int*_t
defines. This may break things. However, indentifiers ending with _t are
reserved by POSIX[1]; defining those can lead to undefined behavior.

So if you rely on alsa-lib defining those for you, then you want the
compiler to error so things can be fixed properly.

[1]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02_02

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 include/pcm.h             |  10 ++-
 include/type_compat.h     |  12 ---
 src/pcm/interval.c        |   4 +-
 src/pcm/mask_inline.h     |   6 +-
 src/pcm/pcm.c             |  26 +++----
 src/pcm/pcm_iec958.c      |  12 +--
 src/pcm/pcm_linear.c      |   2 +-
 src/pcm/pcm_misc.c        |  42 +++++------
 src/pcm/pcm_rate_linear.c |   4 +-
 src/pcm/pcm_route.c       |   2 +-
 src/pcm/plugin_ops.h      | 182 +++++++++++++++++++++++-----------------------
 11 files changed, 146 insertions(+), 156 deletions(-)

diff --git a/include/pcm.h b/include/pcm.h
index 0be1a321..d44de54b 100644
--- a/include/pcm.h
+++ b/include/pcm.h
@@ -33,6 +33,8 @@
 extern "C" {
 #endif
 
+#include <stdint.h>
+
 /**
  *  \defgroup PCM PCM Interface
  *  See the \ref pcm page for more details.
@@ -1108,10 +1110,10 @@ int snd_pcm_format_width(snd_pcm_format_t format);			/* in bits */
 int snd_pcm_format_physical_width(snd_pcm_format_t format);		/* in bits */
 snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd, int big_endian);
 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
-u_int8_t snd_pcm_format_silence(snd_pcm_format_t format);
-u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format);
-u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format);
-u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format);
+uint8_t snd_pcm_format_silence(snd_pcm_format_t format);
+uint16_t snd_pcm_format_silence_16(snd_pcm_format_t format);
+uint32_t snd_pcm_format_silence_32(snd_pcm_format_t format);
+uint64_t 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 samples);
 
 snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes);
diff --git a/include/type_compat.h b/include/type_compat.h
index 0c10aed7..35973b1e 100644
--- a/include/type_compat.h
+++ b/include/type_compat.h
@@ -47,18 +47,6 @@
 #ifndef __le64
 #define __le64	uint64_t
 #endif
-#ifndef u_int8_t
-#define u_int8_t	uint8_t
-#endif
-#ifndef u_int16_t
-#define u_int16_t	uint16_t
-#endif
-#ifndef u_int32_t
-#define u_int32_t	uint32_t
-#endif
-#ifndef u_int32_t
-#define u_int32_t	uint64_t
-#endif
 #ifndef __kernel_pid_t
 #define __kernel_pid_t	pid_t
 #endif
diff --git a/src/pcm/interval.c b/src/pcm/interval.c
index 6e398084..74ec3204 100644
--- a/src/pcm/interval.c
+++ b/src/pcm/interval.c
@@ -26,7 +26,7 @@
 #include <limits.h>
 #include "pcm_local.h"
 
-static inline void div64_32(u_int64_t *n, u_int32_t d, u_int32_t *rem)
+static inline void div64_32(uint64_t *n, uint32_t d, uint32_t *rem)
 {
 	*rem = *n % d;
 	*n /= d;
@@ -88,7 +88,7 @@ static inline unsigned int sub(unsigned int a, unsigned int b)
 static inline unsigned int muldiv32(unsigned int a, unsigned int b,
 				    unsigned int c, unsigned int *r)
 {
-	u_int64_t n = (u_int64_t) a * b;
+	uint64_t n = (uint64_t) a * b;
 	if (c == 0) {
 		assert(n > 0);
 		*r = 0;
diff --git a/src/pcm/mask_inline.h b/src/pcm/mask_inline.h
index f656568d..04c7ee6e 100644
--- a/src/pcm/mask_inline.h
+++ b/src/pcm/mask_inline.h
@@ -29,7 +29,7 @@
 #define MASK_OFS(i)	((i) >> 5)
 #define MASK_BIT(i)	(1U << ((i) & 31))
 
-MASK_INLINE unsigned int ld2(u_int32_t v)
+MASK_INLINE unsigned int ld2(uint32_t v)
 {
         unsigned r = 0;
 
@@ -54,7 +54,7 @@ MASK_INLINE unsigned int ld2(u_int32_t v)
         return r;
 }
 
-MASK_INLINE unsigned int hweight32(u_int32_t v)
+MASK_INLINE unsigned int hweight32(uint32_t v)
 {
         v = (v & 0x55555555) + ((v >> 1) & 0x55555555);
         v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
@@ -75,7 +75,7 @@ MASK_INLINE void snd_mask_none(snd_mask_t *mask)
 
 MASK_INLINE void snd_mask_any(snd_mask_t *mask)
 {
-	memset(mask, 0xff, MASK_SIZE * sizeof(u_int32_t));
+	memset(mask, 0xff, MASK_SIZE * sizeof(uint32_t));
 }
 
 MASK_INLINE int snd_mask_empty(const snd_mask_t *mask)
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index 2b4ce8ec..fc7bd52c 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -2894,7 +2894,7 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
 	char *dst;
 	unsigned int dst_step;
 	int width;
-	u_int64_t silence;
+	uint64_t silence;
 	if (!dst_area->addr)
 		return 0;
 	dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
@@ -2902,7 +2902,7 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
 	silence = snd_pcm_format_silence_64(format);
 	if (dst_area->step == (unsigned int) width) {
 		unsigned int dwords = samples * width / 64;
-		u_int64_t *dstp = (u_int64_t *)dst;
+		uint64_t *dstp = (uint64_t *)dst;
 		samples -= dwords * 64 / width;
 		while (dwords-- > 0)
 			*dstp++ = silence;
@@ -2912,8 +2912,8 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
 	dst_step = dst_area->step / 8;
 	switch (width) {
 	case 4: {
-		u_int8_t s0 = silence & 0xf0;
-		u_int8_t s1 = silence & 0x0f;
+		uint8_t s0 = silence & 0xf0;
+		uint8_t s1 = silence & 0x0f;
 		int dstbit = dst_area->first % 8;
 		int dstbit_step = dst_area->step % 8;
 		while (samples-- > 0) {
@@ -2934,7 +2934,7 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
 		break;
 	}
 	case 8: {
-		u_int8_t sil = silence;
+		uint8_t sil = silence;
 		while (samples-- > 0) {
 			*dst = sil;
 			dst += dst_step;
@@ -2942,9 +2942,9 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
 		break;
 	}
 	case 16: {
-		u_int16_t sil = silence;
+		uint16_t sil = silence;
 		while (samples-- > 0) {
-			*(u_int16_t*)dst = sil;
+			*(uint16_t*)dst = sil;
 			dst += dst_step;
 		}
 		break;
@@ -2961,16 +2961,16 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
 #endif
 		break;
 	case 32: {
-		u_int32_t sil = silence;
+		uint32_t sil = silence;
 		while (samples-- > 0) {
-			*(u_int32_t*)dst = sil;
+			*(uint32_t*)dst = sil;
 			dst += dst_step;
 		}
 		break;
 	}
 	case 64: {
 		while (samples-- > 0) {
-			*(u_int64_t*)dst = silence;
+			*(uint64_t*)dst = silence;
 			dst += dst_step;
 		}
 		break;
@@ -3114,7 +3114,7 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t
 	}
 	case 16: {
 		while (samples-- > 0) {
-			*(u_int16_t*)dst = *(const u_int16_t*)src;
+			*(uint16_t*)dst = *(const uint16_t*)src;
 			src += src_step;
 			dst += dst_step;
 		}
@@ -3131,7 +3131,7 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t
 		break;
 	case 32: {
 		while (samples-- > 0) {
-			*(u_int32_t*)dst = *(const u_int32_t*)src;
+			*(uint32_t*)dst = *(const uint32_t*)src;
 			src += src_step;
 			dst += dst_step;
 		}
@@ -3139,7 +3139,7 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t
 	}
 	case 64: {
 		while (samples-- > 0) {
-			*(u_int64_t*)dst = *(const u_int64_t*)src;
+			*(uint64_t*)dst = *(const uint64_t*)src;
 			src += src_step;
 			dst += dst_step;
 		}
diff --git a/src/pcm/pcm_iec958.c b/src/pcm/pcm_iec958.c
index 86ac9cfd..115092de 100644
--- a/src/pcm/pcm_iec958.c
+++ b/src/pcm/pcm_iec958.c
@@ -102,7 +102,7 @@ static unsigned int iec958_parity(unsigned int data)
  *     31   = parity
  */
 
-static inline u_int32_t iec958_subframe(snd_pcm_iec958_t *iec, u_int32_t data, int channel)
+static inline uint32_t iec958_subframe(snd_pcm_iec958_t *iec, uint32_t data, int channel)
 {
 	unsigned int byte = iec->counter >> 3;
 	unsigned int mask = 1 << (iec->counter - (byte << 3));
@@ -132,7 +132,7 @@ static inline u_int32_t iec958_subframe(snd_pcm_iec958_t *iec, u_int32_t data, i
 	return data;
 }
 
-static inline int32_t iec958_to_s32(snd_pcm_iec958_t *iec, u_int32_t data)
+static inline int32_t iec958_to_s32(snd_pcm_iec958_t *iec, uint32_t data)
 {
 	if (iec->byteswap)
 		data = bswap_32(data);
@@ -155,7 +155,7 @@ static void snd_pcm_iec958_decode(snd_pcm_iec958_t *iec,
 	void *put = put32_labels[iec->getput_idx];
 	unsigned int channel;
 	for (channel = 0; channel < channels; ++channel) {
-		const u_int32_t *src;
+		const uint32_t *src;
 		char *dst;
 		int src_step, dst_step;
 		snd_pcm_uframes_t frames1;
@@ -163,7 +163,7 @@ static void snd_pcm_iec958_decode(snd_pcm_iec958_t *iec,
 		const snd_pcm_channel_area_t *dst_area = &dst_areas[channel];
 		src = snd_pcm_channel_area_addr(src_area, src_offset);
 		dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
-		src_step = snd_pcm_channel_area_step(src_area) / sizeof(u_int32_t);
+		src_step = snd_pcm_channel_area_step(src_area) / sizeof(uint32_t);
 		dst_step = snd_pcm_channel_area_step(dst_area);
 		frames1 = frames;
 		while (frames1-- > 0) {
@@ -195,7 +195,7 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec,
 	int counter = iec->counter;
 	for (channel = 0; channel < channels; ++channel) {
 		const char *src;
-		u_int32_t *dst;
+		uint32_t *dst;
 		int src_step, dst_step;
 		snd_pcm_uframes_t frames1;
 		const snd_pcm_channel_area_t *src_area = &src_areas[channel];
@@ -203,7 +203,7 @@ static void snd_pcm_iec958_encode(snd_pcm_iec958_t *iec,
 		src = snd_pcm_channel_area_addr(src_area, src_offset);
 		dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
 		src_step = snd_pcm_channel_area_step(src_area);
-		dst_step = snd_pcm_channel_area_step(dst_area) / sizeof(u_int32_t);
+		dst_step = snd_pcm_channel_area_step(dst_area) / sizeof(uint32_t);
 		frames1 = frames;
 		iec->counter = counter;
 		while (frames1-- > 0) {
diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c
index 50df7794..9b1d9638 100644
--- a/src/pcm/pcm_linear.c
+++ b/src/pcm/pcm_linear.c
@@ -183,7 +183,7 @@ void snd_pcm_linear_getput(const snd_pcm_channel_area_t *dst_areas, snd_pcm_ufra
 	void *get = get32_labels[get_idx];
 	void *put = put32_labels[put_idx];
 	unsigned int channel;
-	u_int32_t sample = 0;
+	uint32_t sample = 0;
 	for (channel = 0; channel < channels; ++channel) {
 		const char *src;
 		char *dst;
diff --git a/src/pcm/pcm_misc.c b/src/pcm/pcm_misc.c
index 7d2b05db..a321c87e 100644
--- a/src/pcm/pcm_misc.c
+++ b/src/pcm/pcm_misc.c
@@ -387,7 +387,7 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
  * \param format Sample format
  * \return silence 64 bit word
  */
-u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
+uint64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
 {
 	switch (format) {
 	case SNDRV_PCM_FORMAT_S8:
@@ -467,7 +467,7 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
 	{
 		union {
 			float f[2];
-			u_int64_t i;
+			uint64_t i;
 		} u;
 		u.f[0] = u.f[1] = 0.0;
 #ifdef SNDRV_LITTLE_ENDIAN
@@ -480,7 +480,7 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
 	{
 		union {
 			double f;
-			u_int64_t i;
+			uint64_t i;
 		} u;
 		u.f = 0.0;
 #ifdef SNDRV_LITTLE_ENDIAN
@@ -493,7 +493,7 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
 	{
 		union {
 			float f[2];
-			u_int64_t i;
+			uint64_t i;
 		} u;
 		u.f[0] = u.f[1] = 0.0;
 #ifdef SNDRV_LITTLE_ENDIAN
@@ -506,7 +506,7 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
 	{
 		union {
 			double f;
-			u_int64_t i;
+			uint64_t i;
 		} u;
 		u.f = 0.0;
 #ifdef SNDRV_LITTLE_ENDIAN
@@ -539,10 +539,10 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
  * \param format Sample format
  * \return silence 32 bit word
  */
-u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format)
+uint32_t snd_pcm_format_silence_32(snd_pcm_format_t format)
 {
 	assert(snd_pcm_format_physical_width(format) <= 32);
-	return (u_int32_t)snd_pcm_format_silence_64(format);
+	return (uint32_t)snd_pcm_format_silence_64(format);
 }
 
 /**
@@ -550,10 +550,10 @@ u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format)
  * \param format Sample format
  * \return silence 16 bit word
  */
-u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format)
+uint16_t snd_pcm_format_silence_16(snd_pcm_format_t format)
 {
 	assert(snd_pcm_format_physical_width(format) <= 16);
-	return (u_int16_t)snd_pcm_format_silence_64(format);
+	return (uint16_t)snd_pcm_format_silence_64(format);
 }
 
 /**
@@ -561,10 +561,10 @@ u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format)
  * \param format Sample format
  * \return silence 8 bit word
  */
-u_int8_t snd_pcm_format_silence(snd_pcm_format_t format)
+uint8_t snd_pcm_format_silence(snd_pcm_format_t format)
 {
 	assert(snd_pcm_format_physical_width(format) <= 8);
-	return (u_int8_t)snd_pcm_format_silence_64(format);
+	return (uint8_t)snd_pcm_format_silence_64(format);
 }
 
 /**
@@ -580,7 +580,7 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
 		return 0;
 	switch (snd_pcm_format_physical_width(format)) {
 	case 4: {
-		u_int8_t silence = snd_pcm_format_silence_64(format);
+		uint8_t silence = snd_pcm_format_silence_64(format);
 		unsigned int samples1;
 		if (samples % 2 != 0)
 			return -EINVAL;
@@ -589,13 +589,13 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
 		break;
 	}
 	case 8: {
-		u_int8_t silence = snd_pcm_format_silence_64(format);
+		uint8_t silence = snd_pcm_format_silence_64(format);
 		memset(data, silence, samples);
 		break;
 	}
 	case 16: {
-		u_int16_t silence = snd_pcm_format_silence_64(format);
-		u_int16_t *pdata = (u_int16_t *)data;
+		uint16_t silence = snd_pcm_format_silence_64(format);
+		uint16_t *pdata = (uint16_t *)data;
 		if (! silence)
 			memset(data, 0, samples * 2);
 		else {
@@ -605,8 +605,8 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
 		break;
 	}
 	case 24: {
-		u_int32_t silence = snd_pcm_format_silence_64(format);
-		u_int8_t *pdata = (u_int8_t *)data;
+		uint32_t silence = snd_pcm_format_silence_64(format);
+		uint8_t *pdata = (uint8_t *)data;
 		if (! silence)
 			memset(data, 0, samples * 3);
 		else {
@@ -625,8 +625,8 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
 		break;
 	}
 	case 32: {
-		u_int32_t silence = snd_pcm_format_silence_64(format);
-		u_int32_t *pdata = (u_int32_t *)data;
+		uint32_t silence = snd_pcm_format_silence_64(format);
+		uint32_t *pdata = (uint32_t *)data;
 		if (! silence)
 			memset(data, 0, samples * 4);
 		else {
@@ -636,8 +636,8 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
 		break;
 	}
 	case 64: {
-		u_int64_t silence = snd_pcm_format_silence_64(format);
-		u_int64_t *pdata = (u_int64_t *)data;
+		uint64_t silence = snd_pcm_format_silence_64(format);
+		uint64_t *pdata = (uint64_t *)data;
 		if (! silence)
 			memset(data, 0, samples * 8);
 		else {
diff --git a/src/pcm/pcm_rate_linear.c b/src/pcm/pcm_rate_linear.c
index 70399e0d..b20c715a 100644
--- a/src/pcm/pcm_rate_linear.c
+++ b/src/pcm/pcm_rate_linear.c
@@ -346,7 +346,7 @@ static int linear_init(void *obj, snd_pcm_rate_info_t *info)
 			rate->func = linear_shrink;
 		/* pitch is get_increment */
 	}
-	rate->pitch = (((u_int64_t)info->out.rate * LINEAR_DIV) +
+	rate->pitch = (((uint64_t)info->out.rate * LINEAR_DIV) +
 		       (info->in.rate / 2)) / info->in.rate;
 	rate->channels = info->channels;
 
@@ -363,7 +363,7 @@ static int linear_adjust_pitch(void *obj, snd_pcm_rate_info_t *info)
 	struct rate_linear *rate = obj;
 	snd_pcm_uframes_t cframes;
 
-	rate->pitch = (((u_int64_t)info->out.period_size * LINEAR_DIV) +
+	rate->pitch = (((uint64_t)info->out.period_size * LINEAR_DIV) +
 		       (info->in.period_size/2) ) / info->in.period_size;
 			
 	cframes = input_frames(rate, info->out.period_size);
diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c
index 508d5b0f..1bb83d2f 100644
--- a/src/pcm/pcm_route.c
+++ b/src/pcm/pcm_route.c
@@ -190,7 +190,7 @@ static void snd_pcm_route_convert1_one_getput(const snd_pcm_channel_area_t *dst_
 	const char *src;
 	char *dst;
 	int src_step, dst_step;
-	u_int32_t sample = 0;
+	uint32_t sample = 0;
 	for (srcidx = 0; srcidx < ttable->nsrcs && srcidx < src_channels; ++srcidx) {
 		unsigned int channel = ttable->srcs[srcidx].channel;
 		if (channel >= src_channels)
diff --git a/src/pcm/plugin_ops.h b/src/pcm/plugin_ops.h
index eb8c2c4f..69e7f2cf 100644
--- a/src/pcm/plugin_ops.h
+++ b/src/pcm/plugin_ops.h
@@ -21,13 +21,13 @@
 
 #ifndef SX_INLINES
 #define SX_INLINES
-static inline u_int32_t sx24(u_int32_t x)
+static inline uint32_t sx24(uint32_t x)
 {
 	if(x&0x00800000)
 		return x|0xFF000000;
 	return x&0x00FFFFFF;
 }
-static inline u_int32_t sx24s(u_int32_t x)
+static inline uint32_t sx24s(uint32_t x)
 {
 	if(x&0x00008000)
 		return x|0x000000FF;
@@ -35,10 +35,10 @@ static inline u_int32_t sx24s(u_int32_t x)
 }
 #endif
 
-#define as_u8(ptr) (*(u_int8_t*)(ptr))
-#define as_u16(ptr) (*(u_int16_t*)(ptr))
-#define as_u32(ptr) (*(u_int32_t*)(ptr))
-#define as_u64(ptr) (*(u_int64_t*)(ptr))
+#define as_u8(ptr) (*(uint8_t*)(ptr))
+#define as_u16(ptr) (*(uint16_t*)(ptr))
+#define as_u32(ptr) (*(uint32_t*)(ptr))
+#define as_u64(ptr) (*(uint64_t*)(ptr))
 #define as_s8(ptr) (*(int8_t*)(ptr))
 #define as_s16(ptr) (*(int16_t*)(ptr))
 #define as_s32(ptr) (*(int32_t*)(ptr))
@@ -46,10 +46,10 @@ static inline u_int32_t sx24s(u_int32_t x)
 #define as_float(ptr) (*(float_t*)(ptr))
 #define as_double(ptr) (*(double_t*)(ptr))
 
-#define as_u8c(ptr) (*(const u_int8_t*)(ptr))
-#define as_u16c(ptr) (*(const u_int16_t*)(ptr))
-#define as_u32c(ptr) (*(const u_int32_t*)(ptr))
-#define as_u64c(ptr) (*(const u_int64_t*)(ptr))
+#define as_u8c(ptr) (*(const uint8_t*)(ptr))
+#define as_u16c(ptr) (*(const uint16_t*)(ptr))
+#define as_u32c(ptr) (*(const uint32_t*)(ptr))
+#define as_u64c(ptr) (*(const uint64_t*)(ptr))
 #define as_s8c(ptr) (*(const int8_t*)(ptr))
 #define as_s16c(ptr) (*(const int16_t*)(ptr))
 #define as_s32c(ptr) (*(const int32_t*)(ptr))
@@ -57,18 +57,18 @@ static inline u_int32_t sx24s(u_int32_t x)
 #define as_floatc(ptr) (*(const float_t*)(ptr))
 #define as_doublec(ptr) (*(const double_t*)(ptr))
 
-#define _get_triple_le(ptr) (*(u_int8_t*)(ptr) | (u_int32_t)*((u_int8_t*)(ptr) + 1) << 8 | (u_int32_t)*((u_int8_t*)(ptr) + 2) << 16)
-#define _get_triple_be(ptr) ((u_int32_t)*(u_int8_t*)(ptr) << 16 | (u_int32_t)*((u_int8_t*)(ptr) + 1) << 8 | *((u_int8_t*)(ptr) + 2))
+#define _get_triple_le(ptr) (*(uint8_t*)(ptr) | (uint32_t)*((uint8_t*)(ptr) + 1) << 8 | (uint32_t)*((uint8_t*)(ptr) + 2) << 16)
+#define _get_triple_be(ptr) ((uint32_t)*(uint8_t*)(ptr) << 16 | (uint32_t)*((uint8_t*)(ptr) + 1) << 8 | *((uint8_t*)(ptr) + 2))
 #define _put_triple_le(ptr,val) do { \
-	u_int8_t *_tmp = (u_int8_t *)(ptr); \
-	u_int32_t _val = (val); \
+	uint8_t *_tmp = (uint8_t *)(ptr); \
+	uint32_t _val = (val); \
 	_tmp[0] = _val; \
 	_tmp[1] = _val >> 8; \
 	_tmp[2] = _val >> 16; \
 } while(0)
 #define _put_triple_be(ptr,val) do { \
-	u_int8_t *_tmp = (u_int8_t *)(ptr); \
-	u_int32_t _val = (val); \
+	uint8_t *_tmp = (uint8_t *)(ptr); \
+	uint32_t _val = (val); \
 	_tmp[0] = _val >> 16; \
 	_tmp[1] = _val >> 8; \
 	_tmp[2] = _val; \
@@ -243,45 +243,45 @@ static void *const conv_labels[4 * 2 * 2 * 4 * 2] = {
 #ifdef CONV_END
 while(0) {
 conv_xxx1_xxx1: as_u8(dst) = as_u8c(src); goto CONV_END;
-conv_xxx1_xx10: as_u16(dst) = (u_int16_t)as_u8c(src) << 8; goto CONV_END;
-conv_xxx1_xx01: as_u16(dst) = (u_int16_t)as_u8c(src); goto CONV_END;
-conv_xxx1_x100: as_u32(dst) = sx24((u_int32_t)as_u8c(src) << 16); goto CONV_END;
-conv_xxx1_001x: as_u32(dst) = sx24s((u_int32_t)as_u8c(src) << 8); goto CONV_END;
-conv_xxx1_1000: as_u32(dst) = (u_int32_t)as_u8c(src) << 24; goto CONV_END;
-conv_xxx1_0001: as_u32(dst) = (u_int32_t)as_u8c(src); goto CONV_END;
+conv_xxx1_xx10: as_u16(dst) = (uint16_t)as_u8c(src) << 8; goto CONV_END;
+conv_xxx1_xx01: as_u16(dst) = (uint16_t)as_u8c(src); goto CONV_END;
+conv_xxx1_x100: as_u32(dst) = sx24((uint32_t)as_u8c(src) << 16); goto CONV_END;
+conv_xxx1_001x: as_u32(dst) = sx24s((uint32_t)as_u8c(src) << 8); goto CONV_END;
+conv_xxx1_1000: as_u32(dst) = (uint32_t)as_u8c(src) << 24; goto CONV_END;
+conv_xxx1_0001: as_u32(dst) = (uint32_t)as_u8c(src); goto CONV_END;
 conv_xxx1_xxx9: as_u8(dst) = as_u8c(src) ^ 0x80; goto CONV_END;
-conv_xxx1_xx90: as_u16(dst) = (u_int16_t)(as_u8c(src) ^ 0x80) << 8; goto CONV_END;
-conv_xxx1_xx09: as_u16(dst) = (u_int16_t)(as_u8c(src) ^ 0x80); goto CONV_END;
-conv_xxx1_x900: as_u32(dst) = sx24((u_int32_t)(as_u8c(src) ^ 0x80) << 16); goto CONV_END;
-conv_xxx1_009x: as_u32(dst) = sx24s((u_int32_t)(as_u8c(src) ^ 0x80) << 8); goto CONV_END;
-conv_xxx1_9000: as_u32(dst) = (u_int32_t)(as_u8c(src) ^ 0x80) << 24; goto CONV_END;
-conv_xxx1_0009: as_u32(dst) = (u_int32_t)(as_u8c(src) ^ 0x80); goto CONV_END;
+conv_xxx1_xx90: as_u16(dst) = (uint16_t)(as_u8c(src) ^ 0x80) << 8; goto CONV_END;
+conv_xxx1_xx09: as_u16(dst) = (uint16_t)(as_u8c(src) ^ 0x80); goto CONV_END;
+conv_xxx1_x900: as_u32(dst) = sx24((uint32_t)(as_u8c(src) ^ 0x80) << 16); goto CONV_END;
+conv_xxx1_009x: as_u32(dst) = sx24s((uint32_t)(as_u8c(src) ^ 0x80) << 8); goto CONV_END;
+conv_xxx1_9000: as_u32(dst) = (uint32_t)(as_u8c(src) ^ 0x80) << 24; goto CONV_END;
+conv_xxx1_0009: as_u32(dst) = (uint32_t)(as_u8c(src) ^ 0x80); goto CONV_END;
 conv_xx12_xxx1: as_u8(dst) = as_u16c(src) >> 8; goto CONV_END;
 conv_xx12_xx12: as_u16(dst) = as_u16c(src); goto CONV_END;
 conv_xx12_xx21: as_u16(dst) = bswap_16(as_u16c(src)); goto CONV_END;
-conv_xx12_x120: as_u32(dst) = sx24((u_int32_t)as_u16c(src) << 8); goto CONV_END;
-conv_xx12_021x: as_u32(dst) = sx24s((u_int32_t)bswap_16(as_u16c(src)) << 8); goto CONV_END;
-conv_xx12_1200: as_u32(dst) = (u_int32_t)as_u16c(src) << 16; goto CONV_END;
-conv_xx12_0021: as_u32(dst) = (u_int32_t)bswap_16(as_u16c(src)); goto CONV_END;
+conv_xx12_x120: as_u32(dst) = sx24((uint32_t)as_u16c(src) << 8); goto CONV_END;
+conv_xx12_021x: as_u32(dst) = sx24s((uint32_t)bswap_16(as_u16c(src)) << 8); goto CONV_END;
+conv_xx12_1200: as_u32(dst) = (uint32_t)as_u16c(src) << 16; goto CONV_END;
+conv_xx12_0021: as_u32(dst) = (uint32_t)bswap_16(as_u16c(src)); goto CONV_END;
 conv_xx12_xxx9: as_u8(dst) = (as_u16c(src) >> 8) ^ 0x80; goto CONV_END;
 conv_xx12_xx92: as_u16(dst) = as_u16c(src) ^ 0x8000; goto CONV_END;
 conv_xx12_xx29: as_u16(dst) = bswap_16(as_u16c(src)) ^ 0x80; goto CONV_END;
-conv_xx12_x920: as_u32(dst) = sx24((u_int32_t)(as_u16c(src) ^ 0x8000) << 8); goto CONV_END;
-conv_xx12_029x: as_u32(dst) = sx24s((u_int32_t)(bswap_16(as_u16c(src)) ^ 0x80) << 8); goto CONV_END;
-conv_xx12_9200: as_u32(dst) = (u_int32_t)(as_u16c(src) ^ 0x8000) << 16; goto CONV_END;
-conv_xx12_0029: as_u32(dst) = (u_int32_t)(bswap_16(as_u16c(src)) ^ 0x80); goto CONV_END;
+conv_xx12_x920: as_u32(dst) = sx24((uint32_t)(as_u16c(src) ^ 0x8000) << 8); goto CONV_END;
+conv_xx12_029x: as_u32(dst) = sx24s((uint32_t)(bswap_16(as_u16c(src)) ^ 0x80) << 8); goto CONV_END;
+conv_xx12_9200: as_u32(dst) = (uint32_t)(as_u16c(src) ^ 0x8000) << 16; goto CONV_END;
+conv_xx12_0029: as_u32(dst) = (uint32_t)(bswap_16(as_u16c(src)) ^ 0x80); goto CONV_END;
 conv_xx12_xxx2: as_u8(dst) = as_u16c(src) & 0xff; goto CONV_END;
-conv_xx12_x210: as_u32(dst) = sx24((u_int32_t)bswap_16(as_u16c(src)) << 8); goto CONV_END;
-conv_xx12_012x: as_u32(dst) = sx24s((u_int32_t)as_u16c(src) << 8); goto CONV_END;
-conv_xx12_2100: as_u32(dst) = (u_int32_t)bswap_16(as_u16c(src)) << 16; goto CONV_END;
-conv_xx12_0012: as_u32(dst) = (u_int32_t)as_u16c(src); goto CONV_END; 
+conv_xx12_x210: as_u32(dst) = sx24((uint32_t)bswap_16(as_u16c(src)) << 8); goto CONV_END;
+conv_xx12_012x: as_u32(dst) = sx24s((uint32_t)as_u16c(src) << 8); goto CONV_END;
+conv_xx12_2100: as_u32(dst) = (uint32_t)bswap_16(as_u16c(src)) << 16; goto CONV_END;
+conv_xx12_0012: as_u32(dst) = (uint32_t)as_u16c(src); goto CONV_END; 
 conv_xx12_xxxA: as_u8(dst) = (as_u16c(src) ^ 0x80) & 0xff; goto CONV_END;
 conv_xx12_xxA1: as_u16(dst) = bswap_16(as_u16c(src) ^ 0x80); goto CONV_END;
 conv_xx12_xx1A: as_u16(dst) = as_u16c(src) ^ 0x80; goto CONV_END;
-conv_xx12_xA10: as_u32(dst) = sx24((u_int32_t)bswap_16(as_u16c(src) ^ 0x80) << 8); goto CONV_END;
-conv_xx12_01Ax: as_u32(dst) = sx24s((u_int32_t)(as_u16c(src) ^ 0x80) << 8); goto CONV_END;
-conv_xx12_A100: as_u32(dst) = (u_int32_t)bswap_16(as_u16c(src) ^ 0x80) << 16; goto CONV_END;
-conv_xx12_001A: as_u32(dst) = (u_int32_t)(as_u16c(src) ^ 0x80); goto CONV_END;
+conv_xx12_xA10: as_u32(dst) = sx24((uint32_t)bswap_16(as_u16c(src) ^ 0x80) << 8); goto CONV_END;
+conv_xx12_01Ax: as_u32(dst) = sx24s((uint32_t)(as_u16c(src) ^ 0x80) << 8); goto CONV_END;
+conv_xx12_A100: as_u32(dst) = (uint32_t)bswap_16(as_u16c(src) ^ 0x80) << 16; goto CONV_END;
+conv_xx12_001A: as_u32(dst) = (uint32_t)(as_u16c(src) ^ 0x80); goto CONV_END;
 conv_x123_xxx1: as_u8(dst) = as_u32c(src) >> 16; goto CONV_END;
 conv_x123_xx12: as_u16(dst) = as_u32c(src) >> 8; goto CONV_END;
 conv_x123_xx21: as_u16(dst) = bswap_16(as_u32c(src) >> 8); goto CONV_END;
@@ -376,8 +376,8 @@ static void *const get16_labels[4 * 2 * 2 + 4 * 3] = {
 
 #ifdef GET16_END
 while(0) {
-get16_1_10: sample = (u_int16_t)as_u8c(src) << 8; goto GET16_END;
-get16_1_90: sample = (u_int16_t)(as_u8c(src) ^ 0x80) << 8; goto GET16_END;
+get16_1_10: sample = (uint16_t)as_u8c(src) << 8; goto GET16_END;
+get16_1_90: sample = (uint16_t)(as_u8c(src) ^ 0x80) << 8; goto GET16_END;
 get16_12_12: sample = as_u16c(src); goto GET16_END;
 get16_12_92: sample = as_u16c(src) ^ 0x8000; goto GET16_END;
 get16_12_21: sample = bswap_16(as_u16c(src)); goto GET16_END;
@@ -448,26 +448,26 @@ put16_12_12: as_u16(dst) = sample; goto PUT16_END;
 put16_12_92: as_u16(dst) = sample ^ 0x8000; goto PUT16_END;
 put16_12_21: as_u16(dst) = bswap_16(sample); goto PUT16_END;
 put16_12_29: as_u16(dst) = bswap_16(sample) ^ 0x80; goto PUT16_END;
-put16_12_0120: as_u32(dst) = sx24((u_int32_t)sample << 8); goto PUT16_END;
-put16_12_0920: as_u32(dst) = sx24((u_int32_t)(sample ^ 0x8000) << 8); goto PUT16_END;
-put16_12_0210: as_u32(dst) = sx24s((u_int32_t)bswap_16(sample) << 8); goto PUT16_END;
-put16_12_0290: as_u32(dst) = sx24s((u_int32_t)(bswap_16(sample) ^ 0x80) << 8); goto PUT16_END;
-put16_12_1200: as_u32(dst) = (u_int32_t)sample << 16; goto PUT16_END;
-put16_12_9200: as_u32(dst) = (u_int32_t)(sample ^ 0x8000) << 16; goto PUT16_END;
-put16_12_0021: as_u32(dst) = (u_int32_t)bswap_16(sample); goto PUT16_END;
-put16_12_0029: as_u32(dst) = (u_int32_t)bswap_16(sample) ^ 0x80; goto PUT16_END;
-put16_12_120: _put_triple(dst, (u_int32_t)sample << 8); goto PUT16_END;
-put16_12_920: _put_triple(dst, (u_int32_t)(sample ^ 0x8000) << 8); goto PUT16_END;
-put16_12_021: _put_triple_s(dst, (u_int32_t)sample << 8); goto PUT16_END;
-put16_12_029: _put_triple_s(dst, (u_int32_t)(sample ^ 0x8000) << 8); goto PUT16_END;
-put16_12_120_20: _put_triple(dst, (u_int32_t)sample << 4); goto PUT16_END;
-put16_12_920_20: _put_triple(dst, (u_int32_t)(sample ^ 0x8000) << 4); goto PUT16_END;
-put16_12_021_20: _put_triple_s(dst, (u_int32_t)sample << 4); goto PUT16_END;
-put16_12_029_20: _put_triple_s(dst, (u_int32_t)(sample ^ 0x8000) << 4); goto PUT16_END;
-put16_12_120_18: _put_triple(dst, (u_int32_t)sample << 2); goto PUT16_END;
-put16_12_920_18: _put_triple(dst, (u_int32_t)(sample ^ 0x8000) << 2); goto PUT16_END;
-put16_12_021_18: _put_triple_s(dst, (u_int32_t)sample << 2); goto PUT16_END;
-put16_12_029_18: _put_triple_s(dst, (u_int32_t)(sample ^ 0x8000) << 2); goto PUT16_END;
+put16_12_0120: as_u32(dst) = sx24((uint32_t)sample << 8); goto PUT16_END;
+put16_12_0920: as_u32(dst) = sx24((uint32_t)(sample ^ 0x8000) << 8); goto PUT16_END;
+put16_12_0210: as_u32(dst) = sx24s((uint32_t)bswap_16(sample) << 8); goto PUT16_END;
+put16_12_0290: as_u32(dst) = sx24s((uint32_t)(bswap_16(sample) ^ 0x80) << 8); goto PUT16_END;
+put16_12_1200: as_u32(dst) = (uint32_t)sample << 16; goto PUT16_END;
+put16_12_9200: as_u32(dst) = (uint32_t)(sample ^ 0x8000) << 16; goto PUT16_END;
+put16_12_0021: as_u32(dst) = (uint32_t)bswap_16(sample); goto PUT16_END;
+put16_12_0029: as_u32(dst) = (uint32_t)bswap_16(sample) ^ 0x80; goto PUT16_END;
+put16_12_120: _put_triple(dst, (uint32_t)sample << 8); goto PUT16_END;
+put16_12_920: _put_triple(dst, (uint32_t)(sample ^ 0x8000) << 8); goto PUT16_END;
+put16_12_021: _put_triple_s(dst, (uint32_t)sample << 8); goto PUT16_END;
+put16_12_029: _put_triple_s(dst, (uint32_t)(sample ^ 0x8000) << 8); goto PUT16_END;
+put16_12_120_20: _put_triple(dst, (uint32_t)sample << 4); goto PUT16_END;
+put16_12_920_20: _put_triple(dst, (uint32_t)(sample ^ 0x8000) << 4); goto PUT16_END;
+put16_12_021_20: _put_triple_s(dst, (uint32_t)sample << 4); goto PUT16_END;
+put16_12_029_20: _put_triple_s(dst, (uint32_t)(sample ^ 0x8000) << 4); goto PUT16_END;
+put16_12_120_18: _put_triple(dst, (uint32_t)sample << 2); goto PUT16_END;
+put16_12_920_18: _put_triple(dst, (uint32_t)(sample ^ 0x8000) << 2); goto PUT16_END;
+put16_12_021_18: _put_triple_s(dst, (uint32_t)sample << 2); goto PUT16_END;
+put16_12_029_18: _put_triple_s(dst, (uint32_t)(sample ^ 0x8000) << 2); goto PUT16_END;
 }
 #endif
 
@@ -517,12 +517,12 @@ static void *const get32_labels[4 * 2 * 2 + 4 * 3] = {
 
 #ifdef GET32_END
 while (0) {
-get32_1_1000: sample = (u_int32_t)as_u8c(src) << 24; goto GET32_END;
-get32_1_9000: sample = (u_int32_t)(as_u8c(src) ^ 0x80) << 24; goto GET32_END;
-get32_12_1200: sample = (u_int32_t)as_u16c(src) << 16; goto GET32_END;
-get32_12_9200: sample = (u_int32_t)(as_u16c(src) ^ 0x8000) << 16; goto GET32_END;
-get32_12_2100: sample = (u_int32_t)bswap_16(as_u16c(src)) << 16; goto GET32_END;
-get32_12_A100: sample = (u_int32_t)bswap_16(as_u16c(src) ^ 0x80) << 16; goto GET32_END;
+get32_1_1000: sample = (uint32_t)as_u8c(src) << 24; goto GET32_END;
+get32_1_9000: sample = (uint32_t)(as_u8c(src) ^ 0x80) << 24; goto GET32_END;
+get32_12_1200: sample = (uint32_t)as_u16c(src) << 16; goto GET32_END;
+get32_12_9200: sample = (uint32_t)(as_u16c(src) ^ 0x8000) << 16; goto GET32_END;
+get32_12_2100: sample = (uint32_t)bswap_16(as_u16c(src)) << 16; goto GET32_END;
+get32_12_A100: sample = (uint32_t)bswap_16(as_u16c(src) ^ 0x80) << 16; goto GET32_END;
 get32_0123_1230: sample = as_u32c(src) << 8; goto GET32_END;
 get32_0123_9230: sample = (as_u32c(src) << 8) ^ 0x80000000; goto GET32_END;
 get32_1230_3210: sample = bswap_32(as_u32c(src) >> 8); goto GET32_END;
@@ -786,18 +786,18 @@ static inline void _norms(const void *src, void *dst,
 		s += (1U << (dst_wid - 1));
 	switch (dst_wid) {
 	case 8:
-		*(u_int8_t*)dst = s;
+		*(uint8_t*)dst = s;
 		break;
 	case 16:
 		if (dst_end)
 			s = bswap_16(s);
-		*(u_int16_t*)dst = s;
+		*(uint16_t*)dst = s;
 		break;
 	case 24:
 	case 32:
 		if (dst_end)
 			s = bswap_32(s);
-		*(u_int32_t*)dst = s;
+		*(uint32_t*)dst = s;
 		break;
 	}
 	return;
@@ -806,27 +806,27 @@ static inline void _norms(const void *src, void *dst,
 	switch (dst_wid) {
 	case 8:
 		if (dst_sign)
-			*(u_int8_t*)dst = 0x80;
+			*(uint8_t*)dst = 0x80;
 		else
-			*(u_int8_t*)dst = 0;
+			*(uint8_t*)dst = 0;
 		break;
 	case 16:
 		if (dst_sign)
-			*(u_int16_t*)dst = dst_end ? 0x0080 : 0x8000;
+			*(uint16_t*)dst = dst_end ? 0x0080 : 0x8000;
 		else
-			*(u_int16_t*)dst = 0;
+			*(uint16_t*)dst = 0;
 		break;
 	case 24:
 		if (dst_sign)
-			*(u_int32_t*)dst = dst_end ? 0x00008000 : 0x00800000;
+			*(uint32_t*)dst = dst_end ? 0x00008000 : 0x00800000;
 		else
-			*(u_int32_t*)dst = 0;
+			*(uint32_t*)dst = 0;
 		break;
 	case 32:
 		if (dst_sign)
-			*(u_int32_t*)dst = dst_end ? 0x00000080 : 0x80000000;
+			*(uint32_t*)dst = dst_end ? 0x00000080 : 0x80000000;
 		else
-			*(u_int32_t*)dst = 0;
+			*(uint32_t*)dst = 0;
 		break;
 	default:
 		assert(0);
@@ -838,27 +838,27 @@ static inline void _norms(const void *src, void *dst,
 	switch (dst_wid) {
 	case 8:
 		if (dst_sign)
-			*(u_int8_t*)dst = 0x7f;
+			*(uint8_t*)dst = 0x7f;
 		else
-			*(u_int8_t*)dst = 0xff;
+			*(uint8_t*)dst = 0xff;
 		break;
 	case 16:
 		if (dst_sign)
-			*(u_int16_t*)dst = dst_end ? 0xff7f : 0x7fff;
+			*(uint16_t*)dst = dst_end ? 0xff7f : 0x7fff;
 		else
-			*(u_int16_t*)dst = 0;
+			*(uint16_t*)dst = 0;
 		break;
 	case 24:
 		if (dst_sign)
-			*(u_int32_t*)dst = dst_end ? 0xffff7f00 : 0x007fffff;
+			*(uint32_t*)dst = dst_end ? 0xffff7f00 : 0x007fffff;
 		else
-			*(u_int32_t*)dst = 0;
+			*(uint32_t*)dst = 0;
 		break;
 	case 32:
 		if (dst_sign)
-			*(u_int32_t*)dst = dst_end ? 0xffffff7f : 0x7fffffff;
+			*(uint32_t*)dst = dst_end ? 0xffffff7f : 0x7fffffff;
 		else
-			*(u_int32_t*)dst = 0;
+			*(uint32_t*)dst = 0;
 		break;
 	default:
 		assert(0);
-- 
2.13.5


From cb34cee0d8da2fb131986d5782ddf5cec985c532 Mon Sep 17 00:00:00 2001
From: Natanael Copa <ncopa@alpinelinux.org>
Date: Fri, 14 Jul 2017 18:47:05 +0200
Subject: [PATCH 28/39] snd_user_file: avoid use wordexp

As suggested in POSIX[1], wordexp might execute the shell. If the libc
implementation does so, it will break the firefox sandbox which does
not allow exec. This happened on Alpine Linux with musl libc[2].

Since we cannot guarantee that the system wordexp implementation does
not execute shell, we cannot really use it, and need to implement the
~/ expansion ourselves.

We provide a configure option --with-wordexp for users that still may
need it, but we leave this off by default because wordexp is a large
attack vector and it is better to avoid it.

[1]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/wordexp.html#tag_16_684_08
[2]: http://bugs.alpinelinux.org/issues/7454#note-2

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 configure.ac   | 19 ++++++++++++++++-
 src/userfile.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 75 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 26e5d125..fbcfa829 100644
--- a/configure.ac
+++ b/configure.ac
@@ -303,8 +303,25 @@ fi
 
 AC_SUBST(ALSA_DEPLIBS)
 
+dnl Check for use of wordexp...
+AC_MSG_CHECKING(for use of wordexp)
+AC_ARG_WITH(wordexp,
+  AS_HELP_STRING([--with-wordexp],
+    [Use wordexp when expanding configs (default = no)]),
+  [case "$withval" in
+	y|yes) wordexp=yes ;;
+	*) wordexp=no ;;
+   esac],)
+if test "$wordexp" = "yes" ; then
+  AC_DEFINE(HAVE_WORDEXP, "1", [Enable use of wordexp])
+  AC_MSG_RESULT(yes)
+  AC_CHECK_HEADER([wordexp.h],[], [AC_MSG_ERROR([Couldn't find wordexp.h])])
+else
+  AC_MSG_RESULT(no)
+fi
+
 dnl Check for headers
-AC_CHECK_HEADERS([wordexp.h endian.h sys/endian.h sys/shm.h])
+AC_CHECK_HEADERS([endian.h sys/endian.h sys/shm.h])
 
 dnl Check for resmgr support...
 AC_MSG_CHECKING(for resmgr support)
diff --git a/src/userfile.c b/src/userfile.c
index 72779da4..f2145470 100644
--- a/src/userfile.c
+++ b/src/userfile.c
@@ -21,6 +21,7 @@
 #include <config.h>
 #include <string.h>
 #include <errno.h>
+#include <assert.h>
 
 /**
  * \brief Get the full file name
@@ -32,14 +33,13 @@
  * stores the first matchine one.  The returned string is strdup'ed.
  */
 
-#ifdef HAVE_WORDEXP_H
+#ifdef HAVE_WORDEXP
 #include <wordexp.h>
-#include <assert.h>
 int snd_user_file(const char *file, char **result)
 {
 	wordexp_t we;
 	int err;
-	
+
 	assert(file && result);
 	err = wordexp(file, &we, WRDE_NOCMD);
 	switch (err) {
@@ -61,13 +61,62 @@ int snd_user_file(const char *file, char **result)
 	return 0;
 }
 
-#else /* !HAVE_WORDEXP_H */
-/* just copy the string - would be nicer to expand by ourselves, though... */
+#else /* !HAVE_WORDEX */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
 int snd_user_file(const char *file, char **result)
 {
-	*result = strdup(file);
-	if (! *result)
+	int err;
+	size_t len;
+	char *buf = NULL;
+
+	assert(file && result);
+	*result = NULL;
+
+	/* expand ~/ if needed */
+	if (file[0] == '~' && file[1] == '/') {
+		const char *home = getenv("HOME");
+		if (home == NULL) {
+			struct passwd pwent, *p = NULL;
+			uid_t id = getuid();
+			size_t bufsize = 1024;
+
+			buf = malloc(bufsize);
+			if (buf == NULL)
+				goto out;
+
+			while ((err = getpwuid_r(id, &pwent, buf, bufsize, &p)) == ERANGE) {
+				char *newbuf;
+				bufsize += 1024;
+				if (bufsize < 1024)
+					break;
+				newbuf = realloc(buf, bufsize);
+				if (newbuf == NULL)
+					goto out;
+				buf = newbuf;
+			}
+			home = err ? "" : pwent.pw_dir;
+		}
+		len = strlen(home) + strlen(&file[2]) + 2;
+		*result = malloc(len);
+		if (*result)
+			snprintf(*result, len, "%s/%s", home, &file[2]);
+	} else {
+		*result = strdup(file);
+	}
+
+out:
+	if (buf)
+		free(buf);
+
+	if (*result == NULL)
 		return -ENOMEM;
 	return 0;
 }
-#endif /* HAVE_WORDEXP_H */
+
+#endif /* HAVE_WORDEXP */
-- 
2.13.5


From c01dc3fa4899a9b9948629c103c0bc435d4f1574 Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Date: Thu, 10 Aug 2017 13:36:16 +0200
Subject: [PATCH 29/39] conf/ucm: DB410c-HiFi: add CIC selection

This patch adds CIC selection controls which have been added recently to
the kernel to select mic source.

Without this patch user has to manually select the control to record
from DMIC or AMIC.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/conf/ucm/DB410c/HiFi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/conf/ucm/DB410c/HiFi b/src/conf/ucm/DB410c/HiFi
index f9cbcf05..dcb7ac98 100644
--- a/src/conf/ucm/DB410c/HiFi
+++ b/src/conf/ucm/DB410c/HiFi
@@ -108,6 +108,7 @@ SectionDevice."Handset" {
 	EnableSequence [
 		cdev "hw:0"
 		cset "name='DEC1 MUX' ADC2"
+		cset "name='CIC1 MUX' AMIC"
 		cset "name='ADC2 Volume' 8"
 		cset "name='ADC2 MUX' INP2"
 	]
@@ -130,6 +131,7 @@ SectionDevice."Primarymic" {
 	EnableSequence [
 		cdev "hw:0"
 		cset "name='DEC1 MUX' ADC1"
+		cset "name='CIC1 MUX' AMIC"
 		cset "name='ADC1 Volume' 8"
 	]
 
@@ -150,6 +152,7 @@ SectionDevice."Secondarymic" {
 	EnableSequence [
 		cdev "hw:0"
 		cset "name='DEC1 MUX' ADC2"
+		cset "name='CIC1 MUX' AMIC"
 		cset "name='ADC2 Volume' 8"
 		cset "name='ADC2 MUX' INP2"
 	]
@@ -172,6 +175,7 @@ SectionDevice."DMIC" {
 	EnableSequence [
 		cdev "hw:0"
 		cset "name='DEC1 MUX' DMIC1"
+		cset "name='CIC1 MUX' DMIC"
 	]
 
 	DisableSequence [
-- 
2.13.5


From 97da58213a7f56850468fc74726f255a5739cb49 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Fri, 11 Aug 2017 23:24:03 +0200
Subject: [PATCH 30/39] rawmidi: symbols: use rawmidi_virt only when available

src/rawmidi/Makefile.am only brings rawmidi_virt.c into the build when
BUILD_SEQ is defined (i.e when --enable-seq is passed). However,
rawmidi_symbols.c unconditionally refers to _snd_module_rawmidi_virt,
defined in rawmidi_virt.c.

This causes a link failure when BUILD_SEQ is disabled. For example
when linking ffmpeg against alsa-lib:

/home/thomas/projets/buildroot/output/host/arm-buildroot-linux-uclibcgnueabi/sysroot/usr/lib/libasound.a(pcm_dmix.o): In function `snd_pcm_dmix_sync_ptr':
pcm_dmix.c:(.text+0x83c): warning:
/home/thomas/projets/buildroot/output/host/arm-buildroot-linux-uclibcgnueabi/sysroot/usr/lib/libasound.a(rawmidi_symbols.o):(.data+0x4): undefined reference to `_snd_module_rawmidi_virt'
collect2: error: ld returned 1 exit status

To fix this, we make sure that rawmidi_symbols.c only uses
_snd_module_rawmidi_virt when available.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/rawmidi/rawmidi_symbols.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/rawmidi/rawmidi_symbols.c b/src/rawmidi/rawmidi_symbols.c
index cdc06d7f..64734334 100644
--- a/src/rawmidi/rawmidi_symbols.c
+++ b/src/rawmidi/rawmidi_symbols.c
@@ -21,11 +21,15 @@
 #ifndef PIC
 
 extern const char *_snd_module_rawmidi_hw;
+#ifdef BUILD_SEQ
 extern const char *_snd_module_rawmidi_virt;
+#endif
 
 static const char **snd_rawmidi_open_objects[] = {
 	&_snd_module_rawmidi_hw,
+#ifdef BUILD_SEQ
 	&_snd_module_rawmidi_virt
+#endif
 };
 	
 void *snd_rawmidi_open_symbols(void)
-- 
2.13.5


From 80bd4ce1478efdc08189c82a74da183da591c0fb Mon Sep 17 00:00:00 2001
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Date: Wed, 16 Aug 2017 11:08:48 -0500
Subject: [PATCH 31/39] conf: HdmiLpeAudio: add support for 3 devices

The LPE Audio mode on BYT/CHT supports up to 3 devices, and also supports
IEC61937 passthrough. Add missing alsa-lib configurations so that
apps can use the usual -D'hdmi:CARD=X,DEV=Y,AES0=0x[4|6]' syntax, e.g.

aplay -D'hdmi:CARD=0,DEV=2,AES0=0x6' -c2 -r48000 -fs16_le
ac3_surround_test.spdif

Tested on Zotac PI330 with Onkyo receiver

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/conf/cards/HdmiLpeAudio.conf | 77 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/src/conf/cards/HdmiLpeAudio.conf b/src/conf/cards/HdmiLpeAudio.conf
index dae71fac..9fa30da0 100644
--- a/src/conf/cards/HdmiLpeAudio.conf
+++ b/src/conf/cards/HdmiLpeAudio.conf
@@ -56,6 +56,83 @@ HdmiLpeAudio.pcm.hdmi.0 {
 			{
 				interface PCM
 				name "IEC958 Playback Default"
+				device 0
+				lock true
+				preserve true
+				value [ $AES0 $AES1 $AES2 $AES3 ]
+			}
+		]
+	}
+}
+
+HdmiLpeAudio.pcm.hdmi.1 {
+	@args [ CARD AES0 AES1 AES2 AES3 ]
+	@args.CARD {
+		type string
+	}
+	@args.AES0 {
+		type integer
+	}
+	@args.AES1 {
+		type integer
+	}
+	@args.AES2 {
+		type integer
+	}
+	@args.AES3 {
+		type integer
+	}
+	type hooks
+	slave.pcm {
+		type hw
+		card $CARD
+		device 1
+	}
+	hooks.0 {
+		type ctl_elems
+		hook_args [
+			{
+				interface PCM
+				name "IEC958 Playback Default"
+				device 1
+				lock true
+				preserve true
+				value [ $AES0 $AES1 $AES2 $AES3 ]
+			}
+		]
+	}
+}
+
+HdmiLpeAudio.pcm.hdmi.2 {
+	@args [ CARD AES0 AES1 AES2 AES3 ]
+	@args.CARD {
+		type string
+	}
+	@args.AES0 {
+		type integer
+	}
+	@args.AES1 {
+		type integer
+	}
+	@args.AES2 {
+		type integer
+	}
+	@args.AES3 {
+		type integer
+	}
+	type hooks
+	slave.pcm {
+		type hw
+		card $CARD
+		device 2
+	}
+	hooks.0 {
+		type ctl_elems
+		hook_args [
+			{
+				interface PCM
+				name "IEC958 Playback Default"
+				device 2
 				lock true
 				preserve true
 				value [ $AES0 $AES1 $AES2 $AES3 ]
-- 
2.13.5


From 52826d4655fac9fa86600d5238391eb2c8ca8092 Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Tue, 22 Aug 2017 10:16:05 +0100
Subject: [PATCH 32/39] topology: Fix private data for BEs

Private data was not being added to BEs. Fix this.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/topology/data.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/topology/data.c b/src/topology/data.c
index 5b83b9fc..f96ff9bb 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -50,7 +50,9 @@ struct snd_soc_tplg_private *get_priv_data(struct tplg_elem *elem)
 	case SND_TPLG_TYPE_DAI:
 		priv = &elem->dai->priv;
 		break;
-
+	case SND_TPLG_TYPE_BE:
+		priv = &elem->link->priv;
+		break;
 	default:
 		SNDERR("error: '%s': no support for private data for type %d\n",
 			elem->id, elem->type);
-- 
2.13.5


From 5efdabc1ab60f443f7183e50fea99510d0e3fe77 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Thu, 24 Aug 2017 10:48:35 +0900
Subject: [PATCH 33/39] test: apply optimization for v4.14 kernel about changes
 for TLV data handling on user-defined element set

At kernel v4.14, in initial state, elements on user-defined sets have
write-only flag. When applications write TLV data, then the elements
get readable flag and the TLV data is available. Originally TLV data
is shared by elements in the same set, thus events are generated for
all of elements in the set by the write operation.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 test/user-ctl-element-set.c | 84 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 73 insertions(+), 11 deletions(-)

diff --git a/test/user-ctl-element-set.c b/test/user-ctl-element-set.c
index 8635c156..f3710732 100644
--- a/test/user-ctl-element-set.c
+++ b/test/user-ctl-element-set.c
@@ -9,6 +9,7 @@
 
 #include "../include/asoundlib.h"
 #include <sound/tlv.h>
+#include <stdbool.h>
 
 struct elem_set_trial {
 	snd_ctl_t *handle;
@@ -28,6 +29,8 @@ struct elem_set_trial {
 				    snd_ctl_elem_value_t *elem_data);
 	int (*allocate_elem_set_tlv)(struct elem_set_trial *trial,
 				     unsigned int **tlv);
+
+	bool tlv_readable;
 };
 
 struct chmap_entry {
@@ -420,9 +423,9 @@ static int check_event(struct elem_set_trial *trial, unsigned int mask,
 			continue;
 		/*
 		 * I expect each event is generated separately to the same
-		 * element.
+		 * element or several events are generated at once.
 		 */
-		if (!(snd_ctl_event_elem_get_mask(event) & mask))
+		if ((snd_ctl_event_elem_get_mask(event) & mask) != mask)
 			continue;
 		--expected_count;
 	}
@@ -561,6 +564,16 @@ static int check_elem_set_props(struct elem_set_trial *trial)
 		if (!snd_ctl_elem_info_is_locked(info))
 			return -EIO;
 
+		/*
+		 * In initial state, any application can register TLV data for
+		 * user-defined element set except for IEC 958 type, thus
+		 * elements in any user-defined set should allow any write
+		 * operation.
+		 */
+		if (trial->type != SND_CTL_ELEM_TYPE_IEC958 &&
+		    !snd_ctl_elem_info_is_tlv_writable(info))
+			return -EIO;
+
 		/* Check type-specific properties. */
 		if (trial->check_elem_props != NULL) {
 			err = trial->check_elem_props(trial, info);
@@ -572,6 +585,25 @@ static int check_elem_set_props(struct elem_set_trial *trial)
 		err = snd_ctl_elem_unlock(trial->handle, id);
 		if (err < 0)
 			return err;
+
+		/*
+		 * Till kernel v4.14, ALSA control core allows elements in any
+		 * user-defined set to have TLV_READ flag even if they have no
+		 * TLV data in their initial state. In this case, any read
+		 * operation for TLV data should return -ENXIO.
+		 */
+		if (snd_ctl_elem_info_is_tlv_readable(info)) {
+			unsigned int data[32];
+			err = snd_ctl_elem_tlv_read(trial->handle, trial->id,
+						    data, sizeof(data));
+			if (err >= 0)
+				return -EIO;
+			if (err != -ENXIO)
+				return err;
+
+			trial->tlv_readable = true;
+		}
+
 	}
 
 	return 0;
@@ -619,6 +651,8 @@ static int check_elems(struct elem_set_trial *trial)
 static int check_tlv(struct elem_set_trial *trial)
 {
 	unsigned int *tlv;
+	int mask;
+	unsigned int count;
 	unsigned int len;
 	unsigned int *curr;
 	int err;
@@ -644,6 +678,36 @@ static int check_tlv(struct elem_set_trial *trial)
 	if (err < 0)
 		goto end;
 
+	/*
+	 * Since kernel v4.14, any write operation to an element in user-defined
+	 * set can change state of the other elements in the same set. In this
+	 * case, any TLV data is firstly available after the operation.
+	 */
+	if (!trial->tlv_readable) {
+		mask = SND_CTL_EVENT_MASK_INFO | SND_CTL_EVENT_MASK_TLV;
+		count = trial->element_count;
+	} else {
+		mask = SND_CTL_EVENT_MASK_TLV;
+		count = 1;
+	}
+	err = check_event(trial, mask, count);
+	if (err < 0)
+		goto end;
+	if (!trial->tlv_readable) {
+		snd_ctl_elem_info_t *info;
+		snd_ctl_elem_info_alloca(&info);
+
+		snd_ctl_elem_info_set_id(info, trial->id);
+		err = snd_ctl_elem_info(trial->handle, info);
+		if (err < 0)
+			return err;
+		if (!snd_ctl_elem_info_is_tlv_readable(info))
+			return -EIO;
+
+		/* Now TLV data is available for this element set. */
+		trial->tlv_readable = true;
+	}
+
 	err = snd_ctl_elem_tlv_read(trial->handle, trial->id, curr, len);
 	if (err < 0)
 		goto end;
@@ -690,6 +754,7 @@ int main(void)
 			trial.change_elem_members = change_bool_elem_members;
 			trial.allocate_elem_set_tlv =
 						allocate_bool_elem_set_tlv;
+			trial.tlv_readable = false;
 			break;
 		case SND_CTL_ELEM_TYPE_INTEGER:
 			trial.element_count = 900;
@@ -703,6 +768,7 @@ int main(void)
 			trial.change_elem_members = change_int_elem_members;
 			trial.allocate_elem_set_tlv =
 						allocate_int_elem_set_tlv;
+			trial.tlv_readable = false;
 			break;
 		case SND_CTL_ELEM_TYPE_ENUMERATED:
 			trial.element_count = 900;
@@ -715,6 +781,7 @@ int main(void)
 			trial.check_elem_props = check_enum_elem_props;
 			trial.change_elem_members = change_enum_elem_members;
 			trial.allocate_elem_set_tlv = NULL;
+			trial.tlv_readable = false;
 			break;
 		case SND_CTL_ELEM_TYPE_BYTES:
 			trial.element_count = 900;
@@ -728,6 +795,7 @@ int main(void)
 			trial.change_elem_members = change_bytes_elem_members;
 			trial.allocate_elem_set_tlv =
 						allocate_bytes_elem_set_tlv;
+			trial.tlv_readable = false;
 			break;
 		case SND_CTL_ELEM_TYPE_IEC958:
 			trial.element_count = 1;
@@ -740,6 +808,7 @@ int main(void)
 			trial.check_elem_props = NULL;
 			trial.change_elem_members = change_iec958_elem_members;
 			trial.allocate_elem_set_tlv = NULL;
+			trial.tlv_readable = false;
 			break;
 		case SND_CTL_ELEM_TYPE_INTEGER64:
 		default:
@@ -754,6 +823,7 @@ int main(void)
 			trial.change_elem_members = change_int64_elem_members;
 			trial.allocate_elem_set_tlv =
 						allocate_int64_elem_set_tlv;
+			trial.tlv_readable = false;
 			break;
 		}
 
@@ -784,7 +854,7 @@ int main(void)
 		/* Check properties of each element in this element set. */
 		err = check_elem_set_props(&trial);
 		if (err < 0) {
-			printf("Fail to check propetries of each element with "
+			printf("Fail to check properties of each element with "
 			       "%s type.\n",
 			       snd_ctl_elem_type_name(trial.type));
 			break;
@@ -822,14 +892,6 @@ int main(void)
 				       snd_ctl_elem_type_name(trial.type));
 				break;
 			}
-			err = check_event(&trial, SND_CTL_EVENT_MASK_TLV, 1);
-			if (err < 0) {
-				printf("Fail to check an event to change TLV"
-				       "data of an an element set with %s "
-				       "type.\n",
-				       snd_ctl_elem_type_name(trial.type));
-				break;
-			}
 		}
 
 		/* Test an operation to remove elements in this element set. */
-- 
2.13.5


From 8d6169514519a3f3246ad09dd1281e3a7d854d42 Mon Sep 17 00:00:00 2001
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Date: Tue, 12 Sep 2017 21:47:42 +0100
Subject: [PATCH 34/39] topology: fix usage of SND_TPLG_INDEX_ALL when checking
 routes

Make sure SND_TPLG_INDEX_ALL is used correctly when checking routes so
that connecting routes of different indexes does not emit any warnings.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/topology/dapm.c | 4 ++--
 src/topology/elem.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/topology/dapm.c b/src/topology/dapm.c
index 66892a66..0ddbf965 100644
--- a/src/topology/dapm.c
+++ b/src/topology/dapm.c
@@ -279,7 +279,7 @@ int tplg_build_routes(snd_tplg_t *tplg)
 
 		}
 		if (!tplg_elem_lookup(&tplg->widget_list, route->sink,
-			SND_TPLG_TYPE_DAPM_WIDGET, elem->index)) {
+			SND_TPLG_TYPE_DAPM_WIDGET, SND_TPLG_INDEX_ALL)) {
 			SNDERR("warning: undefined sink widget/stream '%s'\n",
 				route->sink);
 		}
@@ -302,7 +302,7 @@ int tplg_build_routes(snd_tplg_t *tplg)
 
 		}
 		if (!tplg_elem_lookup(&tplg->widget_list, route->source,
-			SND_TPLG_TYPE_DAPM_WIDGET, elem->index)) {
+			SND_TPLG_TYPE_DAPM_WIDGET, SND_TPLG_INDEX_ALL)) {
 			SNDERR("warning: Undefined source widget/stream '%s'\n",
 				route->source);
 		}
diff --git a/src/topology/elem.c b/src/topology/elem.c
index 89a4ac9f..9a7c7b75 100644
--- a/src/topology/elem.c
+++ b/src/topology/elem.c
@@ -123,7 +123,7 @@ struct tplg_elem *tplg_elem_lookup(struct list_head *base, const char* id,
 			return elem;
 		/* SND_TPLG_INDEX_ALL is the default value "0" and applicable
 		   for all use cases */
-		if ((elem->index != SND_TPLG_INDEX_ALL)
+		if ((index != SND_TPLG_INDEX_ALL)
 			&& (elem->index > index))
 			break;
 	}
-- 
2.13.5


From 6a617cc719d553ad8eb96308b7f3b94f5a53d243 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Krause?= <joerg.krause@embedded.rocks>
Date: Wed, 13 Sep 2017 16:21:10 +0200
Subject: [PATCH 35/39] pcm: softvol: add support for S24_LE
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Tested with the Wolfson WM8524 DAC on a i.MX6UL board and the following
ALSA configuration file using the pcm test utility from alsa-lib:

"""
$ cat /etc/asound.conf
pcm.!default {
    type plug
    slave.pcm "softvol"
}
pcm.softvol {
    type softvol
    slave {
        pcm "hw:0"
    }
    control {
        name "Master"
        card 0
    }
}
ctl.!default {
    type hw
    card 0
}
ctl.softvol {
    type hw
    card 0
}

$ pcm -D softvol -o S24_LE -c 2 -r 48000
"""

The data in the Synchronous Audio Interface (SAI) of the i.MX6UL is
aligned the following way:

"""
31 30 29 28 | 27 26 25 24 | 23 22 21 20 | .. | 3 2 1 0
## ## ## ##   ## ## ## ## [           DATA[23:0]       ]
"""

Signed-off-by: Jörg Krause <joerg.krause@embedded.rocks>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/pcm/pcm_softvol.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 53 insertions(+), 3 deletions(-)

diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c
index 1fe5784d..68a35b56 100644
--- a/src/pcm/pcm_softvol.c
+++ b/src/pcm/pcm_softvol.c
@@ -251,6 +251,44 @@ static inline short MULTI_DIV_short(short a, unsigned int b, int swap)
 		}							\
 	}								\
 } while (0)
+
+#define CONVERT_AREA_S24_LE() do {					\
+	unsigned int ch, fr;						\
+	int *src, *dst;							\
+	int tmp;							\
+	for (ch = 0; ch < channels; ch++) {				\
+		src_area = &src_areas[ch];				\
+		dst_area = &dst_areas[ch];				\
+		src = snd_pcm_channel_area_addr(src_area, src_offset);	\
+		dst = snd_pcm_channel_area_addr(dst_area, dst_offset);	\
+		src_step = snd_pcm_channel_area_step(src_area)		\
+				/ sizeof(int);				\
+		dst_step = snd_pcm_channel_area_step(dst_area)		\
+				/ sizeof(int);				\
+		GET_VOL_SCALE;						\
+		fr = frames;						\
+		if (! vol_scale) {					\
+			while (fr--) {					\
+				*dst = 0;				\
+				dst += dst_step;			\
+			}						\
+		} else if (vol_scale == 0xffff) {			\
+			while (fr--) {					\
+				*dst = *src;				\
+				src += dst_step;			\
+				dst += src_step;			\
+			}						\
+		} else {						\
+			while (fr--) {					\
+				tmp = *src << 8;			\
+				tmp = (signed int) tmp >> 8;		\
+				*dst = MULTI_DIV_24(tmp, vol_scale);	\
+				src += dst_step;			\
+				dst += src_step;			\
+			}						\
+		}							\
+	}								\
+} while (0)
 		
 #define GET_VOL_SCALE \
 	switch (ch) { \
@@ -315,6 +353,10 @@ static void softvol_convert_stereo_vol(snd_pcm_softvol_t *svol,
 		CONVERT_AREA(int,
 			     !snd_pcm_format_cpu_endian(svol->sformat));
 		break;
+	case SND_PCM_FORMAT_S24_LE:
+		/* 24bit samples */
+		CONVERT_AREA_S24_LE();
+		break;
 	case SND_PCM_FORMAT_S24_3LE:
 		CONVERT_AREA_S24_3LE();
 		break;
@@ -366,6 +408,10 @@ static void softvol_convert_mono_vol(snd_pcm_softvol_t *svol,
 		CONVERT_AREA(int,
 			     !snd_pcm_format_cpu_endian(svol->sformat));
 		break;
+	case SND_PCM_FORMAT_S24_LE:
+		/* 24bit samples */
+		CONVERT_AREA_S24_LE();
+		break;
 	case SND_PCM_FORMAT_S24_3LE:
 		CONVERT_AREA_S24_3LE();
 		break;
@@ -422,6 +468,7 @@ static int snd_pcm_softvol_hw_refine_cprepare(snd_pcm_t *pcm,
 		{
 			(1ULL << SND_PCM_FORMAT_S16_LE) |
 			(1ULL << SND_PCM_FORMAT_S16_BE) |
+			(1ULL << SND_PCM_FORMAT_S24_LE) |
 			(1ULL << SND_PCM_FORMAT_S32_LE) |
  			(1ULL << SND_PCM_FORMAT_S32_BE),
 			(1ULL << (SND_PCM_FORMAT_S24_3LE - 32))
@@ -577,10 +624,11 @@ static int snd_pcm_softvol_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * param
 	if (slave->format != SND_PCM_FORMAT_S16_LE &&
 	    slave->format != SND_PCM_FORMAT_S16_BE &&
 	    slave->format != SND_PCM_FORMAT_S24_3LE && 
+	    slave->format != SND_PCM_FORMAT_S24_LE &&
 	    slave->format != SND_PCM_FORMAT_S32_LE &&
 	    slave->format != SND_PCM_FORMAT_S32_BE) {
-		SNDERR("softvol supports only S16_LE, S16_BE, S24_3LE, S32_LE "
-		       " or S32_BE");
+		SNDERR("softvol supports only S16_LE, S16_BE, S24_LE, S24_3LE, "
+		       "S32_LE or S32_BE");
 		return -EINVAL;
 	}
 	svol->sformat = slave->format;
@@ -863,6 +911,7 @@ int snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
 	    sformat != SND_PCM_FORMAT_S16_LE &&
 	    sformat != SND_PCM_FORMAT_S16_BE &&
 	    sformat != SND_PCM_FORMAT_S24_3LE && 
+	    sformat != SND_PCM_FORMAT_S24_LE &&
 	    sformat != SND_PCM_FORMAT_S32_LE &&
 	    sformat != SND_PCM_FORMAT_S32_BE)
 		return -EINVAL;
@@ -1082,9 +1131,10 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
 		    sformat != SND_PCM_FORMAT_S16_LE &&
 		    sformat != SND_PCM_FORMAT_S16_BE &&
 		    sformat != SND_PCM_FORMAT_S24_3LE && 
+		    sformat != SND_PCM_FORMAT_S24_LE &&
 		    sformat != SND_PCM_FORMAT_S32_LE &&
 		    sformat != SND_PCM_FORMAT_S32_BE) {
-			SNDERR("only S16_LE, S16_BE, S24_3LE, S32_LE or S32_BE format is supported");
+			SNDERR("only S16_LE, S16_BE, S24_LE, S24_3LE, S32_LE or S32_BE format is supported");
 			snd_config_delete(sconf);
 			return -EINVAL;
 		}
-- 
2.13.5


From baed295faafb076d380392fa938234a7ec426dfc Mon Sep 17 00:00:00 2001
From: Antonio Ospite <ao2@ao2.it>
Date: Thu, 28 Sep 2017 15:46:15 +0200
Subject: [PATCH 36/39] seq: fix snd_seq_set_queue_tempo() usage example in the
 documentation

snd_seq_set_queue_tempo() requires a queue id as the second argument,
fix the example in documentation to reflect that.

Also add the queue id as an argument of the set_tempo() function, just
to keep the whole example compilable.

Signed-off-by: Antonio Ospite <ao2@ao2.it>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/seq/seq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/seq/seq.c b/src/seq/seq.c
index d5ed1c6a..808c7915 100644
--- a/src/seq/seq.c
+++ b/src/seq/seq.c
@@ -452,13 +452,13 @@ For setting these tempo parameters, use #snd_seq_queue_tempo_t record.
 For example, to set the tempo of the queue <code>q</code> to
 48 PPQ, 60 BPM,
 \code
-void set_tempo(snd_seq_t *handle)
+void set_tempo(snd_seq_t *handle, int queue)
 {
         snd_seq_queue_tempo_t *tempo;
         snd_seq_queue_tempo_alloca(&tempo);
         snd_seq_queue_tempo_set_tempo(tempo, 1000000); // 60 BPM
         snd_seq_queue_tempo_set_ppq(tempo, 48); // 48 PPQ
-        snd_seq_set_queue_tempo(handle, tempo);
+        snd_seq_set_queue_tempo(handle, queue, tempo);
 }
 \endcode
 
-- 
2.13.5


From 8c0b17bca3d641dc86d35eb1b97fae5fe4080984 Mon Sep 17 00:00:00 2001
From: Antonio Ospite <ao2@ao2.it>
Date: Tue, 26 Sep 2017 16:44:49 +0200
Subject: [PATCH 37/39] test/seq-decoder: enable timestamping for external
 subscribers

Events sent by external clients subscribed to the input port are not
timestamped.

This inconsistent behavior may surprise newbies who look at seq-decoder as
a reference example.

See the example below using "vkeybd --addr 128:0" to connect to seq-decoder,
the events sent by vkeybd are on a different queue with no timestamps:

  ...
  EVENT>>> Type = 66, flags = 0x0, time = 0 ticks
           Source = 0.1, dest = 128.0, queue = 253
           Event = Port Subscribed; 129:0 -> 128:0
  EVENT>>> Type = 66, flags = 0x1, time = 4.829712627
           Source = 0.1, dest = 128.0, queue = 0
           Event = Port Subscribed; 129:0 -> 128:0
  EVENT>>> Type = 10, flags = 0x0, time = 0 ticks
           Source = 129.0, dest = 128.0, queue = 253
           Event = Controller; ch=0, param=0, value=0
  EVENT>>> Type = 11, flags = 0x0, time = 0 ticks
           Source = 129.0, dest = 128.0, queue = 253
           Event = Program Change; ch=0, program=0
  ...

After the change events are on the main queue and are timestamped:

  ...
  EVENT>>> Type = 66, flags = 0x1, time = 4.280907223
           Source = 0.1, dest = 128.0, queue = 0
           Event = Port Subscribed; 129:0 -> 128:0
  EVENT>>> Type = 66, flags = 0x1, time = 4.280912063
           Source = 0.1, dest = 128.0, queue = 0
           Event = Port Subscribed; 129:0 -> 128:0
  EVENT>>> Type = 10, flags = 0x1, time = 4.280990702
           Source = 129.0, dest = 128.0, queue = 0
           Event = Controller; ch=0, param=0, value=0
  EVENT>>> Type = 11, flags = 0x1, time = 4.280994862
           Source = 129.0, dest = 128.0, queue = 0
           Event = Program Change; ch=0, program=0
  ...

Signed-off-by: Antonio Ospite <ao2@ao2.it>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 test/seq-decoder.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/test/seq-decoder.c b/test/seq-decoder.c
index b110e98d..38755553 100644
--- a/test/seq-decoder.c
+++ b/test/seq-decoder.c
@@ -283,6 +283,12 @@ void event_decoder(snd_seq_t *handle, int argc, char *argv[])
 	snd_seq_port_info_set_name(pinfo, "Input");
 	snd_seq_port_info_set_type(pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC);
 	snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_WRITE);
+
+	/* Enable timestamping for events sent by external subscribers. */
+	snd_seq_port_info_set_timestamping(pinfo, 1);
+	snd_seq_port_info_set_timestamp_real(pinfo, 1);
+	snd_seq_port_info_set_timestamp_queue(pinfo, queue);
+
 	if ((err = snd_seq_create_port(handle, pinfo)) < 0) {
 		fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err));
 		return;
-- 
2.13.5


From 98d2c12ac2f8dc7e92790e927f472e26459d3852 Mon Sep 17 00:00:00 2001
From: Timo Wischer <twischer@de.adit-jv.com>
Date: Thu, 5 Oct 2017 16:25:23 +0200
Subject: [PATCH 38/39] ctl: ext: Fail with error code if
 snd_ctl_ext_callback::read_event() callback is not defined

The snd_ctl_ext_callback::read_event() callback is only optional
if no poll descriptor was given via
snd_ctl_ext_t::poll_fd
or
snd_ctl_ext_callback::snd_ctl_ext_poll_descriptors().

If a poll descriptor is given the
snd_ctl_ext_callback::read_event()
callback has also to be defined
because there is no minigful default behavior.

This callback will be called when ever the poll() on
the file descriptor indicates that there is an event pending.
Therefore returning a 0 which indicates that there is no event makes no
sense.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/control/control_ext.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/control/control_ext.c b/src/control/control_ext.c
index 56552fa1..d7de8e84 100644
--- a/src/control/control_ext.c
+++ b/src/control/control_ext.c
@@ -415,8 +415,12 @@ static int snd_ctl_ext_read(snd_ctl_t *handle, snd_ctl_event_t *event)
 {
 	snd_ctl_ext_t *ext = handle->private_data;
 
-	memset(event, 0, sizeof(*event));
-	return ext->callback->read_event(ext, &event->data.elem.id, &event->data.elem.mask);
+	if (ext->callback->read_event) {
+		memset(event, 0, sizeof(*event));
+		return ext->callback->read_event(ext, &event->data.elem.id, &event->data.elem.mask);
+	}
+
+	return -EINVAL;
 }
 
 static int snd_ctl_ext_poll_descriptors_count(snd_ctl_t *handle)
-- 
2.13.5


From 996dd33b5f0df06d0b1fdd8f43b7a212c26e2a27 Mon Sep 17 00:00:00 2001
From: Tanu Kaskinen <tanuk@iki.fi>
Date: Wed, 4 Oct 2017 22:44:00 +0300
Subject: [PATCH 39/39] conf: HdmiLpeAudio: remove the "front" pcm definition

PulseAudio assumes that the "front" pcm device always refers to an
analog device, not HDMI. While that assumption is not really valid, the
reality is that without that assumption PulseAudio can't know whether
"front" and "hdmi" refer to a different or the same device.

The HDMI LPE driver doesn't allow audio streaming while the HDMI cable
is unplugged, so PulseAudio has to know when it's plugged in and when
it's not. If both "front" and "hdmi" devices exist, PulseAudio will
notice that HDMI is unplugged, but it doesn't know that "front" refers
to the same device, and PulseAudio will try to use the "front" device
with bad consequences. The kernel driver's refusal to stream any audio
makes PulseAudio enter an infinite loop and then the kernel kills
PulseAudio, because it consumes too much CPU time in a realtime thread.

While the looping in PulseAudio could probably be fixed, that wouldn't
change the fact that PulseAudio thinks that there is an analog device. I
believe it's best to avoid having the same device as both "front" and
"hdmi" in alsa-lib.

I removed also the surround configuration includes. I don't think they
had any effect anyway, so I wonder why they were there in the first
place.

BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 src/conf/cards/HdmiLpeAudio.conf | 24 ------------------------
 1 file changed, 24 deletions(-)

diff --git a/src/conf/cards/HdmiLpeAudio.conf b/src/conf/cards/HdmiLpeAudio.conf
index 9fa30da0..a1e493da 100644
--- a/src/conf/cards/HdmiLpeAudio.conf
+++ b/src/conf/cards/HdmiLpeAudio.conf
@@ -2,30 +2,6 @@
 # Configuration for the Intel HDMI/DP LPE audio
 #
 
-<confdir:pcm/front.conf>
-
-HdmiLpeAudio.pcm.front.0 {
-	@args [ CARD ]
-	@args.CARD {
-		type string
-	}
-	type softvol
-	slave.pcm {
-		type hw
-		card $CARD
-	}
-	control {
-		name "PCM Playback Volume"
-		card $CARD
-	}
-}
-
-<confdir:pcm/surround40.conf>
-<confdir:pcm/surround21.conf>
-<confdir:pcm/surround41.conf>
-<confdir:pcm/surround50.conf>
-<confdir:pcm/surround51.conf>
-
 <confdir:pcm/hdmi.conf>
 
 HdmiLpeAudio.pcm.hdmi.0 {
-- 
2.13.5

From 7f3ad37fd7e9327542be7f467ad337dd7398e2b7 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Sun, 22 Oct 2017 15:02:19 +0200
Subject: [PATCH] topology: fix coverity issues

---
 src/topology/ctl.c  | 6 +++---
 src/topology/dapm.c | 7 ++++++-
 src/topology/data.c | 7 +++----
 src/topology/elem.c | 4 +++-
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/topology/ctl.c b/src/topology/ctl.c
index e73d9eb7..9dd88db6 100644
--- a/src/topology/ctl.c
+++ b/src/topology/ctl.c
@@ -130,7 +130,7 @@ static int tplg_build_mixer_control(snd_tplg_t *tplg,
 	list_for_each(pos, base) {
 
 		ref = list_entry(pos, struct tplg_ref, list);
-		if (ref->id == NULL || ref->elem)
+		if (ref->elem)
 			continue;
 
 		if (ref->type == SND_TPLG_TYPE_TLV) {
@@ -180,7 +180,7 @@ static int tplg_build_enum_control(snd_tplg_t *tplg,
 	list_for_each(pos, base) {
 
 		ref = list_entry(pos, struct tplg_ref, list);
-		if (ref->id == NULL || ref->elem)
+		if (ref->elem)
 			continue;
 
 		if (ref->type == SND_TPLG_TYPE_TEXT) {
@@ -216,7 +216,7 @@ static int tplg_build_bytes_control(snd_tplg_t *tplg, struct tplg_elem *elem)
 	list_for_each(pos, base) {
 
 		ref = list_entry(pos, struct tplg_ref, list);
-		if (ref->id == NULL || ref->elem)
+		if (ref->elem)
 			continue;
 
 		 if (ref->type == SND_TPLG_TYPE_DATA) {
diff --git a/src/topology/dapm.c b/src/topology/dapm.c
index 0ddbf965..e5d473a8 100644
--- a/src/topology/dapm.c
+++ b/src/topology/dapm.c
@@ -428,7 +428,7 @@ int tplg_parse_dapm_graph(snd_tplg_t *tplg, snd_config_t *cfg,
 	snd_config_t *n;
 	int err;
 	const char *graph_id, *val = NULL;
-	int index;
+	int index = -1;
 
 	if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
 		SNDERR("error: compound is expected for dapm graph definition\n");
@@ -452,6 +452,11 @@ int tplg_parse_dapm_graph(snd_tplg_t *tplg, snd_config_t *cfg,
 		}
 
 		if (strcmp(id, "lines") == 0) {
+			if (index < 0) {
+				SNDERR("error: failed to parse dapm graph %s, missing index\n",
+					graph_id);
+				return -EINVAL;
+			}
 			err = tplg_parse_routes(tplg, n, index);
 			if (err < 0) {
 				SNDERR("error: failed to parse dapm graph %s\n",
diff --git a/src/topology/data.c b/src/topology/data.c
index f96ff9bb..6b7c3f6c 100644
--- a/src/topology/data.c
+++ b/src/topology/data.c
@@ -132,7 +132,6 @@ err:
 static void dump_priv_data(struct tplg_elem *elem)
 {
 	struct snd_soc_tplg_private *priv = elem->data;
-	unsigned char *p = (unsigned char *)priv->data;
 	unsigned int i, j = 0;
 
 	tplg_dbg(" elem size = %d, priv data size = %d\n",
@@ -366,7 +365,7 @@ static struct tplg_elem *get_tokens(snd_tplg_t *tplg, struct tplg_elem *elem)
 
 		ref = list_entry(pos, struct tplg_ref, list);
 
-		if (!ref->id || ref->type != SND_TPLG_TYPE_TOKEN)
+		if (ref->type != SND_TPLG_TYPE_TOKEN)
 			continue;
 
 		if (!ref->elem) {
@@ -390,7 +389,7 @@ static bool has_tuples(struct tplg_elem *elem)
 	list_for_each(pos, base) {
 
 		ref = list_entry(pos, struct tplg_ref, list);
-		if (ref->id && ref->type == SND_TPLG_TYPE_TUPLE)
+		if (ref->type == SND_TPLG_TYPE_TUPLE)
 			return true;
 	}
 
@@ -504,7 +503,7 @@ static int build_tuples(snd_tplg_t *tplg, struct tplg_elem *elem)
 
 		ref = list_entry(pos, struct tplg_ref, list);
 
-		if (!ref->id || ref->type != SND_TPLG_TYPE_TUPLE)
+		if (ref->type != SND_TPLG_TYPE_TUPLE)
 			continue;
 
 		tplg_dbg("tuples '%s' used by data '%s'\n", ref->id, elem->id);
diff --git a/src/topology/elem.c b/src/topology/elem.c
index 9a7c7b75..16ad4423 100644
--- a/src/topology/elem.c
+++ b/src/topology/elem.c
@@ -178,8 +178,10 @@ struct tplg_elem* tplg_elem_new_common(snd_tplg_t *tplg,
 			if (snd_config_get_id(n, &id))
 				continue;
 			if (strcmp(id, "index") == 0) {
-				if (snd_config_get_string(n, &val) < 0)
+				if (snd_config_get_string(n, &val) < 0) {
+					free(elem);
 					return NULL;
+				}
 				elem->index = atoi(val);
 			}
 		}
-- 
2.13.5