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(¤t_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; }