aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2007-08-13 11:40:54 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:58:54 -0400
commit918f3a0e8cf67b5db966516f255eaf24d814fac0 (patch)
treeae4ac300f4ca93346d4b4ca9a22d760c87ab3072 /sound
parent7653d557606c7cae921557a6a0ebb7c510e458eb (diff)
[ALSA] pcm: add snd_pcm_rate_to_rate_bit() helper
Add a snd_pcm_rate_to_rate_bit() function to factor out common code used by several drivers. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_misc.c18
-rw-r--r--sound/pci/bt87x.c21
-rw-r--r--sound/pci/rme32.c21
-rw-r--r--sound/pci/rme96.c22
-rw-r--r--sound/ppc/pmac.c31
-rw-r--r--sound/soc/codecs/cs4270.c49
-rw-r--r--sound/usb/usbaudio.c29
7 files changed, 46 insertions, 145 deletions
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index afd1e4929755..e5f25ae73ee2 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -450,3 +450,21 @@ int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
450} 450}
451 451
452EXPORT_SYMBOL(snd_pcm_limit_hw_rates); 452EXPORT_SYMBOL(snd_pcm_limit_hw_rates);
453
454/**
455 * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit
456 * @rate: the sample rate to convert
457 *
458 * Returns the SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or
459 * SNDRV_PCM_RATE_KNOT for an unknown rate.
460 */
461unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
462{
463 unsigned int i;
464
465 for (i = 0; i < snd_pcm_known_rates.count; i++)
466 if (snd_pcm_known_rates.list[i] == rate)
467 return 1u << i;
468 return SNDRV_PCM_RATE_KNOT;
469}
470EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index f0e12985dc29..85d50b64d2ba 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -340,28 +340,9 @@ static struct snd_pcm_hardware snd_bt87x_analog_hw = {
340 340
341static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime) 341static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime)
342{ 342{
343 static struct {
344 int rate;
345 unsigned int bit;
346 } ratebits[] = {
347 {8000, SNDRV_PCM_RATE_8000},
348 {11025, SNDRV_PCM_RATE_11025},
349 {16000, SNDRV_PCM_RATE_16000},
350 {22050, SNDRV_PCM_RATE_22050},
351 {32000, SNDRV_PCM_RATE_32000},
352 {44100, SNDRV_PCM_RATE_44100},
353 {48000, SNDRV_PCM_RATE_48000}
354 };
355 int i;
356
357 chip->reg_control |= CTL_DA_IOM_DA; 343 chip->reg_control |= CTL_DA_IOM_DA;
358 runtime->hw = snd_bt87x_digital_hw; 344 runtime->hw = snd_bt87x_digital_hw;
359 runtime->hw.rates = SNDRV_PCM_RATE_KNOT; 345 runtime->hw.rates = snd_pcm_rate_to_rate_bit(chip->dig_rate);
360 for (i = 0; i < ARRAY_SIZE(ratebits); ++i)
361 if (chip->dig_rate == ratebits[i].rate) {
362 runtime->hw.rates = ratebits[i].bit;
363 break;
364 }
365 runtime->hw.rate_min = chip->dig_rate; 346 runtime->hw.rate_min = chip->dig_rate;
366 runtime->hw.rate_max = chip->dig_rate; 347 runtime->hw.rate_max = chip->dig_rate;
367 return 0; 348 return 0;
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index ee0189b756d1..1475912588e9 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -258,19 +258,6 @@ static inline unsigned int snd_rme32_pcm_byteptr(struct rme32 * rme32)
258 & RME32_RCR_AUDIO_ADDR_MASK); 258 & RME32_RCR_AUDIO_ADDR_MASK);
259} 259}
260 260
261static int snd_rme32_ratecode(int rate)
262{
263 switch (rate) {
264 case 32000: return SNDRV_PCM_RATE_32000;
265 case 44100: return SNDRV_PCM_RATE_44100;
266 case 48000: return SNDRV_PCM_RATE_48000;
267 case 64000: return SNDRV_PCM_RATE_64000;
268 case 88200: return SNDRV_PCM_RATE_88200;
269 case 96000: return SNDRV_PCM_RATE_96000;
270 }
271 return 0;
272}
273
274/* silence callback for halfduplex mode */ 261/* silence callback for halfduplex mode */
275static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */ 262static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, int channel, /* not used (interleaved data) */
276 snd_pcm_uframes_t pos, 263 snd_pcm_uframes_t pos,
@@ -887,7 +874,7 @@ static int snd_rme32_playback_spdif_open(struct snd_pcm_substream *substream)
887 if ((rme32->rcreg & RME32_RCR_KMODE) && 874 if ((rme32->rcreg & RME32_RCR_KMODE) &&
888 (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) { 875 (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
889 /* AutoSync */ 876 /* AutoSync */
890 runtime->hw.rates = snd_rme32_ratecode(rate); 877 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
891 runtime->hw.rate_min = rate; 878 runtime->hw.rate_min = rate;
892 runtime->hw.rate_max = rate; 879 runtime->hw.rate_max = rate;
893 } 880 }
@@ -929,7 +916,7 @@ static int snd_rme32_capture_spdif_open(struct snd_pcm_substream *substream)
929 if (isadat) { 916 if (isadat) {
930 return -EIO; 917 return -EIO;
931 } 918 }
932 runtime->hw.rates = snd_rme32_ratecode(rate); 919 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
933 runtime->hw.rate_min = rate; 920 runtime->hw.rate_min = rate;
934 runtime->hw.rate_max = rate; 921 runtime->hw.rate_max = rate;
935 } 922 }
@@ -965,7 +952,7 @@ snd_rme32_playback_adat_open(struct snd_pcm_substream *substream)
965 if ((rme32->rcreg & RME32_RCR_KMODE) && 952 if ((rme32->rcreg & RME32_RCR_KMODE) &&
966 (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) { 953 (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
967 /* AutoSync */ 954 /* AutoSync */
968 runtime->hw.rates = snd_rme32_ratecode(rate); 955 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
969 runtime->hw.rate_min = rate; 956 runtime->hw.rate_min = rate;
970 runtime->hw.rate_max = rate; 957 runtime->hw.rate_max = rate;
971 } 958 }
@@ -989,7 +976,7 @@ snd_rme32_capture_adat_open(struct snd_pcm_substream *substream)
989 if (!isadat) { 976 if (!isadat) {
990 return -EIO; 977 return -EIO;
991 } 978 }
992 runtime->hw.rates = snd_rme32_ratecode(rate); 979 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
993 runtime->hw.rate_min = rate; 980 runtime->hw.rate_min = rate;
994 runtime->hw.rate_max = rate; 981 runtime->hw.rate_max = rate;
995 } 982 }
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index ba4a34bae48f..0b3c532c4014 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -301,20 +301,6 @@ snd_rme96_capture_ptr(struct rme96 *rme96)
301} 301}
302 302
303static int 303static int
304snd_rme96_ratecode(int rate)
305{
306 switch (rate) {
307 case 32000: return SNDRV_PCM_RATE_32000;
308 case 44100: return SNDRV_PCM_RATE_44100;
309 case 48000: return SNDRV_PCM_RATE_48000;
310 case 64000: return SNDRV_PCM_RATE_64000;
311 case 88200: return SNDRV_PCM_RATE_88200;
312 case 96000: return SNDRV_PCM_RATE_96000;
313 }
314 return 0;
315}
316
317static int
318snd_rme96_playback_silence(struct snd_pcm_substream *substream, 304snd_rme96_playback_silence(struct snd_pcm_substream *substream,
319 int channel, /* not used (interleaved data) */ 305 int channel, /* not used (interleaved data) */
320 snd_pcm_uframes_t pos, 306 snd_pcm_uframes_t pos,
@@ -1192,7 +1178,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
1192 (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) 1178 (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
1193 { 1179 {
1194 /* slave clock */ 1180 /* slave clock */
1195 runtime->hw.rates = snd_rme96_ratecode(rate); 1181 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
1196 runtime->hw.rate_min = rate; 1182 runtime->hw.rate_min = rate;
1197 runtime->hw.rate_max = rate; 1183 runtime->hw.rate_max = rate;
1198 } 1184 }
@@ -1219,7 +1205,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
1219 if (isadat) { 1205 if (isadat) {
1220 return -EIO; 1206 return -EIO;
1221 } 1207 }
1222 runtime->hw.rates = snd_rme96_ratecode(rate); 1208 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
1223 runtime->hw.rate_min = rate; 1209 runtime->hw.rate_min = rate;
1224 runtime->hw.rate_max = rate; 1210 runtime->hw.rate_max = rate;
1225 } 1211 }
@@ -1259,7 +1245,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
1259 (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) 1245 (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
1260 { 1246 {
1261 /* slave clock */ 1247 /* slave clock */
1262 runtime->hw.rates = snd_rme96_ratecode(rate); 1248 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
1263 runtime->hw.rate_min = rate; 1249 runtime->hw.rate_min = rate;
1264 runtime->hw.rate_max = rate; 1250 runtime->hw.rate_max = rate;
1265 } 1251 }
@@ -1284,7 +1270,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
1284 if (!isadat) { 1270 if (!isadat) {
1285 return -EIO; 1271 return -EIO;
1286 } 1272 }
1287 runtime->hw.rates = snd_rme96_ratecode(rate); 1273 runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate);
1288 runtime->hw.rate_min = rate; 1274 runtime->hw.rate_min = rate;
1289 runtime->hw.rate_max = rate; 1275 runtime->hw.rate_max = rate;
1290 } 1276 }
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 04b95ae5c3aa..4f9b19c90a43 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -490,35 +490,14 @@ static int snd_pmac_pcm_open(struct snd_pmac *chip, struct pmac_stream *rec,
490 struct snd_pcm_substream *subs) 490 struct snd_pcm_substream *subs)
491{ 491{
492 struct snd_pcm_runtime *runtime = subs->runtime; 492 struct snd_pcm_runtime *runtime = subs->runtime;
493 int i, j, fflags; 493 int i;
494 static int typical_freqs[] = {
495 44100,
496 22050,
497 11025,
498 0,
499 };
500 static int typical_freq_flags[] = {
501 SNDRV_PCM_RATE_44100,
502 SNDRV_PCM_RATE_22050,
503 SNDRV_PCM_RATE_11025,
504 0,
505 };
506 494
507 /* look up frequency table and fill bit mask */ 495 /* look up frequency table and fill bit mask */
508 runtime->hw.rates = 0; 496 runtime->hw.rates = 0;
509 fflags = chip->freqs_ok; 497 for (i = 0; i < chip->num_freqs; i++)
510 for (i = 0; typical_freqs[i]; i++) { 498 if (chip->freqs_ok & (1 << i))
511 for (j = 0; j < chip->num_freqs; j++) { 499 runtime->hw.rates |=
512 if ((chip->freqs_ok & (1 << j)) && 500 snd_pcm_rate_to_rate_bit(chip->freq_table[i]);
513 chip->freq_table[j] == typical_freqs[i]) {
514 runtime->hw.rates |= typical_freq_flags[i];
515 fflags &= ~(1 << j);
516 break;
517 }
518 }
519 }
520 if (fflags) /* rest */
521 runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
522 501
523 /* check for minimum and maximum rates */ 502 /* check for minimum and maximum rates */
524 for (i = 0; i < chip->num_freqs; i++) { 503 for (i = 0; i < chip->num_freqs; i++) {
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 8beae65d083c..43d50a4d8089 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -56,35 +56,6 @@ static unsigned int mclk_ratios[NUM_MCLK_RATIOS] =
56 {64, 96, 128, 192, 256, 384, 512, 768, 1024}; 56 {64, 96, 128, 192, 256, 384, 512, 768, 1024};
57 57
58/* 58/*
59 * Sampling rate <-> bit patter mapping
60 *
61 * This array maps sampling rates to their SNDRV_PCM_RATE_x equivalent.
62 *
63 * This is really something that ALSA should provide.
64 *
65 * This table is used by cs4270_set_dai_sysclk() to tell ALSA which sampling
66 * rates the CS4270 currently supports.
67 */
68static struct {
69 unsigned int rate;
70 unsigned int bit;
71} rate_map[] = {
72 {5512, SNDRV_PCM_RATE_5512},
73 {8000, SNDRV_PCM_RATE_8000},
74 {11025, SNDRV_PCM_RATE_11025},
75 {16000, SNDRV_PCM_RATE_16000},
76 {22050, SNDRV_PCM_RATE_22050},
77 {32000, SNDRV_PCM_RATE_32000},
78 {44100, SNDRV_PCM_RATE_44100},
79 {48000, SNDRV_PCM_RATE_48000},
80 {64000, SNDRV_PCM_RATE_64000},
81 {88200, SNDRV_PCM_RATE_88200},
82 {96000, SNDRV_PCM_RATE_96000},
83 {176400, SNDRV_PCM_RATE_176400},
84 {192000, SNDRV_PCM_RATE_192000}
85};
86
87/*
88 * Determine the CS4270 samples rates. 59 * Determine the CS4270 samples rates.
89 * 60 *
90 * 'freq' is the input frequency to MCLK. The other parameters are ignored. 61 * 'freq' is the input frequency to MCLK. The other parameters are ignored.
@@ -126,19 +97,15 @@ static int cs4270_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
126 cs4270->mclk = freq; 97 cs4270->mclk = freq;
127 98
128 for (i = 0; i < NUM_MCLK_RATIOS; i++) { 99 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
129 unsigned int rate; 100 unsigned int rate = freq / mclk_ratios[i];
130 unsigned int j; 101 rates |= snd_pcm_rate_to_rate_bit(rate);
131 rate = freq / mclk_ratios[i]; 102 if (rate < rate_min)
132 for (j = 0; j < ARRAY_SIZE(rate_map); j++) { 103 rate_min = rate;
133 if (rate == rate_map[j].rate) { 104 if (rate > rate_max)
134 rates |= rate_map[j].bit; 105 rate_max = rate;
135 if (rate < rate_min)
136 rate_min = rate;
137 if (rate > rate_max)
138 rate_max = rate;
139 }
140 }
141 } 106 }
107 /* FIXME: soc should support a rate list */
108 rates &= ~SNDRV_PCM_RATE_KNOT;
142 109
143 if (!rates) { 110 if (!rates) {
144 printk(KERN_ERR "cs4270: could not find a valid sample rate\n"); 111 printk(KERN_ERR "cs4270: could not find a valid sample rate\n");
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index ac5666f4c6d5..cbe8b335147c 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -123,7 +123,6 @@ struct audioformat {
123 unsigned int rate_min, rate_max; /* min/max rates */ 123 unsigned int rate_min, rate_max; /* min/max rates */
124 unsigned int nr_rates; /* number of rate table entries */ 124 unsigned int nr_rates; /* number of rate table entries */
125 unsigned int *rate_table; /* rate table */ 125 unsigned int *rate_table; /* rate table */
126 unsigned int needs_knot; /* any unusual rates? */
127}; 126};
128 127
129struct snd_usb_substream; 128struct snd_usb_substream;
@@ -1761,7 +1760,7 @@ static int check_hw_params_convention(struct snd_usb_substream *subs)
1761 channels[f->format] |= (1 << f->channels); 1760 channels[f->format] |= (1 << f->channels);
1762 rates[f->format] |= f->rates; 1761 rates[f->format] |= f->rates;
1763 /* needs knot? */ 1762 /* needs knot? */
1764 if (f->needs_knot) 1763 if (f->rates & SNDRV_PCM_RATE_KNOT)
1765 goto __out; 1764 goto __out;
1766 } 1765 }
1767 /* check whether channels and rates match for all formats */ 1766 /* check whether channels and rates match for all formats */
@@ -1817,7 +1816,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
1817 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) 1816 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
1818 return 0; 1817 return 0;
1819 count += fp->nr_rates; 1818 count += fp->nr_rates;
1820 if (fp->needs_knot) 1819 if (fp->rates & SNDRV_PCM_RATE_KNOT)
1821 needs_knot = 1; 1820 needs_knot = 1;
1822 } 1821 }
1823 if (!needs_knot) 1822 if (!needs_knot)
@@ -2453,7 +2452,7 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2453 unsigned char *fmt, int offset) 2452 unsigned char *fmt, int offset)
2454{ 2453{
2455 int nr_rates = fmt[offset]; 2454 int nr_rates = fmt[offset];
2456 int found; 2455
2457 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { 2456 if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
2458 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n", 2457 snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n",
2459 chip->dev->devnum, fp->iface, fp->altsetting); 2458 chip->dev->devnum, fp->iface, fp->altsetting);
@@ -2464,20 +2463,15 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2464 /* 2463 /*
2465 * build the rate table and bitmap flags 2464 * build the rate table and bitmap flags
2466 */ 2465 */
2467 int r, idx, c; 2466 int r, idx;
2468 unsigned int nonzero_rates = 0; 2467 unsigned int nonzero_rates = 0;
2469 /* this table corresponds to the SNDRV_PCM_RATE_XXX bit */ 2468
2470 static unsigned int conv_rates[] = {
2471 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
2472 64000, 88200, 96000, 176400, 192000
2473 };
2474 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); 2469 fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL);
2475 if (fp->rate_table == NULL) { 2470 if (fp->rate_table == NULL) {
2476 snd_printk(KERN_ERR "cannot malloc\n"); 2471 snd_printk(KERN_ERR "cannot malloc\n");
2477 return -1; 2472 return -1;
2478 } 2473 }
2479 2474
2480 fp->needs_knot = 0;
2481 fp->nr_rates = nr_rates; 2475 fp->nr_rates = nr_rates;
2482 fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); 2476 fp->rate_min = fp->rate_max = combine_triple(&fmt[8]);
2483 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { 2477 for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
@@ -2493,23 +2487,12 @@ static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioform
2493 fp->rate_min = rate; 2487 fp->rate_min = rate;
2494 else if (rate > fp->rate_max) 2488 else if (rate > fp->rate_max)
2495 fp->rate_max = rate; 2489 fp->rate_max = rate;
2496 found = 0; 2490 fp->rates |= snd_pcm_rate_to_rate_bit(rate);
2497 for (c = 0; c < (int)ARRAY_SIZE(conv_rates); c++) {
2498 if (rate == conv_rates[c]) {
2499 found = 1;
2500 fp->rates |= (1 << c);
2501 break;
2502 }
2503 }
2504 if (!found)
2505 fp->needs_knot = 1;
2506 } 2491 }
2507 if (!nonzero_rates) { 2492 if (!nonzero_rates) {
2508 hwc_debug("All rates were zero. Skipping format!\n"); 2493 hwc_debug("All rates were zero. Skipping format!\n");
2509 return -1; 2494 return -1;
2510 } 2495 }
2511 if (fp->needs_knot)
2512 fp->rates |= SNDRV_PCM_RATE_KNOT;
2513 } else { 2496 } else {
2514 /* continuous rates */ 2497 /* continuous rates */
2515 fp->rates = SNDRV_PCM_RATE_CONTINUOUS; 2498 fp->rates = SNDRV_PCM_RATE_CONTINUOUS;