Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio: TDFB: Update component for IPC4 #8279

Merged
merged 2 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 171 additions & 4 deletions src/audio/tdfb/tdfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
#include <stddef.h>
#include <stdint.h>

#if CONFIG_IPC_MAJOR_4
#include <ipc4/header.h>
#include <ipc4/module.h>
#include <ipc4/notification.h>
#endif

/* The driver assigns running numbers for control index. If there's single control of
* type switch, enum, binary they all have index 0.
*/
Expand All @@ -57,10 +63,60 @@ DECLARE_SOF_RT_UUID("tdfb", tdfb_uuid, 0xdd511749, 0xd9fa, 0x455c, 0xb3, 0xa7,

DECLARE_TR_CTX(tdfb_tr, SOF_UUID(tdfb_uuid), LOG_LEVEL_INFO);

/* IPC */
/* IPC helpers for control update to user space */

/* TODO: ALSA control update to user space need to be moved to module adapter */
#if CONFIG_IPC_MAJOR_4
static struct ipc_msg *tdfb_notification_init(struct processing_module *mod,
uint32_t control_type_param_id,
uint32_t control_id)
{
struct ipc_msg msg_proto;
struct comp_dev *dev = mod->dev;
struct comp_ipc_config *ipc_config = &dev->ipc_config;
union ipc4_notification_header *primary =
(union ipc4_notification_header *)&msg_proto.header;
struct ipc_msg *msg;
struct tdfb_notification_payload *payload;

/* Clear header, extension, and other ipc_msg members */
memset_s(&msg_proto, sizeof(msg_proto), 0, sizeof(msg_proto));
primary->r.notif_type = SOF_IPC4_MODULE_NOTIFICATION;
primary->r.type = SOF_IPC4_GLB_NOTIFICATION;
primary->r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST;
primary->r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG;
msg = ipc_msg_w_ext_init(msg_proto.header, msg_proto.extension,
lgirdwood marked this conversation as resolved.
Show resolved Hide resolved
sizeof(struct tdfb_notification_payload));
if (!msg)
return NULL;

payload = (struct tdfb_notification_payload *)msg->tx_data;
payload->module_data.instance_id = IPC4_INST_ID(ipc_config->id);
payload->module_data.module_id = IPC4_MOD_ID(ipc_config->id);
payload->module_data.event_id = SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL |
control_type_param_id;
payload->module_data.event_data_size = sizeof(struct sof_ipc4_control_msg_payload) +
lgirdwood marked this conversation as resolved.
Show resolved Hide resolved
sizeof(struct sof_ipc4_ctrl_value_chan);
payload->control_msg.id = control_id;
payload->control_msg.num_elems = 1;
payload->control_value.channel = 0;

comp_dbg(dev, "instance_id = 0x%08x, module_id = 0x%08x",
payload->module_data.instance_id, payload->module_data.module_id);
return msg;
}

static void tdfb_send_notification(struct ipc_msg *msg, uint32_t val)
{
struct tdfb_notification_payload *ipc_payload;

ipc_payload = (struct tdfb_notification_payload *)msg->tx_data;
ipc_payload->control_value.value = val;
ipc_msg_send(msg, NULL, false);
}

/* end CONFIG_IPC_MAJOR_4 */

#elif CONFIG_IPC_MAJOR_3
static int init_get_ctl_ipc(struct processing_module *mod)
{
struct tdfb_comp_data *cd = module_get_private_data(mod);
Expand Down Expand Up @@ -94,6 +150,7 @@ static void send_get_ctl_ipc(struct processing_module *mod)

ipc_msg_send(cd->msg, cd->ctrl_data, false);
}
#endif /* CONFIG_IPC_MAJOR_3 */

/*
* The optimized FIR functions variants need to be updated into function
Expand Down Expand Up @@ -447,9 +504,19 @@ static int tdfb_init(struct processing_module *mod)
*/

/* Initialize IPC for direction of arrival estimate update */
#if CONFIG_IPC_MAJOR_4
cd->msg = tdfb_notification_init(mod, SOF_IPC4_ENUM_CONTROL_PARAM_ID,
CTRL_INDEX_AZIMUTH_ESTIMATE);
if (!cd->msg) {
comp_err(dev, "Failed to initialize control notification.");
ret = -EINVAL;
goto err_free_cd;
}
#elif CONFIG_IPC_MAJOR_3
ret = init_get_ctl_ipc(mod);
if (ret)
goto err_free_cd;
#endif

/* Handler for configuration data */
cd->model_handler = comp_data_blob_handler_new(dev);
Expand All @@ -476,7 +543,9 @@ static int tdfb_init(struct processing_module *mod)
return 0;

err:
/* These are null if not used for IPC version */
rfree(cd->ctrl_data);
ipc_msg_free(cd->msg);

err_free_cd:
rfree(cd);
Expand All @@ -503,6 +572,7 @@ static int tdfb_free(struct processing_module *mod)
* Module commands handling
*/

#if CONFIG_IPC_MAJOR_3
static int tdfb_cmd_switch_get(struct sof_ipc_ctrl_data *cdata, struct tdfb_comp_data *cd)
{
int j;
Expand Down Expand Up @@ -557,11 +627,16 @@ static int tdfb_cmd_get_value(struct processing_module *mod, struct sof_ipc_ctrl
comp_err(mod->dev, "tdfb_cmd_get_value() error: invalid cdata->cmd");
return -EINVAL;
}
#endif /* CONFIG_IPC_MAJOR_3 */

static int tdfb_get_config(struct processing_module *mod,
uint32_t config_id, uint32_t *data_offset_size,
uint32_t param_id, uint32_t *data_offset_size,
uint8_t *fragment, size_t fragment_size)
{
#if CONFIG_IPC_MAJOR_4
comp_err(mod->dev, "tdfb_get_config(), Not supported, should not happen");
return -EINVAL;
#elif CONFIG_IPC_MAJOR_3
struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment;
struct tdfb_comp_data *cd = module_get_private_data(mod);

Expand All @@ -570,8 +645,10 @@ static int tdfb_get_config(struct processing_module *mod,

comp_dbg(mod->dev, "tdfb_get_config(), binary");
return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size);
#endif /* CONFIG_IPC_MAJOR_3 */
}

#if CONFIG_IPC_MAJOR_3
static int tdfb_cmd_enum_set(struct sof_ipc_ctrl_data *cdata, struct tdfb_comp_data *cd)
{
if (cdata->num_elems != 1)
Expand Down Expand Up @@ -634,16 +711,80 @@ static int tdfb_cmd_set_value(struct processing_module *mod, struct sof_ipc_ctrl
return -EINVAL;
}

static int tdfb_set_config(struct processing_module *mod, uint32_t config_id,
/* end CONFIG_IPC_MAJOR_3 */

#elif CONFIG_IPC_MAJOR_4
static int tdfb_cmd_enum_set(struct sof_ipc4_control_msg_payload *ctl, struct tdfb_comp_data *cd)
{
if (ctl->num_elems != 1)
return -EINVAL;

if (ctl->chanv[0].value > SOF_TDFB_MAX_ANGLES)
return -EINVAL;

switch (ctl->id) {
case CTRL_INDEX_AZIMUTH:
cd->az_value = ctl->chanv[0].value;
cd->update = true;
break;
case CTRL_INDEX_AZIMUTH_ESTIMATE:
cd->az_value_estimate = ctl->chanv[0].value;
break;
default:
return -EINVAL;
}

return 0;
}

static int tdfb_cmd_switch_set(struct sof_ipc4_control_msg_payload *ctl, struct tdfb_comp_data *cd)
{
if (ctl->num_elems != 1)
return -EINVAL;

switch (ctl->id) {
case CTRL_INDEX_PROCESS:
cd->beam_on = ctl->chanv[0].value;
cd->update = true;
break;
case CTRL_INDEX_DIRECTION:
cd->direction_updates = ctl->chanv[0].value;
break;
default:
return -EINVAL;
}

return 0;
}
#endif

static int tdfb_set_config(struct processing_module *mod, uint32_t param_id,
enum module_cfg_fragment_position pos, uint32_t data_offset_size,
const uint8_t *fragment, size_t fragment_size, uint8_t *response,
size_t response_size)
{
struct tdfb_comp_data *cd = module_get_private_data(mod);

#if CONFIG_IPC_MAJOR_4
struct sof_ipc4_control_msg_payload *ctl = (struct sof_ipc4_control_msg_payload *)fragment;

switch (param_id) {
case SOF_IPC4_SWITCH_CONTROL_PARAM_ID:
comp_info(mod->dev, "SOF_IPC4_SWITCH_CONTROL_PARAM_ID id = %d, num_elems = %d",
ctl->id, ctl->num_elems);
return tdfb_cmd_switch_set(ctl, cd);

case SOF_IPC4_ENUM_CONTROL_PARAM_ID:
comp_info(mod->dev, "SOF_IPC4_ENUM_CONTROL_PARAM_ID id = %d, num_elems = %d",
ctl->id, ctl->num_elems);
return tdfb_cmd_enum_set(ctl, cd);
}
#elif CONFIG_IPC_MAJOR_3
struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment;

if (cdata->cmd != SOF_CTRL_CMD_BINARY)
return tdfb_cmd_set_value(mod, cdata);
#endif /* CONFIG_IPC_MAJOR_3 */

comp_dbg(mod->dev, "tdfb_set_config(), binary");
return comp_data_blob_set(cd->model_handler, pos, data_offset_size,
Expand Down Expand Up @@ -705,7 +846,11 @@ static int tdfb_process(struct processing_module *mod,
(int32_t)(cd->direction.level_ambient >> 32), cd->direction.az_slow);

if (cd->direction_updates && cd->direction_change) {
#if CONFIG_IPC_MAJOR_3
send_get_ctl_ipc(mod);
#elif CONFIG_IPC_MAJOR_4
tdfb_send_notification(cd->msg, cd->az_value_estimate);
#endif
cd->direction_change = false;
comp_dbg(dev, "tdfb_dupd %d %d",
cd->az_value_estimate, cd->direction.az_slow);
Expand All @@ -725,6 +870,24 @@ static void tdfb_set_alignment(struct audio_stream *source,
audio_stream_init_alignment_constants(byte_align, frame_align_req, sink);
}

#if CONFIG_IPC_MAJOR_4
static void tdfb_params(struct processing_module *mod)
{
struct sof_ipc_stream_params *params = mod->stream_params;
struct comp_buffer *sinkb, *sourceb;
struct comp_dev *dev = mod->dev;

ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params);
component_set_nearest_period_frames(dev, params->rate);

sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list);
ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt);

sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt);
}
#endif

static int tdfb_prepare(struct processing_module *mod,
struct sof_source **sources, int num_of_sources,
struct sof_sink **sinks, int num_of_sinks)
Expand All @@ -740,6 +903,10 @@ static int tdfb_prepare(struct processing_module *mod,

comp_info(dev, "tdfb_prepare()");

#if CONFIG_IPC_MAJOR_4
tdfb_params(mod);
#endif

/* Find source and sink buffers */
sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list);
sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
Expand Down
17 changes: 17 additions & 0 deletions src/include/ipc4/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ struct ipc4_message_reply {

#define SOF_IPC4_SWITCH_CONTROL_PARAM_ID 200
#define SOF_IPC4_ENUM_CONTROL_PARAM_ID 201
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL ((uint32_t)(0xA15A << 16))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not directly with 0xA15A0000


/**
* struct sof_ipc4_ctrl_value_chan: generic channel mapped value data
Expand All @@ -198,4 +199,20 @@ struct sof_ipc4_control_msg_payload {
struct sof_ipc4_ctrl_value_chan chanv[];
} __attribute((packed, aligned(4)));

/**
* struct sof_ipc4_notify_module_data - payload for module notification
* @instance_id: instance ID of the originator module of the notification
* @module_id: module ID of the originator of the notification
* @event_id: module specific event id
* @event_data_size: Size of the @event_data (if any) in bytes
* @event_data: Optional notification data, module and notification dependent
*/
struct sof_ipc4_notify_module_data {
uint16_t instance_id;
uint16_t module_id;
uint32_t event_id;
uint32_t event_data_size;
uint8_t event_data[];
} __attribute((packed, aligned(4)));

#endif
12 changes: 12 additions & 0 deletions src/include/sof/audio/tdfb/tdfb_comp.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
#include <sof/platform.h>
#include <user/tdfb.h>

#if CONFIG_IPC_MAJOR_4
#include <ipc4/header.h>
#endif

/* Select optimized code variant when xt-xcc compiler is used */
#if defined __XCC__
#include <xtensa/config/core-isa.h>
Expand Down Expand Up @@ -110,6 +114,14 @@ struct tdfb_comp_data {
int frames);
};

#if CONFIG_IPC_MAJOR_4
struct tdfb_notification_payload {
struct sof_ipc4_notify_module_data module_data;
struct sof_ipc4_control_msg_payload control_msg;
struct sof_ipc4_ctrl_value_chan control_value; /* One channel value */
};
#endif

#if CONFIG_FORMAT_S16LE
void tdfb_fir_s16(struct tdfb_comp_data *cd,
struct input_stream_buffer *bsource,
Expand Down
Loading