Merge remote-tracking branches 'asoc/topic/max98088', 'asoc/topic/max98090', 'asoc...
authorMark Brown <broonie@kernel.org>
Mon, 8 Dec 2014 13:12:02 +0000 (13:12 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 8 Dec 2014 13:12:02 +0000 (13:12 +0000)
Documentation/devicetree/bindings/sound/max98090.txt
sound/soc/codecs/max98088.c
sound/soc/codecs/max98090.c
sound/soc/codecs/max98090.h
sound/soc/codecs/max98095.c
sound/soc/codecs/max9850.c
sound/soc/generic/simple-card.c
sound/soc/samsung/odroidx2_max98090.c
sound/soc/ux500/mop500.c

index c454e67f54bbc04c04187796b6097aba68bb744d..aa802a274520793a4ae3f46fa3edb8d55be1083c 100644 (file)
@@ -16,6 +16,8 @@ Optional properties:
 
 - clock-names: Should be "mclk"
 
+- maxim,dmic-freq: Frequency at which to clock DMIC
+
 Pins on the device (for linking into audio routes):
 
   * MIC1
index 2cd3e5427441ef895cec7bc45d4e1918afaf4a0e..805b3f8cd39df1d526543385dd273da18d40e35f 100644 (file)
@@ -875,7 +875,7 @@ static const struct snd_kcontrol_new max98088_right_ADC_mixer_controls[] = {
 static int max98088_mic_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = w->codec;
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
        struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
 
        switch (event) {
@@ -905,7 +905,7 @@ static int max98088_mic_event(struct snd_soc_dapm_widget *w,
 static int max98088_line_pga(struct snd_soc_dapm_widget *w,
                             int event, int line, u8 channel)
 {
-       struct snd_soc_codec *codec = w->codec;
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
        struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
        u8 *state;
 
@@ -1887,25 +1887,6 @@ static void max98088_handle_pdata(struct snd_soc_codec *codec)
                max98088_handle_eq_pdata(codec);
 }
 
-#ifdef CONFIG_PM
-static int max98088_suspend(struct snd_soc_codec *codec)
-{
-       max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-       return 0;
-}
-
-static int max98088_resume(struct snd_soc_codec *codec)
-{
-       max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-       return 0;
-}
-#else
-#define max98088_suspend NULL
-#define max98088_resume NULL
-#endif
-
 static int max98088_probe(struct snd_soc_codec *codec)
 {
        struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
@@ -1946,9 +1927,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
 
        snd_soc_write(codec, M98088_REG_51_PWR_SYS, M98088_PWRSV);
 
-       /* initialize registers cache to hardware default */
-       max98088_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
        snd_soc_write(codec, M98088_REG_0F_IRQ_ENABLE, 0x00);
 
        snd_soc_write(codec, M98088_REG_22_MIX_DAC,
@@ -1974,7 +1952,6 @@ static int max98088_remove(struct snd_soc_codec *codec)
 {
        struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
 
-       max98088_set_bias_level(codec, SND_SOC_BIAS_OFF);
        kfree(max98088->eq_texts);
 
        return 0;
@@ -1983,9 +1960,9 @@ static int max98088_remove(struct snd_soc_codec *codec)
 static struct snd_soc_codec_driver soc_codec_dev_max98088 = {
        .probe   = max98088_probe,
        .remove  = max98088_remove,
-       .suspend = max98088_suspend,
-       .resume  = max98088_resume,
        .set_bias_level = max98088_set_bias_level,
+       .suspend_bias_off = true,
+
        .controls = max98088_snd_controls,
        .num_controls = ARRAY_SIZE(max98088_snd_controls),
        .dapm_widgets = max98088_dapm_widgets,
index 34ed9a91f3926f4b4ba01aebf53b01b4ee282213..151f718241ea4359c25b0703b44bf74c5e7164d1 100644 (file)
@@ -806,7 +806,7 @@ static const struct snd_kcontrol_new max98091_snd_controls[] = {
 static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
                                 struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = w->codec;
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
        struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
 
        unsigned int val = snd_soc_read(codec, w->reg);
@@ -1828,27 +1828,155 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
        return 0;
 }
 
-static const int comp_pclk_rates[] = {
-       11289600, 12288000, 12000000, 13000000, 19200000
-};
-
-static const int dmic_micclk[] = {
-       2, 2, 2, 2, 4, 2
-};
+static const int dmic_divisors[] = { 2, 3, 4, 5, 6, 8 };
 
 static const int comp_lrclk_rates[] = {
        8000, 16000, 32000, 44100, 48000, 96000
 };
 
-static const int dmic_comp[6][6] = {
-       {7, 8, 3, 3, 3, 3},
-       {7, 8, 3, 3, 3, 3},
-       {7, 8, 3, 3, 3, 3},
-       {7, 8, 3, 1, 1, 1},
-       {7, 8, 3, 1, 2, 2},
-       {7, 8, 3, 3, 3, 3}
+struct dmic_table {
+       int pclk;
+       struct {
+               int freq;
+               int comp[6]; /* One each for 8, 16, 32, 44.1, 48, and 96 kHz */
+       } settings[6]; /* One for each dmic divisor. */
 };
 
+static const struct dmic_table dmic_table[] = { /* One for each pclk freq. */
+       {
+               .pclk = 11289600,
+               .settings = {
+                       { .freq = 2, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 1, .comp = { 7, 8, 2, 2, 2, 2 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 0, .comp = { 7, 8, 6, 6, 6, 6 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+               },
+       },
+       {
+               .pclk = 12000000,
+               .settings = {
+                       { .freq = 2, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 1, .comp = { 7, 8, 2, 2, 2, 2 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 0, .comp = { 7, 8, 5, 5, 6, 6 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+               }
+       },
+       {
+               .pclk = 12288000,
+               .settings = {
+                       { .freq = 2, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 1, .comp = { 7, 8, 2, 2, 2, 2 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 0, .comp = { 7, 8, 6, 6, 6, 6 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+                       { .freq = 0, .comp = { 7, 8, 3, 3, 3, 3 } },
+               }
+       },
+       {
+               .pclk = 13000000,
+               .settings = {
+                       { .freq = 2, .comp = { 7, 8, 1, 1, 1, 1 } },
+                       { .freq = 1, .comp = { 7, 8, 0, 0, 0, 0 } },
+                       { .freq = 0, .comp = { 7, 8, 1, 1, 1, 1 } },
+                       { .freq = 0, .comp = { 7, 8, 4, 4, 5, 5 } },
+                       { .freq = 0, .comp = { 7, 8, 1, 1, 1, 1 } },
+                       { .freq = 0, .comp = { 7, 8, 1, 1, 1, 1 } },
+               }
+       },
+       {
+               .pclk = 19200000,
+               .settings = {
+                       { .freq = 2, .comp = { 0, 0, 0, 0, 0, 0 } },
+                       { .freq = 1, .comp = { 7, 8, 1, 1, 1, 1 } },
+                       { .freq = 0, .comp = { 7, 8, 5, 5, 6, 6 } },
+                       { .freq = 0, .comp = { 7, 8, 2, 2, 3, 3 } },
+                       { .freq = 0, .comp = { 7, 8, 1, 1, 2, 2 } },
+                       { .freq = 0, .comp = { 7, 8, 5, 5, 6, 6 } },
+               }
+       },
+};
+
+static int max98090_find_divisor(int target_freq, int pclk)
+{
+       int current_diff = INT_MAX;
+       int test_diff = INT_MAX;
+       int divisor_index = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dmic_divisors); i++) {
+               test_diff = abs(target_freq - (pclk / dmic_divisors[i]));
+               if (test_diff < current_diff) {
+                       current_diff = test_diff;
+                       divisor_index = i;
+               }
+       }
+
+       return divisor_index;
+}
+
+static int max98090_find_closest_pclk(int pclk)
+{
+       int m1;
+       int m2;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dmic_table); i++) {
+               if (pclk == dmic_table[i].pclk)
+                       return i;
+               if (pclk < dmic_table[i].pclk) {
+                       if (i == 0)
+                               return i;
+                       m1 = pclk - dmic_table[i-1].pclk;
+                       m2 = dmic_table[i].pclk - pclk;
+                       if (m1 < m2)
+                               return i - 1;
+                       else
+                               return i;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int max98090_configure_dmic(struct max98090_priv *max98090,
+                                  int target_dmic_clk, int pclk, int fs)
+{
+       int micclk_index;
+       int pclk_index;
+       int dmic_freq;
+       int dmic_comp;
+       int i;
+
+       pclk_index = max98090_find_closest_pclk(pclk);
+       if (pclk_index < 0)
+               return pclk_index;
+
+       micclk_index = max98090_find_divisor(target_dmic_clk, pclk);
+
+       for (i = 0; i < ARRAY_SIZE(comp_lrclk_rates) - 1; i++) {
+               if (fs <= (comp_lrclk_rates[i] + comp_lrclk_rates[i+1]) / 2)
+                       break;
+       }
+
+       dmic_freq = dmic_table[pclk_index].settings[micclk_index].freq;
+       dmic_comp = dmic_table[pclk_index].settings[micclk_index].comp[i];
+
+       regmap_update_bits(max98090->regmap, M98090_REG_DIGITAL_MIC_ENABLE,
+                          M98090_MICCLK_MASK,
+                          micclk_index << M98090_MICCLK_SHIFT);
+
+       regmap_update_bits(max98090->regmap, M98090_REG_DIGITAL_MIC_CONFIG,
+                          M98090_DMIC_COMP_MASK | M98090_DMIC_FREQ_MASK,
+                          dmic_comp << M98090_DMIC_COMP_SHIFT |
+                          dmic_freq << M98090_DMIC_FREQ_SHIFT);
+
+       return 0;
+}
+
 static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
@@ -1856,7 +1984,6 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_codec *codec = dai->codec;
        struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
        struct max98090_cdata *cdata;
-       int i, j;
 
        cdata = &max98090->dai[0];
        max98090->bclk = snd_soc_params_to_bclk(params);
@@ -1895,27 +2022,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
                snd_soc_update_bits(codec, M98090_REG_FILTER_CONFIG,
                        M98090_DHF_MASK, M98090_DHF_MASK);
 
-       /* Check for supported PCLK to LRCLK ratios */
-       for (j = 0; j < ARRAY_SIZE(comp_pclk_rates); j++) {
-               if (comp_pclk_rates[j] == max98090->sysclk) {
-                       break;
-               }
-       }
-
-       for (i = 0; i < ARRAY_SIZE(comp_lrclk_rates) - 1; i++) {
-               if (max98090->lrclk <= (comp_lrclk_rates[i] +
-                       comp_lrclk_rates[i + 1]) / 2) {
-                       break;
-               }
-       }
-
-       snd_soc_update_bits(codec, M98090_REG_DIGITAL_MIC_ENABLE,
-                       M98090_MICCLK_MASK,
-                       dmic_micclk[j] << M98090_MICCLK_SHIFT);
-
-       snd_soc_update_bits(codec, M98090_REG_DIGITAL_MIC_CONFIG,
-                       M98090_DMIC_COMP_MASK,
-                       dmic_comp[j][i] << M98090_DMIC_COMP_SHIFT);
+       max98090_configure_dmic(max98090, max98090->dmic_freq, max98090->pclk,
+                               max98090->lrclk);
 
        return 0;
 }
@@ -1946,12 +2054,15 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
        if ((freq >= 10000000) && (freq <= 20000000)) {
                snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV1);
+               max98090->pclk = freq;
        } else if ((freq > 20000000) && (freq <= 40000000)) {
                snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV2);
+               max98090->pclk = freq >> 1;
        } else if ((freq > 40000000) && (freq <= 60000000)) {
                snd_soc_write(codec, M98090_REG_SYSTEM_CLOCK,
                        M98090_PSCLK_DIV4);
+               max98090->pclk = freq >> 2;
        } else {
                dev_err(codec->dev, "Invalid master clock frequency\n");
                return -EINVAL;
@@ -2326,6 +2437,7 @@ static int max98090_probe(struct snd_soc_codec *codec)
        /* Initialize private data */
 
        max98090->sysclk = (unsigned)-1;
+       max98090->pclk = (unsigned)-1;
        max98090->master = false;
 
        cdata = &max98090->dai[0];
@@ -2465,6 +2577,11 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
        i2c_set_clientdata(i2c, max98090);
        max98090->pdata = i2c->dev.platform_data;
 
+       ret = of_property_read_u32(i2c->dev.of_node, "maxim,dmic-freq",
+                                  &max98090->dmic_freq);
+       if (ret < 0)
+               max98090->dmic_freq = MAX98090_DEFAULT_DMIC_FREQ;
+
        max98090->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap);
        if (IS_ERR(max98090->regmap)) {
                ret = PTR_ERR(max98090->regmap);
index a5f6bada06daf2d886e0717f5c13c3bcd0cfdb1f..21ff743f5af28d07bdc6ec4209b84b6ca2e77929 100644 (file)
 #ifndef _MAX98090_H
 #define _MAX98090_H
 
+/*
+ * The default operating frequency for a DMIC attached to the codec.
+ * This can be overridden by a device tree property.
+ */
+#define MAX98090_DEFAULT_DMIC_FREQ             2500000
+
 /*
  * MAX98090 Register Definitions
  */
@@ -1518,8 +1524,10 @@ struct max98090_priv {
        struct max98090_pdata *pdata;
        struct clk *mclk;
        unsigned int sysclk;
+       unsigned int pclk;
        unsigned int bclk;
        unsigned int lrclk;
+       u32 dmic_freq;
        struct max98090_cdata dai[1];
        int jack_state;
        struct delayed_work jack_work;
index 01f3cc9c780f2c2a2dbc1dce37177eb478a0aa0a..8fba0c3db79827c97135928b4ed537bdec88bbaf 100644 (file)
@@ -866,7 +866,7 @@ static const struct snd_kcontrol_new max98095_right_ADC_mixer_controls[] = {
 static int max98095_mic_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = w->codec;
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
        struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
 
        switch (event) {
@@ -896,7 +896,7 @@ static int max98095_mic_event(struct snd_soc_dapm_widget *w,
 static int max98095_line_pga(struct snd_soc_dapm_widget *w,
                             int event, u8 channel)
 {
-       struct snd_soc_codec *codec = w->codec;
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
        struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
        u8 *state;
 
@@ -944,7 +944,7 @@ static int max98095_pga_in2_event(struct snd_soc_dapm_widget *w,
 static int max98095_lineout_event(struct snd_soc_dapm_widget *w,
                             struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = w->codec;
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
@@ -2319,9 +2319,6 @@ static int max98095_probe(struct snd_soc_codec *codec)
 
        snd_soc_write(codec, M98095_097_PWR_SYS, M98095_PWRSV);
 
-       /* initialize registers cache to hardware default */
-       max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
        snd_soc_write(codec, M98095_048_MIX_DAC_LR,
                M98095_DAI1L_TO_DACL|M98095_DAI1R_TO_DACR);
 
@@ -2361,8 +2358,6 @@ static int max98095_remove(struct snd_soc_codec *codec)
        struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
        struct i2c_client *client = to_i2c_client(codec->dev);
 
-       max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
        if (max98095->headphone_jack || max98095->mic_jack)
                max98095_jack_detect_disable(codec);
 
index 4fdf5aaa236f65cbb643cd837bd792da0619970d..10f8e47ce2c28604a1d8cfdbe87b871d1e029290 100644 (file)
@@ -291,25 +291,6 @@ static struct snd_soc_dai_driver max9850_dai = {
        .ops = &max9850_dai_ops,
 };
 
-#ifdef CONFIG_PM
-static int max9850_suspend(struct snd_soc_codec *codec)
-{
-       max9850_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-       return 0;
-}
-
-static int max9850_resume(struct snd_soc_codec *codec)
-{
-       max9850_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-       return 0;
-}
-#else
-#define max9850_suspend NULL
-#define max9850_resume NULL
-#endif
-
 static int max9850_probe(struct snd_soc_codec *codec)
 {
        /* enable zero-detect */
@@ -324,9 +305,8 @@ static int max9850_probe(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver soc_codec_dev_max9850 = {
        .probe =        max9850_probe,
-       .suspend =      max9850_suspend,
-       .resume =       max9850_resume,
        .set_bias_level = max9850_set_bias_level,
+       .suspend_bias_off = true,
 
        .controls = max9850_controls,
        .num_controls = ARRAY_SIZE(max9850_controls),
index d1b7293c133eaa456f9d7761f273ee2887251121..3e3fec4e5c4ea5f15f1c2e1ee6ebeccbc9600a38 100644 (file)
@@ -29,7 +29,9 @@ struct simple_card_data {
        } *dai_props;
        unsigned int mclk_fs;
        int gpio_hp_det;
+       int gpio_hp_det_invert;
        int gpio_mic_det;
+       int gpio_mic_det_invert;
        struct snd_soc_dai_link dai_link[];     /* dynamically allocated */
 };
 
@@ -148,6 +150,7 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
                                      simple_card_hp_jack_pins);
 
                simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det;
+               simple_card_hp_jack_gpio.invert = priv->gpio_hp_det_invert;
                snd_soc_jack_add_gpios(&simple_card_hp_jack, 1,
                                       &simple_card_hp_jack_gpio);
        }
@@ -159,6 +162,7 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
                                      ARRAY_SIZE(simple_card_mic_jack_pins),
                                      simple_card_mic_jack_pins);
                simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det;
+               simple_card_mic_jack_gpio.invert = priv->gpio_mic_det_invert;
                snd_soc_jack_add_gpios(&simple_card_mic_jack, 1,
                                       &simple_card_mic_jack_gpio);
        }
@@ -226,6 +230,53 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
        return 0;
 }
 
+static int asoc_simple_card_parse_daifmt(struct device_node *node,
+                                        struct simple_card_data *priv,
+                                        struct device_node *cpu,
+                                        struct device_node *codec,
+                                        char *prefix, int idx)
+{
+       struct device *dev = simple_priv_to_dev(priv);
+       struct device_node *bitclkmaster = NULL;
+       struct device_node *framemaster = NULL;
+       struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
+       struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
+       struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
+       unsigned int daifmt;
+
+       daifmt = snd_soc_of_parse_daifmt(node, prefix,
+                                        &bitclkmaster, &framemaster);
+       daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
+
+       if (strlen(prefix) && !bitclkmaster && !framemaster) {
+               /*
+                * No dai-link level and master setting was not found from
+                * sound node level, revert back to legacy DT parsing and
+                * take the settings from codec node.
+                */
+               dev_dbg(dev, "Revert to legacy daifmt parsing\n");
+
+               cpu_dai->fmt = codec_dai->fmt =
+                       snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
+                       (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
+       } else {
+               if (codec == bitclkmaster)
+                       daifmt |= (codec == framemaster) ?
+                               SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
+               else
+                       daifmt |= (codec == framemaster) ?
+                               SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
+
+               cpu_dai->fmt    = daifmt;
+               codec_dai->fmt  = daifmt;
+       }
+
+       of_node_put(bitclkmaster);
+       of_node_put(framemaster);
+
+       return 0;
+}
+
 static int asoc_simple_card_dai_link_of(struct device_node *node,
                                        struct simple_card_data *priv,
                                        int idx,
@@ -234,10 +285,8 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
        struct device *dev = simple_priv_to_dev(priv);
        struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
        struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
-       struct device_node *np = NULL;
-       struct device_node *bitclkmaster = NULL;
-       struct device_node *framemaster = NULL;
-       unsigned int daifmt;
+       struct device_node *cpu = NULL;
+       struct device_node *codec = NULL;
        char *name;
        char prop[128];
        char *prefix = "";
@@ -247,85 +296,36 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
        if (is_top_level_node)
                prefix = "simple-audio-card,";
 
-       daifmt = snd_soc_of_parse_daifmt(node, prefix,
-                                        &bitclkmaster, &framemaster);
-       daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
-
        snprintf(prop, sizeof(prop), "%scpu", prefix);
-       np = of_get_child_by_name(node, prop);
-       if (!np) {
+       cpu = of_get_child_by_name(node, prop);
+
+       snprintf(prop, sizeof(prop), "%scodec", prefix);
+       codec = of_get_child_by_name(node, prop);
+
+       if (!cpu || !codec) {
                ret = -EINVAL;
                dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
                goto dai_link_of_err;
        }
 
-       ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai,
+       ret = asoc_simple_card_parse_daifmt(node, priv,
+                                           cpu, codec, prefix, idx);
+       if (ret < 0)
+               goto dai_link_of_err;
+
+       ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai,
                                            &dai_link->cpu_of_node,
                                            &dai_link->cpu_dai_name,
                                            &cpu_args);
        if (ret < 0)
                goto dai_link_of_err;
 
-       dai_props->cpu_dai.fmt = daifmt;
-       switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
-       case 0x11:
-               dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
-               break;
-       case 0x10:
-               dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM;
-               break;
-       case 0x01:
-               dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS;
-               break;
-       default:
-               dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
-               break;
-       }
-
-       of_node_put(np);
-       snprintf(prop, sizeof(prop), "%scodec", prefix);
-       np = of_get_child_by_name(node, prop);
-       if (!np) {
-               ret = -EINVAL;
-               dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
-               goto dai_link_of_err;
-       }
-
-       ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai,
+       ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai,
                                            &dai_link->codec_of_node,
                                            &dai_link->codec_dai_name, NULL);
        if (ret < 0)
                goto dai_link_of_err;
 
-       if (strlen(prefix) && !bitclkmaster && !framemaster) {
-               /*
-                * No DAI link level and master setting was found
-                * from sound node level, revert back to legacy DT
-                * parsing and take the settings from codec node.
-                */
-               dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n",
-                       __func__);
-               dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt =
-                       snd_soc_of_parse_daifmt(np, NULL, NULL, NULL) |
-                       (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
-       } else {
-               dai_props->codec_dai.fmt = daifmt;
-               switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
-               case 0x11:
-                       dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
-                       break;
-               case 0x10:
-                       dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS;
-                       break;
-               case 0x01:
-                       dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM;
-                       break;
-               default:
-                       dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
-                       break;
-               }
-       }
-
        if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
                ret = -EINVAL;
                goto dai_link_of_err;
@@ -368,12 +368,9 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
                dai_link->cpu_dai_name = NULL;
 
 dai_link_of_err:
-       if (np)
-               of_node_put(np);
-       if (bitclkmaster)
-               of_node_put(bitclkmaster);
-       if (framemaster)
-               of_node_put(framemaster);
+       of_node_put(cpu);
+       of_node_put(codec);
+
        return ret;
 }
 
@@ -381,6 +378,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
                                     struct simple_card_data *priv)
 {
        struct device *dev = simple_priv_to_dev(priv);
+       enum of_gpio_flags flags;
        u32 val;
        int ret;
 
@@ -436,13 +434,15 @@ static int asoc_simple_card_parse_of(struct device_node *node,
                        return ret;
        }
 
-       priv->gpio_hp_det = of_get_named_gpio(node,
-                               "simple-audio-card,hp-det-gpio", 0);
+       priv->gpio_hp_det = of_get_named_gpio_flags(node,
+                               "simple-audio-card,hp-det-gpio", 0, &flags);
+       priv->gpio_hp_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW);
        if (priv->gpio_hp_det == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
-       priv->gpio_mic_det = of_get_named_gpio(node,
-                               "simple-audio-card,mic-det-gpio", 0);
+       priv->gpio_mic_det = of_get_named_gpio_flags(node,
+                               "simple-audio-card,mic-det-gpio", 0, &flags);
+       priv->gpio_mic_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW);
        if (priv->gpio_mic_det == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
@@ -457,18 +457,13 @@ static int asoc_simple_card_unref(struct platform_device *pdev)
 {
        struct snd_soc_card *card = platform_get_drvdata(pdev);
        struct snd_soc_dai_link *dai_link;
-       struct device_node *np;
        int num_links;
 
        for (num_links = 0, dai_link = card->dai_link;
             num_links < card->num_links;
             num_links++, dai_link++) {
-               np = (struct device_node *) dai_link->cpu_of_node;
-               if (np)
-                       of_node_put(np);
-               np = (struct device_node *) dai_link->codec_of_node;
-               if (np)
-                       of_node_put(np);
+               of_node_put(dai_link->cpu_of_node);
+               of_node_put(dai_link->codec_of_node);
        }
        return 0;
 }
index 3c8f60423e825d401e659e459afed3f00642799a..d7640e72cb1d7d7fead83054858292ce2e92be10 100644 (file)
@@ -153,8 +153,8 @@ static int odroidx2_audio_remove(struct platform_device *pdev)
 
        snd_soc_unregister_card(card);
 
-       of_node_put((struct device_node *)odroidx2_dai[0].cpu_of_node);
-       of_node_put((struct device_node *)odroidx2_dai[0].codec_of_node);
+       of_node_put(odroidx2_dai[0].cpu_of_node);
+       of_node_put(odroidx2_dai[0].codec_of_node);
 
        return 0;
 }
index b3b66aa98dce7d8b3f6844eb9f65a7d59a728cd8..9f2d045ee11854dc094a0588a3b20f35c5b07d03 100644 (file)
@@ -63,12 +63,8 @@ static void mop500_of_node_put(void)
        int i;
 
        for (i = 0; i < 2; i++) {
-               if (mop500_dai_links[i].cpu_of_node)
-                       of_node_put((struct device_node *)
-                               mop500_dai_links[i].cpu_of_node);
-               if (mop500_dai_links[i].codec_of_node)
-                       of_node_put((struct device_node *)
-                               mop500_dai_links[i].codec_of_node);
+               of_node_put(mop500_dai_links[i].cpu_of_node);
+               of_node_put(mop500_dai_links[i].codec_of_node);
        }
 }