void mxs_log_charge_update(int mode) /* 0 : event, 1 : auto */ { static unsigned long count; char log[100]; struct timespec ts; struct rtc_time tm; int16_t i16Low; int16_t i16High; uint16_t u16Reading; if (!_timeout || mxs_log_open(_FILE_NAME) < 0) return; getnstimeofday(&ts); if (_state == -1) { _time = ts.tv_sec; _gi_time = ts.tv_sec; rtc_time_to_tm(ts.tv_sec, &tm); sprintf(log, "%d-%02d-%02d %02d:%02d:%02d,,,,,,\n%s\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, _LOG_TITLE); mxs_log_write(_FILE_NAME, log); } if (!mode && _state == ddi_bc_GetState()) return; count++; _state = ddi_bc_GetState(); if (ts.tv_sec - _gi_time < _timeout) return; ddi_bc_hwGetDieTemp(&i16Low, &i16High); ddi_bc_hwGetBatteryTemp(&u16Reading); sprintf(log, "%ld,%d,%d,%d.%03d,%d,%d,%d,%d,%d\n", (ts.tv_sec - _time), mode, count, (ddi_power_GetBattery()/1000), (ddi_power_GetBattery()%1000), _state, mxs_bat_get_ui_status(), ddi_bc_GetBrokenReason(), (i16High - 5), /* remove margin */ u16Reading); mxs_log_write(_FILE_NAME, log); _gi_time = ts.tv_sec; count = 0; }
static void handle_battery_voltage_changes(struct stmp3xxx_info *info) { #if 0 uint16_t battery_voltage; battery_voltage = ddi_power_GetBattery(); if (info->sm_5v_connection_status != _5v_connected_verified) { if (battery_voltage < OS_SHUTDOWN_BATTERY_VOLTAGE_THRESHOLD_MV) { printk(KERN_CRIT "Polled battery voltage measurement is\ less than %dmV. Shutting down the \ system\n", OS_SHUTDOWN_BATTERY_VOLTAGE_THRESHOLD_MV); shutdown_os(); return; } } else #endif { ddi_power_handle_cmptrip(); if (ddi_power_IsBattRdyForXfer()) ddi_power_enable_5v_to_battery_xfer(true); else ddi_power_enable_5v_to_battery_xfer(false); } }
void init_protection(struct mxs_info *info) { enum ddi_power_5v_status pmu_5v_status; uint16_t battery_voltage; pmu_5v_status = ddi_power_GetPmu5vStatus(); battery_voltage = ddi_power_GetBattery(); /* InitializeFiqSystem(); */ ddi_power_InitOutputBrownouts(); if (info->powersource == NO_VDD5V_SOURCE) { ddi_power_EnableBatteryBoInterrupt(true); return; } /* if we start the kernel with 4p2 already started * by the bootlets, we need to hand off from this * state to the kernel 4p2 enabled state. */ if ((pmu_5v_status == existing_5v_connection) && ddi_power_check_4p2_bits()) { ddi_power_enable_5v_disconnect_detection(); /* includes VBUS DROOP workaround for errata */ ddi_power_init_4p2_protection(); /* if we still have our 5V connection, we can disable * battery brownout interrupt. This is because the * VDD5V DROOP IRQ handler will also shutdown if battery * is browned out and it will enable the battery brownout * and bring VBUSVALID_TRSH level back to a normal level * which caused the hardware battery brownout shutdown * to be enabled. The benefit of this is that device * that have detachable batteries (or devices going through * the assembly line and running this firmware to test * with) can avoid shutting down if 5V is present and * battery voltage goes away. */ ddi_power_EnableBatteryBoInterrupt(false); info->sm_5v_connection_status = _5v_connected_verified; } else { #ifdef DEBUG_IRQS if (battery_voltage < OS_SHUTDOWN_BATTERY_VOLTAGE_THRESHOLD_MV) { printk(KERN_CRIT "Polled battery voltage measurement is\ less than %dmV. Kernel should be halted/\ shutdown\n", OS_SHUTDOWN_BATTERY_VOLTAGE_THRESHOLD_MV); return; } #endif info->sm_5v_connection_status = _5v_disconnected_verified; ddi_power_EnableBatteryBoInterrupt(true); } /* all brownouts are now handled software fiqs. We * can now disable the hardware protection mechanisms * because leaving them on yields ~2kV ESD level * versus ~4kV ESD levels when they are off. This * difference is suspected to be cause by the fast * falling edge pswitch functionality being tripped * by ESD events. This functionality is disabled * when PWD_OFF is disabled. */ #ifdef DISABLE_HARDWARE_PROTECTION_MECHANISMS __raw_writel(BM_POWER_RESET_PWD_OFF, HW_POWER_RESET_SET_ADDR); #endif }
//////////////////////////////////////////////////////////////////////////////// //! //! \brief Report the voltage across the battery. //! //! \fntype Function //! //! This function reports the voltage across the battery. //! //! \retval The voltage across the battery, in mV. //! //////////////////////////////////////////////////////////////////////////////// uint16_t ddi_bc_hwGetBatteryVoltage(void) { //TODO: replace ddi_bc_hwGetBattery with function below return ddi_power_GetBattery(); }
static int stmp3xxx_bat_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { struct stmp3xxx_info *info = to_stmp3xxx_info(psy); ddi_bc_State_t state; ddi_bc_BrokenReason_t reason; int temp_alarm; int16_t temp_lo, temp_hi; switch (psp) { case POWER_SUPPLY_PROP_STATUS: state = ddi_bc_GetState(); switch (state) { case DDI_BC_STATE_CONDITIONING: case DDI_BC_STATE_CHARGING: case DDI_BC_STATE_TOPPING_OFF: val->intval = POWER_SUPPLY_STATUS_CHARGING; break; case DDI_BC_STATE_DISABLED: val->intval = ddi_power_Get5vPresentFlag() ? POWER_SUPPLY_STATUS_NOT_CHARGING : POWER_SUPPLY_STATUS_DISCHARGING; break; default: /* TODO: detect full */ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; break; } break; case POWER_SUPPLY_PROP_PRESENT: /* is battery present */ state = ddi_bc_GetState(); switch (state) { case DDI_BC_STATE_WAITING_TO_CHARGE: case DDI_BC_STATE_DCDC_MODE_WAITING_TO_CHARGE: case DDI_BC_STATE_CONDITIONING: case DDI_BC_STATE_CHARGING: case DDI_BC_STATE_TOPPING_OFF: case DDI_BC_STATE_DISABLED: val->intval = 1; break; case DDI_BC_STATE_BROKEN: val->intval = !(ddi_bc_GetBrokenReason() == DDI_BC_BROKEN_NO_BATTERY_DETECTED); break; default: val->intval = 0; break; } break; case POWER_SUPPLY_PROP_HEALTH: temp_alarm = ddi_bc_RampGetDieTempAlarm(); if (temp_alarm) { val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; } else { state = ddi_bc_GetState(); switch (state) { case DDI_BC_STATE_BROKEN: reason = ddi_bc_GetBrokenReason(); val->intval = (reason == DDI_BC_BROKEN_CHARGING_TIMEOUT) ? POWER_SUPPLY_HEALTH_DEAD : POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; break; case DDI_BC_STATE_UNINITIALIZED: val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; break; default: val->intval = POWER_SUPPLY_HEALTH_GOOD; break; } } break; case POWER_SUPPLY_PROP_TECHNOLOGY: val->intval = POWER_SUPPLY_TECHNOLOGY_LION; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: /* uV */ val->intval = ddi_power_GetBattery() * 1000; break; case POWER_SUPPLY_PROP_CURRENT_NOW: /* uA */ val->intval = ddi_power_GetMaxBatteryChargeCurrent() * 1000; break; case POWER_SUPPLY_PROP_TEMP: mutex_lock(&info->sm_lock); ddi_power_GetDieTemp(&temp_lo, &temp_hi); mutex_unlock(&info->sm_lock); val->intval = temp_lo + (temp_hi - temp_lo) / 2; break; default: return -EINVAL; } return 0; }