/** * sof_ipc4_probe_get_module_info - Get IPC4 module info for probe module * @cdev: SOF client device * @return: Pointer to IPC4 probe module info * * Look up the IPC4 probe module info based on the hard coded uuid and * store the value for the future calls.
*/ staticstruct sof_man4_module *sof_ipc4_probe_get_module_info(struct sof_client_dev *cdev)
{ struct sof_probes_priv *priv = cdev->data; struct device *dev = &cdev->auxdev.dev; staticconst guid_t probe_uuid =
GUID_INIT(0x7CAD0808, 0xAB10, 0xCD23,
0xEF, 0x45, 0x12, 0xAB, 0x34, 0xCD, 0x56, 0xEF);
if (!priv->ipc_priv) { struct sof_ipc4_fw_module *fw_module =
sof_client_ipc4_find_module(cdev, &probe_uuid);
if (!fw_module) {
dev_err(dev, "%s: no matching uuid found", __func__); return NULL;
}
/** * ipc4_probes_init - initialize data probing * @cdev: SOF client device * @stream_tag: Extractor stream tag * @buffer_size: DMA buffer size to set for extractor * @return: 0 on success, negative error code on error * * Host chooses whether extraction is supported or not by providing * valid stream tag to DSP. Once specified, stream described by that * tag will be tied to DSP for extraction for the entire lifetime of * probe. * * Probing is initialized only once and each INIT request must be * matched by DEINIT call.
*/ staticint ipc4_probes_init(struct sof_client_dev *cdev, u32 stream_tag,
size_t buffer_size)
{ struct sof_man4_module *mentry = sof_ipc4_probe_get_module_info(cdev); struct sof_ipc4_msg msg; struct sof_ipc4_probe_cfg cfg;
/** * ipc4_probes_deinit - cleanup after data probing * @cdev: SOF client device * @return: 0 on success, negative error code on error * * Host sends DEINIT request to free previously initialized probe * on DSP side once it is no longer needed. DEINIT only when there * are no probes connected and with all injectors detached.
*/ staticint ipc4_probes_deinit(struct sof_client_dev *cdev)
{ struct sof_man4_module *mentry = sof_ipc4_probe_get_module_info(cdev); struct sof_ipc4_msg msg;
/** * ipc4_probes_points_info - retrieve list of active probe points * @cdev: SOF client device * @desc: Returned list of active probes * @num_desc: Returned count of active probes * @return: 0 on success, negative error code on error * * Dummy implementation returning empty list of probes.
*/ staticint ipc4_probes_points_info(struct sof_client_dev *cdev, struct sof_probe_point_desc **desc,
size_t *num_desc)
{ /* TODO: Firmware side implementation needed first */
*desc = NULL;
*num_desc = 0; return 0;
}
/** * ipc4_probes_points_add - connect specified probes * @cdev: SOF client device * @desc: List of probe points to connect * @num_desc: Number of elements in @desc * @return: 0 on success, negative error code on error * * Translates the generic probe point presentation to an IPC4 * message to dynamically connect the provided set of endpoints.
*/ staticint ipc4_probes_points_add(struct sof_client_dev *cdev, struct sof_probe_point_desc *desc,
size_t num_desc)
{ struct sof_man4_module *mentry = sof_ipc4_probe_get_module_info(cdev); struct sof_ipc4_probe_point *points; struct sof_ipc4_msg msg; int i, ret;
if (!mentry) return -ENODEV;
/* The sof_probe_point_desc and sof_ipc4_probe_point structs * are of same size and even the integers are the same in the * same order, and similar meaning, but since there is no * performance issue I wrote the conversion explicitly open for * future development.
*/
points = kcalloc(num_desc, sizeof(*points), GFP_KERNEL); if (!points) return -ENOMEM;
for (i = 0; i < num_desc; i++) {
points[i].point_id = desc[i].buffer_id;
points[i].purpose = desc[i].purpose;
points[i].stream_tag = desc[i].stream_tag;
}
ret = sof_client_ipc_set_get_data(cdev, &msg, true);
kfree(points);
return ret;
}
/** * ipc4_probes_points_remove - disconnect specified probes * @cdev: SOF client device * @buffer_id: List of probe points to disconnect * @num_buffer_id: Number of elements in @desc * @return: 0 on success, negative error code on error * * Converts the generic buffer_id to IPC4 probe_point_id and remove * the probe points with an IPC4 for message.
*/ staticint ipc4_probes_points_remove(struct sof_client_dev *cdev, unsignedint *buffer_id, size_t num_buffer_id)
{ struct sof_man4_module *mentry = sof_ipc4_probe_get_module_info(cdev); struct sof_ipc4_msg msg;
u32 *probe_point_ids; int i, ret;
if (!mentry) return -ENODEV;
probe_point_ids = kcalloc(num_buffer_id, sizeof(*probe_point_ids),
GFP_KERNEL); if (!probe_point_ids) return -ENOMEM;
for (i = 0; i < num_buffer_id; i++)
probe_point_ids[i] = buffer_id[i];
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.