extractedLnx/linux-2.6.38/drivers/usb/otg/langwell_otg.c_langwell_otg_work.c
static void langwell_otg_work(struct work_struct *work)
{
struct langwell_otg *lnw;
struct intel_mid_otg_xceiv *iotg;
int retval;
struct pci_dev *pdev;
lnw = container_of(work, struct langwell_otg, work);
iotg = &lnw->iotg;
pdev = to_pci_dev(lnw->dev);
dev_dbg(lnw->dev, "%s: old state = %s\n", __func__,
state_string(iotg->otg.state));
switch (iotg->otg.state) {
case OTG_STATE_UNDEFINED:
case OTG_STATE_B_IDLE:
if (!iotg->hsm.id) {
langwell_otg_del_timer(b_srp_init_tmr);
del_timer_sync(&lnw->hsm_timer);
iotg->otg.default_a = 1;
iotg->hsm.a_srp_det = 0;
langwell_otg_chrg_vbus(0);
set_host_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_A_IDLE;
langwell_update_transceiver();
} else if (iotg->hsm.b_sess_vld) {
langwell_otg_del_timer(b_srp_init_tmr);
del_timer_sync(&lnw->hsm_timer);
iotg->hsm.b_sess_end = 0;
iotg->hsm.a_bus_suspend = 0;
langwell_otg_chrg_vbus(0);
if (lnw->iotg.start_peripheral) {
lnw->iotg.start_peripheral(&lnw->iotg);
iotg->otg.state = OTG_STATE_B_PERIPHERAL;
} else
dev_dbg(lnw->dev, "client driver not loaded\n");
} else if (iotg->hsm.b_srp_init_tmout) {
iotg->hsm.b_srp_init_tmout = 0;
dev_warn(lnw->dev, "SRP init timeout\n");
} else if (iotg->hsm.b_srp_fail_tmout) {
iotg->hsm.b_srp_fail_tmout = 0;
iotg->hsm.b_bus_req = 0;
/* No silence failure */
langwell_otg_nsf_msg(6);
} else if (iotg->hsm.b_bus_req && iotg->hsm.b_sess_end) {
del_timer_sync(&lnw->hsm_timer);
/* workaround for b_se0_srp detection */
retval = langwell_otg_check_se0_srp(0);
if (retval) {
iotg->hsm.b_bus_req = 0;
dev_dbg(lnw->dev, "LS isn't SE0, try later\n");
} else {
/* clear the PHCD before start srp */
langwell_otg_phy_low_power(0);
/* Start SRP */
langwell_otg_add_timer(b_srp_init_tmr);
iotg->otg.start_srp(&iotg->otg);
langwell_otg_del_timer(b_srp_init_tmr);
langwell_otg_add_ktimer(TB_SRP_FAIL_TMR);
/* reset PHY low power mode here */
langwell_otg_phy_low_power_wait(1);
}
}
break;
case OTG_STATE_B_SRP_INIT:
if (!iotg->hsm.id) {
iotg->otg.default_a = 1;
iotg->hsm.a_srp_det = 0;
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
langwell_otg_chrg_vbus(0);
set_host_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_A_IDLE;
langwell_update_transceiver();
} else if (iotg->hsm.b_sess_vld) {
langwell_otg_chrg_vbus(0);
if (lnw->iotg.start_peripheral) {
lnw->iotg.start_peripheral(&lnw->iotg);
iotg->otg.state = OTG_STATE_B_PERIPHERAL;
} else
dev_dbg(lnw->dev, "client driver not loaded\n");
}
break;
case OTG_STATE_B_PERIPHERAL:
if (!iotg->hsm.id) {
iotg->otg.default_a = 1;
iotg->hsm.a_srp_det = 0;
langwell_otg_chrg_vbus(0);
if (lnw->iotg.stop_peripheral)
lnw->iotg.stop_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver has been removed.\n");
set_host_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_A_IDLE;
langwell_update_transceiver();
} else if (!iotg->hsm.b_sess_vld) {
iotg->hsm.b_hnp_enable = 0;
if (lnw->iotg.stop_peripheral)
lnw->iotg.stop_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver has been removed.\n");
iotg->otg.state = OTG_STATE_B_IDLE;
} else if (iotg->hsm.b_bus_req && iotg->otg.gadget &&
iotg->otg.gadget->b_hnp_enable &&
iotg->hsm.a_bus_suspend) {
if (lnw->iotg.stop_peripheral)
lnw->iotg.stop_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver has been removed.\n");
langwell_otg_HAAR(1);
iotg->hsm.a_conn = 0;
if (lnw->iotg.start_host) {
lnw->iotg.start_host(&lnw->iotg);
iotg->otg.state = OTG_STATE_B_WAIT_ACON;
} else
dev_dbg(lnw->dev,
"host driver not loaded.\n");
iotg->hsm.a_bus_resume = 0;
langwell_otg_add_ktimer(TB_ASE0_BRST_TMR);
}
break;
case OTG_STATE_B_WAIT_ACON:
if (!iotg->hsm.id) {
/* delete hsm timer for b_ase0_brst_tmr */
del_timer_sync(&lnw->hsm_timer);
iotg->otg.default_a = 1;
iotg->hsm.a_srp_det = 0;
langwell_otg_chrg_vbus(0);
langwell_otg_HAAR(0);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
set_host_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_A_IDLE;
langwell_update_transceiver();
} else if (!iotg->hsm.b_sess_vld) {
/* delete hsm timer for b_ase0_brst_tmr */
del_timer_sync(&lnw->hsm_timer);
iotg->hsm.b_hnp_enable = 0;
iotg->hsm.b_bus_req = 0;
langwell_otg_chrg_vbus(0);
langwell_otg_HAAR(0);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
set_client_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_B_IDLE;
} else if (iotg->hsm.a_conn) {
/* delete hsm timer for b_ase0_brst_tmr */
del_timer_sync(&lnw->hsm_timer);
langwell_otg_HAAR(0);
iotg->otg.state = OTG_STATE_B_HOST;
langwell_update_transceiver();
} else if (iotg->hsm.a_bus_resume ||
iotg->hsm.b_ase0_brst_tmout) {
/* delete hsm timer for b_ase0_brst_tmr */
del_timer_sync(&lnw->hsm_timer);
langwell_otg_HAAR(0);
langwell_otg_nsf_msg(7);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
iotg->hsm.a_bus_suspend = 0;
iotg->hsm.b_bus_req = 0;
if (lnw->iotg.start_peripheral)
lnw->iotg.start_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver not loaded.\n");
iotg->otg.state = OTG_STATE_B_PERIPHERAL;
}
break;
case OTG_STATE_B_HOST:
if (!iotg->hsm.id) {
iotg->otg.default_a = 1;
iotg->hsm.a_srp_det = 0;
langwell_otg_chrg_vbus(0);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
set_host_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_A_IDLE;
langwell_update_transceiver();
} else if (!iotg->hsm.b_sess_vld) {
iotg->hsm.b_hnp_enable = 0;
iotg->hsm.b_bus_req = 0;
langwell_otg_chrg_vbus(0);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
set_client_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_B_IDLE;
} else if ((!iotg->hsm.b_bus_req) ||
(!iotg->hsm.a_conn)) {
iotg->hsm.b_bus_req = 0;
langwell_otg_loc_sof(0);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
iotg->hsm.a_bus_suspend = 0;
if (lnw->iotg.start_peripheral)
lnw->iotg.start_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver not loaded.\n");
iotg->otg.state = OTG_STATE_B_PERIPHERAL;
}
break;
case OTG_STATE_A_IDLE:
iotg->otg.default_a = 1;
if (iotg->hsm.id) {
iotg->otg.default_a = 0;
iotg->hsm.b_bus_req = 0;
iotg->hsm.vbus_srp_up = 0;
langwell_otg_chrg_vbus(0);
set_client_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_B_IDLE;
langwell_update_transceiver();
} else if (!iotg->hsm.a_bus_drop &&
(iotg->hsm.a_srp_det || iotg->hsm.a_bus_req)) {
langwell_otg_phy_low_power(0);
/* Turn on VBus */
iotg->otg.set_vbus(&iotg->otg, true);
iotg->hsm.vbus_srp_up = 0;
iotg->hsm.a_wait_vrise_tmout = 0;
langwell_otg_add_timer(a_wait_vrise_tmr);
iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
langwell_update_transceiver();
} else if (!iotg->hsm.a_bus_drop && iotg->hsm.a_sess_vld) {
iotg->hsm.vbus_srp_up = 1;
} else if (!iotg->hsm.a_sess_vld && iotg->hsm.vbus_srp_up) {
msleep(10);
langwell_otg_phy_low_power(0);
/* Turn on VBus */
iotg->otg.set_vbus(&iotg->otg, true);
iotg->hsm.a_srp_det = 1;
iotg->hsm.vbus_srp_up = 0;
iotg->hsm.a_wait_vrise_tmout = 0;
langwell_otg_add_timer(a_wait_vrise_tmr);
iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
langwell_update_transceiver();
} else if (!iotg->hsm.a_sess_vld &&
!iotg->hsm.vbus_srp_up) {
langwell_otg_phy_low_power(1);
}
break;
case OTG_STATE_A_WAIT_VRISE:
if (iotg->hsm.id) {
langwell_otg_del_timer(a_wait_vrise_tmr);
iotg->hsm.b_bus_req = 0;
iotg->otg.default_a = 0;
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
set_client_mode();
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_B_IDLE;
} else if (iotg->hsm.a_vbus_vld) {
langwell_otg_del_timer(a_wait_vrise_tmr);
iotg->hsm.b_conn = 0;
if (lnw->iotg.start_host)
lnw->iotg.start_host(&lnw->iotg);
else {
dev_dbg(lnw->dev, "host driver not loaded.\n");
break;
}
langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
iotg->otg.state = OTG_STATE_A_WAIT_BCON;
} else if (iotg->hsm.a_wait_vrise_tmout) {
iotg->hsm.b_conn = 0;
if (iotg->hsm.a_vbus_vld) {
if (lnw->iotg.start_host)
lnw->iotg.start_host(&lnw->iotg);
else {
dev_dbg(lnw->dev,
"host driver not loaded.\n");
break;
}
langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
iotg->otg.state = OTG_STATE_A_WAIT_BCON;
} else {
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_A_VBUS_ERR;
}
}
break;
case OTG_STATE_A_WAIT_BCON:
if (iotg->hsm.id) {
/* delete hsm timer for a_wait_bcon_tmr */
del_timer_sync(&lnw->hsm_timer);
iotg->otg.default_a = 0;
iotg->hsm.b_bus_req = 0;
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
set_client_mode();
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_B_IDLE;
langwell_update_transceiver();
} else if (!iotg->hsm.a_vbus_vld) {
/* delete hsm timer for a_wait_bcon_tmr */
del_timer_sync(&lnw->hsm_timer);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_A_VBUS_ERR;
} else if (iotg->hsm.a_bus_drop ||
(iotg->hsm.a_wait_bcon_tmout &&
!iotg->hsm.a_bus_req)) {
/* delete hsm timer for a_wait_bcon_tmr */
del_timer_sync(&lnw->hsm_timer);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
} else if (iotg->hsm.b_conn) {
/* delete hsm timer for a_wait_bcon_tmr */
del_timer_sync(&lnw->hsm_timer);
iotg->hsm.a_suspend_req = 0;
iotg->otg.state = OTG_STATE_A_HOST;
if (iotg->hsm.a_srp_det && iotg->otg.host &&
!iotg->otg.host->b_hnp_enable) {
/* SRP capable peripheral-only device */
iotg->hsm.a_bus_req = 1;
iotg->hsm.a_srp_det = 0;
} else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
iotg->otg.host->b_hnp_enable) {
/* It is not safe enough to do a fast
* transistion from A_WAIT_BCON to
* A_SUSPEND */
msleep(10000);
if (iotg->hsm.a_bus_req)
break;
if (request_irq(pdev->irq,
otg_dummy_irq, IRQF_SHARED,
driver_name, iotg->base) != 0) {
dev_dbg(lnw->dev,
"request interrupt %d fail\n",
pdev->irq);
}
langwell_otg_HABA(1);
iotg->hsm.b_bus_resume = 0;
iotg->hsm.a_aidl_bdis_tmout = 0;
langwell_otg_loc_sof(0);
/* clear PHCD to enable HW timer */
langwell_otg_phy_low_power(0);
langwell_otg_add_timer(a_aidl_bdis_tmr);
iotg->otg.state = OTG_STATE_A_SUSPEND;
} else if (!iotg->hsm.a_bus_req && iotg->otg.host &&
!iotg->otg.host->b_hnp_enable) {
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
}
}
break;
case OTG_STATE_A_HOST:
if (iotg->hsm.id) {
iotg->otg.default_a = 0;
iotg->hsm.b_bus_req = 0;
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
set_client_mode();
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_B_IDLE;
langwell_update_transceiver();
} else if (iotg->hsm.a_bus_drop ||
(iotg->otg.host &&
!iotg->otg.host->b_hnp_enable &&
!iotg->hsm.a_bus_req)) {
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
} else if (!iotg->hsm.a_vbus_vld) {
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_A_VBUS_ERR;
} else if (iotg->otg.host &&
iotg->otg.host->b_hnp_enable &&
!iotg->hsm.a_bus_req) {
/* Set HABA to enable hardware assistance to signal
* A-connect after receiver B-disconnect. Hardware
* will then set client mode and enable URE, SLE and
* PCE after the assistance. otg_dummy_irq is used to
* clean these ints when client driver is not resumed.
*/
if (request_irq(pdev->irq, otg_dummy_irq, IRQF_SHARED,
driver_name, iotg->base) != 0) {
dev_dbg(lnw->dev,
"request interrupt %d failed\n",
pdev->irq);
}
/* set HABA */
langwell_otg_HABA(1);
iotg->hsm.b_bus_resume = 0;
iotg->hsm.a_aidl_bdis_tmout = 0;
langwell_otg_loc_sof(0);
/* clear PHCD to enable HW timer */
langwell_otg_phy_low_power(0);
langwell_otg_add_timer(a_aidl_bdis_tmr);
iotg->otg.state = OTG_STATE_A_SUSPEND;
} else if (!iotg->hsm.b_conn || !iotg->hsm.a_bus_req) {
langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
iotg->otg.state = OTG_STATE_A_WAIT_BCON;
}
break;
case OTG_STATE_A_SUSPEND:
if (iotg->hsm.id) {
langwell_otg_del_timer(a_aidl_bdis_tmr);
langwell_otg_HABA(0);
free_irq(pdev->irq, iotg->base);
iotg->otg.default_a = 0;
iotg->hsm.b_bus_req = 0;
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
set_client_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_B_IDLE;
langwell_update_transceiver();
} else if (iotg->hsm.a_bus_req ||
iotg->hsm.b_bus_resume) {
langwell_otg_del_timer(a_aidl_bdis_tmr);
langwell_otg_HABA(0);
free_irq(pdev->irq, iotg->base);
iotg->hsm.a_suspend_req = 0;
langwell_otg_loc_sof(1);
iotg->otg.state = OTG_STATE_A_HOST;
} else if (iotg->hsm.a_aidl_bdis_tmout ||
iotg->hsm.a_bus_drop) {
langwell_otg_del_timer(a_aidl_bdis_tmr);
langwell_otg_HABA(0);
free_irq(pdev->irq, iotg->base);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
} else if (!iotg->hsm.b_conn && iotg->otg.host &&
iotg->otg.host->b_hnp_enable) {
langwell_otg_del_timer(a_aidl_bdis_tmr);
langwell_otg_HABA(0);
free_irq(pdev->irq, iotg->base);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
iotg->hsm.b_bus_suspend = 0;
iotg->hsm.b_bus_suspend_vld = 0;
/* msleep(200); */
if (lnw->iotg.start_peripheral)
lnw->iotg.start_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver not loaded.\n");
langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR);
iotg->otg.state = OTG_STATE_A_PERIPHERAL;
break;
} else if (!iotg->hsm.a_vbus_vld) {
langwell_otg_del_timer(a_aidl_bdis_tmr);
langwell_otg_HABA(0);
free_irq(pdev->irq, iotg->base);
if (lnw->iotg.stop_host)
lnw->iotg.stop_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_A_VBUS_ERR;
}
break;
case OTG_STATE_A_PERIPHERAL:
if (iotg->hsm.id) {
/* delete hsm timer for b_bus_suspend_tmr */
del_timer_sync(&lnw->hsm_timer);
iotg->otg.default_a = 0;
iotg->hsm.b_bus_req = 0;
if (lnw->iotg.stop_peripheral)
lnw->iotg.stop_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
set_client_mode();
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_B_IDLE;
langwell_update_transceiver();
} else if (!iotg->hsm.a_vbus_vld) {
/* delete hsm timer for b_bus_suspend_tmr */
del_timer_sync(&lnw->hsm_timer);
if (lnw->iotg.stop_peripheral)
lnw->iotg.stop_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
langwell_otg_phy_low_power_wait(1);
iotg->otg.state = OTG_STATE_A_VBUS_ERR;
} else if (iotg->hsm.a_bus_drop) {
/* delete hsm timer for b_bus_suspend_tmr */
del_timer_sync(&lnw->hsm_timer);
if (lnw->iotg.stop_peripheral)
lnw->iotg.stop_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver has been removed.\n");
/* Turn off VBus */
iotg->otg.set_vbus(&iotg->otg, false);
iotg->otg.state = OTG_STATE_A_WAIT_VFALL;
} else if (iotg->hsm.b_bus_suspend) {
/* delete hsm timer for b_bus_suspend_tmr */
del_timer_sync(&lnw->hsm_timer);
if (lnw->iotg.stop_peripheral)
lnw->iotg.stop_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver has been removed.\n");
if (lnw->iotg.start_host)
lnw->iotg.start_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver not loaded.\n");
langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
iotg->otg.state = OTG_STATE_A_WAIT_BCON;
} else if (iotg->hsm.b_bus_suspend_tmout) {
u32 val;
val = readl(lnw->iotg.base + CI_PORTSC1);
if (!(val & PORTSC_SUSP))
break;
if (lnw->iotg.stop_peripheral)
lnw->iotg.stop_peripheral(&lnw->iotg);
else
dev_dbg(lnw->dev,
"client driver has been removed.\n");
if (lnw->iotg.start_host)
lnw->iotg.start_host(&lnw->iotg);
else
dev_dbg(lnw->dev,
"host driver not loaded.\n");
langwell_otg_add_ktimer(TA_WAIT_BCON_TMR);
iotg->otg.state = OTG_STATE_A_WAIT_BCON;
}
break;
case OTG_STATE_A_VBUS_ERR:
if (iotg->hsm.id) {
iotg->otg.default_a = 0;
iotg->hsm.a_clr_err = 0;
iotg->hsm.a_srp_det = 0;
set_client_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_B_IDLE;
langwell_update_transceiver();
} else if (iotg->hsm.a_clr_err) {
iotg->hsm.a_clr_err = 0;
iotg->hsm.a_srp_det = 0;
reset_otg();
init_hsm();
if (iotg->otg.state == OTG_STATE_A_IDLE)
langwell_update_transceiver();
} else {
/* FW will clear PHCD bit when any VBus
* event detected. Reset PHCD to 1 again */
langwell_otg_phy_low_power(1);
}
break;
case OTG_STATE_A_WAIT_VFALL:
if (iotg->hsm.id) {
iotg->otg.default_a = 0;
set_client_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_B_IDLE;
langwell_update_transceiver();
} else if (iotg->hsm.a_bus_req) {
/* Turn on VBus */
iotg->otg.set_vbus(&iotg->otg, true);
iotg->hsm.a_wait_vrise_tmout = 0;
langwell_otg_add_timer(a_wait_vrise_tmr);
iotg->otg.state = OTG_STATE_A_WAIT_VRISE;
} else if (!iotg->hsm.a_sess_vld) {
iotg->hsm.a_srp_det = 0;
set_host_mode();
langwell_otg_phy_low_power(1);
iotg->otg.state = OTG_STATE_A_IDLE;
}
break;
default:
;
}
dev_dbg(lnw->dev, "%s: new state = %s\n", __func__,
state_string(iotg->otg.state));
}
Generated by GNU enscript 1.6.4.