ASoC: arizona: Add handling for audio related device tree entries
authorCharles Keepax <ckeepax@opensource.cirrus.com>
Mon, 4 Sep 2017 15:41:49 +0000 (16:41 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 19 Sep 2017 14:57:59 +0000 (15:57 +0100)
Currently all the audio related device tree entries are handled by the
MFD code, for most parts of the Arizona driver we group the device
tree handling with the component that uses it and should do so here as
well.

Add handling in the ASoC code for the audio device tree entries, a
later patch removes the MFD side handling but there is no harm in it
being duplicated temporarily.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/arizona.c
sound/soc/codecs/arizona.h
sound/soc/codecs/cs47l24.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8997.c
sound/soc/codecs/wm8998.c

index ba5f57a5821957a14b77212fc6b5318820881e93..e6967385dccb8264be7968a4dbe10f49f90a3587 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/delay.h>
 #include <linux/gcd.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/pm_runtime.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -295,8 +296,78 @@ EXPORT_SYMBOL_GPL(arizona_init_gpio);
 
 int arizona_init_common(struct arizona *arizona)
 {
+       struct arizona_pdata *pdata = &arizona->pdata;
+       unsigned int val, mask;
+       int i;
+
        BLOCKING_INIT_NOTIFIER_HEAD(&arizona->notifier);
 
+       for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
+               /* Default is 0 so noop with defaults */
+               if (pdata->out_mono[i])
+                       val = ARIZONA_OUT1_MONO;
+               else
+                       val = 0;
+
+               regmap_update_bits(arizona->regmap,
+                                  ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8),
+                                  ARIZONA_OUT1_MONO, val);
+       }
+
+       for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) {
+               if (pdata->spk_mute[i])
+                       regmap_update_bits(arizona->regmap,
+                                          ARIZONA_PDM_SPK1_CTRL_1 + (i * 2),
+                                          ARIZONA_SPK1_MUTE_ENDIAN_MASK |
+                                          ARIZONA_SPK1_MUTE_SEQ1_MASK,
+                                          pdata->spk_mute[i]);
+
+               if (pdata->spk_fmt[i])
+                       regmap_update_bits(arizona->regmap,
+                                          ARIZONA_PDM_SPK1_CTRL_2 + (i * 2),
+                                          ARIZONA_SPK1_FMT_MASK,
+                                          pdata->spk_fmt[i]);
+       }
+
+       for (i = 0; i < ARIZONA_MAX_INPUT; i++) {
+               /* Default for both is 0 so noop with defaults */
+               val = pdata->dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT;
+               if (pdata->inmode[i] & ARIZONA_INMODE_DMIC)
+                       val |= 1 << ARIZONA_IN1_MODE_SHIFT;
+
+               switch (arizona->type) {
+               case WM8998:
+               case WM1814:
+                       regmap_update_bits(arizona->regmap,
+                               ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 8),
+                               ARIZONA_IN1L_SRC_SE_MASK,
+                               (pdata->inmode[i] & ARIZONA_INMODE_SE)
+                                       << ARIZONA_IN1L_SRC_SE_SHIFT);
+
+                       regmap_update_bits(arizona->regmap,
+                               ARIZONA_ADC_DIGITAL_VOLUME_1R + (i * 8),
+                               ARIZONA_IN1R_SRC_SE_MASK,
+                               (pdata->inmode[i] & ARIZONA_INMODE_SE)
+                                       << ARIZONA_IN1R_SRC_SE_SHIFT);
+
+                       mask = ARIZONA_IN1_DMIC_SUP_MASK |
+                              ARIZONA_IN1_MODE_MASK;
+                       break;
+               default:
+                       if (pdata->inmode[i] & ARIZONA_INMODE_SE)
+                               val |= 1 << ARIZONA_IN1_SINGLE_ENDED_SHIFT;
+
+                       mask = ARIZONA_IN1_DMIC_SUP_MASK |
+                              ARIZONA_IN1_MODE_MASK |
+                              ARIZONA_IN1_SINGLE_ENDED_MASK;
+                       break;
+               }
+
+               regmap_update_bits(arizona->regmap,
+                                  ARIZONA_IN1L_CONTROL + (i * 8),
+                                  mask, val);
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(arizona_init_common);
@@ -2692,6 +2763,71 @@ int arizona_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
 }
 EXPORT_SYMBOL_GPL(arizona_lhpf_coeff_put);
 
+int arizona_of_get_audio_pdata(struct arizona *arizona)
+{
+       struct arizona_pdata *pdata = &arizona->pdata;
+       struct device_node *np = arizona->dev->of_node;
+       struct property *prop;
+       const __be32 *cur;
+       u32 val;
+       u32 pdm_val[ARIZONA_MAX_PDM_SPK];
+       int ret;
+       int count = 0;
+
+       count = 0;
+       of_property_for_each_u32(np, "wlf,inmode", prop, cur, val) {
+               if (count == ARRAY_SIZE(pdata->inmode))
+                       break;
+
+               pdata->inmode[count] = val;
+               count++;
+       }
+
+       count = 0;
+       of_property_for_each_u32(np, "wlf,dmic-ref", prop, cur, val) {
+               if (count == ARRAY_SIZE(pdata->dmic_ref))
+                       break;
+
+               pdata->dmic_ref[count] = val;
+               count++;
+       }
+
+       count = 0;
+       of_property_for_each_u32(np, "wlf,out-mono", prop, cur, val) {
+               if (count == ARRAY_SIZE(pdata->out_mono))
+                       break;
+
+               pdata->out_mono[count] = !!val;
+               count++;
+       }
+
+       count = 0;
+       of_property_for_each_u32(np, "wlf,max-channels-clocked", prop, cur, val) {
+               if (count == ARRAY_SIZE(pdata->max_channels_clocked))
+                       break;
+
+               pdata->max_channels_clocked[count] = val;
+               count++;
+       }
+
+       ret = of_property_read_u32_array(np, "wlf,spk-fmt",
+                                        pdm_val, ARRAY_SIZE(pdm_val));
+
+       if (ret >= 0)
+               for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
+                       pdata->spk_fmt[count] = pdm_val[count];
+
+       ret = of_property_read_u32_array(np, "wlf,spk-mute",
+                                        pdm_val, ARRAY_SIZE(pdm_val));
+
+       if (ret >= 0)
+               for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
+                       pdata->spk_mute[count] = pdm_val[count];
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(arizona_of_get_audio_pdata);
+
 MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_LICENSE("GPL");
index 292073ca3bd96b007fbe4806b997429dcb7ef5d8..2d198fb2ce97d3865a0c5bcb79f0cc69ef0f5cca 100644 (file)
@@ -351,4 +351,6 @@ static inline int arizona_unregister_notifier(struct snd_soc_codec *codec,
        return blocking_notifier_chain_unregister(&arizona->notifier, nb);
 }
 
+int arizona_of_get_audio_pdata(struct arizona *arizona);
+
 #endif
index fdcc7318993bd59c20dabe4bb708b5e37e1c3646..0fe7d7a87ff33c550f6593919e74afdf299b2449 100644 (file)
@@ -1229,6 +1229,14 @@ static int cs47l24_probe(struct platform_device *pdev)
        if (!cs47l24)
                return -ENOMEM;
 
+       if (IS_ENABLED(CONFIG_OF)) {
+               if (!dev_get_platdata(arizona->dev)) {
+                       ret = arizona_of_get_audio_pdata(arizona);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
        platform_set_drvdata(pdev, cs47l24);
 
        cs47l24->core.arizona = arizona;
index 8354bdf7fc156c3d59956fee88a70a3a1090dd99..5a917dd73f3298dfefe838d83f1c110cc917855b 100644 (file)
@@ -2042,6 +2042,14 @@ static int wm5102_probe(struct platform_device *pdev)
                return -ENOMEM;
        platform_set_drvdata(pdev, wm5102);
 
+       if (IS_ENABLED(CONFIG_OF)) {
+               if (!dev_get_platdata(arizona->dev)) {
+                       ret = arizona_of_get_audio_pdata(arizona);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
        mutex_init(&arizona->dac_comp_lock);
 
        wm5102->core.arizona = arizona;
index 0437df60be77a7f7667476ec3f638ab5b7a035ec..ba1e90ca8be4696dfe4f8e74361b623d138ebbda 100644 (file)
@@ -2397,6 +2397,14 @@ static int wm5110_probe(struct platform_device *pdev)
                return -ENOMEM;
        platform_set_drvdata(pdev, wm5110);
 
+       if (IS_ENABLED(CONFIG_OF)) {
+               if (!dev_get_platdata(arizona->dev)) {
+                       ret = arizona_of_get_audio_pdata(arizona);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
        wm5110->core.arizona = arizona;
        wm5110->core.num_inputs = 8;
 
index 91c3c3e052d169b3a3c866dabd2dfe17c81bd2e7..c5aef9ecdecc4fa430384142417912fb14a1e31b 100644 (file)
@@ -1134,6 +1134,14 @@ static int wm8997_probe(struct platform_device *pdev)
                return -ENOMEM;
        platform_set_drvdata(pdev, wm8997);
 
+       if (IS_ENABLED(CONFIG_OF)) {
+               if (!dev_get_platdata(arizona->dev)) {
+                       ret = arizona_of_get_audio_pdata(arizona);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
        wm8997->core.arizona = arizona;
        wm8997->core.num_inputs = 4;
 
index 27a8e1e75f2851c9f86bde7e3f2f6913d0b05109..c59caaa75ba0cea21d0f007a544f4b9938592bde 100644 (file)
@@ -1398,6 +1398,14 @@ static int wm8998_probe(struct platform_device *pdev)
                return -ENOMEM;
        platform_set_drvdata(pdev, wm8998);
 
+       if (IS_ENABLED(CONFIG_OF)) {
+               if (!dev_get_platdata(arizona->dev)) {
+                       ret = arizona_of_get_audio_pdata(arizona);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
        wm8998->core.arizona = arizona;
        wm8998->core.num_inputs = 3;    /* IN1L, IN1R, IN2 */