コード例 #1
0
static int max17047_get_property(struct power_supply *psy,
			    enum power_supply_property psp,
			    union power_supply_propval *val)
{
	struct max17047_fuelgauge_data *fg_data = container_of(psy,
						  struct max17047_fuelgauge_data,
						  fuelgauge);

#ifdef USE_TRIM_ERROR_DETECTION
	if (fg_data->trim_err == true) {
		switch (psp) {
		case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		case POWER_SUPPLY_PROP_VOLTAGE_AVG:
			val->intval = 4200000;
			break;
		case POWER_SUPPLY_PROP_CAPACITY:
			val->intval = 99;
			break;
		case POWER_SUPPLY_PROP_TEMP:
			val->intval = 300;
			break;
		default:
			return -EINVAL;
		}

		return 0;
	}
#endif

	switch (psp) {
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		switch (val->intval) {
		case VOLTAGE_TYPE_VCELL:
			val->intval = max17047_get_vcell(fg_data->client);
			break;
		case VOLTAGE_TYPE_VFOCV:
			val->intval = max17047_get_vfocv(fg_data->client);
			break;
		default:
			val->intval = max17047_get_vcell(fg_data->client);
			break;
		}
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
		val->intval = max17047_get_avgvcell(fg_data->client);
		break;
	case POWER_SUPPLY_PROP_CAPACITY:
		switch (val->intval) {
		case SOC_TYPE_ADJUSTED:
			val->intval = max17047_get_soc(fg_data->client);
			break;
		case SOC_TYPE_RAW:
			val->intval = max17047_get_rawsoc(fg_data->client);
			break;
		case SOC_TYPE_FULL:
			val->intval = fg_data->full_soc;
			break;
		default:
			val->intval = max17047_get_soc(fg_data->client);
			break;
		}
		break;
	case POWER_SUPPLY_PROP_TEMP:
		val->intval = max17047_get_temperature(fg_data->client);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
コード例 #2
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;
	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_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);

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