summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/wcd937x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wcd937x.c')
-rw-r--r--sound/soc/codecs/wcd937x.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c
index c9d5e67bf66e..dd2045a5d26d 100644
--- a/sound/soc/codecs/wcd937x.c
+++ b/sound/soc/codecs/wcd937x.c
@@ -1197,13 +1197,21 @@ static int wcd937x_connect_port(struct wcd937x_sdw_priv *wcd, u8 port_idx, u8 ch
const struct wcd937x_sdw_ch_info *ch_info = &wcd->ch_info[ch_id];
u8 port_num = ch_info->port_num;
u8 ch_mask = ch_info->ch_mask;
+ u8 mstr_port_num, mstr_ch_mask;
+ struct sdw_slave *sdev = wcd->sdev;
port_config->num = port_num;
- if (enable)
+ mstr_port_num = sdev->m_port_map[port_num];
+ mstr_ch_mask = ch_info->master_ch_mask;
+
+ if (enable) {
port_config->ch_mask |= ch_mask;
- else
+ wcd->master_channel_map[mstr_port_num] |= mstr_ch_mask;
+ } else {
port_config->ch_mask &= ~ch_mask;
+ wcd->master_channel_map[mstr_port_num] &= ~mstr_ch_mask;
+ }
return 0;
}
@@ -2472,7 +2480,7 @@ static const struct irq_domain_ops wcd_domain_ops = {
static int wcd937x_irq_init(struct wcd937x_priv *wcd, struct device *dev)
{
- wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL);
+ wcd->virq = irq_domain_create_linear(NULL, 1, &wcd_domain_ops, NULL);
if (!(wcd->virq)) {
dev_err(dev, "%s: Failed to add IRQ domain\n", __func__);
return -EINVAL;
@@ -2563,6 +2571,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
ARRAY_SIZE(wcd9375_dapm_widgets));
if (ret < 0) {
dev_err(component->dev, "Failed to add snd_ctls\n");
+ wcd_clsh_ctrl_free(wcd937x->clsh_info);
return ret;
}
@@ -2570,6 +2579,7 @@ static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
ARRAY_SIZE(wcd9375_audio_map));
if (ret < 0) {
dev_err(component->dev, "Failed to add routes\n");
+ wcd_clsh_ctrl_free(wcd937x->clsh_info);
return ret;
}
}
@@ -2689,10 +2699,51 @@ static int wcd937x_codec_set_sdw_stream(struct snd_soc_dai *dai,
return 0;
}
+static int wcd937x_get_channel_map(const struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot)
+{
+ struct wcd937x_priv *wcd937x = dev_get_drvdata(dai->dev);
+ struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[dai->id];
+ int i;
+
+ switch (dai->id) {
+ case AIF1_PB:
+ if (!rx_slot || !rx_num) {
+ dev_err(dai->dev, "Invalid rx_slot %p or rx_num %p\n",
+ rx_slot, rx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < SDW_MAX_PORTS; i++)
+ rx_slot[i] = wcd->master_channel_map[i];
+
+ *rx_num = i;
+ break;
+ case AIF1_CAP:
+ if (!tx_slot || !tx_num) {
+ dev_err(dai->dev, "Invalid tx_slot %p or tx_num %p\n",
+ tx_slot, tx_num);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < SDW_MAX_PORTS; i++)
+ tx_slot[i] = wcd->master_channel_map[i];
+
+ *tx_num = i;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops wcd937x_sdw_dai_ops = {
.hw_params = wcd937x_codec_hw_params,
.hw_free = wcd937x_codec_free,
.set_stream = wcd937x_codec_set_sdw_stream,
+ .get_channel_map = wcd937x_get_channel_map,
};
static struct snd_soc_dai_driver wcd937x_dais[] = {