Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
[cascardo/linux.git] / sound / pci / cs5535audio / cs5535audio_pcm.c
index 5802ed9..21df063 100644 (file)
@@ -35,7 +35,7 @@
 #include <sound/ac97_codec.h>
 #include "cs5535audio.h"
 
-static snd_pcm_hardware_t snd_cs5535audio_playback =
+static struct snd_pcm_hardware snd_cs5535audio_playback =
 {
        .info =                 (
                                SNDRV_PCM_INFO_MMAP |
@@ -43,7 +43,7 @@ static snd_pcm_hardware_t snd_cs5535audio_playback =
                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
                                SNDRV_PCM_INFO_MMAP_VALID |
                                SNDRV_PCM_INFO_PAUSE |
-                               SNDRV_PCM_INFO_SYNC_START
+                               SNDRV_PCM_INFO_RESUME
                                ),
        .formats =              (
                                SNDRV_PCM_FMTBIT_S16_LE
@@ -64,14 +64,13 @@ static snd_pcm_hardware_t snd_cs5535audio_playback =
        .fifo_size =            0,
 };
 
-static snd_pcm_hardware_t snd_cs5535audio_capture =
+static struct snd_pcm_hardware snd_cs5535audio_capture =
 {
        .info =                 (
                                SNDRV_PCM_INFO_MMAP |
                                SNDRV_PCM_INFO_INTERLEAVED |
                                SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                               SNDRV_PCM_INFO_MMAP_VALID |
-                               SNDRV_PCM_INFO_SYNC_START
+                               SNDRV_PCM_INFO_MMAP_VALID
                                ),
        .formats =              (
                                SNDRV_PCM_FMTBIT_S16_LE
@@ -92,16 +91,15 @@ static snd_pcm_hardware_t snd_cs5535audio_capture =
        .fifo_size =            0,
 };
 
-static int snd_cs5535audio_playback_open(snd_pcm_substream_t *substream)
+static int snd_cs5535audio_playback_open(struct snd_pcm_substream *substream)
 {
        int err;
-       cs5535audio_t *cs5535au = snd_pcm_substream_chip(substream);
-       snd_pcm_runtime_t *runtime = substream->runtime;
+       struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+       struct snd_pcm_runtime *runtime = substream->runtime;
 
        runtime->hw = snd_cs5535audio_playback;
        cs5535au->playback_substream = substream;
        runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK]);
-       snd_pcm_set_sync(substream);
        if ((err = snd_pcm_hw_constraint_integer(runtime,
                                SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
                return err;
@@ -109,23 +107,23 @@ static int snd_cs5535audio_playback_open(snd_pcm_substream_t *substream)
        return 0;
 }
 
-static int snd_cs5535audio_playback_close(snd_pcm_substream_t *substream)
+static int snd_cs5535audio_playback_close(struct snd_pcm_substream *substream)
 {
        return 0;
 }
 
 #define CS5535AUDIO_DESC_LIST_SIZE \
-       PAGE_ALIGN(CS5535AUDIO_MAX_DESCRIPTORS * sizeof(cs5535audio_dma_desc_t))
+       PAGE_ALIGN(CS5535AUDIO_MAX_DESCRIPTORS * sizeof(struct cs5535audio_dma_desc))
 
-static int cs5535audio_build_dma_packets(cs5535audio_t *cs5535au,
-                                       cs5535audio_dma_t *dma,
-                                       snd_pcm_substream_t *substream,
-                                       unsigned int periods,
-                                       unsigned int period_bytes)
+static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
+                                        struct cs5535audio_dma *dma,
+                                        struct snd_pcm_substream *substream,
+                                        unsigned int periods,
+                                        unsigned int period_bytes)
 {
        unsigned int i;
        u32 addr, desc_addr, jmpprd_addr;
-       cs5535audio_dma_desc_t *lastdesc;
+       struct cs5535audio_dma_desc *lastdesc;
 
        if (periods > CS5535AUDIO_MAX_DESCRIPTORS)
                return -ENOMEM;
@@ -142,27 +140,28 @@ static int cs5535audio_build_dma_packets(cs5535audio_t *cs5535au,
        if (dma->periods == periods && dma->period_bytes == period_bytes)
                return 0;
 
-       /* the u32 cast is okay because in snd*create we succesfully told
+       /* the u32 cast is okay because in snd*create we successfully told
           pci alloc that we're only 32 bit capable so the uppper will be 0 */
        addr = (u32) substream->runtime->dma_addr;
        desc_addr = (u32) dma->desc_buf.addr;
        for (i = 0; i < periods; i++) {
-               cs5535audio_dma_desc_t *desc =
-                       &((cs5535audio_dma_desc_t *) dma->desc_buf.area)[i];
+               struct cs5535audio_dma_desc *desc =
+                       &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i];
                desc->addr = cpu_to_le32(addr);
-               desc->size = period_bytes;
-               desc->ctlreserved = PRD_EOP;
-               desc_addr += sizeof(cs5535audio_dma_desc_t);
+               desc->size = cpu_to_le32(period_bytes);
+               desc->ctlreserved = cpu_to_le32(PRD_EOP);
+               desc_addr += sizeof(struct cs5535audio_dma_desc);
                addr += period_bytes;
        }
        /* we reserved one dummy descriptor at the end to do the PRD jump */
-       lastdesc = &((cs5535audio_dma_desc_t *) dma->desc_buf.area)[periods];
+       lastdesc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[periods];
        lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr);
        lastdesc->size = 0;
-       lastdesc->ctlreserved = PRD_JMP;
+       lastdesc->ctlreserved = cpu_to_le32(PRD_JMP);
        jmpprd_addr = cpu_to_le32(lastdesc->addr +
-                               (sizeof(cs5535audio_dma_desc_t)*periods));
+                                 (sizeof(struct cs5535audio_dma_desc)*periods));
 
+       dma->substream = substream;
        dma->period_bytes = period_bytes;
        dma->periods = periods;
        spin_lock_irq(&cs5535au->reg_lock);
@@ -172,71 +171,82 @@ static int cs5535audio_build_dma_packets(cs5535audio_t *cs5535au,
        return 0;
 }
 
-static void cs5535audio_playback_enable_dma(cs5535audio_t *cs5535au)
+static void cs5535audio_playback_enable_dma(struct cs5535audio *cs5535au)
 {
        cs_writeb(cs5535au, ACC_BM0_CMD, BM_CTL_EN);
 }
 
-static void cs5535audio_playback_disable_dma(cs5535audio_t *cs5535au)
+static void cs5535audio_playback_disable_dma(struct cs5535audio *cs5535au)
 {
        cs_writeb(cs5535au, ACC_BM0_CMD, 0);
 }
 
-static void cs5535audio_playback_pause_dma(cs5535audio_t *cs5535au)
+static void cs5535audio_playback_pause_dma(struct cs5535audio *cs5535au)
 {
        cs_writeb(cs5535au, ACC_BM0_CMD, BM_CTL_PAUSE);
 }
 
-static void cs5535audio_playback_setup_prd(cs5535audio_t *cs5535au,
-                                               u32 prd_addr)
+static void cs5535audio_playback_setup_prd(struct cs5535audio *cs5535au,
+                                          u32 prd_addr)
 {
        cs_writel(cs5535au, ACC_BM0_PRD, prd_addr);
 }
 
-static u32 cs5535audio_playback_read_dma_pntr(cs5535audio_t *cs5535au)
+static u32 cs5535audio_playback_read_prd(struct cs5535audio *cs5535au)
+{
+       return cs_readl(cs5535au, ACC_BM0_PRD);
+}
+
+static u32 cs5535audio_playback_read_dma_pntr(struct cs5535audio *cs5535au)
 {
        return cs_readl(cs5535au, ACC_BM0_PNTR);
 }
 
-static void cs5535audio_capture_enable_dma(cs5535audio_t *cs5535au)
+static void cs5535audio_capture_enable_dma(struct cs5535audio *cs5535au)
 {
        cs_writeb(cs5535au, ACC_BM1_CMD, BM_CTL_EN);
 }
 
-static void cs5535audio_capture_disable_dma(cs5535audio_t *cs5535au)
+static void cs5535audio_capture_disable_dma(struct cs5535audio *cs5535au)
 {
        cs_writeb(cs5535au, ACC_BM1_CMD, 0);
 }
 
-static void cs5535audio_capture_pause_dma(cs5535audio_t *cs5535au)
+static void cs5535audio_capture_pause_dma(struct cs5535audio *cs5535au)
 {
        cs_writeb(cs5535au, ACC_BM1_CMD, BM_CTL_PAUSE);
 }
 
-static void cs5535audio_capture_setup_prd(cs5535audio_t *cs5535au,
-                                               u32 prd_addr)
+static void cs5535audio_capture_setup_prd(struct cs5535audio *cs5535au,
+                                         u32 prd_addr)
 {
        cs_writel(cs5535au, ACC_BM1_PRD, prd_addr);
 }
 
-static u32 cs5535audio_capture_read_dma_pntr(cs5535audio_t *cs5535au)
+static u32 cs5535audio_capture_read_prd(struct cs5535audio *cs5535au)
+{
+       return cs_readl(cs5535au, ACC_BM1_PRD);
+}
+
+static u32 cs5535audio_capture_read_dma_pntr(struct cs5535audio *cs5535au)
 {
        return cs_readl(cs5535au, ACC_BM1_PNTR);
 }
 
-static void cs5535audio_clear_dma_packets(cs5535audio_t *cs5535au,
-                                       cs5535audio_dma_t *dma,
-                                       snd_pcm_substream_t *substream)
+static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au,
+                                         struct cs5535audio_dma *dma,
+                                         struct snd_pcm_substream *substream)
 {
        snd_dma_free_pages(&dma->desc_buf);
        dma->desc_buf.area = NULL;
+       dma->substream = NULL;
 }
 
-static int snd_cs5535audio_hw_params(snd_pcm_substream_t *substream,
-                                snd_pcm_hw_params_t *hw_params)
+static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
+                                    struct snd_pcm_hw_params *hw_params)
 {
-       cs5535audio_t *cs5535au = snd_pcm_substream_chip(substream);
-       cs5535audio_dma_t *dma = substream->runtime->private_data;
+       struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+       struct cs5535audio_dma *dma = substream->runtime->private_data;
        int err;
 
        err = snd_pcm_lib_malloc_pages(substream,
@@ -247,67 +257,68 @@ static int snd_cs5535audio_hw_params(snd_pcm_substream_t *substream,
        dma->buf_bytes = params_buffer_bytes(hw_params);
 
        err = cs5535audio_build_dma_packets(cs5535au, dma, substream,
-                                      params_periods(hw_params),
-                                      params_period_bytes(hw_params));
+                                           params_periods(hw_params),
+                                           params_period_bytes(hw_params));
        return err;
 }
 
-static int snd_cs5535audio_hw_free(snd_pcm_substream_t *substream)
+static int snd_cs5535audio_hw_free(struct snd_pcm_substream *substream)
 {
-       cs5535audio_t *cs5535au = snd_pcm_substream_chip(substream);
-       cs5535audio_dma_t *dma = substream->runtime->private_data;
+       struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+       struct cs5535audio_dma *dma = substream->runtime->private_data;
 
        cs5535audio_clear_dma_packets(cs5535au, dma, substream);
        return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_cs5535audio_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_cs5535audio_playback_prepare(struct snd_pcm_substream *substream)
 {
-       cs5535audio_t *cs5535au = snd_pcm_substream_chip(substream);
+       struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
        return snd_ac97_set_rate(cs5535au->ac97, AC97_PCM_FRONT_DAC_RATE,
-                                       substream->runtime->rate);
+                                substream->runtime->rate);
 }
 
-static int snd_cs5535audio_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-       cs5535audio_t *cs5535au = snd_pcm_substream_chip(substream);
-       cs5535audio_dma_t *dma = substream->runtime->private_data;
+       struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+       struct cs5535audio_dma *dma = substream->runtime->private_data;
+       int err = 0;
 
+       spin_lock(&cs5535au->reg_lock);
        switch (cmd) {
-               case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-                       spin_lock_irq(&cs5535au->reg_lock);
-                       dma->ops->pause_dma(cs5535au);
-                       spin_unlock_irq(&cs5535au->reg_lock);
-                       break;
-               case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-                       spin_lock_irq(&cs5535au->reg_lock);
-                       dma->ops->enable_dma(cs5535au);
-                       spin_unlock_irq(&cs5535au->reg_lock);
-                       break;
-               case SNDRV_PCM_TRIGGER_START:
-                       spin_lock_irq(&cs5535au->reg_lock);
-                       dma->ops->enable_dma(cs5535au);
-                       spin_unlock_irq(&cs5535au->reg_lock);
-                       break;
-               case SNDRV_PCM_TRIGGER_STOP:
-                       spin_lock_irq(&cs5535au->reg_lock);
-                       dma->ops->disable_dma(cs5535au);
-                       spin_unlock_irq(&cs5535au->reg_lock);
-                       break;
-               default:
-                       snd_printk(KERN_ERR "unhandled trigger\n");
-                       return -EINVAL;
-                       break;
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               dma->ops->pause_dma(cs5535au);
+               break;
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               dma->ops->enable_dma(cs5535au);
+               break;
+       case SNDRV_PCM_TRIGGER_START:
+               dma->ops->enable_dma(cs5535au);
+               break;
+       case SNDRV_PCM_TRIGGER_RESUME:
+               dma->ops->enable_dma(cs5535au);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+               dma->ops->disable_dma(cs5535au);
+               break;
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+               dma->ops->disable_dma(cs5535au);
+               break;
+       default:
+               snd_printk(KERN_ERR "unhandled trigger\n");
+               err = -EINVAL;
+               break;
        }
-       return 0;
+       spin_unlock(&cs5535au->reg_lock);
+       return err;
 }
 
-static snd_pcm_uframes_t snd_cs5535audio_pcm_pointer(snd_pcm_substream_t
+static snd_pcm_uframes_t snd_cs5535audio_pcm_pointer(struct snd_pcm_substream
                                                        *substream)
 {
-       cs5535audio_t *cs5535au = snd_pcm_substream_chip(substream);
+       struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
        u32 curdma;
-       cs5535audio_dma_t *dma;
+       struct cs5535audio_dma *dma;
 
        dma = substream->runtime->private_data;
        curdma = dma->ops->read_dma_pntr(cs5535au);
@@ -325,35 +336,34 @@ static snd_pcm_uframes_t snd_cs5535audio_pcm_pointer(snd_pcm_substream_t
        return bytes_to_frames(substream->runtime, curdma);
 }
 
-static int snd_cs5535audio_capture_open(snd_pcm_substream_t *substream)
+static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
 {
        int err;
-       cs5535audio_t *cs5535au = snd_pcm_substream_chip(substream);
-       snd_pcm_runtime_t *runtime = substream->runtime;
+       struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+       struct snd_pcm_runtime *runtime = substream->runtime;
 
        runtime->hw = snd_cs5535audio_capture;
        cs5535au->capture_substream = substream;
        runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE]);
-       snd_pcm_set_sync(substream);
        if ((err = snd_pcm_hw_constraint_integer(runtime,
                                         SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
                return err;
        return 0;
 }
 
-static int snd_cs5535audio_capture_close(snd_pcm_substream_t *substream)
+static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream)
 {
        return 0;
 }
 
-static int snd_cs5535audio_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_cs5535audio_capture_prepare(struct snd_pcm_substream *substream)
 {
-       cs5535audio_t *cs5535au = snd_pcm_substream_chip(substream);
+       struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
        return snd_ac97_set_rate(cs5535au->ac97, AC97_PCM_LR_ADC_RATE,
-                                       substream->runtime->rate);
+                                substream->runtime->rate);
 }
 
-static snd_pcm_ops_t snd_cs5535audio_playback_ops = {
+static struct snd_pcm_ops snd_cs5535audio_playback_ops = {
        .open =         snd_cs5535audio_playback_open,
        .close =        snd_cs5535audio_playback_close,
        .ioctl =        snd_pcm_lib_ioctl,
@@ -364,7 +374,7 @@ static snd_pcm_ops_t snd_cs5535audio_playback_ops = {
        .pointer =      snd_cs5535audio_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_cs5535audio_capture_ops = {
+static struct snd_pcm_ops snd_cs5535audio_capture_ops = {
        .open =         snd_cs5535audio_capture_open,
        .close =        snd_cs5535audio_capture_close,
        .ioctl =        snd_pcm_lib_ioctl,
@@ -375,32 +385,29 @@ static snd_pcm_ops_t snd_cs5535audio_capture_ops = {
        .pointer =      snd_cs5535audio_pcm_pointer,
 };
 
-static void snd_cs5535audio_pcm_free(snd_pcm_t *pcm)
-{
-       snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static cs5535audio_dma_ops_t snd_cs5535audio_playback_dma_ops = {
+static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = {
         .type = CS5535AUDIO_DMA_PLAYBACK,
         .enable_dma = cs5535audio_playback_enable_dma,
         .disable_dma = cs5535audio_playback_disable_dma,
         .setup_prd = cs5535audio_playback_setup_prd,
+        .read_prd = cs5535audio_playback_read_prd,
         .pause_dma = cs5535audio_playback_pause_dma,
         .read_dma_pntr = cs5535audio_playback_read_dma_pntr,
 };
 
-static cs5535audio_dma_ops_t snd_cs5535audio_capture_dma_ops = {
+static struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = {
         .type = CS5535AUDIO_DMA_CAPTURE,
         .enable_dma = cs5535audio_capture_enable_dma,
         .disable_dma = cs5535audio_capture_disable_dma,
         .setup_prd = cs5535audio_capture_setup_prd,
+        .read_prd = cs5535audio_capture_read_prd,
         .pause_dma = cs5535audio_capture_pause_dma,
         .read_dma_pntr = cs5535audio_capture_read_dma_pntr,
 };
 
-int __devinit snd_cs5535audio_pcm(cs5535audio_t *cs5535au)
+int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535au)
 {
-       snd_pcm_t *pcm;
+       struct snd_pcm *pcm;
        int err;
 
        err = snd_pcm_new(cs5535au->card, "CS5535 Audio", 0, 1, 1, &pcm);
@@ -417,13 +424,13 @@ int __devinit snd_cs5535audio_pcm(cs5535audio_t *cs5535au)
                                        &snd_cs5535audio_capture_ops);
 
        pcm->private_data = cs5535au;
-       pcm->private_free = snd_cs5535audio_pcm_free;
        pcm->info_flags = 0;
        strcpy(pcm->name, "CS5535 Audio");
 
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                        snd_dma_pci_data(cs5535au->pci),
                                        64*1024, 128*1024);
+       cs5535au->pcm = pcm;
 
        return 0;
 }