Accepting request 483406 from home:tiwai:branches:multimedia:libs
- Backport upstream fix patches, including the deadlock fix for aplay/arecord (boo#1031525): 0001-ucm-Add-ATTRIBUTE_UNUSED-for-unused-parameters-of-ex.patch 0002-ucm-parser-needs-limits.h.patch 0003-pcm-direct-allow-users-to-configure-different-period.patch 0004-pcm-dshare-enable-silence.patch 0005-pcm-rate-fix-the-hw_ptr-update-until-the-boundary-av.patch 0006-plugin-dynamically-update-avail_min-on-slave.patch 0007-rate-dynamic-update-avail_min-on-slave.patch 0008-topology-fix-unused-const-variable-warning.patch 0009-seq-improve-documentation-about-new-get-pid-card-fun.patch 0010-pcm-direct-returning-semop-error-code-for-semaphore-.patch 0011-pcm-direct-Fix-for-sync-issue-on-xrun-recover.patch 0012-pcm-direct-check-state-before-enter-poll-on-timer.patch 0013-pcm-direct-don-t-return-bogus-buffer-levels-in-xrun-.patch 0014-conf-ucm-broxton-add-broxton-rt298-conf-files.patch 0015-pcm-direct-Fix-deadlock-in-poll_descriptors.patch 0016-ucm-Assure-the-user-input-card-name-not-to-exceed-ma.patch 0017-ucm-Load-device-specific-configuration-file-based-on.patch 0018-ucm-Add-command-get-_file-to-get-the-config-file-nam.patch 0019-topology-Fix-incorrect-license-in-source-comments.patch 0020-conf-cards-add-support-for-pistachio-card.patch 0021-pcm-multi-Drop-the-fixed-slave_map-in-snd_pcm_multi_.patch 0022-conf-Add-card-config-for-Intel-HDMI-DP-LPE-audio.patch 0023-pcm-Avoid-lock-for-snd_pcm_nonblock.patch 0024-pcm-Disable-locking-in-async-mode.patch 0025-pcm-dmix-Allow-disabling-x86-optimizations.patch 0026-pcm-dmix_rewind-corrupts-application-pointer-fix.patch 0027-pcm-direct-fix-race-on-clearing-timer-events.patch 0028-pcm-file-Enable-file-writing-for-capture-path.patch OBS-URL: https://build.opensuse.org/request/show/483406 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=210
This commit is contained in:
parent
a577d8eaee
commit
6977966888
@ -0,0 +1,43 @@
|
||||
From 6ad2a9763d9aaab30c0470d039877b1bb61dda3b Mon Sep 17 00:00:00 2001
|
||||
From: Mengdong Lin <mengdong.lin@linux.intel.com>
|
||||
Date: Tue, 27 Dec 2016 18:08:58 +0800
|
||||
Subject: [PATCH 01/43] ucm: Add ATTRIBUTE_UNUSED for unused parameters of
|
||||
execute_component_seq()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
To fix the following warnings:
|
||||
|
||||
main.c: In function ‘execute_component_seq’:
|
||||
main.c:489:24: warning: unused parameter ‘value_list1’ [-Wunused-parameter]
|
||||
struct list_head *value_list1,
|
||||
^
|
||||
main.c:490:24: warning: unused parameter ‘value_list2’ [-Wunused-parameter]
|
||||
struct list_head *value_list2,
|
||||
^
|
||||
main.c:491:24: warning: unused parameter ‘value_list3’ [-Wunused-parameter]
|
||||
struct list_head *value_list3,
|
||||
^
|
||||
|
||||
Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/ucm/main.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/ucm/main.c
|
||||
+++ b/src/ucm/main.c
|
||||
@@ -486,9 +486,9 @@ static int execute_sequence(snd_use_case
|
||||
*/
|
||||
static int execute_component_seq(snd_use_case_mgr_t *uc_mgr,
|
||||
struct component_sequence *cmpt_seq,
|
||||
- struct list_head *value_list1,
|
||||
- struct list_head *value_list2,
|
||||
- struct list_head *value_list3,
|
||||
+ struct list_head *value_list1 ATTRIBUTE_UNUSED,
|
||||
+ struct list_head *value_list2 ATTRIBUTE_UNUSED,
|
||||
+ struct list_head *value_list3 ATTRIBUTE_UNUSED,
|
||||
char *cdev)
|
||||
{
|
||||
struct use_case_device *device = cmpt_seq->device;
|
24
0002-ucm-parser-needs-limits.h.patch
Normal file
24
0002-ucm-parser-needs-limits.h.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From 9ed4075f05a4242f32331f7f2c365767970f5003 Mon Sep 17 00:00:00 2001
|
||||
From: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
Date: Wed, 21 Dec 2016 19:46:34 -0300
|
||||
Subject: [PATCH 02/43] ucm: parser needs limits.h
|
||||
|
||||
It's using PATH_MAX which is defined there, otherwise the build fails on
|
||||
musl libc.
|
||||
|
||||
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/ucm/parser.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/src/ucm/parser.c
|
||||
+++ b/src/ucm/parser.c
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "ucm_local.h"
|
||||
#include <dirent.h>
|
||||
+#include <limits.h>
|
||||
|
||||
/** The name of the environment variable containing the UCM directory */
|
||||
#define ALSA_CONFIG_UCM_VAR "ALSA_CONFIG_UCM"
|
237
0003-pcm-direct-allow-users-to-configure-different-period.patch
Normal file
237
0003-pcm-direct-allow-users-to-configure-different-period.patch
Normal file
@ -0,0 +1,237 @@
|
||||
From 0a61c796810fcec8b386e5311e871b1744b45a67 Mon Sep 17 00:00:00 2001
|
||||
From: Joshua Frkuska <joshua_frkuska@mentor.com>
|
||||
Date: Fri, 30 Dec 2016 11:56:15 +0530
|
||||
Subject: [PATCH 03/43] pcm: direct: allow users to configure different period
|
||||
sizes
|
||||
|
||||
This patch allows the effective period size to be a multiple of the
|
||||
slave-pcm period size.
|
||||
Allowing only exact multiple of original period size is achieved by
|
||||
borrowing code from the kernel hwrules implementation.
|
||||
|
||||
This patch is intended to save cpu workload when for example, the
|
||||
slave operates with very small periods but a user does not need that
|
||||
small periods.
|
||||
|
||||
This feature is enabled by default and can be disabled by adding
|
||||
config option 'var_periodsize 0'.
|
||||
|
||||
Signed-off-by: Alexander Jahn <ajahn@de.adit-jv.com>
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 88 +++++++++++++++++++++++++++++++++++++++++++++------
|
||||
src/pcm/pcm_direct.h | 3 +
|
||||
src/pcm/pcm_dmix.c | 1
|
||||
src/pcm/pcm_dshare.c | 1
|
||||
src/pcm/pcm_dsnoop.c | 1
|
||||
5 files changed, 84 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -660,6 +660,29 @@ static int hw_param_interval_refine_minm
|
||||
return hw_param_interval_refine_one(params, var, &t);
|
||||
}
|
||||
|
||||
+/* this code is used 'as-is' from the alsa kernel code */
|
||||
+static int snd_interval_step(struct snd_interval *i, unsigned int min,
|
||||
+ unsigned int step)
|
||||
+{
|
||||
+ unsigned int n;
|
||||
+ int changed = 0;
|
||||
+ n = (i->min - min) % step;
|
||||
+ if (n != 0 || i->openmin) {
|
||||
+ i->min += step - n;
|
||||
+ changed = 1;
|
||||
+ }
|
||||
+ n = (i->max - min) % step;
|
||||
+ if (n != 0 || i->openmax) {
|
||||
+ i->max -= n;
|
||||
+ changed = 1;
|
||||
+ }
|
||||
+ if (snd_interval_checkempty(i)) {
|
||||
+ i->empty = 1;
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return changed;
|
||||
+}
|
||||
+
|
||||
#undef REFINE_DEBUG
|
||||
|
||||
int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
@@ -710,15 +733,16 @@ int snd_pcm_direct_hw_refine(snd_pcm_t *
|
||||
&dshare->shmptr->hw.rate);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_SIZE,
|
||||
- &dshare->shmptr->hw.period_size);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
- err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_TIME,
|
||||
- &dshare->shmptr->hw.period_time);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
+
|
||||
if (dshare->max_periods < 0) {
|
||||
+ err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_SIZE,
|
||||
+ &dshare->shmptr->hw.period_size);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_TIME,
|
||||
+ &dshare->shmptr->hw.period_time);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
|
||||
&dshare->shmptr->hw.buffer_size);
|
||||
if (err < 0)
|
||||
@@ -730,11 +754,38 @@ int snd_pcm_direct_hw_refine(snd_pcm_t *
|
||||
} else if (params->rmask & ((1<<SND_PCM_HW_PARAM_PERIODS)|
|
||||
(1<<SND_PCM_HW_PARAM_BUFFER_BYTES)|
|
||||
(1<<SND_PCM_HW_PARAM_BUFFER_SIZE)|
|
||||
- (1<<SND_PCM_HW_PARAM_BUFFER_TIME))) {
|
||||
+ (1<<SND_PCM_HW_PARAM_BUFFER_TIME)|
|
||||
+ (1<<SND_PCM_HW_PARAM_PERIOD_TIME)|
|
||||
+ (1<<SND_PCM_HW_PARAM_PERIOD_SIZE)|
|
||||
+ (1<<SND_PCM_HW_PARAM_PERIOD_BYTES))) {
|
||||
+ snd_interval_t period_size = dshare->shmptr->hw.period_size;
|
||||
+ snd_interval_t period_time = dshare->shmptr->hw.period_time;
|
||||
int changed;
|
||||
unsigned int max_periods = dshare->max_periods;
|
||||
if (max_periods < 2)
|
||||
max_periods = dshare->slave_buffer_size / dshare->slave_period_size;
|
||||
+
|
||||
+ /* make sure buffer size does not exceed slave buffer size */
|
||||
+ err = hw_param_interval_refine_minmax(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
|
||||
+ 2 * dshare->slave_period_size, dshare->slave_buffer_size);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ if (dshare->var_periodsize) {
|
||||
+ /* more tolerant settings... */
|
||||
+ if (dshare->shmptr->hw.buffer_size.max / 2 > period_size.max)
|
||||
+ period_size.max = dshare->shmptr->hw.buffer_size.max / 2;
|
||||
+ if (dshare->shmptr->hw.buffer_time.max / 2 > period_time.max)
|
||||
+ period_time.max = dshare->shmptr->hw.buffer_time.max / 2;
|
||||
+ }
|
||||
+
|
||||
+ err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_SIZE,
|
||||
+ &period_size);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_TIME,
|
||||
+ &period_time);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
do {
|
||||
changed = 0;
|
||||
err = hw_param_interval_refine_minmax(params, SND_PCM_HW_PARAM_PERIODS,
|
||||
@@ -746,8 +797,16 @@ int snd_pcm_direct_hw_refine(snd_pcm_t *
|
||||
if (err < 0)
|
||||
return err;
|
||||
changed |= err;
|
||||
+ err = snd_interval_step(hw_param_interval(params, SND_PCM_HW_PARAM_PERIOD_SIZE),
|
||||
+ 0, dshare->slave_period_size);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ changed |= err;
|
||||
+ if (err)
|
||||
+ params->rmask |= (1 << SND_PCM_HW_PARAM_PERIOD_SIZE);
|
||||
} while (changed);
|
||||
}
|
||||
+ dshare->timer_ticks = hw_param_interval(params, SND_PCM_HW_PARAM_PERIOD_SIZE)->max / dshare->slave_period_size;
|
||||
params->info = dshare->shmptr->s.info;
|
||||
#ifdef REFINE_DEBUG
|
||||
snd_output_puts(log, "DMIX REFINE (end):\n");
|
||||
@@ -1183,6 +1242,7 @@ int snd_pcm_direct_initialize_poll_fd(sn
|
||||
|
||||
dmix->tread = 1;
|
||||
dmix->timer_need_poll = 0;
|
||||
+ dmix->timer_ticks = 1;
|
||||
ret = snd_pcm_info(dmix->spcm, &info);
|
||||
if (ret < 0) {
|
||||
SNDERR("unable to info for slave pcm");
|
||||
@@ -1366,7 +1426,7 @@ int snd_pcm_direct_set_timer_params(snd_
|
||||
snd_timer_params_set_auto_start(¶ms, 1);
|
||||
if (dmix->type != SND_PCM_TYPE_DSNOOP)
|
||||
snd_timer_params_set_early_event(¶ms, 1);
|
||||
- snd_timer_params_set_ticks(¶ms, 1);
|
||||
+ snd_timer_params_set_ticks(¶ms, dmix->timer_ticks);
|
||||
if (dmix->tread) {
|
||||
filter = (1<<SND_TIMER_EVENT_TICK) |
|
||||
dmix->timer_events;
|
||||
@@ -1656,6 +1716,7 @@ int snd_pcm_direct_parse_open_conf(snd_c
|
||||
rec->ipc_gid = -1;
|
||||
rec->slowptr = 1;
|
||||
rec->max_periods = 0;
|
||||
+ rec->var_periodsize = 1;
|
||||
|
||||
/* read defaults */
|
||||
if (snd_config_search(root, "defaults.pcm.dmix_max_periods", &n) >= 0) {
|
||||
@@ -1762,6 +1823,13 @@ int snd_pcm_direct_parse_open_conf(snd_c
|
||||
rec->max_periods = val;
|
||||
continue;
|
||||
}
|
||||
+ if (strcmp(id, "var_periodsize") == 0) {
|
||||
+ err = snd_config_get_bool(n);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ rec->var_periodsize = err;
|
||||
+ continue;
|
||||
+ }
|
||||
SNDERR("Unknown field %s", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
--- a/src/pcm/pcm_direct.h
|
||||
+++ b/src/pcm/pcm_direct.h
|
||||
@@ -147,12 +147,14 @@ struct snd_pcm_direct {
|
||||
int tread: 1;
|
||||
int timer_need_poll: 1;
|
||||
unsigned int timer_events;
|
||||
+ unsigned int timer_ticks;
|
||||
int server_fd;
|
||||
pid_t server_pid;
|
||||
snd_timer_t *timer; /* timer used as poll_fd */
|
||||
int interleaved; /* we have interleaved buffer */
|
||||
int slowptr; /* use slow but more precise ptr updates */
|
||||
int max_periods; /* max periods (-1 = fixed periods, 0 = max buffer size) */
|
||||
+ int var_periodsize; /* allow variable period size if max_periods is != -1*/
|
||||
unsigned int channels; /* client's channels */
|
||||
unsigned int *bindings;
|
||||
union {
|
||||
@@ -326,6 +328,7 @@ struct snd_pcm_direct_open_conf {
|
||||
int ipc_gid;
|
||||
int slowptr;
|
||||
int max_periods;
|
||||
+ int var_periodsize;
|
||||
snd_config_t *slave;
|
||||
snd_config_t *bindings;
|
||||
};
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -1040,6 +1040,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp,
|
||||
dmix->state = SND_PCM_STATE_OPEN;
|
||||
dmix->slowptr = opts->slowptr;
|
||||
dmix->max_periods = opts->max_periods;
|
||||
+ dmix->var_periodsize = opts->var_periodsize;
|
||||
dmix->sync_ptr = snd_pcm_dmix_sync_ptr;
|
||||
|
||||
retry:
|
||||
--- a/src/pcm/pcm_dshare.c
|
||||
+++ b/src/pcm/pcm_dshare.c
|
||||
@@ -725,6 +725,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp
|
||||
dshare->state = SND_PCM_STATE_OPEN;
|
||||
dshare->slowptr = opts->slowptr;
|
||||
dshare->max_periods = opts->max_periods;
|
||||
+ dshare->var_periodsize = opts->var_periodsize;
|
||||
dshare->sync_ptr = snd_pcm_dshare_sync_ptr;
|
||||
|
||||
retry:
|
||||
--- a/src/pcm/pcm_dsnoop.c
|
||||
+++ b/src/pcm/pcm_dsnoop.c
|
||||
@@ -606,6 +606,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp
|
||||
dsnoop->state = SND_PCM_STATE_OPEN;
|
||||
dsnoop->slowptr = opts->slowptr;
|
||||
dsnoop->max_periods = opts->max_periods;
|
||||
+ dsnoop->var_periodsize = opts->var_periodsize;
|
||||
dsnoop->sync_ptr = snd_pcm_dsnoop_sync_ptr;
|
||||
|
||||
retry:
|
34
0004-pcm-dshare-enable-silence.patch
Normal file
34
0004-pcm-dshare-enable-silence.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 8eeee1ab7d7db3110b7b3bb31cfb989304dced94 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Jahn <ajahn@de.adit-jv.com>
|
||||
Date: Fri, 30 Dec 2016 11:59:11 +0530
|
||||
Subject: [PATCH 04/43] pcm: dshare: enable silence
|
||||
|
||||
This issue depends on system load - if the process using dshare is
|
||||
scheduled fast enough, then there is no noise. A delay of e.g >~2ms
|
||||
produces hearable noise.
|
||||
|
||||
Reproduction with instrumented aplay(sleep every 100th period for a
|
||||
given time):
|
||||
During the sleep time of 2000000us (2s) the hardware plays old samples
|
||||
in a loop before xrun is detected and recovered after the sleep.
|
||||
This is resolved by placing it in silence, in case of dshare plugin.
|
||||
|
||||
Signed-off-by: Alexander Jahn <ajahn@de.adit-jv.com>
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -1161,7 +1161,8 @@ int snd_pcm_direct_initialize_slave(snd_
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (dmix->type != SND_PCM_TYPE_DMIX)
|
||||
+ if (dmix->type != SND_PCM_TYPE_DMIX &&
|
||||
+ dmix->type != SND_PCM_TYPE_DSHARE)
|
||||
goto __skip_silencing;
|
||||
|
||||
ret = snd_pcm_sw_params_set_silence_threshold(spcm, &sw_params, 0);
|
@ -0,0 +1,92 @@
|
||||
From 7570e5d77514d8d8af387da04a010fa2ccaf543c Mon Sep 17 00:00:00 2001
|
||||
From: "mahendran.k" <mahendran.kuppusamy@in.bosch.com>
|
||||
Date: Fri, 30 Dec 2016 11:59:27 +0530
|
||||
Subject: [PATCH 05/43] pcm: rate: fix the hw_ptr update until the boundary
|
||||
available
|
||||
|
||||
For long time test case, the slave_hw_ptr will exceed the boundary
|
||||
and wraparound the slave_hw_ptr. This slave boundary wraparound will
|
||||
cause the rate->hw_ptr to wraparound irrespective of the
|
||||
rate->boundary availability and due to that the available size goes
|
||||
wrong.
|
||||
|
||||
Hence, to get the correct available size,
|
||||
- Its necessary to increment the rate->hw_ptr upto the rate->boundary
|
||||
and then wraparound the rate->hw_ptr.
|
||||
- While handling fraction part of slave period, rounded value will be
|
||||
introduced by input_frames(). To eliminate rounding issue on
|
||||
rate->hw_ptr, subtract last rounded value from rate->hw_ptr and add
|
||||
new rounded value of present slave_hw_ptr fraction part to
|
||||
rate->hw_ptr.
|
||||
|
||||
Signed-off-by: mahendran.k <mahendran.kuppusamy@in.bosch.com>
|
||||
Signed-off-by: Mounesh Sutar <mounesh_sutar@mentor.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_rate.c | 31 +++++++++++++++++++++++++------
|
||||
1 file changed, 25 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_rate.c
|
||||
+++ b/src/pcm/pcm_rate.c
|
||||
@@ -50,7 +50,7 @@ typedef struct _snd_pcm_rate snd_pcm_rat
|
||||
|
||||
struct _snd_pcm_rate {
|
||||
snd_pcm_generic_t gen;
|
||||
- snd_pcm_uframes_t appl_ptr, hw_ptr;
|
||||
+ snd_pcm_uframes_t appl_ptr, hw_ptr, last_slave_hw_ptr;
|
||||
snd_pcm_uframes_t last_commit_ptr;
|
||||
snd_pcm_uframes_t orig_avail_min;
|
||||
snd_pcm_sw_params_t sw_params;
|
||||
@@ -563,14 +563,31 @@ static inline void snd_pcm_rate_sync_hwp
|
||||
{
|
||||
snd_pcm_rate_t *rate = pcm->private_data;
|
||||
|
||||
+ snd_pcm_sframes_t slave_hw_ptr_diff = slave_hw_ptr - rate->last_slave_hw_ptr;
|
||||
+ snd_pcm_sframes_t last_slave_hw_ptr_frac;
|
||||
+
|
||||
if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
|
||||
return;
|
||||
- /* FIXME: boundary overlap of slave hw_ptr isn't evaluated here!
|
||||
- * e.g. if slave rate is small...
|
||||
+
|
||||
+ if (slave_hw_ptr_diff < 0)
|
||||
+ slave_hw_ptr_diff += rate->gen.slave->boundary; /* slave boundary wraparound */
|
||||
+ else if (slave_hw_ptr_diff == 0)
|
||||
+ return;
|
||||
+ last_slave_hw_ptr_frac = rate->last_slave_hw_ptr % rate->gen.slave->period_size;
|
||||
+ /* While handling fraction part fo slave period, rounded value will be
|
||||
+ * introduced by input_frames().
|
||||
+ * To eliminate rounding issue on rate->hw_ptr, subtract last rounded
|
||||
+ * value from rate->hw_ptr and add new rounded value of present
|
||||
+ * slave_hw_ptr fraction part to rate->hw_ptr. Hence,
|
||||
+ * rate->hw_ptr += [ (no. of updated slave periods * pcm rate period size) -
|
||||
+ * fractional part of last_slave_hw_ptr rounded value +
|
||||
+ * fractional part of updated slave hw ptr's rounded value ]
|
||||
*/
|
||||
- rate->hw_ptr =
|
||||
- (slave_hw_ptr / rate->gen.slave->period_size) * pcm->period_size +
|
||||
- rate->ops.input_frames(rate->obj, slave_hw_ptr % rate->gen.slave->period_size);
|
||||
+ rate->hw_ptr += (
|
||||
+ (((last_slave_hw_ptr_frac + slave_hw_ptr_diff) / rate->gen.slave->period_size) * pcm->period_size) -
|
||||
+ rate->ops.input_frames(rate->obj, last_slave_hw_ptr_frac) +
|
||||
+ rate->ops.input_frames(rate->obj, (last_slave_hw_ptr_frac + slave_hw_ptr_diff) % rate->gen.slave->period_size));
|
||||
+ rate->last_slave_hw_ptr = slave_hw_ptr;
|
||||
|
||||
rate->hw_ptr %= pcm->boundary;
|
||||
}
|
||||
@@ -635,6 +652,7 @@ static int snd_pcm_rate_prepare(snd_pcm_
|
||||
return err;
|
||||
*pcm->hw.ptr = 0;
|
||||
*pcm->appl.ptr = 0;
|
||||
+ rate->last_slave_hw_ptr = 0;
|
||||
err = snd_pcm_rate_init(pcm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
@@ -650,6 +668,7 @@ static int snd_pcm_rate_reset(snd_pcm_t
|
||||
return err;
|
||||
*pcm->hw.ptr = 0;
|
||||
*pcm->appl.ptr = 0;
|
||||
+ rate->last_slave_hw_ptr = 0;
|
||||
err = snd_pcm_rate_init(pcm);
|
||||
if (err < 0)
|
||||
return err;
|
101
0006-plugin-dynamically-update-avail_min-on-slave.patch
Normal file
101
0006-plugin-dynamically-update-avail_min-on-slave.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From 88e4ae27bb4e47029ed57cc8e02fb1ddf2157fd9 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Mon, 19 Dec 2016 12:37:50 +0900
|
||||
Subject: [PATCH 06/43] plugin: dynamically update avail_min on slave
|
||||
|
||||
mmapped capture access on some plugins can fetch data from
|
||||
slave in the 'background'. A subsequent snd_pcm_wait waits
|
||||
for too long time to reach avail_min threshold again.
|
||||
Waiting too long leads to xruns on other devices waiting for
|
||||
the capture data.
|
||||
As a fix the avail_min on slave is recalculated dynamically.
|
||||
|
||||
V2: updated patch to fix within 80 characters per line
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_plugin.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 63 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/pcm/pcm_plugin.c
|
||||
+++ b/src/pcm/pcm_plugin.c
|
||||
@@ -535,6 +535,68 @@ static int snd_pcm_plugin_status(snd_pcm
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm,
|
||||
+ snd_pcm_uframes_t avail)
|
||||
+{
|
||||
+ if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
|
||||
+ pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
|
||||
+ pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
|
||||
+ /* mmap access on capture device already consumes data from
|
||||
+ * slave in avail_update operation. Entering snd_pcm_wait after
|
||||
+ * having already consumed some fragments leads to waiting for
|
||||
+ * too long time, as slave will unnecessarily wait for avail_min
|
||||
+ * condition reached again. To avoid unnecessary wait times we
|
||||
+ * adapt the avail_min threshold on slave dynamically. Just
|
||||
+ * modifying slave->avail_min as a shortcut and lightweight
|
||||
+ * solution does not work for all slave plugin types and in
|
||||
+ * addition it will not propagate the change through all
|
||||
+ * downstream plugins, so we have to use the sw_params API.
|
||||
+ * note: reading fragmental parts from slave will only happen
|
||||
+ * in case
|
||||
+ * a) the slave can provide contineous hw_ptr between periods
|
||||
+ * b) avail_min does not match one slave_period
|
||||
+ */
|
||||
+ snd_pcm_plugin_t *plugin = pcm->private_data;
|
||||
+ snd_pcm_t *slave = plugin->gen.slave;
|
||||
+ snd_pcm_uframes_t needed_slave_avail_min;
|
||||
+ snd_pcm_sframes_t available;
|
||||
+
|
||||
+ /* update, as it might have changed. This will also call
|
||||
+ * avail_update on slave and also can return error
|
||||
+ */
|
||||
+ available = snd_pcm_avail_update(pcm);
|
||||
+ if (available < 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (available >= pcm->avail_min)
|
||||
+ /* don't wait at all. As we can't configure avail_min
|
||||
+ * of slave to 0 return here
|
||||
+ */
|
||||
+ return 0;
|
||||
+
|
||||
+ needed_slave_avail_min = pcm->avail_min - available;
|
||||
+ if (slave->avail_min != needed_slave_avail_min) {
|
||||
+ snd_pcm_sw_params_t *swparams;
|
||||
+ snd_pcm_sw_params_alloca(&swparams);
|
||||
+ /* pray that changing sw_params while running is
|
||||
+ * properly implemented in all downstream plugins...
|
||||
+ * it's legal but not commonly used.
|
||||
+ */
|
||||
+ snd_pcm_sw_params_current(slave, swparams);
|
||||
+ /* snd_pcm_sw_params_set_avail_min() restricts setting
|
||||
+ * to >= period size. This conflicts at least with our
|
||||
+ * dshare patch which allows combining multiple periods
|
||||
+ * or with slaves which return hw postions between
|
||||
+ * periods -> set directly in sw_param structure
|
||||
+ */
|
||||
+ swparams->avail_min = needed_slave_avail_min;
|
||||
+ snd_pcm_sw_params(slave, swparams);
|
||||
+ }
|
||||
+ avail = available;
|
||||
+ }
|
||||
+ return snd_pcm_generic_may_wait_for_avail_min(pcm, avail);
|
||||
+}
|
||||
+
|
||||
const snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
|
||||
.status = snd_pcm_plugin_status,
|
||||
.state = snd_pcm_generic_state,
|
||||
@@ -564,7 +626,7 @@ const snd_pcm_fast_ops_t snd_pcm_plugin_
|
||||
.poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
|
||||
.poll_descriptors = snd_pcm_generic_poll_descriptors,
|
||||
.poll_revents = snd_pcm_generic_poll_revents,
|
||||
- .may_wait_for_avail_min = snd_pcm_generic_may_wait_for_avail_min,
|
||||
+ .may_wait_for_avail_min = snd_pcm_plugin_may_wait_for_avail_min,
|
||||
};
|
||||
|
||||
#endif
|
57
0007-rate-dynamic-update-avail_min-on-slave.patch
Normal file
57
0007-rate-dynamic-update-avail_min-on-slave.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From ff1f669df4b05da3c44dc4a79ce00233fe9de9b7 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Mon, 19 Dec 2016 12:37:51 +0900
|
||||
Subject: [PATCH 07/43] rate: dynamic update avail_min on slave
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_plugin.c | 4 ++--
|
||||
src/pcm/pcm_plugin.h | 3 +++
|
||||
src/pcm/pcm_rate.c | 2 +-
|
||||
3 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_plugin.c
|
||||
+++ b/src/pcm/pcm_plugin.c
|
||||
@@ -535,8 +535,8 @@ static int snd_pcm_plugin_status(snd_pcm
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm,
|
||||
- snd_pcm_uframes_t avail)
|
||||
+int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm,
|
||||
+ snd_pcm_uframes_t avail)
|
||||
{
|
||||
if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
|
||||
pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED &&
|
||||
--- a/src/pcm/pcm_plugin.h
|
||||
+++ b/src/pcm/pcm_plugin.h
|
||||
@@ -50,6 +50,8 @@ typedef struct {
|
||||
/* make local functions really local */
|
||||
#define snd_pcm_plugin_init \
|
||||
snd1_pcm_plugin_init
|
||||
+#define snd_pcm_plugin_may_wait_for_avail_min \
|
||||
+ snd1_pcm_plugin_may_wait_for_avail_min
|
||||
#define snd_pcm_plugin_fast_ops \
|
||||
snd1_pcm_plugin_fast_ops
|
||||
#define snd_pcm_plugin_undo_read_generic \
|
||||
@@ -64,6 +66,7 @@ typedef struct {
|
||||
void snd_pcm_plugin_init(snd_pcm_plugin_t *plugin);
|
||||
snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
|
||||
snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
|
||||
+int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail);
|
||||
|
||||
extern const snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops;
|
||||
|
||||
--- a/src/pcm/pcm_rate.c
|
||||
+++ b/src/pcm/pcm_rate.c
|
||||
@@ -1213,7 +1213,7 @@ static const snd_pcm_fast_ops_t snd_pcm_
|
||||
.poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
|
||||
.poll_descriptors = snd_pcm_generic_poll_descriptors,
|
||||
.poll_revents = snd_pcm_rate_poll_revents,
|
||||
- .may_wait_for_avail_min = snd_pcm_generic_may_wait_for_avail_min,
|
||||
+ .may_wait_for_avail_min = snd_pcm_plugin_may_wait_for_avail_min,
|
||||
};
|
||||
|
||||
static const snd_pcm_ops_t snd_pcm_rate_ops = {
|
42
0008-topology-fix-unused-const-variable-warning.patch
Normal file
42
0008-topology-fix-unused-const-variable-warning.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From 6f7eaf92e7de73eb32bd97bad83a14fcb0f408f7 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
Date: Wed, 30 Nov 2016 00:44:32 +0900
|
||||
Subject: [PATCH 08/43] topology: fix unused-const-variable warning
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Last year, unused static const variable was added, then compiler generates
|
||||
a below warning.
|
||||
|
||||
dapm.c:43:30: warning: ‘widget_control_map’ defined but not used [-Wunused-const-variable=]
|
||||
static const struct map_elem widget_control_map[] = {
|
||||
^~~~~~~~~~~~~~~~~~
|
||||
|
||||
This commit removes it.
|
||||
|
||||
Fixes: 01a0e1a1c219 ("topology: Add DAPM object parser")
|
||||
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/topology/dapm.c | 8 --------
|
||||
1 file changed, 8 deletions(-)
|
||||
|
||||
--- a/src/topology/dapm.c
|
||||
+++ b/src/topology/dapm.c
|
||||
@@ -39,14 +39,6 @@ static const struct map_elem widget_map[
|
||||
{"dai_link", SND_SOC_TPLG_DAPM_DAI_LINK},
|
||||
};
|
||||
|
||||
-/* mapping of widget kcontrol text names to types */
|
||||
-static const struct map_elem widget_control_map[] = {
|
||||
- {"volsw", SND_SOC_TPLG_DAPM_CTL_VOLSW},
|
||||
- {"enum_double", SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE},
|
||||
- {"enum_virt", SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT},
|
||||
- {"enum_value", SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE},
|
||||
-};
|
||||
-
|
||||
static int lookup_widget(const char *w)
|
||||
{
|
||||
unsigned int i;
|
@ -0,0 +1,77 @@
|
||||
From 1eddf1f918845d1e6cbcac5516319b20cad80f2f Mon Sep 17 00:00:00 2001
|
||||
From: Adam Goode <agoode@google.com>
|
||||
Date: Tue, 3 Jan 2017 08:33:42 -0500
|
||||
Subject: [PATCH 09/43] seq: improve documentation about new get pid/card
|
||||
functions
|
||||
|
||||
Document the technique for determining if the running kernel supports
|
||||
the new snd_seq_client_info_get_pid and snd_seq_client_info_get_card
|
||||
functions. Also add a little information about how to use these
|
||||
functions and add some cross references.
|
||||
|
||||
Signed-off-by: Adam Goode <agoode@google.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/seq/seq.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 42 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/seq/seq.c
|
||||
+++ b/src/seq/seq.c
|
||||
@@ -1530,7 +1530,25 @@ int snd_seq_client_info_get_error_bounce
|
||||
* \param info client_info container
|
||||
* \return card number or -1 if value is not available.
|
||||
*
|
||||
- * Only available for SND_SEQ_KERNEL_CLIENT clients.
|
||||
+ * Only available for #SND_SEQ_KERNEL_CLIENT clients.
|
||||
+ *
|
||||
+ * The card number can be used to query state about the hardware
|
||||
+ * device providing this client, by concatenating <code>"hw:CARD="</code>
|
||||
+ * with the card number and using it as the <code>name</code> parameter
|
||||
+ * to #snd_ctl_open().
|
||||
+ *
|
||||
+ * \note
|
||||
+ * The return value of -1 is returned for two different conditions: when the
|
||||
+ * running kernel does not support this operation, and when the client
|
||||
+ * does not have a hardware card attached. See
|
||||
+ * #snd_seq_client_info_get_pid() for a way to determine if the
|
||||
+ * currently running kernel has support for this operation.
|
||||
+ *
|
||||
+ * \sa snd_seq_client_info_get_pid(),
|
||||
+ * snd_card_get_name(),
|
||||
+ * snd_card_get_longname(),
|
||||
+ * snd_ctl_open(),
|
||||
+ * snd_ctl_card_info()
|
||||
*/
|
||||
int snd_seq_client_info_get_card(const snd_seq_client_info_t *info)
|
||||
{
|
||||
@@ -1543,7 +1561,29 @@ int snd_seq_client_info_get_card(const s
|
||||
* \param info client_info container
|
||||
* \return pid or -1 if value is not available.
|
||||
*
|
||||
- * Only available for SND_SEQ_USER_CLIENT clients.
|
||||
+ * Only available for #SND_SEQ_USER_CLIENT clients.
|
||||
+ *
|
||||
+ * \note
|
||||
+ * The functionality for getting a client's PID and getting a
|
||||
+ * client's card was added to the kernel at the same time, so you can
|
||||
+ * use this function to determine if the running kernel
|
||||
+ * supports reporting these values. If your own client has a valid
|
||||
+ * PID as reported by this function, then the running kernel supports
|
||||
+ * both #snd_seq_client_info_get_card() and #snd_seq_client_info_get_pid().
|
||||
+ *
|
||||
+ * \note
|
||||
+ * Example code for determining kernel support:
|
||||
+ * \code
|
||||
+ * int is_get_card_or_pid_supported(snd_seq_t *seq)
|
||||
+ * {
|
||||
+ * snd_seq_client_info_t *my_client_info;
|
||||
+ * snd_seq_client_info_alloca(&my_client_info);
|
||||
+ * snd_seq_get_client_info(seq, my_client_info);
|
||||
+ * return snd_seq_client_info_get_pid(my_client_info) != -1;
|
||||
+ * }
|
||||
+ * \endcode
|
||||
+ *
|
||||
+ * \sa snd_seq_client_info_get_card()
|
||||
*/
|
||||
int snd_seq_client_info_get_pid(const snd_seq_client_info_t *info)
|
||||
{
|
@ -0,0 +1,38 @@
|
||||
From 3f0dc404f16af58d20b4489b0daafcf87555dfb7 Mon Sep 17 00:00:00 2001
|
||||
From: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Date: Tue, 10 Jan 2017 12:03:17 +0530
|
||||
Subject: [PATCH 10/43] pcm: direct: returning semop error code for semaphore
|
||||
up/down failures
|
||||
|
||||
Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.h | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_direct.h
|
||||
+++ b/src/pcm/pcm_direct.h
|
||||
@@ -263,7 +263,10 @@ static inline int snd_pcm_direct_semapho
|
||||
{
|
||||
struct sembuf op[2] = { { sem_num, 0, 0 }, { sem_num, 1, SEM_UNDO } };
|
||||
int err = semop(dmix->semid, op, 2);
|
||||
- if (err == 0) dmix->locked[sem_num]++;
|
||||
+ if (err == 0)
|
||||
+ dmix->locked[sem_num]++;
|
||||
+ else if (err == -1)
|
||||
+ err = -errno;
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -271,7 +274,10 @@ static inline int snd_pcm_direct_semapho
|
||||
{
|
||||
struct sembuf op = { sem_num, -1, SEM_UNDO | IPC_NOWAIT };
|
||||
int err = semop(dmix->semid, &op, 1);
|
||||
- if (err == 0) dmix->locked[sem_num]--;
|
||||
+ if (err == 0)
|
||||
+ dmix->locked[sem_num]--;
|
||||
+ else if (err == -1)
|
||||
+ err = -errno;
|
||||
return err;
|
||||
}
|
||||
|
370
0011-pcm-direct-Fix-for-sync-issue-on-xrun-recover.patch
Normal file
370
0011-pcm-direct-Fix-for-sync-issue-on-xrun-recover.patch
Normal file
@ -0,0 +1,370 @@
|
||||
From 1a9bd0f0448106b917ae7f7bedccfcbf6ce84802 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Tue, 10 Jan 2017 12:03:36 +0530
|
||||
Subject: [PATCH 11/43] pcm: direct: Fix for sync issue on xrun recover
|
||||
|
||||
If using very short periods, DSHARE/DSNOOP/DMIX may report underruns while in
|
||||
status 'prepared'. This prohibits correct recovery. Now slave xrun conditions
|
||||
for DSHARE/DSNOOP/DMIX are being handled properly.
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Joshua Frkuska <joshua_frkuska@mentor.com>
|
||||
Signed-off-by: Mounesh Sutar <mounesh_sutar@mentor.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
src/pcm/pcm_direct.h | 5 ++
|
||||
src/pcm/pcm_dmix.c | 27 ++++++++++---
|
||||
src/pcm/pcm_dshare.c | 29 +++++++++++---
|
||||
src/pcm/pcm_dsnoop.c | 15 ++++++-
|
||||
5 files changed, 162 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -550,6 +550,101 @@ int snd_pcm_direct_timer_stop(snd_pcm_di
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Recover slave on XRUN.
|
||||
+ * Even if direct plugins disable xrun detection, there might be an xrun
|
||||
+ * raised directly by some drivers.
|
||||
+ * The first client recovers slave pcm.
|
||||
+ * Each client needs to execute sw xrun handling afterwards
|
||||
+ */
|
||||
+int snd_pcm_direct_slave_recover(snd_pcm_direct_t *direct)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int semerr;
|
||||
+
|
||||
+ semerr = snd_pcm_direct_semaphore_down(direct,
|
||||
+ DIRECT_IPC_SEM_CLIENT);
|
||||
+ if (semerr < 0) {
|
||||
+ SNDERR("SEMDOWN FAILED with err %d", semerr);
|
||||
+ return semerr;
|
||||
+ }
|
||||
+
|
||||
+ if (snd_pcm_state(direct->spcm) != SND_PCM_STATE_XRUN) {
|
||||
+ /* ignore... someone else already did recovery */
|
||||
+ semerr = snd_pcm_direct_semaphore_up(direct,
|
||||
+ DIRECT_IPC_SEM_CLIENT);
|
||||
+ if (semerr < 0) {
|
||||
+ SNDERR("SEMUP FAILED with err %d", semerr);
|
||||
+ return semerr;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ ret = snd_pcm_prepare(direct->spcm);
|
||||
+ if (ret < 0) {
|
||||
+ SNDERR("recover: unable to prepare slave");
|
||||
+ semerr = snd_pcm_direct_semaphore_up(direct,
|
||||
+ DIRECT_IPC_SEM_CLIENT);
|
||||
+ if (semerr < 0) {
|
||||
+ SNDERR("SEMUP FAILED with err %d", semerr);
|
||||
+ return semerr;
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (direct->type == SND_PCM_TYPE_DSHARE) {
|
||||
+ const snd_pcm_channel_area_t *dst_areas;
|
||||
+ dst_areas = snd_pcm_mmap_areas(direct->spcm);
|
||||
+ snd_pcm_areas_silence(dst_areas, 0, direct->spcm->channels,
|
||||
+ direct->spcm->buffer_size,
|
||||
+ direct->spcm->format);
|
||||
+ }
|
||||
+
|
||||
+ ret = snd_pcm_start(direct->spcm);
|
||||
+ if (ret < 0) {
|
||||
+ SNDERR("recover: unable to start slave");
|
||||
+ semerr = snd_pcm_direct_semaphore_up(direct,
|
||||
+ DIRECT_IPC_SEM_CLIENT);
|
||||
+ if (semerr < 0) {
|
||||
+ SNDERR("SEMUP FAILED with err %d", semerr);
|
||||
+ return semerr;
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+ direct->shmptr->recoveries++;
|
||||
+ semerr = snd_pcm_direct_semaphore_up(direct,
|
||||
+ DIRECT_IPC_SEM_CLIENT);
|
||||
+ if (semerr < 0) {
|
||||
+ SNDERR("SEMUP FAILED with err %d", semerr);
|
||||
+ return semerr;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * enter xrun state, if slave xrun occurred
|
||||
+ * @return: 0 - no xrun >0: xrun happened
|
||||
+ */
|
||||
+int snd_pcm_direct_client_chk_xrun(snd_pcm_direct_t *direct, snd_pcm_t *pcm)
|
||||
+{
|
||||
+ if (direct->shmptr->recoveries != direct->recoveries) {
|
||||
+ /* no matter how many xruns we missed -
|
||||
+ * so don't increment but just update to actual counter
|
||||
+ */
|
||||
+ direct->recoveries = direct->shmptr->recoveries;
|
||||
+ pcm->fast_ops->drop(pcm);
|
||||
+ /* trigger_tstamp update is missing in drop callbacks */
|
||||
+ gettimestamp(&direct->trigger_tstamp, pcm->tstamp_type);
|
||||
+ /* no timer clear:
|
||||
+ * if slave already entered xrun again the event is lost.
|
||||
+ * snd_pcm_direct_clear_timer_queue(direct);
|
||||
+ */
|
||||
+ direct->state = SND_PCM_STATE_XRUN;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
@@ -572,6 +667,12 @@ int snd_pcm_direct_poll_revents(snd_pcm_
|
||||
}
|
||||
switch (snd_pcm_state(dmix->spcm)) {
|
||||
case SND_PCM_STATE_XRUN:
|
||||
+ /* recover slave and update client state to xrun
|
||||
+ * before returning POLLERR
|
||||
+ */
|
||||
+ snd_pcm_direct_slave_recover(dmix);
|
||||
+ snd_pcm_direct_client_chk_xrun(dmix, pcm);
|
||||
+ /* fallthrough */
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
case SND_PCM_STATE_SETUP:
|
||||
events |= POLLERR;
|
||||
@@ -1382,6 +1483,7 @@ int snd_pcm_direct_open_secondary_client
|
||||
dmix->slave_buffer_size = spcm->buffer_size;
|
||||
dmix->slave_period_size = dmix->shmptr->s.period_size;
|
||||
dmix->slave_boundary = spcm->boundary;
|
||||
+ dmix->recoveries = dmix->shmptr->recoveries;
|
||||
|
||||
ret = snd_pcm_mmap(spcm);
|
||||
if (ret < 0) {
|
||||
--- a/src/pcm/pcm_direct.h
|
||||
+++ b/src/pcm/pcm_direct.h
|
||||
@@ -66,6 +66,7 @@ typedef struct {
|
||||
char socket_name[256]; /* name of communication socket */
|
||||
snd_pcm_type_t type; /* PCM type (currently only hw) */
|
||||
int use_server;
|
||||
+ unsigned int recoveries; /* no of executed recoveries on slave*/
|
||||
struct {
|
||||
unsigned int format;
|
||||
snd_interval_t rate;
|
||||
@@ -157,6 +158,7 @@ struct snd_pcm_direct {
|
||||
int var_periodsize; /* allow variable period size if max_periods is != -1*/
|
||||
unsigned int channels; /* client's channels */
|
||||
unsigned int *bindings;
|
||||
+ unsigned int recoveries; /* mirror of executed recoveries on slave */
|
||||
union {
|
||||
struct {
|
||||
int shmid_sum; /* IPC global sum ring buffer memory identification */
|
||||
@@ -324,7 +326,8 @@ int snd_pcm_direct_open_secondary_client
|
||||
snd_pcm_chmap_query_t **snd_pcm_direct_query_chmaps(snd_pcm_t *pcm);
|
||||
snd_pcm_chmap_t *snd_pcm_direct_get_chmap(snd_pcm_t *pcm);
|
||||
int snd_pcm_direct_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map);
|
||||
-
|
||||
+int snd_pcm_direct_slave_recover(snd_pcm_direct_t *direct);
|
||||
+int snd_pcm_direct_client_chk_xrun(snd_pcm_direct_t *direct, snd_pcm_t *pcm);
|
||||
int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
|
||||
struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm);
|
||||
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -434,15 +434,21 @@ static int snd_pcm_dmix_sync_ptr0(snd_pc
|
||||
static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
+ int err;
|
||||
|
||||
switch (snd_pcm_state(dmix->spcm)) {
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
dmix->state = SND_PCM_STATE_DISCONNECTED;
|
||||
return -ENODEV;
|
||||
+ case SND_PCM_STATE_XRUN:
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dmix)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
-
|
||||
+ if (snd_pcm_direct_client_chk_xrun(dmix, pcm))
|
||||
+ return -EPIPE;
|
||||
if (dmix->slowptr)
|
||||
snd_pcm_hwsync(dmix->spcm);
|
||||
|
||||
@@ -828,12 +834,16 @@ static snd_pcm_sframes_t snd_pcm_dmix_mm
|
||||
|
||||
switch (snd_pcm_state(dmix->spcm)) {
|
||||
case SND_PCM_STATE_XRUN:
|
||||
- return -EPIPE;
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dmix)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
return -ESTRPIPE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+ if (snd_pcm_direct_client_chk_xrun(dmix, pcm))
|
||||
+ return -EPIPE;
|
||||
if (! size)
|
||||
return 0;
|
||||
snd_pcm_mmap_appl_forward(pcm, size);
|
||||
@@ -841,8 +851,10 @@ static snd_pcm_sframes_t snd_pcm_dmix_mm
|
||||
if ((err = snd_pcm_dmix_start_timer(pcm, dmix)) < 0)
|
||||
return err;
|
||||
} else if (dmix->state == SND_PCM_STATE_RUNNING ||
|
||||
- dmix->state == SND_PCM_STATE_DRAINING)
|
||||
- snd_pcm_dmix_sync_ptr(pcm);
|
||||
+ dmix->state == SND_PCM_STATE_DRAINING) {
|
||||
+ if ((err = snd_pcm_dmix_sync_ptr(pcm)) < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
if (dmix->state == SND_PCM_STATE_RUNNING ||
|
||||
dmix->state == SND_PCM_STATE_DRAINING) {
|
||||
/* ok, we commit the changes after the validation of area */
|
||||
@@ -858,10 +870,13 @@ static snd_pcm_sframes_t snd_pcm_dmix_mm
|
||||
static snd_pcm_sframes_t snd_pcm_dmix_avail_update(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
+ int err;
|
||||
|
||||
if (dmix->state == SND_PCM_STATE_RUNNING ||
|
||||
- dmix->state == SND_PCM_STATE_DRAINING)
|
||||
- snd_pcm_dmix_sync_ptr(pcm);
|
||||
+ dmix->state == SND_PCM_STATE_DRAINING) {
|
||||
+ if ((err = snd_pcm_dmix_sync_ptr(pcm)) < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
return snd_pcm_mmap_playback_avail(pcm);
|
||||
}
|
||||
|
||||
--- a/src/pcm/pcm_dshare.c
|
||||
+++ b/src/pcm/pcm_dshare.c
|
||||
@@ -162,7 +162,7 @@ static int snd_pcm_dshare_sync_ptr0(snd_
|
||||
snd_pcm_direct_t *dshare = pcm->private_data;
|
||||
snd_pcm_uframes_t old_slave_hw_ptr, avail;
|
||||
snd_pcm_sframes_t diff;
|
||||
-
|
||||
+
|
||||
old_slave_hw_ptr = dshare->slave_hw_ptr;
|
||||
dshare->slave_hw_ptr = slave_hw_ptr;
|
||||
diff = slave_hw_ptr - old_slave_hw_ptr;
|
||||
@@ -202,15 +202,21 @@ static int snd_pcm_dshare_sync_ptr0(snd_
|
||||
static int snd_pcm_dshare_sync_ptr(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_direct_t *dshare = pcm->private_data;
|
||||
+ int err;
|
||||
|
||||
switch (snd_pcm_state(dshare->spcm)) {
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
dshare->state = SNDRV_PCM_STATE_DISCONNECTED;
|
||||
return -ENODEV;
|
||||
+ case SND_PCM_STATE_XRUN:
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dshare)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
-
|
||||
+ if (snd_pcm_direct_client_chk_xrun(dshare, pcm))
|
||||
+ return -EPIPE;
|
||||
if (dshare->slowptr)
|
||||
snd_pcm_hwsync(dshare->spcm);
|
||||
|
||||
@@ -516,12 +522,16 @@ static snd_pcm_sframes_t snd_pcm_dshare_
|
||||
|
||||
switch (snd_pcm_state(dshare->spcm)) {
|
||||
case SND_PCM_STATE_XRUN:
|
||||
- return -EPIPE;
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dshare)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
return -ESTRPIPE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+ if (snd_pcm_direct_client_chk_xrun(dshare, pcm))
|
||||
+ return -EPIPE;
|
||||
if (! size)
|
||||
return 0;
|
||||
snd_pcm_mmap_appl_forward(pcm, size);
|
||||
@@ -529,8 +539,10 @@ static snd_pcm_sframes_t snd_pcm_dshare_
|
||||
if ((err = snd_pcm_dshare_start_timer(dshare)) < 0)
|
||||
return err;
|
||||
} else if (dshare->state == SND_PCM_STATE_RUNNING ||
|
||||
- dshare->state == SND_PCM_STATE_DRAINING)
|
||||
- snd_pcm_dshare_sync_ptr(pcm);
|
||||
+ dshare->state == SND_PCM_STATE_DRAINING) {
|
||||
+ if ((err = snd_pcm_dshare_sync_ptr(pcm)) < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
if (dshare->state == SND_PCM_STATE_RUNNING ||
|
||||
dshare->state == SND_PCM_STATE_DRAINING) {
|
||||
/* ok, we commit the changes after the validation of area */
|
||||
@@ -546,10 +558,13 @@ static snd_pcm_sframes_t snd_pcm_dshare_
|
||||
static snd_pcm_sframes_t snd_pcm_dshare_avail_update(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_direct_t *dshare = pcm->private_data;
|
||||
+ int err;
|
||||
|
||||
if (dshare->state == SND_PCM_STATE_RUNNING ||
|
||||
- dshare->state == SND_PCM_STATE_DRAINING)
|
||||
- snd_pcm_dshare_sync_ptr(pcm);
|
||||
+ dshare->state == SND_PCM_STATE_DRAINING) {
|
||||
+ if ((err = snd_pcm_dshare_sync_ptr(pcm)) < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
return snd_pcm_mmap_playback_avail(pcm);
|
||||
}
|
||||
|
||||
--- a/src/pcm/pcm_dsnoop.c
|
||||
+++ b/src/pcm/pcm_dsnoop.c
|
||||
@@ -132,14 +132,21 @@ static int snd_pcm_dsnoop_sync_ptr(snd_p
|
||||
snd_pcm_direct_t *dsnoop = pcm->private_data;
|
||||
snd_pcm_uframes_t slave_hw_ptr, old_slave_hw_ptr, avail;
|
||||
snd_pcm_sframes_t diff;
|
||||
-
|
||||
+ int err;
|
||||
+
|
||||
switch (snd_pcm_state(dsnoop->spcm)) {
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
dsnoop->state = SNDRV_PCM_STATE_DISCONNECTED;
|
||||
return -ENODEV;
|
||||
+ case SND_PCM_STATE_XRUN:
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dsnoop)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+ if (snd_pcm_direct_client_chk_xrun(dsnoop, pcm))
|
||||
+ return -EPIPE;
|
||||
if (dsnoop->slowptr)
|
||||
snd_pcm_hwsync(dsnoop->spcm);
|
||||
old_slave_hw_ptr = dsnoop->slave_hw_ptr;
|
||||
@@ -410,12 +417,16 @@ static snd_pcm_sframes_t snd_pcm_dsnoop_
|
||||
|
||||
switch (snd_pcm_state(dsnoop->spcm)) {
|
||||
case SND_PCM_STATE_XRUN:
|
||||
- return -EPIPE;
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dsnoop)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
return -ESTRPIPE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+ if (snd_pcm_direct_client_chk_xrun(dsnoop, pcm))
|
||||
+ return -EPIPE;
|
||||
if (dsnoop->state == SND_PCM_STATE_RUNNING) {
|
||||
err = snd_pcm_dsnoop_sync_ptr(pcm);
|
||||
if (err < 0)
|
184
0012-pcm-direct-check-state-before-enter-poll-on-timer.patch
Normal file
184
0012-pcm-direct-check-state-before-enter-poll-on-timer.patch
Normal file
@ -0,0 +1,184 @@
|
||||
From 789ee39727a12d6573b4d79e9cd7a375e6b8b005 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Tue, 10 Jan 2017 12:03:54 +0530
|
||||
Subject: [PATCH 12/43] pcm: direct: check state before enter poll on timer
|
||||
|
||||
To avoid the chances of timeout, we need to check the enter poll
|
||||
in state xrun.
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Mounesh Sutar <mounesh_sutar@mentor.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
src/pcm/pcm_direct.h | 2 ++
|
||||
src/pcm/pcm_dmix.c | 9 +++++++--
|
||||
src/pcm/pcm_dshare.c | 9 +++++++--
|
||||
src/pcm/pcm_dsnoop.c | 9 +++++++--
|
||||
5 files changed, 63 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -645,6 +645,46 @@ int snd_pcm_direct_client_chk_xrun(snd_p
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * This is the only operation guaranteed to be called before entering poll().
|
||||
+ * Direct plugins use fd of snd_timer to poll on, these timers do NOT check
|
||||
+ * state of substream in kernel by intention.
|
||||
+ * Only the enter to xrun might be notified once (SND_TIMER_EVENT_MSTOP).
|
||||
+ * If xrun event was not correctly handled or was ignored it will never be
|
||||
+ * evaluated again afterwards.
|
||||
+ * This will result in snd_pcm_wait() always returning timeout.
|
||||
+ * In contrast poll() on pcm hardware checks ALSA state and will immediately
|
||||
+ * return POLLERR on XRUN.
|
||||
+ *
|
||||
+ * To prevent timeout and applications endlessly spinning without xrun
|
||||
+ * detected we add a state check here which may trigger the xrun sequence.
|
||||
+ *
|
||||
+ * return count of filled descriptors or negative error code
|
||||
+ */
|
||||
+int snd_pcm_direct_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds,
|
||||
+ unsigned int space)
|
||||
+{
|
||||
+ if (pcm->poll_fd < 0) {
|
||||
+ SNDMSG("poll_fd < 0");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+ if (space >= 1 && pfds) {
|
||||
+ pfds->fd = pcm->poll_fd;
|
||||
+ pfds->events = pcm->poll_events | POLLERR | POLLNVAL;
|
||||
+ } else {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* this will also evaluate slave state and enter xrun if necessary */
|
||||
+ switch (snd_pcm_state(pcm)) {
|
||||
+ case SND_PCM_STATE_XRUN:
|
||||
+ return -EPIPE;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
|
||||
{
|
||||
snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
--- a/src/pcm/pcm_direct.h
|
||||
+++ b/src/pcm/pcm_direct.h
|
||||
@@ -307,6 +307,8 @@ int snd_pcm_direct_parse_bindings(snd_pc
|
||||
snd_config_t *cfg);
|
||||
int snd_pcm_direct_nonblock(snd_pcm_t *pcm, int nonblock);
|
||||
int snd_pcm_direct_async(snd_pcm_t *pcm, int sig, pid_t pid);
|
||||
+int snd_pcm_direct_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds,
|
||||
+ unsigned int space);
|
||||
int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
||||
int snd_pcm_direct_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
|
||||
int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -462,17 +462,22 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm
|
||||
static snd_pcm_state_t snd_pcm_dmix_state(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
+ int err;
|
||||
snd_pcm_state_t state;
|
||||
state = snd_pcm_state(dmix->spcm);
|
||||
switch (state) {
|
||||
- case SND_PCM_STATE_XRUN:
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
dmix->state = state;
|
||||
return state;
|
||||
+ case SND_PCM_STATE_XRUN:
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dmix)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+ snd_pcm_direct_client_chk_xrun(dmix, pcm);
|
||||
if (dmix->state == STATE_RUN_PENDING)
|
||||
return SNDRV_PCM_STATE_RUNNING;
|
||||
return dmix->state;
|
||||
@@ -968,7 +973,7 @@ static const snd_pcm_fast_ops_t snd_pcm_
|
||||
.avail_update = snd_pcm_dmix_avail_update,
|
||||
.mmap_commit = snd_pcm_dmix_mmap_commit,
|
||||
.htimestamp = snd_pcm_dmix_htimestamp,
|
||||
- .poll_descriptors = NULL,
|
||||
+ .poll_descriptors = snd_pcm_direct_poll_descriptors,
|
||||
.poll_descriptors_count = NULL,
|
||||
.poll_revents = snd_pcm_dmix_poll_revents,
|
||||
};
|
||||
--- a/src/pcm/pcm_dshare.c
|
||||
+++ b/src/pcm/pcm_dshare.c
|
||||
@@ -255,17 +255,22 @@ static int snd_pcm_dshare_status(snd_pcm
|
||||
static snd_pcm_state_t snd_pcm_dshare_state(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_direct_t *dshare = pcm->private_data;
|
||||
+ int err;
|
||||
snd_pcm_state_t state;
|
||||
state = snd_pcm_state(dshare->spcm);
|
||||
switch (state) {
|
||||
- case SND_PCM_STATE_XRUN:
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
dshare->state = state;
|
||||
return state;
|
||||
+ case SND_PCM_STATE_XRUN:
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dshare)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+ snd_pcm_direct_client_chk_xrun(dshare, pcm);
|
||||
if (dshare->state == STATE_RUN_PENDING)
|
||||
return SNDRV_PCM_STATE_RUNNING;
|
||||
return dshare->state;
|
||||
@@ -646,7 +651,7 @@ static const snd_pcm_fast_ops_t snd_pcm_
|
||||
.avail_update = snd_pcm_dshare_avail_update,
|
||||
.mmap_commit = snd_pcm_dshare_mmap_commit,
|
||||
.htimestamp = snd_pcm_dshare_htimestamp,
|
||||
- .poll_descriptors = NULL,
|
||||
+ .poll_descriptors = snd_pcm_direct_poll_descriptors,
|
||||
.poll_descriptors_count = NULL,
|
||||
.poll_revents = snd_pcm_direct_poll_revents,
|
||||
};
|
||||
--- a/src/pcm/pcm_dsnoop.c
|
||||
+++ b/src/pcm/pcm_dsnoop.c
|
||||
@@ -208,17 +208,22 @@ static int snd_pcm_dsnoop_status(snd_pcm
|
||||
static snd_pcm_state_t snd_pcm_dsnoop_state(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_direct_t *dsnoop = pcm->private_data;
|
||||
+ int err;
|
||||
snd_pcm_state_t state;
|
||||
state = snd_pcm_state(dsnoop->spcm);
|
||||
switch (state) {
|
||||
- case SND_PCM_STATE_XRUN:
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
case SND_PCM_STATE_DISCONNECTED:
|
||||
dsnoop->state = state;
|
||||
return state;
|
||||
+ case SND_PCM_STATE_XRUN:
|
||||
+ if ((err = snd_pcm_direct_slave_recover(dsnoop)) < 0)
|
||||
+ return err;
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+ snd_pcm_direct_client_chk_xrun(dsnoop, pcm);
|
||||
return dsnoop->state;
|
||||
}
|
||||
|
||||
@@ -531,7 +536,7 @@ static const snd_pcm_fast_ops_t snd_pcm_
|
||||
.avail_update = snd_pcm_dsnoop_avail_update,
|
||||
.mmap_commit = snd_pcm_dsnoop_mmap_commit,
|
||||
.htimestamp = snd_pcm_dsnoop_htimestamp,
|
||||
- .poll_descriptors = NULL,
|
||||
+ .poll_descriptors = snd_pcm_direct_poll_descriptors,
|
||||
.poll_descriptors_count = NULL,
|
||||
.poll_revents = snd_pcm_direct_poll_revents,
|
||||
};
|
@ -0,0 +1,51 @@
|
||||
From 79a358ae26f74ed9b92b2190d4725325edf0c787 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Tue, 10 Jan 2017 12:04:09 +0530
|
||||
Subject: [PATCH 13/43] pcm: direct: don't return bogus buffer levels in xrun
|
||||
state
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Mounesh Sutar <mounesh_sutar@mentor.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_dmix.c | 3 +++
|
||||
src/pcm/pcm_dshare.c | 3 +++
|
||||
src/pcm/pcm_dsnoop.c | 3 +++
|
||||
3 files changed, 9 insertions(+)
|
||||
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -882,6 +882,9 @@ static snd_pcm_sframes_t snd_pcm_dmix_av
|
||||
if ((err = snd_pcm_dmix_sync_ptr(pcm)) < 0)
|
||||
return err;
|
||||
}
|
||||
+ if (dmix->state == SND_PCM_STATE_XRUN)
|
||||
+ return -EPIPE;
|
||||
+
|
||||
return snd_pcm_mmap_playback_avail(pcm);
|
||||
}
|
||||
|
||||
--- a/src/pcm/pcm_dshare.c
|
||||
+++ b/src/pcm/pcm_dshare.c
|
||||
@@ -570,6 +570,9 @@ static snd_pcm_sframes_t snd_pcm_dshare_
|
||||
if ((err = snd_pcm_dshare_sync_ptr(pcm)) < 0)
|
||||
return err;
|
||||
}
|
||||
+ if (dshare->state == SND_PCM_STATE_XRUN)
|
||||
+ return -EPIPE;
|
||||
+
|
||||
return snd_pcm_mmap_playback_avail(pcm);
|
||||
}
|
||||
|
||||
--- a/src/pcm/pcm_dsnoop.c
|
||||
+++ b/src/pcm/pcm_dsnoop.c
|
||||
@@ -454,6 +454,9 @@ static snd_pcm_sframes_t snd_pcm_dsnoop_
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
+ if (dsnoop->state == SND_PCM_STATE_XRUN)
|
||||
+ return -EPIPE;
|
||||
+
|
||||
return snd_pcm_mmap_capture_avail(pcm);
|
||||
}
|
||||
|
284
0014-conf-ucm-broxton-add-broxton-rt298-conf-files.patch
Normal file
284
0014-conf-ucm-broxton-add-broxton-rt298-conf-files.patch
Normal file
@ -0,0 +1,284 @@
|
||||
From 360c976aaa051809c34cb412ffa52380baeaabee Mon Sep 17 00:00:00 2001
|
||||
From: Vinod Koul <vinod.koul@intel.com>
|
||||
Date: Thu, 12 Jan 2017 14:50:28 +0530
|
||||
Subject: [PATCH 14/43] conf/ucm: broxton: add broxton-rt298 conf files
|
||||
|
||||
This adds the UCM conf files for broxton enabling with rt298 codec on
|
||||
I2S audio, HDMI and DMIC ports.
|
||||
|
||||
Signed-off-by: Nishit Sharma <nishitx.sharma@intel.com>
|
||||
Signed-off-by: G Kranthi <gudishax.kranthikumar@intel.com>
|
||||
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
configure.ac | 1
|
||||
src/conf/ucm/Makefile.am | 2
|
||||
src/conf/ucm/broxton-rt298/Hdmi1 | 22 ++++
|
||||
src/conf/ucm/broxton-rt298/Hdmi2 | 14 ++
|
||||
src/conf/ucm/broxton-rt298/HiFi | 129 ++++++++++++++++++++++++++
|
||||
src/conf/ucm/broxton-rt298/Makefile.am | 4
|
||||
src/conf/ucm/broxton-rt298/broxton-rt298.conf | 58 +++++++++++
|
||||
7 files changed, 229 insertions(+), 1 deletion(-)
|
||||
create mode 100644 src/conf/ucm/broxton-rt298/Hdmi1
|
||||
create mode 100644 src/conf/ucm/broxton-rt298/Hdmi2
|
||||
create mode 100644 src/conf/ucm/broxton-rt298/HiFi
|
||||
create mode 100644 src/conf/ucm/broxton-rt298/Makefile.am
|
||||
create mode 100644 src/conf/ucm/broxton-rt298/broxton-rt298.conf
|
||||
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -684,6 +684,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pict
|
||||
src/conf/topology/bxtrt298/Makefile \
|
||||
alsalisp/Makefile aserver/Makefile \
|
||||
test/Makefile test/lsb/Makefile \
|
||||
+ src/conf/ucm/broxton-rt298/Makefile \
|
||||
utils/Makefile utils/alsa-lib.spec utils/alsa.pc)
|
||||
|
||||
dnl Create asoundlib.h dynamically according to configure options
|
||||
--- a/src/conf/ucm/Makefile.am
|
||||
+++ b/src/conf/ucm/Makefile.am
|
||||
@@ -1 +1 @@
|
||||
-SUBDIRS=DAISY-I2S PandaBoard PandaBoardES SDP4430 tegraalc5632 PAZ00 GoogleNyan broadwell-rt286 skylake-rt286 VEYRON-I2S chtrt5645 DB410c
|
||||
+SUBDIRS=DAISY-I2S PandaBoard PandaBoardES SDP4430 tegraalc5632 PAZ00 GoogleNyan broadwell-rt286 skylake-rt286 VEYRON-I2S chtrt5645 DB410c broxton-rt298
|
||||
--- /dev/null
|
||||
+++ b/src/conf/ucm/broxton-rt298/Hdmi1
|
||||
@@ -0,0 +1,22 @@
|
||||
+# Usecase for device HDMI1/Display Port stereo playback on Intel SKYLAKE/KABYLAKE platforms
|
||||
+# For Audio in I2S mode
|
||||
+
|
||||
+SectionDevice."Hdmi1" {
|
||||
+ Comment "HDMI/Display Port 1 Stereo"
|
||||
+
|
||||
+ EnableSequence [
|
||||
+ exec "echo Hdmi1 EnableSequnece"
|
||||
+ ]
|
||||
+
|
||||
+ DisableSequence [
|
||||
+ exec "echo Hdmi1 DisableSequnece"
|
||||
+ ]
|
||||
+
|
||||
+ Value {
|
||||
+ PlaybackPCM "hw:broxtonrt298,4"
|
||||
+ PlaybackChannels "2"
|
||||
+ PlaybackPriority "3"
|
||||
+ JackControl "HDMI/DP, pcm=4 Jack"
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/src/conf/ucm/broxton-rt298/Hdmi2
|
||||
@@ -0,0 +1,14 @@
|
||||
+# Usecase for device HDMI2/Display Port stereo playback on Intel Broxton platforms
|
||||
+# For Audio in I2S mode
|
||||
+
|
||||
+SectionDevice."Hdmi2" {
|
||||
+ Comment "HDMI/Display Port 2 Stereo"
|
||||
+
|
||||
+ Value {
|
||||
+ PlaybackPCM "hw:broxtonrt298,5"
|
||||
+ PlaybackChannels "2"
|
||||
+ PlaybackPriority "4"
|
||||
+ JackControl "HDMI/DP, pcm=5 Jack"
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/src/conf/ucm/broxton-rt298/HiFi
|
||||
@@ -0,0 +1,129 @@
|
||||
+# Usecase for stereo playback Speaker and Headset, Recording on DMIC and Headset MIC.
|
||||
+# For Audio in I2S mode on Intel Broxton platforms
|
||||
+
|
||||
+SectionVerb {
|
||||
+
|
||||
+ EnableSequence [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' 1"
|
||||
+ ]
|
||||
+
|
||||
+ DisableSequence [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ ]
|
||||
+
|
||||
+ Value {
|
||||
+ TQ "HiFi"
|
||||
+ CapturePCM "hw:broxtonrt298,1"
|
||||
+ PlaybackPCM "hw:broxtonrt298,0"
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+SectionDevice."dmiccap" {
|
||||
+ Comment "DMIC Stereo"
|
||||
+
|
||||
+ ConflictingDevice [
|
||||
+ "Headset"
|
||||
+ ]
|
||||
+
|
||||
+ EnableSequence [
|
||||
+
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ exec "echo broxtonrt298 dmiccap called"
|
||||
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' 1"
|
||||
+ cset "name='media0_out mo codec0_in mi Switch' 0"
|
||||
+ cset "name='Mic Jack Switch' 0"
|
||||
+
|
||||
+ ]
|
||||
+
|
||||
+ DisableSequence [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ cset "name='media0_out mo codec0_in mi Switch' 1"
|
||||
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' 0"
|
||||
+ cset "name='Mic Jack Switch' 1"
|
||||
+ cset "name='ADC 0 Mux' 0"
|
||||
+ ]
|
||||
+ Value {
|
||||
+ CaptureChannels "2"
|
||||
+ CapturePriority "2"
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+SectionDevice."Headphones" {
|
||||
+ Comment "Headphones"
|
||||
+
|
||||
+ ConflictingDevice [
|
||||
+ "Speaker"
|
||||
+ ]
|
||||
+ EnableSequence [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ exec "echo broxtonrt298 Headphone called"
|
||||
+ cset "name='HPO L Switch' 1"
|
||||
+ cset "name='HPO R Switch' 1"
|
||||
+ cset "name='Headphone Jack Switch' 1"
|
||||
+ cset "name='Speaker Playback Switch' 0,0"
|
||||
+ ]
|
||||
+
|
||||
+ DisableSequence [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ ]
|
||||
+ Value {
|
||||
+ PlaybackChannels "2"
|
||||
+ PlaybackPriority "1"
|
||||
+ JackControl "Headphone Jack"
|
||||
+ JackHWMute "Speaker"
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+SectionDevice."Speaker" {
|
||||
+ Comment "Speaker"
|
||||
+
|
||||
+ ConflictingDevice [
|
||||
+ "Headphones"
|
||||
+ ]
|
||||
+ EnableSequence [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ exec "echo broxtonrt298 speaker called"
|
||||
+ cset "name='SPO Switch' 1"
|
||||
+ cset "name='Speaker Playback Switch' 1,1"
|
||||
+ cset "name='Speaker Switch' 1"
|
||||
+ cset "name='HPO L Switch' 0"
|
||||
+ cset "name='HPO R Switch' 0"
|
||||
+ ]
|
||||
+
|
||||
+ DisableSequence [
|
||||
+ ]
|
||||
+ Value {
|
||||
+ PlaybackChannels "2"
|
||||
+ PlaybackPriority "1"
|
||||
+ JackHWMute "Headphones"
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+SectionDevice."Headset" {
|
||||
+ Comment "Headset Mic"
|
||||
+
|
||||
+ ConflictingDevice [
|
||||
+ "dmiccap"
|
||||
+ ]
|
||||
+ EnableSequence [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ exec "echo broxtonrt298 Headset called"
|
||||
+ cset "name='media0_out mo codec0_in mi Switch' 1"
|
||||
+ cset "name='ADC0 Capture Volume' 105,105"
|
||||
+ cset "name='ADC 0 Mux' 0"
|
||||
+ cset "name='Mic Jack Switch' 1"
|
||||
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' 0"
|
||||
+ ]
|
||||
+
|
||||
+ DisableSequence [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' 1"
|
||||
+ cset "name='media0_out mo codec0_in mi Switch' 0"
|
||||
+ ]
|
||||
+ Value {
|
||||
+ CaptureChannels "2"
|
||||
+ CapturePriority "2"
|
||||
+ JackControl "Mic Jack"
|
||||
+ }
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/src/conf/ucm/broxton-rt298/Makefile.am
|
||||
@@ -0,0 +1,4 @@
|
||||
+alsaconfigdir = @ALSA_CONFIG_DIR@
|
||||
+ucmdir = $(alsaconfigdir)/ucm/broxton-rt298
|
||||
+ucm_DATA = broxton-rt298.conf HiFi Hdmi1 Hdmi2
|
||||
+EXTRA_DIST = $(ucm_DATA)
|
||||
--- /dev/null
|
||||
+++ b/src/conf/ucm/broxton-rt298/broxton-rt298.conf
|
||||
@@ -0,0 +1,58 @@
|
||||
+# UCM for Intel Broxton platforms
|
||||
+# For Audio in I2S mode
|
||||
+
|
||||
+SectionUseCase."HiFi" {
|
||||
+ File "HiFi"
|
||||
+ Comment "Play and record HiFi quality Music"
|
||||
+}
|
||||
+
|
||||
+SectionUseCase."Hdmi1" {
|
||||
+ File "Hdmi1"
|
||||
+ Comment "Play on Hdmi/DP 1"
|
||||
+}
|
||||
+
|
||||
+SectionUseCase."Hdmi2" {
|
||||
+ File "Hdmi2"
|
||||
+ Comment "Play on Hdmi/DP 2"
|
||||
+}
|
||||
+
|
||||
+ValueDefaults {
|
||||
+ PlaybackCTL "hw:broxtonrt298"
|
||||
+ CaptureCTL "hw:broxtonrt298"
|
||||
+ CaptureChannels "2"
|
||||
+ CapturePriority "2"
|
||||
+}
|
||||
+
|
||||
+SectionDefaults [
|
||||
+ cdev "hw:broxtonrt298"
|
||||
+ exec "echo broxtonrt298 CONF Defaults"
|
||||
+ cset "name='Headphone Jack Switch' 1"
|
||||
+ cset "name='Speaker Switch' 1"
|
||||
+ cset "name='Speaker Playback Switch' 0,0"
|
||||
+ cset "name='Front DAC Switch' 1"
|
||||
+ cset "name='Front RECMIX Switch' 0"
|
||||
+ cset "name='Mic Jack Switch' 1"
|
||||
+ cset "name='ADC 0 Mux' 2"
|
||||
+ cset "name='ADC 1 Mux' 0"
|
||||
+ cset "name='DAC0 Playback Volume' 100,100"
|
||||
+ cset "name='HPO L Switch' 0"
|
||||
+ cset "name='HPO Mux' 0"
|
||||
+ cset "name='HPO R Switch' 0"
|
||||
+ cset "name='Pin 5 Mux' 1"
|
||||
+ cset "name='Pin 6 Mux' 2"
|
||||
+ cset "name='Pin 7 Mux' 3"
|
||||
+ cset "name='RECMIX Beep Switch' 0"
|
||||
+ cset "name='RECMIX Line1 Switch' 0"
|
||||
+ cset "name='RECMIX Mic1 Switch' 0"
|
||||
+ cset "name='SPK Mux' 0"
|
||||
+ cset "name='SPO Switch' 1"
|
||||
+ cset "name='codec0_out mo codec0_in mi Switch' 0"
|
||||
+ cset "name='codec0_out mo dmic01_hifi_in mi Switch' 0"
|
||||
+ cset "name='codec0_out mo media0_in mi Switch' 1"
|
||||
+ cset "name='codec1_out mo codec0_in mi Switch' 0"
|
||||
+ cset "name='codec1_out mo dmic01_hifi_in mi Switch' 0"
|
||||
+ cset "name='codec1_out mo media0_in mi Switch' 0"
|
||||
+ cset "name='media0_out mo codec0_in mi Switch' 1"
|
||||
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' 1"
|
||||
+ cset "name='media0_out mo media0_in mi Switch' 0"
|
||||
+]
|
32
0015-pcm-direct-Fix-deadlock-in-poll_descriptors.patch
Normal file
32
0015-pcm-direct-Fix-deadlock-in-poll_descriptors.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 24e63b75275e9c923c336b8dba3919b980e8f234 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Mon, 16 Jan 2017 16:21:52 +0100
|
||||
Subject: [PATCH 15/43] pcm: direct: Fix deadlock in poll_descriptors
|
||||
|
||||
The recent change in PCM direct plugins to check XRUN in
|
||||
poll_descriptors callback caused a regression; as consequence, the
|
||||
whole playback hangs up.
|
||||
|
||||
The culprit is a mutex dead lock by the call in snd_pcm_state() inside
|
||||
the new snd_pcm_direct_poll_descriptors(). The poll_descriptors code
|
||||
path is protected with pcm mutex, thus an unlocked version
|
||||
(__snd_pcm_state()) has to be used inside the callback instead.
|
||||
|
||||
Fixes: 789ee39727a1 ("pcm: direct: check state before enter poll on timer")
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -676,7 +676,8 @@ int snd_pcm_direct_poll_descriptors(snd_
|
||||
}
|
||||
|
||||
/* this will also evaluate slave state and enter xrun if necessary */
|
||||
- switch (snd_pcm_state(pcm)) {
|
||||
+ /* using __snd_pcm_state() since this function is called inside lock */
|
||||
+ switch (__snd_pcm_state(pcm)) {
|
||||
case SND_PCM_STATE_XRUN:
|
||||
return -EPIPE;
|
||||
default:
|
@ -0,0 +1,43 @@
|
||||
From 2b9b3f013467765219c8ab8a50943d3c7db68f75 Mon Sep 17 00:00:00 2001
|
||||
From: Mengdong Lin <mengdong.lin@linux.intel.com>
|
||||
Date: Wed, 18 Jan 2017 11:52:35 +0800
|
||||
Subject: [PATCH 16/43] ucm: Assure the user input card name not to exceed max
|
||||
size of card long name
|
||||
|
||||
Users can load a card's UCM configuration file by giving the card short
|
||||
name or long name, which should not exceed the maximum card long name
|
||||
defined by the kernel. The kernel uses an 80-character buffer to store
|
||||
the card long name.
|
||||
|
||||
Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/ucm/parser.c | 6 ++++++
|
||||
src/ucm/ucm_local.h | 1 +
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
--- a/src/ucm/parser.c
|
||||
+++ b/src/ucm/parser.c
|
||||
@@ -1335,6 +1335,12 @@ static int load_master_config(const char
|
||||
char *env = getenv(ALSA_CONFIG_UCM_VAR);
|
||||
int err;
|
||||
|
||||
+ if (strnlen(card_name, MAX_CARD_LONG_NAME) == MAX_CARD_LONG_NAME) {
|
||||
+ uc_error("error: invalid card name %s (at most %d chars)\n",
|
||||
+ card_name, MAX_CARD_LONG_NAME - 1);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
snprintf(filename, sizeof(filename)-1,
|
||||
"%s/%s/%s.conf", env ? env : ALSA_USE_CASE_DIR,
|
||||
card_name, card_name);
|
||||
--- a/src/ucm/ucm_local.h
|
||||
+++ b/src/ucm/ucm_local.h
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "use-case.h"
|
||||
|
||||
#define MAX_FILE 256
|
||||
+#define MAX_CARD_LONG_NAME 80
|
||||
#define ALSA_USE_CASE_DIR ALSA_CONFIG_DIR "/ucm"
|
||||
|
||||
#define SEQUENCE_ELEMENT_TYPE_CDEV 1
|
177
0017-ucm-Load-device-specific-configuration-file-based-on.patch
Normal file
177
0017-ucm-Load-device-specific-configuration-file-based-on.patch
Normal file
@ -0,0 +1,177 @@
|
||||
From 4b9297e65f541f1a6c1b4a036f66936b9cafe030 Mon Sep 17 00:00:00 2001
|
||||
From: Mengdong Lin <mengdong.lin@linux.intel.com>
|
||||
Date: Wed, 18 Jan 2017 11:53:35 +0800
|
||||
Subject: [PATCH 17/43] ucm: Load device-specific configuration file based on
|
||||
the card long name
|
||||
|
||||
Intel DSP platform drivers are used by many different devices. For user
|
||||
space to differentiate them, ASoC machine drivers may use the DMI info
|
||||
(vendor-product-version-board) as card long name. Possible card long names
|
||||
are:
|
||||
DellInc.-XPS139343-01-0310JH
|
||||
ASUSTeKCOMPUTERINC.-T100TA-1.0-T100TA
|
||||
Circuitco-MinnowboardMaxD0PLATFORM-D0-MinnowBoardMAX
|
||||
...
|
||||
|
||||
If we want to define a device-specific UCM config file for a card, we
|
||||
need to use the card long name as the name of both the directory that
|
||||
contains the UCM config file and the UCM config file itself, like
|
||||
longname/longname.conf
|
||||
|
||||
When being asked to load configuration file of a card, UCM will try to
|
||||
find the card in the local machine and get its long name. If the card
|
||||
long name is available, try to load the file longname/longname.conf to
|
||||
get the best device-specific configuration; if this file is not available,
|
||||
fall back to load the default configuration file shortname/shortname.conf
|
||||
as before.
|
||||
|
||||
This update is backward compatible, because if ASoC machine drivers don't
|
||||
explicity use DMI or other means to set the card long name, ASoC core
|
||||
will use the card short name as the long name. And so UCM will load the
|
||||
config file that matches both the card short name and the long name.
|
||||
|
||||
Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/ucm/parser.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
src/ucm/ucm_local.h | 2 +
|
||||
2 files changed, 97 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/src/ucm/parser.c
|
||||
+++ b/src/ucm/parser.c
|
||||
@@ -56,6 +56,9 @@ static const char * const component_dir[
|
||||
NULL, /* terminator */
|
||||
};
|
||||
|
||||
+static int filename_filter(const struct dirent *dirent);
|
||||
+static int is_component_directory(const char *dir);
|
||||
+
|
||||
static int parse_sequence(snd_use_case_mgr_t *uc_mgr,
|
||||
struct list_head *base,
|
||||
snd_config_t *cfg);
|
||||
@@ -1329,6 +1332,66 @@ static int parse_master_file(snd_use_cas
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* find the card in the local machine and store the card long name */
|
||||
+static int get_card_long_name(snd_use_case_mgr_t *mgr)
|
||||
+{
|
||||
+ const char *card_name = mgr->card_name;
|
||||
+ snd_ctl_t *handle;
|
||||
+ int card, err;
|
||||
+ snd_ctl_card_info_t *info;
|
||||
+ const char *_name, *_long_name;
|
||||
+
|
||||
+ snd_ctl_card_info_alloca(&info);
|
||||
+
|
||||
+ card = -1;
|
||||
+ if (snd_card_next(&card) < 0 || card < 0) {
|
||||
+ uc_error("no soundcards found...");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ while (card >= 0) {
|
||||
+ char name[32];
|
||||
+
|
||||
+ sprintf(name, "hw:%d", card);
|
||||
+ err = snd_ctl_open(&handle, name, 0);
|
||||
+ if (err < 0) {
|
||||
+ uc_error("control open (%i): %s", card,
|
||||
+ snd_strerror(err));
|
||||
+ goto next_card;
|
||||
+ }
|
||||
+
|
||||
+ err = snd_ctl_card_info(handle, info);
|
||||
+ if (err < 0) {
|
||||
+ uc_error("control hardware info (%i): %s", card,
|
||||
+ snd_strerror(err));
|
||||
+ snd_ctl_close(handle);
|
||||
+ goto next_card;
|
||||
+ }
|
||||
+
|
||||
+ /* Find the local card by comparing the given name with the
|
||||
+ * card short name and long name. The given card name may be
|
||||
+ * either a short name or long name, because users may open
|
||||
+ * the card by either of the two names.
|
||||
+ */
|
||||
+ _name = snd_ctl_card_info_get_name(info);
|
||||
+ _long_name = snd_ctl_card_info_get_longname(info);
|
||||
+ if (!strcmp(card_name, _name)
|
||||
+ || !strcmp(card_name, _long_name)) {
|
||||
+ strcpy(mgr->card_long_name, _long_name);
|
||||
+ snd_ctl_close(handle);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ snd_ctl_close(handle);
|
||||
+next_card:
|
||||
+ if (snd_card_next(&card) < 0) {
|
||||
+ uc_error("snd_card_next");
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
static int load_master_config(const char *card_name, snd_config_t **cfg)
|
||||
{
|
||||
char filename[MAX_FILE];
|
||||
@@ -1356,15 +1419,43 @@ static int load_master_config(const char
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/* load master use case file for sound card */
|
||||
+/* load master use case file for sound card
|
||||
+ *
|
||||
+ * The same ASoC machine driver can be shared by many different devices.
|
||||
+ * For user space to differentiate them and get the best device-specific
|
||||
+ * configuration, ASoC machine drivers may use the DMI info
|
||||
+ * (vendor-product-version-board) as the card long name. And user space can
|
||||
+ * define configuration files like longnamei/longname.conf for a specific device.
|
||||
+ *
|
||||
+ * This function will try to find the card in the local machine and get its
|
||||
+ * long name, then load the file longname/longname.conf to get the best
|
||||
+ * device-specific configuration. If the card is not found in the local
|
||||
+ * machine or the device-specific file is not available, fall back to load
|
||||
+ * the default configuration file name/name.conf.
|
||||
+ */
|
||||
int uc_mgr_import_master_config(snd_use_case_mgr_t *uc_mgr)
|
||||
{
|
||||
snd_config_t *cfg;
|
||||
int err;
|
||||
|
||||
- err = load_master_config(uc_mgr->card_name, &cfg);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
+ err = get_card_long_name(uc_mgr);
|
||||
+ if (err == 0) /* load file that maches the card long name */
|
||||
+ err = load_master_config(uc_mgr->card_long_name, &cfg);
|
||||
+
|
||||
+ if (err == 0) {
|
||||
+ /* got device-specific file that matches the card long name */
|
||||
+ strcpy(uc_mgr->conf_file_name, uc_mgr->card_long_name);
|
||||
+ } else {
|
||||
+ /* Fall back to the file that maches the given card name,
|
||||
+ * either short name or long name (users may open a card by
|
||||
+ * its name or long name).
|
||||
+ */
|
||||
+ err = load_master_config(uc_mgr->card_name, &cfg);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ strcpy(uc_mgr->conf_file_name, uc_mgr->card_name);
|
||||
+ }
|
||||
+
|
||||
err = parse_master_file(uc_mgr, cfg);
|
||||
snd_config_delete(cfg);
|
||||
if (err < 0)
|
||||
--- a/src/ucm/ucm_local.h
|
||||
+++ b/src/ucm/ucm_local.h
|
||||
@@ -191,6 +191,8 @@ struct use_case_verb {
|
||||
*/
|
||||
struct snd_use_case_mgr {
|
||||
char *card_name;
|
||||
+ char card_long_name[MAX_CARD_LONG_NAME];
|
||||
+ char conf_file_name[MAX_CARD_LONG_NAME];
|
||||
char *comment;
|
||||
|
||||
/* use case verb, devices and modifier configs parsed from files */
|
@ -0,0 +1,51 @@
|
||||
From e93d93a8cd37f94f119aba72ca05d7f92b648bcc Mon Sep 17 00:00:00 2001
|
||||
From: Mengdong Lin <mengdong.lin@linux.intel.com>
|
||||
Date: Wed, 18 Jan 2017 11:53:42 +0800
|
||||
Subject: [PATCH 18/43] ucm: Add command 'get _file' to get the config file
|
||||
name of the opened card
|
||||
|
||||
After opening a card, this command can show the name of the actually
|
||||
loaded configuration file, either matches the card name or card long name.
|
||||
So developers can check if there is a device-sepcific configuration file
|
||||
available for a given card.
|
||||
|
||||
Signed-off-by: Mengdong Lin <mengdong.lin@linux.intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
include/use-case.h | 1 +
|
||||
src/ucm/main.c | 14 ++++++++++++++
|
||||
2 files changed, 15 insertions(+)
|
||||
|
||||
--- a/include/use-case.h
|
||||
+++ b/include/use-case.h
|
||||
@@ -230,6 +230,7 @@ int snd_use_case_get_list(snd_use_case_m
|
||||
* Known identifiers:
|
||||
* - NULL - return current card
|
||||
* - _verb - return current verb
|
||||
+ * - _file - return configuration file loaded for current card
|
||||
*
|
||||
* - [=]{NAME}[/[{modifier}|{/device}][/{verb}]]
|
||||
* - value identifier {NAME}
|
||||
--- a/src/ucm/main.c
|
||||
+++ b/src/ucm/main.c
|
||||
@@ -1528,6 +1528,20 @@ int snd_use_case_get(snd_use_case_mgr_t
|
||||
goto __end;
|
||||
}
|
||||
err = 0;
|
||||
+ } else if (strcmp(identifier, "_file") == 0) {
|
||||
+ /* get the conf file name of the opened card */
|
||||
+ if ((uc_mgr->card_name == NULL)
|
||||
+ || (uc_mgr->conf_file_name[0] == '\0')) {
|
||||
+ err = -ENOENT;
|
||||
+ goto __end;
|
||||
+ }
|
||||
+ *value = strndup(uc_mgr->conf_file_name, MAX_FILE);
|
||||
+ if (*value == NULL) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto __end;
|
||||
+ }
|
||||
+ err = 0;
|
||||
+
|
||||
} else if (identifier[0] == '_') {
|
||||
err = -ENOENT;
|
||||
goto __end;
|
278
0019-topology-Fix-incorrect-license-in-source-comments.patch
Normal file
278
0019-topology-Fix-incorrect-license-in-source-comments.patch
Normal file
@ -0,0 +1,278 @@
|
||||
From ec40aafa4374f2388876702513c4b3eee2e2235f Mon Sep 17 00:00:00 2001
|
||||
From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
Date: Tue, 24 Jan 2017 14:59:08 +0000
|
||||
Subject: [PATCH 19/43] topology: Fix incorrect license in source comments.
|
||||
|
||||
The topology source files had the wrong licence specified in the
|
||||
comments when initially upstreamed. The topology source files are all
|
||||
licensed under the LGPL-2.1 and not the GPLv2.
|
||||
|
||||
All earlier versions of the alsa-lib topology source files must be
|
||||
considered LGPL-2.1 like the other source files in alsa-lib and also
|
||||
as specified in the alsa-lib COPYING file.
|
||||
|
||||
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/topology/builder.c | 15 ++++++++-------
|
||||
src/topology/channel.c | 15 ++++++++-------
|
||||
src/topology/ctl.c | 15 ++++++++-------
|
||||
src/topology/dapm.c | 15 ++++++++-------
|
||||
src/topology/data.c | 15 ++++++++-------
|
||||
src/topology/elem.c | 15 ++++++++-------
|
||||
src/topology/ops.c | 15 ++++++++-------
|
||||
src/topology/parser.c | 15 ++++++++-------
|
||||
src/topology/pcm.c | 15 ++++++++-------
|
||||
src/topology/text.c | 15 ++++++++-------
|
||||
10 files changed, 80 insertions(+), 70 deletions(-)
|
||||
|
||||
--- a/src/topology/builder.c
|
||||
+++ b/src/topology/builder.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/channel.c
|
||||
+++ b/src/topology/channel.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/dapm.c
|
||||
+++ b/src/topology/dapm.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/data.c
|
||||
+++ b/src/topology/data.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/elem.c
|
||||
+++ b/src/topology/elem.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/ops.c
|
||||
+++ b/src/topology/ops.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/parser.c
|
||||
+++ b/src/topology/parser.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/pcm.c
|
||||
+++ b/src/topology/pcm.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
||||
--- a/src/topology/text.c
|
||||
+++ b/src/topology/text.c
|
||||
@@ -2,14 +2,15 @@
|
||||
Copyright(c) 2014-2015 Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
- This program is free software; you can redistribute it and/or modify
|
||||
- it under the terms of version 2 of the GNU General Public License as
|
||||
- published by the Free Software Foundation.
|
||||
+ This library is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 of
|
||||
+ the License, or (at your option) any later version.
|
||||
|
||||
- This program is distributed in the hope that it will be useful, but
|
||||
- WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
- General Public License for more details.
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU Lesser General Public License for more details.
|
||||
|
||||
Authors: Mengdong Lin <mengdong.lin@intel.com>
|
||||
Yao Jin <yao.jin@intel.com>
|
100
0020-conf-cards-add-support-for-pistachio-card.patch
Normal file
100
0020-conf-cards-add-support-for-pistachio-card.patch
Normal file
@ -0,0 +1,100 @@
|
||||
From 4dfa8f08fb834f7b087f35f9ba1746cd0c989d02 Mon Sep 17 00:00:00 2001
|
||||
From: Manohar Narkhede <Manohar.Narkhede@imgtec.com>
|
||||
Date: Wed, 25 Jan 2017 22:14:15 +0100
|
||||
Subject: [PATCH 20/43] conf/cards: add support for pistachio-card.
|
||||
|
||||
The data sheet of the chip and technical reference manual can be found at https://docs.creatordev.io/ci40/guides/hardwaredocs/cXT200_datasheet2.pdf
|
||||
and https://docs.creatordev.io/ci40/guides/hardwaredocs/MIPS_Creator_cXT200_Technical_Reference_Manual_1.0.112.pdf.
|
||||
|
||||
The additional information about the cards can be found in src/conf/cards/pistachio-card.conf file.
|
||||
|
||||
Signed-off-by: Manohar Narkhede <Manohar.Narkhede@imgtec.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/conf/cards/Makefile.am | 1
|
||||
src/conf/cards/aliases.conf | 1
|
||||
src/conf/cards/pistachio-card.conf | 58 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 60 insertions(+)
|
||||
create mode 100644 src/conf/cards/pistachio-card.conf
|
||||
|
||||
--- a/src/conf/cards/Makefile.am
|
||||
+++ b/src/conf/cards/Makefile.am
|
||||
@@ -39,6 +39,7 @@ cfg_files = aliases.conf \
|
||||
Maestro3.conf \
|
||||
NFORCE.conf \
|
||||
PC-Speaker.conf \
|
||||
+ pistachio-card.conf \
|
||||
PMac.conf \
|
||||
PMacToonie.conf \
|
||||
PS3.conf \
|
||||
--- a/src/conf/cards/aliases.conf
|
||||
+++ b/src/conf/cards/aliases.conf
|
||||
@@ -55,6 +55,7 @@ AV100 cards.CMI8788
|
||||
AV200 cards.CMI8788
|
||||
CMI8786 cards.CMI8788
|
||||
CMI8787 cards.CMI8788
|
||||
+pistachio cards.pistachio-card
|
||||
|
||||
<confdir:pcm/default.conf>
|
||||
<confdir:pcm/dmix.conf>
|
||||
--- /dev/null
|
||||
+++ b/src/conf/cards/pistachio-card.conf
|
||||
@@ -0,0 +1,58 @@
|
||||
+#
|
||||
+# Configuration for the pistachio chip.
|
||||
+#
|
||||
+# The data sheet of the chip and technical reference manual can be
|
||||
+found at
|
||||
+https://docs.creatordev.io/ci40/guides/hardwaredocs/cXT200_datasheet2.p
|
||||
+df # and
|
||||
+https://docs.creatordev.io/ci40/guides/hardwaredocs/MIPS_Creator_cXT200_Technical_Reference_Manual_1.0.112.pdf.
|
||||
+#
|
||||
+# The list of hardware devices is as per below:
|
||||
+#
|
||||
+# root@OpenWrt:/# arecord -l
|
||||
+# **** List of CAPTURE Hardware Devices **** card 0: pistachiocard [pistachio-card], device 1: pistachio-spdif-in snd-soc-dummy-dai-1 []
|
||||
+# Subdevices: 1/1
|
||||
+# Subdevice #0: subdevice #0
|
||||
+# card 0: pistachiocard [pistachio-card], device 4: pistachio-i2s-in-0 snd-soc-dummy-dai-4 []
|
||||
+# Subdevices: 1/1
|
||||
+# Subdevice #0: subdevice #0
|
||||
+#
|
||||
+# root@OpenWrt:/# aplay -l
|
||||
+# **** List of PLAYBACK Hardware Devices **** card 0: pistachiocard [pistachio-card], device 0: pistachio-spdif-out snd-soc-dummy-dai-0 []
|
||||
+# Subdevices: 1/1
|
||||
+# Subdevice #0: subdevice #0
|
||||
+# card 0: pistachiocard [pistachio-card], device 2: pistachio-parallel-out pistachio_internal_dac-2 []
|
||||
+# Subdevices: 1/1
|
||||
+# Subdevice #0: subdevice #0
|
||||
+# card 0: pistachiocard [pistachio-card], device 3: pistachio-i2s-out snd-soc-dummy-dai-3 []
|
||||
+# Subdevices: 1/1
|
||||
+# Subdevice #0: subdevice #0
|
||||
+#
|
||||
+
|
||||
+pistachio-card.pcm.default{
|
||||
+ @args [ CARD ]
|
||||
+ @args.CARD {
|
||||
+ type string
|
||||
+ default "pistachio"
|
||||
+ }
|
||||
+ @args.DEVICE {
|
||||
+ type integer
|
||||
+ default 2
|
||||
+ }
|
||||
+
|
||||
+ type asym
|
||||
+ capture.pcm {
|
||||
+ type multi
|
||||
+ slaves.a.pcm "hw:0,4"
|
||||
+ slaves.a.channels 12
|
||||
+ bindings.0.slave a
|
||||
+ bindings.0.channel 4
|
||||
+ bindings.1.slave a
|
||||
+ bindings.1.channel 5
|
||||
+ }
|
||||
+
|
||||
+ playback.pcm {
|
||||
+ type hw
|
||||
+ card $CARD
|
||||
+ device $DEVICE
|
||||
+
|
@ -0,0 +1,44 @@
|
||||
From e1143dd9ba350eb19d13d4e298eeb55179712a1e Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Fri, 27 Jan 2017 12:01:51 +0100
|
||||
Subject: [PATCH 21/43] pcm: multi: Drop the fixed slave_map[] in
|
||||
snd_pcm_multi_open()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
slave_map[] in snd_pcm_multi_open() is a fixed size array and
|
||||
obviously we have no overflow check, and eventually the program gets
|
||||
an error when more than 64 channels are used.
|
||||
|
||||
Although we can modify the code to allocate the array dynamically, it
|
||||
turned out that we can drop the whole slave_map[] thingy in this
|
||||
function when looking at the code closely. In the past, it was used
|
||||
to identify the one-to-many mapping. But the check was dropped, and
|
||||
now it's nothing more than a sanity check.
|
||||
|
||||
Reported-by: Jörg Müller <joerg.mueller7744@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_multi.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_multi.c
|
||||
+++ b/src/pcm/pcm_multi.c
|
||||
@@ -1015,7 +1015,6 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp,
|
||||
snd_pcm_multi_t *multi;
|
||||
unsigned int i;
|
||||
snd_pcm_stream_t stream;
|
||||
- char slave_map[64][64] = { { 0 } };
|
||||
int err;
|
||||
|
||||
assert(pcmp);
|
||||
@@ -1059,8 +1058,6 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp,
|
||||
bind->slave_channel = schannels[i];
|
||||
if (sidxs[i] < 0)
|
||||
continue;
|
||||
- assert(!slave_map[sidxs[i]][schannels[i]]);
|
||||
- slave_map[sidxs[i]][schannels[i]] = 1;
|
||||
}
|
||||
multi->channels_count = channels_count;
|
||||
|
115
0022-conf-Add-card-config-for-Intel-HDMI-DP-LPE-audio.patch
Normal file
115
0022-conf-Add-card-config-for-Intel-HDMI-DP-LPE-audio.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From 53dc36f1f465e2a1f9ed37906a7f16a438f941e4 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 7 Feb 2017 14:25:17 +0100
|
||||
Subject: [PATCH 22/43] conf: Add card config for Intel HDMI/DP LPE audio
|
||||
|
||||
It's a playback-only device with a single PCM dedicated for HDMI/DP
|
||||
output. The dmix is working with the latest driver code, so enable it
|
||||
for default, while providing the hdmi PCM dev for the accesses with
|
||||
AES bits.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/conf/cards/HdmiLpeAudio.conf | 85 +++++++++++++++++++++++++++++++++++++++
|
||||
src/conf/cards/Makefile.am | 1
|
||||
2 files changed, 86 insertions(+)
|
||||
create mode 100644 src/conf/cards/HdmiLpeAudio.conf
|
||||
|
||||
--- /dev/null
|
||||
+++ b/src/conf/cards/HdmiLpeAudio.conf
|
||||
@@ -0,0 +1,85 @@
|
||||
+#
|
||||
+# Configuration for the Intel HDMI/DP LPE audio
|
||||
+#
|
||||
+
|
||||
+<confdir:pcm/front.conf>
|
||||
+
|
||||
+HdmiLpeAudio.pcm.front.0 {
|
||||
+ @args [ CARD ]
|
||||
+ @args.CARD {
|
||||
+ type string
|
||||
+ }
|
||||
+ type softvol
|
||||
+ slave.pcm {
|
||||
+ type hw
|
||||
+ card $CARD
|
||||
+ }
|
||||
+ control {
|
||||
+ name "PCM Playback Volume"
|
||||
+ card $CARD
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+# default with dmix+softvol
|
||||
+HdmiLpeAudio.pcm.default {
|
||||
+ @args [ CARD ]
|
||||
+ @args.CARD {
|
||||
+ type string
|
||||
+ }
|
||||
+ type plug
|
||||
+ slave.pcm {
|
||||
+ type softvol
|
||||
+ slave.pcm {
|
||||
+ @func concat
|
||||
+ strings [ "dmix:" $CARD ]
|
||||
+ }
|
||||
+ control {
|
||||
+ name "PCM Playback Volume"
|
||||
+ card $CARD
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+<confdir:pcm/surround40.conf>
|
||||
+<confdir:pcm/surround21.conf>
|
||||
+<confdir:pcm/surround41.conf>
|
||||
+<confdir:pcm/surround50.conf>
|
||||
+<confdir:pcm/surround51.conf>
|
||||
+
|
||||
+<confdir:pcm/hdmi.conf>
|
||||
+
|
||||
+HdmiLpeAudio.pcm.hdmi.0 {
|
||||
+ @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
|
||||
+ }
|
||||
+ hooks.0 {
|
||||
+ type ctl_elems
|
||||
+ hook_args [
|
||||
+ {
|
||||
+ interface PCM
|
||||
+ name "IEC958 Playback Default"
|
||||
+ lock true
|
||||
+ preserve true
|
||||
+ value [ $AES0 $AES1 $AES2 $AES3 ]
|
||||
+ }
|
||||
+ ]
|
||||
+ }
|
||||
+}
|
||||
--- a/src/conf/cards/Makefile.am
|
||||
+++ b/src/conf/cards/Makefile.am
|
||||
@@ -30,6 +30,7 @@ cfg_files = aliases.conf \
|
||||
FireWave.conf \
|
||||
GUS.conf \
|
||||
HDA-Intel.conf \
|
||||
+ HdmiLpeAudio.conf \
|
||||
ICE1712.conf \
|
||||
ICE1724.conf \
|
||||
ICH.conf \
|
43
0023-pcm-Avoid-lock-for-snd_pcm_nonblock.patch
Normal file
43
0023-pcm-Avoid-lock-for-snd_pcm_nonblock.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From b5a2c06f6c5d69fc71ef648af95a044ee1dc25d0 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 9 Feb 2017 17:23:22 +0100
|
||||
Subject: [PATCH 23/43] pcm: Avoid lock for snd_pcm_nonblock()
|
||||
|
||||
snd_pcm_nonblock() is called as snd_pcm_abort(). Since
|
||||
snd_pcm_abort() is called often from a signal handler to clean things
|
||||
up (e.g. aplay does it), we may face a deadlock if the signal is
|
||||
raised during the locked operation.
|
||||
|
||||
There can be some way to check the deadlock state, but they would cost
|
||||
much. Since the race condition of snd_pcm_nonblock() is quite small,
|
||||
let's just drop the locking inside snd_pcm_nonblock() as a
|
||||
workaround.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm.c
|
||||
+++ b/src/pcm/pcm.c
|
||||
@@ -759,7 +759,10 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int
|
||||
int err = 0;
|
||||
|
||||
assert(pcm);
|
||||
- __snd_pcm_lock(pcm); /* forced lock due to pcm field change */
|
||||
+ /* FIXME: __snd_pcm_lock() call below is commented out because of the
|
||||
+ * the possible deadlock in signal handler calling snd_pcm_abort()
|
||||
+ */
|
||||
+ /* __snd_pcm_lock(pcm); */ /* forced lock due to pcm field change */
|
||||
if ((err = pcm->ops->nonblock(pcm->op_arg, nonblock)) < 0)
|
||||
goto unlock;
|
||||
if (nonblock == 2) {
|
||||
@@ -775,7 +778,7 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int
|
||||
pcm->mode &= ~SND_PCM_NONBLOCK;
|
||||
}
|
||||
unlock:
|
||||
- __snd_pcm_unlock(pcm);
|
||||
+ /* __snd_pcm_unlock(pcm); */ /* FIXME: see above */
|
||||
return err;
|
||||
}
|
||||
|
41
0024-pcm-Disable-locking-in-async-mode.patch
Normal file
41
0024-pcm-Disable-locking-in-async-mode.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From e31a3273df6eb619e35d10bf6a0fc0fded91d559 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 9 Feb 2017 17:29:21 +0100
|
||||
Subject: [PATCH 24/43] pcm: Disable locking in async mode
|
||||
|
||||
When PCM is operated in async mode and an async handler calls some PCM
|
||||
functions with lock during other PCM operations, we may hit a
|
||||
deadlock.
|
||||
|
||||
Although async mode is rarely used, it's still a possible use case.
|
||||
Disable the locking when the stream is opened in async mode or it's
|
||||
set to async mode via snd_pcm_async().
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/pcm/pcm.c
|
||||
+++ b/src/pcm/pcm.c
|
||||
@@ -799,6 +799,8 @@ int snd_pcm_async(snd_pcm_t *pcm, int si
|
||||
sig = SIGIO;
|
||||
if (pid == 0)
|
||||
pid = getpid();
|
||||
+ /* async handler may lead to a deadlock; suppose no multi thread */
|
||||
+ pcm->lock_enabled = 0;
|
||||
return pcm->ops->async(pcm->op_arg, sig, pid);
|
||||
}
|
||||
#endif
|
||||
@@ -2597,7 +2599,10 @@ int snd_pcm_new(snd_pcm_t **pcmp, snd_pc
|
||||
* each plugin may suppress this in its open call
|
||||
*/
|
||||
pcm->need_lock = 1;
|
||||
- {
|
||||
+ if (mode & SND_PCM_ASYNC) {
|
||||
+ /* async handler may lead to a deadlock; suppose no MT */
|
||||
+ pcm->lock_enabled = 0;
|
||||
+ } else {
|
||||
/* set lock_enabled field depending on $LIBASOUND_THREAD_SAFE */
|
||||
static int do_lock_enable = -1; /* uninitialized */
|
||||
|
152
0025-pcm-dmix-Allow-disabling-x86-optimizations.patch
Normal file
152
0025-pcm-dmix-Allow-disabling-x86-optimizations.patch
Normal file
@ -0,0 +1,152 @@
|
||||
From 22eca6468b4aea47c783770ec0739d1e13bf3bfc Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Fri, 10 Feb 2017 12:16:12 +0100
|
||||
Subject: [PATCH 25/43] pcm: dmix: Allow disabling x86 optimizations
|
||||
|
||||
The dmix plugin has some optimized implementations for x86 using the
|
||||
direct memory accesses, which was rather the original version, in
|
||||
addition to the "generic" implementation using the semaphore
|
||||
blocking. The x86 implementation relies on the memory coherency *and*
|
||||
the fast read/write on it.
|
||||
|
||||
For other architectures, this has been always disabled just because of
|
||||
memory coherency. But, the recent LPE audio development revealed
|
||||
that, even on x86 platforms, the read/write performance might become
|
||||
extremely bad when the buffer is marked as uncached. Some drivers
|
||||
already know the buffer is uncached, we need to switch to the generic
|
||||
mode in such a case.
|
||||
|
||||
This patch introduces yet another flag to dmix configuration,
|
||||
direct_memory_access, that indicates whether the x86-specific
|
||||
optimization can be used or not. Each driver can set the flag in its
|
||||
cards config namespace, and the default dmix config refers to it.
|
||||
|
||||
As of this patch, only HDMI LPE Audio driver sets it.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/conf/cards/HdmiLpeAudio.conf | 3 +++
|
||||
src/conf/pcm/dmix.conf | 15 +++++++++++++++
|
||||
src/pcm/pcm_direct.c | 8 ++++++++
|
||||
src/pcm/pcm_direct.h | 2 ++
|
||||
src/pcm/pcm_dmix.c | 1 +
|
||||
src/pcm/pcm_dmix_i386.c | 5 +++++
|
||||
src/pcm/pcm_dmix_x86_64.c | 5 +++++
|
||||
7 files changed, 39 insertions(+)
|
||||
|
||||
--- a/src/conf/cards/HdmiLpeAudio.conf
|
||||
+++ b/src/conf/cards/HdmiLpeAudio.conf
|
||||
@@ -20,6 +20,9 @@ HdmiLpeAudio.pcm.front.0 {
|
||||
}
|
||||
}
|
||||
|
||||
+# uncached memory reads have a high penalty
|
||||
+HdmiLpeAudio.dmix.direct_memory_access false
|
||||
+
|
||||
# default with dmix+softvol
|
||||
HdmiLpeAudio.pcm.default {
|
||||
@args [ CARD ]
|
||||
--- a/src/conf/pcm/dmix.conf
|
||||
+++ b/src/conf/pcm/dmix.conf
|
||||
@@ -49,6 +49,21 @@ pcm.!dmix {
|
||||
@func refer
|
||||
name defaults.pcm.ipc_perm
|
||||
}
|
||||
+ direct_memory_access {
|
||||
+ @func refer
|
||||
+ name {
|
||||
+ @func concat
|
||||
+ strings [
|
||||
+ "cards."
|
||||
+ {
|
||||
+ @func card_driver
|
||||
+ card $CARD
|
||||
+ }
|
||||
+ ".dmix.direct_memory_access"
|
||||
+ ]
|
||||
+ }
|
||||
+ default true
|
||||
+ }
|
||||
slave {
|
||||
pcm {
|
||||
type hw
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -1861,6 +1861,7 @@ int snd_pcm_direct_parse_open_conf(snd_c
|
||||
rec->slowptr = 1;
|
||||
rec->max_periods = 0;
|
||||
rec->var_periodsize = 1;
|
||||
+ rec->direct_memory_access = 1;
|
||||
|
||||
/* read defaults */
|
||||
if (snd_config_search(root, "defaults.pcm.dmix_max_periods", &n) >= 0) {
|
||||
@@ -1974,6 +1975,13 @@ int snd_pcm_direct_parse_open_conf(snd_c
|
||||
rec->var_periodsize = err;
|
||||
continue;
|
||||
}
|
||||
+ if (strcmp(id, "direct_memory_access") == 0) {
|
||||
+ err = snd_config_get_bool(n);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ rec->direct_memory_access = err;
|
||||
+ continue;
|
||||
+ }
|
||||
SNDERR("Unknown field %s", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
--- a/src/pcm/pcm_direct.h
|
||||
+++ b/src/pcm/pcm_direct.h
|
||||
@@ -159,6 +159,7 @@ struct snd_pcm_direct {
|
||||
unsigned int channels; /* client's channels */
|
||||
unsigned int *bindings;
|
||||
unsigned int recoveries; /* mirror of executed recoveries on slave */
|
||||
+ int direct_memory_access; /* use arch-optimized buffer RW */
|
||||
union {
|
||||
struct {
|
||||
int shmid_sum; /* IPC global sum ring buffer memory identification */
|
||||
@@ -340,6 +341,7 @@ struct snd_pcm_direct_open_conf {
|
||||
int slowptr;
|
||||
int max_periods;
|
||||
int var_periodsize;
|
||||
+ int direct_memory_access;
|
||||
snd_config_t *slave;
|
||||
snd_config_t *bindings;
|
||||
};
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -1065,6 +1065,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp,
|
||||
dmix->max_periods = opts->max_periods;
|
||||
dmix->var_periodsize = opts->var_periodsize;
|
||||
dmix->sync_ptr = snd_pcm_dmix_sync_ptr;
|
||||
+ dmix->direct_memory_access = opts->direct_memory_access;
|
||||
|
||||
retry:
|
||||
if (first_instance) {
|
||||
--- a/src/pcm/pcm_dmix_i386.c
|
||||
+++ b/src/pcm/pcm_dmix_i386.c
|
||||
@@ -87,6 +87,11 @@ static void mix_select_callbacks(snd_pcm
|
||||
{
|
||||
static int smp = 0, mmx = 0, cmov = 0;
|
||||
|
||||
+ if (!dmix->direct_memory_access) {
|
||||
+ generic_mix_select_callbacks(dmix);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!((1ULL<< dmix->shmptr->s.format) & i386_dmix_supported_format)) {
|
||||
generic_mix_select_callbacks(dmix);
|
||||
return;
|
||||
--- a/src/pcm/pcm_dmix_x86_64.c
|
||||
+++ b/src/pcm/pcm_dmix_x86_64.c
|
||||
@@ -70,6 +70,11 @@ static void mix_select_callbacks(snd_pcm
|
||||
{
|
||||
static int smp = 0;
|
||||
|
||||
+ if (!dmix->direct_memory_access) {
|
||||
+ generic_mix_select_callbacks(dmix);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!((1ULL<< dmix->shmptr->s.format) & x86_64_dmix_supported_format)) {
|
||||
generic_mix_select_callbacks(dmix);
|
||||
return;
|
92
0026-pcm-dmix_rewind-corrupts-application-pointer-fix.patch
Normal file
92
0026-pcm-dmix_rewind-corrupts-application-pointer-fix.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From df7694d80cdd7d273b34ead6841b9f32f5991966 Mon Sep 17 00:00:00 2001
|
||||
From: Timo Wischer <twischer@de.adit-jv.com>
|
||||
Date: Fri, 17 Feb 2017 12:45:36 +0530
|
||||
Subject: [PATCH 26/43] pcm: dmix_rewind corrupts application pointer fix
|
||||
|
||||
sometimes pulseaudio stops with the following assertion in libasound.so:
|
||||
alsa-lib-1.0.29/src/pcm/pcm.c:2761:
|
||||
snd_pcm_area_copy: Assertion `dst < src || dst >= src + bytes' failed.
|
||||
Application pointer is handled properly, in cases of rewind operations.
|
||||
|
||||
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
|
||||
Signed-off-by: Ravikiran Polepalli <ravikiran_polepalli@mentor.com>
|
||||
Signed-off-by: Mikhail Durnev <mikhail_durnev@mentor.com>
|
||||
Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_dmix.c | 33 +++++++++++++++++++++++----------
|
||||
1 file changed, 23 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -706,7 +706,7 @@ static snd_pcm_sframes_t snd_pcm_dmix_re
|
||||
{
|
||||
snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
snd_pcm_uframes_t slave_appl_ptr, slave_size;
|
||||
- snd_pcm_uframes_t appl_ptr, size, transfer, result;
|
||||
+ snd_pcm_uframes_t appl_ptr, size, transfer, result, frames_to_remix;
|
||||
int err;
|
||||
const snd_pcm_channel_area_t *src_areas, *dst_areas;
|
||||
|
||||
@@ -717,6 +717,13 @@ static snd_pcm_sframes_t snd_pcm_dmix_re
|
||||
return err;
|
||||
}
|
||||
|
||||
+ /* (appl_ptr - last_appl_ptr) indicates the frames which are not
|
||||
+ * already mixed
|
||||
+ * (last_appl_ptr - hw_ptr) indicates the frames which are already
|
||||
+ * mixed but not played yet.
|
||||
+ * So they can be remixed.
|
||||
+ */
|
||||
+
|
||||
if (dmix->last_appl_ptr < dmix->appl_ptr)
|
||||
size = dmix->appl_ptr - dmix->last_appl_ptr;
|
||||
else
|
||||
@@ -729,6 +736,9 @@ static snd_pcm_sframes_t snd_pcm_dmix_re
|
||||
return size;
|
||||
result = size;
|
||||
|
||||
+ /* Always at this point last_appl_ptr == appl_ptr
|
||||
+ * So (appl_ptr - hw_ptr) indicates the frames which can be remixed
|
||||
+ */
|
||||
if (dmix->hw_ptr < dmix->appl_ptr)
|
||||
size = dmix->appl_ptr - dmix->hw_ptr;
|
||||
else
|
||||
@@ -741,9 +751,12 @@ static snd_pcm_sframes_t snd_pcm_dmix_re
|
||||
slave_size = dmix->slave_appl_ptr + (pcm->boundary - dmix->slave_hw_ptr);
|
||||
if (slave_size < size)
|
||||
size = slave_size;
|
||||
- frames -= size;
|
||||
- result += size;
|
||||
-
|
||||
+
|
||||
+ /* frames which should be remixed will be saved
|
||||
+ * to also backward the appl pointer on success
|
||||
+ */
|
||||
+ frames_to_remix = size;
|
||||
+
|
||||
/* add sample areas here */
|
||||
src_areas = snd_pcm_mmap_areas(pcm);
|
||||
dst_areas = snd_pcm_mmap_areas(dmix->spcm);
|
||||
@@ -769,15 +782,15 @@ static snd_pcm_sframes_t snd_pcm_dmix_re
|
||||
appl_ptr += transfer;
|
||||
appl_ptr %= pcm->buffer_size;
|
||||
}
|
||||
- dmix->last_appl_ptr -= frames;
|
||||
- dmix->last_appl_ptr %= pcm->boundary;
|
||||
- dmix->slave_appl_ptr -= frames;
|
||||
- dmix->slave_appl_ptr %= dmix->slave_boundary;
|
||||
dmix_up_sem(dmix);
|
||||
|
||||
- snd_pcm_mmap_appl_backward(pcm, frames);
|
||||
+ snd_pcm_mmap_appl_backward(pcm, frames_to_remix);
|
||||
+ result += frames_to_remix;
|
||||
+ /* At this point last_appl_ptr and appl_ptr has to indicate the
|
||||
+ * position of the first not mixed frame
|
||||
+ */
|
||||
|
||||
- return result + frames;
|
||||
+ return result;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_dmix_forwardable(snd_pcm_t *pcm)
|
97
0027-pcm-direct-fix-race-on-clearing-timer-events.patch
Normal file
97
0027-pcm-direct-fix-race-on-clearing-timer-events.patch
Normal file
@ -0,0 +1,97 @@
|
||||
From 9219034301a3bf3d8de57ac5672bbc1c53f18049 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Fri, 17 Feb 2017 12:45:56 +0530
|
||||
Subject: [PATCH 27/43] pcm: direct: fix race on clearing timer events
|
||||
|
||||
snd_timer handling is racy: plugins clear timer queue if avail_min
|
||||
is not reached to force a sleep on timer. The race can happen if
|
||||
the expected event arrives in between the avail check and the
|
||||
clearing of pending events. If this race happens, the user will
|
||||
unnecessarily wait for one more timer event. On low latency/realtime
|
||||
streams this can lead to xruns and must be avoided.
|
||||
|
||||
As a fix we recheck avail after having cleared poll events.
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
|
||||
Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_direct.c | 23 +++++++++++++++++++----
|
||||
src/pcm/pcm_direct.h | 2 +-
|
||||
2 files changed, 20 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_direct.c
|
||||
+++ b/src/pcm/pcm_direct.c
|
||||
@@ -515,10 +515,12 @@ int snd_pcm_direct_async(snd_pcm_t *pcm,
|
||||
}
|
||||
|
||||
/* empty the timer read queue */
|
||||
-void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix)
|
||||
+int snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix)
|
||||
{
|
||||
+ int changed = 0;
|
||||
if (dmix->timer_need_poll) {
|
||||
while (poll(&dmix->timer_fd, 1, 0) > 0) {
|
||||
+ changed++;
|
||||
/* we don't need the value */
|
||||
if (dmix->tread) {
|
||||
snd_timer_tread_t rbuf[4];
|
||||
@@ -533,15 +535,17 @@ void snd_pcm_direct_clear_timer_queue(sn
|
||||
snd_timer_tread_t rbuf[4];
|
||||
int len;
|
||||
while ((len = snd_timer_read(dmix->timer, rbuf,
|
||||
- sizeof(rbuf))) > 0 &&
|
||||
+ sizeof(rbuf))) > 0
|
||||
+ && (++changed) &&
|
||||
len != sizeof(rbuf[0]))
|
||||
;
|
||||
} else {
|
||||
snd_timer_read_t rbuf;
|
||||
while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) > 0)
|
||||
- ;
|
||||
+ changed++;
|
||||
}
|
||||
}
|
||||
+ return changed;
|
||||
}
|
||||
|
||||
int snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix)
|
||||
@@ -693,6 +697,8 @@ int snd_pcm_direct_poll_revents(snd_pcm_
|
||||
int empty = 0;
|
||||
|
||||
assert(pfds && nfds == 1 && revents);
|
||||
+
|
||||
+timer_changed:
|
||||
events = pfds[0].revents;
|
||||
if (events & POLLIN) {
|
||||
snd_pcm_uframes_t avail;
|
||||
@@ -720,7 +726,16 @@ int snd_pcm_direct_poll_revents(snd_pcm_
|
||||
break;
|
||||
default:
|
||||
if (empty) {
|
||||
- snd_pcm_direct_clear_timer_queue(dmix);
|
||||
+ /* here we have a race condition:
|
||||
+ * if period event arrived after the avail_update call
|
||||
+ * above we might clear this event with the following
|
||||
+ * clear_timer_queue.
|
||||
+ * There is no way to do this in atomic manner, so we
|
||||
+ * need to recheck avail_update if we successfully
|
||||
+ * cleared a poll event.
|
||||
+ */
|
||||
+ if (snd_pcm_direct_clear_timer_queue(dmix))
|
||||
+ goto timer_changed;
|
||||
events &= ~(POLLOUT|POLLIN);
|
||||
/* additional check */
|
||||
switch (__snd_pcm_state(pcm)) {
|
||||
--- a/src/pcm/pcm_direct.h
|
||||
+++ b/src/pcm/pcm_direct.h
|
||||
@@ -322,7 +322,7 @@ int snd_pcm_direct_munmap(snd_pcm_t *pcm
|
||||
int snd_pcm_direct_prepare(snd_pcm_t *pcm);
|
||||
int snd_pcm_direct_resume(snd_pcm_t *pcm);
|
||||
int snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix);
|
||||
-void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix);
|
||||
+int snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix);
|
||||
int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix);
|
||||
int snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dmix, const char *client_name);
|
||||
|
77
0028-pcm-file-Enable-file-writing-for-capture-path.patch
Normal file
77
0028-pcm-file-Enable-file-writing-for-capture-path.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From fe65b00f337dd08f8c14d54b0ce6b516424d78e8 Mon Sep 17 00:00:00 2001
|
||||
From: Timo Wischer <twischer@de.adit-jv.com>
|
||||
Date: Fri, 17 Feb 2017 12:47:17 +0530
|
||||
Subject: [PATCH 28/43] pcm: file: Enable file writing for capture path
|
||||
|
||||
This commit reverts parts of commit 4081be0b87ab9fa53a8906e66bc240f18a7a9a54,
|
||||
because it is realy useful to use the file plugin in a capture path for
|
||||
debugging. Also it fixes the truncate issue mentioned in above commit.
|
||||
|
||||
Additionally following MMAP access issue is considered:
|
||||
$ arecord -D teeraw -M -d5 arecord.wav
|
||||
Recording WAVE 'arecord.wav' : Unsigned 8 bit, Rate 8000 Hz, Mono
|
||||
ALSA lib pcm/pcm_file.c:358:(snd_pcm_file_write_bytes)
|
||||
write failed: Bad file descriptor
|
||||
ALSA lib pcm/pcm_file.c:358:(snd_pcm_file_write_bytes)
|
||||
write failed: Bad file descriptor
|
||||
arecord: pcm/pcm_file.c:397: snd_pcm_file_add_frames:
|
||||
Assertion `file->wbuf_used_bytes < file->wbuf_size_bytes' failed.
|
||||
Aborted by signal Aborted...
|
||||
|
||||
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
|
||||
Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_file.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_file.c
|
||||
+++ b/src/pcm/pcm_file.c
|
||||
@@ -544,6 +544,7 @@ static snd_pcm_sframes_t snd_pcm_file_wr
|
||||
static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
+ snd_pcm_channel_area_t areas[pcm->channels];
|
||||
snd_pcm_sframes_t n;
|
||||
|
||||
n = _snd_pcm_readi(file->gen.slave, buffer, size);
|
||||
@@ -555,8 +556,10 @@ static snd_pcm_sframes_t snd_pcm_file_re
|
||||
__snd_pcm_unlock(pcm);
|
||||
if (n < 0)
|
||||
return n;
|
||||
- return n * 8 / pcm->frame_bits;
|
||||
+ n = n * 8 / pcm->frame_bits;
|
||||
}
|
||||
+ snd_pcm_areas_from_buf(pcm, areas, buffer);
|
||||
+ snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -564,6 +567,7 @@ static snd_pcm_sframes_t snd_pcm_file_re
|
||||
static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
|
||||
{
|
||||
snd_pcm_file_t *file = pcm->private_data;
|
||||
+ snd_pcm_channel_area_t areas[pcm->channels];
|
||||
snd_pcm_sframes_t n;
|
||||
|
||||
if (file->ifd >= 0) {
|
||||
@@ -572,6 +576,10 @@ static snd_pcm_sframes_t snd_pcm_file_re
|
||||
}
|
||||
|
||||
n = _snd_pcm_readn(file->gen.slave, bufs, size);
|
||||
+ if (n > 0) {
|
||||
+ snd_pcm_areas_from_bufs(pcm, areas, bufs);
|
||||
+ snd_pcm_file_add_frames(pcm, areas, 0, n);
|
||||
+ }
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -635,7 +643,7 @@ static int snd_pcm_file_hw_params(snd_pc
|
||||
a->first = slave->sample_bits * channel;
|
||||
a->step = slave->frame_bits;
|
||||
}
|
||||
- if ((file->fd < 0) && (pcm->stream == SND_PCM_STREAM_PLAYBACK)) {
|
||||
+ if (file->fd < 0) {
|
||||
err = snd_pcm_file_open_output_file(file);
|
||||
if (err < 0) {
|
||||
SYSERR("failed opening output file %s", file->fname);
|
42
0029-pcm-status-dump-fix-timestamp-formatting.patch
Normal file
42
0029-pcm-status-dump-fix-timestamp-formatting.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From a50496346f39e91ecd42cb09bc5c95321131be55 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Fri, 17 Feb 2017 12:47:36 +0530
|
||||
Subject: [PATCH 29/43] pcm: status dump fix timestamp formatting
|
||||
|
||||
nanosecond part formatted with %06 will give incorrect/confusing results:
|
||||
|
||||
trigger_time: 154.9748287
|
||||
trigger_time: 154.60109090
|
||||
trigger_time: 154.110425257
|
||||
|
||||
time seems to run backwards...
|
||||
|
||||
This patch converts to us before printing
|
||||
which gives the correct/expected result:
|
||||
|
||||
trigger_time: 154.009748
|
||||
trigger_time: 154.060109
|
||||
trigger_time: 154.110425
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm.c
|
||||
+++ b/src/pcm/pcm.c
|
||||
@@ -2194,9 +2194,10 @@ int snd_pcm_status_dump(snd_pcm_status_t
|
||||
assert(status);
|
||||
snd_output_printf(out, " state : %s\n", snd_pcm_state_name((snd_pcm_state_t) status->state));
|
||||
snd_output_printf(out, " trigger_time: %ld.%06ld\n",
|
||||
- status->trigger_tstamp.tv_sec, status->trigger_tstamp.tv_nsec);
|
||||
+ status->trigger_tstamp.tv_sec,
|
||||
+ status->trigger_tstamp.tv_nsec / 1000);
|
||||
snd_output_printf(out, " tstamp : %ld.%06ld\n",
|
||||
- status->tstamp.tv_sec, status->tstamp.tv_nsec);
|
||||
+ status->tstamp.tv_sec, status->tstamp.tv_nsec / 1000);
|
||||
snd_output_printf(out, " delay : %ld\n", (long)status->delay);
|
||||
snd_output_printf(out, " avail : %ld\n", (long)status->avail);
|
||||
snd_output_printf(out, " avail_max : %ld\n", (long)status->avail_max);
|
27
0030-pcm-extplug-refinement-of-masks-in-extplug.patch
Normal file
27
0030-pcm-extplug-refinement-of-masks-in-extplug.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From fbb957138135e09ed9fd0180dcad549aad815465 Mon Sep 17 00:00:00 2001
|
||||
From: Awais Belal <awais_belal@mentor.com>
|
||||
Date: Fri, 17 Feb 2017 12:47:49 +0530
|
||||
Subject: [PATCH 30/43] pcm: extplug: refinement of masks in extplug
|
||||
|
||||
It should be possible to use empty mask format with extplug.
|
||||
The refinement of mask via extplug is now modified,
|
||||
to accept empty masks as well to work properly.
|
||||
|
||||
Signed-off-by: Awais Belal <awais_belal@mentor.com>
|
||||
Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_extplug.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/src/pcm/pcm_extplug.c
|
||||
+++ b/src/pcm/pcm_extplug.c
|
||||
@@ -172,6 +172,8 @@ int snd_ext_parm_mask_refine(snd_mask_t
|
||||
unsigned int i;
|
||||
|
||||
parm += type;
|
||||
+ if (!parm->active)
|
||||
+ return 0;
|
||||
memset(&bits, 0, sizeof(bits));
|
||||
for (i = 0; i < parm->num_list; i++)
|
||||
bits.bits[parm->list[i] / 32] |= 1U << (parm->list[i] % 32);
|
185
0031-pcm-rate-Add-capability-to-pass-configuration-node-t.patch
Normal file
185
0031-pcm-rate-Add-capability-to-pass-configuration-node-t.patch
Normal file
@ -0,0 +1,185 @@
|
||||
From 97be19cf6f44fc5084828114c53281dff6e365b4 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Young <consult.awy@gmail.com>
|
||||
Date: Thu, 7 Apr 2016 09:15:04 +0100
|
||||
Subject: [PATCH 31/43] pcm: rate: Add capability to pass configuration node to
|
||||
plugins
|
||||
|
||||
If a rate plugin uses a node (compound) instead of a plain string for
|
||||
its "converter", and that compound is not a simple string array, then
|
||||
the compound will be passed as an additional parameter to the new plugin
|
||||
open() function (SND_PCM_RATE_PLUGIN_CONF_ENTRY(XXX)). The previous
|
||||
open() function (SND_PCM_RATE_PLUGIN_ENTRY(XXX)) will be called if the
|
||||
CONF version is not found. It is up to the plugin to determine whether
|
||||
the presence of the conf parameter is mandatory.
|
||||
|
||||
Signed-off-by: Alan Young <consult.awy@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
include/pcm_rate.h | 5 ++-
|
||||
src/pcm/pcm_rate.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
2 files changed, 82 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/include/pcm_rate.h
|
||||
+++ b/include/pcm_rate.h
|
||||
@@ -120,11 +120,14 @@ typedef struct snd_pcm_rate_ops {
|
||||
typedef int (*snd_pcm_rate_open_func_t)(unsigned int version, void **objp,
|
||||
snd_pcm_rate_ops_t *opsp);
|
||||
|
||||
+typedef int (*snd_pcm_rate_open_conf_func_t)(unsigned int version, void **objp,
|
||||
+ snd_pcm_rate_ops_t *opsp, const snd_config_t *conf);
|
||||
+
|
||||
/**
|
||||
* Define the object entry for external PCM rate-converter plugins
|
||||
*/
|
||||
#define SND_PCM_RATE_PLUGIN_ENTRY(name) _snd_pcm_rate_##name##_open
|
||||
-
|
||||
+#define SND_PCM_RATE_PLUGIN_CONF_ENTRY(name) _snd_pcm_rate_##name##_open_conf
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
/* old rate_ops for protocol version 0x010001 */
|
||||
--- a/src/pcm/pcm_rate.c
|
||||
+++ b/src/pcm/pcm_rate.c
|
||||
@@ -1258,26 +1258,48 @@ static const char *const default_rate_pl
|
||||
"speexrate", "linear", NULL
|
||||
};
|
||||
|
||||
-static int rate_open_func(snd_pcm_rate_t *rate, const char *type, int verbose)
|
||||
+static int rate_open_func(snd_pcm_rate_t *rate, const char *type, const snd_config_t *converter_conf, int verbose)
|
||||
{
|
||||
- char open_name[64], lib_name[128], *lib = NULL;
|
||||
+ char open_name[64], open_conf_name[64], lib_name[128], *lib = NULL;
|
||||
snd_pcm_rate_open_func_t open_func;
|
||||
+ snd_pcm_rate_open_conf_func_t open_conf_func;
|
||||
int err;
|
||||
|
||||
snprintf(open_name, sizeof(open_name), "_snd_pcm_rate_%s_open", type);
|
||||
+ snprintf(open_conf_name, sizeof(open_conf_name), "_snd_pcm_rate_%s_open_conf", type);
|
||||
if (!is_builtin_plugin(type)) {
|
||||
snprintf(lib_name, sizeof(lib_name),
|
||||
"%s/libasound_module_rate_%s.so", ALSA_PLUGIN_DIR, type);
|
||||
lib = lib_name;
|
||||
}
|
||||
+
|
||||
+ rate->rate_min = SND_PCM_PLUGIN_RATE_MIN;
|
||||
+ rate->rate_max = SND_PCM_PLUGIN_RATE_MAX;
|
||||
+ rate->plugin_version = SND_PCM_RATE_PLUGIN_VERSION;
|
||||
+
|
||||
+ open_conf_func = snd_dlobj_cache_get(lib, open_conf_name, NULL, verbose && converter_conf != NULL);
|
||||
+ if (open_conf_func) {
|
||||
+ err = open_conf_func(SND_PCM_RATE_PLUGIN_VERSION,
|
||||
+ &rate->obj, &rate->ops, converter_conf);
|
||||
+ if (!err) {
|
||||
+ rate->plugin_version = rate->ops.version;
|
||||
+ if (rate->ops.get_supported_rates)
|
||||
+ rate->ops.get_supported_rates(rate->obj,
|
||||
+ &rate->rate_min,
|
||||
+ &rate->rate_max);
|
||||
+ rate->open_func = open_conf_func;
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ snd_dlobj_cache_put(open_conf_func);
|
||||
+ return err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
open_func = snd_dlobj_cache_get(lib, open_name, NULL, verbose);
|
||||
if (!open_func)
|
||||
return -ENOENT;
|
||||
|
||||
rate->open_func = open_func;
|
||||
- rate->rate_min = SND_PCM_PLUGIN_RATE_MIN;
|
||||
- rate->rate_max = SND_PCM_PLUGIN_RATE_MAX;
|
||||
- rate->plugin_version = SND_PCM_RATE_PLUGIN_VERSION;
|
||||
|
||||
err = open_func(SND_PCM_RATE_PLUGIN_VERSION, &rate->obj, &rate->ops);
|
||||
if (!err) {
|
||||
@@ -1301,6 +1323,30 @@ static int rate_open_func(snd_pcm_rate_t
|
||||
}
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * If the conf is an array of alternatives then the id of
|
||||
+ * the first element will be "0" (or maybe NULL). Otherwise assume it is
|
||||
+ * a structure.
|
||||
+ */
|
||||
+static int is_string_array(const snd_config_t *conf)
|
||||
+{
|
||||
+ snd_config_iterator_t i;
|
||||
+
|
||||
+ if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND)
|
||||
+ return 0;
|
||||
+
|
||||
+ i = snd_config_iterator_first(conf);
|
||||
+ if (i && i != snd_config_iterator_end(conf)) {
|
||||
+ snd_config_t *n = snd_config_iterator_entry(i);
|
||||
+ const char *id;
|
||||
+ snd_config_get_id(n, &id);
|
||||
+ if (id && strcmp(id, "0") != 0)
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* \brief Creates a new rate PCM
|
||||
* \param pcmp Returns created PCM handle
|
||||
@@ -1353,24 +1399,42 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp,
|
||||
if (!converter) {
|
||||
const char *const *types;
|
||||
for (types = default_rate_plugins; *types; types++) {
|
||||
- err = rate_open_func(rate, *types, 0);
|
||||
+ err = rate_open_func(rate, *types, NULL, 0);
|
||||
if (!err) {
|
||||
type = *types;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!snd_config_get_string(converter, &type))
|
||||
- err = rate_open_func(rate, type, 1);
|
||||
- else if (snd_config_get_type(converter) == SND_CONFIG_TYPE_COMPOUND) {
|
||||
+ err = rate_open_func(rate, type, NULL, 1);
|
||||
+ else if (is_string_array(converter)) {
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_for_each(i, next, converter) {
|
||||
snd_config_t *n = snd_config_iterator_entry(i);
|
||||
if (snd_config_get_string(n, &type) < 0)
|
||||
break;
|
||||
- err = rate_open_func(rate, type, 0);
|
||||
+ err = rate_open_func(rate, type, NULL, 0);
|
||||
if (!err)
|
||||
break;
|
||||
}
|
||||
+ } else if (snd_config_get_type(converter) == SND_CONFIG_TYPE_COMPOUND) {
|
||||
+ snd_config_iterator_t i, next;
|
||||
+ snd_config_for_each(i, next, converter) {
|
||||
+ snd_config_t *n = snd_config_iterator_entry(i);
|
||||
+ const char *id;
|
||||
+ snd_config_get_id(n, &id);
|
||||
+ if (strcmp(id, "name") != 0)
|
||||
+ continue;
|
||||
+ snd_config_get_string(n, &type);
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!type) {
|
||||
+ SNDERR("No name given for rate converter");
|
||||
+ snd_pcm_free(pcm);
|
||||
+ free(rate);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ err = rate_open_func(rate, type, converter, 1);
|
||||
} else {
|
||||
SNDERR("Invalid type for rate converter");
|
||||
snd_pcm_free(pcm);
|
||||
@@ -1439,6 +1503,11 @@ pcm.name {
|
||||
converter [ STR1 STR2 ... ] # optional
|
||||
# Converter type, default is taken from
|
||||
# defaults.pcm.rate_converter
|
||||
+ # or
|
||||
+ converter { # optional
|
||||
+ name STR # Convertor type
|
||||
+ xxx yyy # optional convertor-specific configuration
|
||||
+ }
|
||||
}
|
||||
\endcode
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 3bad0a21b4d13d8d10691f382c836897fa7a7cb9 Mon Sep 17 00:00:00 2001
|
||||
From: Breno Leitao <leitao@debian.org>
|
||||
Date: Wed, 22 Feb 2017 16:45:00 -0300
|
||||
Subject: [PATCH 32/43] Drop ppc64-specific workaround for versioned symbols
|
||||
|
||||
Currently aserver fails to build when using parameter
|
||||
--without-versioned, due to an workaround for ppc64
|
||||
(06221f86d207cb33ddd4867ca5301eeb247c4400). This workaround is
|
||||
not required anymore on the ppc64 ABI v2, and, in fact is breaking the
|
||||
compilation. Reverting this commit
|
||||
|
||||
Signed-off-by: Breno Leitao <leitao@debian.org>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
include/alsa-symbols.h | 17 -----------------
|
||||
1 file changed, 17 deletions(-)
|
||||
|
||||
--- a/include/alsa-symbols.h
|
||||
+++ b/include/alsa-symbols.h
|
||||
@@ -29,19 +29,10 @@
|
||||
#define INTERNAL_CONCAT2_2(Pre, Post) Pre##Post
|
||||
#define INTERNAL(Name) INTERNAL_CONCAT2_2(__, Name)
|
||||
|
||||
-#ifdef __powerpc64__
|
||||
-# define symbol_version(real, name, version) \
|
||||
- __asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@" #version); \
|
||||
- __asm__ (".symver ." ASM_NAME(#real) ",." ASM_NAME(#name) "@" #version)
|
||||
-# define default_symbol_version(real, name, version) \
|
||||
- __asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@@" #version); \
|
||||
- __asm__ (".symver ." ASM_NAME(#real) ",." ASM_NAME(#name) "@@" #version)
|
||||
-#else
|
||||
# define symbol_version(real, name, version) \
|
||||
__asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@" #version)
|
||||
# define default_symbol_version(real, name, version) \
|
||||
__asm__ (".symver " ASM_NAME(#real) "," ASM_NAME(#name) "@@" #version)
|
||||
-#endif
|
||||
|
||||
#ifdef USE_VERSIONED_SYMBOLS
|
||||
#define use_symbol_version(real, name, version) \
|
||||
@@ -50,13 +41,6 @@
|
||||
default_symbol_version(real, name, version)
|
||||
#else
|
||||
#define use_symbol_version(real, name, version) /* nothing */
|
||||
-#ifdef __powerpc64__
|
||||
-#define use_default_symbol_version(real, name, version) \
|
||||
- __asm__ (".weak " ASM_NAME(#name)); \
|
||||
- __asm__ (".weak ." ASM_NAME(#name)); \
|
||||
- __asm__ (".set " ASM_NAME(#name) "," ASM_NAME(#real)); \
|
||||
- __asm__ (".set ." ASM_NAME(#name) ",." ASM_NAME(#real))
|
||||
-#else
|
||||
#if defined(__alpha__) || defined(__mips__)
|
||||
#define use_default_symbol_version(real, name, version) \
|
||||
__asm__ (".weak " ASM_NAME(#name)); \
|
||||
@@ -67,6 +51,5 @@
|
||||
__asm__ (".set " ASM_NAME(#name) "," ASM_NAME(#real))
|
||||
#endif
|
||||
#endif
|
||||
-#endif
|
||||
|
||||
#endif /* __ALSA_SYMBOLS_H */
|
@ -0,0 +1,68 @@
|
||||
From b0e4652881f883023d2b190cf3897b7494d8d0ed Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 27 Feb 2017 09:25:24 +0100
|
||||
Subject: [PATCH 33/43] pcm_plugin: unify the snd_pcm_mmap_begin result value
|
||||
checking
|
||||
|
||||
---
|
||||
src/pcm/pcm_plugin.c | 26 +++++++++++++++++++-------
|
||||
1 file changed, 19 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_plugin.c
|
||||
+++ b/src/pcm/pcm_plugin.c
|
||||
@@ -251,8 +251,12 @@ static snd_pcm_sframes_t snd_pcm_plugin_
|
||||
snd_pcm_uframes_t slave_offset;
|
||||
snd_pcm_uframes_t slave_frames = ULONG_MAX;
|
||||
|
||||
- err = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
- if (err < 0 || slave_frames == 0)
|
||||
+ result = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
+ if (result < 0) {
|
||||
+ err = result;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ if (slave_frames == 0)
|
||||
break;
|
||||
frames = plugin->write(pcm, areas, offset, frames,
|
||||
slave_areas, slave_offset, &slave_frames);
|
||||
@@ -304,7 +308,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_
|
||||
snd_pcm_uframes_t slave_offset;
|
||||
snd_pcm_uframes_t slave_frames = ULONG_MAX;
|
||||
|
||||
- snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
+ result = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
+ if (result < 0) {
|
||||
+ err = result;
|
||||
+ goto error;
|
||||
+ }
|
||||
if (slave_frames == 0)
|
||||
break;
|
||||
frames = (plugin->read)(pcm, areas, offset, frames,
|
||||
@@ -409,9 +417,11 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pc
|
||||
snd_pcm_uframes_t slave_frames = ULONG_MAX;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
- err = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
- if (err < 0)
|
||||
+ result = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
+ if (result < 0) {
|
||||
+ err = result;
|
||||
goto error;
|
||||
+ }
|
||||
if (frames > cont)
|
||||
frames = cont;
|
||||
frames = plugin->write(pcm, areas, appl_offset, frames,
|
||||
@@ -481,9 +491,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_
|
||||
snd_pcm_uframes_t slave_frames = ULONG_MAX;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
- err = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
- if (err < 0)
|
||||
+ result = snd_pcm_mmap_begin(slave, &slave_areas, &slave_offset, &slave_frames);
|
||||
+ if (result < 0) {
|
||||
+ err = result;
|
||||
goto error;
|
||||
+ }
|
||||
if (frames > cont)
|
||||
frames = cont;
|
||||
frames = (plugin->read)(pcm, areas, hw_offset, frames,
|
@ -0,0 +1,46 @@
|
||||
From 8a38461fac67f6542308063ba8e9887a1a2fa84e Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 27 Feb 2017 09:26:33 +0100
|
||||
Subject: [PATCH 34/43] always handle return value from snd_config_get_id()
|
||||
(coverity)
|
||||
|
||||
---
|
||||
src/pcm/pcm_rate.c | 6 ++++--
|
||||
src/topology/data.c | 4 ++--
|
||||
2 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_rate.c
|
||||
+++ b/src/pcm/pcm_rate.c
|
||||
@@ -1339,7 +1339,8 @@ static int is_string_array(const snd_con
|
||||
if (i && i != snd_config_iterator_end(conf)) {
|
||||
snd_config_t *n = snd_config_iterator_entry(i);
|
||||
const char *id;
|
||||
- snd_config_get_id(n, &id);
|
||||
+ if (snd_config_get_id(n, &id) < 0)
|
||||
+ return 0;
|
||||
if (id && strcmp(id, "0") != 0)
|
||||
return 0;
|
||||
}
|
||||
@@ -1422,7 +1423,8 @@ int snd_pcm_rate_open(snd_pcm_t **pcmp,
|
||||
snd_config_for_each(i, next, converter) {
|
||||
snd_config_t *n = snd_config_iterator_entry(i);
|
||||
const char *id;
|
||||
- snd_config_get_id(n, &id);
|
||||
+ if (snd_config_get_id(n, &id) < 0)
|
||||
+ continue;
|
||||
if (strcmp(id, "name") != 0)
|
||||
continue;
|
||||
snd_config_get_string(n, &type);
|
||||
--- a/src/topology/data.c
|
||||
+++ b/src/topology/data.c
|
||||
@@ -653,8 +653,8 @@ static int parse_tuple_sets(snd_config_t
|
||||
int err;
|
||||
|
||||
if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
|
||||
- snd_config_get_id(cfg, &id);
|
||||
- SNDERR("error: compound type expected for %s", id);
|
||||
+ if (snd_config_get_id(cfg, &id) >= 0)
|
||||
+ SNDERR("error: compound type expected for %s", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
From b96f6f47852aa145645fb8626d009ec532246e55 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 27 Feb 2017 09:29:18 +0100
|
||||
Subject: [PATCH 35/43] pcm file plugin: handle snd_pcm_mmap_begin() error path
|
||||
in snd_pcm_file_mmap_commit()
|
||||
|
||||
---
|
||||
src/pcm/pcm_file.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_file.c
|
||||
+++ b/src/pcm/pcm_file.c
|
||||
@@ -593,11 +593,13 @@ static snd_pcm_sframes_t snd_pcm_file_mm
|
||||
const snd_pcm_channel_area_t *areas;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
- snd_pcm_mmap_begin(file->gen.slave, &areas, &ofs, &siz);
|
||||
- assert(ofs == offset && siz == size);
|
||||
- result = snd_pcm_mmap_commit(file->gen.slave, ofs, siz);
|
||||
- if (result > 0)
|
||||
- snd_pcm_file_add_frames(pcm, areas, ofs, result);
|
||||
+ result = snd_pcm_mmap_begin(file->gen.slave, &areas, &ofs, &siz);
|
||||
+ if (result >= 0) {
|
||||
+ assert(ofs == offset && siz == size);
|
||||
+ result = snd_pcm_mmap_commit(file->gen.slave, ofs, siz);
|
||||
+ if (result > 0)
|
||||
+ snd_pcm_file_add_frames(pcm, areas, ofs, result);
|
||||
+ }
|
||||
return result;
|
||||
}
|
||||
|
83
0036-topology-coverity-remove-dead-code.patch
Normal file
83
0036-topology-coverity-remove-dead-code.patch
Normal file
@ -0,0 +1,83 @@
|
||||
From db0e1dcfc22fb2e408a12993cda2d604e0fb10f8 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 27 Feb 2017 09:46:18 +0100
|
||||
Subject: [PATCH 36/43] topology: coverity - remove dead code
|
||||
|
||||
---
|
||||
src/topology/ctl.c | 5 ++---
|
||||
src/topology/data.c | 2 +-
|
||||
src/topology/pcm.c | 17 +++++++----------
|
||||
3 files changed, 10 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/src/topology/ctl.c
|
||||
+++ b/src/topology/ctl.c
|
||||
@@ -173,7 +173,7 @@ static int tplg_build_enum_control(snd_t
|
||||
{
|
||||
struct tplg_ref *ref;
|
||||
struct list_head *base, *pos;
|
||||
- int err = 0;
|
||||
+ int err;
|
||||
|
||||
base = &elem->ref_list;
|
||||
|
||||
@@ -198,8 +198,7 @@ static int tplg_build_enum_control(snd_t
|
||||
SNDERR("error: cannot find '%s' referenced by"
|
||||
" control '%s'\n", ref->id, elem->id);
|
||||
return -EINVAL;
|
||||
- } else if (err < 0)
|
||||
- return err;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
--- a/src/topology/data.c
|
||||
+++ b/src/topology/data.c
|
||||
@@ -917,7 +917,7 @@ int tplg_build_manifest_data(snd_tplg_t
|
||||
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) {
|
||||
--- a/src/topology/pcm.c
|
||||
+++ b/src/topology/pcm.c
|
||||
@@ -79,8 +79,8 @@ static int build_pcm(snd_tplg_t *tplg, s
|
||||
int err;
|
||||
|
||||
err = tplg_build_stream_caps(tplg, elem->id, elem->pcm->caps);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
|
||||
/* merge private data from the referenced data elements */
|
||||
base = &elem->ref_list;
|
||||
@@ -96,8 +96,7 @@ static int build_pcm(snd_tplg_t *tplg, s
|
||||
SNDERR("error: cannot find '%s' referenced by"
|
||||
" PCM '%s'\n", ref->id, elem->id);
|
||||
return -EINVAL;
|
||||
- } else if (err < 0)
|
||||
- return err;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1208,12 +1207,10 @@ int tplg_add_link_object(snd_tplg_t *tpl
|
||||
|
||||
/* ID and names */
|
||||
link->id = link_tpl->id;
|
||||
- if (link->name)
|
||||
- elem_copy_text(link->name, link_tpl->name,
|
||||
- SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
|
||||
- if (link->stream_name)
|
||||
- elem_copy_text(link->stream_name, link_tpl->stream_name,
|
||||
- SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
|
||||
+ elem_copy_text(link->name, link_tpl->name,
|
||||
+ SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
|
||||
+ elem_copy_text(link->stream_name, link_tpl->stream_name,
|
||||
+ SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
|
||||
|
||||
/* stream configs */
|
||||
if (link_tpl->num_streams > SND_SOC_TPLG_STREAM_CONFIG_MAX)
|
@ -0,0 +1,22 @@
|
||||
From ad188bbf7813eab6f42dcdf617aa947107118857 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 27 Feb 2017 09:53:26 +0100
|
||||
Subject: [PATCH 37/43] ucm parser: fix possible string overflow in
|
||||
uc_mgr_import_master_config()
|
||||
|
||||
---
|
||||
src/ucm/parser.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/ucm/parser.c
|
||||
+++ b/src/ucm/parser.c
|
||||
@@ -1453,7 +1453,8 @@ int uc_mgr_import_master_config(snd_use_
|
||||
err = load_master_config(uc_mgr->card_name, &cfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- strcpy(uc_mgr->conf_file_name, uc_mgr->card_name);
|
||||
+ strncpy(uc_mgr->conf_file_name, uc_mgr->card_name, MAX_CARD_LONG_NAME);
|
||||
+ uc_mgr->conf_file_name[MAX_CARD_LONG_NAME-1] = '\0';
|
||||
}
|
||||
|
||||
err = parse_master_file(uc_mgr, cfg);
|
68
0038-dmix-plugin-fix-drain-for-nonblock-mode.patch
Normal file
68
0038-dmix-plugin-fix-drain-for-nonblock-mode.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From fdc898d41135b26772d0fffe07e9eb0de6597125 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 20 Mar 2017 08:34:33 +0100
|
||||
Subject: [PATCH 38/43] dmix plugin: fix drain for nonblock mode
|
||||
|
||||
---
|
||||
src/pcm/pcm_dmix.c | 24 ++++++++++++++++--------
|
||||
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -628,7 +628,7 @@ static int __snd_pcm_dmix_drain(snd_pcm_
|
||||
{
|
||||
snd_pcm_direct_t *dmix = pcm->private_data;
|
||||
snd_pcm_uframes_t stop_threshold;
|
||||
- int err;
|
||||
+ int err = 0;
|
||||
|
||||
switch (snd_pcm_state(dmix->spcm)) {
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
@@ -639,8 +639,6 @@ static int __snd_pcm_dmix_drain(snd_pcm_
|
||||
|
||||
if (dmix->state == SND_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
- if (pcm->mode & SND_PCM_NONBLOCK)
|
||||
- return -EAGAIN;
|
||||
if (dmix->state == SND_PCM_STATE_PREPARED) {
|
||||
if (snd_pcm_mmap_playback_hw_avail(pcm) > 0)
|
||||
snd_pcm_dmix_start(pcm);
|
||||
@@ -663,23 +661,33 @@ static int __snd_pcm_dmix_drain(snd_pcm_
|
||||
err = snd_pcm_dmix_sync_ptr(pcm);
|
||||
if (err < 0) {
|
||||
snd_pcm_dmix_drop(pcm);
|
||||
- return err;
|
||||
+ goto done;
|
||||
}
|
||||
if (dmix->state == SND_PCM_STATE_DRAINING) {
|
||||
snd_pcm_dmix_sync_area(pcm);
|
||||
- snd_pcm_wait_nocheck(pcm, -1);
|
||||
- snd_pcm_direct_clear_timer_queue(dmix); /* force poll to wait */
|
||||
+ if ((pcm->mode & SND_PCM_NONBLOCK) == 0) {
|
||||
+ snd_pcm_wait_nocheck(pcm, -1);
|
||||
+ snd_pcm_direct_clear_timer_queue(dmix); /* force poll to wait */
|
||||
+ }
|
||||
|
||||
switch (snd_pcm_state(dmix->spcm)) {
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
- return -ESTRPIPE;
|
||||
+ err = -ESTRPIPE;
|
||||
+ goto done;
|
||||
+ case SND_PCM_STATE_DRAINING:
|
||||
+ if (pcm->mode & SND_PCM_NONBLOCK) {
|
||||
+ err = -EAGAIN;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (dmix->state == SND_PCM_STATE_DRAINING);
|
||||
+done:
|
||||
pcm->stop_threshold = stop_threshold;
|
||||
- return 0;
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int snd_pcm_dmix_drain(snd_pcm_t *pcm)
|
34
0039-dmix-plugin-drain-quickfix-for-the-previous-patch.patch
Normal file
34
0039-dmix-plugin-drain-quickfix-for-the-previous-patch.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From e4377b16454f3b7b222613a571bf4244ebd28e56 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 20 Mar 2017 08:41:53 +0100
|
||||
Subject: [PATCH 39/43] dmix plugin: drain - quickfix for the previous patch
|
||||
|
||||
---
|
||||
src/pcm/pcm_dmix.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_dmix.c
|
||||
+++ b/src/pcm/pcm_dmix.c
|
||||
@@ -674,16 +674,16 @@ static int __snd_pcm_dmix_drain(snd_pcm_
|
||||
case SND_PCM_STATE_SUSPENDED:
|
||||
err = -ESTRPIPE;
|
||||
goto done;
|
||||
- case SND_PCM_STATE_DRAINING:
|
||||
- if (pcm->mode & SND_PCM_NONBLOCK) {
|
||||
- err = -EAGAIN;
|
||||
- goto done;
|
||||
- }
|
||||
- break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
+ if (pcm->mode & SND_PCM_NONBLOCK) {
|
||||
+ if (dmix->state == SND_PCM_STATE_DRAINING) {
|
||||
+ err = -EAGAIN;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
} while (dmix->state == SND_PCM_STATE_DRAINING);
|
||||
done:
|
||||
pcm->stop_threshold = stop_threshold;
|
28
0040-rawmidi-virtual-fix-reading-into-a-small-buffer.patch
Normal file
28
0040-rawmidi-virtual-fix-reading-into-a-small-buffer.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From d71f294566e53c967a6a1e2d5c684499ec390d69 Mon Sep 17 00:00:00 2001
|
||||
From: Clemens Ladisch <clemens@ladisch.de>
|
||||
Date: Sat, 18 Mar 2017 23:10:33 +0100
|
||||
Subject: [PATCH 40/43] rawmidi: virtual: fix reading into a small buffer
|
||||
|
||||
In the special case for handling partial messages, the pointer
|
||||
calculations were wrong, which would result in data corruption.
|
||||
|
||||
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
|
||||
Reviewd-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/rawmidi/rawmidi_virt.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/rawmidi/rawmidi_virt.c
|
||||
+++ b/src/rawmidi/rawmidi_virt.c
|
||||
@@ -263,8 +263,8 @@ static ssize_t snd_rawmidi_virtual_read(
|
||||
}
|
||||
size1 = virt->in_buf_size - virt->in_buf_ofs;
|
||||
if ((size_t)size1 > size) {
|
||||
- virt->in_buf_ofs += size1 - size;
|
||||
- memcpy(buffer, virt->in_buf_ptr, size);
|
||||
+ memcpy(buffer, virt->in_buf_ptr + virt->in_buf_ofs, size);
|
||||
+ virt->in_buf_ofs += size;
|
||||
result += size;
|
||||
break;
|
||||
}
|
104
0041-conf-cards-add-VC4-HDMI-card.patch
Normal file
104
0041-conf-cards-add-VC4-HDMI-card.patch
Normal file
@ -0,0 +1,104 @@
|
||||
From 7c2093b1c136e0766116a0b88b565b99176aed19 Mon Sep 17 00:00:00 2001
|
||||
From: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
Date: Thu, 2 Mar 2017 11:49:33 +0100
|
||||
Subject: [PATCH 41/43] conf/cards: add VC4-HDMI card
|
||||
|
||||
Add a conf file for the VC4-HDMI sound card.
|
||||
|
||||
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
|
||||
Tested-by: Eric Anholt <eric@anholt.net>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/conf/cards/Makefile.am | 1
|
||||
src/conf/cards/aliases.conf | 1
|
||||
src/conf/cards/vc4-hdmi.conf | 64 +++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 66 insertions(+)
|
||||
create mode 100644 src/conf/cards/vc4-hdmi.conf
|
||||
|
||||
--- a/src/conf/cards/Makefile.am
|
||||
+++ b/src/conf/cards/Makefile.am
|
||||
@@ -51,6 +51,7 @@ cfg_files = aliases.conf \
|
||||
TRID4DWAVENX.conf \
|
||||
USB-Audio.conf \
|
||||
YMF744.conf \
|
||||
+ vc4-hdmi.conf \
|
||||
VIA686A.conf \
|
||||
VIA8233.conf \
|
||||
VIA8233A.conf \
|
||||
--- a/src/conf/cards/aliases.conf
|
||||
+++ b/src/conf/cards/aliases.conf
|
||||
@@ -56,6 +56,7 @@ AV200 cards.CMI8788
|
||||
CMI8786 cards.CMI8788
|
||||
CMI8787 cards.CMI8788
|
||||
pistachio cards.pistachio-card
|
||||
+VC4-HDMI cards.vc4-hdmi
|
||||
|
||||
<confdir:pcm/default.conf>
|
||||
<confdir:pcm/dmix.conf>
|
||||
--- /dev/null
|
||||
+++ b/src/conf/cards/vc4-hdmi.conf
|
||||
@@ -0,0 +1,64 @@
|
||||
+#
|
||||
+# Configuration for the VC4-HDMI sound card using software IEC958
|
||||
+# subframe conversion
|
||||
+#
|
||||
+
|
||||
+<confdir:pcm/front.conf>
|
||||
+
|
||||
+vc4-hdmi.pcm.front.0 {
|
||||
+ @args [ CARD ]
|
||||
+ @args.CARD {
|
||||
+ type string
|
||||
+ }
|
||||
+ type hw
|
||||
+ card $CARD
|
||||
+}
|
||||
+
|
||||
+# default with dmix
|
||||
+vc4-hdmi.pcm.default {
|
||||
+ @args [ CARD ]
|
||||
+ @args.CARD {
|
||||
+ type string
|
||||
+ }
|
||||
+ type asym
|
||||
+ playback.pcm {
|
||||
+ type plug
|
||||
+ slave.pcm {
|
||||
+ @func concat
|
||||
+ strings [ "dmix:" $CARD ]
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+<confdir:pcm/iec958.conf>
|
||||
+
|
||||
+vc4-hdmi.pcm.iec958.0 {
|
||||
+ @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 iec958
|
||||
+ slave {
|
||||
+ format IEC958_SUBFRAME_LE
|
||||
+ pcm {
|
||||
+ type plug
|
||||
+ slave.pcm {
|
||||
+ type hw
|
||||
+ card $CARD
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ status [ $AES0 $AES1 $AES2 $AES3 ]
|
||||
+}
|
63
0042-pcm-plug-save-converter-config.patch
Normal file
63
0042-pcm-plug-save-converter-config.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 653faa8991aa3460c42d9688ff83846807f3ad51 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Tue, 21 Mar 2017 18:28:18 +0530
|
||||
Subject: [PATCH 42/43] pcm:plug: save converter config
|
||||
|
||||
Passed config is freed after call to open, thus it is invalid when
|
||||
trying to extract the converter name. So config entry is saved
|
||||
for later usage.
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_plug.c | 16 ++++++++++++++--
|
||||
1 file changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/pcm/pcm_plug.c
|
||||
+++ b/src/pcm/pcm_plug.c
|
||||
@@ -50,7 +50,7 @@ typedef struct {
|
||||
snd_pcm_format_t sformat;
|
||||
int schannels;
|
||||
int srate;
|
||||
- const snd_config_t *rate_converter;
|
||||
+ snd_config_t *rate_converter;
|
||||
enum snd_pcm_plug_route_policy route_policy;
|
||||
snd_pcm_route_ttable_entry_t *ttable;
|
||||
int ttable_ok;
|
||||
@@ -64,6 +64,10 @@ static int snd_pcm_plug_close(snd_pcm_t
|
||||
snd_pcm_plug_t *plug = pcm->private_data;
|
||||
int err, result = 0;
|
||||
free(plug->ttable);
|
||||
+ if (plug->rate_converter) {
|
||||
+ snd_config_delete(plug->rate_converter);
|
||||
+ plug->rate_converter = NULL;
|
||||
+ }
|
||||
assert(plug->gen.slave == plug->req_slave);
|
||||
if (plug->gen.close_slave) {
|
||||
snd_pcm_unlink_hw_ptr(pcm, plug->req_slave);
|
||||
@@ -1108,7 +1112,6 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
|
||||
plug->sformat = sformat;
|
||||
plug->schannels = schannels;
|
||||
plug->srate = srate;
|
||||
- plug->rate_converter = rate_converter;
|
||||
plug->gen.slave = plug->req_slave = slave;
|
||||
plug->gen.close_slave = close_slave;
|
||||
plug->route_policy = route_policy;
|
||||
@@ -1125,6 +1128,15 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
|
||||
pcm->ops = &snd_pcm_plug_ops;
|
||||
pcm->fast_ops = slave->fast_ops;
|
||||
pcm->fast_op_arg = slave->fast_op_arg;
|
||||
+ if (rate_converter) {
|
||||
+ err = snd_config_copy(&plug->rate_converter,
|
||||
+ (snd_config_t *)rate_converter);
|
||||
+ if (err < 0) {
|
||||
+ snd_pcm_free(pcm);
|
||||
+ free(plug);
|
||||
+ return err;
|
||||
+ }
|
||||
+ }
|
||||
pcm->private_data = plug;
|
||||
pcm->poll_fd = slave->poll_fd;
|
||||
pcm->poll_events = slave->poll_events;
|
108
0043-pcm-file-delegate-htimestamping-to-slave-instead-of-.patch
Normal file
108
0043-pcm-file-delegate-htimestamping-to-slave-instead-of-.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 01bc7475c3ee4dc0c1c321c781cfb26e6e5fcb34 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Pape <apape@de.adit-jv.com>
|
||||
Date: Thu, 23 Mar 2017 17:10:45 +0530
|
||||
Subject: [PATCH 43/43] pcm:file: delegate htimestamping to slave instead of
|
||||
always getting real_htimestamp
|
||||
|
||||
purpose of this fix, is to read most accurate timestamps.
|
||||
|
||||
From documentation of /src/pcm/pcm.c, we can see:
|
||||
"""" \par Timestamp mode
|
||||
|
||||
The timestamp mode specifies, if timestamps are activated. Currently, only #SND_PCM_TSTAMP_NONE and #SND_PCM_TSTAMP_MMAP modes are known.
|
||||
The mmap mode means that timestamp is taken on every period time boundary. Corresponding position in the ring buffer assigned to timestamp can be obtained using #snd_pcm_htimestamp() function. """"
|
||||
|
||||
As snd_pcm_generic_htimestamp() internally calls snd_pcm_htimestamp() to read time, so accurate timestamp can be read from snd_pcm_generic_htimestamp().
|
||||
|
||||
Also, in case of pcm_file, if the underlying slave is hardware, then we would wish to read elapsed hardware time, as it will be the most accurate, as opposed to the elapsed wall time.
|
||||
This will provide pcm_file with the most accurate timestamps.
|
||||
|
||||
Following are the timesamps read with timestamp enabled, for with fix and without fix scenarios:
|
||||
|
||||
1> With fix:
|
||||
:~#time aplay --enable-tstamp -Dhtstamp_test --period-time=5000 -v -fdat /dev/urandom
|
||||
Playing raw data '/dev/urandom' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
|
||||
File PCM (file=/tmp/swarate_out.wav)
|
||||
Final file PCM (file=/tmp/swarate_out.wav)
|
||||
..
|
||||
|
||||
Slave: Hardware PCM card 0 'imx6q-sabresd-wm8962' device 0 subdevice 0
|
||||
Its setup is:
|
||||
stream : PLAYBACK
|
||||
access : RW_INTERLEAVED
|
||||
format : S16_LE
|
||||
subformat : STD
|
||||
channels : 2
|
||||
rate : 48000
|
||||
exact rate : 48000 (48000/1)
|
||||
msbits : 16
|
||||
buffer_size : 24000
|
||||
period_size : 240
|
||||
period_time : 5000
|
||||
tstamp_mode : ENABLE
|
||||
.
|
||||
.
|
||||
Before sleep = 142:409.807623
|
||||
After sleep = 142:409.807623
|
||||
Before sleep = 142:414.806016 (calling snd_pcm_htimestamp(handle, &avail, &tstamp_before))
|
||||
sleep of 2 milisec
|
||||
After sleep = 142:414.806016 (calling snd_pcm_htimestamp(handle, &avail, &tstamp_after)
|
||||
From the above timestamps, we can see that slave has returned the same timestamps, as --period-time choosen is 5msec.
|
||||
|
||||
2> Without this fix:
|
||||
The timestamps are returned with realtime value.
|
||||
|
||||
:~# time aplay --enable-tstamp -Dhtstamp_test --period-time=5000 -v -fdat /dev/urandom
|
||||
Playing raw data '/dev/urandom' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
|
||||
File PCM (file=/tmp/swarate_out.wav)
|
||||
Final file PCM (file=/tmp/swarate_out.wav)
|
||||
.
|
||||
.
|
||||
Slave: Hardware PCM card 0 'imx6q-sabresd-wm8962' device 0 subdevice 0
|
||||
Its setup is:
|
||||
stream : PLAYBACK
|
||||
access : RW_INTERLEAVED
|
||||
format : S16_LE
|
||||
subformat : STD
|
||||
channels : 2
|
||||
rate : 48000
|
||||
exact rate : 48000 (48000/1)
|
||||
msbits : 16
|
||||
buffer_size : 24000
|
||||
period_size : 240
|
||||
period_time : 5000
|
||||
tstamp_mode : ENABLE
|
||||
.
|
||||
.
|
||||
Before sleep = 241:136.875845 (calling snd_pcm_htimestamp(handle, &avail, &tstamp_before))
|
||||
sleep of 2 milisec
|
||||
After sleep = 241:139.076376 (calling snd_pcm_htimestamp(handle, &avail, &tstamp_after)
|
||||
|
||||
We can observe here, the timestamps shows time diff of ~2ms, which is the time gap of sleep duration.
|
||||
Before sleep = 241:139.617588
|
||||
After sleep = 241:141.746845
|
||||
Before sleep = 241:142.291618
|
||||
After sleep = 241:144.406406
|
||||
Before sleep = 241:144.951421
|
||||
After sleep = 241:147.066118
|
||||
Before sleep = 241:147.623421
|
||||
After sleep = 241:149.740573
|
||||
|
||||
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
|
||||
Signed-off-by: Mounesh Sutar <sutar.mounesh@gmail.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
src/pcm/pcm_file.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/pcm/pcm_file.c
|
||||
+++ b/src/pcm/pcm_file.c
|
||||
@@ -728,7 +728,7 @@ static const snd_pcm_fast_ops_t snd_pcm_
|
||||
.poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
|
||||
.poll_descriptors = snd_pcm_generic_poll_descriptors,
|
||||
.poll_revents = snd_pcm_generic_poll_revents,
|
||||
- .htimestamp = snd_pcm_generic_real_htimestamp,
|
||||
+ .htimestamp = snd_pcm_generic_htimestamp,
|
||||
};
|
||||
|
||||
/**
|
49
alsa.changes
49
alsa.changes
@ -1,3 +1,52 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Mar 29 17:26:08 CEST 2017 - tiwai@suse.de
|
||||
|
||||
- Backport upstream fix patches, including the deadlock fix for
|
||||
aplay/arecord (boo#1031525):
|
||||
0001-ucm-Add-ATTRIBUTE_UNUSED-for-unused-parameters-of-ex.patch
|
||||
0002-ucm-parser-needs-limits.h.patch
|
||||
0003-pcm-direct-allow-users-to-configure-different-period.patch
|
||||
0004-pcm-dshare-enable-silence.patch
|
||||
0005-pcm-rate-fix-the-hw_ptr-update-until-the-boundary-av.patch
|
||||
0006-plugin-dynamically-update-avail_min-on-slave.patch
|
||||
0007-rate-dynamic-update-avail_min-on-slave.patch
|
||||
0008-topology-fix-unused-const-variable-warning.patch
|
||||
0009-seq-improve-documentation-about-new-get-pid-card-fun.patch
|
||||
0010-pcm-direct-returning-semop-error-code-for-semaphore-.patch
|
||||
0011-pcm-direct-Fix-for-sync-issue-on-xrun-recover.patch
|
||||
0012-pcm-direct-check-state-before-enter-poll-on-timer.patch
|
||||
0013-pcm-direct-don-t-return-bogus-buffer-levels-in-xrun-.patch
|
||||
0014-conf-ucm-broxton-add-broxton-rt298-conf-files.patch
|
||||
0015-pcm-direct-Fix-deadlock-in-poll_descriptors.patch
|
||||
0016-ucm-Assure-the-user-input-card-name-not-to-exceed-ma.patch
|
||||
0017-ucm-Load-device-specific-configuration-file-based-on.patch
|
||||
0018-ucm-Add-command-get-_file-to-get-the-config-file-nam.patch
|
||||
0019-topology-Fix-incorrect-license-in-source-comments.patch
|
||||
0020-conf-cards-add-support-for-pistachio-card.patch
|
||||
0021-pcm-multi-Drop-the-fixed-slave_map-in-snd_pcm_multi_.patch
|
||||
0022-conf-Add-card-config-for-Intel-HDMI-DP-LPE-audio.patch
|
||||
0023-pcm-Avoid-lock-for-snd_pcm_nonblock.patch
|
||||
0024-pcm-Disable-locking-in-async-mode.patch
|
||||
0025-pcm-dmix-Allow-disabling-x86-optimizations.patch
|
||||
0026-pcm-dmix_rewind-corrupts-application-pointer-fix.patch
|
||||
0027-pcm-direct-fix-race-on-clearing-timer-events.patch
|
||||
0028-pcm-file-Enable-file-writing-for-capture-path.patch
|
||||
0029-pcm-status-dump-fix-timestamp-formatting.patch
|
||||
0030-pcm-extplug-refinement-of-masks-in-extplug.patch
|
||||
0031-pcm-rate-Add-capability-to-pass-configuration-node-t.patch
|
||||
0032-Drop-ppc64-specific-workaround-for-versioned-symbols.patch
|
||||
0033-pcm_plugin-unify-the-snd_pcm_mmap_begin-result-value.patch
|
||||
0034-always-handle-return-value-from-snd_config_get_id-co.patch
|
||||
0035-pcm-file-plugin-handle-snd_pcm_mmap_begin-error-path.patch
|
||||
0036-topology-coverity-remove-dead-code.patch
|
||||
0037-ucm-parser-fix-possible-string-overflow-in-uc_mgr_im.patch
|
||||
0038-dmix-plugin-fix-drain-for-nonblock-mode.patch
|
||||
0039-dmix-plugin-drain-quickfix-for-the-previous-patch.patch
|
||||
0040-rawmidi-virtual-fix-reading-into-a-small-buffer.patch
|
||||
0041-conf-cards-add-VC4-HDMI-card.patch
|
||||
0042-pcm-plug-save-converter-config.patch
|
||||
0043-pcm-file-delegate-htimestamping-to-slave-instead-of-.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Feb 13 10:28:23 UTC 2017 - tchvatal@suse.com
|
||||
|
||||
|
86
alsa.spec
86
alsa.spec
@ -45,6 +45,49 @@ Source34: alsa-init.sh
|
||||
Source40: 50-alsa.conf
|
||||
Source41: install-snd-module
|
||||
# upstream fixes
|
||||
Patch1: 0001-ucm-Add-ATTRIBUTE_UNUSED-for-unused-parameters-of-ex.patch
|
||||
Patch2: 0002-ucm-parser-needs-limits.h.patch
|
||||
Patch3: 0003-pcm-direct-allow-users-to-configure-different-period.patch
|
||||
Patch4: 0004-pcm-dshare-enable-silence.patch
|
||||
Patch5: 0005-pcm-rate-fix-the-hw_ptr-update-until-the-boundary-av.patch
|
||||
Patch6: 0006-plugin-dynamically-update-avail_min-on-slave.patch
|
||||
Patch7: 0007-rate-dynamic-update-avail_min-on-slave.patch
|
||||
Patch8: 0008-topology-fix-unused-const-variable-warning.patch
|
||||
Patch9: 0009-seq-improve-documentation-about-new-get-pid-card-fun.patch
|
||||
Patch10: 0010-pcm-direct-returning-semop-error-code-for-semaphore-.patch
|
||||
Patch11: 0011-pcm-direct-Fix-for-sync-issue-on-xrun-recover.patch
|
||||
Patch12: 0012-pcm-direct-check-state-before-enter-poll-on-timer.patch
|
||||
Patch13: 0013-pcm-direct-don-t-return-bogus-buffer-levels-in-xrun-.patch
|
||||
Patch14: 0014-conf-ucm-broxton-add-broxton-rt298-conf-files.patch
|
||||
Patch15: 0015-pcm-direct-Fix-deadlock-in-poll_descriptors.patch
|
||||
Patch16: 0016-ucm-Assure-the-user-input-card-name-not-to-exceed-ma.patch
|
||||
Patch17: 0017-ucm-Load-device-specific-configuration-file-based-on.patch
|
||||
Patch18: 0018-ucm-Add-command-get-_file-to-get-the-config-file-nam.patch
|
||||
Patch19: 0019-topology-Fix-incorrect-license-in-source-comments.patch
|
||||
Patch20: 0020-conf-cards-add-support-for-pistachio-card.patch
|
||||
Patch21: 0021-pcm-multi-Drop-the-fixed-slave_map-in-snd_pcm_multi_.patch
|
||||
Patch22: 0022-conf-Add-card-config-for-Intel-HDMI-DP-LPE-audio.patch
|
||||
Patch23: 0023-pcm-Avoid-lock-for-snd_pcm_nonblock.patch
|
||||
Patch24: 0024-pcm-Disable-locking-in-async-mode.patch
|
||||
Patch25: 0025-pcm-dmix-Allow-disabling-x86-optimizations.patch
|
||||
Patch26: 0026-pcm-dmix_rewind-corrupts-application-pointer-fix.patch
|
||||
Patch27: 0027-pcm-direct-fix-race-on-clearing-timer-events.patch
|
||||
Patch28: 0028-pcm-file-Enable-file-writing-for-capture-path.patch
|
||||
Patch29: 0029-pcm-status-dump-fix-timestamp-formatting.patch
|
||||
Patch30: 0030-pcm-extplug-refinement-of-masks-in-extplug.patch
|
||||
Patch31: 0031-pcm-rate-Add-capability-to-pass-configuration-node-t.patch
|
||||
Patch32: 0032-Drop-ppc64-specific-workaround-for-versioned-symbols.patch
|
||||
Patch33: 0033-pcm_plugin-unify-the-snd_pcm_mmap_begin-result-value.patch
|
||||
Patch34: 0034-always-handle-return-value-from-snd_config_get_id-co.patch
|
||||
Patch35: 0035-pcm-file-plugin-handle-snd_pcm_mmap_begin-error-path.patch
|
||||
Patch36: 0036-topology-coverity-remove-dead-code.patch
|
||||
Patch37: 0037-ucm-parser-fix-possible-string-overflow-in-uc_mgr_im.patch
|
||||
Patch38: 0038-dmix-plugin-fix-drain-for-nonblock-mode.patch
|
||||
Patch39: 0039-dmix-plugin-drain-quickfix-for-the-previous-patch.patch
|
||||
Patch40: 0040-rawmidi-virtual-fix-reading-into-a-small-buffer.patch
|
||||
Patch41: 0041-conf-cards-add-VC4-HDMI-card.patch
|
||||
Patch42: 0042-pcm-plug-save-converter-config.patch
|
||||
Patch43: 0043-pcm-file-delegate-htimestamping-to-slave-instead-of-.patch
|
||||
# rest suse patches
|
||||
BuildRequires: doxygen
|
||||
BuildRequires: libtool
|
||||
@ -108,6 +151,49 @@ Architecture.
|
||||
|
||||
%prep
|
||||
%setup -q -n alsa-lib-%{package_version}
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
%patch13 -p1
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
%patch30 -p1
|
||||
%patch31 -p1
|
||||
%patch32 -p1
|
||||
%patch33 -p1
|
||||
%patch34 -p1
|
||||
%patch35 -p1
|
||||
%patch36 -p1
|
||||
%patch37 -p1
|
||||
%patch38 -p1
|
||||
%patch39 -p1
|
||||
%patch40 -p1
|
||||
%patch41 -p1
|
||||
%patch42 -p1
|
||||
%patch43 -p1
|
||||
|
||||
%build
|
||||
export AUTOMAKE_JOBS="%{?_smp_mflags}"
|
||||
|
Loading…
Reference in New Issue
Block a user