[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, ®val))
+ 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, ®val))
- 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