]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - sound/soc/codecs/rt5670.c
Merge remote-tracking branch 'asoc/topic/w-codec' into asoc-next
[karo-tx-linux.git] / sound / soc / codecs / rt5670.c
index 697aabf456a55dc4eb1f874cc9c4d684c50a2382..f5b054de481e26b94f6a4459d839db64ddff523b 100644 (file)
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
+#include <linux/pm_runtime.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
 #include <linux/spi/spi.h>
+#include <linux/dmi.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -2190,6 +2192,13 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
        if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src)
                return 0;
 
+       if (rt5670->pdata.jd_mode) {
+               if (clk_id == RT5670_SCLK_S_PLL1)
+                       snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
+               else
+                       snd_soc_dapm_disable_pin(&codec->dapm, "PLL1");
+               snd_soc_dapm_sync(&codec->dapm);
+       }
        switch (clk_id) {
        case RT5670_SCLK_S_MCLK:
                reg_val |= RT5670_SCLK_SRC_MCLK;
@@ -2551,6 +2560,17 @@ static struct acpi_device_id rt5670_acpi_match[] = {
 MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match);
 #endif
 
+static const struct dmi_system_id dmi_platform_intel_braswell[] = {
+       {
+               .ident = "Intel Braswell",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Braswell CRB"),
+               },
+       },
+       {}
+};
+
 static int rt5670_i2c_probe(struct i2c_client *i2c,
                    const struct i2c_device_id *id)
 {
@@ -2570,6 +2590,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
        if (pdata)
                rt5670->pdata = *pdata;
 
+       if (dmi_check_system(dmi_platform_intel_braswell)) {
+               rt5670->pdata.dmic_en = true;
+               rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
+               rt5670->pdata.jd_mode = 1;
+       }
+
        rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap);
        if (IS_ERR(rt5670->regmap)) {
                ret = PTR_ERR(rt5670->regmap);
@@ -2611,6 +2637,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
        }
 
        if (rt5670->pdata.jd_mode) {
+               regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK,
+                                  RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK);
+               rt5670->sysclk = 0;
+               rt5670->sysclk_src = RT5670_SCLK_S_RCCLK;
                regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1,
                                   RT5670_PWR_MB, RT5670_PWR_MB);
                regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2,
@@ -2718,18 +2748,26 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
 
        }
 
+       pm_runtime_enable(&i2c->dev);
+       pm_request_idle(&i2c->dev);
+
        ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
                        rt5670_dai, ARRAY_SIZE(rt5670_dai));
        if (ret < 0)
                goto err;
 
+       pm_runtime_put(&i2c->dev);
+
        return 0;
 err:
+       pm_runtime_disable(&i2c->dev);
+
        return ret;
 }
 
 static int rt5670_i2c_remove(struct i2c_client *i2c)
 {
+       pm_runtime_disable(&i2c->dev);
        snd_soc_unregister_codec(&i2c->dev);
 
        return 0;