#if defined(CONFIG_X86_INTEL_SOFIA)
#include <linux/usb/phy-intel.h>
+#else
+#include <linux/power/rk_usbbc.h>
#endif
#include "rk818_battery.h"
#define DSOC_CHRG_FINISH_CURR 1100
#define SLP_CHRG_CURR 1000
#define SLP_DSOC_VOL_THRESD 3600
+/*if voltage is lower than this thresd,
+ we consider it as invalid
+ */
+#define INVALID_VOL_THRESD 2500
#define PWR_OFF_THRESD 3400
#define MIN_ZERO_ACCURACY 10 /*0.01%*/
struct delayed_work charge_check_work;
struct delayed_work usb_phy_delay_work;
struct delayed_work chrg_term_mode_switch_work;
- int charge_otg;
+ enum bc_port_type charge_otg;
int ma;
struct wake_lock resume_wake_lock;
} while (buf == 0);
- dev_info(di->dev, "update capacity :%d--remain_cap:%d\n",
+ dev_dbg(di->dev, "update capacity :%d--remain_cap:%d\n",
capacity, di->remain_capacity);
}
static int rk81x_bat_get_vol(struct rk81x_battery *di)
{
int ret;
- int voltage_now = 0;
+ int vol;
u8 buf;
int temp;
int val[3];
else
temp = val[2];
- voltage_now = di->voltage_k * temp / 1000 + di->voltage_b;
+ vol = di->voltage_k * temp / 1000 + di->voltage_b;
- return voltage_now;
+ return vol;
}
static bool is_rk81x_bat_relax_mode(struct rk81x_battery *di)
for (retry = 0; retry < 5; retry++) {
adc_value = rk81x_bat_get_raw_adc_current(di);
if (!rk81x_chrg_online(di) || abs(adc_value) > 30) {
- dev_dbg(di->dev, "charger plugout\n");
+ dev_warn(di->dev, "charger plugout\n");
ret = true;
break;
}
ret = false;
break;
} else {
- dev_warn(di->dev, "ioffset cal failed\n");
+ dev_dbg(di->dev, "ioffset cal failed\n");
rk81x_bat_set_cal_offset(di, C0);
}
/*HW_ADP_TYPE_DUAL: det by rk818 and usb*/
} else if (rk81x_bat_support_adp_type(HW_ADP_TYPE_DUAL)) {
if ((buf & PLUG_IN_STS) != 0) {
- charger_type = dwc_otg_check_dpdm();
+ charger_type = dwc_otg_check_dpdm(0);
if (charger_type == 0)
charger_type = DC_CHARGER;
else
enum charger_type charger_type;
int usb_id, gadget_flag;
- usb_id = dwc_otg_check_dpdm();
+ usb_id = dwc_otg_check_dpdm(0);
switch (usb_id) {
case 0:
charger_type = NO_CHARGER;
void rk81x_charge_disable_open_otg(struct rk81x_battery *di)
{
- int value = di->charge_otg;
+ enum bc_port_type event = di->charge_otg;
- if (value) {
+ switch (event) {
+ case USB_OTG_POWER_ON:
DBG("charge disable, enable OTG.\n");
rk818_set_bits(di->rk818, CHRG_CTRL_REG1, 1 << 7, 0 << 7);
rk818_set_bits(di->rk818, 0x23, 1 << 7, 1 << 7);
- } else {
+ break;
+
+ case USB_OTG_POWER_OFF:
DBG("charge enable, disable OTG.\n");
rk818_set_bits(di->rk818, 0x23, 1 << 7, 0 << 7);
rk818_set_bits(di->rk818, CHRG_CTRL_REG1, 1 << 7, 1 << 7);
+ break;
+
+ default:
+ break;
}
}
temp = di->fcc * 3600 / 100;
if (di->ac_online)
soc_time = temp / DSOC_CHRG_FINISH_CURR;
- else if (di->usb_online)
+ else
soc_time = temp / 450;
plus_soc = sec_finish / soc_time;
static int rk81x_bat_sleep_chrg(struct rk81x_battery *di)
{
- int sleep_soc;
+ int sleep_soc = 0;
unsigned long sleep_sec;
sleep_sec = di->suspend_time_sum;
{
u8 rsoc = di->rsoc;
u8 dsoc = di->dsoc;
- u8 status = di->psy_status;
u8 cnt;
int unit_time;
int smooth_time;
__func__, cnt, unit_time, smooth_time,
BASE_TO_SEC(di->power_on_base), dsoc, rsoc);
- if ((status == POWER_SUPPLY_STATUS_CHARGING) ||
- (status == POWER_SUPPLY_STATUS_FULL && abs(di->current_avg) < 5)) {
+ if (di->current_avg >= 0 || di->chrg_status == CHARGE_FINISH) {
DBG("chrg, sm:%d, aim:%d\n", smooth_time, unit_time * 3 / 5);
if ((dsoc < rsoc - 1) && (smooth_time > unit_time * 3 / 5)) {
cnt = 0;
dsoc = 100;
rk81x_bat_save_dsoc(di, dsoc);
}
- } else {/*status == POWER_SUPPLY_STATUS_DISCHARGING*/
-
- DBG("dischrg, sm:%d, aim:%d\n", smooth_time, unit_time * 3/5);
- if ((dsoc > rsoc) && (smooth_time > unit_time * 3/5)) {
+ } else {
+ DBG("dischrg, sm:%d, aim:%d\n", smooth_time, unit_time * 3 / 5);
+ if ((dsoc > rsoc) && (smooth_time > unit_time * 3 / 5)) {
cnt = 0;
dsoc--;
if (dsoc <= 0)
}
EXPORT_SYMBOL_GPL(battery_notifier_call_chain);
-static void poweron_lowerpoer_handle(struct rk81x_battery *di)
-{
-#ifdef CONFIG_LOGO_LOWERPOWER_WARNING
- if ((di->dsoc <= 2) &&
- (di->psy_status == POWER_SUPPLY_STATUS_DISCHARGING)) {
- mdelay(1500);
- /* kernel_power_off(); */
- }
-#endif
-}
-
static int rk81x_bat_notifier_call(struct notifier_block *nb,
unsigned long event, void *data)
{
container_of(nb, struct rk81x_battery, battery_nb);
switch (event) {
- case 0:
- DBG(" CHARGE enable\n");
- di->charge_otg = 0;
- rk81x_bat_clr_bit(di, NT_STS_MSK_REG2, PLUG_IN_INT);
- rk81x_bat_clr_bit(di, NT_STS_MSK_REG2, PLUG_OUT_INT);
- queue_delayed_work(di->wq, &di->charge_check_work,
- msecs_to_jiffies(50));
- break;
- case 1:
- di->charge_otg = 1;
+ case USB_OTG_POWER_ON:
+ dev_info(di->dev, "charge disable, otg enable\n");
+ di->charge_otg = USB_OTG_POWER_ON;
rk81x_bat_set_bit(di, NT_STS_MSK_REG2, PLUG_IN_INT);
rk81x_bat_set_bit(di, NT_STS_MSK_REG2, PLUG_OUT_INT);
queue_delayed_work(di->wq, &di->charge_check_work,
msecs_to_jiffies(50));
- DBG("charge disable OTG enable\n");
break;
- case 2:
- poweron_lowerpoer_handle(di);
+
+ case USB_OTG_POWER_OFF:
+ dev_info(di->dev, "charge enable, otg disable\n");
+ di->charge_otg = USB_OTG_POWER_OFF;
+ rk81x_bat_clr_bit(di, NT_STS_MSK_REG2, PLUG_IN_INT);
+ rk81x_bat_clr_bit(di, NT_STS_MSK_REG2, PLUG_OUT_INT);
+ queue_delayed_work(di->wq, &di->charge_check_work,
+ msecs_to_jiffies(50));
break;
default:
return NOTIFY_OK;
static void rk81x_bat_info_init(struct rk81x_battery *di,
struct rk818 *chip)
{
+ u8 val;
unsigned long time_base = get_runtime_sec();
+ rk81x_bat_read(di, RK818_VB_MON_REG, &val, 1);
+ if (val & PLUG_IN_STS)
+ rk81x_bat_set_power_supply_state(di, USB_CHARGER);
+
di->cell.config = di->pdata->cell_cfg;
di->design_capacity = di->pdata->cell_cfg->design_capacity;
di->qmax = di->pdata->cell_cfg->design_qmax;
queue_delayed_work(di->wq, &di->battery_monitor_work,
msecs_to_jiffies(TIMER_MS_COUNTS * 5));
+#if defined(CONFIG_ARCH_ROCKCHIP)
INIT_DELAYED_WORK(&di->charge_check_work,
rk81x_battery_charge_check_work);
di->battery_nb.notifier_call = rk81x_bat_notifier_call;
- register_battery_notifier(&di->battery_nb);
-
+ rk_bc_detect_notifier_register(&di->battery_nb, &di->charge_otg);
+#endif
dev_info(di->dev, "battery driver version %s\n", DRIVER_VERSION);
return ret;
int delta_time;
int time_step;
int delta_soc;
+ int vol;
di->discharge_smooth_status = true;
di->charge_smooth_status = true;
di->s2r = 1;
- di->voltage = rk81x_bat_get_vol(di);
+ vol = rk81x_bat_get_vol(di);
+ if (vol < INVALID_VOL_THRESD) {
+ dev_err(di->dev, "invalid voltage :%d", vol);
+ vol = di->voltage;
+ dbg_enable = 1;
+ }
+ di->voltage = vol;
di->current_avg = rk81x_bat_get_avg_current(di);
di->relax_voltage = rk81x_bat_get_relax_vol(di);
di->est_ocv_vol = rk81x_bat_est_ocv_vol(di);
if ((!rk81x_chrg_online(di) && di->voltage <= pwroff_thresd) ||
rk81x_chrg_online(di))
wake_lock_timeout(&di->resume_wake_lock, 5 * HZ);
+
/*
* do not modify the g_base_sec
*/
struct rk81x_battery *di = platform_get_drvdata(dev);
cancel_delayed_work_sync(&di->battery_monitor_work);
+ rk_bc_detect_notifier_unregister(&di->battery_nb);
+
if (BASE_TO_MIN(di->power_on_base) <= REBOOT_INTER_MIN)
rk81x_bat_check_reboot(di);
else