• Home
  • Raw
  • Download

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 :-
26 #include <sound/soc-dpcm.h>
30 * snd_soc_info_enum_double - enumerated double mixer info callback
34 * Callback to provide information about a double enumerated
42 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_info_enum_double()
44 return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2, in snd_soc_info_enum_double()
45 e->items, e->texts); in snd_soc_info_enum_double()
50 * snd_soc_get_enum_double - enumerated double mixer get callback
54 * Callback to get the value of a double enumerated mixer.
62 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_get_enum_double()
66 reg_val = snd_soc_component_read(component, e->reg); in snd_soc_get_enum_double()
67 val = (reg_val >> e->shift_l) & e->mask; in snd_soc_get_enum_double()
69 ucontrol->value.enumerated.item[0] = item; in snd_soc_get_enum_double()
70 if (e->shift_l != e->shift_r) { in snd_soc_get_enum_double()
71 val = (reg_val >> e->shift_r) & e->mask; in snd_soc_get_enum_double()
73 ucontrol->value.enumerated.item[1] = item; in snd_soc_get_enum_double()
81 * snd_soc_put_enum_double - enumerated double mixer put callback
85 * Callback to set the value of a double enumerated mixer.
93 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in snd_soc_put_enum_double()
94 unsigned int *item = ucontrol->value.enumerated.item; in snd_soc_put_enum_double()
98 if (item[0] >= e->items) in snd_soc_put_enum_double()
99 return -EINVAL; in snd_soc_put_enum_double()
100 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; in snd_soc_put_enum_double()
101 mask = e->mask << e->shift_l; in snd_soc_put_enum_double()
102 if (e->shift_l != e->shift_r) { in snd_soc_put_enum_double()
103 if (item[1] >= e->items) in snd_soc_put_enum_double()
104 return -EINVAL; in snd_soc_put_enum_double()
105 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r; in snd_soc_put_enum_double()
106 mask |= e->mask << e->shift_r; in snd_soc_put_enum_double()
109 return snd_soc_component_update_bits(component, e->reg, mask, val); in snd_soc_put_enum_double()
114 * snd_soc_read_signed - Read a codec register and interpret as signed value
124 * the given registervalue into a signed integer if sign_bit is non-zero.
143 /* non-negative number */ in snd_soc_read_signed()
152 * The register most probably does not contain a full-sized int. in snd_soc_read_signed()
154 * representation which has to be translated into a full-sized int. in snd_soc_read_signed()
155 * This is done by filling up all bits above the sign-bit. in snd_soc_read_signed()
157 ret |= ~((int)(BIT(sign_bit) - 1)); in snd_soc_read_signed()
165 * snd_soc_info_volsw - single mixer info callback
169 * Callback to provide information about a single mixer control, or a double
178 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw()
182 max = uinfo->value.integer.max = mc->max - mc->min; in snd_soc_info_volsw()
183 if (mc->platform_max && mc->platform_max < max) in snd_soc_info_volsw()
184 max = mc->platform_max; in snd_soc_info_volsw()
188 vol_string = strstr(kcontrol->id.name, " Volume"); in snd_soc_info_volsw()
190 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw()
192 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_soc_info_volsw()
194 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw()
197 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw()
198 uinfo->value.integer.min = 0; in snd_soc_info_volsw()
199 uinfo->value.integer.max = max; in snd_soc_info_volsw()
206 * snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls
210 * Callback to provide information about a single mixer control, or a double
212 * have a range that represents both positive and negative values either side
222 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw_sx()
225 if (mc->platform_max) in snd_soc_info_volsw_sx()
226 max = mc->platform_max; in snd_soc_info_volsw_sx()
228 max = mc->max; in snd_soc_info_volsw_sx()
230 if (max == 1 && !strstr(kcontrol->id.name, " Volume")) in snd_soc_info_volsw_sx()
231 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_soc_info_volsw_sx()
233 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw_sx()
235 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw_sx()
236 uinfo->value.integer.min = 0; in snd_soc_info_volsw_sx()
237 uinfo->value.integer.max = max; in snd_soc_info_volsw_sx()
244 * snd_soc_get_volsw - single mixer get callback
248 * Callback to get the value of a single mixer control, or a double mixer
258 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw()
259 unsigned int reg = mc->reg; in snd_soc_get_volsw()
260 unsigned int reg2 = mc->rreg; in snd_soc_get_volsw()
261 unsigned int shift = mc->shift; in snd_soc_get_volsw()
262 unsigned int rshift = mc->rshift; in snd_soc_get_volsw()
263 int max = mc->max; in snd_soc_get_volsw()
264 int min = mc->min; in snd_soc_get_volsw()
265 int sign_bit = mc->sign_bit; in snd_soc_get_volsw()
266 unsigned int mask = (1ULL << fls(max)) - 1; in snd_soc_get_volsw()
267 unsigned int invert = mc->invert; in snd_soc_get_volsw()
272 mask = BIT(sign_bit + 1) - 1; in snd_soc_get_volsw()
278 ucontrol->value.integer.value[0] = val - min; in snd_soc_get_volsw()
280 ucontrol->value.integer.value[0] = in snd_soc_get_volsw()
281 max - ucontrol->value.integer.value[0]; in snd_soc_get_volsw()
293 ucontrol->value.integer.value[1] = val - min; in snd_soc_get_volsw()
295 ucontrol->value.integer.value[1] = in snd_soc_get_volsw()
296 max - ucontrol->value.integer.value[1]; in snd_soc_get_volsw()
304 * snd_soc_put_volsw - single mixer put callback
308 * Callback to set the value of a single mixer control, or a double mixer
318 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw()
319 unsigned int reg = mc->reg; in snd_soc_put_volsw()
320 unsigned int reg2 = mc->rreg; in snd_soc_put_volsw()
321 unsigned int shift = mc->shift; in snd_soc_put_volsw()
322 unsigned int rshift = mc->rshift; in snd_soc_put_volsw()
323 int max = mc->max; in snd_soc_put_volsw()
324 int min = mc->min; in snd_soc_put_volsw()
325 unsigned int sign_bit = mc->sign_bit; in snd_soc_put_volsw()
326 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_put_volsw()
327 unsigned int invert = mc->invert; in snd_soc_put_volsw()
334 mask = BIT(sign_bit + 1) - 1; in snd_soc_put_volsw()
336 if (ucontrol->value.integer.value[0] < 0) in snd_soc_put_volsw()
337 return -EINVAL; in snd_soc_put_volsw()
338 val = ucontrol->value.integer.value[0]; in snd_soc_put_volsw()
339 if (mc->platform_max && val > mc->platform_max) in snd_soc_put_volsw()
340 return -EINVAL; in snd_soc_put_volsw()
341 if (val > max - min) in snd_soc_put_volsw()
342 return -EINVAL; in snd_soc_put_volsw()
345 val = max - val; in snd_soc_put_volsw()
349 if (ucontrol->value.integer.value[1] < 0) in snd_soc_put_volsw()
350 return -EINVAL; in snd_soc_put_volsw()
351 val2 = ucontrol->value.integer.value[1]; in snd_soc_put_volsw()
352 if (mc->platform_max && val2 > mc->platform_max) in snd_soc_put_volsw()
353 return -EINVAL; in snd_soc_put_volsw()
354 if (val2 > max - min) in snd_soc_put_volsw()
355 return -EINVAL; in snd_soc_put_volsw()
358 val2 = max - val2; in snd_soc_put_volsw()
386 * snd_soc_get_volsw_sx - single mixer get callback
390 * Callback to get the value of a single mixer control, or a double mixer
400 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_sx()
401 unsigned int reg = mc->reg; in snd_soc_get_volsw_sx()
402 unsigned int reg2 = mc->rreg; in snd_soc_get_volsw_sx()
403 unsigned int shift = mc->shift; in snd_soc_get_volsw_sx()
404 unsigned int rshift = mc->rshift; in snd_soc_get_volsw_sx()
405 int max = mc->max; in snd_soc_get_volsw_sx()
406 int min = mc->min; in snd_soc_get_volsw_sx()
407 unsigned int mask = (1U << (fls(min + max) - 1)) - 1; in snd_soc_get_volsw_sx()
411 ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; in snd_soc_get_volsw_sx()
415 val = ((val >> rshift) - min) & mask; in snd_soc_get_volsw_sx()
416 ucontrol->value.integer.value[1] = val; in snd_soc_get_volsw_sx()
424 * snd_soc_put_volsw_sx - double mixer set callback
428 * Callback to set the value of a double mixer control that spans 2 registers.
437 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_sx()
439 unsigned int reg = mc->reg; in snd_soc_put_volsw_sx()
440 unsigned int reg2 = mc->rreg; in snd_soc_put_volsw_sx()
441 unsigned int shift = mc->shift; in snd_soc_put_volsw_sx()
442 unsigned int rshift = mc->rshift; in snd_soc_put_volsw_sx()
443 int max = mc->max; in snd_soc_put_volsw_sx()
444 int min = mc->min; in snd_soc_put_volsw_sx()
445 unsigned int mask = (1U << (fls(min + max) - 1)) - 1; in snd_soc_put_volsw_sx()
450 if (ucontrol->value.integer.value[0] < 0) in snd_soc_put_volsw_sx()
451 return -EINVAL; in snd_soc_put_volsw_sx()
452 val = ucontrol->value.integer.value[0]; in snd_soc_put_volsw_sx()
453 if (mc->platform_max && val > mc->platform_max) in snd_soc_put_volsw_sx()
454 return -EINVAL; in snd_soc_put_volsw_sx()
456 return -EINVAL; in snd_soc_put_volsw_sx()
467 unsigned int val2 = ucontrol->value.integer.value[1]; in snd_soc_put_volsw_sx()
469 if (mc->platform_max && val2 > mc->platform_max) in snd_soc_put_volsw_sx()
470 return -EINVAL; in snd_soc_put_volsw_sx()
472 return -EINVAL; in snd_soc_put_volsw_sx()
491 * snd_soc_info_volsw_range - single mixer info callback with range.
495 * Callback to provide information, within a range, about a single
504 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw_range()
507 max = mc->max - mc->min; in snd_soc_info_volsw_range()
508 if (mc->platform_max && mc->platform_max < max) in snd_soc_info_volsw_range()
509 max = mc->platform_max; in snd_soc_info_volsw_range()
511 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw_range()
512 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw_range()
513 uinfo->value.integer.min = 0; in snd_soc_info_volsw_range()
514 uinfo->value.integer.max = max; in snd_soc_info_volsw_range()
521 * snd_soc_put_volsw_range - single mixer put value callback with range.
525 * Callback to set the value, within a range, for a single mixer control.
533 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_range()
535 unsigned int reg = mc->reg; in snd_soc_put_volsw_range()
536 unsigned int rreg = mc->rreg; in snd_soc_put_volsw_range()
537 unsigned int shift = mc->shift; in snd_soc_put_volsw_range()
538 int min = mc->min; in snd_soc_put_volsw_range()
539 int max = mc->max; in snd_soc_put_volsw_range()
540 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_put_volsw_range()
541 unsigned int invert = mc->invert; in snd_soc_put_volsw_range()
545 tmp = ucontrol->value.integer.value[0]; in snd_soc_put_volsw_range()
547 return -EINVAL; in snd_soc_put_volsw_range()
548 if (mc->platform_max && tmp > mc->platform_max) in snd_soc_put_volsw_range()
549 return -EINVAL; in snd_soc_put_volsw_range()
550 if (tmp > mc->max - mc->min) in snd_soc_put_volsw_range()
551 return -EINVAL; in snd_soc_put_volsw_range()
554 val = (max - ucontrol->value.integer.value[0]) & mask; in snd_soc_put_volsw_range()
556 val = ((ucontrol->value.integer.value[0] + min) & mask); in snd_soc_put_volsw_range()
566 tmp = ucontrol->value.integer.value[1]; in snd_soc_put_volsw_range()
568 return -EINVAL; in snd_soc_put_volsw_range()
569 if (mc->platform_max && tmp > mc->platform_max) in snd_soc_put_volsw_range()
570 return -EINVAL; in snd_soc_put_volsw_range()
571 if (tmp > mc->max - mc->min) in snd_soc_put_volsw_range()
572 return -EINVAL; in snd_soc_put_volsw_range()
575 val = (max - ucontrol->value.integer.value[1]) & mask; in snd_soc_put_volsw_range()
577 val = ((ucontrol->value.integer.value[1] + min) & mask); in snd_soc_put_volsw_range()
594 * snd_soc_get_volsw_range - single mixer get callback with range
598 * Callback to get the value, within a range, of a single mixer control.
607 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_range()
608 unsigned int reg = mc->reg; in snd_soc_get_volsw_range()
609 unsigned int rreg = mc->rreg; in snd_soc_get_volsw_range()
610 unsigned int shift = mc->shift; in snd_soc_get_volsw_range()
611 int min = mc->min; in snd_soc_get_volsw_range()
612 int max = mc->max; in snd_soc_get_volsw_range()
613 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_get_volsw_range()
614 unsigned int invert = mc->invert; in snd_soc_get_volsw_range()
618 ucontrol->value.integer.value[0] = (val >> shift) & mask; in snd_soc_get_volsw_range()
620 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
621 max - ucontrol->value.integer.value[0]; in snd_soc_get_volsw_range()
623 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
624 ucontrol->value.integer.value[0] - min; in snd_soc_get_volsw_range()
628 ucontrol->value.integer.value[1] = (val >> shift) & mask; in snd_soc_get_volsw_range()
630 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
631 max - ucontrol->value.integer.value[1]; in snd_soc_get_volsw_range()
633 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
634 ucontrol->value.integer.value[1] - min; in snd_soc_get_volsw_range()
642 * snd_soc_limit_volume - Set new limit to an existing volume control.
654 int ret = -EINVAL; in snd_soc_limit_volume()
658 return -EINVAL; in snd_soc_limit_volume()
662 struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; in snd_soc_limit_volume()
663 if (max <= mc->max - mc->min) { in snd_soc_limit_volume()
664 mc->platform_max = max; in snd_soc_limit_volume()
676 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_info()
678 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info()
679 uinfo->count = params->num_regs * component->val_bytes; in snd_soc_bytes_info()
689 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_get()
692 if (component->regmap) in snd_soc_bytes_get()
693 ret = regmap_raw_read(component->regmap, params->base, in snd_soc_bytes_get()
694 ucontrol->value.bytes.data, in snd_soc_bytes_get()
695 params->num_regs * component->val_bytes); in snd_soc_bytes_get()
697 ret = -EINVAL; in snd_soc_bytes_get()
700 if (ret == 0 && params->mask) { in snd_soc_bytes_get()
701 switch (component->val_bytes) { in snd_soc_bytes_get()
703 ucontrol->value.bytes.data[0] &= ~params->mask; in snd_soc_bytes_get()
706 ((u16 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
707 &= cpu_to_be16(~params->mask); in snd_soc_bytes_get()
710 ((u32 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
711 &= cpu_to_be32(~params->mask); in snd_soc_bytes_get()
714 return -EINVAL; in snd_soc_bytes_get()
726 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 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); in snd_soc_bytes_put()
738 return -ENOMEM; in snd_soc_bytes_put()
745 if (params->mask) { in snd_soc_bytes_put()
746 ret = regmap_read(component->regmap, params->base, &val); in snd_soc_bytes_put()
750 val &= params->mask; in snd_soc_bytes_put()
752 switch (component->val_bytes) { in snd_soc_bytes_put()
754 ((u8 *)data)[0] &= ~params->mask; in snd_soc_bytes_put()
758 mask = ~params->mask; in snd_soc_bytes_put()
759 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
766 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
774 mask = ~params->mask; in snd_soc_bytes_put()
775 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
782 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
790 ret = -EINVAL; in snd_soc_bytes_put()
795 ret = regmap_raw_write(component->regmap, params->base, in snd_soc_bytes_put()
808 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_info_ext()
810 ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info_ext()
811 ucontrol->count = params->max; in snd_soc_bytes_info_ext()
820 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_tlv_callback()
821 unsigned int count = size < params->max ? size : params->max; in snd_soc_bytes_tlv_callback()
822 int ret = -ENXIO; in snd_soc_bytes_tlv_callback()
826 if (params->get) in snd_soc_bytes_tlv_callback()
827 ret = params->get(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
830 if (params->put) in snd_soc_bytes_tlv_callback()
831 ret = params->put(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
839 * snd_soc_info_xr_sx - signed multi register info callback
853 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_info_xr_sx()
854 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_xr_sx()
855 uinfo->count = 1; in snd_soc_info_xr_sx()
856 uinfo->value.integer.min = mc->min; in snd_soc_info_xr_sx()
857 uinfo->value.integer.max = mc->max; in snd_soc_info_xr_sx()
864 * snd_soc_get_xr_sx - signed multi register get callback
881 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_get_xr_sx()
882 unsigned int regbase = mc->regbase; in snd_soc_get_xr_sx()
883 unsigned int regcount = mc->regcount; in snd_soc_get_xr_sx()
884 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_get_xr_sx()
885 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_get_xr_sx()
886 unsigned int invert = mc->invert; in snd_soc_get_xr_sx()
887 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_get_xr_sx()
888 long min = mc->min; in snd_soc_get_xr_sx()
889 long max = mc->max; in snd_soc_get_xr_sx()
895 val |= (regval & regwmask) << (regwshift*(regcount-i-1)); in snd_soc_get_xr_sx()
901 val = max - val; in snd_soc_get_xr_sx()
902 ucontrol->value.integer.value[0] = val; in snd_soc_get_xr_sx()
909 * snd_soc_put_xr_sx - signed multi register get callback
926 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_put_xr_sx()
927 unsigned int regbase = mc->regbase; in snd_soc_put_xr_sx()
928 unsigned int regcount = mc->regcount; in snd_soc_put_xr_sx()
929 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_put_xr_sx()
930 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_put_xr_sx()
931 unsigned int invert = mc->invert; in snd_soc_put_xr_sx()
932 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_put_xr_sx()
933 long max = mc->max; in snd_soc_put_xr_sx()
934 long val = ucontrol->value.integer.value[0]; in snd_soc_put_xr_sx()
938 if (val < mc->min || val > mc->max) in snd_soc_put_xr_sx()
939 return -EINVAL; in snd_soc_put_xr_sx()
941 val = max - val; in snd_soc_put_xr_sx()
944 unsigned int regval = (val >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
945 unsigned int regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
959 * snd_soc_get_strobe - strobe get callback
972 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_strobe()
973 unsigned int reg = mc->reg; in snd_soc_get_strobe()
974 unsigned int shift = mc->shift; in snd_soc_get_strobe()
976 unsigned int invert = mc->invert != 0; in snd_soc_get_strobe()
984 ucontrol->value.enumerated.item[0] = val ^ invert; in snd_soc_get_strobe()
991 * snd_soc_put_strobe - strobe put callback
1005 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_strobe()
1006 unsigned int reg = mc->reg; in snd_soc_put_strobe()
1007 unsigned int shift = mc->shift; in snd_soc_put_strobe()
1009 unsigned int invert = mc->invert != 0; in snd_soc_put_strobe()
1010 unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; in snd_soc_put_strobe()