Fix: ac101 noise import by PLL frequncy deviation
This commit is contained in:
parent
0d30a1599d
commit
cff392127f
2 changed files with 44 additions and 28 deletions
17
ac101.c
17
ac101.c
|
@ -443,7 +443,8 @@ struct kv_map {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note : pll code from original tdm/i2s driver.
|
* Note : pll code from original tdm/i2s driver.
|
||||||
* freq_out = freq_in * N/(m*(2k+1)) , k=1,N=N_i+N_f,N_f=factor*0.2;
|
* freq_out = freq_in * N/(M*(2k+1)) , k=1,N=N_i+N_f,N_f=factor*0.2;
|
||||||
|
* N_i[0,1023], N_f_factor[0,7], m[1,64]=REG_VAL[1-63,0]
|
||||||
*/
|
*/
|
||||||
static const struct pll_div codec_pll_div[] = {
|
static const struct pll_div codec_pll_div[] = {
|
||||||
{128000, 22579200, 1, 529, 1},
|
{128000, 22579200, 1, 529, 1},
|
||||||
|
@ -463,7 +464,7 @@ static const struct pll_div codec_pll_div[] = {
|
||||||
{6000000, 24576000, 25, 307, 1},
|
{6000000, 24576000, 25, 307, 1},
|
||||||
{13000000, 24576000, 42, 238, 1},
|
{13000000, 24576000, 42, 238, 1},
|
||||||
{19200000, 24576000, 25, 96, 0},
|
{19200000, 24576000, 25, 96, 0},
|
||||||
{24000000, 24576000, 39, 119, 4},/*((119 + 4 * 0.2) * 24000000) / (39 * (2 * 1 + 1)) */
|
{24000000, 24576000, 25, 76, 4},/* accurate */
|
||||||
{11289600, 22579200, 1, 6, 0},
|
{11289600, 22579200, 1, 6, 0},
|
||||||
{12288000, 24576000, 1, 6, 0},
|
{12288000, 24576000, 1, 6, 0},
|
||||||
};
|
};
|
||||||
|
@ -536,8 +537,10 @@ int ac101_aif_mute(struct snd_soc_dai *codec_dai, int mute)
|
||||||
ac101_headphone_event(codec, SND_SOC_DAPM_PRE_PMD);
|
ac101_headphone_event(codec, SND_SOC_DAPM_PRE_PMD);
|
||||||
late_enable_dac(codec, SND_SOC_DAPM_POST_PMD);
|
late_enable_dac(codec, SND_SOC_DAPM_POST_PMD);
|
||||||
|
|
||||||
|
#if _MASTER_MULTI_CODEC != _MASTER_AC101
|
||||||
ac10x->aif1_clken = 1;
|
ac10x->aif1_clken = 1;
|
||||||
ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD);
|
ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -604,6 +607,7 @@ static int ac101_set_pll(struct snd_soc_dai *codec_dai, int pll_id, int source,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*config pll m*/
|
/*config pll m*/
|
||||||
|
if (m == 64) m = 0;
|
||||||
ac101_update_bits(codec, PLL_CTRL1, (0x3f<<PLL_POSTDIV_M), (m<<PLL_POSTDIV_M));
|
ac101_update_bits(codec, PLL_CTRL1, (0x3f<<PLL_POSTDIV_M), (m<<PLL_POSTDIV_M));
|
||||||
/*config pll n*/
|
/*config pll n*/
|
||||||
ac101_update_bits(codec, PLL_CTRL2, (0x3ff<<PLL_PREDIV_NI), (n_i<<PLL_PREDIV_NI));
|
ac101_update_bits(codec, PLL_CTRL2, (0x3ff<<PLL_PREDIV_NI), (n_i<<PLL_PREDIV_NI));
|
||||||
|
@ -702,6 +706,8 @@ int ac101_hw_params(struct snd_pcm_substream *substream,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ac101_update_bits(codec, AIF_CLK_CTRL, (0xf<<AIF1_BCLK_DIV), i<<AIF1_BCLK_DIV);
|
ac101_update_bits(codec, AIF_CLK_CTRL, (0xf<<AIF1_BCLK_DIV), i<<AIF1_BCLK_DIV);
|
||||||
|
} else {
|
||||||
|
ac101_set_pll(codec_dai, AC101_MCLK1, 0, ac10x->sysclk, freq_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
AC101_DBG("rate: %d , channels: %d , samp_res: %d",
|
AC101_DBG("rate: %d , channels: %d , samp_res: %d",
|
||||||
|
@ -766,6 +772,10 @@ int ac101_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
|
||||||
case SND_SOC_DAIFMT_DSP_A: /* L reg_val msb after FRM LRC */
|
case SND_SOC_DAIFMT_DSP_A: /* L reg_val msb after FRM LRC */
|
||||||
reg_val |= (0x3<<AIF1_DATA_FMT);
|
reg_val |= (0x3<<AIF1_DATA_FMT);
|
||||||
break;
|
break;
|
||||||
|
case SND_SOC_DAIFMT_DSP_B:
|
||||||
|
/* TODO: data offset set to 0 */
|
||||||
|
reg_val |= (0x3<<AIF1_DATA_FMT);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("%s, line:%d\n", __func__, __LINE__);
|
pr_err("%s, line:%d\n", __func__, __LINE__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -814,6 +824,9 @@ static int ac101_set_clock(int y_start_n_stop) {
|
||||||
if (y_start_n_stop) {
|
if (y_start_n_stop) {
|
||||||
/* enable global clock */
|
/* enable global clock */
|
||||||
ac101_aif1clk(static_ac10x->codec, SND_SOC_DAPM_PRE_PMU);
|
ac101_aif1clk(static_ac10x->codec, SND_SOC_DAPM_PRE_PMU);
|
||||||
|
} else {
|
||||||
|
static_ac10x->aif1_clken = 1;
|
||||||
|
ac101_aif1clk(static_ac10x->codec, SND_SOC_DAPM_POST_PMD);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
31
ac108.c
31
ac108.c
|
@ -104,7 +104,7 @@ static const struct pll_div ac108_pll_div_list[] = {
|
||||||
{ 16000000, 24576000, 12, 0, 400, 9, 1 },
|
{ 16000000, 24576000, 12, 0, 400, 9, 1 },
|
||||||
{ 19200000, 24576000, 15, 0, 410, 9, 1 },
|
{ 19200000, 24576000, 15, 0, 410, 9, 1 },
|
||||||
{ 19680000, 24576000, 15, 0, 400, 9, 1 },
|
{ 19680000, 24576000, 15, 0, 400, 9, 1 },
|
||||||
{ 24000000, 24576000, 9, 0, 205, 9, 1 },
|
{ 24000000, 24576000, 4, 0, 128,24, 0 }, //accurate
|
||||||
|
|
||||||
{ 400000, 22579200, 0, 0, 566, 4, 1 },
|
{ 400000, 22579200, 0, 0, 566, 4, 1 },
|
||||||
{ 512000, 22579200, 0, 0, 880, 9, 1 },
|
{ 512000, 22579200, 0, 0, 880, 9, 1 },
|
||||||
|
@ -122,7 +122,7 @@ static const struct pll_div ac108_pll_div_list[] = {
|
||||||
{ 16000000, 22579200, 11, 0, 340, 9, 1 },
|
{ 16000000, 22579200, 11, 0, 340, 9, 1 },
|
||||||
{ 19200000, 22579200, 13, 0, 330, 9, 1 },
|
{ 19200000, 22579200, 13, 0, 330, 9, 1 },
|
||||||
{ 19680000, 22579200, 14, 0, 345, 9, 1 },
|
{ 19680000, 22579200, 14, 0, 345, 9, 1 },
|
||||||
{ 24000000, 22579200, 16, 0, 320, 9, 1 },
|
{ 24000000, 22579200, 24, 0, 588,24, 0 }, // accurate
|
||||||
|
|
||||||
{ 12288000, 24576000, 9, 0, 400, 9, 1 }, //24576000/2
|
{ 12288000, 24576000, 9, 0, 400, 9, 1 }, //24576000/2
|
||||||
{ 11289600, 22579200, 9, 0, 400, 9, 1 }, //22579200/2
|
{ 11289600, 22579200, 9, 0, 400, 9, 1 }, //22579200/2
|
||||||
|
@ -216,12 +216,11 @@ static int snd_ac108_get_volsw(struct snd_kcontrol *kcontrol,
|
||||||
if ((ret = ac10x_read(mc->reg, &val, ac10x->i2cmap[chip])) < 0)
|
if ((ret = ac10x_read(mc->reg, &val, ac10x->i2cmap[chip])) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
val = (val >> mc->shift) & mask;
|
val = ((val >> mc->shift) & mask) - mc->min;
|
||||||
ucontrol->value.integer.value[0] = val - mc->min;
|
|
||||||
if (invert) {
|
if (invert) {
|
||||||
ucontrol->value.integer.value[0] =
|
val = mc->max - val;
|
||||||
mc->max - ucontrol->value.integer.value[0];
|
|
||||||
}
|
}
|
||||||
|
ucontrol->value.integer.value[0] = val;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -725,9 +724,12 @@ static int ac108_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_h
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
unsigned div;
|
||||||
|
|
||||||
/*TDM mode or normal mode*/
|
/*TDM mode or normal mode*/
|
||||||
ac108_multi_chips_write(I2S_LRCK_CTRL2, ac108_samp_res[samp_res].real_val * channels - 1, ac10x);
|
div = ac108_samp_res[samp_res].real_val * channels - 1;
|
||||||
ac108_multi_chips_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, 0x00, ac10x);
|
ac108_multi_chips_write(I2S_LRCK_CTRL2, (div & 0xFF), ac10x);
|
||||||
|
ac108_multi_chips_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, (div >> 8) << 0, ac10x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -869,11 +871,10 @@ static int ac108_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) {
|
||||||
tx_offset = 0;
|
tx_offset = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ac10x->i2s_mode = LEFT_JUSTIFIED_FORMAT;
|
|
||||||
tx_offset = 1;
|
|
||||||
return -EINVAL;
|
|
||||||
pr_err("AC108 I2S format config error:%u\n\n", fmt & SND_SOC_DAIFMT_FORMAT_MASK);
|
pr_err("AC108 I2S format config error:%u\n\n", fmt & SND_SOC_DAIFMT_FORMAT_MASK);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*AC108 config BCLK&LRCK polarity*/
|
/*AC108 config BCLK&LRCK polarity*/
|
||||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||||
case SND_SOC_DAIFMT_NB_NF:
|
case SND_SOC_DAIFMT_NB_NF:
|
||||||
|
@ -957,6 +958,7 @@ static int ac108_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) {
|
||||||
/*
|
/*
|
||||||
* due to miss channels order in cpu_dai, we meed defer the clock starting.
|
* due to miss channels order in cpu_dai, we meed defer the clock starting.
|
||||||
*/
|
*/
|
||||||
|
#if _MASTER_MULTI_CODEC == _MASTER_AC108
|
||||||
static int ac108_set_clock(int y_start_n_stop) {
|
static int ac108_set_clock(int y_start_n_stop) {
|
||||||
u8 r;
|
u8 r;
|
||||||
|
|
||||||
|
@ -983,6 +985,7 @@ static int ac108_set_clock(int y_start_n_stop) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int ac108_trigger(struct snd_pcm_substream *substream, int cmd,
|
static int ac108_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
struct snd_soc_dai *dai)
|
struct snd_soc_dai *dai)
|
||||||
|
@ -1001,9 +1004,10 @@ static int ac108_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||||
/* disable global clock if lrck disabled */
|
/* disable global clock if lrck disabled */
|
||||||
ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
|
ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
|
||||||
if ((r & (0x01 << LRCK_IOEN)) == 0) {
|
if ((r & (0x02 << LRCK_IOEN)) && (r & (0x01 << LRCK_IOEN)) == 0) {
|
||||||
/* disable global clock */
|
/* disable global clock */
|
||||||
ac108_multi_chips_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x0 << GEN, ac10x);
|
ac108_multi_chips_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x1 << TXEN | 0x0 << GEN, ac10x);
|
||||||
|
}
|
||||||
|
|
||||||
/*0x21: Module clock enable<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
|
/*0x21: Module clock enable<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
|
||||||
ac108_multi_chips_write(MOD_CLK_EN, 1 << I2S | 1 << ADC_DIGITAL | 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
|
ac108_multi_chips_write(MOD_CLK_EN, 1 << I2S | 1 << ADC_DIGITAL | 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
|
||||||
|
@ -1012,7 +1016,6 @@ static int ac108_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
ac108_multi_chips_write(MOD_RST_CTRL, 1 << I2S | 1 << ADC_DIGITAL | 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
|
ac108_multi_chips_write(MOD_RST_CTRL, 1 << I2S | 1 << ADC_DIGITAL | 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
|
||||||
|
|
||||||
/* delayed clock starting, move to simple_card_trigger() */
|
/* delayed clock starting, move to simple_card_trigger() */
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
case SNDRV_PCM_TRIGGER_STOP:
|
||||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||||
|
@ -1342,7 +1345,7 @@ static int ac108_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i
|
||||||
if (of_property_read_u32(np, "tdm-chips-count", &val)) val = 1;
|
if (of_property_read_u32(np, "tdm-chips-count", &val)) val = 1;
|
||||||
ac10x->tdm_chips_cnt = val;
|
ac10x->tdm_chips_cnt = val;
|
||||||
|
|
||||||
pr_err(" i2c_id number : %d\n", index);
|
pr_err(" ac10x i2c_id number: %d\n", index);
|
||||||
pr_err(" ac10x data protocol: %d\n", ac10x->data_protocol);
|
pr_err(" ac10x data protocol: %d\n", ac10x->data_protocol);
|
||||||
|
|
||||||
ac10x->i2c[index] = i2c;
|
ac10x->i2c[index] = i2c;
|
||||||
|
|
Loading…
Reference in a new issue