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