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;
}
示例#2
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;
}
示例#3
0
static int
snd_ad1889_playback_prepare(struct snd_pcm_substream *ss)
{
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
	struct snd_pcm_runtime *rt = ss->runtime;
	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
	unsigned int count = snd_pcm_lib_period_bytes(ss);
	u16 reg;

	ad1889_channel_reset(chip, AD_CHAN_WAV);

	reg = ad1889_readw(chip, AD_DS_WSMC);
	
	/* Mask out 16-bit / Stereo */
	reg &= ~(AD_DS_WSMC_WA16 | AD_DS_WSMC_WAST);

	if (snd_pcm_format_width(rt->format) == 16)
		reg |= AD_DS_WSMC_WA16;

	if (rt->channels > 1)
		reg |= AD_DS_WSMC_WAST;

	/* let's make sure we don't clobber ourselves */
	spin_lock_irq(&chip->lock);
	
	chip->wave.size = size;
	chip->wave.reg = reg;
	chip->wave.addr = rt->dma_addr;

	ad1889_writew(chip, AD_DS_WSMC, chip->wave.reg);
	
	/* Set sample rates on the codec */
	ad1889_writew(chip, AD_DS_WAS, rt->rate);

	/* Set up DMA */
	ad1889_load_wave_buffer_address(chip, chip->wave.addr);
	ad1889_load_wave_buffer_count(chip, size);
	ad1889_load_wave_interrupt_count(chip, count);

	/* writes flush */
	ad1889_readw(chip, AD_DS_WSMC);
	
	spin_unlock_irq(&chip->lock);
	
	ad1889_debug("prepare playback: addr = 0x%x, count = %u, "
			"size = %u, reg = 0x%x, rate = %u\n", chip->wave.addr,
			count, size, reg, rt->rate);
	return 0;
}
示例#4
0
static inline void
ad1889_mute(struct snd_ad1889 *chip)
{
	u16 st;
	st = ad1889_readw(chip, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM;
	ad1889_writew(chip, AD_DS_WADA, st);
	ad1889_readw(chip, AD_DS_WADA);
}
示例#5
0
static void
ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel)
{
	u16 reg;
	
	if (channel & AD_CHAN_WAV) {
		/* Disable wave channel */
		reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN;
		ad1889_writew(chip, AD_DS_WSMC, reg);
		chip->wave.reg = reg;
		
		/* disable IRQs */
		reg = ad1889_readw(chip, AD_DMA_WAV);
		reg &= AD_DMA_IM_DIS;
		reg &= ~AD_DMA_LOOP;
		ad1889_writew(chip, AD_DMA_WAV, reg);

		/* clear IRQ and address counters and pointers */
		ad1889_load_wave_buffer_address(chip, 0x0);
		ad1889_load_wave_buffer_count(chip, 0x0);
		ad1889_load_wave_interrupt_count(chip, 0x0);

		/* flush */
		ad1889_readw(chip, AD_DMA_WAV);
	}
	
	if (channel & AD_CHAN_ADC) {
		/* Disable ADC channel */
		reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN;
		ad1889_writew(chip, AD_DS_RAMC, reg);
		chip->ramc.reg = reg;

		reg = ad1889_readw(chip, AD_DMA_ADC);
		reg &= AD_DMA_IM_DIS;
		reg &= ~AD_DMA_LOOP;
		ad1889_writew(chip, AD_DMA_ADC, reg);
	
		ad1889_load_adc_buffer_address(chip, 0x0);
		ad1889_load_adc_buffer_count(chip, 0x0);
		ad1889_load_adc_interrupt_count(chip, 0x0);

		/* flush */
		ad1889_readw(chip, AD_DMA_ADC);
	}
}
static void
ad1889_channel_reset(struct snd_ad1889 *chip, unsigned int channel)
{
	u16 reg;
	
	if (channel & AD_CHAN_WAV) {
		
		reg = ad1889_readw(chip, AD_DS_WSMC) & ~AD_DS_WSMC_WAEN;
		ad1889_writew(chip, AD_DS_WSMC, reg);
		chip->wave.reg = reg;
		
		
		reg = ad1889_readw(chip, AD_DMA_WAV);
		reg &= AD_DMA_IM_DIS;
		reg &= ~AD_DMA_LOOP;
		ad1889_writew(chip, AD_DMA_WAV, reg);

		
		ad1889_load_wave_buffer_address(chip, 0x0);
		ad1889_load_wave_buffer_count(chip, 0x0);
		ad1889_load_wave_interrupt_count(chip, 0x0);

		
		ad1889_readw(chip, AD_DMA_WAV);
	}
	
	if (channel & AD_CHAN_ADC) {
		
		reg = ad1889_readw(chip, AD_DS_RAMC) & ~AD_DS_RAMC_ADEN;
		ad1889_writew(chip, AD_DS_RAMC, reg);
		chip->ramc.reg = reg;

		reg = ad1889_readw(chip, AD_DMA_ADC);
		reg &= AD_DMA_IM_DIS;
		reg &= ~AD_DMA_LOOP;
		ad1889_writew(chip, AD_DMA_ADC, reg);
	
		ad1889_load_adc_buffer_address(chip, 0x0);
		ad1889_load_adc_buffer_count(chip, 0x0);
		ad1889_load_adc_interrupt_count(chip, 0x0);

		
		ad1889_readw(chip, AD_DMA_ADC);
	}
}
示例#7
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;
}
示例#9
0
static void __devinit
snd_ad1889_ac97_xinit(struct snd_ad1889 *chip)
{
	u16 reg;

	reg = ad1889_readw(chip, AD_AC97_ACIC);
	reg |= AD_AC97_ACIC_ACRD;		/* Reset Disable */
	ad1889_writew(chip, AD_AC97_ACIC, reg);
	ad1889_readw(chip, AD_AC97_ACIC);	/* flush posted write */
	udelay(10);
	/* Interface Enable */
	reg |= AD_AC97_ACIC_ACIE;
	ad1889_writew(chip, AD_AC97_ACIC, reg);
	
	snd_ad1889_ac97_ready(chip);

	/* Audio Stream Output | Variable Sample Rate Mode */
	reg = ad1889_readw(chip, AD_AC97_ACIC);
	reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM;
	ad1889_writew(chip, AD_AC97_ACIC, reg);
	ad1889_readw(chip, AD_AC97_ACIC); /* flush posted write */

}
static void __devinit
snd_ad1889_ac97_xinit(struct snd_ad1889 *chip)
{
	u16 reg;

	reg = ad1889_readw(chip, AD_AC97_ACIC);
	reg |= AD_AC97_ACIC_ACRD;		
	ad1889_writew(chip, AD_AC97_ACIC, reg);
	ad1889_readw(chip, AD_AC97_ACIC);	
	udelay(10);
	
	reg |= AD_AC97_ACIC_ACIE;
	ad1889_writew(chip, AD_AC97_ACIC, reg);
	
	snd_ad1889_ac97_ready(chip);

	
	reg = ad1889_readw(chip, AD_AC97_ACIC);
	reg |= AD_AC97_ACIC_ASOE | AD_AC97_ACIC_VSRM;
	ad1889_writew(chip, AD_AC97_ACIC, reg);
	ad1889_readw(chip, AD_AC97_ACIC); 

}
示例#11
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;
}
示例#13
0
文件: ad1889.c 项目: 19Dan01/linux
static int
snd_ad1889_capture_prepare(struct snd_pcm_substream *ss)
{
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
	struct snd_pcm_runtime *rt = ss->runtime;
	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
	unsigned int count = snd_pcm_lib_period_bytes(ss);
	u16 reg;

	ad1889_channel_reset(chip, AD_CHAN_ADC);
	
	reg = ad1889_readw(chip, AD_DS_RAMC);

	/* Mask out 16-bit / Stereo */
	reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST);

	if (snd_pcm_format_width(rt->format) == 16)
		reg |= AD_DS_RAMC_AD16;

	if (rt->channels > 1)
		reg |= AD_DS_RAMC_ADST;

	/* let's make sure we don't clobber ourselves */
	spin_lock_irq(&chip->lock);
	
	chip->ramc.size = size;
	chip->ramc.reg = reg;
	chip->ramc.addr = rt->dma_addr;

	ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg);

	/* Set up DMA */
	ad1889_load_adc_buffer_address(chip, chip->ramc.addr);
	ad1889_load_adc_buffer_count(chip, size);
	ad1889_load_adc_interrupt_count(chip, count);

	/* writes flush */
	ad1889_readw(chip, AD_DS_RAMC);
	
	spin_unlock_irq(&chip->lock);
	
	dev_dbg(chip->card->dev,
		"prepare capture: addr = 0x%x, count = %u, size = %u, reg = 0x%x, rate = %u\n",
		chip->ramc.addr, count, size, reg, rt->rate);
	return 0;
}
static int
snd_ad1889_capture_prepare(struct snd_pcm_substream *ss)
{
	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
	struct snd_pcm_runtime *rt = ss->runtime;
	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
	unsigned int count = snd_pcm_lib_period_bytes(ss);
	u16 reg;

	ad1889_channel_reset(chip, AD_CHAN_ADC);
	
	reg = ad1889_readw(chip, AD_DS_RAMC);

	
	reg &= ~(AD_DS_RAMC_AD16 | AD_DS_RAMC_ADST);

	if (snd_pcm_format_width(rt->format) == 16)
		reg |= AD_DS_RAMC_AD16;

	if (rt->channels > 1)
		reg |= AD_DS_RAMC_ADST;

	
	spin_lock_irq(&chip->lock);
	
	chip->ramc.size = size;
	chip->ramc.reg = reg;
	chip->ramc.addr = rt->dma_addr;

	ad1889_writew(chip, AD_DS_RAMC, chip->ramc.reg);

	
	ad1889_load_adc_buffer_address(chip, chip->ramc.addr);
	ad1889_load_adc_buffer_count(chip, size);
	ad1889_load_adc_interrupt_count(chip, count);

	
	ad1889_readw(chip, AD_DS_RAMC);
	
	spin_unlock_irq(&chip->lock);
	
	ad1889_debug("prepare capture: addr = 0x%x, count = %u, "
			"size = %u, reg = 0x%x, rate = %u\n", chip->ramc.addr,
			count, size, reg, rt->rate);
	return 0;
}
示例#15
0
static void
snd_ad1889_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
{
	struct snd_ad1889 *chip = ac97->private_data;
	ad1889_writew(chip, AD_AC97_BASE + reg, val);
}