Lines Matching +full:range +full:- +full:double

1 // SPDX-License-Identifier: GPL-2.0+
3 // soc-ops.c -- Generic ASoC operations
11 // with code, comments and ideas from :-
27 #include <sound/soc-dpcm.h>
31 * snd_soc_info_enum_double - enumerated double mixer info callback
35 * Callback to provide information about a double enumerated
43 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_info_enum_double()
45 return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2, in snd_soc_info_enum_double()
46 e->items, e->texts); in snd_soc_info_enum_double()
51 * snd_soc_get_enum_double - enumerated double mixer get callback
55 * Callback to get the value of a double enumerated mixer.
63 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_get_enum_double()
67 reg_val = snd_soc_component_read(component, e->reg); in snd_soc_get_enum_double()
68 val = (reg_val >> e->shift_l) & e->mask; in snd_soc_get_enum_double()
70 ucontrol->value.enumerated.item[0] = item; in snd_soc_get_enum_double()
71 if (e->shift_l != e->shift_r) { in snd_soc_get_enum_double()
72 val = (reg_val >> e->shift_r) & e->mask; in snd_soc_get_enum_double()
74 ucontrol->value.enumerated.item[1] = item; in snd_soc_get_enum_double()
82 * snd_soc_put_enum_double - enumerated double mixer put callback
86 * Callback to set the value of a double enumerated mixer.
94 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_put_enum_double()
95 unsigned int *item = ucontrol->value.enumerated.item; in snd_soc_put_enum_double()
99 if (item[0] >= e->items) in snd_soc_put_enum_double()
100 return -EINVAL; in snd_soc_put_enum_double()
101 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; in snd_soc_put_enum_double()
102 mask = e->mask << e->shift_l; in snd_soc_put_enum_double()
103 if (e->shift_l != e->shift_r) { in snd_soc_put_enum_double()
104 if (item[1] >= e->items) in snd_soc_put_enum_double()
105 return -EINVAL; in snd_soc_put_enum_double()
106 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; in snd_soc_put_enum_double()
107 mask |= e->mask << e->shift_r; in snd_soc_put_enum_double()
110 return snd_soc_component_update_bits(component, e->reg, mask, val); in snd_soc_put_enum_double()
115 * snd_soc_read_signed - Read a codec register and interpret as signed value
125 * the given registervalue into a signed integer if sign_bit is non-zero.
144 /* non-negative number */ in snd_soc_read_signed()
153 * The register most probably does not contain a full-sized int. in snd_soc_read_signed()
155 * representation which has to be translated into a full-sized int. in snd_soc_read_signed()
156 * This is done by filling up all bits above the sign-bit. in snd_soc_read_signed()
158 ret |= ~((int)(BIT(sign_bit) - 1)); in snd_soc_read_signed()
166 * snd_soc_info_volsw - single mixer info callback
170 * Callback to provide information about a single mixer control, or a double
179 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw()
183 max = uinfo->value.integer.max = mc->max - mc->min; in snd_soc_info_volsw()
184 if (mc->platform_max && mc->platform_max < max) in snd_soc_info_volsw()
185 max = mc->platform_max; in snd_soc_info_volsw()
189 vol_string = strstr(kcontrol->id.name, " Volume"); in snd_soc_info_volsw()
191 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw()
193 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_soc_info_volsw()
195 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw()
198 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw()
199 uinfo->value.integer.min = 0; in snd_soc_info_volsw()
200 uinfo->value.integer.max = max; in snd_soc_info_volsw()
207 * snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls
211 * Callback to provide information about a single mixer control, or a double
213 * have a range that represents both positive and negative values either side
223 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw_sx()
226 if (mc->platform_max) in snd_soc_info_volsw_sx()
227 max = mc->platform_max; in snd_soc_info_volsw_sx()
229 max = mc->max; in snd_soc_info_volsw_sx()
231 if (max == 1 && !strstr(kcontrol->id.name, " Volume")) in snd_soc_info_volsw_sx()
232 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_soc_info_volsw_sx()
234 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw_sx()
236 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw_sx()
237 uinfo->value.integer.min = 0; in snd_soc_info_volsw_sx()
238 uinfo->value.integer.max = max; in snd_soc_info_volsw_sx()
245 * snd_soc_get_volsw - single mixer get callback
249 * Callback to get the value of a single mixer control, or a double mixer
259 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw()
260 unsigned int reg = mc->reg; in snd_soc_get_volsw()
261 unsigned int reg2 = mc->rreg; in snd_soc_get_volsw()
262 unsigned int shift = mc->shift; in snd_soc_get_volsw()
263 unsigned int rshift = mc->rshift; in snd_soc_get_volsw()
264 int max = mc->max; in snd_soc_get_volsw()
265 int min = mc->min; in snd_soc_get_volsw()
266 int sign_bit = mc->sign_bit; in snd_soc_get_volsw()
267 unsigned int mask = (1ULL << fls(max)) - 1; in snd_soc_get_volsw()
268 unsigned int invert = mc->invert; in snd_soc_get_volsw()
273 mask = BIT(sign_bit + 1) - 1; in snd_soc_get_volsw()
279 ucontrol->value.integer.value[0] = val - min; in snd_soc_get_volsw()
281 ucontrol->value.integer.value[0] = in snd_soc_get_volsw()
282 max - ucontrol->value.integer.value[0]; in snd_soc_get_volsw()
294 ucontrol->value.integer.value[1] = val - min; in snd_soc_get_volsw()
296 ucontrol->value.integer.value[1] = in snd_soc_get_volsw()
297 max - ucontrol->value.integer.value[1]; in snd_soc_get_volsw()
305 * snd_soc_put_volsw - single mixer put callback
309 * Callback to set the value of a single mixer control, or a double mixer
319 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw()
320 unsigned int reg = mc->reg; in snd_soc_put_volsw()
321 unsigned int reg2 = mc->rreg; in snd_soc_put_volsw()
322 unsigned int shift = mc->shift; in snd_soc_put_volsw()
323 unsigned int rshift = mc->rshift; in snd_soc_put_volsw()
324 int max = mc->max; in snd_soc_put_volsw()
325 int min = mc->min; in snd_soc_put_volsw()
326 unsigned int sign_bit = mc->sign_bit; in snd_soc_put_volsw()
327 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_put_volsw()
328 unsigned int invert = mc->invert; in snd_soc_put_volsw()
335 mask = BIT(sign_bit + 1) - 1; in snd_soc_put_volsw()
337 if (ucontrol->value.integer.value[0] < 0) in snd_soc_put_volsw()
338 return -EINVAL; in snd_soc_put_volsw()
339 val = ucontrol->value.integer.value[0]; in snd_soc_put_volsw()
340 if (mc->platform_max && val > mc->platform_max) in snd_soc_put_volsw()
341 return -EINVAL; in snd_soc_put_volsw()
342 if (val > max - min) in snd_soc_put_volsw()
343 return -EINVAL; in snd_soc_put_volsw()
346 val = max - val; in snd_soc_put_volsw()
350 if (ucontrol->value.integer.value[1] < 0) in snd_soc_put_volsw()
351 return -EINVAL; in snd_soc_put_volsw()
352 val2 = ucontrol->value.integer.value[1]; in snd_soc_put_volsw()
353 if (mc->platform_max && val2 > mc->platform_max) in snd_soc_put_volsw()
354 return -EINVAL; in snd_soc_put_volsw()
355 if (val2 > max - min) in snd_soc_put_volsw()
356 return -EINVAL; in snd_soc_put_volsw()
359 val2 = max - val2; in snd_soc_put_volsw()
387 * snd_soc_get_volsw_sx - single mixer get callback
391 * Callback to get the value of a single mixer control, or a double mixer
401 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_sx()
402 unsigned int reg = mc->reg; in snd_soc_get_volsw_sx()
403 unsigned int reg2 = mc->rreg; in snd_soc_get_volsw_sx()
404 unsigned int shift = mc->shift; in snd_soc_get_volsw_sx()
405 unsigned int rshift = mc->rshift; in snd_soc_get_volsw_sx()
406 int max = mc->max; in snd_soc_get_volsw_sx()
407 int min = mc->min; in snd_soc_get_volsw_sx()
408 unsigned int mask = (1U << (fls(min + max) - 1)) - 1; in snd_soc_get_volsw_sx()
412 ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; in snd_soc_get_volsw_sx()
416 val = ((val >> rshift) - min) & mask; in snd_soc_get_volsw_sx()
417 ucontrol->value.integer.value[1] = val; in snd_soc_get_volsw_sx()
425 * snd_soc_put_volsw_sx - double mixer set callback
429 * Callback to set the value of a double mixer control that spans 2 registers.
438 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_sx()
440 unsigned int reg = mc->reg; in snd_soc_put_volsw_sx()
441 unsigned int reg2 = mc->rreg; in snd_soc_put_volsw_sx()
442 unsigned int shift = mc->shift; in snd_soc_put_volsw_sx()
443 unsigned int rshift = mc->rshift; in snd_soc_put_volsw_sx()
444 int max = mc->max; in snd_soc_put_volsw_sx()
445 int min = mc->min; in snd_soc_put_volsw_sx()
446 unsigned int mask = (1U << (fls(min + max) - 1)) - 1; in snd_soc_put_volsw_sx()
451 if (ucontrol->value.integer.value[0] < 0) in snd_soc_put_volsw_sx()
452 return -EINVAL; in snd_soc_put_volsw_sx()
453 val = ucontrol->value.integer.value[0]; in snd_soc_put_volsw_sx()
454 if (mc->platform_max && val > mc->platform_max) in snd_soc_put_volsw_sx()
455 return -EINVAL; in snd_soc_put_volsw_sx()
457 return -EINVAL; in snd_soc_put_volsw_sx()
468 unsigned int val2 = ucontrol->value.integer.value[1]; in snd_soc_put_volsw_sx()
470 if (mc->platform_max && val2 > mc->platform_max) in snd_soc_put_volsw_sx()
471 return -EINVAL; in snd_soc_put_volsw_sx()
473 return -EINVAL; in snd_soc_put_volsw_sx()
492 * snd_soc_info_volsw_range - single mixer info callback with range.
496 * Callback to provide information, within a range, about a single
505 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw_range()
508 max = mc->max - mc->min; in snd_soc_info_volsw_range()
509 if (mc->platform_max && mc->platform_max < max) in snd_soc_info_volsw_range()
510 max = mc->platform_max; in snd_soc_info_volsw_range()
512 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw_range()
513 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw_range()
514 uinfo->value.integer.min = 0; in snd_soc_info_volsw_range()
515 uinfo->value.integer.max = max; in snd_soc_info_volsw_range()
522 * snd_soc_put_volsw_range - single mixer put value callback with range.
526 * Callback to set the value, within a range, for a single mixer control.
534 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_range()
536 unsigned int reg = mc->reg; in snd_soc_put_volsw_range()
537 unsigned int rreg = mc->rreg; in snd_soc_put_volsw_range()
538 unsigned int shift = mc->shift; in snd_soc_put_volsw_range()
539 int min = mc->min; in snd_soc_put_volsw_range()
540 int max = mc->max; in snd_soc_put_volsw_range()
541 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_put_volsw_range()
542 unsigned int invert = mc->invert; in snd_soc_put_volsw_range()
546 tmp = ucontrol->value.integer.value[0]; in snd_soc_put_volsw_range()
548 return -EINVAL; in snd_soc_put_volsw_range()
549 if (mc->platform_max && tmp > mc->platform_max) in snd_soc_put_volsw_range()
550 return -EINVAL; in snd_soc_put_volsw_range()
551 if (tmp > mc->max - mc->min) in snd_soc_put_volsw_range()
552 return -EINVAL; in snd_soc_put_volsw_range()
555 val = (max - ucontrol->value.integer.value[0]) & mask; in snd_soc_put_volsw_range()
557 val = ((ucontrol->value.integer.value[0] + min) & mask); in snd_soc_put_volsw_range()
567 tmp = ucontrol->value.integer.value[1]; in snd_soc_put_volsw_range()
569 return -EINVAL; in snd_soc_put_volsw_range()
570 if (mc->platform_max && tmp > mc->platform_max) in snd_soc_put_volsw_range()
571 return -EINVAL; in snd_soc_put_volsw_range()
572 if (tmp > mc->max - mc->min) in snd_soc_put_volsw_range()
573 return -EINVAL; in snd_soc_put_volsw_range()
576 val = (max - ucontrol->value.integer.value[1]) & mask; in snd_soc_put_volsw_range()
578 val = ((ucontrol->value.integer.value[1] + min) & mask); in snd_soc_put_volsw_range()
595 * snd_soc_get_volsw_range - single mixer get callback with range
599 * Callback to get the value, within a range, of a single mixer control.
608 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_range()
609 unsigned int reg = mc->reg; in snd_soc_get_volsw_range()
610 unsigned int rreg = mc->rreg; in snd_soc_get_volsw_range()
611 unsigned int shift = mc->shift; in snd_soc_get_volsw_range()
612 int min = mc->min; in snd_soc_get_volsw_range()
613 int max = mc->max; in snd_soc_get_volsw_range()
614 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_get_volsw_range()
615 unsigned int invert = mc->invert; in snd_soc_get_volsw_range()
619 ucontrol->value.integer.value[0] = (val >> shift) & mask; in snd_soc_get_volsw_range()
621 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
622 max - ucontrol->value.integer.value[0]; in snd_soc_get_volsw_range()
624 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
625 ucontrol->value.integer.value[0] - min; in snd_soc_get_volsw_range()
629 ucontrol->value.integer.value[1] = (val >> shift) & mask; in snd_soc_get_volsw_range()
631 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
632 max - ucontrol->value.integer.value[1]; in snd_soc_get_volsw_range()
634 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
635 ucontrol->value.integer.value[1] - min; in snd_soc_get_volsw_range()
643 * snd_soc_limit_volume - Set new limit to an existing volume control.
655 int ret = -EINVAL; in snd_soc_limit_volume()
659 return -EINVAL; in snd_soc_limit_volume()
663 struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; in snd_soc_limit_volume()
664 if (max <= mc->max - mc->min) { in snd_soc_limit_volume()
665 mc->platform_max = max; in snd_soc_limit_volume()
677 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_info()
679 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info()
680 uinfo->count = params->num_regs * component->val_bytes; in snd_soc_bytes_info()
690 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_get()
693 if (component->regmap) in snd_soc_bytes_get()
694 ret = regmap_raw_read(component->regmap, params->base, in snd_soc_bytes_get()
695 ucontrol->value.bytes.data, in snd_soc_bytes_get()
696 params->num_regs * component->val_bytes); in snd_soc_bytes_get()
698 ret = -EINVAL; in snd_soc_bytes_get()
701 if (ret == 0 && params->mask) { in snd_soc_bytes_get()
702 switch (component->val_bytes) { in snd_soc_bytes_get()
704 ucontrol->value.bytes.data[0] &= ~params->mask; in snd_soc_bytes_get()
707 ((u16 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
708 &= cpu_to_be16(~params->mask); in snd_soc_bytes_get()
711 ((u32 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
712 &= cpu_to_be32(~params->mask); in snd_soc_bytes_get()
715 return -EINVAL; in snd_soc_bytes_get()
727 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_put()
731 if (!component->regmap || !params->num_regs) in snd_soc_bytes_put()
732 return -EINVAL; in snd_soc_bytes_put()
734 len = params->num_regs * component->val_bytes; in snd_soc_bytes_put()
736 void *data __free(kfree) = kmemdup(ucontrol->value.bytes.data, len, in snd_soc_bytes_put()
739 return -ENOMEM; in snd_soc_bytes_put()
746 if (params->mask) { in snd_soc_bytes_put()
747 ret = regmap_read(component->regmap, params->base, &val); in snd_soc_bytes_put()
751 val &= params->mask; in snd_soc_bytes_put()
753 switch (component->val_bytes) { in snd_soc_bytes_put()
755 ((u8 *)data)[0] &= ~params->mask; in snd_soc_bytes_put()
759 mask = ~params->mask; in snd_soc_bytes_put()
760 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
767 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
775 mask = ~params->mask; in snd_soc_bytes_put()
776 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
783 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
791 return -EINVAL; in snd_soc_bytes_put()
795 return regmap_raw_write(component->regmap, params->base, data, len); in snd_soc_bytes_put()
802 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_info_ext()
804 ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info_ext()
805 ucontrol->count = params->max; in snd_soc_bytes_info_ext()
814 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_tlv_callback()
815 unsigned int count = size < params->max ? size : params->max; in snd_soc_bytes_tlv_callback()
816 int ret = -ENXIO; in snd_soc_bytes_tlv_callback()
820 if (params->get) in snd_soc_bytes_tlv_callback()
821 ret = params->get(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
824 if (params->put) in snd_soc_bytes_tlv_callback()
825 ret = params->put(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
833 * snd_soc_info_xr_sx - signed multi register info callback
847 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_info_xr_sx()
848 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_xr_sx()
849 uinfo->count = 1; in snd_soc_info_xr_sx()
850 uinfo->value.integer.min = mc->min; in snd_soc_info_xr_sx()
851 uinfo->value.integer.max = mc->max; in snd_soc_info_xr_sx()
858 * snd_soc_get_xr_sx - signed multi register get callback
875 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_get_xr_sx()
876 unsigned int regbase = mc->regbase; in snd_soc_get_xr_sx()
877 unsigned int regcount = mc->regcount; in snd_soc_get_xr_sx()
878 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_get_xr_sx()
879 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_get_xr_sx()
880 unsigned int invert = mc->invert; in snd_soc_get_xr_sx()
881 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_get_xr_sx()
882 long min = mc->min; in snd_soc_get_xr_sx()
883 long max = mc->max; in snd_soc_get_xr_sx()
889 val |= (regval & regwmask) << (regwshift*(regcount-i-1)); in snd_soc_get_xr_sx()
895 val = max - val; in snd_soc_get_xr_sx()
896 ucontrol->value.integer.value[0] = val; in snd_soc_get_xr_sx()
903 * snd_soc_put_xr_sx - signed multi register get callback
920 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_put_xr_sx()
921 unsigned int regbase = mc->regbase; in snd_soc_put_xr_sx()
922 unsigned int regcount = mc->regcount; in snd_soc_put_xr_sx()
923 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_put_xr_sx()
924 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_put_xr_sx()
925 unsigned int invert = mc->invert; in snd_soc_put_xr_sx()
926 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_put_xr_sx()
927 long max = mc->max; in snd_soc_put_xr_sx()
928 long val = ucontrol->value.integer.value[0]; in snd_soc_put_xr_sx()
932 if (val < mc->min || val > mc->max) in snd_soc_put_xr_sx()
933 return -EINVAL; in snd_soc_put_xr_sx()
935 val = max - val; in snd_soc_put_xr_sx()
938 unsigned int regval = (val >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
939 unsigned int regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
953 * snd_soc_get_strobe - strobe get callback
966 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_strobe()
967 unsigned int reg = mc->reg; in snd_soc_get_strobe()
968 unsigned int shift = mc->shift; in snd_soc_get_strobe()
970 unsigned int invert = mc->invert != 0; in snd_soc_get_strobe()
978 ucontrol->value.enumerated.item[0] = val ^ invert; in snd_soc_get_strobe()
985 * snd_soc_put_strobe - strobe put callback
999 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_strobe()
1000 unsigned int reg = mc->reg; in snd_soc_put_strobe()
1001 unsigned int shift = mc->shift; in snd_soc_put_strobe()
1003 unsigned int invert = mc->invert != 0; in snd_soc_put_strobe()
1004 unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; in snd_soc_put_strobe()