All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] ASoC: firmware: Add support for FW based kcontrols.
@ 2012-11-19 18:12 Liam Girdwood
  2012-11-19 18:12 ` [PATCH 2/4] ASoC: firmware: Add support for FW based widgets Liam Girdwood
                   ` (4 more replies)
  0 siblings, 5 replies; 28+ messages in thread
From: Liam Girdwood @ 2012-11-19 18:12 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, Liam Girdwood

This patch adds initial support for firmware based kcontrols by allowing
soc.h to be included by any userspace firmware generation tools and assigns
IDs to the standard ASoC kcontrol types using the kcontrol_new index and IDs
to kcontrol get/put/info functions.

Signed-off-by: Liam Girdwood <lrg@ti.com>
---
 include/sound/soc.h |  135 +++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 116 insertions(+), 19 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 91244a0..b0b1703 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -13,6 +13,8 @@
 #ifndef __LINUX_SND_SOC_H
 #define __LINUX_SND_SOC_H
 
+#ifdef __KERNEL__
+
 #include <linux/platform_device.h>
 #include <linux/types.h>
 #include <linux/notifier.h>
@@ -27,6 +29,8 @@
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 
+#endif
+
 /*
  * Convenience kcontrol builders
  */
@@ -51,12 +55,12 @@
 #define SOC_SINGLE(xname, reg, shift, max, invert) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
-	.put = snd_soc_put_volsw, \
+	.put = snd_soc_put_volsw, .index = SOC_CONTROL_IO_VOLSW, \
 	.private_value =  SOC_SINGLE_VALUE(reg, shift, max, invert) }
 #define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
 	.info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \
-	.put = snd_soc_put_volsw_range, \
+	.put = snd_soc_put_volsw_range, .index = SOC_CONTROL_IO_RANGE, \
 	.private_value = (unsigned long)&(struct soc_mixer_control) \
 		{.reg = xreg, .shift = xshift, .min = xmin,\
 		 .max = xmax, .platform_max = xmax, .invert = xinvert} }
@@ -66,7 +70,7 @@
 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
 	.tlv.p = (tlv_array), \
 	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
-	.put = snd_soc_put_volsw, \
+	.put = snd_soc_put_volsw, .index = SOC_CONTROL_IO_VOLSW, \
 	.private_value =  SOC_SINGLE_VALUE(reg, shift, max, invert) }
 #define SOC_SINGLE_SX_TLV(xname, xreg, xshift, xmin, xmax, tlv_array) \
 {       .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -76,6 +80,7 @@
 	.info = snd_soc_info_volsw, \
 	.get = snd_soc_get_volsw_sx,\
 	.put = snd_soc_put_volsw_sx, \
+	.index = SOC_CONTROL_IO_VOLSW_SX \
 	.private_value = (unsigned long)&(struct soc_mixer_control) \
 		{.reg = xreg, .rreg = xreg, \
 		.shift = xshift, .rshift = xshift, \
@@ -85,7 +90,7 @@
 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
 	.tlv.p = (tlv_array), \
-	.info = snd_soc_info_volsw_range, \
+	.info = snd_soc_info_volsw_range, .index = SOC_CONTROL_IO_RANGE, \
 	.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
 	.private_value = (unsigned long)&(struct soc_mixer_control) \
 		{.reg = xreg, .shift = xshift, .min = xmin,\
@@ -93,19 +98,19 @@
 #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
 	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
-	.put = snd_soc_put_volsw, \
+	.put = snd_soc_put_volsw, .index = SOC_CONTROL_IO_VOLSW, \
 	.private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
 					  max, invert) }
 #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
-	.info = snd_soc_info_volsw, \
+	.info = snd_soc_info_volsw, .index = SOC_CONTROL_IO_VOLSW, \
 	.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
 	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
 					    xmax, xinvert) }
 #define SOC_DOUBLE_R_RANGE(xname, reg_left, reg_right, xshift, xmin, \
 			   xmax, xinvert)		\
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
-	.info = snd_soc_info_volsw_range, \
+	.info = snd_soc_info_volsw_range, .index = SOC_CONTROL_IO_RANGE, \
 	.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
 	.private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \
 					    xshift, xmin, xmax, xinvert) }
@@ -115,7 +120,7 @@
 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
 	.tlv.p = (tlv_array), \
 	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
-	.put = snd_soc_put_volsw, \
+	.put = snd_soc_put_volsw, .index = SOC_CONTROL_IO_VOLSW, \
 	.private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
 					  max, invert) }
 #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
@@ -123,7 +128,7 @@
 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
 	.tlv.p = (tlv_array), \
-	.info = snd_soc_info_volsw, \
+	.info = snd_soc_info_volsw, .index = SOC_CONTROL_IO_VOLSW, \
 	.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
 	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
 					    xmax, xinvert) }
@@ -133,7 +138,7 @@
 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
 	.tlv.p = (tlv_array), \
-	.info = snd_soc_info_volsw_range, \
+	.info = snd_soc_info_volsw_range, .index = SOC_CONTROL_IO_RANGE, \
 	.get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
 	.private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \
 					    xshift, xmin, xmax, xinvert) }
@@ -145,6 +150,7 @@
 	.info = snd_soc_info_volsw, \
 	.get = snd_soc_get_volsw_sx, \
 	.put = snd_soc_put_volsw_sx, \
+	.index = SOC_CONTROL_IO_SX, \
 	.private_value = (unsigned long)&(struct soc_mixer_control) \
 		{.reg = xreg, .rreg = xrreg, \
 		.shift = xshift, .rshift = xshift, \
@@ -155,7 +161,7 @@
 		  SNDRV_CTL_ELEM_ACCESS_READWRITE, \
 	.tlv.p  = (tlv_array), \
 	.info   = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
-	.put    = snd_soc_put_volsw_s8, \
+	.put    = snd_soc_put_volsw_s8, .index = SOC_CONTROL_IO_VOLSW_S8, \
 	.private_value = (unsigned long)&(struct soc_mixer_control) \
 		{.reg = xreg, .min = xmin, .max = xmax, \
 		 .platform_max = xmax} }
@@ -174,7 +180,7 @@
 	SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xmax, xtexts, xvalues)
 #define SOC_ENUM(xname, xenum) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
-	.info = snd_soc_info_enum_double, \
+	.info = snd_soc_info_enum_double, .index = SOC_CONTROL_IO_ENUM, \
 	.get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
 	.private_value = (unsigned long)&xenum }
 #define SOC_VALUE_ENUM(xname, xenum) \
@@ -182,17 +188,18 @@
 	.info = snd_soc_info_enum_double, \
 	.get = snd_soc_get_value_enum_double, \
 	.put = snd_soc_put_value_enum_double, \
+	.index = SOC_CONTROL_IO_ENUM_VALUE, \
 	.private_value = (unsigned long)&xenum }
 #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
 	 xhandler_get, xhandler_put) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
-	.info = snd_soc_info_volsw, \
+	.info = snd_soc_info_volsw, .index = SOC_CONTROL_IO_EXT, \
 	.get = xhandler_get, .put = xhandler_put, \
 	.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
 #define SOC_DOUBLE_EXT(xname, reg, shift_left, shift_right, max, invert,\
 	 xhandler_get, xhandler_put) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
-	.info = snd_soc_info_volsw, \
+	.info = snd_soc_info_volsw, .index = SOC_CONTROL_IO_EXT, \
 	.get = xhandler_get, .put = xhandler_put, \
 	.private_value = \
 		SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert) }
@@ -202,7 +209,7 @@
 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
 		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
 	.tlv.p = (tlv_array), \
-	.info = snd_soc_info_volsw, \
+	.info = snd_soc_info_volsw, .index = SOC_CONTROL_IO_EXT, \
 	.get = xhandler_get, .put = xhandler_put, \
 	.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
 #define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
@@ -211,7 +218,7 @@
 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
 		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
 	.tlv.p = (tlv_array), \
-	.info = snd_soc_info_volsw, \
+	.info = snd_soc_info_volsw, .index = SOC_CONTROL_IO_EXT,\
 	.get = xhandler_get, .put = xhandler_put, \
 	.private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \
 					  xmax, xinvert) }
@@ -221,24 +228,25 @@
 	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
 		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
 	.tlv.p = (tlv_array), \
-	.info = snd_soc_info_volsw, \
+	.info = snd_soc_info_volsw, .index = SOC_CONTROL_IO_EXT, \
 	.get = xhandler_get, .put = xhandler_put, \
 	.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
 					    xmax, xinvert) }
 #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
-	.info = snd_soc_info_bool_ext, \
+	.info = snd_soc_info_bool_ext, .index = SOC_CONTROL_IO_BOOL_EXT, \
 	.get = xhandler_get, .put = xhandler_put, \
 	.private_value = xdata }
 #define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
-	.info = snd_soc_info_enum_ext, \
+	.info = snd_soc_info_enum_ext, .index = SOC_CONTROL_IO_ENUM_EXT, \
 	.get = xhandler_get, .put = xhandler_put, \
 	.private_value = (unsigned long)&xenum }
 
 #define SND_SOC_BYTES(xname, xbase, xregs)		      \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
 	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
+	.index = SOC_CONTROL_IO_BYTES, \
 	.put = snd_soc_bytes_put, .private_value =	      \
 		((unsigned long)&(struct soc_bytes)           \
 		{.base = xbase, .num_regs = xregs }) }
@@ -247,6 +255,7 @@
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
 	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
 	.put = snd_soc_bytes_put, .private_value =	      \
+	.index = SOC_CONTROL_IO_BYTES, \
 		((unsigned long)&(struct soc_bytes)           \
 		{.base = xbase, .num_regs = xregs,	      \
 		 .mask = xmask }) }
@@ -256,6 +265,7 @@
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
 	.info = snd_soc_info_xr_sx, .get = snd_soc_get_xr_sx, \
 	.put = snd_soc_put_xr_sx, \
+	.index = SOC_CONTROL_IO_XR_SX, \
 	.private_value = (unsigned long)&(struct soc_mreg_control) \
 		{.regbase = xregbase, .regcount = xregcount, .nbits = xnbits, \
 		.invert = xinvert, .min = xmin, .max = xmax} }
@@ -281,6 +291,92 @@
 #define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
 	SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
 
+
+/*
+ * Numeric IDs for stock mixer types that are used to enumerate FW based mixers.
+ */
+
+#define SOC_CONTROL_ID_PUT(p)	((p & 0xff) << 16)
+#define SOC_CONTROL_ID_GET(g)	((g & 0xff) << 8)
+#define SOC_CONTROL_ID_INFO(i)	((i & 0xff) << 0)
+#define SOC_CONTROL_ID(g, p, i)	\
+	(SOC_CONTROL_ID_PUT(p) | SOC_CONTROL_ID_GET(g) |\
+	SOC_CONTROL_ID_INFO(i))
+
+#define SOC_CONTROL_GET_ID_PUT(id)	((id & 0xff0000) >> 16)
+#define SOC_CONTROL_GET_ID_GET(id)	((id & 0x00ff00) >> 8)
+#define SOC_CONTROL_GET_ID_INFO(id)	((id & 0x0000ff) >> 0)
+
+/* individual kcontrol info types - can be mixed with other types */
+#define SOC_CONTROL_TYPE_EXT		0	/* driver defined */
+#define SOC_CONTROL_TYPE_VOLSW		1
+#define SOC_CONTROL_TYPE_VOLSW_SX	2
+#define SOC_CONTROL_TYPE_VOLSW_S8	3
+#define SOC_CONTROL_TYPE_VOLSW_XR_SX	4
+#define SOC_CONTROL_TYPE_ENUM		6
+#define SOC_CONTROL_TYPE_ENUM_EXT	7
+#define SOC_CONTROL_TYPE_BYTES		8
+#define SOC_CONTROL_TYPE_BOOL_EXT	9
+#define SOC_CONTROL_TYPE_ENUM_VALUE	10
+#define SOC_CONTROL_TYPE_RANGE		11
+#define SOC_CONTROL_TYPE_STROBE		12
+
+/* compound control IDs */
+#define SOC_CONTROL_IO_VOLSW \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_VOLSW, \
+		SOC_CONTROL_TYPE_VOLSW, \
+		SOC_CONTROL_TYPE_VOLSW)
+#define SOC_CONTROL_IO_VOLSW_SX \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_VOLSW_SX, \
+		SOC_CONTROL_TYPE_VOLSW_SX, \
+		SOC_CONTROL_TYPE_VOLSW)
+#define SOC_CONTROL_IO_VOLSW_S8 \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_VOLSW_S8, \
+		SOC_CONTROL_TYPE_VOLSW_S8, \
+		SOC_CONTROL_TYPE_VOLSW_S8)
+#define SOC_CONTROL_IO_VOLSW_XR_SX \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_VOLSW_XR_SX, \
+		SOC_CONTROL_TYPE_VOLSW_XR_SX, \
+		SOC_CONTROL_TYPE_VOLSW_XR_SX)
+#define SOC_CONTROL_IO_EXT \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_EXT, \
+		SOC_CONTROL_TYPE_EXT, \
+		SOC_CONTROL_TYPE_VOLSW)
+#define SOC_CONTROL_IO_ENUM \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_ENUM, \
+		SOC_CONTROL_TYPE_ENUM, \
+		SOC_CONTROL_TYPE_ENUM)
+#define SOC_CONTROL_IO_ENUM_EXT \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_EXT, \
+		SOC_CONTROL_TYPE_EXT, \
+		SOC_CONTROL_TYPE_ENUM_EXT)
+#define SOC_CONTROL_IO_BYTES \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_BYTES, \
+		SOC_CONTROL_TYPE_BYTES, \
+		SOC_CONTROL_TYPE_BYTES)
+#define SOC_CONTROL_IO_BOOL_EXT \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_EXT, \
+		SOC_CONTROL_TYPE_EXT, \
+		SOC_CONTROL_TYPE_BOOL_EXT)
+#define SOC_CONTROL_IO_ENUM_VALUE \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_ENUM_VALUE, \
+		SOC_CONTROL_TYPE_ENUM_VALUE, \
+		SOC_CONTROL_TYPE_ENUM)
+#define SOC_CONTROL_IO_RANGE \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_RANGE, \
+		SOC_CONTROL_TYPE_RANGE, \
+		SOC_CONTROL_TYPE_RANGE)
+#define SOC_CONTROL_IO_STROBE \
+	SOC_CONTROL_ID(SOC_CONTROL_TYPE_STROBE, \
+		SOC_CONTROL_TYPE_STROBE, \
+		SOC_CONTROL_TYPE_STROBE)
+
+#ifdef __KERNEL__
+
+#define snd_soc_get_enum_text(soc_enum, idx) \
+	(soc_enum->texts ? soc_enum->texts[idx] : soc_enum->dtexts[idx])
+
+
 /*
  * Component probe and remove ordering levels for components with runtime
  * dependencies.
@@ -1178,3 +1274,4 @@ extern struct dentry *snd_soc_debugfs_root;
 extern const struct dev_pm_ops snd_soc_pm_ops;
 
 #endif
+#endif
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2012-11-29 17:39 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-19 18:12 [PATCH 1/4] ASoC: firmware: Add support for FW based kcontrols Liam Girdwood
2012-11-19 18:12 ` [PATCH 2/4] ASoC: firmware: Add support for FW based widgets Liam Girdwood
2012-11-20  2:16   ` Mark Brown
2012-11-19 18:12 ` [PATCH 3/4] ASoC: firmware core: Add core support for dynamic kcontrols and widgets Liam Girdwood
2012-11-20  2:36   ` Mark Brown
2012-11-20 12:19     ` Liam Girdwood
2012-11-19 18:12 ` [PATCH 4/4] ASoC: firmware core: Add core support to create and destroy firmware components Liam Girdwood
2012-11-19 18:46   ` Takashi Iwai
2012-11-20 12:03     ` Liam Girdwood
2012-11-20 12:05       ` Takashi Iwai
2012-11-21  0:30       ` Mark Brown
2012-11-21  6:43         ` Takashi Iwai
2012-11-21  6:49           ` Mark Brown
2012-11-20  3:27   ` Mark Brown
2012-11-20 15:14     ` Liam Girdwood
2012-11-21  0:43       ` Mark Brown
2012-11-21 10:21         ` Liam Girdwood
2012-11-21 10:37           ` Mark Brown
2012-11-21 11:16             ` Liam Girdwood
2012-11-21 11:52               ` Mark Brown
2012-11-19 18:36 ` [PATCH 1/4] ASoC: firmware: Add support for FW based kcontrols Takashi Iwai
2012-11-29 12:08   ` Liam Girdwood
2012-11-29 15:15     ` Takashi Iwai
2012-11-29 15:51       ` Liam Girdwood
2012-11-29 16:01         ` Liam Girdwood
2012-11-29 17:35           ` Takashi Iwai
2012-11-29 17:39             ` Liam Girdwood
2012-11-20  2:11 ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.