[PATCH v3 0/3] ASoC: wm8782: Allow higher audio rates
The wm8782 supports higher audio rates than just 48kHz. This is configured by setting the FSAMPEN pin on the codec chip.
This patch series introduces the 'wlf,fsampen' device tree property to indicate the pin status and control the maximum rate available when using the codec.
v2 -> v3: - Rate is now properly constrained using ALSA constraints
v1 -> v2: - Switched from max-rate property to wlf,fsampen property - Clarified property is optional, not required
John Watts (3): ASoC: wm8782: Constrain maximum audio rate at runtime ASoC: wm8782: Use wlf,fsampen device tree property ASoC: dt-bindings: wlf,wm8782: Add wlf,fsampen property
.../devicetree/bindings/sound/wm8782.txt | 5 ++ sound/soc/codecs/wm8782.c | 63 +++++++++++++++---- 2 files changed, 55 insertions(+), 13 deletions(-)
The wm8782 supports up to 192kHz audio when pins are set correctly. Instead of hardcoding which rates are supported constrain them at runtime based on a max_rate variable.
Signed-off-by: John Watts contact@jookia.org --- sound/soc/codecs/wm8782.c | 42 ++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-)
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index 95ff4339d103..f3dc87b92b1e 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -23,6 +23,27 @@ #include <sound/initval.h> #include <sound/soc.h>
+/* regulator power supply names */ +static const char *supply_names[] = { + "Vdda", /* analog supply, 2.7V - 3.6V */ + "Vdd", /* digital supply, 2.7V - 5.5V */ +}; + +struct wm8782_priv { + struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; + int max_rate; +}; + +static int wm8782_dai_startup(struct snd_pcm_substream *sub, struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime = sub->runtime; + struct wm8782_priv *priv = + snd_soc_component_get_drvdata(dai->component); + + return snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, + 8000, priv->max_rate); +} + static const struct snd_soc_dapm_widget wm8782_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AINL"), SND_SOC_DAPM_INPUT("AINR"), @@ -33,28 +54,22 @@ static const struct snd_soc_dapm_route wm8782_dapm_routes[] = { { "Capture", NULL, "AINR" }, };
+static const struct snd_soc_dai_ops wm8782_dai_ops = { + .startup = &wm8782_dai_startup, +}; + static struct snd_soc_dai_driver wm8782_dai = { .name = "wm8782", .capture = { .stream_name = "Capture", .channels_min = 2, .channels_max = 2, - /* For configurations with FSAMPEN=0 */ - .rates = SNDRV_PCM_RATE_8000_48000, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, }, -}; - -/* regulator power supply names */ -static const char *supply_names[] = { - "Vdda", /* analog supply, 2.7V - 3.6V */ - "Vdd", /* digital supply, 2.7V - 5.5V */ -}; - -struct wm8782_priv { - struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; + .ops = &wm8782_dai_ops, };
static int wm8782_soc_probe(struct snd_soc_component *component) @@ -121,6 +136,9 @@ static int wm8782_probe(struct platform_device *pdev) if (ret < 0) return ret;
+ /* For configurations with FSAMPEN=0 */ + priv->max_rate = 48000; + return devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wm8782, &wm8782_dai, 1); }
On Mon, Sep 18, 2023 at 03:37:24AM +1000, John Watts wrote:
The wm8782 supports up to 192kHz audio when pins are set correctly. Instead of hardcoding which rates are supported constrain them at runtime based on a max_rate variable.
Signed-off-by: John Watts contact@jookia.org
Acked-by: Charles Keepax ckeepax@opensource.cirrus.com
Thanks, Charles
The wm8782 supports rates 96kHz and 192kHz as long as the hardware is configured properly. Allow this to be specified in the device tree.
Signed-off-by: John Watts contact@jookia.org --- sound/soc/codecs/wm8782.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index f3dc87b92b1e..3a2acdfa9b85 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -119,8 +119,9 @@ static const struct snd_soc_component_driver soc_component_dev_wm8782 = { static int wm8782_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct wm8782_priv *priv; - int ret, i; + int ret, i, fsampen;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -136,8 +137,26 @@ static int wm8782_probe(struct platform_device *pdev) if (ret < 0) return ret;
- /* For configurations with FSAMPEN=0 */ - priv->max_rate = 48000; + // Assume lowest value by default to avoid inadvertent overclocking + fsampen = 0; + + if (np) + of_property_read_u32(np, "wlf,fsampen", &fsampen); + + switch (fsampen) { + case 0: + priv->max_rate = 48000; + break; + case 1: + priv->max_rate = 96000; + break; + case 2: + priv->max_rate = 192000; + break; + default: + dev_err(dev, "Invalid wlf,fsampen value"); + return -EINVAL; + }
return devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wm8782, &wm8782_dai, 1);
On Mon, Sep 18, 2023 at 03:37:25AM +1000, John Watts wrote:
The wm8782 supports rates 96kHz and 192kHz as long as the hardware is configured properly. Allow this to be specified in the device tree.
Signed-off-by: John Watts contact@jookia.org
Acked-by: Charles Keepax ckeepax@opensource.cirrus.com
Thanks, Charles
The WM8782 can safely support rates higher than 48kHz by changing the value of the FSAMPEN pin.
Allow specifying the FSAMPEN pin value in the device tree.
Signed-off-by: John Watts contact@jookia.org --- Documentation/devicetree/bindings/sound/wm8782.txt | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/wm8782.txt b/Documentation/devicetree/bindings/sound/wm8782.txt index 256cdec6ec4d..d217a616e103 100644 --- a/Documentation/devicetree/bindings/sound/wm8782.txt +++ b/Documentation/devicetree/bindings/sound/wm8782.txt @@ -8,10 +8,15 @@ Required properties: - Vdda-supply : phandle to a regulator for the analog power supply (2.7V - 5.5V) - Vdd-supply : phandle to a regulator for the digital power supply (2.7V - 3.6V)
+Optional properties: + + - wlf,fsampen : FSAMPEN pin value, 0 for low, 1 for high, 2 for disconnected + Example:
wm8782: stereo-adc { compatible = "wlf,wm8782"; Vdda-supply = <&vdda_supply>; Vdd-supply = <&vdd_supply>; + wlf,fsampen = <2>; /* 192KHz */ };
On Mon, Sep 18, 2023 at 03:37:26AM +1000, John Watts wrote:
+Optional properties:
- wlf,fsampen : FSAMPEN pin value, 0 for low, 1 for high, 2 for disconnected
Uh-oh, I forgot to specify what it defaults to. Should I reply to this patch with a fix or re-send the entire series after I get feedback?
John.
On Mon, Sep 18, 2023 at 03:46:06AM +1000, John Watts wrote:
On Mon, Sep 18, 2023 at 03:37:26AM +1000, John Watts wrote:
+Optional properties:
- wlf,fsampen : FSAMPEN pin value, 0 for low, 1 for high, 2 for disconnected
Uh-oh, I forgot to specify what it defaults to. Should I reply to this patch with a fix or re-send the entire series after I get feedback?
I would probably send a new spin with the fix and my acks.
Acked-by: Charles Keepax ckeepax@opensource.cirrus.com
Thanks, Charles
participants (2)
-
Charles Keepax
-
John Watts