RTC(电池电量保存)

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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值