Skip to content

Commit 44f69dd

Browse files
ManuLinarestiwai
authored andcommitted
ALSA: usb-audio: Add sampling rates support for Mbox3
This adds support for all sample rates supported by the hardware,Digidesign Mbox 3 supports: {44100, 48000, 88200, 96000} Fixes syncing clock issues that presented as pops. To test this, without this patch playing 440hz tone produces pops. Clock is now synced between playback and capture interfaces so no more latency drift issue when using pipewire pro-profile. (https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/3900) Signed-off-by: Manuel Barrio Linares <mbarriolinares@gmail.com> Link: https://lore.kernel.org/r/20240430171020.192285-1-mbarriolinares@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 4bfea1d commit 44f69dd

2 files changed

Lines changed: 81 additions & 31 deletions

File tree

sound/usb/quirks-table.h

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3013,44 +3013,54 @@ YAMAHA_DEVICE(0x7010, "UB99"),
30133013
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
30143014
.data = &(const struct audioformat) {
30153015
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
3016+
.fmt_bits = 24,
30163017
.channels = 4,
30173018
.iface = 2,
30183019
.altsetting = 1,
30193020
.altset_idx = 1,
30203021
.attributes = 0x00,
3021-
.endpoint = 0x01,
3022+
.endpoint = USB_RECIP_INTERFACE | USB_DIR_OUT,
30223023
.ep_attr = USB_ENDPOINT_XFER_ISOC |
30233024
USB_ENDPOINT_SYNC_ASYNC,
3024-
.rates = SNDRV_PCM_RATE_48000,
3025-
.rate_min = 48000,
3026-
.rate_max = 48000,
3027-
.nr_rates = 1,
3025+
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
3026+
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000,
3027+
.rate_min = 44100,
3028+
.rate_max = 96000,
3029+
.nr_rates = 4,
30283030
.rate_table = (unsigned int[]) {
3029-
48000
3030-
}
3031+
44100, 48000, 88200, 96000
3032+
},
3033+
.sync_ep = USB_RECIP_INTERFACE | USB_DIR_IN,
3034+
.sync_iface = 3,
3035+
.sync_altsetting = 1,
3036+
.sync_ep_idx = 1,
3037+
.implicit_fb = 1,
30313038
}
30323039
},
30333040
{
30343041
.ifnum = 3,
30353042
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
30363043
.data = &(const struct audioformat) {
30373044
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
3045+
.fmt_bits = 24,
30383046
.channels = 4,
30393047
.iface = 3,
30403048
.altsetting = 1,
30413049
.altset_idx = 1,
3042-
.endpoint = 0x81,
30433050
.attributes = 0x00,
3051+
.endpoint = USB_RECIP_INTERFACE | USB_DIR_IN,
30443052
.ep_attr = USB_ENDPOINT_XFER_ISOC |
30453053
USB_ENDPOINT_SYNC_ASYNC,
30463054
.maxpacksize = 0x009c,
3047-
.rates = SNDRV_PCM_RATE_48000,
3048-
.rate_min = 48000,
3049-
.rate_max = 48000,
3050-
.nr_rates = 1,
3055+
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
3056+
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000,
3057+
.rate_min = 44100,
3058+
.rate_max = 96000,
3059+
.nr_rates = 4,
30513060
.rate_table = (unsigned int[]) {
3052-
48000
3053-
}
3061+
44100, 48000, 88200, 96000
3062+
},
3063+
.implicit_fb = 0,
30543064
}
30553065
},
30563066
{

sound/usb/quirks.c

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -984,21 +984,13 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
984984
return 0;
985985
}
986986

987-
static void mbox3_setup_48_24_magic(struct usb_device *dev)
987+
static void mbox3_setup_defaults(struct usb_device *dev)
988988
{
989989
/* The Mbox 3 is "little endian" */
990990
/* max volume is: 0x0000. */
991991
/* min volume is: 0x0080 (shown in little endian form) */
992992

993-
994-
/* Load 48000Hz rate into buffer */
995-
u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
996-
997-
/* Set 48000Hz sample rate */
998-
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
999-
0x01, 0x21, 0x0100, 0x0001, &com_buff, 4); //Is this really needed?
1000-
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1001-
0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
993+
u8 com_buff[2];
1002994

1003995
/* Deactivate Tuner */
1004996
/* on = 0x01*/
@@ -1008,6 +1000,8 @@ static void mbox3_setup_48_24_magic(struct usb_device *dev)
10081000
0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
10091001

10101002
/* Set clock source to Internal (as opposed to S/PDIF) */
1003+
/* Internal = 0x01*/
1004+
/* S/PDIF = 0x02*/
10111005
com_buff[0] = 0x01;
10121006
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
10131007
1, 0x21, 0x0100, 0x8001, &com_buff, 1);
@@ -1113,9 +1107,11 @@ static void mbox3_setup_48_24_magic(struct usb_device *dev)
11131107
1, 0x21, 0x0107, 0x4201, &com_buff, 2);
11141108

11151109
/* Toggle allowing host control */
1110+
/* Not needed
11161111
com_buff[0] = 0x02;
11171112
snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
11181113
3, 0x21, 0x0000, 0x2001, &com_buff, 1);
1114+
*/
11191115

11201116
/* Do not dim fx returns */
11211117
com_buff[0] = 0x00;
@@ -1259,26 +1255,27 @@ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
12591255
descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
12601256

12611257
if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
1262-
dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
1258+
dev_err(&dev->dev, "MBOX3: Invalid descriptor size=%d.\n", descriptor_size);
12631259
return -ENODEV;
12641260
}
12651261

1266-
dev_dbg(&dev->dev, "device initialised!\n");
1262+
dev_dbg(&dev->dev, "MBOX3: device initialised!\n");
12671263

12681264
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
12691265
&dev->descriptor, sizeof(dev->descriptor));
12701266
config = dev->actconfig;
12711267
if (err < 0)
1272-
dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
1268+
dev_dbg(&dev->dev, "MBOX3: error usb_get_descriptor: %d\n", err);
12731269

12741270
err = usb_reset_configuration(dev);
12751271
if (err < 0)
1276-
dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
1277-
dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
1272+
dev_dbg(&dev->dev, "MBOX3: error usb_reset_configuration: %d\n", err);
1273+
1274+
dev_dbg(&dev->dev, "MBOX3: new boot length = %d\n",
12781275
le16_to_cpu(get_cfg_desc(config)->wTotalLength));
12791276

1280-
mbox3_setup_48_24_magic(dev);
1281-
dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
1277+
mbox3_setup_defaults(dev);
1278+
dev_info(&dev->dev, "MBOX3: Initialized.");
12821279

12831280
return 0; /* Successful boot */
12841281
}
@@ -1734,6 +1731,46 @@ static int pioneer_djm_set_format_quirk(struct snd_usb_substream *subs,
17341731
return 0;
17351732
}
17361733

1734+
static void mbox3_set_format_quirk(struct snd_usb_substream *subs,
1735+
const struct audioformat *fmt)
1736+
{
1737+
__le32 buff4 = 0;
1738+
u8 buff1 = 0x01;
1739+
u32 new_rate = subs->data_endpoint->cur_rate;
1740+
u32 current_rate;
1741+
1742+
// Get current rate from card and check if changing it is needed
1743+
snd_usb_ctl_msg(subs->dev, usb_sndctrlpipe(subs->dev, 0),
1744+
0x01, 0x21 | USB_DIR_IN, 0x0100, 0x8101, &buff4, 4);
1745+
current_rate = le32_to_cpu(buff4);
1746+
dev_dbg(&subs->dev->dev,
1747+
"MBOX3: Current configured sample rate: %d", current_rate);
1748+
if (current_rate == new_rate) {
1749+
dev_dbg(&subs->dev->dev,
1750+
"MBOX3: No change needed (current rate:%d == new rate:%d)",
1751+
current_rate, new_rate);
1752+
return;
1753+
}
1754+
1755+
// Set new rate
1756+
dev_info(&subs->dev->dev,
1757+
"MBOX3: Changing sample rate to: %d", new_rate);
1758+
buff4 = cpu_to_le32(new_rate);
1759+
snd_usb_ctl_msg(subs->dev, usb_sndctrlpipe(subs->dev, 0),
1760+
0x01, 0x21, 0x0100, 0x8101, &buff4, 4);
1761+
1762+
// Set clock source to Internal
1763+
snd_usb_ctl_msg(subs->dev, usb_sndctrlpipe(subs->dev, 0),
1764+
0x01, 0x21, 0x0100, 0x8001, &buff1, 1);
1765+
1766+
// Check whether the change was successful
1767+
buff4 = 0;
1768+
snd_usb_ctl_msg(subs->dev, usb_sndctrlpipe(subs->dev, 0),
1769+
0x01, 0x21 | USB_DIR_IN, 0x0100, 0x8101, &buff4, 4);
1770+
if (new_rate != le32_to_cpu(buff4))
1771+
dev_warn(&subs->dev->dev, "MBOX3: Couldn't set the sample rate");
1772+
}
1773+
17371774
void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
17381775
const struct audioformat *fmt)
17391776
{
@@ -1755,6 +1792,9 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
17551792
case USB_ID(0x08e4, 0x0163): /* Pioneer DJM-850 */
17561793
pioneer_djm_set_format_quirk(subs, 0x0086);
17571794
break;
1795+
case USB_ID(0x0dba, 0x5000):
1796+
mbox3_set_format_quirk(subs, fmt); /* Digidesign Mbox 3 */
1797+
break;
17581798
}
17591799
}
17601800

0 commit comments

Comments
 (0)