static int __exit twl4030_bci_battery_remove(struct platform_device *pdev) { struct twl4030_bci_device_info *di = platform_get_drvdata(pdev); int irq; twl4030charger_ac_en(DISABLE); twl4030charger_usb_en(DISABLE); twl4030battery_hw_level_en(DISABLE); twl4030battery_hw_presence_en(DISABLE); irq = platform_get_irq(pdev, 0); free_irq(irq, di); irq = platform_get_irq(pdev, 1); free_irq(irq, NULL); flush_scheduled_work(); power_supply_unregister(&di->bat); /* LGE_CHANGE_S [[email protected]] 2010-3-12, android NOT need bk battery voltage*/ #if BK_BATT power_supply_unregister(&di->bk_bat); #endif //BK_BATT /* LGE_CHANGE_E [[email protected]] 2010-3-12, android NOT need bk battery voltage*/ platform_set_drvdata(pdev, NULL); kfree(di); return 0; }
static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; int status; #ifdef CONFIG_LOCKDEP local_irq_enable(); #endif status = twl4030_usb_linkstat(twl); if (status != USB_LINK_UNKNOWN) { twl4030charger_usb_en(status == USB_LINK_VBUS); if (status == USB_LINK_NONE) twl4030_phy_suspend(twl, 0); else twl4030_phy_resume(twl); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return IRQ_HANDLED; }
static irqreturn_t twl4030_usb_irq(int irq, void *_twl) { struct twl4030_usb *twl = _twl; int status; #ifdef CONFIG_LOCKDEP /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which * we don't want and can't tolerate. Although it might be * friendlier not to borrow this thread context... */ local_irq_enable(); #endif status = twl4030_usb_linkstat(twl); if (status != USB_LINK_UNKNOWN) { /* FIXME add a set_power() method so that B-devices can * configure the charger appropriately. It's not always * correct to consume VBUS power, and how much current to * consume is a function of the USB configuration chosen * by the host. * * REVISIT usb_gadget_vbus_connect(...) as needed, ditto * its disconnect() sibling, when changing to/from the * USB_LINK_VBUS state. musb_hdrc won't care until it * starts to handle softconnect right. */ twl4030charger_usb_en(status == USB_LINK_VBUS); if (status == USB_LINK_NONE) twl4030_phy_suspend(twl, 0); else twl4030_phy_resume(twl); } sysfs_notify(&twl->dev->kobj, NULL, "vbus"); return IRQ_HANDLED; }
static int __exit twl4030_bci_battery_remove(struct platform_device *pdev) { struct twl4030_bci_device_info *di = platform_get_drvdata(pdev); int irq; twl4030charger_ac_en(DISABLE); twl4030charger_usb_en(DISABLE); twl4030battery_hw_level_en(DISABLE); twl4030battery_hw_presence_en(DISABLE); irq = platform_get_irq(pdev, 0); free_irq(irq, di); irq = platform_get_irq(pdev, 1); free_irq(irq, NULL); flush_scheduled_work(); power_supply_unregister(&di->bat); power_supply_unregister(&di->bk_bat); platform_set_drvdata(pdev, NULL); kfree(di); return 0; }
static int __init twl4030_bci_battery_probe(struct platform_device *pdev) { struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; struct twl4030_bci_device_info *di; int irq; int ret; therm_tbl = pdata->battery_tmp_tbl; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; di->dev = &pdev->dev; // S[, 20120725, [email protected], Enable charging by fake mode. if (thermal_fakemode) di->temp_control = UNLIMITED_TEMP_VAL; else di->temp_control = 0; // E], 20120725, [email protected], Enable charging by fake mode. /* refer - com_android_server_BatteryService.cpp */ di->bat.name = "battery"; di->bat.supplied_to = twl4030_bci_supplied_to; di->bat.num_supplicants = ARRAY_SIZE(twl4030_bci_supplied_to); di->bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bat.properties = twl4030_bci_battery_props; di->bat.num_properties = ARRAY_SIZE(twl4030_bci_battery_props); di->bat.get_property = twl4030_bci_battery_get_property; di->bat.set_property = twl4030_bci_battery_set_property; // 20120725, [email protected], Enable charging by fake mode. di->bat.external_power_changed = NULL; di->bat.set_charged = NULL; /* LGE_CHANGE_S [[email protected]] 2010-3-12, android NOT need bk battery voltage*/ #if BK_BATT di->bk_bat.name = "twl4030_bci_bk_battery"; di->bk_bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bk_bat.properties = twl4030_bk_bci_battery_props; di->bk_bat.num_properties = ARRAY_SIZE(twl4030_bk_bci_battery_props); di->bk_bat.get_property = twl4030_bk_bci_battery_get_property; di->bk_bat.external_power_changed = NULL; di->bk_bat.set_charged = NULL; #endif //BK_BATT /* LGE_CHANGE_E [[email protected]] 2010-3-12, android NOT need bk battery voltage*/ di->ac.name = "ac"; di->ac.type = POWER_SUPPLY_TYPE_MAINS; //LGE_CHANGE [[email protected]] 2010-01-12 di->ac.properties = twl4030_ac_usb_bci_battery_props; di->ac.num_properties = ARRAY_SIZE(twl4030_ac_usb_bci_battery_props); di->ac.get_property = twl4030_ac_bci_battery_get_property; di->ac.external_power_changed = NULL; di->ac.set_charged = NULL; di->usb.name = "usb"; di->usb.type = POWER_SUPPLY_TYPE_USB; //LGE_CHANGE [[email protected]] 2010-01-12 di->usb.properties = twl4030_ac_usb_bci_battery_props; di->usb.num_properties = ARRAY_SIZE(twl4030_ac_usb_bci_battery_props); di->usb.get_property = twl4030_usb_bci_battery_get_property; di->usb.external_power_changed = NULL; di->usb.set_charged = NULL; twl4030charger_ac_en(DISABLE); twl4030charger_usb_en(DISABLE); twl4030battery_hw_level_en(DISABLE); twl4030battery_hw_presence_en(DISABLE); platform_set_drvdata(pdev, di); /* enabling GPCH09 for read back battery voltage */ ret = twl4030backupbatt_voltage_setup(); if (ret) goto voltage_setup_fail; /* REVISIT do we need to request both IRQs ?? */ /* request BCI interruption */ irq = platform_get_irq(pdev, 1); ret = request_irq(irq, twl4030battery_interrupt, 0, pdev->name, NULL); if (ret) { dev_dbg(&pdev->dev, "could not request irq %d, status %d\n", irq, ret); goto batt_irq_fail; } /* request Power interruption */ irq = platform_get_irq(pdev, 0); ret = request_irq(irq, twl4030charger_interrupt, 0, pdev->name, di); if (ret) { dev_dbg(&pdev->dev, "could not request irq %d, status %d\n", irq, ret); goto chg_irq_fail; } ret = power_supply_register(&pdev->dev, &di->bat); if (ret) { dev_dbg(&pdev->dev, "failed to register main battery\n"); goto batt_failed; } INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bci_monitor_work, twl4030_bci_battery_work); schedule_delayed_work(&di->twl4030_bci_monitor_work, 5 * HZ); //[email protected] add delay for secure ops /* LGE_CHANGE_S [[email protected]] 2010-3-12, android NOT need bk battery voltage*/ #if BK_BATT ret = power_supply_register(&pdev->dev, &di->bk_bat); if (ret) { dev_dbg(&pdev->dev, "failed to register backup battery\n"); goto bk_batt_failed; } INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bk_bci_monitor_work, twl4030_bk_bci_battery_work); schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, HZ*1); #endif //BK_BATT /* LGE_CHANGE_E [[email protected]] 2010-3-12, android NOT need bk battery voltage*/ ret = power_supply_register(&pdev->dev, &di->ac); if (ret) { dev_dbg(&pdev->dev, "failed to register battery ac online\n"); goto ac_online_failed; } ret = power_supply_register(&pdev->dev, &di->usb); if (ret) { dev_dbg(&pdev->dev, "failed to register battery usb online\n"); goto usb_online_failed; } ret = device_create_file(&pdev->dev, &dev_attr_pif); if (ret) { printk( "PIF detection register failed: Fail\n"); return ret; } ret = device_create_file(&pdev->dev, &dev_attr_gauge_if); if (ret) { printk( "chager off sysfs register failed: Fail\n"); return ret; } // Update First Battery Information refer_di = di; twl4030_bci_battery_read_status(di); set_battery_status(di); backup_battery_info(di); di->bk_voltage_uV = 3700; return 0; usb_online_failed: power_supply_unregister(&di->bat); ac_online_failed: power_supply_unregister(&di->bat); #if BK_BATT bk_batt_failed: #endif power_supply_unregister(&di->bat); batt_failed: free_irq(irq, di); chg_irq_fail: irq = platform_get_irq(pdev, 1); free_irq(irq, NULL); batt_irq_fail: voltage_setup_fail: twl4030charger_ac_en(DISABLE); twl4030charger_usb_en(DISABLE); twl4030battery_hw_level_en(DISABLE); twl4030battery_hw_presence_en(DISABLE); kfree(di); return ret; }
static int __init twl4030_bci_battery_probe(struct platform_device *pdev) { struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; struct twl4030_bci_device_info *di; int irq; int ret; therm_tbl = pdata->battery_tmp_tbl; bci_charging_current = pdata->twl4030_bci_charging_current; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; di->dev = &pdev->dev; di->bat.name = "twl4030_bci_battery"; di->bat.supplied_to = twl4030_bci_supplied_to; di->bat.num_supplicants = ARRAY_SIZE(twl4030_bci_supplied_to); di->bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bat.properties = twl4030_bci_battery_props; di->bat.num_properties = ARRAY_SIZE(twl4030_bci_battery_props); di->bat.get_property = twl4030_bci_battery_get_property; di->bat.external_power_changed = twl4030_bci_battery_external_power_changed; di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; di->bk_bat.name = "twl4030_bci_bk_battery"; di->bk_bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bk_bat.properties = twl4030_bk_bci_battery_props; di->bk_bat.num_properties = ARRAY_SIZE(twl4030_bk_bci_battery_props); di->bk_bat.get_property = twl4030_bk_bci_battery_get_property; di->bk_bat.external_power_changed = NULL; /* * Android expects a battery type POWER_SUPPLY_TYPE_USB * as a usb charger battery. This battery * and its "online" property are used to determine if the * usb cable is plugged in or not. */ di->usb_bat.name = "twl4030_bci_usb_src"; di->usb_bat.supplied_to = twl4030_bci_supplied_to; di->usb_bat.type = POWER_SUPPLY_TYPE_USB; di->usb_bat.properties = twl4030_usb_battery_props; di->usb_bat.num_properties = ARRAY_SIZE(twl4030_usb_battery_props); di->usb_bat.get_property = twl4030_usb_battery_get_property; di->usb_bat.external_power_changed = NULL; twl4030charger_ac_en(ENABLE); twl4030charger_usb_en(ENABLE); twl4030battery_hw_level_en(ENABLE); twl4030battery_hw_presence_en(ENABLE); platform_set_drvdata(pdev, di); /* settings for temperature sensing */ ret = twl4030battery_temp_setup(); if (ret) goto temp_setup_fail; /* enabling GPCH09 for read back battery voltage */ ret = twl4030backupbatt_voltage_setup(); if (ret) goto voltage_setup_fail; /* REVISIT do we need to request both IRQs ?? */ /* request BCI interruption */ irq = platform_get_irq(pdev, 1); ret = request_irq(irq, twl4030battery_interrupt, 0, pdev->name, NULL); if (ret) { dev_dbg(&pdev->dev, "could not request irq %d, status %d\n", irq, ret); goto batt_irq_fail; } /* request Power interruption */ irq = platform_get_irq(pdev, 0); ret = request_irq(irq, twl4030charger_interrupt, 0, pdev->name, di); if (ret) { dev_dbg(&pdev->dev, "could not request irq %d, status %d\n", irq, ret); goto chg_irq_fail; } ret = power_supply_register(&pdev->dev, &di->bat); if (ret) { dev_dbg(&pdev->dev, "failed to register main battery\n"); goto batt_failed; } INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bci_monitor_work, twl4030_bci_battery_work); schedule_delayed_work(&di->twl4030_bci_monitor_work, 0); ret = power_supply_register(&pdev->dev, &di->bk_bat); if (ret) { dev_dbg(&pdev->dev, "failed to register backup battery\n"); goto bk_batt_failed; } INIT_DELAYED_WORK_DEFERRABLE(&di->twl4030_bk_bci_monitor_work, twl4030_bk_bci_battery_work); schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500); ret = power_supply_register(&pdev->dev, &di->usb_bat); if (ret) { dev_dbg(&pdev->dev, "failed to register usb battery\n"); goto usb_batt_failed; } return 0; usb_batt_failed: power_supply_unregister(&di->bk_bat); bk_batt_failed: power_supply_unregister(&di->bat); batt_failed: free_irq(irq, di); chg_irq_fail: irq = platform_get_irq(pdev, 1); free_irq(irq, NULL); batt_irq_fail: voltage_setup_fail: temp_setup_fail: twl4030charger_ac_en(DISABLE); twl4030charger_usb_en(DISABLE); twl4030battery_hw_level_en(DISABLE); twl4030battery_hw_presence_en(DISABLE); kfree(di); return ret; }