// SPDX-License-Identifier: GPL-2.0-only
/*
* Edirol UA-101/UA-1000 driver
* Copyright (c) Clemens Ladisch <clemens@ladisch.de>
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/usb/audio.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "../usbaudio.h"
#include "../midi.h"
MODULE_DESCRIPTION("Edirol UA-101/1000 driver");
MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
MODULE_LICENSE("GPL v2");
MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}");
/*
* Should not be lower than the minimum scheduling delay of the host
* controller. Some Intel controllers need more than one frame; as long as
* that driver doesn't tell us about this, use 1.5 frames just to be sure.
*/
#define MIN_QUEUE_LENGTH 12
/* Somewhat random. */
#define MAX_QUEUE_LENGTH 30
/*
* This magic value optimizes memory usage efficiency for the UA-101's packet
* sizes at all sample rates, taking into account the stupid cache pool sizes
* that usb_alloc_coherent() uses.
*/
#define DEFAULT_QUEUE_LENGTH 21
#define MAX_PACKET_SIZE 672 /* hardware specific */
#define MAX_MEMORY_BUFFERS DIV_ROUND_UP(MAX_QUEUE_LENGTH, \
PAGE_SIZE / MAX_PACKET_SIZE)
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static unsigned int queue_length = 21;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "card index");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "enable card");
module_param(queue_length, uint, 0644);
MODULE_PARM_DESC(queue_length, "USB queue length in microframes, "
__stringify(MIN_QUEUE_LENGTH)"-"__stringify(MAX_QUEUE_LENGTH));
enum {
INTF_PLAYBACK,
INTF_CAPTURE,
INTF_MIDI,
INTF_COUNT
};
/* bits in struct ua101::states */
enum {
USB_CAPTURE_RUNNING,
USB_PLAYBACK_RUNNING,
ALSA_CAPTURE_OPEN,
ALSA_PLAYBACK_OPEN,
ALSA_CAPTURE_RUNNING,
ALSA_PLAYBACK_RUNNING,
CAPTURE_URB_COMPLETED,
PLAYBACK_URB_COMPLETED,
DISCONNECTED,
};
struct ua101 {
struct usb_device *dev;
struct snd_card *card;
struct usb_interface *intf[INTF_COUNT];
int card_index;
struct snd_pcm *pcm;
struct list_head midi_list;