Skip to content

Commit c06c4f7

Browse files
mohsRafibroonie
authored andcommitted
ASoC: codecs: wcd937x: Add static channel mapping support in wcd937x-sdw
Add static channel mapping between master and slave ports in wcd937x-sdw driver. Currently, the channel mask for each soundwire port is hardcoded in the wcd937x-sdw driver, and the same channel mask value is configured in the soundwire master. The Qualcomm boards like the QCM6490-IDP require different channel mask settings for the soundwire master and slave ports. Implemented logic to read TX/RX channel mappings from device tree properties (qcom,tx-channel-mapping and qcom,rx-channel-mapping). Modified the wcd937x_connect_port to handle master channel masks during port enable/disable operations. Added wcd937x_get_channel_map api to retrieve the current master channel map for TX and RX paths. Signed-off-by: Mohammad Rafi Shaik <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 7282638 commit c06c4f7

File tree

3 files changed

+92
-7
lines changed

3 files changed

+92
-7
lines changed

sound/soc/codecs/wcd937x-sdw.c

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <sound/soc.h>
2020
#include "wcd937x.h"
2121

22-
static const struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = {
22+
static struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = {
2323
WCD_SDW_CH(WCD937X_HPH_L, WCD937X_HPH_PORT, BIT(0)),
2424
WCD_SDW_CH(WCD937X_HPH_R, WCD937X_HPH_PORT, BIT(1)),
2525
WCD_SDW_CH(WCD937X_CLSH, WCD937X_CLSH_PORT, BIT(0)),
@@ -30,7 +30,7 @@ static const struct wcd937x_sdw_ch_info wcd937x_sdw_rx_ch_info[] = {
3030
WCD_SDW_CH(WCD937X_DSD_R, WCD937X_DSD_PORT, BIT(1)),
3131
};
3232

33-
static const struct wcd937x_sdw_ch_info wcd937x_sdw_tx_ch_info[] = {
33+
static struct wcd937x_sdw_ch_info wcd937x_sdw_tx_ch_info[] = {
3434
WCD_SDW_CH(WCD937X_ADC1, WCD937X_ADC_1_PORT, BIT(0)),
3535
WCD_SDW_CH(WCD937X_ADC2, WCD937X_ADC_2_3_PORT, BIT(0)),
3636
WCD_SDW_CH(WCD937X_ADC3, WCD937X_ADC_2_3_PORT, BIT(0)),
@@ -1019,7 +1019,9 @@ static int wcd9370_probe(struct sdw_slave *pdev,
10191019
{
10201020
struct device *dev = &pdev->dev;
10211021
struct wcd937x_sdw_priv *wcd;
1022-
int ret;
1022+
u8 master_ch_mask[WCD937X_MAX_SWR_CH_IDS];
1023+
int master_ch_mask_size = 0;
1024+
int ret, i;
10231025

10241026
wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
10251027
if (!wcd)
@@ -1048,10 +1050,36 @@ static int wcd9370_probe(struct sdw_slave *pdev,
10481050
SDW_SCP_INT1_PARITY;
10491051
pdev->prop.lane_control_support = true;
10501052
pdev->prop.simple_clk_stop_capable = true;
1053+
1054+
memset(master_ch_mask, 0, WCD937X_MAX_SWR_CH_IDS);
1055+
10511056
if (wcd->is_tx) {
1052-
pdev->prop.source_ports = GENMASK(WCD937X_MAX_TX_SWR_PORTS - 1, 0);
1057+
master_ch_mask_size = of_property_count_u8_elems(dev->of_node,
1058+
"qcom,tx-channel-mapping");
1059+
1060+
if (master_ch_mask_size)
1061+
ret = of_property_read_u8_array(dev->of_node, "qcom,tx-channel-mapping",
1062+
master_ch_mask, master_ch_mask_size);
1063+
} else {
1064+
master_ch_mask_size = of_property_count_u8_elems(dev->of_node,
1065+
"qcom,rx-channel-mapping");
1066+
1067+
if (master_ch_mask_size)
1068+
ret = of_property_read_u8_array(dev->of_node, "qcom,rx-channel-mapping",
1069+
master_ch_mask, master_ch_mask_size);
1070+
}
1071+
1072+
if (ret < 0)
1073+
dev_info(dev, "Static channel mapping not specified using device channel maps\n");
1074+
1075+
if (wcd->is_tx) {
1076+
pdev->prop.source_ports = GENMASK(WCD937X_MAX_TX_SWR_PORTS, 0);
10531077
pdev->prop.src_dpn_prop = wcd937x_dpn_prop;
10541078
wcd->ch_info = &wcd937x_sdw_tx_ch_info[0];
1079+
1080+
for (i = 0; i < master_ch_mask_size; i++)
1081+
wcd->ch_info[i].master_ch_mask = WCD937X_SWRM_CH_MASK(master_ch_mask[i]);
1082+
10551083
pdev->prop.wake_capable = true;
10561084

10571085
wcd->regmap = devm_regmap_init_sdw(pdev, &wcd937x_regmap_config);
@@ -1065,6 +1093,9 @@ static int wcd9370_probe(struct sdw_slave *pdev,
10651093
pdev->prop.sink_ports = GENMASK(WCD937X_MAX_SWR_PORTS - 1, 0);
10661094
pdev->prop.sink_dpn_prop = wcd937x_dpn_prop;
10671095
wcd->ch_info = &wcd937x_sdw_rx_ch_info[0];
1096+
1097+
for (i = 0; i < master_ch_mask_size; i++)
1098+
wcd->ch_info[i].master_ch_mask = WCD937X_SWRM_CH_MASK(master_ch_mask[i]);
10681099
}
10691100

10701101

sound/soc/codecs/wcd937x.c

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,13 +1197,21 @@ static int wcd937x_connect_port(struct wcd937x_sdw_priv *wcd, u8 port_idx, u8 ch
11971197
const struct wcd937x_sdw_ch_info *ch_info = &wcd->ch_info[ch_id];
11981198
u8 port_num = ch_info->port_num;
11991199
u8 ch_mask = ch_info->ch_mask;
1200+
u8 mstr_port_num, mstr_ch_mask;
1201+
struct sdw_slave *sdev = wcd->sdev;
12001202

12011203
port_config->num = port_num;
12021204

1203-
if (enable)
1205+
mstr_port_num = sdev->m_port_map[port_num];
1206+
mstr_ch_mask = ch_info->master_ch_mask;
1207+
1208+
if (enable) {
12041209
port_config->ch_mask |= ch_mask;
1205-
else
1210+
wcd->master_channel_map[mstr_port_num] |= mstr_ch_mask;
1211+
} else {
12061212
port_config->ch_mask &= ~ch_mask;
1213+
wcd->master_channel_map[mstr_port_num] &= ~mstr_ch_mask;
1214+
}
12071215

12081216
return 0;
12091217
}
@@ -2689,10 +2697,51 @@ static int wcd937x_codec_set_sdw_stream(struct snd_soc_dai *dai,
26892697
return 0;
26902698
}
26912699

2700+
static int wcd937x_get_channel_map(const struct snd_soc_dai *dai,
2701+
unsigned int *tx_num, unsigned int *tx_slot,
2702+
unsigned int *rx_num, unsigned int *rx_slot)
2703+
{
2704+
struct wcd937x_priv *wcd937x = dev_get_drvdata(dai->dev);
2705+
struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[dai->id];
2706+
int i;
2707+
2708+
switch (dai->id) {
2709+
case AIF1_PB:
2710+
if (!rx_slot || !rx_num) {
2711+
dev_err(dai->dev, "Invalid rx_slot %p or rx_num %p\n",
2712+
rx_slot, rx_num);
2713+
return -EINVAL;
2714+
}
2715+
2716+
for (i = 0; i < SDW_MAX_PORTS; i++)
2717+
rx_slot[i] = wcd->master_channel_map[i];
2718+
2719+
*rx_num = i;
2720+
break;
2721+
case AIF1_CAP:
2722+
if (!tx_slot || !tx_num) {
2723+
dev_err(dai->dev, "Invalid tx_slot %p or tx_num %p\n",
2724+
tx_slot, tx_num);
2725+
return -EINVAL;
2726+
}
2727+
2728+
for (i = 0; i < SDW_MAX_PORTS; i++)
2729+
tx_slot[i] = wcd->master_channel_map[i];
2730+
2731+
*tx_num = i;
2732+
break;
2733+
default:
2734+
break;
2735+
}
2736+
2737+
return 0;
2738+
}
2739+
26922740
static const struct snd_soc_dai_ops wcd937x_sdw_dai_ops = {
26932741
.hw_params = wcd937x_codec_hw_params,
26942742
.hw_free = wcd937x_codec_free,
26952743
.set_stream = wcd937x_codec_set_sdw_stream,
2744+
.get_channel_map = wcd937x_get_channel_map,
26962745
};
26972746

26982747
static struct snd_soc_dai_driver wcd937x_dais[] = {

sound/soc/codecs/wcd937x.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@
489489
#define WCD937X_MAX_MICBIAS 3
490490
#define WCD937X_MAX_BULK_SUPPLY 4
491491
#define WCD937X_MAX_SWR_CH_IDS 15
492+
#define WCD937X_SWRM_CH_MASK(ch_idx) BIT(ch_idx - 1)
492493

493494
enum wcd937x_tx_sdw_ports {
494495
WCD937X_ADC_1_PORT = 1,
@@ -510,12 +511,14 @@ enum wcd937x_rx_sdw_ports {
510511
struct wcd937x_sdw_ch_info {
511512
int port_num;
512513
unsigned int ch_mask;
514+
unsigned int master_ch_mask;
513515
};
514516

515517
#define WCD_SDW_CH(id, pn, cmask) \
516518
[id] = { \
517519
.port_num = pn, \
518520
.ch_mask = cmask, \
521+
.master_ch_mask = cmask, \
519522
}
520523

521524
struct wcd937x_priv;
@@ -524,9 +527,11 @@ struct wcd937x_sdw_priv {
524527
struct sdw_stream_config sconfig;
525528
struct sdw_stream_runtime *sruntime;
526529
struct sdw_port_config port_config[WCD937X_MAX_SWR_PORTS];
527-
const struct wcd937x_sdw_ch_info *ch_info;
530+
struct wcd937x_sdw_ch_info *ch_info;
528531
bool port_enable[WCD937X_MAX_SWR_CH_IDS];
532+
unsigned int master_channel_map[SDW_MAX_PORTS];
529533
int active_ports;
534+
int num_ports;
530535
bool is_tx;
531536
struct wcd937x_priv *wcd937x;
532537
struct irq_domain *slave_irq;

0 commit comments

Comments
 (0)