2022-08-19 13:35:52

by Richard Fitzgerald

[permalink] [raw]
Subject: [PATCH 00/12] ASoC: cs42l42: Add Soundwire support

The CS42L42 has a Soundwire interface for control and audio. This
chain of patches adds support for this.

Patches #1 .. #10 split out various changes to the existing code that
are needed for adding Soundwire. These are mostly around clocking and
supporting the separate probe and enumeration stages in Soundwire.

Patches #11 and #12 actually add the Soundwire handling.

Richard Fitzgerald (12):
ASoC: cs42l42: Add SOFT_RESET_REBOOT register
ASoC: cs42l42: Add bitclock frequency argument to cs42l42_pll_config()
ASoC: cs42l42: Ensure MCLKint is a multiple of the sample rate
ASoC: cs42l42: Separate ASP config from PLL config
ASoC: cs42l42: Use cs42l42->dev instead of &i2c_client->dev
ASoC: cs42l42: Split probe() and remove() into stages
ASoC: cs42l42: Split cs42l42_resume into two functions
ASoC: cs42l42: Pass component and dai defs into common probe
ASoC: cs42l42: Split I2C identity into separate module
ASoC: cs42l42: Export some functions for Soundwire
ASoC: cs42l42: Add Soundwire support
ASoC: cs42l42: Add support for Soundwire interrupts

include/sound/cs42l42.h | 5 +
sound/soc/codecs/Kconfig | 14 +-
sound/soc/codecs/Makefile | 6 +-
sound/soc/codecs/cs42l42-i2c.c | 107 +++++
sound/soc/codecs/cs42l42-sdw.c | 689 +++++++++++++++++++++++++++++++++
sound/soc/codecs/cs42l42.c | 359 +++++++++--------
sound/soc/codecs/cs42l42.h | 30 +-
7 files changed, 1049 insertions(+), 161 deletions(-)
create mode 100644 sound/soc/codecs/cs42l42-i2c.c
create mode 100644 sound/soc/codecs/cs42l42-sdw.c

--
2.30.2


2022-08-19 13:37:02

by Richard Fitzgerald

[permalink] [raw]
Subject: [PATCH 02/12] ASoC: cs42l42: Add bitclock frequency argument to cs42l42_pll_config()

Clean up the handling of bitclock frequency by keeping all the logic
in cs42l42_pcm_hw_params(), which then simply passes the frequency as
an argument to cs42l42_pll_config().

The previous code had become clunky as a legacy of earlier versions of
the clock handling. The logic was split across cs42l42_pcm_hw_params()
and cs42l42_pll_config(), with the params-derived bclk stashed in
struct cs42l42_private only to pass it to cs42l42_pll_config().

Signed-off-by: Richard Fitzgerald <[email protected]>
---
sound/soc/codecs/cs42l42.c | 32 ++++++++++++++++----------------
sound/soc/codecs/cs42l42.h | 1 -
2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index 440d414efe0a..1745b83310ac 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -649,18 +649,12 @@ static const struct cs42l42_pll_params pll_ratio_table[] = {
{ 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1}
};

-static int cs42l42_pll_config(struct snd_soc_component *component)
+static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk)
{
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
int i;
- u32 clk;
u32 fsync;

- if (!cs42l42->sclk)
- clk = cs42l42->bclk;
- else
- clk = cs42l42->sclk;
-
/* Don't reconfigure if there is an audio stream running */
if (cs42l42->stream_use) {
if (pll_ratio_table[cs42l42->pll_config].sclk == clk)
@@ -897,19 +891,25 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
unsigned int width = (params_width(params) / 8) - 1;
unsigned int slot_width = 0;
unsigned int val = 0;
+ unsigned int bclk;
int ret;

cs42l42->srate = params_rate(params);

- /*
- * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being
- * more than assumed (which would result in overclocking).
- */
- if (params_width(params) == 24)
- slot_width = 32;
+ if (cs42l42->sclk) {
+ /* machine driver has set the SCLK */
+ bclk = cs42l42->sclk;
+ } else {
+ /*
+ * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being
+ * more than assumed (which would result in overclocking).
+ */
+ if (params_width(params) == 24)
+ slot_width = 32;

- /* I2S frame always has multiple of 2 channels */
- cs42l42->bclk = snd_soc_tdm_params_to_bclk(params, slot_width, 0, 2);
+ /* I2S frame always has multiple of 2 channels */
+ bclk = snd_soc_tdm_params_to_bclk(params, slot_width, 0, 2);
+ }

switch (substream->stream) {
case SNDRV_PCM_STREAM_CAPTURE:
@@ -949,7 +949,7 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
break;
}

- ret = cs42l42_pll_config(component);
+ ret = cs42l42_pll_config(component, bclk);
if (ret)
return ret;

diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h
index 50299c9f283a..b4ba1467c558 100644
--- a/sound/soc/codecs/cs42l42.h
+++ b/sound/soc/codecs/cs42l42.h
@@ -30,7 +30,6 @@ struct cs42l42_private {
struct snd_soc_jack *jack;
struct mutex irq_lock;
int pll_config;
- int bclk;
u32 sclk;
u32 srate;
u8 plug_state;
--
2.30.2

2022-08-19 13:39:11

by Richard Fitzgerald

[permalink] [raw]
Subject: [PATCH 03/12] ASoC: cs42l42: Ensure MCLKint is a multiple of the sample rate

The chosen clocking configuration must give an internal MCLK (MCLKint)
that is an integer multiple of the sample rate.

On I2S each of the supported bit clock frequencies can only be generated
from one sample rate group (either the 44100 or the 48000) so the code
could use only the bitclock to look up a PLL config.

The relationship between sample rate and bitclock frequency is more
complex on Soundwire and so it is possible to set a frame shape to
generate a bitclock from the "wrong" group. For example 2*147 with a
48000 sample rate would give a bitclock of 14112000 which on I2S
could only be derived from a 44100 sample rate.

Signed-off-by: Richard Fitzgerald <[email protected]>
---
sound/soc/codecs/cs42l42.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index 1745b83310ac..66c10d24169d 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -649,7 +649,8 @@ static const struct cs42l42_pll_params pll_ratio_table[] = {
{ 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1}
};

-static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk)
+static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk,
+ unsigned int sample_rate)
{
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
int i;
@@ -664,6 +665,10 @@ static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int
}

for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
+ /* MCLKint must be a multiple of the sample rate */
+ if (pll_ratio_table[i].mclk_int % sample_rate)
+ continue;
+
if (pll_ratio_table[i].sclk == clk) {
cs42l42->pll_config = i;

@@ -889,6 +894,7 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
unsigned int channels = params_channels(params);
unsigned int width = (params_width(params) / 8) - 1;
+ unsigned int sample_rate = params_rate(params);
unsigned int slot_width = 0;
unsigned int val = 0;
unsigned int bclk;
@@ -949,11 +955,11 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
break;
}

- ret = cs42l42_pll_config(component, bclk);
+ ret = cs42l42_pll_config(component, bclk, sample_rate);
if (ret)
return ret;

- cs42l42_src_config(component, params_rate(params));
+ cs42l42_src_config(component, sample_rate);

return 0;
}
--
2.30.2

2022-09-23 17:12:45

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH 00/12] ASoC: cs42l42: Add Soundwire support

On Fri, 19 Aug 2022 13:52:18 +0100, Richard Fitzgerald wrote:
> The CS42L42 has a Soundwire interface for control and audio. This
> chain of patches adds support for this.
>
> Patches #1 .. #10 split out various changes to the existing code that
> are needed for adding Soundwire. These are mostly around clocking and
> supporting the separate probe and enumeration stages in Soundwire.
>
> [...]

Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[01/12] ASoC: cs42l42: Add SOFT_RESET_REBOOT register
(no commit info)
[02/12] ASoC: cs42l42: Add bitclock frequency argument to cs42l42_pll_config()
commit: 7e178946c3e4e64cebda4e60d0b7e5c02a502d13
[03/12] ASoC: cs42l42: Ensure MCLKint is a multiple of the sample rate
(no commit info)
[04/12] ASoC: cs42l42: Separate ASP config from PLL config
(no commit info)
[05/12] ASoC: cs42l42: Use cs42l42->dev instead of &i2c_client->dev
commit: 2feab7e7d8c01b67d9ffbfb902d1591c08e9d564
[06/12] ASoC: cs42l42: Split probe() and remove() into stages
commit: 0285042feda799edca63b35cea0cda32ed0c47c2
[07/12] ASoC: cs42l42: Split cs42l42_resume into two functions
commit: 56746683c2560ba5604bb212f73eb01f5edfd312
[08/12] ASoC: cs42l42: Pass component and dai defs into common probe
commit: 52c2e370df07092437d1515e773d28a5f53fc810
[09/12] ASoC: cs42l42: Split I2C identity into separate module
commit: ae9f5e607da47104bc3d02e5c0ed237749f5db51
[10/12] ASoC: cs42l42: Export some functions for Soundwire
(no commit info)
[11/12] ASoC: cs42l42: Add Soundwire support
(no commit info)
[12/12] ASoC: cs42l42: Add support for Soundwire interrupts
(no commit info)

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark