static int es705_cfg_slim_rx(struct slim_device *sbdev, unsigned int *ch_num,
			     unsigned int ch_cnt, unsigned int rate)
{
	struct es705_priv *es705_priv = slim_get_devicedata(sbdev);
	struct es705_slim_ch *rx = es705_priv->slim_rx;
	u16 grph;
	u32 sph[ES705_SLIM_RX_PORTS] = {0};
	u16 ch_h[ES705_SLIM_RX_PORTS] = {0};
	struct slim_ch prop;
	int i;
	int idx;
	int rc = 0;

	dev_info(&sbdev->dev, "%s(): ch_cnt = %d, rate = %d\n",
		__func__, ch_cnt, rate);

	for (i = 0; i < ch_cnt; i++) {
		dev_dbg(&sbdev->dev, "%s(): ch_num = %d\n",
			__func__, ch_num[i]);
		idx = es705_rx_ch_num_to_idx(ch_num[i]);
		ch_h[i] = rx[idx].ch_h;
		sph[i] = rx[idx].sph;
	}

	prop.prot = SLIM_AUTO_ISO;
	prop.baser = SLIM_RATE_4000HZ;
	prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
	prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
	prop.ratem = (rate/4000);
	prop.sampleszbits = 16;

	rc = slim_define_ch(sbdev, &prop, ch_h, ch_cnt, true, &grph);
	if (rc < 0) {
		dev_err(&sbdev->dev, "%s(): slim_define_ch() failed: %d\n",
			__func__, rc);
		goto slim_define_ch_error;
	}
	for (i = 0; i < ch_cnt; i++) {
		rc = slim_connect_sink(sbdev, &sph[i], 1, ch_h[i]);
		if (rc < 0) {
			dev_err(&sbdev->dev, "%s(): slim_connect_sink() failed: %d\n",
				__func__, rc);
			goto slim_connect_sink_error;
		}
	}
	rc = slim_control_ch(sbdev, grph, SLIM_CH_ACTIVATE, true);
	if (rc < 0) {
		dev_err(&sbdev->dev,
			"%s(): slim_control_ch() failed: %d\n",
			__func__, rc);
		goto slim_control_ch_error;
	}
	for (i = 0; i < ch_cnt; i++) {
		dev_info(&sbdev->dev, "%s(): ch_num = %d\n",
			__func__, ch_num[i]);
		idx = es705_rx_ch_num_to_idx(ch_num[i]);
		rx[idx].grph = grph;
	}
	return rc;
slim_control_ch_error:
slim_connect_sink_error:
	es705_close_slim_rx(sbdev, ch_num, ch_cnt);
slim_define_ch_error:
	return rc;
}
static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data,
	struct snd_soc_dai *dai,
	enum msm_dai_slim_event event)
{
	struct slim_device *sdev;
	struct msm_dai_slim_drv_data *drv_data;
	struct msm_slim_dai_data *dai_data;
	int rc, rc1, i;

	if (!dma_data || !dma_data->sdev) {
		pr_err("%s: Invalid %s\n", __func__,
		       (!dma_data) ? "dma_data" : "slim_device");
		return -EINVAL;
	}

	sdev = dma_data->sdev;
	drv_data = dev_get_drvdata(&sdev->dev);
	dai_data = msm_slim_get_dai_data(drv_data, dai);

	if (!dai_data) {
		dev_err(dai->dev,
			"%s: Invalid dai_data for dai_id %d\n",
			__func__, dai->id);
		return -EINVAL;
	}

	dev_dbg(&sdev->dev,
		"%s: event = 0x%x, rate = %u\n", __func__,
		event, dai_data->rate);

	switch (event) {
	case MSM_DAI_SLIM_ENABLE:

		if (!(dai_data->status & DAI_STATE_PREPARED)) {
			dev_err(&sdev->dev,
				"%s: dai id (%d) has invalid state 0x%x\n",
				__func__, dai->id, dai_data->status);
			return -EINVAL;
		}

		rc = slim_alloc_mgrports(sdev,
					 SLIM_REQ_DEFAULT, dai_data->ch_cnt,
					 &(dma_data->ph),
					 sizeof(dma_data->ph));

		if (IS_ERR_VALUE(rc)) {
			dev_err(&sdev->dev,
				"%s:alloc mgrport failed rc %d\n",
				__func__ , rc);
			goto done;
		}

		rc = slim_config_mgrports(sdev, &(dma_data->ph),
					  dai_data->ch_cnt,
					  &(dai_data->port_cfg));
		if (IS_ERR_VALUE(rc)) {
			dev_err(&sdev->dev,
				"%s: config mgrport failed rc %d\n",
				__func__ , rc);
			goto err_done;
		}

		for (i = 0; i < dai_data->ch_cnt; i++) {
			rc = slim_connect_sink(sdev,
					       &dma_data->ph, 1,
					       dai_data->chan_h[i]);
			if (IS_ERR_VALUE(rc)) {
				dev_err(&sdev->dev,
					"%s: slim_connect_sink failed, ch = %d, err = %d\n",
					__func__, i, rc);
				goto err_done;
			}
		}

		rc = slim_control_ch(sdev,
				     dai_data->grph,
				     SLIM_CH_ACTIVATE, true);
		if (IS_ERR_VALUE(rc)) {
			dev_err(&sdev->dev,
				"%s: slim activate ch failed, err = %d\n",
				__func__, rc);
			goto err_done;
		}
		/* Mark dai status as running */
		SET_DAI_STATE(dai_data->status, DAI_STATE_RUNNING);
		break;

	case MSM_DAI_SLIM_PRE_DISABLE:
		if (!(dai_data->status & DAI_STATE_RUNNING)) {
			dev_err(&sdev->dev,
				"%s: dai id (%d) has invalid state 0x%x\n",
				__func__, dai->id, dai_data->status);
			return -EINVAL;
		}

		rc = slim_control_ch(sdev,
				     dai_data->grph,
				     SLIM_CH_REMOVE, true);
		if (IS_ERR_VALUE(rc)) {
			dev_err(&sdev->dev,
				"%s: slim activate ch failed, err = %d\n",
				__func__, rc);
			goto done;
		}
		break;

	case MSM_DAI_SLIM_DISABLE:

		rc = slim_dealloc_mgrports(sdev,
					   &dma_data->ph, 1);
		if (IS_ERR_VALUE(rc)) {
			dev_err(&sdev->dev,
				"%s: dealloc mgrport failed, err = %d\n",
				__func__, rc);
			goto done;
		}
		/* clear running state for dai*/
		CLR_DAI_STATE(dai_data->status, DAI_STATE_RUNNING);
		break;

	default:
		dev_err(&sdev->dev,
			"%s: Unhandled event 0x%x\n",
			__func__, event);
		rc = -EINVAL;
		goto done;
	}

	return rc;

err_done:
	rc1 = slim_dealloc_mgrports(sdev,
				   &dma_data->ph, 1);
	if (IS_ERR_VALUE(rc1))
		dev_err(&sdev->dev,
			"%s: dealloc mgrport failed, err = %d\n",
			__func__, rc1);
done:
	return rc;
}
/* Enable slimbus slave device for RX path */
int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
				unsigned int ch_cnt, unsigned int rate)
{
	u8 i = 0;
	u16 grph;
	u32 sph[SLIM_MAX_RX_PORTS] = {0};
	u16 ch_h[SLIM_MAX_RX_PORTS] = {0};
	u16 slave_port_id;
	u8  payload_rx = 0, wm_payload = 0;
	int ret, idx = 0;
	unsigned short  multi_chan_cfg_reg_addr;
	struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
	struct slim_ch prop;

	/* Configure slave interface device */
	pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);

	for (i = 0; i < ch_cnt; i++) {
		idx = (ch_num[i] - BASE_CH_NUM -
			SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
		ch_h[i] = rx[idx].ch_h;
		sph[i] = rx[idx].sph;
		slave_port_id = idx + 1;
		if ((slave_port_id > SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS) ||
			(slave_port_id == 0)) {
			pr_err("Slimbus: invalid slave port id: %d",
							slave_port_id);
			ret = -EINVAL;
			goto err;
		}
		slave_port_id += SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
		/* look for the valid port range and chose the
		 * payload accordingly
		 */
		if ((slave_port_id >
				SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID) &&
			(slave_port_id <=
			 SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID)) {
				payload_rx = payload_rx  |
				(1 <<
				(slave_port_id -
				SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID));
		} else {
			ret = -EINVAL;
			goto err;
		}
		multi_chan_cfg_reg_addr =
				SB_PGD_RX_PORT_MULTI_CHANNEL_0(slave_port_id);
		/* write to interface device */
		ret = wcd9xxx_interface_reg_write(wcd9xxx,
				multi_chan_cfg_reg_addr,
				payload_rx);
		if (ret < 0) {
			pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
							__func__,
							multi_chan_cfg_reg_addr,
							payload_rx, ret);
			goto err;
		}
		/* configure the slave port for water mark and enable*/
		wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
				SLAVE_PORT_WATER_MARK_SHIFT) +
				SLAVE_PORT_ENABLE;
		ret = wcd9xxx_interface_reg_write(wcd9xxx,
				SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
				wm_payload);
		if (ret < 0) {
			pr_err("%s:watermark set failure for port[%d] ret[%d]",
						__func__, slave_port_id, ret);
		}
	}

	/* slim_define_ch api */
	prop.prot = SLIM_AUTO_ISO;
	prop.baser = SLIM_RATE_4000HZ;
	prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
	prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
	prop.ratem = (rate/4000);
	prop.sampleszbits = 16;

	ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
					true, &grph);
	if (ret < 0) {
		pr_err("%s: slim_define_ch failed ret[%d]\n",
					__func__, ret);
		goto err;
	}
	for (i = 0; i < ch_cnt; i++) {
		ret = slim_connect_sink(wcd9xxx->slim, &sph[i],
							1, ch_h[i]);
		if (ret < 0) {
			pr_err("%s: slim_connect_sink failed ret[%d]\n",
						__func__, ret);
			goto err_close_slim_sch;
		}
	}
	/* slim_control_ch */
	ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE,
					true);
	if (ret < 0) {
		pr_err("%s: slim_control_ch failed ret[%d]\n",
				__func__, ret);
		goto err_close_slim_sch;
	}
	for (i = 0; i < ch_cnt; i++) {
		idx = (ch_num[i] - BASE_CH_NUM -
				SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
		rx[idx].grph = grph;
	}
	return 0;

err_close_slim_sch:
	/*  release all acquired handles */
	wcd9xxx_close_slim_sch_rx(wcd9xxx, ch_num, ch_cnt);
err:
	return ret;
}
int escore_cfg_slim_rx(struct slim_device *sbdev, unsigned int *ch_num,
			     unsigned int ch_cnt, unsigned int rate)
{
	struct escore_priv *escore_priv = slim_get_devicedata(sbdev);
	struct escore_slim_ch *rx = escore_priv->slim_rx;
	u16 grph;
	u32 *sph;
	u16 *ch_h;
	struct slim_ch prop;
	int i;
	int idx;
	int rc = 0;

	dev_dbg(&sbdev->dev, "%s(ch_cnt = %d, rate = %d)\n", __func__,
		ch_cnt, rate);

	sph = kmalloc(sizeof(u32)*escore_priv->slim_rx_ports, GFP_KERNEL);
	if (!sph)
		return -ENOMEM;
	ch_h = kmalloc(sizeof(u32)*escore_priv->slim_rx_ports, GFP_KERNEL);
	if (!ch_h) {
		kfree(sph);
		return -ENOMEM;
	}

	for (i = 0; i < ch_cnt; i++) {
		idx = escore_rx_ch_num_to_idx(escore_priv, ch_num[i]);
		ch_h[i] = rx[idx].ch_h;
		sph[i] = rx[idx].sph;
	}

	prop.prot = SLIM_AUTO_ISO;
	prop.baser = SLIM_RATE_4000HZ;
	prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
	prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
	prop.ratem = (rate/4000);
	prop.sampleszbits = 16;

	rc = slim_define_ch(sbdev, &prop, ch_h, ch_cnt, true, &grph);
	if (rc < 0) {
		dev_err(&sbdev->dev, "%s(): slim_define_ch() failed: %d\n",
			__func__, rc);
		goto slim_define_ch_error;
	}
	for (i = 0; i < ch_cnt; i++) {
		rc = slim_connect_sink(sbdev, &sph[i], 1, ch_h[i]);
		if (rc < 0) {
			dev_err(&sbdev->dev,
				"%s(): slim_connect_sink() failed: %d\n",
				__func__, rc);
			goto slim_connect_sink_error;
		}
	}
	rc = slim_control_ch(sbdev, grph, SLIM_CH_ACTIVATE, true);
	if (rc < 0) {
		dev_err(&sbdev->dev,
			"%s(): slim_control_ch() failed: %d\n",
			__func__, rc);
		goto slim_control_ch_error;
	}
	for (i = 0; i < ch_cnt; i++) {
		idx = escore_rx_ch_num_to_idx(escore_priv, ch_num[i]);
		rx[idx].grph = grph;
	}
	kfree(sph);
	kfree(ch_h);
	return rc;
slim_control_ch_error:
slim_connect_sink_error:
	escore_close_slim_rx(sbdev, ch_num, ch_cnt);
slim_define_ch_error:
	kfree(sph);
	kfree(ch_h);
	return rc;
}