diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 16:52:13 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-20 16:52:13 +0100 |
commit | 03c850ec327c42a97e44c448b75983e12da417d9 (patch) | |
tree | d5fe304ba4b0639b331ffe689b5aff7c524cb4da /sound/usb/quirks.c | |
parent | Merge tag 'upstream-3.8-rc1' of git://git.infradead.org/linux-ubi (diff) | |
parent | ALSA: usb-audio: Support for Digidesign Mbox 2 USB sound card: (diff) | |
download | linux-03c850ec327c42a97e44c448b75983e12da417d9.tar.xz linux-03c850ec327c42a97e44c448b75983e12da417d9.zip |
Merge tag 'sound-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"This update contains overall only driver-specific fixes. Slightly
large LOC are seen in usb-audio driver for a couple of new device
quirks and cs42l71 ASoC driver for enhanced features. The others are
a few small (regression) fixes HD-audio, and yet other small / trival
ASoC fixes."
* tag 'sound-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: usb-audio: Support for Digidesign Mbox 2 USB sound card:
ALSA: HDA: Fix sound resume hang
ALSA: hda - bug fix for invalid connection list of Haswell HDMI codec pins
ALSA: hda - Fix the wrong pincaps set in ALC861VD dallas/hp fixup
ALSA: hda - Set codec->single_adc_amp flag for Realtek codecs
ASoC: atmel-ssc: change disable to disable in dts node
ASoC: Prevent pop_wait overwrite
ALSA: usb-audio: ignore-quirk for HP Wireless Audio
ALSA: hda - Always turn on pins for HDMI/DP
ALSA: hda - Fix pin configuration of HP Pavilion dv7
ASoC: core: Fix splitting of log messages
ASoC: cs42l73: Change VSPIN/VSPOUT to VSPINOUT
ASoC: cs42l73: Add DAPM events for power down.
ASoC: cs42l73: Add DMIC's as DAPM inputs.
ASoC: sigmadsp: Fix endianness conversion issue
ASoC: tpa6130a2: Use devm_* APIs
Diffstat (limited to 'sound/usb/quirks.c')
-rw-r--r-- | sound/usb/quirks.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 007fcecdf5cd..f104c68fe1e0 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -306,6 +306,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk, [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk, [QUIRK_MIDI_NOVATION] = create_any_midi_quirk, + [QUIRK_MIDI_MBOX2] = create_any_midi_quirk, [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk, [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, [QUIRK_MIDI_CME] = create_any_midi_quirk, @@ -497,6 +498,92 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev) return -EAGAIN; } +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 */ + +int snd_usb_mbox2_boot_quirk(struct usb_device *dev) +{ + struct usb_host_config *config = dev->actconfig; + int err; + u8 bootresponse; + int fwsize; + int count; + + fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength); + + if (fwsize != MBOX2_FIRMWARE_SIZE) { + snd_printk(KERN_ERR "usb-audio: Invalid firmware size=%d.\n", fwsize); + return -ENODEV; + } + + snd_printd("usb-audio: Sending Digidesign Mbox 2 boot sequence...\n"); + + count = 0; + bootresponse = MBOX2_BOOT_LOADING; + while ((bootresponse == MBOX2_BOOT_LOADING) && (count < 10)) { + 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); + if (bootresponse == MBOX2_BOOT_READY) + break; + snd_printd("usb-audio: device not ready, resending boot sequence...\n"); + count++; + } + + if (bootresponse != MBOX2_BOOT_READY) { + snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse); + return -ENODEV; + } + + snd_printdd("usb-audio: device initialised!\n"); + + err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, + &dev->descriptor, sizeof(dev->descriptor)); + config = dev->actconfig; + if (err < 0) + snd_printd("error usb_get_descriptor: %d\n", err); + + err = usb_reset_configuration(dev); + if (err < 0) + snd_printd("error usb_reset_configuration: %d\n", err); + snd_printdd("mbox2_boot: new boot length = %d\n", + le16_to_cpu(get_cfg_desc(config)->wTotalLength)); + + mbox2_setup_48_24_magic(dev); + + snd_printk(KERN_INFO "usb-audio: Digidesign Mbox 2: 24bit 48kHz"); + + return 0; /* Successful boot */ +} + /* * Setup quirks */ @@ -655,6 +742,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ return snd_usb_cm6206_boot_quirk(dev); + case USB_ID(0x0dba, 0x3000): + /* Digidesign Mbox 2 */ + return snd_usb_mbox2_boot_quirk(dev); + case USB_ID(0x133e, 0x0815): /* Access Music VirusTI Desktop */ return snd_usb_accessmusic_boot_quirk(dev); |