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