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

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

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/ivtv/ivtv-alsa-pcm.c
Extension
.c
Size
6832 bytes
Lines
275
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(IVTV_F_S_STREAMING, &s->s_flags)) {
		/* We're already streaming.  No additional action required */
		snd_ivtv_unlock(itvsc);
		return 0;
	}


	runtime->hw = snd_ivtv_hw_capture;
	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
	itvsc->capture_pcm_substream = substream;
	runtime->private_data = itv;

	itv->pcm_announce_callback = ivtv_alsa_announce_pcm_data;

	/* Not currently streaming, so start it up */
	set_bit(IVTV_F_S_STREAMING, &s->s_flags);
	ret = ivtv_start_v4l2_encode_stream(s);
	snd_ivtv_unlock(itvsc);

	return ret;
}

static int snd_ivtv_pcm_capture_close(struct snd_pcm_substream *substream)
{
	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);
	struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
	struct ivtv *itv = to_ivtv(v4l2_dev);
	struct ivtv_stream *s;

	/* Instruct the ivtv to stop sending packets */
	snd_ivtv_lock(itvsc);
	s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
	ivtv_stop_v4l2_encode_stream(s, 0);
	clear_bit(IVTV_F_S_STREAMING, &s->s_flags);

	ivtv_release_stream(s);

	itv->pcm_announce_callback = NULL;
	snd_ivtv_unlock(itvsc);

	return 0;
}

static int snd_ivtv_pcm_prepare(struct snd_pcm_substream *substream)
{
	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);

	itvsc->hwptr_done_capture = 0;
	itvsc->capture_transfer_done = 0;

	return 0;
}

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

static
snd_pcm_uframes_t snd_ivtv_pcm_pointer(struct snd_pcm_substream *substream)
{
	unsigned long flags;
	snd_pcm_uframes_t hwptr_done;
	struct snd_ivtv_card *itvsc = snd_pcm_substream_chip(substream);

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

	return hwptr_done;
}

static const struct snd_pcm_ops snd_ivtv_pcm_capture_ops = {
	.open		= snd_ivtv_pcm_capture_open,
	.close		= snd_ivtv_pcm_capture_close,
	.prepare	= snd_ivtv_pcm_prepare,
	.trigger	= snd_ivtv_pcm_trigger,
	.pointer	= snd_ivtv_pcm_pointer,
};

int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc)
{
	struct snd_pcm *sp;
	struct snd_card *sc = itvsc->sc;
	struct v4l2_device *v4l2_dev = itvsc->v4l2_dev;
	struct ivtv *itv = to_ivtv(v4l2_dev);
	int ret;

	ret = snd_pcm_new(sc, "CX2341[56] PCM",
			  0, /* PCM device 0, the only one for this card */

Annotation

Implementation Notes