static int pm860x_charger_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm860x_charger_info *info; int ret; int count; int i; int j; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; count = pdev->num_resources; for (i = 0, j = 0; i < count; i++) { info->irq[j] = platform_get_irq(pdev, i); if (info->irq[j] < 0) continue; j++; } info->irq_nums = j; info->chip = chip; info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion : chip->client; if (!info->i2c_8606) { dev_err(&pdev->dev, "Missed I2C address of 88PM8606!\n"); ret = -EINVAL; goto out; } info->dev = &pdev->dev; /* set init value for the case we are not using battery */ set_vchg_threshold(info, VCHG_NORMAL_LOW, VCHG_OVP_LOW); mutex_init(&info->lock); platform_set_drvdata(pdev, info); info->usb.name = "usb"; info->usb.type = POWER_SUPPLY_TYPE_USB; info->usb.supplied_to = pm860x_supplied_to; info->usb.num_supplicants = ARRAY_SIZE(pm860x_supplied_to); info->usb.properties = pm860x_usb_props; info->usb.num_properties = ARRAY_SIZE(pm860x_usb_props); info->usb.get_property = pm860x_usb_get_prop; ret = power_supply_register(&pdev->dev, &info->usb); if (ret) goto out; pm860x_init_charger(info); for (i = 0; i < ARRAY_SIZE(info->irq); i++) { ret = request_threaded_irq(info->irq[i], NULL, pm860x_irq_descs[i].handler, IRQF_ONESHOT, pm860x_irq_descs[i].name, info); if (ret < 0) { dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", info->irq[i], ret); goto out_irq; } } return 0; out_irq: power_supply_unregister(&info->usb); while (--i >= 0) free_irq(info->irq[i], info); out: return ret; }
static int __devinit SM5414_charger_probe( struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct sec_charger_info *charger; int ret = 0; dev_info(&client->dev, "%s: SM5414 Charger Driver Loading\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; charger = kzalloc(sizeof(*charger), GFP_KERNEL); if (!charger) return -ENOMEM; charger->client = client; if (client->dev.of_node) { void * pdata = kzalloc(sizeof(sec_battery_platform_data_t), GFP_KERNEL); if (!pdata) goto err_free1; charger->pdata = pdata; if (SM5414_charger_parse_dt(charger)) dev_err(&client->dev, "%s : Failed to get charger dt\n", __func__); } else charger->pdata = client->dev.platform_data; i2c_set_clientdata(client, charger); charger->siop_level = 100; charger->psy_chg.name = "SM5414"; charger->psy_chg.type = POWER_SUPPLY_TYPE_UNKNOWN; charger->psy_chg.get_property = SM5414_chg_get_property; charger->psy_chg.set_property = SM5414_chg_set_property; charger->psy_chg.properties = SM5414_charger_props; charger->psy_chg.num_properties = ARRAY_SIZE(SM5414_charger_props); charger->is_slow_charging = false; if (charger->pdata->chg_gpio_init) { if (!charger->pdata->chg_gpio_init()) { dev_err(&client->dev, "%s: Failed to Initialize GPIO\n", __func__); goto err_free; } } if (!SM5414_hal_chg_init(charger->client)) { dev_err(&client->dev, "%s: Failed to Initialize Charger\n", __func__); goto err_free; } ret = power_supply_register(&client->dev, &charger->psy_chg); if (ret) { dev_err(&client->dev, "%s: Failed to Register psy_chg\n", __func__); goto err_free; } if (charger->pdata->chg_irq) { INIT_DELAYED_WORK_DEFERRABLE( &charger->isr_work, SM5414_chg_isr_work); ret = request_threaded_irq(charger->pdata->chg_irq, NULL, SM5414_chg_irq_thread, charger->pdata->chg_irq_attr, "charger-irq", charger); if (ret) { dev_err(&client->dev, "%s: Failed to Reqeust IRQ\n", __func__); goto err_supply_unreg; } ret = enable_irq_wake(charger->pdata->chg_irq); if (ret < 0) dev_err(&client->dev, "%s: Failed to Enable Wakeup Source(%d)\n", __func__, ret); } ret = SM5414_chg_create_attrs(charger->psy_chg.dev); if (ret) { dev_err(&client->dev, "%s : Failed to create_attrs\n", __func__); goto err_req_irq; } dev_dbg(&client->dev, "%s: SM5414 Charger Driver Loaded\n", __func__); return 0; err_req_irq: if (charger->pdata->chg_irq) free_irq(charger->pdata->chg_irq, charger); err_supply_unreg: power_supply_unregister(&charger->psy_chg); err_free: kfree(charger->pdata); err_free1: kfree(charger); return ret; }
static __devinit int max8998_charger_probe(struct platform_device *pdev) { struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); struct chg_data *chg; struct i2c_client *i2c = iodev->i2c; int ret = 0; bat_info("%s : MAX8998 Charger Driver Loading\n", __func__); chg = kzalloc(sizeof(*chg), GFP_KERNEL); if (!chg) return -ENOMEM; chg->iodev = iodev; chg->pdata = pdata->charger; if (!chg->pdata || !chg->pdata->adc_table) { pr_err("%s : No platform data & adc_table supplied\n", __func__); ret = -EINVAL; goto err_bat_table; } chg->psy_bat.name = "battery"; chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY; chg->psy_bat.properties = max8998_battery_props; chg->psy_bat.num_properties = ARRAY_SIZE(max8998_battery_props); chg->psy_bat.get_property = s3c_bat_get_property; chg->psy_usb.name = "usb"; chg->psy_usb.type = POWER_SUPPLY_TYPE_USB; chg->psy_usb.supplied_to = supply_list; chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list); chg->psy_usb.properties = s3c_power_properties; chg->psy_usb.num_properties = ARRAY_SIZE(s3c_power_properties); chg->psy_usb.get_property = s3c_usb_get_property; chg->psy_ac.name = "ac"; chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS; chg->psy_ac.supplied_to = supply_list; chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list); chg->psy_ac.properties = s3c_power_properties; chg->psy_ac.num_properties = ARRAY_SIZE(s3c_power_properties); chg->psy_ac.get_property = s3c_ac_get_property; chg->present = 1; chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD; chg->bat_info.batt_is_full = false; chg->set_batt_full = false; chg->set_charge_timeout = false; chg->cable_status = CABLE_TYPE_NONE; chg->esafe = MAX8998_USB_VBUS_AP_ON; mutex_init(&chg->mutex); platform_set_drvdata(pdev, chg); ret = max8998_write_reg(i2c, MAX8998_REG_IRQM1, ~(MAX8998_IRQ_DCINR_MASK | MAX8998_IRQ_DCINF_MASK)); if (ret < 0) goto err_kfree; ret = max8998_write_reg(i2c, MAX8998_REG_IRQM2, 0xFF); if (ret < 0) goto err_kfree; #ifdef TOPOFF_CURRENT_CHECK ret = max8998_write_reg(i2c, MAX8998_REG_IRQM3, 0xFF); #else ret = max8998_write_reg(i2c, MAX8998_REG_IRQM3, ~MAX8998_IRQ_TOPOFFR_MASK); #endif if (ret < 0) goto err_kfree; ret = max8998_write_reg(i2c, MAX8998_REG_IRQM4, ~(MAX8998_IRQ_LOBAT2_MASK | MAX8998_IRQ_LOBAT1_MASK)); if (ret < 0) goto err_kfree; ret = max8998_update_reg(i2c, MAX8998_REG_ONOFF3, (1 << MAX8998_SHIFT_ENBATTMON), MAX8998_MASK_ENBATTMON); if (ret < 0) goto err_kfree; ret = max8998_update_reg(i2c, MAX8998_REG_LBCNFG1, 0x7, 0x37); //3.57V if (ret < 0) goto err_kfree; ret = max8998_update_reg(i2c, MAX8998_REG_LBCNFG2, 0x5, 0x37); //3.4V if (ret < 0) goto err_kfree; max8998_lowbat_config(chg, 0); wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present"); wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND, "max8998-charger"); wake_lock_init(&chg->lowbat_wake_lock, WAKE_LOCK_SUSPEND, "max8998-lowbat"); INIT_WORK(&chg->bat_work, s3c_bat_work); setup_timer(&chg->bat_work_timer, s3c_bat_work_timer_func, (unsigned long)chg); chg->monitor_wqueue = create_freezeable_workqueue(dev_name(&pdev->dev)); if (!chg->monitor_wqueue) { pr_err("%s : Failed to create freezeable workqueue\n", __func__); ret = -ENOMEM; goto err_wake_lock; } check_lpm_charging_mode(chg); /* init power supplier framework */ ret = power_supply_register(&pdev->dev, &chg->psy_bat); if (ret) { pr_err("%s : Failed to register power supply psy_bat\n", __func__); goto err_wqueue; } ret = power_supply_register(&pdev->dev, &chg->psy_usb); if (ret) { pr_err("%s : Failed to register power supply psy_usb\n", __func__); goto err_supply_unreg_bat; } ret = power_supply_register(&pdev->dev, &chg->psy_ac); if (ret) { pr_err("%s : Failed to register power supply psy_ac\n", __func__); goto err_supply_unreg_usb; } ret = request_threaded_irq(iodev->i2c->irq, NULL, max8998_int_work_func, IRQF_TRIGGER_FALLING, "max8998-charger", chg); if (ret) { pr_err("%s : Failed to request pmic irq\n", __func__); goto err_supply_unreg_ac; } ret = enable_irq_wake(iodev->i2c->irq); if (ret) { pr_err("%s : Failed to enable pmic irq wake\n", __func__); goto err_irq; } ret = s3c_bat_create_attrs(chg->psy_bat.dev); if (ret) { pr_err("%s : Failed to create_attrs\n", __func__); goto err_irq; } chg->callbacks.set_cable = max8998_set_cable; chg->callbacks.set_esafe = max8998_set_esafe; chg->callbacks.get_vdcin = max8998_get_vdcin; if (chg->pdata->register_callbacks) chg->pdata->register_callbacks(&chg->callbacks); wake_lock(&chg->work_wake_lock); queue_work(chg->monitor_wqueue, &chg->bat_work); return 0; err_irq: free_irq(iodev->i2c->irq, NULL); err_supply_unreg_ac: power_supply_unregister(&chg->psy_ac); err_supply_unreg_usb: power_supply_unregister(&chg->psy_usb); err_supply_unreg_bat: power_supply_unregister(&chg->psy_bat); err_wqueue: destroy_workqueue(chg->monitor_wqueue); cancel_work_sync(&chg->bat_work); err_wake_lock: wake_lock_destroy(&chg->work_wake_lock); wake_lock_destroy(&chg->vbus_wake_lock); wake_lock_destroy(&chg->lowbat_wake_lock); err_kfree: mutex_destroy(&chg->mutex); err_bat_table: kfree(chg); return ret; }
static int aml1216_battery_probe(struct platform_device *pdev) { struct aml1216_supply *supply; struct aml_charger *c; struct battery_curve *curve; struct power_supply_info *b; int ret; uint32_t i; AML1216_DBG("call %s in", __func__); g_aml1216_init = pdev->dev.platform_data; if (g_aml1216_init == NULL) { AML1216_ERR("%s, NO platform data\n", __func__); return -EINVAL; } aml1216_power_key = input_allocate_device(); if (!aml1216_power_key) { kfree(aml1216_power_key); return -ENODEV; } aml1216_power_key->name = pdev->name; aml1216_power_key->phys = "m1kbd/input2"; aml1216_power_key->id.bustype = BUS_HOST; aml1216_power_key->id.vendor = 0x0001; aml1216_power_key->id.product = 0x0001; aml1216_power_key->id.version = 0x0100; aml1216_power_key->open = NULL; aml1216_power_key->close = NULL; aml1216_power_key->dev.parent = &pdev->dev; set_bit(EV_KEY, aml1216_power_key->evbit); set_bit(EV_REL, aml1216_power_key->evbit); set_bit(KEY_POWER, aml1216_power_key->keybit); ret = input_register_device(aml1216_power_key); aml1216_battery = g_aml1216_init->board_battery; /* * initialize parameters for supply */ supply = kzalloc(sizeof(*supply), GFP_KERNEL); if (supply == NULL) return -ENOMEM; supply->battery_info = kzalloc(sizeof(struct power_supply_info), GFP_KERNEL); if (supply->battery_info == NULL) { kfree(supply); return -ENOMEM; } supply->master = pdev->dev.parent; g_aml1216_supply = supply; c = &supply->aml_charger; curve = aml1216_battery->pmu_bat_curve; if (aml1216_battery) { for (i = 1; i < 16; i++) { if (!c->ocv_empty && curve[i].discharge_percent > 0) c->ocv_empty = curve[i-1].ocv; if (!c->ocv_full && curve[i].discharge_percent == 100) c->ocv_full = curve[i].ocv; } supply->irq = aml1216_battery->pmu_irq_id; b = supply->battery_info; b->technology = aml1216_battery->pmu_battery_technology; b->voltage_max_design = aml1216_battery->pmu_init_chgvol; b->energy_full_design = aml1216_battery->pmu_battery_cap; b->voltage_min_design = c->ocv_empty * 1000; b->use_for_apm = 1; b->name = aml1216_battery->pmu_battery_name; } else AML1216_ERR(" NO BATTERY_PARAMETERS FOUND\n"); c->soft_limit_to99 = g_aml1216_init->soft_limit_to99; c->coulomb_type = COULOMB_BOTH; supply->charge_timeout_retry = g_aml1216_init->charge_timeout_retry; aml1216_update_state(c); #ifdef CONFIG_AMLOGIC_USB INIT_WORK(&aml1216_otg_work, aml1216_otg_work_fun); if (aml1216_charger_job.flag) { aml1216_usb_charger(NULL, aml1216_charger_job.value, NULL); aml1216_charger_job.flag = 0; } if (aml1216_otg_job.flag) { aml1216_otg_change(NULL, aml1216_otg_job.value, NULL); aml1216_otg_job.flag = 0; } #endif if (supply->irq) { INIT_WORK(&supply->irq_work, aml1216_irq_work_func); ret = request_irq(supply->irq, aml1216_irq_handler, IRQF_DISABLED | IRQF_SHARED, AML1216_IRQ_NAME, supply); if (ret) { AML1216_DBG("request irq failed, ret:%d, irq:%d\n", ret, supply->irq); } } ret = aml1216_first_init(supply); if (ret) goto err_charger_init; aml1216_battery_setup_psy(supply); ret = power_supply_register(&pdev->dev, &supply->batt); if (ret) goto err_ps_register; ret = power_supply_register(&pdev->dev, &supply->ac); if (ret) { power_supply_unregister(&supply->batt); goto err_ps_register; } ret = power_supply_register(&pdev->dev, &supply->usb); if (ret) { power_supply_unregister(&supply->ac); power_supply_unregister(&supply->batt); goto err_ps_register; } ret = aml1216_supply_create_attrs(&supply->batt); if (ret) return ret; platform_set_drvdata(pdev, supply); supply->interval = msecs_to_jiffies(AML1216_WORK_CYCLE); INIT_DELAYED_WORK(&supply->work, aml1216_charging_monitor); schedule_delayed_work(&supply->work, supply->interval); #ifdef CONFIG_HAS_EARLYSUSPEND aml1216_early_suspend.suspend = aml1216_earlysuspend; aml1216_early_suspend.resume = aml1216_lateresume; aml1216_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 2; aml1216_early_suspend.param = supply; register_early_suspend(&aml1216_early_suspend); wake_lock_init(&aml1216_lock, WAKE_LOCK_SUSPEND, "aml1216"); #endif if (aml1216_battery) power_supply_changed(&supply->batt); /* update battery status */ aml1216_dump_all_register(NULL); AML1216_DBG("call %s exit, ret:%d", __func__, ret); return ret; err_ps_register: free_irq(supply->irq, supply); cancel_delayed_work_sync(&supply->work); err_charger_init: kfree(supply->battery_info); kfree(supply); input_unregister_device(aml1216_power_key); kfree(aml1216_power_key); AML1216_DBG("call %s exit, ret:%d", __func__, ret); return ret; }
static int ulpmc_battery_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ulpmc_chip_info *chip; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int ret = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { dev_err(&client->dev, "SM bus doesn't support BYTE transactions\n"); return -EIO; } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_err(&client->dev, "SM bus doesn't support WORD transactions\n"); return -EIO; } /* check if the device is accessible */ ret = ulpmc_read_reg16(client, ULPMC_FG_REG_CNTL); if (ret < 0) { dev_err(&client->dev, "I2C read error:%s error:%d\n", __func__, ret); return -EIO; } else { dev_err(&client->dev, "FG control reg:%x\n", ret); } chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) { dev_err(&client->dev, "failed to allocate memory\n"); return -ENOMEM; } chip->client = client; chip->pdata = client->dev.platform_data; i2c_set_clientdata(client, chip); INIT_DELAYED_WORK(&chip->work, ulpmc_battery_monitor); mutex_init(&chip->lock); chip->bat.name = "byt-battery"; chip->bat.type = POWER_SUPPLY_TYPE_BATTERY; chip->bat.properties = ulpmc_battery_props; chip->bat.num_properties = ARRAY_SIZE(ulpmc_battery_props); chip->bat.get_property = ulpmc_get_battery_property; ret = power_supply_register(&client->dev, &chip->bat); if (ret) { dev_err(&client->dev, "failed to register battery: %d\n", ret); goto probe_failed_1; } chip->chrg.name = "byt-charger"; chip->chrg.type = POWER_SUPPLY_TYPE_MAINS; chip->chrg.properties = ulpmc_charger_properties; chip->chrg.num_properties = ARRAY_SIZE(ulpmc_charger_properties); chip->chrg.get_property = ulpmc_get_charger_property; ret = power_supply_register(&client->dev, &chip->chrg); if (ret) { dev_err(&client->dev, "failed to register charger: %d\n", ret); goto probe_failed_2; } /* get extcon device */ chip->edev = extcon_get_extcon_dev(chip->pdata->extcon_devname); if (!chip->edev) { dev_err(&client->dev, "failed to get extcon device\n"); } else { chip->nb.notifier_call = &ulpmc_extcon_callback; ret = extcon_register_notifier(chip->edev, &chip->nb); if (ret) dev_err(&client->dev, "failed to register extcon notifier:%d\n", ret); } /* get irq and register */ ulpmc_init_irq(chip); /* schedule status monitoring worker */ schedule_delayed_work(&chip->work, STATUS_MON_JIFFIES); return 0; probe_failed_2: power_supply_unregister(&chip->bat); probe_failed_1: kfree(chip); return ret; }
static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct max17047_fuelgauge_data *fg_data; struct max17047_platform_data *pdata = client->dev.platform_data; int ret = -ENODEV; int rawsoc, firstsoc; pr_info("%s: fuelgauge init\n", __func__); if (!pdata) { pr_err("%s: no platform data\n", __func__); return -ENODEV; } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; fg_data = kzalloc(sizeof(struct max17047_fuelgauge_data), GFP_KERNEL); if (!fg_data) return -ENOMEM; fg_data->client = client; fg_data->pdata = pdata; i2c_set_clientdata(client, fg_data); mutex_init(&fg_data->irq_lock); wake_lock_init(&fg_data->update_wake_lock, WAKE_LOCK_SUSPEND, "fuel-update"); #ifdef USE_TRIM_ERROR_DETECTION /* trim error detect */ fg_data->trim_err = max17047_detect_trim_error(fg_data); #endif /* Initialize full_soc, set this before fisrt SOC reading */ fg_data->full_soc = FULL_SOC_DEFAULT; /* first full_soc update */ rawsoc = max17047_get_rawsoc(fg_data->client); if (rawsoc > FULL_SOC_DEFAULT) max17047_adjust_fullsoc(client); firstsoc = max17047_get_soc(client); pr_info("%s: rsoc=%d, fsoc=%d, soc=%d\n", __func__, rawsoc, fg_data->full_soc, firstsoc); if (fg_data->pdata->psy_name) fg_data->fuelgauge.name = fg_data->pdata->psy_name; else fg_data->fuelgauge.name = "max17047-fuelgauge"; #if defined(CONFIG_MACH_GC1) fg_data->prev_status = POWER_SUPPLY_STATUS_DISCHARGING; #endif fg_data->fuelgauge.type = POWER_SUPPLY_TYPE_UNKNOWN; fg_data->fuelgauge.properties = max17047_fuelgauge_props; fg_data->fuelgauge.num_properties = ARRAY_SIZE(max17047_fuelgauge_props); fg_data->fuelgauge.get_property = max17047_get_property; fg_data->fuelgauge.set_property = max17047_set_property; ret = power_supply_register(&client->dev, &fg_data->fuelgauge); if (ret) { pr_err("%s: failed power supply register\n", __func__); goto err_psy_reg_fg; } /* Initialize fuelgauge registers */ max17047_reg_init(fg_data); /* Initialize fuelgauge alert */ max17047_alert_init(fg_data); INIT_DELAYED_WORK_DEFERRABLE(&fg_data->update_work, max17047_update_work); /* Request IRQ */ fg_data->irq = gpio_to_irq(fg_data->pdata->irq_gpio); ret = gpio_request(fg_data->pdata->irq_gpio, "fuelgauge-irq"); if (ret) { pr_err("%s: failed requesting gpio %d\n", __func__, fg_data->pdata->irq_gpio); goto err_irq; } gpio_direction_input(fg_data->pdata->irq_gpio); gpio_free(fg_data->pdata->irq_gpio); ret = request_threaded_irq(fg_data->irq, NULL, max17047_fuelgauge_isr, IRQF_TRIGGER_FALLING, "max17047-alert", fg_data); if (ret < 0) { pr_err("%s: fail to request max17047 irq: %d: %d\n", __func__, fg_data->irq, ret); goto err_irq; } ret = enable_irq_wake(fg_data->irq); if (ret < 0) { pr_err("%s: failed enable irq wake %d\n", __func__, fg_data->irq); goto err_enable_irq; } #ifdef DEBUG_FUELGAUGE_POLLING INIT_DELAYED_WORK_DEFERRABLE(&fg_data->polling_work, max17047_polling_work); schedule_delayed_work(&fg_data->polling_work, 0); #else max17047_test_read(fg_data); #endif pr_info("%s: probe complete\n", __func__); #if defined(CONFIG_TARGET_LOCALE_KOR) #ifdef CONFIG_DEBUG_FS fg_data->fg_debugfs_dir = debugfs_create_dir("fg_debug", NULL); if (fg_data->fg_debugfs_dir) { if (!debugfs_create_file("max17047_regs", 0644, fg_data->fg_debugfs_dir, fg_data, &max17047_debugfs_fops)) pr_err("%s : debugfs_create_file, error\n", __func__); if (!debugfs_create_file("default_data", 0644, fg_data->fg_debugfs_dir, fg_data, &max17047_debugfs_fops2)) pr_err("%s : debugfs_create_file2, error\n", __func__); } else pr_err("%s : debugfs_create_dir, error\n", __func__); #endif #endif return 0; err_enable_irq: free_irq(fg_data->irq, fg_data); err_irq: power_supply_unregister(&fg_data->fuelgauge); err_psy_reg_fg: wake_lock_destroy(&fg_data->update_wake_lock); mutex_destroy(&fg_data->irq_lock); kfree(fg_data); return ret; }
static int __devinit sec_fuelgauge_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct sec_fuelgauge_info *fuelgauge; int ret = 0; union power_supply_propval raw_soc_val; dev_dbg(&client->dev, "%s: SEC Fuelgauge Driver Loading\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; fuelgauge = kzalloc(sizeof(*fuelgauge), GFP_KERNEL); if (!fuelgauge) return -ENOMEM; mutex_init(&fuelgauge->fg_lock); fuelgauge->client = client; fuelgauge->pdata = client->dev.platform_data; i2c_set_clientdata(client, fuelgauge); fuelgauge->psy_fg.name = "sec-fuelgauge"; fuelgauge->psy_fg.type = POWER_SUPPLY_TYPE_UNKNOWN; fuelgauge->psy_fg.get_property = sec_fg_get_property; fuelgauge->psy_fg.set_property = sec_fg_set_property; fuelgauge->psy_fg.properties = sec_fuelgauge_props; fuelgauge->psy_fg.num_properties = ARRAY_SIZE(sec_fuelgauge_props); fuelgauge->capacity_max = fuelgauge->pdata->capacity_max; raw_soc_val.intval = SEC_FUELGAUGE_CAPACITY_TYPE_RAW; sec_hal_fg_get_property(fuelgauge->client, POWER_SUPPLY_PROP_CAPACITY, &raw_soc_val); raw_soc_val.intval /= 10; fuelgauge->is_reset = false; if(raw_soc_val.intval > fuelgauge->pdata->capacity_max) sec_fg_calculate_dynamic_scale(fuelgauge); if (!fuelgauge->pdata->fg_gpio_init()) { dev_err(&client->dev, "%s: Failed to Initialize GPIO\n", __func__); goto err_free; } if (!sec_hal_fg_init(fuelgauge->client)) { dev_err(&client->dev, "%s: Failed to Initialize Fuelgauge\n", __func__); goto err_free; } ret = power_supply_register(&client->dev, &fuelgauge->psy_fg); if (ret) { dev_err(&client->dev, "%s: Failed to Register psy_fg\n", __func__); goto err_free; } if (fuelgauge->pdata->fg_irq) { INIT_DELAYED_WORK_DEFERRABLE( &fuelgauge->isr_work, sec_fg_isr_work); ret = request_threaded_irq(fuelgauge->pdata->fg_irq, NULL, sec_fg_irq_thread, fuelgauge->pdata->fg_irq_attr, "fuelgauge-irq", fuelgauge); if (ret) { dev_err(&client->dev, "%s: Failed to Reqeust IRQ\n", __func__); goto err_supply_unreg; } ret = enable_irq_wake(fuelgauge->pdata->fg_irq); if (ret < 0) dev_err(&client->dev, "%s: Failed to Enable Wakeup Source(%d)\n", __func__, ret); } fuelgauge->is_fuel_alerted = false; if (fuelgauge->pdata->fuel_alert_soc >= 0) { if (sec_hal_fg_fuelalert_init(fuelgauge->client, fuelgauge->pdata->fuel_alert_soc)) wake_lock_init(&fuelgauge->fuel_alert_wake_lock, WAKE_LOCK_SUSPEND, "fuel_alerted"); else { dev_err(&client->dev, "%s: Failed to Initialize Fuel-alert\n", __func__); goto err_irq; } } fuelgauge->initial_update_of_soc = true; ret = sec_fg_create_attrs(fuelgauge->psy_fg.dev); if (ret) { dev_err(&client->dev, "%s : Failed to create_attrs\n", __func__); goto err_irq; } dev_dbg(&client->dev, "%s: SEC Fuelgauge Driver Loaded\n", __func__); return 0; err_irq: if (fuelgauge->pdata->fg_irq) free_irq(fuelgauge->pdata->fg_irq, fuelgauge); wake_lock_destroy(&fuelgauge->fuel_alert_wake_lock); err_supply_unreg: power_supply_unregister(&fuelgauge->psy_fg); err_free: mutex_destroy(&fuelgauge->fg_lock); kfree(fuelgauge); return ret; }
/* * imx6_usb_remove_charger - remove a USB charger * @charger: the charger to be removed * * Unregister the chargers power supply. */ void imx6_usb_remove_charger(struct usb_charger *charger) { power_supply_unregister(&charger->psy); }
static int __init twl4030_bci_probe(struct platform_device *pdev) { struct twl4030_bci *bci; struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; 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; bci->usb_reg = regulator_get(bci->dev, "bci3v1"); 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, IRQF_ONESHOT, 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, IRQF_ONESHOT, 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 = usb_get_phy(USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(bci->transceiver)) { bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; usb_register_notifier(bci->transceiver, &bci->usb_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); twl4030_charger_enable_backup(pdata->bb_uvolt, pdata->bb_uamp); return 0; fail_unmask_interrupts: if (!IS_ERR_OR_NULL(bci->transceiver)) { usb_unregister_notifier(bci->transceiver, &bci->usb_nb); usb_put_phy(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 __init twl6030_bci_battery_probe(struct platform_device *pdev) { struct twl6030_bci_platform_data *pdata = pdev->dev.platform_data; struct twl6030_bci_device_info *di; int irq; int ret; u8 rd_reg = 0, controller_stat = 0; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; if (!pdata) { dev_dbg(&pdev->dev, "platform_data not available\n"); ret = -EINVAL; goto err_pdata; } di->dev = &pdev->dev; di->bat.name = "twl6030_bci_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.external_power_changed = twl6030_bci_battery_external_power_changed; di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; di->bk_bat.name = "twl6030_bci_bk_battery"; di->bk_bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bk_bat.properties = twl6030_bk_bci_battery_props; di->bk_bat.num_properties = ARRAY_SIZE(twl6030_bk_bci_battery_props); di->bk_bat.get_property = twl6030_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 = "twl6030_bci_usb_battery"; di->usb_bat.supplied_to = twl6030_bci_supplied_to; di->usb_bat.type = POWER_SUPPLY_TYPE_USB; di->usb_bat.properties = twl6030_usb_battery_props; di->usb_bat.num_properties = ARRAY_SIZE(twl6030_usb_battery_props); di->usb_bat.get_property = twl6030_usb_battery_get_property; di->usb_bat.external_power_changed = NULL; di->vac_priority = 1; platform_set_drvdata(pdev, di); /* settings for temperature sensing */ ret = twl6030battery_temp_setup(); if (ret) goto temp_setup_fail; /* request charger fault interruption */ irq = platform_get_irq(pdev, 1); ret = request_irq(irq, twl6030charger_fault_interrupt, 0, "twl_bci_fault", di); if (ret) { dev_dbg(&pdev->dev, "could not request irq %d, status %d\n", irq, ret); goto batt_irq_fail; } /* request charger ctrl interruption */ irq = platform_get_irq(pdev, 0); ret = request_irq(irq, twl6030charger_ctrl_interrupt, 0, "twl_bci_ctrl", di); if (ret) { dev_dbg(&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 = 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->twl6030_bci_monitor_work, twl6030_bci_battery_work); schedule_delayed_work(&di->twl6030_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; } ret = power_supply_register(&pdev->dev, &di->usb_bat); if (ret) { dev_dbg(&pdev->dev, "failed to register usb source\n"); goto usb_batt_failed; } INIT_DELAYED_WORK_DEFERRABLE(&di->twl6030_bk_bci_monitor_work, twl6030_bk_bci_battery_work); schedule_delayed_work(&di->twl6030_bk_bci_monitor_work, 500); twl_i2c_read_u8(TWL6030_MODULE_ID0, &rd_reg, REG_MISC1); rd_reg = rd_reg | VAC_MEAS | VBAT_MEAS | BB_MEAS; twl_i2c_write_u8(TWL6030_MODULE_ID0, rd_reg, REG_MISC1); twl_i2c_read_u8(TWL6030_MODULE_ID1, &rd_reg, REG_TOGGLE1); rd_reg = rd_reg | ENABLE_FUELGUAGE; twl_i2c_write_u8(TWL6030_MODULE_ID1, rd_reg, REG_TOGGLE1); twl_i2c_read_u8(TWL_MODULE_MADC, &rd_reg, TWL6030_GPADC_CTRL); rd_reg = rd_reg | ENABLE_ISOURCE; twl_i2c_write_u8(TWL_MODULE_MADC, rd_reg, TWL6030_GPADC_CTRL); twl_i2c_read_u8(TWL_MODULE_USB, &rd_reg, REG_USB_VBUS_CTRL_SET); rd_reg = rd_reg | VBUS_MEAS; twl_i2c_write_u8(TWL_MODULE_USB, rd_reg, REG_USB_VBUS_CTRL_SET); twl_i2c_read_u8(TWL_MODULE_USB, &rd_reg, REG_USB_ID_CTRL_SET); rd_reg = rd_reg | ID_MEAS; twl_i2c_write_u8(TWL_MODULE_USB, rd_reg, REG_USB_ID_CTRL_SET); /* initialize for USB charging */ twl_i2c_write_u8(TWL6030_MODULE_CHARGER, MBAT_TEMP, CONTROLLER_INT_MASK); twl_i2c_write_u8(TWL6030_MODULE_CHARGER, MASK_MCHARGERUSB_THMREG, CHARGERUSB_INT_MASK); twl_i2c_write_u8(TWL6030_MODULE_CHARGER, CHARGERUSB_VOREG_4P2, CHARGERUSB_VOREG); twl_i2c_write_u8(TWL6030_MODULE_CHARGER, CHARGERUSB_VICHRG_1500, CHARGERUSB_VICHRG); twl_i2c_write_u8(TWL6030_MODULE_CHARGER, CHARGERUSB_CTRL2_VITERM_100, CHARGERUSB_CTRL2); twl_i2c_write_u8(TWL6030_MODULE_CHARGER, CHARGERUSB_CIN_LIMIT_NONE, CHARGERUSB_CINLIMIT); twl_i2c_write_u8(TWL6030_MODULE_CHARGER, CHARGERUSB_CTRLLIMIT2_1500, CHARGERUSB_CTRLLIMIT2); twl_i2c_write_u8(TWL6030_MODULE_BQ, 0xa0, REG_SAFETY_LIMIT); twl_i2c_read_u8(TWL6030_MODULE_CHARGER, &controller_stat, CONTROLLER_STAT1); if (controller_stat & VBUS_DET) twl6030_start_usb_charger(); if (controller_stat & VAC_DET) twl6030_start_ac_charger(); 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); err_pdata: batt_irq_fail: temp_setup_fail: kfree(di); return ret; }
static __devinit int max8903_probe(struct platform_device *pdev) { struct max8903_platform_data *pdata = dev_get_platdata(&pdev->dev); struct max8903_info *info; int ret; dev_info(&pdev->dev, "%s : MAX8903 Charger Driver Loading\n", __func__); info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; platform_set_drvdata(pdev, info); info->dev = &pdev->dev; info->pdata = pdata; info->psy_bat.name = "max8903-charger", info->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY, info->psy_bat.properties = max8903_battery_props, info->psy_bat.num_properties = ARRAY_SIZE(max8903_battery_props), info->psy_bat.get_property = max8903_get_property, info->psy_bat.set_property = max8903_set_property, ret = power_supply_register(&pdev->dev, &info->psy_bat); if (ret) { dev_err(info->dev, "Failed to register psy_bat\n"); goto err_kfree; } if (pdata->cfg_gpio) { ret = pdata->cfg_gpio(); if (ret) { dev_err(info->dev, "failed to configure GPIO\n"); goto err_kfree; } } if (gpio_is_valid(pdata->gpio_curr_adj)) { if (!pdata->gpio_curr_adj) { dev_err(info->dev, "gpio_curr_adj defined as 0\n"); WARN_ON(!pdata->gpio_curr_adj); ret = -EIO; goto err_kfree; } gpio_request(pdata->gpio_curr_adj, "MAX8903 gpio_curr_adj"); } if (gpio_is_valid(pdata->gpio_ta_en)) { if (!pdata->gpio_ta_en) { dev_err(info->dev, "gpio_ta_en defined as 0\n"); WARN_ON(!pdata->gpio_ta_en); ret = -EIO; goto err_kfree; } gpio_request(pdata->gpio_ta_en, "MAX8903 gpio_ta_en"); } if (gpio_is_valid(pdata->gpio_ta_nconnected)) { if (!pdata->gpio_ta_nconnected) { dev_err(info->dev, "gpio_ta_nconnected defined as 0\n"); WARN_ON(!pdata->gpio_ta_nconnected); ret = -EIO; goto err_kfree; } gpio_request(pdata->gpio_ta_nconnected, "MAX8903 TA_nCONNECTED"); } if (gpio_is_valid(pdata->gpio_ta_nchg)) { if (!pdata->gpio_ta_nchg) { dev_err(info->dev, "gpio_ta_nchg defined as 0\n"); WARN_ON(!pdata->gpio_ta_nchg); ret = -EIO; goto err_kfree; } gpio_request(pdata->gpio_ta_nchg, "MAX8903 gpio_ta_nchg"); } #if 0 info->irq_chg_ing = gpio_to_irq(pdata->gpio_chg_ing); ret = request_threaded_irq(info->irq_chg_ing, NULL, max8922_chg_ing_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "chg_ing", info); if (ret) dev_err(&pdev->dev, "%s: fail to request chg_ing IRQ:" " %d: %d\n", __func__, info->irq_chg_ing, ret); #endif return 0; err_kfree: power_supply_unregister(&info->psy_bat); platform_set_drvdata(pdev, NULL); kfree(info); return ret; }
static int __devinit tosa_bat_probe(struct platform_device *dev) { int ret; int i; if (!machine_is_tosa()) return -ENODEV; for (i = 0; i < ARRAY_SIZE(gpios); i++) { ret = gpio_request(gpios[i].gpio, gpios[i].name); if (ret) { i--; goto err_gpio; } if (gpios[i].output) ret = gpio_direction_output(gpios[i].gpio, gpios[i].value); else ret = gpio_direction_input(gpios[i].gpio); if (ret) goto err_gpio; } mutex_init(&tosa_bat_main.work_lock); mutex_init(&tosa_bat_jacket.work_lock); INIT_WORK(&bat_work, tosa_bat_work); ret = power_supply_register(&dev->dev, &tosa_bat_main.psy); if (ret) goto err_psy_reg_main; ret = power_supply_register(&dev->dev, &tosa_bat_jacket.psy); if (ret) goto err_psy_reg_jacket; ret = power_supply_register(&dev->dev, &tosa_bat_bu.psy); if (ret) goto err_psy_reg_bu; ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "main full", &tosa_bat_main); if (ret) goto err_req_main; ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "jacket full", &tosa_bat_jacket); if (ret) goto err_req_jacket; ret = request_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "jacket detect", &tosa_bat_jacket); if (!ret) { schedule_work(&bat_work); return 0; } free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); err_req_jacket: free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); err_req_main: power_supply_unregister(&tosa_bat_bu.psy); err_psy_reg_bu: power_supply_unregister(&tosa_bat_jacket.psy); err_psy_reg_jacket: power_supply_unregister(&tosa_bat_main.psy); err_psy_reg_main: /* see comment in tosa_bat_remove */ cancel_work_sync(&bat_work); i--; err_gpio: for (; i >= 0; i--) gpio_free(gpios[i].gpio); return ret; }
static int pmic_battery_probe(struct platform_device *pdev) { int retval = 0; struct mc13892_dev_info *di; pmic_event_callback_t bat_event_callback; pmic_version_t pmic_version; /* Only apply battery driver for MC13892 V2.0 due to ENGR108085 */ pmic_version = pmic_get_version(); if (pmic_version.revision < 20) { pr_debug("Battery driver is only applied for MC13892 V2.0\n"); return -1; } if (machine_is_mx50_arm2()) { pr_debug("mc13892 charger is not used for this platform\n"); return -1; } di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) { retval = -ENOMEM; goto di_alloc_failed; } platform_set_drvdata(pdev, di); di->charger.name = "mc13892_charger"; di->charger.type = POWER_SUPPLY_TYPE_MAINS; di->charger.properties = mc13892_charger_props; di->charger.num_properties = ARRAY_SIZE(mc13892_charger_props); di->charger.get_property = mc13892_charger_get_property; retval = power_supply_register(&pdev->dev, &di->charger); if (retval) { dev_err(di->dev, "failed to register charger\n"); goto charger_failed; } INIT_DELAYED_WORK(&chg_work, chg_thread); chg_wq = create_singlethread_workqueue("mxc_chg"); if (!chg_wq) { retval = -ESRCH; goto workqueue_failed; } INIT_DELAYED_WORK(&di->monitor_work, mc13892_battery_work); di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); if (!di->monitor_wqueue) { retval = -ESRCH; goto workqueue_failed; } queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 10); di->dev = &pdev->dev; di->bat.name = "mc13892_bat"; di->bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bat.properties = mc13892_battery_props; di->bat.num_properties = ARRAY_SIZE(mc13892_battery_props); di->bat.get_property = mc13892_battery_get_property; di->bat.use_for_apm = 1; di->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; retval = power_supply_register(&pdev->dev, &di->bat); if (retval) { dev_err(di->dev, "failed to register battery\n"); goto batt_failed; } bat_event_callback.func = charger_online_event_callback; bat_event_callback.param = (void *) di; pmic_event_subscribe(EVENT_CHGDETI, bat_event_callback); retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr); if (retval) { printk(KERN_ERR "Battery: Unable to register sysdev entry for Battery"); goto workqueue_failed; } chg_wa_is_active = 1; chg_wa_timer = 0; disable_chg_timer = 0; pmic_stop_coulomb_counter(); pmic_calibrate_coulomb_counter(); goto success; workqueue_failed: power_supply_unregister(&di->charger); charger_failed: power_supply_unregister(&di->bat); batt_failed: kfree(di); di_alloc_failed: success: dev_dbg(di->dev, "%s battery probed!\n", __func__); return retval; 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; 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; }
static __devinit int max8971_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct max8971_chip *chip; int ret; dev_info(&client->dev, "%s..\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { dev_err(&client->dev, "%s i2c check failed..\n", __func__); return -EIO; } chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) { dev_err(&client->dev, "Memory allocation failed\n"); return -ENOMEM; } /* */ max8971_chg = chip; /* */ #ifdef MAX8971_TOPOFF_WORKAROUND dev_info(&client->dev, "Starting delayed workd queue..\n"); INIT_DELAYED_WORK(&chip->topoff_work, max8971_topoff_work); //printk(KERN_DEBUG "%s(%d)\n", __func__, __LINE__); chip->start_topoff_work = 0; chip->prev_chg_dtl = 0; #endif chip->client = client; chip->pdata = client->dev.platform_data; i2c_set_clientdata(client, chip); if(chip->pdata->gpio_init) chip->pdata->gpio_init(); else printk("max8971_probe : Failed to gpio init\n"); chip->charger.name = "charger"; chip->charger.type = POWER_SUPPLY_TYPE_BATTERY; chip->charger.properties = max8971_charger_props; chip->charger.num_properties = ARRAY_SIZE(max8971_charger_props); chip->charger.get_property = max8971_charger_get_property; chip->charger.set_property = max8971_charger_set_property; ret = power_supply_register(&client->dev, &chip->charger); if (ret) { dev_err(&client->dev, "power supply register failed : %d\n", ret); goto err_power_supply_register; } //INIT_WORK(&max8971_wq, max8971_charger_wq); //kkk_test INIT_DELAYED_WORK_DEFERRABLE(&chip->monitor_work, lge_charger_setting_work); //schedule_delayed_work(&chip->monitor_work, 0); if(is_tegra_batteryexistWhenBoot() == 1) { ret = request_threaded_irq(client->irq, NULL, max8971_charger_wq, IRQF_ONESHOT | IRQF_TRIGGER_LOW, client->name, chip); if (ret < 0) { printk(KERN_INFO "[max8971_probe] MAX8971_IRQB_GPIO set up failed!\n"); free_irq(client->irq, &client->dev); return -ENOSYS; } } /* chip->chg_online = 0; ret = max8971_read_reg(chip->client, MAX8971_REG_CHG_STAT); if (ret >= 0) { chip->chg_online = (ret & MAX8971_DCUVP_MASK) ? 0 : 1; if (chip->chg_online) { // Set IRQ MASK register max8971_write_reg(chip->client, MAX8971_REG_CHGINT_MASK, chip->pdata->int_mask); max8971_set_reg(chip, 1); } } else { dev_err(&client->dev, "i2c reading err : %d\n", ret); goto err; } */ chip->chgcc_forced = 0; chip->dcilmt_forced = 60; ret = device_create_file(&client->dev, &dev_attr_chgcc_ta); if (ret < 0) { printk("device_create_file(chgcc_ta) error!\n"); goto err; } ret = device_create_file(&client->dev, &dev_attr_chgcc_forced); if (ret < 0) { printk("device_create_file(chgcc_forced) error!\n"); goto err_chgcc_forced; } ret = device_create_file(&client->dev, &dev_attr_dcilmt_forced); if (ret < 0) { printk("device_create_file(dcilmt_forced) error!\n"); goto err_dcilmt_forced; } dev_info(&client->dev, "%s finish...\n", __func__); return 0; err_dcilmt_forced: device_remove_file(&client->dev, &dev_attr_chgcc_forced); err_chgcc_forced: device_remove_file(&client->dev, &dev_attr_chgcc_ta); err: free_irq(client->irq, chip); err_irq_request: err_gpio_register_2: gpio_free(client->irq); err_gpio_register_1: power_supply_unregister(&chip->charger); err_power_supply_register: i2c_set_clientdata(client, NULL); kfree(chip); return ret; }
static int __devinit tosa_bat_probe(struct platform_device *dev) { int ret; if (!machine_is_tosa()) return -ENODEV; ret = gpio_request_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios)); if (ret) return ret; mutex_init(&tosa_bat_main.work_lock); mutex_init(&tosa_bat_jacket.work_lock); INIT_WORK(&bat_work, tosa_bat_work); ret = power_supply_register(&dev->dev, &tosa_bat_main.psy); if (ret) goto err_psy_reg_main; ret = power_supply_register(&dev->dev, &tosa_bat_jacket.psy); if (ret) goto err_psy_reg_jacket; ret = power_supply_register(&dev->dev, &tosa_bat_bu.psy); if (ret) goto err_psy_reg_bu; ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "main full", &tosa_bat_main); if (ret) goto err_req_main; ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "jacket full", &tosa_bat_jacket); if (ret) goto err_req_jacket; ret = request_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "jacket detect", &tosa_bat_jacket); if (!ret) { schedule_work(&bat_work); return 0; } free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket); err_req_jacket: free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main); err_req_main: power_supply_unregister(&tosa_bat_bu.psy); err_psy_reg_bu: power_supply_unregister(&tosa_bat_jacket.psy); err_psy_reg_jacket: power_supply_unregister(&tosa_bat_main.psy); err_psy_reg_main: /* see comment in tosa_bat_remove */ cancel_work_sync(&bat_work); gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios)); return ret; }
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(); update_charger(); 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); setup_timer(&supply_timer, supply_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); } #ifdef CONFIG_USB_OTG_UTILS transceiver = usb_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; } #endif 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; } } #ifdef CONFIG_USB_OTG_UTILS if (transceiver && pdata->use_otg_notifier) { otg_nb.notifier_call = otg_handle_notification; ret = usb_register_notifier(transceiver, &otg_nb); if (ret) { dev_err(dev, "failure to register otg notifier\n"); goto otg_reg_notifier_failed; } polling = 0; } #endif 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; #ifdef CONFIG_USB_OTG_UTILS otg_reg_notifier_failed: if (pdata->is_usb_online && usb_irq) free_irq(usb_irq->start, &pda_psy_usb); #endif 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); #ifdef CONFIG_USB_OTG_UTILS if (transceiver) usb_put_transceiver(transceiver); #endif 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 olpc_battery_probe(struct platform_device *pdev) { int ret; uint8_t status; /* * We've seen a number of EC protocol changes; this driver requires * the latest EC protocol, supported by 0x44 and above. */ if (olpc_platform_info.ecver < 0x44) { printk(KERN_NOTICE "OLPC EC version 0x%02x too old for " "battery driver.\n", olpc_platform_info.ecver); return -ENXIO; } ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1); if (ret) return ret; /* Ignore the status. It doesn't actually matter */ olpc_ac = power_supply_register(&pdev->dev, &olpc_ac_desc, NULL); if (IS_ERR(olpc_ac)) return PTR_ERR(olpc_ac); if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */ olpc_bat_desc.properties = olpc_xo15_bat_props; olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); } else { /* XO-1 */ olpc_bat_desc.properties = olpc_xo1_bat_props; olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); } olpc_bat = power_supply_register(&pdev->dev, &olpc_bat_desc, NULL); if (IS_ERR(olpc_bat)) { ret = PTR_ERR(olpc_bat); goto battery_failed; } ret = device_create_bin_file(&olpc_bat->dev, &olpc_bat_eeprom); if (ret) goto eeprom_failed; ret = device_create_file(&olpc_bat->dev, &olpc_bat_error); if (ret) goto error_failed; if (olpc_ec_wakeup_available()) { device_set_wakeup_capable(&olpc_ac->dev, true); device_set_wakeup_capable(&olpc_bat->dev, true); } return 0; error_failed: device_remove_bin_file(&olpc_bat->dev, &olpc_bat_eeprom); eeprom_failed: power_supply_unregister(olpc_bat); battery_failed: power_supply_unregister(olpc_ac); return ret; }
static int __devinit sec_battery_probe(struct platform_device *pdev) { sec_battery_platform_data_t *pdata = dev_get_platdata(&pdev->dev); struct sec_battery_info *battery; int irq = 0; int ret = 0; pr_debug("%s: SEC Battery Driver Loading\n", __func__); battery = kzalloc(sizeof(*battery), GFP_KERNEL); if (!battery) return -ENOMEM; platform_set_drvdata(pdev, battery); battery->dev = &pdev->dev; battery->pdata = pdata; mutex_init(&battery->adclock); pr_debug("%s: ADC init\n", __func__); adc_init(pdev, pdata, pdata->cable_check_adc_channel); adc_init(pdev, pdata, pdata->check_adc_channel); adc_init(pdev, pdata, pdata->temp_adc_channel); adc_init(pdev, pdata, pdata->temp_amb_adc_channel); adc_init(pdev, pdata, pdata->full_check_adc_channel); wake_lock_init(&battery->monitor_wake_lock, WAKE_LOCK_SUSPEND, "sec-battery-monitor"); wake_lock_init(&battery->cable_wake_lock, WAKE_LOCK_SUSPEND, "sec-battery-cable"); wake_lock_init(&battery->vbus_wake_lock, WAKE_LOCK_SUSPEND, "sec-battery-vbus"); /* initialization of battery info */ battery->status = POWER_SUPPLY_STATUS_DISCHARGING; battery->health = POWER_SUPPLY_HEALTH_GOOD; battery->present = false; battery->long_polling_activated = false; battery->polling_count = 0; battery->polling_time = pdata->short_polling_time; battery->check_count = 0; battery->check_adc_count = 0; battery->check_adc_value = 0; battery->charging_start_time = 0; battery->charging_passed_time = 0; battery->charging_next_time = 0; setup_timer(&battery->event_expired_timer, sec_bat_event_expired_timer_func, (unsigned long)battery); battery->temp_high_threshold = pdata->temp_high_threshold_normal; battery->temp_high_recovery = pdata->temp_high_recovery_normal; battery->temp_low_recovery = pdata->temp_low_recovery_normal; battery->temp_low_threshold = pdata->temp_low_threshold_normal; battery->charging_mode = SEC_BATTERY_CHARGING_NONE; battery->cable_type = POWER_SUPPLY_TYPE_BATTERY; battery->test_activated = false; battery->psy_bat.name = "battery", battery->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY, battery->psy_bat.properties = sec_battery_props, battery->psy_bat.num_properties = ARRAY_SIZE(sec_battery_props), battery->psy_bat.get_property = sec_bat_get_property, battery->psy_bat.set_property = sec_bat_set_property, battery->psy_usb.name = "usb", battery->psy_usb.type = POWER_SUPPLY_TYPE_USB, battery->psy_usb.supplied_to = supply_list, battery->psy_usb.num_supplicants = ARRAY_SIZE(supply_list), battery->psy_usb.properties = sec_power_props, battery->psy_usb.num_properties = ARRAY_SIZE(sec_power_props), battery->psy_usb.get_property = sec_usb_get_property, battery->psy_ac.name = "ac", battery->psy_ac.type = POWER_SUPPLY_TYPE_MAINS, battery->psy_ac.supplied_to = supply_list, battery->psy_ac.num_supplicants = ARRAY_SIZE(supply_list), battery->psy_ac.properties = sec_power_props, battery->psy_ac.num_properties = ARRAY_SIZE(sec_power_props), battery->psy_ac.get_property = sec_ac_get_property; /* init power supplier framework */ ret = power_supply_register(&pdev->dev, &battery->psy_bat); if (ret) { pr_err("%s: Failed to Register psy_bat\n", __func__); goto err_wake_lock; } ret = power_supply_register(&pdev->dev, &battery->psy_usb); if (ret) { pr_err("%s: Failed to Register psy_usb\n", __func__); goto err_supply_unreg_bat; } ret = power_supply_register(&pdev->dev, &battery->psy_ac); if (ret) { pr_err("%s: Failed to Register psy_ac\n", __func__); goto err_supply_unreg_usb; } /* create work queue */ battery->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); if (!battery->monitor_wqueue) { pr_err("%s: Fail to Create Workqueue\n", __func__); goto err_supply_unreg_ac; } INIT_WORK(&battery->monitor_work, sec_bat_monitor_work); INIT_WORK(&battery->cable_work, sec_bat_cable_work); if (battery->pdata->bat_gpio_irq) { irq = gpio_to_irq(battery->pdata->bat_gpio_irq); ret = request_threaded_irq(irq, NULL, sec_bat_irq_thread, battery->pdata->bat_irq_attr, "battery-irq", battery); if (ret) { pr_err("%s: Failed to Reqeust IRQ\n", __func__); return ret; } ret = enable_irq_wake(irq); if (ret < 0) pr_err("%s: Failed to Enable Wakeup Source(%d)\n" , __func__, ret); } ret = sec_bat_create_attrs(battery->psy_bat.dev); if (ret) { pr_err("%s : Failed to create_attrs\n", __func__); goto err_supply_unreg_ac; } switch (pdata->polling_type) { case SEC_BATTERY_MONITOR_WORKQUEUE: INIT_DELAYED_WORK_DEFERRABLE(&battery->polling_work, sec_bat_polling_work); break; case SEC_BATTERY_MONITOR_ALARM: battery->last_poll_time = alarm_get_elapsed_realtime(); alarm_init(&battery->polling_alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, sec_bat_alarm); break; default: break; } wake_lock(&battery->monitor_wake_lock); queue_work(battery->monitor_wqueue, &battery->monitor_work); pdata->initial_check(); pr_debug("%s: SEC Battery Driver Loaded\n", __func__); return 0; err_supply_unreg_ac: power_supply_unregister(&battery->psy_ac); err_supply_unreg_usb: power_supply_unregister(&battery->psy_usb); err_supply_unreg_bat: power_supply_unregister(&battery->psy_bat); err_wake_lock: wake_lock_destroy(&battery->monitor_wake_lock); wake_lock_destroy(&battery->cable_wake_lock); wake_lock_destroy(&battery->vbus_wake_lock); mutex_destroy(&battery->adclock); kfree(battery); return ret; }
static int max8925_power_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); struct max8925_power_pdata *pdata = NULL; struct max8925_power_info *info; int ret; pdata = max8925_power_dt_init(pdev); if (!pdata) { dev_err(&pdev->dev, "platform data isn't assigned to " "power supply\n"); return -EINVAL; } info = kzalloc(sizeof(struct max8925_power_info), GFP_KERNEL); if (!info) return -ENOMEM; info->chip = chip; info->gpm = chip->i2c; info->adc = chip->adc; platform_set_drvdata(pdev, info); info->ac.name = "max8925-ac"; info->ac.type = POWER_SUPPLY_TYPE_MAINS; info->ac.properties = max8925_ac_props; info->ac.num_properties = ARRAY_SIZE(max8925_ac_props); info->ac.get_property = max8925_ac_get_prop; info->ac.supplied_to = pdata->supplied_to; info->ac.num_supplicants = pdata->num_supplicants; ret = power_supply_register(&pdev->dev, &info->ac); if (ret) goto out; info->ac.dev->parent = &pdev->dev; info->usb.name = "max8925-usb"; info->usb.type = POWER_SUPPLY_TYPE_USB; info->usb.properties = max8925_usb_props; info->usb.num_properties = ARRAY_SIZE(max8925_usb_props); info->usb.get_property = max8925_usb_get_prop; info->usb.supplied_to = pdata->supplied_to; info->usb.num_supplicants = pdata->num_supplicants; ret = power_supply_register(&pdev->dev, &info->usb); if (ret) goto out_usb; info->usb.dev->parent = &pdev->dev; info->battery.name = "max8925-battery"; info->battery.type = POWER_SUPPLY_TYPE_BATTERY; info->battery.properties = max8925_battery_props; info->battery.num_properties = ARRAY_SIZE(max8925_battery_props); info->battery.get_property = max8925_bat_get_prop; ret = power_supply_register(&pdev->dev, &info->battery); if (ret) goto out_battery; info->battery.dev->parent = &pdev->dev; info->batt_detect = pdata->batt_detect; info->topoff_threshold = pdata->topoff_threshold; info->fast_charge = pdata->fast_charge; info->set_charger = pdata->set_charger; info->no_temp_support = pdata->no_temp_support; info->no_insert_detect = pdata->no_insert_detect; max8925_init_charger(chip, info); return 0; out_battery: power_supply_unregister(&info->battery); out_usb: power_supply_unregister(&info->ac); out: kfree(info); return ret; }
static int ftt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ftt_charger_pdata *pdata = pdev->dev.platform_data; struct ftt_charger_device *ftt_pdev; int err; int retval = 0; #ifdef CONFIG_OF struct device_node *np = pdev->dev.of_node; #endif #ifdef CONFIG_OF printk("[FTT] +ftt_probe()\n"); if (pdev->dev.of_node) { pdata = devm_kzalloc(&pdev->dev, sizeof(struct ftt_charger_pdata), GFP_KERNEL); if (!pdata) { printk("ftt : cannot allocate\n"); return -ENOMEM; } pdev->dev.platform_data = pdata; pdata->chg_ctrl_gpio = of_get_named_gpio(np, "chg_ctrl_gpio", 0); pdata->half_chg_ctrl_gpio = of_get_named_gpio(np, "half_chg_ctrl_gpio", 0); pdata->active_n_gpio = of_get_named_gpio(np, "active_n_gpio", 0); pdata->otg_ctrl_gpio= of_get_named_gpio(np, "otg_ctrl_gpio", 0); pdata->wlc_ts_mpp = of_get_named_gpio(np, "wlc_ts_mpp", 0); pdata->ftt_gpio = of_get_named_gpio(np, "track_gpio", 0); pdata->get_ftt_gpio = get_ftt_gpio; pdata->online_fn = wireless_online; pdata->on_change_level_fn = on_change_level; } #endif ftt_pdev = kzalloc(sizeof(struct ftt_charger_device), GFP_KERNEL); if (!ftt_pdev) { dev_dbg(&pdev->dev, "out of memory\n"); retval = -ENOMEM; goto err_out; } ftt_pdev->pdev = pdev; pdata = ftt_pdev->pdev->dev.platform_data; #ifdef CONFIG_OF ftt_pdev->chg_ctrl_gpio = pdata->chg_ctrl_gpio; printk("[FTT] - chg_ctrl_gpio : %d\n", ftt_pdev->chg_ctrl_gpio); ftt_pdev->half_chg_ctrl_gpio = pdata->half_chg_ctrl_gpio; printk("[FTT] - half_chg_ctrl_gpio : %d\n", ftt_pdev->half_chg_ctrl_gpio); ftt_pdev->active_n_gpio = pdata->active_n_gpio; printk("[FTT] - active_n_gpio : %d\n", ftt_pdev->active_n_gpio); ftt_pdev->otg_ctrl_gpio = pdata->otg_ctrl_gpio; printk("[FTT] - otg_ctrl_gpio : %d\n", ftt_pdev->otg_ctrl_gpio); ftt_pdev->wlc_ts_mpp = pdata->wlc_ts_mpp; printk("[FTT] - wlc_ts_mpp : %d\n", ftt_pdev->wlc_ts_mpp); ftt_pdev->ftt_gpio = pdata->ftt_gpio; printk("[FTT] - track_gpio : %d\n", ftt_pdev->ftt_gpio); ftt_hw_init(ftt_pdev); #endif /* initalize member start */ set_ftt_charger_init_data(ftt_pdev); set_ftt_charger_reset_status(ftt_pdev); set_ftt_charger_reset_data(ftt_pdev); /* initalize member end */ if (!pdata) { dev_err(dev, "Cannot find platform data.\n"); retval = -ENXIO; goto err_kzalloc; } DPRINT(FTT_INFO, "%s\n", __FUNCTION__); #if (FTT_CHIP_ENABLE_PIN_USE == 1) err = gpio_request(pdata->en1, "FTT_CHIP_ENABLE"); if (err) printk(KERN_ERR "#### failed to request FTT_CHIP_ENABLE ####\n"); gpio_direction_output(pdata->en1, ftt_chip_enable_flag); #endif if (pdata->get_ftt_gpio == NULL) { retval = -ENXIO; goto err_kzalloc; } err = gpio_request(ftt_pdev->ftt_gpio, "FTT_FREQUANCY"); if (err) { printk(KERN_ERR "#### failed to request FTT_FREQUANCY ####\n"); retval = ENODEV; goto err_kzalloc; } gpio_direction_input(ftt_pdev->ftt_gpio); ftt_pdev->ftt_irq = gpio_to_irq(ftt_pdev->ftt_gpio); ftt_pdev->ftt_charger_status_timer.function = ftt_charger_status_timer_handler; ftt_pdev->ftt_charger_status_timer.data = (unsigned long)ftt_pdev; init_timer(&ftt_pdev->ftt_charger_status_timer); err = request_irq(ftt_pdev->ftt_irq, ftt_interrupt_pin_cb, IRQF_TRIGGER_RISING, DEVICE_NAME, (void *)ftt_pdev); if (err) { printk(KERN_ERR "gpio-ftt-charger: Unable to claim irq %d; error %d\n", ftt_pdev->ftt_irq, err); retval = err; goto err_gpio; } ftt_interrupt_disable(ftt_pdev); ftt_pdev->ftt_interrupt_booting_enable_flag = true; set_ftt_charger_reset_status(ftt_pdev); #ifndef FTT_FILE_OPEN_ENABLE ftt_enable(ftt_pdev); #endif /* FTT_FILE_OPEN_ENABLE */ #if defined(CONFIG_HAS_EARLYSUSPEND) /************************************************************** EARLYSUSPEND/LATERESUME **************************************************************/ ftt_pdev->power.suspend = ftt_suspend; ftt_pdev->power.resume = ftt_resume; ftt_pdev->power.level = EARLY_SUSPEND_LEVEL_DISABLE_FB-1; register_early_suspend(&ftt_pdev->power); #endif #if FTT_UEVENT ftt_uevent_init(ftt_pdev); if ((err = power_supply_register(dev, &ftt_pdev->ftt_supply))) { dev_err(dev, "failed: power supply ftt wireless register.\n"); retval = err; goto err_suspend; } else { dev_info(dev, "power supply ftt wireless registerd.\n"); } #endif #if FTT_CHARACTER_DEVICE ftt_pdev->ftt_misc.fops = &ftt_fops; ftt_pdev->ftt_misc.name = FTT_CHAR_DEVICE_NAME; ftt_pdev->ftt_misc.minor = MISC_DYNAMIC_MINOR;//FTT_MINOR; if ((err = misc_register(&ftt_pdev->ftt_misc))) { retval = err; goto err_power_supply; } else { dev_info(dev, "misc device ftt wireless registerd.\n"); } #endif /* FTT_CHARACTER_DEVICE */ init_waitqueue_head(&ftt_pdev->wait); INIT_LIST_HEAD(&ftt_pdev->read_cmd_queue); #ifdef CONFIG_FTT_SYSFS err = sysfs_create_group(&pdev->dev.kobj, &ftt_sysfs_attr_group); if (err) { printk(KERN_ERR "#### failed to sysfs_create_group ####\n"); retval = err; goto err_character_device; } #endif /* CONFIG_FTT_SYSFS */ platform_set_drvdata(pdev, ftt_pdev); printk(DEVICE_NAME " Initialized\n"); return 0; /******************************************************************************************* ERROR *******************************************************************************************/ err_character_device: #if FTT_CHARACTER_DEVICE misc_deregister(&ftt_pdev->ftt_misc); #endif /* FTT_CHARACTER_DEVICE */ err_power_supply: #if FTT_UEVENT power_supply_unregister(&ftt_pdev->ftt_supply); #endif err_suspend: #if defined(CONFIG_HAS_EARLYSUSPEND) unregister_early_suspend(&ftt_pdev->power); #endif free_irq(ftt_pdev->ftt_irq, ftt_pdev); #if FTT_CHARGER_STATUS_TIMER del_timer(&ftt_pdev->ftt_charger_status_timer); #endif err_gpio: gpio_free(ftt_pdev->ftt_gpio); err_kzalloc: kfree(ftt_pdev); err_out: return retval; }
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->phy = usb_get_phy(); if (!isp->phy) 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 usb notifications to be * made atomically in the future. */ INIT_WORK(&isp->work, isp1704_charger_work); isp->nb.notifier_call = isp1704_notifier_call; ret = usb_register_notifier(isp->phy, &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->phy->otg->gadget) usb_gadget_disconnect(isp->phy->otg->gadget); /* Detect charger if VBUS is valid (the cable was already plugged). */ ret = isp1704_read(isp, ULPI_USB_INT_STS); isp1704_charger_set_power(isp, 0); if ((ret & ULPI_INT_VBUS_VALID) && !isp->phy->otg->default_a) { isp->event = USB_EVENT_VBUS; schedule_work(&isp->work); } return 0; fail2: power_supply_unregister(&isp->psy); fail1: usb_put_phy(isp->phy); fail0: kfree(isp); dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret); isp1704_charger_set_power(isp, 0); return ret; }
static int __init twl4030_bci_probe(struct platform_device *pdev) { struct twl4030_bci *bci; const struct twl4030_bci_platform_data *pdata = pdev->dev.platform_data; int ret; u32 reg; bci = kzalloc(sizeof(*bci), GFP_KERNEL); if (bci == NULL) return -ENOMEM; if (!pdata) pdata = twl4030_bci_parse_dt(&pdev->dev); bci->dev = &pdev->dev; bci->irq_chg = platform_get_irq(pdev, 0); bci->irq_bci = platform_get_irq(pdev, 1); /* Only proceed further *IF* battery is physically present */ ret = twl4030_is_battery_present(bci); if (ret) { dev_crit(&pdev->dev, "Battery was not detected:%d\n", ret); goto fail_no_battery; } platform_set_drvdata(pdev, bci); bci->ac = power_supply_register(&pdev->dev, &twl4030_bci_ac_desc, NULL); if (IS_ERR(bci->ac)) { ret = PTR_ERR(bci->ac); dev_err(&pdev->dev, "failed to register ac: %d\n", ret); goto fail_register_ac; } bci->usb_reg = regulator_get(bci->dev, "bci3v1"); bci->usb = power_supply_register(&pdev->dev, &twl4030_bci_usb_desc, NULL); if (IS_ERR(bci->usb)) { ret = PTR_ERR(bci->usb); 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, IRQF_ONESHOT, 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, IRQF_ONESHOT, 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 = usb_get_phy(USB_PHY_TYPE_USB2); if (!IS_ERR_OR_NULL(bci->transceiver)) { bci->usb_nb.notifier_call = twl4030_bci_usb_ncb; usb_register_notifier(bci->transceiver, &bci->usb_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); if (pdata) twl4030_charger_enable_backup(pdata->bb_uvolt, pdata->bb_uamp); else twl4030_charger_enable_backup(0, 0); return 0; fail_unmask_interrupts: if (!IS_ERR_OR_NULL(bci->transceiver)) { usb_unregister_notifier(bci->transceiver, &bci->usb_nb); usb_put_phy(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: fail_no_battery: kfree(bci); return ret; }
static __devinit int max8903_probe(struct platform_device *pdev) { struct max8903_data *data; struct device *dev = &pdev->dev; struct max8903_pdata *pdata = pdev->dev.platform_data; int ret = 0; int gpio = 0; int ta_in = 0; int usb_in = 0; int retval; cpu_type_flag = 0; //-> [J.Chiang], debug printk("sabresd_battery: max8903_probe is called......\n"); // <- End. if (cpu_is_mx6q()) cpu_type_flag = 1; if (cpu_is_mx6dl()) cpu_type_flag = 0; data = kzalloc(sizeof(struct max8903_data), GFP_KERNEL); if (data == NULL) { dev_err(dev, "Cannot allocate memory.\n"); return -ENOMEM; } data->first_delay_count = 0; data->pdata = pdata; data->dev = dev; platform_set_drvdata(pdev, data); data->usb_in = 0; data->ta_in = 0; #ifndef CONFIG_DSA2L if (pdata->dc_valid == false && pdata->usb_valid == false) { dev_err(dev, "No valid power sources.\n"); printk(KERN_INFO "No valid power sources.\n"); ret = -EINVAL; goto err; } if (pdata->dc_valid) { if (pdata->dok && gpio_is_valid(pdata->dok)) { gpio = pdata->dok; /* PULL_UPed Interrupt */ /* set DOK gpio input */ ret = gpio_request(gpio, "max8903-DOK"); if (ret) { printk(KERN_ERR"request max8903-DOK error!!\n"); goto err; } else { gpio_direction_input(gpio); } ta_in = gpio_get_value(gpio) ? 0 : 1; } else if (pdata->dok && gpio_is_valid(pdata->dok) && pdata->dcm_always_high) { ta_in = pdata->dok; /* PULL_UPed Interrupt */ ta_in = gpio_get_value(gpio) ? 0 : 1; } else { dev_err(dev, "When DC is wired, DOK and DCM should" " be wired as well." " or set dcm always high\n"); ret = -EINVAL; goto err; } } if (pdata->usb_valid) { if (pdata->uok && gpio_is_valid(pdata->uok)) { gpio = pdata->uok; /* set UOK gpio input */ ret = gpio_request(gpio, "max8903-UOK"); if (ret) { printk(KERN_ERR"request max8903-UOK error!!\n"); goto err; } else { gpio_direction_input(gpio); } usb_in = gpio_get_value(gpio) ? 0 : 1; } else { dev_err(dev, "When USB is wired, UOK should be wired." "as well.\n"); ret = -EINVAL; goto err; } } if (pdata->chg) { if (!gpio_is_valid(pdata->chg)) { dev_err(dev, "Invalid pin: chg.\n"); ret = -EINVAL; goto err; } /* set CHG gpio input */ ret = gpio_request(pdata->chg, "max8903-CHG"); if (ret) { printk(KERN_ERR"request max8903-CHG error!!\n"); goto err; } else { gpio_direction_input(pdata->chg); } } if (pdata->flt) { if (!gpio_is_valid(pdata->flt)) { dev_err(dev, "Invalid pin: flt.\n"); ret = -EINVAL; goto err; } /* set FLT gpio input */ ret = gpio_request(pdata->flt, "max8903-FLT"); if (ret) { printk(KERN_ERR"request max8903-FLT error!!\n"); goto err; } else { gpio_direction_input(pdata->flt); } } if (pdata->usus) { if (!gpio_is_valid(pdata->usus)) { dev_err(dev, "Invalid pin: usus.\n"); ret = -EINVAL; goto err; } } #endif // CONFIG_DSA2L mutex_init(&data->work_lock); //-> [J.Chiang], debug printk("sabresd_battery: register max8903-ac......\n"); // <- End. data->fault = false; data->ta_in = ta_in; data->usb_in = usb_in; data->psy.name = "max8903-ac"; data->psy.type = POWER_SUPPLY_TYPE_MAINS; data->psy.get_property = max8903_get_property; data->psy.properties = max8903_charger_props; data->psy.num_properties = ARRAY_SIZE(max8903_charger_props); ret = power_supply_register(dev, &data->psy); if (ret) { dev_err(dev, "failed: power supply register.\n"); goto err_psy; } #ifndef CONFIG_DSA2L data->usb.name = "max8903-usb"; data->usb.type = POWER_SUPPLY_TYPE_USB; data->usb.get_property = max8903_get_usb_property; data->usb.properties = max8903_charger_props; data->usb.num_properties = ARRAY_SIZE(max8903_charger_props); ret = power_supply_register(dev, &data->usb); if (ret) { dev_err(dev, "failed: power supply register.\n"); goto err_psy; } #endif // CONFIG_DSA2L //-> [J.Chiang], debug printk("sabresd_battery: register max8903-charger......\n"); // <- End. data->bat.name = "max8903-charger"; data->bat.type = POWER_SUPPLY_TYPE_BATTERY; data->bat.properties = max8903_battery_props; data->bat.num_properties = ARRAY_SIZE(max8903_battery_props); data->bat.get_property = max8903_battery_get_property; data->bat.use_for_apm = 1; retval = power_supply_register(&pdev->dev, &data->bat); if (retval) { dev_err(data->dev, "failed to register battery\n"); goto battery_failed; } INIT_DELAYED_WORK(&data->work, max8903_battery_work); schedule_delayed_work(&data->work, data->interval); #ifndef CONFIG_DSA2L if (pdata->dc_valid) { ret = request_threaded_irq(gpio_to_irq(pdata->dok), NULL, max8903_dcin, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "MAX8903 DC IN", data); if (ret) { dev_err(dev, "Cannot request irq %d for DC (%d)\n", gpio_to_irq(pdata->dok), ret); goto err_usb_irq; } } if (pdata->usb_valid) { ret = request_threaded_irq(gpio_to_irq(pdata->uok), NULL, max8903_usbin, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "MAX8903 USB IN", data); if (ret) { dev_err(dev, "Cannot request irq %d for USB (%d)\n", gpio_to_irq(pdata->uok), ret); goto err_dc_irq; } } if (pdata->flt) { ret = request_threaded_irq(gpio_to_irq(pdata->flt), NULL, max8903_fault, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "MAX8903 Fault", data); if (ret) { dev_err(dev, "Cannot request irq %d for Fault (%d)\n", gpio_to_irq(pdata->flt), ret); goto err_flt_irq; } } if (pdata->chg) { ret = request_threaded_irq(gpio_to_irq(pdata->chg), NULL, max8903_chg, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "MAX8903 Status", data); if (ret) { dev_err(dev, "Cannot request irq %d for Status (%d)\n", gpio_to_irq(pdata->flt), ret); goto err_chg_irq; } } #endif // CONFIG_DSA2L ret = device_create_file(&pdev->dev, &max8903_discharger_dev_attr); if (ret) dev_err(&pdev->dev, "create device file failed!\n"); ret = device_create_file(&pdev->dev, &max8903_charger_dev_attr); if (ret) dev_err(&pdev->dev, "create device file failed!\n"); #ifndef CONFIG_DSA2L ret = device_create_file(&pdev->dev, &max8903_usb_charger_dev_attr); if (ret) dev_err(&pdev->dev, "create device file failed!\n"); #endif // CONFIG_DSA2L if (cpu_type_flag == 1) { offset_discharger = 1694; offset_charger = 1900; offset_usb_charger = 1685; } if (cpu_type_flag == 0) { offset_discharger = 1464; offset_charger = 1485; offset_usb_charger = 1285; } max8903_charger_update_status(data); max8903_battery_update_status(data); return 0; err_psy: power_supply_unregister(&data->psy); battery_failed: power_supply_unregister(&data->bat); err_usb_irq: if (pdata->usb_valid) free_irq(gpio_to_irq(pdata->uok), data); cancel_delayed_work(&data->work); err_dc_irq: if (pdata->dc_valid) free_irq(gpio_to_irq(pdata->dok), data); cancel_delayed_work(&data->work); err_flt_irq: if (pdata->usb_valid) free_irq(gpio_to_irq(pdata->uok), data); cancel_delayed_work(&data->work); err_chg_irq: if (pdata->dc_valid) free_irq(gpio_to_irq(pdata->dok), data); cancel_delayed_work(&data->work); err: if (pdata->uok) gpio_free(pdata->uok); if (pdata->dok) gpio_free(pdata->dok); if (pdata->flt) gpio_free(pdata->flt); if (pdata->chg) gpio_free(pdata->chg); kfree(data); return ret; }
static void lp8788_psy_unregister(struct lp8788_charger *pchg) { power_supply_unregister(pchg->battery); power_supply_unregister(pchg->charger); }
static int bq51221_charger_probe( struct i2c_client *client, const struct i2c_device_id *id) { struct device_node *of_node = client->dev.of_node; struct bq51221_charger_data *charger; bq51221_charger_platform_data_t *pdata = client->dev.platform_data; int ret = 0; dev_info(&client->dev, "%s: bq51221 Charger Driver Loading\n", __func__); if (of_node) { pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(&client->dev, "Failed to allocate memory\n"); return -ENOMEM; } ret = bq51221_chg_parse_dt(&client->dev, pdata); if (ret < 0) goto err_parse_dt; } else { pdata = client->dev.platform_data; } charger = kzalloc(sizeof(*charger), GFP_KERNEL); if (charger == NULL) { dev_err(&client->dev, "Memory is not enough.\n"); ret = -ENOMEM; goto err_wpc_nomem; } charger->dev = &client->dev; ret = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); if (!ret) { ret = i2c_get_functionality(client->adapter); dev_err(charger->dev, "I2C functionality is not supported.\n"); ret = -ENOSYS; goto err_i2cfunc_not_support; } charger->client = client; charger->pdata = pdata; pr_info("%s: %s\n", __func__, charger->pdata->wireless_charger_name ); /* if board-init had already assigned irq_base (>=0) , no need to allocate it; assign -1 to let this driver allocate resource by itself*/ #if 0 /* this part is for bq51221s */ if (pdata->irq_base < 0) pdata->irq_base = irq_alloc_descs(-1, 0, BQ51221_EVENT_IRQ, 0); if (pdata->irq_base < 0) { pr_err("%s: irq_alloc_descs Fail! ret(%d)\n", __func__, pdata->irq_base); ret = -EINVAL; goto irq_base_err; } else { charger->irq_base = pdata->irq_base; pr_info("%s: irq_base = %d\n", __func__, charger->irq_base); #if (LINUX_VERSION_CODE>=KERNEL_VERSION(3,4,0)) irq_domain_add_legacy(of_node, BQ51221_EVENT_IRQ, charger->irq_base, 0, &irq_domain_simple_ops, NULL); #endif /*(LINUX_VERSION_CODE>=KERNEL_VERSION(3,4,0))*/ } #endif i2c_set_clientdata(client, charger); charger->psy_chg.name = pdata->wireless_charger_name; charger->psy_chg.type = POWER_SUPPLY_TYPE_UNKNOWN; charger->psy_chg.get_property = bq51221_chg_get_property; charger->psy_chg.set_property = bq51221_chg_set_property; charger->psy_chg.properties = sec_charger_props; charger->psy_chg.num_properties = ARRAY_SIZE(sec_charger_props); mutex_init(&charger->io_lock); #if 0 /* this part is for bq51221s */ if (charger->chg_irq) { INIT_DELAYED_WORK( &charger->isr_work, bq51221_chg_isr_work); ret = request_threaded_irq(charger->chg_irq, NULL, bq51221_chg_irq_thread, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "charger-irq", charger); if (ret) { dev_err(&client->dev, "%s: Failed to Reqeust IRQ\n", __func__); goto err_supply_unreg; } ret = enable_irq_wake(charger->chg_irq); if (ret < 0) dev_err(&client->dev, "%s: Failed to Enable Wakeup Source(%d)\n", __func__, ret); } #endif charger->pdata->cs100_status = 0; charger->pdata->pad_mode = BQ51221_PAD_MODE_NONE; ret = power_supply_register(&client->dev, &charger->psy_chg); if (ret) { dev_err(&client->dev, "%s: Failed to Register psy_chg\n", __func__); goto err_supply_unreg; } charger->wqueue = create_workqueue("bq51221_workqueue"); if (!charger->wqueue) { pr_err("%s: Fail to Create Workqueue\n", __func__); goto err_pdata_free; } wake_lock_init(&(charger->wpc_wake_lock), WAKE_LOCK_SUSPEND, "wpc_wakelock"); INIT_DELAYED_WORK(&charger->wpc_work, bq51221_detect_work); dev_info(&client->dev, "%s: bq51221 Charger Driver Loaded\n", __func__); return 0; err_pdata_free: power_supply_unregister(&charger->psy_chg); err_supply_unreg: mutex_destroy(&charger->io_lock); err_i2cfunc_not_support: kfree(charger); err_wpc_nomem: err_parse_dt: kfree(pdata); return ret; }
static int pmic_battery_probe(struct platform_device *pdev) { int retval = 0; struct mc13892_dev_info *di; pmic_event_callback_t bat_event_callback; pmic_version_t pmic_version; //printk("%s %s %d \n",__FILE__,__func__,__LINE__); /* Only apply battery driver for MC13892 V2.0 due to ENGR108085 */ pmic_version = pmic_get_version(); if (pmic_version.revision < 20) { pr_debug("Battery driver is only applied for MC13892 V2.0\n"); return -1; } if (machine_is_mx50_arm2()) { pr_debug("mc13892 charger is not used for this platform\n"); return -1; } di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) { retval = -ENOMEM; goto di_alloc_failed; } di->init_charge = -1; platform_set_drvdata(pdev, di); di->charger.name = "mc13892_charger"; di->charger.type = POWER_SUPPLY_TYPE_MAINS; di->charger.properties = mc13892_charger_props; di->charger.num_properties = ARRAY_SIZE(mc13892_charger_props); di->charger.get_property = mc13892_charger_get_property; retval = power_supply_register(&pdev->dev, &di->charger); if (retval) { dev_err(di->dev, "failed to register charger\n"); goto charger_failed; } INIT_DELAYED_WORK(&di->monitor_work, mc13892_battery_work); di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); if (!di->monitor_wqueue) { retval = -ESRCH; goto workqueue_failed; } queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 10); //queue_delayed_work(di->monitor_wqueue, &di->monitor_work, msecs_to_jiffies(10000)); pmic_stop_coulomb_counter(); pmic_calibrate_coulomb_counter(); //for get correct voltage on the battery when booting with external power. //chg_thread will change it, when next work (chg_work) is start. pmic_set_chg_current(0); INIT_DELAYED_WORK(&di->calc_capacity,mc13892_compute_battery_capacity_from_CC); queue_delayed_work(di->monitor_wqueue, &di->calc_capacity, 0); INIT_DELAYED_WORK(&chg_work, chg_thread); chg_wq = create_singlethread_workqueue("mxc_chg"); if (!chg_wq) { retval = -ESRCH; goto workqueue_failed; } queue_delayed_work(chg_wq, &chg_work, HZ); di->dev = &pdev->dev; di->bat.name = "mc13892_bat"; di->bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bat.properties = mc13892_battery_props; di->bat.num_properties = ARRAY_SIZE(mc13892_battery_props); di->bat.get_property = mc13892_battery_get_property; di->bat.use_for_apm = 1; di->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; //di->battery_status = POWER_SUPPLY_STATUS_DISCHARGING; retval = power_supply_register(&pdev->dev, &di->bat); if (retval) { dev_err(di->dev, "failed to register battery\n"); goto batt_failed; } bat_event_callback.func = charger_online_event_callback; bat_event_callback.param = (void *) di; pmic_event_subscribe(EVENT_CHGDETI, bat_event_callback); retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr); if (retval) { printk(KERN_ERR "Battery: Unable to register sysdev entry for Battery"); goto workqueue_failed; } chg_wa_is_active = 1; chg_wa_timer = 0; disable_chg_timer = 0; #if defined(PMIC_MC13892_BATTERY_WORK) work_init(); #endif goto success; workqueue_failed: power_supply_unregister(&di->charger); charger_failed: power_supply_unregister(&di->bat); batt_failed: kfree(di); di_alloc_failed: success: dev_dbg(di->dev, "%s battery probed!\n", __func__); return retval; return 0; }
static __devinit int max8998_charger_probe(struct platform_device *pdev) { struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); struct chg_data *chg; int ret = 0; pr_info("%s : MAX8998 Charger Driver Loading\n", __func__); chg = kzalloc(sizeof(*chg), GFP_KERNEL); if (!chg) return -ENOMEM; chg->iodev = iodev; chg->pdata = pdata->charger; if (!chg->pdata || !chg->pdata->adc_table) { pr_err("%s : No platform data & adc_table supplied\n", __func__); ret = -EINVAL; goto err_bat_table; } chg->psy_bat.name = "battery", chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY, chg->psy_bat.properties = max8998_battery_props, chg->psy_bat.num_properties = ARRAY_SIZE(max8998_battery_props), chg->psy_bat.get_property = s3c_bat_get_property, chg->psy_usb.name = "usb", chg->psy_usb.type = POWER_SUPPLY_TYPE_USB, chg->psy_usb.supplied_to = supply_list, chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list), chg->psy_usb.properties = s3c_power_properties, chg->psy_usb.num_properties = ARRAY_SIZE(s3c_power_properties), chg->psy_usb.get_property = s3c_usb_get_property, chg->psy_ac.name = "ac", chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS, chg->psy_ac.supplied_to = supply_list, chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list), chg->psy_ac.properties = s3c_power_properties, chg->psy_ac.num_properties = ARRAY_SIZE(s3c_power_properties), chg->psy_ac.get_property = s3c_ac_get_property, chg->present = 1; chg->polling_interval = POLLING_INTERVAL; chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD; chg->bat_info.batt_is_full = false; chg->bat_info.batt_max_soc = 0; chg->set_charge_timeout = false; chg->cable_status = CABLE_TYPE_NONE; mutex_init(&chg->mutex); platform_set_drvdata(pdev, chg); ret = max8998_update_reg(iodev, MAX8998_REG_CHGR1, /* disable */ (0x3 << MAX8998_SHIFT_RSTR), MAX8998_MASK_RSTR); if (ret < 0) goto err_kfree; ret = max8998_update_reg(iodev, MAX8998_REG_CHGR2, /* 6 Hr */ (0x2 << MAX8998_SHIFT_FT), MAX8998_MASK_FT); if (ret < 0) goto err_kfree; ret = max8998_update_reg(iodev, MAX8998_REG_CHGR2, /* 4.2V */ (0x0 << MAX8998_SHIFT_BATTSL), MAX8998_MASK_BATTSL); if (ret < 0) goto err_kfree; ret = max8998_update_reg(iodev, MAX8998_REG_CHGR2, /* 105c */ (0x0 << MAX8998_SHIFT_TMP), MAX8998_MASK_TMP); if (ret < 0) goto err_kfree; pr_info("%s : pmic interrupt registered\n", __func__); ret = max8998_write_reg(iodev, MAX8998_REG_IRQM1, ~(MAX8998_MASK_DCINR | MAX8998_MASK_DCINF)); if (ret < 0) goto err_kfree; ret = max8998_write_reg(iodev, MAX8998_REG_IRQM2, 0xFF); if (ret < 0) goto err_kfree; ret = max8998_write_reg(iodev, MAX8998_REG_IRQM3, ~0x4); if (ret < 0) goto err_kfree; ret = max8998_write_reg(iodev, MAX8998_REG_IRQM4, 0xFF); if (ret < 0) goto err_kfree; wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present"); wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND, "max8998-charger"); INIT_WORK(&chg->bat_work, s3c_bat_work); chg->monitor_wqueue = create_freezeable_workqueue(dev_name(&pdev->dev)); if (!chg->monitor_wqueue) { pr_err("Failed to create freezeable workqueue\n"); ret = -ENOMEM; goto err_wake_lock; } chg->last_poll = alarm_get_elapsed_realtime(); alarm_init(&chg->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, s3c_battery_alarm); check_lpm_charging_mode(chg); /* init power supplier framework */ ret = power_supply_register(&pdev->dev, &chg->psy_bat); if (ret) { pr_err("Failed to register power supply psy_bat\n"); goto err_wqueue; } ret = power_supply_register(&pdev->dev, &chg->psy_usb); if (ret) { pr_err("Failed to register power supply psy_usb\n"); goto err_supply_unreg_bat; } ret = power_supply_register(&pdev->dev, &chg->psy_ac); if (ret) { pr_err("Failed to register power supply psy_ac\n"); goto err_supply_unreg_usb; } ret = request_threaded_irq(iodev->i2c_client->irq, NULL, max8998_int_work_func, IRQF_TRIGGER_FALLING, "max8998-charger", chg); if (ret) { pr_err("%s : Failed to request pmic irq\n", __func__); goto err_supply_unreg_ac; } ret = enable_irq_wake(iodev->i2c_client->irq); if (ret) { pr_err("Failed to enable pmic irq wake\n"); goto err_irq; } ret = s3c_bat_create_attrs(chg->psy_bat.dev); if (ret) { pr_err("%s : Failed to create_attrs\n", __func__); goto err_irq; } chg->callbacks.set_cable = max8998_set_cable; if (chg->pdata->register_callbacks) chg->pdata->register_callbacks(&chg->callbacks); wake_lock(&chg->work_wake_lock); queue_work(chg->monitor_wqueue, &chg->bat_work); return 0; err_irq: free_irq(iodev->i2c_client->irq, NULL); err_supply_unreg_ac: power_supply_unregister(&chg->psy_ac); err_supply_unreg_usb: power_supply_unregister(&chg->psy_usb); err_supply_unreg_bat: power_supply_unregister(&chg->psy_bat); err_wqueue: destroy_workqueue(chg->monitor_wqueue); cancel_work_sync(&chg->bat_work); alarm_cancel(&chg->alarm); err_wake_lock: wake_lock_destroy(&chg->work_wake_lock); wake_lock_destroy(&chg->vbus_wake_lock); err_kfree: mutex_destroy(&chg->mutex); err_bat_table: kfree(chg); return ret; }
static int __devinit bcmpmu_spa_pb_probe(struct platform_device *pdev) { int ret = 0; struct bcmpmu_spa_pb *bcmpmu_spa_pb; struct bcmpmu59xxx *bcmpmu = dev_get_drvdata(pdev->dev.parent); struct bcmpmu59xxx_spa_pb_pdata *pdata; pdata = (struct bcmpmu59xxx_spa_pb_pdata *)pdev->dev.platform_data; pr_pb(INIT, "%s\n", __func__); BUG_ON(!(bcmpmu->flags & BCMPMU_SPA_EN) || !pdata); bcmpmu_spa_pb = kzalloc(sizeof(struct bcmpmu_spa_pb), GFP_KERNEL); if (bcmpmu_spa_pb == NULL) { dev_err(&pdev->dev, "failed to alloc mem: %d\n", ret); return -ENOMEM; } bcmpmu_spa_pb->bcmpmu = bcmpmu; bcmpmu->spa_pb_info = (void *)bcmpmu_spa_pb; mutex_init(&bcmpmu_spa_pb->lock); INIT_DELAYED_WORK(&bcmpmu_spa_pb->spa_work, bcmpmu_spa_pb_work); bcmpmu_spa_pb->chrgr.properties = bcmpmu_spa_pb_chrgr_props; bcmpmu_spa_pb->chrgr.num_properties = ARRAY_SIZE(bcmpmu_spa_pb_chrgr_props); bcmpmu_spa_pb->chrgr.get_property = bcmpmu_spa_pb_chrgr_get_property; bcmpmu_spa_pb->chrgr.set_property = bcmpmu_spa_pb_chrgr_set_property; bcmpmu_spa_pb->chrgr.name = pdata->chrgr_name; ret = power_supply_register(&pdev->dev, &bcmpmu_spa_pb->chrgr); if (ret) goto cghr_err; bcmpmu->register_irq(bcmpmu, PMU_IRQ_MBTEMPLOW, bcmpmu_spa_pb_isr, bcmpmu_spa_pb); bcmpmu->register_irq(bcmpmu, PMU_IRQ_MBTEMPHIGH, bcmpmu_spa_pb_isr, bcmpmu_spa_pb); bcmpmu->register_irq(bcmpmu, PMU_IRQ_CHGERRDIS, bcmpmu_spa_pb_isr, bcmpmu_spa_pb); bcmpmu->register_irq(bcmpmu, PMU_IRQ_MBOV, bcmpmu_spa_pb_isr, bcmpmu_spa_pb); bcmpmu->register_irq(bcmpmu, PMU_IRQ_MBOV_DIS, bcmpmu_spa_pb_isr, bcmpmu_spa_pb); bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_MBTEMPLOW); bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_MBTEMPHIGH); bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_CHGERRDIS); bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_MBOV); bcmpmu->unmask_irq(bcmpmu, PMU_IRQ_MBOV_DIS); bcmpmu_spa_pb->nb_chgr_det.notifier_call = bcmpmu_spa_pb_event_hndlr; ret = bcmpmu_add_notifier(PMU_ACCY_EVT_OUT_CHRGR_TYPE, &bcmpmu_spa_pb->nb_chgr_det); if (ret) { pr_pb(ERROR, "%s, failed to register chrgr det notifier\n", __func__); goto err; } bcmpmu_spa_pb->nb_usbin.notifier_call = bcmpmu_spa_pb_event_hndlr; ret = bcmpmu_add_notifier(PMU_ACCY_EVT_OUT_USB_IN, &bcmpmu_spa_pb->nb_usbin); if (ret) { pr_pb(ERROR, "%s, failed to register chrgr det notifier\n", __func__); goto err; } #ifdef CONFIG_DEBUG_FS bcmpmu_spa_pb_dbg_init(bcmpmu_spa_pb); #endif return 0; err: bcmpmu_remove_notifier(PMU_ACCY_EVT_OUT_CHRGR_TYPE, &bcmpmu_spa_pb->nb_chgr_det); bcmpmu_remove_notifier(PMU_ACCY_EVT_OUT_USB_IN, &bcmpmu_spa_pb->nb_usbin); power_supply_unregister(&bcmpmu_spa_pb->chrgr); cghr_err: kfree(bcmpmu_spa_pb); return ret; }
static int cw_bat_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct cw_battery *cw_bat; int ret; int irq; int irq_flags; int loop = 0; cw_bat = devm_kzalloc(&client->dev, sizeof(*cw_bat), GFP_KERNEL); if (!cw_bat) { dev_err(&cw_bat->client->dev, "fail to allocate memory\n"); return -ENOMEM; } i2c_set_clientdata(client, cw_bat); cw_bat->plat_data = client->dev.platform_data; ret = cw_bat_gpio_init(cw_bat); if (ret) { dev_err(&cw_bat->client->dev, "cw_bat_gpio_init error\n"); return ret; } cw_bat->client = client; ret = cw_init(cw_bat); while ((loop++ < 200) && (ret != 0)) { ret = cw_init(cw_bat); } if (ret) return ret; cw_bat->rk_bat.name = "rk-bat"; cw_bat->rk_bat.type = POWER_SUPPLY_TYPE_BATTERY; cw_bat->rk_bat.properties = rk_battery_properties; cw_bat->rk_bat.num_properties = ARRAY_SIZE(rk_battery_properties); cw_bat->rk_bat.get_property = rk_battery_get_property; ret = power_supply_register(&client->dev, &cw_bat->rk_bat); if(ret < 0) { dev_err(&cw_bat->client->dev, "power supply register rk_bat error\n"); goto rk_bat_register_fail; } cw_bat->rk_ac.name = "rk-ac"; cw_bat->rk_ac.type = POWER_SUPPLY_TYPE_MAINS; cw_bat->rk_ac.properties = rk_ac_properties; cw_bat->rk_ac.num_properties = ARRAY_SIZE(rk_ac_properties); cw_bat->rk_ac.get_property = rk_ac_get_property; ret = power_supply_register(&client->dev, &cw_bat->rk_ac); if(ret < 0) { dev_err(&cw_bat->client->dev, "power supply register rk_ac error\n"); goto rk_ac_register_fail; } cw_bat->rk_usb.name = "rk-usb"; cw_bat->rk_usb.type = POWER_SUPPLY_TYPE_USB; cw_bat->rk_usb.properties = rk_usb_properties; cw_bat->rk_usb.num_properties = ARRAY_SIZE(rk_usb_properties); cw_bat->rk_usb.get_property = rk_usb_get_property; ret = power_supply_register(&client->dev, &cw_bat->rk_usb); if(ret < 0) { dev_err(&cw_bat->client->dev, "power supply register rk_ac error\n"); goto rk_usb_register_fail; } cw_bat->charger_init_mode = dwc_otg_check_dpdm(); cw_bat->dc_online = 0; cw_bat->usb_online = 0; cw_bat->charger_mode = 0; cw_bat->capacity = 2; cw_bat->voltage = 0; cw_bat->status = 0; cw_bat->time_to_empty = 0; cw_bat->bat_change = 0; cw_update_time_member_capacity_change(cw_bat); cw_update_time_member_charge_start(cw_bat); cw_bat->battery_workqueue = create_singlethread_workqueue("rk_battery"); INIT_DELAYED_WORK(&cw_bat->battery_delay_work, cw_bat_work); INIT_DELAYED_WORK(&cw_bat->dc_wakeup_work, dc_detect_do_wakeup); queue_delayed_work(cw_bat->battery_workqueue, &cw_bat->battery_delay_work, msecs_to_jiffies(10)); if (cw_bat->plat_data->dc_det_pin != INVALID_GPIO) { irq = gpio_to_irq(cw_bat->plat_data->dc_det_pin); irq_flags = gpio_get_value(cw_bat->plat_data->dc_det_pin) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; ret = request_irq(irq, dc_detect_irq_handler, irq_flags, "usb_detect", cw_bat); if (ret < 0) { pr_err("%s: request_irq(%d) failed\n", __func__, irq); } enable_irq_wake(irq); } #ifdef BAT_LOW_INTERRUPT INIT_DELAYED_WORK(&cw_bat->bat_low_wakeup_work, bat_low_detect_do_wakeup); wake_lock_init(&bat_low_wakelock, WAKE_LOCK_SUSPEND, "bat_low_detect"); if (cw_bat->plat_data->bat_low_pin != INVALID_GPIO) { irq = gpio_to_irq(cw_bat->plat_data->bat_low_pin); ret = request_irq(irq, bat_low_detect_irq_handler, IRQF_TRIGGER_RISING, "bat_low_detect", cw_bat); if (ret < 0) { gpio_free(cw_bat->plat_data->bat_low_pin); } enable_irq_wake(irq); } #endif dev_info(&cw_bat->client->dev, "cw2015/cw2013 driver v1.2 probe sucess\n"); return 0; rk_usb_register_fail: power_supply_unregister(&cw_bat->rk_bat); rk_ac_register_fail: power_supply_unregister(&cw_bat->rk_ac); rk_bat_register_fail: dev_info(&cw_bat->client->dev, "cw2015/cw2013 driver v1.2 probe error!!!!\n"); return ret; }