static int mhl_tx_chip_init(struct mhl_tx_ctrl *mhl_ctrl) { uint8_t chip_rev_id = 0x00; struct i2c_client *client = mhl_ctrl->i2c_handle; unsigned long flags; spin_lock_irqsave(&mhl_ctrl->lock, flags); mhl_ctrl->dwnstream_hpd = 0; mhl_ctrl->tx_powered_off = false; spin_unlock_irqrestore(&mhl_ctrl->lock, flags); /* Reset the TX chip */ mhl_sii_reset_pin(mhl_ctrl, 0); msleep(20); mhl_sii_reset_pin(mhl_ctrl, 1); /* TX PR-guide requires a 100 ms wait here */ msleep(100); /* Read the chip rev ID */ chip_rev_id = MHL_SII_PAGE0_RD(0x04); pr_debug("MHL: chip rev ID read=[%x]\n", chip_rev_id); mhl_ctrl->chip_rev_id = chip_rev_id; /* * Need to disable MHL discovery if * MHL-USB handshake is implemented */ mhl_init_reg_settings(mhl_ctrl, true); switch_mode(mhl_ctrl, POWER_STATE_D3, true); return 0; }
static int mhl_chip_init(void) { /* Read the chip rev ID */ mhl_msm_state->chip_rev_id = mhl_i2c_reg_read(TX_PAGE_L0, 0x04); pr_debug("MHL: chip rev ID read=[%x]\n", mhl_msm_state->chip_rev_id); /* Reset the TX chip */ mhl_sii_reset_pin(1); msleep(20); mhl_sii_reset_pin(0); msleep(20); mhl_sii_reset_pin(1); /* MHL spec requires a 100 ms wait here. */ msleep(100); /* * Need to disable MHL discovery */ mhl_init_reg_settings(true); /* * Power down the chip to the * D3 - a low power standby mode * cable impedance measurement logic is operational */ switch_mode(POWER_STATE_D3); return 0; }
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 int mhl_tx_chip_init(struct mhl_tx_ctrl *mhl_ctrl) { uint8_t chip_rev_id = 0x00; struct i2c_client *client = mhl_ctrl->i2c_handle; /* Reset the TX chip */ mhl_sii_reset_pin(mhl_ctrl, 0); msleep(20); mhl_sii_reset_pin(mhl_ctrl, 1); /* TX PR-guide requires a 100 ms wait here */ msleep(100); /* Read the chip rev ID */ chip_rev_id = MHL_SII_PAGE0_RD(0x04); pr_debug("MHL: chip rev ID read=[%x]\n", chip_rev_id); mhl_ctrl->chip_rev_id = chip_rev_id; /* * Need to disable MHL discovery if * MHL-USB handshake is implemented */ mhl_init_reg_settings(mhl_ctrl, true); switch_mode(mhl_ctrl, POWER_STATE_D3); return 0; }
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; } }
/* USB_HANDSHAKING FUNCTIONS */ static int mhl_sii_device_discovery(void *data, int id, void (*usb_notify_cb)(int online)) { int rc; struct mhl_tx_ctrl *mhl_ctrl = data; if (id) { /* When MHL cable is disconnected we get a sii8334 * mhl_disconnect interrupt which is handled separately. */ pr_debug("%s: USB ID pin high\n", __func__); return id; } if (!mhl_ctrl || !usb_notify_cb) { pr_warn("%s: cb || ctrl is NULL\n", __func__); /* return "USB" so caller can proceed */ return -EINVAL; } if (!mhl_ctrl->notify_usb_online) mhl_ctrl->notify_usb_online = usb_notify_cb; if (!mhl_ctrl->disc_enabled) { mhl_sii_reset_pin(mhl_ctrl, 0); msleep(50); mhl_sii_reset_pin(mhl_ctrl, 1); /* TX PR-guide requires a 100 ms wait here */ msleep(100); mhl_init_reg_settings(mhl_ctrl, true); rc = mhl_sii_wait_for_rgnd(mhl_ctrl); } else { if (mhl_ctrl->cur_state == POWER_STATE_D3) { rc = mhl_sii_wait_for_rgnd(mhl_ctrl); } else { /* in MHL mode */ pr_debug("%s:%u\n", __func__, __LINE__); rc = 0; } } pr_debug("%s: ret result: %s\n", __func__, rc ? "usb" : " mhl"); return rc; }
static int mhl_chip_init(void) { mhl_msm_state->chip_rev_id = mhl_i2c_reg_read(TX_PAGE_L0, 0x04); pr_debug("MHL: chip rev ID read=[%x]\n", mhl_msm_state->chip_rev_id); mhl_sii_reset_pin(1); msleep(20); mhl_sii_reset_pin(0); msleep(20); mhl_sii_reset_pin(1); msleep(100); mhl_init_reg_settings(true); switch_mode(POWER_STATE_D3); return 0; }
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 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; } }