コード例 #1
0
static int tegra_otg_probe(struct platform_device *pdev)
{
	struct tegra_otg_data *tegra;
	struct resource *res;
	struct tegra_usb_otg_data *pdata = dev_get_platdata(&pdev->dev);
	int err;

	tegra = kzalloc(sizeof(struct tegra_otg_data), GFP_KERNEL);
	if (!tegra)
		return -ENOMEM;

	tegra->otg.dev = &pdev->dev;
	tegra->otg.label = "tegra-otg";
	tegra->otg.state = OTG_STATE_UNDEFINED;
	tegra->otg.set_host = tegra_otg_set_host;
	tegra->otg.set_peripheral = tegra_otg_set_peripheral;
	tegra->otg.set_suspend = tegra_otg_set_suspend;
	tegra->otg.set_power = tegra_otg_set_power;
	spin_lock_init(&tegra->lock);

	if (pdata) {
		tegra->builtin_host = !pdata->ehci_pdata->builtin_host_disabled;
	}

	platform_set_drvdata(pdev, tegra);
	tegra_clone = tegra;
	tegra->interrupt_mode = true;
	tegra->suspended = false;

	tegra->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(tegra->clk)) {
		dev_err(&pdev->dev, "Can't get otg clock\n");
		err = PTR_ERR(tegra->clk);
		goto err_clk;
	}

	err = clk_enable(tegra->clk);
	if (err)
		goto err_clken;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get I/O memory\n");
		err = -ENXIO;
		goto err_io;
	}
	tegra->regs = ioremap(res->start, resource_size(res));
	if (!tegra->regs) {
		err = -ENOMEM;
		goto err_io;
	}

	tegra->otg.state = OTG_STATE_A_SUSPEND;

	err = otg_set_transceiver(&tegra->otg);
	if (err) {
		dev_err(&pdev->dev, "can't register transceiver (%d)\n", err);
		goto err_otg;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get IRQ\n");
		err = -ENXIO;
		goto err_irq;
	}

	tegra->irq = res->start;
	err = request_threaded_irq(tegra->irq, tegra_otg_irq,
				   NULL,
				   IRQF_SHARED | IRQF_TRIGGER_HIGH,
				   "tegra-otg", tegra);
	if (err) {
		dev_err(&pdev->dev, "Failed to register IRQ\n");
		goto err_irq;
	}

	err = enable_irq_wake(tegra->irq);
	if (err < 0) {
		dev_warn(&pdev->dev,
			"Couldn't enable USB otg mode wakeup, irq=%d, error=%d\n",
			tegra->irq, err);
		err = 0;
	}

	INIT_WORK(&tegra->work, irq_work);

	dev_info(&pdev->dev, "otg transceiver registered\n");

	err = device_create_file(&pdev->dev, &dev_attr_enable_host);
	if (err) {
		dev_warn(&pdev->dev, "Can't register sysfs attribute\n");
		goto err_irq;
	}

	clk_disable(tegra->clk);
#if (defined(CONFIG_USB_OTG) && defined(CONFIG_USB_OTG_HOST))
	usb_host_detect_register_notifier(&usb_host_status_notifier);
#endif

	USBH_INFO("%s done!\n", __func__);
	return 0;

err_irq:
	otg_set_transceiver(NULL);
err_otg:
	iounmap(tegra->regs);
err_io:
	clk_disable(tegra->clk);
err_clken:
	clk_put(tegra->clk);
err_clk:
	platform_set_drvdata(pdev, NULL);
	kfree(tegra);
	return err;
}
コード例 #2
0
static int tegra_otg_probe(struct platform_device *pdev)
{
	struct tegra_otg_data *tegra;
	struct resource *res;
	int err;

	tegra = kzalloc(sizeof(struct tegra_otg_data), GFP_KERNEL);
	if (!tegra)
		return -ENOMEM;

	tegra->otg.dev = &pdev->dev;
	tegra->otg.label = "tegra-otg";
	tegra->otg.state = OTG_STATE_UNDEFINED;
	tegra->otg.set_host = tegra_otg_set_host;
	tegra->otg.set_peripheral = tegra_otg_set_peripheral;
	tegra->otg.set_suspend = tegra_otg_set_suspend;
	tegra->otg.set_power = tegra_otg_set_power;
	spin_lock_init(&tegra->lock);

	platform_set_drvdata(pdev, tegra);
	tegra_clone = tegra;
	//tegra->clk_enabled = false;
	tegra->clk_enabled = true;

	tegra->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(tegra->clk)) {
		dev_err(&pdev->dev, "Can't get otg clock\n");
		err = PTR_ERR(tegra->clk);
		goto err_clk;
	}

	err = clk_enable(tegra->clk);
	if (err)
		goto err_clken;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get I/O memory\n");
		err = -ENXIO;
		goto err_io;
	}
	tegra->regs = ioremap(res->start, resource_size(res));
	if (!tegra->regs) {
		err = -ENOMEM;
		goto err_io;
	}

	tegra->otg.state = OTG_STATE_A_SUSPEND;

	err = otg_set_transceiver(&tegra->otg);
	if (err) {
		dev_err(&pdev->dev, "can't register transceiver (%d)\n", err);
		goto err_otg;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get IRQ\n");
		err = -ENXIO;
		goto err_irq;
	}
	tegra->irq = res->start;
	err = request_threaded_irq(tegra->irq, tegra_otg_irq,
				   NULL,
				   IRQF_SHARED, "tegra-otg", tegra);
	if (err) {
		dev_err(&pdev->dev, "Failed to register IRQ\n");
		goto err_irq;
	}
	INIT_WORK (&tegra->work, irq_work);

	dev_info(&pdev->dev, "otg transceiver registered\n");
	return 0;

err_irq:
	otg_set_transceiver(NULL);
err_otg:
	iounmap(tegra->regs);
err_io:
	clk_disable(tegra->clk);
err_clken:
	clk_put(tegra->clk);
err_clk:
	platform_set_drvdata(pdev, NULL);
	kfree(tegra);
	return err;
}
コード例 #3
0
static int __devinit bcmpmu_otg_xceiv_probe(struct platform_device *pdev)
{
	int error = 0;
	struct bcmpmu_otg_xceiv_data *xceiv_data;
	struct bcmpmu *bcmpmu = pdev->dev.platform_data;

	dev_info(&pdev->dev, "Probing started...\n");

	xceiv_data = kzalloc(sizeof(*xceiv_data), GFP_KERNEL);
	if (!xceiv_data) {
		dev_warn(&pdev->dev, "Memory allocation failed\n");
		return -ENOMEM;
	}

	/* REVISIT: Currently there isn't a way to obtain
	 * regulator string associated with USB. Hardcode for now
	 */
	xceiv_data->bcm_hsotg_regulator =
		regulator_get(NULL, "hv2ldo_uc");

	if (IS_ERR(xceiv_data->bcm_hsotg_regulator)) {
		dev_warn(&pdev->dev, "Failed to get regulator handle\n");
		kfree(xceiv_data);
		return -ENODEV;
	}

	/* Enable USB LDO */
	regulator_enable(xceiv_data->bcm_hsotg_regulator);
	/* Give 2ms to ramp up USBLDO */
	mdelay(USBLDO_RAMP_UP_DELAY_IN_MS);
	xceiv_data->regulator_enabled = true;

	xceiv_data->dev = &pdev->dev;
	xceiv_data->bcmpmu = bcmpmu;
	xceiv_data->otg_xceiver.xceiver.dev = xceiv_data->dev;
	xceiv_data->otg_xceiver.xceiver.label = "bcmpmu_otg_xceiv";
	xceiv_data->host = false;
	xceiv_data->vbus_enabled = false;

	/* Create a work queue for OTG work items */
	xceiv_data->bcm_otg_work_queue = create_workqueue("bcm_otg_events");
	if (xceiv_data->bcm_otg_work_queue == NULL) {
		dev_warn(&pdev->dev,
			 "BCM OTG events work queue creation failed\n");
		bcmpmu_otg_free_regulator(xceiv_data);
		kfree(xceiv_data);
		return -ENOMEM;
	}

	/* Create one work item per deferrable function */
	INIT_WORK(&xceiv_data->bcm_otg_vbus_invalid_work,
		  bcmpmu_otg_xceiv_vbus_invalid_handler);
	INIT_WORK(&xceiv_data->bcm_otg_vbus_valid_work,
		  bcmpmu_otg_xceiv_vbus_valid_handler);
	INIT_WORK(&xceiv_data->bcm_otg_vbus_a_invalid_work,
		  bcmpmu_otg_xceiv_vbus_a_invalid_handler);
	INIT_WORK(&xceiv_data->bcm_otg_vbus_a_valid_work,
		  bcmpmu_otg_xceiv_vbus_a_valid_handler);
	INIT_WORK(&xceiv_data->bcm_otg_id_status_change_work,
		  bcmpmu_otg_xceiv_id_change_handler);
	INIT_WORK(&xceiv_data->bcm_otg_chg_detect_work,
		  bcmpmu_otg_xceiv_chg_detect_handler);
	INIT_WORK(&xceiv_data->bcm_otg_sess_end_srp_work,
		  bcmpmu_otg_xceiv_sess_end_srp_handler);
	INIT_DELAYED_WORK(&xceiv_data->bcm_otg_delayed_adp_work,
			  bcmpmu_otg_xceiv_delayed_adp_handler);

	xceiv_data->otg_xceiver.xceiver.state = OTG_STATE_UNDEFINED;
	xceiv_data->otg_xceiver.xceiver.set_vbus = bcmpmu_otg_xceiv_set_vbus;
	xceiv_data->otg_xceiver.xceiver.set_peripheral =
	    bcmpmu_otg_xceiv_set_peripheral;
	xceiv_data->otg_xceiver.xceiver.set_power =
	    bcmpmu_otg_xceiv_set_vbus_power;
	xceiv_data->otg_xceiver.xceiver.set_host = bcmpmu_otg_xceiv_set_host;
	xceiv_data->otg_xceiver.xceiver.shutdown = bcmpmu_otg_xceiv_shutdown;
	xceiv_data->otg_xceiver.xceiver.init = bcmpmu_otg_xceiv_start;
	xceiv_data->otg_xceiver.xceiver.set_delayed_adp =
	    bcmpmu_otg_xceiv_set_delayed_adp;
	xceiv_data->otg_xceiver.xceiver.set_srp_reqd =
	    bcmpmu_otg_xceiv_set_srp_reqd_handler;
	xceiv_data->otg_xceiver.xceiver.set_otg_enable =
	    bcmpmu_otg_xceiv_set_otg_enable;
	xceiv_data->otg_xceiver.xceiver.pullup_on = bcmpmu_otg_xceiv_pullup_on;
	xceiv_data->otg_xceiver.xceiver.set_suspend =
	    bcmpmu_otg_xceiv_set_suspend;

	ATOMIC_INIT_NOTIFIER_HEAD(&xceiv_data->otg_xceiver.xceiver.notifier);

	xceiv_data->bcm_otg_vbus_validity_notifier.notifier_call =
	    bcmpmu_otg_xceiv_vbus_notif_handler;
	bcmpmu_add_notifier(BCMPMU_USB_EVENT_VBUS_VALID,
			    &xceiv_data->bcm_otg_vbus_validity_notifier);
	bcmpmu_add_notifier(BCMPMU_USB_EVENT_SESSION_INVALID,
			    &xceiv_data->bcm_otg_vbus_validity_notifier);
	xceiv_data->bcm_otg_id_chg_notifier.notifier_call =
	    bcmpmu_otg_xceiv_id_chg_notif_handler;
	bcmpmu_add_notifier(BCMPMU_USB_EVENT_ID_CHANGE,
			    &xceiv_data->bcm_otg_id_chg_notifier);

	xceiv_data->bcm_otg_chg_detection_notifier.notifier_call =
	    bcmpmu_otg_xceiv_chg_detection_notif_handler;
	bcmpmu_add_notifier(BCMPMU_USB_EVENT_USB_DETECTION,
			    &xceiv_data->bcm_otg_chg_detection_notifier);

	wake_lock_init(&xceiv_data->otg_xceiver.xceiver_wake_lock,
		       WAKE_LOCK_SUSPEND, "otg_xcvr_wakelock");

#ifdef CONFIG_USB_OTG
	init_timer(&xceiv_data->otg_xceiver.srp_failure_timer);
	xceiv_data->otg_xceiver.srp_failure_timer.data =
	    (unsigned long)xceiv_data;
	xceiv_data->otg_xceiver.srp_failure_timer.function =
	    bcmpmu_otg_xceiv_srp_failure_handler;

	init_timer(&xceiv_data->otg_xceiver.sess_end_srp_timer);
	xceiv_data->otg_xceiver.sess_end_srp_timer.data =
	    (unsigned long)xceiv_data;
	xceiv_data->otg_xceiver.sess_end_srp_timer.function =
	    bcmpmu_otg_xceiv_sess_end_srp_timer_handler;

	error = bcm_otg_adp_init(xceiv_data);
	if (error)
		goto error_attr_host;
#endif

	otg_set_transceiver(&xceiv_data->otg_xceiver.xceiver);

	platform_set_drvdata(pdev, xceiv_data);

	error = device_create_file(&pdev->dev, &dev_attr_host);
	if (error) {
		dev_warn(&pdev->dev, "Failed to create HOST file\n");
		goto error_attr_host;
	}

	error = device_create_file(&pdev->dev, &dev_attr_vbus);
	if (error) {
		dev_warn(&pdev->dev, "Failed to create VBUS file\n");
		goto error_attr_vbus;
	}

	error = device_create_file(&pdev->dev, &dev_attr_wake);
	if (error) {
		dev_warn(&pdev->dev, "Failed to create WAKE file\n");
		goto error_attr_wake;
	}

	/* Check if we should default to A-device */
	xceiv_data->otg_xceiver.xceiver.default_a =
	    bcmpmu_otg_xceiv_check_id_gnd(xceiv_data) ||
	    bcmpmu_otg_xceiv_check_id_rid_a(xceiv_data);

	bcmpmu_otg_xceiv_set_def_state(xceiv_data,
		xceiv_data->otg_xceiver.xceiver.default_a);

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	dev_info(&pdev->dev, "Probing successful\n");

	return 0;

error_attr_wake:
	device_remove_file(xceiv_data->dev, &dev_attr_vbus);

error_attr_vbus:
	device_remove_file(xceiv_data->dev, &dev_attr_host);

error_attr_host:
	wake_lock_destroy(&xceiv_data->otg_xceiver.xceiver_wake_lock);
	destroy_workqueue(xceiv_data->bcm_otg_work_queue);
	bcmpmu_otg_free_regulator(xceiv_data);
	kfree(xceiv_data);
	return error;
}
コード例 #4
0
static int __init gpio_vbus_probe(struct platform_device *pdev)
{
	struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data;
	struct gpio_vbus_data *gpio_vbus;
	struct resource *res;
	int err, gpio, irq;

	if (!pdata || !gpio_is_valid(pdata->gpio_vbus))
		return -EINVAL;
	gpio = pdata->gpio_vbus;

	gpio_vbus = kzalloc(sizeof(struct gpio_vbus_data), GFP_KERNEL);
	if (!gpio_vbus)
		return -ENOMEM;

	platform_set_drvdata(pdev, gpio_vbus);
	gpio_vbus->dev = &pdev->dev;
	gpio_vbus->otg.label = "gpio-vbus";
	gpio_vbus->otg.state = OTG_STATE_UNDEFINED;
	gpio_vbus->otg.set_peripheral = gpio_vbus_set_peripheral;
	gpio_vbus->otg.set_power = gpio_vbus_set_power;
	gpio_vbus->otg.set_suspend = gpio_vbus_set_suspend;

	err = gpio_request(gpio, "vbus_detect");
	if (err) {
		dev_err(&pdev->dev, "can't request vbus gpio %d, err: %d\n",
			gpio, err);
		goto err_gpio;
	}
	gpio_direction_input(gpio);

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res) {
		irq = res->start;
		res->flags &= IRQF_TRIGGER_MASK;
		res->flags |= IRQF_SAMPLE_RANDOM | IRQF_SHARED;
	} else
		irq = gpio_to_irq(gpio);

	/* if data line pullup is in use, initialize it to "not pulling up" */
	gpio = pdata->gpio_pullup;
	if (gpio_is_valid(gpio)) {
		err = gpio_request(gpio, "udc_pullup");
		if (err) {
			dev_err(&pdev->dev,
				"can't request pullup gpio %d, err: %d\n",
				gpio, err);
			gpio_free(pdata->gpio_vbus);
			goto err_gpio;
		}
		gpio_direction_output(gpio, pdata->gpio_pullup_inverted);
	}

	err = request_irq(irq, gpio_vbus_irq, VBUS_IRQ_FLAGS,
		"vbus_detect", pdev);
	if (err) {
		dev_err(&pdev->dev, "can't request irq %i, err: %d\n",
			irq, err);
		goto err_irq;
	}

	/* only active when a gadget is registered */
	err = otg_set_transceiver(&gpio_vbus->otg);
	if (err) {
		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",
			err);
		goto err_otg;
	}

	gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw");
	if (IS_ERR(gpio_vbus->vbus_draw)) {
		dev_dbg(&pdev->dev, "can't get vbus_draw regulator, err: %ld\n",
			PTR_ERR(gpio_vbus->vbus_draw));
		gpio_vbus->vbus_draw = NULL;
	}

	return 0;
err_otg:
	free_irq(irq, &pdev->dev);
err_irq:
	if (gpio_is_valid(pdata->gpio_pullup))
		gpio_free(pdata->gpio_pullup);
	gpio_free(pdata->gpio_vbus);
err_gpio:
	platform_set_drvdata(pdev, NULL);
	kfree(gpio_vbus);
	return err;
}
コード例 #5
0
static int __init msm_otg_probe(struct platform_device *pdev)
{
	int ret = 0;
	int vbus_on_irq = 0;
	struct resource *res;
	struct msm_otg *dev;
	struct msm_otg_platform_data *pdata;

	dev = kzalloc(sizeof(struct msm_otg), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	dev->otg.dev = &pdev->dev;
	pdata = pdev->dev.platform_data;

	if (pdev->dev.platform_data) {
		dev->rpc_connect = pdata->rpc_connect;
		dev->phy_reset = pdata->phy_reset;
		dev->core_clk  = pdata->core_clk;
		/* pmic apis */
		dev->pmic_notif_init = pdata->pmic_notif_init;
		dev->pmic_notif_deinit = pdata->pmic_notif_deinit;
		dev->pmic_register_vbus_sn = pdata->pmic_register_vbus_sn;
		dev->pmic_unregister_vbus_sn = pdata->pmic_unregister_vbus_sn;
		dev->pmic_enable_ldo = pdata->pmic_enable_ldo;
	}

	if (pdata && pdata->pmic_vbus_irq) {
		vbus_on_irq = platform_get_irq_byname(pdev, "vbus_on");
		if (vbus_on_irq < 0) {
			pr_err("%s: unable to get vbus on irq\n", __func__);
			ret = vbus_on_irq;
			goto free_dev;
		}
	}

	if (dev->rpc_connect) {
		ret = dev->rpc_connect(1);
		pr_info("%s: rpc_connect(%d)\n", __func__, ret);
		if (ret) {
			pr_err("%s: rpc connect failed\n", __func__);
			ret = -ENODEV;
			goto free_dev;
		}
	}

	dev->clk = clk_get(&pdev->dev, "usb_hs_clk");
	if (IS_ERR(dev->clk)) {
		pr_err("%s: failed to get usb_hs_clk\n", __func__);
		ret = PTR_ERR(dev->clk);
		goto rpc_fail;
	}
	dev->pclk = clk_get(&pdev->dev, "usb_hs_pclk");
	if (IS_ERR(dev->pclk)) {
		pr_err("%s: failed to get usb_hs_pclk\n", __func__);
		ret = PTR_ERR(dev->pclk);
		goto put_clk;
	}
	if (dev->core_clk) {
		dev->cclk = clk_get(&pdev->dev, "usb_hs_core_clk");
		if (IS_ERR(dev->cclk)) {
			pr_err("%s: failed to get usb_hs_core_clk\n", __func__);
			ret = PTR_ERR(dev->cclk);
			goto put_pclk;
		}
	}
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_err("%s: failed to get platform resource mem\n", __func__);
		ret = -ENODEV;
		goto put_cclk;
	}

	dev->regs = ioremap(res->start, resource_size(res));
	if (!dev->regs) {
		pr_err("%s: ioremap failed\n", __func__);
		ret = -ENOMEM;
		goto put_cclk;
	}
	dev->irq = platform_get_irq(pdev, 0);
	if (!dev->irq) {
		pr_err("%s: platform_get_irq failed\n", __func__);
		ret = -ENODEV;
		goto free_regs;
	}

	/* enable clocks */
	clk_enable(dev->pclk);
	if (dev->cclk)
		clk_enable(dev->cclk);

	/* To reduce phy power consumption and to avoid external LDO
	 * on the board, PMIC comparators can be used to detect VBUS
	 * session change.
	 */
	if (dev->pmic_notif_init) {
		ret = dev->pmic_notif_init();
		if (!ret) {
			dev->pmic_notif_supp = 1;
			dev->pmic_enable_ldo(1);
		} else if (ret != -ENOTSUPP) {
			clk_disable(dev->pclk);
			if (dev->cclk)
				clk_disable(dev->cclk);
			goto free_regs;
		}
	}

	otg_reset(dev);

	ret = request_irq(dev->irq, msm_otg_irq, IRQF_SHARED,
					"msm_otg", dev);
	if (ret) {
		pr_info("%s: request irq failed\n", __func__);
		clk_disable(dev->pclk);
		if (dev->cclk)
			clk_disable(dev->cclk);
		goto free_regs;
	}

	the_msm_otg = dev;
	dev->vbus_on_irq = vbus_on_irq;
	dev->otg.set_peripheral = msm_otg_set_peripheral;
	dev->otg.set_host = msm_otg_set_host;
	dev->otg.set_suspend = msm_otg_set_suspend;
	dev->set_clk = msm_otg_set_clk;
	if (otg_set_transceiver(&dev->otg)) {
		WARN_ON(1);
		goto free_otg_irq;
	}

	device_init_wakeup(&pdev->dev, 1);

	if (vbus_on_irq) {
		ret = request_irq(vbus_on_irq, pmic_vbus_on_irq,
				IRQF_TRIGGER_RISING, "msm_otg_vbus_on", NULL);
		if (ret) {
			pr_info("%s: request_irq for vbus_on"
					"interrupt failed\n", __func__);
			goto free_otg_irq;
		}
	}

	return 0;
free_otg_irq:
	free_irq(dev->irq, dev);
free_regs:
	iounmap(dev->regs);
put_cclk:
	if (dev->cclk)
		clk_put(dev->cclk);
put_pclk:
	clk_put(dev->pclk);
put_clk:
	clk_put(dev->clk);
rpc_fail:
	dev->rpc_connect(0);
free_dev:
	kfree(dev);
	return ret;
}
コード例 #6
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.set_power	= twl6030_set_power;
	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;
}
コード例 #7
0
ファイル: tahvo-usb.c プロジェクト: tmlind/linux
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;
}
コード例 #8
0
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.set_hz_mode	= twl6030_set_hz_mode;
	twl->otg.init		= twl6030_phy_init;
	twl->otg.set_power    = twl6030_set_power;
	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->vbus_enable = false;
	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;
}
コード例 #9
0
static int __init msm_otg_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct resource *res;
	struct msm_otg *motg;
	struct otg_transceiver *otg;

	dev_info(&pdev->dev, "msm_otg probe\n");
	if (!pdev->dev.platform_data) {
		dev_err(&pdev->dev, "No platform data given. Bailing out\n");
		return -ENODEV;
	}

	motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL);
	if (!motg) {
		dev_err(&pdev->dev, "unable to allocate msm_otg\n");
		return -ENOMEM;
	}

	motg->pdata = pdev->dev.platform_data;
	otg = &motg->otg;
	otg->dev = &pdev->dev;

	motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk");
	if (IS_ERR(motg->phy_reset_clk)) {
		dev_err(&pdev->dev, "failed to get usb_phy_clk\n");
		ret = PTR_ERR(motg->phy_reset_clk);
		goto free_motg;
	}

	motg->clk = clk_get(&pdev->dev, "usb_hs_clk");
	if (IS_ERR(motg->clk)) {
		dev_err(&pdev->dev, "failed to get usb_hs_clk\n");
		ret = PTR_ERR(motg->clk);
		goto put_phy_reset_clk;
	}

	motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk");
	if (IS_ERR(motg->pclk)) {
		dev_err(&pdev->dev, "failed to get usb_hs_pclk\n");
		ret = PTR_ERR(motg->pclk);
		goto put_clk;
	}

	/*
	 * USB core clock is not present on all MSM chips. This
	 * clock is introduced to remove the dependency on AXI
	 * bus frequency.
	 */
	motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk");
	if (IS_ERR(motg->core_clk))
		motg->core_clk = NULL;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to get platform resource mem\n");
		ret = -ENODEV;
		goto put_core_clk;
	}

	motg->regs = ioremap(res->start, resource_size(res));
	if (!motg->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto put_core_clk;
	}
	dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs);

	motg->irq = platform_get_irq(pdev, 0);
	if (!motg->irq) {
		dev_err(&pdev->dev, "platform_get_irq failed\n");
		ret = -ENODEV;
		goto free_regs;
	}

	clk_enable(motg->clk);
	clk_enable(motg->pclk);
	if (motg->core_clk)
		clk_enable(motg->core_clk);

	writel(0, USB_USBINTR);
	writel(0, USB_OTGSC);

	INIT_WORK(&motg->sm_work, msm_otg_sm_work);
	ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED,
					"msm_otg", motg);
	if (ret) {
		dev_err(&pdev->dev, "request irq failed\n");
		goto disable_clks;
	}

	otg->init = msm_otg_reset;
	otg->set_host = msm_otg_set_host;
	otg->set_peripheral = msm_otg_set_peripheral;

	otg->io_ops = &msm_otg_io_ops;

	ret = otg_set_transceiver(&motg->otg);
	if (ret) {
		dev_err(&pdev->dev, "otg_set_transceiver failed\n");
		goto free_irq;
	}

	platform_set_drvdata(pdev, motg);
	device_init_wakeup(&pdev->dev, 1);

	if (motg->pdata->mode == USB_OTG &&
			motg->pdata->otg_control == OTG_USER_CONTROL) {
		ret = msm_otg_debugfs_init(motg);
		if (ret)
			dev_dbg(&pdev->dev, "mode debugfs file is"
					"not available\n");
	}

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;
free_irq:
	free_irq(motg->irq, motg);
disable_clks:
	clk_disable(motg->pclk);
	clk_disable(motg->clk);
free_regs:
	iounmap(motg->regs);
put_core_clk:
	if (motg->core_clk)
		clk_put(motg->core_clk);
	clk_put(motg->pclk);
put_clk:
	clk_put(motg->clk);
put_phy_reset_clk:
	clk_put(motg->phy_reset_clk);
free_motg:
	kfree(motg);
	return ret;
}
コード例 #10
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;
}
コード例 #11
0
static int __init twl4030_usb_probe(struct platform_device *pdev)
{
    struct twl4030_usb_data *pdata = pdev->dev.platform_data;
    struct twl4030_usb	*twl;
    int			status, err;

    if (!pdata) {
        dev_dbg(&pdev->dev, "platform_data not available\n");
        return -EINVAL;
    }

    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		= "twl4030";
    twl->otg.set_host	= twl4030_set_host;
    twl->otg.set_peripheral	= twl4030_set_peripheral;
    twl->otg.set_suspend	= twl4030_set_suspend;
    twl->usb_mode		= pdata->usb_mode;
    twl->asleep		= 1;

    /* init spinlock for workqueue */
    spin_lock_init(&twl->lock);

    err = twl4030_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");

    /* 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_irq(twl->irq, twl4030_usb_irq,
                         IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                         "twl4030_usb", twl);
    if (status < 0) {
        dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
                twl->irq, status);
        kfree(twl);
        return status;
    }

    /* The IRQ handler just handles changes from the previous states
     * of the ID and VBUS pins ... in probe() we must initialize that
     * previous state.  The easy way:  fake an IRQ.
     *
     * REVISIT:  a real IRQ might have happened already, if PREEMPT is
     * enabled.  Else the IRQ may not yet be configured or enabled,
     * because of scheduling delays.
     */
    twl4030_usb_irq(twl->irq, twl);

    dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
    return 0;
}
コード例 #12
0
static int __devinit twl6030_usb_probe(struct platform_device *pdev)
{
	struct twl6030_usb	*twl;
	int			status;
	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_vbus	= twl6030_set_vbus;
	twl->otg.set_hz_mode	= twl6030_set_hz_mode;
	twl->otg.init		= twl6030_phy_init;
	twl->otg.shutdown	= twl6030_phy_shutdown;
	twl->otg.enable_irq	= twl6030_enable_irq;


	/*We need to make sure ID comparator is ON*/
	twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG);

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	wake_lock_init(&twl_lock, WAKE_LOCK_SUSPEND, "twl_wake_lock");

	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);

	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_enable_irq(&twl->otg);
	dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");

	return 0;
}
コード例 #13
0
ファイル: twl4030-usb.c プロジェクト: Adjustxx/Savaged-Zen
static int __devinit twl4030_usb_probe(struct platform_device *pdev)
{
	struct twl4030_usb_data *pdata = pdev->dev.platform_data;
	struct twl4030_usb	*twl;
	int			status, err;

	if (!pdata) {
		dev_dbg(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

	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		= "twl4030";
	twl->otg.set_host	= twl4030_set_host;
	twl->otg.set_peripheral	= twl4030_set_peripheral;
	twl->otg.set_suspend	= twl4030_set_suspend;
	twl->usb_mode		= pdata->usb_mode;
	twl->asleep = 1;

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl4030_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.
	 */
	twl->irq_enabled = true;
	status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"twl4030_usb", twl);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq, status);
		kfree(twl);
		return status;
	}

	/* Power down phy or make it work according to
	 * current link state.
	 */
	twl4030_usb_phy_init(twl);

	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
コード例 #14
0
static int __init msm_otg_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct resource *res;
	struct msm_otg *dev;
	struct msm_otg_platform_data *pdata;

	dev = kzalloc(sizeof(struct msm_otg), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	dev->otg.dev = &pdev->dev;

	if (pdev->dev.platform_data) {
		pdata = pdev->dev.platform_data;
		dev->rpc_connect = pdata->rpc_connect;
		dev->phy_reset = pdata->phy_reset;
	}

	if (dev->rpc_connect) {
		ret = dev->rpc_connect(1);
		pr_info("%s: rpc_connect(%d)\n", __func__, ret);
		if (ret) {
			pr_err("%s: rpc connect failed\n", __func__);
			ret = -ENODEV;
			goto free_dev;
		}
	}

	dev->clk = clk_get(&pdev->dev, "usb_hs_clk");
	if (IS_ERR(dev->clk)) {
		pr_err("%s: failed to get usb_hs_clk\n", __func__);
		ret = PTR_ERR(dev->clk);
		goto rpc_fail;
	}
	dev->pclk = clk_get(&pdev->dev, "usb_hs_pclk");
	if (IS_ERR(dev->clk)) {
		pr_err("%s: failed to get usb_hs_pclk\n", __func__);
		ret = PTR_ERR(dev->pclk);
		goto put_clk;
	}
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_err("%s: failed to get platform resource mem\n", __func__);
		ret = -ENODEV;
		goto put_pclk;
	}

	dev->regs = ioremap(res->start, resource_size(res));
	if (!dev->regs) {
		pr_err("%s: ioremap failed\n", __func__);
		ret = -ENOMEM;
		goto put_pclk;
	}
	dev->irq = platform_get_irq(pdev, 0);
	if (!dev->irq) {
		pr_err("%s: platform_get_irq failed\n", __func__);
		ret = -ENODEV;
		goto free_regs;
	}

	/* enable clocks */
	clk_enable(dev->clk);
	clk_enable(dev->pclk);

	otg_reset(dev);

	ret = request_irq(dev->irq, msm_otg_irq, IRQF_SHARED,
					"msm_otg", dev);
	if (ret) {
		pr_info("%s: request irq failed\n", __func__);
		clk_disable(dev->clk);
		clk_disable(dev->pclk);
		goto free_regs;
	}

	the_msm_otg = dev;
	dev->otg.set_peripheral = msm_otg_set_peripheral;
	dev->otg.set_host = msm_otg_set_host;
	dev->otg.set_suspend = msm_otg_set_suspend;
	if (otg_set_transceiver(&dev->otg)) {
		WARN_ON(1);
		goto free_regs;
	}

	wake_lock_init(&dev->wlock,
			WAKE_LOCK_SUSPEND, "usb_bus_active");
	wake_lock(&dev->wlock);
	msm_otg_debugfs_init(dev);
	device_init_wakeup(&pdev->dev, 1);

	return 0;
free_regs:
	iounmap(dev->regs);
put_pclk:
	clk_put(dev->pclk);
put_clk:
	clk_put(dev->clk);
rpc_fail:
	dev->rpc_connect(0);
free_dev:
	kfree(dev);
	return ret;
}
コード例 #15
0
static int __devinit twl4030_usb_probe(struct platform_device *pdev)
{
	struct twl4030_usb_data *pdata = pdev->dev.platform_data;
	struct twl4030_usb	*twl;
	int			status, err;

#ifdef CONFIG_LGE_OMAP3_EXT_PWR
	INIT_WORK(&set_ext_pwr_twl_usb_work, twl_usb_ext_pwr_work);
#endif 

#if 1 /* mbk_wake mbk_temp */ 
	// LGE_CHANGE wake lock for usb connection
	wake_lock_init(&the_wlock.wake_lock, WAKE_LOCK_SUSPEND, "twl4030_usb_connection");
	the_wlock.wake_lock_on=0;
	// LGE_CHANGE wake lock for usb connection

	// LGE_CHANGE work queue
	INIT_DELAYED_WORK(&twl4030_usb_wq, twl4030_usb_wq_func);
	// LGE_CHANGE work queue
#endif

	if (!pdata) {
		dev_dbg(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

	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		= "twl4030";
	twl->otg.set_host	= twl4030_set_host;
	twl->otg.set_peripheral	= twl4030_set_peripheral;
	twl->otg.set_suspend	= twl4030_set_suspend;
	twl->usb_mode		= pdata->usb_mode;
	twl->asleep		= 1;

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl4030_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.
	 */
	twl->irq_enabled = true;
	status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"twl4030_usb", twl);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq, status);
		kfree(twl);
		return status;
	}
	
	//regulator_enable(twl->usb3v1);
	/* The IRQ handler just handles changes from the previous states
	 * of the ID and VBUS pins ... in probe() we must initialize that
	 * previous state.  The easy way:  fake an IRQ.
	 *
	 * REVISIT:  a real IRQ might have happened already, if PREEMPT is
	 * enabled.  Else the IRQ may not yet be configured or enabled,
	 * because of scheduling delays.
	 */
	twl4030_usb_irq(twl->irq, twl);
	//if (twl4030_usb_linkstat(twl) == USB_EVENT_NONE) {
	//	regulator_disable(twl->usb3v1);
	//}

//20110829 [email protected] [LS855] reset USB1.8V LDO when phone reset [START]
	backuptwl = twl;
//20110829 [email protected] [LS855] reset USB1.8V LDO when phone reset [END]	


	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
コード例 #16
0
ファイル: isp1301_omap.c プロジェクト: ivucica/linux
static void __exit isp_exit(void)
{
	if (the_transceiver)
		otg_set_transceiver(0);
	i2c_del_driver(&isp1301_driver);
}
コード例 #17
0
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;
}
コード例 #18
0
/* no error returns, they'd just make bus scanning stop */
static int isp1301_probe(struct i2c_adapter *bus, int address, int kind)
{
	int			status;
	struct isp1301		*isp;
	struct i2c_client	*i2c;

	if (the_transceiver)
		return 0;

	isp = kzalloc(sizeof *isp, GFP_KERNEL);
	if (!isp)
		return 0;

	INIT_WORK(&isp->work, isp1301_work, isp);
	init_timer(&isp->timer);
	isp->timer.function = isp1301_timer;
	isp->timer.data = (unsigned long) isp;

	isp->irq = -1;
	isp->client.addr = address;
	i2c_set_clientdata(&isp->client, isp);
	isp->client.adapter = bus;
	isp->client.driver = &isp1301_driver;
	strlcpy(isp->client.name, DRIVER_NAME, I2C_NAME_SIZE);
	i2c = &isp->client;

	/* if this is a true probe, verify the chip ... */
	if (kind < 0) {
		status = isp1301_get_u16(isp, ISP1301_VENDOR_ID);
		if (status != I2C_VENDOR_ID_PHILIPS) {
			dev_dbg(&bus->dev, "addr %d not philips id: %d\n",
				address, status);
			goto fail1;
		}
		status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID);
		if (status != I2C_PRODUCT_ID_PHILIPS_1301) {
			dev_dbg(&bus->dev, "%d not isp1301, %d\n",
				address, status);
			goto fail1;
		}
	}

	status = i2c_attach_client(i2c);
	if (status < 0) {
		dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n",
				DRIVER_NAME, address, status);
fail1:
		kfree(isp);
		return 0;
	}
	isp->i2c_release = i2c->dev.release;
	i2c->dev.release = isp1301_release;

	/* initial development used chiprev 2.00 */
	status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE);
	dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n",
		status >> 8, status & 0xff);

	/* make like power-on reset */
	isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK);

	isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI);
	isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI);

	isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1,
				OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN);
	isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
				~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN));

	isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0);
	isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0);
	isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0);

#ifdef	CONFIG_USB_OTG
	status = otg_bind(isp);
	if (status < 0) {
		dev_dbg(&i2c->dev, "can't bind OTG\n");
		goto fail2;
	}
#endif

	if (machine_is_omap_h2()) {
		/* full speed signaling by default */
		isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1,
			MC1_SPEED_REG);
		isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2,
			MC2_SPD_SUSP_CTRL);

		/* IRQ wired at M14 */
		omap_cfg_reg(M14_1510_GPIO2);
		isp->irq = OMAP_GPIO_IRQ(2);
		omap_request_gpio(2);
		omap_set_gpio_direction(2, 1);
		omap_set_gpio_edge_ctrl(2, OMAP_GPIO_FALLING_EDGE);
	}

	status = request_irq(isp->irq, isp1301_irq,
			IRQF_SAMPLE_RANDOM, DRIVER_NAME, isp);
	if (status < 0) {
		dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n",
				isp->irq, status);
#ifdef	CONFIG_USB_OTG
fail2:
#endif
		i2c_detach_client(i2c);
		goto fail1;
	}

	isp->otg.dev = &isp->client.dev;
	isp->otg.label = DRIVER_NAME;

	isp->otg.set_host = isp1301_set_host,
	isp->otg.set_peripheral = isp1301_set_peripheral,
	isp->otg.set_power = isp1301_set_power,
	isp->otg.start_srp = isp1301_start_srp,
	isp->otg.start_hnp = isp1301_start_hnp,

	enable_vbus_draw(isp, 0);
	power_down(isp);
	the_transceiver = isp;

#ifdef	CONFIG_USB_OTG
	update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
#endif

	dump_regs(isp, __FUNCTION__);

#ifdef	VERBOSE
	mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);
	dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES);
#endif

	status = otg_set_transceiver(&isp->otg);
	if (status < 0)
		dev_err(&i2c->dev, "can't register transceiver, %d\n",
			status);

	return 0;
}
コード例 #19
0
ファイル: isp1301_omap.c プロジェクト: 119-org/hi3518-osdrv
static int __devinit
isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
	int			status;
	struct isp1301		*isp;

	if (the_transceiver)
		return 0;

	isp = kzalloc(sizeof *isp, GFP_KERNEL);
	if (!isp)
		return 0;

	INIT_WORK(&isp->work, isp1301_work);
	init_timer(&isp->timer);
	isp->timer.function = isp1301_timer;
	isp->timer.data = (unsigned long) isp;

	i2c_set_clientdata(i2c, isp);
	isp->client = i2c;

	/* verify the chip (shouldn't be necessary) */
	status = isp1301_get_u16(isp, ISP1301_VENDOR_ID);
	if (status != I2C_VENDOR_ID_PHILIPS) {
		dev_dbg(&i2c->dev, "not philips id: %d\n", status);
		goto fail;
	}
	status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID);
	if (status != I2C_PRODUCT_ID_PHILIPS_1301) {
		dev_dbg(&i2c->dev, "not isp1301, %d\n", status);
		goto fail;
	}
	isp->i2c_release = i2c->dev.release;
	i2c->dev.release = isp1301_release;

	/* initial development used chiprev 2.00 */
	status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE);
	dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n",
		status >> 8, status & 0xff);

	/* make like power-on reset */
	isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK);

	isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI);
	isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI);

	isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1,
				OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN);
	isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
				~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN));

	isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0);
	isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0);
	isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0);

#ifdef	CONFIG_USB_OTG
	status = otg_bind(isp);
	if (status < 0) {
		dev_dbg(&i2c->dev, "can't bind OTG\n");
		goto fail;
	}
#endif

	if (machine_is_omap_h2()) {
		/* full speed signaling by default */
		isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1,
			MC1_SPEED);
		isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2,
			MC2_SPD_SUSP_CTRL);

		/* IRQ wired at M14 */
		omap_cfg_reg(M14_1510_GPIO2);
		if (gpio_request(2, "isp1301") == 0)
			gpio_direction_input(2);
		isp->irq_type = IRQF_TRIGGER_FALLING;
	}

	isp->irq_type |= IRQF_SAMPLE_RANDOM;
	status = request_irq(i2c->irq, isp1301_irq,
			isp->irq_type, DRIVER_NAME, isp);
	if (status < 0) {
		dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n",
				i2c->irq, status);
		goto fail;
	}

	isp->otg.dev = &i2c->dev;
	isp->otg.label = DRIVER_NAME;

	isp->otg.set_host = isp1301_set_host,
	isp->otg.set_peripheral = isp1301_set_peripheral,
	isp->otg.set_power = isp1301_set_power,
	isp->otg.start_srp = isp1301_start_srp,
	isp->otg.start_hnp = isp1301_start_hnp,

	enable_vbus_draw(isp, 0);
	power_down(isp);
	the_transceiver = isp;

#ifdef	CONFIG_USB_OTG
	update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
#endif

	dump_regs(isp, __func__);

#ifdef	VERBOSE
	mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);
	dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES);
#endif

	status = otg_set_transceiver(&isp->otg);
	if (status < 0)
		dev_err(&i2c->dev, "can't register transceiver, %d\n",
			status);

	return 0;

fail:
	kfree(isp);
	return -ENODEV;
}