Exemple #1
0
static irqreturn_t
snd_ad1889_interrupt(int irq, void *dev_id)
{
	unsigned long st;
	struct snd_ad1889 *chip = dev_id;

	st = ad1889_readl(chip, AD_DMA_DISR);

	/* clear ISR */
	ad1889_writel(chip, AD_DMA_DISR, st);

	st &= AD_INTR_MASK;

	if (unlikely(!st))
		return IRQ_NONE;

	if (st & (AD_DMA_DISR_PMAI|AD_DMA_DISR_PTAI))
		ad1889_debug("Unexpected master or target abort interrupt!\n");

	if ((st & AD_DMA_DISR_WAVI) && chip->psubs)
		snd_pcm_period_elapsed(chip->psubs);
	if ((st & AD_DMA_DISR_ADCI) && chip->csubs)
		snd_pcm_period_elapsed(chip->csubs);

	return IRQ_HANDLED;
}
Exemple #2
0
static int
snd_ad1889_free(struct snd_ad1889 *chip)
{
	if (chip->irq < 0)
		goto skip_hw;

	spin_lock_irq(&chip->lock);

	ad1889_mute(chip);

	/* Turn off interrupt on count and zero DMA registers */
	ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC);

	/* clear DISR. If we don't, we'd better jump off the Eiffel Tower */
	ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI);
	ad1889_readl(chip, AD_DMA_DISR);	/* flush, dammit! */

	spin_unlock_irq(&chip->lock);

	synchronize_irq(chip->irq);
	
	if (chip->irq >= 0)
		free_irq(chip->irq, chip);

skip_hw:
	if (chip->iobase)
		iounmap(chip->iobase);

	pci_release_regions(chip->pci);
	pci_disable_device(chip->pci);

	kfree(chip);
	return 0;
}
static int
snd_ad1889_free(struct snd_ad1889 *chip)
{
	if (chip->irq < 0)
		goto skip_hw;

	spin_lock_irq(&chip->lock);

	ad1889_mute(chip);

	
	ad1889_channel_reset(chip, AD_CHAN_WAV | AD_CHAN_ADC);

	
	ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PTAI | AD_DMA_DISR_PMAI);
	ad1889_readl(chip, AD_DMA_DISR);	

	spin_unlock_irq(&chip->lock);

	if (chip->irq >= 0)
		free_irq(chip->irq, chip);

skip_hw:
	if (chip->iobase)
		iounmap(chip->iobase);

	pci_release_regions(chip->pci);
	pci_disable_device(chip->pci);

	kfree(chip);
	return 0;
}
Exemple #4
0
/* this is called in atomic context with IRQ disabled.
   Must be as fast as possible and not sleep.
   DMA should be *triggered* by this call.
   The RAMC "ADEN" bit triggers DMA ADC On/Off */
static int
snd_ad1889_capture_trigger(struct snd_pcm_substream *ss, int cmd)
{
	u16 ramc;
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);

	ramc = ad1889_readw(chip, AD_DS_RAMC);
	
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		/* enable DMA loop & interrupts */
		ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT);
		ramc |= AD_DS_RAMC_ADEN;
		/* 1 to clear CHSS bit */
		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		ramc &= ~AD_DS_RAMC_ADEN;
		break;
	default:
		return -EINVAL;
	}
	
	chip->ramc.reg = ramc;
	ad1889_writew(chip, AD_DS_RAMC, ramc);	
	ad1889_readw(chip, AD_DS_RAMC);	/* flush */
	
	/* reset the chip when STOP - will disable IRQs */
	if (cmd == SNDRV_PCM_TRIGGER_STOP)
		ad1889_channel_reset(chip, AD_CHAN_ADC);
		
	return 0;
}
static int
snd_ad1889_capture_trigger(struct snd_pcm_substream *ss, int cmd)
{
	u16 ramc;
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);

	ramc = ad1889_readw(chip, AD_DS_RAMC);
	
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		
		ad1889_writew(chip, AD_DMA_ADC, AD_DMA_LOOP | AD_DMA_IM_CNT);
		ramc |= AD_DS_RAMC_ADEN;
		
		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_ADCS);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		ramc &= ~AD_DS_RAMC_ADEN;
		break;
	default:
		return -EINVAL;
	}
	
	chip->ramc.reg = ramc;
	ad1889_writew(chip, AD_DS_RAMC, ramc);	
	ad1889_readw(chip, AD_DS_RAMC);	
	
	
	if (cmd == SNDRV_PCM_TRIGGER_STOP)
		ad1889_channel_reset(chip, AD_CHAN_ADC);
		
	return 0;
}
Exemple #6
0
static int __devinit
snd_ad1889_init(struct snd_ad1889 *chip) 
{
	ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */
	ad1889_readw(chip, AD_DS_CCS);	/* flush posted write */

	mdelay(10);

	/* enable Master and Target abort interrupts */
	ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE);

	return 0;
}
static int __devinit
snd_ad1889_init(struct snd_ad1889 *chip) 
{
	ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); 
	ad1889_readw(chip, AD_DS_CCS);	

	mdelay(10);

	
	ad1889_writel(chip, AD_DMA_DISR, AD_DMA_DISR_PMAE | AD_DMA_DISR_PTAE);

	return 0;
}
Exemple #8
0
/* this is called in atomic context with IRQ disabled.
   Must be as fast as possible and not sleep.
   DMA should be *triggered* by this call.
   The WSMC "WAEN" bit triggers DMA Wave On/Off */
static int
snd_ad1889_playback_trigger(struct snd_pcm_substream *ss, int cmd)
{
	u16 wsmc;
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
	
	wsmc = ad1889_readw(chip, AD_DS_WSMC);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		/* enable DMA loop & interrupts */
		ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT);
		wsmc |= AD_DS_WSMC_WAEN;
		/* 1 to clear CHSS bit */
		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS);
		ad1889_unmute(chip);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		ad1889_mute(chip);
		wsmc &= ~AD_DS_WSMC_WAEN;
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}
	
	chip->wave.reg = wsmc;
	ad1889_writew(chip, AD_DS_WSMC, wsmc);	
	ad1889_readw(chip, AD_DS_WSMC);	/* flush */

	/* reset the chip when STOP - will disable IRQs */
	if (cmd == SNDRV_PCM_TRIGGER_STOP)
		ad1889_channel_reset(chip, AD_CHAN_WAV);

	return 0;
}
static int
snd_ad1889_playback_trigger(struct snd_pcm_substream *ss, int cmd)
{
	u16 wsmc;
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
	
	wsmc = ad1889_readw(chip, AD_DS_WSMC);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		
		ad1889_writew(chip, AD_DMA_WAV, AD_DMA_LOOP | AD_DMA_IM_CNT);
		wsmc |= AD_DS_WSMC_WAEN;
		
		ad1889_writel(chip, AD_DMA_CHSS, AD_DMA_CHSS_WAVS);
		ad1889_unmute(chip);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		ad1889_mute(chip);
		wsmc &= ~AD_DS_WSMC_WAEN;
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}
	
	chip->wave.reg = wsmc;
	ad1889_writew(chip, AD_DS_WSMC, wsmc);	
	ad1889_readw(chip, AD_DS_WSMC);	

	
	if (cmd == SNDRV_PCM_TRIGGER_STOP)
		ad1889_channel_reset(chip, AD_CHAN_WAV);

	return 0;
}
Exemple #10
0
static inline void
ad1889_load_wave_interrupt_count(struct snd_ad1889 *chip, u32 count)
{
	ad1889_writel(chip, AD_DMA_WAVIB, count);
	ad1889_writel(chip, AD_DMA_WAVIC, count);
}
Exemple #11
0
static inline void
ad1889_load_wave_buffer_count(struct snd_ad1889 *chip, u32 count)
{
	ad1889_writel(chip, AD_DMA_WAVBC, count);
	ad1889_writel(chip, AD_DMA_WAVCC, count);
}
Exemple #12
0
static inline void
ad1889_load_wave_buffer_address(struct snd_ad1889 *chip, u32 address)
{
	ad1889_writel(chip, AD_DMA_WAVBA, address);
	ad1889_writel(chip, AD_DMA_WAVCA, address);
}
Exemple #13
0
static inline void
ad1889_load_adc_buffer_count(struct snd_ad1889 *chip, u32 count)
{
	ad1889_writel(chip, AD_DMA_ADCBC, count);
	ad1889_writel(chip, AD_DMA_ADCCC, count);
}
Exemple #14
0
static inline void
ad1889_load_adc_buffer_address(struct snd_ad1889 *chip, u32 address)
{
	ad1889_writel(chip, AD_DMA_ADCBA, address);
	ad1889_writel(chip, AD_DMA_ADCCA, address);
}