Motu M4 Linux compatible?

Talk about your MIDI interfaces, microphones, keyboards...

Moderators: MattKingUSA, khz

puleglot
Established Member
Posts: 135
Joined: Thu Jan 23, 2020 3:14 pm
Has thanked: 3 times
Been thanked: 13 times

Re: Motu M4 Linux compatible?

Post by puleglot »

zlw wrote: Sun Mar 03, 2024 11:10 pm

Switched to motu m4, in general it works, but you will get the the periodic bitcrush effect (about every 2s) creeping in from time to time, need to power off the unit, wait a bit and power on again and it is usually gone, restarting pipewire works as well.
Tried the quirk 0x220 but seems to be unrelated as this is still there.

If you have 2nd revision M4, then I can only suggest you to try patch from MOTU AVB thread:
viewtopic.php?p=165431#p165431
Probably device can't correctly recover after a packet loss or something like that.
I don't have this issue with the 1st revision M4 which is based on XMOS controller.

User avatar
sh7d
Established Member
Posts: 4
Joined: Fri Mar 01, 2024 9:38 pm
Has thanked: 1 time
Been thanked: 3 times

Re: Motu M4 Linux compatible?

Post by sh7d »

puleglot wrote: Mon Mar 04, 2024 1:29 pm
zlw wrote: Sun Mar 03, 2024 11:10 pm

Switched to motu m4, in general it works, but you will get the the periodic bitcrush effect (about every 2s) creeping in from time to time, need to power off the unit, wait a bit and power on again and it is usually gone, restarting pipewire works as well.
Tried the quirk 0x220 but seems to be unrelated as this is still there.

If you have 2nd revision M4, then I can only suggest you to try patch from MOTU AVB thread:
viewtopic.php?p=165431#p165431
Probably device can't correctly recover after a packet loss or something like that.
I don't have this issue with the 1st revision M4 which is based on XMOS controller.

If you want do this, please be aware that one of the workarounds is activated only for the Motu 16A by comparing USB vid and pid values of the device.
If you want to activate for your M4 look at these lines:

Code: Select all

+	if (chip->usb_id == USB_ID(0x07fd, 0x0004) || 
+		chip->usb_id == USB_ID(0x07fd, 0x0005)) {

and add a proper conditional for your device or simply replace the values with the ones corresponding with the motu M4 2nd revision

EDIT:
Perhaps the path for M4 should look like:

Code: Select all

diff --git a/sound/usb/card.h b/sound/usb/card.h
index 6ec95b2ed..c3dbc9c16 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -91,9 +91,10 @@ struct snd_usb_endpoint {
 	struct snd_usb_packet_info {
 		uint32_t packet_size[MAX_PACKS_HS];
 		int packets;
-	} next_packet[MAX_URBS];
+	} next_packet[MAX_URBS + 2];
 	unsigned int next_packet_head;	/* ring buffer offset to read */
 	unsigned int next_packet_queued; /* queued items in the ring buffer */
+	unsigned int startup_wait_urbs; /* number of capture URBS - 1 before starting playback for implicit feedback */
 	struct list_head ready_playback_urbs; /* playback URB FIFO for implicit fb */
 
 	unsigned int nurbs;		/* # urbs */
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index a676ad093..90b8875bf 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -180,7 +180,8 @@ static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
 	 * Sample rate changes takes more than 2 seconds for this device. Clock
 	 * validity request returns false during that period.
 	 */
-	if (chip->usb_id == USB_ID(0x07fd, 0x0004)) {
+	if (chip->usb_id == USB_ID(0x07fd, 0x0004) || chip->usb_id == USB_ID(0x07fd, 0x000b) || 
+		chip->usb_id == USB_ID(0x07fd, 0x0005)) {
 		count = 0;
 
while ((!ret) && (count < 50)) {
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 8f65349a0..91c99674b 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -468,8 +468,10 @@ int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep,
 		int err, i;
 
spin_lock_irqsave(&ep->lock, flags);
-		if ((!implicit_fb || ep->next_packet_queued > 0) &&
+		if ((!implicit_fb || ep->next_packet_queued > ep->startup_wait_urbs) &&
 		    !list_empty(&ep->ready_playback_urbs)) {
+			/* once started stop waiting */
+			ep->startup_wait_urbs = 0;
 			/* take URB out of FIFO */
 			ctx = list_first_entry(&ep->ready_playback_urbs,
 					       struct snd_urb_ctx, ready_list);
@@ -1588,7 +1590,9 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
 
 	if (snd_usb_endpoint_implicit_feedback_sink(ep) &&
 	    !(ep->chip->quirk_flags & QUIRK_FLAG_PLAYBACK_FIRST)) {
-		usb_audio_dbg(ep->chip, "No URB submission due to implicit fb sync\n");
+		printk(KERN_INFO "MOTU Patch - 6.0.3");
+		usb_audio_dbg(ep->chip, "Delaying URB submission due to implicit fb sync\n");
+		ep->startup_wait_urbs = ep->nurbs - 1;
 		i = 0;
 		goto fill_rest;
 	}

But since I don't own m4 i cannot give any guaranties :)
And please confirm that vid and pid for your device are 0x07fd and 0x000b respectively

puleglot
Established Member
Posts: 135
Joined: Thu Jan 23, 2020 3:14 pm
Has thanked: 3 times
Been thanked: 13 times

Re: Motu M4 Linux compatible?

Post by puleglot »

sh7d wrote: Mon Mar 04, 2024 7:22 pm

If you want do this, please be aware that one of the workarounds is activated only for the Motu 16A by comparing USB vid and pid values of the device.
If you want to activate for your M4 look at these lines:

Code: Select all

+	if (chip->usb_id == USB_ID(0x07fd, 0x0004) || 
+		chip->usb_id == USB_ID(0x07fd, 0x0005)) {

and add a proper conditional for your device or simply replace the values with the ones corresponding with the motu M4 2nd revision

The hunk that changes sound/usb/clock.c is not needed for M4 at all, but shouldn't do any hurt. I just was too lazy to find original patch in the thread that doesn't change sound/usb/clock.c :)

zlw
Established Member
Posts: 4
Joined: Thu May 07, 2020 2:12 pm
Has thanked: 2 times
Contact:

Re: Motu M4 Linux compatible?

Post by zlw »

Ah thank you, will test it out, ID is indeed 07fd:000b and yeah missing packet makes sense, will give an update once I get to do it, cheers !

Post Reply