sound/soc/tegra/tegra210_adx.c

Source file repositories/reference/linux-study-clean/sound/soc/tegra/tegra210_adx.c

File Facts

System
Linux kernel
Corpus path
sound/soc/tegra/tegra210_adx.c
Extension
.c
Size
22248 bytes
Lines
760
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-only
// SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES.
// All rights reserved.
//
// tegra210_adx.c - Tegra210 ADX driver

#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>

#include "tegra210_adx.h"
#include "tegra_cif.h"

static const struct reg_default tegra210_adx_reg_defaults[] = {
	{ TEGRA210_ADX_RX_INT_MASK, 0x00000001},
	{ TEGRA210_ADX_RX_CIF_CTRL, 0x00007000},
	{ TEGRA210_ADX_TX_INT_MASK, 0x0000000f },
	{ TEGRA210_ADX_TX1_CIF_CTRL, 0x00007000},
	{ TEGRA210_ADX_TX2_CIF_CTRL, 0x00007000},
	{ TEGRA210_ADX_TX3_CIF_CTRL, 0x00007000},
	{ TEGRA210_ADX_TX4_CIF_CTRL, 0x00007000},
	{ TEGRA210_ADX_CG, 0x1},
	{ TEGRA210_ADX_CFG_RAM_CTRL, 0x00004000},
};

static const struct reg_default tegra264_adx_reg_defaults[] = {
	{ TEGRA210_ADX_RX_INT_MASK, 0x00000001},
	{ TEGRA210_ADX_RX_CIF_CTRL, 0x00003800},
	{ TEGRA210_ADX_TX_INT_MASK, 0x0000000f },
	{ TEGRA210_ADX_TX1_CIF_CTRL, 0x00003800},
	{ TEGRA210_ADX_TX2_CIF_CTRL, 0x00003800},
	{ TEGRA210_ADX_TX3_CIF_CTRL, 0x00003800},
	{ TEGRA210_ADX_TX4_CIF_CTRL, 0x00003800},
	{ TEGRA210_ADX_CG, 0x1},
	{ TEGRA264_ADX_CFG_RAM_CTRL, 0x00004000},
};

static void tegra210_adx_write_map_ram(struct tegra210_adx *adx)
{
	const unsigned int bits_per_mask = BITS_PER_TYPE(*adx->byte_mask);
	int i;

	memset(adx->byte_mask, 0,
	       adx->soc_data->byte_mask_size * sizeof(*adx->byte_mask));

	regmap_write(adx->regmap, TEGRA210_ADX_CFG_RAM_CTRL +
			adx->soc_data->cya_offset,
		     TEGRA210_ADX_CFG_RAM_CTRL_SEQ_ACCESS_EN |
		     TEGRA210_ADX_CFG_RAM_CTRL_ADDR_INIT_EN |
		     TEGRA210_ADX_CFG_RAM_CTRL_RW_WRITE);

	for (i = 0; i < adx->soc_data->ram_depth; i++) {
		u32 word = 0;
		int b;

		for (b = 0; b < TEGRA_ADX_SLOTS_PER_WORD; b++) {
			unsigned int slot = i * TEGRA_ADX_SLOTS_PER_WORD + b;
			u16 val = adx->map[slot];

			if (val >= 256)
				continue;

			word |= (u32)val << (b * BITS_PER_BYTE);
			adx->byte_mask[slot / bits_per_mask] |=
				1U << (slot % bits_per_mask);
		}
		regmap_write(adx->regmap, TEGRA210_ADX_CFG_RAM_DATA +
				adx->soc_data->cya_offset, word);
	}

	for (i = 0; i < adx->soc_data->byte_mask_size; i++)
		regmap_write(adx->regmap,
			     TEGRA210_ADX_IN_BYTE_EN0 + (i * TEGRA210_ADX_AUDIOCIF_CH_STRIDE),
			     adx->byte_mask[i]);
}

static int tegra210_adx_startup(struct snd_pcm_substream *substream,
				struct snd_soc_dai *dai)
{

Annotation

Implementation Notes