Merge remote-tracking branches 'asoc/topic/ad1980', 'asoc/topic/adsp', 'asoc/topic...
authorMark Brown <broonie@linaro.org>
Wed, 21 May 2014 23:23:45 +0000 (00:23 +0100)
committerMark Brown <broonie@linaro.org>
Wed, 21 May 2014 23:23:45 +0000 (00:23 +0100)
Documentation/devicetree/bindings/sound/ak4104.txt
Documentation/devicetree/bindings/sound/alc5623.txt [new file with mode: 0644]
sound/soc/atmel/Kconfig
sound/soc/codecs/Kconfig
sound/soc/codecs/ad1980.c
sound/soc/codecs/ak4104.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/alc5623.c
sound/soc/codecs/cq93vc.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm_adsp.c

index b902ee39cf8973bae24217f329c5c24ab8d012bb..deca5e18f304bd2a45723acd4579959a6fe8ce61 100644 (file)
@@ -8,6 +8,8 @@ Required properties:
 
   - reg : The chip select number on the SPI bus
 
+  - vdd-supply : A regulator node, providing 2.7V - 3.6V
+
 Optional properties:
 
   - reset-gpio : a GPIO spec for the reset pin. If specified, it will be
@@ -19,4 +21,5 @@ spdif: ak4104@0 {
        compatible = "asahi-kasei,ak4104";
        reg = <0>;
        spi-max-frequency = <5000000>;
+       vdd-supply = <&vdd_3v3_reg>;
 };
diff --git a/Documentation/devicetree/bindings/sound/alc5623.txt b/Documentation/devicetree/bindings/sound/alc5623.txt
new file mode 100644 (file)
index 0000000..26c86c9
--- /dev/null
@@ -0,0 +1,25 @@
+ALC5621/ALC5622/ALC5623 audio Codec
+
+Required properties:
+
+ - compatible: "realtek,alc5623"
+ - reg:                the I2C address of the device.
+
+Optional properties:
+
+ - add-ctrl:     Default register value for Reg-40h, Additional Control
+                 Register. If absent or has the value of 0, the
+                 register is untouched.
+
+ - jack-det-ctrl: Default register value for Reg-5Ah, Jack Detect
+                 Control Register. If absent or has value 0, the
+                 register is untouched.
+
+Example:
+
+       alc5621: alc5621@1a {
+               compatible = "alc5621";
+               reg = <0x1a>;
+               add-ctrl = <0x3700>;
+               jack-det-ctrl = <0x4810>;
+       };
index 4789619a52d86dc38b8da2222b11cbda50dd0a8c..27e3fc4a536b40595d774865c7f9b7013c01752a 100644 (file)
@@ -35,7 +35,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
 
 config SND_ATMEL_SOC_WM8904
        tristate "Atmel ASoC driver for boards using WM8904 codec"
-       depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC
+       depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC && I2C
        select SND_ATMEL_SOC_SSC
        select SND_ATMEL_SOC_DMA
        select SND_SOC_WM8904
index c7b853f520cf17454a80d0ab81e671cccf972609..6735435cccb9e4c9698673e18b816df5edbb19d3 100644 (file)
@@ -270,7 +270,7 @@ config SND_SOC_AK5386
        tristate "AKM AK5638 CODEC"
 
 config SND_SOC_ALC5623
-       tristate
+       tristate "Realtek ALC5623 CODEC"
 
 config SND_SOC_ALC5632
        tristate
index 34d965a4a040c91d861a8d2f8a3ef183b95bc5e8..304d3003339a63bcedc4db0b3de821edd133ce05 100644 (file)
@@ -189,28 +189,27 @@ static struct snd_soc_dai_driver ad1980_dai = {
 
 static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)
 {
-       u16 retry_cnt = 0;
+       unsigned int retry_cnt = 0;
 
-retry:
-       if (try_warm && soc_ac97_ops->warm_reset) {
-               soc_ac97_ops->warm_reset(codec->ac97);
-               if (ac97_read(codec, AC97_RESET) == 0x0090)
-                       return 1;
-       }
-
-       soc_ac97_ops->reset(codec->ac97);
-       /* Set bit 16slot in register 74h, then every slot will has only 16
-        * bits. This command is sent out in 20bit mode, in which case the
-        * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/
-       ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
-
-       if (ac97_read(codec, AC97_RESET)  != 0x0090)
-               goto err;
-       return 0;
+       do {
+               if (try_warm && soc_ac97_ops->warm_reset) {
+                       soc_ac97_ops->warm_reset(codec->ac97);
+                       if (ac97_read(codec, AC97_RESET) == 0x0090)
+                               return 1;
+               }
 
-err:
-       while (retry_cnt++ < 10)
-               goto retry;
+               soc_ac97_ops->reset(codec->ac97);
+               /*
+                * Set bit 16slot in register 74h, then every slot will has only
+                * 16 bits. This command is sent out in 20bit mode, in which
+                * case the first nibble of data is eaten by the addr. (Tag is
+                * always 16 bit)
+                */
+               ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900);
+
+               if (ac97_read(codec, AC97_RESET)  == 0x0090)
+                       return 0;
+       } while (retry_cnt++ < 10);
 
        printk(KERN_ERR "AD1980 AC97 reset failed\n");
        return -EIO;
index 10adf25d4c14f36e64d383d8be3a967387ce1726..1fd7f72b2a62a05f99567e02e634328f65bc5fce 100644 (file)
 
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/soc.h>
-#include <sound/initval.h>
 #include <linux/spi/spi.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
 #include <sound/asoundef.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
 
 /* AK4104 registers addresses */
 #define AK4104_REG_CONTROL1            0x00
@@ -47,6 +48,7 @@
 
 struct ak4104_private {
        struct regmap *regmap;
+       struct regulator *regulator;
 };
 
 static const struct snd_soc_dapm_widget ak4104_dapm_widgets[] = {
@@ -174,20 +176,30 @@ static int ak4104_probe(struct snd_soc_codec *codec)
        struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
+       ret = regulator_enable(ak4104->regulator);
+       if (ret < 0) {
+               dev_err(codec->dev, "Unable to enable regulator: %d\n", ret);
+               return ret;
+       }
+
        /* set power-up and non-reset bits */
        ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
                                 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,
                                 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);
        if (ret < 0)
-               return ret;
+               goto exit_disable_regulator;
 
        /* enable transmitter */
        ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX,
                                 AK4104_TX_TXE, AK4104_TX_TXE);
        if (ret < 0)
-               return ret;
+               goto exit_disable_regulator;
 
        return 0;
+
+exit_disable_regulator:
+       regulator_disable(ak4104->regulator);
+       return ret;
 }
 
 static int ak4104_remove(struct snd_soc_codec *codec)
@@ -196,13 +208,42 @@ static int ak4104_remove(struct snd_soc_codec *codec)
 
        regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,
                           AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);
+       regulator_disable(ak4104->regulator);
 
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int ak4104_soc_suspend(struct snd_soc_codec *codec)
+{
+       struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec);
+
+       regulator_disable(priv->regulator);
+
+       return 0;
+}
+
+static int ak4104_soc_resume(struct snd_soc_codec *codec)
+{
+       struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec);
+       int ret;
+
+       ret = regulator_enable(priv->regulator);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+#else
+#define ak4104_soc_suspend     NULL
+#define ak4104_soc_resume      NULL
+#endif /* CONFIG_PM */
+
 static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
-       .probe =        ak4104_probe,
-       .remove =       ak4104_remove,
+       .probe = ak4104_probe,
+       .remove = ak4104_remove,
+       .suspend = ak4104_soc_suspend,
+       .resume = ak4104_soc_resume,
 
        .dapm_widgets = ak4104_dapm_widgets,
        .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets),
@@ -239,6 +280,13 @@ static int ak4104_spi_probe(struct spi_device *spi)
        if (ak4104 == NULL)
                return -ENOMEM;
 
+       ak4104->regulator = devm_regulator_get(&spi->dev, "vdd");
+       if (IS_ERR(ak4104->regulator)) {
+               ret = PTR_ERR(ak4104->regulator);
+               dev_err(&spi->dev, "Unable to get Vdd regulator: %d\n", ret);
+               return ret;
+       }
+
        ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap);
        if (IS_ERR(ak4104->regmap)) {
                ret = PTR_ERR(ak4104->regmap);
index 92655cc189ae0ad5791ab3483286de18dbd559b5..3ba4c0f11418a8228012f17ff6f3500739401940 100644 (file)
@@ -98,7 +98,7 @@
 #define MGAIN0         (1 << 0) /* MIC amp gain*/
 
 /* TIMER */
-#define ZTM(param)     ((param & 0x3) << 4) /* ALC Zoro Crossing TimeOut */
+#define ZTM(param)     ((param & 0x3) << 4) /* ALC Zero Crossing TimeOut */
 #define WTM(param)     (((param & 0x4) << 4) | ((param & 0x3) << 2))
 
 /* ALC_CTL1 */
 /* MD_CTL4 */
 #define DACH           (1 << 0)
 
+struct ak4642_drvdata {
+       const struct regmap_config *regmap_config;
+       int extended_frequencies;
+};
+
+struct ak4642_priv {
+       const struct ak4642_drvdata *drvdata;
+};
+
 /*
  * Playback Volume (table 39)
  *
@@ -148,6 +157,8 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
 
        SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
                         0, 0xFF, 1, out_tlv),
+       SOC_SINGLE("ALC Capture Switch", ALC_CTL1, 5, 1, 0),
+       SOC_SINGLE("ALC Capture ZC Switch", ALC_CTL1, 4, 1, 1),
 };
 
 static const struct snd_kcontrol_new ak4642_headphone_control =
@@ -287,7 +298,9 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
        int clk_id, unsigned int freq, int dir)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
+       struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
        u8 pll;
+       int extended_freq = 0;
 
        switch (freq) {
        case 11289600:
@@ -308,9 +321,25 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
        case 27000000:
                pll = PLL3 | PLL2 | PLL0;
                break;
+       case 19200000:
+               pll = PLL3;
+               extended_freq = 1;
+               break;
+       case 13000000:
+               pll = PLL3 | PLL2 | PLL1;
+               extended_freq = 1;
+               break;
+       case 26000000:
+               pll = PLL3 | PLL2 | PLL1 | PLL0;
+               extended_freq = 1;
+               break;
        default:
                return -EINVAL;
        }
+
+       if (extended_freq && !priv->drvdata->extended_frequencies)
+               return -EINVAL;
+
        snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll);
 
        return 0;
@@ -505,30 +534,52 @@ static const struct regmap_config ak4648_regmap = {
        .num_reg_defaults       = ARRAY_SIZE(ak4648_reg),
 };
 
+static const struct ak4642_drvdata ak4642_drvdata = {
+       .regmap_config = &ak4642_regmap,
+};
+
+static const struct ak4642_drvdata ak4643_drvdata = {
+       .regmap_config = &ak4642_regmap,
+};
+
+static const struct ak4642_drvdata ak4648_drvdata = {
+       .regmap_config = &ak4648_regmap,
+       .extended_frequencies = 1,
+};
+
 static struct of_device_id ak4642_of_match[];
 static int ak4642_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
 {
        struct device_node *np = i2c->dev.of_node;
-       const struct regmap_config *regmap_config = NULL;
+       const struct ak4642_drvdata *drvdata = NULL;
        struct regmap *regmap;
+       struct ak4642_priv *priv;
 
        if (np) {
                const struct of_device_id *of_id;
 
                of_id = of_match_device(ak4642_of_match, &i2c->dev);
                if (of_id)
-                       regmap_config = of_id->data;
+                       drvdata = of_id->data;
        } else {
-               regmap_config = (const struct regmap_config *)id->driver_data;
+               drvdata = (const struct ak4642_drvdata *)id->driver_data;
        }
 
-       if (!regmap_config) {
+       if (!drvdata) {
                dev_err(&i2c->dev, "Unknown device type\n");
                return -EINVAL;
        }
 
-       regmap = devm_regmap_init_i2c(i2c, regmap_config);
+       priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->drvdata = drvdata;
+
+       i2c_set_clientdata(i2c, priv);
+
+       regmap = devm_regmap_init_i2c(i2c, drvdata->regmap_config);
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
@@ -543,17 +594,17 @@ static int ak4642_i2c_remove(struct i2c_client *client)
 }
 
 static struct of_device_id ak4642_of_match[] = {
-       { .compatible = "asahi-kasei,ak4642",   .data = &ak4642_regmap},
-       { .compatible = "asahi-kasei,ak4643",   .data = &ak4642_regmap},
-       { .compatible = "asahi-kasei,ak4648",   .data = &ak4648_regmap},
+       { .compatible = "asahi-kasei,ak4642",   .data = &ak4642_drvdata},
+       { .compatible = "asahi-kasei,ak4643",   .data = &ak4643_drvdata},
+       { .compatible = "asahi-kasei,ak4648",   .data = &ak4648_drvdata},
        {},
 };
 MODULE_DEVICE_TABLE(of, ak4642_of_match);
 
 static const struct i2c_device_id ak4642_i2c_id[] = {
-       { "ak4642", (kernel_ulong_t)&ak4642_regmap },
-       { "ak4643", (kernel_ulong_t)&ak4642_regmap },
-       { "ak4648", (kernel_ulong_t)&ak4648_regmap },
+       { "ak4642", (kernel_ulong_t)&ak4642_drvdata },
+       { "ak4643", (kernel_ulong_t)&ak4643_drvdata },
+       { "ak4648", (kernel_ulong_t)&ak4648_drvdata },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
index 2acf82f4a08a8bed4db26c6c444a0eabec688412..9d0755aa1d16929e970ef6e51792b2d39efba494 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/i2c.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
+#include <linux/of.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -998,8 +999,10 @@ static int alc5623_i2c_probe(struct i2c_client *client,
 {
        struct alc5623_platform_data *pdata;
        struct alc5623_priv *alc5623;
+       struct device_node *np;
        unsigned int vid1, vid2;
        int ret;
+       u32 val32;
 
        alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
                               GFP_KERNEL);
@@ -1040,6 +1043,16 @@ static int alc5623_i2c_probe(struct i2c_client *client,
        if (pdata) {
                alc5623->add_ctrl = pdata->add_ctrl;
                alc5623->jack_det_ctrl = pdata->jack_det_ctrl;
+       } else {
+               if (client->dev.of_node) {
+                       np = client->dev.of_node;
+                       ret = of_property_read_u32(np, "add-ctrl", &val32);
+                       if (!ret)
+                               alc5623->add_ctrl = val32;
+                       ret = of_property_read_u32(np, "jack-det-ctrl", &val32);
+                       if (!ret)
+                               alc5623->jack_det_ctrl = val32;
+               }
        }
 
        alc5623->id = vid2;
@@ -1081,11 +1094,18 @@ static const struct i2c_device_id alc5623_i2c_table[] = {
 };
 MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table);
 
+static const struct of_device_id alc5623_of_match[] = {
+       { .compatible = "realtek,alc5623", },
+       { }
+};
+MODULE_DEVICE_TABLE(of, alc5623_of_match);
+
 /*  i2c codec control layer */
 static struct i2c_driver alc5623_i2c_driver = {
        .driver = {
                .name = "alc562x-codec",
                .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(alc5623_of_match),
        },
        .probe = alc5623_i2c_probe,
        .remove =  alc5623_i2c_remove,
index 5ee48c8e48490948847333d3a650a875e19421ff..537327c7f7f13f364fa99d52e07848653fe3559e 100644 (file)
@@ -154,7 +154,7 @@ static int cq93vc_remove(struct snd_soc_codec *codec)
 
 static struct regmap *cq93vc_get_regmap(struct device *dev)
 {
-       struct davinci_vc *davinci_vc = codec->dev->platform_data;
+       struct davinci_vc *davinci_vc = dev->platform_data;
 
        return davinci_vc->regmap;
 }
index 20527c4098ce5c02ae4fd603d70f11b2aade3e2c..2e5fcb559e9000892c59dea01b3b6ee54c1a166a 100644 (file)
@@ -367,6 +367,11 @@ SOC_SINGLE("HPOUT2 SC Protect Switch", ARIZONA_HP2_SHORT_CIRCUIT_CTRL,
 SOC_SINGLE("HPOUT3 SC Protect Switch", ARIZONA_HP3_SHORT_CIRCUIT_CTRL,
           ARIZONA_HP3_SC_ENA_SHIFT, 1, 0),
 
+SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
+          ARIZONA_OUT5_OSR_SHIFT, 1, 0),
+SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L,
+          ARIZONA_OUT6_OSR_SHIFT, 1, 0),
+
 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
             ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
index d9686dcd024c756e3efd8db5596d2c3e8d37adba..ff15eec3ab2fc8ebe6f5b674ae5b386997eeffad 100644 (file)
@@ -1625,7 +1625,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
                break;
        default:
                break;
-       };
+       }
 
        return 0;
 }