static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) { #ifndef CONFIG_USB_MUSB_PERIPHERAL struct twl6030_usb *twl = _twl; int status = USB_EVENT_NONE; u8 hw_state; hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); if (hw_state & STS_USB_ID) { twl6030_usb_ldo_init(twl); regulator_enable(twl->usb3v3); twl->asleep = 1; twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1); twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x10); status = USB_EVENT_ID; twl->otg.default_a = true; twl->otg.state = OTG_STATE_A_IDLE; blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } else { twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x10); twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x1); } twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_LATCH_CLR, status); twl->linkstat = status; #endif return IRQ_HANDLED; }
static irqreturn_t twl6030_usb_irq(int irq, void *_twl) { struct twl6030_usb *twl = _twl; int status; u8 vbus_state, hw_state; hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); vbus_state = twl6030_readb(twl, TWL_MODULE_MAIN_CHARGE, CONTROLLER_STAT1); if (!(hw_state & STS_USB_ID)) { if (vbus_state & VBUS_DET) { twl6030_usb_ldo_init(twl); regulator_enable(twl->usb3v3); twl->asleep = 1; status = USB_EVENT_VBUS; twl->otg.default_a = false; twl->otg.state = OTG_STATE_B_IDLE; twl->linkstat = status; blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); } else { status = USB_EVENT_NONE; twl->linkstat = status; blocking_notifier_call_chain(&twl->otg.notifier, status, twl->otg.gadget); if (twl->asleep) { regulator_disable(twl->usb3v3); twl->asleep = 0; } wake_lock_timeout(&twl_lock,1*HZ); } } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return IRQ_HANDLED; }
static int __devinit twl6030_usb_probe(struct platform_device *pdev) { struct twl6030_usb *twl; int status, err; struct twl4030_usb_data *pdata; struct device *dev = &pdev->dev; pdata = dev->platform_data; twl = kzalloc(sizeof *twl, GFP_KERNEL); if (!twl) return -ENOMEM; twl->dev = &pdev->dev; twl->irq1 = platform_get_irq(pdev, 0); twl->irq2 = platform_get_irq(pdev, 1); twl->features = pdata->features; twl->otg.dev = twl->dev; twl->otg.label = "twl6030"; twl->otg.set_host = twl6030_set_host; twl->otg.set_peripheral = twl6030_set_peripheral; twl->otg.set_vbus = twl6030_set_vbus; twl->otg.init = twl6030_phy_init; twl->otg.shutdown = twl6030_phy_shutdown; twl->otg.set_suspend = twl6030_phy_suspend; twl->otg.start_srp = twl6030_start_srp; /* init spinlock for workqueue */ spin_lock_init(&twl->lock); err = twl6030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); kfree(twl); return err; } otg_set_transceiver(&twl->otg); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier); INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); twl->irq_enabled = true; status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq1, status); device_remove_file(twl->dev, &dev_attr_vbus); kfree(twl); return status; } status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq2, status); free_irq(twl->irq1, twl); device_remove_file(twl->dev, &dev_attr_vbus); kfree(twl); return status; } twl->asleep = 0; pdata->phy_init(dev); twl6030_phy_suspend(&twl->otg, 0); twl6030_enable_irq(&twl->otg); dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); return 0; }
static int twl6030_usb_probe(struct platform_device *pdev) { u32 ret; struct twl6030_usb *twl; int status, err; struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; struct twl4030_usb_data *pdata = dev_get_platdata(dev); twl = devm_kzalloc(dev, sizeof(*twl), GFP_KERNEL); if (!twl) return -ENOMEM; twl->dev = &pdev->dev; twl->irq1 = platform_get_irq(pdev, 0); twl->irq2 = platform_get_irq(pdev, 1); twl->linkstat = MUSB_UNKNOWN; twl->comparator.set_vbus = twl6030_set_vbus; twl->comparator.start_srp = twl6030_start_srp; ret = omap_usb2_set_comparator(&twl->comparator); if (ret == -ENODEV) { dev_info(&pdev->dev, "phy not ready, deferring probe"); return -EPROBE_DEFER; } if (np) { twl->regulator = "usb"; } else if (pdata) { if (pdata->features & TWL6032_SUBCLASS) twl->regulator = "ldousb"; else twl->regulator = "vusb"; } else { dev_err(&pdev->dev, "twl6030 initialized without pdata\n"); return -EINVAL; } /* init spinlock for workqueue */ spin_lock_init(&twl->lock); err = twl6030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); return err; } platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl6030_usb", twl); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq1, status); device_remove_file(twl->dev, &dev_attr_vbus); return status; } status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "twl6030_usb", twl); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq2, status); free_irq(twl->irq1, twl); device_remove_file(twl->dev, &dev_attr_vbus); return status; } twl->asleep = 0; twl6030_enable_irq(twl); dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); return 0; }
static int __devinit twl6030_usb_probe(struct platform_device *pdev) { struct twl6030_usb *twl; int status,err,vbus_state; struct twl4030_usb_data *pdata; struct device *dev = &pdev->dev; pdata = dev->platform_data; twl = kzalloc(sizeof *twl, GFP_KERNEL); if (!twl) return -ENOMEM; twl->dev = &pdev->dev; twl->irq1 = platform_get_irq(pdev, 0); twl->irq2 = platform_get_irq(pdev, 1); twl->otg.dev = twl->dev; twl->otg.label = "twl6030"; twl->otg.set_host = twl6030_set_host; twl->otg.set_peripheral = twl6030_set_peripheral; twl->otg.set_suspend = twl6030_set_suspend; twl->asleep = 1; #ifndef CONFIG_USB_ETH_RNDIS twl->otg.set_power = twl6030_set_input_current_limit; twl->otg.set_vbus = twl6030_set_vbus; #endif twl->otg.set_hz_mode = twl6030_set_hz_mode; twl->otg.init = phy_init; twl->otg.shutdown = phy_shutdown; twl->otg.enable_irq = twl6030_enable_irq; twl->otg.set_clk = set_phy_clk; twl->otg.shutdown = phy_shutdown; twl->prev_vbus = 0; twl->vusb = regulator_get(NULL, "usb-phy"); if (IS_ERR(twl->vusb)) { pr_err("Unable to get usb-phy regulator\n"); } twl->mbid=quanta_get_mbid(); printk(KERN_INFO "%s mbid=%d\n",__func__,twl->mbid); err = regulator_set_voltage(twl->vusb, 3300000, 3300000); //regulator_disable(twl->vusb); /* init spinlock for workqueue */ spin_lock_init(&twl->lock); err = twl6030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); kfree(twl); return err; } otg_set_transceiver(&twl->otg); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); INIT_WORK(&twl->vbus_work, vbus_monitor_work_func); INIT_WORK(&twl->id_work, id_monitor_work_func); /* Our job is to use irqs and status from the power module * to keep the transceiver disabled when nothing's connected. * * FIXME we actually shouldn't start enabling it until the * USB controller drivers have said they're ready, by calling * set_host() and/or set_peripheral() ... OTG_capable boards * need both handles, otherwise just one suffices. */ twl->irq_enabled = true; status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq1, status); kfree(twl); return status; } status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq2, status); kfree(twl); return status; } vbus_state = twl6030_readb(twl, TWL6030_MODULE_CHARGER, CONTROLLER_STAT1); wake_lock_init(&twlusb_lock, WAKE_LOCK_SUSPEND, "usb_wake_lock"); ctrl_base = ioremap(0x4A002000, SZ_1K); /* power down the phy by default can be enabled on connect */ __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF); dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); return 0; }
static int __devinit twl6030_usb_probe(struct platform_device *pdev) { struct twl6030_usb *twl; int status, err; twl = kzalloc(sizeof *twl, GFP_KERNEL); if (!twl) return -ENOMEM; twl->dev = &pdev->dev; twl->irq = platform_get_irq(pdev, 0); twl->otg.dev = twl->dev; twl->otg.label = "twl6030"; twl->otg.set_host = twl6030_set_host; twl->otg.set_peripheral = twl6030_set_peripheral; twl->otg.set_suspend = twl6030_set_suspend; twl->asleep = 1; twl->otg.set_vbus = twl6030_set_vbus; twl->otg.init = phy_init; twl->otg.enable_irq = twl6030_enable_irq; twl->otg.set_clk = set_phy_clk; twl->otg.shutdown = phy_shutdown; twl->prev_vbus = 0; /* init spinlock for workqueue */ spin_lock_init(&twl->lock); err = twl6030_usb_ldo_init(twl); if (err) { dev_err(&pdev->dev, "ldo init failed\n"); kfree(twl); return err; } otg_set_transceiver(&twl->otg); platform_set_drvdata(pdev, twl); if (device_create_file(&pdev->dev, &dev_attr_vbus)) dev_warn(&pdev->dev, "could not create sysfs file\n"); BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); /* Our job is to use irqs and status from the power module * to keep the transceiver disabled when nothing's connected. * * FIXME we actually shouldn't start enabling it until the * USB controller drivers have said they're ready, by calling * set_host() and/or set_peripheral() ... OTG_capable boards * need both handles, otherwise just one suffices. */ // LGE_UPDATE_S INIT_WORK(&twl6030_usb_irq_wq, twl6030_usb_irq_wq_func); INIT_WORK(&twl6030_usbotg_irq_wq, twl6030_usbotg_irq_wq_func); // LGE_UPDATE_E twl->irq_enabled = true; status = request_threaded_irq(twl->irq, NULL, twl6030_usbotg_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq, status); kfree(twl); return status; } twl->irq = platform_get_irq(pdev, 1); status = request_threaded_irq(twl->irq, NULL, twl6030_usb_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "twl6030_usb", twl); if (status < 0) { dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", twl->irq, status); kfree(twl); return status; } ctrl_base = ioremap(0x4A002000, SZ_1K); /* power down the phy by default can be enabled on connect */ __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF); dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); return 0; }