Merge f374586dc0 on remote branch

Change-Id: Ia8b656096a655924d9f773a066988009ca65ddb0
This commit is contained in:
Linux Build Service Account 2022-03-16 06:24:55 -07:00
commit 4487054fd4
36 changed files with 3261 additions and 1269 deletions

View file

@ -30,6 +30,9 @@ endif
ifeq ($(CONFIG_ARCH_SA6155), y)
include $(srctree)/techpack/audio/config/sa6155auto.conf
endif
ifeq ($(CONFIG_ARCH_SM6150), y)
include $(srctree)/techpack/audio/config/sm6150auto.conf
endif
endif
# Use USERINCLUDE when you must reference the UAPI directories only.
USERINCLUDE += \
@ -79,7 +82,10 @@ ifeq ($(CONFIG_ARCH_SA6155), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/audio/config/sa6155autoconf.h
endif
ifeq ($(CONFIG_ARCH_SM6150), y)
LINUXINCLUDE += \
-include $(srctree)/techpack/audio/config/sm6150autoconf.h
endif
obj-y += soc/
obj-y += dsp/
obj-y += ipc/

View file

@ -136,7 +136,6 @@ endif
# for SM6150 sound card driver
ifdef CONFIG_SND_SOC_SM6150
MACHINE_OBJS += sm6150.o
MACHINE_OBJS += machine_615x_init.o
endif
# For sa6155 sound card driver

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk.h>
@ -3956,6 +3957,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
*/
mutex_lock(&mi2s_intf_conf[index].lock);
if (++mi2s_intf_conf[index].ref_cnt == 1) {
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) {
dev_err(rtd->card->dev,
@ -3978,11 +3982,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
atomic_inc(&(pdata->mi2s_gpio_ref_count[index]));
}
}
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",

View file

@ -147,6 +147,7 @@ ifdef CONFIG_WCD9XXX_CODEC_CORE
WCD9XXX_OBJS += wcd9xxx-resmgr-v2.o
WCD9XXX_OBJS += wcd-dsp-utils.o
WCD9XXX_OBJS += wcd-dsp-mgr.o
WCD9XXX_OBJS += wcd-clsh.o
else
WCD9XXX_OBJS += wcd-clsh.o
endif

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/kernel.h>
@ -58,6 +59,8 @@ struct audio_ext_clk_priv {
uint32_t lpass_audio_hwvote_client_handle;
};
static struct audio_ext_clk audio_clk_array[];
static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw)
{
return container_of(hw, struct audio_ext_clk_priv, audio_clk.fact.hw);
@ -137,8 +140,8 @@ static u8 audio_ext_clk_get_parent(struct clk_hw *hw)
{
struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
int num_parents = clk_hw_get_num_parents(hw);
const char * const *parent_names = hw->init->parent_names;
u8 i = 0, ret = hw->init->num_parents + 1;
const char * const *parent_names = audio_clk_array[clk_priv->clk_src].fact.hw.init->parent_names;
u8 i = 0, ret = num_parents + 1;
if ((clk_priv->clk_src == AUDIO_EXT_CLK_PMI) && clk_priv->clk_name) {
for (i = 0; i < num_parents; i++) {

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/init.h>
@ -1478,7 +1479,7 @@ static int wcd_spi_component_bind(struct device *dev,
spi_message_add_tail(&wcd_spi->xfer2[1], &wcd_spi->msg2);
/* Pre-allocate the buffers */
wcd_spi->tx_buf = dma_zalloc_coherent(&spi->dev,
wcd_spi->tx_buf = dma_alloc_coherent(&spi->dev,
WCD_SPI_RW_MAX_BUF_SIZE,
&wcd_spi->tx_dma, GFP_KERNEL);
if (!wcd_spi->tx_buf) {
@ -1486,7 +1487,7 @@ static int wcd_spi_component_bind(struct device *dev,
goto done;
}
wcd_spi->rx_buf = dma_zalloc_coherent(&spi->dev,
wcd_spi->rx_buf = dma_alloc_coherent(&spi->dev,
WCD_SPI_RW_MAX_BUF_SIZE,
&wcd_spi->rx_dma, GFP_KERNEL);
if (!wcd_spi->rx_buf) {

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
#include <linux/init.h>
@ -21,6 +22,7 @@
#include <linux/spi/spi.h>
#include <linux/regulator/consumer.h>
#include <audio/linux/mfd/wcd9xxx/wcd9xxx_registers.h>
#include <soc/swr-common.h>
#include <soc/swr-wcd.h>
#include <soc/snd_event.h>
#include <sound/pcm.h>
@ -500,6 +502,7 @@ struct wcd_swr_ctrl_platform_data {
int (*write)(void *handle, int reg, int val);
int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
int (*clk)(void *handle, bool enable);
int (*core_vote)(void *handle, bool enable);
int (*handle_irq)(void *handle,
irqreturn_t (*swrm_irq_handler)(int irq, void *data),
void *swrm_handle, int action);
@ -748,6 +751,34 @@ void *tavil_get_afe_config(struct snd_soc_component *component,
}
EXPORT_SYMBOL(tavil_get_afe_config);
int tavil_set_port_map(struct snd_soc_component *component,
u32 size, void *data)
{
struct swr_mstr_port_map *map = NULL;
struct swrm_port_config port_cfg;
struct tavil_priv *priv = NULL;
if (!component || (size == 0) || !data)
return -EINVAL;
priv = snd_soc_component_get_drvdata(component);
map = (struct swr_mstr_port_map *)data;
port_cfg.uc = map->uc;
port_cfg.size = SWR_MSTR_PORT_LEN;
port_cfg.params = map->swr_port_params;
swrm_wcd_notify(
priv->swr.ctrl_data[0].swr_pdev,
SWR_SET_PORT_MAP, &port_cfg);
return 0;
}
EXPORT_SYMBOL(tavil_set_port_map);
static bool is_tavil_playback_dai(int dai_id)
{
if ((dai_id == AIF1_PB) || (dai_id == AIF2_PB) ||
@ -11345,6 +11376,7 @@ static int tavil_probe(struct platform_device *pdev)
tavil->swr.plat_data.bulk_write = tavil_swrm_bulk_write;
tavil->swr.plat_data.clk = tavil_swrm_clock;
tavil->swr.plat_data.handle_irq = tavil_swrm_handle_irq;
tavil->swr.plat_data.core_vote = NULL;
tavil->swr.spkr_gain_offset = WCD934X_RX_GAIN_OFFSET_0_DB;
/* Register for Clock */

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef WCD934X_H
#define WCD934X_H
@ -129,6 +130,8 @@ struct tavil_reg_mask_val {
#if IS_ENABLED(CONFIG_SND_SOC_WCD934X)
extern void *tavil_get_afe_config(struct snd_soc_component *component,
enum afe_config_type config_type);
extern int tavil_set_port_map(struct snd_soc_component *component,
u32 size, void *data);
extern int tavil_cdc_mclk_enable(struct snd_soc_component *component,
bool enable);
extern int tavil_cdc_mclk_tx_enable(struct snd_soc_component *component,
@ -159,6 +162,11 @@ extern void *tavil_get_afe_config(struct snd_soc_component *component,
{
return NULL;
}
extern int tavil_set_port_map(struct snd_soc_component *component,
u32 size, void *data)
{
return 0;
}
extern int tavil_cdc_mclk_enable(struct snd_soc_component *component,
bool enable)
{

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -188,6 +189,12 @@ static int wcd937x_init_reg(struct snd_soc_component *component)
0xFF, 0xFA);
snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_1,
0xFF, 0xFA);
snd_soc_component_update_bits(component, WCD937X_MICB1_TEST_CTL_2,
0x38, 0x00);
snd_soc_component_update_bits(component, WCD937X_MICB2_TEST_CTL_2,
0x38, 0x00);
snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_2,
0x38, 0x00);
/* Set Bandgap Fine Adjustment to +5mV for Tanggu SMIC part */
if (snd_soc_component_read32(component, WCD937X_DIGITAL_EFUSE_REG_16)
== 0x01) {

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@ -30,9 +31,21 @@
#include "wsa881x-temp-sensor.h"
#include "asoc/bolero-slave-internal.h"
#define DRV_NAME "wsa-codec"
#define WSA881X_NUM_RETRY 5
#define MAX_NAME_LEN 30
#define WSA881X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
SNDRV_PCM_RATE_384000)
/* Fractional Rates */
#define WSA881X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
#define WSA881X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S24_LE |\
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
enum {
G_18DB = 0,
G_16P5DB,
@ -115,6 +128,9 @@ struct wsa881x_priv {
struct dentry *debugfs_poke;
struct dentry *debugfs_reg_dump;
unsigned int read_data;
char *wsa881x_name_prefix;
struct snd_soc_dai_driver *dai_driver;
struct snd_soc_component_driver *driver;
};
struct wsa_ctrl_platform_data {
@ -1356,7 +1372,7 @@ static void wsa881x_remove(struct snd_soc_component *component)
}
static const struct snd_soc_component_driver soc_codec_dev_wsa881x = {
.name = DRV_NAME,
.name = "wsa-codec",
.probe = wsa881x_probe,
.remove = wsa881x_remove,
.controls = wsa881x_snd_controls,
@ -1367,6 +1383,21 @@ static const struct snd_soc_component_driver soc_codec_dev_wsa881x = {
.num_dapm_routes = ARRAY_SIZE(wsa881x_audio_map),
};
static struct snd_soc_dai_driver wsa_dai[] = {
{
.name = "wsa_rx",
.playback = {
.stream_name = "WSA881X_AIF Playback",
.rates = WSA881X_RATES | WSA881X_FRAC_RATES,
.formats = WSA881X_FORMATS,
.rate_max = 192000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 2,
},
},
};
static int wsa881x_gpio_ctrl(struct wsa881x_priv *wsa881x, bool enable)
{
int ret = 0;
@ -1461,9 +1492,13 @@ static int wsa881x_event_notify(struct notifier_block *nb,
static int wsa881x_swr_probe(struct swr_device *pdev)
{
int ret = 0;
struct wsa881x_priv *wsa881x;
struct wsa881x_priv *wsa881x = NULL;
struct snd_soc_component *component;
u8 devnum = 0;
int dev_index = 0;
bool pin_state_current = false;
char buffer[MAX_NAME_LEN];
const char *wsa881x_name_prefix_of = NULL;
struct wsa_ctrl_platform_data *plat_data = NULL;
wsa881x = devm_kzalloc(&pdev->dev, sizeof(struct wsa881x_priv),
@ -1553,14 +1588,74 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
goto dev_err;
}
ret = snd_soc_register_component(&pdev->dev, &soc_codec_dev_wsa881x,
NULL, 0);
ret = of_property_read_string(pdev->dev.of_node,
"qcom,wsa-prefix", &wsa881x_name_prefix_of);
if (ret) {
dev_err(&pdev->dev,
"%s: Looking up %s property in node %s failed\n",
__func__, "qcom,wsa-prefix",
pdev->dev.of_node->full_name);
goto dev_err;
}
wsa881x->driver = devm_kzalloc(&pdev->dev,
sizeof(struct snd_soc_component_driver),
GFP_KERNEL);
if (!wsa881x->driver) {
ret = -ENOMEM;
goto err_mem;
}
memcpy(wsa881x->driver, &soc_codec_dev_wsa881x,
sizeof(struct snd_soc_component_driver));
wsa881x->dai_driver = devm_kzalloc(&pdev->dev,
sizeof(struct snd_soc_dai_driver),
GFP_KERNEL);
if (!wsa881x->dai_driver) {
ret = -ENOMEM;
goto err_mem;
}
memcpy(wsa881x->dai_driver, wsa_dai,
sizeof(struct snd_soc_dai_driver));
dev_index = (int)((char)(pdev->addr & 0xF));
snprintf(buffer, sizeof(buffer), "wsa-codec.%d", dev_index);
wsa881x->driver->name = kstrndup(buffer,
strlen(buffer), GFP_KERNEL);
snprintf(buffer, sizeof(buffer), "wsa_rx%d", dev_index);
wsa881x->dai_driver->name =
kstrndup(buffer, strlen(buffer), GFP_KERNEL);
snprintf(buffer, sizeof(buffer),
"WSA881X_AIF%d Playback", dev_index);
wsa881x->dai_driver->playback.stream_name =
kstrndup(buffer, strlen(buffer), GFP_KERNEL);
/* Number of DAI's used is 1 */
ret = snd_soc_register_component(&pdev->dev,
wsa881x->driver, wsa881x->dai_driver, 1);
if (ret) {
dev_err(&pdev->dev, "%s: Codec registration failed\n",
__func__);
goto dev_err;
goto err_mem;
}
wsa881x->wsa881x_name_prefix = kstrndup(wsa881x_name_prefix_of,
strlen(wsa881x_name_prefix_of), GFP_KERNEL);
component = snd_soc_lookup_component(&pdev->dev, wsa881x->driver->name);
if (!component) {
dev_err(&pdev->dev, "%s: component is NULL \n", __func__);
ret = -EINVAL;
goto err_mem;
}
component->name_prefix = wsa881x->wsa881x_name_prefix;
wsa881x->bolero_np = of_parse_phandle(pdev->dev.of_node,
"qcom,bolero-handle", 0);
if (wsa881x->bolero_np) {
@ -1596,6 +1691,17 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
return 0;
err_mem:
kfree(wsa881x->wsa881x_name_prefix);
if (wsa881x->dai_driver) {
devm_kfree(&pdev->dev, wsa881x->dai_driver->name);
devm_kfree(&pdev->dev, wsa881x->dai_driver->playback.stream_name);
devm_kfree(&pdev->dev, wsa881x->dai_driver);
}
if (wsa881x->driver) {
devm_kfree(&pdev->dev, wsa881x->driver->name);
devm_kfree(&pdev->dev, wsa881x->driver);
}
dev_err:
if (pin_state_current == false)
wsa881x_gpio_ctrl(wsa881x, false);
@ -1625,6 +1731,16 @@ static int wsa881x_swr_remove(struct swr_device *pdev)
if (wsa881x->pd_gpio)
gpio_free(wsa881x->pd_gpio);
swr_set_dev_data(pdev, NULL);
kfree(wsa881x->wsa881x_name_prefix);
if (wsa881x->dai_driver) {
devm_kfree(&pdev->dev, wsa881x->dai_driver->name);
devm_kfree(&pdev->dev, wsa881x->dai_driver->playback.stream_name);
devm_kfree(&pdev->dev, wsa881x->dai_driver);
}
if (wsa881x->driver) {
devm_kfree(&pdev->dev, wsa881x->driver->name);
devm_kfree(&pdev->dev, wsa881x->driver);
}
return 0;
}

View file

@ -218,26 +218,6 @@ static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm_common_dai_links[] = {
/* BackEnd DAI Links */
{
.name = "TERT_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-TERTIARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(tert_tdm_rx_0_dummy),
},
{
.name = "TERT_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-TERTIARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(tert_tdm_tx_0_dummy),
},
{
.name = "LPASS_BE_AUXPCM_RX_DUMMY",
.stream_name = "AUXPCM-LPAIF-RX-PRIMARY",
@ -258,6 +238,46 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(lpass_be_auxpcm_tx_dummy),
},
{
.name = "SEC_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-SECONDARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(secondary_tdm_rx_0_dummy),
},
{
.name = "SEC_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-SECONDARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(secondary_tdm_tx_0_dummy),
},
{
.name = "TERT_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-TERTIARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(tert_tdm_rx_0_dummy),
},
{
.name = "TERT_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-TERTIARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(tert_tdm_tx_0_dummy),
},
{
.name = "QUAT_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-QUATERNARY",
@ -278,6 +298,26 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(quat_tdm_tx_0_dummy),
},
{
.name = "QUIN_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-QUINARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(quin_tdm_rx_0_dummy),
},
{
.name = "QUIN_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-QUINARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(quin_tdm_tx_0_dummy),
},
};
static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
@ -344,7 +384,7 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
},
{
.name = "QUAT_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-QUATERNARY",
.stream_name = "TDM-LPAIF_RXTX-RX-PRIMARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -354,7 +394,7 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
},
{
.name = "QUAT_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-QUATERNARY",
.stream_name = "TDM-LPAIF_RXTX-TX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -364,7 +404,7 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
},
{
.name = "QUIN_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-QUINARY",
.stream_name = "TDM-LPAIF_VA-RX-PRIMARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -374,7 +414,7 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
},
{
.name = "QUIN_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-QUINARY",
.stream_name = "TDM-LPAIF_VA-TX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -384,7 +424,7 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
},
{
.name = "SEN_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-SENARY",
.stream_name = "TDM-LPAIF_WSA-RX-PRIMARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -394,7 +434,7 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
},
{
.name = "SEN_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-SENARY",
.stream_name = "TDM-LPAIF_WSA-TX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -404,7 +444,7 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
},
{
.name = "SEP_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-SEPTENARY",
.stream_name = "TDM-LPAIF_AUD-RX-PRIMARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -414,7 +454,7 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
},
{
.name = "SEP_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-SEPTENARY",
.stream_name = "TDM-LPAIF_AUD-TX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -422,30 +462,70 @@ static struct snd_soc_dai_link msm_gvm8295_dai_links[] = {
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(sep_tdm_tx_0_dummy),
},
{
.name = "HS_IF0_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF_SDR-RX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(hs_if0_tdm_rx_0_dummy),
},
{
.name = "HS_IF0_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF_SDR-TX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(hs_if0_tdm_tx_0_dummy),
},
{
.name = "HS_IF1_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF_SDR-RX-SECONDARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(hs_if1_tdm_rx_0_dummy),
},
{
.name = "HS_IF1_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF_SDR-TX-SECONDARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(hs_if1_tdm_tx_0_dummy),
},
{
.name = "HS_IF2_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF_SDR-RX-TERTIARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(hs_if2_tdm_rx_0_dummy),
},
{
.name = "HS_IF2_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF_SDR-TX-TERTIARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(hs_if2_tdm_tx_0_dummy),
},
};
static struct snd_soc_dai_link msm_talos_dai_links[] = {
/* BackEnd DAI Links */
{
.name = "PRIMARY_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF_WSA-RX-PRIMARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(primary_tdm_rx_0_dummy),
},
{
.name = "PRIMARY_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF_WSA-TX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(primary_tdm_tx_0_dummy),
},
{
.name = "LPASS_BE_AUXPCM_RX_DUMMY",
.stream_name = "AUXPCM-LPAIF-RX-PRIMARY",
@ -466,9 +546,49 @@ static struct snd_soc_dai_link msm_talos_dai_links[] = {
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(lpass_be_auxpcm_tx_dummy),
},
{
.name = "SEC_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-SECONDARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(secondary_tdm_rx_0_dummy),
},
{
.name = "SEC_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-SECONDARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(secondary_tdm_tx_0_dummy),
},
{
.name = "TERT_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF_WSA-RX-PRIMARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(tert_tdm_rx_0_dummy),
},
{
.name = "TERT_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF_WSA-TX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(tert_tdm_tx_0_dummy),
},
{
.name = "QUAT_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-QUATERNARY",
.stream_name = "TDM-LPAIF_RXTX-RX-PRIMARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -478,7 +598,7 @@ static struct snd_soc_dai_link msm_talos_dai_links[] = {
},
{
.name = "QUAT_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-QUATERNARY",
.stream_name = "TDM-LPAIF_RXTX-TX-PRIMARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
@ -486,6 +606,26 @@ static struct snd_soc_dai_link msm_talos_dai_links[] = {
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(quat_tdm_tx_0_dummy),
},
{
.name = "QUIN_TDM_RX_0_DUMMY",
.stream_name = "TDM-LPAIF-RX-TERTIARY",
.dpcm_playback = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(quin_tdm_rx_0_dummy),
},
{
.name = "QUIN_TDM_TX_0_DUMMY",
.stream_name = "TDM-LPAIF-TX-TERTIARY",
.dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.ignore_suspend = 1,
.ignore_pmdown_time = 1,
SND_SOC_DAILINK_REG(quin_tdm_tx_0_dummy),
},
};
struct snd_soc_card snd_soc_card_auto_hana_dummy_msm = {

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk.h>
@ -4459,6 +4460,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
}
if (++mi2s_intf_conf[index].ref_cnt == 1) {
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) {
dev_err(rtd->card->dev,
@ -4481,11 +4485,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
atomic_inc(&(pdata->mi2s_gpio_ref_count[index]));
}
}
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk.h>
@ -5100,6 +5101,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
}
if (++mi2s_intf_conf[index].ref_cnt == 1) {
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) {
dev_err(rtd->card->dev,
@ -5122,11 +5126,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
atomic_inc(&(pdata->mi2s_gpio_ref_count[index]));
}
}
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",
@ -6841,6 +6842,17 @@ static struct snd_soc_dai_link msm_wsa_cdc_dma_be_dai_links[] = {
.ops = &msm_cdc_dma_be_ops,
SND_SOC_DAILINK_REG(wsa_dma_tx1),
},
{
.name = LPASS_BE_WSA_CDC_DMA_TX_0_VI,
.stream_name = "WSA CDC DMA0 Capture",
.no_pcm = 1,
.dpcm_capture = 1,
.id = MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0,
.be_hw_params_fixup = msm_be_hw_params_fixup,
.ignore_suspend = 1,
.ops = &msm_cdc_dma_be_ops,
SND_SOC_DAILINK_REG(wsa_dma_tx0_vi),
},
};
static struct snd_soc_dai_link msm_rx_tx_cdc_dma_be_dai_links[] = {

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk.h>
@ -5440,6 +5441,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
mi2s_clk[index].clk_freq_in_hz);
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) {
dev_err(rtd->card->dev,
@ -5462,11 +5466,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
atomic_inc(&(pdata->mi2s_gpio_ref_count[index]));
}
}
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",

View file

@ -481,6 +481,8 @@ static bool afe_port_logging_item[IDX_TDM_MAX];
static int afe_port_loggging_control_added;
static int afe_dyn_mclk_control_added;
static DEFINE_MUTEX(tdm_mutex);
static atomic_t tdm_group_ref[IDX_GROUP_TDM_MAX];
@ -522,6 +524,51 @@ static struct afe_clk_set tdm_clk_set = {
0,
};
static int clk_id_index;
static int clk_root_index;
static int clk_attri_index;
static int global_dyn_mclk_cfg_portid;
struct afe_param_id_clock_set_v2_t global_dyn_mclk_cfg = {
.clk_set_minor_version = Q6AFE_LPASS_CLK_CONFIG_API_VERSION,
.clk_id = Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT,
.clk_freq_in_hz = 12288000,
.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
.clk_root = Q6AFE_LPASS_MCLK_IN0,
.divider_2x = AFE_CLOCK_DEFAULT_INTEGER_DIVIDER,
.m = AFE_CLOCK_DEFAULT_M_VALUE,
.n = AFE_CLOCK_DEFAULT_N_VALUE,
.d = AFE_CLOCK_DEFAULT_D_VALUE,
.enable = 0,
};
static int afe_dyn_clk_root_enum[] = {
Q6AFE_LPASS_MCLK_IN0,
Q6AFE_LPASS_MCLK_IN1,
};
static int afe_dyn_clk_attri_enum[] = {
Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND,
Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR,
};
static int afe_dyn_clk_id_enum[] = {
Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT,
Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT, Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT,
Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT,
Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT, Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT,
Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_IBIT, Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_EBIT,
Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR,
Q6AFE_LPASS_CLK_ID_PRI_PCM_IBIT, Q6AFE_LPASS_CLK_ID_PRI_PCM_EBIT,
Q6AFE_LPASS_CLK_ID_SEC_PCM_IBIT, Q6AFE_LPASS_CLK_ID_SEC_PCM_EBIT,
Q6AFE_LPASS_CLK_ID_TER_PCM_IBIT, Q6AFE_LPASS_CLK_ID_TER_PCM_EBIT,
Q6AFE_LPASS_CLK_ID_QUAD_PCM_IBIT, Q6AFE_LPASS_CLK_ID_QUAD_PCM_EBIT,
Q6AFE_LPASS_CLK_ID_MCLK_1, Q6AFE_LPASS_CLK_ID_MCLK_2,
Q6AFE_LPASS_CLK_ID_MCLK_3, Q6AFE_LPASS_CLK_ID_MCLK_4,
Q6AFE_LPASS_CLK_ID_MCLK_5, Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT,
Q6AFE_LPASS_CLK_ID_SPDIF_CORE
};
static int msm_dai_q6_get_tdm_clk_ref(u16 id)
{
switch (id) {
@ -10371,14 +10418,168 @@ static int msm_pcm_add_afe_port_logging_control(struct snd_soc_dai *dai)
return rc;
}
static int get_global_clk_root(int value)
{
if ((value < 0) || (value > ARRAY_SIZE(afe_dyn_clk_root_enum) - 1)) {
pr_err("%s, %d set clk_root range failed\n", __func__, __LINE__);
return global_dyn_mclk_cfg.clk_root;
}
clk_root_index = value;
return afe_dyn_clk_root_enum[clk_root_index];
}
static int get_global_clk_attri(int value)
{
if ((value < 0) || (value > ARRAY_SIZE(afe_dyn_clk_attri_enum) - 1)) {
pr_err("%s, %d set clk_attri range failed\n", __func__, __LINE__);
return global_dyn_mclk_cfg.clk_attri;
}
clk_attri_index = value;
return afe_dyn_clk_attri_enum[clk_attri_index];
}
static int get_global_clk_id(int value)
{
if ((value < 0) || (value > ARRAY_SIZE(afe_dyn_clk_id_enum) - 1)) {
pr_err("%s, %d set clk_id range failed\n", __func__, __LINE__);
return global_dyn_mclk_cfg.clk_id;
}
clk_id_index = value;
return afe_dyn_clk_id_enum[clk_id_index];
}
static int msm_pcm_afe_dyn_mclk_ctl_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *ucontrol)
{
ucontrol->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
/* 11 int values:clk_set_minor_version, clk_id, clk_freq_in_hz, clk_attri,
* clk_root, enable, divider_2x, m, n, d
*/
ucontrol->count = 11;
ucontrol->value.integer.min = 0;
ucontrol->value.integer.max = INT_MAX;
/* Valid range is all positive values to support above controls */
pr_debug("%s,%d\n", __func__, __LINE__);
return 0;
}
static int msm_pcm_afe_dyn_mclk_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = global_dyn_mclk_cfg_portid;
ucontrol->value.integer.value[1] = clk_id_index;
ucontrol->value.integer.value[2] = global_dyn_mclk_cfg.clk_freq_in_hz;
ucontrol->value.integer.value[3] = clk_attri_index;
ucontrol->value.integer.value[4] = clk_root_index;
ucontrol->value.integer.value[5] = global_dyn_mclk_cfg.enable;
ucontrol->value.integer.value[6] = global_dyn_mclk_cfg.divider_2x;
ucontrol->value.integer.value[7] = global_dyn_mclk_cfg.m;
ucontrol->value.integer.value[8] = global_dyn_mclk_cfg.n;
ucontrol->value.integer.value[9] = global_dyn_mclk_cfg.d;
ucontrol->value.integer.value[10] = global_dyn_mclk_cfg.clk_set_minor_version;
pr_debug("%s:%d.... portid:%d, clk_id:%d, clk_freq_in_hz:%d, clk_attri:%d, clk_root:%d, enable:%d, divider_2x:%d, m:%d, n:%d, d:%d, version:%d\n",
__func__, __LINE__, global_dyn_mclk_cfg_portid, global_dyn_mclk_cfg.clk_id,
global_dyn_mclk_cfg.clk_freq_in_hz, global_dyn_mclk_cfg.clk_attri,
global_dyn_mclk_cfg.clk_root, global_dyn_mclk_cfg.enable,
global_dyn_mclk_cfg.divider_2x, global_dyn_mclk_cfg.m, global_dyn_mclk_cfg.n,
global_dyn_mclk_cfg.d, global_dyn_mclk_cfg.clk_set_minor_version);
return 0;
}
static int msm_pcm_afe_dyn_mclk_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int ret = -EINVAL;
pr_debug("%s: enter\n", __func__);
global_dyn_mclk_cfg_portid = ucontrol->value.integer.value[0];
global_dyn_mclk_cfg.clk_id = get_global_clk_id(ucontrol->value.integer.value[1]);
if (ucontrol->value.integer.value[2] >= 0)
global_dyn_mclk_cfg.clk_freq_in_hz = ucontrol->value.integer.value[2];
global_dyn_mclk_cfg.clk_attri = get_global_clk_attri(ucontrol->value.integer.value[3]);
global_dyn_mclk_cfg.clk_root = get_global_clk_root(ucontrol->value.integer.value[4]);
if ((ucontrol->value.integer.value[5] <= 1) && (ucontrol->value.integer.value[5] >= 0))
global_dyn_mclk_cfg.enable = ucontrol->value.integer.value[5];
global_dyn_mclk_cfg.divider_2x = ucontrol->value.integer.value[6];
global_dyn_mclk_cfg.m = ucontrol->value.integer.value[7];
global_dyn_mclk_cfg.n = ucontrol->value.integer.value[8];
global_dyn_mclk_cfg.d = ucontrol->value.integer.value[9];
pr_debug("%s:%d.... portid:%d, clk_id_index:%d, clk_freq_in_hz:%d, clk_attri_index:%d, clk_root_index:%d, enable:%d, divider_2x:%d, m:%d, n:%d, d:%d, version:%d\n",
__func__, __LINE__, ucontrol->value.integer.value[0],
ucontrol->value.integer.value[1],
ucontrol->value.integer.value[2], ucontrol->value.integer.value[3],
ucontrol->value.integer.value[4], ucontrol->value.integer.value[5],
ucontrol->value.integer.value[6], ucontrol->value.integer.value[7],
ucontrol->value.integer.value[8], ucontrol->value.integer.value[9]);
ret = afe_set_lpass_clk_cfg_ext_mclk_v2(global_dyn_mclk_cfg_portid,
&global_dyn_mclk_cfg, 0);
if (ret)
pr_err("%s: AFE port logging setting for port 0x%x failed %d\n",
__func__, global_dyn_mclk_cfg_portid, ret);
return ret;
}
static int msm_pcm_add_afe_dyn_mclk_control(struct snd_soc_dai *dai)
{
int rc = 0;
struct snd_kcontrol_new *knew = NULL;
struct snd_kcontrol *kctl = NULL;
const char *afe_dyn_mclk_ctl_name = "AFE_dyn_switch_mclk_source";
/* Add AFE port logging controls */
knew = kzalloc(sizeof(struct snd_kcontrol_new), GFP_KERNEL);
if (!knew)
return -ENOMEM;
knew->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
knew->info = msm_pcm_afe_dyn_mclk_ctl_info;
knew->get = msm_pcm_afe_dyn_mclk_ctl_get;
knew->put = msm_pcm_afe_dyn_mclk_ctl_put;
knew->name = afe_dyn_mclk_ctl_name;
knew->private_value = dai->id;
kctl = snd_ctl_new1(knew, knew);
if (!kctl) {
kfree(knew);
return -ENOMEM;
}
rc = snd_ctl_add(dai->component->card->snd_card, kctl);
if (rc < 0)
pr_err("%s: err add AFE dyn mclk control, DAI = %s\n",
__func__, dai->name);
return rc;
}
int jitter_cleaner_afe_enable_mclk_and_get_info_cb_func(void *private_data,
uint32_t enable, uint32_t mclk_freq,
struct afe_param_id_clock_set_v2_t *dyn_mclk_cfg)
{
pr_debug("%s,%d\n", __func__, __LINE__);
return 0;
}
static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai)
{
int rc = 0;
int port_idx = 0;
struct msm_dai_q6_tdm_dai_data *tdm_dai_data = NULL;
struct snd_kcontrol *data_format_kcontrol = NULL;
struct snd_kcontrol *header_type_kcontrol = NULL;
struct snd_kcontrol *header_kcontrol = NULL;
int port_idx = 0;
const struct snd_kcontrol_new *data_format_ctrl = NULL;
const struct snd_kcontrol_new *header_type_ctrl = NULL;
const struct snd_kcontrol_new *header_ctrl = NULL;
@ -10459,6 +10660,26 @@ static int msm_dai_q6_dai_tdm_probe(struct snd_soc_dai *dai)
afe_port_loggging_control_added = 1;
}
/* add AFE dyn mclk controls */
if (!afe_dyn_mclk_control_added) {
rc = msm_pcm_add_afe_dyn_mclk_control(dai);
if (rc < 0) {
dev_err(dai->dev, "%s: add AFE dyn mclk control failed DAI: %s\n",
__func__, dai->name);
goto rtn;
}
afe_dyn_mclk_control_added = 1;
rc = afe_register_ext_mclk_cb(jitter_cleaner_afe_enable_mclk_and_get_info_cb_func,
(void *)&global_dyn_mclk_cfg);
if (rc < 0) {
dev_err(dai->dev, "%s: add AFE afe_register_ext_mclk_cb failed : %s\n",
__func__, dai->name);
goto rtn;
}
}
if (tdm_dai_data->is_island_dai)
rc = msm_dai_q6_add_island_mx_ctls(
dai->component->card->snd_card,

View file

@ -412,6 +412,7 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
if (!temp) {
dev_err(rtd->dev, "%s: no memory for event status\n",
__func__);
spin_unlock_irqrestore(&prtd->event_lock, flags);
__pm_relax(prtd->ws);
return;
}

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/init.h>
@ -683,7 +684,7 @@ static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
u64 fe_id = kcontrol->private_value;
int session_type = SESSION_TYPE_RX;
int be_id = ucontrol->value.integer.value[3];
struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0, 0};
struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0, 0, 0};
int ret = 0;
cfg_data.app_type = ucontrol->value.integer.value[0];
@ -694,10 +695,12 @@ static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
cfg_data.copp_token = ucontrol->value.integer.value[4];
if (ucontrol->value.integer.value[5] != 0)
cfg_data.bit_width = ucontrol->value.integer.value[5];
if (ucontrol->value.integer.value[6] != 0)
cfg_data.copp_perf_mode = ucontrol->value.integer.value[6];
pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d"
"sample_rate- %d copp_token- %d bit_width- %d\n",
"sample_rate- %d copp_token- %d bit_width- %d copp_perf_mode- %d\n",
__func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id,
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width);
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width, cfg_data.copp_perf_mode);
ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
be_id, &cfg_data);
if (ret < 0)
@ -730,11 +733,12 @@ static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[3] = be_id;
ucontrol->value.integer.value[4] = cfg_data.copp_token;
ucontrol->value.integer.value[5] = cfg_data.bit_width;
ucontrol->value.integer.value[6] = cfg_data.copp_perf_mode;
pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d"
"sample_rate- %d copp_token- %d bit_width- %d\n",
"sample_rate- %d copp_token- %d bit_width- %d copp_perf_mode- %d\n",
__func__, fe_id, session_type, be_id,
cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate,
cfg_data.copp_token, cfg_data.bit_width);
cfg_data.copp_token, cfg_data.bit_width, cfg_data.copp_perf_mode);
done:
return ret;
@ -746,7 +750,7 @@ static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
u64 fe_id = kcontrol->private_value;
int session_type = SESSION_TYPE_TX;
int be_id = ucontrol->value.integer.value[3];
struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0, 0};
struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0, 0, 0};
int ret = 0;
cfg_data.app_type = ucontrol->value.integer.value[0];
@ -757,10 +761,12 @@ static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
cfg_data.copp_token = ucontrol->value.integer.value[4];
if (ucontrol->value.integer.value[5] != 0)
cfg_data.bit_width = ucontrol->value.integer.value[5];
if (ucontrol->value.integer.value[6] != 0)
cfg_data.copp_perf_mode = ucontrol->value.integer.value[6];
pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d"
"sample_rate- %d copp_token- %d bit_width- %d\n",
"sample_rate- %d copp_token- %d bit_width- %d copp_perf_mode- %d\n",
__func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id,
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width);
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width, cfg_data.copp_perf_mode);
ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
be_id, &cfg_data);
if (ret < 0)
@ -793,11 +799,12 @@ static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[3] = be_id;
ucontrol->value.integer.value[4] = cfg_data.copp_token;
ucontrol->value.integer.value[5] = cfg_data.bit_width;
ucontrol->value.integer.value[6] = cfg_data.copp_perf_mode;
pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d"
"sample_rate- %d copp_token- %d bit_width- %d\n",
"sample_rate- %d copp_token- %d bit_width- %d copp_perf_mode- %d\n",
__func__, fe_id, session_type, be_id,
cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate,
cfg_data.copp_token, cfg_data.bit_width);
cfg_data.copp_token, cfg_data.bit_width, cfg_data.copp_perf_mode);
done:
return ret;
}

214
asoc/msm-pcm-q6-v2.c Normal file → Executable file
View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
@ -128,6 +129,8 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
.mask = 0,
};
static struct asm_softvolume_params soft_params = {0,0,0};
struct msm_pcm_channel_map *chmap_pspd[MSM_FRONTEND_DAI_MM_SIZE][2];
static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
@ -150,6 +153,181 @@ static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
}
}
static int msm_pcm_set_soft_volume_params(struct msm_audio *prtd,struct asm_softvolume_params *soft_vol_params)
{
int rc = 0;
switch (prtd->audio_client->topology) {
default:
rc = q6asm_set_softvolume_v2(prtd->audio_client, soft_vol_params,
SOFT_VOLUME_INSTANCE_1);
if (rc < 0)
pr_err("%s: Send SoftVolume Param failed ret=%d\n",
__func__, rc);
}
return rc;
}
static int msm_pcm_soft_volume_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_pcm_soft_volume *soft_vol = (struct snd_pcm_soft_volume *) snd_kcontrol_chip(kcontrol);
struct msm_plat_data *pdata = NULL;
struct snd_pcm_substream *substream = NULL;
struct snd_soc_pcm_runtime *soc_prtd = NULL;
struct snd_soc_component *component = NULL;
pr_debug("%s\n", __func__);
if (!soft_vol || !soft_vol->pcm) {
pr_err("%s: soft vol is NULL\n", __func__);
return -ENODEV;
}
substream = soft_vol->pcm->streams[soft_vol->stream].substream;
if (!substream) {
pr_err("%s substream not found\n", __func__);
return -ENODEV;
}
soc_prtd = substream->private_data;
if (!soc_prtd) {
pr_err("%s substream runtime or private_data not found\n",
__func__);
return -ENODEV;
}
component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME);
if (!component || !component->dev) {
pr_err("%s: component is NULL\n", __func__);
return -ENODEV;
}
pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev);
if (!pdata) {
pr_err("%s: pdata not found\n", __func__);
return -ENODEV;
}
mutex_lock(&pdata->lock);
ucontrol->value.integer.value[0] = soft_params.period;
ucontrol->value.integer.value[1] = soft_params.step;
ucontrol->value.integer.value[2] = soft_params.rampingcurve;
pr_debug("%s: period = %d, step = %d , ramping curve: %d",__func__,
ucontrol->value.integer.value[0],
ucontrol->value.integer.value[1],
ucontrol->value.integer.value[2]);
mutex_unlock(&pdata->lock);
return 0;
}
static int msm_pcm_soft_volume_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int rc = 0;
struct snd_pcm_soft_volume *soft_vol = (struct snd_pcm_soft_volume *) snd_kcontrol_chip(kcontrol);
struct msm_plat_data *pdata = NULL;
struct snd_soc_pcm_runtime *soc_prtd = NULL;
struct snd_soc_component *component = NULL;
struct snd_pcm_substream *substream = NULL;
struct msm_audio *prtd;
if (!soft_vol || !soft_vol->pcm) {
pr_err("%s: soft vol is NULL\n", __func__);
return -ENODEV;
}
substream = soft_vol->pcm->streams[soft_vol->stream].substream;
if (!substream) {
pr_err("%s: substream not found\n", __func__);
return -ENODEV;
}
soc_prtd = substream->private_data;
if (!substream->runtime || !soc_prtd) {
pr_err("%s: substream runtime or private_data not found\n",
__func__);
return -ENODEV;
}
component = snd_soc_rtdcom_lookup(soc_prtd, DRV_NAME);
if (!component || !component->dev) {
pr_err("%s: component is NULL\n", __func__);
return -ENODEV;
}
pdata = (struct msm_plat_data *) dev_get_drvdata(component->dev);
if (!pdata) {
pr_err("%s: pdata not found\n", __func__);
return -ENODEV;
}
mutex_lock(&pdata->lock);
if (substream->ref_count > 0) {
prtd = substream->runtime->private_data;
if ( prtd) {
if ((ucontrol->value.integer.value[0] < 0) || (ucontrol->value.integer.value[0] > 15000)) {
pr_err("%s : Ramp period range (0 to 15000), input value is out of range: %d",__func__,soft_params.period);
goto exit;
} else {
soft_params.period = ucontrol->value.integer.value[0];
}
if ((ucontrol->value.integer.value[1] < 0) || (ucontrol->value.integer.value[1] > 15000000)) {
pr_err("%s : Ramp step range (0 to 15000000), input value is out of range: %d",__func__,soft_params.step);
goto exit;
} else {
soft_params.step = ucontrol->value.integer.value[1];
}
if ((ucontrol->value.integer.value[2] < 0) || (ucontrol->value.integer.value[2] >= SOFT_VOLUME_CURVE_ENUM_MAX)) {
pr_err("%s : Ramping curve range (0 to 2), input value is out of range: %d",__func__,soft_params.rampingcurve);
goto exit;
} else {
soft_params.rampingcurve = ucontrol->value.integer.value[2];
}
pr_debug("%s : soft vol params, period: %d, step: %d, ramp curve: %d",__func__,soft_params.period,
soft_params.step,soft_params.rampingcurve);
rc = msm_pcm_set_soft_volume_params(prtd, &soft_params);
} else {
pr_err("%s: prtd not found\n", __func__);
return -ENODEV;
}
} else {
pr_err("%s: substream ref count is invalid\n", __func__);
return -ENODEV;
}
exit:
mutex_unlock(&pdata->lock);
return rc;
}
static int msm_pcm_add_soft_volume_params_control(struct snd_soc_pcm_runtime *rtd, int stream)
{
int ret = 0;
struct snd_pcm *pcm = rtd->pcm;
struct snd_pcm_soft_volume *soft_vol = NULL;
struct snd_kcontrol *kctl = NULL;
dev_dbg(rtd->dev, "%s, volume control add\n", __func__);
ret = snd_pcm_add_soft_volume_ctls(pcm, stream,
NULL,/* 1,*/ rtd->dai_link->id,
&soft_vol);
if (ret < 0) {
pr_err("%s volume control failed ret %d\n", __func__, ret);
return ret;
}
kctl = soft_vol->kctl;
kctl->put = msm_pcm_soft_volume_ctl_put;
kctl->get = msm_pcm_soft_volume_ctl_get;
return 0;
}
static void event_handler(uint32_t opcode,
uint32_t token, uint32_t *payload, void *priv)
{
@ -2091,7 +2269,7 @@ static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
u64 fe_id = kcontrol->private_value;
int session_type = SESSION_TYPE_RX;
int be_id = ucontrol->value.integer.value[3];
struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0, 0};
struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0, 0, 0};
int ret = 0;
cfg_data.app_type = ucontrol->value.integer.value[0];
@ -2102,10 +2280,12 @@ static int msm_pcm_playback_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
cfg_data.copp_token = ucontrol->value.integer.value[4];
if (ucontrol->value.integer.value[5] != 0)
cfg_data.bit_width = ucontrol->value.integer.value[5];
if (ucontrol->value.integer.value[6] != 0)
cfg_data.copp_perf_mode = ucontrol->value.integer.value[6];
pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d"
"sample_rate- %d copp_token- %d bit_width- %d\n",
"sample_rate- %d copp_token- %d bit_width- %d copp_perf_mode- %d\n",
__func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id,
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width);
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width, cfg_data.copp_perf_mode);
ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
be_id, &cfg_data);
if (ret < 0)
@ -2138,10 +2318,11 @@ static int msm_pcm_playback_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[3] = be_id;
ucontrol->value.integer.value[4] = cfg_data.copp_token;
ucontrol->value.integer.value[5] = cfg_data.bit_width;
ucontrol->value.integer.value[6] = cfg_data.copp_perf_mode;
pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d"
"sample_rate- %d copp_token- %d bit_width- %d\n",
"sample_rate- %d copp_token- %d bit_width- %d copp_perf_mode- %d\n",
__func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id,
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width);
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width, cfg_data.copp_perf_mode);
done:
return ret;
}
@ -2152,7 +2333,7 @@ static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
u64 fe_id = kcontrol->private_value;
int session_type = SESSION_TYPE_TX;
int be_id = ucontrol->value.integer.value[3];
struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0, 0};
struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000, 0, 0, 0};
int ret = 0;
cfg_data.app_type = ucontrol->value.integer.value[0];
@ -2163,10 +2344,12 @@ static int msm_pcm_capture_app_type_cfg_ctl_put(struct snd_kcontrol *kcontrol,
cfg_data.copp_token = ucontrol->value.integer.value[4];
if (ucontrol->value.integer.value[5] != 0)
cfg_data.bit_width = ucontrol->value.integer.value[5];
if (ucontrol->value.integer.value[6] != 0)
cfg_data.copp_perf_mode = ucontrol->value.integer.value[6];
pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d"
"sample_rate- %d copp_token- %d bit_width- %d\n",
"sample_rate- %d copp_token- %d bit_width- %d copp_perf_mode- %d\n",
__func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id,
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width);
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width, cfg_data.copp_perf_mode);
ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
be_id, &cfg_data);
if (ret < 0)
@ -2199,10 +2382,11 @@ static int msm_pcm_capture_app_type_cfg_ctl_get(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[3] = be_id;
ucontrol->value.integer.value[4] = cfg_data.copp_token;
ucontrol->value.integer.value[5] = cfg_data.bit_width;
ucontrol->value.integer.value[6] = cfg_data.copp_perf_mode;
pr_debug("%s: fe_id- %llu session_type- %d be_id- %d app_type- %d acdb_dev_id- %d"
"sample_rate- %d copp_token- %d bit_width- %d\n",
"sample_rate- %d copp_token- %d bit_width- %d copp_perf_mode- %d\n",
__func__, fe_id, session_type, be_id, cfg_data.app_type, cfg_data.acdb_dev_id,
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width);
cfg_data.sample_rate, cfg_data.copp_token, cfg_data.bit_width, cfg_data.copp_perf_mode);
done:
return ret;
}
@ -3490,6 +3674,16 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
pr_err("%s: Could not add pcm Volume Control %d\n",
__func__, ret);
ret = msm_pcm_add_volume_control(rtd, SNDRV_PCM_STREAM_CAPTURE);
if (ret)
pr_err("%s: Could not add pcm Volume Control %d\n",
__func__, ret);
/* adding soft vol module params mixer control command*/
ret = msm_pcm_add_soft_volume_params_control(rtd, SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
pr_err("%s: Could not add pcm Volume Control %d\n",
__func__, ret);
ret = msm_pcm_add_soft_volume_params_control(rtd, SNDRV_PCM_STREAM_CAPTURE);
if (ret)
pr_err("%s: Could not add pcm Volume Control %d\n",
__func__, ret);

139
asoc/msm-pcm-routing-v2.c Executable file → Normal file
View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/init.h>
@ -181,6 +182,81 @@ static int msm_routing_send_device_pp_params(int port_id, int copp_idx,
static void msm_routing_load_topology(size_t data_size, void *data);
static void msm_routing_unload_topology(uint32_t topology_id);
static int pcm_soft_volume_ctl_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = SOFT_VOLUME_CURVE_ENUM_MAX;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = INT_MAX;
return 0;
}
static void pcm_soft_volume_ctl_private_free(struct snd_kcontrol *kcontrol)
{
struct snd_pcm_volume *info = snd_kcontrol_chip(kcontrol);
kfree(info);
}
int snd_pcm_add_soft_volume_ctls(struct snd_pcm *pcm, int stream,
const struct snd_pcm_soft_vol_usr_elem *soft_vol_params,
unsigned long private_value,
struct snd_pcm_soft_volume **info_ret)
{
int err = 0;
int size = 0;
struct snd_pcm_soft_volume *info;
struct snd_kcontrol_new knew = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = pcm_soft_volume_ctl_info,
};
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
info->pcm = pcm;
info->stream = stream;
info->usr_val = soft_vol_params;
size = sizeof("Playback ") + sizeof("Soft Vol Params") +
STRING_LENGTH_OF_INT*sizeof(char) + 1;
knew.name = kzalloc(size, GFP_KERNEL);
if (!knew.name) {
kfree(info);
return -ENOMEM;
}
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
snprintf((char *)knew.name, size, "%s %d %s",
"Playback ", pcm->device, "Soft Vol Params");
else
snprintf((char *)knew.name, size, "%s %d %s",
"Capture", pcm->device, "Soft Vol Params");
knew.device = pcm->device;
knew.count = pcm->streams[stream].substream_count;
knew.private_value = private_value;
info->kctl = snd_ctl_new1(&knew, info);
if (!info->kctl) {
kfree(info);
kfree(knew.name);
return -ENOMEM;
}
info->kctl->private_free = pcm_soft_volume_ctl_private_free;
err = snd_ctl_add(pcm->card, info->kctl);
if (err < 0) {
kfree(info);
kfree(knew.name);
return -ENOMEM;
}
if (info_ret)
*info_ret = info;
kfree(knew.name);
return 0;
}
EXPORT_SYMBOL(snd_pcm_add_soft_volume_ctls);
#ifndef SND_PCM_ADD_VOLUME_CTL
static int pcm_volume_ctl_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
@ -1283,6 +1359,30 @@ static bool is_mm_lsm_fe_id(int fe_id)
return rc;
}
static int get_copp_perf_mode(int fe_id, int sess_type, int port)
{
int fdai_mode, copp_perf_mode, flag, value;
int rc = 0;
if ((fe_id < 0) || (fe_id >= MSM_FRONTEND_DAI_MAX) ||
(port < 0) || (port >= MSM_BACKEND_DAI_MAX) ||
(sess_type != SESSION_TYPE_RX && sess_type != SESSION_TYPE_TX)) {
pr_err("%s: Input out of bounds\n", __func__);
return rc;
}
fdai_mode = fe_dai_map[fe_id][sess_type].perf_mode;
copp_perf_mode = fe_dai_app_type_cfg[fe_id][sess_type][port].copp_perf_mode;
flag = (copp_perf_mode & PP_PERF_MODE_FLAG_MASK);
value = (copp_perf_mode & PP_PERF_MODE_VALUE_MASK);
rc = fdai_mode;
if ((flag != 0) && (value >= LEGACY_PCM_MODE) &&
(value <= ULL_POST_PROCESSING_PCM_MODE)) {
rc = value;
}
pr_debug("%s: Get copp_perf_mode = %d", __func__, rc);
return rc;
}
/*
* msm_pcm_routing_send_chmix_cfg:
* send the channel mixer command to mix the input channels
@ -1476,11 +1576,11 @@ int msm_pcm_routing_reg_stream_app_type_cfg(
}
pr_debug("%s: fedai_id %d, session_type %d, be_id %d, app_type %d, acdb_dev_id %d,"
"sample_rate %d, copp_token %d, bit_width %d\n",
"sample_rate %d, copp_token %d, bit_width %d, copp_perf_mode %d\n",
__func__, fedai_id, session_type, be_id,
cfg_data->app_type, cfg_data->acdb_dev_id,
cfg_data->sample_rate, cfg_data->copp_token,
cfg_data->bit_width);
cfg_data->bit_width, cfg_data->copp_perf_mode);
if (!is_mm_lsm_fe_id(fedai_id)) {
pr_err("%s: Invalid machine driver ID %d\n",
@ -1564,11 +1664,11 @@ int msm_pcm_routing_get_stream_app_type_cfg(
*bedai_id = be_id;
*cfg_data = fe_dai_app_type_cfg[fedai_id][session_type][be_id];
pr_debug("%s: fedai_id %d, session_type %d, be_id %d, app_type %d, acdb_dev_id %d,"
"sample_rate %d, copp_token %d, bit_width %d\n",
"sample_rate %d, copp_token %d, bit_width %d, copp_perf_mode %d\n",
__func__, fedai_id, session_type, *bedai_id,
cfg_data->app_type, cfg_data->acdb_dev_id,
cfg_data->sample_rate, cfg_data->copp_token,
cfg_data->bit_width);
cfg_data->bit_width, cfg_data->copp_perf_mode);
done:
return ret;
}
@ -1906,6 +2006,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
u16 bit_width = 16, be_bit_width;
bool is_lsm;
uint32_t copp_token = 0;
int copp_perf_mode = 0;
pr_debug("%s:fe_id[%d] perf_mode[%d] id[%d] stream_type[%d] passt[%d]",
__func__, fe_id, perf_mode, dspst_id,
@ -1999,6 +2100,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
}
acdb_dev_id =
fe_dai_app_type_cfg[fe_id][session_type][i].acdb_dev_id;
copp_perf_mode = get_copp_perf_mode(fe_id, session_type, i);
topology = msm_routing_get_adm_topology(fe_id,
session_type,
i);
@ -2020,7 +2122,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
SNDRV_PCM_FORMAT_S32_LE);
copp_idx =
adm_open(port_id, path_type, sample_rate,
channels, topology, perf_mode,
channels, topology, copp_perf_mode,
bit_width, app_type, acdb_dev_id,
session_type, passthr_mode, copp_token);
if ((copp_idx < 0) ||
@ -2308,6 +2410,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
uint32_t passthr_mode = LEGACY_PCM;
int ret = 0;
uint32_t copp_token = 0;
int copp_perf_mode = 0;
if (fedai_id >= MSM_FRONTEND_DAI_MM_MAX_ID) {
/* bad ID assigned in machine driver */
@ -2380,7 +2483,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
i);
be_bit_width = msm_routing_get_bit_width(
msm_bedais[i].format);
copp_perf_mode = get_copp_perf_mode(fedai_id, session_type, i);
if (hifi_filter_enabled && (msm_bedais[i].sample_rate ==
384000 ||msm_bedais[i].sample_rate == 352800)
&& be_bit_width == 32)
@ -2403,7 +2506,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
copp_idx = adm_open_v2(port_id, path_type,
sample_rate, channels, topology,
perf_mode, bits_per_sample,
copp_perf_mode, bits_per_sample,
app_type, acdb_dev_id,
session_type, passthr_mode,
copp_token,
@ -2414,7 +2517,7 @@ int msm_pcm_routing_reg_phy_stream(int fedai_id, int perf_mode,
} else
copp_idx = adm_open(port_id, path_type,
sample_rate, channels, topology,
perf_mode, bits_per_sample,
copp_perf_mode, bits_per_sample,
app_type, acdb_dev_id,
session_type, passthr_mode, copp_token);
if ((copp_idx < 0) ||
@ -2495,6 +2598,7 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
{
int i, port_type, session_type, path_type, topology, port_id;
struct msm_pcm_routing_fdai_data *fdai;
int copp_perf_mode;
if (!is_mm_lsm_fe_id(fedai_id)) {
/* bad ID assigned in machine driver */
@ -2536,7 +2640,8 @@ void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
topology = adm_get_topology_for_port_copp_idx(
port_id, idx);
msm_routing_unload_topology(topology);
adm_close(port_id, fdai->perf_mode, idx);
copp_perf_mode = get_copp_perf_mode(fedai_id, session_type, i);
adm_close(port_id, copp_perf_mode, idx);
pr_debug("%s:copp:%ld,idx bit fe:%d,type:%d,be:%d\n",
__func__, copp, fedai_id, session_type, i);
clear_bit(idx,
@ -2580,6 +2685,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
uint32_t passthr_mode;
bool is_lsm;
uint32_t copp_token = 0;
int copp_perf_mode = 0;
pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
@ -2694,6 +2800,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
be_bit_width = msm_routing_get_bit_width(
msm_bedais[reg].format);
copp_perf_mode = get_copp_perf_mode(val, session_type, reg);
if (hifi_filter_enabled && (msm_bedais[reg].sample_rate
== 384000 ||msm_bedais[reg].sample_rate ==
352800) && be_bit_width == 32)
@ -2701,7 +2808,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
SNDRV_PCM_FORMAT_S32_LE);
copp_idx = adm_open(port_id, path_type,
sample_rate, channels, topology,
fdai->perf_mode, bits_per_sample,
copp_perf_mode, bits_per_sample,
app_type, acdb_dev_id,
session_type, passthr_mode, copp_token);
if ((copp_idx < 0) ||
@ -2762,7 +2869,8 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
topology = adm_get_topology_for_port_copp_idx(port_id,
idx);
msm_routing_unload_topology(topology);
adm_close(port_id, fdai->perf_mode, idx);
copp_perf_mode = get_copp_perf_mode(val, session_type, reg);
adm_close(port_id, copp_perf_mode, idx);
pr_debug("%s: copp: %ld, reset idx bit fe:%d, type: %d, be:%d topology=0x%x\n",
__func__, copp, val, session_type, reg,
topology);
@ -41329,6 +41437,7 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
int i, session_type, path_type, topology;
struct msm_pcm_routing_bdai_data *bedai;
struct msm_pcm_routing_fdai_data *fdai;
int copp_perf_mode;
pr_debug("%s: substream->pcm->id:%s\n",
__func__, substream->pcm->id);
@ -41370,7 +41479,8 @@ static int msm_pcm_routing_close(struct snd_pcm_substream *substream)
topology = adm_get_topology_for_port_copp_idx(port_id,
idx);
msm_routing_unload_topology(topology);
adm_close(port_id, fdai->perf_mode, idx);
copp_perf_mode = get_copp_perf_mode(i, session_type, be_id);
adm_close(port_id, copp_perf_mode, idx);
pr_debug("%s: copp:%ld,idx bit fe:%d, type:%d,be:%d topology=0x%x\n",
__func__, copp, i, session_type, be_id,
topology);
@ -41405,6 +41515,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
struct media_format_info voc_be_media_format;
bool is_lsm;
uint32_t copp_token = 0;
int copp_perf_mode = 0;
pr_debug("%s: substream->pcm->id:%s\n",
__func__, substream->pcm->id);
@ -41515,7 +41626,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
be_bit_width = msm_routing_get_bit_width(
bedai->format);
copp_perf_mode = get_copp_perf_mode(i, session_type, be_id);
if (hifi_filter_enabled && (bedai->sample_rate == 384000
|| bedai->sample_rate == 352800) &&
be_bit_width == 32)
@ -41523,7 +41634,7 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
SNDRV_PCM_FORMAT_S32_LE);
copp_idx = adm_open(port_id, path_type,
sample_rate, channels, topology,
fdai->perf_mode, bits_per_sample,
copp_perf_mode, bits_per_sample,
app_type, acdb_dev_id,
session_type, fdai->passthr_mode, copp_token);
if ((copp_idx < 0) ||

24
asoc/msm-pcm-routing-v2.h Normal file → Executable file
View file

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _MSM_PCM_ROUTING_H
#define _MSM_PCM_ROUTING_H
@ -688,6 +689,8 @@ enum {
#define STREAM_TYPE_ASM 0
#define STREAM_TYPE_LSM 1
#define PP_PERF_MODE_FLAG_MASK 0x10000
#define PP_PERF_MODE_VALUE_MASK 0xF
enum {
ADM_TOPOLOGY_CAL_TYPE_IDX = 0,
ADM_LSM_TOPOLOGY_CAL_TYPE_IDX,
@ -743,6 +746,7 @@ struct msm_pcm_stream_app_type_cfg {
int sample_rate;
uint32_t copp_token;
int bit_width;
int copp_perf_mode;
};
/* dai_id: front-end ID,
@ -796,6 +800,26 @@ int msm_pcm_routing_set_channel_mixer_runtime(
int msm_pcm_routing_set_stream_ec_ref_chmix_cfg(
int fedai_id, struct msm_pcm_channel_mixer *cfg_data);
/* array element of usr elem */
struct snd_pcm_soft_vol_usr_elem {
int val[3];
};
/* mixer control information; retrieved via snd_kcontrol_chip() */
struct snd_pcm_soft_volume {
struct snd_pcm *pcm; /* assigned PCM instance */
int stream; /* PLAYBACK or CAPTURE */
struct snd_kcontrol *kctl; /* contorl handle*/
const struct snd_pcm_soft_vol_usr_elem *usr_val;
int max_length;
void *private_data;
};
int snd_pcm_add_soft_volume_ctls(struct snd_pcm *pcm, int stream,
const struct snd_pcm_soft_vol_usr_elem *soft_vol_params,
unsigned long private_value,
struct snd_pcm_soft_volume **info_ret);
#ifndef SND_PCM_ADD_VOLUME_CTL
/* PCM Volume control API
*/

View file

@ -1305,82 +1305,112 @@ SND_SOC_DAILINK_DEFS(ext_display_port,
"msm_dp_audio_codec_rx_dai")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(tert_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(tert_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(quat_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(quat_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(lpass_be_auxpcm_rx_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(lpass_be_auxpcm_tx_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(primary_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(primary_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(secondary_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(secondary_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(tert_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(tert_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(quat_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(quat_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(quin_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(quin_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(sen_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(sen_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(sep_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(sep_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(hs_if0_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(hs_if0_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(hs_if1_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(hs_if1_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(hs_if2_tdm_rx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));
SND_SOC_DAILINK_DEFS(hs_if2_tdm_tx_0_dummy,
DAILINK_COMP_ARRAY(COMP_CPU("snd-soc-dummy-dai")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("snd-soc-dummy")));

1500
asoc/msm_talos_dailink.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk.h>
#include <linux/delay.h>
@ -7065,6 +7066,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
if (++mi2s_intf_conf[index].ref_cnt == 1) {
if (data_format == AFE_DSD_DATA)
fmt = SND_SOC_DAIFMT_CBM_CFS;
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) {
dev_err(rtd->card->dev,
@ -7101,11 +7105,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
}
}
}
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",

View file

@ -1,4 +1,5 @@
/* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/*
* Copyright 2011, The Android Open Source Project
@ -5037,6 +5038,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
intf_conf = &pdata->mi2s_intf_conf[index];
mutex_lock(&intf_conf->lock);
if (++intf_conf->ref_cnt == 1) {
/* Check if msm needs to provide the clock to the interface */
if (!intf_conf->msm_is_mi2s_master)
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) {
dev_err(rtd->card->dev,
@ -5054,11 +5058,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
__func__, ret_pinctrl);
}
}
/* Check if msm needs to provide the clock to the interface */
if (!intf_conf->msm_is_mi2s_master) {
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
if (!intf_conf->msm_is_mi2s_master)
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/*
* Copyright 2011, The Android Open Source Project
@ -7427,6 +7428,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
intf_conf = &pdata->mi2s_intf_conf[index];
mutex_lock(&intf_conf->lock);
if (++intf_conf->ref_cnt == 1) {
/* Check if msm needs to provide the clock to the interface */
if (!intf_conf->msm_is_mi2s_master)
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) {
dev_err(rtd->card->dev,
@ -7444,11 +7448,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
__func__, ret_pinctrl);
}
}
/* Check if msm needs to provide the clock to the interface */
if (!intf_conf->msm_is_mi2s_master) {
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
if (!intf_conf->msm_is_mi2s_master)
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk.h>
@ -4852,6 +4853,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
*/
mutex_lock(&mi2s_intf_conf[index].lock);
if (++mi2s_intf_conf[index].ref_cnt == 1) {
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
ret = msm_mi2s_set_sclk(substream, true);
if (ret < 0) {
dev_err(rtd->card->dev,
@ -4868,11 +4872,8 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
__func__, ret_pinctrl);
}
}
/* Check if msm needs to provide the clock to the interface */
if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
if (!mi2s_intf_conf[index].msm_is_mi2s_master)
fmt = SND_SOC_DAIFMT_CBM_CFM;
}
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
if (ret < 0) {
pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",

127
asoc/talos-port-config.h Normal file
View file

@ -0,0 +1,127 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _TALOS_PORT_CONFIG
#define _TALOS_PORT_CONFIG
#include <soc/swr-common.h>
#define WSA_MSTR_PORT_MASK 0xFF
/*
* Add port configuration in the format
*{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl, dir,
* stream_type}
*/
static struct port_params wsa_frame_params_default[SWR_MSTR_PORT_LEN] = {
{7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{63, 12, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{63, 13, 31, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
};
static struct port_params wsa_frame_params_receiver[SWR_MSTR_PORT_LEN] = {
{3, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{31, 2, 3, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF, 0x00, 0x00},
{63, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{3, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{63, 13, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF, 0x00, 0x00},
{15, 3, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
{15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00},
};
static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00},
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x00},
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x00},
{7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0, 0x00, 0x00},
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0, 0x00, 0x00},
};
/* Headset + PCM Haptics */
static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x00}, /* HPH_CLH */
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x00}, /* HPH_CMP */
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* LO/AUX */
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00}, /* DSD */
{0x18F, 0, 0, 0x8, 0x8, 0x0F, 0x00, 0, 0, 0x00, 0x01}, /* PCM_OUT */
};
/* Headset(44.1K) + PCM Haptics */
static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */
{63, 0, 0, 3, 6, 7, 0, 0xFF, 0, 0x00, 0x00}, /* HPH_CLH */
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0, 0x00, 0x00}, /* HPH_CMP */
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0, 0x00, 0x00}, /* LO/AUX */
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0x00, 0x00}, /* DSD */
{0x1FF, 0, 0, 0x8, 0x8, 0x0F, 0, 0, 0, 0x00, 0x01}, /* PCM_OUT */
};
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX2 */
{7, 5, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
/* 4.8 MHz clock */
static struct port_params tx_frame_params_4p8MHz[SWR_MSTR_PORT_LEN] = {
{15, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX2 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
/* 0.6 MHz clock */
static struct port_params tx_frame_params_0p6MHz[SWR_MSTR_PORT_LEN] = {
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
};
static struct swr_mstr_port_map sm_port_map[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{TX_MACRO, SWR_UC1, tx_frame_params_4p8MHz},
{TX_MACRO, SWR_UC2, tx_frame_params_0p6MHz},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
{WSA_MACRO, SWR_UC1, wsa_frame_params_default},
};
static struct swr_mstr_port_map sm_port_map_tavil[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{TX_MACRO, SWR_UC1, tx_frame_params_4p8MHz},
{TX_MACRO, SWR_UC2, tx_frame_params_0p6MHz},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
{WSA_MACRO, SWR_UC1, wsa_frame_params_default},
};
static struct swr_mstr_port_map sm_port_map_tasha[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{TX_MACRO, SWR_UC1, tx_frame_params_4p8MHz},
{TX_MACRO, SWR_UC2, tx_frame_params_0p6MHz},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
{WSA_MACRO, SWR_UC1, wsa_frame_params_default},
};
static struct swr_mstr_port_map sm_port_map_tavil_wsa[] = {
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
};
#endif /* _TALOS_PORT_CONFIG */

View file

@ -3,6 +3,7 @@ CONFIG_AUDIO_EXT_CLK=m
CONFIG_SND_SOC_WCD9XXX_V2=m
CONFIG_SND_SOC_WCD_MBHC=m
CONFIG_SND_SOC_WSA881X_ANALOG=m
CONFIG_WSA881X_TEMP_SENSOR_DISABLE=m
CONFIG_WCD9XXX_CODEC_CORE_V2=m
CONFIG_MSM_CDC_PINCTRL=m
CONFIG_MSM_QDSP6V2_CODECS=m

View file

@ -1,5 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
/* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the
* disclaimer below) provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of Qualcomm Innovation Center, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
* GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
* HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define CONFIG_PINCTRL_LPI 1
@ -7,6 +41,7 @@
#define CONFIG_SND_SOC_WCD9XXX_V2 1
#define CONFIG_SND_SOC_WCD_MBHC 1
#define CONFIG_SND_SOC_WSA881X_ANALOG 1
#define CONFIG_WSA881X_TEMP_SENSOR_DISABLE 1
#define CONFIG_WCD9XXX_CODEC_CORE_V2 1
#define CONFIG_MSM_CDC_PINCTRL 1
#define CONFIG_MSM_QDSP6V2_CODECS 1

View file

@ -1,48 +1,48 @@
CONFIG_PINCTRL_WCD=m
CONFIG_PINCTRL_LPI=m
CONFIG_AUDIO_EXT_CLK=m
CONFIG_SND_SOC_WCD9XXX_V2=m
CONFIG_SND_SOC_WCD_MBHC=m
CONFIG_SND_SOC_WSA881X=m
CONFIG_SND_SOC_WCD_DSP_MGR=m
CONFIG_SND_SOC_WCD_SPI=m
CONFIG_SND_SOC_WCD934X=m
CONFIG_SND_SOC_WCD934X_MBHC=m
CONFIG_SND_SOC_WCD934X_DSD=m
CONFIG_WCD9XXX_CODEC_CORE=m
CONFIG_MSM_CDC_PINCTRL=m
CONFIG_MSM_QDSP6V2_CODECS=m
CONFIG_MSM_ULTRASOUND=m
CONFIG_MSM_QDSP6_APRV2_RPMSG=m
CONFIG_MSM_ADSP_LOADER=m
CONFIG_REGMAP_SWR=m
CONFIG_MSM_QDSP6_SSR=m
CONFIG_MSM_QDSP6_PDR=m
CONFIG_MSM_QDSP6_NOTIFIER=m
CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m
CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m
CONFIG_SND_SOC_SM6150=m
CONFIG_MSM_GLINK_SPI_XPRT=m
CONFIG_WCD_DSP_GLINK=m
CONFIG_SOUNDWIRE=m
CONFIG_SOUNDWIRE_MSTR_CTRL=m
CONFIG_SND_SOC_QDSP6V2=m
CONFIG_SND_SOC_WCD_MBHC_ADC=m
CONFIG_QTI_PP=m
CONFIG_SND_HWDEP_ROUTING=m
CONFIG_DTS_EAGLE=m
CONFIG_DOLBY_DS2=m
CONFIG_DOLBY_LICENSE=m
CONFIG_DTS_SRS_TM=m
CONFIG_SND_SOC_MSM_STUB=m
CONFIG_MSM_AVTIMER=m
CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
CONFIG_SND_SOC_BOLERO=m
CONFIG_WSA_MACRO=m
CONFIG_VA_MACRO=m
CONFIG_RX_MACRO=m
CONFIG_TX_MACRO=m
CONFIG_SND_SOC_WCD_IRQ=m
CONFIG_SND_SOC_WCD937X=m
CONFIG_SND_SOC_WCD937X_SLAVE=m
CONFIG_SND_EVENT=m
export CONFIG_PINCTRL_WCD=m
export CONFIG_PINCTRL_LPI=m
export CONFIG_AUDIO_EXT_CLK=m
export CONFIG_SND_SOC_WCD9XXX_V2=m
export CONFIG_SND_SOC_WCD_MBHC=m
export CONFIG_SND_SOC_WSA881X=m
export CONFIG_SND_SOC_WCD_DSP_MGR=m
export CONFIG_SND_SOC_WCD_SPI=m
export CONFIG_SND_SOC_WCD934X=m
export CONFIG_SND_SOC_WCD934X_MBHC=m
export CONFIG_SND_SOC_WCD934X_DSD=m
export CONFIG_WCD9XXX_CODEC_CORE=m
export CONFIG_MSM_CDC_PINCTRL=m
export CONFIG_MSM_QDSP6V2_CODECS=m
export CONFIG_MSM_ULTRASOUND=m
export CONFIG_MSM_QDSP6_APRV2_RPMSG=m
export CONFIG_MSM_ADSP_LOADER=m
export CONFIG_REGMAP_SWR=m
export CONFIG_MSM_QDSP6_SSR=m
export CONFIG_MSM_QDSP6_PDR=m
export CONFIG_MSM_QDSP6_NOTIFIER=m
export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m
export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m
export CONFIG_SND_SOC_SM6150=m
export CONFIG_MSM_GLINK_SPI_XPRT=m
export CONFIG_WCD_DSP_GLINK=m
export CONFIG_SOUNDWIRE=m
export CONFIG_SOUNDWIRE_MSTR_CTRL=m
export CONFIG_SND_SOC_QDSP6V2=m
export CONFIG_SND_SOC_WCD_MBHC_ADC=m
export CONFIG_QTI_PP=m
export CONFIG_SND_HWDEP_ROUTING=m
export CONFIG_DTS_EAGLE=m
export CONFIG_DOLBY_DS2=m
export CONFIG_DOLBY_LICENSE=m
export CONFIG_DTS_SRS_TM=m
export CONFIG_SND_SOC_MSM_STUB=m
export CONFIG_MSM_AVTIMER=m
export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
export CONFIG_SND_SOC_BOLERO=m
export CONFIG_WSA_MACRO=m
export CONFIG_VA_MACRO=m
export CONFIG_RX_MACRO=m
export CONFIG_TX_MACRO=m
export CONFIG_SND_SOC_WCD_IRQ=m
export CONFIG_SND_SOC_WCD937X=m
export CONFIG_SND_SOC_WCD937X_SLAVE=m
export CONFIG_SND_EVENT=m

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/debugfs.h>
@ -9792,7 +9793,6 @@ static int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg,
dyn_mclk_cfg.clk_id = cfg->clk_id;
dyn_mclk_cfg.clk_attri = cfg->clk_attri;
dyn_mclk_cfg.enable = cfg->enable;
pr_debug("%s: Minor version =0x%x clk id = %d\n", __func__,
dyn_mclk_cfg.clk_set_minor_version, dyn_mclk_cfg.clk_id);
pr_debug("%s: clk freq (Hz) = %d, clk attri = 0x%x\n", __func__,
@ -9831,6 +9831,83 @@ stop_mclk:
return ret;
}
int afe_set_lpass_clk_cfg_ext_mclk_v2(int index, struct afe_param_id_clock_set_v2_t *dyn_mclk_cfg,
uint32_t mclk_freq)
{
struct param_hdr_v3 param_hdr;
int ret = 0;
if (!dyn_mclk_cfg) {
pr_err("%s: clock cfg is NULL\n", __func__);
ret = -EINVAL;
return ret;
}
if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: index[%d] invalid!\n", __func__, index);
return -EINVAL;
}
memset(&param_hdr, 0, sizeof(param_hdr));
param_hdr.module_id = AFE_MODULE_CLOCK_SET;
param_hdr.instance_id = INSTANCE_ID_0;
param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET_V2;
param_hdr.param_size = sizeof(struct afe_param_id_clock_set_v2_t);
if (afe_ext_mclk.ext_mclk_cb) {
ret = afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data,
dyn_mclk_cfg->enable, mclk_freq, dyn_mclk_cfg);
if (ret) {
pr_err_ratelimited("%s: get mclk cfg failed %d\n",
__func__, ret);
return ret;
}
} else {
pr_err_ratelimited("%s: mclk callback not registered\n", __func__);
return -EINVAL;
}
dyn_mclk_cfg->clk_set_minor_version = 1;
pr_debug("%s: Minor version =0x%x clk id = %d\n", __func__,
dyn_mclk_cfg->clk_set_minor_version, dyn_mclk_cfg->clk_id);
pr_debug("%s: clk freq (Hz) = %d, clk attri = 0x%x\n", __func__,
dyn_mclk_cfg->clk_freq_in_hz, dyn_mclk_cfg->clk_attri);
pr_debug("%s: clk root = 0x%x clk enable = 0x%x\n", __func__,
dyn_mclk_cfg->clk_root, dyn_mclk_cfg->enable);
pr_debug("%s: divider_2x =%d m = %d n = %d, d =%d\n", __func__,
dyn_mclk_cfg->divider_2x, dyn_mclk_cfg->m, dyn_mclk_cfg->n,
dyn_mclk_cfg->d);
ret = afe_q6_interface_prepare();
if (ret != 0) {
pr_err_ratelimited("%s: Q6 interface prepare failed %d\n",
__func__, ret);
goto stop_mclk;
}
mutex_lock(&this_afe.afe_cmd_lock);
ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
(u8 *) dyn_mclk_cfg);
if (ret < 0)
pr_err_ratelimited("%s: ext MCLK clk cfg failed with ret %d\n",
__func__, ret);
mutex_unlock(&this_afe.afe_cmd_lock);
if (ret >= 0)
return ret;
stop_mclk:
if (afe_ext_mclk.ext_mclk_cb && dyn_mclk_cfg->enable) {
afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data,
dyn_mclk_cfg->enable, mclk_freq, dyn_mclk_cfg);
}
return ret;
}
EXPORT_SYMBOL(afe_set_lpass_clk_cfg_ext_mclk_v2);
/**
* afe_set_lpass_clk_cfg - Set AFE clk config
*

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
@ -12209,6 +12210,9 @@ struct afe_param_id_clip_bank_sel {
/* Supported LPASS CLK root*/
#define Q6AFE_LPASS_CLK_ROOT_DEFAULT 0
#define Q6AFE_LPASS_MCLK_IN0 1
#define Q6AFE_LPASS_MCLK_IN1 2
enum afe_lpass_clk_mode {
Q6AFE_LPASS_MODE_BOTH_INVALID,
Q6AFE_LPASS_MODE_CLK1_VALID,
@ -12362,6 +12366,8 @@ enum afe_lpass_clk_mode {
/* Clock ID for AHB HDMI input */
#define Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT 0x400
#define Q6AFE_LPASS_CLK_ID_SPDIF_CORE 0x000
/* Clock ID for the primary SPDIF output core. */
#define AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE 0x500
/* Clock ID for the secondary SPDIF output core. */
@ -12448,6 +12454,12 @@ struct afe_clk_set {
#define AFE_PARAM_ID_CLOCK_SET_V2 0x000102E6
#define AFE_CLOCK_SET_CLOCK_ROOT_DEFAULT 0x2
#define AFE_CLOCK_DEFAULT_INTEGER_DIVIDER 0x0
#define AFE_CLOCK_DEFAULT_M_VALUE 0x1
#define AFE_CLOCK_DEFAULT_N_VALUE 0x2
#define AFE_CLOCK_DEFAULT_D_VALUE 0x1
#define AFE_API_VERSION_CLOCK_SET_V2 0x1
struct afe_param_id_clock_set_v2_t {

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __Q6AFE_V2_H__
#define __Q6AFE_V2_H__
@ -592,6 +593,8 @@ int afe_port_send_logging_cfg(u16 port_id,
struct afe_param_id_port_data_log_disable_t *log_disable);
int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
u16 port);
int afe_set_lpass_clk_cfg_ext_mclk_v2(int index,
struct afe_param_id_clock_set_v2_t *dyn_mclk_cfg, uint32_t mclk_freq);
int afe_get_sp_rx_tmax_xmax_logging_data(
struct afe_sp_rx_tmax_xmax_logging_param *xt_logging,
u16 port_id);

2
include/dsp/q6asm-v2.h Normal file → Executable file
View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2012-2019, 2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __Q6_ASM_V2_H__
#define __Q6_ASM_V2_H__
@ -150,6 +151,7 @@ enum {
SOFT_VOLUME_CURVE_LINEAR = 0,
SOFT_VOLUME_CURVE_EXP,
SOFT_VOLUME_CURVE_LOG,
SOFT_VOLUME_CURVE_ENUM_MAX,
};
#define SOFT_VOLUME_INSTANCE_1 1

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/irq.h>
@ -1464,12 +1465,14 @@ static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
SWRS_DP_SAMPLE_CONTROL_1_BANK(slv_id,
bank));
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(
if ((port_req->sinterval >> 8)& 0xFF) {
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(
(port_req->sinterval >> 8)& 0xFF,
port_req->dev_num, 0x00,
SWRS_DP_SAMPLE_CONTROL_2_BANK(slv_id,
bank));
}
reg[len] = SWRM_CMD_FIFO_WR_CMD;
val[len++] = SWR_REG_VAL_PACK(port_req->offset1,