sound/usb/media.c

Source file repositories/reference/linux-study-clean/sound/usb/media.c

File Facts

System
Linux kernel
Corpus path
sound/usb/media.c
Extension
.c
Size
8151 bytes
Lines
326
Domain
Driver Families
Bucket
sound/usb
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

switch (entity->function) {
		case MEDIA_ENT_F_AUDIO_MIXER:
			ret = media_create_pad_link(entity, mixer_pad,
						    &mctl->media_entity, 0,
						    MEDIA_LNK_FL_ENABLED);
			if (ret)
				goto remove_intf_link;
			break;
		}
	}

	subs->media_ctl = mctl;
	return 0;

remove_intf_link:
	media_remove_intf_link(mctl->intf_link);
devnode_remove:
	media_devnode_remove(mctl->intf_devnode);
unregister_entity:
	media_device_unregister_entity(&mctl->media_entity);
free_mctl:
	kfree(mctl);
	return ret;
}

void snd_media_stream_delete(struct snd_usb_substream *subs)
{
	struct media_ctl *mctl = subs->media_ctl;

	if (mctl) {
		struct media_device *mdev;

		mdev = mctl->media_dev;
		if (mdev && media_devnode_is_registered(mdev->devnode)) {
			media_devnode_remove(mctl->intf_devnode);
			media_device_unregister_entity(&mctl->media_entity);
			media_entity_cleanup(&mctl->media_entity);
		}
		kfree(mctl);
		subs->media_ctl = NULL;
	}
}

int snd_media_start_pipeline(struct snd_usb_substream *subs)
{
	struct media_ctl *mctl = subs->media_ctl;
	int ret = 0;

	if (!mctl)
		return 0;

	guard(mutex)(&mctl->media_dev->graph_mutex);
	if (mctl->media_dev->enable_source)
		ret = mctl->media_dev->enable_source(&mctl->media_entity,
						     &mctl->media_pipe);
	return ret;
}

void snd_media_stop_pipeline(struct snd_usb_substream *subs)
{
	struct media_ctl *mctl = subs->media_ctl;

	if (!mctl)
		return;

	guard(mutex)(&mctl->media_dev->graph_mutex);
	if (mctl->media_dev->disable_source)
		mctl->media_dev->disable_source(&mctl->media_entity);
}

static int snd_media_mixer_init(struct snd_usb_audio *chip)
{
	struct device *ctl_dev = chip->card->ctl_dev;
	struct media_intf_devnode *ctl_intf;
	struct usb_mixer_interface *mixer;
	struct media_device *mdev = chip->media_dev;
	struct media_mixer_ctl *mctl;
	u32 intf_type = MEDIA_INTF_T_ALSA_CONTROL;
	int ret;

	if (!mdev)
		return -ENODEV;

	ctl_intf = chip->ctl_intf_media_devnode;
	if (!ctl_intf) {
		ctl_intf = media_devnode_create(mdev, intf_type, 0,
						MAJOR(ctl_dev->devt),
						MINOR(ctl_dev->devt));
		if (!ctl_intf)
			return -ENOMEM;

Annotation

Implementation Notes