예제 #1
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;

	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;

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

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

	
	twl4030_usb_irq(twl->irq, twl);

	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
예제 #2
0
파일: twl4030.c 프로젝트: nunb/gforth
/*
 * Initiaze the ULPI interface
 * ULPI : Universal Transceiver Macrocell Low Pin Interface
 * An interface between the USB link controller like musb and the
 * the PHY or transceiver that drives the actual bus.
 */
int twl4030_usb_ulpi_init(void)
{
    long timeout = 1000 * 1000; /* 1 sec */;
    u8 clk, sts, pwr;

    /* twl4030 ldo init */
    twl4030_usb_ldo_init();

    /* Enable the twl4030 phy */
    twl4030_phy_power();

    /* Enable DPLL to access PHY registers over I2C */
    clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
    clk |= REQ_PHY_DPLL_CLK;
    twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);

    /* Check if the PHY DPLL is locked */
    sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
    while (!(sts & PHY_DPLL_CLK) && 0 < timeout) {
        udelay(10);
        sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
        timeout -= 10;
    }

    /* Final check */
    sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
    if (!(sts & PHY_DPLL_CLK)) {
        printf("Error:TWL4030:USB Timeout setting PHY DPLL clock\n");
        return -1;
    }

    /*
     * There are two circuit blocks attached to the PHY,
     * Carkit and USB OTG.  Disable Carkit and enable USB OTG
     */
    twl4030_usb_write(TWL4030_USB_IFC_CTRL_CLR, CARKITMODE);
    pwr = twl4030_usb_read(TWL4030_USB_POWER_CTRL);
    pwr |= OTG_ENAB;
    twl4030_usb_write(TWL4030_USB_POWER_CTRL_SET, pwr);

    /* Clear the opmode bits to ensure normal encode */
    twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, OPMODE_MASK);

    /* Clear the xcvrselect bits to enable the high speed transeiver */
    twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, XCVRSELECT_MASK);

    /* Let ULPI control the DPLL clock */
    clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
    clk &= ~REQ_PHY_DPLL_CLK;
    twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);

    return 0;
}
예제 #3
0
static int __init twl4030_usb_init(void)
{
	struct twl4030_usb	*twl;
	int status;

	if (the_transceiver)
		return 0;

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

	the_transceiver = twl;

	twl->irq		= TWL4030_PWRIRQ_USB_PRES;
	twl->otg.set_host	= twl4030_set_host;
	twl->otg.set_peripheral	= twl4030_set_peripheral;
	twl->otg.set_suspend	= twl4030_set_suspend;

	usb_irq_disable();
	status = request_irq(twl->irq, twl4030_usb_irq, 0, "twl4030_usb", twl);
	if (status < 0) {
		printk(KERN_DEBUG "can't get IRQ %d, err %d\n",
			twl->irq, status);
		kfree(twl);
		return -ENODEV;
	}

#if defined(CONFIG_TWL4030_USB_HS_ULPI)
	hs_usb_init(twl);
#endif
	twl4030_usb_ldo_init(twl);
	twl4030_phy_power(twl, 1);
	twl4030_i2c_access(1);
	twl4030_usb_set_mode(twl, twl->usb_mode);
	if (twl->usb_mode == T2_USB_MODE_ULPI)
		twl4030_i2c_access(0);

	twl->asleep = 0;

	if (twl->usb_mode == T2_USB_MODE_ULPI)
		twl4030_phy_suspend(1);

	otg_set_transceiver(&twl->otg);

	printk(KERN_INFO "Initialized TWL4030 USB module\n");

	return 0;
}
예제 #4
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;

	twl = kzalloc(sizeof *twl, GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

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

	wake_lock_init(&twl->wake_lock, WAKE_LOCK_SUSPEND, "twl_usb");

	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;

	t2_transceiver = twl;
	t2_transceiver->link_context_restore_and_wakeup = NULL;
	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	twl4030_usb_ldo_init(twl);
	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;
	}

#if defined(USB_LAT_CONST) && defined(CONFIG_OMAP3_PM)
	/* Get handle to USB Constraint for OFF/RETENTION */
	twl->usb_power_constraint = constraint_get("usb", &cnstr_id);
#endif

#if 0
/* FIXME-TI: check this logic */
<<<<<<< HEAD:drivers/i2c/chips/twl4030-usb.c
예제 #5
0
static int twl4030_usb_probe(struct platform_device *pdev)
{
	struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
	struct twl4030_usb	*twl;
	struct phy		*phy;
	int			status, err;
	struct usb_otg		*otg;
	struct device_node	*np = pdev->dev.of_node;
	struct phy_provider	*phy_provider;
	struct phy_init_data	*init_data = NULL;

	twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

	if (np)
		of_property_read_u32(np, "usb_mode",
				(enum twl4030_usb_mode *)&twl->usb_mode);
	else if (pdata) {
		twl->usb_mode = pdata->usb_mode;
		init_data = pdata->init_data;
	} else {
		dev_err(&pdev->dev, "twl4030 initialized without pdata\n");
		return -EINVAL;
	}

	otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
	if (!otg)
		return -ENOMEM;

	twl->dev		= &pdev->dev;
	twl->irq		= platform_get_irq(pdev, 0);
	twl->vbus_supplied	= false;
	twl->asleep		= 1;
	twl->linkstat		= OMAP_MUSB_UNKNOWN;

	twl->phy.dev		= twl->dev;
	twl->phy.label		= "twl4030";
	twl->phy.otg		= otg;
	twl->phy.type		= USB_PHY_TYPE_USB2;

	otg->phy		= &twl->phy;
	otg->set_host		= twl4030_set_host;
	otg->set_peripheral	= twl4030_set_peripheral;

	phy = devm_phy_create(twl->dev, NULL, &ops, init_data);
	if (IS_ERR(phy)) {
		dev_dbg(&pdev->dev, "Failed to create PHY\n");
		return PTR_ERR(phy);
	}

	phy_set_drvdata(phy, twl);

	phy_provider = devm_of_phy_provider_register(twl->dev,
		of_phy_simple_xlate);
	if (IS_ERR(phy_provider))
		return PTR_ERR(phy_provider);

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

	INIT_DELAYED_WORK(&twl->id_workaround_work, twl4030_id_workaround_work);

	err = twl4030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		return err;
	}
	usb_add_phy_dev(&twl->phy);

	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->phy.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 = devm_request_threaded_irq(twl->dev, 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);
		return status;
	}

	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
예제 #6
0
파일: twl4030-usb.c 프로젝트: UAVXP/A10
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;
	int OTG_ID_detect_irq = 0;

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

	twl = kzalloc(sizeof *twl, GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

   twl4030_otg_enable(0);
	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;

#ifdef CONFIG_HAS_EARLYSUSPEND
	twl->early_suspend.suspend = twl4030_usb_early_suspend;
	twl->early_suspend.resume = twl4030_usb_late_resume;
	register_early_suspend(&twl->early_suspend);
#endif
	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);
//&*&*&*SJ1_20110701, fix adb connect issue.
	INIT_DELAYED_WORK(&twl->usb_irq_delay_work, do_softint_usb_irq);
//&*&*&*SJ2_20110701, fix adb connect issue.

	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;
	g_twl_usb = twl;

	
	//&*&*&*AL1_20110523, USB OTG/Charger switch on EVT3 of EP10
	status = gpio_request(OTG_EN_1V8, "otg_charger_en");
	if (status < 0) {
		dev_dbg(&pdev->dev, "couldn't request OTG_EN_1V8 GPIO: %d\n",
			OTG_EN_1V8);
	}
	//ret = gpio_direction_output(OTG_EN_1V8, 0);
	status = gpio_request(CHG_OFFMODE, "otg_vbus_out_en");
	if (status < 0) {
		dev_dbg(&pdev->dev, "couldn't request CHG_OFFMODE GPIO: %d\n",
			CHG_OFFMODE);
	}
	//ret = gpio_direction_output(CHG_OFFMODE, 0);
	//&*&*&*AL1_20110523, USB OTG/Charger switch on EVT3 of EP10
	
	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;
	}
	
	
	//&*&*&*Simon_20110615, register Interrupt handling function for GPIO-41
   
   if(gpio_request(41, "OTG_ID_GPIO") < 0)			
   {
		printk("[simon]Failed to request GPIO%d fOTG_ID_GPIO\n", 41);
	}
	else
	{
		gpio_direction_input(41);		  
      OTG_ID_detect_irq = OMAP_GPIO_IRQ(41);
       
		printk("[Simon] GPIO-41 irq=%d \n",OTG_ID_detect_irq);
			
		status = request_threaded_irq(OTG_ID_detect_irq, NULL,twl4030_OTG_irq,    	
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |IRQF_DISABLED ,
			"OTG_ID_irq", twl);	
			
		if (status < 0) 
		{
			dev_dbg(&pdev->dev, "can't get OTG IRQ %d, err %d\n",
				OTG_ID_detect_irq, status);
			kfree(twl);
			return status;
		}
	}
   //&*&*&*Simon_20110615 end.

	wake_lock_init(&usb_lock, WAKE_LOCK_SUSPEND, "twl4030_musb_wake_lock");
	
	/* 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;
}
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;

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

	twl4030_usb_ldo_init(twl);
	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;
}
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;
	struct usb_otg		*otg;

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

	twl = kzalloc(sizeof *twl, GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

	otg = kzalloc(sizeof *otg, GFP_KERNEL);
	if (!otg) {
		kfree(twl);
		return -ENOMEM;
	}

	twl->dev		= &pdev->dev;
	twl->irq		= platform_get_irq(pdev, 0);
	twl->usb_mode		= pdata->usb_mode;
	twl->vbus_supplied	= false;
	twl->asleep		= 1;

	twl->phy.dev		= twl->dev;
	twl->phy.label		= "twl4030";
	twl->phy.otg		= otg;
	twl->phy.set_suspend	= twl4030_set_suspend;

	otg->phy		= &twl->phy;
	otg->set_host		= twl4030_set_host;
	otg->set_peripheral	= twl4030_set_peripheral;

	
	spin_lock_init(&twl->lock);

	err = twl4030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		kfree(otg);
		kfree(twl);
		return err;
	}
	usb_set_transceiver(&twl->phy);

	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->phy.notifier);

	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(otg);
		kfree(twl);
		return status;
	}

	twl4030_usb_phy_init(twl);

	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
예제 #9
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;
}
예제 #10
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;

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