]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: pcm: Fix breakage of PCM rates used for topology
authorTakashi Iwai <tiwai@suse.de>
Wed, 11 Sep 2024 13:57:52 +0000 (15:57 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 11 Sep 2024 14:17:44 +0000 (16:17 +0200)
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: 090624b7dc83 ("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>
include/sound/pcm.h
sound/core/pcm_misc.c
sound/core/pcm_native.c

index c993350975a9532eac05f402ec1fa597bbf5031b..0bf7d25434d7f8286ca8415f7e4faf48aec48cbc 100644 (file)
@@ -109,23 +109,24 @@ struct snd_pcm_ops {
 #define SNDRV_PCM_RATE_5512            (1U<<0)         /* 5512Hz */
 #define SNDRV_PCM_RATE_8000            (1U<<1)         /* 8000Hz */
 #define SNDRV_PCM_RATE_11025           (1U<<2)         /* 11025Hz */
-#define SNDRV_PCM_RATE_12000           (1U<<3)         /* 12000Hz */
-#define SNDRV_PCM_RATE_16000           (1U<<4)         /* 16000Hz */
-#define SNDRV_PCM_RATE_22050           (1U<<5)         /* 22050Hz */
-#define SNDRV_PCM_RATE_24000           (1U<<6)         /* 24000Hz */
-#define SNDRV_PCM_RATE_32000           (1U<<7)         /* 32000Hz */
-#define SNDRV_PCM_RATE_44100           (1U<<8)         /* 44100Hz */
-#define SNDRV_PCM_RATE_48000           (1U<<9)         /* 48000Hz */
-#define SNDRV_PCM_RATE_64000           (1U<<10)        /* 64000Hz */
-#define SNDRV_PCM_RATE_88200           (1U<<11)        /* 88200Hz */
-#define SNDRV_PCM_RATE_96000           (1U<<12)        /* 96000Hz */
-#define SNDRV_PCM_RATE_128000          (1U<<13)        /* 128000Hz */
-#define SNDRV_PCM_RATE_176400          (1U<<14)        /* 176400Hz */
-#define SNDRV_PCM_RATE_192000          (1U<<15)        /* 192000Hz */
-#define SNDRV_PCM_RATE_352800          (1U<<16)        /* 352800Hz */
-#define SNDRV_PCM_RATE_384000          (1U<<17)        /* 384000Hz */
-#define SNDRV_PCM_RATE_705600          (1U<<18)        /* 705600Hz */
-#define SNDRV_PCM_RATE_768000          (1U<<19)        /* 768000Hz */
+#define SNDRV_PCM_RATE_16000           (1U<<3)         /* 16000Hz */
+#define SNDRV_PCM_RATE_22050           (1U<<4)         /* 22050Hz */
+#define SNDRV_PCM_RATE_32000           (1U<<5)         /* 32000Hz */
+#define SNDRV_PCM_RATE_44100           (1U<<6)         /* 44100Hz */
+#define SNDRV_PCM_RATE_48000           (1U<<7)         /* 48000Hz */
+#define SNDRV_PCM_RATE_64000           (1U<<8)         /* 64000Hz */
+#define SNDRV_PCM_RATE_88200           (1U<<9)         /* 88200Hz */
+#define SNDRV_PCM_RATE_96000           (1U<<10)        /* 96000Hz */
+#define SNDRV_PCM_RATE_176400          (1U<<11)        /* 176400Hz */
+#define SNDRV_PCM_RATE_192000          (1U<<12)        /* 192000Hz */
+#define SNDRV_PCM_RATE_352800          (1U<<13)        /* 352800Hz */
+#define SNDRV_PCM_RATE_384000          (1U<<14)        /* 384000Hz */
+#define SNDRV_PCM_RATE_705600          (1U<<15)        /* 705600Hz */
+#define SNDRV_PCM_RATE_768000          (1U<<16)        /* 768000Hz */
+/* extended rates since 6.12 */
+#define SNDRV_PCM_RATE_12000           (1U<<17)        /* 12000Hz */
+#define SNDRV_PCM_RATE_24000           (1U<<18)        /* 24000Hz */
+#define SNDRV_PCM_RATE_128000          (1U<<19)        /* 128000Hz */
 
 #define SNDRV_PCM_RATE_CONTINUOUS      (1U<<30)        /* continuous range */
 #define SNDRV_PCM_RATE_KNOT            (1U<<31)        /* supports more non-continuous rates */
index 5588b6a1ee8bd0c7fe57388c755899066b312943..4f556211bb56d3ade58e676c3d8655c69bd7a39e 100644 (file)
@@ -494,18 +494,20 @@ EXPORT_SYMBOL(snd_pcm_format_set_silence);
 int snd_pcm_hw_limit_rates(struct snd_pcm_hardware *hw)
 {
        int i;
+       unsigned int rmin, rmax;
+
+       rmin = UINT_MAX;
+       rmax = 0;
        for (i = 0; i < (int)snd_pcm_known_rates.count; i++) {
                if (hw->rates & (1 << i)) {
-                       hw->rate_min = snd_pcm_known_rates.list[i];
-                       break;
-               }
-       }
-       for (i = (int)snd_pcm_known_rates.count - 1; i >= 0; i--) {
-               if (hw->rates & (1 << i)) {
-                       hw->rate_max = snd_pcm_known_rates.list[i];
-                       break;
+                       rmin = min(rmin, snd_pcm_known_rates.list[i]);
+                       rmax = max(rmax, snd_pcm_known_rates.list[i]);
                }
        }
+       if (rmin > rmax)
+               return -EINVAL;
+       hw->rate_min = rmin;
+       hw->rate_max = rmax;
        return 0;
 }
 EXPORT_SYMBOL(snd_pcm_hw_limit_rates);
index 7461a727615c29bbae8cd0ddf1dbef9ab4477b69..5e1e6006707b46e3896f90de192a3584ee6e06cc 100644 (file)
@@ -2418,13 +2418,17 @@ static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params,
        return snd_interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
-#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_768000 != 1 << 19
+#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12 ||\
+       SNDRV_PCM_RATE_128000 != 1 << 19
 #error "Change this table"
 #endif
 
+/* NOTE: the list is unsorted! */
 static const unsigned int rates[] = {
-       5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000,
-       88200, 96000, 128000, 176400, 192000, 352800, 384000, 705600, 768000,
+       5512, 8000, 11025, 16000, 22050, 32000, 44100,
+       48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000,
+       /* extended */
+       12000, 24000, 128000
 };
 
 const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = {