blob: 85a895945e32e7b96378f832a40ca0482a8a5e91 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2018-2020 Oplus. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include "oplus_charger.h"
#include "oplus_vooc.h"
#include "oplus_gauge.h"
#include "oplus_adapter.h"
extern int enable_charger_log;
#define adapter_xlog_printk(num, fmt, ...) \
do { \
if (enable_charger_log >= (int)num) { \
printk(KERN_NOTICE pr_fmt("[OPLUS_CHG][%s]"fmt), __func__, ##__VA_ARGS__);\
} \
} while (0)
static struct oplus_adapter_chip *g_adapter_chip = NULL;
static void oplus_adpater_awake_init(struct oplus_adapter_chip *chip)
{
if (!chip)
return;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0))
wake_lock_init(&chip->adapter_wake_lock, WAKE_LOCK_SUSPEND, "adpater_wake_lock");
#else
chip->adapter_ws = wakeup_source_register(NULL, "adpater_wake_lock");
#endif
}
static void oplus_adapter_set_awake(struct oplus_adapter_chip *chip, bool awake)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0))
if (awake)
wake_lock(&chip->adapter_wake_lock);
else
wake_unlock(&chip->adapter_wake_lock);
#else
static bool pm_flag = false;
if (!chip || !chip->adapter_ws)
return;
if (awake && !pm_flag) {
pm_flag = true;
__pm_stay_awake(chip->adapter_ws);
} else if (!awake && pm_flag) {
__pm_relax(chip->adapter_ws);
pm_flag = false;
}
#endif
}
static void adapter_update_work_func(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct oplus_adapter_chip *chip = container_of(dwork, struct oplus_adapter_chip, adapter_update_work);
bool update_result = false;
long tx_gpio = 0, rx_gpio = 0;
int i = 0;
if (!chip) {
chg_err("oplus_adapter_chip NULL\n");
return;
}
oplus_adapter_set_awake(chip, true);
tx_gpio = oplus_vooc_get_uart_tx();
rx_gpio = oplus_vooc_get_uart_rx();
adapter_xlog_printk(CHG_LOG_CRTI, " begin\n");
oplus_vooc_uart_init();
for (i = 0;i < 2;i++) {
update_result = chip->vops->adapter_update(tx_gpio, rx_gpio);
if (update_result == true) {
break;
}
if (i < 1) {
msleep(1650);
}
}
if (update_result) {
oplus_vooc_set_adapter_update_real_status(ADAPTER_FW_UPDATE_SUCCESS);
} else {
oplus_vooc_set_adapter_update_real_status(ADAPTER_FW_UPDATE_FAIL);
oplus_vooc_set_adapter_update_report_status(ADAPTER_FW_UPDATE_FAIL);
}
msleep(20);
oplus_vooc_uart_reset();
if (update_result) {
msleep(2000);
oplus_vooc_set_adapter_update_report_status(ADAPTER_FW_UPDATE_SUCCESS);
}
oplus_vooc_battery_update();
adapter_xlog_printk(CHG_LOG_CRTI, " end update_result:%d\n", update_result);
oplus_adapter_set_awake(chip, false);
}
#define ADAPTER_UPDATE_DELAY 1400
void oplus_adapter_fw_update(void)
{
struct oplus_adapter_chip *chip = g_adapter_chip ;
adapter_xlog_printk(CHG_LOG_CRTI, " call \n");
/*schedule_delayed_work_on(7, &chip->adapter_update_work, */
/* round_jiffies_relative(msecs_to_jiffies(ADAPTER_UPDATE_DELAY)));*/
schedule_delayed_work(&chip->adapter_update_work,
round_jiffies_relative(msecs_to_jiffies(ADAPTER_UPDATE_DELAY)));
}
void oplus_adapter_init(struct oplus_adapter_chip *chip)
{
g_adapter_chip = chip;
oplus_adpater_awake_init(chip);
INIT_DELAYED_WORK(&chip->adapter_update_work, adapter_update_work_func);
}
bool oplus_adapter_check_chip_is_null(void)
{
if (!g_adapter_chip) {
return true;
} else {
return false;
}
}