Skip to content

Commit 9a26234

Browse files
committed
ALSA: pcm: Fix breakage of PCM rates used for topology
It turned out that the topology ABI takes the standard PCM rate bits as is, and it means that the recent change of the PCM rate bits would lead to the inconsistent rate values used for topology. This patch reverts the original PCM rate bit definitions while adding the new rates to the extended bits instead. This needed the change of snd_pcm_known_rates, too. And this also required to fix the handling in snd_pcm_hw_limit_rates() that blindly assumed that the list is sorted while it became unsorted now. Fixes: 090624b ("ALSA: pcm: add more sample rate definitions") Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Closes: https://lore.kernel.org/1ab3efaa-863c-4dd0-8f81-b50fd9775fad@linux.intel.com Reviewed-by: Jaroslav Kysela <perex@perex.cz> Tested-by: Jerome Brunet <jbrunet@baylibre.com> Tested-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://patch.msgid.link/20240911135756.24434-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 9408ace commit 9a26234

3 files changed

Lines changed: 35 additions & 28 deletions

File tree

include/sound/pcm.h

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,23 +109,24 @@ struct snd_pcm_ops {
109109
#define SNDRV_PCM_RATE_5512 (1U<<0) /* 5512Hz */
110110
#define SNDRV_PCM_RATE_8000 (1U<<1) /* 8000Hz */
111111
#define SNDRV_PCM_RATE_11025 (1U<<2) /* 11025Hz */
112-
#define SNDRV_PCM_RATE_12000 (1U<<3) /* 12000Hz */
113-
#define SNDRV_PCM_RATE_16000 (1U<<4) /* 16000Hz */
114-
#define SNDRV_PCM_RATE_22050 (1U<<5) /* 22050Hz */
115-
#define SNDRV_PCM_RATE_24000 (1U<<6) /* 24000Hz */
116-
#define SNDRV_PCM_RATE_32000 (1U<<7) /* 32000Hz */
117-
#define SNDRV_PCM_RATE_44100 (1U<<8) /* 44100Hz */
118-
#define SNDRV_PCM_RATE_48000 (1U<<9) /* 48000Hz */
119-
#define SNDRV_PCM_RATE_64000 (1U<<10) /* 64000Hz */
120-
#define SNDRV_PCM_RATE_88200 (1U<<11) /* 88200Hz */
121-
#define SNDRV_PCM_RATE_96000 (1U<<12) /* 96000Hz */
122-
#define SNDRV_PCM_RATE_128000 (1U<<13) /* 128000Hz */
123-
#define SNDRV_PCM_RATE_176400 (1U<<14) /* 176400Hz */
124-
#define SNDRV_PCM_RATE_192000 (1U<<15) /* 192000Hz */
125-
#define SNDRV_PCM_RATE_352800 (1U<<16) /* 352800Hz */
126-
#define SNDRV_PCM_RATE_384000 (1U<<17) /* 384000Hz */
127-
#define SNDRV_PCM_RATE_705600 (1U<<18) /* 705600Hz */
128-
#define SNDRV_PCM_RATE_768000 (1U<<19) /* 768000Hz */
112+
#define SNDRV_PCM_RATE_16000 (1U<<3) /* 16000Hz */
113+
#define SNDRV_PCM_RATE_22050 (1U<<4) /* 22050Hz */
114+
#define SNDRV_PCM_RATE_32000 (1U<<5) /* 32000Hz */
115+
#define SNDRV_PCM_RATE_44100 (1U<<6) /* 44100Hz */
116+
#define SNDRV_PCM_RATE_48000 (1U<<7) /* 48000Hz */
117+
#define SNDRV_PCM_RATE_64000 (1U<<8) /* 64000Hz */
118+
#define SNDRV_PCM_RATE_88200 (1U<<9) /* 88200Hz */
119+
#define SNDRV_PCM_RATE_96000 (1U<<10) /* 96000Hz */
120+
#define SNDRV_PCM_RATE_176400 (1U<<11) /* 176400Hz */
121+
#define SNDRV_PCM_RATE_192000 (1U<<12) /* 192000Hz */
122+
#define SNDRV_PCM_RATE_352800 (1U<<13) /* 352800Hz */
123+
#define SNDRV_PCM_RATE_384000 (1U<<14) /* 384000Hz */
124+
#define SNDRV_PCM_RATE_705600 (1U<<15) /* 705600Hz */
125+
#define SNDRV_PCM_RATE_768000 (1U<<16) /* 768000Hz */
126+
/* extended rates since 6.12 */
127+
#define SNDRV_PCM_RATE_12000 (1U<<17) /* 12000Hz */
128+
#define SNDRV_PCM_RATE_24000 (1U<<18) /* 24000Hz */
129+
#define SNDRV_PCM_RATE_128000 (1U<<19) /* 128000Hz */
129130

130131
#define SNDRV_PCM_RATE_CONTINUOUS (1U<<30) /* continuous range */
131132
#define SNDRV_PCM_RATE_KNOT (1U<<31) /* supports more non-continuous rates */

sound/core/pcm_misc.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -494,18 +494,20 @@ EXPORT_SYMBOL(snd_pcm_format_set_silence);
494494
int snd_pcm_hw_limit_rates(struct snd_pcm_hardware *hw)
495495
{
496496
int i;
497+
unsigned int rmin, rmax;
498+
499+
rmin = UINT_MAX;
500+
rmax = 0;
497501
for (i = 0; i < (int)snd_pcm_known_rates.count; i++) {
498502
if (hw->rates & (1 << i)) {
499-
hw->rate_min = snd_pcm_known_rates.list[i];
500-
break;
501-
}
502-
}
503-
for (i = (int)snd_pcm_known_rates.count - 1; i >= 0; i--) {
504-
if (hw->rates & (1 << i)) {
505-
hw->rate_max = snd_pcm_known_rates.list[i];
506-
break;
503+
rmin = min(rmin, snd_pcm_known_rates.list[i]);
504+
rmax = max(rmax, snd_pcm_known_rates.list[i]);
507505
}
508506
}
507+
if (rmin > rmax)
508+
return -EINVAL;
509+
hw->rate_min = rmin;
510+
hw->rate_max = rmax;
509511
return 0;
510512
}
511513
EXPORT_SYMBOL(snd_pcm_hw_limit_rates);

sound/core/pcm_native.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,13 +2418,17 @@ static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params,
24182418
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
24192419
}
24202420

2421-
#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_768000 != 1 << 19
2421+
#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12 ||\
2422+
SNDRV_PCM_RATE_128000 != 1 << 19
24222423
#error "Change this table"
24232424
#endif
24242425

2426+
/* NOTE: the list is unsorted! */
24252427
static const unsigned int rates[] = {
2426-
5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000,
2427-
88200, 96000, 128000, 176400, 192000, 352800, 384000, 705600, 768000,
2428+
5512, 8000, 11025, 16000, 22050, 32000, 44100,
2429+
48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000,
2430+
/* extended */
2431+
12000, 24000, 128000
24282432
};
24292433

24302434
const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = {

0 commit comments

Comments
 (0)