static int __init otg_wakelock_init(void) { int ret; otgwl_xceiv = otg_get_transceiver(); if (!otgwl_xceiv) { pr_err("%s: No OTG transceiver found\n", __func__); return -ENODEV; } snprintf(vbus_lock.name, sizeof(vbus_lock.name), "vbus-%s", dev_name(otgwl_xceiv->dev)); wake_lock_init(&vbus_lock.wakelock, WAKE_LOCK_SUSPEND, vbus_lock.name); otgwl_nb.notifier_call = otgwl_otg_notifications; ret = otg_register_notifier(otgwl_xceiv, &otgwl_nb); if (ret) { pr_err("%s: otg_register_notifier on transceiver %s" " failed\n", __func__, dev_name(otgwl_xceiv->dev)); otgwl_xceiv = NULL; wake_lock_destroy(&vbus_lock.wakelock); return ret; } otgwl_handle_event(otgwl_xceiv->last_event); return ret; }
static int omap2430_musb_init(struct musb *musb) { u32 l; int status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ musb->xceiv = otg_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work); status = pm_runtime_get_sync(dev); if (status < 0) { dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); goto err1; } l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ l &= ~ULPI_12PIN; /* Disable ULPI */ l |= UTMI_8BIT; /* Enable UTMI */ } else { l |= ULPI_12PIN; } musb_writel(musb->mregs, OTG_INTERFSEL, l); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); musb->nb.notifier_call = musb_otg_notifications; status = otg_register_notifier(musb->xceiv, &musb->nb); if (status) dev_dbg(musb->controller, "notification register failed\n"); setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); return 0; err1: return status; }
static int __devinit isp1704_charger_probe(struct platform_device *pdev) { struct isp1704_charger *isp; int ret = -ENODEV; isp = kzalloc(sizeof *isp, GFP_KERNEL); if (!isp) return -ENOMEM; isp->otg = otg_get_transceiver(); if (!isp->otg) goto fail0; ret = isp1704_test_ulpi(isp); if (ret < 0) goto fail1; isp->dev = &pdev->dev; platform_set_drvdata(pdev, isp); isp->psy.name = "isp1704"; isp->psy.type = POWER_SUPPLY_TYPE_USB; isp->psy.properties = power_props; isp->psy.num_properties = ARRAY_SIZE(power_props); isp->psy.get_property = isp1704_charger_get_property; ret = power_supply_register(isp->dev, &isp->psy); if (ret) goto fail1; /* * REVISIT: using work in order to allow the otg notifications to be * made atomically in the future. */ INIT_WORK(&isp->work, isp1704_charger_work); isp->nb.notifier_call = isp1704_notifier_call; ret = otg_register_notifier(isp->otg, &isp->nb); if (ret) goto fail2; dev_info(isp->dev, "registered with product id %s\n", isp->model); return 0; fail2: power_supply_unregister(&isp->psy); fail1: otg_put_transceiver(isp->otg); fail0: kfree(isp); dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret); return ret; }
int __init musb_platform_init(struct musb *musb) { u32 l; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; int status; u32 val; /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ musb->xceiv = otg_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } /* Fixme this can be enabled when load the gadget driver also*/ musb_platform_resume(musb); /*powerup the phy as romcode would have put the phy in some state * which is impacting the core retention if the gadget driver is not * loaded. */ l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ l &= ~ULPI_12PIN; /* Disable ULPI */ l |= UTMI_8BIT; /* Enable UTMI */ } else { l |= ULPI_12PIN; } musb_writel(musb->mregs, OTG_INTERFSEL, l); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); if (is_host_enabled(musb)) musb->board_set_vbus = omap_set_vbus; setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); plat->is_usb_active = is_musb_active; wake_lock_init(&plat->musb_lock, WAKE_LOCK_SUSPEND, "musb_wake_lock"); if (cpu_is_omap44xx()) { phymux_base = ioremap(0x4A100000, SZ_1K); ctrl_base = ioremap(0x4A002000, SZ_1K); /* register for transciever notification*/ status = otg_register_notifier(musb->xceiv, &musb->nb); if (status) { DBG(1, "notification register failed\n"); wake_lock_destroy(&plat->musb_lock); } ctrl_base = ioremap(0x4A002000, SZ_1K); if (!ctrl_base) { dev_err(dev, "ioremap failed\n"); return -ENOMEM; } } /* configure in force idle/ standby */ musb_writel(musb->mregs, OTG_FORCESTDBY, 1); val = musb_readl(musb->mregs, OTG_SYSCONFIG); val &= ~(SMARTIDLEWKUP | NOSTDBY | ENABLEWAKEUP); val |= FORCEIDLE | FORCESTDBY; musb_writel(musb->mregs, OTG_SYSCONFIG, val); l = musb_readl(musb->mregs, OTG_FORCESTDBY); l &= ~ENABLEFORCE; /* disable MSTANDBY */ musb_writel(musb->mregs, OTG_FORCESTDBY, l); return 0; }
static int pda_power_probe(struct platform_device *pdev) { int ret = 0; dev = &pdev->dev; if (pdev->id != -1) { dev_err(dev, "it's meaningless to register several " "pda_powers; use id = -1\n"); ret = -EINVAL; goto wrongid; } pdata = pdev->dev.platform_data; if (pdata->init) { ret = pdata->init(dev); if (ret < 0) goto init_failed; } update_status(); if (!pdata->wait_for_status) pdata->wait_for_status = 500; if (!pdata->wait_for_charger) pdata->wait_for_charger = 500; if (!pdata->polling_interval) pdata->polling_interval = 2000; if (!pdata->ac_max_uA) pdata->ac_max_uA = 500000; setup_timer(&charger_timer, charger_timer_func, 0); ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); if (pdata->supplied_to) { pda_psy_ac.supplied_to = pdata->supplied_to; pda_psy_ac.num_supplicants = pdata->num_supplicants; pda_psy_usb.supplied_to = pdata->supplied_to; pda_psy_usb.num_supplicants = pdata->num_supplicants; } ac_draw = regulator_get(dev, "ac_draw"); if (IS_ERR(ac_draw)) { dev_dbg(dev, "couldn't get ac_draw regulator\n"); ac_draw = NULL; ret = PTR_ERR(ac_draw); } transceiver = otg_get_transceiver(); if (transceiver && !pdata->is_usb_online) { pdata->is_usb_online = otg_is_usb_online; } if (transceiver && !pdata->is_ac_online) { pdata->is_ac_online = otg_is_ac_online; } if (pdata->is_ac_online) { ret = power_supply_register(&pdev->dev, &pda_psy_ac); if (ret) { dev_err(dev, "failed to register %s power supply\n", pda_psy_ac.name); goto ac_supply_failed; } if (ac_irq) { ret = request_irq(ac_irq->start, power_changed_isr, get_irq_flags(ac_irq), ac_irq->name, &pda_psy_ac); if (ret) { dev_err(dev, "request ac irq failed\n"); goto ac_irq_failed; } } else { polling = 1; } } if (pdata->is_usb_online) { ret = power_supply_register(&pdev->dev, &pda_psy_usb); if (ret) { dev_err(dev, "failed to register %s power supply\n", pda_psy_usb.name); goto usb_supply_failed; } if (usb_irq) { ret = request_irq(usb_irq->start, power_changed_isr, get_irq_flags(usb_irq), usb_irq->name, &pda_psy_usb); if (ret) { dev_err(dev, "request usb irq failed\n"); goto usb_irq_failed; } } else { polling = 1; } } if (transceiver && pdata->use_otg_notifier) { otg_nb.notifier_call = otg_handle_notification; ret = otg_register_notifier(transceiver, &otg_nb); if (ret) { dev_err(dev, "failure to register otg notifier\n"); goto otg_reg_notifier_failed; } polling = 0; } if (polling) { dev_dbg(dev, "will poll for status\n"); setup_timer(&polling_timer, polling_timer_func, 0); mod_timer(&polling_timer, jiffies + msecs_to_jiffies(pdata->polling_interval)); } if (ac_irq || usb_irq) device_init_wakeup(&pdev->dev, 1); return 0; otg_reg_notifier_failed: if (pdata->is_usb_online && usb_irq) free_irq(usb_irq->start, &pda_psy_usb); usb_irq_failed: if (pdata->is_usb_online) power_supply_unregister(&pda_psy_usb); usb_supply_failed: if (pdata->is_ac_online && ac_irq) free_irq(ac_irq->start, &pda_psy_ac); if (transceiver) otg_put_transceiver(transceiver); ac_irq_failed: if (pdata->is_ac_online) power_supply_unregister(&pda_psy_ac); ac_supply_failed: if (ac_draw) { regulator_put(ac_draw); ac_draw = NULL; } if (pdata->exit) pdata->exit(dev); init_failed: wrongid: return ret; }
static int cpcap_otg_probe(struct platform_device *pdev) { struct cpcap_otg_data *cpcap; struct resource *res; unsigned long val; int err; cpcap = kzalloc(sizeof(struct cpcap_otg_data), GFP_KERNEL); if (!cpcap) return -ENOMEM; cpcap->otg.dev = &pdev->dev; cpcap->otg.label = "cpcap-otg"; cpcap->otg.state = OTG_STATE_UNDEFINED; cpcap->otg.set_host = cpcap_otg_set_host; cpcap->otg.set_peripheral = cpcap_otg_set_peripheral; cpcap->otg.set_suspend = cpcap_otg_set_suspend; cpcap->otg.set_power = cpcap_otg_set_power; cpcap->host = pdev->dev.platform_data; wake_lock_init(&cpcap->wake_lock, WAKE_LOCK_SUSPEND, "cpcap_otg"); platform_set_drvdata(pdev, cpcap); cpcap->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(cpcap->clk)) { dev_err(&pdev->dev, "Can't get otg clock\n"); err = PTR_ERR(cpcap->clk); goto err_clk; } err = clk_enable(cpcap->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; } cpcap->regs = ioremap(res->start, resource_size(res)); if (!cpcap->regs) { err = -ENOMEM; goto err_io; } val = readl(cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); val |= TEGRA_VBUS_WAKEUP_SW_ENABLE | TEGRA_ID_SW_ENABLE; val |= TEGRA_ID_SW_VALUE; val &= ~(TEGRA_VBUS_WAKEUP_SW_VALUE); writel(val, cpcap->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); clk_disable(cpcap->clk); cpcap->otg.state = OTG_STATE_A_SUSPEND; ATOMIC_INIT_NOTIFIER_HEAD(&cpcap->otg.notifier); cpcap->nb.notifier_call = cpcap_otg_notify; otg_register_notifier(&cpcap->otg, &cpcap->nb); err = otg_set_transceiver(&cpcap->otg); if (err) { dev_err(&pdev->dev, "can't register transceiver (%d)\n", err); goto err_otg; } return 0; err_otg: iounmap(cpcap->regs); err_io: clk_disable(cpcap->clk); err_clken: clk_put(cpcap->clk); err_clk: wake_lock_destroy(&cpcap->wake_lock); platform_set_drvdata(pdev, NULL); kfree(cpcap); return err; }
static int omap2430_musb_init(struct musb *musb) { u32 l; int status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ musb->xceiv = otg_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } musb->otg_notifier_wq = create_singlethread_workqueue("musb-otg"); if (!musb->otg_notifier_wq) { pr_err("HS USB OTG: cannot allocate otg event wq\n"); status = -ENOMEM; goto err1; } #ifdef CONFIG_USB_SAMSUNG_OMAP_NORPM omap2430_async_resume(musb); #endif status = pm_runtime_get_sync(dev); #ifndef CONFIG_USB_SAMSUNG_OMAP_NORPM if (status < 0) { dev_err(dev, "pm_runtime_get_sync FAILED"); goto err2; } #endif l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ l &= ~ULPI_12PIN; /* Disable ULPI */ l |= UTMI_8BIT; /* Enable UTMI */ } else { l |= ULPI_12PIN; } musb_writel(musb->mregs, OTG_INTERFSEL, l); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); musb->nb.notifier_call = musb_otg_notifications; status = otg_register_notifier(musb->xceiv, &musb->nb); if (status) dev_dbg(musb->controller, "notification register failed\n"); setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); musb->otg_enum_delay = INIT_OTG_DELAY; pm_runtime_put_noidle(musb->controller); #ifdef CONFIG_USB_SAMSUNG_OMAP_NORPM musb->reserve_async_suspend++; #endif return 0; err2: destroy_workqueue(musb->otg_notifier_wq); err1: otg_put_transceiver(musb->xceiv); pm_runtime_disable(dev); return status; }
static int omap2430_musb_init(struct musb *musb) { u32 l, status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ musb->xceiv = otg_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } omap2430_low_level_init(musb); l = musb_readl(musb->mregs, OTG_SYSCONFIG); l &= ~ENABLEWAKEUP; /* disable wakeup */ l &= ~NOSTDBY; /* remove possible nostdby */ l |= SMARTSTDBY; /* enable smart standby */ l &= ~AUTOIDLE; /* disable auto idle */ l &= ~NOIDLE; /* remove possible noidle */ l |= SMARTIDLE; /* enable smart idle */ /* * MUSB AUTOIDLE don't work in 3430. * Workaround by Richard Woodruff/TI */ if (!cpu_is_omap3430()) l |= AUTOIDLE; /* enable auto idle */ musb_writel(musb->mregs, OTG_SYSCONFIG, l); l = musb_readl(musb->mregs, OTG_INTERFSEL); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* OMAP4 uses Internal PHY GS70 which uses UTMI interface */ l &= ~ULPI_12PIN; /* Disable ULPI */ l |= UTMI_8BIT; /* Enable UTMI */ } else { l |= ULPI_12PIN; } musb_writel(musb->mregs, OTG_INTERFSEL, l); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); musb->nb.notifier_call = musb_otg_notifications; status = otg_register_notifier(musb->xceiv, &musb->nb); if (status) DBG(1, "notification register failed\n"); /* check whether cable is already connected */ if (musb->xceiv->state ==OTG_STATE_B_IDLE) musb_otg_notifications(&musb->nb, 1, musb->xceiv->gadget); setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); return 0; }
static int omap2430_musb_init(struct musb *musb) { u32 l; int status = 0; struct device *dev = musb->controller; /* We require some kind of external transceiver, hooked * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ musb->xceiv = otg_get_transceiver(); if (!musb->xceiv) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } musb->otg_notifier_wq = create_singlethread_workqueue("musb-otg"); if (!musb->otg_notifier_wq) { pr_err("HS USB OTG: cannot allocate otg event wq\n"); status = -ENOMEM; goto err1; } status = pm_runtime_get_sync(dev); if (status < 0) { dev_err(dev, "pm_runtime_get_sync FAILED"); goto err2; } /* Set OTG_INTERFSEL to ULPI for correct charger detection. * This should be later set to UTMI. */ l = musb_readl(musb->mregs, OTG_INTERFSEL); l |= ULPI_12PIN; musb_writel(musb->mregs, OTG_INTERFSEL, l); pr_debug("HS USB OTG: revision 0x%x, sysconfig 0x%02x, " "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n", musb_readl(musb->mregs, OTG_REVISION), musb_readl(musb->mregs, OTG_SYSCONFIG), musb_readl(musb->mregs, OTG_SYSSTATUS), musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); musb->nb.notifier_call = musb_otg_notifications; status = otg_register_notifier(musb->xceiv, &musb->nb); if (status) dev_dbg(musb->controller, "notification register failed\n"); setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); return 0; err2: destroy_workqueue(musb->otg_notifier_wq); err1: otg_put_transceiver(musb->xceiv); pm_runtime_disable(dev); return status; }
/*Charger Module Initialization*/ static int max8903_charger_probe(struct platform_device *pdev) { struct max8903_charger *mc; int ret; struct resource *r; /*allocate mem*/ mc = kzalloc(sizeof(*mc), GFP_KERNEL); if (!mc) return -ENOMEM; platform_set_drvdata(pdev, mc); printk("MAX8903: Charger Initializing...\n"); //INIT_DELAYED_WORK(&mc->max8903_charger_detect_work, max8903_charger_detect); /* Create power supplies for WALL/USB which are the only 2 ext supplies*/ mc->adapter.name = "ac"; mc->adapter.type = POWER_SUPPLY_TYPE_MAINS; mc->adapter.properties = power_props; mc->adapter.num_properties = ARRAY_SIZE(power_props); mc->adapter.get_property = &adapter_get_property; mc->usb.name = "usb"; mc->usb.type = POWER_SUPPLY_TYPE_USB; mc->usb.properties = power_props; mc->usb.num_properties = ARRAY_SIZE(power_props); mc->usb.get_property = usb_get_property; mc->adapter_online = 0; mc->adapter_active = 0; mc->adapter_curr_limit = USB_CURRENT_LIMIT_HIGH; /* default limit is high limit */ mc->usb_online = 0; mc->usb_active = 0; ret = power_supply_register(&pdev->dev, &mc->adapter); if (ret) { printk("MAX8903: Failed to register WALL CHARGER\n"); goto exit0; } ret = power_supply_register(&pdev->dev, &mc->usb); if (ret) { printk("MAX8903: Failed to register USB CHARGER\n"); goto exit1; } /*****************/ /* Get resources */ /*****************/ r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_EN); if (!r) { dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_EN); goto exit1; } mc->max8903_gpio_chg_en = r->start; r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_FLT); if (!r) { dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_FLT); goto exit1; } mc->max8903_gpio_chg_flt = r->start; r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_IUSB); if (!r) { dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_IUSB); goto exit1; } mc->max8903_gpio_chg_iusb = r->start; r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_USUS); if (!r) { dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_USUS); goto exit1; } mc->max8903_gpio_chg_usus = r->start; r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_ILM); if (!r) { dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_ILM); goto exit1; } mc->max8903_gpio_chg_ilm = r->start; r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_UOK); if (!r) { dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_UOK); goto exit1; } mc->max8903_gpio_chg_uok = r->start; r = platform_get_resource_byname(pdev, IORESOURCE_IO, MAX8903_TOKEN_GPIO_CHG_DOK); if (!r) { dev_err(&pdev->dev, "failed to get resource: %s\n", MAX8903_TOKEN_GPIO_CHG_DOK); goto exit1; } mc->max8903_gpio_chg_dok = r->start; /******************************/ /* Control pins configuration */ /******************************/ /*~DOK Status*/ if (gpio_request(mc->max8903_gpio_chg_dok, MAX8903_TOKEN_GPIO_CHG_DOK) < 0) { printk(KERN_ERR "Can't get GPIO for max8903 chg_dok\n"); goto exit2; } gpio_direction_input(mc->max8903_gpio_chg_dok); /*~UOK Status*/ if (gpio_request(mc->max8903_gpio_chg_uok, MAX8903_TOKEN_GPIO_CHG_UOK) < 0) { printk(KERN_ERR "Can't get GPIO for max8903 chg_uok\n"); goto exit3; } gpio_direction_input(mc->max8903_gpio_chg_uok); /*IUSB control*/ if (gpio_request(mc->max8903_gpio_chg_iusb, MAX8903_TOKEN_GPIO_CHG_IUSB) < 0) { printk(KERN_ERR "Can't get GPIO for max8903 chg_iusb\n"); goto exit5; } gpio_direction_output(mc->max8903_gpio_chg_iusb, CHG_IUSB_SELECT_500mA); /*USUS control*/ if (gpio_request(mc->max8903_gpio_chg_usus, MAX8903_TOKEN_GPIO_CHG_USUS) < 0) { printk(KERN_ERR "Can't get GPIO for max8903 chg_usus\n"); goto exit6; } gpio_direction_output(mc->max8903_gpio_chg_usus, DISABLED); // leave USUS disabled until we connect /*~CEN control */ if (gpio_request(mc->max8903_gpio_chg_en, MAX8903_TOKEN_GPIO_CHG_EN) < 0) { printk(KERN_ERR "Can't get GPIO for max8903 chg_en\n"); goto exit7; } gpio_direction_output(mc->max8903_gpio_chg_en, DISABLED); if (gpio_request(mc->max8903_gpio_chg_ilm, MAX8903_TOKEN_GPIO_CHG_ILM) < 0) { printk(KERN_ERR "Can't get GPIO for max8903 chg_ilm\n"); goto exit8; } gpio_direction_output(mc->max8903_gpio_chg_ilm, CHG_ILM_SELECT_USB); /* set to USB current limit by default */ if (gpio_request(mc->max8903_gpio_chg_flt, MAX8903_TOKEN_GPIO_CHG_FLT) < 0) { printk(KERN_ERR "Can't get GPIO for max8903 chg_flt\n"); goto exit9; } gpio_direction_input(mc->max8903_gpio_chg_flt); /*~FLT status*/ mc->flt_irq= gpio_to_irq(mc->max8903_gpio_chg_flt) ; ret = request_irq( mc->flt_irq, max8903_fault_interrupt, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_DISABLED, "max8903-fault-irq", mc); printk("MAX8903: Request CHARGER FLT IRQ successfully!\n"); if (ret < 0) { printk(KERN_ERR "MAX8903: Can't Request IRQ for max8903 flt_irq\n"); goto exita; } /* create sysfs for manufacture testing coverage on charging the operator should be able to write 1 to turn on the charging and 0 to turn off the charging to verify the charging circuit is functioning */ ret = sysfs_create_group(&pdev->dev.kobj, &max8903_attr_group); if (ret){ printk(KERN_ERR "MAX8903: Can't Create Sysfs Entry for FTM\n"); goto exitd; } // Register charger work and notification callback. INIT_DELAYED_WORK_DEFERRABLE(&mc->usb_work, max8903_usb_charger_work); mc->nb.notifier_call = twl6030_usb_notifier_call; mc->otg = otg_get_transceiver(); if (!mc->otg) { dev_err(&pdev->dev, "otg_get_transceiver() failed\n"); goto exitn; } ret = otg_register_notifier(mc->otg, &mc->nb); if (ret) { dev_err(&pdev->dev, "otg register notifier failed %d\n", ret); goto exitn; } max8903_usb_charger_atboot(mc); return 0; exitn: cancel_delayed_work_sync(&mc->usb_work); sysfs_remove_group(&pdev->dev.kobj, &max8903_attr_group); exitd: free_irq(mc->flt_irq,mc); exita: gpio_free(mc->max8903_gpio_chg_flt); exit9: gpio_free(mc->max8903_gpio_chg_ilm); exit8: gpio_free(mc->max8903_gpio_chg_en); exit7: gpio_free(mc->max8903_gpio_chg_usus); exit6: gpio_free(mc->max8903_gpio_chg_iusb); exit5: gpio_free(mc->max8903_gpio_chg_uok); exit3: gpio_free(mc->max8903_gpio_chg_dok); exit2: power_supply_unregister(&mc->usb); exit1: power_supply_unregister(&mc->adapter); exit0: kfree(mc); return ret; }
static int __devinit bq2416x_charger_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bq2416x_device_info *di; struct bq2416x_platform_data *pdata = client->dev.platform_data; int ret; u8 read_reg = 0; enum plugin_status plugin_stat; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; di->dev = &client->dev; di->client = client; i2c_set_clientdata(client, di); ret = bq2416x_read_byte(di, &read_reg, REG_PART_REVISION); if (ret < 0) { dev_err(&client->dev, "chip not present at address %x\n", client->addr); ret = -EINVAL; goto err_kfree; } #if 0 if ((read_reg & 0x18) == 0x00 && (client->addr == 0x6a)) di->bqchip_version = BQ24156; #endif if ((read_reg & 0x18) == 0x00 && (client->addr == 0x6b)) di->bqchip_version = BQ24161; if (di->bqchip_version == 0) { dev_dbg(&client->dev, "unknown bq chip\n"); dev_dbg(&client->dev, "Chip address %x", client->addr); dev_dbg(&client->dev, "bq chip version reg value %x", read_reg); ret = -EINVAL; goto err_kfree; } // di->nb.notifier_call = bq2416x_charger_event; #if 0 bq2415x_config_safety_reg(di, pdata->max_charger_currentmA, pdata->max_charger_voltagemV); di->cin_limit = 900; di->term_currentmA = pdata->termination_currentmA; bq2415x_config_control_reg(di); bq2415x_config_voltage_reg(di); bq2415x_config_current_reg(di); #endif /*set gpio_174 to control CD pin to disable/enable bq24161 IC*/ gpio_request(BQ2416X_GPIO_174, "gpio_174_cd"); /* set charger CD pin to low level and enable it to supply power normally*/ gpio_direction_output(BQ2416X_GPIO_174, 0); ret = bq2416x_get_max_charge_voltage(di); if(!ret){ di->max_voltagemV = pdata->max_charger_voltagemV; } di->voltagemV = di->max_voltagemV; ret = bq2416x_get_max_charge_current(di); if(!ret){ di->max_currentmA = pdata->max_charger_currentmA; } di->currentmA = CURRENT_USB_CHARGE_IN ; di->term_currentmA = CURRENT_TERM_CHARGE_IN; di->dppm_voltagemV = VOLT_DPPM_ADJUST; di->cin_limit = CURRENT_USB_LIMIT_IN; di->enable_hotcold_temp_charge = set_one; di->enable_low_chg = DISABLE_LOW_CHG;/*set normally charge mode*/ di->enable_iterm = ENABLE_ITERM; /*enable charge current termination*/ di->factory_flag = 0; di->enable_ce = ENABLE_CE; di->hz_mode = 0; di->cd_active = 0; INIT_DELAYED_WORK_DEFERRABLE(&di->bq2416x_charger_work, bq2416x_charger_work); #if BQ2416X_USE_WAKE_LOCK wake_lock_init(&di->charger_wake_lock, WAKE_LOCK_SUSPEND, "charger_wake_lock"); #endif //BLOCKING_INIT_NOTIFIER_HEAD(¬ifier_list); di->active = 0; di->params.enable = 1; di->cfg_params = 1; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); bq2416x_config_safety_reg(di); #if 0 ret = bq2416x_read_byte(di, &read_reg, REG_SPECIAL_CHARGER_VOLTAGE); if (!(read_reg & 0x08)) { di->active = 1; schedule_delayed_work(&di->bq2415x_charger_work, 0); } #endif ret = sysfs_create_group(&client->dev.kobj, &bq2416x_attr_group); if (ret) dev_dbg(&client->dev, "could not create sysfs files\n"); //twl6030_register_notifier(&di->nb, 1); INIT_WORK(&di->usb_work, bq2416x_usb_charger_work); //r00186667, 2011/08/02, otg register for receive USB/AC plugin event.begin di->nb_otg.notifier_call = bq2416x_usb_notifier_call; di->otg = otg_get_transceiver(); ret = otg_register_notifier(di->otg, &di->nb_otg); if (ret) dev_err(&client->dev, "otg register notifier failed %d\n", ret); //r00186667, 2011/08/02, otg register for receive USB/AC plugin event.end //r00186667, 2011/08/02, get the boot event type.begin plugin_stat = get_plugin_device_status(); if( PLUGIN_USB_CHARGER == plugin_stat){ di->event = USB_EVENT_VBUS; }else if (PLUGIN_AC_CHARGER == plugin_stat){ di->event = USB_EVENT_CHARGER; }else{ di->event = USB_EVENT_NONE; } schedule_work(&di->usb_work); //r00186667, 2011/08/02, get the boot event type.end return 0; err_kfree: kfree(di); return ret; }
static int __devinit twl6030_bci_battery_probe(struct platform_device *pdev) { struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; struct twl6030_bci_device_info *di; int irq = -1; int ret; int i; if (!pdata) { dev_dbg(&pdev->dev, "platform_data not available\n"); return -EINVAL; } di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; di->platform_data = kmemdup(pdata, sizeof(*pdata), GFP_KERNEL); if (!di->platform_data) { kfree(di); return -ENOMEM; } di->state = STATE_BATTERY; di->monitoring_interval = 15; di->capacity_max_uAh = 570000; di->full_jiffies = msecs_to_jiffies(120 * 1000) + jiffies; di->vbat_jiffies = jiffies; di->dev = &pdev->dev; di->bat.name = "twl6030_battery"; di->bat.supplied_to = twl6030_bci_supplied_to; di->bat.num_supplicants = ARRAY_SIZE(twl6030_bci_supplied_to); di->bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bat.properties = twl6030_bci_battery_props; di->bat.num_properties = ARRAY_SIZE(twl6030_bci_battery_props); di->bat.get_property = twl6030_bci_battery_get_property; di->bat_health = POWER_SUPPLY_HEALTH_GOOD; di->usb.name = "twl6030_usb"; di->usb.type = POWER_SUPPLY_TYPE_USB; di->usb.properties = twl6030_usb_props; di->usb.num_properties = ARRAY_SIZE(twl6030_usb_props); di->usb.get_property = twl6030_usb_get_property; platform_set_drvdata(pdev, di); wake_lock_init(&usb_wake_lock, WAKE_LOCK_SUSPEND, "usb_wake_lock"); wake_lock_init(&battery_wake_lock, WAKE_LOCK_SUSPEND, "battery_wake_lock"); di->wq = create_freezable_workqueue(dev_name(&pdev->dev)); /* settings for temperature sensing */ ret = twl6030battery_temp_setup(true); if (ret) goto temp_setup_fail; ret = power_supply_register(&pdev->dev, &di->bat); if (ret) { dev_err(&pdev->dev, "failed to register main battery\n"); goto batt_failed; } ret = power_supply_register(&pdev->dev, &di->usb); if (ret) { dev_err(&pdev->dev, "failed to register usb power supply\n"); goto usb_failed; } di->charge_n1 = 0; di->timer_n1 = 0; INIT_WORK(&di->charge_control_work, twl6030_charge_control_work); INIT_WORK(&di->charge_fault_work, twl6030_charge_fault_work); INIT_WORK(&di->calibration_work, twl6030_calibration_work); INIT_DELAYED_WORK_DEFERRABLE(&di->monitor_work, twl6030_monitor_work); ret = twl6030battery_voltage_setup(di); if (ret) dev_err(&pdev->dev, "voltage measurement setup failed\n"); ret = twl6030battery_current_setup(true); if (ret) dev_err(&pdev->dev, "current measurement setup failed\n"); /* initialize for USB charging */ twl6030_config_limit1_reg(di, pdata->max_charger_voltagemV); twl6030_config_limit2_reg(di, pdata->max_charger_currentmA); ret = twl_i2c_write_u8(TWL6030_MODULE_CHARGER, MBAT_TEMP, CONTROLLER_INT_MASK); if (ret) goto init_failed; ret = twl_i2c_write_u8(TWL6030_MODULE_CHARGER, MASK_MCHARGERUSB_THMREG | MASK_MCURRENT_TERM, CHARGERUSB_INT_MASK); if (ret) goto init_failed; di->charger_outcurrentmA = di->platform_data->max_charger_currentmA; twl6030_set_watchdog(di, 32); di->nb.notifier_call = twl6030_usb_notifier_call; di->otg = otg_get_transceiver(); if (di->otg) { ret = otg_register_notifier(di->otg, &di->nb); if (ret) dev_err(&pdev->dev, "otg register notifier failed %d\n", ret); } else dev_err(&pdev->dev, "otg_get_transceiver failed %d\n", ret); di->charger_incurrentmA = twl6030_get_usb_max_power(di->otg); di->gpadc_vbat_chnl = TWL6030_GPADC_VBAT_CHNL; di->voltage_mV = twl6030_get_gpadc_conversion(di, di->gpadc_vbat_chnl); dev_info(&pdev->dev, "Battery Voltage at Bootup is %d mV\n", di->voltage_mV); /* initialize the voltage history table */ /* TODO: consider the best initial values for the table */ for (i=0; i < VOLTAGE_HISTORY_LENGTH; i++) di->voltage_history[i] = di->voltage_mV; /* start with a rough estimate */ di->capacity = twl6030_estimate_capacity(di); if (di->capacity < 5) di->capacity = 5; if (di->capacity > 50) di->capacity = 50; ret = twl6030backupbatt_setup(); if (ret) dev_err(&pdev->dev, "Backup Bat charging setup failed\n"); /* request charger fault interruption */ irq = platform_get_irq(pdev, 1); ret = request_threaded_irq(irq, NULL, twl6030charger_fault_interrupt, 0, "twl_bci_fault", di); if (ret) { dev_err(&pdev->dev, "could not request irq %d, status %d\n", irq, ret); goto init_failed; } /* request charger ctrl interruption */ irq = platform_get_irq(pdev, 0); ret = request_threaded_irq(irq, NULL, twl6030charger_ctrl_interrupt, 0, "twl_bci_ctrl", di); if (ret) { dev_err(&pdev->dev, "could not request irq %d, status %d\n", irq, ret); goto chg_irq_fail; } twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, REG_INT_MSK_LINE_C); twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, REG_INT_MSK_STS_C); twl6030_interrupt_unmask(TWL6030_CHARGER_FAULT_INT_MASK, REG_INT_MSK_LINE_C); twl6030_interrupt_unmask(TWL6030_CHARGER_FAULT_INT_MASK, REG_INT_MSK_STS_C); ret = sysfs_create_group(&pdev->dev.kobj, &twl6030_bci_attr_group); if (ret) dev_err(&pdev->dev, "could not create sysfs files\n"); queue_work(di->wq, &di->calibration_work); queue_delayed_work(di->wq, &di->monitor_work, 0); return 0; /* TODO: fix fail exit mess */ chg_irq_fail: irq = platform_get_irq(pdev, 1); free_irq(irq, di); init_failed: power_supply_unregister(&di->usb); usb_failed: power_supply_unregister(&di->bat); batt_failed: if (irq != -1) free_irq(irq, di); temp_setup_fail: wake_lock_destroy(&usb_wake_lock); platform_set_drvdata(pdev, NULL); kfree(di); return ret; }
static int __devinit isp1704_charger_probe(struct platform_device *pdev) { struct isp1704_charger *isp; int ret = -ENODEV; isp = kzalloc(sizeof *isp, GFP_KERNEL); if (!isp) return -ENOMEM; isp->otg = otg_get_transceiver(); if (!isp->otg) goto fail0; isp->dev = &pdev->dev; platform_set_drvdata(pdev, isp); isp1704_charger_set_power(isp, 1); ret = isp1704_test_ulpi(isp); if (ret < 0) goto fail1; isp->psy.name = "isp1704"; isp->psy.type = POWER_SUPPLY_TYPE_USB; isp->psy.properties = power_props; isp->psy.num_properties = ARRAY_SIZE(power_props); isp->psy.get_property = isp1704_charger_get_property; ret = power_supply_register(isp->dev, &isp->psy); if (ret) goto fail1; /* * REVISIT: using work in order to allow the otg notifications to be * made atomically in the future. */ INIT_WORK(&isp->work, isp1704_charger_work); isp->nb.notifier_call = isp1704_notifier_call; ret = otg_register_notifier(isp->otg, &isp->nb); if (ret) goto fail2; dev_info(isp->dev, "registered with product id %s\n", isp->model); /* * Taking over the D+ pullup. * * FIXME: The device will be disconnected if it was already * enumerated. The charger driver should be always loaded before any * gadget is loaded. */ if (isp->otg->gadget) usb_gadget_disconnect(isp->otg->gadget); /* Detect charger if VBUS is valid (the cable was already plugged). */ ret = otg_io_read(isp->otg, ULPI_USB_INT_STS); isp1704_charger_set_power(isp, 0); if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) { isp->event = USB_EVENT_VBUS; schedule_work(&isp->work); } return 0; fail2: power_supply_unregister(&isp->psy); fail1: otg_put_transceiver(isp->otg); fail0: kfree(isp); dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret); return ret; }
static int __init twl4030_bci_probe(struct platform_device *pdev) { struct twl4030_bci *bci; int ret; u32 reg; bci = kzalloc(sizeof(*bci), GFP_KERNEL); if (bci == NULL) return -ENOMEM; bci->dev = &pdev->dev; bci->irq_chg = platform_get_irq(pdev, 0); bci->irq_bci = platform_get_irq(pdev, 1); platform_set_drvdata(pdev, bci); bci->ac.name = "twl4030_ac"; bci->ac.type = POWER_SUPPLY_TYPE_MAINS; bci->ac.properties = twl4030_charger_props; bci->ac.num_properties = ARRAY_SIZE(twl4030_charger_props); bci->ac.get_property = twl4030_bci_get_property; ret = power_supply_register(&pdev->dev, &bci->ac); if (ret) { dev_err(&pdev->dev, "failed to register ac: %d\n", ret); goto fail_register_ac; } bci->usb.name = "twl4030_usb"; bci->usb.type = POWER_SUPPLY_TYPE_USB; bci->usb.properties = twl4030_charger_props; bci->usb.num_properties = ARRAY_SIZE(twl4030_charger_props); bci->usb.get_property = twl4030_bci_get_property; ret = power_supply_register(&pdev->dev, &bci->usb); if (ret) { dev_err(&pdev->dev, "failed to register usb: %d\n", ret); goto fail_register_usb; } ret = request_threaded_irq(bci->irq_chg, NULL, twl4030_charger_interrupt, 0, pdev->name, bci); if (ret < 0) { dev_err(&pdev->dev, "could not request irq %d, status %d\n", bci->irq_chg, ret); goto fail_chg_irq; } ret = request_threaded_irq(bci->irq_bci, NULL, twl4030_bci_interrupt, 0, pdev->name, bci); if (ret < 0) { dev_err(&pdev->dev, "could not request irq %d, status %d\n", bci->irq_bci, ret); goto fail_bci_irq; } INIT_WORK(&bci->work, twl4030_bci_usb_work); bci->transceiver = otg_get_transceiver(); if (bci->transceiver != NULL) { bci->otg_nb.notifier_call = twl4030_bci_usb_ncb; otg_register_notifier(bci->transceiver, &bci->otg_nb); } /* Enable interrupts now. */ reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 | TWL4030_TBATOR1 | TWL4030_BATSTS); ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, TWL4030_INTERRUPTS_BCIIMR1A); if (ret < 0) { dev_err(&pdev->dev, "failed to unmask interrupts: %d\n", ret); goto fail_unmask_interrupts; } reg = ~(u32)(TWL4030_VBATOV | TWL4030_VBUSOV | TWL4030_ACCHGOV); ret = twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, reg, TWL4030_INTERRUPTS_BCIIMR2A); if (ret < 0) dev_warn(&pdev->dev, "failed to unmask interrupts: %d\n", ret); twl4030_charger_enable_ac(true); twl4030_charger_enable_usb(bci, true); return 0; fail_unmask_interrupts: if (bci->transceiver != NULL) { otg_unregister_notifier(bci->transceiver, &bci->otg_nb); otg_put_transceiver(bci->transceiver); } free_irq(bci->irq_bci, bci); fail_bci_irq: free_irq(bci->irq_chg, bci); fail_chg_irq: power_supply_unregister(&bci->usb); fail_register_usb: power_supply_unregister(&bci->ac); fail_register_ac: platform_set_drvdata(pdev, NULL); kfree(bci); return ret; }
static int __devinit bq2416x_charger_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bq2416x_device_info *di; struct bq2416x_platform_data *pdata = client->dev.platform_data; int ret; u8 read_reg = 0; enum plugin_status plugin_stat; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; di->dev = &client->dev; di->client = client; i2c_set_clientdata(client, di); ret = bq2416x_read_byte(di, &read_reg, REG_PART_REVISION_REG04); if (ret < 0) { dev_err(&client->dev, "chip not present at address %x\n", client->addr); ret = -EINVAL; goto err_kfree; } if ((read_reg & 0x18) == 0x00 && (client->addr == 0x6b)) di->bqchip_version = BQ24161; if (di->bqchip_version == 0) { dev_dbg(&client->dev, "unknown bq chip\n"); dev_dbg(&client->dev, "Chip address %x", client->addr); dev_dbg(&client->dev, "bq chip version reg value %x", read_reg); ret = -EINVAL; goto err_kfree; } // di->nb.notifier_call = bq2416x_charger_event; /*set gpio_174 to control CD pin to disable/enable bq24161 IC*/ gpio_request(ENABLE_BQ2416x_CHARGER, "gpio_174_cd"); /* set charger CD pin to low level and enable it to supply power normally*/ gpio_direction_output(ENABLE_BQ2416x_CHARGER, 0); ret = bq2416x_get_max_charge_voltage(di); if(!ret){ di->max_voltagemV = pdata->max_charger_voltagemV; } ret = bq2416x_get_max_charge_current(di); if(!ret){ di->max_currentmA = pdata->max_charger_currentmA; } di->max_cin_currentmA = IINLIM_1000; di->voltagemV = di->max_voltagemV; di->currentmA = ICHG_MIN_550 ; di->term_currentmA = ITERM_MIN_50; di->dppm_voltagemV = VINDPM_MIN_4200; di->cin_limit = IINLIM_500; di->safety_timer = TMR_X_9; di->enable_low_chg = DISABLE_LOW_CHG;/*set normally charge mode*/ di->enable_iterm = ENABLE_ITERM; /*enable charge current termination*/ di->supply_sel = SUPPLY_SEL_IN; di->factory_flag = 0; di->enable_ce = ENABLE_CHARGER; di->hz_mode = DIS_HIZ; di->cd_active = 0; INIT_DELAYED_WORK_DEFERRABLE(&di->bq2416x_charger_work, bq2416x_charger_work); wake_lock_init(&di->charger_wake_lock, WAKE_LOCK_SUSPEND, "charger_wake_lock"); //BLOCKING_INIT_NOTIFIER_HEAD(¬ifier_list); di->params.enable = 1; di->cfg_params = 1; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); bq2416x_config_safety_reg(di); ret = sysfs_create_group(&client->dev.kobj, &bq2416x_attr_group); if (ret) dev_dbg(&client->dev, "could not create sysfs files\n"); //twl6030_register_notifier(&di->nb, 1); INIT_WORK(&di->usb_work, bq2416x_usb_charger_work); di->nb_otg.notifier_call = bq2416x_usb_notifier_call; di->otg = otg_get_transceiver(); ret = otg_register_notifier(di->otg, &di->nb_otg); if (ret) dev_err(&client->dev, "otg register notifier failed %d\n", ret); plugin_stat = get_plugin_device_status(); if( PLUGIN_USB_CHARGER == plugin_stat){ di->event = USB_EVENT_VBUS; }else if (PLUGIN_AC_CHARGER == plugin_stat){ di->event = USB_EVENT_CHARGER; }else{ di->event = USB_EVENT_NONE; } schedule_work(&di->usb_work); return 0; err_kfree: kfree(di); return ret; }