]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - sound/core/pcm_misc.c
Merge tag 'iwlwifi-for-john-2014-10-23' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / sound / core / pcm_misc.c
1 /*
2  *  PCM Interface - misc routines
3  *  Copyright (c) 1998 by Jaroslav Kysela <perex@perex.cz>
4  *
5  *
6  *   This library is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU Library General Public License as
8  *   published by the Free Software Foundation; either version 2 of
9  *   the License, or (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU Library General Public License for more details.
15  *
16  *   You should have received a copy of the GNU Library General Public
17  *   License along with this library; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  *
20  */
21   
22 #include <linux/time.h>
23 #include <linux/export.h>
24 #include <sound/core.h>
25 #include <sound/pcm.h>
26 #define SND_PCM_FORMAT_UNKNOWN (-1)
27
28 /* NOTE: "signed" prefix must be given below since the default char is
29  *       unsigned on some architectures!
30  */
31 struct pcm_format_data {
32         unsigned char width;    /* bit width */
33         unsigned char phys;     /* physical bit width */
34         signed char le; /* 0 = big-endian, 1 = little-endian, -1 = others */
35         signed char signd;      /* 0 = unsigned, 1 = signed, -1 = others */
36         unsigned char silence[8];       /* silence data to fill */
37 };
38
39 /* we do lots of calculations on snd_pcm_format_t; shut up sparse */
40 #define INT     __force int
41
42 static struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = {
43         [SNDRV_PCM_FORMAT_S8] = {
44                 .width = 8, .phys = 8, .le = -1, .signd = 1,
45                 .silence = {},
46         },
47         [SNDRV_PCM_FORMAT_U8] = {
48                 .width = 8, .phys = 8, .le = -1, .signd = 0,
49                 .silence = { 0x80 },
50         },
51         [SNDRV_PCM_FORMAT_S16_LE] = {
52                 .width = 16, .phys = 16, .le = 1, .signd = 1,
53                 .silence = {},
54         },
55         [SNDRV_PCM_FORMAT_S16_BE] = {
56                 .width = 16, .phys = 16, .le = 0, .signd = 1,
57                 .silence = {},
58         },
59         [SNDRV_PCM_FORMAT_U16_LE] = {
60                 .width = 16, .phys = 16, .le = 1, .signd = 0,
61                 .silence = { 0x00, 0x80 },
62         },
63         [SNDRV_PCM_FORMAT_U16_BE] = {
64                 .width = 16, .phys = 16, .le = 0, .signd = 0,
65                 .silence = { 0x80, 0x00 },
66         },
67         [SNDRV_PCM_FORMAT_S24_LE] = {
68                 .width = 24, .phys = 32, .le = 1, .signd = 1,
69                 .silence = {},
70         },
71         [SNDRV_PCM_FORMAT_S24_BE] = {
72                 .width = 24, .phys = 32, .le = 0, .signd = 1,
73                 .silence = {},
74         },
75         [SNDRV_PCM_FORMAT_U24_LE] = {
76                 .width = 24, .phys = 32, .le = 1, .signd = 0,
77                 .silence = { 0x00, 0x00, 0x80 },
78         },
79         [SNDRV_PCM_FORMAT_U24_BE] = {
80                 .width = 24, .phys = 32, .le = 0, .signd = 0,
81                 .silence = { 0x00, 0x80, 0x00, 0x00 },
82         },
83         [SNDRV_PCM_FORMAT_S32_LE] = {
84                 .width = 32, .phys = 32, .le = 1, .signd = 1,
85                 .silence = {},
86         },
87         [SNDRV_PCM_FORMAT_S32_BE] = {
88                 .width = 32, .phys = 32, .le = 0, .signd = 1,
89                 .silence = {},
90         },
91         [SNDRV_PCM_FORMAT_U32_LE] = {
92                 .width = 32, .phys = 32, .le = 1, .signd = 0,
93                 .silence = { 0x00, 0x00, 0x00, 0x80 },
94         },
95         [SNDRV_PCM_FORMAT_U32_BE] = {
96                 .width = 32, .phys = 32, .le = 0, .signd = 0,
97                 .silence = { 0x80, 0x00, 0x00, 0x00 },
98         },
99         [SNDRV_PCM_FORMAT_FLOAT_LE] = {
100                 .width = 32, .phys = 32, .le = 1, .signd = -1,
101                 .silence = {},
102         },
103         [SNDRV_PCM_FORMAT_FLOAT_BE] = {
104                 .width = 32, .phys = 32, .le = 0, .signd = -1,
105                 .silence = {},
106         },
107         [SNDRV_PCM_FORMAT_FLOAT64_LE] = {
108                 .width = 64, .phys = 64, .le = 1, .signd = -1,
109                 .silence = {},
110         },
111         [SNDRV_PCM_FORMAT_FLOAT64_BE] = {
112                 .width = 64, .phys = 64, .le = 0, .signd = -1,
113                 .silence = {},
114         },
115         [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE] = {
116                 .width = 32, .phys = 32, .le = 1, .signd = -1,
117                 .silence = {},
118         },
119         [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE] = {
120                 .width = 32, .phys = 32, .le = 0, .signd = -1,
121                 .silence = {},
122         },
123         [SNDRV_PCM_FORMAT_MU_LAW] = {
124                 .width = 8, .phys = 8, .le = -1, .signd = -1,
125                 .silence = { 0x7f },
126         },
127         [SNDRV_PCM_FORMAT_A_LAW] = {
128                 .width = 8, .phys = 8, .le = -1, .signd = -1,
129                 .silence = { 0x55 },
130         },
131         [SNDRV_PCM_FORMAT_IMA_ADPCM] = {
132                 .width = 4, .phys = 4, .le = -1, .signd = -1,
133                 .silence = {},
134         },
135         [SNDRV_PCM_FORMAT_G723_24] = {
136                 .width = 3, .phys = 3, .le = -1, .signd = -1,
137                 .silence = {},
138         },
139         [SNDRV_PCM_FORMAT_G723_40] = {
140                 .width = 5, .phys = 5, .le = -1, .signd = -1,
141                 .silence = {},
142         },
143         [SNDRV_PCM_FORMAT_DSD_U8] = {
144                 .width = 8, .phys = 8, .le = 1, .signd = 0,
145                 .silence = { 0x69 },
146         },
147         [SNDRV_PCM_FORMAT_DSD_U16_LE] = {
148                 .width = 16, .phys = 16, .le = 1, .signd = 0,
149                 .silence = { 0x69, 0x69 },
150         },
151         [SNDRV_PCM_FORMAT_DSD_U32_LE] = {
152                 .width = 32, .phys = 32, .le = 1, .signd = 0,
153                 .silence = { 0x69, 0x69, 0x69, 0x69 },
154         },
155         /* FIXME: the following three formats are not defined properly yet */
156         [SNDRV_PCM_FORMAT_MPEG] = {
157                 .le = -1, .signd = -1,
158         },
159         [SNDRV_PCM_FORMAT_GSM] = {
160                 .le = -1, .signd = -1,
161         },
162         [SNDRV_PCM_FORMAT_SPECIAL] = {
163                 .le = -1, .signd = -1,
164         },
165         [SNDRV_PCM_FORMAT_S24_3LE] = {
166                 .width = 24, .phys = 24, .le = 1, .signd = 1,
167                 .silence = {},
168         },
169         [SNDRV_PCM_FORMAT_S24_3BE] = {
170                 .width = 24, .phys = 24, .le = 0, .signd = 1,
171                 .silence = {},
172         },
173         [SNDRV_PCM_FORMAT_U24_3LE] = {
174                 .width = 24, .phys = 24, .le = 1, .signd = 0,
175                 .silence = { 0x00, 0x00, 0x80 },
176         },
177         [SNDRV_PCM_FORMAT_U24_3BE] = {
178                 .width = 24, .phys = 24, .le = 0, .signd = 0,
179                 .silence = { 0x80, 0x00, 0x00 },
180         },
181         [SNDRV_PCM_FORMAT_S20_3LE] = {
182                 .width = 20, .phys = 24, .le = 1, .signd = 1,
183                 .silence = {},
184         },
185         [SNDRV_PCM_FORMAT_S20_3BE] = {
186                 .width = 20, .phys = 24, .le = 0, .signd = 1,
187                 .silence = {},
188         },
189         [SNDRV_PCM_FORMAT_U20_3LE] = {
190                 .width = 20, .phys = 24, .le = 1, .signd = 0,
191                 .silence = { 0x00, 0x00, 0x08 },
192         },
193         [SNDRV_PCM_FORMAT_U20_3BE] = {
194                 .width = 20, .phys = 24, .le = 0, .signd = 0,
195                 .silence = { 0x08, 0x00, 0x00 },
196         },
197         [SNDRV_PCM_FORMAT_S18_3LE] = {
198                 .width = 18, .phys = 24, .le = 1, .signd = 1,
199                 .silence = {},
200         },
201         [SNDRV_PCM_FORMAT_S18_3BE] = {
202                 .width = 18, .phys = 24, .le = 0, .signd = 1,
203                 .silence = {},
204         },
205         [SNDRV_PCM_FORMAT_U18_3LE] = {
206                 .width = 18, .phys = 24, .le = 1, .signd = 0,
207                 .silence = { 0x00, 0x00, 0x02 },
208         },
209         [SNDRV_PCM_FORMAT_U18_3BE] = {
210                 .width = 18, .phys = 24, .le = 0, .signd = 0,
211                 .silence = { 0x02, 0x00, 0x00 },
212         },
213         [SNDRV_PCM_FORMAT_G723_24_1B] = {
214                 .width = 3, .phys = 8, .le = -1, .signd = -1,
215                 .silence = {},
216         },
217         [SNDRV_PCM_FORMAT_G723_40_1B] = {
218                 .width = 5, .phys = 8, .le = -1, .signd = -1,
219                 .silence = {},
220         },
221 };
222
223
224 /**
225  * snd_pcm_format_signed - Check the PCM format is signed linear
226  * @format: the format to check
227  *
228  * Return: 1 if the given PCM format is signed linear, 0 if unsigned
229  * linear, and a negative error code for non-linear formats.
230  */
231 int snd_pcm_format_signed(snd_pcm_format_t format)
232 {
233         int val;
234         if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
235                 return -EINVAL;
236         if ((val = pcm_formats[(INT)format].signd) < 0)
237                 return -EINVAL;
238         return val;
239 }
240
241 EXPORT_SYMBOL(snd_pcm_format_signed);
242
243 /**
244  * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
245  * @format: the format to check
246  *
247  * Return: 1 if the given PCM format is unsigned linear, 0 if signed
248  * linear, and a negative error code for non-linear formats.
249  */
250 int snd_pcm_format_unsigned(snd_pcm_format_t format)
251 {
252         int val;
253
254         val = snd_pcm_format_signed(format);
255         if (val < 0)
256                 return val;
257         return !val;
258 }
259
260 EXPORT_SYMBOL(snd_pcm_format_unsigned);
261
262 /**
263  * snd_pcm_format_linear - Check the PCM format is linear
264  * @format: the format to check
265  *
266  * Return: 1 if the given PCM format is linear, 0 if not.
267  */
268 int snd_pcm_format_linear(snd_pcm_format_t format)
269 {
270         return snd_pcm_format_signed(format) >= 0;
271 }
272
273 EXPORT_SYMBOL(snd_pcm_format_linear);
274
275 /**
276  * snd_pcm_format_little_endian - Check the PCM format is little-endian
277  * @format: the format to check
278  *
279  * Return: 1 if the given PCM format is little-endian, 0 if
280  * big-endian, or a negative error code if endian not specified.
281  */
282 int snd_pcm_format_little_endian(snd_pcm_format_t format)
283 {
284         int val;
285         if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
286                 return -EINVAL;
287         if ((val = pcm_formats[(INT)format].le) < 0)
288                 return -EINVAL;
289         return val;
290 }
291
292 EXPORT_SYMBOL(snd_pcm_format_little_endian);
293
294 /**
295  * snd_pcm_format_big_endian - Check the PCM format is big-endian
296  * @format: the format to check
297  *
298  * Return: 1 if the given PCM format is big-endian, 0 if
299  * little-endian, or a negative error code if endian not specified.
300  */
301 int snd_pcm_format_big_endian(snd_pcm_format_t format)
302 {
303         int val;
304
305         val = snd_pcm_format_little_endian(format);
306         if (val < 0)
307                 return val;
308         return !val;
309 }
310
311 EXPORT_SYMBOL(snd_pcm_format_big_endian);
312
313 /**
314  * snd_pcm_format_width - return the bit-width of the format
315  * @format: the format to check
316  *
317  * Return: The bit-width of the format, or a negative error code
318  * if unknown format.
319  */
320 int snd_pcm_format_width(snd_pcm_format_t format)
321 {
322         int val;
323         if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
324                 return -EINVAL;
325         if ((val = pcm_formats[(INT)format].width) == 0)
326                 return -EINVAL;
327         return val;
328 }
329
330 EXPORT_SYMBOL(snd_pcm_format_width);
331
332 /**
333  * snd_pcm_format_physical_width - return the physical bit-width of the format
334  * @format: the format to check
335  *
336  * Return: The physical bit-width of the format, or a negative error code
337  * if unknown format.
338  */
339 int snd_pcm_format_physical_width(snd_pcm_format_t format)
340 {
341         int val;
342         if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
343                 return -EINVAL;
344         if ((val = pcm_formats[(INT)format].phys) == 0)
345                 return -EINVAL;
346         return val;
347 }
348
349 EXPORT_SYMBOL(snd_pcm_format_physical_width);
350
351 /**
352  * snd_pcm_format_size - return the byte size of samples on the given format
353  * @format: the format to check
354  * @samples: sampling rate
355  *
356  * Return: The byte size of the given samples for the format, or a
357  * negative error code if unknown format.
358  */
359 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
360 {
361         int phys_width = snd_pcm_format_physical_width(format);
362         if (phys_width < 0)
363                 return -EINVAL;
364         return samples * phys_width / 8;
365 }
366
367 EXPORT_SYMBOL(snd_pcm_format_size);
368
369 /**
370  * snd_pcm_format_silence_64 - return the silent data in 8 bytes array
371  * @format: the format to check
372  *
373  * Return: The format pattern to fill or %NULL if error.
374  */
375 const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
376 {
377         if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
378                 return NULL;
379         if (! pcm_formats[(INT)format].phys)
380                 return NULL;
381         return pcm_formats[(INT)format].silence;
382 }
383
384 EXPORT_SYMBOL(snd_pcm_format_silence_64);
385
386 /**
387  * snd_pcm_format_set_silence - set the silence data on the buffer
388  * @format: the PCM format
389  * @data: the buffer pointer
390  * @samples: the number of samples to set silence
391  *
392  * Sets the silence data on the buffer for the given samples.
393  *
394  * Return: Zero if successful, or a negative error code on failure.
395  */
396 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
397 {
398         int width;
399         unsigned char *dst, *pat;
400
401         if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST)
402                 return -EINVAL;
403         if (samples == 0)
404                 return 0;
405         width = pcm_formats[(INT)format].phys; /* physical width */
406         pat = pcm_formats[(INT)format].silence;
407         if (! width)
408                 return -EINVAL;
409         /* signed or 1 byte data */
410         if (pcm_formats[(INT)format].signd == 1 || width <= 8) {
411                 unsigned int bytes = samples * width / 8;
412                 memset(data, *pat, bytes);
413                 return 0;
414         }
415         /* non-zero samples, fill using a loop */
416         width /= 8;
417         dst = data;
418 #if 0
419         while (samples--) {
420                 memcpy(dst, pat, width);
421                 dst += width;
422         }
423 #else
424         /* a bit optimization for constant width */
425         switch (width) {
426         case 2:
427                 while (samples--) {
428                         memcpy(dst, pat, 2);
429                         dst += 2;
430                 }
431                 break;
432         case 3:
433                 while (samples--) {
434                         memcpy(dst, pat, 3);
435                         dst += 3;
436                 }
437                 break;
438         case 4:
439                 while (samples--) {
440                         memcpy(dst, pat, 4);
441                         dst += 4;
442                 }
443                 break;
444         case 8:
445                 while (samples--) {
446                         memcpy(dst, pat, 8);
447                         dst += 8;
448                 }
449                 break;
450         }
451 #endif
452         return 0;
453 }
454
455 EXPORT_SYMBOL(snd_pcm_format_set_silence);
456
457 /**
458  * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
459  * @runtime: the runtime instance
460  *
461  * Determines the rate_min and rate_max fields from the rates bits of
462  * the given runtime->hw.
463  *
464  * Return: Zero if successful.
465  */
466 int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
467 {
468         int i;
469         for (i = 0; i < (int)snd_pcm_known_rates.count; i++) {
470                 if (runtime->hw.rates & (1 << i)) {
471                         runtime->hw.rate_min = snd_pcm_known_rates.list[i];
472                         break;
473                 }
474         }
475         for (i = (int)snd_pcm_known_rates.count - 1; i >= 0; i--) {
476                 if (runtime->hw.rates & (1 << i)) {
477                         runtime->hw.rate_max = snd_pcm_known_rates.list[i];
478                         break;
479                 }
480         }
481         return 0;
482 }
483
484 EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
485
486 /**
487  * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit
488  * @rate: the sample rate to convert
489  *
490  * Return: The SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or
491  * SNDRV_PCM_RATE_KNOT for an unknown rate.
492  */
493 unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
494 {
495         unsigned int i;
496
497         for (i = 0; i < snd_pcm_known_rates.count; i++)
498                 if (snd_pcm_known_rates.list[i] == rate)
499                         return 1u << i;
500         return SNDRV_PCM_RATE_KNOT;
501 }
502 EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);
503
504 /**
505  * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate
506  * @rate_bit: the rate bit to convert
507  *
508  * Return: The sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag
509  * or 0 for an unknown rate bit.
510  */
511 unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit)
512 {
513         unsigned int i;
514
515         for (i = 0; i < snd_pcm_known_rates.count; i++)
516                 if ((1u << i) == rate_bit)
517                         return snd_pcm_known_rates.list[i];
518         return 0;
519 }
520 EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate);
521
522 static unsigned int snd_pcm_rate_mask_sanitize(unsigned int rates)
523 {
524         if (rates & SNDRV_PCM_RATE_CONTINUOUS)
525                 return SNDRV_PCM_RATE_CONTINUOUS;
526         else if (rates & SNDRV_PCM_RATE_KNOT)
527                 return SNDRV_PCM_RATE_KNOT;
528         return rates;
529 }
530
531 /**
532  * snd_pcm_rate_mask_intersect - computes the intersection between two rate masks
533  * @rates_a: The first rate mask
534  * @rates_b: The second rate mask
535  *
536  * This function computes the rates that are supported by both rate masks passed
537  * to the function. It will take care of the special handling of
538  * SNDRV_PCM_RATE_CONTINUOUS and SNDRV_PCM_RATE_KNOT.
539  *
540  * Return: A rate mask containing the rates that are supported by both rates_a
541  * and rates_b.
542  */
543 unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
544         unsigned int rates_b)
545 {
546         rates_a = snd_pcm_rate_mask_sanitize(rates_a);
547         rates_b = snd_pcm_rate_mask_sanitize(rates_b);
548
549         if (rates_a & SNDRV_PCM_RATE_CONTINUOUS)
550                 return rates_b;
551         else if (rates_b & SNDRV_PCM_RATE_CONTINUOUS)
552                 return rates_a;
553         else if (rates_a & SNDRV_PCM_RATE_KNOT)
554                 return rates_b;
555         else if (rates_b & SNDRV_PCM_RATE_KNOT)
556                 return rates_a;
557         return rates_a & rates_b;
558 }
559 EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect);