1 /* 2 * Digital Audio (PCM) abstract layer 3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 4 * Abramo Bagnara <abramo@alsa-project.org> 5 * 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 */ 22 23 #include <sound/driver.h> 24 #include <linux/slab.h> 25 #include <linux/time.h> 26 #include <sound/core.h> 27 #include <sound/control.h> 28 #include <sound/info.h> 29 #include <sound/pcm.h> 30 #include <sound/pcm_params.h> 31 #include <sound/timer.h> 32 33 /* 34 * fill ring buffer with silence 35 * runtime->silence_start: starting pointer to silence area 36 * runtime->silence_filled: size filled with silence 37 * runtime->silence_threshold: threshold from application 38 * runtime->silence_size: maximal size from application 39 * 40 * when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately 41 */ 42 void snd_pcm_playback_silence(snd_pcm_substream_t *substream, snd_pcm_uframes_t new_hw_ptr) 43 { 44 snd_pcm_runtime_t *runtime = substream->runtime; 45 snd_pcm_uframes_t frames, ofs, transfer; 46 47 if (runtime->silence_size < runtime->boundary) { 48 snd_pcm_sframes_t noise_dist, n; 49 if (runtime->silence_start != runtime->control->appl_ptr) { 50 n = runtime->control->appl_ptr - runtime->silence_start; 51 if (n < 0) 52 n += runtime->boundary; 53 if ((snd_pcm_uframes_t)n < runtime->silence_filled) 54 runtime->silence_filled -= n; 55 else 56 runtime->silence_filled = 0; 57 runtime->silence_start = runtime->control->appl_ptr; 58 } 59 if (runtime->silence_filled == runtime->buffer_size) 60 return; 61 snd_assert(runtime->silence_filled <= runtime->buffer_size, return); 62 noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled; 63 if (noise_dist >= (snd_pcm_sframes_t) runtime->silence_threshold) 64 return; 65 frames = runtime->silence_threshold - noise_dist; 66 if (frames > runtime->silence_size) 67 frames = runtime->silence_size; 68 } else { 69 if (new_hw_ptr == ULONG_MAX) { /* initialization */ 70 snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime); 71 runtime->silence_filled = avail > 0 ? avail : 0; 72 runtime->silence_start = (runtime->status->hw_ptr + 73 runtime->silence_filled) % 74 runtime->boundary; 75 } else { 76 ofs = runtime->status->hw_ptr; 77 frames = new_hw_ptr - ofs; 78 if ((snd_pcm_sframes_t)frames < 0) 79 frames += runtime->boundary; 80 runtime->silence_filled -= frames; 81 if ((snd_pcm_sframes_t)runtime->silence_filled < 0) { 82 runtime->silence_filled = 0; 83 runtime->silence_start = (ofs + frames) - runtime->buffer_size; 84 } else { 85 runtime->silence_start = ofs - runtime->silence_filled; 86 } 87 if ((snd_pcm_sframes_t)runtime->silence_start < 0) 88 runtime->silence_start += runtime->boundary; 89 } 90 frames = runtime->buffer_size - runtime->silence_filled; 91 } 92 snd_assert(frames <= runtime->buffer_size, return); 93 if (frames == 0) 94 return; 95 ofs = (runtime->silence_start + runtime->silence_filled) % runtime->buffer_size; 96 while (frames > 0) { 97 transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames; 98 if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || 99 runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) { 100 if (substream->ops->silence) { 101 int err; 102 err = substream->ops->silence(substream, -1, ofs, transfer); 103 snd_assert(err >= 0, ); 104 } else { 105 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs); 106 snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels); 107 } 108 } else { 109 unsigned int c; 110 unsigned int channels = runtime->channels; 111 if (substream->ops->silence) { 112 for (c = 0; c < channels; ++c) { 113 int err; 114 err = substream->ops->silence(substream, c, ofs, transfer); 115 snd_assert(err >= 0, ); 116 } 117 } else { 118 size_t dma_csize = runtime->dma_bytes / channels; 119 for (c = 0; c < channels; ++c) { 120 char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs); 121 snd_pcm_format_set_silence(runtime->format, hwbuf, transfer); 122 } 123 } 124 } 125 runtime->silence_filled += transfer; 126 frames -= transfer; 127 ofs = 0; 128 } 129 } 130 131 static void xrun(snd_pcm_substream_t *substream) 132 { 133 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 134 #ifdef CONFIG_SND_DEBUG 135 if (substream->pstr->xrun_debug) { 136 snd_printd(KERN_DEBUG "XRUN: pcmC%dD%d%c\n", 137 substream->pcm->card->number, 138 substream->pcm->device, 139 substream->stream ? 'c' : 'p'); 140 if (substream->pstr->xrun_debug > 1) 141 dump_stack(); 142 } 143 #endif 144 } 145 146 static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(snd_pcm_substream_t *substream, 147 snd_pcm_runtime_t *runtime) 148 { 149 snd_pcm_uframes_t pos; 150 151 pos = substream->ops->pointer(substream); 152 if (pos == SNDRV_PCM_POS_XRUN) 153 return pos; /* XRUN */ 154 if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP) 155 getnstimeofday((struct timespec *)&runtime->status->tstamp); 156 #ifdef CONFIG_SND_DEBUG 157 if (pos >= runtime->buffer_size) { 158 snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size); 159 } 160 #endif 161 pos -= pos % runtime->min_align; 162 return pos; 163 } 164 165 static inline int snd_pcm_update_hw_ptr_post(snd_pcm_substream_t *substream, 166 snd_pcm_runtime_t *runtime) 167 { 168 snd_pcm_uframes_t avail; 169 170 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 171 avail = snd_pcm_playback_avail(runtime); 172 else 173 avail = snd_pcm_capture_avail(runtime); 174 if (avail > runtime->avail_max) 175 runtime->avail_max = avail; 176 if (avail >= runtime->stop_threshold) { 177 if (substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING) 178 snd_pcm_drain_done(substream); 179 else 180 xrun(substream); 181 return -EPIPE; 182 } 183 if (avail >= runtime->control->avail_min) 184 wake_up(&runtime->sleep); 185 return 0; 186 } 187 188 static inline int snd_pcm_update_hw_ptr_interrupt(snd_pcm_substream_t *substream) 189 { 190 snd_pcm_runtime_t *runtime = substream->runtime; 191 snd_pcm_uframes_t pos; 192 snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt; 193 snd_pcm_sframes_t delta; 194 195 pos = snd_pcm_update_hw_ptr_pos(substream, runtime); 196 if (pos == SNDRV_PCM_POS_XRUN) { 197 xrun(substream); 198 return -EPIPE; 199 } 200 if (runtime->period_size == runtime->buffer_size) 201 goto __next_buf; 202 new_hw_ptr = runtime->hw_ptr_base + pos; 203 hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size; 204 205 delta = hw_ptr_interrupt - new_hw_ptr; 206 if (delta > 0) { 207 if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { 208 #ifdef CONFIG_SND_DEBUG 209 if (runtime->periods > 1 && substream->pstr->xrun_debug) { 210 snd_printd(KERN_ERR "Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); 211 if (substream->pstr->xrun_debug > 1) 212 dump_stack(); 213 } 214 #endif 215 return 0; 216 } 217 __next_buf: 218 runtime->hw_ptr_base += runtime->buffer_size; 219 if (runtime->hw_ptr_base == runtime->boundary) 220 runtime->hw_ptr_base = 0; 221 new_hw_ptr = runtime->hw_ptr_base + pos; 222 } 223 224 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 225 runtime->silence_size > 0) 226 snd_pcm_playback_silence(substream, new_hw_ptr); 227 228 runtime->status->hw_ptr = new_hw_ptr; 229 runtime->hw_ptr_interrupt = new_hw_ptr - new_hw_ptr % runtime->period_size; 230 231 return snd_pcm_update_hw_ptr_post(substream, runtime); 232 } 233 234 /* CAUTION: call it with irq disabled */ 235 int snd_pcm_update_hw_ptr(snd_pcm_substream_t *substream) 236 { 237 snd_pcm_runtime_t *runtime = substream->runtime; 238 snd_pcm_uframes_t pos; 239 snd_pcm_uframes_t old_hw_ptr, new_hw_ptr; 240 snd_pcm_sframes_t delta; 241 242 old_hw_ptr = runtime->status->hw_ptr; 243 pos = snd_pcm_update_hw_ptr_pos(substream, runtime); 244 if (pos == SNDRV_PCM_POS_XRUN) { 245 xrun(substream); 246 return -EPIPE; 247 } 248 new_hw_ptr = runtime->hw_ptr_base + pos; 249 250 delta = old_hw_ptr - new_hw_ptr; 251 if (delta > 0) { 252 if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { 253 #ifdef CONFIG_SND_DEBUG 254 if (runtime->periods > 2 && substream->pstr->xrun_debug) { 255 snd_printd(KERN_ERR "Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); 256 if (substream->pstr->xrun_debug > 1) 257 dump_stack(); 258 } 259 #endif 260 return 0; 261 } 262 runtime->hw_ptr_base += runtime->buffer_size; 263 if (runtime->hw_ptr_base == runtime->boundary) 264 runtime->hw_ptr_base = 0; 265 new_hw_ptr = runtime->hw_ptr_base + pos; 266 } 267 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 268 runtime->silence_size > 0) 269 snd_pcm_playback_silence(substream, new_hw_ptr); 270 271 runtime->status->hw_ptr = new_hw_ptr; 272 273 return snd_pcm_update_hw_ptr_post(substream, runtime); 274 } 275 276 /** 277 * snd_pcm_set_ops - set the PCM operators 278 * @pcm: the pcm instance 279 * @direction: stream direction, SNDRV_PCM_STREAM_XXX 280 * @ops: the operator table 281 * 282 * Sets the given PCM operators to the pcm instance. 283 */ 284 void snd_pcm_set_ops(snd_pcm_t *pcm, int direction, snd_pcm_ops_t *ops) 285 { 286 snd_pcm_str_t *stream = &pcm->streams[direction]; 287 snd_pcm_substream_t *substream; 288 289 for (substream = stream->substream; substream != NULL; substream = substream->next) 290 substream->ops = ops; 291 } 292 293 294 /** 295 * snd_pcm_sync - set the PCM sync id 296 * @substream: the pcm substream 297 * 298 * Sets the PCM sync identifier for the card. 299 */ 300 void snd_pcm_set_sync(snd_pcm_substream_t * substream) 301 { 302 snd_pcm_runtime_t *runtime = substream->runtime; 303 304 runtime->sync.id32[0] = substream->pcm->card->number; 305 runtime->sync.id32[1] = -1; 306 runtime->sync.id32[2] = -1; 307 runtime->sync.id32[3] = -1; 308 } 309 310 /* 311 * Standard ioctl routine 312 */ 313 314 /* Code taken from alsa-lib */ 315 #define assert(a) snd_assert((a), return -EINVAL) 316 317 static inline unsigned int div32(unsigned int a, unsigned int b, 318 unsigned int *r) 319 { 320 if (b == 0) { 321 *r = 0; 322 return UINT_MAX; 323 } 324 *r = a % b; 325 return a / b; 326 } 327 328 static inline unsigned int div_down(unsigned int a, unsigned int b) 329 { 330 if (b == 0) 331 return UINT_MAX; 332 return a / b; 333 } 334 335 static inline unsigned int div_up(unsigned int a, unsigned int b) 336 { 337 unsigned int r; 338 unsigned int q; 339 if (b == 0) 340 return UINT_MAX; 341 q = div32(a, b, &r); 342 if (r) 343 ++q; 344 return q; 345 } 346 347 static inline unsigned int mul(unsigned int a, unsigned int b) 348 { 349 if (a == 0) 350 return 0; 351 if (div_down(UINT_MAX, a) < b) 352 return UINT_MAX; 353 return a * b; 354 } 355 356 static inline unsigned int muldiv32(unsigned int a, unsigned int b, 357 unsigned int c, unsigned int *r) 358 { 359 u_int64_t n = (u_int64_t) a * b; 360 if (c == 0) { 361 snd_assert(n > 0, ); 362 *r = 0; 363 return UINT_MAX; 364 } 365 div64_32(&n, c, r); 366 if (n >= UINT_MAX) { 367 *r = 0; 368 return UINT_MAX; 369 } 370 return n; 371 } 372 373 static int snd_interval_refine_min(snd_interval_t *i, unsigned int min, int openmin) 374 { 375 int changed = 0; 376 assert(!snd_interval_empty(i)); 377 if (i->min < min) { 378 i->min = min; 379 i->openmin = openmin; 380 changed = 1; 381 } else if (i->min == min && !i->openmin && openmin) { 382 i->openmin = 1; 383 changed = 1; 384 } 385 if (i->integer) { 386 if (i->openmin) { 387 i->min++; 388 i->openmin = 0; 389 } 390 } 391 if (snd_interval_checkempty(i)) { 392 snd_interval_none(i); 393 return -EINVAL; 394 } 395 return changed; 396 } 397 398 static int snd_interval_refine_max(snd_interval_t *i, unsigned int max, int openmax) 399 { 400 int changed = 0; 401 assert(!snd_interval_empty(i)); 402 if (i->max > max) { 403 i->max = max; 404 i->openmax = openmax; 405 changed = 1; 406 } else if (i->max == max && !i->openmax && openmax) { 407 i->openmax = 1; 408 changed = 1; 409 } 410 if (i->integer) { 411 if (i->openmax) { 412 i->max--; 413 i->openmax = 0; 414 } 415 } 416 if (snd_interval_checkempty(i)) { 417 snd_interval_none(i); 418 return -EINVAL; 419 } 420 return changed; 421 } 422 423 /** 424 * snd_interval_refine - refine the interval value of configurator 425 * @i: the interval value to refine 426 * @v: the interval value to refer to 427 * 428 * Refines the interval value with the reference value. 429 * The interval is changed to the range satisfying both intervals. 430 * The interval status (min, max, integer, etc.) are evaluated. 431 * 432 * Returns non-zero if the value is changed, zero if not changed. 433 */ 434 int snd_interval_refine(snd_interval_t *i, const snd_interval_t *v) 435 { 436 int changed = 0; 437 assert(!snd_interval_empty(i)); 438 if (i->min < v->min) { 439 i->min = v->min; 440 i->openmin = v->openmin; 441 changed = 1; 442 } else if (i->min == v->min && !i->openmin && v->openmin) { 443 i->openmin = 1; 444 changed = 1; 445 } 446 if (i->max > v->max) { 447 i->max = v->max; 448 i->openmax = v->openmax; 449 changed = 1; 450 } else if (i->max == v->max && !i->openmax && v->openmax) { 451 i->openmax = 1; 452 changed = 1; 453 } 454 if (!i->integer && v->integer) { 455 i->integer = 1; 456 changed = 1; 457 } 458 if (i->integer) { 459 if (i->openmin) { 460 i->min++; 461 i->openmin = 0; 462 } 463 if (i->openmax) { 464 i->max--; 465 i->openmax = 0; 466 } 467 } else if (!i->openmin && !i->openmax && i->min == i->max) 468 i->integer = 1; 469 if (snd_interval_checkempty(i)) { 470 snd_interval_none(i); 471 return -EINVAL; 472 } 473 return changed; 474 } 475 476 static int snd_interval_refine_first(snd_interval_t *i) 477 { 478 assert(!snd_interval_empty(i)); 479 if (snd_interval_single(i)) 480 return 0; 481 i->max = i->min; 482 i->openmax = i->openmin; 483 if (i->openmax) 484 i->max++; 485 return 1; 486 } 487 488 static int snd_interval_refine_last(snd_interval_t *i) 489 { 490 assert(!snd_interval_empty(i)); 491 if (snd_interval_single(i)) 492 return 0; 493 i->min = i->max; 494 i->openmin = i->openmax; 495 if (i->openmin) 496 i->min--; 497 return 1; 498 } 499 500 static int snd_interval_refine_set(snd_interval_t *i, unsigned int val) 501 { 502 snd_interval_t t; 503 t.empty = 0; 504 t.min = t.max = val; 505 t.openmin = t.openmax = 0; 506 t.integer = 1; 507 return snd_interval_refine(i, &t); 508 } 509 510 void snd_interval_mul(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c) 511 { 512 if (a->empty || b->empty) { 513 snd_interval_none(c); 514 return; 515 } 516 c->empty = 0; 517 c->min = mul(a->min, b->min); 518 c->openmin = (a->openmin || b->openmin); 519 c->max = mul(a->max, b->max); 520 c->openmax = (a->openmax || b->openmax); 521 c->integer = (a->integer && b->integer); 522 } 523 524 /** 525 * snd_interval_div - refine the interval value with division 526 * @a: dividend 527 * @b: divisor 528 * @c: quotient 529 * 530 * c = a / b 531 * 532 * Returns non-zero if the value is changed, zero if not changed. 533 */ 534 void snd_interval_div(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c) 535 { 536 unsigned int r; 537 if (a->empty || b->empty) { 538 snd_interval_none(c); 539 return; 540 } 541 c->empty = 0; 542 c->min = div32(a->min, b->max, &r); 543 c->openmin = (r || a->openmin || b->openmax); 544 if (b->min > 0) { 545 c->max = div32(a->max, b->min, &r); 546 if (r) { 547 c->max++; 548 c->openmax = 1; 549 } else 550 c->openmax = (a->openmax || b->openmin); 551 } else { 552 c->max = UINT_MAX; 553 c->openmax = 0; 554 } 555 c->integer = 0; 556 } 557 558 /** 559 * snd_interval_muldivk - refine the interval value 560 * @a: dividend 1 561 * @b: dividend 2 562 * @k: divisor (as integer) 563 * @c: result 564 * 565 * c = a * b / k 566 * 567 * Returns non-zero if the value is changed, zero if not changed. 568 */ 569 void snd_interval_muldivk(const snd_interval_t *a, const snd_interval_t *b, 570 unsigned int k, snd_interval_t *c) 571 { 572 unsigned int r; 573 if (a->empty || b->empty) { 574 snd_interval_none(c); 575 return; 576 } 577 c->empty = 0; 578 c->min = muldiv32(a->min, b->min, k, &r); 579 c->openmin = (r || a->openmin || b->openmin); 580 c->max = muldiv32(a->max, b->max, k, &r); 581 if (r) { 582 c->max++; 583 c->openmax = 1; 584 } else 585 c->openmax = (a->openmax || b->openmax); 586 c->integer = 0; 587 } 588 589 /** 590 * snd_interval_mulkdiv - refine the interval value 591 * @a: dividend 1 592 * @k: dividend 2 (as integer) 593 * @b: divisor 594 * @c: result 595 * 596 * c = a * k / b 597 * 598 * Returns non-zero if the value is changed, zero if not changed. 599 */ 600 void snd_interval_mulkdiv(const snd_interval_t *a, unsigned int k, 601 const snd_interval_t *b, snd_interval_t *c) 602 { 603 unsigned int r; 604 if (a->empty || b->empty) { 605 snd_interval_none(c); 606 return; 607 } 608 c->empty = 0; 609 c->min = muldiv32(a->min, k, b->max, &r); 610 c->openmin = (r || a->openmin || b->openmax); 611 if (b->min > 0) { 612 c->max = muldiv32(a->max, k, b->min, &r); 613 if (r) { 614 c->max++; 615 c->openmax = 1; 616 } else 617 c->openmax = (a->openmax || b->openmin); 618 } else { 619 c->max = UINT_MAX; 620 c->openmax = 0; 621 } 622 c->integer = 0; 623 } 624 625 #undef assert 626 /* ---- */ 627 628 629 /** 630 * snd_interval_ratnum - refine the interval value 631 * @i: interval to refine 632 * @rats_count: number of ratnum_t 633 * @rats: ratnum_t array 634 * @nump: pointer to store the resultant numerator 635 * @denp: pointer to store the resultant denominator 636 * 637 * Returns non-zero if the value is changed, zero if not changed. 638 */ 639 int snd_interval_ratnum(snd_interval_t *i, 640 unsigned int rats_count, ratnum_t *rats, 641 unsigned int *nump, unsigned int *denp) 642 { 643 unsigned int best_num, best_diff, best_den; 644 unsigned int k; 645 snd_interval_t t; 646 int err; 647 648 best_num = best_den = best_diff = 0; 649 for (k = 0; k < rats_count; ++k) { 650 unsigned int num = rats[k].num; 651 unsigned int den; 652 unsigned int q = i->min; 653 int diff; 654 if (q == 0) 655 q = 1; 656 den = div_down(num, q); 657 if (den < rats[k].den_min) 658 continue; 659 if (den > rats[k].den_max) 660 den = rats[k].den_max; 661 else { 662 unsigned int r; 663 r = (den - rats[k].den_min) % rats[k].den_step; 664 if (r != 0) 665 den -= r; 666 } 667 diff = num - q * den; 668 if (best_num == 0 || 669 diff * best_den < best_diff * den) { 670 best_diff = diff; 671 best_den = den; 672 best_num = num; 673 } 674 } 675 if (best_den == 0) { 676 i->empty = 1; 677 return -EINVAL; 678 } 679 t.min = div_down(best_num, best_den); 680 t.openmin = !!(best_num % best_den); 681 682 best_num = best_den = best_diff = 0; 683 for (k = 0; k < rats_count; ++k) { 684 unsigned int num = rats[k].num; 685 unsigned int den; 686 unsigned int q = i->max; 687 int diff; 688 if (q == 0) { 689 i->empty = 1; 690 return -EINVAL; 691 } 692 den = div_up(num, q); 693 if (den > rats[k].den_max) 694 continue; 695 if (den < rats[k].den_min) 696 den = rats[k].den_min; 697 else { 698 unsigned int r; 699 r = (den - rats[k].den_min) % rats[k].den_step; 700 if (r != 0) 701 den += rats[k].den_step - r; 702 } 703 diff = q * den - num; 704 if (best_num == 0 || 705 diff * best_den < best_diff * den) { 706 best_diff = diff; 707 best_den = den; 708 best_num = num; 709 } 710 } 711 if (best_den == 0) { 712 i->empty = 1; 713 return -EINVAL; 714 } 715 t.max = div_up(best_num, best_den); 716 t.openmax = !!(best_num % best_den); 717 t.integer = 0; 718 err = snd_interval_refine(i, &t); 719 if (err < 0) 720 return err; 721 722 if (snd_interval_single(i)) { 723 if (nump) 724 *nump = best_num; 725 if (denp) 726 *denp = best_den; 727 } 728 return err; 729 } 730 731 /** 732 * snd_interval_ratden - refine the interval value 733 * @i: interval to refine 734 * @rats_count: number of ratden_t 735 * @rats: ratden_t array 736 * @nump: pointer to store the resultant numerator 737 * @denp: pointer to store the resultant denominator 738 * 739 * Returns non-zero if the value is changed, zero if not changed. 740 */ 741 static int snd_interval_ratden(snd_interval_t *i, 742 unsigned int rats_count, ratden_t *rats, 743 unsigned int *nump, unsigned int *denp) 744 { 745 unsigned int best_num, best_diff, best_den; 746 unsigned int k; 747 snd_interval_t t; 748 int err; 749 750 best_num = best_den = best_diff = 0; 751 for (k = 0; k < rats_count; ++k) { 752 unsigned int num; 753 unsigned int den = rats[k].den; 754 unsigned int q = i->min; 755 int diff; 756 num = mul(q, den); 757 if (num > rats[k].num_max) 758 continue; 759 if (num < rats[k].num_min) 760 num = rats[k].num_max; 761 else { 762 unsigned int r; 763 r = (num - rats[k].num_min) % rats[k].num_step; 764 if (r != 0) 765 num += rats[k].num_step - r; 766 } 767 diff = num - q * den; 768 if (best_num == 0 || 769 diff * best_den < best_diff * den) { 770 best_diff = diff; 771 best_den = den; 772 best_num = num; 773 } 774 } 775 if (best_den == 0) { 776 i->empty = 1; 777 return -EINVAL; 778 } 779 t.min = div_down(best_num, best_den); 780 t.openmin = !!(best_num % best_den); 781 782 best_num = best_den = best_diff = 0; 783 for (k = 0; k < rats_count; ++k) { 784 unsigned int num; 785 unsigned int den = rats[k].den; 786 unsigned int q = i->max; 787 int diff; 788 num = mul(q, den); 789 if (num < rats[k].num_min) 790 continue; 791 if (num > rats[k].num_max) 792 num = rats[k].num_max; 793 else { 794 unsigned int r; 795 r = (num - rats[k].num_min) % rats[k].num_step; 796 if (r != 0) 797 num -= r; 798 } 799 diff = q * den - num; 800 if (best_num == 0 || 801 diff * best_den < best_diff * den) { 802 best_diff = diff; 803 best_den = den; 804 best_num = num; 805 } 806 } 807 if (best_den == 0) { 808 i->empty = 1; 809 return -EINVAL; 810 } 811 t.max = div_up(best_num, best_den); 812 t.openmax = !!(best_num % best_den); 813 t.integer = 0; 814 err = snd_interval_refine(i, &t); 815 if (err < 0) 816 return err; 817 818 if (snd_interval_single(i)) { 819 if (nump) 820 *nump = best_num; 821 if (denp) 822 *denp = best_den; 823 } 824 return err; 825 } 826 827 /** 828 * snd_interval_list - refine the interval value from the list 829 * @i: the interval value to refine 830 * @count: the number of elements in the list 831 * @list: the value list 832 * @mask: the bit-mask to evaluate 833 * 834 * Refines the interval value from the list. 835 * When mask is non-zero, only the elements corresponding to bit 1 are 836 * evaluated. 837 * 838 * Returns non-zero if the value is changed, zero if not changed. 839 */ 840 int snd_interval_list(snd_interval_t *i, unsigned int count, unsigned int *list, unsigned int mask) 841 { 842 unsigned int k; 843 int changed = 0; 844 for (k = 0; k < count; k++) { 845 if (mask && !(mask & (1 << k))) 846 continue; 847 if (i->min == list[k] && !i->openmin) 848 goto _l1; 849 if (i->min < list[k]) { 850 i->min = list[k]; 851 i->openmin = 0; 852 changed = 1; 853 goto _l1; 854 } 855 } 856 i->empty = 1; 857 return -EINVAL; 858 _l1: 859 for (k = count; k-- > 0;) { 860 if (mask && !(mask & (1 << k))) 861 continue; 862 if (i->max == list[k] && !i->openmax) 863 goto _l2; 864 if (i->max > list[k]) { 865 i->max = list[k]; 866 i->openmax = 0; 867 changed = 1; 868 goto _l2; 869 } 870 } 871 i->empty = 1; 872 return -EINVAL; 873 _l2: 874 if (snd_interval_checkempty(i)) { 875 i->empty = 1; 876 return -EINVAL; 877 } 878 return changed; 879 } 880 881 static int snd_interval_step(snd_interval_t *i, unsigned int min, unsigned int step) 882 { 883 unsigned int n; 884 int changed = 0; 885 n = (i->min - min) % step; 886 if (n != 0 || i->openmin) { 887 i->min += step - n; 888 changed = 1; 889 } 890 n = (i->max - min) % step; 891 if (n != 0 || i->openmax) { 892 i->max -= n; 893 changed = 1; 894 } 895 if (snd_interval_checkempty(i)) { 896 i->empty = 1; 897 return -EINVAL; 898 } 899 return changed; 900 } 901 902 /* Info constraints helpers */ 903 904 /** 905 * snd_pcm_hw_rule_add - add the hw-constraint rule 906 * @runtime: the pcm runtime instance 907 * @cond: condition bits 908 * @var: the variable to evaluate 909 * @func: the evaluation function 910 * @private: the private data pointer passed to function 911 * @dep: the dependent variables 912 * 913 * Returns zero if successful, or a negative error code on failure. 914 */ 915 int snd_pcm_hw_rule_add(snd_pcm_runtime_t *runtime, unsigned int cond, 916 int var, 917 snd_pcm_hw_rule_func_t func, void *private, 918 int dep, ...) 919 { 920 snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints; 921 snd_pcm_hw_rule_t *c; 922 unsigned int k; 923 va_list args; 924 va_start(args, dep); 925 if (constrs->rules_num >= constrs->rules_all) { 926 snd_pcm_hw_rule_t *new; 927 unsigned int new_rules = constrs->rules_all + 16; 928 new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); 929 if (!new) 930 return -ENOMEM; 931 if (constrs->rules) { 932 memcpy(new, constrs->rules, 933 constrs->rules_num * sizeof(*c)); 934 kfree(constrs->rules); 935 } 936 constrs->rules = new; 937 constrs->rules_all = new_rules; 938 } 939 c = &constrs->rules[constrs->rules_num]; 940 c->cond = cond; 941 c->func = func; 942 c->var = var; 943 c->private = private; 944 k = 0; 945 while (1) { 946 snd_assert(k < ARRAY_SIZE(c->deps), return -EINVAL); 947 c->deps[k++] = dep; 948 if (dep < 0) 949 break; 950 dep = va_arg(args, int); 951 } 952 constrs->rules_num++; 953 va_end(args); 954 return 0; 955 } 956 957 /** 958 * snd_pcm_hw_constraint_mask 959 * @runtime: PCM runtime instance 960 * @var: hw_params variable to apply the mask 961 * @mask: the bitmap mask 962 * 963 * Apply the constraint of the given bitmap mask to a mask parameter. 964 */ 965 int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var, 966 u_int32_t mask) 967 { 968 snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints; 969 snd_mask_t *maskp = constrs_mask(constrs, var); 970 *maskp->bits &= mask; 971 memset(maskp->bits + 1, 0, (SNDRV_MASK_MAX-32) / 8); /* clear rest */ 972 if (*maskp->bits == 0) 973 return -EINVAL; 974 return 0; 975 } 976 977 /** 978 * snd_pcm_hw_constraint_mask64 979 * @runtime: PCM runtime instance 980 * @var: hw_params variable to apply the mask 981 * @mask: the 64bit bitmap mask 982 * 983 * Apply the constraint of the given bitmap mask to a mask parameter. 984 */ 985 int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var, 986 u_int64_t mask) 987 { 988 snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints; 989 snd_mask_t *maskp = constrs_mask(constrs, var); 990 maskp->bits[0] &= (u_int32_t)mask; 991 maskp->bits[1] &= (u_int32_t)(mask >> 32); 992 memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */ 993 if (! maskp->bits[0] && ! maskp->bits[1]) 994 return -EINVAL; 995 return 0; 996 } 997 998 /** 999 * snd_pcm_hw_constraint_integer 1000 * @runtime: PCM runtime instance 1001 * @var: hw_params variable to apply the integer constraint 1002 * 1003 * Apply the constraint of integer to an interval parameter. 1004 */ 1005 int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var) 1006 { 1007 snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints; 1008 return snd_interval_setinteger(constrs_interval(constrs, var)); 1009 } 1010 1011 /** 1012 * snd_pcm_hw_constraint_minmax 1013 * @runtime: PCM runtime instance 1014 * @var: hw_params variable to apply the range 1015 * @min: the minimal value 1016 * @max: the maximal value 1017 * 1018 * Apply the min/max range constraint to an interval parameter. 1019 */ 1020 int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var, 1021 unsigned int min, unsigned int max) 1022 { 1023 snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints; 1024 snd_interval_t t; 1025 t.min = min; 1026 t.max = max; 1027 t.openmin = t.openmax = 0; 1028 t.integer = 0; 1029 return snd_interval_refine(constrs_interval(constrs, var), &t); 1030 } 1031 1032 static int snd_pcm_hw_rule_list(snd_pcm_hw_params_t *params, 1033 snd_pcm_hw_rule_t *rule) 1034 { 1035 snd_pcm_hw_constraint_list_t *list = rule->private; 1036 return snd_interval_list(hw_param_interval(params, rule->var), list->count, list->list, list->mask); 1037 } 1038 1039 1040 /** 1041 * snd_pcm_hw_constraint_list 1042 * @runtime: PCM runtime instance 1043 * @cond: condition bits 1044 * @var: hw_params variable to apply the list constraint 1045 * @l: list 1046 * 1047 * Apply the list of constraints to an interval parameter. 1048 */ 1049 int snd_pcm_hw_constraint_list(snd_pcm_runtime_t *runtime, 1050 unsigned int cond, 1051 snd_pcm_hw_param_t var, 1052 snd_pcm_hw_constraint_list_t *l) 1053 { 1054 return snd_pcm_hw_rule_add(runtime, cond, var, 1055 snd_pcm_hw_rule_list, l, 1056 var, -1); 1057 } 1058 1059 static int snd_pcm_hw_rule_ratnums(snd_pcm_hw_params_t *params, 1060 snd_pcm_hw_rule_t *rule) 1061 { 1062 snd_pcm_hw_constraint_ratnums_t *r = rule->private; 1063 unsigned int num = 0, den = 0; 1064 int err; 1065 err = snd_interval_ratnum(hw_param_interval(params, rule->var), 1066 r->nrats, r->rats, &num, &den); 1067 if (err >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) { 1068 params->rate_num = num; 1069 params->rate_den = den; 1070 } 1071 return err; 1072 } 1073 1074 /** 1075 * snd_pcm_hw_constraint_ratnums 1076 * @runtime: PCM runtime instance 1077 * @cond: condition bits 1078 * @var: hw_params variable to apply the ratnums constraint 1079 * @r: ratnums_t constriants 1080 */ 1081 int snd_pcm_hw_constraint_ratnums(snd_pcm_runtime_t *runtime, 1082 unsigned int cond, 1083 snd_pcm_hw_param_t var, 1084 snd_pcm_hw_constraint_ratnums_t *r) 1085 { 1086 return snd_pcm_hw_rule_add(runtime, cond, var, 1087 snd_pcm_hw_rule_ratnums, r, 1088 var, -1); 1089 } 1090 1091 static int snd_pcm_hw_rule_ratdens(snd_pcm_hw_params_t *params, 1092 snd_pcm_hw_rule_t *rule) 1093 { 1094 snd_pcm_hw_constraint_ratdens_t *r = rule->private; 1095 unsigned int num = 0, den = 0; 1096 int err = snd_interval_ratden(hw_param_interval(params, rule->var), 1097 r->nrats, r->rats, &num, &den); 1098 if (err >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) { 1099 params->rate_num = num; 1100 params->rate_den = den; 1101 } 1102 return err; 1103 } 1104 1105 /** 1106 * snd_pcm_hw_constraint_ratdens 1107 * @runtime: PCM runtime instance 1108 * @cond: condition bits 1109 * @var: hw_params variable to apply the ratdens constraint 1110 * @r: ratdens_t constriants 1111 */ 1112 int snd_pcm_hw_constraint_ratdens(snd_pcm_runtime_t *runtime, 1113 unsigned int cond, 1114 snd_pcm_hw_param_t var, 1115 snd_pcm_hw_constraint_ratdens_t *r) 1116 { 1117 return snd_pcm_hw_rule_add(runtime, cond, var, 1118 snd_pcm_hw_rule_ratdens, r, 1119 var, -1); 1120 } 1121 1122 static int snd_pcm_hw_rule_msbits(snd_pcm_hw_params_t *params, 1123 snd_pcm_hw_rule_t *rule) 1124 { 1125 unsigned int l = (unsigned long) rule->private; 1126 int width = l & 0xffff; 1127 unsigned int msbits = l >> 16; 1128 snd_interval_t *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); 1129 if (snd_interval_single(i) && snd_interval_value(i) == width) 1130 params->msbits = msbits; 1131 return 0; 1132 } 1133 1134 /** 1135 * snd_pcm_hw_constraint_msbits 1136 * @runtime: PCM runtime instance 1137 * @cond: condition bits 1138 * @width: sample bits width 1139 * @msbits: msbits width 1140 */ 1141 int snd_pcm_hw_constraint_msbits(snd_pcm_runtime_t *runtime, 1142 unsigned int cond, 1143 unsigned int width, 1144 unsigned int msbits) 1145 { 1146 unsigned long l = (msbits << 16) | width; 1147 return snd_pcm_hw_rule_add(runtime, cond, -1, 1148 snd_pcm_hw_rule_msbits, 1149 (void*) l, 1150 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); 1151 } 1152 1153 static int snd_pcm_hw_rule_step(snd_pcm_hw_params_t *params, 1154 snd_pcm_hw_rule_t *rule) 1155 { 1156 unsigned long step = (unsigned long) rule->private; 1157 return snd_interval_step(hw_param_interval(params, rule->var), 0, step); 1158 } 1159 1160 /** 1161 * snd_pcm_hw_constraint_step 1162 * @runtime: PCM runtime instance 1163 * @cond: condition bits 1164 * @var: hw_params variable to apply the step constraint 1165 * @step: step size 1166 */ 1167 int snd_pcm_hw_constraint_step(snd_pcm_runtime_t *runtime, 1168 unsigned int cond, 1169 snd_pcm_hw_param_t var, 1170 unsigned long step) 1171 { 1172 return snd_pcm_hw_rule_add(runtime, cond, var, 1173 snd_pcm_hw_rule_step, (void *) step, 1174 var, -1); 1175 } 1176 1177 static int snd_pcm_hw_rule_pow2(snd_pcm_hw_params_t *params, snd_pcm_hw_rule_t *rule) 1178 { 1179 static int pow2_sizes[] = { 1180 1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7, 1181 1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15, 1182 1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23, 1183 1<<24, 1<<25, 1<<26, 1<<27, 1<<28, 1<<29, 1<<30 1184 }; 1185 return snd_interval_list(hw_param_interval(params, rule->var), 1186 ARRAY_SIZE(pow2_sizes), pow2_sizes, 0); 1187 } 1188 1189 /** 1190 * snd_pcm_hw_constraint_pow2 1191 * @runtime: PCM runtime instance 1192 * @cond: condition bits 1193 * @var: hw_params variable to apply the power-of-2 constraint 1194 */ 1195 int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime, 1196 unsigned int cond, 1197 snd_pcm_hw_param_t var) 1198 { 1199 return snd_pcm_hw_rule_add(runtime, cond, var, 1200 snd_pcm_hw_rule_pow2, NULL, 1201 var, -1); 1202 } 1203 1204 /* To use the same code we have in alsa-lib */ 1205 #define snd_pcm_t snd_pcm_substream_t 1206 #define assert(i) snd_assert((i), return -EINVAL) 1207 #ifndef INT_MIN 1208 #define INT_MIN ((int)((unsigned int)INT_MAX+1)) 1209 #endif 1210 1211 static void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, 1212 snd_pcm_hw_param_t var) 1213 { 1214 if (hw_is_mask(var)) { 1215 snd_mask_any(hw_param_mask(params, var)); 1216 params->cmask |= 1 << var; 1217 params->rmask |= 1 << var; 1218 return; 1219 } 1220 if (hw_is_interval(var)) { 1221 snd_interval_any(hw_param_interval(params, var)); 1222 params->cmask |= 1 << var; 1223 params->rmask |= 1 << var; 1224 return; 1225 } 1226 snd_BUG(); 1227 } 1228 1229 #if 0 1230 /* 1231 * snd_pcm_hw_param_any 1232 */ 1233 int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 1234 snd_pcm_hw_param_t var) 1235 { 1236 _snd_pcm_hw_param_any(params, var); 1237 return snd_pcm_hw_refine(pcm, params); 1238 } 1239 #endif /* 0 */ 1240 1241 void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params) 1242 { 1243 unsigned int k; 1244 memset(params, 0, sizeof(*params)); 1245 for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) 1246 _snd_pcm_hw_param_any(params, k); 1247 for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) 1248 _snd_pcm_hw_param_any(params, k); 1249 params->info = ~0U; 1250 } 1251 1252 #if 0 1253 /* 1254 * snd_pcm_hw_params_any 1255 * 1256 * Fill PARAMS with full configuration space boundaries 1257 */ 1258 int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) 1259 { 1260 _snd_pcm_hw_params_any(params); 1261 return snd_pcm_hw_refine(pcm, params); 1262 } 1263 #endif /* 0 */ 1264 1265 /** 1266 * snd_pcm_hw_param_value 1267 * @params: the hw_params instance 1268 * @var: parameter to retrieve 1269 * @dir: pointer to the direction (-1,0,1) or NULL 1270 * 1271 * Return the value for field PAR if it's fixed in configuration space 1272 * defined by PARAMS. Return -EINVAL otherwise 1273 */ 1274 static int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params, 1275 snd_pcm_hw_param_t var, int *dir) 1276 { 1277 if (hw_is_mask(var)) { 1278 const snd_mask_t *mask = hw_param_mask_c(params, var); 1279 if (!snd_mask_single(mask)) 1280 return -EINVAL; 1281 if (dir) 1282 *dir = 0; 1283 return snd_mask_value(mask); 1284 } 1285 if (hw_is_interval(var)) { 1286 const snd_interval_t *i = hw_param_interval_c(params, var); 1287 if (!snd_interval_single(i)) 1288 return -EINVAL; 1289 if (dir) 1290 *dir = i->openmin; 1291 return snd_interval_value(i); 1292 } 1293 assert(0); 1294 return -EINVAL; 1295 } 1296 1297 /** 1298 * snd_pcm_hw_param_value_min 1299 * @params: the hw_params instance 1300 * @var: parameter to retrieve 1301 * @dir: pointer to the direction (-1,0,1) or NULL 1302 * 1303 * Return the minimum value for field PAR. 1304 */ 1305 unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params, 1306 snd_pcm_hw_param_t var, int *dir) 1307 { 1308 if (hw_is_mask(var)) { 1309 if (dir) 1310 *dir = 0; 1311 return snd_mask_min(hw_param_mask_c(params, var)); 1312 } 1313 if (hw_is_interval(var)) { 1314 const snd_interval_t *i = hw_param_interval_c(params, var); 1315 if (dir) 1316 *dir = i->openmin; 1317 return snd_interval_min(i); 1318 } 1319 assert(0); 1320 return -EINVAL; 1321 } 1322 1323 /** 1324 * snd_pcm_hw_param_value_max 1325 * @params: the hw_params instance 1326 * @var: parameter to retrieve 1327 * @dir: pointer to the direction (-1,0,1) or NULL 1328 * 1329 * Return the maximum value for field PAR. 1330 */ 1331 unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params, 1332 snd_pcm_hw_param_t var, int *dir) 1333 { 1334 if (hw_is_mask(var)) { 1335 if (dir) 1336 *dir = 0; 1337 return snd_mask_max(hw_param_mask_c(params, var)); 1338 } 1339 if (hw_is_interval(var)) { 1340 const snd_interval_t *i = hw_param_interval_c(params, var); 1341 if (dir) 1342 *dir = - (int) i->openmax; 1343 return snd_interval_max(i); 1344 } 1345 assert(0); 1346 return -EINVAL; 1347 } 1348 1349 void _snd_pcm_hw_param_setempty(snd_pcm_hw_params_t *params, 1350 snd_pcm_hw_param_t var) 1351 { 1352 if (hw_is_mask(var)) { 1353 snd_mask_none(hw_param_mask(params, var)); 1354 params->cmask |= 1 << var; 1355 params->rmask |= 1 << var; 1356 } else if (hw_is_interval(var)) { 1357 snd_interval_none(hw_param_interval(params, var)); 1358 params->cmask |= 1 << var; 1359 params->rmask |= 1 << var; 1360 } else { 1361 snd_BUG(); 1362 } 1363 } 1364 1365 int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params, 1366 snd_pcm_hw_param_t var) 1367 { 1368 int changed; 1369 assert(hw_is_interval(var)); 1370 changed = snd_interval_setinteger(hw_param_interval(params, var)); 1371 if (changed) { 1372 params->cmask |= 1 << var; 1373 params->rmask |= 1 << var; 1374 } 1375 return changed; 1376 } 1377 1378 #if 0 1379 /* 1380 * snd_pcm_hw_param_setinteger 1381 * 1382 * Inside configuration space defined by PARAMS remove from PAR all 1383 * non integer values. Reduce configuration space accordingly. 1384 * Return -EINVAL if the configuration space is empty 1385 */ 1386 int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, 1387 snd_pcm_hw_params_t *params, 1388 snd_pcm_hw_param_t var) 1389 { 1390 int changed = _snd_pcm_hw_param_setinteger(params, var); 1391 if (changed < 0) 1392 return changed; 1393 if (params->rmask) { 1394 int err = snd_pcm_hw_refine(pcm, params); 1395 if (err < 0) 1396 return err; 1397 } 1398 return 0; 1399 } 1400 #endif /* 0 */ 1401 1402 static int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, 1403 snd_pcm_hw_param_t var) 1404 { 1405 int changed; 1406 if (hw_is_mask(var)) 1407 changed = snd_mask_refine_first(hw_param_mask(params, var)); 1408 else if (hw_is_interval(var)) 1409 changed = snd_interval_refine_first(hw_param_interval(params, var)); 1410 else { 1411 assert(0); 1412 return -EINVAL; 1413 } 1414 if (changed) { 1415 params->cmask |= 1 << var; 1416 params->rmask |= 1 << var; 1417 } 1418 return changed; 1419 } 1420 1421 1422 /** 1423 * snd_pcm_hw_param_first 1424 * @pcm: PCM instance 1425 * @params: the hw_params instance 1426 * @var: parameter to retrieve 1427 * @dir: pointer to the direction (-1,0,1) or NULL 1428 * 1429 * Inside configuration space defined by PARAMS remove from PAR all 1430 * values > minimum. Reduce configuration space accordingly. 1431 * Return the minimum. 1432 */ 1433 static int snd_pcm_hw_param_first(snd_pcm_t *pcm, 1434 snd_pcm_hw_params_t *params, 1435 snd_pcm_hw_param_t var, int *dir) 1436 { 1437 int changed = _snd_pcm_hw_param_first(params, var); 1438 if (changed < 0) 1439 return changed; 1440 if (params->rmask) { 1441 int err = snd_pcm_hw_refine(pcm, params); 1442 assert(err >= 0); 1443 } 1444 return snd_pcm_hw_param_value(params, var, dir); 1445 } 1446 1447 static int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, 1448 snd_pcm_hw_param_t var) 1449 { 1450 int changed; 1451 if (hw_is_mask(var)) 1452 changed = snd_mask_refine_last(hw_param_mask(params, var)); 1453 else if (hw_is_interval(var)) 1454 changed = snd_interval_refine_last(hw_param_interval(params, var)); 1455 else { 1456 assert(0); 1457 return -EINVAL; 1458 } 1459 if (changed) { 1460 params->cmask |= 1 << var; 1461 params->rmask |= 1 << var; 1462 } 1463 return changed; 1464 } 1465 1466 1467 /** 1468 * snd_pcm_hw_param_last 1469 * @pcm: PCM instance 1470 * @params: the hw_params instance 1471 * @var: parameter to retrieve 1472 * @dir: pointer to the direction (-1,0,1) or NULL 1473 * 1474 * Inside configuration space defined by PARAMS remove from PAR all 1475 * values < maximum. Reduce configuration space accordingly. 1476 * Return the maximum. 1477 */ 1478 static int snd_pcm_hw_param_last(snd_pcm_t *pcm, 1479 snd_pcm_hw_params_t *params, 1480 snd_pcm_hw_param_t var, int *dir) 1481 { 1482 int changed = _snd_pcm_hw_param_last(params, var); 1483 if (changed < 0) 1484 return changed; 1485 if (params->rmask) { 1486 int err = snd_pcm_hw_refine(pcm, params); 1487 assert(err >= 0); 1488 } 1489 return snd_pcm_hw_param_value(params, var, dir); 1490 } 1491 1492 int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, 1493 snd_pcm_hw_param_t var, unsigned int val, int dir) 1494 { 1495 int changed; 1496 int open = 0; 1497 if (dir) { 1498 if (dir > 0) { 1499 open = 1; 1500 } else if (dir < 0) { 1501 if (val > 0) { 1502 open = 1; 1503 val--; 1504 } 1505 } 1506 } 1507 if (hw_is_mask(var)) 1508 changed = snd_mask_refine_min(hw_param_mask(params, var), val + !!open); 1509 else if (hw_is_interval(var)) 1510 changed = snd_interval_refine_min(hw_param_interval(params, var), val, open); 1511 else { 1512 assert(0); 1513 return -EINVAL; 1514 } 1515 if (changed) { 1516 params->cmask |= 1 << var; 1517 params->rmask |= 1 << var; 1518 } 1519 return changed; 1520 } 1521 1522 /** 1523 * snd_pcm_hw_param_min 1524 * @pcm: PCM instance 1525 * @params: the hw_params instance 1526 * @var: parameter to retrieve 1527 * @val: minimal value 1528 * @dir: pointer to the direction (-1,0,1) or NULL 1529 * 1530 * Inside configuration space defined by PARAMS remove from PAR all 1531 * values < VAL. Reduce configuration space accordingly. 1532 * Return new minimum or -EINVAL if the configuration space is empty 1533 */ 1534 static int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 1535 snd_pcm_hw_param_t var, unsigned int val, 1536 int *dir) 1537 { 1538 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0); 1539 if (changed < 0) 1540 return changed; 1541 if (params->rmask) { 1542 int err = snd_pcm_hw_refine(pcm, params); 1543 if (err < 0) 1544 return err; 1545 } 1546 return snd_pcm_hw_param_value_min(params, var, dir); 1547 } 1548 1549 static int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, 1550 snd_pcm_hw_param_t var, unsigned int val, 1551 int dir) 1552 { 1553 int changed; 1554 int open = 0; 1555 if (dir) { 1556 if (dir < 0) { 1557 open = 1; 1558 } else if (dir > 0) { 1559 open = 1; 1560 val++; 1561 } 1562 } 1563 if (hw_is_mask(var)) { 1564 if (val == 0 && open) { 1565 snd_mask_none(hw_param_mask(params, var)); 1566 changed = -EINVAL; 1567 } else 1568 changed = snd_mask_refine_max(hw_param_mask(params, var), val - !!open); 1569 } else if (hw_is_interval(var)) 1570 changed = snd_interval_refine_max(hw_param_interval(params, var), val, open); 1571 else { 1572 assert(0); 1573 return -EINVAL; 1574 } 1575 if (changed) { 1576 params->cmask |= 1 << var; 1577 params->rmask |= 1 << var; 1578 } 1579 return changed; 1580 } 1581 1582 /** 1583 * snd_pcm_hw_param_max 1584 * @pcm: PCM instance 1585 * @params: the hw_params instance 1586 * @var: parameter to retrieve 1587 * @val: maximal value 1588 * @dir: pointer to the direction (-1,0,1) or NULL 1589 * 1590 * Inside configuration space defined by PARAMS remove from PAR all 1591 * values >= VAL + 1. Reduce configuration space accordingly. 1592 * Return new maximum or -EINVAL if the configuration space is empty 1593 */ 1594 static int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 1595 snd_pcm_hw_param_t var, unsigned int val, 1596 int *dir) 1597 { 1598 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0); 1599 if (changed < 0) 1600 return changed; 1601 if (params->rmask) { 1602 int err = snd_pcm_hw_refine(pcm, params); 1603 if (err < 0) 1604 return err; 1605 } 1606 return snd_pcm_hw_param_value_max(params, var, dir); 1607 } 1608 1609 int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params, 1610 snd_pcm_hw_param_t var, unsigned int val, int dir) 1611 { 1612 int changed; 1613 if (hw_is_mask(var)) { 1614 snd_mask_t *m = hw_param_mask(params, var); 1615 if (val == 0 && dir < 0) { 1616 changed = -EINVAL; 1617 snd_mask_none(m); 1618 } else { 1619 if (dir > 0) 1620 val++; 1621 else if (dir < 0) 1622 val--; 1623 changed = snd_mask_refine_set(hw_param_mask(params, var), val); 1624 } 1625 } else if (hw_is_interval(var)) { 1626 snd_interval_t *i = hw_param_interval(params, var); 1627 if (val == 0 && dir < 0) { 1628 changed = -EINVAL; 1629 snd_interval_none(i); 1630 } else if (dir == 0) 1631 changed = snd_interval_refine_set(i, val); 1632 else { 1633 snd_interval_t t; 1634 t.openmin = 1; 1635 t.openmax = 1; 1636 t.empty = 0; 1637 t.integer = 0; 1638 if (dir < 0) { 1639 t.min = val - 1; 1640 t.max = val; 1641 } else { 1642 t.min = val; 1643 t.max = val+1; 1644 } 1645 changed = snd_interval_refine(i, &t); 1646 } 1647 } else { 1648 assert(0); 1649 return -EINVAL; 1650 } 1651 if (changed) { 1652 params->cmask |= 1 << var; 1653 params->rmask |= 1 << var; 1654 } 1655 return changed; 1656 } 1657 1658 /** 1659 * snd_pcm_hw_param_set 1660 * @pcm: PCM instance 1661 * @params: the hw_params instance 1662 * @var: parameter to retrieve 1663 * @val: value to set 1664 * @dir: pointer to the direction (-1,0,1) or NULL 1665 * 1666 * Inside configuration space defined by PARAMS remove from PAR all 1667 * values != VAL. Reduce configuration space accordingly. 1668 * Return VAL or -EINVAL if the configuration space is empty 1669 */ 1670 int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 1671 snd_pcm_hw_param_t var, unsigned int val, int dir) 1672 { 1673 int changed = _snd_pcm_hw_param_set(params, var, val, dir); 1674 if (changed < 0) 1675 return changed; 1676 if (params->rmask) { 1677 int err = snd_pcm_hw_refine(pcm, params); 1678 if (err < 0) 1679 return err; 1680 } 1681 return snd_pcm_hw_param_value(params, var, NULL); 1682 } 1683 1684 static int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params, 1685 snd_pcm_hw_param_t var, const snd_mask_t *val) 1686 { 1687 int changed; 1688 assert(hw_is_mask(var)); 1689 changed = snd_mask_refine(hw_param_mask(params, var), val); 1690 if (changed) { 1691 params->cmask |= 1 << var; 1692 params->rmask |= 1 << var; 1693 } 1694 return changed; 1695 } 1696 1697 /** 1698 * snd_pcm_hw_param_mask 1699 * @pcm: PCM instance 1700 * @params: the hw_params instance 1701 * @var: parameter to retrieve 1702 * @val: mask to apply 1703 * 1704 * Inside configuration space defined by PARAMS remove from PAR all values 1705 * not contained in MASK. Reduce configuration space accordingly. 1706 * This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS, 1707 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. 1708 * Return 0 on success or -EINVAL 1709 * if the configuration space is empty 1710 */ 1711 int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 1712 snd_pcm_hw_param_t var, const snd_mask_t *val) 1713 { 1714 int changed = _snd_pcm_hw_param_mask(params, var, val); 1715 if (changed < 0) 1716 return changed; 1717 if (params->rmask) { 1718 int err = snd_pcm_hw_refine(pcm, params); 1719 if (err < 0) 1720 return err; 1721 } 1722 return 0; 1723 } 1724 1725 static int boundary_sub(int a, int adir, 1726 int b, int bdir, 1727 int *c, int *cdir) 1728 { 1729 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0); 1730 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0); 1731 *c = a - b; 1732 *cdir = adir - bdir; 1733 if (*cdir == -2) { 1734 assert(*c > INT_MIN); 1735 (*c)--; 1736 } else if (*cdir == 2) { 1737 assert(*c < INT_MAX); 1738 (*c)++; 1739 } 1740 return 0; 1741 } 1742 1743 static int boundary_lt(unsigned int a, int adir, 1744 unsigned int b, int bdir) 1745 { 1746 assert(a > 0 || adir >= 0); 1747 assert(b > 0 || bdir >= 0); 1748 if (adir < 0) { 1749 a--; 1750 adir = 1; 1751 } else if (adir > 0) 1752 adir = 1; 1753 if (bdir < 0) { 1754 b--; 1755 bdir = 1; 1756 } else if (bdir > 0) 1757 bdir = 1; 1758 return a < b || (a == b && adir < bdir); 1759 } 1760 1761 /* Return 1 if min is nearer to best than max */ 1762 static int boundary_nearer(int min, int mindir, 1763 int best, int bestdir, 1764 int max, int maxdir) 1765 { 1766 int dmin, dmindir; 1767 int dmax, dmaxdir; 1768 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir); 1769 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir); 1770 return boundary_lt(dmin, dmindir, dmax, dmaxdir); 1771 } 1772 1773 /** 1774 * snd_pcm_hw_param_near 1775 * @pcm: PCM instance 1776 * @params: the hw_params instance 1777 * @var: parameter to retrieve 1778 * @best: value to set 1779 * @dir: pointer to the direction (-1,0,1) or NULL 1780 * 1781 * Inside configuration space defined by PARAMS set PAR to the available value 1782 * nearest to VAL. Reduce configuration space accordingly. 1783 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS, 1784 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT. 1785 * Return the value found. 1786 */ 1787 int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, 1788 snd_pcm_hw_param_t var, unsigned int best, int *dir) 1789 { 1790 snd_pcm_hw_params_t *save = NULL; 1791 int v; 1792 unsigned int saved_min; 1793 int last = 0; 1794 int min, max; 1795 int mindir, maxdir; 1796 int valdir = dir ? *dir : 0; 1797 /* FIXME */ 1798 if (best > INT_MAX) 1799 best = INT_MAX; 1800 min = max = best; 1801 mindir = maxdir = valdir; 1802 if (maxdir > 0) 1803 maxdir = 0; 1804 else if (maxdir == 0) 1805 maxdir = -1; 1806 else { 1807 maxdir = 1; 1808 max--; 1809 } 1810 save = kmalloc(sizeof(*save), GFP_KERNEL); 1811 if (save == NULL) 1812 return -ENOMEM; 1813 *save = *params; 1814 saved_min = min; 1815 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir); 1816 if (min >= 0) { 1817 snd_pcm_hw_params_t *params1; 1818 if (max < 0) 1819 goto _end; 1820 if ((unsigned int)min == saved_min && mindir == valdir) 1821 goto _end; 1822 params1 = kmalloc(sizeof(*params1), GFP_KERNEL); 1823 if (params1 == NULL) { 1824 kfree(save); 1825 return -ENOMEM; 1826 } 1827 *params1 = *save; 1828 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir); 1829 if (max < 0) { 1830 kfree(params1); 1831 goto _end; 1832 } 1833 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) { 1834 *params = *params1; 1835 last = 1; 1836 } 1837 kfree(params1); 1838 } else { 1839 *params = *save; 1840 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); 1841 assert(max >= 0); 1842 last = 1; 1843 } 1844 _end: 1845 kfree(save); 1846 if (last) 1847 v = snd_pcm_hw_param_last(pcm, params, var, dir); 1848 else 1849 v = snd_pcm_hw_param_first(pcm, params, var, dir); 1850 assert(v >= 0); 1851 return v; 1852 } 1853 1854 /** 1855 * snd_pcm_hw_param_choose 1856 * @pcm: PCM instance 1857 * @params: the hw_params instance 1858 * 1859 * Choose one configuration from configuration space defined by PARAMS 1860 * The configuration chosen is that obtained fixing in this order: 1861 * first access, first format, first subformat, min channels, 1862 * min rate, min period time, max buffer size, min tick time 1863 */ 1864 int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) 1865 { 1866 int err; 1867 1868 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_ACCESS, NULL); 1869 assert(err >= 0); 1870 1871 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_FORMAT, NULL); 1872 assert(err >= 0); 1873 1874 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_SUBFORMAT, NULL); 1875 assert(err >= 0); 1876 1877 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_CHANNELS, NULL); 1878 assert(err >= 0); 1879 1880 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_RATE, NULL); 1881 assert(err >= 0); 1882 1883 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, NULL); 1884 assert(err >= 0); 1885 1886 err = snd_pcm_hw_param_last(pcm, params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL); 1887 assert(err >= 0); 1888 1889 err = snd_pcm_hw_param_first(pcm, params, SNDRV_PCM_HW_PARAM_TICK_TIME, NULL); 1890 assert(err >= 0); 1891 1892 return 0; 1893 } 1894 1895 #undef snd_pcm_t 1896 #undef assert 1897 1898 static int snd_pcm_lib_ioctl_reset(snd_pcm_substream_t *substream, 1899 void *arg) 1900 { 1901 snd_pcm_runtime_t *runtime = substream->runtime; 1902 unsigned long flags; 1903 snd_pcm_stream_lock_irqsave(substream, flags); 1904 if (snd_pcm_running(substream) && 1905 snd_pcm_update_hw_ptr(substream) >= 0) 1906 runtime->status->hw_ptr %= runtime->buffer_size; 1907 else 1908 runtime->status->hw_ptr = 0; 1909 snd_pcm_stream_unlock_irqrestore(substream, flags); 1910 return 0; 1911 } 1912 1913 static int snd_pcm_lib_ioctl_channel_info(snd_pcm_substream_t *substream, 1914 void *arg) 1915 { 1916 snd_pcm_channel_info_t *info = arg; 1917 snd_pcm_runtime_t *runtime = substream->runtime; 1918 int width; 1919 if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) { 1920 info->offset = -1; 1921 return 0; 1922 } 1923 width = snd_pcm_format_physical_width(runtime->format); 1924 if (width < 0) 1925 return width; 1926 info->offset = 0; 1927 switch (runtime->access) { 1928 case SNDRV_PCM_ACCESS_MMAP_INTERLEAVED: 1929 case SNDRV_PCM_ACCESS_RW_INTERLEAVED: 1930 info->first = info->channel * width; 1931 info->step = runtime->channels * width; 1932 break; 1933 case SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED: 1934 case SNDRV_PCM_ACCESS_RW_NONINTERLEAVED: 1935 { 1936 size_t size = runtime->dma_bytes / runtime->channels; 1937 info->first = info->channel * size * 8; 1938 info->step = width; 1939 break; 1940 } 1941 default: 1942 snd_BUG(); 1943 break; 1944 } 1945 return 0; 1946 } 1947 1948 /** 1949 * snd_pcm_lib_ioctl - a generic PCM ioctl callback 1950 * @substream: the pcm substream instance 1951 * @cmd: ioctl command 1952 * @arg: ioctl argument 1953 * 1954 * Processes the generic ioctl commands for PCM. 1955 * Can be passed as the ioctl callback for PCM ops. 1956 * 1957 * Returns zero if successful, or a negative error code on failure. 1958 */ 1959 int snd_pcm_lib_ioctl(snd_pcm_substream_t *substream, 1960 unsigned int cmd, void *arg) 1961 { 1962 switch (cmd) { 1963 case SNDRV_PCM_IOCTL1_INFO: 1964 return 0; 1965 case SNDRV_PCM_IOCTL1_RESET: 1966 return snd_pcm_lib_ioctl_reset(substream, arg); 1967 case SNDRV_PCM_IOCTL1_CHANNEL_INFO: 1968 return snd_pcm_lib_ioctl_channel_info(substream, arg); 1969 } 1970 return -ENXIO; 1971 } 1972 1973 /* 1974 * Conditions 1975 */ 1976 1977 static void snd_pcm_system_tick_set(snd_pcm_substream_t *substream, 1978 unsigned long ticks) 1979 { 1980 snd_pcm_runtime_t *runtime = substream->runtime; 1981 if (ticks == 0) 1982 del_timer(&runtime->tick_timer); 1983 else { 1984 ticks += (1000000 / HZ) - 1; 1985 ticks /= (1000000 / HZ); 1986 mod_timer(&runtime->tick_timer, jiffies + ticks); 1987 } 1988 } 1989 1990 /* Temporary alias */ 1991 void snd_pcm_tick_set(snd_pcm_substream_t *substream, unsigned long ticks) 1992 { 1993 snd_pcm_system_tick_set(substream, ticks); 1994 } 1995 1996 void snd_pcm_tick_prepare(snd_pcm_substream_t *substream) 1997 { 1998 snd_pcm_runtime_t *runtime = substream->runtime; 1999 snd_pcm_uframes_t frames = ULONG_MAX; 2000 snd_pcm_uframes_t avail, dist; 2001 unsigned int ticks; 2002 u_int64_t n; 2003 u_int32_t r; 2004 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 2005 if (runtime->silence_size >= runtime->boundary) { 2006 frames = 1; 2007 } else if (runtime->silence_size > 0 && 2008 runtime->silence_filled < runtime->buffer_size) { 2009 snd_pcm_sframes_t noise_dist; 2010 noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled; 2011 snd_assert(noise_dist <= (snd_pcm_sframes_t)runtime->silence_threshold, ); 2012 frames = noise_dist - runtime->silence_threshold; 2013 } 2014 avail = snd_pcm_playback_avail(runtime); 2015 } else { 2016 avail = snd_pcm_capture_avail(runtime); 2017 } 2018 if (avail < runtime->control->avail_min) { 2019 snd_pcm_sframes_t n = runtime->control->avail_min - avail; 2020 if (n > 0 && frames > (snd_pcm_uframes_t)n) 2021 frames = n; 2022 } 2023 if (avail < runtime->buffer_size) { 2024 snd_pcm_sframes_t n = runtime->buffer_size - avail; 2025 if (n > 0 && frames > (snd_pcm_uframes_t)n) 2026 frames = n; 2027 } 2028 if (frames == ULONG_MAX) { 2029 snd_pcm_tick_set(substream, 0); 2030 return; 2031 } 2032 dist = runtime->status->hw_ptr - runtime->hw_ptr_base; 2033 /* Distance to next interrupt */ 2034 dist = runtime->period_size - dist % runtime->period_size; 2035 if (dist <= frames) { 2036 snd_pcm_tick_set(substream, 0); 2037 return; 2038 } 2039 /* the base time is us */ 2040 n = frames; 2041 n *= 1000000; 2042 div64_32(&n, runtime->tick_time * runtime->rate, &r); 2043 ticks = n + (r > 0 ? 1 : 0); 2044 if (ticks < runtime->sleep_min) 2045 ticks = runtime->sleep_min; 2046 snd_pcm_tick_set(substream, (unsigned long) ticks); 2047 } 2048 2049 void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream) 2050 { 2051 snd_pcm_runtime_t *runtime; 2052 unsigned long flags; 2053 2054 snd_assert(substream != NULL, return); 2055 runtime = substream->runtime; 2056 snd_assert(runtime != NULL, return); 2057 2058 snd_pcm_stream_lock_irqsave(substream, flags); 2059 if (!snd_pcm_running(substream) || 2060 snd_pcm_update_hw_ptr(substream) < 0) 2061 goto _end; 2062 if (runtime->sleep_min) 2063 snd_pcm_tick_prepare(substream); 2064 _end: 2065 snd_pcm_stream_unlock_irqrestore(substream, flags); 2066 } 2067 2068 /** 2069 * snd_pcm_period_elapsed - update the pcm status for the next period 2070 * @substream: the pcm substream instance 2071 * 2072 * This function is called from the interrupt handler when the 2073 * PCM has processed the period size. It will update the current 2074 * pointer, set up the tick, wake up sleepers, etc. 2075 * 2076 * Even if more than one periods have elapsed since the last call, you 2077 * have to call this only once. 2078 */ 2079 void snd_pcm_period_elapsed(snd_pcm_substream_t *substream) 2080 { 2081 snd_pcm_runtime_t *runtime; 2082 unsigned long flags; 2083 2084 snd_assert(substream != NULL, return); 2085 runtime = substream->runtime; 2086 snd_assert(runtime != NULL, return); 2087 2088 if (runtime->transfer_ack_begin) 2089 runtime->transfer_ack_begin(substream); 2090 2091 snd_pcm_stream_lock_irqsave(substream, flags); 2092 if (!snd_pcm_running(substream) || 2093 snd_pcm_update_hw_ptr_interrupt(substream) < 0) 2094 goto _end; 2095 2096 if (substream->timer_running) 2097 snd_timer_interrupt(substream->timer, 1); 2098 if (runtime->sleep_min) 2099 snd_pcm_tick_prepare(substream); 2100 _end: 2101 snd_pcm_stream_unlock_irqrestore(substream, flags); 2102 if (runtime->transfer_ack_end) 2103 runtime->transfer_ack_end(substream); 2104 kill_fasync(&runtime->fasync, SIGIO, POLL_IN); 2105 } 2106 2107 static int snd_pcm_lib_write_transfer(snd_pcm_substream_t *substream, 2108 unsigned int hwoff, 2109 unsigned long data, unsigned int off, 2110 snd_pcm_uframes_t frames) 2111 { 2112 snd_pcm_runtime_t *runtime = substream->runtime; 2113 int err; 2114 char __user *buf = (char __user *) data + frames_to_bytes(runtime, off); 2115 if (substream->ops->copy) { 2116 if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0) 2117 return err; 2118 } else { 2119 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); 2120 snd_assert(runtime->dma_area, return -EFAULT); 2121 if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) 2122 return -EFAULT; 2123 } 2124 return 0; 2125 } 2126 2127 typedef int (*transfer_f)(snd_pcm_substream_t *substream, unsigned int hwoff, 2128 unsigned long data, unsigned int off, 2129 snd_pcm_uframes_t size); 2130 2131 static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, 2132 unsigned long data, 2133 snd_pcm_uframes_t size, 2134 int nonblock, 2135 transfer_f transfer) 2136 { 2137 snd_pcm_runtime_t *runtime = substream->runtime; 2138 snd_pcm_uframes_t xfer = 0; 2139 snd_pcm_uframes_t offset = 0; 2140 int err = 0; 2141 2142 if (size == 0) 2143 return 0; 2144 if (size > runtime->xfer_align) 2145 size -= size % runtime->xfer_align; 2146 2147 snd_pcm_stream_lock_irq(substream); 2148 switch (runtime->status->state) { 2149 case SNDRV_PCM_STATE_PREPARED: 2150 case SNDRV_PCM_STATE_RUNNING: 2151 case SNDRV_PCM_STATE_PAUSED: 2152 break; 2153 case SNDRV_PCM_STATE_XRUN: 2154 err = -EPIPE; 2155 goto _end_unlock; 2156 case SNDRV_PCM_STATE_SUSPENDED: 2157 err = -ESTRPIPE; 2158 goto _end_unlock; 2159 default: 2160 err = -EBADFD; 2161 goto _end_unlock; 2162 } 2163 2164 while (size > 0) { 2165 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2166 snd_pcm_uframes_t avail; 2167 snd_pcm_uframes_t cont; 2168 if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING) 2169 snd_pcm_update_hw_ptr(substream); 2170 avail = snd_pcm_playback_avail(runtime); 2171 if (((avail < runtime->control->avail_min && size > avail) || 2172 (size >= runtime->xfer_align && avail < runtime->xfer_align))) { 2173 wait_queue_t wait; 2174 enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state; 2175 long tout; 2176 2177 if (nonblock) { 2178 err = -EAGAIN; 2179 goto _end_unlock; 2180 } 2181 2182 init_waitqueue_entry(&wait, current); 2183 add_wait_queue(&runtime->sleep, &wait); 2184 while (1) { 2185 if (signal_pending(current)) { 2186 state = SIGNALED; 2187 break; 2188 } 2189 set_current_state(TASK_INTERRUPTIBLE); 2190 snd_pcm_stream_unlock_irq(substream); 2191 tout = schedule_timeout(10 * HZ); 2192 snd_pcm_stream_lock_irq(substream); 2193 if (tout == 0) { 2194 if (runtime->status->state != SNDRV_PCM_STATE_PREPARED && 2195 runtime->status->state != SNDRV_PCM_STATE_PAUSED) { 2196 state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED; 2197 break; 2198 } 2199 } 2200 switch (runtime->status->state) { 2201 case SNDRV_PCM_STATE_XRUN: 2202 case SNDRV_PCM_STATE_DRAINING: 2203 state = ERROR; 2204 goto _end_loop; 2205 case SNDRV_PCM_STATE_SUSPENDED: 2206 state = SUSPENDED; 2207 goto _end_loop; 2208 case SNDRV_PCM_STATE_SETUP: 2209 state = DROPPED; 2210 goto _end_loop; 2211 default: 2212 break; 2213 } 2214 avail = snd_pcm_playback_avail(runtime); 2215 if (avail >= runtime->control->avail_min) { 2216 state = READY; 2217 break; 2218 } 2219 } 2220 _end_loop: 2221 remove_wait_queue(&runtime->sleep, &wait); 2222 2223 switch (state) { 2224 case ERROR: 2225 err = -EPIPE; 2226 goto _end_unlock; 2227 case SUSPENDED: 2228 err = -ESTRPIPE; 2229 goto _end_unlock; 2230 case SIGNALED: 2231 err = -ERESTARTSYS; 2232 goto _end_unlock; 2233 case EXPIRED: 2234 snd_printd("playback write error (DMA or IRQ trouble?)\n"); 2235 err = -EIO; 2236 goto _end_unlock; 2237 case DROPPED: 2238 err = -EBADFD; 2239 goto _end_unlock; 2240 default: 2241 break; 2242 } 2243 } 2244 if (avail > runtime->xfer_align) 2245 avail -= avail % runtime->xfer_align; 2246 frames = size > avail ? avail : size; 2247 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; 2248 if (frames > cont) 2249 frames = cont; 2250 snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL); 2251 appl_ptr = runtime->control->appl_ptr; 2252 appl_ofs = appl_ptr % runtime->buffer_size; 2253 snd_pcm_stream_unlock_irq(substream); 2254 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 2255 goto _end; 2256 snd_pcm_stream_lock_irq(substream); 2257 switch (runtime->status->state) { 2258 case SNDRV_PCM_STATE_XRUN: 2259 err = -EPIPE; 2260 goto _end_unlock; 2261 case SNDRV_PCM_STATE_SUSPENDED: 2262 err = -ESTRPIPE; 2263 goto _end_unlock; 2264 default: 2265 break; 2266 } 2267 appl_ptr += frames; 2268 if (appl_ptr >= runtime->boundary) 2269 appl_ptr -= runtime->boundary; 2270 runtime->control->appl_ptr = appl_ptr; 2271 if (substream->ops->ack) 2272 substream->ops->ack(substream); 2273 2274 offset += frames; 2275 size -= frames; 2276 xfer += frames; 2277 if (runtime->status->state == SNDRV_PCM_STATE_PREPARED && 2278 snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) { 2279 err = snd_pcm_start(substream); 2280 if (err < 0) 2281 goto _end_unlock; 2282 } 2283 if (runtime->sleep_min && 2284 runtime->status->state == SNDRV_PCM_STATE_RUNNING) 2285 snd_pcm_tick_prepare(substream); 2286 } 2287 _end_unlock: 2288 snd_pcm_stream_unlock_irq(substream); 2289 _end: 2290 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 2291 } 2292 2293 snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void __user *buf, snd_pcm_uframes_t size) 2294 { 2295 snd_pcm_runtime_t *runtime; 2296 int nonblock; 2297 2298 snd_assert(substream != NULL, return -ENXIO); 2299 runtime = substream->runtime; 2300 snd_assert(runtime != NULL, return -ENXIO); 2301 snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); 2302 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2303 return -EBADFD; 2304 2305 snd_assert(substream->ffile != NULL, return -ENXIO); 2306 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2307 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 2308 if (substream->oss.oss) { 2309 snd_pcm_oss_setup_t *setup = substream->oss.setup; 2310 if (setup != NULL) { 2311 if (setup->nonblock) 2312 nonblock = 1; 2313 else if (setup->block) 2314 nonblock = 0; 2315 } 2316 } 2317 #endif 2318 2319 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && 2320 runtime->channels > 1) 2321 return -EINVAL; 2322 return snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock, 2323 snd_pcm_lib_write_transfer); 2324 } 2325 2326 static int snd_pcm_lib_writev_transfer(snd_pcm_substream_t *substream, 2327 unsigned int hwoff, 2328 unsigned long data, unsigned int off, 2329 snd_pcm_uframes_t frames) 2330 { 2331 snd_pcm_runtime_t *runtime = substream->runtime; 2332 int err; 2333 void __user **bufs = (void __user **)data; 2334 int channels = runtime->channels; 2335 int c; 2336 if (substream->ops->copy) { 2337 snd_assert(substream->ops->silence != NULL, return -EINVAL); 2338 for (c = 0; c < channels; ++c, ++bufs) { 2339 if (*bufs == NULL) { 2340 if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0) 2341 return err; 2342 } else { 2343 char __user *buf = *bufs + samples_to_bytes(runtime, off); 2344 if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0) 2345 return err; 2346 } 2347 } 2348 } else { 2349 /* default transfer behaviour */ 2350 size_t dma_csize = runtime->dma_bytes / channels; 2351 snd_assert(runtime->dma_area, return -EFAULT); 2352 for (c = 0; c < channels; ++c, ++bufs) { 2353 char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); 2354 if (*bufs == NULL) { 2355 snd_pcm_format_set_silence(runtime->format, hwbuf, frames); 2356 } else { 2357 char __user *buf = *bufs + samples_to_bytes(runtime, off); 2358 if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames))) 2359 return -EFAULT; 2360 } 2361 } 2362 } 2363 return 0; 2364 } 2365 2366 snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream, 2367 void __user **bufs, 2368 snd_pcm_uframes_t frames) 2369 { 2370 snd_pcm_runtime_t *runtime; 2371 int nonblock; 2372 2373 snd_assert(substream != NULL, return -ENXIO); 2374 runtime = substream->runtime; 2375 snd_assert(runtime != NULL, return -ENXIO); 2376 snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); 2377 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2378 return -EBADFD; 2379 2380 snd_assert(substream->ffile != NULL, return -ENXIO); 2381 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2382 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 2383 if (substream->oss.oss) { 2384 snd_pcm_oss_setup_t *setup = substream->oss.setup; 2385 if (setup != NULL) { 2386 if (setup->nonblock) 2387 nonblock = 1; 2388 else if (setup->block) 2389 nonblock = 0; 2390 } 2391 } 2392 #endif 2393 2394 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 2395 return -EINVAL; 2396 return snd_pcm_lib_write1(substream, (unsigned long)bufs, frames, 2397 nonblock, snd_pcm_lib_writev_transfer); 2398 } 2399 2400 static int snd_pcm_lib_read_transfer(snd_pcm_substream_t *substream, 2401 unsigned int hwoff, 2402 unsigned long data, unsigned int off, 2403 snd_pcm_uframes_t frames) 2404 { 2405 snd_pcm_runtime_t *runtime = substream->runtime; 2406 int err; 2407 char __user *buf = (char __user *) data + frames_to_bytes(runtime, off); 2408 if (substream->ops->copy) { 2409 if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0) 2410 return err; 2411 } else { 2412 char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); 2413 snd_assert(runtime->dma_area, return -EFAULT); 2414 if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) 2415 return -EFAULT; 2416 } 2417 return 0; 2418 } 2419 2420 static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, 2421 unsigned long data, 2422 snd_pcm_uframes_t size, 2423 int nonblock, 2424 transfer_f transfer) 2425 { 2426 snd_pcm_runtime_t *runtime = substream->runtime; 2427 snd_pcm_uframes_t xfer = 0; 2428 snd_pcm_uframes_t offset = 0; 2429 int err = 0; 2430 2431 if (size == 0) 2432 return 0; 2433 if (size > runtime->xfer_align) 2434 size -= size % runtime->xfer_align; 2435 2436 snd_pcm_stream_lock_irq(substream); 2437 switch (runtime->status->state) { 2438 case SNDRV_PCM_STATE_PREPARED: 2439 if (size >= runtime->start_threshold) { 2440 err = snd_pcm_start(substream); 2441 if (err < 0) 2442 goto _end_unlock; 2443 } 2444 break; 2445 case SNDRV_PCM_STATE_DRAINING: 2446 case SNDRV_PCM_STATE_RUNNING: 2447 case SNDRV_PCM_STATE_PAUSED: 2448 break; 2449 case SNDRV_PCM_STATE_XRUN: 2450 err = -EPIPE; 2451 goto _end_unlock; 2452 case SNDRV_PCM_STATE_SUSPENDED: 2453 err = -ESTRPIPE; 2454 goto _end_unlock; 2455 default: 2456 err = -EBADFD; 2457 goto _end_unlock; 2458 } 2459 2460 while (size > 0) { 2461 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2462 snd_pcm_uframes_t avail; 2463 snd_pcm_uframes_t cont; 2464 if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING) 2465 snd_pcm_update_hw_ptr(substream); 2466 __draining: 2467 avail = snd_pcm_capture_avail(runtime); 2468 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { 2469 if (avail < runtime->xfer_align) { 2470 err = -EPIPE; 2471 goto _end_unlock; 2472 } 2473 } else if ((avail < runtime->control->avail_min && size > avail) || 2474 (size >= runtime->xfer_align && avail < runtime->xfer_align)) { 2475 wait_queue_t wait; 2476 enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state; 2477 long tout; 2478 2479 if (nonblock) { 2480 err = -EAGAIN; 2481 goto _end_unlock; 2482 } 2483 2484 init_waitqueue_entry(&wait, current); 2485 add_wait_queue(&runtime->sleep, &wait); 2486 while (1) { 2487 if (signal_pending(current)) { 2488 state = SIGNALED; 2489 break; 2490 } 2491 set_current_state(TASK_INTERRUPTIBLE); 2492 snd_pcm_stream_unlock_irq(substream); 2493 tout = schedule_timeout(10 * HZ); 2494 snd_pcm_stream_lock_irq(substream); 2495 if (tout == 0) { 2496 if (runtime->status->state != SNDRV_PCM_STATE_PREPARED && 2497 runtime->status->state != SNDRV_PCM_STATE_PAUSED) { 2498 state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED; 2499 break; 2500 } 2501 } 2502 switch (runtime->status->state) { 2503 case SNDRV_PCM_STATE_XRUN: 2504 state = ERROR; 2505 goto _end_loop; 2506 case SNDRV_PCM_STATE_SUSPENDED: 2507 state = SUSPENDED; 2508 goto _end_loop; 2509 case SNDRV_PCM_STATE_DRAINING: 2510 goto __draining; 2511 case SNDRV_PCM_STATE_SETUP: 2512 state = DROPPED; 2513 goto _end_loop; 2514 default: 2515 break; 2516 } 2517 avail = snd_pcm_capture_avail(runtime); 2518 if (avail >= runtime->control->avail_min) { 2519 state = READY; 2520 break; 2521 } 2522 } 2523 _end_loop: 2524 remove_wait_queue(&runtime->sleep, &wait); 2525 2526 switch (state) { 2527 case ERROR: 2528 err = -EPIPE; 2529 goto _end_unlock; 2530 case SUSPENDED: 2531 err = -ESTRPIPE; 2532 goto _end_unlock; 2533 case SIGNALED: 2534 err = -ERESTARTSYS; 2535 goto _end_unlock; 2536 case EXPIRED: 2537 snd_printd("capture read error (DMA or IRQ trouble?)\n"); 2538 err = -EIO; 2539 goto _end_unlock; 2540 case DROPPED: 2541 err = -EBADFD; 2542 goto _end_unlock; 2543 default: 2544 break; 2545 } 2546 } 2547 if (avail > runtime->xfer_align) 2548 avail -= avail % runtime->xfer_align; 2549 frames = size > avail ? avail : size; 2550 cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; 2551 if (frames > cont) 2552 frames = cont; 2553 snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL); 2554 appl_ptr = runtime->control->appl_ptr; 2555 appl_ofs = appl_ptr % runtime->buffer_size; 2556 snd_pcm_stream_unlock_irq(substream); 2557 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 2558 goto _end; 2559 snd_pcm_stream_lock_irq(substream); 2560 switch (runtime->status->state) { 2561 case SNDRV_PCM_STATE_XRUN: 2562 err = -EPIPE; 2563 goto _end_unlock; 2564 case SNDRV_PCM_STATE_SUSPENDED: 2565 err = -ESTRPIPE; 2566 goto _end_unlock; 2567 default: 2568 break; 2569 } 2570 appl_ptr += frames; 2571 if (appl_ptr >= runtime->boundary) 2572 appl_ptr -= runtime->boundary; 2573 runtime->control->appl_ptr = appl_ptr; 2574 if (substream->ops->ack) 2575 substream->ops->ack(substream); 2576 2577 offset += frames; 2578 size -= frames; 2579 xfer += frames; 2580 if (runtime->sleep_min && 2581 runtime->status->state == SNDRV_PCM_STATE_RUNNING) 2582 snd_pcm_tick_prepare(substream); 2583 } 2584 _end_unlock: 2585 snd_pcm_stream_unlock_irq(substream); 2586 _end: 2587 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 2588 } 2589 2590 snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void __user *buf, snd_pcm_uframes_t size) 2591 { 2592 snd_pcm_runtime_t *runtime; 2593 int nonblock; 2594 2595 snd_assert(substream != NULL, return -ENXIO); 2596 runtime = substream->runtime; 2597 snd_assert(runtime != NULL, return -ENXIO); 2598 snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); 2599 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2600 return -EBADFD; 2601 2602 snd_assert(substream->ffile != NULL, return -ENXIO); 2603 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2604 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 2605 if (substream->oss.oss) { 2606 snd_pcm_oss_setup_t *setup = substream->oss.setup; 2607 if (setup != NULL) { 2608 if (setup->nonblock) 2609 nonblock = 1; 2610 else if (setup->block) 2611 nonblock = 0; 2612 } 2613 } 2614 #endif 2615 if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) 2616 return -EINVAL; 2617 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); 2618 } 2619 2620 static int snd_pcm_lib_readv_transfer(snd_pcm_substream_t *substream, 2621 unsigned int hwoff, 2622 unsigned long data, unsigned int off, 2623 snd_pcm_uframes_t frames) 2624 { 2625 snd_pcm_runtime_t *runtime = substream->runtime; 2626 int err; 2627 void __user **bufs = (void __user **)data; 2628 int channels = runtime->channels; 2629 int c; 2630 if (substream->ops->copy) { 2631 for (c = 0; c < channels; ++c, ++bufs) { 2632 char __user *buf; 2633 if (*bufs == NULL) 2634 continue; 2635 buf = *bufs + samples_to_bytes(runtime, off); 2636 if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0) 2637 return err; 2638 } 2639 } else { 2640 snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; 2641 snd_assert(runtime->dma_area, return -EFAULT); 2642 for (c = 0; c < channels; ++c, ++bufs) { 2643 char *hwbuf; 2644 char __user *buf; 2645 if (*bufs == NULL) 2646 continue; 2647 2648 hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); 2649 buf = *bufs + samples_to_bytes(runtime, off); 2650 if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames))) 2651 return -EFAULT; 2652 } 2653 } 2654 return 0; 2655 } 2656 2657 snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream, 2658 void __user **bufs, 2659 snd_pcm_uframes_t frames) 2660 { 2661 snd_pcm_runtime_t *runtime; 2662 int nonblock; 2663 2664 snd_assert(substream != NULL, return -ENXIO); 2665 runtime = substream->runtime; 2666 snd_assert(runtime != NULL, return -ENXIO); 2667 snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); 2668 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) 2669 return -EBADFD; 2670 2671 snd_assert(substream->ffile != NULL, return -ENXIO); 2672 nonblock = !!(substream->ffile->f_flags & O_NONBLOCK); 2673 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) 2674 if (substream->oss.oss) { 2675 snd_pcm_oss_setup_t *setup = substream->oss.setup; 2676 if (setup != NULL) { 2677 if (setup->nonblock) 2678 nonblock = 1; 2679 else if (setup->block) 2680 nonblock = 0; 2681 } 2682 } 2683 #endif 2684 2685 if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 2686 return -EINVAL; 2687 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); 2688 } 2689 2690 /* 2691 * Exported symbols 2692 */ 2693 2694 EXPORT_SYMBOL(snd_interval_refine); 2695 EXPORT_SYMBOL(snd_interval_list); 2696 EXPORT_SYMBOL(snd_interval_ratnum); 2697 EXPORT_SYMBOL(_snd_pcm_hw_params_any); 2698 EXPORT_SYMBOL(_snd_pcm_hw_param_min); 2699 EXPORT_SYMBOL(_snd_pcm_hw_param_set); 2700 EXPORT_SYMBOL(_snd_pcm_hw_param_setempty); 2701 EXPORT_SYMBOL(_snd_pcm_hw_param_setinteger); 2702 EXPORT_SYMBOL(snd_pcm_hw_param_value_min); 2703 EXPORT_SYMBOL(snd_pcm_hw_param_value_max); 2704 EXPORT_SYMBOL(snd_pcm_hw_param_mask); 2705 EXPORT_SYMBOL(snd_pcm_hw_param_first); 2706 EXPORT_SYMBOL(snd_pcm_hw_param_last); 2707 EXPORT_SYMBOL(snd_pcm_hw_param_near); 2708 EXPORT_SYMBOL(snd_pcm_hw_param_set); 2709 EXPORT_SYMBOL(snd_pcm_hw_refine); 2710 EXPORT_SYMBOL(snd_pcm_hw_constraints_init); 2711 EXPORT_SYMBOL(snd_pcm_hw_constraints_complete); 2712 EXPORT_SYMBOL(snd_pcm_hw_constraint_list); 2713 EXPORT_SYMBOL(snd_pcm_hw_constraint_step); 2714 EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums); 2715 EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens); 2716 EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits); 2717 EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax); 2718 EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); 2719 EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); 2720 EXPORT_SYMBOL(snd_pcm_hw_rule_add); 2721 EXPORT_SYMBOL(snd_pcm_set_ops); 2722 EXPORT_SYMBOL(snd_pcm_set_sync); 2723 EXPORT_SYMBOL(snd_pcm_lib_ioctl); 2724 EXPORT_SYMBOL(snd_pcm_stop); 2725 EXPORT_SYMBOL(snd_pcm_period_elapsed); 2726 EXPORT_SYMBOL(snd_pcm_lib_write); 2727 EXPORT_SYMBOL(snd_pcm_lib_read); 2728 EXPORT_SYMBOL(snd_pcm_lib_writev); 2729 EXPORT_SYMBOL(snd_pcm_lib_readv); 2730 EXPORT_SYMBOL(snd_pcm_lib_buffer_bytes); 2731 EXPORT_SYMBOL(snd_pcm_lib_period_bytes); 2732 /* pcm_memory.c */ 2733 EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all); 2734 EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages); 2735 EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); 2736 EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); 2737 EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); 2738 EXPORT_SYMBOL(snd_pcm_lib_free_pages); 2739