sound/soc/samsung/bells.c

Source file repositories/reference/linux-study-clean/sound/soc/samsung/bells.c

File Facts

System
Linux kernel
Corpus path
sound/soc/samsung/bells.c
Extension
.c
Size
12954 bytes
Lines
498
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

struct bells_drvdata {
	int sysclk_rate;
	int asyncclk_rate;
};

static struct bells_drvdata wm2200_drvdata = {
	.sysclk_rate = 22579200,
};

static struct bells_drvdata wm5102_drvdata = {
	.sysclk_rate = 45158400,
	.asyncclk_rate = 49152000,
};

static struct bells_drvdata wm5110_drvdata = {
	.sysclk_rate = 135475200,
	.asyncclk_rate = 147456000,
};

static int bells_set_bias_level(struct snd_soc_card *card,
				struct snd_soc_dapm_context *dapm,
				enum snd_soc_bias_level level)
{
	struct snd_soc_pcm_runtime *rtd;
	struct snd_soc_dai *codec_dai;
	struct snd_soc_component *component;
	struct bells_drvdata *bells = card->drvdata;
	int ret;

	rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[DAI_DSP_CODEC]);
	codec_dai = snd_soc_rtd_to_codec(rtd, 0);
	component = codec_dai->component;

	if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev)
		return 0;

	switch (level) {
	case SND_SOC_BIAS_PREPARE:
		if (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_STANDBY)
			break;

		ret = snd_soc_component_set_pll(component, WM5102_FLL1,
					    ARIZONA_FLL_SRC_MCLK1,
					    MCLK_RATE,
					    bells->sysclk_rate);
		if (ret < 0)
			pr_err("Failed to start FLL: %d\n", ret);

		if (bells->asyncclk_rate) {
			ret = snd_soc_component_set_pll(component, WM5102_FLL2,
						    ARIZONA_FLL_SRC_AIF2BCLK,
						    BCLK2_RATE,
						    bells->asyncclk_rate);
			if (ret < 0)
				pr_err("Failed to start FLL: %d\n", ret);
		}
		break;

	default:
		break;
	}

	return 0;
}

static int bells_set_bias_level_post(struct snd_soc_card *card,
				     struct snd_soc_dapm_context *dapm,
				     enum snd_soc_bias_level level)
{
	struct snd_soc_pcm_runtime *rtd;
	struct snd_soc_dai *codec_dai;
	struct snd_soc_component *component;
	struct bells_drvdata *bells = card->drvdata;
	int ret;

	rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[DAI_DSP_CODEC]);
	codec_dai = snd_soc_rtd_to_codec(rtd, 0);
	component = codec_dai->component;

	if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev)
		return 0;

	switch (level) {
	case SND_SOC_BIAS_STANDBY:
		ret = snd_soc_component_set_pll(component, WM5102_FLL1, 0, 0, 0);
		if (ret < 0) {
			pr_err("Failed to stop FLL: %d\n", ret);
			return ret;
		}

Annotation

Implementation Notes