CHROMIUM: ASoC: max98095 - allow to select MCLK source
authorVincent Palatin <vpalatin@chromium.org>
Wed, 23 Jan 2013 00:41:26 +0000 (16:41 -0800)
committerChromeBot <chrome-bot@google.com>
Thu, 31 Jan 2013 01:57:09 +0000 (17:57 -0800)
The codec clock can come from either MCLK1 or MCLK2 pin.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BUG=chrome-os-partner:17343
TEST=emerge-daisy_spring chromeos-kernel
play sound on Snow with the codec on MCLK1, on Spring proto-1 with the codec
on MCLK2.

Change-Id: Ic82158c63f8fb5c8eb00771e9a1cbf186d561670
Reviewed-on: https://gerrit.chromium.org/gerrit/41876
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>

Documentation/devicetree/bindings/sound/max98095.txt
include/sound/max98095.h
sound/soc/codecs/max98095.c
sound/soc/codecs/max98095.h

index 3a55141..c3d492c 100644 (file)
@@ -12,6 +12,8 @@ Optional properties:
                        instead of analog
   - mic-right-digital : specifies if the right microphone is a DMIC
                        instead of analog
+  - mclk-pin :  specifies which MCLKx pin is used to provide the codec clock
+               1 for MCLK1, 2 for MCLK2/GPIO3.
 
 Example:
 
@@ -21,4 +23,5 @@ codec: max98095@11 {
 
        mic-left-digital;
        mic-righ-digital;
+       mclk-pin = <1>;
 };
index 7513a42..b13392e 100644 (file)
@@ -49,6 +49,9 @@ struct max98095_pdata {
         */
        unsigned int digmic_left_mode:1;
        unsigned int digmic_right_mode:1;
+
+       /* Codec master clock pin selection */
+       u8 mclksel;
 };
 
 #endif
index a5937eb..799b407 100644 (file)
@@ -1499,6 +1499,7 @@ static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
 {
        struct snd_soc_codec *codec = dai->codec;
        struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
+       u8 sysclk = max98095->pdata->mclksel;
 
        /* Requested clock frequency is already setup */
        if (freq == max98095->sysclk)
@@ -1510,17 +1511,19 @@ static int max98095_dai_set_sysclk(struct snd_soc_dai *dai,
         *         0x03 (when master clk is 40MHz to 60MHz)..
         */
        if ((freq >= 10000000) && (freq < 20000000)) {
-               snd_soc_write(codec, M98095_026_SYS_CLK, 0x10);
+               sysclk |= M98095_PSCLK_DIV1;
        } else if ((freq >= 20000000) && (freq < 40000000)) {
-               snd_soc_write(codec, M98095_026_SYS_CLK, 0x20);
+               sysclk |= M98095_PSCLK_DIV2;
        } else if ((freq >= 40000000) && (freq < 60000000)) {
-               snd_soc_write(codec, M98095_026_SYS_CLK, 0x30);
+               sysclk |= M98095_PSCLK_DIV4;
        } else {
                dev_err(codec->dev, "Invalid master clock frequency\n");
                return -EINVAL;
        }
+       snd_soc_write(codec, M98095_026_SYS_CLK, sysclk);
 
-       dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
+       dev_dbg(codec->dev, "Clock source is MCLK%d at %uHz\n",
+               max98095->pdata->mclksel + 1, freq);
 
        max98095->sysclk = freq;
        return 0;
@@ -2369,6 +2372,7 @@ static struct max98095_pdata *max98095_of_pdata(struct i2c_client *i2c)
 {
        struct max98095_pdata *pdata;
        struct device_node *dn = i2c->dev.of_node;
+       u32 pin;
 
        pdata = devm_kzalloc(&i2c->dev, sizeof(struct max98095_pdata),
                             GFP_KERNEL);
@@ -2381,6 +2385,11 @@ static struct max98095_pdata *max98095_of_pdata(struct i2c_client *i2c)
        if (of_get_property(dn, "mic-right-digital", NULL))
                pdata->digmic_right_mode = 1;
 
+       if (!of_property_read_u32(dn, "mclk-pin", &pin) && (pin == 2))
+               pdata->mclksel = M98095_MCLKSEL_MCLK2;
+       else
+               pdata->mclksel = M98095_MCLKSEL_MCLK1;
+
        pdata->eq_cfgcnt = ARRAY_SIZE(built_in_eqs);
        pdata->eq_cfg = built_in_eqs;
 
index 28edb0e..cddeb43 100644 (file)
        #define M98095_XTEN                     (1<<1)
        #define M98095_MDLLEN                   (1<<2)
 
+/* M98095_026_SYS_CLK */
+       #define M98095_MCLKSEL_MCLK1            (0<<0)
+       #define M98095_MCLKSEL_MCLK2            (1<<0)
+       #define M98095_PSCLK_DISABLED           (0<<4)
+       #define M98095_PSCLK_DIV1               (1<<4)
+       #define M98095_PSCLK_DIV2               (2<<4)
+       #define M98095_PSCLK_DIV4               (3<<4)
+
 /* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
        #define M98095_CLKMODE_MASK             0xFF