mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
ALSA: line6: Reorganize card resource handling
This is a fairly big rewrite regarding the card resource management in line6 drivers: - The card creation is moved into line6_probe(). This adds the global destructor to private_free, so that each driver doesn't have to call it any longer. - The USB disconnect callback handles the card release, thus each driver needs to concentrate on only its own resources. No need to snd_card_*() call in the destructor. - Fix the potential stall in disconnection by removing snd_card_free(). It's replaced with snd_card_free_when_closed() for asynchronous release. - The only remaining operation for the card in each driver is the call of snd_card_register(). All the rest are dealt in the common module by itself. - These ended up with removal of audio.[ch] as a result of a reduction of one layer. Each driver just needs to call line6_probe(). Tested-by: Chris Rorvick <chris@rorvick.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
84ac9bb12e
commit
85a9339bec
@ -1,5 +1,4 @@
|
|||||||
snd-usb-line6-y := \
|
snd-usb-line6-y := \
|
||||||
audio.o \
|
|
||||||
capture.o \
|
capture.o \
|
||||||
driver.o \
|
driver.o \
|
||||||
midi.o \
|
midi.o \
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Line6 Linux USB driver - 0.9.1beta
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation, version 2.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sound/core.h>
|
|
||||||
#include <sound/initval.h>
|
|
||||||
#include <linux/export.h>
|
|
||||||
|
|
||||||
#include "driver.h"
|
|
||||||
#include "audio.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
Initialize the Line6 USB audio system.
|
|
||||||
*/
|
|
||||||
int line6_init_audio(struct usb_line6 *line6)
|
|
||||||
{
|
|
||||||
struct snd_card *card;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = snd_card_new(line6->ifcdev,
|
|
||||||
SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
|
|
||||||
THIS_MODULE, 0, &card);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
line6->card = card;
|
|
||||||
|
|
||||||
strcpy(card->id, line6->properties->id);
|
|
||||||
strcpy(card->driver, DRIVER_NAME);
|
|
||||||
strcpy(card->shortname, line6->properties->name);
|
|
||||||
/* longname is 80 chars - see asound.h */
|
|
||||||
sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
|
|
||||||
dev_name(line6->ifcdev));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(line6_init_audio);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Register the Line6 USB audio system.
|
|
||||||
*/
|
|
||||||
int line6_register_audio(struct usb_line6 *line6)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = snd_card_register(line6->card);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(line6_register_audio);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Cleanup the Line6 USB audio system.
|
|
||||||
*/
|
|
||||||
void line6_cleanup_audio(struct usb_line6 *line6)
|
|
||||||
{
|
|
||||||
struct snd_card *card = line6->card;
|
|
||||||
|
|
||||||
if (card == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
snd_card_disconnect(card);
|
|
||||||
snd_card_free(card);
|
|
||||||
line6->card = NULL;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(line6_cleanup_audio);
|
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Line6 Linux USB driver - 0.9.1beta
|
|
||||||
*
|
|
||||||
* Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation, version 2.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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
|
|
@ -14,7 +14,6 @@
|
|||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "pcm.h"
|
#include "pcm.h"
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
|
|
||||||
#include "audio.h"
|
#include <sound/core.h>
|
||||||
|
#include <sound/initval.h>
|
||||||
|
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
@ -481,17 +483,16 @@ ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
|
|||||||
EXPORT_SYMBOL_GPL(line6_nop_read);
|
EXPORT_SYMBOL_GPL(line6_nop_read);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Generic destructor.
|
Card destructor.
|
||||||
*/
|
*/
|
||||||
static void line6_destruct(struct usb_interface *interface)
|
static void line6_destruct(struct snd_card *card)
|
||||||
{
|
{
|
||||||
struct usb_line6 *line6;
|
struct usb_line6 *line6 = card->private_data;
|
||||||
|
struct usb_device *usbdev;
|
||||||
|
|
||||||
if (interface == NULL)
|
if (!line6)
|
||||||
return;
|
|
||||||
line6 = usb_get_intfdata(interface);
|
|
||||||
if (line6 == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
usbdev = line6->usbdev;
|
||||||
|
|
||||||
/* free buffer memory first: */
|
/* free buffer memory first: */
|
||||||
kfree(line6->buffer_message);
|
kfree(line6->buffer_message);
|
||||||
@ -500,8 +501,11 @@ static void line6_destruct(struct usb_interface *interface)
|
|||||||
/* then free URBs: */
|
/* then free URBs: */
|
||||||
usb_free_urb(line6->urb_listen);
|
usb_free_urb(line6->urb_listen);
|
||||||
|
|
||||||
/* make sure the device isn't destructed twice: */
|
/* free interface data: */
|
||||||
usb_set_intfdata(interface, NULL);
|
kfree(line6);
|
||||||
|
|
||||||
|
/* decrement reference counters: */
|
||||||
|
usb_put_dev(usbdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -513,6 +517,7 @@ int line6_probe(struct usb_interface *interface,
|
|||||||
int (*private_init)(struct usb_interface *, struct usb_line6 *))
|
int (*private_init)(struct usb_interface *, struct usb_line6 *))
|
||||||
{
|
{
|
||||||
struct usb_device *usbdev;
|
struct usb_device *usbdev;
|
||||||
|
struct snd_card *card;
|
||||||
int interface_number;
|
int interface_number;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -569,8 +574,26 @@ int line6_probe(struct usb_interface *interface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = snd_card_new(line6->ifcdev,
|
||||||
|
SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
|
||||||
|
THIS_MODULE, 0, &card);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err_put;
|
||||||
|
|
||||||
|
line6->card = card;
|
||||||
|
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));
|
||||||
|
card->private_data = line6;
|
||||||
|
card->private_free = line6_destruct;
|
||||||
|
|
||||||
usb_set_intfdata(interface, line6);
|
usb_set_intfdata(interface, line6);
|
||||||
|
|
||||||
|
/* increment reference counters: */
|
||||||
|
usb_get_dev(usbdev);
|
||||||
|
|
||||||
if (properties->capabilities & LINE6_CAP_CONTROL) {
|
if (properties->capabilities & LINE6_CAP_CONTROL) {
|
||||||
/* initialize USB buffers: */
|
/* initialize USB buffers: */
|
||||||
line6->buffer_listen =
|
line6->buffer_listen =
|
||||||
@ -612,15 +635,11 @@ int line6_probe(struct usb_interface *interface,
|
|||||||
dev_info(&interface->dev, "Line6 %s now attached\n",
|
dev_info(&interface->dev, "Line6 %s now attached\n",
|
||||||
line6->properties->name);
|
line6->properties->name);
|
||||||
|
|
||||||
/* increment reference counters: */
|
|
||||||
usb_get_intf(interface);
|
|
||||||
usb_get_dev(usbdev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_destruct:
|
err_destruct:
|
||||||
line6_destruct(interface);
|
snd_card_free(card);
|
||||||
err_put:
|
err_put:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(line6_probe);
|
EXPORT_SYMBOL_GPL(line6_probe);
|
||||||
@ -642,29 +661,26 @@ void line6_disconnect(struct usb_interface *interface)
|
|||||||
|
|
||||||
interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
|
interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
|
||||||
line6 = usb_get_intfdata(interface);
|
line6 = usb_get_intfdata(interface);
|
||||||
|
if (!line6)
|
||||||
|
return;
|
||||||
|
|
||||||
if (line6 != NULL) {
|
if (line6->urb_listen != NULL)
|
||||||
if (line6->urb_listen != NULL)
|
line6_stop_listen(line6);
|
||||||
line6_stop_listen(line6);
|
|
||||||
|
|
||||||
if (usbdev != line6->usbdev)
|
if (usbdev != line6->usbdev)
|
||||||
dev_err(line6->ifcdev,
|
dev_err(line6->ifcdev, "driver bug: inconsistent usb device\n");
|
||||||
"driver bug: inconsistent usb device\n");
|
|
||||||
|
|
||||||
|
snd_card_disconnect(line6->card);
|
||||||
|
if (line6->disconnect)
|
||||||
line6->disconnect(interface);
|
line6->disconnect(interface);
|
||||||
|
|
||||||
dev_info(&interface->dev, "Line6 %s now disconnected\n",
|
dev_info(&interface->dev, "Line6 %s now disconnected\n",
|
||||||
line6->properties->name);
|
line6->properties->name);
|
||||||
}
|
|
||||||
|
|
||||||
line6_destruct(interface);
|
/* make sure the device isn't destructed twice: */
|
||||||
|
usb_set_intfdata(interface, NULL);
|
||||||
|
|
||||||
/* free interface data: */
|
snd_card_free_when_closed(line6->card);
|
||||||
kfree(line6);
|
|
||||||
|
|
||||||
/* decrement reference counters: */
|
|
||||||
usb_put_intf(interface);
|
|
||||||
usb_put_dev(usbdev);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(line6_disconnect);
|
EXPORT_SYMBOL_GPL(line6_disconnect);
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/rawmidi.h>
|
#include <sound/rawmidi.h>
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
#include "usbdefs.h"
|
#include "usbdefs.h"
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "pcm.h"
|
#include "pcm.h"
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
@ -340,7 +339,7 @@ static void pod_startup4(struct work_struct *work)
|
|||||||
line6_read_serial_number(&pod->line6, &pod->serial_number);
|
line6_read_serial_number(&pod->line6, &pod->serial_number);
|
||||||
|
|
||||||
/* ALSA audio interface: */
|
/* ALSA audio interface: */
|
||||||
line6_register_audio(line6);
|
snd_card_register(line6->card);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* POD special files: */
|
/* POD special files: */
|
||||||
@ -397,21 +396,6 @@ static struct snd_kcontrol_new pod_control_monitor = {
|
|||||||
.put = snd_pod_control_monitor_put
|
.put = snd_pod_control_monitor_put
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
POD destructor.
|
|
||||||
*/
|
|
||||||
static void pod_destruct(struct usb_interface *interface)
|
|
||||||
{
|
|
||||||
struct usb_line6_pod *pod = usb_get_intfdata(interface);
|
|
||||||
|
|
||||||
if (pod == NULL)
|
|
||||||
return;
|
|
||||||
line6_cleanup_audio(&pod->line6);
|
|
||||||
|
|
||||||
del_timer(&pod->startup_timer);
|
|
||||||
cancel_work_sync(&pod->startup_work);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
POD device disconnected.
|
POD device disconnected.
|
||||||
*/
|
*/
|
||||||
@ -424,21 +408,18 @@ static void line6_pod_disconnect(struct usb_interface *interface)
|
|||||||
pod = usb_get_intfdata(interface);
|
pod = usb_get_intfdata(interface);
|
||||||
|
|
||||||
if (pod != NULL) {
|
if (pod != NULL) {
|
||||||
struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
|
|
||||||
struct device *dev = &interface->dev;
|
struct device *dev = &interface->dev;
|
||||||
|
|
||||||
if (line6pcm != NULL)
|
|
||||||
line6_pcm_disconnect(line6pcm);
|
|
||||||
|
|
||||||
if (dev != NULL) {
|
if (dev != NULL) {
|
||||||
/* remove sysfs entries: */
|
/* remove sysfs entries: */
|
||||||
device_remove_file(dev, &dev_attr_device_id);
|
device_remove_file(dev, &dev_attr_device_id);
|
||||||
device_remove_file(dev, &dev_attr_firmware_version);
|
device_remove_file(dev, &dev_attr_firmware_version);
|
||||||
device_remove_file(dev, &dev_attr_serial_number);
|
device_remove_file(dev, &dev_attr_serial_number);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pod_destruct(interface);
|
del_timer_sync(&pod->startup_timer);
|
||||||
|
cancel_work_sync(&pod->startup_work);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -457,8 +438,8 @@ static int pod_create_files2(struct device *dev)
|
|||||||
/*
|
/*
|
||||||
Try to init POD device.
|
Try to init POD device.
|
||||||
*/
|
*/
|
||||||
static int pod_try_init(struct usb_interface *interface,
|
static int pod_init(struct usb_interface *interface,
|
||||||
struct usb_line6 *line6)
|
struct usb_line6 *line6)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
|
struct usb_line6_pod *pod = (struct usb_line6_pod *) line6;
|
||||||
@ -477,11 +458,6 @@ static int pod_try_init(struct usb_interface *interface,
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* initialize audio system: */
|
|
||||||
err = line6_init_audio(line6);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* initialize MIDI subsystem: */
|
/* initialize MIDI subsystem: */
|
||||||
err = line6_init_midi(line6);
|
err = line6_init_midi(line6);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@ -514,20 +490,6 @@ static int pod_try_init(struct usb_interface *interface,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Init POD device (and clean up in case of failure).
|
|
||||||
*/
|
|
||||||
static int pod_init(struct usb_interface *interface,
|
|
||||||
struct usb_line6 *line6)
|
|
||||||
{
|
|
||||||
int err = pod_try_init(interface, line6);
|
|
||||||
|
|
||||||
if (err < 0)
|
|
||||||
pod_destruct(interface);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
|
#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
|
||||||
#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
|
#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
|
||||||
|
|
||||||
@ -636,17 +598,13 @@ static int pod_probe(struct usb_interface *interface,
|
|||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct usb_line6_pod *pod;
|
struct usb_line6_pod *pod;
|
||||||
int err;
|
|
||||||
|
|
||||||
pod = kzalloc(sizeof(*pod), GFP_KERNEL);
|
pod = kzalloc(sizeof(*pod), GFP_KERNEL);
|
||||||
if (!pod)
|
if (!pod)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
err = line6_probe(interface, &pod->line6,
|
return line6_probe(interface, &pod->line6,
|
||||||
&pod_properties_table[id->driver_info],
|
&pod_properties_table[id->driver_info],
|
||||||
pod_init);
|
pod_init);
|
||||||
if (err < 0)
|
|
||||||
kfree(pod);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_driver pod_driver = {
|
static struct usb_driver pod_driver = {
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "pcm.h"
|
#include "pcm.h"
|
||||||
#include "usbdefs.h"
|
#include "usbdefs.h"
|
||||||
@ -85,58 +84,18 @@ static struct line6_pcm_properties podhd_pcm_properties = {
|
|||||||
.bytes_per_frame = PODHD_BYTES_PER_FRAME
|
.bytes_per_frame = PODHD_BYTES_PER_FRAME
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
POD HD destructor.
|
|
||||||
*/
|
|
||||||
static void podhd_destruct(struct usb_interface *interface)
|
|
||||||
{
|
|
||||||
struct usb_line6_podhd *podhd = usb_get_intfdata(interface);
|
|
||||||
|
|
||||||
if (podhd == NULL)
|
|
||||||
return;
|
|
||||||
line6_cleanup_audio(&podhd->line6);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
POD HD device disconnected.
|
|
||||||
*/
|
|
||||||
static void line6_podhd_disconnect(struct usb_interface *interface)
|
|
||||||
{
|
|
||||||
struct usb_line6_podhd *podhd;
|
|
||||||
|
|
||||||
if (interface == NULL)
|
|
||||||
return;
|
|
||||||
podhd = usb_get_intfdata(interface);
|
|
||||||
|
|
||||||
if (podhd != NULL) {
|
|
||||||
struct snd_line6_pcm *line6pcm = podhd->line6.line6pcm;
|
|
||||||
|
|
||||||
if (line6pcm != NULL)
|
|
||||||
line6_pcm_disconnect(line6pcm);
|
|
||||||
}
|
|
||||||
|
|
||||||
podhd_destruct(interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try to init POD HD device.
|
Try to init POD HD device.
|
||||||
*/
|
*/
|
||||||
static int podhd_try_init(struct usb_interface *interface,
|
static int podhd_init(struct usb_interface *interface,
|
||||||
struct usb_line6_podhd *podhd)
|
struct usb_line6 *line6)
|
||||||
{
|
{
|
||||||
|
struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6;
|
||||||
int err;
|
int err;
|
||||||
struct usb_line6 *line6 = &podhd->line6;
|
|
||||||
|
|
||||||
if ((interface == NULL) || (podhd == NULL))
|
if ((interface == NULL) || (podhd == NULL))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
line6->disconnect = line6_podhd_disconnect;
|
|
||||||
|
|
||||||
/* initialize audio system: */
|
|
||||||
err = line6_init_audio(line6);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* initialize MIDI subsystem: */
|
/* initialize MIDI subsystem: */
|
||||||
err = line6_init_midi(line6);
|
err = line6_init_midi(line6);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@ -148,8 +107,7 @@ static int podhd_try_init(struct usb_interface *interface,
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* register USB audio system: */
|
/* register USB audio system: */
|
||||||
err = line6_register_audio(line6);
|
return snd_card_register(line6->card);
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
|
#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
|
||||||
@ -217,21 +175,6 @@ static const struct line6_properties podhd_properties_table[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
Init POD HD device (and clean up in case of failure).
|
|
||||||
*/
|
|
||||||
static int podhd_init(struct usb_interface *interface,
|
|
||||||
struct usb_line6 *line6)
|
|
||||||
{
|
|
||||||
struct usb_line6_podhd *podhd = (struct usb_line6_podhd *) line6;
|
|
||||||
int err = podhd_try_init(interface, podhd);
|
|
||||||
|
|
||||||
if (err < 0)
|
|
||||||
podhd_destruct(interface);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Probe USB device.
|
Probe USB device.
|
||||||
*/
|
*/
|
||||||
@ -239,17 +182,13 @@ static int podhd_probe(struct usb_interface *interface,
|
|||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct usb_line6_podhd *podhd;
|
struct usb_line6_podhd *podhd;
|
||||||
int err;
|
|
||||||
|
|
||||||
podhd = kzalloc(sizeof(*podhd), GFP_KERNEL);
|
podhd = kzalloc(sizeof(*podhd), GFP_KERNEL);
|
||||||
if (!podhd)
|
if (!podhd)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
err = line6_probe(interface, &podhd->line6,
|
return line6_probe(interface, &podhd->line6,
|
||||||
&podhd_properties_table[id->driver_info],
|
&podhd_properties_table[id->driver_info],
|
||||||
podhd_init);
|
podhd_init);
|
||||||
if (err < 0)
|
|
||||||
kfree(podhd);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_driver podhd_driver = {
|
static struct usb_driver podhd_driver = {
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "capture.h"
|
#include "capture.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
@ -330,18 +329,6 @@ static struct snd_kcontrol_new toneport_control_source = {
|
|||||||
.put = snd_toneport_source_put
|
.put = snd_toneport_source_put
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
Toneport destructor.
|
|
||||||
*/
|
|
||||||
static void toneport_destruct(struct usb_interface *interface)
|
|
||||||
{
|
|
||||||
struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
|
|
||||||
|
|
||||||
if (toneport == NULL)
|
|
||||||
return;
|
|
||||||
line6_cleanup_audio(&toneport->line6);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Setup Toneport device.
|
Setup Toneport device.
|
||||||
*/
|
*/
|
||||||
@ -394,25 +381,14 @@ static void line6_toneport_disconnect(struct usb_interface *interface)
|
|||||||
device_remove_file(&interface->dev, &dev_attr_led_red);
|
device_remove_file(&interface->dev, &dev_attr_led_red);
|
||||||
device_remove_file(&interface->dev, &dev_attr_led_green);
|
device_remove_file(&interface->dev, &dev_attr_led_green);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toneport != NULL) {
|
|
||||||
struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
|
|
||||||
|
|
||||||
if (line6pcm != NULL) {
|
|
||||||
line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
|
|
||||||
line6_pcm_disconnect(line6pcm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
toneport_destruct(interface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try to init Toneport device.
|
Try to init Toneport device.
|
||||||
*/
|
*/
|
||||||
static int toneport_try_init(struct usb_interface *interface,
|
static int toneport_init(struct usb_interface *interface,
|
||||||
struct usb_line6 *line6)
|
struct usb_line6 *line6)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6;
|
struct usb_line6_toneport *toneport = (struct usb_line6_toneport *) line6;
|
||||||
@ -422,11 +398,6 @@ static int toneport_try_init(struct usb_interface *interface,
|
|||||||
|
|
||||||
line6->disconnect = line6_toneport_disconnect;
|
line6->disconnect = line6_toneport_disconnect;
|
||||||
|
|
||||||
/* initialize audio system: */
|
|
||||||
err = line6_init_audio(line6);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* initialize PCM subsystem: */
|
/* initialize PCM subsystem: */
|
||||||
err = line6_init_pcm(line6, &toneport_pcm_properties);
|
err = line6_init_pcm(line6, &toneport_pcm_properties);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@ -456,11 +427,6 @@ static int toneport_try_init(struct usb_interface *interface,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* register audio system: */
|
|
||||||
err = line6_register_audio(line6);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
line6_read_serial_number(line6, &toneport->serial_number);
|
line6_read_serial_number(line6, &toneport->serial_number);
|
||||||
line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
|
line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
|
||||||
|
|
||||||
@ -477,21 +443,8 @@ static int toneport_try_init(struct usb_interface *interface,
|
|||||||
(unsigned long)toneport);
|
(unsigned long)toneport);
|
||||||
mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
|
mod_timer(&toneport->timer, jiffies + TONEPORT_PCM_DELAY * HZ);
|
||||||
|
|
||||||
return 0;
|
/* register audio system: */
|
||||||
}
|
return snd_card_register(line6->card);
|
||||||
|
|
||||||
/*
|
|
||||||
Init Toneport device (and clean up in case of failure).
|
|
||||||
*/
|
|
||||||
static int toneport_init(struct usb_interface *interface,
|
|
||||||
struct usb_line6 *line6)
|
|
||||||
{
|
|
||||||
int err = toneport_try_init(interface, line6);
|
|
||||||
|
|
||||||
if (err < 0)
|
|
||||||
toneport_destruct(interface);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
@ -595,18 +548,14 @@ static int toneport_probe(struct usb_interface *interface,
|
|||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct usb_line6_toneport *toneport;
|
struct usb_line6_toneport *toneport;
|
||||||
int err;
|
|
||||||
|
|
||||||
toneport = kzalloc(sizeof(*toneport), GFP_KERNEL);
|
toneport = kzalloc(sizeof(*toneport), GFP_KERNEL);
|
||||||
if (!toneport)
|
if (!toneport)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
toneport->type = id->driver_info;
|
toneport->type = id->driver_info;
|
||||||
err = line6_probe(interface, &toneport->line6,
|
return line6_probe(interface, &toneport->line6,
|
||||||
&toneport_properties_table[id->driver_info],
|
&toneport_properties_table[id->driver_info],
|
||||||
toneport_init);
|
toneport_init);
|
||||||
if (err < 0)
|
|
||||||
kfree(toneport);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_driver toneport_driver = {
|
static struct usb_driver toneport_driver = {
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
|
|
||||||
#include "audio.h"
|
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "usbdefs.h"
|
#include "usbdefs.h"
|
||||||
|
|
||||||
@ -179,7 +178,7 @@ static void variax_startup6(struct work_struct *work)
|
|||||||
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
|
CHECK_STARTUP_PROGRESS(variax->startup_progress, VARIAX_STARTUP_SETUP);
|
||||||
|
|
||||||
/* ALSA audio interface: */
|
/* ALSA audio interface: */
|
||||||
line6_register_audio(&variax->line6);
|
snd_card_register(variax->line6.card);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -211,13 +210,16 @@ static void line6_variax_process_message(struct usb_line6 *line6)
|
|||||||
/*
|
/*
|
||||||
Variax destructor.
|
Variax destructor.
|
||||||
*/
|
*/
|
||||||
static void variax_destruct(struct usb_interface *interface)
|
static void line6_variax_disconnect(struct usb_interface *interface)
|
||||||
{
|
{
|
||||||
struct usb_line6_variax *variax = usb_get_intfdata(interface);
|
struct usb_line6_variax *variax;
|
||||||
|
|
||||||
if (variax == NULL)
|
if (!interface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
variax = usb_get_intfdata(interface);
|
||||||
|
if (!variax)
|
||||||
return;
|
return;
|
||||||
line6_cleanup_audio(&variax->line6);
|
|
||||||
|
|
||||||
del_timer(&variax->startup_timer1);
|
del_timer(&variax->startup_timer1);
|
||||||
del_timer(&variax->startup_timer2);
|
del_timer(&variax->startup_timer2);
|
||||||
@ -226,22 +228,11 @@ static void variax_destruct(struct usb_interface *interface)
|
|||||||
kfree(variax->buffer_activate);
|
kfree(variax->buffer_activate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Workbench device disconnected.
|
|
||||||
*/
|
|
||||||
static void line6_variax_disconnect(struct usb_interface *interface)
|
|
||||||
{
|
|
||||||
if (interface == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
variax_destruct(interface);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try to init workbench device.
|
Try to init workbench device.
|
||||||
*/
|
*/
|
||||||
static int variax_try_init(struct usb_interface *interface,
|
static int variax_init(struct usb_interface *interface,
|
||||||
struct usb_line6 *line6)
|
struct usb_line6 *line6)
|
||||||
{
|
{
|
||||||
struct usb_line6_variax *variax = (struct usb_line6_variax *) line6;
|
struct usb_line6_variax *variax = (struct usb_line6_variax *) line6;
|
||||||
int err;
|
int err;
|
||||||
@ -263,11 +254,6 @@ static int variax_try_init(struct usb_interface *interface,
|
|||||||
if (variax->buffer_activate == NULL)
|
if (variax->buffer_activate == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* initialize audio system: */
|
|
||||||
err = line6_init_audio(&variax->line6);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* initialize MIDI subsystem: */
|
/* initialize MIDI subsystem: */
|
||||||
err = line6_init_midi(&variax->line6);
|
err = line6_init_midi(&variax->line6);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@ -278,20 +264,6 @@ static int variax_try_init(struct usb_interface *interface,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Init workbench device (and clean up in case of failure).
|
|
||||||
*/
|
|
||||||
static int variax_init(struct usb_interface *interface,
|
|
||||||
struct usb_line6 *line6)
|
|
||||||
{
|
|
||||||
int err = variax_try_init(interface, line6);
|
|
||||||
|
|
||||||
if (err < 0)
|
|
||||||
variax_destruct(interface);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
|
#define LINE6_DEVICE(prod) USB_DEVICE(0x0e41, prod)
|
||||||
#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
|
#define LINE6_IF_NUM(prod, n) USB_DEVICE_INTERFACE_NUMBER(0x0e41, prod, n)
|
||||||
|
|
||||||
@ -335,17 +307,13 @@ static int variax_probe(struct usb_interface *interface,
|
|||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct usb_line6_variax *variax;
|
struct usb_line6_variax *variax;
|
||||||
int err;
|
|
||||||
|
|
||||||
variax = kzalloc(sizeof(*variax), GFP_KERNEL);
|
variax = kzalloc(sizeof(*variax), GFP_KERNEL);
|
||||||
if (!variax)
|
if (!variax)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
err = line6_probe(interface, &variax->line6,
|
return line6_probe(interface, &variax->line6,
|
||||||
&variax_properties_table[id->driver_info],
|
&variax_properties_table[id->driver_info],
|
||||||
variax_init);
|
variax_init);
|
||||||
if (err < 0)
|
|
||||||
kfree(variax);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_driver variax_driver = {
|
static struct usb_driver variax_driver = {
|
||||||
|
Loading…
Reference in New Issue
Block a user