/*M-MT:read control status ss bit*/ int bq27410_read_control_status(struct i2c_client *client) { int ret = 0; int dev_type = 0; int control_status = 0; u8 buf[2]; if(g_bq27410_mode == BQ27410_NORMAL_MODE){ buf[0] = 0x00; //CONTROL_STATUS buf[1] = 0x00; bq27410_write(client,0x00,buf,2); udelay(66); ret = bq27410_read(client,0x00,buf,2); control_status = get_unaligned_le16(buf); printk("control_status=0x%x \n",control_status); buf[0] = 0x01; //CONTROL_STATUS buf[1] = 0x00; bq27410_write(client,0x00,buf,2); udelay(66); ret = bq27410_read(client,0x00,buf,2); dev_type = get_unaligned_le16(buf); DBG("dev_type = 0x%x \n",dev_type); if((control_status & BQ27410_CONTROL_STATUS_SS) && (control_status & BQ27410_CONTROL_STATUS_FAS)){ return 1; } else{ return 0; } } }
static void bq27410_exit_rom_mode(void) { struct bq27410_device_info *di; u8 buf[2]; di = bq27410_di; if(g_bq27410_mode == BQ27410_NORMAL_MODE){ /*W: AA 00 14 04*/ buf[0] = 0x14; buf[1] = 0x04; bq27410_write(di->client,0x00,buf,2); /*W: AA 00 72 36*/ buf[0] = 0x72; buf[1] = 0x36; bq27410_write(di->client,0x00,buf,2); /*W: AA 00 FF FF*/ buf[0] = 0xFF; buf[1] = 0xFF; bq27410_write(di->client,0x00,buf,2); /*W: AA 00 FF FF*/ buf[0] = 0xFF; buf[1] = 0xFF; bq27410_write(di->client,0x00,buf,2); /*X: 1000*/ msleep(1000); } }
/*M-MT:setup discharge/charge current threshold.*/ int bq27410_write_current_threshold(struct i2c_client *client) { int ret = 0; int dsg_current_threshold = 0; u8 buf[16]; // 1. unseal bq27410. bq27410_unseal_device(); // 2. write BlockDataControl command to enable block data flash control. buf[0] = 0x00; bq27410_write(client,0x61,buf,1); udelay(66); // 3. write subclass id. buf[0] = 0x51; bq27410_write(client,0x3E,buf,1); udelay(66); // 4. write subclass current offset. buf[0] = 0x00; bq27410_write(client,0x3F,buf,1); udelay(66); // 5. read old dsg current. ret = bq27410_read(client,0x40,buf,2); dsg_current_threshold = get_unaligned_le16(buf); DBG("dsg_current_threshold = 0x%x \n",dsg_current_threshold); #if 0 ret = bq27410_read(client,0x40,buf,16); { int i; for(i =0; i< 16; i++) { DBG("0x%x ",buf[i]); } DBG(" \n"); } #endif // 6. read old checksum. //ret = bq27410_read(client,0x60,buf,1); //DBG("checksum = 0x%x \n",buf[0]); #if 0 // 7. write new taper current. buf[0] = 0x00; buf[1] = 0xC8; bq27410_write(client,0x40,buf,2); udelay(66); ret = bq27410_read(client,0x40,buf,2); dsg_current_threshold = get_unaligned_le16(buf); DBG("dsg_current_threshold =0x%x \n",dsg_current_threshold); // 8. write new checksum. #endif bq27410_soft_reset(); bq27410_sealed(); return 0; }
/*M-MT:write batt insert command.*/ int bq27410_write_batt_insert(struct i2c_client *client) { int ret = 0; int control_status = 0; u8 buf[2]; int flags = 0; if(g_bq27410_mode == BQ27410_NORMAL_MODE){ buf[0] = 0x00; //CONTROL_STATUS buf[1] = 0x00; bq27410_write(client,0x00,buf,2); udelay(66); ret = bq27410_read(client,0x00,buf,2); control_status = get_unaligned_le16(buf); printk("control_status=0x%x \n",control_status); ret = bq27410_read(client,BQ27410_REG_FLAGS, buf, 2); if (ret < 0) { DBG("error reading flags\n"); return ret; } flags = get_unaligned_le16(buf); printk("1 Enter:%s --flags = 0x%x\n",__FUNCTION__,flags); if (!(flags & BQ27410_FLAG_BAT_DET)) { buf[0] = 0x0c; //batt insert buf[1] = 0x00; bq27410_write(client,0x00,buf,2); udelay(66); ret = bq27410_read(client,BQ27410_REG_FLAGS, buf, 2); if (ret < 0) { DBG("error reading flags\n"); return ret; } flags = get_unaligned_le16(buf); if (!(flags & BQ27410_FLAG_BAT_DET)){ printk("27410: %s, flags = 0x%x, set virtual_battery_enable = 1\n",__FUNCTION__,flags); virtual_battery_enable = 1; } } } return 0; }
void bq27410_soft_reset(void) { u8 buf[2]; if(g_bq27410_mode == BQ27410_NORMAL_MODE){ buf[0] = 0x41; //soft reset buf[1] = 0x00; bq27410_write(g_client,0x00,buf,2); udelay(66); } }
void bq27410_sealed(void) { int ret = 0; u8 buf[2]; if(g_bq27410_mode == BQ27410_NORMAL_MODE){ buf[0] = 0x20; //seal buf[1] = 0x00; bq27410_write(g_client,0x00,buf,2); udelay(66); ret = bq27410_read(g_client,0x00,buf,2); } }
static void bq27410_update_enter_rom_mode(void) { struct bq27410_device_info *di; u8 buf[6]; int ret = 2; di = bq27410_di; if(g_bq27410_mode == BQ27410_NORMAL_MODE){ /*W: AA 00 00 0F*/ buf[0] = 0x00; buf[1] = 0x0F; ret = bq27410_write(di->client,0x00,buf,2); } /*X: 1000*/ g_client->addr = 0x0B;//when enter rom mode,the iic addr is 0x0B msleep(1000); }
static int bq27410_update_fw(struct file *filp, char *buff, unsigned long len, void *data) { struct file * file_data = NULL; mm_segment_t old_fs; int file_len; char *data_buf = NULL; int ret; char buf[128]; char *pch = NULL; s32 base = 16; int count = 0; int wCount = 0; int xCount = 0; int cCount = 0; #define isspace(c) ((c) == ' ') file_len = update_get_flen(buff); ///Open update file. file_data = update_file_open(buff, &old_fs); if(file_data == NULL) { return -1; } data_buf = kzalloc(file_len, GFP_KERNEL); if(file_len > 0) { ret = file_data->f_op->read(file_data, data_buf, file_len, &file_data->f_pos); //printk("get file strlen(data_buf): %d.\n", strlen(data_buf)); pch = data_buf; while(count < file_len) { if(*pch == 'W') { wCount = 0; pch +=2; count +=2; while(*pch != 'W' && *pch != 'X' && *pch != 'C') { while(isspace(*pch)) { pch++; count ++; } ret = simple_strtoul(pch, NULL, base); buf[wCount] = ret; wCount++; //printk("%x ", ret); pch +=2; count +=2; while((*pch == '\r') || (*pch == '\n')) { pch +=2; count +=2; } } //printk("\n"); //printk("\n W count = %d , wCount=%d\n", count, wCount); ret = bq27410_write(g_client,buf[1],&buf[2],wCount - 2); //printk("W ret =%d ", ret); } else if(*pch == 'X') { xCount = 0; pch +=2; count +=2; while(*pch != 'W' && *pch != 'X' && *pch != 'C') { while(isspace(*pch)) { pch++; count ++; } ret = simple_strtoul(pch, NULL, 10); //printk("%d ", ret); xCount++; if(ret < 0x10) { pch +=1; count +=1; } else if(ret < 0x100){ pch +=2; count +=2; } else if(ret < 0x1000){ pch +=3; count +=3; } else if(ret < 0x10000){ pch +=4; count +=4; } while((*pch == '\r') || (*pch == '\n')) { pch +=2; count +=2; } if(ret == 4000) { count = file_len; break; } } //printk("\n X count = %d, xCount=%d \n", count, xCount); //printk("\n"); msleep(ret); } else if(*pch == 'C') { cCount = 0; pch +=2; count +=2; while(*pch != 'W' && *pch != 'X' && *pch != 'C') { while(isspace(*pch)) { pch++; count ++; } ret = simple_strtoul(pch, NULL, base); buf[cCount] = ret; //printk("%x ", ret); cCount++; pch +=2; count +=2; while((*pch == '\r') || (*pch == '\n')) { pch +=2; count +=2; break; } } //printk("\n"); //printk("\n C count = %d , cCount=%d\n", count, cCount); ret = bq27410_read(g_client,buf[1],&buf[2],cCount - 2); //printk("C ret =%d ", ret); } } } if(data_buf){ kfree(data_buf); data_buf = NULL; } ///Close file update_file_close(file_data, old_fs); return 0; }