diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/pcm_misc.c | 39 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 3 | ||||
-rw-r--r-- | sound/soc/fsl/mpc5200_psc_i2s.c | 3 | ||||
-rw-r--r-- | sound/soc/s6000/s6000-i2s.c | 3 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 23 |
5 files changed, 53 insertions, 18 deletions
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 43f24cce3dec..4560ca0e5651 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -514,3 +514,42 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) return 0; } EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate); + +static unsigned int snd_pcm_rate_mask_sanitize(unsigned int rates) +{ + if (rates & SNDRV_PCM_RATE_CONTINUOUS) + return SNDRV_PCM_RATE_CONTINUOUS; + else if (rates & SNDRV_PCM_RATE_KNOT) + return SNDRV_PCM_RATE_KNOT; + return rates; +} + +/** + * snd_pcm_rate_mask_intersect - computes the intersection between two rate masks + * @rates_a: The first rate mask + * @rates_b: The second rate mask + * + * This function computes the rates that are supported by both rate masks passed + * to the function. It will take care of the special handling of + * SNDRV_PCM_RATE_CONTINUOUS and SNDRV_PCM_RATE_KNOT. + * + * Return: A rate mask containing the rates that are supported by both rates_a + * and rates_b. + */ +unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, + unsigned int rates_b) +{ + rates_a = snd_pcm_rate_mask_sanitize(rates_a); + rates_b = snd_pcm_rate_mask_sanitize(rates_b); + + if (rates_a & SNDRV_PCM_RATE_CONTINUOUS) + return rates_b; + else if (rates_b & SNDRV_PCM_RATE_CONTINUOUS) + return rates_a; + else if (rates_a & SNDRV_PCM_RATE_KNOT) + return rates_b; + else if (rates_b & SNDRV_PCM_RATE_KNOT) + return rates_a; + return rates_a & rates_b; +} +EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect); diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index b2ebaf811599..76e56b39db01 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -80,8 +80,7 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) * ALSA that we support all rates and let the codec driver decide what rates * are really supported. */ -#define FSLSSI_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ - SNDRV_PCM_RATE_CONTINUOUS) +#define FSLSSI_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS /** * FSLSSI_I2S_FORMATS: audio formats supported by the SSI diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index f4efaadb80a2..5d07e8a74a21 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -26,8 +26,7 @@ * ALSA that we support all rates and let the codec driver decide what rates * are really supported. */ -#define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ - SNDRV_PCM_RATE_CONTINUOUS) +#define PSC_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS /** * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index 73bb99f0109a..7eba7979b9af 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -405,8 +405,7 @@ static int s6000_i2s_dai_probe(struct snd_soc_dai *dai) return 0; } -#define S6000_I2S_RATES (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \ - SNDRV_PCM_RATE_8000_192000) +#define S6000_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS #define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) static const struct snd_soc_dai_ops s6000_i2s_dai_ops = { diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index e95ef9586723..5932971cf54d 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -240,14 +240,15 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_runtime *runtime, cpu_stream->channels_min); hw->channels_max = min(codec_stream->channels_max, cpu_stream->channels_max); - hw->formats = codec_stream->formats & cpu_stream->formats; - hw->rates = codec_stream->rates & cpu_stream->rates; - if (codec_stream->rates - & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) - hw->rates |= cpu_stream->rates; - if (cpu_stream->rates - & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) - hw->rates |= codec_stream->rates; + if (hw->formats) + hw->formats &= codec_stream->formats & cpu_stream->formats; + else + hw->formats = codec_stream->formats & cpu_stream->formats; + hw->rates = snd_pcm_rate_mask_intersect(codec_stream->rates, + cpu_stream->rates); + + hw->rate_min = 0; + hw->rate_max = UINT_MAX; snd_pcm_limit_hw_rates(runtime); @@ -2140,10 +2141,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) int ret = 0, playback = 0, capture = 0; if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { - if (cpu_dai->driver->playback.channels_min) - playback = 1; - if (cpu_dai->driver->capture.channels_min) - capture = 1; + playback = rtd->dai_link->dpcm_playback; + capture = rtd->dai_link->dpcm_capture; } else { if (codec_dai->driver->playback.channels_min && cpu_dai->driver->playback.channels_min) |