mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-21 00:42:16 +00:00
Staging: line6: another upstream sync
Everything should be in sync now. Signed-off-by: Markus Grabner <grabner@icg.tugraz.at> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
1027f476f5
commit
e1a164d7a3
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -15,11 +15,9 @@
|
||||
#include "driver.h"
|
||||
#include "audio.h"
|
||||
|
||||
|
||||
static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
|
||||
static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
|
||||
|
||||
|
||||
/*
|
||||
Initialize the Line6 USB audio system.
|
||||
*/
|
||||
@ -39,8 +37,7 @@ int line6_init_audio(struct usb_line6 *line6)
|
||||
strcpy(card->id, line6->properties->id);
|
||||
strcpy(card->driver, DRIVER_NAME);
|
||||
strcpy(card->shortname, line6->properties->name);
|
||||
sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
|
||||
dev_name(line6->ifcdev)); /* 80 chars - see asound.h */
|
||||
sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name, dev_name(line6->ifcdev)); /* 80 chars - see asound.h */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,13 +12,10 @@
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
|
||||
extern void line6_cleanup_audio(struct usb_line6 *);
|
||||
extern int line6_init_audio(struct usb_line6 *);
|
||||
extern int line6_register_audio(struct usb_line6 *);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -19,7 +19,6 @@
|
||||
#include "pcm.h"
|
||||
#include "pod.h"
|
||||
|
||||
|
||||
/*
|
||||
Find a free URB and submit it.
|
||||
*/
|
||||
@ -28,6 +27,7 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
|
||||
int index;
|
||||
unsigned long flags;
|
||||
int i, urb_size;
|
||||
int ret;
|
||||
struct urb *urb_in;
|
||||
|
||||
spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
|
||||
@ -57,11 +57,13 @@ static int submit_audio_in_urb(struct snd_line6_pcm *line6pcm)
|
||||
urb_in->transfer_buffer_length = urb_size;
|
||||
urb_in->context = line6pcm;
|
||||
|
||||
if (usb_submit_urb(urb_in, GFP_ATOMIC) == 0)
|
||||
ret = usb_submit_urb(urb_in, GFP_ATOMIC);
|
||||
|
||||
if (ret == 0)
|
||||
set_bit(index, &line6pcm->active_urb_in);
|
||||
else
|
||||
dev_err(line6pcm->line6->ifcdev,
|
||||
"URB in #%d submission failed\n", index);
|
||||
"URB in #%d submission failed (%d)\n", index, ret);
|
||||
|
||||
spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
|
||||
return 0;
|
||||
@ -147,9 +149,9 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
|
||||
|
||||
if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
|
||||
/*
|
||||
The transferred area goes over buffer boundary,
|
||||
copy two separate chunks.
|
||||
*/
|
||||
The transferred area goes over buffer boundary,
|
||||
copy two separate chunks.
|
||||
*/
|
||||
int len;
|
||||
len = runtime->buffer_size - line6pcm->pos_in_done;
|
||||
|
||||
@ -216,7 +218,7 @@ static void audio_in_callback(struct urb *urb)
|
||||
int fsize;
|
||||
struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
|
||||
|
||||
if (fin->status == -18) {
|
||||
if (fin->status == -EXDEV) {
|
||||
shutdown = 1;
|
||||
break;
|
||||
}
|
||||
@ -258,8 +260,11 @@ static void audio_in_callback(struct urb *urb)
|
||||
if (!shutdown) {
|
||||
submit_audio_in_urb(line6pcm);
|
||||
|
||||
if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags))
|
||||
line6_capture_check_period(line6pcm, length);
|
||||
#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
|
||||
if (!(line6pcm->flags & MASK_PCM_IMPULSE))
|
||||
#endif
|
||||
if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags))
|
||||
line6_capture_check_period(line6pcm, length);
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,8 +277,8 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream)
|
||||
|
||||
err = snd_pcm_hw_constraint_ratdens(runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_RATE,
|
||||
(&line6pcm->properties->
|
||||
snd_line6_rates));
|
||||
(&line6pcm->
|
||||
properties->snd_line6_rates));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -366,14 +371,14 @@ snd_line6_capture_pointer(struct snd_pcm_substream *substream)
|
||||
|
||||
/* capture operators */
|
||||
struct snd_pcm_ops snd_line6_capture_ops = {
|
||||
.open = snd_line6_capture_open,
|
||||
.close = snd_line6_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_line6_capture_hw_params,
|
||||
.hw_free = snd_line6_capture_hw_free,
|
||||
.prepare = snd_line6_prepare,
|
||||
.trigger = snd_line6_trigger,
|
||||
.pointer = snd_line6_capture_pointer,
|
||||
.open = snd_line6_capture_open,
|
||||
.close = snd_line6_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_line6_capture_hw_params,
|
||||
.hw_free = snd_line6_capture_hw_free,
|
||||
.prepare = snd_line6_prepare,
|
||||
.trigger = snd_line6_trigger,
|
||||
.pointer = snd_line6_capture_pointer,
|
||||
};
|
||||
|
||||
int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
|
||||
@ -396,8 +401,8 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
|
||||
urb->dev = line6pcm->line6->usbdev;
|
||||
urb->pipe =
|
||||
usb_rcvisocpipe(line6pcm->line6->usbdev,
|
||||
line6pcm->
|
||||
ep_audio_read & USB_ENDPOINT_NUMBER_MASK);
|
||||
line6pcm->ep_audio_read &
|
||||
USB_ENDPOINT_NUMBER_MASK);
|
||||
urb->transfer_flags = URB_ISO_ASAP;
|
||||
urb->start_frame = -1;
|
||||
urb->number_of_packets = LINE6_ISO_PACKETS;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,17 +12,17 @@
|
||||
#ifndef CAPTURE_H
|
||||
#define CAPTURE_H
|
||||
|
||||
|
||||
#include <sound/pcm.h>
|
||||
|
||||
#include "driver.h"
|
||||
#include "pcm.h"
|
||||
|
||||
|
||||
extern struct snd_pcm_ops snd_line6_capture_ops;
|
||||
|
||||
extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
|
||||
int fsize);
|
||||
extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
|
||||
int length);
|
||||
extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
|
||||
extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
|
||||
extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -22,7 +22,9 @@
|
||||
from "control.h", and this process depends on the exact formatting of the
|
||||
code and the comments below!
|
||||
*/
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
enum {
|
||||
POD_tweak = 1,
|
||||
POD_wah_position = 4,
|
||||
@ -181,11 +183,13 @@ enum {
|
||||
VARIAXMIDI_tone = 79,
|
||||
};
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
extern int line6_pod_create_files(int firmware, int type, struct device *dev);
|
||||
extern void line6_pod_remove_files(int firmware, int type, struct device *dev);
|
||||
extern int line6_variax_create_files(int firmware, int type, struct device *dev);
|
||||
extern void line6_variax_remove_files(int firmware, int type, struct device *dev);
|
||||
|
||||
extern int line6_variax_create_files(int firmware, int type,
|
||||
struct device *dev);
|
||||
extern void line6_variax_remove_files(int firmware, int type,
|
||||
struct device *dev);
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -26,35 +26,35 @@
|
||||
#include "usbdefs.h"
|
||||
#include "variax.h"
|
||||
|
||||
|
||||
#define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>"
|
||||
#define DRIVER_DESC "Line6 USB Driver"
|
||||
#define DRIVER_VERSION "0.9.0"
|
||||
|
||||
#define DRIVER_VERSION "0.9.1beta" DRIVER_REVISION
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
static const struct usb_device_id line6_id_table[] = {
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2) },
|
||||
{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX) },
|
||||
{ },
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_GX)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX1)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODSTUDIO_UX2)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2)},
|
||||
{USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX)},
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, line6_id_table);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
static struct line6_properties line6_properties_table[] = {
|
||||
{ "BassPODxt", "BassPODxt", LINE6_BIT_BASSPODXT, LINE6_BIT_CONTROL_PCM_HWMON },
|
||||
{ "BassPODxtLive", "BassPODxt Live", LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM_HWMON },
|
||||
@ -74,7 +74,7 @@ static struct line6_properties line6_properties_table[] = {
|
||||
{ "TonePortUX2", "TonePort UX2", LINE6_BIT_TONEPORT_UX2, LINE6_BIT_PCM },
|
||||
{ "Variax", "Variax Workbench", LINE6_BIT_VARIAX, LINE6_BIT_CONTROL }
|
||||
};
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
This is Line6's MIDI manufacturer ID.
|
||||
@ -96,10 +96,8 @@ static const char line6_request_version0[] = {
|
||||
*/
|
||||
static const char *line6_request_version;
|
||||
|
||||
|
||||
struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
|
||||
|
||||
|
||||
/**
|
||||
Class for asynchronous messages.
|
||||
*/
|
||||
@ -110,7 +108,6 @@ struct message {
|
||||
int done;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Forward declarations.
|
||||
*/
|
||||
@ -118,7 +115,6 @@ static void line6_data_received(struct urb *urb);
|
||||
static int line6_send_raw_message_async_part(struct message *msg,
|
||||
struct urb *urb);
|
||||
|
||||
|
||||
/*
|
||||
Start to listen on endpoint.
|
||||
*/
|
||||
@ -130,7 +126,7 @@ static int line6_start_listen(struct usb_line6 *line6)
|
||||
line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
|
||||
line6_data_received, line6, line6->interval);
|
||||
line6->urb_listen->actual_length = 0;
|
||||
err = usb_submit_urb(line6->urb_listen, GFP_KERNEL);
|
||||
err = usb_submit_urb(line6->urb_listen, GFP_ATOMIC);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -166,12 +162,13 @@ void line6_write_hexdump(struct usb_line6 *line6, char dir,
|
||||
if (j < n) {
|
||||
unsigned char val = buffer[i + j];
|
||||
bytes = snprintf(p, hexdumpsize, " %02X", val);
|
||||
asc[j] = ((val >= 0x20) && (val < 0x7f)) ? val : '.';
|
||||
asc[j] = ((val >= 0x20)
|
||||
&& (val < 0x7f)) ? val : '.';
|
||||
} else
|
||||
bytes = snprintf(p, hexdumpsize, " ");
|
||||
|
||||
if (bytes > hexdumpsize)
|
||||
break; /* buffer overflow */
|
||||
break; /* buffer overflow */
|
||||
|
||||
p += bytes;
|
||||
hexdumpsize -= bytes;
|
||||
@ -286,7 +283,7 @@ static int line6_send_raw_message_async_part(struct message *msg,
|
||||
Setup and start timer.
|
||||
*/
|
||||
void line6_start_timer(struct timer_list *timer, unsigned int msecs,
|
||||
void (*function)(unsigned long), unsigned long data)
|
||||
void (*function) (unsigned long), unsigned long data)
|
||||
{
|
||||
setup_timer(timer, function, data);
|
||||
timer->expires = jiffies + msecs * HZ / 1000;
|
||||
@ -334,7 +331,8 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
|
||||
*/
|
||||
int line6_version_request_async(struct usb_line6 *line6)
|
||||
{
|
||||
return line6_send_raw_message_async(line6, line6_request_version, sizeof(line6_request_version0));
|
||||
return line6_send_raw_message_async(line6, line6_request_version,
|
||||
sizeof(line6_request_version0));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -343,7 +341,9 @@ int line6_version_request_async(struct usb_line6 *line6)
|
||||
int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
|
||||
int size)
|
||||
{
|
||||
return line6_send_raw_message(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE;
|
||||
return line6_send_raw_message(line6, buffer,
|
||||
size + SYSEX_EXTRA_SIZE) -
|
||||
SYSEX_EXTRA_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -352,7 +352,9 @@ int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
|
||||
int line6_send_sysex_message_async(struct usb_line6 *line6, const char *buffer,
|
||||
int size)
|
||||
{
|
||||
return line6_send_raw_message_async(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE;
|
||||
return line6_send_raw_message_async(line6, buffer,
|
||||
size + SYSEX_EXTRA_SIZE) -
|
||||
SYSEX_EXTRA_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -394,21 +396,28 @@ static void line6_data_received(struct urb *urb)
|
||||
line6_dump_urb(urb);
|
||||
#endif
|
||||
|
||||
done = line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
|
||||
done =
|
||||
line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
|
||||
|
||||
if (done < urb->actual_length) {
|
||||
line6_midibuf_ignore(mb, done);
|
||||
DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(line6->ifcdev,
|
||||
"%d %d buffer overflow - message skipped\n",
|
||||
done, urb->actual_length));
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
done = line6_midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN);
|
||||
done =
|
||||
line6_midibuf_read(mb, line6->buffer_message,
|
||||
LINE6_MESSAGE_MAXLEN);
|
||||
|
||||
if (done == 0)
|
||||
break;
|
||||
|
||||
/* MIDI input filter */
|
||||
if (line6_midibuf_skip_message(mb, line6->line6midi->midi_mask_receive))
|
||||
if (line6_midibuf_skip_message
|
||||
(mb, line6->line6midi->midi_mask_receive))
|
||||
continue;
|
||||
|
||||
line6->message_length = done;
|
||||
@ -424,26 +433,33 @@ static void line6_data_received(struct urb *urb)
|
||||
case LINE6_DEVID_PODXT:
|
||||
case LINE6_DEVID_PODXTPRO:
|
||||
case LINE6_DEVID_POCKETPOD:
|
||||
line6_pod_process_message((struct usb_line6_pod *)line6);
|
||||
line6_pod_process_message((struct usb_line6_pod *)
|
||||
line6);
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_PODXTLIVE:
|
||||
switch (line6->interface_number) {
|
||||
case PODXTLIVE_INTERFACE_POD:
|
||||
line6_pod_process_message((struct usb_line6_pod *)line6);
|
||||
line6_pod_process_message((struct usb_line6_pod
|
||||
*)line6);
|
||||
break;
|
||||
|
||||
case PODXTLIVE_INTERFACE_VARIAX:
|
||||
line6_variax_process_message((struct usb_line6_variax *)line6);
|
||||
line6_variax_process_message((struct
|
||||
usb_line6_variax
|
||||
*)line6);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(line6->ifcdev, "PODxt Live interface %d not supported\n", line6->interface_number);
|
||||
dev_err(line6->ifcdev,
|
||||
"PODxt Live interface %d not supported\n",
|
||||
line6->interface_number);
|
||||
}
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_VARIAX:
|
||||
line6_variax_process_message((struct usb_line6_variax *)line6);
|
||||
line6_variax_process_message((struct usb_line6_variax *)
|
||||
line6);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -483,7 +499,8 @@ int line6_send_program(struct usb_line6 *line6, int value)
|
||||
buffer, 2, &partial, LINE6_TIMEOUT * HZ);
|
||||
|
||||
if (retval)
|
||||
dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
|
||||
dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
|
||||
retval);
|
||||
|
||||
kfree(buffer);
|
||||
return retval;
|
||||
@ -514,11 +531,13 @@ int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
|
||||
#endif
|
||||
|
||||
retval = usb_interrupt_msg(line6->usbdev,
|
||||
usb_sndintpipe(line6->usbdev, line6->ep_control_write),
|
||||
usb_sndintpipe(line6->usbdev,
|
||||
line6->ep_control_write),
|
||||
buffer, 3, &partial, LINE6_TIMEOUT * HZ);
|
||||
|
||||
if (retval)
|
||||
dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
|
||||
dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n",
|
||||
retval);
|
||||
|
||||
kfree(buffer);
|
||||
return retval;
|
||||
@ -527,7 +546,8 @@ int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
|
||||
/*
|
||||
Read data from device.
|
||||
*/
|
||||
int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen)
|
||||
int line6_read_data(struct usb_line6 *line6, int address, void *data,
|
||||
size_t datalen)
|
||||
{
|
||||
struct usb_device *usbdev = line6->usbdev;
|
||||
int ret;
|
||||
@ -615,8 +635,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data,
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
while (status == 0xff)
|
||||
;
|
||||
while (status == 0xff);
|
||||
|
||||
if (status != 0) {
|
||||
dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
|
||||
@ -632,7 +651,8 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data,
|
||||
*/
|
||||
int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
|
||||
{
|
||||
return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number));
|
||||
return line6_read_data(line6, 0x80d0, serial_number,
|
||||
sizeof(*serial_number));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -647,7 +667,7 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
|
||||
/*
|
||||
No operation (i.e., unsupported).
|
||||
*/
|
||||
ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
|
||||
ssize_t line6_nop_write(struct device * dev, struct device_attribute * attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
return count;
|
||||
@ -657,7 +677,7 @@ ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
|
||||
"write" request on "raw" special file.
|
||||
*/
|
||||
#ifdef CONFIG_LINE6_USB_RAW
|
||||
ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
|
||||
ssize_t line6_set_raw(struct device * dev, struct device_attribute * attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_interface *interface = to_usb_interface(dev);
|
||||
@ -697,7 +717,8 @@ static void line6_destruct(struct usb_interface *interface)
|
||||
/*
|
||||
Probe USB device.
|
||||
*/
|
||||
static int line6_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||
static int line6_probe(struct usb_interface *interface,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
int devtype;
|
||||
struct usb_device *usbdev = NULL;
|
||||
@ -765,7 +786,7 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
case LINE6_DEVID_POCKETPOD:
|
||||
switch (interface_number) {
|
||||
case 0:
|
||||
return 0; /* this interface has no endpoints */
|
||||
return 0; /* this interface has no endpoints */
|
||||
case 1:
|
||||
alternate = 0;
|
||||
break;
|
||||
@ -800,7 +821,7 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
case LINE6_DEVID_PODSTUDIO_UX1:
|
||||
case LINE6_DEVID_TONEPORT_GX:
|
||||
case LINE6_DEVID_TONEPORT_UX1:
|
||||
alternate = 2; /* 1..4 seem to be ok */
|
||||
alternate = 2; /* 1..4 seem to be ok */
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_TONEPORT_UX2:
|
||||
@ -812,9 +833,9 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
break;
|
||||
case 1:
|
||||
/* don't know yet what this is ...
|
||||
alternate = 1;
|
||||
break;
|
||||
*/
|
||||
alternate = 1;
|
||||
break;
|
||||
*/
|
||||
return -ENODEV;
|
||||
default:
|
||||
MISSING_CASE;
|
||||
@ -841,13 +862,13 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
case LINE6_DEVID_PODXT:
|
||||
case LINE6_DEVID_PODXTPRO:
|
||||
size = sizeof(struct usb_line6_pod);
|
||||
ep_read = 0x84;
|
||||
ep_read = 0x84;
|
||||
ep_write = 0x03;
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_POCKETPOD:
|
||||
size = sizeof(struct usb_line6_pod);
|
||||
ep_read = 0x82;
|
||||
ep_read = 0x82;
|
||||
ep_write = 0x02;
|
||||
break;
|
||||
|
||||
@ -855,7 +876,7 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
case LINE6_DEVID_PODX3LIVE:
|
||||
/* currently unused! */
|
||||
size = sizeof(struct usb_line6_pod);
|
||||
ep_read = 0x81;
|
||||
ep_read = 0x81;
|
||||
ep_write = 0x01;
|
||||
break;
|
||||
|
||||
@ -874,13 +895,13 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
switch (interface_number) {
|
||||
case PODXTLIVE_INTERFACE_POD:
|
||||
size = sizeof(struct usb_line6_pod);
|
||||
ep_read = 0x84;
|
||||
ep_read = 0x84;
|
||||
ep_write = 0x03;
|
||||
break;
|
||||
|
||||
case PODXTLIVE_INTERFACE_VARIAX:
|
||||
size = sizeof(struct usb_line6_variax);
|
||||
ep_read = 0x86;
|
||||
ep_read = 0x86;
|
||||
ep_write = 0x05;
|
||||
break;
|
||||
|
||||
@ -892,7 +913,7 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
|
||||
case LINE6_DEVID_VARIAX:
|
||||
size = sizeof(struct usb_line6_variax);
|
||||
ep_read = 0x82;
|
||||
ep_read = 0x82;
|
||||
ep_write = 0x01;
|
||||
break;
|
||||
|
||||
@ -903,7 +924,8 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
dev_err(line6->ifcdev, "driver bug: interface data size not set\n");
|
||||
dev_err(line6->ifcdev,
|
||||
"driver bug: interface data size not set\n");
|
||||
ret = -ENODEV;
|
||||
goto err_put;
|
||||
}
|
||||
@ -928,16 +950,19 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
/* get data from endpoint descriptor (see usb_maxpacket): */
|
||||
{
|
||||
struct usb_host_endpoint *ep;
|
||||
unsigned epnum = usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
|
||||
unsigned epnum =
|
||||
usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
|
||||
ep = usbdev->ep_in[epnum];
|
||||
|
||||
if (ep != NULL) {
|
||||
line6->interval = ep->desc.bInterval;
|
||||
line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
|
||||
line6->max_packet_size =
|
||||
le16_to_cpu(ep->desc.wMaxPacketSize);
|
||||
} else {
|
||||
line6->interval = LINE6_FALLBACK_INTERVAL;
|
||||
line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
|
||||
dev_err(line6->ifcdev, "endpoint not available, using fallback values");
|
||||
dev_err(line6->ifcdev,
|
||||
"endpoint not available, using fallback values");
|
||||
}
|
||||
}
|
||||
|
||||
@ -945,7 +970,8 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
|
||||
if (properties->capabilities & LINE6_BIT_CONTROL) {
|
||||
/* initialize USB buffers: */
|
||||
line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
|
||||
line6->buffer_listen =
|
||||
kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
|
||||
|
||||
if (line6->buffer_listen == NULL) {
|
||||
dev_err(&interface->dev, "Out of memory\n");
|
||||
@ -953,7 +979,8 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
goto err_destruct;
|
||||
}
|
||||
|
||||
line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
|
||||
line6->buffer_message =
|
||||
kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
|
||||
|
||||
if (line6->buffer_message == NULL) {
|
||||
dev_err(&interface->dev, "Out of memory\n");
|
||||
@ -994,11 +1021,15 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
case LINE6_DEVID_PODXTLIVE:
|
||||
switch (interface_number) {
|
||||
case PODXTLIVE_INTERFACE_POD:
|
||||
ret = line6_pod_init(interface, (struct usb_line6_pod *)line6);
|
||||
ret =
|
||||
line6_pod_init(interface,
|
||||
(struct usb_line6_pod *)line6);
|
||||
break;
|
||||
|
||||
case PODXTLIVE_INTERFACE_VARIAX:
|
||||
ret = line6_variax_init(interface, (struct usb_line6_variax *)line6);
|
||||
ret =
|
||||
line6_variax_init(interface,
|
||||
(struct usb_line6_variax *)line6);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1011,7 +1042,9 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_VARIAX:
|
||||
ret = line6_variax_init(interface, (struct usb_line6_variax *)line6);
|
||||
ret =
|
||||
line6_variax_init(interface,
|
||||
(struct usb_line6_variax *)line6);
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_PODSTUDIO_GX:
|
||||
@ -1021,7 +1054,9 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
case LINE6_DEVID_TONEPORT_UX1:
|
||||
case LINE6_DEVID_TONEPORT_UX2:
|
||||
case LINE6_DEVID_GUITARPORT:
|
||||
ret = line6_toneport_init(interface, (struct usb_line6_toneport *)line6);
|
||||
ret =
|
||||
line6_toneport_init(interface,
|
||||
(struct usb_line6_toneport *)line6);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1043,10 +1078,11 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
|
||||
line6->properties->name);
|
||||
line6_devices[devnum] = line6;
|
||||
|
||||
switch(product) {
|
||||
switch (product) {
|
||||
case LINE6_DEVID_PODX3:
|
||||
case LINE6_DEVID_PODX3LIVE:
|
||||
dev_info(&interface->dev, "NOTE: the Line6 %s is detected, but not yet supported\n",
|
||||
dev_info(&interface->dev,
|
||||
"NOTE: the Line6 %s is detected, but not yet supported\n",
|
||||
line6->properties->name);
|
||||
}
|
||||
|
||||
@ -1137,7 +1173,8 @@ static void line6_disconnect(struct usb_interface *interface)
|
||||
MISSING_CASE;
|
||||
}
|
||||
|
||||
dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name);
|
||||
dev_info(&interface->dev, "Line6 %s now disconnected\n",
|
||||
line6->properties->name);
|
||||
|
||||
for (i = LINE6_MAX_DEVICES; i--;)
|
||||
if (line6_devices[i] == line6)
|
||||
@ -1210,7 +1247,7 @@ static int line6_reset_resume(struct usb_interface *interface)
|
||||
return line6_resume(interface);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct usb_driver line6_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
@ -1231,8 +1268,7 @@ static int __init line6_init(void)
|
||||
{
|
||||
int i, retval;
|
||||
|
||||
printk(KERN_INFO "%s driver version %s%s\n",
|
||||
DRIVER_NAME, DRIVER_VERSION, DRIVER_REVISION);
|
||||
printk(KERN_INFO "%s driver version %s\n", DRIVER_NAME, DRIVER_VERSION);
|
||||
|
||||
for (i = LINE6_MAX_DEVICES; i--;)
|
||||
line6_devices[i] = NULL;
|
||||
@ -1263,8 +1299,27 @@ static int __init line6_init(void)
|
||||
*/
|
||||
static void __exit line6_exit(void)
|
||||
{
|
||||
kfree(line6_request_version);
|
||||
int i;
|
||||
struct usb_line6 *line6;
|
||||
struct snd_line6_pcm *line6pcm;
|
||||
|
||||
/* stop all PCM channels */
|
||||
for (i = LINE6_MAX_DEVICES; i--;) {
|
||||
line6 = line6_devices[i];
|
||||
|
||||
if (line6 == NULL)
|
||||
continue;
|
||||
|
||||
line6pcm = line6->line6pcm;
|
||||
|
||||
if (line6pcm == NULL)
|
||||
continue;
|
||||
|
||||
line6_pcm_stop(line6pcm, ~0);
|
||||
}
|
||||
|
||||
usb_deregister(&line6_driver);
|
||||
kfree(line6_request_version);
|
||||
}
|
||||
|
||||
module_init(line6_init);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,14 +12,12 @@
|
||||
#ifndef DRIVER_H
|
||||
#define DRIVER_H
|
||||
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/usb.h>
|
||||
#include <sound/core.h>
|
||||
|
||||
#include "midi.h"
|
||||
|
||||
|
||||
#define DRIVER_NAME "line6usb"
|
||||
|
||||
#if defined(CONFIG_LINE6_USB_DUMP_CTRL) || defined(CONFIG_LINE6_USB_DUMP_MIDI) || defined(CONFIG_LINE6_USB_DUMP_PCM)
|
||||
@ -51,7 +49,7 @@
|
||||
*/
|
||||
#define LINE6_CHANNEL_DEVICE 0x02
|
||||
|
||||
#define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */
|
||||
#define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */
|
||||
|
||||
#define LINE6_CHANNEL_MASK 0x0f
|
||||
|
||||
@ -61,12 +59,10 @@
|
||||
#define DEBUG_MESSAGES(x)
|
||||
#endif
|
||||
|
||||
|
||||
#define MISSING_CASE \
|
||||
printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
|
||||
#define CHECK_RETURN(x) \
|
||||
do { \
|
||||
err = x; \
|
||||
@ -79,14 +75,12 @@ do { \
|
||||
return; \
|
||||
x = (n);
|
||||
|
||||
|
||||
extern const unsigned char line6_midi_id[3];
|
||||
extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
|
||||
|
||||
static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
|
||||
static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
|
||||
|
||||
|
||||
/**
|
||||
Common properties of Line6 devices.
|
||||
*/
|
||||
@ -202,7 +196,6 @@ struct usb_line6 {
|
||||
int message_length;
|
||||
};
|
||||
|
||||
|
||||
extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
|
||||
int code2, int size);
|
||||
extern ssize_t line6_nop_read(struct device *dev,
|
||||
@ -226,7 +219,8 @@ extern int line6_send_sysex_message_async(struct usb_line6 *line6,
|
||||
extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
extern void line6_start_timer(struct timer_list *timer, unsigned int msecs,
|
||||
void (*function)(unsigned long), unsigned long data);
|
||||
void (*function) (unsigned long),
|
||||
unsigned long data);
|
||||
extern int line6_transmit_parameter(struct usb_line6 *line6, int param,
|
||||
int value);
|
||||
extern int line6_version_request_async(struct usb_line6 *line6);
|
||||
@ -238,5 +232,4 @@ extern void line6_write_hexdump(struct usb_line6 *line6, char dir,
|
||||
const unsigned char *buffer, int size);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -14,7 +14,6 @@
|
||||
#include "driver.h"
|
||||
#include "dumprequest.h"
|
||||
|
||||
|
||||
/*
|
||||
Set "dump in progress" flag.
|
||||
*/
|
||||
@ -63,7 +62,8 @@ int line6_dump_request_async(struct line6_dump_request *l6dr,
|
||||
*/
|
||||
int line6_dump_wait_interruptible(struct line6_dump_request *l6dr)
|
||||
{
|
||||
return wait_event_interruptible(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE);
|
||||
return wait_event_interruptible(l6dr->wait,
|
||||
l6dr->in_progress == LINE6_DUMP_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -79,7 +79,9 @@ void line6_dump_wait(struct line6_dump_request *l6dr)
|
||||
*/
|
||||
int line6_dump_wait_timeout(struct line6_dump_request *l6dr, long timeout)
|
||||
{
|
||||
return wait_event_timeout(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE, timeout);
|
||||
return wait_event_timeout(l6dr->wait,
|
||||
l6dr->in_progress == LINE6_DUMP_NONE,
|
||||
timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,18 +12,15 @@
|
||||
#ifndef DUMPREQUEST_H
|
||||
#define DUMPREQUEST_H
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <linux/wait.h>
|
||||
#include <sound/core.h>
|
||||
|
||||
|
||||
enum {
|
||||
LINE6_DUMP_NONE,
|
||||
LINE6_DUMP_CURRENT
|
||||
};
|
||||
|
||||
|
||||
struct line6_dump_reqbuf {
|
||||
/**
|
||||
Buffer for dump requests.
|
||||
@ -76,5 +73,4 @@ extern int line6_dump_wait_interruptible(struct line6_dump_request *l6dr);
|
||||
extern int line6_dump_wait_timeout(struct line6_dump_request *l6dr,
|
||||
long timeout);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -20,15 +20,12 @@
|
||||
#include "pod.h"
|
||||
#include "usbdefs.h"
|
||||
|
||||
|
||||
#define line6_rawmidi_substream_midi(substream) \
|
||||
((struct snd_line6_midi *)((substream)->rmidi->private_data))
|
||||
|
||||
|
||||
static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
|
||||
int length);
|
||||
|
||||
|
||||
/*
|
||||
Pass data received via USB to MIDI.
|
||||
*/
|
||||
@ -45,7 +42,8 @@ void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
|
||||
*/
|
||||
static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
|
||||
struct usb_line6 *line6 =
|
||||
line6_rawmidi_substream_midi(substream)->line6;
|
||||
struct snd_line6_midi *line6midi = line6->line6midi;
|
||||
struct MidiBuffer *mb = &line6midi->midibuf_out;
|
||||
unsigned long flags;
|
||||
@ -74,7 +72,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
|
||||
if (done == 0)
|
||||
break;
|
||||
|
||||
if (line6_midibuf_skip_message(mb, line6midi->midi_mask_transmit))
|
||||
if (line6_midibuf_skip_message
|
||||
(mb, line6midi->midi_mask_transmit))
|
||||
continue;
|
||||
|
||||
send_midi_async(line6, chunk, done);
|
||||
@ -132,7 +131,6 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
|
||||
dev_err(line6->ifcdev, "Out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LINE6_USB_DUMP_CTRL
|
||||
line6_write_hexdump(line6, 'S', data, length);
|
||||
#endif
|
||||
@ -174,6 +172,9 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
|
||||
length);
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_VARIAX:
|
||||
break;
|
||||
|
||||
default:
|
||||
MISSING_CASE;
|
||||
}
|
||||
@ -195,7 +196,8 @@ static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
|
||||
int up)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
|
||||
struct usb_line6 *line6 =
|
||||
line6_rawmidi_substream_midi(substream)->line6;
|
||||
|
||||
line6->line6midi->substream_transmit = substream;
|
||||
spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
|
||||
@ -208,9 +210,11 @@ static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
|
||||
|
||||
static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
|
||||
{
|
||||
struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
|
||||
struct usb_line6 *line6 =
|
||||
line6_rawmidi_substream_midi(substream)->line6;
|
||||
struct snd_line6_midi *midi = line6->line6midi;
|
||||
wait_event_interruptible(midi->send_wait, midi->num_active_send_urbs == 0);
|
||||
wait_event_interruptible(midi->send_wait,
|
||||
midi->num_active_send_urbs == 0);
|
||||
}
|
||||
|
||||
static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
|
||||
@ -226,7 +230,8 @@ static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
|
||||
static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
|
||||
int up)
|
||||
{
|
||||
struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
|
||||
struct usb_line6 *line6 =
|
||||
line6_rawmidi_substream_midi(substream)->line6;
|
||||
|
||||
if (up)
|
||||
line6->line6midi->substream_receive = substream;
|
||||
@ -271,9 +276,8 @@ static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
|
||||
strcpy(rmidi->name, line6midi->line6->properties->name);
|
||||
|
||||
rmidi->info_flags =
|
||||
SNDRV_RAWMIDI_INFO_OUTPUT |
|
||||
SNDRV_RAWMIDI_INFO_INPUT |
|
||||
SNDRV_RAWMIDI_INFO_DUPLEX;
|
||||
SNDRV_RAWMIDI_INFO_OUTPUT |
|
||||
SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
|
||||
|
||||
snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&line6_midi_output_ops);
|
||||
@ -346,15 +350,19 @@ static ssize_t midi_set_midi_mask_receive(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
|
||||
static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
|
||||
static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO,
|
||||
midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
|
||||
static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO,
|
||||
midi_get_midi_mask_receive, midi_set_midi_mask_receive);
|
||||
|
||||
/* MIDI device destructor */
|
||||
static int snd_line6_midi_free(struct snd_device *device)
|
||||
{
|
||||
struct snd_line6_midi *line6midi = device->device_data;
|
||||
device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_transmit);
|
||||
device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_receive);
|
||||
device_remove_file(line6midi->line6->ifcdev,
|
||||
&dev_attr_midi_mask_transmit);
|
||||
device_remove_file(line6midi->line6->ifcdev,
|
||||
&dev_attr_midi_mask_receive);
|
||||
line6_midibuf_destroy(&line6midi->midibuf_in);
|
||||
line6_midibuf_destroy(&line6midi->midibuf_out);
|
||||
return 0;
|
||||
@ -373,7 +381,7 @@ int line6_init_midi(struct usb_line6 *line6)
|
||||
struct snd_line6_midi *line6midi;
|
||||
|
||||
if (!(line6->properties->capabilities & LINE6_BIT_CONTROL))
|
||||
return 0; /* skip MIDI initialization and report success */
|
||||
return 0; /* skip MIDI initialization and report success */
|
||||
|
||||
line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,15 +12,12 @@
|
||||
#ifndef MIDI_H
|
||||
#define MIDI_H
|
||||
|
||||
|
||||
#include <sound/rawmidi.h>
|
||||
|
||||
#include "midibuf.h"
|
||||
|
||||
|
||||
#define MIDI_BUFFER_SIZE 1024
|
||||
|
||||
|
||||
struct snd_line6_midi {
|
||||
/**
|
||||
Pointer back to the Line6 driver data structure.
|
||||
@ -78,10 +75,8 @@ struct snd_line6_midi {
|
||||
struct MidiBuffer midibuf_out;
|
||||
};
|
||||
|
||||
|
||||
extern int line6_init_midi(struct usb_line6 *line6);
|
||||
extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
|
||||
int length);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -13,7 +13,6 @@
|
||||
|
||||
#include "midibuf.h"
|
||||
|
||||
|
||||
static int midibuf_message_length(unsigned char code)
|
||||
{
|
||||
if (code < 0x80)
|
||||
@ -23,12 +22,13 @@ static int midibuf_message_length(unsigned char code)
|
||||
return length[(code >> 4) - 8];
|
||||
} else {
|
||||
/*
|
||||
Note that according to the MIDI specification 0xf2 is
|
||||
the "Song Position Pointer", but this is used by Line6
|
||||
to send sysex messages to the host.
|
||||
*/
|
||||
Note that according to the MIDI specification 0xf2 is
|
||||
the "Song Position Pointer", but this is used by Line6
|
||||
to send sysex messages to the host.
|
||||
*/
|
||||
static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
|
||||
1, 1, 1, -1, 1, 1 };
|
||||
1, 1, 1, -1, 1, 1
|
||||
};
|
||||
return length[code & 0x0f];
|
||||
}
|
||||
}
|
||||
@ -72,20 +72,23 @@ void line6_midibuf_status(struct MidiBuffer *this)
|
||||
int line6_midibuf_bytes_free(struct MidiBuffer *this)
|
||||
{
|
||||
return
|
||||
midibuf_is_full(this) ?
|
||||
0 :
|
||||
(this->pos_read - this->pos_write + this->size - 1) % this->size + 1;
|
||||
midibuf_is_full(this) ?
|
||||
0 :
|
||||
(this->pos_read - this->pos_write + this->size - 1) % this->size +
|
||||
1;
|
||||
}
|
||||
|
||||
int line6_midibuf_bytes_used(struct MidiBuffer *this)
|
||||
{
|
||||
return
|
||||
midibuf_is_empty(this) ?
|
||||
0 :
|
||||
(this->pos_write - this->pos_read + this->size - 1) % this->size + 1;
|
||||
midibuf_is_empty(this) ?
|
||||
0 :
|
||||
(this->pos_write - this->pos_read + this->size - 1) % this->size +
|
||||
1;
|
||||
}
|
||||
|
||||
int line6_midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
|
||||
int line6_midibuf_write(struct MidiBuffer *this, unsigned char *data,
|
||||
int length)
|
||||
{
|
||||
int bytes_free;
|
||||
int length1, length2;
|
||||
@ -158,7 +161,8 @@ int line6_midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
|
||||
this->command_prev = command;
|
||||
} else {
|
||||
if (this->command_prev > 0) {
|
||||
int midi_length_prev = midibuf_message_length(this->command_prev);
|
||||
int midi_length_prev =
|
||||
midibuf_message_length(this->command_prev);
|
||||
|
||||
if (midi_length_prev > 0) {
|
||||
midi_length = midi_length_prev - 1;
|
||||
@ -198,15 +202,15 @@ int line6_midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
|
||||
}
|
||||
|
||||
if (midi_length == length)
|
||||
midi_length = -1; /* end of message not found */
|
||||
midi_length = -1; /* end of message not found */
|
||||
}
|
||||
|
||||
if (midi_length < 0) {
|
||||
if (!this->split)
|
||||
return 0; /* command is not yet complete */
|
||||
return 0; /* command is not yet complete */
|
||||
} else {
|
||||
if (length < midi_length)
|
||||
return 0; /* command is not yet complete */
|
||||
return 0; /* command is not yet complete */
|
||||
|
||||
length = midi_length;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,7 +12,6 @@
|
||||
#ifndef MIDIBUF_H
|
||||
#define MIDIBUF_H
|
||||
|
||||
|
||||
struct MidiBuffer {
|
||||
unsigned char *buf;
|
||||
int size;
|
||||
@ -22,18 +21,18 @@ struct MidiBuffer {
|
||||
int command_prev;
|
||||
};
|
||||
|
||||
|
||||
extern int line6_midibuf_bytes_used(struct MidiBuffer *mb);
|
||||
extern int line6_midibuf_bytes_free(struct MidiBuffer *mb);
|
||||
extern void line6_midibuf_destroy(struct MidiBuffer *mb);
|
||||
extern int line6_midibuf_ignore(struct MidiBuffer *mb, int length);
|
||||
extern int line6_midibuf_init(struct MidiBuffer *mb, int size, int split);
|
||||
extern int line6_midibuf_read(struct MidiBuffer *mb, unsigned char *data, int length);
|
||||
extern int line6_midibuf_read(struct MidiBuffer *mb, unsigned char *data,
|
||||
int length);
|
||||
extern void line6_midibuf_reset(struct MidiBuffer *mb);
|
||||
extern int line6_midibuf_skip_message(struct MidiBuffer *mb, unsigned short mask);
|
||||
extern int line6_midibuf_skip_message(struct MidiBuffer *mb,
|
||||
unsigned short mask);
|
||||
extern void line6_midibuf_status(struct MidiBuffer *mb);
|
||||
extern int line6_midibuf_write(struct MidiBuffer *mb, unsigned char *data,
|
||||
int length);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -21,10 +21,9 @@
|
||||
#include "playback.h"
|
||||
#include "pod.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
|
||||
|
||||
static struct snd_line6_pcm* dev2pcm(struct device *dev)
|
||||
static struct snd_line6_pcm *dev2pcm(struct device *dev)
|
||||
{
|
||||
struct usb_interface *interface = to_usb_interface(dev);
|
||||
struct usb_line6 *line6 = usb_get_intfdata(interface);
|
||||
@ -36,8 +35,7 @@ static struct snd_line6_pcm* dev2pcm(struct device *dev)
|
||||
"read" request on "impulse_volume" special file.
|
||||
*/
|
||||
static ssize_t pcm_get_impulse_volume(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_volume);
|
||||
}
|
||||
@ -53,7 +51,7 @@ static ssize_t pcm_set_impulse_volume(struct device *dev,
|
||||
int value = simple_strtoul(buf, NULL, 10);
|
||||
line6pcm->impulse_volume = value;
|
||||
|
||||
if(value > 0)
|
||||
if (value > 0)
|
||||
line6_pcm_start(line6pcm, MASK_PCM_IMPULSE);
|
||||
else
|
||||
line6_pcm_stop(line6pcm, MASK_PCM_IMPULSE);
|
||||
@ -65,8 +63,7 @@ static ssize_t pcm_set_impulse_volume(struct device *dev,
|
||||
"read" request on "impulse_period" special file.
|
||||
*/
|
||||
static ssize_t pcm_get_impulse_period(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", dev2pcm(dev)->impulse_period);
|
||||
}
|
||||
@ -82,87 +79,100 @@ static ssize_t pcm_set_impulse_period(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume, pcm_set_impulse_volume);
|
||||
static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period, pcm_set_impulse_period);
|
||||
static DEVICE_ATTR(impulse_volume, S_IWUGO | S_IRUGO, pcm_get_impulse_volume,
|
||||
pcm_set_impulse_volume);
|
||||
static DEVICE_ATTR(impulse_period, S_IWUGO | S_IRUGO, pcm_get_impulse_period,
|
||||
pcm_set_impulse_period);
|
||||
|
||||
#endif
|
||||
|
||||
int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels)
|
||||
{
|
||||
unsigned long flags_old = __sync_fetch_and_or(&line6pcm->flags, channels);
|
||||
unsigned long flags_old =
|
||||
__sync_fetch_and_or(&line6pcm->flags, channels);
|
||||
unsigned long flags_new = flags_old | channels;
|
||||
int err = 0;
|
||||
|
||||
#if LINE6_BACKUP_MONITOR_SIGNAL
|
||||
if (!(line6pcm->line6->properties->capabilities & LINE6_BIT_HWMON)) {
|
||||
line6pcm->prev_fbuf = kmalloc(LINE6_ISO_PACKETS * line6pcm->max_packet_size, GFP_KERNEL);
|
||||
line6pcm->prev_fbuf =
|
||||
kmalloc(LINE6_ISO_PACKETS * line6pcm->max_packet_size,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!line6pcm->prev_fbuf) {
|
||||
dev_err(line6pcm->line6->ifcdev, "cannot malloc monitor buffer\n");
|
||||
dev_err(line6pcm->line6->ifcdev,
|
||||
"cannot malloc monitor buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
#else
|
||||
line6pcm->prev_fbuf = NULL;
|
||||
#endif
|
||||
|
||||
|
||||
if (((flags_old & MASK_CAPTURE) == 0) &&
|
||||
((flags_new & MASK_CAPTURE) != 0)) {
|
||||
/*
|
||||
Waiting for completion of active URBs in the stop handler is
|
||||
a bug, we therefore report an error if capturing is restarted
|
||||
too soon.
|
||||
*/
|
||||
if(line6pcm->active_urb_in | line6pcm->unlink_urb_in)
|
||||
Waiting for completion of active URBs in the stop handler is
|
||||
a bug, we therefore report an error if capturing is restarted
|
||||
too soon.
|
||||
*/
|
||||
if (line6pcm->active_urb_in | line6pcm->unlink_urb_in)
|
||||
return -EBUSY;
|
||||
|
||||
line6pcm->buffer_in = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * line6pcm->max_packet_size, GFP_KERNEL);
|
||||
line6pcm->buffer_in =
|
||||
kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
|
||||
line6pcm->max_packet_size, GFP_KERNEL);
|
||||
|
||||
if (!line6pcm->buffer_in) {
|
||||
dev_err(line6pcm->line6->ifcdev, "cannot malloc capture buffer\n");
|
||||
dev_err(line6pcm->line6->ifcdev,
|
||||
"cannot malloc capture buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
line6pcm->count_in = 0;
|
||||
line6pcm->prev_fsize = 0;
|
||||
err = line6_submit_audio_in_all_urbs(line6pcm);
|
||||
|
||||
|
||||
if (err < 0) {
|
||||
__sync_fetch_and_and(&line6pcm->flags, ~channels);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (((flags_old & MASK_PLAYBACK) == 0) &&
|
||||
((flags_new & MASK_PLAYBACK) != 0)) {
|
||||
/*
|
||||
See comment above regarding PCM restart.
|
||||
*/
|
||||
if(line6pcm->active_urb_out | line6pcm->unlink_urb_out)
|
||||
See comment above regarding PCM restart.
|
||||
*/
|
||||
if (line6pcm->active_urb_out | line6pcm->unlink_urb_out)
|
||||
return -EBUSY;
|
||||
|
||||
line6pcm->buffer_out = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * line6pcm->max_packet_size, GFP_KERNEL);
|
||||
line6pcm->buffer_out =
|
||||
kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
|
||||
line6pcm->max_packet_size, GFP_KERNEL);
|
||||
|
||||
if (!line6pcm->buffer_out) {
|
||||
dev_err(line6pcm->line6->ifcdev, "cannot malloc playback buffer\n");
|
||||
dev_err(line6pcm->line6->ifcdev,
|
||||
"cannot malloc playback buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
line6pcm->count_out = 0;
|
||||
err = line6_submit_audio_out_all_urbs(line6pcm);
|
||||
|
||||
|
||||
if (err < 0) {
|
||||
__sync_fetch_and_and(&line6pcm->flags, ~channels);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels)
|
||||
{
|
||||
unsigned long flags_old = __sync_fetch_and_and(&line6pcm->flags, ~channels);
|
||||
unsigned long flags_old =
|
||||
__sync_fetch_and_and(&line6pcm->flags, ~channels);
|
||||
unsigned long flags_new = flags_old & ~channels;
|
||||
|
||||
if (((flags_old & MASK_CAPTURE) != 0) &&
|
||||
@ -178,7 +188,6 @@ int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels)
|
||||
kfree(line6pcm->buffer_out);
|
||||
line6pcm->buffer_out = NULL;
|
||||
}
|
||||
|
||||
#if LINE6_BACKUP_MONITOR_SIGNAL
|
||||
if (line6pcm->prev_fbuf != NULL)
|
||||
kfree(line6pcm->prev_fbuf);
|
||||
@ -223,8 +232,8 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(line6pcm->line6->ifcdev, "Unknown stream direction %d\n",
|
||||
s->stream);
|
||||
dev_err(line6pcm->line6->ifcdev,
|
||||
"Unknown stream direction %d\n", s->stream);
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,8 +273,10 @@ static int snd_line6_control_playback_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
for (i = 2; i--;)
|
||||
if (line6pcm->volume_playback[i] != ucontrol->value.integer.value[i]) {
|
||||
line6pcm->volume_playback[i] = ucontrol->value.integer.value[i];
|
||||
if (line6pcm->volume_playback[i] !=
|
||||
ucontrol->value.integer.value[i]) {
|
||||
line6pcm->volume_playback[i] =
|
||||
ucontrol->value.integer.value[i];
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
@ -315,8 +326,8 @@ static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
|
||||
int err;
|
||||
|
||||
err = snd_pcm_new(line6pcm->line6->card,
|
||||
(char *)line6pcm->line6->properties->name,
|
||||
0, 1, 1, &pcm);
|
||||
(char *)line6pcm->line6->properties->name,
|
||||
0, 1, 1, &pcm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -328,13 +339,13 @@ static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
|
||||
/* set operators */
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||||
&snd_line6_playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
|
||||
&snd_line6_capture_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
|
||||
|
||||
/* pre-allocation of buffers */
|
||||
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
|
||||
snd_dma_continuous_data(GFP_KERNEL),
|
||||
64 * 1024, 128 * 1024);
|
||||
snd_dma_continuous_data
|
||||
(GFP_KERNEL), 64 * 1024,
|
||||
128 * 1024);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -350,7 +361,7 @@ static int snd_line6_pcm_free(struct snd_device *device)
|
||||
*/
|
||||
static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
|
||||
{
|
||||
if(substream->runtime && snd_pcm_running(substream)) {
|
||||
if (substream->runtime && snd_pcm_running(substream)) {
|
||||
snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
@ -360,8 +371,10 @@ static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
|
||||
*/
|
||||
void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
|
||||
{
|
||||
pcm_disconnect_substream(get_substream(line6pcm, SNDRV_PCM_STREAM_CAPTURE));
|
||||
pcm_disconnect_substream(get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK));
|
||||
pcm_disconnect_substream(get_substream
|
||||
(line6pcm, SNDRV_PCM_STREAM_CAPTURE));
|
||||
pcm_disconnect_substream(get_substream
|
||||
(line6pcm, SNDRV_PCM_STREAM_PLAYBACK));
|
||||
line6_unlink_wait_clear_audio_out_urbs(line6pcm);
|
||||
line6_unlink_wait_clear_audio_in_urbs(line6pcm);
|
||||
}
|
||||
@ -382,7 +395,7 @@ int line6_init_pcm(struct usb_line6 *line6,
|
||||
struct snd_line6_pcm *line6pcm;
|
||||
|
||||
if (!(line6->properties->capabilities & LINE6_BIT_PCM))
|
||||
return 0; /* skip PCM initialization and report success */
|
||||
return 0; /* skip PCM initialization and report success */
|
||||
|
||||
/* initialize PCM subsystem based on product id: */
|
||||
switch (line6->product) {
|
||||
@ -392,18 +405,18 @@ int line6_init_pcm(struct usb_line6 *line6,
|
||||
case LINE6_DEVID_PODXT:
|
||||
case LINE6_DEVID_PODXTLIVE:
|
||||
case LINE6_DEVID_PODXTPRO:
|
||||
ep_read = 0x82;
|
||||
ep_read = 0x82;
|
||||
ep_write = 0x01;
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_PODX3:
|
||||
case LINE6_DEVID_PODX3LIVE:
|
||||
ep_read = 0x86;
|
||||
ep_read = 0x86;
|
||||
ep_write = 0x02;
|
||||
break;
|
||||
|
||||
case LINE6_DEVID_POCKETPOD:
|
||||
ep_read = 0x82;
|
||||
ep_read = 0x82;
|
||||
ep_write = 0x02;
|
||||
break;
|
||||
|
||||
@ -414,17 +427,17 @@ int line6_init_pcm(struct usb_line6 *line6,
|
||||
case LINE6_DEVID_TONEPORT_GX:
|
||||
case LINE6_DEVID_TONEPORT_UX1:
|
||||
case LINE6_DEVID_TONEPORT_UX2:
|
||||
ep_read = 0x82;
|
||||
ep_read = 0x82;
|
||||
ep_write = 0x01;
|
||||
break;
|
||||
|
||||
/* this is for interface_number == 1:
|
||||
case LINE6_DEVID_TONEPORT_UX2:
|
||||
case LINE6_DEVID_PODSTUDIO_UX2:
|
||||
ep_read = 0x87;
|
||||
ep_write = 0x00;
|
||||
break;
|
||||
*/
|
||||
case LINE6_DEVID_TONEPORT_UX2:
|
||||
case LINE6_DEVID_PODSTUDIO_UX2:
|
||||
ep_read = 0x87;
|
||||
ep_write = 0x00;
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
MISSING_CASE;
|
||||
@ -442,8 +455,7 @@ int line6_init_pcm(struct usb_line6 *line6,
|
||||
line6pcm->ep_audio_write = ep_write;
|
||||
line6pcm->max_packet_size = usb_maxpacket(line6->usbdev,
|
||||
usb_rcvintpipe(line6->usbdev,
|
||||
ep_read),
|
||||
0);
|
||||
ep_read), 0);
|
||||
line6pcm->properties = properties;
|
||||
line6->line6pcm = line6pcm;
|
||||
|
||||
@ -471,7 +483,9 @@ int line6_init_pcm(struct usb_line6 *line6,
|
||||
return err;
|
||||
|
||||
/* mixer: */
|
||||
err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control_playback, line6pcm));
|
||||
err =
|
||||
snd_ctl_add(line6->card,
|
||||
snd_ctl_new1(&line6_control_playback, line6pcm));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -16,13 +16,11 @@
|
||||
#ifndef PCM_H
|
||||
#define PCM_H
|
||||
|
||||
|
||||
#include <sound/pcm.h>
|
||||
|
||||
#include "driver.h"
|
||||
#include "usbdefs.h"
|
||||
|
||||
|
||||
/* number of URBs */
|
||||
#define LINE6_ISO_BUFFERS 2
|
||||
|
||||
@ -44,13 +42,11 @@
|
||||
#define LINE6_BACKUP_MONITOR_SIGNAL 0
|
||||
#define LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 0
|
||||
|
||||
|
||||
/*
|
||||
Get substream from Line6 PCM data structure
|
||||
*/
|
||||
#define get_substream(line6pcm, stream) (line6pcm->pcm->streams[stream].substream)
|
||||
|
||||
|
||||
/*
|
||||
PCM mode bits and masks.
|
||||
"ALSA": operations triggered by applications via ALSA
|
||||
@ -71,6 +67,7 @@ enum {
|
||||
BIT_PREPARED,
|
||||
|
||||
/* individual masks: */
|
||||
/* *INDENT-OFF* */
|
||||
MASK_PCM_ALSA_PLAYBACK = 1 << BIT_PCM_ALSA_PLAYBACK,
|
||||
MASK_PCM_ALSA_CAPTURE = 1 << BIT_PCM_ALSA_CAPTURE,
|
||||
MASK_PCM_MONITOR_PLAYBACK = 1 << BIT_PCM_MONITOR_PLAYBACK,
|
||||
@ -81,9 +78,10 @@ enum {
|
||||
#endif
|
||||
MASK_PAUSE_PLAYBACK = 1 << BIT_PAUSE_PLAYBACK,
|
||||
MASK_PREPARED = 1 << BIT_PREPARED,
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* combined masks (by operation): */
|
||||
MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE,
|
||||
MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE,
|
||||
MASK_PCM_MONITOR = MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_MONITOR_CAPTURE,
|
||||
#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
|
||||
MASK_PCM_IMPULSE = MASK_PCM_IMPULSE_PLAYBACK | MASK_PCM_IMPULSE_CAPTURE,
|
||||
@ -91,11 +89,15 @@ enum {
|
||||
|
||||
/* combined masks (by direction): */
|
||||
#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
|
||||
MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_IMPULSE_PLAYBACK,
|
||||
MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE | MASK_PCM_IMPULSE_CAPTURE
|
||||
MASK_PLAYBACK =
|
||||
MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK |
|
||||
MASK_PCM_IMPULSE_PLAYBACK,
|
||||
MASK_CAPTURE =
|
||||
MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE |
|
||||
MASK_PCM_IMPULSE_CAPTURE
|
||||
#else
|
||||
MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK,
|
||||
MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE
|
||||
MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -302,7 +304,6 @@ struct snd_line6_pcm {
|
||||
int last_frame_in, last_frame_out;
|
||||
};
|
||||
|
||||
|
||||
extern int line6_init_pcm(struct usb_line6 *line6,
|
||||
struct line6_pcm_properties *properties);
|
||||
extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
|
||||
@ -311,7 +312,6 @@ extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
|
||||
extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels);
|
||||
extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels);
|
||||
|
||||
|
||||
#define PRINT_FRAME_DIFF(op) { \
|
||||
static int diff_prev = 1000; \
|
||||
int diff = line6pcm->last_frame_out - line6pcm->last_frame_in; \
|
||||
@ -321,5 +321,4 @@ extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels);
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -68,7 +68,16 @@ static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm,
|
||||
int frames = urb_out->transfer_buffer_length / bytes_per_frame;
|
||||
|
||||
if (bytes_per_frame == 4) {
|
||||
/* TODO: add code for TonePort etc. */
|
||||
int i;
|
||||
short *pi = (short *)line6pcm->prev_fbuf;
|
||||
short *po = (short *)urb_out->transfer_buffer;
|
||||
|
||||
for (i = 0; i < frames; ++i) {
|
||||
po[0] = pi[0];
|
||||
po[1] = 0;
|
||||
pi += 2;
|
||||
po += 2;
|
||||
}
|
||||
} else if (bytes_per_frame == 6) {
|
||||
int i, j;
|
||||
unsigned char *pi = line6pcm->prev_fbuf;
|
||||
@ -84,14 +93,12 @@ static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm,
|
||||
pi += bytes_per_frame;
|
||||
po += bytes_per_frame;
|
||||
}
|
||||
|
||||
if (--line6pcm->impulse_count <= 0) {
|
||||
((unsigned char *)(urb_out->
|
||||
transfer_buffer))[bytes_per_frame -
|
||||
1] =
|
||||
line6pcm->impulse_volume;
|
||||
line6pcm->impulse_count = line6pcm->impulse_period;
|
||||
}
|
||||
}
|
||||
if (--line6pcm->impulse_count <= 0) {
|
||||
((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame -
|
||||
1] =
|
||||
line6pcm->impulse_volume;
|
||||
line6pcm->impulse_count = line6pcm->impulse_period;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,9 +124,9 @@ static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
|
||||
}
|
||||
|
||||
/*
|
||||
We don't need to handle devices with 6 bytes per frame here
|
||||
since they all support hardware monitoring.
|
||||
*/
|
||||
We don't need to handle devices with 6 bytes per frame here
|
||||
since they all support hardware monitoring.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@ -130,6 +137,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
|
||||
int index;
|
||||
unsigned long flags;
|
||||
int i, urb_size, urb_frames;
|
||||
int ret;
|
||||
const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
|
||||
const int frame_increment =
|
||||
line6pcm->properties->snd_line6_rates.rats[0].num_min;
|
||||
@ -244,16 +252,20 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
|
||||
create_impulse_test_signal(line6pcm, urb_out,
|
||||
bytes_per_frame);
|
||||
if (line6pcm->flags & MASK_PCM_ALSA_CAPTURE) {
|
||||
line6_capture_copy(line6pcm, urb_out->transfer_buffer,
|
||||
urb_out->transfer_buffer_length);
|
||||
line6_capture_copy(line6pcm,
|
||||
urb_out->transfer_buffer,
|
||||
urb_out->
|
||||
transfer_buffer_length);
|
||||
line6_capture_check_period(line6pcm,
|
||||
urb_out->transfer_buffer_length);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
if (!
|
||||
(line6pcm->line6->properties->
|
||||
capabilities & LINE6_BIT_HWMON)
|
||||
&& (line6pcm->flags & MASK_PLAYBACK)
|
||||
&& (line6pcm->flags & MASK_CAPTURE))
|
||||
(line6pcm->line6->
|
||||
properties->capabilities & LINE6_BIT_HWMON)
|
||||
&& (line6pcm->flags & MASK_PLAYBACK)
|
||||
&& (line6pcm->flags & MASK_CAPTURE))
|
||||
add_monitor_signal(urb_out, line6pcm->prev_fbuf,
|
||||
line6pcm->volume_monitor,
|
||||
bytes_per_frame);
|
||||
@ -271,11 +283,13 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (usb_submit_urb(urb_out, GFP_ATOMIC) == 0)
|
||||
ret = usb_submit_urb(urb_out, GFP_ATOMIC);
|
||||
|
||||
if (ret == 0)
|
||||
set_bit(index, &line6pcm->active_urb_out);
|
||||
else
|
||||
dev_err(line6pcm->line6->ifcdev,
|
||||
"URB out #%d submission failed\n", index);
|
||||
"URB out #%d submission failed (%d)\n", index, ret);
|
||||
|
||||
spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
|
||||
return 0;
|
||||
@ -355,8 +369,7 @@ static void audio_out_callback(struct urb *urb)
|
||||
int i, index, length = 0, shutdown = 0;
|
||||
unsigned long flags;
|
||||
|
||||
struct snd_line6_pcm *line6pcm =
|
||||
(struct snd_line6_pcm *)urb->context;
|
||||
struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
|
||||
struct snd_pcm_substream *substream =
|
||||
get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
|
||||
@ -391,7 +404,7 @@ static void audio_out_callback(struct urb *urb)
|
||||
clear_bit(index, &line6pcm->active_urb_out);
|
||||
|
||||
for (i = LINE6_ISO_PACKETS; i--;)
|
||||
if (urb->iso_frame_desc[i].status == -ESHUTDOWN) {
|
||||
if (urb->iso_frame_desc[i].status == -EXDEV) {
|
||||
shutdown = 1;
|
||||
break;
|
||||
}
|
||||
@ -422,8 +435,8 @@ static int snd_line6_playback_open(struct snd_pcm_substream *substream)
|
||||
struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
|
||||
|
||||
err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
|
||||
(&line6pcm->properties->
|
||||
snd_line6_rates));
|
||||
(&line6pcm->
|
||||
properties->snd_line6_rates));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -524,14 +537,14 @@ snd_line6_playback_pointer(struct snd_pcm_substream *substream)
|
||||
|
||||
/* playback operators */
|
||||
struct snd_pcm_ops snd_line6_playback_ops = {
|
||||
.open = snd_line6_playback_open,
|
||||
.close = snd_line6_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_line6_playback_hw_params,
|
||||
.hw_free = snd_line6_playback_hw_free,
|
||||
.prepare = snd_line6_prepare,
|
||||
.trigger = snd_line6_trigger,
|
||||
.pointer = snd_line6_playback_pointer,
|
||||
.open = snd_line6_playback_open,
|
||||
.close = snd_line6_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
.hw_params = snd_line6_playback_hw_params,
|
||||
.hw_free = snd_line6_playback_hw_free,
|
||||
.prepare = snd_line6_prepare,
|
||||
.trigger = snd_line6_trigger,
|
||||
.pointer = snd_line6_playback_pointer,
|
||||
};
|
||||
|
||||
int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
|
||||
@ -554,8 +567,8 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
|
||||
urb->dev = line6pcm->line6->usbdev;
|
||||
urb->pipe =
|
||||
usb_sndisocpipe(line6pcm->line6->usbdev,
|
||||
line6pcm->
|
||||
ep_audio_write & USB_ENDPOINT_NUMBER_MASK);
|
||||
line6pcm->ep_audio_write &
|
||||
USB_ENDPOINT_NUMBER_MASK);
|
||||
urb->transfer_flags = URB_ISO_ASAP;
|
||||
urb->start_frame = -1;
|
||||
urb->number_of_packets = LINE6_ISO_PACKETS;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,12 +12,10 @@
|
||||
#ifndef PLAYBACK_H
|
||||
#define PLAYBACK_H
|
||||
|
||||
|
||||
#include <sound/pcm.h>
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
|
||||
/*
|
||||
When the TonePort is used with jack in full duplex mode and the outputs are
|
||||
not connected, the software monitor produces an ugly noise since everything
|
||||
@ -28,7 +26,6 @@
|
||||
*/
|
||||
#define USE_CLEAR_BUFFER_WORKAROUND 1
|
||||
|
||||
|
||||
extern struct snd_pcm_ops snd_line6_playback_ops;
|
||||
|
||||
extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -20,10 +20,10 @@
|
||||
#include "playback.h"
|
||||
#include "pod.h"
|
||||
|
||||
|
||||
#define POD_SYSEX_CODE 3
|
||||
#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
|
||||
#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
enum {
|
||||
POD_SYSEX_CLIP = 0x0f,
|
||||
@ -49,6 +49,8 @@ enum {
|
||||
POD_system_invalid = 0x10000
|
||||
};
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
enum {
|
||||
POD_DUMP_MEMORY = 2
|
||||
};
|
||||
@ -61,7 +63,6 @@ enum {
|
||||
POD_BUSY_MIDISEND
|
||||
};
|
||||
|
||||
|
||||
static struct snd_ratden pod_ratden = {
|
||||
.num_min = 78125,
|
||||
.num_max = 78125,
|
||||
@ -71,52 +72,49 @@ static struct snd_ratden pod_ratden = {
|
||||
|
||||
static struct line6_pcm_properties pod_pcm_properties = {
|
||||
.snd_line6_playback_hw = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
#ifdef CONFIG_PM
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
#endif
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = 39062,
|
||||
.rate_max = 39063,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.buffer_bytes_max = 60000,
|
||||
.period_bytes_min = 64,
|
||||
.period_bytes_max = 8192,
|
||||
.periods_min = 1,
|
||||
.periods_max = 1024
|
||||
},
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = 39062,
|
||||
.rate_max = 39063,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.buffer_bytes_max = 60000,
|
||||
.period_bytes_min = 64,
|
||||
.period_bytes_max = 8192,
|
||||
.periods_min = 1,
|
||||
.periods_max = 1024},
|
||||
.snd_line6_capture_hw = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
#ifdef CONFIG_PM
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
#endif
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = 39062,
|
||||
.rate_max = 39063,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.buffer_bytes_max = 60000,
|
||||
.period_bytes_min = 64,
|
||||
.period_bytes_max = 8192,
|
||||
.periods_min = 1,
|
||||
.periods_max = 1024
|
||||
},
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = 39062,
|
||||
.rate_max = 39063,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.buffer_bytes_max = 60000,
|
||||
.period_bytes_min = 64,
|
||||
.period_bytes_max = 8192,
|
||||
.periods_min = 1,
|
||||
.periods_max = 1024},
|
||||
.snd_line6_rates = {
|
||||
.nrats = 1,
|
||||
.rats = &pod_ratden
|
||||
},
|
||||
.nrats = 1,
|
||||
.rats = &pod_ratden},
|
||||
.bytes_per_frame = POD_BYTES_PER_FRAME
|
||||
};
|
||||
|
||||
@ -124,17 +122,15 @@ static const char pod_request_channel[] = {
|
||||
0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7
|
||||
};
|
||||
|
||||
static const char pod_version_header[] = {
|
||||
static const char pod_version_header[] = {
|
||||
0xf2, 0x7e, 0x7f, 0x06, 0x02
|
||||
};
|
||||
|
||||
|
||||
/* forward declarations: */
|
||||
static void pod_startup2(unsigned long data);
|
||||
static void pod_startup3(struct usb_line6_pod *pod);
|
||||
static void pod_startup4(struct usb_line6_pod *pod);
|
||||
|
||||
|
||||
/*
|
||||
Mark all parameters as dirty and notify waiting processes.
|
||||
*/
|
||||
@ -146,9 +142,11 @@ static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
|
||||
set_bit(i, pod->param_dirty);
|
||||
}
|
||||
|
||||
static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size)
|
||||
static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
|
||||
int size)
|
||||
{
|
||||
return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, size);
|
||||
return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code,
|
||||
size);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -183,7 +181,8 @@ static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
|
||||
/*
|
||||
Handle SAVE button.
|
||||
*/
|
||||
static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int index)
|
||||
static void pod_save_button_pressed(struct usb_line6_pod *pod, int type,
|
||||
int index)
|
||||
{
|
||||
pod->dirty = 0;
|
||||
set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
|
||||
@ -201,10 +200,10 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
|
||||
case LINE6_PARAM_CHANGE:
|
||||
case LINE6_PROGRAM_CHANGE:
|
||||
case LINE6_SYSEX_BEGIN:
|
||||
break; /* handle these further down */
|
||||
break; /* handle these further down */
|
||||
|
||||
default:
|
||||
return; /* ignore all others */
|
||||
return; /* ignore all others */
|
||||
}
|
||||
|
||||
/* process all remaining messages */
|
||||
@ -217,7 +216,8 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
|
||||
if ((buf[1] == POD_amp_model_setup) ||
|
||||
(buf[1] == POD_effect_setup))
|
||||
/* these also affect other settings */
|
||||
line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, LINE6_DUMP_CURRENT);
|
||||
line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
|
||||
LINE6_DUMP_CURRENT);
|
||||
|
||||
break;
|
||||
|
||||
@ -226,7 +226,8 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
|
||||
pod->channel_num = buf[1];
|
||||
pod->dirty = 0;
|
||||
set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
|
||||
line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, LINE6_DUMP_CURRENT);
|
||||
line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
|
||||
LINE6_DUMP_CURRENT);
|
||||
break;
|
||||
|
||||
case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
|
||||
@ -234,31 +235,50 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
|
||||
if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
|
||||
switch (buf[5]) {
|
||||
case POD_SYSEX_DUMP:
|
||||
if (pod->line6.message_length == sizeof(pod->prog_data) + 7) {
|
||||
if (pod->line6.message_length ==
|
||||
sizeof(pod->prog_data) + 7) {
|
||||
switch (pod->dumpreq.in_progress) {
|
||||
case LINE6_DUMP_CURRENT:
|
||||
memcpy(&pod->prog_data, buf + 7, sizeof(pod->prog_data));
|
||||
memcpy(&pod->prog_data, buf + 7,
|
||||
sizeof(pod->prog_data));
|
||||
pod_mark_batch_all_dirty(pod);
|
||||
break;
|
||||
|
||||
case POD_DUMP_MEMORY:
|
||||
memcpy(&pod->prog_data_buf, buf + 7, sizeof(pod->prog_data_buf));
|
||||
memcpy(&pod->prog_data_buf,
|
||||
buf + 7,
|
||||
sizeof
|
||||
(pod->prog_data_buf));
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown dump code %02X\n", pod->dumpreq.in_progress));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(pod->
|
||||
line6.ifcdev,
|
||||
"unknown dump code %02X\n",
|
||||
pod->
|
||||
dumpreq.in_progress));
|
||||
}
|
||||
|
||||
line6_dump_finished(&pod->dumpreq);
|
||||
pod_startup3(pod);
|
||||
} else
|
||||
DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "wrong size of channel dump message (%d instead of %d)\n",
|
||||
pod->line6.message_length, (int)sizeof(pod->prog_data) + 7));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(pod->line6.ifcdev,
|
||||
"wrong size of channel dump message (%d instead of %d)\n",
|
||||
pod->
|
||||
line6.message_length,
|
||||
(int)
|
||||
sizeof(pod->prog_data) +
|
||||
7));
|
||||
|
||||
break;
|
||||
|
||||
case POD_SYSEX_SYSTEM: {
|
||||
short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | ((int)buf[9] << 4) | (int)buf[10];
|
||||
case POD_SYSEX_SYSTEM:{
|
||||
short value =
|
||||
((int)buf[7] << 12) | ((int)buf[8]
|
||||
<< 8) |
|
||||
((int)buf[9] << 4) | (int)buf[10];
|
||||
|
||||
#define PROCESS_SYSTEM_PARAM(x) \
|
||||
case POD_ ## x: \
|
||||
@ -266,22 +286,31 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
|
||||
wake_up(&pod->x.wait); \
|
||||
break;
|
||||
|
||||
switch (buf[6]) {
|
||||
PROCESS_SYSTEM_PARAM(monitor_level);
|
||||
PROCESS_SYSTEM_PARAM(routing);
|
||||
PROCESS_SYSTEM_PARAM(tuner_mute);
|
||||
PROCESS_SYSTEM_PARAM(tuner_freq);
|
||||
PROCESS_SYSTEM_PARAM(tuner_note);
|
||||
PROCESS_SYSTEM_PARAM(tuner_pitch);
|
||||
switch (buf[6]) {
|
||||
PROCESS_SYSTEM_PARAM
|
||||
(monitor_level);
|
||||
PROCESS_SYSTEM_PARAM(routing);
|
||||
PROCESS_SYSTEM_PARAM
|
||||
(tuner_mute);
|
||||
PROCESS_SYSTEM_PARAM
|
||||
(tuner_freq);
|
||||
PROCESS_SYSTEM_PARAM
|
||||
(tuner_note);
|
||||
PROCESS_SYSTEM_PARAM
|
||||
(tuner_pitch);
|
||||
|
||||
#undef PROCESS_SYSTEM_PARAM
|
||||
|
||||
default:
|
||||
DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown tuner/system response %02X\n", buf[6]));
|
||||
}
|
||||
default:
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(pod->
|
||||
line6.ifcdev,
|
||||
"unknown tuner/system response %02X\n",
|
||||
buf[6]));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case POD_SYSEX_FINISH:
|
||||
/* do we need to respond to this? */
|
||||
@ -292,24 +321,40 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
|
||||
break;
|
||||
|
||||
case POD_SYSEX_CLIP:
|
||||
DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "audio clipped\n"));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(pod->line6.ifcdev,
|
||||
"audio clipped\n"));
|
||||
pod->clipping.value = 1;
|
||||
wake_up(&pod->clipping.wait);
|
||||
break;
|
||||
|
||||
case POD_SYSEX_STORE:
|
||||
DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "message %02X not yet implemented\n", buf[5]));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(pod->line6.ifcdev,
|
||||
"message %02X not yet implemented\n",
|
||||
buf[5]));
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex message %02X\n", buf[5]));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(pod->line6.ifcdev,
|
||||
"unknown sysex message %02X\n",
|
||||
buf[5]));
|
||||
}
|
||||
} else if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
|
||||
pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
|
||||
pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10];
|
||||
} else
|
||||
if (memcmp
|
||||
(buf, pod_version_header,
|
||||
sizeof(pod_version_header)) == 0) {
|
||||
pod->firmware_version =
|
||||
buf[13] * 100 + buf[14] * 10 + buf[15];
|
||||
pod->device_id =
|
||||
((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)
|
||||
buf[10];
|
||||
pod_startup4(pod);
|
||||
} else
|
||||
DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex header\n"));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(pod->line6.ifcdev,
|
||||
"unknown sysex header\n"));
|
||||
|
||||
break;
|
||||
|
||||
@ -317,7 +362,9 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "POD: unknown message %02X\n", buf[0]));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(pod->line6.ifcdev,
|
||||
"POD: unknown message %02X\n", buf[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,7 +379,8 @@ void line6_pod_process_message(struct usb_line6_pod *pod)
|
||||
*) This method fails if a param change message is "chopped" after the first
|
||||
byte.
|
||||
*/
|
||||
void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length)
|
||||
void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data,
|
||||
int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -343,8 +391,11 @@ void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data,
|
||||
if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
|
||||
line6_invalidate_current(&pod->dumpreq);
|
||||
break;
|
||||
} else if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST)) && (i < length - 1))
|
||||
if ((data[i + 1] == POD_amp_model_setup) || (data[i + 1] == POD_effect_setup)) {
|
||||
} else
|
||||
if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST))
|
||||
&& (i < length - 1))
|
||||
if ((data[i + 1] == POD_amp_model_setup)
|
||||
|| (data[i + 1] == POD_effect_setup)) {
|
||||
line6_invalidate_current(&pod->dumpreq);
|
||||
break;
|
||||
}
|
||||
@ -367,19 +418,21 @@ static void pod_send_channel(struct usb_line6_pod *pod, int value)
|
||||
/*
|
||||
Transmit PODxt Pro control parameter.
|
||||
*/
|
||||
void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value)
|
||||
void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
|
||||
int value)
|
||||
{
|
||||
if (line6_transmit_parameter(&pod->line6, param, value) == 0)
|
||||
pod_store_parameter(pod, param, value);
|
||||
|
||||
if ((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
|
||||
if ((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
|
||||
line6_invalidate_current(&pod->dumpreq);
|
||||
}
|
||||
|
||||
/*
|
||||
Resolve value to memory location.
|
||||
*/
|
||||
static int pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
|
||||
static int pod_resolve(const char *buf, short block0, short block1,
|
||||
unsigned char *location)
|
||||
{
|
||||
unsigned long value;
|
||||
short block;
|
||||
@ -399,7 +452,8 @@ static int pod_resolve(const char *buf, short block0, short block1, unsigned cha
|
||||
/*
|
||||
Send command to store channel/effects setup/amp setup to PODxt Pro.
|
||||
*/
|
||||
static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
|
||||
static ssize_t pod_send_store_command(struct device *dev, const char *buf,
|
||||
size_t count, short block0, short block1)
|
||||
{
|
||||
struct usb_interface *interface = to_usb_interface(dev);
|
||||
struct usb_line6_pod *pod = usb_get_intfdata(interface);
|
||||
@ -410,14 +464,15 @@ static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_
|
||||
if (!sysex)
|
||||
return 0;
|
||||
|
||||
sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
|
||||
sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
|
||||
ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
|
||||
if (ret) {
|
||||
kfree(sysex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
|
||||
memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf,
|
||||
sizeof(pod->prog_data_buf));
|
||||
|
||||
line6_send_sysex_message(&pod->line6, sysex, size);
|
||||
kfree(sysex);
|
||||
@ -428,7 +483,9 @@ static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_
|
||||
/*
|
||||
Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
|
||||
*/
|
||||
static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
|
||||
static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf,
|
||||
size_t count, short block0,
|
||||
short block1)
|
||||
{
|
||||
struct usb_interface *interface = to_usb_interface(dev);
|
||||
struct usb_line6_pod *pod = usb_get_intfdata(interface);
|
||||
@ -459,7 +516,8 @@ static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, si
|
||||
/*
|
||||
Generic get name function.
|
||||
*/
|
||||
static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str, char *buf)
|
||||
static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str,
|
||||
char *buf)
|
||||
{
|
||||
int length = 0;
|
||||
const char *p1;
|
||||
@ -521,7 +579,8 @@ static ssize_t pod_get_name(struct device *dev, struct device_attribute *attr,
|
||||
{
|
||||
struct usb_interface *interface = to_usb_interface(dev);
|
||||
struct usb_line6_pod *pod = usb_get_intfdata(interface);
|
||||
return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET, buf);
|
||||
return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET,
|
||||
buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -532,7 +591,9 @@ static ssize_t pod_get_name_buf(struct device *dev,
|
||||
{
|
||||
struct usb_interface *interface = to_usb_interface(dev);
|
||||
struct usb_line6_pod *pod = usb_get_intfdata(interface);
|
||||
return get_name_generic(pod, pod->prog_data_buf.header + POD_NAME_OFFSET, buf);
|
||||
return get_name_generic(pod,
|
||||
pod->prog_data_buf.header + POD_NAME_OFFSET,
|
||||
buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -561,8 +622,8 @@ static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
if (count != sizeof(pod->prog_data)) {
|
||||
dev_err(pod->line6.ifcdev,
|
||||
"data block must be exactly %d bytes\n",
|
||||
(int)sizeof(pod->prog_data));
|
||||
"data block must be exactly %d bytes\n",
|
||||
(int)sizeof(pod->prog_data));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -576,24 +637,24 @@ static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
|
||||
static bool pod_is_tuner(int code)
|
||||
{
|
||||
return
|
||||
(code == POD_tuner_mute) ||
|
||||
(code == POD_tuner_freq) ||
|
||||
(code == POD_tuner_note) ||
|
||||
(code == POD_tuner_pitch);
|
||||
(code == POD_tuner_mute) ||
|
||||
(code == POD_tuner_freq) ||
|
||||
(code == POD_tuner_note) || (code == POD_tuner_pitch);
|
||||
}
|
||||
|
||||
/*
|
||||
Get system parameter (as integer).
|
||||
@param tuner non-zero, if code refers to a tuner parameter
|
||||
*/
|
||||
static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value, int code,
|
||||
struct ValueWait *param, int sign)
|
||||
static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value,
|
||||
int code, struct ValueWait *param, int sign)
|
||||
{
|
||||
char *sysex;
|
||||
static const int size = 1;
|
||||
int retval = 0;
|
||||
|
||||
if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && pod_is_tuner(code))
|
||||
if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
|
||||
&& pod_is_tuner(code))
|
||||
return -ENODEV;
|
||||
|
||||
/* send value request to device: */
|
||||
@ -608,15 +669,18 @@ static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value, int c
|
||||
kfree(sysex);
|
||||
|
||||
/* wait for device to respond: */
|
||||
retval = wait_event_interruptible(param->wait, param->value != POD_system_invalid);
|
||||
retval =
|
||||
wait_event_interruptible(param->wait,
|
||||
param->value != POD_system_invalid);
|
||||
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
*value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value;
|
||||
*value = sign ? (int)(signed short)param->value : (int)(unsigned short)
|
||||
param->value;
|
||||
|
||||
if(*value == POD_system_invalid)
|
||||
*value = 0; /* don't report uninitialized values */
|
||||
if (*value == POD_system_invalid)
|
||||
*value = 0; /* don't report uninitialized values */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -625,13 +689,14 @@ static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value, int c
|
||||
Get system parameter (as string).
|
||||
@param tuner non-zero, if code refers to a tuner parameter
|
||||
*/
|
||||
static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf, int code,
|
||||
struct ValueWait *param, int sign)
|
||||
static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf,
|
||||
int code, struct ValueWait *param,
|
||||
int sign)
|
||||
{
|
||||
int retval, value = 0;
|
||||
retval = pod_get_system_param_int(pod, &value, code, param, sign);
|
||||
|
||||
if(retval < 0)
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
return sprintf(buf, "%d\n", value);
|
||||
@ -641,12 +706,14 @@ static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf,
|
||||
Send system parameter (from integer).
|
||||
@param tuner non-zero, if code refers to a tuner parameter
|
||||
*/
|
||||
static int pod_set_system_param_int(struct usb_line6_pod *pod, int value, int code)
|
||||
static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
|
||||
int code)
|
||||
{
|
||||
char *sysex;
|
||||
static const int size = 5;
|
||||
|
||||
if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && pod_is_tuner(code))
|
||||
if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
|
||||
&& pod_is_tuner(code))
|
||||
return -EINVAL;
|
||||
|
||||
/* send value to tuner: */
|
||||
@ -655,9 +722,9 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value, int co
|
||||
return -ENOMEM;
|
||||
sysex[SYSEX_DATA_OFS] = code;
|
||||
sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
|
||||
sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
|
||||
sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
|
||||
sysex[SYSEX_DATA_OFS + 4] = (value ) & 0x0f;
|
||||
sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
|
||||
sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
|
||||
sysex[SYSEX_DATA_OFS + 4] = (value) & 0x0f;
|
||||
line6_send_sysex_message(&pod->line6, sysex, size);
|
||||
kfree(sysex);
|
||||
return 0;
|
||||
@ -667,8 +734,9 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value, int co
|
||||
Send system parameter (from string).
|
||||
@param tuner non-zero, if code refers to a tuner parameter
|
||||
*/
|
||||
static ssize_t pod_set_system_param_string(struct usb_line6_pod *pod, const char *buf,
|
||||
int count, int code, unsigned short mask)
|
||||
static ssize_t pod_set_system_param_string(struct usb_line6_pod *pod,
|
||||
const char *buf, int count, int code,
|
||||
unsigned short mask)
|
||||
{
|
||||
int retval;
|
||||
unsigned short value = simple_strtoul(buf, NULL, 10) & mask;
|
||||
@ -878,7 +946,8 @@ static ssize_t pod_wait_for_clip(struct device *dev,
|
||||
{
|
||||
struct usb_interface *interface = to_usb_interface(dev);
|
||||
struct usb_line6_pod *pod = usb_get_intfdata(interface);
|
||||
return wait_event_interruptible(pod->clipping.wait, pod->clipping.value != 0);
|
||||
return wait_event_interruptible(pod->clipping.wait,
|
||||
pod->clipping.value != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -890,25 +959,34 @@ static ssize_t pod_wait_for_clip(struct device *dev,
|
||||
|
||||
static void pod_startup1(struct usb_line6_pod *pod)
|
||||
{
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, 1);
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_INIT);
|
||||
|
||||
/* delay startup procedure: */
|
||||
line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2, (unsigned long)pod);
|
||||
line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
|
||||
(unsigned long)pod);
|
||||
}
|
||||
|
||||
static void pod_startup2(unsigned long data)
|
||||
{
|
||||
struct usb_line6_pod *pod = (struct usb_line6_pod *)data;
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, 2);
|
||||
|
||||
/* schedule another startup procedure until startup is complete: */
|
||||
if (pod->startup_progress >= POD_STARTUP_LAST)
|
||||
return;
|
||||
|
||||
pod->startup_progress = POD_STARTUP_DUMPREQ;
|
||||
line6_start_timer(&pod->startup_timer, POD_STARTUP_DELAY, pod_startup2,
|
||||
(unsigned long)pod);
|
||||
|
||||
/* current channel dump: */
|
||||
line6_dump_request_async(&pod->dumpreq, &pod->line6, 0, LINE6_DUMP_CURRENT);
|
||||
line6_dump_request_async(&pod->dumpreq, &pod->line6, 0,
|
||||
LINE6_DUMP_CURRENT);
|
||||
}
|
||||
|
||||
static void pod_startup3(struct usb_line6_pod *pod)
|
||||
{
|
||||
struct usb_line6 *line6 = &pod->line6;
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, 3);
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_VERSIONREQ);
|
||||
|
||||
/* request firmware version: */
|
||||
line6_version_request_async(line6);
|
||||
@ -916,7 +994,7 @@ static void pod_startup3(struct usb_line6_pod *pod)
|
||||
|
||||
static void pod_startup4(struct usb_line6_pod *pod)
|
||||
{
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, 4);
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_WORKQUEUE);
|
||||
|
||||
/* schedule work for global work queue: */
|
||||
schedule_work(&pod->startup_work);
|
||||
@ -924,10 +1002,11 @@ static void pod_startup4(struct usb_line6_pod *pod)
|
||||
|
||||
static void pod_startup5(struct work_struct *work)
|
||||
{
|
||||
struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, startup_work);
|
||||
struct usb_line6_pod *pod =
|
||||
container_of(work, struct usb_line6_pod, startup_work);
|
||||
struct usb_line6 *line6 = &pod->line6;
|
||||
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, 5);
|
||||
CHECK_STARTUP_PROGRESS(pod->startup_progress, POD_STARTUP_SETUP);
|
||||
|
||||
/* serial number: */
|
||||
line6_read_serial_number(&pod->line6, &pod->serial_number);
|
||||
@ -936,7 +1015,8 @@ static void pod_startup5(struct work_struct *work)
|
||||
line6_register_audio(line6);
|
||||
|
||||
/* device files: */
|
||||
line6_pod_create_files(pod->firmware_version, line6->properties->device_bit, line6->ifcdev);
|
||||
line6_pod_create_files(pod->firmware_version,
|
||||
line6->properties->device_bit, line6->ifcdev);
|
||||
}
|
||||
|
||||
#define POD_GET_SYSTEM_PARAM(code, sign) \
|
||||
@ -971,28 +1051,43 @@ POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
|
||||
#undef GET_SYSTEM_PARAM
|
||||
|
||||
/* POD special files: */
|
||||
static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel);
|
||||
static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel,
|
||||
pod_set_channel);
|
||||
static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
|
||||
static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
|
||||
static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
|
||||
static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
|
||||
static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
|
||||
static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf,
|
||||
pod_set_dump_buf);
|
||||
static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
|
||||
static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
|
||||
static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
|
||||
static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
|
||||
static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
|
||||
line6_nop_write);
|
||||
static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO,
|
||||
pod_get_midi_postprocess, pod_set_midi_postprocess);
|
||||
static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level,
|
||||
pod_set_monitor_level);
|
||||
static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
|
||||
static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
|
||||
static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup);
|
||||
static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel);
|
||||
static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup);
|
||||
static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing);
|
||||
static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
|
||||
static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup);
|
||||
static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel);
|
||||
static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup);
|
||||
static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
|
||||
static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
|
||||
static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read,
|
||||
pod_set_retrieve_amp_setup);
|
||||
static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read,
|
||||
pod_set_retrieve_channel);
|
||||
static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read,
|
||||
pod_set_retrieve_effects_setup);
|
||||
static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing,
|
||||
pod_set_routing);
|
||||
static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
|
||||
line6_nop_write);
|
||||
static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read,
|
||||
pod_set_store_amp_setup);
|
||||
static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read,
|
||||
pod_set_store_channel);
|
||||
static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read,
|
||||
pod_set_store_effects_setup);
|
||||
static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq,
|
||||
pod_set_tuner_freq);
|
||||
static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute,
|
||||
pod_set_tuner_mute);
|
||||
static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
|
||||
static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
|
||||
|
||||
@ -1028,11 +1123,12 @@ static int snd_pod_control_monitor_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
|
||||
struct usb_line6_pod *pod = (struct usb_line6_pod *)line6pcm->line6;
|
||||
|
||||
if(ucontrol->value.integer.value[0] == pod->monitor_level.value)
|
||||
if (ucontrol->value.integer.value[0] == pod->monitor_level.value)
|
||||
return 0;
|
||||
|
||||
pod->monitor_level.value = ucontrol->value.integer.value[0];
|
||||
pod_set_system_param_int(pod, ucontrol->value.integer.value[0], POD_monitor_level);
|
||||
pod_set_system_param_int(pod, ucontrol->value.integer.value[0],
|
||||
POD_monitor_level);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1062,6 +1158,9 @@ static void pod_destruct(struct usb_interface *interface)
|
||||
return;
|
||||
line6_cleanup_audio(line6);
|
||||
|
||||
del_timer(&pod->startup_timer);
|
||||
cancel_work_sync(&pod->startup_work);
|
||||
|
||||
/* free dump request data: */
|
||||
line6_dumpreq_destruct(&pod->dumpreq);
|
||||
}
|
||||
@ -1108,11 +1207,15 @@ static int pod_create_files2(struct device *dev)
|
||||
/*
|
||||
Try to init POD device.
|
||||
*/
|
||||
static int pod_try_init(struct usb_interface *interface, struct usb_line6_pod *pod)
|
||||
static int pod_try_init(struct usb_interface *interface,
|
||||
struct usb_line6_pod *pod)
|
||||
{
|
||||
int err;
|
||||
struct usb_line6 *line6 = &pod->line6;
|
||||
|
||||
init_timer(&pod->startup_timer);
|
||||
INIT_WORK(&pod->startup_work, pod_startup5);
|
||||
|
||||
if ((interface == NULL) || (pod == NULL))
|
||||
return -ENODEV;
|
||||
|
||||
@ -1126,8 +1229,6 @@ static int pod_try_init(struct usb_interface *interface, struct usb_line6_pod *p
|
||||
init_waitqueue_head(&pod->tuner_note.wait);
|
||||
init_waitqueue_head(&pod->tuner_pitch.wait);
|
||||
init_waitqueue_head(&pod->clipping.wait);
|
||||
init_timer(&pod->startup_timer);
|
||||
INIT_WORK(&pod->startup_work, pod_startup5);
|
||||
|
||||
memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty));
|
||||
|
||||
@ -1164,16 +1265,18 @@ static int pod_try_init(struct usb_interface *interface, struct usb_line6_pod *p
|
||||
}
|
||||
|
||||
/* register monitor control: */
|
||||
err = snd_ctl_add(line6->card, snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
|
||||
err =
|
||||
snd_ctl_add(line6->card,
|
||||
snd_ctl_new1(&pod_control_monitor, line6->line6pcm));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
When the sound card is registered at this point, the PODxt Live
|
||||
displays "Invalid Code Error 07", so we do it later in the event
|
||||
handler.
|
||||
*/
|
||||
When the sound card is registered at this point, the PODxt Live
|
||||
displays "Invalid Code Error 07", so we do it later in the event
|
||||
handler.
|
||||
*/
|
||||
|
||||
if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
|
||||
pod->monitor_level.value = POD_system_invalid;
|
||||
@ -1220,7 +1323,9 @@ void line6_pod_disconnect(struct usb_interface *interface)
|
||||
|
||||
if (dev != NULL) {
|
||||
/* remove sysfs entries: */
|
||||
line6_pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev);
|
||||
line6_pod_remove_files(pod->firmware_version,
|
||||
pod->line6.
|
||||
properties->device_bit, dev);
|
||||
|
||||
device_remove_file(dev, &dev_attr_channel);
|
||||
device_remove_file(dev, &dev_attr_clip);
|
||||
@ -1236,7 +1341,8 @@ void line6_pod_disconnect(struct usb_interface *interface)
|
||||
device_remove_file(dev, &dev_attr_name_buf);
|
||||
device_remove_file(dev, &dev_attr_retrieve_amp_setup);
|
||||
device_remove_file(dev, &dev_attr_retrieve_channel);
|
||||
device_remove_file(dev, &dev_attr_retrieve_effects_setup);
|
||||
device_remove_file(dev,
|
||||
&dev_attr_retrieve_effects_setup);
|
||||
device_remove_file(dev, &dev_attr_routing);
|
||||
device_remove_file(dev, &dev_attr_serial_number);
|
||||
device_remove_file(dev, &dev_attr_store_amp_setup);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,7 +12,6 @@
|
||||
#ifndef POD_H
|
||||
#define POD_H
|
||||
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/usb.h>
|
||||
@ -23,7 +22,6 @@
|
||||
#include "driver.h"
|
||||
#include "dumprequest.h"
|
||||
|
||||
|
||||
/*
|
||||
PODxt Live interfaces
|
||||
*/
|
||||
@ -41,7 +39,19 @@
|
||||
*/
|
||||
#define POD_CONTROL_SIZE 0x80
|
||||
#define POD_BUFSIZE_DUMPREQ 7
|
||||
#define POD_STARTUP_DELAY 3000
|
||||
#define POD_STARTUP_DELAY 1000
|
||||
|
||||
/*
|
||||
Stages of POD startup procedure
|
||||
*/
|
||||
enum {
|
||||
POD_STARTUP_INIT = 1,
|
||||
POD_STARTUP_DUMPREQ,
|
||||
POD_STARTUP_VERSIONREQ,
|
||||
POD_STARTUP_WORKQUEUE,
|
||||
POD_STARTUP_SETUP,
|
||||
POD_STARTUP_LAST = POD_STARTUP_SETUP - 1
|
||||
};
|
||||
|
||||
/**
|
||||
Data structure for values that need to be requested explicitly.
|
||||
@ -183,14 +193,13 @@ struct usb_line6_pod {
|
||||
char midi_postprocess;
|
||||
};
|
||||
|
||||
|
||||
extern void line6_pod_disconnect(struct usb_interface *interface);
|
||||
extern int line6_pod_init(struct usb_interface *interface, struct usb_line6_pod *pod);
|
||||
extern int line6_pod_init(struct usb_interface *interface,
|
||||
struct usb_line6_pod *pod);
|
||||
extern void line6_pod_midi_postprocess(struct usb_line6_pod *pod,
|
||||
unsigned char *data, int length);
|
||||
extern void line6_pod_process_message(struct usb_line6_pod *pod);
|
||||
extern void line6_pod_transmit_parameter(struct usb_line6_pod *pod, int param,
|
||||
int value);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifndef DRIVER_REVISION
|
||||
/* current subversion revision */
|
||||
#define DRIVER_REVISION " (revision 665)"
|
||||
#define DRIVER_REVISION " (revision 684)"
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
* Emil Myhrman (emil.myhrman@gmail.com)
|
||||
@ -19,13 +19,10 @@
|
||||
#include "playback.h"
|
||||
#include "toneport.h"
|
||||
|
||||
|
||||
static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
|
||||
|
||||
|
||||
#define TONEPORT_PCM_DELAY 1
|
||||
|
||||
|
||||
static struct snd_ratden toneport_ratden = {
|
||||
.num_min = 44100,
|
||||
.num_max = 44100,
|
||||
@ -35,52 +32,49 @@ static struct snd_ratden toneport_ratden = {
|
||||
|
||||
static struct line6_pcm_properties toneport_pcm_properties = {
|
||||
.snd_line6_playback_hw = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_PAUSE |
|
||||
#ifdef CONFIG_PM
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
#endif
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = 44100,
|
||||
.rate_max = 44100,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.buffer_bytes_max = 60000,
|
||||
.period_bytes_min = 64,
|
||||
.period_bytes_max = 8192,
|
||||
.periods_min = 1,
|
||||
.periods_max = 1024
|
||||
},
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = 44100,
|
||||
.rate_max = 44100,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.buffer_bytes_max = 60000,
|
||||
.period_bytes_min = 64,
|
||||
.period_bytes_max = 8192,
|
||||
.periods_min = 1,
|
||||
.periods_max = 1024},
|
||||
.snd_line6_capture_hw = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
#ifdef CONFIG_PM
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
#endif
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = 44100,
|
||||
.rate_max = 44100,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.buffer_bytes_max = 60000,
|
||||
.period_bytes_min = 64,
|
||||
.period_bytes_max = 8192,
|
||||
.periods_min = 1,
|
||||
.periods_max = 1024
|
||||
},
|
||||
SNDRV_PCM_INFO_SYNC_START),
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.rate_min = 44100,
|
||||
.rate_max = 44100,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.buffer_bytes_max = 60000,
|
||||
.period_bytes_min = 64,
|
||||
.period_bytes_max = 8192,
|
||||
.periods_min = 1,
|
||||
.periods_max = 1024},
|
||||
.snd_line6_rates = {
|
||||
.nrats = 1,
|
||||
.rats = &toneport_ratden
|
||||
},
|
||||
.nrats = 1,
|
||||
.rats = &toneport_ratden},
|
||||
.bytes_per_frame = 4
|
||||
};
|
||||
|
||||
@ -93,24 +87,23 @@ static struct line6_pcm_properties toneport_pcm_properties = {
|
||||
static int led_red = 0x00;
|
||||
static int led_green = 0x26;
|
||||
|
||||
struct ToneportSourceInfo
|
||||
{
|
||||
struct ToneportSourceInfo {
|
||||
const char *name;
|
||||
int code;
|
||||
};
|
||||
|
||||
static const struct ToneportSourceInfo toneport_source_info[] = {
|
||||
{ "Microphone", 0x0a01 },
|
||||
{ "Line" , 0x0801 },
|
||||
{ "Instrument", 0x0b01 },
|
||||
{ "Inst & Mic", 0x0901 }
|
||||
{"Microphone", 0x0a01},
|
||||
{"Line", 0x0801},
|
||||
{"Instrument", 0x0b01},
|
||||
{"Inst & Mic", 0x0901}
|
||||
};
|
||||
|
||||
static bool toneport_has_led(short product)
|
||||
{
|
||||
return
|
||||
(product == LINE6_DEVID_GUITARPORT) ||
|
||||
(product == LINE6_DEVID_TONEPORT_GX);
|
||||
(product == LINE6_DEVID_GUITARPORT) ||
|
||||
(product == LINE6_DEVID_TONEPORT_GX);
|
||||
/* add your device here if you are missing support for the LEDs */
|
||||
}
|
||||
|
||||
@ -166,7 +159,6 @@ static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read,
|
||||
static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read,
|
||||
toneport_set_led_green);
|
||||
|
||||
|
||||
static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
|
||||
{
|
||||
int ret;
|
||||
@ -209,10 +201,16 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
|
||||
{
|
||||
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
if(ucontrol->value.integer.value[0] == line6pcm->volume_monitor)
|
||||
if (ucontrol->value.integer.value[0] == line6pcm->volume_monitor)
|
||||
return 0;
|
||||
|
||||
line6pcm->volume_monitor = ucontrol->value.integer.value[0];
|
||||
|
||||
if (line6pcm->volume_monitor > 0)
|
||||
line6_pcm_start(line6pcm, MASK_PCM_MONITOR);
|
||||
else
|
||||
line6_pcm_stop(line6pcm, MASK_PCM_MONITOR);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -225,7 +223,7 @@ static int snd_toneport_source_info(struct snd_kcontrol *kcontrol,
|
||||
uinfo->count = 1;
|
||||
uinfo->value.enumerated.items = size;
|
||||
|
||||
if(uinfo->value.enumerated.item >= size)
|
||||
if (uinfo->value.enumerated.item >= size)
|
||||
uinfo->value.enumerated.item = size - 1;
|
||||
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
@ -239,7 +237,8 @@ static int snd_toneport_source_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
|
||||
struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)line6pcm->line6;
|
||||
struct usb_line6_toneport *toneport =
|
||||
(struct usb_line6_toneport *)line6pcm->line6;
|
||||
ucontrol->value.enumerated.item[0] = toneport->source;
|
||||
return 0;
|
||||
}
|
||||
@ -249,13 +248,15 @@ static int snd_toneport_source_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
|
||||
struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)line6pcm->line6;
|
||||
struct usb_line6_toneport *toneport =
|
||||
(struct usb_line6_toneport *)line6pcm->line6;
|
||||
|
||||
if(ucontrol->value.enumerated.item[0] == toneport->source)
|
||||
if (ucontrol->value.enumerated.item[0] == toneport->source)
|
||||
return 0;
|
||||
|
||||
toneport->source = ucontrol->value.enumerated.item[0];
|
||||
toneport_send_cmd(toneport->line6.usbdev, toneport_source_info[toneport->source].code, 0x0000);
|
||||
toneport_send_cmd(toneport->line6.usbdev,
|
||||
toneport_source_info[toneport->source].code, 0x0000);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -321,10 +322,12 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
|
||||
toneport_send_cmd(usbdev, 0x0301, 0x0000);
|
||||
|
||||
/* initialize source select: */
|
||||
switch(usbdev->descriptor.idProduct) {
|
||||
switch (usbdev->descriptor.idProduct) {
|
||||
case LINE6_DEVID_TONEPORT_UX1:
|
||||
case LINE6_DEVID_PODSTUDIO_UX1:
|
||||
toneport_send_cmd(usbdev, toneport_source_info[toneport->source].code, 0x0000);
|
||||
toneport_send_cmd(usbdev,
|
||||
toneport_source_info[toneport->source].code,
|
||||
0x0000);
|
||||
}
|
||||
|
||||
if (toneport_has_led(usbdev->descriptor.idProduct))
|
||||
@ -357,16 +360,22 @@ static int toneport_try_init(struct usb_interface *interface,
|
||||
}
|
||||
|
||||
/* register monitor control: */
|
||||
err = snd_ctl_add(line6->card, snd_ctl_new1(&toneport_control_monitor, line6->line6pcm));
|
||||
err =
|
||||
snd_ctl_add(line6->card,
|
||||
snd_ctl_new1(&toneport_control_monitor,
|
||||
line6->line6pcm));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* register source select control: */
|
||||
switch(usbdev->descriptor.idProduct) {
|
||||
switch (usbdev->descriptor.idProduct) {
|
||||
case LINE6_DEVID_TONEPORT_UX1:
|
||||
case LINE6_DEVID_PODSTUDIO_UX1:
|
||||
err = snd_ctl_add(line6->card, snd_ctl_new1(&toneport_control_source, line6->line6pcm));
|
||||
err =
|
||||
snd_ctl_add(line6->card,
|
||||
snd_ctl_new1(&toneport_control_source,
|
||||
line6->line6pcm));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
@ -382,8 +391,10 @@ static int toneport_try_init(struct usb_interface *interface,
|
||||
line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
|
||||
|
||||
if (toneport_has_led(usbdev->descriptor.idProduct)) {
|
||||
CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_red));
|
||||
CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_green));
|
||||
CHECK_RETURN(device_create_file
|
||||
(&interface->dev, &dev_attr_led_red));
|
||||
CHECK_RETURN(device_create_file
|
||||
(&interface->dev, &dev_attr_led_green));
|
||||
}
|
||||
|
||||
toneport_setup(toneport);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,13 +12,11 @@
|
||||
#ifndef TONEPORT_H
|
||||
#define TONEPORT_H
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <sound/core.h>
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
|
||||
struct usb_line6_toneport {
|
||||
/**
|
||||
Generic Line6 USB data.
|
||||
@ -46,11 +44,9 @@ struct usb_line6_toneport {
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
|
||||
extern void line6_toneport_disconnect(struct usb_interface *interface);
|
||||
extern int line6_toneport_init(struct usb_interface *interface,
|
||||
struct usb_line6_toneport *toneport);
|
||||
extern void line6_toneport_reset_resume(struct usb_line6_toneport *toneport);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,7 +12,6 @@
|
||||
#ifndef USBDEFS_H
|
||||
#define USBDEFS_H
|
||||
|
||||
|
||||
#define LINE6_VENDOR_ID 0x0e41
|
||||
|
||||
#define USB_INTERVALS_PER_SECOND 1000
|
||||
@ -80,5 +79,4 @@
|
||||
#define LINE6_FALLBACK_INTERVAL 10
|
||||
#define LINE6_FALLBACK_MAXPACKETSIZE 16
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -16,7 +16,6 @@
|
||||
#include "driver.h"
|
||||
#include "variax.h"
|
||||
|
||||
|
||||
#define VARIAX_SYSEX_CODE 7
|
||||
#define VARIAX_SYSEX_PARAM 0x3b
|
||||
#define VARIAX_SYSEX_ACTIVATE 0x2a
|
||||
@ -24,7 +23,6 @@
|
||||
#define VARIAX_MODEL_MESSAGE_LENGTH 199
|
||||
#define VARIAX_OFFSET_ACTIVATE 7
|
||||
|
||||
|
||||
/*
|
||||
This message is sent by the device during initialization and identifies
|
||||
the connected guitar model.
|
||||
@ -71,14 +69,12 @@ static const char variax_request_model2[] = {
|
||||
0x00, 0x00, 0x00, 0xf7
|
||||
};
|
||||
|
||||
|
||||
/* forward declarations: */
|
||||
static int variax_create_files2(struct device *dev);
|
||||
static void variax_startup2(unsigned long data);
|
||||
static void variax_startup4(unsigned long data);
|
||||
static void variax_startup5(unsigned long data);
|
||||
|
||||
|
||||
/*
|
||||
Decode data transmitted by workbench.
|
||||
*/
|
||||
@ -110,17 +106,25 @@ static void variax_activate_async(struct usb_line6_variax *variax, int a)
|
||||
|
||||
static void variax_startup1(struct usb_line6_variax *variax)
|
||||
{
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, 1);
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_INIT);
|
||||
|
||||
/* delay startup procedure: */
|
||||
line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY1, variax_startup2, (unsigned long)variax);
|
||||
line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
|
||||
variax_startup2, (unsigned long)variax);
|
||||
}
|
||||
|
||||
static void variax_startup2(unsigned long data)
|
||||
{
|
||||
struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
|
||||
struct usb_line6 *line6 = &variax->line6;
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, 2);
|
||||
|
||||
/* schedule another startup procedure until startup is complete: */
|
||||
if (variax->startup_progress >= VARIAX_STARTUP_LAST)
|
||||
return;
|
||||
|
||||
variax->startup_progress = VARIAX_STARTUP_VERSIONREQ;
|
||||
line6_start_timer(&variax->startup_timer1, VARIAX_STARTUP_DELAY1,
|
||||
variax_startup2, (unsigned long)variax);
|
||||
|
||||
/* request firmware version: */
|
||||
line6_version_request_async(line6);
|
||||
@ -128,35 +132,41 @@ static void variax_startup2(unsigned long data)
|
||||
|
||||
static void variax_startup3(struct usb_line6_variax *variax)
|
||||
{
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, 3);
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_WAIT);
|
||||
|
||||
/* delay startup procedure: */
|
||||
line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY3, variax_startup4, (unsigned long)variax);
|
||||
line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY3,
|
||||
variax_startup4, (unsigned long)variax);
|
||||
}
|
||||
|
||||
static void variax_startup4(unsigned long data)
|
||||
{
|
||||
struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, 4);
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress,
|
||||
VARIAX_STARTUP_ACTIVATE);
|
||||
|
||||
/* activate device: */
|
||||
variax_activate_async(variax, 1);
|
||||
line6_start_timer(&variax->startup_timer, VARIAX_STARTUP_DELAY4, variax_startup5, (unsigned long)variax);
|
||||
line6_start_timer(&variax->startup_timer2, VARIAX_STARTUP_DELAY4,
|
||||
variax_startup5, (unsigned long)variax);
|
||||
}
|
||||
|
||||
static void variax_startup5(unsigned long data)
|
||||
{
|
||||
struct usb_line6_variax *variax = (struct usb_line6_variax *)data;
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, 5);
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress,
|
||||
VARIAX_STARTUP_DUMPREQ);
|
||||
|
||||
/* current model dump: */
|
||||
line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, VARIAX_DUMP_PASS1);
|
||||
line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
|
||||
VARIAX_DUMP_PASS1);
|
||||
/* passes 2 and 3 are performed implicitly before entering variax_startup6 */
|
||||
}
|
||||
|
||||
static void variax_startup6(struct usb_line6_variax *variax)
|
||||
{
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, 6);
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress,
|
||||
VARIAX_STARTUP_WORKQUEUE);
|
||||
|
||||
/* schedule work for global work queue: */
|
||||
schedule_work(&variax->startup_work);
|
||||
@ -164,10 +174,11 @@ static void variax_startup6(struct usb_line6_variax *variax)
|
||||
|
||||
static void variax_startup7(struct work_struct *work)
|
||||
{
|
||||
struct usb_line6_variax *variax = container_of(work, struct usb_line6_variax, startup_work);
|
||||
struct usb_line6_variax *variax =
|
||||
container_of(work, struct usb_line6_variax, startup_work);
|
||||
struct usb_line6 *line6 = &variax->line6;
|
||||
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, 7);
|
||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
|
||||
|
||||
/* ALSA audio interface: */
|
||||
line6_register_audio(&variax->line6);
|
||||
@ -200,7 +211,8 @@ void line6_variax_process_message(struct usb_line6_variax *variax)
|
||||
case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
|
||||
case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
|
||||
variax->model = buf[1];
|
||||
line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, VARIAX_DUMP_PASS1);
|
||||
line6_dump_request_async(&variax->dumpreq, &variax->line6, 0,
|
||||
VARIAX_DUMP_PASS1);
|
||||
break;
|
||||
|
||||
case LINE6_RESET:
|
||||
@ -214,20 +226,44 @@ void line6_variax_process_message(struct usb_line6_variax *variax)
|
||||
VARIAX_MODEL_MESSAGE_LENGTH) {
|
||||
switch (variax->dumpreq.in_progress) {
|
||||
case VARIAX_DUMP_PASS1:
|
||||
variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, (unsigned char *)&variax->model_data,
|
||||
(sizeof(variax->model_data.name) + sizeof(variax->model_data.control) / 2) * 2);
|
||||
line6_dump_request_async(&variax->dumpreq, &variax->line6, 1, VARIAX_DUMP_PASS2);
|
||||
variax_decode(buf +
|
||||
VARIAX_MODEL_HEADER_LENGTH,
|
||||
(unsigned char *)
|
||||
&variax->model_data,
|
||||
(sizeof
|
||||
(variax->model_data.
|
||||
name) +
|
||||
sizeof(variax->
|
||||
model_data.
|
||||
control)
|
||||
/ 2) * 2);
|
||||
line6_dump_request_async
|
||||
(&variax->dumpreq, &variax->line6,
|
||||
1, VARIAX_DUMP_PASS2);
|
||||
break;
|
||||
|
||||
case VARIAX_DUMP_PASS2:
|
||||
/* model name is transmitted twice, so skip it here: */
|
||||
variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH,
|
||||
(unsigned char *)&variax->model_data.control + sizeof(variax->model_data.control) / 2,
|
||||
sizeof(variax->model_data.control) / 2 * 2);
|
||||
line6_dump_request_async(&variax->dumpreq, &variax->line6, 2, VARIAX_DUMP_PASS3);
|
||||
variax_decode(buf +
|
||||
VARIAX_MODEL_HEADER_LENGTH,
|
||||
(unsigned char *)
|
||||
&variax->
|
||||
model_data.control +
|
||||
sizeof(variax->model_data.
|
||||
control)
|
||||
/ 2,
|
||||
sizeof(variax->model_data.
|
||||
control)
|
||||
/ 2 * 2);
|
||||
line6_dump_request_async
|
||||
(&variax->dumpreq, &variax->line6,
|
||||
2, VARIAX_DUMP_PASS3);
|
||||
}
|
||||
} else {
|
||||
DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "illegal length %d of model data\n", variax->line6.message_length));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(variax->line6.ifcdev,
|
||||
"illegal length %d of model data\n",
|
||||
variax->line6.message_length));
|
||||
line6_dump_finished(&variax->dumpreq);
|
||||
}
|
||||
} else if (memcmp(buf + 1, variax_request_bank + 1,
|
||||
@ -257,7 +293,9 @@ void line6_variax_process_message(struct usb_line6_variax *variax)
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "Variax: unknown message %02X\n", buf[0]));
|
||||
DEBUG_MESSAGES(dev_err
|
||||
(variax->line6.ifcdev,
|
||||
"Variax: unknown message %02X\n", buf[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,7 +305,8 @@ void line6_variax_process_message(struct usb_line6_variax *variax)
|
||||
static ssize_t variax_get_volume(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
return sprintf(buf, "%d\n", variax->volume);
|
||||
}
|
||||
|
||||
@ -278,7 +317,8 @@ static ssize_t variax_set_volume(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
unsigned long value;
|
||||
int ret;
|
||||
|
||||
@ -299,7 +339,8 @@ static ssize_t variax_set_volume(struct device *dev,
|
||||
static ssize_t variax_get_model(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
return sprintf(buf, "%d\n", variax->model);
|
||||
}
|
||||
|
||||
@ -310,7 +351,8 @@ static ssize_t variax_set_model(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
unsigned long value;
|
||||
int ret;
|
||||
|
||||
@ -330,8 +372,10 @@ static ssize_t variax_set_model(struct device *dev,
|
||||
static ssize_t variax_get_active(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
return sprintf(buf, "%d\n", variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
return sprintf(buf, "%d\n",
|
||||
variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -341,7 +385,8 @@ static ssize_t variax_set_active(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
unsigned long value;
|
||||
int ret;
|
||||
|
||||
@ -359,7 +404,8 @@ static ssize_t variax_set_active(struct device *dev,
|
||||
static ssize_t variax_get_tone(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
return sprintf(buf, "%d\n", variax->tone);
|
||||
}
|
||||
|
||||
@ -370,7 +416,8 @@ static ssize_t variax_set_tone(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
unsigned long value;
|
||||
int ret;
|
||||
|
||||
@ -407,7 +454,8 @@ static ssize_t get_string(char *buf, const char *data, int length)
|
||||
static ssize_t variax_get_name(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
line6_dump_wait_interruptible(&variax->dumpreq);
|
||||
return get_string(buf, variax->model_data.name,
|
||||
sizeof(variax->model_data.name));
|
||||
@ -419,7 +467,8 @@ static ssize_t variax_get_name(struct device *dev,
|
||||
static ssize_t variax_get_bank(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
line6_dump_wait_interruptible(&variax->dumpreq);
|
||||
return get_string(buf, variax->bank, sizeof(variax->bank));
|
||||
}
|
||||
@ -430,7 +479,8 @@ static ssize_t variax_get_bank(struct device *dev,
|
||||
static ssize_t variax_get_dump(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
int retval;
|
||||
retval = line6_dump_wait_interruptible(&variax->dumpreq);
|
||||
if (retval < 0)
|
||||
@ -446,15 +496,18 @@ static ssize_t variax_get_dump(struct device *dev,
|
||||
static ssize_t variax_get_guitar(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
return sprintf(buf, "%s\n", variax->guitar);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LINE6_USB_RAW
|
||||
|
||||
static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax, int code, int size)
|
||||
static char *variax_alloc_sysex_buffer(struct usb_line6_variax *variax,
|
||||
int code, int size)
|
||||
{
|
||||
return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code, size);
|
||||
return line6_alloc_sysex_buffer(&variax->line6, VARIAX_SYSEX_CODE, code,
|
||||
size);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -464,7 +517,8 @@ static ssize_t variax_set_raw2(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
|
||||
struct usb_line6_variax *variax =
|
||||
usb_get_intfdata(to_usb_interface(dev));
|
||||
int size;
|
||||
int i;
|
||||
char *sysex;
|
||||
@ -495,13 +549,16 @@ static ssize_t variax_set_raw2(struct device *dev,
|
||||
#endif
|
||||
|
||||
/* Variax workbench special files: */
|
||||
static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model);
|
||||
static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume);
|
||||
static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model,
|
||||
variax_set_model);
|
||||
static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume,
|
||||
variax_set_volume);
|
||||
static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
|
||||
static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
|
||||
static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
|
||||
static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
|
||||
static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active);
|
||||
static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active,
|
||||
variax_set_active);
|
||||
static DEVICE_ATTR(guitar, S_IRUGO, variax_get_guitar, line6_nop_write);
|
||||
|
||||
#ifdef CONFIG_LINE6_USB_RAW
|
||||
@ -509,7 +566,6 @@ static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
|
||||
static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Variax destructor.
|
||||
*/
|
||||
@ -525,6 +581,10 @@ static void variax_destruct(struct usb_interface *interface)
|
||||
return;
|
||||
line6_cleanup_audio(line6);
|
||||
|
||||
del_timer(&variax->startup_timer1);
|
||||
del_timer(&variax->startup_timer2);
|
||||
cancel_work_sync(&variax->startup_work);
|
||||
|
||||
/* free dump request data: */
|
||||
line6_dumpreq_destructbuf(&variax->dumpreq, 2);
|
||||
line6_dumpreq_destructbuf(&variax->dumpreq, 1);
|
||||
@ -562,12 +622,13 @@ static int variax_try_init(struct usb_interface *interface,
|
||||
{
|
||||
int err;
|
||||
|
||||
init_timer(&variax->startup_timer1);
|
||||
init_timer(&variax->startup_timer2);
|
||||
INIT_WORK(&variax->startup_work, variax_startup7);
|
||||
|
||||
if ((interface == NULL) || (variax == NULL))
|
||||
return -ENODEV;
|
||||
|
||||
init_timer(&variax->startup_timer);
|
||||
INIT_WORK(&variax->startup_work, variax_startup7);
|
||||
|
||||
/* initialize USB buffers: */
|
||||
err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
|
||||
sizeof(variax_request_model1));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Line6 Linux USB driver - 0.9.0
|
||||
* Line6 Linux USB driver - 0.9.1beta
|
||||
*
|
||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
||||
*
|
||||
@ -12,7 +12,6 @@
|
||||
#ifndef VARIAX_H
|
||||
#define VARIAX_H
|
||||
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/wait.h>
|
||||
@ -21,11 +20,23 @@
|
||||
#include "driver.h"
|
||||
#include "dumprequest.h"
|
||||
|
||||
|
||||
#define VARIAX_STARTUP_DELAY1 1000
|
||||
#define VARIAX_STARTUP_DELAY3 100
|
||||
#define VARIAX_STARTUP_DELAY4 100
|
||||
|
||||
/*
|
||||
Stages of Variax startup procedure
|
||||
*/
|
||||
enum {
|
||||
VARIAX_STARTUP_INIT = 1,
|
||||
VARIAX_STARTUP_VERSIONREQ,
|
||||
VARIAX_STARTUP_WAIT,
|
||||
VARIAX_STARTUP_ACTIVATE,
|
||||
VARIAX_STARTUP_DUMPREQ,
|
||||
VARIAX_STARTUP_WORKQUEUE,
|
||||
VARIAX_STARTUP_SETUP,
|
||||
VARIAX_STARTUP_LAST = VARIAX_STARTUP_SETUP - 1
|
||||
};
|
||||
|
||||
enum {
|
||||
VARIAX_DUMP_PASS1 = LINE6_DUMP_CURRENT,
|
||||
@ -33,7 +44,6 @@ enum {
|
||||
VARIAX_DUMP_PASS3
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Binary Variax model dump
|
||||
*/
|
||||
@ -59,7 +69,8 @@ struct usb_line6_variax {
|
||||
Dump request structure.
|
||||
Append two extra buffers for 3-pass data query.
|
||||
*/
|
||||
struct line6_dump_request dumpreq; struct line6_dump_reqbuf extrabuf[2];
|
||||
struct line6_dump_request dumpreq;
|
||||
struct line6_dump_reqbuf extrabuf[2];
|
||||
|
||||
/**
|
||||
Buffer for activation code.
|
||||
@ -102,9 +113,10 @@ struct usb_line6_variax {
|
||||
struct work_struct startup_work;
|
||||
|
||||
/**
|
||||
Timer for device initializaton.
|
||||
Timers for device initializaton.
|
||||
*/
|
||||
struct timer_list startup_timer;
|
||||
struct timer_list startup_timer1;
|
||||
struct timer_list startup_timer2;
|
||||
|
||||
/**
|
||||
Current progress in startup procedure.
|
||||
@ -112,11 +124,9 @@ struct usb_line6_variax {
|
||||
int startup_progress;
|
||||
};
|
||||
|
||||
|
||||
extern void line6_variax_disconnect(struct usb_interface *interface);
|
||||
extern int line6_variax_init(struct usb_interface *interface,
|
||||
struct usb_line6_variax *variax);
|
||||
extern void line6_variax_process_message(struct usb_line6_variax *variax);
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user