summaryrefslogtreecommitdiff
path: root/sound/usb/midi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-02-16 20:02:19 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2024-02-16 20:02:19 +0300
commit0f1dd5e91e2ba3990143645faff2bcce2d99778e (patch)
treedb67ad7f572704e11f928fb11d102a78b2ec322c /sound/usb/midi.c
parentbeda9c23ad82aa37be7f4a457e9b9544d04b84fd (diff)
parent41c25e193b2befc22462aa41591d397fab174ca1 (diff)
downloadlinux-0f1dd5e91e2ba3990143645faff2bcce2d99778e.tar.xz
Merge tag 'sound-6.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "A collection of device-specific fixes. It became a bit bigger than wished, but all look reasonably small and safe to apply. - A few Cirrus Logic CS35L56 and CS42L43 driver fixes - ASoC SOF fixes and workarounds - Various ASoC Intel fixes - Lots of HD-, USB-audio and AMD ACP quirks" * tag 'sound-6.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (33 commits) ALSA: usb-audio: More relaxed check of MIDI jack names ALSA: hda/realtek: fix mute/micmute LED For HP mt645 ALSA: hda/realtek: cs35l41: Fix order and duplicates in quirks table ALSA: hda/realtek: cs35l41: Fix device ID / model name ALSA: hda/realtek: cs35l41: Add internal speaker support for ASUS UM3402 with missing DSD ASoC: cs35l56: Workaround for ACPI with broken spk-id-gpios property ALSA: hda: Add Lenovo Legion 7i gen7 sound quirk ASoC: SOF: IPC3: fix message bounds on ipc ops ASoC: SOF: ipc4-pcm: Workaround for crashed firmware on system suspend ASoC: q6dsp: fix event handler prototype ASoC: SOF: Intel: pci-lnl: Change the topology path to intel/sof-ipc4-tplg ASoC: SOF: Intel: pci-tgl: Change the default paths and firmware names ASoC: amd: yc: Fix non-functional mic on Lenovo 82UU ASoC: rt5645: Add DMI quirk for inverted jack-detect on MeeGoPad T8 ASoC: rt5645: Make LattePanda board DMI match more precise ASoC: SOF: amd: Fix locking in ACP IRQ handler ASoC: rt5645: Fix deadlock in rt5645_jack_detect_work() ASoC: Intel: cht_bsw_rt5645: Cleanup codec_name handling ASoC: Intel: Boards: Fix NULL pointer deref in BYT/CHT boards ASoC: cs35l56: Remove default from IRQ1_CFG register ...
Diffstat (limited to 'sound/usb/midi.c')
-rw-r--r--sound/usb/midi.c73
1 files changed, 25 insertions, 48 deletions
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 6b0993258e03..c1f2e5a03de9 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1742,50 +1742,44 @@ static void snd_usbmidi_get_port_info(struct snd_rawmidi *rmidi, int number,
}
}
-static struct usb_midi_in_jack_descriptor *find_usb_in_jack_descriptor(
- struct usb_host_interface *hostif, uint8_t jack_id)
+/* return iJack for the corresponding jackID */
+static int find_usb_ijack(struct usb_host_interface *hostif, uint8_t jack_id)
{
unsigned char *extra = hostif->extra;
int extralen = hostif->extralen;
+ struct usb_descriptor_header *h;
+ struct usb_midi_out_jack_descriptor *outjd;
+ struct usb_midi_in_jack_descriptor *injd;
+ size_t sz;
while (extralen > 4) {
- struct usb_midi_in_jack_descriptor *injd =
- (struct usb_midi_in_jack_descriptor *)extra;
+ h = (struct usb_descriptor_header *)extra;
+ if (h->bDescriptorType != USB_DT_CS_INTERFACE)
+ goto next;
+ outjd = (struct usb_midi_out_jack_descriptor *)h;
+ if (h->bLength >= sizeof(*outjd) &&
+ outjd->bDescriptorSubtype == UAC_MIDI_OUT_JACK &&
+ outjd->bJackID == jack_id) {
+ sz = USB_DT_MIDI_OUT_SIZE(outjd->bNrInputPins);
+ if (outjd->bLength < sz)
+ goto next;
+ return *(extra + sz - 1);
+ }
+
+ injd = (struct usb_midi_in_jack_descriptor *)h;
if (injd->bLength >= sizeof(*injd) &&
- injd->bDescriptorType == USB_DT_CS_INTERFACE &&
injd->bDescriptorSubtype == UAC_MIDI_IN_JACK &&
- injd->bJackID == jack_id)
- return injd;
- if (!extra[0])
- break;
- extralen -= extra[0];
- extra += extra[0];
- }
- return NULL;
-}
-
-static struct usb_midi_out_jack_descriptor *find_usb_out_jack_descriptor(
- struct usb_host_interface *hostif, uint8_t jack_id)
-{
- unsigned char *extra = hostif->extra;
- int extralen = hostif->extralen;
+ injd->bJackID == jack_id)
+ return injd->iJack;
- while (extralen > 4) {
- struct usb_midi_out_jack_descriptor *outjd =
- (struct usb_midi_out_jack_descriptor *)extra;
-
- if (outjd->bLength >= sizeof(*outjd) &&
- outjd->bDescriptorType == USB_DT_CS_INTERFACE &&
- outjd->bDescriptorSubtype == UAC_MIDI_OUT_JACK &&
- outjd->bJackID == jack_id)
- return outjd;
+next:
if (!extra[0])
break;
extralen -= extra[0];
extra += extra[0];
}
- return NULL;
+ return 0;
}
static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi,
@@ -1796,13 +1790,10 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi,
const char *name_format;
struct usb_interface *intf;
struct usb_host_interface *hostif;
- struct usb_midi_in_jack_descriptor *injd;
- struct usb_midi_out_jack_descriptor *outjd;
uint8_t jack_name_buf[32];
uint8_t *default_jack_name = "MIDI";
uint8_t *jack_name = default_jack_name;
uint8_t iJack;
- size_t sz;
int res;
struct snd_rawmidi_substream *substream =
@@ -1816,21 +1807,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi,
intf = umidi->iface;
if (intf && jack_id >= 0) {
hostif = intf->cur_altsetting;
- iJack = 0;
- if (stream != SNDRV_RAWMIDI_STREAM_OUTPUT) {
- /* in jacks connect to outs */
- outjd = find_usb_out_jack_descriptor(hostif, jack_id);
- if (outjd) {
- sz = USB_DT_MIDI_OUT_SIZE(outjd->bNrInputPins);
- if (outjd->bLength >= sz)
- iJack = *(((uint8_t *) outjd) + sz - sizeof(uint8_t));
- }
- } else {
- /* and out jacks connect to ins */
- injd = find_usb_in_jack_descriptor(hostif, jack_id);
- if (injd)
- iJack = injd->iJack;
- }
+ iJack = find_usb_ijack(hostif, jack_id);
if (iJack != 0) {
res = usb_string(umidi->dev, iJack, jack_name_buf,
ARRAY_SIZE(jack_name_buf));