[PATCH 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 'max-rate' device tree property to allow indicating which rates are fully supported by the codec without accidentally overclocking.
John Watts (3): ASoC: wm8782: Handle maximum audio rate at runtime ASoC: wm8782: Use max-rate device tree property ASoC: dt-bindings: wlf,wm8782: Add max-rate property
.../devicetree/bindings/sound/wm8782.txt | 2 + sound/soc/codecs/wm8782.c | 49 ++++++++++++++----- 2 files changed, 39 insertions(+), 12 deletions(-)
The wm8782 supports up to 192kHz audio when pins are set correctly. Instead of hardcoding which rates are supported enable them all then refer to a max_rate variable at runtime.
Signed-off-by: John Watts contact@jookia.org --- sound/soc/codecs/wm8782.c | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-)
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index 95ff4339d103..63ab63f3189a 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -23,6 +23,30 @@ #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_hw_params(struct snd_pcm_substream *component, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct wm8782_priv *priv = + snd_soc_component_get_drvdata(dai->component); + + if (params_rate(params) > priv->max_rate) + return -EINVAL; + + return 0; +} + static const struct snd_soc_dapm_widget wm8782_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AINL"), SND_SOC_DAPM_INPUT("AINR"), @@ -33,28 +57,22 @@ static const struct snd_soc_dapm_route wm8782_dapm_routes[] = { { "Capture", NULL, "AINR" }, };
+static const struct snd_soc_dai_ops wm8782_dai_ops = { + .hw_params = &wm8782_dai_hw_params, +}; + 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 +139,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); }
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 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index 63ab63f3189a..6a2f29ee897c 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -122,6 +122,7 @@ 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;
@@ -139,9 +140,12 @@ static int wm8782_probe(struct platform_device *pdev) if (ret < 0) return ret;
- /* For configurations with FSAMPEN=0 */ + /* Assume lowest value by default to avoid inadvertent overclocking */ priv->max_rate = 48000;
+ if (np) + of_property_read_u32(np, "max-rate", &priv->max_rate); + return devm_snd_soc_register_component(&pdev->dev, &soc_component_dev_wm8782, &wm8782_dai, 1); }
The WM8782 can safely support rates higher than 48kHz by changing the value of the FSAMPEN pin.
Allow specifying the maximum support rate the hardware configuration supports in the device tree.
Signed-off-by: John Watts contact@jookia.org --- Documentation/devicetree/bindings/sound/wm8782.txt | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/wm8782.txt b/Documentation/devicetree/bindings/sound/wm8782.txt index 256cdec6ec4d..a68061a3e671 100644 --- a/Documentation/devicetree/bindings/sound/wm8782.txt +++ b/Documentation/devicetree/bindings/sound/wm8782.txt @@ -7,6 +7,7 @@ Required properties: - compatible : "wlf,wm8782" - 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) + - max-rate : max supported audio rate configured by FSAMPEN pin, defaults to 48000
Example:
@@ -14,4 +15,5 @@ wm8782: stereo-adc { compatible = "wlf,wm8782"; Vdda-supply = <&vdda_supply>; Vdd-supply = <&vdd_supply>; + max-rate = <96000>; /* FSAMPEN is 1 */ };
On Fri, Aug 11, 2023 at 08:49:30AM +1000, John Watts wrote:
- max-rate : max supported audio rate configured by FSAMPEN pin, defaults to 48000
This seems like a cumbersome and error prone way to configure this - why not just have the binding specify the state of the pin? That's just a boolean high/low whereas this requires getting the rate right and then having the driver validate it.
On Fri, Aug 11, 2023 at 02:59:35PM +0100, Mark Brown wrote:
On Fri, Aug 11, 2023 at 08:49:30AM +1000, John Watts wrote:
- max-rate : max supported audio rate configured by FSAMPEN pin, defaults to 48000
This seems like a cumbersome and error prone way to configure this - why not just have the binding specify the state of the pin? That's just a boolean high/low whereas this requires getting the rate right and then having the driver validate it.
Hi there, the pin is tristate, Z, 0 and 1. How would that be represented?
John.
On Sat, Aug 12, 2023 at 12:26:15AM +1000, John Watts wrote:
On Fri, Aug 11, 2023 at 02:59:35PM +0100, Mark Brown wrote:
On Fri, Aug 11, 2023 at 08:49:30AM +1000, John Watts wrote:
- max-rate : max supported audio rate configured by FSAMPEN pin, defaults to 48000
This seems like a cumbersome and error prone way to configure this - why not just have the binding specify the state of the pin? That's just a boolean high/low whereas this requires getting the rate right and then having the driver validate it.
Hi there, the pin is tristate, Z, 0 and 1. How would that be represented?
You'd have to define an enum for that but it does still feel like it might be easier to work with since it's more direct.
On Mon, Aug 14, 2023 at 07:27:04PM +0100, Mark Brown wrote:
You'd have to define an enum for that but it does still feel like it might be easier to work with since it's more direct.
Alright, I'll give it a go in the next version. Thanks for the feedback!
John.
On Mon, Aug 14, 2023 at 4:45 PM John Watts contact@jookia.org wrote:
On Mon, Aug 14, 2023 at 07:27:04PM +0100, Mark Brown wrote:
You'd have to define an enum for that but it does still feel like it might be easier to work with since it's more direct.
Alright, I'll give it a go in the next version. Thanks for the feedback!
That property will need a vendor prefix as well which was missing here.
Rob
participants (3)
-
John Watts
-
Mark Brown
-
Rob Herring