Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.38 581 lines 15 kB view raw
1/* 2 * Line6 Linux USB driver - 0.9.1beta 3 * 4 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation, version 2. 9 * 10 */ 11 12#include <sound/core.h> 13#include <sound/pcm.h> 14#include <sound/pcm_params.h> 15 16#include "audio.h" 17#include "capture.h" 18#include "driver.h" 19#include "pcm.h" 20#include "pod.h" 21#include "playback.h" 22 23/* 24 Software stereo volume control. 25*/ 26static void change_volume(struct urb *urb_out, int volume[], 27 int bytes_per_frame) 28{ 29 int chn = 0; 30 31 if (volume[0] == 256 && volume[1] == 256) 32 return; /* maximum volume - no change */ 33 34 if (bytes_per_frame == 4) { 35 short *p, *buf_end; 36 p = (short *)urb_out->transfer_buffer; 37 buf_end = p + urb_out->transfer_buffer_length / sizeof(*p); 38 39 for (; p < buf_end; ++p) { 40 *p = (*p * volume[chn & 1]) >> 8; 41 ++chn; 42 } 43 } else if (bytes_per_frame == 6) { 44 unsigned char *p, *buf_end; 45 p = (unsigned char *)urb_out->transfer_buffer; 46 buf_end = p + urb_out->transfer_buffer_length; 47 48 for (; p < buf_end; p += 3) { 49 int val; 50 val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16); 51 val = (val * volume[chn & 1]) >> 8; 52 p[0] = val; 53 p[1] = val >> 8; 54 p[2] = val >> 16; 55 ++chn; 56 } 57 } 58} 59 60#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 61 62/* 63 Create signal for impulse response test. 64*/ 65static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm, 66 struct urb *urb_out, int bytes_per_frame) 67{ 68 int frames = urb_out->transfer_buffer_length / bytes_per_frame; 69 70 if (bytes_per_frame == 4) { 71 int i; 72 short *pi = (short *)line6pcm->prev_fbuf; 73 short *po = (short *)urb_out->transfer_buffer; 74 75 for (i = 0; i < frames; ++i) { 76 po[0] = pi[0]; 77 po[1] = 0; 78 pi += 2; 79 po += 2; 80 } 81 } else if (bytes_per_frame == 6) { 82 int i, j; 83 unsigned char *pi = line6pcm->prev_fbuf; 84 unsigned char *po = urb_out->transfer_buffer; 85 86 for (i = 0; i < frames; ++i) { 87 for (j = 0; j < bytes_per_frame / 2; ++j) 88 po[j] = pi[j]; 89 90 for (; j < bytes_per_frame; ++j) 91 po[j] = 0; 92 93 pi += bytes_per_frame; 94 po += bytes_per_frame; 95 } 96 } 97 if (--line6pcm->impulse_count <= 0) { 98 ((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame - 99 1] = 100 line6pcm->impulse_volume; 101 line6pcm->impulse_count = line6pcm->impulse_period; 102 } 103} 104 105#endif 106 107/* 108 Add signal to buffer for software monitoring. 109*/ 110static void add_monitor_signal(struct urb *urb_out, unsigned char *signal, 111 int volume, int bytes_per_frame) 112{ 113 if (volume == 0) 114 return; /* zero volume - no change */ 115 116 if (bytes_per_frame == 4) { 117 short *pi, *po, *buf_end; 118 pi = (short *)signal; 119 po = (short *)urb_out->transfer_buffer; 120 buf_end = po + urb_out->transfer_buffer_length / sizeof(*po); 121 122 for (; po < buf_end; ++pi, ++po) 123 *po += (*pi * volume) >> 8; 124 } 125 126 /* 127 We don't need to handle devices with 6 bytes per frame here 128 since they all support hardware monitoring. 129 */ 130} 131 132/* 133 Find a free URB, prepare audio data, and submit URB. 134*/ 135static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) 136{ 137 int index; 138 unsigned long flags; 139 int i, urb_size, urb_frames; 140 int ret; 141 const int bytes_per_frame = line6pcm->properties->bytes_per_frame; 142 const int frame_increment = 143 line6pcm->properties->snd_line6_rates.rats[0].num_min; 144 const int frame_factor = 145 line6pcm->properties->snd_line6_rates.rats[0].den * 146 (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL); 147 struct urb *urb_out; 148 149 spin_lock_irqsave(&line6pcm->lock_audio_out, flags); 150 index = 151 find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS); 152 153 if (index < 0 || index >= LINE6_ISO_BUFFERS) { 154 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); 155 dev_err(line6pcm->line6->ifcdev, "no free URB found\n"); 156 return -EINVAL; 157 } 158 159 urb_out = line6pcm->urb_audio_out[index]; 160 urb_size = 0; 161 162 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 163 /* compute frame size for given sampling rate */ 164 int fsize = 0; 165 struct usb_iso_packet_descriptor *fout = 166 &urb_out->iso_frame_desc[i]; 167 168 if (line6pcm->flags & MASK_CAPTURE) 169 fsize = line6pcm->prev_fsize; 170 171 if (fsize == 0) { 172 int n; 173 line6pcm->count_out += frame_increment; 174 n = line6pcm->count_out / frame_factor; 175 line6pcm->count_out -= n * frame_factor; 176 fsize = n * bytes_per_frame; 177 } 178 179 fout->offset = urb_size; 180 fout->length = fsize; 181 urb_size += fsize; 182 } 183 184 if (urb_size == 0) { 185 /* can't determine URB size */ 186 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); 187 dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); /* this is somewhat paranoid */ 188 return -EINVAL; 189 } 190 191 urb_frames = urb_size / bytes_per_frame; 192 urb_out->transfer_buffer = 193 line6pcm->buffer_out + 194 line6pcm->max_packet_size * line6pcm->index_out; 195 urb_out->transfer_buffer_length = urb_size; 196 urb_out->context = line6pcm; 197 198 if (++line6pcm->index_out == LINE6_ISO_BUFFERS) 199 line6pcm->index_out = 0; 200 201 if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags) && 202 !test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) { 203 struct snd_pcm_runtime *runtime = 204 get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime; 205 206 if (line6pcm->pos_out + urb_frames > runtime->buffer_size) { 207 /* 208 The transferred area goes over buffer boundary, 209 copy the data to the temp buffer. 210 */ 211 int len; 212 len = runtime->buffer_size - line6pcm->pos_out; 213 214 if (len > 0) { 215 memcpy(urb_out->transfer_buffer, 216 runtime->dma_area + 217 line6pcm->pos_out * bytes_per_frame, 218 len * bytes_per_frame); 219 memcpy(urb_out->transfer_buffer + 220 len * bytes_per_frame, runtime->dma_area, 221 (urb_frames - len) * bytes_per_frame); 222 } else 223 dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len); /* this is somewhat paranoid */ 224 } else { 225#if LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 226 /* set the buffer pointer */ 227 urb_out->transfer_buffer = 228 runtime->dma_area + 229 line6pcm->pos_out * bytes_per_frame; 230#else 231 /* copy data */ 232 memcpy(urb_out->transfer_buffer, 233 runtime->dma_area + 234 line6pcm->pos_out * bytes_per_frame, 235 urb_out->transfer_buffer_length); 236#endif 237 } 238 239 line6pcm->pos_out += urb_frames; 240 if (line6pcm->pos_out >= runtime->buffer_size) 241 line6pcm->pos_out -= runtime->buffer_size; 242 } else { 243 memset(urb_out->transfer_buffer, 0, 244 urb_out->transfer_buffer_length); 245 } 246 247 change_volume(urb_out, line6pcm->volume_playback, bytes_per_frame); 248 249 if (line6pcm->prev_fbuf != NULL) { 250#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 251 if (line6pcm->flags & MASK_PCM_IMPULSE) { 252 create_impulse_test_signal(line6pcm, urb_out, 253 bytes_per_frame); 254 if (line6pcm->flags & MASK_PCM_ALSA_CAPTURE) { 255 line6_capture_copy(line6pcm, 256 urb_out->transfer_buffer, 257 urb_out-> 258 transfer_buffer_length); 259 line6_capture_check_period(line6pcm, 260 urb_out->transfer_buffer_length); 261 } 262 } else { 263#endif 264 if (! 265 (line6pcm->line6-> 266 properties->capabilities & LINE6_BIT_HWMON) 267&& (line6pcm->flags & MASK_PLAYBACK) 268&& (line6pcm->flags & MASK_CAPTURE)) 269 add_monitor_signal(urb_out, line6pcm->prev_fbuf, 270 line6pcm->volume_monitor, 271 bytes_per_frame); 272#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE 273 } 274#endif 275 } 276#ifdef CONFIG_LINE6_USB_DUMP_PCM 277 for (i = 0; i < LINE6_ISO_PACKETS; ++i) { 278 struct usb_iso_packet_descriptor *fout = 279 &urb_out->iso_frame_desc[i]; 280 line6_write_hexdump(line6pcm->line6, 'P', 281 urb_out->transfer_buffer + fout->offset, 282 fout->length); 283 } 284#endif 285 286 ret = usb_submit_urb(urb_out, GFP_ATOMIC); 287 288 if (ret == 0) 289 set_bit(index, &line6pcm->active_urb_out); 290 else 291 dev_err(line6pcm->line6->ifcdev, 292 "URB out #%d submission failed (%d)\n", index, ret); 293 294 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); 295 return 0; 296} 297 298/* 299 Submit all currently available playback URBs. 300*/ 301int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm) 302{ 303 int ret, i; 304 305 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 306 ret = submit_audio_out_urb(line6pcm); 307 if (ret < 0) 308 return ret; 309 } 310 311 return 0; 312} 313 314/* 315 Unlink all currently active playback URBs. 316*/ 317void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm) 318{ 319 unsigned int i; 320 321 for (i = LINE6_ISO_BUFFERS; i--;) { 322 if (test_bit(i, &line6pcm->active_urb_out)) { 323 if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) { 324 struct urb *u = line6pcm->urb_audio_out[i]; 325 usb_unlink_urb(u); 326 } 327 } 328 } 329} 330 331/* 332 Wait until unlinking of all currently active playback URBs has been finished. 333*/ 334static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) 335{ 336 int timeout = HZ; 337 unsigned int i; 338 int alive; 339 340 do { 341 alive = 0; 342 for (i = LINE6_ISO_BUFFERS; i--;) { 343 if (test_bit(i, &line6pcm->active_urb_out)) 344 alive++; 345 } 346 if (!alive) 347 break; 348 set_current_state(TASK_UNINTERRUPTIBLE); 349 schedule_timeout(1); 350 } while (--timeout > 0); 351 if (alive) 352 snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); 353} 354 355/* 356 Unlink all currently active playback URBs, and wait for finishing. 357*/ 358void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) 359{ 360 line6_unlink_audio_out_urbs(line6pcm); 361 wait_clear_audio_out_urbs(line6pcm); 362} 363 364/* 365 Callback for completed playback URB. 366*/ 367static void audio_out_callback(struct urb *urb) 368{ 369 int i, index, length = 0, shutdown = 0; 370 unsigned long flags; 371 372 struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context; 373 struct snd_pcm_substream *substream = 374 get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK); 375 376#if USE_CLEAR_BUFFER_WORKAROUND 377 memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); 378#endif 379 380 line6pcm->last_frame_out = urb->start_frame; 381 382 /* find index of URB */ 383 for (index = LINE6_ISO_BUFFERS; index--;) 384 if (urb == line6pcm->urb_audio_out[index]) 385 break; 386 387 if (index < 0) 388 return; /* URB has been unlinked asynchronously */ 389 390 for (i = LINE6_ISO_PACKETS; i--;) 391 length += urb->iso_frame_desc[i].length; 392 393 spin_lock_irqsave(&line6pcm->lock_audio_out, flags); 394 395 if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) { 396 struct snd_pcm_runtime *runtime = substream->runtime; 397 line6pcm->pos_out_done += 398 length / line6pcm->properties->bytes_per_frame; 399 400 if (line6pcm->pos_out_done >= runtime->buffer_size) 401 line6pcm->pos_out_done -= runtime->buffer_size; 402 } 403 404 clear_bit(index, &line6pcm->active_urb_out); 405 406 for (i = LINE6_ISO_PACKETS; i--;) 407 if (urb->iso_frame_desc[i].status == -EXDEV) { 408 shutdown = 1; 409 break; 410 } 411 412 if (test_and_clear_bit(index, &line6pcm->unlink_urb_out)) 413 shutdown = 1; 414 415 spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); 416 417 if (!shutdown) { 418 submit_audio_out_urb(line6pcm); 419 420 if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) { 421 line6pcm->bytes_out += length; 422 if (line6pcm->bytes_out >= line6pcm->period_out) { 423 line6pcm->bytes_out %= line6pcm->period_out; 424 snd_pcm_period_elapsed(substream); 425 } 426 } 427 } 428} 429 430/* open playback callback */ 431static int snd_line6_playback_open(struct snd_pcm_substream *substream) 432{ 433 int err; 434 struct snd_pcm_runtime *runtime = substream->runtime; 435 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 436 437 err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 438 (&line6pcm-> 439 properties->snd_line6_rates)); 440 if (err < 0) 441 return err; 442 443 runtime->hw = line6pcm->properties->snd_line6_playback_hw; 444 return 0; 445} 446 447/* close playback callback */ 448static int snd_line6_playback_close(struct snd_pcm_substream *substream) 449{ 450 return 0; 451} 452 453/* hw_params playback callback */ 454static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, 455 struct snd_pcm_hw_params *hw_params) 456{ 457 int ret; 458 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 459 460 /* -- Florian Demski [FD] */ 461 /* don't ask me why, but this fixes the bug on my machine */ 462 if (line6pcm == NULL) { 463 if (substream->pcm == NULL) 464 return -ENOMEM; 465 if (substream->pcm->private_data == NULL) 466 return -ENOMEM; 467 substream->private_data = substream->pcm->private_data; 468 line6pcm = snd_pcm_substream_chip(substream); 469 } 470 /* -- [FD] end */ 471 472 ret = snd_pcm_lib_malloc_pages(substream, 473 params_buffer_bytes(hw_params)); 474 if (ret < 0) 475 return ret; 476 477 line6pcm->period_out = params_period_bytes(hw_params); 478 return 0; 479} 480 481/* hw_free playback callback */ 482static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream) 483{ 484 return snd_pcm_lib_free_pages(substream); 485} 486 487/* trigger playback callback */ 488int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd) 489{ 490 int err; 491 492 switch (cmd) { 493 case SNDRV_PCM_TRIGGER_START: 494#ifdef CONFIG_PM 495 case SNDRV_PCM_TRIGGER_RESUME: 496#endif 497 err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_PLAYBACK); 498 499 if (err < 0) 500 return err; 501 502 break; 503 504 case SNDRV_PCM_TRIGGER_STOP: 505#ifdef CONFIG_PM 506 case SNDRV_PCM_TRIGGER_SUSPEND: 507#endif 508 err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_PLAYBACK); 509 510 if (err < 0) 511 return err; 512 513 break; 514 515 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 516 set_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags); 517 break; 518 519 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 520 clear_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags); 521 break; 522 523 default: 524 return -EINVAL; 525 } 526 527 return 0; 528} 529 530/* playback pointer callback */ 531static snd_pcm_uframes_t 532snd_line6_playback_pointer(struct snd_pcm_substream *substream) 533{ 534 struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream); 535 return line6pcm->pos_out_done; 536} 537 538/* playback operators */ 539struct snd_pcm_ops snd_line6_playback_ops = { 540 .open = snd_line6_playback_open, 541 .close = snd_line6_playback_close, 542 .ioctl = snd_pcm_lib_ioctl, 543 .hw_params = snd_line6_playback_hw_params, 544 .hw_free = snd_line6_playback_hw_free, 545 .prepare = snd_line6_prepare, 546 .trigger = snd_line6_trigger, 547 .pointer = snd_line6_playback_pointer, 548}; 549 550int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) 551{ 552 int i; 553 554 /* create audio URBs and fill in constant values: */ 555 for (i = 0; i < LINE6_ISO_BUFFERS; ++i) { 556 struct urb *urb; 557 558 /* URB for audio out: */ 559 urb = line6pcm->urb_audio_out[i] = 560 usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL); 561 562 if (urb == NULL) { 563 dev_err(line6pcm->line6->ifcdev, "Out of memory\n"); 564 return -ENOMEM; 565 } 566 567 urb->dev = line6pcm->line6->usbdev; 568 urb->pipe = 569 usb_sndisocpipe(line6pcm->line6->usbdev, 570 line6pcm->ep_audio_write & 571 USB_ENDPOINT_NUMBER_MASK); 572 urb->transfer_flags = URB_ISO_ASAP; 573 urb->start_frame = -1; 574 urb->number_of_packets = LINE6_ISO_PACKETS; 575 urb->interval = LINE6_ISO_INTERVAL; 576 urb->error_count = 0; 577 urb->complete = audio_out_callback; 578 } 579 580 return 0; 581}