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 ...@@ -17,7 +17,7 @@ config SND_USB_AUDIO
config SND_USB_USX2Y config SND_USB_USX2Y
tristate "Tascam US-122, US-224 and US-428 USB driver" 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_HWDEP
select SND_RAWMIDI select SND_RAWMIDI
select SND_PCM 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 obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-usx2y.o
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include "usbusx2y.h" #include "usbusx2y.h"
#include "usX2Yhwdep.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) 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) ...@@ -196,6 +198,8 @@ static int usX2Y_create_alsa_devices(snd_card_t* card)
} }
if ((err = usX2Y_audio_create(card)) < 0) if ((err = usX2Y_audio_create(card)) < 0)
break; break;
if ((err = usX2Y_hwdep_pcm_new(card)) < 0)
break;
if ((err = snd_card_register(card)) < 0) if ((err = snd_card_register(card)) < 0)
break; break;
} while (0); } while (0);
......
...@@ -20,6 +20,7 @@ typedef struct { ...@@ -20,6 +20,7 @@ typedef struct {
} snd_usX2Y_urbSeq_t; } snd_usX2Y_urbSeq_t;
typedef struct snd_usX2Y_substream snd_usX2Y_substream_t; typedef struct snd_usX2Y_substream snd_usX2Y_substream_t;
#include "usx2yhwdeppcm.h"
typedef struct { typedef struct {
snd_usb_audio_t chip; snd_usb_audio_t chip;
...@@ -38,6 +39,7 @@ typedef struct { ...@@ -38,6 +39,7 @@ typedef struct {
us428ctls_sharedmem_t *us428ctls_sharedmem; us428ctls_sharedmem_t *us428ctls_sharedmem;
int wait_iso_frame; int wait_iso_frame;
wait_queue_head_t us428ctls_wait_queue_head; 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 *subs[4];
snd_usX2Y_substream_t * volatile prepare_subs; snd_usX2Y_substream_t * volatile prepare_subs;
wait_queue_head_t prepare_wait_queue; wait_queue_head_t prepare_wait_queue;
......
...@@ -67,7 +67,6 @@ ...@@ -67,7 +67,6 @@
#endif #endif
static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs) static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs)
{ {
struct urb *urb = subs->completed_urb; struct urb *urb = subs->completed_urb;
...@@ -892,6 +891,9 @@ static int snd_usX2Y_pcm_open(snd_pcm_substream_t *substream) ...@@ -892,6 +891,9 @@ static int snd_usX2Y_pcm_open(snd_pcm_substream_t *substream)
snd_pcm_substream_chip(substream))[substream->stream]; snd_pcm_substream_chip(substream))[substream->stream];
snd_pcm_runtime_t *runtime = substream->runtime; 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->hw = snd_usX2Y_2c;
runtime->private_data = subs; runtime->private_data = subs;
subs->pcm_substream = substream; subs->pcm_substream = substream;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
/* hwdep id string */ /* hwdep id string */
#define SND_USX2Y_LOADER_ID "USX2Y Loader" #define SND_USX2Y_LOADER_ID "USX2Y Loader"
#define SND_USX2Y_USBPCM_ID "USX2Y USBPCM"
/* hardware type */ /* hardware type */
enum { enum {
...@@ -43,6 +44,7 @@ enum { ...@@ -43,6 +44,7 @@ enum {
/* chip status */ /* chip status */
enum { enum {
USX2Y_STAT_CHIP_INIT = (1 << 0), /* all operational */ 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 */ 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