示例#1
0
static void bq27520_hw_config(struct work_struct *work)
{
	int ret = 0, flags = 0, type = 0, fw_ver = 0, status = 0;
	struct bq27520_device_info *di;

	di  = container_of(work, struct bq27520_device_info, hw_config.work);

	pr_debug(KERN_INFO "Enter bq27520_hw_config\n");
	ret = bq27520_chip_config(di);
	if (ret) {
		dev_err(di->dev, "Failed to config Bq27520 ret = %d\n", ret);
		return;
	}
	/* bq27520 is ready for access, update current_battery_status by reading
	 * from hardware
	 */
	if_notify_msm_charger(&status);
	update_current_battery_status(status);
	msm_battery_gauge_register(&bq27520_batt_gauge);
	msm_charger_notify_event(NULL, CHG_BATT_STATUS_CHANGE);

	enable_irq(di->irq);

	/* poll battery status every 3 seconds, if charging status changes,
	 * notify msm_charger
	 */
	schedule_delayed_work(&current_battery_status.poller,
				BQ27520_POLLING_STATUS);

	if (di->pdata->enable_dlog) {
		schedule_work(&di->counter);
		init_timer(&timer);
		timer.function = &bq27520_every_30secs;
		timer.data = (unsigned long)di;
		timer.expires = jiffies + BQ27520_COULOMB_POLL;
		add_timer(&timer);
	}

	bq27520_cntl_cmd(di, BQ27520_SUBCMD_CTNL_STATUS);
	udelay(66);
	bq27520_read(BQ27520_REG_CNTL, &flags, 0, di);
	bq27520_cntl_cmd(di, BQ27520_SUBCMD_DEVCIE_TYPE);
	udelay(66);
	bq27520_read(BQ27520_REG_CNTL, &type, 0, di);
	bq27520_cntl_cmd(di, BQ27520_SUBCMD_FW_VER);
	udelay(66);
	bq27520_read(BQ27520_REG_CNTL, &fw_ver, 0, di);

	dev_info(di->dev, "DEVICE_TYPE is 0x%02X, FIRMWARE_VERSION\
		is 0x%02X\n", type, fw_ver);
	dev_info(di->dev, "Complete bq27520 configuration 0x%02X\n", flags);
}
static ssize_t bq27520_read_subcmd(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	int ret, temp = 0;
	struct platform_device *client;
	struct bq27520_device_info *di;

	client = to_platform_device(dev);
	di = platform_get_drvdata(client);

	if (subcmd == BQ27520_SUBCMD_DEVCIE_TYPE ||
		 subcmd == BQ27520_SUBCMD_FW_VER ||
		 subcmd == BQ27520_SUBCMD_HW_VER ||
		 subcmd == BQ27520_SUBCMD_CHEM_ID) {

		bq27520_cntl_cmd(di, subcmd);/* Retrieve Chip status */
		udelay(66);
		ret = bq27520_read(BQ27520_REG_CNTL, &temp, 0, di);

		if (ret)
			ret = snprintf(buf, PAGE_SIZE, "Read Error!\n");
		else
			ret = snprintf(buf, PAGE_SIZE, "0x%02x\n", temp);
	} else
		ret = snprintf(buf, PAGE_SIZE, "Register Error!\n");

	return ret;
}
int bq27520_send_subcmd(struct i2c_client *client, int *rt_value, u16 sub_cmd)
{
    int ret, tmp_buf = 0;
    int retry_count = RETRY_COUNT;

    do
    {
    ret = bq27520_cntl_cmd(client, sub_cmd);
    if (ret) {
        dev_err(&client->dev, "Send subcommand 0x%04X error.\n", sub_cmd);
        retry_count--;
        msleep(I2C_RETRY_DELAY);
    }
    } while (ret && retry_count > 0);

    if (!rt_value) return ret;

    retry_count = RETRY_COUNT;
    udelay(800);
    do
    {
    /* need read data to rt_value */
    ret = bq27520_read(client, BQ27520_REG_CNTL, &tmp_buf, 0);
    if (ret)
    {
        dev_err(&client->dev, "Error!! %s subcommand %04X\n",
                         __func__, sub_cmd);
        retry_count--;
        msleep(I2C_RETRY_DELAY);
    }
    } while (ret && retry_count > 0);
    *rt_value = tmp_buf;
    return ret;
}
static int bq27520_chip_config(struct bq27520_device_info *di)
{
	int flags = 0, ret = 0;

	bq27520_cntl_cmd(di, BQ27520_SUBCMD_CTNL_STATUS);
	udelay(66);
	ret = bq27520_read(BQ27520_REG_CNTL, &flags, 0, di);
	if (ret < 0) {
		dev_err(di->dev, "error %d reading register %02x\n",
			 ret, BQ27520_REG_CNTL);
		return ret;
	}
	udelay(66);

	bq27520_cntl_cmd(di, BQ27520_SUBCMD_ENABLE_IT);
	udelay(66);

	if (di->pdata->enable_dlog && !(flags & BQ27520_CS_DLOGEN)) {
		bq27520_cntl_cmd(di, BQ27520_SUBCMD_ENABLE_DLOG);
		udelay(66);
	}

	return 0;
}