• 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 :-
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()
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
203 * Callback to provide information about a single mixer control, or a double
205 * have a range that represents both positive and negative values either side
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
231 * Callback to get the value of a single mixer control, or a double mixer
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()
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()
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()
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
291 * Callback to set the value of a single mixer control, or a double mixer
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()
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]; in snd_soc_put_volsw()
320 if (mc->platform_max && ((int)val + min) > mc->platform_max) in snd_soc_put_volsw()
321 return -EINVAL; in snd_soc_put_volsw()
322 if (val > max - min) in snd_soc_put_volsw()
323 return -EINVAL; in snd_soc_put_volsw()
325 return -EINVAL; in snd_soc_put_volsw()
328 val = max - val; in snd_soc_put_volsw()
332 val2 = ucontrol->value.integer.value[1]; in snd_soc_put_volsw()
333 if (mc->platform_max && ((int)val2 + min) > mc->platform_max) in snd_soc_put_volsw()
334 return -EINVAL; in snd_soc_put_volsw()
335 if (val2 > max - min) in snd_soc_put_volsw()
336 return -EINVAL; in snd_soc_put_volsw()
338 return -EINVAL; in snd_soc_put_volsw()
341 val2 = max - val2; in snd_soc_put_volsw()
369 * snd_soc_get_volsw_sx - single mixer get callback
373 * Callback to get the value of a single mixer control, or a double mixer
383 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_sx()
384 unsigned int reg = mc->reg; in snd_soc_get_volsw_sx()
385 unsigned int reg2 = mc->rreg; in snd_soc_get_volsw_sx()
386 unsigned int shift = mc->shift; in snd_soc_get_volsw_sx()
387 unsigned int rshift = mc->rshift; in snd_soc_get_volsw_sx()
388 int max = mc->max; in snd_soc_get_volsw_sx()
389 int min = mc->min; in snd_soc_get_volsw_sx()
390 unsigned int mask = (1U << (fls(min + max) - 1)) - 1; in snd_soc_get_volsw_sx()
394 ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; in snd_soc_get_volsw_sx()
398 val = ((val >> rshift) - min) & mask; in snd_soc_get_volsw_sx()
399 ucontrol->value.integer.value[1] = val; in snd_soc_get_volsw_sx()
407 * snd_soc_put_volsw_sx - double mixer set callback
411 * Callback to set the value of a double mixer control that spans 2 registers.
420 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_sx()
422 unsigned int reg = mc->reg; in snd_soc_put_volsw_sx()
423 unsigned int reg2 = mc->rreg; in snd_soc_put_volsw_sx()
424 unsigned int shift = mc->shift; in snd_soc_put_volsw_sx()
425 unsigned int rshift = mc->rshift; in snd_soc_put_volsw_sx()
426 int max = mc->max; in snd_soc_put_volsw_sx()
427 int min = mc->min; in snd_soc_put_volsw_sx()
428 unsigned int mask = (1U << (fls(min + max) - 1)) - 1; in snd_soc_put_volsw_sx()
432 val = ucontrol->value.integer.value[0]; in snd_soc_put_volsw_sx()
433 if (mc->platform_max && val > mc->platform_max) in snd_soc_put_volsw_sx()
434 return -EINVAL; in snd_soc_put_volsw_sx()
436 return -EINVAL; in snd_soc_put_volsw_sx()
438 return -EINVAL; in snd_soc_put_volsw_sx()
448 val2 = ucontrol->value.integer.value[1]; in snd_soc_put_volsw_sx()
450 if (mc->platform_max && val2 > mc->platform_max) in snd_soc_put_volsw_sx()
451 return -EINVAL; in snd_soc_put_volsw_sx()
453 return -EINVAL; in snd_soc_put_volsw_sx()
467 * snd_soc_info_volsw_range - single mixer info callback with range.
471 * Callback to provide information, within a range, about a single
480 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_info_volsw_range()
482 int min = mc->min; in snd_soc_info_volsw_range()
484 if (!mc->platform_max) in snd_soc_info_volsw_range()
485 mc->platform_max = mc->max; in snd_soc_info_volsw_range()
486 platform_max = mc->platform_max; in snd_soc_info_volsw_range()
488 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_volsw_range()
489 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; in snd_soc_info_volsw_range()
490 uinfo->value.integer.min = 0; in snd_soc_info_volsw_range()
491 uinfo->value.integer.max = platform_max - min; in snd_soc_info_volsw_range()
498 * snd_soc_put_volsw_range - single mixer put value callback with range.
502 * Callback to set the value, within a range, for a single mixer control.
510 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_volsw_range()
512 unsigned int reg = mc->reg; in snd_soc_put_volsw_range()
513 unsigned int rreg = mc->rreg; in snd_soc_put_volsw_range()
514 unsigned int shift = mc->shift; in snd_soc_put_volsw_range()
515 int min = mc->min; in snd_soc_put_volsw_range()
516 int max = mc->max; in snd_soc_put_volsw_range()
517 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_put_volsw_range()
518 unsigned int invert = mc->invert; in snd_soc_put_volsw_range()
522 tmp = ucontrol->value.integer.value[0]; in snd_soc_put_volsw_range()
524 return -EINVAL; in snd_soc_put_volsw_range()
525 if (mc->platform_max && tmp > mc->platform_max) in snd_soc_put_volsw_range()
526 return -EINVAL; in snd_soc_put_volsw_range()
527 if (tmp > mc->max - mc->min) in snd_soc_put_volsw_range()
528 return -EINVAL; in snd_soc_put_volsw_range()
531 val = (max - ucontrol->value.integer.value[0]) & mask; in snd_soc_put_volsw_range()
533 val = ((ucontrol->value.integer.value[0] + min) & mask); in snd_soc_put_volsw_range()
543 tmp = ucontrol->value.integer.value[1]; in snd_soc_put_volsw_range()
545 return -EINVAL; in snd_soc_put_volsw_range()
546 if (mc->platform_max && tmp > mc->platform_max) in snd_soc_put_volsw_range()
547 return -EINVAL; in snd_soc_put_volsw_range()
548 if (tmp > mc->max - mc->min) in snd_soc_put_volsw_range()
549 return -EINVAL; in snd_soc_put_volsw_range()
552 val = (max - ucontrol->value.integer.value[1]) & mask; in snd_soc_put_volsw_range()
554 val = ((ucontrol->value.integer.value[1] + min) & mask); in snd_soc_put_volsw_range()
571 * snd_soc_get_volsw_range - single mixer get callback with range
575 * Callback to get the value, within a range, of a single mixer control.
584 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_volsw_range()
585 unsigned int reg = mc->reg; in snd_soc_get_volsw_range()
586 unsigned int rreg = mc->rreg; in snd_soc_get_volsw_range()
587 unsigned int shift = mc->shift; in snd_soc_get_volsw_range()
588 int min = mc->min; in snd_soc_get_volsw_range()
589 int max = mc->max; in snd_soc_get_volsw_range()
590 unsigned int mask = (1 << fls(max)) - 1; in snd_soc_get_volsw_range()
591 unsigned int invert = mc->invert; in snd_soc_get_volsw_range()
595 ucontrol->value.integer.value[0] = (val >> shift) & mask; in snd_soc_get_volsw_range()
597 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
598 max - ucontrol->value.integer.value[0]; in snd_soc_get_volsw_range()
600 ucontrol->value.integer.value[0] = in snd_soc_get_volsw_range()
601 ucontrol->value.integer.value[0] - min; in snd_soc_get_volsw_range()
605 ucontrol->value.integer.value[1] = (val >> shift) & mask; in snd_soc_get_volsw_range()
607 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
608 max - ucontrol->value.integer.value[1]; in snd_soc_get_volsw_range()
610 ucontrol->value.integer.value[1] = in snd_soc_get_volsw_range()
611 ucontrol->value.integer.value[1] - min; in snd_soc_get_volsw_range()
619 * snd_soc_limit_volume - Set new limit to an existing volume control.
632 int ret = -EINVAL; in snd_soc_limit_volume()
636 return -EINVAL; in snd_soc_limit_volume()
640 mc = (struct soc_mixer_control *)kctl->private_value; in snd_soc_limit_volume()
641 if (max <= mc->max) { in snd_soc_limit_volume()
642 mc->platform_max = max; in snd_soc_limit_volume()
654 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_info()
656 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info()
657 uinfo->count = params->num_regs * component->val_bytes; in snd_soc_bytes_info()
667 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_get()
670 if (component->regmap) in snd_soc_bytes_get()
671 ret = regmap_raw_read(component->regmap, params->base, in snd_soc_bytes_get()
672 ucontrol->value.bytes.data, in snd_soc_bytes_get()
673 params->num_regs * component->val_bytes); in snd_soc_bytes_get()
675 ret = -EINVAL; in snd_soc_bytes_get()
678 if (ret == 0 && params->mask) { in snd_soc_bytes_get()
679 switch (component->val_bytes) { in snd_soc_bytes_get()
681 ucontrol->value.bytes.data[0] &= ~params->mask; in snd_soc_bytes_get()
684 ((u16 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
685 &= cpu_to_be16(~params->mask); in snd_soc_bytes_get()
688 ((u32 *)(&ucontrol->value.bytes.data))[0] in snd_soc_bytes_get()
689 &= cpu_to_be32(~params->mask); in snd_soc_bytes_get()
692 return -EINVAL; in snd_soc_bytes_get()
704 struct soc_bytes *params = (void *)kcontrol->private_value; in snd_soc_bytes_put()
709 if (!component->regmap || !params->num_regs) in snd_soc_bytes_put()
710 return -EINVAL; in snd_soc_bytes_put()
712 len = params->num_regs * component->val_bytes; in snd_soc_bytes_put()
714 data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); in snd_soc_bytes_put()
716 return -ENOMEM; in snd_soc_bytes_put()
723 if (params->mask) { in snd_soc_bytes_put()
724 ret = regmap_read(component->regmap, params->base, &val); in snd_soc_bytes_put()
728 val &= params->mask; in snd_soc_bytes_put()
730 switch (component->val_bytes) { in snd_soc_bytes_put()
732 ((u8 *)data)[0] &= ~params->mask; in snd_soc_bytes_put()
736 mask = ~params->mask; in snd_soc_bytes_put()
737 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
744 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
752 mask = ~params->mask; in snd_soc_bytes_put()
753 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
760 ret = regmap_parse_val(component->regmap, in snd_soc_bytes_put()
768 ret = -EINVAL; in snd_soc_bytes_put()
773 ret = regmap_raw_write(component->regmap, params->base, in snd_soc_bytes_put()
786 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_info_ext()
788 ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; in snd_soc_bytes_info_ext()
789 ucontrol->count = params->max; in snd_soc_bytes_info_ext()
798 struct soc_bytes_ext *params = (void *)kcontrol->private_value; in snd_soc_bytes_tlv_callback()
799 unsigned int count = size < params->max ? size : params->max; in snd_soc_bytes_tlv_callback()
800 int ret = -ENXIO; in snd_soc_bytes_tlv_callback()
804 if (params->get) in snd_soc_bytes_tlv_callback()
805 ret = params->get(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
808 if (params->put) in snd_soc_bytes_tlv_callback()
809 ret = params->put(kcontrol, tlv, count); in snd_soc_bytes_tlv_callback()
817 * snd_soc_info_xr_sx - signed multi register info callback
831 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_info_xr_sx()
832 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_soc_info_xr_sx()
833 uinfo->count = 1; in snd_soc_info_xr_sx()
834 uinfo->value.integer.min = mc->min; in snd_soc_info_xr_sx()
835 uinfo->value.integer.max = mc->max; in snd_soc_info_xr_sx()
842 * snd_soc_get_xr_sx - signed multi register get callback
859 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_get_xr_sx()
860 unsigned int regbase = mc->regbase; in snd_soc_get_xr_sx()
861 unsigned int regcount = mc->regcount; in snd_soc_get_xr_sx()
862 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_get_xr_sx()
863 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_get_xr_sx()
864 unsigned int invert = mc->invert; in snd_soc_get_xr_sx()
865 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_get_xr_sx()
866 long min = mc->min; in snd_soc_get_xr_sx()
867 long max = mc->max; in snd_soc_get_xr_sx()
874 val |= (regval & regwmask) << (regwshift*(regcount-i-1)); in snd_soc_get_xr_sx()
880 val = max - val; in snd_soc_get_xr_sx()
881 ucontrol->value.integer.value[0] = val; in snd_soc_get_xr_sx()
888 * snd_soc_put_xr_sx - signed multi register get callback
905 (struct soc_mreg_control *)kcontrol->private_value; in snd_soc_put_xr_sx()
906 unsigned int regbase = mc->regbase; in snd_soc_put_xr_sx()
907 unsigned int regcount = mc->regcount; in snd_soc_put_xr_sx()
908 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; in snd_soc_put_xr_sx()
909 unsigned int regwmask = (1UL<<regwshift)-1; in snd_soc_put_xr_sx()
910 unsigned int invert = mc->invert; in snd_soc_put_xr_sx()
911 unsigned long mask = (1UL<<mc->nbits)-1; in snd_soc_put_xr_sx()
912 long max = mc->max; in snd_soc_put_xr_sx()
913 long val = ucontrol->value.integer.value[0]; in snd_soc_put_xr_sx()
917 if (val < mc->min || val > mc->max) in snd_soc_put_xr_sx()
918 return -EINVAL; in snd_soc_put_xr_sx()
920 val = max - val; in snd_soc_put_xr_sx()
923 regval = (val >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
924 regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; in snd_soc_put_xr_sx()
936 * snd_soc_get_strobe - strobe get callback
949 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_get_strobe()
950 unsigned int reg = mc->reg; in snd_soc_get_strobe()
951 unsigned int shift = mc->shift; in snd_soc_get_strobe()
953 unsigned int invert = mc->invert != 0; in snd_soc_get_strobe()
961 ucontrol->value.enumerated.item[0] = val ^ invert; in snd_soc_get_strobe()
968 * snd_soc_put_strobe - strobe put callback
982 (struct soc_mixer_control *)kcontrol->private_value; in snd_soc_put_strobe()
983 unsigned int reg = mc->reg; in snd_soc_put_strobe()
984 unsigned int shift = mc->shift; in snd_soc_put_strobe()
986 unsigned int invert = mc->invert != 0; in snd_soc_put_strobe()
987 unsigned int strobe = ucontrol->value.enumerated.item[0] != 0; in snd_soc_put_strobe()