[alsa-devel] [PATCH 1/1] ASoC: codecs: max98088: Combined DAI operations for DAI1 and DAI2.

Jinyoung Park jinyoungp at nvidia.com
Fri Jun 10 11:13:45 CEST 2011


Submitting again the patch what applied Peter's comments.

>> These added local variables and their initialization repeats.
>> It may be better to put them in struct max98088_cdata[].
> I got it. I will change register offset into struct max98088_cdata[].
>
>> DAI2 does not have an OSR bit in the _CLOCK register.
>> In the combined function, this should be conditionally for DAI1 only.
> I will fix it.

Thanks,
Jin.

Combined DAI operations for DAI1 and DAI2.
For this, added id into DAI runtime data to identify each DAI.

Signed-off-by: Jin Park <jinyoungp at nvidia.com>
---
 sound/soc/codecs/max98088.c |  278
+++++++++++--------------------------------
 1 files changed, 69 insertions(+), 209 deletions(-)

diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index ac65a2d..3c0e4f7 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -36,6 +36,14 @@ struct max98088_cdata {
        unsigned int rate;
        unsigned int fmt;
        int eq_sel;
+
+       unsigned short clkmode_reg;
+       unsigned short clk_reg;
+       unsigned short clkcfg_hi_reg;
+       unsigned short clkcfg_lo_reg;
+       unsigned short fmt_reg;
+       unsigned short play_lvl_reg;
+       unsigned short filters_reg;
 };

 struct max98088_priv {
@@ -1253,29 +1261,26 @@ static inline int rate_value(int rate, u8 *value)
        return -EINVAL;
 }

-static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,
+static int max98088_dai_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_pcm_hw_params *params,
                                   struct snd_soc_dai *dai)
 {
        struct snd_soc_codec *codec = dai->codec;
        struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-       struct max98088_cdata *cdata;
+       struct max98088_cdata *cdata = &max98088->dai[dai->id - 1];
        unsigned long long ni;
        unsigned int rate;
-       u8 regval;
-
-       cdata = &max98088->dai[0];
+       u8 val;

        rate = params_rate(params);

        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
-                       M98088_DAI_WS, 0);
+               snd_soc_update_bits(codec, cdata->fmt_reg,
M98088_DAI_WS, 0);
                break;
        case SNDRV_PCM_FORMAT_S24_LE:
-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
-                       M98088_DAI_WS, M98088_DAI_WS);
+               snd_soc_update_bits(codec, cdata->fmt_reg, M98088_DAI_WS,
+                                   M98088_DAI_WS);
                break;
        default:
                return -EINVAL;
@@ -1283,16 +1288,14 @@ static int max98088_dai1_hw_params(struct
snd_pcm_substream *substream,

        snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
M98088_SHDNRUN, 0);

-       if (rate_value(rate, &regval))
+       if (rate_value(rate, &val))
                return -EINVAL;

-       snd_soc_update_bits(codec, M98088_REG_11_DAI1_CLKMODE,
-               M98088_CLKMODE_MASK, regval);
+       snd_soc_update_bits(codec, cdata->clkmode_reg,
M98088_CLKMODE_MASK, val);
        cdata->rate = rate;

        /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98088_REG_14_DAI1_FORMAT)
-               & M98088_DAI_MAS) {
+       if (snd_soc_read(codec, cdata->fmt_reg) & M98088_DAI_MAS) {
                if (max98088->sysclk == 0) {
                        dev_err(codec->dev, "Invalid system clock
frequency\n");
                        return -EINVAL;
@@ -1300,86 +1303,16 @@ static int max98088_dai1_hw_params(struct
snd_pcm_substream *substream,
                ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
                                * (unsigned long long int)rate;
                do_div(ni, (unsigned long long int)max98088->sysclk);
-               snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
-                       (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
-                       ni & 0xFF);
+               snd_soc_write(codec, cdata->clkcfg_hi_reg, (ni >> 8) &
0x7F);
+               snd_soc_write(codec, cdata->clkcfg_lo_reg, ni & 0xFF);
        }

        /* Update sample rate mode */
        if (rate < 50000)
-               snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
-                       M98088_DAI_DHF, 0);
+               snd_soc_update_bits(codec, cdata->filters_reg,
M98088_DAI_DHF, 0);
        else
-               snd_soc_update_bits(codec, M98088_REG_18_DAI1_FILTERS,
-                       M98088_DAI_DHF, M98088_DAI_DHF);
-
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
-               M98088_SHDNRUN);
-
-       return 0;
-}
-
-static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,
-                                  struct snd_pcm_hw_params *params,
-                                  struct snd_soc_dai *dai)
-{
-       struct snd_soc_codec *codec = dai->codec;
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-       struct max98088_cdata *cdata;
-       unsigned long long ni;
-       unsigned int rate;
-       u8 regval;
-
-       cdata = &max98088->dai[1];
-
-       rate = params_rate(params);
-
-       switch (params_format(params)) {
-       case SNDRV_PCM_FORMAT_S16_LE:
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
-                       M98088_DAI_WS, 0);
-               break;
-       case SNDRV_PCM_FORMAT_S24_LE:
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
-                       M98088_DAI_WS, M98088_DAI_WS);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS,
M98088_SHDNRUN, 0);
-
-       if (rate_value(rate, &regval))
-               return -EINVAL;
-
-       snd_soc_update_bits(codec, M98088_REG_19_DAI2_CLKMODE,
-               M98088_CLKMODE_MASK, regval);
-       cdata->rate = rate;
-
-       /* Configure NI when operating as master */
-       if (snd_soc_read(codec, M98088_REG_1C_DAI2_FORMAT)
-               & M98088_DAI_MAS) {
-               if (max98088->sysclk == 0) {
-                       dev_err(codec->dev, "Invalid system clock
frequency\n");
-                       return -EINVAL;
-               }
-               ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)
-                               * (unsigned long long int)rate;
-               do_div(ni, (unsigned long long int)max98088->sysclk);
-               snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
-                       (ni >> 8) & 0x7F);
-               snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
-                       ni & 0xFF);
-       }
-
-       /* Update sample rate mode */
-       if (rate < 50000)
-               snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
-                       M98088_DAI_DHF, 0);
-       else
-               snd_soc_update_bits(codec, M98088_REG_20_DAI2_FILTERS,
-                       M98088_DAI_DHF, M98088_DAI_DHF);
+               snd_soc_update_bits(codec, cdata->filters_reg,
M98088_DAI_DHF,
+                                   M98088_DAI_DHF);

        snd_soc_update_bits(codec, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,
                M98088_SHDNRUN);
@@ -1423,16 +1356,13 @@ static int max98088_dai_set_sysclk(struct
snd_soc_dai *dai,
        return 0;
 }

-static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,
-                                unsigned int fmt)
+static int max98088_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_codec *codec = dai->codec;
        struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-       struct max98088_cdata *cdata;
-       u8 reg15val;
-       u8 reg14val = 0;
-
-       cdata = &max98088->dai[0];
+       struct max98088_cdata *cdata = &max98088->dai[dai->id - 1];
+       u8 clk_val;
+       u8 fmt_val = 0;

        if (fmt != cdata->fmt) {
                cdata->fmt = fmt;
@@ -1440,14 +1370,12 @@ static int max98088_dai1_set_fmt(struct
snd_soc_dai *codec_dai,
                switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
                case SND_SOC_DAIFMT_CBS_CFS:
                        /* Slave mode PLL */
-                       snd_soc_write(codec, M98088_REG_12_DAI1_CLKCFG_HI,
-                               0x80);
-                       snd_soc_write(codec, M98088_REG_13_DAI1_CLKCFG_LO,
-                               0x00);
+                       snd_soc_write(codec, cdata->clkcfg_hi_reg, 0x80);
+                       snd_soc_write(codec, cdata->clkcfg_lo_reg, 0x00);
                        break;
                case SND_SOC_DAIFMT_CBM_CFM:
                        /* Set to master mode */
-                       reg14val |= M98088_DAI_MAS;
+                       fmt_val |= M98088_DAI_MAS;
                        break;
                case SND_SOC_DAIFMT_CBS_CFM:
                case SND_SOC_DAIFMT_CBM_CFS:
@@ -1458,7 +1386,7 @@ static int max98088_dai1_set_fmt(struct
snd_soc_dai *codec_dai,

                switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
                case SND_SOC_DAIFMT_I2S:
-                       reg14val |= M98088_DAI_DLY;
+                       fmt_val |= M98088_DAI_DLY;
                        break;
                case SND_SOC_DAIFMT_LEFT_J:
                        break;
@@ -1470,127 +1398,43 @@ static int max98088_dai1_set_fmt(struct
snd_soc_dai *codec_dai,
                case SND_SOC_DAIFMT_NB_NF:
                        break;
                case SND_SOC_DAIFMT_NB_IF:
-                       reg14val |= M98088_DAI_WCI;
+                       fmt_val |= M98088_DAI_WCI;
                        break;
                case SND_SOC_DAIFMT_IB_NF:
-                       reg14val |= M98088_DAI_BCI;
+                       fmt_val |= M98088_DAI_BCI;
                        break;
                case SND_SOC_DAIFMT_IB_IF:
-                       reg14val |= M98088_DAI_BCI|M98088_DAI_WCI;
+                       fmt_val |= M98088_DAI_BCI|M98088_DAI_WCI;
                        break;
                default:
                        return -EINVAL;
                }

-               snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT,
+               snd_soc_update_bits(codec, cdata->fmt_reg,
                        M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
-                       M98088_DAI_WCI, reg14val);
+                       M98088_DAI_WCI, fmt_val);

-               reg15val = M98088_DAI_BSEL64;
-               if (max98088->digmic)
-                       reg15val |= M98088_DAI_OSR64;
-               snd_soc_write(codec, M98088_REG_15_DAI1_CLOCK, reg15val);
+               clk_val = M98088_DAI_BSEL64;
+               if ((dai->id == 1) && max98088->digmic)
+                       clk_val |= M98088_DAI_OSR64;
+               snd_soc_write(codec, cdata->clk_reg, clk_val);
        }

        return 0;
 }

-static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
-                                unsigned int fmt)
+static int max98088_dai_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       struct snd_soc_codec *codec = codec_dai->codec;
+       struct snd_soc_codec *codec = dai->codec;
        struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
-       struct max98088_cdata *cdata;
-       u8 reg1Cval = 0;
-
-       cdata = &max98088->dai[1];
-
-       if (fmt != cdata->fmt) {
-               cdata->fmt = fmt;
-
-               switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
-               case SND_SOC_DAIFMT_CBS_CFS:
-                       /* Slave mode PLL */
-                       snd_soc_write(codec, M98088_REG_1A_DAI2_CLKCFG_HI,
-                               0x80);
-                       snd_soc_write(codec, M98088_REG_1B_DAI2_CLKCFG_LO,
-                               0x00);
-                       break;
-               case SND_SOC_DAIFMT_CBM_CFM:
-                       /* Set to master mode */
-                       reg1Cval |= M98088_DAI_MAS;
-                       break;
-               case SND_SOC_DAIFMT_CBS_CFM:
-               case SND_SOC_DAIFMT_CBM_CFS:
-               default:
-                       dev_err(codec->dev, "Clock mode unsupported");
-                       return -EINVAL;
-               }
-
-               switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
-               case SND_SOC_DAIFMT_I2S:
-                       reg1Cval |= M98088_DAI_DLY;
-                       break;
-               case SND_SOC_DAIFMT_LEFT_J:
-                       break;
-               default:
-                       return -EINVAL;
-               }
-
-               switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
-               case SND_SOC_DAIFMT_NB_NF:
-                       break;
-               case SND_SOC_DAIFMT_NB_IF:
-                       reg1Cval |= M98088_DAI_WCI;
-                       break;
-               case SND_SOC_DAIFMT_IB_NF:
-                       reg1Cval |= M98088_DAI_BCI;
-                       break;
-               case SND_SOC_DAIFMT_IB_IF:
-                       reg1Cval |= M98088_DAI_BCI|M98088_DAI_WCI;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-
-               snd_soc_update_bits(codec, M98088_REG_1C_DAI2_FORMAT,
-                       M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |
-                       M98088_DAI_WCI, reg1Cval);
-
-               snd_soc_write(codec, M98088_REG_1D_DAI2_CLOCK,
-                       M98088_DAI_BSEL64);
-       }
-
-       return 0;
-}
-
-static int max98088_dai1_digital_mute(struct snd_soc_dai *codec_dai,
int mute)
-{
-       struct snd_soc_codec *codec = codec_dai->codec;
-       int reg;
-
-       if (mute)
-               reg = M98088_DAI_MUTE;
-       else
-               reg = 0;
-
-       snd_soc_update_bits(codec, M98088_REG_2F_LVL_DAI1_PLAY,
-                           M98088_DAI_MUTE_MASK, reg);
-       return 0;
-}
-
-static int max98088_dai2_digital_mute(struct snd_soc_dai *codec_dai,
int mute)
-{
-       struct snd_soc_codec *codec = codec_dai->codec;
-       int reg;
+       struct max98088_cdata *cdata = &max98088->dai[dai->id - 1];
+       int val = 0;

        if (mute)
-               reg = M98088_DAI_MUTE;
-       else
-               reg = 0;
+               val = M98088_DAI_MUTE;

-       snd_soc_update_bits(codec, M98088_REG_31_LVL_DAI2_PLAY,
-                           M98088_DAI_MUTE_MASK, reg);
+       snd_soc_update_bits(codec, cdata->play_lvl_reg,
M98088_DAI_MUTE_MASK,
+                                  val);
        return 0;
 }

@@ -1653,21 +1497,22 @@ static int max98088_set_bias_level(struct
snd_soc_codec *codec,

 static struct snd_soc_dai_ops max98088_dai1_ops = {
        .set_sysclk = max98088_dai_set_sysclk,
-       .set_fmt = max98088_dai1_set_fmt,
-       .hw_params = max98088_dai1_hw_params,
-       .digital_mute = max98088_dai1_digital_mute,
+       .set_fmt = max98088_dai_set_fmt,
+       .hw_params = max98088_dai_hw_params,
+       .digital_mute = max98088_dai_digital_mute,
 };

 static struct snd_soc_dai_ops max98088_dai2_ops = {
        .set_sysclk = max98088_dai_set_sysclk,
-       .set_fmt = max98088_dai2_set_fmt,
-       .hw_params = max98088_dai2_hw_params,
-       .digital_mute = max98088_dai2_digital_mute,
+       .set_fmt = max98088_dai_set_fmt,
+       .hw_params = max98088_dai_hw_params,
+       .digital_mute = max98088_dai_digital_mute,
 };

 static struct snd_soc_dai_driver max98088_dai[] = {
 {
        .name = "HiFi",
+       .id = 1,
        .playback = {
                .stream_name = "HiFi Playback",
                .channels_min = 1,
@@ -1686,6 +1531,7 @@ static struct snd_soc_dai_driver max98088_dai[] = {
 },
 {
        .name = "Aux",
+       .id = 2,
        .playback = {
                .stream_name = "Aux Playback",
                .channels_min = 1,
@@ -1977,11 +1823,25 @@ static int max98088_probe(struct snd_soc_codec
*codec)
        cdata->rate = (unsigned)-1;
        cdata->fmt  = (unsigned)-1;
        cdata->eq_sel = 0;
+       cdata->clkmode_reg = M98088_REG_11_DAI1_CLKMODE;
+       cdata->clk_reg = M98088_REG_15_DAI1_CLOCK;
+       cdata->clkcfg_hi_reg = M98088_REG_12_DAI1_CLKCFG_HI;
+       cdata->clkcfg_lo_reg = M98088_REG_13_DAI1_CLKCFG_LO;
+       cdata->fmt_reg = M98088_REG_14_DAI1_FORMAT;
+       cdata->play_lvl_reg = M98088_REG_2F_LVL_DAI1_PLAY;
+       cdata->filters_reg = M98088_REG_18_DAI1_FILTERS;

        cdata = &max98088->dai[1];
        cdata->rate = (unsigned)-1;
        cdata->fmt  = (unsigned)-1;
        cdata->eq_sel = 0;
+       cdata->clkmode_reg = M98088_REG_19_DAI2_CLKMODE;
+       cdata->clk_reg = M98088_REG_1D_DAI2_CLOCK;
+       cdata->clkcfg_hi_reg = M98088_REG_1A_DAI2_CLKCFG_HI;
+       cdata->clkcfg_lo_reg = M98088_REG_1B_DAI2_CLKCFG_LO;
+       cdata->fmt_reg = M98088_REG_1C_DAI2_FORMAT;
+       cdata->play_lvl_reg = M98088_REG_31_LVL_DAI2_PLAY;
+       cdata->filters_reg = M98088_REG_20_DAI2_FILTERS;

        max98088->ina_state = 0;
        max98088->inb_state = 0;
--
1.7.1



More information about the Alsa-devel mailing list