2019-05-27 09:55:05 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2010-03-04 21:46:13 +03:00
/*
*/
# include <linux/init.h>
2010-03-29 09:02:50 +04:00
# include <linux/slab.h>
2010-03-04 21:46:13 +03:00
# include <linux/usb.h>
# include <linux/usb/audio.h>
2013-04-01 01:43:12 +04:00
# include <linux/usb/midi.h>
2018-11-03 00:11:33 +03:00
# include <linux/bits.h>
2010-03-04 21:46:13 +03:00
2011-05-25 11:09:01 +04:00
# include <sound/control.h>
2010-03-04 21:46:13 +03:00
# include <sound/core.h>
# include <sound/info.h>
# include <sound/pcm.h>
# include "usbaudio.h"
# include "card.h"
2010-03-11 23:13:23 +03:00
# include "mixer.h"
2010-03-11 23:13:22 +03:00
# include "mixer_quirks.h"
2010-03-04 21:46:13 +03:00
# include "midi.h"
# include "quirks.h"
# include "helper.h"
# include "endpoint.h"
# include "pcm.h"
2010-06-16 19:57:31 +04:00
# include "clock.h"
2011-09-12 20:54:12 +04:00
# include "stream.h"
2010-03-04 21:46:13 +03:00
/*
* handle the quirks for the contained interfaces
*/
static int create_composite_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
2014-11-10 09:41:59 +03:00
const struct snd_usb_audio_quirk * quirk_comp )
2010-03-04 21:46:13 +03:00
{
int probed_ifnum = get_iface_desc ( iface - > altsetting ) - > bInterfaceNumber ;
2014-11-10 09:41:59 +03:00
const struct snd_usb_audio_quirk * quirk ;
2010-03-04 21:46:13 +03:00
int err ;
2014-11-10 09:41:59 +03:00
for ( quirk = quirk_comp - > data ; quirk - > ifnum > = 0 ; + + quirk ) {
2010-03-04 21:46:13 +03:00
iface = usb_ifnum_to_if ( chip - > dev , quirk - > ifnum ) ;
if ( ! iface )
continue ;
if ( quirk - > ifnum ! = probed_ifnum & &
usb_interface_claimed ( iface ) )
continue ;
err = snd_usb_create_quirk ( chip , iface , driver , quirk ) ;
if ( err < 0 )
return err ;
2014-11-09 20:21:23 +03:00
}
2014-11-10 09:41:59 +03:00
for ( quirk = quirk_comp - > data ; quirk - > ifnum > = 0 ; + + quirk ) {
2014-11-09 20:21:23 +03:00
iface = usb_ifnum_to_if ( chip - > dev , quirk - > ifnum ) ;
if ( ! iface )
continue ;
if ( quirk - > ifnum ! = probed_ifnum & &
2021-04-06 14:35:34 +03:00
! usb_interface_claimed ( iface ) ) {
err = usb_driver_claim_interface ( driver , iface ,
USB_AUDIO_IFACE_UNUSED ) ;
if ( err < 0 )
return err ;
}
2010-03-04 21:46:13 +03:00
}
2014-11-09 20:21:23 +03:00
2010-03-04 21:46:13 +03:00
return 0 ;
}
static int ignore_interface_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
const struct snd_usb_audio_quirk * quirk )
{
return 0 ;
}
static int create_any_midi_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * intf ,
struct usb_driver * driver ,
const struct snd_usb_audio_quirk * quirk )
{
return snd_usbmidi_create ( chip - > card , intf , & chip - > midi_list , quirk ) ;
}
/*
* create a stream for an interface with proper descriptors
*/
static int create_standard_audio_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
const struct snd_usb_audio_quirk * quirk )
{
struct usb_host_interface * alts ;
struct usb_interface_descriptor * altsd ;
int err ;
alts = & iface - > altsetting [ 0 ] ;
altsd = get_iface_desc ( alts ) ;
2011-09-12 20:54:12 +04:00
err = snd_usb_parse_audio_interface ( chip , altsd - > bInterfaceNumber ) ;
2010-03-04 21:46:13 +03:00
if ( err < 0 ) {
2014-02-26 16:02:17 +04:00
usb_audio_err ( chip , " cannot setup if %d: error %d \n " ,
2010-03-04 21:46:13 +03:00
altsd - > bInterfaceNumber , err ) ;
return err ;
}
/* reset the current interface */
usb_set_interface ( chip - > dev , altsd - > bInterfaceNumber , 0 ) ;
return 0 ;
}
2021-01-08 10:52:15 +03:00
/* create the audio stream and the corresponding endpoints from the fixed
* audioformat object ; this is used for quirks with the fixed EPs
*/
static int add_audio_stream_from_fixed_fmt ( struct snd_usb_audio * chip ,
struct audioformat * fp )
{
int stream , err ;
stream = ( fp - > endpoint & USB_DIR_IN ) ?
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK ;
snd_usb_audioformat_set_sync_ep ( chip , fp ) ;
err = snd_usb_add_audio_stream ( chip , stream , fp ) ;
if ( err < 0 )
return err ;
err = snd_usb_add_endpoint ( chip , fp - > endpoint ,
SND_USB_ENDPOINT_TYPE_DATA ) ;
if ( err < 0 )
return err ;
if ( fp - > sync_ep ) {
err = snd_usb_add_endpoint ( chip , fp - > sync_ep ,
fp - > implicit_fb ?
SND_USB_ENDPOINT_TYPE_DATA :
SND_USB_ENDPOINT_TYPE_SYNC ) ;
if ( err < 0 )
return err ;
}
return 0 ;
}
2010-03-04 21:46:13 +03:00
/*
* create a stream for an endpoint / altsetting without proper descriptors
*/
static int create_fixed_stream_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
const struct snd_usb_audio_quirk * quirk )
{
struct audioformat * fp ;
struct usb_host_interface * alts ;
2013-07-09 22:36:15 +04:00
struct usb_interface_descriptor * altsd ;
2010-03-04 21:46:13 +03:00
unsigned * rate_table = NULL ;
2021-01-08 10:52:15 +03:00
int err ;
2010-03-04 21:46:13 +03:00
fp = kmemdup ( quirk - > data , sizeof ( * fp ) , GFP_KERNEL ) ;
2017-08-11 19:38:25 +03:00
if ( ! fp )
2010-03-04 21:46:13 +03:00
return - ENOMEM ;
2017-08-11 19:38:25 +03:00
2016-03-31 19:05:43 +03:00
INIT_LIST_HEAD ( & fp - > list ) ;
2012-02-14 14:18:48 +04:00
if ( fp - > nr_rates > MAX_NR_RATES ) {
kfree ( fp ) ;
return - EINVAL ;
}
2010-03-04 21:46:13 +03:00
if ( fp - > nr_rates > 0 ) {
2011-11-10 22:38:43 +04:00
rate_table = kmemdup ( fp - > rate_table ,
sizeof ( int ) * fp - > nr_rates , GFP_KERNEL ) ;
2010-03-04 21:46:13 +03:00
if ( ! rate_table ) {
kfree ( fp ) ;
return - ENOMEM ;
}
fp - > rate_table = rate_table ;
}
if ( fp - > iface ! = get_iface_desc ( & iface - > altsetting [ 0 ] ) - > bInterfaceNumber | |
fp - > altset_idx > = iface - > num_altsetting ) {
2016-03-15 14:14:49 +03:00
err = - EINVAL ;
goto error ;
2010-03-04 21:46:13 +03:00
}
alts = & iface - > altsetting [ fp - > altset_idx ] ;
2013-07-09 22:36:15 +04:00
altsd = get_iface_desc ( alts ) ;
2021-01-08 10:52:18 +03:00
if ( altsd - > bNumEndpoints < = fp - > ep_idx ) {
2016-03-15 14:14:49 +03:00
err = - EINVAL ;
goto error ;
2016-03-15 14:09:10 +03:00
}
2013-07-09 22:36:15 +04:00
fp - > protocol = altsd - > bInterfaceProtocol ;
2013-03-17 15:07:54 +04:00
if ( fp - > datainterval = = 0 )
fp - > datainterval = snd_usb_parse_datainterval ( chip , alts ) ;
if ( fp - > maxpacksize = = 0 )
2021-01-08 10:52:18 +03:00
fp - > maxpacksize = le16_to_cpu ( get_endpoint ( alts , fp - > ep_idx ) - > wMaxPacketSize ) ;
2021-01-08 10:52:15 +03:00
if ( ! fp - > fmt_type )
fp - > fmt_type = UAC_FORMAT_TYPE_I ;
err = add_audio_stream_from_fixed_fmt ( chip , fp ) ;
if ( err < 0 )
goto error ;
2010-03-04 21:46:13 +03:00
usb_set_interface ( chip - > dev , fp - > iface , 0 ) ;
2020-11-23 11:53:26 +03:00
snd_usb_init_pitch ( chip , fp ) ;
2020-11-23 11:53:25 +03:00
snd_usb_init_sample_rate ( chip , fp , fp - > rate_max ) ;
2010-03-04 21:46:13 +03:00
return 0 ;
2016-03-15 14:14:49 +03:00
error :
2016-03-31 19:05:43 +03:00
list_del ( & fp - > list ) ; /* unlink for avoiding double-free */
2016-03-15 14:14:49 +03:00
kfree ( fp ) ;
kfree ( rate_table ) ;
return err ;
2010-03-04 21:46:13 +03:00
}
2013-04-01 01:43:12 +04:00
static int create_auto_pcm_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver )
{
struct usb_host_interface * alts ;
struct usb_interface_descriptor * altsd ;
struct usb_endpoint_descriptor * epd ;
struct uac1_as_header_descriptor * ashd ;
struct uac_format_type_i_discrete_descriptor * fmtd ;
/*
* Most Roland / Yamaha audio streaming interfaces have more or less
* standard descriptors , but older devices might lack descriptors , and
* future ones might change , so ensure that we fail silently if the
* interface doesn ' t look exactly right .
*/
/* must have a non-zero altsetting for streaming */
if ( iface - > num_altsetting < 2 )
return - ENODEV ;
alts = & iface - > altsetting [ 1 ] ;
altsd = get_iface_desc ( alts ) ;
/* must have an isochronous endpoint for streaming */
if ( altsd - > bNumEndpoints < 1 )
return - ENODEV ;
epd = get_endpoint ( alts , 0 ) ;
if ( ! usb_endpoint_xfer_isoc ( epd ) )
return - ENODEV ;
/* must have format descriptors */
ashd = snd_usb_find_csint_desc ( alts - > extra , alts - > extralen , NULL ,
UAC_AS_GENERAL ) ;
fmtd = snd_usb_find_csint_desc ( alts - > extra , alts - > extralen , NULL ,
UAC_FORMAT_TYPE ) ;
if ( ! ashd | | ashd - > bLength < 7 | |
! fmtd | | fmtd - > bLength < 8 )
return - ENODEV ;
return create_standard_audio_quirk ( chip , iface , driver , NULL ) ;
}
static int create_yamaha_midi_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
struct usb_host_interface * alts )
{
static const struct snd_usb_audio_quirk yamaha_midi_quirk = {
. type = QUIRK_MIDI_YAMAHA
} ;
struct usb_midi_in_jack_descriptor * injd ;
struct usb_midi_out_jack_descriptor * outjd ;
/* must have some valid jack descriptors */
injd = snd_usb_find_csint_desc ( alts - > extra , alts - > extralen ,
NULL , USB_MS_MIDI_IN_JACK ) ;
outjd = snd_usb_find_csint_desc ( alts - > extra , alts - > extralen ,
NULL , USB_MS_MIDI_OUT_JACK ) ;
if ( ! injd & & ! outjd )
return - ENODEV ;
2019-11-13 14:12:59 +03:00
if ( ( injd & & ! snd_usb_validate_midi_desc ( injd ) ) | |
( outjd & & ! snd_usb_validate_midi_desc ( outjd ) ) )
2019-08-20 18:17:09 +03:00
return - ENODEV ;
2013-04-01 01:43:12 +04:00
if ( injd & & ( injd - > bLength < 5 | |
( injd - > bJackType ! = USB_MS_EMBEDDED & &
injd - > bJackType ! = USB_MS_EXTERNAL ) ) )
return - ENODEV ;
if ( outjd & & ( outjd - > bLength < 6 | |
( outjd - > bJackType ! = USB_MS_EMBEDDED & &
outjd - > bJackType ! = USB_MS_EXTERNAL ) ) )
return - ENODEV ;
return create_any_midi_quirk ( chip , iface , driver , & yamaha_midi_quirk ) ;
}
static int create_roland_midi_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
struct usb_host_interface * alts )
{
static const struct snd_usb_audio_quirk roland_midi_quirk = {
. type = QUIRK_MIDI_ROLAND
} ;
u8 * roland_desc = NULL ;
/* might have a vendor-specific descriptor <06 24 F1 02 ...> */
for ( ; ; ) {
roland_desc = snd_usb_find_csint_desc ( alts - > extra ,
alts - > extralen ,
roland_desc , 0xf1 ) ;
if ( ! roland_desc )
return - ENODEV ;
if ( roland_desc [ 0 ] < 6 | | roland_desc [ 3 ] ! = 2 )
continue ;
return create_any_midi_quirk ( chip , iface , driver ,
& roland_midi_quirk ) ;
}
}
static int create_std_midi_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
struct usb_host_interface * alts )
{
struct usb_ms_header_descriptor * mshd ;
struct usb_ms_endpoint_descriptor * msepd ;
/* must have the MIDIStreaming interface header descriptor*/
mshd = ( struct usb_ms_header_descriptor * ) alts - > extra ;
if ( alts - > extralen < 7 | |
mshd - > bLength < 7 | |
mshd - > bDescriptorType ! = USB_DT_CS_INTERFACE | |
mshd - > bDescriptorSubtype ! = USB_MS_HEADER )
return - ENODEV ;
/* must have the MIDIStreaming endpoint descriptor*/
msepd = ( struct usb_ms_endpoint_descriptor * ) alts - > endpoint [ 0 ] . extra ;
if ( alts - > endpoint [ 0 ] . extralen < 4 | |
msepd - > bLength < 4 | |
msepd - > bDescriptorType ! = USB_DT_CS_ENDPOINT | |
msepd - > bDescriptorSubtype ! = UAC_MS_GENERAL | |
msepd - > bNumEmbMIDIJack < 1 | |
msepd - > bNumEmbMIDIJack > 16 )
return - ENODEV ;
return create_any_midi_quirk ( chip , iface , driver , NULL ) ;
}
static int create_auto_midi_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver )
{
struct usb_host_interface * alts ;
struct usb_interface_descriptor * altsd ;
struct usb_endpoint_descriptor * epd ;
int err ;
alts = & iface - > altsetting [ 0 ] ;
altsd = get_iface_desc ( alts ) ;
/* must have at least one bulk/interrupt endpoint for streaming */
if ( altsd - > bNumEndpoints < 1 )
return - ENODEV ;
epd = get_endpoint ( alts , 0 ) ;
2013-08-11 16:13:13 +04:00
if ( ! usb_endpoint_xfer_bulk ( epd ) & &
2013-04-01 01:43:12 +04:00
! usb_endpoint_xfer_int ( epd ) )
return - ENODEV ;
switch ( USB_ID_VENDOR ( chip - > usb_id ) ) {
case 0x0499 : /* Yamaha */
err = create_yamaha_midi_quirk ( chip , iface , driver , alts ) ;
2013-08-11 16:13:13 +04:00
if ( err ! = - ENODEV )
2013-04-01 01:43:12 +04:00
return err ;
break ;
case 0x0582 : /* Roland */
err = create_roland_midi_quirk ( chip , iface , driver , alts ) ;
2013-08-11 16:13:13 +04:00
if ( err ! = - ENODEV )
2013-04-01 01:43:12 +04:00
return err ;
break ;
}
return create_std_midi_quirk ( chip , iface , driver , alts ) ;
}
static int create_autodetect_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
2013-04-04 23:43:57 +04:00
struct usb_driver * driver )
2013-04-01 01:43:12 +04:00
{
int err ;
err = create_auto_pcm_quirk ( chip , iface , driver ) ;
if ( err = = - ENODEV )
err = create_auto_midi_quirk ( chip , iface , driver ) ;
return err ;
}
2013-04-04 23:43:57 +04:00
static int create_autodetect_quirks ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
const struct snd_usb_audio_quirk * quirk )
{
int probed_ifnum = get_iface_desc ( iface - > altsetting ) - > bInterfaceNumber ;
int ifcount , ifnum , err ;
err = create_autodetect_quirk ( chip , iface , driver ) ;
if ( err < 0 )
return err ;
/*
* ALSA PCM playback / capture devices cannot be registered in two steps ,
* so we have to claim the other corresponding interface here .
*/
ifcount = chip - > dev - > actconfig - > desc . bNumInterfaces ;
for ( ifnum = 0 ; ifnum < ifcount ; ifnum + + ) {
if ( ifnum = = probed_ifnum | | quirk - > ifnum > = 0 )
continue ;
iface = usb_ifnum_to_if ( chip - > dev , ifnum ) ;
if ( ! iface | |
usb_interface_claimed ( iface ) | |
get_iface_desc ( iface - > altsetting ) - > bInterfaceClass ! =
USB_CLASS_VENDOR_SPEC )
continue ;
err = create_autodetect_quirk ( chip , iface , driver ) ;
2021-04-06 14:35:34 +03:00
if ( err > = 0 ) {
err = usb_driver_claim_interface ( driver , iface ,
USB_AUDIO_IFACE_UNUSED ) ;
if ( err < 0 )
return err ;
}
2013-04-04 23:43:57 +04:00
}
return 0 ;
}
2010-03-04 21:46:13 +03:00
/*
* Create a stream for an Edirol UA - 700 / UA - 25 / UA - 4F X interface .
* The only way to detect the sample rate is by looking at wMaxPacketSize .
*/
static int create_uaxx_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
const struct snd_usb_audio_quirk * quirk )
{
static const struct audioformat ua_format = {
2010-03-04 21:46:15 +03:00
. formats = SNDRV_PCM_FMTBIT_S24_3LE ,
2010-03-04 21:46:13 +03:00
. channels = 2 ,
. fmt_type = UAC_FORMAT_TYPE_I ,
. altsetting = 1 ,
. altset_idx = 1 ,
. rates = SNDRV_PCM_RATE_CONTINUOUS ,
} ;
struct usb_host_interface * alts ;
struct usb_interface_descriptor * altsd ;
struct audioformat * fp ;
2021-01-08 10:52:15 +03:00
int err ;
2010-03-04 21:46:13 +03:00
/* both PCM and MIDI interfaces have 2 or more altsettings */
if ( iface - > num_altsetting < 2 )
return - ENXIO ;
alts = & iface - > altsetting [ 1 ] ;
altsd = get_iface_desc ( alts ) ;
if ( altsd - > bNumEndpoints = = 2 ) {
static const struct snd_usb_midi_endpoint_info ua700_ep = {
. out_cables = 0x0003 ,
. in_cables = 0x0003
} ;
static const struct snd_usb_audio_quirk ua700_quirk = {
. type = QUIRK_MIDI_FIXED_ENDPOINT ,
. data = & ua700_ep
} ;
static const struct snd_usb_midi_endpoint_info uaxx_ep = {
. out_cables = 0x0001 ,
. in_cables = 0x0001
} ;
static const struct snd_usb_audio_quirk uaxx_quirk = {
. type = QUIRK_MIDI_FIXED_ENDPOINT ,
. data = & uaxx_ep
} ;
const struct snd_usb_audio_quirk * quirk =
chip - > usb_id = = USB_ID ( 0x0582 , 0x002b )
? & ua700_quirk : & uaxx_quirk ;
2016-01-11 13:33:34 +03:00
return __snd_usbmidi_create ( chip - > card , iface ,
& chip - > midi_list , quirk ,
chip - > usb_id ) ;
2010-03-04 21:46:13 +03:00
}
if ( altsd - > bNumEndpoints ! = 1 )
return - ENXIO ;
2011-11-10 22:38:43 +04:00
fp = kmemdup ( & ua_format , sizeof ( * fp ) , GFP_KERNEL ) ;
2010-03-04 21:46:13 +03:00
if ( ! fp )
return - ENOMEM ;
fp - > iface = altsd - > bInterfaceNumber ;
fp - > endpoint = get_endpoint ( alts , 0 ) - > bEndpointAddress ;
fp - > ep_attr = get_endpoint ( alts , 0 ) - > bmAttributes ;
fp - > datainterval = 0 ;
fp - > maxpacksize = le16_to_cpu ( get_endpoint ( alts , 0 ) - > wMaxPacketSize ) ;
2016-03-31 19:05:43 +03:00
INIT_LIST_HEAD ( & fp - > list ) ;
2010-03-04 21:46:13 +03:00
switch ( fp - > maxpacksize ) {
case 0x120 :
fp - > rate_max = fp - > rate_min = 44100 ;
break ;
case 0x138 :
case 0x140 :
fp - > rate_max = fp - > rate_min = 48000 ;
break ;
case 0x258 :
case 0x260 :
fp - > rate_max = fp - > rate_min = 96000 ;
break ;
default :
2014-02-26 16:02:17 +04:00
usb_audio_err ( chip , " unknown sample rate \n " ) ;
2010-03-04 21:46:13 +03:00
kfree ( fp ) ;
return - ENXIO ;
}
2021-01-08 10:52:15 +03:00
err = add_audio_stream_from_fixed_fmt ( chip , fp ) ;
2010-03-04 21:46:13 +03:00
if ( err < 0 ) {
2016-03-31 19:05:43 +03:00
list_del ( & fp - > list ) ; /* unlink for avoiding double-free */
2010-03-04 21:46:13 +03:00
kfree ( fp ) ;
return err ;
}
usb_set_interface ( chip - > dev , fp - > iface , 0 ) ;
return 0 ;
}
2011-05-25 11:09:02 +04:00
/*
* Create a standard mixer for the specified interface .
*/
static int create_standard_mixer_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
const struct snd_usb_audio_quirk * quirk )
{
if ( quirk - > ifnum < 0 )
return 0 ;
2021-07-29 10:44:01 +03:00
return snd_usb_create_mixer ( chip , quirk - > ifnum ) ;
2011-05-25 11:09:02 +04:00
}
2010-03-04 21:46:13 +03:00
/*
* audio - interface quirks
*
* returns zero if no standard audio / MIDI parsing is needed .
2011-03-31 05:57:33 +04:00
* returns a positive value if standard audio / midi interfaces are parsed
2010-03-04 21:46:13 +03:00
* after this .
* returns a negative value at error .
*/
int snd_usb_create_quirk ( struct snd_usb_audio * chip ,
struct usb_interface * iface ,
struct usb_driver * driver ,
const struct snd_usb_audio_quirk * quirk )
{
typedef int ( * quirk_func_t ) ( struct snd_usb_audio * ,
struct usb_interface * ,
struct usb_driver * ,
const struct snd_usb_audio_quirk * ) ;
static const quirk_func_t quirk_funcs [ ] = {
[ QUIRK_IGNORE_INTERFACE ] = ignore_interface_quirk ,
[ QUIRK_COMPOSITE ] = create_composite_quirk ,
2013-04-04 23:43:57 +04:00
[ QUIRK_AUTODETECT ] = create_autodetect_quirks ,
2010-03-04 21:46:13 +03:00
[ QUIRK_MIDI_STANDARD_INTERFACE ] = create_any_midi_quirk ,
[ QUIRK_MIDI_FIXED_ENDPOINT ] = create_any_midi_quirk ,
[ QUIRK_MIDI_YAMAHA ] = create_any_midi_quirk ,
2013-04-01 01:43:12 +04:00
[ QUIRK_MIDI_ROLAND ] = create_any_midi_quirk ,
2010-03-04 21:46:13 +03:00
[ QUIRK_MIDI_MIDIMAN ] = create_any_midi_quirk ,
[ QUIRK_MIDI_NOVATION ] = create_any_midi_quirk ,
2010-10-22 20:20:48 +04:00
[ QUIRK_MIDI_RAW_BYTES ] = create_any_midi_quirk ,
2010-03-04 21:46:13 +03:00
[ QUIRK_MIDI_EMAGIC ] = create_any_midi_quirk ,
[ QUIRK_MIDI_CME ] = create_any_midi_quirk ,
2010-05-20 23:31:10 +04:00
[ QUIRK_MIDI_AKAI ] = create_any_midi_quirk ,
2011-08-26 15:19:49 +04:00
[ QUIRK_MIDI_FTDI ] = create_any_midi_quirk ,
2015-11-16 00:38:29 +03:00
[ QUIRK_MIDI_CH345 ] = create_any_midi_quirk ,
2010-03-04 21:46:13 +03:00
[ QUIRK_AUDIO_STANDARD_INTERFACE ] = create_standard_audio_quirk ,
[ QUIRK_AUDIO_FIXED_ENDPOINT ] = create_fixed_stream_quirk ,
[ QUIRK_AUDIO_EDIROL_UAXX ] = create_uaxx_quirk ,
2011-05-25 11:09:02 +04:00
[ QUIRK_AUDIO_STANDARD_MIXER ] = create_standard_mixer_quirk ,
2010-03-04 21:46:13 +03:00
} ;
if ( quirk - > type < QUIRK_TYPE_COUNT ) {
return quirk_funcs [ quirk - > type ] ( chip , iface , driver , quirk ) ;
} else {
2014-02-26 16:02:17 +04:00
usb_audio_err ( chip , " invalid quirk type %d \n " , quirk - > type ) ;
2010-03-04 21:46:13 +03:00
return - ENXIO ;
}
}
/*
* boot quirks
*/
# define EXTIGY_FIRMWARE_SIZE_OLD 794
# define EXTIGY_FIRMWARE_SIZE_NEW 483
static int snd_usb_extigy_boot_quirk ( struct usb_device * dev , struct usb_interface * intf )
{
struct usb_host_config * config = dev - > actconfig ;
int err ;
if ( le16_to_cpu ( get_cfg_desc ( config ) - > wTotalLength ) = = EXTIGY_FIRMWARE_SIZE_OLD | |
le16_to_cpu ( get_cfg_desc ( config ) - > wTotalLength ) = = EXTIGY_FIRMWARE_SIZE_NEW ) {
2014-02-26 16:02:17 +04:00
dev_dbg ( & dev - > dev , " sending Extigy boot sequence... \n " ) ;
2010-03-04 21:46:13 +03:00
/* Send message to force it to reconnect with full interface. */
err = snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
2011-09-26 23:15:27 +04:00
0x10 , 0x43 , 0x0001 , 0x000a , NULL , 0 ) ;
2014-02-26 16:02:17 +04:00
if ( err < 0 )
dev_dbg ( & dev - > dev , " error sending boot message: %d \n " , err ) ;
2010-03-04 21:46:13 +03:00
err = usb_get_descriptor ( dev , USB_DT_DEVICE , 0 ,
& dev - > descriptor , sizeof ( dev - > descriptor ) ) ;
config = dev - > actconfig ;
2014-02-26 16:02:17 +04:00
if ( err < 0 )
dev_dbg ( & dev - > dev , " error usb_get_descriptor: %d \n " , err ) ;
2010-03-04 21:46:13 +03:00
err = usb_reset_configuration ( dev ) ;
2014-02-26 16:02:17 +04:00
if ( err < 0 )
dev_dbg ( & dev - > dev , " error usb_reset_configuration: %d \n " , err ) ;
dev_dbg ( & dev - > dev , " extigy_boot: new boot length = %d \n " ,
2010-03-04 21:46:13 +03:00
le16_to_cpu ( get_cfg_desc ( config ) - > wTotalLength ) ) ;
return - ENODEV ; /* quit this anyway */
}
return 0 ;
}
static int snd_usb_audigy2nx_boot_quirk ( struct usb_device * dev )
{
u8 buf = 1 ;
snd_usb_ctl_msg ( dev , usb_rcvctrlpipe ( dev , 0 ) , 0x2a ,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER ,
2011-09-26 23:15:27 +04:00
0 , 0 , & buf , 1 ) ;
2010-03-04 21:46:13 +03:00
if ( buf = = 0 ) {
snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) , 0x29 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER ,
2011-09-26 23:15:27 +04:00
1 , 2000 , NULL , 0 ) ;
2010-03-04 21:46:13 +03:00
return - ENODEV ;
}
return 0 ;
}
2011-07-12 20:13:46 +04:00
static int snd_usb_fasttrackpro_boot_quirk ( struct usb_device * dev )
{
int err ;
if ( dev - > actconfig - > desc . bConfigurationValue = = 1 ) {
2014-02-26 16:02:17 +04:00
dev_info ( & dev - > dev ,
2011-07-12 20:13:46 +04:00
" Fast Track Pro switching to config #2 \n " ) ;
/* This function has to be available by the usb core module.
* if it is not avialable the boot quirk has to be left out
* and the configuration has to be set by udev or hotplug
* rules
*/
err = usb_driver_set_configuration ( dev , 2 ) ;
2013-01-04 20:02:18 +04:00
if ( err < 0 )
2014-02-26 16:02:17 +04:00
dev_dbg ( & dev - > dev ,
" error usb_driver_set_configuration: %d \n " ,
err ) ;
2013-01-04 20:02:18 +04:00
/* Always return an error, so that we stop creating a device
that will just be destroyed and recreated with a new
configuration */
return - ENODEV ;
2011-07-12 20:13:46 +04:00
} else
2014-02-26 16:02:17 +04:00
dev_info ( & dev - > dev , " Fast Track Pro config OK \n " ) ;
2011-07-12 20:13:46 +04:00
return 0 ;
}
2010-03-04 21:46:13 +03:00
/*
* C - Media CM106 / CM106 + have four 16 - bit internal registers that are nicely
* documented in the device ' s data sheet .
*/
static int snd_usb_cm106_write_int_reg ( struct usb_device * dev , int reg , u16 value )
{
u8 buf [ 4 ] ;
buf [ 0 ] = 0x20 ;
buf [ 1 ] = value & 0xff ;
buf [ 2 ] = ( value > > 8 ) & 0xff ;
buf [ 3 ] = reg ;
return snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) , USB_REQ_SET_CONFIGURATION ,
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT ,
2011-09-26 23:15:27 +04:00
0 , 0 , & buf , 4 ) ;
2010-03-04 21:46:13 +03:00
}
static int snd_usb_cm106_boot_quirk ( struct usb_device * dev )
{
/*
* Enable line - out driver mode , set headphone source to front
* channels , enable stereo mic .
*/
return snd_usb_cm106_write_int_reg ( dev , 2 , 0x8004 ) ;
}
/*
2018-11-03 00:11:33 +03:00
* CM6206 registers from the CM6206 datasheet rev 2.1
2010-03-04 21:46:13 +03:00
*/
2018-11-03 00:11:33 +03:00
# define CM6206_REG0_DMA_MASTER BIT(15)
# define CM6206_REG0_SPDIFO_RATE_48K (2 << 12)
# define CM6206_REG0_SPDIFO_RATE_96K (7 << 12)
/* Bit 4 thru 11 is the S/PDIF category code */
# define CM6206_REG0_SPDIFO_CAT_CODE_GENERAL (0 << 4)
# define CM6206_REG0_SPDIFO_EMPHASIS_CD BIT(3)
# define CM6206_REG0_SPDIFO_COPYRIGHT_NA BIT(2)
# define CM6206_REG0_SPDIFO_NON_AUDIO BIT(1)
# define CM6206_REG0_SPDIFO_PRO_FORMAT BIT(0)
# define CM6206_REG1_TEST_SEL_CLK BIT(14)
# define CM6206_REG1_PLLBIN_EN BIT(13)
# define CM6206_REG1_SOFT_MUTE_EN BIT(12)
# define CM6206_REG1_GPIO4_OUT BIT(11)
# define CM6206_REG1_GPIO4_OE BIT(10)
# define CM6206_REG1_GPIO3_OUT BIT(9)
# define CM6206_REG1_GPIO3_OE BIT(8)
# define CM6206_REG1_GPIO2_OUT BIT(7)
# define CM6206_REG1_GPIO2_OE BIT(6)
# define CM6206_REG1_GPIO1_OUT BIT(5)
# define CM6206_REG1_GPIO1_OE BIT(4)
# define CM6206_REG1_SPDIFO_INVALID BIT(3)
# define CM6206_REG1_SPDIF_LOOP_EN BIT(2)
# define CM6206_REG1_SPDIFO_DIS BIT(1)
# define CM6206_REG1_SPDIFI_MIX BIT(0)
# define CM6206_REG2_DRIVER_ON BIT(15)
# define CM6206_REG2_HEADP_SEL_SIDE_CHANNELS (0 << 13)
# define CM6206_REG2_HEADP_SEL_SURROUND_CHANNELS (1 << 13)
# define CM6206_REG2_HEADP_SEL_CENTER_SUBW (2 << 13)
# define CM6206_REG2_HEADP_SEL_FRONT_CHANNELS (3 << 13)
# define CM6206_REG2_MUTE_HEADPHONE_RIGHT BIT(12)
# define CM6206_REG2_MUTE_HEADPHONE_LEFT BIT(11)
# define CM6206_REG2_MUTE_REAR_SURROUND_RIGHT BIT(10)
# define CM6206_REG2_MUTE_REAR_SURROUND_LEFT BIT(9)
# define CM6206_REG2_MUTE_SIDE_SURROUND_RIGHT BIT(8)
# define CM6206_REG2_MUTE_SIDE_SURROUND_LEFT BIT(7)
# define CM6206_REG2_MUTE_SUBWOOFER BIT(6)
# define CM6206_REG2_MUTE_CENTER BIT(5)
# define CM6206_REG2_MUTE_RIGHT_FRONT BIT(3)
# define CM6206_REG2_MUTE_LEFT_FRONT BIT(3)
# define CM6206_REG2_EN_BTL BIT(2)
# define CM6206_REG2_MCUCLKSEL_1_5_MHZ (0)
# define CM6206_REG2_MCUCLKSEL_3_MHZ (1)
# define CM6206_REG2_MCUCLKSEL_6_MHZ (2)
# define CM6206_REG2_MCUCLKSEL_12_MHZ (3)
/* Bit 11..13 sets the sensitivity to FLY tuner volume control VP/VD signal */
# define CM6206_REG3_FLYSPEED_DEFAULT (2 << 11)
# define CM6206_REG3_VRAP25EN BIT(10)
# define CM6206_REG3_MSEL1 BIT(9)
# define CM6206_REG3_SPDIFI_RATE_44_1K BIT(0 << 7)
# define CM6206_REG3_SPDIFI_RATE_48K BIT(2 << 7)
# define CM6206_REG3_SPDIFI_RATE_32K BIT(3 << 7)
# define CM6206_REG3_PINSEL BIT(6)
# define CM6206_REG3_FOE BIT(5)
# define CM6206_REG3_ROE BIT(4)
# define CM6206_REG3_CBOE BIT(3)
# define CM6206_REG3_LOSE BIT(2)
# define CM6206_REG3_HPOE BIT(1)
# define CM6206_REG3_SPDIFI_CANREC BIT(0)
# define CM6206_REG5_DA_RSTN BIT(13)
# define CM6206_REG5_AD_RSTN BIT(12)
# define CM6206_REG5_SPDIFO_AD2SPDO BIT(12)
# define CM6206_REG5_SPDIFO_SEL_FRONT (0 << 9)
# define CM6206_REG5_SPDIFO_SEL_SIDE_SUR (1 << 9)
# define CM6206_REG5_SPDIFO_SEL_CEN_LFE (2 << 9)
# define CM6206_REG5_SPDIFO_SEL_REAR_SUR (3 << 9)
# define CM6206_REG5_CODECM BIT(8)
# define CM6206_REG5_EN_HPF BIT(7)
# define CM6206_REG5_T_SEL_DSDA4 BIT(6)
# define CM6206_REG5_T_SEL_DSDA3 BIT(5)
# define CM6206_REG5_T_SEL_DSDA2 BIT(4)
# define CM6206_REG5_T_SEL_DSDA1 BIT(3)
# define CM6206_REG5_T_SEL_DSDAD_NORMAL 0
# define CM6206_REG5_T_SEL_DSDAD_FRONT 4
# define CM6206_REG5_T_SEL_DSDAD_S_SURROUND 5
# define CM6206_REG5_T_SEL_DSDAD_CEN_LFE 6
# define CM6206_REG5_T_SEL_DSDAD_R_SURROUND 7
2010-03-04 21:46:13 +03:00
static int snd_usb_cm6206_boot_quirk ( struct usb_device * dev )
{
2011-08-06 02:23:18 +04:00
int err = 0 , reg ;
2018-11-03 00:11:33 +03:00
int val [ ] = {
/*
* Values here are chosen based on sniffing USB traffic
* under Windows .
*
* REG0 : DAC is master , sample rate 48 kHz , no copyright
*/
CM6206_REG0_SPDIFO_RATE_48K |
CM6206_REG0_SPDIFO_COPYRIGHT_NA ,
/*
* REG1 : PLL binary search enable , soft mute enable .
*/
CM6206_REG1_PLLBIN_EN |
2019-01-08 23:03:11 +03:00
CM6206_REG1_SOFT_MUTE_EN ,
2018-11-03 00:11:33 +03:00
/*
* REG2 : enable output drivers ,
* select front channels to the headphone output ,
* then mute the headphone channels , run the MCU
* at 1.5 MHz .
*/
CM6206_REG2_DRIVER_ON |
CM6206_REG2_HEADP_SEL_FRONT_CHANNELS |
CM6206_REG2_MUTE_HEADPHONE_RIGHT |
CM6206_REG2_MUTE_HEADPHONE_LEFT ,
/*
* REG3 : default flyspeed , set 2.5 V mic bias
* enable all line out ports and enable SPDIF
*/
CM6206_REG3_FLYSPEED_DEFAULT |
CM6206_REG3_VRAP25EN |
CM6206_REG3_FOE |
CM6206_REG3_ROE |
CM6206_REG3_CBOE |
CM6206_REG3_LOSE |
CM6206_REG3_HPOE |
CM6206_REG3_SPDIFI_CANREC ,
/* REG4 is just a bunch of GPIO lines */
0x0000 ,
/* REG5: de-assert AD/DA reset signals */
CM6206_REG5_DA_RSTN |
CM6206_REG5_AD_RSTN } ;
2010-03-04 21:46:13 +03:00
for ( reg = 0 ; reg < ARRAY_SIZE ( val ) ; reg + + ) {
err = snd_usb_cm106_write_int_reg ( dev , reg , val [ reg ] ) ;
if ( err < 0 )
return err ;
}
return err ;
}
2013-12-19 17:32:53 +04:00
/* quirk for Plantronics GameCom 780 with CM6302 chip */
static int snd_usb_gamecon780_boot_quirk ( struct usb_device * dev )
{
/* set the initial volume and don't change; other values are either
* too loud or silent due to firmware bug ( bko # 65251 )
*/
2014-08-04 02:47:36 +04:00
u8 buf [ 2 ] = { 0x74 , 0xe3 } ;
2013-12-19 17:32:53 +04:00
return snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) , UAC_SET_CUR ,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT ,
UAC_FU_VOLUME < < 8 , 9 < < 8 , buf , 2 ) ;
}
2013-03-17 15:07:53 +04:00
/*
* Novation Twitch DJ controller
2013-12-20 12:06:58 +04:00
* Focusrite Novation Saffire 6 USB audio card
2013-03-17 15:07:53 +04:00
*/
2013-12-20 12:06:58 +04:00
static int snd_usb_novation_boot_quirk ( struct usb_device * dev )
2013-03-17 15:07:53 +04:00
{
/* preemptively set up the device because otherwise the
* raw MIDI endpoints are not active */
usb_set_interface ( dev , 0 , 1 ) ;
return 0 ;
}
2010-03-04 21:46:13 +03:00
/*
* This call will put the synth in " USB send " mode , i . e it will send MIDI
* messages through USB ( this is disabled at startup ) . The synth will
* acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
* sign on its LCD . Values here are chosen based on sniffing USB traffic
* under Windows .
*/
static int snd_usb_accessmusic_boot_quirk ( struct usb_device * dev )
{
int err , actual_length ;
/* "midi send" enable */
static const u8 seq [ ] = { 0x4e , 0x73 , 0x52 , 0x01 } ;
2019-06-24 16:08:28 +03:00
void * buf ;
2010-03-04 21:46:13 +03:00
2020-09-14 18:37:46 +03:00
if ( usb_pipe_type_check ( dev , usb_sndintpipe ( dev , 0x05 ) ) )
2019-06-24 16:08:28 +03:00
return - EINVAL ;
buf = kmemdup ( seq , ARRAY_SIZE ( seq ) , GFP_KERNEL ) ;
2010-03-04 21:46:13 +03:00
if ( ! buf )
return - ENOMEM ;
err = usb_interrupt_msg ( dev , usb_sndintpipe ( dev , 0x05 ) , buf ,
ARRAY_SIZE ( seq ) , & actual_length , 1000 ) ;
kfree ( buf ) ;
if ( err < 0 )
return err ;
return 0 ;
}
2011-02-11 14:08:06 +03:00
/*
* Some sound cards from Native Instruments are in fact compliant to the USB
* audio standard of version 2 and other approved USB standards , even though
* they come up as vendor - specific device when first connected .
*
* However , they can be told to come up with a new set of descriptors
* upon their next enumeration , and the interfaces announced by the new
* descriptors will then be handled by the kernel ' s class drivers . As the
* product ID will also change , no further checks are required .
*/
static int snd_usb_nativeinstruments_boot_quirk ( struct usb_device * dev )
{
2019-06-24 16:08:28 +03:00
int ret ;
ret = usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
2011-02-11 14:08:06 +03:00
0xaf , USB_TYPE_VENDOR | USB_RECIP_DEVICE ,
2013-04-05 22:49:46 +04:00
1 , 0 , NULL , 0 , 1000 ) ;
2011-02-11 14:08:06 +03:00
if ( ret < 0 )
return ret ;
usb_reset_device ( dev ) ;
/* return -EAGAIN, so the creation of an audio interface for this
* temporary device is aborted . The device will reconnect with a
* new product ID */
return - EAGAIN ;
}
2012-12-19 14:27:22 +04:00
static void mbox2_setup_48_24_magic ( struct usb_device * dev )
{
u8 srate [ 3 ] ;
u8 temp [ 12 ] ;
/* Choose 48000Hz permanently */
srate [ 0 ] = 0x80 ;
srate [ 1 ] = 0xbb ;
srate [ 2 ] = 0x00 ;
/* Send the magic! */
snd_usb_ctl_msg ( dev , usb_rcvctrlpipe ( dev , 0 ) ,
0x01 , 0x22 , 0x0100 , 0x0085 , & temp , 0x0003 ) ;
snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
0x81 , 0xa2 , 0x0100 , 0x0085 , & srate , 0x0003 ) ;
snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
0x81 , 0xa2 , 0x0100 , 0x0086 , & srate , 0x0003 ) ;
snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
0x81 , 0xa2 , 0x0100 , 0x0003 , & srate , 0x0003 ) ;
return ;
}
/* Digidesign Mbox 2 needs to load firmware onboard
* and driver must wait a few seconds for initialisation .
*/
# define MBOX2_FIRMWARE_SIZE 646
# define MBOX2_BOOT_LOADING 0x01 /* Hard coded into the device */
# define MBOX2_BOOT_READY 0x02 /* Hard coded into the device */
2013-01-04 12:51:44 +04:00
static int snd_usb_mbox2_boot_quirk ( struct usb_device * dev )
2012-12-19 14:27:22 +04:00
{
struct usb_host_config * config = dev - > actconfig ;
int err ;
2013-02-17 17:33:04 +04:00
u8 bootresponse [ 0x12 ] ;
2012-12-19 14:27:22 +04:00
int fwsize ;
int count ;
fwsize = le16_to_cpu ( get_cfg_desc ( config ) - > wTotalLength ) ;
if ( fwsize ! = MBOX2_FIRMWARE_SIZE ) {
2014-02-26 16:02:17 +04:00
dev_err ( & dev - > dev , " Invalid firmware size=%d. \n " , fwsize ) ;
2012-12-19 14:27:22 +04:00
return - ENODEV ;
}
2014-02-26 16:02:17 +04:00
dev_dbg ( & dev - > dev , " Sending Digidesign Mbox 2 boot sequence... \n " ) ;
2012-12-19 14:27:22 +04:00
count = 0 ;
2013-01-04 12:51:44 +04:00
bootresponse [ 0 ] = MBOX2_BOOT_LOADING ;
while ( ( bootresponse [ 0 ] = = MBOX2_BOOT_LOADING ) & & ( count < 10 ) ) {
2012-12-19 14:27:22 +04:00
msleep ( 500 ) ; /* 0.5 second delay */
snd_usb_ctl_msg ( dev , usb_rcvctrlpipe ( dev , 0 ) ,
/* Control magic - load onboard firmware */
0x85 , 0xc0 , 0x0001 , 0x0000 , & bootresponse , 0x0012 ) ;
2013-01-04 12:51:44 +04:00
if ( bootresponse [ 0 ] = = MBOX2_BOOT_READY )
2012-12-19 14:27:22 +04:00
break ;
2014-02-26 16:02:17 +04:00
dev_dbg ( & dev - > dev , " device not ready, resending boot sequence... \n " ) ;
2012-12-19 14:27:22 +04:00
count + + ;
}
2013-01-04 12:51:44 +04:00
if ( bootresponse [ 0 ] ! = MBOX2_BOOT_READY ) {
2014-02-26 16:02:17 +04:00
dev_err ( & dev - > dev , " Unknown bootresponse=%d, or timed out, ignoring device. \n " , bootresponse [ 0 ] ) ;
2012-12-19 14:27:22 +04:00
return - ENODEV ;
}
2014-02-26 16:02:17 +04:00
dev_dbg ( & dev - > dev , " device initialised! \n " ) ;
2012-12-19 14:27:22 +04:00
err = usb_get_descriptor ( dev , USB_DT_DEVICE , 0 ,
& dev - > descriptor , sizeof ( dev - > descriptor ) ) ;
config = dev - > actconfig ;
if ( err < 0 )
2014-02-26 16:02:17 +04:00
dev_dbg ( & dev - > dev , " error usb_get_descriptor: %d \n " , err ) ;
2012-12-19 14:27:22 +04:00
err = usb_reset_configuration ( dev ) ;
if ( err < 0 )
2014-02-26 16:02:17 +04:00
dev_dbg ( & dev - > dev , " error usb_reset_configuration: %d \n " , err ) ;
dev_dbg ( & dev - > dev , " mbox2_boot: new boot length = %d \n " ,
2012-12-19 14:27:22 +04:00
le16_to_cpu ( get_cfg_desc ( config ) - > wTotalLength ) ) ;
mbox2_setup_48_24_magic ( dev ) ;
2014-02-26 16:02:17 +04:00
dev_info ( & dev - > dev , " Digidesign Mbox 2: 24bit 48kHz " ) ;
2012-12-19 14:27:22 +04:00
return 0 ; /* Successful boot */
}
2018-05-09 01:14:13 +03:00
static int snd_usb_axefx3_boot_quirk ( struct usb_device * dev )
{
int err ;
dev_dbg ( & dev - > dev , " Waiting for Axe-Fx III to boot up... \n " ) ;
/* If the Axe-Fx III has not fully booted, it will timeout when trying
* to enable the audio streaming interface . A more generous timeout is
* used here to detect when the Axe - Fx III has finished booting as the
* set interface message will be acked once it has
*/
err = usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_SET_INTERFACE , USB_RECIP_INTERFACE ,
1 , 1 , NULL , 0 , 120000 ) ;
if ( err < 0 ) {
dev_err ( & dev - > dev ,
" failed waiting for Axe-Fx III to boot: %d \n " , err ) ;
return err ;
}
dev_dbg ( & dev - > dev , " Axe-Fx III is now ready \n " ) ;
err = usb_set_interface ( dev , 1 , 0 ) ;
if ( err < 0 )
dev_dbg ( & dev - > dev ,
" error stopping Axe-Fx III interface: %d \n " , err ) ;
return 0 ;
}
2019-02-28 22:34:04 +03:00
# define MICROBOOK_BUF_SIZE 128
static int snd_usb_motu_microbookii_communicate ( struct usb_device * dev , u8 * buf ,
int buf_size , int * length )
{
int err , actual_length ;
2020-09-14 18:37:46 +03:00
if ( usb_pipe_type_check ( dev , usb_sndintpipe ( dev , 0x01 ) ) )
2019-06-24 16:08:28 +03:00
return - EINVAL ;
2019-02-28 22:34:04 +03:00
err = usb_interrupt_msg ( dev , usb_sndintpipe ( dev , 0x01 ) , buf , * length ,
& actual_length , 1000 ) ;
if ( err < 0 )
return err ;
print_hex_dump ( KERN_DEBUG , " MicroBookII snd: " , DUMP_PREFIX_NONE , 16 , 1 ,
buf , actual_length , false ) ;
memset ( buf , 0 , buf_size ) ;
2020-09-14 18:37:46 +03:00
if ( usb_pipe_type_check ( dev , usb_rcvintpipe ( dev , 0x82 ) ) )
2019-06-24 16:08:28 +03:00
return - EINVAL ;
2019-02-28 22:34:04 +03:00
err = usb_interrupt_msg ( dev , usb_rcvintpipe ( dev , 0x82 ) , buf , buf_size ,
& actual_length , 1000 ) ;
if ( err < 0 )
return err ;
print_hex_dump ( KERN_DEBUG , " MicroBookII rcv: " , DUMP_PREFIX_NONE , 16 , 1 ,
buf , actual_length , false ) ;
* length = actual_length ;
return 0 ;
}
static int snd_usb_motu_microbookii_boot_quirk ( struct usb_device * dev )
{
int err , actual_length , poll_attempts = 0 ;
static const u8 set_samplerate_seq [ ] = { 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x0b , 0x14 ,
0x00 , 0x00 , 0x00 , 0x01 } ;
static const u8 poll_ready_seq [ ] = { 0x00 , 0x04 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x0b , 0x18 } ;
u8 * buf = kzalloc ( MICROBOOK_BUF_SIZE , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
dev_info ( & dev - > dev , " Waiting for MOTU Microbook II to boot up... \n " ) ;
/* First we tell the device which sample rate to use. */
memcpy ( buf , set_samplerate_seq , sizeof ( set_samplerate_seq ) ) ;
actual_length = sizeof ( set_samplerate_seq ) ;
err = snd_usb_motu_microbookii_communicate ( dev , buf , MICROBOOK_BUF_SIZE ,
& actual_length ) ;
if ( err < 0 ) {
dev_err ( & dev - > dev ,
" failed setting the sample rate for Motu MicroBook II: %d \n " ,
err ) ;
goto free_buf ;
}
/* Then we poll every 100 ms until the device informs of its readiness. */
while ( true ) {
if ( + + poll_attempts > 100 ) {
dev_err ( & dev - > dev ,
" failed booting Motu MicroBook II: timeout \n " ) ;
err = - ENODEV ;
goto free_buf ;
}
memset ( buf , 0 , MICROBOOK_BUF_SIZE ) ;
memcpy ( buf , poll_ready_seq , sizeof ( poll_ready_seq ) ) ;
actual_length = sizeof ( poll_ready_seq ) ;
err = snd_usb_motu_microbookii_communicate (
dev , buf , MICROBOOK_BUF_SIZE , & actual_length ) ;
if ( err < 0 ) {
dev_err ( & dev - > dev ,
" failed booting Motu MicroBook II: communication error %d \n " ,
err ) ;
goto free_buf ;
}
/* the device signals its readiness through a message of the
* form
* XX 06 00 00 00 00 0 b 18 00 00 00 01
* If the device is not yet ready to accept audio data , the
* last byte of that sequence is 00.
*/
if ( actual_length = = 12 & & buf [ actual_length - 1 ] = = 1 )
break ;
msleep ( 100 ) ;
}
dev_info ( & dev - > dev , " MOTU MicroBook II ready \n " ) ;
free_buf :
kfree ( buf ) ;
return err ;
}
2020-01-12 13:23:58 +03:00
static int snd_usb_motu_m_series_boot_quirk ( struct usb_device * dev )
{
msleep ( 2000 ) ;
return 0 ;
}
2010-03-04 21:46:13 +03:00
/*
* Setup quirks
*/
2011-07-12 20:13:46 +04:00
# define MAUDIO_SET 0x01 /* parse device_setup */
# define MAUDIO_SET_COMPATIBLE 0x80 /* use only "win-compatible" interfaces */
# define MAUDIO_SET_DTS 0x02 /* enable DTS Digital Output */
2020-06-29 06:26:07 +03:00
# define MAUDIO_SET_96K 0x04 /* 48-96kHz rate if set, 8-48kHz otherwise */
2011-07-12 20:13:46 +04:00
# define MAUDIO_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
# define MAUDIO_SET_DI 0x10 /* enable Digital Input */
# define MAUDIO_SET_MASK 0x1f /* bit mask for setup value */
2020-06-29 06:26:07 +03:00
# define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48kHz+Digital Input */
# define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48kHz+No Digital Input */
# define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48kHz+Digital Input */
# define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48kHz+No Digital Input */
2011-07-12 20:13:46 +04:00
static int quattro_skip_setting_quirk ( struct snd_usb_audio * chip ,
int iface , int altno )
{
/* Reset ALL ifaces to 0 altsetting.
* Call it for every possible altsetting of every interface .
*/
usb_set_interface ( chip - > dev , iface , 0 ) ;
if ( chip - > setup & MAUDIO_SET ) {
if ( chip - > setup & MAUDIO_SET_COMPATIBLE ) {
if ( iface ! = 1 & & iface ! = 2 )
return 1 ; /* skip all interfaces but 1 and 2 */
} else {
unsigned int mask ;
if ( iface = = 1 | | iface = = 2 )
return 1 ; /* skip interfaces 1 and 2 */
if ( ( chip - > setup & MAUDIO_SET_96K ) & & altno ! = 1 )
return 1 ; /* skip this altsetting */
mask = chip - > setup & MAUDIO_SET_MASK ;
if ( mask = = MAUDIO_SET_24B_48K_DI & & altno ! = 2 )
return 1 ; /* skip this altsetting */
if ( mask = = MAUDIO_SET_24B_48K_NOTDI & & altno ! = 3 )
return 1 ; /* skip this altsetting */
if ( mask = = MAUDIO_SET_16B_48K_NOTDI & & altno ! = 4 )
return 1 ; /* skip this altsetting */
}
}
2014-02-26 16:02:17 +04:00
usb_audio_dbg ( chip ,
2011-07-12 20:13:46 +04:00
" using altsetting %d for interface %d config %d \n " ,
altno , iface , chip - > setup ) ;
return 0 ; /* keep this altsetting */
}
2010-03-04 21:46:13 +03:00
static int audiophile_skip_setting_quirk ( struct snd_usb_audio * chip ,
int iface ,
int altno )
{
/* Reset ALL ifaces to 0 altsetting.
* Call it for every possible altsetting of every interface .
*/
usb_set_interface ( chip - > dev , iface , 0 ) ;
2011-07-12 20:13:46 +04:00
if ( chip - > setup & MAUDIO_SET ) {
unsigned int mask ;
if ( ( chip - > setup & MAUDIO_SET_DTS ) & & altno ! = 6 )
2010-03-04 21:46:13 +03:00
return 1 ; /* skip this altsetting */
2011-07-12 20:13:46 +04:00
if ( ( chip - > setup & MAUDIO_SET_96K ) & & altno ! = 1 )
2010-03-04 21:46:13 +03:00
return 1 ; /* skip this altsetting */
2011-07-12 20:13:46 +04:00
mask = chip - > setup & MAUDIO_SET_MASK ;
if ( mask = = MAUDIO_SET_24B_48K_DI & & altno ! = 2 )
2010-03-04 21:46:13 +03:00
return 1 ; /* skip this altsetting */
2011-07-12 20:13:46 +04:00
if ( mask = = MAUDIO_SET_24B_48K_NOTDI & & altno ! = 3 )
2010-03-04 21:46:13 +03:00
return 1 ; /* skip this altsetting */
2011-07-12 20:13:46 +04:00
if ( mask = = MAUDIO_SET_16B_48K_DI & & altno ! = 4 )
2010-03-04 21:46:13 +03:00
return 1 ; /* skip this altsetting */
2011-07-12 20:13:46 +04:00
if ( mask = = MAUDIO_SET_16B_48K_NOTDI & & altno ! = 5 )
2010-03-04 21:46:13 +03:00
return 1 ; /* skip this altsetting */
}
return 0 ; /* keep this altsetting */
}
2011-07-12 20:13:46 +04:00
static int fasttrackpro_skip_setting_quirk ( struct snd_usb_audio * chip ,
int iface , int altno )
{
/* Reset ALL ifaces to 0 altsetting.
* Call it for every possible altsetting of every interface .
*/
usb_set_interface ( chip - > dev , iface , 0 ) ;
/* possible configuration where both inputs and only one output is
* used is not supported by the current setup
*/
if ( chip - > setup & ( MAUDIO_SET | MAUDIO_SET_24B ) ) {
if ( chip - > setup & MAUDIO_SET_96K ) {
if ( altno ! = 3 & & altno ! = 6 )
return 1 ;
} else if ( chip - > setup & MAUDIO_SET_DI ) {
if ( iface = = 4 )
return 1 ; /* no analog input */
if ( altno ! = 2 & & altno ! = 5 )
return 1 ; /* enable only altsets 2 and 5 */
} else {
if ( iface = = 5 )
return 1 ; /* disable digialt input */
if ( altno ! = 2 & & altno ! = 5 )
return 1 ; /* enalbe only altsets 2 and 5 */
}
} else {
/* keep only 16-Bit mode */
if ( altno ! = 1 )
return 1 ;
}
2014-02-26 16:02:17 +04:00
usb_audio_dbg ( chip ,
2011-07-12 20:13:46 +04:00
" using altsetting %d for interface %d config %d \n " ,
altno , iface , chip - > setup ) ;
return 0 ; /* keep this altsetting */
}
2020-02-15 04:23:35 +03:00
static int s1810c_skip_setting_quirk ( struct snd_usb_audio * chip ,
int iface , int altno )
{
/*
* Altno settings :
*
* Playback ( Interface 1 ) :
* 1 : 6 Analog + 2 S / PDIF
* 2 : 6 Analog + 2 S / PDIF
* 3 : 6 Analog
*
* Capture ( Interface 2 ) :
* 1 : 8 Analog + 2 S / PDIF + 8 ADAT
* 2 : 8 Analog + 2 S / PDIF + 4 ADAT
* 3 : 8 Analog
*/
/*
* I ' ll leave 2 as the default one and
* use device_setup to switch to the
* other two .
*/
if ( ( chip - > setup = = 0 | | chip - > setup > 2 ) & & altno ! = 2 )
return 1 ;
else if ( chip - > setup = = 1 & & altno ! = 1 )
return 1 ;
else if ( chip - > setup = = 2 & & altno ! = 3 )
return 1 ;
return 0 ;
}
2010-03-04 21:46:13 +03:00
int snd_usb_apply_interface_quirk ( struct snd_usb_audio * chip ,
int iface ,
int altno )
{
/* audiophile usb: skip altsets incompatible with device_setup */
if ( chip - > usb_id = = USB_ID ( 0x0763 , 0x2003 ) )
return audiophile_skip_setting_quirk ( chip , iface , altno ) ;
2011-07-12 20:13:46 +04:00
/* quattro usb: skip altsets incompatible with device_setup */
if ( chip - > usb_id = = USB_ID ( 0x0763 , 0x2001 ) )
return quattro_skip_setting_quirk ( chip , iface , altno ) ;
/* fasttrackpro usb: skip altsets incompatible with device_setup */
if ( chip - > usb_id = = USB_ID ( 0x0763 , 0x2012 ) )
return fasttrackpro_skip_setting_quirk ( chip , iface , altno ) ;
2020-02-15 04:23:35 +03:00
/* presonus studio 1810c: skip altsets incompatible with device_setup */
if ( chip - > usb_id = = USB_ID ( 0x0194f , 0x010c ) )
return s1810c_skip_setting_quirk ( chip , iface , altno ) ;
2010-03-04 21:46:13 +03:00
return 0 ;
}
int snd_usb_apply_boot_quirk ( struct usb_device * dev ,
struct usb_interface * intf ,
2016-01-11 13:33:34 +03:00
const struct snd_usb_audio_quirk * quirk ,
unsigned int id )
2010-03-04 21:46:13 +03:00
{
2011-02-11 14:34:12 +03:00
switch ( id ) {
case USB_ID ( 0x041e , 0x3000 ) :
/* SB Extigy needs special boot-up sequence */
/* if more models come, this will go to the quirk list. */
2010-03-04 21:46:13 +03:00
return snd_usb_extigy_boot_quirk ( dev , intf ) ;
2011-02-11 14:34:12 +03:00
case USB_ID ( 0x041e , 0x3020 ) :
/* SB Audigy 2 NX needs its own boot-up magic, too */
2010-03-04 21:46:13 +03:00
return snd_usb_audigy2nx_boot_quirk ( dev ) ;
2011-02-11 14:34:12 +03:00
case USB_ID ( 0x10f5 , 0x0200 ) :
/* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
2010-03-04 21:46:13 +03:00
return snd_usb_cm106_boot_quirk ( dev ) ;
2011-02-11 14:34:12 +03:00
case USB_ID ( 0x0d8c , 0x0102 ) :
/* C-Media CM6206 / CM106-Like Sound Device */
2011-04-28 18:18:40 +04:00
case USB_ID ( 0x0ccd , 0x00b1 ) : /* Terratec Aureon 7.1 USB */
2010-03-04 21:46:13 +03:00
return snd_usb_cm6206_boot_quirk ( dev ) ;
2012-12-19 14:27:22 +04:00
case USB_ID ( 0x0dba , 0x3000 ) :
/* Digidesign Mbox 2 */
return snd_usb_mbox2_boot_quirk ( dev ) ;
2013-12-20 12:06:58 +04:00
case USB_ID ( 0x1235 , 0x0010 ) : /* Focusrite Novation Saffire 6 USB */
case USB_ID ( 0x1235 , 0x0018 ) : /* Focusrite Novation Twitch */
return snd_usb_novation_boot_quirk ( dev ) ;
2013-03-17 15:07:53 +04:00
2011-02-11 14:34:12 +03:00
case USB_ID ( 0x133e , 0x0815 ) :
/* Access Music VirusTI Desktop */
2010-03-04 21:46:13 +03:00
return snd_usb_accessmusic_boot_quirk ( dev ) ;
2011-05-18 13:28:41 +04:00
case USB_ID ( 0x17cc , 0x1000 ) : /* Komplete Audio 6 */
2011-02-11 14:34:12 +03:00
case USB_ID ( 0x17cc , 0x1010 ) : /* Traktor Audio 6 */
case USB_ID ( 0x17cc , 0x1020 ) : /* Traktor Audio 10 */
2011-02-11 14:08:06 +03:00
return snd_usb_nativeinstruments_boot_quirk ( dev ) ;
2011-07-12 20:13:46 +04:00
case USB_ID ( 0x0763 , 0x2012 ) : /* M-Audio Fast Track Pro USB */
return snd_usb_fasttrackpro_boot_quirk ( dev ) ;
2013-12-19 17:32:53 +04:00
case USB_ID ( 0x047f , 0xc010 ) : /* Plantronics Gamecom 780 */
return snd_usb_gamecon780_boot_quirk ( dev ) ;
2018-05-09 01:14:13 +03:00
case USB_ID ( 0x2466 , 0x8010 ) : /* Fractal Audio Axe-Fx 3 */
return snd_usb_axefx3_boot_quirk ( dev ) ;
2019-02-28 22:34:04 +03:00
case USB_ID ( 0x07fd , 0x0004 ) : /* MOTU MicroBook II */
2020-02-29 18:18:15 +03:00
/*
* For some reason interface 3 with vendor - spec class is
* detected on MicroBook IIc .
*/
if ( get_iface_desc ( intf - > altsetting ) - > bInterfaceClass = =
USB_CLASS_VENDOR_SPEC & &
get_iface_desc ( intf - > altsetting ) - > bInterfaceNumber < 3 )
return snd_usb_motu_microbookii_boot_quirk ( dev ) ;
break ;
2011-02-11 14:34:12 +03:00
}
2011-02-11 14:08:06 +03:00
2010-03-04 21:46:13 +03:00
return 0 ;
}
2020-01-12 13:23:58 +03:00
int snd_usb_apply_boot_quirk_once ( struct usb_device * dev ,
struct usb_interface * intf ,
const struct snd_usb_audio_quirk * quirk ,
unsigned int id )
{
switch ( id ) {
case USB_ID ( 0x07fd , 0x0008 ) : /* MOTU M Series */
return snd_usb_motu_m_series_boot_quirk ( dev ) ;
}
return 0 ;
}
2010-03-04 21:46:13 +03:00
/*
* check if the device uses big - endian samples
*/
2020-11-23 11:53:33 +03:00
int snd_usb_is_big_endian_format ( struct snd_usb_audio * chip ,
const struct audioformat * fp )
2010-03-04 21:46:13 +03:00
{
2012-09-20 05:48:00 +04:00
/* it depends on altsetting whether the device is big-endian or not */
2010-03-04 21:46:13 +03:00
switch ( chip - > usb_id ) {
case USB_ID ( 0x0763 , 0x2001 ) : /* M-Audio Quattro: captured data only */
2011-07-12 20:13:46 +04:00
if ( fp - > altsetting = = 2 | | fp - > altsetting = = 3 | |
fp - > altsetting = = 5 | | fp - > altsetting = = 6 )
2010-03-04 21:46:13 +03:00
return 1 ;
break ;
case USB_ID ( 0x0763 , 0x2003 ) : /* M-Audio Audiophile USB */
if ( chip - > setup = = 0x00 | |
2011-07-12 20:13:46 +04:00
fp - > altsetting = = 1 | | fp - > altsetting = = 2 | |
fp - > altsetting = = 3 )
return 1 ;
break ;
case USB_ID ( 0x0763 , 0x2012 ) : /* M-Audio Fast Track Pro */
if ( fp - > altsetting = = 2 | | fp - > altsetting = = 3 | |
fp - > altsetting = = 5 | | fp - > altsetting = = 6 )
2010-03-04 21:46:13 +03:00
return 1 ;
2011-07-12 20:13:46 +04:00
break ;
2010-03-04 21:46:13 +03:00
}
return 0 ;
}
/*
2011-02-08 09:22:36 +03:00
* For E - Mu 0404U SB / 0202U SB / TrackerPre / 0204 sample rate should be set for device ,
2010-03-04 21:46:13 +03:00
* not for interface .
*/
enum {
EMU_QUIRK_SR_44100HZ = 0 ,
EMU_QUIRK_SR_48000HZ ,
EMU_QUIRK_SR_88200HZ ,
EMU_QUIRK_SR_96000HZ ,
EMU_QUIRK_SR_176400HZ ,
EMU_QUIRK_SR_192000HZ
} ;
static void set_format_emu_quirk ( struct snd_usb_substream * subs ,
2020-11-23 11:53:33 +03:00
const struct audioformat * fmt )
2010-03-04 21:46:13 +03:00
{
unsigned char emu_samplerate_id = 0 ;
/* When capture is active
* sample rate shouldn ' t be changed
* by playback substream
*/
if ( subs - > direction = = SNDRV_PCM_STREAM_PLAYBACK ) {
2020-11-23 11:53:36 +03:00
if ( subs - > stream - > substream [ SNDRV_PCM_STREAM_CAPTURE ] . cur_audiofmt )
2010-03-04 21:46:13 +03:00
return ;
}
switch ( fmt - > rate_min ) {
case 48000 :
emu_samplerate_id = EMU_QUIRK_SR_48000HZ ;
break ;
case 88200 :
emu_samplerate_id = EMU_QUIRK_SR_88200HZ ;
break ;
case 96000 :
emu_samplerate_id = EMU_QUIRK_SR_96000HZ ;
break ;
case 176400 :
emu_samplerate_id = EMU_QUIRK_SR_176400HZ ;
break ;
case 192000 :
emu_samplerate_id = EMU_QUIRK_SR_192000HZ ;
break ;
default :
emu_samplerate_id = EMU_QUIRK_SR_44100HZ ;
break ;
}
snd_emuusb_set_samplerate ( subs - > stream - > chip , emu_samplerate_id ) ;
2013-04-13 07:33:59 +04:00
subs - > pkt_offset_adj = ( emu_samplerate_id > = EMU_QUIRK_SR_176400HZ ) ? 4 : 0 ;
2010-03-04 21:46:13 +03:00
}
2021-02-02 16:42:26 +03:00
static int pioneer_djm_set_format_quirk ( struct snd_usb_substream * subs ,
u16 windex )
{
unsigned int cur_rate = subs - > data_endpoint - > cur_rate ;
u8 sr [ 3 ] ;
// Convert to little endian
sr [ 0 ] = cur_rate & 0xff ;
sr [ 1 ] = ( cur_rate > > 8 ) & 0xff ;
sr [ 2 ] = ( cur_rate > > 16 ) & 0xff ;
usb_set_interface ( subs - > dev , 0 , 1 ) ;
// we should derive windex from fmt-sync_ep but it's not set
snd_usb_ctl_msg ( subs - > stream - > chip - > dev ,
2021-03-01 17:29:27 +03:00
usb_sndctrlpipe ( subs - > stream - > chip - > dev , 0 ) ,
2021-02-02 16:42:26 +03:00
0x01 , 0x22 , 0x0100 , windex , & sr , 0x0003 ) ;
return 0 ;
}
2010-03-04 21:46:13 +03:00
void snd_usb_set_format_quirk ( struct snd_usb_substream * subs ,
2020-11-23 11:53:33 +03:00
const struct audioformat * fmt )
2010-03-04 21:46:13 +03:00
{
switch ( subs - > stream - > chip - > usb_id ) {
case USB_ID ( 0x041e , 0x3f02 ) : /* E-Mu 0202 USB */
case USB_ID ( 0x041e , 0x3f04 ) : /* E-Mu 0404 USB */
case USB_ID ( 0x041e , 0x3f0a ) : /* E-Mu Tracker Pre */
2011-02-08 09:22:36 +03:00
case USB_ID ( 0x041e , 0x3f19 ) : /* E-Mu 0204 USB */
2010-03-04 21:46:13 +03:00
set_format_emu_quirk ( subs , fmt ) ;
break ;
2020-08-10 11:24:00 +03:00
case USB_ID ( 0x534d , 0x2109 ) : /* MacroSilicon MS2109 */
subs - > stream_offset_adj = 2 ;
break ;
2021-02-02 16:42:26 +03:00
case USB_ID ( 0x2b73 , 0x0013 ) : /* Pioneer DJM-450 */
pioneer_djm_set_format_quirk ( subs , 0x0082 ) ;
break ;
2021-04-18 19:59:01 +03:00
case USB_ID ( 0x08e4 , 0x017f ) : /* Pioneer DJM-750 */
2021-03-01 18:27:28 +03:00
case USB_ID ( 0x08e4 , 0x0163 ) : /* Pioneer DJM-850 */
pioneer_djm_set_format_quirk ( subs , 0x0086 ) ;
break ;
2010-03-04 21:46:13 +03:00
}
}
2020-11-23 11:53:24 +03:00
int snd_usb_select_mode_quirk ( struct snd_usb_audio * chip ,
2020-11-23 11:53:33 +03:00
const struct audioformat * fmt )
2014-11-28 19:32:54 +03:00
{
2020-11-23 11:53:24 +03:00
struct usb_device * dev = chip - > dev ;
2014-11-28 19:32:54 +03:00
int err ;
2021-07-29 10:38:53 +03:00
if ( chip - > quirk_flags & QUIRK_FLAG_ITF_USB_DSD_DAC ) {
2014-11-28 19:32:54 +03:00
/* First switch to alt set 0, otherwise the mode switch cmd
* will not be accepted by the DAC
*/
err = usb_set_interface ( dev , fmt - > iface , 0 ) ;
if ( err < 0 )
return err ;
2018-07-27 11:55:28 +03:00
msleep ( 20 ) ; /* Delay needed after setting the interface */
2014-11-28 19:32:54 +03:00
2016-12-12 19:24:08 +03:00
/* Vendor mode switch cmd is required. */
2018-03-23 13:21:13 +03:00
if ( fmt - > formats & SNDRV_PCM_FMTBIT_DSD_U32_BE ) {
/* DSD mode (DSD_U32) requested */
2016-12-12 19:24:08 +03:00
err = snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) , 0 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
1 , 1 , NULL , 0 ) ;
if ( err < 0 )
return err ;
2018-03-23 13:21:13 +03:00
} else {
/* PCM or DOP mode (S32) requested */
/* PCM mode (S16) requested */
2016-12-12 19:24:08 +03:00
err = snd_usb_ctl_msg ( dev , usb_sndctrlpipe ( dev , 0 ) , 0 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
0 , 1 , NULL , 0 ) ;
if ( err < 0 )
return err ;
2018-03-23 13:21:13 +03:00
2016-12-12 19:24:08 +03:00
}
2018-07-27 11:55:28 +03:00
msleep ( 20 ) ;
2014-11-28 19:32:54 +03:00
}
return 0 ;
}
2012-09-04 12:23:07 +04:00
void snd_usb_endpoint_start_quirk ( struct snd_usb_endpoint * ep )
{
/*
* " Playback Design " products send bogus feedback data at the start
* of the stream . Ignore them .
*/
2016-01-11 13:33:34 +03:00
if ( USB_ID_VENDOR ( ep - > chip - > usb_id ) = = 0x23ba & &
2012-09-04 12:23:07 +04:00
ep - > type = = SND_USB_ENDPOINT_TYPE_SYNC )
ep - > skip_packets = 4 ;
2013-01-14 02:02:03 +04:00
/*
2013-02-09 21:56:35 +04:00
* M - Audio Fast Track C400 / C600 - when packets are not skipped , real
2020-06-29 06:26:07 +03:00
* world latency varies by approx . + / - 50 frames ( at 96 kHz ) each time
2013-02-09 21:56:35 +04:00
* the stream is ( re ) started . When skipping packets 16 at endpoint
* start up , the real world latency is stable within + / - 1 frame ( also
2013-01-14 02:02:03 +04:00
* across power cycles ) .
*/
2013-02-09 21:56:35 +04:00
if ( ( ep - > chip - > usb_id = = USB_ID ( 0x0763 , 0x2030 ) | |
ep - > chip - > usb_id = = USB_ID ( 0x0763 , 0x2031 ) ) & &
2013-01-14 02:02:03 +04:00
ep - > type = = SND_USB_ENDPOINT_TYPE_DATA )
ep - > skip_packets = 16 ;
2016-08-22 09:53:36 +03:00
/* Work around devices that report unreasonable feedback data */
2016-08-22 09:53:37 +03:00
if ( ( ep - > chip - > usb_id = = USB_ID ( 0x0644 , 0x8038 ) | | /* TEAC UD-H01 */
ep - > chip - > usb_id = = USB_ID ( 0x1852 , 0x5034 ) ) & & /* T+A Dac8 */
2016-08-22 09:53:36 +03:00
ep - > syncmaxsize = = 4 )
2016-08-22 09:53:37 +03:00
ep - > tenor_fb_quirk = 1 ;
2012-09-04 12:23:07 +04:00
}
2016-01-11 13:33:34 +03:00
/* quirk applied after snd_usb_ctl_msg(); not applied during boot quirks */
2012-09-04 12:23:07 +04:00
void snd_usb_ctl_msg_quirk ( struct usb_device * dev , unsigned int pipe ,
__u8 request , __u8 requesttype , __u16 value ,
__u16 index , void * data , __u16 size )
{
2016-01-11 13:33:34 +03:00
struct snd_usb_audio * chip = dev_get_drvdata ( & dev - > dev ) ;
2021-07-29 10:38:54 +03:00
if ( ! chip | | ( requesttype & USB_TYPE_MASK ) ! = USB_TYPE_CLASS )
2016-01-11 13:33:34 +03:00
return ;
2014-11-15 16:01:21 +03:00
2021-07-29 10:38:54 +03:00
if ( chip - > quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY )
2018-07-27 11:55:28 +03:00
msleep ( 20 ) ;
2021-07-29 10:38:54 +03:00
else if ( chip - > quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY_1M )
2018-07-27 11:55:28 +03:00
usleep_range ( 1000 , 2000 ) ;
2021-07-29 10:38:54 +03:00
else if ( chip - > quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY_5M )
2020-06-23 14:03:23 +03:00
usleep_range ( 5000 , 6000 ) ;
2012-09-04 12:23:07 +04:00
}
2013-04-16 20:01:40 +04:00
/*
* snd_usb_interface_dsd_format_quirks ( ) is called from format . c to
* augment the PCM format bit - field for DSD types . The UAC standards
* don ' t have a designated bit field to denote DSD - capable interfaces ,
* hence all hardware that is known to support this format has to be
* listed here .
*/
u64 snd_usb_interface_dsd_format_quirks ( struct snd_usb_audio * chip ,
struct audioformat * fp ,
unsigned int sample_bytes )
{
2018-03-23 13:21:13 +03:00
struct usb_interface * iface ;
2013-04-16 20:01:40 +04:00
/* Playback Designs */
2019-08-28 00:08:46 +03:00
if ( USB_ID_VENDOR ( chip - > usb_id ) = = 0x23ba & &
USB_ID_PRODUCT ( chip - > usb_id ) < 0x0110 ) {
2013-04-16 20:01:40 +04:00
switch ( fp - > altsetting ) {
case 1 :
fp - > dsd_dop = true ;
return SNDRV_PCM_FMTBIT_DSD_U16_LE ;
case 2 :
fp - > dsd_bitrev = true ;
return SNDRV_PCM_FMTBIT_DSD_U8 ;
case 3 :
fp - > dsd_bitrev = true ;
return SNDRV_PCM_FMTBIT_DSD_U16_LE ;
}
}
2014-09-05 20:14:46 +04:00
/* XMOS based USB DACs */
switch ( chip - > usb_id ) {
2018-04-20 23:29:41 +03:00
case USB_ID ( 0x1511 , 0x0037 ) : /* AURALiC VEGA */
case USB_ID ( 0x2522 , 0x0012 ) : /* LH Labs VI DAC Infinity */
2017-10-15 12:41:32 +03:00
case USB_ID ( 0x2772 , 0x0230 ) : /* Pro-Ject Pre Box S2 Digital */
2014-09-05 20:14:46 +04:00
if ( fp - > altsetting = = 2 )
2014-11-21 17:04:46 +03:00
return SNDRV_PCM_FMTBIT_DSD_U32_BE ;
2014-09-05 20:14:46 +04:00
break ;
2015-06-05 10:42:49 +03:00
2018-04-20 23:29:41 +03:00
case USB_ID ( 0x0d8c , 0x0316 ) : /* Hegel HD12 DSD */
2019-01-29 01:47:01 +03:00
case USB_ID ( 0x10cb , 0x0103 ) : /* The Bit Opus #3 ; with fp - > dsd_raw */
2020-04-30 15:47:55 +03:00
case USB_ID ( 0x16d0 , 0x06b2 ) : /* NuPrime DAC-10 */
2019-01-29 01:47:01 +03:00
case USB_ID ( 0x16d0 , 0x09dd ) : /* Encore mDSD */
2018-04-20 23:29:41 +03:00
case USB_ID ( 0x16d0 , 0x0733 ) : /* Furutech ADL Stratos */
case USB_ID ( 0x16d0 , 0x09db ) : /* NuPrime Audio DAC-9 */
case USB_ID ( 0x1db5 , 0x0003 ) : /* Bryston BDA3 */
case USB_ID ( 0x22e1 , 0xca01 ) : /* HDTA Serenade DSD */
case USB_ID ( 0x249c , 0x9326 ) : /* M2Tech Young MkIII */
2016-01-29 16:59:25 +03:00
case USB_ID ( 0x2616 , 0x0106 ) : /* PS Audio NuWave DAC */
2018-04-20 23:29:41 +03:00
case USB_ID ( 0x2622 , 0x0041 ) : /* Audiolab M-DAC+ */
case USB_ID ( 0x27f7 , 0x3002 ) : /* W4S DAC-2v2SE */
case USB_ID ( 0x29a2 , 0x0086 ) : /* Mutec MC3+ USB */
case USB_ID ( 0x6b42 , 0x0042 ) : /* MSB Technology */
2014-09-05 20:14:46 +04:00
if ( fp - > altsetting = = 3 )
2014-11-21 17:04:46 +03:00
return SNDRV_PCM_FMTBIT_DSD_U32_BE ;
2014-09-05 20:14:46 +04:00
break ;
2016-12-18 00:51:41 +03:00
2018-02-11 16:50:27 +03:00
/* Amanero Combo384 USB based DACs with native DSD support */
case USB_ID ( 0x16d0 , 0x071a ) : /* Amanero - Combo384 */
case USB_ID ( 0x2ab6 , 0x0004 ) : /* T+A DAC8DSD-V2.0, MP1000E-V2.0, MP2000R-V2.0, MP2500R-V2.0, MP3100HV-V2.0 */
case USB_ID ( 0x2ab6 , 0x0005 ) : /* T+A USB HD Audio 1 */
case USB_ID ( 0x2ab6 , 0x0006 ) : /* T+A USB HD Audio 2 */
2016-12-18 00:51:41 +03:00
if ( fp - > altsetting = = 2 ) {
2017-05-12 15:34:37 +03:00
switch ( le16_to_cpu ( chip - > dev - > descriptor . bcdDevice ) ) {
2016-12-18 00:51:41 +03:00
case 0x199 :
return SNDRV_PCM_FMTBIT_DSD_U32_LE ;
case 0x19b :
2017-11-02 00:32:33 +03:00
case 0x203 :
2016-12-18 00:51:41 +03:00
return SNDRV_PCM_FMTBIT_DSD_U32_BE ;
default :
break ;
}
}
break ;
2017-08-18 10:42:14 +03:00
case USB_ID ( 0x16d0 , 0x0a23 ) :
if ( fp - > altsetting = = 2 )
return SNDRV_PCM_FMTBIT_DSD_U32_BE ;
break ;
2016-12-18 00:51:41 +03:00
2014-09-05 20:14:46 +04:00
default :
break ;
}
2018-03-23 13:21:13 +03:00
/* ITF-USB DSD based DACs */
2021-07-29 10:38:53 +03:00
if ( chip - > quirk_flags & QUIRK_FLAG_ITF_USB_DSD_DAC ) {
2018-03-23 13:21:13 +03:00
iface = usb_ifnum_to_if ( chip - > dev , fp - > iface ) ;
2014-11-28 19:32:53 +03:00
2018-03-23 13:21:13 +03:00
/* Altsetting 2 support native DSD if the num of altsets is
* three ( 0 - 2 ) ,
* Altsetting 3 support native DSD if the num of altsets is
* four ( 0 - 3 ) .
*/
if ( fp - > altsetting = = iface - > num_altsetting - 1 )
2016-12-12 19:24:08 +03:00
return SNDRV_PCM_FMTBIT_DSD_U32_BE ;
}
2021-07-29 10:44:02 +03:00
/* Mostly generic method to detect many DSD-capable implementations */
if ( ( chip - > quirk_flags & QUIRK_FLAG_DSD_RAW ) & & fp - > dsd_raw )
return SNDRV_PCM_FMTBIT_DSD_U32_BE ;
2018-06-13 01:43:01 +03:00
2013-04-16 20:01:40 +04:00
return 0 ;
}
2018-03-19 04:46:02 +03:00
void snd_usb_audioformat_attributes_quirk ( struct snd_usb_audio * chip ,
struct audioformat * fp ,
int stream )
{
switch ( chip - > usb_id ) {
case USB_ID ( 0x0a92 , 0x0053 ) : /* AudioTrak Optoplay */
/* Optoplay sets the sample rate attribute although
* it seems not supporting it in fact .
*/
fp - > attributes & = ~ UAC_EP_CS_ATTR_SAMPLE_RATE ;
break ;
case USB_ID ( 0x041e , 0x3020 ) : /* Creative SB Audigy 2 NX */
case USB_ID ( 0x0763 , 0x2003 ) : /* M-Audio Audiophile USB */
/* doesn't set the sample rate attribute, but supports it */
fp - > attributes | = UAC_EP_CS_ATTR_SAMPLE_RATE ;
break ;
case USB_ID ( 0x0763 , 0x2001 ) : /* M-Audio Quattro USB */
case USB_ID ( 0x0763 , 0x2012 ) : /* M-Audio Fast Track Pro USB */
case USB_ID ( 0x047f , 0x0ca1 ) : /* plantronics headset */
case USB_ID ( 0x077d , 0x07af ) : /* Griffin iMic (note that there is
an older model 77 d : 223 ) */
/*
* plantronics headset and Griffin iMic have set adaptive - in
* although it ' s really not . . .
*/
fp - > ep_attr & = ~ USB_ENDPOINT_SYNCTYPE ;
if ( stream = = SNDRV_PCM_STREAM_PLAYBACK )
fp - > ep_attr | = USB_ENDPOINT_SYNC_ADAPTIVE ;
else
fp - > ep_attr | = USB_ENDPOINT_SYNC_SYNC ;
break ;
2020-02-29 18:18:15 +03:00
case USB_ID ( 0x07fd , 0x0004 ) : /* MOTU MicroBook IIc */
/*
* MaxPacketsOnly attribute is erroneously set in endpoint
* descriptors . As a result this card produces noise with
2020-06-29 06:26:07 +03:00
* all sample rates other than 96 kHz .
2020-02-29 18:18:15 +03:00
*/
fp - > attributes & = ~ UAC_EP_CS_ATTR_FILL_MAX ;
break ;
2021-10-18 19:25:52 +03:00
case USB_ID ( 0x1224 , 0x2a25 ) : /* Jieli Technology USB PHY 2.0 */
/* mic works only when ep packet size is set to wMaxPacketSize */
fp - > attributes | = UAC_EP_CS_ATTR_FILL_MAX ;
break ;
2018-03-19 04:46:02 +03:00
}
}
2020-03-14 19:54:49 +03:00
2020-03-25 13:33:19 +03:00
/*
* registration quirk :
* the registration is skipped if a device matches with the given ID ,
* unless the interface reaches to the defined one . This is for delaying
* the registration until the last known interface , so that the card and
* devices appear at the same time .
*/
struct registration_quirk {
unsigned int usb_id ; /* composed via USB_ID() */
unsigned int interface ; /* the interface to trigger register */
} ;
# define REG_QUIRK_ENTRY(vendor, product, iface) \
{ . usb_id = USB_ID ( vendor , product ) , . interface = ( iface ) }
static const struct registration_quirk registration_quirks [ ] = {
REG_QUIRK_ENTRY ( 0x0951 , 0x16d8 , 2 ) , /* Kingston HyperX AMP */
2020-04-04 18:38:43 +03:00
REG_QUIRK_ENTRY ( 0x0951 , 0x16ed , 2 ) , /* Kingston HyperX Cloud Alpha S */
2020-06-19 14:48:22 +03:00
REG_QUIRK_ENTRY ( 0x0951 , 0x16ea , 2 ) , /* Kingston HyperX Cloud Flight S */
2021-07-22 02:56:05 +03:00
REG_QUIRK_ENTRY ( 0x0ecb , 0x1f46 , 2 ) , /* JBL Quantum 600 */
2021-08-31 03:25:31 +03:00
REG_QUIRK_ENTRY ( 0x0ecb , 0x1f47 , 2 ) , /* JBL Quantum 800 */
2021-10-30 20:43:08 +03:00
REG_QUIRK_ENTRY ( 0x0ecb , 0x1f4c , 2 ) , /* JBL Quantum 400 */
2021-07-22 02:56:05 +03:00
REG_QUIRK_ENTRY ( 0x0ecb , 0x2039 , 2 ) , /* JBL Quantum 400 */
2021-07-27 12:33:26 +03:00
REG_QUIRK_ENTRY ( 0x0ecb , 0x203c , 2 ) , /* JBL Quantum 600 */
2021-07-22 02:56:05 +03:00
REG_QUIRK_ENTRY ( 0x0ecb , 0x203e , 2 ) , /* JBL Quantum 800 */
2020-03-25 13:33:19 +03:00
{ 0 } /* terminator */
} ;
/* return true if skipping registration */
bool snd_usb_registration_quirk ( struct snd_usb_audio * chip , int iface )
2020-03-14 19:54:49 +03:00
{
2020-03-25 13:33:19 +03:00
const struct registration_quirk * q ;
for ( q = registration_quirks ; q - > usb_id ; q + + )
if ( chip - > usb_id = = q - > usb_id )
return iface ! = q - > interface ;
2020-03-14 19:54:49 +03:00
/* Register as normal */
2020-03-25 13:33:19 +03:00
return false ;
2020-03-14 19:54:49 +03:00
}
2021-07-29 10:38:47 +03:00
/*
* driver behavior quirk flags
*/
struct usb_audio_quirk_flags_table {
u32 id ;
u32 flags ;
} ;
# define DEVICE_FLG(vid, pid, _flags) \
{ . id = USB_ID ( vid , pid ) , . flags = ( _flags ) }
# define VENDOR_FLG(vid, _flags) DEVICE_FLG(vid, 0, _flags)
static const struct usb_audio_quirk_flags_table quirk_flags_table [ ] = {
/* Device matches */
2021-07-29 10:44:01 +03:00
DEVICE_FLG ( 0x041e , 0x3000 , /* Creative SB Extigy */
QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x041e , 0x4080 , /* Creative Live Cam VF0610 */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
DEVICE_FLG ( 0x046d , 0x084c , /* Logitech ConferenceCam Connect */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY_1M ) ,
2021-07-29 10:44:01 +03:00
DEVICE_FLG ( 0x046d , 0x0991 , /* Logitech QuickCam Pro */
QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
DEVICE_FLG ( 0x046d , 0x09a4 , /* Logitech QuickCam E 3500 */
QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x04d8 , 0xfeea , /* Benchmark DAC1 Pre */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:38:52 +03:00
DEVICE_FLG ( 0x04e8 , 0xa051 , /* Samsung USBC Headset (AKG) */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_SKIP_CLOCK_SELECTOR | QUIRK_FLAG_CTL_MSG_DELAY_5M ) ,
2021-08-24 08:57:20 +03:00
DEVICE_FLG ( 0x054c , 0x0b8c , /* Sony WALKMAN NW-A45 DAC */
QUIRK_FLAG_SET_IFACE_FIRST ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x0556 , 0x0014 , /* Phoenix Audio TMX320VC */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
DEVICE_FLG ( 0x05a3 , 0x9420 , /* ELP HD USB Camera */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
DEVICE_FLG ( 0x05a7 , 0x1020 , /* Bose Companion 5 */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:38:49 +03:00
DEVICE_FLG ( 0x05e1 , 0x0408 , /* Syntek STK1160 */
QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x05e1 , 0x0480 , /* Hauppauge Woodbury */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:53 +03:00
DEVICE_FLG ( 0x0644 , 0x8043 , /* TEAC UD-501/UD-501V2/UD-503/NT-503 */
2021-07-29 10:38:55 +03:00
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
QUIRK_FLAG_IFACE_DELAY ) ,
2021-07-29 10:38:53 +03:00
DEVICE_FLG ( 0x0644 , 0x8044 , /* Esoteric D-05X */
2021-07-29 10:38:55 +03:00
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
QUIRK_FLAG_IFACE_DELAY ) ,
2021-07-29 10:38:53 +03:00
DEVICE_FLG ( 0x0644 , 0x804a , /* TEAC UD-301 */
2021-07-29 10:38:55 +03:00
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
QUIRK_FLAG_IFACE_DELAY ) ,
2021-07-29 10:44:01 +03:00
DEVICE_FLG ( 0x06f8 , 0xb000 , /* Hercules DJ Console (Windows Edition) */
QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
DEVICE_FLG ( 0x06f8 , 0xd002 , /* Hercules DJ Console (Macintosh Edition) */
QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x074d , 0x3553 , /* Outlaw RR2150 (Micronas UAC3553B) */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:44:01 +03:00
DEVICE_FLG ( 0x08bb , 0x2702 , /* LineX FM Transmitter */
QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
2021-07-29 10:38:54 +03:00
DEVICE_FLG ( 0x0951 , 0x16ad , /* Kingston HyperX */
QUIRK_FLAG_CTL_MSG_DELAY_1M ) ,
DEVICE_FLG ( 0x0b0e , 0x0349 , /* Jabra 550a */
QUIRK_FLAG_CTL_MSG_DELAY_1M ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x0fd9 , 0x0008 , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x1395 , 0x740a , /* Sennheiser DECT */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:44:01 +03:00
DEVICE_FLG ( 0x13e5 , 0x0001 , /* Serato Phono */
QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
2021-07-29 10:38:53 +03:00
DEVICE_FLG ( 0x154e , 0x1002 , /* Denon DCD-1500RE */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY ) ,
2021-07-29 10:38:53 +03:00
DEVICE_FLG ( 0x154e , 0x1003 , /* Denon DA-300USB */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY ) ,
2021-07-29 10:38:53 +03:00
DEVICE_FLG ( 0x154e , 0x3005 , /* Marantz HD-DAC1 */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY ) ,
2021-07-29 10:38:53 +03:00
DEVICE_FLG ( 0x154e , 0x3006 , /* Marantz SA-14S1 */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY ) ,
2021-07-29 10:38:52 +03:00
DEVICE_FLG ( 0x154e , 0x500e , /* Denon DN-X1600 */
QUIRK_FLAG_IGNORE_CLOCK_SOURCE ) ,
2021-07-29 10:38:50 +03:00
DEVICE_FLG ( 0x1686 , 0x00dd , /* Zoom R16/24 */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_TX_LENGTH | QUIRK_FLAG_CTL_MSG_DELAY_1M ) ,
2021-07-29 10:44:00 +03:00
DEVICE_FLG ( 0x17aa , 0x1046 , /* Lenovo ThinkStation P620 Rear Line-in, Line-out and Microphone */
QUIRK_FLAG_DISABLE_AUTOSUSPEND ) ,
DEVICE_FLG ( 0x17aa , 0x104d , /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */
QUIRK_FLAG_DISABLE_AUTOSUSPEND ) ,
2021-07-29 10:38:53 +03:00
DEVICE_FLG ( 0x1852 , 0x5065 , /* Luxman DA-06 */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x1901 , 0x0191 , /* GE B850V3 CP2114 audio interface */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7200 , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7201 , /* Hauppauge HVR-950Q-MXL */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7210 , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7211 , /* Hauppauge HVR-950Q-MXL */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7213 , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7217 , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x721b , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x721e , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x721f , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7240 , /* Hauppauge HVR-850 */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7260 , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7270 , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7280 , /* Hauppauge HVR-950Q */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x7281 , /* Hauppauge HVR-950Q-MXL */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:48 +03:00
DEVICE_FLG ( 0x2040 , 0x8200 , /* Hauppauge Woodbury */
2021-07-29 10:38:49 +03:00
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x21b4 , 0x0081 , /* AudioQuest DragonFly */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-11-02 19:18:59 +03:00
DEVICE_FLG ( 0x2708 , 0x0002 , /* Audient iD14 */
QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x2912 , 0x30c8 , /* Audioengine D1 */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
ALSA: usb-audio: add Schiit Hel device to quirk table
The Shciit Hel device responds to the ctl message for the mic capture
switch with a timeout of -EPIPE:
usb 7-2.2: cannot get ctl value: req = 0x81, wValue = 0x100, wIndex = 0x1100, type = 1
usb 7-2.2: cannot get ctl value: req = 0x81, wValue = 0x100, wIndex = 0x1100, type = 1
usb 7-2.2: cannot get ctl value: req = 0x81, wValue = 0x100, wIndex = 0x1100, type = 1
usb 7-2.2: cannot get ctl value: req = 0x81, wValue = 0x100, wIndex = 0x1100, type = 1
This seems safe to ignore as the device works properly with the control
message quirk, so add it to the quirk table so all is good.
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: alsa-devel@alsa-project.org
Cc: linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://lore.kernel.org/r/YWgR3nOI1osvr5Yo@kroah.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2021-10-14 14:17:50 +03:00
DEVICE_FLG ( 0x30be , 0x0101 , /* Schiit Hel */
QUIRK_FLAG_IGNORE_CTL_ERROR ) ,
2021-07-29 10:38:47 +03:00
DEVICE_FLG ( 0x413c , 0xa506 , /* Dell AE515 sound bar */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:38:49 +03:00
DEVICE_FLG ( 0x534d , 0x2109 , /* MacroSilicon MS2109 */
QUIRK_FLAG_ALIGN_TRANSFER ) ,
2021-10-18 19:25:52 +03:00
DEVICE_FLG ( 0x1224 , 0x2a25 , /* Jieli Technology USB PHY 2.0 */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:38:47 +03:00
/* Vendor matches */
VENDOR_FLG ( 0x045e , /* MS Lifecam */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:38:54 +03:00
VENDOR_FLG ( 0x046d , /* Logitech */
QUIRK_FLAG_CTL_MSG_DELAY_1M ) ,
2021-07-29 10:38:47 +03:00
VENDOR_FLG ( 0x047f , /* Plantronics */
2021-07-29 10:38:54 +03:00
QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY ) ,
VENDOR_FLG ( 0x0644 , /* TEAC Corp. */
2021-07-29 10:38:55 +03:00
QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY ) ,
2021-07-29 10:43:59 +03:00
VENDOR_FLG ( 0x07fd , /* MOTU */
QUIRK_FLAG_VALIDATE_RATES ) ,
2021-10-04 10:40:50 +03:00
VENDOR_FLG ( 0x1235 , /* Focusrite Novation */
QUIRK_FLAG_VALIDATE_RATES ) ,
2021-07-29 10:44:02 +03:00
VENDOR_FLG ( 0x152a , /* Thesycon devices */
QUIRK_FLAG_DSD_RAW ) ,
2021-07-29 10:38:47 +03:00
VENDOR_FLG ( 0x1de7 , /* Phoenix Audio */
QUIRK_FLAG_GET_SAMPLE_RATE ) ,
2021-07-29 10:44:02 +03:00
VENDOR_FLG ( 0x20b1 , /* XMOS based devices */
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0x22d9 , /* Oppo */
QUIRK_FLAG_DSD_RAW ) ,
2021-07-29 10:38:54 +03:00
VENDOR_FLG ( 0x23ba , /* Playback Design */
2021-07-29 10:44:02 +03:00
QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY |
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0x25ce , /* Mytek devices */
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0x278b , /* Rotel? */
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0x292b , /* Gustard/Ess based devices */
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0x2972 , /* FiiO devices */
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0x2ab6 , /* T+A devices */
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0x3353 , /* Khadas devices */
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0x3842 , /* EVGA */
QUIRK_FLAG_DSD_RAW ) ,
VENDOR_FLG ( 0xc502 , /* HiBy devices */
QUIRK_FLAG_DSD_RAW ) ,
2021-07-29 10:38:47 +03:00
{ } /* terminator */
} ;
void snd_usb_init_quirk_flags ( struct snd_usb_audio * chip )
{
const struct usb_audio_quirk_flags_table * p ;
for ( p = quirk_flags_table ; p - > id ; p + + ) {
if ( chip - > usb_id = = p - > id | |
( ! USB_ID_PRODUCT ( p - > id ) & &
USB_ID_VENDOR ( chip - > usb_id ) = = USB_ID_VENDOR ( p - > id ) ) ) {
usb_audio_dbg ( chip ,
" Set quirk_flags 0x%x for device %04x:%04x \n " ,
p - > flags , USB_ID_VENDOR ( chip - > usb_id ) ,
USB_ID_PRODUCT ( chip - > usb_id ) ) ;
chip - > quirk_flags | = p - > flags ;
return ;
}
}
}