Skip to content

Commit eeca59a

Browse files
puleglottiwai
authored andcommitted
ALSA: usb-audio: Support read-only clock selector control
Clock selector control might be read-only. Add corresponding checks to prevent sending control requests that would fail. Signed-off-by: Alexander Tsoy <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 668abe6 commit eeca59a

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

sound/usb/clock.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
261261
int ret, i, cur, err, pins, clock_id;
262262
const u8 *sources;
263263
int proto = fmt->protocol;
264+
bool readable, writeable;
265+
u32 bmControls;
264266

265267
entity_id &= 0xff;
266268

@@ -292,11 +294,27 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
292294
sources = GET_VAL(selector, proto, baCSourceID);
293295
cur = 0;
294296

297+
if (proto == UAC_VERSION_3)
298+
bmControls = le32_to_cpu(*(__le32 *)(&selector->v3.baCSourceID[0] + pins));
299+
else
300+
bmControls = *(__u8 *)(&selector->v2.baCSourceID[0] + pins);
301+
302+
readable = uac_v2v3_control_is_readable(bmControls,
303+
UAC2_CX_CLOCK_SELECTOR);
304+
writeable = uac_v2v3_control_is_writeable(bmControls,
305+
UAC2_CX_CLOCK_SELECTOR);
306+
295307
if (pins == 1) {
296308
ret = 1;
297309
goto find_source;
298310
}
299311

312+
/* for now just warn about buggy device */
313+
if (!readable)
314+
usb_audio_warn(chip,
315+
"%s(): clock selector control is not readable, id %d\n",
316+
__func__, clock_id);
317+
300318
/* the entity ID we are looking at is a selector.
301319
* find out what it currently selects */
302320
ret = uac_clock_selector_get_val(chip, clock_id);
@@ -326,7 +344,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
326344
if (ret > 0) {
327345
/* Skip setting clock selector again for some devices */
328346
if (chip->quirk_flags & QUIRK_FLAG_SKIP_CLOCK_SELECTOR ||
329-
pins == 1)
347+
pins == 1 || !writeable)
330348
return ret;
331349
err = uac_clock_selector_set_val(chip, entity_id, cur);
332350
if (err < 0)
@@ -337,6 +355,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
337355
return ret;
338356

339357
find_others:
358+
if (!writeable)
359+
return -ENXIO;
360+
340361
/* The current clock source is invalid, try others. */
341362
for (i = 1; i <= pins; i++) {
342363
if (i == cur)

0 commit comments

Comments
 (0)