13 #ifndef __LINUX_SND_SOC_H
14 #define __LINUX_SND_SOC_H
17 #include <linux/types.h>
21 #include <linux/kernel.h>
33 #define SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, xmax, xinvert) \
34 ((unsigned long)&(struct soc_mixer_control) \
35 {.reg = xreg, .rreg = xreg, .shift = shift_left, \
36 .rshift = shift_right, .max = xmax, .platform_max = xmax, \
38 #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
39 SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert)
40 #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
41 ((unsigned long)&(struct soc_mixer_control) \
42 {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert})
43 #define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmax, xinvert) \
44 ((unsigned long)&(struct soc_mixer_control) \
45 {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
46 .max = xmax, .platform_max = xmax, .invert = xinvert})
47 #define SOC_DOUBLE_R_RANGE_VALUE(xlreg, xrreg, xshift, xmin, xmax, xinvert) \
48 ((unsigned long)&(struct soc_mixer_control) \
49 {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
50 .min = xmin, .max = xmax, .platform_max = xmax, .invert = xinvert})
51 #define SOC_SINGLE(xname, reg, shift, max, invert) \
52 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
53 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
54 .put = snd_soc_put_volsw, \
55 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
56 #define SOC_SINGLE_RANGE(xname, xreg, xshift, xmin, xmax, xinvert) \
57 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
58 .info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \
59 .put = snd_soc_put_volsw_range, \
60 .private_value = (unsigned long)&(struct soc_mixer_control) \
61 {.reg = xreg, .shift = xshift, .min = xmin,\
62 .max = xmax, .platform_max = xmax, .invert = xinvert} }
63 #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
64 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
65 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
66 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
67 .tlv.p = (tlv_array), \
68 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
69 .put = snd_soc_put_volsw, \
70 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
71 #define SOC_SINGLE_SX_TLV(xname, xreg, xshift, xmin, xmax, tlv_array) \
72 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
73 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
74 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
75 .tlv.p = (tlv_array),\
76 .info = snd_soc_info_volsw, \
77 .get = snd_soc_get_volsw_sx,\
78 .put = snd_soc_put_volsw_sx, \
79 .private_value = (unsigned long)&(struct soc_mixer_control) \
80 {.reg = xreg, .rreg = xreg, \
81 .shift = xshift, .rshift = xshift, \
82 .max = xmax, .min = xmin} }
83 #define SOC_SINGLE_RANGE_TLV(xname, xreg, xshift, xmin, xmax, xinvert, tlv_array) \
84 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
85 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
86 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
87 .tlv.p = (tlv_array), \
88 .info = snd_soc_info_volsw_range, \
89 .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
90 .private_value = (unsigned long)&(struct soc_mixer_control) \
91 {.reg = xreg, .shift = xshift, .min = xmin,\
92 .max = xmax, .platform_max = xmax, .invert = xinvert} }
93 #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
94 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
95 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
96 .put = snd_soc_put_volsw, \
97 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
99 #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
100 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
101 .info = snd_soc_info_volsw, \
102 .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
103 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
105 #define SOC_DOUBLE_R_RANGE(xname, reg_left, reg_right, xshift, xmin, \
107 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
108 .info = snd_soc_info_volsw_range, \
109 .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
110 .private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \
111 xshift, xmin, xmax, xinvert) }
112 #define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \
113 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
114 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
115 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
116 .tlv.p = (tlv_array), \
117 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
118 .put = snd_soc_put_volsw, \
119 .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
121 #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
122 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
123 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
124 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
125 .tlv.p = (tlv_array), \
126 .info = snd_soc_info_volsw, \
127 .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
128 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
130 #define SOC_DOUBLE_R_RANGE_TLV(xname, reg_left, reg_right, xshift, xmin, \
131 xmax, xinvert, tlv_array) \
132 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
133 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
134 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
135 .tlv.p = (tlv_array), \
136 .info = snd_soc_info_volsw_range, \
137 .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
138 .private_value = SOC_DOUBLE_R_RANGE_VALUE(reg_left, reg_right, \
139 xshift, xmin, xmax, xinvert) }
140 #define SOC_DOUBLE_R_SX_TLV(xname, xreg, xrreg, xshift, xmin, xmax, tlv_array) \
141 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
142 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
143 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
144 .tlv.p = (tlv_array), \
145 .info = snd_soc_info_volsw, \
146 .get = snd_soc_get_volsw_sx, \
147 .put = snd_soc_put_volsw_sx, \
148 .private_value = (unsigned long)&(struct soc_mixer_control) \
149 {.reg = xreg, .rreg = xrreg, \
150 .shift = xshift, .rshift = xshift, \
151 .max = xmax, .min = xmin} }
152 #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
153 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
154 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
155 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
156 .tlv.p = (tlv_array), \
157 .info = snd_soc_info_volsw_s8, .get = snd_soc_get_volsw_s8, \
158 .put = snd_soc_put_volsw_s8, \
159 .private_value = (unsigned long)&(struct soc_mixer_control) \
160 {.reg = xreg, .min = xmin, .max = xmax, \
161 .platform_max = xmax} }
162 #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
163 { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
164 .max = xmax, .texts = xtexts, \
165 .mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0}
166 #define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \
167 SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
168 #define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
169 { .max = xmax, .texts = xtexts }
170 #define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xmax, xtexts, xvalues) \
171 { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
172 .mask = xmask, .max = xmax, .texts = xtexts, .values = xvalues}
173 #define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xmax, xtexts, xvalues) \
174 SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xmax, xtexts, xvalues)
175 #define SOC_ENUM(xname, xenum) \
176 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
177 .info = snd_soc_info_enum_double, \
178 .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \
179 .private_value = (unsigned long)&xenum }
180 #define SOC_VALUE_ENUM(xname, xenum) \
181 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
182 .info = snd_soc_info_enum_double, \
183 .get = snd_soc_get_value_enum_double, \
184 .put = snd_soc_put_value_enum_double, \
185 .private_value = (unsigned long)&xenum }
186 #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\
187 xhandler_get, xhandler_put) \
188 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
189 .info = snd_soc_info_volsw, \
190 .get = xhandler_get, .put = xhandler_put, \
191 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
192 #define SOC_DOUBLE_EXT(xname, reg, shift_left, shift_right, max, invert,\
193 xhandler_get, xhandler_put) \
194 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
195 .info = snd_soc_info_volsw, \
196 .get = xhandler_get, .put = xhandler_put, \
198 SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert) }
199 #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
200 xhandler_get, xhandler_put, tlv_array) \
201 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
202 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
203 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
204 .tlv.p = (tlv_array), \
205 .info = snd_soc_info_volsw, \
206 .get = xhandler_get, .put = xhandler_put, \
207 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
208 #define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
209 xhandler_get, xhandler_put, tlv_array) \
210 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
211 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
212 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
213 .tlv.p = (tlv_array), \
214 .info = snd_soc_info_volsw, \
215 .get = xhandler_get, .put = xhandler_put, \
216 .private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \
218 #define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
219 xhandler_get, xhandler_put, tlv_array) \
220 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
221 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
222 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
223 .tlv.p = (tlv_array), \
224 .info = snd_soc_info_volsw, \
225 .get = xhandler_get, .put = xhandler_put, \
226 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
228 #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
229 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
230 .info = snd_soc_info_bool_ext, \
231 .get = xhandler_get, .put = xhandler_put, \
232 .private_value = xdata }
233 #define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
234 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
235 .info = snd_soc_info_enum_ext, \
236 .get = xhandler_get, .put = xhandler_put, \
237 .private_value = (unsigned long)&xenum }
239 #define SND_SOC_BYTES(xname, xbase, xregs) \
240 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
241 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
242 .put = snd_soc_bytes_put, .private_value = \
243 ((unsigned long)&(struct soc_bytes) \
244 {.base = xbase, .num_regs = xregs }) }
246 #define SND_SOC_BYTES_MASK(xname, xbase, xregs, xmask) \
247 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
248 .info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
249 .put = snd_soc_bytes_put, .private_value = \
250 ((unsigned long)&(struct soc_bytes) \
251 {.base = xbase, .num_regs = xregs, \
254 #define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \
255 xmin, xmax, xinvert) \
256 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
257 .info = snd_soc_info_xr_sx, .get = snd_soc_get_xr_sx, \
258 .put = snd_soc_put_xr_sx, \
259 .private_value = (unsigned long)&(struct soc_mreg_control) \
260 {.regbase = xregbase, .regcount = xregcount, .nbits = xnbits, \
261 .invert = xinvert, .min = xmin, .max = xmax} }
263 #define SOC_SINGLE_STROBE(xname, xreg, xshift, xinvert) \
264 SOC_SINGLE_EXT(xname, xreg, xshift, 1, xinvert, \
265 snd_soc_get_strobe, snd_soc_put_strobe)
271 #define SOC_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xtexts) \
272 struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \
273 ARRAY_SIZE(xtexts), xtexts)
274 #define SOC_ENUM_SINGLE_DECL(name, xreg, xshift, xtexts) \
275 SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts)
276 #define SOC_ENUM_SINGLE_EXT_DECL(name, xtexts) \
277 struct soc_enum name = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(xtexts), xtexts)
278 #define SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xmask, xtexts, xvalues) \
279 struct soc_enum name = SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, \
280 ARRAY_SIZE(xtexts), xtexts, xvalues)
281 #define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
282 SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
288 #define SND_SOC_COMP_ORDER_FIRST -2
289 #define SND_SOC_COMP_ORDER_EARLY -1
290 #define SND_SOC_COMP_ORDER_NORMAL 0
291 #define SND_SOC_COMP_ORDER_LATE 1
292 #define SND_SOC_COMP_ORDER_LAST 2
333 #ifdef CONFIG_GPIOLIB
334 struct snd_soc_jack_gpio;
364 unsigned int freq_in,
unsigned int freq_out);
385 int addr_bits,
int data_bits,
391 unsigned int reg,
unsigned int value);
393 unsigned int reg,
unsigned int *
value);
403 unsigned int reg,
unsigned int val);
408 const char *dai_link,
int stream);
438 #ifdef CONFIG_GPIOLIB
440 struct snd_soc_jack_gpio *gpios);
442 struct snd_soc_jack_gpio *gpios);
449 unsigned short reg,
unsigned int mask,
462 void *
data,
const char *long_name,
488 #define snd_soc_info_bool_ext snd_ctl_boolean_mono_info
493 #define snd_soc_get_volsw_2r snd_soc_get_volsw
494 #define snd_soc_put_volsw_2r snd_soc_put_volsw
591 #ifdef CONFIG_GPIOLIB
592 struct snd_soc_jack_gpio {
603 int (*jack_status_check)(
void);
653 unsigned int *
value);
710 #ifdef CONFIG_DEBUG_FS
711 struct dentry *debugfs_codec_root;
712 struct dentry *debugfs_reg;
713 struct dentry *debugfs_dapm;
738 unsigned int freq_in,
unsigned int freq_out);
836 #ifdef CONFIG_DEBUG_FS
837 struct dentry *debugfs_platform_root;
838 struct dentry *debugfs_dapm;
1018 #ifdef CONFIG_DEBUG_FS
1019 struct dentry *debugfs_card_root;
1020 struct dentry *debugfs_pop_time;
1052 #ifdef CONFIG_DEBUG_FS
1053 struct dentry *debugfs_dpcm_root;
1054 struct dentry *debugfs_dpcm_state;
1092 unsigned int reg,
unsigned int val);
1094 unsigned int reg,
const void *
data,
size_t len);
1120 static inline void snd_soc_platform_set_drvdata(
struct snd_soc_platform *platform,
1126 static inline void *snd_soc_platform_get_drvdata(
struct snd_soc_platform *platform)
1142 static inline void snd_soc_initialize_card_lists(
struct snd_soc_card *
card)
1147 INIT_LIST_HEAD(&card->
widgets);
1148 INIT_LIST_HEAD(&card->
paths);
1168 const char *propname);
1170 const char *propname);
1174 #ifdef CONFIG_DEBUG_FS
1175 extern struct dentry *snd_soc_debugfs_root;