1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Conexant Cx231xx audio extension
4  *
5  *  Copyright (C) 2008 <srinivasa.deevi at conexant dot com>
6  *       Based on em28xx driver
7  */
8 
9 #include "cx231xx.h"
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/sound.h>
13 #include <linux/spinlock.h>
14 #include <linux/soundcard.h>
15 #include <linux/slab.h>
16 #include <linux/vmalloc.h>
17 #include <linux/module.h>
18 #include <sound/core.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/info.h>
22 #include <sound/initval.h>
23 #include <sound/control.h>
24 #include <media/v4l2-common.h>
25 
26 static int debug;
27 module_param(debug, int, 0644);
28 MODULE_PARM_DESC(debug, "activates debug info");
29 
30 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
31 
32 static int cx231xx_isoc_audio_deinit(struct cx231xx *dev)
33 {
34 	int i;
35 
36 	dev_dbg(dev->dev, "Stopping isoc\n");
37 
38 	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
39 		if (dev->adev.urb[i]) {
40 			if (!irqs_disabled())
41 				usb_kill_urb(dev->adev.urb[i]);
42 			else
43 				usb_unlink_urb(dev->adev.urb[i]);
44 
45 			usb_free_urb(dev->adev.urb[i]);
46 			dev->adev.urb[i] = NULL;
47 
48 			kfree(dev->adev.transfer_buffer[i]);
49 			dev->adev.transfer_buffer[i] = NULL;
50 		}
51 	}
52 
53 	return 0;
54 }
55 
56 static int cx231xx_bulk_audio_deinit(struct cx231xx *dev)
57 {
58 	int i;
59 
60 	dev_dbg(dev->dev, "Stopping bulk\n");
61 
62 	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
63 		if (dev->adev.urb[i]) {
64 			if (!irqs_disabled())
65 				usb_kill_urb(dev->adev.urb[i]);
66 			else
67 				usb_unlink_urb(dev->adev.urb[i]);
68 
69 			usb_free_urb(dev->adev.urb[i]);
70 			dev->adev.urb[i] = NULL;
71 
72 			kfree(dev->adev.transfer_buffer[i]);
73 			dev->adev.transfer_buffer[i] = NULL;
74 		}
75 	}
76 
77 	return 0;
78 }
79 
80 static void cx231xx_audio_isocirq(struct urb *urb)
81 {
82 	struct cx231xx *dev = urb->context;
83 	int i;
84 	unsigned int oldptr;
85 	int period_elapsed = 0;
86 	int status;
87 	unsigned char *cp;
88 	unsigned int stride;
89 	struct snd_pcm_substream *substream;
90 	struct snd_pcm_runtime *runtime;
91 
92 	if (dev->state & DEV_DISCONNECTED)
93 		return;
94 
95 	switch (urb->status) {
96 	case 0:		/* success */
97 	case -ETIMEDOUT:	/* NAK */
98 		break;
99 	case -ECONNRESET:	/* kill */
100 	case -ENOENT:
101 	case -ESHUTDOWN:
102 		return;
103 	default:		/* error */
104 		dev_dbg(dev->dev, "urb completion error %d.\n",
105 			urb->status);
106 		break;
107 	}
108 
109 	if (atomic_read(&dev->stream_started) == 0)
110 		return;
111 
112 	if (dev->adev.capture_pcm_substream) {
113 		substream = dev->adev.capture_pcm_substream;
114 		runtime = substream->runtime;
115 		stride = runtime->frame_bits >> 3;
116 
117 		for (i = 0; i < urb->number_of_packets; i++) {
118 			unsigned long flags;
119 			int length = urb->iso_frame_desc[i].actual_length /
120 				     stride;
121 			cp = (unsigned char *)urb->transfer_buffer +
122 					      urb->iso_frame_desc[i].offset;
123 
124 			if (!length)
125 				continue;
126 
127 			oldptr = dev->adev.hwptr_done_capture;
128 			if (oldptr + length >= runtime->buffer_size) {
129 				unsigned int cnt;
130 
131 				cnt = runtime->buffer_size - oldptr;
132 				memcpy(runtime->dma_area + oldptr * stride, cp,
133 				       cnt * stride);
134 				memcpy(runtime->dma_area, cp + cnt * stride,
135 				       length * stride - cnt * stride);
136 			} else {
137 				memcpy(runtime->dma_area + oldptr * stride, cp,
138 				       length * stride);
139 			}
140 
141 			snd_pcm_stream_lock_irqsave(substream, flags);
142 
143 			dev->adev.hwptr_done_capture += length;
144 			if (dev->adev.hwptr_done_capture >=
145 						runtime->buffer_size)
146 				dev->adev.hwptr_done_capture -=
147 						runtime->buffer_size;
148 
149 			dev->adev.capture_transfer_done += length;
150 			if (dev->adev.capture_transfer_done >=
151 				runtime->period_size) {
152 				dev->adev.capture_transfer_done -=
153 						runtime->period_size;
154 				period_elapsed = 1;
155 			}
156 			snd_pcm_stream_unlock_irqrestore(substream, flags);
157 		}
158 		if (period_elapsed)
159 			snd_pcm_period_elapsed(substream);
160 	}
161 	urb->status = 0;
162 
163 	status = usb_submit_urb(urb, GFP_ATOMIC);
164 	if (status < 0) {
165 		dev_err(dev->dev,
166 			"resubmit of audio urb failed (error=%i)\n",
167 			status);
168 	}
169 	return;
170 }
171 
172 static void cx231xx_audio_bulkirq(struct urb *urb)
173 {
174 	struct cx231xx *dev = urb->context;
175 	unsigned int oldptr;
176 	int period_elapsed = 0;
177 	int status;
178 	unsigned char *cp;
179 	unsigned int stride;
180 	struct snd_pcm_substream *substream;
181 	struct snd_pcm_runtime *runtime;
182 
183 	if (dev->state & DEV_DISCONNECTED)
184 		return;
185 
186 	switch (urb->status) {
187 	case 0:		/* success */
188 	case -ETIMEDOUT:	/* NAK */
189 		break;
190 	case -ECONNRESET:	/* kill */
191 	case -ENOENT:
192 	case -ESHUTDOWN:
193 		return;
194 	default:		/* error */
195 		dev_dbg(dev->dev, "urb completion error %d.\n",
196 			urb->status);
197 		break;
198 	}
199 
200 	if (atomic_read(&dev->stream_started) == 0)
201 		return;
202 
203 	if (dev->adev.capture_pcm_substream) {
204 		substream = dev->adev.capture_pcm_substream;
205 		runtime = substream->runtime;
206 		stride = runtime->frame_bits >> 3;
207 
208 		if (1) {
209 			unsigned long flags;
210 			int length = urb->actual_length /
211 				     stride;
212 			cp = (unsigned char *)urb->transfer_buffer;
213 
214 			oldptr = dev->adev.hwptr_done_capture;
215 			if (oldptr + length >= runtime->buffer_size) {
216 				unsigned int cnt;
217 
218 				cnt = runtime->buffer_size - oldptr;
219 				memcpy(runtime->dma_area + oldptr * stride, cp,
220 				       cnt * stride);
221 				memcpy(runtime->dma_area, cp + cnt * stride,
222 				       length * stride - cnt * stride);
223 			} else {
224 				memcpy(runtime->dma_area + oldptr * stride, cp,
225 				       length * stride);
226 			}
227 
228 			snd_pcm_stream_lock_irqsave(substream, flags);
229 
230 			dev->adev.hwptr_done_capture += length;
231 			if (dev->adev.hwptr_done_capture >=
232 						runtime->buffer_size)
233 				dev->adev.hwptr_done_capture -=
234 						runtime->buffer_size;
235 
236 			dev->adev.capture_transfer_done += length;
237 			if (dev->adev.capture_transfer_done >=
238 				runtime->period_size) {
239 				dev->adev.capture_transfer_done -=
240 						runtime->period_size;
241 				period_elapsed = 1;
242 			}
243 			snd_pcm_stream_unlock_irqrestore(substream, flags);
244 		}
245 		if (period_elapsed)
246 			snd_pcm_period_elapsed(substream);
247 	}
248 	urb->status = 0;
249 
250 	status = usb_submit_urb(urb, GFP_ATOMIC);
251 	if (status < 0) {
252 		dev_err(dev->dev,
253 			"resubmit of audio urb failed (error=%i)\n",
254 			status);
255 	}
256 	return;
257 }
258 
259 static int cx231xx_init_audio_isoc(struct cx231xx *dev)
260 {
261 	int i, errCode;
262 	int sb_size;
263 
264 	dev_dbg(dev->dev,
265 		"%s: Starting ISO AUDIO transfers\n", __func__);
266 
267 	if (dev->state & DEV_DISCONNECTED)
268 		return -ENODEV;
269 
270 	sb_size = CX231XX_ISO_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
271 
272 	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
273 		struct urb *urb;
274 		int j, k;
275 
276 		dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
277 		if (!dev->adev.transfer_buffer[i])
278 			return -ENOMEM;
279 
280 		memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
281 		urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC);
282 		if (!urb) {
283 			for (j = 0; j < i; j++) {
284 				usb_free_urb(dev->adev.urb[j]);
285 				kfree(dev->adev.transfer_buffer[j]);
286 			}
287 			return -ENOMEM;
288 		}
289 
290 		urb->dev = dev->udev;
291 		urb->context = dev;
292 		urb->pipe = usb_rcvisocpipe(dev->udev,
293 						dev->adev.end_point_addr);
294 		urb->transfer_flags = URB_ISO_ASAP;
295 		urb->transfer_buffer = dev->adev.transfer_buffer[i];
296 		urb->interval = 1;
297 		urb->complete = cx231xx_audio_isocirq;
298 		urb->number_of_packets = CX231XX_ISO_NUM_AUDIO_PACKETS;
299 		urb->transfer_buffer_length = sb_size;
300 
301 		for (j = k = 0; j < CX231XX_ISO_NUM_AUDIO_PACKETS;
302 			j++, k += dev->adev.max_pkt_size) {
303 			urb->iso_frame_desc[j].offset = k;
304 			urb->iso_frame_desc[j].length = dev->adev.max_pkt_size;
305 		}
306 		dev->adev.urb[i] = urb;
307 	}
308 
309 	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
310 		errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
311 		if (errCode < 0) {
312 			cx231xx_isoc_audio_deinit(dev);
313 			return errCode;
314 		}
315 	}
316 
317 	return errCode;
318 }
319 
320 static int cx231xx_init_audio_bulk(struct cx231xx *dev)
321 {
322 	int i, errCode;
323 	int sb_size;
324 
325 	dev_dbg(dev->dev,
326 		"%s: Starting BULK AUDIO transfers\n", __func__);
327 
328 	if (dev->state & DEV_DISCONNECTED)
329 		return -ENODEV;
330 
331 	sb_size = CX231XX_NUM_AUDIO_PACKETS * dev->adev.max_pkt_size;
332 
333 	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
334 		struct urb *urb;
335 		int j;
336 
337 		dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
338 		if (!dev->adev.transfer_buffer[i])
339 			return -ENOMEM;
340 
341 		memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
342 		urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
343 		if (!urb) {
344 			for (j = 0; j < i; j++) {
345 				usb_free_urb(dev->adev.urb[j]);
346 				kfree(dev->adev.transfer_buffer[j]);
347 			}
348 			return -ENOMEM;
349 		}
350 
351 		urb->dev = dev->udev;
352 		urb->context = dev;
353 		urb->pipe = usb_rcvbulkpipe(dev->udev,
354 						dev->adev.end_point_addr);
355 		urb->transfer_flags = 0;
356 		urb->transfer_buffer = dev->adev.transfer_buffer[i];
357 		urb->complete = cx231xx_audio_bulkirq;
358 		urb->transfer_buffer_length = sb_size;
359 
360 		dev->adev.urb[i] = urb;
361 
362 	}
363 
364 	for (i = 0; i < CX231XX_AUDIO_BUFS; i++) {
365 		errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
366 		if (errCode < 0) {
367 			cx231xx_bulk_audio_deinit(dev);
368 			return errCode;
369 		}
370 	}
371 
372 	return errCode;
373 }
374 
375 static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
376 					size_t size)
377 {
378 	struct snd_pcm_runtime *runtime = subs->runtime;
379 	struct cx231xx *dev = snd_pcm_substream_chip(subs);
380 
381 	dev_dbg(dev->dev, "Allocating vbuffer\n");
382 	if (runtime->dma_area) {
383 		if (runtime->dma_bytes > size)
384 			return 0;
385 
386 		vfree(runtime->dma_area);
387 	}
388 	runtime->dma_area = vmalloc(size);
389 	if (!runtime->dma_area)
390 		return -ENOMEM;
391 
392 	runtime->dma_bytes = size;
393 
394 	return 0;
395 }
396 
397 static const struct snd_pcm_hardware snd_cx231xx_hw_capture = {
398 	.info = SNDRV_PCM_INFO_BLOCK_TRANSFER	|
399 	    SNDRV_PCM_INFO_MMAP			|
400 	    SNDRV_PCM_INFO_INTERLEAVED		|
401 	    SNDRV_PCM_INFO_MMAP_VALID,
402 
403 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
404 
405 	.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,
406 
407 	.rate_min = 48000,
408 	.rate_max = 48000,
409 	.channels_min = 2,
410 	.channels_max = 2,
411 	.buffer_bytes_max = 62720 * 8,	/* just about the value in usbaudio.c */
412 	.period_bytes_min = 64,		/* 12544/2, */
413 	.period_bytes_max = 12544,
414 	.periods_min = 2,
415 	.periods_max = 98,		/* 12544, */
416 };
417 
418 static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream)
419 {
420 	struct cx231xx *dev = snd_pcm_substream_chip(substream);
421 	struct snd_pcm_runtime *runtime = substream->runtime;
422 	int ret = 0;
423 
424 	dev_dbg(dev->dev,
425 		"opening device and trying to acquire exclusive lock\n");
426 
427 	if (dev->state & DEV_DISCONNECTED) {
428 		dev_err(dev->dev,
429 			"Can't open. the device was removed.\n");
430 		return -ENODEV;
431 	}
432 
433 	/* set alternate setting for audio interface */
434 	/* 1 - 48000 samples per sec */
435 	mutex_lock(&dev->lock);
436 	if (dev->USE_ISO)
437 		ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 1);
438 	else
439 		ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0);
440 	mutex_unlock(&dev->lock);
441 	if (ret < 0) {
442 		dev_err(dev->dev,
443 			"failed to set alternate setting !\n");
444 
445 		return ret;
446 	}
447 
448 	runtime->hw = snd_cx231xx_hw_capture;
449 
450 	mutex_lock(&dev->lock);
451 	/* inform hardware to start streaming */
452 	ret = cx231xx_capture_start(dev, 1, Audio);
453 
454 	dev->adev.users++;
455 	mutex_unlock(&dev->lock);
456 
457 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
458 	dev->adev.capture_pcm_substream = substream;
459 	runtime->private_data = dev;
460 
461 	return 0;
462 }
463 
464 static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream)
465 {
466 	int ret;
467 	struct cx231xx *dev = snd_pcm_substream_chip(substream);
468 
469 	dev_dbg(dev->dev, "closing device\n");
470 
471 	/* inform hardware to stop streaming */
472 	mutex_lock(&dev->lock);
473 	ret = cx231xx_capture_start(dev, 0, Audio);
474 
475 	/* set alternate setting for audio interface */
476 	/* 1 - 48000 samples per sec */
477 	ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0);
478 	if (ret < 0) {
479 		dev_err(dev->dev,
480 			"failed to set alternate setting !\n");
481 
482 		mutex_unlock(&dev->lock);
483 		return ret;
484 	}
485 
486 	dev->adev.users--;
487 	if (substream->runtime->dma_area) {
488 		dev_dbg(dev->dev, "freeing\n");
489 		vfree(substream->runtime->dma_area);
490 		substream->runtime->dma_area = NULL;
491 	}
492 	mutex_unlock(&dev->lock);
493 
494 	if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
495 		dev_dbg(dev->dev, "audio users: %d\n", dev->adev.users);
496 		dev_dbg(dev->dev, "disabling audio stream!\n");
497 		dev->adev.shutdown = 0;
498 		dev_dbg(dev->dev, "released lock\n");
499 		if (atomic_read(&dev->stream_started) > 0) {
500 			atomic_set(&dev->stream_started, 0);
501 			schedule_work(&dev->wq_trigger);
502 		}
503 	}
504 	return 0;
505 }
506 
507 static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream,
508 					 struct snd_pcm_hw_params *hw_params)
509 {
510 	struct cx231xx *dev = snd_pcm_substream_chip(substream);
511 	int ret;
512 
513 	dev_dbg(dev->dev, "Setting capture parameters\n");
514 
515 	ret = snd_pcm_alloc_vmalloc_buffer(substream,
516 					   params_buffer_bytes(hw_params));
517 #if 0
518 	/* TODO: set up cx231xx audio chip to deliver the correct audio format,
519 	   current default is 48000hz multiplexed => 96000hz mono
520 	   which shouldn't matter since analogue TV only supports mono */
521 	unsigned int channels, rate, format;
522 
523 	format = params_format(hw_params);
524 	rate = params_rate(hw_params);
525 	channels = params_channels(hw_params);
526 #endif
527 
528 	return ret;
529 }
530 
531 static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream)
532 {
533 	struct cx231xx *dev = snd_pcm_substream_chip(substream);
534 
535 	dev_dbg(dev->dev, "Stop capture, if needed\n");
536 
537 	if (atomic_read(&dev->stream_started) > 0) {
538 		atomic_set(&dev->stream_started, 0);
539 		schedule_work(&dev->wq_trigger);
540 	}
541 
542 	return 0;
543 }
544 
545 static int snd_cx231xx_prepare(struct snd_pcm_substream *substream)
546 {
547 	struct cx231xx *dev = snd_pcm_substream_chip(substream);
548 
549 	dev->adev.hwptr_done_capture = 0;
550 	dev->adev.capture_transfer_done = 0;
551 
552 	return 0;
553 }
554 
555 static void audio_trigger(struct work_struct *work)
556 {
557 	struct cx231xx *dev = container_of(work, struct cx231xx, wq_trigger);
558 
559 	if (atomic_read(&dev->stream_started)) {
560 		dev_dbg(dev->dev, "starting capture");
561 		if (is_fw_load(dev) == 0)
562 			cx25840_call(dev, core, load_fw);
563 		if (dev->USE_ISO)
564 			cx231xx_init_audio_isoc(dev);
565 		else
566 			cx231xx_init_audio_bulk(dev);
567 	} else {
568 		dev_dbg(dev->dev, "stopping capture");
569 		cx231xx_isoc_audio_deinit(dev);
570 	}
571 }
572 
573 static int snd_cx231xx_capture_trigger(struct snd_pcm_substream *substream,
574 				       int cmd)
575 {
576 	struct cx231xx *dev = snd_pcm_substream_chip(substream);
577 	int retval = 0;
578 
579 	if (dev->state & DEV_DISCONNECTED)
580 		return -ENODEV;
581 
582 	spin_lock(&dev->adev.slock);
583 	switch (cmd) {
584 	case SNDRV_PCM_TRIGGER_START:
585 		atomic_set(&dev->stream_started, 1);
586 		break;
587 	case SNDRV_PCM_TRIGGER_STOP:
588 		atomic_set(&dev->stream_started, 0);
589 		break;
590 	default:
591 		retval = -EINVAL;
592 		break;
593 	}
594 	spin_unlock(&dev->adev.slock);
595 
596 	schedule_work(&dev->wq_trigger);
597 
598 	return retval;
599 }
600 
601 static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream
602 						     *substream)
603 {
604 	struct cx231xx *dev;
605 	unsigned long flags;
606 	snd_pcm_uframes_t hwptr_done;
607 
608 	dev = snd_pcm_substream_chip(substream);
609 
610 	spin_lock_irqsave(&dev->adev.slock, flags);
611 	hwptr_done = dev->adev.hwptr_done_capture;
612 	spin_unlock_irqrestore(&dev->adev.slock, flags);
613 
614 	return hwptr_done;
615 }
616 
617 static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
618 					     unsigned long offset)
619 {
620 	void *pageptr = subs->runtime->dma_area + offset;
621 
622 	return vmalloc_to_page(pageptr);
623 }
624 
625 static const struct snd_pcm_ops snd_cx231xx_pcm_capture = {
626 	.open = snd_cx231xx_capture_open,
627 	.close = snd_cx231xx_pcm_close,
628 	.ioctl = snd_pcm_lib_ioctl,
629 	.hw_params = snd_cx231xx_hw_capture_params,
630 	.hw_free = snd_cx231xx_hw_capture_free,
631 	.prepare = snd_cx231xx_prepare,
632 	.trigger = snd_cx231xx_capture_trigger,
633 	.pointer = snd_cx231xx_capture_pointer,
634 	.page = snd_pcm_get_vmalloc_page,
635 };
636 
637 static int cx231xx_audio_init(struct cx231xx *dev)
638 {
639 	struct cx231xx_audio *adev = &dev->adev;
640 	struct snd_pcm *pcm;
641 	struct snd_card *card;
642 	static int devnr;
643 	int err;
644 	struct usb_interface *uif;
645 	int i, isoc_pipe = 0;
646 
647 	if (dev->has_alsa_audio != 1) {
648 		/* This device does not support the extension (in this case
649 		   the device is expecting the snd-usb-audio module or
650 		   doesn't have analog audio support at all) */
651 		return 0;
652 	}
653 
654 	dev_dbg(dev->dev,
655 		"probing for cx231xx non standard usbaudio\n");
656 
657 	err = snd_card_new(dev->dev, index[devnr], "Cx231xx Audio",
658 			   THIS_MODULE, 0, &card);
659 	if (err < 0)
660 		return err;
661 
662 	spin_lock_init(&adev->slock);
663 	err = snd_pcm_new(card, "Cx231xx Audio", 0, 0, 1, &pcm);
664 	if (err < 0)
665 		goto err_free_card;
666 
667 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
668 			&snd_cx231xx_pcm_capture);
669 	pcm->info_flags = 0;
670 	pcm->private_data = dev;
671 	strscpy(pcm->name, "Conexant cx231xx Capture", sizeof(pcm->name));
672 	strscpy(card->driver, "Cx231xx-Audio", sizeof(card->driver));
673 	strscpy(card->shortname, "Cx231xx Audio", sizeof(card->shortname));
674 	strscpy(card->longname, "Conexant cx231xx Audio", sizeof(card->longname));
675 
676 	INIT_WORK(&dev->wq_trigger, audio_trigger);
677 
678 	err = snd_card_register(card);
679 	if (err < 0)
680 		goto err_free_card;
681 
682 	adev->sndcard = card;
683 	adev->udev = dev->udev;
684 
685 	/* compute alternate max packet sizes for Audio */
686 	uif =
687 	    dev->udev->actconfig->interface[dev->current_pcb_config.
688 					    hs_config_info[0].interface_info.
689 					    audio_index + 1];
690 
691 	if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) {
692 		err = -ENODEV;
693 		goto err_free_card;
694 	}
695 
696 	adev->end_point_addr =
697 	    uif->altsetting[0].endpoint[isoc_pipe].desc.
698 			bEndpointAddress;
699 
700 	adev->num_alt = uif->num_altsetting;
701 	dev_info(dev->dev,
702 		"audio EndPoint Addr 0x%x, Alternate settings: %i\n",
703 		adev->end_point_addr, adev->num_alt);
704 	adev->alt_max_pkt_size = kmalloc_array(32, adev->num_alt, GFP_KERNEL);
705 	if (!adev->alt_max_pkt_size) {
706 		err = -ENOMEM;
707 		goto err_free_card;
708 	}
709 
710 	for (i = 0; i < adev->num_alt; i++) {
711 		u16 tmp;
712 
713 		if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) {
714 			err = -ENODEV;
715 			goto err_free_pkt_size;
716 		}
717 
718 		tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
719 				wMaxPacketSize);
720 		adev->alt_max_pkt_size[i] =
721 		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
722 		dev_dbg(dev->dev,
723 			"audio alternate setting %i, max size= %i\n", i,
724 			adev->alt_max_pkt_size[i]);
725 	}
726 
727 	return 0;
728 
729 err_free_pkt_size:
730 	kfree(adev->alt_max_pkt_size);
731 err_free_card:
732 	snd_card_free(card);
733 
734 	return err;
735 }
736 
737 static int cx231xx_audio_fini(struct cx231xx *dev)
738 {
739 	if (dev == NULL)
740 		return 0;
741 
742 	if (dev->has_alsa_audio != 1) {
743 		/* This device does not support the extension (in this case
744 		   the device is expecting the snd-usb-audio module or
745 		   doesn't have analog audio support at all) */
746 		return 0;
747 	}
748 
749 	if (dev->adev.sndcard) {
750 		snd_card_free(dev->adev.sndcard);
751 		kfree(dev->adev.alt_max_pkt_size);
752 		dev->adev.sndcard = NULL;
753 	}
754 
755 	return 0;
756 }
757 
758 static struct cx231xx_ops audio_ops = {
759 	.id = CX231XX_AUDIO,
760 	.name = "Cx231xx Audio Extension",
761 	.init = cx231xx_audio_init,
762 	.fini = cx231xx_audio_fini,
763 };
764 
765 static int __init cx231xx_alsa_register(void)
766 {
767 	return cx231xx_register_extension(&audio_ops);
768 }
769 
770 static void __exit cx231xx_alsa_unregister(void)
771 {
772 	cx231xx_unregister_extension(&audio_ops);
773 }
774 
775 MODULE_LICENSE("GPL");
776 MODULE_AUTHOR("Srinivasa Deevi <srinivasa.deevi@conexant.com>");
777 MODULE_DESCRIPTION("Cx231xx Audio driver");
778 
779 module_init(cx231xx_alsa_register);
780 module_exit(cx231xx_alsa_unregister);
781