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

Commit cc29b9e8 authored by Ralf Herz's avatar Ralf Herz
Browse files

dsp: support for AFE SPDIF input interface



Support two SPDIF input and two SPDIF output interfaces in AFE.
Support 61937 compressed capture.

Change-Id: Ie71434eb53be798567a6240e0f4bf171aee305b8
Signed-off-by: default avatarRalf Herz <rherz@codeaurora.org>
parent 1fdb5b3e
Loading
Loading
Loading
Loading
+281 −7
Original line number Diff line number Diff line
@@ -103,6 +103,19 @@ struct afe_ctl {
	void *rx_private_data;
	uint32_t mmap_handle;

	void (*pri_spdif_tx_cb)(uint32_t opcode,
		uint32_t token, uint32_t *payload, void *priv);
	void (*sec_spdif_tx_cb)(uint32_t opcode,
		uint32_t token, uint32_t *payload, void *priv);
	void *pri_spdif_tx_private_data;
	void *sec_spdif_tx_private_data;
	struct afe_port_mod_evt_rsp_hdr pri_spdif_evt_pl;
	struct afe_event_fmt_update pri_spdif_fmt_event;
	struct afe_port_mod_evt_rsp_hdr sec_spdif_evt_pl;
	struct afe_event_fmt_update sec_spdif_fmt_event;
	struct work_struct afe_pri_spdif_work;
	struct work_struct afe_sec_spdif_work;

	int	topology[AFE_MAX_PORTS];
	struct cal_type_data *cal_data[MAX_AFE_CAL_TYPES];

@@ -353,6 +366,128 @@ static void afe_notify_dc_presence_work_fn(struct work_struct *work)
		       __func__, event, ret);
}


static const char *const afe_event_port_text[] = {
	"PORT=Primary",
	"PORT=Secondary",
};

static const char * const afe_event_state_text[] = {
	"STATE=Inactive",
	"STATE=Active",
	"STATE=EOS",
};

static const char *const afe_event_rate_text[] = {
	"RATE=32000",
	"RATE=44100",
	"RATE=48000",
	"RATE=88200",
	"RATE=96000",
	"RATE=176400",
	"RATE=192000",
};

static const char *const afe_event_format_text[] = {
	"FORMAT=LPCM",
	"FORMAT=Compr",
};

static void afe_notify_spdif_fmt_update_common(void *payload)
{
	int ret = 0;
	char *env[6];
	struct afe_port_mod_evt_rsp_hdr *evt_pl;
	struct afe_event_fmt_update *fmt_event;

	evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload;
	fmt_event = (struct afe_event_fmt_update *)
			(payload + sizeof(struct afe_port_mod_evt_rsp_hdr));

	env[0] = "SPDIF_FMT_UPDATE=TRUE";
	if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX)
		env[1] = (char *)afe_event_port_text[0];
	else
		env[1] = (char *)afe_event_port_text[1];

	switch (fmt_event->status) {
	case AFE_PORT_STATUS_AUDIO_ACTIVE:
		env[2] = (char *)afe_event_state_text[1];
		break;
	case AFE_PORT_STATUS_AUDIO_EOS:
		env[2] = (char *)afe_event_state_text[2];
		break;
	default:
		env[2] = (char *)afe_event_state_text[0];
	}

	switch (fmt_event->sample_rate) {
	case 32000:
		env[3] = (char *)afe_event_rate_text[0];
		break;
	case 44100:
		env[3] = (char *)afe_event_rate_text[1];
		break;
	case 48000:
		env[3] = (char *)afe_event_rate_text[2];
		break;
	case 88200:
		env[3] = (char *)afe_event_rate_text[3];
		break;
	case 96000:
		env[3] = (char *)afe_event_rate_text[4];
		break;
	case 176400:
		env[3] = (char *)afe_event_rate_text[5];
		break;
	case 192000:
		env[3] = (char *)afe_event_rate_text[6];
		break;
	default:
		env[3] = (char *)afe_event_rate_text[2];
	}

	if (fmt_event->data_format == AFE_NON_LINEAR_DATA)
		env[4] = (char *)afe_event_format_text[1];
	else
		env[4] = (char *)afe_event_format_text[0];

	env[5] = NULL;

	ret = q6core_send_uevent_env(this_afe.uevent_data, env);
	if (ret)
		pr_err("%s: Send UEvent %s failed: %d\n", __func__,
			env[0], ret);
}

static void afe_notify_pri_spdif_fmt_update_work_fn(struct work_struct *work)
{
	afe_notify_spdif_fmt_update_common(&this_afe.pri_spdif_evt_pl);
}

static void afe_notify_sec_spdif_fmt_update_work_fn(struct work_struct *work)
{
	afe_notify_spdif_fmt_update_common(&this_afe.sec_spdif_evt_pl);
}

static void afe_notify_spdif_fmt_update(void *payload)
{
	struct afe_port_mod_evt_rsp_hdr *evt_pl;

	evt_pl = (struct afe_port_mod_evt_rsp_hdr *)payload;
	if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) {
		memcpy(&this_afe.pri_spdif_evt_pl, payload,
			sizeof(struct afe_port_mod_evt_rsp_hdr) +
			sizeof(struct afe_event_fmt_update));
		schedule_work(&this_afe.afe_pri_spdif_work);
	} else {
		memcpy(&this_afe.sec_spdif_evt_pl, payload,
			sizeof(struct afe_port_mod_evt_rsp_hdr) +
			sizeof(struct afe_event_fmt_update));
		schedule_work(&this_afe.afe_sec_spdif_work);
	}
}

static int32_t afe_callback(struct apr_client_data *data, void *priv)
{
	if (!data) {
@@ -549,6 +684,20 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
					flag_dc_presence[1] == 1) {
					afe_notify_dc_presence();
				}
			} else if (evt_pl->port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) {
				if (this_afe.pri_spdif_tx_cb) {
					this_afe.pri_spdif_tx_cb(data->opcode,
						data->token, data->payload,
						this_afe.pri_spdif_tx_private_data);
				}
				afe_notify_spdif_fmt_update(data->payload);
			} else if (evt_pl->port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX) {
				if (this_afe.sec_spdif_tx_cb) {
					this_afe.sec_spdif_tx_cb(data->opcode,
						data->token, data->payload,
						this_afe.sec_spdif_tx_private_data);
				}
				afe_notify_spdif_fmt_update(data->payload);
			} else {
				pr_debug("%s: mod ID = 0x%x event_id = 0x%x\n",
						__func__, evt_pl->module_id,
@@ -639,6 +788,13 @@ int afe_sizeof_cfg_cmd(u16 port_id)
		ret_size =
		SIZEOF_CFG_CMD(afe_param_id_hdmi_multi_chan_audio_cfg);
		break;
	case AFE_PORT_ID_PRIMARY_SPDIF_RX:
	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
	case AFE_PORT_ID_SECONDARY_SPDIF_RX:
	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
		ret_size =
		SIZEOF_CFG_CMD(afe_param_id_spdif_cfg_v2);
		break;
	case SLIMBUS_0_RX:
	case SLIMBUS_0_TX:
	case SLIMBUS_1_RX:
@@ -2806,11 +2962,14 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port,
		goto fail_cmd;
	}

	ret = afe_send_spdif_ch_status_cfg(&spdif_port->ch_status, port_id);
	if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX) {
		ret = afe_send_spdif_ch_status_cfg(&spdif_port->ch_status,
						   port_id);
		if (ret < 0) {
			pr_err("%s: afe send failed %d\n", __func__, ret);
			goto fail_cmd;
		}
	}

	return afe_send_cmd_port_start(port_id);

@@ -2819,6 +2978,105 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port,
}
EXPORT_SYMBOL(afe_spdif_port_start);

/**
 * afe_spdif_reg_event_cfg -
 *         register for event from AFE spdif port
 *
 * @port_id: Port ID to register event
 * @reg_flag: register or unregister
 * @cb: callback function to invoke for events from module
 * @private_data: private data to sent back in callback fn
 *
 * Returns 0 on success or error on failure
 */
int afe_spdif_reg_event_cfg(u16 port_id, u16 reg_flag,
		void (*cb)(uint32_t opcode,
		uint32_t token, uint32_t *payload, void *priv),
		void *private_data)
{
	struct afe_port_cmd_event_cfg *config;
	struct afe_port_cmd_mod_evt_cfg_payload pl;
	int index;
	int ret;
	int num_events = 1;
	int cmd_size = sizeof(struct afe_port_cmd_event_cfg) +
		(num_events * sizeof(struct afe_port_cmd_mod_evt_cfg_payload));

	config = kzalloc(cmd_size, GFP_KERNEL);
	if (!config)
		return -ENOMEM;

	if (port_id == AFE_PORT_ID_PRIMARY_SPDIF_TX) {
		this_afe.pri_spdif_tx_cb = cb;
		this_afe.pri_spdif_tx_private_data = private_data;
	} else if (port_id == AFE_PORT_ID_SECONDARY_SPDIF_TX) {
		this_afe.sec_spdif_tx_cb = cb;
		this_afe.sec_spdif_tx_private_data = private_data;
	} else {
		pr_err("%s: wrong port id 0x%x\n", __func__, port_id);
		ret = -EINVAL;
		goto fail_idx;
	}

	index = q6audio_get_port_index(port_id);
	if (index < 0) {
		pr_err("%s: Invalid index number: %d\n", __func__, index);
		ret = -EINVAL;
		goto fail_idx;
	}

	memset(&pl, 0, sizeof(pl));
	pl.module_id = AFE_MODULE_CUSTOM_EVENTS;
	pl.event_id = AFE_PORT_FMT_UPDATE_EVENT;
	pl.reg_flag = reg_flag;

	config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
				APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
	config->hdr.pkt_size = cmd_size;
	config->hdr.src_port = 1;
	config->hdr.dest_port = 1;
	config->hdr.token = index;

	config->hdr.opcode = AFE_PORT_CMD_MOD_EVENT_CFG;
	config->port_id = q6audio_get_port_id(port_id);
	config->num_events = num_events;
	config->version = 1;
	memcpy(config->payload, &pl, sizeof(pl));
	atomic_set(&this_afe.state, 1);
	atomic_set(&this_afe.status, 0);
	ret = apr_send_pkt(this_afe.apr, (uint32_t *) config);
	if (ret < 0) {
		pr_err("%s: port = 0x%x failed %d\n",
			__func__, port_id, ret);
		goto fail_cmd;
	}
	ret = wait_event_timeout(this_afe.wait[index],
		(atomic_read(&this_afe.state) == 0),
		msecs_to_jiffies(TIMEOUT_MS));
	if (!ret) {
		pr_err("%s: wait_event timeout\n", __func__);
		ret = -EINVAL;
		goto fail_cmd;
	}
	if (atomic_read(&this_afe.status) > 0) {
		pr_err("%s: config cmd failed [%s]\n",
			__func__, adsp_err_get_err_str(
			atomic_read(&this_afe.status)));
		ret = adsp_err_get_lnx_err_code(
				atomic_read(&this_afe.status));
		goto fail_idx;
	}
	ret = 0;
fail_cmd:
	pr_debug("%s: config.opcode 0x%x status %d\n",
		__func__, config->hdr.opcode, ret);

fail_idx:
	kfree(config);
	return ret;
}
EXPORT_SYMBOL(afe_spdif_reg_event_cfg);

int afe_send_slot_mapping_cfg(
	struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg,
	u16 port_id)
@@ -3880,7 +4138,10 @@ int afe_get_port_index(u16 port_id)
	case MI2S_TX: return IDX_MI2S_TX;
	case HDMI_RX: return IDX_HDMI_RX;
	case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX;
	case AFE_PORT_ID_SPDIF_RX: return IDX_SPDIF_RX;
	case AFE_PORT_ID_PRIMARY_SPDIF_RX: return IDX_PRIMARY_SPDIF_RX;
	case AFE_PORT_ID_PRIMARY_SPDIF_TX: return IDX_PRIMARY_SPDIF_TX;
	case AFE_PORT_ID_SECONDARY_SPDIF_RX: return IDX_SECONDARY_SPDIF_RX;
	case AFE_PORT_ID_SECONDARY_SPDIF_TX: return IDX_SECONDARY_SPDIF_TX;
	case RSVD_2: return IDX_RSVD_2;
	case RSVD_3: return IDX_RSVD_3;
	case DIGI_MIC_TX: return IDX_DIGI_MIC_TX;
@@ -4259,6 +4520,12 @@ int afe_open(u16 port_id,
	case DISPLAY_PORT_RX:
		cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
		break;
	case AFE_PORT_ID_PRIMARY_SPDIF_RX:
	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
	case AFE_PORT_ID_SECONDARY_SPDIF_RX:
	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
		cfg_type = AFE_PARAM_ID_SPDIF_CONFIG;
		break;
	case SLIMBUS_0_RX:
	case SLIMBUS_0_TX:
	case SLIMBUS_1_RX:
@@ -6100,7 +6367,10 @@ int afe_validate_port(u16 port_id)
	case MI2S_TX:
	case HDMI_RX:
	case DISPLAY_PORT_RX:
	case AFE_PORT_ID_SPDIF_RX:
	case AFE_PORT_ID_PRIMARY_SPDIF_RX:
	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
	case AFE_PORT_ID_SECONDARY_SPDIF_RX:
	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
	case RSVD_2:
	case RSVD_3:
	case DIGI_MIC_TX:
@@ -7695,6 +7965,10 @@ int __init afe_init(void)
	q6core_init_uevent_data(this_afe.uevent_data, "q6afe_uevent");

	INIT_WORK(&this_afe.afe_dc_work, afe_notify_dc_presence_work_fn);
	INIT_WORK(&this_afe.afe_pri_spdif_work,
		  afe_notify_pri_spdif_fmt_update_work_fn);
	INIT_WORK(&this_afe.afe_sec_spdif_work,
		  afe_notify_sec_spdif_fmt_update_work_fn);

	return 0;
}
+81 −1
Original line number Diff line number Diff line
@@ -1953,6 +1953,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
		case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
		case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
		case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS:
		case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
		case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
			pr_debug("%s: session %d opcode 0x%x token 0x%x Payload = [0x%x] stat 0x%x src %d dest %d\n",
				__func__, ac->session,
@@ -2166,7 +2167,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)

		if (ac->io_mode & SYNC_IO_MODE) {
			if (port->buf == NULL) {
				pr_err("%s: Unexpected Write Done\n", __func__);
				pr_err("%s: Unexpected Read Done\n", __func__);
				spin_unlock_irqrestore(
					&(session[session_id].session_lock),
					flags);
@@ -2833,6 +2834,85 @@ int q6asm_set_soft_volume_module_instance_ids(int instance,
}
EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids);

/**
 * q6asm_open_read_compressed -
 *       command to open ASM in compressed read mode
 *
 * @ac: Audio client handle
 * @format: capture format for ASM
 * @passthrough_flag: flag to indicate passthrough option
 *
 * Returns 0 on success or error on failure
 */
int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format,
			       uint32_t passthrough_flag)
{
	int rc = 0;
	struct asm_stream_cmd_open_read_compressed open;

	if (ac == NULL) {
		pr_err("%s: ac[%pK] NULL\n",  __func__, ac);
		rc = -EINVAL;
		goto fail_cmd;
	}

	if (ac->apr == NULL) {
		pr_err("%s: APR handle[%pK] NULL\n", __func__,  ac->apr);
		rc = -EINVAL;
		goto fail_cmd;
	}
	pr_debug("%s: session[%d] wr_format[0x%x]\n", __func__, ac->session,
		format);

	q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
	open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ_COMPRESSED;
	atomic_set(&ac->cmd_state, -1);

	/*
	 * Below flag indicates whether DSP shall keep IEC61937 packing or
	 * unpack to raw compressed format
	 */
	if (format == FORMAT_IEC61937) {
		open.mode_flags = 0x1;
		pr_debug("%s: Flag 1 IEC61937 output\n", __func__);
	} else {
		open.mode_flags = 0;
		open.frames_per_buf = 1;
		pr_debug("%s: Flag 0 RAW_COMPR output\n", __func__);
	}

	rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
	if (rc < 0) {
		pr_err("%s: open failed op[0x%x]rc[%d]\n",
			__func__, open.hdr.opcode, rc);
		rc = -EINVAL;
		goto fail_cmd;
	}
	rc = wait_event_timeout(ac->cmd_wait,
			(atomic_read(&ac->cmd_state) >= 0), 1*HZ);
	if (!rc) {
		pr_err("%s: timeout. waited for OPEN_READ_COMPR rc[%d]\n",
			__func__, rc);
		rc = -ETIMEDOUT;
		goto fail_cmd;
	}

	if (atomic_read(&ac->cmd_state) > 0) {
		pr_err("%s: DSP returned error[%s]\n",
			__func__, adsp_err_get_err_str(
			atomic_read(&ac->cmd_state)));
		rc = adsp_err_get_lnx_err_code(
			atomic_read(&ac->cmd_state));
		goto fail_cmd;
	}

	return 0;

fail_cmd:
	return rc;
}
EXPORT_SYMBOL(q6asm_open_read_compressed);

static int __q6asm_open_read(struct audio_client *ac,
			     uint32_t format, uint16_t bits_per_sample,
			     uint32_t pcm_format_block_ver,
+20 −3
Original line number Diff line number Diff line
@@ -50,7 +50,10 @@ int q6audio_get_port_index(u16 port_id)
	case MI2S_TX: return IDX_MI2S_TX;
	case HDMI_RX: return IDX_HDMI_RX;
	case DISPLAY_PORT_RX: return IDX_DISPLAY_PORT_RX;
	case AFE_PORT_ID_SPDIF_RX: return IDX_SPDIF_RX;
	case AFE_PORT_ID_PRIMARY_SPDIF_RX: return IDX_PRIMARY_SPDIF_RX;
	case AFE_PORT_ID_PRIMARY_SPDIF_TX: return IDX_PRIMARY_SPDIF_TX;
	case AFE_PORT_ID_SECONDARY_SPDIF_RX: return IDX_SECONDARY_SPDIF_RX;
	case AFE_PORT_ID_SECONDARY_SPDIF_TX: return IDX_SECONDARY_SPDIF_TX;
	case RSVD_2: return IDX_RSVD_2;
	case RSVD_3: return IDX_RSVD_3;
	case DIGI_MIC_TX: return IDX_DIGI_MIC_TX;
@@ -351,7 +354,14 @@ int q6audio_get_port_id(u16 port_id)
	case HDMI_RX: return AFE_PORT_ID_MULTICHAN_HDMI_RX;
	case DISPLAY_PORT_RX:
			return AFE_PORT_ID_HDMI_OVER_DP_RX;
	case AFE_PORT_ID_SPDIF_RX: return AFE_PORT_ID_SPDIF_RX;
	case AFE_PORT_ID_PRIMARY_SPDIF_RX:
			return AFE_PORT_ID_PRIMARY_SPDIF_RX;
	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
			return AFE_PORT_ID_PRIMARY_SPDIF_TX;
	case AFE_PORT_ID_SECONDARY_SPDIF_RX:
			return AFE_PORT_ID_SECONDARY_SPDIF_RX;
	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
			return AFE_PORT_ID_SECONDARY_SPDIF_TX;
	case RSVD_2: return IDX_RSVD_2;
	case RSVD_3: return IDX_RSVD_3;
	case DIGI_MIC_TX: return AFE_PORT_ID_DIGITAL_MIC_TX;
@@ -777,6 +787,10 @@ int q6audio_is_digital_pcm_interface(u16 port_id)
	case AFE_PORT_ID_WSA_CODEC_DMA_TX_2:
	case AFE_PORT_ID_VA_CODEC_DMA_TX_0:
	case AFE_PORT_ID_VA_CODEC_DMA_TX_1:
	case AFE_PORT_ID_PRIMARY_SPDIF_RX:
	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
	case AFE_PORT_ID_SECONDARY_SPDIF_RX:
	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
		break;
	default:
		ret = -EINVAL;
@@ -854,7 +868,10 @@ int q6audio_validate_port(u16 port_id)
	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
	case AFE_PORT_ID_SECONDARY_MI2S_RX:
	case AFE_PORT_ID_SECONDARY_MI2S_TX:
	case AFE_PORT_ID_SPDIF_RX:
	case AFE_PORT_ID_PRIMARY_SPDIF_RX:
	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
	case AFE_PORT_ID_SECONDARY_SPDIF_RX:
	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
	case AFE_PORT_ID_TERTIARY_MI2S_RX:
	case AFE_PORT_ID_TERTIARY_MI2S_TX:
	case AFE_PORT_ID_QUINARY_MI2S_RX:
+17 −0
Original line number Diff line number Diff line
@@ -189,6 +189,23 @@ int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *event)
}
EXPORT_SYMBOL(q6core_send_uevent);

/**
 * q6core_send_uevent_env - send uevent with list of keys to userspace.
 *
 * @uevent_data: uevent data.
 * @event: array of event keys to send.
 *
 * Returns 0 on success or error otherwise.
 */
int q6core_send_uevent_env(struct audio_uevent_data *uevent_data, char *env[])
{
	if (!env || !uevent_data)
		return -EINVAL;

	return kobject_uevent_env(&uevent_data->kobj, KOBJ_CHANGE, env);
}
EXPORT_SYMBOL(q6core_send_uevent_env);

static int parse_fwk_version_info(uint32_t *payload)
{
	size_t ver_size;
+87 −10
Original line number Diff line number Diff line
@@ -1236,7 +1236,11 @@ struct adm_cmd_connect_afe_port_v5 {
#define AFE_PORT_ID_QUINARY_PCM_RX       0x103C
#define AFE_PORT_ID_QUINARY_PCM_TX       0x103D

#define AFE_PORT_ID_SPDIF_RX                0x5000
#define AFE_PORT_ID_PRIMARY_SPDIF_RX        0x5000
#define AFE_PORT_ID_PRIMARY_SPDIF_TX        0x5001
#define AFE_PORT_ID_SECONDARY_SPDIF_RX      0x5002
#define AFE_PORT_ID_SECONDARY_SPDIF_TX      0x5003

#define  AFE_PORT_ID_RT_PROXY_PORT_001_RX   0x2000
#define  AFE_PORT_ID_RT_PROXY_PORT_001_TX   0x2001
#define AFE_PORT_ID_INTERNAL_BT_SCO_RX      0x3000
@@ -2270,6 +2274,7 @@ struct afe_param_id_i2s_cfg {
 * This param id is used to configure PCM interface
 */

#define AFE_API_VERSION_SPDIF_CONFIG_V2 0x2
#define AFE_API_VERSION_SPDIF_CONFIG 0x1
#define AFE_API_VERSION_SPDIF_CH_STATUS_CONFIG 0x1
#define AFE_API_VERSION_SPDIF_CLK_CONFIG 0x1
@@ -2283,10 +2288,20 @@ struct afe_param_id_i2s_cfg {
#define AFE_PORT_CLK_ROOT_LPAPLL 0x3
#define AFE_PORT_CLK_ROOT_LPAQ6PLL   0x4

struct afe_param_id_spdif_cfg {
#define AFE_MODULE_CUSTOM_EVENTS            0x00010251

#define AFE_PORT_FMT_UPDATE_EVENT           0x0001010E

#define AFE_API_VERSION_EVENT_FMT_UPDATE    0x1
#define AFE_PORT_STATUS_NO_SIGNAL           0
#define AFE_PORT_STATUS_AUDIO_ACTIVE        1
#define AFE_PORT_STATUS_AUDIO_EOS           2

struct afe_param_id_spdif_cfg_v2 {
/* Minor version used for tracking the version of the SPDIF
 * configuration interface.
 * Supported values: #AFE_API_VERSION_SPDIF_CONFIG
 * Supported values: #AFE_API_VERSION_SPDIF_CONFIG,
 *                   #AFE_API_VERSION_SPDIF_CONFIG_V2
 */
	u32	spdif_cfg_minor_version;

@@ -2318,6 +2333,8 @@ struct afe_param_id_spdif_cfg {
	u16	bit_width;
/* This field must be set to zero. */
	u16	reserved;
/* Input select for spdif input, must be set to 0 for spdif output. */
	u32	src_sel;
} __packed;

struct afe_param_id_spdif_ch_status_cfg {
@@ -2344,6 +2361,7 @@ struct afe_param_id_spdif_ch_status_cfg {
 */
} __packed;

/* deprecated */
struct afe_param_id_spdif_clk_cfg {
	u32 clk_cfg_minor_version;
/* Minor version used for tracking the version of SPDIF
@@ -2367,8 +2385,43 @@ struct afe_param_id_spdif_clk_cfg {
 */
} __packed;

struct afe_event_fmt_update {
	/* Tracks the configuration of this event. */
	u32 minor_version;

	/* Detected port status.
	 * Supported values:
	 * - #AFE_PORT_STATUS_NO_SIGNAL
	 * - #AFE_PORT_STATUS_AUDIO_ACTIVE
	 * - #AFE_PORT_STATUS_AUDIO_EOS
	 */
	u32 status;

	/* Sampling rate of the port.
	 * Supported values:
	 * - #AFE_PORT_SAMPLE_RATE_32K
	 * - #AFE_PORT_SAMPLE_RATE_44_1K
	 * - #AFE_PORT_SAMPLE_RATE_48K
	 * - #AFE_PORT_SAMPLE_RATE_88_2K
	 * - #AFE_PORT_SAMPLE_RATE_96K
	 * - #AFE_PORT_SAMPLE_RATE_176_4K
	 * - #AFE_PORT_SAMPLE_RATE_192K
	 */
	u32 sample_rate;

	/* Data format of the port.
	 * Supported values:
	 * - #AFE_LINEAR_PCM_DATA
	 * - #AFE_NON_LINEAR_DATA
	 */
	u16 data_format;

	/* First 6 bytes of channel status bits */
	u8 channel_status[6];
} __packed;

struct afe_spdif_port_config {
	struct afe_param_id_spdif_cfg            cfg;
	struct afe_param_id_spdif_cfg_v2         cfg;
	struct afe_param_id_spdif_ch_status_cfg  ch_status;
} __packed;

@@ -4093,7 +4146,7 @@ union afe_port_config {
	struct afe_param_id_internal_bt_fm_cfg    int_bt_fm;
	struct afe_param_id_pseudo_port_cfg       pseudo_port;
	struct afe_param_id_device_hw_delay_cfg   hw_delay;
	struct afe_param_id_spdif_cfg             spdif;
	struct afe_param_id_spdif_cfg_v2          spdif;
	struct afe_param_id_set_topology_cfg      topology;
	struct afe_param_id_tdm_cfg               tdm;
	struct afe_param_id_usb_audio_cfg         usb_audio;
@@ -4793,7 +4846,7 @@ struct asm_generic_compressed_fmt_blk_t {

/* Command to send sample rate & channels for IEC61937 (compressed) or IEC60958
 * (pcm) streams. Both audio standards use the same format and are used for
 * HDMI or SPDIF.
 * HDMI or SPDIF output.
 */
#define ASM_DATA_CMD_IEC_60958_MEDIA_FMT        0x0001321E

@@ -7669,11 +7722,23 @@ struct asm_data_cmd_remove_silence {

#define ASM_STREAM_CMD_OPEN_READ_COMPRESSED                        0x00010D95

/* Bitmask for the IEC 61937 to 61937 pass-through capture. */
#define ASM_BIT_MASK_IEC_61937_PASS_THROUGH_FLAG        (0x00000001UL)

/* Shift value for the IEC 61937 to 61937 pass-through capture. */
#define ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG           0

struct asm_stream_cmd_open_read_compressed {
	struct apr_hdr hdr;
	u32                    mode_flags;
/* Mode flags that indicate whether meta information per encoded
 * frame is to be provided.
 * frame is to be provided and packaging.
 * Supported values for bit 0: (IEC 61937 pass-through mode)
 * - 0 -- Unpack the IEC 61937 format stream to RAW compressed format
 * - 1 -- Pass-through transfer of the IEC 61937 format stream
 * - Use #ASM_BIT_MASK_IEC_61937_PASS_THROUGH_FLAG to set the bitmask
 *   and #ASM_SHIFT_IEC_61937_PASS_THROUGH_FLAG to set the shift value
 *   for this bit.
 * Supported values for bit 4:
 * - 0 -- Return data buffer contains all encoded frames only; it does
 *      not contain frame metadata.
@@ -7687,7 +7752,9 @@ struct asm_stream_cmd_open_read_compressed {
	u32                    frames_per_buf;
/* Indicates the number of frames that need to be returned per
 * read buffer
 * Supported values: should be greater than 0
 * Supported values: should be greater than 0 for IEC to RAW compressed
 *                   unpack mode.
 *                   Value is don't care for IEC 61937 pass-through mode.
 */

} __packed;
@@ -10321,8 +10388,18 @@ enum afe_lpass_clk_mode {
/* Clock ID for AHB HDMI input */
#define Q6AFE_LPASS_CLK_ID_AHB_HDMI_INPUT                         0x400

/* Clock ID for SPDIF core */
#define Q6AFE_LPASS_CLK_ID_SPDIF_CORE                             0x500
/* Clock ID for the primary SPDIF output core. */
#define AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_CORE              0x500
/* Clock ID for the secondary SPDIF output core. */
#define AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_CORE              0x501
/* Clock ID for the primary SPDIF input core. */
#define AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_INPUT_CORE               0x502
/* Clock ID for the secondary SPDIF input core. */
#define AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_INPUT_CORE               0x503
/* Clock ID for the secondary SPDIF output NPL clk. */
#define AFE_CLOCK_SET_CLOCK_ID_PRI_SPDIF_OUTPUT_NPL               0x504
/* Clock ID for the primary SPDIF output NPL clk. */
#define AFE_CLOCK_SET_CLOCK_ID_SEC_SPDIF_OUTPUT_NPL               0x505


/* Clock attribute for invalid use (reserved for internal usage) */
Loading