int mhl_msc_recv_set_int(struct mhl_tx_ctrl *mhl_ctrl, u8 offset, u8 set_int) { int prior; if (offset >= 2) return -EFAULT; switch (offset) { case 0: if (set_int & MHL_INT_DCAP_CHG) { /* peer dcap has changed */ mhl_ctrl->devcap_state = 0; mhl_msc_read_devcap_all(mhl_ctrl); } if (set_int & MHL_INT_DSCR_CHG) { /* peer's scratchpad reg changed */ pr_debug("%s: dscr chg\n", __func__); mhl_read_scratchpad(mhl_ctrl); mhl_ctrl->scrpd_busy = false; mhl_notify_event(mhl_ctrl, MHL_TX_EVENT_DSCR_CHG); } if (set_int & MHL_INT_REQ_WRT) { /* SET_INT: REQ_WRT */ if (mhl_ctrl->scrpd_busy) { prior = MSC_NORMAL_SEND; } else { prior = MSC_PRIORITY_SEND; mhl_ctrl->scrpd_busy = true; } mhl_msc_send_set_int( mhl_ctrl, MHL_RCHANGE_INT, MHL_INT_GRT_WRT, prior); } if (set_int & MHL_INT_GRT_WRT) { /* SET_INT: GRT_WRT */ pr_debug("%s: recvd req to permit/grant write", __func__); complete_all(&mhl_ctrl->req_write_done); mhl_msc_write_burst( mhl_ctrl, MHL_SCRATCHPAD_OFFSET, mhl_ctrl->scrpd.data, mhl_ctrl->scrpd.length); } break; case 1: if (set_int & MHL_INT_EDID_CHG) { /* peer EDID has changed * toggle HPD to read EDID */ pr_debug("%s: EDID CHG\n", __func__); mhl_drive_hpd(mhl_ctrl, HPD_DOWN); msleep(110); mhl_drive_hpd(mhl_ctrl, HPD_UP); } } return 0; }
void mhl_screen_notify(struct mhl_tx_ctrl *mhl_ctrl, int screen_mode) { if (!mhl_ctrl) { pr_err("%s: invalid input\n", __func__); return; } if (screen_mode) { mhl_ctrl->screen_mode = true; if (mhl_ctrl->cur_state == POWER_STATE_D0_MHL) { if (mhl_ctrl->tmds_ctrl_en) { mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE); mhl_drive_hpd(mhl_ctrl, HPD_UP); } mhl_rap_send_msc_msg(mhl_ctrl, MHL_RAP_CONTENT_ON); } } else { if (!mhl_ctrl->tmds_en_state || !mhl_ctrl->screen_mode) { mhl_ctrl->screen_mode = false; return; } if (mhl_ctrl->cur_state == POWER_STATE_D0_MHL) { mhl_drive_hpd(mhl_ctrl, HPD_DOWN); mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE); mhl_rap_send_msc_msg(mhl_ctrl, MHL_RAP_CONTENT_OFF); } /* NACK any RAP call until chagne to screen on */ mhl_ctrl->screen_mode = false; } }
static int mhl_rap_action(struct mhl_tx_ctrl *mhl_ctrl, u8 action_code) { switch (action_code) { case MHL_RAP_CONTENT_ON: if (!mhl_ctrl->tmds_en_state) { /* * not only enabling tmds * send power button press to wake up the device */ if (!mhl_ctrl->screen_mode) mhl_send_power_key_event(mhl_ctrl); mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE); mhl_drive_hpd(mhl_ctrl, HPD_UP); } break; case MHL_RAP_CONTENT_OFF: if (mhl_ctrl->tmds_en_state && mhl_ctrl->screen_mode) { mhl_drive_hpd(mhl_ctrl, HPD_DOWN); mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE); /* NACK any RAP call until change to screen on */ mhl_ctrl->screen_mode = false; /* * instead of only disabling tmds * send power button press - CONTENT_OFF */ mhl_send_power_key_event(mhl_ctrl); } break; default: break; } return 0; }
int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl, struct msc_command_struct *req) { bool dongle_pwr_en = false; switch (req->command) { case MHL_WRITE_STAT: if (req->offset == MHL_STATUS_REG_LINK_MODE) { if (req->payload.data[0] & MHL_STATUS_PATH_ENABLED) { /* Enable TMDS output */ mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE); if (mhl_ctrl->devcap_state == MHL_DEVCAP_ALL) { dongle_pwr_en = mhl_ctrl->devcap[ MHL_DEV_CATEGORY_OFFSET] & MHL_DEV_CATEGORY_POW_BIT; if (dongle_pwr_en) mhl_drive_hpd(mhl_ctrl, HPD_UP); } } else { /* Disable TMDS output */ mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE); mhl_drive_hpd(mhl_ctrl, HPD_DOWN); } } break; case MHL_READ_DEVCAP: mhl_update_devcap(mhl_ctrl, req->offset, req->retval); mhl_ctrl->devcap_state |= BIT(req->offset); switch (req->offset) { case MHL_DEV_CATEGORY_OFFSET: if (req->retval & MHL_DEV_CATEGORY_POW_BIT) pr_debug("%s: devcap pow bit set\n", __func__); else pr_debug("%s: devcap pow bit unset\n", __func__); break; case DEVCAP_OFFSET_RESERVED: mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE); mhl_drive_hpd(mhl_ctrl, HPD_UP); break; case DEVCAP_OFFSET_MHL_VERSION: case DEVCAP_OFFSET_INT_STAT_SIZE: if (mhl_qualify_path_enable(mhl_ctrl)) mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE); break; } break; case MHL_WRITE_BURST: mhl_msc_send_set_int( mhl_ctrl, MHL_RCHANGE_INT, MHL_INT_DSCR_CHG, MSC_PRIORITY_SEND); break; } return 0; }
int mhl_msc_command_done(struct mhl_tx_ctrl *mhl_ctrl, struct msc_command_struct *req) { switch (req->command) { case MHL_WRITE_STAT: if (req->offset == MHL_STATUS_REG_LINK_MODE) { if (req->payload.data[0] & MHL_STATUS_PATH_ENABLED) { /* Enable TMDS output */ mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE); if (mhl_ctrl->devcap_state == MHL_DEVCAP_ALL) { mhl_drive_hpd(mhl_ctrl, HPD_UP); mhl_ctrl->tmds_ctrl_en = true; } } else { /* Disable TMDS output */ mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE); mhl_drive_hpd(mhl_ctrl, HPD_DOWN); } } break; case MHL_READ_DEVCAP: mhl_update_devcap(mhl_ctrl, req->offset, req->retval); mhl_ctrl->devcap_state |= BIT(req->offset); switch (req->offset) { case MHL_DEV_CATEGORY_OFFSET: if (req->retval & MHL_DEV_CATEGORY_POW_BIT) pr_debug("%s: devcap pow bit set\n", __func__); else pr_debug("%s: devcap pow bit unset\n", __func__); power_supply_set_present(&mhl_ctrl->mhl_psy, !!(req->retval & MHL_DEV_CATEGORY_POW_BIT)); break; case DEVCAP_OFFSET_FEATURE_FLAG: mhl_rap_send_msc_msg(mhl_ctrl, MHL_RAP_CONTENT_ON); break; case DEVCAP_OFFSET_RESERVED: if (mhl_qualify_path_enable(mhl_ctrl)) { mhl_tmds_ctrl(mhl_ctrl, TMDS_ENABLE); mhl_drive_hpd(mhl_ctrl, HPD_UP); mhl_ctrl->tmds_ctrl_en = true; } break; } break; case MHL_WRITE_BURST: mhl_msc_send_set_int( mhl_ctrl, MHL_RCHANGE_INT, MHL_INT_DSCR_CHG, MSC_PRIORITY_SEND); break; } return 0; }
static void mhl_hpd_stat_isr(struct mhl_tx_ctrl *mhl_ctrl) { uint8_t intr_1_stat; uint8_t cbus_stat; struct i2c_client *client = mhl_ctrl->i2c_handle; /* INTR STATUS 1 */ intr_1_stat = MHL_SII_PAGE0_RD(0x0071); if (!intr_1_stat) return; /* Clear interrupts */ MHL_SII_PAGE0_WR(0x0071, intr_1_stat); if (BIT6 & intr_1_stat) { /* * HPD status change event is pending * Read CBUS HPD status for this info * MSC REQ ABRT REASON */ cbus_stat = MHL_SII_CBUS_RD(0x0D); if (BIT6 & cbus_stat) mhl_drive_hpd(mhl_ctrl, HPD_UP); } return; }
static void switch_mode(enum mhl_st_type to_mode) { unsigned long flags; switch (to_mode) { case POWER_STATE_D0_NO_MHL: break; case POWER_STATE_D0_MHL: mhl_init_reg_settings(true); mhl_i2c_reg_modify(TX_PAGE_3, 0x0010, BIT1 | BIT0, BIT0); mhl_i2c_reg_modify(TX_PAGE_TPI, 0x001E, BIT1 | BIT0, 0x00); break; case POWER_STATE_D3: if (mhl_msm_state->cur_state != POWER_STATE_D3) { mhl_drive_hpd(HPD_DOWN); mhl_i2c_reg_write(TX_PAGE_3, 0x0030, 0xD0); msleep(50); mhl_i2c_reg_modify(TX_PAGE_3, 0x0010, BIT1 | BIT0, 0x00); mhl_i2c_reg_modify(TX_PAGE_3, 0x003D, BIT0, 0x00); spin_lock_irqsave(&mhl_state_lock, flags); mhl_msm_state->cur_state = POWER_STATE_D3; spin_unlock_irqrestore(&mhl_state_lock, flags); } break; default: break; } }
static void int_1_isr(void) { /* This ISR mainly handles the HPD status changes */ uint8_t intr_1_stat; uint8_t cbus_stat; /* INTR STATUS 1 */ intr_1_stat = mhl_i2c_reg_read(TX_PAGE_L0, 0x0071); if (intr_1_stat) { /* Clear interrupts */ mhl_i2c_reg_write(TX_PAGE_L0, 0x0071, intr_1_stat); if (BIT6 & intr_1_stat) { /* * HPD status change event is pending * Read CBUS HPD status for this info */ /* MSC REQ ABRT REASON */ cbus_stat = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0D); if (BIT6 & cbus_stat) mhl_drive_hpd(HPD_UP); } } return; }
static void mhl_msm_disconnection(void) { mhl_i2c_reg_write(TX_PAGE_3, 0x30, 0xD0); mhl_drive_hpd(HPD_DOWN); switch_mode(POWER_STATE_D3); return; }
static void switch_mode(struct mhl_tx_ctrl *mhl_ctrl, enum mhl_st_type to_mode, bool hpd_off) { struct i2c_client *client = mhl_ctrl->i2c_handle; unsigned long flags; int rc; struct msm_hdmi_mhl_ops *hdmi_mhl_ops = mhl_ctrl->hdmi_mhl_ops; pr_debug("%s: tx pwr on\n", __func__); spin_lock_irqsave(&mhl_ctrl->lock, flags); mhl_ctrl->tx_powered_off = false; spin_unlock_irqrestore(&mhl_ctrl->lock, flags); switch (to_mode) { case POWER_STATE_D0_NO_MHL: mhl_ctrl->cur_state = to_mode; mhl_init_reg_settings(mhl_ctrl, true); /* REG_DISC_CTRL1 */ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, BIT0); /* TPI_DEVICE_POWER_STATE_CTRL_REG */ mhl_i2c_reg_modify(client, TX_PAGE_TPI, 0x001E, BIT1 | BIT0, 0x00); break; case POWER_STATE_D0_MHL: mhl_ctrl->cur_state = to_mode; break; case POWER_STATE_D3: if (mhl_ctrl->cur_state == POWER_STATE_D3) { pr_debug("%s: mhl tx already in low power mode\n", __func__); break; } /* Force HPD to 0 when not in MHL mode. */ mhl_drive_hpd(mhl_ctrl, HPD_DOWN); mhl_tmds_ctrl(mhl_ctrl, TMDS_DISABLE); /* * Change TMDS termination to high impedance * on disconnection. */ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0xD0); msleep(50); if (!mhl_ctrl->disc_enabled) MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, 0x00); if (hdmi_mhl_ops && hpd_off) { rc = hdmi_mhl_ops->set_upstream_hpd( mhl_ctrl->pdata->hdmi_pdev, 0); pr_debug("%s: hdmi unset hpd %s\n", __func__, rc ? "failed" : "passed"); } mhl_ctrl->cur_state = POWER_STATE_D3; break; default: break; } }
void mhl_tmds_ctrl(struct mhl_tx_ctrl *mhl_ctrl, uint8_t on) { struct i2c_client *client = mhl_ctrl->i2c_handle; if (on) { MHL_SII_REG_NAME_MOD(REG_TMDS_CCTRL, BIT4, BIT4); mhl_drive_hpd(mhl_ctrl, HPD_UP); } else { MHL_SII_REG_NAME_MOD(REG_TMDS_CCTRL, BIT4, 0x00); } }
static void mhl_msm_disconnection(void) { /* * MHL TX CTL1 * Disabling Tx termination */ mhl_i2c_reg_write(TX_PAGE_3, 0x30, 0xD0); /* Change HPD line to drive it low */ mhl_drive_hpd(HPD_DOWN); /* switch power state to D3 */ switch_mode(POWER_STATE_D3); return; }
static void mhl_hpd_stat_isr(struct mhl_tx_ctrl *mhl_ctrl) { uint8_t intr_1_stat, cbus_stat, t; unsigned long flags; struct i2c_client *client = mhl_ctrl->i2c_handle; if (!is_mhl_powered(mhl_ctrl)) return; /* INTR STATUS 1 */ intr_1_stat = MHL_SII_PAGE0_RD(0x0071); if (!intr_1_stat) return; /* Clear interrupts */ MHL_SII_PAGE0_WR(0x0071, intr_1_stat); if (BIT6 & intr_1_stat) { /* * HPD status change event is pending * Read CBUS HPD status for this info * MSC REQ ABRT REASON */ cbus_stat = MHL_SII_CBUS_RD(0x0D); pr_debug("%s: cbus_stat=[0x%02x] cur_pwr=[%u]\n", __func__, cbus_stat, mhl_ctrl->cur_state); spin_lock_irqsave(&mhl_ctrl->lock, flags); t = mhl_ctrl->dwnstream_hpd; spin_unlock_irqrestore(&mhl_ctrl->lock, flags); if (BIT6 & (cbus_stat ^ t)) { u8 status = cbus_stat & BIT6; mhl_drive_hpd(mhl_ctrl, status ? HPD_UP : HPD_DOWN); if (!status) { MHL_SII_PAGE1_MOD(0x003D, BIT0, 0x00); spin_lock_irqsave(&mhl_ctrl->lock, flags); mhl_ctrl->tx_powered_off = true; spin_unlock_irqrestore(&mhl_ctrl->lock, flags); } spin_lock_irqsave(&mhl_ctrl->lock, flags); mhl_ctrl->dwnstream_hpd = cbus_stat; spin_unlock_irqrestore(&mhl_ctrl->lock, flags); } } }
static void switch_mode(enum mhl_st_type to_mode) { unsigned long flags; switch (to_mode) { case POWER_STATE_D0_NO_MHL: break; case POWER_STATE_D0_MHL: mhl_init_reg_settings(true); /* REG_DISC_CTRL1 */ mhl_i2c_reg_modify(TX_PAGE_3, 0x0010, BIT1 | BIT0, BIT0); /* * TPI_DEVICE_POWER_STATE_CTRL_REG * TX_POWER_STATE_MASK = BIT1 | BIT0 */ mhl_i2c_reg_modify(TX_PAGE_TPI, 0x001E, BIT1 | BIT0, 0x00); break; case POWER_STATE_D3: if (mhl_msm_state->cur_state != POWER_STATE_D3) { /* Force HPD to 0 when not in MHL mode. */ mhl_drive_hpd(HPD_DOWN); /* * Change TMDS termination to high impedance * on disconnection. */ mhl_i2c_reg_write(TX_PAGE_3, 0x0030, 0xD0); msleep(50); mhl_i2c_reg_modify(TX_PAGE_3, 0x0010, BIT1 | BIT0, 0x00); mhl_i2c_reg_modify(TX_PAGE_3, 0x003D, BIT0, 0x00); spin_lock_irqsave(&mhl_state_lock, flags); mhl_msm_state->cur_state = POWER_STATE_D3; spin_unlock_irqrestore(&mhl_state_lock, flags); } break; default: break; } }
static void int_1_isr(void) { uint8_t intr_1_stat; uint8_t cbus_stat; intr_1_stat = mhl_i2c_reg_read(TX_PAGE_L0, 0x0071); if (intr_1_stat) { mhl_i2c_reg_write(TX_PAGE_L0, 0x0071, intr_1_stat); if (BIT6 & intr_1_stat) { cbus_stat = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0D); if (BIT6 & cbus_stat) mhl_drive_hpd(HPD_UP); } } return; }
static void switch_mode(struct mhl_tx_ctrl *mhl_ctrl, enum mhl_st_type to_mode) { struct i2c_client *client = mhl_ctrl->i2c_handle; switch (to_mode) { case POWER_STATE_D0_NO_MHL: mhl_ctrl->cur_state = to_mode; mhl_init_reg_settings(mhl_ctrl, true); /* REG_DISC_CTRL1 */ MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, BIT0); /* TPI_DEVICE_POWER_STATE_CTRL_REG */ mhl_i2c_reg_modify(client, TX_PAGE_TPI, 0x001E, BIT1 | BIT0, 0x00); break; case POWER_STATE_D0_MHL: mhl_ctrl->cur_state = to_mode; break; case POWER_STATE_D3: if (mhl_ctrl->cur_state == POWER_STATE_D3) break; /* Force HPD to 0 when not in MHL mode. */ mhl_drive_hpd(mhl_ctrl, HPD_DOWN); /* * Change TMDS termination to high impedance * on disconnection. */ MHL_SII_REG_NAME_WR(REG_MHLTX_CTL1, 0xD0); msleep(50); if (!mhl_ctrl->disc_enabled) MHL_SII_REG_NAME_MOD(REG_DISC_CTRL1, BIT1 | BIT0, 0x00); MHL_SII_PAGE3_MOD(0x003D, BIT0, 0x00); mhl_ctrl->cur_state = POWER_STATE_D3; break; default: break; } }
static void mhl_init_reg_settings(bool mhl_disc_en) { mhl_i2c_reg_write(TX_PAGE_L1, 0x003D, 0x3F); msleep(50); mhl_i2c_reg_write(TX_PAGE_2, 0x0011, 0x01); mhl_i2c_reg_write(TX_PAGE_2, 0x0012, 0x11); mhl_i2c_reg_write(TX_PAGE_3, 0x0030, 0x10); mhl_i2c_reg_write(TX_PAGE_3, 0x0035, 0xAC); mhl_i2c_reg_write(TX_PAGE_3, 0x0031, 0x3C); mhl_i2c_reg_write(TX_PAGE_3, 0x0033, 0xD9); mhl_i2c_reg_write(TX_PAGE_3, 0x0037, 0x02); mhl_i2c_reg_write(TX_PAGE_L0, 0x0080, 0x00); mhl_i2c_reg_write(TX_PAGE_L0, 0x00F8, 0x0C); mhl_i2c_reg_write(TX_PAGE_L0, 0x0085, 0x02); mhl_i2c_reg_write(TX_PAGE_2, 0x0000, 0x00); mhl_i2c_reg_write(TX_PAGE_2, 0x0013, 0x60); mhl_i2c_reg_write(TX_PAGE_2, 0x0017, 0x03); mhl_i2c_reg_write(TX_PAGE_2, 0x001A, 0x20); mhl_i2c_reg_write(TX_PAGE_2, 0x0022, 0xE0); mhl_i2c_reg_write(TX_PAGE_2, 0x0023, 0xC0); mhl_i2c_reg_write(TX_PAGE_2, 0x0024, 0xA0); mhl_i2c_reg_write(TX_PAGE_2, 0x0025, 0x80); mhl_i2c_reg_write(TX_PAGE_2, 0x0026, 0x60); mhl_i2c_reg_write(TX_PAGE_2, 0x0027, 0x40); mhl_i2c_reg_write(TX_PAGE_2, 0x0028, 0x20); mhl_i2c_reg_write(TX_PAGE_2, 0x0029, 0x00); mhl_i2c_reg_write(TX_PAGE_2, 0x0031, 0x0A); mhl_i2c_reg_write(TX_PAGE_2, 0x0045, 0x06); mhl_i2c_reg_write(TX_PAGE_2, 0x004B, 0x06); mhl_i2c_reg_write(TX_PAGE_2, 0x004C, 0xE0); mhl_i2c_reg_write(TX_PAGE_2, 0x004D, 0x00); mhl_i2c_reg_write(TX_PAGE_L0, 0x0008, 0x35); mhl_i2c_reg_write(TX_PAGE_3, 0x0011, 0xAD); mhl_i2c_reg_write(TX_PAGE_3, 0x0014, 0x55); mhl_i2c_reg_write(TX_PAGE_3, 0x0015, 0x11); mhl_i2c_reg_write(TX_PAGE_3, 0x0017, 0x82); mhl_i2c_reg_write(TX_PAGE_3, 0x0018, 0x24); mhl_i2c_reg_write(TX_PAGE_3, 0x0013, 0x8C); if (mhl_disc_en) mhl_i2c_reg_write(TX_PAGE_3, 0x0010, 0x27); else mhl_i2c_reg_write(TX_PAGE_3, 0x0010, 0x26); mhl_i2c_reg_write(TX_PAGE_3, 0x0016, 0x20); mhl_i2c_reg_write(TX_PAGE_3, 0x0012, 0x86); if (mhl_msm_state->cur_state != POWER_STATE_D0_MHL) mhl_drive_hpd(HPD_DOWN); mhl_i2c_reg_write(TX_PAGE_3, 0x0000, 0x084); mhl_i2c_reg_write(TX_PAGE_L0, 0x000D, 0x1C); cbus_reset(); init_cbus_regs(); }
/* * Configure the initial reg settings */ static void mhl_init_reg_settings(bool mhl_disc_en) { /* * ============================================ * POWER UP * ============================================ */ /* Power up 1.2V core */ mhl_i2c_reg_write(TX_PAGE_L1, 0x003D, 0x3F); /* * Wait for the source power to be enabled * before enabling pll clocks. */ msleep(50); /* Enable Tx PLL Clock */ mhl_i2c_reg_write(TX_PAGE_2, 0x0011, 0x01); /* Enable Tx Clock Path and Equalizer */ mhl_i2c_reg_write(TX_PAGE_2, 0x0012, 0x11); /* Tx Source Termination ON */ mhl_i2c_reg_write(TX_PAGE_3, 0x0030, 0x10); /* Enable 1X MHL Clock output */ mhl_i2c_reg_write(TX_PAGE_3, 0x0035, 0xAC); /* Tx Differential Driver Config */ mhl_i2c_reg_write(TX_PAGE_3, 0x0031, 0x3C); mhl_i2c_reg_write(TX_PAGE_3, 0x0033, 0xD9); /* PLL Bandwidth Control */ mhl_i2c_reg_write(TX_PAGE_3, 0x0037, 0x02); /* * ============================================ * Analog PLL Control * ============================================ */ /* Enable Rx PLL clock */ mhl_i2c_reg_write(TX_PAGE_L0, 0x0080, 0x00); mhl_i2c_reg_write(TX_PAGE_L0, 0x00F8, 0x0C); mhl_i2c_reg_write(TX_PAGE_L0, 0x0085, 0x02); mhl_i2c_reg_write(TX_PAGE_2, 0x0000, 0x00); mhl_i2c_reg_write(TX_PAGE_2, 0x0013, 0x60); /* PLL Cal ref sel */ mhl_i2c_reg_write(TX_PAGE_2, 0x0017, 0x03); /* VCO Cal */ mhl_i2c_reg_write(TX_PAGE_2, 0x001A, 0x20); /* Auto EQ */ mhl_i2c_reg_write(TX_PAGE_2, 0x0022, 0xE0); mhl_i2c_reg_write(TX_PAGE_2, 0x0023, 0xC0); mhl_i2c_reg_write(TX_PAGE_2, 0x0024, 0xA0); mhl_i2c_reg_write(TX_PAGE_2, 0x0025, 0x80); mhl_i2c_reg_write(TX_PAGE_2, 0x0026, 0x60); mhl_i2c_reg_write(TX_PAGE_2, 0x0027, 0x40); mhl_i2c_reg_write(TX_PAGE_2, 0x0028, 0x20); mhl_i2c_reg_write(TX_PAGE_2, 0x0029, 0x00); /* Rx PLL Bandwidth 4MHz */ mhl_i2c_reg_write(TX_PAGE_2, 0x0031, 0x0A); /* Rx PLL Bandwidth value from I2C */ mhl_i2c_reg_write(TX_PAGE_2, 0x0045, 0x06); mhl_i2c_reg_write(TX_PAGE_2, 0x004B, 0x06); /* Manual zone control */ mhl_i2c_reg_write(TX_PAGE_2, 0x004C, 0xE0); /* PLL Mode value */ mhl_i2c_reg_write(TX_PAGE_2, 0x004D, 0x00); mhl_i2c_reg_write(TX_PAGE_L0, 0x0008, 0x35); /* * Discovery Control and Status regs * Setting De-glitch time to 50 ms (default) * Switch Control Disabled */ mhl_i2c_reg_write(TX_PAGE_3, 0x0011, 0xAD); /* 1.8V CBUS VTH */ mhl_i2c_reg_write(TX_PAGE_3, 0x0014, 0x55); /* RGND and single Discovery attempt */ mhl_i2c_reg_write(TX_PAGE_3, 0x0015, 0x11); /* Ignore VBUS */ mhl_i2c_reg_write(TX_PAGE_3, 0x0017, 0x82); mhl_i2c_reg_write(TX_PAGE_3, 0x0018, 0x24); /* Pull-up resistance off for IDLE state */ mhl_i2c_reg_write(TX_PAGE_3, 0x0013, 0x8C); /* Enable CBUS Discovery */ if (mhl_disc_en) /* Enable MHL Discovery */ mhl_i2c_reg_write(TX_PAGE_3, 0x0010, 0x27); else /* Disable MHL Discovery */ mhl_i2c_reg_write(TX_PAGE_3, 0x0010, 0x26); mhl_i2c_reg_write(TX_PAGE_3, 0x0016, 0x20); /* MHL CBUS Discovery - immediate comm. */ mhl_i2c_reg_write(TX_PAGE_3, 0x0012, 0x86); /* Do not force HPD to 0 during wake-up from D3 */ if (mhl_msm_state->cur_state != POWER_STATE_D0_MHL) mhl_drive_hpd(HPD_DOWN); /* Enable Auto Soft RESET */ mhl_i2c_reg_write(TX_PAGE_3, 0x0000, 0x084); /* HDMI Transcode mode enable */ mhl_i2c_reg_write(TX_PAGE_L0, 0x000D, 0x1C); cbus_reset(); init_cbus_regs(); }