Пример #1
0
/* read scratchpad */
void mhl_read_scratchpad(struct mhl_tx_ctrl *mhl_ctrl)
{
	struct i2c_client *client = mhl_ctrl->i2c_handle;
	int i;

	for (i = 0; i < MHL_SCRATCHPAD_SIZE; i++) {
		mhl_ctrl->scrpd.data[i] = MHL_SII_REG_NAME_RD(
			REG_CBUS_SCRATCHPAD_0 + i);
	}
}
Пример #2
0
static void mhl_misc_isr(struct mhl_tx_ctrl *mhl_ctrl)
{
	uint8_t intr_5_stat;
	struct i2c_client *client = mhl_ctrl->i2c_handle;

	/*
	 * Clear INT 5
	 * INTR5 is related to FIFO underflow/overflow reset
	 * which is handled in 8334 by auto FIFO reset
	 */
	intr_5_stat = MHL_SII_REG_NAME_RD(REG_INTR5);
	MHL_SII_REG_NAME_WR(REG_INTR5,  intr_5_stat);
}
Пример #3
0
static void mhl_sii_cbus_process_errors(struct i2c_client *client,
					u8 int_status)
{
	u8 abort_reason = 0;

	if (int_status & BIT2) {
		abort_reason = MHL_SII_REG_NAME_RD(REG_DDC_ABORT_REASON);
		pr_debug("%s: CBUS DDC Abort Reason(0x%02x)\n",
			 __func__, abort_reason);
	}
	if (int_status & BIT5) {
		abort_reason = MHL_SII_REG_NAME_RD(REG_PRI_XFR_ABORT_REASON);
		pr_debug("%s: CBUS MSC Requestor Abort Reason(0x%02x)\n",
			 __func__, abort_reason);
		MHL_SII_REG_NAME_WR(REG_PRI_XFR_ABORT_REASON, 0xFF);
	}
	if (int_status & BIT6) {
		abort_reason = MHL_SII_REG_NAME_RD(
			REG_CBUS_PRI_FWR_ABORT_REASON);
		pr_debug("%s: CBUS MSC Responder Abort Reason(0x%02x)\n",
			 __func__, abort_reason);
		MHL_SII_REG_NAME_WR(REG_CBUS_PRI_FWR_ABORT_REASON, 0xFF);
	}
}
Пример #4
0
static void scdt_st_chg(struct i2c_client *client)
{
	uint8_t tmds_cstat;
	uint8_t mhl_fifo_status;

	/* tmds cstat */
	tmds_cstat = MHL_SII_PAGE3_RD(0x0040);
	pr_debug("%s: tmds cstat: 0x%02x\n", __func__,
		 tmds_cstat);

	if (!(tmds_cstat & BIT1))
		return;

	mhl_fifo_status = MHL_SII_REG_NAME_RD(REG_INTR5);
	pr_debug("%s: mhl fifo st: 0x%02x\n", __func__,
		 mhl_fifo_status);
	if (mhl_fifo_status & 0x0C) {
		MHL_SII_REG_NAME_WR(REG_INTR5,  0x0C);
		pr_debug("%s: mhl fifo rst\n", __func__);
		MHL_SII_REG_NAME_WR(REG_SRST, 0x94);
		MHL_SII_REG_NAME_WR(REG_SRST, 0x84);
	}
}
Пример #5
0
static int dev_detect_isr(struct mhl_tx_ctrl *mhl_ctrl)
{
	uint8_t status, reg;
	struct i2c_client *client = mhl_ctrl->i2c_handle;

	/* INTR_STATUS4 */
	status = MHL_SII_REG_NAME_RD(REG_INTR4);
	pr_debug("%s: reg int4 st=%02X\n", __func__, status);

	if ((0x00 == status) &&\
	    (mhl_ctrl->cur_state == POWER_STATE_D3)) {
		pr_err("%s: invalid intr\n", __func__);
		return 0;
	}

	if (0xFF == status) {
		pr_debug("%s: invalid intr 0xff\n", __func__);
		MHL_SII_REG_NAME_WR(REG_INTR4, status);
		return 0;
	}

	if ((status & BIT0) && (mhl_ctrl->chip_rev_id < 1)) {
		pr_debug("%s: scdt intr\n", __func__);
		scdt_st_chg(client);
	}

	if (status & BIT1)
		pr_debug("mhl: int4 bit1 set\n");

	/* mhl_est interrupt */
	if (status & BIT2) {
		pr_debug("%s: mhl_est st=%02X\n", __func__,
			 (int) status);
		mhl_msm_connection(mhl_ctrl);
	} else if (status & BIT3) {
		pr_debug("%s: uUSB-a type dev detct\n", __func__);

		/* Short RGND */
		MHL_SII_REG_NAME_MOD(REG_DISC_STAT2, BIT0 | BIT1, 0x00);
		mhl_msm_disconnection(mhl_ctrl);
		power_supply_changed(&mhl_ctrl->mhl_psy);
		if (mhl_ctrl->notify_usb_online)
			mhl_ctrl->notify_usb_online(0);
		return -EACCES;
	}

	if (status & BIT5) {
		/* clr intr - reg int4 */
		pr_debug("%s: mhl discon: int4 st=%02X\n", __func__,
			 (int)status);

		reg = MHL_SII_REG_NAME_RD(REG_INTR4);
		MHL_SII_REG_NAME_WR(REG_INTR4, reg);
		mhl_msm_disconnection(mhl_ctrl);
		power_supply_changed(&mhl_ctrl->mhl_psy);
		if (mhl_ctrl->notify_usb_online)
			mhl_ctrl->notify_usb_online(0);
		return -EACCES;
	}

	if ((mhl_ctrl->cur_state != POWER_STATE_D0_NO_MHL) &&\
	    (status & BIT6)) {
		/* rgnd rdy Intr */
		pr_debug("%s: rgnd ready intr\n", __func__);
		switch_mode(mhl_ctrl, POWER_STATE_D0_NO_MHL, true);
		mhl_msm_read_rgnd_int(mhl_ctrl);
	}

	/* Can't succeed at these in D3 */
	if ((mhl_ctrl->cur_state != POWER_STATE_D3) &&\
	     (status & BIT4)) {
		/* cbus lockout interrupt?
		 * Hardware detection mechanism figures that
		 * CBUS line is latched and raises this intr
		 * where we force usb switch open and release
		 */
		pr_warn("%s: cbus locked out!\n", __func__);
		force_usb_switch_open(mhl_ctrl);
		release_usb_switch_open(mhl_ctrl);
	}
	MHL_SII_REG_NAME_WR(REG_INTR4, status);
	return 0;
}
Пример #6
0
static void mhl_cbus_isr(struct mhl_tx_ctrl *mhl_ctrl)
{
	uint8_t regval;
	int req_done = 0;
	uint8_t sub_cmd = 0x0;
	uint8_t cmd_data = 0x0;
	int msc_msg_recved = 0;
	int rc = -1;
	struct i2c_client *client = mhl_ctrl->i2c_handle;

	regval = MHL_SII_REG_NAME_RD(REG_CBUS_INTR_STATUS);
	if (regval == 0xff)
		return;

	if (regval)
		MHL_SII_REG_NAME_WR(REG_CBUS_INTR_STATUS, regval);

	pr_debug("%s: CBUS_INT = %02x\n", __func__, regval);

	/* MSC_MSG (RCP/RAP) */
	if (regval & BIT3) {
		sub_cmd = MHL_SII_REG_NAME_RD(REG_CBUS_PRI_VS_CMD);
		cmd_data = MHL_SII_REG_NAME_RD(REG_CBUS_PRI_VS_DATA);
		msc_msg_recved = 1;
	}
	/* MSC_MT_ABRT/MSC_MR_ABRT/DDC_ABORT */
	if (regval & (BIT6 | BIT5 | BIT2))
		mhl_sii_cbus_process_errors(client, regval);

	/* MSC_REQ_DONE */
	if (regval & BIT4)
		req_done = 1;

	/* look for interrupts on CBUS_MSC_INT2 */
	regval  = MHL_SII_REG_NAME_RD(REG_CBUS_MSC_INT2_STATUS);

	/* clear all interrupts */
	if (regval)
		MHL_SII_REG_NAME_WR(REG_CBUS_MSC_INT2_STATUS, regval);

	pr_debug("%s: CBUS_MSC_INT2 = %02x\n", __func__, regval);

	/* received SET_INT */
	if (regval & BIT2) {
		uint8_t intr;
		intr = MHL_SII_REG_NAME_RD(REG_CBUS_SET_INT_0);
		MHL_SII_REG_NAME_WR(REG_CBUS_SET_INT_0, intr);
		mhl_msc_recv_set_int(mhl_ctrl, 0, intr);

		pr_debug("%s: MHL_INT_0 = %02x\n", __func__, intr);
		intr = MHL_SII_REG_NAME_RD(REG_CBUS_SET_INT_1);
		MHL_SII_REG_NAME_WR(REG_CBUS_SET_INT_1, intr);
		mhl_msc_recv_set_int(mhl_ctrl, 1, intr);

		pr_debug("%s: MHL_INT_1 = %02x\n", __func__, intr);
		MHL_SII_REG_NAME_WR(REG_CBUS_SET_INT_2, 0xFF);
		MHL_SII_REG_NAME_WR(REG_CBUS_SET_INT_3, 0xFF);
	}

	/* received WRITE_STAT */
	if (regval & BIT3) {
		uint8_t stat;
		stat = MHL_SII_REG_NAME_RD(REG_CBUS_WRITE_STAT_0);
		mhl_msc_recv_write_stat(mhl_ctrl, 0, stat);

		pr_debug("%s: MHL_STATUS_0 = %02x\n", __func__, stat);
		stat = MHL_SII_REG_NAME_RD(REG_CBUS_WRITE_STAT_1);
		mhl_msc_recv_write_stat(mhl_ctrl, 1, stat);
		pr_debug("%s: MHL_STATUS_1 = %02x\n", __func__, stat);

		MHL_SII_REG_NAME_WR(REG_CBUS_WRITE_STAT_0, 0xFF);
		MHL_SII_REG_NAME_WR(REG_CBUS_WRITE_STAT_1, 0xFF);
		MHL_SII_REG_NAME_WR(REG_CBUS_WRITE_STAT_2, 0xFF);
		MHL_SII_REG_NAME_WR(REG_CBUS_WRITE_STAT_3, 0xFF);
	}

	/* received MSC_MSG */
	if (msc_msg_recved) {
		/*mhl msc recv msc msg*/
		rc = mhl_msc_recv_msc_msg(mhl_ctrl, sub_cmd, cmd_data);
		if (rc)
			pr_err("MHL: mhl msc recv msc msg failed(%d)!\n", rc);
	}
	/* complete last command */
	if (req_done)
		complete_all(&mhl_ctrl->msc_cmd_done);

}
Пример #7
0
int mhl_send_msc_command(struct mhl_tx_ctrl *mhl_ctrl,
			 struct msc_command_struct *req)
{
	int timeout;
	u8 start_bit = 0x00;
	u8 *burst_data;
	int i;
	struct i2c_client *client = mhl_ctrl->i2c_handle;

	if (mhl_ctrl->cur_state != POWER_STATE_D0_MHL) {
		pr_debug("%s: power_state:%02x CBUS(0x0A):%02x\n",
			 __func__,
			 mhl_ctrl->cur_state,
			 MHL_SII_REG_NAME_RD(REG_CBUS_BUS_STATUS));
		return -EFAULT;
	}

	if (!req)
		return -EFAULT;

	pr_debug("%s: command=0x%02x offset=0x%02x %02x %02x",
		 __func__,
		 req->command,
		 req->offset,
		 req->payload.data[0],
		 req->payload.data[1]);

	/* REG_CBUS_PRI_ADDR_CMD = REQ CBUS CMD or OFFSET */
	MHL_SII_REG_NAME_WR(REG_CBUS_PRI_ADDR_CMD, req->offset);
	MHL_SII_REG_NAME_WR(REG_CBUS_PRI_WR_DATA_1ST,
			    req->payload.data[0]);

	switch (req->command) {
	case MHL_SET_INT:
	case MHL_WRITE_STAT:
		start_bit = MSC_START_BIT_WRITE_REG;
		break;
	case MHL_READ_DEVCAP:
		start_bit = MSC_START_BIT_READ_REG;
		break;
	case MHL_GET_STATE:
	case MHL_GET_VENDOR_ID:
	case MHL_SET_HPD:
	case MHL_CLR_HPD:
	case MHL_GET_SC1_ERRORCODE:
	case MHL_GET_DDC_ERRORCODE:
	case MHL_GET_MSC_ERRORCODE:
	case MHL_GET_SC3_ERRORCODE:
		start_bit = MSC_START_BIT_MSC_CMD;
		MHL_SII_REG_NAME_WR(REG_CBUS_PRI_ADDR_CMD, req->command);
		break;
	case MHL_MSC_MSG:
		start_bit = MSC_START_BIT_VS_CMD;
		MHL_SII_REG_NAME_WR(REG_CBUS_PRI_WR_DATA_2ND,
				    req->payload.data[1]);
		MHL_SII_REG_NAME_WR(REG_CBUS_PRI_ADDR_CMD, req->command);
		break;
	case MHL_WRITE_BURST:
		start_bit = MSC_START_BIT_WRITE_BURST;
		MHL_SII_REG_NAME_WR(REG_MSC_WRITE_BURST_LEN, req->length - 1);
		if (!(req->payload.burst_data)) {
			pr_err("%s: burst data is null!\n", __func__);
			goto cbus_send_fail;
		}
		burst_data = req->payload.burst_data;
		for (i = 0; i < req->length; i++, burst_data++)
			MHL_SII_REG_NAME_WR(REG_CBUS_SCRATCHPAD_0 + i,
				*burst_data);
		break;
	default:
		pr_err("%s: unknown command! (%02x)\n",
		       __func__, req->command);
		goto cbus_send_fail;
	}

	INIT_COMPLETION(mhl_ctrl->msc_cmd_done);
	MHL_SII_REG_NAME_WR(REG_CBUS_PRI_START, start_bit);
	timeout = wait_for_completion_interruptible_timeout
		(&mhl_ctrl->msc_cmd_done, msecs_to_jiffies(T_ABORT_NEXT));
	if (!timeout) {
		pr_err("%s: cbus_command_send timed out!\n", __func__);
		goto cbus_send_fail;
	}

	switch (req->command) {
	case MHL_READ_DEVCAP:
		req->retval = MHL_SII_REG_NAME_RD(REG_CBUS_PRI_RD_DATA_1ST);
		break;
	case MHL_MSC_MSG:
		/* check if MSC_MSG NACKed */
		if (MHL_SII_REG_NAME_RD(REG_MSC_WRITE_BURST_LEN) & BIT6)
			return -EAGAIN;
	default:
		req->retval = 0;
		break;
	}
	mhl_msc_command_done(mhl_ctrl, req);
	pr_debug("%s: msc cmd done\n", __func__);
	return 0;

cbus_send_fail:
	return -EFAULT;
}
Пример #8
0
static void clear_all_intrs(struct i2c_client *client)
{
	uint8_t regval = 0x00;

	pr_debug_intr("********* exiting isr mask check ?? *************\n");
	pr_debug_intr("int1 mask = %02X\n",
		(int) MHL_SII_REG_NAME_RD(REG_INTR1));
	pr_debug_intr("int3 mask = %02X\n",
		(int) MHL_SII_PAGE0_RD(0x0077));
	pr_debug_intr("int4 mask = %02X\n",
		(int) MHL_SII_REG_NAME_RD(REG_INTR4));
	pr_debug_intr("int5 mask = %02X\n",
		(int) MHL_SII_REG_NAME_RD(REG_INTR5));
	pr_debug_intr("cbus1 mask = %02X\n",
		(int) MHL_SII_CBUS_RD(0x0009));
	pr_debug_intr("cbus2 mask = %02X\n",
		(int) MHL_SII_CBUS_RD(0x001F));
	pr_debug_intr("********* end of isr mask check *************\n");

	regval = MHL_SII_REG_NAME_RD(REG_INTR1);
	pr_debug_intr("int1 st = %02X\n", (int)regval);
	MHL_SII_REG_NAME_WR(REG_INTR1, regval);

	regval =  MHL_SII_REG_NAME_RD(REG_INTR2);
	pr_debug_intr("int2 st = %02X\n", (int)regval);
	MHL_SII_REG_NAME_WR(REG_INTR2, regval);

	regval =  MHL_SII_PAGE0_RD(0x0073);
	pr_debug_intr("int3 st = %02X\n", (int)regval);
	MHL_SII_PAGE0_WR(0x0073, regval);

	regval =  MHL_SII_REG_NAME_RD(REG_INTR4);
	pr_debug_intr("int4 st = %02X\n", (int)regval);
	MHL_SII_REG_NAME_WR(REG_INTR4, regval);

	regval =  MHL_SII_REG_NAME_RD(REG_INTR5);
	pr_debug_intr("int5 st = %02X\n", (int)regval);
	MHL_SII_REG_NAME_WR(REG_INTR5, regval);

	regval =  MHL_SII_CBUS_RD(0x0008);
	pr_debug_intr("cbusInt st = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x0008, regval);

	regval =  MHL_SII_CBUS_RD(0x001E);
	pr_debug_intr("CBUS intR_2: %d\n", (int)regval);
	MHL_SII_CBUS_WR(0x001E, regval);

	regval =  MHL_SII_CBUS_RD(0x00A0);
	pr_debug_intr("A0 int set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00A0, regval);

	regval =  MHL_SII_CBUS_RD(0x00A1);
	pr_debug_intr("A1 int set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00A1, regval);

	regval =  MHL_SII_CBUS_RD(0x00A2);
	pr_debug_intr("A2 int set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00A2, regval);

	regval =  MHL_SII_CBUS_RD(0x00A3);
	pr_debug_intr("A3 int set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00A3, regval);

	regval =  MHL_SII_CBUS_RD(0x00B0);
	pr_debug_intr("B0 st set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00B0, regval);

	regval =  MHL_SII_CBUS_RD(0x00B1);
	pr_debug_intr("B1 st set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00B1, regval);

	regval =  MHL_SII_CBUS_RD(0x00B2);
	pr_debug_intr("B2 st set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00B2, regval);

	regval =  MHL_SII_CBUS_RD(0x00B3);
	pr_debug_intr("B3 st set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00B3, regval);

	regval =  MHL_SII_CBUS_RD(0x00E0);
	pr_debug_intr("E0 st set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00E0, regval);

	regval =  MHL_SII_CBUS_RD(0x00E1);
	pr_debug_intr("E1 st set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00E1, regval);

	regval =  MHL_SII_CBUS_RD(0x00E2);
	pr_debug_intr("E2 st set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00E2, regval);

	regval =  MHL_SII_CBUS_RD(0x00E3);
	pr_debug_intr("E3 st set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00E3, regval);

	regval =  MHL_SII_CBUS_RD(0x00F0);
	pr_debug_intr("F0 int set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00F0, regval);

	regval =  MHL_SII_CBUS_RD(0x00F1);
	pr_debug_intr("F1 int set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00F1, regval);

	regval =  MHL_SII_CBUS_RD(0x00F2);
	pr_debug_intr("F2 int set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00F2, regval);

	regval =  MHL_SII_CBUS_RD(0x00F3);
	pr_debug_intr("F3 int set = %02X\n", (int)regval);
	MHL_SII_CBUS_WR(0x00F3, regval);
	pr_debug_intr("********* end of exiting in isr *************\n");
}