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