summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/sound/usb
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /ANDROID_3.4.5/sound/usb
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'ANDROID_3.4.5/sound/usb')
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/Makefile3
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/chip.c220
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/chip.h31
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/comm.c175
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/comm.h43
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/common.h29
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/control.c631
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/control.h57
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/firmware.c418
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/firmware.h27
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/midi.c202
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/midi.h45
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/pcm.c666
-rw-r--r--ANDROID_3.4.5/sound/usb/6fire/pcm.h75
-rw-r--r--ANDROID_3.4.5/sound/usb/Kconfig119
-rw-r--r--ANDROID_3.4.5/sound/usb/Makefile26
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/Makefile4
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/audio.c889
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/audio.h7
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/control.c559
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/control.h6
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/device.c542
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/device.h140
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/input.c842
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/input.h8
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/midi.c174
-rw-r--r--ANDROID_3.4.5/sound/usb/caiaq/midi.h8
-rw-r--r--ANDROID_3.4.5/sound/usb/card.c729
-rw-r--r--ANDROID_3.4.5/sound/usb/card.h111
-rw-r--r--ANDROID_3.4.5/sound/usb/clock.c318
-rw-r--r--ANDROID_3.4.5/sound/usb/clock.h10
-rw-r--r--ANDROID_3.4.5/sound/usb/debug.h15
-rw-r--r--ANDROID_3.4.5/sound/usb/endpoint.c966
-rw-r--r--ANDROID_3.4.5/sound/usb/endpoint.h21
-rw-r--r--ANDROID_3.4.5/sound/usb/format.c515
-rw-r--r--ANDROID_3.4.5/sound/usb/format.h9
-rw-r--r--ANDROID_3.4.5/sound/usb/helper.c118
-rw-r--r--ANDROID_3.4.5/sound/usb/helper.h36
-rw-r--r--ANDROID_3.4.5/sound/usb/midi.c2237
-rw-r--r--ANDROID_3.4.5/sound/usb/midi.h50
-rw-r--r--ANDROID_3.4.5/sound/usb/misc/Makefile2
-rw-r--r--ANDROID_3.4.5/sound/usb/misc/ua101.c1390
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer.c2283
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer.h71
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer_maps.c376
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer_quirks.c654
-rw-r--r--ANDROID_3.4.5/sound/usb/mixer_quirks.h13
-rw-r--r--ANDROID_3.4.5/sound/usb/pcm.c911
-rw-r--r--ANDROID_3.4.5/sound/usb/pcm.h14
-rw-r--r--ANDROID_3.4.5/sound/usb/power.h17
-rw-r--r--ANDROID_3.4.5/sound/usb/proc.c173
-rw-r--r--ANDROID_3.4.5/sound/usb/proc.h8
-rw-r--r--ANDROID_3.4.5/sound/usb/quirks-table.h2769
-rw-r--r--ANDROID_3.4.5/sound/usb/quirks.c763
-rw-r--r--ANDROID_3.4.5/sound/usb/quirks.h23
-rw-r--r--ANDROID_3.4.5/sound/usb/stream.c452
-rw-r--r--ANDROID_3.4.5/sound/usb/stream.h12
-rw-r--r--ANDROID_3.4.5/sound/usb/usbaudio.h105
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/Makefile5
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/us122l.c775
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/us122l.h31
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.c265
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.h6
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usb_stream.c754
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usb_stream.h112
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usbus428ctldefs.h104
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.c462
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.h88
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usbusx2yaudio.c1028
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usx2y.h51
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.c794
-rw-r--r--ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.h22
72 files changed, 0 insertions, 25614 deletions
diff --git a/ANDROID_3.4.5/sound/usb/6fire/Makefile b/ANDROID_3.4.5/sound/usb/6fire/Makefile
deleted file mode 100644
index dfce6ec5..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-snd-usb-6fire-objs += chip.o comm.o midi.o control.o firmware.o pcm.o
-obj-$(CONFIG_SND_USB_6FIRE) += snd-usb-6fire.o
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/chip.c b/ANDROID_3.4.5/sound/usb/6fire/chip.c
deleted file mode 100644
index fc8cc823..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/chip.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Main routines and module definitions.
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "chip.h"
-#include "firmware.h"
-#include "pcm.h"
-#include "control.h"
-#include "comm.h"
-#include "midi.h"
-
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/gfp.h>
-#include <sound/initval.h>
-
-MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>");
-MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */
-static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the 6fire sound device");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the 6fire sound device.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable the 6fire sound device.");
-
-static DEFINE_MUTEX(register_mutex);
-
-static void usb6fire_chip_abort(struct sfire_chip *chip)
-{
- if (chip) {
- if (chip->pcm)
- usb6fire_pcm_abort(chip);
- if (chip->midi)
- usb6fire_midi_abort(chip);
- if (chip->comm)
- usb6fire_comm_abort(chip);
- if (chip->control)
- usb6fire_control_abort(chip);
- if (chip->card) {
- snd_card_disconnect(chip->card);
- snd_card_free_when_closed(chip->card);
- chip->card = NULL;
- }
- }
-}
-
-static void usb6fire_chip_destroy(struct sfire_chip *chip)
-{
- if (chip) {
- if (chip->pcm)
- usb6fire_pcm_destroy(chip);
- if (chip->midi)
- usb6fire_midi_destroy(chip);
- if (chip->comm)
- usb6fire_comm_destroy(chip);
- if (chip->control)
- usb6fire_control_destroy(chip);
- if (chip->card)
- snd_card_free(chip->card);
- }
-}
-
-static int __devinit usb6fire_chip_probe(struct usb_interface *intf,
- const struct usb_device_id *usb_id)
-{
- int ret;
- int i;
- struct sfire_chip *chip = NULL;
- struct usb_device *device = interface_to_usbdev(intf);
- int regidx = -1; /* index in module parameter array */
- struct snd_card *card = NULL;
-
- /* look if we already serve this card and return if so */
- mutex_lock(&register_mutex);
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (devices[i] == device) {
- if (chips[i])
- chips[i]->intf_count++;
- usb_set_intfdata(intf, chips[i]);
- mutex_unlock(&register_mutex);
- return 0;
- } else if (regidx < 0)
- regidx = i;
- }
- if (regidx < 0) {
- mutex_unlock(&register_mutex);
- snd_printk(KERN_ERR PREFIX "too many cards registered.\n");
- return -ENODEV;
- }
- devices[regidx] = device;
- mutex_unlock(&register_mutex);
-
- /* check, if firmware is present on device, upload it if not */
- ret = usb6fire_fw_init(intf);
- if (ret < 0)
- return ret;
- else if (ret == FW_NOT_READY) /* firmware update performed */
- return 0;
-
- /* if we are here, card can be registered in alsa. */
- if (usb_set_interface(device, 0, 0) != 0) {
- snd_printk(KERN_ERR PREFIX "can't set first interface.\n");
- return -EIO;
- }
- ret = snd_card_create(index[regidx], id[regidx], THIS_MODULE,
- sizeof(struct sfire_chip), &card);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n");
- return ret;
- }
- strcpy(card->driver, "6FireUSB");
- strcpy(card->shortname, "TerraTec DMX6FireUSB");
- sprintf(card->longname, "%s at %d:%d", card->shortname,
- device->bus->busnum, device->devnum);
- snd_card_set_dev(card, &intf->dev);
-
- chip = card->private_data;
- chips[regidx] = chip;
- chip->dev = device;
- chip->regidx = regidx;
- chip->intf_count = 1;
- chip->card = card;
-
- ret = usb6fire_comm_init(chip);
- if (ret < 0) {
- usb6fire_chip_destroy(chip);
- return ret;
- }
-
- ret = usb6fire_midi_init(chip);
- if (ret < 0) {
- usb6fire_chip_destroy(chip);
- return ret;
- }
-
- ret = usb6fire_pcm_init(chip);
- if (ret < 0) {
- usb6fire_chip_destroy(chip);
- return ret;
- }
-
- ret = usb6fire_control_init(chip);
- if (ret < 0) {
- usb6fire_chip_destroy(chip);
- return ret;
- }
-
- ret = snd_card_register(card);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "cannot register card.");
- usb6fire_chip_destroy(chip);
- return ret;
- }
- usb_set_intfdata(intf, chip);
- return 0;
-}
-
-static void usb6fire_chip_disconnect(struct usb_interface *intf)
-{
- struct sfire_chip *chip;
- struct snd_card *card;
-
- chip = usb_get_intfdata(intf);
- if (chip) { /* if !chip, fw upload has been performed */
- card = chip->card;
- chip->intf_count--;
- if (!chip->intf_count) {
- mutex_lock(&register_mutex);
- devices[chip->regidx] = NULL;
- chips[chip->regidx] = NULL;
- mutex_unlock(&register_mutex);
-
- chip->shutdown = true;
- usb6fire_chip_abort(chip);
- usb6fire_chip_destroy(chip);
- }
- }
-}
-
-static struct usb_device_id device_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0ccd,
- .idProduct = 0x0080
- },
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, device_table);
-
-static struct usb_driver usb_driver = {
- .name = "snd-usb-6fire",
- .probe = usb6fire_chip_probe,
- .disconnect = usb6fire_chip_disconnect,
- .id_table = device_table,
-};
-
-module_usb_driver(usb_driver);
diff --git a/ANDROID_3.4.5/sound/usb/6fire/chip.h b/ANDROID_3.4.5/sound/usb/6fire/chip.h
deleted file mode 100644
index bde02d10..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/chip.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef USB6FIRE_CHIP_H
-#define USB6FIRE_CHIP_H
-
-#include "common.h"
-
-struct sfire_chip {
- struct usb_device *dev;
- struct snd_card *card;
- int intf_count; /* number of registered interfaces */
- int regidx; /* index in module parameter arrays */
- bool shutdown;
-
- struct midi_runtime *midi;
- struct pcm_runtime *pcm;
- struct control_runtime *control;
- struct comm_runtime *comm;
-};
-#endif /* USB6FIRE_CHIP_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/comm.c b/ANDROID_3.4.5/sound/usb/6fire/comm.c
deleted file mode 100644
index 6c3d531a..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/comm.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Device communications
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "comm.h"
-#include "chip.h"
-#include "midi.h"
-
-enum {
- COMM_EP = 1,
- COMM_FPGA_EP = 2
-};
-
-static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb,
- u8 *buffer, void *context, void(*handler)(struct urb *urb))
-{
- usb_init_urb(urb);
- urb->transfer_buffer = buffer;
- urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP);
- urb->complete = handler;
- urb->context = context;
- urb->interval = 1;
- urb->dev = rt->chip->dev;
-}
-
-static void usb6fire_comm_receiver_handler(struct urb *urb)
-{
- struct comm_runtime *rt = urb->context;
- struct midi_runtime *midi_rt = rt->chip->midi;
-
- if (!urb->status) {
- if (rt->receiver_buffer[0] == 0x10) /* midi in event */
- if (midi_rt)
- midi_rt->in_received(midi_rt,
- rt->receiver_buffer + 2,
- rt->receiver_buffer[1]);
- }
-
- if (!rt->chip->shutdown) {
- urb->status = 0;
- urb->actual_length = 0;
- if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
- snd_printk(KERN_WARNING PREFIX
- "comm data receiver aborted.\n");
- }
-}
-
-static void usb6fire_comm_init_buffer(u8 *buffer, u8 id, u8 request,
- u8 reg, u8 vl, u8 vh)
-{
- buffer[0] = 0x01;
- buffer[2] = request;
- buffer[3] = id;
- switch (request) {
- case 0x02:
- buffer[1] = 0x05; /* length (starting at buffer[2]) */
- buffer[4] = reg;
- buffer[5] = vl;
- buffer[6] = vh;
- break;
-
- case 0x12:
- buffer[1] = 0x0b; /* length (starting at buffer[2]) */
- buffer[4] = 0x00;
- buffer[5] = 0x18;
- buffer[6] = 0x05;
- buffer[7] = 0x00;
- buffer[8] = 0x01;
- buffer[9] = 0x00;
- buffer[10] = 0x9e;
- buffer[11] = reg;
- buffer[12] = vl;
- break;
-
- case 0x20:
- case 0x21:
- case 0x22:
- buffer[1] = 0x04;
- buffer[4] = reg;
- buffer[5] = vl;
- break;
- }
-}
-
-static int usb6fire_comm_send_buffer(u8 *buffer, struct usb_device *dev)
-{
- int ret;
- int actual_len;
-
- ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, COMM_EP),
- buffer, buffer[1] + 2, &actual_len, HZ);
- if (ret < 0)
- return ret;
- else if (actual_len != buffer[1] + 2)
- return -EIO;
- return 0;
-}
-
-static int usb6fire_comm_write8(struct comm_runtime *rt, u8 request,
- u8 reg, u8 value)
-{
- u8 buffer[13]; /* 13: maximum length of message */
-
- usb6fire_comm_init_buffer(buffer, 0x00, request, reg, value, 0x00);
- return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
-}
-
-static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
- u8 reg, u8 vl, u8 vh)
-{
- u8 buffer[13]; /* 13: maximum length of message */
-
- usb6fire_comm_init_buffer(buffer, 0x00, request, reg, vl, vh);
- return usb6fire_comm_send_buffer(buffer, rt->chip->dev);
-}
-
-int __devinit usb6fire_comm_init(struct sfire_chip *chip)
-{
- struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
- GFP_KERNEL);
- struct urb *urb = &rt->receiver;
- int ret;
-
- if (!rt)
- return -ENOMEM;
-
- rt->serial = 1;
- rt->chip = chip;
- usb_init_urb(urb);
- rt->init_urb = usb6fire_comm_init_urb;
- rt->write8 = usb6fire_comm_write8;
- rt->write16 = usb6fire_comm_write16;
-
- /* submit an urb that receives communication data from device */
- urb->transfer_buffer = rt->receiver_buffer;
- urb->transfer_buffer_length = COMM_RECEIVER_BUFSIZE;
- urb->pipe = usb_rcvintpipe(chip->dev, COMM_EP);
- urb->dev = chip->dev;
- urb->complete = usb6fire_comm_receiver_handler;
- urb->context = rt;
- urb->interval = 1;
- ret = usb_submit_urb(urb, GFP_KERNEL);
- if (ret < 0) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX "cannot create comm data receiver.");
- return ret;
- }
- chip->comm = rt;
- return 0;
-}
-
-void usb6fire_comm_abort(struct sfire_chip *chip)
-{
- struct comm_runtime *rt = chip->comm;
-
- if (rt)
- usb_poison_urb(&rt->receiver);
-}
-
-void usb6fire_comm_destroy(struct sfire_chip *chip)
-{
- kfree(chip->comm);
- chip->comm = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/6fire/comm.h b/ANDROID_3.4.5/sound/usb/6fire/comm.h
deleted file mode 100644
index d2af0a5d..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/comm.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef USB6FIRE_COMM_H
-#define USB6FIRE_COMM_H
-
-#include "common.h"
-
-enum /* settings for comm */
-{
- COMM_RECEIVER_BUFSIZE = 64,
-};
-
-struct comm_runtime {
- struct sfire_chip *chip;
-
- struct urb receiver;
- u8 receiver_buffer[COMM_RECEIVER_BUFSIZE];
-
- u8 serial; /* urb serial */
-
- void (*init_urb)(struct comm_runtime *rt, struct urb *urb, u8 *buffer,
- void *context, void(*handler)(struct urb *urb));
- /* writes control data to the device */
- int (*write8)(struct comm_runtime *rt, u8 request, u8 reg, u8 value);
- int (*write16)(struct comm_runtime *rt, u8 request, u8 reg,
- u8 vh, u8 vl);
-};
-
-int __devinit usb6fire_comm_init(struct sfire_chip *chip);
-void usb6fire_comm_abort(struct sfire_chip *chip);
-void usb6fire_comm_destroy(struct sfire_chip *chip);
-#endif /* USB6FIRE_COMM_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/common.h b/ANDROID_3.4.5/sound/usb/6fire/common.h
deleted file mode 100644
index b6eb03ed..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/common.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_COMMON_H
-#define USB6FIRE_COMMON_H
-
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-
-#define PREFIX "6fire: "
-
-struct sfire_chip;
-struct midi_runtime;
-struct pcm_runtime;
-struct control_runtime;
-struct comm_runtime;
-#endif /* USB6FIRE_COMMON_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/control.c b/ANDROID_3.4.5/sound/usb/6fire/control.c
deleted file mode 100644
index 07ed914d..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/control.c
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Mixer control
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * Thanks to:
- * - Holger Ruckdeschel: he found out how to control individual channel
- * volumes and introduced mute switch
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/interrupt.h>
-#include <sound/control.h>
-#include <sound/tlv.h>
-
-#include "control.h"
-#include "comm.h"
-#include "chip.h"
-
-static char *opt_coax_texts[2] = { "Optical", "Coax" };
-static char *line_phono_texts[2] = { "Line", "Phono" };
-
-/*
- * data that needs to be sent to device. sets up card internal stuff.
- * values dumped from windows driver and filtered by trial'n'error.
- */
-static const struct {
- u8 type;
- u8 reg;
- u8 value;
-}
-init_data[] = {
- { 0x22, 0x00, 0x00 }, { 0x20, 0x00, 0x08 }, { 0x22, 0x01, 0x01 },
- { 0x20, 0x01, 0x08 }, { 0x22, 0x02, 0x00 }, { 0x20, 0x02, 0x08 },
- { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 },
- { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 },
- { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 },
- { 0x12, 0x0d, 0x38 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 },
- { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 },
- { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 },
- { 0 } /* TERMINATING ENTRY */
-};
-
-static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
-/* values to write to soundcard register for all samplerates */
-static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
-static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
-
-static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0);
-static DECLARE_TLV_DB_MINMAX(tlv_input, -1500, 1500);
-
-enum {
- DIGITAL_THRU_ONLY_SAMPLERATE = 3
-};
-
-static void usb6fire_control_output_vol_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
- int i;
-
- if (comm_rt)
- for (i = 0; i < 6; i++)
- if (!(rt->ovol_updated & (1 << i))) {
- comm_rt->write8(comm_rt, 0x12, 0x0f + i,
- 180 - rt->output_vol[i]);
- rt->ovol_updated |= 1 << i;
- }
-}
-
-static void usb6fire_control_output_mute_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
-
- if (comm_rt)
- comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute);
-}
-
-static void usb6fire_control_input_vol_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
- int i;
-
- if (comm_rt)
- for (i = 0; i < 2; i++)
- if (!(rt->ivol_updated & (1 << i))) {
- comm_rt->write8(comm_rt, 0x12, 0x1c + i,
- rt->input_vol[i] & 0x3f);
- rt->ivol_updated |= 1 << i;
- }
-}
-
-static void usb6fire_control_line_phono_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
- if (comm_rt) {
- comm_rt->write8(comm_rt, 0x22, 0x02, rt->line_phono_switch);
- comm_rt->write8(comm_rt, 0x21, 0x02, rt->line_phono_switch);
- }
-}
-
-static void usb6fire_control_opt_coax_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
- if (comm_rt) {
- comm_rt->write8(comm_rt, 0x22, 0x00, rt->opt_coax_switch);
- comm_rt->write8(comm_rt, 0x21, 0x00, rt->opt_coax_switch);
- }
-}
-
-static int usb6fire_control_set_rate(struct control_runtime *rt, int rate)
-{
- int ret;
- struct usb_device *device = rt->chip->dev;
- struct comm_runtime *comm_rt = rt->chip->comm;
-
- if (rate < 0 || rate >= CONTROL_N_RATES)
- return -EINVAL;
-
- ret = usb_set_interface(device, 1, rates_altsetting[rate]);
- if (ret < 0)
- return ret;
-
- /* set soundcard clock */
- ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate],
- rates_6fire_vh[rate]);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int usb6fire_control_set_channels(
- struct control_runtime *rt, int n_analog_out,
- int n_analog_in, bool spdif_out, bool spdif_in)
-{
- int ret;
- struct comm_runtime *comm_rt = rt->chip->comm;
-
- /* enable analog inputs and outputs
- * (one bit per stereo-channel) */
- ret = comm_rt->write16(comm_rt, 0x02, 0x02,
- (1 << (n_analog_out / 2)) - 1,
- (1 << (n_analog_in / 2)) - 1);
- if (ret < 0)
- return ret;
-
- /* disable digital inputs and outputs */
- /* TODO: use spdif_x to enable/disable digital channels */
- ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int usb6fire_control_streaming_update(struct control_runtime *rt)
-{
- struct comm_runtime *comm_rt = rt->chip->comm;
-
- if (comm_rt) {
- if (!rt->usb_streaming && rt->digital_thru_switch)
- usb6fire_control_set_rate(rt,
- DIGITAL_THRU_ONLY_SAMPLERATE);
- return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00,
- (rt->usb_streaming ? 0x01 : 0x00) |
- (rt->digital_thru_switch ? 0x08 : 0x00));
- }
- return -EINVAL;
-}
-
-static int usb6fire_control_output_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 180;
- return 0;
-}
-
-static int usb6fire_control_output_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- unsigned int ch = kcontrol->private_value;
- int changed = 0;
-
- if (ch > 4) {
- snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
- return -EINVAL;
- }
-
- if (rt->output_vol[ch] != ucontrol->value.integer.value[0]) {
- rt->output_vol[ch] = ucontrol->value.integer.value[0];
- rt->ovol_updated &= ~(1 << ch);
- changed = 1;
- }
- if (rt->output_vol[ch + 1] != ucontrol->value.integer.value[1]) {
- rt->output_vol[ch + 1] = ucontrol->value.integer.value[1];
- rt->ovol_updated &= ~(2 << ch);
- changed = 1;
- }
-
- if (changed)
- usb6fire_control_output_vol_update(rt);
-
- return changed;
-}
-
-static int usb6fire_control_output_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- unsigned int ch = kcontrol->private_value;
-
- if (ch > 4) {
- snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
- return -EINVAL;
- }
-
- ucontrol->value.integer.value[0] = rt->output_vol[ch];
- ucontrol->value.integer.value[1] = rt->output_vol[ch + 1];
- return 0;
-}
-
-static int usb6fire_control_output_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- unsigned int ch = kcontrol->private_value;
- u8 old = rt->output_mute;
- u8 value = 0;
-
- if (ch > 4) {
- snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
- return -EINVAL;
- }
-
- rt->output_mute &= ~(3 << ch);
- if (ucontrol->value.integer.value[0])
- value |= 1;
- if (ucontrol->value.integer.value[1])
- value |= 2;
- rt->output_mute |= value << ch;
-
- if (rt->output_mute != old)
- usb6fire_control_output_mute_update(rt);
-
- return rt->output_mute != old;
-}
-
-static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- unsigned int ch = kcontrol->private_value;
- u8 value = rt->output_mute >> ch;
-
- if (ch > 4) {
- snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
- return -EINVAL;
- }
-
- ucontrol->value.integer.value[0] = 1 & value;
- value >>= 1;
- ucontrol->value.integer.value[1] = 1 & value;
-
- return 0;
-}
-
-static int usb6fire_control_input_vol_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 2;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 30;
- return 0;
-}
-
-static int usb6fire_control_input_vol_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- int changed = 0;
-
- if (rt->input_vol[0] != ucontrol->value.integer.value[0]) {
- rt->input_vol[0] = ucontrol->value.integer.value[0] - 15;
- rt->ivol_updated &= ~(1 << 0);
- changed = 1;
- }
- if (rt->input_vol[1] != ucontrol->value.integer.value[1]) {
- rt->input_vol[1] = ucontrol->value.integer.value[1] - 15;
- rt->ivol_updated &= ~(1 << 1);
- changed = 1;
- }
-
- if (changed)
- usb6fire_control_input_vol_update(rt);
-
- return changed;
-}
-
-static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = rt->input_vol[0] + 15;
- ucontrol->value.integer.value[1] = rt->input_vol[1] + 15;
-
- return 0;
-}
-
-static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- line_phono_texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int usb6fire_control_line_phono_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- int changed = 0;
- if (rt->line_phono_switch != ucontrol->value.integer.value[0]) {
- rt->line_phono_switch = ucontrol->value.integer.value[0];
- usb6fire_control_line_phono_update(rt);
- changed = 1;
- }
- return changed;
-}
-
-static int usb6fire_control_line_phono_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = rt->line_phono_switch;
- return 0;
-}
-
-static int usb6fire_control_opt_coax_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = 1;
- uinfo->value.enumerated.items = 2;
- if (uinfo->value.enumerated.item > 1)
- uinfo->value.enumerated.item = 1;
- strcpy(uinfo->value.enumerated.name,
- opt_coax_texts[uinfo->value.enumerated.item]);
- return 0;
-}
-
-static int usb6fire_control_opt_coax_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- int changed = 0;
-
- if (rt->opt_coax_switch != ucontrol->value.enumerated.item[0]) {
- rt->opt_coax_switch = ucontrol->value.enumerated.item[0];
- usb6fire_control_opt_coax_update(rt);
- changed = 1;
- }
- return changed;
-}
-
-static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- ucontrol->value.enumerated.item[0] = rt->opt_coax_switch;
- return 0;
-}
-
-static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- int changed = 0;
-
- if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) {
- rt->digital_thru_switch = ucontrol->value.integer.value[0];
- usb6fire_control_streaming_update(rt);
- changed = 1;
- }
- return changed;
-}
-
-static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
- ucontrol->value.integer.value[0] = rt->digital_thru_switch;
- return 0;
-}
-
-static struct __devinitdata snd_kcontrol_new vol_elements[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Volume",
- .index = 0,
- .private_value = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = usb6fire_control_output_vol_info,
- .get = usb6fire_control_output_vol_get,
- .put = usb6fire_control_output_vol_put,
- .tlv = { .p = tlv_output }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Volume",
- .index = 1,
- .private_value = 2,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = usb6fire_control_output_vol_info,
- .get = usb6fire_control_output_vol_get,
- .put = usb6fire_control_output_vol_put,
- .tlv = { .p = tlv_output }
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Volume",
- .index = 2,
- .private_value = 4,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = usb6fire_control_output_vol_info,
- .get = usb6fire_control_output_vol_get,
- .put = usb6fire_control_output_vol_put,
- .tlv = { .p = tlv_output }
- },
- {}
-};
-
-static struct __devinitdata snd_kcontrol_new mute_elements[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Switch",
- .index = 0,
- .private_value = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ctl_boolean_stereo_info,
- .get = usb6fire_control_output_mute_get,
- .put = usb6fire_control_output_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Switch",
- .index = 1,
- .private_value = 2,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ctl_boolean_stereo_info,
- .get = usb6fire_control_output_mute_get,
- .put = usb6fire_control_output_mute_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Playback Switch",
- .index = 2,
- .private_value = 4,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ctl_boolean_stereo_info,
- .get = usb6fire_control_output_mute_get,
- .put = usb6fire_control_output_mute_put,
- },
- {}
-};
-
-static struct __devinitdata snd_kcontrol_new elements[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Line/Phono Capture Route",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = usb6fire_control_line_phono_info,
- .get = usb6fire_control_line_phono_get,
- .put = usb6fire_control_line_phono_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Opt/Coax Capture Route",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = usb6fire_control_opt_coax_info,
- .get = usb6fire_control_opt_coax_get,
- .put = usb6fire_control_opt_coax_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Thru Playback Route",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .info = snd_ctl_boolean_mono_info,
- .get = usb6fire_control_digital_thru_get,
- .put = usb6fire_control_digital_thru_put
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Analog Capture Volume",
- .index = 0,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
- SNDRV_CTL_ELEM_ACCESS_TLV_READ,
- .info = usb6fire_control_input_vol_info,
- .get = usb6fire_control_input_vol_get,
- .put = usb6fire_control_input_vol_put,
- .tlv = { .p = tlv_input }
- },
- {}
-};
-
-static int usb6fire_control_add_virtual(
- struct control_runtime *rt,
- struct snd_card *card,
- char *name,
- struct snd_kcontrol_new *elems)
-{
- int ret;
- int i;
- struct snd_kcontrol *vmaster =
- snd_ctl_make_virtual_master(name, tlv_output);
- struct snd_kcontrol *control;
-
- if (!vmaster)
- return -ENOMEM;
- ret = snd_ctl_add(card, vmaster);
- if (ret < 0)
- return ret;
-
- i = 0;
- while (elems[i].name) {
- control = snd_ctl_new1(&elems[i], rt);
- if (!control)
- return -ENOMEM;
- ret = snd_ctl_add(card, control);
- if (ret < 0)
- return ret;
- ret = snd_ctl_add_slave(vmaster, control);
- if (ret < 0)
- return ret;
- i++;
- }
- return 0;
-}
-
-int __devinit usb6fire_control_init(struct sfire_chip *chip)
-{
- int i;
- int ret;
- struct control_runtime *rt = kzalloc(sizeof(struct control_runtime),
- GFP_KERNEL);
- struct comm_runtime *comm_rt = chip->comm;
-
- if (!rt)
- return -ENOMEM;
-
- rt->chip = chip;
- rt->update_streaming = usb6fire_control_streaming_update;
- rt->set_rate = usb6fire_control_set_rate;
- rt->set_channels = usb6fire_control_set_channels;
-
- i = 0;
- while (init_data[i].type) {
- comm_rt->write8(comm_rt, init_data[i].type, init_data[i].reg,
- init_data[i].value);
- i++;
- }
-
- usb6fire_control_opt_coax_update(rt);
- usb6fire_control_line_phono_update(rt);
- usb6fire_control_output_vol_update(rt);
- usb6fire_control_output_mute_update(rt);
- usb6fire_control_input_vol_update(rt);
- usb6fire_control_streaming_update(rt);
-
- ret = usb6fire_control_add_virtual(rt, chip->card,
- "Master Playback Volume", vol_elements);
- if (ret) {
- snd_printk(KERN_ERR PREFIX "cannot add control.\n");
- kfree(rt);
- return ret;
- }
- ret = usb6fire_control_add_virtual(rt, chip->card,
- "Master Playback Switch", mute_elements);
- if (ret) {
- snd_printk(KERN_ERR PREFIX "cannot add control.\n");
- kfree(rt);
- return ret;
- }
-
- i = 0;
- while (elements[i].name) {
- ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt));
- if (ret < 0) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX "cannot add control.\n");
- return ret;
- }
- i++;
- }
-
- chip->control = rt;
- return 0;
-}
-
-void usb6fire_control_abort(struct sfire_chip *chip)
-{}
-
-void usb6fire_control_destroy(struct sfire_chip *chip)
-{
- kfree(chip->control);
- chip->control = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/6fire/control.h b/ANDROID_3.4.5/sound/usb/6fire/control.h
deleted file mode 100644
index 9a596d95..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/control.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_CONTROL_H
-#define USB6FIRE_CONTROL_H
-
-#include "common.h"
-
-enum {
- CONTROL_MAX_ELEMENTS = 32
-};
-
-enum {
- CONTROL_RATE_44KHZ,
- CONTROL_RATE_48KHZ,
- CONTROL_RATE_88KHZ,
- CONTROL_RATE_96KHZ,
- CONTROL_RATE_176KHZ,
- CONTROL_RATE_192KHZ,
- CONTROL_N_RATES
-};
-
-struct control_runtime {
- int (*update_streaming)(struct control_runtime *rt);
- int (*set_rate)(struct control_runtime *rt, int rate);
- int (*set_channels)(struct control_runtime *rt, int n_analog_out,
- int n_analog_in, bool spdif_out, bool spdif_in);
-
- struct sfire_chip *chip;
-
- struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS];
- bool opt_coax_switch;
- bool line_phono_switch;
- bool digital_thru_switch;
- bool usb_streaming;
- u8 output_vol[6];
- u8 ovol_updated;
- u8 output_mute;
- s8 input_vol[2];
- u8 ivol_updated;
-};
-
-int __devinit usb6fire_control_init(struct sfire_chip *chip);
-void usb6fire_control_abort(struct sfire_chip *chip);
-void usb6fire_control_destroy(struct sfire_chip *chip);
-#endif /* USB6FIRE_CONTROL_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/firmware.c b/ANDROID_3.4.5/sound/usb/6fire/firmware.c
deleted file mode 100644
index 6f9715ab..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/firmware.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Firmware loader
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/firmware.h>
-#include <linux/module.h>
-#include <linux/bitrev.h>
-#include <linux/kernel.h>
-
-#include "firmware.h"
-#include "chip.h"
-
-MODULE_FIRMWARE("6fire/dmx6firel2.ihx");
-MODULE_FIRMWARE("6fire/dmx6fireap.ihx");
-MODULE_FIRMWARE("6fire/dmx6firecf.bin");
-
-enum {
- FPGA_BUFSIZE = 512, FPGA_EP = 2
-};
-
-/*
- * wMaxPacketSize of pcm endpoints.
- * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c
- * fpp: frames per isopacket
- *
- * CAUTION: keep sizeof <= buffer[] in usb6fire_fw_init
- */
-static const u8 ep_w_max_packet_size[] = {
- 0xe4, 0x00, 0xe4, 0x00, /* alt 1: 228 EP2 and EP6 (7 fpp) */
- 0xa4, 0x01, 0xa4, 0x01, /* alt 2: 420 EP2 and EP6 (13 fpp)*/
- 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */
-};
-
-static const u8 known_fw_versions[][4] = {
- { 0x03, 0x01, 0x0b, 0x00 }
-};
-
-struct ihex_record {
- u16 address;
- u8 len;
- u8 data[256];
- char error; /* true if an error occurred parsing this record */
-
- u8 max_len; /* maximum record length in whole ihex */
-
- /* private */
- const char *txt_data;
- unsigned int txt_length;
- unsigned int txt_offset; /* current position in txt_data */
-};
-
-static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc)
-{
- u8 val = 0;
- int hval;
-
- hval = hex_to_bin(data[0]);
- if (hval >= 0)
- val |= (hval << 4);
-
- hval = hex_to_bin(data[1]);
- if (hval >= 0)
- val |= hval;
-
- *crc += val;
- return val;
-}
-
-/*
- * returns true if record is available, false otherwise.
- * iff an error occurred, false will be returned and record->error will be true.
- */
-static bool usb6fire_fw_ihex_next_record(struct ihex_record *record)
-{
- u8 crc = 0;
- u8 type;
- int i;
-
- record->error = false;
-
- /* find begin of record (marked by a colon) */
- while (record->txt_offset < record->txt_length
- && record->txt_data[record->txt_offset] != ':')
- record->txt_offset++;
- if (record->txt_offset == record->txt_length)
- return false;
-
- /* number of characters needed for len, addr and type entries */
- record->txt_offset++;
- if (record->txt_offset + 8 > record->txt_length) {
- record->error = true;
- return false;
- }
-
- record->len = usb6fire_fw_ihex_hex(record->txt_data +
- record->txt_offset, &crc);
- record->txt_offset += 2;
- record->address = usb6fire_fw_ihex_hex(record->txt_data +
- record->txt_offset, &crc) << 8;
- record->txt_offset += 2;
- record->address |= usb6fire_fw_ihex_hex(record->txt_data +
- record->txt_offset, &crc);
- record->txt_offset += 2;
- type = usb6fire_fw_ihex_hex(record->txt_data +
- record->txt_offset, &crc);
- record->txt_offset += 2;
-
- /* number of characters needed for data and crc entries */
- if (record->txt_offset + 2 * (record->len + 1) > record->txt_length) {
- record->error = true;
- return false;
- }
- for (i = 0; i < record->len; i++) {
- record->data[i] = usb6fire_fw_ihex_hex(record->txt_data
- + record->txt_offset, &crc);
- record->txt_offset += 2;
- }
- usb6fire_fw_ihex_hex(record->txt_data + record->txt_offset, &crc);
- if (crc) {
- record->error = true;
- return false;
- }
-
- if (type == 1 || !record->len) /* eof */
- return false;
- else if (type == 0)
- return true;
- else {
- record->error = true;
- return false;
- }
-}
-
-static int usb6fire_fw_ihex_init(const struct firmware *fw,
- struct ihex_record *record)
-{
- record->txt_data = fw->data;
- record->txt_length = fw->size;
- record->txt_offset = 0;
- record->max_len = 0;
- /* read all records, if loop ends, record->error indicates,
- * whether ihex is valid. */
- while (usb6fire_fw_ihex_next_record(record))
- record->max_len = max(record->len, record->max_len);
- if (record->error)
- return -EINVAL;
- record->txt_offset = 0;
- return 0;
-}
-
-static int usb6fire_fw_ezusb_write(struct usb_device *device,
- int type, int value, char *data, int len)
-{
- int ret;
-
- ret = usb_control_msg(device, usb_sndctrlpipe(device, 0), type,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- value, 0, data, len, HZ);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EIO;
- return 0;
-}
-
-static int usb6fire_fw_ezusb_read(struct usb_device *device,
- int type, int value, char *data, int len)
-{
- int ret = usb_control_msg(device, usb_rcvctrlpipe(device, 0), type,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value,
- 0, data, len, HZ);
- if (ret < 0)
- return ret;
- else if (ret != len)
- return -EIO;
- return 0;
-}
-
-static int usb6fire_fw_fpga_write(struct usb_device *device,
- char *data, int len)
-{
- int actual_len;
- int ret;
-
- ret = usb_bulk_msg(device, usb_sndbulkpipe(device, FPGA_EP), data, len,
- &actual_len, HZ);
- if (ret < 0)
- return ret;
- else if (actual_len != len)
- return -EIO;
- return 0;
-}
-
-static int usb6fire_fw_ezusb_upload(
- struct usb_interface *intf, const char *fwname,
- unsigned int postaddr, u8 *postdata, unsigned int postlen)
-{
- int ret;
- u8 data;
- struct usb_device *device = interface_to_usbdev(intf);
- const struct firmware *fw = 0;
- struct ihex_record *rec = kmalloc(sizeof(struct ihex_record),
- GFP_KERNEL);
-
- if (!rec)
- return -ENOMEM;
-
- ret = request_firmware(&fw, fwname, &device->dev);
- if (ret < 0) {
- kfree(rec);
- snd_printk(KERN_ERR PREFIX "error requesting ezusb "
- "firmware %s.\n", fwname);
- return ret;
- }
- ret = usb6fire_fw_ihex_init(fw, rec);
- if (ret < 0) {
- kfree(rec);
- release_firmware(fw);
- snd_printk(KERN_ERR PREFIX "error validating ezusb "
- "firmware %s.\n", fwname);
- return ret;
- }
- /* upload firmware image */
- data = 0x01; /* stop ezusb cpu */
- ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
- if (ret < 0) {
- kfree(rec);
- release_firmware(fw);
- snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
- "firmware %s: begin message.\n", fwname);
- return ret;
- }
-
- while (usb6fire_fw_ihex_next_record(rec)) { /* write firmware */
- ret = usb6fire_fw_ezusb_write(device, 0xa0, rec->address,
- rec->data, rec->len);
- if (ret < 0) {
- kfree(rec);
- release_firmware(fw);
- snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
- "firmware %s: data urb.\n", fwname);
- return ret;
- }
- }
-
- release_firmware(fw);
- kfree(rec);
- if (postdata) { /* write data after firmware has been uploaded */
- ret = usb6fire_fw_ezusb_write(device, 0xa0, postaddr,
- postdata, postlen);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
- "firmware %s: post urb.\n", fwname);
- return ret;
- }
- }
-
- data = 0x00; /* resume ezusb cpu */
- ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to upload ezusb "
- "firmware %s: end message.\n", fwname);
- return ret;
- }
- return 0;
-}
-
-static int usb6fire_fw_fpga_upload(
- struct usb_interface *intf, const char *fwname)
-{
- int ret;
- int i;
- struct usb_device *device = interface_to_usbdev(intf);
- u8 *buffer = kmalloc(FPGA_BUFSIZE, GFP_KERNEL);
- const char *c;
- const char *end;
- const struct firmware *fw;
-
- if (!buffer)
- return -ENOMEM;
-
- ret = request_firmware(&fw, fwname, &device->dev);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to get fpga firmware %s.\n",
- fwname);
- kfree(buffer);
- return -EIO;
- }
-
- c = fw->data;
- end = fw->data + fw->size;
-
- ret = usb6fire_fw_ezusb_write(device, 8, 0, NULL, 0);
- if (ret < 0) {
- kfree(buffer);
- release_firmware(fw);
- snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: "
- "begin urb.\n");
- return ret;
- }
-
- while (c != end) {
- for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
- buffer[i] = byte_rev_table[(u8) *c];
-
- ret = usb6fire_fw_fpga_write(device, buffer, i);
- if (ret < 0) {
- release_firmware(fw);
- kfree(buffer);
- snd_printk(KERN_ERR PREFIX "unable to upload fpga "
- "firmware: fw urb.\n");
- return ret;
- }
- }
- release_firmware(fw);
- kfree(buffer);
-
- ret = usb6fire_fw_ezusb_write(device, 9, 0, NULL, 0);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to upload fpga firmware: "
- "end urb.\n");
- return ret;
- }
- return 0;
-}
-
-/* check, if the firmware version the devices has currently loaded
- * is known by this driver. 'version' needs to have 4 bytes version
- * info data. */
-static int usb6fire_fw_check(u8 *version)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++)
- if (!memcmp(version, known_fw_versions + i, 4))
- return 0;
-
- snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
- "%02x %02x %02x %02x. "
- "please reconnect to power. if this failure "
- "still happens, check your firmware installation.",
- version[0], version[1], version[2], version[3]);
- return -EINVAL;
-}
-
-int usb6fire_fw_init(struct usb_interface *intf)
-{
- int i;
- int ret;
- struct usb_device *device = interface_to_usbdev(intf);
- /* buffer: 8 receiving bytes from device and
- * sizeof(EP_W_MAX_PACKET_SIZE) bytes for non-const copy */
- u8 buffer[12];
-
- ret = usb6fire_fw_ezusb_read(device, 1, 0, buffer, 8);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "unable to receive device "
- "firmware state.\n");
- return ret;
- }
- if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
- snd_printk(KERN_ERR PREFIX "unknown device firmware state "
- "received from device: ");
- for (i = 0; i < 8; i++)
- snd_printk("%02x ", buffer[i]);
- snd_printk("\n");
- return -EIO;
- }
- /* do we need fpga loader ezusb firmware? */
- if (buffer[3] == 0x01) {
- ret = usb6fire_fw_ezusb_upload(intf,
- "6fire/dmx6firel2.ihx", 0, NULL, 0);
- if (ret < 0)
- return ret;
- return FW_NOT_READY;
- }
- /* do we need fpga firmware and application ezusb firmware? */
- else if (buffer[3] == 0x02) {
- ret = usb6fire_fw_check(buffer + 4);
- if (ret < 0)
- return ret;
- ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin");
- if (ret < 0)
- return ret;
- memcpy(buffer, ep_w_max_packet_size,
- sizeof(ep_w_max_packet_size));
- ret = usb6fire_fw_ezusb_upload(intf, "6fire/dmx6fireap.ihx",
- 0x0003, buffer, sizeof(ep_w_max_packet_size));
- if (ret < 0)
- return ret;
- return FW_NOT_READY;
- }
- /* all fw loaded? */
- else if (buffer[3] == 0x03)
- return usb6fire_fw_check(buffer + 4);
- /* unknown data? */
- else {
- snd_printk(KERN_ERR PREFIX "unknown device firmware state "
- "received from device: ");
- for (i = 0; i < 8; i++)
- snd_printk("%02x ", buffer[i]);
- snd_printk("\n");
- return -EIO;
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/firmware.h b/ANDROID_3.4.5/sound/usb/6fire/firmware.h
deleted file mode 100644
index 00856989..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/firmware.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_FIRMWARE_H
-#define USB6FIRE_FIRMWARE_H
-
-#include "common.h"
-
-enum /* firmware state of device */
-{
- FW_READY = 0,
- FW_NOT_READY = 1
-};
-
-int __devinit usb6fire_fw_init(struct usb_interface *intf);
-#endif /* USB6FIRE_FIRMWARE_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/midi.c b/ANDROID_3.4.5/sound/usb/6fire/midi.c
deleted file mode 100644
index f0e5179b..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/midi.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Rawmidi driver
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <sound/rawmidi.h>
-
-#include "midi.h"
-#include "chip.h"
-#include "comm.h"
-
-static void usb6fire_midi_out_handler(struct urb *urb)
-{
- struct midi_runtime *rt = urb->context;
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&rt->out_lock, flags);
-
- if (rt->out) {
- ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4,
- MIDI_BUFSIZE - 4);
- if (ret > 0) { /* more data available, send next packet */
- rt->out_buffer[1] = ret + 2;
- rt->out_buffer[3] = rt->out_serial++;
- urb->transfer_buffer_length = ret + 4;
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0)
- snd_printk(KERN_ERR PREFIX "midi out urb "
- "submit failed: %d\n", ret);
- } else /* no more data to transmit */
- rt->out = NULL;
- }
- spin_unlock_irqrestore(&rt->out_lock, flags);
-}
-
-static void usb6fire_midi_in_received(
- struct midi_runtime *rt, u8 *data, int length)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&rt->in_lock, flags);
- if (rt->in)
- snd_rawmidi_receive(rt->in, data, length);
- spin_unlock_irqrestore(&rt->in_lock, flags);
-}
-
-static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub)
-{
- return 0;
-}
-
-static int usb6fire_midi_out_close(struct snd_rawmidi_substream *alsa_sub)
-{
- return 0;
-}
-
-static void usb6fire_midi_out_trigger(
- struct snd_rawmidi_substream *alsa_sub, int up)
-{
- struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- struct urb *urb = &rt->out_urb;
- __s8 ret;
- unsigned long flags;
-
- spin_lock_irqsave(&rt->out_lock, flags);
- if (up) { /* start transfer */
- if (rt->out) { /* we are already transmitting so just return */
- spin_unlock_irqrestore(&rt->out_lock, flags);
- return;
- }
-
- ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
- MIDI_BUFSIZE - 4);
- if (ret > 0) {
- rt->out_buffer[1] = ret + 2;
- rt->out_buffer[3] = rt->out_serial++;
- urb->transfer_buffer_length = ret + 4;
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0)
- snd_printk(KERN_ERR PREFIX "midi out urb "
- "submit failed: %d\n", ret);
- else
- rt->out = alsa_sub;
- }
- } else if (rt->out == alsa_sub)
- rt->out = NULL;
- spin_unlock_irqrestore(&rt->out_lock, flags);
-}
-
-static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub)
-{
- struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- int retry = 0;
-
- while (rt->out && retry++ < 100)
- msleep(10);
-}
-
-static int usb6fire_midi_in_open(struct snd_rawmidi_substream *alsa_sub)
-{
- return 0;
-}
-
-static int usb6fire_midi_in_close(struct snd_rawmidi_substream *alsa_sub)
-{
- return 0;
-}
-
-static void usb6fire_midi_in_trigger(
- struct snd_rawmidi_substream *alsa_sub, int up)
-{
- struct midi_runtime *rt = alsa_sub->rmidi->private_data;
- unsigned long flags;
-
- spin_lock_irqsave(&rt->in_lock, flags);
- if (up)
- rt->in = alsa_sub;
- else
- rt->in = NULL;
- spin_unlock_irqrestore(&rt->in_lock, flags);
-}
-
-static struct snd_rawmidi_ops out_ops = {
- .open = usb6fire_midi_out_open,
- .close = usb6fire_midi_out_close,
- .trigger = usb6fire_midi_out_trigger,
- .drain = usb6fire_midi_out_drain
-};
-
-static struct snd_rawmidi_ops in_ops = {
- .open = usb6fire_midi_in_open,
- .close = usb6fire_midi_in_close,
- .trigger = usb6fire_midi_in_trigger
-};
-
-int __devinit usb6fire_midi_init(struct sfire_chip *chip)
-{
- int ret;
- struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime),
- GFP_KERNEL);
- struct comm_runtime *comm_rt = chip->comm;
-
- if (!rt)
- return -ENOMEM;
-
- rt->chip = chip;
- rt->in_received = usb6fire_midi_in_received;
- rt->out_buffer[0] = 0x80; /* 'send midi' command */
- rt->out_buffer[1] = 0x00; /* size of data */
- rt->out_buffer[2] = 0x00; /* always 0 */
- spin_lock_init(&rt->in_lock);
- spin_lock_init(&rt->out_lock);
-
- comm_rt->init_urb(comm_rt, &rt->out_urb, rt->out_buffer, rt,
- usb6fire_midi_out_handler);
-
- ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
- if (ret < 0) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX "unable to create midi.\n");
- return ret;
- }
- rt->instance->private_data = rt;
- strcpy(rt->instance->name, "DMX6FireUSB MIDI");
- rt->instance->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &out_ops);
- snd_rawmidi_set_ops(rt->instance, SNDRV_RAWMIDI_STREAM_INPUT,
- &in_ops);
-
- chip->midi = rt;
- return 0;
-}
-
-void usb6fire_midi_abort(struct sfire_chip *chip)
-{
- struct midi_runtime *rt = chip->midi;
-
- if (rt)
- usb_poison_urb(&rt->out_urb);
-}
-
-void usb6fire_midi_destroy(struct sfire_chip *chip)
-{
- kfree(chip->midi);
- chip->midi = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/6fire/midi.h b/ANDROID_3.4.5/sound/usb/6fire/midi.h
deleted file mode 100644
index 5114eccc..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/midi.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_MIDI_H
-#define USB6FIRE_MIDI_H
-
-#include "common.h"
-
-enum {
- MIDI_BUFSIZE = 64
-};
-
-struct midi_runtime {
- struct sfire_chip *chip;
- struct snd_rawmidi *instance;
-
- struct snd_rawmidi_substream *in;
- char in_active;
-
- spinlock_t in_lock;
- spinlock_t out_lock;
- struct snd_rawmidi_substream *out;
- struct urb out_urb;
- u8 out_serial; /* serial number of out packet */
- u8 out_buffer[MIDI_BUFSIZE];
- int buffer_offset;
-
- void (*in_received)(struct midi_runtime *rt, u8 *data, int length);
-};
-
-int __devinit usb6fire_midi_init(struct sfire_chip *chip);
-void usb6fire_midi_abort(struct sfire_chip *chip);
-void usb6fire_midi_destroy(struct sfire_chip *chip);
-#endif /* USB6FIRE_MIDI_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/6fire/pcm.c b/ANDROID_3.4.5/sound/usb/6fire/pcm.c
deleted file mode 100644
index c97d05f0..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/pcm.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * PCM driver
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "pcm.h"
-#include "chip.h"
-#include "comm.h"
-#include "control.h"
-
-enum {
- OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4
-};
-
-/* keep next two synced with
- * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE
- * and CONTROL_RATE_XXX in control.h */
-static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 };
-static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 };
-static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 };
-static const int rates_alsaid[] = {
- SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000,
- SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000,
- SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 };
-
-enum { /* settings for pcm */
- OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024
-};
-
-enum { /* pcm streaming states */
- STREAM_DISABLED, /* no pcm streaming */
- STREAM_STARTING, /* pcm streaming requested, waiting to become ready */
- STREAM_RUNNING, /* pcm streaming running */
- STREAM_STOPPING
-};
-
-static const struct snd_pcm_hardware pcm_hw = {
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH,
-
- .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
-
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000 |
- SNDRV_PCM_RATE_176400 |
- SNDRV_PCM_RATE_192000,
-
- .rate_min = 44100,
- .rate_max = 192000,
- .channels_min = 1,
- .channels_max = 0, /* set in pcm_open, depending on capture/playback */
- .buffer_bytes_max = MAX_BUFSIZE,
- .period_bytes_min = PCM_N_PACKETS_PER_URB * (PCM_MAX_PACKET_SIZE - 4),
- .period_bytes_max = MAX_BUFSIZE,
- .periods_min = 2,
- .periods_max = 1024
-};
-
-static int usb6fire_pcm_set_rate(struct pcm_runtime *rt)
-{
- int ret;
- struct control_runtime *ctrl_rt = rt->chip->control;
-
- ctrl_rt->usb_streaming = false;
- ret = ctrl_rt->update_streaming(ctrl_rt);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "error stopping streaming while "
- "setting samplerate %d.\n", rates[rt->rate]);
- return ret;
- }
-
- ret = ctrl_rt->set_rate(ctrl_rt, rt->rate);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n",
- rates[rt->rate]);
- return ret;
- }
-
- ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS,
- false, false);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "error initializing channels "
- "while setting samplerate %d.\n",
- rates[rt->rate]);
- return ret;
- }
-
- ctrl_rt->usb_streaming = true;
- ret = ctrl_rt->update_streaming(ctrl_rt);
- if (ret < 0) {
- snd_printk(KERN_ERR PREFIX "error starting streaming while "
- "setting samplerate %d.\n", rates[rt->rate]);
- return ret;
- }
-
- rt->in_n_analog = IN_N_CHANNELS;
- rt->out_n_analog = OUT_N_CHANNELS;
- rt->in_packet_size = rates_in_packet_size[rt->rate];
- rt->out_packet_size = rates_out_packet_size[rt->rate];
- return 0;
-}
-
-static struct pcm_substream *usb6fire_pcm_get_substream(
- struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
-
- if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- return &rt->playback;
- else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE)
- return &rt->capture;
- snd_printk(KERN_ERR PREFIX "error getting pcm substream slot.\n");
- return NULL;
-}
-
-/* call with stream_mutex locked */
-static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
-{
- int i;
- struct control_runtime *ctrl_rt = rt->chip->control;
-
- if (rt->stream_state != STREAM_DISABLED) {
- for (i = 0; i < PCM_N_URBS; i++) {
- usb_kill_urb(&rt->in_urbs[i].instance);
- usb_kill_urb(&rt->out_urbs[i].instance);
- }
- ctrl_rt->usb_streaming = false;
- ctrl_rt->update_streaming(ctrl_rt);
- rt->stream_state = STREAM_DISABLED;
- }
-}
-
-/* call with stream_mutex locked */
-static int usb6fire_pcm_stream_start(struct pcm_runtime *rt)
-{
- int ret;
- int i;
- int k;
- struct usb_iso_packet_descriptor *packet;
-
- if (rt->stream_state == STREAM_DISABLED) {
- /* submit our in urbs */
- rt->stream_wait_cond = false;
- rt->stream_state = STREAM_STARTING;
- for (i = 0; i < PCM_N_URBS; i++) {
- for (k = 0; k < PCM_N_PACKETS_PER_URB; k++) {
- packet = &rt->in_urbs[i].packets[k];
- packet->offset = k * rt->in_packet_size;
- packet->length = rt->in_packet_size;
- packet->actual_length = 0;
- packet->status = 0;
- }
- ret = usb_submit_urb(&rt->in_urbs[i].instance,
- GFP_ATOMIC);
- if (ret) {
- usb6fire_pcm_stream_stop(rt);
- return ret;
- }
- }
-
- /* wait for first out urb to return (sent in in urb handler) */
- wait_event_timeout(rt->stream_wait_queue, rt->stream_wait_cond,
- HZ);
- if (rt->stream_wait_cond)
- rt->stream_state = STREAM_RUNNING;
- else {
- usb6fire_pcm_stream_stop(rt);
- return -EIO;
- }
- }
- return 0;
-}
-
-/* call with substream locked */
-static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
-{
- int i;
- int frame;
- int frame_count;
- unsigned int total_length = 0;
- struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
- struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
- u32 *src = NULL;
- u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
- * (alsa_rt->frame_bits >> 3));
- u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
- * (alsa_rt->frame_bits >> 3));
- int bytes_per_frame = alsa_rt->channels << 2;
-
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
- /* at least 4 header bytes for valid packet.
- * after that: 32 bits per sample for analog channels */
- if (urb->packets[i].actual_length > 4)
- frame_count = (urb->packets[i].actual_length - 4)
- / (rt->in_n_analog << 2);
- else
- frame_count = 0;
-
- if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
- src = (u32 *) (urb->buffer + total_length);
- else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
- src = (u32 *) (urb->buffer - 1 + total_length);
- else
- return;
- src++; /* skip leading 4 bytes of every packet */
- total_length += urb->packets[i].length;
- for (frame = 0; frame < frame_count; frame++) {
- memcpy(dest, src, bytes_per_frame);
- dest += alsa_rt->channels;
- src += rt->in_n_analog;
- sub->dma_off++;
- sub->period_off++;
- if (dest == dest_end) {
- sub->dma_off = 0;
- dest = (u32 *) alsa_rt->dma_area;
- }
- }
- }
-}
-
-/* call with substream locked */
-static void usb6fire_pcm_playback(struct pcm_substream *sub,
- struct pcm_urb *urb)
-{
- int i;
- int frame;
- int frame_count;
- struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
- struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
- u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off
- * (alsa_rt->frame_bits >> 3));
- u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
- * (alsa_rt->frame_bits >> 3));
- u32 *dest;
- int bytes_per_frame = alsa_rt->channels << 2;
-
- if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE)
- dest = (u32 *) (urb->buffer - 1);
- else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE)
- dest = (u32 *) (urb->buffer);
- else {
- snd_printk(KERN_ERR PREFIX "Unknown sample format.");
- return;
- }
-
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
- /* at least 4 header bytes for valid packet.
- * after that: 32 bits per sample for analog channels */
- if (urb->packets[i].length > 4)
- frame_count = (urb->packets[i].length - 4)
- / (rt->out_n_analog << 2);
- else
- frame_count = 0;
- dest++; /* skip leading 4 bytes of every frame */
- for (frame = 0; frame < frame_count; frame++) {
- memcpy(dest, src, bytes_per_frame);
- src += alsa_rt->channels;
- dest += rt->out_n_analog;
- sub->dma_off++;
- sub->period_off++;
- if (src == src_end) {
- src = (u32 *) alsa_rt->dma_area;
- sub->dma_off = 0;
- }
- }
- }
-}
-
-static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
-{
- struct pcm_urb *in_urb = usb_urb->context;
- struct pcm_urb *out_urb = in_urb->peer;
- struct pcm_runtime *rt = in_urb->chip->pcm;
- struct pcm_substream *sub;
- unsigned long flags;
- int total_length = 0;
- int frame_count;
- int frame;
- int channel;
- int i;
- u8 *dest;
-
- if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING)
- return;
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
- if (in_urb->packets[i].status) {
- rt->panic = true;
- return;
- }
-
- if (rt->stream_state == STREAM_DISABLED) {
- snd_printk(KERN_ERR PREFIX "internal error: "
- "stream disabled in in-urb handler.\n");
- return;
- }
-
- /* receive our capture data */
- sub = &rt->capture;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active) {
- usb6fire_pcm_capture(sub, in_urb);
- if (sub->period_off >= sub->instance->runtime->period_size) {
- sub->period_off %= sub->instance->runtime->period_size;
- spin_unlock_irqrestore(&sub->lock, flags);
- snd_pcm_period_elapsed(sub->instance);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
-
- /* setup out urb structure */
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
- out_urb->packets[i].offset = total_length;
- out_urb->packets[i].length = (in_urb->packets[i].actual_length
- - 4) / (rt->in_n_analog << 2)
- * (rt->out_n_analog << 2) + 4;
- out_urb->packets[i].status = 0;
- total_length += out_urb->packets[i].length;
- }
- memset(out_urb->buffer, 0, total_length);
-
- /* now send our playback data (if a free out urb was found) */
- sub = &rt->playback;
- spin_lock_irqsave(&sub->lock, flags);
- if (sub->active) {
- usb6fire_pcm_playback(sub, out_urb);
- if (sub->period_off >= sub->instance->runtime->period_size) {
- sub->period_off %= sub->instance->runtime->period_size;
- spin_unlock_irqrestore(&sub->lock, flags);
- snd_pcm_period_elapsed(sub->instance);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
- } else
- spin_unlock_irqrestore(&sub->lock, flags);
-
- /* setup the 4th byte of each sample (0x40 for analog channels) */
- dest = out_urb->buffer;
- for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
- if (out_urb->packets[i].length >= 4) {
- frame_count = (out_urb->packets[i].length - 4)
- / (rt->out_n_analog << 2);
- *(dest++) = 0xaa;
- *(dest++) = 0xaa;
- *(dest++) = frame_count;
- *(dest++) = 0x00;
- for (frame = 0; frame < frame_count; frame++)
- for (channel = 0;
- channel < rt->out_n_analog;
- channel++) {
- dest += 3; /* skip sample data */
- *(dest++) = 0x40;
- }
- }
- usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
- usb_submit_urb(&in_urb->instance, GFP_ATOMIC);
-}
-
-static void usb6fire_pcm_out_urb_handler(struct urb *usb_urb)
-{
- struct pcm_urb *urb = usb_urb->context;
- struct pcm_runtime *rt = urb->chip->pcm;
-
- if (rt->stream_state == STREAM_STARTING) {
- rt->stream_wait_cond = true;
- wake_up(&rt->stream_wait_queue);
- }
-}
-
-static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- struct pcm_substream *sub = NULL;
- struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
-
- if (rt->panic)
- return -EPIPE;
-
- mutex_lock(&rt->stream_mutex);
- alsa_rt->hw = pcm_hw;
-
- if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- if (rt->rate < ARRAY_SIZE(rates))
- alsa_rt->hw.rates = rates_alsaid[rt->rate];
- alsa_rt->hw.channels_max = OUT_N_CHANNELS;
- sub = &rt->playback;
- } else if (alsa_sub->stream == SNDRV_PCM_STREAM_CAPTURE) {
- if (rt->rate < ARRAY_SIZE(rates))
- alsa_rt->hw.rates = rates_alsaid[rt->rate];
- alsa_rt->hw.channels_max = IN_N_CHANNELS;
- sub = &rt->capture;
- }
-
- if (!sub) {
- mutex_unlock(&rt->stream_mutex);
- snd_printk(KERN_ERR PREFIX "invalid stream type.\n");
- return -EINVAL;
- }
-
- sub->instance = alsa_sub;
- sub->active = false;
- mutex_unlock(&rt->stream_mutex);
- return 0;
-}
-
-static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- unsigned long flags;
-
- if (rt->panic)
- return 0;
-
- mutex_lock(&rt->stream_mutex);
- if (sub) {
- /* deactivate substream */
- spin_lock_irqsave(&sub->lock, flags);
- sub->instance = NULL;
- sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
-
- /* all substreams closed? if so, stop streaming */
- if (!rt->playback.instance && !rt->capture.instance) {
- usb6fire_pcm_stream_stop(rt);
- rt->rate = ARRAY_SIZE(rates);
- }
- }
- mutex_unlock(&rt->stream_mutex);
- return 0;
-}
-
-static int usb6fire_pcm_hw_params(struct snd_pcm_substream *alsa_sub,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(alsa_sub,
- params_buffer_bytes(hw_params));
-}
-
-static int usb6fire_pcm_hw_free(struct snd_pcm_substream *alsa_sub)
-{
- return snd_pcm_lib_free_pages(alsa_sub);
-}
-
-static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime;
- int ret;
-
- if (rt->panic)
- return -EPIPE;
- if (!sub)
- return -ENODEV;
-
- mutex_lock(&rt->stream_mutex);
- sub->dma_off = 0;
- sub->period_off = 0;
-
- if (rt->stream_state == STREAM_DISABLED) {
- for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++)
- if (alsa_rt->rate == rates[rt->rate])
- break;
- if (rt->rate == ARRAY_SIZE(rates)) {
- mutex_unlock(&rt->stream_mutex);
- snd_printk("invalid rate %d in prepare.\n",
- alsa_rt->rate);
- return -EINVAL;
- }
-
- ret = usb6fire_pcm_set_rate(rt);
- if (ret) {
- mutex_unlock(&rt->stream_mutex);
- return ret;
- }
- ret = usb6fire_pcm_stream_start(rt);
- if (ret) {
- mutex_unlock(&rt->stream_mutex);
- snd_printk(KERN_ERR PREFIX
- "could not start pcm stream.\n");
- return ret;
- }
- }
- mutex_unlock(&rt->stream_mutex);
- return 0;
-}
-
-static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
-{
- struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
-
- if (rt->panic)
- return -EPIPE;
- if (!sub)
- return -ENODEV;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- spin_lock_irqsave(&sub->lock, flags);
- sub->active = true;
- spin_unlock_irqrestore(&sub->lock, flags);
- return 0;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- spin_lock_irqsave(&sub->lock, flags);
- sub->active = false;
- spin_unlock_irqrestore(&sub->lock, flags);
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static snd_pcm_uframes_t usb6fire_pcm_pointer(
- struct snd_pcm_substream *alsa_sub)
-{
- struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
- struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
- unsigned long flags;
- snd_pcm_uframes_t ret;
-
- if (rt->panic || !sub)
- return SNDRV_PCM_STATE_XRUN;
-
- spin_lock_irqsave(&sub->lock, flags);
- ret = sub->dma_off;
- spin_unlock_irqrestore(&sub->lock, flags);
- return ret;
-}
-
-static struct snd_pcm_ops pcm_ops = {
- .open = usb6fire_pcm_open,
- .close = usb6fire_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = usb6fire_pcm_hw_params,
- .hw_free = usb6fire_pcm_hw_free,
- .prepare = usb6fire_pcm_prepare,
- .trigger = usb6fire_pcm_trigger,
- .pointer = usb6fire_pcm_pointer,
-};
-
-static void __devinit usb6fire_pcm_init_urb(struct pcm_urb *urb,
- struct sfire_chip *chip, bool in, int ep,
- void (*handler)(struct urb *))
-{
- urb->chip = chip;
- usb_init_urb(&urb->instance);
- urb->instance.transfer_buffer = urb->buffer;
- urb->instance.transfer_buffer_length =
- PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE;
- urb->instance.dev = chip->dev;
- urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep)
- : usb_sndisocpipe(chip->dev, ep);
- urb->instance.interval = 1;
- urb->instance.transfer_flags = URB_ISO_ASAP;
- urb->instance.complete = handler;
- urb->instance.context = urb;
- urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
-}
-
-int __devinit usb6fire_pcm_init(struct sfire_chip *chip)
-{
- int i;
- int ret;
- struct snd_pcm *pcm;
- struct pcm_runtime *rt =
- kzalloc(sizeof(struct pcm_runtime), GFP_KERNEL);
-
- if (!rt)
- return -ENOMEM;
-
- rt->chip = chip;
- rt->stream_state = STREAM_DISABLED;
- rt->rate = ARRAY_SIZE(rates);
- init_waitqueue_head(&rt->stream_wait_queue);
- mutex_init(&rt->stream_mutex);
-
- spin_lock_init(&rt->playback.lock);
- spin_lock_init(&rt->capture.lock);
-
- for (i = 0; i < PCM_N_URBS; i++) {
- usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
- usb6fire_pcm_in_urb_handler);
- usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
- usb6fire_pcm_out_urb_handler);
-
- rt->in_urbs[i].peer = &rt->out_urbs[i];
- rt->out_urbs[i].peer = &rt->in_urbs[i];
- }
-
- ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
- if (ret < 0) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX "cannot create pcm instance.\n");
- return ret;
- }
-
- pcm->private_data = rt;
- strcpy(pcm->name, "DMX 6Fire USB");
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_ops);
-
- ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- MAX_BUFSIZE, MAX_BUFSIZE);
- if (ret) {
- kfree(rt);
- snd_printk(KERN_ERR PREFIX
- "error preallocating pcm buffers.\n");
- return ret;
- }
- rt->instance = pcm;
-
- chip->pcm = rt;
- return 0;
-}
-
-void usb6fire_pcm_abort(struct sfire_chip *chip)
-{
- struct pcm_runtime *rt = chip->pcm;
- int i;
-
- if (rt) {
- rt->panic = true;
-
- if (rt->playback.instance)
- snd_pcm_stop(rt->playback.instance,
- SNDRV_PCM_STATE_XRUN);
- if (rt->capture.instance)
- snd_pcm_stop(rt->capture.instance,
- SNDRV_PCM_STATE_XRUN);
-
- for (i = 0; i < PCM_N_URBS; i++) {
- usb_poison_urb(&rt->in_urbs[i].instance);
- usb_poison_urb(&rt->out_urbs[i].instance);
- }
-
- }
-}
-
-void usb6fire_pcm_destroy(struct sfire_chip *chip)
-{
- kfree(chip->pcm);
- chip->pcm = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/6fire/pcm.h b/ANDROID_3.4.5/sound/usb/6fire/pcm.h
deleted file mode 100644
index 3104301b..00000000
--- a/ANDROID_3.4.5/sound/usb/6fire/pcm.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Linux driver for TerraTec DMX 6Fire USB
- *
- * Author: Torsten Schenk <torsten.schenk@zoho.com>
- * Created: Jan 01, 2011
- * Copyright: (C) Torsten Schenk
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef USB6FIRE_PCM_H
-#define USB6FIRE_PCM_H
-
-#include <sound/pcm.h>
-#include <linux/mutex.h>
-
-#include "common.h"
-
-enum /* settings for pcm */
-{
- /* maximum of EP_W_MAX_PACKET_SIZE[] (see firmware.c) */
- PCM_N_URBS = 16, PCM_N_PACKETS_PER_URB = 8, PCM_MAX_PACKET_SIZE = 604
-};
-
-struct pcm_urb {
- struct sfire_chip *chip;
-
- /* BEGIN DO NOT SEPARATE */
- struct urb instance;
- struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
- /* END DO NOT SEPARATE */
- u8 buffer[PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE];
-
- struct pcm_urb *peer;
-};
-
-struct pcm_substream {
- spinlock_t lock;
- struct snd_pcm_substream *instance;
-
- bool active;
-
- snd_pcm_uframes_t dma_off; /* current position in alsa dma_area */
- snd_pcm_uframes_t period_off; /* current position in current period */
-};
-
-struct pcm_runtime {
- struct sfire_chip *chip;
- struct snd_pcm *instance;
-
- struct pcm_substream playback;
- struct pcm_substream capture;
- bool panic; /* if set driver won't do anymore pcm on device */
-
- struct pcm_urb in_urbs[PCM_N_URBS];
- struct pcm_urb out_urbs[PCM_N_URBS];
- int in_packet_size;
- int out_packet_size;
- int in_n_analog; /* number of analog channels soundcard sends */
- int out_n_analog; /* number of analog channels soundcard receives */
-
- struct mutex stream_mutex;
- u8 stream_state; /* one of STREAM_XXX (pcm.c) */
- u8 rate; /* one of PCM_RATE_XXX */
- wait_queue_head_t stream_wait_queue;
- bool stream_wait_cond;
-};
-
-int __devinit usb6fire_pcm_init(struct sfire_chip *chip);
-void usb6fire_pcm_abort(struct sfire_chip *chip);
-void usb6fire_pcm_destroy(struct sfire_chip *chip);
-#endif /* USB6FIRE_PCM_H */
diff --git a/ANDROID_3.4.5/sound/usb/Kconfig b/ANDROID_3.4.5/sound/usb/Kconfig
deleted file mode 100644
index ff77b28f..00000000
--- a/ANDROID_3.4.5/sound/usb/Kconfig
+++ /dev/null
@@ -1,119 +0,0 @@
-# ALSA USB drivers
-
-menuconfig SND_USB
- bool "USB sound devices"
- depends on USB
- default y
- help
- Support for sound devices connected via the USB bus.
-
-if SND_USB && USB
-
-config SND_USB_AUDIO
- tristate "USB Audio/MIDI driver"
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for USB audio and USB MIDI
- devices.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-usb-audio.
-
-config SND_USB_UA101
- tristate "Edirol UA-101/UA-1000 driver"
- select SND_PCM
- select SND_RAWMIDI
- help
- Say Y here to include support for the Edirol UA-101 and UA-1000
- audio/MIDI interfaces.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-ua101.
-
-config SND_USB_USX2Y
- tristate "Tascam US-122, US-224 and US-428 USB driver"
- depends on X86 || PPC || ALPHA
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for Tascam USB Audio/MIDI
- interfaces or controllers US-122, US-224 and US-428.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-usb-usx2y.
-
-config SND_USB_CAIAQ
- tristate "Native Instruments USB audio devices"
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_PCM
- help
- Say Y here to include support for caiaq USB audio interfaces,
- namely:
-
- * Native Instruments RigKontrol2
- * Native Instruments RigKontrol3
- * Native Instruments Kore Controller
- * Native Instruments Kore Controller 2
- * Native Instruments Audio Kontrol 1
- * Native Instruments Audio 2 DJ
- * Native Instruments Audio 4 DJ
- * Native Instruments Audio 8 DJ
- * Native Instruments Traktor Audio 2
- * Native Instruments Guitar Rig Session I/O
- * Native Instruments Guitar Rig mobile
- * Native Instruments Traktor Kontrol X1
- * Native Instruments Traktor Kontrol S4
- * Native Instruments Maschine Controller
-
- To compile this driver as a module, choose M here: the module
- will be called snd-usb-caiaq.
-
-config SND_USB_CAIAQ_INPUT
- bool "enable input device for controllers"
- depends on SND_USB_CAIAQ
- depends on INPUT=y || INPUT=SND_USB_CAIAQ
- help
- Say Y here to support input controllers like buttons, knobs,
- alpha dials and analog pedals on the following products:
-
- * Native Instruments RigKontrol2
- * Native Instruments RigKontrol3
- * Native Instruments Kore Controller
- * Native Instruments Kore Controller 2
- * Native Instruments Audio Kontrol 1
- * Native Instruments Traktor Kontrol S4
- * Native Instruments Maschine Controller
-
-config SND_USB_US122L
- tristate "Tascam US-122L USB driver"
- depends on X86 && EXPERIMENTAL
- select SND_HWDEP
- select SND_RAWMIDI
- help
- Say Y here to include support for Tascam US-122L USB Audio/MIDI
- interfaces.
-
- To compile this driver as a module, choose M here: the module
- will be called snd-usb-us122l.
-
-config SND_USB_6FIRE
- tristate "TerraTec DMX 6Fire USB"
- select FW_LOADER
- select BITREVERSE
- select SND_RAWMIDI
- select SND_PCM
- select SND_VMASTER
- help
- Say Y here to include support for TerraTec 6fire DMX USB interface.
-
- You will need firmware files in order to be able to use the device
- after it has been coldstarted. An install script for the firmware
- and further help can be found at
- http://sixfireusb.sourceforge.net
-
-endif # SND_USB
-
diff --git a/ANDROID_3.4.5/sound/usb/Makefile b/ANDROID_3.4.5/sound/usb/Makefile
deleted file mode 100644
index ac256dc4..00000000
--- a/ANDROID_3.4.5/sound/usb/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Makefile for ALSA
-#
-
-snd-usb-audio-objs := card.o \
- clock.o \
- endpoint.o \
- format.o \
- helper.o \
- mixer.o \
- mixer_quirks.o \
- pcm.o \
- proc.o \
- quirks.o \
- stream.o
-
-snd-usbmidi-lib-objs := midi.o
-
-# Toplevel Module Dependency
-obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usbmidi-lib.o
-
-obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o
-obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o
-obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o
-
-obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/Makefile b/ANDROID_3.4.5/sound/usb/caiaq/Makefile
deleted file mode 100644
index 38899965..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-snd-usb-caiaq-y := device.o audio.o midi.o control.o
-snd-usb-caiaq-$(CONFIG_SND_USB_CAIAQ_INPUT) += input.o
-
-obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/audio.c b/ANDROID_3.4.5/sound/usb/caiaq/audio.c
deleted file mode 100644
index fde9a7a2..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/audio.c
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * Copyright (c) 2006-2008 Daniel Mack, Karsten Wiese
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "audio.h"
-
-#define N_URBS 32
-#define CLOCK_DRIFT_TOLERANCE 5
-#define FRAMES_PER_URB 8
-#define BYTES_PER_FRAME 512
-#define CHANNELS_PER_STREAM 2
-#define BYTES_PER_SAMPLE 3
-#define BYTES_PER_SAMPLE_USB 4
-#define MAX_BUFFER_SIZE (128*1024)
-#define MAX_ENDPOINT_SIZE 512
-
-#define ENDPOINT_CAPTURE 2
-#define ENDPOINT_PLAYBACK 6
-
-#define MAKE_CHECKBYTE(dev,stream,i) \
- (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1)
-
-static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = {
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER),
- .formats = SNDRV_PCM_FMTBIT_S24_3BE,
- .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_96000),
- .rate_min = 44100,
- .rate_max = 0, /* will overwrite later */
- .channels_min = CHANNELS_PER_STREAM,
- .channels_max = CHANNELS_PER_STREAM,
- .buffer_bytes_max = MAX_BUFFER_SIZE,
- .period_bytes_min = 128,
- .period_bytes_max = MAX_BUFFER_SIZE,
- .periods_min = 1,
- .periods_max = 1024,
-};
-
-static void
-activate_substream(struct snd_usb_caiaqdev *dev,
- struct snd_pcm_substream *sub)
-{
- spin_lock(&dev->spinlock);
-
- if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dev->sub_playback[sub->number] = sub;
- else
- dev->sub_capture[sub->number] = sub;
-
- spin_unlock(&dev->spinlock);
-}
-
-static void
-deactivate_substream(struct snd_usb_caiaqdev *dev,
- struct snd_pcm_substream *sub)
-{
- unsigned long flags;
- spin_lock_irqsave(&dev->spinlock, flags);
-
- if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dev->sub_playback[sub->number] = NULL;
- else
- dev->sub_capture[sub->number] = NULL;
-
- spin_unlock_irqrestore(&dev->spinlock, flags);
-}
-
-static int
-all_substreams_zero(struct snd_pcm_substream **subs)
-{
- int i;
- for (i = 0; i < MAX_STREAMS; i++)
- if (subs[i] != NULL)
- return 0;
- return 1;
-}
-
-static int stream_start(struct snd_usb_caiaqdev *dev)
-{
- int i, ret;
-
- debug("%s(%p)\n", __func__, dev);
-
- if (dev->streaming)
- return -EINVAL;
-
- memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
- memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
- dev->input_panic = 0;
- dev->output_panic = 0;
- dev->first_packet = 4;
- dev->streaming = 1;
- dev->warned = 0;
-
- for (i = 0; i < N_URBS; i++) {
- ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC);
- if (ret) {
- log("unable to trigger read #%d! (ret %d)\n", i, ret);
- dev->streaming = 0;
- return -EPIPE;
- }
- }
-
- return 0;
-}
-
-static void stream_stop(struct snd_usb_caiaqdev *dev)
-{
- int i;
-
- debug("%s(%p)\n", __func__, dev);
- if (!dev->streaming)
- return;
-
- dev->streaming = 0;
-
- for (i = 0; i < N_URBS; i++) {
- usb_kill_urb(dev->data_urbs_in[i]);
-
- if (test_bit(i, &dev->outurb_active_mask))
- usb_kill_urb(dev->data_urbs_out[i]);
- }
-
- dev->outurb_active_mask = 0;
-}
-
-static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream)
-{
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
- debug("%s(%p)\n", __func__, substream);
- substream->runtime->hw = dev->pcm_info;
- snd_pcm_limit_hw_rates(substream->runtime);
- return 0;
-}
-
-static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
-{
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
-
- debug("%s(%p)\n", __func__, substream);
- if (all_substreams_zero(dev->sub_playback) &&
- all_substreams_zero(dev->sub_capture)) {
- /* when the last client has stopped streaming,
- * all sample rates are allowed again */
- stream_stop(dev);
- dev->pcm_info.rates = dev->samplerates;
- }
-
- return 0;
-}
-
-static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
- struct snd_pcm_hw_params *hw_params)
-{
- debug("%s(%p)\n", __func__, sub);
- return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params));
-}
-
-static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
-{
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
- debug("%s(%p)\n", __func__, sub);
- deactivate_substream(dev, sub);
- return snd_pcm_lib_free_pages(sub);
-}
-
-/* this should probably go upstream */
-#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
-#error "Change this table"
-#endif
-
-static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
- 48000, 64000, 88200, 96000, 176400, 192000 };
-
-static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
-{
- int bytes_per_sample, bpp, ret, i;
- int index = substream->number;
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- debug("%s(%p)\n", __func__, substream);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- int out_pos;
-
- switch (dev->spec.data_alignment) {
- case 0:
- case 2:
- out_pos = BYTES_PER_SAMPLE + 1;
- break;
- case 3:
- default:
- out_pos = 0;
- break;
- }
-
- dev->period_out_count[index] = out_pos;
- dev->audio_out_buf_pos[index] = out_pos;
- } else {
- int in_pos;
-
- switch (dev->spec.data_alignment) {
- case 0:
- in_pos = BYTES_PER_SAMPLE + 2;
- break;
- case 2:
- in_pos = BYTES_PER_SAMPLE;
- break;
- case 3:
- default:
- in_pos = 0;
- break;
- }
-
- dev->period_in_count[index] = in_pos;
- dev->audio_in_buf_pos[index] = in_pos;
- }
-
- if (dev->streaming)
- return 0;
-
- /* the first client that opens a stream defines the sample rate
- * setting for all subsequent calls, until the last client closed. */
- for (i=0; i < ARRAY_SIZE(rates); i++)
- if (runtime->rate == rates[i])
- dev->pcm_info.rates = 1 << i;
-
- snd_pcm_limit_hw_rates(runtime);
-
- bytes_per_sample = BYTES_PER_SAMPLE;
- if (dev->spec.data_alignment >= 2)
- bytes_per_sample++;
-
- bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
- * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams;
-
- if (bpp > MAX_ENDPOINT_SIZE)
- bpp = MAX_ENDPOINT_SIZE;
-
- ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate,
- runtime->sample_bits, bpp);
- if (ret)
- return ret;
-
- ret = stream_start(dev);
- if (ret)
- return ret;
-
- dev->output_running = 0;
- wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ);
- if (!dev->output_running) {
- stream_stop(dev);
- return -EPIPE;
- }
-
- return 0;
-}
-
-static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
-{
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
-
- debug("%s(%p) cmd %d\n", __func__, sub, cmd);
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- activate_substream(dev, sub);
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- deactivate_substream(dev, sub);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static snd_pcm_uframes_t
-snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
-{
- int index = sub->number;
- struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
- snd_pcm_uframes_t ptr;
-
- spin_lock(&dev->spinlock);
-
- if (dev->input_panic || dev->output_panic) {
- ptr = SNDRV_PCM_POS_XRUN;
- goto unlock;
- }
-
- if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
- ptr = bytes_to_frames(sub->runtime,
- dev->audio_out_buf_pos[index]);
- else
- ptr = bytes_to_frames(sub->runtime,
- dev->audio_in_buf_pos[index]);
-
-unlock:
- spin_unlock(&dev->spinlock);
- return ptr;
-}
-
-/* operators for both playback and capture */
-static struct snd_pcm_ops snd_usb_caiaq_ops = {
- .open = snd_usb_caiaq_substream_open,
- .close = snd_usb_caiaq_substream_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usb_caiaq_pcm_hw_params,
- .hw_free = snd_usb_caiaq_pcm_hw_free,
- .prepare = snd_usb_caiaq_pcm_prepare,
- .trigger = snd_usb_caiaq_pcm_trigger,
- .pointer = snd_usb_caiaq_pcm_pointer
-};
-
-static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev,
- struct snd_pcm_substream **subs)
-{
- int stream, pb, *cnt;
- struct snd_pcm_substream *sub;
-
- for (stream = 0; stream < dev->n_streams; stream++) {
- sub = subs[stream];
- if (!sub)
- continue;
-
- pb = snd_pcm_lib_period_bytes(sub);
- cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
- &dev->period_out_count[stream] :
- &dev->period_in_count[stream];
-
- if (*cnt >= pb) {
- snd_pcm_period_elapsed(sub);
- *cnt %= pb;
- }
- }
-}
-
-static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev,
- const struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- struct snd_pcm_substream *sub;
- int stream, i;
-
- if (all_substreams_zero(dev->sub_capture))
- return;
-
- for (i = 0; i < iso->actual_length;) {
- for (stream = 0; stream < dev->n_streams; stream++, i++) {
- sub = dev->sub_capture[stream];
- if (sub) {
- struct snd_pcm_runtime *rt = sub->runtime;
- char *audio_buf = rt->dma_area;
- int sz = frames_to_bytes(rt, rt->buffer_size);
- audio_buf[dev->audio_in_buf_pos[stream]++]
- = usb_buf[i];
- dev->period_in_count[stream]++;
- if (dev->audio_in_buf_pos[stream] == sz)
- dev->audio_in_buf_pos[stream] = 0;
- }
- }
- }
-}
-
-static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev,
- const struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- unsigned char check_byte;
- struct snd_pcm_substream *sub;
- int stream, i;
-
- for (i = 0; i < iso->actual_length;) {
- if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) {
- for (stream = 0;
- stream < dev->n_streams;
- stream++, i++) {
- if (dev->first_packet)
- continue;
-
- check_byte = MAKE_CHECKBYTE(dev, stream, i);
-
- if ((usb_buf[i] & 0x3f) != check_byte)
- dev->input_panic = 1;
-
- if (usb_buf[i] & 0x80)
- dev->output_panic = 1;
- }
- }
- dev->first_packet = 0;
-
- for (stream = 0; stream < dev->n_streams; stream++, i++) {
- sub = dev->sub_capture[stream];
- if (dev->input_panic)
- usb_buf[i] = 0;
-
- if (sub) {
- struct snd_pcm_runtime *rt = sub->runtime;
- char *audio_buf = rt->dma_area;
- int sz = frames_to_bytes(rt, rt->buffer_size);
- audio_buf[dev->audio_in_buf_pos[stream]++] =
- usb_buf[i];
- dev->period_in_count[stream]++;
- if (dev->audio_in_buf_pos[stream] == sz)
- dev->audio_in_buf_pos[stream] = 0;
- }
- }
- }
-}
-
-static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev,
- const struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- int stream, i;
-
- /* paranoia check */
- if (iso->actual_length % (BYTES_PER_SAMPLE_USB * CHANNELS_PER_STREAM))
- return;
-
- for (i = 0; i < iso->actual_length;) {
- for (stream = 0; stream < dev->n_streams; stream++) {
- struct snd_pcm_substream *sub = dev->sub_capture[stream];
- char *audio_buf = NULL;
- int c, n, sz = 0;
-
- if (sub && !dev->input_panic) {
- struct snd_pcm_runtime *rt = sub->runtime;
- audio_buf = rt->dma_area;
- sz = frames_to_bytes(rt, rt->buffer_size);
- }
-
- for (c = 0; c < CHANNELS_PER_STREAM; c++) {
- /* 3 audio data bytes, followed by 1 check byte */
- if (audio_buf) {
- for (n = 0; n < BYTES_PER_SAMPLE; n++) {
- audio_buf[dev->audio_in_buf_pos[stream]++] = usb_buf[i+n];
-
- if (dev->audio_in_buf_pos[stream] == sz)
- dev->audio_in_buf_pos[stream] = 0;
- }
-
- dev->period_in_count[stream] += BYTES_PER_SAMPLE;
- }
-
- i += BYTES_PER_SAMPLE;
-
- if (usb_buf[i] != ((stream << 1) | c) &&
- !dev->first_packet) {
- if (!dev->input_panic)
- printk(" EXPECTED: %02x got %02x, c %d, stream %d, i %d\n",
- ((stream << 1) | c), usb_buf[i], c, stream, i);
- dev->input_panic = 1;
- }
-
- i++;
- }
- }
- }
-
- if (dev->first_packet > 0)
- dev->first_packet--;
-}
-
-static void read_in_urb(struct snd_usb_caiaqdev *dev,
- const struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- if (!dev->streaming)
- return;
-
- if (iso->actual_length < dev->bpp)
- return;
-
- switch (dev->spec.data_alignment) {
- case 0:
- read_in_urb_mode0(dev, urb, iso);
- break;
- case 2:
- read_in_urb_mode2(dev, urb, iso);
- break;
- case 3:
- read_in_urb_mode3(dev, urb, iso);
- break;
- }
-
- if ((dev->input_panic || dev->output_panic) && !dev->warned) {
- debug("streaming error detected %s %s\n",
- dev->input_panic ? "(input)" : "",
- dev->output_panic ? "(output)" : "");
- dev->warned = 1;
- }
-}
-
-static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev,
- struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- struct snd_pcm_substream *sub;
- int stream, i;
-
- for (i = 0; i < iso->length;) {
- for (stream = 0; stream < dev->n_streams; stream++, i++) {
- sub = dev->sub_playback[stream];
- if (sub) {
- struct snd_pcm_runtime *rt = sub->runtime;
- char *audio_buf = rt->dma_area;
- int sz = frames_to_bytes(rt, rt->buffer_size);
- usb_buf[i] =
- audio_buf[dev->audio_out_buf_pos[stream]];
- dev->period_out_count[stream]++;
- dev->audio_out_buf_pos[stream]++;
- if (dev->audio_out_buf_pos[stream] == sz)
- dev->audio_out_buf_pos[stream] = 0;
- } else
- usb_buf[i] = 0;
- }
-
- /* fill in the check bytes */
- if (dev->spec.data_alignment == 2 &&
- i % (dev->n_streams * BYTES_PER_SAMPLE_USB) ==
- (dev->n_streams * CHANNELS_PER_STREAM))
- for (stream = 0; stream < dev->n_streams; stream++, i++)
- usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i);
- }
-}
-
-static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev,
- struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
- int stream, i;
-
- for (i = 0; i < iso->length;) {
- for (stream = 0; stream < dev->n_streams; stream++) {
- struct snd_pcm_substream *sub = dev->sub_playback[stream];
- char *audio_buf = NULL;
- int c, n, sz = 0;
-
- if (sub) {
- struct snd_pcm_runtime *rt = sub->runtime;
- audio_buf = rt->dma_area;
- sz = frames_to_bytes(rt, rt->buffer_size);
- }
-
- for (c = 0; c < CHANNELS_PER_STREAM; c++) {
- for (n = 0; n < BYTES_PER_SAMPLE; n++) {
- if (audio_buf) {
- usb_buf[i+n] = audio_buf[dev->audio_out_buf_pos[stream]++];
-
- if (dev->audio_out_buf_pos[stream] == sz)
- dev->audio_out_buf_pos[stream] = 0;
- } else {
- usb_buf[i+n] = 0;
- }
- }
-
- if (audio_buf)
- dev->period_out_count[stream] += BYTES_PER_SAMPLE;
-
- i += BYTES_PER_SAMPLE;
-
- /* fill in the check byte pattern */
- usb_buf[i++] = (stream << 1) | c;
- }
- }
- }
-}
-
-static inline void fill_out_urb(struct snd_usb_caiaqdev *dev,
- struct urb *urb,
- const struct usb_iso_packet_descriptor *iso)
-{
- switch (dev->spec.data_alignment) {
- case 0:
- case 2:
- fill_out_urb_mode_0(dev, urb, iso);
- break;
- case 3:
- fill_out_urb_mode_3(dev, urb, iso);
- break;
- }
-}
-
-static void read_completed(struct urb *urb)
-{
- struct snd_usb_caiaq_cb_info *info = urb->context;
- struct snd_usb_caiaqdev *dev;
- struct urb *out = NULL;
- int i, frame, len, send_it = 0, outframe = 0;
- size_t offset = 0;
-
- if (urb->status || !info)
- return;
-
- dev = info->dev;
-
- if (!dev->streaming)
- return;
-
- /* find an unused output urb that is unused */
- for (i = 0; i < N_URBS; i++)
- if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) {
- out = dev->data_urbs_out[i];
- break;
- }
-
- if (!out) {
- log("Unable to find an output urb to use\n");
- goto requeue;
- }
-
- /* read the recently received packet and send back one which has
- * the same layout */
- for (frame = 0; frame < FRAMES_PER_URB; frame++) {
- if (urb->iso_frame_desc[frame].status)
- continue;
-
- len = urb->iso_frame_desc[outframe].actual_length;
- out->iso_frame_desc[outframe].length = len;
- out->iso_frame_desc[outframe].actual_length = 0;
- out->iso_frame_desc[outframe].offset = offset;
- offset += len;
-
- if (len > 0) {
- spin_lock(&dev->spinlock);
- fill_out_urb(dev, out, &out->iso_frame_desc[outframe]);
- read_in_urb(dev, urb, &urb->iso_frame_desc[frame]);
- spin_unlock(&dev->spinlock);
- check_for_elapsed_periods(dev, dev->sub_playback);
- check_for_elapsed_periods(dev, dev->sub_capture);
- send_it = 1;
- }
-
- outframe++;
- }
-
- if (send_it) {
- out->number_of_packets = outframe;
- out->transfer_flags = URB_ISO_ASAP;
- usb_submit_urb(out, GFP_ATOMIC);
- } else {
- struct snd_usb_caiaq_cb_info *oinfo = out->context;
- clear_bit(oinfo->index, &dev->outurb_active_mask);
- }
-
-requeue:
- /* re-submit inbound urb */
- for (frame = 0; frame < FRAMES_PER_URB; frame++) {
- urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame;
- urb->iso_frame_desc[frame].length = BYTES_PER_FRAME;
- urb->iso_frame_desc[frame].actual_length = 0;
- }
-
- urb->number_of_packets = FRAMES_PER_URB;
- urb->transfer_flags = URB_ISO_ASAP;
- usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-static void write_completed(struct urb *urb)
-{
- struct snd_usb_caiaq_cb_info *info = urb->context;
- struct snd_usb_caiaqdev *dev = info->dev;
-
- if (!dev->output_running) {
- dev->output_running = 1;
- wake_up(&dev->prepare_wait_queue);
- }
-
- clear_bit(info->index, &dev->outurb_active_mask);
-}
-
-static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret)
-{
- int i, frame;
- struct urb **urbs;
- struct usb_device *usb_dev = dev->chip.dev;
- unsigned int pipe;
-
- pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ?
- usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) :
- usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE);
-
- urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL);
- if (!urbs) {
- log("unable to kmalloc() urbs, OOM!?\n");
- *ret = -ENOMEM;
- return NULL;
- }
-
- for (i = 0; i < N_URBS; i++) {
- urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL);
- if (!urbs[i]) {
- log("unable to usb_alloc_urb(), OOM!?\n");
- *ret = -ENOMEM;
- return urbs;
- }
-
- urbs[i]->transfer_buffer =
- kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL);
- if (!urbs[i]->transfer_buffer) {
- log("unable to kmalloc() transfer buffer, OOM!?\n");
- *ret = -ENOMEM;
- return urbs;
- }
-
- for (frame = 0; frame < FRAMES_PER_URB; frame++) {
- struct usb_iso_packet_descriptor *iso =
- &urbs[i]->iso_frame_desc[frame];
-
- iso->offset = BYTES_PER_FRAME * frame;
- iso->length = BYTES_PER_FRAME;
- }
-
- urbs[i]->dev = usb_dev;
- urbs[i]->pipe = pipe;
- urbs[i]->transfer_buffer_length = FRAMES_PER_URB
- * BYTES_PER_FRAME;
- urbs[i]->context = &dev->data_cb_info[i];
- urbs[i]->interval = 1;
- urbs[i]->transfer_flags = URB_ISO_ASAP;
- urbs[i]->number_of_packets = FRAMES_PER_URB;
- urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ?
- read_completed : write_completed;
- }
-
- *ret = 0;
- return urbs;
-}
-
-static void free_urbs(struct urb **urbs)
-{
- int i;
-
- if (!urbs)
- return;
-
- for (i = 0; i < N_URBS; i++) {
- if (!urbs[i])
- continue;
-
- usb_kill_urb(urbs[i]);
- kfree(urbs[i]->transfer_buffer);
- usb_free_urb(urbs[i]);
- }
-
- kfree(urbs);
-}
-
-int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
-{
- int i, ret;
-
- dev->n_audio_in = max(dev->spec.num_analog_audio_in,
- dev->spec.num_digital_audio_in) /
- CHANNELS_PER_STREAM;
- dev->n_audio_out = max(dev->spec.num_analog_audio_out,
- dev->spec.num_digital_audio_out) /
- CHANNELS_PER_STREAM;
- dev->n_streams = max(dev->n_audio_in, dev->n_audio_out);
-
- debug("dev->n_audio_in = %d\n", dev->n_audio_in);
- debug("dev->n_audio_out = %d\n", dev->n_audio_out);
- debug("dev->n_streams = %d\n", dev->n_streams);
-
- if (dev->n_streams > MAX_STREAMS) {
- log("unable to initialize device, too many streams.\n");
- return -EINVAL;
- }
-
- ret = snd_pcm_new(dev->chip.card, dev->product_name, 0,
- dev->n_audio_out, dev->n_audio_in, &dev->pcm);
-
- if (ret < 0) {
- log("snd_pcm_new() returned %d\n", ret);
- return ret;
- }
-
- dev->pcm->private_data = dev;
- strlcpy(dev->pcm->name, dev->product_name, sizeof(dev->pcm->name));
-
- memset(dev->sub_playback, 0, sizeof(dev->sub_playback));
- memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
-
- memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware,
- sizeof(snd_usb_caiaq_pcm_hardware));
-
- /* setup samplerates */
- dev->samplerates = dev->pcm_info.rates;
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_SESSIONIO):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE):
- dev->samplerates |= SNDRV_PCM_RATE_192000;
- /* fall thru */
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORAUDIO2):
- dev->samplerates |= SNDRV_PCM_RATE_88200;
- break;
- }
-
- snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
- &snd_usb_caiaq_ops);
- snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
- &snd_usb_caiaq_ops);
-
- snd_pcm_lib_preallocate_pages_for_all(dev->pcm,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
-
- dev->data_cb_info =
- kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS,
- GFP_KERNEL);
-
- if (!dev->data_cb_info)
- return -ENOMEM;
-
- dev->outurb_active_mask = 0;
- BUILD_BUG_ON(N_URBS > (sizeof(dev->outurb_active_mask) * 8));
-
- for (i = 0; i < N_URBS; i++) {
- dev->data_cb_info[i].dev = dev;
- dev->data_cb_info[i].index = i;
- }
-
- dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret);
- if (ret < 0) {
- kfree(dev->data_cb_info);
- free_urbs(dev->data_urbs_in);
- return ret;
- }
-
- dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret);
- if (ret < 0) {
- kfree(dev->data_cb_info);
- free_urbs(dev->data_urbs_in);
- free_urbs(dev->data_urbs_out);
- return ret;
- }
-
- return 0;
-}
-
-void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev)
-{
- debug("%s(%p)\n", __func__, dev);
- stream_stop(dev);
- free_urbs(dev->data_urbs_in);
- free_urbs(dev->data_urbs_out);
- kfree(dev->data_cb_info);
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/audio.h b/ANDROID_3.4.5/sound/usb/caiaq/audio.h
deleted file mode 100644
index 8ab1f8d9..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/audio.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef CAIAQ_AUDIO_H
-#define CAIAQ_AUDIO_H
-
-int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev);
-void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev);
-
-#endif /* CAIAQ_AUDIO_H */
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/control.c b/ANDROID_3.4.5/sound/usb/caiaq/control.c
deleted file mode 100644
index 00e5d0a4..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/control.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) 2007 Daniel Mack
- * friendly supported by NI.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "control.h"
-
-#define CNT_INTVAL 0x10000
-
-static int control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
- struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
- int pos = kcontrol->private_value;
- int is_intval = pos & CNT_INTVAL;
- int maxval = 63;
-
- uinfo->count = 1;
- pos &= ~CNT_INTVAL;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
- if (pos == 0) {
- /* current input mode of A8DJ and A4DJ */
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 2;
- return 0;
- }
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- maxval = 127;
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- maxval = 31;
- break;
- }
-
- if (is_intval) {
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = maxval;
- } else {
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- }
-
- return 0;
-}
-
-static int control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
- struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
- int pos = kcontrol->private_value;
-
- if (pos & CNT_INTVAL)
- ucontrol->value.integer.value[0]
- = dev->control_state[pos & ~CNT_INTVAL];
- else
- ucontrol->value.integer.value[0]
- = !!(dev->control_state[pos / 8] & (1 << pos % 8));
-
- return 0;
-}
-
-static int control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
- struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
- int pos = kcontrol->private_value;
- int v = ucontrol->value.integer.value[0];
- unsigned char cmd = EP1_CMD_WRITE_IO;
-
- if (dev->chip.usb_id ==
- USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1))
- cmd = EP1_CMD_DIMM_LEDS;
-
- if (pos & CNT_INTVAL) {
- int i = pos & ~CNT_INTVAL;
-
- dev->control_state[i] = v;
-
- if (dev->chip.usb_id ==
- USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4)) {
- int actual_len;
-
- dev->ep8_out_buf[0] = i;
- dev->ep8_out_buf[1] = v;
-
- usb_bulk_msg(dev->chip.dev,
- usb_sndbulkpipe(dev->chip.dev, 8),
- dev->ep8_out_buf, sizeof(dev->ep8_out_buf),
- &actual_len, 200);
- } else {
- snd_usb_caiaq_send_command(dev, cmd,
- dev->control_state, sizeof(dev->control_state));
- }
- } else {
- if (v)
- dev->control_state[pos / 8] |= 1 << (pos % 8);
- else
- dev->control_state[pos / 8] &= ~(1 << (pos % 8));
-
- snd_usb_caiaq_send_command(dev, cmd,
- dev->control_state, sizeof(dev->control_state));
- }
-
- return 1;
-}
-
-static struct snd_kcontrol_new kcontrol_template __devinitdata = {
- .iface = SNDRV_CTL_ELEM_IFACE_HWDEP,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .index = 0,
- .info = control_info,
- .get = control_get,
- .put = control_put,
- /* name and private_value filled later */
-};
-
-struct caiaq_controller {
- char *name;
- int index;
-};
-
-static struct caiaq_controller ak1_controller[] = {
- { "LED left", 2 },
- { "LED middle", 1 },
- { "LED right", 0 },
- { "LED ring", 3 }
-};
-
-static struct caiaq_controller rk2_controller[] = {
- { "LED 1", 5 },
- { "LED 2", 4 },
- { "LED 3", 3 },
- { "LED 4", 2 },
- { "LED 5", 1 },
- { "LED 6", 0 },
- { "LED pedal", 6 },
- { "LED 7seg_1b", 8 },
- { "LED 7seg_1c", 9 },
- { "LED 7seg_2a", 10 },
- { "LED 7seg_2b", 11 },
- { "LED 7seg_2c", 12 },
- { "LED 7seg_2d", 13 },
- { "LED 7seg_2e", 14 },
- { "LED 7seg_2f", 15 },
- { "LED 7seg_2g", 16 },
- { "LED 7seg_3a", 17 },
- { "LED 7seg_3b", 18 },
- { "LED 7seg_3c", 19 },
- { "LED 7seg_3d", 20 },
- { "LED 7seg_3e", 21 },
- { "LED 7seg_3f", 22 },
- { "LED 7seg_3g", 23 }
-};
-
-static struct caiaq_controller rk3_controller[] = {
- { "LED 7seg_1a", 0 + 0 },
- { "LED 7seg_1b", 0 + 1 },
- { "LED 7seg_1c", 0 + 2 },
- { "LED 7seg_1d", 0 + 3 },
- { "LED 7seg_1e", 0 + 4 },
- { "LED 7seg_1f", 0 + 5 },
- { "LED 7seg_1g", 0 + 6 },
- { "LED 7seg_1p", 0 + 7 },
-
- { "LED 7seg_2a", 8 + 0 },
- { "LED 7seg_2b", 8 + 1 },
- { "LED 7seg_2c", 8 + 2 },
- { "LED 7seg_2d", 8 + 3 },
- { "LED 7seg_2e", 8 + 4 },
- { "LED 7seg_2f", 8 + 5 },
- { "LED 7seg_2g", 8 + 6 },
- { "LED 7seg_2p", 8 + 7 },
-
- { "LED 7seg_3a", 16 + 0 },
- { "LED 7seg_3b", 16 + 1 },
- { "LED 7seg_3c", 16 + 2 },
- { "LED 7seg_3d", 16 + 3 },
- { "LED 7seg_3e", 16 + 4 },
- { "LED 7seg_3f", 16 + 5 },
- { "LED 7seg_3g", 16 + 6 },
- { "LED 7seg_3p", 16 + 7 },
-
- { "LED 7seg_4a", 24 + 0 },
- { "LED 7seg_4b", 24 + 1 },
- { "LED 7seg_4c", 24 + 2 },
- { "LED 7seg_4d", 24 + 3 },
- { "LED 7seg_4e", 24 + 4 },
- { "LED 7seg_4f", 24 + 5 },
- { "LED 7seg_4g", 24 + 6 },
- { "LED 7seg_4p", 24 + 7 },
-
- { "LED 1", 32 + 0 },
- { "LED 2", 32 + 1 },
- { "LED 3", 32 + 2 },
- { "LED 4", 32 + 3 },
- { "LED 5", 32 + 4 },
- { "LED 6", 32 + 5 },
- { "LED 7", 32 + 6 },
- { "LED 8", 32 + 7 },
- { "LED pedal", 32 + 8 }
-};
-
-static struct caiaq_controller kore_controller[] = {
- { "LED F1", 8 | CNT_INTVAL },
- { "LED F2", 12 | CNT_INTVAL },
- { "LED F3", 0 | CNT_INTVAL },
- { "LED F4", 4 | CNT_INTVAL },
- { "LED F5", 11 | CNT_INTVAL },
- { "LED F6", 15 | CNT_INTVAL },
- { "LED F7", 3 | CNT_INTVAL },
- { "LED F8", 7 | CNT_INTVAL },
- { "LED touch1", 10 | CNT_INTVAL },
- { "LED touch2", 14 | CNT_INTVAL },
- { "LED touch3", 2 | CNT_INTVAL },
- { "LED touch4", 6 | CNT_INTVAL },
- { "LED touch5", 9 | CNT_INTVAL },
- { "LED touch6", 13 | CNT_INTVAL },
- { "LED touch7", 1 | CNT_INTVAL },
- { "LED touch8", 5 | CNT_INTVAL },
- { "LED left", 18 | CNT_INTVAL },
- { "LED right", 22 | CNT_INTVAL },
- { "LED up", 16 | CNT_INTVAL },
- { "LED down", 20 | CNT_INTVAL },
- { "LED stop", 23 | CNT_INTVAL },
- { "LED play", 21 | CNT_INTVAL },
- { "LED record", 19 | CNT_INTVAL },
- { "LED listen", 17 | CNT_INTVAL },
- { "LED lcd", 30 | CNT_INTVAL },
- { "LED menu", 28 | CNT_INTVAL },
- { "LED sound", 31 | CNT_INTVAL },
- { "LED esc", 29 | CNT_INTVAL },
- { "LED view", 27 | CNT_INTVAL },
- { "LED enter", 24 | CNT_INTVAL },
- { "LED control", 26 | CNT_INTVAL }
-};
-
-static struct caiaq_controller a8dj_controller[] = {
- { "Current input mode", 0 | CNT_INTVAL },
- { "GND lift for TC Vinyl mode", 24 + 0 },
- { "GND lift for TC CD/Line mode", 24 + 1 },
- { "GND lift for phono mode", 24 + 2 },
- { "Software lock", 40 }
-};
-
-static struct caiaq_controller a4dj_controller[] = {
- { "Current input mode", 0 | CNT_INTVAL }
-};
-
-static struct caiaq_controller kontrolx1_controller[] = {
- { "LED FX A: ON", 7 | CNT_INTVAL },
- { "LED FX A: 1", 6 | CNT_INTVAL },
- { "LED FX A: 2", 5 | CNT_INTVAL },
- { "LED FX A: 3", 4 | CNT_INTVAL },
- { "LED FX B: ON", 3 | CNT_INTVAL },
- { "LED FX B: 1", 2 | CNT_INTVAL },
- { "LED FX B: 2", 1 | CNT_INTVAL },
- { "LED FX B: 3", 0 | CNT_INTVAL },
-
- { "LED Hotcue", 28 | CNT_INTVAL },
- { "LED Shift (white)", 29 | CNT_INTVAL },
- { "LED Shift (green)", 30 | CNT_INTVAL },
-
- { "LED Deck A: FX1", 24 | CNT_INTVAL },
- { "LED Deck A: FX2", 25 | CNT_INTVAL },
- { "LED Deck A: IN", 17 | CNT_INTVAL },
- { "LED Deck A: OUT", 16 | CNT_INTVAL },
- { "LED Deck A: < BEAT", 19 | CNT_INTVAL },
- { "LED Deck A: BEAT >", 18 | CNT_INTVAL },
- { "LED Deck A: CUE/ABS", 21 | CNT_INTVAL },
- { "LED Deck A: CUP/REL", 20 | CNT_INTVAL },
- { "LED Deck A: PLAY", 23 | CNT_INTVAL },
- { "LED Deck A: SYNC", 22 | CNT_INTVAL },
-
- { "LED Deck B: FX1", 26 | CNT_INTVAL },
- { "LED Deck B: FX2", 27 | CNT_INTVAL },
- { "LED Deck B: IN", 15 | CNT_INTVAL },
- { "LED Deck B: OUT", 14 | CNT_INTVAL },
- { "LED Deck B: < BEAT", 13 | CNT_INTVAL },
- { "LED Deck B: BEAT >", 12 | CNT_INTVAL },
- { "LED Deck B: CUE/ABS", 11 | CNT_INTVAL },
- { "LED Deck B: CUP/REL", 10 | CNT_INTVAL },
- { "LED Deck B: PLAY", 9 | CNT_INTVAL },
- { "LED Deck B: SYNC", 8 | CNT_INTVAL },
-};
-
-static struct caiaq_controller kontrols4_controller[] = {
- { "LED: Master: Quant", 10 | CNT_INTVAL },
- { "LED: Master: Headphone", 11 | CNT_INTVAL },
- { "LED: Master: Master", 12 | CNT_INTVAL },
- { "LED: Master: Snap", 14 | CNT_INTVAL },
- { "LED: Master: Warning", 15 | CNT_INTVAL },
- { "LED: Master: Master button", 112 | CNT_INTVAL },
- { "LED: Master: Snap button", 113 | CNT_INTVAL },
- { "LED: Master: Rec", 118 | CNT_INTVAL },
- { "LED: Master: Size", 119 | CNT_INTVAL },
- { "LED: Master: Quant button", 120 | CNT_INTVAL },
- { "LED: Master: Browser button", 121 | CNT_INTVAL },
- { "LED: Master: Play button", 126 | CNT_INTVAL },
- { "LED: Master: Undo button", 127 | CNT_INTVAL },
-
- { "LED: Channel A: >", 4 | CNT_INTVAL },
- { "LED: Channel A: <", 5 | CNT_INTVAL },
- { "LED: Channel A: Meter 1", 97 | CNT_INTVAL },
- { "LED: Channel A: Meter 2", 98 | CNT_INTVAL },
- { "LED: Channel A: Meter 3", 99 | CNT_INTVAL },
- { "LED: Channel A: Meter 4", 100 | CNT_INTVAL },
- { "LED: Channel A: Meter 5", 101 | CNT_INTVAL },
- { "LED: Channel A: Meter 6", 102 | CNT_INTVAL },
- { "LED: Channel A: Meter clip", 103 | CNT_INTVAL },
- { "LED: Channel A: Active", 114 | CNT_INTVAL },
- { "LED: Channel A: Cue", 116 | CNT_INTVAL },
- { "LED: Channel A: FX1", 149 | CNT_INTVAL },
- { "LED: Channel A: FX2", 148 | CNT_INTVAL },
-
- { "LED: Channel B: >", 2 | CNT_INTVAL },
- { "LED: Channel B: <", 3 | CNT_INTVAL },
- { "LED: Channel B: Meter 1", 89 | CNT_INTVAL },
- { "LED: Channel B: Meter 2", 90 | CNT_INTVAL },
- { "LED: Channel B: Meter 3", 91 | CNT_INTVAL },
- { "LED: Channel B: Meter 4", 92 | CNT_INTVAL },
- { "LED: Channel B: Meter 5", 93 | CNT_INTVAL },
- { "LED: Channel B: Meter 6", 94 | CNT_INTVAL },
- { "LED: Channel B: Meter clip", 95 | CNT_INTVAL },
- { "LED: Channel B: Active", 122 | CNT_INTVAL },
- { "LED: Channel B: Cue", 125 | CNT_INTVAL },
- { "LED: Channel B: FX1", 147 | CNT_INTVAL },
- { "LED: Channel B: FX2", 146 | CNT_INTVAL },
-
- { "LED: Channel C: >", 6 | CNT_INTVAL },
- { "LED: Channel C: <", 7 | CNT_INTVAL },
- { "LED: Channel C: Meter 1", 105 | CNT_INTVAL },
- { "LED: Channel C: Meter 2", 106 | CNT_INTVAL },
- { "LED: Channel C: Meter 3", 107 | CNT_INTVAL },
- { "LED: Channel C: Meter 4", 108 | CNT_INTVAL },
- { "LED: Channel C: Meter 5", 109 | CNT_INTVAL },
- { "LED: Channel C: Meter 6", 110 | CNT_INTVAL },
- { "LED: Channel C: Meter clip", 111 | CNT_INTVAL },
- { "LED: Channel C: Active", 115 | CNT_INTVAL },
- { "LED: Channel C: Cue", 117 | CNT_INTVAL },
- { "LED: Channel C: FX1", 151 | CNT_INTVAL },
- { "LED: Channel C: FX2", 150 | CNT_INTVAL },
-
- { "LED: Channel D: >", 0 | CNT_INTVAL },
- { "LED: Channel D: <", 1 | CNT_INTVAL },
- { "LED: Channel D: Meter 1", 81 | CNT_INTVAL },
- { "LED: Channel D: Meter 2", 82 | CNT_INTVAL },
- { "LED: Channel D: Meter 3", 83 | CNT_INTVAL },
- { "LED: Channel D: Meter 4", 84 | CNT_INTVAL },
- { "LED: Channel D: Meter 5", 85 | CNT_INTVAL },
- { "LED: Channel D: Meter 6", 86 | CNT_INTVAL },
- { "LED: Channel D: Meter clip", 87 | CNT_INTVAL },
- { "LED: Channel D: Active", 123 | CNT_INTVAL },
- { "LED: Channel D: Cue", 124 | CNT_INTVAL },
- { "LED: Channel D: FX1", 145 | CNT_INTVAL },
- { "LED: Channel D: FX2", 144 | CNT_INTVAL },
-
- { "LED: Deck A: 1 (blue)", 22 | CNT_INTVAL },
- { "LED: Deck A: 1 (green)", 23 | CNT_INTVAL },
- { "LED: Deck A: 2 (blue)", 20 | CNT_INTVAL },
- { "LED: Deck A: 2 (green)", 21 | CNT_INTVAL },
- { "LED: Deck A: 3 (blue)", 18 | CNT_INTVAL },
- { "LED: Deck A: 3 (green)", 19 | CNT_INTVAL },
- { "LED: Deck A: 4 (blue)", 16 | CNT_INTVAL },
- { "LED: Deck A: 4 (green)", 17 | CNT_INTVAL },
- { "LED: Deck A: Load", 44 | CNT_INTVAL },
- { "LED: Deck A: Deck C button", 45 | CNT_INTVAL },
- { "LED: Deck A: In", 47 | CNT_INTVAL },
- { "LED: Deck A: Out", 46 | CNT_INTVAL },
- { "LED: Deck A: Shift", 24 | CNT_INTVAL },
- { "LED: Deck A: Sync", 27 | CNT_INTVAL },
- { "LED: Deck A: Cue", 26 | CNT_INTVAL },
- { "LED: Deck A: Play", 25 | CNT_INTVAL },
- { "LED: Deck A: Tempo up", 33 | CNT_INTVAL },
- { "LED: Deck A: Tempo down", 32 | CNT_INTVAL },
- { "LED: Deck A: Master", 34 | CNT_INTVAL },
- { "LED: Deck A: Keylock", 35 | CNT_INTVAL },
- { "LED: Deck A: Deck A", 37 | CNT_INTVAL },
- { "LED: Deck A: Deck C", 36 | CNT_INTVAL },
- { "LED: Deck A: Samples", 38 | CNT_INTVAL },
- { "LED: Deck A: On Air", 39 | CNT_INTVAL },
- { "LED: Deck A: Sample 1", 31 | CNT_INTVAL },
- { "LED: Deck A: Sample 2", 30 | CNT_INTVAL },
- { "LED: Deck A: Sample 3", 29 | CNT_INTVAL },
- { "LED: Deck A: Sample 4", 28 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - A", 55 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - B", 54 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - C", 53 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - D", 52 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - E", 51 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - F", 50 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - G", 49 | CNT_INTVAL },
- { "LED: Deck A: Digit 1 - dot", 48 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - A", 63 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - B", 62 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - C", 61 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - D", 60 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - E", 59 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - F", 58 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - G", 57 | CNT_INTVAL },
- { "LED: Deck A: Digit 2 - dot", 56 | CNT_INTVAL },
-
- { "LED: Deck B: 1 (blue)", 78 | CNT_INTVAL },
- { "LED: Deck B: 1 (green)", 79 | CNT_INTVAL },
- { "LED: Deck B: 2 (blue)", 76 | CNT_INTVAL },
- { "LED: Deck B: 2 (green)", 77 | CNT_INTVAL },
- { "LED: Deck B: 3 (blue)", 74 | CNT_INTVAL },
- { "LED: Deck B: 3 (green)", 75 | CNT_INTVAL },
- { "LED: Deck B: 4 (blue)", 72 | CNT_INTVAL },
- { "LED: Deck B: 4 (green)", 73 | CNT_INTVAL },
- { "LED: Deck B: Load", 180 | CNT_INTVAL },
- { "LED: Deck B: Deck D button", 181 | CNT_INTVAL },
- { "LED: Deck B: In", 183 | CNT_INTVAL },
- { "LED: Deck B: Out", 182 | CNT_INTVAL },
- { "LED: Deck B: Shift", 64 | CNT_INTVAL },
- { "LED: Deck B: Sync", 67 | CNT_INTVAL },
- { "LED: Deck B: Cue", 66 | CNT_INTVAL },
- { "LED: Deck B: Play", 65 | CNT_INTVAL },
- { "LED: Deck B: Tempo up", 185 | CNT_INTVAL },
- { "LED: Deck B: Tempo down", 184 | CNT_INTVAL },
- { "LED: Deck B: Master", 186 | CNT_INTVAL },
- { "LED: Deck B: Keylock", 187 | CNT_INTVAL },
- { "LED: Deck B: Deck B", 189 | CNT_INTVAL },
- { "LED: Deck B: Deck D", 188 | CNT_INTVAL },
- { "LED: Deck B: Samples", 190 | CNT_INTVAL },
- { "LED: Deck B: On Air", 191 | CNT_INTVAL },
- { "LED: Deck B: Sample 1", 71 | CNT_INTVAL },
- { "LED: Deck B: Sample 2", 70 | CNT_INTVAL },
- { "LED: Deck B: Sample 3", 69 | CNT_INTVAL },
- { "LED: Deck B: Sample 4", 68 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - A", 175 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - B", 174 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - C", 173 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - D", 172 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - E", 171 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - F", 170 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - G", 169 | CNT_INTVAL },
- { "LED: Deck B: Digit 1 - dot", 168 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - A", 167 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - B", 166 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - C", 165 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - D", 164 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - E", 163 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - F", 162 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - G", 161 | CNT_INTVAL },
- { "LED: Deck B: Digit 2 - dot", 160 | CNT_INTVAL },
-
- { "LED: FX1: dry/wet", 153 | CNT_INTVAL },
- { "LED: FX1: 1", 154 | CNT_INTVAL },
- { "LED: FX1: 2", 155 | CNT_INTVAL },
- { "LED: FX1: 3", 156 | CNT_INTVAL },
- { "LED: FX1: Mode", 157 | CNT_INTVAL },
- { "LED: FX2: dry/wet", 129 | CNT_INTVAL },
- { "LED: FX2: 1", 130 | CNT_INTVAL },
- { "LED: FX2: 2", 131 | CNT_INTVAL },
- { "LED: FX2: 3", 132 | CNT_INTVAL },
- { "LED: FX2: Mode", 133 | CNT_INTVAL },
-};
-
-static int __devinit add_controls(struct caiaq_controller *c, int num,
- struct snd_usb_caiaqdev *dev)
-{
- int i, ret;
- struct snd_kcontrol *kc;
-
- for (i = 0; i < num; i++, c++) {
- kcontrol_template.name = c->name;
- kcontrol_template.private_value = c->index;
- kc = snd_ctl_new1(&kcontrol_template, dev);
- ret = snd_ctl_add(dev->chip.card, kc);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
-{
- int ret = 0;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- ret = add_controls(ak1_controller,
- ARRAY_SIZE(ak1_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- ret = add_controls(rk2_controller,
- ARRAY_SIZE(rk2_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- ret = add_controls(rk3_controller,
- ARRAY_SIZE(rk3_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- ret = add_controls(kore_controller,
- ARRAY_SIZE(kore_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
- ret = add_controls(a8dj_controller,
- ARRAY_SIZE(a8dj_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
- ret = add_controls(a4dj_controller,
- ARRAY_SIZE(a4dj_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- ret = add_controls(kontrolx1_controller,
- ARRAY_SIZE(kontrolx1_controller), dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- ret = add_controls(kontrols4_controller,
- ARRAY_SIZE(kontrols4_controller), dev);
- break;
- }
-
- return ret;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/control.h b/ANDROID_3.4.5/sound/usb/caiaq/control.h
deleted file mode 100644
index 2e7ab1aa..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/control.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef CAIAQ_CONTROL_H
-#define CAIAQ_CONTROL_H
-
-int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev);
-
-#endif /* CAIAQ_CONTROL_H */
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/device.c b/ANDROID_3.4.5/sound/usb/caiaq/device.c
deleted file mode 100644
index 64aed432..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/device.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * caiaq.c: ALSA driver for caiaq/NativeInstruments devices
- *
- * Copyright (c) 2007 Daniel Mack <daniel@caiaq.de>
- * Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/gfp.h>
-#include <linux/usb.h>
-#include <sound/initval.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "audio.h"
-#include "midi.h"
-#include "control.h"
-#include "input.h"
-
-MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("caiaq USB audio");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
- "{Native Instruments, RigKontrol3},"
- "{Native Instruments, Kore Controller},"
- "{Native Instruments, Kore Controller 2},"
- "{Native Instruments, Audio Kontrol 1},"
- "{Native Instruments, Audio 2 DJ},"
- "{Native Instruments, Audio 4 DJ},"
- "{Native Instruments, Audio 8 DJ},"
- "{Native Instruments, Traktor Audio 2},"
- "{Native Instruments, Session I/O},"
- "{Native Instruments, GuitarRig mobile}"
- "{Native Instruments, Traktor Kontrol X1}"
- "{Native Instruments, Traktor Kontrol S4}"
- "{Native Instruments, Maschine Controller}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-static int snd_card_used[SNDRV_CARDS];
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the caiaq sound device");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the caiaq soundcard.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable the caiaq soundcard.");
-
-enum {
- SAMPLERATE_44100 = 0,
- SAMPLERATE_48000 = 1,
- SAMPLERATE_96000 = 2,
- SAMPLERATE_192000 = 3,
- SAMPLERATE_88200 = 4,
- SAMPLERATE_INVALID = 0xff
-};
-
-enum {
- DEPTH_NONE = 0,
- DEPTH_16 = 1,
- DEPTH_24 = 2,
- DEPTH_32 = 3
-};
-
-static struct usb_device_id snd_usb_id_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_RIGKONTROL2
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_RIGKONTROL3
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_KORECONTROLLER
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_KORECONTROLLER2
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_AK1
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_AUDIO8DJ
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_SESSIONIO
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_GUITARRIGMOBILE
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_AUDIO4DJ
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_AUDIO2DJ
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_TRAKTORKONTROLX1
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_TRAKTORKONTROLS4
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_TRAKTORAUDIO2
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = USB_VID_NATIVEINSTRUMENTS,
- .idProduct = USB_PID_MASCHINECONTROLLER
- },
- { /* terminator */ }
-};
-
-static void usb_ep1_command_reply_dispatch (struct urb* urb)
-{
- int ret;
- struct snd_usb_caiaqdev *dev = urb->context;
- unsigned char *buf = urb->transfer_buffer;
-
- if (urb->status || !dev) {
- log("received EP1 urb->status = %i\n", urb->status);
- return;
- }
-
- switch(buf[0]) {
- case EP1_CMD_GET_DEVICE_INFO:
- memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec));
- dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version);
- debug("device spec (firmware %d): audio: %d in, %d out, "
- "MIDI: %d in, %d out, data alignment %d\n",
- dev->spec.fw_version,
- dev->spec.num_analog_audio_in,
- dev->spec.num_analog_audio_out,
- dev->spec.num_midi_in,
- dev->spec.num_midi_out,
- dev->spec.data_alignment);
-
- dev->spec_received++;
- wake_up(&dev->ep1_wait_queue);
- break;
- case EP1_CMD_AUDIO_PARAMS:
- dev->audio_parm_answer = buf[1];
- wake_up(&dev->ep1_wait_queue);
- break;
- case EP1_CMD_MIDI_READ:
- snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]);
- break;
- case EP1_CMD_READ_IO:
- if (dev->chip.usb_id ==
- USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ)) {
- if (urb->actual_length > sizeof(dev->control_state))
- urb->actual_length = sizeof(dev->control_state);
- memcpy(dev->control_state, buf + 1, urb->actual_length);
- wake_up(&dev->ep1_wait_queue);
- break;
- }
-#ifdef CONFIG_SND_USB_CAIAQ_INPUT
- case EP1_CMD_READ_ERP:
- case EP1_CMD_READ_ANALOG:
- snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length);
-#endif
- break;
- }
-
- dev->ep1_in_urb.actual_length = 0;
- ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC);
- if (ret < 0)
- log("unable to submit urb. OOM!?\n");
-}
-
-int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev,
- unsigned char command,
- const unsigned char *buffer,
- int len)
-{
- int actual_len;
- struct usb_device *usb_dev = dev->chip.dev;
-
- if (!usb_dev)
- return -EIO;
-
- if (len > EP1_BUFSIZE - 1)
- len = EP1_BUFSIZE - 1;
-
- if (buffer && len > 0)
- memcpy(dev->ep1_out_buf+1, buffer, len);
-
- dev->ep1_out_buf[0] = command;
- return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1),
- dev->ep1_out_buf, len+1, &actual_len, 200);
-}
-
-int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev,
- int rate, int depth, int bpp)
-{
- int ret;
- char tmp[5];
-
- switch (rate) {
- case 44100: tmp[0] = SAMPLERATE_44100; break;
- case 48000: tmp[0] = SAMPLERATE_48000; break;
- case 88200: tmp[0] = SAMPLERATE_88200; break;
- case 96000: tmp[0] = SAMPLERATE_96000; break;
- case 192000: tmp[0] = SAMPLERATE_192000; break;
- default: return -EINVAL;
- }
-
- switch (depth) {
- case 16: tmp[1] = DEPTH_16; break;
- case 24: tmp[1] = DEPTH_24; break;
- default: return -EINVAL;
- }
-
- tmp[2] = bpp & 0xff;
- tmp[3] = bpp >> 8;
- tmp[4] = 1; /* packets per microframe */
-
- debug("setting audio params: %d Hz, %d bits, %d bpp\n",
- rate, depth, bpp);
-
- dev->audio_parm_answer = -1;
- ret = snd_usb_caiaq_send_command(dev, EP1_CMD_AUDIO_PARAMS,
- tmp, sizeof(tmp));
-
- if (ret)
- return ret;
-
- if (!wait_event_timeout(dev->ep1_wait_queue,
- dev->audio_parm_answer >= 0, HZ))
- return -EPIPE;
-
- if (dev->audio_parm_answer != 1)
- debug("unable to set the device's audio params\n");
- else
- dev->bpp = bpp;
-
- return dev->audio_parm_answer == 1 ? 0 : -EINVAL;
-}
-
-int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *dev,
- int digital, int analog, int erp)
-{
- char tmp[3] = { digital, analog, erp };
- return snd_usb_caiaq_send_command(dev, EP1_CMD_AUTO_MSG,
- tmp, sizeof(tmp));
-}
-
-static void __devinit setup_card(struct snd_usb_caiaqdev *dev)
-{
- int ret;
- char val[4];
-
- /* device-specific startup specials */
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- /* RigKontrol2 - display centered dash ('-') */
- val[0] = 0x00;
- val[1] = 0x00;
- val[2] = 0x01;
- snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 3);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- /* RigKontrol2 - display two centered dashes ('--') */
- val[0] = 0x00;
- val[1] = 0x40;
- val[2] = 0x40;
- val[3] = 0x00;
- snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 4);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- /* Audio Kontrol 1 - make USB-LED stop blinking */
- val[0] = 0x00;
- snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, val, 1);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
- /* Audio 8 DJ - trigger read of current settings */
- dev->control_state[0] = 0xff;
- snd_usb_caiaq_set_auto_msg(dev, 1, 0, 0);
- snd_usb_caiaq_send_command(dev, EP1_CMD_READ_IO, NULL, 0);
-
- if (!wait_event_timeout(dev->ep1_wait_queue,
- dev->control_state[0] != 0xff, HZ))
- return;
-
- /* fix up some defaults */
- if ((dev->control_state[1] != 2) ||
- (dev->control_state[2] != 3) ||
- (dev->control_state[4] != 2)) {
- dev->control_state[1] = 2;
- dev->control_state[2] = 3;
- dev->control_state[4] = 2;
- snd_usb_caiaq_send_command(dev,
- EP1_CMD_WRITE_IO, dev->control_state, 6);
- }
-
- break;
- }
-
- if (dev->spec.num_analog_audio_out +
- dev->spec.num_analog_audio_in +
- dev->spec.num_digital_audio_out +
- dev->spec.num_digital_audio_in > 0) {
- ret = snd_usb_caiaq_audio_init(dev);
- if (ret < 0)
- log("Unable to set up audio system (ret=%d)\n", ret);
- }
-
- if (dev->spec.num_midi_in +
- dev->spec.num_midi_out > 0) {
- ret = snd_usb_caiaq_midi_init(dev);
- if (ret < 0)
- log("Unable to set up MIDI system (ret=%d)\n", ret);
- }
-
-#ifdef CONFIG_SND_USB_CAIAQ_INPUT
- ret = snd_usb_caiaq_input_init(dev);
- if (ret < 0)
- log("Unable to set up input system (ret=%d)\n", ret);
-#endif
-
- /* finally, register the card and all its sub-instances */
- ret = snd_card_register(dev->chip.card);
- if (ret < 0) {
- log("snd_card_register() returned %d\n", ret);
- snd_card_free(dev->chip.card);
- }
-
- ret = snd_usb_caiaq_control_init(dev);
- if (ret < 0)
- log("Unable to set up control system (ret=%d)\n", ret);
-}
-
-static int create_card(struct usb_device *usb_dev,
- struct usb_interface *intf,
- struct snd_card **cardp)
-{
- int devnum;
- int err;
- struct snd_card *card;
- struct snd_usb_caiaqdev *dev;
-
- for (devnum = 0; devnum < SNDRV_CARDS; devnum++)
- if (enable[devnum] && !snd_card_used[devnum])
- break;
-
- if (devnum >= SNDRV_CARDS)
- return -ENODEV;
-
- err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
- sizeof(struct snd_usb_caiaqdev), &card);
- if (err < 0)
- return err;
-
- dev = caiaqdev(card);
- dev->chip.dev = usb_dev;
- dev->chip.card = card;
- dev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor),
- le16_to_cpu(usb_dev->descriptor.idProduct));
- spin_lock_init(&dev->spinlock);
- snd_card_set_dev(card, &intf->dev);
-
- *cardp = card;
- return 0;
-}
-
-static int __devinit init_card(struct snd_usb_caiaqdev *dev)
-{
- char *c, usbpath[32];
- struct usb_device *usb_dev = dev->chip.dev;
- struct snd_card *card = dev->chip.card;
- int err, len;
-
- if (usb_set_interface(usb_dev, 0, 1) != 0) {
- log("can't set alt interface.\n");
- return -EIO;
- }
-
- usb_init_urb(&dev->ep1_in_urb);
- usb_init_urb(&dev->midi_out_urb);
-
- usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x1),
- dev->ep1_in_buf, EP1_BUFSIZE,
- usb_ep1_command_reply_dispatch, dev);
-
- usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev,
- usb_sndbulkpipe(usb_dev, 0x1),
- dev->midi_out_buf, EP1_BUFSIZE,
- snd_usb_caiaq_midi_output_done, dev);
-
- init_waitqueue_head(&dev->ep1_wait_queue);
- init_waitqueue_head(&dev->prepare_wait_queue);
-
- if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
- return -EIO;
-
- err = snd_usb_caiaq_send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
- if (err)
- return err;
-
- if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ))
- return -ENODEV;
-
- usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
- dev->vendor_name, CAIAQ_USB_STR_LEN);
-
- usb_string(usb_dev, usb_dev->descriptor.iProduct,
- dev->product_name, CAIAQ_USB_STR_LEN);
-
- strlcpy(card->driver, MODNAME, sizeof(card->driver));
- strlcpy(card->shortname, dev->product_name, sizeof(card->shortname));
- strlcpy(card->mixername, dev->product_name, sizeof(card->mixername));
-
- /* if the id was not passed as module option, fill it with a shortened
- * version of the product string which does not contain any
- * whitespaces */
-
- if (*card->id == '\0') {
- char id[sizeof(card->id)];
-
- memset(id, 0, sizeof(id));
-
- for (c = card->shortname, len = 0;
- *c && len < sizeof(card->id); c++)
- if (*c != ' ')
- id[len++] = *c;
-
- snd_card_set_id(card, id);
- }
-
- usb_make_path(usb_dev, usbpath, sizeof(usbpath));
- snprintf(card->longname, sizeof(card->longname),
- "%s %s (%s)",
- dev->vendor_name, dev->product_name, usbpath);
-
- setup_card(dev);
- return 0;
-}
-
-static int __devinit snd_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- int ret;
- struct snd_card *card;
- struct usb_device *device = interface_to_usbdev(intf);
-
- ret = create_card(device, intf, &card);
-
- if (ret < 0)
- return ret;
-
- usb_set_intfdata(intf, card);
- ret = init_card(caiaqdev(card));
- if (ret < 0) {
- log("unable to init card! (ret=%d)\n", ret);
- snd_card_free(card);
- return ret;
- }
-
- return 0;
-}
-
-static void snd_disconnect(struct usb_interface *intf)
-{
- struct snd_usb_caiaqdev *dev;
- struct snd_card *card = usb_get_intfdata(intf);
-
- debug("%s(%p)\n", __func__, intf);
-
- if (!card)
- return;
-
- dev = caiaqdev(card);
- snd_card_disconnect(card);
-
-#ifdef CONFIG_SND_USB_CAIAQ_INPUT
- snd_usb_caiaq_input_free(dev);
-#endif
- snd_usb_caiaq_audio_free(dev);
-
- usb_kill_urb(&dev->ep1_in_urb);
- usb_kill_urb(&dev->midi_out_urb);
-
- snd_card_free(card);
- usb_reset_device(interface_to_usbdev(intf));
-}
-
-
-MODULE_DEVICE_TABLE(usb, snd_usb_id_table);
-static struct usb_driver snd_usb_driver = {
- .name = MODNAME,
- .probe = snd_probe,
- .disconnect = snd_disconnect,
- .id_table = snd_usb_id_table,
-};
-
-module_usb_driver(snd_usb_driver);
-
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/device.h b/ANDROID_3.4.5/sound/usb/caiaq/device.h
deleted file mode 100644
index 562b0bff..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/device.h
+++ /dev/null
@@ -1,140 +0,0 @@
-#ifndef CAIAQ_DEVICE_H
-#define CAIAQ_DEVICE_H
-
-#include "../usbaudio.h"
-
-#define USB_VID_NATIVEINSTRUMENTS 0x17cc
-
-#define USB_PID_RIGKONTROL2 0x1969
-#define USB_PID_RIGKONTROL3 0x1940
-#define USB_PID_KORECONTROLLER 0x4711
-#define USB_PID_KORECONTROLLER2 0x4712
-#define USB_PID_AK1 0x0815
-#define USB_PID_AUDIO2DJ 0x041c
-#define USB_PID_AUDIO4DJ 0x0839
-#define USB_PID_AUDIO8DJ 0x1978
-#define USB_PID_SESSIONIO 0x1915
-#define USB_PID_GUITARRIGMOBILE 0x0d8d
-#define USB_PID_TRAKTORKONTROLX1 0x2305
-#define USB_PID_TRAKTORKONTROLS4 0xbaff
-#define USB_PID_TRAKTORAUDIO2 0x041d
-#define USB_PID_MASCHINECONTROLLER 0x0808
-
-#define EP1_BUFSIZE 64
-#define EP4_BUFSIZE 512
-#define CAIAQ_USB_STR_LEN 0xff
-#define MAX_STREAMS 32
-
-//#define SND_USB_CAIAQ_DEBUG
-
-#define MODNAME "snd-usb-caiaq"
-#define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x)
-
-#ifdef SND_USB_CAIAQ_DEBUG
-#define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x)
-#else
-#define debug(x...) do { } while(0)
-#endif
-
-#define EP1_CMD_GET_DEVICE_INFO 0x1
-#define EP1_CMD_READ_ERP 0x2
-#define EP1_CMD_READ_ANALOG 0x3
-#define EP1_CMD_READ_IO 0x4
-#define EP1_CMD_WRITE_IO 0x5
-#define EP1_CMD_MIDI_READ 0x6
-#define EP1_CMD_MIDI_WRITE 0x7
-#define EP1_CMD_AUDIO_PARAMS 0x9
-#define EP1_CMD_AUTO_MSG 0xb
-#define EP1_CMD_DIMM_LEDS 0xc
-
-struct caiaq_device_spec {
- unsigned short fw_version;
- unsigned char hw_subtype;
- unsigned char num_erp;
- unsigned char num_analog_in;
- unsigned char num_digital_in;
- unsigned char num_digital_out;
- unsigned char num_analog_audio_out;
- unsigned char num_analog_audio_in;
- unsigned char num_digital_audio_out;
- unsigned char num_digital_audio_in;
- unsigned char num_midi_out;
- unsigned char num_midi_in;
- unsigned char data_alignment;
-} __attribute__ ((packed));
-
-struct snd_usb_caiaq_cb_info;
-
-struct snd_usb_caiaqdev {
- struct snd_usb_audio chip;
-
- struct urb ep1_in_urb;
- struct urb midi_out_urb;
- struct urb **data_urbs_in;
- struct urb **data_urbs_out;
- struct snd_usb_caiaq_cb_info *data_cb_info;
-
- unsigned char ep1_in_buf[EP1_BUFSIZE];
- unsigned char ep1_out_buf[EP1_BUFSIZE];
- unsigned char midi_out_buf[EP1_BUFSIZE];
-
- struct caiaq_device_spec spec;
- spinlock_t spinlock;
- wait_queue_head_t ep1_wait_queue;
- wait_queue_head_t prepare_wait_queue;
- int spec_received, audio_parm_answer;
- int midi_out_active;
-
- char vendor_name[CAIAQ_USB_STR_LEN];
- char product_name[CAIAQ_USB_STR_LEN];
-
- int n_streams, n_audio_in, n_audio_out;
- int streaming, first_packet, output_running;
- int audio_in_buf_pos[MAX_STREAMS];
- int audio_out_buf_pos[MAX_STREAMS];
- int period_in_count[MAX_STREAMS];
- int period_out_count[MAX_STREAMS];
- int input_panic, output_panic, warned;
- char *audio_in_buf, *audio_out_buf;
- unsigned int samplerates, bpp;
- unsigned long outurb_active_mask;
-
- struct snd_pcm_substream *sub_playback[MAX_STREAMS];
- struct snd_pcm_substream *sub_capture[MAX_STREAMS];
-
- /* Controls */
- unsigned char control_state[256];
- unsigned char ep8_out_buf[2];
-
- /* Linux input */
-#ifdef CONFIG_SND_USB_CAIAQ_INPUT
- struct input_dev *input_dev;
- char phys[64]; /* physical device path */
- unsigned short keycode[128];
- struct urb *ep4_in_urb;
- unsigned char ep4_in_buf[EP4_BUFSIZE];
-#endif
-
- /* ALSA */
- struct snd_pcm *pcm;
- struct snd_pcm_hardware pcm_info;
- struct snd_rawmidi *rmidi;
- struct snd_rawmidi_substream *midi_receive_substream;
- struct snd_rawmidi_substream *midi_out_substream;
-};
-
-struct snd_usb_caiaq_cb_info {
- struct snd_usb_caiaqdev *dev;
- int index;
-};
-
-#define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data)
-
-int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp);
-int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp);
-int snd_usb_caiaq_send_command(struct snd_usb_caiaqdev *dev,
- unsigned char command,
- const unsigned char *buffer,
- int len);
-
-#endif /* CAIAQ_DEVICE_H */
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/input.c b/ANDROID_3.4.5/sound/usb/caiaq/input.c
deleted file mode 100644
index 26a121b4..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/input.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- * Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "input.h"
-
-static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A };
-static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4,
- KEY_5, KEY_6, KEY_7 };
-static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4,
- KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 };
-
-static unsigned short keycode_kore[] = {
- KEY_FN_F1, /* "menu" */
- KEY_FN_F7, /* "lcd backlight */
- KEY_FN_F2, /* "control" */
- KEY_FN_F3, /* "enter" */
- KEY_FN_F4, /* "view" */
- KEY_FN_F5, /* "esc" */
- KEY_FN_F6, /* "sound" */
- KEY_FN_F8, /* array spacer, never triggered. */
- KEY_RIGHT,
- KEY_DOWN,
- KEY_UP,
- KEY_LEFT,
- KEY_SOUND, /* "listen" */
- KEY_RECORD,
- KEY_PLAYPAUSE,
- KEY_STOP,
- BTN_4, /* 8 softkeys */
- BTN_3,
- BTN_2,
- BTN_1,
- BTN_8,
- BTN_7,
- BTN_6,
- BTN_5,
- KEY_BRL_DOT4, /* touch sensitive knobs */
- KEY_BRL_DOT3,
- KEY_BRL_DOT2,
- KEY_BRL_DOT1,
- KEY_BRL_DOT8,
- KEY_BRL_DOT7,
- KEY_BRL_DOT6,
- KEY_BRL_DOT5
-};
-
-#define MASCHINE_BUTTONS (42)
-#define MASCHINE_BUTTON(X) ((X) + BTN_MISC)
-#define MASCHINE_PADS (16)
-#define MASCHINE_PAD(X) ((X) + ABS_PRESSURE)
-
-static unsigned short keycode_maschine[] = {
- MASCHINE_BUTTON(40), /* mute */
- MASCHINE_BUTTON(39), /* solo */
- MASCHINE_BUTTON(38), /* select */
- MASCHINE_BUTTON(37), /* duplicate */
- MASCHINE_BUTTON(36), /* navigate */
- MASCHINE_BUTTON(35), /* pad mode */
- MASCHINE_BUTTON(34), /* pattern */
- MASCHINE_BUTTON(33), /* scene */
- KEY_RESERVED, /* spacer */
-
- MASCHINE_BUTTON(30), /* rec */
- MASCHINE_BUTTON(31), /* erase */
- MASCHINE_BUTTON(32), /* shift */
- MASCHINE_BUTTON(28), /* grid */
- MASCHINE_BUTTON(27), /* > */
- MASCHINE_BUTTON(26), /* < */
- MASCHINE_BUTTON(25), /* restart */
-
- MASCHINE_BUTTON(21), /* E */
- MASCHINE_BUTTON(22), /* F */
- MASCHINE_BUTTON(23), /* G */
- MASCHINE_BUTTON(24), /* H */
- MASCHINE_BUTTON(20), /* D */
- MASCHINE_BUTTON(19), /* C */
- MASCHINE_BUTTON(18), /* B */
- MASCHINE_BUTTON(17), /* A */
-
- MASCHINE_BUTTON(0), /* control */
- MASCHINE_BUTTON(2), /* browse */
- MASCHINE_BUTTON(4), /* < */
- MASCHINE_BUTTON(6), /* snap */
- MASCHINE_BUTTON(7), /* autowrite */
- MASCHINE_BUTTON(5), /* > */
- MASCHINE_BUTTON(3), /* sampling */
- MASCHINE_BUTTON(1), /* step */
-
- MASCHINE_BUTTON(15), /* 8 softkeys */
- MASCHINE_BUTTON(14),
- MASCHINE_BUTTON(13),
- MASCHINE_BUTTON(12),
- MASCHINE_BUTTON(11),
- MASCHINE_BUTTON(10),
- MASCHINE_BUTTON(9),
- MASCHINE_BUTTON(8),
-
- MASCHINE_BUTTON(16), /* note repeat */
- MASCHINE_BUTTON(29) /* play */
-};
-
-#define KONTROLX1_INPUTS (40)
-#define KONTROLS4_BUTTONS (12 * 8)
-#define KONTROLS4_AXIS (46)
-
-#define KONTROLS4_BUTTON(X) ((X) + BTN_MISC)
-#define KONTROLS4_ABS(X) ((X) + ABS_HAT0X)
-
-#define DEG90 (range / 2)
-#define DEG180 (range)
-#define DEG270 (DEG90 + DEG180)
-#define DEG360 (DEG180 * 2)
-#define HIGH_PEAK (268)
-#define LOW_PEAK (-7)
-
-/* some of these devices have endless rotation potentiometers
- * built in which use two tapers, 90 degrees phase shifted.
- * this algorithm decodes them to one single value, ranging
- * from 0 to 999 */
-static unsigned int decode_erp(unsigned char a, unsigned char b)
-{
- int weight_a, weight_b;
- int pos_a, pos_b;
- int ret;
- int range = HIGH_PEAK - LOW_PEAK;
- int mid_value = (HIGH_PEAK + LOW_PEAK) / 2;
-
- weight_b = abs(mid_value - a) - (range / 2 - 100) / 2;
-
- if (weight_b < 0)
- weight_b = 0;
-
- if (weight_b > 100)
- weight_b = 100;
-
- weight_a = 100 - weight_b;
-
- if (a < mid_value) {
- /* 0..90 and 270..360 degrees */
- pos_b = b - LOW_PEAK + DEG270;
- if (pos_b >= DEG360)
- pos_b -= DEG360;
- } else
- /* 90..270 degrees */
- pos_b = HIGH_PEAK - b + DEG90;
-
-
- if (b > mid_value)
- /* 0..180 degrees */
- pos_a = a - LOW_PEAK;
- else
- /* 180..360 degrees */
- pos_a = HIGH_PEAK - a + DEG180;
-
- /* interpolate both slider values, depending on weight factors */
- /* 0..99 x DEG360 */
- ret = pos_a * weight_a + pos_b * weight_b;
-
- /* normalize to 0..999 */
- ret *= 10;
- ret /= DEG360;
-
- if (ret < 0)
- ret += 1000;
-
- if (ret >= 1000)
- ret -= 1000;
-
- return ret;
-}
-
-#undef DEG90
-#undef DEG180
-#undef DEG270
-#undef DEG360
-#undef HIGH_PEAK
-#undef LOW_PEAK
-
-static inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *dev,
- int axis, const unsigned char *buf,
- int offset)
-{
- input_report_abs(dev->input_dev, axis,
- (buf[offset * 2] << 8) | buf[offset * 2 + 1]);
-}
-
-static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
- const unsigned char *buf,
- unsigned int len)
-{
- struct input_dev *input_dev = dev->input_dev;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- snd_caiaq_input_report_abs(dev, ABS_X, buf, 2);
- snd_caiaq_input_report_abs(dev, ABS_Y, buf, 0);
- snd_caiaq_input_report_abs(dev, ABS_Z, buf, 1);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- snd_caiaq_input_report_abs(dev, ABS_X, buf, 0);
- snd_caiaq_input_report_abs(dev, ABS_Y, buf, 1);
- snd_caiaq_input_report_abs(dev, ABS_Z, buf, 2);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- snd_caiaq_input_report_abs(dev, ABS_HAT0X, buf, 4);
- snd_caiaq_input_report_abs(dev, ABS_HAT0Y, buf, 2);
- snd_caiaq_input_report_abs(dev, ABS_HAT1X, buf, 6);
- snd_caiaq_input_report_abs(dev, ABS_HAT1Y, buf, 1);
- snd_caiaq_input_report_abs(dev, ABS_HAT2X, buf, 7);
- snd_caiaq_input_report_abs(dev, ABS_HAT2Y, buf, 0);
- snd_caiaq_input_report_abs(dev, ABS_HAT3X, buf, 5);
- snd_caiaq_input_report_abs(dev, ABS_HAT3Y, buf, 3);
- break;
- }
-
- input_sync(input_dev);
-}
-
-static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
- const char *buf, unsigned int len)
-{
- struct input_dev *input_dev = dev->input_dev;
- int i;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- i = decode_erp(buf[0], buf[1]);
- input_report_abs(input_dev, ABS_X, i);
- input_sync(input_dev);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- i = decode_erp(buf[7], buf[5]);
- input_report_abs(input_dev, ABS_HAT0X, i);
- i = decode_erp(buf[12], buf[14]);
- input_report_abs(input_dev, ABS_HAT0Y, i);
- i = decode_erp(buf[15], buf[13]);
- input_report_abs(input_dev, ABS_HAT1X, i);
- i = decode_erp(buf[0], buf[2]);
- input_report_abs(input_dev, ABS_HAT1Y, i);
- i = decode_erp(buf[3], buf[1]);
- input_report_abs(input_dev, ABS_HAT2X, i);
- i = decode_erp(buf[8], buf[10]);
- input_report_abs(input_dev, ABS_HAT2Y, i);
- i = decode_erp(buf[11], buf[9]);
- input_report_abs(input_dev, ABS_HAT3X, i);
- i = decode_erp(buf[4], buf[6]);
- input_report_abs(input_dev, ABS_HAT3Y, i);
- input_sync(input_dev);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- /* 4 under the left screen */
- input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20]));
- input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14]));
- input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9], buf[8]));
- input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3], buf[2]));
-
- /* 4 under the right screen */
- input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18]));
- input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12]));
- input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7], buf[6]));
- input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1], buf[0]));
-
- /* volume */
- input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16]));
- /* tempo */
- input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10]));
- /* swing */
- input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5], buf[4]));
-
- input_sync(input_dev);
- break;
- }
-}
-
-static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
- unsigned char *buf, unsigned int len)
-{
- struct input_dev *input_dev = dev->input_dev;
- unsigned short *keycode = input_dev->keycode;
- int i;
-
- if (!keycode)
- return;
-
- if (input_dev->id.product == USB_PID_RIGKONTROL2)
- for (i = 0; i < len; i++)
- buf[i] = ~buf[i];
-
- for (i = 0; i < input_dev->keycodemax && i < len * 8; i++)
- input_report_key(input_dev, keycode[i],
- buf[i / 8] & (1 << (i % 8)));
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- /* rotary encoders */
- input_report_abs(dev->input_dev, ABS_X, buf[5] & 0xf);
- input_report_abs(dev->input_dev, ABS_Y, buf[5] >> 4);
- input_report_abs(dev->input_dev, ABS_Z, buf[6] & 0xf);
- input_report_abs(dev->input_dev, ABS_MISC, buf[6] >> 4);
- break;
- }
-
- input_sync(input_dev);
-}
-
-#define TKS4_MSGBLOCK_SIZE 16
-
-static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev,
- const unsigned char *buf,
- unsigned int len)
-{
- while (len) {
- unsigned int i, block_id = (buf[0] << 8) | buf[1];
-
- switch (block_id) {
- case 0:
- /* buttons */
- for (i = 0; i < KONTROLS4_BUTTONS; i++)
- input_report_key(dev->input_dev, KONTROLS4_BUTTON(i),
- (buf[4 + (i / 8)] >> (i % 8)) & 1);
- break;
-
- case 1:
- /* left wheel */
- input_report_abs(dev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8));
- /* right wheel */
- input_report_abs(dev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8));
-
- /* rotary encoders */
- input_report_abs(dev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4);
- input_report_abs(dev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf);
-
- break;
- case 2:
- /* Volume Fader Channel D */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(0), buf, 1);
- /* Volume Fader Channel B */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(1), buf, 2);
- /* Volume Fader Channel A */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(2), buf, 3);
- /* Volume Fader Channel C */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(3), buf, 4);
- /* Loop Volume */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(4), buf, 6);
- /* Crossfader */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(7), buf, 7);
-
- break;
-
- case 3:
- /* Tempo Fader R */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(6), buf, 3);
- /* Tempo Fader L */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(5), buf, 4);
- /* Mic Volume */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(8), buf, 6);
- /* Cue Mix */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(9), buf, 7);
-
- break;
-
- case 4:
- /* Wheel distance sensor L */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(10), buf, 1);
- /* Wheel distance sensor R */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(11), buf, 2);
- /* Channel D EQ - Filter */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(12), buf, 3);
- /* Channel D EQ - Low */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(13), buf, 4);
- /* Channel D EQ - Mid */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(14), buf, 5);
- /* Channel D EQ - Hi */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(15), buf, 6);
- /* FX2 - dry/wet */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(16), buf, 7);
-
- break;
-
- case 5:
- /* FX2 - 1 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(17), buf, 1);
- /* FX2 - 2 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(18), buf, 2);
- /* FX2 - 3 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(19), buf, 3);
- /* Channel B EQ - Filter */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(20), buf, 4);
- /* Channel B EQ - Low */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(21), buf, 5);
- /* Channel B EQ - Mid */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(22), buf, 6);
- /* Channel B EQ - Hi */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(23), buf, 7);
-
- break;
-
- case 6:
- /* Channel A EQ - Filter */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(24), buf, 1);
- /* Channel A EQ - Low */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(25), buf, 2);
- /* Channel A EQ - Mid */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(26), buf, 3);
- /* Channel A EQ - Hi */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(27), buf, 4);
- /* Channel C EQ - Filter */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(28), buf, 5);
- /* Channel C EQ - Low */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(29), buf, 6);
- /* Channel C EQ - Mid */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(30), buf, 7);
-
- break;
-
- case 7:
- /* Channel C EQ - Hi */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(31), buf, 1);
- /* FX1 - wet/dry */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(32), buf, 2);
- /* FX1 - 1 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(33), buf, 3);
- /* FX1 - 2 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(34), buf, 4);
- /* FX1 - 3 */
- snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(35), buf, 5);
-
- break;
-
- default:
- debug("%s(): bogus block (id %d)\n",
- __func__, block_id);
- return;
- }
-
- len -= TKS4_MSGBLOCK_SIZE;
- buf += TKS4_MSGBLOCK_SIZE;
- }
-
- input_sync(dev->input_dev);
-}
-
-#define MASCHINE_MSGBLOCK_SIZE 2
-
-static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *dev,
- const unsigned char *buf,
- unsigned int len)
-{
- unsigned int i, pad_id;
- uint16_t pressure;
-
- for (i = 0; i < MASCHINE_PADS; i++) {
- pressure = be16_to_cpu(buf[i * 2] << 8 | buf[(i * 2) + 1]);
- pad_id = pressure >> 12;
-
- input_report_abs(dev->input_dev, MASCHINE_PAD(pad_id), pressure & 0xfff);
- }
-
- input_sync(dev->input_dev);
-}
-
-static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
-{
- struct snd_usb_caiaqdev *dev = urb->context;
- unsigned char *buf = urb->transfer_buffer;
- int ret;
-
- if (urb->status || !dev || urb != dev->ep4_in_urb)
- return;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- if (urb->actual_length < 24)
- goto requeue;
-
- if (buf[0] & 0x3)
- snd_caiaq_input_read_io(dev, buf + 1, 7);
-
- if (buf[0] & 0x4)
- snd_caiaq_input_read_analog(dev, buf + 8, 16);
-
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length);
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE))
- goto requeue;
-
- snd_usb_caiaq_maschine_dispatch(dev, buf, urb->actual_length);
- break;
- }
-
-requeue:
- dev->ep4_in_urb->actual_length = 0;
- ret = usb_submit_urb(dev->ep4_in_urb, GFP_ATOMIC);
- if (ret < 0)
- log("unable to submit urb. OOM!?\n");
-}
-
-static int snd_usb_caiaq_input_open(struct input_dev *idev)
-{
- struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
-
- if (!dev)
- return -EINVAL;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
- return -EIO;
- break;
- }
-
- return 0;
-}
-
-static void snd_usb_caiaq_input_close(struct input_dev *idev)
-{
- struct snd_usb_caiaqdev *dev = input_get_drvdata(idev);
-
- if (!dev)
- return;
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- usb_kill_urb(dev->ep4_in_urb);
- break;
- }
-}
-
-void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev,
- char *buf,
- unsigned int len)
-{
- if (!dev->input_dev || len < 1)
- return;
-
- switch (buf[0]) {
- case EP1_CMD_READ_ANALOG:
- snd_caiaq_input_read_analog(dev, buf + 1, len - 1);
- break;
- case EP1_CMD_READ_ERP:
- snd_caiaq_input_read_erp(dev, buf + 1, len - 1);
- break;
- case EP1_CMD_READ_IO:
- snd_caiaq_input_read_io(dev, buf + 1, len - 1);
- break;
- }
-}
-
-int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
-{
- struct usb_device *usb_dev = dev->chip.dev;
- struct input_dev *input;
- int i, ret = 0;
-
- input = input_allocate_device();
- if (!input)
- return -ENOMEM;
-
- usb_make_path(usb_dev, dev->phys, sizeof(dev->phys));
- strlcat(dev->phys, "/input0", sizeof(dev->phys));
-
- input->name = dev->product_name;
- input->phys = dev->phys;
- usb_to_input_id(usb_dev, &input->id);
- input->dev.parent = &usb_dev->dev;
-
- input_set_drvdata(input, dev);
-
- switch (dev->chip.usb_id) {
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
- BIT_MASK(ABS_Z);
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk2));
- memcpy(dev->keycode, keycode_rk2, sizeof(keycode_rk2));
- input->keycodemax = ARRAY_SIZE(keycode_rk2);
- input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
- BIT_MASK(ABS_Z);
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk3));
- memcpy(dev->keycode, keycode_rk3, sizeof(keycode_rk3));
- input->keycodemax = ARRAY_SIZE(keycode_rk3);
- input_set_abs_params(input, ABS_X, 0, 1024, 0, 10);
- input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10);
- input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10);
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_X);
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_ak1));
- memcpy(dev->keycode, keycode_ak1, sizeof(keycode_ak1));
- input->keycodemax = ARRAY_SIZE(keycode_ak1);
- input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
- snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
- BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
- BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
- BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
- BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
- BIT_MASK(ABS_Z);
- input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_kore));
- memcpy(dev->keycode, keycode_kore, sizeof(keycode_kore));
- input->keycodemax = ARRAY_SIZE(keycode_kore);
- input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
- break;
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
- BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
- BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
- BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
- BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
- BIT_MASK(ABS_Z);
- input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
- BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLX1_INPUTS);
- for (i = 0; i < KONTROLX1_INPUTS; i++)
- dev->keycode[i] = BTN_MISC + i;
- input->keycodemax = KONTROLX1_INPUTS;
-
- /* analog potentiometers */
- input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10);
- input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10);
-
- /* rotary encoders */
- input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1);
- input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1);
- input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1);
- input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1);
-
- dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->ep4_in_urb) {
- ret = -ENOMEM;
- goto exit_free_idev;
- }
-
- usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x4),
- dev->ep4_in_buf, EP4_BUFSIZE,
- snd_usb_caiaq_ep4_reply_dispatch, dev);
-
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
-
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLS4_BUTTONS);
- for (i = 0; i < KONTROLS4_BUTTONS; i++)
- dev->keycode[i] = KONTROLS4_BUTTON(i);
- input->keycodemax = KONTROLS4_BUTTONS;
-
- for (i = 0; i < KONTROLS4_AXIS; i++) {
- int axis = KONTROLS4_ABS(i);
- input->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
- }
-
- /* 36 analog potentiometers and faders */
- for (i = 0; i < 36; i++)
- input_set_abs_params(input, KONTROLS4_ABS(i), 0, 0xfff, 0, 10);
-
- /* 2 encoder wheels */
- input_set_abs_params(input, KONTROLS4_ABS(36), 0, 0x3ff, 0, 1);
- input_set_abs_params(input, KONTROLS4_ABS(37), 0, 0x3ff, 0, 1);
-
- /* 9 rotary encoders */
- for (i = 0; i < 9; i++)
- input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1);
-
- dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->ep4_in_urb) {
- ret = -ENOMEM;
- goto exit_free_idev;
- }
-
- usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x4),
- dev->ep4_in_buf, EP4_BUFSIZE,
- snd_usb_caiaq_ep4_reply_dispatch, dev);
-
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
-
- break;
-
- case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER):
- input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
- BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
- BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
- BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
- BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) |
- BIT_MASK(ABS_RZ);
-
- BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_maschine));
- memcpy(dev->keycode, keycode_maschine, sizeof(keycode_maschine));
- input->keycodemax = ARRAY_SIZE(keycode_maschine);
-
- for (i = 0; i < MASCHINE_PADS; i++) {
- input->absbit[0] |= MASCHINE_PAD(i);
- input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10);
- }
-
- input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_RX, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_RY, 0, 999, 0, 10);
- input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10);
-
- dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->ep4_in_urb) {
- ret = -ENOMEM;
- goto exit_free_idev;
- }
-
- usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
- usb_rcvbulkpipe(usb_dev, 0x4),
- dev->ep4_in_buf, EP4_BUFSIZE,
- snd_usb_caiaq_ep4_reply_dispatch, dev);
-
- snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
- break;
-
- default:
- /* no input methods supported on this device */
- goto exit_free_idev;
- }
-
- input->open = snd_usb_caiaq_input_open;
- input->close = snd_usb_caiaq_input_close;
- input->keycode = dev->keycode;
- input->keycodesize = sizeof(unsigned short);
- for (i = 0; i < input->keycodemax; i++)
- __set_bit(dev->keycode[i], input->keybit);
-
- dev->input_dev = input;
-
- ret = input_register_device(input);
- if (ret < 0)
- goto exit_free_idev;
-
- return 0;
-
-exit_free_idev:
- input_free_device(input);
- dev->input_dev = NULL;
- return ret;
-}
-
-void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
-{
- if (!dev || !dev->input_dev)
- return;
-
- usb_kill_urb(dev->ep4_in_urb);
- usb_free_urb(dev->ep4_in_urb);
- dev->ep4_in_urb = NULL;
-
- input_unregister_device(dev->input_dev);
- dev->input_dev = NULL;
-}
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/input.h b/ANDROID_3.4.5/sound/usb/caiaq/input.h
deleted file mode 100644
index ced53557..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/input.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CAIAQ_INPUT_H
-#define CAIAQ_INPUT_H
-
-void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len);
-int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev);
-void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/midi.c b/ANDROID_3.4.5/sound/usb/caiaq/midi.c
deleted file mode 100644
index a1a47088..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/midi.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (c) 2006,2007 Daniel Mack
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/usb.h>
-#include <linux/gfp.h>
-#include <sound/rawmidi.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "device.h"
-#include "midi.h"
-
-static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
-
- if (!dev)
- return;
-
- dev->midi_receive_substream = up ? substream : NULL;
-}
-
-
-static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream)
-{
- return 0;
-}
-
-static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
- if (dev->midi_out_active) {
- usb_kill_urb(&dev->midi_out_urb);
- dev->midi_out_active = 0;
- }
- return 0;
-}
-
-static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
- struct snd_rawmidi_substream *substream)
-{
- int len, ret;
-
- dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
- dev->midi_out_buf[1] = 0; /* port */
- len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3,
- EP1_BUFSIZE - 3);
-
- if (len <= 0)
- return;
-
- dev->midi_out_buf[2] = len;
- dev->midi_out_urb.transfer_buffer_length = len+3;
-
- ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);
- if (ret < 0)
- log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed,"
- "ret=%d, len=%d\n",
- substream, ret, len);
- else
- dev->midi_out_active = 1;
-}
-
-static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
-
- if (up) {
- dev->midi_out_substream = substream;
- if (!dev->midi_out_active)
- snd_usb_caiaq_midi_send(dev, substream);
- } else {
- dev->midi_out_substream = NULL;
- }
-}
-
-
-static struct snd_rawmidi_ops snd_usb_caiaq_midi_output =
-{
- .open = snd_usb_caiaq_midi_output_open,
- .close = snd_usb_caiaq_midi_output_close,
- .trigger = snd_usb_caiaq_midi_output_trigger,
-};
-
-static struct snd_rawmidi_ops snd_usb_caiaq_midi_input =
-{
- .open = snd_usb_caiaq_midi_input_open,
- .close = snd_usb_caiaq_midi_input_close,
- .trigger = snd_usb_caiaq_midi_input_trigger,
-};
-
-void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev,
- int port, const char *buf, int len)
-{
- if (!dev->midi_receive_substream)
- return;
-
- snd_rawmidi_receive(dev->midi_receive_substream, buf, len);
-}
-
-int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
-{
- int ret;
- struct snd_rawmidi *rmidi;
-
- ret = snd_rawmidi_new(device->chip.card, device->product_name, 0,
- device->spec.num_midi_out,
- device->spec.num_midi_in,
- &rmidi);
-
- if (ret < 0)
- return ret;
-
- strlcpy(rmidi->name, device->product_name, sizeof(rmidi->name));
-
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->private_data = device;
-
- if (device->spec.num_midi_out > 0) {
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
- &snd_usb_caiaq_midi_output);
- }
-
- if (device->spec.num_midi_in > 0) {
- rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
- &snd_usb_caiaq_midi_input);
- }
-
- device->rmidi = rmidi;
-
- return 0;
-}
-
-void snd_usb_caiaq_midi_output_done(struct urb* urb)
-{
- struct snd_usb_caiaqdev *dev = urb->context;
-
- dev->midi_out_active = 0;
- if (urb->status != 0)
- return;
-
- if (!dev->midi_out_substream)
- return;
-
- snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/caiaq/midi.h b/ANDROID_3.4.5/sound/usb/caiaq/midi.h
deleted file mode 100644
index 380f984b..00000000
--- a/ANDROID_3.4.5/sound/usb/caiaq/midi.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CAIAQ_MIDI_H
-#define CAIAQ_MIDI_H
-
-int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev);
-void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len);
-void snd_usb_caiaq_midi_output_done(struct urb *urb);
-
-#endif /* CAIAQ_MIDI_H */
diff --git a/ANDROID_3.4.5/sound/usb/card.c b/ANDROID_3.4.5/sound/usb/card.c
deleted file mode 100644
index 4a7be7b9..00000000
--- a/ANDROID_3.4.5/sound/usb/card.c
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * (Tentative) USB Audio Driver for ALSA
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * Many codes borrowed from audio.c by
- * Alan Cox (alan@lxorguk.ukuu.org.uk)
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * NOTES:
- *
- * - async unlink should be used for avoiding the sleep inside lock.
- * 2.4.22 usb-uhci seems buggy for async unlinking and results in
- * oops. in such a cse, pass async_unlink=0 option.
- * - the linked URBs would be preferred but not used so far because of
- * the instability of unlinking.
- * - type II is not supported properly. there is no device which supports
- * this type *correctly*. SB extigy looks as if it supports, but it's
- * indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
- */
-
-
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/usb.h>
-#include <linux/moduleparam.h>
-#include <linux/mutex.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-#include <linux/module.h>
-
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "midi.h"
-#include "mixer.h"
-#include "proc.h"
-#include "quirks.h"
-#include "endpoint.h"
-#include "helper.h"
-#include "debug.h"
-#include "pcm.h"
-#include "format.h"
-#include "power.h"
-#include "stream.h"
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("USB Audio");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}");
-
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
-/* Vendor/product IDs for this card */
-static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
-static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 };
-static int nrpacks = 8; /* max. number of packets per urb */
-static bool async_unlink = 1;
-static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
-static bool ignore_ctl_error;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the USB audio adapter.");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the USB audio adapter.");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable USB audio adapter.");
-module_param_array(vid, int, NULL, 0444);
-MODULE_PARM_DESC(vid, "Vendor ID for the USB audio device.");
-module_param_array(pid, int, NULL, 0444);
-MODULE_PARM_DESC(pid, "Product ID for the USB audio device.");
-module_param(nrpacks, int, 0644);
-MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB.");
-module_param(async_unlink, bool, 0444);
-MODULE_PARM_DESC(async_unlink, "Use async unlink mode.");
-module_param_array(device_setup, int, NULL, 0444);
-MODULE_PARM_DESC(device_setup, "Specific device setup (if needed).");
-module_param(ignore_ctl_error, bool, 0444);
-MODULE_PARM_DESC(ignore_ctl_error,
- "Ignore errors from USB controller for mixer interfaces.");
-
-/*
- * we keep the snd_usb_audio_t instances by ourselves for merging
- * the all interfaces on the same card as one sound device.
- */
-
-static DEFINE_MUTEX(register_mutex);
-static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
-static struct usb_driver usb_audio_driver;
-
-/*
- * disconnect streams
- * called from snd_usb_audio_disconnect()
- */
-static void snd_usb_stream_disconnect(struct list_head *head)
-{
- int idx;
- struct snd_usb_stream *as;
- struct snd_usb_substream *subs;
-
- as = list_entry(head, struct snd_usb_stream, list);
- for (idx = 0; idx < 2; idx++) {
- subs = &as->substream[idx];
- if (!subs->num_formats)
- continue;
- snd_usb_release_substream_urbs(subs, 1);
- subs->interface = -1;
- }
-}
-
-static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
-{
- struct usb_device *dev = chip->dev;
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- struct usb_interface *iface = usb_ifnum_to_if(dev, interface);
-
- if (!iface) {
- snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
- dev->devnum, ctrlif, interface);
- return -EINVAL;
- }
-
- if (usb_interface_claimed(iface)) {
- snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n",
- dev->devnum, ctrlif, interface);
- return -EINVAL;
- }
-
- alts = &iface->altsetting[0];
- altsd = get_iface_desc(alts);
- if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
- altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
- altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) {
- int err = snd_usbmidi_create(chip->card, iface,
- &chip->midi_list, NULL);
- if (err < 0) {
- snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n",
- dev->devnum, ctrlif, interface);
- return -EINVAL;
- }
- usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
-
- return 0;
- }
-
- if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
- altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
- altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING) {
- snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n",
- dev->devnum, ctrlif, interface, altsd->bInterfaceClass);
- /* skip non-supported classes */
- return -EINVAL;
- }
-
- if (snd_usb_get_speed(dev) == USB_SPEED_LOW) {
- snd_printk(KERN_ERR "low speed audio streaming not supported\n");
- return -EINVAL;
- }
-
- if (! snd_usb_parse_audio_interface(chip, interface)) {
- usb_set_interface(dev, interface, 0); /* reset the current interface */
- usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * parse audio control descriptor and create pcm/midi streams
- */
-static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
-{
- struct usb_device *dev = chip->dev;
- struct usb_host_interface *host_iface;
- struct usb_interface_descriptor *altsd;
- void *control_header;
- int i, protocol;
-
- /* find audiocontrol interface */
- host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
- control_header = snd_usb_find_csint_desc(host_iface->extra,
- host_iface->extralen,
- NULL, UAC_HEADER);
- altsd = get_iface_desc(host_iface);
- protocol = altsd->bInterfaceProtocol;
-
- if (!control_header) {
- snd_printk(KERN_ERR "cannot find UAC_HEADER\n");
- return -EINVAL;
- }
-
- switch (protocol) {
- default:
- snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n",
- protocol);
- /* fall through */
-
- case UAC_VERSION_1: {
- struct uac1_ac_header_descriptor *h1 = control_header;
-
- if (!h1->bInCollection) {
- snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
- return -EINVAL;
- }
-
- if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
- snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
- return -EINVAL;
- }
-
- for (i = 0; i < h1->bInCollection; i++)
- snd_usb_create_stream(chip, ctrlif, h1->baInterfaceNr[i]);
-
- break;
- }
-
- case UAC_VERSION_2: {
- struct usb_interface_assoc_descriptor *assoc =
- usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
-
- if (!assoc) {
- snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
- return -EINVAL;
- }
-
- for (i = 0; i < assoc->bInterfaceCount; i++) {
- int intf = assoc->bFirstInterface + i;
-
- if (intf != ctrlif)
- snd_usb_create_stream(chip, ctrlif, intf);
- }
-
- break;
- }
- }
-
- return 0;
-}
-
-/*
- * free the chip instance
- *
- * here we have to do not much, since pcm and controls are already freed
- *
- */
-
-static int snd_usb_audio_free(struct snd_usb_audio *chip)
-{
- kfree(chip);
- return 0;
-}
-
-static int snd_usb_audio_dev_free(struct snd_device *device)
-{
- struct snd_usb_audio *chip = device->device_data;
- return snd_usb_audio_free(chip);
-}
-
-static void remove_trailing_spaces(char *str)
-{
- char *p;
-
- if (!*str)
- return;
- for (p = str + strlen(str) - 1; p >= str && isspace(*p); p--)
- *p = 0;
-}
-
-/*
- * create a chip instance and set its names.
- */
-static int snd_usb_audio_create(struct usb_device *dev, int idx,
- const struct snd_usb_audio_quirk *quirk,
- struct snd_usb_audio **rchip)
-{
- struct snd_card *card;
- struct snd_usb_audio *chip;
- int err, len;
- char component[14];
- static struct snd_device_ops ops = {
- .dev_free = snd_usb_audio_dev_free,
- };
-
- *rchip = NULL;
-
- switch (snd_usb_get_speed(dev)) {
- case USB_SPEED_LOW:
- case USB_SPEED_FULL:
- case USB_SPEED_HIGH:
- case USB_SPEED_SUPER:
- break;
- default:
- snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
- return -ENXIO;
- }
-
- err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
- return err;
- }
-
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (! chip) {
- snd_card_free(card);
- return -ENOMEM;
- }
-
- mutex_init(&chip->shutdown_mutex);
- chip->index = idx;
- chip->dev = dev;
- chip->card = card;
- chip->setup = device_setup[idx];
- chip->nrpacks = nrpacks;
- chip->async_unlink = async_unlink;
- chip->probing = 1;
-
- chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
- INIT_LIST_HEAD(&chip->pcm_list);
- INIT_LIST_HEAD(&chip->midi_list);
- INIT_LIST_HEAD(&chip->mixer_list);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
- snd_usb_audio_free(chip);
- snd_card_free(card);
- return err;
- }
-
- strcpy(card->driver, "USB-Audio");
- sprintf(component, "USB%04x:%04x",
- USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
- snd_component_add(card, component);
-
- /* retrieve the device string as shortname */
- if (quirk && quirk->product_name && *quirk->product_name) {
- strlcpy(card->shortname, quirk->product_name, sizeof(card->shortname));
- } else {
- if (!dev->descriptor.iProduct ||
- usb_string(dev, dev->descriptor.iProduct,
- card->shortname, sizeof(card->shortname)) <= 0) {
- /* no name available from anywhere, so use ID */
- sprintf(card->shortname, "USB Device %#04x:%#04x",
- USB_ID_VENDOR(chip->usb_id),
- USB_ID_PRODUCT(chip->usb_id));
- }
- }
- remove_trailing_spaces(card->shortname);
-
- /* retrieve the vendor and device strings as longname */
- if (quirk && quirk->vendor_name && *quirk->vendor_name) {
- len = strlcpy(card->longname, quirk->vendor_name, sizeof(card->longname));
- } else {
- if (dev->descriptor.iManufacturer)
- len = usb_string(dev, dev->descriptor.iManufacturer,
- card->longname, sizeof(card->longname));
- else
- len = 0;
- /* we don't really care if there isn't any vendor string */
- }
- if (len > 0) {
- remove_trailing_spaces(card->longname);
- if (*card->longname)
- strlcat(card->longname, " ", sizeof(card->longname));
- }
-
- strlcat(card->longname, card->shortname, sizeof(card->longname));
-
- len = strlcat(card->longname, " at ", sizeof(card->longname));
-
- if (len < sizeof(card->longname))
- usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
-
- switch (snd_usb_get_speed(dev)) {
- case USB_SPEED_LOW:
- strlcat(card->longname, ", low speed", sizeof(card->longname));
- break;
- case USB_SPEED_FULL:
- strlcat(card->longname, ", full speed", sizeof(card->longname));
- break;
- case USB_SPEED_HIGH:
- strlcat(card->longname, ", high speed", sizeof(card->longname));
- break;
- case USB_SPEED_SUPER:
- strlcat(card->longname, ", super speed", sizeof(card->longname));
- break;
- default:
- break;
- }
-
- snd_usb_audio_create_proc(chip);
-
- *rchip = chip;
- return 0;
-}
-
-/*
- * probe the active usb device
- *
- * note that this can be called multiple times per a device, when it
- * includes multiple audio control interfaces.
- *
- * thus we check the usb device pointer and creates the card instance
- * only at the first time. the successive calls of this function will
- * append the pcm interface to the corresponding card.
- */
-static struct snd_usb_audio *
-snd_usb_audio_probe(struct usb_device *dev,
- struct usb_interface *intf,
- const struct usb_device_id *usb_id)
-{
- const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
- int i, err;
- struct snd_usb_audio *chip;
- struct usb_host_interface *alts;
- int ifnum;
- u32 id;
-
- alts = &intf->altsetting[0];
- ifnum = get_iface_desc(alts)->bInterfaceNumber;
- id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
- if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
- goto __err_val;
-
- if (snd_usb_apply_boot_quirk(dev, intf, quirk) < 0)
- goto __err_val;
-
- /*
- * found a config. now register to ALSA
- */
-
- /* check whether it's already registered */
- chip = NULL;
- mutex_lock(&register_mutex);
- for (i = 0; i < SNDRV_CARDS; i++) {
- if (usb_chip[i] && usb_chip[i]->dev == dev) {
- if (usb_chip[i]->shutdown) {
- snd_printk(KERN_ERR "USB device is in the shutdown state, cannot create a card instance\n");
- goto __error;
- }
- chip = usb_chip[i];
- chip->probing = 1;
- break;
- }
- }
- if (! chip) {
- /* it's a fresh one.
- * now look for an empty slot and create a new card instance
- */
- for (i = 0; i < SNDRV_CARDS; i++)
- if (enable[i] && ! usb_chip[i] &&
- (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
- (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
- if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
- goto __error;
- }
- snd_card_set_dev(chip->card, &intf->dev);
- chip->pm_intf = intf;
- break;
- }
- if (!chip) {
- printk(KERN_ERR "no available usb audio device\n");
- goto __error;
- }
- }
-
- /*
- * For devices with more than one control interface, we assume the
- * first contains the audio controls. We might need a more specific
- * check here in the future.
- */
- if (!chip->ctrl_intf)
- chip->ctrl_intf = alts;
-
- chip->txfr_quirk = 0;
- err = 1; /* continue */
- if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) {
- /* need some special handlings */
- if ((err = snd_usb_create_quirk(chip, intf, &usb_audio_driver, quirk)) < 0)
- goto __error;
- }
-
- if (err > 0) {
- /* create normal USB audio interfaces */
- if (snd_usb_create_streams(chip, ifnum) < 0 ||
- snd_usb_create_mixer(chip, ifnum, ignore_ctl_error) < 0) {
- goto __error;
- }
- }
-
- /* we are allowed to call snd_card_register() many times */
- if (snd_card_register(chip->card) < 0) {
- goto __error;
- }
-
- usb_chip[chip->index] = chip;
- chip->num_interfaces++;
- chip->probing = 0;
- mutex_unlock(&register_mutex);
- return chip;
-
- __error:
- if (chip) {
- if (!chip->num_interfaces)
- snd_card_free(chip->card);
- chip->probing = 0;
- }
- mutex_unlock(&register_mutex);
- __err_val:
- return NULL;
-}
-
-/*
- * we need to take care of counter, since disconnection can be called also
- * many times as well as usb_audio_probe().
- */
-static void snd_usb_audio_disconnect(struct usb_device *dev,
- struct snd_usb_audio *chip)
-{
- struct snd_card *card;
- struct list_head *p;
-
- if (chip == (void *)-1L)
- return;
-
- card = chip->card;
- mutex_lock(&register_mutex);
- mutex_lock(&chip->shutdown_mutex);
- chip->shutdown = 1;
- chip->num_interfaces--;
- if (chip->num_interfaces <= 0) {
- snd_card_disconnect(card);
- /* release the pcm resources */
- list_for_each(p, &chip->pcm_list) {
- snd_usb_stream_disconnect(p);
- }
- /* release the midi resources */
- list_for_each(p, &chip->midi_list) {
- snd_usbmidi_disconnect(p);
- }
- /* release mixer resources */
- list_for_each(p, &chip->mixer_list) {
- snd_usb_mixer_disconnect(p);
- }
- usb_chip[chip->index] = NULL;
- mutex_unlock(&chip->shutdown_mutex);
- mutex_unlock(&register_mutex);
- snd_card_free_when_closed(card);
- } else {
- mutex_unlock(&chip->shutdown_mutex);
- mutex_unlock(&register_mutex);
- }
-}
-
-/*
- * new 2.5 USB kernel API
- */
-static int usb_audio_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct snd_usb_audio *chip;
- chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
- if (chip) {
- usb_set_intfdata(intf, chip);
- return 0;
- } else
- return -EIO;
-}
-
-static void usb_audio_disconnect(struct usb_interface *intf)
-{
- snd_usb_audio_disconnect(interface_to_usbdev(intf),
- usb_get_intfdata(intf));
-}
-
-#ifdef CONFIG_PM
-
-int snd_usb_autoresume(struct snd_usb_audio *chip)
-{
- int err = -ENODEV;
-
- if (!chip->shutdown && !chip->probing)
- err = usb_autopm_get_interface(chip->pm_intf);
-
- return err;
-}
-
-void snd_usb_autosuspend(struct snd_usb_audio *chip)
-{
- if (!chip->shutdown && !chip->probing)
- usb_autopm_put_interface(chip->pm_intf);
-}
-
-static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct snd_usb_audio *chip = usb_get_intfdata(intf);
- struct list_head *p;
- struct snd_usb_stream *as;
- struct usb_mixer_interface *mixer;
-
- if (chip == (void *)-1L)
- return 0;
-
- if (!PMSG_IS_AUTO(message)) {
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
- if (!chip->num_suspended_intf++) {
- list_for_each(p, &chip->pcm_list) {
- as = list_entry(p, struct snd_usb_stream, list);
- snd_pcm_suspend_all(as->pcm);
- }
- }
- } else {
- /*
- * otherwise we keep the rest of the system in the dark
- * to keep this transparent
- */
- if (!chip->num_suspended_intf++)
- chip->autosuspended = 1;
- }
-
- list_for_each_entry(mixer, &chip->mixer_list, list)
- snd_usb_mixer_inactivate(mixer);
-
- return 0;
-}
-
-static int usb_audio_resume(struct usb_interface *intf)
-{
- struct snd_usb_audio *chip = usb_get_intfdata(intf);
- struct usb_mixer_interface *mixer;
- int err = 0;
-
- if (chip == (void *)-1L)
- return 0;
- if (--chip->num_suspended_intf)
- return 0;
- /*
- * ALSA leaves material resumption to user space
- * we just notify and restart the mixers
- */
- list_for_each_entry(mixer, &chip->mixer_list, list) {
- err = snd_usb_mixer_activate(mixer);
- if (err < 0)
- goto err_out;
- }
-
- if (!chip->autosuspended)
- snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
- chip->autosuspended = 0;
-
-err_out:
- return err;
-}
-#else
-#define usb_audio_suspend NULL
-#define usb_audio_resume NULL
-#endif /* CONFIG_PM */
-
-static struct usb_device_id usb_audio_ids [] = {
-#include "quirks-table.h"
- { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, usb_audio_ids);
-
-/*
- * entry point for linux usb interface
- */
-
-static struct usb_driver usb_audio_driver = {
- .name = "snd-usb-audio",
- .probe = usb_audio_probe,
- .disconnect = usb_audio_disconnect,
- .suspend = usb_audio_suspend,
- .resume = usb_audio_resume,
- .id_table = usb_audio_ids,
- .supports_autosuspend = 1,
-};
-
-static int __init snd_usb_audio_init(void)
-{
- if (nrpacks < 1 || nrpacks > MAX_PACKS) {
- printk(KERN_WARNING "invalid nrpacks value.\n");
- return -EINVAL;
- }
- return usb_register(&usb_audio_driver);
-}
-
-static void __exit snd_usb_audio_cleanup(void)
-{
- usb_deregister(&usb_audio_driver);
-}
-
-module_init(snd_usb_audio_init);
-module_exit(snd_usb_audio_cleanup);
diff --git a/ANDROID_3.4.5/sound/usb/card.h b/ANDROID_3.4.5/sound/usb/card.h
deleted file mode 100644
index da5fa1ac..00000000
--- a/ANDROID_3.4.5/sound/usb/card.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef __USBAUDIO_CARD_H
-#define __USBAUDIO_CARD_H
-
-#define MAX_NR_RATES 1024
-#define MAX_PACKS 20
-#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
-#define MAX_URBS 8
-#define SYNC_URBS 4 /* always four urbs for sync */
-#define MAX_QUEUE 24 /* try not to exceed this queue length, in ms */
-
-struct audioformat {
- struct list_head list;
- u64 formats; /* ALSA format bits */
- unsigned int channels; /* # channels */
- unsigned int fmt_type; /* USB audio format type (1-3) */
- unsigned int frame_size; /* samples per frame for non-audio */
- int iface; /* interface number */
- unsigned char altsetting; /* corresponding alternate setting */
- unsigned char altset_idx; /* array index of altenate setting */
- unsigned char attributes; /* corresponding attributes of cs endpoint */
- unsigned char endpoint; /* endpoint */
- unsigned char ep_attr; /* endpoint attributes */
- unsigned char datainterval; /* log_2 of data packet interval */
- unsigned int maxpacksize; /* max. packet size */
- unsigned int rates; /* rate bitmasks */
- unsigned int rate_min, rate_max; /* min/max rates */
- unsigned int nr_rates; /* number of rate table entries */
- unsigned int *rate_table; /* rate table */
- unsigned char clock; /* associated clock */
-};
-
-struct snd_usb_substream;
-
-struct snd_urb_ctx {
- struct urb *urb;
- unsigned int buffer_size; /* size of data buffer, if data URB */
- struct snd_usb_substream *subs;
- int index; /* index for urb array */
- int packets; /* number of packets per urb */
-};
-
-struct snd_urb_ops {
- int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
- int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
- int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
- int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
-};
-
-struct snd_usb_substream {
- struct snd_usb_stream *stream;
- struct usb_device *dev;
- struct snd_pcm_substream *pcm_substream;
- int direction; /* playback or capture */
- int interface; /* current interface */
- int endpoint; /* assigned endpoint */
- struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */
- unsigned int cur_rate; /* current rate (for hw_params callback) */
- unsigned int period_bytes; /* current period bytes (for hw_params callback) */
- unsigned int altset_idx; /* USB data format: index of alternate setting */
- unsigned int datapipe; /* the data i/o pipe */
- unsigned int syncpipe; /* 1 - async out or adaptive in */
- unsigned int datainterval; /* log_2 of data packet interval */
- unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
- unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */
- unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */
- int freqshift; /* how much to shift the feedback value to get Q16.16 */
- unsigned int freqmax; /* maximum sampling rate, used for buffer management */
- unsigned int phase; /* phase accumulator */
- unsigned int maxpacksize; /* max packet size in bytes */
- unsigned int maxframesize; /* max packet size in frames */
- unsigned int curpacksize; /* current packet size in bytes (for capture) */
- unsigned int curframesize; /* current packet size in frames (for capture) */
- unsigned int syncmaxsize; /* sync endpoint packet size */
- unsigned int fill_max: 1; /* fill max packet size always */
- unsigned int txfr_quirk:1; /* allow sub-frame alignment */
- unsigned int fmt_type; /* USB audio format type (1-3) */
-
- unsigned int running: 1; /* running status */
-
- unsigned int hwptr_done; /* processed byte position in the buffer */
- unsigned int transfer_done; /* processed frames since last period update */
- unsigned long active_mask; /* bitmask of active urbs */
- unsigned long unlink_mask; /* bitmask of unlinked urbs */
-
- unsigned int nurbs; /* # urbs */
- struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */
- struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */
- char *syncbuf; /* sync buffer for all sync URBs */
- dma_addr_t sync_dma; /* DMA address of syncbuf */
-
- u64 formats; /* format bitmasks (all or'ed) */
- unsigned int num_formats; /* number of supported audio formats (list) */
- struct list_head fmt_list; /* format list */
- struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
- spinlock_t lock;
-
- struct snd_urb_ops ops; /* callbacks (must be filled at init) */
- int last_frame_number; /* stored frame number */
- int last_delay; /* stored delay */
-};
-
-struct snd_usb_stream {
- struct snd_usb_audio *chip;
- struct snd_pcm *pcm;
- int pcm_index;
- unsigned int fmt_type; /* USB audio format type (1-3) */
- struct snd_usb_substream substream[2];
- struct list_head list;
-};
-
-#endif /* __USBAUDIO_CARD_H */
diff --git a/ANDROID_3.4.5/sound/usb/clock.c b/ANDROID_3.4.5/sound/usb/clock.c
deleted file mode 100644
index 6026e0e1..00000000
--- a/ANDROID_3.4.5/sound/usb/clock.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Clock domain and sample rate management functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "helper.h"
-#include "clock.h"
-
-static struct uac_clock_source_descriptor *
- snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface,
- int clock_id)
-{
- struct uac_clock_source_descriptor *cs = NULL;
-
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- cs, UAC2_CLOCK_SOURCE))) {
- if (cs->bClockID == clock_id)
- return cs;
- }
-
- return NULL;
-}
-
-static struct uac_clock_selector_descriptor *
- snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface,
- int clock_id)
-{
- struct uac_clock_selector_descriptor *cs = NULL;
-
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- cs, UAC2_CLOCK_SELECTOR))) {
- if (cs->bClockID == clock_id)
- return cs;
- }
-
- return NULL;
-}
-
-static struct uac_clock_multiplier_descriptor *
- snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface,
- int clock_id)
-{
- struct uac_clock_multiplier_descriptor *cs = NULL;
-
- while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- cs, UAC2_CLOCK_MULTIPLIER))) {
- if (cs->bClockID == clock_id)
- return cs;
- }
-
- return NULL;
-}
-
-static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
-{
- unsigned char buf;
- int ret;
-
- ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0),
- UAC2_CS_CUR,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- UAC2_CX_CLOCK_SELECTOR << 8,
- snd_usb_ctrl_intf(chip) | (selector_id << 8),
- &buf, sizeof(buf));
-
- if (ret < 0)
- return ret;
-
- return buf;
-}
-
-static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
-{
- int err;
- unsigned char data;
- struct usb_device *dev = chip->dev;
- struct uac_clock_source_descriptor *cs_desc =
- snd_usb_find_clock_source(chip->ctrl_intf, source_id);
-
- if (!cs_desc)
- return 0;
-
- /* If a clock source can't tell us whether it's valid, we assume it is */
- if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID))
- return 1;
-
- err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- UAC2_CS_CONTROL_CLOCK_VALID << 8,
- snd_usb_ctrl_intf(chip) | (source_id << 8),
- &data, sizeof(data));
-
- if (err < 0) {
- snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n",
- __func__, source_id);
- return 0;
- }
-
- return !!data;
-}
-
-static int __uac_clock_find_source(struct snd_usb_audio *chip,
- int entity_id, unsigned long *visited)
-{
- struct uac_clock_source_descriptor *source;
- struct uac_clock_selector_descriptor *selector;
- struct uac_clock_multiplier_descriptor *multiplier;
-
- entity_id &= 0xff;
-
- if (test_and_set_bit(entity_id, visited)) {
- snd_printk(KERN_WARNING
- "%s(): recursive clock topology detected, id %d.\n",
- __func__, entity_id);
- return -EINVAL;
- }
-
- /* first, see if the ID we're looking for is a clock source already */
- source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
- if (source)
- return source->bClockID;
-
- selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
- if (selector) {
- int ret;
-
- /* the entity ID we are looking for is a selector.
- * find out what it currently selects */
- ret = uac_clock_selector_get_val(chip, selector->bClockID);
- if (ret < 0)
- return ret;
-
- /* Selector values are one-based */
-
- if (ret > selector->bNrInPins || ret < 1) {
- printk(KERN_ERR
- "%s(): selector reported illegal value, id %d, ret %d\n",
- __func__, selector->bClockID, ret);
-
- return -EINVAL;
- }
-
- return __uac_clock_find_source(chip, selector->baCSourceID[ret-1],
- visited);
- }
-
- /* FIXME: multipliers only act as pass-thru element for now */
- multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
- if (multiplier)
- return __uac_clock_find_source(chip, multiplier->bCSourceID,
- visited);
-
- return -EINVAL;
-}
-
-/*
- * For all kinds of sample rate settings and other device queries,
- * the clock source (end-leaf) must be used. However, clock selectors,
- * clock multipliers and sample rate converters may be specified as
- * clock source input to terminal. This functions walks the clock path
- * to its end and tries to find the source.
- *
- * The 'visited' bitfield is used internally to detect recursive loops.
- *
- * Returns the clock source UnitID (>=0) on success, or an error.
- */
-int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id)
-{
- DECLARE_BITMAP(visited, 256);
- memset(visited, 0, sizeof(visited));
- return __uac_clock_find_source(chip, entity_id, visited);
-}
-
-static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt, int rate)
-{
- struct usb_device *dev = chip->dev;
- unsigned int ep;
- unsigned char data[3];
- int err, crate;
-
- ep = get_endpoint(alts, 0)->bEndpointAddress;
-
- /* if endpoint doesn't have sampling rate control, bail out */
- if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))
- return 0;
-
- data[0] = rate;
- data[1] = rate >> 8;
- data[2] = rate >> 16;
- if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
- USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
- data, sizeof(data))) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n",
- dev->devnum, iface, fmt->altsetting, rate, ep);
- //return err; //just not return, otherwise, logitech camera mic,can't use 2013-10-23
- //printk("%s snd_usb_ctl_msg set rate err! \n", __FUNCTION__);
- //return 0;//dbg if application set the rate that usb audio support just return 0! 2013-10-23
- }
-
- if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
- USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
- UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
- data, sizeof(data))) < 0) {
- snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n",
- dev->devnum, iface, fmt->altsetting, ep);
- printk("%s snd_usb_ctl_msg get rate err!\n", __FUNCTION__);
- return 0; /* some devices don't support reading */
- }
-
- crate = data[0] | (data[1] << 8) | (data[2] << 16);
- printk("%s snd_usb_ctl_msg get rate 2 :%d!\n", __FUNCTION__, crate);
- if (crate != rate) {
- snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
- // runtime->rate = crate;
- }
-
- return 0;
-}
-
-static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt, int rate)
-{
- struct usb_device *dev = chip->dev;
- unsigned char data[4];
- int err, crate;
- int clock = snd_usb_clock_find_source(chip, fmt->clock);
-
- if (clock < 0)
- return clock;
-
- if (!uac_clock_source_is_valid(chip, clock)) {
- /* TODO: should we try to find valid clock setups by ourself? */
- snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n",
- dev->devnum, iface, fmt->altsetting, clock);
- return -ENXIO;
- }
-
- data[0] = rate;
- data[1] = rate >> 8;
- data[2] = rate >> 16;
- data[3] = rate >> 24;
- if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
- UAC2_CS_CONTROL_SAM_FREQ << 8,
- snd_usb_ctrl_intf(chip) | (clock << 8),
- data, sizeof(data))) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n",
- dev->devnum, iface, fmt->altsetting, rate);
- return err;
- }
-
- if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- UAC2_CS_CONTROL_SAM_FREQ << 8,
- snd_usb_ctrl_intf(chip) | (clock << 8),
- data, sizeof(data))) < 0) {
- snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n",
- dev->devnum, iface, fmt->altsetting);
- return err;
- }
-
- crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
- if (crate != rate)
- snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate);
-
- return 0;
-}
-
-int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt, int rate)
-{
- struct usb_interface_descriptor *altsd = get_iface_desc(alts);
-
- switch (altsd->bInterfaceProtocol) {
- case UAC_VERSION_1:
- default:
- return set_sample_rate_v1(chip, iface, alts, fmt, rate);
-
- case UAC_VERSION_2:
- return set_sample_rate_v2(chip, iface, alts, fmt, rate);
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/clock.h b/ANDROID_3.4.5/sound/usb/clock.h
deleted file mode 100644
index 46630936..00000000
--- a/ANDROID_3.4.5/sound/usb/clock.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __USBAUDIO_CLOCK_H
-#define __USBAUDIO_CLOCK_H
-
-int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt, int rate);
-
-int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id);
-
-#endif /* __USBAUDIO_CLOCK_H */
diff --git a/ANDROID_3.4.5/sound/usb/debug.h b/ANDROID_3.4.5/sound/usb/debug.h
deleted file mode 100644
index 58030176..00000000
--- a/ANDROID_3.4.5/sound/usb/debug.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __USBAUDIO_DEBUG_H
-#define __USBAUDIO_DEBUG_H
-
-/*
- * h/w constraints
- */
-
-#ifdef HW_CONST_DEBUG
-#define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args)
-#else
-#define hwc_debug(fmt, args...) do { } while(0)
-#endif
-
-#endif /* __USBAUDIO_DEBUG_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/endpoint.c b/ANDROID_3.4.5/sound/usb/endpoint.c
deleted file mode 100644
index 08dcce53..00000000
--- a/ANDROID_3.4.5/sound/usb/endpoint.c
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/ratelimit.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "helper.h"
-#include "card.h"
-#include "endpoint.h"
-#include "pcm.h"
-
-/*
- * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
- * this will overflow at approx 524 kHz
- */
-static inline unsigned get_usb_full_speed_rate(unsigned int rate)
-{
- return ((rate << 13) + 62) / 125;
-}
-
-/*
- * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
- * this will overflow at approx 4 MHz
- */
-static inline unsigned get_usb_high_speed_rate(unsigned int rate)
-{
- return ((rate << 10) + 62) / 125;
-}
-
-/*
- * unlink active urbs.
- */
-static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
-{
- struct snd_usb_audio *chip = subs->stream->chip;
- unsigned int i;
- int async;
-
- subs->running = 0;
-
- if (!force && subs->stream->chip->shutdown) /* to be sure... */
- return -EBADFD;
-
- async = !can_sleep && chip->async_unlink;
-
- if (!async && in_interrupt())
- return 0;
-
- for (i = 0; i < subs->nurbs; i++) {
- if (test_bit(i, &subs->active_mask)) {
- if (!test_and_set_bit(i, &subs->unlink_mask)) {
- struct urb *u = subs->dataurb[i].urb;
- if (async)
- usb_unlink_urb(u);
- else
- usb_kill_urb(u);
- }
- }
- }
- if (subs->syncpipe) {
- for (i = 0; i < SYNC_URBS; i++) {
- if (test_bit(i+16, &subs->active_mask)) {
- if (!test_and_set_bit(i+16, &subs->unlink_mask)) {
- struct urb *u = subs->syncurb[i].urb;
- if (async)
- usb_unlink_urb(u);
- else
- usb_kill_urb(u);
- }
- }
- }
- }
- return 0;
-}
-
-
-/*
- * release a urb data
- */
-static void release_urb_ctx(struct snd_urb_ctx *u)
-{
- if (u->urb) {
- if (u->buffer_size)
- usb_free_coherent(u->subs->dev, u->buffer_size,
- u->urb->transfer_buffer,
- u->urb->transfer_dma);
- usb_free_urb(u->urb);
- u->urb = NULL;
- }
-}
-
-/*
- * wait until all urbs are processed.
- */
-static int wait_clear_urbs(struct snd_usb_substream *subs)
-{
- unsigned long end_time = jiffies + msecs_to_jiffies(1000);
- unsigned int i;
- int alive;
-
- do {
- alive = 0;
- for (i = 0; i < subs->nurbs; i++) {
- if (test_bit(i, &subs->active_mask))
- alive++;
- }
- if (subs->syncpipe) {
- for (i = 0; i < SYNC_URBS; i++) {
- if (test_bit(i + 16, &subs->active_mask))
- alive++;
- }
- }
- if (! alive)
- break;
- schedule_timeout_uninterruptible(1);
- } while (time_before(jiffies, end_time));
- if (alive)
- snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
- return 0;
-}
-
-/*
- * release a substream
- */
-void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force)
-{
- int i;
-
- /* stop urbs (to be sure) */
- deactivate_urbs(subs, force, 1);
- wait_clear_urbs(subs);
-
- for (i = 0; i < MAX_URBS; i++)
- release_urb_ctx(&subs->dataurb[i]);
- for (i = 0; i < SYNC_URBS; i++)
- release_urb_ctx(&subs->syncurb[i]);
- usb_free_coherent(subs->dev, SYNC_URBS * 4,
- subs->syncbuf, subs->sync_dma);
- subs->syncbuf = NULL;
- subs->nurbs = 0;
-}
-
-/*
- * complete callback from data urb
- */
-static void snd_complete_urb(struct urb *urb)
-{
- struct snd_urb_ctx *ctx = urb->context;
- struct snd_usb_substream *subs = ctx->subs;
- struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
- int err = 0;
-
- if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
- !subs->running || /* can be stopped during retire callback */
- (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 ||
- (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- clear_bit(ctx->index, &subs->active_mask);
- if (err < 0) {
- snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err);
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- }
- }
-}
-
-
-/*
- * complete callback from sync urb
- */
-static void snd_complete_sync_urb(struct urb *urb)
-{
- struct snd_urb_ctx *ctx = urb->context;
- struct snd_usb_substream *subs = ctx->subs;
- struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
- int err = 0;
-
- if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
- !subs->running || /* can be stopped during retire callback */
- (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 ||
- (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- clear_bit(ctx->index + 16, &subs->active_mask);
- if (err < 0) {
- snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err);
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- }
- }
-}
-
-
-/*
- * initialize a substream for plaback/capture
- */
-int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
- unsigned int period_bytes,
- unsigned int rate,
- unsigned int frame_bits)
-{
- unsigned int maxsize, i;
- int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
- unsigned int urb_packs, total_packs, packs_per_ms;
- struct snd_usb_audio *chip = subs->stream->chip;
-
- /* calculate the frequency in 16.16 format */
- if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
- subs->freqn = get_usb_full_speed_rate(rate);
- else
- subs->freqn = get_usb_high_speed_rate(rate);
- subs->freqm = subs->freqn;
- subs->freqshift = INT_MIN;
- /* calculate max. frequency */
- if (subs->maxpacksize) {
- /* whatever fits into a max. size packet */
- maxsize = subs->maxpacksize;
- subs->freqmax = (maxsize / (frame_bits >> 3))
- << (16 - subs->datainterval);
- } else {
- /* no max. packet size: just take 25% higher than nominal */
- subs->freqmax = subs->freqn + (subs->freqn >> 2);
- maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
- >> (16 - subs->datainterval);
- }
- subs->phase = 0;
-
- if (subs->fill_max)
- subs->curpacksize = subs->maxpacksize;
- else
- subs->curpacksize = maxsize;
-
- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
- packs_per_ms = 8 >> subs->datainterval;
- else
- packs_per_ms = 1;
-
- if (is_playback) {
- urb_packs = max(chip->nrpacks, 1);
- urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
- } else
- urb_packs = 1;
- urb_packs *= packs_per_ms;
- if (subs->syncpipe)
- urb_packs = min(urb_packs, 1U << subs->syncinterval);
-
- /* decide how many packets to be used */
- if (is_playback) {
- unsigned int minsize, maxpacks;
- /* determine how small a packet can be */
- minsize = (subs->freqn >> (16 - subs->datainterval))
- * (frame_bits >> 3);
- /* with sync from device, assume it can be 12% lower */
- if (subs->syncpipe)
- minsize -= minsize >> 3;
- minsize = max(minsize, 1u);
- total_packs = (period_bytes + minsize - 1) / minsize;
- /* we need at least two URBs for queueing */
- if (total_packs < 2) {
- total_packs = 2;
- } else {
- /* and we don't want too long a queue either */
- maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2);
- total_packs = min(total_packs, maxpacks);
- }
- } else {
- while (urb_packs > 1 && urb_packs * maxsize >= period_bytes)
- urb_packs >>= 1;
- total_packs = MAX_URBS * urb_packs;
- }
- subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
- if (subs->nurbs > MAX_URBS) {
- /* too much... */
- subs->nurbs = MAX_URBS;
- total_packs = MAX_URBS * urb_packs;
- } else if (subs->nurbs < 2) {
- /* too little - we need at least two packets
- * to ensure contiguous playback/capture
- */
- subs->nurbs = 2;
- }
-
- /* allocate and initialize data urbs */
- for (i = 0; i < subs->nurbs; i++) {
- struct snd_urb_ctx *u = &subs->dataurb[i];
- u->index = i;
- u->subs = subs;
- u->packets = (i + 1) * total_packs / subs->nurbs
- - i * total_packs / subs->nurbs;
- u->buffer_size = maxsize * u->packets;
- if (subs->fmt_type == UAC_FORMAT_TYPE_II)
- u->packets++; /* for transfer delimiter */
- u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
- if (!u->urb)
- goto out_of_memory;
- u->urb->transfer_buffer =
- usb_alloc_coherent(subs->dev, u->buffer_size,
- GFP_KERNEL, &u->urb->transfer_dma);
- if (!u->urb->transfer_buffer)
- goto out_of_memory;
- u->urb->pipe = subs->datapipe;
- u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
- u->urb->interval = 1 << subs->datainterval;
- u->urb->context = u;
- u->urb->complete = snd_complete_urb;
- }
-
- if (subs->syncpipe) {
- /* allocate and initialize sync urbs */
- subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4,
- GFP_KERNEL, &subs->sync_dma);
- if (!subs->syncbuf)
- goto out_of_memory;
- for (i = 0; i < SYNC_URBS; i++) {
- struct snd_urb_ctx *u = &subs->syncurb[i];
- u->index = i;
- u->subs = subs;
- u->packets = 1;
- u->urb = usb_alloc_urb(1, GFP_KERNEL);
- if (!u->urb)
- goto out_of_memory;
- u->urb->transfer_buffer = subs->syncbuf + i * 4;
- u->urb->transfer_dma = subs->sync_dma + i * 4;
- u->urb->transfer_buffer_length = 4;
- u->urb->pipe = subs->syncpipe;
- u->urb->transfer_flags = URB_ISO_ASAP |
- URB_NO_TRANSFER_DMA_MAP;
- u->urb->number_of_packets = 1;
- u->urb->interval = 1 << subs->syncinterval;
- u->urb->context = u;
- u->urb->complete = snd_complete_sync_urb;
- }
- }
- return 0;
-
-out_of_memory:
- snd_usb_release_substream_urbs(subs, 0);
- return -ENOMEM;
-}
-
-/*
- * prepare urb for full speed capture sync pipe
- *
- * fill the length and offset of each urb descriptor.
- * the fixed 10.14 frequency is passed through the pipe.
- */
-static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned char *cp = urb->transfer_buffer;
- struct snd_urb_ctx *ctx = urb->context;
-
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- urb->iso_frame_desc[0].length = 3;
- urb->iso_frame_desc[0].offset = 0;
- cp[0] = subs->freqn >> 2;
- cp[1] = subs->freqn >> 10;
- cp[2] = subs->freqn >> 18;
- return 0;
-}
-
-/*
- * prepare urb for high speed capture sync pipe
- *
- * fill the length and offset of each urb descriptor.
- * the fixed 12.13 frequency is passed as 16.16 through the pipe.
- */
-static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned char *cp = urb->transfer_buffer;
- struct snd_urb_ctx *ctx = urb->context;
-
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- urb->iso_frame_desc[0].length = 4;
- urb->iso_frame_desc[0].offset = 0;
- cp[0] = subs->freqn;
- cp[1] = subs->freqn >> 8;
- cp[2] = subs->freqn >> 16;
- cp[3] = subs->freqn >> 24;
- return 0;
-}
-
-/*
- * process after capture sync complete
- * - nothing to do
- */
-static int retire_capture_sync_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- return 0;
-}
-
-/*
- * prepare urb for capture data pipe
- *
- * fill the offset and length of each descriptor.
- *
- * we use a temporary buffer to write the captured data.
- * since the length of written data is determined by host, we cannot
- * write onto the pcm buffer directly... the data is thus copied
- * later at complete callback to the global buffer.
- */
-static int prepare_capture_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- int i, offs;
- struct snd_urb_ctx *ctx = urb->context;
-
- offs = 0;
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- for (i = 0; i < ctx->packets; i++) {
- urb->iso_frame_desc[i].offset = offs;
- urb->iso_frame_desc[i].length = subs->curpacksize;
- offs += subs->curpacksize;
- }
- urb->transfer_buffer_length = offs;
- urb->number_of_packets = ctx->packets;
- return 0;
-}
-
-/*
- * process after capture complete
- *
- * copy the data from each desctiptor to the pcm buffer, and
- * update the current position.
- */
-static int retire_capture_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned long flags;
- unsigned char *cp;
- int i;
- unsigned int stride, frames, bytes, oldptr;
- int period_elapsed = 0;
-
- stride = runtime->frame_bits >> 3;
-
- for (i = 0; i < urb->number_of_packets; i++) {
- cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (urb->iso_frame_desc[i].status && printk_ratelimit()) {
- snd_printdd("frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
- // continue;
- }
- bytes = urb->iso_frame_desc[i].actual_length;
- frames = bytes / stride;
- if (!subs->txfr_quirk)
- bytes = frames * stride;
- if (bytes % (runtime->sample_bits >> 3) != 0) {
-#ifdef CONFIG_SND_DEBUG_VERBOSE
- int oldbytes = bytes;
-#endif
- bytes = frames * stride;
- snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
- oldbytes, bytes);
- }
- /* update the current pointer */
- spin_lock_irqsave(&subs->lock, flags);
- oldptr = subs->hwptr_done;
- subs->hwptr_done += bytes;
- if (subs->hwptr_done >= runtime->buffer_size * stride)
- subs->hwptr_done -= runtime->buffer_size * stride;
- frames = (bytes + (oldptr % stride)) / stride;
- subs->transfer_done += frames;
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- period_elapsed = 1;
- }
- spin_unlock_irqrestore(&subs->lock, flags);
- /* copy a data chunk */
- if (oldptr + bytes > runtime->buffer_size * stride) {
- unsigned int bytes1 =
- runtime->buffer_size * stride - oldptr;
- memcpy(runtime->dma_area + oldptr, cp, bytes1);
- memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1);
- } else {
- memcpy(runtime->dma_area + oldptr, cp, bytes);
- }
- }
- if (period_elapsed)
- snd_pcm_period_elapsed(subs->pcm_substream);
- return 0;
-}
-
-/*
- * Process after capture complete when paused. Nothing to do.
- */
-static int retire_paused_capture_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- return 0;
-}
-
-
-/*
- * prepare urb for playback sync pipe
- *
- * set up the offset and length to receive the current frequency.
- */
-static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- struct snd_urb_ctx *ctx = urb->context;
-
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize);
- urb->iso_frame_desc[0].offset = 0;
- return 0;
-}
-
-/*
- * process after playback sync complete
- *
- * Full speed devices report feedback values in 10.14 format as samples per
- * frame, high speed devices in 16.16 format as samples per microframe.
- * Because the Audio Class 1 spec was written before USB 2.0, many high speed
- * devices use a wrong interpretation, some others use an entirely different
- * format. Therefore, we cannot predict what format any particular device uses
- * and must detect it automatically.
- */
-static int retire_playback_sync_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned int f;
- int shift;
- unsigned long flags;
-
- if (urb->iso_frame_desc[0].status != 0 ||
- urb->iso_frame_desc[0].actual_length < 3)
- return 0;
-
- f = le32_to_cpup(urb->transfer_buffer);
- if (urb->iso_frame_desc[0].actual_length == 3)
- f &= 0x00ffffff;
- else
- f &= 0x0fffffff;
- if (f == 0)
- return 0;
-
- if (unlikely(subs->freqshift == INT_MIN)) {
- /*
- * The first time we see a feedback value, determine its format
- * by shifting it left or right until it matches the nominal
- * frequency value. This assumes that the feedback does not
- * differ from the nominal value more than +50% or -25%.
- */
- shift = 0;
- while (f < subs->freqn - subs->freqn / 4) {
- f <<= 1;
- shift++;
- }
- while (f > subs->freqn + subs->freqn / 2) {
- f >>= 1;
- shift--;
- }
- subs->freqshift = shift;
- }
- else if (subs->freqshift >= 0)
- f <<= subs->freqshift;
- else
- f >>= -subs->freqshift;
-
- if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) {
- /*
- * If the frequency looks valid, set it.
- * This value is referred to in prepare_playback_urb().
- */
- spin_lock_irqsave(&subs->lock, flags);
- subs->freqm = f;
- spin_unlock_irqrestore(&subs->lock, flags);
- } else {
- /*
- * Out of range; maybe the shift value is wrong.
- * Reset it so that we autodetect again the next time.
- */
- subs->freqshift = INT_MIN;
- }
-
- return 0;
-}
-
-/* determine the number of frames in the next packet */
-static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs)
-{
- if (subs->fill_max)
- return subs->maxframesize;
- else {
- subs->phase = (subs->phase & 0xffff)
- + (subs->freqm << subs->datainterval);
- return min(subs->phase >> 16, subs->maxframesize);
- }
-}
-
-/*
- * Prepare urb for streaming before playback starts or when paused.
- *
- * We don't have any data, so we send silence.
- */
-static int prepare_nodata_playback_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned int i, offs, counts;
- struct snd_urb_ctx *ctx = urb->context;
- int stride = runtime->frame_bits >> 3;
-
- offs = 0;
- urb->dev = ctx->subs->dev;
- for (i = 0; i < ctx->packets; ++i) {
- counts = snd_usb_audio_next_packet_size(subs);
- urb->iso_frame_desc[i].offset = offs * stride;
- urb->iso_frame_desc[i].length = counts * stride;
- offs += counts;
- }
- urb->number_of_packets = ctx->packets;
- urb->transfer_buffer_length = offs * stride;
- memset(urb->transfer_buffer,
- runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
- offs * stride);
- return 0;
-}
-
-/*
- * prepare urb for playback data pipe
- *
- * Since a URB can handle only a single linear buffer, we must use double
- * buffering when the data to be transferred overflows the buffer boundary.
- * To avoid inconsistencies when updating hwptr_done, we use double buffering
- * for all URBs.
- */
-static int prepare_playback_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- int i, stride;
- unsigned int counts, frames, bytes;
- unsigned long flags;
- int period_elapsed = 0;
- struct snd_urb_ctx *ctx = urb->context;
-
- stride = runtime->frame_bits >> 3;
-
- frames = 0;
- urb->dev = ctx->subs->dev; /* we need to set this at each time */
- urb->number_of_packets = 0;
- spin_lock_irqsave(&subs->lock, flags);
- for (i = 0; i < ctx->packets; i++) {
- counts = snd_usb_audio_next_packet_size(subs);
- /* set up descriptor */
- urb->iso_frame_desc[i].offset = frames * stride;
- urb->iso_frame_desc[i].length = counts * stride;
- frames += counts;
- urb->number_of_packets++;
- subs->transfer_done += counts;
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- period_elapsed = 1;
- if (subs->fmt_type == UAC_FORMAT_TYPE_II) {
- if (subs->transfer_done > 0) {
- /* FIXME: fill-max mode is not
- * supported yet */
- frames -= subs->transfer_done;
- counts -= subs->transfer_done;
- urb->iso_frame_desc[i].length =
- counts * stride;
- subs->transfer_done = 0;
- }
- i++;
- if (i < ctx->packets) {
- /* add a transfer delimiter */
- urb->iso_frame_desc[i].offset =
- frames * stride;
- urb->iso_frame_desc[i].length = 0;
- urb->number_of_packets++;
- }
- break;
- }
- }
- if (period_elapsed) /* finish at the period boundary */
- break;
- }
- bytes = frames * stride;
- if (subs->hwptr_done + bytes > runtime->buffer_size * stride) {
- /* err, the transferred area goes over buffer boundary. */
- unsigned int bytes1 =
- runtime->buffer_size * stride - subs->hwptr_done;
- memcpy(urb->transfer_buffer,
- runtime->dma_area + subs->hwptr_done, bytes1);
- memcpy(urb->transfer_buffer + bytes1,
- runtime->dma_area, bytes - bytes1);
- } else {
- memcpy(urb->transfer_buffer,
- runtime->dma_area + subs->hwptr_done, bytes);
- }
- subs->hwptr_done += bytes;
- if (subs->hwptr_done >= runtime->buffer_size * stride)
- subs->hwptr_done -= runtime->buffer_size * stride;
-
- /* update delay with exact number of samples queued */
- runtime->delay = subs->last_delay;
- runtime->delay += frames;
- subs->last_delay = runtime->delay;
-
- /* realign last_frame_number */
- subs->last_frame_number = usb_get_current_frame_number(subs->dev);
- subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
-
- spin_unlock_irqrestore(&subs->lock, flags);
- urb->transfer_buffer_length = bytes;
- if (period_elapsed)
- snd_pcm_period_elapsed(subs->pcm_substream);
- return 0;
-}
-
-/*
- * process after playback data complete
- * - decrease the delay count again
- */
-static int retire_playback_urb(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime,
- struct urb *urb)
-{
- unsigned long flags;
- int stride = runtime->frame_bits >> 3;
- int processed = urb->transfer_buffer_length / stride;
- int est_delay;
-
- spin_lock_irqsave(&subs->lock, flags);
-
- est_delay = snd_usb_pcm_delay(subs, runtime->rate);
- /* update delay with exact number of samples played */
- if (processed > subs->last_delay)
- subs->last_delay = 0;
- else
- subs->last_delay -= processed;
- runtime->delay = subs->last_delay;
-
- /*
- * Report when delay estimate is off by more than 2ms.
- * The error should be lower than 2ms since the estimate relies
- * on two reads of a counter updated every ms.
- */
- if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2)
- snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n",
- est_delay, subs->last_delay);
-
- spin_unlock_irqrestore(&subs->lock, flags);
- return 0;
-}
-
-static const char *usb_error_string(int err)
-{
- switch (err) {
- case -ENODEV:
- return "no device";
- case -ENOENT:
- return "endpoint not enabled";
- case -EPIPE:
- return "endpoint stalled";
- case -ENOSPC:
- return "not enough bandwidth";
- case -ESHUTDOWN:
- return "device disabled";
- case -EHOSTUNREACH:
- return "device suspended";
- case -EINVAL:
- case -EAGAIN:
- case -EFBIG:
- case -EMSGSIZE:
- return "internal error";
- default:
- return "unknown error";
- }
-}
-
-/*
- * set up and start data/sync urbs
- */
-static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
-{
- unsigned int i;
- int err;
-
- if (subs->stream->chip->shutdown)
- return -EBADFD;
-
- for (i = 0; i < subs->nurbs; i++) {
- if (snd_BUG_ON(!subs->dataurb[i].urb))
- return -EINVAL;
- if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) {
- snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i);
- goto __error;
- }
- }
- if (subs->syncpipe) {
- for (i = 0; i < SYNC_URBS; i++) {
- if (snd_BUG_ON(!subs->syncurb[i].urb))
- return -EINVAL;
- if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) {
- snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i);
- goto __error;
- }
- }
- }
-
- subs->active_mask = 0;
- subs->unlink_mask = 0;
- subs->running = 1;
- for (i = 0; i < subs->nurbs; i++) {
- err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot submit datapipe "
- "for urb %d, error %d: %s\n",
- i, err, usb_error_string(err));
- goto __error;
- }
- set_bit(i, &subs->active_mask);
- }
- if (subs->syncpipe) {
- for (i = 0; i < SYNC_URBS; i++) {
- err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot submit syncpipe "
- "for urb %d, error %d: %s\n",
- i, err, usb_error_string(err));
- goto __error;
- }
- set_bit(i + 16, &subs->active_mask);
- }
- }
- return 0;
-
- __error:
- // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
- deactivate_urbs(subs, 0, 0);
- return -EPIPE;
-}
-
-
-/*
- */
-static struct snd_urb_ops audio_urb_ops[2] = {
- {
- .prepare = prepare_nodata_playback_urb,
- .retire = retire_playback_urb,
- .prepare_sync = prepare_playback_sync_urb,
- .retire_sync = retire_playback_sync_urb,
- },
- {
- .prepare = prepare_capture_urb,
- .retire = retire_capture_urb,
- .prepare_sync = prepare_capture_sync_urb,
- .retire_sync = retire_capture_sync_urb,
- },
-};
-
-/*
- * initialize the substream instance.
- */
-
-void snd_usb_init_substream(struct snd_usb_stream *as,
- int stream, struct audioformat *fp)
-{
- struct snd_usb_substream *subs = &as->substream[stream];
-
- INIT_LIST_HEAD(&subs->fmt_list);
- spin_lock_init(&subs->lock);
-
- subs->stream = as;
- subs->direction = stream;
- subs->dev = as->chip->dev;
- subs->txfr_quirk = as->chip->txfr_quirk;
- subs->ops = audio_urb_ops[stream];
- if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH)
- subs->ops.prepare_sync = prepare_capture_sync_urb_hs;
-
- snd_usb_set_pcm_ops(as->pcm, stream);
-
- list_add_tail(&fp->list, &subs->fmt_list);
- subs->formats |= fp->formats;
- subs->endpoint = fp->endpoint;
- subs->num_formats++;
- subs->fmt_type = fp->fmt_type;
-}
-
-int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_usb_substream *subs = substream->runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- subs->ops.prepare = prepare_playback_urb;
- return 0;
- case SNDRV_PCM_TRIGGER_STOP:
- return deactivate_urbs(subs, 0, 0);
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- subs->ops.prepare = prepare_nodata_playback_urb;
- return 0;
- }
-
- return -EINVAL;
-}
-
-int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_usb_substream *subs = substream->runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- subs->ops.retire = retire_capture_urb;
- return start_urbs(subs, substream->runtime);
- case SNDRV_PCM_TRIGGER_STOP:
- return deactivate_urbs(subs, 0, 0);
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- subs->ops.retire = retire_paused_capture_urb;
- return 0;
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- subs->ops.retire = retire_capture_urb;
- return 0;
- }
-
- return -EINVAL;
-}
-
-int snd_usb_substream_prepare(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime)
-{
- /* clear urbs (to be sure) */
- deactivate_urbs(subs, 0, 1);
- wait_clear_urbs(subs);
-
- /* for playback, submit the URBs now; otherwise, the first hwptr_done
- * updates for all URBs would happen at the same time when starting */
- if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
- subs->ops.prepare = prepare_nodata_playback_urb;
- return start_urbs(subs, runtime);
- }
-
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/endpoint.h b/ANDROID_3.4.5/sound/usb/endpoint.h
deleted file mode 100644
index 88eb63a6..00000000
--- a/ANDROID_3.4.5/sound/usb/endpoint.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __USBAUDIO_ENDPOINT_H
-#define __USBAUDIO_ENDPOINT_H
-
-void snd_usb_init_substream(struct snd_usb_stream *as,
- int stream,
- struct audioformat *fp);
-
-int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
- unsigned int period_bytes,
- unsigned int rate,
- unsigned int frame_bits);
-
-void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force);
-
-int snd_usb_substream_prepare(struct snd_usb_substream *subs,
- struct snd_pcm_runtime *runtime);
-
-int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd);
-int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd);
-
-#endif /* __USBAUDIO_ENDPOINT_H */
diff --git a/ANDROID_3.4.5/sound/usb/format.c b/ANDROID_3.4.5/sound/usb/format.c
deleted file mode 100644
index ddfef57c..00000000
--- a/ANDROID_3.4.5/sound/usb/format.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "quirks.h"
-#include "helper.h"
-#include "debug.h"
-#include "clock.h"
-#include "format.h"
-
-/*
- * parse the audio format type I descriptor
- * and returns the corresponding pcm format
- *
- * @dev: usb device
- * @fp: audioformat record
- * @format: the format tag (wFormatTag)
- * @fmt: the format type descriptor
- */
-static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
- struct audioformat *fp,
- int format, void *_fmt,
- int protocol)
-{
- int sample_width, sample_bytes;
- u64 pcm_formats;
-
- switch (protocol) {
- case UAC_VERSION_1:
- default: {
- struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
- sample_width = fmt->bBitResolution;
- sample_bytes = fmt->bSubframeSize;
- format = 1 << format;
- break;
- }
-
- case UAC_VERSION_2: {
- struct uac_format_type_i_ext_descriptor *fmt = _fmt;
- sample_width = fmt->bBitResolution;
- sample_bytes = fmt->bSubslotSize;
- format <<= 1;
- break;
- }
- }
-
- pcm_formats = 0;
-
- if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) {
- /* some devices don't define this correctly... */
- snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
- chip->dev->devnum, fp->iface, fp->altsetting);
- format = 1 << UAC_FORMAT_TYPE_I_PCM;
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) {
- if (chip->usb_id == USB_ID(0x0582, 0x0016) /* Edirol SD-90 */ &&
- sample_width == 24 && sample_bytes == 2)
- sample_bytes = 3;
- else if (sample_width > sample_bytes * 8) {
- snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
- chip->dev->devnum, fp->iface, fp->altsetting,
- sample_width, sample_bytes);
- }
- /* check the format byte size */
- switch (sample_bytes) {
- case 1:
- pcm_formats |= SNDRV_PCM_FMTBIT_S8;
- break;
- case 2:
- if (snd_usb_is_big_endian_format(chip, fp))
- pcm_formats |= SNDRV_PCM_FMTBIT_S16_BE; /* grrr, big endian!! */
- else
- pcm_formats |= SNDRV_PCM_FMTBIT_S16_LE;
- break;
- case 3:
- if (snd_usb_is_big_endian_format(chip, fp))
- pcm_formats |= SNDRV_PCM_FMTBIT_S24_3BE; /* grrr, big endian!! */
- else
- pcm_formats |= SNDRV_PCM_FMTBIT_S24_3LE;
- break;
- case 4:
- pcm_formats |= SNDRV_PCM_FMTBIT_S32_LE;
- break;
- default:
- snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
- chip->dev->devnum, fp->iface, fp->altsetting,
- sample_width, sample_bytes);
- break;
- }
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_PCM8)) {
- /* Dallas DS4201 workaround: it advertises U8 format, but really
- supports S8. */
- if (chip->usb_id == USB_ID(0x04fa, 0x4201))
- pcm_formats |= SNDRV_PCM_FMTBIT_S8;
- else
- pcm_formats |= SNDRV_PCM_FMTBIT_U8;
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_IEEE_FLOAT)) {
- pcm_formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_ALAW)) {
- pcm_formats |= SNDRV_PCM_FMTBIT_A_LAW;
- }
- if (format & (1 << UAC_FORMAT_TYPE_I_MULAW)) {
- pcm_formats |= SNDRV_PCM_FMTBIT_MU_LAW;
- }
- if (format & ~0x3f) {
- snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n",
- chip->dev->devnum, fp->iface, fp->altsetting, format);
- }
- return pcm_formats;
-}
-
-
-/*
- * parse the format descriptor and stores the possible sample rates
- * on the audioformat table (audio class v1).
- *
- * @dev: usb device
- * @fp: audioformat record
- * @fmt: the format descriptor
- * @offset: the start offset of descriptor pointing the rate type
- * (7 for type I and II, 8 for type II)
- */
-static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audioformat *fp,
- unsigned char *fmt, int offset)
-{
- int nr_rates = fmt[offset];
-
- if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
- chip->dev->devnum, fp->iface, fp->altsetting);
- return -1;
- }
-
- if (nr_rates) {
- /*
- * build the rate table and bitmap flags
- */
- int r, idx;
-
- fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
- if (fp->rate_table == NULL) {
- snd_printk(KERN_ERR "cannot malloc\n");
- return -1;
- }
-
- fp->nr_rates = 0;
- fp->rate_min = fp->rate_max = 0;
- for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
- unsigned int rate = combine_triple(&fmt[idx]);
- if (!rate)
- continue;
- /* C-Media CM6501 mislabels its 96 kHz altsetting */
- /* Terratec Aureon 7.1 USB C-Media 6206, too */
- if (rate == 48000 && nr_rates == 1 &&
- (chip->usb_id == USB_ID(0x0d8c, 0x0201) ||
- chip->usb_id == USB_ID(0x0d8c, 0x0102) ||
- chip->usb_id == USB_ID(0x0ccd, 0x00b1)) &&
- fp->altsetting == 5 && fp->maxpacksize == 392)
- rate = 96000;
- /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */
- if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068))
- rate = 8000;
-
- fp->rate_table[fp->nr_rates] = rate;
- if (!fp->rate_min || rate < fp->rate_min)
- fp->rate_min = rate;
- if (!fp->rate_max || rate > fp->rate_max)
- fp->rate_max = rate;
- fp->rates |= snd_pcm_rate_to_rate_bit(rate);
- fp->nr_rates++;
- }
- if (!fp->nr_rates) {
- hwc_debug("All rates were zero. Skipping format!\n");
- return -1;
- }
- } else {
- /* continuous rates */
- fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
- fp->rate_min = combine_triple(&fmt[offset + 1]);
- fp->rate_max = combine_triple(&fmt[offset + 4]);
- }
- return 0;
-}
-
-/*
- * Helper function to walk the array of sample rate triplets reported by
- * the device. The problem is that we need to parse whole array first to
- * get to know how many sample rates we have to expect.
- * Then fp->rate_table can be allocated and filled.
- */
-static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
- const unsigned char *data)
-{
- int i, nr_rates = 0;
-
- fp->rates = fp->rate_min = fp->rate_max = 0;
-
- for (i = 0; i < nr_triplets; i++) {
- int min = combine_quad(&data[2 + 12 * i]);
- int max = combine_quad(&data[6 + 12 * i]);
- int res = combine_quad(&data[10 + 12 * i]);
- unsigned int rate;
-
- if ((max < 0) || (min < 0) || (res < 0) || (max < min))
- continue;
-
- /*
- * for ranges with res == 1, we announce a continuous sample
- * rate range, and this function should return 0 for no further
- * parsing.
- */
- if (res == 1) {
- fp->rate_min = min;
- fp->rate_max = max;
- fp->rates = SNDRV_PCM_RATE_CONTINUOUS;
- return 0;
- }
-
- for (rate = min; rate <= max; rate += res) {
- if (fp->rate_table)
- fp->rate_table[nr_rates] = rate;
- if (!fp->rate_min || rate < fp->rate_min)
- fp->rate_min = rate;
- if (!fp->rate_max || rate > fp->rate_max)
- fp->rate_max = rate;
- fp->rates |= snd_pcm_rate_to_rate_bit(rate);
-
- nr_rates++;
- if (nr_rates >= MAX_NR_RATES) {
- snd_printk(KERN_ERR "invalid uac2 rates\n");
- break;
- }
-
- /* avoid endless loop */
- if (res == 0)
- break;
- }
- }
-
- return nr_rates;
-}
-
-/*
- * parse the format descriptor and stores the possible sample rates
- * on the audioformat table (audio class v2).
- */
-static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
- struct audioformat *fp)
-{
- struct usb_device *dev = chip->dev;
- unsigned char tmp[2], *data;
- int nr_triplets, data_size, ret = 0;
- int clock = snd_usb_clock_find_source(chip, fp->clock);
-
- if (clock < 0) {
- snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",
- __func__, clock);
- goto err;
- }
-
- /* get the number of sample rates first by only fetching 2 bytes */
- ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- UAC2_CS_CONTROL_SAM_FREQ << 8,
- snd_usb_ctrl_intf(chip) | (clock << 8),
- tmp, sizeof(tmp));
-
- if (ret < 0) {
- snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n",
- __func__, clock);
- goto err;
- }
-
- nr_triplets = (tmp[1] << 8) | tmp[0];
- data_size = 2 + 12 * nr_triplets;
- data = kzalloc(data_size, GFP_KERNEL);
- if (!data) {
- ret = -ENOMEM;
- goto err;
- }
-
- /* now get the full information */
- ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
- UAC2_CS_CONTROL_SAM_FREQ << 8,
- snd_usb_ctrl_intf(chip) | (clock << 8),
- data, data_size);
-
- if (ret < 0) {
- snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n",
- __func__, clock);
- ret = -EINVAL;
- goto err_free;
- }
-
- /* Call the triplet parser, and make sure fp->rate_table is NULL.
- * We just use the return value to know how many sample rates we
- * will have to deal with. */
- kfree(fp->rate_table);
- fp->rate_table = NULL;
- fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data);
-
- if (fp->nr_rates == 0) {
- /* SNDRV_PCM_RATE_CONTINUOUS */
- ret = 0;
- goto err_free;
- }
-
- fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL);
- if (!fp->rate_table) {
- ret = -ENOMEM;
- goto err_free;
- }
-
- /* Call the triplet parser again, but this time, fp->rate_table is
- * allocated, so the rates will be stored */
- parse_uac2_sample_rate_range(fp, nr_triplets, data);
-
-err_free:
- kfree(data);
-err:
- return ret;
-}
-
-/*
- * parse the format type I and III descriptors
- */
-static int parse_audio_format_i(struct snd_usb_audio *chip,
- struct audioformat *fp, int format,
- struct uac_format_type_i_continuous_descriptor *fmt,
- struct usb_host_interface *iface)
-{
- struct usb_interface_descriptor *altsd = get_iface_desc(iface);
- int protocol = altsd->bInterfaceProtocol;
- int pcm_format, ret;
-
- if (fmt->bFormatType == UAC_FORMAT_TYPE_III) {
- /* FIXME: the format type is really IECxxx
- * but we give normal PCM format to get the existing
- * apps working...
- */
- switch (chip->usb_id) {
-
- case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
- if (chip->setup == 0x00 &&
- fp->altsetting == 6)
- pcm_format = SNDRV_PCM_FORMAT_S16_BE;
- else
- pcm_format = SNDRV_PCM_FORMAT_S16_LE;
- break;
- default:
- pcm_format = SNDRV_PCM_FORMAT_S16_LE;
- }
- fp->formats = 1uLL << pcm_format;
- } else {
- fp->formats = parse_audio_format_i_type(chip, fp, format,
- fmt, protocol);
- if (!fp->formats)
- return -1;
- }
-
- /* gather possible sample rates */
- /* audio class v1 reports possible sample rates as part of the
- * proprietary class specific descriptor.
- * audio class v2 uses class specific EP0 range requests for that.
- */
- switch (protocol) {
- default:
- snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
- chip->dev->devnum, fp->iface, fp->altsetting, protocol);
- /* fall through */
- case UAC_VERSION_1:
- fp->channels = fmt->bNrChannels;
- ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
- break;
- case UAC_VERSION_2:
- /* fp->channels is already set in this case */
- ret = parse_audio_format_rates_v2(chip, fp);
- break;
- }
-
- if (fp->channels < 1) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
- chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
- return -1;
- }
-
- return ret;
-}
-
-/*
- * parse the format type II descriptor
- */
-static int parse_audio_format_ii(struct snd_usb_audio *chip,
- struct audioformat *fp,
- int format, void *_fmt,
- struct usb_host_interface *iface)
-{
- int brate, framesize, ret;
- struct usb_interface_descriptor *altsd = get_iface_desc(iface);
- int protocol = altsd->bInterfaceProtocol;
-
- switch (format) {
- case UAC_FORMAT_TYPE_II_AC3:
- /* FIXME: there is no AC3 format defined yet */
- // fp->formats = SNDRV_PCM_FMTBIT_AC3;
- fp->formats = SNDRV_PCM_FMTBIT_U8; /* temporary hack to receive byte streams */
- break;
- case UAC_FORMAT_TYPE_II_MPEG:
- fp->formats = SNDRV_PCM_FMTBIT_MPEG;
- break;
- default:
- snd_printd(KERN_INFO "%d:%u:%d : unknown format tag %#x is detected. processed as MPEG.\n",
- chip->dev->devnum, fp->iface, fp->altsetting, format);
- fp->formats = SNDRV_PCM_FMTBIT_MPEG;
- break;
- }
-
- fp->channels = 1;
-
- switch (protocol) {
- default:
- snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
- chip->dev->devnum, fp->iface, fp->altsetting, protocol);
- /* fall through */
- case UAC_VERSION_1: {
- struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
- brate = le16_to_cpu(fmt->wMaxBitRate);
- framesize = le16_to_cpu(fmt->wSamplesPerFrame);
- snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
- fp->frame_size = framesize;
- ret = parse_audio_format_rates_v1(chip, fp, _fmt, 8); /* fmt[8..] sample rates */
- break;
- }
- case UAC_VERSION_2: {
- struct uac_format_type_ii_ext_descriptor *fmt = _fmt;
- brate = le16_to_cpu(fmt->wMaxBitRate);
- framesize = le16_to_cpu(fmt->wSamplesPerFrame);
- snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
- fp->frame_size = framesize;
- ret = parse_audio_format_rates_v2(chip, fp);
- break;
- }
- }
-
- return ret;
-}
-
-int snd_usb_parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
- int format, struct uac_format_type_i_continuous_descriptor *fmt,
- int stream, struct usb_host_interface *iface)
-{
- int err;
-
- switch (fmt->bFormatType) {
- case UAC_FORMAT_TYPE_I:
- case UAC_FORMAT_TYPE_III:
- err = parse_audio_format_i(chip, fp, format, fmt, iface);
- break;
- case UAC_FORMAT_TYPE_II:
- err = parse_audio_format_ii(chip, fp, format, fmt, iface);
- break;
- default:
- snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
- chip->dev->devnum, fp->iface, fp->altsetting,
- fmt->bFormatType);
- return -ENOTSUPP;
- }
- fp->fmt_type = fmt->bFormatType;
- if (err < 0)
- return err;
-#if 1
- /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
- /* extigy apparently supports sample rates other than 48k
- * but not in ordinary way. so we enable only 48k atm.
- */
- if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
- chip->usb_id == USB_ID(0x041e, 0x3020) ||
- chip->usb_id == USB_ID(0x041e, 0x3061)) {
- if (fmt->bFormatType == UAC_FORMAT_TYPE_I &&
- fp->rates != SNDRV_PCM_RATE_48000 &&
- fp->rates != SNDRV_PCM_RATE_96000)
- return -ENOTSUPP;
- }
-#endif
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/format.h b/ANDROID_3.4.5/sound/usb/format.h
deleted file mode 100644
index 387924f0..00000000
--- a/ANDROID_3.4.5/sound/usb/format.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __USBAUDIO_FORMAT_H
-#define __USBAUDIO_FORMAT_H
-
-int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
- struct audioformat *fp, int format,
- struct uac_format_type_i_continuous_descriptor *fmt,
- int stream, struct usb_host_interface *iface);
-
-#endif /* __USBAUDIO_FORMAT_H */
diff --git a/ANDROID_3.4.5/sound/usb/helper.c b/ANDROID_3.4.5/sound/usb/helper.c
deleted file mode 100644
index 9eed8f40..00000000
--- a/ANDROID_3.4.5/sound/usb/helper.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-
-#include "usbaudio.h"
-#include "helper.h"
-
-/*
- * combine bytes and get an integer value
- */
-unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size)
-{
- switch (size) {
- case 1: return *bytes;
- case 2: return combine_word(bytes);
- case 3: return combine_triple(bytes);
- case 4: return combine_quad(bytes);
- default: return 0;
- }
-}
-
-/*
- * parse descriptor buffer and return the pointer starting the given
- * descriptor type.
- */
-void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype)
-{
- u8 *p, *end, *next;
-
- p = descstart;
- end = p + desclen;
- for (; p < end;) {
- if (p[0] < 2)
- return NULL;
- next = p + p[0];
- if (next > end)
- return NULL;
- if (p[1] == dtype && (!after || (void *)p > after)) {
- return p;
- }
- p = next;
- }
- return NULL;
-}
-
-/*
- * find a class-specified interface descriptor with the given subtype.
- */
-void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype)
-{
- unsigned char *p = after;
-
- while ((p = snd_usb_find_desc(buffer, buflen, p,
- USB_DT_CS_INTERFACE)) != NULL) {
- if (p[0] >= 3 && p[2] == dsubtype)
- return p;
- }
- return NULL;
-}
-
-/*
- * Wrapper for usb_control_msg().
- * Allocates a temp buffer to prevent dmaing from/to the stack.
- */
-int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
- __u8 requesttype, __u16 value, __u16 index, void *data,
- __u16 size)
-{
- int err;
- void *buf = NULL;
-
- if (size > 0) {
- buf = kmemdup(data, size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- }
- err = usb_control_msg(dev, pipe, request, requesttype,
- value, index, buf, size, 1000);
- if (size > 0) {
- memcpy(data, buf, size);
- kfree(buf);
- }
- return err;
-}
-
-unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
- struct usb_host_interface *alts)
-{
- switch (snd_usb_get_speed(chip->dev)) {
- case USB_SPEED_HIGH:
- case USB_SPEED_SUPER:
- if (get_endpoint(alts, 0)->bInterval >= 1 &&
- get_endpoint(alts, 0)->bInterval <= 4)
- return get_endpoint(alts, 0)->bInterval - 1;
- break;
- default:
- break;
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/helper.h b/ANDROID_3.4.5/sound/usb/helper.h
deleted file mode 100644
index 805c300d..00000000
--- a/ANDROID_3.4.5/sound/usb/helper.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __USBAUDIO_HELPER_H
-#define __USBAUDIO_HELPER_H
-
-unsigned int snd_usb_combine_bytes(unsigned char *bytes, int size);
-
-void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
-void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
-
-int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
- __u8 request, __u8 requesttype, __u16 value, __u16 index,
- void *data, __u16 size);
-
-unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
- struct usb_host_interface *alts);
-
-/*
- * retrieve usb_interface descriptor from the host interface
- * (conditional for compatibility with the older API)
- */
-#ifndef get_iface_desc
-#define get_iface_desc(iface) (&(iface)->desc)
-#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
-#define get_ep_desc(ep) (&(ep)->desc)
-#define get_cfg_desc(cfg) (&(cfg)->desc)
-#endif
-
-#ifndef snd_usb_get_speed
-#define snd_usb_get_speed(dev) ((dev)->speed)
-#endif
-
-static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip)
-{
- return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber;
-}
-
-#endif /* __USBAUDIO_HELPER_H */
diff --git a/ANDROID_3.4.5/sound/usb/midi.c b/ANDROID_3.4.5/sound/usb/midi.c
deleted file mode 100644
index c83f6143..00000000
--- a/ANDROID_3.4.5/sound/usb/midi.c
+++ /dev/null
@@ -1,2237 +0,0 @@
-/*
- * usbmidi.c - ALSA USB MIDI driver
- *
- * Copyright (c) 2002-2009 Clemens Ladisch
- * All rights reserved.
- *
- * Based on the OSS usb-midi driver by NAGANO Daisuke,
- * NetBSD's umidi driver by Takuya SHIOZAKI,
- * the "USB Device Class Definition for MIDI Devices" by Roland
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed and/or modified under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
-#include <linux/usb.h>
-#include <linux/wait.h>
-#include <linux/usb/audio.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/rawmidi.h>
-#include <sound/asequencer.h>
-#include "usbaudio.h"
-#include "midi.h"
-#include "power.h"
-#include "helper.h"
-
-/*
- * define this to log all USB packets
- */
-/* #define DUMP_PACKETS */
-
-/*
- * how long to wait after some USB errors, so that khubd can disconnect() us
- * without too many spurious errors
- */
-#define ERROR_DELAY_JIFFIES (HZ / 10)
-
-#define OUTPUT_URBS 7
-#define INPUT_URBS 7
-
-
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_DESCRIPTION("USB Audio/MIDI helper module");
-MODULE_LICENSE("Dual BSD/GPL");
-
-
-struct usb_ms_header_descriptor {
- __u8 bLength;
- __u8 bDescriptorType;
- __u8 bDescriptorSubtype;
- __u8 bcdMSC[2];
- __le16 wTotalLength;
-} __attribute__ ((packed));
-
-struct usb_ms_endpoint_descriptor {
- __u8 bLength;
- __u8 bDescriptorType;
- __u8 bDescriptorSubtype;
- __u8 bNumEmbMIDIJack;
- __u8 baAssocJackID[0];
-} __attribute__ ((packed));
-
-struct snd_usb_midi_in_endpoint;
-struct snd_usb_midi_out_endpoint;
-struct snd_usb_midi_endpoint;
-
-struct usb_protocol_ops {
- void (*input)(struct snd_usb_midi_in_endpoint*, uint8_t*, int);
- void (*output)(struct snd_usb_midi_out_endpoint *ep, struct urb *urb);
- void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t);
- void (*init_out_endpoint)(struct snd_usb_midi_out_endpoint*);
- void (*finish_out_endpoint)(struct snd_usb_midi_out_endpoint*);
-};
-
-struct snd_usb_midi {
- struct usb_device *dev;
- struct snd_card *card;
- struct usb_interface *iface;
- const struct snd_usb_audio_quirk *quirk;
- struct snd_rawmidi *rmidi;
- struct usb_protocol_ops* usb_protocol_ops;
- struct list_head list;
- struct timer_list error_timer;
- spinlock_t disc_lock;
- struct mutex mutex;
- u32 usb_id;
- int next_midi_device;
-
- struct snd_usb_midi_endpoint {
- struct snd_usb_midi_out_endpoint *out;
- struct snd_usb_midi_in_endpoint *in;
- } endpoints[MIDI_MAX_ENDPOINTS];
- unsigned long input_triggered;
- unsigned int opened;
- unsigned char disconnected;
-
- struct snd_kcontrol *roland_load_ctl;
-};
-
-struct snd_usb_midi_out_endpoint {
- struct snd_usb_midi* umidi;
- struct out_urb_context {
- struct urb *urb;
- struct snd_usb_midi_out_endpoint *ep;
- } urbs[OUTPUT_URBS];
- unsigned int active_urbs;
- unsigned int drain_urbs;
- int max_transfer; /* size of urb buffer */
- struct tasklet_struct tasklet;
- unsigned int next_urb;
- spinlock_t buffer_lock;
-
- struct usbmidi_out_port {
- struct snd_usb_midi_out_endpoint* ep;
- struct snd_rawmidi_substream *substream;
- int active;
- uint8_t cable; /* cable number << 4 */
- uint8_t state;
-#define STATE_UNKNOWN 0
-#define STATE_1PARAM 1
-#define STATE_2PARAM_1 2
-#define STATE_2PARAM_2 3
-#define STATE_SYSEX_0 4
-#define STATE_SYSEX_1 5
-#define STATE_SYSEX_2 6
- uint8_t data[2];
- } ports[0x10];
- int current_port;
-
- wait_queue_head_t drain_wait;
-};
-
-struct snd_usb_midi_in_endpoint {
- struct snd_usb_midi* umidi;
- struct urb* urbs[INPUT_URBS];
- struct usbmidi_in_port {
- struct snd_rawmidi_substream *substream;
- u8 running_status_length;
- } ports[0x10];
- u8 seen_f5;
- u8 error_resubmit;
- int current_port;
-};
-
-static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep);
-
-static const uint8_t snd_usbmidi_cin_length[] = {
- 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
-};
-
-/*
- * Submits the URB, with error handling.
- */
-static int snd_usbmidi_submit_urb(struct urb* urb, gfp_t flags)
-{
- int err = usb_submit_urb(urb, flags);
- if (err < 0 && err != -ENODEV)
- snd_printk(KERN_ERR "usb_submit_urb: %d\n", err);
- return err;
-}
-
-/*
- * Error handling for URB completion functions.
- */
-static int snd_usbmidi_urb_error(int status)
-{
- switch (status) {
- /* manually unlinked, or device gone */
- case -ENOENT:
- case -ECONNRESET:
- case -ESHUTDOWN:
- case -ENODEV:
- return -ENODEV;
- /* errors that might occur during unplugging */
- case -EPROTO:
- case -ETIME:
- case -EILSEQ:
- return -EIO;
- default:
- snd_printk(KERN_ERR "urb status %d\n", status);
- return 0; /* continue */
- }
-}
-
-/*
- * Receives a chunk of MIDI data.
- */
-static void snd_usbmidi_input_data(struct snd_usb_midi_in_endpoint* ep, int portidx,
- uint8_t* data, int length)
-{
- struct usbmidi_in_port* port = &ep->ports[portidx];
-
- if (!port->substream) {
- snd_printd("unexpected port %d!\n", portidx);
- return;
- }
- if (!test_bit(port->substream->number, &ep->umidi->input_triggered))
- return;
- snd_rawmidi_receive(port->substream, data, length);
-}
-
-#ifdef DUMP_PACKETS
-static void dump_urb(const char *type, const u8 *data, int length)
-{
- snd_printk(KERN_DEBUG "%s packet: [", type);
- for (; length > 0; ++data, --length)
- printk(" %02x", *data);
- printk(" ]\n");
-}
-#else
-#define dump_urb(type, data, length) /* nothing */
-#endif
-
-/*
- * Processes the data read from the device.
- */
-static void snd_usbmidi_in_urb_complete(struct urb* urb)
-{
- struct snd_usb_midi_in_endpoint* ep = urb->context;
-
- if (urb->status == 0) {
- dump_urb("received", urb->transfer_buffer, urb->actual_length);
- ep->umidi->usb_protocol_ops->input(ep, urb->transfer_buffer,
- urb->actual_length);
- } else {
- int err = snd_usbmidi_urb_error(urb->status);
- if (err < 0) {
- if (err != -ENODEV) {
- ep->error_resubmit = 1;
- mod_timer(&ep->umidi->error_timer,
- jiffies + ERROR_DELAY_JIFFIES);
- }
- return;
- }
- }
-
- urb->dev = ep->umidi->dev;
- snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
-}
-
-static void snd_usbmidi_out_urb_complete(struct urb* urb)
-{
- struct out_urb_context *context = urb->context;
- struct snd_usb_midi_out_endpoint* ep = context->ep;
- unsigned int urb_index;
-
- spin_lock(&ep->buffer_lock);
- urb_index = context - ep->urbs;
- ep->active_urbs &= ~(1 << urb_index);
- if (unlikely(ep->drain_urbs)) {
- ep->drain_urbs &= ~(1 << urb_index);
- wake_up(&ep->drain_wait);
- }
- spin_unlock(&ep->buffer_lock);
- if (urb->status < 0) {
- int err = snd_usbmidi_urb_error(urb->status);
- if (err < 0) {
- if (err != -ENODEV)
- mod_timer(&ep->umidi->error_timer,
- jiffies + ERROR_DELAY_JIFFIES);
- return;
- }
- }
- snd_usbmidi_do_output(ep);
-}
-
-/*
- * This is called when some data should be transferred to the device
- * (from one or more substreams).
- */
-static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
-{
- unsigned int urb_index;
- struct urb* urb;
- unsigned long flags;
-
- spin_lock_irqsave(&ep->buffer_lock, flags);
- if (ep->umidi->disconnected) {
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
- return;
- }
-
- urb_index = ep->next_urb;
- for (;;) {
- if (!(ep->active_urbs & (1 << urb_index))) {
- urb = ep->urbs[urb_index].urb;
- urb->transfer_buffer_length = 0;
- ep->umidi->usb_protocol_ops->output(ep, urb);
- if (urb->transfer_buffer_length == 0)
- break;
-
- dump_urb("sending", urb->transfer_buffer,
- urb->transfer_buffer_length);
- urb->dev = ep->umidi->dev;
- if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0)
- break;
- ep->active_urbs |= 1 << urb_index;
- }
- if (++urb_index >= OUTPUT_URBS)
- urb_index = 0;
- if (urb_index == ep->next_urb)
- break;
- }
- ep->next_urb = urb_index;
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
-}
-
-static void snd_usbmidi_out_tasklet(unsigned long data)
-{
- struct snd_usb_midi_out_endpoint* ep = (struct snd_usb_midi_out_endpoint *) data;
-
- snd_usbmidi_do_output(ep);
-}
-
-/* called after transfers had been interrupted due to some USB error */
-static void snd_usbmidi_error_timer(unsigned long data)
-{
- struct snd_usb_midi *umidi = (struct snd_usb_midi *)data;
- unsigned int i, j;
-
- spin_lock(&umidi->disc_lock);
- if (umidi->disconnected) {
- spin_unlock(&umidi->disc_lock);
- return;
- }
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- struct snd_usb_midi_in_endpoint *in = umidi->endpoints[i].in;
- if (in && in->error_resubmit) {
- in->error_resubmit = 0;
- for (j = 0; j < INPUT_URBS; ++j) {
- in->urbs[j]->dev = umidi->dev;
- snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC);
- }
- }
- if (umidi->endpoints[i].out)
- snd_usbmidi_do_output(umidi->endpoints[i].out);
- }
- spin_unlock(&umidi->disc_lock);
-}
-
-/* helper function to send static data that may not DMA-able */
-static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep,
- const void *data, int len)
-{
- int err = 0;
- void *buf = kmemdup(data, len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- dump_urb("sending", buf, len);
- if (ep->urbs[0].urb)
- err = usb_bulk_msg(ep->umidi->dev, ep->urbs[0].urb->pipe,
- buf, len, NULL, 250);
- kfree(buf);
- return err;
-}
-
-/*
- * Standard USB MIDI protocol: see the spec.
- * Midiman protocol: like the standard protocol, but the control byte is the
- * fourth byte in each packet, and uses length instead of CIN.
- */
-
-static void snd_usbmidi_standard_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- int i;
-
- for (i = 0; i + 3 < buffer_length; i += 4)
- if (buffer[i] != 0) {
- int cable = buffer[i] >> 4;
- int length = snd_usbmidi_cin_length[buffer[i] & 0x0f];
- snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length);
- }
-}
-
-static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- int i;
-
- for (i = 0; i + 3 < buffer_length; i += 4)
- if (buffer[i + 3] != 0) {
- int port = buffer[i + 3] >> 4;
- int length = buffer[i + 3] & 3;
- snd_usbmidi_input_data(ep, port, &buffer[i], length);
- }
-}
-
-/*
- * Buggy M-Audio device: running status on input results in a packet that has
- * the data bytes but not the status byte and that is marked with CIN 4.
- */
-static void snd_usbmidi_maudio_broken_running_status_input(
- struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- int i;
-
- for (i = 0; i + 3 < buffer_length; i += 4)
- if (buffer[i] != 0) {
- int cable = buffer[i] >> 4;
- u8 cin = buffer[i] & 0x0f;
- struct usbmidi_in_port *port = &ep->ports[cable];
- int length;
-
- length = snd_usbmidi_cin_length[cin];
- if (cin == 0xf && buffer[i + 1] >= 0xf8)
- ; /* realtime msg: no running status change */
- else if (cin >= 0x8 && cin <= 0xe)
- /* channel msg */
- port->running_status_length = length - 1;
- else if (cin == 0x4 &&
- port->running_status_length != 0 &&
- buffer[i + 1] < 0x80)
- /* CIN 4 that is not a SysEx */
- length = port->running_status_length;
- else
- /*
- * All other msgs cannot begin running status.
- * (A channel msg sent as two or three CIN 0xF
- * packets could in theory, but this device
- * doesn't use this format.)
- */
- port->running_status_length = 0;
- snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length);
- }
-}
-
-/*
- * CME protocol: like the standard protocol, but SysEx commands are sent as a
- * single USB packet preceded by a 0x0F byte.
- */
-static void snd_usbmidi_cme_input(struct snd_usb_midi_in_endpoint *ep,
- uint8_t *buffer, int buffer_length)
-{
- if (buffer_length < 2 || (buffer[0] & 0x0f) != 0x0f)
- snd_usbmidi_standard_input(ep, buffer, buffer_length);
- else
- snd_usbmidi_input_data(ep, buffer[0] >> 4,
- &buffer[1], buffer_length - 1);
-}
-
-/*
- * Adds one USB MIDI packet to the output buffer.
- */
-static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0,
- uint8_t p1, uint8_t p2, uint8_t p3)
-{
-
- uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length;
- buf[0] = p0;
- buf[1] = p1;
- buf[2] = p2;
- buf[3] = p3;
- urb->transfer_buffer_length += 4;
-}
-
-/*
- * Adds one Midiman packet to the output buffer.
- */
-static void snd_usbmidi_output_midiman_packet(struct urb* urb, uint8_t p0,
- uint8_t p1, uint8_t p2, uint8_t p3)
-{
-
- uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length;
- buf[0] = p1;
- buf[1] = p2;
- buf[2] = p3;
- buf[3] = (p0 & 0xf0) | snd_usbmidi_cin_length[p0 & 0x0f];
- urb->transfer_buffer_length += 4;
-}
-
-/*
- * Converts MIDI commands to USB MIDI packets.
- */
-static void snd_usbmidi_transmit_byte(struct usbmidi_out_port* port,
- uint8_t b, struct urb* urb)
-{
- uint8_t p0 = port->cable;
- void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t) =
- port->ep->umidi->usb_protocol_ops->output_packet;
-
- if (b >= 0xf8) {
- output_packet(urb, p0 | 0x0f, b, 0, 0);
- } else if (b >= 0xf0) {
- switch (b) {
- case 0xf0:
- port->data[0] = b;
- port->state = STATE_SYSEX_1;
- break;
- case 0xf1:
- case 0xf3:
- port->data[0] = b;
- port->state = STATE_1PARAM;
- break;
- case 0xf2:
- port->data[0] = b;
- port->state = STATE_2PARAM_1;
- break;
- case 0xf4:
- case 0xf5:
- port->state = STATE_UNKNOWN;
- break;
- case 0xf6:
- output_packet(urb, p0 | 0x05, 0xf6, 0, 0);
- port->state = STATE_UNKNOWN;
- break;
- case 0xf7:
- switch (port->state) {
- case STATE_SYSEX_0:
- output_packet(urb, p0 | 0x05, 0xf7, 0, 0);
- break;
- case STATE_SYSEX_1:
- output_packet(urb, p0 | 0x06, port->data[0], 0xf7, 0);
- break;
- case STATE_SYSEX_2:
- output_packet(urb, p0 | 0x07, port->data[0], port->data[1], 0xf7);
- break;
- }
- port->state = STATE_UNKNOWN;
- break;
- }
- } else if (b >= 0x80) {
- port->data[0] = b;
- if (b >= 0xc0 && b <= 0xdf)
- port->state = STATE_1PARAM;
- else
- port->state = STATE_2PARAM_1;
- } else { /* b < 0x80 */
- switch (port->state) {
- case STATE_1PARAM:
- if (port->data[0] < 0xf0) {
- p0 |= port->data[0] >> 4;
- } else {
- p0 |= 0x02;
- port->state = STATE_UNKNOWN;
- }
- output_packet(urb, p0, port->data[0], b, 0);
- break;
- case STATE_2PARAM_1:
- port->data[1] = b;
- port->state = STATE_2PARAM_2;
- break;
- case STATE_2PARAM_2:
- if (port->data[0] < 0xf0) {
- p0 |= port->data[0] >> 4;
- port->state = STATE_2PARAM_1;
- } else {
- p0 |= 0x03;
- port->state = STATE_UNKNOWN;
- }
- output_packet(urb, p0, port->data[0], port->data[1], b);
- break;
- case STATE_SYSEX_0:
- port->data[0] = b;
- port->state = STATE_SYSEX_1;
- break;
- case STATE_SYSEX_1:
- port->data[1] = b;
- port->state = STATE_SYSEX_2;
- break;
- case STATE_SYSEX_2:
- output_packet(urb, p0 | 0x04, port->data[0], port->data[1], b);
- port->state = STATE_SYSEX_0;
- break;
- }
- }
-}
-
-static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint* ep,
- struct urb *urb)
-{
- int p;
-
- /* FIXME: lower-numbered ports can starve higher-numbered ports */
- for (p = 0; p < 0x10; ++p) {
- struct usbmidi_out_port* port = &ep->ports[p];
- if (!port->active)
- continue;
- while (urb->transfer_buffer_length + 3 < ep->max_transfer) {
- uint8_t b;
- if (snd_rawmidi_transmit(port->substream, &b, 1) != 1) {
- port->active = 0;
- break;
- }
- snd_usbmidi_transmit_byte(port, b, urb);
- }
- }
-}
-
-static struct usb_protocol_ops snd_usbmidi_standard_ops = {
- .input = snd_usbmidi_standard_input,
- .output = snd_usbmidi_standard_output,
- .output_packet = snd_usbmidi_output_standard_packet,
-};
-
-static struct usb_protocol_ops snd_usbmidi_midiman_ops = {
- .input = snd_usbmidi_midiman_input,
- .output = snd_usbmidi_standard_output,
- .output_packet = snd_usbmidi_output_midiman_packet,
-};
-
-static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
- .input = snd_usbmidi_maudio_broken_running_status_input,
- .output = snd_usbmidi_standard_output,
- .output_packet = snd_usbmidi_output_standard_packet,
-};
-
-static struct usb_protocol_ops snd_usbmidi_cme_ops = {
- .input = snd_usbmidi_cme_input,
- .output = snd_usbmidi_standard_output,
- .output_packet = snd_usbmidi_output_standard_packet,
-};
-
-/*
- * AKAI MPD16 protocol:
- *
- * For control port (endpoint 1):
- * ==============================
- * One or more chunks consisting of first byte of (0x10 | msg_len) and then a
- * SysEx message (msg_len=9 bytes long).
- *
- * For data port (endpoint 2):
- * ===========================
- * One or more chunks consisting of first byte of (0x20 | msg_len) and then a
- * MIDI message (msg_len bytes long)
- *
- * Messages sent: Active Sense, Note On, Poly Pressure, Control Change.
- */
-static void snd_usbmidi_akai_input(struct snd_usb_midi_in_endpoint *ep,
- uint8_t *buffer, int buffer_length)
-{
- unsigned int pos = 0;
- unsigned int len = (unsigned int)buffer_length;
- while (pos < len) {
- unsigned int port = (buffer[pos] >> 4) - 1;
- unsigned int msg_len = buffer[pos] & 0x0f;
- pos++;
- if (pos + msg_len <= len && port < 2)
- snd_usbmidi_input_data(ep, 0, &buffer[pos], msg_len);
- pos += msg_len;
- }
-}
-
-#define MAX_AKAI_SYSEX_LEN 9
-
-static void snd_usbmidi_akai_output(struct snd_usb_midi_out_endpoint *ep,
- struct urb *urb)
-{
- uint8_t *msg;
- int pos, end, count, buf_end;
- uint8_t tmp[MAX_AKAI_SYSEX_LEN];
- struct snd_rawmidi_substream *substream = ep->ports[0].substream;
-
- if (!ep->ports[0].active)
- return;
-
- msg = urb->transfer_buffer + urb->transfer_buffer_length;
- buf_end = ep->max_transfer - MAX_AKAI_SYSEX_LEN - 1;
-
- /* only try adding more data when there's space for at least 1 SysEx */
- while (urb->transfer_buffer_length < buf_end) {
- count = snd_rawmidi_transmit_peek(substream,
- tmp, MAX_AKAI_SYSEX_LEN);
- if (!count) {
- ep->ports[0].active = 0;
- return;
- }
- /* try to skip non-SysEx data */
- for (pos = 0; pos < count && tmp[pos] != 0xF0; pos++)
- ;
-
- if (pos > 0) {
- snd_rawmidi_transmit_ack(substream, pos);
- continue;
- }
-
- /* look for the start or end marker */
- for (end = 1; end < count && tmp[end] < 0xF0; end++)
- ;
-
- /* next SysEx started before the end of current one */
- if (end < count && tmp[end] == 0xF0) {
- /* it's incomplete - drop it */
- snd_rawmidi_transmit_ack(substream, end);
- continue;
- }
- /* SysEx complete */
- if (end < count && tmp[end] == 0xF7) {
- /* queue it, ack it, and get the next one */
- count = end + 1;
- msg[0] = 0x10 | count;
- memcpy(&msg[1], tmp, count);
- snd_rawmidi_transmit_ack(substream, count);
- urb->transfer_buffer_length += count + 1;
- msg += count + 1;
- continue;
- }
- /* less than 9 bytes and no end byte - wait for more */
- if (count < MAX_AKAI_SYSEX_LEN) {
- ep->ports[0].active = 0;
- return;
- }
- /* 9 bytes and no end marker in sight - malformed, skip it */
- snd_rawmidi_transmit_ack(substream, count);
- }
-}
-
-static struct usb_protocol_ops snd_usbmidi_akai_ops = {
- .input = snd_usbmidi_akai_input,
- .output = snd_usbmidi_akai_output,
-};
-
-/*
- * Novation USB MIDI protocol: number of data bytes is in the first byte
- * (when receiving) (+1!) or in the second byte (when sending); data begins
- * at the third byte.
- */
-
-static void snd_usbmidi_novation_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- if (buffer_length < 2 || !buffer[0] || buffer_length < buffer[0] + 1)
- return;
- snd_usbmidi_input_data(ep, 0, &buffer[2], buffer[0] - 1);
-}
-
-static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint* ep,
- struct urb *urb)
-{
- uint8_t* transfer_buffer;
- int count;
-
- if (!ep->ports[0].active)
- return;
- transfer_buffer = urb->transfer_buffer;
- count = snd_rawmidi_transmit(ep->ports[0].substream,
- &transfer_buffer[2],
- ep->max_transfer - 2);
- if (count < 1) {
- ep->ports[0].active = 0;
- return;
- }
- transfer_buffer[0] = 0;
- transfer_buffer[1] = count;
- urb->transfer_buffer_length = 2 + count;
-}
-
-static struct usb_protocol_ops snd_usbmidi_novation_ops = {
- .input = snd_usbmidi_novation_input,
- .output = snd_usbmidi_novation_output,
-};
-
-/*
- * "raw" protocol: just move raw MIDI bytes from/to the endpoint
- */
-
-static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
-}
-
-static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint* ep,
- struct urb *urb)
-{
- int count;
-
- if (!ep->ports[0].active)
- return;
- count = snd_rawmidi_transmit(ep->ports[0].substream,
- urb->transfer_buffer,
- ep->max_transfer);
- if (count < 1) {
- ep->ports[0].active = 0;
- return;
- }
- urb->transfer_buffer_length = count;
-}
-
-static struct usb_protocol_ops snd_usbmidi_raw_ops = {
- .input = snd_usbmidi_raw_input,
- .output = snd_usbmidi_raw_output,
-};
-
-/*
- * FTDI protocol: raw MIDI bytes, but input packets have two modem status bytes.
- */
-
-static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- if (buffer_length > 2)
- snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2);
-}
-
-static struct usb_protocol_ops snd_usbmidi_ftdi_ops = {
- .input = snd_usbmidi_ftdi_input,
- .output = snd_usbmidi_raw_output,
-};
-
-static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep,
- uint8_t *buffer, int buffer_length)
-{
- if (buffer_length != 9)
- return;
- buffer_length = 8;
- while (buffer_length && buffer[buffer_length - 1] == 0xFD)
- buffer_length--;
- if (buffer_length)
- snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
-}
-
-static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
- struct urb *urb)
-{
- int count;
-
- if (!ep->ports[0].active)
- return;
- switch (snd_usb_get_speed(ep->umidi->dev)) {
- case USB_SPEED_HIGH:
- case USB_SPEED_SUPER:
- count = 1;
- break;
- default:
- count = 2;
- }
- count = snd_rawmidi_transmit(ep->ports[0].substream,
- urb->transfer_buffer,
- count);
- if (count < 1) {
- ep->ports[0].active = 0;
- return;
- }
-
- memset(urb->transfer_buffer + count, 0xFD, ep->max_transfer - count);
- urb->transfer_buffer_length = ep->max_transfer;
-}
-
-static struct usb_protocol_ops snd_usbmidi_122l_ops = {
- .input = snd_usbmidi_us122l_input,
- .output = snd_usbmidi_us122l_output,
-};
-
-/*
- * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching.
- */
-
-static void snd_usbmidi_emagic_init_out(struct snd_usb_midi_out_endpoint* ep)
-{
- static const u8 init_data[] = {
- /* initialization magic: "get version" */
- 0xf0,
- 0x00, 0x20, 0x31, /* Emagic */
- 0x64, /* Unitor8 */
- 0x0b, /* version number request */
- 0x00, /* command version */
- 0x00, /* EEPROM, box 0 */
- 0xf7
- };
- send_bulk_static_data(ep, init_data, sizeof(init_data));
- /* while we're at it, pour on more magic */
- send_bulk_static_data(ep, init_data, sizeof(init_data));
-}
-
-static void snd_usbmidi_emagic_finish_out(struct snd_usb_midi_out_endpoint* ep)
-{
- static const u8 finish_data[] = {
- /* switch to patch mode with last preset */
- 0xf0,
- 0x00, 0x20, 0x31, /* Emagic */
- 0x64, /* Unitor8 */
- 0x10, /* patch switch command */
- 0x00, /* command version */
- 0x7f, /* to all boxes */
- 0x40, /* last preset in EEPROM */
- 0xf7
- };
- send_bulk_static_data(ep, finish_data, sizeof(finish_data));
-}
-
-static void snd_usbmidi_emagic_input(struct snd_usb_midi_in_endpoint* ep,
- uint8_t* buffer, int buffer_length)
-{
- int i;
-
- /* FF indicates end of valid data */
- for (i = 0; i < buffer_length; ++i)
- if (buffer[i] == 0xff) {
- buffer_length = i;
- break;
- }
-
- /* handle F5 at end of last buffer */
- if (ep->seen_f5)
- goto switch_port;
-
- while (buffer_length > 0) {
- /* determine size of data until next F5 */
- for (i = 0; i < buffer_length; ++i)
- if (buffer[i] == 0xf5)
- break;
- snd_usbmidi_input_data(ep, ep->current_port, buffer, i);
- buffer += i;
- buffer_length -= i;
-
- if (buffer_length <= 0)
- break;
- /* assert(buffer[0] == 0xf5); */
- ep->seen_f5 = 1;
- ++buffer;
- --buffer_length;
-
- switch_port:
- if (buffer_length <= 0)
- break;
- if (buffer[0] < 0x80) {
- ep->current_port = (buffer[0] - 1) & 15;
- ++buffer;
- --buffer_length;
- }
- ep->seen_f5 = 0;
- }
-}
-
-static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint* ep,
- struct urb *urb)
-{
- int port0 = ep->current_port;
- uint8_t* buf = urb->transfer_buffer;
- int buf_free = ep->max_transfer;
- int length, i;
-
- for (i = 0; i < 0x10; ++i) {
- /* round-robin, starting at the last current port */
- int portnum = (port0 + i) & 15;
- struct usbmidi_out_port* port = &ep->ports[portnum];
-
- if (!port->active)
- continue;
- if (snd_rawmidi_transmit_peek(port->substream, buf, 1) != 1) {
- port->active = 0;
- continue;
- }
-
- if (portnum != ep->current_port) {
- if (buf_free < 2)
- break;
- ep->current_port = portnum;
- buf[0] = 0xf5;
- buf[1] = (portnum + 1) & 15;
- buf += 2;
- buf_free -= 2;
- }
-
- if (buf_free < 1)
- break;
- length = snd_rawmidi_transmit(port->substream, buf, buf_free);
- if (length > 0) {
- buf += length;
- buf_free -= length;
- if (buf_free < 1)
- break;
- }
- }
- if (buf_free < ep->max_transfer && buf_free > 0) {
- *buf = 0xff;
- --buf_free;
- }
- urb->transfer_buffer_length = ep->max_transfer - buf_free;
-}
-
-static struct usb_protocol_ops snd_usbmidi_emagic_ops = {
- .input = snd_usbmidi_emagic_input,
- .output = snd_usbmidi_emagic_output,
- .init_out_endpoint = snd_usbmidi_emagic_init_out,
- .finish_out_endpoint = snd_usbmidi_emagic_finish_out,
-};
-
-
-static void update_roland_altsetting(struct snd_usb_midi* umidi)
-{
- struct usb_interface *intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor *intfd;
- int is_light_load;
-
- intf = umidi->iface;
- is_light_load = intf->cur_altsetting != intf->altsetting;
- if (umidi->roland_load_ctl->private_value == is_light_load)
- return;
- hostif = &intf->altsetting[umidi->roland_load_ctl->private_value];
- intfd = get_iface_desc(hostif);
- snd_usbmidi_input_stop(&umidi->list);
- usb_set_interface(umidi->dev, intfd->bInterfaceNumber,
- intfd->bAlternateSetting);
- snd_usbmidi_input_start(&umidi->list);
-}
-
-static void substream_open(struct snd_rawmidi_substream *substream, int open)
-{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
- struct snd_kcontrol *ctl;
-
- mutex_lock(&umidi->mutex);
- if (open) {
- if (umidi->opened++ == 0 && umidi->roland_load_ctl) {
- ctl = umidi->roland_load_ctl;
- ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(umidi->card,
- SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
- update_roland_altsetting(umidi);
- }
- } else {
- if (--umidi->opened == 0 && umidi->roland_load_ctl) {
- ctl = umidi->roland_load_ctl;
- ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(umidi->card,
- SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
- }
- }
- mutex_unlock(&umidi->mutex);
-}
-
-static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
-{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
- struct usbmidi_out_port* port = NULL;
- int i, j;
- int err;
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
- if (umidi->endpoints[i].out)
- for (j = 0; j < 0x10; ++j)
- if (umidi->endpoints[i].out->ports[j].substream == substream) {
- port = &umidi->endpoints[i].out->ports[j];
- break;
- }
- if (!port) {
- snd_BUG();
- return -ENXIO;
- }
- err = usb_autopm_get_interface(umidi->iface);
- if (err < 0)
- return -EIO;
- substream->runtime->private_data = port;
- port->state = STATE_UNKNOWN;
- substream_open(substream, 1);
- return 0;
-}
-
-static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
-{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
-
- substream_open(substream, 0);
- usb_autopm_put_interface(umidi->iface);
- return 0;
-}
-
-static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct usbmidi_out_port* port = (struct usbmidi_out_port*)substream->runtime->private_data;
-
- port->active = up;
- if (up) {
- if (port->ep->umidi->disconnected) {
- /* gobble up remaining bytes to prevent wait in
- * snd_rawmidi_drain_output */
- while (!snd_rawmidi_transmit_empty(substream))
- snd_rawmidi_transmit_ack(substream, 1);
- return;
- }
- tasklet_schedule(&port->ep->tasklet);
- }
-}
-
-static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
-{
- struct usbmidi_out_port* port = substream->runtime->private_data;
- struct snd_usb_midi_out_endpoint *ep = port->ep;
- unsigned int drain_urbs;
- DEFINE_WAIT(wait);
- long timeout = msecs_to_jiffies(50);
-
- if (ep->umidi->disconnected)
- return;
- /*
- * The substream buffer is empty, but some data might still be in the
- * currently active URBs, so we have to wait for those to complete.
- */
- spin_lock_irq(&ep->buffer_lock);
- drain_urbs = ep->active_urbs;
- if (drain_urbs) {
- ep->drain_urbs |= drain_urbs;
- do {
- prepare_to_wait(&ep->drain_wait, &wait,
- TASK_UNINTERRUPTIBLE);
- spin_unlock_irq(&ep->buffer_lock);
- timeout = schedule_timeout(timeout);
- spin_lock_irq(&ep->buffer_lock);
- drain_urbs &= ep->drain_urbs;
- } while (drain_urbs && timeout);
- finish_wait(&ep->drain_wait, &wait);
- }
- spin_unlock_irq(&ep->buffer_lock);
-}
-
-static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
-{
- substream_open(substream, 1);
- return 0;
-}
-
-static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream)
-{
- substream_open(substream, 0);
- return 0;
-}
-
-static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
-{
- struct snd_usb_midi* umidi = substream->rmidi->private_data;
-
- if (up)
- set_bit(substream->number, &umidi->input_triggered);
- else
- clear_bit(substream->number, &umidi->input_triggered);
-}
-
-static struct snd_rawmidi_ops snd_usbmidi_output_ops = {
- .open = snd_usbmidi_output_open,
- .close = snd_usbmidi_output_close,
- .trigger = snd_usbmidi_output_trigger,
- .drain = snd_usbmidi_output_drain,
-};
-
-static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
- .open = snd_usbmidi_input_open,
- .close = snd_usbmidi_input_close,
- .trigger = snd_usbmidi_input_trigger
-};
-
-static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
- unsigned int buffer_length)
-{
- usb_free_coherent(umidi->dev, buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
- usb_free_urb(urb);
-}
-
-/*
- * Frees an input endpoint.
- * May be called when ep hasn't been initialized completely.
- */
-static void snd_usbmidi_in_endpoint_delete(struct snd_usb_midi_in_endpoint* ep)
-{
- unsigned int i;
-
- for (i = 0; i < INPUT_URBS; ++i)
- if (ep->urbs[i])
- free_urb_and_buffer(ep->umidi, ep->urbs[i],
- ep->urbs[i]->transfer_buffer_length);
- kfree(ep);
-}
-
-/*
- * Creates an input endpoint.
- */
-static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* ep_info,
- struct snd_usb_midi_endpoint* rep)
-{
- struct snd_usb_midi_in_endpoint* ep;
- void* buffer;
- unsigned int pipe;
- int length;
- unsigned int i;
-
- rep->in = NULL;
- ep = kzalloc(sizeof(*ep), GFP_KERNEL);
- if (!ep)
- return -ENOMEM;
- ep->umidi = umidi;
-
- for (i = 0; i < INPUT_URBS; ++i) {
- ep->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (!ep->urbs[i]) {
- snd_usbmidi_in_endpoint_delete(ep);
- return -ENOMEM;
- }
- }
- if (ep_info->in_interval)
- pipe = usb_rcvintpipe(umidi->dev, ep_info->in_ep);
- else
- pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep);
- length = usb_maxpacket(umidi->dev, pipe, 0);
- for (i = 0; i < INPUT_URBS; ++i) {
- buffer = usb_alloc_coherent(umidi->dev, length, GFP_KERNEL,
- &ep->urbs[i]->transfer_dma);
- if (!buffer) {
- snd_usbmidi_in_endpoint_delete(ep);
- return -ENOMEM;
- }
- if (ep_info->in_interval)
- usb_fill_int_urb(ep->urbs[i], umidi->dev,
- pipe, buffer, length,
- snd_usbmidi_in_urb_complete,
- ep, ep_info->in_interval);
- else
- usb_fill_bulk_urb(ep->urbs[i], umidi->dev,
- pipe, buffer, length,
- snd_usbmidi_in_urb_complete, ep);
- ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
- }
-
- rep->in = ep;
- return 0;
-}
-
-/*
- * Frees an output endpoint.
- * May be called when ep hasn't been initialized completely.
- */
-static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
-{
- unsigned int i;
-
- for (i = 0; i < OUTPUT_URBS; ++i)
- if (ep->urbs[i].urb) {
- free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
- ep->max_transfer);
- ep->urbs[i].urb = NULL;
- }
-}
-
-static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
-{
- snd_usbmidi_out_endpoint_clear(ep);
- kfree(ep);
-}
-
-/*
- * Creates an output endpoint, and initializes output ports.
- */
-static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* ep_info,
- struct snd_usb_midi_endpoint* rep)
-{
- struct snd_usb_midi_out_endpoint* ep;
- unsigned int i;
- unsigned int pipe;
- void* buffer;
-
- rep->out = NULL;
- ep = kzalloc(sizeof(*ep), GFP_KERNEL);
- if (!ep)
- return -ENOMEM;
- ep->umidi = umidi;
-
- for (i = 0; i < OUTPUT_URBS; ++i) {
- ep->urbs[i].urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ep->urbs[i].urb) {
- snd_usbmidi_out_endpoint_delete(ep);
- return -ENOMEM;
- }
- ep->urbs[i].ep = ep;
- }
- if (ep_info->out_interval)
- pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep);
- else
- pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep);
- switch (umidi->usb_id) {
- default:
- ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1);
- break;
- /*
- * Various chips declare a packet size larger than 4 bytes, but
- * do not actually work with larger packets:
- */
- case USB_ID(0x0a92, 0x1020): /* ESI M4U */
- case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
- case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
- case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */
- case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
- case USB_ID(0xfc08, 0x0101): /* Unknown vendor Cable */
- ep->max_transfer = 4;
- break;
- /*
- * Some devices only work with 9 bytes packet size:
- */
- case USB_ID(0x0644, 0x800E): /* Tascam US-122L */
- case USB_ID(0x0644, 0x800F): /* Tascam US-144 */
- ep->max_transfer = 9;
- break;
- }
- for (i = 0; i < OUTPUT_URBS; ++i) {
- buffer = usb_alloc_coherent(umidi->dev,
- ep->max_transfer, GFP_KERNEL,
- &ep->urbs[i].urb->transfer_dma);
- if (!buffer) {
- snd_usbmidi_out_endpoint_delete(ep);
- return -ENOMEM;
- }
- if (ep_info->out_interval)
- usb_fill_int_urb(ep->urbs[i].urb, umidi->dev,
- pipe, buffer, ep->max_transfer,
- snd_usbmidi_out_urb_complete,
- &ep->urbs[i], ep_info->out_interval);
- else
- usb_fill_bulk_urb(ep->urbs[i].urb, umidi->dev,
- pipe, buffer, ep->max_transfer,
- snd_usbmidi_out_urb_complete,
- &ep->urbs[i]);
- ep->urbs[i].urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
- }
-
- spin_lock_init(&ep->buffer_lock);
- tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep);
- init_waitqueue_head(&ep->drain_wait);
-
- for (i = 0; i < 0x10; ++i)
- if (ep_info->out_cables & (1 << i)) {
- ep->ports[i].ep = ep;
- ep->ports[i].cable = i << 4;
- }
-
- if (umidi->usb_protocol_ops->init_out_endpoint)
- umidi->usb_protocol_ops->init_out_endpoint(ep);
-
- rep->out = ep;
- return 0;
-}
-
-/*
- * Frees everything.
- */
-static void snd_usbmidi_free(struct snd_usb_midi* umidi)
-{
- int i;
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
- if (ep->out)
- snd_usbmidi_out_endpoint_delete(ep->out);
- if (ep->in)
- snd_usbmidi_in_endpoint_delete(ep->in);
- }
- mutex_destroy(&umidi->mutex);
- kfree(umidi);
-}
-
-/*
- * Unlinks all URBs (must be done before the usb_device is deleted).
- */
-void snd_usbmidi_disconnect(struct list_head* p)
-{
- struct snd_usb_midi* umidi;
- unsigned int i, j;
-
- umidi = list_entry(p, struct snd_usb_midi, list);
- /*
- * an URB's completion handler may start the timer and
- * a timer may submit an URB. To reliably break the cycle
- * a flag under lock must be used
- */
- spin_lock_irq(&umidi->disc_lock);
- umidi->disconnected = 1;
- spin_unlock_irq(&umidi->disc_lock);
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
- if (ep->out)
- tasklet_kill(&ep->out->tasklet);
- if (ep->out) {
- for (j = 0; j < OUTPUT_URBS; ++j)
- usb_kill_urb(ep->out->urbs[j].urb);
- if (umidi->usb_protocol_ops->finish_out_endpoint)
- umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
- ep->out->active_urbs = 0;
- if (ep->out->drain_urbs) {
- ep->out->drain_urbs = 0;
- wake_up(&ep->out->drain_wait);
- }
- }
- if (ep->in)
- for (j = 0; j < INPUT_URBS; ++j)
- usb_kill_urb(ep->in->urbs[j]);
- /* free endpoints here; later call can result in Oops */
- if (ep->out)
- snd_usbmidi_out_endpoint_clear(ep->out);
- if (ep->in) {
- snd_usbmidi_in_endpoint_delete(ep->in);
- ep->in = NULL;
- }
- }
- del_timer_sync(&umidi->error_timer);
-}
-
-static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi)
-{
- struct snd_usb_midi* umidi = rmidi->private_data;
- snd_usbmidi_free(umidi);
-}
-
-static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi,
- int stream, int number)
-{
- struct list_head* list;
-
- list_for_each(list, &umidi->rmidi->streams[stream].substreams) {
- struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list);
- if (substream->number == number)
- return substream;
- }
- return NULL;
-}
-
-/*
- * This list specifies names for ports that do not fit into the standard
- * "(product) MIDI (n)" schema because they aren't external MIDI ports,
- * such as internal control or synthesizer ports.
- */
-static struct port_info {
- u32 id;
- short int port;
- short int voices;
- const char *name;
- unsigned int seq_flags;
-} snd_usbmidi_port_info[] = {
-#define PORT_INFO(vendor, product, num, name_, voices_, flags) \
- { .id = USB_ID(vendor, product), \
- .port = num, .voices = voices_, \
- .name = name_, .seq_flags = flags }
-#define EXTERNAL_PORT(vendor, product, num, name) \
- PORT_INFO(vendor, product, num, name, 0, \
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
- SNDRV_SEQ_PORT_TYPE_HARDWARE | \
- SNDRV_SEQ_PORT_TYPE_PORT)
-#define CONTROL_PORT(vendor, product, num, name) \
- PORT_INFO(vendor, product, num, name, 0, \
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
- SNDRV_SEQ_PORT_TYPE_HARDWARE)
-#define ROLAND_SYNTH_PORT(vendor, product, num, name, voices) \
- PORT_INFO(vendor, product, num, name, voices, \
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GM | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GM2 | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GS | \
- SNDRV_SEQ_PORT_TYPE_MIDI_XG | \
- SNDRV_SEQ_PORT_TYPE_HARDWARE | \
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
-#define SOUNDCANVAS_PORT(vendor, product, num, name, voices) \
- PORT_INFO(vendor, product, num, name, voices, \
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GM | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GM2 | \
- SNDRV_SEQ_PORT_TYPE_MIDI_GS | \
- SNDRV_SEQ_PORT_TYPE_MIDI_XG | \
- SNDRV_SEQ_PORT_TYPE_MIDI_MT32 | \
- SNDRV_SEQ_PORT_TYPE_HARDWARE | \
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER)
- /* Roland UA-100 */
- CONTROL_PORT(0x0582, 0x0000, 2, "%s Control"),
- /* Roland SC-8850 */
- SOUNDCANVAS_PORT(0x0582, 0x0003, 0, "%s Part A", 128),
- SOUNDCANVAS_PORT(0x0582, 0x0003, 1, "%s Part B", 128),
- SOUNDCANVAS_PORT(0x0582, 0x0003, 2, "%s Part C", 128),
- SOUNDCANVAS_PORT(0x0582, 0x0003, 3, "%s Part D", 128),
- EXTERNAL_PORT(0x0582, 0x0003, 4, "%s MIDI 1"),
- EXTERNAL_PORT(0x0582, 0x0003, 5, "%s MIDI 2"),
- /* Roland U-8 */
- EXTERNAL_PORT(0x0582, 0x0004, 0, "%s MIDI"),
- CONTROL_PORT(0x0582, 0x0004, 1, "%s Control"),
- /* Roland SC-8820 */
- SOUNDCANVAS_PORT(0x0582, 0x0007, 0, "%s Part A", 64),
- SOUNDCANVAS_PORT(0x0582, 0x0007, 1, "%s Part B", 64),
- EXTERNAL_PORT(0x0582, 0x0007, 2, "%s MIDI"),
- /* Roland SK-500 */
- SOUNDCANVAS_PORT(0x0582, 0x000b, 0, "%s Part A", 64),
- SOUNDCANVAS_PORT(0x0582, 0x000b, 1, "%s Part B", 64),
- EXTERNAL_PORT(0x0582, 0x000b, 2, "%s MIDI"),
- /* Roland SC-D70 */
- SOUNDCANVAS_PORT(0x0582, 0x000c, 0, "%s Part A", 64),
- SOUNDCANVAS_PORT(0x0582, 0x000c, 1, "%s Part B", 64),
- EXTERNAL_PORT(0x0582, 0x000c, 2, "%s MIDI"),
- /* Edirol UM-880 */
- CONTROL_PORT(0x0582, 0x0014, 8, "%s Control"),
- /* Edirol SD-90 */
- ROLAND_SYNTH_PORT(0x0582, 0x0016, 0, "%s Part A", 128),
- ROLAND_SYNTH_PORT(0x0582, 0x0016, 1, "%s Part B", 128),
- EXTERNAL_PORT(0x0582, 0x0016, 2, "%s MIDI 1"),
- EXTERNAL_PORT(0x0582, 0x0016, 3, "%s MIDI 2"),
- /* Edirol UM-550 */
- CONTROL_PORT(0x0582, 0x0023, 5, "%s Control"),
- /* Edirol SD-20 */
- ROLAND_SYNTH_PORT(0x0582, 0x0027, 0, "%s Part A", 64),
- ROLAND_SYNTH_PORT(0x0582, 0x0027, 1, "%s Part B", 64),
- EXTERNAL_PORT(0x0582, 0x0027, 2, "%s MIDI"),
- /* Edirol SD-80 */
- ROLAND_SYNTH_PORT(0x0582, 0x0029, 0, "%s Part A", 128),
- ROLAND_SYNTH_PORT(0x0582, 0x0029, 1, "%s Part B", 128),
- EXTERNAL_PORT(0x0582, 0x0029, 2, "%s MIDI 1"),
- EXTERNAL_PORT(0x0582, 0x0029, 3, "%s MIDI 2"),
- /* Edirol UA-700 */
- EXTERNAL_PORT(0x0582, 0x002b, 0, "%s MIDI"),
- CONTROL_PORT(0x0582, 0x002b, 1, "%s Control"),
- /* Roland VariOS */
- EXTERNAL_PORT(0x0582, 0x002f, 0, "%s MIDI"),
- EXTERNAL_PORT(0x0582, 0x002f, 1, "%s External MIDI"),
- EXTERNAL_PORT(0x0582, 0x002f, 2, "%s Sync"),
- /* Edirol PCR */
- EXTERNAL_PORT(0x0582, 0x0033, 0, "%s MIDI"),
- EXTERNAL_PORT(0x0582, 0x0033, 1, "%s 1"),
- EXTERNAL_PORT(0x0582, 0x0033, 2, "%s 2"),
- /* BOSS GS-10 */
- EXTERNAL_PORT(0x0582, 0x003b, 0, "%s MIDI"),
- CONTROL_PORT(0x0582, 0x003b, 1, "%s Control"),
- /* Edirol UA-1000 */
- EXTERNAL_PORT(0x0582, 0x0044, 0, "%s MIDI"),
- CONTROL_PORT(0x0582, 0x0044, 1, "%s Control"),
- /* Edirol UR-80 */
- EXTERNAL_PORT(0x0582, 0x0048, 0, "%s MIDI"),
- EXTERNAL_PORT(0x0582, 0x0048, 1, "%s 1"),
- EXTERNAL_PORT(0x0582, 0x0048, 2, "%s 2"),
- /* Edirol PCR-A */
- EXTERNAL_PORT(0x0582, 0x004d, 0, "%s MIDI"),
- EXTERNAL_PORT(0x0582, 0x004d, 1, "%s 1"),
- EXTERNAL_PORT(0x0582, 0x004d, 2, "%s 2"),
- /* Edirol UM-3EX */
- CONTROL_PORT(0x0582, 0x009a, 3, "%s Control"),
- /* M-Audio MidiSport 8x8 */
- CONTROL_PORT(0x0763, 0x1031, 8, "%s Control"),
- CONTROL_PORT(0x0763, 0x1033, 8, "%s Control"),
- /* MOTU Fastlane */
- EXTERNAL_PORT(0x07fd, 0x0001, 0, "%s MIDI A"),
- EXTERNAL_PORT(0x07fd, 0x0001, 1, "%s MIDI B"),
- /* Emagic Unitor8/AMT8/MT4 */
- EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"),
- EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"),
- EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"),
- /* Akai MPD16 */
- CONTROL_PORT(0x09e8, 0x0062, 0, "%s Control"),
- PORT_INFO(0x09e8, 0x0062, 1, "%s MIDI", 0,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_HARDWARE),
- /* Access Music Virus TI */
- EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"),
- PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0,
- SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC |
- SNDRV_SEQ_PORT_TYPE_HARDWARE |
- SNDRV_SEQ_PORT_TYPE_SYNTHESIZER),
-};
-
-static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) {
- if (snd_usbmidi_port_info[i].id == umidi->usb_id &&
- snd_usbmidi_port_info[i].port == number)
- return &snd_usbmidi_port_info[i];
- }
- return NULL;
-}
-
-static void snd_usbmidi_get_port_info(struct snd_rawmidi *rmidi, int number,
- struct snd_seq_port_info *seq_port_info)
-{
- struct snd_usb_midi *umidi = rmidi->private_data;
- struct port_info *port_info;
-
- /* TODO: read port flags from descriptors */
- port_info = find_port_info(umidi, number);
- if (port_info) {
- seq_port_info->type = port_info->seq_flags;
- seq_port_info->midi_voices = port_info->voices;
- }
-}
-
-static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
- int stream, int number,
- struct snd_rawmidi_substream ** rsubstream)
-{
- struct port_info *port_info;
- const char *name_format;
-
- struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number);
- if (!substream) {
- snd_printd(KERN_ERR "substream %d:%d not found\n", stream, number);
- return;
- }
-
- /* TODO: read port name from jack descriptor */
- port_info = find_port_info(umidi, number);
- name_format = port_info ? port_info->name : "%s MIDI %d";
- snprintf(substream->name, sizeof(substream->name),
- name_format, umidi->card->shortname, number + 1);
-
- *rsubstream = substream;
-}
-
-/*
- * Creates the endpoints and their ports.
- */
-static int snd_usbmidi_create_endpoints(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoints)
-{
- int i, j, err;
- int out_ports = 0, in_ports = 0;
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- if (endpoints[i].out_cables) {
- err = snd_usbmidi_out_endpoint_create(umidi, &endpoints[i],
- &umidi->endpoints[i]);
- if (err < 0)
- return err;
- }
- if (endpoints[i].in_cables) {
- err = snd_usbmidi_in_endpoint_create(umidi, &endpoints[i],
- &umidi->endpoints[i]);
- if (err < 0)
- return err;
- }
-
- for (j = 0; j < 0x10; ++j) {
- if (endpoints[i].out_cables & (1 << j)) {
- snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, out_ports,
- &umidi->endpoints[i].out->ports[j].substream);
- ++out_ports;
- }
- if (endpoints[i].in_cables & (1 << j)) {
- snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, in_ports,
- &umidi->endpoints[i].in->ports[j].substream);
- ++in_ports;
- }
- }
- }
- snd_printdd(KERN_INFO "created %d output and %d input ports\n",
- out_ports, in_ports);
- return 0;
-}
-
-/*
- * Returns MIDIStreaming device capabilities.
- */
-static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoints)
-{
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
- struct usb_ms_header_descriptor* ms_header;
- struct usb_host_endpoint *hostep;
- struct usb_endpoint_descriptor* ep;
- struct usb_ms_endpoint_descriptor* ms_ep;
- int i, epidx;
-
- intf = umidi->iface;
- if (!intf)
- return -ENXIO;
- hostif = &intf->altsetting[0];
- intfd = get_iface_desc(hostif);
- ms_header = (struct usb_ms_header_descriptor*)hostif->extra;
- if (hostif->extralen >= 7 &&
- ms_header->bLength >= 7 &&
- ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
- ms_header->bDescriptorSubtype == UAC_HEADER)
- snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n",
- ms_header->bcdMSC[1], ms_header->bcdMSC[0]);
- else
- snd_printk(KERN_WARNING "MIDIStreaming interface descriptor not found\n");
-
- epidx = 0;
- for (i = 0; i < intfd->bNumEndpoints; ++i) {
- hostep = &hostif->endpoint[i];
- ep = get_ep_desc(hostep);
- if (!usb_endpoint_xfer_bulk(ep) && !usb_endpoint_xfer_int(ep))
- continue;
- ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra;
- if (hostep->extralen < 4 ||
- ms_ep->bLength < 4 ||
- ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
- ms_ep->bDescriptorSubtype != UAC_MS_GENERAL)
- continue;
- if (usb_endpoint_dir_out(ep)) {
- if (endpoints[epidx].out_ep) {
- if (++epidx >= MIDI_MAX_ENDPOINTS) {
- snd_printk(KERN_WARNING "too many endpoints\n");
- break;
- }
- }
- endpoints[epidx].out_ep = usb_endpoint_num(ep);
- if (usb_endpoint_xfer_int(ep))
- endpoints[epidx].out_interval = ep->bInterval;
- else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)
- /*
- * Low speed bulk transfers don't exist, so
- * force interrupt transfers for devices like
- * ESI MIDI Mate that try to use them anyway.
- */
- endpoints[epidx].out_interval = 1;
- endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
- snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
- ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
- } else {
- if (endpoints[epidx].in_ep) {
- if (++epidx >= MIDI_MAX_ENDPOINTS) {
- snd_printk(KERN_WARNING "too many endpoints\n");
- break;
- }
- }
- endpoints[epidx].in_ep = usb_endpoint_num(ep);
- if (usb_endpoint_xfer_int(ep))
- endpoints[epidx].in_interval = ep->bInterval;
- else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)
- endpoints[epidx].in_interval = 1;
- endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
- snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
- ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack);
- }
- }
- return 0;
-}
-
-static int roland_load_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
-{
- static const char *const names[] = { "High Load", "Light Load" };
-
- return snd_ctl_enum_info(info, 1, 2, names);
-}
-
-static int roland_load_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- value->value.enumerated.item[0] = kcontrol->private_value;
- return 0;
-}
-
-static int roland_load_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
-{
- struct snd_usb_midi* umidi = kcontrol->private_data;
- int changed;
-
- if (value->value.enumerated.item[0] > 1)
- return -EINVAL;
- mutex_lock(&umidi->mutex);
- changed = value->value.enumerated.item[0] != kcontrol->private_value;
- if (changed)
- kcontrol->private_value = value->value.enumerated.item[0];
- mutex_unlock(&umidi->mutex);
- return changed;
-}
-
-static struct snd_kcontrol_new roland_load_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "MIDI Input Mode",
- .info = roland_load_info,
- .get = roland_load_get,
- .put = roland_load_put,
- .private_value = 1,
-};
-
-/*
- * On Roland devices, use the second alternate setting to be able to use
- * the interrupt input endpoint.
- */
-static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi)
-{
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
-
- intf = umidi->iface;
- if (!intf || intf->num_altsetting != 2)
- return;
-
- hostif = &intf->altsetting[1];
- intfd = get_iface_desc(hostif);
- if (intfd->bNumEndpoints != 2 ||
- (get_endpoint(hostif, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ||
- (get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
- return;
-
- snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n",
- intfd->bAlternateSetting);
- usb_set_interface(umidi->dev, intfd->bInterfaceNumber,
- intfd->bAlternateSetting);
-
- umidi->roland_load_ctl = snd_ctl_new1(&roland_load_ctl, umidi);
- if (snd_ctl_add(umidi->card, umidi->roland_load_ctl) < 0)
- umidi->roland_load_ctl = NULL;
-}
-
-/*
- * Try to find any usable endpoints in the interface.
- */
-static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoint,
- int max_endpoints)
-{
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
- struct usb_endpoint_descriptor* epd;
- int i, out_eps = 0, in_eps = 0;
-
- if (USB_ID_VENDOR(umidi->usb_id) == 0x0582)
- snd_usbmidi_switch_roland_altsetting(umidi);
-
- if (endpoint[0].out_ep || endpoint[0].in_ep)
- return 0;
-
- intf = umidi->iface;
- if (!intf || intf->num_altsetting < 1)
- return -ENOENT;
- hostif = intf->cur_altsetting;
- intfd = get_iface_desc(hostif);
-
- for (i = 0; i < intfd->bNumEndpoints; ++i) {
- epd = get_endpoint(hostif, i);
- if (!usb_endpoint_xfer_bulk(epd) &&
- !usb_endpoint_xfer_int(epd))
- continue;
- if (out_eps < max_endpoints &&
- usb_endpoint_dir_out(epd)) {
- endpoint[out_eps].out_ep = usb_endpoint_num(epd);
- if (usb_endpoint_xfer_int(epd))
- endpoint[out_eps].out_interval = epd->bInterval;
- ++out_eps;
- }
- if (in_eps < max_endpoints &&
- usb_endpoint_dir_in(epd)) {
- endpoint[in_eps].in_ep = usb_endpoint_num(epd);
- if (usb_endpoint_xfer_int(epd))
- endpoint[in_eps].in_interval = epd->bInterval;
- ++in_eps;
- }
- }
- return (out_eps || in_eps) ? 0 : -ENOENT;
-}
-
-/*
- * Detects the endpoints for one-port-per-endpoint protocols.
- */
-static int snd_usbmidi_detect_per_port_endpoints(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoints)
-{
- int err, i;
-
- err = snd_usbmidi_detect_endpoints(umidi, endpoints, MIDI_MAX_ENDPOINTS);
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- if (endpoints[i].out_ep)
- endpoints[i].out_cables = 0x0001;
- if (endpoints[i].in_ep)
- endpoints[i].in_cables = 0x0001;
- }
- return err;
-}
-
-/*
- * Detects the endpoints and ports of Yamaha devices.
- */
-static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoint)
-{
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
- uint8_t* cs_desc;
-
- intf = umidi->iface;
- if (!intf)
- return -ENOENT;
- hostif = intf->altsetting;
- intfd = get_iface_desc(hostif);
- if (intfd->bNumEndpoints < 1)
- return -ENOENT;
-
- /*
- * For each port there is one MIDI_IN/OUT_JACK descriptor, not
- * necessarily with any useful contents. So simply count 'em.
- */
- for (cs_desc = hostif->extra;
- cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
- cs_desc += cs_desc[0]) {
- if (cs_desc[1] == USB_DT_CS_INTERFACE) {
- if (cs_desc[2] == UAC_MIDI_IN_JACK)
- endpoint->in_cables = (endpoint->in_cables << 1) | 1;
- else if (cs_desc[2] == UAC_MIDI_OUT_JACK)
- endpoint->out_cables = (endpoint->out_cables << 1) | 1;
- }
- }
- if (!endpoint->in_cables && !endpoint->out_cables)
- return -ENOENT;
-
- return snd_usbmidi_detect_endpoints(umidi, endpoint, 1);
-}
-
-/*
- * Creates the endpoints and their ports for Midiman devices.
- */
-static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,
- struct snd_usb_midi_endpoint_info* endpoint)
-{
- struct snd_usb_midi_endpoint_info ep_info;
- struct usb_interface* intf;
- struct usb_host_interface *hostif;
- struct usb_interface_descriptor* intfd;
- struct usb_endpoint_descriptor* epd;
- int cable, err;
-
- intf = umidi->iface;
- if (!intf)
- return -ENOENT;
- hostif = intf->altsetting;
- intfd = get_iface_desc(hostif);
- /*
- * The various MidiSport devices have more or less random endpoint
- * numbers, so we have to identify the endpoints by their index in
- * the descriptor array, like the driver for that other OS does.
- *
- * There is one interrupt input endpoint for all input ports, one
- * bulk output endpoint for even-numbered ports, and one for odd-
- * numbered ports. Both bulk output endpoints have corresponding
- * input bulk endpoints (at indices 1 and 3) which aren't used.
- */
- if (intfd->bNumEndpoints < (endpoint->out_cables > 0x0001 ? 5 : 3)) {
- snd_printdd(KERN_ERR "not enough endpoints\n");
- return -ENOENT;
- }
-
- epd = get_endpoint(hostif, 0);
- if (!usb_endpoint_dir_in(epd) || !usb_endpoint_xfer_int(epd)) {
- snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n");
- return -ENXIO;
- }
- epd = get_endpoint(hostif, 2);
- if (!usb_endpoint_dir_out(epd) || !usb_endpoint_xfer_bulk(epd)) {
- snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n");
- return -ENXIO;
- }
- if (endpoint->out_cables > 0x0001) {
- epd = get_endpoint(hostif, 4);
- if (!usb_endpoint_dir_out(epd) ||
- !usb_endpoint_xfer_bulk(epd)) {
- snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n");
- return -ENXIO;
- }
- }
-
- ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- ep_info.out_interval = 0;
- ep_info.out_cables = endpoint->out_cables & 0x5555;
- err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
- if (err < 0)
- return err;
-
- ep_info.in_ep = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- ep_info.in_interval = get_endpoint(hostif, 0)->bInterval;
- ep_info.in_cables = endpoint->in_cables;
- err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
- if (err < 0)
- return err;
-
- if (endpoint->out_cables > 0x0001) {
- ep_info.out_ep = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- ep_info.out_cables = endpoint->out_cables & 0xaaaa;
- err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]);
- if (err < 0)
- return err;
- }
-
- for (cable = 0; cable < 0x10; ++cable) {
- if (endpoint->out_cables & (1 << cable))
- snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, cable,
- &umidi->endpoints[cable & 1].out->ports[cable].substream);
- if (endpoint->in_cables & (1 << cable))
- snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, cable,
- &umidi->endpoints[0].in->ports[cable].substream);
- }
- return 0;
-}
-
-static struct snd_rawmidi_global_ops snd_usbmidi_ops = {
- .get_port_info = snd_usbmidi_get_port_info,
-};
-
-static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
- int out_ports, int in_ports)
-{
- struct snd_rawmidi *rmidi;
- int err;
-
- err = snd_rawmidi_new(umidi->card, "USB MIDI",
- umidi->next_midi_device++,
- out_ports, in_ports, &rmidi);
- if (err < 0)
- return err;
- strcpy(rmidi->name, umidi->card->shortname);
- rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
- SNDRV_RAWMIDI_INFO_INPUT |
- SNDRV_RAWMIDI_INFO_DUPLEX;
- rmidi->ops = &snd_usbmidi_ops;
- rmidi->private_data = umidi;
- rmidi->private_free = snd_usbmidi_rawmidi_free;
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops);
- snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_usbmidi_input_ops);
-
- umidi->rmidi = rmidi;
- return 0;
-}
-
-/*
- * Temporarily stop input.
- */
-void snd_usbmidi_input_stop(struct list_head* p)
-{
- struct snd_usb_midi* umidi;
- unsigned int i, j;
-
- umidi = list_entry(p, struct snd_usb_midi, list);
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
- if (ep->in)
- for (j = 0; j < INPUT_URBS; ++j)
- usb_kill_urb(ep->in->urbs[j]);
- }
-}
-
-static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
-{
- unsigned int i;
-
- if (!ep)
- return;
- for (i = 0; i < INPUT_URBS; ++i) {
- struct urb* urb = ep->urbs[i];
- urb->dev = ep->umidi->dev;
- snd_usbmidi_submit_urb(urb, GFP_KERNEL);
- }
-}
-
-/*
- * Resume input after a call to snd_usbmidi_input_stop().
- */
-void snd_usbmidi_input_start(struct list_head* p)
-{
- struct snd_usb_midi* umidi;
- int i;
-
- umidi = list_entry(p, struct snd_usb_midi, list);
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
- snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
-}
-
-/*
- * Creates and registers everything needed for a MIDI streaming interface.
- */
-int snd_usbmidi_create(struct snd_card *card,
- struct usb_interface* iface,
- struct list_head *midi_list,
- const struct snd_usb_audio_quirk* quirk)
-{
- struct snd_usb_midi* umidi;
- struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS];
- int out_ports, in_ports;
- int i, err;
-
- umidi = kzalloc(sizeof(*umidi), GFP_KERNEL);
- if (!umidi)
- return -ENOMEM;
- umidi->dev = interface_to_usbdev(iface);
- umidi->card = card;
- umidi->iface = iface;
- umidi->quirk = quirk;
- umidi->usb_protocol_ops = &snd_usbmidi_standard_ops;
- init_timer(&umidi->error_timer);
- spin_lock_init(&umidi->disc_lock);
- mutex_init(&umidi->mutex);
- umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor),
- le16_to_cpu(umidi->dev->descriptor.idProduct));
- umidi->error_timer.function = snd_usbmidi_error_timer;
- umidi->error_timer.data = (unsigned long)umidi;
-
- /* detect the endpoint(s) to use */
- memset(endpoints, 0, sizeof(endpoints));
- switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
- case QUIRK_MIDI_STANDARD_INTERFACE:
- err = snd_usbmidi_get_ms_info(umidi, endpoints);
- if (umidi->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */
- umidi->usb_protocol_ops =
- &snd_usbmidi_maudio_broken_running_status_ops;
- break;
- case QUIRK_MIDI_US122L:
- umidi->usb_protocol_ops = &snd_usbmidi_122l_ops;
- /* fall through */
- case QUIRK_MIDI_FIXED_ENDPOINT:
- memcpy(&endpoints[0], quirk->data,
- sizeof(struct snd_usb_midi_endpoint_info));
- err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
- break;
- case QUIRK_MIDI_YAMAHA:
- err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]);
- break;
- case QUIRK_MIDI_MIDIMAN:
- umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
- memcpy(&endpoints[0], quirk->data,
- sizeof(struct snd_usb_midi_endpoint_info));
- err = 0;
- break;
- case QUIRK_MIDI_NOVATION:
- umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- case QUIRK_MIDI_RAW_BYTES:
- umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
- /*
- * Interface 1 contains isochronous endpoints, but with the same
- * numbers as in interface 0. Since it is interface 1 that the
- * USB core has most recently seen, these descriptors are now
- * associated with the endpoint numbers. This will foul up our
- * attempts to submit bulk/interrupt URBs to the endpoints in
- * interface 0, so we have to make sure that the USB core looks
- * again at interface 0 by calling usb_set_interface() on it.
- */
- if (umidi->usb_id == USB_ID(0x07fd, 0x0001)) /* MOTU Fastlane */
- usb_set_interface(umidi->dev, 0, 0);
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- case QUIRK_MIDI_EMAGIC:
- umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
- memcpy(&endpoints[0], quirk->data,
- sizeof(struct snd_usb_midi_endpoint_info));
- err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
- break;
- case QUIRK_MIDI_CME:
- umidi->usb_protocol_ops = &snd_usbmidi_cme_ops;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- case QUIRK_MIDI_AKAI:
- umidi->usb_protocol_ops = &snd_usbmidi_akai_ops;
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- /* endpoint 1 is input-only */
- endpoints[1].out_cables = 0;
- break;
- case QUIRK_MIDI_FTDI:
- umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops;
-
- /* set baud rate to 31250 (48 MHz / 16 / 96) */
- err = usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0),
- 3, 0x40, 0x60, 0, NULL, 0, 1000);
- if (err < 0)
- break;
-
- err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
- break;
- default:
- snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
- err = -ENXIO;
- break;
- }
- if (err < 0) {
- kfree(umidi);
- return err;
- }
-
- /* create rawmidi device */
- out_ports = 0;
- in_ports = 0;
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
- out_ports += hweight16(endpoints[i].out_cables);
- in_ports += hweight16(endpoints[i].in_cables);
- }
- err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports);
- if (err < 0) {
- kfree(umidi);
- return err;
- }
-
- /* create endpoint/port structures */
- if (quirk && quirk->type == QUIRK_MIDI_MIDIMAN)
- err = snd_usbmidi_create_endpoints_midiman(umidi, &endpoints[0]);
- else
- err = snd_usbmidi_create_endpoints(umidi, endpoints);
- if (err < 0) {
- snd_usbmidi_free(umidi);
- return err;
- }
-
- list_add_tail(&umidi->list, midi_list);
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
- snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
- return 0;
-}
-
-EXPORT_SYMBOL(snd_usbmidi_create);
-EXPORT_SYMBOL(snd_usbmidi_input_stop);
-EXPORT_SYMBOL(snd_usbmidi_input_start);
-EXPORT_SYMBOL(snd_usbmidi_disconnect);
diff --git a/ANDROID_3.4.5/sound/usb/midi.h b/ANDROID_3.4.5/sound/usb/midi.h
deleted file mode 100644
index 2fca80b7..00000000
--- a/ANDROID_3.4.5/sound/usb/midi.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef __USBMIDI_H
-#define __USBMIDI_H
-
-/* maximum number of endpoints per interface */
-#define MIDI_MAX_ENDPOINTS 2
-
-/* data for QUIRK_MIDI_FIXED_ENDPOINT */
-struct snd_usb_midi_endpoint_info {
- int8_t out_ep; /* ep number, 0 autodetect */
- uint8_t out_interval; /* interval for interrupt endpoints */
- int8_t in_ep;
- uint8_t in_interval;
- uint16_t out_cables; /* bitmask */
- uint16_t in_cables; /* bitmask */
-};
-
-/* for QUIRK_MIDI_YAMAHA, data is NULL */
-
-/* for QUIRK_MIDI_MIDIMAN, data points to a snd_usb_midi_endpoint_info
- * structure (out_cables and in_cables only) */
-
-/* for QUIRK_COMPOSITE, data points to an array of snd_usb_audio_quirk
- * structures, terminated with .ifnum = -1 */
-
-/* for QUIRK_AUDIO_FIXED_ENDPOINT, data points to an audioformat structure */
-
-/* for QUIRK_AUDIO/MIDI_STANDARD_INTERFACE, data is NULL */
-
-/* for QUIRK_AUDIO_EDIROL_UA700_UA25/UA1000, data is NULL */
-
-/* for QUIRK_IGNORE_INTERFACE, data is NULL */
-
-/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
-
-/* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
- * structure (out_cables and in_cables only) */
-
-/* for QUIRK_MIDI_CME, data is NULL */
-
-/* for QUIRK_MIDI_AKAI, data is NULL */
-
-int snd_usbmidi_create(struct snd_card *card,
- struct usb_interface *iface,
- struct list_head *midi_list,
- const struct snd_usb_audio_quirk *quirk);
-void snd_usbmidi_input_stop(struct list_head* p);
-void snd_usbmidi_input_start(struct list_head* p);
-void snd_usbmidi_disconnect(struct list_head *p);
-
-#endif /* __USBMIDI_H */
diff --git a/ANDROID_3.4.5/sound/usb/misc/Makefile b/ANDROID_3.4.5/sound/usb/misc/Makefile
deleted file mode 100644
index ccefd815..00000000
--- a/ANDROID_3.4.5/sound/usb/misc/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-snd-ua101-objs := ua101.o
-obj-$(CONFIG_SND_USB_UA101) += snd-ua101.o
diff --git a/ANDROID_3.4.5/sound/usb/misc/ua101.c b/ANDROID_3.4.5/sound/usb/misc/ua101.c
deleted file mode 100644
index 8b81cb54..00000000
--- a/ANDROID_3.4.5/sound/usb/misc/ua101.c
+++ /dev/null
@@ -1,1390 +0,0 @@
-/*
- * Edirol UA-101/UA-1000 driver
- * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
- *
- * This driver is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2.
- *
- * This driver is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this driver. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "../usbaudio.h"
-#include "../midi.h"
-
-MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
-MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
-MODULE_LICENSE("GPL v2");
-MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
-
-/*
- * Should not be lower than the minimum scheduling delay of the host
- * controller. Some Intel controllers need more than one frame; as long as
- * that driver doesn't tell us about this, use 1.5 frames just to be sure.
- */
-#define MIN_QUEUE_LENGTH 12
-/* Somewhat random. */
-#define MAX_QUEUE_LENGTH 30
-/*
- * This magic value optimizes memory usage efficiency for the UA-101's packet
- * sizes at all sample rates, taking into account the stupid cache pool sizes
- * that usb_alloc_coherent() uses.
- */
-#define DEFAULT_QUEUE_LENGTH 21
-
-#define MAX_PACKET_SIZE 672 /* hardware specific */
-#define MAX_MEMORY_BUFFERS DIV_ROUND_UP(MAX_QUEUE_LENGTH, \
- PAGE_SIZE / MAX_PACKET_SIZE)
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static unsigned int queue_length = 21;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "card index");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "enable card");
-module_param(queue_length, uint, 0644);
-MODULE_PARM_DESC(queue_length, "USB queue length in microframes, "
- __stringify(MIN_QUEUE_LENGTH)"-"__stringify(MAX_QUEUE_LENGTH));
-
-enum {
- INTF_PLAYBACK,
- INTF_CAPTURE,
- INTF_MIDI,
-
- INTF_COUNT
-};
-
-/* bits in struct ua101::states */
-enum {
- USB_CAPTURE_RUNNING,
- USB_PLAYBACK_RUNNING,
- ALSA_CAPTURE_OPEN,
- ALSA_PLAYBACK_OPEN,
- ALSA_CAPTURE_RUNNING,
- ALSA_PLAYBACK_RUNNING,
- CAPTURE_URB_COMPLETED,
- PLAYBACK_URB_COMPLETED,
- DISCONNECTED,
-};
-
-struct ua101 {
- struct usb_device *dev;
- struct snd_card *card;
- struct usb_interface *intf[INTF_COUNT];
- int card_index;
- struct snd_pcm *pcm;
- struct list_head midi_list;
- u64 format_bit;
- unsigned int rate;
- unsigned int packets_per_second;
- spinlock_t lock;
- struct mutex mutex;
- unsigned long states;
-
- /* FIFO to synchronize playback rate to capture rate */
- unsigned int rate_feedback_start;
- unsigned int rate_feedback_count;
- u8 rate_feedback[MAX_QUEUE_LENGTH];
-
- struct list_head ready_playback_urbs;
- struct tasklet_struct playback_tasklet;
- wait_queue_head_t alsa_capture_wait;
- wait_queue_head_t rate_feedback_wait;
- wait_queue_head_t alsa_playback_wait;
- struct ua101_stream {
- struct snd_pcm_substream *substream;
- unsigned int usb_pipe;
- unsigned int channels;
- unsigned int frame_bytes;
- unsigned int max_packet_bytes;
- unsigned int period_pos;
- unsigned int buffer_pos;
- unsigned int queue_length;
- struct ua101_urb {
- struct urb urb;
- struct usb_iso_packet_descriptor iso_frame_desc[1];
- struct list_head ready_list;
- } *urbs[MAX_QUEUE_LENGTH];
- struct {
- unsigned int size;
- void *addr;
- dma_addr_t dma;
- } buffers[MAX_MEMORY_BUFFERS];
- } capture, playback;
-};
-
-static DEFINE_MUTEX(devices_mutex);
-static unsigned int devices_used;
-static struct usb_driver ua101_driver;
-
-static void abort_alsa_playback(struct ua101 *ua);
-static void abort_alsa_capture(struct ua101 *ua);
-
-static const char *usb_error_string(int err)
-{
- switch (err) {
- case -ENODEV:
- return "no device";
- case -ENOENT:
- return "endpoint not enabled";
- case -EPIPE:
- return "endpoint stalled";
- case -ENOSPC:
- return "not enough bandwidth";
- case -ESHUTDOWN:
- return "device disabled";
- case -EHOSTUNREACH:
- return "device suspended";
- case -EINVAL:
- case -EAGAIN:
- case -EFBIG:
- case -EMSGSIZE:
- return "internal error";
- default:
- return "unknown error";
- }
-}
-
-static void abort_usb_capture(struct ua101 *ua)
-{
- if (test_and_clear_bit(USB_CAPTURE_RUNNING, &ua->states)) {
- wake_up(&ua->alsa_capture_wait);
- wake_up(&ua->rate_feedback_wait);
- }
-}
-
-static void abort_usb_playback(struct ua101 *ua)
-{
- if (test_and_clear_bit(USB_PLAYBACK_RUNNING, &ua->states))
- wake_up(&ua->alsa_playback_wait);
-}
-
-static void playback_urb_complete(struct urb *usb_urb)
-{
- struct ua101_urb *urb = (struct ua101_urb *)usb_urb;
- struct ua101 *ua = urb->urb.context;
- unsigned long flags;
-
- if (unlikely(urb->urb.status == -ENOENT || /* unlinked */
- urb->urb.status == -ENODEV || /* device removed */
- urb->urb.status == -ECONNRESET || /* unlinked */
- urb->urb.status == -ESHUTDOWN)) { /* device disabled */
- abort_usb_playback(ua);
- abort_alsa_playback(ua);
- return;
- }
-
- if (test_bit(USB_PLAYBACK_RUNNING, &ua->states)) {
- /* append URB to FIFO */
- spin_lock_irqsave(&ua->lock, flags);
- list_add_tail(&urb->ready_list, &ua->ready_playback_urbs);
- if (ua->rate_feedback_count > 0)
- tasklet_schedule(&ua->playback_tasklet);
- ua->playback.substream->runtime->delay -=
- urb->urb.iso_frame_desc[0].length /
- ua->playback.frame_bytes;
- spin_unlock_irqrestore(&ua->lock, flags);
- }
-}
-
-static void first_playback_urb_complete(struct urb *urb)
-{
- struct ua101 *ua = urb->context;
-
- urb->complete = playback_urb_complete;
- playback_urb_complete(urb);
-
- set_bit(PLAYBACK_URB_COMPLETED, &ua->states);
- wake_up(&ua->alsa_playback_wait);
-}
-
-/* copy data from the ALSA ring buffer into the URB buffer */
-static bool copy_playback_data(struct ua101_stream *stream, struct urb *urb,
- unsigned int frames)
-{
- struct snd_pcm_runtime *runtime;
- unsigned int frame_bytes, frames1;
- const u8 *source;
-
- runtime = stream->substream->runtime;
- frame_bytes = stream->frame_bytes;
- source = runtime->dma_area + stream->buffer_pos * frame_bytes;
- if (stream->buffer_pos + frames <= runtime->buffer_size) {
- memcpy(urb->transfer_buffer, source, frames * frame_bytes);
- } else {
- /* wrap around at end of ring buffer */
- frames1 = runtime->buffer_size - stream->buffer_pos;
- memcpy(urb->transfer_buffer, source, frames1 * frame_bytes);
- memcpy(urb->transfer_buffer + frames1 * frame_bytes,
- runtime->dma_area, (frames - frames1) * frame_bytes);
- }
-
- stream->buffer_pos += frames;
- if (stream->buffer_pos >= runtime->buffer_size)
- stream->buffer_pos -= runtime->buffer_size;
- stream->period_pos += frames;
- if (stream->period_pos >= runtime->period_size) {
- stream->period_pos -= runtime->period_size;
- return true;
- }
- return false;
-}
-
-static inline void add_with_wraparound(struct ua101 *ua,
- unsigned int *value, unsigned int add)
-{
- *value += add;
- if (*value >= ua->playback.queue_length)
- *value -= ua->playback.queue_length;
-}
-
-static void playback_tasklet(unsigned long data)
-{
- struct ua101 *ua = (void *)data;
- unsigned long flags;
- unsigned int frames;
- struct ua101_urb *urb;
- bool do_period_elapsed = false;
- int err;
-
- if (unlikely(!test_bit(USB_PLAYBACK_RUNNING, &ua->states)))
- return;
-
- /*
- * Synchronizing the playback rate to the capture rate is done by using
- * the same sequence of packet sizes for both streams.
- * Submitting a playback URB therefore requires both a ready URB and
- * the size of the corresponding capture packet, i.e., both playback
- * and capture URBs must have been completed. Since the USB core does
- * not guarantee that playback and capture complete callbacks are
- * called alternately, we use two FIFOs for packet sizes and read URBs;
- * submitting playback URBs is possible as long as both FIFOs are
- * nonempty.
- */
- spin_lock_irqsave(&ua->lock, flags);
- while (ua->rate_feedback_count > 0 &&
- !list_empty(&ua->ready_playback_urbs)) {
- /* take packet size out of FIFO */
- frames = ua->rate_feedback[ua->rate_feedback_start];
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
- ua->rate_feedback_count--;
-
- /* take URB out of FIFO */
- urb = list_first_entry(&ua->ready_playback_urbs,
- struct ua101_urb, ready_list);
- list_del(&urb->ready_list);
-
- /* fill packet with data or silence */
- urb->urb.iso_frame_desc[0].length =
- frames * ua->playback.frame_bytes;
- if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
- do_period_elapsed |= copy_playback_data(&ua->playback,
- &urb->urb,
- frames);
- else
- memset(urb->urb.transfer_buffer, 0,
- urb->urb.iso_frame_desc[0].length);
-
- /* and off you go ... */
- err = usb_submit_urb(&urb->urb, GFP_ATOMIC);
- if (unlikely(err < 0)) {
- spin_unlock_irqrestore(&ua->lock, flags);
- abort_usb_playback(ua);
- abort_alsa_playback(ua);
- dev_err(&ua->dev->dev, "USB request error %d: %s\n",
- err, usb_error_string(err));
- return;
- }
- ua->playback.substream->runtime->delay += frames;
- }
- spin_unlock_irqrestore(&ua->lock, flags);
- if (do_period_elapsed)
- snd_pcm_period_elapsed(ua->playback.substream);
-}
-
-/* copy data from the URB buffer into the ALSA ring buffer */
-static bool copy_capture_data(struct ua101_stream *stream, struct urb *urb,
- unsigned int frames)
-{
- struct snd_pcm_runtime *runtime;
- unsigned int frame_bytes, frames1;
- u8 *dest;
-
- runtime = stream->substream->runtime;
- frame_bytes = stream->frame_bytes;
- dest = runtime->dma_area + stream->buffer_pos * frame_bytes;
- if (stream->buffer_pos + frames <= runtime->buffer_size) {
- memcpy(dest, urb->transfer_buffer, frames * frame_bytes);
- } else {
- /* wrap around at end of ring buffer */
- frames1 = runtime->buffer_size - stream->buffer_pos;
- memcpy(dest, urb->transfer_buffer, frames1 * frame_bytes);
- memcpy(runtime->dma_area,
- urb->transfer_buffer + frames1 * frame_bytes,
- (frames - frames1) * frame_bytes);
- }
-
- stream->buffer_pos += frames;
- if (stream->buffer_pos >= runtime->buffer_size)
- stream->buffer_pos -= runtime->buffer_size;
- stream->period_pos += frames;
- if (stream->period_pos >= runtime->period_size) {
- stream->period_pos -= runtime->period_size;
- return true;
- }
- return false;
-}
-
-static void capture_urb_complete(struct urb *urb)
-{
- struct ua101 *ua = urb->context;
- struct ua101_stream *stream = &ua->capture;
- unsigned long flags;
- unsigned int frames, write_ptr;
- bool do_period_elapsed;
- int err;
-
- if (unlikely(urb->status == -ENOENT || /* unlinked */
- urb->status == -ENODEV || /* device removed */
- urb->status == -ECONNRESET || /* unlinked */
- urb->status == -ESHUTDOWN)) /* device disabled */
- goto stream_stopped;
-
- if (urb->status >= 0 && urb->iso_frame_desc[0].status >= 0)
- frames = urb->iso_frame_desc[0].actual_length /
- stream->frame_bytes;
- else
- frames = 0;
-
- spin_lock_irqsave(&ua->lock, flags);
-
- if (frames > 0 && test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
- do_period_elapsed = copy_capture_data(stream, urb, frames);
- else
- do_period_elapsed = false;
-
- if (test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (unlikely(err < 0)) {
- spin_unlock_irqrestore(&ua->lock, flags);
- dev_err(&ua->dev->dev, "USB request error %d: %s\n",
- err, usb_error_string(err));
- goto stream_stopped;
- }
-
- /* append packet size to FIFO */
- write_ptr = ua->rate_feedback_start;
- add_with_wraparound(ua, &write_ptr, ua->rate_feedback_count);
- ua->rate_feedback[write_ptr] = frames;
- if (ua->rate_feedback_count < ua->playback.queue_length) {
- ua->rate_feedback_count++;
- if (ua->rate_feedback_count ==
- ua->playback.queue_length)
- wake_up(&ua->rate_feedback_wait);
- } else {
- /*
- * Ring buffer overflow; this happens when the playback
- * stream is not running. Throw away the oldest entry,
- * so that the playback stream, when it starts, sees
- * the most recent packet sizes.
- */
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
- }
- if (test_bit(USB_PLAYBACK_RUNNING, &ua->states) &&
- !list_empty(&ua->ready_playback_urbs))
- tasklet_schedule(&ua->playback_tasklet);
- }
-
- spin_unlock_irqrestore(&ua->lock, flags);
-
- if (do_period_elapsed)
- snd_pcm_period_elapsed(stream->substream);
-
- return;
-
-stream_stopped:
- abort_usb_playback(ua);
- abort_usb_capture(ua);
- abort_alsa_playback(ua);
- abort_alsa_capture(ua);
-}
-
-static void first_capture_urb_complete(struct urb *urb)
-{
- struct ua101 *ua = urb->context;
-
- urb->complete = capture_urb_complete;
- capture_urb_complete(urb);
-
- set_bit(CAPTURE_URB_COMPLETED, &ua->states);
- wake_up(&ua->alsa_capture_wait);
-}
-
-static int submit_stream_urbs(struct ua101 *ua, struct ua101_stream *stream)
-{
- unsigned int i;
-
- for (i = 0; i < stream->queue_length; ++i) {
- int err = usb_submit_urb(&stream->urbs[i]->urb, GFP_KERNEL);
- if (err < 0) {
- dev_err(&ua->dev->dev, "USB request error %d: %s\n",
- err, usb_error_string(err));
- return err;
- }
- }
- return 0;
-}
-
-static void kill_stream_urbs(struct ua101_stream *stream)
-{
- unsigned int i;
-
- for (i = 0; i < stream->queue_length; ++i)
- if (stream->urbs[i])
- usb_kill_urb(&stream->urbs[i]->urb);
-}
-
-static int enable_iso_interface(struct ua101 *ua, unsigned int intf_index)
-{
- struct usb_host_interface *alts;
-
- alts = ua->intf[intf_index]->cur_altsetting;
- if (alts->desc.bAlternateSetting != 1) {
- int err = usb_set_interface(ua->dev,
- alts->desc.bInterfaceNumber, 1);
- if (err < 0) {
- dev_err(&ua->dev->dev,
- "cannot initialize interface; error %d: %s\n",
- err, usb_error_string(err));
- return err;
- }
- }
- return 0;
-}
-
-static void disable_iso_interface(struct ua101 *ua, unsigned int intf_index)
-{
- struct usb_host_interface *alts;
-
- if (!ua->intf[intf_index])
- return;
-
- alts = ua->intf[intf_index]->cur_altsetting;
- if (alts->desc.bAlternateSetting != 0) {
- int err = usb_set_interface(ua->dev,
- alts->desc.bInterfaceNumber, 0);
- if (err < 0 && !test_bit(DISCONNECTED, &ua->states))
- dev_warn(&ua->dev->dev,
- "interface reset failed; error %d: %s\n",
- err, usb_error_string(err));
- }
-}
-
-static void stop_usb_capture(struct ua101 *ua)
-{
- clear_bit(USB_CAPTURE_RUNNING, &ua->states);
-
- kill_stream_urbs(&ua->capture);
-
- disable_iso_interface(ua, INTF_CAPTURE);
-}
-
-static int start_usb_capture(struct ua101 *ua)
-{
- int err;
-
- if (test_bit(DISCONNECTED, &ua->states))
- return -ENODEV;
-
- if (test_bit(USB_CAPTURE_RUNNING, &ua->states))
- return 0;
-
- kill_stream_urbs(&ua->capture);
-
- err = enable_iso_interface(ua, INTF_CAPTURE);
- if (err < 0)
- return err;
-
- clear_bit(CAPTURE_URB_COMPLETED, &ua->states);
- ua->capture.urbs[0]->urb.complete = first_capture_urb_complete;
- ua->rate_feedback_start = 0;
- ua->rate_feedback_count = 0;
-
- set_bit(USB_CAPTURE_RUNNING, &ua->states);
- err = submit_stream_urbs(ua, &ua->capture);
- if (err < 0)
- stop_usb_capture(ua);
- return err;
-}
-
-static void stop_usb_playback(struct ua101 *ua)
-{
- clear_bit(USB_PLAYBACK_RUNNING, &ua->states);
-
- kill_stream_urbs(&ua->playback);
-
- tasklet_kill(&ua->playback_tasklet);
-
- disable_iso_interface(ua, INTF_PLAYBACK);
-}
-
-static int start_usb_playback(struct ua101 *ua)
-{
- unsigned int i, frames;
- struct urb *urb;
- int err = 0;
-
- if (test_bit(DISCONNECTED, &ua->states))
- return -ENODEV;
-
- if (test_bit(USB_PLAYBACK_RUNNING, &ua->states))
- return 0;
-
- kill_stream_urbs(&ua->playback);
- tasklet_kill(&ua->playback_tasklet);
-
- err = enable_iso_interface(ua, INTF_PLAYBACK);
- if (err < 0)
- return err;
-
- clear_bit(PLAYBACK_URB_COMPLETED, &ua->states);
- ua->playback.urbs[0]->urb.complete =
- first_playback_urb_complete;
- spin_lock_irq(&ua->lock);
- INIT_LIST_HEAD(&ua->ready_playback_urbs);
- spin_unlock_irq(&ua->lock);
-
- /*
- * We submit the initial URBs all at once, so we have to wait for the
- * packet size FIFO to be full.
- */
- wait_event(ua->rate_feedback_wait,
- ua->rate_feedback_count >= ua->playback.queue_length ||
- !test_bit(USB_CAPTURE_RUNNING, &ua->states) ||
- test_bit(DISCONNECTED, &ua->states));
- if (test_bit(DISCONNECTED, &ua->states)) {
- stop_usb_playback(ua);
- return -ENODEV;
- }
- if (!test_bit(USB_CAPTURE_RUNNING, &ua->states)) {
- stop_usb_playback(ua);
- return -EIO;
- }
-
- for (i = 0; i < ua->playback.queue_length; ++i) {
- /* all initial URBs contain silence */
- spin_lock_irq(&ua->lock);
- frames = ua->rate_feedback[ua->rate_feedback_start];
- add_with_wraparound(ua, &ua->rate_feedback_start, 1);
- ua->rate_feedback_count--;
- spin_unlock_irq(&ua->lock);
- urb = &ua->playback.urbs[i]->urb;
- urb->iso_frame_desc[0].length =
- frames * ua->playback.frame_bytes;
- memset(urb->transfer_buffer, 0,
- urb->iso_frame_desc[0].length);
- }
-
- set_bit(USB_PLAYBACK_RUNNING, &ua->states);
- err = submit_stream_urbs(ua, &ua->playback);
- if (err < 0)
- stop_usb_playback(ua);
- return err;
-}
-
-static void abort_alsa_capture(struct ua101 *ua)
-{
- if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
- snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN);
-}
-
-static void abort_alsa_playback(struct ua101 *ua)
-{
- if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
- snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN);
-}
-
-static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
- unsigned int channels)
-{
- int err;
-
- substream->runtime->hw.info =
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_FIFO_IN_FRAMES;
- substream->runtime->hw.formats = ua->format_bit;
- substream->runtime->hw.rates = snd_pcm_rate_to_rate_bit(ua->rate);
- substream->runtime->hw.rate_min = ua->rate;
- substream->runtime->hw.rate_max = ua->rate;
- substream->runtime->hw.channels_min = channels;
- substream->runtime->hw.channels_max = channels;
- substream->runtime->hw.buffer_bytes_max = 45000 * 1024;
- substream->runtime->hw.period_bytes_min = 1;
- substream->runtime->hw.period_bytes_max = UINT_MAX;
- substream->runtime->hw.periods_min = 2;
- substream->runtime->hw.periods_max = UINT_MAX;
- err = snd_pcm_hw_constraint_minmax(substream->runtime,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- 1500000 / ua->packets_per_second,
- UINT_MAX);
- if (err < 0)
- return err;
- err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
- return err;
-}
-
-static int capture_pcm_open(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- ua->capture.substream = substream;
- err = set_stream_hw(ua, substream, ua->capture.channels);
- if (err < 0)
- return err;
- substream->runtime->hw.fifo_size =
- DIV_ROUND_CLOSEST(ua->rate, ua->packets_per_second);
- substream->runtime->delay = substream->runtime->hw.fifo_size;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err >= 0)
- set_bit(ALSA_CAPTURE_OPEN, &ua->states);
- mutex_unlock(&ua->mutex);
- return err;
-}
-
-static int playback_pcm_open(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- ua->playback.substream = substream;
- err = set_stream_hw(ua, substream, ua->playback.channels);
- if (err < 0)
- return err;
- substream->runtime->hw.fifo_size =
- DIV_ROUND_CLOSEST(ua->rate * ua->playback.queue_length,
- ua->packets_per_second);
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err < 0)
- goto error;
- err = start_usb_playback(ua);
- if (err < 0) {
- if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
- stop_usb_capture(ua);
- goto error;
- }
- set_bit(ALSA_PLAYBACK_OPEN, &ua->states);
-error:
- mutex_unlock(&ua->mutex);
- return err;
-}
-
-static int capture_pcm_close(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
-
- mutex_lock(&ua->mutex);
- clear_bit(ALSA_CAPTURE_OPEN, &ua->states);
- if (!test_bit(ALSA_PLAYBACK_OPEN, &ua->states))
- stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- return 0;
-}
-
-static int playback_pcm_close(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
-
- mutex_lock(&ua->mutex);
- stop_usb_playback(ua);
- clear_bit(ALSA_PLAYBACK_OPEN, &ua->states);
- if (!test_bit(ALSA_CAPTURE_OPEN, &ua->states))
- stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- return 0;
-}
-
-static int capture_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- if (err < 0)
- return err;
-
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int playback_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err >= 0)
- err = start_usb_playback(ua);
- mutex_unlock(&ua->mutex);
- if (err < 0)
- return err;
-
- return snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
-}
-
-static int ua101_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-static int capture_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- mutex_unlock(&ua->mutex);
- if (err < 0)
- return err;
-
- /*
- * The EHCI driver schedules the first packet of an iso stream at 10 ms
- * in the future, i.e., no data is actually captured for that long.
- * Take the wait here so that the stream is known to be actually
- * running when the start trigger has been called.
- */
- wait_event(ua->alsa_capture_wait,
- test_bit(CAPTURE_URB_COMPLETED, &ua->states) ||
- !test_bit(USB_CAPTURE_RUNNING, &ua->states));
- if (test_bit(DISCONNECTED, &ua->states))
- return -ENODEV;
- if (!test_bit(USB_CAPTURE_RUNNING, &ua->states))
- return -EIO;
-
- ua->capture.period_pos = 0;
- ua->capture.buffer_pos = 0;
- return 0;
-}
-
-static int playback_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct ua101 *ua = substream->private_data;
- int err;
-
- mutex_lock(&ua->mutex);
- err = start_usb_capture(ua);
- if (err >= 0)
- err = start_usb_playback(ua);
- mutex_unlock(&ua->mutex);
- if (err < 0)
- return err;
-
- /* see the comment in capture_pcm_prepare() */
- wait_event(ua->alsa_playback_wait,
- test_bit(PLAYBACK_URB_COMPLETED, &ua->states) ||
- !test_bit(USB_PLAYBACK_RUNNING, &ua->states));
- if (test_bit(DISCONNECTED, &ua->states))
- return -ENODEV;
- if (!test_bit(USB_PLAYBACK_RUNNING, &ua->states))
- return -EIO;
-
- substream->runtime->delay = 0;
- ua->playback.period_pos = 0;
- ua->playback.buffer_pos = 0;
- return 0;
-}
-
-static int capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct ua101 *ua = substream->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (!test_bit(USB_CAPTURE_RUNNING, &ua->states))
- return -EIO;
- set_bit(ALSA_CAPTURE_RUNNING, &ua->states);
- return 0;
- case SNDRV_PCM_TRIGGER_STOP:
- clear_bit(ALSA_CAPTURE_RUNNING, &ua->states);
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static int playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct ua101 *ua = substream->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- if (!test_bit(USB_PLAYBACK_RUNNING, &ua->states))
- return -EIO;
- set_bit(ALSA_PLAYBACK_RUNNING, &ua->states);
- return 0;
- case SNDRV_PCM_TRIGGER_STOP:
- clear_bit(ALSA_PLAYBACK_RUNNING, &ua->states);
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-static inline snd_pcm_uframes_t ua101_pcm_pointer(struct ua101 *ua,
- struct ua101_stream *stream)
-{
- unsigned long flags;
- unsigned int pos;
-
- spin_lock_irqsave(&ua->lock, flags);
- pos = stream->buffer_pos;
- spin_unlock_irqrestore(&ua->lock, flags);
- return pos;
-}
-
-static snd_pcm_uframes_t capture_pcm_pointer(struct snd_pcm_substream *subs)
-{
- struct ua101 *ua = subs->private_data;
-
- return ua101_pcm_pointer(ua, &ua->capture);
-}
-
-static snd_pcm_uframes_t playback_pcm_pointer(struct snd_pcm_substream *subs)
-{
- struct ua101 *ua = subs->private_data;
-
- return ua101_pcm_pointer(ua, &ua->playback);
-}
-
-static struct snd_pcm_ops capture_pcm_ops = {
- .open = capture_pcm_open,
- .close = capture_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = capture_pcm_hw_params,
- .hw_free = ua101_pcm_hw_free,
- .prepare = capture_pcm_prepare,
- .trigger = capture_pcm_trigger,
- .pointer = capture_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static struct snd_pcm_ops playback_pcm_ops = {
- .open = playback_pcm_open,
- .close = playback_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = playback_pcm_hw_params,
- .hw_free = ua101_pcm_hw_free,
- .prepare = playback_pcm_prepare,
- .trigger = playback_pcm_trigger,
- .pointer = playback_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static const struct uac_format_type_i_discrete_descriptor *
-find_format_descriptor(struct usb_interface *interface)
-{
- struct usb_host_interface *alt;
- u8 *extra;
- int extralen;
-
- if (interface->num_altsetting != 2) {
- dev_err(&interface->dev, "invalid num_altsetting\n");
- return NULL;
- }
-
- alt = &interface->altsetting[0];
- if (alt->desc.bNumEndpoints != 0) {
- dev_err(&interface->dev, "invalid bNumEndpoints\n");
- return NULL;
- }
-
- alt = &interface->altsetting[1];
- if (alt->desc.bNumEndpoints != 1) {
- dev_err(&interface->dev, "invalid bNumEndpoints\n");
- return NULL;
- }
-
- extra = alt->extra;
- extralen = alt->extralen;
- while (extralen >= sizeof(struct usb_descriptor_header)) {
- struct uac_format_type_i_discrete_descriptor *desc;
-
- desc = (struct uac_format_type_i_discrete_descriptor *)extra;
- if (desc->bLength > extralen) {
- dev_err(&interface->dev, "descriptor overflow\n");
- return NULL;
- }
- if (desc->bLength == UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1) &&
- desc->bDescriptorType == USB_DT_CS_INTERFACE &&
- desc->bDescriptorSubtype == UAC_FORMAT_TYPE) {
- if (desc->bFormatType != UAC_FORMAT_TYPE_I_PCM ||
- desc->bSamFreqType != 1) {
- dev_err(&interface->dev,
- "invalid format type\n");
- return NULL;
- }
- return desc;
- }
- extralen -= desc->bLength;
- extra += desc->bLength;
- }
- dev_err(&interface->dev, "sample format descriptor not found\n");
- return NULL;
-}
-
-static int detect_usb_format(struct ua101 *ua)
-{
- const struct uac_format_type_i_discrete_descriptor *fmt_capture;
- const struct uac_format_type_i_discrete_descriptor *fmt_playback;
- const struct usb_endpoint_descriptor *epd;
- unsigned int rate2;
-
- fmt_capture = find_format_descriptor(ua->intf[INTF_CAPTURE]);
- fmt_playback = find_format_descriptor(ua->intf[INTF_PLAYBACK]);
- if (!fmt_capture || !fmt_playback)
- return -ENXIO;
-
- switch (fmt_capture->bSubframeSize) {
- case 3:
- ua->format_bit = SNDRV_PCM_FMTBIT_S24_3LE;
- break;
- case 4:
- ua->format_bit = SNDRV_PCM_FMTBIT_S32_LE;
- break;
- default:
- dev_err(&ua->dev->dev, "sample width is not 24 or 32 bits\n");
- return -ENXIO;
- }
- if (fmt_capture->bSubframeSize != fmt_playback->bSubframeSize) {
- dev_err(&ua->dev->dev,
- "playback/capture sample widths do not match\n");
- return -ENXIO;
- }
-
- if (fmt_capture->bBitResolution != 24 ||
- fmt_playback->bBitResolution != 24) {
- dev_err(&ua->dev->dev, "sample width is not 24 bits\n");
- return -ENXIO;
- }
-
- ua->rate = combine_triple(fmt_capture->tSamFreq[0]);
- rate2 = combine_triple(fmt_playback->tSamFreq[0]);
- if (ua->rate != rate2) {
- dev_err(&ua->dev->dev,
- "playback/capture rates do not match: %u/%u\n",
- rate2, ua->rate);
- return -ENXIO;
- }
-
- switch (ua->dev->speed) {
- case USB_SPEED_FULL:
- ua->packets_per_second = 1000;
- break;
- case USB_SPEED_HIGH:
- ua->packets_per_second = 8000;
- break;
- default:
- dev_err(&ua->dev->dev, "unknown device speed\n");
- return -ENXIO;
- }
-
- ua->capture.channels = fmt_capture->bNrChannels;
- ua->playback.channels = fmt_playback->bNrChannels;
- ua->capture.frame_bytes =
- fmt_capture->bSubframeSize * ua->capture.channels;
- ua->playback.frame_bytes =
- fmt_playback->bSubframeSize * ua->playback.channels;
-
- epd = &ua->intf[INTF_CAPTURE]->altsetting[1].endpoint[0].desc;
- if (!usb_endpoint_is_isoc_in(epd)) {
- dev_err(&ua->dev->dev, "invalid capture endpoint\n");
- return -ENXIO;
- }
- ua->capture.usb_pipe = usb_rcvisocpipe(ua->dev, usb_endpoint_num(epd));
- ua->capture.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize);
-
- epd = &ua->intf[INTF_PLAYBACK]->altsetting[1].endpoint[0].desc;
- if (!usb_endpoint_is_isoc_out(epd)) {
- dev_err(&ua->dev->dev, "invalid playback endpoint\n");
- return -ENXIO;
- }
- ua->playback.usb_pipe = usb_sndisocpipe(ua->dev, usb_endpoint_num(epd));
- ua->playback.max_packet_bytes = le16_to_cpu(epd->wMaxPacketSize);
- return 0;
-}
-
-static int alloc_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
-{
- unsigned int remaining_packets, packets, packets_per_page, i;
- size_t size;
-
- stream->queue_length = queue_length;
- stream->queue_length = max(stream->queue_length,
- (unsigned int)MIN_QUEUE_LENGTH);
- stream->queue_length = min(stream->queue_length,
- (unsigned int)MAX_QUEUE_LENGTH);
-
- /*
- * The cache pool sizes used by usb_alloc_coherent() (128, 512, 2048) are
- * quite bad when used with the packet sizes of this device (e.g. 280,
- * 520, 624). Therefore, we allocate and subdivide entire pages, using
- * a smaller buffer only for the last chunk.
- */
- remaining_packets = stream->queue_length;
- packets_per_page = PAGE_SIZE / stream->max_packet_bytes;
- for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i) {
- packets = min(remaining_packets, packets_per_page);
- size = packets * stream->max_packet_bytes;
- stream->buffers[i].addr =
- usb_alloc_coherent(ua->dev, size, GFP_KERNEL,
- &stream->buffers[i].dma);
- if (!stream->buffers[i].addr)
- return -ENOMEM;
- stream->buffers[i].size = size;
- remaining_packets -= packets;
- if (!remaining_packets)
- break;
- }
- if (remaining_packets) {
- dev_err(&ua->dev->dev, "too many packets\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static void free_stream_buffers(struct ua101 *ua, struct ua101_stream *stream)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(stream->buffers); ++i)
- usb_free_coherent(ua->dev,
- stream->buffers[i].size,
- stream->buffers[i].addr,
- stream->buffers[i].dma);
-}
-
-static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream,
- void (*urb_complete)(struct urb *))
-{
- unsigned max_packet_size = stream->max_packet_bytes;
- struct ua101_urb *urb;
- unsigned int b, u = 0;
-
- for (b = 0; b < ARRAY_SIZE(stream->buffers); ++b) {
- unsigned int size = stream->buffers[b].size;
- u8 *addr = stream->buffers[b].addr;
- dma_addr_t dma = stream->buffers[b].dma;
-
- while (size >= max_packet_size) {
- if (u >= stream->queue_length)
- goto bufsize_error;
- urb = kmalloc(sizeof(*urb), GFP_KERNEL);
- if (!urb)
- return -ENOMEM;
- usb_init_urb(&urb->urb);
- urb->urb.dev = ua->dev;
- urb->urb.pipe = stream->usb_pipe;
- urb->urb.transfer_flags = URB_ISO_ASAP |
- URB_NO_TRANSFER_DMA_MAP;
- urb->urb.transfer_buffer = addr;
- urb->urb.transfer_dma = dma;
- urb->urb.transfer_buffer_length = max_packet_size;
- urb->urb.number_of_packets = 1;
- urb->urb.interval = 1;
- urb->urb.context = ua;
- urb->urb.complete = urb_complete;
- urb->urb.iso_frame_desc[0].offset = 0;
- urb->urb.iso_frame_desc[0].length = max_packet_size;
- stream->urbs[u++] = urb;
- size -= max_packet_size;
- addr += max_packet_size;
- dma += max_packet_size;
- }
- }
- if (u == stream->queue_length)
- return 0;
-bufsize_error:
- dev_err(&ua->dev->dev, "internal buffer size error\n");
- return -ENXIO;
-}
-
-static void free_stream_urbs(struct ua101_stream *stream)
-{
- unsigned int i;
-
- for (i = 0; i < stream->queue_length; ++i) {
- kfree(stream->urbs[i]);
- stream->urbs[i] = NULL;
- }
-}
-
-static void free_usb_related_resources(struct ua101 *ua,
- struct usb_interface *interface)
-{
- unsigned int i;
- struct usb_interface *intf;
-
- mutex_lock(&ua->mutex);
- free_stream_urbs(&ua->capture);
- free_stream_urbs(&ua->playback);
- mutex_unlock(&ua->mutex);
- free_stream_buffers(ua, &ua->capture);
- free_stream_buffers(ua, &ua->playback);
-
- for (i = 0; i < ARRAY_SIZE(ua->intf); ++i) {
- mutex_lock(&ua->mutex);
- intf = ua->intf[i];
- ua->intf[i] = NULL;
- mutex_unlock(&ua->mutex);
- if (intf) {
- usb_set_intfdata(intf, NULL);
- if (intf != interface)
- usb_driver_release_interface(&ua101_driver,
- intf);
- }
- }
-}
-
-static void ua101_card_free(struct snd_card *card)
-{
- struct ua101 *ua = card->private_data;
-
- mutex_destroy(&ua->mutex);
-}
-
-static int ua101_probe(struct usb_interface *interface,
- const struct usb_device_id *usb_id)
-{
- static const struct snd_usb_midi_endpoint_info midi_ep = {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- };
- static const struct snd_usb_audio_quirk midi_quirk = {
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &midi_ep
- };
- static const int intf_numbers[2][3] = {
- { /* UA-101 */
- [INTF_PLAYBACK] = 0,
- [INTF_CAPTURE] = 1,
- [INTF_MIDI] = 2,
- },
- { /* UA-1000 */
- [INTF_CAPTURE] = 1,
- [INTF_PLAYBACK] = 2,
- [INTF_MIDI] = 3,
- },
- };
- struct snd_card *card;
- struct ua101 *ua;
- unsigned int card_index, i;
- int is_ua1000;
- const char *name;
- char usb_path[32];
- int err;
-
- is_ua1000 = usb_id->idProduct == 0x0044;
-
- if (interface->altsetting->desc.bInterfaceNumber !=
- intf_numbers[is_ua1000][0])
- return -ENODEV;
-
- mutex_lock(&devices_mutex);
-
- for (card_index = 0; card_index < SNDRV_CARDS; ++card_index)
- if (enable[card_index] && !(devices_used & (1 << card_index)))
- break;
- if (card_index >= SNDRV_CARDS) {
- mutex_unlock(&devices_mutex);
- return -ENOENT;
- }
- err = snd_card_create(index[card_index], id[card_index], THIS_MODULE,
- sizeof(*ua), &card);
- if (err < 0) {
- mutex_unlock(&devices_mutex);
- return err;
- }
- card->private_free = ua101_card_free;
- ua = card->private_data;
- ua->dev = interface_to_usbdev(interface);
- ua->card = card;
- ua->card_index = card_index;
- INIT_LIST_HEAD(&ua->midi_list);
- spin_lock_init(&ua->lock);
- mutex_init(&ua->mutex);
- INIT_LIST_HEAD(&ua->ready_playback_urbs);
- tasklet_init(&ua->playback_tasklet,
- playback_tasklet, (unsigned long)ua);
- init_waitqueue_head(&ua->alsa_capture_wait);
- init_waitqueue_head(&ua->rate_feedback_wait);
- init_waitqueue_head(&ua->alsa_playback_wait);
-
- ua->intf[0] = interface;
- for (i = 1; i < ARRAY_SIZE(ua->intf); ++i) {
- ua->intf[i] = usb_ifnum_to_if(ua->dev,
- intf_numbers[is_ua1000][i]);
- if (!ua->intf[i]) {
- dev_err(&ua->dev->dev, "interface %u not found\n",
- intf_numbers[is_ua1000][i]);
- err = -ENXIO;
- goto probe_error;
- }
- err = usb_driver_claim_interface(&ua101_driver,
- ua->intf[i], ua);
- if (err < 0) {
- ua->intf[i] = NULL;
- err = -EBUSY;
- goto probe_error;
- }
- }
-
- snd_card_set_dev(card, &interface->dev);
-
- err = detect_usb_format(ua);
- if (err < 0)
- goto probe_error;
-
- name = usb_id->idProduct == 0x0044 ? "UA-1000" : "UA-101";
- strcpy(card->driver, "UA-101");
- strcpy(card->shortname, name);
- usb_make_path(ua->dev, usb_path, sizeof(usb_path));
- snprintf(ua->card->longname, sizeof(ua->card->longname),
- "EDIROL %s (serial %s), %u Hz at %s, %s speed", name,
- ua->dev->serial ? ua->dev->serial : "?", ua->rate, usb_path,
- ua->dev->speed == USB_SPEED_HIGH ? "high" : "full");
-
- err = alloc_stream_buffers(ua, &ua->capture);
- if (err < 0)
- goto probe_error;
- err = alloc_stream_buffers(ua, &ua->playback);
- if (err < 0)
- goto probe_error;
-
- err = alloc_stream_urbs(ua, &ua->capture, capture_urb_complete);
- if (err < 0)
- goto probe_error;
- err = alloc_stream_urbs(ua, &ua->playback, playback_urb_complete);
- if (err < 0)
- goto probe_error;
-
- err = snd_pcm_new(card, name, 0, 1, 1, &ua->pcm);
- if (err < 0)
- goto probe_error;
- ua->pcm->private_data = ua;
- strcpy(ua->pcm->name, name);
- snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_pcm_ops);
- snd_pcm_set_ops(ua->pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_pcm_ops);
-
- err = snd_usbmidi_create(card, ua->intf[INTF_MIDI],
- &ua->midi_list, &midi_quirk);
- if (err < 0)
- goto probe_error;
-
- err = snd_card_register(card);
- if (err < 0)
- goto probe_error;
-
- usb_set_intfdata(interface, ua);
- devices_used |= 1 << card_index;
-
- mutex_unlock(&devices_mutex);
- return 0;
-
-probe_error:
- free_usb_related_resources(ua, interface);
- snd_card_free(card);
- mutex_unlock(&devices_mutex);
- return err;
-}
-
-static void ua101_disconnect(struct usb_interface *interface)
-{
- struct ua101 *ua = usb_get_intfdata(interface);
- struct list_head *midi;
-
- if (!ua)
- return;
-
- mutex_lock(&devices_mutex);
-
- set_bit(DISCONNECTED, &ua->states);
- wake_up(&ua->rate_feedback_wait);
-
- /* make sure that userspace cannot create new requests */
- snd_card_disconnect(ua->card);
-
- /* make sure that there are no pending USB requests */
- __list_for_each(midi, &ua->midi_list)
- snd_usbmidi_disconnect(midi);
- abort_alsa_playback(ua);
- abort_alsa_capture(ua);
- mutex_lock(&ua->mutex);
- stop_usb_playback(ua);
- stop_usb_capture(ua);
- mutex_unlock(&ua->mutex);
-
- free_usb_related_resources(ua, interface);
-
- devices_used &= ~(1 << ua->card_index);
-
- snd_card_free_when_closed(ua->card);
-
- mutex_unlock(&devices_mutex);
-}
-
-static struct usb_device_id ua101_ids[] = {
- { USB_DEVICE(0x0582, 0x0044) }, /* UA-1000 high speed */
- { USB_DEVICE(0x0582, 0x007d) }, /* UA-101 high speed */
- { USB_DEVICE(0x0582, 0x008d) }, /* UA-101 full speed */
- { }
-};
-MODULE_DEVICE_TABLE(usb, ua101_ids);
-
-static struct usb_driver ua101_driver = {
- .name = "snd-ua101",
- .id_table = ua101_ids,
- .probe = ua101_probe,
- .disconnect = ua101_disconnect,
-#if 0
- .suspend = ua101_suspend,
- .resume = ua101_resume,
-#endif
-};
-
-module_usb_driver(ua101_driver);
diff --git a/ANDROID_3.4.5/sound/usb/mixer.c b/ANDROID_3.4.5/sound/usb/mixer.c
deleted file mode 100644
index ab23869c..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer.c
+++ /dev/null
@@ -1,2283 +0,0 @@
-/*
- * (Tentative) USB Audio Driver for ALSA
- *
- * Mixer control part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * Many codes borrowed from audio.c by
- * Alan Cox (alan@lxorguk.ukuu.org.uk)
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-/*
- * TODOs, for both the mixer and the streaming interfaces:
- *
- * - support for UAC2 effect units
- * - support for graphical equalizers
- * - RANGE and MEM set commands (UAC2)
- * - RANGE and MEM interrupt dispatchers (UAC2)
- * - audio channel clustering (UAC2)
- * - audio sample rate converter units (UAC2)
- * - proper handling of clock multipliers (UAC2)
- * - dispatch clock change notifications (UAC2)
- * - stop PCM streams which use a clock that became invalid
- * - stop PCM streams which use a clock selector that has changed
- * - parse available sample rates again when clock sources changed
- */
-
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/hwdep.h>
-#include <sound/info.h>
-#include <sound/tlv.h>
-
-#include "usbaudio.h"
-#include "mixer.h"
-#include "helper.h"
-#include "mixer_quirks.h"
-#include "power.h"
-
-#define MAX_ID_ELEMS 256
-
-struct usb_audio_term {
- int id;
- int type;
- int channels;
- unsigned int chconfig;
- int name;
-};
-
-struct usbmix_name_map;
-
-struct mixer_build {
- struct snd_usb_audio *chip;
- struct usb_mixer_interface *mixer;
- unsigned char *buffer;
- unsigned int buflen;
- DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS);
- struct usb_audio_term oterm;
- const struct usbmix_name_map *map;
- const struct usbmix_selector_map *selector_map;
-};
-
-/*E-mu 0202/0404/0204 eXtension Unit(XU) control*/
-enum {
- USB_XU_CLOCK_RATE = 0xe301,
- USB_XU_CLOCK_SOURCE = 0xe302,
- USB_XU_DIGITAL_IO_STATUS = 0xe303,
- USB_XU_DEVICE_OPTIONS = 0xe304,
- USB_XU_DIRECT_MONITORING = 0xe305,
- USB_XU_METERING = 0xe306
-};
-enum {
- USB_XU_CLOCK_SOURCE_SELECTOR = 0x02, /* clock source*/
- USB_XU_CLOCK_RATE_SELECTOR = 0x03, /* clock rate */
- USB_XU_DIGITAL_FORMAT_SELECTOR = 0x01, /* the spdif format */
- USB_XU_SOFT_LIMIT_SELECTOR = 0x03 /* soft limiter */
-};
-
-/*
- * manual mapping of mixer names
- * if the mixer topology is too complicated and the parsed names are
- * ambiguous, add the entries in usbmixer_maps.c.
- */
-#include "mixer_maps.c"
-
-static const struct usbmix_name_map *
-find_map(struct mixer_build *state, int unitid, int control)
-{
- const struct usbmix_name_map *p = state->map;
-
- if (!p)
- return NULL;
-
- for (p = state->map; p->id; p++) {
- if (p->id == unitid &&
- (!control || !p->control || control == p->control))
- return p;
- }
- return NULL;
-}
-
-/* get the mapped name if the unit matches */
-static int
-check_mapped_name(const struct usbmix_name_map *p, char *buf, int buflen)
-{
- if (!p || !p->name)
- return 0;
-
- buflen--;
- return strlcpy(buf, p->name, buflen);
-}
-
-/* check whether the control should be ignored */
-static inline int
-check_ignored_ctl(const struct usbmix_name_map *p)
-{
- if (!p || p->name || p->dB)
- return 0;
- return 1;
-}
-
-/* dB mapping */
-static inline void check_mapped_dB(const struct usbmix_name_map *p,
- struct usb_mixer_elem_info *cval)
-{
- if (p && p->dB) {
- cval->dBmin = p->dB->min;
- cval->dBmax = p->dB->max;
- cval->initialized = 1;
- }
-}
-
-/* get the mapped selector source name */
-static int check_mapped_selector_name(struct mixer_build *state, int unitid,
- int index, char *buf, int buflen)
-{
- const struct usbmix_selector_map *p;
-
- if (! state->selector_map)
- return 0;
- for (p = state->selector_map; p->id; p++) {
- if (p->id == unitid && index < p->count)
- return strlcpy(buf, p->names[index], buflen);
- }
- return 0;
-}
-
-/*
- * find an audio control unit with the given unit id
- */
-static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
-{
- /* we just parse the header */
- struct uac_feature_unit_descriptor *hdr = NULL;
-
- while ((hdr = snd_usb_find_desc(state->buffer, state->buflen, hdr,
- USB_DT_CS_INTERFACE)) != NULL) {
- if (hdr->bLength >= 4 &&
- hdr->bDescriptorSubtype >= UAC_INPUT_TERMINAL &&
- hdr->bDescriptorSubtype <= UAC2_SAMPLE_RATE_CONVERTER &&
- hdr->bUnitID == unit)
- return hdr;
- }
-
- return NULL;
-}
-
-/*
- * copy a string with the given id
- */
-static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen)
-{
- int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
- buf[len] = 0;
- return len;
-}
-
-/*
- * convert from the byte/word on usb descriptor to the zero-based integer
- */
-static int convert_signed_value(struct usb_mixer_elem_info *cval, int val)
-{
- switch (cval->val_type) {
- case USB_MIXER_BOOLEAN:
- return !!val;
- case USB_MIXER_INV_BOOLEAN:
- return !val;
- case USB_MIXER_U8:
- val &= 0xff;
- break;
- case USB_MIXER_S8:
- val &= 0xff;
- if (val >= 0x80)
- val -= 0x100;
- break;
- case USB_MIXER_U16:
- val &= 0xffff;
- break;
- case USB_MIXER_S16:
- val &= 0xffff;
- if (val >= 0x8000)
- val -= 0x10000;
- break;
- }
- return val;
-}
-
-/*
- * convert from the zero-based int to the byte/word for usb descriptor
- */
-static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
-{
- switch (cval->val_type) {
- case USB_MIXER_BOOLEAN:
- return !!val;
- case USB_MIXER_INV_BOOLEAN:
- return !val;
- case USB_MIXER_S8:
- case USB_MIXER_U8:
- return val & 0xff;
- case USB_MIXER_S16:
- case USB_MIXER_U16:
- return val & 0xffff;
- }
- return 0; /* not reached */
-}
-
-static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
-{
- if (! cval->res)
- cval->res = 1;
- if (val < cval->min)
- return 0;
- else if (val >= cval->max)
- return (cval->max - cval->min + cval->res - 1) / cval->res;
- else
- return (val - cval->min) / cval->res;
-}
-
-static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
-{
- if (val < 0)
- return cval->min;
- if (! cval->res)
- cval->res = 1;
- val *= cval->res;
- val += cval->min;
- if (val > cval->max)
- return cval->max;
- return val;
-}
-
-
-/*
- * retrieve a mixer value
- */
-
-static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
-{
- struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2];
- int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
- int timeout = 10;
- int err;
-
- err = snd_usb_autoresume(cval->mixer->chip);
- if (err < 0)
- return -EIO;
- while (timeout-- > 0) {
- if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
- buf, val_len) >= val_len) {
- *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
- snd_usb_autosuspend(cval->mixer->chip);
- return 0;
- }
- }
- snd_usb_autosuspend(cval->mixer->chip);
- snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
- return -EINVAL;
-}
-
-static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
-{
- struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
- unsigned char *val;
- int ret, size;
- __u8 bRequest;
-
- if (request == UAC_GET_CUR) {
- bRequest = UAC2_CS_CUR;
- size = sizeof(__u16);
- } else {
- bRequest = UAC2_CS_RANGE;
- size = sizeof(buf);
- }
-
- memset(buf, 0, sizeof(buf));
-
- ret = snd_usb_autoresume(chip) ? -EIO : 0;
- if (ret)
- goto error;
-
- ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
- buf, size);
- snd_usb_autosuspend(chip);
-
- if (ret < 0) {
-error:
- snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
- return ret;
- }
-
- /* FIXME: how should we handle multiple triplets here? */
-
- switch (request) {
- case UAC_GET_CUR:
- val = buf;
- break;
- case UAC_GET_MIN:
- val = buf + sizeof(__u16);
- break;
- case UAC_GET_MAX:
- val = buf + sizeof(__u16) * 2;
- break;
- case UAC_GET_RES:
- val = buf + sizeof(__u16) * 3;
- break;
- default:
- return -EINVAL;
- }
-
- *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16)));
-
- return 0;
-}
-
-static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
-{
- return (cval->mixer->protocol == UAC_VERSION_1) ?
- get_ctl_value_v1(cval, request, validx, value_ret) :
- get_ctl_value_v2(cval, request, validx, value_ret);
-}
-
-static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
-{
- return get_ctl_value(cval, UAC_GET_CUR, validx, value);
-}
-
-/* channel = 0: master, 1 = first channel */
-static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval,
- int channel, int *value)
-{
- return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value);
-}
-
-static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
- int channel, int index, int *value)
-{
- int err;
-
- if (cval->cached & (1 << channel)) {
- *value = cval->cache_val[index];
- return 0;
- }
- err = get_cur_mix_raw(cval, channel, value);
- if (err < 0) {
- if (!cval->mixer->ignore_ctl_error)
- snd_printd(KERN_ERR "cannot get current value for control %d ch %d: err = %d\n",
- cval->control, channel, err);
- return err;
- }
- cval->cached |= 1 << channel;
- cval->cache_val[index] = *value;
- return 0;
-}
-
-
-/*
- * set a mixer value
- */
-
-int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
- int request, int validx, int value_set)
-{
- struct snd_usb_audio *chip = cval->mixer->chip;
- unsigned char buf[2];
- int val_len, err, timeout = 10;
-
- if (cval->mixer->protocol == UAC_VERSION_1) {
- val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
- } else { /* UAC_VERSION_2 */
- /* audio class v2 controls are always 2 bytes in size */
- val_len = sizeof(__u16);
-
- /* FIXME */
- if (request != UAC_SET_CUR) {
- snd_printdd(KERN_WARNING "RANGE setting not yet supported\n");
- return -EINVAL;
- }
-
- request = UAC2_CS_CUR;
- }
-
- value_set = convert_bytes_value(cval, value_set);
- buf[0] = value_set & 0xff;
- buf[1] = (value_set >> 8) & 0xff;
- err = snd_usb_autoresume(chip);
- if (err < 0)
- return -EIO;
- while (timeout-- > 0)
- if (snd_usb_ctl_msg(chip->dev,
- usb_sndctrlpipe(chip->dev, 0), request,
- USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
- validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
- buf, val_len) >= 0) {
- snd_usb_autosuspend(chip);
- return 0;
- }
- snd_usb_autosuspend(chip);
- snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
- request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
- return -EINVAL;
-}
-
-static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
-{
- return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value);
-}
-
-static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
- int index, int value)
-{
- int err;
- unsigned int read_only = (channel == 0) ?
- cval->master_readonly :
- cval->ch_readonly & (1 << (channel - 1));
-
- if (read_only) {
- snd_printdd(KERN_INFO "%s(): channel %d of control %d is read_only\n",
- __func__, channel, cval->control);
- return 0;
- }
-
- err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
- value);
- if (err < 0)
- return err;
- cval->cached |= 1 << channel;
- cval->cache_val[index] = value;
- return 0;
-}
-
-/*
- * TLV callback for mixer volume controls
- */
-static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
- unsigned int size, unsigned int __user *_tlv)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- DECLARE_TLV_DB_MINMAX(scale, 0, 0);
-
- if (size < sizeof(scale))
- return -ENOMEM;
- scale[2] = cval->dBmin;
- scale[3] = cval->dBmax;
- if (copy_to_user(_tlv, scale, sizeof(scale)))
- return -EFAULT;
- return 0;
-}
-
-/*
- * parser routines begin here...
- */
-
-static int parse_audio_unit(struct mixer_build *state, int unitid);
-
-
-/*
- * check if the input/output channel routing is enabled on the given bitmap.
- * used for mixer unit parser
- */
-static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs)
-{
- int idx = ich * num_outs + och;
- return bmap[idx >> 3] & (0x80 >> (idx & 7));
-}
-
-
-/*
- * add an alsa control element
- * search and increment the index until an empty slot is found.
- *
- * if failed, give up and free the control instance.
- */
-
-int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
- struct snd_kcontrol *kctl)
-{
- struct usb_mixer_elem_info *cval = kctl->private_data;
- int err;
-
- while (snd_ctl_find_id(mixer->chip->card, &kctl->id))
- kctl->id.index++;
- if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) {
- snd_printd(KERN_ERR "cannot add control (err = %d)\n", err);
- return err;
- }
- cval->elem_id = &kctl->id;
- cval->next_id_elem = mixer->id_elems[cval->id];
- mixer->id_elems[cval->id] = cval;
- return 0;
-}
-
-
-/*
- * get a terminal name string
- */
-
-static struct iterm_name_combo {
- int type;
- char *name;
-} iterm_names[] = {
- { 0x0300, "Output" },
- { 0x0301, "Speaker" },
- { 0x0302, "Headphone" },
- { 0x0303, "HMD Audio" },
- { 0x0304, "Desktop Speaker" },
- { 0x0305, "Room Speaker" },
- { 0x0306, "Com Speaker" },
- { 0x0307, "LFE" },
- { 0x0600, "External In" },
- { 0x0601, "Analog In" },
- { 0x0602, "Digital In" },
- { 0x0603, "Line" },
- { 0x0604, "Legacy In" },
- { 0x0605, "IEC958 In" },
- { 0x0606, "1394 DA Stream" },
- { 0x0607, "1394 DV Stream" },
- { 0x0700, "Embedded" },
- { 0x0701, "Noise Source" },
- { 0x0702, "Equalization Noise" },
- { 0x0703, "CD" },
- { 0x0704, "DAT" },
- { 0x0705, "DCC" },
- { 0x0706, "MiniDisk" },
- { 0x0707, "Analog Tape" },
- { 0x0708, "Phonograph" },
- { 0x0709, "VCR Audio" },
- { 0x070a, "Video Disk Audio" },
- { 0x070b, "DVD Audio" },
- { 0x070c, "TV Tuner Audio" },
- { 0x070d, "Satellite Rec Audio" },
- { 0x070e, "Cable Tuner Audio" },
- { 0x070f, "DSS Audio" },
- { 0x0710, "Radio Receiver" },
- { 0x0711, "Radio Transmitter" },
- { 0x0712, "Multi-Track Recorder" },
- { 0x0713, "Synthesizer" },
- { 0 },
-};
-
-static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm,
- unsigned char *name, int maxlen, int term_only)
-{
- struct iterm_name_combo *names;
-
- if (iterm->name)
- return snd_usb_copy_string_desc(state, iterm->name, name, maxlen);
-
- /* virtual type - not a real terminal */
- if (iterm->type >> 16) {
- if (term_only)
- return 0;
- switch (iterm->type >> 16) {
- case UAC_SELECTOR_UNIT:
- strcpy(name, "Selector"); return 8;
- case UAC1_PROCESSING_UNIT:
- strcpy(name, "Process Unit"); return 12;
- case UAC1_EXTENSION_UNIT:
- strcpy(name, "Ext Unit"); return 8;
- case UAC_MIXER_UNIT:
- strcpy(name, "Mixer"); return 5;
- default:
- return sprintf(name, "Unit %d", iterm->id);
- }
- }
-
- switch (iterm->type & 0xff00) {
- case 0x0100:
- strcpy(name, "PCM"); return 3;
- case 0x0200:
- strcpy(name, "Mic"); return 3;
- case 0x0400:
- strcpy(name, "Headset"); return 7;
- case 0x0500:
- strcpy(name, "Phone"); return 5;
- }
-
- for (names = iterm_names; names->type; names++)
- if (names->type == iterm->type) {
- strcpy(name, names->name);
- return strlen(names->name);
- }
- return 0;
-}
-
-
-/*
- * parse the source unit recursively until it reaches to a terminal
- * or a branched unit.
- */
-static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
-{
- int err;
- void *p1;
-
- memset(term, 0, sizeof(*term));
- while ((p1 = find_audio_control_unit(state, id)) != NULL) {
- unsigned char *hdr = p1;
- term->id = id;
- switch (hdr[2]) {
- case UAC_INPUT_TERMINAL:
- if (state->mixer->protocol == UAC_VERSION_1) {
- struct uac_input_terminal_descriptor *d = p1;
- term->type = le16_to_cpu(d->wTerminalType);
- term->channels = d->bNrChannels;
- term->chconfig = le16_to_cpu(d->wChannelConfig);
- term->name = d->iTerminal;
- } else { /* UAC_VERSION_2 */
- struct uac2_input_terminal_descriptor *d = p1;
- term->type = le16_to_cpu(d->wTerminalType);
- term->channels = d->bNrChannels;
- term->chconfig = le32_to_cpu(d->bmChannelConfig);
- term->name = d->iTerminal;
-
- /* call recursively to get the clock selectors */
- err = check_input_term(state, d->bCSourceID, term);
- if (err < 0)
- return err;
- }
- return 0;
- case UAC_FEATURE_UNIT: {
- /* the header is the same for v1 and v2 */
- struct uac_feature_unit_descriptor *d = p1;
- id = d->bSourceID;
- break; /* continue to parse */
- }
- case UAC_MIXER_UNIT: {
- struct uac_mixer_unit_descriptor *d = p1;
- term->type = d->bDescriptorSubtype << 16; /* virtual type */
- term->channels = uac_mixer_unit_bNrChannels(d);
- term->chconfig = uac_mixer_unit_wChannelConfig(d, state->mixer->protocol);
- term->name = uac_mixer_unit_iMixer(d);
- return 0;
- }
- case UAC_SELECTOR_UNIT:
- case UAC2_CLOCK_SELECTOR: {
- struct uac_selector_unit_descriptor *d = p1;
- /* call recursively to retrieve the channel info */
- if (check_input_term(state, d->baSourceID[0], term) < 0)
- return -ENODEV;
- term->type = d->bDescriptorSubtype << 16; /* virtual type */
- term->id = id;
- term->name = uac_selector_unit_iSelector(d);
- return 0;
- }
- case UAC1_PROCESSING_UNIT:
- case UAC1_EXTENSION_UNIT: {
- struct uac_processing_unit_descriptor *d = p1;
- if (d->bNrInPins) {
- id = d->baSourceID[0];
- break; /* continue to parse */
- }
- term->type = d->bDescriptorSubtype << 16; /* virtual type */
- term->channels = uac_processing_unit_bNrChannels(d);
- term->chconfig = uac_processing_unit_wChannelConfig(d, state->mixer->protocol);
- term->name = uac_processing_unit_iProcessing(d, state->mixer->protocol);
- return 0;
- }
- case UAC2_CLOCK_SOURCE: {
- struct uac_clock_source_descriptor *d = p1;
- term->type = d->bDescriptorSubtype << 16; /* virtual type */
- term->id = id;
- term->name = d->iClockSource;
- return 0;
- }
- default:
- return -ENODEV;
- }
- }
- return -ENODEV;
-}
-
-
-/*
- * Feature Unit
- */
-
-/* feature unit control information */
-struct usb_feature_control_info {
- const char *name;
- unsigned int type; /* control type (mute, volume, etc.) */
-};
-
-static struct usb_feature_control_info audio_feature_info[] = {
- { "Mute", USB_MIXER_INV_BOOLEAN },
- { "Volume", USB_MIXER_S16 },
- { "Tone Control - Bass", USB_MIXER_S8 },
- { "Tone Control - Mid", USB_MIXER_S8 },
- { "Tone Control - Treble", USB_MIXER_S8 },
- { "Graphic Equalizer", USB_MIXER_S8 }, /* FIXME: not implemeted yet */
- { "Auto Gain Control", USB_MIXER_BOOLEAN },
- { "Delay Control", USB_MIXER_U16 },
- { "Bass Boost", USB_MIXER_BOOLEAN },
- { "Loudness", USB_MIXER_BOOLEAN },
- /* UAC2 specific */
- { "Input Gain Control", USB_MIXER_U16 },
- { "Input Gain Pad Control", USB_MIXER_BOOLEAN },
- { "Phase Inverter Control", USB_MIXER_BOOLEAN },
-};
-
-
-/* private_free callback */
-static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
-{
- kfree(kctl->private_data);
- kctl->private_data = NULL;
-}
-
-
-/*
- * interface to ALSA control for feature/mixer units
- */
-
-/* volume control quirks */
-static void volume_control_quirks(struct usb_mixer_elem_info *cval,
- struct snd_kcontrol *kctl)
-{
- switch (cval->mixer->chip->usb_id) {
- case USB_ID(0x0471, 0x0101):
- case USB_ID(0x0471, 0x0104):
- case USB_ID(0x0471, 0x0105):
- case USB_ID(0x0672, 0x1041):
- /* quirk for UDA1321/N101.
- * note that detection between firmware 2.1.1.7 (N101)
- * and later 2.1.1.21 is not very clear from datasheets.
- * I hope that the min value is -15360 for newer firmware --jk
- */
- if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
- cval->min == -15616) {
- snd_printk(KERN_INFO
- "set volume quirk for UDA1321/N101 chip\n");
- cval->max = -256;
- }
- break;
-
- case USB_ID(0x046d, 0x09a4):
- if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
- snd_printk(KERN_INFO
- "set volume quirk for QuickCam E3500\n");
- cval->min = 6080;
- cval->max = 8768;
- cval->res = 192;
- }
- break;
-
- case USB_ID(0x046d, 0x0808):
- case USB_ID(0x046d, 0x0809):
- case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */
- case USB_ID(0x046d, 0x0991):
- /* Most audio usb devices lie about volume resolution.
- * Most Logitech webcams have res = 384.
- * Proboly there is some logitech magic behind this number --fishor
- */
- if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
- snd_printk(KERN_INFO
- "set resolution quirk: cval->res = 384\n");
- cval->res = 384;
- }
- break;
-
- }
-}
-
-/*
- * retrieve the minimum and maximum values for the specified control
- */
-static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
- int default_min, struct snd_kcontrol *kctl)
-{
- /* for failsafe */
- cval->min = default_min;
- cval->max = cval->min + 1;
- cval->res = 1;
- cval->dBmin = cval->dBmax = 0;
-
- if (cval->val_type == USB_MIXER_BOOLEAN ||
- cval->val_type == USB_MIXER_INV_BOOLEAN) {
- cval->initialized = 1;
- } else {
- int minchn = 0;
- if (cval->cmask) {
- int i;
- for (i = 0; i < MAX_CHANNELS; i++)
- if (cval->cmask & (1 << i)) {
- minchn = i + 1;
- break;
- }
- }
- if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
- get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
- snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
- cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id);
- return -EINVAL;
- }
- if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
- cval->res = 1;
- } else {
- int last_valid_res = cval->res;
-
- while (cval->res > 1) {
- if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES,
- (cval->control << 8) | minchn, cval->res / 2) < 0)
- break;
- cval->res /= 2;
- }
- if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0)
- cval->res = last_valid_res;
- }
- if (cval->res == 0)
- cval->res = 1;
-
- /* Additional checks for the proper resolution
- *
- * Some devices report smaller resolutions than actually
- * reacting. They don't return errors but simply clip
- * to the lower aligned value.
- */
- if (cval->min + cval->res < cval->max) {
- int last_valid_res = cval->res;
- int saved, test, check;
- get_cur_mix_raw(cval, minchn, &saved);
- for (;;) {
- test = saved;
- if (test < cval->max)
- test += cval->res;
- else
- test -= cval->res;
- if (test < cval->min || test > cval->max ||
- set_cur_mix_value(cval, minchn, 0, test) ||
- get_cur_mix_raw(cval, minchn, &check)) {
- cval->res = last_valid_res;
- break;
- }
- if (test == check)
- break;
- cval->res *= 2;
- }
- set_cur_mix_value(cval, minchn, 0, saved);
- }
-
- cval->initialized = 1;
- }
-
- if (kctl)
- volume_control_quirks(cval, kctl);
-
- /* USB descriptions contain the dB scale in 1/256 dB unit
- * while ALSA TLV contains in 1/100 dB unit
- */
- cval->dBmin = (convert_signed_value(cval, cval->min) * 100) / 256;
- cval->dBmax = (convert_signed_value(cval, cval->max) * 100) / 256;
- if (cval->dBmin > cval->dBmax) {
- /* something is wrong; assume it's either from/to 0dB */
- if (cval->dBmin < 0)
- cval->dBmax = 0;
- else if (cval->dBmin > 0)
- cval->dBmin = 0;
- if (cval->dBmin > cval->dBmax) {
- /* totally crap, return an error */
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)
-
-/* get a feature/mixer unit info */
-static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
-
- if (cval->val_type == USB_MIXER_BOOLEAN ||
- cval->val_type == USB_MIXER_INV_BOOLEAN)
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- else
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = cval->channels;
- if (cval->val_type == USB_MIXER_BOOLEAN ||
- cval->val_type == USB_MIXER_INV_BOOLEAN) {
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- } else {
- if (!cval->initialized) {
- get_min_max_with_quirks(cval, 0, kcontrol);
- if (cval->initialized && cval->dBmin >= cval->dBmax) {
- kcontrol->vd[0].access &=
- ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
- snd_ctl_notify(cval->mixer->chip->card,
- SNDRV_CTL_EVENT_MASK_INFO,
- &kcontrol->id);
- }
- }
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max =
- (cval->max - cval->min + cval->res - 1) / cval->res;
- }
- return 0;
-}
-
-/* get the current value from feature/mixer unit */
-static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int c, cnt, val, err;
-
- ucontrol->value.integer.value[0] = cval->min;
- if (cval->cmask) {
- cnt = 0;
- for (c = 0; c < MAX_CHANNELS; c++) {
- if (!(cval->cmask & (1 << c)))
- continue;
- err = get_cur_mix_value(cval, c + 1, cnt, &val);
- if (err < 0)
- return cval->mixer->ignore_ctl_error ? 0 : err;
- val = get_relative_value(cval, val);
- ucontrol->value.integer.value[cnt] = val;
- cnt++;
- }
- return 0;
- } else {
- /* master channel */
- err = get_cur_mix_value(cval, 0, 0, &val);
- if (err < 0)
- return cval->mixer->ignore_ctl_error ? 0 : err;
- val = get_relative_value(cval, val);
- ucontrol->value.integer.value[0] = val;
- }
- return 0;
-}
-
-/* put the current value to feature/mixer unit */
-static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int c, cnt, val, oval, err;
- int changed = 0;
-
- if (cval->cmask) {
- cnt = 0;
- for (c = 0; c < MAX_CHANNELS; c++) {
- if (!(cval->cmask & (1 << c)))
- continue;
- err = get_cur_mix_value(cval, c + 1, cnt, &oval);
- if (err < 0)
- return cval->mixer->ignore_ctl_error ? 0 : err;
- val = ucontrol->value.integer.value[cnt];
- val = get_abs_value(cval, val);
- if (oval != val) {
- set_cur_mix_value(cval, c + 1, cnt, val);
- changed = 1;
- }
- cnt++;
- }
- } else {
- /* master channel */
- err = get_cur_mix_value(cval, 0, 0, &oval);
- if (err < 0)
- return cval->mixer->ignore_ctl_error ? 0 : err;
- val = ucontrol->value.integer.value[0];
- val = get_abs_value(cval, val);
- if (val != oval) {
- set_cur_mix_value(cval, 0, 0, val);
- changed = 1;
- }
- }
- return changed;
-}
-
-static struct snd_kcontrol_new usb_feature_unit_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "", /* will be filled later manually */
- .info = mixer_ctl_feature_info,
- .get = mixer_ctl_feature_get,
- .put = mixer_ctl_feature_put,
-};
-
-/* the read-only variant */
-static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "", /* will be filled later manually */
- .info = mixer_ctl_feature_info,
- .get = mixer_ctl_feature_get,
- .put = NULL,
-};
-
-/* This symbol is exported in order to allow the mixer quirks to
- * hook up to the standard feature unit control mechanism */
-struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl;
-
-/*
- * build a feature control
- */
-
-static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
-{
- return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
-}
-
-static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
- unsigned int ctl_mask, int control,
- struct usb_audio_term *iterm, int unitid,
- int readonly_mask)
-{
- struct uac_feature_unit_descriptor *desc = raw_desc;
- unsigned int len = 0;
- int mapped_name = 0;
- int nameid = uac_feature_unit_iFeature(desc);
- struct snd_kcontrol *kctl;
- struct usb_mixer_elem_info *cval;
- const struct usbmix_name_map *map;
- unsigned int range;
-
- control++; /* change from zero-based to 1-based value */
-
- if (control == UAC_FU_GRAPHIC_EQUALIZER) {
- /* FIXME: not supported yet */
- return;
- }
-
- map = find_map(state, unitid, control);
- if (check_ignored_ctl(map))
- return;
-
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- return;
- }
- cval->mixer = state->mixer;
- cval->id = unitid;
- cval->control = control;
- cval->cmask = ctl_mask;
- cval->val_type = audio_feature_info[control-1].type;
- if (ctl_mask == 0) {
- cval->channels = 1; /* master channel */
- cval->master_readonly = readonly_mask;
- } else {
- int i, c = 0;
- for (i = 0; i < 16; i++)
- if (ctl_mask & (1 << i))
- c++;
- cval->channels = c;
- cval->ch_readonly = readonly_mask;
- }
-
- /* if all channels in the mask are marked read-only, make the control
- * read-only. set_cur_mix_value() will check the mask again and won't
- * issue write commands to read-only channels. */
- if (cval->channels == readonly_mask)
- kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
- else
- kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
-
- if (! kctl) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- kfree(cval);
- return;
- }
- kctl->private_free = usb_mixer_elem_free;
-
- len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
- mapped_name = len != 0;
- if (! len && nameid)
- len = snd_usb_copy_string_desc(state, nameid,
- kctl->id.name, sizeof(kctl->id.name));
-
- /* get min/max values */
- get_min_max_with_quirks(cval, 0, kctl);
-
- switch (control) {
- case UAC_FU_MUTE:
- case UAC_FU_VOLUME:
- /* determine the control name. the rule is:
- * - if a name id is given in descriptor, use it.
- * - if the connected input can be determined, then use the name
- * of terminal type.
- * - if the connected output can be determined, use it.
- * - otherwise, anonymous name.
- */
- if (! len) {
- len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 1);
- if (! len)
- len = get_term_name(state, &state->oterm, kctl->id.name, sizeof(kctl->id.name), 1);
- if (! len)
- len = snprintf(kctl->id.name, sizeof(kctl->id.name),
- "Feature %d", unitid);
- }
- /* determine the stream direction:
- * if the connected output is USB stream, then it's likely a
- * capture stream. otherwise it should be playback (hopefully :)
- */
- if (! mapped_name && ! (state->oterm.type >> 16)) {
- if ((state->oterm.type & 0xff00) == 0x0100) {
- len = append_ctl_name(kctl, " Capture");
- } else {
- len = append_ctl_name(kctl, " Playback");
- }
- }
- append_ctl_name(kctl, control == UAC_FU_MUTE ?
- " Switch" : " Volume");
- if (control == UAC_FU_VOLUME) {
- check_mapped_dB(map, cval);
- if (cval->dBmin < cval->dBmax || !cval->initialized) {
- kctl->tlv.c = mixer_vol_tlv;
- kctl->vd[0].access |=
- SNDRV_CTL_ELEM_ACCESS_TLV_READ |
- SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
- }
- }
- break;
-
- default:
- if (! len)
- strlcpy(kctl->id.name, audio_feature_info[control-1].name,
- sizeof(kctl->id.name));
- break;
- }
-
- range = (cval->max - cval->min) / cval->res;
- /* Are there devices with volume range more than 255? I use a bit more
- * to be sure. 384 is a resolution magic number found on Logitech
- * devices. It will definitively catch all buggy Logitech devices.
- */
- if (range > 384) {
- snd_printk(KERN_WARNING "usb_audio: Warning! Unlikely big "
- "volume range (=%u), cval->res is probably wrong.",
- range);
- snd_printk(KERN_WARNING "usb_audio: [%d] FU [%s] ch = %d, "
- "val = %d/%d/%d", cval->id,
- kctl->id.name, cval->channels,
- cval->min, cval->max, cval->res);
- }
-
- snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
- snd_usb_mixer_add_control(state->mixer, kctl);
-}
-
-
-
-/*
- * parse a feature unit
- *
- * most of controls are defined here.
- */
-static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr)
-{
- int channels, i, j;
- struct usb_audio_term iterm;
- unsigned int master_bits, first_ch_bits;
- int err, csize;
- struct uac_feature_unit_descriptor *hdr = _ftr;
- __u8 *bmaControls;
-
- if (state->mixer->protocol == UAC_VERSION_1) {
- csize = hdr->bControlSize;
- if (!csize) {
- snd_printdd(KERN_ERR "usbaudio: unit %u: "
- "invalid bControlSize == 0\n", unitid);
- return -EINVAL;
- }
- channels = (hdr->bLength - 7) / csize - 1;
- bmaControls = hdr->bmaControls;
- } else {
- struct uac2_feature_unit_descriptor *ftr = _ftr;
- csize = 4;
- channels = (hdr->bLength - 6) / 4 - 1;
- bmaControls = ftr->bmaControls;
- }
-
- if (hdr->bLength < 7 || !csize || hdr->bLength < 7 + csize) {
- snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid);
- return -EINVAL;
- }
-
- /* parse the source unit */
- if ((err = parse_audio_unit(state, hdr->bSourceID)) < 0)
- return err;
-
- /* determine the input source type and name */
- if (check_input_term(state, hdr->bSourceID, &iterm) < 0)
- return -EINVAL;
-
- master_bits = snd_usb_combine_bytes(bmaControls, csize);
- /* master configuration quirks */
- switch (state->chip->usb_id) {
- case USB_ID(0x08bb, 0x2702):
- snd_printk(KERN_INFO
- "usbmixer: master volume quirk for PCM2702 chip\n");
- /* disable non-functional volume control */
- master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);
- break;
- }
- if (channels > 0)
- first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
- else
- first_ch_bits = 0;
-
- if (state->mixer->protocol == UAC_VERSION_1) {
- /* check all control types */
- for (i = 0; i < 10; i++) {
- unsigned int ch_bits = 0;
- for (j = 0; j < channels; j++) {
- unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
- if (mask & (1 << i))
- ch_bits |= (1 << j);
- }
- /* audio class v1 controls are never read-only */
- if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
- build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0);
- if (master_bits & (1 << i))
- build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0);
- }
- } else { /* UAC_VERSION_2 */
- for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) {
- unsigned int ch_bits = 0;
- unsigned int ch_read_only = 0;
-
- for (j = 0; j < channels; j++) {
- unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize);
- if (uac2_control_is_readable(mask, i)) {
- ch_bits |= (1 << j);
- if (!uac2_control_is_writeable(mask, i))
- ch_read_only |= (1 << j);
- }
- }
-
- /* NOTE: build_feature_ctl() will mark the control read-only if all channels
- * are marked read-only in the descriptors. Otherwise, the control will be
- * reported as writeable, but the driver will not actually issue a write
- * command for read-only channels */
- if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
- build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only);
- if (uac2_control_is_readable(master_bits, i))
- build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
- !uac2_control_is_writeable(master_bits, i));
- }
- }
-
- return 0;
-}
-
-
-/*
- * Mixer Unit
- */
-
-/*
- * build a mixer unit control
- *
- * the callbacks are identical with feature unit.
- * input channel number (zero based) is given in control field instead.
- */
-
-static void build_mixer_unit_ctl(struct mixer_build *state,
- struct uac_mixer_unit_descriptor *desc,
- int in_pin, int in_ch, int unitid,
- struct usb_audio_term *iterm)
-{
- struct usb_mixer_elem_info *cval;
- unsigned int num_outs = uac_mixer_unit_bNrChannels(desc);
- unsigned int i, len;
- struct snd_kcontrol *kctl;
- const struct usbmix_name_map *map;
-
- map = find_map(state, unitid, 0);
- if (check_ignored_ctl(map))
- return;
-
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval)
- return;
-
- cval->mixer = state->mixer;
- cval->id = unitid;
- cval->control = in_ch + 1; /* based on 1 */
- cval->val_type = USB_MIXER_S16;
- for (i = 0; i < num_outs; i++) {
- if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) {
- cval->cmask |= (1 << i);
- cval->channels++;
- }
- }
-
- /* get min/max values */
- get_min_max(cval, 0);
-
- kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
- if (! kctl) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- kfree(cval);
- return;
- }
- kctl->private_free = usb_mixer_elem_free;
-
- len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
- if (! len)
- len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
- if (! len)
- len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
- append_ctl_name(kctl, " Volume");
-
- snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
- snd_usb_mixer_add_control(state->mixer, kctl);
-}
-
-
-/*
- * parse a mixer unit
- */
-static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc)
-{
- struct uac_mixer_unit_descriptor *desc = raw_desc;
- struct usb_audio_term iterm;
- int input_pins, num_ins, num_outs;
- int pin, ich, err;
-
- if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) {
- snd_printk(KERN_ERR "invalid MIXER UNIT descriptor %d\n", unitid);
- return -EINVAL;
- }
- /* no bmControls field (e.g. Maya44) -> ignore */
- if (desc->bLength <= 10 + input_pins) {
- snd_printdd(KERN_INFO "MU %d has no bmControls field\n", unitid);
- return 0;
- }
-
- num_ins = 0;
- ich = 0;
- for (pin = 0; pin < input_pins; pin++) {
- err = parse_audio_unit(state, desc->baSourceID[pin]);
- if (err < 0)
- return err;
- err = check_input_term(state, desc->baSourceID[pin], &iterm);
- if (err < 0)
- return err;
- num_ins += iterm.channels;
- for (; ich < num_ins; ++ich) {
- int och, ich_has_controls = 0;
-
- for (och = 0; och < num_outs; ++och) {
- if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol),
- ich, och, num_outs)) {
- ich_has_controls = 1;
- break;
- }
- }
- if (ich_has_controls)
- build_mixer_unit_ctl(state, desc, pin, ich,
- unitid, &iterm);
- }
- }
- return 0;
-}
-
-
-/*
- * Processing Unit / Extension Unit
- */
-
-/* get callback for processing/extension unit */
-static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int err, val;
-
- err = get_cur_ctl_value(cval, cval->control << 8, &val);
- if (err < 0 && cval->mixer->ignore_ctl_error) {
- ucontrol->value.integer.value[0] = cval->min;
- return 0;
- }
- if (err < 0)
- return err;
- val = get_relative_value(cval, val);
- ucontrol->value.integer.value[0] = val;
- return 0;
-}
-
-/* put callback for processing/extension unit */
-static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int val, oval, err;
-
- err = get_cur_ctl_value(cval, cval->control << 8, &oval);
- if (err < 0) {
- if (cval->mixer->ignore_ctl_error)
- return 0;
- return err;
- }
- val = ucontrol->value.integer.value[0];
- val = get_abs_value(cval, val);
- if (val != oval) {
- set_cur_ctl_value(cval, cval->control << 8, val);
- return 1;
- }
- return 0;
-}
-
-/* alsa control interface for processing/extension unit */
-static struct snd_kcontrol_new mixer_procunit_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "", /* will be filled later */
- .info = mixer_ctl_feature_info,
- .get = mixer_ctl_procunit_get,
- .put = mixer_ctl_procunit_put,
-};
-
-
-/*
- * predefined data for processing units
- */
-struct procunit_value_info {
- int control;
- char *suffix;
- int val_type;
- int min_value;
-};
-
-struct procunit_info {
- int type;
- char *name;
- struct procunit_value_info *values;
-};
-
-static struct procunit_value_info updown_proc_info[] = {
- { UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
- { 0 }
-};
-static struct procunit_value_info prologic_proc_info[] = {
- { UAC_DP_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_DP_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
- { 0 }
-};
-static struct procunit_value_info threed_enh_proc_info[] = {
- { UAC_3D_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_3D_SPACE, "Spaciousness", USB_MIXER_U8 },
- { 0 }
-};
-static struct procunit_value_info reverb_proc_info[] = {
- { UAC_REVERB_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_REVERB_LEVEL, "Level", USB_MIXER_U8 },
- { UAC_REVERB_TIME, "Time", USB_MIXER_U16 },
- { UAC_REVERB_FEEDBACK, "Feedback", USB_MIXER_U8 },
- { 0 }
-};
-static struct procunit_value_info chorus_proc_info[] = {
- { UAC_CHORUS_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_CHORUS_LEVEL, "Level", USB_MIXER_U8 },
- { UAC_CHORUS_RATE, "Rate", USB_MIXER_U16 },
- { UAC_CHORUS_DEPTH, "Depth", USB_MIXER_U16 },
- { 0 }
-};
-static struct procunit_value_info dcr_proc_info[] = {
- { UAC_DCR_ENABLE, "Switch", USB_MIXER_BOOLEAN },
- { UAC_DCR_RATE, "Ratio", USB_MIXER_U16 },
- { UAC_DCR_MAXAMPL, "Max Amp", USB_MIXER_S16 },
- { UAC_DCR_THRESHOLD, "Threshold", USB_MIXER_S16 },
- { UAC_DCR_ATTACK_TIME, "Attack Time", USB_MIXER_U16 },
- { UAC_DCR_RELEASE_TIME, "Release Time", USB_MIXER_U16 },
- { 0 }
-};
-
-static struct procunit_info procunits[] = {
- { UAC_PROCESS_UP_DOWNMIX, "Up Down", updown_proc_info },
- { UAC_PROCESS_DOLBY_PROLOGIC, "Dolby Prologic", prologic_proc_info },
- { UAC_PROCESS_STEREO_EXTENDER, "3D Stereo Extender", threed_enh_proc_info },
- { UAC_PROCESS_REVERB, "Reverb", reverb_proc_info },
- { UAC_PROCESS_CHORUS, "Chorus", chorus_proc_info },
- { UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info },
- { 0 },
-};
-/*
- * predefined data for extension units
- */
-static struct procunit_value_info clock_rate_xu_info[] = {
- { USB_XU_CLOCK_RATE_SELECTOR, "Selector", USB_MIXER_U8, 0 },
- { 0 }
-};
-static struct procunit_value_info clock_source_xu_info[] = {
- { USB_XU_CLOCK_SOURCE_SELECTOR, "External", USB_MIXER_BOOLEAN },
- { 0 }
-};
-static struct procunit_value_info spdif_format_xu_info[] = {
- { USB_XU_DIGITAL_FORMAT_SELECTOR, "SPDIF/AC3", USB_MIXER_BOOLEAN },
- { 0 }
-};
-static struct procunit_value_info soft_limit_xu_info[] = {
- { USB_XU_SOFT_LIMIT_SELECTOR, " ", USB_MIXER_BOOLEAN },
- { 0 }
-};
-static struct procunit_info extunits[] = {
- { USB_XU_CLOCK_RATE, "Clock rate", clock_rate_xu_info },
- { USB_XU_CLOCK_SOURCE, "DigitalIn CLK source", clock_source_xu_info },
- { USB_XU_DIGITAL_IO_STATUS, "DigitalOut format:", spdif_format_xu_info },
- { USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info },
- { 0 }
-};
-/*
- * build a processing/extension unit
- */
-static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name)
-{
- struct uac_processing_unit_descriptor *desc = raw_desc;
- int num_ins = desc->bNrInPins;
- struct usb_mixer_elem_info *cval;
- struct snd_kcontrol *kctl;
- int i, err, nameid, type, len;
- struct procunit_info *info;
- struct procunit_value_info *valinfo;
- const struct usbmix_name_map *map;
- static struct procunit_value_info default_value_info[] = {
- { 0x01, "Switch", USB_MIXER_BOOLEAN },
- { 0 }
- };
- static struct procunit_info default_info = {
- 0, NULL, default_value_info
- };
-
- if (desc->bLength < 13 || desc->bLength < 13 + num_ins ||
- desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) {
- snd_printk(KERN_ERR "invalid %s descriptor (id %d)\n", name, unitid);
- return -EINVAL;
- }
-
- for (i = 0; i < num_ins; i++) {
- if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
- return err;
- }
-
- type = le16_to_cpu(desc->wProcessType);
- for (info = list; info && info->type; info++)
- if (info->type == type)
- break;
- if (! info || ! info->type)
- info = &default_info;
-
- for (valinfo = info->values; valinfo->control; valinfo++) {
- __u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol);
-
- if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1))))
- continue;
- map = find_map(state, unitid, valinfo->control);
- if (check_ignored_ctl(map))
- continue;
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- return -ENOMEM;
- }
- cval->mixer = state->mixer;
- cval->id = unitid;
- cval->control = valinfo->control;
- cval->val_type = valinfo->val_type;
- cval->channels = 1;
-
- /* get min/max values */
- if (type == UAC_PROCESS_UP_DOWNMIX && cval->control == UAC_UD_MODE_SELECT) {
- __u8 *control_spec = uac_processing_unit_specific(desc, state->mixer->protocol);
- /* FIXME: hard-coded */
- cval->min = 1;
- cval->max = control_spec[0];
- cval->res = 1;
- cval->initialized = 1;
- } else {
- if (type == USB_XU_CLOCK_RATE) {
- /* E-Mu USB 0404/0202/TrackerPre/0204
- * samplerate control quirk
- */
- cval->min = 0;
- cval->max = 5;
- cval->res = 1;
- cval->initialized = 1;
- } else
- get_min_max(cval, valinfo->min_value);
- }
-
- kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
- if (! kctl) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- kfree(cval);
- return -ENOMEM;
- }
- kctl->private_free = usb_mixer_elem_free;
-
- if (check_mapped_name(map, kctl->id.name,
- sizeof(kctl->id.name)))
- /* nothing */ ;
- else if (info->name)
- strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name));
- else {
- nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol);
- len = 0;
- if (nameid)
- len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
- if (! len)
- strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
- }
- append_ctl_name(kctl, " ");
- append_ctl_name(kctl, valinfo->suffix);
-
- snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
- cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
- if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)
- return err;
- }
- return 0;
-}
-
-
-static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc)
-{
- return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit");
-}
-
-static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc)
-{
- /* Note that we parse extension units with processing unit descriptors.
- * That's ok as the layout is the same */
- return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit");
-}
-
-
-/*
- * Selector Unit
- */
-
-/* info callback for selector unit
- * use an enumerator type for routing
- */
-static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- const char **itemlist = (const char **)kcontrol->private_value;
-
- if (snd_BUG_ON(!itemlist))
- return -EINVAL;
- return snd_ctl_enum_info(uinfo, 1, cval->max, itemlist);
-}
-
-/* get callback for selector unit */
-static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int val, err;
-
- err = get_cur_ctl_value(cval, cval->control << 8, &val);
- if (err < 0) {
- if (cval->mixer->ignore_ctl_error) {
- ucontrol->value.enumerated.item[0] = 0;
- return 0;
- }
- return err;
- }
- val = get_relative_value(cval, val);
- ucontrol->value.enumerated.item[0] = val;
- return 0;
-}
-
-/* put callback for selector unit */
-static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *cval = kcontrol->private_data;
- int val, oval, err;
-
- err = get_cur_ctl_value(cval, cval->control << 8, &oval);
- if (err < 0) {
- if (cval->mixer->ignore_ctl_error)
- return 0;
- return err;
- }
- val = ucontrol->value.enumerated.item[0];
- val = get_abs_value(cval, val);
- if (val != oval) {
- set_cur_ctl_value(cval, cval->control << 8, val);
- return 1;
- }
- return 0;
-}
-
-/* alsa control interface for selector unit */
-static struct snd_kcontrol_new mixer_selectunit_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "", /* will be filled later */
- .info = mixer_ctl_selector_info,
- .get = mixer_ctl_selector_get,
- .put = mixer_ctl_selector_put,
-};
-
-
-/* private free callback.
- * free both private_data and private_value
- */
-static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
-{
- int i, num_ins = 0;
-
- if (kctl->private_data) {
- struct usb_mixer_elem_info *cval = kctl->private_data;
- num_ins = cval->max;
- kfree(cval);
- kctl->private_data = NULL;
- }
- if (kctl->private_value) {
- char **itemlist = (char **)kctl->private_value;
- for (i = 0; i < num_ins; i++)
- kfree(itemlist[i]);
- kfree(itemlist);
- kctl->private_value = 0;
- }
-}
-
-/*
- * parse a selector unit
- */
-static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc)
-{
- struct uac_selector_unit_descriptor *desc = raw_desc;
- unsigned int i, nameid, len;
- int err;
- struct usb_mixer_elem_info *cval;
- struct snd_kcontrol *kctl;
- const struct usbmix_name_map *map;
- char **namelist;
-
- if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
- snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
- return -EINVAL;
- }
-
- for (i = 0; i < desc->bNrInPins; i++) {
- if ((err = parse_audio_unit(state, desc->baSourceID[i])) < 0)
- return err;
- }
-
- if (desc->bNrInPins == 1) /* only one ? nonsense! */
- return 0;
-
- map = find_map(state, unitid, 0);
- if (check_ignored_ctl(map))
- return 0;
-
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (! cval) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- return -ENOMEM;
- }
- cval->mixer = state->mixer;
- cval->id = unitid;
- cval->val_type = USB_MIXER_U8;
- cval->channels = 1;
- cval->min = 1;
- cval->max = desc->bNrInPins;
- cval->res = 1;
- cval->initialized = 1;
-
- if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
- cval->control = UAC2_CX_CLOCK_SELECTOR;
- else
- cval->control = 0;
-
- namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL);
- if (! namelist) {
- snd_printk(KERN_ERR "cannot malloc\n");
- kfree(cval);
- return -ENOMEM;
- }
-#define MAX_ITEM_NAME_LEN 64
- for (i = 0; i < desc->bNrInPins; i++) {
- struct usb_audio_term iterm;
- len = 0;
- namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
- if (! namelist[i]) {
- snd_printk(KERN_ERR "cannot malloc\n");
- while (i--)
- kfree(namelist[i]);
- kfree(namelist);
- kfree(cval);
- return -ENOMEM;
- }
- len = check_mapped_selector_name(state, unitid, i, namelist[i],
- MAX_ITEM_NAME_LEN);
- if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0)
- len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
- if (! len)
- sprintf(namelist[i], "Input %d", i);
- }
-
- kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
- if (! kctl) {
- snd_printk(KERN_ERR "cannot malloc kcontrol\n");
- kfree(namelist);
- kfree(cval);
- return -ENOMEM;
- }
- kctl->private_value = (unsigned long)namelist;
- kctl->private_free = usb_mixer_selector_elem_free;
-
- nameid = uac_selector_unit_iSelector(desc);
- len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
- if (len)
- ;
- else if (nameid)
- snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name));
- else {
- len = get_term_name(state, &state->oterm,
- kctl->id.name, sizeof(kctl->id.name), 0);
- if (! len)
- strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
-
- if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR)
- append_ctl_name(kctl, " Clock Source");
- else if ((state->oterm.type & 0xff00) == 0x0100)
- append_ctl_name(kctl, " Capture Source");
- else
- append_ctl_name(kctl, " Playback Source");
- }
-
- snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
- cval->id, kctl->id.name, desc->bNrInPins);
- if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * parse an audio unit recursively
- */
-
-static int parse_audio_unit(struct mixer_build *state, int unitid)
-{
- unsigned char *p1;
-
- if (test_and_set_bit(unitid, state->unitbitmap))
- return 0; /* the unit already visited */
-
- p1 = find_audio_control_unit(state, unitid);
- if (!p1) {
- snd_printk(KERN_ERR "usbaudio: unit %d not found!\n", unitid);
- return -EINVAL;
- }
-
- switch (p1[2]) {
- case UAC_INPUT_TERMINAL:
- case UAC2_CLOCK_SOURCE:
- return 0; /* NOP */
- case UAC_MIXER_UNIT:
- return parse_audio_mixer_unit(state, unitid, p1);
- case UAC_SELECTOR_UNIT:
- case UAC2_CLOCK_SELECTOR:
- return parse_audio_selector_unit(state, unitid, p1);
- case UAC_FEATURE_UNIT:
- return parse_audio_feature_unit(state, unitid, p1);
- case UAC1_PROCESSING_UNIT:
- /* UAC2_EFFECT_UNIT has the same value */
- if (state->mixer->protocol == UAC_VERSION_1)
- return parse_audio_processing_unit(state, unitid, p1);
- else
- return 0; /* FIXME - effect units not implemented yet */
- case UAC1_EXTENSION_UNIT:
- /* UAC2_PROCESSING_UNIT_V2 has the same value */
- if (state->mixer->protocol == UAC_VERSION_1)
- return parse_audio_extension_unit(state, unitid, p1);
- else /* UAC_VERSION_2 */
- return parse_audio_processing_unit(state, unitid, p1);
- default:
- snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
- return -EINVAL;
- }
-}
-
-static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
-{
- kfree(mixer->id_elems);
- if (mixer->urb) {
- kfree(mixer->urb->transfer_buffer);
- usb_free_urb(mixer->urb);
- }
- usb_free_urb(mixer->rc_urb);
- kfree(mixer->rc_setup_packet);
- kfree(mixer);
-}
-
-static int snd_usb_mixer_dev_free(struct snd_device *device)
-{
- struct usb_mixer_interface *mixer = device->device_data;
- snd_usb_mixer_free(mixer);
- return 0;
-}
-
-/*
- * create mixer controls
- *
- * walk through all UAC_OUTPUT_TERMINAL descriptors to search for mixers
- */
-static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
-{
- struct mixer_build state;
- int err;
- const struct usbmix_ctl_map *map;
- void *p;
-
- memset(&state, 0, sizeof(state));
- state.chip = mixer->chip;
- state.mixer = mixer;
- state.buffer = mixer->hostif->extra;
- state.buflen = mixer->hostif->extralen;
-
- /* check the mapping table */
- for (map = usbmix_ctl_maps; map->id; map++) {
- if (map->id == state.chip->usb_id) {
- state.map = map->map;
- state.selector_map = map->selector_map;
- mixer->ignore_ctl_error = map->ignore_ctl_error;
- break;
- }
- }
-
- p = NULL;
- while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen,
- p, UAC_OUTPUT_TERMINAL)) != NULL) {
- if (mixer->protocol == UAC_VERSION_1) {
- struct uac1_output_terminal_descriptor *desc = p;
-
- if (desc->bLength < sizeof(*desc))
- continue; /* invalid descriptor? */
- set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
- state.oterm.id = desc->bTerminalID;
- state.oterm.type = le16_to_cpu(desc->wTerminalType);
- state.oterm.name = desc->iTerminal;
- err = parse_audio_unit(&state, desc->bSourceID);
- if (err < 0)
- return err;
- } else { /* UAC_VERSION_2 */
- struct uac2_output_terminal_descriptor *desc = p;
-
- if (desc->bLength < sizeof(*desc))
- continue; /* invalid descriptor? */
- set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */
- state.oterm.id = desc->bTerminalID;
- state.oterm.type = le16_to_cpu(desc->wTerminalType);
- state.oterm.name = desc->iTerminal;
- err = parse_audio_unit(&state, desc->bSourceID);
- if (err < 0)
- return err;
-
- /* for UAC2, use the same approach to also add the clock selectors */
- err = parse_audio_unit(&state, desc->bCSourceID);
- if (err < 0)
- return err;
- }
- }
-
- return 0;
-}
-
-void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
-{
- struct usb_mixer_elem_info *info;
-
- for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem)
- snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- info->elem_id);
-}
-
-static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
- int unitid,
- struct usb_mixer_elem_info *cval)
-{
- static char *val_types[] = {"BOOLEAN", "INV_BOOLEAN",
- "S8", "U8", "S16", "U16"};
- snd_iprintf(buffer, " Unit: %i\n", unitid);
- if (cval->elem_id)
- snd_iprintf(buffer, " Control: name=\"%s\", index=%i\n",
- cval->elem_id->name, cval->elem_id->index);
- snd_iprintf(buffer, " Info: id=%i, control=%i, cmask=0x%x, "
- "channels=%i, type=\"%s\"\n", cval->id,
- cval->control, cval->cmask, cval->channels,
- val_types[cval->val_type]);
- snd_iprintf(buffer, " Volume: min=%i, max=%i, dBmin=%i, dBmax=%i\n",
- cval->min, cval->max, cval->dBmin, cval->dBmax);
-}
-
-static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- struct snd_usb_audio *chip = entry->private_data;
- struct usb_mixer_interface *mixer;
- struct usb_mixer_elem_info *cval;
- int unitid;
-
- list_for_each_entry(mixer, &chip->mixer_list, list) {
- snd_iprintf(buffer,
- "USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
- chip->usb_id, snd_usb_ctrl_intf(chip),
- mixer->ignore_ctl_error);
- snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
- for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
- for (cval = mixer->id_elems[unitid]; cval;
- cval = cval->next_id_elem)
- snd_usb_mixer_dump_cval(buffer, unitid, cval);
- }
- }
-}
-
-static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
- int attribute, int value, int index)
-{
- struct usb_mixer_elem_info *info;
- __u8 unitid = (index >> 8) & 0xff;
- __u8 control = (value >> 8) & 0xff;
- __u8 channel = value & 0xff;
-
- if (channel >= MAX_CHANNELS) {
- snd_printk(KERN_DEBUG "%s(): bogus channel number %d\n",
- __func__, channel);
- return;
- }
-
- for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem) {
- if (info->control != control)
- continue;
-
- switch (attribute) {
- case UAC2_CS_CUR:
- /* invalidate cache, so the value is read from the device */
- if (channel)
- info->cached &= ~(1 << channel);
- else /* master channel */
- info->cached = 0;
-
- snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- info->elem_id);
- break;
-
- case UAC2_CS_RANGE:
- /* TODO */
- break;
-
- case UAC2_CS_MEM:
- /* TODO */
- break;
-
- default:
- snd_printk(KERN_DEBUG "unknown attribute %d in interrupt\n",
- attribute);
- break;
- } /* switch */
- }
-}
-
-static void snd_usb_mixer_interrupt(struct urb *urb)
-{
- struct usb_mixer_interface *mixer = urb->context;
- int len = urb->actual_length;
- int ustatus = urb->status;
-
- if (ustatus != 0)
- goto requeue;
-
- if (mixer->protocol == UAC_VERSION_1) {
- struct uac1_status_word *status;
-
- for (status = urb->transfer_buffer;
- len >= sizeof(*status);
- len -= sizeof(*status), status++) {
- snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n",
- status->bStatusType,
- status->bOriginator);
-
- /* ignore any notifications not from the control interface */
- if ((status->bStatusType & UAC1_STATUS_TYPE_ORIG_MASK) !=
- UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF)
- continue;
-
- if (status->bStatusType & UAC1_STATUS_TYPE_MEM_CHANGED)
- snd_usb_mixer_rc_memory_change(mixer, status->bOriginator);
- else
- snd_usb_mixer_notify_id(mixer, status->bOriginator);
- }
- } else { /* UAC_VERSION_2 */
- struct uac2_interrupt_data_msg *msg;
-
- for (msg = urb->transfer_buffer;
- len >= sizeof(*msg);
- len -= sizeof(*msg), msg++) {
- /* drop vendor specific and endpoint requests */
- if ((msg->bInfo & UAC2_INTERRUPT_DATA_MSG_VENDOR) ||
- (msg->bInfo & UAC2_INTERRUPT_DATA_MSG_EP))
- continue;
-
- snd_usb_mixer_interrupt_v2(mixer, msg->bAttribute,
- le16_to_cpu(msg->wValue),
- le16_to_cpu(msg->wIndex));
- }
- }
-
-requeue:
- if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) {
- urb->dev = mixer->chip->dev;
- usb_submit_urb(urb, GFP_ATOMIC);
- }
-}
-
-/* stop any bus activity of a mixer */
-void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
-{
- usb_kill_urb(mixer->urb);
- usb_kill_urb(mixer->rc_urb);
-}
-
-int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
-{
- int err;
-
- if (mixer->urb) {
- err = usb_submit_urb(mixer->urb, GFP_NOIO);
- if (err < 0)
- return err;
- }
-
- return 0;
-}
-
-/* create the handler for the optional status interrupt endpoint */
-static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
-{
- struct usb_endpoint_descriptor *ep;
- void *transfer_buffer;
- int buffer_length;
- unsigned int epnum;
-
- /* we need one interrupt input endpoint */
- if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1)
- return 0;
- ep = get_endpoint(mixer->hostif, 0);
- if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep))
- return 0;
-
- epnum = usb_endpoint_num(ep);
- buffer_length = le16_to_cpu(ep->wMaxPacketSize);
- transfer_buffer = kmalloc(buffer_length, GFP_KERNEL);
- if (!transfer_buffer)
- return -ENOMEM;
- mixer->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!mixer->urb) {
- kfree(transfer_buffer);
- return -ENOMEM;
- }
- usb_fill_int_urb(mixer->urb, mixer->chip->dev,
- usb_rcvintpipe(mixer->chip->dev, epnum),
- transfer_buffer, buffer_length,
- snd_usb_mixer_interrupt, mixer, ep->bInterval);
- usb_submit_urb(mixer->urb, GFP_KERNEL);
- return 0;
-}
-
-int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
- int ignore_error)
-{
- static struct snd_device_ops dev_ops = {
- .dev_free = snd_usb_mixer_dev_free
- };
- struct usb_mixer_interface *mixer;
- struct snd_info_entry *entry;
- int err;
-
- strcpy(chip->card->mixername, "USB Mixer");
-
- mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
- if (!mixer)
- return -ENOMEM;
- mixer->chip = chip;
- mixer->ignore_ctl_error = ignore_error;
- mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
- GFP_KERNEL);
- if (!mixer->id_elems) {
- kfree(mixer);
- return -ENOMEM;
- }
-
- mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
- switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) {
- case UAC_VERSION_1:
- default:
- mixer->protocol = UAC_VERSION_1;
- break;
- case UAC_VERSION_2:
- mixer->protocol = UAC_VERSION_2;
- break;
- }
-
- if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
- (err = snd_usb_mixer_status_create(mixer)) < 0)
- goto _error;
-
- snd_usb_mixer_apply_create_quirk(mixer);
-
- err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
- if (err < 0)
- goto _error;
-
- if (list_empty(&chip->mixer_list) &&
- !snd_card_proc_new(chip->card, "usbmixer", &entry))
- snd_info_set_text_ops(entry, chip, snd_usb_mixer_proc_read);
-
- list_add(&mixer->list, &chip->mixer_list);
- return 0;
-
-_error:
- snd_usb_mixer_free(mixer);
- return err;
-}
-
-void snd_usb_mixer_disconnect(struct list_head *p)
-{
- struct usb_mixer_interface *mixer;
-
- mixer = list_entry(p, struct usb_mixer_interface, list);
- usb_kill_urb(mixer->urb);
- usb_kill_urb(mixer->rc_urb);
-}
diff --git a/ANDROID_3.4.5/sound/usb/mixer.h b/ANDROID_3.4.5/sound/usb/mixer.h
deleted file mode 100644
index 81b2d8a3..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef __USBMIXER_H
-#define __USBMIXER_H
-
-struct usb_mixer_interface {
- struct snd_usb_audio *chip;
- struct usb_host_interface *hostif;
- struct list_head list;
- unsigned int ignore_ctl_error;
- struct urb *urb;
- /* array[MAX_ID_ELEMS], indexed by unit id */
- struct usb_mixer_elem_info **id_elems;
-
- /* the usb audio specification version this interface complies to */
- int protocol;
-
- /* Sound Blaster remote control stuff */
- const struct rc_config *rc_cfg;
- u32 rc_code;
- wait_queue_head_t rc_waitq;
- struct urb *rc_urb;
- struct usb_ctrlrequest *rc_setup_packet;
- u8 rc_buffer[6];
-
- u8 audigy2nx_leds[3];
- u8 xonar_u1_status;
-};
-
-#define MAX_CHANNELS 16 /* max logical channels */
-
-enum {
- USB_MIXER_BOOLEAN,
- USB_MIXER_INV_BOOLEAN,
- USB_MIXER_S8,
- USB_MIXER_U8,
- USB_MIXER_S16,
- USB_MIXER_U16,
-};
-
-struct usb_mixer_elem_info {
- struct usb_mixer_interface *mixer;
- struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
- struct snd_ctl_elem_id *elem_id;
- unsigned int id;
- unsigned int control; /* CS or ICN (high byte) */
- unsigned int cmask; /* channel mask bitmap: 0 = master */
- unsigned int ch_readonly;
- unsigned int master_readonly;
- int channels;
- int val_type;
- int min, max, res;
- int dBmin, dBmax;
- int cached;
- int cache_val[MAX_CHANNELS];
- u8 initialized;
-};
-
-int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
- int ignore_error);
-void snd_usb_mixer_disconnect(struct list_head *p);
-
-void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid);
-
-int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
- int request, int validx, int value_set);
-void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer);
-int snd_usb_mixer_activate(struct usb_mixer_interface *mixer);
-
-int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
- struct snd_kcontrol *kctl);
-
-#endif /* __USBMIXER_H */
diff --git a/ANDROID_3.4.5/sound/usb/mixer_maps.c b/ANDROID_3.4.5/sound/usb/mixer_maps.c
deleted file mode 100644
index f1324c42..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer_maps.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Additional mixer mapping
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-struct usbmix_dB_map {
- u32 min;
- u32 max;
-};
-
-struct usbmix_name_map {
- int id;
- const char *name;
- int control;
- struct usbmix_dB_map *dB;
-};
-
-struct usbmix_selector_map {
- int id;
- int count;
- const char **names;
-};
-
-struct usbmix_ctl_map {
- u32 id;
- const struct usbmix_name_map *map;
- const struct usbmix_selector_map *selector_map;
- int ignore_ctl_error;
-};
-
-/*
- * USB control mappers for SB Exitigy
- */
-
-/*
- * Topology of SB Extigy (see on the wide screen :)
-
-USB_IN[1] --->FU[2]------------------------------+->MU[16]-->PU[17]-+->FU[18]--+->EU[27]--+->EU[21]-->FU[22]--+->FU[23] > Dig_OUT[24]
- ^ | | | |
-USB_IN[3] -+->SU[5]-->FU[6]--+->MU[14] ->PU[15]->+ | | | +->FU[25] > Dig_OUT[26]
- ^ ^ | | | |
-Dig_IN[4] -+ | | | | +->FU[28]---------------------> Spk_OUT[19]
- | | | |
-Lin-IN[7] -+-->FU[8]---------+ | | +----------------------------------------> Hph_OUT[20]
- | | |
-Mic-IN[9] --+->FU[10]----------------------------+ |
- || |
- || +----------------------------------------------------+
- VV V
- ++--+->SU[11]-->FU[12] --------------------------------------------------------------------------------------> USB_OUT[13]
-*/
-
-static struct usbmix_name_map extigy_map[] = {
- /* 1: IT pcm */
- { 2, "PCM Playback" }, /* FU */
- /* 3: IT pcm */
- /* 4: IT digital in */
- { 5, NULL }, /* DISABLED: this seems to be bogus on some firmware */
- { 6, "Digital In" }, /* FU */
- /* 7: IT line */
- { 8, "Line Playback" }, /* FU */
- /* 9: IT mic */
- { 10, "Mic Playback" }, /* FU */
- { 11, "Capture Source" }, /* SU */
- { 12, "Capture" }, /* FU */
- /* 13: OT pcm capture */
- /* 14: MU (w/o controls) */
- /* 15: PU (3D enh) */
- /* 16: MU (w/o controls) */
- { 17, NULL, 1 }, /* DISABLED: PU-switch (any effect?) */
- { 17, "Channel Routing", 2 }, /* PU: mode select */
- { 18, "Tone Control - Bass", UAC_FU_BASS }, /* FU */
- { 18, "Tone Control - Treble", UAC_FU_TREBLE }, /* FU */
- { 18, "Master Playback" }, /* FU; others */
- /* 19: OT speaker */
- /* 20: OT headphone */
- { 21, NULL }, /* DISABLED: EU (for what?) */
- { 22, "Digital Out Playback" }, /* FU */
- { 23, "Digital Out1 Playback" }, /* FU */ /* FIXME: corresponds to 24 */
- /* 24: OT digital out */
- { 25, "IEC958 Optical Playback" }, /* FU */
- { 26, "IEC958 Optical Playback" }, /* OT */
- { 27, NULL }, /* DISABLED: EU (for what?) */
- /* 28: FU speaker (mute) */
- { 29, NULL }, /* Digital Input Playback Source? */
- { 0 } /* terminator */
-};
-
-/* Sound Blaster MP3+ controls mapping
- * The default mixer channels have totally misleading names,
- * e.g. no Master and fake PCM volume
- * Pavel Mihaylov <bin@bash.info>
- */
-static struct usbmix_dB_map mp3plus_dB_1 = {-4781, 0}; /* just guess */
-static struct usbmix_dB_map mp3plus_dB_2 = {-1781, 618}; /* just guess */
-
-static struct usbmix_name_map mp3plus_map[] = {
- /* 1: IT pcm */
- /* 2: IT mic */
- /* 3: IT line */
- /* 4: IT digital in */
- /* 5: OT digital out */
- /* 6: OT speaker */
- /* 7: OT pcm capture */
- { 8, "Capture Source" }, /* FU, default PCM Capture Source */
- /* (Mic, Input 1 = Line input, Input 2 = Optical input) */
- { 9, "Master Playback" }, /* FU, default Speaker 1 */
- /* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */
- { 10, /* "Mic Capture", */ NULL, 2, .dB = &mp3plus_dB_2 },
- /* FU, Mic Capture */
- { 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */
- { 11, "Line Capture", .dB = &mp3plus_dB_2 },
- /* FU, default PCM Capture */
- { 12, "Digital In Playback" }, /* FU, default PCM 1 */
- { 13, /* "Mic Playback", */ .dB = &mp3plus_dB_1 },
- /* FU, default Mic Playback */
- { 14, "Line Playback", .dB = &mp3plus_dB_1 }, /* FU, default Speaker */
- /* 15: MU */
- { 0 } /* terminator */
-};
-
-/* Topology of SB Audigy 2 NX
-
- +----------------------------->EU[27]--+
- | v
- | +----------------------------------->SU[29]---->FU[22]-->Dig_OUT[24]
- | | ^
-USB_IN[1]-+------------+ +->EU[17]->+->FU[11]-+
- | v | v |
-Dig_IN[4]---+->FU[6]-->MU[16]->FU[18]-+->EU[21]->SU[31]----->FU[30]->Hph_OUT[20]
- | ^ | |
-Lin_IN[7]-+--->FU[8]---+ +->EU[23]->FU[28]------------->Spk_OUT[19]
- | | v
- +--->FU[12]------------------------------------->SU[14]--->USB_OUT[15]
- | ^
- +->FU[13]--------------------------------------+
-*/
-static struct usbmix_name_map audigy2nx_map[] = {
- /* 1: IT pcm playback */
- /* 4: IT digital in */
- { 6, "Digital In Playback" }, /* FU */
- /* 7: IT line in */
- { 8, "Line Playback" }, /* FU */
- { 11, "What-U-Hear Capture" }, /* FU */
- { 12, "Line Capture" }, /* FU */
- { 13, "Digital In Capture" }, /* FU */
- { 14, "Capture Source" }, /* SU */
- /* 15: OT pcm capture */
- /* 16: MU w/o controls */
- { 17, NULL }, /* DISABLED: EU (for what?) */
- { 18, "Master Playback" }, /* FU */
- /* 19: OT speaker */
- /* 20: OT headphone */
- { 21, NULL }, /* DISABLED: EU (for what?) */
- { 22, "Digital Out Playback" }, /* FU */
- { 23, NULL }, /* DISABLED: EU (for what?) */
- /* 24: OT digital out */
- { 27, NULL }, /* DISABLED: EU (for what?) */
- { 28, "Speaker Playback" }, /* FU */
- { 29, "Digital Out Source" }, /* SU */
- { 30, "Headphone Playback" }, /* FU */
- { 31, "Headphone Source" }, /* SU */
- { 0 } /* terminator */
-};
-
-static struct usbmix_selector_map audigy2nx_selectors[] = {
- {
- .id = 14, /* Capture Source */
- .count = 3,
- .names = (const char*[]) {"Line", "Digital In", "What-U-Hear"}
- },
- {
- .id = 29, /* Digital Out Source */
- .count = 3,
- .names = (const char*[]) {"Front", "PCM", "Digital In"}
- },
- {
- .id = 31, /* Headphone Source */
- .count = 2,
- .names = (const char*[]) {"Front", "Side"}
- },
- { 0 } /* terminator */
-};
-
-/* Creative SoundBlaster Live! 24-bit External */
-static struct usbmix_name_map live24ext_map[] = {
- /* 2: PCM Playback Volume */
- { 5, "Mic Capture" }, /* FU, default PCM Capture Volume */
- { 0 } /* terminator */
-};
-
-/* LineX FM Transmitter entry - needed to bypass controls bug */
-static struct usbmix_name_map linex_map[] = {
- /* 1: IT pcm */
- /* 2: OT Speaker */
- { 3, "Master" }, /* FU: master volume - left / right / mute */
- { 0 } /* terminator */
-};
-
-static struct usbmix_name_map maya44_map[] = {
- /* 1: IT line */
- { 2, "Line Playback" }, /* FU */
- /* 3: IT line */
- { 4, "Line Playback" }, /* FU */
- /* 5: IT pcm playback */
- /* 6: MU */
- { 7, "Master Playback" }, /* FU */
- /* 8: OT speaker */
- /* 9: IT line */
- { 10, "Line Capture" }, /* FU */
- /* 11: MU */
- /* 12: OT pcm capture */
- { }
-};
-
-/* Section "justlink_map" below added by James Courtier-Dutton <James@superbug.demon.co.uk>
- * sourced from Maplin Electronics (http://www.maplin.co.uk), part number A56AK
- * Part has 2 connectors that act as a single output. (TOSLINK Optical for digital out, and 3.5mm Jack for Analogue out.)
- * The USB Mixer publishes a Microphone and extra Volume controls for it, but none exist on the device,
- * so this map removes all unwanted sliders from alsamixer
- */
-
-static struct usbmix_name_map justlink_map[] = {
- /* 1: IT pcm playback */
- /* 2: Not present */
- { 3, NULL}, /* IT mic (No mic input on device) */
- /* 4: Not present */
- /* 5: OT speacker */
- /* 6: OT pcm capture */
- { 7, "Master Playback" }, /* Mute/volume for speaker */
- { 8, NULL }, /* Capture Switch (No capture inputs on device) */
- { 9, NULL }, /* Capture Mute/volume (No capture inputs on device */
- /* 0xa: Not present */
- /* 0xb: MU (w/o controls) */
- { 0xc, NULL }, /* Mic feedback Mute/volume (No capture inputs on device) */
- { 0 } /* terminator */
-};
-
-/* TerraTec Aureon 5.1 MkII USB */
-static struct usbmix_name_map aureon_51_2_map[] = {
- /* 1: IT USB */
- /* 2: IT Mic */
- /* 3: IT Line */
- /* 4: IT SPDIF */
- /* 5: OT SPDIF */
- /* 6: OT Speaker */
- /* 7: OT USB */
- { 8, "Capture Source" }, /* SU */
- { 9, "Master Playback" }, /* FU */
- { 10, "Mic Capture" }, /* FU */
- { 11, "Line Capture" }, /* FU */
- { 12, "IEC958 In Capture" }, /* FU */
- { 13, "Mic Playback" }, /* FU */
- { 14, "Line Playback" }, /* FU */
- /* 15: MU */
- {} /* terminator */
-};
-
-static struct usbmix_name_map scratch_live_map[] = {
- /* 1: IT Line 1 (USB streaming) */
- /* 2: OT Line 1 (Speaker) */
- /* 3: IT Line 1 (Line connector) */
- { 4, "Line 1 In" }, /* FU */
- /* 5: OT Line 1 (USB streaming) */
- /* 6: IT Line 2 (USB streaming) */
- /* 7: OT Line 2 (Speaker) */
- /* 8: IT Line 2 (Line connector) */
- { 9, "Line 2 In" }, /* FU */
- /* 10: OT Line 2 (USB streaming) */
- /* 11: IT Mic (Line connector) */
- /* 12: OT Mic (USB streaming) */
- { 0 } /* terminator */
-};
-
-/* "Gamesurround Muse Pocket LT" looks same like "Sound Blaster MP3+"
- * most importand difference is SU[8], it should be set to "Capture Source"
- * to make alsamixer and PA working properly.
- * FIXME: or mp3plus_map should use "Capture Source" too,
- * so this maps can be merget
- */
-static struct usbmix_name_map hercules_usb51_map[] = {
- { 8, "Capture Source" }, /* SU, default "PCM Capture Source" */
- { 9, "Master Playback" }, /* FU, default "Speaker Playback" */
- { 10, "Mic Boost", 7 }, /* FU, default "Auto Gain Input" */
- { 11, "Line Capture" }, /* FU, default "PCM Capture" */
- { 13, "Mic Bypass Playback" }, /* FU, default "Mic Playback" */
- { 14, "Line Bypass Playback" }, /* FU, default "Line Playback" */
- { 0 } /* terminator */
-};
-
-/*
- * Control map entries
- */
-
-static struct usbmix_ctl_map usbmix_ctl_maps[] = {
- {
- .id = USB_ID(0x041e, 0x3000),
- .map = extigy_map,
- .ignore_ctl_error = 1,
- },
- {
- .id = USB_ID(0x041e, 0x3010),
- .map = mp3plus_map,
- },
- {
- .id = USB_ID(0x041e, 0x3020),
- .map = audigy2nx_map,
- .selector_map = audigy2nx_selectors,
- },
- {
- .id = USB_ID(0x041e, 0x3040),
- .map = live24ext_map,
- },
- {
- .id = USB_ID(0x041e, 0x3048),
- .map = audigy2nx_map,
- .selector_map = audigy2nx_selectors,
- },
- {
- /* Hercules DJ Console (Windows Edition) */
- .id = USB_ID(0x06f8, 0xb000),
- .ignore_ctl_error = 1,
- },
- {
- /* Hercules DJ Console (Macintosh Edition) */
- .id = USB_ID(0x06f8, 0xd002),
- .ignore_ctl_error = 1,
- },
- {
- /* Hercules Gamesurround Muse Pocket LT
- * (USB 5.1 Channel Audio Adapter)
- */
- .id = USB_ID(0x06f8, 0xc000),
- .map = hercules_usb51_map,
- },
- {
- .id = USB_ID(0x08bb, 0x2702),
- .map = linex_map,
- .ignore_ctl_error = 1,
- },
- {
- .id = USB_ID(0x0a92, 0x0091),
- .map = maya44_map,
- },
- {
- .id = USB_ID(0x0c45, 0x1158),
- .map = justlink_map,
- },
- {
- .id = USB_ID(0x0ccd, 0x0028),
- .map = aureon_51_2_map,
- },
- {
- .id = USB_ID(0x13e5, 0x0001),
- .map = scratch_live_map,
- .ignore_ctl_error = 1,
- },
- { 0 } /* terminator */
-};
-
diff --git a/ANDROID_3.4.5/sound/usb/mixer_quirks.c b/ANDROID_3.4.5/sound/usb/mixer_quirks.c
deleted file mode 100644
index ab125ee0..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer_quirks.c
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * USB Audio Driver for ALSA
- *
- * Quirks and vendor-specific extensions for mixer interfaces
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * Many codes borrowed from audio.c by
- * Alan Cox (alan@lxorguk.ukuu.org.uk)
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-
-#include <sound/core.h>
-#include <sound/control.h>
-#include <sound/hwdep.h>
-#include <sound/info.h>
-
-#include "usbaudio.h"
-#include "mixer.h"
-#include "mixer_quirks.h"
-#include "helper.h"
-
-extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
-
-/*
- * Sound Blaster remote control configuration
- *
- * format of remote control data:
- * Extigy: xx 00
- * Audigy 2 NX: 06 80 xx 00 00 00
- * Live! 24-bit: 06 80 xx yy 22 83
- */
-static const struct rc_config {
- u32 usb_id;
- u8 offset;
- u8 length;
- u8 packet_length;
- u8 min_packet_length; /* minimum accepted length of the URB result */
- u8 mute_mixer_id;
- u32 mute_code;
-} rc_configs[] = {
- { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
- { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
- { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
- { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */
- { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */
- { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
-};
-
-static void snd_usb_soundblaster_remote_complete(struct urb *urb)
-{
- struct usb_mixer_interface *mixer = urb->context;
- const struct rc_config *rc = mixer->rc_cfg;
- u32 code;
-
- if (urb->status < 0 || urb->actual_length < rc->min_packet_length)
- return;
-
- code = mixer->rc_buffer[rc->offset];
- if (rc->length == 2)
- code |= mixer->rc_buffer[rc->offset + 1] << 8;
-
- /* the Mute button actually changes the mixer control */
- if (code == rc->mute_code)
- snd_usb_mixer_notify_id(mixer, rc->mute_mixer_id);
- mixer->rc_code = code;
- wmb();
- wake_up(&mixer->rc_waitq);
-}
-
-static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
- long count, loff_t *offset)
-{
- struct usb_mixer_interface *mixer = hw->private_data;
- int err;
- u32 rc_code;
-
- if (count != 1 && count != 4)
- return -EINVAL;
- err = wait_event_interruptible(mixer->rc_waitq,
- (rc_code = xchg(&mixer->rc_code, 0)) != 0);
- if (err == 0) {
- if (count == 1)
- err = put_user(rc_code, buf);
- else
- err = put_user(rc_code, (u32 __user *)buf);
- }
- return err < 0 ? err : count;
-}
-
-static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
- poll_table *wait)
-{
- struct usb_mixer_interface *mixer = hw->private_data;
-
- poll_wait(file, &mixer->rc_waitq, wait);
- return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
-}
-
-static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
-{
- struct snd_hwdep *hwdep;
- int err, len, i;
-
- for (i = 0; i < ARRAY_SIZE(rc_configs); ++i)
- if (rc_configs[i].usb_id == mixer->chip->usb_id)
- break;
- if (i >= ARRAY_SIZE(rc_configs))
- return 0;
- mixer->rc_cfg = &rc_configs[i];
-
- len = mixer->rc_cfg->packet_length;
-
- init_waitqueue_head(&mixer->rc_waitq);
- err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
- if (err < 0)
- return err;
- snprintf(hwdep->name, sizeof(hwdep->name),
- "%s remote control", mixer->chip->card->shortname);
- hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
- hwdep->private_data = mixer;
- hwdep->ops.read = snd_usb_sbrc_hwdep_read;
- hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
- hwdep->exclusive = 1;
-
- mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!mixer->rc_urb)
- return -ENOMEM;
- mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
- if (!mixer->rc_setup_packet) {
- usb_free_urb(mixer->rc_urb);
- mixer->rc_urb = NULL;
- return -ENOMEM;
- }
- mixer->rc_setup_packet->bRequestType =
- USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- mixer->rc_setup_packet->bRequest = UAC_GET_MEM;
- mixer->rc_setup_packet->wValue = cpu_to_le16(0);
- mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
- mixer->rc_setup_packet->wLength = cpu_to_le16(len);
- usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
- usb_rcvctrlpipe(mixer->chip->dev, 0),
- (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
- snd_usb_soundblaster_remote_complete, mixer);
- return 0;
-}
-
-#define snd_audigy2nx_led_info snd_ctl_boolean_mono_info
-
-static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
-
- ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
- return 0;
-}
-
-static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- int index = kcontrol->private_value;
- int value = ucontrol->value.integer.value[0];
- int err, changed;
-
- if (value > 1)
- return -EINVAL;
- changed = value != mixer->audigy2nx_leds[index];
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- !value, 0, NULL, 0);
- /* USB X-Fi S51 Pro */
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df))
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- !value, 0, NULL, 0);
- else
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- value, index + 2, NULL, 0);
- if (err < 0)
- return err;
- mixer->audigy2nx_leds[index] = value;
- return changed;
-}
-
-static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "CMSS LED Switch",
- .info = snd_audigy2nx_led_info,
- .get = snd_audigy2nx_led_get,
- .put = snd_audigy2nx_led_put,
- .private_value = 0,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Power LED Switch",
- .info = snd_audigy2nx_led_info,
- .get = snd_audigy2nx_led_get,
- .put = snd_audigy2nx_led_put,
- .private_value = 1,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Dolby Digital LED Switch",
- .info = snd_audigy2nx_led_info,
- .get = snd_audigy2nx_led_get,
- .put = snd_audigy2nx_led_put,
- .private_value = 2,
- },
-};
-
-static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
-{
- int i, err;
-
- for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
- /* USB X-Fi S51 doesn't have a CMSS LED */
- if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0)
- continue;
- /* USB X-Fi S51 Pro doesn't have one either */
- if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0)
- continue;
- if (i > 1 && /* Live24ext has 2 LEDs only */
- (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x3042) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x30df) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x3048)))
- break;
- err = snd_ctl_add(mixer->chip->card,
- snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
- if (err < 0)
- return err;
- }
- mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
- return 0;
-}
-
-static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
- struct snd_info_buffer *buffer)
-{
- static const struct sb_jack {
- int unitid;
- const char *name;
- } jacks_audigy2nx[] = {
- {4, "dig in "},
- {7, "line in"},
- {19, "spk out"},
- {20, "hph out"},
- {-1, NULL}
- }, jacks_live24ext[] = {
- {4, "line in"}, /* &1=Line, &2=Mic*/
- {3, "hph out"}, /* headphones */
- {0, "RC "}, /* last command, 6 bytes see rc_config above */
- {-1, NULL}
- };
- const struct sb_jack *jacks;
- struct usb_mixer_interface *mixer = entry->private_data;
- int i, err;
- u8 buf[3];
-
- snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
- jacks = jacks_audigy2nx;
- else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
- jacks = jacks_live24ext;
- else
- return;
-
- for (i = 0; jacks[i].name; ++i) {
- snd_iprintf(buffer, "%s: ", jacks[i].name);
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_rcvctrlpipe(mixer->chip->dev, 0),
- UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0,
- jacks[i].unitid << 8, buf, 3);
- if (err == 3 && (buf[0] == 3 || buf[0] == 6))
- snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
- else
- snd_iprintf(buffer, "?\n");
- }
-}
-
-static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
-
- ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
- return 0;
-}
-
-static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- u8 old_status, new_status;
- int err, changed;
-
- old_status = mixer->xonar_u1_status;
- if (ucontrol->value.integer.value[0])
- new_status = old_status | 0x02;
- else
- new_status = old_status & ~0x02;
- changed = new_status != old_status;
- err = snd_usb_ctl_msg(mixer->chip->dev,
- usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- 50, 0, &new_status, 1);
- if (err < 0)
- return err;
- mixer->xonar_u1_status = new_status;
- return changed;
-}
-
-static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Digital Playback Switch",
- .info = snd_ctl_boolean_mono_info,
- .get = snd_xonar_u1_switch_get,
- .put = snd_xonar_u1_switch_put,
-};
-
-static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
-{
- int err;
-
- err = snd_ctl_add(mixer->chip->card,
- snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
- if (err < 0)
- return err;
- mixer->xonar_u1_status = 0x05;
- return 0;
-}
-
-/* Native Instruments device quirks */
-
-#define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
-
-static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- struct usb_device *dev = mixer->chip->dev;
- u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
- u16 wIndex = kcontrol->private_value & 0xffff;
- u8 tmp;
-
- int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
- 0, cpu_to_le16(wIndex),
- &tmp, sizeof(tmp), 1000);
-
- if (ret < 0) {
- snd_printk(KERN_ERR
- "unable to issue vendor read request (ret = %d)", ret);
- return ret;
- }
-
- ucontrol->value.integer.value[0] = tmp;
-
- return 0;
-}
-
-static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
- struct usb_device *dev = mixer->chip->dev;
- u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
- u16 wIndex = kcontrol->private_value & 0xffff;
- u16 wValue = ucontrol->value.integer.value[0];
-
- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
- cpu_to_le16(wValue), cpu_to_le16(wIndex),
- NULL, 0, 1000);
-
- if (ret < 0) {
- snd_printk(KERN_ERR
- "unable to issue vendor write request (ret = %d)", ret);
- return ret;
- }
-
- return 0;
-}
-
-static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
- {
- .name = "Direct Thru Channel A",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
- },
- {
- .name = "Direct Thru Channel B",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
- },
- {
- .name = "Phono Input Channel A",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
- },
- {
- .name = "Phono Input Channel B",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
- },
-};
-
-static struct snd_kcontrol_new snd_nativeinstruments_ta10_mixers[] = {
- {
- .name = "Direct Thru Channel A",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x03),
- },
- {
- .name = "Direct Thru Channel B",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x05),
- },
- {
- .name = "Direct Thru Channel C",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x07),
- },
- {
- .name = "Direct Thru Channel D",
- .private_value = _MAKE_NI_CONTROL(0x01, 0x09),
- },
- {
- .name = "Phono Input Channel A",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x03),
- },
- {
- .name = "Phono Input Channel B",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x05),
- },
- {
- .name = "Phono Input Channel C",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x07),
- },
- {
- .name = "Phono Input Channel D",
- .private_value = _MAKE_NI_CONTROL(0x02, 0x09),
- },
-};
-
-static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
- const struct snd_kcontrol_new *kc,
- unsigned int count)
-{
- int i, err = 0;
- struct snd_kcontrol_new template = {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
- .get = snd_nativeinstruments_control_get,
- .put = snd_nativeinstruments_control_put,
- .info = snd_ctl_boolean_mono_info,
- };
-
- for (i = 0; i < count; i++) {
- struct snd_kcontrol *c;
-
- template.name = kc[i].name;
- template.private_value = kc[i].private_value;
-
- c = snd_ctl_new1(&template, mixer);
- err = snd_ctl_add(mixer->chip->card, c);
-
- if (err < 0)
- break;
- }
-
- return err;
-}
-
-/* M-Audio FastTrack Ultra quirks */
-
-/* private_free callback */
-static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
-{
- kfree(kctl->private_data);
- kctl->private_data = NULL;
-}
-
-static int snd_maudio_ftu_create_ctl(struct usb_mixer_interface *mixer,
- int in, int out, const char *name)
-{
- struct usb_mixer_elem_info *cval;
- struct snd_kcontrol *kctl;
-
- cval = kzalloc(sizeof(*cval), GFP_KERNEL);
- if (!cval)
- return -ENOMEM;
-
- cval->id = 5;
- cval->mixer = mixer;
- cval->val_type = USB_MIXER_S16;
- cval->channels = 1;
- cval->control = out + 1;
- cval->cmask = 1 << in;
-
- kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval);
- if (!kctl) {
- kfree(cval);
- return -ENOMEM;
- }
-
- snprintf(kctl->id.name, sizeof(kctl->id.name), name);
- kctl->private_free = usb_mixer_elem_free;
- return snd_usb_mixer_add_control(mixer, kctl);
-}
-
-static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer)
-{
- char name[64];
- int in, out, err;
-
- for (out = 0; out < 8; out++) {
- for (in = 0; in < 8; in++) {
- snprintf(name, sizeof(name),
- "AIn%d - Out%d Capture Volume", in + 1, out + 1);
- err = snd_maudio_ftu_create_ctl(mixer, in, out, name);
- if (err < 0)
- return err;
- }
-
- for (in = 8; in < 16; in++) {
- snprintf(name, sizeof(name),
- "DIn%d - Out%d Playback Volume", in - 7, out + 1);
- err = snd_maudio_ftu_create_ctl(mixer, in, out, name);
- if (err < 0)
- return err;
- }
- }
-
- return 0;
-}
-
-void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
- unsigned char samplerate_id)
-{
- struct usb_mixer_interface *mixer;
- struct usb_mixer_elem_info *cval;
- int unitid = 12; /* SamleRate ExtensionUnit ID */
-
- list_for_each_entry(mixer, &chip->mixer_list, list) {
- cval = mixer->id_elems[unitid];
- if (cval) {
- snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
- cval->control << 8,
- samplerate_id);
- snd_usb_mixer_notify_id(mixer, unitid);
- }
- break;
- }
-}
-
-int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
-{
- int err = 0;
- struct snd_info_entry *entry;
-
- if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
- return err;
-
- switch (mixer->chip->usb_id) {
- case USB_ID(0x041e, 0x3020):
- case USB_ID(0x041e, 0x3040):
- case USB_ID(0x041e, 0x3042):
- case USB_ID(0x041e, 0x30df):
- case USB_ID(0x041e, 0x3048):
- err = snd_audigy2nx_controls_create(mixer);
- if (err < 0)
- break;
- if (!snd_card_proc_new(mixer->chip->card, "audigy2nx", &entry))
- snd_info_set_text_ops(entry, mixer,
- snd_audigy2nx_proc_read);
- break;
-
- case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */
- case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
- err = snd_maudio_ftu_create_mixer(mixer);
- break;
-
- case USB_ID(0x0b05, 0x1739):
- case USB_ID(0x0b05, 0x1743):
- err = snd_xonar_u1_controls_create(mixer);
- break;
-
- case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
- err = snd_nativeinstruments_create_mixer(mixer,
- snd_nativeinstruments_ta6_mixers,
- ARRAY_SIZE(snd_nativeinstruments_ta6_mixers));
- break;
-
- case USB_ID(0x17cc, 0x1021): /* Traktor Audio 10 */
- err = snd_nativeinstruments_create_mixer(mixer,
- snd_nativeinstruments_ta10_mixers,
- ARRAY_SIZE(snd_nativeinstruments_ta10_mixers));
- break;
- }
-
- return err;
-}
-
-void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
- int unitid)
-{
- if (!mixer->rc_cfg)
- return;
- /* unit ids specific to Extigy/Audigy 2 NX: */
- switch (unitid) {
- case 0: /* remote control */
- mixer->rc_urb->dev = mixer->chip->dev;
- usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
- break;
- case 4: /* digital in jack */
- case 7: /* line in jacks */
- case 19: /* speaker out jacks */
- case 20: /* headphones out jack */
- break;
- /* live24ext: 4 = line-in jack */
- case 3: /* hp-out jack (may actuate Mute) */
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) ||
- mixer->chip->usb_id == USB_ID(0x041e, 0x3048))
- snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
- break;
- default:
- snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
- break;
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/mixer_quirks.h b/ANDROID_3.4.5/sound/usb/mixer_quirks.h
deleted file mode 100644
index bdbfab09..00000000
--- a/ANDROID_3.4.5/sound/usb/mixer_quirks.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef SND_USB_MIXER_QUIRKS_H
-#define SND_USB_MIXER_QUIRKS_H
-
-int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer);
-
-void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
- unsigned char samplerate_id);
-
-void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
- int unitid);
-
-#endif /* SND_USB_MIXER_QUIRKS_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/pcm.c b/ANDROID_3.4.5/sound/usb/pcm.c
deleted file mode 100644
index 67a4d6db..00000000
--- a/ANDROID_3.4.5/sound/usb/pcm.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "quirks.h"
-#include "debug.h"
-#include "endpoint.h"
-#include "helper.h"
-#include "pcm.h"
-#include "clock.h"
-#include "power.h"
-
-/* return the estimated delay based on USB frame counters */
-snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
- unsigned int rate)
-{
- int current_frame_number;
- int frame_diff;
- int est_delay;
-
- current_frame_number = usb_get_current_frame_number(subs->dev);
- /*
- * HCD implementations use different widths, use lower 8 bits.
- * The delay will be managed up to 256ms, which is more than
- * enough
- */
- frame_diff = (current_frame_number - subs->last_frame_number) & 0xff;
-
- /* Approximation based on number of samples per USB frame (ms),
- some truncation for 44.1 but the estimate is good enough */
- est_delay = subs->last_delay - (frame_diff * rate / 1000);
- if (est_delay < 0)
- est_delay = 0;
- return est_delay;
-}
-
-/*
- * return the current pcm pointer. just based on the hwptr_done value.
- */
-static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_usb_substream *subs;
- unsigned int hwptr_done;
-
- subs = (struct snd_usb_substream *)substream->runtime->private_data;
- spin_lock(&subs->lock);
- hwptr_done = subs->hwptr_done;
- substream->runtime->delay = snd_usb_pcm_delay(subs,
- substream->runtime->rate);
- spin_unlock(&subs->lock);
- return hwptr_done / (substream->runtime->frame_bits >> 3);
-}
-
-/*
- * find a matching audio format
- */
-static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
- unsigned int rate, unsigned int channels)
-{
- struct list_head *p;
- struct audioformat *found = NULL;
- int cur_attr = 0, attr;
-
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- if (!(fp->formats & (1uLL << format)))
- continue;
- if (fp->channels != channels)
- continue;
- if (rate < fp->rate_min || rate > fp->rate_max)
- continue;
- if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
- unsigned int i;
- for (i = 0; i < fp->nr_rates; i++)
- if (fp->rate_table[i] == rate)
- break;
- if (i >= fp->nr_rates)
- continue;
- }
- attr = fp->ep_attr & USB_ENDPOINT_SYNCTYPE;
- if (! found) {
- found = fp;
- cur_attr = attr;
- continue;
- }
- /* avoid async out and adaptive in if the other method
- * supports the same format.
- * this is a workaround for the case like
- * M-audio audiophile USB.
- */
- if (attr != cur_attr) {
- if ((attr == USB_ENDPOINT_SYNC_ASYNC &&
- subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
- (attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
- subs->direction == SNDRV_PCM_STREAM_CAPTURE))
- continue;
- if ((cur_attr == USB_ENDPOINT_SYNC_ASYNC &&
- subs->direction == SNDRV_PCM_STREAM_PLAYBACK) ||
- (cur_attr == USB_ENDPOINT_SYNC_ADAPTIVE &&
- subs->direction == SNDRV_PCM_STREAM_CAPTURE)) {
- found = fp;
- cur_attr = attr;
- continue;
- }
- }
- /* find the format with the largest max. packet size */
- if (fp->maxpacksize > found->maxpacksize) {
- found = fp;
- cur_attr = attr;
- }
- }
- return found;
-}
-
-static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt)
-{
- struct usb_device *dev = chip->dev;
- unsigned int ep;
- unsigned char data[1];
- int err;
-
- ep = get_endpoint(alts, 0)->bEndpointAddress;
-
- data[0] = 1;
- if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
- USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
- UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep,
- data, sizeof(data))) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n",
- dev->devnum, iface, ep);
- return err;
- }
-
- return 0;
-}
-
-static int init_pitch_v2(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt)
-{
- struct usb_device *dev = chip->dev;
- unsigned char data[1];
- unsigned int ep;
- int err;
-
- ep = get_endpoint(alts, 0)->bEndpointAddress;
-
- data[0] = 1;
- if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
- USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- UAC2_EP_CS_PITCH << 8, 0,
- data, sizeof(data))) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n",
- dev->devnum, iface, fmt->altsetting);
- return err;
- }
-
- return 0;
-}
-
-/*
- * initialize the pitch control and sample rate
- */
-int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt)
-{
- struct usb_interface_descriptor *altsd = get_iface_desc(alts);
-
- /* if endpoint doesn't have pitch control, bail out */
- if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
- return 0;
-
- switch (altsd->bInterfaceProtocol) {
- case UAC_VERSION_1:
- default:
- return init_pitch_v1(chip, iface, alts, fmt);
-
- case UAC_VERSION_2:
- return init_pitch_v2(chip, iface, alts, fmt);
- }
-}
-
-/*
- * find a matching format and set up the interface
- */
-static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
-{
- struct usb_device *dev = subs->dev;
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- struct usb_interface *iface;
- unsigned int ep, attr;
- int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
- int err;
-
- iface = usb_ifnum_to_if(dev, fmt->iface);
- if (WARN_ON(!iface))
- return -EINVAL;
- alts = &iface->altsetting[fmt->altset_idx];
- altsd = get_iface_desc(alts);
- if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
- return -EINVAL;
-
- if (fmt == subs->cur_audiofmt)
- return 0;
-
- /* close the old interface */
- if (subs->interface >= 0 && subs->interface != fmt->iface) {
- if (usb_set_interface(subs->dev, subs->interface, 0) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n",
- dev->devnum, fmt->iface, fmt->altsetting);
- return -EIO;
- }
- subs->interface = -1;
- subs->altset_idx = 0;
- }
-
- /* set interface */
- if (subs->interface != fmt->iface || subs->altset_idx != fmt->altset_idx) {
- if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) {
- snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n",
- dev->devnum, fmt->iface, fmt->altsetting);
- return -EIO;
- }
- snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting);
- subs->interface = fmt->iface;
- subs->altset_idx = fmt->altset_idx;
- }
-
- /* create a data pipe */
- ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK;
- if (is_playback)
- subs->datapipe = usb_sndisocpipe(dev, ep);
- else
- subs->datapipe = usb_rcvisocpipe(dev, ep);
- subs->datainterval = fmt->datainterval;
- subs->syncpipe = subs->syncinterval = 0;
- subs->maxpacksize = fmt->maxpacksize;
- subs->syncmaxsize = 0;
- subs->fill_max = 0;
-
- /* we need a sync pipe in async OUT or adaptive IN mode */
- /* check the number of EP, since some devices have broken
- * descriptors which fool us. if it has only one EP,
- * assume it as adaptive-out or sync-in.
- */
- attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
- if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
- (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
- altsd->bNumEndpoints >= 2) {
- /* check sync-pipe endpoint */
- /* ... and check descriptor size before accessing bSynchAddress
- because there is a version of the SB Audigy 2 NX firmware lacking
- the audio fields in the endpoint descriptors */
- if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 ||
- (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
- get_endpoint(alts, 1)->bSynchAddress != 0)) {
- snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
- dev->devnum, fmt->iface, fmt->altsetting);
- return -EINVAL;
- }
- ep = get_endpoint(alts, 1)->bEndpointAddress;
- if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
- (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
- (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
- snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
- dev->devnum, fmt->iface, fmt->altsetting);
- return -EINVAL;
- }
- ep &= USB_ENDPOINT_NUMBER_MASK;
- if (is_playback)
- subs->syncpipe = usb_rcvisocpipe(dev, ep);
- else
- subs->syncpipe = usb_sndisocpipe(dev, ep);
- if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
- get_endpoint(alts, 1)->bRefresh >= 1 &&
- get_endpoint(alts, 1)->bRefresh <= 9)
- subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
- else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
- subs->syncinterval = 1;
- else if (get_endpoint(alts, 1)->bInterval >= 1 &&
- get_endpoint(alts, 1)->bInterval <= 16)
- subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
- else
- subs->syncinterval = 3;
- subs->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
- }
-
- /* always fill max packet size */
- if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX)
- subs->fill_max = 1;
-
- if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0)
- return err;
-
- subs->cur_audiofmt = fmt;
-
- snd_usb_set_format_quirk(subs, fmt);
-
-#if 0
- printk(KERN_DEBUG
- "setting done: format = %d, rate = %d..%d, channels = %d\n",
- fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
- printk(KERN_DEBUG
- " datapipe = 0x%0x, syncpipe = 0x%0x\n",
- subs->datapipe, subs->syncpipe);
-#endif
-
- return 0;
-}
-
-/*
- * hw_params callback
- *
- * allocate a buffer and set the given audio format.
- *
- * so far we use a physically linear buffer although packetize transfer
- * doesn't need a continuous area.
- * if sg buffer is supported on the later version of alsa, we'll follow
- * that.
- */
-static int snd_usb_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- struct snd_usb_substream *subs = substream->runtime->private_data;
- struct audioformat *fmt;
- unsigned int channels, rate, format;
- int ret, changed;
-
- ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
- params_buffer_bytes(hw_params));
- if (ret < 0)
- return ret;
-
- format = params_format(hw_params);
- rate = params_rate(hw_params);
- channels = params_channels(hw_params);
- fmt = find_format(subs, format, rate, channels);
- if (!fmt) {
- snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
- format, rate, channels);
- return -EINVAL;
- }
-
- changed = subs->cur_audiofmt != fmt ||
- subs->period_bytes != params_period_bytes(hw_params) ||
- subs->cur_rate != rate;
- if ((ret = set_format(subs, fmt)) < 0)
- return ret;
-
- if (subs->cur_rate != rate) {
- struct usb_host_interface *alts;
- struct usb_interface *iface;
- iface = usb_ifnum_to_if(subs->dev, fmt->iface);
- alts = &iface->altsetting[fmt->altset_idx];
- ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate);
- if (ret < 0)
- return ret;
- subs->cur_rate = rate;
- }
-
- if (changed) {
- mutex_lock(&subs->stream->chip->shutdown_mutex);
- /* format changed */
- snd_usb_release_substream_urbs(subs, 0);
- /* influenced: period_bytes, channels, rate, format, */
- ret = snd_usb_init_substream_urbs(subs, params_period_bytes(hw_params),
- params_rate(hw_params),
- snd_pcm_format_physical_width(params_format(hw_params)) *
- params_channels(hw_params));
- mutex_unlock(&subs->stream->chip->shutdown_mutex);
- }
-
- return ret;
-}
-
-/*
- * hw_free callback
- *
- * reset the audio format and release the buffer
- */
-static int snd_usb_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_usb_substream *subs = substream->runtime->private_data;
-
- subs->cur_audiofmt = NULL;
- subs->cur_rate = 0;
- subs->period_bytes = 0;
- mutex_lock(&subs->stream->chip->shutdown_mutex);
- snd_usb_release_substream_urbs(subs, 0);
- mutex_unlock(&subs->stream->chip->shutdown_mutex);
- return snd_pcm_lib_free_vmalloc_buffer(substream);
-}
-
-/*
- * prepare callback
- *
- * only a few subtle things...
- */
-static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usb_substream *subs = runtime->private_data;
-
- if (! subs->cur_audiofmt) {
- snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
- return -ENXIO;
- }
-
- /* some unit conversions in runtime */
- subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
- subs->curframesize = bytes_to_frames(runtime, subs->curpacksize);
-
- /* reset the pointer */
- subs->hwptr_done = 0;
- subs->transfer_done = 0;
- subs->phase = 0;
- subs->last_delay = 0;
- subs->last_frame_number = 0;
- runtime->delay = 0;
-
- return snd_usb_substream_prepare(subs, runtime);
-}
-
-static struct snd_pcm_hardware snd_usb_hardware =
-{
- .info = SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH |
- SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_PAUSE,
- .buffer_bytes_max = 1024 * 1024,
- .period_bytes_min = 64,
- .period_bytes_max = 512 * 1024,
- .periods_min = 2,
- .periods_max = 1024,
-};
-
-static int hw_check_valid_format(struct snd_usb_substream *subs,
- struct snd_pcm_hw_params *params,
- struct audioformat *fp)
-{
- struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- struct snd_interval *pt = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
- struct snd_mask check_fmts;
- unsigned int ptime;
-
- /* check the format */
- snd_mask_none(&check_fmts);
- check_fmts.bits[0] = (u32)fp->formats;
- check_fmts.bits[1] = (u32)(fp->formats >> 32);
- snd_mask_intersect(&check_fmts, fmts);
- if (snd_mask_empty(&check_fmts)) {
- hwc_debug(" > check: no supported format %d\n", fp->format);
- return 0;
- }
- /* check the channels */
- if (fp->channels < ct->min || fp->channels > ct->max) {
- hwc_debug(" > check: no valid channels %d (%d/%d)\n", fp->channels, ct->min, ct->max);
- return 0;
- }
- /* check the rate is within the range */
- if (fp->rate_min > it->max || (fp->rate_min == it->max && it->openmax)) {
- hwc_debug(" > check: rate_min %d > max %d\n", fp->rate_min, it->max);
- return 0;
- }
- if (fp->rate_max < it->min || (fp->rate_max == it->min && it->openmin)) {
- hwc_debug(" > check: rate_max %d < min %d\n", fp->rate_max, it->min);
- return 0;
- }
- /* check whether the period time is >= the data packet interval */
- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) {
- ptime = 125 * (1 << fp->datainterval);
- if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
- hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
- return 0;
- }
- }
- return 1;
-}
-
-static int hw_rule_rate(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_usb_substream *subs = rule->private;
- struct list_head *p;
- struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
- unsigned int rmin, rmax;
- int changed;
-
- hwc_debug("hw_rule_rate: (%d,%d)\n", it->min, it->max);
- changed = 0;
- rmin = rmax = 0;
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(subs, params, fp))
- continue;
- if (changed++) {
- if (rmin > fp->rate_min)
- rmin = fp->rate_min;
- if (rmax < fp->rate_max)
- rmax = fp->rate_max;
- } else {
- rmin = fp->rate_min;
- rmax = fp->rate_max;
- }
- }
-
- if (!changed) {
- hwc_debug(" --> get empty\n");
- it->empty = 1;
- return -EINVAL;
- }
-
- changed = 0;
- if (it->min < rmin) {
- it->min = rmin;
- it->openmin = 0;
- changed = 1;
- }
- if (it->max > rmax) {
- it->max = rmax;
- it->openmax = 0;
- changed = 1;
- }
- if (snd_interval_checkempty(it)) {
- it->empty = 1;
- return -EINVAL;
- }
- hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
- return changed;
-}
-
-
-static int hw_rule_channels(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_usb_substream *subs = rule->private;
- struct list_head *p;
- struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
- unsigned int rmin, rmax;
- int changed;
-
- hwc_debug("hw_rule_channels: (%d,%d)\n", it->min, it->max);
- changed = 0;
- rmin = rmax = 0;
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(subs, params, fp))
- continue;
- if (changed++) {
- if (rmin > fp->channels)
- rmin = fp->channels;
- if (rmax < fp->channels)
- rmax = fp->channels;
- } else {
- rmin = fp->channels;
- rmax = fp->channels;
- }
- }
-
- if (!changed) {
- hwc_debug(" --> get empty\n");
- it->empty = 1;
- return -EINVAL;
- }
-
- changed = 0;
- if (it->min < rmin) {
- it->min = rmin;
- it->openmin = 0;
- changed = 1;
- }
- if (it->max > rmax) {
- it->max = rmax;
- it->openmax = 0;
- changed = 1;
- }
- if (snd_interval_checkempty(it)) {
- it->empty = 1;
- return -EINVAL;
- }
- hwc_debug(" --> (%d, %d) (changed = %d)\n", it->min, it->max, changed);
- return changed;
-}
-
-static int hw_rule_format(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_usb_substream *subs = rule->private;
- struct list_head *p;
- struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
- u64 fbits;
- u32 oldbits[2];
- int changed;
-
- hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
- fbits = 0;
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- if (!hw_check_valid_format(subs, params, fp))
- continue;
- fbits |= fp->formats;
- }
-
- oldbits[0] = fmt->bits[0];
- oldbits[1] = fmt->bits[1];
- fmt->bits[0] &= (u32)fbits;
- fmt->bits[1] &= (u32)(fbits >> 32);
- if (!fmt->bits[0] && !fmt->bits[1]) {
- hwc_debug(" --> get empty\n");
- return -EINVAL;
- }
- changed = (oldbits[0] != fmt->bits[0] || oldbits[1] != fmt->bits[1]);
- hwc_debug(" --> %x:%x (changed = %d)\n", fmt->bits[0], fmt->bits[1], changed);
- return changed;
-}
-
-static int hw_rule_period_time(struct snd_pcm_hw_params *params,
- struct snd_pcm_hw_rule *rule)
-{
- struct snd_usb_substream *subs = rule->private;
- struct audioformat *fp;
- struct snd_interval *it;
- unsigned char min_datainterval;
- unsigned int pmin;
- int changed;
-
- it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME);
- hwc_debug("hw_rule_period_time: (%u,%u)\n", it->min, it->max);
- min_datainterval = 0xff;
- list_for_each_entry(fp, &subs->fmt_list, list) {
- if (!hw_check_valid_format(subs, params, fp))
- continue;
- min_datainterval = min(min_datainterval, fp->datainterval);
- }
- if (min_datainterval == 0xff) {
- hwc_debug(" --> get empty\n");
- it->empty = 1;
- return -EINVAL;
- }
- pmin = 125 * (1 << min_datainterval);
- changed = 0;
- if (it->min < pmin) {
- it->min = pmin;
- it->openmin = 0;
- changed = 1;
- }
- if (snd_interval_checkempty(it)) {
- it->empty = 1;
- return -EINVAL;
- }
- hwc_debug(" --> (%u,%u) (changed = %d)\n", it->min, it->max, changed);
- return changed;
-}
-
-/*
- * If the device supports unusual bit rates, does the request meet these?
- */
-static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
- struct snd_usb_substream *subs)
-{
- struct audioformat *fp;
- int *rate_list;
- int count = 0, needs_knot = 0;
- int err;
-
- kfree(subs->rate_list.list);
- subs->rate_list.list = NULL;
-
- list_for_each_entry(fp, &subs->fmt_list, list) {
- if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
- return 0;
- count += fp->nr_rates;
- if (fp->rates & SNDRV_PCM_RATE_KNOT)
- needs_knot = 1;
- }
- if (!needs_knot)
- return 0;
-
- subs->rate_list.list = rate_list =
- kmalloc(sizeof(int) * count, GFP_KERNEL);
- if (!subs->rate_list.list)
- return -ENOMEM;
- subs->rate_list.count = count;
- subs->rate_list.mask = 0;
- count = 0;
- list_for_each_entry(fp, &subs->fmt_list, list) {
- int i;
- for (i = 0; i < fp->nr_rates; i++)
- rate_list[count++] = fp->rate_table[i];
- }
- err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- &subs->rate_list);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-
-/*
- * set up the runtime hardware information.
- */
-
-static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
-{
- struct list_head *p;
- unsigned int pt, ptmin;
- int param_period_time_if_needed;
- int err;
-
- runtime->hw.formats = subs->formats;
-
- runtime->hw.rate_min = 0x7fffffff;
- runtime->hw.rate_max = 0;
- runtime->hw.channels_min = 256;
- runtime->hw.channels_max = 0;
- runtime->hw.rates = 0;
- ptmin = UINT_MAX;
- /* check min/max rates and channels */
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
- runtime->hw.rates |= fp->rates;
- if (runtime->hw.rate_min > fp->rate_min)
- runtime->hw.rate_min = fp->rate_min;
- if (runtime->hw.rate_max < fp->rate_max)
- runtime->hw.rate_max = fp->rate_max;
- if (runtime->hw.channels_min > fp->channels)
- runtime->hw.channels_min = fp->channels;
- if (runtime->hw.channels_max < fp->channels)
- runtime->hw.channels_max = fp->channels;
- if (fp->fmt_type == UAC_FORMAT_TYPE_II && fp->frame_size > 0) {
- /* FIXME: there might be more than one audio formats... */
- runtime->hw.period_bytes_min = runtime->hw.period_bytes_max =
- fp->frame_size;
- }
- pt = 125 * (1 << fp->datainterval);
- ptmin = min(ptmin, pt);
- }
- err = snd_usb_autoresume(subs->stream->chip);
- if (err < 0)
- return err;
-
- param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
- if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
- /* full speed devices have fixed data packet interval */
- ptmin = 1000;
- if (ptmin == 1000)
- /* if period time doesn't go below 1 ms, no rules needed */
- param_period_time_if_needed = -1;
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- ptmin, UINT_MAX);
-
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
- hw_rule_rate, subs,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- param_period_time_if_needed,
- -1)) < 0)
- goto rep_err;
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
- hw_rule_channels, subs,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_RATE,
- param_period_time_if_needed,
- -1)) < 0)
- goto rep_err;
- if ((err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
- hw_rule_format, subs,
- SNDRV_PCM_HW_PARAM_RATE,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- param_period_time_if_needed,
- -1)) < 0)
- goto rep_err;
- if (param_period_time_if_needed >= 0) {
- err = snd_pcm_hw_rule_add(runtime, 0,
- SNDRV_PCM_HW_PARAM_PERIOD_TIME,
- hw_rule_period_time, subs,
- SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- SNDRV_PCM_HW_PARAM_RATE,
- -1);
- if (err < 0)
- goto rep_err;
- }
- if ((err = snd_usb_pcm_check_knot(runtime, subs)) < 0)
- goto rep_err;
- return 0;
-
-rep_err:
- snd_usb_autosuspend(subs->stream->chip);
- return err;
-}
-
-static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction)
-{
- struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usb_substream *subs = &as->substream[direction];
-
- subs->interface = -1;
- subs->altset_idx = 0;
- runtime->hw = snd_usb_hardware;
- runtime->private_data = subs;
- subs->pcm_substream = substream;
- /* runtime PM is also done there */
- return setup_hw_info(runtime, subs);
-}
-
-static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
-{
- struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
- struct snd_usb_substream *subs = &as->substream[direction];
-
- if (!as->chip->shutdown && subs->interface >= 0) {
- usb_set_interface(subs->dev, subs->interface, 0);
- subs->interface = -1;
- }
- subs->pcm_substream = NULL;
- snd_usb_autosuspend(subs->stream->chip);
- return 0;
-}
-
-static int snd_usb_playback_open(struct snd_pcm_substream *substream)
-{
- return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK);
-}
-
-static int snd_usb_playback_close(struct snd_pcm_substream *substream)
-{
- return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
-}
-
-static int snd_usb_capture_open(struct snd_pcm_substream *substream)
-{
- return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE);
-}
-
-static int snd_usb_capture_close(struct snd_pcm_substream *substream)
-{
- return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
-}
-
-static struct snd_pcm_ops snd_usb_playback_ops = {
- .open = snd_usb_playback_open,
- .close = snd_usb_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usb_hw_params,
- .hw_free = snd_usb_hw_free,
- .prepare = snd_usb_pcm_prepare,
- .trigger = snd_usb_substream_playback_trigger,
- .pointer = snd_usb_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-static struct snd_pcm_ops snd_usb_capture_ops = {
- .open = snd_usb_capture_open,
- .close = snd_usb_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usb_hw_params,
- .hw_free = snd_usb_hw_free,
- .prepare = snd_usb_pcm_prepare,
- .trigger = snd_usb_substream_capture_trigger,
- .pointer = snd_usb_pcm_pointer,
- .page = snd_pcm_lib_get_vmalloc_page,
- .mmap = snd_pcm_lib_mmap_vmalloc,
-};
-
-void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream)
-{
- snd_pcm_set_ops(pcm, stream,
- stream == SNDRV_PCM_STREAM_PLAYBACK ?
- &snd_usb_playback_ops : &snd_usb_capture_ops);
-}
diff --git a/ANDROID_3.4.5/sound/usb/pcm.h b/ANDROID_3.4.5/sound/usb/pcm.h
deleted file mode 100644
index df7a0036..00000000
--- a/ANDROID_3.4.5/sound/usb/pcm.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __USBAUDIO_PCM_H
-#define __USBAUDIO_PCM_H
-
-snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
- unsigned int rate);
-
-void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream);
-
-int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
- struct usb_host_interface *alts,
- struct audioformat *fmt);
-
-
-#endif /* __USBAUDIO_PCM_H */
diff --git a/ANDROID_3.4.5/sound/usb/power.h b/ANDROID_3.4.5/sound/usb/power.h
deleted file mode 100644
index 48ee51dc..00000000
--- a/ANDROID_3.4.5/sound/usb/power.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __USBAUDIO_POWER_H
-#define __USBAUDIO_POWER_H
-
-#ifdef CONFIG_PM
-int snd_usb_autoresume(struct snd_usb_audio *chip);
-void snd_usb_autosuspend(struct snd_usb_audio *chip);
-#else
-static inline int snd_usb_autoresume(struct snd_usb_audio *chip)
-{
- return 0;
-}
-static inline void snd_usb_autosuspend(struct snd_usb_audio *chip)
-{
-}
-#endif
-
-#endif /* __USBAUDIO_POWER_H */
diff --git a/ANDROID_3.4.5/sound/usb/proc.c b/ANDROID_3.4.5/sound/usb/proc.c
deleted file mode 100644
index 961c9a25..00000000
--- a/ANDROID_3.4.5/sound/usb/proc.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/init.h>
-#include <linux/usb.h>
-
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "helper.h"
-#include "card.h"
-#include "proc.h"
-
-/* convert our full speed USB rate into sampling rate in Hz */
-static inline unsigned get_full_speed_hz(unsigned int usb_rate)
-{
- return (usb_rate * 125 + (1 << 12)) >> 13;
-}
-
-/* convert our high speed USB rate into sampling rate in Hz */
-static inline unsigned get_high_speed_hz(unsigned int usb_rate)
-{
- return (usb_rate * 125 + (1 << 9)) >> 10;
-}
-
-/*
- * common proc files to show the usb device info
- */
-static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_usb_audio *chip = entry->private_data;
- if (!chip->shutdown)
- snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
-}
-
-static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_usb_audio *chip = entry->private_data;
- if (!chip->shutdown)
- snd_iprintf(buffer, "%04x:%04x\n",
- USB_ID_VENDOR(chip->usb_id),
- USB_ID_PRODUCT(chip->usb_id));
-}
-
-void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
-{
- struct snd_info_entry *entry;
- if (!snd_card_proc_new(chip->card, "usbbus", &entry))
- snd_info_set_text_ops(entry, chip, proc_audio_usbbus_read);
- if (!snd_card_proc_new(chip->card, "usbid", &entry))
- snd_info_set_text_ops(entry, chip, proc_audio_usbid_read);
-}
-
-/*
- * proc interface for list the supported pcm formats
- */
-static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
-{
- struct list_head *p;
- static char *sync_types[4] = {
- "NONE", "ASYNC", "ADAPTIVE", "SYNC"
- };
-
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- snd_pcm_format_t fmt;
- fp = list_entry(p, struct audioformat, list);
- snd_iprintf(buffer, " Interface %d\n", fp->iface);
- snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
- snd_iprintf(buffer, " Format:");
- for (fmt = 0; fmt <= SNDRV_PCM_FORMAT_LAST; ++fmt)
- if (fp->formats & (1uLL << fmt))
- snd_iprintf(buffer, " %s",
- snd_pcm_format_name(fmt));
- snd_iprintf(buffer, "\n");
- snd_iprintf(buffer, " Channels: %d\n", fp->channels);
- snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
- fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
- fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
- sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
- if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
- snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
- fp->rate_min, fp->rate_max);
- } else {
- unsigned int i;
- snd_iprintf(buffer, " Rates: ");
- for (i = 0; i < fp->nr_rates; i++) {
- if (i > 0)
- snd_iprintf(buffer, ", ");
- snd_iprintf(buffer, "%d", fp->rate_table[i]);
- }
- snd_iprintf(buffer, "\n");
- }
- if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
- snd_iprintf(buffer, " Data packet interval: %d us\n",
- 125 * (1 << fp->datainterval));
- // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
- // snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
- }
-}
-
-static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
-{
- if (subs->running) {
- unsigned int i;
- snd_iprintf(buffer, " Status: Running\n");
- snd_iprintf(buffer, " Interface = %d\n", subs->interface);
- snd_iprintf(buffer, " Altset = %d\n", subs->altset_idx);
- snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs);
- for (i = 0; i < subs->nurbs; i++)
- snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
- snd_iprintf(buffer, "]\n");
- snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize);
- snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
- snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
- ? get_full_speed_hz(subs->freqm)
- : get_high_speed_hz(subs->freqm),
- subs->freqm >> 16, subs->freqm & 0xffff);
- if (subs->freqshift != INT_MIN)
- snd_iprintf(buffer, " Feedback Format = %d.%d\n",
- (subs->syncmaxsize > 3 ? 32 : 24)
- - (16 - subs->freqshift),
- 16 - subs->freqshift);
- } else {
- snd_iprintf(buffer, " Status: Stop\n");
- }
-}
-
-static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
-{
- struct snd_usb_stream *stream = entry->private_data;
-
- snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
-
- if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
- snd_iprintf(buffer, "\nPlayback:\n");
- proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
- proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
- }
- if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
- snd_iprintf(buffer, "\nCapture:\n");
- proc_dump_substream_status(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
- proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
- }
-}
-
-void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream)
-{
- struct snd_info_entry *entry;
- char name[32];
- struct snd_card *card = stream->chip->card;
-
- sprintf(name, "stream%d", stream->pcm_index);
- if (!snd_card_proc_new(card, name, &entry))
- snd_info_set_text_ops(entry, stream, proc_pcm_format_read);
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/proc.h b/ANDROID_3.4.5/sound/usb/proc.h
deleted file mode 100644
index a45b765e..00000000
--- a/ANDROID_3.4.5/sound/usb/proc.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __USBAUDIO_PROC_H
-#define __USBAUDIO_PROC_H
-
-void snd_usb_audio_create_proc(struct snd_usb_audio *chip);
-void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream);
-
-#endif /* __USBAUDIO_PROC_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/quirks-table.h b/ANDROID_3.4.5/sound/usb/quirks-table.h
deleted file mode 100644
index d89ab4c7..00000000
--- a/ANDROID_3.4.5/sound/usb/quirks-table.h
+++ /dev/null
@@ -1,2769 +0,0 @@
-/*
- * ALSA USB Audio Driver
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>,
- * Clemens Ladisch <clemens@ladisch.de>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * The contents of this file are part of the driver's id_table.
- *
- * In a perfect world, this file would be empty.
- */
-
-/*
- * Use this for devices where other interfaces are standard compliant,
- * to prevent the quirk being applied to those interfaces. (To work with
- * hotplugging, bDeviceClass must be set to USB_CLASS_PER_INTERFACE.)
- */
-#define USB_DEVICE_VENDOR_SPEC(vend, prod) \
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR | \
- USB_DEVICE_ID_MATCH_PRODUCT | \
- USB_DEVICE_ID_MATCH_INT_CLASS, \
- .idVendor = vend, \
- .idProduct = prod, \
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC
-
-/* FTDI devices */
-{
- USB_DEVICE(0x0403, 0xb8d8),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "STARR LABS", */
- /* .product_name = "Starr Labs MIDI USB device", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FTDI
- }
-},
-
-/* Creative/Toshiba Multimedia Center SB-0500 */
-{
- USB_DEVICE(0x041e, 0x3048),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Toshiba",
- .product_name = "SB-0500",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-
-/* Creative/E-Mu devices */
-{
- USB_DEVICE(0x041e, 0x3010),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Creative Labs",
- .product_name = "Sound Blaster MP3+",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-{
- /* E-Mu 0202 USB */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x041e,
- .idProduct = 0x3f02,
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-{
- /* E-Mu 0404 USB */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x041e,
- .idProduct = 0x3f04,
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-{
- /* E-Mu Tracker Pre */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x041e,
- .idProduct = 0x3f0a,
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-{
- /* E-Mu 0204 USB */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x041e,
- .idProduct = 0x3f19,
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-
-/*
- * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
- * class matches do not take effect without an explicit ID match.
- */
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x0850,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08ae,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08c6,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08f0,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08f5,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .idVendor = 0x046d,
- .idProduct = 0x08f6,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL
-},
-{
- USB_DEVICE(0x046d, 0x0990),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Logitech, Inc.",
- .product_name = "QuickCam Pro 9000",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-
-/*
- * Yamaha devices
- */
-
-#define YAMAHA_DEVICE(id, name) { \
- USB_DEVICE(0x0499, id), \
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \
- .vendor_name = "Yamaha", \
- .product_name = name, \
- .ifnum = QUIRK_ANY_INTERFACE, \
- .type = QUIRK_MIDI_YAMAHA \
- } \
-}
-#define YAMAHA_INTERFACE(id, intf, name) { \
- USB_DEVICE_VENDOR_SPEC(0x0499, id), \
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \
- .vendor_name = "Yamaha", \
- .product_name = name, \
- .ifnum = intf, \
- .type = QUIRK_MIDI_YAMAHA \
- } \
-}
-YAMAHA_DEVICE(0x1000, "UX256"),
-YAMAHA_DEVICE(0x1001, "MU1000"),
-YAMAHA_DEVICE(0x1002, "MU2000"),
-YAMAHA_DEVICE(0x1003, "MU500"),
-YAMAHA_INTERFACE(0x1004, 3, "UW500"),
-YAMAHA_DEVICE(0x1005, "MOTIF6"),
-YAMAHA_DEVICE(0x1006, "MOTIF7"),
-YAMAHA_DEVICE(0x1007, "MOTIF8"),
-YAMAHA_DEVICE(0x1008, "UX96"),
-YAMAHA_DEVICE(0x1009, "UX16"),
-YAMAHA_INTERFACE(0x100a, 3, "EOS BX"),
-YAMAHA_DEVICE(0x100c, "UC-MX"),
-YAMAHA_DEVICE(0x100d, "UC-KX"),
-YAMAHA_DEVICE(0x100e, "S08"),
-YAMAHA_DEVICE(0x100f, "CLP-150"),
-YAMAHA_DEVICE(0x1010, "CLP-170"),
-YAMAHA_DEVICE(0x1011, "P-250"),
-YAMAHA_DEVICE(0x1012, "TYROS"),
-YAMAHA_DEVICE(0x1013, "PF-500"),
-YAMAHA_DEVICE(0x1014, "S90"),
-YAMAHA_DEVICE(0x1015, "MOTIF-R"),
-YAMAHA_DEVICE(0x1016, "MDP-5"),
-YAMAHA_DEVICE(0x1017, "CVP-204"),
-YAMAHA_DEVICE(0x1018, "CVP-206"),
-YAMAHA_DEVICE(0x1019, "CVP-208"),
-YAMAHA_DEVICE(0x101a, "CVP-210"),
-YAMAHA_DEVICE(0x101b, "PSR-1100"),
-YAMAHA_DEVICE(0x101c, "PSR-2100"),
-YAMAHA_DEVICE(0x101d, "CLP-175"),
-YAMAHA_DEVICE(0x101e, "PSR-K1"),
-YAMAHA_DEVICE(0x101f, "EZ-J24"),
-YAMAHA_DEVICE(0x1020, "EZ-250i"),
-YAMAHA_DEVICE(0x1021, "MOTIF ES 6"),
-YAMAHA_DEVICE(0x1022, "MOTIF ES 7"),
-YAMAHA_DEVICE(0x1023, "MOTIF ES 8"),
-YAMAHA_DEVICE(0x1024, "CVP-301"),
-YAMAHA_DEVICE(0x1025, "CVP-303"),
-YAMAHA_DEVICE(0x1026, "CVP-305"),
-YAMAHA_DEVICE(0x1027, "CVP-307"),
-YAMAHA_DEVICE(0x1028, "CVP-309"),
-YAMAHA_DEVICE(0x1029, "CVP-309GP"),
-YAMAHA_DEVICE(0x102a, "PSR-1500"),
-YAMAHA_DEVICE(0x102b, "PSR-3000"),
-YAMAHA_DEVICE(0x102e, "ELS-01/01C"),
-YAMAHA_DEVICE(0x1030, "PSR-295/293"),
-YAMAHA_DEVICE(0x1031, "DGX-205/203"),
-YAMAHA_DEVICE(0x1032, "DGX-305"),
-YAMAHA_DEVICE(0x1033, "DGX-505"),
-YAMAHA_DEVICE(0x1034, NULL),
-YAMAHA_DEVICE(0x1035, NULL),
-YAMAHA_DEVICE(0x1036, NULL),
-YAMAHA_DEVICE(0x1037, NULL),
-YAMAHA_DEVICE(0x1038, NULL),
-YAMAHA_DEVICE(0x1039, NULL),
-YAMAHA_DEVICE(0x103a, NULL),
-YAMAHA_DEVICE(0x103b, NULL),
-YAMAHA_DEVICE(0x103c, NULL),
-YAMAHA_DEVICE(0x103d, NULL),
-YAMAHA_DEVICE(0x103e, NULL),
-YAMAHA_DEVICE(0x103f, NULL),
-YAMAHA_DEVICE(0x1040, NULL),
-YAMAHA_DEVICE(0x1041, NULL),
-YAMAHA_DEVICE(0x1042, NULL),
-YAMAHA_DEVICE(0x1043, NULL),
-YAMAHA_DEVICE(0x1044, NULL),
-YAMAHA_DEVICE(0x1045, NULL),
-YAMAHA_INTERFACE(0x104e, 0, NULL),
-YAMAHA_DEVICE(0x104f, NULL),
-YAMAHA_DEVICE(0x1050, NULL),
-YAMAHA_DEVICE(0x1051, NULL),
-YAMAHA_DEVICE(0x1052, NULL),
-YAMAHA_INTERFACE(0x1053, 0, NULL),
-YAMAHA_INTERFACE(0x1054, 0, NULL),
-YAMAHA_DEVICE(0x1055, NULL),
-YAMAHA_DEVICE(0x1056, NULL),
-YAMAHA_DEVICE(0x1057, NULL),
-YAMAHA_DEVICE(0x1058, NULL),
-YAMAHA_DEVICE(0x1059, NULL),
-YAMAHA_DEVICE(0x105a, NULL),
-YAMAHA_DEVICE(0x105b, NULL),
-YAMAHA_DEVICE(0x105c, NULL),
-YAMAHA_DEVICE(0x105d, NULL),
-{
- USB_DEVICE(0x0499, 0x1503),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Yamaha", */
- /* .product_name = "MOX6/MOX8", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_YAMAHA
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-YAMAHA_DEVICE(0x2000, "DGP-7"),
-YAMAHA_DEVICE(0x2001, "DGP-5"),
-YAMAHA_DEVICE(0x2002, NULL),
-YAMAHA_DEVICE(0x2003, NULL),
-YAMAHA_DEVICE(0x5000, "CS1D"),
-YAMAHA_DEVICE(0x5001, "DSP1D"),
-YAMAHA_DEVICE(0x5002, "DME32"),
-YAMAHA_DEVICE(0x5003, "DM2000"),
-YAMAHA_DEVICE(0x5004, "02R96"),
-YAMAHA_DEVICE(0x5005, "ACU16-C"),
-YAMAHA_DEVICE(0x5006, "NHB32-C"),
-YAMAHA_DEVICE(0x5007, "DM1000"),
-YAMAHA_DEVICE(0x5008, "01V96"),
-YAMAHA_DEVICE(0x5009, "SPX2000"),
-YAMAHA_DEVICE(0x500a, "PM5D"),
-YAMAHA_DEVICE(0x500b, "DME64N"),
-YAMAHA_DEVICE(0x500c, "DME24N"),
-YAMAHA_DEVICE(0x500d, NULL),
-YAMAHA_DEVICE(0x500e, NULL),
-YAMAHA_DEVICE(0x500f, NULL),
-YAMAHA_DEVICE(0x7000, "DTX"),
-YAMAHA_DEVICE(0x7010, "UB99"),
-#undef YAMAHA_DEVICE
-#undef YAMAHA_INTERFACE
-
-/*
- * Roland/RolandED/Edirol/BOSS devices
- */
-{
- USB_DEVICE(0x0582, 0x0000),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "UA-100",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels = 4,
- .iface = 0,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x01,
- .ep_attr = 0x09,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
- .channels = 2,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_FILL_MAX,
- .endpoint = 0x81,
- .ep_attr = 0x05,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0007,
- .in_cables = 0x0007
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0002),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-4",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0003),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SC-8850",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x003f,
- .in_cables = 0x003f
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0004),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "U-8",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0005,
- .in_cables = 0x0005
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Has ID 0x0099 when not in "Advanced Driver" mode.
- * The UM-2EX has only one input, but we cannot detect this. */
- USB_DEVICE(0x0582, 0x0005),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-2",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0007),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SC-8820",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0013,
- .in_cables = 0x0013
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0008),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "PC-300",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x009d when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0009),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-1",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x000b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SK-500",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0013,
- .in_cables = 0x0013
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* thanks to Emiliano Grilli <emillo@libero.it>
- * for helping researching this data */
- USB_DEVICE(0x0582, 0x000c),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SC-D70",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .iface = 0,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x01,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x81,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0007,
- .in_cables = 0x0007
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{ /*
- * This quirk is for the "Advanced Driver" mode of the Edirol UA-5.
- * If the advanced mode switch at the back of the unit is off, the
- * UA-5 has ID 0x0582/0x0011 and is standard compliant (no quirks),
- * but offers only 16-bit PCM.
- * In advanced mode, the UA-5 will output S24_3LE samples (two
- * channels) at the rate indicated on the front switch, including
- * the 96kHz sample rate.
- */
- USB_DEVICE(0x0582, 0x0010),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-5",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0013 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0012),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "XV-5050",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0015 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0014),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-880",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x01ff,
- .in_cables = 0x01ff
- }
- }
-},
-{
- /* has ID 0x0017 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0016),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "SD-90",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x001c when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x001b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "MMP-2",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x001e when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x001d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "V-SYNTH",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0024 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0023),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-550",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x003f,
- .in_cables = 0x003f
- }
- }
-},
-{
- /*
- * This quirk is for the "Advanced Driver" mode. If off, the UA-20
- * has ID 0x0026 and is standard compliant, but has only 16-bit PCM
- * and no MIDI.
- */
- USB_DEVICE(0x0582, 0x0025),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-20",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x01,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 2,
- .iface = 2,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = 0,
- .endpoint = 0x82,
- .ep_attr = 0x01,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 44100,
- .rate_max = 44100,
- }
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0028 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0027),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "SD-20",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
-{
- /* has ID 0x002a when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0029),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "SD-80",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- }
-},
-{ /*
- * This quirk is for the "Advanced" modes of the Edirol UA-700.
- * If the sample format switch is not in an advanced setting, the
- * UA-700 has ID 0x0582/0x002c and is standard compliant (no quirks),
- * but offers only 16-bit PCM and no MIDI.
- */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x002b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-700",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 3,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x002e when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x002d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "XV-2020",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0030 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x002f),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "VariOS",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0007,
- .in_cables = 0x0007
- }
- }
-},
-{
- /* has ID 0x0034 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0033),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "PCR",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
- /* TODO: add Roland M-1000 support */
-{
- /*
- * Has ID 0x0038 when not in "Advanced Driver" mode;
- * later revisions use IDs 0x0054 and 0x00a2.
- */
- USB_DEVICE(0x0582, 0x0037),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "Digital Piano",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /*
- * This quirk is for the "Advanced Driver" mode. If off, the GS-10
- * has ID 0x003c and is standard compliant, but has only 16-bit PCM
- * and no MIDI.
- */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x003b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "BOSS",
- .product_name = "GS-10",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0041 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0040),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "GI-20",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0043 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0042),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "RS-70",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x0049 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0047),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "EDIROL", */
- /* .product_name = "UR-80", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- /* in the 96 kHz modes, only interface 1 is there */
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x004a when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0048),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "EDIROL", */
- /* .product_name = "UR-80", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
- /* TODO: add Edirol M-100FX support */
-{
- /* has ID 0x004e when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x004c),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "PCR-A",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x004f when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x004d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "PCR-A",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
-{
- /*
- * This quirk is for the "Advanced Driver" mode. If off, the UA-3FX
- * is standard compliant, but has only 16-bit PCM.
- */
- USB_DEVICE(0x0582, 0x0050),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-3FX",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0052),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-1SX",
- .ifnum = 0,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- USB_DEVICE(0x0582, 0x0060),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "EXR Series",
- .ifnum = 0,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- /* has ID 0x0066 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0064),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "EDIROL", */
- /* .product_name = "PCR-1", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0067 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0065),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "EDIROL", */
- /* .product_name = "PCR-1", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0003
- }
- }
-},
-{
- /* has ID 0x006b when not in "Advanced Driver" mode */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x006a),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SP-606",
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x006e when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x006d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "FANTOM-X",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{ /*
- * This quirk is for the "Advanced" modes of the Edirol UA-25.
- * If the switch is not in an advanced setting, the UA-25 has
- * ID 0x0582/0x0073 and is standard compliant (no quirks), but
- * offers only 16-bit PCM at 44.1 kHz and no MIDI.
- */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x0074),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-25",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0076 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0075),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "BOSS",
- .product_name = "DR-880",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* has ID 0x007b when not in "Advanced Driver" mode */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x007a),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- /* "RD" or "RD-700SX"? */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- }
-},
-{
- /* has ID 0x0081 when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x0080),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "G-70",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
- /* TODO: add Roland V-SYNTH XT support */
- /* TODO: add BOSS GT-PRO support */
-{
- /* has ID 0x008c when not in "Advanced Driver" mode */
- USB_DEVICE(0x0582, 0x008b),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "PC-50",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
- /* TODO: add Edirol PC-80 support */
-{
- USB_DEVICE(0x0582, 0x0096),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-1EX",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x009a),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UM-3EX",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- }
-},
-{
- /*
- * This quirk is for the "Advanced Driver" mode. If off, the UA-4FX
- * is standard compliant, but has only 16-bit PCM and no MIDI.
- */
- USB_DEVICE(0x0582, 0x00a3),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-4FX",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = -1
- }
- }
- }
-},
- /* TODO: add Edirol MD-P1 support */
-{
- USB_DEVICE(0x582, 0x00a6),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "Juno-G",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* Roland SH-201 */
- USB_DEVICE(0x0582, 0x00ad),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SH-201",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Roland SonicCell */
- USB_DEVICE(0x0582, 0x00c2),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "SonicCell",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Edirol M-16DX */
- /* FIXME: This quirk gives a good-working capture stream but the
- * playback seems problematic because of lacking of sync
- * with capture stream. It needs to sync with the capture
- * clock. As now, you'll get frequent sound distortions
- * via the playback.
- */
- USB_DEVICE(0x0582, 0x00c4),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* BOSS GT-10 */
- USB_DEVICE(0x0582, 0x00da),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Advanced modes of the Edirol UA-25EX.
- * For the standard mode, UA-25EX has ID 0582:00e7, which
- * offers only 16-bit PCM at 44.1 kHz and no MIDI.
- */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e6),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "EDIROL",
- .product_name = "UA-25EX",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_EDIROL_UAXX
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x00ea when not in Advanced Driver mode */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e9),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Roland", */
- /* .product_name = "UA-1G", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x0104),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Roland", */
- /* .product_name = "UM-1G", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- /* Edirol UM-3G */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = 0,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- /* Boss JS-8 Jam Station */
- USB_DEVICE(0x0582, 0x0109),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "BOSS", */
- /* .product_name = "JS-8", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* has ID 0x0110 when not in Advanced Driver mode */
- USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Roland", */
- /* .product_name = "A-PRO", */
- .ifnum = 1,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0007
- }
- }
-},
-{
- /* Roland GAIA SH-01 */
- USB_DEVICE(0x0582, 0x0111),
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Roland",
- .product_name = "GAIA",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &(const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0113),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "BOSS", */
- /* .product_name = "ME-25", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0127),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Roland", */
- /* .product_name = "GR-55", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- /* Added support for Roland UM-ONE which differs from UM-1 */
- USB_DEVICE(0x0582, 0x012a),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "ROLAND", */
- /* .product_name = "UM-ONE", */
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0003
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x011e),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "BOSS", */
- /* .product_name = "BR-800", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0582, 0x0130),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "BOSS", */
- /* .product_name = "MICRO BR-80", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-
-/* Guillemot devices */
-{
- /*
- * This is for the "Windows Edition" where the external MIDI ports are
- * the only MIDI ports; the control data is reported through HID
- * interfaces. The "Macintosh Edition" has ID 0xd002 and uses standard
- * compliant USB MIDI ports for external MIDI and controls.
- */
- USB_DEVICE_VENDOR_SPEC(0x06f8, 0xb000),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Hercules",
- .product_name = "DJ Console (WE)",
- .ifnum = 4,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-
-/* Midiman/M-Audio devices */
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1002),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 2x2",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1011),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 1x1",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1015),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "Keystation",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1021),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 4x4",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x000f
- }
- }
-},
-{
- /*
- * For hardware revision 1.05; in the later revisions (1.10 and
- * 1.21), 0x1031 is the ID for the device without firmware.
- * Thanks to Olaf Giesbrecht <Olaf_Giesbrecht@yahoo.de>
- */
- USB_DEVICE_VER(0x0763, 0x1031, 0x0100, 0x0109),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 8x8",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x01ff,
- .in_cables = 0x01ff
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1033),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 8x8",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x01ff,
- .in_cables = 0x01ff
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x1041),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "MidiSport 2x4",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x000f,
- .in_cables = 0x0003
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2001),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "Quattro",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- /*
- * Interfaces 0-2 are "Windows-compatible", 16-bit only,
- * and share endpoints with the other interfaces.
- * Ignore them. The other interfaces can do 24 bits,
- * but captured samples are big-endian (see usbaudio.c).
- */
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 4,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 5,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 6,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 7,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 8,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 9,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2003),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "AudioPhile",
- .ifnum = 6,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2008),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "Ozone",
- .ifnum = 3,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x200d),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "M-Audio",
- .product_name = "OmniStudio",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 4,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 5,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 6,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = 7,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 8,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 9,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE(0x0763, 0x2019),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "M-Audio", */
- /* .product_name = "Ozone Academic", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_STANDARD_INTERFACE
- },
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_MIDIMAN,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0001,
- .in_cables = 0x0001
- }
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "M-Audio", */
- /* .product_name = "Fast Track Ultra", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_MIXER,
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 8,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x01,
- .ep_attr = 0x09,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 44100,
- .rate_max = 96000,
- .nr_rates = 4,
- .rate_table = (unsigned int[]) {
- 44100, 48000, 88200, 96000
- }
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 8,
- .iface = 2,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x81,
- .ep_attr = 0x05,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 44100,
- .rate_max = 96000,
- .nr_rates = 4,
- .rate_table = (unsigned int[]) {
- 44100, 48000, 88200, 96000
- }
- }
- },
- /* interface 3 (MIDI) is standard compliant */
- {
- .ifnum = -1
- }
- }
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0763, 0x2081),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "M-Audio", */
- /* .product_name = "Fast Track Ultra 8R", */
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_AUDIO_STANDARD_MIXER,
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 8,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x01,
- .ep_attr = 0x09,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 44100,
- .rate_max = 96000,
- .nr_rates = 4,
- .rate_table = (unsigned int[]) {
- 44100, 48000, 88200, 96000
- }
- }
- },
- {
- .ifnum = 2,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = & (const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .channels = 8,
- .iface = 2,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x81,
- .ep_attr = 0x05,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000 |
- SNDRV_PCM_RATE_88200 |
- SNDRV_PCM_RATE_96000,
- .rate_min = 44100,
- .rate_max = 96000,
- .nr_rates = 4,
- .rate_table = (unsigned int[]) {
- 44100, 48000, 88200, 96000
- }
- }
- },
- /* interface 3 (MIDI) is standard compliant */
- {
- .ifnum = -1
- }
- }
- }
-},
-
-/* Casio devices */
-{
- USB_DEVICE(0x07cf, 0x6801),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Casio",
- .product_name = "PL-40R",
- .ifnum = 0,
- .type = QUIRK_MIDI_YAMAHA
- }
-},
-{
- /* this ID is used by several devices without a product ID */
- USB_DEVICE(0x07cf, 0x6802),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Casio",
- .product_name = "Keyboard",
- .ifnum = 0,
- .type = QUIRK_MIDI_YAMAHA
- }
-},
-
-/* Mark of the Unicorn devices */
-{
- /* thanks to Robert A. Lerche <ral 'at' msbit.com> */
- .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
- USB_DEVICE_ID_MATCH_PRODUCT |
- USB_DEVICE_ID_MATCH_DEV_SUBCLASS,
- .idVendor = 0x07fd,
- .idProduct = 0x0001,
- .bDeviceSubClass = 2,
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "MOTU",
- .product_name = "Fastlane",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = & (const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 0,
- .type = QUIRK_MIDI_RAW_BYTES
- },
- {
- .ifnum = 1,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-
-/* Emagic devices */
-{
- USB_DEVICE(0x086a, 0x0001),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Emagic",
- /* .product_name = "Unitor8", */
- .ifnum = 2,
- .type = QUIRK_MIDI_EMAGIC,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x80ff,
- .in_cables = 0x80ff
- }
- }
-},
-{
- USB_DEVICE(0x086a, 0x0002),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Emagic",
- /* .product_name = "AMT8", */
- .ifnum = 2,
- .type = QUIRK_MIDI_EMAGIC,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x80ff,
- .in_cables = 0x80ff
- }
- }
-},
-{
- USB_DEVICE(0x086a, 0x0003),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Emagic",
- /* .product_name = "MT4", */
- .ifnum = 2,
- .type = QUIRK_MIDI_EMAGIC,
- .data = & (const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x800f,
- .in_cables = 0x8003
- }
- }
-},
-
-/* KORG devices */
-{
- USB_DEVICE_VENDOR_SPEC(0x0944, 0x0200),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "KORG, Inc.",
- /* .product_name = "PANDORA PX5D", */
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE,
- }
-},
-
-{
- USB_DEVICE_VENDOR_SPEC(0x0944, 0x0201),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "KORG, Inc.",
- /* .product_name = "ToneLab ST", */
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE,
- }
-},
-
-/* AKAI devices */
-{
- USB_DEVICE(0x09e8, 0x0062),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "AKAI",
- .product_name = "MPD16",
- .ifnum = 0,
- .type = QUIRK_MIDI_AKAI,
- }
-},
-
-/* TerraTec devices */
-{
- USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "TerraTec",
- .product_name = "PHASE 26",
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0013),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "TerraTec",
- .product_name = "PHASE 26",
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0014),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "TerraTec",
- .product_name = "PHASE 26",
- .ifnum = 3,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-{
- USB_DEVICE(0x0ccd, 0x0028),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "TerraTec",
- .product_name = "Aureon5.1MkII",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-{
- USB_DEVICE(0x0ccd, 0x0035),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Miditech",
- .product_name = "Play'n Roll",
- .ifnum = 0,
- .type = QUIRK_MIDI_CME
- }
-},
-
-/* Stanton/N2IT Final Scratch v1 device ('Scratchamp') */
-{
- USB_DEVICE(0x103d, 0x0100),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Stanton",
- .product_name = "ScratchAmp",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-{
- USB_DEVICE(0x103d, 0x0101),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Stanton",
- .product_name = "ScratchAmp",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-
-/* Novation EMS devices */
-{
- USB_DEVICE_VENDOR_SPEC(0x1235, 0x0001),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Novation",
- .product_name = "ReMOTE Audio/XStation",
- .ifnum = 4,
- .type = QUIRK_MIDI_NOVATION
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x1235, 0x0002),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Novation",
- .product_name = "Speedio",
- .ifnum = 3,
- .type = QUIRK_MIDI_NOVATION
- }
-},
-{
- USB_DEVICE(0x1235, 0x000e),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- /* .vendor_name = "Novation", */
- /* .product_name = "Launchpad", */
- .ifnum = 0,
- .type = QUIRK_MIDI_RAW_BYTES
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x1235, 0x4661),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Novation",
- .product_name = "ReMOTE25",
- .ifnum = 0,
- .type = QUIRK_MIDI_NOVATION
- }
-},
-
-/* Access Music devices */
-{
- /* VirusTI Desktop */
- USB_DEVICE_VENDOR_SPEC(0x133e, 0x0815),
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = &(const struct snd_usb_audio_quirk[]) {
- {
- .ifnum = 3,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &(const struct snd_usb_midi_endpoint_info) {
- .out_cables = 0x0003,
- .in_cables = 0x0003
- }
- },
- {
- .ifnum = 4,
- .type = QUIRK_IGNORE_INTERFACE
- },
- {
- .ifnum = -1
- }
- }
- }
-},
-
-/* */
-{
- /* aka. Serato Scratch Live DJ Box */
- USB_DEVICE(0x13e5, 0x0001),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Rane",
- .product_name = "SL-1",
- .ifnum = QUIRK_NO_INTERFACE
- }
-},
-
-/* Native Instruments MK2 series */
-{
- /* Komplete Audio 6 */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x17cc,
- .idProduct = 0x1000,
-},
-{
- /* Traktor Audio 6 */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x17cc,
- .idProduct = 0x1010,
-},
-{
- /* Traktor Audio 10 */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x17cc,
- .idProduct = 0x1020,
-},
-
-/* KeithMcMillen Stringport */
-{
- USB_DEVICE(0x1f38, 0x0001),
- .bInterfaceClass = USB_CLASS_AUDIO,
-},
-
-/* Miditech devices */
-{
- USB_DEVICE(0x4752, 0x0011),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .vendor_name = "Miditech",
- .product_name = "Midistart-2",
- .ifnum = 0,
- .type = QUIRK_MIDI_CME
- }
-},
-
-/* Central Music devices */
-{
- /* this ID used by both Miditech MidiStudio-2 and CME UF-x */
- USB_DEVICE(0x7104, 0x2202),
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = 0,
- .type = QUIRK_MIDI_CME
- }
-},
-
-/* Hauppauge HVR-950Q and HVR-850 */
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7200),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-850",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7217),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x721b),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x721e),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x721f),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x2040, 0x7280),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-{
- USB_DEVICE_VENDOR_SPEC(0x0fd9, 0x0008),
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Hauppauge",
- .product_name = "HVR-950Q",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_AUDIO_ALIGN_TRANSFER,
- }
-},
-
-/* Digidesign Mbox */
-{
- /* Thanks to Clemens Ladisch <clemens@ladisch.de> */
- USB_DEVICE(0x0dba, 0x1000),
- .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
- .vendor_name = "Digidesign",
- .product_name = "MBox",
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_COMPOSITE,
- .data = (const struct snd_usb_audio_quirk[]){
- {
- .ifnum = 0,
- .type = QUIRK_IGNORE_INTERFACE,
- },
- {
- .ifnum = 1,
- .type = QUIRK_AUDIO_FIXED_ENDPOINT,
- .data = &(const struct audioformat) {
- .formats = SNDRV_PCM_FMTBIT_S24_3BE,
- .channels = 2,
- .iface = 1,
- .altsetting = 1,
- .altset_idx = 1,
- .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
- .endpoint = 0x02,
- .ep_attr = 0x01,
- .maxpacksize = 0x130,
- .rates = SNDRV_PCM_RATE_44100 |
- SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .nr_rates = 2,
- .rate_table = (unsigned int[]) {
- 44100, 48000
- }
- }
- },
- {
- .ifnum = -1
- }
- }
-
- }
-},
-
-{
- /*
- * Some USB MIDI devices don't have an audio control interface,
- * so we have to grab MIDI streaming interfaces here.
- */
- .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_AUDIO,
- .bInterfaceSubClass = USB_SUBCLASS_MIDISTREAMING,
- .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
- .ifnum = QUIRK_ANY_INTERFACE,
- .type = QUIRK_MIDI_STANDARD_INTERFACE
- }
-},
-
-#undef USB_DEVICE_VENDOR_SPEC
diff --git a/ANDROID_3.4.5/sound/usb/quirks.c b/ANDROID_3.4.5/sound/usb/quirks.c
deleted file mode 100644
index 27817266..00000000
--- a/ANDROID_3.4.5/sound/usb/quirks.c
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "mixer.h"
-#include "mixer_quirks.h"
-#include "midi.h"
-#include "quirks.h"
-#include "helper.h"
-#include "endpoint.h"
-#include "pcm.h"
-#include "clock.h"
-#include "stream.h"
-
-/*
- * 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,
- const struct snd_usb_audio_quirk *quirk)
-{
- int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
- int err;
-
- for (quirk = quirk->data; quirk->ifnum >= 0; ++quirk) {
- 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;
- if (quirk->ifnum != probed_ifnum)
- usb_driver_claim_interface(driver, iface, (void *)-1L);
- }
- 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;
-}
-
-
-/*
- * Allow alignment on audio sub-slot (channel samples) rather than
- * on audio slots (audio frames)
- */
-static int create_align_transfer_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- chip->txfr_quirk = 1;
- return 1; /* Continue with creating streams and mixer */
-}
-
-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);
- err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber);
- if (err < 0) {
- snd_printk(KERN_ERR "cannot setup if %d: error %d\n",
- altsd->bInterfaceNumber, err);
- return err;
- }
- /* reset the current interface */
- usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
- return 0;
-}
-
-/*
- * 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;
- int stream, err;
- unsigned *rate_table = NULL;
-
- fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
- if (!fp) {
- snd_printk(KERN_ERR "cannot memdup\n");
- return -ENOMEM;
- }
- if (fp->nr_rates > MAX_NR_RATES) {
- kfree(fp);
- return -EINVAL;
- }
- if (fp->nr_rates > 0) {
- rate_table = kmemdup(fp->rate_table,
- sizeof(int) * fp->nr_rates, GFP_KERNEL);
- if (!rate_table) {
- kfree(fp);
- return -ENOMEM;
- }
- fp->rate_table = rate_table;
- }
-
- stream = (fp->endpoint & USB_DIR_IN)
- ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- err = snd_usb_add_audio_stream(chip, stream, fp);
- if (err < 0) {
- kfree(fp);
- kfree(rate_table);
- return err;
- }
- if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
- fp->altset_idx >= iface->num_altsetting) {
- kfree(fp);
- kfree(rate_table);
- return -EINVAL;
- }
- alts = &iface->altsetting[fp->altset_idx];
- fp->datainterval = snd_usb_parse_datainterval(chip, alts);
- fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
- usb_set_interface(chip->dev, fp->iface, 0);
- snd_usb_init_pitch(chip, fp->iface, alts, fp);
- snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
- return 0;
-}
-
-/*
- * Create a stream for an Edirol UA-700/UA-25/UA-4FX 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 = {
- .formats = SNDRV_PCM_FMTBIT_S24_3LE,
- .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;
- int stream, err;
-
- /* 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;
- return snd_usbmidi_create(chip->card, iface,
- &chip->midi_list, quirk);
- }
-
- if (altsd->bNumEndpoints != 1)
- return -ENXIO;
-
- fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL);
- 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);
-
- 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:
- snd_printk(KERN_ERR "unknown sample rate\n");
- kfree(fp);
- return -ENXIO;
- }
-
- stream = (fp->endpoint & USB_DIR_IN)
- ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- err = snd_usb_add_audio_stream(chip, stream, fp);
- if (err < 0) {
- kfree(fp);
- return err;
- }
- usb_set_interface(chip->dev, fp->iface, 0);
- return 0;
-}
-
-/*
- * 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;
-
- return snd_usb_create_mixer(chip, quirk->ifnum, 0);
-}
-
-/*
- * audio-interface quirks
- *
- * returns zero if no standard audio/MIDI parsing is needed.
- * returns a positive value if standard audio/midi interfaces are parsed
- * 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,
- [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
- [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
- [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
- [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
- [QUIRK_MIDI_NOVATION] = 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,
- [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
- [QUIRK_MIDI_FTDI] = create_any_midi_quirk,
- [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
- [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
- [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
- [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
- [QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
- };
-
- if (quirk->type < QUIRK_TYPE_COUNT) {
- return quirk_funcs[quirk->type](chip, iface, driver, quirk);
- } else {
- snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
- 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) {
- snd_printdd("sending Extigy boot sequence...\n");
- /* Send message to force it to reconnect with full interface. */
- err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
- 0x10, 0x43, 0x0001, 0x000a, NULL, 0);
- if (err < 0) snd_printdd("error sending boot message: %d\n", err);
- err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
- &dev->descriptor, sizeof(dev->descriptor));
- config = dev->actconfig;
- if (err < 0) snd_printdd("error usb_get_descriptor: %d\n", err);
- err = usb_reset_configuration(dev);
- if (err < 0) snd_printdd("error usb_reset_configuration: %d\n", err);
- snd_printdd("extigy_boot: new boot length = %d\n",
- 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,
- 0, 0, &buf, 1);
- if (buf == 0) {
- snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- 1, 2000, NULL, 0);
- return -ENODEV;
- }
- return 0;
-}
-
-static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
-{
- int err;
-
- if (dev->actconfig->desc.bConfigurationValue == 1) {
- snd_printk(KERN_INFO "usb-audio: "
- "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);
- if (err < 0) {
- snd_printdd("error usb_driver_set_configuration: %d\n",
- err);
- return -ENODEV;
- }
- } else
- snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n");
-
- return 0;
-}
-
-/*
- * 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,
- 0, 0, &buf, 4);
-}
-
-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);
-}
-
-/*
- * C-Media CM6206 is based on CM106 with two additional
- * registers that are not documented in the data sheet.
- * Values here are chosen based on sniffing USB traffic
- * under Windows.
- */
-static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
-{
- int err = 0, reg;
- int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000};
-
- 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;
-}
-
-/*
- * 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 };
-
- void *buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
- 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;
-}
-
-/*
- * 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)
-{
- int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- cpu_to_le16(1), 0, NULL, 0, 1000);
-
- 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;
-}
-
-/*
- * Setup quirks
- */
-#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 */
-#define MAUDIO_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
-#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 */
-#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 */
-
-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 */
- }
- }
- snd_printdd(KERN_INFO
- "using altsetting %d for interface %d config %d\n",
- altno, iface, chip->setup);
- return 0; /* keep this altsetting */
-}
-
-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);
-
- if (chip->setup & MAUDIO_SET) {
- unsigned int mask;
- if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
- return 1; /* skip this altsetting */
- 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_DI && altno != 4)
- return 1; /* skip this altsetting */
- if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
- return 1; /* skip this altsetting */
- }
-
- return 0; /* keep this altsetting */
-}
-
-
-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;
- }
-
- snd_printdd(KERN_INFO
- "using altsetting %d for interface %d config %d\n",
- altno, iface, chip->setup);
- return 0; /* keep this altsetting */
-}
-
-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);
- /* 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);
-
- return 0;
-}
-
-int snd_usb_apply_boot_quirk(struct usb_device *dev,
- struct usb_interface *intf,
- const struct snd_usb_audio_quirk *quirk)
-{
- u32 id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- 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. */
- return snd_usb_extigy_boot_quirk(dev, intf);
-
- case USB_ID(0x041e, 0x3020):
- /* SB Audigy 2 NX needs its own boot-up magic, too */
- return snd_usb_audigy2nx_boot_quirk(dev);
-
- case USB_ID(0x10f5, 0x0200):
- /* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
- return snd_usb_cm106_boot_quirk(dev);
-
- case USB_ID(0x0d8c, 0x0102):
- /* C-Media CM6206 / CM106-Like Sound Device */
- case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
- return snd_usb_cm6206_boot_quirk(dev);
-
- case USB_ID(0x133e, 0x0815):
- /* Access Music VirusTI Desktop */
- return snd_usb_accessmusic_boot_quirk(dev);
-
- case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
- case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
- case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
- return snd_usb_nativeinstruments_boot_quirk(dev);
- case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
- return snd_usb_fasttrackpro_boot_quirk(dev);
- }
-
- return 0;
-}
-
-/*
- * check if the device uses big-endian samples
- */
-int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
-{
- /* it depends on altsetting wether the device is big-endian or not */
- switch (chip->usb_id) {
- case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
- if (fp->altsetting == 2 || fp->altsetting == 3 ||
- fp->altsetting == 5 || fp->altsetting == 6)
- return 1;
- break;
- case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
- if (chip->setup == 0x00 ||
- 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)
- return 1;
- break;
- }
- return 0;
-}
-
-/*
- * For E-Mu 0404USB/0202USB/TrackerPre/0204 sample rate should be set for device,
- * 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,
- struct audioformat *fmt)
-{
- 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) {
- if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].interface != -1)
- 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);
-}
-
-void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
- struct audioformat *fmt)
-{
- 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 */
- case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
- set_format_emu_quirk(subs, fmt);
- break;
- }
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/quirks.h b/ANDROID_3.4.5/sound/usb/quirks.h
deleted file mode 100644
index 03e5e940..00000000
--- a/ANDROID_3.4.5/sound/usb/quirks.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __USBAUDIO_QUIRKS_H
-#define __USBAUDIO_QUIRKS_H
-
-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);
-
-int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
- int iface,
- int altno);
-
-int snd_usb_apply_boot_quirk(struct usb_device *dev,
- struct usb_interface *intf,
- const struct snd_usb_audio_quirk *quirk);
-
-void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
- struct audioformat *fmt);
-
-int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
- struct audioformat *fp);
-
-#endif /* __USBAUDIO_QUIRKS_H */
diff --git a/ANDROID_3.4.5/sound/usb/stream.c b/ANDROID_3.4.5/sound/usb/stream.c
deleted file mode 100644
index 5ff8010b..00000000
--- a/ANDROID_3.4.5/sound/usb/stream.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/usb/audio-v2.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-
-#include "usbaudio.h"
-#include "card.h"
-#include "proc.h"
-#include "quirks.h"
-#include "endpoint.h"
-#include "pcm.h"
-#include "helper.h"
-#include "format.h"
-#include "clock.h"
-#include "stream.h"
-
-/*
- * free a substream
- */
-static void free_substream(struct snd_usb_substream *subs)
-{
- struct list_head *p, *n;
-
- if (!subs->num_formats)
- return; /* not initialized */
- list_for_each_safe(p, n, &subs->fmt_list) {
- struct audioformat *fp = list_entry(p, struct audioformat, list);
- kfree(fp->rate_table);
- kfree(fp);
- }
- kfree(subs->rate_list.list);
-}
-
-
-/*
- * free a usb stream instance
- */
-static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
-{
- free_substream(&stream->substream[0]);
- free_substream(&stream->substream[1]);
- list_del(&stream->list);
- kfree(stream);
-}
-
-static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
-{
- struct snd_usb_stream *stream = pcm->private_data;
- if (stream) {
- stream->pcm = NULL;
- snd_usb_audio_stream_free(stream);
- }
-}
-
-
-/*
- * add this endpoint to the chip instance.
- * if a stream with the same endpoint already exists, append to it.
- * if not, create a new pcm stream.
- */
-int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
- int stream,
- struct audioformat *fp)
-{
- struct list_head *p;
- struct snd_usb_stream *as;
- struct snd_usb_substream *subs;
- struct snd_pcm *pcm;
- int err;
-
- list_for_each(p, &chip->pcm_list) {
- as = list_entry(p, struct snd_usb_stream, list);
- if (as->fmt_type != fp->fmt_type)
- continue;
- subs = &as->substream[stream];
- if (!subs->endpoint)
- continue;
- if (subs->endpoint == fp->endpoint) {
- list_add_tail(&fp->list, &subs->fmt_list);
- subs->num_formats++;
- subs->formats |= fp->formats;
- return 0;
- }
- }
- /* look for an empty stream */
- list_for_each(p, &chip->pcm_list) {
- as = list_entry(p, struct snd_usb_stream, list);
- if (as->fmt_type != fp->fmt_type)
- continue;
- subs = &as->substream[stream];
- if (subs->endpoint)
- continue;
- err = snd_pcm_new_stream(as->pcm, stream, 1);
- if (err < 0)
- return err;
- snd_usb_init_substream(as, stream, fp);
- return 0;
- }
-
- /* create a new pcm */
- as = kzalloc(sizeof(*as), GFP_KERNEL);
- if (!as)
- return -ENOMEM;
- as->pcm_index = chip->pcm_devs;
- as->chip = chip;
- as->fmt_type = fp->fmt_type;
- err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs,
- stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0,
- stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1,
- &pcm);
- if (err < 0) {
- kfree(as);
- return err;
- }
- as->pcm = pcm;
- pcm->private_data = as;
- pcm->private_free = snd_usb_audio_pcm_free;
- pcm->info_flags = 0;
- if (chip->pcm_devs > 0)
- sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
- else
- strcpy(pcm->name, "USB Audio");
-
- snd_usb_init_substream(as, stream, fp);
-
- list_add(&as->list, &chip->pcm_list);
- chip->pcm_devs++;
-
- snd_usb_proc_pcm_format_add(as);
-
- return 0;
-}
-
-static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
- struct usb_host_interface *alts,
- int protocol, int iface_no)
-{
- /* parsed with a v1 header here. that's ok as we only look at the
- * header first which is the same for both versions */
- struct uac_iso_endpoint_descriptor *csep;
- struct usb_interface_descriptor *altsd = get_iface_desc(alts);
- int attributes = 0;
-
- csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
-
- /* Creamware Noah has this descriptor after the 2nd endpoint */
- if (!csep && altsd->bNumEndpoints >= 2)
- csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
-
- if (!csep || csep->bLength < 7 ||
- csep->bDescriptorSubtype != UAC_EP_GENERAL) {
- snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
- " class specific endpoint descriptor\n",
- chip->dev->devnum, iface_no,
- altsd->bAlternateSetting);
- return 0;
- }
-
- if (protocol == UAC_VERSION_1) {
- attributes = csep->bmAttributes;
- } else {
- struct uac2_iso_endpoint_descriptor *csep2 =
- (struct uac2_iso_endpoint_descriptor *) csep;
-
- attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX;
-
- /* emulate the endpoint attributes of a v1 device */
- if (csep2->bmControls & UAC2_CONTROL_PITCH)
- attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL;
- }
-
- return attributes;
-}
-
-static struct uac2_input_terminal_descriptor *
- snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
- int terminal_id)
-{
- struct uac2_input_terminal_descriptor *term = NULL;
-
- while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- term, UAC_INPUT_TERMINAL))) {
- if (term->bTerminalID == terminal_id)
- return term;
- }
-
- return NULL;
-}
-
-static struct uac2_output_terminal_descriptor *
- snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
- int terminal_id)
-{
- struct uac2_output_terminal_descriptor *term = NULL;
-
- while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
- ctrl_iface->extralen,
- term, UAC_OUTPUT_TERMINAL))) {
- if (term->bTerminalID == terminal_id)
- return term;
- }
-
- return NULL;
-}
-
-int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
-{
- struct usb_device *dev;
- struct usb_interface *iface;
- struct usb_host_interface *alts;
- struct usb_interface_descriptor *altsd;
- int i, altno, err, stream;
- int format = 0, num_channels = 0;
- struct audioformat *fp = NULL;
- int num, protocol, clock = 0;
- struct uac_format_type_i_continuous_descriptor *fmt;
-
- dev = chip->dev;
-
- /* parse the interface's altsettings */
- iface = usb_ifnum_to_if(dev, iface_no);
-
- num = iface->num_altsetting;
-
- /*
- * Dallas DS4201 workaround: It presents 5 altsettings, but the last
- * one misses syncpipe, and does not produce any sound.
- */
- if (chip->usb_id == USB_ID(0x04fa, 0x4201))
- num = 4;
-
- for (i = 0; i < num; i++) {
- alts = &iface->altsetting[i];
- altsd = get_iface_desc(alts);
- protocol = altsd->bInterfaceProtocol;
- /* skip invalid one */
- if ((altsd->bInterfaceClass != USB_CLASS_AUDIO &&
- altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
- (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING &&
- altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) ||
- altsd->bNumEndpoints < 1 ||
- le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0)
- continue;
- /* must be isochronous */
- if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
- USB_ENDPOINT_XFER_ISOC)
- continue;
- /* check direction */
- stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
- SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
- altno = altsd->bAlternateSetting;
-
- if (snd_usb_apply_interface_quirk(chip, iface_no, altno))
- continue;
-
- /* get audio formats */
- switch (protocol) {
- default:
- snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n",
- dev->devnum, iface_no, altno, protocol);
- protocol = UAC_VERSION_1;
- /* fall through */
-
- case UAC_VERSION_1: {
- struct uac1_as_header_descriptor *as =
- snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
-
- if (!as) {
- snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- if (as->bLength < sizeof(*as)) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- format = le16_to_cpu(as->wFormatTag); /* remember the format value */
- break;
- }
-
- case UAC_VERSION_2: {
- struct uac2_input_terminal_descriptor *input_term;
- struct uac2_output_terminal_descriptor *output_term;
- struct uac2_as_header_descriptor *as =
- snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
-
- if (!as) {
- snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- if (as->bLength < sizeof(*as)) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- num_channels = as->bNrChannels;
- format = le32_to_cpu(as->bmFormats);
-
- /* lookup the terminal associated to this interface
- * to extract the clock */
- input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
- as->bTerminalLink);
- if (input_term) {
- clock = input_term->bCSourceID;
- break;
- }
-
- output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
- as->bTerminalLink);
- if (output_term) {
- clock = output_term->bCSourceID;
- break;
- }
-
- snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n",
- dev->devnum, iface_no, altno, as->bTerminalLink);
- continue;
- }
- }
-
- /* get format type */
- fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE);
- if (!fmt) {
- snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n",
- dev->devnum, iface_no, altno);
- continue;
- }
- if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) ||
- ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) {
- snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n",
- dev->devnum, iface_no, altno);
- continue;
- }
-
- /*
- * Blue Microphones workaround: The last altsetting is identical
- * with the previous one, except for a larger packet size, but
- * is actually a mislabeled two-channel setting; ignore it.
- */
- if (fmt->bNrChannels == 1 &&
- fmt->bSubframeSize == 2 &&
- altno == 2 && num == 3 &&
- fp && fp->altsetting == 1 && fp->channels == 1 &&
- fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
- protocol == UAC_VERSION_1 &&
- le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
- fp->maxpacksize * 2)
- continue;
-
- fp = kzalloc(sizeof(*fp), GFP_KERNEL);
- if (! fp) {
- snd_printk(KERN_ERR "cannot malloc\n");
- return -ENOMEM;
- }
-
- fp->iface = iface_no;
- fp->altsetting = altno;
- fp->altset_idx = i;
- fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
- fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
- fp->datainterval = snd_usb_parse_datainterval(chip, alts);
- fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
- /* num_channels is only set for v2 interfaces */
- fp->channels = num_channels;
- if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
- fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
- * (fp->maxpacksize & 0x7ff);
- fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
- fp->clock = clock;
-
- /* some quirks for attributes here */
-
- 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 77d: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;
- }
-
- /* ok, let's parse further... */
- if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
- kfree(fp->rate_table);
- kfree(fp);
- fp = NULL;
- continue;
- }
-
- snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
- err = snd_usb_add_audio_stream(chip, stream, fp);
- if (err < 0) {
- kfree(fp->rate_table);
- kfree(fp);
- return err;
- }
- /* try to set the interface... */
- usb_set_interface(chip->dev, iface_no, altno);
- snd_usb_init_pitch(chip, iface_no, alts, fp);
- snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max);
- }
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/stream.h b/ANDROID_3.4.5/sound/usb/stream.h
deleted file mode 100644
index c97f679f..00000000
--- a/ANDROID_3.4.5/sound/usb/stream.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __USBAUDIO_STREAM_H
-#define __USBAUDIO_STREAM_H
-
-int snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
- int iface_no);
-
-int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
- int stream,
- struct audioformat *fp);
-
-#endif /* __USBAUDIO_STREAM_H */
-
diff --git a/ANDROID_3.4.5/sound/usb/usbaudio.h b/ANDROID_3.4.5/sound/usb/usbaudio.h
deleted file mode 100644
index 3e2b0357..00000000
--- a/ANDROID_3.4.5/sound/usb/usbaudio.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef __USBAUDIO_H
-#define __USBAUDIO_H
-/*
- * (Tentative) USB Audio Driver for ALSA
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* handling of USB vendor/product ID pairs as 32-bit numbers */
-#define USB_ID(vendor, product) (((vendor) << 16) | (product))
-#define USB_ID_VENDOR(id) ((id) >> 16)
-#define USB_ID_PRODUCT(id) ((u16)(id))
-
-/*
- *
- */
-
-struct snd_usb_audio {
- int index;
- struct usb_device *dev;
- struct snd_card *card;
- struct usb_interface *pm_intf;
- u32 usb_id;
- struct mutex shutdown_mutex;
- unsigned int shutdown:1;
- unsigned int probing:1;
- unsigned int autosuspended:1;
- unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
-
- int num_interfaces;
- int num_suspended_intf;
-
- struct list_head pcm_list; /* list of pcm streams */
- int pcm_devs;
-
- struct list_head midi_list; /* list of midi interfaces */
-
- struct list_head mixer_list; /* list of mixer interfaces */
-
- int setup; /* from the 'device_setup' module param */
- int nrpacks; /* from the 'nrpacks' module param */
- int async_unlink; /* from the 'async_unlink' module param */
-
- struct usb_host_interface *ctrl_intf; /* the audio control interface */
-};
-
-/*
- * Information about devices with broken descriptors
- */
-
-/* special values for .ifnum */
-#define QUIRK_NO_INTERFACE -2
-#define QUIRK_ANY_INTERFACE -1
-
-enum quirk_type {
- QUIRK_IGNORE_INTERFACE,
- QUIRK_COMPOSITE,
- QUIRK_MIDI_STANDARD_INTERFACE,
- QUIRK_MIDI_FIXED_ENDPOINT,
- QUIRK_MIDI_YAMAHA,
- QUIRK_MIDI_MIDIMAN,
- QUIRK_MIDI_NOVATION,
- QUIRK_MIDI_RAW_BYTES,
- QUIRK_MIDI_EMAGIC,
- QUIRK_MIDI_CME,
- QUIRK_MIDI_AKAI,
- QUIRK_MIDI_US122L,
- QUIRK_MIDI_FTDI,
- QUIRK_AUDIO_STANDARD_INTERFACE,
- QUIRK_AUDIO_FIXED_ENDPOINT,
- QUIRK_AUDIO_EDIROL_UAXX,
- QUIRK_AUDIO_ALIGN_TRANSFER,
- QUIRK_AUDIO_STANDARD_MIXER,
-
- QUIRK_TYPE_COUNT
-};
-
-struct snd_usb_audio_quirk {
- const char *vendor_name;
- const char *product_name;
- int16_t ifnum;
- uint16_t type;
- const void *data;
-};
-
-#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
-#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
-#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
-
-#endif /* __USBAUDIO_H */
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/Makefile b/ANDROID_3.4.5/sound/usb/usx2y/Makefile
deleted file mode 100644
index 74893305..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o
-snd-usb-us122l-objs := us122l.o
-
-obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o
-obj-$(CONFIG_SND_USB_US122L) += snd-usb-us122l.o
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/us122l.c b/ANDROID_3.4.5/sound/usb/usx2y/us122l.c
deleted file mode 100644
index c4fd3b1d..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/us122l.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/usb/audio.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/hwdep.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-#define MODNAME "US122L"
-#include "usb_stream.c"
-#include "../usbaudio.h"
-#include "../midi.h"
-#include "us122l.h"
-
-MODULE_AUTHOR("Karsten Wiese <fzu@wemgehoertderstaat.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.5");
-MODULE_LICENSE("GPL");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
- /* Enable this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
-
-static int snd_us122l_card_used[SNDRV_CARDS];
-
-
-static int us122l_create_usbmidi(struct snd_card *card)
-{
- static struct snd_usb_midi_endpoint_info quirk_data = {
- .out_ep = 4,
- .in_ep = 3,
- .out_cables = 0x001,
- .in_cables = 0x001
- };
- static struct snd_usb_audio_quirk quirk = {
- .vendor_name = "US122L",
- .product_name = NAME_ALLCAPS,
- .ifnum = 1,
- .type = QUIRK_MIDI_US122L,
- .data = &quirk_data
- };
- struct usb_device *dev = US122L(card)->dev;
- struct usb_interface *iface = usb_ifnum_to_if(dev, 1);
-
- return snd_usbmidi_create(card, iface,
- &US122L(card)->midi_list, &quirk);
-}
-
-static int us144_create_usbmidi(struct snd_card *card)
-{
- static struct snd_usb_midi_endpoint_info quirk_data = {
- .out_ep = 4,
- .in_ep = 3,
- .out_cables = 0x001,
- .in_cables = 0x001
- };
- static struct snd_usb_audio_quirk quirk = {
- .vendor_name = "US144",
- .product_name = NAME_ALLCAPS,
- .ifnum = 0,
- .type = QUIRK_MIDI_US122L,
- .data = &quirk_data
- };
- struct usb_device *dev = US122L(card)->dev;
- struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
-
- return snd_usbmidi_create(card, iface,
- &US122L(card)->midi_list, &quirk);
-}
-
-/*
- * Wrapper for usb_control_msg().
- * Allocates a temp buffer to prevent dmaing from/to the stack.
- */
-static int us122l_ctl_msg(struct usb_device *dev, unsigned int pipe,
- __u8 request, __u8 requesttype,
- __u16 value, __u16 index, void *data,
- __u16 size, int timeout)
-{
- int err;
- void *buf = NULL;
-
- if (size > 0) {
- buf = kmemdup(data, size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- }
- err = usb_control_msg(dev, pipe, request, requesttype,
- value, index, buf, size, timeout);
- if (size > 0) {
- memcpy(data, buf, size);
- kfree(buf);
- }
- return err;
-}
-
-static void pt_info_set(struct usb_device *dev, u8 v)
-{
- int ret;
-
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 'I',
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- v, 0, NULL, 0, 1000);
- snd_printdd(KERN_DEBUG "%i\n", ret);
-}
-
-static void usb_stream_hwdep_vm_open(struct vm_area_struct *area)
-{
- struct us122l *us122l = area->vm_private_data;
- atomic_inc(&us122l->mmap_count);
- snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
-}
-
-static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- unsigned long offset;
- struct page *page;
- void *vaddr;
- struct us122l *us122l = area->vm_private_data;
- struct usb_stream *s;
-
- mutex_lock(&us122l->mutex);
- s = us122l->sk.s;
- if (!s)
- goto unlock;
-
- offset = vmf->pgoff << PAGE_SHIFT;
- if (offset < PAGE_ALIGN(s->read_size))
- vaddr = (char *)s + offset;
- else {
- offset -= PAGE_ALIGN(s->read_size);
- if (offset >= PAGE_ALIGN(s->write_size))
- goto unlock;
-
- vaddr = us122l->sk.write_page + offset;
- }
- page = virt_to_page(vaddr);
-
- get_page(page);
- mutex_unlock(&us122l->mutex);
-
- vmf->page = page;
-
- return 0;
-unlock:
- mutex_unlock(&us122l->mutex);
- return VM_FAULT_SIGBUS;
-}
-
-static void usb_stream_hwdep_vm_close(struct vm_area_struct *area)
-{
- struct us122l *us122l = area->vm_private_data;
- atomic_dec(&us122l->mmap_count);
- snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
-}
-
-static const struct vm_operations_struct usb_stream_hwdep_vm_ops = {
- .open = usb_stream_hwdep_vm_open,
- .fault = usb_stream_hwdep_vm_fault,
- .close = usb_stream_hwdep_vm_close,
-};
-
-
-static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
-{
- struct us122l *us122l = hw->private_data;
- struct usb_interface *iface;
- snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
- if (hw->used >= 2)
- return -EBUSY;
-
- if (!us122l->first)
- us122l->first = file;
-
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
- iface = usb_ifnum_to_if(us122l->dev, 0);
- usb_autopm_get_interface(iface);
- }
- iface = usb_ifnum_to_if(us122l->dev, 1);
- usb_autopm_get_interface(iface);
- return 0;
-}
-
-static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
-{
- struct us122l *us122l = hw->private_data;
- struct usb_interface *iface;
- snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
-
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
- iface = usb_ifnum_to_if(us122l->dev, 0);
- usb_autopm_put_interface(iface);
- }
- iface = usb_ifnum_to_if(us122l->dev, 1);
- usb_autopm_put_interface(iface);
- if (us122l->first == file)
- us122l->first = NULL;
- mutex_lock(&us122l->mutex);
- if (us122l->master == file)
- us122l->master = us122l->slave;
-
- us122l->slave = NULL;
- mutex_unlock(&us122l->mutex);
- return 0;
-}
-
-static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,
- struct file *filp, struct vm_area_struct *area)
-{
- unsigned long size = area->vm_end - area->vm_start;
- struct us122l *us122l = hw->private_data;
- unsigned long offset;
- struct usb_stream *s;
- int err = 0;
- bool read;
-
- offset = area->vm_pgoff << PAGE_SHIFT;
- mutex_lock(&us122l->mutex);
- s = us122l->sk.s;
- read = offset < s->read_size;
- if (read && area->vm_flags & VM_WRITE) {
- err = -EPERM;
- goto out;
- }
- snd_printdd(KERN_DEBUG "%lu %u\n", size,
- read ? s->read_size : s->write_size);
- /* if userspace tries to mmap beyond end of our buffer, fail */
- if (size > PAGE_ALIGN(read ? s->read_size : s->write_size)) {
- snd_printk(KERN_WARNING "%lu > %u\n", size,
- read ? s->read_size : s->write_size);
- err = -EINVAL;
- goto out;
- }
-
- area->vm_ops = &usb_stream_hwdep_vm_ops;
- area->vm_flags |= VM_RESERVED;
- area->vm_private_data = us122l;
- atomic_inc(&us122l->mmap_count);
-out:
- mutex_unlock(&us122l->mutex);
- return err;
-}
-
-static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
- struct file *file, poll_table *wait)
-{
- struct us122l *us122l = hw->private_data;
- unsigned *polled;
- unsigned int mask;
-
- poll_wait(file, &us122l->sk.sleep, wait);
-
- mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
- if (mutex_trylock(&us122l->mutex)) {
- struct usb_stream *s = us122l->sk.s;
- if (s && s->state == usb_stream_ready) {
- if (us122l->first == file)
- polled = &s->periods_polled;
- else
- polled = &us122l->second_periods_polled;
- if (*polled != s->periods_done) {
- *polled = s->periods_done;
- mask = POLLIN | POLLOUT | POLLWRNORM;
- } else
- mask = 0;
- }
- mutex_unlock(&us122l->mutex);
- }
- return mask;
-}
-
-static void us122l_stop(struct us122l *us122l)
-{
- struct list_head *p;
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_input_stop(p);
-
- usb_stream_stop(&us122l->sk);
- usb_stream_free(&us122l->sk);
-}
-
-static int us122l_set_sample_rate(struct usb_device *dev, int rate)
-{
- unsigned int ep = 0x81;
- unsigned char data[3];
- int err;
-
- data[0] = rate;
- data[1] = rate >> 8;
- data[2] = rate >> 16;
- err = us122l_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
- USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT,
- UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, data, 3, 1000);
- if (err < 0)
- snd_printk(KERN_ERR "%d: cannot set freq %d to ep 0x%x\n",
- dev->devnum, rate, ep);
- return err;
-}
-
-static bool us122l_start(struct us122l *us122l,
- unsigned rate, unsigned period_frames)
-{
- struct list_head *p;
- int err;
- unsigned use_packsize = 0;
- bool success = false;
-
- if (us122l->dev->speed == USB_SPEED_HIGH) {
- /* The us-122l's descriptor defaults to iso max_packsize 78,
- which isn't needed for samplerates <= 48000.
- Lets save some memory:
- */
- switch (rate) {
- case 44100:
- use_packsize = 36;
- break;
- case 48000:
- use_packsize = 42;
- break;
- case 88200:
- use_packsize = 72;
- break;
- }
- }
- if (!usb_stream_new(&us122l->sk, us122l->dev, 1, 2,
- rate, use_packsize, period_frames, 6))
- goto out;
-
- err = us122l_set_sample_rate(us122l->dev, rate);
- if (err < 0) {
- us122l_stop(us122l);
- snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
- goto out;
- }
- err = usb_stream_start(&us122l->sk);
- if (err < 0) {
- us122l_stop(us122l);
- snd_printk(KERN_ERR "us122l_start error %i \n", err);
- goto out;
- }
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_input_start(p);
- success = true;
-out:
- return success;
-}
-
-static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
- unsigned cmd, unsigned long arg)
-{
- struct usb_stream_config *cfg;
- struct us122l *us122l = hw->private_data;
- struct usb_stream *s;
- unsigned min_period_frames;
- int err = 0;
- bool high_speed;
-
- if (cmd != SNDRV_USB_STREAM_IOCTL_SET_PARAMS)
- return -ENOTTY;
-
- cfg = memdup_user((void *)arg, sizeof(*cfg));
- if (IS_ERR(cfg))
- return PTR_ERR(cfg);
-
- if (cfg->version != USB_STREAM_INTERFACE_VERSION) {
- err = -ENXIO;
- goto free;
- }
- high_speed = us122l->dev->speed == USB_SPEED_HIGH;
- if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 &&
- (!high_speed ||
- (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) ||
- cfg->frame_size != 6 ||
- cfg->period_frames > 0x3000) {
- err = -EINVAL;
- goto free;
- }
- switch (cfg->sample_rate) {
- case 44100:
- min_period_frames = 48;
- break;
- case 48000:
- min_period_frames = 52;
- break;
- default:
- min_period_frames = 104;
- break;
- }
- if (!high_speed)
- min_period_frames <<= 1;
- if (cfg->period_frames < min_period_frames) {
- err = -EINVAL;
- goto free;
- }
-
- snd_power_wait(hw->card, SNDRV_CTL_POWER_D0);
-
- mutex_lock(&us122l->mutex);
- s = us122l->sk.s;
- if (!us122l->master)
- us122l->master = file;
- else if (us122l->master != file) {
- if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg))) {
- err = -EIO;
- goto unlock;
- }
- us122l->slave = file;
- }
- if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg)) ||
- s->state == usb_stream_xrun) {
- us122l_stop(us122l);
- if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames))
- err = -EIO;
- else
- err = 1;
- }
-unlock:
- mutex_unlock(&us122l->mutex);
-free:
- kfree(cfg);
- wake_up_all(&us122l->sk.sleep);
- return err;
-}
-
-#define SND_USB_STREAM_ID "USB STREAM"
-static int usb_stream_hwdep_new(struct snd_card *card)
-{
- int err;
- struct snd_hwdep *hw;
- struct usb_device *dev = US122L(card)->dev;
-
- err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw);
- if (err < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_USB_STREAM;
- hw->private_data = US122L(card);
- hw->ops.open = usb_stream_hwdep_open;
- hw->ops.release = usb_stream_hwdep_release;
- hw->ops.ioctl = usb_stream_hwdep_ioctl;
- hw->ops.ioctl_compat = usb_stream_hwdep_ioctl;
- hw->ops.mmap = usb_stream_hwdep_mmap;
- hw->ops.poll = usb_stream_hwdep_poll;
-
- sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm",
- dev->bus->busnum, dev->devnum);
- return 0;
-}
-
-
-static bool us122l_create_card(struct snd_card *card)
-{
- int err;
- struct us122l *us122l = US122L(card);
-
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
- err = usb_set_interface(us122l->dev, 0, 1);
- if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- return false;
- }
- }
- err = usb_set_interface(us122l->dev, 1, 1);
- if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- return false;
- }
-
- pt_info_set(us122l->dev, 0x11);
- pt_info_set(us122l->dev, 0x10);
-
- if (!us122l_start(us122l, 44100, 256))
- return false;
-
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII)
- err = us144_create_usbmidi(card);
- else
- err = us122l_create_usbmidi(card);
- if (err < 0) {
- snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err);
- us122l_stop(us122l);
- return false;
- }
- err = usb_stream_hwdep_new(card);
- if (err < 0) {
-/* release the midi resources */
- struct list_head *p;
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_disconnect(p);
-
- us122l_stop(us122l);
- return false;
- }
- return true;
-}
-
-static void snd_us122l_free(struct snd_card *card)
-{
- struct us122l *us122l = US122L(card);
- int index = us122l->card_index;
- if (index >= 0 && index < SNDRV_CARDS)
- snd_us122l_card_used[index] = 0;
-}
-
-static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
-{
- int dev;
- struct snd_card *card;
- int err;
-
- for (dev = 0; dev < SNDRV_CARDS; ++dev)
- if (enable[dev] && !snd_us122l_card_used[dev])
- break;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct us122l), &card);
- if (err < 0)
- return err;
- snd_us122l_card_used[US122L(card)->card_index = dev] = 1;
- card->private_free = snd_us122l_free;
- US122L(card)->dev = device;
- mutex_init(&US122L(card)->mutex);
- init_waitqueue_head(&US122L(card)->sk.sleep);
- INIT_LIST_HEAD(&US122L(card)->midi_list);
- strcpy(card->driver, "USB "NAME_ALLCAPS"");
- sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
- sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
- card->shortname,
- le16_to_cpu(device->descriptor.idVendor),
- le16_to_cpu(device->descriptor.idProduct),
- 0,
- US122L(card)->dev->bus->busnum,
- US122L(card)->dev->devnum
- );
- *cardp = card;
- return 0;
-}
-
-static int us122l_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *device_id,
- struct snd_card **cardp)
-{
- struct usb_device *device = interface_to_usbdev(intf);
- struct snd_card *card;
- int err;
-
- err = usx2y_create_card(device, &card);
- if (err < 0)
- return err;
-
- snd_card_set_dev(card, &intf->dev);
- if (!us122l_create_card(card)) {
- snd_card_free(card);
- return -EINVAL;
- }
-
- err = snd_card_register(card);
- if (err < 0) {
- snd_card_free(card);
- return err;
- }
-
- usb_get_intf(usb_ifnum_to_if(device, 0));
- usb_get_dev(device);
- *cardp = card;
- return 0;
-}
-
-static int snd_us122l_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *device = interface_to_usbdev(intf);
- struct snd_card *card;
- int err;
-
- if ((device->descriptor.idProduct == USB_ID_US144 ||
- device->descriptor.idProduct == USB_ID_US144MKII)
- && device->speed == USB_SPEED_HIGH) {
- snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
- return -ENODEV;
- }
-
- snd_printdd(KERN_DEBUG"%p:%i\n",
- intf, intf->cur_altsetting->desc.bInterfaceNumber);
- if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
- return 0;
-
- err = us122l_usb_probe(usb_get_intf(intf), id, &card);
- if (err < 0) {
- usb_put_intf(intf);
- return err;
- }
-
- usb_set_intfdata(intf, card);
- return 0;
-}
-
-static void snd_us122l_disconnect(struct usb_interface *intf)
-{
- struct snd_card *card;
- struct us122l *us122l;
- struct list_head *p;
-
- card = usb_get_intfdata(intf);
- if (!card)
- return;
-
- snd_card_disconnect(card);
-
- us122l = US122L(card);
- mutex_lock(&us122l->mutex);
- us122l_stop(us122l);
- mutex_unlock(&us122l->mutex);
-
-/* release the midi resources */
- list_for_each(p, &us122l->midi_list) {
- snd_usbmidi_disconnect(p);
- }
-
- usb_put_intf(usb_ifnum_to_if(us122l->dev, 0));
- usb_put_intf(usb_ifnum_to_if(us122l->dev, 1));
- usb_put_dev(us122l->dev);
-
- while (atomic_read(&us122l->mmap_count))
- msleep(500);
-
- snd_card_free(card);
-}
-
-static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct snd_card *card;
- struct us122l *us122l;
- struct list_head *p;
-
- card = usb_get_intfdata(intf);
- if (!card)
- return 0;
- snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-
- us122l = US122L(card);
- if (!us122l)
- return 0;
-
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_input_stop(p);
-
- mutex_lock(&us122l->mutex);
- usb_stream_stop(&us122l->sk);
- mutex_unlock(&us122l->mutex);
-
- return 0;
-}
-
-static int snd_us122l_resume(struct usb_interface *intf)
-{
- struct snd_card *card;
- struct us122l *us122l;
- struct list_head *p;
- int err;
-
- card = usb_get_intfdata(intf);
- if (!card)
- return 0;
-
- us122l = US122L(card);
- if (!us122l)
- return 0;
-
- mutex_lock(&us122l->mutex);
- /* needed, doesn't restart without: */
- if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
- us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
- err = usb_set_interface(us122l->dev, 0, 1);
- if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- goto unlock;
- }
- }
- err = usb_set_interface(us122l->dev, 1, 1);
- if (err) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- goto unlock;
- }
-
- pt_info_set(us122l->dev, 0x11);
- pt_info_set(us122l->dev, 0x10);
-
- err = us122l_set_sample_rate(us122l->dev,
- us122l->sk.s->cfg.sample_rate);
- if (err < 0) {
- snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
- goto unlock;
- }
- err = usb_stream_start(&us122l->sk);
- if (err)
- goto unlock;
-
- list_for_each(p, &us122l->midi_list)
- snd_usbmidi_input_start(p);
-unlock:
- mutex_unlock(&us122l->mutex);
- snd_power_change_state(card, SNDRV_CTL_POWER_D0);
- return err;
-}
-
-static struct usb_device_id snd_us122l_usb_id_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US122L
- },
- { /* US-144 only works at USB1.1! Disable module ehci-hcd. */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US144
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US122MKII
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x0644,
- .idProduct = USB_ID_US144MKII
- },
- { /* terminator */ }
-};
-
-MODULE_DEVICE_TABLE(usb, snd_us122l_usb_id_table);
-static struct usb_driver snd_us122l_usb_driver = {
- .name = "snd-usb-us122l",
- .probe = snd_us122l_probe,
- .disconnect = snd_us122l_disconnect,
- .suspend = snd_us122l_suspend,
- .resume = snd_us122l_resume,
- .reset_resume = snd_us122l_resume,
- .id_table = snd_us122l_usb_id_table,
- .supports_autosuspend = 1
-};
-
-module_usb_driver(snd_us122l_usb_driver);
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/us122l.h b/ANDROID_3.4.5/sound/usb/usx2y/us122l.h
deleted file mode 100644
index f263b3f9..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/us122l.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef US122L_H
-#define US122L_H
-
-
-struct us122l {
- struct usb_device *dev;
- int card_index;
- int stride;
- struct usb_stream_kernel sk;
-
- struct mutex mutex;
- struct file *first;
- unsigned second_periods_polled;
- struct file *master;
- struct file *slave;
- struct list_head midi_list;
-
- atomic_t mmap_count;
-};
-
-
-#define US122L(c) ((struct us122l *)(c)->private_data)
-
-#define NAME_ALLCAPS "US-122L"
-
-#define USB_ID_US122L 0x800E
-#define USB_ID_US144 0x800F
-#define USB_ID_US122MKII 0x8021
-#define USB_ID_US144MKII 0x8020
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.c b/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.c
deleted file mode 100644
index 04aafb43..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Driver for Tascam US-X2Y USB soundcards
- *
- * FPGA Loader + ALSA Startup
- *
- * Copyright (c) 2003 by Karsten Wiese <annabellesgarden@yahoo.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-#include <sound/memalloc.h>
-#include <sound/pcm.h>
-#include <sound/hwdep.h>
-#include "usx2y.h"
-#include "usbusx2y.h"
-#include "usX2Yhwdep.h"
-
-static int snd_us428ctls_vm_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- unsigned long offset;
- struct page * page;
- void *vaddr;
-
- snd_printdd("ENTER, start %lXh, pgoff %ld\n",
- area->vm_start,
- vmf->pgoff);
-
- offset = vmf->pgoff << PAGE_SHIFT;
- vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->us428ctls_sharedmem + offset;
- page = virt_to_page(vaddr);
- get_page(page);
- vmf->page = page;
-
- snd_printdd("vaddr=%p made us428ctls_vm_fault() page %p\n",
- vaddr, page);
-
- return 0;
-}
-
-static const struct vm_operations_struct us428ctls_vm_ops = {
- .fault = snd_us428ctls_vm_fault,
-};
-
-static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
-{
- unsigned long size = (unsigned long)(area->vm_end - area->vm_start);
- struct usX2Ydev *us428 = hw->private_data;
-
- // FIXME this hwdep interface is used twice: fpga download and mmap for controlling Lights etc. Maybe better using 2 hwdep devs?
- // so as long as the device isn't fully initialised yet we return -EBUSY here.
- if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT))
- return -EBUSY;
-
- /* if userspace tries to mmap beyond end of our buffer, fail */
- if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) {
- snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem));
- return -EINVAL;
- }
-
- if (!us428->us428ctls_sharedmem) {
- init_waitqueue_head(&us428->us428ctls_wait_queue_head);
- if(!(us428->us428ctls_sharedmem = snd_malloc_pages(sizeof(struct us428ctls_sharedmem), GFP_KERNEL)))
- return -ENOMEM;
- memset(us428->us428ctls_sharedmem, -1, sizeof(struct us428ctls_sharedmem));
- us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
- }
- area->vm_ops = &us428ctls_vm_ops;
- area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- area->vm_private_data = hw->private_data;
- return 0;
-}
-
-static unsigned int snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, poll_table *wait)
-{
- unsigned int mask = 0;
- struct usX2Ydev *us428 = hw->private_data;
- struct us428ctls_sharedmem *shm = us428->us428ctls_sharedmem;
- if (us428->chip_status & USX2Y_STAT_CHIP_HUP)
- return POLLHUP;
-
- poll_wait(file, &us428->us428ctls_wait_queue_head, wait);
-
- if (shm != NULL && shm->CtlSnapShotLast != shm->CtlSnapShotRed)
- mask |= POLLIN;
-
- return mask;
-}
-
-
-static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_status *info)
-{
- static char *type_ids[USX2Y_TYPE_NUMS] = {
- [USX2Y_TYPE_122] = "us122",
- [USX2Y_TYPE_224] = "us224",
- [USX2Y_TYPE_428] = "us428",
- };
- struct usX2Ydev *us428 = hw->private_data;
- int id = -1;
-
- switch (le16_to_cpu(us428->dev->descriptor.idProduct)) {
- case USB_ID_US122:
- id = USX2Y_TYPE_122;
- break;
- case USB_ID_US224:
- id = USX2Y_TYPE_224;
- break;
- case USB_ID_US428:
- id = USX2Y_TYPE_428;
- break;
- }
- if (0 > id)
- return -ENODEV;
- strcpy(info->id, type_ids[id]);
- info->num_dsps = 2; // 0: Prepad Data, 1: FPGA Code
- if (us428->chip_status & USX2Y_STAT_CHIP_INIT)
- info->chip_ready = 1;
- info->version = USX2Y_DRIVER_VERSION;
- return 0;
-}
-
-
-static int usX2Y_create_usbmidi(struct snd_card *card)
-{
- static struct snd_usb_midi_endpoint_info quirk_data_1 = {
- .out_ep = 0x06,
- .in_ep = 0x06,
- .out_cables = 0x001,
- .in_cables = 0x001
- };
- static struct snd_usb_audio_quirk quirk_1 = {
- .vendor_name = "TASCAM",
- .product_name = NAME_ALLCAPS,
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &quirk_data_1
- };
- static struct snd_usb_midi_endpoint_info quirk_data_2 = {
- .out_ep = 0x06,
- .in_ep = 0x06,
- .out_cables = 0x003,
- .in_cables = 0x003
- };
- static struct snd_usb_audio_quirk quirk_2 = {
- .vendor_name = "TASCAM",
- .product_name = "US428",
- .ifnum = 0,
- .type = QUIRK_MIDI_FIXED_ENDPOINT,
- .data = &quirk_data_2
- };
- struct usb_device *dev = usX2Y(card)->dev;
- struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
- struct snd_usb_audio_quirk *quirk =
- le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
- &quirk_2 : &quirk_1;
-
- snd_printdd("usX2Y_create_usbmidi \n");
- return snd_usbmidi_create(card, iface, &usX2Y(card)->midi_list, quirk);
-}
-
-static int usX2Y_create_alsa_devices(struct snd_card *card)
-{
- int err;
-
- do {
- if ((err = usX2Y_create_usbmidi(card)) < 0) {
- snd_printk(KERN_ERR "usX2Y_create_alsa_devices: usX2Y_create_usbmidi error %i \n", err);
- break;
- }
- if ((err = usX2Y_audio_create(card)) < 0)
- break;
- if ((err = usX2Y_hwdep_pcm_new(card)) < 0)
- break;
- if ((err = snd_card_register(card)) < 0)
- break;
- } while (0);
-
- return err;
-}
-
-static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
- struct snd_hwdep_dsp_image *dsp)
-{
- struct usX2Ydev *priv = hw->private_data;
- int lret, err = -EINVAL;
- snd_printdd( "dsp_load %s\n", dsp->name);
-
- if (access_ok(VERIFY_READ, dsp->image, dsp->length)) {
- struct usb_device* dev = priv->dev;
- char *buf;
-
- buf = memdup_user(dsp->image, dsp->length);
- if (IS_ERR(buf))
- return PTR_ERR(buf);
-
- err = usb_set_interface(dev, 0, 1);
- if (err)
- snd_printk(KERN_ERR "usb_set_interface error \n");
- else
- err = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 2), buf, dsp->length, &lret, 6000);
- kfree(buf);
- }
- if (err)
- return err;
- if (dsp->index == 1) {
- msleep(250); // give the device some time
- err = usX2Y_AsyncSeq04_init(priv);
- if (err) {
- snd_printk(KERN_ERR "usX2Y_AsyncSeq04_init error \n");
- return err;
- }
- err = usX2Y_In04_init(priv);
- if (err) {
- snd_printk(KERN_ERR "usX2Y_In04_init error \n");
- return err;
- }
- err = usX2Y_create_alsa_devices(hw->card);
- if (err) {
- snd_printk(KERN_ERR "usX2Y_create_alsa_devices error %i \n", err);
- snd_card_free(hw->card);
- return err;
- }
- priv->chip_status |= USX2Y_STAT_CHIP_INIT;
- snd_printdd("%s: alsa all started\n", hw->name);
- }
- return err;
-}
-
-
-int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device)
-{
- int err;
- struct snd_hwdep *hw;
-
- if ((err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw)) < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_USX2Y;
- hw->private_data = usX2Y(card);
- hw->ops.dsp_status = snd_usX2Y_hwdep_dsp_status;
- hw->ops.dsp_load = snd_usX2Y_hwdep_dsp_load;
- hw->ops.mmap = snd_us428ctls_mmap;
- hw->ops.poll = snd_us428ctls_poll;
- hw->exclusive = 1;
- sprintf(hw->name, "/proc/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);
- return 0;
-}
-
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.h b/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.h
deleted file mode 100644
index c095d5bf..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usX2Yhwdep.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef USX2YHWDEP_H
-#define USX2YHWDEP_H
-
-int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device);
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.c b/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.c
deleted file mode 100644
index 1e7a47a8..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/usb.h>
-#include <linux/gfp.h>
-
-#include "usb_stream.h"
-
-
-/* setup */
-
-static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk)
-{
- struct usb_stream *s = sk->s;
- sk->out_phase_peeked = (sk->out_phase & 0xffff) + sk->freqn;
- return (sk->out_phase_peeked >> 16) * s->cfg.frame_size;
-}
-
-static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb)
-{
- struct usb_stream *s = sk->s;
- int pack, lb = 0;
-
- for (pack = 0; pack < sk->n_o_ps; pack++) {
- int l = usb_stream_next_packet_size(sk);
- if (s->idle_outsize + lb + l > s->period_size)
- goto check;
-
- sk->out_phase = sk->out_phase_peeked;
- urb->iso_frame_desc[pack].offset = lb;
- urb->iso_frame_desc[pack].length = l;
- lb += l;
- }
- snd_printdd(KERN_DEBUG "%i\n", lb);
-
-check:
- urb->number_of_packets = pack;
- urb->transfer_buffer_length = lb;
- s->idle_outsize += lb - s->period_size;
- snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize,
- lb, s->period_size);
-}
-
-static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
- struct urb **urbs, char *transfer,
- struct usb_device *dev, int pipe)
-{
- int u, p;
- int maxpacket = use_packsize ?
- use_packsize : usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- int transfer_length = maxpacket * sk->n_o_ps;
-
- for (u = 0; u < USB_STREAM_NURBS;
- ++u, transfer += transfer_length) {
- struct urb *urb = urbs[u];
- struct usb_iso_packet_descriptor *desc;
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = transfer;
- urb->dev = dev;
- urb->pipe = pipe;
- urb->number_of_packets = sk->n_o_ps;
- urb->context = sk;
- urb->interval = 1;
- if (usb_pipeout(pipe))
- continue;
-
- urb->transfer_buffer_length = transfer_length;
- desc = urb->iso_frame_desc;
- desc->offset = 0;
- desc->length = maxpacket;
- for (p = 1; p < sk->n_o_ps; ++p) {
- desc[p].offset = desc[p - 1].offset + maxpacket;
- desc[p].length = maxpacket;
- }
- }
-}
-
-static void init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
- struct usb_device *dev, int in_pipe, int out_pipe)
-{
- struct usb_stream *s = sk->s;
- char *indata = (char *)s + sizeof(*s) +
- sizeof(struct usb_stream_packet) *
- s->inpackets;
- int u;
-
- for (u = 0; u < USB_STREAM_NURBS; ++u) {
- sk->inurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
- sk->outurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
- }
-
- init_pipe_urbs(sk, use_packsize, sk->inurb, indata, dev, in_pipe);
- init_pipe_urbs(sk, use_packsize, sk->outurb, sk->write_page, dev,
- out_pipe);
-}
-
-
-/*
- * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
- * this will overflow at approx 524 kHz
- */
-static inline unsigned get_usb_full_speed_rate(unsigned rate)
-{
- return ((rate << 13) + 62) / 125;
-}
-
-/*
- * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
- * this will overflow at approx 4 MHz
- */
-static inline unsigned get_usb_high_speed_rate(unsigned rate)
-{
- return ((rate << 10) + 62) / 125;
-}
-
-void usb_stream_free(struct usb_stream_kernel *sk)
-{
- struct usb_stream *s;
- unsigned u;
-
- for (u = 0; u < USB_STREAM_NURBS; ++u) {
- usb_free_urb(sk->inurb[u]);
- sk->inurb[u] = NULL;
- usb_free_urb(sk->outurb[u]);
- sk->outurb[u] = NULL;
- }
-
- s = sk->s;
- if (!s)
- return;
-
- free_pages((unsigned long)sk->write_page, get_order(s->write_size));
- sk->write_page = NULL;
- free_pages((unsigned long)s, get_order(s->read_size));
- sk->s = NULL;
-}
-
-struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
- struct usb_device *dev,
- unsigned in_endpoint, unsigned out_endpoint,
- unsigned sample_rate, unsigned use_packsize,
- unsigned period_frames, unsigned frame_size)
-{
- int packets, max_packsize;
- int in_pipe, out_pipe;
- int read_size = sizeof(struct usb_stream);
- int write_size;
- int usb_frames = dev->speed == USB_SPEED_HIGH ? 8000 : 1000;
- int pg;
-
- in_pipe = usb_rcvisocpipe(dev, in_endpoint);
- out_pipe = usb_sndisocpipe(dev, out_endpoint);
-
- max_packsize = use_packsize ?
- use_packsize : usb_maxpacket(dev, in_pipe, 0);
-
- /*
- t_period = period_frames / sample_rate
- iso_packs = t_period / t_iso_frame
- = (period_frames / sample_rate) * (1 / t_iso_frame)
- */
-
- packets = period_frames * usb_frames / sample_rate + 1;
-
- if (dev->speed == USB_SPEED_HIGH)
- packets = (packets + 7) & ~7;
-
- read_size += packets * USB_STREAM_URBDEPTH *
- (max_packsize + sizeof(struct usb_stream_packet));
-
- max_packsize = usb_maxpacket(dev, out_pipe, 1);
- write_size = max_packsize * packets * USB_STREAM_URBDEPTH;
-
- if (read_size >= 256*PAGE_SIZE || write_size >= 256*PAGE_SIZE) {
- snd_printk(KERN_WARNING "a size exceeds 128*PAGE_SIZE\n");
- goto out;
- }
-
- pg = get_order(read_size);
- sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
- if (!sk->s) {
- snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
- goto out;
- }
- sk->s->cfg.version = USB_STREAM_INTERFACE_VERSION;
-
- sk->s->read_size = read_size;
-
- sk->s->cfg.sample_rate = sample_rate;
- sk->s->cfg.frame_size = frame_size;
- sk->n_o_ps = packets;
- sk->s->inpackets = packets * USB_STREAM_URBDEPTH;
- sk->s->cfg.period_frames = period_frames;
- sk->s->period_size = frame_size * period_frames;
-
- sk->s->write_size = write_size;
- pg = get_order(write_size);
-
- sk->write_page =
- (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
- if (!sk->write_page) {
- snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
- usb_stream_free(sk);
- return NULL;
- }
-
- /* calculate the frequency in 16.16 format */
- if (dev->speed == USB_SPEED_FULL)
- sk->freqn = get_usb_full_speed_rate(sample_rate);
- else
- sk->freqn = get_usb_high_speed_rate(sample_rate);
-
- init_urbs(sk, use_packsize, dev, in_pipe, out_pipe);
- sk->s->state = usb_stream_stopped;
-out:
- return sk->s;
-}
-
-
-/* start */
-
-static bool balance_check(struct usb_stream_kernel *sk, struct urb *urb)
-{
- bool r;
- if (unlikely(urb->status)) {
- if (urb->status != -ESHUTDOWN && urb->status != -ENOENT)
- snd_printk(KERN_WARNING "status=%i\n", urb->status);
- sk->iso_frame_balance = 0x7FFFFFFF;
- return false;
- }
- r = sk->iso_frame_balance == 0;
- if (!r)
- sk->i_urb = urb;
- return r;
-}
-
-static bool balance_playback(struct usb_stream_kernel *sk, struct urb *urb)
-{
- sk->iso_frame_balance += urb->number_of_packets;
- return balance_check(sk, urb);
-}
-
-static bool balance_capture(struct usb_stream_kernel *sk, struct urb *urb)
-{
- sk->iso_frame_balance -= urb->number_of_packets;
- return balance_check(sk, urb);
-}
-
-static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
-{
- int u;
-
- for (u = 0; u < USB_STREAM_NURBS; u++) {
- struct urb *urb = urbs[u];
- urb->complete = complete;
- }
-}
-
-static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
- struct urb *inurb)
-{
- struct usb_stream *s = sk->s;
- struct urb *io;
- struct usb_iso_packet_descriptor *id, *od;
- int p = 0, lb = 0, l = 0;
-
- io = sk->idle_outurb;
- od = io->iso_frame_desc;
-
- for (; s->sync_packet < 0; ++p, ++s->sync_packet) {
- struct urb *ii = sk->completed_inurb;
- id = ii->iso_frame_desc +
- ii->number_of_packets + s->sync_packet;
- l = id->actual_length;
-
- od[p].length = l;
- od[p].offset = lb;
- lb += l;
- }
-
- for (;
- s->sync_packet < inurb->number_of_packets && p < sk->n_o_ps;
- ++p, ++s->sync_packet) {
- l = inurb->iso_frame_desc[s->sync_packet].actual_length;
-
- if (s->idle_outsize + lb + l > s->period_size)
- goto check_ok;
-
- od[p].length = l;
- od[p].offset = lb;
- lb += l;
- }
-
-check_ok:
- s->sync_packet -= inurb->number_of_packets;
- if (unlikely(s->sync_packet < -2 || s->sync_packet > 0)) {
- snd_printk(KERN_WARNING "invalid sync_packet = %i;"
- " p=%i nop=%i %i %x %x %x > %x\n",
- s->sync_packet, p, inurb->number_of_packets,
- s->idle_outsize + lb + l,
- s->idle_outsize, lb, l,
- s->period_size);
- return -1;
- }
- if (unlikely(lb % s->cfg.frame_size)) {
- snd_printk(KERN_WARNING"invalid outsize = %i\n",
- lb);
- return -1;
- }
- s->idle_outsize += lb - s->period_size;
- io->number_of_packets = p;
- io->transfer_buffer_length = lb;
- if (s->idle_outsize <= 0)
- return 0;
-
- snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize);
- return -1;
-}
-
-static void prepare_inurb(int number_of_packets, struct urb *iu)
-{
- struct usb_iso_packet_descriptor *id;
- int p;
-
- iu->number_of_packets = number_of_packets;
- id = iu->iso_frame_desc;
- id->offset = 0;
- for (p = 0; p < iu->number_of_packets - 1; ++p)
- id[p + 1].offset = id[p].offset + id[p].length;
-
- iu->transfer_buffer_length =
- id[0].length * iu->number_of_packets;
-}
-
-static int submit_urbs(struct usb_stream_kernel *sk,
- struct urb *inurb, struct urb *outurb)
-{
- int err;
- prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb);
- err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR "%i\n", err);
- return err;
- }
- sk->idle_inurb = sk->completed_inurb;
- sk->completed_inurb = inurb;
- err = usb_submit_urb(sk->idle_outurb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR "%i\n", err);
- return err;
- }
- sk->idle_outurb = sk->completed_outurb;
- sk->completed_outurb = outurb;
- return 0;
-}
-
-#ifdef DEBUG_LOOP_BACK
-/*
- This loop_back() shows how to read/write the period data.
- */
-static void loop_back(struct usb_stream *s)
-{
- char *i, *o;
- int il, ol, l, p;
- struct urb *iu;
- struct usb_iso_packet_descriptor *id;
-
- o = s->playback1st_to;
- ol = s->playback1st_size;
- l = 0;
-
- if (s->insplit_pack >= 0) {
- iu = sk->idle_inurb;
- id = iu->iso_frame_desc;
- p = s->insplit_pack;
- } else
- goto second;
-loop:
- for (; p < iu->number_of_packets && l < s->period_size; ++p) {
- i = iu->transfer_buffer + id[p].offset;
- il = id[p].actual_length;
- if (l + il > s->period_size)
- il = s->period_size - l;
- if (il <= ol) {
- memcpy(o, i, il);
- o += il;
- ol -= il;
- } else {
- memcpy(o, i, ol);
- singen_6pack(o, ol);
- o = s->playback_to;
- memcpy(o, i + ol, il - ol);
- o += il - ol;
- ol = s->period_size - s->playback1st_size;
- }
- l += il;
- }
- if (iu == sk->completed_inurb) {
- if (l != s->period_size)
- printk(KERN_DEBUG"%s:%i %i\n", __func__, __LINE__,
- l/(int)s->cfg.frame_size);
-
- return;
- }
-second:
- iu = sk->completed_inurb;
- id = iu->iso_frame_desc;
- p = 0;
- goto loop;
-
-}
-#else
-static void loop_back(struct usb_stream *s)
-{
-}
-#endif
-
-static void stream_idle(struct usb_stream_kernel *sk,
- struct urb *inurb, struct urb *outurb)
-{
- struct usb_stream *s = sk->s;
- int l, p;
- int insize = s->idle_insize;
- int urb_size = 0;
-
- s->inpacket_split = s->next_inpacket_split;
- s->inpacket_split_at = s->next_inpacket_split_at;
- s->next_inpacket_split = -1;
- s->next_inpacket_split_at = 0;
-
- for (p = 0; p < inurb->number_of_packets; ++p) {
- struct usb_iso_packet_descriptor *id = inurb->iso_frame_desc;
- l = id[p].actual_length;
- if (unlikely(l == 0 || id[p].status)) {
- snd_printk(KERN_WARNING "underrun, status=%u\n",
- id[p].status);
- goto err_out;
- }
- s->inpacket_head++;
- s->inpacket_head %= s->inpackets;
- if (s->inpacket_split == -1)
- s->inpacket_split = s->inpacket_head;
-
- s->inpacket[s->inpacket_head].offset =
- id[p].offset + (inurb->transfer_buffer - (void *)s);
- s->inpacket[s->inpacket_head].length = l;
- if (insize + l > s->period_size &&
- s->next_inpacket_split == -1) {
- s->next_inpacket_split = s->inpacket_head;
- s->next_inpacket_split_at = s->period_size - insize;
- }
- insize += l;
- urb_size += l;
- }
- s->idle_insize += urb_size - s->period_size;
- if (s->idle_insize < 0) {
- snd_printk(KERN_WARNING "%i\n",
- (s->idle_insize)/(int)s->cfg.frame_size);
- goto err_out;
- }
- s->insize_done += urb_size;
-
- l = s->idle_outsize;
- s->outpacket[0].offset = (sk->idle_outurb->transfer_buffer -
- sk->write_page) - l;
-
- if (usb_stream_prepare_playback(sk, inurb) < 0)
- goto err_out;
-
- s->outpacket[0].length = sk->idle_outurb->transfer_buffer_length + l;
- s->outpacket[1].offset = sk->completed_outurb->transfer_buffer -
- sk->write_page;
-
- if (submit_urbs(sk, inurb, outurb) < 0)
- goto err_out;
-
- loop_back(s);
- s->periods_done++;
- wake_up_all(&sk->sleep);
- return;
-err_out:
- s->state = usb_stream_xrun;
- wake_up_all(&sk->sleep);
-}
-
-static void i_capture_idle(struct urb *urb)
-{
- struct usb_stream_kernel *sk = urb->context;
- if (balance_capture(sk, urb))
- stream_idle(sk, urb, sk->i_urb);
-}
-
-static void i_playback_idle(struct urb *urb)
-{
- struct usb_stream_kernel *sk = urb->context;
- if (balance_playback(sk, urb))
- stream_idle(sk, sk->i_urb, urb);
-}
-
-static void stream_start(struct usb_stream_kernel *sk,
- struct urb *inurb, struct urb *outurb)
-{
- struct usb_stream *s = sk->s;
- if (s->state >= usb_stream_sync1) {
- int l, p, max_diff, max_diff_0;
- int urb_size = 0;
- unsigned frames_per_packet, min_frames = 0;
- frames_per_packet = (s->period_size - s->idle_insize);
- frames_per_packet <<= 8;
- frames_per_packet /=
- s->cfg.frame_size * inurb->number_of_packets;
- frames_per_packet++;
-
- max_diff_0 = s->cfg.frame_size;
- if (s->cfg.period_frames >= 256)
- max_diff_0 <<= 1;
- if (s->cfg.period_frames >= 1024)
- max_diff_0 <<= 1;
- max_diff = max_diff_0;
- for (p = 0; p < inurb->number_of_packets; ++p) {
- int diff;
- l = inurb->iso_frame_desc[p].actual_length;
- urb_size += l;
-
- min_frames += frames_per_packet;
- diff = urb_size -
- (min_frames >> 8) * s->cfg.frame_size;
- if (diff < max_diff) {
- snd_printdd(KERN_DEBUG "%i %i %i %i\n",
- s->insize_done,
- urb_size / (int)s->cfg.frame_size,
- inurb->number_of_packets, diff);
- max_diff = diff;
- }
- }
- s->idle_insize -= max_diff - max_diff_0;
- s->idle_insize += urb_size - s->period_size;
- if (s->idle_insize < 0) {
- snd_printk(KERN_WARNING "%i %i %i\n",
- s->idle_insize, urb_size, s->period_size);
- return;
- } else if (s->idle_insize == 0) {
- s->next_inpacket_split =
- (s->inpacket_head + 1) % s->inpackets;
- s->next_inpacket_split_at = 0;
- } else {
- unsigned split = s->inpacket_head;
- l = s->idle_insize;
- while (l > s->inpacket[split].length) {
- l -= s->inpacket[split].length;
- if (split == 0)
- split = s->inpackets - 1;
- else
- split--;
- }
- s->next_inpacket_split = split;
- s->next_inpacket_split_at =
- s->inpacket[split].length - l;
- }
-
- s->insize_done += urb_size;
-
- if (usb_stream_prepare_playback(sk, inurb) < 0)
- return;
-
- } else
- playback_prep_freqn(sk, sk->idle_outurb);
-
- if (submit_urbs(sk, inurb, outurb) < 0)
- return;
-
- if (s->state == usb_stream_sync1 && s->insize_done > 360000) {
- /* just guesswork ^^^^^^ */
- s->state = usb_stream_ready;
- subs_set_complete(sk->inurb, i_capture_idle);
- subs_set_complete(sk->outurb, i_playback_idle);
- }
-}
-
-static void i_capture_start(struct urb *urb)
-{
- struct usb_iso_packet_descriptor *id = urb->iso_frame_desc;
- struct usb_stream_kernel *sk = urb->context;
- struct usb_stream *s = sk->s;
- int p;
- int empty = 0;
-
- if (urb->status) {
- snd_printk(KERN_WARNING "status=%i\n", urb->status);
- return;
- }
-
- for (p = 0; p < urb->number_of_packets; ++p) {
- int l = id[p].actual_length;
- if (l < s->cfg.frame_size) {
- ++empty;
- if (s->state >= usb_stream_sync0) {
- snd_printk(KERN_WARNING "%i\n", l);
- return;
- }
- }
- s->inpacket_head++;
- s->inpacket_head %= s->inpackets;
- s->inpacket[s->inpacket_head].offset =
- id[p].offset + (urb->transfer_buffer - (void *)s);
- s->inpacket[s->inpacket_head].length = l;
- }
-#ifdef SHOW_EMPTY
- if (empty) {
- printk(KERN_DEBUG"%s:%i: %i", __func__, __LINE__,
- urb->iso_frame_desc[0].actual_length);
- for (pack = 1; pack < urb->number_of_packets; ++pack) {
- int l = urb->iso_frame_desc[pack].actual_length;
- printk(" %i", l);
- }
- printk("\n");
- }
-#endif
- if (!empty && s->state < usb_stream_sync1)
- ++s->state;
-
- if (balance_capture(sk, urb))
- stream_start(sk, urb, sk->i_urb);
-}
-
-static void i_playback_start(struct urb *urb)
-{
- struct usb_stream_kernel *sk = urb->context;
- if (balance_playback(sk, urb))
- stream_start(sk, sk->i_urb, urb);
-}
-
-int usb_stream_start(struct usb_stream_kernel *sk)
-{
- struct usb_stream *s = sk->s;
- int frame = 0, iters = 0;
- int u, err;
- int try = 0;
-
- if (s->state != usb_stream_stopped)
- return -EAGAIN;
-
- subs_set_complete(sk->inurb, i_capture_start);
- subs_set_complete(sk->outurb, i_playback_start);
- memset(sk->write_page, 0, s->write_size);
-dotry:
- s->insize_done = 0;
- s->idle_insize = 0;
- s->idle_outsize = 0;
- s->sync_packet = -1;
- s->inpacket_head = -1;
- sk->iso_frame_balance = 0;
- ++try;
- for (u = 0; u < 2; u++) {
- struct urb *inurb = sk->inurb[u];
- struct urb *outurb = sk->outurb[u];
- playback_prep_freqn(sk, outurb);
- inurb->number_of_packets = outurb->number_of_packets;
- inurb->transfer_buffer_length =
- inurb->number_of_packets *
- inurb->iso_frame_desc[0].length;
-
- if (u == 0) {
- int now;
- struct usb_device *dev = inurb->dev;
- frame = usb_get_current_frame_number(dev);
- do {
- now = usb_get_current_frame_number(dev);
- ++iters;
- } while (now > -1 && now == frame);
- }
- err = usb_submit_urb(inurb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
- " returned %i\n", u, err);
- return err;
- }
- err = usb_submit_urb(outurb, GFP_ATOMIC);
- if (err < 0) {
- snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
- " returned %i\n", u, err);
- return err;
- }
-
- if (inurb->start_frame != outurb->start_frame) {
- snd_printd(KERN_DEBUG
- "u[%i] start_frames differ in:%u out:%u\n",
- u, inurb->start_frame, outurb->start_frame);
- goto check_retry;
- }
- }
- snd_printdd(KERN_DEBUG "%i %i\n", frame, iters);
- try = 0;
-check_retry:
- if (try) {
- usb_stream_stop(sk);
- if (try < 5) {
- msleep(1500);
- snd_printd(KERN_DEBUG "goto dotry;\n");
- goto dotry;
- }
- snd_printk(KERN_WARNING"couldn't start"
- " all urbs on the same start_frame.\n");
- return -EFAULT;
- }
-
- sk->idle_inurb = sk->inurb[USB_STREAM_NURBS - 2];
- sk->idle_outurb = sk->outurb[USB_STREAM_NURBS - 2];
- sk->completed_inurb = sk->inurb[USB_STREAM_NURBS - 1];
- sk->completed_outurb = sk->outurb[USB_STREAM_NURBS - 1];
-
-/* wait, check */
- {
- int wait_ms = 3000;
- while (s->state != usb_stream_ready && wait_ms > 0) {
- snd_printdd(KERN_DEBUG "%i\n", s->state);
- msleep(200);
- wait_ms -= 200;
- }
- }
-
- return s->state == usb_stream_ready ? 0 : -EFAULT;
-}
-
-
-/* stop */
-
-void usb_stream_stop(struct usb_stream_kernel *sk)
-{
- int u;
- if (!sk->s)
- return;
- for (u = 0; u < USB_STREAM_NURBS; ++u) {
- usb_kill_urb(sk->inurb[u]);
- usb_kill_urb(sk->outurb[u]);
- }
- sk->s->state = usb_stream_stopped;
- msleep(400);
-}
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.h b/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.h
deleted file mode 100644
index 4dd74ab1..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usb_stream.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define USB_STREAM_INTERFACE_VERSION 2
-
-#define SNDRV_USB_STREAM_IOCTL_SET_PARAMS \
- _IOW('H', 0x90, struct usb_stream_config)
-
-struct usb_stream_packet {
- unsigned offset;
- unsigned length;
-};
-
-
-struct usb_stream_config {
- unsigned version;
- unsigned sample_rate;
- unsigned period_frames;
- unsigned frame_size;
-};
-
-struct usb_stream {
- struct usb_stream_config cfg;
- unsigned read_size;
- unsigned write_size;
-
- int period_size;
-
- unsigned state;
-
- int idle_insize;
- int idle_outsize;
- int sync_packet;
- unsigned insize_done;
- unsigned periods_done;
- unsigned periods_polled;
-
- struct usb_stream_packet outpacket[2];
- unsigned inpackets;
- unsigned inpacket_head;
- unsigned inpacket_split;
- unsigned inpacket_split_at;
- unsigned next_inpacket_split;
- unsigned next_inpacket_split_at;
- struct usb_stream_packet inpacket[0];
-};
-
-enum usb_stream_state {
- usb_stream_invalid,
- usb_stream_stopped,
- usb_stream_sync0,
- usb_stream_sync1,
- usb_stream_ready,
- usb_stream_running,
- usb_stream_xrun,
-};
-
-#if __KERNEL__
-
-#define USB_STREAM_NURBS 4
-#define USB_STREAM_URBDEPTH 4
-
-struct usb_stream_kernel {
- struct usb_stream *s;
-
- void *write_page;
-
- unsigned n_o_ps;
-
- struct urb *inurb[USB_STREAM_NURBS];
- struct urb *idle_inurb;
- struct urb *completed_inurb;
- struct urb *outurb[USB_STREAM_NURBS];
- struct urb *idle_outurb;
- struct urb *completed_outurb;
- struct urb *i_urb;
-
- int iso_frame_balance;
-
- wait_queue_head_t sleep;
-
- unsigned out_phase;
- unsigned out_phase_peeked;
- unsigned freqn;
-};
-
-struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
- struct usb_device *dev,
- unsigned in_endpoint, unsigned out_endpoint,
- unsigned sample_rate, unsigned use_packsize,
- unsigned period_frames, unsigned frame_size);
-void usb_stream_free(struct usb_stream_kernel *);
-int usb_stream_start(struct usb_stream_kernel *);
-void usb_stream_stop(struct usb_stream_kernel *);
-
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usbus428ctldefs.h b/ANDROID_3.4.5/sound/usb/usx2y/usbus428ctldefs.h
deleted file mode 100644
index b864e7e2..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usbus428ctldefs.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *
- * Copyright (c) 2003 by Karsten Wiese <annabellesgarden@yahoo.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-enum E_In84{
- eFader0 = 0,
- eFader1,
- eFader2,
- eFader3,
- eFader4,
- eFader5,
- eFader6,
- eFader7,
- eFaderM,
- eTransport,
- eModifier = 10,
- eFilterSelect,
- eSelect,
- eMute,
-
- eSwitch = 15,
- eWheelGain,
- eWheelFreq,
- eWheelQ,
- eWheelPan,
- eWheel = 20
-};
-
-#define T_RECORD 1
-#define T_PLAY 2
-#define T_STOP 4
-#define T_F_FWD 8
-#define T_REW 0x10
-#define T_SOLO 0x20
-#define T_REC 0x40
-#define T_NULL 0x80
-
-
-struct us428_ctls {
- unsigned char Fader[9];
- unsigned char Transport;
- unsigned char Modifier;
- unsigned char FilterSelect;
- unsigned char Select;
- unsigned char Mute;
- unsigned char UNKNOWN;
- unsigned char Switch;
- unsigned char Wheel[5];
-};
-
-struct us428_setByte {
- unsigned char Offset,
- Value;
-};
-
-enum {
- eLT_Volume = 0,
- eLT_Light
-};
-
-struct usX2Y_volume {
- unsigned char Channel,
- LH,
- LL,
- RH,
- RL;
-};
-
-struct us428_lights {
- struct us428_setByte Light[7];
-};
-
-struct us428_p4out {
- char type;
- union {
- struct usX2Y_volume vol;
- struct us428_lights lights;
- } val;
-};
-
-#define N_us428_ctl_BUFS 16
-#define N_us428_p4out_BUFS 16
-struct us428ctls_sharedmem{
- struct us428_ctls CtlSnapShot[N_us428_ctl_BUFS];
- int CtlSnapShotDiffersAt[N_us428_ctl_BUFS];
- int CtlSnapShotLast, CtlSnapShotRed;
- struct us428_p4out p4out[N_us428_p4out_BUFS];
- int p4outLast, p4outSent;
-};
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.c b/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.c
deleted file mode 100644
index 9af7c1f1..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * usbusy2y.c - ALSA USB US-428 Driver
- *
-2005-04-14 Karsten Wiese
- Version 0.8.7.2:
- Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom.
- Tested ok with kernel 2.6.12-rc2.
-
-2004-12-14 Karsten Wiese
- Version 0.8.7.1:
- snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open.
-
-2004-12-02 Karsten Wiese
- Version 0.8.7:
- Use macro usb_maxpacket() for portability.
-
-2004-10-26 Karsten Wiese
- Version 0.8.6:
- wake_up() process waiting in usX2Y_urbs_start() on error.
-
-2004-10-21 Karsten Wiese
- Version 0.8.5:
- nrpacks is runtime or compiletime configurable now with tested values from 1 to 4.
-
-2004-10-03 Karsten Wiese
- Version 0.8.2:
- Avoid any possible racing while in prepare callback.
-
-2004-09-30 Karsten Wiese
- Version 0.8.0:
- Simplified things and made ohci work again.
-
-2004-09-20 Karsten Wiese
- Version 0.7.3:
- Use usb_kill_urb() instead of deprecated (kernel 2.6.9) usb_unlink_urb().
-
-2004-07-13 Karsten Wiese
- Version 0.7.1:
- Don't sleep in START/STOP callbacks anymore.
- us428 channels C/D not handled just for this version, sorry.
-
-2004-06-21 Karsten Wiese
- Version 0.6.4:
- Temporarely suspend midi input
- to sanely call usb_set_interface() when setting format.
-
-2004-06-12 Karsten Wiese
- Version 0.6.3:
- Made it thus the following rule is enforced:
- "All pcm substreams of one usX2Y have to operate at the same rate & format."
-
-2004-04-06 Karsten Wiese
- Version 0.6.0:
- Runs on 2.6.5 kernel without any "--with-debug=" things.
- us224 reported running.
-
-2004-01-14 Karsten Wiese
- Version 0.5.1:
- Runs with 2.6.1 kernel.
-
-2003-12-30 Karsten Wiese
- Version 0.4.1:
- Fix 24Bit 4Channel capturing for the us428.
-
-2003-11-27 Karsten Wiese, Martin Langer
- Version 0.4:
- us122 support.
- us224 could be tested by uncommenting the sections containing USB_ID_US224
-
-2003-11-03 Karsten Wiese
- Version 0.3:
- 24Bit support.
- "arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works.
-
-2003-08-22 Karsten Wiese
- Version 0.0.8:
- Removed EZUSB Firmware. First Stage Firmwaredownload is now done by tascam-firmware downloader.
- See:
- http://usb-midi-fw.sourceforge.net/tascam-firmware.tar.gz
-
-2003-06-18 Karsten Wiese
- Version 0.0.5:
- changed to compile with kernel 2.4.21 and alsa 0.9.4
-
-2002-10-16 Karsten Wiese
- Version 0.0.4:
- compiles again with alsa-current.
- USB_ISO_ASAP not used anymore (most of the time), instead
- urb->start_frame is calculated here now, some calls inside usb-driver don't need to happen anymore.
-
- To get the best out of this:
- Disable APM-support in the kernel as APM-BIOS calls (once each second) hard disable interrupt for many precious milliseconds.
- This helped me much on my slowish PII 400 & PIII 500.
- ACPI yet untested but might cause the same bad behaviour.
- Use a kernel with lowlatency and preemptiv patches applied.
- To autoload snd-usb-midi append a line
- post-install snd-usb-us428 modprobe snd-usb-midi
- to /etc/modules.conf.
-
- known problems:
- sliders, knobs, lights not yet handled except MASTER Volume slider.
- "pcm -c 2" doesn't work. "pcm -c 2 -m direct_interleaved" does.
- KDE3: "Enable full duplex operation" deadlocks.
-
-
-2002-08-31 Karsten Wiese
- Version 0.0.3: audio also simplex;
- simplifying: iso urbs only 1 packet, melted structs.
- ASYNC_UNLINK not used anymore: no more crashes so far.....
- for alsa 0.9 rc3.
-
-2002-08-09 Karsten Wiese
- Version 0.0.2: midi works with snd-usb-midi, audio (only fullduplex now) with i.e. bristol.
- The firmware has been sniffed from win2k us-428 driver 3.09.
-
- * Copyright (c) 2002 - 2004 Karsten Wiese
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/usb.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-
-#include <sound/rawmidi.h>
-#include "usx2y.h"
-#include "usbusx2y.h"
-#include "usX2Yhwdep.h"
-
-
-
-MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
-MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2");
-MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}");
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
-static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
-
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS".");
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for "NAME_ALLCAPS".");
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable "NAME_ALLCAPS".");
-
-
-static int snd_usX2Y_card_used[SNDRV_CARDS];
-
-static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr);
-static void snd_usX2Y_card_private_free(struct snd_card *card);
-
-/*
- * pipe 4 is used for switching the lamps, setting samplerate, volumes ....
- */
-static void i_usX2Y_Out04Int(struct urb *urb)
-{
-#ifdef CONFIG_SND_DEBUG
- if (urb->status) {
- int i;
- struct usX2Ydev *usX2Y = urb->context;
- for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++);
- snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status);
- }
-#endif
-}
-
-static void i_usX2Y_In04Int(struct urb *urb)
-{
- int err = 0;
- struct usX2Ydev *usX2Y = urb->context;
- struct us428ctls_sharedmem *us428ctls = usX2Y->us428ctls_sharedmem;
-
- usX2Y->In04IntCalls++;
-
- if (urb->status) {
- snd_printdd("Interrupt Pipe 4 came back with status=%i\n", urb->status);
- return;
- }
-
- // printk("%i:0x%02X ", 8, (int)((unsigned char*)usX2Y->In04Buf)[8]); Master volume shows 0 here if fader is at max during boot ?!?
- if (us428ctls) {
- int diff = -1;
- if (-2 == us428ctls->CtlSnapShotLast) {
- diff = 0;
- memcpy(usX2Y->In04Last, usX2Y->In04Buf, sizeof(usX2Y->In04Last));
- us428ctls->CtlSnapShotLast = -1;
- } else {
- int i;
- for (i = 0; i < 21; i++) {
- if (usX2Y->In04Last[i] != ((char*)usX2Y->In04Buf)[i]) {
- if (diff < 0)
- diff = i;
- usX2Y->In04Last[i] = ((char*)usX2Y->In04Buf)[i];
- }
- }
- }
- if (0 <= diff) {
- int n = us428ctls->CtlSnapShotLast + 1;
- if (n >= N_us428_ctl_BUFS || n < 0)
- n = 0;
- memcpy(us428ctls->CtlSnapShot + n, usX2Y->In04Buf, sizeof(us428ctls->CtlSnapShot[0]));
- us428ctls->CtlSnapShotDiffersAt[n] = diff;
- us428ctls->CtlSnapShotLast = n;
- wake_up(&usX2Y->us428ctls_wait_queue_head);
- }
- }
-
-
- if (usX2Y->US04) {
- if (0 == usX2Y->US04->submitted)
- do {
- err = usb_submit_urb(usX2Y->US04->urb[usX2Y->US04->submitted++], GFP_ATOMIC);
- } while (!err && usX2Y->US04->submitted < usX2Y->US04->len);
- } else
- if (us428ctls && us428ctls->p4outLast >= 0 && us428ctls->p4outLast < N_us428_p4out_BUFS) {
- if (us428ctls->p4outLast != us428ctls->p4outSent) {
- int j, send = us428ctls->p4outSent + 1;
- if (send >= N_us428_p4out_BUFS)
- send = 0;
- for (j = 0; j < URBS_AsyncSeq && !err; ++j)
- if (0 == usX2Y->AS04.urb[j]->status) {
- struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost.
- usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev,
- usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol,
- p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5,
- i_usX2Y_Out04Int, usX2Y);
- err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC);
- us428ctls->p4outSent = send;
- break;
- }
- }
- }
-
- if (err)
- snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);
-
- urb->dev = usX2Y->dev;
- usb_submit_urb(urb, GFP_ATOMIC);
-}
-
-/*
- * Prepare some urbs
- */
-int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y)
-{
- int err = 0,
- i;
-
- if (NULL == (usX2Y->AS04.buffer = kmalloc(URB_DataLen_AsyncSeq*URBS_AsyncSeq, GFP_KERNEL))) {
- err = -ENOMEM;
- } else
- for (i = 0; i < URBS_AsyncSeq; ++i) {
- if (NULL == (usX2Y->AS04.urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
- err = -ENOMEM;
- break;
- }
- usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev,
- usb_sndbulkpipe(usX2Y->dev, 0x04),
- usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0,
- i_usX2Y_Out04Int, usX2Y
- );
- }
- return err;
-}
-
-int usX2Y_In04_init(struct usX2Ydev *usX2Y)
-{
- if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL)))
- return -ENOMEM;
-
- if (! (usX2Y->In04Buf = kmalloc(21, GFP_KERNEL))) {
- usb_free_urb(usX2Y->In04urb);
- return -ENOMEM;
- }
-
- init_waitqueue_head(&usX2Y->In04WaitQueue);
- usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4),
- usX2Y->In04Buf, 21,
- i_usX2Y_In04Int, usX2Y,
- 10);
- return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
-}
-
-static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S)
-{
- int i;
- for (i = 0; i < URBS_AsyncSeq; ++i) {
- if (S[i].urb) {
- usb_kill_urb(S->urb[i]);
- usb_free_urb(S->urb[i]);
- S->urb[i] = NULL;
- }
- }
- kfree(S->buffer);
-}
-
-
-static struct usb_device_id snd_usX2Y_usb_id_table[] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x1604,
- .idProduct = USB_ID_US428
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x1604,
- .idProduct = USB_ID_US122
- },
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x1604,
- .idProduct = USB_ID_US224
- },
- { /* terminator */ }
-};
-
-static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
-{
- int dev;
- struct snd_card * card;
- int err;
-
- for (dev = 0; dev < SNDRV_CARDS; ++dev)
- if (enable[dev] && !snd_usX2Y_card_used[dev])
- break;
- if (dev >= SNDRV_CARDS)
- return -ENODEV;
- err = snd_card_create(index[dev], id[dev], THIS_MODULE,
- sizeof(struct usX2Ydev), &card);
- if (err < 0)
- return err;
- snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
- card->private_free = snd_usX2Y_card_private_free;
- usX2Y(card)->dev = device;
- init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
- mutex_init(&usX2Y(card)->prepare_mutex);
- INIT_LIST_HEAD(&usX2Y(card)->midi_list);
- strcpy(card->driver, "USB "NAME_ALLCAPS"");
- sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
- sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
- card->shortname,
- le16_to_cpu(device->descriptor.idVendor),
- le16_to_cpu(device->descriptor.idProduct),
- 0,//us428(card)->usbmidi.ifnum,
- usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum
- );
- *cardp = card;
- return 0;
-}
-
-
-static int usX2Y_usb_probe(struct usb_device *device,
- struct usb_interface *intf,
- const struct usb_device_id *device_id,
- struct snd_card **cardp)
-{
- int err;
- struct snd_card * card;
-
- *cardp = NULL;
- if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
- (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
- le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
- le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
- return -EINVAL;
-
- err = usX2Y_create_card(device, &card);
- if (err < 0)
- return err;
- snd_card_set_dev(card, &intf->dev);
- if ((err = usX2Y_hwdep_new(card, device)) < 0 ||
- (err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
- *cardp = card;
- return 0;
-}
-
-/*
- * new 2.5 USB kernel API
- */
-static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct snd_card *card;
- int err;
-
- err = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id, &card);
- if (err < 0)
- return err;
- dev_set_drvdata(&intf->dev, card);
- return 0;
-}
-
-static void snd_usX2Y_disconnect(struct usb_interface *intf)
-{
- usX2Y_usb_disconnect(interface_to_usbdev(intf),
- usb_get_intfdata(intf));
-}
-
-MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);
-static struct usb_driver snd_usX2Y_usb_driver = {
- .name = "snd-usb-usx2y",
- .probe = snd_usX2Y_probe,
- .disconnect = snd_usX2Y_disconnect,
- .id_table = snd_usX2Y_usb_id_table,
-};
-
-static void snd_usX2Y_card_private_free(struct snd_card *card)
-{
- kfree(usX2Y(card)->In04Buf);
- usb_free_urb(usX2Y(card)->In04urb);
- if (usX2Y(card)->us428ctls_sharedmem)
- snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem));
- if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS)
- snd_usX2Y_card_used[usX2Y(card)->card_index] = 0;
-}
-
-/*
- * Frees the device.
- */
-static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr)
-{
- if (ptr) {
- struct snd_card *card = ptr;
- struct usX2Ydev *usX2Y = usX2Y(card);
- struct list_head *p;
- usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
- usX2Y_unlinkSeq(&usX2Y->AS04);
- usb_kill_urb(usX2Y->In04urb);
- snd_card_disconnect(card);
- /* release the midi resources */
- list_for_each(p, &usX2Y->midi_list) {
- snd_usbmidi_disconnect(p);
- }
- if (usX2Y->us428ctls_sharedmem)
- wake_up(&usX2Y->us428ctls_wait_queue_head);
- snd_card_free(card);
- }
-}
-
-module_usb_driver(snd_usX2Y_usb_driver);
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.h b/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.h
deleted file mode 100644
index e43c0a86..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2y.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef USBUSX2Y_H
-#define USBUSX2Y_H
-#include "../usbaudio.h"
-#include "../midi.h"
-#include "usbus428ctldefs.h"
-
-#define NRURBS 2
-
-
-#define URBS_AsyncSeq 10
-#define URB_DataLen_AsyncSeq 32
-struct snd_usX2Y_AsyncSeq {
- struct urb *urb[URBS_AsyncSeq];
- char *buffer;
-};
-
-struct snd_usX2Y_urbSeq {
- int submitted;
- int len;
- struct urb *urb[0];
-};
-
-#include "usx2yhwdeppcm.h"
-
-struct usX2Ydev {
- struct usb_device *dev;
- int card_index;
- int stride;
- struct urb *In04urb;
- void *In04Buf;
- char In04Last[24];
- unsigned In04IntCalls;
- struct snd_usX2Y_urbSeq *US04;
- wait_queue_head_t In04WaitQueue;
- struct snd_usX2Y_AsyncSeq AS04;
- unsigned int rate,
- format;
- int chip_status;
- struct mutex prepare_mutex;
- struct us428ctls_sharedmem *us428ctls_sharedmem;
- int wait_iso_frame;
- wait_queue_head_t us428ctls_wait_queue_head;
- struct snd_usX2Y_hwdep_pcm_shm *hwdep_pcm_shm;
- struct snd_usX2Y_substream *subs[4];
- struct snd_usX2Y_substream * volatile prepare_subs;
- wait_queue_head_t prepare_wait_queue;
- struct list_head midi_list;
- struct list_head pcm_list;
- int pcm_devs;
-};
-
-
-struct snd_usX2Y_substream {
- struct usX2Ydev *usX2Y;
- struct snd_pcm_substream *pcm_substream;
-
- int endpoint;
- unsigned int maxpacksize; /* max packet size in bytes */
-
- atomic_t state;
-#define state_STOPPED 0
-#define state_STARTING1 1
-#define state_STARTING2 2
-#define state_STARTING3 3
-#define state_PREPARED 4
-#define state_PRERUNNING 6
-#define state_RUNNING 8
-
- int hwptr; /* free frame position in the buffer (only for playback) */
- int hwptr_done; /* processed frame position in the buffer */
- int transfer_done; /* processed frames since last period update */
-
- struct urb *urb[NRURBS]; /* data urb table */
- struct urb *completed_urb;
- char *tmpbuf; /* temporary buffer for playback */
-};
-
-
-#define usX2Y(c) ((struct usX2Ydev *)(c)->private_data)
-
-int usX2Y_audio_create(struct snd_card *card);
-
-int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y);
-int usX2Y_In04_init(struct usX2Ydev *usX2Y);
-
-#define NAME_ALLCAPS "US-X2Y"
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2yaudio.c b/ANDROID_3.4.5/sound/usb/usx2y/usbusx2yaudio.c
deleted file mode 100644
index 520ef96d..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usbusx2yaudio.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-/*
- * US-X2Y AUDIO
- * Copyright (c) 2002-2004 by Karsten Wiese
- *
- * based on
- *
- * (Tentative) USB Audio Driver for ALSA
- *
- * Main and PCM part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- * Many codes borrowed from audio.c by
- * Alan Cox (alan@lxorguk.ukuu.org.uk)
- * Thomas Sailer (sailer@ife.ee.ethz.ch)
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/moduleparam.h>
-#include <sound/core.h>
-#include <sound/info.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include "usx2y.h"
-#include "usbusx2y.h"
-
-#define USX2Y_NRPACKS 4 /* Default value used for nr of packs per urb.
- 1 to 4 have been tested ok on uhci.
- To use 3 on ohci, you'd need a patch:
- look for "0000425-linux-2.6.9-rc4-mm1_ohci-hcd.patch.gz" on
- "https://bugtrack.alsa-project.org/alsa-bug/bug_view_page.php?bug_id=0000425"
- .
- 1, 2 and 4 work out of the box on ohci, if I recall correctly.
- Bigger is safer operation,
- smaller gives lower latencies.
- */
-#define USX2Y_NRPACKS_VARIABLE y /* If your system works ok with this module's parameter
- nrpacks set to 1, you might as well comment
- this #define out, and thereby produce smaller, faster code.
- You'd also set USX2Y_NRPACKS to 1 then.
- */
-
-#ifdef USX2Y_NRPACKS_VARIABLE
- static int nrpacks = USX2Y_NRPACKS; /* number of packets per urb */
- #define nr_of_packs() nrpacks
- module_param(nrpacks, int, 0444);
- MODULE_PARM_DESC(nrpacks, "Number of packets per URB.");
-#else
- #define nr_of_packs() USX2Y_NRPACKS
-#endif
-
-
-static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
-{
- struct urb *urb = subs->completed_urb;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- unsigned char *cp;
- int i, len, lens = 0, hwptr_done = subs->hwptr_done;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- for (i = 0; i < nr_of_packs(); i++) {
- cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk(KERN_ERR "active frame status %i. "
- "Most probably some hardware problem.\n",
- urb->iso_frame_desc[i].status);
- return urb->iso_frame_desc[i].status;
- }
- len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
- if (! len) {
- snd_printd("0 == len ERROR!\n");
- continue;
- }
-
- /* copy a data chunk */
- if ((hwptr_done + len) > runtime->buffer_size) {
- int cnt = runtime->buffer_size - hwptr_done;
- int blen = cnt * usX2Y->stride;
- memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, blen);
- memcpy(runtime->dma_area, cp + blen, len * usX2Y->stride - blen);
- } else {
- memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp,
- len * usX2Y->stride);
- }
- lens += len;
- if ((hwptr_done += len) >= runtime->buffer_size)
- hwptr_done -= runtime->buffer_size;
- }
-
- subs->hwptr_done = hwptr_done;
- subs->transfer_done += lens;
- /* update the pointer, call callback if necessary */
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- snd_pcm_period_elapsed(subs->pcm_substream);
- }
- return 0;
-}
-/*
- * prepare urb for playback data pipe
- *
- * we copy the data directly from the pcm buffer.
- * the current position to be copied is held in hwptr field.
- * since a urb can handle only a single linear buffer, if the total
- * transferred area overflows the buffer boundary, we cannot send
- * it directly from the buffer. thus the data is once copied to
- * a temporary buffer and urb points to that.
- */
-static int usX2Y_urb_play_prepare(struct snd_usX2Y_substream *subs,
- struct urb *cap_urb,
- struct urb *urb)
-{
- int count, counts, pack;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
-
- count = 0;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- /* calculate the size of a packet */
- counts = cap_urb->iso_frame_desc[pack].actual_length / usX2Y->stride;
- count += counts;
- if (counts < 43 || counts > 50) {
- snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
- return -EPIPE;
- }
- /* set up descriptor */
- urb->iso_frame_desc[pack].offset = pack ?
- urb->iso_frame_desc[pack - 1].offset +
- urb->iso_frame_desc[pack - 1].length :
- 0;
- urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
- }
- if (atomic_read(&subs->state) >= state_PRERUNNING)
- if (subs->hwptr + count > runtime->buffer_size) {
- /* err, the transferred area goes over buffer boundary.
- * copy the data to the temp buffer.
- */
- int len;
- len = runtime->buffer_size - subs->hwptr;
- urb->transfer_buffer = subs->tmpbuf;
- memcpy(subs->tmpbuf, runtime->dma_area +
- subs->hwptr * usX2Y->stride, len * usX2Y->stride);
- memcpy(subs->tmpbuf + len * usX2Y->stride,
- runtime->dma_area, (count - len) * usX2Y->stride);
- subs->hwptr += count;
- subs->hwptr -= runtime->buffer_size;
- } else {
- /* set the buffer pointer */
- urb->transfer_buffer = runtime->dma_area + subs->hwptr * usX2Y->stride;
- if ((subs->hwptr += count) >= runtime->buffer_size)
- subs->hwptr -= runtime->buffer_size;
- }
- else
- urb->transfer_buffer = subs->tmpbuf;
- urb->transfer_buffer_length = count * usX2Y->stride;
- return 0;
-}
-
-/*
- * process after playback data complete
- *
- * update the current position and call callback if a period is processed.
- */
-static void usX2Y_urb_play_retire(struct snd_usX2Y_substream *subs, struct urb *urb)
-{
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- int len = urb->actual_length / subs->usX2Y->stride;
-
- subs->transfer_done += len;
- subs->hwptr_done += len;
- if (subs->hwptr_done >= runtime->buffer_size)
- subs->hwptr_done -= runtime->buffer_size;
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- snd_pcm_period_elapsed(subs->pcm_substream);
- }
-}
-
-static int usX2Y_urb_submit(struct snd_usX2Y_substream *subs, struct urb *urb, int frame)
-{
- int err;
- if (!urb)
- return -ENODEV;
- urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks
- urb->hcpriv = NULL;
- urb->dev = subs->usX2Y->dev; /* we need to set this at each time */
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
- return err;
- }
- return 0;
-}
-
-static inline int usX2Y_usbframe_complete(struct snd_usX2Y_substream *capsubs,
- struct snd_usX2Y_substream *playbacksubs,
- int frame)
-{
- int err, state;
- struct urb *urb = playbacksubs->completed_urb;
-
- state = atomic_read(&playbacksubs->state);
- if (NULL != urb) {
- if (state == state_RUNNING)
- usX2Y_urb_play_retire(playbacksubs, urb);
- else if (state >= state_PRERUNNING)
- atomic_inc(&playbacksubs->state);
- } else {
- switch (state) {
- case state_STARTING1:
- urb = playbacksubs->urb[0];
- atomic_inc(&playbacksubs->state);
- break;
- case state_STARTING2:
- urb = playbacksubs->urb[1];
- atomic_inc(&playbacksubs->state);
- break;
- }
- }
- if (urb) {
- if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
- (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
- return err;
- }
- }
-
- playbacksubs->completed_urb = NULL;
-
- state = atomic_read(&capsubs->state);
- if (state >= state_PREPARED) {
- if (state == state_RUNNING) {
- if ((err = usX2Y_urb_capt_retire(capsubs)))
- return err;
- } else if (state >= state_PRERUNNING)
- atomic_inc(&capsubs->state);
- if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
- return err;
- }
- capsubs->completed_urb = NULL;
- return 0;
-}
-
-
-static void usX2Y_clients_stop(struct usX2Ydev *usX2Y)
-{
- int s, u;
-
- for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
- if (subs) {
- snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
- atomic_set(&subs->state, state_STOPPED);
- }
- }
- for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
- if (subs) {
- if (atomic_read(&subs->state) >= state_PRERUNNING) {
- snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
- }
- for (u = 0; u < NRURBS; u++) {
- struct urb *urb = subs->urb[u];
- if (NULL != urb)
- snd_printdd("%i status=%i start_frame=%i\n",
- u, urb->status, urb->start_frame);
- }
- }
- }
- usX2Y->prepare_subs = NULL;
- wake_up(&usX2Y->prepare_wait_queue);
-}
-
-static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y,
- struct snd_usX2Y_substream *subs, struct urb *urb)
-{
- snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
- urb->status = 0;
- usX2Y_clients_stop(usX2Y);
-}
-
-static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
- struct snd_usX2Y_substream *subs, struct urb *urb)
-{
- snd_printk(KERN_ERR
-"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
-"Most probably some urb of usb-frame %i is still missing.\n"
-"Cause could be too long delays in usb-hcd interrupt handling.\n",
- usb_get_current_frame_number(usX2Y->dev),
- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
- usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
- usX2Y_clients_stop(usX2Y);
-}
-
-static void i_usX2Y_urb_complete(struct urb *urb)
-{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
- snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
- usb_get_current_frame_number(usX2Y->dev),
- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
- urb->status, urb->start_frame);
- return;
- }
- if (unlikely(urb->status)) {
- usX2Y_error_urb_status(usX2Y, subs, urb);
- return;
- }
- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
- subs->completed_urb = urb;
- else {
- usX2Y_error_sequence(usX2Y, subs, urb);
- return;
- }
- {
- struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
- *playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (capsubs->completed_urb &&
- atomic_read(&capsubs->state) >= state_PREPARED &&
- (playbacksubs->completed_urb ||
- atomic_read(&playbacksubs->state) < state_PREPARED)) {
- if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame))
- usX2Y->wait_iso_frame += nr_of_packs();
- else {
- snd_printdd("\n");
- usX2Y_clients_stop(usX2Y);
- }
- }
- }
-}
-
-static void usX2Y_urbs_set_complete(struct usX2Ydev * usX2Y,
- void (*complete)(struct urb *))
-{
- int s, u;
- for (s = 0; s < 4; s++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[s];
- if (NULL != subs)
- for (u = 0; u < NRURBS; u++) {
- struct urb * urb = subs->urb[u];
- if (NULL != urb)
- urb->complete = complete;
- }
- }
-}
-
-static void usX2Y_subs_startup_finish(struct usX2Ydev * usX2Y)
-{
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
- usX2Y->prepare_subs = NULL;
-}
-
-static void i_usX2Y_subs_startup(struct urb *urb)
-{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
- if (NULL != prepare_subs)
- if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
- usX2Y_subs_startup_finish(usX2Y);
- atomic_inc(&prepare_subs->state);
- wake_up(&usX2Y->prepare_wait_queue);
- }
-
- i_usX2Y_urb_complete(urb);
-}
-
-static void usX2Y_subs_prepare(struct snd_usX2Y_substream *subs)
-{
- snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n",
- subs, subs->endpoint, subs->urb[0], subs->urb[1]);
- /* reset the pointer */
- subs->hwptr = 0;
- subs->hwptr_done = 0;
- subs->transfer_done = 0;
-}
-
-
-static void usX2Y_urb_release(struct urb **urb, int free_tb)
-{
- if (*urb) {
- usb_kill_urb(*urb);
- if (free_tb)
- kfree((*urb)->transfer_buffer);
- usb_free_urb(*urb);
- *urb = NULL;
- }
-}
-/*
- * release a substreams urbs
- */
-static void usX2Y_urbs_release(struct snd_usX2Y_substream *subs)
-{
- int i;
- snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint);
- for (i = 0; i < NRURBS; i++)
- usX2Y_urb_release(subs->urb + i,
- subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
-
- kfree(subs->tmpbuf);
- subs->tmpbuf = NULL;
-}
-/*
- * initialize a substream's urbs
- */
-static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
-{
- int i;
- unsigned int pipe;
- int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- struct usb_device *dev = subs->usX2Y->dev;
-
- pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
- usb_rcvisocpipe(dev, subs->endpoint);
- subs->maxpacksize = usb_maxpacket(dev, pipe, is_playback);
- if (!subs->maxpacksize)
- return -EINVAL;
-
- if (is_playback && NULL == subs->tmpbuf) { /* allocate a temporary buffer for playback */
- subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL);
- if (NULL == subs->tmpbuf) {
- snd_printk(KERN_ERR "cannot malloc tmpbuf\n");
- return -ENOMEM;
- }
- }
- /* allocate and initialize data urbs */
- for (i = 0; i < NRURBS; i++) {
- struct urb **purb = subs->urb + i;
- if (*purb) {
- usb_kill_urb(*purb);
- continue;
- }
- *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
- if (NULL == *purb) {
- usX2Y_urbs_release(subs);
- return -ENOMEM;
- }
- if (!is_playback && !(*purb)->transfer_buffer) {
- /* allocate a capture buffer per urb */
- (*purb)->transfer_buffer = kmalloc(subs->maxpacksize * nr_of_packs(), GFP_KERNEL);
- if (NULL == (*purb)->transfer_buffer) {
- usX2Y_urbs_release(subs);
- return -ENOMEM;
- }
- }
- (*purb)->dev = dev;
- (*purb)->pipe = pipe;
- (*purb)->number_of_packets = nr_of_packs();
- (*purb)->context = subs;
- (*purb)->interval = 1;
- (*purb)->complete = i_usX2Y_subs_startup;
- }
- return 0;
-}
-
-static void usX2Y_subs_startup(struct snd_usX2Y_substream *subs)
-{
- struct usX2Ydev *usX2Y = subs->usX2Y;
- usX2Y->prepare_subs = subs;
- subs->urb[0]->start_frame = -1;
- wmb();
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
-}
-
-static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
-{
- int i, err;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- if ((err = usX2Y_urbs_allocate(subs)) < 0)
- return err;
- subs->completed_urb = NULL;
- for (i = 0; i < 4; i++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[i];
- if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
- goto start;
- }
-
- start:
- usX2Y_subs_startup(subs);
- for (i = 0; i < NRURBS; i++) {
- struct urb *urb = subs->urb[i];
- if (usb_pipein(urb->pipe)) {
- unsigned long pack;
- if (0 == i)
- atomic_set(&subs->state, state_STARTING3);
- urb->dev = usX2Y->dev;
- urb->transfer_flags = URB_ISO_ASAP;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
- urb->iso_frame_desc[pack].length = subs->maxpacksize;
- }
- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
- if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
- snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
- err = -EPIPE;
- goto cleanup;
- } else
- if (i == 0)
- usX2Y->wait_iso_frame = urb->start_frame;
- urb->transfer_flags = 0;
- } else {
- atomic_set(&subs->state, state_STARTING1);
- break;
- }
- }
- err = 0;
- wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
- if (atomic_read(&subs->state) != state_PREPARED)
- err = -EPIPE;
-
- cleanup:
- if (err) {
- usX2Y_subs_startup_finish(usX2Y);
- usX2Y_clients_stop(usX2Y); // something is completely wroong > stop evrything
- }
- return err;
-}
-
-/*
- * return the current pcm pointer. just return the hwptr_done value.
- */
-static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(struct snd_pcm_substream *substream)
-{
- struct snd_usX2Y_substream *subs = substream->runtime->private_data;
- return subs->hwptr_done;
-}
-/*
- * start/stop substream
- */
-static int snd_usX2Y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_usX2Y_substream *subs = substream->runtime->private_data;
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- snd_printdd("snd_usX2Y_pcm_trigger(START)\n");
- if (atomic_read(&subs->state) == state_PREPARED &&
- atomic_read(&subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]->state) >= state_PREPARED) {
- atomic_set(&subs->state, state_PRERUNNING);
- } else {
- snd_printdd("\n");
- return -EPIPE;
- }
- break;
- case SNDRV_PCM_TRIGGER_STOP:
- snd_printdd("snd_usX2Y_pcm_trigger(STOP)\n");
- if (atomic_read(&subs->state) >= state_PRERUNNING)
- atomic_set(&subs->state, state_PREPARED);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-
-/*
- * allocate a buffer, setup samplerate
- *
- * so far we use a physically linear buffer although packetize transfer
- * doesn't need a continuous area.
- * if sg buffer is supported on the later version of alsa, we'll follow
- * that.
- */
-static struct s_c2
-{
- char c1, c2;
-}
- SetRate44100[] =
-{
- { 0x14, 0x08}, // this line sets 44100, well actually a little less
- { 0x18, 0x40}, // only tascam / frontier design knows the further lines .......
- { 0x18, 0x42},
- { 0x18, 0x45},
- { 0x18, 0x46},
- { 0x18, 0x48},
- { 0x18, 0x4A},
- { 0x18, 0x4C},
- { 0x18, 0x4E},
- { 0x18, 0x50},
- { 0x18, 0x52},
- { 0x18, 0x54},
- { 0x18, 0x56},
- { 0x18, 0x58},
- { 0x18, 0x5A},
- { 0x18, 0x5C},
- { 0x18, 0x5E},
- { 0x18, 0x60},
- { 0x18, 0x62},
- { 0x18, 0x64},
- { 0x18, 0x66},
- { 0x18, 0x68},
- { 0x18, 0x6A},
- { 0x18, 0x6C},
- { 0x18, 0x6E},
- { 0x18, 0x70},
- { 0x18, 0x72},
- { 0x18, 0x74},
- { 0x18, 0x76},
- { 0x18, 0x78},
- { 0x18, 0x7A},
- { 0x18, 0x7C},
- { 0x18, 0x7E}
-};
-static struct s_c2 SetRate48000[] =
-{
- { 0x14, 0x09}, // this line sets 48000, well actually a little less
- { 0x18, 0x40}, // only tascam / frontier design knows the further lines .......
- { 0x18, 0x42},
- { 0x18, 0x45},
- { 0x18, 0x46},
- { 0x18, 0x48},
- { 0x18, 0x4A},
- { 0x18, 0x4C},
- { 0x18, 0x4E},
- { 0x18, 0x50},
- { 0x18, 0x52},
- { 0x18, 0x54},
- { 0x18, 0x56},
- { 0x18, 0x58},
- { 0x18, 0x5A},
- { 0x18, 0x5C},
- { 0x18, 0x5E},
- { 0x18, 0x60},
- { 0x18, 0x62},
- { 0x18, 0x64},
- { 0x18, 0x66},
- { 0x18, 0x68},
- { 0x18, 0x6A},
- { 0x18, 0x6C},
- { 0x18, 0x6E},
- { 0x18, 0x70},
- { 0x18, 0x73},
- { 0x18, 0x74},
- { 0x18, 0x76},
- { 0x18, 0x78},
- { 0x18, 0x7A},
- { 0x18, 0x7C},
- { 0x18, 0x7E}
-};
-#define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
-
-static void i_usX2Y_04Int(struct urb *urb)
-{
- struct usX2Ydev *usX2Y = urb->context;
-
- if (urb->status)
- snd_printk(KERN_ERR "snd_usX2Y_04Int() urb->status=%i\n", urb->status);
- if (0 == --usX2Y->US04->len)
- wake_up(&usX2Y->In04WaitQueue);
-}
-
-static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
-{
- int err = 0, i;
- struct snd_usX2Y_urbSeq *us = NULL;
- int *usbdata = NULL;
- struct s_c2 *ra = rate == 48000 ? SetRate48000 : SetRate44100;
-
- if (usX2Y->rate != rate) {
- us = kzalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
- if (NULL == us) {
- err = -ENOMEM;
- goto cleanup;
- }
- usbdata = kmalloc(sizeof(int) * NOOF_SETRATE_URBS, GFP_KERNEL);
- if (NULL == usbdata) {
- err = -ENOMEM;
- goto cleanup;
- }
- for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
- if (NULL == (us->urb[i] = usb_alloc_urb(0, GFP_KERNEL))) {
- err = -ENOMEM;
- goto cleanup;
- }
- ((char*)(usbdata + i))[0] = ra[i].c1;
- ((char*)(usbdata + i))[1] = ra[i].c2;
- usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
- usbdata + i, 2, i_usX2Y_04Int, usX2Y);
-#ifdef OLD_USB
- us->urb[i]->transfer_flags = USB_QUEUE_BULK;
-#endif
- }
- us->submitted = 0;
- us->len = NOOF_SETRATE_URBS;
- usX2Y->US04 = us;
- wait_event_timeout(usX2Y->In04WaitQueue, 0 == us->len, HZ);
- usX2Y->US04 = NULL;
- if (us->len)
- err = -ENODEV;
- cleanup:
- if (us) {
- us->submitted = 2*NOOF_SETRATE_URBS;
- for (i = 0; i < NOOF_SETRATE_URBS; ++i) {
- struct urb *urb = us->urb[i];
- if (urb->status) {
- if (!err)
- err = -ENODEV;
- usb_kill_urb(urb);
- }
- usb_free_urb(urb);
- }
- usX2Y->US04 = NULL;
- kfree(usbdata);
- kfree(us);
- if (!err)
- usX2Y->rate = rate;
- }
- }
-
- return err;
-}
-
-
-static int usX2Y_format_set(struct usX2Ydev *usX2Y, snd_pcm_format_t format)
-{
- int alternate, err;
- struct list_head* p;
- if (format == SNDRV_PCM_FORMAT_S24_3LE) {
- alternate = 2;
- usX2Y->stride = 6;
- } else {
- alternate = 1;
- usX2Y->stride = 4;
- }
- list_for_each(p, &usX2Y->midi_list) {
- snd_usbmidi_input_stop(p);
- }
- usb_kill_urb(usX2Y->In04urb);
- if ((err = usb_set_interface(usX2Y->dev, 0, alternate))) {
- snd_printk(KERN_ERR "usb_set_interface error \n");
- return err;
- }
- usX2Y->In04urb->dev = usX2Y->dev;
- err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
- list_for_each(p, &usX2Y->midi_list) {
- snd_usbmidi_input_start(p);
- }
- usX2Y->format = format;
- usX2Y->rate = 0;
- return err;
-}
-
-
-static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- int err = 0;
- unsigned int rate = params_rate(hw_params);
- snd_pcm_format_t format = params_format(hw_params);
- struct snd_card *card = substream->pstr->pcm->card;
- struct list_head *list;
-
- snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
- // all pcm substreams off one usX2Y have to operate at the same rate & format
- list_for_each(list, &card->devices) {
- struct snd_device *dev;
- struct snd_pcm *pcm;
- int s;
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- for (s = 0; s < 2; ++s) {
- struct snd_pcm_substream *test_substream;
- test_substream = pcm->streams[s].substream;
- if (test_substream && test_substream != substream &&
- test_substream->runtime &&
- ((test_substream->runtime->format &&
- test_substream->runtime->format != format) ||
- (test_substream->runtime->rate &&
- test_substream->runtime->rate != rate)))
- return -EINVAL;
- }
- }
- if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
- snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",
- substream, params_buffer_bytes(hw_params), err);
- return err;
- }
- return 0;
-}
-
-/*
- * free the buffer
- */
-static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- mutex_lock(&subs->usX2Y->prepare_mutex);
- snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
-
- if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
- struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_urbs_release(subs);
- if (!cap_subs->pcm_substream ||
- !cap_subs->pcm_substream->runtime ||
- !cap_subs->pcm_substream->runtime->status ||
- cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
- atomic_set(&cap_subs->state, state_STOPPED);
- usX2Y_urbs_release(cap_subs);
- }
- } else {
- struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (atomic_read(&playback_subs->state) < state_PREPARED) {
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_urbs_release(subs);
- }
- }
- mutex_unlock(&subs->usX2Y->prepare_mutex);
- return snd_pcm_lib_free_pages(substream);
-}
-/*
- * prepare callback
- *
- * set format and initialize urbs
- */
-static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- int err = 0;
- snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
-
- mutex_lock(&usX2Y->prepare_mutex);
- usX2Y_subs_prepare(subs);
-// Start hardware streams
-// SyncStream first....
- if (atomic_read(&capsubs->state) < state_PREPARED) {
- if (usX2Y->format != runtime->format)
- if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
- goto up_prepare_mutex;
- if (usX2Y->rate != runtime->rate)
- if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
- goto up_prepare_mutex;
- snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
- if (0 > (err = usX2Y_urbs_start(capsubs)))
- goto up_prepare_mutex;
- }
-
- if (subs != capsubs && atomic_read(&subs->state) < state_PREPARED)
- err = usX2Y_urbs_start(subs);
-
- up_prepare_mutex:
- mutex_unlock(&usX2Y->prepare_mutex);
- return err;
-}
-
-static struct snd_pcm_hardware snd_usX2Y_2c =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID |
- SNDRV_PCM_INFO_BATCH),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 2,
- .buffer_bytes_max = (2*128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0
-};
-
-
-
-static int snd_usX2Y_pcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_usX2Y_substream *subs = ((struct snd_usX2Y_substream **)
- snd_pcm_substream_chip(substream))[substream->stream];
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
- return -EBUSY;
-
- runtime->hw = snd_usX2Y_2c;
- runtime->private_data = subs;
- subs->pcm_substream = substream;
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
- return 0;
-}
-
-
-
-static int snd_usX2Y_pcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
-
- subs->pcm_substream = NULL;
-
- return 0;
-}
-
-
-static struct snd_pcm_ops snd_usX2Y_pcm_ops =
-{
- .open = snd_usX2Y_pcm_open,
- .close = snd_usX2Y_pcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usX2Y_pcm_hw_params,
- .hw_free = snd_usX2Y_pcm_hw_free,
- .prepare = snd_usX2Y_pcm_prepare,
- .trigger = snd_usX2Y_pcm_trigger,
- .pointer = snd_usX2Y_pcm_pointer,
-};
-
-
-/*
- * free a usb stream instance
- */
-static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream)
-{
- kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]);
- usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK] = NULL;
-
- kfree(usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]);
- usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL;
-}
-
-static void snd_usX2Y_pcm_private_free(struct snd_pcm *pcm)
-{
- struct snd_usX2Y_substream **usX2Y_stream = pcm->private_data;
- if (usX2Y_stream)
- usX2Y_audio_stream_free(usX2Y_stream);
-}
-
-static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint, int capture_endpoint)
-{
- struct snd_pcm *pcm;
- int err, i;
- struct snd_usX2Y_substream **usX2Y_substream =
- usX2Y(card)->subs + 2 * usX2Y(card)->pcm_devs;
-
- for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
- i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
- usX2Y_substream[i] = kzalloc(sizeof(struct snd_usX2Y_substream), GFP_KERNEL);
- if (NULL == usX2Y_substream[i]) {
- snd_printk(KERN_ERR "cannot malloc\n");
- return -ENOMEM;
- }
- usX2Y_substream[i]->usX2Y = usX2Y(card);
- }
-
- if (playback_endpoint)
- usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
- usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
-
- err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->pcm_devs,
- playback_endpoint ? 1 : 0, 1,
- &pcm);
- if (err < 0) {
- usX2Y_audio_stream_free(usX2Y_substream);
- return err;
- }
-
- if (playback_endpoint)
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_pcm_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_pcm_ops);
-
- pcm->private_data = usX2Y_substream;
- pcm->private_free = snd_usX2Y_pcm_private_free;
- pcm->info_flags = 0;
-
- sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->pcm_devs);
-
- if ((playback_endpoint &&
- 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 128*1024))) ||
- 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 128*1024))) {
- snd_usX2Y_pcm_private_free(pcm);
- return err;
- }
- usX2Y(card)->pcm_devs++;
-
- return 0;
-}
-
-/*
- * create a chip instance and set its names.
- */
-int usX2Y_audio_create(struct snd_card *card)
-{
- int err = 0;
-
- INIT_LIST_HEAD(&usX2Y(card)->pcm_list);
-
- if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
- return err;
- if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) == USB_ID_US428)
- if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
- return err;
- if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) != USB_ID_US122)
- err = usX2Y_rate_set(usX2Y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122.
- return err;
-}
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usx2y.h b/ANDROID_3.4.5/sound/usb/usx2y/usx2y.h
deleted file mode 100644
index 7e59263d..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usx2y.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Driver for Tascam US-X2Y USB soundcards
- *
- * Copyright (c) 2003 by Karsten Wiese <annabellesgarden@yahoo.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SOUND_USX2Y_COMMON_H
-#define __SOUND_USX2Y_COMMON_H
-
-
-#define USX2Y_DRIVER_VERSION 0x0100 /* 0.1.0 */
-
-
-/* hwdep id string */
-#define SND_USX2Y_LOADER_ID "USX2Y Loader"
-#define SND_USX2Y_USBPCM_ID "USX2Y USBPCM"
-
-/* hardware type */
-enum {
- USX2Y_TYPE_122,
- USX2Y_TYPE_224,
- USX2Y_TYPE_428,
- USX2Y_TYPE_NUMS
-};
-
-#define USB_ID_US122 0x8007
-#define USB_ID_US224 0x8005
-#define USB_ID_US428 0x8001
-
-/* chip status */
-enum {
- USX2Y_STAT_CHIP_INIT = (1 << 0), /* all operational */
- USX2Y_STAT_CHIP_MMAP_PCM_URBS = (1 << 1), /* pcm transport over mmaped urbs */
- USX2Y_STAT_CHIP_HUP = (1 << 31), /* all operational */
-};
-
-#endif /* __SOUND_USX2Y_COMMON_H */
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.c b/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.c
deleted file mode 100644
index 8e40b6e6..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.c
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* USX2Y "rawusb" aka hwdep_pcm implementation
-
- Its usb's unableness to atomically handle power of 2 period sized data chuncs
- at standard samplerates,
- what led to this part of the usx2y module:
- It provides the alsa kernel half of the usx2y-alsa-jack driver pair.
- The pair uses a hardware dependent alsa-device for mmaped pcm transport.
- Advantage achieved:
- The usb_hc moves pcm data from/into memory via DMA.
- That memory is mmaped by jack's usx2y driver.
- Jack's usx2y driver is the first/last to read/write pcm data.
- Read/write is a combination of power of 2 period shaping and
- float/int conversation.
- Compared to mainline alsa/jack we leave out power of 2 period shaping inside
- snd-usb-usx2y which needs memcpy() and additional buffers.
- As a side effect possible unwanted pcm-data coruption resulting of
- standard alsa's snd-usb-usx2y period shaping scheme falls away.
- Result is sane jack operation at buffering schemes down to 128frames,
- 2 periods.
- plain usx2y alsa mode is able to achieve 64frames, 4periods, but only at the
- cost of easier triggered i.e. aeolus xruns (128 or 256frames,
- 2periods works but is useless cause of crackling).
-
- This is a first "proof of concept" implementation.
- Later, functionalities should migrate to more appropriate places:
- Userland:
- - The jackd could mmap its float-pcm buffers directly from alsa-lib.
- - alsa-lib could provide power of 2 period sized shaping combined with int/float
- conversation.
- Currently the usx2y jack driver provides above 2 services.
- Kernel:
- - rawusb dma pcm buffer transport should go to snd-usb-lib, so also snd-usb-audio
- devices can use it.
- Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y.
-*/
-
-#include <linux/delay.h>
-#include <linux/gfp.h>
-#include "usbusx2yaudio.c"
-
-#if defined(USX2Y_NRPACKS_VARIABLE) || USX2Y_NRPACKS == 1
-
-#include <sound/hwdep.h>
-
-
-static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
-{
- struct urb *urb = subs->completed_urb;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
- int i, lens = 0, hwptr_done = subs->hwptr_done;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- if (0 > usX2Y->hwdep_pcm_shm->capture_iso_start) { //FIXME
- int head = usX2Y->hwdep_pcm_shm->captured_iso_head + 1;
- if (head >= ARRAY_SIZE(usX2Y->hwdep_pcm_shm->captured_iso))
- head = 0;
- usX2Y->hwdep_pcm_shm->capture_iso_start = head;
- snd_printdd("cap start %i\n", head);
- }
- for (i = 0; i < nr_of_packs(); i++) {
- if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
- snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
- return urb->iso_frame_desc[i].status;
- }
- lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
- }
- if ((hwptr_done += lens) >= runtime->buffer_size)
- hwptr_done -= runtime->buffer_size;
- subs->hwptr_done = hwptr_done;
- subs->transfer_done += lens;
- /* update the pointer, call callback if necessary */
- if (subs->transfer_done >= runtime->period_size) {
- subs->transfer_done -= runtime->period_size;
- snd_pcm_period_elapsed(subs->pcm_substream);
- }
- return 0;
-}
-
-static inline int usX2Y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
- struct usX2Ydev * usX2Y)
-{
- return (runtime->buffer_size * 1000) / usX2Y->rate + 1; //FIXME: so far only correct period_size == 2^x ?
-}
-
-/*
- * prepare urb for playback data pipe
- *
- * we copy the data directly from the pcm buffer.
- * the current position to be copied is held in hwptr field.
- * since a urb can handle only a single linear buffer, if the total
- * transferred area overflows the buffer boundary, we cannot send
- * it directly from the buffer. thus the data is once copied to
- * a temporary buffer and urb points to that.
- */
-static int usX2Y_hwdep_urb_play_prepare(struct snd_usX2Y_substream *subs,
- struct urb *urb)
-{
- int count, counts, pack;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_hwdep_pcm_shm *shm = usX2Y->hwdep_pcm_shm;
- struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
-
- if (0 > shm->playback_iso_start) {
- shm->playback_iso_start = shm->captured_iso_head -
- usX2Y_iso_frames_per_buffer(runtime, usX2Y);
- if (0 > shm->playback_iso_start)
- shm->playback_iso_start += ARRAY_SIZE(shm->captured_iso);
- shm->playback_iso_head = shm->playback_iso_start;
- }
-
- count = 0;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- /* calculate the size of a packet */
- counts = shm->captured_iso[shm->playback_iso_head].length / usX2Y->stride;
- if (counts < 43 || counts > 50) {
- snd_printk(KERN_ERR "should not be here with counts=%i\n", counts);
- return -EPIPE;
- }
- /* set up descriptor */
- urb->iso_frame_desc[pack].offset = shm->captured_iso[shm->playback_iso_head].offset;
- urb->iso_frame_desc[pack].length = shm->captured_iso[shm->playback_iso_head].length;
- if (atomic_read(&subs->state) != state_RUNNING)
- memset((char *)urb->transfer_buffer + urb->iso_frame_desc[pack].offset, 0,
- urb->iso_frame_desc[pack].length);
- if (++shm->playback_iso_head >= ARRAY_SIZE(shm->captured_iso))
- shm->playback_iso_head = 0;
- count += counts;
- }
- urb->transfer_buffer_length = count * usX2Y->stride;
- return 0;
-}
-
-
-static inline void usX2Y_usbpcm_urb_capt_iso_advance(struct snd_usX2Y_substream *subs,
- struct urb *urb)
-{
- int pack;
- for (pack = 0; pack < nr_of_packs(); ++pack) {
- struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack;
- if (NULL != subs) {
- struct snd_usX2Y_hwdep_pcm_shm *shm = subs->usX2Y->hwdep_pcm_shm;
- int head = shm->captured_iso_head + 1;
- if (head >= ARRAY_SIZE(shm->captured_iso))
- head = 0;
- shm->captured_iso[head].frame = urb->start_frame + pack;
- shm->captured_iso[head].offset = desc->offset;
- shm->captured_iso[head].length = desc->actual_length;
- shm->captured_iso_head = head;
- shm->captured_iso_frames++;
- }
- if ((desc->offset += desc->length * NRURBS*nr_of_packs()) +
- desc->length >= SSS)
- desc->offset -= (SSS - desc->length);
- }
-}
-
-static inline int usX2Y_usbpcm_usbframe_complete(struct snd_usX2Y_substream *capsubs,
- struct snd_usX2Y_substream *capsubs2,
- struct snd_usX2Y_substream *playbacksubs,
- int frame)
-{
- int err, state;
- struct urb *urb = playbacksubs->completed_urb;
-
- state = atomic_read(&playbacksubs->state);
- if (NULL != urb) {
- if (state == state_RUNNING)
- usX2Y_urb_play_retire(playbacksubs, urb);
- else if (state >= state_PRERUNNING)
- atomic_inc(&playbacksubs->state);
- } else {
- switch (state) {
- case state_STARTING1:
- urb = playbacksubs->urb[0];
- atomic_inc(&playbacksubs->state);
- break;
- case state_STARTING2:
- urb = playbacksubs->urb[1];
- atomic_inc(&playbacksubs->state);
- break;
- }
- }
- if (urb) {
- if ((err = usX2Y_hwdep_urb_play_prepare(playbacksubs, urb)) ||
- (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
- return err;
- }
- }
-
- playbacksubs->completed_urb = NULL;
-
- state = atomic_read(&capsubs->state);
- if (state >= state_PREPARED) {
- if (state == state_RUNNING) {
- if ((err = usX2Y_usbpcm_urb_capt_retire(capsubs)))
- return err;
- } else if (state >= state_PRERUNNING)
- atomic_inc(&capsubs->state);
- usX2Y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->completed_urb);
- if (NULL != capsubs2)
- usX2Y_usbpcm_urb_capt_iso_advance(NULL, capsubs2->completed_urb);
- if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
- return err;
- if (NULL != capsubs2)
- if ((err = usX2Y_urb_submit(capsubs2, capsubs2->completed_urb, frame)))
- return err;
- }
- capsubs->completed_urb = NULL;
- if (NULL != capsubs2)
- capsubs2->completed_urb = NULL;
- return 0;
-}
-
-
-static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
-{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs, *capsubs2, *playbacksubs;
-
- if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
- snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
- usb_get_current_frame_number(usX2Y->dev),
- subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
- urb->status, urb->start_frame);
- return;
- }
- if (unlikely(urb->status)) {
- usX2Y_error_urb_status(usX2Y, subs, urb);
- return;
- }
- if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
- subs->completed_urb = urb;
- else {
- usX2Y_error_sequence(usX2Y, subs, urb);
- return;
- }
-
- capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- capsubs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
- (NULL == capsubs2 || capsubs2->completed_urb) &&
- (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
- if (!usX2Y_usbpcm_usbframe_complete(capsubs, capsubs2, playbacksubs, urb->start_frame))
- usX2Y->wait_iso_frame += nr_of_packs();
- else {
- snd_printdd("\n");
- usX2Y_clients_stop(usX2Y);
- }
- }
-}
-
-
-static void usX2Y_hwdep_urb_release(struct urb **urb)
-{
- usb_kill_urb(*urb);
- usb_free_urb(*urb);
- *urb = NULL;
-}
-
-/*
- * release a substream
- */
-static void usX2Y_usbpcm_urbs_release(struct snd_usX2Y_substream *subs)
-{
- int i;
- snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint);
- for (i = 0; i < NRURBS; i++)
- usX2Y_hwdep_urb_release(subs->urb + i);
-}
-
-static void usX2Y_usbpcm_subs_startup_finish(struct usX2Ydev * usX2Y)
-{
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_urb_complete);
- usX2Y->prepare_subs = NULL;
-}
-
-static void i_usX2Y_usbpcm_subs_startup(struct urb *urb)
-{
- struct snd_usX2Y_substream *subs = urb->context;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
- if (NULL != prepare_subs &&
- urb->start_frame == prepare_subs->urb[0]->start_frame) {
- atomic_inc(&prepare_subs->state);
- if (prepare_subs == usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]) {
- struct snd_usX2Y_substream *cap_subs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- if (cap_subs2 != NULL)
- atomic_inc(&cap_subs2->state);
- }
- usX2Y_usbpcm_subs_startup_finish(usX2Y);
- wake_up(&usX2Y->prepare_wait_queue);
- }
-
- i_usX2Y_usbpcm_urb_complete(urb);
-}
-
-/*
- * initialize a substream's urbs
- */
-static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
-{
- int i;
- unsigned int pipe;
- int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- struct usb_device *dev = subs->usX2Y->dev;
-
- pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
- usb_rcvisocpipe(dev, subs->endpoint);
- subs->maxpacksize = usb_maxpacket(dev, pipe, is_playback);
- if (!subs->maxpacksize)
- return -EINVAL;
-
- /* allocate and initialize data urbs */
- for (i = 0; i < NRURBS; i++) {
- struct urb **purb = subs->urb + i;
- if (*purb) {
- usb_kill_urb(*purb);
- continue;
- }
- *purb = usb_alloc_urb(nr_of_packs(), GFP_KERNEL);
- if (NULL == *purb) {
- usX2Y_usbpcm_urbs_release(subs);
- return -ENOMEM;
- }
- (*purb)->transfer_buffer = is_playback ?
- subs->usX2Y->hwdep_pcm_shm->playback : (
- subs->endpoint == 0x8 ?
- subs->usX2Y->hwdep_pcm_shm->capture0x8 :
- subs->usX2Y->hwdep_pcm_shm->capture0xA);
-
- (*purb)->dev = dev;
- (*purb)->pipe = pipe;
- (*purb)->number_of_packets = nr_of_packs();
- (*purb)->context = subs;
- (*purb)->interval = 1;
- (*purb)->complete = i_usX2Y_usbpcm_subs_startup;
- }
- return 0;
-}
-
-/*
- * free the buffer
- */
-static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data,
- *cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
- mutex_lock(&subs->usX2Y->prepare_mutex);
- snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
-
- if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
- struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- atomic_set(&subs->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(subs);
- if (!cap_subs->pcm_substream ||
- !cap_subs->pcm_substream->runtime ||
- !cap_subs->pcm_substream->runtime->status ||
- cap_subs->pcm_substream->runtime->status->state < SNDRV_PCM_STATE_PREPARED) {
- atomic_set(&cap_subs->state, state_STOPPED);
- if (NULL != cap_subs2)
- atomic_set(&cap_subs2->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(cap_subs);
- if (NULL != cap_subs2)
- usX2Y_usbpcm_urbs_release(cap_subs2);
- }
- } else {
- struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
- if (atomic_read(&playback_subs->state) < state_PREPARED) {
- atomic_set(&subs->state, state_STOPPED);
- if (NULL != cap_subs2)
- atomic_set(&cap_subs2->state, state_STOPPED);
- usX2Y_usbpcm_urbs_release(subs);
- if (NULL != cap_subs2)
- usX2Y_usbpcm_urbs_release(cap_subs2);
- }
- }
- mutex_unlock(&subs->usX2Y->prepare_mutex);
- return snd_pcm_lib_free_pages(substream);
-}
-
-static void usX2Y_usbpcm_subs_startup(struct snd_usX2Y_substream *subs)
-{
- struct usX2Ydev * usX2Y = subs->usX2Y;
- usX2Y->prepare_subs = subs;
- subs->urb[0]->start_frame = -1;
- smp_wmb(); // Make sure above modifications are seen by i_usX2Y_subs_startup()
- usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_subs_startup);
-}
-
-static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
-{
- int p, u, err,
- stream = subs->pcm_substream->stream;
- struct usX2Ydev *usX2Y = subs->usX2Y;
-
- if (SNDRV_PCM_STREAM_CAPTURE == stream) {
- usX2Y->hwdep_pcm_shm->captured_iso_head = -1;
- usX2Y->hwdep_pcm_shm->captured_iso_frames = 0;
- }
-
- for (p = 0; 3 >= (stream + p); p += 2) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[stream + p];
- if (subs != NULL) {
- if ((err = usX2Y_usbpcm_urbs_allocate(subs)) < 0)
- return err;
- subs->completed_urb = NULL;
- }
- }
-
- for (p = 0; p < 4; p++) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[p];
- if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
- goto start;
- }
-
- start:
- usX2Y_usbpcm_subs_startup(subs);
- for (u = 0; u < NRURBS; u++) {
- for (p = 0; 3 >= (stream + p); p += 2) {
- struct snd_usX2Y_substream *subs = usX2Y->subs[stream + p];
- if (subs != NULL) {
- struct urb *urb = subs->urb[u];
- if (usb_pipein(urb->pipe)) {
- unsigned long pack;
- if (0 == u)
- atomic_set(&subs->state, state_STARTING3);
- urb->dev = usX2Y->dev;
- urb->transfer_flags = URB_ISO_ASAP;
- for (pack = 0; pack < nr_of_packs(); pack++) {
- urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
- urb->iso_frame_desc[pack].length = subs->maxpacksize;
- }
- urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs();
- if ((err = usb_submit_urb(urb, GFP_KERNEL)) < 0) {
- snd_printk (KERN_ERR "cannot usb_submit_urb() for urb %d, err = %d\n", u, err);
- err = -EPIPE;
- goto cleanup;
- } else {
- snd_printdd("%i\n", urb->start_frame);
- if (u == 0)
- usX2Y->wait_iso_frame = urb->start_frame;
- }
- urb->transfer_flags = 0;
- } else {
- atomic_set(&subs->state, state_STARTING1);
- break;
- }
- }
- }
- }
- err = 0;
- wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
- if (atomic_read(&subs->state) != state_PREPARED)
- err = -EPIPE;
-
- cleanup:
- if (err) {
- usX2Y_subs_startup_finish(usX2Y); // Call it now
- usX2Y_clients_stop(usX2Y); // something is completely wroong > stop evrything
- }
- return err;
-}
-
-/*
- * prepare callback
- *
- * set format and initialize urbs
- */
-static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
- struct usX2Ydev *usX2Y = subs->usX2Y;
- struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
- int err = 0;
- snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
-
- if (NULL == usX2Y->hwdep_pcm_shm) {
- if (NULL == (usX2Y->hwdep_pcm_shm = snd_malloc_pages(sizeof(struct snd_usX2Y_hwdep_pcm_shm), GFP_KERNEL)))
- return -ENOMEM;
- memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
- }
-
- mutex_lock(&usX2Y->prepare_mutex);
- usX2Y_subs_prepare(subs);
-// Start hardware streams
-// SyncStream first....
- if (atomic_read(&capsubs->state) < state_PREPARED) {
- if (usX2Y->format != runtime->format)
- if ((err = usX2Y_format_set(usX2Y, runtime->format)) < 0)
- goto up_prepare_mutex;
- if (usX2Y->rate != runtime->rate)
- if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
- goto up_prepare_mutex;
- snd_printdd("starting capture pipe for %s\n", subs == capsubs ?
- "self" : "playpipe");
- if (0 > (err = usX2Y_usbpcm_urbs_start(capsubs)))
- goto up_prepare_mutex;
- }
-
- if (subs != capsubs) {
- usX2Y->hwdep_pcm_shm->playback_iso_start = -1;
- if (atomic_read(&subs->state) < state_PREPARED) {
- while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) >
- usX2Y->hwdep_pcm_shm->captured_iso_frames) {
- snd_printdd("Wait: iso_frames_per_buffer=%i,"
- "captured_iso_frames=%i\n",
- usX2Y_iso_frames_per_buffer(runtime, usX2Y),
- usX2Y->hwdep_pcm_shm->captured_iso_frames);
- if (msleep_interruptible(10)) {
- err = -ERESTARTSYS;
- goto up_prepare_mutex;
- }
- }
- if (0 > (err = usX2Y_usbpcm_urbs_start(subs)))
- goto up_prepare_mutex;
- }
- snd_printdd("Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
- usX2Y_iso_frames_per_buffer(runtime, usX2Y),
- usX2Y->hwdep_pcm_shm->captured_iso_frames);
- } else
- usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
-
- up_prepare_mutex:
- mutex_unlock(&usX2Y->prepare_mutex);
- return err;
-}
-
-static struct snd_pcm_hardware snd_usX2Y_4c =
-{
- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
- SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP_VALID),
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
- .rate_max = 48000,
- .channels_min = 2,
- .channels_max = 4,
- .buffer_bytes_max = (2*128*1024),
- .period_bytes_min = 64,
- .period_bytes_max = (128*1024),
- .periods_min = 2,
- .periods_max = 1024,
- .fifo_size = 0
-};
-
-
-
-static int snd_usX2Y_usbpcm_open(struct snd_pcm_substream *substream)
-{
- struct snd_usX2Y_substream *subs = ((struct snd_usX2Y_substream **)
- snd_pcm_substream_chip(substream))[substream->stream];
- struct snd_pcm_runtime *runtime = substream->runtime;
-
- if (!(subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS))
- return -EBUSY;
-
- runtime->hw = SNDRV_PCM_STREAM_PLAYBACK == substream->stream ? snd_usX2Y_2c :
- (subs->usX2Y->subs[3] ? snd_usX2Y_4c : snd_usX2Y_2c);
- runtime->private_data = subs;
- subs->pcm_substream = substream;
- snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
- return 0;
-}
-
-
-static int snd_usX2Y_usbpcm_close(struct snd_pcm_substream *substream)
-{
- struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_usX2Y_substream *subs = runtime->private_data;
-
- subs->pcm_substream = NULL;
- return 0;
-}
-
-
-static struct snd_pcm_ops snd_usX2Y_usbpcm_ops =
-{
- .open = snd_usX2Y_usbpcm_open,
- .close = snd_usX2Y_usbpcm_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_usX2Y_pcm_hw_params,
- .hw_free = snd_usX2Y_usbpcm_hw_free,
- .prepare = snd_usX2Y_usbpcm_prepare,
- .trigger = snd_usX2Y_pcm_trigger,
- .pointer = snd_usX2Y_pcm_pointer,
-};
-
-
-static int usX2Y_pcms_lock_check(struct snd_card *card)
-{
- struct list_head *list;
- struct snd_device *dev;
- struct snd_pcm *pcm;
- int err = 0;
- list_for_each(list, &card->devices) {
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- mutex_lock(&pcm->open_mutex);
- }
- list_for_each(list, &card->devices) {
- int s;
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- for (s = 0; s < 2; ++s) {
- struct snd_pcm_substream *substream;
- substream = pcm->streams[s].substream;
- if (substream && SUBSTREAM_BUSY(substream))
- err = -EBUSY;
- }
- }
- return err;
-}
-
-
-static void usX2Y_pcms_unlock(struct snd_card *card)
-{
- struct list_head *list;
- struct snd_device *dev;
- struct snd_pcm *pcm;
- list_for_each(list, &card->devices) {
- dev = snd_device(list);
- if (dev->type != SNDRV_DEV_PCM)
- continue;
- pcm = dev->device_data;
- mutex_unlock(&pcm->open_mutex);
- }
-}
-
-
-static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
-{
- // we need to be the first
- struct snd_card *card = hw->card;
- int err = usX2Y_pcms_lock_check(card);
- if (0 == err)
- usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
- usX2Y_pcms_unlock(card);
- return err;
-}
-
-
-static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
-{
- struct snd_card *card = hw->card;
- int err = usX2Y_pcms_lock_check(card);
- if (0 == err)
- usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
- usX2Y_pcms_unlock(card);
- return err;
-}
-
-
-static void snd_usX2Y_hwdep_pcm_vm_open(struct vm_area_struct *area)
-{
-}
-
-
-static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area)
-{
-}
-
-
-static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_area_struct *area,
- struct vm_fault *vmf)
-{
- unsigned long offset;
- void *vaddr;
-
- offset = vmf->pgoff << PAGE_SHIFT;
- vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->hwdep_pcm_shm + offset;
- vmf->page = virt_to_page(vaddr);
- get_page(vmf->page);
- return 0;
-}
-
-
-static const struct vm_operations_struct snd_usX2Y_hwdep_pcm_vm_ops = {
- .open = snd_usX2Y_hwdep_pcm_vm_open,
- .close = snd_usX2Y_hwdep_pcm_vm_close,
- .fault = snd_usX2Y_hwdep_pcm_vm_fault,
-};
-
-
-static int snd_usX2Y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
-{
- unsigned long size = (unsigned long)(area->vm_end - area->vm_start);
- struct usX2Ydev *usX2Y = hw->private_data;
-
- if (!(usX2Y->chip_status & USX2Y_STAT_CHIP_INIT))
- return -EBUSY;
-
- /* if userspace tries to mmap beyond end of our buffer, fail */
- if (size > PAGE_ALIGN(sizeof(struct snd_usX2Y_hwdep_pcm_shm))) {
- snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct snd_usX2Y_hwdep_pcm_shm));
- return -EINVAL;
- }
-
- if (!usX2Y->hwdep_pcm_shm) {
- return -ENODEV;
- }
- area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
- area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
- area->vm_private_data = hw->private_data;
- return 0;
-}
-
-
-static void snd_usX2Y_hwdep_pcm_private_free(struct snd_hwdep *hwdep)
-{
- struct usX2Ydev *usX2Y = hwdep->private_data;
- if (NULL != usX2Y->hwdep_pcm_shm)
- snd_free_pages(usX2Y->hwdep_pcm_shm, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
-}
-
-
-int usX2Y_hwdep_pcm_new(struct snd_card *card)
-{
- int err;
- struct snd_hwdep *hw;
- struct snd_pcm *pcm;
- struct usb_device *dev = usX2Y(card)->dev;
- if (1 != nr_of_packs())
- return 0;
-
- if ((err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw)) < 0)
- return err;
-
- hw->iface = SNDRV_HWDEP_IFACE_USX2Y_PCM;
- hw->private_data = usX2Y(card);
- hw->private_free = snd_usX2Y_hwdep_pcm_private_free;
- hw->ops.open = snd_usX2Y_hwdep_pcm_open;
- hw->ops.release = snd_usX2Y_hwdep_pcm_release;
- hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap;
- hw->exclusive = 1;
- sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum);
-
- err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm);
- if (err < 0) {
- return err;
- }
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_usX2Y_usbpcm_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_usbpcm_ops);
-
- pcm->private_data = usX2Y(card)->subs;
- pcm->info_flags = 0;
-
- sprintf(pcm->name, NAME_ALLCAPS" hwdep Audio");
- if (0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 128*1024)) ||
- 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
- SNDRV_DMA_TYPE_CONTINUOUS,
- snd_dma_continuous_data(GFP_KERNEL),
- 64*1024, 128*1024))) {
- return err;
- }
-
-
- return 0;
-}
-
-#else
-
-int usX2Y_hwdep_pcm_new(struct snd_card *card)
-{
- return 0;
-}
-
-#endif
diff --git a/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.h b/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.h
deleted file mode 100644
index 9c4fb84b..00000000
--- a/ANDROID_3.4.5/sound/usb/usx2y/usx2yhwdeppcm.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#define MAXPACK 50
-#define MAXBUFFERMS 100
-#define MAXSTRIDE 3
-
-#define SSS (((MAXPACK*MAXBUFFERMS*MAXSTRIDE + 4096) / 4096) * 4096)
-struct snd_usX2Y_hwdep_pcm_shm {
- char playback[SSS];
- char capture0x8[SSS];
- char capture0xA[SSS];
- volatile int playback_iso_head;
- int playback_iso_start;
- struct {
- int frame,
- offset,
- length;
- } captured_iso[128];
- volatile int captured_iso_head;
- volatile unsigned captured_iso_frames;
- int capture_iso_start;
-};
-
-int usX2Y_hwdep_pcm_new(struct snd_card *card);