int rk610_hdmi_sys_init(struct hdmi *hdmi) { // System power power off HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_OFF | v_INT_POL_HIGH); //Synchronize analog module. // HDMIWrReg(PHY_SYNC, 0x00); // HDMIWrReg(PHY_SYNC, 0x01); // set hdmi phy parameters // driver mode HDMIWrReg(PHY_DRIVER, v_MAIN_DRIVER(8)| v_PRE_DRIVER(0) | v_TX_ENABLE(0)); // HDMIWrReg(PHY_PRE_EMPHASIS, 0x04); HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(1)); //Driver power down // pll mode HDMIWrReg(0xe8, 0x10); HDMIWrReg(0xe6, 0x2c); #if 0 HDMIWrReg(PHY_PLL_CTRL, 0); #else HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(1) | v_PLL_RESET(1) | v_TMDS_RESET(1)); HDMIWrReg(PHY_PLL_LDO_PWR, v_LDO_PWR_DOWN(1)); HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_DOWN); #endif // Enable Hotplug interrupt HDMIWrReg(INTERRUPT_MASK1, m_INT_HOTPLUG); return HDMI_ERROR_SUCESS; }
static void rk2928_hdmi_config_avi(unsigned char vic, unsigned char output_color) { int i; char info[SIZE_AVI_INFOFRAME]; memset(info, 0, SIZE_AVI_INFOFRAME); HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); info[0] = 0x82; info[1] = 0x02; info[2] = 0x0D; info[3] = info[0] + info[1] + info[2]; info[4] = (AVI_COLOR_MODE_RGB << 5); info[5] = (AVI_COLORIMETRY_NO_DATA << 6) | (AVI_CODED_FRAME_ASPECT_NO_DATA << 4) | ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME; info[6] = 0; info[7] = vic; info[8] = 0; // Calculate AVI InfoFrame ChecKsum for (i = 4; i < SIZE_AVI_INFOFRAME; i++) { info[3] += info[i]; } info[3] = 0x100 - info[3]; for(i = 0; i < SIZE_AVI_INFOFRAME; i++) HDMIWrReg(CONTROL_PACKET_ADDR + i, info[i]); }
static void rk30_hdmi_config_avi(unsigned char vic, unsigned char output_color) { int i, clolorimetry, aspect_ratio; char info[SIZE_AVI_INFOFRAME]; memset(info, 0, SIZE_AVI_INFOFRAME); HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI); info[0] = 0x82; info[1] = 0x02; info[2] = 0x0D; info[3] = info[0] + info[1] + info[2]; if(output_color == VIDEO_OUTPUT_YCBCR444) info[4] = (AVI_COLOR_MODE_YCBCR444 << 5); else if(output_color == VIDEO_OUTPUT_YCBCR422) info[4] = (AVI_COLOR_MODE_YCBCR422 << 5); else info[4] = (AVI_COLOR_MODE_RGB << 5); info[4] |= (1 << 4); //Enable active format data bits is present in info[2] switch(vic) { case HDMI_720x480i_60Hz_4_3: case HDMI_720x576i_50Hz_4_3: case HDMI_720x480p_60Hz_4_3: case HDMI_720x576p_50Hz_4_3: aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3; clolorimetry = AVI_COLORIMETRY_SMPTE_170M; break; case HDMI_720x480i_60Hz_16_9: case HDMI_720x576i_50Hz_16_9: case HDMI_720x480p_60Hz_16_9: case HDMI_720x576p_50Hz_16_9: aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9; clolorimetry = AVI_COLORIMETRY_SMPTE_170M; break; default: aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9; clolorimetry = AVI_COLORIMETRY_ITU709; } if(output_color == VIDEO_OUTPUT_RGB444) clolorimetry = AVI_COLORIMETRY_NO_DATA; info[5] = (clolorimetry << 6) | (aspect_ratio << 4) | ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME; info[6] = 0; info[7] = vic; info[8] = 0; // Calculate AVI InfoFrame ChecKsum for (i = 4; i < SIZE_AVI_INFOFRAME; i++) { info[3] += info[i]; } info[3] = 0x100 - info[3]; for(i = 0; i < SIZE_AVI_INFOFRAME; i++) HDMIWrReg(CONTROL_PACKET_HB0 + i*4, info[i]); }
static inline void rk30_hdmi_config_phy_reg(int reg, int value) { HDMIWrReg(reg, value); HDMIWrReg(SYS_CTRL, 0x2C); delay100us(); HDMIWrReg(SYS_CTRL, 0x20); msleep(1); }
int rk610_hdmi_sys_insert(struct hdmi *hdmi) { //Bring up analog module. HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_UP); //BG power on HDMIWrReg(PHY_PLL_LDO_PWR, 0x00); //PLL power on msleep(1); HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(0)); //Analog reset return 0; }
int rk610_hdmi_sys_insert(void) { hdmi_dbg(hdmi->dev, "%s \n", __FUNCTION__); //Bring up analog module. HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_UP); //BG power on HDMIWrReg(PHY_PLL_LDO_PWR, 0x00); //PLL power on msleep(1); HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(0)); //Analog reset return 0; }
int rk610_hdmi_sys_remove(struct hdmi *hdmi) { if(rk610_hdmi->hdcp_power_off_cb) rk610_hdmi->hdcp_power_off_cb(); HDMIWrReg(PHY_DRIVER, v_MAIN_DRIVER(8)| v_PRE_DRIVER(0) | v_TX_ENABLE(0)); HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(1)); //Driver power down HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(1) | v_PLL_RESET(1) | v_TMDS_RESET(1)); HDMIWrReg(PHY_PLL_LDO_PWR, v_LDO_PWR_DOWN(1)); HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_DOWN); return 0; }
int rk610_hdmi_sys_remove(void) { hdmi_dbg(hdmi->dev, "%s \n", __FUNCTION__); if(hdmi->hdcp_power_off_cb) hdmi->hdcp_power_off_cb(); HDMIWrReg(PHY_DRIVER, v_MAIN_DRIVER(8)| v_PRE_DRIVER(0) | v_TX_ENABLE(0)); HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(1)); //Driver power down HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(1) | v_PLL_RESET(1) | v_TMDS_RESET(1)); HDMIWrReg(PHY_PLL_LDO_PWR, v_LDO_PWR_DOWN(1)); HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_DOWN); return 0; }
irqreturn_t hdmi_irq(int irq, void *priv) { char interrupt1 = 0, interrupt2 = 0, interrupt3 = 0, interrupt4 = 0; if(hdmi->pwr_mode == PWR_SAVE_MODE_A) { HDMIWrReg(SYS_CTRL, 0x20); hdmi->pwr_mode = PWR_SAVE_MODE_B; hdmi_dbg(hdmi->dev, "hdmi irq wake up\n"); // HDMI was inserted when system is sleeping, irq was triggered only once // when wake up. So we need to check hotplug status. if(HDMIRdReg(HPD_MENS_STA) & (m_HOTPLUG_STATUS | m_MSEN_STATUS)) { queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); } } else { interrupt1 = HDMIRdReg(INTR_STATUS1); interrupt2 = HDMIRdReg(INTR_STATUS2); interrupt3 = HDMIRdReg(INTR_STATUS3); interrupt4 = HDMIRdReg(INTR_STATUS4); HDMIWrReg(INTR_STATUS1, interrupt1); // HDMIWrReg(INTR_STATUS2, interrupt2); // HDMIWrReg(INTR_STATUS3, interrupt3); // HDMIWrReg(INTR_STATUS4, interrupt4); #if 0 hdmi_dbg(hdmi->dev, "[%s] interrupt1 %02x interrupt2 %02x interrupt3 %02x interrupt4 %02x\n",\ __FUNCTION__, interrupt1, interrupt2, interrupt3, interrupt4); #endif if(interrupt1 & (m_INT_HOTPLUG | m_INT_MSENS)) { if(hdmi->state == HDMI_SLEEP) hdmi->state = WAIT_HOTPLUG; interrupt1 &= ~(m_INT_HOTPLUG | m_INT_MSENS); queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); } else if(interrupt1 & (m_INT_EDID_READY | m_INT_EDID_ERR)) { spin_lock(&hdmi->irq_lock); edid_result = interrupt1; spin_unlock(&hdmi->irq_lock); } // else if(hdmi->state == HDMI_SLEEP) { // RK30DBG( "hdmi return to sleep mode\n"); // HDMIWrReg(SYS_CTRL, 0x10); // rk30_hdmi->pwr_mode = PWR_SAVE_MODE_A; // } if(hdmi->hdcp_irq_cb) hdmi->hdcp_irq_cb(interrupt2); } return IRQ_HANDLED; }
irqreturn_t hdmi_irq(int irq, void *priv) { char interrupt1 = 0; unsigned long flags; spin_lock_irqsave(&hdmi->irq_lock,flags); interrupt1 = HDMIRdReg(INTERRUPT_STATUS1); HDMIWrReg(INTERRUPT_STATUS1, interrupt1); #if 1 hdmi_dbg(hdmi->dev, "[%s] interrupt1 %02x \n",\ __FUNCTION__, interrupt1); #endif if(interrupt1 & m_INT_HOTPLUG ){ if(hdmi->state == HDMI_SLEEP) hdmi->state = WAIT_HOTPLUG; if(hdmi->pwr_mode == LOWER_PWR) rk2928_hdmi_set_pwr_mode(NORMAL); queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); }else if(interrupt1 & m_INT_EDID_READY) { edid_result = interrupt1; }else if(hdmi->state == HDMI_SLEEP) { hdmi_dbg(hdmi->dev, "hdmi return to sleep mode\n"); rk2928_hdmi_set_pwr_mode(LOWER_PWR); } #if 0 if(hdmi->hdcp_irq_cb) hdmi->hdcp_irq_cb(interrupt2); #endif spin_unlock_irqrestore(&hdmi->irq_lock,flags); return IRQ_HANDLED; }
static void rk30_hdmi_config_csc(struct hdmi_video_para *vpara) { int i, mode; char *coeff = NULL; 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) )) { return; } switch(vpara->vic) { case HDMI_720x480i_60Hz_4_3: case HDMI_720x576i_50Hz_4_3: case HDMI_720x480p_60Hz_4_3: case HDMI_720x576p_50Hz_4_3: case HDMI_720x480i_60Hz_16_9: case HDMI_720x576i_50Hz_16_9: case HDMI_720x480p_60Hz_16_9: case HDMI_720x576p_50Hz_16_9: if(vpara->input_color == VIDEO_INPUT_COLOR_RGB) mode = CSC_RGB_0_255_TO_ITU601_16_235; else if(vpara->output_mode == OUTPUT_HDMI) mode = CSC_ITU601_16_235_TO_RGB_16_235; else mode = CSC_ITU601_16_235_TO_RGB_0_255; break; default: if(vpara->input_color == VIDEO_INPUT_COLOR_RGB) mode = CSC_RGB_0_255_TO_ITU709_16_235; else if(vpara->output_mode == OUTPUT_HDMI) mode = CSC_ITU709_16_235_TO_RGB_16_235; else mode = CSC_ITU709_16_235_TO_RGB_0_255; break; } coeff = coeff_csc[mode]; HDMIWrReg(CSC_CONFIG1, v_CSC_MODE(CSC_MODE_MANUAL) | v_CSC_BRSWAP_DIABLE(1)); for(i = 0; i < 24; i++) HDMIWrReg(CSC_PARA_C0_H + i*4, coeff[i]); HDMIWrReg(AV_CTRL2, v_CSC_ENABLE(1)); }
int rk30_hdmi_removed(void) { if(hdmi->pwr_mode == PWR_SAVE_MODE_E) { HDMIWrReg(VIDEO_SETTING2, 0x00); rk30_hdmi_audio_reset(); rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D); } if(hdmi->pwr_mode == PWR_SAVE_MODE_D) rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B); if(hdmi->pwr_mode == PWR_SAVE_MODE_B && hdmi->state == HDMI_SLEEP) { HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS); HDMIWrReg(INTR_MASK2, 0); HDMIWrReg(INTR_MASK3, 0); HDMIWrReg(INTR_MASK4, 0); // Disable color space convertion HDMIWrReg(AV_CTRL2, v_CSC_ENABLE(0)); HDMIWrReg(CSC_CONFIG1, v_CSC_MODE(CSC_MODE_AUTO) | v_CSC_BRSWAP_DIABLE(1)); if(hdmi->hdcp_power_off_cb) hdmi->hdcp_power_off_cb(); rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_A); } dev_printk(KERN_INFO , hdmi->dev , "Removed.\n"); return HDMI_ERROR_SUCESS; }
void rk610_hdmi_interrupt() { char interrupt = 0; if(rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &interrupt)) return; HDMIWrReg(INTERRUPT_STATUS1, interrupt); hdmi_dbg(rk610_hdmi->hdmi->dev, "%s interrupt %02x\n", __FUNCTION__, interrupt); if(interrupt) HDMIWrReg(INTERRUPT_STATUS1, interrupt); if(interrupt & m_INT_HOTPLUG) hdmi_changed(rk610_hdmi->hdmi, 0); if(interrupt & m_INT_EDID_READY) edid_ready = 1; }
void rk30_hdmi_control_output(int enable) { hdmi_dbg(hdmi->dev, "[%s] %d\n", __FUNCTION__, enable); if(enable == 0) { HDMIWrReg(VIDEO_SETTING2, 0x03); } else { if(hdmi->pwr_mode == PWR_SAVE_MODE_B) { // Switch to power save mode_d rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D); } if(hdmi->pwr_mode == PWR_SAVE_MODE_D) { // Switch to power save mode_e rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_E); } HDMIWrReg(VIDEO_SETTING2, 0x00); rk30_hdmi_audio_reset(); } }
void rk610_hdmi_sys_enalbe_output(int enable) { char mutestatus = 0; if(enable) { rk610_hdmi_i2c_read_reg(AV_MUTE, &mutestatus); if(mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) { HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_ON | v_INT_POL_HIGH); HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_OFF | v_INT_POL_HIGH); HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_ON | v_INT_POL_HIGH); if(hdmi->hdcp_cb) hdmi->hdcp_cb(); } } else { HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); } }
int rk30_hdmi_initial(void) { int rc = HDMI_ERROR_SUCESS; // internal hclk = hdmi_hclk/20 HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV); if(hdmi->hdcp_power_on_cb) rc = hdmi->hdcp_power_on_cb(); return rc; }
static void rk30_hdmi_config_phy(unsigned char vic) { HDMIWrReg(DEEP_COLOR_MODE, 0x22); // tmds frequency same as input dlck rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B); switch(vic) { case HDMI_1920x1080p_60Hz: case HDMI_1920x1080p_50Hz: rk30_hdmi_config_phy_reg(0x158, 0x0E); rk30_hdmi_config_phy_reg(0x15c, 0x00); rk30_hdmi_config_phy_reg(0x160, 0x60); rk30_hdmi_config_phy_reg(0x164, 0x00); rk30_hdmi_config_phy_reg(0x168, 0xDA); rk30_hdmi_config_phy_reg(0x16c, 0xA1); rk30_hdmi_config_phy_reg(0x170, 0x0e); rk30_hdmi_config_phy_reg(0x174, 0x22); rk30_hdmi_config_phy_reg(0x178, 0x00); break; case HDMI_1920x1080i_60Hz: case HDMI_1920x1080i_50Hz: case HDMI_1280x720p_60Hz: case HDMI_1280x720p_50Hz: rk30_hdmi_config_phy_reg(0x158, 0x06); rk30_hdmi_config_phy_reg(0x15c, 0x00); rk30_hdmi_config_phy_reg(0x160, 0x60); rk30_hdmi_config_phy_reg(0x164, 0x00); rk30_hdmi_config_phy_reg(0x168, 0xCA); rk30_hdmi_config_phy_reg(0x16c, 0xA3); rk30_hdmi_config_phy_reg(0x170, 0x0e); rk30_hdmi_config_phy_reg(0x174, 0x20); rk30_hdmi_config_phy_reg(0x178, 0x00); break; case HDMI_720x576p_50Hz_4_3: case HDMI_720x576p_50Hz_16_9: case HDMI_720x480p_60Hz_4_3: case HDMI_720x480p_60Hz_16_9: rk30_hdmi_config_phy_reg(0x158, 0x02); rk30_hdmi_config_phy_reg(0x15c, 0x00); rk30_hdmi_config_phy_reg(0x160, 0x60); rk30_hdmi_config_phy_reg(0x164, 0x00); rk30_hdmi_config_phy_reg(0x168, 0xC2); rk30_hdmi_config_phy_reg(0x16c, 0xA2); rk30_hdmi_config_phy_reg(0x170, 0x0e); rk30_hdmi_config_phy_reg(0x174, 0x20); rk30_hdmi_config_phy_reg(0x178, 0x00); break; default: hdmi_err(hdmi->dev, "not support such vic %d\n", vic); break; } }
static void rk30_hdmi_config_aai(void) { int i; char info[SIZE_AUDIO_INFOFRAME]; memset(info, 0, SIZE_AUDIO_INFOFRAME); info[0] = 0x84; info[1] = 0x01; info[2] = 0x0A; info[3] = info[0] + info[1] + info[2]; for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++) info[3] += info[i]; info[3] = 0x100 - info[3]; HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI); for(i = 0; i < SIZE_AUDIO_INFOFRAME; i++) HDMIWrReg(CONTROL_PACKET_HB0 + i*4, info[i]); }
static void rk30_hdmi_set_pwr_mode(int mode) { if(hdmi->pwr_mode == mode) return; hdmi_dbg(hdmi->dev, "[%s] mode %d\n", __FUNCTION__, mode); switch(mode) { case PWR_SAVE_MODE_A: HDMIWrReg(SYS_CTRL, 0x10); break; case PWR_SAVE_MODE_B: HDMIWrReg(SYS_CTRL, 0x20); break; case PWR_SAVE_MODE_D: // reset PLL A&B HDMIWrReg(SYS_CTRL, 0x4C); delay100us(); // release PLL A reset HDMIWrReg(SYS_CTRL, 0x48); delay100us(); // release PLL B reset HDMIWrReg(SYS_CTRL, 0x40); break; case PWR_SAVE_MODE_E: HDMIWrReg(SYS_CTRL, 0x80); break; } hdmi->pwr_mode = mode; if(mode != PWR_SAVE_MODE_A) msleep(10); hdmi_dbg(hdmi->dev, "[%s] curmode %02x\n", __FUNCTION__, HDMIRdReg(SYS_CTRL)); }
void rk610_hdmi_interrupt() { char interrupt = 0; if(rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &interrupt)) return; HDMIWrReg(INTERRUPT_STATUS1, interrupt); if(interrupt) HDMIWrReg(INTERRUPT_STATUS1, interrupt); if(interrupt & m_INT_HOTPLUG) { hdmi_dbg(hdmi->dev, "%s interrupt %02x\n", __FUNCTION__, interrupt); if(hdmi->state == HDMI_SLEEP) hdmi->state = WAIT_HOTPLUG; queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); } else if(interrupt & m_INT_EDID_READY) { atomic_set(&edid_ready, 1); } }
void rk2928_hdmi_control_output(int enable) { char mutestatus = 0; if(enable) { mutestatus = HDMIRdReg(AV_MUTE); if(mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) { HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); rk2928_hdmi_sys_power_up(); rk2928_hdmi_sys_power_down(); rk2928_hdmi_sys_power_up(); if(analog_sync){ HDMIWrReg(0xce, 0x00); delay100us(); HDMIWrReg(0xce, 0x01); analog_sync = 0; } } } else { HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1)); } }
int rk610_hdmi_sys_read_edid(struct hdmi *hdmi, int block, unsigned char *buff) { char value; int count, rc = HDMI_ERROR_EDID; // Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b) // when reg00 select reg_clk equal to sys_clk which is equal // to i2s clk, it gernerally is 11.2896MHz. count = SYSCLK/(DDC_CLK*4); HDMIWrReg(DDC_CLK_L, count & 0xFF); HDMIWrReg(DDC_CLK_H, (count >> 8) & 0xFF); // Enable EDID Interrupt edid_ready = 0; value = 0; rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value); value |= m_INT_EDID_READY; HDMIWrReg(INTERRUPT_MASK1, value); // Reset FIFO offset HDMIWrReg(EDID_FIFO_OFFSET, 0); // Set EDID read addr. HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80); HDMIWrReg(EDID_SEGMENT_POINTER, block/2); count = 0; while(count++ < 100) { value = 0; rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &value); #ifdef HDMI_USE_IRQ value = edid_ready; #else HDMIWrReg(INTERRUPT_STATUS1, value); #endif if(value | m_INT_EDID_READY) { for(count = 0; count < 128; count++) rk610_hdmi_i2c_read_reg(EDID_FIFO_ADDR, buff + count); rc = HDMI_ERROR_SUCESS; break; } } // Disable EDID interrupt. value = 0; rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value); value &= ~m_INT_EDID_READY; HDMIWrReg(INTERRUPT_MASK1, value); return rc; }
static int CecReadFrame(CEC_FrameData_t *Frame) { int i, length; char *data = Frame; if(Frame == NULL) return -1; length = HDMIRdReg(CEC_RX_LENGTH); HDMIWrReg(CEC_RX_OFFSET, 0); printk("%s length is %d\n", __FUNCTION__, length); for(i = 0; i < length; i++) { data[i] = HDMIRdReg(CEC_DATA); printk("%02x\n", data[i]); } return 0; }
static inline void hdmi_io_remap(void) { unsigned int value; // Remap HDMI IO Pin rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_HDMI_I2C_SDA); rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_HDMI_I2C_SCL); rk30_mux_api_set(GPIO0A0_HDMIHOTPLUGIN_NAME, GPIO0A_HDMI_HOT_PLUG_IN); // Select LCDC0 as video source and enabled. value = (HDMI_SOURCE_DEFAULT << 14) | (1 << 30); writel(value, GRF_SOC_CON0 + RK30_GRF_BASE); // internal hclk = hdmi_hclk/20 HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV); }
int rk610_hdmi_sys_detect_hpd(void) { char hdmi_status = 0; #ifdef HDMI_USE_IRQ rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &hdmi_status); HDMIWrReg(INTERRUPT_STATUS1, hdmi_status); #endif hdmi_status = 0; rk610_hdmi_i2c_read_reg(HDMI_STATUS, &hdmi_status); // printk("%s value is %02x\n", __FUNCTION__, hdmi_status); if(hdmi_status) return HDMI_HPD_ACTIVED; else return HDMI_HPD_REMOVED; }
int rk610_hdmi_sys_detect_hpd(struct hdmi *hdmi, int *hpdstatus) { char hdmi_status = 0; #ifdef HDMI_USE_IRQ rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &hdmi_status); HDMIWrReg(INTERRUPT_STATUS1, hdmi_status); #endif hdmi_status = 0; rk610_hdmi_i2c_read_reg(HDMI_STATUS, &hdmi_status); // printk("%s value is %02x\n", __FUNCTION__, hdmi_status); if(hdmi_status) *hpdstatus = HDMI_RECEIVER_ACTIVE; else *hpdstatus = HDMI_RECEIVER_REMOVE; return HDMI_ERROR_SUCESS; }
int rk610_hdmi_sys_read_edid(int block, unsigned char *buff) { char value; int count, rc = HDMI_ERROR_EDID; int trytime = 2; // Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b) // when reg00 select reg_clk equal to sys_clk which is equal // to i2s clk, it gernerally is 11.2896MHz. count = SYSCLK/(DDC_CLK*4); HDMIWrReg(DDC_CLK_L, count & 0xFF); HDMIWrReg(DDC_CLK_H, (count >> 8) & 0xFF); // Enable EDID Interrupt // edid_ready = 0; atomic_set(&edid_ready, 0); value = 0; rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value); value |= m_INT_EDID_READY; HDMIWrReg(INTERRUPT_MASK1, value); while(trytime--) { // Reset FIFO offset HDMIWrReg(EDID_FIFO_OFFSET, 0); // Set EDID read addr. HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80); HDMIWrReg(EDID_SEGMENT_POINTER, block/2); count = 0; while(count++ < 10) { value = atomic_read(&edid_ready); if(value) { for(count = 0; count < 128; count++) rk610_hdmi_i2c_read_reg(EDID_FIFO_ADDR, buff + count); rc = HDMI_ERROR_SUCESS; break; } msleep(100); } } // Disable EDID interrupt. value = 0; rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value); value &= ~m_INT_EDID_READY; HDMIWrReg(INTERRUPT_MASK1, value); return rc; }
static void rk30_hdmi_early_resume(struct early_suspend *h) { struct rk30_hdmi *rk30_hdmi = container_of(h, struct rk30_hdmi, early_suspend); struct hdmi *hdmi = rk30_hdmi->hdmi; RK30DBG("hdmi exit early resume\n"); rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_HDMI_I2C_SDA); rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_HDMI_I2C_SCL); clk_enable(rk30_hdmi->hclk); // internal hclk = hdmi_hclk/20 HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV); if(hdmi->ops->hdcp_power_on_cb) hdmi->ops->hdcp_power_on_cb(); hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, NULL); return; }
int rk30_hdmi_initial(void) { int rc = HDMI_ERROR_SUCESS; hdmi->pwr_mode = PWR_SAVE_MODE_A; hdmi->remove = rk30_hdmi_removed ; hdmi->control_output = rk30_hdmi_control_output; hdmi->config_video = rk30_hdmi_config_video; hdmi->config_audio = rk30_hdmi_config_audio; hdmi->detect_hotplug = rk30_hdmi_detect_hotplug; hdmi->read_edid = rk30_hdmi_read_edid; // internal hclk = hdmi_hclk/20 HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV); if(hdmi->hdcp_power_on_cb) rc = hdmi->hdcp_power_on_cb(); return rc; }
static int CecSendFrame(CEC_FrameData_t *Frame) { int i; CECDBG("TX srcDestAddr %02x opcode %02x ", Frame->srcDestAddr, Frame->opcode); if(Frame->argCount) { CECDBG("args:"); for(i = 0; i < Frame->argCount; i++) { CECDBG("%02x ", Frame->args[i]); } } CECDBG("\n"); HDMIWrReg(CEC_TX_OFFSET, 0); HDMIWrReg(CEC_DATA, Frame->srcDestAddr); HDMIWrReg(CEC_DATA, Frame->opcode); for(i = 0; i < Frame->argCount; i++) HDMIWrReg(CEC_DATA, Frame->args[i]); HDMIWrReg(CEC_TX_LENGTH, Frame->argCount + 2); //Wait for bus free Cec.busfree = 1; HDMIWrReg(CEC_CTRL, m_BUSFREETIME_ENABLE); if(wait_event_interruptible_timeout(Cec.wait, Cec.busfree == 0, msecs_to_jiffies(17))) { return -1; } //Start TX Cec.tx_done = 0; HDMIWrReg(CEC_CTRL, m_BUSFREETIME_ENABLE|m_START_TX); if(wait_event_interruptible_timeout(Cec.wait, Cec.tx_done != 0, msecs_to_jiffies(100))) HDMIWrReg(CEC_CTRL, 0); if(Cec.tx_done == 1) { return 0; } else return -1; }