diff options
| author | Jaroslav Kysela <perex@suse.cz> | 2002-11-10 23:04:58 +0100 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2002-11-10 23:04:58 +0100 |
| commit | b706cbf8bc7faeb415ed5d6de5d168c9f40b314d (patch) | |
| tree | de504961e0bd245d2daa5da1782e2a1a963dd326 | |
| parent | a1a1c4024aaafb0bb9148100cdee5a268c2911a0 (diff) | |
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
| -rw-r--r-- | include/sound/cs4231.h | 45 | ||||
| -rw-r--r-- | include/sound/version.h | 2 | ||||
| -rw-r--r-- | sound/isa/cs423x/cs4231_lib.c | 247 | ||||
| -rw-r--r-- | sound/pci/ice1712/ak4524.c | 178 | ||||
| -rw-r--r-- | sound/pci/ice1712/delta.c | 26 | ||||
| -rw-r--r-- | sound/pci/ice1712/delta.h | 6 | ||||
| -rw-r--r-- | sound/pci/ice1712/ews.c | 3 | ||||
| -rw-r--r-- | sound/pci/ice1712/ice1712.c | 46 | ||||
| -rw-r--r-- | sound/pci/ice1712/ice1712.h | 6 | ||||
| -rw-r--r-- | sound/usb/usbaudio.c | 76 | ||||
| -rw-r--r-- | sound/usb/usbaudio.h | 11 | ||||
| -rw-r--r-- | sound/usb/usbmidi.c | 111 |
12 files changed, 519 insertions, 238 deletions
diff --git a/include/sound/cs4231.h b/include/sound/cs4231.h index 610c2e94705b..75d1b588ee87 100644 --- a/include/sound/cs4231.h +++ b/include/sound/cs4231.h @@ -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 */ diff --git a/include/sound/version.h b/include/sound/version.h index de5e5218a7b4..acaac7181bbe 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* 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)" diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c index 827c3c2541d2..0982bba6b988 100644 --- a/sound/isa/cs423x/cs4231_lib.c +++ b/sound/isa/cs423x/cs4231_lib.c @@ -124,6 +124,48 @@ static unsigned char snd_cs4231_original_image[32] = * Basic I/O functions */ +#if !defined(EBUS_SUPPORT) && !defined(SBUS_SUPPORT) +#define __CS4231_INLINE__ inline +#else +#define __CS4231_INLINE__ /* nothing */ +#endif + +static __CS4231_INLINE__ void cs4231_outb(cs4231_t *chip, u8 offset, u8 val) +{ +#ifdef EBUS_SUPPORT + if (chip->ebus->flag) { + writeb(val, chip->port + (offset << 2)); + } else { +#endif +#ifdef SBUS_SUPPORT + sbus_writeb(val, chip->port + (offset << 2)); +#endif +#ifdef EBUS_SUPPORT + } +#endif +#ifdef LEGACY_SUPPORT + outb(val, chip->port + offset); +#endif +} + +static __CS4231_INLINE__ u8 cs4231_inb(cs4231_t *chip, u8 offset) +{ +#ifdef EBUS_SUPPORT + if (chip->ebus_flag) { + return readb(chip->port + (offset << 2)); + } else { +#endif +#ifdef SBUS_SUPPORT + return sbus_writeb(chip->port + (offset << 2)); +#endif +#ifdef EBUS_SUPPORT + } +#endif +#ifdef LEGACY_SUPPORT + return inb(chip->port + offset); +#endif +} + void snd_cs4231_outm(cs4231_t *chip, unsigned char reg, unsigned char mask, unsigned char value) { @@ -131,21 +173,21 @@ void snd_cs4231_outm(cs4231_t *chip, unsigned char reg, unsigned char tmp; for (timeout = 250; - timeout > 0 && (inb(CS4231P(chip, REGSEL)) & CS4231_INIT); + timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(100); #ifdef CONFIG_SND_DEBUG - if (inb(CS4231P(chip, REGSEL)) & CS4231_INIT) + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); #endif if (chip->calibrate_mute) { chip->image[reg] &= mask; chip->image[reg] |= value; } else { - outb(chip->mce_bit | reg, CS4231P(chip, REGSEL)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); mb(); tmp = (chip->image[reg] & mask) | value; - outb(tmp, CS4231P(chip, REG)); + cs4231_outb(chip, CS4231P(REG), tmp); chip->image[reg] = tmp; mb(); } @@ -156,11 +198,11 @@ static void snd_cs4231_dout(cs4231_t *chip, unsigned char reg, unsigned char val int timeout; for (timeout = 250; - timeout > 0 && (inb(CS4231P(chip, REGSEL)) & CS4231_INIT); + timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(10); - outb(chip->mce_bit | reg, CS4231P(chip, REGSEL)); - outb(value, CS4231P(chip, REG)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + cs4231_outb(chip, CS4231P(REG), value); mb(); } @@ -169,15 +211,15 @@ void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char value) int timeout; for (timeout = 250; - timeout > 0 && (inb(CS4231P(chip, REGSEL)) & CS4231_INIT); + timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(100); #ifdef CONFIG_SND_DEBUG - if (inb(CS4231P(chip, REGSEL)) & CS4231_INIT) + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); #endif - outb(chip->mce_bit | reg, CS4231P(chip, REGSEL)); - outb(value, CS4231P(chip, REG)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); + cs4231_outb(chip, CS4231P(REG), value); chip->image[reg] = value; mb(); #if 0 @@ -190,23 +232,23 @@ unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg) int timeout; for (timeout = 250; - timeout > 0 && (inb(CS4231P(chip, REGSEL)) & CS4231_INIT); + timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(100); #ifdef CONFIG_SND_DEBUG - if (inb(CS4231P(chip, REGSEL)) & CS4231_INIT) + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("in: auto calibration time out - reg = 0x%x\n", reg); #endif - outb(chip->mce_bit | reg, CS4231P(chip, REGSEL)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg); mb(); - return inb(CS4231P(chip, REG)); + return cs4231_inb(chip, CS4231P(REG)); } void snd_cs4236_ext_out(cs4231_t *chip, unsigned char reg, unsigned char val) { - outb(chip->mce_bit | 0x17, CS4231P(chip, REGSEL)); - outb(reg | (chip->image[CS4236_EXT_REG] & 0x01), CS4231P(chip, REG)); - outb(val, CS4231P(chip, REG)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); + cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01)); + cs4231_outb(chip, CS4231P(REG), val); chip->eimage[CS4236_REG(reg)] = val; #if 0 printk("ext out : reg = 0x%x, val = 0x%x\n", reg, val); @@ -215,14 +257,14 @@ void snd_cs4236_ext_out(cs4231_t *chip, unsigned char reg, unsigned char val) unsigned char snd_cs4236_ext_in(cs4231_t *chip, unsigned char reg) { - outb(chip->mce_bit | 0x17, CS4231P(chip, REGSEL)); - outb(reg | (chip->image[CS4236_EXT_REG] & 0x01), CS4231P(chip, REG)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17); + cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01)); #if 1 - return inb(CS4231P(chip, REG)); + return cs4231_inb(chip, CS4231P(REG)); #else { unsigned char res; - res = inb(CS4231P(chip, REG)); + res = cs4231_inb(chip, CS4231P(REG)); printk("ext in : reg = 0x%x, val = 0x%x\n", reg, res); return res; } @@ -233,8 +275,8 @@ unsigned char snd_cs4236_ext_in(cs4231_t *chip, unsigned char reg) void snd_cs4231_debug(cs4231_t *chip) { - printk("CS4231 REGS: INDEX = 0x%02x ", inb(CS4231P(chip, REGSEL))); - printk(" STATUS = 0x%02x\n", inb(CS4231P(chip, STATUS))); + printk("CS4231 REGS: INDEX = 0x%02x ", cs4231_inb(chip, CS4231P(REGSEL))); + printk(" STATUS = 0x%02x\n", cs4231_inb(chip, CS4231P(STATUS))); printk(" 0x00: left input = 0x%02x ", snd_cs4231_in(chip, 0x00)); printk(" 0x10: alt 1 (CFIG 2) = 0x%02x\n", snd_cs4231_in(chip, 0x10)); printk(" 0x01: right input = 0x%02x ", snd_cs4231_in(chip, 0x01)); @@ -281,10 +323,10 @@ static void snd_cs4231_busy_wait(cs4231_t *chip) /* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */ for (timeout = 5; timeout > 0; timeout--) - inb(CS4231P(chip, REGSEL)); + cs4231_inb(chip, CS4231P(REGSEL)); /* end of cleanup sequence */ for (timeout = 250; - timeout > 0 && (inb(CS4231P(chip, REGSEL)) & CS4231_INIT); + timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(10); } @@ -295,18 +337,18 @@ void snd_cs4231_mce_up(cs4231_t *chip) int timeout; spin_lock_irqsave(&chip->reg_lock, flags); - for (timeout = 250; timeout > 0 && (inb(CS4231P(chip, REGSEL)) & CS4231_INIT); timeout--) + for (timeout = 250; timeout > 0 && (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT); timeout--) udelay(100); #ifdef CONFIG_SND_DEBUG - if (inb(CS4231P(chip, REGSEL)) & CS4231_INIT) + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) snd_printk("mce_up - auto calibration time out (0)\n"); #endif chip->mce_bit |= CS4231_MCE; - timeout = inb(CS4231P(chip, REGSEL)); + timeout = cs4231_inb(chip, CS4231P(REGSEL)); if (timeout == 0x80) snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); if (!(timeout & CS4231_MCE)) - outb(chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); spin_unlock_irqrestore(&chip->reg_lock, flags); } @@ -322,12 +364,12 @@ void snd_cs4231_mce_down(cs4231_t *chip) printk("(1) timeout = %i\n", timeout); #endif #ifdef CONFIG_SND_DEBUG - if (inb(CS4231P(chip, REGSEL)) & CS4231_INIT) - snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", CS4231P(chip, REGSEL)); + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) + snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", (long)CS4231P(REGSEL)); #endif chip->mce_bit &= ~CS4231_MCE; - timeout = inb(CS4231P(chip, REGSEL)); - outb(chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); + timeout = cs4231_inb(chip, CS4231P(REGSEL)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); if (timeout == 0x80) snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((timeout & CS4231_MCE) == 0 || @@ -364,7 +406,7 @@ void snd_cs4231_mce_down(cs4231_t *chip) printk("(3) jiffies = %li\n", jiffies); #endif time = HZ / 10; - while (inb(CS4231P(chip, REGSEL)) & CS4231_INIT) { + while (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) { spin_unlock_irqrestore(&chip->reg_lock, flags); if (time <= 0) { snd_printk("mce_down - auto calibration time out (3)\n"); @@ -377,7 +419,7 @@ void snd_cs4231_mce_down(cs4231_t *chip) spin_unlock_irqrestore(&chip->reg_lock, flags); #if 0 printk("(4) jiffies = %li\n", jiffies); - snd_printk("mce_down - exit = 0x%x\n", inb(CS4231P(chip, REGSEL))); + snd_printk("mce_down - exit = 0x%x\n", cs4231_inb(chip, CS4231P(REGSEL))); #endif } @@ -403,7 +445,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int result = 0; #if 0 - printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, inb(CS4231P(card, STATUS))); + printk("codec trigger!!! - what = %i, enable = %i, status = 0x%x\n", what, enable, cs4231_inb(chip, CS4231P(STATUS))); #endif switch (cmd) { @@ -423,10 +465,15 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, s = s->link_next; } while (s != substream); spin_lock(&chip->reg_lock); - if (cmd == SNDRV_PCM_TRIGGER_START) + if (cmd == SNDRV_PCM_TRIGGER_START) { chip->image[CS4231_IFACE_CTRL] |= what; - else + if (chip->trigger) + chip->trigger(chip, what, 1); + } else { chip->image[CS4231_IFACE_CTRL] &= ~what; + if (chip->trigger) + chip->trigger(chip, what, 0); + } snd_cs4231_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]); spin_unlock(&chip->reg_lock); break; @@ -640,7 +687,7 @@ static void snd_cs4231_init(cs4231_t *chip) snd_cs4231_mce_down(chip); -#ifdef SNDRV_DEBUG_MCE +#ifdef SNDRV_DEBUGq_MCE snd_printk("init: (1)\n"); #endif snd_cs4231_mce_up(chip); @@ -713,8 +760,8 @@ static int snd_cs4231_open(cs4231_t *chip, unsigned int mode) CS4231_RECORD_IRQ | CS4231_TIMER_IRQ); snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - outb(0, CS4231P(chip, STATUS)); /* clear IRQ */ - outb(0, CS4231P(chip, STATUS)); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE; snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); snd_cs4231_out(chip, CS4231_IRQ_STATUS, CS4231_PLAYBACK_IRQ | @@ -743,8 +790,8 @@ static void snd_cs4231_close(cs4231_t *chip, unsigned int mode) /* disable IRQ */ spin_lock_irqsave(&chip->reg_lock, flags); snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - outb(0, CS4231P(chip, STATUS)); /* clear IRQ */ - outb(0, CS4231P(chip, STATUS)); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE; snd_cs4231_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]); @@ -765,8 +812,8 @@ static void snd_cs4231_close(cs4231_t *chip, unsigned int mode) /* clear IRQ again */ snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0); - outb(0, CS4231P(chip, STATUS)); /* clear IRQ */ - outb(0, CS4231P(chip, STATUS)); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); /* clear IRQ */ spin_unlock_irqrestore(&chip->reg_lock, flags); snd_cs4231_calibrate_mute(chip, 0); @@ -829,6 +876,7 @@ static int snd_cs4231_playback_hw_free(snd_pcm_substream_t * substream) return snd_pcm_lib_free_pages(substream); } +#ifdef LEGACY_SUPPORT static int snd_cs4231_playback_prepare(snd_pcm_substream_t * substream) { cs4231_t *chip = snd_pcm_substream_chip(substream); @@ -850,6 +898,7 @@ static int snd_cs4231_playback_prepare(snd_pcm_substream_t * substream) #endif return 0; } +#endif /* LEGACY_SUPPORT */ static int snd_cs4231_capture_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params) @@ -871,6 +920,7 @@ static int snd_cs4231_capture_hw_free(snd_pcm_substream_t * substream) return snd_pcm_lib_free_pages(substream); } +#ifdef LEGACY_SUPPORT static int snd_cs4231_capture_prepare(snd_pcm_substream_t * substream) { cs4231_t *chip = snd_pcm_substream_chip(substream); @@ -894,6 +944,7 @@ static int snd_cs4231_capture_prepare(snd_pcm_substream_t * substream) spin_unlock_irqrestore(&chip->reg_lock, flags); return 0; } +#endif static void snd_cs4231_overrange(cs4231_t *chip) { @@ -940,6 +991,7 @@ void snd_cs4231_interrupt(int irq, void *dev_id, struct pt_regs *regs) spin_unlock(&chip->reg_lock); } +#ifdef LEGACY_SUPPORT static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t * substream) { cs4231_t *chip = snd_pcm_substream_chip(substream); @@ -961,12 +1013,13 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substr ptr = chip->c_dma_size - snd_dma_residue(chip->dma2); return bytes_to_frames(substream->runtime, ptr); } +#endif /* LEGACY_SUPPORT */ /* */ -static int snd_cs4231_probe(cs4231_t *chip) +int snd_cs4231_probe(cs4231_t *chip) { unsigned long flags; int i, id, rev; @@ -979,7 +1032,7 @@ static int snd_cs4231_probe(cs4231_t *chip) id = 0; for (i = 0; i < 50; i++) { mb(); - if (inb(CS4231P(chip, REGSEL)) & CS4231_INIT) + if (cs4231_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) udelay(2000); else { spin_lock_irqsave(&chip->reg_lock, flags); @@ -1020,8 +1073,8 @@ static int snd_cs4231_probe(cs4231_t *chip) } } spin_lock_irqsave(&chip->reg_lock, flags); - inb(CS4231P(chip, STATUS)); /* clear any pendings IRQ */ - outb(0, CS4231P(chip, STATUS)); + cs4231_inb(chip, CS4231P(STATUS)); /* clear any pendings IRQ */ + cs4231_outb(chip, CS4231P(STATUS), 0); mb(); spin_unlock_irqrestore(&chip->reg_lock, flags); @@ -1189,6 +1242,7 @@ static int snd_cs4231_playback_open(snd_pcm_substream_t * substream) chip->hardware == CS4231_HW_CS4239) runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; +#ifdef LEGACY_SUPPORT snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max); snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max); @@ -1196,14 +1250,20 @@ static int snd_cs4231_playback_open(snd_pcm_substream_t * substream) if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0) return err; } +#endif if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) { +#ifdef LEGACY_SUPPORT if (chip->release_dma) chip->release_dma(chip, chip->dma_private_data, chip->dma1); +#endif snd_free_pages(runtime->dma_area, runtime->dma_bytes); return err; } chip->playback_substream = substream; +#if defined(SBUS_SUPPORT) || defined(EBUS_SUPPORT) + chip->p_periods_sent = 0; +#endif snd_pcm_set_sync(substream); chip->rate_constraint(runtime); return 0; @@ -1222,21 +1282,28 @@ static int snd_cs4231_capture_open(snd_pcm_substream_t * substream) chip->hardware == CS4231_HW_CS4239) runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE; +#ifdef LEGACY_SUPPORT + snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max); + snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max); + if (chip->claim_dma) { if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0) return err; } - - snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max); - snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max); +#endif if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) { +#ifdef LEGACY_SUPPORT if (chip->release_dma) chip->release_dma(chip, chip->dma_private_data, chip->dma2); +#endif snd_free_pages(runtime->dma_area, runtime->dma_bytes); return err; } chip->capture_substream = substream; +#if defined(SBUS_SUPPORT) || defined(EBUS_SUPPORT) + chip->c_periods_sent = 0; +#endif snd_pcm_set_sync(substream); chip->rate_constraint(runtime); return 0; @@ -1301,8 +1368,8 @@ static void snd_cs4231_resume(cs4231_t *chip) spin_lock_irqsave(&chip->reg_lock, flags); snd_cs4231_busy_wait(chip); chip->mce_bit &= ~CS4231_MCE; - timeout = inb(CS4231P(chip, REGSEL)); - outb(chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL)); + timeout = cs4231_inb(chip, CS4231P(REGSEL)); + cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f)); if (timeout == 0x80) snd_printk("down [0x%lx]: serious init problem - codec still busy\n", chip->port); if ((timeout & CS4231_MCE) == 0 || @@ -1334,6 +1401,8 @@ static int snd_cs4231_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *d #endif /* CONFIG_PM */ +#ifdef LEGACY_SUPPORT + static int snd_cs4231_free(cs4231_t *chip) { if (chip->res_port) { @@ -1373,6 +1442,8 @@ static int snd_cs4231_dev_free(snd_device_t *device) return snd_cs4231_free(chip); } +#endif /* LEGACY_SUPPORT */ + const char *snd_cs4231_chip_id(cs4231_t *chip) { switch (chip->hardware) { @@ -1392,6 +1463,35 @@ const char *snd_cs4231_chip_id(cs4231_t *chip) } } +static int snd_cs4231_new(snd_card_t * card, + unsigned short hardware, + unsigned short hwshare, + cs4231_t ** rchip) +{ + cs4231_t *chip; + + *rchip = NULL; + chip = snd_magic_kcalloc(cs4231_t, 0, GFP_KERNEL); + if (chip == NULL) + return -ENOMEM; + chip->hardware = hardware; + chip->hwshare = hwshare; + + spin_lock_init(&chip->reg_lock); + init_MUTEX(&chip->mce_mutex); + init_MUTEX(&chip->open_mutex); + chip->card = card; + chip->rate_constraint = snd_cs4231_xrate; + chip->set_playback_format = snd_cs4231_playback_format; + chip->set_capture_format = snd_cs4231_capture_format; + memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image)); + + *rchip = chip; + return 0; +} + +#ifdef LEGACY_SUPPORT + int snd_cs4231_create(snd_card_t * card, unsigned long port, unsigned long cport, @@ -1406,15 +1506,13 @@ int snd_cs4231_create(snd_card_t * card, cs4231_t *chip; int err; - *rchip = NULL; - chip = snd_magic_kcalloc(cs4231_t, 0, GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; + err = snd_cs4231_new(card, hardware, hwshare, &chip); + if (err < 0) + return err; + chip->irq = -1; chip->dma1 = -1; chip->dma2 = -1; - chip->hardware = hardware; - chip->hwshare = hwshare; if ((chip->res_port = request_region(port, 4, "CS4231")) == NULL) { snd_cs4231_free(chip); @@ -1446,15 +1544,6 @@ int snd_cs4231_create(snd_card_t * card, } else chip->dma2 = dma2; - spin_lock_init(&chip->reg_lock); - init_MUTEX(&chip->mce_mutex); - init_MUTEX(&chip->open_mutex); - chip->card = card; - chip->rate_constraint = snd_cs4231_xrate; - chip->set_playback_format = snd_cs4231_playback_format; - chip->set_capture_format = snd_cs4231_capture_format; - memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image)); - /* global setup */ if (snd_cs4231_probe(chip) < 0) { snd_cs4231_free(chip); @@ -1486,6 +1575,8 @@ int snd_cs4231_create(snd_card_t * card, return 0; } +#endif /* LEGACY_SUPPORT */ + static snd_pcm_ops_t snd_cs4231_playback_ops = { .open = snd_cs4231_playback_open, .close = snd_cs4231_playback_close, @@ -1540,7 +1631,23 @@ int snd_cs4231_pcm(cs4231_t *chip, int device, snd_pcm_t **rpcm) pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX; strcpy(pcm->name, snd_cs4231_chip_id(chip)); +#ifdef LEGACY_SUPPORT snd_pcm_lib_preallocate_isa_pages_for_all(pcm, 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024); +#else +# ifdef EBUS_SUPPORT + if (chip->ebus_flag) { + snd_pcm_lib_preallocate_pci_pages_for_all(chip->dev_u.pdev, pcm, + 64*1024, 128*1024); + } else { +# endif +# ifdef SBUS_SUPPORT + snd_pcm_lib_preallocate_sbus_pages_for_all(chip->dev_u.sdev, pcm, + 64*1024, 128*1024); +# endif +# ifdef EBUS_SUPPORT + } +# endif +#endif chip->pcm = pcm; if (rpcm) diff --git a/sound/pci/ice1712/ak4524.c b/sound/pci/ice1712/ak4524.c index bf0f0cdeb3bd..fe2e2a061de4 100644 --- a/sound/pci/ice1712/ak4524.c +++ b/sound/pci/ice1712/ak4524.c @@ -1,7 +1,7 @@ /* * ALSA driver for ICEnsemble ICE1712 (Envy24) * - * AK4524 / AK4528 interface + * AK4524 / AK4528 / AK4529 interface * * Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz> * @@ -67,6 +67,7 @@ void snd_ice1712_ak4524_write(ice1712_t *ice, int chip, addr &= 0x07; /* build I2C address + data byte */ + /* assume C1=1, C0=0 */ addrdata = 0xa000 | (addr << 8) | data; for (idx = 15; idx >= 0; idx--) { tmp &= ~(ak->data_mask | ak->clk_mask); @@ -80,11 +81,13 @@ void snd_ice1712_ak4524_write(ice1712_t *ice, int chip, udelay(1); } - if ((addr != 0x04 && addr != 0x05) || (data & 0x80) == 0) - ak->images[chip][addr] = data; - else - ak->ipga_gain[chip][addr-4] = data; - + if (ak->type == SND_AK4524) { + if ((addr != 0x04 && addr != 0x05) || (data & 0x80) == 0) + ak->images[chip][addr] = data; + else + ak->ipga_gain[chip][addr-4] = data; + } + if (ak->cs_mask == ak->cs_addr) { if (ak->cif) { /* assert a cs pulse to trigger */ @@ -112,16 +115,26 @@ void snd_ice1712_ak4524_reset(ice1712_t *ice, int state) unsigned char reg; ak4524_t *ak = &ice->ak4524; - for (chip = 0; chip < ak->num_dacs/2; chip++) { - snd_ice1712_ak4524_write(ice, chip, 0x01, state ? 0x00 : 0x03); - if (state) - continue; - for (reg = 0x04; reg < (ak->is_ak4528 ? 0x06 : 0x08); reg++) - snd_ice1712_ak4524_write(ice, chip, reg, ak->images[chip][reg]); - if (ak->is_ak4528) - continue; - for (reg = 0x04; reg < 0x06; reg++) - snd_ice1712_ak4524_write(ice, chip, reg, ak->ipga_gain[chip][reg-4]); + switch (ak->type) { + case SND_AK4524: + case SND_AK4528: + for (chip = 0; chip < ak->num_dacs/2; chip++) { + snd_ice1712_ak4524_write(ice, chip, 0x01, state ? 0x00 : 0x03); + if (state) + continue; + /* DAC volumes */ + for (reg = 0x04; reg < (ak->type == SND_AK4528 ? 0x06 : 0x08); reg++) + snd_ice1712_ak4524_write(ice, chip, reg, ak->images[chip][reg]); + if (ak->type == SND_AK4528) + continue; + /* IPGA */ + for (reg = 0x04; reg < 0x06; reg++) + snd_ice1712_ak4524_write(ice, chip, reg, ak->ipga_gain[chip][reg-4]); + } + break; + case SND_AK4529: + /* FIXME: needed for ak4529? */ + break; } } @@ -130,7 +143,7 @@ void snd_ice1712_ak4524_reset(ice1712_t *ice, int state) */ void __devinit snd_ice1712_ak4524_init(ice1712_t *ice) { - static unsigned char inits[] = { + static unsigned char inits_ak4524[] = { 0x00, 0x07, /* 0: all power up */ 0x01, 0x00, /* 1: ADC/DAC reset */ 0x02, 0x60, /* 2: 24bit I2S */ @@ -144,28 +157,68 @@ void __devinit snd_ice1712_ak4524_init(ice1712_t *ice) 0x07, 0x00, /* 7: DAC right muted */ 0xff, 0xff }; - int chip, idx; - unsigned char *ptr, reg, data; + static unsigned char inits_ak4528[] = { + 0x00, 0x07, /* 0: all power up */ + 0x01, 0x00, /* 1: ADC/DAC reset */ + 0x02, 0x60, /* 2: 24bit I2S */ + 0x03, 0x0d, /* 3: deemphasis off, turn LR highpass filters on */ + 0x01, 0x03, /* 1: ADC/DAC enable */ + 0x04, 0x00, /* 4: ADC left muted */ + 0x05, 0x00, /* 5: ADC right muted */ + 0xff, 0xff + }; + static unsigned char inits_ak4529[] = { + 0x09, 0x01, /* 9: ATS=0, RSTN=1 */ + 0x0a, 0x3f, /* A: all power up, no zero/overflow detection */ + 0x00, 0x08, /* 0: TDM=0, 24bit I2S, SMUTE=0 */ + 0x01, 0x00, /* 1: ACKS=0, ADC, loop off */ + 0x02, 0xff, /* 2: LOUT1 muted */ + 0x03, 0xff, /* 3: ROUT1 muted */ + 0x04, 0xff, /* 4: LOUT2 muted */ + 0x05, 0xff, /* 5: ROUT2 muted */ + 0x06, 0xff, /* 6: LOUT3 muted */ + 0x07, 0xff, /* 7: ROUT3 muted */ + 0x0b, 0xff, /* B: LOUT4 muted */ + 0x0c, 0xff, /* C: ROUT4 muted */ + 0x08, 0x55, /* 8: deemphasis all off */ + 0xff, 0xff + }; + int chip, num_chips; + unsigned char *ptr, reg, data, *inits; ak4524_t *ak = &ice->ak4524; - for (chip = idx = 0; chip < ak->num_dacs/2; chip++) { + switch (ak->type) { + case SND_AK4524: + inits = inits_ak4524; + num_chips = ak->num_dacs / 2; + break; + case SND_AK4528: + inits = inits_ak4528; + num_chips = ak->num_dacs / 2; + break; + case SND_AK4529: + default: + inits = inits_ak4529; + num_chips = 1; + break; + } + + for (chip = 0; chip < num_chips; chip++) { ptr = inits; while (*ptr != 0xff) { reg = *ptr++; data = *ptr++; - if (ak->is_ak4528) { - if (reg > 5) - continue; - if (reg >= 4 && (data & 0x80)) - continue; - } - if (reg == 0x03 && ak->is_ak4528) - data = 0x0d; /* deemphasis off, turn LR highpass filters on */ snd_ice1712_ak4524_write(ice, chip, reg, data); } } } + +#define AK_GET_CHIP(val) (((val) >> 8) & 0xff) +#define AK_GET_ADDR(val) ((val) & 0xff) +#define AK_GET_SHIFT(val) (((val) >> 16) & 0xff) +#define AK_COMPOSE(chip,addr,shift) (((chip) << 8) | (addr) | ((shift) << 16)) + static int snd_ice1712_ak4524_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -178,8 +231,8 @@ static int snd_ice1712_ak4524_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem static int snd_ice1712_ak4524_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int chip = kcontrol->private_value / 8; - int addr = kcontrol->private_value % 8; + int chip = AK_GET_CHIP(kcontrol->private_value); + int addr = AK_GET_ADDR(kcontrol->private_value); ucontrol->value.integer.value[0] = ice->ak4524.images[chip][addr]; return 0; } @@ -187,8 +240,8 @@ static int snd_ice1712_ak4524_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_ static int snd_ice1712_ak4524_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int chip = kcontrol->private_value / 8; - int addr = kcontrol->private_value % 8; + int chip = AK_GET_CHIP(kcontrol->private_value); + int addr = AK_GET_ADDR(kcontrol->private_value); unsigned char nval = ucontrol->value.integer.value[0]; int change = ice->ak4524.images[chip][addr] != nval; if (change) @@ -208,8 +261,8 @@ static int snd_ice1712_ak4524_ipga_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_e static int snd_ice1712_ak4524_ipga_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int chip = kcontrol->private_value / 8; - int addr = kcontrol->private_value % 8; + int chip = AK_GET_CHIP(kcontrol->private_value); + int addr = AK_GET_ADDR(kcontrol->private_value); ucontrol->value.integer.value[0] = ice->ak4524.ipga_gain[chip][addr-4] & 0x7f; return 0; } @@ -217,8 +270,8 @@ static int snd_ice1712_ak4524_ipga_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_el static int snd_ice1712_ak4524_ipga_gain_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int chip = kcontrol->private_value / 8; - int addr = kcontrol->private_value % 8; + int chip = AK_GET_CHIP(kcontrol->private_value); + int addr = AK_GET_ADDR(kcontrol->private_value); unsigned char nval = (ucontrol->value.integer.value[0] % 37) | 0x80; int change = ice->ak4524.ipga_gain[chip][addr] != nval; if (change) @@ -243,21 +296,26 @@ static int snd_ice1712_ak4524_deemphasis_info(snd_kcontrol_t *kcontrol, snd_ctl_ static int snd_ice1712_ak4524_deemphasis_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol) { ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int chip = kcontrol->id.index; - ucontrol->value.enumerated.item[0] = ice->ak4524.images[chip][3] & 3; + int chip = AK_GET_CHIP(kcontrol->private_value); + int addr = AK_GET_ADDR(kcontrol->private_value); + int shift = AK_GET_SHIFT(kcontrol->private_value); + ucontrol->value.enumerated.item[0] = (ice->ak4524.images[chip][addr] >> shift) & 3; return 0; } static int snd_ice1712_ak4524_deemphasis_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) { ice1712_t *ice = snd_kcontrol_chip(kcontrol); - int chip = kcontrol->id.index; - unsigned char nval = ucontrol->value.enumerated.item[0]; + int chip = AK_GET_CHIP(kcontrol->private_value); + int addr = AK_GET_ADDR(kcontrol->private_value); + int shift = AK_GET_SHIFT(kcontrol->private_value); + unsigned char nval = ucontrol->value.enumerated.item[0] & 3; int change; - nval |= (nval & 3) | (ice->ak4524.images[chip][3] & ~3); - change = ice->ak4524.images[chip][3] != nval; + + nval = (nval << shift) | (ice->ak4524.images[chip][addr] & ~(3 << shift)); + change = ice->ak4524.images[chip][addr] != nval; if (change) - snd_ice1712_ak4524_write(ice, chip, 3, nval); + snd_ice1712_ak4524_write(ice, chip, addr, nval); return change; } @@ -280,15 +338,24 @@ int __devinit snd_ice1712_ak4524_build_controls(ice1712_t *ice) ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE; ctl.get = snd_ice1712_ak4524_volume_get; ctl.put = snd_ice1712_ak4524_volume_put; - if (ak->is_ak4528) - ctl.private_value = (idx / 2) * 8 + (idx % 2) + 4; /* register 4 & 5 */ - else - ctl.private_value = (idx / 2) * 8 + (idx % 2) + 6; /* register 6 & 7 */ + switch (ak->type) { + case SND_AK4524: + ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 6, 0); /* register 6 & 7 */ + break; + case SND_AK4528: + ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0); /* register 4 & 5 */ + break; + case SND_AK4529: { + int val = idx < 6 ? idx + 2 : (idx - 6) + 0xb; /* registers 2-7 and b,c */ + ctl.private_value = AK_COMPOSE(0, val, 0); + break; + } + } ctl.private_data = ice; if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0) return err; } - for (idx = 0; idx < ak->num_adcs && !ak->is_ak4528; ++idx) { + for (idx = 0; idx < ak->num_adcs && ak->type == SND_AK4524; ++idx) { snd_kcontrol_t ctl; memset(&ctl, 0, sizeof(ctl)); strcpy(ctl.id.name, "ADC Volume"); @@ -298,7 +365,7 @@ int __devinit snd_ice1712_ak4524_build_controls(ice1712_t *ice) ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE; ctl.get = snd_ice1712_ak4524_volume_get; ctl.put = snd_ice1712_ak4524_volume_put; - ctl.private_value = (idx / 2) * 8 + (idx % 2) + 4; /* register 4 & 5 */ + ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0); /* register 4 & 5 */ ctl.private_data = ice; if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0) return err; @@ -310,7 +377,7 @@ int __devinit snd_ice1712_ak4524_build_controls(ice1712_t *ice) ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE; ctl.get = snd_ice1712_ak4524_ipga_gain_get; ctl.put = snd_ice1712_ak4524_ipga_gain_put; - ctl.private_value = (idx / 2) * 8 + (idx % 2) + 4; /* register 4 & 5 */ + ctl.private_value = AK_COMPOSE(idx/2, (idx%2) + 4, 0); /* register 4 & 5 */ ctl.private_data = ice; if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0) return err; @@ -325,6 +392,17 @@ int __devinit snd_ice1712_ak4524_build_controls(ice1712_t *ice) ctl.access = SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE; ctl.get = snd_ice1712_ak4524_deemphasis_get; ctl.put = snd_ice1712_ak4524_deemphasis_put; + switch (ak->type) { + case SND_AK4524: + case SND_AK4528: + ctl.private_value = AK_COMPOSE(idx, 3, 0); /* register 3 */ + break; + case SND_AK4529: { + int shift = idx == 3 ? 6 : (2 - idx) * 2; + ctl.private_value = AK_COMPOSE(0, 8, shift); /* register 8 with shift */ + break; + } + } ctl.private_data = ice; if ((err = snd_ctl_add(ice->card, snd_ctl_new(&ctl))) < 0) return err; diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 46a293aba458..e4518ddab848 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -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); @@ -539,6 +553,12 @@ struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { 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", snd_ice1712_delta_init, diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index edae9fbcf224..dc8a3a61428d 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h @@ -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 */ diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 230731ad8a14..2195982175a0 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -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; diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 2e7f439874b2..e1dba1ddbfcb 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -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 }; diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index d530dd64d629..3d6ae77c1d62 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -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; diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 24c693642b65..d18451343ddf 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -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; } diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 868143cd4f47..1f70895ea831 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -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 */ diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index f26b2069e5b2..4e75e1c102ec 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -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) |
