diff options
Diffstat (limited to 'ANDROID_3.4.5/sound/usb/6fire')
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/Makefile | 3 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/chip.c | 220 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/chip.h | 31 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/comm.c | 175 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/comm.h | 43 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/common.h | 29 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/control.c | 631 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/control.h | 57 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/firmware.c | 418 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/firmware.h | 27 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/midi.c | 202 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/midi.h | 45 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/pcm.c | 666 | ||||
-rw-r--r-- | ANDROID_3.4.5/sound/usb/6fire/pcm.h | 75 |
14 files changed, 0 insertions, 2622 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(®ister_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(®ister_mutex); - return 0; - } else if (regidx < 0) - regidx = i; - } - if (regidx < 0) { - mutex_unlock(®ister_mutex); - snd_printk(KERN_ERR PREFIX "too many cards registered.\n"); - return -ENODEV; - } - devices[regidx] = device; - mutex_unlock(®ister_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(®ister_mutex); - devices[chip->regidx] = NULL; - chips[chip->regidx] = NULL; - mutex_unlock(®ister_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 */ |