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 :-
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;
44 return snd_ctl_enum_info(uinfo, e->shift_l == e->shift_r ? 1 : 2,
45 e->items, e->texts);
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;
66 reg_val = snd_soc_component_read(component, e->reg);
67 val = (reg_val >> e->shift_l) & e->mask;
69 ucontrol->value.enumerated.item[0] = item;
70 if (e->shift_l != e->shift_r) {
71 val = (reg_val >> e->shift_r) & e->mask;
73 ucontrol->value.enumerated.item[1] = item;
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;
94 unsigned int *item = ucontrol->value.enumerated.item;
98 if (item[0] >= e->items)
99 return -EINVAL;
100 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
101 mask = e->mask << e->shift_l;
102 if (e->shift_l != e->shift_r) {
103 if (item[1] >= e->items)
104 return -EINVAL;
105 val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r;
106 mask |= e->mask << e->shift_r;
109 return snd_soc_component_update_bits(component, e->reg, mask, val);
118 if (mc->sign_bit)
119 val = sign_extend32(val, mc->sign_bit);
121 val = clamp(val, mc->min, mc->max);
122 val -= mc->min;
124 if (mc->invert)
125 val = max - val;
136 if (mc->invert)
137 val = max - val;
139 reg_val = val + mc->min;
147 return -EINVAL;
149 if (mc->platform_max && val > mc->platform_max)
150 return -EINVAL;
153 return -EINVAL;
160 if (mc->sign_bit)
161 return GENMASK(mc->sign_bit, 0);
163 return GENMASK(fls(mc->max) - 1, 0);
168 // min + max will take us 1-bit over the size of the mask
169 return GENMASK(fls(mc->min + mc->max) - 2, 0);
176 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
180 const char *vol_string = strstr(kcontrol->id.name, " Volume");
183 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
186 if (mc->platform_max && mc->platform_max < max)
187 max = mc->platform_max;
189 uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
190 uinfo->value.integer.min = 0;
191 uinfo->value.integer.max = max;
206 ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max);
210 val1 = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0],
211 mask, mc->shift, max);
212 val_mask = mask << mc->shift;
215 ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max);
219 if (mc->reg == mc->rreg) {
221 ucontrol->value.integer.value[1],
222 mask, mc->rshift, max);
223 val_mask |= mask << mc->rshift;
226 ucontrol->value.integer.value[1],
227 mask, mc->shift, max);
232 ret = snd_soc_component_update_bits(component, mc->reg, val_mask, val1);
237 int err = snd_soc_component_update_bits(component, mc->rreg,
255 reg_val = snd_soc_component_read(component, mc->reg);
256 val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max);
258 ucontrol->value.integer.value[0] = val;
261 if (mc->reg == mc->rreg) {
262 val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->rshift, max);
264 reg_val = snd_soc_component_read(component, mc->rreg);
265 val = soc_mixer_reg_to_ctl(mc, reg_val, mask, mc->shift, max);
268 ucontrol->value.integer.value[1] = val;
275 * snd_soc_info_volsw - single mixer info callback with range.
279 * Callback to provide information, with a range, about a single mixer control,
280 * or a double mixer control that spans 2 registers.
288 (struct soc_mixer_control *)kcontrol->private_value;
290 return soc_info_volsw(kcontrol, uinfo, mc, mc->max - mc->min);
295 * snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls
299 * Callback to provide information about a single mixer control, or a double
301 * have a range that represents both positive and negative values either side
311 (struct soc_mixer_control *)kcontrol->private_value;
313 return soc_info_volsw(kcontrol, uinfo, mc, mc->max);
318 * snd_soc_get_volsw - single mixer get callback with range
322 * Callback to get the value, within a range, of a single mixer control, or a
323 * double mixer control that spans 2 registers.
331 (struct soc_mixer_control *)kcontrol->private_value;
334 return soc_get_volsw(kcontrol, ucontrol, mc, mask, mc->max - mc->min);
339 * snd_soc_put_volsw - single mixer put callback with range
343 * Callback to set the value , within a range, of a single mixer control, or
344 * a double mixer control that spans 2 registers.
352 (struct soc_mixer_control *)kcontrol->private_value;
355 return soc_put_volsw(kcontrol, ucontrol, mc, mask, mc->max - mc->min);
360 * snd_soc_get_volsw_sx - single mixer get callback
364 * Callback to get the value of a single mixer control, or a double mixer
373 (struct soc_mixer_control *)kcontrol->private_value;
376 return soc_get_volsw(kcontrol, ucontrol, mc, mask, mc->max);
381 * snd_soc_put_volsw_sx - double mixer set callback
385 * Callback to set the value of a double mixer control that spans 2 registers.
393 (struct soc_mixer_control *)kcontrol->private_value;
396 return soc_put_volsw(kcontrol, ucontrol, mc, mask, mc->max);
402 struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value;
406 if (!mc->platform_max)
411 return -ENOMEM;
413 ret = kctl->get(kctl, uctl);
417 if (uctl->value.integer.value[0] > mc->platform_max)
418 uctl->value.integer.value[0] = mc->platform_max;
421 uctl->value.integer.value[1] > mc->platform_max)
422 uctl->value.integer.value[1] = mc->platform_max;
424 ret = kctl->put(kctl, uctl);
432 * snd_soc_limit_volume - Set new limit to an existing volume control.
443 int ret = -EINVAL;
447 return -EINVAL;
452 (struct soc_mixer_control *)kctl->private_value;
454 if (max <= mc->max - mc->min) {
455 mc->platform_max = max;
468 struct soc_bytes *params = (void *)kcontrol->private_value;
470 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
471 uinfo->count = params->num_regs * component->val_bytes;
481 struct soc_bytes *params = (void *)kcontrol->private_value;
484 if (component->regmap)
485 ret = regmap_raw_read(component->regmap, params->base,
486 ucontrol->value.bytes.data,
487 params->num_regs * component->val_bytes);
489 ret = -EINVAL;
492 if (ret == 0 && params->mask) {
493 switch (component->val_bytes) {
495 ucontrol->value.bytes.data[0] &= ~params->mask;
498 ((u16 *)(&ucontrol->value.bytes.data))[0]
499 &= cpu_to_be16(~params->mask);
502 ((u32 *)(&ucontrol->value.bytes.data))[0]
503 &= cpu_to_be32(~params->mask);
506 return -EINVAL;
518 struct soc_bytes *params = (void *)kcontrol->private_value;
522 if (!component->regmap || !params->num_regs)
523 return -EINVAL;
525 len = params->num_regs * component->val_bytes;
527 void *data __free(kfree) = kmemdup(ucontrol->value.bytes.data, len,
530 return -ENOMEM;
537 if (params->mask) {
538 ret = regmap_read(component->regmap, params->base, &val);
542 val &= params->mask;
544 switch (component->val_bytes) {
546 ((u8 *)data)[0] &= ~params->mask;
550 mask = ~params->mask;
551 ret = regmap_parse_val(component->regmap, &mask, &mask);
557 ret = regmap_parse_val(component->regmap, &val, &val);
564 mask = ~params->mask;
565 ret = regmap_parse_val(component->regmap, &mask, &mask);
571 ret = regmap_parse_val(component->regmap, &val, &val);
578 return -EINVAL;
582 return regmap_raw_write(component->regmap, params->base, data, len);
589 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
591 ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES;
592 ucontrol->count = params->max;
601 struct soc_bytes_ext *params = (void *)kcontrol->private_value;
602 unsigned int count = size < params->max ? size : params->max;
603 int ret = -ENXIO;
607 if (params->get)
608 ret = params->get(kcontrol, tlv, count);
611 if (params->put)
612 ret = params->put(kcontrol, tlv, count);
621 * snd_soc_info_xr_sx - signed multi register info callback
627 * that unlike the non-xr variant of sx controls these may or may not
636 (struct soc_mreg_control *)kcontrol->private_value;
638 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
639 uinfo->count = 1;
640 uinfo->value.integer.min = mc->min;
641 uinfo->value.integer.max = mc->max;
648 * snd_soc_get_xr_sx - signed multi register get callback
655 * across the multiple codec registers. Note that unlike the non-xr
666 (struct soc_mreg_control *)kcontrol->private_value;
667 unsigned int regbase = mc->regbase;
668 unsigned int regcount = mc->regcount;
669 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE;
670 unsigned int regwmask = GENMASK(regwshift - 1, 0);
671 unsigned long mask = GENMASK(mc->nbits - 1, 0);
678 val |= (regval & regwmask) << (regwshift * (regcount - i - 1));
681 if (mc->min < 0 && val > mc->max)
683 if (mc->invert)
684 val = mc->max - val;
685 ucontrol->value.integer.value[0] = val;
692 * snd_soc_put_xr_sx - signed multi register get callback
699 * across the multiple codec registers. Note that unlike the non-xr
710 (struct soc_mreg_control *)kcontrol->private_value;
711 unsigned int regbase = mc->regbase;
712 unsigned int regcount = mc->regcount;
713 unsigned int regwshift = component->val_bytes * BITS_PER_BYTE;
714 unsigned int regwmask = GENMASK(regwshift - 1, 0);
715 unsigned long mask = GENMASK(mc->nbits - 1, 0);
716 long val = ucontrol->value.integer.value[0];
720 if (val < mc->min || val > mc->max)
721 return -EINVAL;
722 if (mc->invert)
723 val = mc->max - val;
726 unsigned int regval = (val >> (regwshift * (regcount - i - 1))) &
728 unsigned int regmask = (mask >> (regwshift * (regcount - i - 1))) &
744 * snd_soc_get_strobe - strobe get callback
757 (struct soc_mixer_control *)kcontrol->private_value;
758 unsigned int invert = mc->invert != 0;
759 unsigned int mask = BIT(mc->shift);
762 val = snd_soc_component_read(component, mc->reg);
765 if (mc->shift != 0 && val != 0)
766 val = val >> mc->shift;
768 ucontrol->value.enumerated.item[0] = val ^ invert;
775 * snd_soc_put_strobe - strobe put callback
789 (struct soc_mixer_control *)kcontrol->private_value;
790 unsigned int strobe = ucontrol->value.enumerated.item[0] != 0;
791 unsigned int invert = mc->invert != 0;
792 unsigned int mask = BIT(mc->shift);
797 ret = snd_soc_component_update_bits(component, mc->reg, mask, val1);
801 return snd_soc_component_update_bits(component, mc->reg, mask, val2);