static void b_peripheral(struct isp1301 *isp) { OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS; usb_gadget_vbus_connect(isp->otg.gadget); #ifdef CONFIG_USB_OTG enable_vbus_draw(isp, 8); otg_update_isp(isp); #else enable_vbus_draw(isp, 100); /* UDC driver just set OTG_BSESSVLD */ isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP); isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN); isp->otg.state = OTG_STATE_B_PERIPHERAL; pr_debug(" --> b_peripheral\n"); dump_regs(isp, "2periph"); #endif }
static void isp1301_work(struct work_struct *work) { struct isp1301 *isp = container_of(work, struct isp1301, work); int stop; /* implicit lock: we're the only task using this device */ isp->working = 1; do { stop = test_bit(WORK_STOP, &isp->todo); #ifdef CONFIG_USB_OTG /* transfer state from otg engine to isp1301 */ if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) { otg_update_isp(isp); put_device(&isp->client->dev); } #endif /* transfer state from isp1301 to otg engine */ if (test_and_clear_bit(WORK_UPDATE_OTG, &isp->todo)) { u8 stat = isp1301_clear_latch(isp); isp_update_otg(isp, stat); put_device(&isp->client->dev); } if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) { u32 otg_ctrl; /* * skip A_WAIT_VRISE; hc transitions invisibly * skip A_WAIT_BCON; same. */ switch (isp->otg.state) { case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_WAIT_VRISE: isp->otg.state = OTG_STATE_A_HOST; pr_debug(" --> a_host\n"); otg_ctrl = omap_readl(OTG_CTRL); otg_ctrl |= OTG_A_BUSREQ; otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ) & OTG_CTRL_MASK; omap_writel(otg_ctrl, OTG_CTRL); break; case OTG_STATE_B_WAIT_ACON: isp->otg.state = OTG_STATE_B_HOST; pr_debug(" --> b_host (acon)\n"); break; case OTG_STATE_B_HOST: case OTG_STATE_B_IDLE: case OTG_STATE_A_IDLE: break; default: pr_debug(" host resume in %s\n", state_name(isp)); } host_resume(isp); // mdelay(10); put_device(&isp->client->dev); } if (test_and_clear_bit(WORK_TIMER, &isp->todo)) { #ifdef VERBOSE dump_regs(isp, "timer"); if (!stop) mod_timer(&isp->timer, jiffies + TIMER_JIFFIES); #endif put_device(&isp->client->dev); } if (isp->todo) dev_vdbg(&isp->client->dev, "work done, todo = 0x%lx\n", isp->todo); if (stop) { dev_dbg(&isp->client->dev, "stop\n"); break; } } while (isp->todo); isp->working = 0; }