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;
}
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);
}
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);
}
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);
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
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 int tegra30_dam_show(struct seq_file *s, void *unused)
{
#define REG(r) { r, #r }
	static const struct {
		int offset;
		const char *name;
	} regs[] = {
		REG(TEGRA30_DAM_CTRL),
		REG(TEGRA30_DAM_CLIP),
		REG(TEGRA30_DAM_CLIP_THRESHOLD),
		REG(TEGRA30_DAM_AUDIOCIF_OUT_CTRL),
		REG(TEGRA30_DAM_CH0_CTRL),
		REG(TEGRA30_DAM_CH0_CONV),
		REG(TEGRA30_DAM_AUDIOCIF_CH0_CTRL),
		REG(TEGRA30_DAM_CH1_CTRL),
		REG(TEGRA30_DAM_CH1_CONV),
		REG(TEGRA30_DAM_AUDIOCIF_CH1_CTRL),
	};
#undef REG

	struct tegra30_dam_context *dam = s->private;
	int i;

	tegra30_ahub_enable_clocks();
	clk_enable(dam->dam_clk);

	for (i = 0; i < ARRAY_SIZE(regs); i++) {
		u32 val = tegra30_dam_readl(dam, regs[i].offset);
		seq_printf(s, "%s = %08x\n", regs[i].name, val);
	}

	clk_disable(dam->dam_clk);
	tegra30_ahub_disable_clocks();

	return 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;
		}
	}
}