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: Ralf Herz <rherz@codeaurora.org>
This commit is contained in:
parent
1fdb5b3e3f
commit
cc29b9e839
8 changed files with 501 additions and 23 deletions
288
dsp/q6afe.c
288
dsp/q6afe.c
|
@ -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:
|
||||
|
@ -2793,7 +2949,7 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port,
|
|||
param_hdr, (u8 *) spdif_port);
|
||||
if (ret) {
|
||||
pr_err("%s: AFE enable for port 0x%x failed ret = %d\n",
|
||||
__func__, port_id, ret);
|
||||
__func__, port_id, ret);
|
||||
goto fail_cmd;
|
||||
}
|
||||
|
||||
|
@ -2806,10 +2962,13 @@ 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 (ret < 0) {
|
||||
pr_err("%s: afe send failed %d\n", __func__, ret);
|
||||
goto fail_cmd;
|
||||
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;
|
||||
}
|
||||
|
|
82
dsp/q6asm.c
82
dsp/q6asm.c
|
@ -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,
|
||||
|
|
|
@ -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
dsp/q6core.c
17
dsp/q6core.c
|
@ -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;
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -107,7 +107,7 @@ enum {
|
|||
/* IDX 45->49 */
|
||||
IDX_SLIMBUS_6_RX,
|
||||
IDX_SLIMBUS_6_TX,
|
||||
IDX_SPDIF_RX,
|
||||
IDX_PRIMARY_SPDIF_RX,
|
||||
IDX_GLOBAL_CFG,
|
||||
IDX_AUDIO_PORT_ID_I2S_RX,
|
||||
/* IDX 50->53 */
|
||||
|
@ -229,7 +229,7 @@ enum {
|
|||
IDX_AFE_PORT_ID_QUINARY_TDM_TX_6,
|
||||
IDX_AFE_PORT_ID_QUINARY_TDM_RX_7,
|
||||
IDX_AFE_PORT_ID_QUINARY_TDM_TX_7,
|
||||
/* IDX 161 to 166 */
|
||||
/* IDX 161 to 167 */
|
||||
IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_0,
|
||||
IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_0,
|
||||
IDX_AFE_PORT_ID_WSA_CODEC_DMA_RX_1,
|
||||
|
@ -237,6 +237,10 @@ enum {
|
|||
IDX_AFE_PORT_ID_WSA_CODEC_DMA_TX_2,
|
||||
IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_0,
|
||||
IDX_AFE_PORT_ID_VA_CODEC_DMA_TX_1,
|
||||
/* IDX 168 to 170 */
|
||||
IDX_SECONDARY_SPDIF_RX,
|
||||
IDX_PRIMARY_SPDIF_TX,
|
||||
IDX_SECONDARY_SPDIF_TX,
|
||||
AFE_MAX_PORTS
|
||||
};
|
||||
|
||||
|
@ -389,6 +393,11 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg
|
|||
int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port,
|
||||
u32 rate);
|
||||
|
||||
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);
|
||||
|
||||
int afe_turn_onoff_hw_mad(u16 mad_type, u16 mad_enable);
|
||||
int afe_port_set_mad_type(u16 port_id, enum afe_mad_type mad_type);
|
||||
enum afe_mad_type afe_port_get_mad_type(u16 port_id);
|
||||
|
|
|
@ -323,6 +323,9 @@ int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format,
|
|||
uint16_t bits_per_sample, int32_t stream_id,
|
||||
bool is_gapless_mode);
|
||||
|
||||
int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format,
|
||||
uint32_t passthrough_flag);
|
||||
|
||||
int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
|
||||
uint32_t passthrough_flag);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ struct audio_uevent_data {
|
|||
int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name);
|
||||
void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data);
|
||||
int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *name);
|
||||
int q6core_send_uevent_env(struct audio_uevent_data *uevent_data, char *env[]);
|
||||
int q6core_get_avcs_api_version_per_service(uint32_t service_id);
|
||||
|
||||
#define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919
|
||||
|
|
Loading…
Reference in a new issue