aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/quirks.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/quirks.c')
-rw-r--r--sound/usb/quirks.c72
1 files changed, 69 insertions, 3 deletions
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 60dfe0d28771..4dbfb3d18ee2 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -43,12 +43,13 @@
43static int create_composite_quirk(struct snd_usb_audio *chip, 43static int create_composite_quirk(struct snd_usb_audio *chip,
44 struct usb_interface *iface, 44 struct usb_interface *iface,
45 struct usb_driver *driver, 45 struct usb_driver *driver,
46 const struct snd_usb_audio_quirk *quirk) 46 const struct snd_usb_audio_quirk *quirk_comp)
47{ 47{
48 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber; 48 int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
49 const struct snd_usb_audio_quirk *quirk;
49 int err; 50 int err;
50 51
51 for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) { 52 for (quirk = quirk_comp->data; quirk->ifnum >= 0; ++quirk) {
52 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum); 53 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
53 if (!iface) 54 if (!iface)
54 continue; 55 continue;
@@ -58,9 +59,17 @@ static int create_composite_quirk(struct snd_usb_audio *chip,
58 err = snd_usb_create_quirk(chip, iface, driver, quirk); 59 err = snd_usb_create_quirk(chip, iface, driver, quirk);
59 if (err < 0) 60 if (err < 0)
60 return err; 61 return err;
61 if (quirk->ifnum != probed_ifnum) 62 }
63
64 for (quirk = quirk_comp->data; quirk->ifnum >= 0; ++quirk) {
65 iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
66 if (!iface)
67 continue;
68 if (quirk->ifnum != probed_ifnum &&
69 !usb_interface_claimed(iface))
62 usb_driver_claim_interface(driver, iface, (void *)-1L); 70 usb_driver_claim_interface(driver, iface, (void *)-1L);
63 } 71 }
72
64 return 0; 73 return 0;
65} 74}
66 75
@@ -1102,6 +1111,44 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
1102 } 1111 }
1103} 1112}
1104 1113
1114
1115/* Marantz/Denon USB DACs need a vendor cmd to switch
1116 * between PCM and native DSD mode
1117 */
1118int snd_usb_select_mode_quirk(struct snd_usb_substream *subs,
1119 struct audioformat *fmt)
1120{
1121 struct usb_device *dev = subs->dev;
1122 int err;
1123
1124 switch (subs->stream->chip->usb_id) {
1125 case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */
1126 case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */
1127
1128 /* First switch to alt set 0, otherwise the mode switch cmd
1129 * will not be accepted by the DAC
1130 */
1131 err = usb_set_interface(dev, fmt->iface, 0);
1132 if (err < 0)
1133 return err;
1134
1135 mdelay(20); /* Delay needed after setting the interface */
1136
1137 switch (fmt->altsetting) {
1138 case 2: /* DSD mode requested */
1139 case 1: /* PCM mode requested */
1140 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
1141 USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
1142 fmt->altsetting - 1, 1, NULL, 0);
1143 if (err < 0)
1144 return err;
1145 break;
1146 }
1147 mdelay(20);
1148 }
1149 return 0;
1150}
1151
1105void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) 1152void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
1106{ 1153{
1107 /* 1154 /*
@@ -1160,6 +1207,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
1160 break; 1207 break;
1161 } 1208 }
1162 } 1209 }
1210
1211 /* Zoom R16/24 needs a tiny delay here, otherwise requests like
1212 * get/set frequency return as failed despite actually succeeding.
1213 */
1214 if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1686) &&
1215 (le16_to_cpu(dev->descriptor.idProduct) == 0x00dd) &&
1216 (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
1217 mdelay(1);
1163} 1218}
1164 1219
1165/* 1220/*
@@ -1204,5 +1259,16 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
1204 break; 1259 break;
1205 } 1260 }
1206 1261
1262 /* Denon/Marantz devices with USB DAC functionality */
1263 switch (chip->usb_id) {
1264 case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */
1265 case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */
1266 if (fp->altsetting == 2)
1267 return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1268 break;
1269 default:
1270 break;
1271 }
1272
1207 return 0; 1273 return 0;
1208} 1274}