mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
nvidia: oot: add tegra-virt-alt as OOT module
Combined nvaudio-ivc with tegra-virt-alt. Bug 3735757 Change-Id: I9642c5367e43bfc470c70641fa22e50a4ae0e992 Signed-off-by: pmedawala <pmedawala@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2800354 GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com> Reviewed-by: Uday Gupta <udayg@nvidia.com> Reviewed-by: Niranjan Dighe <ndighe@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
7f189297bd
commit
e6e4bbc853
2
Makefile
2
Makefile
@@ -3,7 +3,9 @@
|
||||
|
||||
# Enable upstream fuse helper functions
|
||||
ccflags-y += -DCONFIG_TEGRA_FUSE_UPSTREAM
|
||||
LINUXINCLUDE += -I$(srctree.nvidia-oot)/include
|
||||
|
||||
obj-m += drivers/
|
||||
obj-m += sound/soc/tegra/
|
||||
obj-m += sound/tegra-safety-audio/
|
||||
obj-m += sound/soc/tegra-virt-alt/
|
||||
|
||||
22
sound/soc/tegra-virt-alt/Makefile
Normal file
22
sound/soc/tegra-virt-alt/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
GCOV_PROFILE := y
|
||||
|
||||
subdir-ccflags-y := -Werror
|
||||
ccflags-y += -I$(overlay)/$(src)/../tegra-virt-alt/include/
|
||||
ccflags-y += -I$(overlay)/$(src)/../codecs
|
||||
ccflags-y += -I$(srctree.nvidia)/sound/soc/tegra-virt-alt/nvaudio_ivc/
|
||||
|
||||
# Tegra platform Support
|
||||
|
||||
snd-soc-tegra210-virt-alt-admaif-objs := tegra210_virt_alt_admaif.o \
|
||||
tegra_asoc_xbar_virt_alt.o \
|
||||
tegra_asoc_util_virt_alt.o \
|
||||
tegra_asoc_machine_virt_alt.o \
|
||||
tegra_pcm_virt_alt.o \
|
||||
nvaudio_ivc/tegra_virt_alt_ivc.o
|
||||
|
||||
snd-soc-tegra-virt-t210ref-pcm-objs := tegra_virt_ref_alt.o
|
||||
obj-m += snd-soc-tegra210-virt-alt-admaif.o
|
||||
obj-m += snd-soc-tegra-virt-t210ref-pcm.o
|
||||
61
sound/soc/tegra-virt-alt/include/tegra_asoc_utils_alt.h
Normal file
61
sound/soc/tegra-virt-alt/include/tegra_asoc_utils_alt.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_ASOC_UTILS_ALT_H_
|
||||
#define __TEGRA_ASOC_UTILS_ALT_H_
|
||||
|
||||
struct clk;
|
||||
struct device;
|
||||
|
||||
enum tegra_asoc_utils_soc {
|
||||
TEGRA_ASOC_UTILS_SOC_TEGRA210,
|
||||
TEGRA_ASOC_UTILS_SOC_TEGRA186,
|
||||
TEGRA_ASOC_UTILS_SOC_TEGRA194,
|
||||
};
|
||||
|
||||
/*
|
||||
* Maintain same order in DT entry
|
||||
* FIXME: (This would be removed going ahead)
|
||||
*/
|
||||
enum tegra_asoc_utils_clkrate {
|
||||
PLLA_x11025_RATE,
|
||||
AUD_MCLK_x11025_RATE,
|
||||
PLLA_OUT0_x11025_RATE,
|
||||
AHUB_x11025_RATE,
|
||||
PLLA_x8000_RATE,
|
||||
AUD_MCLK_x8000_RATE,
|
||||
PLLA_OUT0_x8000_RATE,
|
||||
AHUB_x8000_RATE,
|
||||
MAX_NUM_RATES,
|
||||
};
|
||||
|
||||
struct tegra_asoc_audio_clock_info {
|
||||
struct device *dev;
|
||||
struct snd_soc_card *card;
|
||||
enum tegra_asoc_utils_soc soc;
|
||||
struct clk *clk_pll_base;
|
||||
struct clk *clk_pll_out;
|
||||
struct clk *clk_aud_mclk;
|
||||
struct reset_control *clk_cdev1_rst;
|
||||
unsigned int *pll_base_rate;
|
||||
u32 set_pll_base_rate;
|
||||
u32 set_pll_out_rate;
|
||||
u32 set_aud_mclk_rate;
|
||||
u32 mclk_scale;
|
||||
|
||||
/* FIXME: below would be removed going ahead */
|
||||
u32 clk_rates[MAX_NUM_RATES];
|
||||
u32 num_clk;
|
||||
};
|
||||
|
||||
int tegra_alt_asoc_utils_set_rate(struct tegra_asoc_audio_clock_info *data,
|
||||
unsigned int srate, unsigned int mclk,
|
||||
unsigned int clk_out_rate);
|
||||
int tegra_alt_asoc_utils_init(struct tegra_asoc_audio_clock_info *data,
|
||||
struct device *dev, struct snd_soc_card *card);
|
||||
int tegra_alt_asoc_utils_clk_enable(struct tegra_asoc_audio_clock_info *data);
|
||||
int tegra_alt_asoc_utils_clk_disable(struct tegra_asoc_audio_clock_info *data);
|
||||
|
||||
#endif
|
||||
22
sound/soc/tegra-virt-alt/include/tegra_isomgr_bw_alt.h
Normal file
22
sound/soc/tegra-virt-alt/include/tegra_isomgr_bw_alt.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_ISOMGR_BW_ALT_H__
|
||||
#define __TEGRA_ISOMGR_BW_ALT_H__
|
||||
|
||||
#if defined(CONFIG_TEGRA_ISOMGR)
|
||||
void tegra_isomgr_adma_register(void);
|
||||
void tegra_isomgr_adma_unregister(void);
|
||||
void tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream,
|
||||
bool is_running);
|
||||
void tegra_isomgr_adma_renegotiate(void *p, u32 avail_bw);
|
||||
#else
|
||||
static inline void tegra_isomgr_adma_register(void) { return; }
|
||||
static inline void tegra_isomgr_adma_unregister(void) { return; }
|
||||
static inline void tegra_isomgr_adma_setbw(struct snd_pcm_substream *substream,
|
||||
bool is_running) { return; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
22
sound/soc/tegra-virt-alt/include/tegra_pcm_alt.h
Normal file
22
sound/soc/tegra-virt-alt/include/tegra_pcm_alt.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_PCM_ALT_H__
|
||||
#define __TEGRA_PCM_ALT_H__
|
||||
|
||||
#define MAX_DMA_REQ_COUNT 2
|
||||
|
||||
struct tegra_alt_pcm_dma_params {
|
||||
unsigned long addr;
|
||||
unsigned long width;
|
||||
unsigned long req_sel;
|
||||
const char *chan_name;
|
||||
size_t buffer_size;
|
||||
};
|
||||
|
||||
int tegra_alt_pcm_platform_register(struct device *dev);
|
||||
void tegra_alt_pcm_platform_unregister(struct device *dev);
|
||||
|
||||
#endif
|
||||
265
sound/soc/tegra-virt-alt/nvaudio_ivc/tegra_virt_alt_ivc.c
Normal file
265
sound/soc/tegra-virt-alt/nvaudio_ivc/tegra_virt_alt_ivc.c
Normal file
@@ -0,0 +1,265 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/resource.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <soc/tegra/virt/hv-ivc.h>
|
||||
|
||||
#include "tegra_virt_alt_ivc.h"
|
||||
#include "tegra_virt_alt_ivc_common.h"
|
||||
|
||||
static struct nvaudio_ivc_ctxt *saved_ivc_ctxt;
|
||||
|
||||
static void nvaudio_ivc_deinit(struct nvaudio_ivc_ctxt *ictxt);
|
||||
static int nvaudio_ivc_init(struct nvaudio_ivc_ctxt *ictxt);
|
||||
|
||||
int nvaudio_ivc_send_retry(struct nvaudio_ivc_ctxt *ictxt,
|
||||
struct nvaudio_ivc_msg *msg, int size)
|
||||
{
|
||||
int err = 0;
|
||||
int dcnt = 50;
|
||||
|
||||
if (!ictxt || !ictxt->ivck || !msg || !size)
|
||||
return -EINVAL;
|
||||
|
||||
err = nvaudio_ivc_send(ictxt, msg, size);
|
||||
|
||||
while (err < 0 && dcnt--) {
|
||||
udelay(100);
|
||||
err = nvaudio_ivc_send(ictxt, msg, size);
|
||||
}
|
||||
return (dcnt < 0) ? -ETIMEDOUT : err;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvaudio_ivc_send_retry);
|
||||
|
||||
int nvaudio_ivc_send(struct nvaudio_ivc_ctxt *ictxt,
|
||||
struct nvaudio_ivc_msg *msg, int size)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned long flags = 0;
|
||||
int err = 0;
|
||||
int dcnt = 50;
|
||||
|
||||
if (!ictxt || !ictxt->ivck || !msg || !size)
|
||||
return -EINVAL;
|
||||
|
||||
while (tegra_hv_ivc_channel_notified(ictxt->ivck) != 0) {
|
||||
dev_err(ictxt->dev, "channel notified returns non zero\n");
|
||||
dcnt--;
|
||||
udelay(100);
|
||||
if (!dcnt)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ictxt->ivck_tx_lock, flags);
|
||||
|
||||
if (!tegra_hv_ivc_can_write(ictxt->ivck)) {
|
||||
err = -EBUSY;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
len = tegra_hv_ivc_write(ictxt->ivck, msg, size);
|
||||
if (len != size) {
|
||||
pr_err("%s: write Error\n", __func__);
|
||||
err = -EIO;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = len;
|
||||
|
||||
fail:
|
||||
spin_unlock_irqrestore(&ictxt->ivck_tx_lock, flags);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvaudio_ivc_send);
|
||||
|
||||
int nvaudio_ivc_send_receive(struct nvaudio_ivc_ctxt *ictxt,
|
||||
struct nvaudio_ivc_msg *rx_msg, int size)
|
||||
{
|
||||
|
||||
int len = 0;
|
||||
unsigned long flags = 0, flags1 = 0;
|
||||
int err = 0;
|
||||
int dcnt = 50;
|
||||
int status = -1;
|
||||
struct nvaudio_ivc_msg *msg = rx_msg;
|
||||
|
||||
if (!ictxt || !ictxt->ivck || !msg || !size)
|
||||
return -EINVAL;
|
||||
|
||||
while (tegra_hv_ivc_channel_notified(ictxt->ivck) != 0) {
|
||||
dev_err(ictxt->dev, "channel notified returns non zero\n");
|
||||
dcnt--;
|
||||
udelay(100);
|
||||
if (!dcnt)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ictxt->ivck_rx_lock, flags);
|
||||
spin_lock_irqsave(&ictxt->ivck_tx_lock, flags1);
|
||||
|
||||
if (!tegra_hv_ivc_can_write(ictxt->ivck)) {
|
||||
err = -EBUSY;
|
||||
spin_unlock_irqrestore(&ictxt->ivck_tx_lock, flags1);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
len = tegra_hv_ivc_write(ictxt->ivck, msg, size);
|
||||
if (len != size) {
|
||||
pr_err("%s: write Error\n", __func__);
|
||||
err = -EIO;
|
||||
spin_unlock_irqrestore(&ictxt->ivck_tx_lock, flags1);
|
||||
goto fail;
|
||||
}
|
||||
spin_unlock_irqrestore(&ictxt->ivck_tx_lock, flags1);
|
||||
|
||||
err = readx_poll_timeout_atomic(tegra_hv_ivc_can_read, ictxt->ivck,
|
||||
status, status, 10, NVAUDIO_IVC_WAIT_TIMEOUT);
|
||||
|
||||
if (err == -ETIMEDOUT) {
|
||||
pr_err("%s: Waited too long for msg reply\n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Message available */
|
||||
memset(rx_msg, 0, sizeof(struct nvaudio_ivc_msg));
|
||||
len = tegra_hv_ivc_read(ictxt->ivck,
|
||||
rx_msg,
|
||||
sizeof(struct nvaudio_ivc_msg));
|
||||
if (len != sizeof(struct nvaudio_ivc_msg)) {
|
||||
dev_err(ictxt->dev, "IVC read failure (msg size error)\n");
|
||||
err = -1;
|
||||
goto fail;
|
||||
}
|
||||
err = len;
|
||||
|
||||
fail:
|
||||
spin_unlock_irqrestore(&ictxt->ivck_rx_lock, flags);
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvaudio_ivc_send_receive);
|
||||
|
||||
/* Every communication with the server is identified
|
||||
* with this ivc context.
|
||||
* There can be one outstanding request to the server per
|
||||
* ivc context.
|
||||
*/
|
||||
struct nvaudio_ivc_ctxt *nvaudio_ivc_alloc_ctxt(struct device *dev)
|
||||
{
|
||||
struct nvaudio_ivc_ctxt *ictxt = NULL;
|
||||
|
||||
if (saved_ivc_ctxt)
|
||||
return saved_ivc_ctxt;
|
||||
|
||||
ictxt = devm_kzalloc(dev, sizeof(struct nvaudio_ivc_ctxt),
|
||||
GFP_KERNEL);
|
||||
if (ictxt == NULL) {
|
||||
dev_err(dev, "unable to allocate mem for ivc context\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
saved_ivc_ctxt = ictxt;
|
||||
ictxt->dev = dev;
|
||||
ictxt->timeout = 250; /* Not used in polling */
|
||||
if (nvaudio_ivc_init(ictxt) != 0) {
|
||||
dev_err(dev, "nvaudio_ivc_init failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
spin_lock_init(&ictxt->ivck_rx_lock);
|
||||
spin_lock_init(&ictxt->ivck_tx_lock);
|
||||
|
||||
tegra_hv_ivc_channel_reset(ictxt->ivck);
|
||||
|
||||
return ictxt;
|
||||
fail:
|
||||
nvaudio_ivc_free_ctxt(dev);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvaudio_ivc_alloc_ctxt);
|
||||
|
||||
struct nvaudio_ivc_ctxt *nvaudio_get_ivc_alloc_ctxt(void)
|
||||
{
|
||||
if (saved_ivc_ctxt)
|
||||
return saved_ivc_ctxt;
|
||||
|
||||
pr_err("%s: ivc ctxt not allocated\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvaudio_get_ivc_alloc_ctxt);
|
||||
|
||||
/* hook to domain destroy */
|
||||
void nvaudio_ivc_free_ctxt(struct device *dev)
|
||||
{
|
||||
if (saved_ivc_ctxt) {
|
||||
nvaudio_ivc_deinit(saved_ivc_ctxt);
|
||||
devm_kfree(dev, saved_ivc_ctxt);
|
||||
saved_ivc_ctxt = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvaudio_ivc_free_ctxt);
|
||||
|
||||
static void nvaudio_ivc_deinit(struct nvaudio_ivc_ctxt *ictxt)
|
||||
{
|
||||
if (ictxt)
|
||||
tegra_hv_ivc_unreserve(ictxt->ivck);
|
||||
}
|
||||
|
||||
static int nvaudio_ivc_init(struct nvaudio_ivc_ctxt *ictxt)
|
||||
{
|
||||
int err, ivc_queue;
|
||||
struct device_node *dn, *hv_dn;
|
||||
struct device *dev = ictxt->dev;
|
||||
struct tegra_hv_ivc_cookie *ivck = NULL;
|
||||
|
||||
dn = dev->of_node;
|
||||
if (dn == NULL) {
|
||||
dev_err(dev, "No OF data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hv_dn = of_parse_phandle(dn, "ivc_queue", 0);
|
||||
if (hv_dn == NULL) {
|
||||
dev_err(dev, "Failed to parse phandle of ivc prop\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = of_property_read_u32_index(dn, "ivc_queue", 1, &ivc_queue);
|
||||
if (err != 0) {
|
||||
dev_err(dev, "Failed to read IVC property ID\n");
|
||||
of_node_put(hv_dn);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ivck = tegra_hv_ivc_reserve(hv_dn, ivc_queue, NULL);
|
||||
|
||||
if (IS_ERR_OR_NULL(ivck)) {
|
||||
dev_err(dev, "Failed to reserve ivc queue %d\n", ivc_queue);
|
||||
if (ivck == ERR_PTR(-EPROBE_DEFER))
|
||||
return -EPROBE_DEFER;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_node_put(hv_dn);
|
||||
|
||||
ictxt->ivc_queue = ivc_queue;
|
||||
ictxt->ivck = ivck;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
54
sound/soc/tegra-virt-alt/nvaudio_ivc/tegra_virt_alt_ivc.h
Normal file
54
sound/soc/tegra-virt-alt/nvaudio_ivc/tegra_virt_alt_ivc.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_VIRT_ALT_IVC_H__
|
||||
#define __TEGRA_VIRT_ALT_IVC_H__
|
||||
|
||||
#include "tegra_virt_alt_ivc_common.h"
|
||||
|
||||
#define NVAUDIO_IVC_WAIT_TIMEOUT 1000000
|
||||
struct nvaudio_ivc_dev;
|
||||
|
||||
struct nvaudio_ivc_ctxt {
|
||||
struct tegra_hv_ivc_cookie *ivck;
|
||||
struct device *dev;
|
||||
int ivc_queue;
|
||||
wait_queue_head_t wait;
|
||||
int timeout;
|
||||
enum rx_state_t rx_state;
|
||||
struct nvaudio_ivc_dev *ivcdev;
|
||||
spinlock_t ivck_rx_lock;
|
||||
spinlock_t ivck_tx_lock;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
void nvaudio_ivc_rx(struct tegra_hv_ivc_cookie *ivck);
|
||||
|
||||
struct nvaudio_ivc_ctxt *nvaudio_ivc_alloc_ctxt(struct device *dev);
|
||||
|
||||
void nvaudio_ivc_free_ctxt(struct device *dev);
|
||||
|
||||
int nvaudio_ivc_send(struct nvaudio_ivc_ctxt *ictxt,
|
||||
struct nvaudio_ivc_msg *msg,
|
||||
int size);
|
||||
|
||||
int nvaudio_ivc_send_retry(struct nvaudio_ivc_ctxt *ictxt,
|
||||
struct nvaudio_ivc_msg *msg,
|
||||
int size);
|
||||
|
||||
int nvaudio_ivc_send_receive(struct nvaudio_ivc_ctxt *ictxt,
|
||||
struct nvaudio_ivc_msg *msg,
|
||||
int size);
|
||||
|
||||
int tegra124_virt_xbar_set_ivc(struct nvaudio_ivc_ctxt *ictxt,
|
||||
int rx_idx,
|
||||
int tx_idx);
|
||||
int tegra124_virt_xbar_get_ivc(struct nvaudio_ivc_ctxt *ictxt,
|
||||
int rx_idx,
|
||||
int *tx_idx);
|
||||
|
||||
struct nvaudio_ivc_ctxt *nvaudio_get_ivc_alloc_ctxt(void);
|
||||
|
||||
#endif
|
||||
279
sound/soc/tegra-virt-alt/nvaudio_ivc/tegra_virt_alt_ivc_common.h
Normal file
279
sound/soc/tegra-virt-alt/nvaudio_ivc/tegra_virt_alt_ivc_common.h
Normal file
@@ -0,0 +1,279 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_VIRT_ALT_IVC_COMMON_H__
|
||||
#define __TEGRA_VIRT_ALT_IVC_COMMON_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define TEGRA210_MIXER_AXBAR_RX_MAX 10
|
||||
|
||||
enum ivc_audio_err_t {
|
||||
NVAUDIO_ERR_OK,
|
||||
NVAUDIO_ERR_SERVER_STATE,
|
||||
NVAUDIO_ERR_ARGS,
|
||||
NVAUDIO_ERR_REQ,
|
||||
NVAUDIO_ERR_UNSUPPORTED_REQ
|
||||
};
|
||||
|
||||
enum rx_state_t {
|
||||
RX_INIT,
|
||||
RX_PENDING,
|
||||
RX_AVAIL,
|
||||
RX_DONE,
|
||||
};
|
||||
|
||||
enum ivc_audio_regdump_t {
|
||||
NVAUDIO_REGDUMP_RX_TX,
|
||||
NVAUDIO_REGDUMP_RX,
|
||||
NVAUDIO_REGDUMP_TX,
|
||||
NVAUDIO_REGDUMP_GLOBAL
|
||||
};
|
||||
|
||||
enum ivc_adsp_assert {
|
||||
ASSERT, /* SET */
|
||||
DEASSERT /* CLEAR */
|
||||
};
|
||||
|
||||
enum ape_ahub_blocks_t {
|
||||
ADMAIF1 = 1,
|
||||
ADMAIF2,
|
||||
ADMAIF3,
|
||||
ADMAIF4,
|
||||
ADMAIF5,
|
||||
ADMAIF6,
|
||||
ADMAIF7,
|
||||
ADMAIF8,
|
||||
ADMAIF9,
|
||||
ADMAIF10,
|
||||
ADMAIF11,
|
||||
ADMAIF12,
|
||||
ADMAIF13,
|
||||
ADMAIF14,
|
||||
ADMAIF15,
|
||||
ADMAIF16,
|
||||
ADMAIF17,
|
||||
ADMAIF18,
|
||||
ADMAIF19,
|
||||
ADMAIF20,
|
||||
AMX1,
|
||||
AMX2,
|
||||
AMX3,
|
||||
AMX4,
|
||||
ADX1,
|
||||
ADX2,
|
||||
ADX3,
|
||||
ADX4,
|
||||
MIXER1,
|
||||
I2S1,
|
||||
I2S2,
|
||||
I2S3,
|
||||
I2S4,
|
||||
I2S5,
|
||||
I2S6,
|
||||
ASRC1,
|
||||
SFC1,
|
||||
SFC2,
|
||||
SFC3,
|
||||
SFC4,
|
||||
AFC1,
|
||||
AFC2,
|
||||
AFC3,
|
||||
AFC4,
|
||||
AFC5,
|
||||
AFC6,
|
||||
MVC1,
|
||||
MVC2,
|
||||
ARAD1,
|
||||
MAX_AHUB_RESOURCES
|
||||
};
|
||||
|
||||
enum nvaudio_ivc_cmd_t {
|
||||
NVAUDIO_DMAIF_SET_RXCIF,
|
||||
NVAUDIO_DMAIF_SET_TXCIF,
|
||||
NVAUDIO_START_PLAYBACK,
|
||||
NVAUDIO_STOP_PLAYBACK,
|
||||
NVAUDIO_START_CAPTURE,
|
||||
NVAUDIO_STOP_CAPTURE,
|
||||
NVAUDIO_XBAR_SET_ROUTE,
|
||||
NVAUDIO_XBAR_GET_ROUTE,
|
||||
NVAUDIO_AMIXER_SET_RX_GAIN,
|
||||
NVAUDIO_AMIXER_SET_TX_ADDER_CONFIG,
|
||||
NVAUDIO_AMIXER_SET_ENABLE,
|
||||
NVAUDIO_AMIXER_GET_TX_ADDER_CONFIG,
|
||||
NVAUDIO_AMIXER_GET_ENABLE,
|
||||
NVAUDIO_SFC_SET_IN_FREQ,
|
||||
NVAUDIO_SFC_GET_IN_FREQ,
|
||||
NVAUDIO_SFC_SET_OUT_FREQ,
|
||||
NVAUDIO_SFC_GET_OUT_FREQ,
|
||||
NVAUDIO_ASRC_SET_INT_RATIO,
|
||||
NVAUDIO_ASRC_GET_INT_RATIO,
|
||||
NVAUDIO_ASRC_SET_FRAC_RATIO,
|
||||
NVAUDIO_ASRC_GET_FRAC_RATIO,
|
||||
NVAUDIO_ASRC_SET_RATIO_SOURCE,
|
||||
NVAUDIO_ASRC_GET_RATIO_SOURCE,
|
||||
NVAUDIO_ASRC_SET_STREAM_ENABLE,
|
||||
NVAUDIO_ASRC_GET_STREAM_ENABLE,
|
||||
NVAUDIO_ASRC_SET_HWCOMP_DISABLE,
|
||||
NVAUDIO_ASRC_GET_HWCOMP_DISABLE,
|
||||
NVAUDIO_ASRC_SET_INPUT_THRESHOLD,
|
||||
NVAUDIO_ASRC_GET_INPUT_THRESHOLD,
|
||||
NVAUDIO_ASRC_SET_OUTPUT_THRESHOLD,
|
||||
NVAUDIO_ASRC_GET_OUTPUT_THRESHOLD,
|
||||
NVAUDIO_ARAD_SET_LANE_SRC,
|
||||
NVAUDIO_ARAD_GET_LANE_SRC,
|
||||
NVAUDIO_ARAD_SET_PRESCALAR,
|
||||
NVAUDIO_ARAD_GET_PRESCALAR,
|
||||
NVAUDIO_ARAD_SET_LANE_ENABLE,
|
||||
NVAUDIO_ARAD_GET_LANE_ENABLE,
|
||||
NVAUDIO_ARAD_GET_LANE_RATIO,
|
||||
NVAUDIO_AMX_SET_INPUT_STREAM_ENABLE,
|
||||
NVAUDIO_I2S_SET_LOOPBACK_ENABLE,
|
||||
NVAUDIO_I2S_GET_LOOPBACK_ENABLE,
|
||||
NVAUDIO_I2S_GET_RATE,
|
||||
NVAUDIO_I2S_SET_RATE,
|
||||
NVAUDIO_ASRC_SET_RATIO,
|
||||
NVAUDIO_ASRC_GET_RATIO,
|
||||
NVAUDIO_MVC_SET_CURVETYPE,
|
||||
NVAUDIO_MVC_GET_CURVETYPE,
|
||||
NVAUDIO_MVC_SET_TAR_VOL,
|
||||
NVAUDIO_MVC_GET_TAR_VOL,
|
||||
NVAUDIO_MVC_SET_MUTE,
|
||||
NVAUDIO_MVC_GET_MUTE,
|
||||
NVAUDIO_AMIXER_GET_RX_GAIN,
|
||||
NVAUDIO_AMIXER_SET_RX_DURATION,
|
||||
NVAUDIO_AMIXER_GET_RX_DURATION,
|
||||
NVAUDIO_AHUB_BLOCK_REGDUMP,
|
||||
NVAUDIO_AMIXER_SET_FADE,
|
||||
NVAUDIO_AMIXER_GET_FADE_STATUS,
|
||||
NVAUDIO_AMX_SET_INPUT_IDLE_CNT,
|
||||
NVAUDIO_ADSP_RESET,
|
||||
NVAUDIO_ADMA_BLOCK_REGDUMP,
|
||||
NVAUDIO_CMD_MAX,
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t210_amx_info {
|
||||
int32_t amx_id;
|
||||
uint32_t amx_stream_id;
|
||||
uint32_t amx_stream_enable;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t210_i2s_info {
|
||||
int32_t i2s_id;
|
||||
uint32_t i2s_loopback_enable;
|
||||
uint32_t i2s_rate;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t210_amixer_info {
|
||||
int32_t id;
|
||||
uint32_t rx_idx;
|
||||
uint32_t gain;
|
||||
uint32_t adder_idx;
|
||||
uint32_t adder_rx_idx;
|
||||
uint32_t adder_rx_idx_enable;
|
||||
uint32_t is_instant_gain;
|
||||
uint32_t duration_n3;
|
||||
uint32_t enable;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t210_sfc_info {
|
||||
int32_t id;
|
||||
uint32_t in_freq;
|
||||
uint32_t out_freq;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t210_mvc_info {
|
||||
int32_t id;
|
||||
uint32_t curve_type;
|
||||
uint32_t tar_vol;
|
||||
uint32_t mute;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t186_asrc_info {
|
||||
int32_t id;
|
||||
int32_t stream_num;
|
||||
uint32_t int_ratio;
|
||||
uint32_t frac_ratio;
|
||||
uint32_t input_threshold;
|
||||
uint32_t output_threshold;
|
||||
uint32_t hwcomp_disable;
|
||||
uint32_t stream_enable;
|
||||
uint32_t ratio_source;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t186_arad_info {
|
||||
int32_t id;
|
||||
uint32_t lane_id;
|
||||
uint32_t int_ratio;
|
||||
uint32_t frac_ratio;
|
||||
int32_t num_source;
|
||||
int32_t den_source;
|
||||
int32_t num_prescalar;
|
||||
int32_t den_prescalar;
|
||||
uint32_t lane_enable;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_xbar_link {
|
||||
int32_t rx_reg;
|
||||
uint32_t tx_value;
|
||||
uint32_t tx_idx;
|
||||
uint32_t bit_pos;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_dmaif_info {
|
||||
int32_t id;
|
||||
int32_t value;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_ahub_block {
|
||||
uint32_t block_id;
|
||||
uint32_t dump_cmd;
|
||||
uint32_t stream_id;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t210_amixer_fade_info {
|
||||
uint32_t id;
|
||||
uint32_t rx_idx;
|
||||
uint32_t gain_level[TEGRA210_MIXER_AXBAR_RX_MAX];
|
||||
uint32_t duration_n3[TEGRA210_MIXER_AXBAR_RX_MAX];
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t210_amixer_fade_status {
|
||||
uint32_t id;
|
||||
int32_t status[TEGRA210_MIXER_AXBAR_RX_MAX];
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_adsp_reset {
|
||||
uint32_t reset_req;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_t210_adma_info {
|
||||
uint32_t channel_num;
|
||||
};
|
||||
|
||||
struct nvaudio_ivc_msg {
|
||||
int32_t channel_id;
|
||||
enum nvaudio_ivc_cmd_t cmd;
|
||||
union {
|
||||
struct nvaudio_ivc_dmaif_info dmaif_info;
|
||||
struct nvaudio_ivc_t210_amixer_info amixer_info;
|
||||
struct nvaudio_ivc_t210_sfc_info sfc_info;
|
||||
struct nvaudio_ivc_t210_mvc_info mvc_info;
|
||||
struct nvaudio_ivc_t186_asrc_info asrc_info;
|
||||
struct nvaudio_ivc_t186_arad_info arad_info;
|
||||
struct nvaudio_ivc_t210_amx_info amx_info;
|
||||
struct nvaudio_ivc_t210_i2s_info i2s_info;
|
||||
struct nvaudio_ivc_xbar_link xbar_info;
|
||||
struct nvaudio_ivc_ahub_block ahub_block_info;
|
||||
struct nvaudio_ivc_t210_amixer_fade_info fade_info;
|
||||
struct nvaudio_ivc_t210_amixer_fade_status fade_status;
|
||||
struct nvaudio_ivc_adsp_reset adsp_reset_info;
|
||||
struct nvaudio_ivc_t210_adma_info adma_info;
|
||||
} params;
|
||||
bool ack_required;
|
||||
int32_t err;
|
||||
};
|
||||
|
||||
#endif
|
||||
949
sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.c
Normal file
949
sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.c
Normal file
@@ -0,0 +1,949 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021-2022 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;
|
||||
if (!cif_conf.direction)
|
||||
msg.cmd = NVAUDIO_DMAIF_SET_TXCIF;
|
||||
else
|
||||
msg.cmd = NVAUDIO_DMAIF_SET_RXCIF;
|
||||
|
||||
err = nvaudio_ivc_send(data->hivc_client,
|
||||
&msg,
|
||||
sizeof(struct nvaudio_ivc_msg));
|
||||
|
||||
if (err < 0)
|
||||
pr_err("%s: error on ivc_send\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)
|
||||
{
|
||||
dai->capture_dma_data = &admaif->capture_dma_data[dai->id];
|
||||
dai->playback_dma_data = &admaif->playback_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");
|
||||
104
sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.h
Normal file
104
sound/soc/tegra-virt-alt/tegra210_virt_alt_admaif.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA210_VIRT_ALT_ADMAIF_H__
|
||||
#define __TEGRA210_VIRT_ALT_ADMAIF_H__
|
||||
|
||||
#define DRV_NAME "virt-alt-pcm-oot"
|
||||
|
||||
#define TEGRA210_ADMAIF_BASE 0x702d0000
|
||||
#define TEGRA210_ADMAIF_XBAR_RX_FIFO_READ 0x2c
|
||||
#define TEGRA210_ADMAIF_XBAR_TX_FIFO_WRITE 0x32c
|
||||
#define TEGRA210_ADMAIF_CHANNEL_REG_STRIDE 0x40
|
||||
|
||||
#define TEGRA186_ADMAIF_BASE 0x0290f000
|
||||
#define TEGRA186_ADMAIF_XBAR_RX_FIFO_READ 0x2c
|
||||
#define TEGRA186_ADMAIF_XBAR_TX_FIFO_WRITE 0x52c
|
||||
#define TEGRA186_ADMAIF_CHANNEL_REG_STRIDE 0x40
|
||||
|
||||
#define TEGRA210_AUDIOCIF_BITS_8 1
|
||||
#define TEGRA210_AUDIOCIF_BITS_12 2
|
||||
#define TEGRA210_AUDIOCIF_BITS_16 3
|
||||
#define TEGRA210_AUDIOCIF_BITS_20 4
|
||||
#define TEGRA210_AUDIOCIF_BITS_24 5
|
||||
#define TEGRA210_AUDIOCIF_BITS_28 6
|
||||
#define TEGRA210_AUDIOCIF_BITS_32 7
|
||||
|
||||
#define TEGRA210_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT 24
|
||||
#define TEGRA210_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT 20
|
||||
#define TEGRA210_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT 16
|
||||
#define TEGRA210_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT 12
|
||||
#define TEGRA210_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT 8
|
||||
#define TEGRA210_AUDIOCIF_CTRL_EXPAND_SHIFT 6
|
||||
#define TEGRA210_AUDIOCIF_CTRL_STEREO_CONV_SHIFT 4
|
||||
#define TEGRA210_AUDIOCIF_CTRL_REPLICATE_SHIFT 3
|
||||
#define TEGRA210_AUDIOCIF_CTRL_TRUNCATE_SHIFT 1
|
||||
#define TEGRA210_AUDIOCIF_CTRL_MONO_CONV_SHIFT 0
|
||||
|
||||
/* ADMAIF ids */
|
||||
enum {
|
||||
ADMAIF_ID_0 = 0,
|
||||
ADMAIF_ID_1,
|
||||
ADMAIF_ID_2,
|
||||
ADMAIF_ID_3,
|
||||
ADMAIF_ID_4,
|
||||
ADMAIF_ID_5,
|
||||
ADMAIF_ID_6,
|
||||
ADMAIF_ID_7,
|
||||
ADMAIF_ID_8,
|
||||
ADMAIF_ID_9,
|
||||
ADMAIF_ID_10,
|
||||
TEGRA210_ADMAIF_CHANNEL_COUNT = ADMAIF_ID_10,
|
||||
ADMAIF_ID_11,
|
||||
ADMAIF_ID_12,
|
||||
ADMAIF_ID_13,
|
||||
ADMAIF_ID_14,
|
||||
ADMAIF_ID_15,
|
||||
ADMAIF_ID_16,
|
||||
ADMAIF_ID_17,
|
||||
ADMAIF_ID_18,
|
||||
ADMAIF_ID_19,
|
||||
MAX_ADMAIF_T186_IDS,
|
||||
TEGRA186_ADMAIF_CHANNEL_COUNT = MAX_ADMAIF_T186_IDS,
|
||||
MAX_ADMAIF_IDS = MAX_ADMAIF_T186_IDS,
|
||||
};
|
||||
|
||||
/* Audio cif definition */
|
||||
struct tegra210_virt_audio_cif {
|
||||
unsigned int threshold;
|
||||
unsigned int audio_channels;
|
||||
unsigned int client_channels;
|
||||
unsigned int audio_bits;
|
||||
unsigned int client_bits;
|
||||
unsigned int expand;
|
||||
unsigned int stereo_conv;
|
||||
unsigned int replicate;
|
||||
int32_t direction;
|
||||
unsigned int truncate;
|
||||
unsigned int mono_conv;
|
||||
};
|
||||
|
||||
/* apbif data */
|
||||
struct tegra210_virt_admaif_client_data {
|
||||
struct nvaudio_ivc_ctxt *hivc_client;
|
||||
};
|
||||
|
||||
struct tegra210_admaif {
|
||||
struct tegra_alt_pcm_dma_params *capture_dma_data;
|
||||
struct tegra_alt_pcm_dma_params *playback_dma_data;
|
||||
struct tegra210_virt_admaif_client_data client_data;
|
||||
};
|
||||
|
||||
struct tegra_virt_admaif_soc_data {
|
||||
unsigned int num_ch;
|
||||
};
|
||||
|
||||
int tegra210_virt_admaif_register_component(struct platform_device *pdev,
|
||||
struct tegra_virt_admaif_soc_data *soc_data);
|
||||
void tegra210_virt_admaif_unregister_component(struct platform_device *pdev);
|
||||
|
||||
struct nvaudio_ivc_ctxt *nvaudio_get_saved_ivc_ctxt(void);
|
||||
|
||||
#endif
|
||||
897
sound/soc/tegra-virt-alt/tegra_asoc_machine_virt_alt.c
Normal file
897
sound/soc/tegra-virt-alt/tegra_asoc_machine_virt_alt.c
Normal file
@@ -0,0 +1,897 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/export.h>
|
||||
#include <sound/soc.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <sound/soc.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
|
||||
#include "tegra_asoc_machine_virt_alt.h"
|
||||
|
||||
#define CODEC_NAME NULL
|
||||
|
||||
#define DAI_NAME(i) "AUDIO" #i
|
||||
#define STREAM_NAME "playback"
|
||||
#define LINK_CPU_NAME DRV_NAME
|
||||
#define CPU_DAI_NAME(i) "ADMAIF" #i
|
||||
#define CODEC_DAI_NAME "dit-hifi"
|
||||
#define PLATFORM_NAME LINK_CPU_NAME
|
||||
|
||||
static unsigned int num_dai_links;
|
||||
static const struct snd_soc_pcm_stream default_params = {
|
||||
.rate_min = 48000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
};
|
||||
|
||||
static const struct snd_soc_pcm_stream adsp_default_params = {
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rate_min = 48000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
};
|
||||
|
||||
static struct snd_soc_pcm_stream adsp_admaif_params[MAX_ADMAIF_IDS];
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio1,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(1))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF1 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio2,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(2))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF2 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio3,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(3))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF3 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio4,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(4))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF4 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio5,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(5))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF5 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio6,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(6))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF6 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio7,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(7))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF7 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio8,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(8))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF8 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio9,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(9))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF9 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio10,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(10))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF10 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio11,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(11))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF11 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio12,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(12))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF12 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio13,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(13))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF13 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio14,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(14))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF14 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio15,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(15))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF15 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio16,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(16))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF16 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio17,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(17))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF17 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio18,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(18))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF18 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio19,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(19))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF19 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(audio20,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, CPU_DAI_NAME(20))),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF20 CIF")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM(PLATFORM_NAME)));
|
||||
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif1,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF1 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif2,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF2")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF2 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif3,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF3")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF3 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif4,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF4")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF4 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif5,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF5")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF5 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif6,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF6")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF6 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif7,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF7")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF7 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif8,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF8")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF8 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif9,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF9")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF9 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif10,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF10")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF10 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif11,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF11")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF11 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif12,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF12")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF12 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif13,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF13")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF13 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif14,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF14")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF14 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif15,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF15")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF15 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif16,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF16")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF16 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif17,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF17")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF17 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif18,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF18")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF18 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif19,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF19")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF19 CIF")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_admaif20,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP-ADMAIF20")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(LINK_CPU_NAME, "ADMAIF20 CIF")));
|
||||
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm1,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE1")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm2,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM2")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE2")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm3,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM3")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE3")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm4,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM4")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE4")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm5,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM5")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE5")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm6,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM6")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE6")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm7,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM7")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE7")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm8,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM8")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE8")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm9,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM9")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE9")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm10,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM10")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE10")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm11,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM11")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE11")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm12,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM12")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE12")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm13,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM13")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE13")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm14,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM14")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE14")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(adsp_pcm15,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt","ADSP PCM15")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tegra210-adsp-virt", "ADSP-FE15")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("tegra210-adsp-virt")));
|
||||
|
||||
static struct snd_soc_dai_link tegra_virt_t186ref_pcm_links[] = {
|
||||
{
|
||||
/* 0 */
|
||||
.name = DAI_NAME(1),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio1),
|
||||
},
|
||||
{
|
||||
/* 1 */
|
||||
.name = DAI_NAME(2),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio2),
|
||||
},
|
||||
{
|
||||
/* 2 */
|
||||
.name = DAI_NAME(3),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio3),
|
||||
},
|
||||
{
|
||||
/* 3 */
|
||||
.name = DAI_NAME(4),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio4),
|
||||
},
|
||||
{
|
||||
/* 4 */
|
||||
.name = DAI_NAME(5),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio5),
|
||||
},
|
||||
{
|
||||
/* 5 */
|
||||
.name = DAI_NAME(6),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio6),
|
||||
},
|
||||
{
|
||||
/* 6 */
|
||||
.name = DAI_NAME(7),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio7),
|
||||
},
|
||||
{
|
||||
/* 7 */
|
||||
.name = DAI_NAME(8),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio8),
|
||||
},
|
||||
{
|
||||
/* 8 */
|
||||
.name = DAI_NAME(9),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio9),
|
||||
},
|
||||
{
|
||||
/* 9 */
|
||||
.name = DAI_NAME(10),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio10),
|
||||
},
|
||||
{
|
||||
/* 10 */
|
||||
.name = DAI_NAME(11),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio11),
|
||||
},
|
||||
{
|
||||
/* 11 */
|
||||
.name = DAI_NAME(12),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio12),
|
||||
},
|
||||
{
|
||||
/* 12 */
|
||||
.name = DAI_NAME(13),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio13),
|
||||
},
|
||||
{
|
||||
/* 13 */
|
||||
.name = DAI_NAME(14),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio14),
|
||||
},
|
||||
{
|
||||
/* 14 */
|
||||
.name = DAI_NAME(15),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio15),
|
||||
},
|
||||
{
|
||||
/* 15 */
|
||||
.name = DAI_NAME(16),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio16),
|
||||
},
|
||||
{
|
||||
/* 16 */
|
||||
.name = DAI_NAME(17),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio17),
|
||||
},
|
||||
{
|
||||
/* 17 */
|
||||
.name = DAI_NAME(18),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio18),
|
||||
},
|
||||
{
|
||||
/* 18 */
|
||||
.name = DAI_NAME(19),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio19),
|
||||
},
|
||||
{
|
||||
/* 19 */
|
||||
.name = DAI_NAME(20),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(audio20),
|
||||
},
|
||||
{
|
||||
/* 20 */
|
||||
.name = "ADSP ADMAIF1",
|
||||
.stream_name = "ADSP AFMAIF1",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif1),
|
||||
},
|
||||
{
|
||||
/* 21 */
|
||||
.name = "ADSP ADMAIF2",
|
||||
.stream_name = "ADSP AFMAIF2",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif2),
|
||||
},
|
||||
{
|
||||
/* 22 */
|
||||
.name = "ADSP ADMAIF3",
|
||||
.stream_name = "ADSP AFMAIF3",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif3),
|
||||
},
|
||||
{
|
||||
/* 23 */
|
||||
.name = "ADSP ADMAIF4",
|
||||
.stream_name = "ADSP AFMAIF4",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif4),
|
||||
},
|
||||
{
|
||||
/* 24 */
|
||||
.name = "ADSP ADMAIF5",
|
||||
.stream_name = "ADSP AFMAIF5",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif5),
|
||||
},
|
||||
{
|
||||
/* 25 */
|
||||
.name = "ADSP ADMAIF6",
|
||||
.stream_name = "ADSP AFMAIF6",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif6),
|
||||
},
|
||||
{
|
||||
/* 26 */
|
||||
.name = "ADSP ADMAIF7",
|
||||
.stream_name = "ADSP AFMAIF7",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif7),
|
||||
},
|
||||
{
|
||||
/* 27 */
|
||||
.name = "ADSP ADMAIF8",
|
||||
.stream_name = "ADSP AFMAIF8",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif8),
|
||||
},
|
||||
{
|
||||
/* 28 */
|
||||
.name = "ADSP ADMAIF9",
|
||||
.stream_name = "ADSP AFMAIF9",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif9),
|
||||
},
|
||||
{
|
||||
/* 29 */
|
||||
.name = "ADSP ADMAIF10",
|
||||
.stream_name = "ADSP AFMAIF10",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif10),
|
||||
},
|
||||
{
|
||||
/* 30 */
|
||||
.name = "ADSP ADMAIF11",
|
||||
.stream_name = "ADSP AFMAIF11",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif11),
|
||||
},
|
||||
{
|
||||
/* 31 */
|
||||
.name = "ADSP ADMAIF12",
|
||||
.stream_name = "ADSP AFMAIF12",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif12),
|
||||
},
|
||||
{
|
||||
/* 32 */
|
||||
.name = "ADSP ADMAIF13",
|
||||
.stream_name = "ADSP AFMAIF13",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif13),
|
||||
},
|
||||
{
|
||||
/* 33 */
|
||||
.name = "ADSP ADMAIF14",
|
||||
.stream_name = "ADSP AFMAIF14",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif14),
|
||||
},
|
||||
{
|
||||
/* 34 */
|
||||
.name = "ADSP ADMAIF15",
|
||||
.stream_name = "ADSP AFMAIF15",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif15),
|
||||
},
|
||||
{
|
||||
/* 35 */
|
||||
.name = "ADSP ADMAIF16",
|
||||
.stream_name = "ADSP AFMAIF16",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif16),
|
||||
},
|
||||
{
|
||||
/* 36 */
|
||||
.name = "ADSP ADMAIF17",
|
||||
.stream_name = "ADSP AFMAIF17",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif17),
|
||||
},
|
||||
{
|
||||
/* 37 */
|
||||
.name = "ADSP ADMAIF18",
|
||||
.stream_name = "ADSP AFMAIF18",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif18),
|
||||
},
|
||||
{
|
||||
/* 38 */
|
||||
.name = "ADSP ADMAIF19",
|
||||
.stream_name = "ADSP AFMAIF19",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif19),
|
||||
},
|
||||
{
|
||||
/* 39 */
|
||||
.name = "ADSP ADMAIF20",
|
||||
.stream_name = "ADSP AFMAIF20",
|
||||
.params = &adsp_default_params,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(adsp_admaif20),
|
||||
},
|
||||
{
|
||||
/* 40 */
|
||||
.name = "ADSP PCM1",
|
||||
.stream_name = "ADSP PCM1",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm1),
|
||||
},
|
||||
{
|
||||
/* 41 */
|
||||
.name = "ADSP PCM2",
|
||||
.stream_name = "ADSP PCM2",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm2),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM3",
|
||||
.stream_name = "ADSP PCM3",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm3),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM4",
|
||||
.stream_name = "ADSP PCM4",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm4),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM5",
|
||||
.stream_name = "ADSP PCM5",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm5),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM6",
|
||||
.stream_name = "ADSP PCM6",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm6),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM7",
|
||||
.stream_name = "ADSP PCM7",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm7),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM8",
|
||||
.stream_name = "ADSP PCM8",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm8),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM9",
|
||||
.stream_name = "ADSP PCM9",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm9),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM10",
|
||||
.stream_name = "ADSP PCM10",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm10),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM11",
|
||||
.stream_name = "ADSP PCM11",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm11),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM12",
|
||||
.stream_name = "ADSP PCM12",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm12),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM13",
|
||||
.stream_name = "ADSP PCM13",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm13),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM14",
|
||||
.stream_name = "ADSP PCM14",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm14),
|
||||
},
|
||||
{
|
||||
.name = "ADSP PCM15",
|
||||
.stream_name = "ADSP PCM15",
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 0,
|
||||
SND_SOC_DAILINK_REG(adsp_pcm15),
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_link tegra_virt_t210ref_pcm_links[] = {
|
||||
{
|
||||
/* 0 */
|
||||
.name = DAI_NAME(1),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio1),
|
||||
},
|
||||
{
|
||||
/* 1 */
|
||||
.name = DAI_NAME(2),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio2),
|
||||
},
|
||||
{
|
||||
/* 2 */
|
||||
.name = DAI_NAME(3),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio3),
|
||||
},
|
||||
{
|
||||
/* 3 */
|
||||
.name = DAI_NAME(4),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio4),
|
||||
},
|
||||
{
|
||||
/* 4 */
|
||||
.name = DAI_NAME(5),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio5),
|
||||
},
|
||||
{
|
||||
/* 5 */
|
||||
.name = DAI_NAME(6),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio6),
|
||||
},
|
||||
{
|
||||
/* 6 */
|
||||
.name = DAI_NAME(7),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio7),
|
||||
},
|
||||
{
|
||||
/* 7 */
|
||||
.name = DAI_NAME(8),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio8),
|
||||
},
|
||||
{
|
||||
/* 8 */
|
||||
.name = DAI_NAME(9),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio9),
|
||||
},
|
||||
{
|
||||
/* 9 */
|
||||
.name = DAI_NAME(10),
|
||||
.stream_name = STREAM_NAME,
|
||||
.params = &default_params,
|
||||
.ignore_pmdown_time = 1,
|
||||
.ignore_suspend = 1,
|
||||
SND_SOC_DAILINK_REG(audio10),
|
||||
},
|
||||
};
|
||||
|
||||
void tegra_virt_machine_set_num_dai_links(unsigned int val)
|
||||
{
|
||||
num_dai_links = val;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_virt_machine_set_num_dai_links);
|
||||
|
||||
unsigned int tegra_virt_machine_get_num_dai_links(void)
|
||||
{
|
||||
return num_dai_links;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_virt_machine_get_num_dai_links);
|
||||
|
||||
struct snd_soc_dai_link *tegra_virt_machine_get_dai_link(void)
|
||||
{
|
||||
struct snd_soc_dai_link *link = tegra_virt_t186ref_pcm_links;
|
||||
unsigned int size = TEGRA186_XBAR_DAI_LINKS;
|
||||
|
||||
if (of_machine_is_compatible("nvidia,tegra210")) {
|
||||
link = tegra_virt_t210ref_pcm_links;
|
||||
size = TEGRA210_XBAR_DAI_LINKS;
|
||||
}
|
||||
|
||||
tegra_virt_machine_set_num_dai_links(size);
|
||||
return link;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_virt_machine_get_dai_link);
|
||||
|
||||
void tegra_virt_machine_set_adsp_admaif_dai_params(
|
||||
uint32_t id, struct snd_soc_pcm_stream *params)
|
||||
{
|
||||
struct snd_soc_dai_link *link = tegra_virt_t186ref_pcm_links;
|
||||
|
||||
/* Check for valid ADSP ADMAIF ID */
|
||||
if (id >= MAX_ADMAIF_IDS) {
|
||||
pr_err("Invalid ADSP ADMAIF ID: %d\n", id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find DAI link corresponding to ADSP ADMAIF */
|
||||
link += id + MAX_ADMAIF_IDS;
|
||||
|
||||
memcpy(&adsp_admaif_params[id], params,
|
||||
sizeof(struct snd_soc_pcm_stream));
|
||||
|
||||
link->params = &adsp_admaif_params[id];
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_virt_machine_set_adsp_admaif_dai_params);
|
||||
|
||||
MODULE_AUTHOR("Dipesh Gandhi <dipeshg@nvidia.com>");
|
||||
MODULE_DESCRIPTION("Tegra Virt ASoC machine code");
|
||||
MODULE_LICENSE("GPL");
|
||||
89
sound/soc/tegra-virt-alt/tegra_asoc_machine_virt_alt.h
Normal file
89
sound/soc/tegra-virt-alt/tegra_asoc_machine_virt_alt.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_ASOC_MACHINE_VIRT_ALT_H__
|
||||
#define __TEGRA_ASOC_MACHINE_VIRT_ALT_H__
|
||||
|
||||
#include "tegra210_virt_alt_admaif.h"
|
||||
|
||||
enum tegra210_xbar_dai_link {
|
||||
TEGRA210_DAI_LINK_ADMAIF1,
|
||||
TEGRA210_DAI_LINK_ADMAIF2,
|
||||
TEGRA210_DAI_LINK_ADMAIF3,
|
||||
TEGRA210_DAI_LINK_ADMAIF4,
|
||||
TEGRA210_DAI_LINK_ADMAIF5,
|
||||
TEGRA210_DAI_LINK_ADMAIF6,
|
||||
TEGRA210_DAI_LINK_ADMAIF7,
|
||||
TEGRA210_DAI_LINK_ADMAIF8,
|
||||
TEGRA210_DAI_LINK_ADMAIF9,
|
||||
TEGRA210_DAI_LINK_ADMAIF10,
|
||||
TEGRA210_XBAR_DAI_LINKS, /* Total number of xbar dai links */
|
||||
};
|
||||
|
||||
enum tegra186_xbar_dai_link {
|
||||
TEGRA186_DAI_LINK_ADMAIF1,
|
||||
TEGRA186_DAI_LINK_ADMAIF2,
|
||||
TEGRA186_DAI_LINK_ADMAIF3,
|
||||
TEGRA186_DAI_LINK_ADMAIF4,
|
||||
TEGRA186_DAI_LINK_ADMAIF5,
|
||||
TEGRA186_DAI_LINK_ADMAIF6,
|
||||
TEGRA186_DAI_LINK_ADMAIF7,
|
||||
TEGRA186_DAI_LINK_ADMAIF8,
|
||||
TEGRA186_DAI_LINK_ADMAIF9,
|
||||
TEGRA186_DAI_LINK_ADMAIF10,
|
||||
TEGRA186_DAI_LINK_ADMAIF11,
|
||||
TEGRA186_DAI_LINK_ADMAIF12,
|
||||
TEGRA186_DAI_LINK_ADMAIF13,
|
||||
TEGRA186_DAI_LINK_ADMAIF14,
|
||||
TEGRA186_DAI_LINK_ADMAIF15,
|
||||
TEGRA186_DAI_LINK_ADMAIF16,
|
||||
TEGRA186_DAI_LINK_ADMAIF17,
|
||||
TEGRA186_DAI_LINK_ADMAIF18,
|
||||
TEGRA186_DAI_LINK_ADMAIF19,
|
||||
TEGRA186_DAI_LINK_ADMAIF20,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF1,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF2,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF3,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF4,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF5,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF6,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF7,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF8,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF9,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF10,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF11,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF12,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF13,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF14,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF15,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF16,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF17,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF18,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF19,
|
||||
TEGRA186_DAI_LINK_ADSP_ADMAIF20,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM1,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM2,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM3,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM4,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM5,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM6,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM7,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM8,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM9,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM10,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM11,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM12,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM13,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM14,
|
||||
TEGRA186_DAI_LINK_ADSP_PCM15,
|
||||
TEGRA186_XBAR_DAI_LINKS, /* Total number of xbar dai links */
|
||||
};
|
||||
|
||||
struct snd_soc_dai_link *tegra_virt_machine_get_dai_link(void);
|
||||
unsigned int tegra_virt_machine_get_num_dai_links(void);
|
||||
void tegra_virt_machine_set_num_dai_links(unsigned int val);
|
||||
void tegra_virt_machine_set_adsp_admaif_dai_params(
|
||||
uint32_t id, struct snd_soc_pcm_stream *params);
|
||||
#endif
|
||||
1626
sound/soc/tegra-virt-alt/tegra_asoc_util_virt_alt.c
Normal file
1626
sound/soc/tegra-virt-alt/tegra_asoc_util_virt_alt.c
Normal file
File diff suppressed because it is too large
Load Diff
418
sound/soc/tegra-virt-alt/tegra_asoc_util_virt_alt.h
Normal file
418
sound/soc/tegra-virt-alt/tegra_asoc_util_virt_alt.h
Normal file
@@ -0,0 +1,418 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_VIRT_UTIL_H
|
||||
#define __LINUX_VIRT_UTIL_H
|
||||
|
||||
#include <sound/soc.h>
|
||||
|
||||
#define MIXER_CONFIG_SHIFT_VALUE 16
|
||||
#define STREAM_ID_SHIFT_VALUE 16
|
||||
#define REGDUMP_CMD_SHIFT_VALUE 24
|
||||
#define MIXER_MAX_RX_GAIN 0x7FFFFFFF
|
||||
#define TEGRA186_ASRC_STREAM_RATIO_INTEGER_PART_MASK 0x1F
|
||||
#define TEGRA186_ASRC_STREAM_RATIO_FRAC_PART_MASK 0xFFFFFFFF
|
||||
#define TEGRA186_ASRC_STREAM_RATIO_MASK 0x1FFFFFFFFF
|
||||
#define NUM_ARAD_SOURCES 11
|
||||
#define NUM_ARAD_LANES 6
|
||||
#define NUM_ASRC_MODE 2
|
||||
#define NUM_MVC_CURVETYPE 2
|
||||
#define MAX_MVC_TAR_VOL 16000
|
||||
|
||||
#define MIXER_GAIN_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, MIXER_MAX_RX_GAIN, 0, \
|
||||
tegra_virt_t210mixer_get_gain, \
|
||||
tegra_virt_t210mixer_set_gain)
|
||||
|
||||
#define MIXER_GAIN_INSTANT_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, MIXER_MAX_RX_GAIN, 0, \
|
||||
tegra_virt_t210mixer_get_gain, \
|
||||
tegra_virt_t210mixer_set_gain_instant)
|
||||
|
||||
#define MIXER_DURATION_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
64, 0x7FFFFFFF, 0, \
|
||||
tegra_virt_t210mixer_get_duration, \
|
||||
tegra_virt_t210mixer_set_duration)
|
||||
|
||||
#define REG_PACK(id1, id2) ((id1 << MIXER_CONFIG_SHIFT_VALUE) | id2)
|
||||
#define MIXER_ADDER_CTRL_DECL(ename, reg1, reg2) \
|
||||
SOC_SINGLE_EXT(ename, REG_PACK(reg1, reg2), \
|
||||
0, 1, 0, \
|
||||
tegra_virt_t210mixer_get_adder_config, \
|
||||
tegra_virt_t210mixer_set_adder_config)
|
||||
|
||||
#define MIXER_ENABLE_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 1, 0, \
|
||||
tegra_virt_t210mixer_get_enable, \
|
||||
tegra_virt_t210mixer_set_enable)
|
||||
|
||||
#define SFC_IN_FREQ_CTRL_DECL(ename, id) \
|
||||
SOC_SINGLE_EXT(ename, id, \
|
||||
0, 192000, 0, \
|
||||
tegra_virt_t210sfc_get_in_freq, \
|
||||
tegra_virt_t210sfc_set_in_freq)
|
||||
|
||||
#define SFC_OUT_FREQ_CTRL_DECL(ename, id) \
|
||||
SOC_SINGLE_EXT(ename, id, \
|
||||
0, 192000, 0, \
|
||||
tegra_virt_t210sfc_get_out_freq, \
|
||||
tegra_virt_t210sfc_set_out_freq)
|
||||
|
||||
#define MVC_CURVE_TYPE_CTRL_DECL(ename, reg, src) \
|
||||
SOC_ENUM_EXT_REG(ename, reg, \
|
||||
src, \
|
||||
tegra_virt_t210mvc_get_curve_type, \
|
||||
tegra_virt_t210mvc_set_curve_type)
|
||||
|
||||
#define MVC_TAR_VOL_CTRL_DECL(ename, id) \
|
||||
SOC_SINGLE_EXT(ename, id, \
|
||||
0, MAX_MVC_TAR_VOL, 0, \
|
||||
tegra_virt_t210mvc_get_tar_vol, \
|
||||
tegra_virt_t210mvc_set_tar_vol)
|
||||
|
||||
#define MVC_MUTE_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 1, 0, \
|
||||
tegra_virt_t210mvc_get_mute, \
|
||||
tegra_virt_t210mvc_set_mute)
|
||||
|
||||
#define SOC_SINGLE_EXT_FRAC(xname, xregbase, xmax, xget, xput) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.info = snd_soc_info_xr_sx, .get = xget, \
|
||||
.put = xput, \
|
||||
.private_value = (unsigned long)&(struct soc_mreg_control) \
|
||||
{.regbase = xregbase, .regcount = 1, .nbits = 32, \
|
||||
.invert = 0, .min = 0, .max = xmax} }
|
||||
|
||||
#define ASRC_RATIO_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT_FRAC(ename, reg, \
|
||||
TEGRA186_ASRC_STREAM_RATIO_MASK, \
|
||||
tegra186_virt_asrc_get_ratio, \
|
||||
tegra186_virt_asrc_set_ratio)
|
||||
|
||||
#define ASRC_STREAM_RATIO_CTRL_DECL(ename, reg, src) \
|
||||
SOC_ENUM_EXT_REG(ename, reg, \
|
||||
src, \
|
||||
tegra186_virt_asrc_get_ratio_source, \
|
||||
tegra186_virt_asrc_set_ratio_source)
|
||||
|
||||
#define ASRC_STREAM_ENABLE_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 1, 0, \
|
||||
tegra186_virt_asrc_get_stream_enable, \
|
||||
tegra186_virt_asrc_set_stream_enable)
|
||||
|
||||
#define ASRC_STREAM_HWCOMP_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 1, 0, \
|
||||
tegra186_virt_asrc_get_hwcomp_disable, \
|
||||
tegra186_virt_asrc_set_hwcomp_disable)
|
||||
|
||||
#define ASRC_STREAM_INPUT_THRESHOLD_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 3, 0, \
|
||||
tegra186_virt_asrc_get_input_threshold, \
|
||||
tegra186_virt_asrc_set_input_threshold)
|
||||
|
||||
#define ASRC_STREAM_OUTPUT_THRESHOLD_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 3, 0, \
|
||||
tegra186_virt_asrc_get_output_threshold, \
|
||||
tegra186_virt_asrc_set_output_threshold)
|
||||
|
||||
#define AMX_ENABLE_CTRL_DECL(ename, reg1, reg2) \
|
||||
SOC_SINGLE_EXT(ename, REG_PACK(reg1, reg2), \
|
||||
0, 1, 0, \
|
||||
tegra_virt_t210_amx_get_input_stream_enable, \
|
||||
tegra_virt_t210_amx_set_input_stream_enable)
|
||||
|
||||
#define ARAD_LANE_SOURCE_CTRL_DECL(ename, reg, src) \
|
||||
SOC_ENUM_EXT_REG(ename, reg, \
|
||||
src, \
|
||||
tegra186_virt_arad_get_lane_source, \
|
||||
tegra186_virt_arad_set_lane_source)
|
||||
|
||||
#define ARAD_LANE_PRESCALAR_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 65535, 0, \
|
||||
tegra186_virt_arad_get_lane_prescalar, \
|
||||
tegra186_virt_arad_set_lane_prescalar)
|
||||
|
||||
#define ARAD_LANE_ENABLE_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 1, 0, \
|
||||
tegra186_virt_arad_get_lane_enable, \
|
||||
tegra186_virt_arad_set_lane_enable)
|
||||
|
||||
#define ARAD_LANE_RATIO_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 0xFFFFFFFF, 0, \
|
||||
tegra186_virt_arad_get_lane_ratio, NULL)
|
||||
|
||||
#define I2S_LOOPBACK_ENABLE_CTRL_DECL(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 1, 0, \
|
||||
tegra_virt_i2s_get_loopback_enable, \
|
||||
tegra_virt_i2s_set_loopback_enable)
|
||||
|
||||
#define I2S_SET_RATE(ename, reg) \
|
||||
SOC_SINGLE_EXT(ename, reg, \
|
||||
0, 96000, 0, \
|
||||
tegra_virt_i2s_get_rate, \
|
||||
tegra_virt_i2s_set_rate)
|
||||
|
||||
#define MIXER_SET_FADE(xname, xbase) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.info = tegra_virt_t210mixer_param_info, \
|
||||
.name = xname, \
|
||||
.put = tegra_virt_t210mixer_set_fade, \
|
||||
.get = tegra_virt_t210mixer_get_fade, \
|
||||
.private_value = \
|
||||
((unsigned long)&(struct soc_bytes) \
|
||||
{.base = xbase, .num_regs = 128, \
|
||||
.mask = SNDRV_CTL_ELEM_TYPE_INTEGER}) }
|
||||
|
||||
#define MIXER_GET_FADE_STATUS(xname, xbase) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.info = tegra_virt_t210mixer_param_info, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ, \
|
||||
.name = xname, \
|
||||
.get = tegra_virt_t210mixer_get_fade_status, \
|
||||
.private_value = \
|
||||
((unsigned long)&(struct soc_bytes) \
|
||||
{.base = xbase, .num_regs = 128, \
|
||||
.mask = SNDRV_CTL_ELEM_TYPE_INTEGER}) }
|
||||
|
||||
#define REGDUMP_PACK(id1, id2, id3) \
|
||||
(id1 | (id2 << STREAM_ID_SHIFT_VALUE) | (id3 << REGDUMP_CMD_SHIFT_VALUE))
|
||||
#define REGDUMP_CTRL_DECL(ename, id, stream_id, cmd) \
|
||||
SOC_SINGLE_EXT(ename, REGDUMP_PACK(id, stream_id, cmd), \
|
||||
0, 1, 0, \
|
||||
tegra_virt_t210ahub_get_regdump, \
|
||||
tegra_virt_t210ahub_set_regdump)
|
||||
|
||||
#define ADMA_REGDUMP_CTRL_DECL(ename, channel_id) \
|
||||
SOC_SINGLE_EXT(ename, channel_id, \
|
||||
0, 1, 0, \
|
||||
tegra_virt_t210adma_get_regdump, \
|
||||
tegra_virt_t210adma_set_regdump)
|
||||
|
||||
#define ADDER_CTRL_DECL(name, id) \
|
||||
static const struct snd_kcontrol_new name[] = { \
|
||||
MIXER_ADDER_CTRL_DECL("RX1", id, 0x01), \
|
||||
MIXER_ADDER_CTRL_DECL("RX2", id, 0x02), \
|
||||
MIXER_ADDER_CTRL_DECL("RX3", id, 0x03), \
|
||||
MIXER_ADDER_CTRL_DECL("RX4", id, 0x04), \
|
||||
MIXER_ADDER_CTRL_DECL("RX5", id, 0x05), \
|
||||
MIXER_ADDER_CTRL_DECL("RX6", id, 0x06), \
|
||||
MIXER_ADDER_CTRL_DECL("RX7", id, 0x07), \
|
||||
MIXER_ADDER_CTRL_DECL("RX8", id, 0x08), \
|
||||
MIXER_ADDER_CTRL_DECL("RX9", id, 0x09), \
|
||||
MIXER_ADDER_CTRL_DECL("RX10", id, 0x0a), \
|
||||
}
|
||||
|
||||
enum {
|
||||
numerator1_enum = 0,
|
||||
numerator2_enum,
|
||||
numerator3_enum,
|
||||
numerator4_enum,
|
||||
numerator5_enum,
|
||||
numerator6_enum,
|
||||
denominator1_enum = NUM_ARAD_LANES,
|
||||
denominator2_enum,
|
||||
denominator3_enum,
|
||||
denominator4_enum,
|
||||
denominator5_enum,
|
||||
denominator6_enum,
|
||||
};
|
||||
|
||||
extern const int tegra186_arad_mux_value[];
|
||||
extern const char * const tegra186_arad_mux_text[];
|
||||
extern const char * const tegra186_asrc_ratio_source_text[];
|
||||
extern const char * const tegra210_mvc_curve_type_text[];
|
||||
|
||||
static inline int tegra_register_component(struct device *dev,
|
||||
const struct snd_soc_component_driver *component_driver,
|
||||
struct snd_soc_dai_driver *dai_drv,
|
||||
int num_dai, const char *debugfs_prefix)
|
||||
{
|
||||
struct snd_soc_component *component;
|
||||
int ret;
|
||||
|
||||
component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL);
|
||||
if (!component)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = snd_soc_component_initialize(component, component_driver, dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
component->debugfs_prefix = debugfs_prefix;
|
||||
#endif
|
||||
|
||||
return snd_soc_add_component(component, dai_drv, num_dai);
|
||||
}
|
||||
|
||||
int tegra_virt_t210mixer_get_gain(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mixer_set_gain(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mixer_set_gain_instant(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210mixer_get_duration(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mixer_set_duration(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210mixer_get_adder_config(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210mixer_set_adder_config(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210mixer_get_enable(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210mixer_set_enable(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210sfc_get_in_freq(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210sfc_set_in_freq(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210sfc_get_out_freq(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210sfc_set_out_freq(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210mvc_get_curve_type(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mvc_set_curve_type(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210mvc_get_tar_vol(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mvc_set_tar_vol(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210mvc_get_mute(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mvc_set_mute(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_asrc_get_ratio(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_asrc_set_ratio(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_asrc_get_ratio_source(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra186_virt_asrc_set_ratio_source(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra186_virt_asrc_get_stream_enable(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_asrc_set_stream_enable(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_asrc_get_hwcomp_disable(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_asrc_set_hwcomp_disable(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra186_virt_asrc_get_input_threshold(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_asrc_set_input_threshold(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_asrc_get_output_threshold(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra186_virt_asrc_set_output_threshold(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210_amx_get_input_stream_enable(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210_amx_set_input_stream_enable(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
|
||||
int tegra186_virt_arad_get_lane_source(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra186_virt_arad_set_lane_source(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_arad_get_lane_prescalar(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_arad_set_lane_prescalar(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_arad_get_lane_enable(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_arad_set_lane_enable(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra186_virt_arad_get_lane_ratio(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_i2s_set_loopback_enable(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_i2s_get_loopback_enable(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_i2s_set_rate(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_i2s_get_rate(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
//Mixer fade
|
||||
int tegra_virt_t210mixer_get_fade_status(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mixer_set_fade(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mixer_get_fade(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210mixer_param_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int tegra_virt_t210ahub_get_regdump(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210ahub_set_regdump(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int tegra_virt_t210adma_set_regdump(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_t210adma_get_regdump(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
#endif
|
||||
1127
sound/soc/tegra-virt-alt/tegra_asoc_xbar_virt_alt.c
Normal file
1127
sound/soc/tegra-virt-alt/tegra_asoc_xbar_virt_alt.c
Normal file
File diff suppressed because it is too large
Load Diff
82
sound/soc/tegra-virt-alt/tegra_asoc_xbar_virt_alt.h
Normal file
82
sound/soc/tegra-virt-alt/tegra_asoc_xbar_virt_alt.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEGRA_VIRT_ALT_XBAR_H__
|
||||
#define __TEGRA_VIRT_ALT_XBAR_H__
|
||||
|
||||
#include <sound/soc.h>
|
||||
|
||||
#define TEGRA_XBAR_RX_STRIDE 0x4
|
||||
#define TEGRA_T186_SRC_NUM_MUX 83
|
||||
#define TEGRA_T210_SRC_NUM_MUX 55
|
||||
|
||||
#define MUX_REG(id) (TEGRA_XBAR_RX_STRIDE * (id))
|
||||
#define SOC_ENUM_EXT_REG(xname, xcount, xenum, xhandler_get, xhandler_put) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_info_enum_double, \
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = (unsigned long)xenum, \
|
||||
.tlv.p = (unsigned int *) xcount, \
|
||||
}
|
||||
|
||||
#define SOC_VALUE_ENUM_WIDE(xreg, shift, xmax, xtexts, xvalues) \
|
||||
{ .reg = xreg, .shift_l = shift, .shift_r = shift, \
|
||||
.items = xmax, .texts = xtexts, .values = xvalues, \
|
||||
.mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0}
|
||||
|
||||
#define SOC_VALUE_ENUM_WIDE_DECL(name, xreg, shift, \
|
||||
xtexts, xvalues) \
|
||||
static struct soc_enum name = SOC_VALUE_ENUM_WIDE(xreg, shift, \
|
||||
ARRAY_SIZE(xtexts), xtexts, xvalues)
|
||||
|
||||
#define MUX_ENUM_CTRL_DECL_186(ename, id) \
|
||||
SOC_VALUE_ENUM_WIDE_DECL(ename##_enum, MUX_REG(id), 0, \
|
||||
tegra_virt_t186ref_source_text, \
|
||||
tegra_virt_t186ref_source_value); \
|
||||
static const struct snd_kcontrol_new ename##_control = \
|
||||
SOC_DAPM_ENUM_EXT("Route", ename##_enum,\
|
||||
tegra_virt_get_route,\
|
||||
tegra_virt_put_route)
|
||||
|
||||
#define MUX_VALUE(npart, nbit) (1 + nbit + npart * 32)
|
||||
|
||||
#define WIDGETS(sname, ename) \
|
||||
SND_SOC_DAPM_AIF_IN(sname " RX", NULL, 0, SND_SOC_NOPM, 0, 0), \
|
||||
SND_SOC_DAPM_MUX(sname " Mux", SND_SOC_NOPM, 0, 0, &ename##_control)
|
||||
|
||||
#define TX_WIDGETS(sname) \
|
||||
SND_SOC_DAPM_AIF_IN(sname " RX", NULL, 0, SND_SOC_NOPM, 0, 0)
|
||||
|
||||
#define MIXER_IN_WIDGETS(sname, ename) \
|
||||
SND_SOC_DAPM_MUX(sname " Mux", SND_SOC_NOPM, 0, 0, &ename##_control)
|
||||
|
||||
#define MIXER_OUT_WIDGETS(sname) \
|
||||
SND_SOC_DAPM_AIF_IN(sname " RX", NULL, 0, SND_SOC_NOPM, 0, 0)
|
||||
|
||||
#define SND_SOC_DAPM_OUT(wname) \
|
||||
{.id = snd_soc_dapm_spk, .name = wname, .kcontrol_news = NULL, \
|
||||
.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = NULL,}
|
||||
|
||||
#define SND_SOC_DAPM_IN(wname) \
|
||||
{.id = snd_soc_dapm_mic, .name = wname, .kcontrol_news = NULL, \
|
||||
.num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = NULL,}
|
||||
|
||||
#define CODEC_WIDGET(sname) \
|
||||
SND_SOC_DAPM_IN(sname " MIC"), \
|
||||
SND_SOC_DAPM_OUT(sname " HEADPHONE")
|
||||
|
||||
|
||||
extern const int tegra_virt_t210ref_source_value[];
|
||||
extern const char * const tegra_virt_t210ref_source_text[];
|
||||
extern const int tegra_virt_t186ref_source_value[];
|
||||
extern const char * const tegra_virt_t186ref_source_text[];
|
||||
|
||||
int tegra_virt_get_route(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int tegra_virt_put_route(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
void tegra_virt_set_enum_source(const struct soc_enum *enum_virt);
|
||||
int tegra_virt_xbar_register_codec(struct platform_device *pdev);
|
||||
#endif
|
||||
339
sound/soc/tegra-virt-alt/tegra_pcm_virt_alt.c
Normal file
339
sound/soc/tegra-virt-alt/tegra_pcm_virt_alt.c
Normal file
@@ -0,0 +1,339 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "tegra_pcm_alt.h"
|
||||
#include "tegra_asoc_util_virt_alt.h"
|
||||
|
||||
static const struct snd_pcm_hardware tegra_alt_pcm_hardware = {
|
||||
.info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_INTERLEAVED,
|
||||
.formats = SNDRV_PCM_FMTBIT_S8 |
|
||||
SNDRV_PCM_FMTBIT_S16_LE |
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
.period_bytes_min = 128,
|
||||
.period_bytes_max = PAGE_SIZE * 4,
|
||||
.periods_min = 1,
|
||||
.periods_max = 8,
|
||||
.buffer_bytes_max = PAGE_SIZE * 8,
|
||||
.fifo_size = 4,
|
||||
};
|
||||
|
||||
static int tegra_alt_pcm_open(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct tegra_alt_pcm_dma_params *dmap;
|
||||
struct dma_chan *chan;
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int ret;
|
||||
|
||||
if (rtd->dai_link->no_pcm)
|
||||
return 0;
|
||||
|
||||
dmap = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
|
||||
|
||||
/* Set HW params now that initialization is complete */
|
||||
snd_soc_set_runtime_hwparams(substream, &tegra_alt_pcm_hardware);
|
||||
|
||||
/* Update buffer size from device tree */
|
||||
if (dmap->buffer_size > substream->runtime->hw.buffer_bytes_max) {
|
||||
substream->runtime->hw.buffer_bytes_max = dmap->buffer_size;
|
||||
substream->runtime->hw.period_bytes_max = dmap->buffer_size / 2;
|
||||
}
|
||||
|
||||
/* Ensure period size is multiple of 8 */
|
||||
ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 0x8);
|
||||
if (ret) {
|
||||
dev_err(cpu_dai->dev, "failed to set constraint %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
chan = dma_request_slave_channel(cpu_dai->dev, dmap->chan_name);
|
||||
if (!chan) {
|
||||
dev_err(cpu_dai->dev,
|
||||
"dmaengine request slave channel failed! (%s)\n",
|
||||
dmap->chan_name);
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = snd_dmaengine_pcm_open(substream, chan);
|
||||
|
||||
if (ret) {
|
||||
dev_err(cpu_dai->dev, "dmaengine pcm open failed with err %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_alt_pcm_close(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
|
||||
if (rtd->dai_link->no_pcm)
|
||||
return 0;
|
||||
|
||||
snd_dmaengine_pcm_close_release_chan(substream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_alt_pcm_hw_params(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct device *dev = rtd->dev;
|
||||
struct dma_chan *chan;
|
||||
struct tegra_alt_pcm_dma_params *dmap;
|
||||
struct dma_slave_config slave_config;
|
||||
int ret;
|
||||
|
||||
if (rtd->dai_link->no_pcm)
|
||||
return 0;
|
||||
|
||||
dmap = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
|
||||
if (!dmap)
|
||||
return 0;
|
||||
|
||||
chan = snd_dmaengine_pcm_get_chan(substream);
|
||||
|
||||
ret = snd_hwparams_to_dma_slave_config(substream, params,
|
||||
&slave_config);
|
||||
if (ret) {
|
||||
dev_err(dev, "hw params config failed with err %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
slave_config.dst_addr = dmap->addr;
|
||||
slave_config.dst_maxburst = 8;
|
||||
} else {
|
||||
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
slave_config.src_addr = dmap->addr;
|
||||
slave_config.src_maxburst = 8;
|
||||
}
|
||||
|
||||
ret = dmaengine_slave_config(chan, &slave_config);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "dma slave config failed with err %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_alt_pcm_hw_free(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
|
||||
if (rtd->dai_link->no_pcm)
|
||||
return 0;
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_alt_pcm_mmap(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
|
||||
if (rtd->dai_link->no_pcm)
|
||||
return 0;
|
||||
|
||||
return dma_mmap_wc(substream->pcm->card->dev, vma,
|
||||
runtime->dma_area,
|
||||
runtime->dma_addr,
|
||||
runtime->dma_bytes);
|
||||
}
|
||||
|
||||
static snd_pcm_uframes_t tegra_alt_pcm_pointer
|
||||
(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
|
||||
snd_pcm_uframes_t appl_offset, pos = 0;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
char *appl_ptr;
|
||||
|
||||
pos = snd_dmaengine_pcm_pointer(substream);
|
||||
|
||||
/* In DRAINING state pointer callback comes from dma completion, here
|
||||
* we want to make sure if if dma completion callback is late we should
|
||||
* not endup playing stale data.
|
||||
*/
|
||||
if ((runtime->status->state == SNDRV_PCM_STATE_DRAINING) &&
|
||||
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
|
||||
appl_offset = runtime->control->appl_ptr %
|
||||
runtime->buffer_size;
|
||||
appl_ptr = runtime->dma_area + frames_to_bytes(runtime,
|
||||
appl_offset);
|
||||
if (pos < appl_offset) {
|
||||
memset(appl_ptr, 0, frames_to_bytes(runtime,
|
||||
runtime->buffer_size - appl_offset));
|
||||
memset(runtime->dma_area, 0, frames_to_bytes(runtime,
|
||||
pos));
|
||||
} else
|
||||
memset(appl_ptr, 0, frames_to_bytes(runtime,
|
||||
pos - appl_offset));
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static int tegra_alt_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
|
||||
unsigned int stream, size_t size)
|
||||
{
|
||||
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
|
||||
struct snd_dma_buffer *buf = &substream->dma_buffer;
|
||||
buf->area = dma_alloc_coherent(pcm->card->dev, size,
|
||||
&buf->addr, GFP_KERNEL);
|
||||
if (!buf->area)
|
||||
return -ENOMEM;
|
||||
buf->private_data = NULL;
|
||||
buf->dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
buf->dev.dev = pcm->card->dev;
|
||||
buf->bytes = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tegra_alt_pcm_deallocate_dma_buffer(struct snd_pcm *pcm, unsigned int stream)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_dma_buffer *buf;
|
||||
|
||||
substream = pcm->streams[stream].substream;
|
||||
if (!substream)
|
||||
return;
|
||||
|
||||
buf = &substream->dma_buffer;
|
||||
if (!buf->area)
|
||||
return;
|
||||
|
||||
dma_free_coherent(pcm->card->dev, buf->bytes,
|
||||
buf->area, buf->addr);
|
||||
buf->area = NULL;
|
||||
}
|
||||
|
||||
static int tegra_alt_pcm_dma_allocate(struct snd_soc_pcm_runtime *rtd,
|
||||
size_t size)
|
||||
{
|
||||
struct snd_card *card = rtd->card->snd_card;
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
struct tegra_alt_pcm_dma_params *dmap;
|
||||
size_t buffer_size = size;
|
||||
int ret;
|
||||
|
||||
ret = dma_set_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dmap = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0),
|
||||
pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
|
||||
if (dmap->buffer_size > size)
|
||||
buffer_size = dmap->buffer_size;
|
||||
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
|
||||
ret = tegra_alt_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK,
|
||||
buffer_size);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
dmap = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0),
|
||||
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
|
||||
if (dmap->buffer_size > size)
|
||||
buffer_size = dmap->buffer_size;
|
||||
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
|
||||
ret = tegra_alt_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_CAPTURE,
|
||||
buffer_size);
|
||||
if (ret)
|
||||
goto err_free_play;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_play:
|
||||
tegra_alt_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tegra_alt_pcm_new(struct snd_soc_component *c,
|
||||
struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
return tegra_alt_pcm_dma_allocate(rtd,
|
||||
tegra_alt_pcm_hardware.buffer_bytes_max);
|
||||
}
|
||||
|
||||
static void tegra_alt_pcm_free(struct snd_soc_component *c,
|
||||
struct snd_pcm *pcm)
|
||||
{
|
||||
tegra_alt_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE);
|
||||
tegra_alt_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
}
|
||||
|
||||
static int tegra_alt_pcm_ioctl(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream, unsigned int cmd, void *arg)
|
||||
{
|
||||
return snd_pcm_lib_ioctl(substream, cmd, arg);
|
||||
}
|
||||
|
||||
|
||||
static int tegra_alt_pcm_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
|
||||
dapm->idle_bias_off = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_component_driver tegra_alt_pcm_platform = {
|
||||
.open = tegra_alt_pcm_open,
|
||||
.close = tegra_alt_pcm_close,
|
||||
.ioctl = tegra_alt_pcm_ioctl,
|
||||
.hw_params = tegra_alt_pcm_hw_params,
|
||||
.hw_free = tegra_alt_pcm_hw_free,
|
||||
.pointer = tegra_alt_pcm_pointer,
|
||||
.mmap = tegra_alt_pcm_mmap,
|
||||
.pcm_construct = tegra_alt_pcm_new,
|
||||
.pcm_destruct = tegra_alt_pcm_free,
|
||||
.probe = tegra_alt_pcm_probe,
|
||||
};
|
||||
|
||||
int tegra_alt_pcm_platform_register(struct device *dev)
|
||||
{
|
||||
return tegra_register_component(dev, &tegra_alt_pcm_platform, NULL, 0, "pcm");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra_alt_pcm_platform_register);
|
||||
|
||||
void tegra_alt_pcm_platform_unregister(struct device *dev)
|
||||
{
|
||||
snd_soc_unregister_component(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tegra_alt_pcm_platform_unregister);
|
||||
|
||||
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
|
||||
MODULE_DESCRIPTION("Tegra Alt PCM ASoC driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
261
sound/soc/tegra-virt-alt/tegra_virt_ref_alt.c
Normal file
261
sound/soc/tegra-virt-alt/tegra_virt_ref_alt.c
Normal file
@@ -0,0 +1,261 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "tegra210_virt_alt_admaif.h"
|
||||
#include "tegra_asoc_machine_virt_alt.h"
|
||||
#include "tegra_asoc_util_virt_alt.h"
|
||||
#include "tegra_asoc_xbar_virt_alt.h"
|
||||
#include "tegra_virt_alt_ivc.h"
|
||||
|
||||
static struct snd_soc_card tegra_virt_t210ref_card = {
|
||||
.name = "t210ref-virt-card",
|
||||
.owner = THIS_MODULE,
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static struct snd_soc_card tegra_virt_t186ref_card = {
|
||||
.name = "t186ref-virt-card",
|
||||
.owner = THIS_MODULE,
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static void tegra_virt_set_dai_params(
|
||||
struct snd_soc_dai_link *dai_link,
|
||||
struct snd_soc_pcm_stream *user_params,
|
||||
unsigned int dai_id)
|
||||
{
|
||||
dai_link[dai_id].params = user_params;
|
||||
}
|
||||
|
||||
static struct tegra_virt_admaif_soc_data soc_data_tegra186 = {
|
||||
.num_ch = TEGRA186_ADMAIF_CHANNEL_COUNT,
|
||||
};
|
||||
|
||||
|
||||
static const struct of_device_id tegra_virt_machine_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra186-virt-pcm",
|
||||
.data = &soc_data_tegra186},
|
||||
{ .compatible = "nvidia,tegra234-virt-pcm-oot",
|
||||
.data = &soc_data_tegra186},
|
||||
{},
|
||||
};
|
||||
|
||||
static int tegra_virt_machine_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = NULL;
|
||||
int i, ret = 0;
|
||||
int admaif_ch_num = 0;
|
||||
bool adsp_enabled = false;
|
||||
unsigned int admaif_ch_list[MAX_ADMAIF_IDS];
|
||||
const struct of_device_id *match;
|
||||
struct tegra_virt_admaif_soc_data *soc_data;
|
||||
char buffer[30];
|
||||
int32_t adsp_admaif_bits, adsp_admaif_format;
|
||||
int32_t adsp_admaif_channels;
|
||||
struct snd_soc_pcm_stream adsp_admaif_dt_params;
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
|
||||
match = tegra_virt_machine_of_match;
|
||||
if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"nvidia,tegra210-virt-pcm")) {
|
||||
card = &tegra_virt_t210ref_card;
|
||||
match = of_match_device(tegra_virt_machine_of_match,
|
||||
&pdev->dev);
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
soc_data = (struct tegra_virt_admaif_soc_data *)match->data;
|
||||
} else {
|
||||
card = &tegra_virt_t186ref_card;
|
||||
match = of_match_device(tegra_virt_machine_of_match,
|
||||
&pdev->dev);
|
||||
if (!match)
|
||||
return -ENODEV;
|
||||
soc_data = (struct tegra_virt_admaif_soc_data *)match->data;
|
||||
}
|
||||
|
||||
card->dev = &pdev->dev;
|
||||
card->dai_link = tegra_virt_machine_get_dai_link();
|
||||
card->num_links = tegra_virt_machine_get_num_dai_links();
|
||||
adsp_enabled = of_property_read_bool(pdev->dev.of_node,
|
||||
"adsp_enabled");
|
||||
|
||||
|
||||
if (adsp_enabled) {
|
||||
dev_info(&pdev->dev, "virt-alt-pcm: adsp config is set\n");
|
||||
|
||||
/* Get ADSP ADMAIF default param info */
|
||||
for (i = 0; i < MAX_ADMAIF_IDS; i++) {
|
||||
if ((sprintf(buffer, "adsp-admaif%d-channels", i + 1)) < 0)
|
||||
return -EINVAL;
|
||||
if (of_property_read_u32(pdev->dev.of_node,
|
||||
buffer, &adsp_admaif_channels))
|
||||
adsp_admaif_channels = 2;
|
||||
|
||||
if ((sprintf(buffer, "adsp-admaif%d-bits", i + 1) < 0))
|
||||
return -EINVAL;
|
||||
if (of_property_read_u32(pdev->dev.of_node,
|
||||
buffer, &adsp_admaif_bits))
|
||||
adsp_admaif_bits = 16;
|
||||
|
||||
if (adsp_admaif_channels > 16 || adsp_admaif_channels < 1) {
|
||||
dev_err(&pdev->dev,
|
||||
"unsupported channels %d for adsp admaif %d, setting default 2 channel\n",
|
||||
adsp_admaif_channels, i + 1);
|
||||
adsp_admaif_channels = 2;
|
||||
}
|
||||
|
||||
switch (adsp_admaif_bits) {
|
||||
|
||||
case 8:
|
||||
adsp_admaif_format = SNDRV_PCM_FMTBIT_S8;
|
||||
break;
|
||||
case 16:
|
||||
adsp_admaif_format = SNDRV_PCM_FMTBIT_S16_LE;
|
||||
break;
|
||||
case 32:
|
||||
adsp_admaif_format = SNDRV_PCM_FMTBIT_S32_LE;
|
||||
break;
|
||||
default:
|
||||
adsp_admaif_format = SNDRV_PCM_FMTBIT_S16_LE;
|
||||
dev_err(&pdev->dev,
|
||||
"unsupported bits %d for adsp admaif %d, setting default 16 bit\n",
|
||||
adsp_admaif_bits, i + 1);
|
||||
adsp_admaif_bits = 16;
|
||||
break;
|
||||
}
|
||||
adsp_admaif_dt_params.formats = adsp_admaif_format;
|
||||
adsp_admaif_dt_params.rate_min = 48000;
|
||||
adsp_admaif_dt_params.rate_max = 48000;
|
||||
adsp_admaif_dt_params.channels_min = adsp_admaif_channels;
|
||||
adsp_admaif_dt_params.channels_max = adsp_admaif_channels;
|
||||
|
||||
tegra_virt_machine_set_adsp_admaif_dai_params(
|
||||
i, &adsp_admaif_dt_params);
|
||||
}
|
||||
} else {
|
||||
dev_info(&pdev->dev, "virt-alt-pcm: adsp config is not set\n");
|
||||
card->num_links = soc_data->num_ch;
|
||||
}
|
||||
|
||||
if (tegra210_virt_admaif_register_component(pdev, soc_data)) {
|
||||
dev_err(&pdev->dev, "Failed register admaif component\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tegra_virt_xbar_register_codec(pdev)) {
|
||||
dev_err(&pdev->dev, "Failed register xbar component\n");
|
||||
ret = -EINVAL;
|
||||
goto undo_register_component;
|
||||
}
|
||||
|
||||
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");
|
||||
ret = -EINVAL;
|
||||
goto undo_register_codec;
|
||||
}
|
||||
|
||||
if (of_property_read_string(pdev->dev.of_node, "cardname", &card->name))
|
||||
dev_warn(&pdev->dev, "Using default card name %s\n",
|
||||
card->name);
|
||||
|
||||
if (admaif_ch_num > 0) {
|
||||
|
||||
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 os not populated\n");
|
||||
ret = -EINVAL;
|
||||
goto undo_register_codec;
|
||||
}
|
||||
for (i = 0; i < admaif_ch_num; i++) {
|
||||
tegra_virt_set_dai_params(
|
||||
tegra_virt_machine_get_dai_link(),
|
||||
NULL,
|
||||
(admaif_ch_list[i] - 1));
|
||||
}
|
||||
}
|
||||
|
||||
ret = snd_soc_register_card(card);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
|
||||
ret);
|
||||
ret = -EPROBE_DEFER;
|
||||
goto undo_register_codec;
|
||||
}
|
||||
|
||||
list_for_each_entry(rtd, &card->rtd_list, list) {
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai_driver *codec_drv = codec_dai->driver;
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
struct snd_soc_dai_driver *cpu_drv = cpu_dai->driver;
|
||||
|
||||
cpu_drv->playback.rates = SNDRV_PCM_RATE_KNOT;
|
||||
cpu_drv->playback.rate_min = 8000;
|
||||
cpu_drv->playback.rate_max = 192000;
|
||||
cpu_drv->capture.rates = SNDRV_PCM_RATE_KNOT;
|
||||
cpu_drv->capture.rate_min = 8000;
|
||||
cpu_drv->capture.rate_max = 192000;
|
||||
|
||||
codec_drv->playback.rates = SNDRV_PCM_RATE_KNOT;
|
||||
codec_drv->playback.rate_min = 8000;
|
||||
codec_drv->playback.rate_max = 192000;
|
||||
codec_drv->capture.rates = SNDRV_PCM_RATE_KNOT;
|
||||
codec_drv->capture.rate_min = 8000;
|
||||
codec_drv->capture.rate_max = 192000;
|
||||
}
|
||||
|
||||
pm_runtime_forbid(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
undo_register_codec:
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
undo_register_component:
|
||||
tegra210_virt_admaif_unregister_component(pdev);
|
||||
|
||||
nvaudio_ivc_free_ctxt(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tegra_virt_machine_driver_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_unregister_card(card);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver tegra_virt_machine_driver = {
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &snd_soc_pm_ops,
|
||||
.of_match_table =
|
||||
of_match_ptr(tegra_virt_machine_of_match),
|
||||
},
|
||||
.probe = tegra_virt_machine_driver_probe,
|
||||
.remove = tegra_virt_machine_driver_remove,
|
||||
};
|
||||
module_platform_driver(tegra_virt_machine_driver);
|
||||
|
||||
MODULE_AUTHOR("Paresh Anandathirtha <paresha@nvidia.com>");
|
||||
MODULE_DESCRIPTION("Tegra virt machine driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(of, tegra_virt_machine_of_match);
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
||||
MODULE_SOFTDEP("pre: snd_soc_tegra210_virt_alt_adsp");
|
||||
Reference in New Issue
Block a user