int bat_thread_kthread(void *x)
->BAT_thread();
->mt_battery_update_status();
->usb_update(&usb_main);
->ac_update(&ac_main);
->wireless_update(&wireless_main);
->battery_update(&battery_main);
->set_rtc_spare_fg_value(BMT_status.UI_SOC);
->hal_rtc_set_spare_register(RTC_FGSOC, val);
/kernel-4.19-lc/drivers/misc/mediatek/include/mt-plat/mtk_rtc_hal_common.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | enum rtc_spare_enum { RTC_FGSOC = 0, RTC_ANDROID, RTC_FAC_RESET, RTC_BYPASS_PWR, RTC_PWRON_TIME, RTC_FAST_BOOT, RTC_KPOC, RTC_DEBUG, RTC_PWRON_AL, RTC_UART, RTC_AUTOBOOT, RTC_PWRON_LOGO, RTC_32K_LESS, RTC_LP_DET, RTC_FG_INIT, RTC_SPAR_NUM };
enum rtc_reg_set { RTC_REG, RTC_MASK, RTC_SHIFT }; |
/kernel-4.19-lc/drivers/misc/mediatek/rtc/mtk_rtc_common.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | int get_rtc_spare_fg_value(void) { /* RTC_AL_HOU bit8~14 */ u16 temp; unsigned long flags;
spin_lock_irqsave(&rtc_lock, flags); temp = hal_rtc_get_spare_register(RTC_FGSOC); spin_unlock_irqrestore(&rtc_lock, flags);
return temp; }
int set_rtc_spare_fg_value(int val) { /* RTC_AL_HOU bit8~14 */ unsigned long flags;
#ifdef CONFIG_MTK_GAUGE_VERSION #if (CONFIG_MTK_GAUGE_VERSION != 30) if (val > 100) return 1; #endif #endif
spin_lock_irqsave(&rtc_lock, flags); hal_rtc_set_spare_register(RTC_FGSOC, val); spin_unlock_irqrestore(&rtc_lock, flags);
return 0; } |
/kernel-4.19-lc/drivers/misc/mediatek/rtc/mt6350/mt_rtc_hw.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #define RTC_BASE (0x8000) /* * RTC_NEW_SPARE0: RTC_AL_HOU bit0~4 * bit 8 ~ 14 : Fuel Gauge * bit 15 : reserved bits */ #define RTC_AL_HOU (RTC_BASE + 0x001c) /* * RTC_PDN1: * bit 0 - 3 : Android bits * bit 4 - 5 : Recovery bits (0x10: factory data reset) * bit 6 : Bypass PWRKEY bit * bit 7 : Power-On Time bit * bit 8 : RTC_GPIO_USER_WIFI bit * bit 9 : RTC_GPIO_USER_GPS bit * bit 10 : RTC_GPIO_USER_BT bit * bit 11 : RTC_GPIO_USER_FM bit * bit 12 : RTC_GPIO_USER_PMIC bit * bit 13 : Fast Boot * bit 14 : Kernel Power Off Charging * bit 15 : Debug bit */ #define RTC_PDN1 (RTC_BASE + 0x002c) /* * RTC_PDN2: * bit 0 - 3 : MTH in power-on time * bit 4 : Power-On Alarm bit * bit 5 - 6 : UART bits * bit 7 : reserved bit * bit 8 - 14: YEA in power-on time * bit 15 : Power-On Logo bit */ #define RTC_PDN2 (RTC_BASE + 0x002e) /* * RTC_SPAR0: * bit 0 - 5 : SEC in power-on time * bit 6 : 32K less bit. True:with 32K, False:Without 32K * bit 7 - 15: reserved bits */ #define RTC_SPAR0 (RTC_BASE + 0x0030) |
/kernel-4.19-lc/drivers/misc/mediatek/rtc/mt6350/mtk_rtc_hal.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | u16 rtc_spare_reg[RTC_SPAR_NUM][3] = { {RTC_AL_HOU, 0x7f, 8}, {RTC_PDN1, 0xf, 0}, {RTC_PDN1, 0x3, 4}, {RTC_PDN1, 0x1, 6}, {RTC_PDN1, 0x1, 7}, {RTC_PDN1, 0x1, 13}, {RTC_PDN1, 0x1, 14}, {RTC_PDN1, 0x1, 15}, {RTC_PDN2, 0x1, 4}, {RTC_PDN2, 0x3, 5}, {RTC_PDN2, 0x1, 7}, {RTC_PDN2, 0x1, 15}, {RTC_SPAR0, 0x1, 6}, {RTC_SPAR0, 0x1, 7} }; |
/kernel-4.19-lc/drivers/misc/mediatek/rtc/mtk_rtc_hal_common.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | void hal_rtc_set_spare_register(enum rtc_spare_enum cmd, u16 val) { u16 tmp_val;
if (cmd >= 0 && cmd < RTC_SPAR_NUM) { tmp_val = rtc_read(rtc_spare_reg[cmd][RTC_REG]) & ~(rtc_spare_reg[cmd][RTC_MASK] << rtc_spare_reg[cmd][RTC_SHIFT]); rtc_write(rtc_spare_reg[cmd][RTC_REG], tmp_val | ((val & rtc_spare_reg[cmd][RTC_MASK]) << rtc_spare_reg[cmd][RTC_SHIFT])); rtc_write_trigger(); } }
u16 hal_rtc_get_spare_register(enum rtc_spare_enum cmd) { u16 tmp_val;
if (cmd >= 0 && cmd < RTC_SPAR_NUM) { hal_rtc_xinfo("rtc_spare_reg[%d] = {%d, %d, %d}\n", cmd, rtc_spare_reg[cmd][RTC_REG], rtc_spare_reg[cmd][RTC_MASK], rtc_spare_reg[cmd][RTC_SHIFT]); tmp_val = rtc_read(rtc_spare_reg[cmd][RTC_REG]); tmp_val = (tmp_val >> rtc_spare_reg[cmd][RTC_SHIFT]) & rtc_spare_reg[cmd][RTC_MASK]; return tmp_val; } return 0; } |
==========================================
static void nl_data_handler(struct sk_buff *skb)
->bmd_ctrl_cmd_from_user(data, fgd_ret_msg); //void bmd_ctrl_cmd_from_user(void *nl_data, struct fgd_nl_msg_t *ret_msg)
->case FG_DAEMON_CMD_GET_RTC_UI_SOC:
->gauge_dev_get_rtc_ui_soc(gm.gdev, &rtc_ui_soc);
->gauge_dev->ops->gauge_get_rtc_ui_soc(gauge_dev, ui_soc);
->spare3_reg = get_rtc_spare_fg_value();
->*ui_soc = (spare3_reg & 0x7f); //取低7位
->case FG_DAEMON_CMD_SET_RTC_UI_SOC:
->gauge_dev_set_rtc_ui_soc(gm.gdev, rtc_ui_soc);
->gauge_dev->ops->gauge_set_rtc_ui_soc(gauge_dev, ui_soc);
->spare3_reg = get_rtc_spare_fg_value()
->new_spare3_reg = (spare3_reg & 0x80) + rtc_ui_soc; //将低7位清零
->set_rtc_spare_fg_value(new_spare3_reg)
->nl_send_to_user(pid, seq, fgd_ret_msg);
/kernel-4.14/arch/arm64/boot/dts/mediatek/mt8168.dtsi
1 2 3 4 5 6 7 8 9 10 11 12 13 | / { model = "MT8168"; compatible = "mediatek,mt8168"; interrupt-parent = <&sysirq>; #address-cells = <2>; #size-cells = <2>;
mt6357_gauge { compatible = "mediatek,mt6357_gauge"; gauge_name = "gauge"; alias_name = "MT6357"; }; }; |
/kernel-4.14/drivers/misc/mediatek/pmic/mt6357/v1/mt6357_gauge.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | static struct gauge_ops mt6357_gauge_ops = { ... ... .gauge_set_rtc_ui_soc = fgauge_set_rtc_ui_soc, .gauge_get_rtc_ui_soc = fgauge_get_rtc_ui_soc, };
static int mt6357_gauge_probe(struct platform_device *pdev) { int ret = 0; struct mt6357_gauge *info;
bm_debug("%s: starts\n", __func__);
info = devm_kzalloc( &pdev->dev, sizeof(struct mt6357_gauge), GFP_KERNEL); if (!info) return -ENOMEM;
mt6357_parse_dt(info, &pdev->dev); platform_set_drvdata(pdev, info);
/* Register charger device */ info->gauge_dev = gauge_device_register(info->gauge_dev_name, &pdev->dev, info, &mt6357_gauge_ops, &info->gauge_prop); if (IS_ERR_OR_NULL(info->gauge_dev)) { ret = PTR_ERR(info->gauge_dev); goto err_register_gauge_dev; }
return 0; err_register_gauge_dev: devm_kfree(&pdev->dev, info); return ret;
}
static const struct of_device_id mt6357_gauge_of_match[] = { {.compatible = "mediatek,mt6357_gauge",}, {}, };
MODULE_DEVICE_TABLE(of, mt6357_gauge_of_match);
static struct platform_driver mt6357_gauge_driver = { .probe = mt6357_gauge_probe, .remove = mt6357_gauge_remove, .shutdown = mt6357_gauge_shutdown, .driver = { .name = "mt6357_gauge", .of_match_table = mt6357_gauge_of_match, }, };
static int __init mt6357_gauge_init(void) { return platform_driver_register(&mt6357_gauge_driver); } device_initcall(mt6357_gauge_init);
static void __exit mt6357_gauge_exit(void) { platform_driver_unregister(&mt6357_gauge_driver); } module_exit(mt6357_gauge_exit); |
/kernel-4.14/drivers/misc/mediatek/pmic/mt6357/v1/mt6357_gauge.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | static int fgauge_set_rtc_ui_soc(struct gauge_device *gauge_dev, int rtc_ui_soc) { int spare3_reg = get_rtc_spare_fg_value(); int spare3_reg_valid; int new_spare3_reg;
spare3_reg_valid = (spare3_reg & 0x80); new_spare3_reg = spare3_reg_valid + rtc_ui_soc;
/* set spare3 0x7f */ set_rtc_spare_fg_value(new_spare3_reg);
bm_notice("[fg_set_rtc_ui_soc] rtc_ui_soc %d spare3_reg 0x%x new_spare3_reg 0x%x\n", rtc_ui_soc, spare3_reg, new_spare3_reg);
return 0; }
static int fgauge_get_rtc_ui_soc(struct gauge_device *gauge_dev, int *ui_soc) { int spare3_reg = get_rtc_spare_fg_value(); int rtc_ui_soc;
rtc_ui_soc = (spare3_reg & 0x7f);
*ui_soc = rtc_ui_soc; bm_notice("[%s] rtc_ui_soc %d spare3_reg 0x%x\n", __func__, rtc_ui_soc, spare3_reg);
return 0; } |
/kernel-4.14/drivers/mfd/mt6358-misc.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #define RTC_AL_HOU 0x24 #define RTC_AL_MTH 0x2a #define RTC_PDN1 0x34 #define RTC_PDN2 0x36 #define RTC_SPAR0 0x38 #define RTC_SPAR1 0x3a #define RTC_WRTGR 0x42
enum rtc_spare_enum { RTC_FGSOC = 0, RTC_ANDROID, RTC_FAC_RESET, RTC_BYPASS_PWR, RTC_PWRON_TIME, RTC_FAST_BOOT, RTC_KPOC, RTC_DEBUG, RTC_PWRON_AL, RTC_UART, RTC_AUTOBOOT, RTC_PWRON_LOGO, RTC_32K_LESS, RTC_LP_DET, RTC_FG_INIT, RTC_SPAR_NUM };
enum rtc_reg_set { RTC_REG, RTC_MASK, RTC_SHIFT };
u16 rtc_spare_reg[RTC_SPAR_NUM][3] = { //和rtc_spare_enum一一对应 {RTC_AL_MTH, 0xff, 8}, {RTC_PDN1, 0xf, 0}, {RTC_PDN1, 0x3, 4}, {RTC_PDN1, 0x1, 6}, {RTC_PDN1, 0x1, 7}, {RTC_PDN1, 0x1, 13}, {RTC_PDN1, 0x1, 14}, {RTC_PDN1, 0x1, 15}, {RTC_PDN2, 0x1, 4}, {RTC_PDN2, 0x3, 5}, {RTC_PDN2, 0x1, 7}, {RTC_PDN2, 0x1, 15}, {RTC_SPAR0, 0x1, 6}, {RTC_SPAR0, 0x1, 7}, {RTC_AL_HOU, 0xff, 8} }; |
/kernel-4.14/drivers/mfd/mt6358-misc.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | int get_rtc_spare_fg_value(void) { /* RTC_AL_HOU bit8~14 */ u16 temp; unsigned long flags;
spin_lock_irqsave(&rtc_misc->lock, flags); temp = mtk_rtc_get_spare_register(RTC_FGSOC); spin_unlock_irqrestore(&rtc_misc->lock, flags);
return temp; }
int set_rtc_spare_fg_value(int val) { /* RTC_AL_HOU bit8~14 */ unsigned long flags;
spin_lock_irqsave(&rtc_misc->lock, flags); mtk_rtc_set_spare_register(RTC_FGSOC, val); spin_unlock_irqrestore(&rtc_misc->lock, flags);
return 0; } |
/kernel-4.14/drivers/mfd/mt6358-misc.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | static int mtk_rtc_get_spare_register(enum rtc_spare_enum cmd) { unsigned int tmp_val = 0; int ret = -EINVAL;
if (cmd >= 0 && cmd < RTC_SPAR_NUM) {
ret = rtc_field_read(rtc_spare_reg[cmd][RTC_REG], rtc_spare_reg[cmd][RTC_MASK] << rtc_spare_reg[cmd][RTC_SHIFT], rtc_spare_reg[cmd][RTC_SHIFT], &tmp_val);
if (ret < 0) goto exit;
pr_notice("%s: cmd[%d], get rg[0x%x, 0x%x , %d] = 0x%x\n", __func__, cmd, rtc_spare_reg[cmd][RTC_REG], rtc_spare_reg[cmd][RTC_MASK], rtc_spare_reg[cmd][RTC_SHIFT], tmp_val);
return tmp_val; }
exit: return ret; }
static void mtk_rtc_set_spare_register(enum rtc_spare_enum cmd, u16 val) { u32 tmp_val = 0; int ret;
if (cmd >= 0 && cmd < RTC_SPAR_NUM) {
pr_notice("%s: cmd[%d], set rg[0x%x, 0x%x , %d] = 0x%x\n", __func__, cmd, rtc_spare_reg[cmd][RTC_REG], rtc_spare_reg[cmd][RTC_MASK], rtc_spare_reg[cmd][RTC_SHIFT], val);
tmp_val = ((val & rtc_spare_reg[cmd][RTC_MASK]) << rtc_spare_reg[cmd][RTC_SHIFT]); ret = rtc_update_bits(rtc_spare_reg[cmd][RTC_REG], rtc_spare_reg[cmd][RTC_MASK] << rtc_spare_reg[cmd][RTC_SHIFT], tmp_val); if (ret < 0) goto exit; ret = rtc_write_trigger(); if (ret < 0) goto exit; } return; exit: pr_err("%s error\n", __func__); } |
/kernel-4.14/drivers/mfd/mt6358-misc.c
1 2 3 4 5 6 7 8 9 10 | static int rtc_write_trigger(void) { int ret;
ret = rtc_write(RTC_WRTGR, 1); if (ret < 0) return ret;
return rtc_busy_wait(); } |