hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/sound/usb/mixer.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * (Tentative) USB Audio Driver for ALSA
34 *
....@@ -8,22 +9,6 @@
89 * Many codes borrowed from audio.c by
910 * Alan Cox (alan@lxorguk.ukuu.org.uk)
1011 * Thomas Sailer (sailer@ife.ee.ethz.ch)
11
- *
12
- *
13
- * This program is free software; you can redistribute it and/or modify
14
- * it under the terms of the GNU General Public License as published by
15
- * the Free Software Foundation; either version 2 of the License, or
16
- * (at your option) any later version.
17
- *
18
- * This program is distributed in the hope that it will be useful,
19
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- * GNU General Public License for more details.
22
- *
23
- * You should have received a copy of the GNU General Public License
24
- * along with this program; if not, write to the Free Software
25
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
- *
2712 */
2813
2914 /*
....@@ -307,6 +292,11 @@
307292 * retrieve a mixer value
308293 */
309294
295
+static inline int mixer_ctrl_intf(struct usb_mixer_interface *mixer)
296
+{
297
+ return get_iface_desc(mixer->hostif)->bInterfaceNumber;
298
+}
299
+
310300 static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request,
311301 int validx, int *value_ret)
312302 {
....@@ -321,7 +311,7 @@
321311 return -EIO;
322312
323313 while (timeout-- > 0) {
324
- idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
314
+ idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
325315 err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
326316 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
327317 validx, idx, buf, val_len);
....@@ -369,7 +359,7 @@
369359 if (ret)
370360 goto error;
371361
372
- idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
362
+ idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
373363 ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
374364 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
375365 validx, idx, buf, size);
....@@ -494,7 +484,7 @@
494484 return -EIO;
495485
496486 while (timeout-- > 0) {
497
- idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
487
+ idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
498488 err = snd_usb_ctl_msg(chip->dev,
499489 usb_sndctrlpipe(chip->dev, 0), request,
500490 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
....@@ -918,6 +908,12 @@
918908 struct usb_audio_term *term,
919909 void *p1, int id)
920910 {
911
+ struct uac2_effect_unit_descriptor *d = p1;
912
+ int err;
913
+
914
+ err = __check_input_term(state, d->bSourceID, term);
915
+ if (err < 0)
916
+ return err;
921917 term->type = UAC3_EFFECT_UNIT << 16; /* virtual type */
922918 term->id = id;
923919 return 0;
....@@ -1228,7 +1224,7 @@
12281224 get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
12291225 usb_audio_err(cval->head.mixer->chip,
12301226 "%d:%d: cannot get min/max values for control %d (id %d)\n",
1231
- cval->head.id, snd_usb_ctrl_intf(cval->head.mixer->chip),
1227
+ cval->head.id, mixer_ctrl_intf(cval->head.mixer),
12321228 cval->control, cval->head.id);
12331229 return -EINVAL;
12341230 }
....@@ -1304,6 +1300,17 @@
13041300 if (cval->dBmin > cval->dBmax) {
13051301 /* totally crap, return an error */
13061302 return -EINVAL;
1303
+ }
1304
+ } else {
1305
+ /* if the max volume is too low, it's likely a bogus range;
1306
+ * here we use -96dB as the threshold
1307
+ */
1308
+ if (cval->dBmax <= -9600) {
1309
+ usb_audio_info(cval->head.mixer->chip,
1310
+ "%d:%d: bogus dB values (%d/%d), disabling dB reporting\n",
1311
+ cval->head.id, mixer_ctrl_intf(cval->head.mixer),
1312
+ cval->dBmin, cval->dBmax);
1313
+ cval->dBmin = cval->dBmax = 0;
13071314 }
13081315 }
13091316
....@@ -1447,7 +1454,7 @@
14471454 if (ret)
14481455 goto error;
14491456
1450
- idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8);
1457
+ idx = mixer_ctrl_intf(cval->head.mixer) | (cval->head.id << 8);
14511458 if (cval->head.mixer->protocol == UAC_VERSION_2) {
14521459 struct uac2_connectors_ctl_blk uac2_conn;
14531460
....@@ -1467,6 +1474,10 @@
14671474 snd_usb_unlock_shutdown(chip);
14681475
14691476 if (ret < 0) {
1477
+ if (strstr(kcontrol->id.name, "Speaker")) {
1478
+ ucontrol->value.integer.value[0] = 1;
1479
+ return 0;
1480
+ }
14701481 error:
14711482 usb_audio_err(chip,
14721483 "cannot get connectors status: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
....@@ -1478,7 +1489,7 @@
14781489 return 0;
14791490 }
14801491
1481
-static struct snd_kcontrol_new usb_feature_unit_ctl = {
1492
+static const struct snd_kcontrol_new usb_feature_unit_ctl = {
14821493 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14831494 .name = "", /* will be filled later manually */
14841495 .info = mixer_ctl_feature_info,
....@@ -1499,7 +1510,7 @@
14991510 * A control which shows the boolean value from reading a UAC control on
15001511 * the master channel.
15011512 */
1502
-static struct snd_kcontrol_new usb_bool_master_control_ctl_ro = {
1513
+static const struct snd_kcontrol_new usb_bool_master_control_ctl_ro = {
15031514 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
15041515 .name = "", /* will be filled later manually */
15051516 .access = SNDRV_CTL_ELEM_ACCESS_READ,
....@@ -1521,7 +1532,7 @@
15211532 * This symbol is exported in order to allow the mixer quirks to
15221533 * hook up to the standard feature unit control mechanism
15231534 */
1524
-struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;
1535
+const struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;
15251536
15261537 /*
15271538 * build a feature control
....@@ -1899,7 +1910,7 @@
18991910 {
19001911 int channels, i, j;
19011912 struct usb_audio_term iterm;
1902
- unsigned int master_bits, first_ch_bits;
1913
+ unsigned int master_bits;
19031914 int err, csize;
19041915 struct uac_feature_unit_descriptor *hdr = _ftr;
19051916 __u8 *bmaControls;
....@@ -1948,10 +1959,6 @@
19481959 break;
19491960
19501961 }
1951
- if (channels > 0)
1952
- first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
1953
- else
1954
- first_ch_bits = 0;
19551962
19561963 if (state->mixer->protocol == UAC_VERSION_1) {
19571964 /* check all control types */
....@@ -2375,7 +2382,7 @@
23752382 int num_ins;
23762383 struct usb_mixer_elem_info *cval;
23772384 struct snd_kcontrol *kctl;
2378
- int i, err, nameid, type, len;
2385
+ int i, err, nameid, type, len, val;
23792386 const struct procunit_info *info;
23802387 const struct procunit_value_info *valinfo;
23812388 const struct usbmix_name_map *map;
....@@ -2476,6 +2483,12 @@
24762483 default:
24772484 get_min_max(cval, valinfo->min_value);
24782485 break;
2486
+ }
2487
+
2488
+ err = get_cur_ctl_value(cval, cval->control << 8, &val);
2489
+ if (err < 0) {
2490
+ usb_mixer_elem_info_free(cval);
2491
+ return -EINVAL;
24792492 }
24802493
24812494 kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
....@@ -3261,7 +3274,15 @@
32613274 {
32623275 struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
32633276 static const char * const val_types[] = {
3264
- "BOOLEAN", "INV_BOOLEAN", "S8", "U8", "S16", "U16", "S32", "U32",
3277
+ [USB_MIXER_BOOLEAN] = "BOOLEAN",
3278
+ [USB_MIXER_INV_BOOLEAN] = "INV_BOOLEAN",
3279
+ [USB_MIXER_S8] = "S8",
3280
+ [USB_MIXER_U8] = "U8",
3281
+ [USB_MIXER_S16] = "S16",
3282
+ [USB_MIXER_U16] = "U16",
3283
+ [USB_MIXER_S32] = "S32",
3284
+ [USB_MIXER_U32] = "U32",
3285
+ [USB_MIXER_BESPOKEN] = "BESPOKEN",
32653286 };
32663287 snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
32673288 "channels=%i, type=\"%s\"\n", cval->head.id,
....@@ -3282,7 +3303,7 @@
32823303 list_for_each_entry(mixer, &chip->mixer_list, list) {
32833304 snd_iprintf(buffer,
32843305 "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
3285
- chip->usb_id, snd_usb_ctrl_intf(chip),
3306
+ chip->usb_id, mixer_ctrl_intf(mixer),
32863307 mixer->ignore_ctl_error);
32873308 snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
32883309 for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
....@@ -3498,11 +3519,10 @@
34983519 int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
34993520 int ignore_error)
35003521 {
3501
- static struct snd_device_ops dev_ops = {
3522
+ static const struct snd_device_ops dev_ops = {
35023523 .dev_free = snd_usb_mixer_dev_free
35033524 };
35043525 struct usb_mixer_interface *mixer;
3505
- struct snd_info_entry *entry;
35063526 int err;
35073527
35083528 strcpy(chip->card->mixername, "USB Mixer");
....@@ -3560,9 +3580,9 @@
35603580 if (err < 0)
35613581 goto _error;
35623582
3563
- if (list_empty(&chip->mixer_list) &&
3564
- !snd_card_proc_new(chip->card, "usbmixer", &entry))
3565
- snd_info_set_text_ops(entry, chip, snd_usb_mixer_proc_read);
3583
+ if (list_empty(&chip->mixer_list))
3584
+ snd_card_ro_proc_new(chip->card, "usbmixer", chip,
3585
+ snd_usb_mixer_proc_read);
35663586
35673587 list_add(&mixer->list, &chip->mixer_list);
35683588 return 0;
....@@ -3580,6 +3600,8 @@
35803600 usb_kill_urb(mixer->urb);
35813601 if (mixer->rc_urb)
35823602 usb_kill_urb(mixer->rc_urb);
3603
+ if (mixer->private_free)
3604
+ mixer->private_free(mixer);
35833605 mixer->disconnected = true;
35843606 }
35853607
....@@ -3607,6 +3629,8 @@
36073629 int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer)
36083630 {
36093631 snd_usb_mixer_inactivate(mixer);
3632
+ if (mixer->private_suspend)
3633
+ mixer->private_suspend(mixer);
36103634 return 0;
36113635 }
36123636
....@@ -3615,6 +3639,9 @@
36153639 struct usb_mixer_elem_info *cval = mixer_elem_list_to_info(list);
36163640 int c, err, idx;
36173641
3642
+ if (cval->val_type == USB_MIXER_BESPOKEN)
3643
+ return 0;
3644
+
36183645 if (cval->cmask) {
36193646 idx = 0;
36203647 for (c = 0; c < MAX_CHANNELS; c++) {