sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c

Source file repositories/reference/linux-study-clean/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c

File Facts

System
Linux kernel
Corpus path
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
Extension
.c
Size
9182 bytes
Lines
323
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (IS_ERR(afe_priv->base_ck[i])) {
			dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
			return PTR_ERR(afe_priv->base_ck[i]);
		}
	}

	i2s_num = min(afe_priv->soc->i2s_num, MT2701_BASE_CLK_NUM);
	/* Get I2S related clocks */
	for (i = 0; i < i2s_num; i++) {
		struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
		struct clk *i2s_ck;
		char name[13];

		snprintf(name, sizeof(name), "i2s%d_src_sel", i);
		i2s_path->sel_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_path->sel_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_path->sel_ck);
		}

		snprintf(name, sizeof(name), "i2s%d_src_div", i);
		i2s_path->div_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_path->div_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_path->div_ck);
		}

		snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
		i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_path->mclk_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_path->mclk_ck);
		}

		snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
		i2s_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_ck);
		}
		i2s_path->hop_ck[SNDRV_PCM_STREAM_PLAYBACK] = i2s_ck;

		snprintf(name, sizeof(name), "i2si%d_hop_ck", i);
		i2s_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_ck);
		}
		i2s_path->hop_ck[SNDRV_PCM_STREAM_CAPTURE] = i2s_ck;

		snprintf(name, sizeof(name), "asrc%d_out_ck", i);
		i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
		if (IS_ERR(i2s_path->asrco_ck)) {
			dev_err(afe->dev, "failed to get %s\n", name);
			return PTR_ERR(i2s_path->asrco_ck);
		}
	}

	/* Some platforms may support BT path */
	afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
	if (IS_ERR(afe_priv->mrgif_ck)) {
		if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		afe_priv->mrgif_ck = NULL;
	}

	/*
	 * Optional HDMI audio clocks. Platforms that do not wire up the
	 * HDMI output (e.g. MT2701 devkits using only the I2S BE DAIs)
	 * may omit these; in that case the HDMI BE DAI simply cannot be
	 * enabled, but the rest of the AFE still probes.
	 */
	afe_priv->hadds2pll_ck = devm_clk_get_optional(afe->dev, "hadds2pll_294m");
	if (IS_ERR(afe_priv->hadds2pll_ck))
		return PTR_ERR(afe_priv->hadds2pll_ck);

	afe_priv->audio_hdmi_ck = devm_clk_get_optional(afe->dev, "audio_hdmi_pd");
	if (IS_ERR(afe_priv->audio_hdmi_ck))
		return PTR_ERR(afe_priv->audio_hdmi_ck);

	afe_priv->audio_spdf_ck = devm_clk_get_optional(afe->dev, "audio_spdf_pd");
	if (IS_ERR(afe_priv->audio_spdf_ck))
		return PTR_ERR(afe_priv->audio_spdf_ck);

	afe_priv->audio_apll_ck = devm_clk_get_optional(afe->dev, "audio_apll_pd");
	if (IS_ERR(afe_priv->audio_apll_ck))
		return PTR_ERR(afe_priv->audio_apll_ck);

	return 0;

Annotation

Implementation Notes