Commit 246118b9 authored by Jaroslav Kysela's avatar Jaroslav Kysela

[ALSA] hwdep interface for pcm data

USB,USB USX2Y
Implements 'rawusb' pcm data transfer through hwdep interface:
The usb_hc moves pcm data from/into memory via DMA.
That memory is mmaped by jack's usx2y driver.
Jack's usx2y driver is the first/last executable code to read/write pcm data.
Read/write is a combination of power of 2 period shaping and float/int
conversation.

Compared to standard alsa/jack we leave out power of 2 period shaping
inside snd-usb-usx2y which needs memcpy() and additional buffers.
As a side effect possible unwanted pcm-data coruption resulting of
standard alsa's snd-usb-usx2y period shaping scheme falls away.
Result is sane jack operation at buffering schemes down to 128frames,
2 periods.

Also changed Kconfig file, so snd-usb-usx2y is only available for X86,
PPC or ALPHA platforms, as on others DMA-memory isn't mmapable.
Signed-off-by: default avatarKarsten Wiese <annabellesgarden@yahoo.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 5376d7f6
......@@ -17,7 +17,7 @@ config SND_USB_AUDIO
config SND_USB_USX2Y
tristate "Tascam US-122, US-224 and US-428 USB driver"
depends on SND && USB
depends on SND && USB && (X86 || PPC || ALPHA)
select SND_HWDEP
select SND_RAWMIDI
select SND_PCM
......
snd-usb-usx2y-objs := usbusx2y.o usbusx2yaudio.o usX2Yhwdep.o
snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o
obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o
......@@ -31,6 +31,8 @@
#include "usbusx2y.h"
#include "usX2Yhwdep.h"
int usX2Y_hwdep_pcm_new(snd_card_t* card);
static struct page * snd_us428ctls_vm_nopage(struct vm_area_struct *area, unsigned long address, int *type)
{
......@@ -196,6 +198,8 @@ static int usX2Y_create_alsa_devices(snd_card_t* card)
}
if ((err = usX2Y_audio_create(card)) < 0)
break;
if ((err = usX2Y_hwdep_pcm_new(card)) < 0)
break;
if ((err = snd_card_register(card)) < 0)
break;
} while (0);
......
......@@ -20,6 +20,7 @@ typedef struct {
} snd_usX2Y_urbSeq_t;
typedef struct snd_usX2Y_substream snd_usX2Y_substream_t;
#include "usx2yhwdeppcm.h"
typedef struct {
snd_usb_audio_t chip;
......@@ -38,6 +39,7 @@ typedef struct {
us428ctls_sharedmem_t *us428ctls_sharedmem;
int wait_iso_frame;
wait_queue_head_t us428ctls_wait_queue_head;
snd_usX2Y_hwdep_pcm_shm_t *hwdep_pcm_shm;
snd_usX2Y_substream_t *subs[4];
snd_usX2Y_substream_t * volatile prepare_subs;
wait_queue_head_t prepare_wait_queue;
......
......@@ -67,7 +67,6 @@
#endif
static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs)
{
struct urb *urb = subs->completed_urb;
......@@ -892,6 +891,9 @@ static int snd_usX2Y_pcm_open(snd_pcm_substream_t *substream)
snd_pcm_substream_chip(substream))[substream->stream];
snd_pcm_runtime_t *runtime = substream->runtime;
if (subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
return -EBUSY;
runtime->hw = snd_usX2Y_2c;
runtime->private_data = subs;
subs->pcm_substream = substream;
......
......@@ -27,6 +27,7 @@
/* hwdep id string */
#define SND_USX2Y_LOADER_ID "USX2Y Loader"
#define SND_USX2Y_USBPCM_ID "USX2Y USBPCM"
/* hardware type */
enum {
......@@ -43,6 +44,7 @@ enum {
/* chip status */
enum {
USX2Y_STAT_CHIP_INIT = (1 << 0), /* all operational */
USX2Y_STAT_CHIP_MMAP_PCM_URBS = (1 << 1), /* pcm transport over mmaped urbs */
USX2Y_STAT_CHIP_HUP = (1 << 31), /* all operational */
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment