sound/soc/fsl/imx-pcm-rpmsg.c
Source file repositories/reference/linux-study-clean/sound/soc/fsl/imx-pcm-rpmsg.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/fsl/imx-pcm-rpmsg.c- Extension
.c- Size
- 24163 bytes
- Lines
- 843
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/dma-mapping.hlinux/slab.hlinux/module.hlinux/delay.hlinux/rpmsg.hsound/core.hsound/pcm.hsound/pcm_params.hsound/dmaengine_pcm.hsound/soc.himx-pcm.hfsl_rpmsg.himx-pcm-rpmsg.h
Detected Declarations
function imx_rpmsg_pcm_send_messagefunction imx_rpmsg_insert_workqueuefunction imx_rpmsg_pcm_hw_paramsfunction imx_rpmsg_pcm_pointerfunction imx_rpmsg_timer_callbackfunction imx_rpmsg_pcm_openfunction imx_rpmsg_pcm_closefunction imx_rpmsg_pcm_preparefunction imx_rpmsg_pcm_dma_completefunction imx_rpmsg_prepare_and_submitfunction imx_rpmsg_async_issue_pendingfunction imx_rpmsg_restartfunction imx_rpmsg_pausefunction imx_rpmsg_terminate_allfunction imx_rpmsg_pcm_triggerfunction imx_rpmsg_pcm_ackfunction periodfunction imx_rpmsg_pcm_newfunction imx_rpmsg_pcm_workfunction imx_rpmsg_pcm_probefunction imx_rpmsg_pcm_removefunction imx_rpmsg_pcm_runtime_resumefunction imx_rpmsg_pcm_runtime_suspendfunction imx_rpmsg_pcm_suspendfunction imx_rpmsg_pcm_resume
Annotated Snippet
if (!rpmsg->force_lpa) {
if (runtime->info & SNDRV_PCM_INFO_PAUSE)
ret = imx_rpmsg_pause(component, substream);
else
ret = imx_rpmsg_terminate_all(component, substream);
}
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
ret = imx_rpmsg_pause(component, substream);
break;
case SNDRV_PCM_TRIGGER_STOP:
ret = imx_rpmsg_terminate_all(component, substream);
break;
default:
return -EINVAL;
}
if (ret)
return ret;
return 0;
}
/*
* imx_rpmsg_pcm_ack
*
* Send the period index to M core through rpmsg, but not send
* all the period index to M core, reduce some unnessesary msg
* to reduce the pressure of rpmsg bandwidth.
*/
static int imx_rpmsg_pcm_ack(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct fsl_rpmsg *rpmsg = dev_get_drvdata(cpu_dai->dev);
struct rpmsg_info *info = dev_get_drvdata(component->dev);
snd_pcm_uframes_t period_size = runtime->period_size;
snd_pcm_sframes_t avail;
struct timer_list *timer;
struct rpmsg_msg *msg;
unsigned long flags;
int buffer_tail = 0;
int written_num;
if (!rpmsg->force_lpa)
return 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];
msg->s_msg.header.cmd = TX_PERIOD_DONE;
} else {
msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];
msg->s_msg.header.cmd = RX_PERIOD_DONE;
}
msg->s_msg.header.type = MSG_TYPE_C;
buffer_tail = (frames_to_bytes(runtime, runtime->control->appl_ptr) %
snd_pcm_lib_buffer_bytes(substream));
buffer_tail = buffer_tail / snd_pcm_lib_period_bytes(substream);
/* There is update for period index */
if (buffer_tail != msg->s_msg.param.buffer_tail) {
written_num = buffer_tail - msg->s_msg.param.buffer_tail;
if (written_num < 0)
written_num += runtime->periods;
msg->s_msg.param.buffer_tail = buffer_tail;
/* The notification message is updated to latest */
spin_lock_irqsave(&info->lock[substream->stream], flags);
memcpy(&info->notify[substream->stream], msg,
sizeof(struct rpmsg_s_msg));
info->notify_updated[substream->stream] = true;
spin_unlock_irqrestore(&info->lock[substream->stream], flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
avail = snd_pcm_playback_hw_avail(runtime);
else
avail = snd_pcm_capture_hw_avail(runtime);
timer = &info->stream_timer[substream->stream].timer;
/*
* If the data in the buffer is less than one period before
* this fill, which means the data may not enough on M
* core side, we need to send message immediately to let
* M core know the pointer is updated.
* if there is more than one period data in the buffer before
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/slab.h`, `linux/module.h`, `linux/delay.h`, `linux/rpmsg.h`, `sound/core.h`, `sound/pcm.h`, `sound/pcm_params.h`.
- Detected declarations: `function imx_rpmsg_pcm_send_message`, `function imx_rpmsg_insert_workqueue`, `function imx_rpmsg_pcm_hw_params`, `function imx_rpmsg_pcm_pointer`, `function imx_rpmsg_timer_callback`, `function imx_rpmsg_pcm_open`, `function imx_rpmsg_pcm_close`, `function imx_rpmsg_pcm_prepare`, `function imx_rpmsg_pcm_dma_complete`, `function imx_rpmsg_prepare_and_submit`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
- 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.