+ writel(aacirun->cr, aacirun->base + AACI_RXCR);
+}
+
+static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
+{
+ u32 ie;
+
+ aaci_chan_wait_ready(aacirun);
+
+#ifdef DEBUG
+ /* RX Timeout value: bits 28:17 in RXCR */
+ aacirun->cr |= 0xf << 17;
+#endif
+
+ aacirun->cr |= CR_EN;
+ writel(aacirun->cr, aacirun->base + AACI_RXCR);
+
+ ie = readl(aacirun->base + AACI_IE);
+ ie |= IE_ORIE |IE_RXIE; // overrun and rx interrupt -- half full
+ writel(ie, aacirun->base + AACI_IE);
+}
+
+static int aaci_pcm_capture_trigger(snd_pcm_substream_t *substream, int cmd){
+
+ struct aaci *aaci = substream->private_data;
+ struct aaci_runtime *aacirun = substream->runtime->private_data;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&aaci->lock, flags);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ aaci_pcm_capture_start(aacirun);
+ break;
+
+ case SNDRV_PCM_TRIGGER_RESUME:
+ aaci_pcm_capture_start(aacirun);
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ aaci_pcm_capture_stop(aacirun);
+ break;
+
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ aaci_pcm_capture_stop(aacirun);
+ break;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ break;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ break;
+
+ default:
+ ret = -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&aaci->lock, flags);
+
+ return ret;
+}
+
+static int aaci_pcm_capture_prepare(snd_pcm_substream_t *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct aaci *aaci = substream->private_data;
+
+ aaci_pcm_prepare(substream);
+
+ /* allow changing of sample rate */
+ aaci_ac97_write(aaci->ac97, AC97_EXTENDED_STATUS, 0x0001); /* VRA */
+ aaci_ac97_write(aaci->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
+ aaci_ac97_write(aaci->ac97, AC97_PCM_MIC_ADC_RATE, runtime->rate);
+
+ /* Record select: Mic: 0, Aux: 3, Line: 4 */
+ aaci_ac97_write(aaci->ac97, AC97_REC_SEL, 0x0404);
+
+ return 0;
+}
+
+static snd_pcm_ops_t aaci_capture_ops = {
+ .open = aaci_pcm_open,
+ .close = aaci_pcm_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = aaci_pcm_capture_hw_params,
+ .hw_free = aaci_pcm_hw_free,
+ .prepare = aaci_pcm_capture_prepare,
+ .trigger = aaci_pcm_capture_trigger,
+ .pointer = aaci_pcm_pointer,
+ .mmap = aaci_pcm_mmap,
+};