Commit b706cbf8 authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA update

   - CS4231 - added sparc support to merge sparc/cs4231.c code
   - ICE1712
     - added support for AK4529
     - added support for Midiman M-Audio Delta410
   - USB driver
     - fixed against newer USB API but allow compilation under 2.4
parent a1a1c402
......@@ -26,9 +26,24 @@
#include "pcm.h"
#include "timer.h"
#ifdef CONFIG_SBUS
#define SBUS_SUPPORT
#include <asm/sbus.h>
#endif
#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
#define EBUS_SUPPORT
#include <linux/pci.h>
#include <asm/ebus.h>
#endif
#if !defined(SBUS_SUPPORT) && !defined(EBUS_SUPPORT)
#define LEGACY_SUPPORT
#endif
/* IO ports */
#define CS4231P(chip, x) ((chip)->port + c_d_c_CS4231##x)
#define CS4231P(x) (c_d_c_CS4231##x)
#define c_d_c_CS4231REGSEL 0
#define c_d_c_CS4231REG 1
......@@ -221,17 +236,38 @@ typedef struct _snd_cs4231 cs4231_t;
struct _snd_cs4231 {
unsigned long port; /* base i/o port */
#ifdef LEGACY_SUPPORT
struct resource *res_port;
unsigned long cport; /* control base i/o port (CS4236) */
struct resource *res_cport;
int irq; /* IRQ line */
int dma1; /* playback DMA */
int dma2; /* record DMA */
#endif
unsigned short version; /* version of CODEC chip */
unsigned short mode; /* see to CS4231_MODE_XXXX */
unsigned short hardware; /* see to CS4231_HW_XXXX */
unsigned short hwshare; /* shared resources */
unsigned short single_dma:1; /* forced single DMA mode (GUS 16-bit daughter board) or dma1 == dma2 */
unsigned short single_dma:1, /* forced single DMA mode (GUS 16-bit daughter board) or dma1 == dma2 */
ebus_flag:1; /* SPARC: EBUS present */
#ifdef EBUS_SUPPORT
struct ebus_dma_info eb2c;
struct ebus_dma_info eb2p;
#endif
#if defined(SBUS_SUPPORT) || defined(EBUS_SUPPORT)
union {
#ifdef SBUS_SUPPORT
struct sbus_dev *sdev;
#endif
#ifdef EBUS_SUPPORT
struct pci_dev *pdev;
#endif
} dev_u;
unsigned int p_periods_sent;
unsigned int c_periods_sent;
#endif
snd_card_t *card;
snd_pcm_t *pcm;
......@@ -245,8 +281,10 @@ struct _snd_cs4231 {
int mce_bit;
int calibrate_mute;
int sw_3d_bit;
#ifdef LEGACY_SUPPORT
unsigned int p_dma_size;
unsigned int c_dma_size;
#endif
spinlock_t reg_lock;
struct semaphore mce_mutex;
......@@ -255,14 +293,17 @@ struct _snd_cs4231 {
int (*rate_constraint) (snd_pcm_runtime_t *runtime);
void (*set_playback_format) (cs4231_t *chip, snd_pcm_hw_params_t *hw_params, unsigned char pdfr);
void (*set_capture_format) (cs4231_t *chip, snd_pcm_hw_params_t *hw_params, unsigned char cdfr);
void (*trigger) (cs4231_t *chip, unsigned int what, int start);
#ifdef CONFIG_PM
struct pm_dev *pm_dev;
void (*suspend) (cs4231_t *chip);
void (*resume) (cs4231_t *chip);
#endif
void *dma_private_data;
#ifdef LEGACY_SUPPORT
int (*claim_dma) (cs4231_t *chip, void *dma_private_data, int dma);
int (*release_dma) (cs4231_t *chip, void *dma_private_data, int dma);
#endif
};
/* exported functions */
......
/* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc5"
#define CONFIG_SND_DATE " (Tue Oct 29 09:19:27 2002 UTC)"
#define CONFIG_SND_DATE " (Sun Nov 10 19:48:18 2002 UTC)"
This diff is collapsed.
This diff is collapsed.
......@@ -337,6 +337,9 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
case ICE1712_SUBDEVICE_AUDIOPHILE:
ice->num_total_dacs = 2;
break;
case ICE1712_SUBDEVICE_DELTA410:
ice->num_total_dacs = 8;
break;
case ICE1712_SUBDEVICE_DELTA44:
case ICE1712_SUBDEVICE_DELTA66:
ice->num_total_dacs = ice->omni ? 8 : 4;
......@@ -350,6 +353,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
/* initialize spdif */
switch (ice->eeprom.subvendor) {
case ICE1712_SUBDEVICE_AUDIOPHILE:
case ICE1712_SUBDEVICE_DELTA410:
case ICE1712_SUBDEVICE_DELTA1010LT:
if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
snd_printk("unable to create I2C bus\n");
......@@ -378,12 +382,17 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
ak = &ice->ak4524;
switch (ice->eeprom.subvendor) {
case ICE1712_SUBDEVICE_AUDIOPHILE:
case ICE1712_SUBDEVICE_DELTA410:
ak->num_adcs = ak->num_dacs = 2;
ak->is_ak4528 = 1;
ak->cif = 0; /* the default level of the CIF pin from AK4524 */
ak->type = SND_AK4528;
if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA410) {
ak->num_dacs = 8;
ak->type = SND_AK4529;
}
ak->cif = 0; /* the default level of the CIF pin from AK4528/4529 */
ak->data_mask = ICE1712_DELTA_AP_DOUT;
ak->clk_mask = ICE1712_DELTA_AP_CCLK;
ak->cs_mask = ak->cs_addr = ICE1712_DELTA_AP_CS_CODEC; /* select AK4528 codec */
ak->cs_mask = ak->cs_addr = ICE1712_DELTA_AP_CS_CODEC; /* select AK4528/4529 codec */
ak->cs_none = 0;
ak->add_flags = ICE1712_DELTA_AP_CS_DIGITAL; /* assert digital high */
ak->mask_flags = 0;
......@@ -392,6 +401,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
break;
case ICE1712_SUBDEVICE_DELTA1010LT:
ak->num_adcs = ak->num_dacs = 8;
ak->type = SND_AK4524;
ak->cif = 0; /* the default level of the CIF pin from AK4524 */
ak->data_mask = ICE1712_DELTA_1010LT_DOUT;
ak->clk_mask = ICE1712_DELTA_1010LT_CCLK;
......@@ -406,6 +416,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
case ICE1712_SUBDEVICE_DELTA66:
case ICE1712_SUBDEVICE_DELTA44:
ak->num_adcs = ak->num_dacs = 4;
ak->type = SND_AK4524;
ak->cif = 0; /* the default level of the CIF pin from AK4524 */
ak->data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA;
ak->clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK;
......@@ -471,6 +482,8 @@ static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice)
case ICE1712_SUBDEVICE_DELTADIO2496:
case ICE1712_SUBDEVICE_DELTA66:
case ICE1712_SUBDEVICE_AUDIOPHILE:
case ICE1712_SUBDEVICE_DELTA410:
case ICE1712_SUBDEVICE_DELTA1010LT:
err = snd_ice1712_spdif_build_controls(ice);
if (err < 0)
return err;
......@@ -492,6 +505,7 @@ static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice)
switch (ice->eeprom.subvendor) {
case ICE1712_SUBDEVICE_DELTA1010LT:
case ICE1712_SUBDEVICE_AUDIOPHILE:
case ICE1712_SUBDEVICE_DELTA410:
case ICE1712_SUBDEVICE_DELTA44:
case ICE1712_SUBDEVICE_DELTA66:
err = snd_ice1712_ak4524_build_controls(ice);
......@@ -538,6 +552,12 @@ struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
snd_ice1712_delta_init,
snd_ice1712_delta_add_controls,
},
{
ICE1712_SUBDEVICE_DELTA410,
"M Audio Delta 410",
snd_ice1712_delta_init,
snd_ice1712_delta_add_controls,
},
{
ICE1712_SUBDEVICE_DELTA1010LT,
"M Audio Delta 1010LT",
......
......@@ -37,6 +37,7 @@
#define ICE1712_SUBDEVICE_DELTA66 0x121432d6
#define ICE1712_SUBDEVICE_DELTA44 0x121433d6
#define ICE1712_SUBDEVICE_AUDIOPHILE 0x121434d6
#define ICE1712_SUBDEVICE_DELTA410 0x121438d6
#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6
/* entry point */
......@@ -106,7 +107,8 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
/* 0x40 = CODEC_CHIP_A */
/* 0x80 = CODEC_CHIP_B */
/* MidiMan M-Audio Audiophile definitions */
/* MidiMan M-Audio Audiophile/Delta410 definitions */
/* thanks to Kristof Pelckmans <Kristof.Pelckmans@antwerpen.be> for Delta410 info */
/* 0x01 = DFS */
#define ICE1712_DELTA_AP_CCLK 0x02 /* SPI clock */
/* (clocking on rising edge - 0->1) */
......@@ -114,7 +116,7 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
#define ICE1712_DELTA_AP_DOUT 0x08 /* data output */
#define ICE1712_DELTA_AP_CS_DIGITAL 0x10 /* CS8427 chip select */
/* low signal = select */
#define ICE1712_DELTA_AP_CS_CODEC 0x20 /* AK4528 chip select */
#define ICE1712_DELTA_AP_CS_CODEC 0x20 /* AK4528 (audiophile), AK4529 (Delta410) chip select */
/* low signal = select */
/* MidiMan M-Audio Delta1010LT definitions */
......
......@@ -406,6 +406,7 @@ static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
switch (ice->eeprom.subvendor) {
case ICE1712_SUBDEVICE_EWS88MT:
ak->num_adcs = ak->num_dacs = 8;
ak->type = SND_AK4524;
ak->cif = 1; /* CIF high */
ak->data_mask = ICE1712_EWS88_SERIAL_DATA;
ak->clk_mask = ICE1712_EWS88_SERIAL_CLOCK;
......@@ -418,6 +419,7 @@ static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
break;
case ICE1712_SUBDEVICE_EWX2496:
ak->num_adcs = ak->num_dacs = 2;
ak->type = SND_AK4524;
ak->cif = 1; /* CIF high */
ak->data_mask = ICE1712_EWS88_SERIAL_DATA;
ak->clk_mask = ICE1712_EWS88_SERIAL_CLOCK;
......@@ -430,6 +432,7 @@ static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
break;
case ICE1712_SUBDEVICE_DMX6FIRE:
ak->num_adcs = ak->num_dacs = 6;
ak->type = SND_AK4524;
ak->cif = 1; /* CIF high */
ak->data_mask = ICE1712_6FIRE_SERIAL_DATA;
ak->clk_mask = ICE1712_6FIRE_SERIAL_CLOCK;
......
......@@ -1532,7 +1532,7 @@ static snd_kcontrol_new_t snd_ice1712_eeprom __devinitdata = {
/*
*/
static int snd_ice1712_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
static int snd_ice1712_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
uinfo->count = 1;
......@@ -1559,20 +1559,13 @@ static int snd_ice1712_spdif_default_put(snd_kcontrol_t * kcontrol,
static snd_kcontrol_new_t snd_ice1712_spdif_default __devinitdata =
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
.info = snd_ice1712_spdif_default_info,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
.info = snd_ice1712_spdif_info,
.get = snd_ice1712_spdif_default_get,
.put = snd_ice1712_spdif_default_put
};
static int snd_ice1712_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
uinfo->count = 1;
return 0;
}
static int snd_ice1712_spdif_maskc_get(snd_kcontrol_t * kcontrol,
snd_ctl_elem_value_t * ucontrol)
{
......@@ -1617,29 +1610,22 @@ static int snd_ice1712_spdif_maskp_get(snd_kcontrol_t * kcontrol,
static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
.info = snd_ice1712_spdif_mask_info,
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
.info = snd_ice1712_spdif_info,
.get = snd_ice1712_spdif_maskc_get,
};
static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
.info = snd_ice1712_spdif_mask_info,
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
.info = snd_ice1712_spdif_info,
.get = snd_ice1712_spdif_maskp_get,
};
static int snd_ice1712_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
uinfo->count = 1;
return 0;
}
static int snd_ice1712_spdif_stream_get(snd_kcontrol_t * kcontrol,
snd_ctl_elem_value_t * ucontrol)
{
......@@ -1660,10 +1646,10 @@ static int snd_ice1712_spdif_stream_put(snd_kcontrol_t * kcontrol,
static snd_kcontrol_new_t snd_ice1712_spdif_stream __devinitdata =
{
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
.info = snd_ice1712_spdif_stream_info,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
.info = snd_ice1712_spdif_info,
.get = snd_ice1712_spdif_stream_get,
.put = snd_ice1712_spdif_stream_put
};
......
......@@ -239,10 +239,12 @@ typedef struct {
struct snd_ak4524 {
int num_adcs; /* AK4524 or AK4528 ADCs */
int num_dacs; /* AK4524 or AK4528 DACs */
unsigned char images[4][8];
unsigned char images[4][16];
unsigned char ipga_gain[4][2];
/* */
unsigned int is_ak4528: 1; /* AK4524 or AK4528 */
enum {
SND_AK4524, SND_AK4528, SND_AK4529
} type;
unsigned int cif: 1;
unsigned char data_mask;
unsigned char clk_mask;
......
......@@ -935,7 +935,8 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
struct usb_device *dev = subs->dev;
struct usb_host_config *config = dev->actconfig;
struct usb_host_interface *alts;
struct usb_interface *iface;
struct usb_interface_descriptor *altsd;
struct usb_interface *iface;
struct audioformat *fmt;
unsigned int ep, attr;
unsigned char data[3];
......@@ -951,7 +952,8 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
iface = &config->interface[fmt->iface];
alts = &iface->altsetting[fmt->altset_idx];
snd_assert(alts->desc.bAlternateSetting == fmt->altsetting, return -EINVAL);
altsd = get_iface_desc(alts);
snd_assert(altsd->bAlternateSetting == fmt->altsetting, return -EINVAL);
/* close the old interface */
if (subs->interface >= 0 && subs->interface != fmt->iface) {
......@@ -973,31 +975,31 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
}
/* create a data pipe */
ep = alts->endpoint[0].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
ep = get_endpoint(alts, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
if (is_playback)
subs->datapipe = usb_sndisocpipe(dev, ep);
else
subs->datapipe = usb_rcvisocpipe(dev, ep);
subs->syncpipe = subs->syncinterval = 0;
subs->maxpacksize = alts->endpoint[0].desc.wMaxPacketSize;
subs->maxpacksize = get_endpoint(alts, 0)->wMaxPacketSize;
subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize);
subs->fill_max = 0;
/* we need a sync pipe in async OUT or adaptive IN mode */
attr = alts->endpoint[0].desc.bmAttributes & EP_ATTR_MASK;
attr = get_endpoint(alts, 0)->bmAttributes & EP_ATTR_MASK;
if ((is_playback && attr == EP_ATTR_ASYNC) ||
(! is_playback && attr == EP_ATTR_ADAPTIVE)) {
/* check endpoint */
if (alts->desc.bNumEndpoints < 2 ||
alts->endpoint[1].desc.bmAttributes != 0x01 ||
alts->endpoint[1].desc.bSynchAddress != 0) {
if (altsd->bNumEndpoints < 2 ||
get_endpoint(alts, 1)->bmAttributes != 0x01 ||
get_endpoint(alts, 1)->bSynchAddress != 0) {
snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
dev->devnum, fmt->iface, fmt->altsetting);
return -EINVAL;
}
ep = alts->endpoint[1].desc.bEndpointAddress;
if ((is_playback && ep != (alts->endpoint[0].desc.bSynchAddress | USB_DIR_IN)) ||
(! is_playback && ep != (alts->endpoint[0].desc.bSynchAddress & ~USB_DIR_IN))) {
ep = get_endpoint(alts, 1)->bEndpointAddress;
if ((is_playback && ep != (get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
(! is_playback && ep != (get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN))) {
snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n",
dev->devnum, fmt->iface, fmt->altsetting);
return -EINVAL;
......@@ -1007,10 +1009,10 @@ static int set_format(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
subs->syncpipe = usb_rcvisocpipe(dev, ep);
else
subs->syncpipe = usb_sndisocpipe(dev, ep);
subs->syncinterval = alts->endpoint[1].desc.bRefresh;
subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
}
ep = alts->endpoint[0].desc.bEndpointAddress;
ep = get_endpoint(alts, 0)->bEndpointAddress;
/* if endpoint has pitch control, enable it */
if (fmt->attributes & EP_CS_ATTR_PITCH_CONTROL) {
data[0] = 1;
......@@ -1676,6 +1678,7 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, i
struct usb_host_config *config;
struct usb_interface *iface;
struct usb_host_interface *alts;
struct usb_interface_descriptor *altsd;
int i, altno, err, stream;
int channels, nr_rates, pcm_format, format;
struct audioformat *fp;
......@@ -1688,19 +1691,20 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, i
iface = &config->interface[iface_no];
for (i = 0; i < iface->num_altsetting; i++) {
alts = &iface->altsetting[i];
altsd = get_iface_desc(alts);
/* skip invalid one */
if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO ||
alts->desc.bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING ||
alts->desc.bNumEndpoints < 1)
if (altsd->bInterfaceClass != USB_CLASS_AUDIO ||
altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING ||
altsd->bNumEndpoints < 1)
continue;
/* must be isochronous */
if ((alts->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
USB_ENDPOINT_XFER_ISOC)
continue;
/* check direction */
stream = (alts->endpoint[0].desc.bEndpointAddress & USB_DIR_IN) ?
stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ?
SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
altno = alts->desc.bAlternateSetting;
altno = altsd->bAlternateSetting;
/* get audio formats */
fmt = snd_usb_find_csint_desc(buffer, buflen, NULL, AS_GENERAL, iface_no, altno);
......@@ -1767,8 +1771,8 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, unsigned char *buffer, i
fp->altsetting = altno;
fp->altset_idx = i;
fp->format = pcm_format;
fp->endpoint = alts->endpoint[0].desc.bEndpointAddress;
fp->ep_attr = alts->endpoint[0].desc.bmAttributes;
fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
fp->channels = channels;
fp->attributes = csep[3];
......@@ -1857,8 +1861,10 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
*/
config = dev->actconfig;
for (i = 0; i < p1[7]; i++) {
struct usb_host_interface *alts;
struct usb_interface_descriptor *altsd;
j = p1[8 + i];
if (j >= config->desc.bNumInterfaces) {
if (j >= get_cfg_desc(config)->bNumInterfaces) {
snd_printk(KERN_ERR "%d:%u:%d : does not exist\n",
dev->devnum, ctrlif, j);
continue;
......@@ -1868,8 +1874,10 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", dev->devnum, ctrlif, j);
continue;
}
if (iface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO &&
iface->altsetting[0].desc.bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
alts = &iface->altsetting[0];
altsd = get_iface_desc(alts);
if (altsd->bInterfaceClass == USB_CLASS_AUDIO &&
altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
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;
......@@ -1877,9 +1885,9 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1);
continue;
}
if (iface->altsetting[0].desc.bInterfaceClass != USB_CLASS_AUDIO ||
iface->altsetting[0].desc.bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) {
snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, iface->altsetting[0].desc.bInterfaceClass);
if (altsd->bInterfaceClass != USB_CLASS_AUDIO ||
altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) {
snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, altsd->bInterfaceClass);
/* skip non-supported classes */
continue;
}
......@@ -1941,7 +1949,7 @@ static int snd_usb_roland_ua100_hack(snd_usb_audio_t *chip)
struct usb_interface *iface;
int err;
if (cfg->desc.bNumInterfaces != 3) {
if (get_cfg_desc(cfg)->bNumInterfaces != 3) {
snd_printdd(KERN_ERR "invalid UA-100 descriptor\n");
return -ENXIO;
}
......@@ -2134,18 +2142,22 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
struct usb_interface *intf,
const struct usb_device_id *usb_id)
{
struct usb_host_config *config = dev->actconfig;
struct usb_host_config *config = dev->actconfig;
const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)usb_id->driver_info;
int i;
snd_card_t *card;
snd_usb_audio_t *chip;
int ifnum = intf->altsetting->desc.bInterfaceNumber;
struct usb_host_interface *alts;
int ifnum;
alts = &intf->altsetting[0];
ifnum = get_iface_desc(alts)->bInterfaceNumber;
if (quirk && quirk->ifnum != QUIRK_ANY_INTERFACE && ifnum != quirk->ifnum)
goto __err_val;
if (usb_set_configuration(dev, config->desc.bConfigurationValue) < 0) {
snd_printk(KERN_ERR "cannot set configuration (value 0x%x)\n", config->desc.bConfigurationValue);
if (usb_set_configuration(dev, get_cfg_desc(config)->bConfigurationValue) < 0) {
snd_printk(KERN_ERR "cannot set configuration (value 0x%x)\n", get_cfg_desc(config)->bConfigurationValue);
goto __err_val;
}
......
......@@ -191,4 +191,15 @@ int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif, unsigned char *buffe
int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk);
/*
* retrieve usb_interface descriptor from the host interface
* (conditional for compatibility with the older API)
*/
#ifndef get_iface_desc
#define get_iface_desc(iface) (&iface->desc)
#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
#define get_ep_desc(ep) (&(ep)->desc)
#define get_cfg_desc(cfg) (&(cfg)->desc)
#endif
#endif /* __USBAUDIO_H */
......@@ -515,7 +515,8 @@ static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep)
static struct usb_endpoint_descriptor* snd_usbmidi_get_int_epd(snd_usb_midi_t* umidi)
{
struct usb_interface* intf;
struct usb_host_interface* intfd;
struct usb_host_interface *hostif;
struct usb_interface_descriptor* intfd;
if (umidi->chip->dev->descriptor.idVendor != 0x0582)
return NULL;
......@@ -523,29 +524,37 @@ static struct usb_endpoint_descriptor* snd_usbmidi_get_int_epd(snd_usb_midi_t* u
if (!intf || intf->num_altsetting != 2)
return NULL;
intfd = &intf->altsetting[0];
if (intfd->desc.bNumEndpoints != 2 ||
(intfd->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ||
(intfd->endpoint[1].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK)
hostif = &intf->altsetting[0];
intfd = get_iface_desc(hostif);
if (intfd->bNumEndpoints != 2 ||
(get_endpoint(hostif, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ||
(get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK)
return NULL;
intfd = &intf->altsetting[1];
if (intfd->desc.bNumEndpoints != 2 ||
(intfd->endpoint[0].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ||
(intfd->endpoint[1].desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
hostif = &intf->altsetting[1];
intfd = get_iface_desc(hostif);
if (intfd->bNumEndpoints != 2 ||
(get_endpoint(hostif, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK ||
(get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
return NULL;
usb_set_interface(umidi->chip->dev, intfd->desc.bInterfaceNumber,
intfd->desc.bAlternateSetting);
return &intfd->endpoint[1].desc;
usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber,
intfd->bAlternateSetting);
return get_endpoint(hostif, 1);
}
static struct usb_endpoint_descriptor* snd_usbmidi_get_midiman_int_epd(snd_usb_midi_t* umidi)
{
struct usb_interface* intf = umidi->iface;
if (!intf || intf->altsetting[0].desc.bNumEndpoints < 1)
struct usb_host_interface *hostif;
struct usb_interface_descriptor *intfd;
if (!intf)
return NULL;
hostif = &intf->altsetting[0];
intfd = get_iface_desc(hostif);
if (intfd->bNumEndpoints < 1)
return NULL;
return &intf->altsetting[0].endpoint[0].desc;
return get_endpoint(hostif, 0);
}
/*
......@@ -772,18 +781,21 @@ static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi,
snd_usb_midi_endpoint_info_t* endpoints)
{
struct usb_interface* intf;
struct usb_host_interface* intfd;
struct usb_host_interface *hostif;
struct usb_interface_descriptor* intfd;
struct usb_ms_header_descriptor* ms_header;
struct usb_host_endpoint* ep;
struct usb_host_endpoint *hostep;
struct usb_endpoint_descriptor* ep;
struct usb_ms_endpoint_descriptor* ms_ep;
int i, epidx;
intf = umidi->iface;
if (!intf)
return -ENXIO;
intfd = &intf->altsetting[0];
ms_header = (struct usb_ms_header_descriptor*)intfd->extra;
if (intfd->extralen >= 7 &&
hostif = &intf->altsetting[0];
intfd = get_iface_desc(hostif);
ms_header = (struct usb_ms_header_descriptor*)hostif->extra;
if (hostif->extralen >= 7 &&
ms_header->bLength >= 7 &&
ms_header->bDescriptorType == USB_DT_CS_INTERFACE &&
ms_header->bDescriptorSubtype == HEADER)
......@@ -793,33 +805,34 @@ static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi,
printk(KERN_WARNING "snd-usb-midi: MIDIStreaming interface descriptor not found\n");
epidx = 0;
for (i = 0; i < intfd->desc.bNumEndpoints; ++i) {
ep = &intfd->endpoint[i];
if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK)
for (i = 0; i < intfd->bNumEndpoints; ++i) {
hostep = &hostif->endpoint[i];
ep = get_ep_desc(hostep);
if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK)
continue;
ms_ep = (struct usb_ms_endpoint_descriptor*)ep->extra;
if (ep->extralen < 4 ||
ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra;
if (hostep->extralen < 4 ||
ms_ep->bLength < 4 ||
ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
ms_ep->bDescriptorSubtype != MS_GENERAL)
continue;
if (endpoints[epidx].epnum != 0 &&
endpoints[epidx].epnum != (ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) {
endpoints[epidx].epnum != (ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) {
++epidx;
if (epidx >= MIDI_MAX_ENDPOINTS) {
printk(KERN_WARNING "snd-usb-midi: too many endpoints\n");
break;
}
}
endpoints[epidx].epnum = ep->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
if (ep->desc.bEndpointAddress & USB_DIR_IN) {
endpoints[epidx].epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
if (ep->bEndpointAddress & USB_DIR_IN) {
endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
} else {
endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
}
printk(KERN_INFO "snd-usb-midi: detected %d %s jack(s) on endpoint %d\n",
ms_ep->bNumEmbMIDIJack,
ep->desc.bEndpointAddress & USB_DIR_IN ? "input" : "output",
ep->bEndpointAddress & USB_DIR_IN ? "input" : "output",
endpoints[epidx].epnum);
}
return 0;
......@@ -833,17 +846,19 @@ static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi,
snd_usb_midi_endpoint_info_t* endpoint)
{
struct usb_interface* intf;
struct usb_host_interface* intfd;
struct usb_host_interface *hostif;
struct usb_interface_descriptor* intfd;
struct usb_endpoint_descriptor* epd;
if (endpoint->epnum == -1) {
intf = umidi->iface;
if (!intf || intf->num_altsetting < 1)
return -ENOENT;
intfd = intf->altsetting;
if (intfd->desc.bNumEndpoints < 1)
hostif = intf->altsetting;
intfd = get_iface_desc(hostif);
if (intfd->bNumEndpoints < 1)
return -ENOENT;
epd = &intfd->endpoint [0].desc;
epd = get_endpoint(hostif, 0);
endpoint->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
}
return 0;
......@@ -856,18 +871,20 @@ static int snd_usbmidi_detect_yamaha(snd_usb_midi_t* umidi,
snd_usb_midi_endpoint_info_t* endpoint)
{
struct usb_interface* intf;
struct usb_host_interface* intfd;
struct usb_host_interface *hostif;
struct usb_interface_descriptor* intfd;
uint8_t* cs_desc;
intf = umidi->iface;
if (!intf)
return -ENOENT;
intfd = intf->altsetting;
if (intfd->desc.bNumEndpoints < 1)
hostif = intf->altsetting;
intfd = get_iface_desc(hostif);
if (intfd->bNumEndpoints < 1)
return -ENOENT;
for (cs_desc = intfd->extra;
cs_desc < intfd->extra + intfd->extralen && cs_desc[0] >= 2;
for (cs_desc = hostif->extra;
cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2;
cs_desc += cs_desc[0]) {
if (cs_desc[1] == CS_AUDIO_INTERFACE) {
if (cs_desc[2] == MIDI_IN_JACK)
......@@ -890,33 +907,35 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports
{
snd_usb_midi_endpoint_info_t ep_info;
struct usb_interface* intf;
struct usb_host_interface* intfd;
struct usb_host_interface *hostif;
struct usb_interface_descriptor* intfd;
struct usb_endpoint_descriptor* epd;
int cable, err;
intf = umidi->iface;
if (!intf)
return -ENOENT;
intfd = intf->altsetting;
if (intfd->desc.bNumEndpoints < (ports > 1 ? 5 : 3)) {
hostif = intf->altsetting;
intfd = get_iface_desc(hostif);
if (intfd->bNumEndpoints < (ports > 1 ? 5 : 3)) {
snd_printdd(KERN_ERR "not enough endpoints\n");
return -ENOENT;
}
epd = &intfd->endpoint[0].desc;
epd = get_endpoint(hostif, 0);
if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN ||
(epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n");
return -ENXIO;
}
epd = &intfd->endpoint[2].desc;
epd = get_endpoint(hostif, 2);
if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT ||
(epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n");
return -ENXIO;
}
if (ports > 1) {
epd = &intfd->endpoint[4].desc;
epd = get_endpoint(hostif, 4);
if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT ||
(epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n");
......@@ -924,13 +943,13 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports
}
}
ep_info.epnum = intfd->endpoint[2].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
ep_info.epnum = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
ep_info.out_cables = 0x5555 & ((1 << ports) - 1);
err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
if (err < 0)
return err;
ep_info.epnum = intfd->endpoint[0].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
ep_info.epnum = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
ep_info.in_cables = (1 << ports) - 1;
err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]);
if (err < 0)
......@@ -938,7 +957,7 @@ static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, int ports
umidi->endpoints[0].in->urb->complete = snd_usbmidi_in_midiman_complete;
if (ports > 1) {
ep_info.epnum = intfd->endpoint[4].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
ep_info.epnum = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
ep_info.out_cables = 0xaaaa & ((1 << ports) - 1);
err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]);
if (err < 0)
......
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