root/drivers/media/usb/cx231xx/cx231xx-audio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cx231xx_isoc_audio_deinit
  2. cx231xx_bulk_audio_deinit
  3. cx231xx_audio_isocirq
  4. cx231xx_audio_bulkirq
  5. cx231xx_init_audio_isoc
  6. cx231xx_init_audio_bulk
  7. snd_pcm_alloc_vmalloc_buffer
  8. snd_cx231xx_capture_open
  9. snd_cx231xx_pcm_close
  10. snd_cx231xx_hw_capture_params
  11. snd_cx231xx_hw_capture_free
  12. snd_cx231xx_prepare
  13. audio_trigger
  14. snd_cx231xx_capture_trigger
  15. snd_cx231xx_capture_pointer
  16. snd_pcm_get_vmalloc_page
  17. cx231xx_audio_init
  18. cx231xx_audio_fini
  19. cx231xx_alsa_register
  20. cx231xx_alsa_unregister

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

/* [<][>][^][v][top][bottom][index][help] */