aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/pcm.h8
-rw-r--r--include/sound/pcm_params.h20
-rw-r--r--sound/core/oss/pcm_oss.c481
-rw-r--r--sound/core/pcm.c36
-rw-r--r--sound/core/pcm_lib.c649
-rw-r--r--sound/core/pcm_memory.c12
-rw-r--r--sound/core/pcm_misc.c24
-rw-r--r--sound/core/pcm_native.c21
8 files changed, 605 insertions, 646 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 373425895faa..998bacefc8f8 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -825,14 +825,6 @@ int snd_interval_ratnum(struct snd_interval *i,
825 825
826void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params); 826void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params);
827void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var); 827void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var);
828int snd_pcm_hw_param_near(struct snd_pcm_substream *substream,
829 struct snd_pcm_hw_params *params,
830 snd_pcm_hw_param_t var,
831 unsigned int val, int *dir);
832int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
833 struct snd_pcm_hw_params *params,
834 snd_pcm_hw_param_t var,
835 unsigned int val, int dir);
836int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); 828int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
837 829
838int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); 830int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h
index e3bebd98e1ce..85cf1cf4f31a 100644
--- a/include/sound/pcm_params.h
+++ b/include/sound/pcm_params.h
@@ -22,18 +22,14 @@
22 * 22 *
23 */ 23 */
24 24
25extern int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params, 25int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
26 snd_pcm_hw_param_t var, const struct snd_mask *val); 26 struct snd_pcm_hw_params *params,
27extern unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params, 27 snd_pcm_hw_param_t var, int *dir);
28 snd_pcm_hw_param_t var, int *dir); 28int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
29extern unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, 29 struct snd_pcm_hw_params *params,
30 snd_pcm_hw_param_t var, int *dir); 30 snd_pcm_hw_param_t var, int *dir);
31extern int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 31int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
32 snd_pcm_hw_param_t var, unsigned int val, int dir); 32 snd_pcm_hw_param_t var, int *dir);
33extern int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
34 snd_pcm_hw_param_t var);
35extern int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
36 snd_pcm_hw_param_t var, unsigned int val, int dir);
37 33
38#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */ 34#define SNDRV_MASK_BITS 64 /* we use so far 64bits only */
39#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32) 35#define SNDRV_MASK_SIZE (SNDRV_MASK_BITS / 32)
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index ac990bf0b48f..0d2e232afe6c 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -78,6 +78,487 @@ static inline void snd_leave_user(mm_segment_t fs)
78 set_fs(fs); 78 set_fs(fs);
79} 79}
80 80
81/*
82 * helper functions to process hw_params
83 */
84static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
85{
86 int changed = 0;
87 if (i->min < min) {
88 i->min = min;
89 i->openmin = openmin;
90 changed = 1;
91 } else if (i->min == min && !i->openmin && openmin) {
92 i->openmin = 1;
93 changed = 1;
94 }
95 if (i->integer) {
96 if (i->openmin) {
97 i->min++;
98 i->openmin = 0;
99 }
100 }
101 if (snd_interval_checkempty(i)) {
102 snd_interval_none(i);
103 return -EINVAL;
104 }
105 return changed;
106}
107
108static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
109{
110 int changed = 0;
111 if (i->max > max) {
112 i->max = max;
113 i->openmax = openmax;
114 changed = 1;
115 } else if (i->max == max && !i->openmax && openmax) {
116 i->openmax = 1;
117 changed = 1;
118 }
119 if (i->integer) {
120 if (i->openmax) {
121 i->max--;
122 i->openmax = 0;
123 }
124 }
125 if (snd_interval_checkempty(i)) {
126 snd_interval_none(i);
127 return -EINVAL;
128 }
129 return changed;
130}
131
132static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
133{
134 struct snd_interval t;
135 t.empty = 0;
136 t.min = t.max = val;
137 t.openmin = t.openmax = 0;
138 t.integer = 1;
139 return snd_interval_refine(i, &t);
140}
141
142/**
143 * snd_pcm_hw_param_value_min
144 * @params: the hw_params instance
145 * @var: parameter to retrieve
146 * @dir: pointer to the direction (-1,0,1) or NULL
147 *
148 * Return the minimum value for field PAR.
149 */
150static unsigned int
151snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
152 snd_pcm_hw_param_t var, int *dir)
153{
154 if (hw_is_mask(var)) {
155 if (dir)
156 *dir = 0;
157 return snd_mask_min(hw_param_mask_c(params, var));
158 }
159 if (hw_is_interval(var)) {
160 const struct snd_interval *i = hw_param_interval_c(params, var);
161 if (dir)
162 *dir = i->openmin;
163 return snd_interval_min(i);
164 }
165 return -EINVAL;
166}
167
168/**
169 * snd_pcm_hw_param_value_max
170 * @params: the hw_params instance
171 * @var: parameter to retrieve
172 * @dir: pointer to the direction (-1,0,1) or NULL
173 *
174 * Return the maximum value for field PAR.
175 */
176static unsigned int
177snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
178 snd_pcm_hw_param_t var, int *dir)
179{
180 if (hw_is_mask(var)) {
181 if (dir)
182 *dir = 0;
183 return snd_mask_max(hw_param_mask_c(params, var));
184 }
185 if (hw_is_interval(var)) {
186 const struct snd_interval *i = hw_param_interval_c(params, var);
187 if (dir)
188 *dir = - (int) i->openmax;
189 return snd_interval_max(i);
190 }
191 return -EINVAL;
192}
193
194static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
195 snd_pcm_hw_param_t var,
196 const struct snd_mask *val)
197{
198 int changed;
199 changed = snd_mask_refine(hw_param_mask(params, var), val);
200 if (changed) {
201 params->cmask |= 1 << var;
202 params->rmask |= 1 << var;
203 }
204 return changed;
205}
206
207static int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm,
208 struct snd_pcm_hw_params *params,
209 snd_pcm_hw_param_t var,
210 const struct snd_mask *val)
211{
212 int changed = _snd_pcm_hw_param_mask(params, var, val);
213 if (changed < 0)
214 return changed;
215 if (params->rmask) {
216 int err = snd_pcm_hw_refine(pcm, params);
217 if (err < 0)
218 return err;
219 }
220 return 0;
221}
222
223static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
224 snd_pcm_hw_param_t var, unsigned int val,
225 int dir)
226{
227 int changed;
228 int open = 0;
229 if (dir) {
230 if (dir > 0) {
231 open = 1;
232 } else if (dir < 0) {
233 if (val > 0) {
234 open = 1;
235 val--;
236 }
237 }
238 }
239 if (hw_is_mask(var))
240 changed = snd_mask_refine_min(hw_param_mask(params, var),
241 val + !!open);
242 else if (hw_is_interval(var))
243 changed = snd_interval_refine_min(hw_param_interval(params, var),
244 val, open);
245 else
246 return -EINVAL;
247 if (changed) {
248 params->cmask |= 1 << var;
249 params->rmask |= 1 << var;
250 }
251 return changed;
252}
253
254/**
255 * snd_pcm_hw_param_min
256 * @pcm: PCM instance
257 * @params: the hw_params instance
258 * @var: parameter to retrieve
259 * @val: minimal value
260 * @dir: pointer to the direction (-1,0,1) or NULL
261 *
262 * Inside configuration space defined by PARAMS remove from PAR all
263 * values < VAL. Reduce configuration space accordingly.
264 * Return new minimum or -EINVAL if the configuration space is empty
265 */
266static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm,
267 struct snd_pcm_hw_params *params,
268 snd_pcm_hw_param_t var, unsigned int val,
269 int *dir)
270{
271 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
272 if (changed < 0)
273 return changed;
274 if (params->rmask) {
275 int err = snd_pcm_hw_refine(pcm, params);
276 if (err < 0)
277 return err;
278 }
279 return snd_pcm_hw_param_value_min(params, var, dir);
280}
281
282static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
283 snd_pcm_hw_param_t var, unsigned int val,
284 int dir)
285{
286 int changed;
287 int open = 0;
288 if (dir) {
289 if (dir < 0) {
290 open = 1;
291 } else if (dir > 0) {
292 open = 1;
293 val++;
294 }
295 }
296 if (hw_is_mask(var)) {
297 if (val == 0 && open) {
298 snd_mask_none(hw_param_mask(params, var));
299 changed = -EINVAL;
300 } else
301 changed = snd_mask_refine_max(hw_param_mask(params, var),
302 val - !!open);
303 } else if (hw_is_interval(var))
304 changed = snd_interval_refine_max(hw_param_interval(params, var),
305 val, open);
306 else
307 return -EINVAL;
308 if (changed) {
309 params->cmask |= 1 << var;
310 params->rmask |= 1 << var;
311 }
312 return changed;
313}
314
315/**
316 * snd_pcm_hw_param_max
317 * @pcm: PCM instance
318 * @params: the hw_params instance
319 * @var: parameter to retrieve
320 * @val: maximal value
321 * @dir: pointer to the direction (-1,0,1) or NULL
322 *
323 * Inside configuration space defined by PARAMS remove from PAR all
324 * values >= VAL + 1. Reduce configuration space accordingly.
325 * Return new maximum or -EINVAL if the configuration space is empty
326 */
327static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm,
328 struct snd_pcm_hw_params *params,
329 snd_pcm_hw_param_t var, unsigned int val,
330 int *dir)
331{
332 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
333 if (changed < 0)
334 return changed;
335 if (params->rmask) {
336 int err = snd_pcm_hw_refine(pcm, params);
337 if (err < 0)
338 return err;
339 }
340 return snd_pcm_hw_param_value_max(params, var, dir);
341}
342
343static int boundary_sub(int a, int adir,
344 int b, int bdir,
345 int *c, int *cdir)
346{
347 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
348 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
349 *c = a - b;
350 *cdir = adir - bdir;
351 if (*cdir == -2) {
352 (*c)--;
353 } else if (*cdir == 2) {
354 (*c)++;
355 }
356 return 0;
357}
358
359static int boundary_lt(unsigned int a, int adir,
360 unsigned int b, int bdir)
361{
362 if (adir < 0) {
363 a--;
364 adir = 1;
365 } else if (adir > 0)
366 adir = 1;
367 if (bdir < 0) {
368 b--;
369 bdir = 1;
370 } else if (bdir > 0)
371 bdir = 1;
372 return a < b || (a == b && adir < bdir);
373}
374
375/* Return 1 if min is nearer to best than max */
376static int boundary_nearer(int min, int mindir,
377 int best, int bestdir,
378 int max, int maxdir)
379{
380 int dmin, dmindir;
381 int dmax, dmaxdir;
382 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
383 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
384 return boundary_lt(dmin, dmindir, dmax, dmaxdir);
385}
386
387/**
388 * snd_pcm_hw_param_near
389 * @pcm: PCM instance
390 * @params: the hw_params instance
391 * @var: parameter to retrieve
392 * @best: value to set
393 * @dir: pointer to the direction (-1,0,1) or NULL
394 *
395 * Inside configuration space defined by PARAMS set PAR to the available value
396 * nearest to VAL. Reduce configuration space accordingly.
397 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
398 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
399 * Return the value found.
400 */
401static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
402 struct snd_pcm_hw_params *params,
403 snd_pcm_hw_param_t var, unsigned int best,
404 int *dir)
405{
406 struct snd_pcm_hw_params *save = NULL;
407 int v;
408 unsigned int saved_min;
409 int last = 0;
410 int min, max;
411 int mindir, maxdir;
412 int valdir = dir ? *dir : 0;
413 /* FIXME */
414 if (best > INT_MAX)
415 best = INT_MAX;
416 min = max = best;
417 mindir = maxdir = valdir;
418 if (maxdir > 0)
419 maxdir = 0;
420 else if (maxdir == 0)
421 maxdir = -1;
422 else {
423 maxdir = 1;
424 max--;
425 }
426 save = kmalloc(sizeof(*save), GFP_KERNEL);
427 if (save == NULL)
428 return -ENOMEM;
429 *save = *params;
430 saved_min = min;
431 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
432 if (min >= 0) {
433 struct snd_pcm_hw_params *params1;
434 if (max < 0)
435 goto _end;
436 if ((unsigned int)min == saved_min && mindir == valdir)
437 goto _end;
438 params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
439 if (params1 == NULL) {
440 kfree(save);
441 return -ENOMEM;
442 }
443 *params1 = *save;
444 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
445 if (max < 0) {
446 kfree(params1);
447 goto _end;
448 }
449 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
450 *params = *params1;
451 last = 1;
452 }
453 kfree(params1);
454 } else {
455 *params = *save;
456 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
457 snd_assert(max >= 0, return -EINVAL);
458 last = 1;
459 }
460 _end:
461 kfree(save);
462 if (last)
463 v = snd_pcm_hw_param_last(pcm, params, var, dir);
464 else
465 v = snd_pcm_hw_param_first(pcm, params, var, dir);
466 snd_assert(v >= 0, return -EINVAL);
467 return v;
468}
469
470static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
471 snd_pcm_hw_param_t var, unsigned int val,
472 int dir)
473{
474 int changed;
475 if (hw_is_mask(var)) {
476 struct snd_mask *m = hw_param_mask(params, var);
477 if (val == 0 && dir < 0) {
478 changed = -EINVAL;
479 snd_mask_none(m);
480 } else {
481 if (dir > 0)
482 val++;
483 else if (dir < 0)
484 val--;
485 changed = snd_mask_refine_set(hw_param_mask(params, var), val);
486 }
487 } else if (hw_is_interval(var)) {
488 struct snd_interval *i = hw_param_interval(params, var);
489 if (val == 0 && dir < 0) {
490 changed = -EINVAL;
491 snd_interval_none(i);
492 } else if (dir == 0)
493 changed = snd_interval_refine_set(i, val);
494 else {
495 struct snd_interval t;
496 t.openmin = 1;
497 t.openmax = 1;
498 t.empty = 0;
499 t.integer = 0;
500 if (dir < 0) {
501 t.min = val - 1;
502 t.max = val;
503 } else {
504 t.min = val;
505 t.max = val+1;
506 }
507 changed = snd_interval_refine(i, &t);
508 }
509 } else
510 return -EINVAL;
511 if (changed) {
512 params->cmask |= 1 << var;
513 params->rmask |= 1 << var;
514 }
515 return changed;
516}
517
518/**
519 * snd_pcm_hw_param_set
520 * @pcm: PCM instance
521 * @params: the hw_params instance
522 * @var: parameter to retrieve
523 * @val: value to set
524 * @dir: pointer to the direction (-1,0,1) or NULL
525 *
526 * Inside configuration space defined by PARAMS remove from PAR all
527 * values != VAL. Reduce configuration space accordingly.
528 * Return VAL or -EINVAL if the configuration space is empty
529 */
530static int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
531 struct snd_pcm_hw_params *params,
532 snd_pcm_hw_param_t var, unsigned int val,
533 int dir)
534{
535 int changed = _snd_pcm_hw_param_set(params, var, val, dir);
536 if (changed < 0)
537 return changed;
538 if (params->rmask) {
539 int err = snd_pcm_hw_refine(pcm, params);
540 if (err < 0)
541 return err;
542 }
543 return snd_pcm_hw_param_value(params, var, NULL);
544}
545
546static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
547 snd_pcm_hw_param_t var)
548{
549 int changed;
550 changed = snd_interval_setinteger(hw_param_interval(params, var));
551 if (changed) {
552 params->cmask |= 1 << var;
553 params->rmask |= 1 << var;
554 }
555 return changed;
556}
557
558/*
559 * plugin
560 */
561
81#ifdef CONFIG_SND_PCM_OSS_PLUGINS 562#ifdef CONFIG_SND_PCM_OSS_PLUGINS
82static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) 563static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
83{ 564{
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 84b00038236d..8c15c01907f4 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -671,6 +671,8 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
671 return 0; 671 return 0;
672} 672}
673 673
674EXPORT_SYMBOL(snd_pcm_new_stream);
675
674/** 676/**
675 * snd_pcm_new - create a new PCM instance 677 * snd_pcm_new - create a new PCM instance
676 * @card: the card instance 678 * @card: the card instance
@@ -730,6 +732,8 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
730 return 0; 732 return 0;
731} 733}
732 734
735EXPORT_SYMBOL(snd_pcm_new);
736
733static void snd_pcm_free_stream(struct snd_pcm_str * pstr) 737static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
734{ 738{
735 struct snd_pcm_substream *substream, *substream_next; 739 struct snd_pcm_substream *substream, *substream_next;
@@ -1022,6 +1026,8 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
1022 return 0; 1026 return 0;
1023} 1027}
1024 1028
1029EXPORT_SYMBOL(snd_pcm_notify);
1030
1025#ifdef CONFIG_PROC_FS 1031#ifdef CONFIG_PROC_FS
1026/* 1032/*
1027 * Info interface 1033 * Info interface
@@ -1099,33 +1105,3 @@ static void __exit alsa_pcm_exit(void)
1099 1105
1100module_init(alsa_pcm_init) 1106module_init(alsa_pcm_init)
1101module_exit(alsa_pcm_exit) 1107module_exit(alsa_pcm_exit)
1102
1103EXPORT_SYMBOL(snd_pcm_new);
1104EXPORT_SYMBOL(snd_pcm_new_stream);
1105EXPORT_SYMBOL(snd_pcm_notify);
1106EXPORT_SYMBOL(snd_pcm_open_substream);
1107EXPORT_SYMBOL(snd_pcm_release_substream);
1108 /* pcm_native.c */
1109EXPORT_SYMBOL(snd_pcm_link_rwlock);
1110#ifdef CONFIG_PM
1111EXPORT_SYMBOL(snd_pcm_suspend);
1112EXPORT_SYMBOL(snd_pcm_suspend_all);
1113#endif
1114EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
1115EXPORT_SYMBOL(snd_pcm_mmap_data);
1116#if SNDRV_PCM_INFO_MMAP_IOMEM
1117EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
1118#endif
1119 /* pcm_misc.c */
1120EXPORT_SYMBOL(snd_pcm_format_signed);
1121EXPORT_SYMBOL(snd_pcm_format_unsigned);
1122EXPORT_SYMBOL(snd_pcm_format_linear);
1123EXPORT_SYMBOL(snd_pcm_format_little_endian);
1124EXPORT_SYMBOL(snd_pcm_format_big_endian);
1125EXPORT_SYMBOL(snd_pcm_format_width);
1126EXPORT_SYMBOL(snd_pcm_format_physical_width);
1127EXPORT_SYMBOL(snd_pcm_format_size);
1128EXPORT_SYMBOL(snd_pcm_format_silence_64);
1129EXPORT_SYMBOL(snd_pcm_format_set_silence);
1130EXPORT_SYMBOL(snd_pcm_build_linear_format);
1131EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index eedc6cb038bb..786f88145ee8 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -289,6 +289,7 @@ void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops
289 substream->ops = ops; 289 substream->ops = ops;
290} 290}
291 291
292EXPORT_SYMBOL(snd_pcm_set_ops);
292 293
293/** 294/**
294 * snd_pcm_sync - set the PCM sync id 295 * snd_pcm_sync - set the PCM sync id
@@ -306,13 +307,12 @@ void snd_pcm_set_sync(struct snd_pcm_substream *substream)
306 runtime->sync.id32[3] = -1; 307 runtime->sync.id32[3] = -1;
307} 308}
308 309
310EXPORT_SYMBOL(snd_pcm_set_sync);
311
309/* 312/*
310 * Standard ioctl routine 313 * Standard ioctl routine
311 */ 314 */
312 315
313/* Code taken from alsa-lib */
314#define assert(a) snd_assert((a), return -EINVAL)
315
316static inline unsigned int div32(unsigned int a, unsigned int b, 316static inline unsigned int div32(unsigned int a, unsigned int b,
317 unsigned int *r) 317 unsigned int *r)
318{ 318{
@@ -369,56 +369,6 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b,
369 return n; 369 return n;
370} 370}
371 371
372static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
373{
374 int changed = 0;
375 assert(!snd_interval_empty(i));
376 if (i->min < min) {
377 i->min = min;
378 i->openmin = openmin;
379 changed = 1;
380 } else if (i->min == min && !i->openmin && openmin) {
381 i->openmin = 1;
382 changed = 1;
383 }
384 if (i->integer) {
385 if (i->openmin) {
386 i->min++;
387 i->openmin = 0;
388 }
389 }
390 if (snd_interval_checkempty(i)) {
391 snd_interval_none(i);
392 return -EINVAL;
393 }
394 return changed;
395}
396
397static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
398{
399 int changed = 0;
400 assert(!snd_interval_empty(i));
401 if (i->max > max) {
402 i->max = max;
403 i->openmax = openmax;
404 changed = 1;
405 } else if (i->max == max && !i->openmax && openmax) {
406 i->openmax = 1;
407 changed = 1;
408 }
409 if (i->integer) {
410 if (i->openmax) {
411 i->max--;
412 i->openmax = 0;
413 }
414 }
415 if (snd_interval_checkempty(i)) {
416 snd_interval_none(i);
417 return -EINVAL;
418 }
419 return changed;
420}
421
422/** 372/**
423 * snd_interval_refine - refine the interval value of configurator 373 * snd_interval_refine - refine the interval value of configurator
424 * @i: the interval value to refine 374 * @i: the interval value to refine
@@ -433,7 +383,7 @@ static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int
433int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) 383int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
434{ 384{
435 int changed = 0; 385 int changed = 0;
436 assert(!snd_interval_empty(i)); 386 snd_assert(!snd_interval_empty(i), return -EINVAL);
437 if (i->min < v->min) { 387 if (i->min < v->min) {
438 i->min = v->min; 388 i->min = v->min;
439 i->openmin = v->openmin; 389 i->openmin = v->openmin;
@@ -472,9 +422,11 @@ int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
472 return changed; 422 return changed;
473} 423}
474 424
425EXPORT_SYMBOL(snd_interval_refine);
426
475static int snd_interval_refine_first(struct snd_interval *i) 427static int snd_interval_refine_first(struct snd_interval *i)
476{ 428{
477 assert(!snd_interval_empty(i)); 429 snd_assert(!snd_interval_empty(i), return -EINVAL);
478 if (snd_interval_single(i)) 430 if (snd_interval_single(i))
479 return 0; 431 return 0;
480 i->max = i->min; 432 i->max = i->min;
@@ -486,7 +438,7 @@ static int snd_interval_refine_first(struct snd_interval *i)
486 438
487static int snd_interval_refine_last(struct snd_interval *i) 439static int snd_interval_refine_last(struct snd_interval *i)
488{ 440{
489 assert(!snd_interval_empty(i)); 441 snd_assert(!snd_interval_empty(i), return -EINVAL);
490 if (snd_interval_single(i)) 442 if (snd_interval_single(i))
491 return 0; 443 return 0;
492 i->min = i->max; 444 i->min = i->max;
@@ -496,16 +448,6 @@ static int snd_interval_refine_last(struct snd_interval *i)
496 return 1; 448 return 1;
497} 449}
498 450
499static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
500{
501 struct snd_interval t;
502 t.empty = 0;
503 t.min = t.max = val;
504 t.openmin = t.openmax = 0;
505 t.integer = 1;
506 return snd_interval_refine(i, &t);
507}
508
509void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c) 451void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
510{ 452{
511 if (a->empty || b->empty) { 453 if (a->empty || b->empty) {
@@ -621,7 +563,6 @@ void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
621 c->integer = 0; 563 c->integer = 0;
622} 564}
623 565
624#undef assert
625/* ---- */ 566/* ---- */
626 567
627 568
@@ -727,6 +668,8 @@ int snd_interval_ratnum(struct snd_interval *i,
727 return err; 668 return err;
728} 669}
729 670
671EXPORT_SYMBOL(snd_interval_ratnum);
672
730/** 673/**
731 * snd_interval_ratden - refine the interval value 674 * snd_interval_ratden - refine the interval value
732 * @i: interval to refine 675 * @i: interval to refine
@@ -877,6 +820,8 @@ int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *
877 return changed; 820 return changed;
878} 821}
879 822
823EXPORT_SYMBOL(snd_interval_list);
824
880static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step) 825static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step)
881{ 826{
882 unsigned int n; 827 unsigned int n;
@@ -953,6 +898,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
953 return 0; 898 return 0;
954} 899}
955 900
901EXPORT_SYMBOL(snd_pcm_hw_rule_add);
902
956/** 903/**
957 * snd_pcm_hw_constraint_mask 904 * snd_pcm_hw_constraint_mask
958 * @runtime: PCM runtime instance 905 * @runtime: PCM runtime instance
@@ -1007,6 +954,8 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa
1007 return snd_interval_setinteger(constrs_interval(constrs, var)); 954 return snd_interval_setinteger(constrs_interval(constrs, var));
1008} 955}
1009 956
957EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
958
1010/** 959/**
1011 * snd_pcm_hw_constraint_minmax 960 * snd_pcm_hw_constraint_minmax
1012 * @runtime: PCM runtime instance 961 * @runtime: PCM runtime instance
@@ -1028,6 +977,8 @@ int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_par
1028 return snd_interval_refine(constrs_interval(constrs, var), &t); 977 return snd_interval_refine(constrs_interval(constrs, var), &t);
1029} 978}
1030 979
980EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
981
1031static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, 982static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
1032 struct snd_pcm_hw_rule *rule) 983 struct snd_pcm_hw_rule *rule)
1033{ 984{
@@ -1055,6 +1006,8 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
1055 var, -1); 1006 var, -1);
1056} 1007}
1057 1008
1009EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
1010
1058static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params, 1011static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
1059 struct snd_pcm_hw_rule *rule) 1012 struct snd_pcm_hw_rule *rule)
1060{ 1013{
@@ -1087,6 +1040,8 @@ int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
1087 var, -1); 1040 var, -1);
1088} 1041}
1089 1042
1043EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
1044
1090static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params, 1045static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
1091 struct snd_pcm_hw_rule *rule) 1046 struct snd_pcm_hw_rule *rule)
1092{ 1047{
@@ -1118,6 +1073,8 @@ int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime,
1118 var, -1); 1073 var, -1);
1119} 1074}
1120 1075
1076EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
1077
1121static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params, 1078static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
1122 struct snd_pcm_hw_rule *rule) 1079 struct snd_pcm_hw_rule *rule)
1123{ 1080{
@@ -1149,6 +1106,8 @@ int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime,
1149 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1); 1106 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
1150} 1107}
1151 1108
1109EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
1110
1152static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params, 1111static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
1153 struct snd_pcm_hw_rule *rule) 1112 struct snd_pcm_hw_rule *rule)
1154{ 1113{
@@ -1173,6 +1132,8 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
1173 var, -1); 1132 var, -1);
1174} 1133}
1175 1134
1135EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
1136
1176static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) 1137static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
1177{ 1138{
1178 static int pow2_sizes[] = { 1139 static int pow2_sizes[] = {
@@ -1200,6 +1161,8 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
1200 var, -1); 1161 var, -1);
1201} 1162}
1202 1163
1164EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
1165
1203/* To use the same code we have in alsa-lib */ 1166/* To use the same code we have in alsa-lib */
1204#define assert(i) snd_assert((i), return -EINVAL) 1167#define assert(i) snd_assert((i), return -EINVAL)
1205#ifndef INT_MIN 1168#ifndef INT_MIN
@@ -1224,18 +1187,6 @@ static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1224 snd_BUG(); 1187 snd_BUG();
1225} 1188}
1226 1189
1227#if 0
1228/*
1229 * snd_pcm_hw_param_any
1230 */
1231int snd_pcm_hw_param_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1232 snd_pcm_hw_param_t var)
1233{
1234 _snd_pcm_hw_param_any(params, var);
1235 return snd_pcm_hw_refine(pcm, params);
1236}
1237#endif /* 0 */
1238
1239void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params) 1190void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1240{ 1191{
1241 unsigned int k; 1192 unsigned int k;
@@ -1247,18 +1198,7 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1247 params->info = ~0U; 1198 params->info = ~0U;
1248} 1199}
1249 1200
1250#if 0 1201EXPORT_SYMBOL(_snd_pcm_hw_params_any);
1251/*
1252 * snd_pcm_hw_params_any
1253 *
1254 * Fill PARAMS with full configuration space boundaries
1255 */
1256int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params)
1257{
1258 _snd_pcm_hw_params_any(params);
1259 return snd_pcm_hw_refine(pcm, params);
1260}
1261#endif /* 0 */
1262 1202
1263/** 1203/**
1264 * snd_pcm_hw_param_value 1204 * snd_pcm_hw_param_value
@@ -1269,8 +1209,8 @@ int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_param
1269 * Return the value for field PAR if it's fixed in configuration space 1209 * Return the value for field PAR if it's fixed in configuration space
1270 * defined by PARAMS. Return -EINVAL otherwise 1210 * defined by PARAMS. Return -EINVAL otherwise
1271 */ 1211 */
1272static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, 1212int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1273 snd_pcm_hw_param_t var, int *dir) 1213 snd_pcm_hw_param_t var, int *dir)
1274{ 1214{
1275 if (hw_is_mask(var)) { 1215 if (hw_is_mask(var)) {
1276 const struct snd_mask *mask = hw_param_mask_c(params, var); 1216 const struct snd_mask *mask = hw_param_mask_c(params, var);
@@ -1292,57 +1232,7 @@ static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1292 return -EINVAL; 1232 return -EINVAL;
1293} 1233}
1294 1234
1295/** 1235EXPORT_SYMBOL(snd_pcm_hw_param_value);
1296 * snd_pcm_hw_param_value_min
1297 * @params: the hw_params instance
1298 * @var: parameter to retrieve
1299 * @dir: pointer to the direction (-1,0,1) or NULL
1300 *
1301 * Return the minimum value for field PAR.
1302 */
1303unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
1304 snd_pcm_hw_param_t var, int *dir)
1305{
1306 if (hw_is_mask(var)) {
1307 if (dir)
1308 *dir = 0;
1309 return snd_mask_min(hw_param_mask_c(params, var));
1310 }
1311 if (hw_is_interval(var)) {
1312 const struct snd_interval *i = hw_param_interval_c(params, var);
1313 if (dir)
1314 *dir = i->openmin;
1315 return snd_interval_min(i);
1316 }
1317 assert(0);
1318 return -EINVAL;
1319}
1320
1321/**
1322 * snd_pcm_hw_param_value_max
1323 * @params: the hw_params instance
1324 * @var: parameter to retrieve
1325 * @dir: pointer to the direction (-1,0,1) or NULL
1326 *
1327 * Return the maximum value for field PAR.
1328 */
1329unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
1330 snd_pcm_hw_param_t var, int *dir)
1331{
1332 if (hw_is_mask(var)) {
1333 if (dir)
1334 *dir = 0;
1335 return snd_mask_max(hw_param_mask_c(params, var));
1336 }
1337 if (hw_is_interval(var)) {
1338 const struct snd_interval *i = hw_param_interval_c(params, var);
1339 if (dir)
1340 *dir = - (int) i->openmax;
1341 return snd_interval_max(i);
1342 }
1343 assert(0);
1344 return -EINVAL;
1345}
1346 1236
1347void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, 1237void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1348 snd_pcm_hw_param_t var) 1238 snd_pcm_hw_param_t var)
@@ -1360,42 +1250,7 @@ void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1360 } 1250 }
1361} 1251}
1362 1252
1363int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, 1253EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
1364 snd_pcm_hw_param_t var)
1365{
1366 int changed;
1367 assert(hw_is_interval(var));
1368 changed = snd_interval_setinteger(hw_param_interval(params, var));
1369 if (changed) {
1370 params->cmask |= 1 << var;
1371 params->rmask |= 1 << var;
1372 }
1373 return changed;
1374}
1375
1376#if 0
1377/*
1378 * snd_pcm_hw_param_setinteger
1379 *
1380 * Inside configuration space defined by PARAMS remove from PAR all
1381 * non integer values. Reduce configuration space accordingly.
1382 * Return -EINVAL if the configuration space is empty
1383 */
1384int snd_pcm_hw_param_setinteger(struct snd_pcm_substream *pcm,
1385 struct snd_pcm_hw_params *params,
1386 snd_pcm_hw_param_t var)
1387{
1388 int changed = _snd_pcm_hw_param_setinteger(params, var);
1389 if (changed < 0)
1390 return changed;
1391 if (params->rmask) {
1392 int err = snd_pcm_hw_refine(pcm, params);
1393 if (err < 0)
1394 return err;
1395 }
1396 return 0;
1397}
1398#endif /* 0 */
1399 1254
1400static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, 1255static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1401 snd_pcm_hw_param_t var) 1256 snd_pcm_hw_param_t var)
@@ -1428,9 +1283,9 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1428 * values > minimum. Reduce configuration space accordingly. 1283 * values > minimum. Reduce configuration space accordingly.
1429 * Return the minimum. 1284 * Return the minimum.
1430 */ 1285 */
1431static int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 1286int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
1432 struct snd_pcm_hw_params *params, 1287 struct snd_pcm_hw_params *params,
1433 snd_pcm_hw_param_t var, int *dir) 1288 snd_pcm_hw_param_t var, int *dir)
1434{ 1289{
1435 int changed = _snd_pcm_hw_param_first(params, var); 1290 int changed = _snd_pcm_hw_param_first(params, var);
1436 if (changed < 0) 1291 if (changed < 0)
@@ -1442,6 +1297,8 @@ static int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm,
1442 return snd_pcm_hw_param_value(params, var, dir); 1297 return snd_pcm_hw_param_value(params, var, dir);
1443} 1298}
1444 1299
1300EXPORT_SYMBOL(snd_pcm_hw_param_first);
1301
1445static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, 1302static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1446 snd_pcm_hw_param_t var) 1303 snd_pcm_hw_param_t var)
1447{ 1304{
@@ -1473,9 +1330,9 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1473 * values < maximum. Reduce configuration space accordingly. 1330 * values < maximum. Reduce configuration space accordingly.
1474 * Return the maximum. 1331 * Return the maximum.
1475 */ 1332 */
1476static int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 1333int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
1477 struct snd_pcm_hw_params *params, 1334 struct snd_pcm_hw_params *params,
1478 snd_pcm_hw_param_t var, int *dir) 1335 snd_pcm_hw_param_t var, int *dir)
1479{ 1336{
1480 int changed = _snd_pcm_hw_param_last(params, var); 1337 int changed = _snd_pcm_hw_param_last(params, var);
1481 if (changed < 0) 1338 if (changed < 0)
@@ -1487,367 +1344,7 @@ static int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
1487 return snd_pcm_hw_param_value(params, var, dir); 1344 return snd_pcm_hw_param_value(params, var, dir);
1488} 1345}
1489 1346
1490int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, 1347EXPORT_SYMBOL(snd_pcm_hw_param_last);
1491 snd_pcm_hw_param_t var, unsigned int val, int dir)
1492{
1493 int changed;
1494 int open = 0;
1495 if (dir) {
1496 if (dir > 0) {
1497 open = 1;
1498 } else if (dir < 0) {
1499 if (val > 0) {
1500 open = 1;
1501 val--;
1502 }
1503 }
1504 }
1505 if (hw_is_mask(var))
1506 changed = snd_mask_refine_min(hw_param_mask(params, var), val + !!open);
1507 else if (hw_is_interval(var))
1508 changed = snd_interval_refine_min(hw_param_interval(params, var), val, open);
1509 else {
1510 assert(0);
1511 return -EINVAL;
1512 }
1513 if (changed) {
1514 params->cmask |= 1 << var;
1515 params->rmask |= 1 << var;
1516 }
1517 return changed;
1518}
1519
1520/**
1521 * snd_pcm_hw_param_min
1522 * @pcm: PCM instance
1523 * @params: the hw_params instance
1524 * @var: parameter to retrieve
1525 * @val: minimal value
1526 * @dir: pointer to the direction (-1,0,1) or NULL
1527 *
1528 * Inside configuration space defined by PARAMS remove from PAR all
1529 * values < VAL. Reduce configuration space accordingly.
1530 * Return new minimum or -EINVAL if the configuration space is empty
1531 */
1532static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1533 snd_pcm_hw_param_t var, unsigned int val,
1534 int *dir)
1535{
1536 int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
1537 if (changed < 0)
1538 return changed;
1539 if (params->rmask) {
1540 int err = snd_pcm_hw_refine(pcm, params);
1541 if (err < 0)
1542 return err;
1543 }
1544 return snd_pcm_hw_param_value_min(params, var, dir);
1545}
1546
1547static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
1548 snd_pcm_hw_param_t var, unsigned int val,
1549 int dir)
1550{
1551 int changed;
1552 int open = 0;
1553 if (dir) {
1554 if (dir < 0) {
1555 open = 1;
1556 } else if (dir > 0) {
1557 open = 1;
1558 val++;
1559 }
1560 }
1561 if (hw_is_mask(var)) {
1562 if (val == 0 && open) {
1563 snd_mask_none(hw_param_mask(params, var));
1564 changed = -EINVAL;
1565 } else
1566 changed = snd_mask_refine_max(hw_param_mask(params, var), val - !!open);
1567 } else if (hw_is_interval(var))
1568 changed = snd_interval_refine_max(hw_param_interval(params, var), val, open);
1569 else {
1570 assert(0);
1571 return -EINVAL;
1572 }
1573 if (changed) {
1574 params->cmask |= 1 << var;
1575 params->rmask |= 1 << var;
1576 }
1577 return changed;
1578}
1579
1580/**
1581 * snd_pcm_hw_param_max
1582 * @pcm: PCM instance
1583 * @params: the hw_params instance
1584 * @var: parameter to retrieve
1585 * @val: maximal value
1586 * @dir: pointer to the direction (-1,0,1) or NULL
1587 *
1588 * Inside configuration space defined by PARAMS remove from PAR all
1589 * values >= VAL + 1. Reduce configuration space accordingly.
1590 * Return new maximum or -EINVAL if the configuration space is empty
1591 */
1592static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1593 snd_pcm_hw_param_t var, unsigned int val,
1594 int *dir)
1595{
1596 int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
1597 if (changed < 0)
1598 return changed;
1599 if (params->rmask) {
1600 int err = snd_pcm_hw_refine(pcm, params);
1601 if (err < 0)
1602 return err;
1603 }
1604 return snd_pcm_hw_param_value_max(params, var, dir);
1605}
1606
1607int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
1608 snd_pcm_hw_param_t var, unsigned int val, int dir)
1609{
1610 int changed;
1611 if (hw_is_mask(var)) {
1612 struct snd_mask *m = hw_param_mask(params, var);
1613 if (val == 0 && dir < 0) {
1614 changed = -EINVAL;
1615 snd_mask_none(m);
1616 } else {
1617 if (dir > 0)
1618 val++;
1619 else if (dir < 0)
1620 val--;
1621 changed = snd_mask_refine_set(hw_param_mask(params, var), val);
1622 }
1623 } else if (hw_is_interval(var)) {
1624 struct snd_interval *i = hw_param_interval(params, var);
1625 if (val == 0 && dir < 0) {
1626 changed = -EINVAL;
1627 snd_interval_none(i);
1628 } else if (dir == 0)
1629 changed = snd_interval_refine_set(i, val);
1630 else {
1631 struct snd_interval t;
1632 t.openmin = 1;
1633 t.openmax = 1;
1634 t.empty = 0;
1635 t.integer = 0;
1636 if (dir < 0) {
1637 t.min = val - 1;
1638 t.max = val;
1639 } else {
1640 t.min = val;
1641 t.max = val+1;
1642 }
1643 changed = snd_interval_refine(i, &t);
1644 }
1645 } else {
1646 assert(0);
1647 return -EINVAL;
1648 }
1649 if (changed) {
1650 params->cmask |= 1 << var;
1651 params->rmask |= 1 << var;
1652 }
1653 return changed;
1654}
1655
1656/**
1657 * snd_pcm_hw_param_set
1658 * @pcm: PCM instance
1659 * @params: the hw_params instance
1660 * @var: parameter to retrieve
1661 * @val: value to set
1662 * @dir: pointer to the direction (-1,0,1) or NULL
1663 *
1664 * Inside configuration space defined by PARAMS remove from PAR all
1665 * values != VAL. Reduce configuration space accordingly.
1666 * Return VAL or -EINVAL if the configuration space is empty
1667 */
1668int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1669 snd_pcm_hw_param_t var, unsigned int val, int dir)
1670{
1671 int changed = _snd_pcm_hw_param_set(params, var, val, dir);
1672 if (changed < 0)
1673 return changed;
1674 if (params->rmask) {
1675 int err = snd_pcm_hw_refine(pcm, params);
1676 if (err < 0)
1677 return err;
1678 }
1679 return snd_pcm_hw_param_value(params, var, NULL);
1680}
1681
1682static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
1683 snd_pcm_hw_param_t var, const struct snd_mask *val)
1684{
1685 int changed;
1686 assert(hw_is_mask(var));
1687 changed = snd_mask_refine(hw_param_mask(params, var), val);
1688 if (changed) {
1689 params->cmask |= 1 << var;
1690 params->rmask |= 1 << var;
1691 }
1692 return changed;
1693}
1694
1695/**
1696 * snd_pcm_hw_param_mask
1697 * @pcm: PCM instance
1698 * @params: the hw_params instance
1699 * @var: parameter to retrieve
1700 * @val: mask to apply
1701 *
1702 * Inside configuration space defined by PARAMS remove from PAR all values
1703 * not contained in MASK. Reduce configuration space accordingly.
1704 * This function can be called only for SNDRV_PCM_HW_PARAM_ACCESS,
1705 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
1706 * Return 0 on success or -EINVAL
1707 * if the configuration space is empty
1708 */
1709int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1710 snd_pcm_hw_param_t var, const struct snd_mask *val)
1711{
1712 int changed = _snd_pcm_hw_param_mask(params, var, val);
1713 if (changed < 0)
1714 return changed;
1715 if (params->rmask) {
1716 int err = snd_pcm_hw_refine(pcm, params);
1717 if (err < 0)
1718 return err;
1719 }
1720 return 0;
1721}
1722
1723static int boundary_sub(int a, int adir,
1724 int b, int bdir,
1725 int *c, int *cdir)
1726{
1727 adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
1728 bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
1729 *c = a - b;
1730 *cdir = adir - bdir;
1731 if (*cdir == -2) {
1732 assert(*c > INT_MIN);
1733 (*c)--;
1734 } else if (*cdir == 2) {
1735 assert(*c < INT_MAX);
1736 (*c)++;
1737 }
1738 return 0;
1739}
1740
1741static int boundary_lt(unsigned int a, int adir,
1742 unsigned int b, int bdir)
1743{
1744 assert(a > 0 || adir >= 0);
1745 assert(b > 0 || bdir >= 0);
1746 if (adir < 0) {
1747 a--;
1748 adir = 1;
1749 } else if (adir > 0)
1750 adir = 1;
1751 if (bdir < 0) {
1752 b--;
1753 bdir = 1;
1754 } else if (bdir > 0)
1755 bdir = 1;
1756 return a < b || (a == b && adir < bdir);
1757}
1758
1759/* Return 1 if min is nearer to best than max */
1760static int boundary_nearer(int min, int mindir,
1761 int best, int bestdir,
1762 int max, int maxdir)
1763{
1764 int dmin, dmindir;
1765 int dmax, dmaxdir;
1766 boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
1767 boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
1768 return boundary_lt(dmin, dmindir, dmax, dmaxdir);
1769}
1770
1771/**
1772 * snd_pcm_hw_param_near
1773 * @pcm: PCM instance
1774 * @params: the hw_params instance
1775 * @var: parameter to retrieve
1776 * @best: value to set
1777 * @dir: pointer to the direction (-1,0,1) or NULL
1778 *
1779 * Inside configuration space defined by PARAMS set PAR to the available value
1780 * nearest to VAL. Reduce configuration space accordingly.
1781 * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
1782 * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
1783 * Return the value found.
1784 */
1785int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
1786 snd_pcm_hw_param_t var, unsigned int best, int *dir)
1787{
1788 struct snd_pcm_hw_params *save = NULL;
1789 int v;
1790 unsigned int saved_min;
1791 int last = 0;
1792 int min, max;
1793 int mindir, maxdir;
1794 int valdir = dir ? *dir : 0;
1795 /* FIXME */
1796 if (best > INT_MAX)
1797 best = INT_MAX;
1798 min = max = best;
1799 mindir = maxdir = valdir;
1800 if (maxdir > 0)
1801 maxdir = 0;
1802 else if (maxdir == 0)
1803 maxdir = -1;
1804 else {
1805 maxdir = 1;
1806 max--;
1807 }
1808 save = kmalloc(sizeof(*save), GFP_KERNEL);
1809 if (save == NULL)
1810 return -ENOMEM;
1811 *save = *params;
1812 saved_min = min;
1813 min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
1814 if (min >= 0) {
1815 struct snd_pcm_hw_params *params1;
1816 if (max < 0)
1817 goto _end;
1818 if ((unsigned int)min == saved_min && mindir == valdir)
1819 goto _end;
1820 params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
1821 if (params1 == NULL) {
1822 kfree(save);
1823 return -ENOMEM;
1824 }
1825 *params1 = *save;
1826 max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
1827 if (max < 0) {
1828 kfree(params1);
1829 goto _end;
1830 }
1831 if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
1832 *params = *params1;
1833 last = 1;
1834 }
1835 kfree(params1);
1836 } else {
1837 *params = *save;
1838 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
1839 assert(max >= 0);
1840 last = 1;
1841 }
1842 _end:
1843 kfree(save);
1844 if (last)
1845 v = snd_pcm_hw_param_last(pcm, params, var, dir);
1846 else
1847 v = snd_pcm_hw_param_first(pcm, params, var, dir);
1848 assert(v >= 0);
1849 return v;
1850}
1851 1348
1852/** 1349/**
1853 * snd_pcm_hw_param_choose 1350 * snd_pcm_hw_param_choose
@@ -1967,6 +1464,8 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
1967 return -ENXIO; 1464 return -ENXIO;
1968} 1465}
1969 1466
1467EXPORT_SYMBOL(snd_pcm_lib_ioctl);
1468
1970/* 1469/*
1971 * Conditions 1470 * Conditions
1972 */ 1471 */
@@ -2101,6 +1600,8 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
2101 kill_fasync(&runtime->fasync, SIGIO, POLL_IN); 1600 kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
2102} 1601}
2103 1602
1603EXPORT_SYMBOL(snd_pcm_period_elapsed);
1604
2104static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, 1605static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
2105 unsigned int hwoff, 1606 unsigned int hwoff,
2106 unsigned long data, unsigned int off, 1607 unsigned long data, unsigned int off,
@@ -2308,6 +1809,8 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v
2308 snd_pcm_lib_write_transfer); 1809 snd_pcm_lib_write_transfer);
2309} 1810}
2310 1811
1812EXPORT_SYMBOL(snd_pcm_lib_write);
1813
2311static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, 1814static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
2312 unsigned int hwoff, 1815 unsigned int hwoff,
2313 unsigned long data, unsigned int off, 1816 unsigned long data, unsigned int off,
@@ -2370,6 +1873,8 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
2370 nonblock, snd_pcm_lib_writev_transfer); 1873 nonblock, snd_pcm_lib_writev_transfer);
2371} 1874}
2372 1875
1876EXPORT_SYMBOL(snd_pcm_lib_writev);
1877
2373static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, 1878static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream,
2374 unsigned int hwoff, 1879 unsigned int hwoff,
2375 unsigned long data, unsigned int off, 1880 unsigned long data, unsigned int off,
@@ -2578,6 +2083,8 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u
2578 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer); 2083 return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
2579} 2084}
2580 2085
2086EXPORT_SYMBOL(snd_pcm_lib_read);
2087
2581static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, 2088static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
2582 unsigned int hwoff, 2089 unsigned int hwoff,
2583 unsigned long data, unsigned int off, 2090 unsigned long data, unsigned int off,
@@ -2635,52 +2142,4 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
2635 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer); 2142 return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
2636} 2143}
2637 2144
2638/*
2639 * Exported symbols
2640 */
2641
2642EXPORT_SYMBOL(snd_interval_refine);
2643EXPORT_SYMBOL(snd_interval_list);
2644EXPORT_SYMBOL(snd_interval_ratnum);
2645EXPORT_SYMBOL(_snd_pcm_hw_params_any);
2646EXPORT_SYMBOL(_snd_pcm_hw_param_min);
2647EXPORT_SYMBOL(_snd_pcm_hw_param_set);
2648EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
2649EXPORT_SYMBOL(_snd_pcm_hw_param_setinteger);
2650EXPORT_SYMBOL(snd_pcm_hw_param_value_min);
2651EXPORT_SYMBOL(snd_pcm_hw_param_value_max);
2652EXPORT_SYMBOL(snd_pcm_hw_param_mask);
2653EXPORT_SYMBOL(snd_pcm_hw_param_first);
2654EXPORT_SYMBOL(snd_pcm_hw_param_last);
2655EXPORT_SYMBOL(snd_pcm_hw_param_near);
2656EXPORT_SYMBOL(snd_pcm_hw_param_set);
2657EXPORT_SYMBOL(snd_pcm_hw_refine);
2658EXPORT_SYMBOL(snd_pcm_hw_constraints_init);
2659EXPORT_SYMBOL(snd_pcm_hw_constraints_complete);
2660EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
2661EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
2662EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
2663EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
2664EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
2665EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
2666EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
2667EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
2668EXPORT_SYMBOL(snd_pcm_hw_rule_add);
2669EXPORT_SYMBOL(snd_pcm_set_ops);
2670EXPORT_SYMBOL(snd_pcm_set_sync);
2671EXPORT_SYMBOL(snd_pcm_lib_ioctl);
2672EXPORT_SYMBOL(snd_pcm_stop);
2673EXPORT_SYMBOL(snd_pcm_period_elapsed);
2674EXPORT_SYMBOL(snd_pcm_lib_write);
2675EXPORT_SYMBOL(snd_pcm_lib_read);
2676EXPORT_SYMBOL(snd_pcm_lib_writev);
2677EXPORT_SYMBOL(snd_pcm_lib_readv); 2145EXPORT_SYMBOL(snd_pcm_lib_readv);
2678EXPORT_SYMBOL(snd_pcm_lib_buffer_bytes);
2679EXPORT_SYMBOL(snd_pcm_lib_period_bytes);
2680/* pcm_memory.c */
2681EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
2682EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
2683EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
2684EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
2685EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
2686EXPORT_SYMBOL(snd_pcm_lib_free_pages);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 428f8c169ee1..eb56167d3bb4 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -126,6 +126,8 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
126 return 0; 126 return 0;
127} 127}
128 128
129EXPORT_SYMBOL(snd_pcm_lib_preallocate_free_for_all);
130
129#ifdef CONFIG_SND_VERBOSE_PROCFS 131#ifdef CONFIG_SND_VERBOSE_PROCFS
130/* 132/*
131 * read callback for prealloc proc file 133 * read callback for prealloc proc file
@@ -253,6 +255,8 @@ int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
253 return snd_pcm_lib_preallocate_pages1(substream, size, max); 255 return snd_pcm_lib_preallocate_pages1(substream, size, max);
254} 256}
255 257
258EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages);
259
256/** 260/**
257 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams) 261 * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continous memory type (all substreams)
258 * @pcm: the pcm instance 262 * @pcm: the pcm instance
@@ -280,6 +284,8 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
280 return 0; 284 return 0;
281} 285}
282 286
287EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
288
283/** 289/**
284 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset 290 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
285 * @substream: the pcm substream instance 291 * @substream: the pcm substream instance
@@ -298,6 +304,8 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
298 return sgbuf->page_table[idx]; 304 return sgbuf->page_table[idx];
299} 305}
300 306
307EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
308
301/** 309/**
302 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 310 * snd_pcm_lib_malloc_pages - allocate the DMA buffer
303 * @substream: the substream to allocate the DMA buffer to 311 * @substream: the substream to allocate the DMA buffer to
@@ -349,6 +357,8 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
349 return 1; /* area was changed */ 357 return 1; /* area was changed */
350} 358}
351 359
360EXPORT_SYMBOL(snd_pcm_lib_malloc_pages);
361
352/** 362/**
353 * snd_pcm_lib_free_pages - release the allocated DMA buffer. 363 * snd_pcm_lib_free_pages - release the allocated DMA buffer.
354 * @substream: the substream to release the DMA buffer 364 * @substream: the substream to release the DMA buffer
@@ -374,3 +384,5 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
374 snd_pcm_set_runtime_buffer(substream, NULL); 384 snd_pcm_set_runtime_buffer(substream, NULL);
375 return 0; 385 return 0;
376} 386}
387
388EXPORT_SYMBOL(snd_pcm_lib_free_pages);
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 593c77f4d181..0019c59a779d 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -207,6 +207,8 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
207 return val; 207 return val;
208} 208}
209 209
210EXPORT_SYMBOL(snd_pcm_format_signed);
211
210/** 212/**
211 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear 213 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
212 * @format: the format to check 214 * @format: the format to check
@@ -224,6 +226,8 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format)
224 return !val; 226 return !val;
225} 227}
226 228
229EXPORT_SYMBOL(snd_pcm_format_unsigned);
230
227/** 231/**
228 * snd_pcm_format_linear - Check the PCM format is linear 232 * snd_pcm_format_linear - Check the PCM format is linear
229 * @format: the format to check 233 * @format: the format to check
@@ -235,6 +239,8 @@ int snd_pcm_format_linear(snd_pcm_format_t format)
235 return snd_pcm_format_signed(format) >= 0; 239 return snd_pcm_format_signed(format) >= 0;
236} 240}
237 241
242EXPORT_SYMBOL(snd_pcm_format_linear);
243
238/** 244/**
239 * snd_pcm_format_little_endian - Check the PCM format is little-endian 245 * snd_pcm_format_little_endian - Check the PCM format is little-endian
240 * @format: the format to check 246 * @format: the format to check
@@ -252,6 +258,8 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
252 return val; 258 return val;
253} 259}
254 260
261EXPORT_SYMBOL(snd_pcm_format_little_endian);
262
255/** 263/**
256 * snd_pcm_format_big_endian - Check the PCM format is big-endian 264 * snd_pcm_format_big_endian - Check the PCM format is big-endian
257 * @format: the format to check 265 * @format: the format to check
@@ -269,6 +277,8 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format)
269 return !val; 277 return !val;
270} 278}
271 279
280EXPORT_SYMBOL(snd_pcm_format_big_endian);
281
272/** 282/**
273 * snd_pcm_format_width - return the bit-width of the format 283 * snd_pcm_format_width - return the bit-width of the format
274 * @format: the format to check 284 * @format: the format to check
@@ -286,6 +296,8 @@ int snd_pcm_format_width(snd_pcm_format_t format)
286 return val; 296 return val;
287} 297}
288 298
299EXPORT_SYMBOL(snd_pcm_format_width);
300
289/** 301/**
290 * snd_pcm_format_physical_width - return the physical bit-width of the format 302 * snd_pcm_format_physical_width - return the physical bit-width of the format
291 * @format: the format to check 303 * @format: the format to check
@@ -303,6 +315,8 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format)
303 return val; 315 return val;
304} 316}
305 317
318EXPORT_SYMBOL(snd_pcm_format_physical_width);
319
306/** 320/**
307 * snd_pcm_format_size - return the byte size of samples on the given format 321 * snd_pcm_format_size - return the byte size of samples on the given format
308 * @format: the format to check 322 * @format: the format to check
@@ -318,6 +332,8 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
318 return samples * phys_width / 8; 332 return samples * phys_width / 8;
319} 333}
320 334
335EXPORT_SYMBOL(snd_pcm_format_size);
336
321/** 337/**
322 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array 338 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array
323 * @format: the format to check 339 * @format: the format to check
@@ -333,6 +349,8 @@ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
333 return pcm_formats[format].silence; 349 return pcm_formats[format].silence;
334} 350}
335 351
352EXPORT_SYMBOL(snd_pcm_format_silence_64);
353
336/** 354/**
337 * snd_pcm_format_set_silence - set the silence data on the buffer 355 * snd_pcm_format_set_silence - set the silence data on the buffer
338 * @format: the PCM format 356 * @format: the PCM format
@@ -402,6 +420,8 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
402 return 0; 420 return 0;
403} 421}
404 422
423EXPORT_SYMBOL(snd_pcm_format_set_silence);
424
405/* [width][unsigned][bigendian] */ 425/* [width][unsigned][bigendian] */
406static int linear_formats[4][2][2] = { 426static int linear_formats[4][2][2] = {
407 {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, 427 {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8},
@@ -432,6 +452,8 @@ snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_end
432 return linear_formats[width][!!unsignd][!!big_endian]; 452 return linear_formats[width][!!unsignd][!!big_endian];
433} 453}
434 454
455EXPORT_SYMBOL(snd_pcm_build_linear_format);
456
435/** 457/**
436 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields 458 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
437 * @runtime: the runtime instance 459 * @runtime: the runtime instance
@@ -463,3 +485,5 @@ int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
463 } 485 }
464 return 0; 486 return 0;
465} 487}
488
489EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 0860c5a84502..7b5729c4b213 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -71,8 +71,9 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
71 */ 71 */
72 72
73DEFINE_RWLOCK(snd_pcm_link_rwlock); 73DEFINE_RWLOCK(snd_pcm_link_rwlock);
74static DECLARE_RWSEM(snd_pcm_link_rwsem); 74EXPORT_SYMBOL(snd_pcm_link_rwlock);
75 75
76static DECLARE_RWSEM(snd_pcm_link_rwsem);
76 77
77static inline mm_segment_t snd_enter_user(void) 78static inline mm_segment_t snd_enter_user(void)
78{ 79{
@@ -319,6 +320,8 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
319 return 0; 320 return 0;
320} 321}
321 322
323EXPORT_SYMBOL(snd_pcm_hw_refine);
324
322static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream, 325static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
323 struct snd_pcm_hw_params __user * _params) 326 struct snd_pcm_hw_params __user * _params)
324{ 327{
@@ -936,6 +939,8 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
936 return snd_pcm_action(&snd_pcm_action_stop, substream, state); 939 return snd_pcm_action(&snd_pcm_action_stop, substream, state);
937} 940}
938 941
942EXPORT_SYMBOL(snd_pcm_stop);
943
939/** 944/**
940 * snd_pcm_drain_done 945 * snd_pcm_drain_done
941 * @substream: the PCM substream 946 * @substream: the PCM substream
@@ -1085,6 +1090,8 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream)
1085 return err; 1090 return err;
1086} 1091}
1087 1092
1093EXPORT_SYMBOL(snd_pcm_suspend);
1094
1088/** 1095/**
1089 * snd_pcm_suspend_all 1096 * snd_pcm_suspend_all
1090 * @pcm: the PCM instance 1097 * @pcm: the PCM instance
@@ -1114,6 +1121,8 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
1114 return 0; 1121 return 0;
1115} 1122}
1116 1123
1124EXPORT_SYMBOL(snd_pcm_suspend_all);
1125
1117/* resume */ 1126/* resume */
1118 1127
1119static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state) 1128static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
@@ -2020,6 +2029,8 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2020 snd_pcm_detach_substream(substream); 2029 snd_pcm_detach_substream(substream);
2021} 2030}
2022 2031
2032EXPORT_SYMBOL(snd_pcm_release_substream);
2033
2023int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, 2034int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2024 struct file *file, 2035 struct file *file,
2025 struct snd_pcm_substream **rsubstream) 2036 struct snd_pcm_substream **rsubstream)
@@ -2056,6 +2067,8 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2056 return err; 2067 return err;
2057} 2068}
2058 2069
2070EXPORT_SYMBOL(snd_pcm_open_substream);
2071
2059static int snd_pcm_open_file(struct file *file, 2072static int snd_pcm_open_file(struct file *file,
2060 struct snd_pcm *pcm, 2073 struct snd_pcm *pcm,
2061 int stream, 2074 int stream,
@@ -2768,6 +2781,8 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2768 return result; 2781 return result;
2769} 2782}
2770 2783
2784EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
2785
2771static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, 2786static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
2772 loff_t * offset) 2787 loff_t * offset)
2773{ 2788{
@@ -3169,6 +3184,8 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3169 atomic_inc(&substream->runtime->mmap_count); 3184 atomic_inc(&substream->runtime->mmap_count);
3170 return 0; 3185 return 0;
3171} 3186}
3187
3188EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
3172#endif /* SNDRV_PCM_INFO_MMAP */ 3189#endif /* SNDRV_PCM_INFO_MMAP */
3173 3190
3174/* 3191/*
@@ -3212,6 +3229,8 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3212 return snd_pcm_default_mmap(substream, area); 3229 return snd_pcm_default_mmap(substream, area);
3213} 3230}
3214 3231
3232EXPORT_SYMBOL(snd_pcm_mmap_data);
3233
3215static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) 3234static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
3216{ 3235{
3217 struct snd_pcm_file * pcm_file; 3236 struct snd_pcm_file * pcm_file;