drivers/media/pci/cobalt/cobalt-alsa-pcm.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/cobalt/cobalt-alsa-pcm.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/cobalt/cobalt-alsa-pcm.c
Extension
.c
Size
12767 bytes
Lines
531
Domain
Driver Families
Bucket
drivers/media
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (is_s32) {
			*dst++ = 0;
			*dst++ = val & 0xff;
		}
		*dst++ = (val >> 8) & 0xff;
		*dst++ = (val >> 16) & 0xff;
		len -= is_s32 ? 4 : 2;
		idx++;
	}
}

static void cobalt_alsa_announce_pcm_data(struct snd_cobalt_card *cobsc,
					u8 *pcm_data,
					size_t skip,
					size_t samples)
{
	struct snd_pcm_substream *substream;
	struct snd_pcm_runtime *runtime;
	unsigned long flags;
	unsigned int oldptr;
	unsigned int stride;
	int length = samples;
	int period_elapsed = 0;
	bool is_s32;

	dprintk("cobalt alsa announce ptr=%p data=%p num_bytes=%zd\n", cobsc,
		pcm_data, samples);

	substream = cobsc->capture_pcm_substream;
	if (substream == NULL) {
		dprintk("substream was NULL\n");
		return;
	}

	runtime = substream->runtime;
	if (runtime == NULL) {
		dprintk("runtime was NULL\n");
		return;
	}
	is_s32 = runtime->format == SNDRV_PCM_FORMAT_S32_LE;

	stride = runtime->frame_bits >> 3;
	if (stride == 0) {
		dprintk("stride is zero\n");
		return;
	}

	if (length == 0) {
		dprintk("%s: length was zero\n", __func__);
		return;
	}

	if (runtime->dma_area == NULL) {
		dprintk("dma area was NULL - ignoring\n");
		return;
	}

	oldptr = cobsc->hwptr_done_capture;
	if (oldptr + length >= runtime->buffer_size) {
		unsigned int cnt = runtime->buffer_size - oldptr;
		unsigned i;

		for (i = 0; i < cnt; i++)
			sample_cpy(runtime->dma_area + (oldptr + i) * stride,
					pcm_data + i * skip,
					stride, is_s32);
		for (i = cnt; i < length; i++)
			sample_cpy(runtime->dma_area + (i - cnt) * stride,
					pcm_data + i * skip, stride, is_s32);
	} else {
		unsigned i;

		for (i = 0; i < length; i++)
			sample_cpy(runtime->dma_area + (oldptr + i) * stride,
					pcm_data + i * skip,
					stride, is_s32);
	}
	snd_pcm_stream_lock_irqsave(substream, flags);

	cobsc->hwptr_done_capture += length;
	if (cobsc->hwptr_done_capture >=
	    runtime->buffer_size)
		cobsc->hwptr_done_capture -=
			runtime->buffer_size;

	cobsc->capture_transfer_done += length;
	if (cobsc->capture_transfer_done >=
	    runtime->period_size) {
		cobsc->capture_transfer_done -=
			runtime->period_size;

Annotation

Implementation Notes