• Home
  • Raw
  • Download

Lines Matching +full:data +full:- +full:shift

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
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
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
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
119 * @shift: Right shift of register value
124 * by 'shift' bits and masked with the given 'mask'. Afterwards it translates
125 * the given registervalue into a signed integer if sign_bit is non-zero.
130 unsigned int reg, unsigned int mask, unsigned int shift, in snd_soc_read_signed() argument
137 val = (val >> shift) & mask; in snd_soc_read_signed()
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
179 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw()
182 if (!mc->platform_max) in snd_soc_info_volsw()
183 mc->platform_max = mc->max; in snd_soc_info_volsw()
184 platform_max = mc->platform_max; in snd_soc_info_volsw()
186 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) in snd_soc_info_volsw()
187 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in snd_soc_info_volsw()
189 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw()
191 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw()
192 uinfo->value.integer.min = 0; in snd_soc_info_volsw()
193 uinfo->value.integer.max = platform_max - mc->min; in snd_soc_info_volsw()
199 * snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls
214 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw_sx()
220 uinfo->value.integer.max += mc->min; in snd_soc_info_volsw_sx()
227 * snd_soc_get_volsw - single mixer get callback
241 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw()
242 unsigned int reg = mc->reg; in snd_soc_get_volsw()
243 unsigned int reg2 = mc->rreg; in snd_soc_get_volsw()
244 unsigned int shift = mc->shift; in snd_soc_get_volsw() local
245 unsigned int rshift = mc->rshift; in snd_soc_get_volsw()
246 int max = mc->max; in snd_soc_get_volsw()
247 int min = mc->min; in snd_soc_get_volsw()
248 int sign_bit = mc->sign_bit; in snd_soc_get_volsw()
249 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_get_volsw()
250 unsigned int invert = mc->invert; in snd_soc_get_volsw()
255 mask = BIT(sign_bit + 1) - 1; in snd_soc_get_volsw()
257 ret = snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); in snd_soc_get_volsw()
261 ucontrol->value.integer.value[0] = val - min; in snd_soc_get_volsw()
263 ucontrol->value.integer.value[0] = in snd_soc_get_volsw()
264 max - ucontrol->value.integer.value[0]; in snd_soc_get_volsw()
271 ret = snd_soc_read_signed(component, reg2, mask, shift, in snd_soc_get_volsw()
276 ucontrol->value.integer.value[1] = val - min; in snd_soc_get_volsw()
278 ucontrol->value.integer.value[1] = in snd_soc_get_volsw()
279 max - ucontrol->value.integer.value[1]; in snd_soc_get_volsw()
287 * snd_soc_put_volsw - single mixer put callback
301 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw()
302 unsigned int reg = mc->reg; in snd_soc_put_volsw()
303 unsigned int reg2 = mc->rreg; in snd_soc_put_volsw()
304 unsigned int shift = mc->shift; in snd_soc_put_volsw() local
305 unsigned int rshift = mc->rshift; in snd_soc_put_volsw()
306 int max = mc->max; in snd_soc_put_volsw()
307 int min = mc->min; in snd_soc_put_volsw()
308 unsigned int sign_bit = mc->sign_bit; in snd_soc_put_volsw()
309 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_put_volsw()
310 unsigned int invert = mc->invert; in snd_soc_put_volsw()
317 mask = BIT(sign_bit + 1) - 1; in snd_soc_put_volsw()
319 val = ((ucontrol->value.integer.value[0] + min) & mask); in snd_soc_put_volsw()
321 val = max - val; in snd_soc_put_volsw()
322 val_mask = mask << shift; in snd_soc_put_volsw()
323 val = val << shift; in snd_soc_put_volsw()
325 val2 = ((ucontrol->value.integer.value[1] + min) & mask); in snd_soc_put_volsw()
327 val2 = max - val2; in snd_soc_put_volsw()
332 val2 = val2 << shift; in snd_soc_put_volsw()
349 * snd_soc_get_volsw_sx - single mixer get callback
363 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_sx()
364 unsigned int reg = mc->reg; in snd_soc_get_volsw_sx()
365 unsigned int reg2 = mc->rreg; in snd_soc_get_volsw_sx()
366 unsigned int shift = mc->shift; in snd_soc_get_volsw_sx() local
367 unsigned int rshift = mc->rshift; in snd_soc_get_volsw_sx()
368 int max = mc->max; in snd_soc_get_volsw_sx()
369 int min = mc->min; in snd_soc_get_volsw_sx()
370 unsigned int mask = (1U << (fls(min + max) - 1)) - 1; in snd_soc_get_volsw_sx()
374 ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; in snd_soc_get_volsw_sx()
378 val = ((val >> rshift) - min) & mask; in snd_soc_get_volsw_sx()
379 ucontrol->value.integer.value[1] = val; in snd_soc_get_volsw_sx()
387 * snd_soc_put_volsw_sx - double mixer set callback
400 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_sx()
402 unsigned int reg = mc->reg; in snd_soc_put_volsw_sx()
403 unsigned int reg2 = mc->rreg; in snd_soc_put_volsw_sx()
404 unsigned int shift = mc->shift; in snd_soc_put_volsw_sx() local
405 unsigned int rshift = mc->rshift; in snd_soc_put_volsw_sx()
406 int max = mc->max; in snd_soc_put_volsw_sx()
407 int min = mc->min; in snd_soc_put_volsw_sx()
408 unsigned int mask = (1U << (fls(min + max) - 1)) - 1; in snd_soc_put_volsw_sx()
412 val_mask = mask << shift; in snd_soc_put_volsw_sx()
413 val = (ucontrol->value.integer.value[0] + min) & mask; in snd_soc_put_volsw_sx()
414 val = val << shift; in snd_soc_put_volsw_sx()
422 val2 = (ucontrol->value.integer.value[1] + min) & mask; in snd_soc_put_volsw_sx()
433 * snd_soc_info_volsw_range - single mixer info callback with range.
446 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw_range()
448 int min = mc->min; in snd_soc_info_volsw_range()
450 if (!mc->platform_max) in snd_soc_info_volsw_range()
451 mc->platform_max = mc->max; in snd_soc_info_volsw_range()
452 platform_max = mc->platform_max; in snd_soc_info_volsw_range()
454 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw_range()
455 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw_range()
456 uinfo->value.integer.min = 0; in snd_soc_info_volsw_range()
457 uinfo->value.integer.max = platform_max - min; in snd_soc_info_volsw_range()
464 * snd_soc_put_volsw_range - single mixer put value callback with range.
476 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_range()
478 unsigned int reg = mc->reg; in snd_soc_put_volsw_range()
479 unsigned int rreg = mc->rreg; in snd_soc_put_volsw_range()
480 unsigned int shift = mc->shift; in snd_soc_put_volsw_range() local
481 int min = mc->min; in snd_soc_put_volsw_range()
482 int max = mc->max; in snd_soc_put_volsw_range()
483 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_put_volsw_range()
484 unsigned int invert = mc->invert; in snd_soc_put_volsw_range()
489 val = (max - ucontrol->value.integer.value[0]) & mask; in snd_soc_put_volsw_range()
491 val = ((ucontrol->value.integer.value[0] + min) & mask); in snd_soc_put_volsw_range()
492 val_mask = mask << shift; in snd_soc_put_volsw_range()
493 val = val << shift; in snd_soc_put_volsw_range()
501 val = (max - ucontrol->value.integer.value[1]) & mask; in snd_soc_put_volsw_range()
503 val = ((ucontrol->value.integer.value[1] + min) & mask); in snd_soc_put_volsw_range()
504 val_mask = mask << shift; in snd_soc_put_volsw_range()
505 val = val << shift; in snd_soc_put_volsw_range()
516 * snd_soc_get_volsw_range - single mixer get callback with range
529 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_range()
530 unsigned int reg = mc->reg; in snd_soc_get_volsw_range()
531 unsigned int rreg = mc->rreg; in snd_soc_get_volsw_range()
532 unsigned int shift = mc->shift; in snd_soc_get_volsw_range() local
533 int min = mc->min; in snd_soc_get_volsw_range()
534 int max = mc->max; in snd_soc_get_volsw_range()
535 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_get_volsw_range()
536 unsigned int invert = mc->invert; in snd_soc_get_volsw_range()
540 ucontrol->value.integer.value[0] = (val >> shift) & mask; in snd_soc_get_volsw_range()
542 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
543 max - ucontrol->value.integer.value[0]; in snd_soc_get_volsw_range()
545 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
546 ucontrol->value.integer.value[0] - min; in snd_soc_get_volsw_range()
550 ucontrol->value.integer.value[1] = (val >> shift) & mask; in snd_soc_get_volsw_range()
552 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
553 max - ucontrol->value.integer.value[1]; in snd_soc_get_volsw_range()
555 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
556 ucontrol->value.integer.value[1] - min; in snd_soc_get_volsw_range()
564 * snd_soc_limit_volume - Set new limit to an existing volume control.
577 int ret = -EINVAL; in snd_soc_limit_volume()
581 return -EINVAL; in snd_soc_limit_volume()
585 mc = (struct soc_mixer_control *)kctl->private_value; in snd_soc_limit_volume()
586 if (max <= mc->max) { in snd_soc_limit_volume()
587 mc->platform_max = max; in snd_soc_limit_volume()
599 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_info()
601 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info()
602 uinfo->count = params->num_regs * component->val_bytes; in snd_soc_bytes_info()
612 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_get()
615 if (component->regmap) in snd_soc_bytes_get()
616 ret = regmap_raw_read(component->regmap, params->base, in snd_soc_bytes_get()
617 ucontrol->value.bytes.data, in snd_soc_bytes_get()
618 params->num_regs * component->val_bytes); in snd_soc_bytes_get()
620 ret = -EINVAL; in snd_soc_bytes_get()
622 /* Hide any masked bytes to ensure consistent data reporting */ in snd_soc_bytes_get()
623 if (ret == 0 && params->mask) { in snd_soc_bytes_get()
624 switch (component->val_bytes) { in snd_soc_bytes_get()
626 ucontrol->value.bytes.data[0] &= ~params->mask; in snd_soc_bytes_get()
629 ((u16 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
630 &= cpu_to_be16(~params->mask); in snd_soc_bytes_get()
633 ((u32 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
634 &= cpu_to_be32(~params->mask); in snd_soc_bytes_get()
637 return -EINVAL; in snd_soc_bytes_get()
649 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_put()
652 void *data; in snd_soc_bytes_put() local
654 if (!component->regmap || !params->num_regs) in snd_soc_bytes_put()
655 return -EINVAL; in snd_soc_bytes_put()
657 len = params->num_regs * component->val_bytes; in snd_soc_bytes_put()
659 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); in snd_soc_bytes_put()
660 if (!data) in snd_soc_bytes_put()
661 return -ENOMEM; in snd_soc_bytes_put()
665 * bits. We shouldn't modify the incoming data so take a in snd_soc_bytes_put()
668 if (params->mask) { in snd_soc_bytes_put()
669 ret = regmap_read(component->regmap, params->base, &val); in snd_soc_bytes_put()
673 val &= params->mask; in snd_soc_bytes_put()
675 switch (component->val_bytes) { in snd_soc_bytes_put()
677 ((u8 *)data)[0] &= ~params->mask; in snd_soc_bytes_put()
678 ((u8 *)data)[0] |= val; in snd_soc_bytes_put()
681 mask = ~params->mask; in snd_soc_bytes_put()
682 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
687 ((u16 *)data)[0] &= mask; in snd_soc_bytes_put()
689 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
694 ((u16 *)data)[0] |= val; in snd_soc_bytes_put()
697 mask = ~params->mask; in snd_soc_bytes_put()
698 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
703 ((u32 *)data)[0] &= mask; in snd_soc_bytes_put()
705 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
710 ((u32 *)data)[0] |= val; in snd_soc_bytes_put()
713 ret = -EINVAL; in snd_soc_bytes_put()
718 ret = regmap_raw_write(component->regmap, params->base, in snd_soc_bytes_put()
719 data, len); in snd_soc_bytes_put()
722 kfree(data); in snd_soc_bytes_put()
731 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_info_ext()
733 ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info_ext()
734 ucontrol->count = params->max; in snd_soc_bytes_info_ext()
743 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_tlv_callback()
744 unsigned int count = size < params->max ? size : params->max; in snd_soc_bytes_tlv_callback()
745 int ret = -ENXIO; in snd_soc_bytes_tlv_callback()
749 if (params->get) in snd_soc_bytes_tlv_callback()
750 ret = params->get(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
753 if (params->put) in snd_soc_bytes_tlv_callback()
754 ret = params->put(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
762 * snd_soc_info_xr_sx - signed multi register info callback
776 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_info_xr_sx()
777 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_xr_sx()
778 uinfo->count = 1; in snd_soc_info_xr_sx()
779 uinfo->value.integer.min = mc->min; in snd_soc_info_xr_sx()
780 uinfo->value.integer.max = mc->max; in snd_soc_info_xr_sx()
787 * snd_soc_get_xr_sx - signed multi register get callback
804 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_get_xr_sx()
805 unsigned int regbase = mc->regbase; in snd_soc_get_xr_sx()
806 unsigned int regcount = mc->regcount; in snd_soc_get_xr_sx()
807 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_get_xr_sx()
808 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_get_xr_sx()
809 unsigned int invert = mc->invert; in snd_soc_get_xr_sx()
810 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_get_xr_sx()
811 long min = mc->min; in snd_soc_get_xr_sx()
812 long max = mc->max; in snd_soc_get_xr_sx()
819 val |= (regval & regwmask) << (regwshift*(regcount-i-1)); in snd_soc_get_xr_sx()
825 val = max - val; in snd_soc_get_xr_sx()
826 ucontrol->value.integer.value[0] = val; in snd_soc_get_xr_sx()
833 * snd_soc_put_xr_sx - signed multi register get callback
850 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_put_xr_sx()
851 unsigned int regbase = mc->regbase; in snd_soc_put_xr_sx()
852 unsigned int regcount = mc->regcount; in snd_soc_put_xr_sx()
853 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_put_xr_sx()
854 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_put_xr_sx()
855 unsigned int invert = mc->invert; in snd_soc_put_xr_sx()
856 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_put_xr_sx()
857 long max = mc->max; in snd_soc_put_xr_sx()
858 long val = ucontrol->value.integer.value[0]; in snd_soc_put_xr_sx()
863 val = max - val; in snd_soc_put_xr_sx()
866 regval = (val >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
867 regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
879 * snd_soc_get_strobe - strobe get callback
892 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_strobe()
893 unsigned int reg = mc->reg; in snd_soc_get_strobe()
894 unsigned int shift = mc->shift; in snd_soc_get_strobe() local
895 unsigned int mask = 1 << shift; in snd_soc_get_strobe()
896 unsigned int invert = mc->invert != 0; in snd_soc_get_strobe()
902 if (shift != 0 && val != 0) in snd_soc_get_strobe()
903 val = val >> shift; in snd_soc_get_strobe()
904 ucontrol->value.enumerated.item[0] = val ^ invert; in snd_soc_get_strobe()
911 * snd_soc_put_strobe - strobe put callback
925 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_strobe()
926 unsigned int reg = mc->reg; in snd_soc_put_strobe()
927 unsigned int shift = mc->shift; in snd_soc_put_strobe() local
928 unsigned int mask = 1 << shift; in snd_soc_put_strobe()
929 unsigned int invert = mc->invert != 0; in snd_soc_put_strobe()
930 unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; in snd_soc_put_strobe()