sound/soc/codecs/pcm3060.c

Source file repositories/reference/linux-study-clean/sound/soc/codecs/pcm3060.c

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/pcm3060.c
Extension
.c
Size
8330 bytes
Lines
348
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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
//
// PCM3060 codec driver
//
// Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com>

#include <linux/module.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>

#include "pcm3060.h"

/* dai */

static int pcm3060_set_sysclk(struct snd_soc_dai *dai, int clk_id,
			      unsigned int freq, int dir)
{
	struct snd_soc_component *comp = dai->component;
	struct pcm3060_priv *priv = snd_soc_component_get_drvdata(comp);
	unsigned int reg;
	unsigned int val;

	if (dir != SND_SOC_CLOCK_IN) {
		dev_err(comp->dev, "unsupported sysclock dir: %d\n", dir);
		return -EINVAL;
	}

	switch (clk_id) {
	case PCM3060_CLK_DEF:
		val = 0;
		break;

	case PCM3060_CLK1:
		val = (dai->id == PCM3060_DAI_ID_DAC ? PCM3060_REG_CSEL : 0);
		break;

	case PCM3060_CLK2:
		val = (dai->id == PCM3060_DAI_ID_DAC ? 0 : PCM3060_REG_CSEL);
		break;

	default:
		dev_err(comp->dev, "unsupported sysclock id: %d\n", clk_id);
		return -EINVAL;
	}

	if (dai->id == PCM3060_DAI_ID_DAC)
		reg = PCM3060_REG67;
	else
		reg = PCM3060_REG72;

	regmap_update_bits(priv->regmap, reg, PCM3060_REG_CSEL, val);

	priv->dai[dai->id].sclk_freq = freq;

	return 0;
}

static int pcm3060_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	struct snd_soc_component *comp = dai->component;
	struct pcm3060_priv *priv = snd_soc_component_get_drvdata(comp);
	unsigned int reg;
	unsigned int val;

	if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
		dev_err(comp->dev, "unsupported DAI polarity: 0x%x\n", fmt);
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_CBP_CFP:
		priv->dai[dai->id].is_provider = true;
		break;
	case SND_SOC_DAIFMT_CBC_CFC:
		priv->dai[dai->id].is_provider = false;
		break;
	default:
		dev_err(comp->dev, "unsupported DAI mode: 0x%x\n", fmt);
		return -EINVAL;
	}

	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		val = PCM3060_REG_FMT_I2S;
		break;
	case SND_SOC_DAIFMT_RIGHT_J:
		val = PCM3060_REG_FMT_RJ;
		break;
	case SND_SOC_DAIFMT_LEFT_J:

Annotation

Implementation Notes