mirror of https://github.com/torvalds/linux.git
ASoC: tegra: AMX: Add Tegra264 support
Add Tegra264 AMX support with following changes: - Add soc_data for Tegra264-specific variations - Tegra264 AMX supports 32 output channels, hence update the capture DAI channels_max parameter and CIF configuration API. - Register offsets and default values are updated to align with Tegra264. - Add 128 byte map controls for Tegra264 to accommodate each byte per channel (32channels x 32bits). Signed-off-by: Sheetal <sheetal@nvidia.com> Link: https://patch.msgid.link/20250512051747.1026770-9-sheetal@nvidia.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
b3354438d8
commit
fd509c6f8e
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES.
|
// SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES.
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// tegra210_amx.c - Tegra210 AMX driver
|
// tegra210_amx.c - Tegra210 AMX driver
|
||||||
|
|
@ -46,21 +46,35 @@ static const struct reg_default tegra210_amx_reg_defaults[] = {
|
||||||
{ TEGRA210_AMX_CFG_RAM_CTRL, 0x00004000},
|
{ TEGRA210_AMX_CFG_RAM_CTRL, 0x00004000},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct reg_default tegra264_amx_reg_defaults[] = {
|
||||||
|
{ TEGRA210_AMX_RX_INT_MASK, 0x0000000f},
|
||||||
|
{ TEGRA210_AMX_RX1_CIF_CTRL, 0x00003800},
|
||||||
|
{ TEGRA210_AMX_RX2_CIF_CTRL, 0x00003800},
|
||||||
|
{ TEGRA210_AMX_RX3_CIF_CTRL, 0x00003800},
|
||||||
|
{ TEGRA210_AMX_RX4_CIF_CTRL, 0x00003800},
|
||||||
|
{ TEGRA210_AMX_TX_INT_MASK, 0x00000001},
|
||||||
|
{ TEGRA210_AMX_TX_CIF_CTRL, 0x00003800},
|
||||||
|
{ TEGRA210_AMX_CG, 0x1},
|
||||||
|
{ TEGRA264_AMX_CFG_RAM_CTRL, 0x00004000},
|
||||||
|
};
|
||||||
|
|
||||||
static void tegra210_amx_write_map_ram(struct tegra210_amx *amx)
|
static void tegra210_amx_write_map_ram(struct tegra210_amx *amx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_CTRL,
|
regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_CTRL + amx->soc_data->reg_offset,
|
||||||
TEGRA210_AMX_CFG_RAM_CTRL_SEQ_ACCESS_EN |
|
TEGRA210_AMX_CFG_RAM_CTRL_SEQ_ACCESS_EN |
|
||||||
TEGRA210_AMX_CFG_RAM_CTRL_ADDR_INIT_EN |
|
TEGRA210_AMX_CFG_RAM_CTRL_ADDR_INIT_EN |
|
||||||
TEGRA210_AMX_CFG_RAM_CTRL_RW_WRITE);
|
TEGRA210_AMX_CFG_RAM_CTRL_RW_WRITE);
|
||||||
|
|
||||||
for (i = 0; i < TEGRA210_AMX_RAM_DEPTH; i++)
|
for (i = 0; i < amx->soc_data->ram_depth; i++)
|
||||||
regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_DATA,
|
regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_DATA + amx->soc_data->reg_offset,
|
||||||
amx->map[i]);
|
amx->map[i]);
|
||||||
|
|
||||||
regmap_write(amx->regmap, TEGRA210_AMX_OUT_BYTE_EN0, amx->byte_mask[0]);
|
for (i = 0; i < amx->soc_data->byte_mask_size; i++)
|
||||||
regmap_write(amx->regmap, TEGRA210_AMX_OUT_BYTE_EN1, amx->byte_mask[1]);
|
regmap_write(amx->regmap,
|
||||||
|
TEGRA210_AMX_OUT_BYTE_EN0 + (i * TEGRA210_AMX_AUDIOCIF_CH_STRIDE),
|
||||||
|
amx->byte_mask[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tegra210_amx_startup(struct snd_pcm_substream *substream,
|
static int tegra210_amx_startup(struct snd_pcm_substream *substream,
|
||||||
|
|
@ -157,6 +171,9 @@ static int tegra210_amx_set_audio_cif(struct snd_soc_dai *dai,
|
||||||
cif_conf.audio_bits = audio_bits;
|
cif_conf.audio_bits = audio_bits;
|
||||||
cif_conf.client_bits = audio_bits;
|
cif_conf.client_bits = audio_bits;
|
||||||
|
|
||||||
|
if (amx->soc_data->max_ch == TEGRA264_AMX_MAX_CHANNEL)
|
||||||
|
tegra264_set_cif(amx->regmap, reg, &cif_conf);
|
||||||
|
else
|
||||||
tegra_set_cif(amx->regmap, reg, &cif_conf);
|
tegra_set_cif(amx->regmap, reg, &cif_conf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -170,9 +187,10 @@ static int tegra210_amx_in_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
|
||||||
if (amx->soc_data->auto_disable) {
|
if (amx->soc_data->auto_disable) {
|
||||||
regmap_write(amx->regmap,
|
regmap_write(amx->regmap,
|
||||||
AMX_CH_REG(dai->id, TEGRA194_AMX_RX1_FRAME_PERIOD),
|
AMX_CH_REG(dai->id, TEGRA194_AMX_RX1_FRAME_PERIOD +
|
||||||
|
amx->soc_data->reg_offset),
|
||||||
TEGRA194_MAX_FRAME_IDLE_COUNT);
|
TEGRA194_MAX_FRAME_IDLE_COUNT);
|
||||||
regmap_write(amx->regmap, TEGRA210_AMX_CYA, 1);
|
regmap_write(amx->regmap, TEGRA210_AMX_CYA + amx->soc_data->reg_offset, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tegra210_amx_set_audio_cif(dai, params,
|
return tegra210_amx_set_audio_cif(dai, params,
|
||||||
|
|
@ -194,14 +212,11 @@ static int tegra210_amx_get_byte_map(struct snd_kcontrol *kcontrol,
|
||||||
struct soc_mixer_control *mc =
|
struct soc_mixer_control *mc =
|
||||||
(struct soc_mixer_control *)kcontrol->private_value;
|
(struct soc_mixer_control *)kcontrol->private_value;
|
||||||
struct tegra210_amx *amx = snd_soc_component_get_drvdata(cmpnt);
|
struct tegra210_amx *amx = snd_soc_component_get_drvdata(cmpnt);
|
||||||
unsigned char *bytes_map = (unsigned char *)&amx->map;
|
unsigned char *bytes_map = (unsigned char *)amx->map;
|
||||||
int reg = mc->reg;
|
int reg = mc->reg;
|
||||||
int enabled;
|
int enabled;
|
||||||
|
|
||||||
if (reg > 31)
|
enabled = amx->byte_mask[reg / 32] & (1 << (reg % 32));
|
||||||
enabled = amx->byte_mask[1] & (1 << (reg - 32));
|
|
||||||
else
|
|
||||||
enabled = amx->byte_mask[0] & (1 << reg);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Simplify this logic to just return from bytes_map[]
|
* TODO: Simplify this logic to just return from bytes_map[]
|
||||||
|
|
@ -228,7 +243,7 @@ static int tegra210_amx_put_byte_map(struct snd_kcontrol *kcontrol,
|
||||||
(struct soc_mixer_control *)kcontrol->private_value;
|
(struct soc_mixer_control *)kcontrol->private_value;
|
||||||
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
|
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
|
||||||
struct tegra210_amx *amx = snd_soc_component_get_drvdata(cmpnt);
|
struct tegra210_amx *amx = snd_soc_component_get_drvdata(cmpnt);
|
||||||
unsigned char *bytes_map = (unsigned char *)&amx->map;
|
unsigned char *bytes_map = (unsigned char *)amx->map;
|
||||||
int reg = mc->reg;
|
int reg = mc->reg;
|
||||||
int value = ucontrol->value.integer.value[0];
|
int value = ucontrol->value.integer.value[0];
|
||||||
unsigned int mask_val = amx->byte_mask[reg / 32];
|
unsigned int mask_val = amx->byte_mask[reg / 32];
|
||||||
|
|
@ -418,7 +433,90 @@ static struct snd_kcontrol_new tegra210_amx_controls[] = {
|
||||||
TEGRA210_AMX_BYTE_MAP_CTRL(63),
|
TEGRA210_AMX_BYTE_MAP_CTRL(63),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct snd_kcontrol_new tegra264_amx_controls[] = {
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(64),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(65),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(66),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(67),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(68),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(69),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(70),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(71),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(72),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(73),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(74),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(75),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(76),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(77),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(78),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(79),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(80),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(81),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(82),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(83),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(84),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(85),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(86),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(87),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(88),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(89),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(90),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(91),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(92),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(93),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(94),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(95),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(96),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(97),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(98),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(99),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(100),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(101),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(102),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(103),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(104),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(105),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(106),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(107),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(108),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(109),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(110),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(111),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(112),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(113),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(114),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(115),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(116),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(117),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(118),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(119),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(120),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(121),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(122),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(123),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(124),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(125),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(126),
|
||||||
|
TEGRA210_AMX_BYTE_MAP_CTRL(127),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tegra210_amx_component_probe(struct snd_soc_component *component)
|
||||||
|
{
|
||||||
|
struct tegra210_amx *amx = snd_soc_component_get_drvdata(component);
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (amx->soc_data->num_controls) {
|
||||||
|
err = snd_soc_add_component_controls(component, amx->soc_data->controls,
|
||||||
|
amx->soc_data->num_controls);
|
||||||
|
if (err)
|
||||||
|
dev_err(component->dev, "can't add AMX controls, err: %d\n", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct snd_soc_component_driver tegra210_amx_cmpnt = {
|
static const struct snd_soc_component_driver tegra210_amx_cmpnt = {
|
||||||
|
.probe = tegra210_amx_component_probe,
|
||||||
.dapm_widgets = tegra210_amx_widgets,
|
.dapm_widgets = tegra210_amx_widgets,
|
||||||
.num_dapm_widgets = ARRAY_SIZE(tegra210_amx_widgets),
|
.num_dapm_widgets = ARRAY_SIZE(tegra210_amx_widgets),
|
||||||
.dapm_routes = tegra210_amx_routes,
|
.dapm_routes = tegra210_amx_routes,
|
||||||
|
|
@ -450,6 +548,22 @@ static bool tegra194_amx_wr_reg(struct device *dev, unsigned int reg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool tegra264_amx_wr_reg(struct device *dev,
|
||||||
|
unsigned int reg)
|
||||||
|
{
|
||||||
|
switch (reg) {
|
||||||
|
case TEGRA210_AMX_RX_INT_MASK ... TEGRA210_AMX_RX4_CIF_CTRL:
|
||||||
|
case TEGRA210_AMX_TX_INT_MASK ... TEGRA210_AMX_TX_CIF_CTRL:
|
||||||
|
case TEGRA210_AMX_ENABLE ... TEGRA210_AMX_CG:
|
||||||
|
case TEGRA210_AMX_CTRL ... TEGRA264_AMX_STREAMS_AUTO_DISABLE:
|
||||||
|
case TEGRA264_AMX_CFG_RAM_CTRL ... TEGRA264_AMX_CFG_RAM_DATA:
|
||||||
|
case TEGRA264_AMX_RX1_FRAME_PERIOD ... TEGRA264_AMX_RX4_FRAME_PERIOD:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool tegra210_amx_rd_reg(struct device *dev, unsigned int reg)
|
static bool tegra210_amx_rd_reg(struct device *dev, unsigned int reg)
|
||||||
{
|
{
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
|
|
@ -470,6 +584,21 @@ static bool tegra194_amx_rd_reg(struct device *dev, unsigned int reg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool tegra264_amx_rd_reg(struct device *dev,
|
||||||
|
unsigned int reg)
|
||||||
|
{
|
||||||
|
switch (reg) {
|
||||||
|
case TEGRA210_AMX_RX_STATUS ... TEGRA210_AMX_RX4_CIF_CTRL:
|
||||||
|
case TEGRA210_AMX_TX_STATUS ... TEGRA210_AMX_TX_CIF_CTRL:
|
||||||
|
case TEGRA210_AMX_ENABLE ... TEGRA210_AMX_INT_STATUS:
|
||||||
|
case TEGRA210_AMX_CTRL ... TEGRA264_AMX_CFG_RAM_DATA:
|
||||||
|
case TEGRA264_AMX_RX1_FRAME_PERIOD ... TEGRA264_AMX_RX4_FRAME_PERIOD:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool tegra210_amx_volatile_reg(struct device *dev, unsigned int reg)
|
static bool tegra210_amx_volatile_reg(struct device *dev, unsigned int reg)
|
||||||
{
|
{
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
|
|
@ -492,6 +621,29 @@ static bool tegra210_amx_volatile_reg(struct device *dev, unsigned int reg)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool tegra264_amx_volatile_reg(struct device *dev,
|
||||||
|
unsigned int reg)
|
||||||
|
{
|
||||||
|
switch (reg) {
|
||||||
|
case TEGRA210_AMX_RX_STATUS:
|
||||||
|
case TEGRA210_AMX_RX_INT_STATUS:
|
||||||
|
case TEGRA210_AMX_RX_INT_SET:
|
||||||
|
case TEGRA210_AMX_TX_STATUS:
|
||||||
|
case TEGRA210_AMX_TX_INT_STATUS:
|
||||||
|
case TEGRA210_AMX_TX_INT_SET:
|
||||||
|
case TEGRA210_AMX_SOFT_RESET:
|
||||||
|
case TEGRA210_AMX_STATUS:
|
||||||
|
case TEGRA210_AMX_INT_STATUS:
|
||||||
|
case TEGRA264_AMX_CFG_RAM_CTRL:
|
||||||
|
case TEGRA264_AMX_CFG_RAM_DATA:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct regmap_config tegra210_amx_regmap_config = {
|
static const struct regmap_config tegra210_amx_regmap_config = {
|
||||||
.reg_bits = 32,
|
.reg_bits = 32,
|
||||||
.reg_stride = 4,
|
.reg_stride = 4,
|
||||||
|
|
@ -518,18 +670,51 @@ static const struct regmap_config tegra194_amx_regmap_config = {
|
||||||
.cache_type = REGCACHE_FLAT,
|
.cache_type = REGCACHE_FLAT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct regmap_config tegra264_amx_regmap_config = {
|
||||||
|
.reg_bits = 32,
|
||||||
|
.reg_stride = 4,
|
||||||
|
.val_bits = 32,
|
||||||
|
.max_register = TEGRA264_AMX_RX4_LAST_FRAME_PERIOD,
|
||||||
|
.writeable_reg = tegra264_amx_wr_reg,
|
||||||
|
.readable_reg = tegra264_amx_rd_reg,
|
||||||
|
.volatile_reg = tegra264_amx_volatile_reg,
|
||||||
|
.reg_defaults = tegra264_amx_reg_defaults,
|
||||||
|
.num_reg_defaults = ARRAY_SIZE(tegra264_amx_reg_defaults),
|
||||||
|
.cache_type = REGCACHE_FLAT,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct tegra210_amx_soc_data soc_data_tegra210 = {
|
static const struct tegra210_amx_soc_data soc_data_tegra210 = {
|
||||||
.regmap_conf = &tegra210_amx_regmap_config,
|
.regmap_conf = &tegra210_amx_regmap_config,
|
||||||
|
.max_ch = TEGRA210_AMX_MAX_CHANNEL,
|
||||||
|
.ram_depth = TEGRA210_AMX_RAM_DEPTH,
|
||||||
|
.byte_mask_size = TEGRA210_AMX_BYTE_MASK_COUNT,
|
||||||
|
.reg_offset = TEGRA210_AMX_AUTO_DISABLE_OFFSET,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct tegra210_amx_soc_data soc_data_tegra194 = {
|
static const struct tegra210_amx_soc_data soc_data_tegra194 = {
|
||||||
.regmap_conf = &tegra194_amx_regmap_config,
|
.regmap_conf = &tegra194_amx_regmap_config,
|
||||||
.auto_disable = true,
|
.auto_disable = true,
|
||||||
|
.max_ch = TEGRA210_AMX_MAX_CHANNEL,
|
||||||
|
.ram_depth = TEGRA210_AMX_RAM_DEPTH,
|
||||||
|
.byte_mask_size = TEGRA210_AMX_BYTE_MASK_COUNT,
|
||||||
|
.reg_offset = TEGRA210_AMX_AUTO_DISABLE_OFFSET,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct tegra210_amx_soc_data soc_data_tegra264 = {
|
||||||
|
.regmap_conf = &tegra264_amx_regmap_config,
|
||||||
|
.auto_disable = true,
|
||||||
|
.max_ch = TEGRA264_AMX_MAX_CHANNEL,
|
||||||
|
.ram_depth = TEGRA264_AMX_RAM_DEPTH,
|
||||||
|
.byte_mask_size = TEGRA264_AMX_BYTE_MASK_COUNT,
|
||||||
|
.reg_offset = TEGRA264_AMX_AUTO_DISABLE_OFFSET,
|
||||||
|
.controls = tegra264_amx_controls,
|
||||||
|
.num_controls = ARRAY_SIZE(tegra264_amx_controls),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id tegra210_amx_of_match[] = {
|
static const struct of_device_id tegra210_amx_of_match[] = {
|
||||||
{ .compatible = "nvidia,tegra210-amx", .data = &soc_data_tegra210 },
|
{ .compatible = "nvidia,tegra210-amx", .data = &soc_data_tegra210 },
|
||||||
{ .compatible = "nvidia,tegra194-amx", .data = &soc_data_tegra194 },
|
{ .compatible = "nvidia,tegra194-amx", .data = &soc_data_tegra194 },
|
||||||
|
{ .compatible = "nvidia,tegra264-amx", .data = &soc_data_tegra264 },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, tegra210_amx_of_match);
|
MODULE_DEVICE_TABLE(of, tegra210_amx_of_match);
|
||||||
|
|
@ -562,6 +747,20 @@ static int tegra210_amx_platform_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
regcache_cache_only(amx->regmap, true);
|
regcache_cache_only(amx->regmap, true);
|
||||||
|
|
||||||
|
amx->map = devm_kzalloc(dev, amx->soc_data->ram_depth * sizeof(*amx->map),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!amx->map)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
amx->byte_mask = devm_kzalloc(dev,
|
||||||
|
amx->soc_data->byte_mask_size * sizeof(*amx->byte_mask),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!amx->byte_mask)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
tegra210_amx_dais[TEGRA_AMX_OUT_DAI_ID].capture.channels_max =
|
||||||
|
amx->soc_data->max_ch;
|
||||||
|
|
||||||
err = devm_snd_soc_register_component(dev, &tegra210_amx_cmpnt,
|
err = devm_snd_soc_register_component(dev, &tegra210_amx_cmpnt,
|
||||||
tegra210_amx_dais,
|
tegra210_amx_dais,
|
||||||
ARRAY_SIZE(tegra210_amx_dais));
|
ARRAY_SIZE(tegra210_amx_dais));
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
* SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION. All rights reserved.
|
||||||
* tegra210_amx.h - Definitions for Tegra210 AMX driver
|
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
* tegra210_amx.h - Definitions for Tegra210 AMX driver
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -32,7 +31,6 @@
|
||||||
#define TEGRA210_AMX_INT_STATUS 0x90
|
#define TEGRA210_AMX_INT_STATUS 0x90
|
||||||
#define TEGRA210_AMX_CTRL 0xa4
|
#define TEGRA210_AMX_CTRL 0xa4
|
||||||
#define TEGRA210_AMX_OUT_BYTE_EN0 0xa8
|
#define TEGRA210_AMX_OUT_BYTE_EN0 0xa8
|
||||||
#define TEGRA210_AMX_OUT_BYTE_EN1 0xac
|
|
||||||
#define TEGRA210_AMX_CYA 0xb0
|
#define TEGRA210_AMX_CYA 0xb0
|
||||||
#define TEGRA210_AMX_CFG_RAM_CTRL 0xb8
|
#define TEGRA210_AMX_CFG_RAM_CTRL 0xb8
|
||||||
#define TEGRA210_AMX_CFG_RAM_DATA 0xbc
|
#define TEGRA210_AMX_CFG_RAM_DATA 0xbc
|
||||||
|
|
@ -41,6 +39,13 @@
|
||||||
#define TEGRA194_AMX_RX4_FRAME_PERIOD 0xcc
|
#define TEGRA194_AMX_RX4_FRAME_PERIOD 0xcc
|
||||||
#define TEGRA194_AMX_RX4_LAST_FRAME_PERIOD 0xdc
|
#define TEGRA194_AMX_RX4_LAST_FRAME_PERIOD 0xdc
|
||||||
|
|
||||||
|
#define TEGRA264_AMX_STREAMS_AUTO_DISABLE 0xb8
|
||||||
|
#define TEGRA264_AMX_CFG_RAM_CTRL 0xc0
|
||||||
|
#define TEGRA264_AMX_CFG_RAM_DATA 0xc4
|
||||||
|
#define TEGRA264_AMX_RX1_FRAME_PERIOD 0xc8
|
||||||
|
#define TEGRA264_AMX_RX4_FRAME_PERIOD 0xd4
|
||||||
|
#define TEGRA264_AMX_RX4_LAST_FRAME_PERIOD 0xe4
|
||||||
|
|
||||||
/* Fields in TEGRA210_AMX_ENABLE */
|
/* Fields in TEGRA210_AMX_ENABLE */
|
||||||
#define TEGRA210_AMX_ENABLE_SHIFT 0
|
#define TEGRA210_AMX_ENABLE_SHIFT 0
|
||||||
|
|
||||||
|
|
@ -72,6 +77,15 @@
|
||||||
#define TEGRA210_AMX_MAP_STREAM_NUM_SHIFT 6
|
#define TEGRA210_AMX_MAP_STREAM_NUM_SHIFT 6
|
||||||
#define TEGRA210_AMX_MAP_WORD_NUM_SHIFT 2
|
#define TEGRA210_AMX_MAP_WORD_NUM_SHIFT 2
|
||||||
#define TEGRA210_AMX_MAP_BYTE_NUM_SHIFT 0
|
#define TEGRA210_AMX_MAP_BYTE_NUM_SHIFT 0
|
||||||
|
#define TEGRA210_AMX_BYTE_MASK_COUNT 2
|
||||||
|
#define TEGRA210_AMX_MAX_CHANNEL 16
|
||||||
|
#define TEGRA210_AMX_AUTO_DISABLE_OFFSET 0
|
||||||
|
|
||||||
|
#define TEGRA264_AMX_RAM_DEPTH 32
|
||||||
|
#define TEGRA264_AMX_BYTE_MASK_COUNT 4
|
||||||
|
#define TEGRA264_AMX_MAX_CHANNEL 32
|
||||||
|
#define TEGRA264_AMX_AUTO_DISABLE_OFFSET 8
|
||||||
|
#define TEGRA_AMX_OUT_DAI_ID 4
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TEGRA210_AMX_WAIT_ON_ALL,
|
TEGRA210_AMX_WAIT_ON_ALL,
|
||||||
|
|
@ -81,13 +95,19 @@ enum {
|
||||||
struct tegra210_amx_soc_data {
|
struct tegra210_amx_soc_data {
|
||||||
const struct regmap_config *regmap_conf;
|
const struct regmap_config *regmap_conf;
|
||||||
bool auto_disable;
|
bool auto_disable;
|
||||||
|
const struct snd_kcontrol_new *controls;
|
||||||
|
unsigned int num_controls;
|
||||||
|
unsigned int max_ch;
|
||||||
|
unsigned int ram_depth;
|
||||||
|
unsigned int byte_mask_size;
|
||||||
|
unsigned int reg_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tegra210_amx {
|
struct tegra210_amx {
|
||||||
const struct tegra210_amx_soc_data *soc_data;
|
const struct tegra210_amx_soc_data *soc_data;
|
||||||
unsigned int map[TEGRA210_AMX_RAM_DEPTH];
|
unsigned int *map;
|
||||||
|
unsigned int *byte_mask;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
unsigned int byte_mask[2];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue