Esempio n. 1
0
static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
			     struct rsnd_mod *mod)
{
	struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
	struct rsnd_mod *src = rsnd_io_to_mod_src(io);
	struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
	const u8 *entry = NULL;
	int id = rsnd_mod_id(mod);
	int size = 0;

	if (mod == ssi) {
		entry = gen2_id_table_ssiu;
		size = ARRAY_SIZE(gen2_id_table_ssiu);
	} else if (mod == src) {
		entry = gen2_id_table_scu;
		size = ARRAY_SIZE(gen2_id_table_scu);
	} else if (mod == dvc) {
		entry = gen2_id_table_cmd;
		size = ARRAY_SIZE(gen2_id_table_cmd);
	}

	if (!entry)
		return 0xFF;

	if (size <= id)
		return 0xFF;

	return entry[id];
}
Esempio n. 2
0
static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
			     struct rsnd_mod *mod)
{
	struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
	struct rsnd_mod *src = rsnd_io_to_mod_src(io);
	struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
	const u8 *entry = NULL;
	int id = rsnd_mod_id(mod);
	int size = 0;

	if (mod == ssi) {
		entry = gen2_id_table_ssiu;
		size = ARRAY_SIZE(gen2_id_table_ssiu);
	} else if (mod == src) {
		entry = gen2_id_table_scu;
		size = ARRAY_SIZE(gen2_id_table_scu);
	} else if (mod == dvc) {
		entry = gen2_id_table_cmd;
		size = ARRAY_SIZE(gen2_id_table_cmd);
	}

	if ((!entry) || (size <= id)) {
		struct device *dev = rsnd_priv_to_dev(rsnd_io_to_priv(io));

		dev_err(dev, "unknown connection (%s[%d])\n",
			rsnd_mod_name(mod), rsnd_mod_id(mod));

		/* use non-prohibited SRS number as error */
		return 0x00; /* SSI00 */
	}

	return entry[id];
}
Esempio n. 3
0
File: core.c Progetto: 3null/linux
static void rsnd_dma_of_path(struct rsnd_dma *dma,
			     int is_play,
			     struct rsnd_mod **mod_from,
			     struct rsnd_mod **mod_to)
{
	struct rsnd_mod *this = rsnd_dma_to_mod(dma);
	struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
	struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
	struct rsnd_mod *src = rsnd_io_to_mod_src(io);
	struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
	struct rsnd_mod *mod[MOD_MAX];
	int i, index;


	for (i = 0; i < MOD_MAX; i++)
		mod[i] = NULL;

	/*
	 * in play case...
	 *
	 * src -> dst
	 *
	 * mem -> SSI
	 * mem -> SRC -> SSI
	 * mem -> SRC -> DVC -> SSI
	 */
	mod[0] = NULL; /* for "mem" */
	index = 1;
	for (i = 1; i < MOD_MAX; i++) {
		if (!src) {
			mod[i] = ssi;
		} else if (!dvc) {
			mod[i] = src;
			src = NULL;
		} else {
			if ((!is_play) && (this == src))
				this = dvc;

			mod[i] = (is_play) ? src : dvc;
			i++;
			mod[i] = (is_play) ? dvc : src;
			src = NULL;
			dvc = NULL;
		}

		if (mod[i] == this)
			index = i;

		if (mod[i] == ssi)
			break;
	}

	if (is_play) {
		*mod_from = mod[index - 1];
		*mod_to   = mod[index];
	} else {
		*mod_from = mod[index];
		*mod_to   = mod[index - 1];
	}
}
Esempio n. 4
0
static dma_addr_t
rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
		   struct rsnd_mod *mod,
		   int is_play, int is_from)
{
	struct rsnd_priv *priv = rsnd_io_to_priv(io);
	struct device *dev = rsnd_priv_to_dev(priv);
	phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
	phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
	int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
	int use_src = !!rsnd_io_to_mod_src(io);
	int use_dvc = !!rsnd_io_to_mod_dvc(io);
	int id = rsnd_mod_id(mod);
	struct dma_addr {
		dma_addr_t out_addr;
		dma_addr_t in_addr;
	} dma_addrs[3][2][3] = {
		/* SRC */
		{{{ 0,				0 },
		  /* Capture */
		  { RDMA_SRC_O_N(src, id),	RDMA_SRC_I_P(src, id) },
		  { RDMA_CMD_O_N(src, id),	RDMA_SRC_I_P(src, id) } },
		 /* Playback */
		 {{ 0,				0, },
		  { RDMA_SRC_O_P(src, id),	RDMA_SRC_I_N(src, id) },
		  { RDMA_CMD_O_P(src, id),	RDMA_SRC_I_N(src, id) } }
		},
		/* SSI */
		/* Capture */
		{{{ RDMA_SSI_O_N(ssi, id),	0 },
		  { RDMA_SSIU_O_P(ssi, id),	0 },
		  { RDMA_SSIU_O_P(ssi, id),	0 } },
		 /* Playback */
		 {{ 0,				RDMA_SSI_I_N(ssi, id) },
		  { 0,				RDMA_SSIU_I_P(ssi, id) },
		  { 0,				RDMA_SSIU_I_P(ssi, id) } }
		},
		/* SSIU */
		/* Capture */
		{{{ RDMA_SSIU_O_N(ssi, id),	0 },
		  { RDMA_SSIU_O_P(ssi, id),	0 },
		  { RDMA_SSIU_O_P(ssi, id),	0 } },
		 /* Playback */
		 {{ 0,				RDMA_SSIU_I_N(ssi, id) },
		  { 0,				RDMA_SSIU_I_P(ssi, id) },
		  { 0,				RDMA_SSIU_I_P(ssi, id) } } },
	};

	/* it shouldn't happen */
	if (use_dvc && !use_src)
		dev_err(dev, "DVC is selected without SRC\n");

	/* use SSIU or SSI ? */
	if (is_ssi && rsnd_ssi_use_busif(io, mod))
		is_ssi++;

	return (is_from) ?
		dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
		dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
}
Esempio n. 5
0
static void rsnd_dma_of_name(struct rsnd_dma *dma,
			     int is_play, char *dma_name)
{
	struct rsnd_mod *this = rsnd_dma_to_mod(dma);
	struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
	struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
	struct rsnd_mod *src = rsnd_io_to_mod_src(io);
	struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
	struct rsnd_mod *mod[MOD_MAX];
	struct rsnd_mod *src_mod, *dst_mod;
	int i, index;


	for (i = 0; i < MOD_MAX; i++)
		mod[i] = NULL;

	/*
	 * in play case...
	 *
	 * src -> dst
	 *
	 * mem -> SSI
	 * mem -> SRC -> SSI
	 * mem -> SRC -> DVC -> SSI
	 */
	mod[0] = NULL; /* for "mem" */
	index = 1;
	for (i = 1; i < MOD_MAX; i++) {
		if (!src) {
			mod[i] = ssi;
		} else if (!dvc) {
			mod[i] = src;
			src = NULL;
		} else {
			mod[i] = dvc;
			dvc = NULL;
		}

		if (mod[i] == this)
			index = i;

		if (mod[i] == ssi)
			break;
	}

	if (is_play) {
		src_mod = mod[index - 1];
		dst_mod = mod[index];
	} else {
		src_mod = mod[index];
		dst_mod = mod[index + 1];
	}

	index = 0;
	index = _rsnd_dma_of_name(dma_name + index, src_mod);
	*(dma_name + index++) = '_';
	index = _rsnd_dma_of_name(dma_name + index, dst_mod);
}
Esempio n. 6
0
/*
 *		Gen1/Gen2 common functions
 */
int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
			   struct rsnd_dai *rdai,
			   struct rsnd_dai_stream *io)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
	int ssi_id = rsnd_mod_id(ssi_mod);
	int has_src = 0;

	/*
	 * SSI_MODE0
	 */
	if (info->dai_info) {
		has_src = !!src_mod;
	} else {
		struct rsnd_src *src = rsnd_mod_to_src(src_mod);
		has_src = rsnd_src_hpbif_is_enable(src);
	}

	rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
		      has_src ? 0 : (1 << ssi_id));

	/*
	 * SSI_MODE1
	 */
	if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
		int shift = -1;
		switch (ssi_id) {
		case 1:
			shift = 0;
			break;
		case 2:
			shift = 2;
			break;
		case 4:
			shift = 16;
			break;
		}

		if (shift >= 0)
			rsnd_mod_bset(ssi_mod, SSI_MODE1,
				      0x3 << shift,
				      rsnd_dai_is_clk_master(rdai) ?
				      0x2 << shift : 0x1 << shift);
	}

	return 0;
}
Esempio n. 7
0
File: ssi.c Progetto: 19Dan01/linux
int rsnd_ssi_use_busif(struct rsnd_mod *mod)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
	int use_busif = 0;

	if (!rsnd_ssi_is_dma_mode(mod))
		return 0;

	if (!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_NO_BUSIF))
		use_busif = 1;
	if (rsnd_io_to_mod_src(io))
		use_busif = 1;

	return use_busif;
}
Esempio n. 8
0
File: src.c Progetto: MaxChina/linux
/*
 *		Gen1/Gen2 common functions
 */
int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod,
			   struct rsnd_dai *rdai)
{
	struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod);
	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
	int ssi_id = rsnd_mod_id(ssi_mod);

	/*
	 * SSI_MODE0
	 */
	rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
		      src_mod ? 0 : (1 << ssi_id));

	/*
	 * SSI_MODE1
	 */
	if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
		int shift = -1;
		switch (ssi_id) {
		case 1:
			shift = 0;
			break;
		case 2:
			shift = 2;
			break;
		case 4:
			shift = 16;
			break;
		}

		if (shift >= 0)
			rsnd_mod_bset(ssi_mod, SSI_MODE1,
				      0x3 << shift,
				      rsnd_dai_is_clk_master(rdai) ?
				      0x2 << shift : 0x1 << shift);
	}

	return 0;
}
Esempio n. 9
0
unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
				   struct rsnd_dai_stream *io,
				   struct snd_pcm_runtime *runtime)
{
	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
	struct rsnd_src *src;
	unsigned int rate = 0;

	if (src_mod) {
		src = rsnd_mod_to_src(src_mod);

		/*
		 * return convert rate if SRC is used,
		 * otherwise, return runtime->rate as usual
		 */
		rate = rsnd_src_convert_rate(src);
	}

	if (!rate)
		rate = runtime->rate;

	return rate;
}
Esempio n. 10
0
	if (!mod)
		return 0;

	return rsnd_gen2_dma_addr(io, mod, is_play, is_from);
}

#define MOD_MAX (RSND_MOD_MAX + 1) /* +Memory */
static void rsnd_dma_of_path(struct rsnd_mod *this,
			     struct rsnd_dai_stream *io,
			     int is_play,
			     struct rsnd_mod **mod_from,
			     struct rsnd_mod **mod_to)
{
	struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
	struct rsnd_mod *src = rsnd_io_to_mod_src(io);
	struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
	struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
	struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
	struct rsnd_mod *mod[MOD_MAX];
	struct rsnd_mod *mod_start, *mod_end;
	struct rsnd_priv *priv = rsnd_mod_to_priv(this);
	struct device *dev = rsnd_priv_to_dev(priv);
	int nr, i, idx;

	if (!ssi)
		return;

	nr = 0;
	for (i = 0; i < MOD_MAX; i++) {
		mod[i] = NULL;
Esempio n. 11
0
File: mix.c Progetto: krzk/linux
static int rsnd_mix_pcm_new(struct rsnd_mod *mod,
			    struct rsnd_dai_stream *io,
			    struct snd_soc_pcm_runtime *rtd)
{
	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_mix *mix = rsnd_mod_to_mix(mod);
	struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
	struct rsnd_kctrl_cfg_s *volume;
	int ret;

	switch (rsnd_mod_id(src_mod)) {
	case 3:
	case 6:	/* MDBAR */
		volume = &mix->volumeA;
		rsnd_flags_set(mix, HAS_VOLA);
		break;
	case 4:
	case 9:	/* MDBBR */
		volume = &mix->volumeB;
		rsnd_flags_set(mix, HAS_VOLB);
		break;
	case 0:
	case 1:	/* MDBCR */
		volume = &mix->volumeC;
		rsnd_flags_set(mix, HAS_VOLC);
		break;
	case 2:
	case 5:	/* MDBDR */
		volume = &mix->volumeD;
		rsnd_flags_set(mix, HAS_VOLD);
		break;
	default:
		dev_err(dev, "unknown SRC is connected\n");
		return -EINVAL;
	}

	/* Volume */
	ret = rsnd_kctrl_new_s(mod, io, rtd,
			       "MIX Playback Volume",
			       rsnd_kctrl_accept_anytime,
			       rsnd_mix_volume_update,
			       volume, VOL_MAX);
	if (ret < 0)
		return ret;
	rsnd_kctrl_vals(*volume) = VOL_MAX;

	if (rsnd_flags_has(mix, ONCE_KCTRL_INITIALIZED))
		return ret;

	/* Ramp */
	ret = rsnd_kctrl_new_s(mod, io, rtd,
			       "MIX Ramp Switch",
			       rsnd_kctrl_accept_anytime,
			       rsnd_mix_volume_update,
			       &mix->ren, 1);
	if (ret < 0)
		return ret;

	ret = rsnd_kctrl_new_e(mod, io, rtd,
			       "MIX Ramp Up Rate",
			       rsnd_kctrl_accept_anytime,
			       rsnd_mix_volume_update,
			       &mix->rup,
			       volume_ramp_rate,
			       VOLUME_RAMP_MAX_MIX);
	if (ret < 0)
		return ret;

	ret = rsnd_kctrl_new_e(mod, io, rtd,
			       "MIX Ramp Down Rate",
			       rsnd_kctrl_accept_anytime,
			       rsnd_mix_volume_update,
			       &mix->rdw,
			       volume_ramp_rate,
			       VOLUME_RAMP_MAX_MIX);

	rsnd_flags_set(mix, ONCE_KCTRL_INITIALIZED);

	return ret;
}