Files
linux-nv-oot/sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.c
Jon Hunter 59b14ea0b8 ASoC: tegra: Avoid kernel version checks
Rather than using kernel version checks to determine which kernel APIs
to use, add the necessary tests to the conftest script to determine
which kernel APIs are present in the kernel.

Note that the function snd_soc_dai_init_dma_data() has been present
in the Linux kernel since v3.13 and so use this for all kernel versions.
In Linux v6.3, the 'playback_dma_data' and 'capture_dma_data' members of
the snd_soc_dai_driver structure were replaced and so these could no
longer be set directly. However, the arguments to
snd_soc_dai_init_dma_data() have not changed and so can be used for
older kernels and well has the current.

This is beneficial for working with 3rd party Linux kernels that may
have back-ported upstream changes into their kernel and so the kernel
version checks do not work.

Bug 4221847

Change-Id: Ibac0c6bab78e93f03981dfe3d1b2025ea19d4c92
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2993795
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
2023-10-12 20:29:24 -07:00

951 lines
35 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <sound/dmaengine_pcm.h>
#include "tegra210_virt_alt_admaif.h"
#include "tegra_virt_alt_ivc.h"
#include "tegra_pcm_alt.h"
#include "tegra_asoc_xbar_virt_alt.h"
#include "tegra_asoc_util_virt_alt.h"
#define NUM_META_CONTROLS 3
static const unsigned int tegra210_rates[] = {
8000, 11025, 12000, 16000, 22050,
24000, 32000, 44100, 48000, 64000,
88200, 96000, 176400, 192000
};
static const struct snd_pcm_hw_constraint_list tegra210_rate_constraints = {
.count = ARRAY_SIZE(tegra210_rates),
.list = tegra210_rates,
};
static struct nvaudio_ivc_ctxt *svd_cntxt;
static struct tegra210_admaif *admaif;
static int tegra210_admaif_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct device *dev = dai->dev;
struct tegra210_virt_admaif_client_data *data =
&admaif->client_data;
struct tegra210_virt_audio_cif cif_conf;
struct nvaudio_ivc_msg msg;
unsigned int value;
int err;
memset(&cif_conf, 0, sizeof(struct tegra210_virt_audio_cif));
cif_conf.audio_channels = params_channels(params);
cif_conf.client_channels = params_channels(params);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_8;
cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_8;
break;
case SNDRV_PCM_FORMAT_S16_LE:
cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_16;
cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_24;
cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_32;
cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_32;
break;
default:
dev_err(dev, "Wrong format!\n");
return -EINVAL;
}
cif_conf.direction = substream->stream;
value = (cif_conf.threshold <<
TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
((cif_conf.audio_channels - 1) <<
TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
((cif_conf.client_channels - 1) <<
TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
(cif_conf.audio_bits <<
TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT) |
(cif_conf.client_bits <<
TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT) |
(cif_conf.expand <<
TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT) |
(cif_conf.stereo_conv <<
TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT) |
(cif_conf.replicate <<
TEGRA210_AUDIOCIF_CTRL_REPLICATE_SHIFT) |
(cif_conf.truncate <<
TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT) |
(cif_conf.mono_conv <<
TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT);
memset(&msg, 0, sizeof(struct nvaudio_ivc_msg));
msg.params.dmaif_info.id = dai->id;
msg.params.dmaif_info.value = value;
msg.ack_required = true;
if (!cif_conf.direction)
msg.cmd = NVAUDIO_DMAIF_SET_TXCIF;
else
msg.cmd = NVAUDIO_DMAIF_SET_RXCIF;
err = nvaudio_ivc_send_receive(data->hivc_client,
&msg,
sizeof(struct nvaudio_ivc_msg));
if (err < 0)
pr_err("%s: error on ivc_send_receive\n", __func__);
return 0;
}
static void tegra210_admaif_start_playback(struct snd_soc_dai *dai)
{
struct tegra210_virt_admaif_client_data *data =
&admaif->client_data;
int err;
struct nvaudio_ivc_msg msg;
memset(&msg, 0, sizeof(struct nvaudio_ivc_msg));
msg.cmd = NVAUDIO_START_PLAYBACK;
msg.params.dmaif_info.id = dai->id;
msg.ack_required = true;
err = nvaudio_ivc_send_receive(data->hivc_client,
&msg, sizeof(struct nvaudio_ivc_msg));
if (err < 0)
pr_err("%s: error on ivc_send\n", __func__);
}
static void tegra210_admaif_stop_playback(struct snd_soc_dai *dai)
{
struct tegra210_virt_admaif_client_data *data =
&admaif->client_data;
int err;
struct nvaudio_ivc_msg msg;
memset(&msg, 0, sizeof(struct nvaudio_ivc_msg));
msg.cmd = NVAUDIO_STOP_PLAYBACK;
msg.params.dmaif_info.id = dai->id;
msg.ack_required = true;
err = nvaudio_ivc_send_receive(data->hivc_client,
&msg, sizeof(struct nvaudio_ivc_msg));
if (err < 0)
pr_err("%s: error on ivc_send\n", __func__);
}
static void tegra210_admaif_start_capture(struct snd_soc_dai *dai)
{
struct tegra210_virt_admaif_client_data *data =
&admaif->client_data;
int err;
struct nvaudio_ivc_msg msg;
memset(&msg, 0, sizeof(struct nvaudio_ivc_msg));
msg.cmd = NVAUDIO_START_CAPTURE;
msg.params.dmaif_info.id = dai->id;
msg.ack_required = true;
err = nvaudio_ivc_send_receive(data->hivc_client,
&msg, sizeof(struct nvaudio_ivc_msg));
if (err < 0)
pr_err("%s: error on ivc_send\n", __func__);
}
static void tegra210_admaif_stop_capture(struct snd_soc_dai *dai)
{
struct tegra210_virt_admaif_client_data *data =
&admaif->client_data;
int err;
struct nvaudio_ivc_msg msg;
memset(&msg, 0, sizeof(struct nvaudio_ivc_msg));
msg.cmd = NVAUDIO_STOP_CAPTURE;
msg.params.dmaif_info.id = dai->id;
msg.ack_required = true;
err = nvaudio_ivc_send_receive(data->hivc_client,
&msg, sizeof(struct nvaudio_ivc_msg));
if (err < 0)
pr_err("%s: error on ivc_send\n", __func__);
}
static int tegra210_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
int err;
pr_info("Pcm trigger for admaif%d %s: cmd_id %d\n", dai->id+1,
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
"playback":"capture", cmd);
err = snd_dmaengine_pcm_trigger(substream, cmd);
if (err)
return err;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
tegra210_admaif_start_playback(dai);
else
tegra210_admaif_start_capture(dai);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
tegra210_admaif_stop_playback(dai);
else
tegra210_admaif_stop_capture(dai);
break;
default:
return -EINVAL;
}
return 0;
}
static int tegra210_admaif_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &tegra210_rate_constraints);
}
static struct snd_soc_dai_ops tegra210_admaif_dai_ops = {
.hw_params = tegra210_admaif_hw_params,
.trigger = tegra210_admaif_trigger,
.startup = tegra210_admaif_startup,
};
static int tegra210_admaif_dai_probe(struct snd_soc_dai *dai)
{
snd_soc_dai_init_dma_data(dai, &admaif->playback_dma_data[dai->id],
&admaif->capture_dma_data[dai->id]);
return 0;
}
#define ADMAIF_DAI(id) \
{ \
.name = "ADMAIF" #id, \
.probe = tegra210_admaif_dai_probe, \
.playback = { \
.stream_name = "Playback " #id, \
.channels_min = 1, \
.channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \
.formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE, \
}, \
.capture = { \
.stream_name = "Capture " #id, \
.channels_min = 1, \
.channels_max = 16, \
.rates = SNDRV_PCM_RATE_8000_192000, \
.formats = SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE, \
}, \
.ops = &tegra210_admaif_dai_ops, \
}
static struct snd_soc_dai_driver tegra210_admaif_dais[] = {
ADMAIF_DAI(1),
ADMAIF_DAI(2),
ADMAIF_DAI(3),
ADMAIF_DAI(4),
ADMAIF_DAI(5),
ADMAIF_DAI(6),
ADMAIF_DAI(7),
ADMAIF_DAI(8),
ADMAIF_DAI(9),
ADMAIF_DAI(10),
ADMAIF_DAI(11),
ADMAIF_DAI(12),
ADMAIF_DAI(13),
ADMAIF_DAI(14),
ADMAIF_DAI(15),
ADMAIF_DAI(16),
ADMAIF_DAI(17),
ADMAIF_DAI(18),
ADMAIF_DAI(19),
ADMAIF_DAI(20),
};
static const struct soc_enum tegra_virt_t186_asrc_source =
SOC_ENUM_SINGLE_EXT(NUM_ASRC_MODE, tegra186_asrc_ratio_source_text);
static const struct soc_enum tegra_virt_t186_arad_source =
SOC_VALUE_ENUM_SINGLE(0, 0, 0, NUM_ARAD_SOURCES,
tegra186_arad_mux_text,
tegra186_arad_mux_value);
static const struct soc_enum tegra_virt_t210_mvc_curvetype =
SOC_ENUM_SINGLE_EXT(NUM_MVC_CURVETYPE, tegra210_mvc_curve_type_text);
static const struct snd_kcontrol_new tegra_virt_t210ref_controls[] = {
MIXER_GAIN_CTRL_DECL("RX1 Gain", 0x00),
MIXER_GAIN_CTRL_DECL("RX2 Gain", 0x01),
MIXER_GAIN_CTRL_DECL("RX3 Gain", 0x02),
MIXER_GAIN_CTRL_DECL("RX4 Gain", 0x03),
MIXER_GAIN_CTRL_DECL("RX5 Gain", 0x04),
MIXER_GAIN_CTRL_DECL("RX6 Gain", 0x05),
MIXER_GAIN_CTRL_DECL("RX7 Gain", 0x06),
MIXER_GAIN_CTRL_DECL("RX8 Gain", 0x07),
MIXER_GAIN_CTRL_DECL("RX9 Gain", 0x08),
MIXER_GAIN_CTRL_DECL("RX10 Gain", 0x09),
MIXER_GAIN_INSTANT_CTRL_DECL("RX1 Gain Instant", 0x00),
MIXER_GAIN_INSTANT_CTRL_DECL("RX2 Gain Instant", 0x01),
MIXER_GAIN_INSTANT_CTRL_DECL("RX3 Gain Instant", 0x02),
MIXER_GAIN_INSTANT_CTRL_DECL("RX4 Gain Instant", 0x03),
MIXER_GAIN_INSTANT_CTRL_DECL("RX5 Gain Instant", 0x04),
MIXER_GAIN_INSTANT_CTRL_DECL("RX6 Gain Instant", 0x05),
MIXER_GAIN_INSTANT_CTRL_DECL("RX7 Gain Instant", 0x06),
MIXER_GAIN_INSTANT_CTRL_DECL("RX8 Gain Instant", 0x07),
MIXER_GAIN_INSTANT_CTRL_DECL("RX9 Gain Instant", 0x08),
MIXER_GAIN_INSTANT_CTRL_DECL("RX10 Gain Instant", 0x09),
MIXER_DURATION_CTRL_DECL("RX1 Duration", 0x00),
MIXER_DURATION_CTRL_DECL("RX2 Duration", 0x01),
MIXER_DURATION_CTRL_DECL("RX3 Duration", 0x02),
MIXER_DURATION_CTRL_DECL("RX4 Duration", 0x03),
MIXER_DURATION_CTRL_DECL("RX5 Duration", 0x04),
MIXER_DURATION_CTRL_DECL("RX6 Duration", 0x05),
MIXER_DURATION_CTRL_DECL("RX7 Duration", 0x06),
MIXER_DURATION_CTRL_DECL("RX8 Duration", 0x07),
MIXER_DURATION_CTRL_DECL("RX9 Duration", 0x08),
MIXER_DURATION_CTRL_DECL("RX10 Duration", 0x09),
MIXER_ENABLE_CTRL_DECL("Mixer Enable", 0x00),
MIXER_SET_FADE("Mixer fade", 0x00),
MIXER_GET_FADE_STATUS("Mixer fade status", 0x00),
SFC_IN_FREQ_CTRL_DECL("SFC1 input rate", 0x00),
SFC_IN_FREQ_CTRL_DECL("SFC2 input rate", 0x01),
SFC_IN_FREQ_CTRL_DECL("SFC3 input rate", 0x02),
SFC_IN_FREQ_CTRL_DECL("SFC4 input rate", 0x03),
SFC_OUT_FREQ_CTRL_DECL("SFC1 output rate", 0x00),
SFC_OUT_FREQ_CTRL_DECL("SFC2 output rate", 0x01),
SFC_OUT_FREQ_CTRL_DECL("SFC3 output rate", 0x02),
SFC_OUT_FREQ_CTRL_DECL("SFC4 output rate", 0x03),
MVC_CURVE_TYPE_CTRL_DECL("MVC1 Curve Type", 0x00,
&tegra_virt_t210_mvc_curvetype),
MVC_CURVE_TYPE_CTRL_DECL("MVC2 Curve Type", 0x01,
&tegra_virt_t210_mvc_curvetype),
MVC_TAR_VOL_CTRL_DECL("MVC1 Vol", 0x00),
MVC_TAR_VOL_CTRL_DECL("MVC2 Vol", 0x01),
MVC_MUTE_CTRL_DECL("MVC1 Mute", 0x00),
MVC_MUTE_CTRL_DECL("MVC2 Mute", 0x01),
AMX_ENABLE_CTRL_DECL("AMX1-1 Enable", 0x01, 0x01),
AMX_ENABLE_CTRL_DECL("AMX1-2 Enable", 0x01, 0x02),
AMX_ENABLE_CTRL_DECL("AMX1-3 Enable", 0x01, 0x03),
AMX_ENABLE_CTRL_DECL("AMX1-4 Enable", 0x01, 0x04),
AMX_ENABLE_CTRL_DECL("AMX2-1 Enable", 0x02, 0x01),
AMX_ENABLE_CTRL_DECL("AMX2-2 Enable", 0x02, 0x02),
AMX_ENABLE_CTRL_DECL("AMX2-3 Enable", 0x02, 0x03),
AMX_ENABLE_CTRL_DECL("AMX2-4 Enable", 0x02, 0x04),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S1 Loopback", 0x01),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S2 Loopback", 0x02),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S3 Loopback", 0x03),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S4 Loopback", 0x04),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S5 Loopback", 0x05),
REGDUMP_CTRL_DECL("ADMAIF1 regdump", ADMAIF1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF2 regdump", ADMAIF2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF3 regdump", ADMAIF3, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF4 regdump", ADMAIF4, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF5 regdump", ADMAIF5, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF6 regdump", ADMAIF6, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF7 regdump", ADMAIF7, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF8 regdump", ADMAIF8, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF9 regdump", ADMAIF9, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF10 regdump", ADMAIF10, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("AMX1 regdump", AMX1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("AMX2 regdump", AMX2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADX1 regdump", ADX1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADX2 regdump", ADX2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("MIXER1-1 RX regdump", MIXER1, 0, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-2 RX regdump", MIXER1, 1, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-3 RX regdump", MIXER1, 2, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-4 RX regdump", MIXER1, 3, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-5 RX regdump", MIXER1, 4, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-6 RX regdump", MIXER1, 5, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-7 RX regdump", MIXER1, 6, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-8 RX regdump", MIXER1, 7, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-9 RX regdump", MIXER1, 8, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-10 RX regdump", MIXER1, 9, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-1 TX regdump", MIXER1, 0, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("MIXER1-2 TX regdump", MIXER1, 1, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("MIXER1-3 TX regdump", MIXER1, 2, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("MIXER1-4 TX regdump", MIXER1, 3, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("MIXER1-5 TX regdump", MIXER1, 4, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("I2S1 regdump", I2S1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S2 regdump", I2S2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S3 regdump", I2S3, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S4 regdump", I2S4, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S5 regdump", I2S5, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("SFC1 regdump", SFC1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("SFC2 regdump", SFC2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("SFC3 regdump", SFC3, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("SFC4 regdump", SFC4, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("MVC1 regdump", MVC1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("MVC2 regdump", MVC2, 0, NVAUDIO_REGDUMP_RX_TX),
ADMA_REGDUMP_CTRL_DECL("ADMA1 regdump", 1),
ADMA_REGDUMP_CTRL_DECL("ADMA2 regdump", 2),
ADMA_REGDUMP_CTRL_DECL("ADMA3 regdump", 3),
ADMA_REGDUMP_CTRL_DECL("ADMA4 regdump", 4),
ADMA_REGDUMP_CTRL_DECL("ADMA5 regdump", 5),
ADMA_REGDUMP_CTRL_DECL("ADMA6 regdump", 6),
ADMA_REGDUMP_CTRL_DECL("ADMA7 regdump", 7),
ADMA_REGDUMP_CTRL_DECL("ADMA8 regdump", 8),
ADMA_REGDUMP_CTRL_DECL("ADMA9 regdump", 9),
ADMA_REGDUMP_CTRL_DECL("ADMA10 regdump", 10),
ADMA_REGDUMP_CTRL_DECL("ADMA11 regdump", 11),
ADMA_REGDUMP_CTRL_DECL("ADMA12 regdump", 12),
ADMA_REGDUMP_CTRL_DECL("ADMA13 regdump", 13),
ADMA_REGDUMP_CTRL_DECL("ADMA14 regdump", 14),
ADMA_REGDUMP_CTRL_DECL("ADMA15 regdump", 15),
ADMA_REGDUMP_CTRL_DECL("ADMA16 regdump", 16),
ADMA_REGDUMP_CTRL_DECL("ADMA17 regdump", 17),
ADMA_REGDUMP_CTRL_DECL("ADMA18 regdump", 18),
ADMA_REGDUMP_CTRL_DECL("ADMA19 regdump", 19),
ADMA_REGDUMP_CTRL_DECL("ADMA20 regdump", 20),
};
static const struct snd_kcontrol_new tegra_virt_t186ref_controls[] = {
MIXER_GAIN_CTRL_DECL("RX1 Gain", 0x00),
MIXER_GAIN_CTRL_DECL("RX2 Gain", 0x01),
MIXER_GAIN_CTRL_DECL("RX3 Gain", 0x02),
MIXER_GAIN_CTRL_DECL("RX4 Gain", 0x03),
MIXER_GAIN_CTRL_DECL("RX5 Gain", 0x04),
MIXER_GAIN_CTRL_DECL("RX6 Gain", 0x05),
MIXER_GAIN_CTRL_DECL("RX7 Gain", 0x06),
MIXER_GAIN_CTRL_DECL("RX8 Gain", 0x07),
MIXER_GAIN_CTRL_DECL("RX9 Gain", 0x08),
MIXER_GAIN_CTRL_DECL("RX10 Gain", 0x09),
MIXER_GAIN_INSTANT_CTRL_DECL("RX1 Gain Instant", 0x00),
MIXER_GAIN_INSTANT_CTRL_DECL("RX2 Gain Instant", 0x01),
MIXER_GAIN_INSTANT_CTRL_DECL("RX3 Gain Instant", 0x02),
MIXER_GAIN_INSTANT_CTRL_DECL("RX4 Gain Instant", 0x03),
MIXER_GAIN_INSTANT_CTRL_DECL("RX5 Gain Instant", 0x04),
MIXER_GAIN_INSTANT_CTRL_DECL("RX6 Gain Instant", 0x05),
MIXER_GAIN_INSTANT_CTRL_DECL("RX7 Gain Instant", 0x06),
MIXER_GAIN_INSTANT_CTRL_DECL("RX8 Gain Instant", 0x07),
MIXER_GAIN_INSTANT_CTRL_DECL("RX9 Gain Instant", 0x08),
MIXER_GAIN_INSTANT_CTRL_DECL("RX10 Gain Instant", 0x09),
MIXER_DURATION_CTRL_DECL("RX1 Duration", 0x00),
MIXER_DURATION_CTRL_DECL("RX2 Duration", 0x01),
MIXER_DURATION_CTRL_DECL("RX3 Duration", 0x02),
MIXER_DURATION_CTRL_DECL("RX4 Duration", 0x03),
MIXER_DURATION_CTRL_DECL("RX5 Duration", 0x04),
MIXER_DURATION_CTRL_DECL("RX6 Duration", 0x05),
MIXER_DURATION_CTRL_DECL("RX7 Duration", 0x06),
MIXER_DURATION_CTRL_DECL("RX8 Duration", 0x07),
MIXER_DURATION_CTRL_DECL("RX9 Duration", 0x08),
MIXER_DURATION_CTRL_DECL("RX10 Duration", 0x09),
MIXER_ENABLE_CTRL_DECL("Mixer Enable", 0x00),
MIXER_SET_FADE("Mixer fade", 0x00),
MIXER_GET_FADE_STATUS("Mixer fade status", 0x00),
SFC_IN_FREQ_CTRL_DECL("SFC1 input rate", 0x00),
SFC_IN_FREQ_CTRL_DECL("SFC2 input rate", 0x01),
SFC_IN_FREQ_CTRL_DECL("SFC3 input rate", 0x02),
SFC_IN_FREQ_CTRL_DECL("SFC4 input rate", 0x03),
SFC_OUT_FREQ_CTRL_DECL("SFC1 output rate", 0x00),
SFC_OUT_FREQ_CTRL_DECL("SFC2 output rate", 0x01),
SFC_OUT_FREQ_CTRL_DECL("SFC3 output rate", 0x02),
SFC_OUT_FREQ_CTRL_DECL("SFC4 output rate", 0x03),
MVC_CURVE_TYPE_CTRL_DECL("MVC1 Curve Type", 0x00,
&tegra_virt_t210_mvc_curvetype),
MVC_CURVE_TYPE_CTRL_DECL("MVC2 Curve Type", 0x01,
&tegra_virt_t210_mvc_curvetype),
MVC_TAR_VOL_CTRL_DECL("MVC1 Vol", 0x00),
MVC_TAR_VOL_CTRL_DECL("MVC2 Vol", 0x01),
MVC_MUTE_CTRL_DECL("MVC1 Mute", 0x00),
MVC_MUTE_CTRL_DECL("MVC2 Mute", 0x01),
ASRC_RATIO_CTRL_DECL("ASRC1 Ratio1", 0x01),
ASRC_RATIO_CTRL_DECL("ASRC1 Ratio2", 0x02),
ASRC_RATIO_CTRL_DECL("ASRC1 Ratio3", 0x03),
ASRC_RATIO_CTRL_DECL("ASRC1 Ratio4", 0x04),
ASRC_RATIO_CTRL_DECL("ASRC1 Ratio5", 0x05),
ASRC_RATIO_CTRL_DECL("ASRC1 Ratio6", 0x06),
ASRC_STREAM_RATIO_CTRL_DECL("ASRC1 Ratio1 SRC", 0x01,
&tegra_virt_t186_asrc_source),
ASRC_STREAM_RATIO_CTRL_DECL("ASRC1 Ratio2 SRC", 0x02,
&tegra_virt_t186_asrc_source),
ASRC_STREAM_RATIO_CTRL_DECL("ASRC1 Ratio3 SRC", 0x03,
&tegra_virt_t186_asrc_source),
ASRC_STREAM_RATIO_CTRL_DECL("ASRC1 Ratio4 SRC", 0x04,
&tegra_virt_t186_asrc_source),
ASRC_STREAM_RATIO_CTRL_DECL("ASRC1 Ratio5 SRC", 0x05,
&tegra_virt_t186_asrc_source),
ASRC_STREAM_RATIO_CTRL_DECL("ASRC1 Ratio6 SRC", 0x06,
&tegra_virt_t186_asrc_source),
ASRC_STREAM_ENABLE_CTRL_DECL("ASRC1 Stream1 Enable", 0x01),
ASRC_STREAM_ENABLE_CTRL_DECL("ASRC1 Stream2 Enable", 0x02),
ASRC_STREAM_ENABLE_CTRL_DECL("ASRC1 Stream3 Enable", 0x03),
ASRC_STREAM_ENABLE_CTRL_DECL("ASRC1 Stream4 Enable", 0x04),
ASRC_STREAM_ENABLE_CTRL_DECL("ASRC1 Stream5 Enable", 0x05),
ASRC_STREAM_ENABLE_CTRL_DECL("ASRC1 Stream6 Enable", 0x06),
ASRC_STREAM_HWCOMP_CTRL_DECL("ASRC1 Stream1 Hwcomp Disable", 0x01),
ASRC_STREAM_HWCOMP_CTRL_DECL("ASRC1 Stream2 Hwcomp Disable", 0x02),
ASRC_STREAM_HWCOMP_CTRL_DECL("ASRC1 Stream3 Hwcomp Disable", 0x03),
ASRC_STREAM_HWCOMP_CTRL_DECL("ASRC1 Stream4 Hwcomp Disable", 0x04),
ASRC_STREAM_HWCOMP_CTRL_DECL("ASRC1 Stream5 Hwcomp Disable", 0x05),
ASRC_STREAM_HWCOMP_CTRL_DECL("ASRC1 Stream6 Hwcomp Disable", 0x06),
ASRC_STREAM_INPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream1 Input Thresh", 0x01),
ASRC_STREAM_INPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream2 Input Thresh", 0x02),
ASRC_STREAM_INPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream3 Input Thresh", 0x03),
ASRC_STREAM_INPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream4 Input Thresh", 0x04),
ASRC_STREAM_INPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream5 Input Thresh", 0x05),
ASRC_STREAM_INPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream6 Input Thresh", 0x06),
ASRC_STREAM_OUTPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream1 Output Thresh", 0x01),
ASRC_STREAM_OUTPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream2 Output Thresh", 0x02),
ASRC_STREAM_OUTPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream3 Output Thresh", 0x03),
ASRC_STREAM_OUTPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream4 Output Thresh", 0x04),
ASRC_STREAM_OUTPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream5 Output Thresh", 0x05),
ASRC_STREAM_OUTPUT_THRESHOLD_CTRL_DECL("ASRC1 Stream6 Output Thresh", 0x06),
ARAD_LANE_SOURCE_CTRL_DECL("Numerator1 Mux", numerator1_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Numerator2 Mux", numerator2_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Numerator3 Mux", numerator3_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Numerator4 Mux", numerator4_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Numerator5 Mux", numerator5_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Numerator6 Mux", numerator6_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Denominator1 Mux", denominator1_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Denominator2 Mux", denominator2_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Denominator3 Mux", denominator3_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Denominator4 Mux", denominator4_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Denominator5 Mux", denominator5_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_SOURCE_CTRL_DECL("Denominator6 Mux", denominator6_enum,
&tegra_virt_t186_arad_source),
ARAD_LANE_PRESCALAR_CTRL_DECL("Numerator1 Prescalar", numerator1_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Numerator2 Prescalar", numerator2_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Numerator3 Prescalar", numerator3_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Numerator4 Prescalar", numerator4_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Numerator5 Prescalar", numerator5_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Numerator6 Prescalar", numerator6_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Denominator1 Prescalar", denominator1_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Denominator2 Prescalar", denominator2_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Denominator3 Prescalar", denominator3_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Denominator4 Prescalar", denominator4_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Denominator5 Prescalar", denominator5_enum),
ARAD_LANE_PRESCALAR_CTRL_DECL("Denominator6 Prescalar", denominator6_enum),
ARAD_LANE_ENABLE_CTRL_DECL("Lane1 enable", 0x00),
ARAD_LANE_ENABLE_CTRL_DECL("Lane2 enable", 0x01),
ARAD_LANE_ENABLE_CTRL_DECL("Lane3 enable", 0x02),
ARAD_LANE_ENABLE_CTRL_DECL("Lane4 enable", 0x03),
ARAD_LANE_ENABLE_CTRL_DECL("Lane5 enable", 0x04),
ARAD_LANE_ENABLE_CTRL_DECL("Lane6 enable", 0x05),
ARAD_LANE_RATIO_CTRL_DECL("Lane1 Ratio", 0x00),
ARAD_LANE_RATIO_CTRL_DECL("Lane2 Ratio", 0x01),
ARAD_LANE_RATIO_CTRL_DECL("Lane3 Ratio", 0x02),
ARAD_LANE_RATIO_CTRL_DECL("Lane4 Ratio", 0x03),
ARAD_LANE_RATIO_CTRL_DECL("Lane5 Ratio", 0x04),
ARAD_LANE_RATIO_CTRL_DECL("Lane6 Ratio", 0x05),
AMX_ENABLE_CTRL_DECL("AMX1-1 Enable", 0x01, 0x01),
AMX_ENABLE_CTRL_DECL("AMX1-2 Enable", 0x01, 0x02),
AMX_ENABLE_CTRL_DECL("AMX1-3 Enable", 0x01, 0x03),
AMX_ENABLE_CTRL_DECL("AMX1-4 Enable", 0x01, 0x04),
AMX_ENABLE_CTRL_DECL("AMX2-1 Enable", 0x02, 0x01),
AMX_ENABLE_CTRL_DECL("AMX2-2 Enable", 0x02, 0x02),
AMX_ENABLE_CTRL_DECL("AMX2-3 Enable", 0x02, 0x03),
AMX_ENABLE_CTRL_DECL("AMX2-4 Enable", 0x02, 0x04),
AMX_ENABLE_CTRL_DECL("AMX3-1 Enable", 0x03, 0x01),
AMX_ENABLE_CTRL_DECL("AMX3-2 Enable", 0x03, 0x02),
AMX_ENABLE_CTRL_DECL("AMX3-3 Enable", 0x03, 0x03),
AMX_ENABLE_CTRL_DECL("AMX3-4 Enable", 0x03, 0x04),
AMX_ENABLE_CTRL_DECL("AMX4-1 Enable", 0x04, 0x01),
AMX_ENABLE_CTRL_DECL("AMX4-2 Enable", 0x04, 0x02),
AMX_ENABLE_CTRL_DECL("AMX4-3 Enable", 0x04, 0x03),
AMX_ENABLE_CTRL_DECL("AMX4-4 Enable", 0x04, 0x04),
I2S_SET_RATE("I2S1 rate", 0x01),
I2S_SET_RATE("I2S2 rate", 0x02),
I2S_SET_RATE("I2S3 rate", 0x03),
I2S_SET_RATE("I2S4 rate", 0x04),
I2S_SET_RATE("I2S5 rate", 0x05),
I2S_SET_RATE("I2S6 rate", 0x06),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S1 Loopback", 0x01),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S2 Loopback", 0x02),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S3 Loopback", 0x03),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S4 Loopback", 0x04),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S5 Loopback", 0x05),
I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S6 Loopback", 0x06),
REGDUMP_CTRL_DECL("ADMAIF1 regdump", ADMAIF1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF2 regdump", ADMAIF2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF3 regdump", ADMAIF3, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF4 regdump", ADMAIF4, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF5 regdump", ADMAIF5, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF6 regdump", ADMAIF6, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF7 regdump", ADMAIF7, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF8 regdump", ADMAIF8, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF9 regdump", ADMAIF9, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF10 regdump", ADMAIF10, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF11 regdump", ADMAIF11, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF12 regdump", ADMAIF12, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF13 regdump", ADMAIF13, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF14 regdump", ADMAIF14, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF15 regdump", ADMAIF15, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF16 regdump", ADMAIF16, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF17 regdump", ADMAIF17, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF18 regdump", ADMAIF18, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF19 regdump", ADMAIF19, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADMAIF20 regdump", ADMAIF20, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("AMX1 regdump", AMX1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("AMX2 regdump", AMX2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("AMX3 regdump", AMX3, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("AMX4 regdump", AMX4, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADX1 regdump", ADX1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADX2 regdump", ADX2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADX3 regdump", ADX3, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ADX4 regdump", ADX4, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("MIXER1-1 RX regdump", MIXER1, 0, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-2 RX regdump", MIXER1, 1, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-3 RX regdump", MIXER1, 2, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-4 RX regdump", MIXER1, 3, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-5 RX regdump", MIXER1, 4, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-6 RX regdump", MIXER1, 5, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-7 RX regdump", MIXER1, 6, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-8 RX regdump", MIXER1, 7, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-9 RX regdump", MIXER1, 8, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-10 RX regdump", MIXER1, 9, NVAUDIO_REGDUMP_RX),
REGDUMP_CTRL_DECL("MIXER1-1 TX regdump", MIXER1, 0, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("MIXER1-2 TX regdump", MIXER1, 1, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("MIXER1-3 TX regdump", MIXER1, 2, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("MIXER1-4 TX regdump", MIXER1, 3, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("MIXER1-5 TX regdump", MIXER1, 4, NVAUDIO_REGDUMP_TX),
REGDUMP_CTRL_DECL("I2S1 regdump", I2S1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S2 regdump", I2S2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S3 regdump", I2S3, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S4 regdump", I2S4, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S5 regdump", I2S5, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("I2S6 regdump", I2S6, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ASRC1-1 regdump", ASRC1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ASRC1-2 regdump", ASRC1, 1, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ASRC1-3 regdump", ASRC1, 2, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ASRC1-4 regdump", ASRC1, 3, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ASRC1-5 regdump", ASRC1, 4, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ASRC1-6 regdump", ASRC1, 5, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("SFC1 regdump", SFC1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("SFC2 regdump", SFC2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("SFC3 regdump", SFC3, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("SFC4 regdump", SFC4, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("MVC1 regdump", MVC1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("MVC2 regdump", MVC2, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ARAD1 Lane1 regdump", ARAD1, 0, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ARAD1 Lane2 regdump", ARAD1, 1, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ARAD1 Lane3 regdump", ARAD1, 2, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ARAD1 Lane4 regdump", ARAD1, 3, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ARAD1 Lane5 regdump", ARAD1, 4, NVAUDIO_REGDUMP_RX_TX),
REGDUMP_CTRL_DECL("ARAD1 Lane6 regdump", ARAD1, 5, NVAUDIO_REGDUMP_RX_TX),
ADMA_REGDUMP_CTRL_DECL("ADMA1 regdump", 1),
ADMA_REGDUMP_CTRL_DECL("ADMA2 regdump", 2),
ADMA_REGDUMP_CTRL_DECL("ADMA3 regdump", 3),
ADMA_REGDUMP_CTRL_DECL("ADMA4 regdump", 4),
ADMA_REGDUMP_CTRL_DECL("ADMA5 regdump", 5),
ADMA_REGDUMP_CTRL_DECL("ADMA6 regdump", 6),
ADMA_REGDUMP_CTRL_DECL("ADMA7 regdump", 7),
ADMA_REGDUMP_CTRL_DECL("ADMA8 regdump", 8),
ADMA_REGDUMP_CTRL_DECL("ADMA9 regdump", 9),
ADMA_REGDUMP_CTRL_DECL("ADMA10 regdump", 10),
ADMA_REGDUMP_CTRL_DECL("ADMA11 regdump", 11),
ADMA_REGDUMP_CTRL_DECL("ADMA12 regdump", 12),
ADMA_REGDUMP_CTRL_DECL("ADMA13 regdump", 13),
ADMA_REGDUMP_CTRL_DECL("ADMA14 regdump", 14),
ADMA_REGDUMP_CTRL_DECL("ADMA15 regdump", 15),
ADMA_REGDUMP_CTRL_DECL("ADMA16 regdump", 16),
ADMA_REGDUMP_CTRL_DECL("ADMA17 regdump", 17),
ADMA_REGDUMP_CTRL_DECL("ADMA18 regdump", 18),
ADMA_REGDUMP_CTRL_DECL("ADMA19 regdump", 19),
ADMA_REGDUMP_CTRL_DECL("ADMA20 regdump", 20),
ADMA_REGDUMP_CTRL_DECL("ADMA21 regdump", 21),
ADMA_REGDUMP_CTRL_DECL("ADMA22 regdump", 22),
ADMA_REGDUMP_CTRL_DECL("ADMA23 regdump", 23),
ADMA_REGDUMP_CTRL_DECL("ADMA24 regdump", 24),
ADMA_REGDUMP_CTRL_DECL("ADMA25 regdump", 25),
ADMA_REGDUMP_CTRL_DECL("ADMA26 regdump", 26),
ADMA_REGDUMP_CTRL_DECL("ADMA27 regdump", 27),
ADMA_REGDUMP_CTRL_DECL("ADMA28 regdump", 28),
ADMA_REGDUMP_CTRL_DECL("ADMA29 regdump", 29),
ADMA_REGDUMP_CTRL_DECL("ADMA30 regdump", 30),
ADMA_REGDUMP_CTRL_DECL("ADMA31 regdump", 31),
ADMA_REGDUMP_CTRL_DECL("ADMA32 regdump", 32),
};
static struct snd_soc_component_driver tegra210_admaif_dai_driver = {
.name = "tegra210-virt-pcm",
.controls = tegra_virt_t186ref_controls,
.num_controls = ARRAY_SIZE(tegra_virt_t186ref_controls),
};
int tegra210_virt_admaif_register_component(struct platform_device *pdev,
struct tegra_virt_admaif_soc_data *data)
{
int i = 0;
int ret;
int admaif_ch_num = 0;
unsigned int admaif_ch_list[MAX_ADMAIF_IDS] = {0};
struct tegra_virt_admaif_soc_data *soc_data = data;
int adma_count = 0;
bool meta_enabled = false;
unsigned int buffer_size;
admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
if (admaif == NULL) {
ret = -ENOMEM;
goto err;
}
admaif->client_data.hivc_client =
nvaudio_ivc_alloc_ctxt(&pdev->dev);
if (!admaif->client_data.hivc_client) {
dev_err(&pdev->dev, "Failed to allocate IVC context\n");
ret = -ENODEV;
goto err;
}
svd_cntxt = admaif->client_data.hivc_client;
admaif->capture_dma_data = devm_kzalloc(&pdev->dev,
sizeof(struct tegra_alt_pcm_dma_params) *
soc_data->num_ch,
GFP_KERNEL);
if (admaif->capture_dma_data == NULL) {
ret = -ENOMEM;
goto err;
}
admaif->playback_dma_data = devm_kzalloc(&pdev->dev,
sizeof(struct tegra_alt_pcm_dma_params) *
soc_data->num_ch,
GFP_KERNEL);
if (admaif->playback_dma_data == NULL) {
ret = -ENOMEM;
goto err;
}
if (of_property_read_u32(pdev->dev.of_node,
"admaif_ch_num", &admaif_ch_num)) {
dev_err(&pdev->dev, "number of admaif channels is not set\n");
return -EINVAL;
}
if (of_property_read_u32_array(pdev->dev.of_node,
"admaif_ch_list",
admaif_ch_list,
admaif_ch_num)) {
dev_err(&pdev->dev, "admaif_ch_list is not populated\n");
return -EINVAL;
}
for (i = 0; i < soc_data->num_ch; i++) {
if ((i + 1) != admaif_ch_list[adma_count])
continue;
if (of_device_is_compatible(pdev->dev.of_node,
"nvidia,tegra186-virt-pcm")) {
admaif->playback_dma_data[i].addr = TEGRA186_ADMAIF_BASE +
TEGRA186_ADMAIF_XBAR_TX_FIFO_WRITE +
(i * TEGRA186_ADMAIF_CHANNEL_REG_STRIDE);
admaif->capture_dma_data[i].addr = TEGRA186_ADMAIF_BASE +
TEGRA186_ADMAIF_XBAR_RX_FIFO_READ +
(i * TEGRA186_ADMAIF_CHANNEL_REG_STRIDE);
} else if (of_device_is_compatible(pdev->dev.of_node,
"nvidia,tegra234-virt-pcm-oot")) {
admaif->playback_dma_data[i].addr = TEGRA186_ADMAIF_BASE +
TEGRA186_ADMAIF_XBAR_TX_FIFO_WRITE +
(i * TEGRA186_ADMAIF_CHANNEL_REG_STRIDE);
admaif->capture_dma_data[i].addr = TEGRA186_ADMAIF_BASE +
TEGRA186_ADMAIF_XBAR_RX_FIFO_READ +
(i * TEGRA186_ADMAIF_CHANNEL_REG_STRIDE);
} else if (of_device_is_compatible(pdev->dev.of_node,
"nvidia,tegra210-virt-pcm")) {
admaif->playback_dma_data[i].addr = TEGRA210_ADMAIF_BASE +
TEGRA210_ADMAIF_XBAR_TX_FIFO_WRITE +
(i * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
admaif->capture_dma_data[i].addr = TEGRA210_ADMAIF_BASE +
TEGRA210_ADMAIF_XBAR_RX_FIFO_READ +
(i * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
} else {
dev_err(&pdev->dev,
"Uncompatible device driver\n");
ret = -ENODEV;
goto err;
}
buffer_size = 0;
if (of_property_read_u32_index(pdev->dev.of_node,
"dma-buffer-size",
(i * 2) + 1,
&buffer_size) < 0)
dev_dbg(&pdev->dev,
"Missing property nvidia,dma-buffer-size\n");
admaif->playback_dma_data[i].buffer_size = buffer_size;
admaif->playback_dma_data[i].width = 32;
admaif->playback_dma_data[i].req_sel = i + 1;
if (of_property_read_string_index(pdev->dev.of_node,
"dma-names",
(adma_count * 2) + 1,
&admaif->playback_dma_data[i].chan_name) < 0) {
dev_err(&pdev->dev,
"Missing property nvidia,dma-names\n");
ret = -ENODEV;
goto err;
}
buffer_size = 0;
if (of_property_read_u32_index(pdev->dev.of_node,
"dma-buffer-size",
(i * 2),
&buffer_size) < 0)
dev_dbg(&pdev->dev,
"Missing property nvidia,dma-buffer-size\n");
admaif->capture_dma_data[i].buffer_size = buffer_size;
admaif->capture_dma_data[i].width = 32;
admaif->capture_dma_data[i].req_sel = i + 1;
if (of_property_read_string_index(pdev->dev.of_node,
"dma-names",
(adma_count * 2),
&admaif->capture_dma_data[i].chan_name) < 0) {
dev_err(&pdev->dev,
"Missing property nvidia,dma-names\n");
ret = -ENODEV;
goto err;
}
adma_count++;
}
/* Remove exposing metadata controls if not enabled in device node */
meta_enabled = of_property_read_bool(pdev->dev.of_node,
"sad_enabled");
if (!meta_enabled) {
tegra210_admaif_dai_driver.num_controls =
ARRAY_SIZE(tegra_virt_t186ref_controls) - NUM_META_CONTROLS;
}
ret = tegra_register_component(&pdev->dev,
&tegra210_admaif_dai_driver,
tegra210_admaif_dais,
soc_data->num_ch, "admaif");
if (ret) {
dev_err(&pdev->dev, "Could not register DAIs %d: %d\n",
i, ret);
goto err;
}
ret = tegra_alt_pcm_platform_register(&pdev->dev);
if (ret) {
dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
goto err_unregister_dais;
}
return 0;
err_unregister_dais:
snd_soc_unregister_component(&pdev->dev);
err:
return ret;
}
EXPORT_SYMBOL_GPL(tegra210_virt_admaif_register_component);
void tegra210_virt_admaif_unregister_component(struct platform_device *pdev)
{
tegra_alt_pcm_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
}
EXPORT_SYMBOL_GPL(tegra210_virt_admaif_unregister_component);
struct nvaudio_ivc_ctxt *nvaudio_get_saved_ivc_ctxt(void)
{
if (svd_cntxt)
return svd_cntxt;
pr_err("%s: ivc ctxt not allocated\n", __func__);
return NULL;
}
EXPORT_SYMBOL_GPL(nvaudio_get_saved_ivc_ctxt);
MODULE_LICENSE("GPL");