mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
ALSA: Add USB US122L driver
Added a new US122L usb-audio driver. This driver works together with a dedicated alsa-lib plugin. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
committed by
Jaroslav Kysela
parent
896e6cc20e
commit
030a07e441
@@ -93,9 +93,10 @@ enum {
|
||||
SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */
|
||||
SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */
|
||||
SNDRV_HWDEP_IFACE_HDA, /* HD-audio */
|
||||
SNDRV_HWDEP_IFACE_USB_STREAM, /* direct access to usb stream */
|
||||
|
||||
/* Don't forget to change the following: */
|
||||
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_HDA
|
||||
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM
|
||||
};
|
||||
|
||||
struct snd_hwdep_info {
|
||||
|
||||
@@ -67,5 +67,16 @@ config SND_USB_CAIAQ_INPUT
|
||||
* Native Instruments Kore Controller 2
|
||||
* Native Instruments Audio Kontrol 1
|
||||
|
||||
config SND_USB_US122L
|
||||
tristate "Tascam US-122L USB driver"
|
||||
depends on X86 && EXPERIMENTAL
|
||||
select SND_RAWMIDI
|
||||
help
|
||||
Say Y here to include support for Tascam US-122L USB Audio/MIDI
|
||||
interfaces.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-usb-us122l.
|
||||
|
||||
endif # SND_USB
|
||||
|
||||
|
||||
@@ -8,5 +8,6 @@ snd-usb-lib-objs := usbmidi.o
|
||||
# Toplevel Module Dependency
|
||||
obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o
|
||||
obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o
|
||||
obj-$(CONFIG_SND_USB_US122L) += snd-usb-lib.o
|
||||
|
||||
obj-$(CONFIG_SND) += usx2y/ caiaq/
|
||||
|
||||
@@ -156,6 +156,7 @@ enum quirk_type {
|
||||
QUIRK_MIDI_RAW,
|
||||
QUIRK_MIDI_EMAGIC,
|
||||
QUIRK_MIDI_CME,
|
||||
QUIRK_MIDI_US122L,
|
||||
QUIRK_AUDIO_STANDARD_INTERFACE,
|
||||
QUIRK_AUDIO_FIXED_ENDPOINT,
|
||||
QUIRK_AUDIO_EDIROL_UA700_UA25,
|
||||
|
||||
@@ -669,6 +669,42 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = {
|
||||
.output = snd_usbmidi_raw_output,
|
||||
};
|
||||
|
||||
static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep,
|
||||
uint8_t *buffer, int buffer_length)
|
||||
{
|
||||
if (buffer_length != 9)
|
||||
return;
|
||||
buffer_length = 8;
|
||||
while (buffer_length && buffer[buffer_length - 1] == 0xFD)
|
||||
buffer_length--;
|
||||
if (buffer_length)
|
||||
snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
|
||||
}
|
||||
|
||||
static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep)
|
||||
{
|
||||
int count;
|
||||
|
||||
if (!ep->ports[0].active)
|
||||
return;
|
||||
count = ep->urb->dev->speed == USB_SPEED_HIGH ? 1 : 2;
|
||||
count = snd_rawmidi_transmit(ep->ports[0].substream,
|
||||
ep->urb->transfer_buffer,
|
||||
count);
|
||||
if (count < 1) {
|
||||
ep->ports[0].active = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
memset(ep->urb->transfer_buffer + count, 0xFD, 9 - count);
|
||||
ep->urb->transfer_buffer_length = count;
|
||||
}
|
||||
|
||||
static struct usb_protocol_ops snd_usbmidi_122l_ops = {
|
||||
.input = snd_usbmidi_us122l_input,
|
||||
.output = snd_usbmidi_us122l_output,
|
||||
};
|
||||
|
||||
/*
|
||||
* Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching.
|
||||
*/
|
||||
@@ -1714,6 +1750,9 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
|
||||
umidi->usb_protocol_ops =
|
||||
&snd_usbmidi_maudio_broken_running_status_ops;
|
||||
break;
|
||||
case QUIRK_MIDI_US122L:
|
||||
umidi->usb_protocol_ops = &snd_usbmidi_122l_ops;
|
||||
/* fall through */
|
||||
case QUIRK_MIDI_FIXED_ENDPOINT:
|
||||
memcpy(&endpoints[0], quirk->data,
|
||||
sizeof(struct snd_usb_midi_endpoint_info));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o
|
||||
snd-usb-us122l-objs := us122l.o
|
||||
|
||||
obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o
|
||||
obj-$(CONFIG_SND_USB_US122L) += snd-usb-us122l.o
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
#ifndef US122L_H
|
||||
#define US122L_H
|
||||
|
||||
|
||||
struct us122l {
|
||||
struct snd_usb_audio chip;
|
||||
int stride;
|
||||
struct usb_stream_kernel sk;
|
||||
|
||||
struct mutex mutex;
|
||||
struct file *first;
|
||||
unsigned second_periods_polled;
|
||||
struct file *master;
|
||||
struct file *slave;
|
||||
|
||||
atomic_t mmap_count;
|
||||
};
|
||||
|
||||
|
||||
#define US122L(c) ((struct us122l *)(c)->private_data)
|
||||
|
||||
#define NAME_ALLCAPS "US-122L"
|
||||
|
||||
#define USB_ID_US122L 0x800E
|
||||
#define USB_ID_US144 0x800F
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define USB_STREAM_INTERFACE_VERSION 2
|
||||
|
||||
#define SNDRV_USB_STREAM_IOCTL_SET_PARAMS \
|
||||
_IOW('H', 0x90, struct usb_stream_config)
|
||||
|
||||
struct usb_stream_packet {
|
||||
unsigned offset;
|
||||
unsigned length;
|
||||
};
|
||||
|
||||
|
||||
struct usb_stream_config {
|
||||
unsigned version;
|
||||
unsigned sample_rate;
|
||||
unsigned period_frames;
|
||||
unsigned frame_size;
|
||||
};
|
||||
|
||||
struct usb_stream {
|
||||
struct usb_stream_config cfg;
|
||||
unsigned read_size;
|
||||
unsigned write_size;
|
||||
|
||||
int period_size;
|
||||
|
||||
unsigned state;
|
||||
|
||||
int idle_insize;
|
||||
int idle_outsize;
|
||||
int sync_packet;
|
||||
unsigned insize_done;
|
||||
unsigned periods_done;
|
||||
unsigned periods_polled;
|
||||
|
||||
struct usb_stream_packet outpacket[2];
|
||||
unsigned inpackets;
|
||||
unsigned inpacket_head;
|
||||
unsigned inpacket_split;
|
||||
unsigned inpacket_split_at;
|
||||
unsigned next_inpacket_split;
|
||||
unsigned next_inpacket_split_at;
|
||||
struct usb_stream_packet inpacket[0];
|
||||
};
|
||||
|
||||
enum usb_stream_state {
|
||||
usb_stream_invalid,
|
||||
usb_stream_stopped,
|
||||
usb_stream_sync0,
|
||||
usb_stream_sync1,
|
||||
usb_stream_ready,
|
||||
usb_stream_running,
|
||||
usb_stream_xrun,
|
||||
};
|
||||
|
||||
#if __KERNEL__
|
||||
|
||||
#define USB_STREAM_NURBS 4
|
||||
#define USB_STREAM_URBDEPTH 4
|
||||
|
||||
struct usb_stream_kernel {
|
||||
struct usb_stream *s;
|
||||
|
||||
void *write_page;
|
||||
|
||||
unsigned n_o_ps;
|
||||
|
||||
struct urb *inurb[USB_STREAM_NURBS];
|
||||
struct urb *idle_inurb;
|
||||
struct urb *completed_inurb;
|
||||
struct urb *outurb[USB_STREAM_NURBS];
|
||||
struct urb *idle_outurb;
|
||||
struct urb *completed_outurb;
|
||||
struct urb *i_urb;
|
||||
|
||||
int iso_frame_balance;
|
||||
|
||||
wait_queue_head_t sleep;
|
||||
|
||||
unsigned out_phase;
|
||||
unsigned out_phase_peeked;
|
||||
unsigned freqn;
|
||||
};
|
||||
|
||||
struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
|
||||
struct usb_device *dev,
|
||||
unsigned in_endpoint, unsigned out_endpoint,
|
||||
unsigned sample_rate, unsigned use_packsize,
|
||||
unsigned period_frames, unsigned frame_size);
|
||||
void usb_stream_free(struct usb_stream_kernel *);
|
||||
int usb_stream_start(struct usb_stream_kernel *);
|
||||
void usb_stream_stop(struct usb_stream_kernel *);
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user