23 #include <linux/kernel.h>
26 #include <linux/sound.h>
28 #include <linux/soundcard.h>
29 #include <linux/slab.h>
32 #include <linux/module.h>
46 #define dprintk(fmt, arg...) do { \
48 printk(KERN_INFO "cx231xx-audio %s: " fmt, \
54 static int cx231xx_isoc_audio_deinit(
struct cx231xx *
dev)
61 if (dev->
adev.urb[i]) {
78 static int cx231xx_bulk_audio_deinit(
struct cx231xx *
dev)
85 if (dev->
adev.urb[i]) {
102 static void cx231xx_audio_isocirq(
struct urb *
urb)
104 struct cx231xx *dev = urb->context;
107 int period_elapsed = 0;
117 switch (urb->status) {
126 dprintk(
"urb completition error %d.\n", urb->status);
133 if (dev->
adev.capture_pcm_substream) {
134 substream = dev->
adev.capture_pcm_substream;
138 for (i = 0; i < urb->number_of_packets; i++) {
139 int length = urb->iso_frame_desc[
i].actual_length /
141 cp = (
unsigned char *)urb->transfer_buffer +
142 urb->iso_frame_desc[i].offset;
147 oldptr = dev->
adev.hwptr_done_capture;
155 length * stride - cnt * stride);
161 snd_pcm_stream_lock(substream);
164 if (dev->
adev.hwptr_done_capture >=
166 dev->
adev.hwptr_done_capture -=
170 if (dev->
adev.capture_transfer_done >=
172 dev->
adev.capture_transfer_done -=
176 snd_pcm_stream_unlock(substream);
191 static void cx231xx_audio_bulkirq(
struct urb *urb)
193 struct cx231xx *dev = urb->context;
195 int period_elapsed = 0;
205 switch (urb->status) {
214 dprintk(
"urb completition error %d.\n", urb->status);
221 if (dev->
adev.capture_pcm_substream) {
222 substream = dev->
adev.capture_pcm_substream;
227 int length = urb->actual_length /
229 cp = (
unsigned char *)urb->transfer_buffer;
231 oldptr = dev->
adev.hwptr_done_capture;
239 length * stride - cnt * stride);
245 snd_pcm_stream_lock(substream);
248 if (dev->
adev.hwptr_done_capture >=
250 dev->
adev.hwptr_done_capture -=
254 if (dev->
adev.capture_transfer_done >=
256 dev->
adev.capture_transfer_done -=
260 snd_pcm_stream_unlock(substream);
275 static int cx231xx_init_audio_isoc(
struct cx231xx *dev)
280 cx231xx_info(
"%s: Starting ISO AUDIO transfers\n", __func__);
292 if (!dev->
adev.transfer_buffer[i])
295 memset(dev->
adev.transfer_buffer[i], 0x80, sb_size);
299 for (j = 0; j <
i; j++) {
306 urb->dev = dev->
udev;
308 urb->pipe = usb_rcvisocpipe(dev->
udev,
309 dev->
adev.end_point_addr);
310 urb->transfer_flags = URB_ISO_ASAP;
311 urb->transfer_buffer = dev->
adev.transfer_buffer[
i];
313 urb->complete = cx231xx_audio_isocirq;
315 urb->transfer_buffer_length = sb_size;
318 j++, k += dev->
adev.max_pkt_size) {
319 urb->iso_frame_desc[
j].offset =
k;
320 urb->iso_frame_desc[
j].length = dev->
adev.max_pkt_size;
328 cx231xx_isoc_audio_deinit(dev);
336 static int cx231xx_init_audio_bulk(
struct cx231xx *dev)
341 cx231xx_info(
"%s: Starting BULK AUDIO transfers\n", __func__);
353 if (!dev->
adev.transfer_buffer[i])
356 memset(dev->
adev.transfer_buffer[i], 0x80, sb_size);
360 for (j = 0; j <
i; j++) {
367 urb->dev = dev->
udev;
369 urb->pipe = usb_rcvbulkpipe(dev->
udev,
370 dev->
adev.end_point_addr);
371 urb->transfer_flags = 0;
372 urb->transfer_buffer = dev->
adev.transfer_buffer[
i];
373 urb->complete = cx231xx_audio_bulkirq;
374 urb->transfer_buffer_length = sb_size;
383 cx231xx_bulk_audio_deinit(dev);
396 dprintk(
"Allocating vbuffer\n");
426 .buffer_bytes_max = 62720 * 8,
427 .period_bytes_min = 64,
428 .period_bytes_max = 12544,
439 dprintk(
"opening device and trying to acquire exclusive lock\n");
443 " Can't proceed with open\n");
469 runtime->
hw = snd_cx231xx_hw_capture;
479 dev->
adev.capture_pcm_substream = substream;
510 if (dev->
adev.users == 0 && dev->
adev.shutdown == 1) {
512 dprintk(
"disabling audio stream!\n");
513 dev->
adev.shutdown = 0;
528 dprintk(
"Setting capture parameters\n");
530 ret = snd_pcm_alloc_vmalloc_buffer(substream,
550 dprintk(
"Stop capture, if needed\n");
564 dev->
adev.hwptr_done_capture = 0;
565 dev->
adev.capture_transfer_done = 0;
579 cx231xx_init_audio_isoc(dev);
581 cx231xx_init_audio_bulk(dev);
584 cx231xx_isoc_audio_deinit(dev);
597 spin_lock(&dev->
adev.slock);
609 spin_unlock(&dev->
adev.slock);
626 hwptr_done = dev->
adev.hwptr_done_capture;
627 spin_unlock_irqrestore(&dev->
adev.slock, flags);
640 static struct snd_pcm_ops snd_cx231xx_pcm_capture = {
641 .open = snd_cx231xx_capture_open,
642 .close = snd_cx231xx_pcm_close,
644 .hw_params = snd_cx231xx_hw_capture_params,
645 .hw_free = snd_cx231xx_hw_capture_free,
646 .prepare = snd_cx231xx_prepare,
647 .trigger = snd_cx231xx_capture_trigger,
648 .pointer = snd_cx231xx_capture_pointer,
649 .page = snd_pcm_get_vmalloc_page,
652 static int cx231xx_audio_init(
struct cx231xx *dev)
660 int i, isoc_pipe = 0;
670 "non standard usbaudio\n");
678 err =
snd_pcm_new(card,
"Cx231xx Audio", 0, 0, 1, &pcm);
685 &snd_cx231xx_pcm_capture);
688 strcpy(pcm->
name,
"Conexant cx231xx Capture");
707 hs_config_info[0].interface_info.
711 le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
714 adev->
num_alt = uif->num_altsetting;
715 cx231xx_info(
"EndPoint Addr 0x%x, Alternate settings: %i\n",
724 for (i = 0; i < adev->
num_alt; i++) {
726 le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
729 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
737 static int cx231xx_audio_fini(
struct cx231xx *dev)
749 if (dev->
adev.sndcard) {
760 .name =
"Cx231xx Audio Extension",
761 .init = cx231xx_audio_init,
762 .fini = cx231xx_audio_fini,
765 static int __init cx231xx_alsa_register(
void)
770 static void __exit cx231xx_alsa_unregister(
void)