Lines Matching +full:eq +full:- +full:level

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Tascam US-16x08 ALSA driver
10 #include <linux/usb/audio-v2.h>
28 0x01, /* input index (0x01/0x02 eq. left/right) or bus (0x01-0x08) */
36 0x01, /* output index (0x01-0x08) */
94 0xf0, /* 0x08: Threshold db (8) (e0 ... 00) (+-0dB -- -32dB) x-32 */
122 0x04, /* 0x08: EQ set num (0x01..0x04) (LOW, LOWMID, HIGHMID, HIGH)) */
125 0x0c, /* 0x0b: value dB (0 ... 12) (-12db .. +12db) x-6 */
128 0x0f, /* 0x0e: value freq (32-47) (1.7kHz..18kHz) */
131 0x02, /* 0x11: band width (0-6) (Q16-Q0.25) 2^x/4 (EQ xxMID only) */
134 0x01, /* 0x14: main EQ switch (0 ... 1) (off ... on)) */
155 mutex_lock(&chip->mutex); in snd_us16x08_recv_urb()
156 snd_usb_ctl_msg(chip->dev, in snd_us16x08_recv_urb()
157 usb_rcvctrlpipe(chip->dev, 0), in snd_us16x08_recv_urb()
160 mutex_unlock(&chip->mutex); in snd_us16x08_recv_urb()
169 return snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), in snd_us16x08_send_urb()
183 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_route_get()
184 int index = ucontrol->id.index; in snd_us16x08_route_get()
187 ucontrol->value.enumerated.item[0] = elem->cache_val[index]; in snd_us16x08_route_get()
195 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_route_put()
196 struct snd_usb_audio *chip = elem->head.mixer->chip; in snd_us16x08_route_put()
197 int index = ucontrol->id.index; in snd_us16x08_route_put()
202 val = ucontrol->value.enumerated.item[0]; in snd_us16x08_route_put()
206 return -EINVAL; in snd_us16x08_route_put()
218 val_org = val - 2; in snd_us16x08_route_put()
229 elem->cached |= 1 << index; in snd_us16x08_route_put()
230 elem->cache_val[index] = val; in snd_us16x08_route_put()
241 uinfo->count = 1; in snd_us16x08_master_info()
242 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_us16x08_master_info()
243 uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol); in snd_us16x08_master_info()
244 uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol); in snd_us16x08_master_info()
245 uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol); in snd_us16x08_master_info()
252 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_master_get()
253 int index = ucontrol->id.index; in snd_us16x08_master_get()
255 ucontrol->value.integer.value[0] = elem->cache_val[index]; in snd_us16x08_master_get()
263 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_master_put()
264 struct snd_usb_audio *chip = elem->head.mixer->chip; in snd_us16x08_master_put()
267 int index = ucontrol->id.index; in snd_us16x08_master_put()
270 val = ucontrol->value.integer.value[0]; in snd_us16x08_master_put()
275 return -EINVAL; in snd_us16x08_master_put()
280 buf[8] = val - SND_US16X08_KCBIAS(kcontrol); in snd_us16x08_master_put()
281 buf[6] = elem->head.id; in snd_us16x08_master_put()
288 elem->cached |= 1 << index; in snd_us16x08_master_put()
289 elem->cache_val[index] = val; in snd_us16x08_master_put()
300 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_bus_put()
301 struct snd_usb_audio *chip = elem->head.mixer->chip; in snd_us16x08_bus_put()
305 val = ucontrol->value.integer.value[0]; in snd_us16x08_bus_put()
308 switch (elem->head.id) { in snd_us16x08_bus_put()
322 buf[6] = elem->head.id; in snd_us16x08_bus_put()
329 elem->cached |= 1; in snd_us16x08_bus_put()
330 elem->cache_val[0] = val; in snd_us16x08_bus_put()
341 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_bus_get()
343 switch (elem->head.id) { in snd_us16x08_bus_get()
345 ucontrol->value.integer.value[0] = elem->cache_val[0]; in snd_us16x08_bus_get()
348 ucontrol->value.integer.value[0] = elem->cache_val[0]; in snd_us16x08_bus_get()
351 ucontrol->value.integer.value[0] = elem->cache_val[0]; in snd_us16x08_bus_get()
362 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_channel_get()
363 int index = ucontrol->id.index; in snd_us16x08_channel_get()
365 ucontrol->value.integer.value[0] = elem->cache_val[index]; in snd_us16x08_channel_get()
373 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_channel_put()
374 struct snd_usb_audio *chip = elem->head.mixer->chip; in snd_us16x08_channel_put()
377 int index = ucontrol->id.index; in snd_us16x08_channel_put()
379 val = ucontrol->value.integer.value[0]; in snd_us16x08_channel_put()
384 return -EINVAL; in snd_us16x08_channel_put()
390 buf[8] = val - SND_US16X08_KCBIAS(kcontrol); in snd_us16x08_channel_put()
391 buf[6] = elem->head.id; in snd_us16x08_channel_put()
397 elem->cached |= 1 << index; in snd_us16x08_channel_put()
398 elem->cache_val[index] = val; in snd_us16x08_channel_put()
409 uinfo->count = 1; in snd_us16x08_mix_info()
410 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_us16x08_mix_info()
411 uinfo->value.integer.max = SND_US16X08_KCMAX(kcontrol); in snd_us16x08_mix_info()
412 uinfo->value.integer.min = SND_US16X08_KCMIN(kcontrol); in snd_us16x08_mix_info()
413 uinfo->value.integer.step = SND_US16X08_KCSTEP(kcontrol); in snd_us16x08_mix_info()
420 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_comp_get()
421 struct snd_us16x08_comp_store *store = elem->private_data; in snd_us16x08_comp_get()
422 int index = ucontrol->id.index; in snd_us16x08_comp_get()
423 int val_idx = COMP_STORE_IDX(elem->head.id); in snd_us16x08_comp_get()
425 ucontrol->value.integer.value[0] = store->val[val_idx][index]; in snd_us16x08_comp_get()
433 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_comp_put()
434 struct snd_usb_audio *chip = elem->head.mixer->chip; in snd_us16x08_comp_put()
435 struct snd_us16x08_comp_store *store = elem->private_data; in snd_us16x08_comp_put()
436 int index = ucontrol->id.index; in snd_us16x08_comp_put()
441 val = ucontrol->value.integer.value[0]; in snd_us16x08_comp_put()
446 return -EINVAL; in snd_us16x08_comp_put()
449 val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE; in snd_us16x08_comp_put()
451 store->val[val_idx][index] = ucontrol->value.integer.value[0]; in snd_us16x08_comp_put()
457 buf[8] = store->val[ in snd_us16x08_comp_put()
459 - SND_US16X08_COMP_THRESHOLD_BIAS; in snd_us16x08_comp_put()
460 buf[11] = ratio_map[store->val[ in snd_us16x08_comp_put()
462 buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index] in snd_us16x08_comp_put()
464 buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index] in snd_us16x08_comp_put()
466 buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index]; in snd_us16x08_comp_put()
467 buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index]; in snd_us16x08_comp_put()
475 elem->cached |= 1 << index; in snd_us16x08_comp_put()
476 elem->cache_val[index] = val; in snd_us16x08_comp_put()
488 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_eqswitch_get()
489 struct snd_us16x08_eq_store *store = elem->private_data; in snd_us16x08_eqswitch_get()
490 int index = ucontrol->id.index; in snd_us16x08_eqswitch_get()
493 val = store->val[EQ_STORE_BAND_IDX(elem->head.id)] in snd_us16x08_eqswitch_get()
494 [EQ_STORE_PARAM_IDX(elem->head.id)][index]; in snd_us16x08_eqswitch_get()
495 ucontrol->value.integer.value[0] = val; in snd_us16x08_eqswitch_get()
503 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_eqswitch_put()
504 struct snd_usb_audio *chip = elem->head.mixer->chip; in snd_us16x08_eqswitch_put()
505 struct snd_us16x08_eq_store *store = elem->private_data; in snd_us16x08_eqswitch_put()
506 int index = ucontrol->id.index; in snd_us16x08_eqswitch_put()
512 val = ucontrol->value.integer.value[0] + SND_US16X08_KCBIAS(kcontrol); in snd_us16x08_eqswitch_put()
514 /* prepare URB message from EQ template */ in snd_us16x08_eqswitch_put()
520 /* all four EQ bands have to be enabled/disabled in once */ in snd_us16x08_eqswitch_put()
522 buf[17] = store->val[b_idx][2][index]; in snd_us16x08_eqswitch_put()
523 buf[14] = store->val[b_idx][1][index]; in snd_us16x08_eqswitch_put()
524 buf[11] = store->val[b_idx][0][index]; in snd_us16x08_eqswitch_put()
529 store->val[b_idx][3][index] = val; in snd_us16x08_eqswitch_put()
534 elem->cached |= 1 << index; in snd_us16x08_eqswitch_put()
535 elem->cache_val[index] = val; in snd_us16x08_eqswitch_put()
537 usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err); in snd_us16x08_eqswitch_put()
547 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_eq_get()
548 struct snd_us16x08_eq_store *store = elem->private_data; in snd_us16x08_eq_get()
549 int index = ucontrol->id.index; in snd_us16x08_eq_get()
550 int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1; in snd_us16x08_eq_get()
551 int p_idx = EQ_STORE_PARAM_IDX(elem->head.id); in snd_us16x08_eq_get()
553 val = store->val[b_idx][p_idx][index]; in snd_us16x08_eq_get()
555 ucontrol->value.integer.value[0] = val; in snd_us16x08_eq_get()
563 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_eq_put()
564 struct snd_usb_audio *chip = elem->head.mixer->chip; in snd_us16x08_eq_put()
565 struct snd_us16x08_eq_store *store = elem->private_data; in snd_us16x08_eq_put()
566 int index = ucontrol->id.index; in snd_us16x08_eq_put()
569 int b_idx = EQ_STORE_BAND_IDX(elem->head.id) - 1; in snd_us16x08_eq_put()
570 int p_idx = EQ_STORE_PARAM_IDX(elem->head.id); in snd_us16x08_eq_put()
572 val = ucontrol->value.integer.value[0]; in snd_us16x08_eq_put()
577 return -EINVAL; in snd_us16x08_eq_put()
579 /* copy URB buffer from EQ template */ in snd_us16x08_eq_put()
582 store->val[b_idx][p_idx][index] = val; in snd_us16x08_eq_put()
583 buf[20] = store->val[b_idx][3][index]; in snd_us16x08_eq_put()
584 buf[17] = store->val[b_idx][2][index]; in snd_us16x08_eq_put()
585 buf[14] = store->val[b_idx][1][index]; in snd_us16x08_eq_put()
586 buf[11] = store->val[b_idx][0][index]; in snd_us16x08_eq_put()
591 /* place EQ band in URB buffer */ in snd_us16x08_eq_put()
597 /* store new value in EQ band cache */ in snd_us16x08_eq_put()
598 elem->cached |= 1 << index; in snd_us16x08_eq_put()
599 elem->cache_val[index] = val; in snd_us16x08_eq_put()
601 usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err); in snd_us16x08_eq_put()
610 uinfo->count = 34; in snd_us16x08_meter_info()
611 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_us16x08_meter_info()
612 uinfo->value.integer.max = 0x7FFF; in snd_us16x08_meter_info()
613 uinfo->value.integer.min = 0; in snd_us16x08_meter_info()
618 /* calculate compressor index for reduction level request */
624 if (store->comp_active_index) { in snd_get_meter_comp_index()
626 if (store->comp_active_index & 0x20) { in snd_get_meter_comp_index()
628 if (store->comp_index - in snd_get_meter_comp_index()
629 store->comp_active_index > 1) in snd_get_meter_comp_index()
630 store->comp_index = in snd_get_meter_comp_index()
631 store->comp_active_index; in snd_get_meter_comp_index()
633 ret = store->comp_index++ & 0x1F; in snd_get_meter_comp_index()
636 ret = store->comp_active_index; in snd_get_meter_comp_index()
640 while (store->comp_index <= SND_US16X08_MAX_CHANNELS in snd_get_meter_comp_index()
641 && !store->comp_store->val[ in snd_get_meter_comp_index()
643 [store->comp_index - 1]) { in snd_get_meter_comp_index()
644 store->comp_index++; in snd_get_meter_comp_index()
646 ret = store->comp_index++; in snd_get_meter_comp_index()
647 if (store->comp_index > SND_US16X08_MAX_CHANNELS) in snd_get_meter_comp_index()
648 store->comp_index = 1; in snd_get_meter_comp_index()
653 /* retrieve the meter level values from URB message */
663 store->meter_level[MUB2(meter_urb, s) - 1] = val; in get_meter_levels_from_urb()
665 store->comp_level[MUB2(meter_urb, s) - 1] = val; in get_meter_levels_from_urb()
669 store->master_level[MUB2(meter_urb, s) - 1] = val; in get_meter_levels_from_urb()
678 * to retrieve compressor reduction level value for given channel. This round
680 * A mixer can interrupt this round-trip by selecting one ore two (stereo-link)
687 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_meter_get()
688 struct snd_usb_audio *chip = elem->head.mixer->chip; in snd_us16x08_meter_get()
689 struct snd_us16x08_meter_store *store = elem->private_data; in snd_us16x08_meter_get()
692 switch (kcontrol->private_value) { in snd_us16x08_meter_get()
700 kcontrol->private_value++; in snd_us16x08_meter_get()
706 kcontrol->private_value++; in snd_us16x08_meter_get()
711 kcontrol->private_value++; in snd_us16x08_meter_get()
721 kcontrol->private_value = 0; in snd_us16x08_meter_get()
730 ucontrol->value.integer.value[i] = in snd_us16x08_meter_get()
731 store ? store->meter_level[i] : 0; in snd_us16x08_meter_get()
734 ucontrol->value.integer.value[i++] = store ? store->master_level[0] : 0; in snd_us16x08_meter_get()
735 ucontrol->value.integer.value[i++] = store ? store->master_level[1] : 0; in snd_us16x08_meter_get()
738 ucontrol->value.integer.value[i + SND_US16X08_MAX_CHANNELS] = in snd_us16x08_meter_get()
739 store ? store->comp_level[i - 2] : 0; in snd_us16x08_meter_get()
747 struct usb_mixer_elem_info *elem = kcontrol->private_data; in snd_us16x08_meter_put()
748 struct snd_us16x08_meter_store *store = elem->private_data; in snd_us16x08_meter_put()
751 val = ucontrol->value.integer.value[0]; in snd_us16x08_meter_put()
755 return -EINVAL; in snd_us16x08_meter_put()
757 store->comp_active_index = val; in snd_us16x08_meter_put()
758 store->comp_index = val; in snd_us16x08_meter_put()
852 sizeof(ratio_map) - 1), /*max*/
970 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][i] in snd_us16x08_create_comp_store()
972 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][i] = 0x00; in snd_us16x08_create_comp_store()
973 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][i] = 0x00; in snd_us16x08_create_comp_store()
974 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][i] = 0x00; in snd_us16x08_create_comp_store()
975 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][i] = 0x00; in snd_us16x08_create_comp_store()
976 tmp->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][i] = 0x00; in snd_us16x08_create_comp_store()
981 /* setup EQ store and assign default values */
993 tmp->val[b_idx][0][i] = 0x0c; in snd_us16x08_create_eq_store()
994 tmp->val[b_idx][3][i] = 0x00; in snd_us16x08_create_eq_store()
996 case 0: /* EQ Low */ in snd_us16x08_create_eq_store()
997 tmp->val[b_idx][1][i] = 0x05; in snd_us16x08_create_eq_store()
998 tmp->val[b_idx][2][i] = 0xff; in snd_us16x08_create_eq_store()
1000 case 1: /* EQ Mid low */ in snd_us16x08_create_eq_store()
1001 tmp->val[b_idx][1][i] = 0x0e; in snd_us16x08_create_eq_store()
1002 tmp->val[b_idx][2][i] = 0x02; in snd_us16x08_create_eq_store()
1004 case 2: /* EQ Mid High */ in snd_us16x08_create_eq_store()
1005 tmp->val[b_idx][1][i] = 0x1b; in snd_us16x08_create_eq_store()
1006 tmp->val[b_idx][2][i] = 0x02; in snd_us16x08_create_eq_store()
1008 case 3: /* EQ High */ in snd_us16x08_create_eq_store()
1009 tmp->val[b_idx][1][i] = 0x2f in snd_us16x08_create_eq_store()
1010 - SND_US16X08_EQ_HIGHFREQ_BIAS; in snd_us16x08_create_eq_store()
1011 tmp->val[b_idx][2][i] = 0xff; in snd_us16x08_create_eq_store()
1026 tmp->comp_index = 1; in snd_us16x08_create_meter_store()
1027 tmp->comp_active_index = 0; in snd_us16x08_create_meter_store()
1031 /* release elem->private_free as well; called only once for each *_store */
1034 struct usb_mixer_elem_info *elem = kctl->private_data; in elem_private_free()
1037 kfree(elem->private_data); in elem_private_free()
1039 kctl->private_data = NULL; in elem_private_free()
1053 usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name); in add_new_ctl()
1057 return -ENOMEM; in add_new_ctl()
1059 elem->head.mixer = mixer; in add_new_ctl()
1060 elem->head.resume = NULL; in add_new_ctl()
1061 elem->control = 0; in add_new_ctl()
1062 elem->idx_off = 0; in add_new_ctl()
1063 elem->head.id = index; in add_new_ctl()
1064 elem->val_type = val_type; in add_new_ctl()
1065 elem->channels = channels; in add_new_ctl()
1066 elem->private_data = opt; in add_new_ctl()
1071 return -ENOMEM; in add_new_ctl()
1075 kctl->private_free = elem_private_free; in add_new_ctl()
1077 kctl->private_free = snd_usb_mixer_elem_free; in add_new_ctl()
1079 strscpy(kctl->id.name, name, sizeof(kctl->id.name)); in add_new_ctl()
1081 err = snd_usb_mixer_add_control(&elem->head, kctl); in add_new_ctl()
1091 /* table of EQ controls */
1093 { /* EQ switch */
1098 .name = "EQ Switch",
1100 { /* EQ low gain */
1105 .name = "EQ Low Volume",
1107 { /* EQ low freq */
1112 .name = "EQ Low Frequency",
1114 { /* EQ mid low gain */
1119 .name = "EQ MidLow Volume",
1121 { /* EQ mid low freq */
1126 .name = "EQ MidLow Frequency",
1128 { /* EQ mid low Q */
1133 .name = "EQ MidLow Q",
1135 { /* EQ mid high gain */
1140 .name = "EQ MidHigh Volume",
1142 { /* EQ mid high freq */
1147 .name = "EQ MidHigh Frequency",
1149 { /* EQ mid high Q */
1154 .name = "EQ MidHigh Q",
1156 { /* EQ high gain */
1161 .name = "EQ High Volume",
1163 { /* EQ low freq */
1168 .name = "EQ High Frequency",
1249 .name = "Pan Left-Right Volume",
1300 /* just check for non-MIDI interface */ in snd_us16x08_controls_create()
1301 if (mixer->hostif->desc.bInterfaceNumber == 3) { in snd_us16x08_controls_create()
1308 usb_audio_dbg(mixer->chip, in snd_us16x08_controls_create()
1314 elem->cache_val[i] = i < 2 ? i : i + 2; in snd_us16x08_controls_create()
1315 elem->cached = 0xff; in snd_us16x08_controls_create()
1320 return -ENOMEM; in snd_us16x08_controls_create()
1336 elem->cache_val[0] = master_controls[i].default_val; in snd_us16x08_controls_create()
1337 elem->cached = 1; in snd_us16x08_controls_create()
1354 elem->cache_val[j] = in snd_us16x08_controls_create()
1357 elem->cached = 0xffff; in snd_us16x08_controls_create()
1360 /* create eq store */ in snd_us16x08_controls_create()
1363 return -ENOMEM; in snd_us16x08_controls_create()
1365 /* add EQ controls */ in snd_us16x08_controls_create()
1399 return -ENOMEM; in snd_us16x08_controls_create()
1404 meter_store->comp_store = comp_store; in snd_us16x08_controls_create()
1406 SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter", in snd_us16x08_controls_create()