static void tegra30_dam_write_coeff_ram(struct tegra30_dam_context *dam, int fsin, int fsout)
{
	u32 val;
	int i, *coefRam = NULL;

	tegra30_dam_writel(dam, 0x00002000,
			TEGRA30_DAM_AUDIORAMCTL_DAM_CTRL_0);

	switch(fsin) {
		case TEGRA30_AUDIO_SAMPLERATE_8000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_48000)
				coefRam = coefRam8To48;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_44100)
				coefRam = coefRam8To44;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				coefRam = coefRam8To16;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_16000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_48000)
				coefRam = coefRam16To48;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_44100)
				coefRam = coefRam16To44;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				coefRam = coefRam16To8;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_44100:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				coefRam = coefRam44To8;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				coefRam = coefRam44To16;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_48000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				coefRam = coefRam48To8;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				coefRam = coefRam48To16;
			break;

		default:
			break;
	}

	tegra30_dam_writel(dam, 0x00005000,
			TEGRA30_DAM_AUDIORAMCTL_DAM_CTRL_0);

	if (coefRam) {
		for (i = 0; i < 64; i++) {
			val = coefRam[i];
			tegra30_dam_writel(dam, val,
				TEGRA30_DAM_AUDIORAMCTL_DAM_DATA_0);
		}
	}
}
static void tegra30_dam_set_biquad_fixed_coef(struct tegra30_dam_context *dam)
{
	u32 val = TEGRA30_DAM_CH0_BIQUAD_FIXED_COEF_0_VAL;

	tegra30_dam_writel(dam, val,
			TEGRA30_DAM_CH0_BIQUAD_FIXED_COEF_0);
}
static void tegra30_dam_set_input_samplerate(struct tegra30_dam_context *dam,
	int fsin)
{
	u32 val;

	val = tegra30_dam_readl(dam, TEGRA30_DAM_CH0_CTRL);
	val &= ~TEGRA30_DAM_CH0_CTRL_FSIN_MASK;

	switch (fsin) {
	case TEGRA30_AUDIO_SAMPLERATE_8000:
		val |= TEGRA30_DAM_CH0_CTRL_FSIN_FS8;
		break;
	case TEGRA30_AUDIO_SAMPLERATE_16000:
		val |= TEGRA30_DAM_CH0_CTRL_FSIN_FS16;
		break;
	case TEGRA30_AUDIO_SAMPLERATE_44100:
		val |= TEGRA30_DAM_CH0_CTRL_FSIN_FS44;
		break;
	case TEGRA30_AUDIO_SAMPLERATE_48000:
		val |= TEGRA30_DAM_CH0_CTRL_FSIN_FS48;
		break;
	default:
		break;
	}

	tegra30_dam_writel(dam, val, TEGRA30_DAM_CH0_CTRL);
}
int tegra30_dam_set_acif_stereo_conv(int ifc, int chtype, int conv)
{
	unsigned int reg;
	unsigned int val = 0;

	if (ifc >= TEGRA30_NR_DAM_IFC)
		return -EINVAL;

	if ((conv != TEGRA30_CIF_STEREOCONV_CH0) &&
		(conv != TEGRA30_CIF_STEREOCONV_CH1) &&
		(conv != TEGRA30_CIF_STEREOCONV_AVG))
			return -EINVAL;

	switch (chtype) {
	case dam_ch_out:
		reg = TEGRA30_DAM_AUDIOCIF_OUT_CTRL;
		break;
	case dam_ch_in0:
		reg = TEGRA30_DAM_AUDIOCIF_CH0_CTRL;
		break;
	case dam_ch_in1:
		reg = TEGRA30_DAM_AUDIOCIF_CH1_CTRL;
		break;
	default:
		return -EINVAL;
	}

	val = tegra30_dam_readl(dams_cont_info[ifc], reg);
	val &= ~TEGRA30_CIF_STEREOCONV_MASK;
	val |= conv;

	tegra30_dam_writel(dams_cont_info[ifc], val, reg);

	return 0;
}
int tegra30_dam_set_acif(int ifc, int chid, unsigned int audio_channels,
	unsigned int audio_bits, unsigned int client_channels,
	unsigned int client_bits)
{
	unsigned int reg;
	unsigned int value = 0;

	if (ifc >= TEGRA30_NR_DAM_IFC)
		return -EINVAL;

#ifndef CONFIG_ARCH_TEGRA_3x_SOC
	/*ch0 takes input as mono always*/
	if ((chid == dam_ch_in0) &&
		((client_channels != 1)))
		return -EINVAL;
	/*as per dam spec file chout is fixed to 32 bits*/
	/*so accept ch0, ch1 and chout as 32bit always*/
	if (client_bits != 32)
		return -EINVAL;
#else
	/*ch0 takes input as mono/16bit always*/
	if ((chid == dam_ch_in0) &&
		((client_channels != 1) || (client_bits != 16)))
		return -EINVAL;
#endif

	value |= TEGRA30_AUDIOCIF_CTRL_MONO_CONV_COPY;
	value |= TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_AVG;
	value |= (audio_channels-1)  <<
				TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT;
	value |= (((audio_bits>>2)-1) <<
				TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT);
	value |= (client_channels-1) <<
				TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT;
	value |= (((client_bits>>2)-1) <<
				TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT);

	switch (chid) {
	case dam_ch_out:
		value |= TEGRA30_CIF_DIRECTION_TX;
		reg = TEGRA30_DAM_AUDIOCIF_OUT_CTRL;
		break;
	case dam_ch_in0:
		value |= TEGRA30_CIF_DIRECTION_RX;
		reg = TEGRA30_DAM_AUDIOCIF_CH0_CTRL;
		break;
	case dam_ch_in1:
		value |= TEGRA30_CIF_DIRECTION_RX;
		reg = TEGRA30_DAM_AUDIOCIF_CH1_CTRL;
		break;
	default:
		return -EINVAL;
	}

	tegra30_dam_writel(dams_cont_info[ifc], value, reg);

	return 0;
}
static void tegra30_dam_enable_coeff_ram(struct tegra30_dam_context *dam)
{
	u32 val;

	val = tegra30_dam_readl(dam, TEGRA30_DAM_CH0_CTRL);
	val |= TEGRA30_DAM_CH0_CTRL_COEFF_RAM_ENABLE;

	tegra30_dam_writel(dam, val, TEGRA30_DAM_CH0_CTRL);
}
static void tegra30_dam_ch0_set_step(struct tegra30_dam_context *dam, int step)
{
	u32 val;

	val = tegra30_dam_readl(dam, TEGRA30_DAM_CH0_CTRL);
	val &= ~TEGRA30_DAM_CH0_CTRL_STEP_MASK;
	val |= step << TEGRA30_DAM_CH0_CTRL_STEP_SHIFT;
	tegra30_dam_writel(dam, val, TEGRA30_DAM_CH0_CTRL);
}
void tegra30_dam_enable_clip_counter(struct tegra30_dam_context *dam, int on)
{
	u32 val;

	val = tegra30_dam_readl(dam, TEGRA30_DAM_CLIP);
	val &= ~TEGRA30_DAM_CLIP_COUNTER_ENABLE;
	val |= on ?  TEGRA30_DAM_CLIP_COUNTER_ENABLE : 0;
	tegra30_dam_writel(dam, val, TEGRA30_DAM_CLIP);
}
int tegra30_dam_set_gain(int ifc, int chid, int gain)
{
	if (ifc >= TEGRA30_NR_DAM_IFC)
		return -EINVAL;

	switch (chid) {
	case dam_ch_in0:
		tegra30_dam_writel(dams_cont_info[ifc], gain,
			TEGRA30_DAM_CH0_CONV);
		break;
	case dam_ch_in1:
		tegra30_dam_writel(dams_cont_info[ifc], gain,
			TEGRA30_DAM_CH1_CONV);
		break;
	default:
		break;
	}

	return 0;
}
void tegra30_dam_ch1_set_datasync(int ifc, int datasync)
{
	u32 val;
	struct tegra30_dam_context *dam = NULL;

	dam =  dams_cont_info[ifc];
	val = tegra30_dam_readl(dam, TEGRA30_DAM_CH1_CTRL);
	val &= ~TEGRA30_DAM_CH1_CTRL_DATA_SYNC_MASK;
	val |= datasync << TEGRA30_DAM_DATA_SYNC_SHIFT;
	tegra30_dam_writel(dam, val, TEGRA30_DAM_CH1_CTRL);
}
示例#11
0
int tegra30_dam_soft_reset(int ifc)
{
	int dcnt = 10;
	u32 val;
	struct tegra30_dam_context *dam = NULL;

	dam =  dams_cont_info[ifc];
	val = tegra30_dam_readl(dam, TEGRA30_DAM_CTRL);
	val |= TEGRA30_DAM_CTRL_SOFT_RESET_ENABLE;
	tegra30_dam_writel(dam, val, TEGRA30_DAM_CTRL);

	while ((tegra30_dam_readl(dam, TEGRA30_DAM_CTRL) &
			TEGRA30_DAM_CTRL_SOFT_RESET_ENABLE) && dcnt--)
		udelay(100);

	/* Restore reg_ctrl to ensure if a concurrent playback/capture
	   session was active it continues after SOFT_RESET */
	val &= ~TEGRA30_DAM_CTRL_SOFT_RESET_ENABLE;
	tegra30_dam_writel(dam, val, TEGRA30_DAM_CTRL);

	return (dcnt < 0) ? -ETIMEDOUT : 0;
}
示例#12
0
void tegra30_dam_enable_stereo_mixing(int ifc, int on)
{
	u32 val;

	if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
		return;

	val = tegra30_dam_readl(dams_cont_info[ifc], TEGRA30_DAM_CTRL);
	if (on)
		val |= TEGRA30_DAM_CTRL_STEREO_MIXING_ENABLE;
	else
		val &= ~TEGRA30_DAM_CTRL_STEREO_MIXING_ENABLE;
	tegra30_dam_writel(dams_cont_info[ifc], val, TEGRA30_DAM_CTRL);
}
static void tegra30_dam_set_filter_stages(struct tegra30_dam_context *dam, int fsin, int fsout)
{
	u32 val;
	int filt_stages = 0;

	val = tegra30_dam_readl(dam, TEGRA30_DAM_CH0_CTRL);

	switch(fsin) {
		case TEGRA30_AUDIO_SAMPLERATE_8000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_48000)
				filt_stages = 1;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_44100)
				filt_stages = 2;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				filt_stages = 0;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_16000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_48000)
				filt_stages = 0;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_44100)
				filt_stages = 3;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				filt_stages = 0;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_44100:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				filt_stages = 2;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				filt_stages = 2;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_48000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				filt_stages = 1;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				filt_stages = 0;
			break;

		default:
			break;
	}

	val |= filt_stages << TEGRA30_DAM_CH0_CTRL_FILT_STAGES_SHIFT;

	tegra30_dam_writel(dam, val, TEGRA30_DAM_CH0_CTRL);
}
static void tegra30_dam_set_farrow_param(struct tegra30_dam_context *dam, int fsin, int fsout)
{
	u32 val = TEGRA30_FARROW_PARAM_RESET;

	switch(fsin) {
		case TEGRA30_AUDIO_SAMPLERATE_8000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_48000)
				val = TEGRA30_FARROW_PARAM_1;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_44100)
				val = TEGRA30_FARROW_PARAM_2;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				val = TEGRA30_FARROW_PARAM_1;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_16000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_48000)
				val = TEGRA30_FARROW_PARAM_1;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_44100)
				val = TEGRA30_FARROW_PARAM_2;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				val = TEGRA30_FARROW_PARAM_1;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_44100:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				val = TEGRA30_FARROW_PARAM_3;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				val = TEGRA30_FARROW_PARAM_3;
			break;

		case TEGRA30_AUDIO_SAMPLERATE_48000:
			if (fsout == TEGRA30_AUDIO_SAMPLERATE_8000)
				val = TEGRA30_FARROW_PARAM_1;
			else if (fsout == TEGRA30_AUDIO_SAMPLERATE_16000)
				val = TEGRA30_FARROW_PARAM_1;
			break;

		default:
			break;
	}

	tegra30_dam_writel(dam, val,
			TEGRA30_DAM_FARROW_PARAM_0);
}
void tegra30_dam_enable(int ifc, int on, int chid)
{
	u32 old_val, val, enreg;
	u32 old_val_dam, val_dam;
	int dcnt = 10;
	struct tegra30_dam_context *dam;

	if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC) ||
	    (chid < dam_ch_in0) || (chid > dam_ch_in1))
		return;

	dam = dams_cont_info[ifc];

	if (chid == dam_ch_in0)
		enreg = TEGRA30_DAM_CH0_CTRL;
	else
		enreg = TEGRA30_DAM_CH1_CTRL;

	old_val = val = tegra30_dam_readl(dam, enreg);

	if (on) {
		if (!dam->ch_enable_refcnt[chid]++)
			val |= TEGRA30_DAM_CH0_CTRL_EN;
	} else if (dam->ch_enable_refcnt[chid]) {
		dam->ch_enable_refcnt[chid]--;
		if (!dam->ch_enable_refcnt[chid])
			val &= ~TEGRA30_DAM_CH0_CTRL_EN;
	}

	old_val_dam = val_dam = tegra30_dam_readl(dam, TEGRA30_DAM_CTRL);

	if (dam->ch_enable_refcnt[dam_ch_in0] ||
		dam->ch_enable_refcnt[dam_ch_in1])
		val_dam |= TEGRA30_DAM_CTRL_DAM_EN;
	else
		val_dam &= ~TEGRA30_DAM_CTRL_DAM_EN;

	if (val != old_val) {
		tegra30_dam_writel(dam, val, enreg);

		if (!on) {
			if (chid == dam_ch_in0) {
				while (!tegra30_ahub_dam_ch0_is_empty(ifc)
					&& dcnt--)
					udelay(100);

				dcnt = 10;
			}
			else {
				while (!tegra30_ahub_dam_ch1_is_empty(ifc)
					&& dcnt--)
					udelay(100);

				dcnt = 10;
			}
		}
	}

	if (old_val_dam != val_dam) {
		tegra30_dam_writel(dam, val_dam, TEGRA30_DAM_CTRL);
		if (!on) {
			while (!tegra30_ahub_dam_tx_is_empty(ifc) && dcnt--)
				udelay(100);

			dcnt = 10;
		}
	}
}