Commit 7f6f7753 authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA update

  - CS46xx driver - removed unused variable
  - USB code
    - pass struct usb_interface pointer to the usb-midi parser.
      in usb-midi functions, this instance is used instead of parsing
      the interface from dev and ifnum.
    - allocate the descriptor buffer only for parsing the audio device.
    - clean up, new probe/disconnect callbacks for 2.4 API.
    - added the support for Yamaha and Midiman devices.                                                  
parent 0f8328bc
...@@ -1577,7 +1577,6 @@ int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip) ...@@ -1577,7 +1577,6 @@ int cs46xx_dsp_disable_spdif_out (cs46xx_t *chip)
int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip) int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
{ {
dsp_spos_instance_t * ins = chip->dsp_spos_instance; dsp_spos_instance_t * ins = chip->dsp_spos_instance;
unsigned int flags;
/* turn on amplifier */ /* turn on amplifier */
chip->active_ctrl(chip, 1); chip->active_ctrl(chip, 1);
......
...@@ -1410,7 +1410,6 @@ int cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src) ...@@ -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_spos_instance_t * ins = chip->dsp_spos_instance;
dsp_scb_descriptor_t * parent_scb; dsp_scb_descriptor_t * parent_scb;
unsigned int flags;
snd_assert (src->parent_scb_ptr == NULL, return -EINVAL ); snd_assert (src->parent_scb_ptr == NULL, return -EINVAL );
snd_assert(ins->master_mix_scb !=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, ...@@ -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 * 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) while(*list)
{ {
...@@ -130,13 +130,12 @@ static void __sound_remove_unit(struct sound_unit **list, int unit) ...@@ -130,13 +130,12 @@ static void __sound_remove_unit(struct sound_unit **list, int unit)
if(p->unit_minor==unit) if(p->unit_minor==unit)
{ {
*list=p->next; *list=p->next;
devfs_unregister (p->de); return p;
kfree(p);
return;
} }
list=&(p->next); list=&(p->next);
} }
printk(KERN_ERR "Sound device %d went missing!\n", unit); 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 ...@@ -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) static void sound_remove_unit(struct sound_unit **list, int unit)
{ {
struct sound_unit *p;
spin_lock(&sound_loader_lock); spin_lock(&sound_loader_lock);
__sound_remove_unit(list, unit); p = __sound_remove_unit(list, unit);
spin_unlock(&sound_loader_lock); spin_unlock(&sound_loader_lock);
if (p) {
devfs_unregister (p->de);
kfree(p);
}
} }
/* /*
......
...@@ -1308,12 +1308,10 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype ...@@ -1308,12 +1308,10 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype
* entry point for linux usb interface * entry point for linux usb interface
*/ */
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_device *dev, void *ptr);
#ifdef OLD_USB #ifdef OLD_USB
#define usb_audio_probe _usb_audio_probe static void * usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
#define usb_audio_disconnect _usb_audio_disconnect const struct usb_device_id *id);
static void usb_audio_disconnect(struct usb_device *dev, void *ptr);
#else #else
static int usb_audio_probe(struct usb_interface *intf, static int usb_audio_probe(struct usb_interface *intf,
const struct usb_device_id *id); const struct usb_device_id *id);
...@@ -1828,7 +1826,8 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, i ...@@ -1828,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 * 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); const snd_usb_audio_quirk_t *quirk);
static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif, static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
...@@ -1868,7 +1867,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif, ...@@ -1868,7 +1867,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
} }
if (iface->altsetting[0].bInterfaceClass == USB_CLASS_AUDIO && if (iface->altsetting[0].bInterfaceClass == USB_CLASS_AUDIO &&
iface->altsetting[0].bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) { 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); snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
continue; continue;
} }
...@@ -1889,7 +1888,8 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif, ...@@ -1889,7 +1888,8 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
return 0; 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) const snd_usb_audio_quirk_t *quirk)
{ {
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
...@@ -1906,18 +1906,20 @@ static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum, ...@@ -1906,18 +1906,20 @@ static int snd_usb_create_midi_interface(snd_usb_audio_t *chip, int ifnum,
strcpy(seq_device->name, chip->card->shortname); strcpy(seq_device->name, chip->card->shortname);
umidi = (snd_usb_midi_t *)SNDRV_SEQ_DEVICE_ARGPTR(seq_device); umidi = (snd_usb_midi_t *)SNDRV_SEQ_DEVICE_ARGPTR(seq_device);
umidi->chip = chip; umidi->chip = chip;
umidi->ifnum = ifnum; umidi->iface = iface;
umidi->ifnum = iface->altsetting->bInterfaceNumber;
umidi->quirk = quirk; umidi->quirk = quirk;
umidi->seq_client = -1; umidi->seq_client = -1;
#endif #endif
return 0; 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) const snd_usb_audio_quirk_t *quirk)
{ {
/* in the future, there may be quirks for PCM devices */ /* 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);
} }
...@@ -2068,18 +2070,18 @@ static int alloc_desc_buffer(struct usb_device *dev, int index, unsigned char ** ...@@ -2068,18 +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 * only at the first time. the successive calls of this function will
* append the pcm interface to the corresponding card. * append the pcm interface to the corresponding card.
*/ */
static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum, static void *snd_usb_audio_probe(struct usb_device *dev,
const struct usb_device_id *id) struct usb_interface *intf,
const struct usb_device_id *id)
{ {
struct usb_config_descriptor *config = dev->actconfig; struct usb_config_descriptor *config = dev->actconfig;
const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)id->driver_info; const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)id->driver_info;
unsigned char *buffer; int i;
unsigned int index;
int i, buflen;
snd_card_t *card; snd_card_t *card;
snd_usb_audio_t *chip; 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; goto __err_val;
if (usb_set_configuration(dev, config->bConfigurationValue) < 0) { if (usb_set_configuration(dev, config->bConfigurationValue) < 0) {
...@@ -2087,11 +2089,6 @@ static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -2087,11 +2089,6 @@ static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
goto __err_val; 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 * found a config. now register to ALSA
*/ */
...@@ -2133,12 +2130,24 @@ static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -2133,12 +2130,24 @@ static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
} }
if (!quirk) { 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; 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; goto __error;
}
kfree(buffer);
} else { } else {
if (snd_usb_create_quirk(chip, ifnum, quirk) < 0) /* USB midi interface */
if (snd_usb_create_quirk(chip, intf, quirk) < 0)
goto __error; goto __error;
} }
...@@ -2151,12 +2160,10 @@ static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -2151,12 +2160,10 @@ static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
chip->num_interfaces++; chip->num_interfaces++;
up(&register_mutex); up(&register_mutex);
kfree(buffer);
return chip; return chip;
__error: __error:
up(&register_mutex); up(&register_mutex);
kfree(buffer);
__err_val: __err_val:
return NULL; return NULL;
} }
...@@ -2165,7 +2172,7 @@ static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum, ...@@ -2165,7 +2172,7 @@ static void *_usb_audio_probe(struct usb_device *dev, unsigned int ifnum,
* we need to take care of counter, since disconnection can be called also * we need to take care of counter, since disconnection can be called also
* many times as well as usb_audio_probe(). * many times as well as usb_audio_probe().
*/ */
static void _usb_audio_disconnect(struct usb_device *dev, void *ptr) static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
{ {
snd_usb_audio_t *chip; snd_usb_audio_t *chip;
...@@ -2179,17 +2186,32 @@ static void _usb_audio_disconnect(struct usb_device *dev, void *ptr) ...@@ -2179,17 +2186,32 @@ static void _usb_audio_disconnect(struct usb_device *dev, void *ptr)
} }
#ifndef OLD_USB #ifdef OLD_USB
/* /*
* new 2.5 USB kernel API * 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, static int usb_audio_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
void *chip; void *chip;
chip = _usb_audio_probe(interface_to_usbdev(intf), chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
intf->altsetting->bInterfaceNumber, id);
if (chip) { if (chip) {
dev_set_drvdata(&intf->dev, chip); dev_set_drvdata(&intf->dev, chip);
return 0; return 0;
...@@ -2199,8 +2221,8 @@ static int usb_audio_probe(struct usb_interface *intf, ...@@ -2199,8 +2221,8 @@ static int usb_audio_probe(struct usb_interface *intf,
static void usb_audio_disconnect(struct usb_interface *intf) static void usb_audio_disconnect(struct usb_interface *intf)
{ {
_usb_audio_disconnect(interface_to_usbdev(intf), snd_usb_audio_disconnect(interface_to_usbdev(intf),
dev_get_drvdata(&intf->dev)); dev_get_drvdata(&intf->dev));
} }
#endif #endif
......
...@@ -58,6 +58,8 @@ ...@@ -58,6 +58,8 @@
#define EP_GENERAL 0x01 #define EP_GENERAL 0x01
#define MS_GENERAL 0x01 #define MS_GENERAL 0x01
#define MIDI_IN_JACK 0x02
#define MIDI_OUT_JACK 0x03
/* endpoint attributes */ /* endpoint attributes */
#define EP_ATTR_MASK 0x0c #define EP_ATTR_MASK 0x0c
...@@ -146,22 +148,34 @@ struct snd_usb_audio { ...@@ -146,22 +148,34 @@ struct snd_usb_audio {
/* /*
* Information about devices with broken descriptors * 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_audio_quirk snd_usb_audio_quirk_t;
typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t; typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
struct snd_usb_audio_quirk { struct snd_usb_audio_quirk {
const char *vendor_name; const char *vendor_name;
const char *product_name; const char *product_name;
int ifnum; int16_t ifnum;
int16_t type;
const void *data;
};
/* MIDI specific */ /* data for QUIRK_MIDI_FIXED_ENDPOINT */
struct snd_usb_midi_endpoint_info { struct snd_usb_midi_endpoint_info {
int16_t epnum; /* ep number, -1 autodetect */ int16_t epnum; /* ep number, -1 autodetect */
uint16_t out_cables; /* bitmask */ uint16_t out_cables; /* bitmask */
uint16_t in_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 * USB MIDI sequencer device data
*/ */
...@@ -173,6 +187,7 @@ typedef struct snd_usb_midi_in_endpoint snd_usb_midi_in_endpoint_t; ...@@ -173,6 +187,7 @@ typedef struct snd_usb_midi_in_endpoint snd_usb_midi_in_endpoint_t;
struct snd_usb_midi { struct snd_usb_midi {
/* filled by usbaudio.c */ /* filled by usbaudio.c */
snd_usb_audio_t *chip; snd_usb_audio_t *chip;
struct usb_interface *iface;
int ifnum; int ifnum;
const snd_usb_audio_quirk_t *quirk; 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