From e0581fe17fc34d68632eb2dbeac75bfcff59d2c7 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2018 05:13:51 +0000 Subject: import alsa-lib-1.1.6-2.el7 --- diff --git a/.alsa-lib.metadata b/.alsa-lib.metadata index 3dd896f..feeb5e3 100644 --- a/.alsa-lib.metadata +++ b/.alsa-lib.metadata @@ -1 +1 @@ -628634afbdc19054fca26d714aa6c2f1e41e465d SOURCES/alsa-lib-1.1.4.1.tar.bz2 +b96002ef24b4155e5d86c081869d8d7b4b496fde SOURCES/alsa-lib-1.1.6.tar.bz2 diff --git a/.gitignore b/.gitignore index f2718d2..745582a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/alsa-lib-1.1.4.1.tar.bz2 +SOURCES/alsa-lib-1.1.6.tar.bz2 diff --git a/SOURCES/alsa-lib-1.1.4.1-post.patch b/SOURCES/alsa-lib-1.1.4.1-post.patch deleted file mode 100644 index 3d26a42..0000000 --- a/SOURCES/alsa-lib-1.1.4.1-post.patch +++ /dev/null @@ -1,4493 +0,0 @@ -From 6d843ba5d377961f6765466ba0cc362dd10f7557 Mon Sep 17 00:00:00 2001 -From: Liam Girdwood -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 - #include - --#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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Tested-by: Takashi Sakamoto -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 - #include - #include -+#include - #include - #include - #include -@@ -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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Tested-by: Takashi Sakamoto -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 to [-Wcpp] - #warning redirecting incorrect #include to - ^~~~~~~ - -Signed-off-by: Natanael Copa -Signed-off-by: Takashi Iwai ---- - 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 - #include --#include -+#include - #include - #include - #include -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 - #include - #include --#include -+#include - #include - #include -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 --#include -+#include - #include - #include - #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 - #include - #include --#include -+#include - #include - #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 - #include - #include --#include -+#include - #include - #include - #include -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 - #include - #include --#include -+#include - #include - #include - #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 - #include - #include --#include -+#include - #include - #include - #include -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 - #include - #include --#include -+#include - #include - #ifdef HAVE_SYS_SHM_H - #include -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 - #include - #include --#include -+#include - #include - #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 - #include - #include --#include -+#include - #include - #include - #include -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 -+#include - #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 - #include - #include --#include -+#include - #include - #include - #include "list.h" --- -2.13.5 - - -From adab355f35c8fcb424b1336043634cf9a6856515 Mon Sep 17 00:00:00 2001 -From: Natanael Copa -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 -Signed-off-by: Takashi Iwai ---- - 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 -+ - /** - * \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 - #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 -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 -Signed-off-by: Takashi Iwai ---- - 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 - #include - #include -+#include - - /** - * \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 --#include - 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 -+#include -+#include -+#include -+#include -+ - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -+#include - - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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?= -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 q 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 -Signed-off-by: Takashi Iwai ---- - 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 -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 ---- - 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 - # - -- -- --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 -- } --} -- -- -- -- -- -- -- - - - HdmiLpeAudio.pcm.hdmi.0 { --- -2.13.5 - -From 7f3ad37fd7e9327542be7f467ad337dd7398e2b7 Mon Sep 17 00:00:00 2001 -From: Jaroslav Kysela -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 - diff --git a/SOURCES/alsa-lib-1.1.6-post.patch b/SOURCES/alsa-lib-1.1.6-post.patch new file mode 100644 index 0000000..cd02f49 --- /dev/null +++ b/SOURCES/alsa-lib-1.1.6-post.patch @@ -0,0 +1,2778 @@ +From 93e03bdc2a3dcd5d12516f5de78e14d88a32ff2c Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 4 Apr 2018 09:58:12 +0200 +Subject: [PATCH 01/26] alsa.conf: change the location for add-on configs to + /etc/alsa/conf.d + +The add-on configuration files should be placed to a volatile place. + +Signed-off-by: Jaroslav Kysela +--- + src/conf/alsa.conf | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf +index f22918fb..bb00ff40 100644 +--- a/src/conf/alsa.conf ++++ b/src/conf/alsa.conf +@@ -8,13 +8,7 @@ + { + func load + files [ +- { +- @func concat +- strings [ +- { @func datadir } +- "/alsa.conf.d/" +- ] +- } ++ "/etc/alsa/conf.d" + "/etc/asound.conf" + "~/.asoundrc" + ] +-- +2.13.6 + + +From 78505dccd23546cc77e5221cb21c01325bc0138d Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 4 Apr 2018 10:02:49 +0200 +Subject: [PATCH 02/26] conf: remove alsa.conf.d from the datadir + +Signed-off-by: Jaroslav Kysela +--- + src/conf/Makefile.am | 2 +- + src/conf/alsa.conf.d/Makefile.am | 8 -------- + src/conf/alsa.conf.d/README | 2 -- + 3 files changed, 1 insertion(+), 11 deletions(-) + delete mode 100644 src/conf/alsa.conf.d/Makefile.am + delete mode 100644 src/conf/alsa.conf.d/README + +diff --git a/src/conf/Makefile.am b/src/conf/Makefile.am +index ef2ea9c1..2b46f95c 100644 +--- a/src/conf/Makefile.am ++++ b/src/conf/Makefile.am +@@ -1,4 +1,4 @@ +-SUBDIRS=cards pcm alsa.conf.d ++SUBDIRS=cards pcm + + if BUILD_UCM + SUBDIRS += ucm +diff --git a/src/conf/alsa.conf.d/Makefile.am b/src/conf/alsa.conf.d/Makefile.am +deleted file mode 100644 +index c91661e9..00000000 +--- a/src/conf/alsa.conf.d/Makefile.am ++++ /dev/null +@@ -1,8 +0,0 @@ +-alsaconfigdir = @ALSA_CONFIG_DIR@ +-alsadir = $(alsaconfigdir)/alsa.conf.d +-cfg_files = README +- +-alsa_DATA = $(cfg_files) +- +-EXTRA_DIST = \ +- $(cfg_files) +diff --git a/src/conf/alsa.conf.d/README b/src/conf/alsa.conf.d/README +deleted file mode 100644 +index 99978848..00000000 +--- a/src/conf/alsa.conf.d/README ++++ /dev/null +@@ -1,2 +0,0 @@ +-You can place files named *.conf in this folder and they will be processed +-when initialising alsa-lib. +-- +2.13.6 + + +From 17bc74d3a25f0d4b1ca25d2d92fcad9c2a9d7f79 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Tue, 10 Apr 2018 08:57:07 +0200 +Subject: [PATCH 03/26] configure: remove src/conf/alsa.conf.d/Makefile + +Signed-off-by: Jaroslav Kysela +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index cce195ae..5bc1994f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -713,7 +713,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \ + src/rawmidi/Makefile src/timer/Makefile \ + src/hwdep/Makefile src/seq/Makefile src/ucm/Makefile \ + src/alisp/Makefile src/topology/Makefile \ +- src/conf/Makefile src/conf/alsa.conf.d/Makefile \ ++ src/conf/Makefile \ + src/conf/cards/Makefile \ + src/conf/pcm/Makefile \ + src/conf/ucm/Makefile \ +-- +2.13.6 + + +From 3778a30bb0095c7d3275735718f33058e3c198d5 Mon Sep 17 00:00:00 2001 +From: Kirill Marinushkin +Date: Mon, 16 Apr 2018 20:26:38 +0200 +Subject: [PATCH 04/26] ASoC: topology: Fix bclk and fsync inversion in + set_link_hw_format() + +The values of bclk and fsync are inverted WRT the codec. But the existing +solution already works for Broadwell, see the alsa-lib config: + +`alsa-lib/src/conf/topology/broadwell/broadwell.conf` + +This commit provides the backwards-compatible solution to fix this misuse. +This commit goes in pair with the corresponding patch for linux. + +Signed-off-by: Kirill Marinushkin +Reviewed-by: Pierre-Louis Bossart +Tested-by: Pan Xiuli +Tested-by: Pierre-Louis Bossart +Cc: Jaroslav Kysela +Cc: Takashi Iwai +Cc: Mark Brown +Cc: Liam Girdwood +Cc: linux-kernel@vger.kernel.org +Cc: alsa-devel@alsa-project.org +Signed-off-by: Takashi Iwai +--- + include/sound/asoc.h | 16 ++++++++++++++-- + include/topology.h | 4 ++-- + src/conf/topology/broadwell/broadwell.conf | 4 ++-- + src/topology/pcm.c | 30 ++++++++++++++++++++++++++---- + 4 files changed, 44 insertions(+), 10 deletions(-) + +diff --git a/include/sound/asoc.h b/include/sound/asoc.h +index 0f5d9f9a..89b00703 100644 +--- a/include/sound/asoc.h ++++ b/include/sound/asoc.h +@@ -156,6 +156,18 @@ + #define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2) + #define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP (1 << 3) + ++/* DAI topology BCLK parameter ++ * For the backwards capability, by default codec is bclk master ++ */ ++#define SND_SOC_TPLG_BCLK_CM 0 /* codec is bclk master */ ++#define SND_SOC_TPLG_BCLK_CS 1 /* codec is bclk slave */ ++ ++/* DAI topology FSYNC parameter ++ * For the backwards capability, by default codec is fsync master ++ */ ++#define SND_SOC_TPLG_FSYNC_CM 0 /* codec is fsync master */ ++#define SND_SOC_TPLG_FSYNC_CS 1 /* codec is fsync slave */ ++ + /* + * Block Header. + * This header precedes all object and object arrays below. +@@ -311,8 +323,8 @@ struct snd_soc_tplg_hw_config { + __u8 clock_gated; /* 1 if clock can be gated to save power */ + __u8 invert_bclk; /* 1 for inverted BCLK, 0 for normal */ + __u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */ +- __u8 bclk_master; /* 1 for master of BCLK, 0 for slave */ +- __u8 fsync_master; /* 1 for master of FSYNC, 0 for slave */ ++ __u8 bclk_master; /* SND_SOC_TPLG_BCLK_ value */ ++ __u8 fsync_master; /* SND_SOC_TPLG_FSYNC_ value */ + __u8 mclk_direction; /* 0 for input, 1 for output */ + __le16 reserved; /* for 32bit alignment */ + __le32 mclk_rate; /* MCLK or SYSCLK freqency in Hz */ +diff --git a/include/topology.h b/include/topology.h +index 8779da4d..5d7b46df 100644 +--- a/include/topology.h ++++ b/include/topology.h +@@ -1000,8 +1000,8 @@ struct snd_tplg_hw_config_template { + unsigned char clock_gated; /* 1 if clock can be gated to save power */ + unsigned char invert_bclk; /* 1 for inverted BCLK, 0 for normal */ + unsigned char invert_fsync; /* 1 for inverted frame clock, 0 for normal */ +- unsigned char bclk_master; /* 1 for master of BCLK, 0 for slave */ +- unsigned char fsync_master; /* 1 for master of FSYNC, 0 for slave */ ++ unsigned char bclk_master; /* SND_SOC_TPLG_BCLK_ value */ ++ unsigned char fsync_master; /* SND_SOC_TPLG_FSYNC_ value */ + unsigned char mclk_direction; /* 0 for input, 1 for output */ + unsigned short reserved; /* for 32bit alignment */ + unsigned int mclk_rate; /* MCLK or SYSCLK freqency in Hz */ +diff --git a/src/conf/topology/broadwell/broadwell.conf b/src/conf/topology/broadwell/broadwell.conf +index b8405d93..09fc4daa 100644 +--- a/src/conf/topology/broadwell/broadwell.conf ++++ b/src/conf/topology/broadwell/broadwell.conf +@@ -393,8 +393,8 @@ SectionGraph."dsp" { + SectionHWConfig."CodecHWConfig" { + id "1" + format "I2S" # physical audio format. +- bclk "master" # Platform is master of bit clock +- fsync "master" # platform is master of fsync ++ bclk "codec_slave" # platform is master of bit clock (codec is slave) ++ fsync "codec_slave" # platform is master of fsync (codec is slave) + } + + SectionLink."Codec" { +diff --git a/src/topology/pcm.c b/src/topology/pcm.c +index bb47b9af..d0395182 100644 +--- a/src/topology/pcm.c ++++ b/src/topology/pcm.c +@@ -1141,8 +1141,19 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +- if (!strcmp(val, "master")) +- hw_cfg->bclk_master = true; ++ if (!strcmp(val, "master")) { ++ /* For backwards capability, ++ * "master" == "codec is slave" ++ */ ++ SNDERR("warning: deprecated bclk value '%s'\n", ++ val); ++ ++ hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CS; ++ } else if (!strcmp(val, "codec_slave")) { ++ hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CS; ++ } else if (!strcmp(val, "codec_master")) { ++ hw_cfg->bclk_master = SND_SOC_TPLG_BCLK_CM; ++ } + continue; + } + +@@ -1167,8 +1178,19 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +- if (!strcmp(val, "master")) +- hw_cfg->fsync_master = true; ++ if (!strcmp(val, "master")) { ++ /* For backwards capability, ++ * "master" == "codec is slave" ++ */ ++ SNDERR("warning: deprecated fsync value '%s'\n", ++ val); ++ ++ hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CS; ++ } else if (!strcmp(val, "codec_slave")) { ++ hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CS; ++ } else if (!strcmp(val, "codec_master")) { ++ hw_cfg->fsync_master = SND_SOC_TPLG_FSYNC_CM; ++ } + continue; + } + +-- +2.13.6 + + +From bdb709ab2a091743980c9154950c01f0c540476b Mon Sep 17 00:00:00 2001 +From: Kirill Marinushkin +Date: Mon, 16 Apr 2018 20:26:39 +0200 +Subject: [PATCH 05/26] ASoC: topology: Add missing clock gating parameter when + parsing hw_configs + +Clock gating parameter is a part of `dai_fmt`. It is supported by +`alsa-lib` when creating a topology binary file, but ignored by kernel +when loading this topology file. + +After applying this commit, the clock gating parameter is not ignored any +more. This solution is backwards compatible. The existing behaviour is +not broken, because by default the parameter value is 0 and is ignored. + +snd_soc_tplg_hw_config.clock_gated = 0 => no effect +snd_soc_tplg_hw_config.clock_gated = 1 => SND_SOC_DAIFMT_GATED +snd_soc_tplg_hw_config.clock_gated = 2 => SND_SOC_DAIFMT_CONT + +For example, the following config, based on +alsa-lib/src/conf/topology/broadwell/broadwell.conf, is now supported: + +~~~~ +SectionHWConfig."CodecHWConfig" { + id "1" + format "I2S" # physical audio format. + pm_gate_clocks "true" # clock can be gated +} + +SectionLink."Codec" { + + # used for binding to the physical link + id "0" + + hw_configs [ + "CodecHWConfig" + ] + + default_hw_conf_id "1" +} +~~~~ + +Signed-off-by: Kirill Marinushkin +Reviewed-by: Pierre-Louis Bossart +Cc: Jaroslav Kysela +Cc: Takashi Iwai +Cc: Mark Brown +Cc: Pan Xiuli +Cc: Liam Girdwood +Cc: linux-kernel@vger.kernel.org +Cc: alsa-devel@alsa-project.org +Signed-off-by: Takashi Iwai +--- + include/sound/asoc.h | 7 ++++++- + include/topology.h | 2 +- + src/topology/pcm.c | 6 +++++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/include/sound/asoc.h b/include/sound/asoc.h +index 89b00703..297e837c 100644 +--- a/include/sound/asoc.h ++++ b/include/sound/asoc.h +@@ -135,6 +135,11 @@ + #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS (1 << 1) + #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS (1 << 2) + ++/* DAI clock gating */ ++#define SND_SOC_TPLG_DAI_CLK_GATE_UNDEFINED 0 ++#define SND_SOC_TPLG_DAI_CLK_GATE_GATED 1 ++#define SND_SOC_TPLG_DAI_CLK_GATE_CONT 2 ++ + /* DAI physical PCM data formats. + * Add new formats to the end of the list. + */ +@@ -320,7 +325,7 @@ struct snd_soc_tplg_hw_config { + __le32 size; /* in bytes of this structure */ + __le32 id; /* unique ID - - used to match */ + __le32 fmt; /* SND_SOC_DAI_FORMAT_ format value */ +- __u8 clock_gated; /* 1 if clock can be gated to save power */ ++ __u8 clock_gated; /* SND_SOC_TPLG_DAI_CLK_GATE_ value */ + __u8 invert_bclk; /* 1 for inverted BCLK, 0 for normal */ + __u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */ + __u8 bclk_master; /* SND_SOC_TPLG_BCLK_ value */ +diff --git a/include/topology.h b/include/topology.h +index 5d7b46df..3793115c 100644 +--- a/include/topology.h ++++ b/include/topology.h +@@ -997,7 +997,7 @@ struct snd_tplg_pcm_template { + struct snd_tplg_hw_config_template { + int id; /* unique ID - - used to match */ + unsigned int fmt; /* SND_SOC_DAI_FORMAT_ format value */ +- unsigned char clock_gated; /* 1 if clock can be gated to save power */ ++ unsigned char clock_gated; /* SND_SOC_TPLG_DAI_CLK_GATE_ value */ + unsigned char invert_bclk; /* 1 for inverted BCLK, 0 for normal */ + unsigned char invert_fsync; /* 1 for inverted frame clock, 0 for normal */ + unsigned char bclk_master; /* SND_SOC_TPLG_BCLK_ value */ +diff --git a/src/topology/pcm.c b/src/topology/pcm.c +index d0395182..b53f6b03 100644 +--- a/src/topology/pcm.c ++++ b/src/topology/pcm.c +@@ -1233,7 +1233,11 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + return -EINVAL; + + if (!strcmp(val, "true")) +- hw_cfg->clock_gated = true; ++ hw_cfg->clock_gated = ++ SND_SOC_TPLG_DAI_CLK_GATE_GATED; ++ else ++ hw_cfg->clock_gated = ++ SND_SOC_TPLG_DAI_CLK_GATE_CONT; + continue; + } + +-- +2.13.6 + + +From 7cf73b56e4505ad194f5789293494a6ebaa1feff Mon Sep 17 00:00:00 2001 +From: Kirill Marinushkin +Date: Mon, 16 Apr 2018 20:26:40 +0200 +Subject: [PATCH 06/26] ASoC: topology: Add definitions for mclk_direction + values + +Current comment makes not clear the direction of mclk. Previously, similar +description caused a misunderstanding for bclk_master and fsync_master. + +This commit solves the potential confusion the same way it is solved for +bclk_master and fsync_master. + +Signed-off-by: Kirill Marinushkin +Acked-by: Pierre-Louis Bossart +Cc: Jaroslav Kysela +Cc: Takashi Iwai +Cc: Mark Brown +Cc: Pan Xiuli +Cc: Liam Girdwood +Cc: alsa-devel@alsa-project.org +Signed-off-by: Takashi Iwai +--- + include/sound/asoc.h | 6 +++++- + include/topology.h | 2 +- + src/topology/pcm.c | 15 +++++++++++++-- + 3 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/include/sound/asoc.h b/include/sound/asoc.h +index 297e837c..bb8aec78 100644 +--- a/include/sound/asoc.h ++++ b/include/sound/asoc.h +@@ -140,6 +140,10 @@ + #define SND_SOC_TPLG_DAI_CLK_GATE_GATED 1 + #define SND_SOC_TPLG_DAI_CLK_GATE_CONT 2 + ++/* DAI mclk_direction */ ++#define SND_SOC_TPLG_MCLK_CO 0 /* for codec, mclk is output */ ++#define SND_SOC_TPLG_MCLK_CI 1 /* for codec, mclk is input */ ++ + /* DAI physical PCM data formats. + * Add new formats to the end of the list. + */ +@@ -330,7 +334,7 @@ struct snd_soc_tplg_hw_config { + __u8 invert_fsync; /* 1 for inverted frame clock, 0 for normal */ + __u8 bclk_master; /* SND_SOC_TPLG_BCLK_ value */ + __u8 fsync_master; /* SND_SOC_TPLG_FSYNC_ value */ +- __u8 mclk_direction; /* 0 for input, 1 for output */ ++ __u8 mclk_direction; /* SND_SOC_TPLG_MCLK_ value */ + __le16 reserved; /* for 32bit alignment */ + __le32 mclk_rate; /* MCLK or SYSCLK freqency in Hz */ + __le32 bclk_rate; /* BCLK freqency in Hz */ +diff --git a/include/topology.h b/include/topology.h +index 3793115c..27da7308 100644 +--- a/include/topology.h ++++ b/include/topology.h +@@ -1002,7 +1002,7 @@ struct snd_tplg_hw_config_template { + unsigned char invert_fsync; /* 1 for inverted frame clock, 0 for normal */ + unsigned char bclk_master; /* SND_SOC_TPLG_BCLK_ value */ + unsigned char fsync_master; /* SND_SOC_TPLG_FSYNC_ value */ +- unsigned char mclk_direction; /* 0 for input, 1 for output */ ++ unsigned char mclk_direction; /* SND_SOC_TPLG_MCLK_ value */ + unsigned short reserved; /* for 32bit alignment */ + unsigned int mclk_rate; /* MCLK or SYSCLK freqency in Hz */ + unsigned int bclk_rate; /* BCLK freqency in Hz */ +diff --git a/src/topology/pcm.c b/src/topology/pcm.c +index b53f6b03..2ce1651b 100644 +--- a/src/topology/pcm.c ++++ b/src/topology/pcm.c +@@ -1223,8 +1223,19 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +- if (!strcmp(val, "master")) +- hw_cfg->mclk_direction = true; ++ if (!strcmp(val, "master")) { ++ /* For backwards capability, ++ * "master" == "for codec, mclk is input" ++ */ ++ SNDERR("warning: deprecated mclk value '%s'\n", ++ val); ++ ++ hw_cfg->mclk_direction = SND_SOC_TPLG_MCLK_CI; ++ } else if (!strcmp(val, "codec_mclk_in")) { ++ hw_cfg->mclk_direction = SND_SOC_TPLG_MCLK_CI; ++ } else if (!strcmp(val, "codec_mclk_out")) { ++ hw_cfg->mclk_direction = SND_SOC_TPLG_MCLK_CO; ++ } + continue; + } + +-- +2.13.6 + + +From 4493f6a560a315970f5b068126120526a04ae6a2 Mon Sep 17 00:00:00 2001 +From: Kirill Marinushkin +Date: Mon, 16 Apr 2018 20:26:41 +0200 +Subject: [PATCH 07/26] ASoC: topology: Add alias conf parameter names for + hw_configs + +Currently, some parameter names in conf differ from field names in struct. +These look like typos. + +This commit suggests to add aliases for such parameters, so that the names +in conf are similar to names in struct. This solution is backwards +compatible. + +If the difference between conf names and struct names is done on purpose - +this commit can be dropped. + +Signed-off-by: Kirill Marinushkin +Acked-by: Pierre-Louis Bossart +Cc: Jaroslav Kysela +Cc: Takashi Iwai +Cc: Mark Brown +Cc: Pan Xiuli +Cc: Liam Girdwood +Cc: alsa-devel@alsa-project.org +Signed-off-by: Takashi Iwai +--- + src/topology/pcm.c | 30 ++++++++++++++++++++---------- + 1 file changed, 20 insertions(+), 10 deletions(-) + +diff --git a/src/topology/pcm.c b/src/topology/pcm.c +index 2ce1651b..8ebfafd8 100644 +--- a/src/topology/pcm.c ++++ b/src/topology/pcm.c +@@ -1126,7 +1126,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "format") == 0) { ++ if (strcmp(id, "format") == 0 || ++ strcmp(id, "fmt") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1137,7 +1138,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "bclk") == 0) { ++ if (strcmp(id, "bclk") == 0 || ++ strcmp(id, "bclk_master") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1157,7 +1159,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "bclk_freq") == 0) { ++ if (strcmp(id, "bclk_freq") == 0 || ++ strcmp(id, "bclk_rate") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1165,7 +1168,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "bclk_invert") == 0) { ++ if (strcmp(id, "bclk_invert") == 0 || ++ strcmp(id, "invert_bclk") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1174,7 +1178,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "fsync") == 0) { ++ if (strcmp(id, "fsync") == 0 || ++ strcmp(id, "fsync_master") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1194,7 +1199,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "fsync_invert") == 0) { ++ if (strcmp(id, "fsync_invert") == 0 || ++ strcmp(id, "invert_fsync") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1203,7 +1209,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "fsync_freq") == 0) { ++ if (strcmp(id, "fsync_freq") == 0 || ++ strcmp(id, "fsync_rate") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1211,7 +1218,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "mclk_freq") == 0) { ++ if (strcmp(id, "mclk_freq") == 0 || ++ strcmp(id, "mclk_rate") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1219,7 +1227,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "mclk") == 0) { ++ if (strcmp(id, "mclk") == 0 || ++ strcmp(id, "mclk_direction") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +@@ -1239,7 +1248,8 @@ int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, + continue; + } + +- if (strcmp(id, "pm_gate_clocks") == 0) { ++ if (strcmp(id, "pm_gate_clocks") == 0 || ++ strcmp(id, "clock_gated") == 0) { + if (snd_config_get_string(n, &val) < 0) + return -EINVAL; + +-- +2.13.6 + + +From 23a20cda111232b5d21dde12d10e19e4ecb71cea Mon Sep 17 00:00:00 2001 +From: Ricard Wanderlof +Date: Wed, 18 Apr 2018 17:03:09 +0200 +Subject: [PATCH 08/26] pcm: softvol: Allow up to 90 dB of gain + +The gain algorithm used in softvol can handle gain factors of up to +32767 which is slightly more than 90 dB, so allow a max_dB of 90 dB. +This doesn't affect existing asound.conf files, but does allow a +max_dB of up to 90 dB when needed. + +Tested using Audacity that there is no undue distorsion or other +artefacts when 90 dB of gain is applied to a suitable signal (i.e. +a signal quiet enough not be clipped whan applying 90 dB of gain). + +Signed-off-by: Ricard Wanderlof +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_softvol.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c +index 8bb4a397..0eaeacef 100644 +--- a/src/pcm/pcm_softvol.c ++++ b/src/pcm/pcm_softvol.c +@@ -59,7 +59,11 @@ typedef struct { + #define PRESET_RESOLUTION 256 + #define PRESET_MIN_DB -51.0 + #define ZERO_DB 0.0 +-#define MAX_DB_UPPER_LIMIT 50 ++/* ++ * The gain algorithm as it stands supports gain factors up to 32767, which ++ * is a fraction more than 90 dB, so set 90 dB as the maximum possible gain. ++ */ ++#define MAX_DB_UPPER_LIMIT 90 + + static const unsigned int preset_dB_value[PRESET_RESOLUTION] = { + 0x00b8, 0x00bd, 0x00c1, 0x00c5, 0x00ca, 0x00cf, 0x00d4, 0x00d9, +-- +2.13.6 + + +From 181f8e251bc05832f9c9401544e680ea0572a2e3 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Wed, 2 May 2018 14:08:05 +0800 +Subject: [PATCH 09/26] ucm: adding the folder of card_long_name when finding + verb conf file + +The board configuration file and verb conf file are allowed to be +in the folder named of card_long_name, so when finding the verb conf +file, we need to check if it is in the folder of card_long_name or +card_name. + +Signed-off-by: Hui Wang +Signed-off-by: Jaroslav Kysela +--- + src/ucm/parser.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/ucm/parser.c b/src/ucm/parser.c +index 2d76152f..219edb96 100644 +--- a/src/ucm/parser.c ++++ b/src/ucm/parser.c +@@ -1056,6 +1056,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr, + char filename[MAX_FILE]; + char *env = getenv(ALSA_CONFIG_UCM_VAR); + int err; ++ char *folder_name; + + /* allocate verb */ + verb = calloc(1, sizeof(struct use_case_verb)); +@@ -1082,12 +1083,17 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr, + } + + /* open Verb file for reading */ ++ if (!strncmp(uc_mgr->conf_file_name, uc_mgr->card_long_name, MAX_CARD_LONG_NAME)) ++ folder_name = uc_mgr->card_long_name; ++ else ++ folder_name = uc_mgr->card_name; ++ + if (env) + snprintf(filename, sizeof(filename), "%s/%s/%s", +- env, uc_mgr->card_name, file); ++ env, folder_name, file); + else + snprintf(filename, sizeof(filename), "%s/ucm/%s/%s", +- snd_config_topdir(), uc_mgr->card_name, file); ++ snd_config_topdir(), folder_name, file); + filename[sizeof(filename)-1] = '\0'; + + err = uc_mgr_config_load(filename, &cfg); +-- +2.13.6 + + +From 81db276f8c2235adc83e9698b0174265f6482655 Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Wed, 2 May 2018 14:08:06 +0800 +Subject: [PATCH 10/26] conf/ucm: increase the input volume for LineIn + +Otherwise, the boost value is 0, and the sound captured from that +LineIn jack is too weak for users. + +Signed-off-by: Hui Wang +Signed-off-by: Jaroslav Kysela +--- + src/conf/ucm/HDAudio-Lenovo-DualCodecs/HiFi.conf | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/conf/ucm/HDAudio-Lenovo-DualCodecs/HiFi.conf b/src/conf/ucm/HDAudio-Lenovo-DualCodecs/HiFi.conf +index 50967896..ece780da 100644 +--- a/src/conf/ucm/HDAudio-Lenovo-DualCodecs/HiFi.conf ++++ b/src/conf/ucm/HDAudio-Lenovo-DualCodecs/HiFi.conf +@@ -99,6 +99,7 @@ SectionDevice."LineIn" { + EnableSequence [ + cdev "hw:PCH" + cset "name='Input Source' Line" ++ cset "name='Line Boost Volume' 3" + ] + } + +-- +2.13.6 + + +From f7c38c29d1be8bab9dd4f406aea3b0e9151c1c06 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart +Date: Sat, 28 Apr 2018 21:51:56 +0200 +Subject: [PATCH 11/26] conf/ucm: chtrt5645: Cleanup and playback fixes + +Apply cleanup and playback fixes changes from: +https://github.com/plbossart/UCM.git + +Cc: Pierre-Louis Bossart +Signed-off-by: Pierre-Louis Bossart +[hdegoede@redhat.com: Modify commit msg and paths for merging into alsa-lib] +Signed-off-by: Hans de Goede +Signed-off-by: Takashi Iwai +--- + src/conf/ucm/chtrt5645/HiFi.conf | 157 ++++++++++++++++++++++++++++++++------- + 1 file changed, 129 insertions(+), 28 deletions(-) + +diff --git a/src/conf/ucm/chtrt5645/HiFi.conf b/src/conf/ucm/chtrt5645/HiFi.conf +index 0c2c83cc..f63392d4 100644 +--- a/src/conf/ucm/chtrt5645/HiFi.conf ++++ b/src/conf/ucm/chtrt5645/HiFi.conf +@@ -11,51 +11,146 @@ SectionVerb { + EnableSequence [ + cdev "hw:chtrt5645" + +- # Enable audio output path +- cset "name='codec_out1 mix 0 pcm0_in Switch' on" +- cset "name='media0_out mix 0 media1_in Switch' on" ++ # media mixer settings ++ # compress ++ cset "name='media0_in Gain 0 Switch' on" ++ cset "name='media0_in Gain 0 Volume' 0" + +- cset "name='media1_in Gain 0 Ramp Delay' 50" ++ # normal + cset "name='media1_in Gain 0 Switch' on" +- cset "name='media1_in Gain 0 Volume' 80% 80%" ++ cset "name='media1_in Gain 0 Volume' 0" ++ # swm loopback ++ cset "name='media2_in Gain 0 Switch' off" ++ cset "name='media2_in Gain 0 Volume' 0%" ++ # deep buffer ++ cset "name='media3_in Gain 0 Switch' on" ++ cset "name='media3_in Gain 0 Volume' 0" ++ ++ cset "name='media0_out mix 0 media0_in Switch' on" ++ cset "name='media0_out mix 0 media1_in Switch' on" ++ cset "name='media0_out mix 0 media2_in Switch' off" ++ cset "name='media0_out mix 0 media3_in Switch' on" ++ ++ cset "name='media1_out mix 0 media0_in Switch' off" ++ cset "name='media1_out mix 0 media1_in Switch' off" ++ cset "name='media1_out mix 0 media2_in Switch' off" ++ cset "name='media1_out mix 0 media3_in Switch' off" + +- cset "name='pcm0_in Gain 0 Ramp Delay' 50" + cset "name='pcm0_in Gain 0 Switch' on" +- cset "name='pcm0_in Gain 0 Volume' 80% 80%" ++ cset "name='pcm0_in Gain 0 Volume' 0" ++ ++ cset "name='pcm1_in Gain 0 Switch' off" ++ cset "name='pcm1_in Gain 0 Volume' 0%" ++ ++ # codec0_out settings (used if ssp2 is connected to aif1) ++ cset "name='codec_out0 mix 0 codec_in0 Switch' off" ++ cset "name='codec_out0 mix 0 codec_in1 Switch' off" ++ cset "name='codec_out0 mix 0 media_loop1_in Switch' off" ++ cset "name='codec_out0 mix 0 media_loop2_in Switch' off" ++ cset "name='codec_out0 mix 0 pcm0_in Switch' on" ++ cset "name='codec_out0 mix 0 pcm1_in Switch' off" ++ cset "name='codec_out0 mix 0 sprot_loop_in Switch' off" ++ cset "name='codec_out0 Gain 0 Switch' on" ++ cset "name='codec_out0 Gain 0 Volume' 0" ++ ++ # modem_out settings (used if ssp0 is connected to aif2) ++ cset "name='modem_out mix 0 codec_in0 Switch' off" ++ cset "name='modem_out mix 0 codec_in1 Switch' off" ++ cset "name='modem_out mix 0 media_loop1_in Switch' off" ++ cset "name='modem_out mix 0 media_loop2_in Switch' off" ++ cset "name='modem_out mix 0 pcm0_in Switch' on" ++ cset "name='modem_out mix 0 pcm1_in Switch' off" ++ cset "name='modem_out mix 0 sprot_loop_in Switch' off" ++ cset "name='modem_out Gain 0 Switch' on" ++ cset "name='modem_out Gain 0 Volume' 0" ++ ++ # input settings ++ # pcm1_out settings ++ ++ # input used when SSP2 is connected ++ cset "name='codec_in0 Gain 0 Switch' on" ++ cset "name='codec_in0 Gain 0 Volume' 0" + +- cset "name='codec_out1 Gain 0 Ramp Delay' 50" +- cset "name='codec_out1 Gain 0 Switch' on" +- cset "name='codec_out1 Gain 0 Volume' 70% 70%" ++ # input used when SSP0 is connected ++ cset "name='modem_in Gain 0 Switch' on" ++ cset "name='modem_in Gain 0 Volume' 0" + +- # Enable audio input path +- cset "name='pcm1_out mix 0 media_loop2_in Switch' on" +- cset "name='media_loop2_out mix 0 codec_in0 Switch' on" ++ cset "name='pcm1_out mix 0 codec_in0 Switch' on" ++ cset "name='pcm1_out mix 0 modem_in Switch' on" ++ cset "name='pcm1_out mix 0 codec_in1 Switch' off" ++ cset "name='pcm1_out mix 0 media_loop1_in Switch' off" ++ cset "name='pcm1_out mix 0 media_loop2_in Switch' off" ++ cset "name='pcm1_out mix 0 pcm0_in Switch' off" ++ cset "name='pcm1_out mix 0 pcm1_in Switch' off" ++ cset "name='pcm1_out mix 0 sprot_loop_in Switch' off" + +- cset "name='codec_in0 Gain 0 Ramp Delay' 50" +- cset "name='codec_in0 Gain 0 Switch' on" +- cset "name='codec_in0 Gain 0 Volume' 80% 80%" ++ cset "name='pcm1_out Gain 0 Switch' on" ++ cset "name='pcm1_out Gain 0 Volume' 0" + +- cset "name='media_loop2_out Gain 0 Ramp Delay' 50" +- cset "name='media_loop2_out Gain 0 Switch' on" +- cset "name='media_loop2_out Gain 0 Volume' 80% 80%" ++ # disable codec_out1 ++ cset "name='codec_out1 mix 0 codec_in0 Switch' off" ++ cset "name='codec_out1 mix 0 codec_in1 Switch' off" ++ cset "name='codec_out1 mix 0 media_loop1_in Switch' off" ++ cset "name='codec_out1 mix 0 media_loop2_in Switch' off" ++ cset "name='codec_out1 mix 0 pcm0_in Switch' off" ++ cset "name='codec_out1 mix 0 pcm1_in Switch' off" ++ cset "name='codec_out1 mix 0 sprot_loop_in Switch' off" ++ cset "name='codec_out1 Gain 0 Switch' off" ++ cset "name='codec_out1 Gain 0 Volume' 0%" + +- cset "name='pcm1_out Gain 0 Ramp Delay' 50" +- cset "name='pcm1_out Gain 0 Switch' on" +- cset "name='pcm1_out Gain 0 Volume' 80% 80%" ++ # disable codec_in1 ++ cset "name='codec_in1 Gain 0 Switch' off" ++ cset "name='codec_in1 Gain 0 Volume' 0%" ++ ++ # disable all loops ++ cset "name='media_loop1_out mix 0 codec_in0 Switch' off" ++ cset "name='media_loop1_out mix 0 codec_in1 Switch' off" ++ cset "name='media_loop1_out mix 0 media_loop1_in Switch' off" ++ cset "name='media_loop1_out mix 0 media_loop2_in Switch' off" ++ cset "name='media_loop1_out mix 0 pcm0_in Switch' off" ++ cset "name='media_loop1_out mix 0 pcm1_in Switch' off" ++ cset "name='media_loop1_out mix 0 sprot_loop_in Switch' off" ++ ++ cset "name='media_loop2_out mix 0 codec_in0 Switch' off" ++ cset "name='media_loop2_out mix 0 codec_in1 Switch' off" ++ cset "name='media_loop2_out mix 0 media_loop1_in Switch' off" ++ cset "name='media_loop2_out mix 0 media_loop2_in Switch' off" ++ cset "name='media_loop2_out mix 0 pcm0_in Switch' off" ++ cset "name='media_loop2_out mix 0 pcm1_in Switch' off" ++ cset "name='media_loop2_out mix 0 sprot_loop_in Switch' off" ++ ++ cset "name='sprot_loop_out mix 0 codec_in0 Switch' off" ++ cset "name='sprot_loop_out mix 0 codec_in1 Switch' off" ++ cset "name='sprot_loop_out mix 0 media_loop1_in Switch' off" ++ cset "name='sprot_loop_out mix 0 media_loop2_in Switch' off" ++ cset "name='sprot_loop_out mix 0 pcm0_in Switch' off" ++ cset "name='sprot_loop_out mix 0 pcm1_in Switch' off" ++ cset "name='sprot_loop_out mix 0 sprot_loop_in Switch' off" + + # Output Configuration +- cset "name='DAC L2 Mux' 'IF1 DAC'" +- cset "name='DAC R2 Mux' 'IF1 DAC'" ++ cset "name='DAC1 L Mux' IF1 DAC" ++ cset "name='DAC1 R Mux' IF1 DAC" ++ cset "name='DAC1 MIXL DAC1 Switch' 1" ++ cset "name='DAC1 MIXR DAC1 Switch' 1" ++ cset "name='Stereo DAC MIXL DAC L1 Switch' 1" ++ cset "name='Stereo DAC MIXR DAC R1 Switch' 1" ++ ++ cset "name='DAC L2 Mux' IF2 DAC" ++ cset "name='DAC R2 Mux' IF2 DAC" + cset "name='Mono DAC MIXL DAC L2 Switch' on" + cset "name='Mono DAC MIXR DAC R2 Switch' on" + cset "name='DAC2 Playback Switch' on" + ++ cset "name='HPOVOL MIXL DAC1 Switch' on" ++ cset "name='HPOVOL MIXR DAC1 Switch' on" + cset "name='HPOVOL MIXL DAC2 Switch' on" + cset "name='HPOVOL MIXR DAC2 Switch' on" + cset "name='HPO MIX HPVOL Switch' on" + cset "name='HPOVOL L Switch' on" + cset "name='HPOVOL R Switch' on" + ++ cset "name='SPK MIXL DAC L1 Switch' on" ++ cset "name='SPK MIXR DAC R1 Switch' on" + cset "name='SPK MIXL DAC L2 Switch' on" + cset "name='SPK MIXR DAC R2 Switch' on" + cset "name='SPOL MIX SPKVOL L Switch' on" +@@ -105,15 +200,18 @@ SectionDevice."Speaker" { + } + + ConflictingDevice [ +- "Headphone" ++ "Headphones" + ] + + EnableSequence [ + cdev "hw:chtrt5645" + ++ cset "name='Headphone Switch' off" ++ cset "name='Headphone Channel Switch' off" ++ + cset "name='Ext Spk Switch' on" + cset "name='Speaker Channel Switch' on" +- cset "name='Speaker Playback Volume' 39" ++ cset "name='Speaker Playback Volume' 31" + ] + + DisableSequence [ +@@ -124,7 +222,7 @@ SectionDevice."Speaker" { + ] + } + +-SectionDevice."Headphone".0 { ++SectionDevice."Headphones" { + Comment "Headphones" + + Value { +@@ -140,9 +238,12 @@ SectionDevice."Headphone".0 { + EnableSequence [ + cdev "hw:chtrt5645" + ++ cset "name='Ext Spk Switch' off" ++ cset "name='Speaker Channel Switch' off" ++ + cset "name='Headphone Switch' on" + cset "name='Headphone Channel Switch' on" +- cset "name='Headphone Playback Volume' 39" ++ cset "name='Headphone Playback Volume' 31" + ] + + DisableSequence [ +-- +2.13.6 + + +From 4c0d983d7b4402e7275455ac43f39049b45037ea Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart +Date: Sat, 28 Apr 2018 21:51:57 +0200 +Subject: [PATCH 12/26] conf/ucm: chtrt5645: Microphone recording fixes + +Apply microphone recording changes from: +https://github.com/plbossart/UCM.git + +Cc: Pierre-Louis Bossart +Signed-off-by: Pierre-Louis Bossart +[hdegoede@redhat.com: Drop non generic DMIC changes] +Signed-off-by: Hans de Goede +Signed-off-by: Takashi Iwai +--- + src/conf/ucm/chtrt5645/HiFi.conf | 50 ++++++++++++++++++++++++++++++++-------- + 1 file changed, 41 insertions(+), 9 deletions(-) + +diff --git a/src/conf/ucm/chtrt5645/HiFi.conf b/src/conf/ucm/chtrt5645/HiFi.conf +index f63392d4..b97a9c00 100644 +--- a/src/conf/ucm/chtrt5645/HiFi.conf ++++ b/src/conf/ucm/chtrt5645/HiFi.conf +@@ -4,8 +4,8 @@ SectionVerb { + TQ "HiFi" + + # ALSA PCM device for HiFi +- PlaybackPCM "hw:chtrt5645,0" +- CapturePCM "hw:chtrt5645,0" ++ PlaybackPCM "hw:chtrt5645" ++ CapturePCM "hw:chtrt5645" + } + + EnableSequence [ +@@ -255,7 +255,7 @@ SectionDevice."Headphones" { + } + + SectionDevice."Mic".0 { +- Comment "Internal Microphone" ++ Comment "Internal Analog Microphones" + + Value { + CaptureChannels "2" +@@ -266,15 +266,33 @@ SectionDevice."Mic".0 { + cdev "hw:chtrt5645" + + cset "name='Int Mic Switch' on" +- cset "name='Sto1 ADC MIXL ADC2 Switch' on" +- cset "name='Sto1 ADC MIXR ADC2 Switch' on" ++ ++ cset "name='Sto1 ADC MIXL ADC1 Switch' on" ++ cset "name='Sto1 ADC MIXR ADC1 Switch' on" ++ cset "name='Sto1 ADC MIXL ADC2 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC2 Switch' off" ++ ++ cset "name='Mono ADC MIXL ADC1 Switch' on" ++ cset "name='Mono ADC MIXR ADC1 Switch' on" ++ cset "name='Mono ADC MIXL ADC2 Switch' off" ++ cset "name='Mono ADC MIXR ADC2 Switch' off" ++ ++ cset "name='RECMIXL BST1 Switch' on" ++ cset "name='RECMIXR BST1 Switch' on" ++ + ] + + DisableSequence [ + cdev "hw:chtrt5645" + +- cset "name='Sto1 ADC MIXL ADC2 Switch' off" +- cset "name='Sto1 ADC MIXR ADC2 Switch' off" ++ cset "name='Sto1 ADC MIXL ADC1 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC1 Switch' off" ++ cset "name='Mono ADC MIXL ADC1 Switch' off" ++ cset "name='Mono ADC MIXR ADC1 Switch' off" ++ ++ cset "name='RECMIXL BST1 Switch' off" ++ cset "name='RECMIXR BST1 Switch' off" ++ + cset "name='Int Mic Switch' off" + ] + } +@@ -292,19 +310,33 @@ SectionDevice."HSMic".0 { + cdev "hw:chtrt5645" + + cset "name='Headset Mic Switch' on" +- cset "name='RECMIXL BST1 Switch' on" +- cset "name='RECMIXR BST1 Switch' on" ++ + cset "name='Sto1 ADC MIXL ADC1 Switch' on" + cset "name='Sto1 ADC MIXR ADC1 Switch' on" ++ cset "name='Sto1 ADC MIXL ADC2 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC2 Switch' off" ++ ++ cset "name='Mono ADC MIXL ADC1 Switch' on" ++ cset "name='Mono ADC MIXR ADC1 Switch' on" ++ cset "name='Mono ADC MIXL ADC2 Switch' off" ++ cset "name='Mono ADC MIXR ADC2 Switch' off" ++ ++ cset "name='RECMIXL BST1 Switch' on" ++ cset "name='RECMIXR BST1 Switch' on" ++ + ] + + DisableSequence [ + cdev "hw:chtrt5645" + + cset "name='Headset Mic Switch' off" ++ + cset "name='RECMIXL BST1 Switch' off" + cset "name='RECMIXR BST1 Switch' off" + cset "name='Sto1 ADC MIXL ADC1 Switch' off" + cset "name='Sto1 ADC MIXR ADC1 Switch' off" ++ cset "name='Mono ADC MIXL ADC1 Switch' on" ++ cset "name='Mono ADC MIXR ADC1 Switch' on" ++ + ] + } +-- +2.13.6 + + +From 76bc53e69a12163a86e6746fd3011de6b1652043 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sat, 28 Apr 2018 21:51:58 +0200 +Subject: [PATCH 13/26] conf/ucm: chtrt5645: Fix recording from internal analog + microphone + +The internal analog mic switch is called 'Int Analog Mic Switch' +(not 'Int Mic Switch') and is connected to BST2 not BST1. + +Also change the analog mic volume levels so that we get better +audio / less noise. + +Signed-off-by: Hans de Goede +Signed-off-by: Takashi Iwai +--- + src/conf/ucm/chtrt5645/HiFi.conf | 38 ++++++++++++++++++++++++-------------- + 1 file changed, 24 insertions(+), 14 deletions(-) + +diff --git a/src/conf/ucm/chtrt5645/HiFi.conf b/src/conf/ucm/chtrt5645/HiFi.conf +index b97a9c00..e81866cf 100644 +--- a/src/conf/ucm/chtrt5645/HiFi.conf ++++ b/src/conf/ucm/chtrt5645/HiFi.conf +@@ -160,15 +160,24 @@ SectionVerb { + + # Input Configuration + cset "name='Stereo1 DMIC Mux' 0" ++ cset "name='Stereo1 ADC1 Mux' 1" + cset "name='Stereo1 ADC2 Mux' 1" + cset "name='ADC Capture Switch' on" +- cset "name='ADC Capture Volume' 31" +- cset "name='ADC Boost Capture Volume' 3" +- cset "name='Mono ADC Capture Volume' 63" +- cset "name='Mono ADC Boost Capture Volume' 2" +- cset "name='IN Capture Volume' 63" ++ # 55/63 ++ cset "name='ADC Capture Volume' 55" ++ # set ADC Boost to 0/3, higher vals cause a lot of white noise ++ cset "name='ADC Boost Capture Volume' 0" ++ # 55/63 ++ cset "name='Mono ADC Capture Volume' 55" ++ # 0/3 ++ cset "name='Mono ADC Boost Capture Volume' 0" ++ # 27/31 ++ cset "name='IN Capture Volume' 27" + cset "name='I2S2 Func Switch' on" +- ++ # 3/12 the headphone mic tends to be quite loud ++ cset "name='IN1 Boost' 3" ++ # 8/8 the internal analog mic tends to be quite soft ++ cset "name='IN2 Boost' 8" + ] + + DisableSequence [ +@@ -243,7 +252,8 @@ SectionDevice."Headphones" { + + cset "name='Headphone Switch' on" + cset "name='Headphone Channel Switch' on" +- cset "name='Headphone Playback Volume' 31" ++ # 25/39 higher values cause crackling on some boards ++ cset "name='Headphone Playback Volume' 25" + ] + + DisableSequence [ +@@ -255,7 +265,7 @@ SectionDevice."Headphones" { + } + + SectionDevice."Mic".0 { +- Comment "Internal Analog Microphones" ++ Comment "Internal Analog Microphone" + + Value { + CaptureChannels "2" +@@ -265,7 +275,7 @@ SectionDevice."Mic".0 { + EnableSequence [ + cdev "hw:chtrt5645" + +- cset "name='Int Mic Switch' on" ++ cset "name='Int Analog Mic Switch' on" + + cset "name='Sto1 ADC MIXL ADC1 Switch' on" + cset "name='Sto1 ADC MIXR ADC1 Switch' on" +@@ -277,8 +287,8 @@ SectionDevice."Mic".0 { + cset "name='Mono ADC MIXL ADC2 Switch' off" + cset "name='Mono ADC MIXR ADC2 Switch' off" + +- cset "name='RECMIXL BST1 Switch' on" +- cset "name='RECMIXR BST1 Switch' on" ++ cset "name='RECMIXL BST2 Switch' on" ++ cset "name='RECMIXR BST2 Switch' on" + + ] + +@@ -290,10 +300,10 @@ SectionDevice."Mic".0 { + cset "name='Mono ADC MIXL ADC1 Switch' off" + cset "name='Mono ADC MIXR ADC1 Switch' off" + +- cset "name='RECMIXL BST1 Switch' off" +- cset "name='RECMIXR BST1 Switch' off" ++ cset "name='RECMIXL BST2 Switch' off" ++ cset "name='RECMIXR BST2 Switch' off" + +- cset "name='Int Mic Switch' off" ++ cset "name='Int Analog Mic Switch' off" + ] + } + +-- +2.13.6 + + +From c22a7f423ddef2a1376bc84f2aafc0a167192ab6 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sat, 28 Apr 2018 21:51:59 +0200 +Subject: [PATCH 14/26] conf/ucm: chtrt5645: At config for the Asus T100HA + +The Asus T100HA uses a digital mic rather then an analog one, add +long-name config specific for the T100HA, which is a copy of the standard +chtrt5645 config with the internal analog mic section replaced with one +for the digital mic found on the Asus T100HA. + +Signed-off-by: Hans de Goede +Signed-off-by: Takashi Iwai +--- + configure.ac | 1 + + .../ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN.conf | 5 + + .../HiFi.conf | 348 +++++++++++++++++++++ + .../Makefile.am | 4 + + src/conf/ucm/Makefile.am | 1 + + 5 files changed, 359 insertions(+) + create mode 100644 src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN.conf + create mode 100644 src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/HiFi.conf + create mode 100644 src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/Makefile.am + +diff --git a/configure.ac b/configure.ac +index 5bc1994f..94baf055 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -717,6 +717,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \ + src/conf/cards/Makefile \ + src/conf/pcm/Makefile \ + src/conf/ucm/Makefile \ ++ src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/Makefile \ + src/conf/ucm/broadwell-rt286/Makefile \ + src/conf/ucm/broxton-rt298/Makefile \ + src/conf/ucm/bytcr-rt5651/Makefile \ +diff --git a/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN.conf b/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN.conf +new file mode 100644 +index 00000000..5afe5f0b +--- /dev/null ++++ b/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN.conf +@@ -0,0 +1,5 @@ ++Comment "Intel SoC Audio Device" ++SectionUseCase."HiFi" { ++ File "../ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/HiFi.conf" ++ Comment "Default" ++} +diff --git a/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/HiFi.conf b/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/HiFi.conf +new file mode 100644 +index 00000000..78bf9823 +--- /dev/null ++++ b/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/HiFi.conf +@@ -0,0 +1,348 @@ ++SectionVerb { ++ # ALSA PCM ++ Value { ++ TQ "HiFi" ++ ++ # ALSA PCM device for HiFi ++ PlaybackPCM "hw:chtrt5645" ++ CapturePCM "hw:chtrt5645" ++ } ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ # media mixer settings ++ # compress ++ cset "name='media0_in Gain 0 Switch' on" ++ cset "name='media0_in Gain 0 Volume' 0" ++ ++ # normal ++ cset "name='media1_in Gain 0 Switch' on" ++ cset "name='media1_in Gain 0 Volume' 0" ++ # swm loopback ++ cset "name='media2_in Gain 0 Switch' off" ++ cset "name='media2_in Gain 0 Volume' 0%" ++ # deep buffer ++ cset "name='media3_in Gain 0 Switch' on" ++ cset "name='media3_in Gain 0 Volume' 0" ++ ++ cset "name='media0_out mix 0 media0_in Switch' on" ++ cset "name='media0_out mix 0 media1_in Switch' on" ++ cset "name='media0_out mix 0 media2_in Switch' off" ++ cset "name='media0_out mix 0 media3_in Switch' on" ++ ++ cset "name='media1_out mix 0 media0_in Switch' off" ++ cset "name='media1_out mix 0 media1_in Switch' off" ++ cset "name='media1_out mix 0 media2_in Switch' off" ++ cset "name='media1_out mix 0 media3_in Switch' off" ++ ++ cset "name='pcm0_in Gain 0 Switch' on" ++ cset "name='pcm0_in Gain 0 Volume' 0" ++ ++ cset "name='pcm1_in Gain 0 Switch' off" ++ cset "name='pcm1_in Gain 0 Volume' 0%" ++ ++ # codec0_out settings (used if ssp2 is connected to aif1) ++ cset "name='codec_out0 mix 0 codec_in0 Switch' off" ++ cset "name='codec_out0 mix 0 codec_in1 Switch' off" ++ cset "name='codec_out0 mix 0 media_loop1_in Switch' off" ++ cset "name='codec_out0 mix 0 media_loop2_in Switch' off" ++ cset "name='codec_out0 mix 0 pcm0_in Switch' on" ++ cset "name='codec_out0 mix 0 pcm1_in Switch' off" ++ cset "name='codec_out0 mix 0 sprot_loop_in Switch' off" ++ cset "name='codec_out0 Gain 0 Switch' on" ++ cset "name='codec_out0 Gain 0 Volume' 0" ++ ++ # modem_out settings (used if ssp0 is connected to aif2) ++ cset "name='modem_out mix 0 codec_in0 Switch' off" ++ cset "name='modem_out mix 0 codec_in1 Switch' off" ++ cset "name='modem_out mix 0 media_loop1_in Switch' off" ++ cset "name='modem_out mix 0 media_loop2_in Switch' off" ++ cset "name='modem_out mix 0 pcm0_in Switch' on" ++ cset "name='modem_out mix 0 pcm1_in Switch' off" ++ cset "name='modem_out mix 0 sprot_loop_in Switch' off" ++ cset "name='modem_out Gain 0 Switch' on" ++ cset "name='modem_out Gain 0 Volume' 0" ++ ++ # input settings ++ # pcm1_out settings ++ ++ # input used when SSP2 is connected ++ cset "name='codec_in0 Gain 0 Switch' on" ++ cset "name='codec_in0 Gain 0 Volume' 0" ++ ++ # input used when SSP0 is connected ++ cset "name='modem_in Gain 0 Switch' on" ++ cset "name='modem_in Gain 0 Volume' 0" ++ ++ cset "name='pcm1_out mix 0 codec_in0 Switch' on" ++ cset "name='pcm1_out mix 0 modem_in Switch' on" ++ cset "name='pcm1_out mix 0 codec_in1 Switch' off" ++ cset "name='pcm1_out mix 0 media_loop1_in Switch' off" ++ cset "name='pcm1_out mix 0 media_loop2_in Switch' off" ++ cset "name='pcm1_out mix 0 pcm0_in Switch' off" ++ cset "name='pcm1_out mix 0 pcm1_in Switch' off" ++ cset "name='pcm1_out mix 0 sprot_loop_in Switch' off" ++ ++ cset "name='pcm1_out Gain 0 Switch' on" ++ cset "name='pcm1_out Gain 0 Volume' 0" ++ ++ # disable codec_out1 ++ cset "name='codec_out1 mix 0 codec_in0 Switch' off" ++ cset "name='codec_out1 mix 0 codec_in1 Switch' off" ++ cset "name='codec_out1 mix 0 media_loop1_in Switch' off" ++ cset "name='codec_out1 mix 0 media_loop2_in Switch' off" ++ cset "name='codec_out1 mix 0 pcm0_in Switch' off" ++ cset "name='codec_out1 mix 0 pcm1_in Switch' off" ++ cset "name='codec_out1 mix 0 sprot_loop_in Switch' off" ++ cset "name='codec_out1 Gain 0 Switch' off" ++ cset "name='codec_out1 Gain 0 Volume' 0%" ++ ++ # disable codec_in1 ++ cset "name='codec_in1 Gain 0 Switch' off" ++ cset "name='codec_in1 Gain 0 Volume' 0%" ++ ++ # disable all loops ++ cset "name='media_loop1_out mix 0 codec_in0 Switch' off" ++ cset "name='media_loop1_out mix 0 codec_in1 Switch' off" ++ cset "name='media_loop1_out mix 0 media_loop1_in Switch' off" ++ cset "name='media_loop1_out mix 0 media_loop2_in Switch' off" ++ cset "name='media_loop1_out mix 0 pcm0_in Switch' off" ++ cset "name='media_loop1_out mix 0 pcm1_in Switch' off" ++ cset "name='media_loop1_out mix 0 sprot_loop_in Switch' off" ++ ++ cset "name='media_loop2_out mix 0 codec_in0 Switch' off" ++ cset "name='media_loop2_out mix 0 codec_in1 Switch' off" ++ cset "name='media_loop2_out mix 0 media_loop1_in Switch' off" ++ cset "name='media_loop2_out mix 0 media_loop2_in Switch' off" ++ cset "name='media_loop2_out mix 0 pcm0_in Switch' off" ++ cset "name='media_loop2_out mix 0 pcm1_in Switch' off" ++ cset "name='media_loop2_out mix 0 sprot_loop_in Switch' off" ++ ++ cset "name='sprot_loop_out mix 0 codec_in0 Switch' off" ++ cset "name='sprot_loop_out mix 0 codec_in1 Switch' off" ++ cset "name='sprot_loop_out mix 0 media_loop1_in Switch' off" ++ cset "name='sprot_loop_out mix 0 media_loop2_in Switch' off" ++ cset "name='sprot_loop_out mix 0 pcm0_in Switch' off" ++ cset "name='sprot_loop_out mix 0 pcm1_in Switch' off" ++ cset "name='sprot_loop_out mix 0 sprot_loop_in Switch' off" ++ ++ # Output Configuration ++ cset "name='DAC1 L Mux' IF1 DAC" ++ cset "name='DAC1 R Mux' IF1 DAC" ++ cset "name='DAC1 MIXL DAC1 Switch' 1" ++ cset "name='DAC1 MIXR DAC1 Switch' 1" ++ cset "name='Stereo DAC MIXL DAC L1 Switch' 1" ++ cset "name='Stereo DAC MIXR DAC R1 Switch' 1" ++ ++ cset "name='DAC L2 Mux' IF2 DAC" ++ cset "name='DAC R2 Mux' IF2 DAC" ++ cset "name='Mono DAC MIXL DAC L2 Switch' on" ++ cset "name='Mono DAC MIXR DAC R2 Switch' on" ++ cset "name='DAC2 Playback Switch' on" ++ ++ cset "name='HPOVOL MIXL DAC1 Switch' on" ++ cset "name='HPOVOL MIXR DAC1 Switch' on" ++ cset "name='HPOVOL MIXL DAC2 Switch' on" ++ cset "name='HPOVOL MIXR DAC2 Switch' on" ++ cset "name='HPO MIX HPVOL Switch' on" ++ cset "name='HPOVOL L Switch' on" ++ cset "name='HPOVOL R Switch' on" ++ ++ cset "name='SPK MIXL DAC L1 Switch' on" ++ cset "name='SPK MIXR DAC R1 Switch' on" ++ cset "name='SPK MIXL DAC L2 Switch' on" ++ cset "name='SPK MIXR DAC R2 Switch' on" ++ cset "name='SPOL MIX SPKVOL L Switch' on" ++ cset "name='SPOR MIX SPKVOL R Switch' on" ++ cset "name='SPKVOL L Switch' on" ++ cset "name='SPKVOL R Switch' on" ++ ++ # Input Configuration ++ cset "name='Stereo1 DMIC Mux' 0" ++ cset "name='Stereo1 ADC1 Mux' 1" ++ cset "name='Stereo1 ADC2 Mux' 1" ++ cset "name='ADC Capture Switch' on" ++ # 55/63 ++ cset "name='ADC Capture Volume' 55" ++ # set ADC Boost to 0/3, higher vals cause a lot of white noise ++ cset "name='ADC Boost Capture Volume' 0" ++ # 55/63 ++ cset "name='Mono ADC Capture Volume' 55" ++ # 0/3 ++ cset "name='Mono ADC Boost Capture Volume' 0" ++ # 27/31 ++ cset "name='IN Capture Volume' 27" ++ cset "name='I2S2 Func Switch' on" ++ # 3/12 the headphone mic tends to be quite loud ++ cset "name='IN1 Boost' 3" ++ # 8/8 the internal analog mic tends to be quite soft ++ cset "name='IN2 Boost' 8" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ # Disable audio output path ++ cset "name='codec_out1 mix 0 pcm0_in Switch' off" ++ cset "name='media0_out mix 0 media1_in Switch' off" ++ ++ cset "name='media1_in Gain 0 Switch' off" ++ cset "name='pcm0_in Gain 0 Switch' off" ++ cset "name='codec_out1 Gain 0 Switch' off" ++ ++ # Disable audio input path ++ cset "name='pcm1_out mix 0 media_loop2_in Switch' off" ++ cset "name='media_loop2_out mix 0 codec_in0 Switch' off" ++ ++ cset "name='media_loop2_out Gain 0 Switch' off" ++ cset "name='pcm1_out Gain 0 Switch' off" ++ cset "name='codec_in0 Gain 0 Switch' off" ++ ] ++} ++ ++SectionDevice."Speaker" { ++ Comment "Speaker" ++ ++ Value { ++ PlaybackChannels "2" ++ } ++ ++ ConflictingDevice [ ++ "Headphones" ++ ] ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Headphone Switch' off" ++ cset "name='Headphone Channel Switch' off" ++ ++ cset "name='Ext Spk Switch' on" ++ cset "name='Speaker Channel Switch' on" ++ cset "name='Speaker Playback Volume' 31" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Ext Spk Switch' off" ++ cset "name='Speaker Channel Switch' off" ++ ] ++} ++ ++SectionDevice."Headphones" { ++ Comment "Headphones" ++ ++ Value { ++ PlaybackChannels "2" ++ JackControl "Headphone Jack" ++ JackHWMute "Speaker" ++ } ++ ++ ConflictingDevice [ ++ "Speaker" ++ ] ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Ext Spk Switch' off" ++ cset "name='Speaker Channel Switch' off" ++ ++ cset "name='Headphone Switch' on" ++ cset "name='Headphone Channel Switch' on" ++ # 25/39 higher values cause crackling on some boards ++ cset "name='Headphone Playback Volume' 25" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Headphone Switch' off" ++ cset "name='Headphone Channel Switch' off" ++ ] ++} ++ ++SectionDevice."DMic".0 { ++ Comment "Internal Microphone" ++ ++ Value { ++ CaptureChannels "2" ++ CapturePriority "150" ++ } ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Int Mic Switch' on" ++ ++ cset "name='Stereo1 DMIC Mux' DMIC1" ++ cset "name='Stereo1 ADC2 Mux' DMIC" ++ cset "name='Mono ADC L2 Mux' DMIC" ++ cset "name='Mono ADC R2 Mux' DMIC" ++ ++ cset "name='Sto1 ADC MIXL ADC1 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC1 Switch' off" ++ cset "name='Sto1 ADC MIXL ADC2 Switch' on" ++ cset "name='Sto1 ADC MIXR ADC2 Switch' on" ++ cset "name='Mono ADC MIXL ADC1 Switch' off" ++ cset "name='Mono ADC MIXR ADC1 Switch' off" ++ cset "name='Mono ADC MIXL ADC2 Switch' on" ++ cset "name='Mono ADC MIXR ADC2 Switch' on" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Sto1 ADC MIXL ADC2 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC2 Switch' off" ++ cset "name='Mono ADC MIXL ADC2 Switch' off" ++ cset "name='Mono ADC MIXR ADC2 Switch' off" ++ cset "name='Int Mic Switch' off" ++ ] ++} ++ ++SectionDevice."HSMic".0 { ++ Comment "Headset Microphone" ++ ++ Value { ++ CaptureChannels "2" ++ JackControl "Headset Mic Jack" ++ JackHWMute "DMic" ++ } ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Headset Mic Switch' on" ++ ++ cset "name='Sto1 ADC MIXL ADC1 Switch' on" ++ cset "name='Sto1 ADC MIXR ADC1 Switch' on" ++ cset "name='Sto1 ADC MIXL ADC2 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC2 Switch' off" ++ ++ cset "name='Mono ADC MIXL ADC1 Switch' on" ++ cset "name='Mono ADC MIXR ADC1 Switch' on" ++ cset "name='Mono ADC MIXL ADC2 Switch' off" ++ cset "name='Mono ADC MIXR ADC2 Switch' off" ++ ++ cset "name='RECMIXL BST1 Switch' on" ++ cset "name='RECMIXR BST1 Switch' on" ++ ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Headset Mic Switch' off" ++ ++ cset "name='RECMIXL BST1 Switch' off" ++ cset "name='RECMIXR BST1 Switch' off" ++ cset "name='Sto1 ADC MIXL ADC1 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC1 Switch' off" ++ cset "name='Mono ADC MIXL ADC1 Switch' on" ++ cset "name='Mono ADC MIXR ADC1 Switch' on" ++ ++ ] ++} +diff --git a/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/Makefile.am b/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/Makefile.am +new file mode 100644 +index 00000000..dd8b372a +--- /dev/null ++++ b/src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/Makefile.am +@@ -0,0 +1,4 @@ ++alsaconfigdir = @ALSA_CONFIG_DIR@ ++ucmdir = $(alsaconfigdir)/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN ++ucm_DATA = ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN.conf HiFi.conf ++EXTRA_DIST = $(ucm_DATA) +diff --git a/src/conf/ucm/Makefile.am b/src/conf/ucm/Makefile.am +index 3b4f13a8..e496ca89 100644 +--- a/src/conf/ucm/Makefile.am ++++ b/src/conf/ucm/Makefile.am +@@ -1,4 +1,5 @@ + SUBDIRS=\ ++ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN \ + broadwell-rt286 \ + broxton-rt298 \ + bytcr-rt5651 \ +-- +2.13.6 + + +From 5a2df9449d0b17e3579bde60ba48244ba24ea604 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sat, 28 Apr 2018 21:52:00 +0200 +Subject: [PATCH 15/26] conf/ucm: chtrt5645: At config for the Lenovo Ideapad + Miix 320 + +The Lenovo Ideapad Miix 320 uses a digital mic connected to the DMIC2 input +(unlike the Asus T100HA which has it connected to the DMIC1 input), add a +long-name config specific for the Miix 320, which is a copy of the standard +chtrt5645 config with the internal analog mic section replaced with one +for a digital mic connected to the DMIC2 input. + +Signed-off-by: Hans de Goede +Signed-off-by: Takashi Iwai +--- + configure.ac | 1 + + .../HiFi.conf | 350 +++++++++++++++++++++ + ...ENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216.conf | 5 + + .../Makefile.am | 4 + + src/conf/ucm/Makefile.am | 1 + + 5 files changed, 361 insertions(+) + create mode 100644 src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/HiFi.conf + create mode 100644 src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216.conf + create mode 100644 src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/Makefile.am + +diff --git a/configure.ac b/configure.ac +index 94baf055..3ee989eb 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -729,6 +729,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \ + src/conf/ucm/gpd-win-pocket-rt5645/Makefile \ + src/conf/ucm/HDAudio-Gigabyte-ALC1220DualCodecs/Makefile \ + src/conf/ucm/HDAudio-Lenovo-DualCodecs/Makefile \ ++ src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/Makefile \ + src/conf/ucm/PandaBoard/Makefile \ + src/conf/ucm/PandaBoardES/Makefile \ + src/conf/ucm/PAZ00/Makefile \ +diff --git a/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/HiFi.conf b/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/HiFi.conf +new file mode 100644 +index 00000000..8cc9c7f2 +--- /dev/null ++++ b/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/HiFi.conf +@@ -0,0 +1,350 @@ ++SectionVerb { ++ # ALSA PCM ++ Value { ++ TQ "HiFi" ++ ++ # ALSA PCM device for HiFi ++ PlaybackPCM "hw:chtrt5645" ++ CapturePCM "hw:chtrt5645" ++ } ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ # media mixer settings ++ # compress ++ cset "name='media0_in Gain 0 Switch' on" ++ cset "name='media0_in Gain 0 Volume' 0" ++ ++ # normal ++ cset "name='media1_in Gain 0 Switch' on" ++ cset "name='media1_in Gain 0 Volume' 0" ++ # swm loopback ++ cset "name='media2_in Gain 0 Switch' off" ++ cset "name='media2_in Gain 0 Volume' 0%" ++ # deep buffer ++ cset "name='media3_in Gain 0 Switch' on" ++ cset "name='media3_in Gain 0 Volume' 0" ++ ++ cset "name='media0_out mix 0 media0_in Switch' on" ++ cset "name='media0_out mix 0 media1_in Switch' on" ++ cset "name='media0_out mix 0 media2_in Switch' off" ++ cset "name='media0_out mix 0 media3_in Switch' on" ++ ++ cset "name='media1_out mix 0 media0_in Switch' off" ++ cset "name='media1_out mix 0 media1_in Switch' off" ++ cset "name='media1_out mix 0 media2_in Switch' off" ++ cset "name='media1_out mix 0 media3_in Switch' off" ++ ++ cset "name='pcm0_in Gain 0 Switch' on" ++ cset "name='pcm0_in Gain 0 Volume' 0" ++ ++ cset "name='pcm1_in Gain 0 Switch' off" ++ cset "name='pcm1_in Gain 0 Volume' 0%" ++ ++ # codec0_out settings (used if ssp2 is connected to aif1) ++ cset "name='codec_out0 mix 0 codec_in0 Switch' off" ++ cset "name='codec_out0 mix 0 codec_in1 Switch' off" ++ cset "name='codec_out0 mix 0 media_loop1_in Switch' off" ++ cset "name='codec_out0 mix 0 media_loop2_in Switch' off" ++ cset "name='codec_out0 mix 0 pcm0_in Switch' on" ++ cset "name='codec_out0 mix 0 pcm1_in Switch' off" ++ cset "name='codec_out0 mix 0 sprot_loop_in Switch' off" ++ cset "name='codec_out0 Gain 0 Switch' on" ++ cset "name='codec_out0 Gain 0 Volume' 0" ++ ++ # modem_out settings (used if ssp0 is connected to aif2) ++ cset "name='modem_out mix 0 codec_in0 Switch' off" ++ cset "name='modem_out mix 0 codec_in1 Switch' off" ++ cset "name='modem_out mix 0 media_loop1_in Switch' off" ++ cset "name='modem_out mix 0 media_loop2_in Switch' off" ++ cset "name='modem_out mix 0 pcm0_in Switch' on" ++ cset "name='modem_out mix 0 pcm1_in Switch' off" ++ cset "name='modem_out mix 0 sprot_loop_in Switch' off" ++ cset "name='modem_out Gain 0 Switch' on" ++ cset "name='modem_out Gain 0 Volume' 0" ++ ++ # input settings ++ # pcm1_out settings ++ ++ # input used when SSP2 is connected ++ cset "name='codec_in0 Gain 0 Switch' on" ++ cset "name='codec_in0 Gain 0 Volume' 0" ++ ++ # input used when SSP0 is connected ++ cset "name='modem_in Gain 0 Switch' on" ++ cset "name='modem_in Gain 0 Volume' 0" ++ ++ cset "name='pcm1_out mix 0 codec_in0 Switch' on" ++ cset "name='pcm1_out mix 0 modem_in Switch' on" ++ cset "name='pcm1_out mix 0 codec_in1 Switch' off" ++ cset "name='pcm1_out mix 0 media_loop1_in Switch' off" ++ cset "name='pcm1_out mix 0 media_loop2_in Switch' off" ++ cset "name='pcm1_out mix 0 pcm0_in Switch' off" ++ cset "name='pcm1_out mix 0 pcm1_in Switch' off" ++ cset "name='pcm1_out mix 0 sprot_loop_in Switch' off" ++ ++ cset "name='pcm1_out Gain 0 Switch' on" ++ cset "name='pcm1_out Gain 0 Volume' 0" ++ ++ # disable codec_out1 ++ cset "name='codec_out1 mix 0 codec_in0 Switch' off" ++ cset "name='codec_out1 mix 0 codec_in1 Switch' off" ++ cset "name='codec_out1 mix 0 media_loop1_in Switch' off" ++ cset "name='codec_out1 mix 0 media_loop2_in Switch' off" ++ cset "name='codec_out1 mix 0 pcm0_in Switch' off" ++ cset "name='codec_out1 mix 0 pcm1_in Switch' off" ++ cset "name='codec_out1 mix 0 sprot_loop_in Switch' off" ++ cset "name='codec_out1 Gain 0 Switch' off" ++ cset "name='codec_out1 Gain 0 Volume' 0%" ++ ++ # disable codec_in1 ++ cset "name='codec_in1 Gain 0 Switch' off" ++ cset "name='codec_in1 Gain 0 Volume' 0%" ++ ++ # disable all loops ++ cset "name='media_loop1_out mix 0 codec_in0 Switch' off" ++ cset "name='media_loop1_out mix 0 codec_in1 Switch' off" ++ cset "name='media_loop1_out mix 0 media_loop1_in Switch' off" ++ cset "name='media_loop1_out mix 0 media_loop2_in Switch' off" ++ cset "name='media_loop1_out mix 0 pcm0_in Switch' off" ++ cset "name='media_loop1_out mix 0 pcm1_in Switch' off" ++ cset "name='media_loop1_out mix 0 sprot_loop_in Switch' off" ++ ++ cset "name='media_loop2_out mix 0 codec_in0 Switch' off" ++ cset "name='media_loop2_out mix 0 codec_in1 Switch' off" ++ cset "name='media_loop2_out mix 0 media_loop1_in Switch' off" ++ cset "name='media_loop2_out mix 0 media_loop2_in Switch' off" ++ cset "name='media_loop2_out mix 0 pcm0_in Switch' off" ++ cset "name='media_loop2_out mix 0 pcm1_in Switch' off" ++ cset "name='media_loop2_out mix 0 sprot_loop_in Switch' off" ++ ++ cset "name='sprot_loop_out mix 0 codec_in0 Switch' off" ++ cset "name='sprot_loop_out mix 0 codec_in1 Switch' off" ++ cset "name='sprot_loop_out mix 0 media_loop1_in Switch' off" ++ cset "name='sprot_loop_out mix 0 media_loop2_in Switch' off" ++ cset "name='sprot_loop_out mix 0 pcm0_in Switch' off" ++ cset "name='sprot_loop_out mix 0 pcm1_in Switch' off" ++ cset "name='sprot_loop_out mix 0 sprot_loop_in Switch' off" ++ ++ # Output Configuration ++ cset "name='DAC1 L Mux' IF1 DAC" ++ cset "name='DAC1 R Mux' IF1 DAC" ++ cset "name='DAC1 MIXL DAC1 Switch' 1" ++ cset "name='DAC1 MIXR DAC1 Switch' 1" ++ cset "name='Stereo DAC MIXL DAC L1 Switch' 1" ++ cset "name='Stereo DAC MIXR DAC R1 Switch' 1" ++ ++ cset "name='DAC L2 Mux' IF2 DAC" ++ cset "name='DAC R2 Mux' IF2 DAC" ++ cset "name='Mono DAC MIXL DAC L2 Switch' on" ++ cset "name='Mono DAC MIXR DAC R2 Switch' on" ++ cset "name='DAC2 Playback Switch' on" ++ ++ cset "name='HPOVOL MIXL DAC1 Switch' on" ++ cset "name='HPOVOL MIXR DAC1 Switch' on" ++ cset "name='HPOVOL MIXL DAC2 Switch' on" ++ cset "name='HPOVOL MIXR DAC2 Switch' on" ++ cset "name='HPO MIX HPVOL Switch' on" ++ cset "name='HPOVOL L Switch' on" ++ cset "name='HPOVOL R Switch' on" ++ ++ cset "name='SPK MIXL DAC L1 Switch' on" ++ cset "name='SPK MIXR DAC R1 Switch' on" ++ cset "name='SPK MIXL DAC L2 Switch' on" ++ cset "name='SPK MIXR DAC R2 Switch' on" ++ cset "name='SPOL MIX SPKVOL L Switch' on" ++ cset "name='SPOR MIX SPKVOL R Switch' on" ++ cset "name='SPKVOL L Switch' on" ++ cset "name='SPKVOL R Switch' on" ++ ++ # Input Configuration ++ cset "name='Stereo1 DMIC Mux' 0" ++ cset "name='Stereo1 ADC1 Mux' 1" ++ cset "name='Stereo1 ADC2 Mux' 1" ++ cset "name='ADC Capture Switch' on" ++ # 55/63 ++ cset "name='ADC Capture Volume' 55" ++ # set ADC Boost to 0/3, higher vals cause a lot of white noise ++ cset "name='ADC Boost Capture Volume' 0" ++ # 55/63 ++ cset "name='Mono ADC Capture Volume' 55" ++ # 0/3 ++ cset "name='Mono ADC Boost Capture Volume' 0" ++ # 27/31 ++ cset "name='IN Capture Volume' 27" ++ cset "name='I2S2 Func Switch' on" ++ # 3/12 the headphone mic tends to be quite loud ++ cset "name='IN1 Boost' 3" ++ # 8/8 the internal analog mic tends to be quite soft ++ cset "name='IN2 Boost' 8" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ # Disable audio output path ++ cset "name='codec_out1 mix 0 pcm0_in Switch' off" ++ cset "name='media0_out mix 0 media1_in Switch' off" ++ ++ cset "name='media1_in Gain 0 Switch' off" ++ cset "name='pcm0_in Gain 0 Switch' off" ++ cset "name='codec_out1 Gain 0 Switch' off" ++ ++ # Disable audio input path ++ cset "name='pcm1_out mix 0 media_loop2_in Switch' off" ++ cset "name='media_loop2_out mix 0 codec_in0 Switch' off" ++ ++ cset "name='media_loop2_out Gain 0 Switch' off" ++ cset "name='pcm1_out Gain 0 Switch' off" ++ cset "name='codec_in0 Gain 0 Switch' off" ++ ] ++} ++ ++SectionDevice."Speaker" { ++ Comment "Speaker" ++ ++ Value { ++ PlaybackChannels "2" ++ } ++ ++ ConflictingDevice [ ++ "Headphones" ++ ] ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Headphone Switch' off" ++ cset "name='Headphone Channel Switch' off" ++ ++ cset "name='Ext Spk Switch' on" ++ cset "name='Speaker Channel Switch' on" ++ cset "name='Speaker Playback Volume' 31" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Ext Spk Switch' off" ++ cset "name='Speaker Channel Switch' off" ++ ] ++} ++ ++SectionDevice."Headphones" { ++ Comment "Headphones" ++ ++ Value { ++ PlaybackChannels "2" ++ JackControl "Headphone Jack" ++ JackHWMute "Speaker" ++ } ++ ++ ConflictingDevice [ ++ "Speaker" ++ ] ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Ext Spk Switch' off" ++ cset "name='Speaker Channel Switch' off" ++ ++ cset "name='Headphone Switch' on" ++ cset "name='Headphone Channel Switch' on" ++ # 25/39 higher values cause crackling on some boards ++ cset "name='Headphone Playback Volume' 25" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Headphone Switch' off" ++ cset "name='Headphone Channel Switch' off" ++ ] ++} ++ ++SectionDevice."DMic".0 { ++ Comment "Internal Microphone" ++ ++ Value { ++ CaptureChannels "2" ++ CapturePriority "150" ++ } ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Int Mic Switch' on" ++ ++ cset "name='Stereo1 DMIC Mux' DMIC2" ++ cset "name='Stereo1 ADC2 Mux' DMIC" ++ cset "name='Mono DMIC L Mux' DMIC2" ++ cset "name='Mono DMIC R Mux' DMIC2" ++ cset "name='Mono ADC L2 Mux' DMIC" ++ cset "name='Mono ADC R2 Mux' DMIC" ++ ++ cset "name='Sto1 ADC MIXL ADC1 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC1 Switch' off" ++ cset "name='Sto1 ADC MIXL ADC2 Switch' on" ++ cset "name='Sto1 ADC MIXR ADC2 Switch' on" ++ cset "name='Mono ADC MIXL ADC1 Switch' off" ++ cset "name='Mono ADC MIXR ADC1 Switch' off" ++ cset "name='Mono ADC MIXL ADC2 Switch' on" ++ cset "name='Mono ADC MIXR ADC2 Switch' on" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Sto1 ADC MIXL ADC2 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC2 Switch' off" ++ cset "name='Mono ADC MIXL ADC2 Switch' off" ++ cset "name='Mono ADC MIXR ADC2 Switch' off" ++ cset "name='Int Mic Switch' off" ++ ] ++} ++ ++SectionDevice."HSMic".0 { ++ Comment "Headset Microphone" ++ ++ Value { ++ CaptureChannels "2" ++ JackControl "Headset Mic Jack" ++ JackHWMute "DMic" ++ } ++ ++ EnableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Headset Mic Switch' on" ++ ++ cset "name='Sto1 ADC MIXL ADC1 Switch' on" ++ cset "name='Sto1 ADC MIXR ADC1 Switch' on" ++ cset "name='Sto1 ADC MIXL ADC2 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC2 Switch' off" ++ ++ cset "name='Mono ADC MIXL ADC1 Switch' on" ++ cset "name='Mono ADC MIXR ADC1 Switch' on" ++ cset "name='Mono ADC MIXL ADC2 Switch' off" ++ cset "name='Mono ADC MIXR ADC2 Switch' off" ++ ++ cset "name='RECMIXL BST1 Switch' on" ++ cset "name='RECMIXR BST1 Switch' on" ++ ++ ] ++ ++ DisableSequence [ ++ cdev "hw:chtrt5645" ++ ++ cset "name='Headset Mic Switch' off" ++ ++ cset "name='RECMIXL BST1 Switch' off" ++ cset "name='RECMIXR BST1 Switch' off" ++ cset "name='Sto1 ADC MIXL ADC1 Switch' off" ++ cset "name='Sto1 ADC MIXR ADC1 Switch' off" ++ cset "name='Mono ADC MIXL ADC1 Switch' on" ++ cset "name='Mono ADC MIXR ADC1 Switch' on" ++ ++ ] ++} +diff --git a/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216.conf b/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216.conf +new file mode 100644 +index 00000000..50bda000 +--- /dev/null ++++ b/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216.conf +@@ -0,0 +1,5 @@ ++Comment "Intel SoC Audio Device" ++SectionUseCase."HiFi" { ++ File "../LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/HiFi.conf" ++ Comment "Default" ++} +diff --git a/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/Makefile.am b/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/Makefile.am +new file mode 100644 +index 00000000..18963c21 +--- /dev/null ++++ b/src/conf/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216/Makefile.am +@@ -0,0 +1,4 @@ ++alsaconfigdir = @ALSA_CONFIG_DIR@ ++ucmdir = $(alsaconfigdir)/ucm/LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216 ++ucm_DATA = LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216.conf HiFi.conf ++EXTRA_DIST = $(ucm_DATA) +diff --git a/src/conf/ucm/Makefile.am b/src/conf/ucm/Makefile.am +index e496ca89..02df25f0 100644 +--- a/src/conf/ucm/Makefile.am ++++ b/src/conf/ucm/Makefile.am +@@ -11,6 +11,7 @@ GoogleNyan \ + gpd-win-pocket-rt5645 \ + HDAudio-Gigabyte-ALC1220DualCodecs \ + HDAudio-Lenovo-DualCodecs \ ++LENOVO-80XF-LenovoMIIX320_10ICR-LNVNB161216 \ + PandaBoard \ + PandaBoardES \ + PAZ00 \ +-- +2.13.6 + + +From 8ebb40c96970c913719a75deb2fe82ba2e257386 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 2 May 2018 16:23:21 +0200 +Subject: [PATCH 16/26] conf/ucm: Add a UCM profile for Dell WD15 Dock + USB-audio + +USB-audio device on Dell WD15 docking station provides two individual +PCM streams, one for headphone and another for line out. A UCM +profile gives the proper roles for these. + +Signed-off-by: Takashi Iwai +--- + src/conf/ucm/Dell-WD15-Dock/Dell-WD15-Dock.conf | 5 +++++ + src/conf/ucm/Dell-WD15-Dock/HiFi.conf | 26 +++++++++++++++++++++++++ + src/conf/ucm/Dell-WD15-Dock/Makefile.am | 4 ++++ + src/conf/ucm/Makefile.am | 1 + + 4 files changed, 36 insertions(+) + create mode 100644 src/conf/ucm/Dell-WD15-Dock/Dell-WD15-Dock.conf + create mode 100644 src/conf/ucm/Dell-WD15-Dock/HiFi.conf + create mode 100644 src/conf/ucm/Dell-WD15-Dock/Makefile.am + +diff --git a/src/conf/ucm/Dell-WD15-Dock/Dell-WD15-Dock.conf b/src/conf/ucm/Dell-WD15-Dock/Dell-WD15-Dock.conf +new file mode 100644 +index 00000000..f4f0a8d9 +--- /dev/null ++++ b/src/conf/ucm/Dell-WD15-Dock/Dell-WD15-Dock.conf +@@ -0,0 +1,5 @@ ++Comment "USB-audio on Dell WD15 docking station" ++SectionUseCase."HiFi" { ++ File "HiFi.conf" ++ Comment "Default" ++} +diff --git a/src/conf/ucm/Dell-WD15-Dock/HiFi.conf b/src/conf/ucm/Dell-WD15-Dock/HiFi.conf +new file mode 100644 +index 00000000..b07f3440 +--- /dev/null ++++ b/src/conf/ucm/Dell-WD15-Dock/HiFi.conf +@@ -0,0 +1,26 @@ ++SectionDevice."Headphone" { ++ Comment "Headphone" ++ ++ Value { ++ PlaybackChannels "2" ++ PlaybackPCM "hw:WD15Dock,0" ++ } ++} ++ ++SectionDevice."LineOut" { ++ Comment "Line Out" ++ ++ Value { ++ PlaybackChannels "2" ++ PlaybackPCM "hw:WD15Dock,1" ++ } ++} ++ ++SectionDevice."Mic" { ++ Comment "Microphone" ++ ++ Value { ++ CaptureChannels "2" ++ CapturePCM "hw:WD15Dock,0" ++ } ++} +diff --git a/src/conf/ucm/Dell-WD15-Dock/Makefile.am b/src/conf/ucm/Dell-WD15-Dock/Makefile.am +new file mode 100644 +index 00000000..7ab58730 +--- /dev/null ++++ b/src/conf/ucm/Dell-WD15-Dock/Makefile.am +@@ -0,0 +1,4 @@ ++alsaconfigdir = @ALSA_CONFIG_DIR@ ++ucmdir = $(alsaconfigdir)/ucm/Dell-WD15-Dock ++ucm_DATA = Dell-WD15-Dock.conf HiFi.conf ++EXTRA_DIST = $(ucm_DATA) +diff --git a/src/conf/ucm/Makefile.am b/src/conf/ucm/Makefile.am +index 02df25f0..38fc6b25 100644 +--- a/src/conf/ucm/Makefile.am ++++ b/src/conf/ucm/Makefile.am +@@ -7,6 +7,7 @@ chtrt5645 \ + chtrt5645-mono-speaker-analog-mic \ + DAISY-I2S \ + DB410c \ ++Dell-WD15-Dock \ + GoogleNyan \ + gpd-win-pocket-rt5645 \ + HDAudio-Gigabyte-ALC1220DualCodecs \ +-- +2.13.6 + + +From 44f499bb22f3923f966e11a234455e3d06936b8b Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 3 May 2018 08:40:20 +0200 +Subject: [PATCH 17/26] configure: Fix forgotten ucm entry + +The previous commit forgot to add to configure.ac. Fix it. + +Signed-off-by: Takashi Iwai +--- + configure.ac | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configure.ac b/configure.ac +index 3ee989eb..693b5d53 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -725,6 +725,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \ + src/conf/ucm/chtrt5645-mono-speaker-analog-mic/Makefile \ + src/conf/ucm/DAISY-I2S/Makefile \ + src/conf/ucm/DB410c/Makefile \ ++ src/conf/ucm/Dell-WD15-Dock/Makefile \ + src/conf/ucm/GoogleNyan/Makefile \ + src/conf/ucm/gpd-win-pocket-rt5645/Makefile \ + src/conf/ucm/HDAudio-Gigabyte-ALC1220DualCodecs/Makefile \ +-- +2.13.6 + + +From 5eb78219f6bc0114cbb6518dae1c9256a63ec23a Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Tue, 15 May 2018 21:36:34 +0900 +Subject: [PATCH 18/26] control: add a series of macro for offset of several + types of TLV + +In development period for Linux v4.18, a series of SNDRV_CTL_TLVO_XXX +macro was introduced to kernel stuffs for position offset of TLV data. + +This commit adds these macros to backport header in this library. + +Signed-off-by: Takashi Sakamoto +Signed-off-by: Takashi Iwai +--- + include/sound/tlv.h | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/include/sound/tlv.h b/include/sound/tlv.h +index b4df440c..2ea47685 100644 +--- a/include/sound/tlv.h ++++ b/include/sound/tlv.h +@@ -41,6 +41,10 @@ + #define SNDRV_CTL_TLVD_LENGTH(...) \ + ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ })) + ++/* Accessor offsets for TLV data items */ ++#define SNDRV_CTL_TLVO_TYPE 0 ++#define SNDRV_CTL_TLVO_LEN 1 ++ + #define SNDRV_CTL_TLVD_CONTAINER_ITEM(...) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__) + #define SNDRV_CTL_TLVD_DECLARE_CONTAINER(name, ...) \ +@@ -60,6 +64,10 @@ + SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \ + } + ++/* Accessor offsets for min, mute and step items in dB scale type TLV */ ++#define SNDRV_CTL_TLVO_DB_SCALE_MIN 2 ++#define SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP 3 ++ + /* dB scale specified with min/max values instead of step */ + #define SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB)) +@@ -74,6 +82,10 @@ + SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \ + } + ++/* Accessor offsets for min, max items in db-minmax types of TLV. */ ++#define SNDRV_CTL_TLVO_DB_MINMAX_MIN 2 ++#define SNDRV_CTL_TLVO_DB_MINMAX_MAX 3 ++ + /* linear volume between min_dB and max_dB (.01dB unit) */ + #define SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \ + SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB)) +@@ -82,6 +94,10 @@ + SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \ + } + ++/* Accessor offsets for min, max items in db-linear type of TLV. */ ++#define SNDRV_CTL_TLVO_DB_LINEAR_MIN 2 ++#define SNDRV_CTL_TLVO_DB_LINEAR_MAX 3 ++ + /* dB range container: + * Items in dB range container must be ordered by their values and by their + * dB values. This implies that larger values must correspond with larger +-- +2.13.6 + + +From f61193c96c52cbd99e22d9cbb94937374ce2cb39 Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Tue, 15 May 2018 21:36:35 +0900 +Subject: [PATCH 19/26] control: use position offset macro of TLV data + +A series of SNDRV_CTL_TLVO_XXX macro was introduced for position offset +of TLV data. This commit applies a code optimization. + +Signed-off-by: Takashi Sakamoto +Signed-off-by: Takashi Iwai +--- + src/control/control.c | 12 ++++---- + src/control/control_hw.c | 6 ++-- + src/control/control_local.h | 1 + + src/control/tlv.c | 72 ++++++++++++++++++++++++--------------------- + 4 files changed, 51 insertions(+), 40 deletions(-) + +diff --git a/src/control/control.c b/src/control/control.c +index 11f7815a..82cd1a05 100644 +--- a/src/control/control.c ++++ b/src/control/control.c +@@ -938,10 +938,10 @@ int snd_ctl_elem_tlv_read(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + * and compare the returned value after ioctl for checking + * the validity of TLV. + */ +- tlv[0] = -1; +- tlv[1] = 0; ++ tlv[SNDRV_CTL_TLVO_TYPE] = -1; ++ tlv[SNDRV_CTL_TLVO_LEN] = 0; + err = snd_ctl_tlv_do(ctl, 0, id, tlv, tlv_size); +- if (err >= 0 && tlv[0] == (unsigned int)-1) ++ if (err >= 0 && tlv[SNDRV_CTL_TLVO_TYPE] == (unsigned int)-1) + err = -ENXIO; + return err; + } +@@ -967,7 +967,8 @@ int snd_ctl_elem_tlv_write(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + const unsigned int *tlv) + { + assert(ctl && id && (id->name[0] || id->numid) && tlv); +- return snd_ctl_tlv_do(ctl, 1, id, (unsigned int *)tlv, tlv[1] + 2 * sizeof(unsigned int)); ++ return snd_ctl_tlv_do(ctl, 1, id, (unsigned int *)tlv, ++ tlv[SNDRV_CTL_TLVO_LEN] + 2 * sizeof(unsigned int)); + } + + /** +@@ -991,7 +992,8 @@ int snd_ctl_elem_tlv_command(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id, + const unsigned int *tlv) + { + assert(ctl && id && (id->name[0] || id->numid) && tlv); +- return snd_ctl_tlv_do(ctl, -1, id, (unsigned int *)tlv, tlv[1] + 2 * sizeof(unsigned int)); ++ return snd_ctl_tlv_do(ctl, -1, id, (unsigned int *)tlv, ++ tlv[SNDRV_CTL_TLVO_LEN] + 2 * sizeof(unsigned int)); + } + + /** +diff --git a/src/control/control_hw.c b/src/control/control_hw.c +index 4cbd306f..68eca522 100644 +--- a/src/control/control_hw.c ++++ b/src/control/control_hw.c +@@ -240,11 +240,13 @@ static int snd_ctl_hw_elem_tlv(snd_ctl_t *handle, int op_flag, + return -errno; + } + if (op_flag == 0) { +- if (xtlv->tlv[1] + 2 * sizeof(unsigned int) > tlv_size) { ++ unsigned int size; ++ size = xtlv->tlv[SNDRV_CTL_TLVO_LEN] + 2 * sizeof(unsigned int); ++ if (size > tlv_size) { + free(xtlv); + return -EFAULT; + } +- memcpy(tlv, xtlv->tlv, xtlv->tlv[1] + 2 * sizeof(unsigned int)); ++ memcpy(tlv, xtlv->tlv, size); + } + free(xtlv); + return 0; +diff --git a/src/control/control_local.h b/src/control/control_local.h +index 30218c6c..9568968e 100644 +--- a/src/control/control_local.h ++++ b/src/control/control_local.h +@@ -20,6 +20,7 @@ + */ + + #include "local.h" ++#include + + typedef struct _snd_ctl_ops { + int (*close)(snd_ctl_t *handle); +diff --git a/src/control/tlv.c b/src/control/tlv.c +index 467023b3..d6944b52 100644 +--- a/src/control/tlv.c ++++ b/src/control/tlv.c +@@ -65,8 +65,8 @@ int snd_tlv_parse_dB_info(unsigned int *tlv, + int err; + + *db_tlvp = NULL; +- type = tlv[0]; +- size = tlv[1]; ++ type = tlv[SNDRV_CTL_TLVO_TYPE]; ++ size = tlv[SNDRV_CTL_TLVO_LEN]; + tlv_size -= 2 * sizeof(int); + if (size > tlv_size) { + SNDERR("TLV size error"); +@@ -83,7 +83,7 @@ int snd_tlv_parse_dB_info(unsigned int *tlv, + return err; /* error */ + if (err > 0) + return err; /* found */ +- len = int_index(tlv[1]) + 2; ++ len = int_index(tlv[SNDRV_CTL_TLVO_LEN]) + 2; + size -= len * sizeof(int); + tlv += len; + } +@@ -131,10 +131,10 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax, + { + int err; + +- switch (tlv[0]) { ++ switch (tlv[SNDRV_CTL_TLVO_TYPE]) { + case SND_CTL_TLVT_DB_RANGE: { + unsigned int pos, len; +- len = int_index(tlv[1]); ++ len = int_index(tlv[SNDRV_CTL_TLVO_LEN]); + if (len > MAX_TLV_RANGE_SIZE) + return -EINVAL; + pos = 2; +@@ -167,22 +167,23 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax, + } + case SND_CTL_TLVT_DB_SCALE: { + int step; +- if (tlv[3] & 0x10000) ++ if (tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 0x10000) + *min = SND_CTL_TLV_DB_GAIN_MUTE; + else +- *min = (int)tlv[2]; +- step = (tlv[3] & 0xffff); +- *max = (int)tlv[2] + step * (rangemax - rangemin); ++ *min = (int)tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN]; ++ step = (tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 0xffff); ++ *max = (int)tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] + ++ step * (rangemax - rangemin); + return 0; + } + case SND_CTL_TLVT_DB_MINMAX: + case SND_CTL_TLVT_DB_LINEAR: +- *min = (int)tlv[2]; +- *max = (int)tlv[3]; ++ *min = (int)tlv[SNDRV_CTL_TLVO_DB_LINEAR_MIN]; ++ *max = (int)tlv[SNDRV_CTL_TLVO_DB_LINEAR_MAX]; + return 0; + case SND_CTL_TLVT_DB_MINMAX_MUTE: + *min = SND_CTL_TLV_DB_GAIN_MUTE; +- *max = (int)tlv[3]; ++ *max = (int)tlv[SNDRV_CTL_TLVO_DB_MINMAX_MAX]; + return 0; + } + return -EINVAL; +@@ -200,10 +201,12 @@ int snd_tlv_get_dB_range(unsigned int *tlv, long rangemin, long rangemax, + int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax, + long volume, long *db_gain) + { +- switch (tlv[0]) { ++ unsigned int type = tlv[SNDRV_CTL_TLVO_TYPE]; ++ ++ switch (type) { + case SND_CTL_TLVT_DB_RANGE: { + unsigned int pos, len; +- len = int_index(tlv[1]); ++ len = int_index(tlv[SNDRV_CTL_TLVO_LEN]); + if (len > MAX_TLV_RANGE_SIZE) + return -EINVAL; + pos = 2; +@@ -220,9 +223,9 @@ int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax, + } + case SND_CTL_TLVT_DB_SCALE: { + int min, step, mute; +- min = tlv[2]; +- step = (tlv[3] & 0xffff); +- mute = (tlv[3] >> 16) & 1; ++ min = tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN]; ++ step = (tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 0xffff); ++ mute = (tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] >> 16) & 1; + if (mute && volume <= rangemin) + *db_gain = SND_CTL_TLV_DB_GAIN_MUTE; + else +@@ -232,10 +235,10 @@ int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax, + case SND_CTL_TLVT_DB_MINMAX: + case SND_CTL_TLVT_DB_MINMAX_MUTE: { + int mindb, maxdb; +- mindb = tlv[2]; +- maxdb = tlv[3]; ++ mindb = tlv[SNDRV_CTL_TLVO_DB_MINMAX_MIN]; ++ maxdb = tlv[SNDRV_CTL_TLVO_DB_MINMAX_MAX]; + if (volume <= rangemin || rangemax <= rangemin) { +- if (tlv[0] == SND_CTL_TLVT_DB_MINMAX_MUTE) ++ if (type == SND_CTL_TLVT_DB_MINMAX_MUTE) + *db_gain = SND_CTL_TLV_DB_GAIN_MUTE; + else + *db_gain = mindb; +@@ -248,8 +251,8 @@ int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax, + } + #ifndef HAVE_SOFT_FLOAT + case SND_CTL_TLVT_DB_LINEAR: { +- int mindb = tlv[2]; +- int maxdb = tlv[3]; ++ int mindb = tlv[SNDRV_CTL_TLVO_DB_LINEAR_MIN]; ++ int maxdb = tlv[SNDRV_CTL_TLVO_DB_LINEAR_MAX]; + if (volume <= rangemin || rangemax <= rangemin) + *db_gain = mindb; + else if (volume >= rangemax) +@@ -289,11 +292,13 @@ int snd_tlv_convert_to_dB(unsigned int *tlv, long rangemin, long rangemax, + int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, + long db_gain, long *value, int xdir) + { +- switch (tlv[0]) { ++ unsigned int type = tlv[SNDRV_CTL_TLVO_TYPE]; ++ ++ switch (type) { + case SND_CTL_TLVT_DB_RANGE: { + long dbmin, dbmax, prev_submax; + unsigned int pos, len; +- len = int_index(tlv[1]); ++ len = int_index(tlv[SNDRV_CTL_TLVO_LEN]); + if (len < 6 || len > MAX_TLV_RANGE_SIZE) + return -EINVAL; + pos = 2; +@@ -324,13 +329,14 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, + return 0; + } + case SND_CTL_TLVT_DB_SCALE: { +- int min, step, max; +- min = tlv[2]; +- step = (tlv[3] & 0xffff); ++ int min, step, max, mute; ++ min = tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN]; ++ step = tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 0xffff; ++ mute = tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] & 0x10000; + max = min + (int)(step * (rangemax - rangemin)); + if (db_gain <= min) + if (db_gain > SND_CTL_TLV_DB_GAIN_MUTE && xdir > 0 && +- (tlv[3] & 0x10000)) ++ mute) + *value = rangemin + 1; + else + *value = rangemin; +@@ -348,11 +354,11 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, + case SND_CTL_TLVT_DB_MINMAX: + case SND_CTL_TLVT_DB_MINMAX_MUTE: { + int min, max; +- min = tlv[2]; +- max = tlv[3]; ++ min = tlv[SNDRV_CTL_TLVO_DB_MINMAX_MIN]; ++ max = tlv[SNDRV_CTL_TLVO_DB_MINMAX_MAX]; + if (db_gain <= min) + if (db_gain > SND_CTL_TLV_DB_GAIN_MUTE && xdir > 0 && +- tlv[0] == SND_CTL_TLVT_DB_MINMAX_MUTE) ++ type == SND_CTL_TLVT_DB_MINMAX_MUTE) + *value = rangemin + 1; + else + *value = rangemin; +@@ -370,8 +376,8 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax, + #ifndef HAVE_SOFT_FLOAT + case SND_CTL_TLVT_DB_LINEAR: { + int min, max; +- min = tlv[2]; +- max = tlv[3]; ++ min = tlv[SNDRV_CTL_TLVO_DB_LINEAR_MIN]; ++ max = tlv[SNDRV_CTL_TLVO_DB_LINEAR_MAX]; + if (db_gain <= min) + *value = rangemin; + else if (db_gain >= max) +-- +2.13.6 + + +From 33f0888f0da191af49f17916f6548076d7125ea9 Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Tue, 15 May 2018 21:36:36 +0900 +Subject: [PATCH 20/26] hcontrol: use position offset macro of TLV data + +A series of SNDRV_CTL_TLVO_XXX macro was introduced for position offset +of TLV data. This commit applies a code optimization. + +Signed-off-by: Takashi Sakamoto +Signed-off-by: Takashi Iwai +--- + src/control/hcontrol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/control/hcontrol.c b/src/control/hcontrol.c +index 7e775248..0cac8956 100644 +--- a/src/control/hcontrol.c ++++ b/src/control/hcontrol.c +@@ -870,7 +870,7 @@ int snd_hctl_elem_tlv_write(snd_hctl_elem_t *elem, const unsigned int *tlv) + { + assert(elem); + assert(tlv); +- assert(tlv[1] >= 4); ++ assert(tlv[SNDRV_CTL_TLVO_LEN] >= 4); + return snd_ctl_elem_tlv_write(elem->hctl->ctl, &elem->id, tlv); + } + +@@ -886,7 +886,7 @@ int snd_hctl_elem_tlv_command(snd_hctl_elem_t *elem, const unsigned int *tlv) + { + assert(elem); + assert(tlv); +- assert(tlv[1] >= 4); ++ assert(tlv[SNDRV_CTL_TLVO_LEN] >= 4); + return snd_ctl_elem_tlv_command(elem->hctl->ctl, &elem->id, tlv); + } + +-- +2.13.6 + + +From b0b720513ee35ec0a5afada0b240310f2f2e1b30 Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Tue, 15 May 2018 21:36:37 +0900 +Subject: [PATCH 21/26] pcm: hw: use position offset macro of TLV data + +A series of SNDRV_CTL_TLVO_XXX macro was introduced for position offset +of TLV data. This commit applies a code optimization. + +Signed-off-by: Takashi Sakamoto +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_hw.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c +index 65b198c5..a728b23b 100644 +--- a/src/pcm/pcm_hw.c ++++ b/src/pcm/pcm_hw.c +@@ -1199,6 +1199,7 @@ snd_pcm_query_chmaps_from_hw(int card, int dev, int subdev, + snd_ctl_t *ctl; + snd_ctl_elem_id_t id = {0}; + unsigned int tlv[2048], *start; ++ unsigned int type; + snd_pcm_chmap_query_t **map; + int i, ret, nums; + +@@ -1223,9 +1224,10 @@ snd_pcm_query_chmaps_from_hw(int card, int dev, int subdev, + /* FIXME: the parser below assumes that the TLV only contains + * chmap-related blocks + */ +- if (tlv[0] != SND_CTL_TLVT_CONTAINER) { +- if (!is_chmap_type(tlv[0])) { +- SYSMSG("Invalid TLV type %d\n", tlv[0]); ++ type = tlv[SNDRV_CTL_TLVO_TYPE]; ++ if (type != SND_CTL_TLVT_CONTAINER) { ++ if (!is_chmap_type(type)) { ++ SYSMSG("Invalid TLV type %d\n", type); + return NULL; + } + start = tlv; +@@ -1234,7 +1236,7 @@ snd_pcm_query_chmaps_from_hw(int card, int dev, int subdev, + unsigned int *p; + int size; + start = tlv + 2; +- size = tlv[1]; ++ size = tlv[SNDRV_CTL_TLVO_LEN]; + nums = 0; + for (p = start; size > 0; ) { + if (!is_chmap_type(p[0])) { +-- +2.13.6 + + +From 6dc2ed4090bee0e5516839173166c6a35c3d80be Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Tue, 15 May 2018 21:36:38 +0900 +Subject: [PATCH 22/26] pcm: softvol: use position offset macro of TLV data + +A series of SNDRV_CTL_TLVO_XXX macro was introduced for position offset +of TLV data. This commit applies a code optimization. + +Signed-off-by: Takashi Sakamoto +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_softvol.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c +index 0eaeacef..f08208f8 100644 +--- a/src/pcm/pcm_softvol.c ++++ b/src/pcm/pcm_softvol.c +@@ -31,6 +31,8 @@ + #include "pcm_local.h" + #include "pcm_plugin.h" + ++#include ++ + #ifndef PIC + /* entry for static linking */ + const char *_snd_module_pcm_softvol = ""; +@@ -708,10 +710,11 @@ static void snd_pcm_softvol_dump(snd_pcm_t *pcm, snd_output_t *out) + static int add_tlv_info(snd_pcm_softvol_t *svol, snd_ctl_elem_info_t *cinfo) + { + unsigned int tlv[4]; +- tlv[0] = SND_CTL_TLVT_DB_SCALE; +- tlv[1] = 2 * sizeof(int); +- tlv[2] = (int)(svol->min_dB * 100); +- tlv[3] = (int)((svol->max_dB - svol->min_dB) * 100 / svol->max_val); ++ tlv[SNDRV_CTL_TLVO_TYPE] = SND_CTL_TLVT_DB_SCALE; ++ tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(int); ++ tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = (int)(svol->min_dB * 100); ++ tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] = ++ (int)((svol->max_dB - svol->min_dB) * 100 / svol->max_val); + return snd_ctl_elem_tlv_write(svol->ctl, &cinfo->id, tlv); + } + +-- +2.13.6 + + +From 275a438d425c3477be21e1929061f0c1605876f2 Mon Sep 17 00:00:00 2001 +From: Takashi Sakamoto +Date: Tue, 15 May 2018 21:36:39 +0900 +Subject: [PATCH 23/26] test: use position offset macro of TLV data + +A series of SNDRV_CTL_TLVO_XXX macro was introduced for position offset +of TLV data. This commit applies a code optimization. + +Signed-off-by: Takashi Sakamoto +Signed-off-by: Takashi Iwai +--- + test/user-ctl-element-set.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/user-ctl-element-set.c b/test/user-ctl-element-set.c +index e94152b9..fee130e2 100644 +--- a/test/user-ctl-element-set.c ++++ b/test/user-ctl-element-set.c +@@ -660,7 +660,7 @@ static int check_tlv(struct elem_set_trial *trial) + if (err < 0) + return err; + +- len = tlv[1] + sizeof(unsigned int) * 2; ++ len = tlv[SNDRV_CTL_TLVO_LEN] + sizeof(unsigned int) * 2; + curr = malloc(len); + if (curr == NULL) { + free(tlv); +-- +2.13.6 + + +From 9ee3e4338f46f18a5cddc267bbb19c7a222c5801 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 22 May 2018 14:10:59 +0200 +Subject: [PATCH 24/26] conf: USB-audio: Fix for Xonar U7 SPDIF device + +Add the entry for Xonar U7 to make SPDIF working on it. + +Reported-by: Steve Banks +Signed-off-by: Takashi Iwai +--- + src/conf/cards/USB-Audio.conf | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/conf/cards/USB-Audio.conf b/src/conf/cards/USB-Audio.conf +index 2b8f9a29..05779c47 100644 +--- a/src/conf/cards/USB-Audio.conf ++++ b/src/conf/cards/USB-Audio.conf +@@ -38,6 +38,7 @@ USB-Audio.pcm.surround40_type { + USB-Audio.pcm.iec958_device { + # "NoiseBlaster 3000" 42 + "USB Sound Blaster HD" 1 ++ "Xonar U7" 1 + + # The below don't have digital in/out, so prevent them from being opened. + "Andrea PureAudio USB-SA Headset" 999 +-- +2.13.6 + + +From 4740dd97bf54d67f0edef80e1b9e86c04c8ed402 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 23 May 2018 10:33:40 +0200 +Subject: [PATCH 25/26] pcm: add missing flags initialization for the fallback + control data + +Signed-off-by: Jaroslav Kysela +--- + src/pcm/pcm_hw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c +index a728b23b..59a24200 100644 +--- a/src/pcm/pcm_hw.c ++++ b/src/pcm/pcm_hw.c +@@ -1018,7 +1018,7 @@ 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) { +- unsigned int flags; ++ unsigned int flags = 0; + /* read appl_ptr and avail_min from kernel when device opened + * with SND_PCM_APPEND flag + */ +-- +2.13.6 + + +From ad5aea89226f131f27790c98c4638e4596060f81 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Wed, 23 May 2018 10:36:17 +0200 +Subject: [PATCH 26/26] pcm ioplug: fix some coverity issues (switch, missing + unlock in snd_pcm_ioplug_drain()) + +Signed-off-by: Jaroslav Kysela +--- + src/pcm/pcm_ioplug.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c +index db64853b..4d44ae22 100644 +--- a/src/pcm/pcm_ioplug.c ++++ b/src/pcm/pcm_ioplug.c +@@ -533,6 +533,7 @@ static int snd_pcm_ioplug_drain(snd_pcm_t *pcm) + case SND_PCM_STATE_OPEN: + case SND_PCM_STATE_DISCONNECTED: + case SND_PCM_STATE_SUSPENDED: ++ snd_pcm_unlock(pcm); + return -EBADFD; + case SND_PCM_STATE_PREPARED: + if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { +@@ -545,6 +546,8 @@ static int snd_pcm_ioplug_drain(snd_pcm_t *pcm) + case SND_PCM_STATE_RUNNING: + io->data->state = SND_PCM_STATE_DRAINING; + break; ++ default: ++ break; + } + + if (io->data->state == SND_PCM_STATE_DRAINING) { +-- +2.13.6 + diff --git a/SPECS/alsa-lib.spec b/SPECS/alsa-lib.spec index 065b8a6..8f01603 100644 --- a/SPECS/alsa-lib.spec +++ b/SPECS/alsa-lib.spec @@ -4,7 +4,7 @@ Summary: The Advanced Linux Sound Architecture (ALSA) library Name: alsa-lib -Version: 1.1.4.1 +Version: 1.1.6 Release: 2%{?prever_dot}%{?dist} License: LGPLv2+ Group: System Environment/Libraries @@ -14,7 +14,7 @@ Source: ftp://ftp.alsa-project.org/pub/lib/%{name}-%{version}%{?prever}%{?post Source10: asound.conf Source11: modprobe-dist-alsa.conf Source12: modprobe-dist-oss.conf -Patch0: alsa-lib-1.1.4.1-post.patch +Patch0: alsa-lib-1.1.6-post.patch Patch1: alsa-lib-1.1.0-config.patch BuildRequires: doxygen @@ -100,7 +100,7 @@ find %{buildroot} -name '*.la' -delete %config %{_sysconfdir}/asound.conf /%{_lib}/libasound.so.* %{_bindir}/aserver -#%{_libdir}/alsa-lib/ +#{_libdir}/alsa-lib/ %{_datadir}/alsa/ /lib/modprobe.d/dist-* @@ -114,6 +114,10 @@ find %{buildroot} -name '*.la' -delete %{_datadir}/aclocal/alsa.m4 %changelog +* Tue May 22 2018 Jaroslav Kysela - 1.1.6-2 +- Updated to 1.1.6 +- Resolves: rhbz#1578680 + * Sun Oct 22 2017 Jaroslav Kysela - 1.1.4.1-2 - Updated to 1.1.4.1 - Resolves: rhbz#1485645