rk3288-hdmi: fix i2s audio output no sound

This commit is contained in:
zwl
2014-03-30 16:05:02 +08:00
parent 51d93b269a
commit 5d5387e982
2 changed files with 26 additions and 5 deletions

View File

@@ -807,7 +807,8 @@ static void rk3288_hdmi_config_aai(struct hdmi *hdmi_drv, struct hdmi_audio *aud
int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
{
int word_length = 0, channel = 0, N = 0, mclk_fs;
int word_length = 0, channel = 0, mclk_fs;
unsigned int N = 0, CTS = 0;
struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
if(audio->channel < 3)
@@ -829,6 +830,8 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
N = N_32K_MIDCLK;
else
N = N_32K_LOWCLK;
CTS = CALC_CTS(N, hdmi_drv->tmdsclk/1000, 32); //div a num to avoid the value is exceed 2^32(int)
break;
case HDMI_AUDIO_FS_44100:
mclk_fs = FS_256;
@@ -838,6 +841,8 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
N = N_441K_MIDCLK;
else
N = N_441K_LOWCLK;
CTS = CALC_CTS(N, hdmi_drv->tmdsclk/100, 441);
break;
case HDMI_AUDIO_FS_48000:
mclk_fs = FS_256;
@@ -847,6 +852,8 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
N = N_48K_MIDCLK;
else
N = N_48K_LOWCLK;
CTS = CALC_CTS(N, hdmi_drv->tmdsclk/1000, 48);
break;
case HDMI_AUDIO_FS_88200:
mclk_fs = FS_256;
@@ -856,6 +863,8 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
N = N_882K_MIDCLK;
else
N = N_882K_LOWCLK;
CTS = CALC_CTS(N, hdmi_drv->tmdsclk/100, 882);
break;
case HDMI_AUDIO_FS_96000:
mclk_fs = FS_256;
@@ -865,6 +874,8 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
N = N_96K_MIDCLK;
else
N = N_96K_LOWCLK;
CTS = CALC_CTS(N, hdmi_drv->tmdsclk/1000, 96);
break;
case HDMI_AUDIO_FS_176400:
mclk_fs = FS_256;
@@ -874,6 +885,8 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
N = N_1764K_MIDCLK;
else
N = N_1764K_LOWCLK;
CTS = CALC_CTS(N, hdmi_drv->tmdsclk/100, 1764);
break;
case HDMI_AUDIO_FS_192000:
mclk_fs = FS_256;
@@ -883,6 +896,8 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
N = N_192K_MIDCLK;
else
N = N_192K_LOWCLK;
CTS = CALC_CTS(N, hdmi_drv->tmdsclk/1000, 192);
break;
default:
hdmi_err(hdmi_drv->dev, "[%s] not support such sample rate %d\n", __FUNCTION__, audio->rate);
@@ -904,9 +919,10 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
word_length = I2S_16BIT_SAMPLE;
}
hdmi_dbg(hdmi_drv->dev, "rate = %d, tmdsclk = %d, N = %d, CTS = %d\n", audio->rate, hdmi_drv->tmdsclk, N, CTS);
/* more than 2 channels => layout 1 else layout 0 */
//value = (audio->channel > 2) ? 1 : 0; //TODO Daisen wait to modify
hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, m_AUD_PACK_LAYOUT, v_AUD_PACK_LAYOUT(1));
//hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, m_AUD_PACK_LAYOUT, v_AUD_PACK_LAYOUT(value));
if(hdmi_drv->audio.type == INPUT_SPDIF) {
hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_I2S_SEL, v_I2S_SEL(AUDIO_SPDIF_GPA));
@@ -916,7 +932,7 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
hdmi_msk_reg(hdmi_dev, AUD_SPDIF0, m_SW_SAUD_FIFO_RST, v_SW_SAUD_FIFO_RST(1));
}
else {
hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_I2S_SEL | m_I2S_IN_EN, v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(0x0f));
hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_I2S_SEL | m_I2S_IN_EN, v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(channel));
hdmi_writel(hdmi_dev, AUD_CONF1, v_I2S_MODE(I2S_STANDARD_MODE) | v_I2S_WIDTH(word_length));
//Mask fifo empty and full int and reset fifo
hdmi_msk_reg(hdmi_dev, AUD_INT, m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK, v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
@@ -929,8 +945,11 @@ int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16));
hdmi_writel(hdmi_dev, AUD_N2, (N >> 8) & 0xff);
hdmi_writel(hdmi_dev, AUD_N1, N & 0xff);
//Set Automatic CTS generation
hdmi_msk_reg(hdmi_dev, AUD_CTS3, m_CTS_MANUAL, v_CTS_MANUAL(0));
//Set CTS by manual
hdmi_msk_reg(hdmi_dev, AUD_CTS3, m_N_SHIFT | m_CTS_MANUAL | m_AUD_CTS3,
v_N_SHIFT(N_SHIFT_1) | v_CTS_MANUAL(1) | v_AUD_CTS3(CTS >> 16));
hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff);
hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff);
hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE, v_AUDCLK_DISABLE(0));
rk3288_hdmi_config_aai(hdmi_drv, audio);

View File

@@ -851,6 +851,8 @@ enum I2S_WIDTH {
#define N_192K_LOWCLK 0x6000
#define N_192K_MIDCLK 0x5000
#define N_192K_HIGHCLK 0x6000
#define CALC_CTS(N, TMDSCLK, FS) ((N) / 128) * (TMDSCLK) / (FS)
/****************************************/
#define AUD_N1 0x3200