return NULL;
}
+static void rk3288_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
+{
+ if(hdmi_drv->pwr_mode == mode)
+ return;
+
+ hdmi_dbg(hdmi->dev,"%s change pwr_mode %d --> %d\n",__FUNCTION__, hdmi_drv->pwr_mode, mode);
+ switch(mode)
+ {
+ case NORMAL:
+ hdmi_msk_reg(hdmi_dev, MC_SWRSTZREQ, m_TMDS_SWRST | m_PIXEL_SWRST,
+ v_TMDS_SWRST(0) | v_PIXEL_SWRST(0));
+ hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE | m_PREPCLK_DISABLE | m_TMDSCLK_DISABLE | m_PIXELCLK_DISABLE,
+ v_AUDCLK_DISABLE(0) | v_PREPCLK_DISABLE(0) | v_TMDSCLK_DISABLE(0) | v_PIXELCLK_DISABLE(0));
+ hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_TXPWRON_SIG, v_TXPWRON_SIG(1));
+ hdmi_msk_reg(hdmi_dev, FC_GCP, m_FC_SET_AVMUTE, v_FC_SET_AVMUTE(1));
+ break;
+ case LOWER_PWR:
+ hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE | m_PREPCLK_DISABLE | m_TMDSCLK_DISABLE | m_PIXELCLK_DISABLE,
+ v_AUDCLK_DISABLE(1) | v_PREPCLK_DISABLE(1) | v_TMDSCLK_DISABLE(1) | v_PIXELCLK_DISABLE(1));
+ hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_TXPWRON_SIG, v_TXPWRON_SIG(0));
+ break;
+ default:
+ hdmi_dbg(hdmi_drv->dev,"unkown hdmi pwr mode %d\n",mode);
+ }
+ hdmi_drv->pwr_mode = mode;
+}
//i2c master reset
void rk3288_hdmi_i2cm_reset(struct rk3288_hdmi_device *hdmi_dev)
y1y0 = AVI_COLOR_MODE_YCBCR444;
else if(output_color == VIDEO_OUTPUT_YCBCR422)
y1y0 = AVI_COLOR_MODE_YCBCR422;
+ else if(output_color == VIDEO_OUTPUT_YCBCR420)
+ y1y0 = AVI_COLOR_MODE_YCBCR420;
else
y1y0 = AVI_COLOR_MODE_RGB;
if( ((vpara->input_color == VIDEO_INPUT_COLOR_RGB) && (vpara->output_color == VIDEO_OUTPUT_RGB444)) ||
((vpara->input_color == VIDEO_INPUT_COLOR_YCBCR) && (vpara->output_color != VIDEO_OUTPUT_RGB444) ))
{
+ hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(0));
return;
}
hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]);
//enable CSC TODO Daisen wait to add
+ hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, m_FEED_THROUGH_OFF, v_FEED_THROUGH_OFF(1));
}
int de_pol = hdmi_drv->lcdc->cur_screen->pin_den;
struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
+ if(hdmi_drv->pwr_mode == LOWER_PWR)
+ rk3288_hdmi_set_pwr_mode(NORMAL);
+
switch(vpara->input_color)
{
case VIDEO_OUTPUT_RGB444:
static void rk3288_hdmi_config_aai(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
{
- //struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
+ struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
+
+ //Refer to CEA861-E Audio infoFrame
+ //Set both Audio Channel Count and Audio Coding Type Refer to Stream Head for HDMI
+ hdmi_msk_reg(hdmi_dev, FC_AUDICONF0, m_FC_CHN_CNT | m_FC_CODING_TYEP, v_FC_CHN_CNT(0) | v_FC_CODING_TYEP(0));
+
+ //Set both Audio Sample Size and Sample Frequency Refer to Stream Head for HDMI
+ hdmi_msk_reg(hdmi_dev, FC_AUDICONF1, m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ, v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0));
- //hdmi_writel(hdmi_dev, FC_AUDICONF0, m_FC_CHN_CNT | m_FC_CODING_TYEP, v_FC_CHN_CNT(audio->channel) | v_FC_CODING_TYEP());
+ //Set Channel Allocation
+ hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00);
- //TODO Daisen wait to add
+ //Set LFEPBL¡¢DOWN-MIX INH and LSV
+ hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00);
}
int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
{
- int word_length = 0,channel = 0,N = 0;
+ int word_length = 0, channel = 0, N = 0, mclk_fs;
struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
if(audio->channel < 3) //TODO Daisen
switch(audio->rate)
{
case HDMI_AUDIO_FS_32000:
+ mclk_fs = FS_128;
if(hdmi_drv->tmdsclk >= 594000000)
N = N_32K_HIGHCLK;
else if(hdmi_drv->tmdsclk == 297000000)
N = N_32K_LOWCLK;
break;
case HDMI_AUDIO_FS_44100:
+ mclk_fs = FS_128;
if(hdmi_drv->tmdsclk >= 594000000)
N = N_441K_HIGHCLK;
else if(hdmi_drv->tmdsclk == 297000000)
N = N_441K_LOWCLK;
break;
case HDMI_AUDIO_FS_48000:
- if(hdmi_drv->tmdsclk >= 594000000)
+ mclk_fs = FS_128;
+ if(hdmi_drv->tmdsclk >= 594000000) //FS_153.6
N = N_48K_HIGHCLK;
else if(hdmi_drv->tmdsclk == 297000000)
N = N_48K_MIDCLK;
N = N_48K_LOWCLK;
break;
case HDMI_AUDIO_FS_88200:
+ mclk_fs = FS_128;
if(hdmi_drv->tmdsclk >= 594000000)
N = N_882K_HIGHCLK;
else if(hdmi_drv->tmdsclk == 297000000)
N = N_882K_LOWCLK;
break;
case HDMI_AUDIO_FS_96000:
- if(hdmi_drv->tmdsclk >= 594000000)
+ mclk_fs = FS_128;
+ if(hdmi_drv->tmdsclk >= 594000000) //FS_153.6
N = N_96K_HIGHCLK;
else if(hdmi_drv->tmdsclk == 297000000)
N = N_96K_MIDCLK;
N = N_96K_LOWCLK;
break;
case HDMI_AUDIO_FS_176400:
+ mclk_fs = FS_128;
if(hdmi_drv->tmdsclk >= 594000000)
N = N_1764K_HIGHCLK;
else if(hdmi_drv->tmdsclk == 297000000)
N = N_1764K_LOWCLK;
break;
case HDMI_AUDIO_FS_192000:
- if(hdmi_drv->tmdsclk >= 594000000)
+ mclk_fs = FS_128;
+ if(hdmi_drv->tmdsclk >= 594000000) //FS_153.6
N = N_192K_HIGHCLK;
else if(hdmi_drv->tmdsclk == 297000000)
N = N_192K_MIDCLK;
hdmi_writel(hdmi_dev, AUD_CONF1, v_I2S_MODE(I2S_STANDARD_MODE) | v_I2S_WIDTH(word_length));
}
- hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS, m_LFS_FACTOR, v_LFS_FACTOR(FS_128));
+ hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS, m_LFS_FACTOR, v_LFS_FACTOR(mclk_fs));
//Set N value
hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16));
//Set Automatic CTS generation
hdmi_msk_reg(hdmi_dev, AUD_CTS3, m_CTS_MANUAL, v_CTS_MANUAL(0));
+ hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE, v_AUDCLK_DISABLE(0));
rk3288_hdmi_config_aai(hdmi_drv, audio);
return 0;
void rk3288_hdmi_control_output(struct hdmi *hdmi_drv, int enable)
{
+ struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
+ hdmi_dbg(hdmi_drv->dev, "[%s] %d\n", __FUNCTION__, enable);
+ if(enable == 0) {
+ hdmi_msk_reg(hdmi_dev, FC_GCP, m_FC_SET_AVMUTE, v_FC_SET_AVMUTE(1));
+ }
+ else {
+ if(hdmi_drv->pwr_mode == LOWER_PWR)
+ rk3288_hdmi_set_pwr_mode(NORMAL);
+ hdmi_msk_reg(hdmi_dev, FC_GCP, m_FC_SET_AVMUTE, v_FC_SET_AVMUTE(0));
+ }
}
int rk3288_hdmi_removed(struct hdmi *hdmi_drv)
{
+ rk3288_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
+ dev_printk(KERN_INFO , hdmi_drv->dev , "Removed.\n");
return 0;
}