Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Manuel Barrio Linares and committed by
Takashi Iwai
44f69ddc 4bfea1dc

+81 -31
+24 -14
sound/usb/quirks-table.h
··· 3013 3013 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 3014 3014 .data = &(const struct audioformat) { 3015 3015 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 3016 + .fmt_bits = 24, 3016 3017 .channels = 4, 3017 3018 .iface = 2, 3018 3019 .altsetting = 1, 3019 3020 .altset_idx = 1, 3020 3021 .attributes = 0x00, 3021 - .endpoint = 0x01, 3022 + .endpoint = USB_RECIP_INTERFACE | USB_DIR_OUT, 3022 3023 .ep_attr = USB_ENDPOINT_XFER_ISOC | 3023 3024 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, 3028 3030 .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, 3031 3038 } 3032 3039 }, 3033 3040 { ··· 3042 3035 .type = QUIRK_AUDIO_FIXED_ENDPOINT, 3043 3036 .data = &(const struct audioformat) { 3044 3037 .formats = SNDRV_PCM_FMTBIT_S24_3LE, 3038 + .fmt_bits = 24, 3045 3039 .channels = 4, 3046 3040 .iface = 3, 3047 3041 .altsetting = 1, 3048 3042 .altset_idx = 1, 3049 - .endpoint = 0x81, 3050 3043 .attributes = 0x00, 3044 + .endpoint = USB_RECIP_INTERFACE | USB_DIR_IN, 3051 3045 .ep_attr = USB_ENDPOINT_XFER_ISOC | 3052 3046 USB_ENDPOINT_SYNC_ASYNC, 3053 3047 .maxpacksize = 0x009c, 3054 - .rates = SNDRV_PCM_RATE_48000, 3055 - .rate_min = 48000, 3056 - .rate_max = 48000, 3057 - .nr_rates = 1, 3048 + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 3049 + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, 3050 + .rate_min = 44100, 3051 + .rate_max = 96000, 3052 + .nr_rates = 4, 3058 3053 .rate_table = (unsigned int[]) { 3059 - 48000 3060 - } 3054 + 44100, 48000, 88200, 96000 3055 + }, 3056 + .implicit_fb = 0, 3061 3057 } 3062 3058 }, 3063 3059 {
+57 -17
sound/usb/quirks.c
··· 984 984 return 0; 985 985 } 986 986 987 - static void mbox3_setup_48_24_magic(struct usb_device *dev) 987 + static void mbox3_setup_defaults(struct usb_device *dev) 988 988 { 989 989 /* The Mbox 3 is "little endian" */ 990 990 /* max volume is: 0x0000. */ 991 991 /* min volume is: 0x0080 (shown in little endian form) */ 992 992 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]; 1002 994 1003 995 /* Deactivate Tuner */ 1004 996 /* on = 0x01*/ ··· 1000 1008 0x01, 0x21, 0x0003, 0x2001, &com_buff, 1); 1001 1009 1002 1010 /* Set clock source to Internal (as opposed to S/PDIF) */ 1011 + /* Internal = 0x01*/ 1012 + /* S/PDIF = 0x02*/ 1003 1013 com_buff[0] = 0x01; 1004 1014 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 1005 1015 1, 0x21, 0x0100, 0x8001, &com_buff, 1); ··· 1107 1113 1, 0x21, 0x0107, 0x4201, &com_buff, 2); 1108 1114 1109 1115 /* Toggle allowing host control */ 1116 + /* Not needed 1110 1117 com_buff[0] = 0x02; 1111 1118 snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 1112 1119 3, 0x21, 0x0000, 0x2001, &com_buff, 1); 1120 + */ 1113 1121 1114 1122 /* Do not dim fx returns */ 1115 1123 com_buff[0] = 0x00; ··· 1255 1259 descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength); 1256 1260 1257 1261 if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) { 1258 - dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size); 1262 + dev_err(&dev->dev, "MBOX3: Invalid descriptor size=%d.\n", descriptor_size); 1259 1263 return -ENODEV; 1260 1264 } 1261 1265 1262 - dev_dbg(&dev->dev, "device initialised!\n"); 1266 + dev_dbg(&dev->dev, "MBOX3: device initialised!\n"); 1263 1267 1264 1268 err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, 1265 1269 &dev->descriptor, sizeof(dev->descriptor)); 1266 1270 config = dev->actconfig; 1267 1271 if (err < 0) 1268 - dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err); 1272 + dev_dbg(&dev->dev, "MBOX3: error usb_get_descriptor: %d\n", err); 1269 1273 1270 1274 err = usb_reset_configuration(dev); 1271 1275 if (err < 0) 1272 - dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err); 1273 - dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n", 1276 + dev_dbg(&dev->dev, "MBOX3: error usb_reset_configuration: %d\n", err); 1277 + 1278 + dev_dbg(&dev->dev, "MBOX3: new boot length = %d\n", 1274 1279 le16_to_cpu(get_cfg_desc(config)->wTotalLength)); 1275 1280 1276 - mbox3_setup_48_24_magic(dev); 1277 - dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz"); 1281 + mbox3_setup_defaults(dev); 1282 + dev_info(&dev->dev, "MBOX3: Initialized."); 1278 1283 1279 1284 return 0; /* Successful boot */ 1280 1285 } ··· 1731 1734 return 0; 1732 1735 } 1733 1736 1737 + static void mbox3_set_format_quirk(struct snd_usb_substream *subs, 1738 + const struct audioformat *fmt) 1739 + { 1740 + __le32 buff4 = 0; 1741 + u8 buff1 = 0x01; 1742 + u32 new_rate = subs->data_endpoint->cur_rate; 1743 + u32 current_rate; 1744 + 1745 + // Get current rate from card and check if changing it is needed 1746 + snd_usb_ctl_msg(subs->dev, usb_sndctrlpipe(subs->dev, 0), 1747 + 0x01, 0x21 | USB_DIR_IN, 0x0100, 0x8101, &buff4, 4); 1748 + current_rate = le32_to_cpu(buff4); 1749 + dev_dbg(&subs->dev->dev, 1750 + "MBOX3: Current configured sample rate: %d", current_rate); 1751 + if (current_rate == new_rate) { 1752 + dev_dbg(&subs->dev->dev, 1753 + "MBOX3: No change needed (current rate:%d == new rate:%d)", 1754 + current_rate, new_rate); 1755 + return; 1756 + } 1757 + 1758 + // Set new rate 1759 + dev_info(&subs->dev->dev, 1760 + "MBOX3: Changing sample rate to: %d", new_rate); 1761 + buff4 = cpu_to_le32(new_rate); 1762 + snd_usb_ctl_msg(subs->dev, usb_sndctrlpipe(subs->dev, 0), 1763 + 0x01, 0x21, 0x0100, 0x8101, &buff4, 4); 1764 + 1765 + // Set clock source to Internal 1766 + snd_usb_ctl_msg(subs->dev, usb_sndctrlpipe(subs->dev, 0), 1767 + 0x01, 0x21, 0x0100, 0x8001, &buff1, 1); 1768 + 1769 + // Check whether the change was successful 1770 + buff4 = 0; 1771 + snd_usb_ctl_msg(subs->dev, usb_sndctrlpipe(subs->dev, 0), 1772 + 0x01, 0x21 | USB_DIR_IN, 0x0100, 0x8101, &buff4, 4); 1773 + if (new_rate != le32_to_cpu(buff4)) 1774 + dev_warn(&subs->dev->dev, "MBOX3: Couldn't set the sample rate"); 1775 + } 1776 + 1734 1777 void snd_usb_set_format_quirk(struct snd_usb_substream *subs, 1735 1778 const struct audioformat *fmt) 1736 1779 { ··· 1791 1754 case USB_ID(0x08e4, 0x017f): /* Pioneer DJM-750 */ 1792 1755 case USB_ID(0x08e4, 0x0163): /* Pioneer DJM-850 */ 1793 1756 pioneer_djm_set_format_quirk(subs, 0x0086); 1757 + break; 1758 + case USB_ID(0x0dba, 0x5000): 1759 + mbox3_set_format_quirk(subs, fmt); /* Digidesign Mbox 3 */ 1794 1760 break; 1795 1761 } 1796 1762 }