| // 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; |
| } |
| } |
| |