[PATCH] ALSA: usb-audio: keep MIDI input running for Roland TD-11

From: Nicholas Hobson

Date: Fri Sep 11 2026 - 23:29:00 EST


>From cbb4e446c3278aa99b34e622ac7ccef3e6d98d5b Mon Sep 17 00:00:00 2001
From: Nicholas Hobson <nicholas.hobson@xxxxxxxxxxx>
Date: Fri, 11 Sep 2026 21:58:09 -0400
Subject: [PATCH] ALSA: usb-audio: keep MIDI input running for Roland TD-11

The TD-11 hands MIDI handling off to the host once connected via
USB. If no MIDI input port is opened on the host, the device itself
becomes unusable as a standalone instrument until its input is
serviced, independent of anything happening on the computer.

Add a per-device keep_input_running flag, set for the TD-11 in
snd_usbmidi_detect_roland(), and check it alongside the existing
opened[1] check in snd_usbmidi_input_start()/snd_usbmidi_input_stop()
so that input is started at device creation and never stopped for
these devices, regardless of whether a client has the input port
open.

Signed-off-by: Nicholas Hobson <nicholas.hobson@xxxxxxxxxxx>
---
sound/usb/midi.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 7e5b1b133..353217b36 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -113,6 +113,7 @@ struct snd_usb_midi {
unsigned int opened[2];
unsigned char disconnected;
unsigned char input_running;
+ unsigned char keep_input_running;

struct snd_kcontrol *roland_load_ctl;
};
@@ -1172,7 +1173,7 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
snd_usbmidi_input_start(&umidi->list);
} else {
umidi->opened[dir]--;
- if (!umidi->opened[1])
+ if (!umidi->opened[1] && !umidi->keep_input_running)
snd_usbmidi_input_stop(&umidi->list);
if (!umidi->opened[0] && !umidi->opened[1]) {
if (umidi->roland_load_ctl) {
@@ -2262,6 +2263,10 @@ static int snd_usbmidi_detect_roland(struct snd_usb_midi *umidi,
struct usb_host_interface *hostif;
u8 *cs_desc;

+ /* TD-11 becomes unusable if input isn't serviced continuously */
+ if (umidi->usb_id == USB_ID(0x0582, 0x0151))
+ umidi->keep_input_running = 1;
+
intf = umidi->iface;
if (!intf)
return -ENOENT;
@@ -2469,7 +2474,7 @@ void snd_usbmidi_input_start(struct list_head *p)
int i;

umidi = list_entry(p, struct snd_usb_midi, list);
- if (umidi->input_running || !umidi->opened[1])
+ if (umidi->input_running || (!umidi->opened[1] && !umidi->keep_input_running))
return;
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
snd_usbmidi_input_start_ep(umidi, umidi->endpoints[i].in);
@@ -2644,6 +2649,10 @@ int __snd_usbmidi_create(struct snd_card *card,
if (err < 0)
goto exit;

+ /* start input for devices that need continuous servicing */
+ if (umidi->keep_input_running)
+ snd_usbmidi_input_start(&umidi->list);
+
usb_autopm_get_interface_no_resume(umidi->iface);

list_add_tail(&umidi->list, midi_list);
--
2.55.0