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

Commit a93b03aa authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "audio-driver: support tdm multi lane for sa8155"

parents 7c39552f b84eea37
Loading
Loading
Loading
Loading
+45 −6
Original line number Diff line number Diff line
@@ -272,6 +272,7 @@ struct msm_dai_q6_tdm_dai_data {
	struct afe_clk_set clk_set; /* hold LPASS clock config. */
	union afe_port_group_config group_cfg; /* hold tdm group config */
	struct afe_tdm_port_config port_cfg; /* hold tdm config */
	struct afe_param_id_tdm_lane_cfg lane_cfg; /* hold tdm lane config */
};

/* MI2S format field for AFE_PORT_CMD_I2S_CONFIG command
@@ -337,6 +338,11 @@ static DEFINE_MUTEX(tdm_mutex);

static atomic_t tdm_group_ref[IDX_GROUP_TDM_MAX];

static struct afe_param_id_tdm_lane_cfg tdm_lane_cfg = {
	AFE_GROUP_DEVICE_ID_QUINARY_TDM_RX,
	0x0,
};

/* cache of group cfg per parent node */
static struct afe_param_id_group_device_tdm_cfg tdm_group_cfg = {
	AFE_API_VERSION_GROUP_DEVICE_TDM_CONFIG,
@@ -6590,6 +6596,24 @@ static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
	} else
		dev_dbg(&pdev->dev, "%s: clk attribute not found\n", __func__);

	/* extract tdm lane cfg to static */
	tdm_lane_cfg.port_id = tdm_group_cfg.group_id;
	tdm_lane_cfg.lane_mask = AFE_LANE_MASK_INVALID;
	if (of_find_property(pdev->dev.of_node,
			"qcom,msm-cpudai-tdm-lane-mask", NULL)) {
		rc = of_property_read_u16(pdev->dev.of_node,
			"qcom,msm-cpudai-tdm-lane-mask",
			&tdm_lane_cfg.lane_mask);
		if (rc) {
			dev_err(&pdev->dev, "%s: value for tdm lane mask not found %s\n",
				__func__, "qcom,msm-cpudai-tdm-lane-mask");
			goto rtn;
		}
		dev_dbg(&pdev->dev, "%s: tdm lane mask from DT file %d\n",
			__func__, tdm_lane_cfg.lane_mask);
	} else
		dev_dbg(&pdev->dev, "%s: tdm lane mask not found\n", __func__);

	/* extract tdm clk src master/slave info into static */
	rc = of_property_read_u32(pdev->dev.of_node,
		"qcom,msm-cpudai-tdm-clk-internal",
@@ -7696,7 +7720,7 @@ static int msm_dai_q6_dai_tdm_remove(struct snd_soc_dai *dai)

		if (atomic_read(group_ref) == 0) {
			rc = afe_port_group_enable(group_id,
				NULL, false);
				NULL, false, NULL);
			if (rc < 0) {
				dev_err(dai->dev, "fail to disable AFE group 0x%x\n",
					group_id);
@@ -8066,7 +8090,17 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
	 * NOTE: group config is set to the same as slot config.
	 */
	tdm_group->bit_width = tdm_group->slot_width;

	/*
	 * for multi lane scenario
	 * Total number of active channels = number of active lanes * number of active slots.
	 */
	if (dai_data->lane_cfg.lane_mask != AFE_LANE_MASK_INVALID)
		tdm_group->num_channels = tdm_group->nslots_per_frame
			* num_of_bits_set(dai_data->lane_cfg.lane_mask);
	else
		tdm_group->num_channels = tdm_group->nslots_per_frame;

	tdm_group->sample_rate = dai_data->rate;

	pr_debug("%s: TDM GROUP:\n"
@@ -8091,6 +8125,10 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
		tdm_group->port_id[5],
		tdm_group->port_id[6],
		tdm_group->port_id[7]);
	pr_debug("%s: TDM GROUP ID 0x%x lane mask 0x%x:\n",
		__func__,
		tdm_group->group_id,
		dai_data->lane_cfg.lane_mask);

	/*
	 * update tdm config param
@@ -8246,7 +8284,8 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
			 */
			if (dai_data->num_group_ports > 1) {
				rc = afe_port_group_enable(group_id,
					&dai_data->group_cfg, true);
					&dai_data->group_cfg, true,
					&dai_data->lane_cfg);
				if (rc < 0) {
					dev_err(dai->dev,
					"%s: fail to enable AFE group 0x%x\n",
@@ -8261,7 +8300,7 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
		if (rc < 0) {
			if (atomic_read(group_ref) == 0) {
				afe_port_group_enable(group_id,
					NULL, false);
					NULL, false, NULL);
			}
			if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) {
				msm_dai_q6_tdm_set_clk(dai_data,
@@ -8318,7 +8357,7 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,

		if (atomic_read(group_ref) == 0) {
			rc = afe_port_group_enable(group_id,
				NULL, false);
				NULL, false, NULL);
			if (rc < 0) {
				dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n",
					__func__, group_id);
@@ -10223,7 +10262,7 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
	dai_data->group_cfg.tdm_cfg = tdm_group_cfg;
	/* copy static num group ports per parent node */
	dai_data->num_group_ports = num_tdm_group_ports;

	dai_data->lane_cfg = tdm_lane_cfg;

	dev_set_drvdata(&pdev->dev, dai_data);

+56 −2
Original line number Diff line number Diff line
@@ -5422,6 +5422,53 @@ int afe_port_group_set_param(u16 group_id,
	return ret;
}

/**
 * afe_port_tdm_lane_config -
 * to configure group TDM lane mask with specified configuration
 *
 * @group_id: AFE group id number
 * @lane_cfg: TDM lane mask configutation
 *
 * Returns 0 on success or error value on failure.
 */
static int afe_port_tdm_lane_config(u16 group_id,
	struct afe_param_id_tdm_lane_cfg *lane_cfg)
{
	struct param_hdr_v3 param_hdr;
	int ret = 0;

	if (lane_cfg == NULL ||
		lane_cfg->lane_mask == AFE_LANE_MASK_INVALID) {
		pr_debug("%s: lane cfg not supported for group id: 0x%x\n",
			__func__, group_id);
		return ret;
	}

	pr_debug("%s: group id: 0x%x lane mask 0x%x\n", __func__,
		group_id, lane_cfg->lane_mask);

	memset(&param_hdr, 0, sizeof(param_hdr));

	ret = afe_q6_interface_prepare();
	if (ret != 0) {
		pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
		return ret;
	}

	param_hdr.module_id = AFE_MODULE_GROUP_DEVICE;
	param_hdr.instance_id = INSTANCE_ID_0;
	param_hdr.param_id = AFE_PARAM_ID_TDM_LANE_CONFIG;
	param_hdr.param_size = sizeof(struct afe_param_id_tdm_lane_cfg);

	ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
						   (u8 *)lane_cfg);
	if (ret)
		pr_err("%s: AFE_PARAM_ID_TDM_LANE_CONFIG failed %d\n",
			__func__, ret);

	return ret;
}

/**
 * afe_port_group_enable -
 *         command to enable AFE port group
@@ -5429,12 +5476,14 @@ int afe_port_group_set_param(u16 group_id,
 * @group_id: group ID for AFE port group
 * @afe_group_config: config for AFE group
 * @enable: flag to indicate enable or disable
 * @lane_cfg: TDM lane mask configutation
 *
 * Returns 0 on success or error on failure
 */
int afe_port_group_enable(u16 group_id,
	union afe_port_group_config *afe_group_config,
	u16 enable)
	u16 enable,
	struct afe_param_id_tdm_lane_cfg *lane_cfg)
{
	struct afe_group_device_enable group_enable;
	struct param_hdr_v3 param_hdr;
@@ -5458,6 +5507,12 @@ int afe_port_group_enable(u16 group_id,
			pr_err("%s: afe send failed %d\n", __func__, ret);
			return ret;
		}
		ret = afe_port_tdm_lane_config(group_id, lane_cfg);
		if (ret < 0) {
			pr_err("%s: afe send lane config failed %d\n",
				__func__, ret);
			return ret;
		}
	}

	param_hdr.module_id = AFE_MODULE_GROUP_DEVICE;
@@ -8998,4 +9053,3 @@ int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle)
	return ret;
}
EXPORT_SYMBOL(afe_unvote_lpass_core_hw);
+33 −0
Original line number Diff line number Diff line
@@ -1354,6 +1354,8 @@ struct adm_cmd_connect_afe_port_v5 {
#define AFE_LOOPBACK_TX	0x6001
#define DISPLAY_PORT_RX	0x6020

#define AFE_LANE_MASK_INVALID 0

#define AFE_PORT_INVALID 0xFFFF
#define SLIMBUS_INVALID AFE_PORT_INVALID

@@ -12430,4 +12432,35 @@ struct afe_param_id_vad_cfg_t {

#define AFE_PARAM_ID_VAD_CORE_CFG                              0x000102BB

/**
 * This parameter is should be used to configure the AFE TDM
 * interface lane configuration.
 * Regular TDM interface ports:
 * This parameter ID must be used with module ID
 * AFE_MODULE_AUDIO_DEV_INTERFACE and set using the AFE_PORT_CMD_SET_PARAM_V3
 * command for the AFE TDM interface port IDs.
 * Group device TDM interface ports:
 * This parameter ID must be used with module ID AFE_MODULE_GROUP_DEVICE
 * and set using the AFE_SVC_CMD_SET_PARAM_V2 command for the AFE TDM group IDs.
 */
#define AFE_PARAM_ID_TDM_LANE_CONFIG                           0x000102C1

/* Payload of the AFE_PARAM_ID_TDM_LANE_CONFIG parameter used by
 * AFE_MODULE_AUDIO_DEV_INTERFACE.
 */
struct afe_param_id_tdm_lane_cfg {
	uint16_t port_id;
	/** ID of the TDM interface.
	 * For regular TDM interfaces value corresponds to valid port ID.
	 * For group devices TDM interface value corresponds to valid group device ID.
	 */

	uint16_t lane_mask;
	/** Position of the active lanes. Bits 0 to N correspond to lanes 0 to N.
	 * 1 to 2^N-1 When a bit is set, the corresponding lane is active.
	 * The number of active lanes can be inferred from the number of bits
	 * set in the mask.
	 */
};

#endif /*_APR_AUDIO_V2_H_ */
+2 −1
Original line number Diff line number Diff line
@@ -432,7 +432,8 @@ int afe_set_aanc_noise_level(int val);
int afe_port_group_set_param(u16 group_id,
	union afe_port_group_config *afe_group_config);
int afe_port_group_enable(u16 group_id,
	union afe_port_group_config *afe_group_config, u16 enable);
	union afe_port_group_config *afe_group_config, u16 enable,
	struct afe_param_id_tdm_lane_cfg *lane_cfg);
int afe_unmap_rtac_block(uint32_t *mem_map_handle);
int afe_map_rtac_block(struct rtac_cal_block_data *cal_block);
int afe_send_slot_mapping_cfg(