mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
audio: fix tdm audio format
PD#146334: audio: fix tdm bclk and fclk revert and skew issue Change-Id: I1dcb6f8559b3c04a2ddbb7c13a6115001c249c18 Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
@@ -440,8 +440,8 @@
|
||||
format = "i2s";
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
bitclock-inversion;
|
||||
frame-inversion;
|
||||
//bitclock-inversion;
|
||||
//frame-inversion;
|
||||
//bitclock-master = <&aml_tdmb>;
|
||||
//frame-master = <&aml_tdmb>;
|
||||
cpu {
|
||||
@@ -461,8 +461,8 @@
|
||||
format = "i2s";
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
bitclock-inversion;
|
||||
frame-inversion;
|
||||
//bitclock-inversion;
|
||||
//frame-inversion;
|
||||
//bitclock-master = <&aml_tdmc>;
|
||||
//frame-master = <&aml_tdmc>;
|
||||
cpu {
|
||||
@@ -479,13 +479,7 @@
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@3 {
|
||||
format = "i2s";
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
//bitclock-inversion;
|
||||
//frame-inversion;
|
||||
bitclock-master = <&aml_pdm>;
|
||||
frame-master = <&aml_pdm>;
|
||||
cpu {
|
||||
sound-dai = <&aml_pdm>;
|
||||
};
|
||||
@@ -495,12 +489,9 @@
|
||||
};
|
||||
|
||||
aml-audio-card,dai-link@4 {
|
||||
//format = "i2s";
|
||||
mclk-fs = <128>;
|
||||
continuous-clock;
|
||||
cpu {
|
||||
sound-dai = <&aml_spdif>;
|
||||
system-clock-frequency = <12288000>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&dummy_codec>;
|
||||
|
||||
@@ -480,7 +480,7 @@
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
//bitclock-inversion;
|
||||
frame-inversion;
|
||||
//frame-inversion;
|
||||
bitclock-master = <&aml_tdmb>;
|
||||
frame-master = <&aml_tdmb>;
|
||||
cpu {
|
||||
@@ -506,7 +506,7 @@
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
//bitclock-inversion;
|
||||
frame-inversion;
|
||||
//frame-inversion;
|
||||
//bitclock-master = <&aml_tdmc>;
|
||||
//frame-master = <&aml_tdmc>;
|
||||
cpu {
|
||||
@@ -912,8 +912,8 @@
|
||||
aml_tdma: tdma {
|
||||
compatible = "amlogic, snd-tdma";
|
||||
#sound-dai-cells = <0>;
|
||||
dai-tdm-lane-slot-mask-in = <1>;
|
||||
dai-tdm-lane-slot-mask-out = <1>;
|
||||
dai-tdm-lane-slot-mask-in = <1 0>;
|
||||
dai-tdm-lane-slot-mask-out = <0 1>;
|
||||
dai-tdm-clk-sel = <0>;
|
||||
tdm_from_ddr = <0>;
|
||||
tdm_to_ddr = <0>;
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
mclk-fs = <256>;
|
||||
continuous-clock;
|
||||
//bitclock-inversion;
|
||||
frame-inversion;
|
||||
//frame-inversion;
|
||||
bitclock-master = <&aml_tdmb>;
|
||||
frame-master = <&aml_tdmb>;
|
||||
cpu {
|
||||
@@ -388,7 +388,7 @@
|
||||
continuous-clock;
|
||||
/* tdmb clk using tdmc so no bclk-inv */
|
||||
//bitclock-inversion;
|
||||
frame-inversion;
|
||||
//frame-inversion;
|
||||
bitclock-master = <&aml_tdmc>;
|
||||
frame-master = <&aml_tdmc>;
|
||||
cpu {
|
||||
@@ -762,7 +762,7 @@
|
||||
dai-tdm-clk-sel = <0>;
|
||||
tdm_from_ddr = <0>;
|
||||
tdm_to_ddr = <0>;
|
||||
clocks = <&clkc CLKID_MPLL2>;
|
||||
clocks = <&clkc CLKID_MPLL0>;
|
||||
//&clkaudio CLKID_AUDIO_TDMOUTA
|
||||
//&clkaudio CLKID_AUDIO_MCLK_A>;
|
||||
clock-names = "mpll0", "gate", "mclk";
|
||||
|
||||
@@ -336,8 +336,6 @@ static int aml_dai_tdm_startup(struct snd_pcm_substream *substream,
|
||||
struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
int ret;
|
||||
|
||||
aml_tdm_fifo_reset(p_tdm->actrl, substream->stream, p_tdm->id);
|
||||
|
||||
ret = clk_prepare_enable(p_tdm->clk);
|
||||
if (ret) {
|
||||
pr_err("Can't enable mpll clock: %d\n", ret);
|
||||
@@ -624,7 +622,9 @@ static int aml_dai_set_tdm_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
|
||||
fmt, p_tdm, p_tdm->id, p_tdm->clk_sel);
|
||||
|
||||
aml_tdm_set_format(p_tdm->actrl,
|
||||
&(p_tdm->setting), p_tdm->clk_sel, p_tdm->id, fmt);
|
||||
&(p_tdm->setting), p_tdm->clk_sel, p_tdm->id, fmt,
|
||||
cpu_dai->capture_active,
|
||||
cpu_dai->playback_active);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,13 @@
|
||||
|
||||
#include "tdm_hw.h"
|
||||
|
||||
#define MST_CLK_INVERT_PH0_PAD_BCLK (1 << 0)
|
||||
#define MST_CLK_INVERT_PH0_PAD_FCLK (1 << 1)
|
||||
#define MST_CLK_INVERT_PH1_TDMIN_BCLK (1 << 2)
|
||||
#define MST_CLK_INVERT_PH1_TDMIN_FCLK (1 << 3)
|
||||
#define MST_CLK_INVERT_PH2_TDMOUT_BCLK (1 << 4)
|
||||
#define MST_CLK_INVERT_PH2_TDMOUT_FCLK (1 << 5)
|
||||
|
||||
void aml_tdm_enable(
|
||||
struct aml_audio_controller *actrl,
|
||||
int stream, int index,
|
||||
@@ -80,22 +87,19 @@ void aml_tdm_fifo_ctrl(
|
||||
int bitwidth, int stream,
|
||||
int index)
|
||||
{
|
||||
unsigned int frddr_type, toddr_type;
|
||||
unsigned int frddr_type;
|
||||
unsigned int reg, offset;
|
||||
|
||||
switch (bitwidth) {
|
||||
case 8:
|
||||
frddr_type = 0;
|
||||
toddr_type = 0;
|
||||
break;
|
||||
case 16:
|
||||
frddr_type = 2;
|
||||
toddr_type = 2;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
frddr_type = 4;
|
||||
toddr_type = 4;
|
||||
break;
|
||||
default:
|
||||
pr_err("invalid bit_depth: %d\n",
|
||||
@@ -123,20 +127,26 @@ void aml_tdm_set_format(
|
||||
struct pcm_setting *p_config,
|
||||
unsigned int clk_sel,
|
||||
unsigned int index,
|
||||
unsigned int fmt)
|
||||
unsigned int fmt,
|
||||
unsigned int capture_active,
|
||||
unsigned int playback_active)
|
||||
{
|
||||
unsigned int binv, finv, id;
|
||||
unsigned int valb, valf;
|
||||
unsigned int reg_in, reg_out, off_set;
|
||||
int bclkin_skew, bclkout_skew;
|
||||
int master_mode;
|
||||
unsigned int clkctl = 0;
|
||||
|
||||
id = index;
|
||||
|
||||
binv = 0;
|
||||
finv = 0;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
valb = SLAVE_A + id;
|
||||
valf = SLAVE_A;
|
||||
valf = SLAVE_A + id;
|
||||
master_mode = 0;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
@@ -162,28 +172,47 @@ void aml_tdm_set_format(
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
bclkout_skew = 1;
|
||||
bclkin_skew = 3;
|
||||
|
||||
clkctl |= MST_CLK_INVERT_PH0_PAD_FCLK;
|
||||
if (!master_mode)
|
||||
finv = 1;
|
||||
|
||||
if (master_mode) {
|
||||
bclkout_skew = 1;
|
||||
bclkin_skew = 3;
|
||||
clkctl |= MST_CLK_INVERT_PH0_PAD_BCLK;
|
||||
if (capture_active)
|
||||
binv |= 1;
|
||||
} else {
|
||||
bclkout_skew = 2;
|
||||
bclkin_skew = 3;
|
||||
if (playback_active)
|
||||
binv |= 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
if (master_mode) {
|
||||
bclkout_skew = 1;
|
||||
bclkin_skew = 4;
|
||||
} else {
|
||||
bclkout_skew = 2;
|
||||
bclkin_skew = 3;
|
||||
}
|
||||
/*
|
||||
* Frame high, 1clk before data, one bit for frame sync,
|
||||
* frame sync starts one serial clock cycle earlier,
|
||||
* that is, together with the last bit of the previous
|
||||
* data word.
|
||||
*/
|
||||
bclkout_skew = 1;
|
||||
bclkin_skew = 3;
|
||||
|
||||
if (capture_active)
|
||||
binv |= 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
//TODO: need test
|
||||
/*
|
||||
* Frame high, one bit for frame sync,
|
||||
* frame sync asserts with the first bit of the frame.
|
||||
*/
|
||||
bclkout_skew = 2;
|
||||
bclkin_skew = 2;
|
||||
|
||||
if (capture_active)
|
||||
binv |= 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -191,69 +220,91 @@ void aml_tdm_set_format(
|
||||
|
||||
p_config->pcm_mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
|
||||
|
||||
pr_info("pad clk ctl value:%x\n", clkctl);
|
||||
/* set lrclk/bclk invertion */
|
||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
case SND_SOC_DAIFMT_IB_IF:
|
||||
/* Invert both clocks */
|
||||
binv = 1;
|
||||
finv = 1;
|
||||
if (!master_mode)
|
||||
binv ^= 1;
|
||||
|
||||
finv |= 1;
|
||||
clkctl ^= MST_CLK_INVERT_PH0_PAD_BCLK;
|
||||
clkctl ^= MST_CLK_INVERT_PH0_PAD_FCLK;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
/* Invert bit clock */
|
||||
binv = 1;
|
||||
finv = 0;
|
||||
if (!master_mode)
|
||||
binv ^= 1;
|
||||
clkctl ^= MST_CLK_INVERT_PH0_PAD_BCLK;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_NB_IF:
|
||||
/* Invert frame clock */
|
||||
binv = 0;
|
||||
finv = 1;
|
||||
finv ^= 1;
|
||||
clkctl ^= MST_CLK_INVERT_PH0_PAD_FCLK;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_NB_NF:
|
||||
/* normal cases */
|
||||
binv = 0;
|
||||
finv = 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
pr_info("sclk_ph0 (pad) clk ctl set:%x\n", clkctl);
|
||||
/* clk ctrl: delay line and invert clk */
|
||||
/*clkctl |= 0x88880000;*/
|
||||
if (master_mode) {
|
||||
off_set = EE_AUDIO_MST_B_SCLK_CTRL1 - EE_AUDIO_MST_A_SCLK_CTRL1;
|
||||
reg_out = EE_AUDIO_MST_A_SCLK_CTRL1 + off_set * id;
|
||||
|
||||
aml_audiobus_update_bits(actrl, reg_out, 0x3f, clkctl);
|
||||
}
|
||||
|
||||
pr_info("master_mode(%d), binv(%d), finv(%d) out_skew(%d), in_skew(%d)\n",
|
||||
master_mode, binv, finv, bclkout_skew, bclkin_skew);
|
||||
|
||||
/* TDM out */
|
||||
reg_out = EE_AUDIO_CLK_TDMOUT_A_CTRL + id;
|
||||
aml_audiobus_update_bits(actrl, reg_out,
|
||||
0x3<<30|0x1<<29, 0x3<<30/*|binv<<29*/);
|
||||
// sclk_ph0 (pad) invert
|
||||
off_set = EE_AUDIO_MST_B_SCLK_CTRL1 - EE_AUDIO_MST_A_SCLK_CTRL1;
|
||||
reg_out = EE_AUDIO_MST_A_SCLK_CTRL1 + off_set * id;
|
||||
aml_audiobus_update_bits(actrl, reg_out, 0x3f, !binv);
|
||||
if (!binv)
|
||||
bclkin_skew = 4;
|
||||
if (playback_active) {
|
||||
|
||||
off_set = EE_AUDIO_TDMOUT_B_CTRL0 - EE_AUDIO_TDMOUT_A_CTRL0;
|
||||
reg_out = EE_AUDIO_TDMOUT_A_CTRL0 + off_set * id;
|
||||
aml_audiobus_update_bits(actrl, reg_out, 0x1f<<15, bclkout_skew<<15);
|
||||
reg_out = EE_AUDIO_CLK_TDMOUT_A_CTRL + id;
|
||||
aml_audiobus_update_bits(actrl, reg_out,
|
||||
0x3<<30, 0x3<<30);
|
||||
|
||||
off_set = EE_AUDIO_TDMOUT_B_CTRL1 - EE_AUDIO_TDMOUT_A_CTRL1;
|
||||
reg_out = EE_AUDIO_TDMOUT_A_CTRL1 + off_set * id;
|
||||
aml_audiobus_update_bits(actrl, reg_out, 0x1<<28, finv<<28);
|
||||
aml_audiobus_update_bits(actrl, reg_out,
|
||||
0x1<<29, binv<<29);
|
||||
|
||||
off_set = EE_AUDIO_TDMOUT_B_CTRL1 - EE_AUDIO_TDMOUT_A_CTRL1;
|
||||
reg_out = EE_AUDIO_TDMOUT_A_CTRL1 + off_set * id;
|
||||
aml_audiobus_update_bits(actrl, reg_out, 0x1<<28, finv<<28);
|
||||
|
||||
off_set = EE_AUDIO_TDMOUT_B_CTRL0 - EE_AUDIO_TDMOUT_A_CTRL0;
|
||||
reg_out = EE_AUDIO_TDMOUT_A_CTRL0 + off_set * id;
|
||||
aml_audiobus_update_bits(actrl, reg_out,
|
||||
0x1f<<15, bclkout_skew<<15);
|
||||
}
|
||||
|
||||
/* TDM in */
|
||||
reg_in = EE_AUDIO_CLK_TDMIN_A_CTRL + id;
|
||||
aml_audiobus_update_bits(actrl, reg_in,
|
||||
0x3<<30|0x1<<29, 0x3<<30|binv<<29);
|
||||
|
||||
off_set = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL;
|
||||
reg_in = EE_AUDIO_TDMIN_A_CTRL + off_set * id;
|
||||
if (p_config->pcm_mode == SND_SOC_DAIFMT_I2S)
|
||||
if (capture_active) {
|
||||
reg_in = EE_AUDIO_CLK_TDMIN_A_CTRL + id;
|
||||
aml_audiobus_update_bits(actrl, reg_in,
|
||||
1<<30|3<<26|0x1<<25|0x7<<16,
|
||||
1<<30|3<<26|1<<25|bclkin_skew<<16);
|
||||
else
|
||||
0x3<<30, 0x3<<30);
|
||||
|
||||
if (master_mode)
|
||||
aml_audiobus_update_bits(actrl, reg_in,
|
||||
0x1<<29, binv<<29);
|
||||
|
||||
off_set = EE_AUDIO_TDMIN_B_CTRL - EE_AUDIO_TDMIN_A_CTRL;
|
||||
reg_in = EE_AUDIO_TDMIN_A_CTRL + off_set * id;
|
||||
aml_audiobus_update_bits(actrl, reg_in,
|
||||
3<<26|0x7<<16, 3<<26|bclkin_skew<<16);
|
||||
|
||||
aml_audiobus_update_bits(actrl, reg_in,
|
||||
0x1<<25, finv<<25);
|
||||
|
||||
if (p_config->pcm_mode == SND_SOC_DAIFMT_I2S)
|
||||
aml_audiobus_update_bits(actrl, reg_in,
|
||||
1<<30,
|
||||
1<<30);
|
||||
}
|
||||
}
|
||||
|
||||
void aml_tdm_set_slot(
|
||||
|
||||
@@ -59,7 +59,9 @@ extern void aml_tdm_set_format(
|
||||
struct pcm_setting *p_config,
|
||||
unsigned int clk_sel,
|
||||
unsigned int index,
|
||||
unsigned int fmt);
|
||||
unsigned int fmt,
|
||||
unsigned int capture_active,
|
||||
unsigned int playback_active);
|
||||
|
||||
extern void aml_tdm_set_slot(
|
||||
struct aml_audio_controller *actrl,
|
||||
|
||||
Reference in New Issue
Block a user