sound/soc/samsung/lowland.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/samsung/lowland.c
Extension
.c
Size
5451 bytes
Lines
214
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

// SPDX-License-Identifier: GPL-2.0+
//
// Lowland audio support
//
// Copyright 2011 Wolfson Microelectronics

#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <linux/module.h>

#include "../codecs/wm5100.h"
#include "../codecs/wm9081.h"

#define MCLK1_RATE (44100 * 512)
#define CLKOUT_RATE (44100 * 256)

static struct snd_soc_jack lowland_headset;

/* Headset jack detection DAPM pins */
static struct snd_soc_jack_pin lowland_headset_pins[] = {
	{
		.pin = "Headphone",
		.mask = SND_JACK_HEADPHONE,
	},
	{
		.pin = "Headset Mic",
		.mask = SND_JACK_MICROPHONE,
	},
	{
		.pin = "Line Out",
		.mask = SND_JACK_LINEOUT,
	},
};

static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
	int ret;

	ret = snd_soc_component_set_sysclk(component, WM5100_CLK_SYSCLK,
				       WM5100_CLKSRC_MCLK1, MCLK1_RATE,
				       SND_SOC_CLOCK_IN);
	if (ret < 0) {
		pr_err("Failed to set SYSCLK clock source: %d\n", ret);
		return ret;
	}

	/* Clock OPCLK, used by the other audio components. */
	ret = snd_soc_component_set_sysclk(component, WM5100_CLK_OPCLK, 0,
				       CLKOUT_RATE, 0);
	if (ret < 0) {
		pr_err("Failed to set OPCLK rate: %d\n", ret);
		return ret;
	}

	ret = snd_soc_card_jack_new_pins(rtd->card, "Headset",
					 SND_JACK_LINEOUT | SND_JACK_HEADSET |
					 SND_JACK_BTN_0,
					 &lowland_headset, lowland_headset_pins,
					 ARRAY_SIZE(lowland_headset_pins));
	if (ret)
		return ret;

	wm5100_detect(component, &lowland_headset);

	return 0;
}

static int lowland_wm9081_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card);

	snd_soc_dapm_disable_pin(dapm, "LINEOUT");

	/* At any time the WM9081 is active it will have this clock */
	return snd_soc_component_set_sysclk(component, WM9081_SYSCLK_MCLK, 0,
					CLKOUT_RATE, 0);
}

static const struct snd_soc_pcm_stream sub_params = {
	.formats = SNDRV_PCM_FMTBIT_S32_LE,
	.rate_min = 44100,
	.rate_max = 44100,
	.channels_min = 2,
	.channels_max = 2,
};

SND_SOC_DAILINK_DEFS(cpu,

Annotation

Implementation Notes