sound/soc/meson/axg-toddr.c

Source file repositories/reference/linux-study-clean/sound/soc/meson/axg-toddr.c

File Facts

System
Linux kernel
Corpus path
sound/soc/meson/axg-toddr.c
Extension
.c
Size
11089 bytes
Lines
354
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 OR MIT)
//
// Copyright (c) 2018 BayLibre, SAS.
// Author: Jerome Brunet <jbrunet@baylibre.com>

/* This driver implements the frontend capture DAI of AXG based SoCs */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/regmap.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>

#include "axg-fifo.h"

#define CTRL0_TODDR_SEL_RESAMPLE	BIT(30)
#define CTRL0_TODDR_EXT_SIGNED		BIT(29)
#define CTRL0_TODDR_PP_MODE		BIT(28)
#define CTRL0_TODDR_SYNC_CH		BIT(27)
#define CTRL0_TODDR_TYPE		GENMASK(15, 13)
#define CTRL0_TODDR_MSB_POS		GENMASK(12, 8)
#define CTRL0_TODDR_LSB_POS		GENMASK(7, 3)
#define CTRL1_TODDR_FORCE_FINISH	BIT(25)
#define CTRL1_SEL_SHIFT			28

#define TODDR_MSB_POS	31

static int axg_toddr_pcm_new(struct snd_soc_pcm_runtime *rtd,
			     struct snd_soc_dai *dai)
{
	return axg_fifo_pcm_new(rtd, SNDRV_PCM_STREAM_CAPTURE);
}

static int g12a_toddr_dai_prepare(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai)
{
	struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);

	/* Reset the write pointer to the FIFO_INIT_ADDR */
	regmap_update_bits(fifo->map, FIFO_CTRL1,
			   CTRL1_TODDR_FORCE_FINISH, 0);
	regmap_update_bits(fifo->map, FIFO_CTRL1,
			   CTRL1_TODDR_FORCE_FINISH, CTRL1_TODDR_FORCE_FINISH);
	regmap_update_bits(fifo->map, FIFO_CTRL1,
			   CTRL1_TODDR_FORCE_FINISH, 0);

	return 0;
}

static int axg_toddr_dai_hw_params(struct snd_pcm_substream *substream,
				   struct snd_pcm_hw_params *params,
				   struct snd_soc_dai *dai)
{
	struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
	unsigned int type, width;

	switch (params_physical_width(params)) {
	case 8:
		type = 0; /* 8 samples of 8 bits */
		break;
	case 16:
		type = 2; /* 4 samples of 16 bits - right justified */
		break;
	case 32:
		type = 4; /* 2 samples of 32 bits - right justified */
		break;
	default:
		return -EINVAL;
	}

	width = params_width(params);

	regmap_update_bits(fifo->map, FIFO_CTRL0,
			   CTRL0_TODDR_TYPE |
			   CTRL0_TODDR_MSB_POS |
			   CTRL0_TODDR_LSB_POS,
			   FIELD_PREP(CTRL0_TODDR_TYPE, type) |
			   FIELD_PREP(CTRL0_TODDR_MSB_POS, TODDR_MSB_POS) |
			   FIELD_PREP(CTRL0_TODDR_LSB_POS, TODDR_MSB_POS - (width - 1)));

	return 0;
}

static int axg_toddr_dai_startup(struct snd_pcm_substream *substream,
				 struct snd_soc_dai *dai)
{
	struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);

Annotation

Implementation Notes