/* * set 1 --- enable_charger; 0 --- disable charger * */ static ssize_t bq2416x_set_enable_charger(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { long val; int status = count; long int events = BQ2416x_START_CHARGING; struct bq2416x_device_info *di = dev_get_drvdata(dev); if ((strict_strtol(buf, 10, &val) < 0) || (val < 0) || (val > 1)) return -EINVAL; di->enable_ce = val ^ 0x1; di->factory_flag = val ^ 0x1; bq2416x_config_control_reg(di); if(!di->factory_flag){ events = BQ2416x_START_CHARGING; } else { events = BQ2416x_NOT_CHARGING; } blocking_notifier_call_chain(¬ifier_list, events, NULL); return status; }
static ssize_t bq2416x_set_calling_limit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { long val; int status = count; struct bq2416x_device_info *di = dev_get_drvdata(dev); if ((strict_strtol(buf, 10, &val) < 0) || (val < 0) || (val > 1)) return -EINVAL; di->calling_limit = val; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS){ if(di->calling_limit){ di->cin_limit = IINLIM_800; dev_info(di->dev,"calling_limit_current = %d\n", di->cin_limit); }else{ di->battery_temp_status = -1; di->cin_limit = di->max_cin_currentmA; } bq2416x_config_control_reg(di); } else{ di->calling_limit = 0; } return status; }
static void bq2416x_charger_update_status(struct bq2416x_device_info *di) { u8 read_reg[8] = {0}; timer_fault = 0; bq2416x_read_block(di, &read_reg[0], 0, 8); if ((read_reg[0] & 0x70) == 0x50) dev_dbg(di->dev, "CHARGE DONE\n"); if ((read_reg[0] & 0x7) == 0x4) timer_fault = 1; if (read_reg[0] & 0x7) { di->cfg_params = 1; dev_err(di->dev, "CHARGER STATUS = %x\n", read_reg[0]); } if ((read_reg[1] & 0x6) == 0x2) { di->hz_mode = 1; bq2416x_config_control_reg(di); bq2416x_write_byte(di, di->voltage_reg, REG_BATTERY_VOLTAGE); dev_err(di->dev, "battery ovp = %x,%x\n", read_reg[1],read_reg[3]); msleep(700); di->hz_mode = 0; bq2416x_config_control_reg(di); } if (is_bq27510_battery_exist(g_battery_measure_by_bq27510_device)){ bq2416x__charge_status(di); } if ((timer_fault == 1) || (di->cfg_params == 1)) { bq2416x_write_byte(di, di->control_reg, REG_CONTROL_REGISTER); bq2416x_write_byte(di, di->voltage_reg, REG_BATTERY_VOLTAGE); bq2416x_write_byte(di, di->current_reg, REG_BATTERY_CURRENT); bq2416x_write_byte(di, di->dppm_reg, REG_DPPM_VOLTAGE); bq2416x_config_safety_reg(di); di->cfg_params = 0; } /* reset 32 second timer */ bq2416x_config_status_reg(di); return; }
static void bq2416x_start_ac_charger(struct bq2416x_device_info *di) { long int events = BQ2416x_START_AC_CHARGING; /*set gpio_174 low level for CD pin to enable bq24161 IC*/ gpio_set_value(ENABLE_BQ2416x_CHARGER, 0); blocking_notifier_call_chain(¬ifier_list, events, NULL); di->charger_source = POWER_SUPPLY_TYPE_MAINS; di->charge_status = POWER_SUPPLY_STATUS_CHARGING; di->calling_limit = 0; di->factory_flag = 0; di->battery_temp_status = -1; di->dppm_voltagemV = VINDPM_MIN_4200; di->cin_limit = di->max_cin_currentmA; di->currentmA = di->max_currentmA ; di->voltagemV = di->max_voltagemV; di->term_currentmA = ITERM_MIN_50; di->enable_ce = ENABLE_CHARGER; /*enable charger*/ di->enable_iterm = ENABLE_ITERM; /*enable charge current termination*/ di->hz_mode = DIS_HIZ; di->safety_timer = TMR_X_9; di->enable_low_chg = DISABLE_LOW_CHG; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); bq2416x_config_safety_reg(di); bq2416x_config_watchdog_reg(di); schedule_delayed_work(&di->bq2416x_charger_work, msecs_to_jiffies(0)); dev_info(di->dev,"%s, ---->START AC CHARGING, \n" "battery current = %d mA\n" "battery voltage = %d mV\n" , __func__, di->currentmA, di->voltagemV); di->battery_present = is_bq27510_battery_exist(g_battery_measure_by_bq27510_device); if (!di->battery_present){ dev_info(di->dev, "BATTERY NOT DETECTED!\n"); events = BQ2416x_NOT_CHARGING; blocking_notifier_call_chain(¬ifier_list, events, NULL); di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; } di->wakelock_enabled = 1; if (di->wakelock_enabled) wake_lock(&di->charger_wake_lock); return; }
static ssize_t bq2416x_set_enable_itermination(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { long val; int status = count; struct bq2416x_device_info *di = dev_get_drvdata(dev); if ((strict_strtol(buf, 10, &val) < 0) || (val < 0) || (val > 1)) return -EINVAL; di->enable_iterm = val; bq2416x_config_control_reg(di); return status; }
/* * set 1 --- enable_charger; 0 --- disable charger * */ static ssize_t bq2416x_set_enable_charger(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { long val; int status = count; struct bq2416x_device_info *di = dev_get_drvdata(dev); if ((strict_strtol(buf, 10, &val) < 0) || (val < 0) || (val > 1)) return -EINVAL; di->enable_ce = val ^ 0x1; bq2416x_config_control_reg(di); di->factory_flag = di->enable_ce; bq2416x__charge_status(di); return status; }
/*di->enable_ce = 0,charger enable and display charging status di->enable_ce = 1 or USB supply fault,charger disable and display not charging status*/ static void bq2416x__charge_status(struct bq2416x_device_info *di) { long int events=BQ2416x_START_CHARGING; u8 read_reg[8] = {0}; int battery_capacity = 0; bq2416x_read_block(di, &read_reg[0], 0, 2); if((read_reg[1] & BQ2416x_FAULT_VBUS_VUVLO) == BQ2416x_FAULT_VBUS_OVP){ dev_err(di->dev, " POWER_SUPPLY_OVERVOLTAGE = %x\n",read_reg[1]); events = POWER_SUPPLY_OVERVOLTAGE; blocking_notifier_call_chain(¬ifier_list, events, NULL); return; } if ((read_reg[0] & BQ2416x_VUSB_FAULT) == BQ2416x_CHARGING_FROM_USB){ events = BQ2416x_START_CHARGING; } else if((di->enable_ce == DISABLE_CE) || ((read_reg[0] & POWER_SUPPLY_STATE_FAULT) == POWER_SUPPLY_STATE_FAULT)){ dev_err(di->dev, " BQ2416x_NOT_CHARGING \n"); events = BQ2416x_NOT_CHARGING; } else if((read_reg[0] & BQ2416x_VUSB_FAULT) == BQ2416x_CHARGE_DONE){ battery_capacity = bq27510_battery_capacity(g_battery_measure_by_bq27510_device); if((!is_bq27510_battery_full(g_battery_measure_by_bq27510_device))||(battery_capacity !=100)){ dev_info(di->dev, "charge_done_battery_capacity=%d\n",battery_capacity); di->hz_mode = 1; /*enable bq2416x charger high impedance mode*/ bq2416x_write_byte(di, di->control_reg | di->hz_mode, REG_CONTROL_REGISTER); di->hz_mode = 0; /*disable bq2416x charger high impedance mode*/ msleep(700); bq2416x_config_control_reg(di); events = BQ2416x_START_CHARGING; } else{ events = BQ2416x_CHARGE_DONE; } } else{ events=BQ2416x_START_CHARGING; dev_dbg(di->dev, "BQ2416x_START_CHARGING !\n"); } if(di->charger_source == POWER_SUPPLY_TYPE_BATTERY){ return; } blocking_notifier_call_chain(¬ifier_list, events, NULL); }
void bq2416x_open_inner_fet(struct bq2416x_device_info *di) { u8 en_nobatop = 0; bq2416x_read_byte(di, &en_nobatop, REG_BATTERY_AND_SUPPLY_STATUS); if(g_battery_measure_by_bq27510_device && is_bq27510_battery_exist(g_battery_measure_by_bq27510_device) ){ di->enable_iterm = ENABLE_ITERM; en_nobatop = en_nobatop & (~EN_NOBATOP); }else { di->enable_iterm = DISABLE_ITERM; en_nobatop = en_nobatop | EN_NOBATOP; } bq2416x_config_control_reg(di); bq2416x_write_byte(di, en_nobatop, REG_BATTERY_AND_SUPPLY_STATUS); }
static ssize_t bq2416x_set_cin_limit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { long val; int status = count; struct bq2416x_device_info *di = dev_get_drvdata(dev); if ((strict_strtol(buf, 10, &val) < 0) || (val < 100) || (val > di->max_currentmA)) return -EINVAL; di->cin_limit = val; bq2416x_config_control_reg(di); return status; }
static void bq2416x_open_inner_fet(struct bq2416x_device_info *di) { u8 en_nobatop = 0; bq2416x_read_byte(di, &en_nobatop, REG_BATTERY_AND_SUPPLY_STATUS_REG01); if(di->battery_present){ di->enable_iterm = ENABLE_ITERM; en_nobatop = en_nobatop & (~EN_NOBATOP); }else { di->enable_iterm = DISABLE_ITERM; en_nobatop = en_nobatop | EN_NOBATOP; } bq2416x_config_control_reg(di); bq2416x_write_byte(di, en_nobatop, REG_BATTERY_AND_SUPPLY_STATUS_REG01); }
static void bq2416x_start_ac_charger(struct bq2416x_device_info *di) { long int events; /*set gpio_174 low level for CD pin to enable bq24161 IC*/ gpio_set_value(BQ2416X_GPIO_174, 0); events = BQ2416x_START_AC_CHARGING; blocking_notifier_call_chain(¬ifier_list, events, NULL); di->enable_ce = ENABLE_CE; /*enable charger*/ di->enable_iterm = ENABLE_ITERM; /*enable charge current termination*/ if(! g_battery_measure_by_bq27510_device) return ; di->charger_source = POWER_SUPPLY_TYPE_MAINS; di->charge_status = POWER_SUPPLY_STATUS_CHARGING; di->calling_limit = set_zero; di->dppm_voltagemV = VOLT_DPPM_ADJUST_AC; di->cin_limit = CURRENT_AC_LIMIT_IN; di->currentmA = di->max_currentmA ; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); #if BQ2416X_USE_WAKE_LOCK wake_lock(&di->charger_wake_lock); #endif schedule_delayed_work(&di->bq2416x_charger_work, msecs_to_jiffies(0)); dev_info(di->dev,"%s, ---->START AC CHARGING, \n" "battery current = %d mA\n" "battery voltage = %d mV\n" , __func__, di->currentmA, di->voltagemV); if (!is_bq27510_battery_exist(g_battery_measure_by_bq27510_device)){ dev_dbg(di->dev, "BATTERY NOT DETECTED!\n"); events = BQ2416x_NOT_CHARGING; blocking_notifier_call_chain(¬ifier_list, events, NULL); di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; di->enable_low_chg = DISABLE_LOW_CHG; bq2416x_config_safety_reg(di); } }
static void bq2416x_stop_charger(struct bq2416x_device_info *di) { long int events; dev_info(di->dev,"%s,---->STOP CHARGING\n", __func__); di->calling_limit = set_zero; di->enable_hotcold_temp_charge = set_one; di->factory_flag = set_zero; di->enable_ce = DISABLE_CE; di->hz_mode = set_zero; /*not high impedance mode*/ bq2416x_config_control_reg(di); #if BQ2416X_USE_WAKE_LOCK if (POWER_SUPPLY_TYPE_MAINS == di->charger_source) wake_unlock(&di->charger_wake_lock); #endif di->charger_source = POWER_SUPPLY_TYPE_BATTERY; di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; cancel_delayed_work_sync(&di->bq2416x_charger_work); events = BQ2416x_STOP_CHARGING; blocking_notifier_call_chain(¬ifier_list, events, NULL); /*set gpio_174 high level for CD pin to disable bq24161 IC */ gpio_set_value(BQ2416X_GPIO_174, 1); }
static int bq2416x_charger_event(struct notifier_block *nb, unsigned long event, void *_data) { printk("%s,---->enter bq2416x_charger_event\n", __func__); struct bq2416x_device_info *di; struct charge_params *data; u8 read_reg[8] = {0}; int ret = 0; di = container_of(nb, struct bq2416x_device_info, nb); data = &di->params; di->cfg_params = 1; if (event & BQ2416x_CHARGER_FAULT) { bq2416x_read_block(di, &read_reg[0], 0, 8); ret = read_reg[0] & 0x7F; return ret; } if (data->enable == 0) { di->currentmA = data->currentmA; di->voltagemV = data->voltagemV; di->enable_iterm = data->enable_iterm; } if ((event & BQ2416x_DEFAULT_USB_CHARGING ) && (di->active == 0)) { di->cin_limit = 500; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); schedule_delayed_work(&di->bq2416x_charger_work, msecs_to_jiffies(0)); di->active = 1; } if ((event & BQ2416x_START_AC_CHARGING) && (di->active == 0)) { di->cin_limit = 1000; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); printk("%s, charging with VAC\n", __func__); schedule_delayed_work(&di->bq2416x_charger_work, msecs_to_jiffies(0)); di->active = 1; } if ((event & BQ2416x_START_USB_CHARGING) && (di->active == 0)) { di->cin_limit = 500; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); printk("%s, charging with USB\n", __func__); schedule_delayed_work(&di->bq2416x_charger_work, msecs_to_jiffies(0)); di->active = 1; } if (event & BQ2416x_STOP_CHARGING) { cancel_delayed_work(&di->bq2416x_charger_work); di->active = 0; } if (event & BQ2416x_RESET_TIMER) { /* reset 32 second timer */ bq2416x_config_status_reg(di); } return ret; }
/*small current charging(100mA) when low battery voltage or low battery temprature*/ static void bq2416x_low_current_charge(struct bq2416x_device_info *di) { int battery_voltage = 0; int battery_temperature = 0; if (!is_bq27510_battery_exist(g_battery_measure_by_bq27510_device)) return; battery_voltage = bq27510_battery_voltage(g_battery_measure_by_bq27510_device); battery_temperature = bq27510_battery_temperature(g_battery_measure_by_bq27510_device); if (battery_temperature < BQ2416x_COLD_BATTERY_THRESHOLD){ dev_dbg(di->dev, "battery temp less than -10 degree,disable charging\n"); di->enable_ce = DISABLE_CE; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS){ if(di->calling_limit){ di->cin_limit = CURRENT_AC_LIMIT_IN_800; } else{ di->cin_limit = CURRENT_AC_LIMIT_IN; } } else di->cin_limit = CURRENT_USB_LIMIT_IN; } else if ((battery_temperature >= BQ2416x_COLD_BATTERY_THRESHOLD) && (battery_temperature < BQ2416x_COOL_BATTERY_THRESHOLD)){ /*battery temp is between -10 and 0 degree,or battery voltage is less than 3.0V*/ di->enable_low_chg = ENABLE_LOW_CHG;/*enable low charge,100mA charging*/ bq2416x_config_safety_reg(di); if (di->charger_source == POWER_SUPPLY_TYPE_MAINS){ if(di->calling_limit){ di->cin_limit = CURRENT_AC_LIMIT_IN_800; } else{ di->cin_limit = CURRENT_AC_LIMIT_IN; } } else di->cin_limit = CURRENT_USB_LIMIT_IN; if(battery_voltage < BQ2416x_LOW_TEMP_TERM_VOLTAGE){ di->enable_ce = ENABLE_CE; } else{ di->enable_ce = DISABLE_CE; } } else if ((battery_temperature >= BQ2416x_COOL_BATTERY_THRESHOLD) && (battery_temperature < (BQ2416x_WARM_BATTERY_THRESHOLD - TEMPERATURE_OFFSET))){ /*battery temp is between 00 and 50 degree,normal charge*/ di->enable_low_chg = DISABLE_LOW_CHG;/*normal charge*/ bq2416x_config_safety_reg(di); di->enable_ce = ENABLE_CE; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS){ if(di->calling_limit){ di->cin_limit = CURRENT_AC_LIMIT_IN_800; } else{ di->cin_limit = CURRENT_AC_LIMIT_IN; } } else di->cin_limit = CURRENT_USB_LIMIT_IN; } else if ((battery_temperature >= BQ2416x_WARM_BATTERY_THRESHOLD) && (battery_temperature < BQ2416x_HOT_BATTERY_THRESHOLD )){ /*battery temp is between 00 and 50 degree,normal charge*/ di->enable_low_chg = DISABLE_LOW_CHG;/*normal charge*/ bq2416x_config_safety_reg(di); di->enable_ce = ENABLE_CE; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS) di->cin_limit = CURRENT_AC_LIMIT_IN_800; else di->cin_limit = CURRENT_USB_LIMIT_IN; } else if (battery_temperature >= BQ2416x_HOT_BATTERY_THRESHOLD) { dev_dbg(di->dev, "battery temp more than 50 degree,disable charging\n"); di->enable_ce = DISABLE_CE; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS) di->cin_limit = CURRENT_AC_LIMIT_IN_800; else di->cin_limit = CURRENT_USB_LIMIT_IN; } else{ di->cin_limit = di->cin_limit; } di->enable_ce = (di->enable_ce | di->factory_flag); bq2416x_config_control_reg(di); return; }
static void bq2416x_charger_update_status(struct bq2416x_device_info *di) { u8 read_reg[8] = {0}; long int events=BQ2416x_START_CHARGING; static int battery_capacity = 0; di->timer_fault = 0; bq2416x_read_block(di, &read_reg[0], 0, 8); if((read_reg[1] & BQ2416x_FAULT_VBUS_VUVLO) == BQ2416x_FAULT_VBUS_OVP){ dev_err(di->dev, "bq2416x charger over voltage = %x\n",read_reg[1]); events = POWER_SUPPLY_OVERVOLTAGE; blocking_notifier_call_chain(¬ifier_list, events, NULL); } if ((read_reg[0] & BQ2416x_CHARGE_FAULT) == BQ2416x_STATUS_CHARGE_DONE){ dev_dbg(di->dev, "CHARGE DONE\n"); battery_capacity = bq27510_battery_capacity(g_battery_measure_by_bq27510_device); if (((!is_bq27510_battery_full(g_battery_measure_by_bq27510_device))||(battery_capacity!=100))&& (di->battery_present)){ dev_info(di->dev, "charge_done_battery_capacity=%d\n",battery_capacity); di->hz_mode = EN_HIZ; bq2416x_write_byte(di, di->control_reg02 | di->hz_mode, REG_CONTROL_REGISTER_REG02); msleep(500); di->hz_mode = DIS_HIZ; bq2416x_config_control_reg(di); events = BQ2416x_START_CHARGING; }else{ events = BQ2416x_CHARGE_DONE; } blocking_notifier_call_chain(¬ifier_list, events, NULL); } if ((read_reg[0] & BQ2416x_FAULT_BATTERY) == BQ2416x_FAULT_WATCHDOG_TIMER){ di->timer_fault = 1; } if ((read_reg[0] & BQ2416x_FAULT_BATTERY) == BQ2416x_FAULT_SAFETY_TIMER) di->timer_fault = 1; if (read_reg[0] & BQ2416x_FAULT_BATTERY) { di->cfg_params = 1; dev_err(di->dev, "CHARGER STATUS %x\n", read_reg[0]); } if ((read_reg[1] & 0x6) == BQ2416x_FAULT_BAT_OVP) { gpio_set_value(ENABLE_BQ2416x_CHARGER, 1); dev_err(di->dev, "battery ovp = %x,%x\n", read_reg[1],read_reg[3]); msleep(1000); gpio_set_value(ENABLE_BQ2416x_CHARGER, 0); } if ((di->timer_fault == 1) || (di->cfg_params == 1)) { bq2416x_write_byte(di, di->control_reg02, REG_CONTROL_REGISTER_REG02); bq2416x_write_byte(di, di->voltage_reg03, REG_BATTERY_VOLTAGE_REG03); bq2416x_write_byte(di, di->current_reg05, REG_BATTERY_CURRENT_REG05); bq2416x_write_byte(di, di->dppm_reg06, REG_DPPM_VOLTAGE_REG06); bq2416x_config_safety_reg(di); di->cfg_params = 0; } /* reset 32 second timer */ bq2416x_config_status_reg(di); return; }
static void bq2416x_monitor_battery_ntc_charging(struct bq2416x_device_info *di) { int battery_voltage = 0; int battery_status = 0; long int events = BQ2416x_START_CHARGING; if(!di->battery_present){ blocking_notifier_call_chain(¬ifier_list, BQ2416x_NOT_CHARGING, NULL); return; } battery_voltage = bq27510_battery_voltage(g_battery_measure_by_bq27510_device); //battery_voltage = battery_voltage/VOLTAGE_MULTIPLE; battery_status = bq2416x_check_battery_temperature_threshold(); switch (battery_status) { case BATTERY_HEALTH_TEMPERATURE_OVERLOW: di->enable_ce = DISABLE_CHARGER; break; case BATTERY_HEALTH_TEMPERATURE_LOW: if(battery_voltage > BQ2416x_LOW_TEMP_TERM_VOLTAGE){ di->enable_ce = DISABLE_CHARGER; }else{ di->enable_ce = ENABLE_CHARGER; } di->enable_low_chg = ENABLE_LOW_CHG; break; case BATTERY_HEALTH_TEMPERATURE_NORMAL: di->enable_ce = ENABLE_CHARGER; di->enable_low_chg = DISABLE_LOW_CHG; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS){ bq2416x_calling_limit_ac_input_current(di,0); } break; case BATTERY_HEALTH_TEMPERATURE_NORMAL_HIGH: di->enable_ce = ENABLE_CHARGER; di->enable_low_chg = DISABLE_LOW_CHG; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS){ if(di->battery_temp_status == BATTERY_HEALTH_TEMPERATURE_NORMAL){ bq2416x_calling_limit_ac_input_current(di,0); }else{ di->cin_limit = di->cin_limit; } } break; case BATTERY_HEALTH_TEMPERATURE_HIGH: di->enable_ce = ENABLE_CHARGER; di->enable_low_chg = DISABLE_LOW_CHG; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS){ di->cin_limit = IINLIM_800; } break; case BATTERY_HEALTH_TEMPERATURE_OVERHIGH: di->enable_ce = DISABLE_CHARGER; di->enable_low_chg = DISABLE_LOW_CHG; if (di->charger_source == POWER_SUPPLY_TYPE_MAINS){ di->cin_limit = IINLIM_800; } break; default: break; } di->enable_ce = di->enable_ce | di->factory_flag; if(!di->enable_ce){ events = BQ2416x_START_CHARGING; }else{ events = BQ2416x_NOT_CHARGING; } bq2416x_config_control_reg(di); bq2416x_config_safety_reg(di); di->battery_temp_status = battery_status; blocking_notifier_call_chain(¬ifier_list, events, NULL); return; }
static int __devinit bq2416x_charger_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bq2416x_device_info *di; struct bq2416x_platform_data *pdata = client->dev.platform_data; int ret; u8 read_reg = 0; enum plugin_status plugin_stat; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; di->dev = &client->dev; di->client = client; i2c_set_clientdata(client, di); ret = bq2416x_read_byte(di, &read_reg, REG_PART_REVISION); if (ret < 0) { dev_err(&client->dev, "chip not present at address %x\n", client->addr); ret = -EINVAL; goto err_kfree; } #if 0 if ((read_reg & 0x18) == 0x00 && (client->addr == 0x6a)) di->bqchip_version = BQ24156; #endif if ((read_reg & 0x18) == 0x00 && (client->addr == 0x6b)) di->bqchip_version = BQ24161; if (di->bqchip_version == 0) { dev_dbg(&client->dev, "unknown bq chip\n"); dev_dbg(&client->dev, "Chip address %x", client->addr); dev_dbg(&client->dev, "bq chip version reg value %x", read_reg); ret = -EINVAL; goto err_kfree; } // di->nb.notifier_call = bq2416x_charger_event; #if 0 bq2415x_config_safety_reg(di, pdata->max_charger_currentmA, pdata->max_charger_voltagemV); di->cin_limit = 900; di->term_currentmA = pdata->termination_currentmA; bq2415x_config_control_reg(di); bq2415x_config_voltage_reg(di); bq2415x_config_current_reg(di); #endif /*set gpio_174 to control CD pin to disable/enable bq24161 IC*/ gpio_request(BQ2416X_GPIO_174, "gpio_174_cd"); /* set charger CD pin to low level and enable it to supply power normally*/ gpio_direction_output(BQ2416X_GPIO_174, 0); ret = bq2416x_get_max_charge_voltage(di); if(!ret){ di->max_voltagemV = pdata->max_charger_voltagemV; } di->voltagemV = di->max_voltagemV; ret = bq2416x_get_max_charge_current(di); if(!ret){ di->max_currentmA = pdata->max_charger_currentmA; } di->currentmA = CURRENT_USB_CHARGE_IN ; di->term_currentmA = CURRENT_TERM_CHARGE_IN; di->dppm_voltagemV = VOLT_DPPM_ADJUST; di->cin_limit = CURRENT_USB_LIMIT_IN; di->enable_hotcold_temp_charge = set_one; di->enable_low_chg = DISABLE_LOW_CHG;/*set normally charge mode*/ di->enable_iterm = ENABLE_ITERM; /*enable charge current termination*/ di->factory_flag = 0; di->enable_ce = ENABLE_CE; di->hz_mode = 0; di->cd_active = 0; INIT_DELAYED_WORK_DEFERRABLE(&di->bq2416x_charger_work, bq2416x_charger_work); #if BQ2416X_USE_WAKE_LOCK wake_lock_init(&di->charger_wake_lock, WAKE_LOCK_SUSPEND, "charger_wake_lock"); #endif //BLOCKING_INIT_NOTIFIER_HEAD(¬ifier_list); di->active = 0; di->params.enable = 1; di->cfg_params = 1; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); bq2416x_config_safety_reg(di); #if 0 ret = bq2416x_read_byte(di, &read_reg, REG_SPECIAL_CHARGER_VOLTAGE); if (!(read_reg & 0x08)) { di->active = 1; schedule_delayed_work(&di->bq2415x_charger_work, 0); } #endif ret = sysfs_create_group(&client->dev.kobj, &bq2416x_attr_group); if (ret) dev_dbg(&client->dev, "could not create sysfs files\n"); //twl6030_register_notifier(&di->nb, 1); INIT_WORK(&di->usb_work, bq2416x_usb_charger_work); //r00186667, 2011/08/02, otg register for receive USB/AC plugin event.begin di->nb_otg.notifier_call = bq2416x_usb_notifier_call; di->otg = otg_get_transceiver(); ret = otg_register_notifier(di->otg, &di->nb_otg); if (ret) dev_err(&client->dev, "otg register notifier failed %d\n", ret); //r00186667, 2011/08/02, otg register for receive USB/AC plugin event.end //r00186667, 2011/08/02, get the boot event type.begin plugin_stat = get_plugin_device_status(); if( PLUGIN_USB_CHARGER == plugin_stat){ di->event = USB_EVENT_VBUS; }else if (PLUGIN_AC_CHARGER == plugin_stat){ di->event = USB_EVENT_CHARGER; }else{ di->event = USB_EVENT_NONE; } schedule_work(&di->usb_work); //r00186667, 2011/08/02, get the boot event type.end return 0; err_kfree: kfree(di); return ret; }
static int __devinit bq2416x_charger_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bq2416x_device_info *di; struct bq2416x_platform_data *pdata = client->dev.platform_data; int ret; u8 read_reg = 0; enum plugin_status plugin_stat; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) return -ENOMEM; di->dev = &client->dev; di->client = client; i2c_set_clientdata(client, di); ret = bq2416x_read_byte(di, &read_reg, REG_PART_REVISION_REG04); if (ret < 0) { dev_err(&client->dev, "chip not present at address %x\n", client->addr); ret = -EINVAL; goto err_kfree; } if ((read_reg & 0x18) == 0x00 && (client->addr == 0x6b)) di->bqchip_version = BQ24161; if (di->bqchip_version == 0) { dev_dbg(&client->dev, "unknown bq chip\n"); dev_dbg(&client->dev, "Chip address %x", client->addr); dev_dbg(&client->dev, "bq chip version reg value %x", read_reg); ret = -EINVAL; goto err_kfree; } // di->nb.notifier_call = bq2416x_charger_event; /*set gpio_174 to control CD pin to disable/enable bq24161 IC*/ gpio_request(ENABLE_BQ2416x_CHARGER, "gpio_174_cd"); /* set charger CD pin to low level and enable it to supply power normally*/ gpio_direction_output(ENABLE_BQ2416x_CHARGER, 0); ret = bq2416x_get_max_charge_voltage(di); if(!ret){ di->max_voltagemV = pdata->max_charger_voltagemV; } ret = bq2416x_get_max_charge_current(di); if(!ret){ di->max_currentmA = pdata->max_charger_currentmA; } di->max_cin_currentmA = IINLIM_1000; di->voltagemV = di->max_voltagemV; di->currentmA = ICHG_MIN_550 ; di->term_currentmA = ITERM_MIN_50; di->dppm_voltagemV = VINDPM_MIN_4200; di->cin_limit = IINLIM_500; di->safety_timer = TMR_X_9; di->enable_low_chg = DISABLE_LOW_CHG;/*set normally charge mode*/ di->enable_iterm = ENABLE_ITERM; /*enable charge current termination*/ di->supply_sel = SUPPLY_SEL_IN; di->factory_flag = 0; di->enable_ce = ENABLE_CHARGER; di->hz_mode = DIS_HIZ; di->cd_active = 0; INIT_DELAYED_WORK_DEFERRABLE(&di->bq2416x_charger_work, bq2416x_charger_work); wake_lock_init(&di->charger_wake_lock, WAKE_LOCK_SUSPEND, "charger_wake_lock"); //BLOCKING_INIT_NOTIFIER_HEAD(¬ifier_list); di->params.enable = 1; di->cfg_params = 1; bq2416x_config_control_reg(di); bq2416x_config_voltage_reg(di); bq2416x_config_current_reg(di); bq2416x_config_dppm_voltage_reg(di,di->dppm_voltagemV); bq2416x_config_safety_reg(di); ret = sysfs_create_group(&client->dev.kobj, &bq2416x_attr_group); if (ret) dev_dbg(&client->dev, "could not create sysfs files\n"); //twl6030_register_notifier(&di->nb, 1); INIT_WORK(&di->usb_work, bq2416x_usb_charger_work); di->nb_otg.notifier_call = bq2416x_usb_notifier_call; di->otg = otg_get_transceiver(); ret = otg_register_notifier(di->otg, &di->nb_otg); if (ret) dev_err(&client->dev, "otg register notifier failed %d\n", ret); plugin_stat = get_plugin_device_status(); if( PLUGIN_USB_CHARGER == plugin_stat){ di->event = USB_EVENT_VBUS; }else if (PLUGIN_AC_CHARGER == plugin_stat){ di->event = USB_EVENT_CHARGER; }else{ di->event = USB_EVENT_NONE; } schedule_work(&di->usb_work); return 0; err_kfree: kfree(di); return ret; }