Exemple #1
0
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;
}
Exemple #2
0
/*
 *		ssi mod function
 */
struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
					  int dai_id, int is_play)
{
	struct rsnd_ssi *ssi;
	int i, has_play;

	is_play = !!is_play;

	for_each_rsnd_ssi(ssi, priv, i) {
		if (rsnd_ssi_dai_id(ssi) != dai_id)
			continue;

		has_play = !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY);

		if (is_play == has_play)
			return &ssi->mod;
	}

	return NULL;
}
Exemple #3
0
int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE);
}
Exemple #4
0
int rsnd_ssi_probe(struct platform_device *pdev,
		   struct rcar_snd_info *info,
		   struct rsnd_priv *priv)
{
	struct rsnd_ssi_platform_info *pinfo;
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_mod_ops *ops;
	struct clk *clk;
	struct rsnd_ssiu *ssiu;
	struct rsnd_ssi *ssi;
	char name[RSND_SSI_NAME_SIZE];
	int i, nr, ret;

	/*
	 *	init SSI
	 */
	nr	= info->ssi_info_nr;
	ssiu	= devm_kzalloc(dev, sizeof(*ssiu) + (sizeof(*ssi) * nr),
			       GFP_KERNEL);
	if (!ssiu) {
		dev_err(dev, "SSI allocate failed\n");
		return -ENOMEM;
	}

	priv->ssiu	= ssiu;
	ssiu->ssi	= (struct rsnd_ssi *)(ssiu + 1);
	ssiu->ssi_nr	= nr;

	for_each_rsnd_ssi(ssi, priv, i) {
		pinfo = &info->ssi_info[i];

		snprintf(name, RSND_SSI_NAME_SIZE, "ssi.%d", i);

		clk = devm_clk_get(dev, name);
		if (IS_ERR(clk))
			return PTR_ERR(clk);

		ssi->info	= pinfo;
		ssi->clk	= clk;

		ops = &rsnd_ssi_non_ops;

		/*
		 * SSI DMA case
		 */
		if (pinfo->dma_id > 0) {
			ret = rsnd_dma_init(
				priv, rsnd_mod_to_dma(&ssi->mod),
				(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY),
				pinfo->dma_id,
				rsnd_ssi_dma_inquiry,
				rsnd_ssi_dma_complete);
			if (ret < 0)
				dev_info(dev, "SSI DMA failed. try PIO transter\n");
			else
				ops	= &rsnd_ssi_dma_ops;

			dev_dbg(dev, "SSI%d use DMA transfer\n", i);
		}

		/*
		 * SSI PIO case
		 */
		if (!rsnd_ssi_dma_available(ssi) &&
		     rsnd_ssi_pio_available(ssi)) {
			ret = devm_request_irq(dev, pinfo->pio_irq,
					       &rsnd_ssi_pio_interrupt,
					       IRQF_SHARED,
					       dev_name(dev), ssi);
			if (ret) {
				dev_err(dev, "SSI request interrupt failed\n");
				return ret;
			}

			ops	= &rsnd_ssi_pio_ops;

			dev_dbg(dev, "SSI%d use PIO transfer\n", i);
		}

		rsnd_mod_init(priv, &ssi->mod, ops, i);
	}
Exemple #5
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);
}
Exemple #6
0
int rsnd_ssi_is_play(struct rsnd_mod *mod)
{
	struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);

	return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY);
}