]> git.neil.brown.name Git - history.git/commitdiff
ALSA update
authorJaroslav Kysela <perex@suse.cz>
Sun, 10 Nov 2002 22:04:58 +0000 (23:04 +0100)
committerJaroslav Kysela <perex@suse.cz>
Sun, 10 Nov 2002 22:04:58 +0000 (23:04 +0100)
   - 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

12 files changed:
include/sound/cs4231.h
include/sound/version.h
sound/isa/cs423x/cs4231_lib.c
sound/pci/ice1712/ak4524.c
sound/pci/ice1712/delta.c
sound/pci/ice1712/delta.h
sound/pci/ice1712/ews.c
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1712.h
sound/usb/usbaudio.c
sound/usb/usbaudio.h
sound/usb/usbmidi.c

index 610c2e94705b6f7af91db6bd4b860d0e203dc68b..75d1b588ee87fd1fdce79779e5e0cdf935a375e5 100644 (file)
 #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 */
index de5e5218a7b4424cfb8fce8bc92e75dabf932b7c..acaac7181bbed1a04fb114999357c1f0e29772a1 100644 (file)
@@ -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)"
index 827c3c2541d216df9e04f0111e52b0d7a1f8d694..0982bba6b988990c2bf85958a325f76ea5375463 100644 (file)
@@ -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)
index bf0f0cdeb3bdabd91b09ac58b239725adb5e9af4..fe2e2a061de44079acfb2e6cf1c21d05921f8a90 100644 (file)
@@ -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;
index 46a293aba458ab81348add7880c12152d361d6e7..e4518ddab848eff71da20b3f1da781ee13c7af54 100644 (file)
@@ -337,6 +337,9 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
        case ICE1712_SUBDEVICE_AUDIOPHILE:
                ice->num_total_dacs = 2;
                break;
+       case ICE1712_SUBDEVICE_DELTA410:
+               ice->num_total_dacs = 8;
+               break;
        case ICE1712_SUBDEVICE_DELTA44:
        case ICE1712_SUBDEVICE_DELTA66:
                ice->num_total_dacs = ice->omni ? 8 : 4;
@@ -350,6 +353,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
        /* initialize spdif */
        switch (ice->eeprom.subvendor) {
        case ICE1712_SUBDEVICE_AUDIOPHILE:
+       case ICE1712_SUBDEVICE_DELTA410:
        case ICE1712_SUBDEVICE_DELTA1010LT:
                if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
                        snd_printk("unable to create I2C bus\n");
@@ -378,12 +382,17 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
        ak = &ice->ak4524;
        switch (ice->eeprom.subvendor) {
        case ICE1712_SUBDEVICE_AUDIOPHILE:
+       case ICE1712_SUBDEVICE_DELTA410:
                ak->num_adcs = ak->num_dacs = 2;
-               ak->is_ak4528 = 1;
-               ak->cif = 0; /* the default level of the CIF pin from AK4524 */
+               ak->type = SND_AK4528;
+               if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA410) {
+                       ak->num_dacs = 8;
+                       ak->type = SND_AK4529;
+               }
+               ak->cif = 0; /* the default level of the CIF pin from AK4528/4529 */
                ak->data_mask = ICE1712_DELTA_AP_DOUT;
                ak->clk_mask = ICE1712_DELTA_AP_CCLK;
-               ak->cs_mask = ak->cs_addr = ICE1712_DELTA_AP_CS_CODEC; /* select AK4528 codec */
+               ak->cs_mask = ak->cs_addr = ICE1712_DELTA_AP_CS_CODEC; /* select AK4528/4529 codec */
                ak->cs_none = 0;
                ak->add_flags = ICE1712_DELTA_AP_CS_DIGITAL; /* assert digital high */
                ak->mask_flags = 0;
@@ -392,6 +401,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
                break;
        case ICE1712_SUBDEVICE_DELTA1010LT:
                ak->num_adcs = ak->num_dacs = 8;
+               ak->type = SND_AK4524;
                ak->cif = 0; /* the default level of the CIF pin from AK4524 */
                ak->data_mask = ICE1712_DELTA_1010LT_DOUT;
                ak->clk_mask = ICE1712_DELTA_1010LT_CCLK;
@@ -406,6 +416,7 @@ static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
        case ICE1712_SUBDEVICE_DELTA66:
        case ICE1712_SUBDEVICE_DELTA44:
                ak->num_adcs = ak->num_dacs = 4;
+               ak->type = SND_AK4524;
                ak->cif = 0; /* the default level of the CIF pin from AK4524 */
                ak->data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA;
                ak->clk_mask = ICE1712_DELTA_CODEC_SERIAL_CLOCK;
@@ -471,6 +482,8 @@ static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice)
        case ICE1712_SUBDEVICE_DELTADIO2496:
        case ICE1712_SUBDEVICE_DELTA66:
        case ICE1712_SUBDEVICE_AUDIOPHILE:
+       case ICE1712_SUBDEVICE_DELTA410:
+       case ICE1712_SUBDEVICE_DELTA1010LT:
                err = snd_ice1712_spdif_build_controls(ice);
                if (err < 0)
                        return err;
@@ -492,6 +505,7 @@ static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice)
        switch (ice->eeprom.subvendor) {
        case ICE1712_SUBDEVICE_DELTA1010LT:
        case ICE1712_SUBDEVICE_AUDIOPHILE:
+       case ICE1712_SUBDEVICE_DELTA410:
        case ICE1712_SUBDEVICE_DELTA44:
        case ICE1712_SUBDEVICE_DELTA66:
                err = snd_ice1712_ak4524_build_controls(ice);
@@ -538,6 +552,12 @@ struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
                snd_ice1712_delta_init,
                snd_ice1712_delta_add_controls,
        },
+       {
+               ICE1712_SUBDEVICE_DELTA410,
+               "M Audio Delta 410",
+               snd_ice1712_delta_init,
+               snd_ice1712_delta_add_controls,
+       },
        {
                ICE1712_SUBDEVICE_DELTA1010LT,
                "M Audio Delta 1010LT",
index edae9fbcf22412633a5bd3ab237a02ae77ff4eed..dc8a3a61428d848315c21c779fec9ddb9e3718c0 100644 (file)
@@ -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 */
index 230731ad8a149888cbc2716edcc157ddf0551ab6..2195982175a03236b732f0ef175ae690455b05a8 100644 (file)
@@ -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;
index 2e7f439874b29826cc04c09375e0e8eb355867e9..e1dba1ddbfcb3107a5369120453e5efb7557f6f1 100644 (file)
@@ -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
 };
index d530dd64d629f482b5210dcc65f273f65dd8e5f5..3d6ae77c1d62e6e783c7cb655e8ef4d55e3a2ba7 100644 (file)
@@ -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;
index 24c693642b656d594ba5ec9062ea0bf766b8afe2..d18451343ddf8e08469d04fa920af76b3e129db7 100644 (file)
@@ -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;
        }
 
index 868143cd4f4738a3a82bf075a71fdbd5ecb61f94..1f70895ea83178b6a04ba817a836282642052220 100644 (file)
@@ -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 */
index f26b2069e5b2bc27e805b99043b2dd3271008c27..4e75e1c102ecc4ea8d57991c70a6e62935b35f9e 100644 (file)
@@ -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)