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