sound/soc/intel/boards/sof_wm8804.c

Source file repositories/reference/linux-study-clean/sound/soc/intel/boards/sof_wm8804.c

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/boards/sof_wm8804.c
Extension
.c
Size
7384 bytes
Lines
303
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 sof_card_private {
	struct gpio_desc *gpio_44;
	struct gpio_desc *gpio_48;
	int sample_rate;
};

#define SOF_WM8804_UP2_QUIRK			BIT(0)

static unsigned long sof_wm8804_quirk;

static int sof_wm8804_quirk_cb(const struct dmi_system_id *id)
{
	sof_wm8804_quirk = (unsigned long)id->driver_data;
	return 1;
}

static const struct dmi_system_id sof_wm8804_quirk_table[] = {
	{
		.callback = sof_wm8804_quirk_cb,
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "AAEON"),
			DMI_MATCH(DMI_PRODUCT_NAME, "UP-APL01"),
		},
		.driver_data = (void *)SOF_WM8804_UP2_QUIRK,
	},
	{}
};

static int sof_wm8804_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
	struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
	struct snd_soc_component *codec = codec_dai->component;
	const int sysclk = 27000000; /* This is fixed on this board */
	int samplerate;
	long mclk_freq;
	int mclk_div;
	int sampling_freq;
	bool clk_44;
	int ret;

	samplerate = params_rate(params);
	if (samplerate == ctx->sample_rate)
		return 0;

	ctx->sample_rate = 0;

	if (samplerate <= 96000) {
		mclk_freq = samplerate * 256;
		mclk_div = WM8804_MCLKDIV_256FS;
	} else {
		mclk_freq = samplerate * 128;
		mclk_div = WM8804_MCLKDIV_128FS;
	}

	switch (samplerate) {
	case 32000:
		sampling_freq = 0x03;
		break;
	case 44100:
		sampling_freq = 0x00;
		break;
	case 48000:
		sampling_freq = 0x02;
		break;
	case 88200:
		sampling_freq = 0x08;
		break;
	case 96000:
		sampling_freq = 0x0a;
		break;
	case 176400:
		sampling_freq = 0x0c;
		break;
	case 192000:
		sampling_freq = 0x0e;
		break;
	default:
		dev_err(rtd->card->dev,
			"unsupported samplerate %d\n", samplerate);
		return -EINVAL;
	}

	if (samplerate % 16000)
		clk_44 = true; /* use 44.1 kHz root frequency */
	else
		clk_44 = false;

Annotation

Implementation Notes