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

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

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/cx18/cx18-alsa-pcm.c
Extension
.c
Size
6799 bytes
Lines
273
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

test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) {
		/* We're already streaming.  No additional action required */
		snd_cx18_unlock(cxsc);
		return 0;
	}


	runtime->hw = snd_cx18_hw_capture;
	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
	cxsc->capture_pcm_substream = substream;
	runtime->private_data = cx;

	cx->pcm_announce_callback = cx18_alsa_announce_pcm_data;

	/* Not currently streaming, so start it up */
	set_bit(CX18_F_S_STREAMING, &s->s_flags);
	ret = cx18_start_v4l2_encode_stream(s);
	snd_cx18_unlock(cxsc);

	return ret;
}

static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
{
	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
	struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
	struct cx18 *cx = to_cx18(v4l2_dev);
	struct cx18_stream *s;

	/* Instruct the cx18 to stop sending packets */
	snd_cx18_lock(cxsc);
	s = &cx->streams[CX18_ENC_STREAM_TYPE_PCM];
	cx18_stop_v4l2_encode_stream(s, 0);
	clear_bit(CX18_F_S_STREAMING, &s->s_flags);

	cx18_release_stream(s);

	cx->pcm_announce_callback = NULL;
	snd_cx18_unlock(cxsc);

	return 0;
}

static int snd_cx18_pcm_prepare(struct snd_pcm_substream *substream)
{
	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);

	cxsc->hwptr_done_capture = 0;
	cxsc->capture_transfer_done = 0;

	return 0;
}

static int snd_cx18_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	return 0;
}

static
snd_pcm_uframes_t snd_cx18_pcm_pointer(struct snd_pcm_substream *substream)
{
	unsigned long flags;
	snd_pcm_uframes_t hwptr_done;
	struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);

	spin_lock_irqsave(&cxsc->slock, flags);
	hwptr_done = cxsc->hwptr_done_capture;
	spin_unlock_irqrestore(&cxsc->slock, flags);

	return hwptr_done;
}

static const struct snd_pcm_ops snd_cx18_pcm_capture_ops = {
	.open		= snd_cx18_pcm_capture_open,
	.close		= snd_cx18_pcm_capture_close,
	.prepare	= snd_cx18_pcm_prepare,
	.trigger	= snd_cx18_pcm_trigger,
	.pointer	= snd_cx18_pcm_pointer,
};

int snd_cx18_pcm_create(struct snd_cx18_card *cxsc)
{
	struct snd_pcm *sp;
	struct snd_card *sc = cxsc->sc;
	struct v4l2_device *v4l2_dev = cxsc->v4l2_dev;
	struct cx18 *cx = to_cx18(v4l2_dev);
	int ret;

	ret = snd_pcm_new(sc, "CX23418 PCM",
			  0, /* PCM device 0, the only one for this card */

Annotation

Implementation Notes