Exemple #1
0
static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
		int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec);
	struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);

	switch (clk_id) {
	case ADAU17X1_CLK_SRC_MCLK:
	case ADAU17X1_CLK_SRC_PLL:
		break;
	default:
		return -EINVAL;
	}

	adau->sysclk = freq;

	if (adau->clk_src != clk_id) {
		if (clk_id == ADAU17X1_CLK_SRC_PLL) {
			snd_soc_dapm_add_routes(dapm,
				&adau17x1_dapm_pll_route, 1);
		} else {
			snd_soc_dapm_del_routes(dapm,
				&adau17x1_dapm_pll_route, 1);
		}
	}

	adau->clk_src = clk_id;

	return 0;
}
Exemple #2
0
static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
				  int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_codec *codec = dai->codec;
	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
	struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
	struct snd_soc_dapm_route routes[2];

	switch (clk_id) {
	case ARIZONA_CLK_SYSCLK:
	case ARIZONA_CLK_ASYNCCLK:
		break;
	default:
		return -EINVAL;
	}

	if (clk_id == dai_priv->clk)
		return 0;

	if (dai->active) {
		dev_err(codec->dev, "Can't change clock on active DAI %d\n",
			dai->id);
		return -EBUSY;
	}

	memset(&routes, 0, sizeof(routes));
	routes[0].sink = dai->driver->capture.stream_name;
	routes[1].sink = dai->driver->playback.stream_name;

	switch (clk_id) {
	case ARIZONA_CLK_SYSCLK:
		routes[0].source = arizona_dai_clk_str(dai_priv->clk);
		routes[1].source = arizona_dai_clk_str(dai_priv->clk);
		snd_soc_dapm_del_routes(&codec->dapm, routes,
					ARRAY_SIZE(routes));
		break;
	default:
		break;
	}

	switch (clk_id) {
	case ARIZONA_CLK_ASYNCCLK:
		routes[0].source = arizona_dai_clk_str(clk_id);
		routes[1].source = arizona_dai_clk_str(clk_id);
		snd_soc_dapm_add_routes(&codec->dapm, routes,
					ARRAY_SIZE(routes));
		break;
	default:
		break;
	}

	dai_priv->clk = clk_id;

	return snd_soc_dapm_sync(&codec->dapm);
}
Exemple #3
0
static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
		int clk_id, unsigned int freq, int dir)
{
	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(dai->component);
	struct adau *adau = snd_soc_component_get_drvdata(dai->component);
	bool is_pll;
	bool was_pll;

	switch (clk_id) {
	case ADAU17X1_CLK_SRC_MCLK:
		is_pll = false;
		break;
	case ADAU17X1_CLK_SRC_PLL_AUTO:
		if (!adau->mclk)
			return -EINVAL;
		/* Fall-through */
	case ADAU17X1_CLK_SRC_PLL:
		is_pll = true;
		break;
	default:
		return -EINVAL;
	}

	switch (adau->clk_src) {
	case ADAU17X1_CLK_SRC_MCLK:
		was_pll = false;
		break;
	case ADAU17X1_CLK_SRC_PLL:
	case ADAU17X1_CLK_SRC_PLL_AUTO:
		was_pll = true;
		break;
	default:
		return -EINVAL;
	}

	adau->sysclk = freq;

	if (is_pll != was_pll) {
		if (is_pll) {
			snd_soc_dapm_add_routes(dapm,
				&adau17x1_dapm_pll_route, 1);
		} else {
			snd_soc_dapm_del_routes(dapm,
				&adau17x1_dapm_pll_route, 1);
		}
	}

	adau->clk_src = clk_id;

	return 0;
}
Exemple #4
0
static int cs35l33_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
				unsigned int rx_mask, int slots, int slot_width)
{
	struct snd_soc_component *component = dai->component;
	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
	struct cs35l33_private *priv = snd_soc_component_get_drvdata(component);
	unsigned int reg, bit_pos, i;
	int slot, slot_num;

	if (slot_width != 8)
		return -EINVAL;

	/* scan rx_mask for aud slot */
	slot = ffs(rx_mask) - 1;
	if (slot >= 0) {
		regmap_update_bits(priv->regmap, CS35L33_RX_AUD,
			CS35L33_X_LOC, slot);
		dev_dbg(component->dev, "Audio starts from slots %d", slot);
	}

	/*
	 * scan tx_mask: vmon(2 slots); imon (2 slots);
	 * vpmon (1 slot) vbstmon (1 slot)
	 */
	slot = ffs(tx_mask) - 1;
	slot_num = 0;

	for (i = 0; i < 2 ; i++) {
		/* disable vpmon/vbstmon: enable later if set in tx_mask */
		regmap_update_bits(priv->regmap, CS35L33_TX_VPMON + i,
			CS35L33_X_STATE | CS35L33_X_LOC, CS35L33_X_STATE
			| CS35L33_X_LOC);
	}

	/* disconnect {vp,vbst}_mon routes: eanble later if set in tx_mask*/
	snd_soc_dapm_del_routes(dapm, cs35l33_vp_vbst_mon_route,
		ARRAY_SIZE(cs35l33_vp_vbst_mon_route));

	while (slot >= 0) {
		/* configure VMON_TX_LOC */
		if (slot_num == 0) {
			regmap_update_bits(priv->regmap, CS35L33_TX_VMON,
				CS35L33_X_STATE | CS35L33_X_LOC, slot);
			dev_dbg(component->dev, "VMON enabled in slots %d-%d",
				slot, slot + 1);
		}

		/* configure IMON_TX_LOC */
		if (slot_num == 3) {
			regmap_update_bits(priv->regmap, CS35L33_TX_IMON,
				CS35L33_X_STATE | CS35L33_X_LOC, slot);
			dev_dbg(component->dev, "IMON enabled in slots %d-%d",
				slot, slot + 1);
		}

		/* configure VPMON_TX_LOC */
		if (slot_num == 4) {
			regmap_update_bits(priv->regmap, CS35L33_TX_VPMON,
				CS35L33_X_STATE | CS35L33_X_LOC, slot);
			snd_soc_dapm_add_routes(dapm,
				&cs35l33_vp_vbst_mon_route[0], 2);
			dev_dbg(component->dev, "VPMON enabled in slots %d", slot);
		}

		/* configure VBSTMON_TX_LOC */
		if (slot_num == 5) {
			regmap_update_bits(priv->regmap, CS35L33_TX_VBSTMON,
				CS35L33_X_STATE | CS35L33_X_LOC, slot);
			snd_soc_dapm_add_routes(dapm,
				&cs35l33_vp_vbst_mon_route[2], 2);
			dev_dbg(component->dev,
				"VBSTMON enabled in slots %d", slot);
		}

		/* Enable the relevant tx slot */
		reg = CS35L33_TX_EN4 - (slot/8);
		bit_pos = slot - ((slot / 8) * (8));
		regmap_update_bits(priv->regmap, reg,
			1 << bit_pos, 1 << bit_pos);

		tx_mask &= ~(1 << slot);
		slot = ffs(tx_mask) - 1;
		slot_num++;
	}

	return 0;
}