Skip to content

Commit 6aa8700

Browse files
kkosik20tiwai
authored andcommitted
ALSA: usb-audio: Support multiple control interfaces
Registering Numark Party Mix II fails with error 'bogus bTerminalLink 1'. The problem stems from the driver not being able to find input/output terminals required to configure audio streaming. The information about those terminals is stored in AudioControl Interface. Numark device contains 2 AudioControl Interfaces and the driver checks only one of them. According to the USB standard, a device can have multiple audio functions, each represented by Audio Interface Collection. Every audio function is considered to be closed box and will contain unique AudioControl Interface and zero or more AudioStreaming and MIDIStreaming Interfaces. The Numark device adheres to the standard and defines two audio functions: - MIDIStreaming function - AudioStreaming function It starts with MIDI function, followed by the audio function. The driver saves the first AudioControl Interface in `snd_usb_audio` structure associated with the entire device. It then attempts to use this interface to query for terminals and clocks. However, this fails because the correct information is stored in the second AudioControl Interface, defined in the second Audio Interface Collection. This patch introduces a structure holding association between each MIDI/Audio Interface and its corresponding AudioControl Interface, instead of relying on AudioControl Interface defined for the entire device. This structure is populated during usb probing phase and leveraged later when querying for terminals and when sending USB requests. Alternative solutions considered include: - defining a quirk for Numark where the order of interface is manually changed, or terminals are hardcoded in the driver. This solution would have fixed only this model, though it seems that device is USB compliant, and it also seems that other devices from this company may be affected. What's more, it looks like products from other manufacturers have similar problems, i.e. Rane One DJ console - keeping a list of all AudioControl Interfaces and querying all of them to find required information. That would have solved my problem and have low probability of breaking other devices, as we would always start with the same logic of querying first AudioControl Interface. This solution would not have followed the standard though. This patch preserves the `snd_usb_audio.ctrl_intf` variable, which holds the first AudioControl Interface, and uses it as a fallback when some interfaces are not parsed correctly and lack an associated AudioControl Interface, i.e., when configured via quirks. Link: https://bugzilla.kernel.org/show_bug.cgi?id=217865 Signed-off-by: Karol Kosik <k.kosik@outlook.com> Link: https://patch.msgid.link/AS8P190MB1285893F4735C8B32AD3886BEC852@AS8P190MB1285.EURP190.PROD.OUTLOOK.COM Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent ebfb5a5 commit 6aa8700

File tree

12 files changed

+127
-47
lines changed

12 files changed

+127
-47
lines changed

sound/usb/card.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int
206206
return -EINVAL;
207207
}
208208

209+
snd_usb_add_ctrl_interface_link(chip, interface, ctrlif);
210+
209211
if (! snd_usb_parse_audio_interface(chip, interface)) {
210212
usb_set_interface(dev, interface, 0); /* reset the current interface */
211213
return usb_driver_claim_interface(&usb_audio_driver, iface,

sound/usb/clock.c

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,14 @@ static bool validate_clock_multiplier(void *p, int id, int proto)
7676
}
7777

7878
#define DEFINE_FIND_HELPER(name, obj, validator, type2, type3) \
79-
static obj *name(struct snd_usb_audio *chip, int id, int proto) \
79+
static obj *name(struct snd_usb_audio *chip, int id, \
80+
const struct audioformat *fmt) \
8081
{ \
81-
return find_uac_clock_desc(chip->ctrl_intf, id, validator, \
82-
proto == UAC_VERSION_3 ? (type3) : (type2), \
83-
proto); \
82+
struct usb_host_interface *ctrl_intf = \
83+
snd_usb_find_ctrl_interface(chip, fmt->iface); \
84+
return find_uac_clock_desc(ctrl_intf, id, validator, \
85+
fmt->protocol == UAC_VERSION_3 ? (type3) : (type2), \
86+
fmt->protocol); \
8487
}
8588

8689
DEFINE_FIND_HELPER(snd_usb_find_clock_source,
@@ -93,16 +96,19 @@ DEFINE_FIND_HELPER(snd_usb_find_clock_multiplier,
9396
union uac23_clock_multiplier_desc, validate_clock_multiplier,
9497
UAC2_CLOCK_MULTIPLIER, UAC3_CLOCK_MULTIPLIER);
9598

96-
static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
99+
static int uac_clock_selector_get_val(struct snd_usb_audio *chip,
100+
int selector_id, int iface_no)
97101
{
102+
struct usb_host_interface *ctrl_intf;
98103
unsigned char buf;
99104
int ret;
100105

106+
ctrl_intf = snd_usb_find_ctrl_interface(chip, iface_no);
101107
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),
102108
UAC2_CS_CUR,
103109
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
104110
UAC2_CX_CLOCK_SELECTOR << 8,
105-
snd_usb_ctrl_intf(chip) | (selector_id << 8),
111+
snd_usb_ctrl_intf(ctrl_intf) | (selector_id << 8),
106112
&buf, sizeof(buf));
107113

108114
if (ret < 0)
@@ -111,16 +117,18 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i
111117
return buf;
112118
}
113119

114-
static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_id,
115-
unsigned char pin)
120+
static int uac_clock_selector_set_val(struct snd_usb_audio *chip,
121+
int selector_id, unsigned char pin, int iface_no)
116122
{
123+
struct usb_host_interface *ctrl_intf;
117124
int ret;
118125

126+
ctrl_intf = snd_usb_find_ctrl_interface(chip, iface_no);
119127
ret = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
120128
UAC2_CS_CUR,
121129
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
122130
UAC2_CX_CLOCK_SELECTOR << 8,
123-
snd_usb_ctrl_intf(chip) | (selector_id << 8),
131+
snd_usb_ctrl_intf(ctrl_intf) | (selector_id << 8),
124132
&pin, sizeof(pin));
125133
if (ret < 0)
126134
return ret;
@@ -132,7 +140,7 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_i
132140
return -EINVAL;
133141
}
134142

135-
ret = uac_clock_selector_get_val(chip, selector_id);
143+
ret = uac_clock_selector_get_val(chip, selector_id, iface_no);
136144
if (ret < 0)
137145
return ret;
138146

@@ -155,8 +163,10 @@ static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
155163
unsigned char data;
156164
struct usb_device *dev = chip->dev;
157165
union uac23_clock_source_desc *cs_desc;
166+
struct usb_host_interface *ctrl_intf;
158167

159-
cs_desc = snd_usb_find_clock_source(chip, source_id, fmt->protocol);
168+
ctrl_intf = snd_usb_find_ctrl_interface(chip, fmt->iface);
169+
cs_desc = snd_usb_find_clock_source(chip, source_id, fmt);
160170
if (!cs_desc)
161171
return false;
162172

@@ -191,7 +201,7 @@ static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
191201
err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
192202
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
193203
UAC2_CS_CONTROL_CLOCK_VALID << 8,
194-
snd_usb_ctrl_intf(chip) | (source_id << 8),
204+
snd_usb_ctrl_intf(ctrl_intf) | (source_id << 8),
195205
&data, sizeof(data));
196206
if (err < 0) {
197207
dev_warn(&dev->dev,
@@ -217,8 +227,10 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
217227
struct usb_device *dev = chip->dev;
218228
u32 bmControls;
219229
union uac23_clock_source_desc *cs_desc;
230+
struct usb_host_interface *ctrl_intf;
220231

221-
cs_desc = snd_usb_find_clock_source(chip, source_id, fmt->protocol);
232+
ctrl_intf = snd_usb_find_ctrl_interface(chip, fmt->iface);
233+
cs_desc = snd_usb_find_clock_source(chip, source_id, fmt);
222234
if (!cs_desc)
223235
return false;
224236

@@ -235,7 +247,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
235247
err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
236248
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
237249
UAC2_CS_CONTROL_CLOCK_VALID << 8,
238-
snd_usb_ctrl_intf(chip) | (source_id << 8),
250+
snd_usb_ctrl_intf(ctrl_intf) | (source_id << 8),
239251
&data, sizeof(data));
240252

241253
if (err < 0) {
@@ -274,7 +286,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
274286
}
275287

276288
/* first, see if the ID we're looking at is a clock source already */
277-
source = snd_usb_find_clock_source(chip, entity_id, proto);
289+
source = snd_usb_find_clock_source(chip, entity_id, fmt);
278290
if (source) {
279291
entity_id = GET_VAL(source, proto, bClockID);
280292
if (validate && !uac_clock_source_is_valid(chip, fmt,
@@ -287,7 +299,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
287299
return entity_id;
288300
}
289301

290-
selector = snd_usb_find_clock_selector(chip, entity_id, proto);
302+
selector = snd_usb_find_clock_selector(chip, entity_id, fmt);
291303
if (selector) {
292304
pins = GET_VAL(selector, proto, bNrInPins);
293305
clock_id = GET_VAL(selector, proto, bClockID);
@@ -317,7 +329,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
317329

318330
/* the entity ID we are looking at is a selector.
319331
* find out what it currently selects */
320-
ret = uac_clock_selector_get_val(chip, clock_id);
332+
ret = uac_clock_selector_get_val(chip, clock_id, fmt->iface);
321333
if (ret < 0) {
322334
if (!chip->autoclock)
323335
return ret;
@@ -346,7 +358,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
346358
if (chip->quirk_flags & QUIRK_FLAG_SKIP_CLOCK_SELECTOR ||
347359
!writeable)
348360
return ret;
349-
err = uac_clock_selector_set_val(chip, entity_id, cur);
361+
err = uac_clock_selector_set_val(chip, entity_id, cur, fmt->iface);
350362
if (err < 0) {
351363
if (pins == 1) {
352364
usb_audio_dbg(chip,
@@ -377,7 +389,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
377389
if (ret < 0)
378390
continue;
379391

380-
err = uac_clock_selector_set_val(chip, entity_id, i);
392+
err = uac_clock_selector_set_val(chip, entity_id, i, fmt->iface);
381393
if (err < 0)
382394
continue;
383395

@@ -391,7 +403,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
391403
}
392404

393405
/* FIXME: multipliers only act as pass-thru element for now */
394-
multiplier = snd_usb_find_clock_multiplier(chip, entity_id, proto);
406+
multiplier = snd_usb_find_clock_multiplier(chip, entity_id, fmt);
395407
if (multiplier)
396408
return __uac_clock_find_source(chip, fmt,
397409
GET_VAL(multiplier, proto, bCSourceID),
@@ -491,11 +503,13 @@ static int get_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
491503
struct usb_device *dev = chip->dev;
492504
__le32 data;
493505
int err;
506+
struct usb_host_interface *ctrl_intf;
494507

508+
ctrl_intf = snd_usb_find_ctrl_interface(chip, iface);
495509
err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
496510
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
497511
UAC2_CS_CONTROL_SAM_FREQ << 8,
498-
snd_usb_ctrl_intf(chip) | (clock << 8),
512+
snd_usb_ctrl_intf(ctrl_intf) | (clock << 8),
499513
&data, sizeof(data));
500514
if (err < 0) {
501515
dev_warn(&dev->dev, "%d:%d: cannot get freq (v2/v3): err %d\n",
@@ -524,8 +538,10 @@ int snd_usb_set_sample_rate_v2v3(struct snd_usb_audio *chip,
524538
__le32 data;
525539
int err;
526540
union uac23_clock_source_desc *cs_desc;
541+
struct usb_host_interface *ctrl_intf;
527542

528-
cs_desc = snd_usb_find_clock_source(chip, clock, fmt->protocol);
543+
ctrl_intf = snd_usb_find_ctrl_interface(chip, fmt->iface);
544+
cs_desc = snd_usb_find_clock_source(chip, clock, fmt);
529545

530546
if (!cs_desc)
531547
return 0;
@@ -544,7 +560,7 @@ int snd_usb_set_sample_rate_v2v3(struct snd_usb_audio *chip,
544560
err = snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC2_CS_CUR,
545561
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
546562
UAC2_CS_CONTROL_SAM_FREQ << 8,
547-
snd_usb_ctrl_intf(chip) | (clock << 8),
563+
snd_usb_ctrl_intf(ctrl_intf) | (clock << 8),
548564
&data, sizeof(data));
549565
if (err < 0)
550566
return err;

sound/usb/format.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,9 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,
545545
unsigned char tmp[2], *data;
546546
int nr_triplets, data_size, ret = 0, ret_l6;
547547
int clock = snd_usb_clock_find_source(chip, fp, false);
548+
struct usb_host_interface *ctrl_intf;
548549

550+
ctrl_intf = snd_usb_find_ctrl_interface(chip, fp->iface);
549551
if (clock < 0) {
550552
dev_err(&dev->dev,
551553
"%s(): unable to find clock source (clock %d)\n",
@@ -557,7 +559,7 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,
557559
ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
558560
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
559561
UAC2_CS_CONTROL_SAM_FREQ << 8,
560-
snd_usb_ctrl_intf(chip) | (clock << 8),
562+
snd_usb_ctrl_intf(ctrl_intf) | (clock << 8),
561563
tmp, sizeof(tmp));
562564

563565
if (ret < 0) {
@@ -592,7 +594,7 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,
592594
ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
593595
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
594596
UAC2_CS_CONTROL_SAM_FREQ << 8,
595-
snd_usb_ctrl_intf(chip) | (clock << 8),
597+
snd_usb_ctrl_intf(ctrl_intf) | (clock << 8),
596598
data, data_size);
597599

598600
if (ret < 0) {

sound/usb/helper.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,37 @@ snd_usb_get_host_interface(struct snd_usb_audio *chip, int ifnum, int altsetting
130130
return NULL;
131131
return usb_altnum_to_altsetting(iface, altsetting);
132132
}
133+
134+
int snd_usb_add_ctrl_interface_link(struct snd_usb_audio *chip, int ifnum,
135+
int ctrlif)
136+
{
137+
struct usb_device *dev = chip->dev;
138+
struct usb_host_interface *host_iface;
139+
140+
if (chip->num_intf_to_ctrl >= MAX_CARD_INTERFACES) {
141+
dev_info(&dev->dev, "Too many interfaces assigned to the single USB-audio card\n");
142+
return -EINVAL;
143+
}
144+
145+
/* find audiocontrol interface */
146+
host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
147+
148+
chip->intf_to_ctrl[chip->num_intf_to_ctrl].interface = ifnum;
149+
chip->intf_to_ctrl[chip->num_intf_to_ctrl].ctrl_intf = host_iface;
150+
chip->num_intf_to_ctrl++;
151+
152+
return 0;
153+
}
154+
155+
struct usb_host_interface *snd_usb_find_ctrl_interface(struct snd_usb_audio *chip,
156+
int ifnum)
157+
{
158+
int i;
159+
160+
for (i = 0; i < chip->num_intf_to_ctrl; ++i)
161+
if (chip->intf_to_ctrl[i].interface == ifnum)
162+
return chip->intf_to_ctrl[i].ctrl_intf;
163+
164+
/* Fallback to first audiocontrol interface */
165+
return chip->ctrl_intf;
166+
}

sound/usb/helper.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
1717
struct usb_host_interface *
1818
snd_usb_get_host_interface(struct snd_usb_audio *chip, int ifnum, int altsetting);
1919

20+
int snd_usb_add_ctrl_interface_link(struct snd_usb_audio *chip, int ifnum,
21+
int ctrlif);
22+
23+
struct usb_host_interface *snd_usb_find_ctrl_interface(struct snd_usb_audio *chip,
24+
int ifnum);
25+
2026
/*
2127
* retrieve usb_interface descriptor from the host interface
2228
* (conditional for compatibility with the older API)
@@ -28,9 +34,9 @@ snd_usb_get_host_interface(struct snd_usb_audio *chip, int ifnum, int altsetting
2834

2935
#define snd_usb_get_speed(dev) ((dev)->speed)
3036

31-
static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip)
37+
static inline int snd_usb_ctrl_intf(struct usb_host_interface *ctrl_intf)
3238
{
33-
return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber;
39+
return get_iface_desc(ctrl_intf)->bInterfaceNumber;
3440
}
3541

3642
/* in validate.c */

sound/usb/mixer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ static int get_cluster_channels_v3(struct mixer_build *state, unsigned int clust
728728
UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
729729
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
730730
cluster_id,
731-
snd_usb_ctrl_intf(state->chip),
731+
snd_usb_ctrl_intf(state->mixer->hostif),
732732
&c_header, sizeof(c_header));
733733
if (err < 0)
734734
goto error;

sound/usb/mixer_quirks.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,7 +1043,7 @@ static int snd_ftu_eff_switch_init(struct usb_mixer_interface *mixer,
10431043
err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
10441044
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
10451045
pval & 0xff00,
1046-
snd_usb_ctrl_intf(mixer->chip) | ((pval & 0xff) << 8),
1046+
snd_usb_ctrl_intf(mixer->hostif) | ((pval & 0xff) << 8),
10471047
value, 2);
10481048
if (err < 0)
10491049
return err;
@@ -1077,7 +1077,7 @@ static int snd_ftu_eff_switch_update(struct usb_mixer_elem_list *list)
10771077
UAC_SET_CUR,
10781078
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
10791079
pval & 0xff00,
1080-
snd_usb_ctrl_intf(chip) | ((pval & 0xff) << 8),
1080+
snd_usb_ctrl_intf(list->mixer->hostif) | ((pval & 0xff) << 8),
10811081
value, 2);
10821082
snd_usb_unlock_shutdown(chip);
10831083
return err;
@@ -2115,24 +2115,25 @@ static int dell_dock_mixer_create(struct usb_mixer_interface *mixer)
21152115
return 0;
21162116
}
21172117

2118-
static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id)
2118+
static void dell_dock_init_vol(struct usb_mixer_interface *mixer, int ch, int id)
21192119
{
2120+
struct snd_usb_audio *chip = mixer->chip;
21202121
u16 buf = 0;
21212122

21222123
snd_usb_ctl_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
21232124
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
21242125
(UAC_FU_VOLUME << 8) | ch,
2125-
snd_usb_ctrl_intf(chip) | (id << 8),
2126+
snd_usb_ctrl_intf(mixer->hostif) | (id << 8),
21262127
&buf, 2);
21272128
}
21282129

21292130
static int dell_dock_mixer_init(struct usb_mixer_interface *mixer)
21302131
{
21312132
/* fix to 0dB playback volumes */
2132-
dell_dock_init_vol(mixer->chip, 1, 16);
2133-
dell_dock_init_vol(mixer->chip, 2, 16);
2134-
dell_dock_init_vol(mixer->chip, 1, 19);
2135-
dell_dock_init_vol(mixer->chip, 2, 19);
2133+
dell_dock_init_vol(mixer, 1, 16);
2134+
dell_dock_init_vol(mixer, 2, 16);
2135+
dell_dock_init_vol(mixer, 1, 19);
2136+
dell_dock_init_vol(mixer, 2, 19);
21362137
return 0;
21372138
}
21382139

sound/usb/mixer_scarlett.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ static int scarlett_ctl_meter_get(struct snd_kcontrol *kctl,
460460
struct snd_usb_audio *chip = elem->head.mixer->chip;
461461
unsigned char buf[2 * MAX_CHANNELS] = {0, };
462462
int wValue = (elem->control << 8) | elem->idx_off;
463-
int idx = snd_usb_ctrl_intf(chip) | (elem->head.id << 8);
463+
int idx = snd_usb_ctrl_intf(elem->head.mixer->hostif) | (elem->head.id << 8);
464464
int err;
465465

466466
err = snd_usb_ctl_msg(chip->dev,
@@ -1002,7 +1002,7 @@ int snd_scarlett_controls_create(struct usb_mixer_interface *mixer)
10021002
err = snd_usb_ctl_msg(mixer->chip->dev,
10031003
usb_sndctrlpipe(mixer->chip->dev, 0), UAC2_CS_CUR,
10041004
USB_RECIP_INTERFACE | USB_TYPE_CLASS |
1005-
USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->chip) |
1005+
USB_DIR_OUT, 0x0100, snd_usb_ctrl_intf(mixer->hostif) |
10061006
(0x29 << 8), sample_rate_buffer, 4);
10071007
if (err < 0)
10081008
return err;

sound/usb/power.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ snd_usb_find_power_domain(struct usb_host_interface *ctrl_iface,
4040
le16_to_cpu(pd_desc->waRecoveryTime1);
4141
pd->pd_d2d0_rec =
4242
le16_to_cpu(pd_desc->waRecoveryTime2);
43+
pd->ctrl_iface = ctrl_iface;
4344
return pd;
4445
}
4546
}
@@ -57,7 +58,7 @@ int snd_usb_power_domain_set(struct snd_usb_audio *chip,
5758
unsigned char current_state;
5859
int err, idx;
5960

60-
idx = snd_usb_ctrl_intf(chip) | (pd->pd_id << 8);
61+
idx = snd_usb_ctrl_intf(pd->ctrl_iface) | (pd->pd_id << 8);
6162

6263
err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),
6364
UAC2_CS_CUR,

0 commit comments

Comments
 (0)