Ver código fonte

soc: swr-mstr-ctrl: Update SWR_TX to receive port params from slave

Update swr_tx slave port config to use slave provided port params
and remove slave port static tables.

Change-Id: Icfedf1229a88432e80c2294e13f2ccc3949417c5
Signed-off-by: Laxminath Kasam <[email protected]>
Laxminath Kasam 4 anos atrás
pai
commit
6a7bb13614

+ 73 - 0
asoc/codecs/swr-dmic.c

@@ -68,6 +68,8 @@ struct swr_dmic_priv {
 	bool is_wcd_supply;
 	int is_en_supply;
 	u8 tx_master_port_map[SWR_DMIC_MAX_PORTS];
+	struct swr_port_params tx_port_params[SWR_UC_MAX][SWR_DMIC_MAX_PORTS];
+	struct swr_dev_frame_config swr_tx_port_params[SWR_UC_MAX];
 	struct notifier_block nblock;
 };
 
@@ -256,6 +258,74 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w,
 	return ret;
 }
 
+/* qcom,swr-tx-port-params = <OFFSET1_VAL0 LANE1>, <OFFSET1_VAL5 LANE0>, *UC0*
+			<OFFSET1_VAL0 LANE1>, <OFFSET1_VAL2 LANE0>, *UC1*
+			<OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, *UC2*
+			<OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, *UC3 */
+static int swr_dmic_parse_port_params(struct device *dev,
+				      char *prop)
+{
+	int i, j;
+	u32 *dt_array, map_size, max_uc;
+	int ret = 0;
+	u32 cnt = 0;
+	struct swr_port_params (*map)[SWR_UC_MAX][SWR_DMIC_MAX_PORTS];
+	struct swr_dev_frame_config (*map_uc)[SWR_UC_MAX];
+	struct swr_dmic_priv *swr_dmic = dev_get_drvdata(dev);
+
+	map = &swr_dmic->tx_port_params;
+	map_uc = &swr_dmic->swr_tx_port_params;
+
+	if (!of_find_property(dev->of_node, prop,
+				&map_size)) {
+		dev_err(dev, "missing port mapping prop %s\n", prop);
+		ret = -EINVAL;
+		goto err_port_map;
+	}
+
+	max_uc = map_size / (SWR_DMIC_MAX_PORTS * SWR_PORT_PARAMS * sizeof(u32));
+
+	if (max_uc != SWR_UC_MAX) {
+		dev_err(dev,
+			"%s:port params not provided for all usecases\n",
+			__func__);
+		ret = -EINVAL;
+		goto err_port_map;
+	}
+	dt_array = kzalloc(map_size, GFP_KERNEL);
+
+	if (!dt_array) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+	ret = of_property_read_u32_array(dev->of_node, prop, dt_array,
+				SWR_DMIC_MAX_PORTS * SWR_PORT_PARAMS * max_uc);
+	if (ret) {
+		dev_err(dev, "%s: Failed to read  port mapping from prop %s\n",
+					__func__, prop);
+		goto err_pdata_fail;
+	}
+
+	for (i = 0; i < max_uc; i++) {
+		for (j = 0; j < SWR_DMIC_MAX_PORTS; j++) {
+			cnt = (i * SWR_DMIC_MAX_PORTS + j) * SWR_PORT_PARAMS;
+			(*map)[i][j].offset1 = dt_array[cnt];
+			(*map)[i][j].lane_ctrl = dt_array[cnt + 1];
+			dev_err(dev, "%s: port %d, uc: %d, offset1:%d, lane: %d\n",
+				__func__, j, i, dt_array[cnt], dt_array[cnt + 1]);
+		}
+		(*map_uc)[i].pp = &(*map)[i][0];
+	}
+	kfree(dt_array);
+	return 0;
+
+err_pdata_fail:
+	kfree(dt_array);
+err_alloc:
+err_port_map:
+	return ret;
+}
+
 static const char * const tx_master_port_text[] = {
 	"ZERO", "SWRM_TX1_CH1", "SWRM_TX1_CH2", "SWRM_TX1_CH3", "SWRM_TX1_CH4",
 	"SWRM_TX2_CH1", "SWRM_TX2_CH2", "SWRM_TX2_CH3", "SWRM_TX2_CH4",
@@ -540,6 +610,7 @@ static int swr_dmic_probe(struct swr_device *pdev)
 		pdev->dev.of_node->full_name);
 		goto dev_err;
 	}
+	swr_dmic_parse_port_params(&pdev->dev, "qcom,swr-tx-port-params");
 
 	/*
 	 * Add 5msec delay to provide sufficient time for
@@ -568,6 +639,8 @@ static int swr_dmic_probe(struct swr_device *pdev)
 		goto err;
 	}
 	pdev->dev_num = swr_devnum;
+	swr_init_port_params(pdev, SWR_DMIC_MAX_PORTS,
+			     swr_dmic->swr_tx_port_params);
 
 	swr_dmic->driver = devm_kzalloc(&pdev->dev,
 			sizeof(struct snd_soc_component_driver), GFP_KERNEL);

+ 4 - 0
asoc/codecs/wcd937x/internal.h

@@ -8,6 +8,7 @@
 #include <asoc/wcd-clsh.h>
 #include <asoc/wcd-mbhc-v2.h>
 #include <asoc/wcd-irq.h>
+#include <soc/soundwire.h>
 #include "wcd937x-mbhc.h"
 #include "wcd937x.h"
 
@@ -18,6 +19,7 @@
 #define MAX_PORT 8
 #define MAX_CH_PER_PORT 8
 #define MAX_TX_PWR_CH 2
+#define SWR_NUM_PORTS 4
 
 #define WCD937X_MAX_SLAVE_PORT_TYPES 10
 extern struct regmap_config wcd937x_regmap_config;
@@ -72,6 +74,8 @@ struct wcd937x_priv {
 			tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
 	struct codec_port_info
 			rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
+	struct port_params tx_port_params[SWR_UC_MAX][SWR_NUM_PORTS];
+	struct swr_dev_frame_config swr_tx_port_params[SWR_UC_MAX];
 	struct regulator_bulk_data *supplies;
 	struct notifier_block nblock;
 	/* wcd callback to bolero */

+ 80 - 0
asoc/codecs/wcd937x/wcd937x.c

@@ -229,6 +229,77 @@ found:
 	return 0;
 }
 
+/* qcom,swr-tx-port-params = <OFFSET1_VAL0 LANE1>, <OFFSET1_VAL5 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>,*UC0*
+			<OFFSET1_VAL0 LANE1>, <OFFSET1_VAL2 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, *UC1*
+			<OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>; *UC2*
+			<OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>; *UC3 */
+static int wcd937x_parse_port_params(struct device *dev,
+			char *prop, u8 path)
+{
+	u32 *dt_array, map_size, max_uc;
+	int ret = 0;
+	u32 offset1, lane_ctrl, cnt = 0;
+	struct port_params (*map)[SWR_UC_MAX][SWR_NUM_PORTS];
+	struct swr_dev_frame_config (*map_uc)[SWR_UC_MAX];
+	struct wcd937x_priv *wcd937x = dev_get_drvdata(dev);
+
+	switch (path) {
+	case CODEC_TX:
+		map = &wcd937x->tx_port_params;
+		map_uc = &wcd937x->swr_tx_port_params;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_port_map;
+	}
+
+	if (!of_find_property(dev->of_node, prop,
+				&map_size)) {
+		dev_err(dev, "missing port mapping prop %s\n", prop);
+		ret = -EINVAL;
+		goto err_port_map;
+	}
+
+	max_uc = map_size / (SWR_NUM_PORTS * SWR_PORT_PARAMS * sizeof(u32));
+
+	if (max_uc != SWR_UC_MAX) {
+		dev_err(dev, "%s: port params not provided for all usecases\n",
+			__func__);
+		ret = -EINVAL;
+		goto err_port_map;
+	}
+	dt_array = kzalloc(map_size, GFP_KERNEL);
+
+	if (!dt_array) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+	ret = of_property_read_u32_array(dev->of_node, prop, dt_array,
+				SWR_NUM_PORTS * SWR_PORT_PARAMS * max_uc);
+	if (ret) {
+		dev_err(dev, "%s: Failed to read  port mapping from prop %s\n",
+					__func__, prop);
+		goto err_pdata_fail;
+	}
+
+	for (i = 0; i < max_uc; i++) {
+		for (j = 0; j < SWR_NUM_PORTS; j++) {
+			cnt = (i * SWR_NUM_PORTS + j) * SWR_PORT_PARAMS;
+			(*map)[i][j].offset1 = dt_array[cnt];
+			(*map)[i][j].lane_ctrl = dt_array[cnt + 1];
+		}
+		(*map_uc)[i] = &(*map)[i][0];
+	}
+	kfree(dt_array);
+	return 0;
+
+err_pdata_fail:
+	kfree(dt_array);
+err_alloc:
+err_port_map:
+	return ret;
+}
+
 static int wcd937x_parse_port_mapping(struct device *dev,
 			char *prop, u8 path)
 {
@@ -3186,6 +3257,13 @@ static int wcd937x_bind(struct device *dev)
 		dev_err(dev, "Failed to read port mapping\n");
 		goto err;
 	}
+	ret = wcd937x_parse_port_params(dev, "qcom,swr-tx-port-params",
+					CODEC_TX);
+	if (ret) {
+		dev_err(dev, "Failed to read port params\n");
+		goto err;
+	}
+
 
 	wcd937x->rx_swr_dev = get_matching_swr_slave_device(pdata->rx_slave);
 	if (!wcd937x->rx_swr_dev) {
@@ -3202,6 +3280,8 @@ static int wcd937x_bind(struct device *dev)
 		ret = -ENODEV;
 		goto err;
 	}
+	swr_init_port_params(wcd937x->tx_swr_dev, SWR_NUM_PORTS,
+			     wcd937x->swr_tx_port_params);
 
 	wcd937x->regmap = devm_regmap_init_swr(wcd937x->tx_swr_dev,
 					       &wcd937x_regmap_config);

+ 4 - 0
asoc/codecs/wcd938x/internal.h

@@ -9,6 +9,7 @@
 #include <asoc/wcd-mbhc-v2.h>
 #include <asoc/wcd-irq.h>
 #include <asoc/wcd-clsh.h>
+#include <soc/soundwire.h>
 #include "wcd938x-mbhc.h"
 #include "wcd938x.h"
 
@@ -21,6 +22,7 @@
 #define MAX_PORT 8
 #define MAX_CH_PER_PORT 8
 #define TX_ADC_MAX 4
+#define SWR_NUM_PORTS	4
 
 enum {
 	TX_HDR12 = 0,
@@ -88,6 +90,8 @@ struct wcd938x_priv {
 			tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
 	struct codec_port_info
 			rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
+	struct port_params tx_port_params[SWR_UC_MAX][SWR_NUM_PORTS];
+	struct swr_dev_frame_config swr_tx_port_params[SWR_UC_MAX];
 	struct regulator_bulk_data *supplies;
 	struct notifier_block nblock;
 	/* wcd callback to bolero */

+ 80 - 0
asoc/codecs/wcd938x/wcd938x.c

@@ -342,6 +342,78 @@ found:
 	return 0;
 }
 
+
+/* qcom,swr-tx-port-params = <OFFSET1_VAL0 LANE1>, <OFFSET1_VAL5 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>,*UC0*
+			<OFFSET1_VAL0 LANE1>, <OFFSET1_VAL2 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, *UC1*
+			<OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>; *UC2*
+			<OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>, <OFFSET1_VAL1 LANE0>; *UC3 */
+static int wcd938x_parse_port_params(struct device *dev,
+			char *prop, u8 path)
+{
+	u32 *dt_array, map_size, max_uc;
+	int ret = 0;
+	u32 offset1, lane_ctrl, cnt = 0;
+	struct port_params (*map)[SWR_UC_MAX][SWR_NUM_PORTS];
+	struct swr_dev_frame_config (*map_uc)[SWR_UC_MAX];
+	struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
+
+	switch (path) {
+	case CODEC_TX:
+		map = &wcd938x->tx_port_params;
+		map_uc = &wcd938x->swr_tx_port_params;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err_port_map;
+	}
+
+	if (!of_find_property(dev->of_node, prop,
+				&map_size)) {
+		dev_err(dev, "missing port mapping prop %s\n", prop);
+		ret = -EINVAL;
+		goto err_port_map;
+	}
+
+	max_uc = map_size / (SWR_NUM_PORTS * SWR_PORT_PARAMS * sizeof(u32));
+
+	if (max_uc != SWR_UC_MAX) {
+		dev_err(dev, "%s: port params not provided for all usecases\n",
+			__func__);
+		ret = -EINVAL;
+		goto err_port_map;
+	}
+	dt_array = kzalloc(map_size, GFP_KERNEL);
+
+	if (!dt_array) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+	ret = of_property_read_u32_array(dev->of_node, prop, dt_array,
+				SWR_NUM_PORTS * SWR_PORT_PARAMS * max_uc);
+	if (ret) {
+		dev_err(dev, "%s: Failed to read  port mapping from prop %s\n",
+					__func__, prop);
+		goto err_pdata_fail;
+	}
+
+	for (i = 0; i < max_uc; i++) {
+		for (j = 0; j < SWR_NUM_PORTS; j++) {
+			cnt = (i * SWR_NUM_PORTS + j) * SWR_PORT_PARAMS;
+			(*map)[i][j].offset1 = dt_array[cnt];
+			(*map)[i][j].lane_ctrl = dt_array[cnt + 1];
+		}
+		(*map_uc)[i] = &(*map)[i][0];
+	}
+	kfree(dt_array);
+	return 0;
+
+err_pdata_fail:
+	kfree(dt_array);
+err_alloc:
+err_port_map:
+	return ret;
+}
+
 static int wcd938x_parse_port_mapping(struct device *dev,
 			char *prop, u8 path)
 {
@@ -4277,6 +4349,8 @@ static int wcd938x_bind(struct device *dev)
 		ret = -ENODEV;
 		goto err;
 	}
+	swr_init_port_params(wcd938x->tx_swr_dev, SWR_NUM_PORTS,
+			     wcd938x->swr_tx_port_params);
 
 	wcd938x->regmap = devm_regmap_init_swr(wcd938x->tx_swr_dev,
 					       &wcd938x_regmap_config);
@@ -4479,6 +4553,12 @@ static int wcd938x_probe(struct platform_device *pdev)
 		dev_err(dev, "Failed to read port mapping\n");
 		goto err;
 	}
+	ret = wcd938x_parse_port_params(dev, "qcom,swr-tx-port-params",
+					CODEC_TX);
+	if (ret) {
+		dev_err(dev, "Failed to read port params\n");
+		goto err;
+	}
 
 	mutex_init(&wcd938x->wakeup_lock);
 	mutex_init(&wcd938x->micb_lock);

+ 1 - 0
asoc/lahaina-port-config.h

@@ -7,6 +7,7 @@
 #define _LAHAINA_PORT_CONFIG
 
 #include <soc/swr-common.h>
+#include <soc/soundwire.h>
 
 #define WSA_MSTR_PORT_MASK 0xFF
 /*

+ 25 - 0
include/soc/soundwire.h

@@ -11,6 +11,14 @@
 #include <linux/regmap.h>
 #include "audio_mod_devicetable.h"
 
+enum {
+	SWR_UC0 = 0,
+	SWR_UC1,
+	SWR_UC2,
+	SWR_UC3,
+	SWR_UC_MAX,
+};
+
 #define SWR_CLK_RATE_0P3MHZ       300000
 #define SWR_CLK_RATE_0P6MHZ       600000
 #define SWR_CLK_RATE_1P2MHZ      1200000
@@ -32,6 +40,8 @@ struct swr_device;
  * configurations of all devices
  */
 #define SWR_MAX_MSTR_PORT_NUM	(SWR_MAX_DEV_NUM * SWR_MAX_DEV_PORT_NUM)
+/* SWR slave port params count */
+#define SWR_PORT_PARAMS 2
 
 /* Regmap support for soundwire interface */
 struct regmap *__devm_regmap_init_swr(struct swr_device *dev,
@@ -121,6 +131,16 @@ struct swr_port_info {
 	u32 ch_rate;
 };
 
+struct swr_port_params {
+	u32 offset1;
+	u32 lane_ctrl;
+};
+
+struct swr_dev_frame_config {
+	struct swr_port_params *pp;
+};
+
+
 /*
  * struct swr_params - represent transfer of data from soundwire slave
  * to soundwire master
@@ -208,6 +228,8 @@ struct swr_master {
 			  const void *buf, size_t len);
 	int (*get_logical_dev_num)(struct swr_master *mstr, u64 dev_id,
 				u8 *dev_num);
+	int (*init_port_params)(struct swr_master *mstr, u32 dev_num,
+				u32 num_ports, struct swr_dev_frame_config *uc_arr);
 	int (*slvdev_datapath_control)(struct swr_master *mstr, bool enable);
 	bool (*remove_from_group)(struct swr_master *mstr);
 	void (*device_wakeup_vote)(struct swr_master *mstr);
@@ -332,6 +354,9 @@ extern void swr_port_response(struct swr_master *mstr, u8 tid);
 extern int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id,
 			u8 *dev_num);
 
+extern int swr_init_port_params(struct swr_device *dev,
+			u32 num_ports, struct swr_dev_frame_config *pp);
+
 extern int swr_read(struct swr_device *dev, u8 dev_num, u16 reg_addr,
 			void *buf, u32 len);
 

+ 0 - 7
include/soc/swr-common.h

@@ -10,13 +10,6 @@
 #include <linux/device.h>
 #include <linux/bitops.h>
 
-enum {
-	SWR_UC0 = 0,
-	SWR_UC1,
-	SWR_UC2,
-	SWR_UC_MAX,
-};
-
 struct port_params {
 	u16 si;
 	u8 off1;

+ 26 - 0
soc/soundwire.c

@@ -476,6 +476,32 @@ int swr_get_logical_dev_num(struct swr_device *dev, u64 dev_id,
 }
 EXPORT_SYMBOL(swr_get_logical_dev_num);
 
+/**
+ * swr_init_port_params - soundwire slave port params set
+ * @dev: pointer to soundwire slave device
+ * @num_ports: number of slave ports
+ * @pp: port params for all ports for all usecases
+ *
+ * This API will set soundwire port params from slave
+ */
+int swr_init_port_params(struct swr_device *dev,
+			 u32 num_ports, struct swr_dev_frame_config *pp)
+{
+	int ret = 0;
+	struct swr_master *master = dev->master;
+
+	if (!master) {
+		pr_err("%s: Master is NULL\n", __func__);
+		return -EINVAL;
+	}
+	mutex_lock(&master->mlock);
+	ret = master->init_port_params(master, dev->dev_num,
+				       num_ports, pp);
+	mutex_unlock(&master->mlock);
+	return ret;
+}
+EXPORT_SYMBOL(swr_init_port_params);
+
 /**
  * swr_device_wakeup_vote - Wakeup master and slave devices from clock stop
  * @dev: pointer to soundwire slave device

+ 56 - 63
soc/swr-mstr-ctrl.c

@@ -26,7 +26,6 @@
 #include "swr-slave-registers.h"
 #include <dsp/digital-cdc-rsc-mgr.h>
 #include "swr-mstr-ctrl.h"
-#include "swr-slave-port-config.h"
 
 #define SWR_NUM_PORTS    4 /* TODO - Get this info from DT */
 
@@ -131,32 +130,6 @@ static u32 swr_master_read(struct swr_mstr_ctrl *swrm, unsigned int reg_addr);
 static void swr_master_write(struct swr_mstr_ctrl *swrm, u16 reg_addr, u32 val);
 static int swrm_runtime_resume(struct device *dev);
 
-static u64 swrm_phy_dev[] = {
-	0,
-	0xd01170223,
-	0x858350223,
-	0x858350222,
-	0x858350221,
-	0x858350220,
-};
-
-static u8 swrm_get_device_id(struct swr_mstr_ctrl *swrm, u8 devnum)
-{
-	int i;
-
-	for (i = 1; i < (swrm->num_dev + 1); i++) {
-		if (swrm->logical_dev[devnum] == swrm_phy_dev[i])
-			break;
-	}
-
-	if (i == (swrm->num_dev + 1)) {
-		pr_info("%s: could not find the slave\n", __func__);
-		i = devnum;
-	}
-
-	return i;
-}
-
 static u8 swrm_get_clk_div(int mclk_freq, int bus_clk_freq)
 {
 	int clk_div = 0;
@@ -1361,37 +1334,44 @@ static u8 swrm_get_controller_offset1(struct swr_mstr_ctrl *swrm,
 	return offset1;
 }
 
+static int swrm_get_uc(int bus_clk)
+{
+	switch (bus_clk) {
+		case SWR_CLK_RATE_4P8MHZ:
+			return SWR_UC1;
+		case SWR_CLK_RATE_1P2MHZ:
+			return SWR_UC2;
+		case SWR_CLK_RATE_0P6MHZ:
+			return SWR_UC3;
+		case SWR_CLK_RATE_9P6MHZ:
+		default:
+			return SWR_UC0;
+	}
+	return SWR_UC0;
+}
+
 static void swrm_get_device_frame_shape(struct swr_mstr_ctrl *swrm,
 					struct swrm_mports *mport,
 					struct swr_port_info *port_req)
 {
-	u32 port_id = 0;
-	u8 dev_num = 0;
-	struct port_params *pp_dev;
-	struct port_params *pp_port;
-
-	if ((swrm->master_id == MASTER_ID_TX) &&
-		((swrm->bus_clk == SWR_CLK_RATE_9P6MHZ) ||
-		 (swrm->bus_clk == SWR_CLK_RATE_0P6MHZ) ||
-		 (swrm->bus_clk == SWR_CLK_RATE_4P8MHZ))) {
-		dev_num = swrm_get_device_id(swrm, port_req->dev_num);
-		port_id = port_req->slave_port_id;
-		if (swrm->bus_clk == SWR_CLK_RATE_9P6MHZ)
-			pp_dev = swrdev_frame_params_9p6MHz[dev_num].pp;
-		else if (swrm->bus_clk == SWR_CLK_RATE_0P6MHZ)
-			pp_dev = swrdev_frame_params_0p6MHz[dev_num].pp;
-		else
-			pp_dev = swrdev_frame_params_4p8MHz[dev_num].pp;
-		pp_port = &pp_dev[port_id];
-		port_req->sinterval = pp_port->si;
-		port_req->offset1 = pp_port->off1;
-		port_req->offset2 = pp_port->off2;
-		port_req->hstart = pp_port->hstart;
-		port_req->hstop = pp_port->hstop;
-		port_req->word_length = pp_port->wd_len;
-		port_req->blk_pack_mode = pp_port->bp_mode;
-		port_req->blk_grp_count = pp_port->bgp_ctrl;
-		port_req->lane_ctrl = pp_port->lane_ctrl;
+	u32 uc = SWR_UC0;
+	u32 port_id_offset = 0;
+
+	if (swrm->master_id == MASTER_ID_TX) {
+		uc = swrm_get_uc(swrm->bus_clk);
+		port_id_offset = (port_req->dev_num - 1) *
+					SWR_MAX_DEV_PORT_NUM +
+					port_req->slave_port_id;
+		port_req->sinterval =
+				((swrm->bus_clk * 2) / port_req->ch_rate) - 1;
+		port_req->offset1 = swrm->pp[uc][port_id_offset].offset1;
+		port_req->offset2 = 0x00;
+		port_req->hstart = 0xFF;
+		port_req->hstop = 0xFF;
+		port_req->word_length = 0xFF;
+		port_req->blk_pack_mode = 0xFF;
+		port_req->blk_grp_count = 0xFF;
+		port_req->lane_ctrl = swrm->pp[uc][port_id_offset].lane_ctrl;
 	} else {
 		/* copy master port config to slave */
 		port_req->sinterval = mport->sinterval;
@@ -2398,7 +2378,6 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id,
 							"%s: devnum %d assigned for dev %llx\n",
 							__func__, i,
 							swr_dev->addr);
-						swrm->logical_dev[i] = swr_dev->addr;
 					}
 				}
 			}
@@ -2414,6 +2393,27 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id,
 	return ret;
 }
 
+static int swrm_init_port_params(struct swr_master *mstr, u32 dev_num,
+				 u32 num_ports,
+				 struct swr_dev_frame_config *uc_arr)
+{
+	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr);
+	int i, j, port_id_offset;
+
+	if (!swrm) {
+		pr_err("%s: Invalid handle to swr controller\n", __func__);
+		return 0;
+	}
+	for (i = 0; i < SWR_UC_MAX; i++) {
+		for (j = 0; j < num_ports; j++) {
+			port_id_offset = (dev_num - 1) * SWR_MAX_DEV_PORT_NUM + j;
+			swrm->pp[i][port_id_offset].offset1 = uc_arr[i].pp[j].offset1;
+			swrm->pp[i][port_id_offset].lane_ctrl = uc_arr[i].pp[j].lane_ctrl;
+		}
+	}
+	return 0;
+}
+
 static void swrm_device_wakeup_vote(struct swr_master *mstr)
 {
 	struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr);
@@ -2613,7 +2613,6 @@ static int swrm_probe(struct platform_device *pdev)
 	int ret = 0;
 	struct clk *lpass_core_hw_vote = NULL;
 	struct clk *lpass_core_audio = NULL;
-	u32 is_wcd937x = 0;
 
 	/* Allocate soundwire master driver structure */
 	swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl),
@@ -2654,13 +2653,6 @@ static int swrm_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "%s: failed to get master id\n", __func__);
 		goto err_pdata_fail;
 	}
-	/* update the physical device address if wcd937x. */
-	ret = of_property_read_u32(pdev->dev.of_node, "qcom,is_wcd937x",
-				&is_wcd937x);
-	if (ret)
-		dev_dbg(&pdev->dev, "%s: failed to get wcd info\n", __func__);
-	else if (is_wcd937x)
-		swrm_phy_dev[1] = 0xa01170223;
 
 	ret = of_property_read_u32(pdev->dev.of_node, "qcom,dynamic-port-map-supported",
 				&swrm->dynamic_port_map_supported);
@@ -2779,6 +2771,7 @@ static int swrm_probe(struct platform_device *pdev)
 	swrm->master.write = swrm_write;
 	swrm->master.bulk_write = swrm_bulk_write;
 	swrm->master.get_logical_dev_num = swrm_get_logical_dev_num;
+	swrm->master.init_port_params = swrm_init_port_params;
 	swrm->master.connect_port = swrm_connect_port;
 	swrm->master.disconnect_port = swrm_disconnect_port;
 	swrm->master.slvdev_datapath_control = swrm_slvdev_datapath_control;

+ 2 - 2
soc/swr-mstr-ctrl.h

@@ -44,7 +44,7 @@
 
 #define SWR_MAX_CH_PER_PORT 8
 
-#define SWRM_NUM_AUTO_ENUM_SLAVES    6
+#define SWRM_NUM_AUTO_ENUM_SLAVES    11
 
 enum {
 	SWR_MSTR_PAUSE,
@@ -196,8 +196,8 @@ struct swr_mstr_ctrl {
 	u32 wr_fifo_depth;
 	u32 num_auto_enum;
 	bool enable_slave_irq;
-	u64 logical_dev[SWRM_NUM_AUTO_ENUM_SLAVES];
 	u32 is_always_on;
+	struct swr_port_params pp[SWR_UC_MAX][SWR_MAX_MSTR_PORT_NUM];/*max_devNum * max_ports 11 * 14 */
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *debugfs_swrm_dent;
 	struct dentry *debugfs_peek;

+ 0 - 167
soc/swr-slave-port-config.h

@@ -1,167 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
- */
-
-#ifndef _SWR_SLAVE_PORT_CONFIG
-#define _SWR_SLAVE_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}
- */
-
-/* DUMMY */
-static struct port_params tx_dummy[SWR_MSTR_PORT_LEN] = {
-	{0,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{0,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-	{0,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
-};
-
-/* AMIC 9.6 MHz clock */
-#ifdef CONFIG_SND_SOC_HOLI
-static struct port_params tx_wcd_9p6MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
-	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
-	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */
-};
-#else
-static struct port_params tx_wcd_9p6MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
-	{7,  5,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
-	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */
-};
-#endif
-
-/* AMIC 4.8 MHz clock */
-static struct port_params tx_wcd_4p8MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
-	{3,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
-	{3,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */
-};
-
-/* AMIC 0.6 MHz clock, single channel */
-static struct port_params tx_wcd_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 */
-	{1,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX4 */
-};
-/* 4 Channel configuration */
-/* SWR DMIC0 */
-static struct port_params tx_bottom_mic_9p6MHz[SWR_MSTR_PORT_LEN] = {
-	{7,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{7,  6,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC1 */
-static struct port_params tx_receiver_mic_9p6MHz[SWR_MSTR_PORT_LEN] = {
-	{7,  4,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{7,  7,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC2 */
-static struct port_params tx_back_mic_9p6MHz[SWR_MSTR_PORT_LEN] = {
-	{7,  3,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC3 */
-static struct port_params tx_top_mic_9p6MHz[SWR_MSTR_PORT_LEN] = {
-	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{7,  5,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* The 4.8MHZ port config is used in
- * 1. single mic standalone in "high power" mode
- * 2. dual mic standalone in "high power" mode
- * 3. sva standalone single/dual/tri/quad in "low-power" mode
- * 4. sva single/dmic in "low-power" + single mic in "high power" concurrency
- */
-/* SWR DMIC0 */
-static struct port_params tx_bottom_mic_4p8MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{15,  4,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC1 */
-static struct port_params tx_receiver_mic_4p8MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  3,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{7,  6,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC2 */
-static struct port_params tx_back_mic_4p8MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  3,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{7,  7,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC3 */
-static struct port_params tx_top_mic_4p8MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{15,  3,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* 1 Channel configuration */
-/* SWR DMIC0 */
-static struct port_params tx_bottom_mic_0p6MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{1,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC1 */
-static struct port_params tx_receiver_mic_0p6MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{1,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC2 */
-static struct port_params tx_back_mic_0p6MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{1,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-/* SWR DMIC3 */
-static struct port_params tx_top_mic_0p6MHz[SWR_MSTR_PORT_LEN] = {
-	{3,  3,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
-	{1,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
-};
-
-struct swr_dev_frame_config {
-	struct port_params *pp;
-};
-
-static struct swr_dev_frame_config swrdev_frame_params_9p6MHz[] = {
-	{tx_dummy},
-	{tx_wcd_9p6MHz},
-	{tx_top_mic_9p6MHz},
-	{tx_back_mic_9p6MHz},
-	{tx_receiver_mic_9p6MHz},
-	{tx_bottom_mic_9p6MHz},
-};
-
-static struct swr_dev_frame_config swrdev_frame_params_4p8MHz[] = {
-	{tx_dummy},
-	{tx_wcd_4p8MHz},
-	{tx_top_mic_4p8MHz},
-	{tx_back_mic_4p8MHz},
-	{tx_receiver_mic_4p8MHz},
-	{tx_bottom_mic_4p8MHz},
-};
-
-static struct swr_dev_frame_config swrdev_frame_params_0p6MHz[] = {
-	{tx_dummy},
-	{tx_wcd_0p6MHz},
-	{tx_top_mic_0p6MHz},
-	{tx_back_mic_0p6MHz},
-	{tx_receiver_mic_0p6MHz},
-	{tx_bottom_mic_0p6MHz},
-};
-#endif /* _LAHAINA_PORT_CONFIG */