void battery_callback() { if (!charging_allowed) return; adc_configure(&batt_adc_config); BATTERY_VOLTAGE_TRIS = 1; BATTERY_VOLTAGE_DIGITAL = 0; adc_set_channel(1); last_battery_voltage = adc_convert_one(); //Disable charging if battery voltage is greater than max charge level if (last_battery_voltage >= kBatteryChargedLevel) disable_charging(); else if (last_battery_voltage < kBatteryHysteresisLevel) //Reenable charging once battery level falls below hysteresis enable_charging(); }
static void change_charge_status(int status) { switch (status) { case POWER_SUPPLY_STATUS_UNKNOWN: case POWER_SUPPLY_STATUS_NOT_CHARGING: case POWER_SUPPLY_STATUS_DISCHARGING: if (sec_bci->battery.battery_health != POWER_SUPPLY_HEALTH_DEAD) disable_charging(); #ifdef HIGH_TEMP_GAURD_FOR_CAMCORDER sec_bci->charger.camera_recording_inout = 0; #endif break; case POWER_SUPPLY_STATUS_FULL: break; case POWER_SUPPLY_STATUS_FULL_END: sec_bci->charger.rechg_count = 4; /*Cancel timer */ clear_charge_start_time(); disable_charging(); break; case POWER_SUPPLY_STATUS_CHARGING: if (sec_bci->battery.battery_vf_ok) { sec_bci->battery.battery_health = POWER_SUPPLY_HEALTH_GOOD; /*Start monitoring charging time */ set_charge_start_time(); enable_charging(); break; } else { sec_bci->battery.battery_health = POWER_SUPPLY_HEALTH_DEAD; status = POWER_SUPPLY_STATUS_DISCHARGING; printk( KERN_INFO "[TA] INVALID BATTERY, %d !! \n", status); disable_charging(); break; } case POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL: /*Start monitoring charging time */ sec_bci->charger.charging_timeout = DEFAULT_RECHARGING_TIMEOUT; set_charge_start_time(); enable_charging(); break; case POWER_SUPPLY_STATUS_RECHARGING_FOR_TEMP: enable_charging(); break; default: ; } sec_bci->charger.prev_charge_status = sec_bci->charger.charge_status; sec_bci->charger.charge_status = status; _charger_state_change_(STATUS_CATEGORY_CHARGING, status); }
int _battery_state_change_(int category, int value) { struct charger_device_info *di; struct platform_device *pdev; int state; pdev = to_platform_device(this_dev); di = platform_get_drvdata(pdev); printk( KERN_INFO "[TA] cate: %d, value: %d, %s\n", category, value, di->dev->kobj.name ); switch (category) { case STATUS_CATEGORY_TEMP: switch (value) { case BATTERY_TEMPERATURE_NORMAL: printk( KERN_INFO "[TA] Charging re start normal TEMP!!\n"); change_charge_status(POWER_SUPPLY_STATUS_RECHARGING_FOR_TEMP); break; case BATTERY_TEMPERATURE_LOW: printk( KERN_INFO "[TA] Charging stop LOW TEMP!!\n"); change_charge_status(POWER_SUPPLY_STATUS_NOT_CHARGING); break; case BATTERY_TEMPERATURE_HIGH: printk( KERN_INFO "[TA] Charging stop HI TEMP!!\n"); change_charge_status(POWER_SUPPLY_STATUS_NOT_CHARGING); break; #ifdef HIGH_TEMP_GAURD_FOR_CAMCORDER case BATTERY_TEMPERATURE_ETC: if(sec_bci->charger.camera_recording && sec_bci->charger.camera_recording_inout){ printk( KERN_INFO "[TA] Charger is set to the USB mode\n"); state = sec_bci->charger.cable_status; sec_bci->charger.cable_status = POWER_SUPPLY_TYPE_USB; enable_charging(); sec_bci->charger.cable_status = state; break; } else { printk( KERN_INFO "[TA] Charger is set to the original mode\n"); enable_charging(); break; } #endif default: break; } break; case STATUS_CATEGORY_CHARGING: switch (value) { case POWER_SUPPLY_STATUS_FULL: printk( KERN_INFO "[TA] Charge FULL(#1)! (monitoring charge current)\n"); change_charge_status(POWER_SUPPLY_STATUS_FULL); break; case POWER_SUPPLY_STATUS_FULL_END: printk( KERN_INFO "[TA] Charge FULL(#2)! (monitoring charge current)\n"); change_charge_status(POWER_SUPPLY_STATUS_FULL_END); break; case POWER_SUPPLY_STATUS_CHARGING_OVERTIME: printk( KERN_INFO "[TA] CHARGING TAKE OVER 6 hours !!\n"); change_charge_status(POWER_SUPPLY_STATUS_FULL_END); break; case POWER_SUPPLY_STATUS_FULL_DUR_SLEEP: printk( KERN_INFO "[TA] Charge FULL!\n"); change_charge_status(POWER_SUPPLY_STATUS_FULL); break; case POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL: printk( KERN_INFO "[TA] Re-Charging Start!!\n"); change_charge_status(POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL); break; default: break; } break; case STATUS_CATEGORY_ETC: switch (value) { case ETC_CABLE_IS_DISCONNECTED: printk( KERN_INFO "[TA] CABLE IS NOT CONNECTED.... Charge Stop!!\n"); change_cable_status(POWER_SUPPLY_TYPE_BATTERY, di); break; default: break; } break; default: printk( KERN_INFO "[TA] Invalid category!!!!!\n"); break; } return 0; }
void charger_task(void) { int next_state; int wait_time = T1_USEC; timestamp_t pre_chg_start = get_time(); pmu_init(); /* Enable low current charging */ pmu_low_current_charging(1); /* Enable charger interrupt */ gpio_enable_interrupt(GPIO_CHARGER_INT_L); /* * EC STOP mode support * The charging loop can be stopped in idle state with AC unplugged. * Charging loop will be resumed by TPSCHROME interrupt. */ enable_charging(0); disable_sleep(SLEEP_MASK_CHARGING); while (1) { last_waken = get_time(); pmu_clear_irq(); #ifdef CONFIG_PMU_TPS65090_CHARGING_LED update_battery_led(); #endif /* * When battery is extremely low, the internal voltage can not * power on its gas guage IC. Charging loop will enable the * charger and turn on trickle charging. For safty reason, * charger should be disabled if the communication to battery * failed. */ if (current_state == ST_PRE_CHARGING && get_time().val - pre_chg_start.val >= PRE_CHARGING_TIMEOUT) next_state = ST_CHARGING_ERROR; else next_state = calc_next_state(current_state); if (next_state != current_state) { /* Reset state of charge moving average window */ rsoc_moving_average(-1); CPRINTS("batt state %s -> %s", state_list[current_state], state_list[next_state]); current_state = next_state; switch (current_state) { case ST_PRE_CHARGING: pre_chg_start = get_time(); /* Fall through */ case ST_CHARGING: if (pmu_blink_led(0)) next_state = ST_CHARGING_ERROR; else enable_charging(1); break; case ST_CHARGING_ERROR: /* * Enable hardware charging circuit after set * PMU to hardware error state. */ if (pmu_blink_led(1)) enable_charging(0); else enable_charging(1); break; case ST_IDLE: case ST_IDLE0: case ST_BAD_COND: case ST_DISCHARGING: enable_charging(0); /* Ignore charger error when discharging */ pmu_blink_led(0); break; } } switch (current_state) { case ST_CHARGING: case ST_CHARGING_ERROR: wait_time = T2_USEC; break; case ST_DISCHARGING: wait_time = T3_USEC; break; case ST_PRE_CHARGING: wait_time = T1_USEC; if (get_time().val - pre_chg_start.val >= PRE_CHARGING_TIMEOUT) enable_charging(0); break; default: if (extpower_is_present()) { wait_time = T1_USEC; break; } else if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { wait_time = T1_OFF_USEC; enable_sleep(SLEEP_MASK_CHARGING); } else if (chipset_in_state(CHIPSET_STATE_SUSPEND)) { wait_time = T1_SUSPEND_USEC; } else { wait_time = T1_USEC; } } if (!has_pending_event) { task_wait_event(wait_time); disable_sleep(SLEEP_MASK_CHARGING); } else { has_pending_event = 0; } } }
static bool check_battery_vf( void ) { int count = 0; int val; bool ret = false; #if 0 count = 0; disable_charging( CHARGE_DUR_ACTIVE ); msleep( 100 ); enable_charging( CHARGE_DUR_ACTIVE ); val = gpio_get_value( KCHG_ING_GPIO ); if ( !val ) return true; while ( count < 10 ) { if ( !gpio_get_value( KCHG_ING_GPIO ) ) return true; count++; msleep( 1 ); } if ( !ret && device_config->VF_CHECK_USING_ADC ) { #if 0 int i; int val[5]; for ( i = 0; i < 5 ; i++ ) { val[i] = _get_t2adc_data_( device_config->VF_ADC_PORT ); } count = _get_average_value_( val, 5 ); #else count = _get_t2adc_data_( device_config->VF_ADC_PORT ); #endif printk("vf: %d\n", count); if ( count < 100 ) return true; } disable_charging( CHARGE_DUR_ACTIVE ); #elif 0 if ( device_config->VF_CHECK_USING_ADC ) { int i; int val[5]; for ( i = 0; i < 5 ; i++ ) { val[i] = _get_t2adc_data_( device_config->VF_ADC_PORT ); if ( val[i] >= 100 ) { printk( "vf: %d\n", val[i] ); return false; } msleep( 100 ); } count = _get_average_value_( val, 5 ); printk("vf: %d\n", count); if ( count < 100 ) return true; /* count = _get_t2adc_data_( device_config->VF_ADC_PORT ); printk("vf: %d\n", count); if ( count < 100 ) return true;*/ } else { count = 0; disable_charging( CHARGE_DUR_ACTIVE ); msleep( 100 ); enable_charging( CHARGE_DUR_ACTIVE ); val = gpio_get_value( KCHG_ING_GPIO ); if ( !val ) return true; while ( count < 10 ) { if ( !gpio_get_value( KCHG_ING_GPIO ) ) return true; count++; msleep( 1 ); } disable_charging( CHARGE_DUR_ACTIVE ); } #else count = 0; disable_charging( CHARGE_DUR_ACTIVE ); msleep( 100 ); enable_charging( CHARGE_DUR_ACTIVE ); val = gpio_get_value( KCHG_ING_GPIO ); if ( !val ) { ret = true; } while ( count < 10 ) { if ( !gpio_get_value( KCHG_ING_GPIO ) ) { ret = true; break; } count++; msleep( 1 ); } disable_charging( CHARGE_DUR_ACTIVE ); if ( !ret && device_config->VF_CHECK_USING_ADC ) { int i; int val[5]; for ( i = 0; i < 5 ; i++ ) { val[i] = _get_t2adc_data_( device_config->VF_ADC_PORT ); msleep( 100 ); } count = _get_average_value_( val, 5 ); printk("vf: %d\n", count); if ( count < 200) return true; } #endif return ret; }
static void change_charge_status( int status, bool is_sleep ) // ---------------------------------------------------------------------------- // Description : // Input Argument : // Return Value : { switch ( status ) { case POWER_SUPPLY_STATUS_UNKNOWN : case POWER_SUPPLY_STATUS_DISCHARGING : case POWER_SUPPLY_STATUS_NOT_CHARGING : disable_charging( is_sleep ); break; case POWER_SUPPLY_STATUS_FULL : disable_charging( is_sleep ); /*Cancel timer*/ clear_charge_start_time(); break; case POWER_SUPPLY_STATUS_CHARGING : if ( sec_bci->battery.battery_vf_ok ) { sec_bci->battery.battery_health = POWER_SUPPLY_HEALTH_GOOD; /*Start monitoring charging time*/ set_charge_start_time(); enable_charging( is_sleep ); } else { sec_bci->battery.battery_health = POWER_SUPPLY_HEALTH_DEAD; status = POWER_SUPPLY_STATUS_NOT_CHARGING; disable_charging( is_sleep ); printk( "[TA] INVALID BATTERY, %d !! \n", status ); } break; case POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL : /*Start monitoring charging time*/ sec_bci->charger.charging_timeout = DEFAULT_RECHARGING_TIMEOUT; set_charge_start_time(); enable_charging( is_sleep ); break; case POWER_SUPPLY_STATUS_RECHARGING_FOR_TEMP : enable_charging( is_sleep ); break; default : ; } sec_bci->charger.prev_charge_status = sec_bci->charger.charge_status; sec_bci->charger.charge_status = status; _charger_state_change_( STATUS_CATEGORY_CHARGING, status, is_sleep ); }