aboutsummaryrefslogtreecommitdiffstats
path: root/include/sound/soc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/sound/soc.h')
-rw-r--r--include/sound/soc.h107
1 files changed, 64 insertions, 43 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index aa19f5a32ba8..11cfb5953e06 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -19,6 +19,7 @@
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/regmap.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/control.h> 25#include <sound/control.h>
@@ -27,13 +28,20 @@
27/* 28/*
28 * Convenience kcontrol builders 29 * Convenience kcontrol builders
29 */ 30 */
30#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ 31#define SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, xmax, xinvert) \
31 ((unsigned long)&(struct soc_mixer_control) \ 32 ((unsigned long)&(struct soc_mixer_control) \
32 {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ 33 {.reg = xreg, .rreg = xreg, .shift = shift_left, \
33 .platform_max = xmax, .invert = xinvert}) 34 .rshift = shift_right, .max = xmax, .platform_max = xmax, \
35 .invert = xinvert})
36#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
37 SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert)
34#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ 38#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
35 ((unsigned long)&(struct soc_mixer_control) \ 39 ((unsigned long)&(struct soc_mixer_control) \
36 {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert}) 40 {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert})
41#define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmax, xinvert) \
42 ((unsigned long)&(struct soc_mixer_control) \
43 {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
44 .max = xmax, .platform_max = xmax, .invert = xinvert})
37#define SOC_SINGLE(xname, reg, shift, max, invert) \ 45#define SOC_SINGLE(xname, reg, shift, max, invert) \
38{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 46{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
39 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 47 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
@@ -47,40 +55,36 @@
47 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ 55 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
48 .put = snd_soc_put_volsw, \ 56 .put = snd_soc_put_volsw, \
49 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } 57 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
50#define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \ 58#define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
51{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 59{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
52 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ 60 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
53 .put = snd_soc_put_volsw, \ 61 .put = snd_soc_put_volsw, \
54 .private_value = (unsigned long)&(struct soc_mixer_control) \ 62 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
55 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 63 max, invert) }
56 .max = xmax, .platform_max = xmax, .invert = xinvert} }
57#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ 64#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
58{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 65{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
59 .info = snd_soc_info_volsw_2r, \ 66 .info = snd_soc_info_volsw, \
60 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 67 .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
61 .private_value = (unsigned long)&(struct soc_mixer_control) \ 68 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
62 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 69 xmax, xinvert) }
63 .max = xmax, .platform_max = xmax, .invert = xinvert} } 70#define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \
64#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \
65{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 71{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
66 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 72 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
67 SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 73 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
68 .tlv.p = (tlv_array), \ 74 .tlv.p = (tlv_array), \
69 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ 75 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
70 .put = snd_soc_put_volsw, \ 76 .put = snd_soc_put_volsw, \
71 .private_value = (unsigned long)&(struct soc_mixer_control) \ 77 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
72 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ 78 max, invert) }
73 .max = xmax, .platform_max = xmax, .invert = xinvert} }
74#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ 79#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
75{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 80{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
76 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ 81 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
77 SNDRV_CTL_ELEM_ACCESS_READWRITE,\ 82 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
78 .tlv.p = (tlv_array), \ 83 .tlv.p = (tlv_array), \
79 .info = snd_soc_info_volsw_2r, \ 84 .info = snd_soc_info_volsw, \
80 .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ 85 .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
81 .private_value = (unsigned long)&(struct soc_mixer_control) \ 86 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
82 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 87 xmax, xinvert) }
83 .max = xmax, .platform_max = xmax, .invert = xinvert} }
84#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ 88#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
85{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 89{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
86 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 90 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
@@ -120,14 +124,13 @@
120 .info = snd_soc_info_volsw, \ 124 .info = snd_soc_info_volsw, \
121 .get = xhandler_get, .put = xhandler_put, \ 125 .get = xhandler_get, .put = xhandler_put, \
122 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } 126 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
123#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\ 127#define SOC_DOUBLE_EXT(xname, reg, shift_left, shift_right, max, invert,\
124 xhandler_get, xhandler_put) \ 128 xhandler_get, xhandler_put) \
125{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ 129{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
126 .info = snd_soc_info_volsw, \ 130 .info = snd_soc_info_volsw, \
127 .get = xhandler_get, .put = xhandler_put, \ 131 .get = xhandler_get, .put = xhandler_put, \
128 .private_value = (unsigned long)&(struct soc_mixer_control) \ 132 .private_value = \
129 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 133 SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert) }
130 .max = xmax, .platform_max = xmax, .invert = xinvert} }
131#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ 134#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
132 xhandler_get, xhandler_put, tlv_array) \ 135 xhandler_get, xhandler_put, tlv_array) \
133{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 136{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
@@ -145,20 +148,18 @@
145 .tlv.p = (tlv_array), \ 148 .tlv.p = (tlv_array), \
146 .info = snd_soc_info_volsw, \ 149 .info = snd_soc_info_volsw, \
147 .get = xhandler_get, .put = xhandler_put, \ 150 .get = xhandler_get, .put = xhandler_put, \
148 .private_value = (unsigned long)&(struct soc_mixer_control) \ 151 .private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \
149 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ 152 xmax, xinvert) }
150 .max = xmax, .platform_max = xmax, .invert = xinvert} }
151#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ 153#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
152 xhandler_get, xhandler_put, tlv_array) \ 154 xhandler_get, xhandler_put, tlv_array) \
153{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 155{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
154 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ 156 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
155 SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 157 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
156 .tlv.p = (tlv_array), \ 158 .tlv.p = (tlv_array), \
157 .info = snd_soc_info_volsw_2r, \ 159 .info = snd_soc_info_volsw, \
158 .get = xhandler_get, .put = xhandler_put, \ 160 .get = xhandler_get, .put = xhandler_put, \
159 .private_value = (unsigned long)&(struct soc_mixer_control) \ 161 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
160 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ 162 xmax, xinvert) }
161 .max = xmax, .platform_max = xmax, .invert = xinvert} }
162#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ 163#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
163{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 164{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
164 .info = snd_soc_info_bool_ext, \ 165 .info = snd_soc_info_bool_ext, \
@@ -260,6 +261,7 @@ extern struct snd_ac97_bus_ops soc_ac97_ops;
260enum snd_soc_control_type { 261enum snd_soc_control_type {
261 SND_SOC_I2C = 1, 262 SND_SOC_I2C = 1,
262 SND_SOC_SPI, 263 SND_SOC_SPI,
264 SND_SOC_REGMAP,
263}; 265};
264 266
265enum snd_soc_compress_type { 267enum snd_soc_compress_type {
@@ -274,7 +276,7 @@ enum snd_soc_pcm_subclass {
274}; 276};
275 277
276int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, 278int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
277 unsigned int freq, int dir); 279 int source, unsigned int freq, int dir);
278int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, 280int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
279 unsigned int freq_in, unsigned int freq_out); 281 unsigned int freq_in, unsigned int freq_out);
280 282
@@ -391,12 +393,8 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol); 393 struct snd_ctl_elem_value *ucontrol);
392int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, 394int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
393 struct snd_ctl_elem_value *ucontrol); 395 struct snd_ctl_elem_value *ucontrol);
394int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, 396#define snd_soc_get_volsw_2r snd_soc_get_volsw
395 struct snd_ctl_elem_info *uinfo); 397#define snd_soc_put_volsw_2r snd_soc_put_volsw
396int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
397 struct snd_ctl_elem_value *ucontrol);
398int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
399 struct snd_ctl_elem_value *ucontrol);
400int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, 398int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
401 struct snd_ctl_elem_info *uinfo); 399 struct snd_ctl_elem_info *uinfo);
402int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, 400int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
@@ -576,9 +574,11 @@ struct snd_soc_codec {
576 const void *reg_def_copy; 574 const void *reg_def_copy;
577 const struct snd_soc_cache_ops *cache_ops; 575 const struct snd_soc_cache_ops *cache_ops;
578 struct mutex cache_rw_mutex; 576 struct mutex cache_rw_mutex;
577 int val_bytes;
579 578
580 /* dapm */ 579 /* dapm */
581 struct snd_soc_dapm_context dapm; 580 struct snd_soc_dapm_context dapm;
581 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
582 582
583#ifdef CONFIG_DEBUG_FS 583#ifdef CONFIG_DEBUG_FS
584 struct dentry *debugfs_codec_root; 584 struct dentry *debugfs_codec_root;
@@ -607,7 +607,7 @@ struct snd_soc_codec_driver {
607 607
608 /* codec wide operations */ 608 /* codec wide operations */
609 int (*set_sysclk)(struct snd_soc_codec *codec, 609 int (*set_sysclk)(struct snd_soc_codec *codec,
610 int clk_id, unsigned int freq, int dir); 610 int clk_id, int source, unsigned int freq, int dir);
611 int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source, 611 int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
612 unsigned int freq_in, unsigned int freq_out); 612 unsigned int freq_in, unsigned int freq_out);
613 613
@@ -619,7 +619,7 @@ struct snd_soc_codec_driver {
619 int (*volatile_register)(struct snd_soc_codec *, unsigned int); 619 int (*volatile_register)(struct snd_soc_codec *, unsigned int);
620 int (*readable_register)(struct snd_soc_codec *, unsigned int); 620 int (*readable_register)(struct snd_soc_codec *, unsigned int);
621 int (*writable_register)(struct snd_soc_codec *, unsigned int); 621 int (*writable_register)(struct snd_soc_codec *, unsigned int);
622 short reg_cache_size; 622 unsigned int reg_cache_size;
623 short reg_cache_step; 623 short reg_cache_step;
624 short reg_word_size; 624 short reg_word_size;
625 const void *reg_cache_default; 625 const void *reg_cache_default;
@@ -630,10 +630,14 @@ struct snd_soc_codec_driver {
630 /* codec bias level */ 630 /* codec bias level */
631 int (*set_bias_level)(struct snd_soc_codec *, 631 int (*set_bias_level)(struct snd_soc_codec *,
632 enum snd_soc_bias_level level); 632 enum snd_soc_bias_level level);
633 bool idle_bias_off;
633 634
634 void (*seq_notifier)(struct snd_soc_dapm_context *, 635 void (*seq_notifier)(struct snd_soc_dapm_context *,
635 enum snd_soc_dapm_type, int); 636 enum snd_soc_dapm_type, int);
636 637
638 /* codec stream completion event */
639 int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
640
637 /* probe ordering - for components with runtime dependencies */ 641 /* probe ordering - for components with runtime dependencies */
638 int probe_order; 642 int probe_order;
639 int remove_order; 643 int remove_order;
@@ -669,6 +673,9 @@ struct snd_soc_platform_driver {
669 /* platform stream ops */ 673 /* platform stream ops */
670 struct snd_pcm_ops *ops; 674 struct snd_pcm_ops *ops;
671 675
676 /* platform stream completion event */
677 int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
678
672 /* probe ordering - for components with runtime dependencies */ 679 /* probe ordering - for components with runtime dependencies */
673 int probe_order; 680 int probe_order;
674 int remove_order; 681 int remove_order;
@@ -703,6 +710,8 @@ struct snd_soc_dai_link {
703 const char *cpu_dai_name; 710 const char *cpu_dai_name;
704 const char *codec_dai_name; 711 const char *codec_dai_name;
705 712
713 unsigned int dai_fmt; /* format to set on init */
714
706 /* Keep DAI active over suspend */ 715 /* Keep DAI active over suspend */
707 unsigned int ignore_suspend:1; 716 unsigned int ignore_suspend:1;
708 717
@@ -815,9 +824,11 @@ struct snd_soc_card {
815 struct list_head widgets; 824 struct list_head widgets;
816 struct list_head paths; 825 struct list_head paths;
817 struct list_head dapm_list; 826 struct list_head dapm_list;
827 struct list_head dapm_dirty;
818 828
819 /* Generic DAPM context for the card */ 829 /* Generic DAPM context for the card */
820 struct snd_soc_dapm_context dapm; 830 struct snd_soc_dapm_context dapm;
831 struct snd_soc_dapm_stats dapm_stats;
821 832
822#ifdef CONFIG_DEBUG_FS 833#ifdef CONFIG_DEBUG_FS
823 struct dentry *debugfs_card_root; 834 struct dentry *debugfs_card_root;
@@ -840,8 +851,6 @@ struct snd_soc_pcm_runtime {
840 unsigned int complete:1; 851 unsigned int complete:1;
841 unsigned int dev_registered:1; 852 unsigned int dev_registered:1;
842 853
843 /* Symmetry data - only valid if symmetry is being enforced */
844 unsigned int rate;
845 long pmdown_time; 854 long pmdown_time;
846 855
847 /* runtime devices */ 856 /* runtime devices */
@@ -936,6 +945,18 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
936 INIT_LIST_HEAD(&card->dapm_list); 945 INIT_LIST_HEAD(&card->dapm_list);
937} 946}
938 947
948static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
949{
950 if (mc->reg == mc->rreg && mc->shift == mc->rshift)
951 return 0;
952 /*
953 * mc->reg == mc->rreg && mc->shift != mc->rshift, or
954 * mc->reg != mc->rreg means that the control is
955 * stereo (bits in one register or in two registers)
956 */
957 return 1;
958}
959
939int snd_soc_util_init(void); 960int snd_soc_util_init(void);
940void snd_soc_util_exit(void); 961void snd_soc_util_exit(void);
941 962