Skip to content

Commit fef66ae

Browse files
committed
ALSA: usb-audio: Add connector notifier delegation
It turned out that ALC1220-VB USB-audio device gives the interrupt event to some PCM terminals while those don't allow the connector state request but only the actual I/O terminals return the request. The recent commit 7dc3c5a ("ALSA: usb-audio: Don't create jack controls for PCM terminals") excluded those phantom terminals, so those events are ignored, too. My first thought was that this could be easily deduced from the associated terminals, but some of them have even no associate terminal ID, hence it's not too trivial to figure out. Since the number of such terminals are small and limited, this patch implements another quirk table for the simple mapping of the connectors. It's not really scalable, but let's hope that there will be not many such funky devices in future. Fixes: 7dc3c5a ("ALSA: usb-audio: Don't create jack controls for PCM terminals") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206873 Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent e7b6b3e commit fef66ae

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

sound/usb/mixer.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3117,6 +3117,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
31173117
if (map->id == state.chip->usb_id) {
31183118
state.map = map->map;
31193119
state.selector_map = map->selector_map;
3120+
mixer->connector_map = map->connector_map;
31203121
mixer->ignore_ctl_error |= map->ignore_ctl_error;
31213122
break;
31223123
}
@@ -3198,10 +3199,32 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
31983199
return 0;
31993200
}
32003201

3202+
static int delegate_notify(struct usb_mixer_interface *mixer, int unitid,
3203+
u8 *control, u8 *channel)
3204+
{
3205+
const struct usbmix_connector_map *map = mixer->connector_map;
3206+
3207+
if (!map)
3208+
return unitid;
3209+
3210+
for (; map->id; map++) {
3211+
if (map->id == unitid) {
3212+
if (control && map->control)
3213+
*control = map->control;
3214+
if (channel && map->channel)
3215+
*channel = map->channel;
3216+
return map->delegated_id;
3217+
}
3218+
}
3219+
return unitid;
3220+
}
3221+
32013222
void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
32023223
{
32033224
struct usb_mixer_elem_list *list;
32043225

3226+
unitid = delegate_notify(mixer, unitid, NULL, NULL);
3227+
32053228
for_each_mixer_elem(list, mixer, unitid) {
32063229
struct usb_mixer_elem_info *info =
32073230
mixer_elem_list_to_info(list);
@@ -3271,6 +3294,8 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
32713294
return;
32723295
}
32733296

3297+
unitid = delegate_notify(mixer, unitid, &control, &channel);
3298+
32743299
for_each_mixer_elem(list, mixer, unitid)
32753300
count++;
32763301

sound/usb/mixer.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
struct media_mixer_ctl;
88

9+
struct usbmix_connector_map {
10+
u8 id;
11+
u8 delegated_id;
12+
u8 control;
13+
u8 channel;
14+
};
15+
916
struct usb_mixer_interface {
1017
struct snd_usb_audio *chip;
1118
struct usb_host_interface *hostif;
@@ -18,6 +25,9 @@ struct usb_mixer_interface {
1825
/* the usb audio specification version this interface complies to */
1926
int protocol;
2027

28+
/* optional connector delegation map */
29+
const struct usbmix_connector_map *connector_map;
30+
2131
/* Sound Blaster remote control stuff */
2232
const struct rc_config *rc_cfg;
2333
u32 rc_code;

sound/usb/mixer_maps.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct usbmix_ctl_map {
2727
u32 id;
2828
const struct usbmix_name_map *map;
2929
const struct usbmix_selector_map *selector_map;
30+
const struct usbmix_connector_map *connector_map;
3031
int ignore_ctl_error;
3132
};
3233

@@ -387,6 +388,15 @@ static const struct usbmix_name_map trx40_mobo_map[] = {
387388
{}
388389
};
389390

391+
static const struct usbmix_connector_map trx40_mobo_connector_map[] = {
392+
{ 10, 16 }, /* (Back) Speaker */
393+
{ 11, 17 }, /* Front Headphone */
394+
{ 13, 7 }, /* Line */
395+
{ 14, 8 }, /* Mic */
396+
{ 15, 9 }, /* Front Mic */
397+
{}
398+
};
399+
390400
/*
391401
* Control map entries
392402
*/
@@ -519,6 +529,7 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
519529
{ /* Gigabyte TRX40 Aorus Pro WiFi */
520530
.id = USB_ID(0x0414, 0xa002),
521531
.map = trx40_mobo_map,
532+
.connector_map = trx40_mobo_connector_map,
522533
},
523534
{ /* ASUS ROG Zenith II */
524535
.id = USB_ID(0x0b05, 0x1916),
@@ -531,10 +542,12 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
531542
{ /* MSI TRX40 Creator */
532543
.id = USB_ID(0x0db0, 0x0d64),
533544
.map = trx40_mobo_map,
545+
.connector_map = trx40_mobo_connector_map,
534546
},
535547
{ /* MSI TRX40 */
536548
.id = USB_ID(0x0db0, 0x543d),
537549
.map = trx40_mobo_map,
550+
.connector_map = trx40_mobo_connector_map,
538551
},
539552
{ 0 } /* terminator */
540553
};

0 commit comments

Comments
 (0)