Hi Takashi, please commit this with Comment: >>> 24Bit in 3Bytes (S24_3LE) support. <<<
Danke, Karsten
Index: alsa-driver/usb/us428/usbus428.c =================================================================== RCS file: /cvsroot/alsa/alsa-driver/usb/us428/usbus428.c,v retrieving revision 1.6 diff -u -r1.6 usbus428.c --- alsa-driver/usb/us428/usbus428.c 24 Oct 2003 13:58:47 -0000 1.6 +++ alsa-driver/usb/us428/usbus428.c 3 Nov 2003 10:55:22 -0000 @@ -1,6 +1,11 @@ /* * usbus428.c - ALSA USB US-428 Driver * +2003-11-03 Karsten Wiese + Version 0.3: + 24Bit support. + "arecord -D hw:1 -c 2 -r 48000 -M -f S24_3LE|aplay -D hw:1 -c 2 -r 48000 -M -f S24_3LE" works. + 2003-08-22 Karsten Wiese Version 0.0.8: Removed EZUSB Firmware. First Stage Firmwaredownload is now done by tascam-firmware downloader. @@ -75,7 +80,7 @@ MODULE_AUTHOR("Karsten Wiese <[EMAIL PROTECTED]>"); -MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.2"); +MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.3"); MODULE_LICENSE("GPL"); MODULE_CLASSES("{sound}"); MODULE_DEVICES("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001) }}"); @@ -226,18 +231,14 @@ { int dev; snd_card_t* card; - for (dev = 0; dev < SNDRV_CARDS; ++dev) if (enable[dev] && !snd_us428_card_used[dev]) break; - if (dev >= SNDRV_CARDS) return NULL; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(us428dev_t)); if (!card) return NULL; - snd_us428_card_used[us428(card)->chip.index = dev] = 1; card->private_free = snd_us428_card_private_free; us428(card)->chip.dev = device; @@ -245,7 +246,6 @@ init_MUTEX (&us428(card)->open_mutex); INIT_LIST_HEAD(&us428(card)->chip.midi_list); us428(card)->Seq04Complete = 1; - us428(card)->stride = 4; // 16 Bit strcpy(card->driver, "USB "NAME_ALLCAPS""); sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", @@ -258,25 +258,15 @@ } -static void* snd_us428_usb_probe(struct usb_device* device, - struct usb_interface *intf, - const struct usb_device_id* device_id) +static void* snd_us428_usb_probe(struct usb_device* device, struct usb_interface *intf, const struct usb_device_id* device_id) { int err; snd_card_t* card; - - /* See if the device offered us matches what we can accept */ - if (device->descriptor.idVendor != 0x1604 || device->descriptor.idProduct != 0x8001) + if (device->descriptor.idVendor != 0x1604 || device->descriptor.idProduct != 0x8001 || + !(card = snd_us428_create_card(device))) return 0; - - if (!(card = snd_us428_create_card(device))) - return 0; - - if ((err = snd_usX2Y_hwdep_new(card, device)) < 0) { - snd_card_free(card); - return 0; - } - if ((err = snd_card_register(card)) < 0) { + if ((err = snd_usX2Y_hwdep_new(card, device)) < 0 || + (err = snd_card_register(card)) < 0) { snd_card_free(card); return 0; } @@ -287,8 +277,7 @@ /* * new 2.5 USB kernel API */ -static int snd_us428_probe(struct usb_interface *intf, - const struct usb_device_id *id) +static int snd_us428_probe(struct usb_interface *intf, const struct usb_device_id *id) { void *chip; chip = snd_us428_usb_probe(interface_to_usbdev(intf), intf, id); @@ -308,8 +297,7 @@ /* * 2.4 USB kernel API */ -static void *snd_us428_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) +static void *snd_us428_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) { return snd_us428_usb_probe(dev, usb_ifnum_to_if(dev, ifnum), id); } Index: alsa-driver/usb/us428/usbus428.h =================================================================== RCS file: /cvsroot/alsa/alsa-driver/usb/us428/usbus428.h,v retrieving revision 1.2 diff -u -r1.2 usbus428.h --- alsa-driver/usb/us428/usbus428.h 24 Sep 2003 16:45:10 -0000 1.2 +++ alsa-driver/usb/us428/usbus428.h 3 Nov 2003 10:55:22 -0000 @@ -14,12 +14,12 @@ #define URBS_AsyncSeq 10 #define URB_DataLen_AsyncSeq 32 -typedef struct{ +typedef struct { urb_t* urb[URBS_AsyncSeq]; char* buffer; } snd_us428_AsyncSeq_t; -typedef struct{ +typedef struct { int submitted; int len; urb_t* urb[0]; @@ -38,7 +38,8 @@ int Seq04Complete; wait_queue_head_t In04WaitQueue; snd_us428_AsyncSeq_t AS04; - int rate; + unsigned int rate, + format; int refframes; purb_t play_urb_waiting[2]; int pipe0Aframes[NRURBS][NRPACKS]; Index: alsa-driver/usb/us428/usbus428audio.c =================================================================== RCS file: /cvsroot/alsa/alsa-driver/usb/us428/usbus428audio.c,v retrieving revision 1.6 diff -u -r1.6 usbus428audio.c --- alsa-driver/usb/us428/usbus428audio.c 24 Oct 2003 13:58:47 -0000 1.6 +++ alsa-driver/usb/us428/usbus428audio.c 3 Nov 2003 10:55:24 -0000 @@ -47,6 +47,7 @@ #include <sound/core.h> #include <sound/info.h> #include <sound/pcm.h> +#include <sound/pcm_params.h> #include <sound/initval.h> #include "usbus428.h" @@ -153,9 +154,9 @@ struct urb *urb) { unsigned long flags; - unsigned char * cp; + unsigned char *cp; int i, len, lens = 0, hwptr_done = subs->hwptr_done; - us428dev_t* us428 = subs->stream->us428; + us428dev_t *us428 = subs->stream->us428; for (i = 0; i < NRPACKS; i++) { cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset; @@ -310,7 +311,7 @@ #if NRPACKS > 1 + urb->iso_frame_desc[1].actual_length #endif - ) / 4; //FIXME !!stride 16 24 Bit!! + ) / subs->stream->us428->stride; spin_lock_irqsave(&subs->lock, flags); @@ -349,7 +350,6 @@ snd_pcm_substream_t *substream = subs->pcm_substream; int err; - if (urb->status) { snd_printk("play urb->status = %i\n", urb->status); urb->status = 0; @@ -390,13 +390,13 @@ int err; if (urb->status) { - snd_printk( "snd_us428_urb_capt_complete(): urb->status = %i\n", urb->status); + snd_printk("snd_us428_urb_capt_complete(): urb->status = %i\n", urb->status); urb->status = 0; return; } if (pcm_captsubs && snd_pcm_running(pcm_captsubs)) runtime = pcm_captsubs->runtime; - if (NULL == runtime){ + if (NULL == runtime) { snd_us428_substream_t *playsubs = captsubs->stream->substream + SNDRV_PCM_STREAM_PLAYBACK; snd_pcm_substream_t *pcm_playsubs = playsubs->pcm_substream; if (pcm_playsubs && snd_pcm_running(pcm_playsubs)) @@ -592,8 +592,7 @@ alive = 0; for (ep = 0; ep < subs->endpoints; ep++) for (i = 0; i < NRURBS; i++) { - if ( subs->dataurb[ep][i] - && subs->dataurb[ep][i]->status) + if (subs->dataurb[ep][i] && subs->dataurb[ep][i]->status) alive++; } if (! alive) @@ -624,11 +623,11 @@ switch (cmd) { case SNDRV_PCM_TRIGGER_START: - snd_printd("snd_us428_pcm_capt_trigger(START )\n"); + snd_printd("snd_us428_pcm_capt_trigger(START)\n"); err = snd_us428_urb_capt_start(subs, substream->runtime); break; case SNDRV_PCM_TRIGGER_STOP: - snd_printd("snd_us428_pcm_capt_trigger(STOP )\n"); + snd_printd("snd_us428_pcm_capt_trigger(STOP)\n"); err = snd_us428_urbs_deactivate(subs); break; default: @@ -647,11 +646,11 @@ switch (cmd) { case SNDRV_PCM_TRIGGER_START: - snd_printd("snd_us428_pcm_play_trigger(START )\n"); + snd_printd("snd_us428_pcm_play_trigger(START)\n"); err = snd_us428_urb_play_start(subs, substream->runtime); break; case SNDRV_PCM_TRIGGER_STOP: - snd_printd("snd_us428_pcm_play_trigger(STOP )\n"); + snd_printd("snd_us428_pcm_play_trigger(STOP)\n"); err = snd_us428_urbs_deactivate(subs); break; default: @@ -759,10 +758,8 @@ static int snd_us428_set_format(snd_us428_substream_t *subs, snd_pcm_runtime_t *runtime) { struct usb_device *dev = subs->stream->us428->chip.dev; - snd_printd("about to set format: format = %s, rate = %d, channels = %d\n", snd_pcm_format_name(runtime->format), runtime->rate, runtime->channels); - /* create data pipes */ if (subs == (subs->stream->substream + SNDRV_PCM_STREAM_PLAYBACK)) { subs->datapipe[0] = usb_sndisocpipe(dev, subs->endpoint[0]); @@ -772,7 +769,6 @@ subs->datapipe[1] = usb_rcvisocpipe(dev, subs->endpoint[1]); subs->maxpacksize = dev->epmaxpacketin[subs->endpoint[0]]; } - return 0; } @@ -957,15 +953,31 @@ static int snd_us428_hw_params( snd_pcm_substream_t* substream, snd_pcm_hw_params_t* hw_params) { - int err = 0, rate = params_rate(hw_params); - snd_us428_stream_t* us428_stream = snd_pcm_substream_chip(substream); - + int err = 0; + unsigned int rate = params_rate(hw_params), + format = params_format(hw_params); + snd_us428_stream_t *us428_stream = snd_pcm_substream_chip(substream); + if (us428_stream->us428->format != format) { + int alternate; + if (format == SNDRV_PCM_FORMAT_S24_3LE) { + alternate = 2; + us428_stream->us428->stride = 6; + } else { + alternate = 1; + us428_stream->us428->stride = 4; + } + if ((err = usb_set_interface(us428_stream->us428->chip.dev, 0, alternate))) { + snd_printk("usb_set_interface error \n"); + return err; + } + us428_stream->us428->format = format; + us428_stream->us428->rate = 0; + } if (us428_stream->us428->rate != rate) err = us428_rate_set(us428_stream, rate); - if (0 == err) { if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) - snd_printd("snd_pcm_lib_malloc_pages(%x, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err); + snd_printd("snd_pcm_lib_malloc_pages(%x, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err); } return err; } @@ -1001,7 +1013,7 @@ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE, .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, .rate_min = 44100, .rate_max = 48000, @@ -1020,7 +1032,7 @@ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE, .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, .rate_min = 44100, .rate_max = 48000, @@ -1037,18 +1049,14 @@ static int snd_usb_pcm_open(snd_pcm_substream_t *substream, int direction, snd_pcm_hardware_t *hw) { - snd_us428_stream_t *as = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - snd_us428_substream_t *subs = &as->substream[direction]; + snd_us428_stream_t *as = snd_pcm_substream_chip(substream); + snd_pcm_runtime_t *runtime = substream->runtime; + snd_us428_substream_t *subs = &as->substream[direction]; runtime->hw = *hw; - runtime->private_data = subs; subs->pcm_substream = substream; - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, - 1000, - 200000); - + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000); return 0; }