sound/soc/uniphier/aio-compress.c
Source file repositories/reference/linux-study-clean/sound/soc/uniphier/aio-compress.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/uniphier/aio-compress.c- Extension
.c- Size
- 11590 bytes
- Lines
- 424
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/bitfield.hlinux/circ_buf.hlinux/dma-mapping.hlinux/errno.hlinux/kernel.hlinux/module.hsound/core.hsound/pcm.hsound/soc.haio.h
Detected Declarations
function uniphier_aio_comprdma_newfunction uniphier_aio_comprdma_freefunction uniphier_aio_compr_openfunction uniphier_aio_compr_freefunction uniphier_aio_compr_get_paramsfunction uniphier_aio_compr_set_paramsfunction uniphier_aio_compr_hw_freefunction uniphier_aio_compr_preparefunction uniphier_aio_compr_triggerfunction uniphier_aio_compr_pointerfunction aio_compr_send_to_hwfunction uniphier_aio_compr_copyfunction uniphier_aio_compr_get_capsfunction uniphier_aio_compr_get_codec_caps
Annotated Snippet
if (frm == IEC61937_HEADER_SIGN) {
frm_a |= 0x01000000;
/* Next data is Pc and Pd */
sub->iec_header = true;
} else {
u16 pc = be16_to_cpu((__be16)frm_a);
if (sub->iec_header && sub->iec_pc != pc) {
/* Force overwrite IEC frame type */
sub->iec_pc = pc;
ret = aio_oport_set_stream_type(sub, pc);
if (ret)
return ret;
}
sub->iec_header = false;
}
dstbuf[dst++] = frm_a;
dstbuf[dst++] = frm_b;
dstsize -= sizeof(u32) * 2;
}
return 0;
}
static int uniphier_aio_compr_copy(struct snd_soc_component *component,
struct snd_compr_stream *cstream,
char __user *buf, size_t count)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_compr_runtime *runtime = cstream->runtime;
struct device *carddev = rtd->compr->card->dev;
struct uniphier_aio *aio = uniphier_priv(snd_soc_rtd_to_cpu(rtd, 0));
struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
size_t cnt = min_t(size_t, count, aio_rb_space_to_end(sub) / 2);
int bytes = runtime->fragment_size;
size_t s;
int ret;
if (cnt < sizeof(u32))
return 0;
if (sub->swm->dir == PORT_DIR_OUTPUT) {
dma_addr_t dmapos = sub->compr_addr + sub->wr_offs;
/* Size of AIO output format is double of IEC61937 */
s = cnt * 2;
dma_sync_single_for_cpu(carddev, dmapos, s, DMA_TO_DEVICE);
ret = aio_compr_send_to_hw(sub, buf, s);
dma_sync_single_for_device(carddev, dmapos, s, DMA_TO_DEVICE);
} else {
dma_addr_t dmapos = sub->compr_addr + sub->rd_offs;
s = cnt;
dma_sync_single_for_cpu(carddev, dmapos, s, DMA_FROM_DEVICE);
ret = copy_to_user(buf, sub->compr_area + sub->rd_offs, s);
dma_sync_single_for_device(carddev, dmapos, s, DMA_FROM_DEVICE);
}
if (ret)
return -EFAULT;
guard(spinlock_irqsave)(&sub->lock);
sub->threshold = 2 * bytes;
aiodma_rb_set_threshold(sub, sub->compr_bytes, 2 * bytes);
if (sub->swm->dir == PORT_DIR_OUTPUT) {
sub->wr_offs += s;
if (sub->wr_offs >= sub->compr_bytes)
sub->wr_offs -= sub->compr_bytes;
} else {
sub->rd_offs += s;
if (sub->rd_offs >= sub->compr_bytes)
sub->rd_offs -= sub->compr_bytes;
}
aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
return cnt;
}
static int uniphier_aio_compr_get_caps(struct snd_soc_component *component,
struct snd_compr_stream *cstream,
struct snd_compr_caps *caps)
{
caps->num_codecs = 1;
caps->min_fragment_size = AUD_MIN_FRAGMENT_SIZE;
caps->max_fragment_size = AUD_MAX_FRAGMENT_SIZE;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/circ_buf.h`, `linux/dma-mapping.h`, `linux/errno.h`, `linux/kernel.h`, `linux/module.h`, `sound/core.h`, `sound/pcm.h`.
- Detected declarations: `function uniphier_aio_comprdma_new`, `function uniphier_aio_comprdma_free`, `function uniphier_aio_compr_open`, `function uniphier_aio_compr_free`, `function uniphier_aio_compr_get_params`, `function uniphier_aio_compr_set_params`, `function uniphier_aio_compr_hw_free`, `function uniphier_aio_compr_prepare`, `function uniphier_aio_compr_trigger`, `function uniphier_aio_compr_pointer`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.