From: James Calligeros Date: Sat, 14 Mar 2026 00:27:11 +0000 (+1000) Subject: ASoC: codecs: cs42l84: set up PLL for more sample rates X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4ebaf9d999327ce8e2ea5847ac96fe53fde3fe9a;p=thirdparty%2Flinux.git ASoC: codecs: cs42l84: set up PLL for more sample rates Previously, this driver only advertised support for 48 kHz and 96 kHz sample rates, as there was no PLL configuration data specified for any other sample rate/BCLK. The CS42L84 is an Apple-specific variant of CS42L42. The PLL configuration parameters for a variety of common BCLKs are available in the latter's datasheet. What happens if we just use those? As it turns out, they work just fine. Fill out more PLL config parameters in the PLL config lookup table, and advertise the corresponding sample rates to userspace. This enables 44.1, 88.2, 176.4 and 192 kHz output and input. Signed-off-by: James Calligeros Link: https://patch.msgid.link/20260314-cs42l84-rates-v2-1-ea8a5af52542@gmail.com Signed-off-by: Mark Brown --- diff --git a/sound/soc/codecs/cs42l84.c b/sound/soc/codecs/cs42l84.c index 1e1307a16f815..e590a43559e4e 100644 --- a/sound/soc/codecs/cs42l84.c +++ b/sound/soc/codecs/cs42l84.c @@ -357,8 +357,11 @@ struct cs42l84_pll_params { * Common PLL Settings for given BCLK */ static const struct cs42l84_pll_params pll_ratio_table[] = { + { 2822400, 1, 0, 0x40, 0x000000, 0x03, 0x10, 11289600}, { 3072000, 1, 0, 0x40, 0x000000, 0x03, 0x10, 12288000}, + { 5644800, 1, 0, 0x40, 0x000000, 0x03, 0x10, 11289600}, { 6144000, 1, 1, 0x40, 0x000000, 0x03, 0x10, 12288000}, + { 11289600, 0, 0, 0, 0, 0, 0, 11289600}, { 12288000, 0, 0, 0, 0, 0, 0, 12288000}, { 24576000, 1, 3, 0x40, 0x000000, 0x03, 0x10, 12288000}, }; @@ -408,11 +411,18 @@ static int cs42l84_pll_config(struct snd_soc_component *component) CS42L84_ASP_FSYNC_CTL3_BCLK_PERIOD_HI, FIELD_PREP(CS42L84_ASP_FSYNC_CTL3_BCLK_PERIOD_HI, fsync >> 7)); - /* Save what the MCLK will be */ + /* + * MCLK values are binned into 12 or 24 MHz regions. If MCLK is exactly + * 12 or 24 MHz, the high bit of CCM_CTL1_MCLK_F is set. If MCLK + * is in the region of 24 MHz, the low bit is set. This seemingly + * corresponds to CS42L42's documented INTERNAL_FS and MCLKDIV + * behaviour respectively. + */ switch (pll_ratio_table[i].mclk_int) { case 12000000: cs42l84->pll_mclk_f = CS42L84_CCM_CTL1_MCLK_F_12MHZ; break; + case 11289600: case 12288000: cs42l84->pll_mclk_f = CS42L84_CCM_CTL1_MCLK_F_12_288KHZ; break; @@ -670,14 +680,18 @@ static struct snd_soc_dai_driver cs42l84_dai = { .stream_name = "Playback", .channels_min = 1, .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, .formats = CS42L84_FORMATS, }, .capture = { .stream_name = "Capture", .channels_min = 1, .channels_max = 1, - .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000, + .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, .formats = CS42L84_FORMATS, }, .symmetric_rate = 1,