Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fa156811 authored by Bala Kishore Pati's avatar Bala Kishore Pati
Browse files

ASoC: msm: enable group config for both tx and rx



Add support to enable group config for tdm tx and
rx ports.On platform where ebit is unsupported it
is expected to start tx and rx ports at a time.
Ensure to start both tdm tx and rx group as
group devices.

Change-Id: Idb995c8215ccad147612b85bf38b289fb24391f2
Signed-off-by: default avatarBala Kishore Pati <balakishorepati@codeaurora.org>
parent 204a4c25
Loading
Loading
Loading
Loading
+146 −30
Original line number Diff line number Diff line
@@ -191,6 +191,7 @@ struct msm_dai_q6_auxpcm_dai_data {
};

static union afe_port_group_config group_cfg_tx;
static union afe_port_group_config group_cfg_rx;

struct msm_dai_q6_tdm_dai_data {
	DECLARE_BITMAP(status_mask, STATUS_MAX);
@@ -5522,24 +5523,34 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
			custom_tdm_header->header[6],
			custom_tdm_header->header[7]);
	}
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		group_cfg_tx.tdm_cfg.num_channels =
			dai_data->group_cfg.tdm_cfg.num_channels;
		group_cfg_tx.tdm_cfg.sample_rate =
			dai_data->group_cfg.tdm_cfg.sample_rate;
		group_cfg_tx.tdm_cfg.bit_width =
			dai_data->group_cfg.tdm_cfg.bit_width;
		group_cfg_tx.tdm_cfg.nslots_per_frame =
			dai_data->group_cfg.tdm_cfg.nslots_per_frame;
		group_cfg_tx.tdm_cfg.slot_width =
			dai_data->group_cfg.tdm_cfg.slot_width;
		group_cfg_tx.tdm_cfg.slot_mask =
			dai_data->group_cfg.tdm_cfg.slot_mask;
	} else {
		group_cfg_rx.tdm_cfg.num_channels =
			dai_data->group_cfg.tdm_cfg.num_channels;
		group_cfg_rx.tdm_cfg.sample_rate =
			dai_data->group_cfg.tdm_cfg.sample_rate;
		group_cfg_rx.tdm_cfg.bit_width =
			dai_data->group_cfg.tdm_cfg.bit_width;
		group_cfg_rx.tdm_cfg.nslots_per_frame =
			dai_data->group_cfg.tdm_cfg.nslots_per_frame;
		group_cfg_rx.tdm_cfg.slot_width =
			dai_data->group_cfg.tdm_cfg.slot_width;
		group_cfg_rx.tdm_cfg.slot_mask =
			dai_data->group_cfg.tdm_cfg.slot_mask;

	memcpy(&group_cfg_tx.group_cfg, &dai_data->group_cfg.group_cfg,
			sizeof(dai_data->group_cfg.group_cfg));
	memcpy(&group_cfg_tx.group_enable, &dai_data->group_cfg.group_enable,
			sizeof(dai_data->group_cfg.group_enable));
	memcpy(&group_cfg_tx.tdm_cfg, &dai_data->group_cfg.tdm_cfg,
			sizeof(dai_data->group_cfg.tdm_cfg));
	pr_debug("%s: TDM GROUP:\n"
		"num_channels=%d sample_rate=%d bit_width=%d\n"
		"nslots_per_frame=%d slot_width=%d slot_mask=0x%x\n",
		__func__,
		group_cfg_tx.tdm_cfg.num_channels,
		group_cfg_tx.tdm_cfg.sample_rate,
		group_cfg_tx.tdm_cfg.bit_width,
		group_cfg_tx.tdm_cfg.nslots_per_frame,
		group_cfg_tx.tdm_cfg.slot_width,
		group_cfg_tx.tdm_cfg.slot_mask);

	}
	return 0;
}

@@ -5550,10 +5561,13 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
	struct msm_dai_q6_tdm_dai_data *dai_data =
		dev_get_drvdata(dai->dev);
	u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
	u16 sec_group_id = 0;
	int group_idx = 0;
	int sec_group_idx = 0;
	u16 prim_port_id = 0;
	u16 sec_port_id = 0;
	atomic_t *group_ref = NULL;
	atomic_t *sec_group_ref = NULL;

	group_idx = msm_dai_q6_get_group_idx(dai->id);
	if (group_idx < 0) {
@@ -5578,13 +5592,14 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
				rc = msm_dai_q6_tdm_set_clk(dai_data,
					dai->id, true);
				if (IS_ERR_VALUE(rc)) {
					dev_err(dai->dev, "%s: fail to enable AFE clk 0x%x\n",
					dev_err(dai->dev,
						"%s:AFE CLK enable fail 0x%x\n",
						__func__, dai->id);
					goto rtn;
				}
			}
			if (dai_data->num_group_ports > 1) {
				dev_dbg(dai->dev, "%s:enable RX afe group\n",
				dev_dbg(dai->dev, "%s:enable afe group\n",
					__func__);
				rc = afe_port_group_enable(group_id,
					&dai_data->group_cfg, true);
@@ -5605,12 +5620,64 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
		*/
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			prim_port_id = dai->id;
			if (dai_data->afe_ebit_unsupported)
			if (dai_data->afe_ebit_unsupported) {
				sec_port_id = AFE_PORT_ID_PRIMARY_TDM_TX;
				sec_group_id =
					AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX;
				sec_group_idx =
					msm_dai_q6_get_group_idx(sec_group_id);
				if (sec_group_idx < 0) {
					dev_err(dai->dev, "%s port id 0x%x\n"
						"not supported\n", __func__,
						sec_group_id);
					goto rtn;
				}
				sec_group_ref = &tdm_group_ref[sec_group_idx];
				if (atomic_read(sec_group_ref) == 0) {
					rc = afe_port_group_enable(
							sec_group_id,
							&group_cfg_tx,
							   true);
					if (IS_ERR_VALUE(rc)) {
							dev_err(dai->dev,
							"%s:failed to\n"
							"enable grp\n"
							"%x\n",	__func__,
							group_id);
						goto rtn;
					}
				}
			}
		} else {
			prim_port_id = dai->id;
			if (dai_data->afe_ebit_unsupported)
			if (dai_data->afe_ebit_unsupported) {
				sec_port_id = AFE_PORT_ID_PRIMARY_TDM_RX;
				sec_group_id =
					AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX;
				sec_group_idx =
					msm_dai_q6_get_group_idx(sec_group_id);
				if (sec_group_idx < 0) {
					dev_err(dai->dev, "%s port id 0x%x\n"
						" not supported\n", __func__,
						sec_group_id);
						goto rtn;
				}
				sec_group_ref = &tdm_group_ref[sec_group_idx];
				if (atomic_read(sec_group_ref) == 0) {
					rc = afe_port_group_enable(
								  sec_group_id,
								  &group_cfg_rx,
								  true);
					if (IS_ERR_VALUE(rc)) {
							dev_err(dai->dev,
							"%s:failed to\n"
							"enable grp\n"
							"%x\n", __func__,
							group_id);
						goto rtn;
					}
				}
			}
		}
		dev_dbg(dai->dev, "\n%s:open prim port id %d TDM rate: %d\n"
				"dai_data->port_cfg.tdm.slot_mask %x\n"
@@ -5667,7 +5734,7 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
			} else {
				set_bit(STATUS_PORT_STARTED,
					dai_data->status_mask);
				atomic_inc(group_ref);
				atomic_inc(sec_group_ref);
			}
		}

@@ -5688,10 +5755,13 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
	struct msm_dai_q6_tdm_dai_data *dai_data =
		dev_get_drvdata(dai->dev);
	u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
	u16 sec_group_id = 0;
	int group_idx = 0;
	int sec_group_idx = 0;
	u16 prim_port_id = 0;
	u16 sec_port_id = 0;
	atomic_t *group_ref = NULL;
	atomic_t *sec_group_ref = NULL;

	group_idx = msm_dai_q6_get_group_idx(dai->id);
	if (group_idx < 0) {
@@ -5707,14 +5777,37 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
	if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			prim_port_id = dai->id;
			if (dai_data->afe_ebit_unsupported)
			if (dai_data->afe_ebit_unsupported) {
				sec_port_id = AFE_PORT_ID_PRIMARY_TDM_TX;
				sec_group_id =
					AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX;
				sec_group_idx =
					msm_dai_q6_get_group_idx(sec_group_id);
				if (sec_group_idx < 0) {
					dev_err(dai->dev, "%s port id 0x%x\n"
						"not supported\n",
						__func__, sec_group_id);
					return;
				}
				sec_group_ref = &tdm_group_ref[sec_group_idx];
			}
		} else {
			prim_port_id = dai->id;
			if (dai_data->afe_ebit_unsupported)
			if (dai_data->afe_ebit_unsupported) {
				sec_port_id = AFE_PORT_ID_PRIMARY_TDM_RX;
				sec_group_id =
					AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX;
				sec_group_idx =
					msm_dai_q6_get_group_idx(sec_group_id);
				if (sec_group_idx < 0) {
					dev_err(dai->dev, "%s port id 0x%x\n"
						"not supported\n",
						__func__, sec_group_id);
					return;
				}
				sec_group_ref = &tdm_group_ref[sec_group_idx];
			}
		}

		rc = afe_close(prim_port_id);
		if (IS_ERR_VALUE(rc)) {
			dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
@@ -5727,6 +5820,7 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
				dev_err(dai->dev, "%s: fail AFE port 0x%x\n",
					__func__, sec_port_id);
			}
			atomic_dec(sec_group_ref);
		}

		atomic_dec(group_ref);
@@ -5749,7 +5843,16 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
					__func__, dai->id);
			}
		}

		if (dai_data->afe_ebit_unsupported) {
			if (atomic_read(sec_group_ref) == 0) {
				rc = afe_port_group_enable(sec_group_id,
							NULL, false);
				if (IS_ERR_VALUE(rc)) {
					dev_err(dai->dev, "%s:failed to\n"
					"enable grp %x\n", __func__, group_id);
				}
			}
		}
		/* TODO: need to monitor PCM/MI2S/TDM HW status */
		/* NOTE: AFE should error out if HW resource contention */

@@ -7125,9 +7228,6 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
		tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_1 ||
		tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_2 ||
		tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_3) {
		dev_dbg(&pdev->dev, "Copy TX group config id %d\n", tdm_dev_id);
		/*memcpy (&group_cfg_tx,&dai_data->group_cfg ,
				sizeof(dai_data->group_cfg));*/
		memcpy(&group_cfg_tx.group_cfg,
			&dai_data->group_cfg.group_cfg ,
			sizeof(dai_data->group_cfg.group_cfg));
@@ -7141,7 +7241,23 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
			"Copy TX group configuration Successfully tdm_id %d\n",
			tdm_dev_id);
	}

	if (tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX ||
		tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_1 ||
		tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_2 ||
		tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_3) {
		memcpy(&group_cfg_rx.group_cfg,
			&dai_data->group_cfg.group_cfg ,
			sizeof(dai_data->group_cfg.group_cfg));
		memcpy(&group_cfg_rx.group_enable,
			&dai_data->group_cfg.group_enable,
			sizeof(dai_data->group_cfg.group_enable));
		memcpy(&group_cfg_rx.tdm_cfg,
			&dai_data->group_cfg.tdm_cfg,
			sizeof(dai_data->group_cfg.tdm_cfg));
		dev_dbg(&pdev->dev,
			"Copy RX group configuration Successfully tdm_id %d\n",
			tdm_dev_id);
	}

	dev_set_drvdata(&pdev->dev, dai_data);