]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
ASoC: arizona: Allow number of channels clocked to be restricted
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Thu, 17 Jan 2013 07:35:14 +0000 (16:35 +0900)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 21 Jan 2013 08:47:39 +0000 (17:47 +0900)
Place a cap on the number of channels clocks are generated for. This is
intended for use with systems which have the WM5102 master an I2S bus with
multiple data lines.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
include/linux/mfd/arizona/pdata.h
sound/soc/codecs/arizona.c

index 8b1d1daaae16c27e59d037f46899a1f6c631acc4..ec3e2a2a6d77a9a16c8916f63783dc2e0822036e 100644 (file)
@@ -62,6 +62,8 @@
 
 #define ARIZONA_MAX_OUTPUT 6
 
+#define ARIZONA_MAX_AIF 3
+
 #define ARIZONA_HAP_ACT_ERM 0
 #define ARIZONA_HAP_ACT_LRA 2
 
@@ -96,6 +98,13 @@ struct arizona_pdata {
        /** Pin state for GPIO pins */
        int gpio_defaults[ARIZONA_MAX_GPIO];
 
+       /**
+        * Maximum number of channels clocks will be generated for,
+        * useful for systems where and I2S bus with multiple data
+        * lines is mastered.
+        */
+       int max_channels_clocked[ARIZONA_MAX_AIF];
+
        /** GPIO for mic detection polarity */
        int micd_pol_gpio;
 
index 845d25630ba2f1e54add550ec2982fe90aab2880..d855a6c098d478b5bad650359e9691c5c5d81a6e 100644 (file)
@@ -762,18 +762,28 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
                             struct snd_soc_dai *dai)
 {
        struct snd_soc_codec *codec = dai->codec;
+       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       struct arizona *arizona = priv->arizona;
        int base = dai->driver->base;
        const int *rates;
        int i, ret;
-       int bclk, lrclk, wl, frame;
+       int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1];
+       int bclk, lrclk, wl, frame, bclk_target;
 
        if (params_rate(params) % 8000)
                rates = &arizona_44k1_bclk_rates[0];
        else
                rates = &arizona_48k_bclk_rates[0];
 
+       bclk_target = snd_soc_params_to_bclk(params);
+       if (chan_limit && chan_limit < params_channels(params)) {
+               arizona_aif_dbg(dai, "Limiting to %d channels\n", chan_limit);
+               bclk_target /= params_channels(params);
+               bclk_target *= chan_limit;
+       }
+
        for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
-               if (rates[i] >= snd_soc_params_to_bclk(params) &&
+               if (rates[i] >= bclk_target &&
                    rates[i] % params_rate(params) == 0) {
                        bclk = i;
                        break;