static struct platform_driver ehci_msm_driver = {
.probe = ehci_msm_probe,
.remove = __exit_p(ehci_msm_remove),
.driver = {.name = "msm_hsusb_host",
.pm = &ehci_msm_dev_pm_ops, },
};
ehci_msm_probe(struct platform_device *pdev)
msm_xusb_init_host(pdev, mhcd);
otg_set_host(mhcd->xceiv, &hcd->self);
otg->set_host(otg, host);
msm_otg_set_host(struct otg_transceiver *xceiv, struct usb_bus *host)
dev->usbdev_nb.notifier_call = usbdev_notify;//挂载通知函数
usb_register_notify(&dev->usbdev_nb);//注册通知链
queue_work(dev->wq, &dev->sm_work);//驱动otg状态机
//--------------------------------------------------------------------------------------------------------
//下面看下通知函数
static int usbdev_notify(struct notifier_block *self,unsigned long action, void *device)
{
enum usb_otg_state state;
struct msm_otg *dev = container_of(self, struct msm_otg, usbdev_nb);
struct usb_device *udev = device;
int work = 1;
unsigned long flags;
if (!udev->parent || udev->parent->parent)//直接插入hub中
goto out;
spin_lock_irqsave(&dev->lock, flags);
state = dev->otg.state;//取出当前otg状态
spin_unlock_irqrestore(&dev->lock, flags);
switch (state) {
case OTG_STATE_A_WAIT_BCON:
if (action == USB_DEVICE_ADD) {
pr_debug("B_CONN set\n");
set_bit(B_CONN, &dev->inputs);//改变位域的值
if (udev->actconfig) {
set_aca_bmaxpower(dev,udev->actconfig->desc.bMaxPower * 2);
goto do_work;
}
if (udev->portnum == udev->bus->otg_port)
set_aca_bmaxpower(dev, USB_IB_UNCFG);
else
set_aca_bmaxpower(dev, 100);
}
break;
case OTG_STATE_A_HOST:
if (action == USB_DEVICE_REMOVE) {
pr_debug("B_CONN clear\n");
clear_bit(B_CONN, &dev->inputs);//改变位域的值
set_aca_bmaxpower(dev, 0);
}
break;
default:
work = 0;
break;
}
do_work:
if (work) {
wake_lock(&dev->wlock);
queue_work(dev->wq, &dev->sm_work);//调度work,驱动otg状态机
}
out:
return NOTIFY_OK;
}
//下面是该通知链调用的时机
static int generic_probe(struct usb_device *udev)
{
................
/* USB device state == configured ... usable */
usb_notify_add_device(udev);//调用通知链函数
return 0;
}
阅读(670) | 评论(0) | 转发(0) |