sound/soc/sof/ipc3-control.c
Source file repositories/reference/linux-study-clean/sound/soc/sof/ipc3-control.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/sof/ipc3-control.c- Extension
.c- Size
- 22024 bytes
- Lines
- 773
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
sof-priv.hsof-audio.hipc3-priv.h
Detected Declarations
function sof_ipc3_set_get_kcontrol_datafunction list_for_each_entryfunction sof_ipc3_refresh_controlfunction sof_ipc3_volume_getfunction sof_ipc3_volume_putfunction sof_ipc3_switch_getfunction sof_ipc3_switch_putfunction sof_ipc3_enum_getfunction sof_ipc3_enum_putfunction sof_ipc3_bytes_getfunction sof_ipc3_bytes_putfunction sof_ipc3_bytes_ext_putfunction _sof_ipc3_bytes_ext_getfunction sof_ipc3_bytes_ext_getfunction sof_ipc3_bytes_ext_volatile_getfunction snd_sof_update_controlfunction sof_ipc3_control_updatefunction sof_ipc3_widget_kcontrol_setupfunction sof_ipc3_set_up_volume_table
Annotated Snippet
if (swidget->comp_id == scontrol->comp_id) {
widget_found = true;
break;
}
}
if (!widget_found) {
dev_err(sdev->dev, "%s: can't find widget with id %d\n", __func__,
scontrol->comp_id);
return -EINVAL;
}
if (lock)
mutex_lock(&swidget->setup_mutex);
else
lockdep_assert_held(&swidget->setup_mutex);
/*
* Volatile controls should always be part of static pipelines and the
* widget use_count would always be > 0 in this case. For the others,
* just return the cached value if the widget is not set up.
*/
if (!swidget->use_count)
goto unlock;
/*
* Select the IPC cmd and the ctrl_type based on the ctrl_cmd and the
* direction
* Note: SOF_CTRL_TYPE_VALUE_COMP_* is not used and supported currently
* for ctrl_type
*/
if (cdata->cmd == SOF_CTRL_CMD_BINARY) {
ipc_cmd = set ? SOF_IPC_COMP_SET_DATA : SOF_IPC_COMP_GET_DATA;
ctrl_type = set ? SOF_CTRL_TYPE_DATA_SET : SOF_CTRL_TYPE_DATA_GET;
} else {
ipc_cmd = set ? SOF_IPC_COMP_SET_VALUE : SOF_IPC_COMP_GET_VALUE;
ctrl_type = set ? SOF_CTRL_TYPE_VALUE_CHAN_SET : SOF_CTRL_TYPE_VALUE_CHAN_GET;
}
cdata->rhdr.hdr.cmd = SOF_IPC_GLB_COMP_MSG | ipc_cmd;
cdata->type = ctrl_type;
cdata->comp_id = scontrol->comp_id;
cdata->msg_index = 0;
/* calculate header and data size */
switch (cdata->type) {
case SOF_CTRL_TYPE_VALUE_CHAN_GET:
case SOF_CTRL_TYPE_VALUE_CHAN_SET:
cdata->num_elems = scontrol->num_channels;
msg_bytes = scontrol->num_channels *
sizeof(struct sof_ipc_ctrl_value_chan);
msg_bytes += sizeof(struct sof_ipc_ctrl_data);
break;
case SOF_CTRL_TYPE_DATA_GET:
case SOF_CTRL_TYPE_DATA_SET:
cdata->num_elems = cdata->data->size;
msg_bytes = cdata->data->size;
msg_bytes += sizeof(struct sof_ipc_ctrl_data) +
sizeof(struct sof_abi_hdr);
break;
default:
ret = -EINVAL;
goto unlock;
}
cdata->rhdr.hdr.size = msg_bytes;
cdata->elems_remaining = 0;
ret = iops->set_get_data(sdev, cdata, cdata->rhdr.hdr.size, set);
if (!set)
goto unlock;
/* It is a set-data operation, and we have a backup that we can restore */
if (ret < 0) {
if (!scontrol->old_ipc_control_data)
goto unlock;
/*
* Current ipc_control_data is not valid, we use the last known good
* configuration
*/
memcpy(scontrol->ipc_control_data, scontrol->old_ipc_control_data,
scontrol->max_size);
kfree(scontrol->old_ipc_control_data);
scontrol->old_ipc_control_data = NULL;
/* Send the last known good configuration to firmware */
ret = iops->set_get_data(sdev, cdata, cdata->rhdr.hdr.size, set);
if (ret < 0)
goto unlock;
Annotation
- Immediate include surface: `sof-priv.h`, `sof-audio.h`, `ipc3-priv.h`.
- Detected declarations: `function sof_ipc3_set_get_kcontrol_data`, `function list_for_each_entry`, `function sof_ipc3_refresh_control`, `function sof_ipc3_volume_get`, `function sof_ipc3_volume_put`, `function sof_ipc3_switch_get`, `function sof_ipc3_switch_put`, `function sof_ipc3_enum_get`, `function sof_ipc3_enum_put`, `function sof_ipc3_bytes_get`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.