static int tahvo_usb_set_host(struct usb_otg *otg, struct usb_bus *host) { struct tahvo_usb *tu = container_of(otg->phy, struct tahvo_usb, phy); dev_dbg(&tu->pt_dev->dev, "%s %p\n", __func__, host); mutex_lock(&tu->serialize); if (host == NULL) { if (tu->tahvo_mode == TAHVO_MODE_HOST) tahvo_usb_power_off(tu); otg->host = NULL; mutex_unlock(&tu->serialize); return 0; } if (tu->tahvo_mode == TAHVO_MODE_HOST) { otg->host = NULL; tahvo_usb_become_host(tu); } otg->host = host; mutex_unlock(&tu->serialize); return 0; }
static int tahvo_usb_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) { struct tahvo_usb *tu = container_of(otg->phy, struct tahvo_usb, phy); dev_dbg(&tu->pt_dev->dev, "%s %p\n", __func__, gadget); mutex_lock(&tu->serialize); if (!gadget) { if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL) tahvo_usb_power_off(tu); tu->phy.otg->gadget = NULL; mutex_unlock(&tu->serialize); return 0; } tu->phy.otg->gadget = gadget; if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL) tahvo_usb_become_peripheral(tu); mutex_unlock(&tu->serialize); return 0; }
static int tahvo_usb_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget) { struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg); dev_dbg(&tu->pt_dev->dev, "set_peripheral %p\n", gadget); if (!otg) return -ENODEV; #if defined(CONFIG_USB_OTG) || defined(CONFIG_USB_GADGET_OMAP) mutex_lock(&tu->serialize); if (!gadget) { if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL) tahvo_usb_power_off(tu); tu->otg.gadget = NULL; mutex_unlock(&tu->serialize); return 0; } tu->otg.gadget = gadget; if (TAHVO_MODE(tu) == TAHVO_MODE_PERIPHERAL) tahvo_usb_become_peripheral(tu); mutex_unlock(&tu->serialize); #else /* No gadget mode configured, so do not allow host controlled to be set */ return -EINVAL; #endif return 0; }
static ssize_t otg_mode_store(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { struct tahvo_usb *tu = dev_get_drvdata(device); int r; mutex_lock(&tu->serialize); if (count >= 4 && strncmp(buf, "host", 4) == 0) { if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL) tahvo_usb_stop_peripheral(tu); tu->tahvo_mode = TAHVO_MODE_HOST; if (tu->phy.otg->host) { dev_info(device, "HOST mode: host controller present\n"); tahvo_usb_become_host(tu); } else { dev_info(device, "HOST mode: no host controller, powering off\n"); tahvo_usb_power_off(tu); } r = strlen(buf); } else if (count >= 10 && strncmp(buf, "peripheral", 10) == 0) { if (tu->tahvo_mode == TAHVO_MODE_HOST) tahvo_usb_stop_host(tu); tu->tahvo_mode = TAHVO_MODE_PERIPHERAL; if (tu->phy.otg->gadget) { dev_info(device, "PERIPHERAL mode: gadget driver present\n"); tahvo_usb_become_peripheral(tu); } else { dev_info(device, "PERIPHERAL mode: no gadget driver, powering off\n"); tahvo_usb_power_off(tu); } r = strlen(buf); } else { r = -EINVAL; } mutex_unlock(&tu->serialize); return r; }
static ssize_t otg_mode_store(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { struct tahvo_usb *tu = (struct tahvo_usb*) device->driver_data; int r; r = strlen(buf); mutex_lock(&tu->serialize); if (strncmp(buf, "host", 4) == 0) { if (tu->tahvo_mode == TAHVO_MODE_PERIPHERAL) tahvo_usb_stop_peripheral(tu); tu->tahvo_mode = TAHVO_MODE_HOST; if (tu->otg.host) { printk(KERN_INFO "Selected HOST mode: host controller present.\n"); tahvo_usb_become_host(tu); } else { printk(KERN_INFO "Selected HOST mode: no host controller, powering off.\n"); tahvo_usb_power_off(tu); } } else if (strncmp(buf, "peripheral", 10) == 0) { if (tu->tahvo_mode == TAHVO_MODE_HOST) tahvo_usb_stop_host(tu); tu->tahvo_mode = TAHVO_MODE_PERIPHERAL; if (tu->otg.gadget) { printk(KERN_INFO "Selected PERIPHERAL mode: gadget driver present.\n"); tahvo_usb_become_peripheral(tu); } else { printk(KERN_INFO "Selected PERIPHERAL mode: no gadget driver, powering off.\n"); tahvo_usb_power_off(tu); } } else r = -EINVAL; mutex_unlock(&tu->serialize); return r; }
static int tahvo_usb_set_host(struct otg_transceiver *otg, struct usb_bus *host) { struct tahvo_usb *tu = container_of(otg, struct tahvo_usb, otg); u32 l; dev_dbg(&tu->pt_dev->dev, "set_host %p\n", host); if (otg == NULL) return -ENODEV; #if defined(CONFIG_USB_OTG) || !defined(CONFIG_USB_GADGET_OMAP) mutex_lock(&tu->serialize); if (host == NULL) { if (TAHVO_MODE(tu) == TAHVO_MODE_HOST) tahvo_usb_power_off(tu); tu->otg.host = NULL; mutex_unlock(&tu->serialize); return 0; } l = omap_readl(OTG_SYSCON_1); l &= ~(OTG_IDLE_EN | HST_IDLE_EN | DEV_IDLE_EN); omap_writel(l, OTG_SYSCON_1); if (TAHVO_MODE(tu) == TAHVO_MODE_HOST) { tu->otg.host = NULL; tahvo_usb_become_host(tu); } else host_suspend(tu); tu->otg.host = host; mutex_unlock(&tu->serialize); #else /* No host mode configured, so do not allow host controlled to be set */ return -EINVAL; #endif return 0; }
static int tahvo_usb_probe(struct platform_device *pdev) { struct retu_dev *rdev = dev_get_drvdata(pdev->dev.parent); struct tahvo_usb *tu; int ret; tu = devm_kzalloc(&pdev->dev, sizeof(*tu), GFP_KERNEL); if (!tu) return -ENOMEM; tu->phy.otg = devm_kzalloc(&pdev->dev, sizeof(*tu->phy.otg), GFP_KERNEL); if (!tu->phy.otg) return -ENOMEM; tu->pt_dev = pdev; /* Default mode */ #ifdef CONFIG_TAHVO_USB_HOST_BY_DEFAULT tu->tahvo_mode = TAHVO_MODE_HOST; #else tu->tahvo_mode = TAHVO_MODE_PERIPHERAL; #endif mutex_init(&tu->serialize); tu->ick = devm_clk_get(&pdev->dev, "usb_l4_ick"); if (!IS_ERR(tu->ick)) clk_enable(tu->ick); /* * Set initial state, so that we generate kevents only on state changes. */ tu->vbus_state = retu_read(rdev, TAHVO_REG_IDSR) & TAHVO_STAT_VBUS; tu->extcon.name = DRIVER_NAME; tu->extcon.supported_cable = tahvo_cable; tu->extcon.dev.parent = &pdev->dev; ret = extcon_dev_register(&tu->extcon); if (ret) { dev_err(&pdev->dev, "could not register extcon device: %d\n", ret); goto err_disable_clk; } /* Set the initial cable state. */ extcon_set_cable_state(&tu->extcon, "USB-HOST", tu->tahvo_mode == TAHVO_MODE_HOST); extcon_set_cable_state(&tu->extcon, "USB", tu->vbus_state); /* Create OTG interface */ tahvo_usb_power_off(tu); tu->phy.dev = &pdev->dev; tu->phy.state = OTG_STATE_UNDEFINED; tu->phy.label = DRIVER_NAME; tu->phy.set_suspend = tahvo_usb_set_suspend; tu->phy.otg->phy = &tu->phy; tu->phy.otg->set_host = tahvo_usb_set_host; tu->phy.otg->set_peripheral = tahvo_usb_set_peripheral; ret = usb_add_phy(&tu->phy, USB_PHY_TYPE_USB2); if (ret < 0) { dev_err(&pdev->dev, "cannot register USB transceiver: %d\n", ret); goto err_extcon_unreg; } dev_set_drvdata(&pdev->dev, tu); tu->irq = platform_get_irq(pdev, 0); ret = request_threaded_irq(tu->irq, NULL, tahvo_usb_vbus_interrupt, 0, "tahvo-vbus", tu); if (ret) { dev_err(&pdev->dev, "could not register tahvo-vbus irq: %d\n", ret); goto err_remove_phy; } /* Attributes */ ret = sysfs_create_group(&pdev->dev.kobj, &tahvo_attr_group); if (ret) { dev_err(&pdev->dev, "cannot create sysfs group: %d\n", ret); goto err_free_irq; } return 0; err_free_irq: free_irq(tu->irq, tu); err_remove_phy: usb_remove_phy(&tu->phy); err_extcon_unreg: extcon_dev_unregister(&tu->extcon); err_disable_clk: if (!IS_ERR(tu->ick)) clk_disable(tu->ick); return ret; }
static int tahvo_usb_probe(struct device *dev) { struct tahvo_usb *tu; int ret; dev_dbg(dev, "probe\n"); /* Create driver data */ tu = kmalloc(sizeof(*tu), GFP_KERNEL); if (!tu) return -ENOMEM; memset(tu, 0, sizeof(*tu)); tu->pt_dev = container_of(dev, struct platform_device, dev); #ifdef CONFIG_USB_OTG /* Default mode */ #ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT tu->tahvo_mode = TAHVO_MODE_HOST; #else tu->tahvo_mode = TAHVO_MODE_PERIPHERAL; #endif #endif INIT_WORK(&tu->irq_work, tahvo_usb_irq_work); mutex_init(&tu->serialize); /* Set initial state, so that we generate kevents only on * state changes */ tu->vbus_state = tahvo_read_reg(TAHVO_REG_IDSR) & 0x01; /* We cannot enable interrupt until omap_udc is initialized */ ret = tahvo_request_irq(TAHVO_INT_VBUSON, tahvo_usb_vbus_interrupt, (unsigned long) tu, "vbus_interrupt"); if (ret != 0) { kfree(tu); printk(KERN_ERR "Could not register Tahvo interrupt for VBUS\n"); return ret; } /* Attributes */ ret = device_create_file(dev, &dev_attr_vbus_state); #ifdef CONFIG_USB_OTG ret |= device_create_file(dev, &dev_attr_otg_mode); #endif if (ret) printk(KERN_ERR "attribute creation failed: %d\n", ret); /* Create OTG interface */ tahvo_usb_power_off(tu); tu->otg.state = OTG_STATE_UNDEFINED; tu->otg.label = DRIVER_NAME; tu->otg.set_host = tahvo_usb_set_host; tu->otg.set_peripheral = tahvo_usb_set_peripheral; tu->otg.set_power = tahvo_usb_set_power; tu->otg.set_suspend = tahvo_usb_set_suspend; tu->otg.start_srp = tahvo_usb_start_srp; tu->otg.start_hnp = tahvo_usb_start_hnp; ret = otg_set_transceiver(&tu->otg); if (ret < 0) { printk(KERN_ERR "Cannot register USB transceiver\n"); kfree(tu); tahvo_free_irq(TAHVO_INT_VBUSON); return ret; } dev->driver_data = tu; /* Act upon current vbus state once at startup. A vbus state irq may or * may not be generated in addition to this. */ schedule_work(&tu->irq_work); return 0; }
static int __init tahvo_usb_probe(struct platform_device *pdev) { struct tahvo_usb *tu; struct device *dev = &pdev->dev; int ret; int irq; dev_dbg(dev, "probe\n"); /* Create driver data */ tu = kzalloc(sizeof(*tu), GFP_KERNEL); if (!tu) return -ENOMEM; tahvo_usb_device = tu; tu->dev = dev; tu->pt_dev = pdev; #ifdef CONFIG_USB_OTG /* Default mode */ #ifdef CONFIG_CBUS_TAHVO_USB_HOST_BY_DEFAULT tu->tahvo_mode = TAHVO_MODE_HOST; #else tu->tahvo_mode = TAHVO_MODE_PERIPHERAL; #endif #endif mutex_init(&tu->serialize); tu->ick = clk_get(NULL, "usb_l4_ick"); if (IS_ERR(tu->ick)) { dev_err(dev, "Failed to get usb_l4_ick\n"); ret = PTR_ERR(tu->ick); goto err_free_tu; } clk_enable(tu->ick); /* Set initial state, so that we generate kevents only on * state changes */ tu->vbus_state = tahvo_read_reg(tu->dev, TAHVO_REG_IDSR) & 0x01; irq = platform_get_irq(pdev, 0); tu->irq = irq; /* We cannot enable interrupt until omap_udc is initialized */ ret = request_threaded_irq(irq, NULL, tahvo_usb_vbus_interrupt, IRQF_ONESHOT, "tahvo-vbus", tu); if (ret != 0) { printk(KERN_ERR "Could not register Tahvo interrupt for VBUS\n"); goto err_release_clk; } /* Attributes */ ret = device_create_file(dev, &dev_attr_vbus_state); #ifdef CONFIG_USB_OTG ret |= device_create_file(dev, &dev_attr_otg_mode); #endif if (ret) printk(KERN_ERR "attribute creation failed: %d\n", ret); /* Create OTG interface */ tahvo_usb_power_off(tu); tu->otg.state = OTG_STATE_UNDEFINED; tu->otg.label = DRIVER_NAME; tu->otg.set_host = tahvo_usb_set_host; tu->otg.set_peripheral = tahvo_usb_set_peripheral; tu->otg.set_power = tahvo_usb_set_power; tu->otg.set_suspend = tahvo_usb_set_suspend; tu->otg.start_srp = tahvo_usb_start_srp; tu->otg.start_hnp = tahvo_usb_start_hnp; ret = otg_set_transceiver(&tu->otg); if (ret < 0) { printk(KERN_ERR "Cannot register USB transceiver\n"); goto err_free_irq; } dev_set_drvdata(dev, tu); return 0; err_free_irq: free_irq(tu->irq, tu); err_release_clk: clk_disable(tu->ick); clk_put(tu->ick); err_free_tu: kfree(tu); tahvo_usb_device = NULL; return ret; }