static void battery_monitor_work(struct work_struct *work) { int vbatt; struct bcl_context *bcl = container_of(work, struct bcl_context, battery_monitor_work); if (gbcl->bcl_mode == BCL_DEVICE_ENABLED) { bcl->btm_mode = BCL_VPH_MONITOR_MODE; update_cpu_freq(); bcl_handle_hotplug(); bcl_get_battery_voltage(&vbatt); pr_debug("vbat is %d\n", vbatt); if (bcl_vph_state == BCL_LOW_THRESHOLD) { if (vbatt <= gbcl->btm_vph_low_thresh) { /*relay the notification to charger ic driver*/ if (bcl->btm_charger_ic_low_thresh == gbcl->btm_vph_adc_param.low_thr) { bcl_hit_shutdown_voltage = true; } else bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE_MIN); } else bcl_config_vph_adc(gbcl, BCL_HIGH_THRESHOLD_TYPE); } else { bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE); } } }
static void bcl_vph_notification(enum qpnp_tm_state state, void *ctx) { struct bcl_context *bcl = ctx; int ret = 0; mutex_lock(&bcl_notify_mutex); if (bcl->btm_mode == BCL_MONITOR_DISABLED) goto unlock_and_exit; switch (state) { case ADC_TM_LOW_STATE: if (bcl->btm_mode != BCL_VPH_MONITOR_MODE) { pr_err("Low thresh received with invalid btm mode:%d\n", bcl->btm_mode); ibat_mode_set(BCL_DEVICE_DISABLED); goto unlock_and_exit; } pr_debug("Initiating Ibat current monitoring\n"); bcl_vph_notify(BCL_LOW_THRESHOLD); bcl_config_ibat_adc(gbcl, BCL_HIGH_THRESHOLD_TYPE); bcl_config_vph_adc(gbcl, BCL_HIGH_THRESHOLD_TYPE); bcl->btm_mode = BCL_IBAT_MONITOR_MODE; break; case ADC_TM_HIGH_STATE: if (bcl->btm_mode != BCL_IBAT_MONITOR_MODE && bcl->btm_mode != BCL_IBAT_HIGH_LOAD_MODE) { pr_err("High thresh received with invalid btm mode:%d\n" , bcl->btm_mode); ibat_mode_set(BCL_DEVICE_DISABLED); goto unlock_and_exit; } pr_debug("Exiting Ibat current monitoring\n"); bcl->btm_mode = BCL_VPH_MONITOR_MODE; ret = ibat_disable(); if (ret) { pr_err("Error disabling ibat ADC. err:%d\n", ret); goto unlock_and_exit; } bcl_vph_notify(BCL_HIGH_THRESHOLD); bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE); break; default: goto set_thresh; } unlock_and_exit: mutex_unlock(&bcl_notify_mutex); return; set_thresh: mutex_unlock(&bcl_notify_mutex); bcl_config_vph_adc(gbcl, BCL_HIGH_THRESHOLD_TYPE); return; }
static void power_supply_callback(struct power_supply *psy) { int vbatt = 0; if (bcl_hit_shutdown_voltage) return; if (0 != bcl_get_battery_voltage(&vbatt)) return; if (vbatt <= gbcl->btm_vph_low_thresh) { /*relay the notification to charger ic driver*/ bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE_MIN); } else if ((vbatt > gbcl->btm_vph_low_thresh) && (vbatt <= gbcl->btm_vph_high_thresh)) bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE); else bcl_config_vph_adc(gbcl, BCL_HIGH_THRESHOLD_TYPE); }
static int bcl_resume(struct device *dev) { struct bcl_context *bcl = dev_get_drvdata(dev); int vbatt = 0; if (bcl->bcl_monitor_type == BCL_IBAT_MONITOR_TYPE && bcl->bcl_mode == BCL_DEVICE_ENABLED) { bcl->btm_mode = BCL_VPH_MONITOR_MODE; bcl_get_battery_voltage(&vbatt); if (vbatt <= gbcl->btm_vph_low_thresh) { /*relay the notification to charger ic driver*/ bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE_MIN); } else if ((vbatt > gbcl->btm_vph_low_thresh) && (vbatt <= gbcl->btm_vph_high_thresh)) bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE); else bcl_config_vph_adc(gbcl, BCL_HIGH_THRESHOLD_TYPE); } return 0; }
static int bcl_resume(struct device *dev) { struct bcl_context *bcl = dev_get_drvdata(dev); if (bcl->bcl_monitor_type == BCL_IBAT_MONITOR_TYPE && bcl->bcl_mode == BCL_DEVICE_ENABLED) { bcl->btm_mode = BCL_VPH_MONITOR_MODE; bcl_config_vph_adc(bcl, BCL_LOW_THRESHOLD_TYPE); } return 0; }
/* * Set BCL mode */ static void bcl_mode_set(enum bcl_device_mode mode) { int ret = 0; if (!gbcl) return; gbcl->bcl_mode = mode; if (BCL_DEVICE_DISABLED == mode) { vph_disable(); } else { mutex_lock(&bcl_notify_mutex); gbcl->btm_mode = BCL_VPH_MONITOR_MODE; mutex_unlock(&bcl_notify_mutex); ret = bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE); if (ret) { pr_err("Vph config error. ret:%d\n", ret); return; } } return; }
static void ibat_mode_set(enum bcl_device_mode mode) { int ret = 0; if (mode == BCL_DEVICE_ENABLED) { gbcl->btm_mode = BCL_VPH_MONITOR_MODE; ret = bcl_config_vph_adc(gbcl, BCL_LOW_THRESHOLD_TYPE); if (ret) { pr_err("Vph config error. ret:%d\n", ret); gbcl->bcl_mode = BCL_DEVICE_DISABLED; gbcl->btm_mode = BCL_MONITOR_DISABLED; return; } } else { switch (gbcl->btm_mode) { case BCL_IBAT_MONITOR_MODE: case BCL_IBAT_HIGH_LOAD_MODE: ret = ibat_disable(); if (ret) return; ret = vph_disable(); if (ret) return; break; case BCL_VPH_MONITOR_MODE: ret = vph_disable(); if (ret) return; break; case BCL_MONITOR_DISABLED: default: break; } gbcl->btm_mode = BCL_MONITOR_DISABLED; } return; }