/* 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); } }
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); }
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); } }
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); } }
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; }
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); }
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; }
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"); }