Пример #1
0
static void sii9244_mhl_tx_ctl_int(struct sii9244_data *sii9244)
{
	mhl_tx_write_reg(sii9244, MHL_TX_MHLTX_CTL1_REG, 0xD0);
	mhl_tx_write_reg(sii9244, MHL_TX_MHLTX_CTL2_REG, 0xFC);
	mhl_tx_write_reg(sii9244, MHL_TX_MHLTX_CTL4_REG, 0xEB);
	mhl_tx_write_reg(sii9244, MHL_TX_MHLTX_CTL7_REG, 0x0C);
}
Пример #2
0
static int sii9244_power_init(struct sii9244_data *sii9244)
{
	int ret;

	/* Force the sii9244 into the D0 state. */
	ret = tpi_write_reg(sii9244, TPI_DPD_REG, 0x3F);
	if (ret < 0)
		return ret;

	/* Enable TxPLL Clock */
	ret = hdmi_rx_write_reg(sii9244, HDMI_RX_TMDS_CLK_EN_REG, 0x01);
	if (ret < 0)
		return ret;

	/* Enable Tx Clock Path & Equalizer*/
	ret = hdmi_rx_write_reg(sii9244, HDMI_RX_TMDS_CH_EN_REG, 0x15);
	if (ret < 0)
		return ret;

	/* Power Up TMDS*/
	ret = mhl_tx_write_reg(sii9244, 0x08, 0x35);
	if (ret < 0)
		return ret;

	return 0;
}
Пример #3
0
static int mhl_tx_clear_reg(struct sii9244_data *sii9244, unsigned int offset,
		u8 mask)
{
	int ret;
	u8 value;

	ret = mhl_tx_read_reg(sii9244, offset, &value);
	if (ret < 0)
		return ret;

	value &= ~mask;

	return mhl_tx_write_reg(sii9244, offset, value);
}
Пример #4
0
static void sii9244_hdmi_init(struct sii9244_data *sii9244)
{
	/* Analog PLL Control
	 * bits 5:4 = 2b00 as per characterization team.
	 */
	hdmi_rx_write_reg(sii9244, HDMI_RX_TMDS0_CCTRL1_REG, 0xC1);

	/* PLL Calrefsel */
	hdmi_rx_write_reg(sii9244, HDMI_RX_PLL_CALREFSEL_REG, 0x03);

	/* VCO Cal */
	hdmi_rx_write_reg(sii9244, HDMI_RX_PLL_VCOCAL_REG, 0x20);

	/* Auto EQ */
	hdmi_rx_write_reg(sii9244, HDMI_RX_EQ_DATA0_REG, 0x8A);

	/* Auto EQ */
	hdmi_rx_write_reg(sii9244, HDMI_RX_EQ_DATA1_REG, 0x6A);

	/* Auto EQ */
	hdmi_rx_write_reg(sii9244, HDMI_RX_EQ_DATA2_REG, 0xAA);

	/* Auto EQ */
	hdmi_rx_write_reg(sii9244, HDMI_RX_EQ_DATA3_REG, 0xCA);

	/* Auto EQ */
	hdmi_rx_write_reg(sii9244, HDMI_RX_EQ_DATA4_REG, 0xEA);

	/* Manual zone */
	hdmi_rx_write_reg(sii9244, HDMI_RX_TMDS_ZONE_CTRL_REG, 0xA0);

	/* PLL Mode Value */
	hdmi_rx_write_reg(sii9244, HDMI_RX_TMDS_MODE_CTRL_REG, 0x00);

	mhl_tx_write_reg(sii9244, MHL_TX_TMDS_CCTRL, 0x34);

	hdmi_rx_write_reg(sii9244, 0x45, 0x44);

	/* Rx PLL BW ~ 4MHz */
	hdmi_rx_write_reg(sii9244, 0x31, 0x0A);

	/* Analog PLL Control
	 * bits 5:4 = 2b00 as per characterization team.
	 */
	hdmi_rx_write_reg(sii9244, HDMI_RX_TMDS0_CCTRL1_REG, 0xC1);
}
Пример #5
0
int mhl_tx_modify_reg(void *drv_context, u8 page, u8 offset, u8 mask, u8 value)
{
	int	reg_value;
	int	write_status;

	reg_value = mhl_tx_read_reg(drv_context, page, offset);
	if (reg_value < 0)
		return reg_value;

	reg_value &= ~mask;
	reg_value |= mask & value;

	write_status = mhl_tx_write_reg(drv_context, page, offset, reg_value);

	if (write_status < 0)
		return write_status;
	else
		return reg_value;
}
Пример #6
0
static int mhl_tx_clear_reg(struct sii9234_data *sii9234, unsigned int offset,
                            u8 mask)
{
    int ret;
    u8 value;

    ret = mhl_tx_read_reg(sii9234, offset, &value);
    if (ret < 0) {
        pr_err("[ERROR] sii9234 : %s(0x%02x, 0x%02x)\n", __func__,
               offset, mask);
        return ret;
    }

    value &= ~mask;

    ret = mhl_tx_write_reg(sii9234, offset, value);
    if (ret < 0)
        pr_err("[ERROR] sii9234 : %s(0x%02x, 0x%02x)\n", __func__,
               offset, mask);
    return ret;
}
Пример #7
0
static irqreturn_t sii9244_irq_thread(int irq, void *data)
{
	struct sii9244_data *sii9244 = data;
	int ret;
	u8 intr1, intr4, value;
	u8 intr1_en, intr4_en;
	bool release_otg = false;

	mutex_lock(&sii9244->lock);
	mhl_tx_read_reg(sii9244, MHL_TX_INTR1_REG, &intr1);
	mhl_tx_read_reg(sii9244, MHL_TX_INTR4_REG, &intr4);

	mhl_tx_read_reg(sii9244, MHL_TX_INTR1_ENABLE_REG, &intr1_en);
	mhl_tx_read_reg(sii9244, MHL_TX_INTR4_ENABLE_REG, &intr4_en);
	pr_debug("sii9244: irq %02x/%02x %02x/%02x\n", intr1, intr1_en,
		 intr4, intr4_en);

	if (intr4 & RGND_READY_INT) {
		ret = mhl_tx_read_reg(sii9244, MHL_TX_STAT2_REG, &value);
		if (ret < 0) {
			dev_err(&sii9244->pdata->mhl_tx_client->dev,
					"STAT2 reg, err %d\n", ret);
			goto err_exit;
		}

		switch (value & RGND_INTP_MASK) {
		case RGND_INTP_OPEN:
			pr_debug("RGND Open\n");
			sii9244->rgnd = RGND_OPEN;
			break;
		case RGND_INTP_1K:
			pr_debug("RGND 1K\n");
			ret = mhl_tx_write_reg(sii9244, MHL_TX_DISC_CTRL1_REG,
					0x25);

			ret = mhl_send_wake_pulses(sii9244);
			sii9244->rgnd = RGND_1K;
			break;
		case RGND_INTP_2K:
			pr_debug("RGND 2K\n");
			ret = mhl_send_wake_pulses(sii9244);
			sii9244->rgnd = RGND_2K;
			break;
		case RGND_INTP_SHORT:
			pr_debug("RGND Short\n");
			sii9244->rgnd = RGND_SHORT;
			break;
		};
	}

	if (intr4 & CBUS_LKOUT_INT) {
		pr_debug("sii9244: CBUS Lockout Interrupt\n");
		sii9244->state = STATE_CBUS_LOCKOUT;
	}

	if (intr4 & MHL_DISC_FAIL_INT)
		sii9244->state = STATE_DISCOVERY_FAILED;

	if (intr4 & MHL_EST_INT) {
		/* discovery override */
		ret = mhl_tx_write_reg(sii9244, MHL_TX_MHLTX_CTL1_REG, 0x10);

		/* increase DDC translation layer timer (byte mode) */
		cbus_write_reg(sii9244, 0x07, 0x32);
		cbus_set_reg(sii9244, 0x44, 1<<1);

		/* Keep the discovery enabled. Need RGND interrupt */
		ret = mhl_tx_set_reg(sii9244, MHL_TX_DISC_CTRL1_REG, (1<<0));

		sii9244->state = STATE_ESTABLISHED;
	}

	if (intr1 & HPD_CHANGE_INT) {
		ret = cbus_read_reg(sii9244, MSC_REQ_ABORT_REASON_REG, &value);

		if (value & SET_HPD_DOWNSTREAM) {
			/* Downstream HPD Highi */

			/* Do we need to send HPD upstream using
			 * Register 0x79(page0)? Is HPD need to be overriden??
			 *      TODO: See if we need code for overriding HPD OUT
			 *      as per Page 0,0x79 Register
			 */

			/* Enable TMDS */
			ret = mhl_tx_set_reg(sii9244, MHL_TX_TMDS_CCTRL,
					     (1<<4));
			pr_debug("sii9244: MHL HPD High, enabled TMDS\n");

			ret = mhl_tx_set_reg(sii9244, MHL_TX_INT_CTRL_REG,
					     (1<<4) | (1<<5));
		} else {
			/*Downstream HPD Low*/

			/* Similar to above comments.
			 * TODO:Do we need to override HPD OUT value
			 * and do we need to disable TMDS here?
			 */

			/* Disable TMDS */
			ret = mhl_tx_clear_reg(sii9244, MHL_TX_TMDS_CCTRL,
					       (1<<4));
			pr_debug("sii9244 MHL HPD low, disabled TMDS\n");
			ret = mhl_tx_clear_reg(sii9244, MHL_TX_INT_CTRL_REG,
					       (1<<4) | (1<<5));
		}
	}

	if (intr1 & RSEN_CHANGE_INT) {
		ret = mhl_tx_read_reg(sii9244, MHL_TX_SYSSTAT_REG, &value);

		sii9244->rsen = value & RSEN_STATUS;

		if (value & RSEN_STATUS) {
			pr_info("sii9244: MHL cable connected.. RESN High\n");
		} else {
			pr_info("sii9244: RSEN lost\n");
			/* Once RSEN loss is confirmed,we need to check
			 * based on cable status and chip power status,whether
			 * it is SINK Loss(HDMI cable not connected, TV Off)
			 * or MHL cable disconnection
			 * TODO: Define the below mhl_disconnection()
			 */
			/* mhl_disconnection(); */
			/* Notify Disconnection to OTG */
			if (sii9244->claimed == true) {
				disable_irq_nosync(sii9244->irq);
				release_otg = true;
			}
			sii9244_power_down(sii9244);
		}
	}

err_exit:
	mhl_tx_write_reg(sii9244, MHL_TX_INTR1_REG, intr1);
	mhl_tx_write_reg(sii9244, MHL_TX_INTR4_REG, intr4);

	mutex_unlock(&sii9244->lock);

	pr_debug("sii9244: wake_up\n");
	wake_up(&sii9244->wq);

	if (release_otg)
		otg_id_notify();

	return IRQ_HANDLED;
}
Пример #8
0
static int sii9244_detection_callback(struct otg_id_notifier_block *nb)
{
	struct sii9244_data *sii9244 = container_of(nb, struct sii9244_data,
						otg_id_nb);
	int ret;
	u8 value;
	int handled = OTG_ID_UNHANDLED;

	pr_debug("sii9244: detection started\n");

	mutex_lock(&sii9244->lock);
	sii9244->rgnd = RGND_UNKNOWN;
	sii9244->state = STATE_DISCONNECTED;
	sii9244->rsen = false;

	/* Set the board configuration so the  sii9244 has access to the
	 * external connector.
	 */
	sii9244->pdata->enable(1);
	sii9244->pdata->power(1);

	ret = sii9244_power_init(sii9244);
	if (ret < 0)
		goto unhandled;

	sii9244_hdmi_init(sii9244);

	sii9244_mhl_tx_ctl_int(sii9244);

	/* Enable HDCP Compliance safety*/
	ret = mhl_tx_write_reg(sii9244, 0x2B, 0x01);
	if (ret < 0)
		goto unhandled;

	/* CBUS discovery cycle time for each drive and float = 150us*/
	ret = mhl_tx_read_reg(sii9244, MHL_TX_DISC_CTRL1_REG, &value);
	if (ret < 0)
		goto unhandled;

	value &= ~(1<<2);
	value |= (1<<3);

	ret = mhl_tx_write_reg(sii9244, MHL_TX_DISC_CTRL1_REG, value);
	if (ret < 0)
		goto unhandled;

	/* Clear bit 6 (reg_skip_rgnd) */
	ret = mhl_tx_write_reg(sii9244, MHL_TX_DISC_CTRL2_REG,
			(1<<7) /* Reserved Bit */ |
			2 << ATT_THRESH_SHIFT |
			DEGLITCH_TIME_128MS);
	if (ret < 0)
		goto unhandled;

	/* Changed from 66 to 65 for 94[1:0] = 01 = 5k reg_cbusmhl_pup_sel */
	/* 1.8V CBUS VTH & GND threshold */
	ret = mhl_tx_write_reg(sii9244, MHL_TX_DISC_CTRL5_REG, 0x75);
	if (ret < 0)
		goto unhandled;

	/* set bit 2 and 3, which is Initiator Timeout */
	ret = cbus_read_reg(sii9244, CBUS_LINK_CONTROL_2_REG, &value);
	if (ret < 0)
		goto unhandled;

	value |= 0x0C;

	ret = cbus_write_reg(sii9244, CBUS_LINK_CONTROL_2_REG, value);
	if (ret < 0)
		goto unhandled;

	ret = mhl_tx_write_reg(sii9244, MHL_TX_MHLTX_CTL6_REG, 0xA0);
	if (ret < 0)
		goto unhandled;

	/* RGND & single discovery attempt (RGND blocking) */
	ret = mhl_tx_write_reg(sii9244, MHL_TX_DISC_CTRL6_REG, BLOCK_RGND_INT |
			DVRFLT_SEL | SINGLE_ATT);
	if (ret < 0)
		goto unhandled;

	/* Use VBUS path of discovery state machine*/
	ret = mhl_tx_write_reg(sii9244, MHL_TX_DISC_CTRL8_REG, 0);
	if (ret < 0)
		goto unhandled;

	ret = mhl_tx_set_reg(sii9244, MHL_TX_DISC_CTRL6_REG, USB_ID_OVR);
	if (ret < 0)
		goto unhandled;

	/* To allow RGND engine to operate correctly.
	 * When moving the chip from D2 to D0 (power up, init regs)
	 * the values should be
	 * 94[1:0] = 01  reg_cbusmhl_pup_sel[1:0] should be set for 5k
	 * 93[7:6] = 10  reg_cbusdisc_pup_sel[1:0] should be
	 * set for 10k (default)
	 * 93[5:4] = 00  reg_cbusidle_pup_sel[1:0] = open (default)
	 */
	ret = mhl_tx_set_reg(sii9244, MHL_TX_DISC_CTRL3_REG, 0x86);
	if (ret < 0)
		goto unhandled;

	/* change from CC to 8C to match 5K*/
	ret = mhl_tx_set_reg(sii9244, MHL_TX_DISC_CTRL4_REG, 0x8C);
	if (ret < 0)
		goto unhandled;

	/* Configure the interrupt as active high */
	ret = mhl_tx_clear_reg(sii9244, MHL_TX_INT_CTRL_REG, (1<<2) | (1<<1));
	if (ret < 0)
		goto unhandled;

	msleep(25);

	ret = mhl_tx_clear_reg(sii9244, MHL_TX_DISC_CTRL6_REG, USB_ID_OVR);
	if (ret < 0)
		goto unhandled;

	ret = mhl_tx_write_reg(sii9244, MHL_TX_DISC_CTRL1_REG, 0x27);
	if (ret < 0)
		goto unhandled;

	/* Reset CBUS */
	ret = mhl_tx_set_reg(sii9244, 0x05, 0x03);
	if (ret < 0)
		goto unhandled;

	usleep_range(2000, 3000);

	ret = mhl_tx_clear_reg(sii9244, 0x05, 0x03);
	if (ret < 0)
		goto unhandled;

	/* Adjust interrupt mask everytime reset is performed.*/
	ret = cbus_write_reg(sii9244, 0x09, 0);
	if (ret < 0)
		goto unhandled;

	ret = cbus_write_reg(sii9244, 0x1F, 0);
	if (ret < 0)
		goto unhandled;

	/* Enable Auto soft reset on SCDT = 0*/
	ret = mhl_tx_write_reg(sii9244, 0x05, 0x04);

	if (ret < 0)
		goto unhandled;

	/* HDMI Transcode mode enable*/
	ret = mhl_tx_write_reg(sii9244, 0x0D, 0x1C);
	if (ret < 0)
		goto unhandled;

	ret = mhl_tx_write_reg(sii9244, MHL_TX_INTR4_ENABLE_REG,
			RGND_READY_MASK | CBUS_LKOUT_MASK |
			MHL_DISC_FAIL_MASK | MHL_EST_MASK);
	if (ret < 0)
		goto unhandled;

	ret = mhl_tx_write_reg(sii9244, MHL_TX_INTR1_ENABLE_REG,
			       (1<<5) | (1<<6));
	if (ret < 0)
		goto unhandled;

	pr_debug("sii9244: waiting for RGND measurement\n");
	enable_irq(sii9244->irq);

	/* SiI9244 Programmer's Reference Section 2.4.3
	 * State : RGND Ready
	 */
	mutex_unlock(&sii9244->lock);
	ret = wait_event_timeout(sii9244->wq,
				 ((sii9244->rgnd != RGND_UNKNOWN) ||
				  mhl_state_is_error(sii9244->state)),
				 msecs_to_jiffies(2000));

	mutex_lock(&sii9244->lock);
	if (sii9244->rgnd == RGND_UNKNOWN || mhl_state_is_error(sii9244->state))
		goto unhandled;

	if (sii9244->rgnd != RGND_1K)
		goto unhandled;

	mutex_unlock(&sii9244->lock);

	pr_debug("sii9244: waiting for detection\n");
	ret = wait_event_timeout(sii9244->wq,
				 sii9244->state != STATE_DISCONNECTED,
				 msecs_to_jiffies(500));
	mutex_lock(&sii9244->lock);
	if (sii9244->state == STATE_DISCONNECTED)
		goto unhandled;

	if (sii9244->state == STATE_DISCOVERY_FAILED) {
		handled = OTG_ID_PROXY_WAIT;
		goto unhandled;
	}

	if (mhl_state_is_error(sii9244->state))
		goto unhandled;

	mutex_unlock(&sii9244->lock);
	wait_event_timeout(sii9244->wq, sii9244->rsen, msecs_to_jiffies(400));
	mutex_lock(&sii9244->lock);
	if (!sii9244->rsen)
		goto unhandled;

	pr_info("si9234: connection established\n");
	sii9244->claimed = true;
	sii9234_vbus_present(true);
	mutex_unlock(&sii9244->lock);

	return OTG_ID_HANDLED;

unhandled:
	pr_info("sii9244: Detection failed");
	if (sii9244->state == STATE_DISCONNECTED)
		pr_cont(" (timeout)");
	else if (sii9244->state == STATE_DISCOVERY_FAILED)
		pr_cont(" (discovery failed)");
	else if (sii9244->state == STATE_CBUS_LOCKOUT)
		pr_cont(" (cbus_lockout)");
	pr_cont("\n");

	disable_irq_nosync(sii9244->irq);

	sii9244_power_down(sii9244);

	mutex_unlock(&sii9244->lock);
	return handled;
}
Пример #9
0
static int sii9234_30pin_init_for_9290(struct sii9234_data *sii9234)
{
    u8 value;
    int ret = 0;
    pr_info("[MHD: %s]++\n", __func__);
    /* init registers */
    ret = sii9234_30pin_reg_init_for_9290(sii9234);
    if (ret < 0)
        goto unhandled;

    /* start tpi */
    ret = mhl_tx_write_reg(sii9234, 0xC7, 0x00);
    if (ret < 0)
        goto unhandled;

    /* enable interrupts */
    ret = mhl_tx_write_reg(sii9234, 0xBC, 0x01);
    if (ret < 0)
        goto unhandled;
    ret = mhl_tx_write_reg(sii9234, 0xBD, 0x78);
    if (ret < 0)
        goto unhandled;
    ret = mhl_tx_write_reg(sii9234, 0xBE, 0x01);
    if (ret < 0)
        goto unhandled;

    /* mhd rx connected */
    ret = mhl_tx_write_reg(sii9234, 0xBC, 0x01);
    if (ret < 0)
        goto unhandled;
    ret = mhl_tx_write_reg(sii9234, 0xBD, 0xA0);
    if (ret < 0)
        goto unhandled;
    ret = mhl_tx_write_reg(sii9234, 0xBE, 0x10);
    if (ret < 0)
        goto unhandled;
    ret = cbus_write_reg(sii9234, 0x07, 0x30 | 0x0E);
    if (ret < 0)
        goto unhandled;
    ret = cbus_write_reg(sii9234, 0x47, 0x03);
    if (ret < 0)
        goto unhandled;
    ret = cbus_write_reg(sii9234, 0x21, 0x01);
    if (ret < 0)
        goto unhandled;

    /* enable mhd tx */
    ret = mhl_tx_clear_reg(sii9234, 0x1A, 1<<4);
    if (ret < 0)
        goto unhandled;

    /* set mhd power active mode */
    ret = mhl_tx_clear_reg(sii9234, 0x1E, 1<<1 | 1<<0);
    if (ret < 0)
        goto unhandled;

    ret = mhl_tx_write_reg(sii9234, 0xBC, 0x01);
    if (ret < 0)
        goto unhandled;
    ret = mhl_tx_write_reg(sii9234, 0xBD, 0xA0);
    if (ret < 0)
        goto unhandled;

    ret = mhl_tx_read_reg(sii9234, 0xBE, &value);
    if (ret < 0)
        goto unhandled;
    if ((value & (1<<7 | 1<<6)) != 0x00) {
        /* Assert Mobile HD FIFO Reset */
        ret = mhl_tx_write_reg(sii9234, 0xBC, 0x01);
        if (ret < 0)
            goto unhandled;
        ret = mhl_tx_write_reg(sii9234, 0xBD, 0x05);
        if (ret < 0)
            goto unhandled;
        ret = mhl_tx_write_reg(sii9234, 0xBE, (1<<4 | 0x04));
        if (ret < 0)
            goto unhandled;
        mdelay(1);
        /* Deassert Mobile HD FIFO Reset */
        ret = mhl_tx_write_reg(sii9234, 0xBC, 0x01);
        if (ret < 0)
            goto unhandled;
        ret = mhl_tx_write_reg(sii9234, 0xBD, 0x05);
        if (ret < 0)
            goto unhandled;
        ret = mhl_tx_write_reg(sii9234, 0xBE, 0x04);
        if (ret < 0)
            goto unhandled;
    }

    /* This is tricky but there's no way to handle other accessories
     * but sending UNHANDLED.
     * return MHL_CON_HANDLED;
     */
    pr_info("[MHD: %s]--\n", __func__);
    return 0;
unhandled:
    return -1;
}
Пример #10
0
static int sii9234_30pin_reg_init_for_9290(struct sii9234_data *sii9234)
{
    int ret = 0;
    u8 value;
    pr_info("[: %s]++\n", __func__);
    ret = tpi_write_reg(sii9234, 0x3D, 0x3F);
    if (ret < 0)
        return ret;

    ret = hdmi_rx_write_reg(sii9234, 0x11, 0x01);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x12, 0x15);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0x08, 0x35);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x00, 0x00);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x13, 0x60);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x14, 0xF0);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x4B, 0x06);
    if (ret < 0)
        return ret;

    /* Analog PLL Control */
    ret = hdmi_rx_write_reg(sii9234, 0x17, 0x07);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x1A, 0x20);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x22, 0xE0);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x23, 0xC0);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x24, 0xA0);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x25, 0x80);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x26, 0x60);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x27, 0x40);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x28, 0x20);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x29, 0x00);
    if (ret < 0)
        return ret;

    ret = hdmi_rx_write_reg(sii9234, 0x4D, 0x02);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x4C, 0xA0);
    if (ret < 0)
        return ret;

    ret = mhl_tx_write_reg(sii9234, 0x80, 0x34);
    if (ret < 0)
        return ret;

    ret = hdmi_rx_write_reg(sii9234, 0x31, 0x0B);
    if (ret < 0)
        return ret;
    ret = hdmi_rx_write_reg(sii9234, 0x45, 0x06);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0xA0, 0xD0);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0xA1, 0xFC);
    if (ret < 0)
        return ret;

    ret = mhl_tx_write_reg(sii9234, 0xA3 /*MHL_TX_MHLTX_CTL4_REG*/,
                           sii9234->pdata->swing_level);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0xA6, 0x00);
    if (ret < 0)
        return ret;

    ret = mhl_tx_write_reg(sii9234, 0x2B, 0x01);
    if (ret < 0)
        return ret;

    /* CBUS & Discovery */
    ret = mhl_tx_read_reg(sii9234, 0x90/*MHL_TX_DISC_CTRL1_REG*/, &value);
    if (ret < 0)
        return ret;
    value &= ~(1<<2);
    value |= (1<<3);
    ret = mhl_tx_write_reg(sii9234, 0x90 /*MHL_TX_DISC_CTRL1_REG*/, value);
    if (ret < 0)
        return ret;

    ret = mhl_tx_write_reg(sii9234, 0x91, 0xE5);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0x94, 0x66);
    if (ret < 0)
        return ret;

    ret = cbus_read_reg(sii9234, 0x31, &value);
    if (ret < 0)
        return ret;
    value |= 0x0C;
    if (ret < 0)
        return ret;
    ret = cbus_write_reg(sii9234, 0x31, value);
    if (ret < 0)
        return ret;

    ret = mhl_tx_write_reg(sii9234, 0xA5, 0x80);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0x95, 0x31);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0x96, 0x22);
    if (ret < 0)
        return ret;

    ret = mhl_tx_read_reg(sii9234, 0x95/*MHL_TX_DISC_CTRL6_REG*/, &value);
    if (ret < 0)
        return ret;
    value |= (1<<6);
    ret = mhl_tx_write_reg(sii9234,  0x95/*MHL_TX_DISC_CTRL6_REG*/, value);
    if (ret < 0)
        return ret;

    ret = mhl_tx_write_reg(sii9234, 0x92, 0x46);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0x93, 0xDC);
    if (ret < 0)
        return ret;
    /*0x79=MHL_TX_INT_CTRL_REG*/
    ret = mhl_tx_clear_reg(sii9234, 0x79, (1<<2) | (1<<1));
    if (ret < 0)
        return ret;

    mdelay(25);
    /*0x95=MHL_TX_DISC_CTRL6_REG*/
    ret = mhl_tx_clear_reg(sii9234,  0x95, (1<<6)/*USB_ID_OVR*/);
    if (ret < 0)
        return ret;

    ret = mhl_tx_write_reg(sii9234, 0x90, 0x27);
    if (ret < 0)
        return ret;

    ret = sii9234_cbus_init_for_9290(sii9234);
    if (ret < 0)
        return ret;

    ret = mhl_tx_write_reg(sii9234, 0x05, 0x4);
    if (ret < 0)
        return ret;
    ret = mhl_tx_write_reg(sii9234, 0x0D, 0x1C);
    pr_info("[MHD: %s]--\n", __func__);
    return ret;
}