static int max17047_set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val) { struct max17047_fuelgauge_data *fg_data = container_of(psy, struct max17047_fuelgauge_data, fuelgauge); switch (psp) { case POWER_SUPPLY_PROP_CAPACITY: max17047_reset_soc(fg_data->client); break; case POWER_SUPPLY_PROP_STATUS: if (val->intval != POWER_SUPPLY_STATUS_FULL) return -EINVAL; pr_info("%s: charger full state!\n", __func__); /* adjust full soc */ max17047_adjust_fullsoc(fg_data->client); break; default: return -EINVAL; } return 0; }
static int max17047_set_property(struct power_supply *psy, enum power_supply_property psp, const union power_supply_propval *val) { struct max17047_fuelgauge_data *fg_data = container_of(psy, struct max17047_fuelgauge_data, fuelgauge); switch (psp) { case POWER_SUPPLY_PROP_CAPACITY: max17047_reset_soc(fg_data->client); break; case POWER_SUPPLY_PROP_STATUS: if (val->intval != POWER_SUPPLY_STATUS_FULL) return -EINVAL; pr_info("%s: charger full state!\n", __func__); /* adjust full soc */ max17047_adjust_fullsoc(fg_data->client); break; #if defined(CONFIG_MACH_GC1) || defined(CONFIG_MACH_GD2) || defined(CONFIG_GC2PD_LTE) case POWER_SUPPLY_PROP_RCOMP: if (fg_data->prev_status == val->intval) { pr_debug("%s: No rcomp change, prev(%d) = cur(%d)\n", __func__, fg_data->prev_status, val->intval); } else { if (val->intval == POWER_SUPPLY_STATUS_CHARGING) max17047_set_rcomp(fg_data->client, 1); else max17047_set_rcomp(fg_data->client, 0); max17047_get_rcomp(fg_data->client, val->intval); fg_data->prev_status = val->intval; } break; #endif default: return -EINVAL; } return 0; }
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; int ret; u8 i2c_data[2]; int rawsoc, firstsoc; pr_info("%s: max17047 Fuel gauge Driver Loading\n", __func__); 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 = client->dev.platform_data; 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"); /* 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"; fg_data->fuelgauge.type = POWER_SUPPLY_TYPE_BATTERY; 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); /* 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; } INIT_DELAYED_WORK_DEFERRABLE(&fg_data->update_work, max17047_update_work); #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 max17047_i2c_read(client, MAX17047_REG_VERSION, i2c_data); pr_info("max17047 fuelgauge(rev.%d%d) initialized.\n", i2c_data[0], i2c_data[1]); #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; }