sound/usb/qcom/mixer_usb_offload.c

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

File Facts

System
Linux kernel
Corpus path
sound/usb/qcom/mixer_usb_offload.c
Extension
.c
Size
4250 bytes
Lines
156
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

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <linux/usb.h>

#include <sound/core.h>
#include <sound/control.h>
#include <sound/soc-usb.h>

#include "../usbaudio.h"
#include "../card.h"
#include "../helper.h"
#include "../mixer.h"

#include "mixer_usb_offload.h"

#define PCM_IDX(n)  ((n) & 0xffff)
#define CARD_IDX(n) ((n) >> 16)

static int
snd_usb_offload_card_route_get(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct device *sysdev = snd_kcontrol_chip(kcontrol);
	int ret;

	ret = snd_soc_usb_update_offload_route(sysdev,
					       CARD_IDX(kcontrol->private_value),
					       PCM_IDX(kcontrol->private_value),
					       SNDRV_PCM_STREAM_PLAYBACK,
					       SND_SOC_USB_KCTL_CARD_ROUTE,
					       ucontrol->value.integer.value);
	if (ret < 0) {
		ucontrol->value.integer.value[0] = -1;
		ucontrol->value.integer.value[1] = -1;
	}

	return 0;
}

static int snd_usb_offload_card_route_info(struct snd_kcontrol *kcontrol,
					   struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	uinfo->value.integer.min = -1;
	uinfo->value.integer.max = SNDRV_CARDS;

	return 0;
}

static struct snd_kcontrol_new snd_usb_offload_mapped_card_ctl = {
	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
	.access = SNDRV_CTL_ELEM_ACCESS_READ,
	.info = snd_usb_offload_card_route_info,
	.get = snd_usb_offload_card_route_get,
};

static int
snd_usb_offload_pcm_route_get(struct snd_kcontrol *kcontrol,
			      struct snd_ctl_elem_value *ucontrol)
{
	struct device *sysdev = snd_kcontrol_chip(kcontrol);
	int ret;

	ret = snd_soc_usb_update_offload_route(sysdev,
					       CARD_IDX(kcontrol->private_value),
					       PCM_IDX(kcontrol->private_value),
					       SNDRV_PCM_STREAM_PLAYBACK,
					       SND_SOC_USB_KCTL_PCM_ROUTE,
					       ucontrol->value.integer.value);
	if (ret < 0) {
		ucontrol->value.integer.value[0] = -1;
		ucontrol->value.integer.value[1] = -1;
	}

	return 0;
}

static int snd_usb_offload_pcm_route_info(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	uinfo->value.integer.min = -1;
	/* Arbitrary max value, as there is no 'limit' on number of PCM devices */
	uinfo->value.integer.max = 0xff;

Annotation

Implementation Notes