alsa/0008-test-use-actual-information-for-TLV-operation.patch
Ismail Dönmez 6117f9abfc Accepting request 442719 from home:tiwai:branches:multimedia:libs
- Backport upstream fixes (bsc#1012594):
  - A few PCM bugs have been fixed:
    * Stall of dmix and others in a wrong PCM state
    * Refactoring of PCM locking scheme
    * SHM initialization race fix
    * plug PCM memory leaks
    * Improvement of dshare/dmix delay calculation
    * Fix endless dshare draining
    * Fix semaphore discard race fix of direct plugins
  - UCM fixes and updates for DB410c and skylake-r5286
  - Mixer code cleanup not to install bogus plugin codes
  - Documentation fixes / updates
  0001-ucm-Add-ucm-files-for-DB410c-board.patch
  0002-mixer-Fix-rounding-mode-documentation.patch
  0003-pcm-Fix-shm-initialization-race-condition.patch
  0004-pcm-Better-understandable-locking-code.patch
  0005-ucm-fix-crash-when-calling-snd_use_case_geti-with-no.patch
  0006-ucm-docs-typeset-lists-of-identifiers-explicitly.patch
  0007-Update-include-sound-tlv.h-from-4.9-pre-kernel-uapi.patch
  0008-test-use-actual-information-for-TLV-operation.patch
  0009-ctl-improve-API-documentation-for-TLV-operation.patch
  0010-ctl-improve-documentation-about-TLV-related-APIs.patch
  0011-ctl-correct-documentation-about-TLV-feature.patch
  0012-conf-ucm-skylake-add-skylake-rt286-conf-files.patch
  0013-pcm_plug-Clear-plugins-on-all-error-conditions.patch
  0014-mixer-Don-t-install-smixer-modules-unless-python-is-.patch
  0015-pcm_dshare-Do-not-discard-slave-reported-delay-in-st.patch
  0016-pcm-direct-Protect-from-freeing-semaphore-when-alrea.patch
  0017-pcm-dshare-Fix-endless-playback-of-buffer.patch
  0018-pcm-Add-the-PCM-state-checks-to-plugins.patch

OBS-URL: https://build.opensuse.org/request/show/442719
OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=202
2016-11-29 18:09:28 +00:00

387 lines
12 KiB
Diff

From ee1182d2cbb4930ca1166bc03f3b0fcfbb594145 Mon Sep 17 00:00:00 2001
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Date: Thu, 29 Sep 2016 08:57:21 +0900
Subject: [PATCH] test: use actual information for TLV operation
Currently, this test program uses undefined type of TLV data. This can
bring confusions to userspace applications.
This commit replaces the array with valid information, constructed by newly
exported TLV macros from kernel land.
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
test/user-ctl-element-set.c | 214 ++++++++++++++++++++++++++++++++++++--------
1 file changed, 178 insertions(+), 36 deletions(-)
diff --git a/test/user-ctl-element-set.c b/test/user-ctl-element-set.c
index 9b9dc598f0af..75083d219fe6 100644
--- a/test/user-ctl-element-set.c
+++ b/test/user-ctl-element-set.c
@@ -8,6 +8,7 @@
*/
#include "../include/asoundlib.h"
+#include <sound/tlv.h>
struct elem_set_trial {
snd_ctl_t *handle;
@@ -25,8 +26,30 @@ struct elem_set_trial {
snd_ctl_elem_info_t *info);
void (*change_elem_members)(struct elem_set_trial *trial,
snd_ctl_elem_value_t *elem_data);
+ int (*allocate_elem_set_tlv)(struct elem_set_trial *trial,
+ unsigned int **tlv);
};
+struct chmap_entry {
+ unsigned int type;
+ unsigned int length;
+ unsigned int maps[0];
+};
+
+/*
+ * History of TLV feature:
+ *
+ * 2016/09/15: 398fa4db6c69 ("ALSA: control: move layout of TLV payload to UAPI
+ * header")
+ * 2012/07/21: 2d3391ec0ecc ("ALSA: PCM: channel mapping API implementation")
+ * 2011/11/20: bf1d1c9b6179 ("ALSA: tlv: add DECLARE_TLV_DB_RANGE()")
+ * 2009/07/16: 085f30654175 ("ALSA: Add new TLV types for dBwith min/max")
+ * 2006/09/06: 55a29af5ed5d ("[ALSA] Add definition of TLV dB range compound")
+ * 2006/08/28: 063a40d9111c ("Add the definition of linear volume TLV")
+ * 2006/08/28: 42750b04c5ba ("[ALSA] Control API - TLV implementation for
+ * additional information like dB scale")
+ */
+
/* Operations for elements in an element set with boolean type. */
static int add_bool_elem_set(struct elem_set_trial *trial,
snd_ctl_elem_info_t *info)
@@ -47,13 +70,30 @@ static void change_bool_elem_members(struct elem_set_trial *trial,
}
}
+static int allocate_bool_elem_set_tlv(struct elem_set_trial *trial,
+ unsigned int **tlv)
+{
+ /*
+ * Performs like a toggle switch for attenuation, because they're bool
+ * elements.
+ */
+ static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(range, -10000, 0);
+
+ *tlv = malloc(sizeof(range));
+ if (*tlv == NULL)
+ return -ENOMEM;
+ memcpy(*tlv, range, sizeof(range));
+
+ return 0;
+}
+
/* Operations for elements in an element set with integer type. */
static int add_int_elem_set(struct elem_set_trial *trial,
snd_ctl_elem_info_t *info)
{
return snd_ctl_add_integer_elem_set(trial->handle, info,
trial->element_count, trial->member_count,
- 0, 99, 1);
+ 0, 25, 1);
}
static int check_int_elem_props(struct elem_set_trial *trial,
@@ -61,7 +101,7 @@ static int check_int_elem_props(struct elem_set_trial *trial,
{
if (snd_ctl_elem_info_get_min(info) != 0)
return -EIO;
- if (snd_ctl_elem_info_get_max(info) != 99)
+ if (snd_ctl_elem_info_get_max(info) != 25)
return -EIO;
if (snd_ctl_elem_info_get_step(info) != 1)
return -EIO;
@@ -81,6 +121,41 @@ static void change_int_elem_members(struct elem_set_trial *trial,
}
}
+static int allocate_int_elem_set_tlv(struct elem_set_trial *trial,
+ unsigned int **tlv)
+{
+ unsigned int len, pos;
+ unsigned int i, j;
+ struct chmap_entry *entry;
+
+ /* Calculate size of TLV packet for channel-mapping information. */
+ len = 0;
+ for (i = 1; i <= 25; ++i) {
+ len += sizeof(struct chmap_entry);
+ len += i * sizeof(unsigned int);
+ }
+
+ *tlv = malloc(len);
+ if (*tlv == NULL)
+ return -ENOMEM;
+
+ /*
+ * Emulate channel-mapping information in in-kernel implementation.
+ * Here, 25 entries are for each different channel.
+ */
+ pos = 0;
+ for (i = 1; i <= 25 && pos < len; ++i) {
+ entry = (struct chmap_entry *)&(*tlv)[pos];
+ entry->type = SNDRV_CTL_TLVT_CHMAP_FIXED;
+ entry->length = i * sizeof(unsigned int);
+ for (j = 0; j < i; ++j)
+ entry->maps[j] = SND_CHMAP_MONO + j;
+ pos += sizeof(struct chmap_entry) + i * sizeof(unsigned int);
+ }
+
+ return 0;
+}
+
/* Operations for elements in an element set with enumerated type. */
static const char *const labels[] = {
"trusty",
@@ -158,6 +233,24 @@ static void change_bytes_elem_members(struct elem_set_trial *trial,
}
}
+static int allocate_bytes_elem_set_tlv(struct elem_set_trial *trial,
+ unsigned int **tlv)
+{
+ /*
+ * Emulate AK4396.
+ * 20 * log10(x/255) (dB)
+ * Here, x is written value.
+ */
+ static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(range, -4813, 0);
+
+ *tlv = malloc(sizeof(range));
+ if (*tlv == NULL)
+ return -ENOMEM;
+ memcpy(*tlv, range, sizeof(range));
+
+ return 0;
+}
+
/* Operations for elements in an element set with iec958 type. */
static int add_iec958_elem_set(struct elem_set_trial *trial,
snd_ctl_elem_info_t *info)
@@ -197,17 +290,17 @@ static int add_int64_elem_set(struct elem_set_trial *trial,
{
return snd_ctl_add_integer64_elem_set(trial->handle, info,
trial->element_count, trial->member_count,
- 100, 10000, 30);
+ 0, 10000, 1);
}
static int check_int64_elem_props(struct elem_set_trial *trial,
snd_ctl_elem_info_t *info)
{
- if (snd_ctl_elem_info_get_min64(info) != 100)
+ if (snd_ctl_elem_info_get_min64(info) != 0)
return -EIO;
if (snd_ctl_elem_info_get_max64(info) != 10000)
return -EIO;
- if (snd_ctl_elem_info_get_step64(info) != 30)
+ if (snd_ctl_elem_info_get_step64(info) != 1)
return -EIO;
return 0;
@@ -225,6 +318,45 @@ static void change_int64_elem_members(struct elem_set_trial *trial,
}
}
+static int allocate_int64_elem_set_tlv(struct elem_set_trial *trial,
+ unsigned int **tlv)
+{
+ /*
+ * Use this fomula between linear/dB value:
+ *
+ * Linear: dB range (coeff)
+ * 0<-> 4: -59.40<->-56.36 (44)
+ * 4<->22: -56.36<->-45.56 (60)
+ * 22<->33: -45.56<->-40.72 (76)
+ * 33<->37: -40.72<->-38.32 (44)
+ * 37<->48: -38.32<->-29.96 (76)
+ * 48<->66: -29.96<->-22.04 (60)
+ * 66<->84: -22.04<-> -8.36 (44)
+ * 84<->95: -8.36<-> -1.76 (60)
+ * 95<->99: -1.76<-> 0.00 (76)
+ * 100<->..: 0.0
+ */
+ static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(range,
+ 0, 4, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-5940, 44, 1),
+ 4, 22, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-5636, 60, 0),
+ 22, 33, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-4556, 76, 0),
+ 33, 37, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-4072, 44, 0),
+ 37, 48, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-3832, 76, 0),
+ 48, 66, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-2996, 60, 0),
+ 66, 84, SNDRV_CTL_TLVD_DB_SCALE_ITEM(-2204, 44, 0),
+ 84, 95, SNDRV_CTL_TLVD_DB_SCALE_ITEM( -836, 60, 0),
+ 95, 99, SNDRV_CTL_TLVD_DB_SCALE_ITEM( -176, 76, 0),
+ 100, 10000, SNDRV_CTL_TLVD_DB_SCALE_ITEM(0, 0, 0),
+ );
+
+ *tlv = malloc(sizeof(range));
+ if (*tlv == NULL)
+ return -ENOMEM;
+ memcpy(*tlv, range, sizeof(range));
+
+ return 0;
+}
+
/* Common operations. */
static int add_elem_set(struct elem_set_trial *trial)
{
@@ -414,41 +546,41 @@ static int check_elems(struct elem_set_trial *trial)
static int check_tlv(struct elem_set_trial *trial)
{
- unsigned int orig[8], curr[8];
+ unsigned int *tlv;
+ unsigned int len;
+ unsigned int *curr;
int err;
- /*
- * See a layout of 'struct snd_ctl_tlv'. I don't know the reason to
- * construct this buffer with the same layout. It should be abstracted
- * inner userspace library...
- */
- orig[0] = snd_ctl_elem_id_get_numid(trial->id);
- orig[1] = 6 * sizeof(orig[0]);
- orig[2] = 'a';
- orig[3] = 'b';
- orig[4] = 'c';
- orig[5] = 'd';
- orig[6] = 'e';
- orig[7] = 'f';
+ err = trial->allocate_elem_set_tlv(trial, &tlv);
+ if (err < 0)
+ return err;
+
+ len = tlv[1] + sizeof(unsigned int) * 2;
+ curr = malloc(len);
+ if (curr == NULL) {
+ free(tlv);
+ return -ENOMEM;
+ }
/*
* In in-kernel implementation, write and command operations are the
- * same for an element set added by userspace applications. Here, I
+ * same for an element set added by userspace applications. Here, I
* use write.
*/
err = snd_ctl_elem_tlv_write(trial->handle, trial->id,
- (const unsigned int *)orig);
+ (const unsigned int *)tlv);
if (err < 0)
- return err;
+ goto end;
- err = snd_ctl_elem_tlv_read(trial->handle, trial->id, curr,
- sizeof(curr));
+ err = snd_ctl_elem_tlv_read(trial->handle, trial->id, curr, len);
if (err < 0)
- return err;
-
- if (memcmp(curr, orig, sizeof(orig)) != 0)
- return -EIO;
+ goto end;
+ if (memcmp(curr, tlv, len) != 0)
+ err = -EIO;
+end:
+ free(tlv);
+ free(curr);
return 0;
}
@@ -484,6 +616,8 @@ int main(void)
trial.add_elem_set = add_bool_elem_set;
trial.check_elem_props = NULL;
trial.change_elem_members = change_bool_elem_members;
+ trial.allocate_elem_set_tlv =
+ allocate_bool_elem_set_tlv;
break;
case SND_CTL_ELEM_TYPE_INTEGER:
trial.element_count = 900;
@@ -495,6 +629,8 @@ int main(void)
trial.add_elem_set = add_int_elem_set;
trial.check_elem_props = check_int_elem_props;
trial.change_elem_members = change_int_elem_members;
+ trial.allocate_elem_set_tlv =
+ allocate_int_elem_set_tlv;
break;
case SND_CTL_ELEM_TYPE_ENUMERATED:
trial.element_count = 900;
@@ -506,6 +642,7 @@ int main(void)
trial.add_elem_set = add_enum_elem_set;
trial.check_elem_props = check_enum_elem_props;
trial.change_elem_members = change_enum_elem_members;
+ trial.allocate_elem_set_tlv = NULL;
break;
case SND_CTL_ELEM_TYPE_BYTES:
trial.element_count = 900;
@@ -517,6 +654,8 @@ int main(void)
trial.add_elem_set = add_bytes_elem_set;
trial.check_elem_props = NULL;
trial.change_elem_members = change_bytes_elem_members;
+ trial.allocate_elem_set_tlv =
+ allocate_bytes_elem_set_tlv;
break;
case SND_CTL_ELEM_TYPE_IEC958:
trial.element_count = 1;
@@ -528,6 +667,7 @@ int main(void)
trial.add_elem_set = add_iec958_elem_set;
trial.check_elem_props = NULL;
trial.change_elem_members = change_iec958_elem_members;
+ trial.allocate_elem_set_tlv = NULL;
break;
case SND_CTL_ELEM_TYPE_INTEGER64:
default:
@@ -540,6 +680,8 @@ int main(void)
trial.add_elem_set = add_int64_elem_set;
trial.check_elem_props = check_int64_elem_props;
trial.change_elem_members = change_int64_elem_members;
+ trial.allocate_elem_set_tlv =
+ allocate_int64_elem_set_tlv;
break;
}
@@ -589,22 +731,22 @@ int main(void)
}
/*
- * Test an operation to change threshold data of this element set,
- * except for IEC958 type.
+ * Test an operation to change TLV data of this element set,
+ * except for enumerated and IEC958 type.
*/
- if (trial.type != SND_CTL_ELEM_TYPE_IEC958) {
+ if (trial.allocate_elem_set_tlv != NULL) {
err = check_tlv(&trial);
if (err < 0) {
- printf("Fail to change threshold level of an "
- "element set with %s type.\n",
+ printf("Fail to change TLV data of an element "
+ "set with %s type.\n",
snd_ctl_elem_type_name(trial.type));
break;
}
err = check_event(&trial, SND_CTL_EVENT_MASK_TLV, 1);
if (err < 0) {
- printf("Fail to check an event to change "
- "threshold level of an an element set "
- "with %s type.\n",
+ printf("Fail to check an event to change TLV"
+ "data of an an element set with %s "
+ "type.\n",
snd_ctl_elem_type_name(trial.type));
break;
}
--
2.10.2