Example #1
0
/*******************************************************************************
* mvAudioRecordControlGet - Get Recording control parameters
*
* DESCRIPTION:
*
* INPUT:
*       ctrl: pointer to MV_AUDIO_RECORD_CTRL structure
* OUTPUT:
*		ctrl: pointer to MV_AUDIO_RECORD_CTRL structure
* RETURN:
*       None
*
*******************************************************************************/
MV_VOID mvAudioRecordControlGet(int unit, MV_AUDIO_RECORD_CTRL *ctrl)
{
	MV_U32 reg;

	ctrl->mono =
			((MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit))&ARCR_RECORD_MONO_MASK)?
			 MV_TRUE:MV_FALSE);

	ctrl->burst =
			((MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit))&ARCR_RECORD_BURST_SIZE_MASK) >>
			 ARCR_RECORD_BURST_SIZE_OFFS);

	ctrl->monoChannel =
			((MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit))&ARCR_RECORDED_MONO_CHNL_MASK) >>
			 ARCR_RECORDED_MONO_CHNL_OFFS);

	ctrl->sampleSize =
			((MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit))&ARCR_RECORD_SAMPLE_SIZE_MASK) >>
			 ARCR_RECORD_SAMPLE_SIZE_OFFS);

	ctrl->bufferPhyBase = MV_REG_READ(MV_AUDIO_RECORD_START_ADDR_REG(unit));
	reg = MV_REG_READ(MV_AUDIO_RECORD_BUFF_SIZE_REG(unit));
	ctrl->bufferSize = AUDIO_REG_TO_SIZE(reg);

    	ctrl->intByteCount = MV_REG_READ(MV_AUDIO_RECORD_BYTE_CNTR_INT_REG(unit));

}
Example #2
0
static int mv88fx_i2s_resume(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;

	mv88fx_i2_hw_init(chip->port);

	spin_lock(&chip->reg_lock);

	mv88fx_snd_writel(chip->base,
		MV_AUDIO_INT_CAUSE_REG(chip->port), 0xffffffff);
	/* restore registers */
	mv88fx_snd_writel(chip->base,
		MV_AUDIO_RECORD_CTRL_REG(chip->port),
		mv88fx_i2s_info[chip->port].capture_cntrl_reg);
	mv88fx_snd_writel(chip->base,
		MV_AUDIO_PLAYBACK_CTRL_REG(chip->port),
		mv88fx_i2s_info[chip->port].playback_cntrl_reg);
	/* enable interrupts */
	mv88fx_snd_writel(chip->base,
		MV_AUDIO_INT_MASK_REG(chip->port),
		mv88fx_i2s_info[chip->port].irq_mask);

	spin_unlock(&chip->reg_lock);

	return 0;
}
Example #3
0
static int mv88fx_i2_hw_init(int port)
{
	mv88fx_snd_debug("");

	mv88fx_snd_writel(mv88fx_i2s_info[port].base,
		MV_AUDIO_INT_CAUSE_REG(port), 0xffffffff);
	mv88fx_snd_writel(mv88fx_i2s_info[port].base,
		MV_AUDIO_INT_MASK_REG(port), 0);
	mv88fx_snd_writel(mv88fx_i2s_info[port].base,
		MV_AUDIO_SPDIF_REC_INT_CAUSE_MASK_REG(port), 0);

//	if (MV_OK != mvAudioInit(mv88fx_i2s_info.port))
//		return -EIO;
	mvSysAudioInit(port);

	/* Disable all playback/recording */
	mv88fx_snd_bitreset(mv88fx_i2s_info[port].base,
		MV_AUDIO_PLAYBACK_CTRL_REG(port),
		(APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK));

	mv88fx_snd_bitreset(mv88fx_i2s_info[port].base,
		MV_AUDIO_RECORD_CTRL_REG(port),
		(ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK));

	if (MV_OK != mvSPDIFRecordTclockSet(port)) {
		mv88fx_snd_error("mvSPDIFRecordTclockSet failed");
		return -ENOMEM;
	}
	return 0;
}
Example #4
0
/*******************************************************************************
* mvAudioRecordControlGet - Get Recording status parameters
*
* DESCRIPTION:
*
* INPUT:
*       status: pointer to MV_AUDIO_RECORD_STATUS structure
* OUTPUT:
*		status: pointer to MV_AUDIO_RECORD_STATUS structure
* RETURN:
*       None
*
*******************************************************************************/
MV_VOID mvAudioRecordStatusGet(int unit, MV_AUDIO_RECORD_STATUS *status)
{
	status->I2SEnable =
			((MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit))&ARCR_RECORD_I2S_EN_MASK)?
			 MV_TRUE:MV_FALSE);

	status->mute =
			((MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit))&ARCR_RECORD_MUTE_MASK)?
			 MV_TRUE:MV_FALSE);

	status->pause =
			((MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit))&ARCR_RECORD_PAUSE_MASK)?
			 MV_TRUE:MV_FALSE);

	status->spdifEnable =
			((MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit))&ARCR_RECORD_SPDIF_EN_MASK)?
			 MV_TRUE:MV_FALSE);

}
Example #5
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;
}
Example #6
0
/* Audio Recording*/
MV_STATUS mvAudioRecordControlSet(int unit, MV_AUDIO_RECORD_CTRL *ctrl)
{
	MV_AUDIO_DEC_WIN audioWin;
	MV_CPU_DEC_WIN  cpuWin;
	MV_ADDR_WIN   bufAddrWin;
	MV_U32 target;
	MV_U32 reg;

	if (ctrl->monoChannel > AUDIO_REC_RIGHT_MONO)
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,illegal monoChannel %x\n",
				   ctrl->monoChannel );

		return MV_FAIL;
	}

	if ((ctrl->burst != AUDIO_32BYTE_BURST) &&
		(ctrl->burst != AUDIO_128BYTE_BURST))
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,illegal burst %x\n",
				   ctrl->burst );

		return MV_FAIL;

	}

	if (ctrl->bufferPhyBase & (MV_AUDIO_BUFFER_MIN_ALIGN - 1))
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,bufferPhyBase is not"\
				   "\n aligned to 0x%x bytes\n",MV_AUDIO_BUFFER_MIN_ALIGN );

		return MV_FAIL;
	}

	if  ((ctrl->bufferSize <= audioBurstBytesNumGet(ctrl->burst))||
		(ctrl->bufferSize & (audioBurstBytesNumGet(ctrl->burst) - 1))||
		 (ctrl->bufferSize > AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX))
		 )
	{
		mvOsPrintf("mvAudioRecordControlSet: Error, bufferSize smaller"\
				   "\nthan or not multiple of 0x%x bytes or larger than"\
				   "\n 0x%x",
				   audioBurstBytesNumGet(ctrl->burst),
				   AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX));

		return MV_FAIL;
	}


	reg = MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit));
	reg &= ~(ARCR_RECORD_BURST_SIZE_MASK|ARCR_RECORDED_MONO_CHNL_MASK|
			 ARCR_RECORD_SAMPLE_SIZE_MASK);
	switch (ctrl->sampleSize)
	{
	case SAMPLE_16BIT:
	case SAMPLE_16BIT_NON_COMPACT:
	case SAMPLE_20BIT:
	case SAMPLE_24BIT:
	case SAMPLE_32BIT:
		reg |= ctrl->sampleSize << ARCR_RECORD_SAMPLE_SIZE_OFFS;
        break;
	default:
        mvOsPrintf("mvAudioRecordControlSet: Error ,illegal sampleSize %x\n",
				   ctrl->sampleSize );

		return MV_FAIL;
	}

	reg |= ctrl->burst << ARCR_RECORD_BURST_SIZE_OFFS;
	reg |= ctrl->monoChannel << ARCR_RECORDED_MONO_CHNL_OFFS;
	MV_REG_WRITE(MV_AUDIO_RECORD_CTRL_REG(unit), reg);

	if (ctrl->mono)
	{
		MV_REG_BIT_SET (MV_AUDIO_RECORD_CTRL_REG(unit), 
				ARCR_RECORD_MONO_MASK);
	}
	else
	{
		MV_REG_BIT_RESET (MV_AUDIO_RECORD_CTRL_REG(unit), 
				ARCR_RECORD_MONO_MASK);
	}

	/* Get the details of the Record address window*/
	if( mvAudioWinGet( MV_AUDIO_RECORD_WIN_NUM, &audioWin ) != MV_OK )
	{
		mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on win %d\n",
				   MV_AUDIO_RECORD_WIN_NUM);
		return MV_FAIL;
	}

	bufAddrWin.baseHigh = 0;
	bufAddrWin.baseLow = ctrl->bufferPhyBase;
	bufAddrWin.size = ctrl->bufferSize;

	/* If Record window is not enabled or buffer address is not within window boundries
	   then try to set a new value to the Record window by
	   Geting the target of where the buffer exist, if the buffer is within the window
	   of the new target then set the Record window to that target
	   else return Fail
    */

	if((audioWin.enable != MV_TRUE) ||
	  (MV_TRUE != ctrlWinWithinWinTest(&bufAddrWin, &audioWin.addrWin)))
	{
		/* Get the target of the buffer that user require*/
		target = mvCpuIfTargetOfBaseAddressGet(ctrl->bufferPhyBase);
		if (MAX_TARGETS == target)
		{
			mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on address 0x%x\n",
					   ctrl->bufferPhyBase);
			return MV_FAIL;
		}

		/* Get the window details of this target*/
		if (MV_OK != mvCpuIfTargetWinGet(target, &cpuWin))
		{
			mvOsPrintf("mvAudioRecordControlSet: Error calling mvCpuIfTargetWinGet on target %d\n",
					   target);
			return MV_FAIL;

		}

		/* if the address window of the target is enabled and te user buffer is within
		   that target address window then set the palyback\recording window to the
		   target window

		*/
		if((cpuWin.enable == MV_TRUE) &&
		  (MV_TRUE == ctrlWinWithinWinTest(&bufAddrWin, &cpuWin.addrWin)))
		{

			audioWin.addrWin.baseHigh = cpuWin.addrWin.baseHigh;
			audioWin.addrWin.baseLow = cpuWin.addrWin.baseLow;
			audioWin.addrWin.size = cpuWin.addrWin.size;
			audioWin.enable = cpuWin.enable;
			audioWin.target = target;

			if( mvAudioWinSet( MV_AUDIO_RECORD_WIN_NUM, &audioWin ) != MV_OK )
			{
				mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on win %d\n",
						   MV_AUDIO_RECORD_WIN_NUM);
				return MV_FAIL;
			}

		}
		else
		{
			mvOsPrintf("mvAudioRecordControlSet: Error buffer is not within a valid target\n");
			return MV_FAIL;

		}
	}

    	/* Set the interrupt byte count.                            */
    	reg = ctrl->intByteCount & ARBCI_BYTE_COUNT_MASK;
    	MV_REG_WRITE(MV_AUDIO_RECORD_BYTE_CNTR_INT_REG(unit), reg);

	MV_REG_WRITE(MV_AUDIO_RECORD_START_ADDR_REG(unit), ctrl->bufferPhyBase);
	MV_REG_WRITE(MV_AUDIO_RECORD_BUFF_SIZE_REG(unit),
				 AUDIO_SIZE_TO_REG(ctrl->bufferSize));

	return MV_OK;
}
Example #7
0
/* Audio Recording*/
MV_STATUS mvAudioRecordControlSet(int unit, MV_AUDIO_RECORD_CTRL *ctrl)
{
	MV_U32 reg;

	if (ctrl->monoChannel > AUDIO_REC_RIGHT_MONO)
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,illegal monoChannel %x\n",
				   ctrl->monoChannel );

		return MV_FAIL;
	}

	if ((ctrl->burst != AUDIO_32BYTE_BURST) &&
		(ctrl->burst != AUDIO_128BYTE_BURST))
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,illegal burst %x\n",
				   ctrl->burst );

		return MV_FAIL;

	}

	if (ctrl->bufferPhyBase & (MV_AUDIO_BUFFER_MIN_ALIGN - 1))
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,bufferPhyBase is not"\
				   "\n aligned to 0x%x bytes\n",MV_AUDIO_BUFFER_MIN_ALIGN );

		return MV_FAIL;
	}

	if  ((ctrl->bufferSize <= audioBurstBytesNumGet(ctrl->burst))||
		(ctrl->bufferSize & (audioBurstBytesNumGet(ctrl->burst) - 1))||
		 (ctrl->bufferSize > AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX))
		 )
	{
		mvOsPrintf("mvAudioRecordControlSet: Error, bufferSize smaller"\
				   "\nthan or not multiple of 0x%x bytes or larger than"\
				   "\n 0x%x",
				   audioBurstBytesNumGet(ctrl->burst),
				   AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX));

		return MV_FAIL;
	}


	reg = MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit));
	reg &= ~(ARCR_RECORD_BURST_SIZE_MASK|ARCR_RECORDED_MONO_CHNL_MASK|
			 ARCR_RECORD_SAMPLE_SIZE_MASK);
	switch (ctrl->sampleSize)
	{
	case SAMPLE_16BIT:
	case SAMPLE_16BIT_NON_COMPACT:
	case SAMPLE_20BIT:
	case SAMPLE_24BIT:
	case SAMPLE_32BIT:
		reg |= ctrl->sampleSize << ARCR_RECORD_SAMPLE_SIZE_OFFS;
        break;
	default:
        mvOsPrintf("mvAudioRecordControlSet: Error ,illegal sampleSize %x\n",
				   ctrl->sampleSize );

		return MV_FAIL;
	}

	reg |= ctrl->burst << ARCR_RECORD_BURST_SIZE_OFFS;
	reg |= ctrl->monoChannel << ARCR_RECORDED_MONO_CHNL_OFFS;
	MV_REG_WRITE(MV_AUDIO_RECORD_CTRL_REG(unit), reg);

	if (ctrl->mono)
	{
		MV_REG_BIT_SET (MV_AUDIO_RECORD_CTRL_REG(unit), 
				ARCR_RECORD_MONO_MASK);
	}
	else
	{
		MV_REG_BIT_RESET (MV_AUDIO_RECORD_CTRL_REG(unit), 
				ARCR_RECORD_MONO_MASK);
	}

#ifndef MV_AUDIO_SKIP_WIN_DECODING
	if(mvAudioReplaceAddrWin(unit, MV_AUDIO_RECORD_WIN_NUM, ctrl->bufferPhyBase,
				ctrl->bufferSize) != MV_OK)
	{
		mvOsPrintf("mvAudioRecordControlSet: Failed to replace address decoding window.\n");
		return MV_FAIL;
	}
#endif

    	/* Set the interrupt byte count.                            */
    	reg = ctrl->intByteCount & ARBCI_BYTE_COUNT_MASK;
    	MV_REG_WRITE(MV_AUDIO_RECORD_BYTE_CNTR_INT_REG(unit), reg);

	MV_REG_WRITE(MV_AUDIO_RECORD_START_ADDR_REG(unit), ctrl->bufferPhyBase);
	MV_REG_WRITE(MV_AUDIO_RECORD_BUFF_SIZE_REG(unit),
				 AUDIO_SIZE_TO_REG(ctrl->bufferSize));

	return MV_OK;
}
Example #8
0
static int mv88fx_i2s_capture_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:
		/* FIXME: should check if busy before */
		mv88fx_snd_debug("");
		/* make sure the dma in pause state */
		mv88fx_snd_bitset(chip->base,
			MV_AUDIO_RECORD_CTRL_REG(chip->port),
			ARCR_RECORD_PAUSE_MASK);

		/* enable interrupt */
		mv88fx_snd_bitset(chip->base, MV_AUDIO_INT_MASK_REG(chip->port),
				  AICR_RECORD_BYTES_INT);

		/* enable dma */
		mv88fx_snd_debug("dig_mode=%x", audio_stream->dig_mode);
		if (audio_stream->dig_mode & I2S) {
			mv88fx_snd_debug("enable dma");
			mv88fx_snd_bitset(chip->base,
					  MV_AUDIO_RECORD_CTRL_REG(chip->port),
					  ARCR_RECORD_I2S_EN_MASK);
		}

		if (audio_stream->dig_mode & SPDIF) {
			mv88fx_snd_debug("enable spdif dma");
			mv88fx_snd_bitset(chip->base,
					  MV_AUDIO_RECORD_CTRL_REG(chip->port),
					  ARCR_RECORD_SPDIF_EN_MASK);
		}

		/* start dma */
		mv88fx_snd_bitreset(chip->base,
			MV_AUDIO_RECORD_CTRL_REG(chip->port),
			ARCR_RECORD_PAUSE_MASK);

		break;
	case SNDRV_PCM_TRIGGER_STOP:

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

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

		/* always stop both I2S and SPDIF */
		mv88fx_snd_bitreset(chip->base,
			MV_AUDIO_RECORD_CTRL_REG(chip->port),
			(ARCR_RECORD_I2S_EN_MASK | ARCR_RECORD_SPDIF_EN_MASK));

		/* FIXME: should check if busy after */

		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		mv88fx_snd_bitset(chip->base,
			MV_AUDIO_RECORD_CTRL_REG(chip->port),
			ARCR_RECORD_PAUSE_MASK);
		break;
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		mv88fx_snd_bitreset(chip->base,
			MV_AUDIO_RECORD_CTRL_REG(chip->port),
			ARCR_RECORD_PAUSE_MASK);

		break;
	default:
		result = -EINVAL;
		break;
	}
	spin_unlock(&chip->reg_lock);
	mv88fx_snd_debug("result=%d", result);
	return result;
}
Example #9
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;

}