Update of /cvsroot/alsa/alsa-kernel/pci/ice1712
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9698/pci/ice1712

Modified Files:
        ice1712.c ice1712.h ice1724.c 
Log Message:
- added the support of independent surround PCM for ice1724.


Index: ice1712.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ice1712.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- ice1712.c   21 Jan 2004 18:32:47 -0000      1.40
+++ ice1712.c   10 Feb 2004 15:35:03 -0000      1.41
@@ -2375,6 +2375,7 @@
        ice->omni = omni ? 1 : 0;
        spin_lock_init(&ice->reg_lock);
        init_MUTEX(&ice->gpio_mutex);
+       init_MUTEX(&ice->open_mutex);
        ice->gpio.set_mask = snd_ice1712_set_gpio_mask;
        ice->gpio.set_dir = snd_ice1712_set_gpio_dir;
        ice->gpio.set_data = snd_ice1712_set_gpio_data;

Index: ice1712.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ice1712.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- ice1712.h   29 Dec 2003 15:41:45 -0000      1.15
+++ ice1712.h   10 Feb 2004 15:35:03 -0000      1.16
@@ -335,6 +335,9 @@
        unsigned short hoontech_boxconfig[4];
        unsigned int cur_rate;          /* current rate */
 
+       struct semaphore open_mutex;
+       snd_pcm_substream_t *pcm_reserved[4];
+
        unsigned int akm_codecs;
        akm4xxx_t *akm;
        struct snd_ice1712_spdif spdif;

Index: ice1724.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/ice1712/ice1724.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- ice1724.c   2 Feb 2004 13:47:55 -0000       1.24
+++ ice1724.c   10 Feb 2004 15:35:03 -0000      1.25
@@ -237,6 +237,18 @@
                                if (ice->capture_pro_substream)
                                        
snd_pcm_period_elapsed(ice->capture_pro_substream);
                        }
+                       if (mtstat & VT1724_MULTI_PDMA1) {
+                               if (ice->playback_con_substream_ds[0])
+                                       
snd_pcm_period_elapsed(ice->playback_con_substream_ds[0]);
+                       }
+                       if (mtstat & VT1724_MULTI_PDMA2) {
+                               if (ice->playback_con_substream_ds[1])
+                                       
snd_pcm_period_elapsed(ice->playback_con_substream_ds[1]);
+                       }
+                       if (mtstat & VT1724_MULTI_PDMA3) {
+                               if (ice->playback_con_substream_ds[2])
+                                       
snd_pcm_period_elapsed(ice->playback_con_substream_ds[2]);
+                       }
                        if (mtstat & VT1724_MULTI_PDMA4) {
                                if (ice->playback_con_substream)
                                        
snd_pcm_period_elapsed(ice->playback_con_substream);
@@ -282,16 +294,6 @@
        .mask = 0,
 };
 
-static unsigned int hw_channels[] = {
-       2, 4, 6, 8
-};
-
-static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
-       .count = ARRAY_SIZE(hw_channels),
-       .list = hw_channels,
-       .mask = 0,
-};
-
 static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
 {
        ice1712_t *ice = snd_pcm_substream_chip(substream);
@@ -300,21 +302,16 @@
        struct list_head *pos;
        snd_pcm_substream_t *s;
 
+       what = 0;
+       snd_pcm_group_for_each(pos, substream) {
+               s = snd_pcm_group_substream_entry(pos);
+               what |= (unsigned long)(s->runtime->private_data);
+               snd_pcm_trigger_done(s, substream);
+       }
+
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               what = 0;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
-                       if (s == ice->playback_pro_substream)
-                               what |= VT1724_PDMA0_PAUSE;
-                       else if (s == ice->capture_pro_substream)
-                               what |= VT1724_RDMA0_PAUSE;
-                       else if (s == ice->playback_con_substream)
-                               what |= VT1724_PDMA4_PAUSE;
-                       else if (s == ice->capture_con_substream)
-                               what |= VT1724_RDMA1_PAUSE;
-               }
                spin_lock(&ice->reg_lock);
                old = inb(ICEMT1724(ice, DMA_PAUSE));
                if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
@@ -327,24 +324,6 @@
 
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_STOP:
-               what = 0;
-               s = substream;
-               snd_pcm_group_for_each(pos, substream) {
-                       s = snd_pcm_group_substream_entry(pos);
-                       if (s == ice->playback_pro_substream) {
-                               what |= VT1724_PDMA0_START;
-                               snd_pcm_trigger_done(s, substream);
-                       } else if (s == ice->capture_pro_substream) {
-                               what |= VT1724_RDMA0_START;
-                               snd_pcm_trigger_done(s, substream);
-                       } else if (s == ice->playback_con_substream) {
-                               what |= VT1724_PDMA4_START;
-                               snd_pcm_trigger_done(s, substream);
-                       } else if (s == ice->capture_con_substream) {
-                               what |= VT1724_RDMA1_START;
-                               snd_pcm_trigger_done(s, substream);
-                       }
-               }
                spin_lock(&ice->reg_lock);
                old = inb(ICEMT1724(ice, DMA_CONTROL));
                if (cmd == SNDRV_PCM_TRIGGER_START)
@@ -364,8 +343,10 @@
 /*
  */
 
-#define DMA_STARTS     
(VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|VT1724_PDMA4_START)
-#define DMA_PAUSES     
(VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|VT1724_PDMA4_PAUSE)
+#define DMA_STARTS     (VT1724_RDMA0_START|VT1724_PDMA0_START|VT1724_RDMA1_START|\
+       VT1724_PDMA1_START|VT1724_PDMA2_START|VT1724_PDMA3_START|VT1724_PDMA4_START)
+#define DMA_PAUSES     (VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|\
+       VT1724_PDMA1_PAUSE|VT1724_PDMA2_PAUSE|VT1724_PDMA3_PAUSE|VT1724_PDMA4_PAUSE)
 
 static void snd_vt1724_set_pro_rate(ice1712_t *ice, unsigned int rate, int force)
 {
@@ -448,13 +429,52 @@
                                    snd_pcm_hw_params_t * hw_params)
 {
        ice1712_t *ice = snd_pcm_substream_chip(substream);
+       int i, chs;
 
+       chs = params_channels(hw_params);
+       down(&ice->open_mutex);
+       /* mark surround channels */
+       if (substream == ice->playback_pro_substream) {
+               chs = chs / 2 - 1;
+               for (i = 0; i < chs; i++) {
+                       if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) 
{
+                               up(&ice->open_mutex);
+                               return -EBUSY;
+                       }
+                       ice->pcm_reserved[i] = substream;
+               }
+               for (; i < 3; i++) {
+                       if (ice->pcm_reserved[i] == substream)
+                               ice->pcm_reserved[i] = NULL;
+               }
+       } else {
+               for (i = 0; i < 3; i++) {
+                       if (ice->playback_con_substream_ds[i] == substream) {
+                               if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != 
substream) {
+                                       up(&ice->open_mutex);
+                                       return -EBUSY;
+                               }
+                               ice->pcm_reserved[i] = substream;
+                               break;
+                       }
+               }
+       }
+       up(&ice->open_mutex);
        snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0);
        return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
 static int snd_vt1724_pcm_hw_free(snd_pcm_substream_t * substream)
 {
+       ice1712_t *ice = snd_pcm_substream_chip(substream);
+       int i;
+
+       down(&ice->open_mutex);
+       /* unmark surround channels */
+       for (i = 0; i < 3; i++)
+               if (ice->pcm_reserved[i] == substream)
+                       ice->pcm_reserved[i] = NULL;
+       up(&ice->open_mutex);
        return snd_pcm_lib_free_pages(substream);
 }
 
@@ -593,14 +613,14 @@
        .rate_max =             192000,
        .channels_min =         2,
        .channels_max =         8,
-       .buffer_bytes_max =     (1UL << 21),    /* 18bits dword */
+       .buffer_bytes_max =     (1UL << 21),    /* 19bits dword */
        .period_bytes_min =     8 * 4 * 2,      /* FIXME: constraints needed */
        .period_bytes_max =     (1UL << 21),
-       .periods_min =          1,
+       .periods_min =          2,
        .periods_max =          1024,
 };
 
-static snd_pcm_hardware_t snd_vt1724_capture_pro =
+static snd_pcm_hardware_t snd_vt1724_2ch_stereo =
 {
        .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
                                 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -612,10 +632,10 @@
        .rate_max =             192000,
        .channels_min =         2,
        .channels_max =         2,
-       .buffer_bytes_max =     (256*1024),
+       .buffer_bytes_max =     (1UL << 18),    /* 16bits dword */
        .period_bytes_min =     2 * 4 * 2,
-       .period_bytes_max =     (256*1024),
-       .periods_min =          1,
+       .period_bytes_max =     (1UL << 18),
+       .periods_min =          2,
        .periods_max =          1024,
 };
 
@@ -628,7 +648,9 @@
 {
        snd_pcm_runtime_t *runtime = substream->runtime;
        ice1712_t *ice = snd_pcm_substream_chip(substream);
+       int chs;
 
+       runtime->private_data = (void*)VT1724_PDMA0_START; /* irq/status/trigger bit */
        ice->playback_pro_substream = substream;
        runtime->hw = snd_vt1724_playback_pro;
        snd_pcm_set_sync(substream);
@@ -639,7 +661,17 @@
        else
                snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 
&hw_constraints_rates_96);
 
-       snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 
&hw_constraints_channels);
+       down(&ice->open_mutex);
+       /* calculate the currently available channels */
+       for (chs = 0; chs < 3; chs++) {
+               if (ice->pcm_reserved[chs])
+                       break;
+       }
+       chs = (chs + 1) * 2;
+       runtime->hw.channels_max = chs;
+       if (chs > 2) /* channels must be even */
+               snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2);
+       up(&ice->open_mutex);
        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
                                   VT1724_BUFFER_ALIGN);
        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
@@ -652,8 +684,9 @@
        ice1712_t *ice = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
+       runtime->private_data = (void*)VT1724_RDMA0_START; /* irq/status/trigger bit */
        ice->capture_pro_substream = substream;
-       runtime->hw = snd_vt1724_capture_pro;
+       runtime->hw = snd_vt1724_2ch_stereo;
        snd_pcm_set_sync(substream);
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
        if ((ice->eeprom.data[ICE_EEP2_ACLINK] & 0x80) &&
@@ -735,25 +768,6 @@
  * SPDIF PCM
  */
 
-static snd_pcm_hardware_t snd_vt1724_playback_spdif =
-{
-       .info =                 (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                SNDRV_PCM_INFO_MMAP_VALID |
-                                SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_SYNC_START),
-       .formats =              SNDRV_PCM_FMTBIT_S32_LE,
-       .rates =                SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_192000,
-       .rate_min =             4000,
-       .rate_max =             192000,
-       .channels_min =         2,
-       .channels_max =         2,
-       .buffer_bytes_max =     (256*1024),
-       .period_bytes_min =     2 * 4 * 2,
-       .period_bytes_max =     (256*1024),
-       .periods_min =          1,
-       .periods_max =          1024,
-};
-
 const static struct vt1724_pcm_reg vt1724_playback_spdif_reg = {
        .addr = VT1724_MT_PDMA4_ADDR,
        .size = VT1724_MT_PDMA4_SIZE,
@@ -795,8 +809,9 @@
        ice1712_t *ice = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
+       runtime->private_data = (void*)VT1724_PDMA4_START; /* irq/status/trigger bit */
        ice->playback_con_substream = substream;
-       runtime->hw = snd_vt1724_playback_spdif;
+       runtime->hw = snd_vt1724_2ch_stereo;
        snd_pcm_set_sync(substream);
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
 
@@ -820,8 +835,9 @@
        ice1712_t *ice = snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
+       runtime->private_data = (void*)VT1724_RDMA1_START; /* irq/status/trigger bit */
        ice->capture_con_substream = substream;
-       runtime->hw = snd_vt1724_playback_spdif;
+       runtime->hw = snd_vt1724_2ch_stereo;
        snd_pcm_set_sync(substream);
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 
&hw_constraints_rates_96);
@@ -903,6 +919,127 @@
 
 
 /*
+ * independent surround PCMs
+ */
+
+const static struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = {
+       {
+               .addr = VT1724_MT_PDMA1_ADDR,
+               .size = VT1724_MT_PDMA1_SIZE,
+               .count = VT1724_MT_PDMA1_COUNT,
+               .start = VT1724_PDMA1_START,
+               .pause = VT1724_PDMA1_PAUSE,
+       },
+       {
+               .addr = VT1724_MT_PDMA2_ADDR,
+               .size = VT1724_MT_PDMA2_SIZE,
+               .count = VT1724_MT_PDMA2_COUNT,
+               .start = VT1724_PDMA2_START,
+               .pause = VT1724_PDMA2_PAUSE,
+       },
+       {
+               .addr = VT1724_MT_PDMA3_ADDR,
+               .size = VT1724_MT_PDMA3_SIZE,
+               .count = VT1724_MT_PDMA3_COUNT,
+               .start = VT1724_PDMA3_START,
+               .pause = VT1724_PDMA3_PAUSE,
+       },
+};
+
+static int snd_vt1724_playback_indep_prepare(snd_pcm_substream_t * substream)
+{
+       ice1712_t *ice = snd_pcm_substream_chip(substream);
+       unsigned char val;
+
+       spin_lock(&ice->reg_lock);
+       val = 3 - substream->number;
+       if (inb(ICEMT1724(ice, BURST)) < val)
+               outb(val, ICEMT1724(ice, BURST));
+       spin_unlock(&ice->reg_lock);
+       return snd_vt1724_pcm_prepare(substream, 
&vt1724_playback_dma_regs[substream->number]);
+}
+
+static snd_pcm_uframes_t snd_vt1724_playback_indep_pointer(snd_pcm_substream_t * 
substream)
+{
+       return snd_vt1724_pcm_pointer(substream, 
&vt1724_playback_dma_regs[substream->number]);
+}
+
+static int snd_vt1724_playback_indep_open(snd_pcm_substream_t *substream)
+{
+       ice1712_t *ice = snd_pcm_substream_chip(substream);
+       snd_pcm_runtime_t *runtime = substream->runtime;
+
+       down(&ice->open_mutex);
+       /* already used by PDMA0? */
+       if (ice->pcm_reserved[substream->number]) {
+               up(&ice->open_mutex);
+               return -EBUSY; /* FIXME: should handle blocking mode properly */
+       }
+       up(&ice->open_mutex);
+       runtime->private_data = (void*)(1 << (substream->number + 4));
+       ice->playback_con_substream_ds[substream->number] = substream;
+       runtime->hw = snd_vt1724_2ch_stereo;
+       snd_pcm_set_sync(substream);
+       snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+
+       snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 
&hw_constraints_rates_192);
+       return 0;
+}
+
+static int snd_vt1724_playback_indep_close(snd_pcm_substream_t * substream)
+{
+       ice1712_t *ice = snd_pcm_substream_chip(substream);
+
+       if (PRO_RATE_RESET)
+               snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
+       ice->playback_con_substream_ds[substream->number] = NULL;
+       ice->pcm_reserved[substream->number] = NULL;
+
+       return 0;
+}
+
+static snd_pcm_ops_t snd_vt1724_playback_indep_ops = {
+       .open =         snd_vt1724_playback_indep_open,
+       .close =        snd_vt1724_playback_indep_close,
+       .ioctl =        snd_pcm_lib_ioctl,
+       .hw_params =    snd_vt1724_pcm_hw_params,
+       .hw_free =      snd_vt1724_pcm_hw_free,
+       .prepare =      snd_vt1724_playback_indep_prepare,
+       .trigger =      snd_vt1724_pcm_trigger,
+       .pointer =      snd_vt1724_playback_indep_pointer,
+};
+
+
+static int __devinit snd_vt1724_pcm_indep(ice1712_t * ice, int device)
+{
+       snd_pcm_t *pcm;
+       int play;
+       int err;
+
+       play = ice->num_total_dacs / 2 - 1;
+       if (play <= 0)
+               return 0;
+
+       err = snd_pcm_new(ice->card, "ICE1724 Surrounds", device, play, 0, &pcm);
+       if (err < 0)
+               return err;
+
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+                       &snd_vt1724_playback_indep_ops);
+
+       pcm->private_data = ice;
+       pcm->info_flags = 0;
+       strcpy(pcm->name, "ICE1724 Surround PCM");
+
+       snd_pcm_lib_preallocate_pci_pages_for_all(ice->pci, pcm, 64*1024, 64*1024);
+
+       ice->pcm_ds = pcm;
+
+       return 0;
+}
+
+
+/*
  *  Mixer section
  */
 
@@ -1808,6 +1945,7 @@
        ice->vt1724 = 1;
        spin_lock_init(&ice->reg_lock);
        init_MUTEX(&ice->gpio_mutex);
+       init_MUTEX(&ice->open_mutex);
        ice->gpio.set_mask = snd_vt1724_set_gpio_mask;
        ice->gpio.set_dir = snd_vt1724_set_gpio_dir;
        ice->gpio.set_data = snd_vt1724_set_gpio_data;
@@ -1932,6 +2070,11 @@
                return err;
        }
        
+       if ((err = snd_vt1724_pcm_indep(ice, pcm_dev++)) < 0) {
+               snd_card_free(card);
+               return err;
+       }
+
        if ((err = snd_vt1724_ac97_mixer(ice)) < 0) {
                snd_card_free(card);
                return err;



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to