diff options
author | Mark Brown <broonie@kernel.org> | 2014-10-28 18:15:31 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-10-29 07:15:10 -0400 |
commit | 7077148fb50a120d20a50516a332ed6eb9233c16 (patch) | |
tree | c057c8f5ef91ed7191e92bebe65d691b022fb405 /sound/soc/soc-ops.c | |
parent | c1b4d1c7774189002bc08766ec10e339dfbc98d6 (diff) |
ASoC: core: Split ops out of soc-core.c
The main ASoC source file is getting quite large and the standard ops don't
really have anything to do with the rest of the file so split them out into
a separate file.
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/soc-ops.c')
-rw-r--r-- | sound/soc/soc-ops.c | 952 |
1 files changed, 952 insertions, 0 deletions
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c new file mode 100644 index 000000000000..100d92b5b77e --- /dev/null +++ b/sound/soc/soc-ops.c | |||
@@ -0,0 +1,952 @@ | |||
1 | /* | ||
2 | * soc-ops.c -- Generic ASoC operations | ||
3 | * | ||
4 | * Copyright 2005 Wolfson Microelectronics PLC. | ||
5 | * Copyright 2005 Openedhand Ltd. | ||
6 | * Copyright (C) 2010 Slimlogic Ltd. | ||
7 | * Copyright (C) 2010 Texas Instruments Inc. | ||
8 | * | ||
9 | * Author: Liam Girdwood <lrg@slimlogic.co.uk> | ||
10 | * with code, comments and ideas from :- | ||
11 | * Richard Purdie <richard@openedhand.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the | ||
15 | * Free Software Foundation; either version 2 of the License, or (at your | ||
16 | * option) any later version. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/moduleparam.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/pm.h> | ||
24 | #include <linux/bitops.h> | ||
25 | #include <linux/ctype.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <sound/core.h> | ||
28 | #include <sound/jack.h> | ||
29 | #include <sound/pcm.h> | ||
30 | #include <sound/pcm_params.h> | ||
31 | #include <sound/soc.h> | ||
32 | #include <sound/soc-dpcm.h> | ||
33 | #include <sound/initval.h> | ||
34 | |||
35 | /** | ||
36 | * snd_soc_info_enum_double - enumerated double mixer info callback | ||
37 | * @kcontrol: mixer control | ||
38 | * @uinfo: control element information | ||
39 | * | ||
40 | * Callback to provide information about a double enumerated | ||
41 | * mixer control. | ||
42 | * | ||
43 | * Returns 0 for success. | ||
44 | */ | ||
45 | int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol, | ||
46 | struct snd_ctl_elem_info *uinfo) | ||
47 | { | ||
48 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
49 | |||
50 | return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2, | ||
51 | e->items, e->texts); | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(snd_soc_info_enum_double); | ||
54 | |||
55 | /** | ||
56 | * snd_soc_get_enum_double - enumerated double mixer get callback | ||
57 | * @kcontrol: mixer control | ||
58 | * @ucontrol: control element information | ||
59 | * | ||
60 | * Callback to get the value of a double enumerated mixer. | ||
61 | * | ||
62 | * Returns 0 for success. | ||
63 | */ | ||
64 | int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, | ||
65 | struct snd_ctl_elem_value *ucontrol) | ||
66 | { | ||
67 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
68 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
69 | unsigned int val, item; | ||
70 | unsigned int reg_val; | ||
71 | int ret; | ||
72 | |||
73 | ret = snd_soc_component_read(component, e->reg, ®_val); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | val = (reg_val >> e->shift_l) & e->mask; | ||
77 | item = snd_soc_enum_val_to_item(e, val); | ||
78 | ucontrol->value.enumerated.item[0] = item; | ||
79 | if (e->shift_l != e->shift_r) { | ||
80 | val = (reg_val >> e->shift_l) & e->mask; | ||
81 | item = snd_soc_enum_val_to_item(e, val); | ||
82 | ucontrol->value.enumerated.item[1] = item; | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(snd_soc_get_enum_double); | ||
88 | |||
89 | /** | ||
90 | * snd_soc_put_enum_double - enumerated double mixer put callback | ||
91 | * @kcontrol: mixer control | ||
92 | * @ucontrol: control element information | ||
93 | * | ||
94 | * Callback to set the value of a double enumerated mixer. | ||
95 | * | ||
96 | * Returns 0 for success. | ||
97 | */ | ||
98 | int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, | ||
99 | struct snd_ctl_elem_value *ucontrol) | ||
100 | { | ||
101 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
102 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | ||
103 | unsigned int *item = ucontrol->value.enumerated.item; | ||
104 | unsigned int val; | ||
105 | unsigned int mask; | ||
106 | |||
107 | if (item[0] >= e->items) | ||
108 | return -EINVAL; | ||
109 | val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; | ||
110 | mask = e->mask << e->shift_l; | ||
111 | if (e->shift_l != e->shift_r) { | ||
112 | if (item[1] >= e->items) | ||
113 | return -EINVAL; | ||
114 | val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; | ||
115 | mask |= e->mask << e->shift_r; | ||
116 | } | ||
117 | |||
118 | return snd_soc_component_update_bits(component, e->reg, mask, val); | ||
119 | } | ||
120 | EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); | ||
121 | |||
122 | /** | ||
123 | * snd_soc_read_signed - Read a codec register and interprete as signed value | ||
124 | * @component: component | ||
125 | * @reg: Register to read | ||
126 | * @mask: Mask to use after shifting the register value | ||
127 | * @shift: Right shift of register value | ||
128 | * @sign_bit: Bit that describes if a number is negative or not. | ||
129 | * @signed_val: Pointer to where the read value should be stored | ||
130 | * | ||
131 | * This functions reads a codec register. The register value is shifted right | ||
132 | * by 'shift' bits and masked with the given 'mask'. Afterwards it translates | ||
133 | * the given registervalue into a signed integer if sign_bit is non-zero. | ||
134 | * | ||
135 | * Returns 0 on sucess, otherwise an error value | ||
136 | */ | ||
137 | static int snd_soc_read_signed(struct snd_soc_component *component, | ||
138 | unsigned int reg, unsigned int mask, unsigned int shift, | ||
139 | unsigned int sign_bit, int *signed_val) | ||
140 | { | ||
141 | int ret; | ||
142 | unsigned int val; | ||
143 | |||
144 | ret = snd_soc_component_read(component, reg, &val); | ||
145 | if (ret < 0) | ||
146 | return ret; | ||
147 | |||
148 | val = (val >> shift) & mask; | ||
149 | |||
150 | if (!sign_bit) { | ||
151 | *signed_val = val; | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | /* non-negative number */ | ||
156 | if (!(val & BIT(sign_bit))) { | ||
157 | *signed_val = val; | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | ret = val; | ||
162 | |||
163 | /* | ||
164 | * The register most probably does not contain a full-sized int. | ||
165 | * Instead we have an arbitrary number of bits in a signed | ||
166 | * representation which has to be translated into a full-sized int. | ||
167 | * This is done by filling up all bits above the sign-bit. | ||
168 | */ | ||
169 | ret |= ~((int)(BIT(sign_bit) - 1)); | ||
170 | |||
171 | *signed_val = ret; | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * snd_soc_info_volsw - single mixer info callback | ||
178 | * @kcontrol: mixer control | ||
179 | * @uinfo: control element information | ||
180 | * | ||
181 | * Callback to provide information about a single mixer control, or a double | ||
182 | * mixer control that spans 2 registers. | ||
183 | * | ||
184 | * Returns 0 for success. | ||
185 | */ | ||
186 | int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, | ||
187 | struct snd_ctl_elem_info *uinfo) | ||
188 | { | ||
189 | struct soc_mixer_control *mc = | ||
190 | (struct soc_mixer_control *)kcontrol->private_value; | ||
191 | int platform_max; | ||
192 | |||
193 | if (!mc->platform_max) | ||
194 | mc->platform_max = mc->max; | ||
195 | platform_max = mc->platform_max; | ||
196 | |||
197 | if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) | ||
198 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
199 | else | ||
200 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
201 | |||
202 | uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; | ||
203 | uinfo->value.integer.min = 0; | ||
204 | uinfo->value.integer.max = platform_max - mc->min; | ||
205 | return 0; | ||
206 | } | ||
207 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw); | ||
208 | |||
209 | /** | ||
210 | * snd_soc_get_volsw - single mixer get callback | ||
211 | * @kcontrol: mixer control | ||
212 | * @ucontrol: control element information | ||
213 | * | ||
214 | * Callback to get the value of a single mixer control, or a double mixer | ||
215 | * control that spans 2 registers. | ||
216 | * | ||
217 | * Returns 0 for success. | ||
218 | */ | ||
219 | int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | ||
220 | struct snd_ctl_elem_value *ucontrol) | ||
221 | { | ||
222 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
223 | struct soc_mixer_control *mc = | ||
224 | (struct soc_mixer_control *)kcontrol->private_value; | ||
225 | unsigned int reg = mc->reg; | ||
226 | unsigned int reg2 = mc->rreg; | ||
227 | unsigned int shift = mc->shift; | ||
228 | unsigned int rshift = mc->rshift; | ||
229 | int max = mc->max; | ||
230 | int min = mc->min; | ||
231 | int sign_bit = mc->sign_bit; | ||
232 | unsigned int mask = (1 << fls(max)) - 1; | ||
233 | unsigned int invert = mc->invert; | ||
234 | int val; | ||
235 | int ret; | ||
236 | |||
237 | if (sign_bit) | ||
238 | mask = BIT(sign_bit + 1) - 1; | ||
239 | |||
240 | ret = snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); | ||
241 | if (ret) | ||
242 | return ret; | ||
243 | |||
244 | ucontrol->value.integer.value[0] = val - min; | ||
245 | if (invert) | ||
246 | ucontrol->value.integer.value[0] = | ||
247 | max - ucontrol->value.integer.value[0]; | ||
248 | |||
249 | if (snd_soc_volsw_is_stereo(mc)) { | ||
250 | if (reg == reg2) | ||
251 | ret = snd_soc_read_signed(component, reg, mask, rshift, | ||
252 | sign_bit, &val); | ||
253 | else | ||
254 | ret = snd_soc_read_signed(component, reg2, mask, shift, | ||
255 | sign_bit, &val); | ||
256 | if (ret) | ||
257 | return ret; | ||
258 | |||
259 | ucontrol->value.integer.value[1] = val - min; | ||
260 | if (invert) | ||
261 | ucontrol->value.integer.value[1] = | ||
262 | max - ucontrol->value.integer.value[1]; | ||
263 | } | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | EXPORT_SYMBOL_GPL(snd_soc_get_volsw); | ||
268 | |||
269 | /** | ||
270 | * snd_soc_put_volsw - single mixer put callback | ||
271 | * @kcontrol: mixer control | ||
272 | * @ucontrol: control element information | ||
273 | * | ||
274 | * Callback to set the value of a single mixer control, or a double mixer | ||
275 | * control that spans 2 registers. | ||
276 | * | ||
277 | * Returns 0 for success. | ||
278 | */ | ||
279 | int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | ||
280 | struct snd_ctl_elem_value *ucontrol) | ||
281 | { | ||
282 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
283 | struct soc_mixer_control *mc = | ||
284 | (struct soc_mixer_control *)kcontrol->private_value; | ||
285 | unsigned int reg = mc->reg; | ||
286 | unsigned int reg2 = mc->rreg; | ||
287 | unsigned int shift = mc->shift; | ||
288 | unsigned int rshift = mc->rshift; | ||
289 | int max = mc->max; | ||
290 | int min = mc->min; | ||
291 | unsigned int sign_bit = mc->sign_bit; | ||
292 | unsigned int mask = (1 << fls(max)) - 1; | ||
293 | unsigned int invert = mc->invert; | ||
294 | int err; | ||
295 | bool type_2r = false; | ||
296 | unsigned int val2 = 0; | ||
297 | unsigned int val, val_mask; | ||
298 | |||
299 | if (sign_bit) | ||
300 | mask = BIT(sign_bit + 1) - 1; | ||
301 | |||
302 | val = ((ucontrol->value.integer.value[0] + min) & mask); | ||
303 | if (invert) | ||
304 | val = max - val; | ||
305 | val_mask = mask << shift; | ||
306 | val = val << shift; | ||
307 | if (snd_soc_volsw_is_stereo(mc)) { | ||
308 | val2 = ((ucontrol->value.integer.value[1] + min) & mask); | ||
309 | if (invert) | ||
310 | val2 = max - val2; | ||
311 | if (reg == reg2) { | ||
312 | val_mask |= mask << rshift; | ||
313 | val |= val2 << rshift; | ||
314 | } else { | ||
315 | val2 = val2 << shift; | ||
316 | type_2r = true; | ||
317 | } | ||
318 | } | ||
319 | err = snd_soc_component_update_bits(component, reg, val_mask, val); | ||
320 | if (err < 0) | ||
321 | return err; | ||
322 | |||
323 | if (type_2r) | ||
324 | err = snd_soc_component_update_bits(component, reg2, val_mask, | ||
325 | val2); | ||
326 | |||
327 | return err; | ||
328 | } | ||
329 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw); | ||
330 | |||
331 | /** | ||
332 | * snd_soc_get_volsw_sx - single mixer get callback | ||
333 | * @kcontrol: mixer control | ||
334 | * @ucontrol: control element information | ||
335 | * | ||
336 | * Callback to get the value of a single mixer control, or a double mixer | ||
337 | * control that spans 2 registers. | ||
338 | * | ||
339 | * Returns 0 for success. | ||
340 | */ | ||
341 | int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, | ||
342 | struct snd_ctl_elem_value *ucontrol) | ||
343 | { | ||
344 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
345 | struct soc_mixer_control *mc = | ||
346 | (struct soc_mixer_control *)kcontrol->private_value; | ||
347 | unsigned int reg = mc->reg; | ||
348 | unsigned int reg2 = mc->rreg; | ||
349 | unsigned int shift = mc->shift; | ||
350 | unsigned int rshift = mc->rshift; | ||
351 | int max = mc->max; | ||
352 | int min = mc->min; | ||
353 | int mask = (1 << (fls(min + max) - 1)) - 1; | ||
354 | unsigned int val; | ||
355 | int ret; | ||
356 | |||
357 | ret = snd_soc_component_read(component, reg, &val); | ||
358 | if (ret < 0) | ||
359 | return ret; | ||
360 | |||
361 | ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; | ||
362 | |||
363 | if (snd_soc_volsw_is_stereo(mc)) { | ||
364 | ret = snd_soc_component_read(component, reg2, &val); | ||
365 | if (ret < 0) | ||
366 | return ret; | ||
367 | |||
368 | val = ((val >> rshift) - min) & mask; | ||
369 | ucontrol->value.integer.value[1] = val; | ||
370 | } | ||
371 | |||
372 | return 0; | ||
373 | } | ||
374 | EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx); | ||
375 | |||
376 | /** | ||
377 | * snd_soc_put_volsw_sx - double mixer set callback | ||
378 | * @kcontrol: mixer control | ||
379 | * @uinfo: control element information | ||
380 | * | ||
381 | * Callback to set the value of a double mixer control that spans 2 registers. | ||
382 | * | ||
383 | * Returns 0 for success. | ||
384 | */ | ||
385 | int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, | ||
386 | struct snd_ctl_elem_value *ucontrol) | ||
387 | { | ||
388 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
389 | struct soc_mixer_control *mc = | ||
390 | (struct soc_mixer_control *)kcontrol->private_value; | ||
391 | |||
392 | unsigned int reg = mc->reg; | ||
393 | unsigned int reg2 = mc->rreg; | ||
394 | unsigned int shift = mc->shift; | ||
395 | unsigned int rshift = mc->rshift; | ||
396 | int max = mc->max; | ||
397 | int min = mc->min; | ||
398 | int mask = (1 << (fls(min + max) - 1)) - 1; | ||
399 | int err = 0; | ||
400 | unsigned int val, val_mask, val2 = 0; | ||
401 | |||
402 | val_mask = mask << shift; | ||
403 | val = (ucontrol->value.integer.value[0] + min) & mask; | ||
404 | val = val << shift; | ||
405 | |||
406 | err = snd_soc_component_update_bits(component, reg, val_mask, val); | ||
407 | if (err < 0) | ||
408 | return err; | ||
409 | |||
410 | if (snd_soc_volsw_is_stereo(mc)) { | ||
411 | val_mask = mask << rshift; | ||
412 | val2 = (ucontrol->value.integer.value[1] + min) & mask; | ||
413 | val2 = val2 << rshift; | ||
414 | |||
415 | err = snd_soc_component_update_bits(component, reg2, val_mask, | ||
416 | val2); | ||
417 | } | ||
418 | return err; | ||
419 | } | ||
420 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); | ||
421 | |||
422 | /** | ||
423 | * snd_soc_info_volsw_range - single mixer info callback with range. | ||
424 | * @kcontrol: mixer control | ||
425 | * @uinfo: control element information | ||
426 | * | ||
427 | * Callback to provide information, within a range, about a single | ||
428 | * mixer control. | ||
429 | * | ||
430 | * returns 0 for success. | ||
431 | */ | ||
432 | int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol, | ||
433 | struct snd_ctl_elem_info *uinfo) | ||
434 | { | ||
435 | struct soc_mixer_control *mc = | ||
436 | (struct soc_mixer_control *)kcontrol->private_value; | ||
437 | int platform_max; | ||
438 | int min = mc->min; | ||
439 | |||
440 | if (!mc->platform_max) | ||
441 | mc->platform_max = mc->max; | ||
442 | platform_max = mc->platform_max; | ||
443 | |||
444 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
445 | uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; | ||
446 | uinfo->value.integer.min = 0; | ||
447 | uinfo->value.integer.max = platform_max - min; | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range); | ||
452 | |||
453 | /** | ||
454 | * snd_soc_put_volsw_range - single mixer put value callback with range. | ||
455 | * @kcontrol: mixer control | ||
456 | * @ucontrol: control element information | ||
457 | * | ||
458 | * Callback to set the value, within a range, for a single mixer control. | ||
459 | * | ||
460 | * Returns 0 for success. | ||
461 | */ | ||
462 | int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, | ||
463 | struct snd_ctl_elem_value *ucontrol) | ||
464 | { | ||
465 | struct soc_mixer_control *mc = | ||
466 | (struct soc_mixer_control *)kcontrol->private_value; | ||
467 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
468 | unsigned int reg = mc->reg; | ||
469 | unsigned int rreg = mc->rreg; | ||
470 | unsigned int shift = mc->shift; | ||
471 | int min = mc->min; | ||
472 | int max = mc->max; | ||
473 | unsigned int mask = (1 << fls(max)) - 1; | ||
474 | unsigned int invert = mc->invert; | ||
475 | unsigned int val, val_mask; | ||
476 | int ret; | ||
477 | |||
478 | if (invert) | ||
479 | val = (max - ucontrol->value.integer.value[0]) & mask; | ||
480 | else | ||
481 | val = ((ucontrol->value.integer.value[0] + min) & mask); | ||
482 | val_mask = mask << shift; | ||
483 | val = val << shift; | ||
484 | |||
485 | ret = snd_soc_component_update_bits(component, reg, val_mask, val); | ||
486 | if (ret < 0) | ||
487 | return ret; | ||
488 | |||
489 | if (snd_soc_volsw_is_stereo(mc)) { | ||
490 | if (invert) | ||
491 | val = (max - ucontrol->value.integer.value[1]) & mask; | ||
492 | else | ||
493 | val = ((ucontrol->value.integer.value[1] + min) & mask); | ||
494 | val_mask = mask << shift; | ||
495 | val = val << shift; | ||
496 | |||
497 | ret = snd_soc_component_update_bits(component, rreg, val_mask, | ||
498 | val); | ||
499 | } | ||
500 | |||
501 | return ret; | ||
502 | } | ||
503 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); | ||
504 | |||
505 | /** | ||
506 | * snd_soc_get_volsw_range - single mixer get callback with range | ||
507 | * @kcontrol: mixer control | ||
508 | * @ucontrol: control element information | ||
509 | * | ||
510 | * Callback to get the value, within a range, of a single mixer control. | ||
511 | * | ||
512 | * Returns 0 for success. | ||
513 | */ | ||
514 | int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, | ||
515 | struct snd_ctl_elem_value *ucontrol) | ||
516 | { | ||
517 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
518 | struct soc_mixer_control *mc = | ||
519 | (struct soc_mixer_control *)kcontrol->private_value; | ||
520 | unsigned int reg = mc->reg; | ||
521 | unsigned int rreg = mc->rreg; | ||
522 | unsigned int shift = mc->shift; | ||
523 | int min = mc->min; | ||
524 | int max = mc->max; | ||
525 | unsigned int mask = (1 << fls(max)) - 1; | ||
526 | unsigned int invert = mc->invert; | ||
527 | unsigned int val; | ||
528 | int ret; | ||
529 | |||
530 | ret = snd_soc_component_read(component, reg, &val); | ||
531 | if (ret) | ||
532 | return ret; | ||
533 | |||
534 | ucontrol->value.integer.value[0] = (val >> shift) & mask; | ||
535 | if (invert) | ||
536 | ucontrol->value.integer.value[0] = | ||
537 | max - ucontrol->value.integer.value[0]; | ||
538 | else | ||
539 | ucontrol->value.integer.value[0] = | ||
540 | ucontrol->value.integer.value[0] - min; | ||
541 | |||
542 | if (snd_soc_volsw_is_stereo(mc)) { | ||
543 | ret = snd_soc_component_read(component, rreg, &val); | ||
544 | if (ret) | ||
545 | return ret; | ||
546 | |||
547 | ucontrol->value.integer.value[1] = (val >> shift) & mask; | ||
548 | if (invert) | ||
549 | ucontrol->value.integer.value[1] = | ||
550 | max - ucontrol->value.integer.value[1]; | ||
551 | else | ||
552 | ucontrol->value.integer.value[1] = | ||
553 | ucontrol->value.integer.value[1] - min; | ||
554 | } | ||
555 | |||
556 | return 0; | ||
557 | } | ||
558 | EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range); | ||
559 | |||
560 | /** | ||
561 | * snd_soc_limit_volume - Set new limit to an existing volume control. | ||
562 | * | ||
563 | * @codec: where to look for the control | ||
564 | * @name: Name of the control | ||
565 | * @max: new maximum limit | ||
566 | * | ||
567 | * Return 0 for success, else error. | ||
568 | */ | ||
569 | int snd_soc_limit_volume(struct snd_soc_codec *codec, | ||
570 | const char *name, int max) | ||
571 | { | ||
572 | struct snd_card *card = codec->component.card->snd_card; | ||
573 | struct snd_kcontrol *kctl; | ||
574 | struct soc_mixer_control *mc; | ||
575 | int found = 0; | ||
576 | int ret = -EINVAL; | ||
577 | |||
578 | /* Sanity check for name and max */ | ||
579 | if (unlikely(!name || max <= 0)) | ||
580 | return -EINVAL; | ||
581 | |||
582 | list_for_each_entry(kctl, &card->controls, list) { | ||
583 | if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) { | ||
584 | found = 1; | ||
585 | break; | ||
586 | } | ||
587 | } | ||
588 | if (found) { | ||
589 | mc = (struct soc_mixer_control *)kctl->private_value; | ||
590 | if (max <= mc->max) { | ||
591 | mc->platform_max = max; | ||
592 | ret = 0; | ||
593 | } | ||
594 | } | ||
595 | return ret; | ||
596 | } | ||
597 | EXPORT_SYMBOL_GPL(snd_soc_limit_volume); | ||
598 | |||
599 | int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, | ||
600 | struct snd_ctl_elem_info *uinfo) | ||
601 | { | ||
602 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
603 | struct soc_bytes *params = (void *)kcontrol->private_value; | ||
604 | |||
605 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
606 | uinfo->count = params->num_regs * component->val_bytes; | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | EXPORT_SYMBOL_GPL(snd_soc_bytes_info); | ||
611 | |||
612 | int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, | ||
613 | struct snd_ctl_elem_value *ucontrol) | ||
614 | { | ||
615 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
616 | struct soc_bytes *params = (void *)kcontrol->private_value; | ||
617 | int ret; | ||
618 | |||
619 | if (component->regmap) | ||
620 | ret = regmap_raw_read(component->regmap, params->base, | ||
621 | ucontrol->value.bytes.data, | ||
622 | params->num_regs * component->val_bytes); | ||
623 | else | ||
624 | ret = -EINVAL; | ||
625 | |||
626 | /* Hide any masked bytes to ensure consistent data reporting */ | ||
627 | if (ret == 0 && params->mask) { | ||
628 | switch (component->val_bytes) { | ||
629 | case 1: | ||
630 | ucontrol->value.bytes.data[0] &= ~params->mask; | ||
631 | break; | ||
632 | case 2: | ||
633 | ((u16 *)(&ucontrol->value.bytes.data))[0] | ||
634 | &= cpu_to_be16(~params->mask); | ||
635 | break; | ||
636 | case 4: | ||
637 | ((u32 *)(&ucontrol->value.bytes.data))[0] | ||
638 | &= cpu_to_be32(~params->mask); | ||
639 | break; | ||
640 | default: | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | } | ||
644 | |||
645 | return ret; | ||
646 | } | ||
647 | EXPORT_SYMBOL_GPL(snd_soc_bytes_get); | ||
648 | |||
649 | int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | ||
650 | struct snd_ctl_elem_value *ucontrol) | ||
651 | { | ||
652 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
653 | struct soc_bytes *params = (void *)kcontrol->private_value; | ||
654 | int ret, len; | ||
655 | unsigned int val, mask; | ||
656 | void *data; | ||
657 | |||
658 | if (!component->regmap || !params->num_regs) | ||
659 | return -EINVAL; | ||
660 | |||
661 | len = params->num_regs * component->val_bytes; | ||
662 | |||
663 | data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); | ||
664 | if (!data) | ||
665 | return -ENOMEM; | ||
666 | |||
667 | /* | ||
668 | * If we've got a mask then we need to preserve the register | ||
669 | * bits. We shouldn't modify the incoming data so take a | ||
670 | * copy. | ||
671 | */ | ||
672 | if (params->mask) { | ||
673 | ret = regmap_read(component->regmap, params->base, &val); | ||
674 | if (ret != 0) | ||
675 | goto out; | ||
676 | |||
677 | val &= params->mask; | ||
678 | |||
679 | switch (component->val_bytes) { | ||
680 | case 1: | ||
681 | ((u8 *)data)[0] &= ~params->mask; | ||
682 | ((u8 *)data)[0] |= val; | ||
683 | break; | ||
684 | case 2: | ||
685 | mask = ~params->mask; | ||
686 | ret = regmap_parse_val(component->regmap, | ||
687 | &mask, &mask); | ||
688 | if (ret != 0) | ||
689 | goto out; | ||
690 | |||
691 | ((u16 *)data)[0] &= mask; | ||
692 | |||
693 | ret = regmap_parse_val(component->regmap, | ||
694 | &val, &val); | ||
695 | if (ret != 0) | ||
696 | goto out; | ||
697 | |||
698 | ((u16 *)data)[0] |= val; | ||
699 | break; | ||
700 | case 4: | ||
701 | mask = ~params->mask; | ||
702 | ret = regmap_parse_val(component->regmap, | ||
703 | &mask, &mask); | ||
704 | if (ret != 0) | ||
705 | goto out; | ||
706 | |||
707 | ((u32 *)data)[0] &= mask; | ||
708 | |||
709 | ret = regmap_parse_val(component->regmap, | ||
710 | &val, &val); | ||
711 | if (ret != 0) | ||
712 | goto out; | ||
713 | |||
714 | ((u32 *)data)[0] |= val; | ||
715 | break; | ||
716 | default: | ||
717 | ret = -EINVAL; | ||
718 | goto out; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | ret = regmap_raw_write(component->regmap, params->base, | ||
723 | data, len); | ||
724 | |||
725 | out: | ||
726 | kfree(data); | ||
727 | |||
728 | return ret; | ||
729 | } | ||
730 | EXPORT_SYMBOL_GPL(snd_soc_bytes_put); | ||
731 | |||
732 | int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol, | ||
733 | struct snd_ctl_elem_info *ucontrol) | ||
734 | { | ||
735 | struct soc_bytes_ext *params = (void *)kcontrol->private_value; | ||
736 | |||
737 | ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
738 | ucontrol->count = params->max; | ||
739 | |||
740 | return 0; | ||
741 | } | ||
742 | EXPORT_SYMBOL_GPL(snd_soc_bytes_info_ext); | ||
743 | |||
744 | int snd_soc_bytes_tlv_callback(struct snd_kcontrol *kcontrol, int op_flag, | ||
745 | unsigned int size, unsigned int __user *tlv) | ||
746 | { | ||
747 | struct soc_bytes_ext *params = (void *)kcontrol->private_value; | ||
748 | unsigned int count = size < params->max ? size : params->max; | ||
749 | int ret = -ENXIO; | ||
750 | |||
751 | switch (op_flag) { | ||
752 | case SNDRV_CTL_TLV_OP_READ: | ||
753 | if (params->get) | ||
754 | ret = params->get(tlv, count); | ||
755 | break; | ||
756 | case SNDRV_CTL_TLV_OP_WRITE: | ||
757 | if (params->put) | ||
758 | ret = params->put(tlv, count); | ||
759 | break; | ||
760 | } | ||
761 | return ret; | ||
762 | } | ||
763 | EXPORT_SYMBOL_GPL(snd_soc_bytes_tlv_callback); | ||
764 | |||
765 | /** | ||
766 | * snd_soc_info_xr_sx - signed multi register info callback | ||
767 | * @kcontrol: mreg control | ||
768 | * @uinfo: control element information | ||
769 | * | ||
770 | * Callback to provide information of a control that can | ||
771 | * span multiple codec registers which together | ||
772 | * forms a single signed value in a MSB/LSB manner. | ||
773 | * | ||
774 | * Returns 0 for success. | ||
775 | */ | ||
776 | int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol, | ||
777 | struct snd_ctl_elem_info *uinfo) | ||
778 | { | ||
779 | struct soc_mreg_control *mc = | ||
780 | (struct soc_mreg_control *)kcontrol->private_value; | ||
781 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
782 | uinfo->count = 1; | ||
783 | uinfo->value.integer.min = mc->min; | ||
784 | uinfo->value.integer.max = mc->max; | ||
785 | |||
786 | return 0; | ||
787 | } | ||
788 | EXPORT_SYMBOL_GPL(snd_soc_info_xr_sx); | ||
789 | |||
790 | /** | ||
791 | * snd_soc_get_xr_sx - signed multi register get callback | ||
792 | * @kcontrol: mreg control | ||
793 | * @ucontrol: control element information | ||
794 | * | ||
795 | * Callback to get the value of a control that can span | ||
796 | * multiple codec registers which together forms a single | ||
797 | * signed value in a MSB/LSB manner. The control supports | ||
798 | * specifying total no of bits used to allow for bitfields | ||
799 | * across the multiple codec registers. | ||
800 | * | ||
801 | * Returns 0 for success. | ||
802 | */ | ||
803 | int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, | ||
804 | struct snd_ctl_elem_value *ucontrol) | ||
805 | { | ||
806 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
807 | struct soc_mreg_control *mc = | ||
808 | (struct soc_mreg_control *)kcontrol->private_value; | ||
809 | unsigned int regbase = mc->regbase; | ||
810 | unsigned int regcount = mc->regcount; | ||
811 | unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; | ||
812 | unsigned int regwmask = (1<<regwshift)-1; | ||
813 | unsigned int invert = mc->invert; | ||
814 | unsigned long mask = (1UL<<mc->nbits)-1; | ||
815 | long min = mc->min; | ||
816 | long max = mc->max; | ||
817 | long val = 0; | ||
818 | unsigned int regval; | ||
819 | unsigned int i; | ||
820 | int ret; | ||
821 | |||
822 | for (i = 0; i < regcount; i++) { | ||
823 | ret = snd_soc_component_read(component, regbase+i, ®val); | ||
824 | if (ret) | ||
825 | return ret; | ||
826 | val |= (regval & regwmask) << (regwshift*(regcount-i-1)); | ||
827 | } | ||
828 | val &= mask; | ||
829 | if (min < 0 && val > max) | ||
830 | val |= ~mask; | ||
831 | if (invert) | ||
832 | val = max - val; | ||
833 | ucontrol->value.integer.value[0] = val; | ||
834 | |||
835 | return 0; | ||
836 | } | ||
837 | EXPORT_SYMBOL_GPL(snd_soc_get_xr_sx); | ||
838 | |||
839 | /** | ||
840 | * snd_soc_put_xr_sx - signed multi register get callback | ||
841 | * @kcontrol: mreg control | ||
842 | * @ucontrol: control element information | ||
843 | * | ||
844 | * Callback to set the value of a control that can span | ||
845 | * multiple codec registers which together forms a single | ||
846 | * signed value in a MSB/LSB manner. The control supports | ||
847 | * specifying total no of bits used to allow for bitfields | ||
848 | * across the multiple codec registers. | ||
849 | * | ||
850 | * Returns 0 for success. | ||
851 | */ | ||
852 | int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, | ||
853 | struct snd_ctl_elem_value *ucontrol) | ||
854 | { | ||
855 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
856 | struct soc_mreg_control *mc = | ||
857 | (struct soc_mreg_control *)kcontrol->private_value; | ||
858 | unsigned int regbase = mc->regbase; | ||
859 | unsigned int regcount = mc->regcount; | ||
860 | unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; | ||
861 | unsigned int regwmask = (1<<regwshift)-1; | ||
862 | unsigned int invert = mc->invert; | ||
863 | unsigned long mask = (1UL<<mc->nbits)-1; | ||
864 | long max = mc->max; | ||
865 | long val = ucontrol->value.integer.value[0]; | ||
866 | unsigned int i, regval, regmask; | ||
867 | int err; | ||
868 | |||
869 | if (invert) | ||
870 | val = max - val; | ||
871 | val &= mask; | ||
872 | for (i = 0; i < regcount; i++) { | ||
873 | regval = (val >> (regwshift*(regcount-i-1))) & regwmask; | ||
874 | regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; | ||
875 | err = snd_soc_component_update_bits(component, regbase+i, | ||
876 | regmask, regval); | ||
877 | if (err < 0) | ||
878 | return err; | ||
879 | } | ||
880 | |||
881 | return 0; | ||
882 | } | ||
883 | EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx); | ||
884 | |||
885 | /** | ||
886 | * snd_soc_get_strobe - strobe get callback | ||
887 | * @kcontrol: mixer control | ||
888 | * @ucontrol: control element information | ||
889 | * | ||
890 | * Callback get the value of a strobe mixer control. | ||
891 | * | ||
892 | * Returns 0 for success. | ||
893 | */ | ||
894 | int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, | ||
895 | struct snd_ctl_elem_value *ucontrol) | ||
896 | { | ||
897 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
898 | struct soc_mixer_control *mc = | ||
899 | (struct soc_mixer_control *)kcontrol->private_value; | ||
900 | unsigned int reg = mc->reg; | ||
901 | unsigned int shift = mc->shift; | ||
902 | unsigned int mask = 1 << shift; | ||
903 | unsigned int invert = mc->invert != 0; | ||
904 | unsigned int val; | ||
905 | int ret; | ||
906 | |||
907 | ret = snd_soc_component_read(component, reg, &val); | ||
908 | if (ret) | ||
909 | return ret; | ||
910 | |||
911 | val &= mask; | ||
912 | |||
913 | if (shift != 0 && val != 0) | ||
914 | val = val >> shift; | ||
915 | ucontrol->value.enumerated.item[0] = val ^ invert; | ||
916 | |||
917 | return 0; | ||
918 | } | ||
919 | EXPORT_SYMBOL_GPL(snd_soc_get_strobe); | ||
920 | |||
921 | /** | ||
922 | * snd_soc_put_strobe - strobe put callback | ||
923 | * @kcontrol: mixer control | ||
924 | * @ucontrol: control element information | ||
925 | * | ||
926 | * Callback strobe a register bit to high then low (or the inverse) | ||
927 | * in one pass of a single mixer enum control. | ||
928 | * | ||
929 | * Returns 1 for success. | ||
930 | */ | ||
931 | int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, | ||
932 | struct snd_ctl_elem_value *ucontrol) | ||
933 | { | ||
934 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
935 | struct soc_mixer_control *mc = | ||
936 | (struct soc_mixer_control *)kcontrol->private_value; | ||
937 | unsigned int reg = mc->reg; | ||
938 | unsigned int shift = mc->shift; | ||
939 | unsigned int mask = 1 << shift; | ||
940 | unsigned int invert = mc->invert != 0; | ||
941 | unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; | ||
942 | unsigned int val1 = (strobe ^ invert) ? mask : 0; | ||
943 | unsigned int val2 = (strobe ^ invert) ? 0 : mask; | ||
944 | int err; | ||
945 | |||
946 | err = snd_soc_component_update_bits(component, reg, mask, val1); | ||
947 | if (err < 0) | ||
948 | return err; | ||
949 | |||
950 | return snd_soc_component_update_bits(component, reg, mask, val2); | ||
951 | } | ||
952 | EXPORT_SYMBOL_GPL(snd_soc_put_strobe); | ||