/*
 *		Gen1
 */
static int rsnd_gen1_path_init(struct rsnd_priv *priv,
			       struct rsnd_dai *rdai,
			       struct rsnd_dai_stream *io)
{
	struct rsnd_mod *mod;
	int ret;
	int id;

	/*
	 * Gen1 is created by SRU/SSI, and this SRU is base module of
	 * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU)
	 *
	 * Easy image is..
	 *	Gen1 SRU = Gen2 SCU + SSIU + etc
	 *
	 * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
	 * using fixed path.
	 *
	 * Then, SSI id = SCU id here
	 */

	/* get SSI's ID */
	mod = rsnd_ssi_mod_get_frm_dai(priv,
				       rsnd_dai_id(priv, rdai),
				       rsnd_dai_is_play(rdai, io));
	id = rsnd_mod_id(mod);

	/* SSI */
	mod = rsnd_ssi_mod_get(priv, id);
	ret = rsnd_dai_connect(rdai, mod, io);
	if (ret < 0)
		return ret;

	/* SCU */
	mod = rsnd_scu_mod_get(priv, id);
	ret = rsnd_dai_connect(rdai, mod, io);

	return ret;
}
Beispiel #2
0
static void rsnd_ssi_mode_set(struct rsnd_priv *priv,
			      struct rsnd_dai *rdai,
			      struct rsnd_ssi *ssi)
{
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_mod *scu;
	struct rsnd_ssiu *ssiu = rsnd_ssi_to_ssiu(ssi);
	int id = rsnd_mod_id(&ssi->mod);
	u32 flags;
	u32 val;

	scu   = rsnd_scu_mod_get(priv, rsnd_mod_id(&ssi->mod));

	/*
	 * SSI_MODE0
	 */

	/* see also BUSIF_MODE */
	if (rsnd_scu_hpbif_is_enable(scu)) {
		ssiu->ssi_mode0 &= ~(1 << id);
		dev_dbg(dev, "SSI%d uses DEPENDENT mode\n", id);
	} else {
		ssiu->ssi_mode0 |= (1 << id);
		dev_dbg(dev, "SSI%d uses INDEPENDENT mode\n", id);
	}

	/*
	 * SSI_MODE1
	 */
#define ssi_parent_set(p, sync, adg, ext)		\
	do {						\
		ssi->parent = ssiu->ssi + p;		\
		if (rsnd_rdai_is_clk_master(rdai))	\
			val = adg;			\
		else					\
			val = ext;			\
		if (flags & RSND_SSI_SYNC)		\
			val |= sync;			\
	} while (0)

	flags = rsnd_ssi_mode_flags(ssi);
	if (flags & RSND_SSI_CLK_PIN_SHARE) {

		val = 0;
		switch (id) {
		case 1:
			ssi_parent_set(0, (1 << 4), (0x2 << 0), (0x1 << 0));
			break;
		case 2:
			ssi_parent_set(0, (1 << 4), (0x2 << 2), (0x1 << 2));
			break;
		case 4:
			ssi_parent_set(3, (1 << 20), (0x2 << 16), (0x1 << 16));
			break;
		case 8:
			ssi_parent_set(7, 0, 0, 0);
			break;
		}

		ssiu->ssi_mode1 |= val;
	}

	rsnd_mod_write(&ssi->mod, SSI_MODE0, ssiu->ssi_mode0);
	rsnd_mod_write(&ssi->mod, SSI_MODE1, ssiu->ssi_mode1);
}