Ejemplo n.º 1
0
static int mv88fx_snd_spdif_default_get(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct mv88fx_snd_chip *chip = snd_kcontrol_chip(kcontrol);
	struct mv88fx_snd_stream *pbstream =
		&chip->stream[SNDRV_PCM_STREAM_PLAYBACK];
	int port = chip->port;
	int i, word;

	mv88fx_snd_debug("");

	port = port;
	spin_lock_irq(&chip->reg_lock);
	for (word = 0; word < 4; word++) {
		pbstream->spdif_status[word] =
		    mv88fx_snd_readl(chip->base,
			MV_AUDIO_SPDIF_PLAY_CH_STATUS_LEFT_REG(port, word));

		for (i = 0; i < 4; i++)
			ucontrol->value.iec958.status[word + i] =
			(pbstream->spdif_status[word] >> (i * 8)) & 0xff;

	}
	spin_unlock_irq(&chip->reg_lock);
	return 0;
}
Ejemplo n.º 2
0
static int mv88fx_i2s_suspend(struct snd_soc_dai *cpu_dai)
{
	struct mv88fx_snd_chip *chip = mv88fx_pcm_snd_chip[cpu_dai->id];

	mv88fx_snd_debug("");

	if (!cpu_dai->active)
		return 0;


	spin_lock(&chip->reg_lock);

	/* save registers */
	mv88fx_i2s_info[chip->port].irq_mask = mv88fx_snd_readl(chip->base,
			MV_AUDIO_INT_MASK_REG(chip->port));
	mv88fx_i2s_info[chip->port].capture_cntrl_reg = mv88fx_snd_readl(chip->base,
			MV_AUDIO_RECORD_CTRL_REG(chip->port));
	mv88fx_i2s_info[chip->port].playback_cntrl_reg = mv88fx_snd_readl(chip->base,
			MV_AUDIO_PLAYBACK_CTRL_REG(chip->port));

	/* clear all interrupts */
	mv88fx_snd_writel(chip->base,
		MV_AUDIO_INT_CAUSE_REG(chip->port), 0xffffffff);
	/* disable all interrupts */
	mv88fx_snd_writel(chip->base,
		MV_AUDIO_INT_MASK_REG(chip->port), 0);
	/* pause dma */
	mv88fx_snd_bitset(chip->base,
		MV_AUDIO_RECORD_CTRL_REG(chip->port), ARCR_RECORD_PAUSE_MASK);
	mv88fx_snd_bitset(chip->base,
		MV_AUDIO_PLAYBACK_CTRL_REG(chip->port), APCR_PLAY_PAUSE_MASK);


	spin_unlock(&chip->reg_lock);

	return 0;
}
Ejemplo n.º 3
0
int mv88fx_snd_hw_playback_set(struct mv88fx_snd_chip	*chip)
{
        struct mv88fx_snd_stream *audio_stream = 
		chip->stream[PLAYBACK]; 
	struct snd_pcm_substream *substream = audio_stream->substream;
	struct snd_pcm_runtime *runtime = substream->runtime;
        
	MV_AUDIO_PLAYBACK_CTRL	pcm_play_ctrl;
	MV_I2S_PLAYBACK_CTRL	i2s_play_ctrl;
	MV_SPDIF_PLAYBACK_CTRL	spdif_play_ctrl;
	MV_AUDIO_FREQ_DATA 	dco_ctrl;


	dco_ctrl.offset = chip->dco_ctrl_offst;
	
	switch(audio_stream->rate) {
	case 44100:
		dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH;
		break;
	case 48000:
		dco_ctrl.baseFreq = AUDIO_FREQ_48KH;
		break;
	case 96000:
		dco_ctrl.baseFreq = AUDIO_FREQ_96KH;
		break;
	default:
		snd_printk("Requested rate %d is not supported\n", 
				runtime->rate); return -1;
	}

	pcm_play_ctrl.burst = (chip->burst == 128)?AUDIO_128BYTE_BURST:
				AUDIO_32BYTE_BURST;
	
	pcm_play_ctrl.loopBack = chip->loopback;
	
	if (audio_stream->stereo) {
		pcm_play_ctrl.monoMode = AUDIO_PLAY_MONO_OFF;
	}
	else {
		switch (audio_stream->mono_mode) {
		case MONO_LEFT:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_LEFT_MONO;
			break;
		case MONO_RIGHT:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_RIGHT_MONO;
			break;
		case MONO_BOTH:
		default:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_BOTH_MONO;
			break;
		}
	}
	
	if (audio_stream->format == SAMPLE_16IN16) {
		pcm_play_ctrl.sampleSize = SAMPLE_16BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_16BIT;
	}
	else if (audio_stream->format == SAMPLE_24IN32) {
		pcm_play_ctrl.sampleSize = SAMPLE_24BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_24BIT;
		
	}
	else if (audio_stream->format == SAMPLE_32IN32) {
		pcm_play_ctrl.sampleSize = SAMPLE_32BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_32BIT;
	}
	else {
		snd_printk("Requested format %d is not supported\n", runtime->format);
		return -1;
	}

	/* buffer and period sizes in frame */
	pcm_play_ctrl.bufferPhyBase = audio_stream->dma_addr;
	pcm_play_ctrl.bufferSize = audio_stream->dma_size;
	pcm_play_ctrl.intByteCount = audio_stream->period_size;

	/* I2S playback streem stuff */
	/*i2s_play_ctrl.sampleSize = pcm_play_ctrl.sampleSize;*/
	i2s_play_ctrl.justification = I2S_JUSTIFIED;
	i2s_play_ctrl.sendLastFrame = 0;

	spdif_play_ctrl.nonPcm = MV_FALSE;
	
	spdif_play_ctrl.validity = chip->ch_stat_valid;

	if (audio_stream->stat_mem) {
		spdif_play_ctrl.userBitsFromMemory = MV_TRUE;
		spdif_play_ctrl.validityFromMemory = MV_TRUE;
		spdif_play_ctrl.blockStartInternally = MV_FALSE;
	} else {
		spdif_play_ctrl.userBitsFromMemory = MV_FALSE;
		spdif_play_ctrl.validityFromMemory = MV_FALSE;
		spdif_play_ctrl.blockStartInternally = MV_TRUE;
	}

	/* If this is non-PCM sound, mute I2S channel */
	spin_lock_irq(&chip->reg_lock);

	if (!(mv88fx_snd_readl(chip, MV_AUDIO_PLAYBACK_CTRL_REG) & 
			(APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK))) {

	if (MV_OK != mvAudioDCOCtrlSet(&dco_ctrl)) {
		snd_printk("Failed to initialize DCO clock control.\n");
		return -1;
	}
	}

	if (audio_stream->clock_src == DCO_CLOCK)
		while ((mv88fx_snd_readl(chip, MV_AUDIO_SPCR_DCO_STATUS_REG) & 
			ASDSR_DCO_LOCK_MASK) == 0);
	else if (audio_stream->clock_src == SPCR_CLOCK)
		while ((mv88fx_snd_readl(chip, MV_AUDIO_SPCR_DCO_STATUS_REG) & 
			ASDSR_SPCR_LOCK_MASK) == 0);
			
	if (MV_OK != mvAudioPlaybackControlSet(&pcm_play_ctrl)) {
		snd_printk("Failed to initialize PCM playback control.\n");
		return -1;
	}

	if (MV_OK != mvI2SPlaybackCtrlSet(&i2s_play_ctrl)) {
		snd_printk("Failed to initialize I2S playback control.\n");
		return -1;
	}

	mvSPDIFPlaybackCtrlSet(&spdif_play_ctrl);

	spin_unlock_irq(&chip->reg_lock);

#if 0 
	mv88fx_snd_debug("runtime->xfer_align=%d\n",(int)runtime->xfer_align);
	mv88fx_snd_debug("runtime->format=%d\n",runtime->format);
	mv88fx_snd_debug("runtime->channels=%d\n",runtime->channels);
	mv88fx_snd_debug("runtime->rate=%d\n",runtime->rate);
	mv88fx_snd_debug("runtime->dma_addr=0x%x\n",runtime->dma_addr);

	mv88fx_snd_debug("runtime->dma_area=0x%x\n",(unsigned int)runtime->dma_area);
	mv88fx_snd_debug("runtime->frame_bits=0x%x\n",runtime->frame_bits);
	mv88fx_snd_debug("runtime->period_size=0x%x\n",
		   (unsigned int)runtime->period_size);
	mv88fx_snd_debug("runtime->buffer_size=0x%x\n",
		   (unsigned int)runtime->buffer_size); 
	mv88fx_snd_debug("bufferPhyBase=0x%x\n",runtime->dma_addr);
	mv88fx_snd_debug("bufferSize=0x%x\n",pcm_play_ctrl.bufferSize);
	mv88fx_snd_debug("intByteCount=0x%x.\n",pcm_play_ctrl.intByteCount);

#endif
	
	return 0;
}
Ejemplo n.º 4
0
int mv88fx_snd_hw_capture_set(struct mv88fx_snd_chip	*chip)
{
        struct mv88fx_snd_stream *audio_stream = 
		chip->stream[CAPTURE]; 
	struct snd_pcm_substream *substream = audio_stream->substream;
	struct snd_pcm_runtime *runtime = substream->runtime;
	
	MV_AUDIO_RECORD_CTRL 	pcm_rec_ctrl;
	MV_I2S_RECORD_CTRL	i2s_rec_ctrl;
	MV_AUDIO_FREQ_DATA	dco_ctrl;


	dco_ctrl.offset = chip->dco_ctrl_offst;

	switch(audio_stream->rate) {
	case 44100:
		dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH;
		break;
	case 48000:
		dco_ctrl.baseFreq = AUDIO_FREQ_48KH;
		break;
	case 96000:
		dco_ctrl.baseFreq = AUDIO_FREQ_96KH;
		break;
	default:
		snd_printk("Requested rate %d is not supported\n", 
				runtime->rate); return -1;
	}
	
	pcm_rec_ctrl.burst = (chip->burst == 128)?AUDIO_128BYTE_BURST:
				AUDIO_32BYTE_BURST;

	if (audio_stream->format == SAMPLE_16IN16) {
		pcm_rec_ctrl.sampleSize = SAMPLE_16BIT;
	}
	else if (audio_stream->format == SAMPLE_24IN32) {
		pcm_rec_ctrl.sampleSize = SAMPLE_24BIT;
	}
	else if (audio_stream->format == SAMPLE_32IN32) {
		pcm_rec_ctrl.sampleSize = SAMPLE_32BIT;
	}
	else {
		snd_printk("Requested format %d is not supported\n", runtime->format);
		return -1;
	}

	pcm_rec_ctrl.mono = (audio_stream->stereo) ? MV_FALSE : MV_TRUE;

	if (pcm_rec_ctrl.mono) {
		switch (audio_stream->mono_mode) {
		case MONO_LEFT:
			pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO;
			break;
		default:
		case MONO_RIGHT:
			pcm_rec_ctrl.monoChannel = AUDIO_REC_RIGHT_MONO;
			break;
		}
		
	}
	else pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO;
		

	pcm_rec_ctrl.bufferPhyBase = audio_stream->dma_addr;
	pcm_rec_ctrl.bufferSize = audio_stream->dma_size;
	
	pcm_rec_ctrl.intByteCount = audio_stream->period_size;

	/* I2S record streem stuff */
	i2s_rec_ctrl.sample = pcm_rec_ctrl.sampleSize;
	i2s_rec_ctrl.justf = I2S_JUSTIFIED;

	spin_lock_irq(&chip->reg_lock);

	/* set clock only if record is not enabled*/
	if (!(mv88fx_snd_readl(chip, MV_AUDIO_RECORD_CTRL_REG) & 
			(ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK))) {

	if (MV_OK != mvAudioDCOCtrlSet(&dco_ctrl)) {
		snd_printk("Failed to initialize DCO clock control.\n");
		return -1;
	}
	}
	
	if (MV_OK != mvAudioRecordControlSet(&pcm_rec_ctrl)) {
		snd_printk("Failed to initialize PCM record control.\n");
		return -1;
	}

	if (MV_OK != mvI2SRecordCntrlSet(&i2s_rec_ctrl)) {
		snd_printk("Failed to initialize I2S record control.\n");
		return -1;
	}
	spin_unlock_irq(&chip->reg_lock);

#if 0

	mv88fx_snd_debug("pcm_rec_ctrl.bufferSize=0x%x\n",(int)pcm_rec_ctrl.bufferSize);
	mv88fx_snd_debug("pcm_rec_ctrl.intByteCount=0x%x\n",(int)pcm_rec_ctrl.intByteCount);

	mv88fx_snd_debug("runtime->xfer_align=%d\n",(int)runtime->xfer_align);
	mv88fx_snd_debug("runtime->format=%d\n",runtime->format);
	mv88fx_snd_debug("runtime->channels=%d\n",runtime->channels);
	mv88fx_snd_debug("runtime->rate=%d\n",runtime->rate);
	mv88fx_snd_debug("runtime->dma_addr=0x%x\n",runtime->dma_addr);

	mv88fx_snd_debug("runtime->dma_area=0x%x\n",(unsigned int)runtime->dma_area);
	mv88fx_snd_debug("runtime->frame_bits=0x%x\n",runtime->frame_bits);
	mv88fx_snd_debug("runtime->period_size=0x%x\n",
		   (unsigned int)runtime->period_size);
	mv88fx_snd_debug("runtime->buffer_size=0x%x\n",
		   (unsigned int)runtime->buffer_size); 
	mv88fx_snd_debug("bufferPhyBase=0x%x\n",runtime->dma_addr);

#endif
	

	return 0;

}
Ejemplo n.º 5
0
static int mv88fx_i2s_snd_hw_playback_set(struct mv88fx_snd_chip *chip,
					  struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mv88fx_snd_stream *audio_stream = runtime->private_data;
	MV_AUDIO_PLAYBACK_CTRL pcm_play_ctrl;
	MV_I2S_PLAYBACK_CTRL i2s_play_ctrl;
	MV_SPDIF_PLAYBACK_CTRL spdif_play_ctrl;
	MV_AUDIO_FREQ_DATA dco_ctrl;

	mv88fx_snd_debug("chip=%p chip->base=%p", chip, chip->base);

	memset(&pcm_play_ctrl, 0, sizeof(pcm_play_ctrl));
	memset(&dco_ctrl, 0, sizeof(dco_ctrl));
	memset(&i2s_play_ctrl, 0, sizeof(i2s_play_ctrl));
	memset(&spdif_play_ctrl, 0, sizeof(spdif_play_ctrl));

	dco_ctrl.offset = chip->dco_ctrl_offst;

	mv88fx_snd_debug("rate: %u	", runtime->rate);
	switch (runtime->rate) {
	case 44100:
		dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH;
		break;
	case 48000:
		dco_ctrl.baseFreq = AUDIO_FREQ_48KH;
		break;
	case 96000:
		dco_ctrl.baseFreq = AUDIO_FREQ_96KH;
		break;
	default:
		mv88fx_snd_error("Requested rate %d is not supported",
				 runtime->rate);
		return -1;
	}

	pcm_play_ctrl.burst = (chip->burst == 128) ? AUDIO_128BYTE_BURST :
	    AUDIO_32BYTE_BURST;

	pcm_play_ctrl.loopBack = chip->loopback;

	if (mv88fx_pcm_is_stereo(runtime)) {
		pcm_play_ctrl.monoMode = AUDIO_PLAY_MONO_OFF;
	} else {

		switch (audio_stream->mono_mode) {
		case MONO_LEFT:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_LEFT_MONO;
			break;
		case MONO_RIGHT:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_RIGHT_MONO;
			break;
		case MONO_BOTH:
		default:
			pcm_play_ctrl.monoMode = AUDIO_PLAY_BOTH_MONO;
			break;
		}
	}

	if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
		pcm_play_ctrl.sampleSize = SAMPLE_16BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_16BIT;
	} else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE) {
		pcm_play_ctrl.sampleSize = SAMPLE_24BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_24BIT;

	} else if (runtime->format == SNDRV_PCM_FORMAT_S32_LE) {
		pcm_play_ctrl.sampleSize = SAMPLE_32BIT;
		i2s_play_ctrl.sampleSize = SAMPLE_32BIT;
	} else {
		mv88fx_snd_error("Requested format %d is not supported",
				 runtime->format);
		return -1;
	}

	/* buffer and period sizes in frame */
	pcm_play_ctrl.bufferPhyBase = runtime->dma_addr;
	pcm_play_ctrl.bufferSize =
	    frames_to_bytes(runtime, runtime->buffer_size);
	pcm_play_ctrl.intByteCount =
	    frames_to_bytes(runtime, runtime->period_size);

	/* I2S playback streem stuff */
	/*i2s_play_ctrl.sampleSize = pcm_play_ctrl.sampleSize; */
	i2s_play_ctrl.justification = I2S_JUSTIFIED;
	i2s_play_ctrl.sendLastFrame = 0;

	spdif_play_ctrl.nonPcm = MV_FALSE;

	spdif_play_ctrl.validity = chip->ch_stat_valid;

	if (audio_stream->stat_mem) {
		spdif_play_ctrl.userBitsFromMemory = MV_TRUE;
		spdif_play_ctrl.validityFromMemory = MV_TRUE;
		spdif_play_ctrl.blockStartInternally = MV_FALSE;
	} else {
		spdif_play_ctrl.userBitsFromMemory = MV_FALSE;
		spdif_play_ctrl.validityFromMemory = MV_FALSE;
		spdif_play_ctrl.blockStartInternally = MV_TRUE;
	}

	mv88fx_snd_debug("");
	/* If this is non-PCM sound, mute I2S channel */
	spin_lock_irq(&chip->reg_lock);

	mv88fx_snd_debug("chip=%p chip->base=%p port=%d", chip, chip->base,
			 chip->port);

	if (!(mv88fx_snd_readl(chip->base,
		MV_AUDIO_PLAYBACK_CTRL_REG(chip->port)) &
		(APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK))) {

		mv88fx_snd_debug("");

		if (MV_OK != mvAudioDCOCtrlSet(chip->port, &dco_ctrl)) {
			mv88fx_snd_error
			    ("Failed to initialize DCO clock control.");
			return -1;
			mv88fx_snd_debug("");

		}
	}

	mv88fx_snd_debug("");

	if (audio_stream->clock_src == DCO_CLOCK)
		while ((mv88fx_snd_readl(chip->base,
			 MV_AUDIO_SPCR_DCO_STATUS_REG(chip->port)) &
			ASDSR_DCO_LOCK_MASK) == 0)
			;
	else if (audio_stream->clock_src == SPCR_CLOCK)
		while ((mv88fx_snd_readl(chip->base,
			 MV_AUDIO_SPCR_DCO_STATUS_REG(chip->port)) &
			ASDSR_SPCR_LOCK_MASK) == 0)
			;

	mv88fx_snd_debug("");

	if (MV_OK != mvAudioPlaybackControlSet(chip->port, &pcm_play_ctrl)) {
		mv88fx_snd_error("Failed to initialize PCM playback control.");
		return -1;
	}
	mv88fx_snd_debug("");

	if (MV_OK != mvI2SPlaybackCtrlSet(chip->port, &i2s_play_ctrl)) {
		mv88fx_snd_error("Failed to initialize I2S playback control.");
		return -1;
	}
	mv88fx_snd_debug("");

	mvSPDIFPlaybackCtrlSet(chip->port, &spdif_play_ctrl);

	mv88fx_snd_debug("");

	spin_unlock_irq(&chip->reg_lock);

	return 0;
}
Ejemplo n.º 6
0
static int mv88fx_i2s_playback_trigger(struct snd_pcm_substream *substream,
				       int cmd)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mv88fx_snd_stream *audio_stream = runtime->private_data;
	struct mv88fx_snd_chip *chip = mv88fx_pcm_get_chip(substream);
	int result = 0;

	mv88fx_snd_debug("substream=%p cmd=%d audio_stream=%p", substream, cmd,
			 audio_stream);

	spin_lock(&chip->reg_lock);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:

		mv88fx_snd_debug("");
		/* enable interrupt */
		mv88fx_snd_bitset(chip->base, MV_AUDIO_INT_MASK_REG(chip->port),
				  AICR_PLAY_BYTES_INT);

		/* make sure the dma in pause state */
		mv88fx_snd_bitset(chip->base,
			MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
			APCR_PLAY_PAUSE_MASK);

		/* enable dma */
		if ((audio_stream->dig_mode & I2S) && (chip->pcm_mode == PCM))
			mv88fx_snd_bitset(chip->base,
				MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
				APCR_PLAY_I2S_ENABLE_MASK);

		if (audio_stream->dig_mode & SPDIF)
			mv88fx_snd_bitset(chip->base,
				MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
				APCR_PLAY_SPDIF_ENABLE_MASK);

		/* start dma */
		mv88fx_snd_bitreset(chip->base,
				    MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
				    APCR_PLAY_PAUSE_MASK);

		break;
	case SNDRV_PCM_TRIGGER_STOP:

		mv88fx_snd_debug("");

		/* disable interrupt */
		mv88fx_snd_bitreset(chip->base,
			MV_AUDIO_INT_MASK_REG(chip->port),
			AICR_PLAY_BYTES_INT);

		/* make sure the dma in pause state */
		mv88fx_snd_bitset(chip->base,
			MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
			APCR_PLAY_PAUSE_MASK);

		/* always stop both I2S and SPDIF */
		mv88fx_snd_bitreset(chip->base,
				    MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
				    (APCR_PLAY_I2S_ENABLE_MASK |
				     APCR_PLAY_SPDIF_ENABLE_MASK));

		/* check if busy twice */
		while (mv88fx_snd_readl(chip->base,
			MV_AUDIO_PLAYBACK_CTRL_REG(chip->port)) &
		       APCR_PLAY_BUSY_MASK)
			;

		while (mv88fx_snd_readl(chip->base,
			MV_AUDIO_PLAYBACK_CTRL_REG(chip->port)) &
		       APCR_PLAY_BUSY_MASK)
			;

		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		mv88fx_snd_debug("");

		mv88fx_snd_bitset(chip->base,
			MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
			APCR_PLAY_PAUSE_MASK);
		break;
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		mv88fx_snd_debug("");

		mv88fx_snd_bitreset(chip->base,
				    MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
				    APCR_PLAY_PAUSE_MASK);

		break;
	default:
		result = -EINVAL;
		break;
	}
	spin_unlock(&chip->reg_lock);
	mv88fx_snd_debug("result=%d", result);
	return result;
}
Ejemplo n.º 7
0
static int mv88fx_i2s_snd_hw_capture_set(struct mv88fx_snd_chip *chip,
					 struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct mv88fx_snd_stream *audio_stream = runtime->private_data;
	MV_AUDIO_RECORD_CTRL pcm_rec_ctrl;
	MV_I2S_RECORD_CTRL i2s_rec_ctrl;
	MV_AUDIO_FREQ_DATA dco_ctrl;
//#ifdef CONFIG_MACH_DOVE_RD_AVNG
//	int phoneInDetected;
//#endif

	mv88fx_snd_debug("chip=%p chip->base=%p", chip, chip->base);

	dco_ctrl.offset = chip->dco_ctrl_offst;

	switch (runtime->rate) {
	case 44100:
		dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH;
		break;
	case 48000:
		dco_ctrl.baseFreq = AUDIO_FREQ_48KH;
		break;
	case 96000:
		dco_ctrl.baseFreq = AUDIO_FREQ_96KH;
		break;
	default:
		mv88fx_snd_debug("ERROR");
		mv88fx_snd_error("Requested rate %d is not supported",
				 runtime->rate);
		return -1;
	}

	pcm_rec_ctrl.burst = (chip->burst == 128) ? AUDIO_128BYTE_BURST :
	    AUDIO_32BYTE_BURST;

	if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
		pcm_rec_ctrl.sampleSize = SAMPLE_16BIT;
	} else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE) {
		pcm_rec_ctrl.sampleSize = SAMPLE_24BIT;
	} else if (runtime->format == SNDRV_PCM_FORMAT_S32_LE) {
		pcm_rec_ctrl.sampleSize = SAMPLE_32BIT;
	} else {
		mv88fx_snd_error("Requested format %d is not supported",
				 runtime->format);
		return -1;
	}

	pcm_rec_ctrl.mono =
	    (mv88fx_pcm_is_stereo(runtime)) ? MV_FALSE : MV_TRUE;

	if (pcm_rec_ctrl.mono) {
		switch (audio_stream->mono_mode) {
		case MONO_LEFT:
			pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO;
			break;
		default:
		case MONO_RIGHT:
			pcm_rec_ctrl.monoChannel = AUDIO_REC_RIGHT_MONO;
			break;
		}

	} else
		pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO;

	pcm_rec_ctrl.bufferPhyBase = runtime->dma_addr;
	pcm_rec_ctrl.bufferSize =
	    frames_to_bytes(runtime, runtime->buffer_size);
	pcm_rec_ctrl.intByteCount =
	    frames_to_bytes(runtime, runtime->period_size);

	/* I2S record streem stuff */
	i2s_rec_ctrl.sample = pcm_rec_ctrl.sampleSize;
	i2s_rec_ctrl.justf = I2S_JUSTIFIED;

	spin_lock_irq(&chip->reg_lock);

	/* set clock only if record is not enabled */
	if (!(mv88fx_snd_readl(chip->base,
		MV_AUDIO_RECORD_CTRL_REG(chip->port)) &
		(ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK))) {

		if (MV_OK != mvAudioDCOCtrlSet(chip->port, &dco_ctrl)) {
			mv88fx_snd_debug("ERROR");
			mv88fx_snd_error
			    ("Failed to initialize DCO clock control.");
			return -1;
		}
	}
	mv88fx_snd_debug("");
	if (MV_OK != mvAudioRecordControlSet(chip->port, &pcm_rec_ctrl)) {
		mv88fx_snd_error("Failed to initialize PCM record control.");
		return -1;
	}

	if (MV_OK != mvI2SRecordCntrlSet(chip->port, &i2s_rec_ctrl)) {
		mv88fx_snd_error("Failed to initialize I2S record control.");
		return -1;
	}
	mv88fx_snd_debug("");

//#ifdef CONFIG_MACH_DOVE_RD_AVNG
//	if (machine_is_dove_rd_avng()) {
//		phoneInDetected = gpio_get_value(53);
//		if (phoneInDetected < 0)
//			mv88fx_snd_error("Failed to detect phone-in.");
//		else {
//			int input_type;
//			mv88fx_snd_error("detect phone-in.");
//			if (!phoneInDetected)
//				input_type = 2;	/* external MIC */
//			else
//				input_type = 1;	/* internal MIC */
//		}
//	}
//#endif
	mv88fx_snd_debug("");

	spin_unlock_irq(&chip->reg_lock);

	mv88fx_snd_debug("");

	return 0;

}