From 35c0d1de8e669878797e40cc625f4bdc37c3e084 Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:39 +0000 Subject: ASoC: tegra: CIF: Add Tegra264 support In Tegra264, the CIF register data bit positions are changed for I2S, AMX, ADX and ADMAIF AHUB modules, as they now support a maximum of 32 channels. tegra264_set_cif API added to set the CIF for IPs supporting 32 channels. Signed-off-by: Sheetal Link: https://patch.msgid.link/20250512051747.1026770-4-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_cif.h | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra_cif.h b/sound/soc/tegra/tegra_cif.h index 7cca8068f4b5..916aa10d8af8 100644 --- a/sound/soc/tegra/tegra_cif.h +++ b/sound/soc/tegra/tegra_cif.h @@ -1,8 +1,7 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * tegra_cif.h - TEGRA Audio CIF Programming +/* SPDX-License-Identifier: GPL-2.0-only + * SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION. All rights reserved. * - * Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. + * tegra_cif.h - TEGRA Audio CIF Programming * */ @@ -22,6 +21,10 @@ #define TEGRA_ACIF_CTRL_TRUNCATE_SHIFT 1 #define TEGRA_ACIF_CTRL_MONO_CONV_SHIFT 0 +#define TEGRA264_ACIF_CTRL_AUDIO_BITS_SHIFT 11 +#define TEGRA264_ACIF_CTRL_CLIENT_CH_SHIFT 14 +#define TEGRA264_ACIF_CTRL_AUDIO_CH_SHIFT 19 + /* AUDIO/CLIENT_BITS values */ #define TEGRA_ACIF_BITS_8 1 #define TEGRA_ACIF_BITS_16 3 @@ -62,4 +65,23 @@ static inline void tegra_set_cif(struct regmap *regmap, unsigned int reg, regmap_update_bits(regmap, reg, TEGRA_ACIF_UPDATE_MASK, value); } +static inline void tegra264_set_cif(struct regmap *regmap, unsigned int reg, + struct tegra_cif_conf *conf) +{ + unsigned int value; + + value = (conf->threshold << TEGRA_ACIF_CTRL_FIFO_TH_SHIFT) | + ((conf->audio_ch - 1) << TEGRA264_ACIF_CTRL_AUDIO_CH_SHIFT) | + ((conf->client_ch - 1) << TEGRA264_ACIF_CTRL_CLIENT_CH_SHIFT) | + (conf->audio_bits << TEGRA264_ACIF_CTRL_AUDIO_BITS_SHIFT) | + (conf->client_bits << TEGRA_ACIF_CTRL_CLIENT_BITS_SHIFT) | + (conf->expand << TEGRA_ACIF_CTRL_EXPAND_SHIFT) | + (conf->stereo_conv << TEGRA_ACIF_CTRL_STEREO_CONV_SHIFT) | + (conf->replicate << TEGRA_ACIF_CTRL_REPLICATE_SHIFT) | + (conf->truncate << TEGRA_ACIF_CTRL_TRUNCATE_SHIFT) | + (conf->mono_conv << TEGRA_ACIF_CTRL_MONO_CONV_SHIFT); + + regmap_update_bits(regmap, reg, TEGRA_ACIF_UPDATE_MASK, value); +} + #endif -- cgit v1.2.3 From 7668c6378b0577893bcf8c0f272b6ed099e0787d Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:40 +0000 Subject: ASoC: tegra: ADMAIF: Add Tegra264 support Add Tegra264 I2S support with following changes: - Add soc_data for Tegra264-specific variations - Tegra264 supports 32 RX and 32 TX ADMAIF channels and each ADMAIF stream supports max 32 channels. To accommodate the change dais, CIF configuration API and driver components are updated. - Register offsets and default values are updated to align with Tegra264. Signed-off-by: Sheetal Link: https://patch.msgid.link/20250512051747.1026770-5-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_admaif.c | 223 +++++++++++++++++++++++++++++++------- sound/soc/tegra/tegra210_admaif.h | 78 +++++++++++++ 2 files changed, 263 insertions(+), 38 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c index 76ff4fe40f65..f88d6a2356e0 100644 --- a/sound/soc/tegra/tegra210_admaif.c +++ b/sound/soc/tegra/tegra210_admaif.c @@ -25,12 +25,12 @@ #define CH_RX_REG(reg, id) CH_REG(admaif->soc_data->rx_base, reg, id) -#define REG_DEFAULTS(id, rx_ctrl, tx_ctrl, tx_base, rx_base) \ +#define REG_DEFAULTS(id, rx_ctrl, tx_ctrl, tx_base, rx_base, cif_ctrl) \ { CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001 }, \ - { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), 0x00007700 }, \ + { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), cif_ctrl }, \ { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl }, \ { CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001 }, \ - { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), 0x00007700 }, \ + { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), cif_ctrl }, \ { CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl } #define ADMAIF_REG_DEFAULTS(id, chip) \ @@ -38,7 +38,8 @@ chip ## _ADMAIF_RX ## id ## _FIFO_CTRL_REG_DEFAULT, \ chip ## _ADMAIF_TX ## id ## _FIFO_CTRL_REG_DEFAULT, \ chip ## _ADMAIF_TX_BASE, \ - chip ## _ADMAIF_RX_BASE) + chip ## _ADMAIF_RX_BASE, \ + chip ## _ADMAIF_CIF_REG_DEFAULT) static const struct reg_default tegra186_admaif_reg_defaults[] = { {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003}, @@ -78,6 +79,42 @@ static const struct reg_default tegra210_admaif_reg_defaults[] = { ADMAIF_REG_DEFAULTS(10, TEGRA210) }; +static const struct reg_default tegra264_admaif_reg_defaults[] = { + {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA264_ADMAIF_GLOBAL_BASE), 0x00000003}, + ADMAIF_REG_DEFAULTS(1, TEGRA264), + ADMAIF_REG_DEFAULTS(2, TEGRA264), + ADMAIF_REG_DEFAULTS(3, TEGRA264), + ADMAIF_REG_DEFAULTS(4, TEGRA264), + ADMAIF_REG_DEFAULTS(5, TEGRA264), + ADMAIF_REG_DEFAULTS(6, TEGRA264), + ADMAIF_REG_DEFAULTS(7, TEGRA264), + ADMAIF_REG_DEFAULTS(8, TEGRA264), + ADMAIF_REG_DEFAULTS(9, TEGRA264), + ADMAIF_REG_DEFAULTS(10, TEGRA264), + ADMAIF_REG_DEFAULTS(11, TEGRA264), + ADMAIF_REG_DEFAULTS(12, TEGRA264), + ADMAIF_REG_DEFAULTS(13, TEGRA264), + ADMAIF_REG_DEFAULTS(14, TEGRA264), + ADMAIF_REG_DEFAULTS(15, TEGRA264), + ADMAIF_REG_DEFAULTS(16, TEGRA264), + ADMAIF_REG_DEFAULTS(17, TEGRA264), + ADMAIF_REG_DEFAULTS(18, TEGRA264), + ADMAIF_REG_DEFAULTS(19, TEGRA264), + ADMAIF_REG_DEFAULTS(20, TEGRA264), + ADMAIF_REG_DEFAULTS(21, TEGRA264), + ADMAIF_REG_DEFAULTS(22, TEGRA264), + ADMAIF_REG_DEFAULTS(23, TEGRA264), + ADMAIF_REG_DEFAULTS(24, TEGRA264), + ADMAIF_REG_DEFAULTS(25, TEGRA264), + ADMAIF_REG_DEFAULTS(26, TEGRA264), + ADMAIF_REG_DEFAULTS(27, TEGRA264), + ADMAIF_REG_DEFAULTS(28, TEGRA264), + ADMAIF_REG_DEFAULTS(29, TEGRA264), + ADMAIF_REG_DEFAULTS(30, TEGRA264), + ADMAIF_REG_DEFAULTS(31, TEGRA264), + ADMAIF_REG_DEFAULTS(32, TEGRA264) +}; + static bool tegra_admaif_wr_reg(struct device *dev, unsigned int reg) { struct tegra_admaif *admaif = dev_get_drvdata(dev); @@ -220,6 +257,19 @@ static const struct regmap_config tegra186_admaif_regmap_config = { .cache_type = REGCACHE_FLAT, }; +static const struct regmap_config tegra264_admaif_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = TEGRA264_ADMAIF_LAST_REG, + .writeable_reg = tegra_admaif_wr_reg, + .readable_reg = tegra_admaif_rd_reg, + .volatile_reg = tegra_admaif_volatile_reg, + .reg_defaults = tegra264_admaif_reg_defaults, + .num_reg_defaults = TEGRA264_ADMAIF_CHANNEL_COUNT * 6 + 1, + .cache_type = REGCACHE_FLAT, +}; + static int tegra_admaif_runtime_suspend(struct device *dev) { struct tegra_admaif *admaif = dev_get_drvdata(dev); @@ -330,7 +380,10 @@ static int tegra_admaif_hw_params(struct snd_pcm_substream *substream, tegra_admaif_set_pack_mode(admaif->regmap, reg, valid_bit); - tegra_set_cif(admaif->regmap, reg, &cif_conf); + if (admaif->soc_data->max_stream_ch == TEGRA264_ADMAIF_MAX_CHANNEL) + tegra264_set_cif(admaif->regmap, reg, &cif_conf); + else + tegra_set_cif(admaif->regmap, reg, &cif_conf); return 0; } @@ -571,13 +624,13 @@ static const struct snd_soc_dai_ops tegra_admaif_dai_ops = { .prepare = tegra_admaif_prepare, }; -#define DAI(dai_name) \ +#define DAI(dai_name, channel) \ { \ .name = dai_name, \ .playback = { \ .stream_name = dai_name " Playback", \ .channels_min = 1, \ - .channels_max = 16, \ + .channels_max = channel, \ .rates = SNDRV_PCM_RATE_8000_192000, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ @@ -587,7 +640,7 @@ static const struct snd_soc_dai_ops tegra_admaif_dai_ops = { .capture = { \ .stream_name = dai_name " Capture", \ .channels_min = 1, \ - .channels_max = 16, \ + .channels_max = channel, \ .rates = SNDRV_PCM_RATE_8000_192000, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ @@ -598,39 +651,74 @@ static const struct snd_soc_dai_ops tegra_admaif_dai_ops = { } static struct snd_soc_dai_driver tegra210_admaif_cmpnt_dais[] = { - DAI("ADMAIF1"), - DAI("ADMAIF2"), - DAI("ADMAIF3"), - DAI("ADMAIF4"), - DAI("ADMAIF5"), - DAI("ADMAIF6"), - DAI("ADMAIF7"), - DAI("ADMAIF8"), - DAI("ADMAIF9"), - DAI("ADMAIF10"), + DAI("ADMAIF1", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF2", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF3", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF4", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF5", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF6", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF7", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF8", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF9", TEGRA210_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF10", TEGRA210_ADMAIF_MAX_CHANNEL), }; static struct snd_soc_dai_driver tegra186_admaif_cmpnt_dais[] = { - DAI("ADMAIF1"), - DAI("ADMAIF2"), - DAI("ADMAIF3"), - DAI("ADMAIF4"), - DAI("ADMAIF5"), - DAI("ADMAIF6"), - DAI("ADMAIF7"), - DAI("ADMAIF8"), - DAI("ADMAIF9"), - DAI("ADMAIF10"), - DAI("ADMAIF11"), - DAI("ADMAIF12"), - DAI("ADMAIF13"), - DAI("ADMAIF14"), - DAI("ADMAIF15"), - DAI("ADMAIF16"), - DAI("ADMAIF17"), - DAI("ADMAIF18"), - DAI("ADMAIF19"), - DAI("ADMAIF20"), + DAI("ADMAIF1", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF2", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF3", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF4", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF5", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF6", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF7", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF8", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF9", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF10", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF11", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF12", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF13", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF14", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF15", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF16", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF17", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF18", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF19", TEGRA186_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF20", TEGRA186_ADMAIF_MAX_CHANNEL), +}; + +static struct snd_soc_dai_driver tegra264_admaif_cmpnt_dais[] = { + DAI("ADMAIF1", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF2", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF3", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF4", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF5", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF6", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF7", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF8", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF9", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF10", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF11", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF12", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF13", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF14", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF15", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF16", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF17", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF18", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF19", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF20", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF21", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF22", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF23", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF24", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF25", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF26", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF27", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF28", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF29", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF30", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF31", TEGRA264_ADMAIF_MAX_CHANNEL), + DAI("ADMAIF32", TEGRA264_ADMAIF_MAX_CHANNEL), }; static const char * const tegra_admaif_stereo_conv_text[] = { @@ -710,6 +798,41 @@ static struct snd_kcontrol_new tegra186_admaif_controls[] = { TEGRA_ADMAIF_CIF_CTRL(20), }; +static struct snd_kcontrol_new tegra264_admaif_controls[] = { + TEGRA_ADMAIF_CIF_CTRL(1), + TEGRA_ADMAIF_CIF_CTRL(2), + TEGRA_ADMAIF_CIF_CTRL(3), + TEGRA_ADMAIF_CIF_CTRL(4), + TEGRA_ADMAIF_CIF_CTRL(5), + TEGRA_ADMAIF_CIF_CTRL(6), + TEGRA_ADMAIF_CIF_CTRL(7), + TEGRA_ADMAIF_CIF_CTRL(8), + TEGRA_ADMAIF_CIF_CTRL(9), + TEGRA_ADMAIF_CIF_CTRL(10), + TEGRA_ADMAIF_CIF_CTRL(11), + TEGRA_ADMAIF_CIF_CTRL(12), + TEGRA_ADMAIF_CIF_CTRL(13), + TEGRA_ADMAIF_CIF_CTRL(14), + TEGRA_ADMAIF_CIF_CTRL(15), + TEGRA_ADMAIF_CIF_CTRL(16), + TEGRA_ADMAIF_CIF_CTRL(17), + TEGRA_ADMAIF_CIF_CTRL(18), + TEGRA_ADMAIF_CIF_CTRL(19), + TEGRA_ADMAIF_CIF_CTRL(20), + TEGRA_ADMAIF_CIF_CTRL(21), + TEGRA_ADMAIF_CIF_CTRL(22), + TEGRA_ADMAIF_CIF_CTRL(23), + TEGRA_ADMAIF_CIF_CTRL(24), + TEGRA_ADMAIF_CIF_CTRL(25), + TEGRA_ADMAIF_CIF_CTRL(26), + TEGRA_ADMAIF_CIF_CTRL(27), + TEGRA_ADMAIF_CIF_CTRL(28), + TEGRA_ADMAIF_CIF_CTRL(29), + TEGRA_ADMAIF_CIF_CTRL(30), + TEGRA_ADMAIF_CIF_CTRL(31), + TEGRA_ADMAIF_CIF_CTRL(32), +}; + static const struct snd_soc_component_driver tegra210_admaif_cmpnt = { .controls = tegra210_admaif_controls, .num_controls = ARRAY_SIZE(tegra210_admaif_controls), @@ -730,8 +853,19 @@ static const struct snd_soc_component_driver tegra186_admaif_cmpnt = { .pointer = tegra_pcm_pointer, }; +static const struct snd_soc_component_driver tegra264_admaif_cmpnt = { + .controls = tegra264_admaif_controls, + .num_controls = ARRAY_SIZE(tegra264_admaif_controls), + .pcm_construct = tegra_pcm_construct, + .open = tegra_pcm_open, + .close = tegra_pcm_close, + .hw_params = tegra_pcm_hw_params, + .pointer = tegra_pcm_pointer, +}; + static const struct tegra_admaif_soc_data soc_data_tegra210 = { .num_ch = TEGRA210_ADMAIF_CHANNEL_COUNT, + .max_stream_ch = TEGRA210_ADMAIF_MAX_CHANNEL, .cmpnt = &tegra210_admaif_cmpnt, .dais = tegra210_admaif_cmpnt_dais, .regmap_conf = &tegra210_admaif_regmap_config, @@ -742,6 +876,7 @@ static const struct tegra_admaif_soc_data soc_data_tegra210 = { static const struct tegra_admaif_soc_data soc_data_tegra186 = { .num_ch = TEGRA186_ADMAIF_CHANNEL_COUNT, + .max_stream_ch = TEGRA186_ADMAIF_MAX_CHANNEL, .cmpnt = &tegra186_admaif_cmpnt, .dais = tegra186_admaif_cmpnt_dais, .regmap_conf = &tegra186_admaif_regmap_config, @@ -750,9 +885,21 @@ static const struct tegra_admaif_soc_data soc_data_tegra186 = { .rx_base = TEGRA186_ADMAIF_RX_BASE, }; +static const struct tegra_admaif_soc_data soc_data_tegra264 = { + .num_ch = TEGRA264_ADMAIF_CHANNEL_COUNT, + .max_stream_ch = TEGRA264_ADMAIF_MAX_CHANNEL, + .cmpnt = &tegra264_admaif_cmpnt, + .dais = tegra264_admaif_cmpnt_dais, + .regmap_conf = &tegra264_admaif_regmap_config, + .global_base = TEGRA264_ADMAIF_GLOBAL_BASE, + .tx_base = TEGRA264_ADMAIF_TX_BASE, + .rx_base = TEGRA264_ADMAIF_RX_BASE, +}; + static const struct of_device_id tegra_admaif_of_match[] = { { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 }, { .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 }, + { .compatible = "nvidia,tegra264-admaif", .data = &soc_data_tegra264 }, {}, }; MODULE_DEVICE_TABLE(of, tegra_admaif_of_match); diff --git a/sound/soc/tegra/tegra210_admaif.h b/sound/soc/tegra/tegra210_admaif.h index 748f886ee74e..304d45c76a9a 100644 --- a/sound/soc/tegra/tegra210_admaif.h +++ b/sound/soc/tegra/tegra210_admaif.h @@ -16,12 +16,21 @@ #define TEGRA210_ADMAIF_RX_BASE 0x0 #define TEGRA210_ADMAIF_TX_BASE 0x300 #define TEGRA210_ADMAIF_GLOBAL_BASE 0x700 +#define TEGRA210_ADMAIF_MAX_CHANNEL 16 /* Tegra186 specific */ #define TEGRA186_ADMAIF_LAST_REG 0xd5f #define TEGRA186_ADMAIF_CHANNEL_COUNT 20 #define TEGRA186_ADMAIF_RX_BASE 0x0 #define TEGRA186_ADMAIF_TX_BASE 0x500 #define TEGRA186_ADMAIF_GLOBAL_BASE 0xd00 +#define TEGRA186_ADMAIF_MAX_CHANNEL 16 +/* Tegra264 specific */ +#define TEGRA264_ADMAIF_LAST_REG 0x205f +#define TEGRA264_ADMAIF_CHANNEL_COUNT 32 +#define TEGRA264_ADMAIF_RX_BASE 0x0 +#define TEGRA264_ADMAIF_TX_BASE 0x1000 +#define TEGRA264_ADMAIF_GLOBAL_BASE 0x2000 +#define TEGRA264_ADMAIF_MAX_CHANNEL 32 /* Global registers */ #define TEGRA_ADMAIF_GLOBAL_ENABLE 0x0 #define TEGRA_ADMAIF_GLOBAL_CG_0 0x8 @@ -66,6 +75,7 @@ #define SW_RESET_MASK 1 #define SW_RESET 1 /* Default values - Tegra210 */ +#define TEGRA210_ADMAIF_CIF_REG_DEFAULT 0x00007700 #define TEGRA210_ADMAIF_RX1_FIFO_CTRL_REG_DEFAULT 0x00000300 #define TEGRA210_ADMAIF_RX2_FIFO_CTRL_REG_DEFAULT 0x00000304 #define TEGRA210_ADMAIF_RX3_FIFO_CTRL_REG_DEFAULT 0x00000208 @@ -87,6 +97,7 @@ #define TEGRA210_ADMAIF_TX9_FIFO_CTRL_REG_DEFAULT 0x0180021a #define TEGRA210_ADMAIF_TX10_FIFO_CTRL_REG_DEFAULT 0x0180021d /* Default values - Tegra186 */ +#define TEGRA186_ADMAIF_CIF_REG_DEFAULT 0x00007700 #define TEGRA186_ADMAIF_RX1_FIFO_CTRL_REG_DEFAULT 0x00000300 #define TEGRA186_ADMAIF_RX2_FIFO_CTRL_REG_DEFAULT 0x00000304 #define TEGRA186_ADMAIF_RX3_FIFO_CTRL_REG_DEFAULT 0x00000308 @@ -127,6 +138,72 @@ #define TEGRA186_ADMAIF_TX18_FIFO_CTRL_REG_DEFAULT 0x01800237 #define TEGRA186_ADMAIF_TX19_FIFO_CTRL_REG_DEFAULT 0x0180023a #define TEGRA186_ADMAIF_TX20_FIFO_CTRL_REG_DEFAULT 0x0180023d +/* Default values - Tegra264 */ +#define TEGRA264_ADMAIF_CIF_REG_DEFAULT 0x00003f00 +#define TEGRA264_ADMAIF_RX1_FIFO_CTRL_REG_DEFAULT 0x00000200 +#define TEGRA264_ADMAIF_RX2_FIFO_CTRL_REG_DEFAULT 0x00000203 +#define TEGRA264_ADMAIF_RX3_FIFO_CTRL_REG_DEFAULT 0x00000206 +#define TEGRA264_ADMAIF_RX4_FIFO_CTRL_REG_DEFAULT 0x00000209 +#define TEGRA264_ADMAIF_RX5_FIFO_CTRL_REG_DEFAULT 0x0000020c +#define TEGRA264_ADMAIF_RX6_FIFO_CTRL_REG_DEFAULT 0x0000020f +#define TEGRA264_ADMAIF_RX7_FIFO_CTRL_REG_DEFAULT 0x00000212 +#define TEGRA264_ADMAIF_RX8_FIFO_CTRL_REG_DEFAULT 0x00000215 +#define TEGRA264_ADMAIF_RX9_FIFO_CTRL_REG_DEFAULT 0x00000218 +#define TEGRA264_ADMAIF_RX10_FIFO_CTRL_REG_DEFAULT 0x0000021b +#define TEGRA264_ADMAIF_RX11_FIFO_CTRL_REG_DEFAULT 0x0000021e +#define TEGRA264_ADMAIF_RX12_FIFO_CTRL_REG_DEFAULT 0x00000221 +#define TEGRA264_ADMAIF_RX13_FIFO_CTRL_REG_DEFAULT 0x00000224 +#define TEGRA264_ADMAIF_RX14_FIFO_CTRL_REG_DEFAULT 0x00000227 +#define TEGRA264_ADMAIF_RX15_FIFO_CTRL_REG_DEFAULT 0x0000022a +#define TEGRA264_ADMAIF_RX16_FIFO_CTRL_REG_DEFAULT 0x0000022d +#define TEGRA264_ADMAIF_RX17_FIFO_CTRL_REG_DEFAULT 0x00000230 +#define TEGRA264_ADMAIF_RX18_FIFO_CTRL_REG_DEFAULT 0x00000233 +#define TEGRA264_ADMAIF_RX19_FIFO_CTRL_REG_DEFAULT 0x00000236 +#define TEGRA264_ADMAIF_RX20_FIFO_CTRL_REG_DEFAULT 0x00000239 +#define TEGRA264_ADMAIF_RX21_FIFO_CTRL_REG_DEFAULT 0x0000023c +#define TEGRA264_ADMAIF_RX22_FIFO_CTRL_REG_DEFAULT 0x0000023f +#define TEGRA264_ADMAIF_RX23_FIFO_CTRL_REG_DEFAULT 0x00000242 +#define TEGRA264_ADMAIF_RX24_FIFO_CTRL_REG_DEFAULT 0x00000245 +#define TEGRA264_ADMAIF_RX25_FIFO_CTRL_REG_DEFAULT 0x00000248 +#define TEGRA264_ADMAIF_RX26_FIFO_CTRL_REG_DEFAULT 0x0000024b +#define TEGRA264_ADMAIF_RX27_FIFO_CTRL_REG_DEFAULT 0x0000024e +#define TEGRA264_ADMAIF_RX28_FIFO_CTRL_REG_DEFAULT 0x00000251 +#define TEGRA264_ADMAIF_RX29_FIFO_CTRL_REG_DEFAULT 0x00000254 +#define TEGRA264_ADMAIF_RX30_FIFO_CTRL_REG_DEFAULT 0x00000257 +#define TEGRA264_ADMAIF_RX31_FIFO_CTRL_REG_DEFAULT 0x0000025a +#define TEGRA264_ADMAIF_RX32_FIFO_CTRL_REG_DEFAULT 0x0000025d +#define TEGRA264_ADMAIF_TX1_FIFO_CTRL_REG_DEFAULT 0x01800200 +#define TEGRA264_ADMAIF_TX2_FIFO_CTRL_REG_DEFAULT 0x01800203 +#define TEGRA264_ADMAIF_TX3_FIFO_CTRL_REG_DEFAULT 0x01800206 +#define TEGRA264_ADMAIF_TX4_FIFO_CTRL_REG_DEFAULT 0x01800209 +#define TEGRA264_ADMAIF_TX5_FIFO_CTRL_REG_DEFAULT 0x0180020c +#define TEGRA264_ADMAIF_TX6_FIFO_CTRL_REG_DEFAULT 0x0180020f +#define TEGRA264_ADMAIF_TX7_FIFO_CTRL_REG_DEFAULT 0x01800212 +#define TEGRA264_ADMAIF_TX8_FIFO_CTRL_REG_DEFAULT 0x01800215 +#define TEGRA264_ADMAIF_TX9_FIFO_CTRL_REG_DEFAULT 0x01800218 +#define TEGRA264_ADMAIF_TX10_FIFO_CTRL_REG_DEFAULT 0x0180021b +#define TEGRA264_ADMAIF_TX11_FIFO_CTRL_REG_DEFAULT 0x0180021e +#define TEGRA264_ADMAIF_TX12_FIFO_CTRL_REG_DEFAULT 0x01800221 +#define TEGRA264_ADMAIF_TX13_FIFO_CTRL_REG_DEFAULT 0x01800224 +#define TEGRA264_ADMAIF_TX14_FIFO_CTRL_REG_DEFAULT 0x01800227 +#define TEGRA264_ADMAIF_TX15_FIFO_CTRL_REG_DEFAULT 0x0180022a +#define TEGRA264_ADMAIF_TX16_FIFO_CTRL_REG_DEFAULT 0x0180022d +#define TEGRA264_ADMAIF_TX17_FIFO_CTRL_REG_DEFAULT 0x01800230 +#define TEGRA264_ADMAIF_TX18_FIFO_CTRL_REG_DEFAULT 0x01800233 +#define TEGRA264_ADMAIF_TX19_FIFO_CTRL_REG_DEFAULT 0x01800236 +#define TEGRA264_ADMAIF_TX20_FIFO_CTRL_REG_DEFAULT 0x01800239 +#define TEGRA264_ADMAIF_TX21_FIFO_CTRL_REG_DEFAULT 0x0180023c +#define TEGRA264_ADMAIF_TX22_FIFO_CTRL_REG_DEFAULT 0x0180023f +#define TEGRA264_ADMAIF_TX23_FIFO_CTRL_REG_DEFAULT 0x01800242 +#define TEGRA264_ADMAIF_TX24_FIFO_CTRL_REG_DEFAULT 0x01800245 +#define TEGRA264_ADMAIF_TX25_FIFO_CTRL_REG_DEFAULT 0x01800248 +#define TEGRA264_ADMAIF_TX26_FIFO_CTRL_REG_DEFAULT 0x0180024b +#define TEGRA264_ADMAIF_TX27_FIFO_CTRL_REG_DEFAULT 0x0180024e +#define TEGRA264_ADMAIF_TX28_FIFO_CTRL_REG_DEFAULT 0x01800251 +#define TEGRA264_ADMAIF_TX29_FIFO_CTRL_REG_DEFAULT 0x01800254 +#define TEGRA264_ADMAIF_TX30_FIFO_CTRL_REG_DEFAULT 0x01800257 +#define TEGRA264_ADMAIF_TX31_FIFO_CTRL_REG_DEFAULT 0x0180025a +#define TEGRA264_ADMAIF_TX32_FIFO_CTRL_REG_DEFAULT 0x0180025d enum { DATA_8BIT, @@ -148,6 +225,7 @@ struct tegra_admaif_soc_data { unsigned int tx_base; unsigned int rx_base; unsigned int num_ch; + unsigned int max_stream_ch; }; struct tegra_admaif { -- cgit v1.2.3 From fa83757df3f40c05b5ab4154253e8aeefa31a9a6 Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:41 +0000 Subject: ASoC: tegra: ASRC: Update ARAM address The ARAM address for Tegra264 has been updated. To maintain backward compatibility given its chip-specific nature, it's now included in the soc_data. Signed-off-by: Sheetal Link: https://patch.msgid.link/20250512051747.1026770-6-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra186_asrc.c | 18 ++++++++++++++---- sound/soc/tegra/tegra186_asrc.h | 12 ++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra186_asrc.c b/sound/soc/tegra/tegra186_asrc.c index 5c67e1f01d9b..851509ae07f5 100644 --- a/sound/soc/tegra/tegra186_asrc.c +++ b/sound/soc/tegra/tegra186_asrc.c @@ -1,8 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION. All rights reserved. // // tegra186_asrc.c - Tegra186 ASRC driver -// -// Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. #include #include @@ -99,7 +98,7 @@ static int tegra186_asrc_runtime_resume(struct device *dev) * sync is done after this to restore other settings. */ regmap_write(asrc->regmap, TEGRA186_ASRC_GLOBAL_SCRATCH_ADDR, - TEGRA186_ASRC_ARAM_START_ADDR); + asrc->soc_data->aram_start_addr); regmap_write(asrc->regmap, TEGRA186_ASRC_GLOBAL_ENB, TEGRA186_ASRC_GLOBAL_EN); @@ -954,8 +953,17 @@ static const struct regmap_config tegra186_asrc_regmap_config = { .cache_type = REGCACHE_FLAT, }; +static const struct tegra_asrc_soc_data soc_data_tegra186 = { + .aram_start_addr = TEGRA186_ASRC_ARAM_START_ADDR, +}; + +static const struct tegra_asrc_soc_data soc_data_tegra264 = { + .aram_start_addr = TEGRA264_ASRC_ARAM_START_ADDR, +}; + static const struct of_device_id tegra186_asrc_of_match[] = { - { .compatible = "nvidia,tegra186-asrc" }, + { .compatible = "nvidia,tegra186-asrc", .data = &soc_data_tegra186 }, + { .compatible = "nvidia,tegra264-asrc", .data = &soc_data_tegra264 }, {}, }; MODULE_DEVICE_TABLE(of, tegra186_asrc_of_match); @@ -985,6 +993,8 @@ static int tegra186_asrc_platform_probe(struct platform_device *pdev) return PTR_ERR(asrc->regmap); } + asrc->soc_data = of_device_get_match_data(&pdev->dev); + regcache_cache_only(asrc->regmap, true); regmap_write(asrc->regmap, TEGRA186_ASRC_GLOBAL_CFG, diff --git a/sound/soc/tegra/tegra186_asrc.h b/sound/soc/tegra/tegra186_asrc.h index 094fcc723c02..0c98e26d5e72 100644 --- a/sound/soc/tegra/tegra186_asrc.h +++ b/sound/soc/tegra/tegra186_asrc.h @@ -1,9 +1,7 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* +/* SPDX-License-Identifier: GPL-2.0-only + * SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION. All rights reserved. * tegra186_asrc.h - Definitions for Tegra186 ASRC driver * - * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - * */ #ifndef __TEGRA186_ASRC_H__ @@ -94,6 +92,7 @@ #define TEGRA186_ASRC_RATIO_SOURCE_SW 0x1 #define TEGRA186_ASRC_ARAM_START_ADDR 0x3f800000 +#define TEGRA264_ASRC_ARAM_START_ADDR 0x8a080000 struct tegra186_asrc_lane { unsigned int int_part; @@ -104,7 +103,12 @@ struct tegra186_asrc_lane { unsigned int output_thresh; }; +struct tegra_asrc_soc_data { + unsigned int aram_start_addr; +}; + struct tegra186_asrc { + const struct tegra_asrc_soc_data *soc_data; struct tegra186_asrc_lane lane[TEGRA186_ASRC_STREAM_MAX]; struct regmap *regmap; }; -- cgit v1.2.3 From 1fb500476f609008ee1c499540af32c4fa5a19de Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:42 +0000 Subject: ASoC: tegra: Update PLL rate for Tegra264 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PLLs should be set with a VCO frequency in the 900MHz – 1GHz range to minimize jitter and ppm error for Tegra264. Add the PLLA rate accordingly. Therefore, use 983040000 frequency is for multiple of 8K frequencies and 993484800 frequency is for multiple of 11.025K frequencies. Signed-off-by: Sheetal Link: https://patch.msgid.link/20250512051747.1026770-7-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_audio_graph_card.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c index 8b48813c2c59..94b5ab77649b 100644 --- a/sound/soc/tegra/tegra_audio_graph_card.c +++ b/sound/soc/tegra/tegra_audio_graph_card.c @@ -1,8 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION. All rights reserved. // // tegra_audio_graph_card.c - Audio Graph based Tegra Machine Driver -// -// Copyright (c) 2020-2021 NVIDIA CORPORATION. All rights reserved. #include #include @@ -232,11 +231,22 @@ static const struct tegra_audio_cdata tegra186_data = { .plla_out0_rates[x11_RATE] = 45158400, }; +static const struct tegra_audio_cdata tegra264_data = { + /* PLLA1 */ + .plla_rates[x8_RATE] = 983040000, + .plla_rates[x11_RATE] = 993484800, + /* PLLA1_OUT1 */ + .plla_out0_rates[x8_RATE] = 49152000, + .plla_out0_rates[x11_RATE] = 45158400, +}; + static const struct of_device_id graph_of_tegra_match[] = { { .compatible = "nvidia,tegra210-audio-graph-card", .data = &tegra210_data }, { .compatible = "nvidia,tegra186-audio-graph-card", .data = &tegra186_data }, + { .compatible = "nvidia,tegra264-audio-graph-card", + .data = &tegra264_data }, {}, }; MODULE_DEVICE_TABLE(of, graph_of_tegra_match); -- cgit v1.2.3 From b3354438d89867654b4a95a9630fd3393e275e33 Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:43 +0000 Subject: ASoC: tegra: I2S: Add Tegra264 support Add Tegra264 I2S support with following changes: - Add soc_data for Tegra264-specific variations - Tegra264 I2S supports 32 audio channels, hence update the TDM config, CIF configuration API and DAI channel_max parameter. - Register offsets and default values are updated to align with Tegra264. Signed-off-by: Sheetal Link: https://patch.msgid.link/20250512051747.1026770-8-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_i2s.c | 231 ++++++++++++++++++++++++++++++++--------- sound/soc/tegra/tegra210_i2s.h | 51 ++++++++- 2 files changed, 233 insertions(+), 49 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c index 766cddebd5f6..100277c39001 100644 --- a/sound/soc/tegra/tegra210_i2s.c +++ b/sound/soc/tegra/tegra210_i2s.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -// SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES. +// SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES. // All rights reserved. // // tegra210_i2s.c - Tegra210 I2S driver @@ -36,14 +36,28 @@ static const struct reg_default tegra210_i2s_reg_defaults[] = { { TEGRA210_I2S_CYA, 0x1 }, }; -static void tegra210_i2s_set_slot_ctrl(struct regmap *regmap, +static const struct reg_default tegra264_i2s_reg_defaults[] = { + { TEGRA210_I2S_RX_INT_MASK, 0x00000003 }, + { TEGRA210_I2S_RX_CIF_CTRL, 0x00003f00 }, + { TEGRA264_I2S_TX_INT_MASK, 0x00000003 }, + { TEGRA264_I2S_TX_CIF_CTRL, 0x00003f00 }, + { TEGRA264_I2S_CG, 0x1 }, + { TEGRA264_I2S_TIMING, 0x0000001f }, + { TEGRA264_I2S_ENABLE, 0x1 }, + { TEGRA264_I2S_RX_FIFO_WR_ACCESS_MODE, 0x1 }, + { TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE, 0x1 }, +}; + +static void tegra210_i2s_set_slot_ctrl(struct tegra210_i2s *i2s, unsigned int total_slots, unsigned int tx_slot_mask, unsigned int rx_slot_mask) { - regmap_write(regmap, TEGRA210_I2S_SLOT_CTRL, total_slots - 1); - regmap_write(regmap, TEGRA210_I2S_TX_SLOT_CTRL, tx_slot_mask); - regmap_write(regmap, TEGRA210_I2S_RX_SLOT_CTRL, rx_slot_mask); + regmap_write(i2s->regmap, TEGRA210_I2S_SLOT_CTRL + i2s->soc_data->i2s_ctrl_offset, + total_slots - 1); + regmap_write(i2s->regmap, TEGRA210_I2S_TX_SLOT_CTRL + i2s->soc_data->tx_offset, + tx_slot_mask); + regmap_write(i2s->regmap, TEGRA210_I2S_RX_SLOT_CTRL, rx_slot_mask); } static int tegra210_i2s_set_clock_rate(struct device *dev, @@ -53,7 +67,7 @@ static int tegra210_i2s_set_clock_rate(struct device *dev, unsigned int val; int err; - regmap_read(i2s->regmap, TEGRA210_I2S_CTRL, &val); + regmap_read(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, &val); /* No need to set rates if I2S is being operated in slave */ if (!(val & I2S_CTRL_MASTER_EN)) @@ -100,15 +114,15 @@ static int tegra210_i2s_sw_reset(struct snd_soc_component *compnt, cif_reg = TEGRA210_I2S_RX_CIF_CTRL; stream_reg = TEGRA210_I2S_RX_CTRL; } else { - reset_reg = TEGRA210_I2S_TX_SOFT_RESET; - cif_reg = TEGRA210_I2S_TX_CIF_CTRL; - stream_reg = TEGRA210_I2S_TX_CTRL; + reset_reg = TEGRA210_I2S_TX_SOFT_RESET + i2s->soc_data->tx_offset; + cif_reg = TEGRA210_I2S_TX_CIF_CTRL + i2s->soc_data->tx_offset; + stream_reg = TEGRA210_I2S_TX_CTRL + i2s->soc_data->tx_offset; } /* Store CIF and I2S control values */ regmap_read(i2s->regmap, cif_reg, &cif_ctrl); regmap_read(i2s->regmap, stream_reg, &stream_ctrl); - regmap_read(i2s->regmap, TEGRA210_I2S_CTRL, &i2s_ctrl); + regmap_read(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, &i2s_ctrl); /* Reset to make sure the previous transactions are clean */ regmap_update_bits(i2s->regmap, reset_reg, reset_mask, reset_en); @@ -125,7 +139,7 @@ static int tegra210_i2s_sw_reset(struct snd_soc_component *compnt, /* Restore CIF and I2S control values */ regmap_write(i2s->regmap, cif_reg, cif_ctrl); regmap_write(i2s->regmap, stream_reg, stream_ctrl); - regmap_write(i2s->regmap, TEGRA210_I2S_CTRL, i2s_ctrl); + regmap_write(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, i2s_ctrl); return 0; } @@ -140,16 +154,13 @@ static int tegra210_i2s_init(struct snd_soc_dapm_widget *w, int stream; int err; - switch (w->reg) { - case TEGRA210_I2S_RX_ENABLE: + if (w->reg == TEGRA210_I2S_RX_ENABLE) { stream = SNDRV_PCM_STREAM_PLAYBACK; status_reg = TEGRA210_I2S_RX_STATUS; - break; - case TEGRA210_I2S_TX_ENABLE: + } else if (w->reg == (TEGRA210_I2S_TX_ENABLE + i2s->soc_data->tx_offset)) { stream = SNDRV_PCM_STREAM_CAPTURE; - status_reg = TEGRA210_I2S_TX_STATUS; - break; - default: + status_reg = TEGRA210_I2S_TX_STATUS + i2s->soc_data->tx_offset; + } else { return -EINVAL; } @@ -199,7 +210,7 @@ static void tegra210_i2s_set_data_offset(struct tegra210_i2s *i2s, unsigned int data_offset) { /* Capture path */ - regmap_update_bits(i2s->regmap, TEGRA210_I2S_TX_CTRL, + regmap_update_bits(i2s->regmap, TEGRA210_I2S_TX_CTRL + i2s->soc_data->tx_offset, I2S_CTRL_DATA_OFFSET_MASK, data_offset << I2S_DATA_SHIFT); @@ -282,7 +293,8 @@ static int tegra210_i2s_set_fmt(struct snd_soc_dai *dai, return -EINVAL; } - regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, mask, val); + regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, + mask, val); i2s->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; @@ -296,10 +308,10 @@ static int tegra210_i2s_set_tdm_slot(struct snd_soc_dai *dai, struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai); /* Copy the required tx and rx mask */ - i2s->tx_mask = (tx_mask > DEFAULT_I2S_SLOT_MASK) ? - DEFAULT_I2S_SLOT_MASK : tx_mask; - i2s->rx_mask = (rx_mask > DEFAULT_I2S_SLOT_MASK) ? - DEFAULT_I2S_SLOT_MASK : rx_mask; + i2s->tx_mask = (tx_mask > i2s->soc_data->slot_mask) ? + i2s->soc_data->slot_mask : tx_mask; + i2s->rx_mask = (rx_mask > i2s->soc_data->slot_mask) ? + i2s->soc_data->slot_mask : rx_mask; return 0; } @@ -327,8 +339,8 @@ static int tegra210_i2s_put_loopback(struct snd_kcontrol *kcontrol, i2s->loopback = value; - regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, I2S_CTRL_LPBK_MASK, - i2s->loopback << I2S_CTRL_LPBK_SHIFT); + regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, + I2S_CTRL_LPBK_MASK, i2s->loopback << I2S_CTRL_LPBK_SHIFT); return 1; } @@ -364,9 +376,9 @@ static int tegra210_i2s_put_fsync_width(struct snd_kcontrol *kcontrol, * cases mixer control is used to update custom values. A value * of "N" here means, width is "N + 1" bit clock wide. */ - regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, - I2S_CTRL_FSYNC_WIDTH_MASK, - i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); + regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, + i2s->soc_data->fsync_width_mask, + i2s->fsync_width << i2s->soc_data->fsync_width_shift); return 1; } @@ -562,7 +574,7 @@ static int tegra210_i2s_set_timing_params(struct device *dev, return err; } - regmap_read(i2s->regmap, TEGRA210_I2S_CTRL, &val); + regmap_read(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, &val); /* * For LRCK mode, channel bit count depends on number of bit clocks @@ -578,7 +590,7 @@ static int tegra210_i2s_set_timing_params(struct device *dev, case I2S_CTRL_FRAME_FMT_FSYNC_MODE: bit_count = (bclk_rate / srate) - 1; - tegra210_i2s_set_slot_ctrl(i2s->regmap, channels, + tegra210_i2s_set_slot_ctrl(i2s, channels, i2s->tx_mask, i2s->rx_mask); break; default: @@ -591,7 +603,7 @@ static int tegra210_i2s_set_timing_params(struct device *dev, return -EINVAL; } - regmap_write(i2s->regmap, TEGRA210_I2S_TIMING, + regmap_write(i2s->regmap, TEGRA210_I2S_TIMING + i2s->soc_data->i2s_ctrl_offset, bit_count << I2S_TIMING_CH_BIT_CNT_SHIFT); return 0; @@ -673,7 +685,7 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, } /* Program sample size */ - regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, + regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, I2S_CTRL_BIT_SIZE_MASK, val); srate = params_rate(params); @@ -697,13 +709,16 @@ static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream, reg = TEGRA210_I2S_RX_CIF_CTRL; } else { - reg = TEGRA210_I2S_TX_CIF_CTRL; + reg = TEGRA210_I2S_TX_CIF_CTRL + i2s->soc_data->tx_offset; } cif_conf.mono_conv = i2s->mono_to_stereo[path]; cif_conf.stereo_conv = i2s->stereo_to_mono[path]; - tegra_set_cif(i2s->regmap, reg, &cif_conf); + if (i2s->soc_data->max_ch == TEGRA264_I2S_MAX_CHANNEL) + tegra264_set_cif(i2s->regmap, reg, &cif_conf); + else + tegra_set_cif(i2s->regmap, reg, &cif_conf); return tegra210_i2s_set_timing_params(dev, sample_size, srate, cif_conf.client_ch); @@ -808,13 +823,20 @@ static const struct snd_kcontrol_new tegra210_i2s_controls[] = { tegra210_i2s_put_bclk_ratio), }; -static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = { - SND_SOC_DAPM_AIF_IN_E("RX", NULL, 0, TEGRA210_I2S_RX_ENABLE, - 0, 0, tegra210_i2s_init, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_AIF_OUT_E("TX", NULL, 0, TEGRA210_I2S_TX_ENABLE, - 0, 0, tegra210_i2s_init, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_MIC("MIC", NULL), +#define TEGRA_I2S_WIDGETS(tx_enable_reg) \ + SND_SOC_DAPM_AIF_IN_E("RX", NULL, 0, TEGRA210_I2S_RX_ENABLE, \ + 0, 0, tegra210_i2s_init, SND_SOC_DAPM_PRE_PMU), \ + SND_SOC_DAPM_AIF_OUT_E("TX", NULL, 0, tx_enable_reg, \ + 0, 0, tegra210_i2s_init, SND_SOC_DAPM_PRE_PMU), \ + SND_SOC_DAPM_MIC("MIC", NULL), \ SND_SOC_DAPM_SPK("SPK", NULL), + +static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = { + TEGRA_I2S_WIDGETS(TEGRA210_I2S_TX_ENABLE) +}; + +static const struct snd_soc_dapm_widget tegra264_i2s_widgets[] = { + TEGRA_I2S_WIDGETS(TEGRA264_I2S_TX_ENABLE) }; static const struct snd_soc_dapm_route tegra210_i2s_routes[] = { @@ -841,6 +863,15 @@ static const struct snd_soc_component_driver tegra210_i2s_cmpnt = { .num_controls = ARRAY_SIZE(tegra210_i2s_controls), }; +static const struct snd_soc_component_driver tegra264_i2s_cmpnt = { + .dapm_widgets = tegra264_i2s_widgets, + .num_dapm_widgets = ARRAY_SIZE(tegra264_i2s_widgets), + .dapm_routes = tegra210_i2s_routes, + .num_dapm_routes = ARRAY_SIZE(tegra210_i2s_routes), + .controls = tegra210_i2s_controls, + .num_controls = ARRAY_SIZE(tegra210_i2s_controls), +}; + static bool tegra210_i2s_wr_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -895,7 +926,68 @@ static bool tegra210_i2s_volatile_reg(struct device *dev, unsigned int reg) } } -static const struct regmap_config tegra210_i2s_regmap_config = { +static bool tegra264_i2s_wr_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TEGRA210_I2S_RX_ENABLE ... TEGRA210_I2S_RX_SOFT_RESET: + case TEGRA210_I2S_RX_INT_MASK ... TEGRA264_I2S_RX_CYA: + case TEGRA264_I2S_TX_ENABLE ... TEGRA264_I2S_TX_SOFT_RESET: + case TEGRA264_I2S_TX_INT_MASK ... TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE: + case TEGRA264_I2S_TX_FIFO_THRESHOLD ... TEGRA264_I2S_TX_CYA: + case TEGRA264_I2S_ENABLE ... TEGRA264_I2S_CG: + case TEGRA264_I2S_INT_SET ... TEGRA264_I2S_INT_MASK: + case TEGRA264_I2S_CTRL ... TEGRA264_I2S_CYA: + return true; + default: + return false; + }; +} + +static bool tegra264_i2s_rd_reg(struct device *dev, unsigned int reg) +{ + if (tegra264_i2s_wr_reg(dev, reg)) + return true; + + switch (reg) { + case TEGRA210_I2S_RX_STATUS: + case TEGRA210_I2S_RX_INT_STATUS: + case TEGRA264_I2S_RX_CIF_FIFO_STATUS: + case TEGRA264_I2S_TX_STATUS: + case TEGRA264_I2S_TX_INT_STATUS: + case TEGRA264_I2S_TX_FIFO_RD_DATA: + case TEGRA264_I2S_TX_CIF_FIFO_STATUS: + case TEGRA264_I2S_STATUS: + case TEGRA264_I2S_INT_STATUS: + case TEGRA264_I2S_PIO_MODE_ENABLE: + case TEGRA264_I2S_PAD_MACRO_STATUS: + return true; + default: + return false; + }; +} + +static bool tegra264_i2s_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TEGRA210_I2S_RX_SOFT_RESET: + case TEGRA210_I2S_RX_STATUS: + case TEGRA210_I2S_RX_INT_STATUS: + case TEGRA264_I2S_RX_CIF_FIFO_STATUS: + case TEGRA264_I2S_TX_STATUS: + case TEGRA264_I2S_TX_INT_STATUS: + case TEGRA264_I2S_TX_FIFO_RD_DATA: + case TEGRA264_I2S_TX_CIF_FIFO_STATUS: + case TEGRA264_I2S_STATUS: + case TEGRA264_I2S_INT_STATUS: + case TEGRA264_I2S_TX_SOFT_RESET: + case TEGRA264_I2S_PAD_MACRO_STATUS: + return true; + default: + return false; + }; +} + +static const struct regmap_config tegra210_regmap_conf = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, @@ -942,20 +1034,34 @@ static void tegra210_parse_client_convert(struct device *dev) i2s->client_sample_format = simple_util_get_sample_fmt(&data); } +static const struct regmap_config tegra264_regmap_conf = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = TEGRA264_I2S_PAD_MACRO_STATUS, + .writeable_reg = tegra264_i2s_wr_reg, + .readable_reg = tegra264_i2s_rd_reg, + .volatile_reg = tegra264_i2s_volatile_reg, + .reg_defaults = tegra264_i2s_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tegra264_i2s_reg_defaults), + .cache_type = REGCACHE_FLAT, +}; + static int tegra210_i2s_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct tegra210_i2s *i2s; void __iomem *regs; - int err; + int err, id; i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL); if (!i2s) return -ENOMEM; + i2s->soc_data = of_device_get_match_data(&pdev->dev); i2s->rx_fifo_th = DEFAULT_I2S_RX_FIFO_THRESHOLD; - i2s->tx_mask = DEFAULT_I2S_SLOT_MASK; - i2s->rx_mask = DEFAULT_I2S_SLOT_MASK; + i2s->tx_mask = i2s->soc_data->slot_mask; + i2s->rx_mask = i2s->soc_data->slot_mask; i2s->loopback = false; i2s->client_sample_format = -EINVAL; @@ -981,7 +1087,7 @@ static int tegra210_i2s_probe(struct platform_device *pdev) return PTR_ERR(regs); i2s->regmap = devm_regmap_init_mmio(dev, regs, - &tegra210_i2s_regmap_config); + i2s->soc_data->regmap_conf); if (IS_ERR(i2s->regmap)) { dev_err(dev, "regmap init failed\n"); return PTR_ERR(i2s->regmap); @@ -991,7 +1097,13 @@ static int tegra210_i2s_probe(struct platform_device *pdev) regcache_cache_only(i2s->regmap, true); - err = devm_snd_soc_register_component(dev, &tegra210_i2s_cmpnt, + /* Update the dais max channel as per soc */ + for (id = 0; id < ARRAY_SIZE(tegra210_i2s_dais); id++) { + tegra210_i2s_dais[id].playback.channels_max = i2s->soc_data->max_ch; + tegra210_i2s_dais[id].capture.channels_max = i2s->soc_data->max_ch; + } + + err = devm_snd_soc_register_component(dev, i2s->soc_data->i2s_cmpnt, tegra210_i2s_dais, ARRAY_SIZE(tegra210_i2s_dais)); if (err) { @@ -1015,8 +1127,31 @@ static const struct dev_pm_ops tegra210_i2s_pm_ops = { SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; +static const struct tegra_i2s_soc_data soc_data_tegra210 = { + .regmap_conf = &tegra210_regmap_conf, + .i2s_cmpnt = &tegra210_i2s_cmpnt, + .max_ch = TEGRA210_I2S_MAX_CHANNEL, + .tx_offset = TEGRA210_I2S_TX_OFFSET, + .i2s_ctrl_offset = TEGRA210_I2S_CTRL_OFFSET, + .fsync_width_mask = I2S_CTRL_FSYNC_WIDTH_MASK, + .fsync_width_shift = I2S_FSYNC_WIDTH_SHIFT, + .slot_mask = DEFAULT_I2S_SLOT_MASK, +}; + +static const struct tegra_i2s_soc_data soc_data_tegra264 = { + .regmap_conf = &tegra264_regmap_conf, + .i2s_cmpnt = &tegra264_i2s_cmpnt, + .max_ch = TEGRA264_I2S_MAX_CHANNEL, + .tx_offset = TEGRA264_I2S_TX_OFFSET, + .i2s_ctrl_offset = TEGRA264_I2S_CTRL_OFFSET, + .fsync_width_mask = TEGRA264_I2S_CTRL_FSYNC_WIDTH_MASK, + .fsync_width_shift = TEGRA264_I2S_FSYNC_WIDTH_SHIFT, + .slot_mask = TEGRA264_DEFAULT_I2S_SLOT_MASK, +}; + static const struct of_device_id tegra210_i2s_of_match[] = { - { .compatible = "nvidia,tegra210-i2s" }, + { .compatible = "nvidia,tegra210-i2s", .data = &soc_data_tegra210 }, + { .compatible = "nvidia,tegra264-i2s", .data = &soc_data_tegra264 }, {}, }; MODULE_DEVICE_TABLE(of, tegra210_i2s_of_match); diff --git a/sound/soc/tegra/tegra210_i2s.h b/sound/soc/tegra/tegra210_i2s.h index 543332de7405..42be2137342c 100644 --- a/sound/soc/tegra/tegra210_i2s.h +++ b/sound/soc/tegra/tegra210_i2s.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only - * SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES. + * SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES. * All rights reserved. * * tegra210_i2s.h - Definitions for Tegra210 I2S driver @@ -47,9 +47,38 @@ #define TEGRA210_I2S_CLK_TRIM 0xac #define TEGRA210_I2S_CYA 0xb0 +/* T264 specific registers */ +#define TEGRA264_I2S_RX_FIFO_WR_ACCESS_MODE 0x30 +#define TEGRA264_I2S_RX_CYA 0x3c +#define TEGRA264_I2S_RX_CIF_FIFO_STATUS 0x40 +#define TEGRA264_I2S_TX_ENABLE 0x80 +#define TEGRA264_I2S_TX_SOFT_RESET 0x84 +#define TEGRA264_I2S_TX_STATUS 0x8c +#define TEGRA264_I2S_TX_INT_STATUS 0x90 +#define TEGRA264_I2S_TX_INT_MASK 0x94 +#define TEGRA264_I2S_TX_CIF_CTRL 0xa0 +#define TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE 0xb0 +#define TEGRA264_I2S_TX_FIFO_RD_DATA 0xb4 +#define TEGRA264_I2S_TX_FIFO_THRESHOLD 0xb8 +#define TEGRA264_I2S_TX_CYA 0xbc +#define TEGRA264_I2S_TX_CIF_FIFO_STATUS 0xc0 +#define TEGRA264_I2S_ENABLE 0x100 +#define TEGRA264_I2S_CG 0x108 +#define TEGRA264_I2S_STATUS 0x10c +#define TEGRA264_I2S_INT_STATUS 0x110 +#define TEGRA264_I2S_INT_SET 0x114 +#define TEGRA264_I2S_INT_MASK 0x11c +#define TEGRA264_I2S_CTRL 0x12c +#define TEGRA264_I2S_TIMING 0x130 +#define TEGRA264_I2S_CYA 0x13c +#define TEGRA264_I2S_PIO_MODE_ENABLE 0x140 +#define TEGRA264_I2S_PAD_MACRO_STATUS 0x144 + /* Bit fields, shifts and masks */ #define I2S_DATA_SHIFT 8 #define I2S_CTRL_DATA_OFFSET_MASK (0x7ff << I2S_DATA_SHIFT) +#define TEGRA264_I2S_FSYNC_WIDTH_SHIFT 23 +#define TEGRA264_I2S_CTRL_FSYNC_WIDTH_MASK (0x1ff << TEGRA264_I2S_FSYNC_WIDTH_SHIFT) #define I2S_EN_SHIFT 0 #define I2S_EN_MASK BIT(I2S_EN_SHIFT) @@ -102,6 +131,14 @@ #define DEFAULT_I2S_RX_FIFO_THRESHOLD 3 #define DEFAULT_I2S_SLOT_MASK 0xffff +#define TEGRA210_I2S_TX_OFFSET 0 +#define TEGRA210_I2S_CTRL_OFFSET 0 +#define TEGRA210_I2S_MAX_CHANNEL 16 + +#define TEGRA264_DEFAULT_I2S_SLOT_MASK 0xffffffff +#define TEGRA264_I2S_TX_OFFSET 0x40 +#define TEGRA264_I2S_CTRL_OFFSET 0x8c +#define TEGRA264_I2S_MAX_CHANNEL 32 enum tegra210_i2s_path { I2S_RX_PATH, @@ -109,7 +146,19 @@ enum tegra210_i2s_path { I2S_PATHS, }; +struct tegra_i2s_soc_data { + const struct regmap_config *regmap_conf; + const struct snd_soc_component_driver *i2s_cmpnt; + unsigned int max_ch; + unsigned int tx_offset; + unsigned int i2s_ctrl_offset; + unsigned int fsync_width_mask; + unsigned int fsync_width_shift; + unsigned int slot_mask; +}; + struct tegra210_i2s { + const struct tegra_i2s_soc_data *soc_data; struct clk *clk_i2s; struct clk *clk_sync_input; struct regmap *regmap; -- cgit v1.2.3 From fd509c6f8e4028539bf35d80e3bcdce7b3ba0f9f Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:44 +0000 Subject: 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 Link: https://patch.msgid.link/20250512051747.1026770-9-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_amx.c | 229 ++++++++++++++++++++++++++++++++++++++--- sound/soc/tegra/tegra210_amx.h | 34 ++++-- 2 files changed, 241 insertions(+), 22 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra210_amx.c b/sound/soc/tegra/tegra210_amx.c index 1981b94009cf..7f558c40e097 100644 --- a/sound/soc/tegra/tegra210_amx.c +++ b/sound/soc/tegra/tegra210_amx.c @@ -1,5 +1,5 @@ // 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. // // 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}, }; +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) { 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_ADDR_INIT_EN | TEGRA210_AMX_CFG_RAM_CTRL_RW_WRITE); - for (i = 0; i < TEGRA210_AMX_RAM_DEPTH; i++) - regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_DATA, + for (i = 0; i < amx->soc_data->ram_depth; i++) + regmap_write(amx->regmap, TEGRA210_AMX_CFG_RAM_DATA + amx->soc_data->reg_offset, amx->map[i]); - regmap_write(amx->regmap, TEGRA210_AMX_OUT_BYTE_EN0, amx->byte_mask[0]); - regmap_write(amx->regmap, TEGRA210_AMX_OUT_BYTE_EN1, amx->byte_mask[1]); + for (i = 0; i < amx->soc_data->byte_mask_size; i++) + 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, @@ -157,7 +171,10 @@ static int tegra210_amx_set_audio_cif(struct snd_soc_dai *dai, cif_conf.audio_bits = audio_bits; cif_conf.client_bits = audio_bits; - tegra_set_cif(amx->regmap, reg, &cif_conf); + 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); return 0; } @@ -170,9 +187,10 @@ static int tegra210_amx_in_hw_params(struct snd_pcm_substream *substream, if (amx->soc_data->auto_disable) { 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); - 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, @@ -194,14 +212,11 @@ static int tegra210_amx_get_byte_map(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; 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 enabled; - if (reg > 31) - enabled = amx->byte_mask[1] & (1 << (reg - 32)); - else - enabled = amx->byte_mask[0] & (1 << reg); + enabled = amx->byte_mask[reg / 32] & (1 << (reg % 32)); /* * 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 snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 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 value = ucontrol->value.integer.value[0]; 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), }; +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 = { + .probe = tegra210_amx_component_probe, .dapm_widgets = tegra210_amx_widgets, .num_dapm_widgets = ARRAY_SIZE(tegra210_amx_widgets), .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) { 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) { switch (reg) { @@ -492,6 +621,29 @@ static bool tegra210_amx_volatile_reg(struct device *dev, unsigned int reg) 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 = { .reg_bits = 32, .reg_stride = 4, @@ -518,18 +670,51 @@ static const struct regmap_config tegra194_amx_regmap_config = { .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 = { .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 = { .regmap_conf = &tegra194_amx_regmap_config, .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[] = { { .compatible = "nvidia,tegra210-amx", .data = &soc_data_tegra210 }, { .compatible = "nvidia,tegra194-amx", .data = &soc_data_tegra194 }, + { .compatible = "nvidia,tegra264-amx", .data = &soc_data_tegra264 }, {}, }; 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); + 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, tegra210_amx_dais, ARRAY_SIZE(tegra210_amx_dais)); diff --git a/sound/soc/tegra/tegra210_amx.h b/sound/soc/tegra/tegra210_amx.h index e277741e4258..50a237b197ba 100644 --- a/sound/soc/tegra/tegra210_amx.h +++ b/sound/soc/tegra/tegra210_amx.h @@ -1,8 +1,7 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * tegra210_amx.h - Definitions for Tegra210 AMX driver +/* SPDX-License-Identifier: GPL-2.0-only + * SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION. All rights reserved. * - * 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_CTRL 0xa4 #define TEGRA210_AMX_OUT_BYTE_EN0 0xa8 -#define TEGRA210_AMX_OUT_BYTE_EN1 0xac #define TEGRA210_AMX_CYA 0xb0 #define TEGRA210_AMX_CFG_RAM_CTRL 0xb8 #define TEGRA210_AMX_CFG_RAM_DATA 0xbc @@ -41,6 +39,13 @@ #define TEGRA194_AMX_RX4_FRAME_PERIOD 0xcc #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 */ #define TEGRA210_AMX_ENABLE_SHIFT 0 @@ -72,6 +77,15 @@ #define TEGRA210_AMX_MAP_STREAM_NUM_SHIFT 6 #define TEGRA210_AMX_MAP_WORD_NUM_SHIFT 2 #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 { TEGRA210_AMX_WAIT_ON_ALL, @@ -81,13 +95,19 @@ enum { struct tegra210_amx_soc_data { const struct regmap_config *regmap_conf; 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 { 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; - unsigned int byte_mask[2]; }; #endif -- cgit v1.2.3 From 7dc8299fbb1c8e6373e8e55d562b7674ee37b2b0 Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:45 +0000 Subject: ASoC: tegra: ADX: Add Tegra264 support Add Tegra264 ADX support with following changes: - Add soc_data for Tegra264-specific variations - Tegra264 ADX supports 32 input channels, hence update the playback 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 Link: https://patch.msgid.link/20250512051747.1026770-10-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_adx.c | 229 +++++++++++++++++++++++++++++++++++++++-- sound/soc/tegra/tegra210_adx.h | 36 +++++-- 2 files changed, 248 insertions(+), 17 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c index b6c798baedea..ad7cd8655047 100644 --- a/sound/soc/tegra/tegra210_adx.c +++ b/sound/soc/tegra/tegra210_adx.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -32,21 +33,37 @@ static const struct reg_default tegra210_adx_reg_defaults[] = { { 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) { int i; - regmap_write(adx->regmap, TEGRA210_ADX_CFG_RAM_CTRL, + 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 < TEGRA210_ADX_RAM_DEPTH; i++) - regmap_write(adx->regmap, TEGRA210_ADX_CFG_RAM_DATA, + for (i = 0; i < adx->soc_data->ram_depth; i++) + regmap_write(adx->regmap, TEGRA210_ADX_CFG_RAM_DATA + + adx->soc_data->cya_offset, adx->map[i]); - regmap_write(adx->regmap, TEGRA210_ADX_IN_BYTE_EN0, adx->byte_mask[0]); - regmap_write(adx->regmap, TEGRA210_ADX_IN_BYTE_EN1, adx->byte_mask[1]); + 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, @@ -117,7 +134,7 @@ static int tegra210_adx_set_audio_cif(struct snd_soc_dai *dai, memset(&cif_conf, 0, sizeof(struct tegra_cif_conf)); - if (channels < 1 || channels > 16) + if (channels < 1 || channels > adx->soc_data->max_ch) return -EINVAL; switch (format) { @@ -140,7 +157,10 @@ static int tegra210_adx_set_audio_cif(struct snd_soc_dai *dai, cif_conf.audio_bits = audio_bits; cif_conf.client_bits = audio_bits; - tegra_set_cif(adx->regmap, reg, &cif_conf); + if (adx->soc_data->max_ch == 32) + tegra264_set_cif(adx->regmap, reg, &cif_conf); + else + tegra_set_cif(adx->regmap, reg, &cif_conf); return 0; } @@ -169,7 +189,7 @@ static int tegra210_adx_get_byte_map(struct snd_kcontrol *kcontrol, struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); struct tegra210_adx *adx = snd_soc_component_get_drvdata(cmpnt); struct soc_mixer_control *mc; - unsigned char *bytes_map = (unsigned char *)&adx->map; + unsigned char *bytes_map = (unsigned char *)adx->map; int enabled; mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -198,7 +218,7 @@ static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol, { struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); struct tegra210_adx *adx = snd_soc_component_get_drvdata(cmpnt); - unsigned char *bytes_map = (unsigned char *)&adx->map; + unsigned char *bytes_map = (unsigned char *)adx->map; int value = ucontrol->value.integer.value[0]; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -402,7 +422,90 @@ static struct snd_kcontrol_new tegra210_adx_controls[] = { TEGRA210_ADX_BYTE_MAP_CTRL(63), }; +static struct snd_kcontrol_new tegra264_adx_controls[] = { + TEGRA210_ADX_BYTE_MAP_CTRL(64), + TEGRA210_ADX_BYTE_MAP_CTRL(65), + TEGRA210_ADX_BYTE_MAP_CTRL(66), + TEGRA210_ADX_BYTE_MAP_CTRL(67), + TEGRA210_ADX_BYTE_MAP_CTRL(68), + TEGRA210_ADX_BYTE_MAP_CTRL(69), + TEGRA210_ADX_BYTE_MAP_CTRL(70), + TEGRA210_ADX_BYTE_MAP_CTRL(71), + TEGRA210_ADX_BYTE_MAP_CTRL(72), + TEGRA210_ADX_BYTE_MAP_CTRL(73), + TEGRA210_ADX_BYTE_MAP_CTRL(74), + TEGRA210_ADX_BYTE_MAP_CTRL(75), + TEGRA210_ADX_BYTE_MAP_CTRL(76), + TEGRA210_ADX_BYTE_MAP_CTRL(77), + TEGRA210_ADX_BYTE_MAP_CTRL(78), + TEGRA210_ADX_BYTE_MAP_CTRL(79), + TEGRA210_ADX_BYTE_MAP_CTRL(80), + TEGRA210_ADX_BYTE_MAP_CTRL(81), + TEGRA210_ADX_BYTE_MAP_CTRL(82), + TEGRA210_ADX_BYTE_MAP_CTRL(83), + TEGRA210_ADX_BYTE_MAP_CTRL(84), + TEGRA210_ADX_BYTE_MAP_CTRL(85), + TEGRA210_ADX_BYTE_MAP_CTRL(86), + TEGRA210_ADX_BYTE_MAP_CTRL(87), + TEGRA210_ADX_BYTE_MAP_CTRL(88), + TEGRA210_ADX_BYTE_MAP_CTRL(89), + TEGRA210_ADX_BYTE_MAP_CTRL(90), + TEGRA210_ADX_BYTE_MAP_CTRL(91), + TEGRA210_ADX_BYTE_MAP_CTRL(92), + TEGRA210_ADX_BYTE_MAP_CTRL(93), + TEGRA210_ADX_BYTE_MAP_CTRL(94), + TEGRA210_ADX_BYTE_MAP_CTRL(95), + TEGRA210_ADX_BYTE_MAP_CTRL(96), + TEGRA210_ADX_BYTE_MAP_CTRL(97), + TEGRA210_ADX_BYTE_MAP_CTRL(98), + TEGRA210_ADX_BYTE_MAP_CTRL(99), + TEGRA210_ADX_BYTE_MAP_CTRL(100), + TEGRA210_ADX_BYTE_MAP_CTRL(101), + TEGRA210_ADX_BYTE_MAP_CTRL(102), + TEGRA210_ADX_BYTE_MAP_CTRL(103), + TEGRA210_ADX_BYTE_MAP_CTRL(104), + TEGRA210_ADX_BYTE_MAP_CTRL(105), + TEGRA210_ADX_BYTE_MAP_CTRL(106), + TEGRA210_ADX_BYTE_MAP_CTRL(107), + TEGRA210_ADX_BYTE_MAP_CTRL(108), + TEGRA210_ADX_BYTE_MAP_CTRL(109), + TEGRA210_ADX_BYTE_MAP_CTRL(110), + TEGRA210_ADX_BYTE_MAP_CTRL(111), + TEGRA210_ADX_BYTE_MAP_CTRL(112), + TEGRA210_ADX_BYTE_MAP_CTRL(113), + TEGRA210_ADX_BYTE_MAP_CTRL(114), + TEGRA210_ADX_BYTE_MAP_CTRL(115), + TEGRA210_ADX_BYTE_MAP_CTRL(116), + TEGRA210_ADX_BYTE_MAP_CTRL(117), + TEGRA210_ADX_BYTE_MAP_CTRL(118), + TEGRA210_ADX_BYTE_MAP_CTRL(119), + TEGRA210_ADX_BYTE_MAP_CTRL(120), + TEGRA210_ADX_BYTE_MAP_CTRL(121), + TEGRA210_ADX_BYTE_MAP_CTRL(122), + TEGRA210_ADX_BYTE_MAP_CTRL(123), + TEGRA210_ADX_BYTE_MAP_CTRL(124), + TEGRA210_ADX_BYTE_MAP_CTRL(125), + TEGRA210_ADX_BYTE_MAP_CTRL(126), + TEGRA210_ADX_BYTE_MAP_CTRL(127), +}; + +static int tegra210_adx_component_probe(struct snd_soc_component *component) +{ + struct tegra210_adx *adx = snd_soc_component_get_drvdata(component); + int err = 0; + + if (adx->soc_data->num_controls) { + err = snd_soc_add_component_controls(component, adx->soc_data->controls, + adx->soc_data->num_controls); + if (err) + dev_err(component->dev, "can't add ADX controls, err: %d\n", err); + } + + return err; +} + static const struct snd_soc_component_driver tegra210_adx_cmpnt = { + .probe = tegra210_adx_component_probe, .dapm_widgets = tegra210_adx_widgets, .num_dapm_widgets = ARRAY_SIZE(tegra210_adx_widgets), .dapm_routes = tegra210_adx_routes, @@ -460,6 +563,58 @@ static bool tegra210_adx_volatile_reg(struct device *dev, return false; } +static bool tegra264_adx_wr_reg(struct device *dev, + unsigned int reg) +{ + switch (reg) { + case TEGRA210_ADX_TX_INT_MASK ... TEGRA210_ADX_TX4_CIF_CTRL: + case TEGRA210_ADX_RX_INT_MASK ... TEGRA210_ADX_RX_CIF_CTRL: + case TEGRA210_ADX_ENABLE ... TEGRA210_ADX_CG: + case TEGRA210_ADX_CTRL ... TEGRA264_ADX_CYA: + case TEGRA264_ADX_CFG_RAM_CTRL ... TEGRA264_ADX_CFG_RAM_DATA: + return true; + default: + return false; + } +} + +static bool tegra264_adx_rd_reg(struct device *dev, + unsigned int reg) +{ + switch (reg) { + case TEGRA210_ADX_RX_STATUS ... TEGRA210_ADX_RX_CIF_CTRL: + case TEGRA210_ADX_TX_STATUS ... TEGRA210_ADX_TX4_CIF_CTRL: + case TEGRA210_ADX_ENABLE ... TEGRA210_ADX_INT_STATUS: + case TEGRA210_ADX_CTRL ... TEGRA264_ADX_CFG_RAM_DATA: + return true; + default: + return false; + } +} + +static bool tegra264_adx_volatile_reg(struct device *dev, + unsigned int reg) +{ + switch (reg) { + case TEGRA210_ADX_RX_STATUS: + case TEGRA210_ADX_RX_INT_STATUS: + case TEGRA210_ADX_RX_INT_SET: + case TEGRA210_ADX_TX_STATUS: + case TEGRA210_ADX_TX_INT_STATUS: + case TEGRA210_ADX_TX_INT_SET: + case TEGRA210_ADX_SOFT_RESET: + case TEGRA210_ADX_STATUS: + case TEGRA210_ADX_INT_STATUS: + case TEGRA264_ADX_CFG_RAM_CTRL: + case TEGRA264_ADX_CFG_RAM_DATA: + return true; + default: + break; + } + + return false; +} + static const struct regmap_config tegra210_adx_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -473,8 +628,40 @@ static const struct regmap_config tegra210_adx_regmap_config = { .cache_type = REGCACHE_FLAT, }; +static const struct regmap_config tegra264_adx_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = TEGRA264_ADX_CFG_RAM_DATA, + .writeable_reg = tegra264_adx_wr_reg, + .readable_reg = tegra264_adx_rd_reg, + .volatile_reg = tegra264_adx_volatile_reg, + .reg_defaults = tegra264_adx_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tegra264_adx_reg_defaults), + .cache_type = REGCACHE_FLAT, +}; + +static const struct tegra210_adx_soc_data soc_data_tegra210 = { + .regmap_conf = &tegra210_adx_regmap_config, + .max_ch = TEGRA210_ADX_MAX_CHANNEL, + .ram_depth = TEGRA210_ADX_RAM_DEPTH, + .byte_mask_size = TEGRA210_ADX_BYTE_MASK_COUNT, + .cya_offset = TEGRA210_ADX_CYA_OFFSET, +}; + +static const struct tegra210_adx_soc_data soc_data_tegra264 = { + .regmap_conf = &tegra264_adx_regmap_config, + .max_ch = TEGRA264_ADX_MAX_CHANNEL, + .ram_depth = TEGRA264_ADX_RAM_DEPTH, + .byte_mask_size = TEGRA264_ADX_BYTE_MASK_COUNT, + .cya_offset = TEGRA264_ADX_CYA_OFFSET, + .controls = tegra264_adx_controls, + .num_controls = ARRAY_SIZE(tegra264_adx_controls), +}; + static const struct of_device_id tegra210_adx_of_match[] = { - { .compatible = "nvidia,tegra210-adx" }, + { .compatible = "nvidia,tegra210-adx", .data = &soc_data_tegra210 }, + { .compatible = "nvidia,tegra264-adx", .data = &soc_data_tegra264 }, {}, }; MODULE_DEVICE_TABLE(of, tegra210_adx_of_match); @@ -483,6 +670,8 @@ static int tegra210_adx_platform_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct tegra210_adx *adx; + const struct of_device_id *match; + struct tegra210_adx_soc_data *soc_data; void __iomem *regs; int err; @@ -490,6 +679,10 @@ static int tegra210_adx_platform_probe(struct platform_device *pdev) if (!adx) return -ENOMEM; + match = of_match_device(tegra210_adx_of_match, dev); + soc_data = (struct tegra210_adx_soc_data *)match->data; + adx->soc_data = soc_data; + dev_set_drvdata(dev, adx); regs = devm_platform_ioremap_resource(pdev, 0); @@ -497,7 +690,7 @@ static int tegra210_adx_platform_probe(struct platform_device *pdev) return PTR_ERR(regs); adx->regmap = devm_regmap_init_mmio(dev, regs, - &tegra210_adx_regmap_config); + soc_data->regmap_conf); if (IS_ERR(adx->regmap)) { dev_err(dev, "regmap init failed\n"); return PTR_ERR(adx->regmap); @@ -505,6 +698,20 @@ static int tegra210_adx_platform_probe(struct platform_device *pdev) regcache_cache_only(adx->regmap, true); + adx->map = devm_kzalloc(dev, soc_data->ram_depth * sizeof(*adx->map), + GFP_KERNEL); + if (!adx->map) + return -ENOMEM; + + adx->byte_mask = devm_kzalloc(dev, + soc_data->byte_mask_size * sizeof(*adx->byte_mask), + GFP_KERNEL); + if (!adx->byte_mask) + return -ENOMEM; + + tegra210_adx_dais[TEGRA_ADX_IN_DAI_ID].playback.channels_max = + adx->soc_data->max_ch; + err = devm_snd_soc_register_component(dev, &tegra210_adx_cmpnt, tegra210_adx_dais, ARRAY_SIZE(tegra210_adx_dais)); diff --git a/sound/soc/tegra/tegra210_adx.h b/sound/soc/tegra/tegra210_adx.h index d7dcb6497978..176a4e40de0a 100644 --- a/sound/soc/tegra/tegra210_adx.h +++ b/sound/soc/tegra/tegra210_adx.h @@ -1,8 +1,7 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * tegra210_adx.h - Definitions for Tegra210 ADX driver +/* SPDX-License-Identifier: GPL-2.0-only + * SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION. All rights reserved. * - * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. + * tegra210_adx.h - Definitions for Tegra210 ADX driver * */ @@ -36,6 +35,10 @@ #define TEGRA210_ADX_CFG_RAM_CTRL 0xb8 #define TEGRA210_ADX_CFG_RAM_DATA 0xbc +#define TEGRA264_ADX_CYA 0xb8 +#define TEGRA264_ADX_CFG_RAM_CTRL 0xc0 +#define TEGRA264_ADX_CFG_RAM_DATA 0xc4 + /* Fields in TEGRA210_ADX_ENABLE */ #define TEGRA210_ADX_ENABLE_SHIFT 0 @@ -62,11 +65,32 @@ #define TEGRA210_ADX_MAP_STREAM_NUMBER_SHIFT 6 #define TEGRA210_ADX_MAP_WORD_NUMBER_SHIFT 2 #define TEGRA210_ADX_MAP_BYTE_NUMBER_SHIFT 0 +#define TEGRA210_ADX_BYTE_MASK_COUNT 2 +#define TEGRA210_ADX_MAX_CHANNEL 16 +#define TEGRA210_ADX_CYA_OFFSET 0 + +#define TEGRA264_ADX_RAM_DEPTH 32 +#define TEGRA264_ADX_BYTE_MASK_COUNT 4 +#define TEGRA264_ADX_MAX_CHANNEL 32 +#define TEGRA264_ADX_CYA_OFFSET 8 + +#define TEGRA_ADX_IN_DAI_ID 4 + +struct tegra210_adx_soc_data { + const struct regmap_config *regmap_conf; + 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 cya_offset; +}; struct tegra210_adx { struct regmap *regmap; - unsigned int map[TEGRA210_ADX_RAM_DEPTH]; - unsigned int byte_mask[2]; + unsigned int *map; + unsigned int *byte_mask; + const struct tegra210_adx_soc_data *soc_data; }; #endif -- cgit v1.2.3 From 4152d33ab162d5378f57cd757e1de5cb4867dfb4 Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:46 +0000 Subject: ASoC: tegra: AHUB: Add Tegra264 support Add Tegra264 AHUB support with following changes: - Update Tegra264 IP instances: DMIC(2), DSPK(1), AMX(6), ADX(6), I2S(8). - Update register offsets for Tegra264. - Add soc_data for Tegra264 chip-specific variations. - Increase channels_max to 32 for Tegra264 DAIs. Signed-off-by: Sheetal Link: https://patch.msgid.link/20250512051747.1026770-11-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra210_ahub.c | 848 +++++++++++++++++++++++++++++++++++++++- sound/soc/tegra/tegra210_ahub.h | 52 ++- 2 files changed, 891 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c index ae4965a9f764..2376cc76e684 100644 --- a/sound/soc/tegra/tegra210_ahub.c +++ b/sound/soc/tegra/tegra210_ahub.c @@ -2,7 +2,7 @@ // // tegra210_ahub.c - Tegra210 AHUB driver // -// Copyright (c) 2020-2024, NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2020-2025, NVIDIA CORPORATION. All rights reserved. #include #include @@ -29,7 +29,7 @@ static int tegra_ahub_get_value_enum(struct snd_kcontrol *kctl, for (i = 0; i < ahub->soc_data->reg_count; i++) { unsigned int reg_val; - reg = e->reg + (TEGRA210_XBAR_PART1_RX * i); + reg = e->reg + (ahub->soc_data->xbar_part_size * i); reg_val = snd_soc_component_read(cmpnt, reg); reg_val &= ahub->soc_data->mask[i]; @@ -80,7 +80,7 @@ static int tegra_ahub_put_value_enum(struct snd_kcontrol *kctl, * different part of the MUX register. */ for (i = 0; i < ahub->soc_data->reg_count; i++) { - update[i].reg = e->reg + (TEGRA210_XBAR_PART1_RX * i); + update[i].reg = e->reg + (ahub->soc_data->xbar_part_size * i); update[i].val = (i == reg_idx) ? reg_val : 0; update[i].mask = ahub->soc_data->mask[i]; update[i].kcontrol = kctl; @@ -304,6 +304,164 @@ static struct snd_soc_dai_driver tegra186_ahub_dais[] = { DAI(OPE1 TX), }; +static struct snd_soc_dai_driver tegra264_ahub_dais[] = { + DAI(ADMAIF1), + DAI(ADMAIF2), + DAI(ADMAIF3), + DAI(ADMAIF4), + DAI(ADMAIF5), + DAI(ADMAIF6), + DAI(ADMAIF7), + DAI(ADMAIF8), + DAI(ADMAIF9), + DAI(ADMAIF10), + DAI(ADMAIF11), + DAI(ADMAIF12), + DAI(ADMAIF13), + DAI(ADMAIF14), + DAI(ADMAIF15), + DAI(ADMAIF16), + DAI(ADMAIF17), + DAI(ADMAIF18), + DAI(ADMAIF19), + DAI(ADMAIF20), + DAI(ADMAIF21), + DAI(ADMAIF22), + DAI(ADMAIF23), + DAI(ADMAIF24), + DAI(ADMAIF25), + DAI(ADMAIF26), + DAI(ADMAIF27), + DAI(ADMAIF28), + DAI(ADMAIF29), + DAI(ADMAIF30), + DAI(ADMAIF31), + DAI(ADMAIF32), + /* XBAR <-> I2S <-> Codec */ + DAI(I2S1), + DAI(I2S2), + DAI(I2S3), + DAI(I2S4), + DAI(I2S5), + DAI(I2S6), + DAI(I2S7), + DAI(I2S8), + /* XBAR <-> DMIC <-> Codec */ + DAI(DMIC1), + DAI(DMIC2), + /* XBAR <-> DSPK <-> Codec */ + DAI(DSPK1), + /* XBAR -> SFC -> XBAR */ + DAI(SFC1 RX), + DAI(SFC1 TX), + DAI(SFC2 RX), + DAI(SFC2 TX), + DAI(SFC3 RX), + DAI(SFC3 TX), + DAI(SFC4 RX), + DAI(SFC4 TX), + /* XBAR -> MVC -> XBAR */ + DAI(MVC1 RX), + DAI(MVC1 TX), + DAI(MVC2 RX), + DAI(MVC2 TX), + /* XBAR -> AMX(4:1) -> XBAR */ + DAI(AMX1 RX1), + DAI(AMX1 RX2), + DAI(AMX1 RX3), + DAI(AMX1 RX4), + DAI(AMX1), + DAI(AMX2 RX1), + DAI(AMX2 RX2), + DAI(AMX2 RX3), + DAI(AMX2 RX4), + DAI(AMX2), + DAI(AMX3 RX1), + DAI(AMX3 RX2), + DAI(AMX3 RX3), + DAI(AMX3 RX4), + DAI(AMX3), + DAI(AMX4 RX1), + DAI(AMX4 RX2), + DAI(AMX4 RX3), + DAI(AMX4 RX4), + DAI(AMX4), + DAI(AMX5 RX1), + DAI(AMX5 RX2), + DAI(AMX5 RX3), + DAI(AMX5 RX4), + DAI(AMX5), + DAI(AMX6 RX1), + DAI(AMX6 RX2), + DAI(AMX6 RX3), + DAI(AMX6 RX4), + DAI(AMX6), + /* XBAR -> ADX(1:4) -> XBAR */ + DAI(ADX1), + DAI(ADX1 TX1), + DAI(ADX1 TX2), + DAI(ADX1 TX3), + DAI(ADX1 TX4), + DAI(ADX2), + DAI(ADX2 TX1), + DAI(ADX2 TX2), + DAI(ADX2 TX3), + DAI(ADX2 TX4), + DAI(ADX3), + DAI(ADX3 TX1), + DAI(ADX3 TX2), + DAI(ADX3 TX3), + DAI(ADX3 TX4), + DAI(ADX4), + DAI(ADX4 TX1), + DAI(ADX4 TX2), + DAI(ADX4 TX3), + DAI(ADX4 TX4), + DAI(ADX5), + DAI(ADX5 TX1), + DAI(ADX5 TX2), + DAI(ADX5 TX3), + DAI(ADX5 TX4), + DAI(ADX6), + DAI(ADX6 TX1), + DAI(ADX6 TX2), + DAI(ADX6 TX3), + DAI(ADX6 TX4), + /* XBAR -> MIXER1(10:5) -> XBAR */ + DAI(MIXER1 RX1), + DAI(MIXER1 RX2), + DAI(MIXER1 RX3), + DAI(MIXER1 RX4), + DAI(MIXER1 RX5), + DAI(MIXER1 RX6), + DAI(MIXER1 RX7), + DAI(MIXER1 RX8), + DAI(MIXER1 RX9), + DAI(MIXER1 RX10), + DAI(MIXER1 TX1), + DAI(MIXER1 TX2), + DAI(MIXER1 TX3), + DAI(MIXER1 TX4), + DAI(MIXER1 TX5), + /* XBAR -> ASRC -> XBAR */ + DAI(ASRC1 RX1), + DAI(ASRC1 TX1), + DAI(ASRC1 RX2), + DAI(ASRC1 TX2), + DAI(ASRC1 RX3), + DAI(ASRC1 TX3), + DAI(ASRC1 RX4), + DAI(ASRC1 TX4), + DAI(ASRC1 RX5), + DAI(ASRC1 TX5), + DAI(ASRC1 RX6), + DAI(ASRC1 TX6), + DAI(ASRC1 RX7), + /* XBAR -> OPE -> XBAR */ + DAI(OPE1 RX), + DAI(OPE1 TX), +}; + static const char * const tegra210_ahub_mux_texts[] = { "None", "ADMAIF1", @@ -421,6 +579,100 @@ static const char * const tegra186_ahub_mux_texts[] = { "OPE1", }; +static const char * const tegra264_ahub_mux_texts[] = { + "None", + "ADMAIF1", + "ADMAIF2", + "ADMAIF3", + "ADMAIF4", + "ADMAIF5", + "ADMAIF6", + "ADMAIF7", + "ADMAIF8", + "ADMAIF9", + "ADMAIF10", + "ADMAIF11", + "ADMAIF12", + "ADMAIF13", + "ADMAIF14", + "ADMAIF15", + "ADMAIF16", + "I2S1", + "I2S2", + "I2S3", + "I2S4", + "I2S5", + "I2S6", + "I2S7", + "I2S8", + "SFC1", + "SFC2", + "SFC3", + "SFC4", + "MIXER1 TX1", + "MIXER1 TX2", + "MIXER1 TX3", + "MIXER1 TX4", + "MIXER1 TX5", + "AMX1", + "AMX2", + "AMX3", + "AMX4", + "AMX5", + "AMX6", + "OPE1", + "MVC1", + "MVC2", + "DMIC1", + "DMIC2", + "ADX1 TX1", + "ADX1 TX2", + "ADX1 TX3", + "ADX1 TX4", + "ADX2 TX1", + "ADX2 TX2", + "ADX2 TX3", + "ADX2 TX4", + "ADX3 TX1", + "ADX3 TX2", + "ADX3 TX3", + "ADX3 TX4", + "ADX4 TX1", + "ADX4 TX2", + "ADX4 TX3", + "ADX4 TX4", + "ADX5 TX1", + "ADX5 TX2", + "ADX5 TX3", + "ADX5 TX4", + "ADX6 TX1", + "ADX6 TX2", + "ADX6 TX3", + "ADX6 TX4", + "ASRC1 TX1", + "ASRC1 TX2", + "ASRC1 TX3", + "ASRC1 TX4", + "ASRC1 TX5", + "ASRC1 TX6", + "ADMAIF17", + "ADMAIF18", + "ADMAIF19", + "ADMAIF20", + "ADMAIF21", + "ADMAIF22", + "ADMAIF23", + "ADMAIF24", + "ADMAIF25", + "ADMAIF26", + "ADMAIF27", + "ADMAIF28", + "ADMAIF29", + "ADMAIF30", + "ADMAIF31", + "ADMAIF32", +}; + static const unsigned int tegra210_ahub_mux_values[] = { 0, /* ADMAIF */ @@ -558,6 +810,111 @@ static const unsigned int tegra186_ahub_mux_values[] = { MUX_VALUE(2, 0), }; +static const unsigned int tegra264_ahub_mux_values[] = { + 0, + /* ADMAIF */ + MUX_VALUE(0, 0), + MUX_VALUE(0, 1), + MUX_VALUE(0, 2), + MUX_VALUE(0, 3), + MUX_VALUE(0, 4), + MUX_VALUE(0, 5), + MUX_VALUE(0, 6), + MUX_VALUE(0, 7), + MUX_VALUE(0, 8), + MUX_VALUE(0, 9), + MUX_VALUE(0, 10), + MUX_VALUE(0, 11), + MUX_VALUE(0, 12), + MUX_VALUE(0, 13), + MUX_VALUE(0, 14), + MUX_VALUE(0, 15), + /* I2S */ + MUX_VALUE(0, 16), + MUX_VALUE(0, 17), + MUX_VALUE(0, 18), + MUX_VALUE(0, 19), + MUX_VALUE(0, 20), + MUX_VALUE(0, 21), + MUX_VALUE(0, 22), + MUX_VALUE(0, 23), + /* SFC */ + MUX_VALUE(0, 24), + MUX_VALUE(0, 25), + MUX_VALUE(0, 26), + MUX_VALUE(0, 27), + /* MIXER */ + MUX_VALUE(1, 0), + MUX_VALUE(1, 1), + MUX_VALUE(1, 2), + MUX_VALUE(1, 3), + MUX_VALUE(1, 4), + /* AMX */ + MUX_VALUE(1, 8), + MUX_VALUE(1, 9), + MUX_VALUE(1, 10), + MUX_VALUE(1, 11), + MUX_VALUE(1, 12), + MUX_VALUE(1, 13), + /* OPE */ + MUX_VALUE(2, 0), + /* MVC */ + MUX_VALUE(2, 8), + MUX_VALUE(2, 9), + /* DMIC */ + MUX_VALUE(2, 18), + MUX_VALUE(2, 19), + /* ADX */ + MUX_VALUE(2, 24), + MUX_VALUE(2, 25), + MUX_VALUE(2, 26), + MUX_VALUE(2, 27), + MUX_VALUE(2, 28), + MUX_VALUE(2, 29), + MUX_VALUE(2, 30), + MUX_VALUE(2, 31), + MUX_VALUE(3, 0), + MUX_VALUE(3, 1), + MUX_VALUE(3, 2), + MUX_VALUE(3, 3), + MUX_VALUE(3, 4), + MUX_VALUE(3, 5), + MUX_VALUE(3, 6), + MUX_VALUE(3, 7), + MUX_VALUE(3, 8), + MUX_VALUE(3, 9), + MUX_VALUE(3, 10), + MUX_VALUE(3, 11), + MUX_VALUE(3, 12), + MUX_VALUE(3, 13), + MUX_VALUE(3, 14), + MUX_VALUE(3, 15), + /* ASRC */ + MUX_VALUE(3, 24), + MUX_VALUE(3, 25), + MUX_VALUE(3, 26), + MUX_VALUE(3, 27), + MUX_VALUE(3, 28), + MUX_VALUE(3, 29), + /* ADMAIF */ + MUX_VALUE(4, 7), + MUX_VALUE(4, 8), + MUX_VALUE(4, 9), + MUX_VALUE(4, 10), + MUX_VALUE(4, 11), + MUX_VALUE(4, 12), + MUX_VALUE(4, 13), + MUX_VALUE(4, 14), + MUX_VALUE(4, 15), + MUX_VALUE(4, 16), + MUX_VALUE(4, 17), + MUX_VALUE(4, 18), + MUX_VALUE(4, 19), + MUX_VALUE(4, 20), + MUX_VALUE(4, 21), + MUX_VALUE(4, 22), +}; + /* Controls for t210 */ MUX_ENUM_CTRL_DECL(t210_admaif1_tx, 0x00); MUX_ENUM_CTRL_DECL(t210_admaif2_tx, 0x01); @@ -712,6 +1069,103 @@ MUX_ENUM_CTRL_DECL_234(t234_asrc15_tx, 0x68); MUX_ENUM_CTRL_DECL_234(t234_asrc16_tx, 0x69); MUX_ENUM_CTRL_DECL_234(t234_asrc17_tx, 0x6a); +/* Controls for t264 */ +MUX_ENUM_CTRL_DECL_264(t264_admaif1_tx, 0x00); +MUX_ENUM_CTRL_DECL_264(t264_admaif2_tx, 0x01); +MUX_ENUM_CTRL_DECL_264(t264_admaif3_tx, 0x02); +MUX_ENUM_CTRL_DECL_264(t264_admaif4_tx, 0x03); +MUX_ENUM_CTRL_DECL_264(t264_admaif5_tx, 0x04); +MUX_ENUM_CTRL_DECL_264(t264_admaif6_tx, 0x05); +MUX_ENUM_CTRL_DECL_264(t264_admaif7_tx, 0x06); +MUX_ENUM_CTRL_DECL_264(t264_admaif8_tx, 0x07); +MUX_ENUM_CTRL_DECL_264(t264_admaif9_tx, 0x08); +MUX_ENUM_CTRL_DECL_264(t264_admaif10_tx, 0x09); +MUX_ENUM_CTRL_DECL_264(t264_admaif11_tx, 0x0a); +MUX_ENUM_CTRL_DECL_264(t264_admaif12_tx, 0x0b); +MUX_ENUM_CTRL_DECL_264(t264_admaif13_tx, 0x0c); +MUX_ENUM_CTRL_DECL_264(t264_admaif14_tx, 0x0d); +MUX_ENUM_CTRL_DECL_264(t264_admaif15_tx, 0x0e); +MUX_ENUM_CTRL_DECL_264(t264_admaif16_tx, 0x0f); +MUX_ENUM_CTRL_DECL_264(t264_i2s1_tx, 0x10); +MUX_ENUM_CTRL_DECL_264(t264_i2s2_tx, 0x11); +MUX_ENUM_CTRL_DECL_264(t264_i2s3_tx, 0x12); +MUX_ENUM_CTRL_DECL_264(t264_i2s4_tx, 0x13); +MUX_ENUM_CTRL_DECL_264(t264_i2s5_tx, 0x14); +MUX_ENUM_CTRL_DECL_264(t264_i2s6_tx, 0x15); +MUX_ENUM_CTRL_DECL_264(t264_i2s7_tx, 0x16); +MUX_ENUM_CTRL_DECL_264(t264_i2s8_tx, 0x17); +MUX_ENUM_CTRL_DECL_264(t264_sfc1_tx, 0x18); +MUX_ENUM_CTRL_DECL_264(t264_sfc2_tx, 0x19); +MUX_ENUM_CTRL_DECL_264(t264_sfc3_tx, 0x1a); +MUX_ENUM_CTRL_DECL_264(t264_sfc4_tx, 0x1b); +MUX_ENUM_CTRL_DECL_264(t264_mixer11_tx, 0x20); +MUX_ENUM_CTRL_DECL_264(t264_mixer12_tx, 0x21); +MUX_ENUM_CTRL_DECL_264(t264_mixer13_tx, 0x22); +MUX_ENUM_CTRL_DECL_264(t264_mixer14_tx, 0x23); +MUX_ENUM_CTRL_DECL_264(t264_mixer15_tx, 0x24); +MUX_ENUM_CTRL_DECL_264(t264_mixer16_tx, 0x25); +MUX_ENUM_CTRL_DECL_264(t264_mixer17_tx, 0x26); +MUX_ENUM_CTRL_DECL_264(t264_mixer18_tx, 0x27); +MUX_ENUM_CTRL_DECL_264(t264_mixer19_tx, 0x28); +MUX_ENUM_CTRL_DECL_264(t264_mixer110_tx, 0x29); +MUX_ENUM_CTRL_DECL_264(t264_dspk1_tx, 0x30); +MUX_ENUM_CTRL_DECL_264(t264_ope1_tx, 0x40); +MUX_ENUM_CTRL_DECL_264(t264_mvc1_tx, 0x44); +MUX_ENUM_CTRL_DECL_264(t264_mvc2_tx, 0x45); +MUX_ENUM_CTRL_DECL_264(t264_amx11_tx, 0x48); +MUX_ENUM_CTRL_DECL_264(t264_amx12_tx, 0x49); +MUX_ENUM_CTRL_DECL_264(t264_amx13_tx, 0x4a); +MUX_ENUM_CTRL_DECL_264(t264_amx14_tx, 0x4b); +MUX_ENUM_CTRL_DECL_264(t264_amx21_tx, 0x4c); +MUX_ENUM_CTRL_DECL_264(t264_amx22_tx, 0x4d); +MUX_ENUM_CTRL_DECL_264(t264_amx23_tx, 0x4e); +MUX_ENUM_CTRL_DECL_264(t264_amx24_tx, 0x4f); +MUX_ENUM_CTRL_DECL_264(t264_amx31_tx, 0x50); +MUX_ENUM_CTRL_DECL_264(t264_amx32_tx, 0x51); +MUX_ENUM_CTRL_DECL_264(t264_amx33_tx, 0x52); +MUX_ENUM_CTRL_DECL_264(t264_amx34_tx, 0x53); +MUX_ENUM_CTRL_DECL_264(t264_adx1_tx, 0x58); +MUX_ENUM_CTRL_DECL_264(t264_adx2_tx, 0x59); +MUX_ENUM_CTRL_DECL_264(t264_adx3_tx, 0x5a); +MUX_ENUM_CTRL_DECL_264(t264_adx4_tx, 0x5b); +MUX_ENUM_CTRL_DECL_264(t264_amx41_tx, 0x5c); +MUX_ENUM_CTRL_DECL_264(t264_amx42_tx, 0x5d); +MUX_ENUM_CTRL_DECL_264(t264_amx43_tx, 0x5e); +MUX_ENUM_CTRL_DECL_264(t264_amx44_tx, 0x5f); +MUX_ENUM_CTRL_DECL_264(t264_admaif17_tx, 0x60); +MUX_ENUM_CTRL_DECL_264(t264_admaif18_tx, 0x61); +MUX_ENUM_CTRL_DECL_264(t264_admaif19_tx, 0x62); +MUX_ENUM_CTRL_DECL_264(t264_admaif20_tx, 0x63); +MUX_ENUM_CTRL_DECL_264(t264_asrc11_tx, 0x64); +MUX_ENUM_CTRL_DECL_264(t264_asrc12_tx, 0x65); +MUX_ENUM_CTRL_DECL_264(t264_asrc13_tx, 0x66); +MUX_ENUM_CTRL_DECL_264(t264_asrc14_tx, 0x67); +MUX_ENUM_CTRL_DECL_264(t264_asrc15_tx, 0x68); +MUX_ENUM_CTRL_DECL_264(t264_asrc16_tx, 0x69); +MUX_ENUM_CTRL_DECL_264(t264_asrc17_tx, 0x6a); +MUX_ENUM_CTRL_DECL_264(t264_admaif21_tx, 0x74); +MUX_ENUM_CTRL_DECL_264(t264_admaif22_tx, 0x75); +MUX_ENUM_CTRL_DECL_264(t264_admaif23_tx, 0x76); +MUX_ENUM_CTRL_DECL_264(t264_admaif24_tx, 0x77); +MUX_ENUM_CTRL_DECL_264(t264_admaif25_tx, 0x78); +MUX_ENUM_CTRL_DECL_264(t264_admaif26_tx, 0x79); +MUX_ENUM_CTRL_DECL_264(t264_admaif27_tx, 0x7a); +MUX_ENUM_CTRL_DECL_264(t264_admaif28_tx, 0x7b); +MUX_ENUM_CTRL_DECL_264(t264_admaif29_tx, 0x7c); +MUX_ENUM_CTRL_DECL_264(t264_admaif30_tx, 0x7d); +MUX_ENUM_CTRL_DECL_264(t264_admaif31_tx, 0x7e); +MUX_ENUM_CTRL_DECL_264(t264_admaif32_tx, 0x7f); +MUX_ENUM_CTRL_DECL_264(t264_amx51_tx, 0x80); +MUX_ENUM_CTRL_DECL_264(t264_amx52_tx, 0x81); +MUX_ENUM_CTRL_DECL_264(t264_amx53_tx, 0x82); +MUX_ENUM_CTRL_DECL_264(t264_amx54_tx, 0x83); +MUX_ENUM_CTRL_DECL_264(t264_amx61_tx, 0x84); +MUX_ENUM_CTRL_DECL_264(t264_amx62_tx, 0x85); +MUX_ENUM_CTRL_DECL_264(t264_amx63_tx, 0x86); +MUX_ENUM_CTRL_DECL_264(t264_amx64_tx, 0x87); +MUX_ENUM_CTRL_DECL_264(t264_adx5_tx, 0x88); +MUX_ENUM_CTRL_DECL_264(t264_adx6_tx, 0x89); + static const struct snd_soc_dapm_widget tegra210_ahub_widgets[] = { WIDGETS("ADMAIF1", t210_admaif1_tx), WIDGETS("ADMAIF2", t210_admaif2_tx), @@ -996,6 +1450,147 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { WIDGETS("OPE1", t186_ope1_tx), }; +static const struct snd_soc_dapm_widget tegra264_ahub_widgets[] = { + WIDGETS("ADMAIF1", t264_admaif1_tx), + WIDGETS("ADMAIF2", t264_admaif2_tx), + WIDGETS("ADMAIF3", t264_admaif3_tx), + WIDGETS("ADMAIF4", t264_admaif4_tx), + WIDGETS("ADMAIF5", t264_admaif5_tx), + WIDGETS("ADMAIF6", t264_admaif6_tx), + WIDGETS("ADMAIF7", t264_admaif7_tx), + WIDGETS("ADMAIF8", t264_admaif8_tx), + WIDGETS("ADMAIF9", t264_admaif9_tx), + WIDGETS("ADMAIF10", t264_admaif10_tx), + WIDGETS("ADMAIF11", t264_admaif11_tx), + WIDGETS("ADMAIF12", t264_admaif12_tx), + WIDGETS("ADMAIF13", t264_admaif13_tx), + WIDGETS("ADMAIF14", t264_admaif14_tx), + WIDGETS("ADMAIF15", t264_admaif15_tx), + WIDGETS("ADMAIF16", t264_admaif16_tx), + WIDGETS("ADMAIF17", t264_admaif17_tx), + WIDGETS("ADMAIF18", t264_admaif18_tx), + WIDGETS("ADMAIF19", t264_admaif19_tx), + WIDGETS("ADMAIF20", t264_admaif20_tx), + WIDGETS("ADMAIF21", t264_admaif21_tx), + WIDGETS("ADMAIF22", t264_admaif22_tx), + WIDGETS("ADMAIF23", t264_admaif23_tx), + WIDGETS("ADMAIF24", t264_admaif24_tx), + WIDGETS("ADMAIF25", t264_admaif25_tx), + WIDGETS("ADMAIF26", t264_admaif26_tx), + WIDGETS("ADMAIF27", t264_admaif27_tx), + WIDGETS("ADMAIF28", t264_admaif28_tx), + WIDGETS("ADMAIF29", t264_admaif29_tx), + WIDGETS("ADMAIF30", t264_admaif30_tx), + WIDGETS("ADMAIF31", t264_admaif31_tx), + WIDGETS("ADMAIF32", t264_admaif32_tx), + WIDGETS("I2S1", t264_i2s1_tx), + WIDGETS("I2S2", t264_i2s2_tx), + WIDGETS("I2S3", t264_i2s3_tx), + WIDGETS("I2S4", t264_i2s4_tx), + WIDGETS("I2S5", t264_i2s5_tx), + WIDGETS("I2S6", t264_i2s6_tx), + WIDGETS("I2S7", t264_i2s7_tx), + WIDGETS("I2S8", t264_i2s8_tx), + TX_WIDGETS("DMIC1"), + TX_WIDGETS("DMIC2"), + WIDGETS("DSPK1", t264_dspk1_tx), + WIDGETS("SFC1", t264_sfc1_tx), + WIDGETS("SFC2", t264_sfc2_tx), + WIDGETS("SFC3", t264_sfc3_tx), + WIDGETS("SFC4", t264_sfc4_tx), + WIDGETS("MVC1", t264_mvc1_tx), + WIDGETS("MVC2", t264_mvc2_tx), + WIDGETS("AMX1 RX1", t264_amx11_tx), + WIDGETS("AMX1 RX2", t264_amx12_tx), + WIDGETS("AMX1 RX3", t264_amx13_tx), + WIDGETS("AMX1 RX4", t264_amx14_tx), + WIDGETS("AMX2 RX1", t264_amx21_tx), + WIDGETS("AMX2 RX2", t264_amx22_tx), + WIDGETS("AMX2 RX3", t264_amx23_tx), + WIDGETS("AMX2 RX4", t264_amx24_tx), + WIDGETS("AMX3 RX1", t264_amx31_tx), + WIDGETS("AMX3 RX2", t264_amx32_tx), + WIDGETS("AMX3 RX3", t264_amx33_tx), + WIDGETS("AMX3 RX4", t264_amx34_tx), + WIDGETS("AMX4 RX1", t264_amx41_tx), + WIDGETS("AMX4 RX2", t264_amx42_tx), + WIDGETS("AMX4 RX3", t264_amx43_tx), + WIDGETS("AMX4 RX4", t264_amx44_tx), + WIDGETS("AMX5 RX1", t264_amx51_tx), + WIDGETS("AMX5 RX2", t264_amx52_tx), + WIDGETS("AMX5 RX3", t264_amx53_tx), + WIDGETS("AMX5 RX4", t264_amx54_tx), + WIDGETS("AMX6 RX1", t264_amx61_tx), + WIDGETS("AMX6 RX2", t264_amx62_tx), + WIDGETS("AMX6 RX3", t264_amx63_tx), + WIDGETS("AMX6 RX4", t264_amx64_tx), + TX_WIDGETS("AMX1"), + TX_WIDGETS("AMX2"), + TX_WIDGETS("AMX3"), + TX_WIDGETS("AMX4"), + TX_WIDGETS("AMX5"), + TX_WIDGETS("AMX6"), + WIDGETS("ADX1", t264_adx1_tx), + WIDGETS("ADX2", t264_adx2_tx), + WIDGETS("ADX3", t264_adx3_tx), + WIDGETS("ADX4", t264_adx4_tx), + WIDGETS("ADX5", t264_adx5_tx), + WIDGETS("ADX6", t264_adx6_tx), + TX_WIDGETS("ADX1 TX1"), + TX_WIDGETS("ADX1 TX2"), + TX_WIDGETS("ADX1 TX3"), + TX_WIDGETS("ADX1 TX4"), + TX_WIDGETS("ADX2 TX1"), + TX_WIDGETS("ADX2 TX2"), + TX_WIDGETS("ADX2 TX3"), + TX_WIDGETS("ADX2 TX4"), + TX_WIDGETS("ADX3 TX1"), + TX_WIDGETS("ADX3 TX2"), + TX_WIDGETS("ADX3 TX3"), + TX_WIDGETS("ADX3 TX4"), + TX_WIDGETS("ADX4 TX1"), + TX_WIDGETS("ADX4 TX2"), + TX_WIDGETS("ADX4 TX3"), + TX_WIDGETS("ADX4 TX4"), + TX_WIDGETS("ADX5 TX1"), + TX_WIDGETS("ADX5 TX2"), + TX_WIDGETS("ADX5 TX3"), + TX_WIDGETS("ADX5 TX4"), + TX_WIDGETS("ADX6 TX1"), + TX_WIDGETS("ADX6 TX2"), + TX_WIDGETS("ADX6 TX3"), + TX_WIDGETS("ADX6 TX4"), + WIDGETS("MIXER1 RX1", t264_mixer11_tx), + WIDGETS("MIXER1 RX2", t264_mixer12_tx), + WIDGETS("MIXER1 RX3", t264_mixer13_tx), + WIDGETS("MIXER1 RX4", t264_mixer14_tx), + WIDGETS("MIXER1 RX5", t264_mixer15_tx), + WIDGETS("MIXER1 RX6", t264_mixer16_tx), + WIDGETS("MIXER1 RX7", t264_mixer17_tx), + WIDGETS("MIXER1 RX8", t264_mixer18_tx), + WIDGETS("MIXER1 RX9", t264_mixer19_tx), + WIDGETS("MIXER1 RX10", t264_mixer110_tx), + TX_WIDGETS("MIXER1 TX1"), + TX_WIDGETS("MIXER1 TX2"), + TX_WIDGETS("MIXER1 TX3"), + TX_WIDGETS("MIXER1 TX4"), + TX_WIDGETS("MIXER1 TX5"), + WIDGETS("ASRC1 RX1", t264_asrc11_tx), + WIDGETS("ASRC1 RX2", t264_asrc12_tx), + WIDGETS("ASRC1 RX3", t264_asrc13_tx), + WIDGETS("ASRC1 RX4", t264_asrc14_tx), + WIDGETS("ASRC1 RX5", t264_asrc15_tx), + WIDGETS("ASRC1 RX6", t264_asrc16_tx), + WIDGETS("ASRC1 RX7", t264_asrc17_tx), + TX_WIDGETS("ASRC1 TX1"), + TX_WIDGETS("ASRC1 TX2"), + TX_WIDGETS("ASRC1 TX3"), + TX_WIDGETS("ASRC1 TX4"), + TX_WIDGETS("ASRC1 TX5"), + TX_WIDGETS("ASRC1 TX6"), + WIDGETS("OPE1", t264_ope1_tx), +}; + #define TEGRA_COMMON_MUX_ROUTES(name) \ { name " XBAR-TX", NULL, name " Mux" }, \ { name " Mux", "ADMAIF1", "ADMAIF1 XBAR-RX" }, \ @@ -1015,7 +1610,6 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { { name " Mux", "I2S5", "I2S5 XBAR-RX" }, \ { name " Mux", "DMIC1", "DMIC1 XBAR-RX" }, \ { name " Mux", "DMIC2", "DMIC2 XBAR-RX" }, \ - { name " Mux", "DMIC3", "DMIC3 XBAR-RX" }, \ { name " Mux", "SFC1", "SFC1 XBAR-RX" }, \ { name " Mux", "SFC2", "SFC2 XBAR-RX" }, \ { name " Mux", "SFC3", "SFC3 XBAR-RX" }, \ @@ -1040,6 +1634,7 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { { name " Mux", "OPE1", "OPE1 XBAR-RX" }, #define TEGRA210_ONLY_MUX_ROUTES(name) \ + { name " Mux", "DMIC3", "DMIC3 XBAR-RX" }, \ { name " Mux", "OPE2", "OPE2 XBAR-RX" }, #define TEGRA186_ONLY_MUX_ROUTES(name) \ @@ -1054,6 +1649,7 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { { name " Mux", "ADMAIF19", "ADMAIF19 XBAR-RX" }, \ { name " Mux", "ADMAIF20", "ADMAIF20 XBAR-RX" }, \ { name " Mux", "I2S6", "I2S6 XBAR-RX" }, \ + { name " Mux", "DMIC3", "DMIC3 XBAR-RX" }, \ { name " Mux", "DMIC4", "DMIC4 XBAR-RX" }, \ { name " Mux", "AMX3", "AMX3 XBAR-RX" }, \ { name " Mux", "AMX4", "AMX4 XBAR-RX" }, \ @@ -1072,6 +1668,59 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { { name " Mux", "ASRC1 TX5", "ASRC1 TX5 XBAR-RX" }, \ { name " Mux", "ASRC1 TX6", "ASRC1 TX6 XBAR-RX" }, +#define TEGRA264_ONLY_MUX_ROUTES(name) \ + { name " Mux", "ADMAIF11", "ADMAIF11 XBAR-RX" }, \ + { name " Mux", "ADMAIF12", "ADMAIF12 XBAR-RX" }, \ + { name " Mux", "ADMAIF13", "ADMAIF13 XBAR-RX" }, \ + { name " Mux", "ADMAIF14", "ADMAIF14 XBAR-RX" }, \ + { name " Mux", "ADMAIF15", "ADMAIF15 XBAR-RX" }, \ + { name " Mux", "ADMAIF16", "ADMAIF16 XBAR-RX" }, \ + { name " Mux", "ADMAIF17", "ADMAIF17 XBAR-RX" }, \ + { name " Mux", "ADMAIF18", "ADMAIF18 XBAR-RX" }, \ + { name " Mux", "ADMAIF19", "ADMAIF19 XBAR-RX" }, \ + { name " Mux", "ADMAIF20", "ADMAIF20 XBAR-RX" }, \ + { name " Mux", "ADMAIF21", "ADMAIF21 XBAR-RX" }, \ + { name " Mux", "ADMAIF22", "ADMAIF22 XBAR-RX" }, \ + { name " Mux", "ADMAIF23", "ADMAIF23 XBAR-RX" }, \ + { name " Mux", "ADMAIF24", "ADMAIF24 XBAR-RX" }, \ + { name " Mux", "ADMAIF25", "ADMAIF25 XBAR-RX" }, \ + { name " Mux", "ADMAIF26", "ADMAIF26 XBAR-RX" }, \ + { name " Mux", "ADMAIF27", "ADMAIF27 XBAR-RX" }, \ + { name " Mux", "ADMAIF28", "ADMAIF28 XBAR-RX" }, \ + { name " Mux", "ADMAIF29", "ADMAIF29 XBAR-RX" }, \ + { name " Mux", "ADMAIF30", "ADMAIF30 XBAR-RX" }, \ + { name " Mux", "ADMAIF31", "ADMAIF31 XBAR-RX" }, \ + { name " Mux", "ADMAIF32", "ADMAIF32 XBAR-RX" }, \ + { name " Mux", "I2S6", "I2S6 XBAR-RX" }, \ + { name " Mux", "I2S7", "I2S7 XBAR-RX" }, \ + { name " Mux", "I2S8", "I2S8 XBAR-RX" }, \ + { name " Mux", "AMX3", "AMX3 XBAR-RX" }, \ + { name " Mux", "AMX4", "AMX4 XBAR-RX" }, \ + { name " Mux", "AMX5", "AMX5 XBAR-RX" }, \ + { name " Mux", "AMX6", "AMX6 XBAR-RX" }, \ + { name " Mux", "ADX3 TX1", "ADX3 TX1 XBAR-RX" }, \ + { name " Mux", "ADX3 TX2", "ADX3 TX2 XBAR-RX" }, \ + { name " Mux", "ADX3 TX3", "ADX3 TX3 XBAR-RX" }, \ + { name " Mux", "ADX3 TX4", "ADX3 TX4 XBAR-RX" }, \ + { name " Mux", "ADX4 TX1", "ADX4 TX1 XBAR-RX" }, \ + { name " Mux", "ADX4 TX2", "ADX4 TX2 XBAR-RX" }, \ + { name " Mux", "ADX4 TX3", "ADX4 TX3 XBAR-RX" }, \ + { name " Mux", "ADX4 TX4", "ADX4 TX4 XBAR-RX" }, \ + { name " Mux", "ADX5 TX1", "ADX5 TX1 XBAR-RX" }, \ + { name " Mux", "ADX5 TX2", "ADX5 TX2 XBAR-RX" }, \ + { name " Mux", "ADX5 TX3", "ADX5 TX3 XBAR-RX" }, \ + { name " Mux", "ADX5 TX4", "ADX5 TX4 XBAR-RX" }, \ + { name " Mux", "ADX6 TX1", "ADX6 TX1 XBAR-RX" }, \ + { name " Mux", "ADX6 TX2", "ADX6 TX2 XBAR-RX" }, \ + { name " Mux", "ADX6 TX3", "ADX6 TX3 XBAR-RX" }, \ + { name " Mux", "ADX6 TX4", "ADX6 TX4 XBAR-RX" }, \ + { name " Mux", "ASRC1 TX1", "ASRC1 TX1 XBAR-RX" }, \ + { name " Mux", "ASRC1 TX2", "ASRC1 TX2 XBAR-RX" }, \ + { name " Mux", "ASRC1 TX3", "ASRC1 TX3 XBAR-RX" }, \ + { name " Mux", "ASRC1 TX4", "ASRC1 TX4 XBAR-RX" }, \ + { name " Mux", "ASRC1 TX5", "ASRC1 TX5 XBAR-RX" }, \ + { name " Mux", "ASRC1 TX6", "ASRC1 TX6 XBAR-RX" }, + #define TEGRA210_MUX_ROUTES(name) \ TEGRA_COMMON_MUX_ROUTES(name) \ TEGRA210_ONLY_MUX_ROUTES(name) @@ -1080,6 +1729,10 @@ static const struct snd_soc_dapm_widget tegra234_ahub_widgets[] = { TEGRA_COMMON_MUX_ROUTES(name) \ TEGRA186_ONLY_MUX_ROUTES(name) +#define TEGRA264_MUX_ROUTES(name) \ + TEGRA_COMMON_MUX_ROUTES(name) \ + TEGRA264_ONLY_MUX_ROUTES(name) + /* Connect FEs with XBAR */ #define TEGRA_FE_ROUTES(name) \ { name " XBAR-Playback", NULL, name " Playback" }, \ @@ -1238,6 +1891,136 @@ static const struct snd_soc_dapm_route tegra186_ahub_routes[] = { TEGRA186_MUX_ROUTES("OPE1") }; +static const struct snd_soc_dapm_route tegra264_ahub_routes[] = { + TEGRA_FE_ROUTES("ADMAIF1") + TEGRA_FE_ROUTES("ADMAIF2") + TEGRA_FE_ROUTES("ADMAIF3") + TEGRA_FE_ROUTES("ADMAIF4") + TEGRA_FE_ROUTES("ADMAIF5") + TEGRA_FE_ROUTES("ADMAIF6") + TEGRA_FE_ROUTES("ADMAIF7") + TEGRA_FE_ROUTES("ADMAIF8") + TEGRA_FE_ROUTES("ADMAIF9") + TEGRA_FE_ROUTES("ADMAIF10") + TEGRA_FE_ROUTES("ADMAIF11") + TEGRA_FE_ROUTES("ADMAIF12") + TEGRA_FE_ROUTES("ADMAIF13") + TEGRA_FE_ROUTES("ADMAIF14") + TEGRA_FE_ROUTES("ADMAIF15") + TEGRA_FE_ROUTES("ADMAIF16") + TEGRA_FE_ROUTES("ADMAIF17") + TEGRA_FE_ROUTES("ADMAIF18") + TEGRA_FE_ROUTES("ADMAIF19") + TEGRA_FE_ROUTES("ADMAIF20") + TEGRA_FE_ROUTES("ADMAIF21") + TEGRA_FE_ROUTES("ADMAIF22") + TEGRA_FE_ROUTES("ADMAIF23") + TEGRA_FE_ROUTES("ADMAIF24") + TEGRA_FE_ROUTES("ADMAIF25") + TEGRA_FE_ROUTES("ADMAIF26") + TEGRA_FE_ROUTES("ADMAIF27") + TEGRA_FE_ROUTES("ADMAIF28") + TEGRA_FE_ROUTES("ADMAIF29") + TEGRA_FE_ROUTES("ADMAIF30") + TEGRA_FE_ROUTES("ADMAIF31") + TEGRA_FE_ROUTES("ADMAIF32") + TEGRA264_MUX_ROUTES("ADMAIF1") + TEGRA264_MUX_ROUTES("ADMAIF2") + TEGRA264_MUX_ROUTES("ADMAIF3") + TEGRA264_MUX_ROUTES("ADMAIF4") + TEGRA264_MUX_ROUTES("ADMAIF5") + TEGRA264_MUX_ROUTES("ADMAIF6") + TEGRA264_MUX_ROUTES("ADMAIF7") + TEGRA264_MUX_ROUTES("ADMAIF8") + TEGRA264_MUX_ROUTES("ADMAIF9") + TEGRA264_MUX_ROUTES("ADMAIF10") + TEGRA264_MUX_ROUTES("ADMAIF11") + TEGRA264_MUX_ROUTES("ADMAIF12") + TEGRA264_MUX_ROUTES("ADMAIF13") + TEGRA264_MUX_ROUTES("ADMAIF14") + TEGRA264_MUX_ROUTES("ADMAIF15") + TEGRA264_MUX_ROUTES("ADMAIF16") + TEGRA264_MUX_ROUTES("ADMAIF17") + TEGRA264_MUX_ROUTES("ADMAIF18") + TEGRA264_MUX_ROUTES("ADMAIF19") + TEGRA264_MUX_ROUTES("ADMAIF20") + TEGRA264_MUX_ROUTES("ADMAIF21") + TEGRA264_MUX_ROUTES("ADMAIF22") + TEGRA264_MUX_ROUTES("ADMAIF23") + TEGRA264_MUX_ROUTES("ADMAIF24") + TEGRA264_MUX_ROUTES("ADMAIF25") + TEGRA264_MUX_ROUTES("ADMAIF26") + TEGRA264_MUX_ROUTES("ADMAIF27") + TEGRA264_MUX_ROUTES("ADMAIF28") + TEGRA264_MUX_ROUTES("ADMAIF29") + TEGRA264_MUX_ROUTES("ADMAIF30") + TEGRA264_MUX_ROUTES("ADMAIF31") + TEGRA264_MUX_ROUTES("ADMAIF32") + TEGRA264_MUX_ROUTES("I2S1") + TEGRA264_MUX_ROUTES("I2S2") + TEGRA264_MUX_ROUTES("I2S3") + TEGRA264_MUX_ROUTES("I2S4") + TEGRA264_MUX_ROUTES("I2S5") + TEGRA264_MUX_ROUTES("I2S6") + TEGRA264_MUX_ROUTES("I2S7") + TEGRA264_MUX_ROUTES("I2S8") + TEGRA264_MUX_ROUTES("DSPK1") + TEGRA264_MUX_ROUTES("SFC1") + TEGRA264_MUX_ROUTES("SFC2") + TEGRA264_MUX_ROUTES("SFC3") + TEGRA264_MUX_ROUTES("SFC4") + TEGRA264_MUX_ROUTES("MVC1") + TEGRA264_MUX_ROUTES("MVC2") + TEGRA264_MUX_ROUTES("AMX1 RX1") + TEGRA264_MUX_ROUTES("AMX1 RX2") + TEGRA264_MUX_ROUTES("AMX1 RX3") + TEGRA264_MUX_ROUTES("AMX1 RX4") + TEGRA264_MUX_ROUTES("AMX2 RX1") + TEGRA264_MUX_ROUTES("AMX2 RX2") + TEGRA264_MUX_ROUTES("AMX2 RX3") + TEGRA264_MUX_ROUTES("AMX2 RX4") + TEGRA264_MUX_ROUTES("AMX3 RX1") + TEGRA264_MUX_ROUTES("AMX3 RX2") + TEGRA264_MUX_ROUTES("AMX3 RX3") + TEGRA264_MUX_ROUTES("AMX3 RX4") + TEGRA264_MUX_ROUTES("AMX4 RX1") + TEGRA264_MUX_ROUTES("AMX4 RX2") + TEGRA264_MUX_ROUTES("AMX4 RX3") + TEGRA264_MUX_ROUTES("AMX4 RX4") + TEGRA264_MUX_ROUTES("AMX5 RX1") + TEGRA264_MUX_ROUTES("AMX5 RX2") + TEGRA264_MUX_ROUTES("AMX5 RX3") + TEGRA264_MUX_ROUTES("AMX5 RX4") + TEGRA264_MUX_ROUTES("AMX6 RX1") + TEGRA264_MUX_ROUTES("AMX6 RX2") + TEGRA264_MUX_ROUTES("AMX6 RX3") + TEGRA264_MUX_ROUTES("AMX6 RX4") + TEGRA264_MUX_ROUTES("ADX1") + TEGRA264_MUX_ROUTES("ADX2") + TEGRA264_MUX_ROUTES("ADX3") + TEGRA264_MUX_ROUTES("ADX4") + TEGRA264_MUX_ROUTES("ADX5") + TEGRA264_MUX_ROUTES("ADX6") + TEGRA264_MUX_ROUTES("MIXER1 RX1") + TEGRA264_MUX_ROUTES("MIXER1 RX2") + TEGRA264_MUX_ROUTES("MIXER1 RX3") + TEGRA264_MUX_ROUTES("MIXER1 RX4") + TEGRA264_MUX_ROUTES("MIXER1 RX5") + TEGRA264_MUX_ROUTES("MIXER1 RX6") + TEGRA264_MUX_ROUTES("MIXER1 RX7") + TEGRA264_MUX_ROUTES("MIXER1 RX8") + TEGRA264_MUX_ROUTES("MIXER1 RX9") + TEGRA264_MUX_ROUTES("MIXER1 RX10") + TEGRA264_MUX_ROUTES("ASRC1 RX1") + TEGRA264_MUX_ROUTES("ASRC1 RX2") + TEGRA264_MUX_ROUTES("ASRC1 RX3") + TEGRA264_MUX_ROUTES("ASRC1 RX4") + TEGRA264_MUX_ROUTES("ASRC1 RX5") + TEGRA264_MUX_ROUTES("ASRC1 RX6") + TEGRA264_MUX_ROUTES("ASRC1 RX7") + TEGRA264_MUX_ROUTES("OPE1") +}; + static const struct snd_soc_component_driver tegra210_ahub_component = { .dapm_widgets = tegra210_ahub_widgets, .num_dapm_widgets = ARRAY_SIZE(tegra210_ahub_widgets), @@ -1259,6 +2042,36 @@ static const struct snd_soc_component_driver tegra234_ahub_component = { .num_dapm_routes = ARRAY_SIZE(tegra186_ahub_routes), }; +static const struct snd_soc_component_driver tegra264_ahub_component = { + .dapm_widgets = tegra264_ahub_widgets, + .num_dapm_widgets = ARRAY_SIZE(tegra264_ahub_widgets), + .dapm_routes = tegra264_ahub_routes, + .num_dapm_routes = ARRAY_SIZE(tegra264_ahub_routes), +}; + +static bool tegra264_ahub_wr_reg(struct device *dev, unsigned int reg) +{ + int part; + + for (part = 0; part < TEGRA264_XBAR_UPDATE_MAX_REG; part++) { + switch (reg & ~(part << 12)) { + case TEGRA264_AXBAR_ADMAIF_RX1 ... TEGRA264_AXBAR_SFC4_RX1: + case TEGRA264_AXBAR_MIXER1_RX1 ... TEGRA264_AXBAR_MIXER1_RX10: + case TEGRA264_AXBAR_DSPK1_RX1: + case TEGRA264_AXBAR_OPE1_RX1: + case TEGRA264_AXBAR_MVC1_RX1 ... TEGRA264_AXBAR_MVC2_RX1: + case TEGRA264_AXBAR_AMX1_RX1 ... TEGRA264_AXBAR_AMX3_RX4: + case TEGRA264_AXBAR_ADX1_RX1 ... TEGRA264_AXBAR_ASRC1_RX7: + case TEGRA264_AXBAR_ADMAIF_RX21 ... TEGRA264_AXBAR_ADX6_RX1: + return true; + default: + break; + }; + } + + return false; +} + static const struct regmap_config tegra210_ahub_regmap_config = { .reg_bits = 32, .val_bits = 32, @@ -1275,6 +2088,15 @@ static const struct regmap_config tegra186_ahub_regmap_config = { .cache_type = REGCACHE_FLAT, }; +static const struct regmap_config tegra264_ahub_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .writeable_reg = tegra264_ahub_wr_reg, + .max_register = TEGRA264_MAX_REGISTER_ADDR, + .cache_type = REGCACHE_FLAT, +}; + static const struct tegra_ahub_soc_data soc_data_tegra210 = { .cmpnt_drv = &tegra210_ahub_component, .dai_drv = tegra210_ahub_dais, @@ -1285,6 +2107,7 @@ static const struct tegra_ahub_soc_data soc_data_tegra210 = { .mask[2] = TEGRA210_XBAR_REG_MASK_2, .mask[3] = TEGRA210_XBAR_REG_MASK_3, .reg_count = TEGRA210_XBAR_UPDATE_MAX_REG, + .xbar_part_size = TEGRA210_XBAR_PART1_RX, }; static const struct tegra_ahub_soc_data soc_data_tegra186 = { @@ -1297,6 +2120,7 @@ static const struct tegra_ahub_soc_data soc_data_tegra186 = { .mask[2] = TEGRA186_XBAR_REG_MASK_2, .mask[3] = TEGRA186_XBAR_REG_MASK_3, .reg_count = TEGRA186_XBAR_UPDATE_MAX_REG, + .xbar_part_size = TEGRA210_XBAR_PART1_RX, }; static const struct tegra_ahub_soc_data soc_data_tegra234 = { @@ -1309,12 +2133,28 @@ static const struct tegra_ahub_soc_data soc_data_tegra234 = { .mask[2] = TEGRA186_XBAR_REG_MASK_2, .mask[3] = TEGRA186_XBAR_REG_MASK_3, .reg_count = TEGRA186_XBAR_UPDATE_MAX_REG, + .xbar_part_size = TEGRA210_XBAR_PART1_RX, +}; + +static const struct tegra_ahub_soc_data soc_data_tegra264 = { + .cmpnt_drv = &tegra264_ahub_component, + .dai_drv = tegra264_ahub_dais, + .num_dais = ARRAY_SIZE(tegra264_ahub_dais), + .regmap_config = &tegra264_ahub_regmap_config, + .mask[0] = TEGRA264_XBAR_REG_MASK_0, + .mask[1] = TEGRA264_XBAR_REG_MASK_1, + .mask[2] = TEGRA264_XBAR_REG_MASK_2, + .mask[3] = TEGRA264_XBAR_REG_MASK_3, + .mask[4] = TEGRA264_XBAR_REG_MASK_4, + .reg_count = TEGRA264_XBAR_UPDATE_MAX_REG, + .xbar_part_size = TEGRA264_XBAR_PART1_RX, }; static const struct of_device_id tegra_ahub_of_match[] = { { .compatible = "nvidia,tegra210-ahub", .data = &soc_data_tegra210 }, { .compatible = "nvidia,tegra186-ahub", .data = &soc_data_tegra186 }, { .compatible = "nvidia,tegra234-ahub", .data = &soc_data_tegra234 }, + { .compatible = "nvidia,tegra264-ahub", .data = &soc_data_tegra264 }, {}, }; MODULE_DEVICE_TABLE(of, tegra_ahub_of_match); diff --git a/sound/soc/tegra/tegra210_ahub.h b/sound/soc/tegra/tegra210_ahub.h index 2728db4d24f2..f355b2cfd19b 100644 --- a/sound/soc/tegra/tegra210_ahub.h +++ b/sound/soc/tegra/tegra210_ahub.h @@ -2,7 +2,7 @@ /* * tegra210_ahub.h - TEGRA210 AHUB * - * Copyright (c) 2020-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2020-2025, NVIDIA CORPORATION. All rights reserved. * */ @@ -28,7 +28,39 @@ #define TEGRA186_XBAR_REG_MASK_3 0x3f0f00ff #define TEGRA186_XBAR_UPDATE_MAX_REG 4 -#define TEGRA_XBAR_UPDATE_MAX_REG (TEGRA186_XBAR_UPDATE_MAX_REG) +/* Tegra264 specific */ +#define TEGRA264_XBAR_PART1_RX 0x1000 +#define TEGRA264_XBAR_PART2_RX 0x2000 +#define TEGRA264_XBAR_PART3_RX 0x3000 +#define TEGRA264_XBAR_PART4_RX 0x4000 +#define TEGRA264_XBAR_PART0_ADX6_RX1 0x224 +#define TEGRA264_XBAR_AUDIO_RX_COUNT ((TEGRA264_XBAR_PART0_ADX6_RX1 / 4) + 1) +#define TEGRA264_XBAR_REG_MASK_0 0xfffffff +#define TEGRA264_XBAR_REG_MASK_1 0x3f013f1f +#define TEGRA264_XBAR_REG_MASK_2 0xff3c0301 +#define TEGRA264_XBAR_REG_MASK_3 0x3f00ffff +#define TEGRA264_XBAR_REG_MASK_4 0x7fff9f +#define TEGRA264_XBAR_UPDATE_MAX_REG 5 + +#define TEGRA264_AXBAR_ADMAIF_RX1 0x0 +#define TEGRA264_AXBAR_SFC4_RX1 0x6c +#define TEGRA264_AXBAR_MIXER1_RX1 0x80 +#define TEGRA264_AXBAR_MIXER1_RX10 0xa4 +#define TEGRA264_AXBAR_DSPK1_RX1 0xc0 +#define TEGRA264_AXBAR_OPE1_RX1 0x100 +#define TEGRA264_AXBAR_MVC1_RX1 0x110 +#define TEGRA264_AXBAR_MVC2_RX1 0x114 +#define TEGRA264_AXBAR_AMX1_RX1 0x120 +#define TEGRA264_AXBAR_AMX3_RX4 0x14c +#define TEGRA264_AXBAR_ADX1_RX1 0x160 +#define TEGRA264_AXBAR_ASRC1_RX7 0x1a8 +#define TEGRA264_AXBAR_ADMAIF_RX21 0x1d0 +#define TEGRA264_AXBAR_ADX6_RX1 0x224 + +#define TEGRA_XBAR_UPDATE_MAX_REG (TEGRA264_XBAR_UPDATE_MAX_REG) + +#define TEGRA264_MAX_REGISTER_ADDR (TEGRA264_XBAR_PART4_RX + \ + (TEGRA210_XBAR_RX_STRIDE * (TEGRA264_XBAR_AUDIO_RX_COUNT - 1))) #define TEGRA186_MAX_REGISTER_ADDR (TEGRA186_XBAR_PART3_RX + \ (TEGRA210_XBAR_RX_STRIDE * (TEGRA186_XBAR_AUDIO_RX_COUNT - 1))) @@ -76,6 +108,15 @@ #define MUX_ENUM_CTRL_DECL_234(ename, id) MUX_ENUM_CTRL_DECL_186(ename, id) +#define MUX_ENUM_CTRL_DECL_264(ename, id) \ + SOC_VALUE_ENUM_WIDE_DECL(ename##_enum, MUX_REG(id), 0, \ + tegra264_ahub_mux_texts, \ + tegra264_ahub_mux_values); \ + static const struct snd_kcontrol_new ename##_control = \ + SOC_DAPM_ENUM_EXT("Route", ename##_enum, \ + tegra_ahub_get_value_enum, \ + tegra_ahub_put_value_enum) + #define WIDGETS(sname, ename) \ SND_SOC_DAPM_AIF_IN(sname " XBAR-RX", NULL, 0, SND_SOC_NOPM, 0, 0), \ SND_SOC_DAPM_AIF_OUT(sname " XBAR-TX", NULL, 0, SND_SOC_NOPM, 0, 0), \ @@ -92,7 +133,7 @@ .playback = { \ .stream_name = #sname " XBAR-Playback", \ .channels_min = 1, \ - .channels_max = 16, \ + .channels_max = 32, \ .rates = SNDRV_PCM_RATE_8000_192000, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ @@ -102,7 +143,7 @@ .capture = { \ .stream_name = #sname " XBAR-Capture", \ .channels_min = 1, \ - .channels_max = 16, \ + .channels_max = 32, \ .rates = SNDRV_PCM_RATE_8000_192000, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ @@ -115,9 +156,10 @@ struct tegra_ahub_soc_data { const struct regmap_config *regmap_config; const struct snd_soc_component_driver *cmpnt_drv; struct snd_soc_dai_driver *dai_drv; - unsigned int mask[4]; + unsigned int mask[TEGRA_XBAR_UPDATE_MAX_REG]; unsigned int reg_count; unsigned int num_dais; + unsigned int xbar_part_size; }; struct tegra_ahub { -- cgit v1.2.3 From 7d852b34be4df61ae4327b47c39701d0f7ffcc70 Mon Sep 17 00:00:00 2001 From: Sheetal Date: Mon, 12 May 2025 05:17:47 +0000 Subject: ASoC: tegra: Tegra264 support in isomgr_bw Tegra264 supports max 32 channels, hence calculating the max bandwidth using the channel info from soc_data. Signed-off-by: Sheetal Link: https://patch.msgid.link/20250512051747.1026770-12-sheetal@nvidia.com Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_isomgr_bw.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra_isomgr_bw.c b/sound/soc/tegra/tegra_isomgr_bw.c index 18e802bca6a6..fa979960bc09 100644 --- a/sound/soc/tegra/tegra_isomgr_bw.c +++ b/sound/soc/tegra/tegra_isomgr_bw.c @@ -11,8 +11,8 @@ #include "tegra_isomgr_bw.h" #include "tegra210_admaif.h" -/* Max possible rate is 192KHz x 16channel x 4bytes */ -#define MAX_BW_PER_DEV 12288 +#define MAX_SAMPLE_RATE 192 /* KHz*/ +#define MAX_BYTES_PER_SAMPLE 4 int tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_running) @@ -98,7 +98,8 @@ int tegra_isomgr_adma_register(struct device *dev) } adma_isomgr->max_pcm_device = admaif->soc_data->num_ch; - adma_isomgr->max_bw = STREAM_TYPE * MAX_BW_PER_DEV * adma_isomgr->max_pcm_device; + adma_isomgr->max_bw = STREAM_TYPE * MAX_SAMPLE_RATE * MAX_BYTES_PER_SAMPLE * + admaif->soc_data->max_stream_ch * adma_isomgr->max_pcm_device; for (i = 0; i < STREAM_TYPE; i++) { adma_isomgr->bw_per_dev[i] = devm_kzalloc(dev, adma_isomgr->max_pcm_device * -- cgit v1.2.3