asoc: kona: Add support for channel map mixer control
Add new mixer control to get channel map associated with codec for Slimbus and Codec DMA interface. Change-Id: Ie38c5b05a2a371a7f3801b1ab194546b39b5a3d6 Signed-off-by: Rohit kumar <rohitkr@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
de3e09d08d
commit
ca765db76b
102
asoc/kona.c
102
asoc/kona.c
@@ -14,6 +14,7 @@
|
|||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/soc/qcom/fsa4480-i2c.h>
|
#include <linux/soc/qcom/fsa4480-i2c.h>
|
||||||
|
#include <sound/control.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
#include <sound/soc-dapm.h>
|
#include <sound/soc-dapm.h>
|
||||||
@@ -114,19 +115,6 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = {
|
|||||||
.moisture_duty_cycle_en = true,
|
.moisture_duty_cycle_en = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
|
||||||
struct snd_pcm_hw_params *params)
|
|
||||||
{
|
|
||||||
struct snd_soc_dai_link *dai_link = rtd->dai_link;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
pr_debug("%s: dai_id= %d, format = %d, rate = %d\n",
|
|
||||||
__func__, dai_link->id, params_format(params),
|
|
||||||
params_rate(params));
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, bool active)
|
static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, bool active)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = component->card;
|
struct snd_soc_card *card = component->card;
|
||||||
@@ -371,6 +359,7 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
bolero_info_create_codec_entry(pdata->codec_root, component);
|
bolero_info_create_codec_entry(pdata->codec_root, component);
|
||||||
bolero_register_wake_irq(component, false);
|
bolero_register_wake_irq(component, false);
|
||||||
codec_reg_done = true;
|
codec_reg_done = true;
|
||||||
|
msm_common_dai_link_init(rtd);
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
@@ -410,9 +399,15 @@ static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
|
unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
|
||||||
unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160};
|
unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160};
|
||||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
|
ret = snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
|
||||||
tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
|
tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
msm_common_dai_link_init(rtd);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct snd_soc_ops msm_common_be_ops = {
|
static struct snd_soc_ops msm_common_be_ops = {
|
||||||
@@ -434,7 +429,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.init = &msm_int_audrx_init,
|
.init = &msm_int_audrx_init,
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
/* this dainlink has playback support */
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
@@ -450,7 +444,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "wsa_macro_rx_mix",
|
.codec_dai_name = "wsa_macro_rx_mix",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
/* this dainlink has playback support */
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
@@ -466,10 +459,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "wsa_macro_echo",
|
.codec_dai_name = "wsa_macro_echo",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_RX_CDC_DMA_RX_0,
|
.name = LPASS_BE_RX_CDC_DMA_RX_0,
|
||||||
@@ -482,7 +472,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "rx_macro_rx1",
|
.codec_dai_name = "rx_macro_rx1",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
/* this dainlink has playback support */
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
@@ -498,7 +487,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "rx_macro_rx2",
|
.codec_dai_name = "rx_macro_rx2",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
/* this dainlink has playback support */
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
@@ -514,7 +502,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "rx_macro_rx3",
|
.codec_dai_name = "rx_macro_rx3",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
/* this dainlink has playback support */
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
@@ -530,7 +517,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "rx_macro_rx4",
|
.codec_dai_name = "rx_macro_rx4",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
/* this dainlink has playback support */
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
@@ -546,10 +532,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "tx_macro_tx1",
|
.codec_dai_name = "tx_macro_tx1",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_TX_CDC_DMA_TX_4,
|
.name = LPASS_BE_TX_CDC_DMA_TX_4,
|
||||||
@@ -562,10 +545,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "tx_macro_tx2",
|
.codec_dai_name = "tx_macro_tx2",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_VA_CDC_DMA_TX_0,
|
.name = LPASS_BE_VA_CDC_DMA_TX_0,
|
||||||
@@ -578,10 +558,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "va_macro_tx1",
|
.codec_dai_name = "va_macro_tx1",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_VA_CDC_DMA_TX_1,
|
.name = LPASS_BE_VA_CDC_DMA_TX_1,
|
||||||
@@ -594,10 +571,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "va_macro_tx2",
|
.codec_dai_name = "va_macro_tx2",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_VA_CDC_DMA_TX_2,
|
.name = LPASS_BE_VA_CDC_DMA_TX_2,
|
||||||
@@ -610,10 +584,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.codec_dai_name = "va_macro_tx3",
|
.codec_dai_name = "va_macro_tx3",
|
||||||
.codec_name = "bolero_codec",
|
.codec_name = "bolero_codec",
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_SLIMBUS_7_RX,
|
.name = LPASS_BE_SLIMBUS_7_RX,
|
||||||
@@ -629,6 +600,7 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
/* this dainlink has playback support */
|
/* this dainlink has playback support */
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
|
.init = &msm_wcn_init,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_SLIMBUS_7_TX,
|
.name = LPASS_BE_SLIMBUS_7_TX,
|
||||||
@@ -642,8 +614,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
.codec_dai_name = "btfm_bt_sco_slim_tx",
|
.codec_dai_name = "btfm_bt_sco_slim_tx",
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
.init = &msm_wcn_init,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = LPASS_BE_DISPLAY_PORT_RX,
|
.name = LPASS_BE_DISPLAY_PORT_RX,
|
||||||
@@ -669,7 +639,6 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||||||
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
|
||||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||||
SND_SOC_DPCM_TRIGGER_POST},
|
SND_SOC_DPCM_TRIGGER_POST},
|
||||||
.ignore_pmdown_time = 1,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
.ops = &msm_common_be_ops,
|
.ops = &msm_common_be_ops,
|
||||||
},
|
},
|
||||||
@@ -705,53 +674,8 @@ static int msm_populate_dai_link_component_of_node(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < card->num_links; i++) {
|
for (i = 0; i < card->num_links; i++) {
|
||||||
if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
|
if (dai_link[i].init == NULL)
|
||||||
continue;
|
dai_link[i].init = &msm_common_dai_link_init;
|
||||||
|
|
||||||
/* populate platform_of_node for snd card dai links */
|
|
||||||
if (dai_link[i].platform_name &&
|
|
||||||
!dai_link[i].platform_of_node) {
|
|
||||||
index = of_property_match_string(cdev->of_node,
|
|
||||||
"asoc-platform-names",
|
|
||||||
dai_link[i].platform_name);
|
|
||||||
if (index < 0) {
|
|
||||||
dev_err(cdev, "%s: No match found for platform name: %s\n",
|
|
||||||
__func__, dai_link[i].platform_name);
|
|
||||||
ret = index;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
np = of_parse_phandle(cdev->of_node, "asoc-platform",
|
|
||||||
index);
|
|
||||||
if (!np) {
|
|
||||||
dev_err(cdev, "%s: retrieving phandle for platform %s, index %d failed\n",
|
|
||||||
__func__, dai_link[i].platform_name,
|
|
||||||
index);
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
dai_link[i].platform_of_node = np;
|
|
||||||
dai_link[i].platform_name = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* populate cpu_of_node for snd card dai links */
|
|
||||||
if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
|
|
||||||
index = of_property_match_string(cdev->of_node,
|
|
||||||
"asoc-cpu-names",
|
|
||||||
dai_link[i].cpu_dai_name);
|
|
||||||
if (index >= 0) {
|
|
||||||
np = of_parse_phandle(cdev->of_node, "asoc-cpu",
|
|
||||||
index);
|
|
||||||
if (!np) {
|
|
||||||
dev_err(cdev, "%s: retrieving phandle for cpu dai %s failed\n",
|
|
||||||
__func__,
|
|
||||||
dai_link[i].cpu_dai_name);
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
dai_link[i].cpu_of_node = np;
|
|
||||||
dai_link[i].cpu_dai_name = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* populate codec_of_node for snd card dai links */
|
/* populate codec_of_node for snd card dai links */
|
||||||
if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
|
if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
|
||||||
@@ -806,7 +730,6 @@ static struct snd_soc_dai_link msm_stub_be_dai_links[] = {
|
|||||||
.codec_dai_name = "msm-stub-rx",
|
.codec_dai_name = "msm-stub-rx",
|
||||||
.dpcm_playback = 1,
|
.dpcm_playback = 1,
|
||||||
.init = &msm_audrx_stub_init,
|
.init = &msm_audrx_stub_init,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
.ops = &msm_stub_be_ops,
|
.ops = &msm_stub_be_ops,
|
||||||
@@ -818,7 +741,6 @@ static struct snd_soc_dai_link msm_stub_be_dai_links[] = {
|
|||||||
.codec_name = "msm-stub-codec.1",
|
.codec_name = "msm-stub-codec.1",
|
||||||
.codec_dai_name = "msm-stub-tx",
|
.codec_dai_name = "msm-stub-tx",
|
||||||
.dpcm_capture = 1,
|
.dpcm_capture = 1,
|
||||||
.be_hw_params_fixup = msm_be_hw_params_fixup,
|
|
||||||
.ignore_suspend = 1,
|
.ignore_suspend = 1,
|
||||||
.ops = &msm_stub_be_ops,
|
.ops = &msm_stub_be_ops,
|
||||||
},
|
},
|
||||||
|
@@ -15,9 +15,14 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
#include <sound/control.h>
|
||||||
|
#include <sound/core.h>
|
||||||
|
#include <sound/soc.h>
|
||||||
#include <asoc/msm-cdc-pinctrl.h>
|
#include <asoc/msm-cdc-pinctrl.h>
|
||||||
#include <dsp/gecko-core.h>
|
#include <dsp/gecko-core.h>
|
||||||
#include <dsp/msm_audio_ion.h>
|
#include <dsp/msm_audio_ion.h>
|
||||||
|
#include <sound/info.h>
|
||||||
|
|
||||||
#include "msm_common.h"
|
#include "msm_common.h"
|
||||||
|
|
||||||
#define to_asoc_mach_common_pdata(kobj) \
|
#define to_asoc_mach_common_pdata(kobj) \
|
||||||
@@ -31,6 +36,19 @@ static struct attribute device_state_attr = {
|
|||||||
.mode = 0660,
|
.mode = 0660,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_PORT 20
|
||||||
|
#define CODEC_CHMAP "Channel Map"
|
||||||
|
|
||||||
|
enum backend_id {
|
||||||
|
SLIM = 1,
|
||||||
|
CODEC_DMA,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct chmap_pdata {
|
||||||
|
int id;
|
||||||
|
struct snd_soc_dai *dai;
|
||||||
|
};
|
||||||
|
|
||||||
#define MAX_USR_INPUT 10
|
#define MAX_USR_INPUT 10
|
||||||
|
|
||||||
static ssize_t aud_dev_sysfs_store(struct kobject *kobj,
|
static ssize_t aud_dev_sysfs_store(struct kobject *kobj,
|
||||||
@@ -265,3 +283,177 @@ void msm_common_snd_deinit(struct msm_common_pdata *common_pdata)
|
|||||||
mutex_destroy(&common_pdata->lock[count]);
|
mutex_destroy(&common_pdata->lock[count]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int msm_channel_map_info(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_info *uinfo)
|
||||||
|
{
|
||||||
|
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
|
||||||
|
uinfo->count = sizeof(uint32_t) * MAX_PORT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int msm_channel_map_get(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct chmap_pdata *kctl_pdata =
|
||||||
|
(struct chmap_pdata *)kcontrol->private_data;
|
||||||
|
struct snd_soc_dai *codec_dai = kctl_pdata->dai;
|
||||||
|
int backend_id = kctl_pdata->id;
|
||||||
|
uint32_t rx_ch[MAX_PORT], tx_ch[MAX_PORT];
|
||||||
|
uint32_t rx_ch_cnt = 0, tx_ch_cnt = 0;
|
||||||
|
uint32_t *chmap_data = NULL;
|
||||||
|
int ret = 0, len = 0;
|
||||||
|
|
||||||
|
if (kctl_pdata == NULL) {
|
||||||
|
pr_debug("%s: chmap_pdata is not initialized\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_soc_dai_get_channel_map(codec_dai,
|
||||||
|
&tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
|
||||||
|
if (ret || (tx_ch_cnt == 0 && rx_ch_cnt == 0)) {
|
||||||
|
pr_err("%s: get channel map failed for %d\n",
|
||||||
|
__func__, backend_id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
switch (backend_id) {
|
||||||
|
case SLIM: {
|
||||||
|
uint32_t *chmap;
|
||||||
|
uint32_t ch_cnt, i;
|
||||||
|
|
||||||
|
if (rx_ch_cnt) {
|
||||||
|
chmap = rx_ch;
|
||||||
|
ch_cnt = rx_ch_cnt;
|
||||||
|
} else {
|
||||||
|
chmap = tx_ch;
|
||||||
|
ch_cnt = tx_ch_cnt;
|
||||||
|
}
|
||||||
|
len = sizeof(uint32_t) * (ch_cnt + 1);
|
||||||
|
chmap_data = kzalloc(len, GFP_KERNEL);
|
||||||
|
if (!chmap_data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
chmap_data[0] = ch_cnt;
|
||||||
|
for (i = 0; i < ch_cnt; i++)
|
||||||
|
chmap_data[i+1] = chmap[i];
|
||||||
|
|
||||||
|
memcpy(ucontrol->value.bytes.data, chmap_data, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CODEC_DMA: {
|
||||||
|
chmap_data = kzalloc(sizeof(uint32_t) * 2, GFP_KERNEL);
|
||||||
|
if (!chmap_data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (rx_ch_cnt) {
|
||||||
|
chmap_data[0] = rx_ch_cnt;
|
||||||
|
chmap_data[1] = rx_ch[0];
|
||||||
|
} else {
|
||||||
|
chmap_data[0] = tx_ch_cnt;
|
||||||
|
chmap_data[1] = tx_ch[0];
|
||||||
|
}
|
||||||
|
memcpy(ucontrol->value.bytes.data, chmap_data,
|
||||||
|
sizeof(uint32_t) * 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
pr_err("%s, Invalid backend %d\n", __func__, backend_id);
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
kfree(chmap_data);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void msm_common_get_backend_name(const char *stream_name, char **backend_name)
|
||||||
|
{
|
||||||
|
char arg[21] = {0};
|
||||||
|
char value[61] = {0};
|
||||||
|
|
||||||
|
sscanf(stream_name, "%20[^-]-%60s", arg, value);
|
||||||
|
*backend_name = kzalloc(strlen(arg)+1, GFP_KERNEL);
|
||||||
|
if (!(*backend_name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
strlcpy(*backend_name, arg, strlen(arg)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int msm_common_dai_link_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
|
{
|
||||||
|
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||||
|
struct snd_soc_component *component = NULL;
|
||||||
|
struct snd_soc_dai_link *dai_link = rtd->dai_link;
|
||||||
|
struct device *dev = rtd->card->dev;
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
const char *mixer_ctl_name = CODEC_CHMAP;
|
||||||
|
char *mixer_str = NULL;
|
||||||
|
char *backend_name = NULL;
|
||||||
|
uint32_t ctl_len = 0;
|
||||||
|
struct chmap_pdata *pdata;
|
||||||
|
struct snd_kcontrol *kctl;
|
||||||
|
struct snd_kcontrol_new msm_common_channel_map[1] = {
|
||||||
|
{
|
||||||
|
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||||
|
.name = "?",
|
||||||
|
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||||
|
.info = msm_channel_map_info,
|
||||||
|
.get = msm_channel_map_get,
|
||||||
|
.private_value = 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!codec_dai) {
|
||||||
|
pr_err("%s: failed to get codec dai", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
component = codec_dai->component;
|
||||||
|
|
||||||
|
msm_common_get_backend_name(dai_link->stream_name, &backend_name);
|
||||||
|
if (!backend_name) {
|
||||||
|
pr_err("%s: failed to get backend name", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdata = devm_kzalloc(dev, sizeof(struct chmap_pdata), GFP_KERNEL);
|
||||||
|
if (!pdata)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if ((!strncmp(backend_name, "SLIM", strlen("SLIM"))) ||
|
||||||
|
(!strncmp(backend_name, "CODEC_DMA", strlen("CODEC_DMA")))) {
|
||||||
|
ctl_len = strlen(dai_link->stream_name) + 1 +
|
||||||
|
strlen(mixer_ctl_name) + 1;
|
||||||
|
mixer_str = kzalloc(ctl_len, GFP_KERNEL);
|
||||||
|
if (!mixer_str)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
snprintf(mixer_str, ctl_len, "%s %s", dai_link->stream_name,
|
||||||
|
mixer_ctl_name);
|
||||||
|
msm_common_channel_map[0].name = mixer_str;
|
||||||
|
msm_common_channel_map[0].private_value = 0;
|
||||||
|
pr_debug("Registering new mixer ctl %s\n", mixer_str);
|
||||||
|
ret = snd_soc_add_component_controls(component,
|
||||||
|
msm_common_channel_map,
|
||||||
|
ARRAY_SIZE(msm_common_channel_map));
|
||||||
|
kctl = snd_soc_card_get_kcontrol(rtd->card, mixer_str);
|
||||||
|
if (!kctl) {
|
||||||
|
pr_err("failed to get kctl %s\n", mixer_str);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto free_mixer_str;
|
||||||
|
}
|
||||||
|
if (!strncmp(backend_name, "SLIM", strlen("SLIM")))
|
||||||
|
pdata->id = SLIM;
|
||||||
|
else
|
||||||
|
pdata->id = CODEC_DMA;
|
||||||
|
|
||||||
|
pdata->dai = codec_dai;
|
||||||
|
kctl->private_data = pdata;
|
||||||
|
free_mixer_str:
|
||||||
|
kfree(backend_name);
|
||||||
|
kfree(mixer_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -54,4 +54,6 @@ int msm_common_snd_init(struct platform_device *pdev,
|
|||||||
struct snd_soc_card *card);
|
struct snd_soc_card *card);
|
||||||
|
|
||||||
void msm_common_snd_deinit(struct msm_common_pdata *pdata);
|
void msm_common_snd_deinit(struct msm_common_pdata *pdata);
|
||||||
|
|
||||||
|
int msm_common_dai_link_init(struct snd_soc_pcm_runtime *rtd);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user