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()
424 val2 = (ucontrol->value.integer.value[1] + min) & mask; in snd_soc_put_volsw_sx()
435 * snd_soc_info_volsw_range - single mixer info callback with range.
448 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw_range()
450 int min = mc->min; in snd_soc_info_volsw_range()
452 if (!mc->platform_max) in snd_soc_info_volsw_range()
453 mc->platform_max = mc->max; in snd_soc_info_volsw_range()
454 platform_max = mc->platform_max; in snd_soc_info_volsw_range()
456 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw_range()
457 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw_range()
458 uinfo->value.integer.min = 0; in snd_soc_info_volsw_range()
459 uinfo->value.integer.max = platform_max - min; in snd_soc_info_volsw_range()
466 * snd_soc_put_volsw_range - single mixer put value callback with range.
478 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_range()
480 unsigned int reg = mc->reg; in snd_soc_put_volsw_range()
481 unsigned int rreg = mc->rreg; in snd_soc_put_volsw_range()
482 unsigned int shift = mc->shift; in snd_soc_put_volsw_range() local
483 int min = mc->min; in snd_soc_put_volsw_range()
484 int max = mc->max; in snd_soc_put_volsw_range()
485 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_put_volsw_range()
486 unsigned int invert = mc->invert; in snd_soc_put_volsw_range()
491 val = (max - ucontrol->value.integer.value[0]) & mask; in snd_soc_put_volsw_range()
493 val = ((ucontrol->value.integer.value[0] + min) & mask); in snd_soc_put_volsw_range()
494 val_mask = mask << shift; in snd_soc_put_volsw_range()
495 val = val << shift; in snd_soc_put_volsw_range()
503 val = (max - ucontrol->value.integer.value[1]) & mask; in snd_soc_put_volsw_range()
505 val = ((ucontrol->value.integer.value[1] + min) & mask); in snd_soc_put_volsw_range()
506 val_mask = mask << shift; in snd_soc_put_volsw_range()
507 val = val << shift; in snd_soc_put_volsw_range()
518 * snd_soc_get_volsw_range - single mixer get callback with range
531 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_range()
532 unsigned int reg = mc->reg; in snd_soc_get_volsw_range()
533 unsigned int rreg = mc->rreg; in snd_soc_get_volsw_range()
534 unsigned int shift = mc->shift; in snd_soc_get_volsw_range() local
535 int min = mc->min; in snd_soc_get_volsw_range()
536 int max = mc->max; in snd_soc_get_volsw_range()
537 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_get_volsw_range()
538 unsigned int invert = mc->invert; in snd_soc_get_volsw_range()
542 ucontrol->value.integer.value[0] = (val >> shift) & mask; in snd_soc_get_volsw_range()
544 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
545 max - ucontrol->value.integer.value[0]; in snd_soc_get_volsw_range()
547 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
548 ucontrol->value.integer.value[0] - min; in snd_soc_get_volsw_range()
552 ucontrol->value.integer.value[1] = (val >> shift) & mask; in snd_soc_get_volsw_range()
554 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
555 max - ucontrol->value.integer.value[1]; in snd_soc_get_volsw_range()
557 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
558 ucontrol->value.integer.value[1] - min; in snd_soc_get_volsw_range()
566 * snd_soc_limit_volume - Set new limit to an existing volume control.
578 int ret = -EINVAL; in snd_soc_limit_volume()
582 return -EINVAL; in snd_soc_limit_volume()
586 struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; in snd_soc_limit_volume()
587 if (max <= mc->max) { in snd_soc_limit_volume()
588 mc->platform_max = max; in snd_soc_limit_volume()
600 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_info()
602 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info()
603 uinfo->count = params->num_regs * component->val_bytes; in snd_soc_bytes_info()
613 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_get()
616 if (component->regmap) in snd_soc_bytes_get()
617 ret = regmap_raw_read(component->regmap, params->base, in snd_soc_bytes_get()
618 ucontrol->value.bytes.data, in snd_soc_bytes_get()
619 params->num_regs * component->val_bytes); in snd_soc_bytes_get()
621 ret = -EINVAL; in snd_soc_bytes_get()
623 /* Hide any masked bytes to ensure consistent data reporting */ in snd_soc_bytes_get()
624 if (ret == 0 && params->mask) { in snd_soc_bytes_get()
625 switch (component->val_bytes) { in snd_soc_bytes_get()
627 ucontrol->value.bytes.data[0] &= ~params->mask; in snd_soc_bytes_get()
630 ((u16 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
631 &= cpu_to_be16(~params->mask); in snd_soc_bytes_get()
634 ((u32 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
635 &= cpu_to_be32(~params->mask); in snd_soc_bytes_get()
638 return -EINVAL; in snd_soc_bytes_get()
650 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_put()
653 void *data; in snd_soc_bytes_put() local
655 if (!component->regmap || !params->num_regs) in snd_soc_bytes_put()
656 return -EINVAL; in snd_soc_bytes_put()
658 len = params->num_regs * component->val_bytes; in snd_soc_bytes_put()
660 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); in snd_soc_bytes_put()
661 if (!data) in snd_soc_bytes_put()
662 return -ENOMEM; in snd_soc_bytes_put()
666 * bits. We shouldn't modify the incoming data so take a in snd_soc_bytes_put()
669 if (params->mask) { in snd_soc_bytes_put()
670 ret = regmap_read(component->regmap, params->base, &val); in snd_soc_bytes_put()
674 val &= params->mask; in snd_soc_bytes_put()
676 switch (component->val_bytes) { in snd_soc_bytes_put()
678 ((u8 *)data)[0] &= ~params->mask; in snd_soc_bytes_put()
679 ((u8 *)data)[0] |= val; in snd_soc_bytes_put()
682 mask = ~params->mask; in snd_soc_bytes_put()
683 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
688 ((u16 *)data)[0] &= mask; in snd_soc_bytes_put()
690 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
695 ((u16 *)data)[0] |= val; in snd_soc_bytes_put()
698 mask = ~params->mask; in snd_soc_bytes_put()
699 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
704 ((u32 *)data)[0] &= mask; in snd_soc_bytes_put()
706 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
711 ((u32 *)data)[0] |= val; in snd_soc_bytes_put()
714 ret = -EINVAL; in snd_soc_bytes_put()
719 ret = regmap_raw_write(component->regmap, params->base, in snd_soc_bytes_put()
720 data, len); in snd_soc_bytes_put()
723 kfree(data); in snd_soc_bytes_put()
732 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_info_ext()
734 ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info_ext()
735 ucontrol->count = params->max; in snd_soc_bytes_info_ext()
744 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_tlv_callback()
745 unsigned int count = size < params->max ? size : params->max; in snd_soc_bytes_tlv_callback()
746 int ret = -ENXIO; in snd_soc_bytes_tlv_callback()
750 if (params->get) in snd_soc_bytes_tlv_callback()
751 ret = params->get(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
754 if (params->put) in snd_soc_bytes_tlv_callback()
755 ret = params->put(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
763 * snd_soc_info_xr_sx - signed multi register info callback
777 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_info_xr_sx()
778 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_xr_sx()
779 uinfo->count = 1; in snd_soc_info_xr_sx()
780 uinfo->value.integer.min = mc->min; in snd_soc_info_xr_sx()
781 uinfo->value.integer.max = mc->max; in snd_soc_info_xr_sx()
788 * snd_soc_get_xr_sx - signed multi register get callback
805 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_get_xr_sx()
806 unsigned int regbase = mc->regbase; in snd_soc_get_xr_sx()
807 unsigned int regcount = mc->regcount; in snd_soc_get_xr_sx()
808 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_get_xr_sx()
809 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_get_xr_sx()
810 unsigned int invert = mc->invert; in snd_soc_get_xr_sx()
811 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_get_xr_sx()
812 long min = mc->min; in snd_soc_get_xr_sx()
813 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()
862 val = max - val; in snd_soc_put_xr_sx()
865 unsigned int regval = (val >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
866 unsigned int regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
878 * snd_soc_get_strobe - strobe get callback
891 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_strobe()
892 unsigned int reg = mc->reg; in snd_soc_get_strobe()
893 unsigned int shift = mc->shift; in snd_soc_get_strobe() local
894 unsigned int mask = 1 << shift; in snd_soc_get_strobe()
895 unsigned int invert = mc->invert != 0; in snd_soc_get_strobe()
901 if (shift != 0 && val != 0) in snd_soc_get_strobe()
902 val = val >> shift; in snd_soc_get_strobe()
903 ucontrol->value.enumerated.item[0] = val ^ invert; in snd_soc_get_strobe()
910 * snd_soc_put_strobe - strobe put callback
924 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_strobe()
925 unsigned int reg = mc->reg; in snd_soc_put_strobe()
926 unsigned int shift = mc->shift; in snd_soc_put_strobe() local
927 unsigned int mask = 1 << shift; in snd_soc_put_strobe()
928 unsigned int invert = mc->invert != 0; in snd_soc_put_strobe()
929 unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; in snd_soc_put_strobe()