]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - sound/pci/ice1712/ice1724.c
[ALSA] oxygen: rename PCM to Master
[linux-2.6-omap-h63xx.git] / sound / pci / ice1712 / ice1724.c
index 3e3a102e6c34286884476f394a6cb3324586a7fb..3147cbc9edb3af4b65111f81f268ef6782e25a36 100644 (file)
@@ -2,7 +2,7 @@
  *   ALSA driver for VT1724 ICEnsemble ICE1724 / VIA VT1724 (Envy24HT)
  *                   VIA VT1720 (Envy24PT)
  *
- *     Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
+ *     Copyright (c) 2000 Jaroslav Kysela <perex@perex.cz>
  *                    2002 James Stafford <jstafford@ampltd.com>
  *                    2003 Takashi Iwai <tiwai@suse.de>
  *
@@ -22,7 +22,6 @@
  *
  */      
 
-#include <sound/driver.h>
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include "prodigy192.h"
 #include "juli.h"
 #include "phase.h"
+#include "wtm.h"
+#include "se.h"
 
-
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{"
@@ -64,6 +64,8 @@ MODULE_SUPPORTED_DEVICE("{"
               PRODIGY192_DEVICE_DESC
               JULI_DEVICE_DESC
               PHASE_DEVICE_DESC
+              WTM_DEVICE_DESC
+              SE_DEVICE_DESC
                "{VIA,VT1720},"
                "{VIA,VT1724},"
                "{ICEnsemble,Generic ICE1724},"
@@ -86,7 +88,7 @@ MODULE_PARM_DESC(model, "Use the given board model.");
 
 
 /* Both VT1720 and VT1724 have the same PCI IDs */
-static struct pci_device_id snd_vt1724_ids[] = {
+static const struct pci_device_id snd_vt1724_ids[] = {
        { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
        { 0, }
 };
@@ -336,16 +338,16 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
        unsigned char what;
        unsigned char old;
-       struct list_head *pos;
        struct snd_pcm_substream *s;
 
        what = 0;
-       snd_pcm_group_for_each(pos, substream) {
-               struct vt1724_pcm_reg *reg;
-               s = snd_pcm_group_substream_entry(pos);
-               reg = s->runtime->private_data;
-               what |= reg->start;
-               snd_pcm_trigger_done(s, substream);
+       snd_pcm_group_for_each_entry(s, substream) {
+               if (snd_pcm_substream_chip(s) == ice) {
+                       const struct vt1724_pcm_reg *reg;
+                       reg = s->runtime->private_data;
+                       what |= reg->start;
+                       snd_pcm_trigger_done(s, substream);
+               }
        }
 
        switch (cmd) {
@@ -605,7 +607,7 @@ static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substrea
 static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream)
 {
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-       struct vt1724_pcm_reg *reg = substream->runtime->private_data;
+       const struct vt1724_pcm_reg *reg = substream->runtime->private_data;
 
        spin_lock_irq(&ice->reg_lock);
        outl(substream->runtime->dma_addr, ice->profi_port + reg->addr);
@@ -620,7 +622,7 @@ static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream)
 static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substream)
 {
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-       struct vt1724_pcm_reg *reg = substream->runtime->private_data;
+       const struct vt1724_pcm_reg *reg = substream->runtime->private_data;
        size_t ptr;
 
        if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start))
@@ -646,21 +648,21 @@ static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substr
 #endif
 }
 
-static struct vt1724_pcm_reg vt1724_playback_pro_reg = {
+static const struct vt1724_pcm_reg vt1724_playback_pro_reg = {
        .addr = VT1724_MT_PLAYBACK_ADDR,
        .size = VT1724_MT_PLAYBACK_SIZE,
        .count = VT1724_MT_PLAYBACK_COUNT,
        .start = VT1724_PDMA0_START,
 };
 
-static struct vt1724_pcm_reg vt1724_capture_pro_reg = {
+static const struct vt1724_pcm_reg vt1724_capture_pro_reg = {
        .addr = VT1724_MT_CAPTURE_ADDR,
        .size = VT1724_MT_CAPTURE_SIZE,
        .count = VT1724_MT_CAPTURE_COUNT,
        .start = VT1724_RDMA0_START,
 };
 
-static struct snd_pcm_hardware snd_vt1724_playback_pro =
+static const struct snd_pcm_hardware snd_vt1724_playback_pro =
 {
        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
                                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -679,7 +681,7 @@ static struct snd_pcm_hardware snd_vt1724_playback_pro =
        .periods_max =          1024,
 };
 
-static struct snd_pcm_hardware snd_vt1724_spdif =
+static const struct snd_pcm_hardware snd_vt1724_spdif =
 {
        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
                                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -701,7 +703,7 @@ static struct snd_pcm_hardware snd_vt1724_spdif =
        .periods_max =          1024,
 };
 
-static struct snd_pcm_hardware snd_vt1724_2ch_stereo =
+static const struct snd_pcm_hardware snd_vt1724_2ch_stereo =
 {
        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
                                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -773,7 +775,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
        int chs;
 
-       runtime->private_data = &vt1724_playback_pro_reg;
+       runtime->private_data = (void *)&vt1724_playback_pro_reg;
        ice->playback_pro_substream = substream;
        runtime->hw = snd_vt1724_playback_pro;
        snd_pcm_set_sync(substream);
@@ -802,7 +804,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
 
-       runtime->private_data = &vt1724_capture_pro_reg;
+       runtime->private_data = (void *)&vt1724_capture_pro_reg;
        ice->capture_pro_substream = substream;
        runtime->hw = snd_vt1724_2ch_stereo;
        snd_pcm_set_sync(substream);
@@ -888,14 +890,14 @@ static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 * ice, int device)
  * SPDIF PCM
  */
 
-static struct vt1724_pcm_reg vt1724_playback_spdif_reg = {
+static const struct vt1724_pcm_reg vt1724_playback_spdif_reg = {
        .addr = VT1724_MT_PDMA4_ADDR,
        .size = VT1724_MT_PDMA4_SIZE,
        .count = VT1724_MT_PDMA4_COUNT,
        .start = VT1724_PDMA4_START,
 };
 
-static struct vt1724_pcm_reg vt1724_capture_spdif_reg = {
+static const struct vt1724_pcm_reg vt1724_capture_spdif_reg = {
        .addr = VT1724_MT_RDMA1_ADDR,
        .size = VT1724_MT_RDMA1_SIZE,
        .count = VT1724_MT_RDMA1_COUNT,
@@ -953,7 +955,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
 
-       runtime->private_data = &vt1724_playback_spdif_reg;
+       runtime->private_data = (void *)&vt1724_playback_spdif_reg;
        ice->playback_con_substream = substream;
        if (ice->force_pdma4) {
                runtime->hw = snd_vt1724_2ch_stereo;
@@ -985,7 +987,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
 
-       runtime->private_data = &vt1724_capture_spdif_reg;
+       runtime->private_data = (void *)&vt1724_capture_spdif_reg;
        ice->capture_con_substream = substream;
        if (ice->force_rdma1) {
                runtime->hw = snd_vt1724_2ch_stereo;
@@ -1090,7 +1092,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device)
  * independent surround PCMs
  */
 
-static struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = {
+static const struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = {
        {
                .addr = VT1724_MT_PDMA1_ADDR,
                .size = VT1724_MT_PDMA1_SIZE,
@@ -1136,7 +1138,7 @@ static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream)
                return -EBUSY; /* FIXME: should handle blocking mode properly */
        }
        mutex_unlock(&ice->open_mutex);
-       runtime->private_data = &vt1724_playback_dma_regs[substream->number];
+       runtime->private_data = (void *)&vt1724_playback_dma_regs[substream->number];
        ice->playback_con_substream_ds[substream->number] = substream;
        runtime->hw = snd_vt1724_2ch_stereo;
        snd_pcm_set_sync(substream);
@@ -1480,15 +1482,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
        .get =          snd_vt1724_spdif_maskp_get,
 };
 
-static int snd_vt1724_spdif_sw_info(struct snd_kcontrol *kcontrol,
-                                   struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 1;
-       return 0;
-}
+#define snd_vt1724_spdif_sw_info               snd_ctl_boolean_mono_info
 
 static int snd_vt1724_spdif_sw_get(struct snd_kcontrol *kcontrol,
                                   struct snd_ctl_elem_value *ucontrol)
@@ -1533,15 +1527,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
  * GPIO access from extern
  */
 
-int snd_vt1724_gpio_info(struct snd_kcontrol *kcontrol,
-                        struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 1;
-       return 0;
-}
+#define snd_vt1724_gpio_info           snd_ctl_boolean_mono_info
 
 int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol,
                        struct snd_ctl_elem_value *ucontrol)
@@ -1584,7 +1570,7 @@ int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol,
 static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
                                              struct snd_ctl_elem_info *uinfo)
 {
-       static char *texts_1724[] = {
+       static const char * const texts_1724[] = {
                "8000",         /* 0: 6 */
                "9600",         /* 1: 3 */
                "11025",        /* 2: 10 */
@@ -1602,7 +1588,7 @@ static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
                "192000",       /* 14: 14 */
                "IEC958 Input", /* 15: -- */
        };
-       static char *texts_1720[] = {
+       static const char * const texts_1720[] = {
                "8000",         /* 0: 6 */
                "9600",         /* 1: 3 */
                "11025",        /* 2: 10 */
@@ -1635,7 +1621,7 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
                                             struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
-       static unsigned char xlate[16] = {
+       static const unsigned char xlate[16] = {
                9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10
        };
        unsigned char val;
@@ -1667,7 +1653,12 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
        spin_lock_irq(&ice->reg_lock);
        oval = inb(ICEMT1724(ice, RATE));
        if (ucontrol->value.enumerated.item[0] == spdif) {
+               unsigned char i2s_oval;
                outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE));
+               /* setting 256fs */
+               i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT));
+               outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X,
+                    ICEMT1724(ice, I2S_FORMAT));
        } else {
                rate = rates[ucontrol->value.integer.value[0] % 15];
                if (rate <= get_max_rate(ice)) {
@@ -1702,15 +1693,7 @@ static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
        .put = snd_vt1724_pro_internal_clock_put
 };
 
-static int snd_vt1724_pro_rate_locking_info(struct snd_kcontrol *kcontrol,
-                                           struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 1;
-       return 0;
-}
+#define snd_vt1724_pro_rate_locking_info       snd_ctl_boolean_mono_info
 
 static int snd_vt1724_pro_rate_locking_get(struct snd_kcontrol *kcontrol,
                                           struct snd_ctl_elem_value *ucontrol)
@@ -1741,15 +1724,7 @@ static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
        .put = snd_vt1724_pro_rate_locking_put
 };
 
-static int snd_vt1724_pro_rate_reset_info(struct snd_kcontrol *kcontrol,
-                                         struct snd_ctl_elem_info *uinfo)
-{
-       uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-       uinfo->count = 1;
-       uinfo->value.integer.min = 0;
-       uinfo->value.integer.max = 1;
-       return 0;
-}
+#define snd_vt1724_pro_rate_reset_info         snd_ctl_boolean_mono_info
 
 static int snd_vt1724_pro_rate_reset_get(struct snd_kcontrol *kcontrol,
                                         struct snd_ctl_elem_value *ucontrol)
@@ -1816,7 +1791,7 @@ static int get_route_val(struct snd_ice1712 *ice, int shift)
 {
        unsigned long val;
        unsigned char eitem;
-       static unsigned char xlate[8] = {
+       static const unsigned char xlate[8] = {
                0, 255, 1, 2, 255, 255, 3, 4,
        };
 
@@ -1835,7 +1810,7 @@ static int put_route_val(struct snd_ice1712 *ice, unsigned int val, int shift)
 {
        unsigned int old_val, nval;
        int change;
-       static unsigned char xroute[8] = {
+       static const unsigned char xroute[8] = {
                0, /* PCM */
                2, /* PSDIN0 Left */
                3, /* PSDIN0 Right */
@@ -1958,6 +1933,8 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
        snd_vt1724_prodigy192_cards,
        snd_vt1724_juli_cards,
        snd_vt1724_phase_cards,
+       snd_vt1724_wtm_cards,
+       snd_vt1724_se_cards,
        NULL,
 };
 
@@ -1980,6 +1957,7 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,
        unsigned char val;
 
        mutex_lock(&ice->i2c_mutex);
+       wait_i2c_busy(ice);
        outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
        outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
        wait_i2c_busy(ice);
@@ -2007,7 +1985,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
 {
        const int dev = 0xa0;           /* EEPROM device address */
        unsigned int i, size;
-       struct snd_ice1712_card_info **tbl, *c;
+       struct snd_ice1712_card_info * const *tbl, *c;
 
        if (! modelname || ! *modelname) {
                ice->eeprom.subvendor = 0;
@@ -2306,7 +2284,7 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
        struct snd_card *card;
        struct snd_ice1712 *ice;
        int pcm_dev = 0, err;
-       struct snd_ice1712_card_info **tbl, *c;
+       struct snd_ice1712_card_info * const *tbl, *c;
 
        if (dev >= SNDRV_CARDS)
                return -ENODEV;
@@ -2345,6 +2323,14 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
        }
        c = &no_matched;
  __found:
+       /*
+        * VT1724 has separate DMAs for the analog and the SPDIF streams while
+        * ICE1712 has only one for both (mixed up).
+        *
+        * Confusingly the analog PCM is named "professional" here because it
+        * was called so in ice1712 driver, and vt1724 driver is derived from
+        * ice1712 driver.
+        */
 
        if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) {
                snd_card_free(card);