Commit 9c7183e1 authored by Jaroslav Kysela's avatar Jaroslav Kysela

Merge http://linux.bkbits.net/linux-2.5

into suse.cz:/home/perex/bk/linux-sound/linux-sound
parents eff95566 7f6f7753
/* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc3"
#define CONFIG_SND_DATE " (Tue Oct 01 14:40:23 2002 UTC)"
#define CONFIG_SND_DATE " (Fri Oct 04 13:09:13 2002 UTC)"
......@@ -960,7 +960,6 @@ void snd_info_free_device(snd_info_entry_t * entry)
{
#ifdef CONFIG_DEVFS_FS
char dname[32];
devfs_handle_t master;
#endif
snd_runtime_check(entry, return);
......@@ -970,12 +969,7 @@ void snd_info_free_device(snd_info_entry_t * entry)
#ifdef CONFIG_DEVFS_FS
if (entry->p && strncmp(entry->name, "controlC", 8)) {
sprintf(dname, "snd/%s", entry->name);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
master = devfs_find_handle(NULL, dname, strlen(dname), 0, 0, DEVFS_SPECIAL_CHR, 0);
devfs_unregister(master);
#else
devfs_find_and_unregister(NULL, dname, 0, 0, DEVFS_SPECIAL_CHR, 0);
#endif
}
#endif
snd_info_free_entry(entry);
......
......@@ -358,21 +358,12 @@ static int __init alsa_sound_init(void)
static void __exit alsa_sound_exit(void)
{
#ifdef CONFIG_DEVFS_FS
devfs_handle_t master;
char controlname[24];
short controlnum;
for (controlnum = 0; controlnum < snd_cards_limit; controlnum++) {
sprintf(controlname, "snd/controlC%d", controlnum);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
master = devfs_find_handle(NULL, controlname, strlen(controlname), 0, 0, DEVFS_SPECIAL_CHR, 0);
devfs_unregister(master);
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
master = devfs_find_handle(NULL, controlname, 0, 0, DEVFS_SPECIAL_CHR, 0);
devfs_unregister(master);
#else
devfs_find_and_unregister(NULL, controlname, 0, 0, DEVFS_SPECIAL_CHR, 0);
#endif
}
#endif
......
......@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/irq.h>
#include <sound/core.h>
#include <sound/sb.h>
#include <sound/ad1848.h>
......@@ -110,6 +111,10 @@ static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char va
return 0;
}
static void snd_sgalaxy_dummy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
}
static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
{
static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1,
......@@ -117,8 +122,6 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
static int dma_bits[] = {1, 2, 0, 3};
int tmp, tmp1;
unsigned long flags;
if ((tmp = inb(port + 3)) == 0xff)
{
snd_printdd("I/O address dead (0x%lx)\n", port);
......@@ -140,20 +143,20 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
snd_printdd("sgalaxy - setting up IRQ/DMA for WSS\n");
#endif
save_flags(flags);
cli();
/* initialize IRQ for WSS codec */
tmp = interrupt_bits[irq % 16];
if (tmp < 0) {
restore_flags(flags);
if (tmp < 0)
return -EINVAL;
}
if (request_irq(irq, snd_sgalaxy_dummy_interrupt, SA_INTERRUPT, "sgalaxy", NULL))
return -EIO;
outb(tmp | 0x40, port);
tmp1 = dma_bits[dma % 4];
outb(tmp | tmp1, port);
restore_flags(flags);
free_irq(irq, NULL);
return 0;
}
......
......@@ -1577,7 +1577,6 @@ int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip)
int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
unsigned int flags;
/* turn on amplifier */
chip->active_ctrl(chip, 1);
......
......@@ -1410,7 +1410,6 @@ int cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src)
{
dsp_spos_instance_t * ins = chip->dsp_spos_instance;
dsp_scb_descriptor_t * parent_scb;
unsigned int flags;
snd_assert (src->parent_scb_ptr == NULL, return -EINVAL );
snd_assert(ins->master_mix_scb !=NULL, return -EINVAL );
......
......@@ -122,7 +122,7 @@ static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list,
* Remove a node from the chain. Called with the lock asserted
*/
static void __sound_remove_unit(struct sound_unit **list, int unit)
static struct sound_unit *__sound_remove_unit(struct sound_unit **list, int unit)
{
while(*list)
{
......@@ -130,13 +130,12 @@ static void __sound_remove_unit(struct sound_unit **list, int unit)
if(p->unit_minor==unit)
{
*list=p->next;
devfs_unregister (p->de);
kfree(p);
return;
return p;
}
list=&(p->next);
}
printk(KERN_ERR "Sound device %d went missing!\n", unit);
return NULL;
}
/*
......@@ -189,9 +188,15 @@ static int sound_insert_unit(struct sound_unit **list, struct file_operations *f
static void sound_remove_unit(struct sound_unit **list, int unit)
{
struct sound_unit *p;
spin_lock(&sound_loader_lock);
__sound_remove_unit(list, unit);
p = __sound_remove_unit(list, unit);
spin_unlock(&sound_loader_lock);
if (p) {
devfs_unregister (p->de);
kfree(p);
}
}
/*
......
......@@ -284,6 +284,16 @@ static int prepare_capture_urb(snd_usb_substream_t *subs,
urb->transfer_buffer = ctx->buf;
urb->transfer_buffer_length = offs;
urb->interval = 1;
#if 0 // for check
if (! urb->bandwidth) {
int bustime;
bustime = usb_check_bandwidth(urb->dev, urb);
if (bustime < 0)
return bustime;
printk("urb %d: bandwidth = %d (packets = %d)\n", ctx->index, bustime, urb->number_of_packets);
usb_claim_bandwidth(urb->dev, urb, bustime, 1);
}
#endif // for check
return 0;
}
......@@ -305,8 +315,10 @@ static int retire_capture_urb(snd_usb_substream_t *subs,
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) /* active? hmm, skip this */
continue;
if (urb->iso_frame_desc[i].status) {
snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
// continue;
}
len = urb->iso_frame_desc[i].actual_length / stride;
if (! len)
continue;
......@@ -1009,6 +1021,7 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
}
/* if endpoint has sampling rate control, set it */
if (fmt->attributes & EP_CS_ATTR_SAMPLE_RATE) {
int crate;
data[0] = runtime->rate;
data[1] = runtime->rate >> 8;
data[2] = runtime->rate >> 16;
......@@ -1026,8 +1039,11 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
dev->devnum, subs->interface, fmt->altsetting, ep);
return err;
}
runtime->rate = data[0] | (data[1] << 8) | (data[2] << 16);
// printk("ok, getting back rate to %d\n", runtime->rate);
crate = data[0] | (data[1] << 8) | (data[2] << 16);
if (crate != runtime->rate) {
snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, runtime->rate);
// runtime->rate = crate;
}
}
/* always fill max packet size */
if (fmt->attributes & EP_CS_ATTR_FILL_MAX)
......@@ -1292,14 +1308,14 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype
* entry point for linux usb interface
*/
#ifndef OLD_USB
static int usb_audio_probe(struct usb_interface *intf,
#ifdef OLD_USB
static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
const struct usb_device_id *id);
static void usb_audio_disconnect(struct usb_interface *intf);
static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
#else
static void * usb_audio_probe(usb_device *dev, unsigned int ifnum,
static int usb_audio_probe(struct usb_interface *intf,
const struct usb_device_id *id);
static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
static void usb_audio_disconnect(struct usb_interface *intf);
#endif
static struct usb_device_id usb_audio_ids [] = {
......@@ -1810,7 +1826,8 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, i
* parse audio control descriptor and create pcm/midi streams
*/
static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum,
static int snd_usb_create_midi_interface(snd_usb_audio_t *chip,
struct usb_interface *iface,
const snd_usb_audio_quirk_t *quirk);
static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
......@@ -1850,7 +1867,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
}
if (iface->altsetting[0].bInterfaceClass == USB_CLASS_AUDIO &&
iface->altsetting[0].bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
if (snd_usb_create_midi_interface(chip, j, NULL) < 0) {
if (snd_usb_create_midi_interface(chip, iface, NULL) < 0) {
snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
continue;
}
......@@ -1871,7 +1888,8 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
return 0;
}
static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum,
static int snd_usb_create_midi_interface(snd_usb_audio_t *chip,
struct usb_interface *iface,
const snd_usb_audio_quirk_t *quirk)
{
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
......@@ -1888,18 +1906,20 @@ static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum,
strcpy(seq_device->name, chip->card->shortname);
umidi = (snd_usb_midi_t *)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
umidi->chip = chip;
umidi->ifnum = ifnum;
umidi->iface = iface;
umidi->ifnum = iface->altsetting->bInterfaceNumber;
umidi->quirk = quirk;
umidi->seq_client = -1;
#endif
return 0;
}
static inline int snd_usb_create_quirk(snd_usb_audio_t *chip, int ifnum,
static inline int snd_usb_create_quirk(snd_usb_audio_t *chip,
struct usb_interface *iface,
const snd_usb_audio_quirk_t *quirk)
{
/* in the future, there may be quirks for PCM devices */
return snd_usb_create_midi_interface(chip, ifnum, quirk);
return snd_usb_create_midi_interface(chip, iface, quirk);
}
......@@ -2050,27 +2070,18 @@ static int alloc_desc_buffer(struct usb_device *dev, int index, unsigned char **
* only at the first time. the successive calls of this function will
* append the pcm interface to the corresponding card.
*/
#ifndef OLD_USB
static int usb_audio_probe(struct usb_interface *intf,
static void *snd_usb_audio_probe(struct usb_device *dev,
struct usb_interface *intf,
const struct usb_device_id *id)
#else
static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
const struct usb_device_id *id)
#endif
{
#ifndef OLD_USB
struct usb_device *dev = interface_to_usbdev(intf);
int ifnum = intf->altsetting->bInterfaceNumber;
#endif
struct usb_config_descriptor *config = dev->actconfig;
const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)id->driver_info;
unsigned char *buffer;
unsigned int index;
int i, buflen;
int i;
snd_card_t *card;
snd_usb_audio_t *chip;
int ifnum = intf->altsetting->bInterfaceNumber;
if (quirk && ifnum != quirk->ifnum)
if (quirk && quirk->ifnum != QUIRK_ANY_INTERFACE && ifnum != quirk->ifnum)
goto __err_val;
if (usb_set_configuration(dev, config->bConfigurationValue) < 0) {
......@@ -2078,11 +2089,6 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
goto __err_val;
}
index = dev->actconfig - config;
buflen = alloc_desc_buffer(dev, index, &buffer);
if (buflen <= 0)
goto __err_val;
/*
* found a config. now register to ALSA
*/
......@@ -2124,12 +2130,24 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
}
if (!quirk) {
if (snd_usb_create_streams(chip, ifnum, buffer, buflen) < 0)
/* USB audio interface */
unsigned char *buffer;
unsigned int index;
int buflen;
index = dev->actconfig - config;
buflen = alloc_desc_buffer(dev, index, &buffer);
if (buflen <= 0)
goto __error;
if (snd_usb_create_mixer(chip, ifnum, buffer, buflen) < 0)
if (snd_usb_create_streams(chip, ifnum, buffer, buflen) < 0 ||
snd_usb_create_mixer(chip, ifnum, buffer, buflen) < 0) {
kfree(buffer);
goto __error;
}
kfree(buffer);
} else {
if (snd_usb_create_quirk(chip, ifnum, quirk) < 0)
/* USB midi interface */
if (snd_usb_create_quirk(chip, intf, quirk) < 0)
goto __error;
}
......@@ -2142,38 +2160,20 @@ static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
chip->num_interfaces++;
up(&register_mutex);
kfree(buffer);
#ifndef OLD_USB
return 0;
#else
return chip;
#endif
__error:
up(&register_mutex);
kfree(buffer);
__err_val:
#ifndef OLD_USB
return -EIO;
#else
return NULL;
#endif
}
/*
* we need to take care of counter, since disconnection can be called also
* many times as well as usb_audio_probe().
*/
#ifndef OLD_USB
static void usb_audio_disconnect(struct usb_interface *intf)
#else
static void usb_audio_disconnect(struct usb_device *dev, void *ptr)
#endif
static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
{
#ifndef OLD_USB
void *ptr = dev_get_drvdata(&intf->dev);
#endif
snd_usb_audio_t *chip;
if (ptr == (void *)-1)
......@@ -2185,6 +2185,49 @@ static void usb_audio_disconnect(struct usb_device *dev, void *ptr)
snd_card_free(chip->card);
}
#ifdef OLD_USB
/*
* 2.4 USB kernel API
*/
static void *usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
const struct usb_device_id *id)
{
return snd_usb_audio_probe(dev, usb_ifnum_to_if(dev, ifnum), id);
}
static void usb_audio_disconnect(struct usb_device *dev, void *ptr)
{
snd_usb_audio_disconnect(dev, ptr);
}
#else
/*
* new 2.5 USB kernel API
*/
static int usb_audio_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
void *chip;
chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
if (chip) {
dev_set_drvdata(&intf->dev, chip);
return 0;
} else
return -EIO;
}
static void usb_audio_disconnect(struct usb_interface *intf)
{
snd_usb_audio_disconnect(interface_to_usbdev(intf),
dev_get_drvdata(&intf->dev));
}
#endif
static int __init snd_usb_audio_init(void)
{
usb_register(&usb_audio_driver);
......
......@@ -58,6 +58,8 @@
#define EP_GENERAL 0x01
#define MS_GENERAL 0x01
#define MIDI_IN_JACK 0x02
#define MIDI_OUT_JACK 0x03
/* endpoint attributes */
#define EP_ATTR_MASK 0x0c
......@@ -146,22 +148,34 @@ struct snd_usb_audio {
/*
* Information about devices with broken descriptors
*/
#define QUIRK_ANY_INTERFACE -1
#define QUIRK_MIDI_FIXED_ENDPOINT 0
#define QUIRK_MIDI_YAMAHA 1
#define QUIRK_MIDI_MIDIMAN 2
typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
struct snd_usb_audio_quirk {
const char *vendor_name;
const char *product_name;
int ifnum;
int16_t ifnum;
int16_t type;
const void *data;
};
/* MIDI specific */
struct snd_usb_midi_endpoint_info {
/* data for QUIRK_MIDI_FIXED_ENDPOINT */
struct snd_usb_midi_endpoint_info {
int16_t epnum; /* ep number, -1 autodetect */
uint16_t out_cables; /* bitmask */
uint16_t in_cables; /* bitmask */
} endpoints[MIDI_MAX_ENDPOINTS];
};
/* for QUIRK_MIDI_YAMAHA, data is NULL */
/* for QUIRK_MIDI_MIDIMAN, data is the number of ports */
/*
* USB MIDI sequencer device data
*/
......@@ -173,6 +187,7 @@ typedef struct snd_usb_midi_in_endpoint snd_usb_midi_in_endpoint_t;
struct snd_usb_midi {
/* filled by usbaudio.c */
snd_usb_audio_t *chip;
struct usb_interface *iface;
int ifnum;
const snd_usb_audio_quirk_t *quirk;
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment