]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.1.13/asoc-add-info-callback-for-sx_tlv-controls.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.1.13 / asoc-add-info-callback-for-sx_tlv-controls.patch
CommitLineData
af068d41
GKH
1From 34198710f55b5f359f43e67d9a08fe5aadfbca1b Mon Sep 17 00:00:00 2001
2From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
3Date: Wed, 14 Oct 2015 13:31:24 +0100
4Subject: ASoC: Add info callback for SX_TLV controls
5
6From: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
7
8commit 34198710f55b5f359f43e67d9a08fe5aadfbca1b upstream.
9
10SX_TLV controls are intended for situations where the register behind
11the control has some non-zero value indicating the minimum gain
12and then gains increasing from there and eventually overflowing through
13zero.
14
15Currently every CODEC implementing these controls specifies the minimum
16as the non-zero value for the minimum and the maximum as the number of
17gain settings available.
18
19This means when the info callback subtracts the minimum value from the
20maximum value to calculate the number of gain levels available it is
21actually under reporting the available levels. This patch fixes this
22issue by adding a new snd_soc_info_volsw_sx callback that does not
23subtract the minimum value.
24
25Fixes: 1d99f2436d0d ("ASoC: core: Rework SOC_DOUBLE_R_SX_TLV add SOC_SINGLE_SX_TLV")
26Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
27Acked-by: Brian Austin <brian.austin@cirrus.com>
28Tested-by: Brian Austin <brian.austin@cirrus.com>
29Signed-off-by: Mark Brown <broonie@kernel.org>
30Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31
32---
33 include/sound/soc.h | 6 ++++--
34 sound/soc/soc-ops.c | 28 ++++++++++++++++++++++++++++
35 2 files changed, 32 insertions(+), 2 deletions(-)
36
37--- a/include/sound/soc.h
38+++ b/include/sound/soc.h
39@@ -85,7 +85,7 @@
40 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
41 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
42 .tlv.p = (tlv_array),\
43- .info = snd_soc_info_volsw, \
44+ .info = snd_soc_info_volsw_sx, \
45 .get = snd_soc_get_volsw_sx,\
46 .put = snd_soc_put_volsw_sx, \
47 .private_value = (unsigned long)&(struct soc_mixer_control) \
48@@ -155,7 +155,7 @@
49 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
50 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
51 .tlv.p = (tlv_array), \
52- .info = snd_soc_info_volsw, \
53+ .info = snd_soc_info_volsw_sx, \
54 .get = snd_soc_get_volsw_sx, \
55 .put = snd_soc_put_volsw_sx, \
56 .private_value = (unsigned long)&(struct soc_mixer_control) \
57@@ -563,6 +563,8 @@ int snd_soc_put_enum_double(struct snd_k
58 struct snd_ctl_elem_value *ucontrol);
59 int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
60 struct snd_ctl_elem_info *uinfo);
61+int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
62+ struct snd_ctl_elem_info *uinfo);
63 #define snd_soc_info_bool_ext snd_ctl_boolean_mono_info
64 int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
65 struct snd_ctl_elem_value *ucontrol);
66--- a/sound/soc/soc-ops.c
67+++ b/sound/soc/soc-ops.c
68@@ -207,6 +207,34 @@ int snd_soc_info_volsw(struct snd_kcontr
69 EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
70
71 /**
72+ * snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls
73+ * @kcontrol: mixer control
74+ * @uinfo: control element information
75+ *
76+ * Callback to provide information about a single mixer control, or a double
77+ * mixer control that spans 2 registers of the SX TLV type. SX TLV controls
78+ * have a range that represents both positive and negative values either side
79+ * of zero but without a sign bit.
80+ *
81+ * Returns 0 for success.
82+ */
83+int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
84+ struct snd_ctl_elem_info *uinfo)
85+{
86+ struct soc_mixer_control *mc =
87+ (struct soc_mixer_control *)kcontrol->private_value;
88+
89+ snd_soc_info_volsw(kcontrol, uinfo);
90+ /* Max represents the number of levels in an SX control not the
91+ * maximum value, so add the minimum value back on
92+ */
93+ uinfo->value.integer.max += mc->min;
94+
95+ return 0;
96+}
97+EXPORT_SYMBOL_GPL(snd_soc_info_volsw_sx);
98+
99+/**
100 * snd_soc_get_volsw - single mixer get callback
101 * @kcontrol: mixer control
102 * @ucontrol: control element information