sound/soc/samsung/arndale.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/samsung/arndale.c
Extension
.c
Size
5760 bytes
Lines
218
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+
//
// Copyright (c) 2014, Insignal Co., Ltd.
//
//  Author: Claude <claude@insginal.co.kr>

#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/clk.h>

#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>

#include "../codecs/wm8994.h"
#include "i2s.h"

static int arndale_rt5631_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 snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
	int rfs, ret;
	unsigned long rclk;

	rfs = 256;

	rclk = params_rate(params) * rfs;

	ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
					0, SND_SOC_CLOCK_OUT);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
					0, SND_SOC_CLOCK_OUT);

	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(codec_dai, 0, rclk, SND_SOC_CLOCK_OUT);
	if (ret < 0)
		return ret;

	return 0;
}

static const struct snd_soc_ops arndale_rt5631_ops = {
	.hw_params = arndale_rt5631_hw_params,
};

static int arndale_wm1811_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 snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
	unsigned int rfs, rclk;

	/* Ensure AIF1CLK is >= 3 MHz for optimal performance */
	if (params_width(params) == 24)
		rfs = 384;
	else if (params_rate(params) == 8000 || params_rate(params) == 11025)
		rfs = 512;
	else
		rfs = 256;

	rclk = params_rate(params) * rfs;

	/*
	 * We add 1 to the frequency value to ensure proper EPLL setting
	 * for each audio sampling rate (see epll_24mhz_tbl in drivers/clk/
	 * samsung/clk-exynos5250.c for list of available EPLL rates).
	 * The CODEC uses clk API and the value will be rounded hence the MCLK1
	 * clock's frequency will still be exact multiple of the sample rate.
	 */
	return snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1,
					rclk + 1, SND_SOC_CLOCK_IN);
}

static const struct snd_soc_ops arndale_wm1811_ops = {
	.hw_params = arndale_wm1811_hw_params,
};

SND_SOC_DAILINK_DEFS(rt5631_hifi,
	DAILINK_COMP_ARRAY(COMP_EMPTY()),
	DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "rt5631-aif1")),
	DAILINK_COMP_ARRAY(COMP_EMPTY()));

Annotation

Implementation Notes