linux/sound/usb/card.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   (Tentative) USB Audio Driver for ALSA
 *
 *   Copyright (c) 2002 by Takashi Iwai <[email protected]>
 *
 *   Many codes borrowed from audio.c by
 *	    Alan Cox ([email protected])
 *	    Thomas Sailer ([email protected])
 *
 *   Audio Class 3.0 support by Ruslan Bilovol <[email protected]>
 *
 *  NOTES:
 *
 *   - the linked URBs would be preferred but not used so far because of
 *     the instability of unlinking.
 *   - type II is not supported properly.  there is no device which supports
 *     this type *correctly*.  SB extigy looks as if it supports, but it's
 *     indeed an AC3 stream packed in SPDIF frames (i.e. no real AC3 stream).
 */


#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/usb.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/usb/audio.h>
#include <linux/usb/audio-v2.h>
#include <linux/usb/audio-v3.h>
#include <linux/module.h>

#include <sound/control.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>

#include "usbaudio.h"
#include "card.h"
#include "midi.h"
#include "midi2.h"
#include "mixer.h"
#include "proc.h"
#include "quirks.h"
#include "endpoint.h"
#include "helper.h"
#include "pcm.h"
#include "format.h"
#include "power.h"
#include "stream.h"
#include "media.h"

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

static int index[SNDRV_CARDS] =;	/* Index 0-MAX */
static char *id[SNDRV_CARDS] =;	/* ID for this card */
static bool enable[SNDRV_CARDS] =;/* Enable this card */
/* Vendor/product IDs for this card */
static int vid[SNDRV_CARDS] =;
static int pid[SNDRV_CARDS] =;
static int device_setup[SNDRV_CARDS]; /* device parameter for this card */
static bool ignore_ctl_error;
static bool autoclock =;
static bool lowlatency =;
static char *quirk_alias[SNDRV_CARDS];
static char *delayed_register[SNDRV_CARDS];
static bool implicit_fb[SNDRV_CARDS];
static unsigned int quirk_flags[SNDRV_CARDS];

bool snd_usb_use_vmalloc =;
bool snd_usb_skip_validation;

module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param(ignore_ctl_error, bool, 0444);
MODULE_PARM_DESC();
module_param(autoclock, bool, 0444);
MODULE_PARM_DESC();
module_param(lowlatency, bool, 0444);
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_named(use_vmalloc, snd_usb_use_vmalloc, bool, 0444);
MODULE_PARM_DESC();
module_param_named(skip_validation, snd_usb_skip_validation, bool, 0444);
MODULE_PARM_DESC();

/*
 * we keep the snd_usb_audio_t instances by ourselves for merging
 * the all interfaces on the same card as one sound device.
 */

static DEFINE_MUTEX(register_mutex);
static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
static struct usb_driver usb_audio_driver;

/*
 * disconnect streams
 * called from usb_audio_disconnect()
 */
static void snd_usb_stream_disconnect(struct snd_usb_stream *as)
{}

static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int interface)
{}

/*
 * parse audio control descriptor and create pcm/midi streams
 */
static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
{}

/*
 * Profile name preset table
 */
struct usb_audio_device_name {};

#define PROFILE_NAME(vid, pid, vendor, product, profile)
#define DEVICE_NAME(vid, pid, vendor, product)

/* vendor/product and profile name presets, sorted in device id order */
static const struct usb_audio_device_name usb_audio_names[] =;

static const struct usb_audio_device_name *
lookup_device_name(u32 id)
{}

/*
 * free the chip instance
 *
 * here we have to do not much, since pcm and controls are already freed
 *
 */

static void snd_usb_audio_free(struct snd_card *card)
{}

static void usb_audio_make_shortname(struct usb_device *dev,
				     struct snd_usb_audio *chip,
				     const struct snd_usb_audio_quirk *quirk)
{}

static void usb_audio_make_longname(struct usb_device *dev,
				    struct snd_usb_audio *chip,
				    const struct snd_usb_audio_quirk *quirk)
{}

/*
 * create a chip instance and set its names.
 */
static int snd_usb_audio_create(struct usb_interface *intf,
				struct usb_device *dev, int idx,
				const struct snd_usb_audio_quirk *quirk,
				unsigned int usb_id,
				struct snd_usb_audio **rchip)
{}

/* look for a matching quirk alias id */
static bool get_alias_id(struct usb_device *dev, unsigned int *id)
{}

static int check_delayed_register_option(struct snd_usb_audio *chip)
{}

static const struct usb_device_id usb_audio_ids[]; /* defined below */

/* look for the last interface that matches with our ids and remember it */
static void find_last_interface(struct snd_usb_audio *chip)
{}

/* look for the corresponding quirk */
static const struct snd_usb_audio_quirk *
get_alias_quirk(struct usb_device *dev, unsigned int id)
{}

/* register card if we reach to the last interface or to the specified
 * one given via option
 */
static int try_to_register_card(struct snd_usb_audio *chip, int ifnum)
{}

/*
 * probe the active usb device
 *
 * note that this can be called multiple times per a device, when it
 * includes multiple audio control interfaces.
 *
 * thus we check the usb device pointer and creates the card instance
 * only at the first time.  the successive calls of this function will
 * append the pcm interface to the corresponding card.
 */
static int usb_audio_probe(struct usb_interface *intf,
			   const struct usb_device_id *usb_id)
{}

/*
 * we need to take care of counter, since disconnection can be called also
 * many times as well as usb_audio_probe().
 */
static void usb_audio_disconnect(struct usb_interface *intf)
{}

/* lock the shutdown (disconnect) task and autoresume */
int snd_usb_lock_shutdown(struct snd_usb_audio *chip)
{}

/* autosuspend and unlock the shutdown */
void snd_usb_unlock_shutdown(struct snd_usb_audio *chip)
{}

int snd_usb_autoresume(struct snd_usb_audio *chip)
{}

void snd_usb_autosuspend(struct snd_usb_audio *chip)
{}

static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
{}

static int usb_audio_resume(struct usb_interface *intf)
{}

static const struct usb_device_id usb_audio_ids [] =;
MODULE_DEVICE_TABLE(usb, usb_audio_ids);

/*
 * entry point for linux usb interface
 */

static struct usb_driver usb_audio_driver =;

module_usb_driver();