Skip to content

Commit fd509c6

Browse files
Sheetalbroonie
authored andcommitted
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 <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent b335443 commit fd509c6

File tree

2 files changed

+241
-22
lines changed

2 files changed

+241
-22
lines changed

sound/soc/tegra/tegra210_amx.c

Lines changed: 214 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: GPL-2.0-only
2-
// SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES.
2+
// SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES.
33
// All rights reserved.
44
//
55
// tegra210_amx.c - Tegra210 AMX driver
@@ -46,21 +46,35 @@ static const struct reg_default tegra210_amx_reg_defaults[] = {
4646
{ TEGRA210_AMX_CFG_RAM_CTRL, 0x00004000},
4747
};
4848

49+
static const struct reg_default tegra264_amx_reg_defaults[] = {
50+
{ TEGRA210_AMX_RX_INT_MASK, 0x0000000f},
51+
{ TEGRA210_AMX_RX1_CIF_CTRL, 0x00003800},
52+
{ TEGRA210_AMX_RX2_CIF_CTRL, 0x00003800},
53+
{ TEGRA210_AMX_RX3_CIF_CTRL, 0x00003800},
54+
{ TEGRA210_AMX_RX4_CIF_CTRL, 0x00003800},
55+
{ TEGRA210_AMX_TX_INT_MASK, 0x00000001},
56+
{ TEGRA210_AMX_TX_CIF_CTRL, 0x00003800},
57+
{ TEGRA210_AMX_CG, 0x1},
58+
{ TEGRA264_AMX_CFG_RAM_CTRL, 0x00004000},
59+
};
60+
4961
static void tegra210_amx_write_map_ram(struct tegra210_amx *amx)
5062
{
5163
int i;
5264

53-
regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_CTRL,
65+
regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_CTRL + amx->soc_data->reg_offset,
5466
TEGRA210_AMX_CFG_RAM_CTRL_SEQ_ACCESS_EN |
5567
TEGRA210_AMX_CFG_RAM_CTRL_ADDR_INIT_EN |
5668
TEGRA210_AMX_CFG_RAM_CTRL_RW_WRITE);
5769

58-
for (i = 0; i < TEGRA210_AMX_RAM_DEPTH; i++)
59-
regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_DATA,
70+
for (i = 0; i < amx->soc_data->ram_depth; i++)
71+
regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_DATA + amx->soc_data->reg_offset,
6072
amx->map[i]);
6173

62-
regmap_write(amx->regmap, TEGRA210_AMX_OUT_BYTE_EN0, amx->byte_mask[0]);
63-
regmap_write(amx->regmap, TEGRA210_AMX_OUT_BYTE_EN1, amx->byte_mask[1]);
74+
for (i = 0; i < amx->soc_data->byte_mask_size; i++)
75+
regmap_write(amx->regmap,
76+
TEGRA210_AMX_OUT_BYTE_EN0 + (i * TEGRA210_AMX_AUDIOCIF_CH_STRIDE),
77+
amx->byte_mask[i]);
6478
}
6579

6680
static int tegra210_amx_startup(struct snd_pcm_substream *substream,
@@ -157,7 +171,10 @@ static int tegra210_amx_set_audio_cif(struct snd_soc_dai *dai,
157171
cif_conf.audio_bits = audio_bits;
158172
cif_conf.client_bits = audio_bits;
159173

160-
tegra_set_cif(amx->regmap, reg, &cif_conf);
174+
if (amx->soc_data->max_ch == TEGRA264_AMX_MAX_CHANNEL)
175+
tegra264_set_cif(amx->regmap, reg, &cif_conf);
176+
else
177+
tegra_set_cif(amx->regmap, reg, &cif_conf);
161178

162179
return 0;
163180
}
@@ -170,9 +187,10 @@ static int tegra210_amx_in_hw_params(struct snd_pcm_substream *substream,
170187

171188
if (amx->soc_data->auto_disable) {
172189
regmap_write(amx->regmap,
173-
AMX_CH_REG(dai->id, TEGRA194_AMX_RX1_FRAME_PERIOD),
190+
AMX_CH_REG(dai->id, TEGRA194_AMX_RX1_FRAME_PERIOD +
191+
amx->soc_data->reg_offset),
174192
TEGRA194_MAX_FRAME_IDLE_COUNT);
175-
regmap_write(amx->regmap, TEGRA210_AMX_CYA, 1);
193+
regmap_write(amx->regmap, TEGRA210_AMX_CYA + amx->soc_data->reg_offset, 1);
176194
}
177195

178196
return tegra210_amx_set_audio_cif(dai, params,
@@ -194,14 +212,11 @@ static int tegra210_amx_get_byte_map(struct snd_kcontrol *kcontrol,
194212
struct soc_mixer_control *mc =
195213
(struct soc_mixer_control *)kcontrol->private_value;
196214
struct tegra210_amx *amx = snd_soc_component_get_drvdata(cmpnt);
197-
unsigned char *bytes_map = (unsigned char *)&amx->map;
215+
unsigned char *bytes_map = (unsigned char *)amx->map;
198216
int reg = mc->reg;
199217
int enabled;
200218

201-
if (reg > 31)
202-
enabled = amx->byte_mask[1] & (1 << (reg - 32));
203-
else
204-
enabled = amx->byte_mask[0] & (1 << reg);
219+
enabled = amx->byte_mask[reg / 32] & (1 << (reg % 32));
205220

206221
/*
207222
* 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,
228243
(struct soc_mixer_control *)kcontrol->private_value;
229244
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
230245
struct tegra210_amx *amx = snd_soc_component_get_drvdata(cmpnt);
231-
unsigned char *bytes_map = (unsigned char *)&amx->map;
246+
unsigned char *bytes_map = (unsigned char *)amx->map;
232247
int reg = mc->reg;
233248
int value = ucontrol->value.integer.value[0];
234249
unsigned int mask_val = amx->byte_mask[reg / 32];
@@ -418,7 +433,90 @@ static struct snd_kcontrol_new tegra210_amx_controls[] = {
418433
TEGRA210_AMX_BYTE_MAP_CTRL(63),
419434
};
420435

436+
static struct snd_kcontrol_new tegra264_amx_controls[] = {
437+
TEGRA210_AMX_BYTE_MAP_CTRL(64),
438+
TEGRA210_AMX_BYTE_MAP_CTRL(65),
439+
TEGRA210_AMX_BYTE_MAP_CTRL(66),
440+
TEGRA210_AMX_BYTE_MAP_CTRL(67),
441+
TEGRA210_AMX_BYTE_MAP_CTRL(68),
442+
TEGRA210_AMX_BYTE_MAP_CTRL(69),
443+
TEGRA210_AMX_BYTE_MAP_CTRL(70),
444+
TEGRA210_AMX_BYTE_MAP_CTRL(71),
445+
TEGRA210_AMX_BYTE_MAP_CTRL(72),
446+
TEGRA210_AMX_BYTE_MAP_CTRL(73),
447+
TEGRA210_AMX_BYTE_MAP_CTRL(74),
448+
TEGRA210_AMX_BYTE_MAP_CTRL(75),
449+
TEGRA210_AMX_BYTE_MAP_CTRL(76),
450+
TEGRA210_AMX_BYTE_MAP_CTRL(77),
451+
TEGRA210_AMX_BYTE_MAP_CTRL(78),
452+
TEGRA210_AMX_BYTE_MAP_CTRL(79),
453+
TEGRA210_AMX_BYTE_MAP_CTRL(80),
454+
TEGRA210_AMX_BYTE_MAP_CTRL(81),
455+
TEGRA210_AMX_BYTE_MAP_CTRL(82),
456+
TEGRA210_AMX_BYTE_MAP_CTRL(83),
457+
TEGRA210_AMX_BYTE_MAP_CTRL(84),
458+
TEGRA210_AMX_BYTE_MAP_CTRL(85),
459+
TEGRA210_AMX_BYTE_MAP_CTRL(86),
460+
TEGRA210_AMX_BYTE_MAP_CTRL(87),
461+
TEGRA210_AMX_BYTE_MAP_CTRL(88),
462+
TEGRA210_AMX_BYTE_MAP_CTRL(89),
463+
TEGRA210_AMX_BYTE_MAP_CTRL(90),
464+
TEGRA210_AMX_BYTE_MAP_CTRL(91),
465+
TEGRA210_AMX_BYTE_MAP_CTRL(92),
466+
TEGRA210_AMX_BYTE_MAP_CTRL(93),
467+
TEGRA210_AMX_BYTE_MAP_CTRL(94),
468+
TEGRA210_AMX_BYTE_MAP_CTRL(95),
469+
TEGRA210_AMX_BYTE_MAP_CTRL(96),
470+
TEGRA210_AMX_BYTE_MAP_CTRL(97),
471+
TEGRA210_AMX_BYTE_MAP_CTRL(98),
472+
TEGRA210_AMX_BYTE_MAP_CTRL(99),
473+
TEGRA210_AMX_BYTE_MAP_CTRL(100),
474+
TEGRA210_AMX_BYTE_MAP_CTRL(101),
475+
TEGRA210_AMX_BYTE_MAP_CTRL(102),
476+
TEGRA210_AMX_BYTE_MAP_CTRL(103),
477+
TEGRA210_AMX_BYTE_MAP_CTRL(104),
478+
TEGRA210_AMX_BYTE_MAP_CTRL(105),
479+
TEGRA210_AMX_BYTE_MAP_CTRL(106),
480+
TEGRA210_AMX_BYTE_MAP_CTRL(107),
481+
TEGRA210_AMX_BYTE_MAP_CTRL(108),
482+
TEGRA210_AMX_BYTE_MAP_CTRL(109),
483+
TEGRA210_AMX_BYTE_MAP_CTRL(110),
484+
TEGRA210_AMX_BYTE_MAP_CTRL(111),
485+
TEGRA210_AMX_BYTE_MAP_CTRL(112),
486+
TEGRA210_AMX_BYTE_MAP_CTRL(113),
487+
TEGRA210_AMX_BYTE_MAP_CTRL(114),
488+
TEGRA210_AMX_BYTE_MAP_CTRL(115),
489+
TEGRA210_AMX_BYTE_MAP_CTRL(116),
490+
TEGRA210_AMX_BYTE_MAP_CTRL(117),
491+
TEGRA210_AMX_BYTE_MAP_CTRL(118),
492+
TEGRA210_AMX_BYTE_MAP_CTRL(119),
493+
TEGRA210_AMX_BYTE_MAP_CTRL(120),
494+
TEGRA210_AMX_BYTE_MAP_CTRL(121),
495+
TEGRA210_AMX_BYTE_MAP_CTRL(122),
496+
TEGRA210_AMX_BYTE_MAP_CTRL(123),
497+
TEGRA210_AMX_BYTE_MAP_CTRL(124),
498+
TEGRA210_AMX_BYTE_MAP_CTRL(125),
499+
TEGRA210_AMX_BYTE_MAP_CTRL(126),
500+
TEGRA210_AMX_BYTE_MAP_CTRL(127),
501+
};
502+
503+
static int tegra210_amx_component_probe(struct snd_soc_component *component)
504+
{
505+
struct tegra210_amx *amx = snd_soc_component_get_drvdata(component);
506+
int err = 0;
507+
508+
if (amx->soc_data->num_controls) {
509+
err = snd_soc_add_component_controls(component, amx->soc_data->controls,
510+
amx->soc_data->num_controls);
511+
if (err)
512+
dev_err(component->dev, "can't add AMX controls, err: %d\n", err);
513+
}
514+
515+
return err;
516+
}
517+
421518
static const struct snd_soc_component_driver tegra210_amx_cmpnt = {
519+
.probe = tegra210_amx_component_probe,
422520
.dapm_widgets = tegra210_amx_widgets,
423521
.num_dapm_widgets = ARRAY_SIZE(tegra210_amx_widgets),
424522
.dapm_routes = tegra210_amx_routes,
@@ -450,6 +548,22 @@ static bool tegra194_amx_wr_reg(struct device *dev, unsigned int reg)
450548
}
451549
}
452550

551+
static bool tegra264_amx_wr_reg(struct device *dev,
552+
unsigned int reg)
553+
{
554+
switch (reg) {
555+
case TEGRA210_AMX_RX_INT_MASK ... TEGRA210_AMX_RX4_CIF_CTRL:
556+
case TEGRA210_AMX_TX_INT_MASK ... TEGRA210_AMX_TX_CIF_CTRL:
557+
case TEGRA210_AMX_ENABLE ... TEGRA210_AMX_CG:
558+
case TEGRA210_AMX_CTRL ... TEGRA264_AMX_STREAMS_AUTO_DISABLE:
559+
case TEGRA264_AMX_CFG_RAM_CTRL ... TEGRA264_AMX_CFG_RAM_DATA:
560+
case TEGRA264_AMX_RX1_FRAME_PERIOD ... TEGRA264_AMX_RX4_FRAME_PERIOD:
561+
return true;
562+
default:
563+
return false;
564+
}
565+
}
566+
453567
static bool tegra210_amx_rd_reg(struct device *dev, unsigned int reg)
454568
{
455569
switch (reg) {
@@ -470,6 +584,21 @@ static bool tegra194_amx_rd_reg(struct device *dev, unsigned int reg)
470584
}
471585
}
472586

587+
static bool tegra264_amx_rd_reg(struct device *dev,
588+
unsigned int reg)
589+
{
590+
switch (reg) {
591+
case TEGRA210_AMX_RX_STATUS ... TEGRA210_AMX_RX4_CIF_CTRL:
592+
case TEGRA210_AMX_TX_STATUS ... TEGRA210_AMX_TX_CIF_CTRL:
593+
case TEGRA210_AMX_ENABLE ... TEGRA210_AMX_INT_STATUS:
594+
case TEGRA210_AMX_CTRL ... TEGRA264_AMX_CFG_RAM_DATA:
595+
case TEGRA264_AMX_RX1_FRAME_PERIOD ... TEGRA264_AMX_RX4_FRAME_PERIOD:
596+
return true;
597+
default:
598+
return false;
599+
}
600+
}
601+
473602
static bool tegra210_amx_volatile_reg(struct device *dev, unsigned int reg)
474603
{
475604
switch (reg) {
@@ -492,6 +621,29 @@ static bool tegra210_amx_volatile_reg(struct device *dev, unsigned int reg)
492621
return false;
493622
}
494623

624+
static bool tegra264_amx_volatile_reg(struct device *dev,
625+
unsigned int reg)
626+
{
627+
switch (reg) {
628+
case TEGRA210_AMX_RX_STATUS:
629+
case TEGRA210_AMX_RX_INT_STATUS:
630+
case TEGRA210_AMX_RX_INT_SET:
631+
case TEGRA210_AMX_TX_STATUS:
632+
case TEGRA210_AMX_TX_INT_STATUS:
633+
case TEGRA210_AMX_TX_INT_SET:
634+
case TEGRA210_AMX_SOFT_RESET:
635+
case TEGRA210_AMX_STATUS:
636+
case TEGRA210_AMX_INT_STATUS:
637+
case TEGRA264_AMX_CFG_RAM_CTRL:
638+
case TEGRA264_AMX_CFG_RAM_DATA:
639+
return true;
640+
default:
641+
break;
642+
}
643+
644+
return false;
645+
}
646+
495647
static const struct regmap_config tegra210_amx_regmap_config = {
496648
.reg_bits = 32,
497649
.reg_stride = 4,
@@ -518,18 +670,51 @@ static const struct regmap_config tegra194_amx_regmap_config = {
518670
.cache_type = REGCACHE_FLAT,
519671
};
520672

673+
static const struct regmap_config tegra264_amx_regmap_config = {
674+
.reg_bits = 32,
675+
.reg_stride = 4,
676+
.val_bits = 32,
677+
.max_register = TEGRA264_AMX_RX4_LAST_FRAME_PERIOD,
678+
.writeable_reg = tegra264_amx_wr_reg,
679+
.readable_reg = tegra264_amx_rd_reg,
680+
.volatile_reg = tegra264_amx_volatile_reg,
681+
.reg_defaults = tegra264_amx_reg_defaults,
682+
.num_reg_defaults = ARRAY_SIZE(tegra264_amx_reg_defaults),
683+
.cache_type = REGCACHE_FLAT,
684+
};
685+
521686
static const struct tegra210_amx_soc_data soc_data_tegra210 = {
522687
.regmap_conf = &tegra210_amx_regmap_config,
688+
.max_ch = TEGRA210_AMX_MAX_CHANNEL,
689+
.ram_depth = TEGRA210_AMX_RAM_DEPTH,
690+
.byte_mask_size = TEGRA210_AMX_BYTE_MASK_COUNT,
691+
.reg_offset = TEGRA210_AMX_AUTO_DISABLE_OFFSET,
523692
};
524693

525694
static const struct tegra210_amx_soc_data soc_data_tegra194 = {
526695
.regmap_conf = &tegra194_amx_regmap_config,
527696
.auto_disable = true,
697+
.max_ch = TEGRA210_AMX_MAX_CHANNEL,
698+
.ram_depth = TEGRA210_AMX_RAM_DEPTH,
699+
.byte_mask_size = TEGRA210_AMX_BYTE_MASK_COUNT,
700+
.reg_offset = TEGRA210_AMX_AUTO_DISABLE_OFFSET,
701+
};
702+
703+
static const struct tegra210_amx_soc_data soc_data_tegra264 = {
704+
.regmap_conf = &tegra264_amx_regmap_config,
705+
.auto_disable = true,
706+
.max_ch = TEGRA264_AMX_MAX_CHANNEL,
707+
.ram_depth = TEGRA264_AMX_RAM_DEPTH,
708+
.byte_mask_size = TEGRA264_AMX_BYTE_MASK_COUNT,
709+
.reg_offset = TEGRA264_AMX_AUTO_DISABLE_OFFSET,
710+
.controls = tegra264_amx_controls,
711+
.num_controls = ARRAY_SIZE(tegra264_amx_controls),
528712
};
529713

530714
static const struct of_device_id tegra210_amx_of_match[] = {
531715
{ .compatible = "nvidia,tegra210-amx", .data = &soc_data_tegra210 },
532716
{ .compatible = "nvidia,tegra194-amx", .data = &soc_data_tegra194 },
717+
{ .compatible = "nvidia,tegra264-amx", .data = &soc_data_tegra264 },
533718
{},
534719
};
535720
MODULE_DEVICE_TABLE(of, tegra210_amx_of_match);
@@ -562,6 +747,20 @@ static int tegra210_amx_platform_probe(struct platform_device *pdev)
562747

563748
regcache_cache_only(amx->regmap, true);
564749

750+
amx->map = devm_kzalloc(dev, amx->soc_data->ram_depth * sizeof(*amx->map),
751+
GFP_KERNEL);
752+
if (!amx->map)
753+
return -ENOMEM;
754+
755+
amx->byte_mask = devm_kzalloc(dev,
756+
amx->soc_data->byte_mask_size * sizeof(*amx->byte_mask),
757+
GFP_KERNEL);
758+
if (!amx->byte_mask)
759+
return -ENOMEM;
760+
761+
tegra210_amx_dais[TEGRA_AMX_OUT_DAI_ID].capture.channels_max =
762+
amx->soc_data->max_ch;
763+
565764
err = devm_snd_soc_register_component(dev, &tegra210_amx_cmpnt,
566765
tegra210_amx_dais,
567766
ARRAY_SIZE(tegra210_amx_dais));

0 commit comments

Comments
 (0)