RK3568关于RK808的定时开关机

RK3568关于RK808的定时开关机


前言

补丁
附件是以rk808为例实现的,使用rk809思路是一样的:


一、补丁

--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -61,7 +61,7 @@ static struct mfd_cell rk808s[] = {

#define VOL_MIN_IDX 0x00
#define VOL_MAX_IDX 0x3f
-
+static int getalarm[6];
const static int buck_set_vol_base_addr[] = {
        RK808_BUCK1_ON_REG,
        RK808_BUCK2_ON_REG,
@@ -1017,6 +1017,31 @@ static ssize_t rk808_test_show(struct kobject *kobj, struct kobj_attribute *attr

}

+static ssize_t rk808_alarm_store(struct kobject *kobj, struct kobj_attribute *attr,
+                                const char *buf, size_t n)
+{
+       char cmd;
+       const char *buftmp = buf;
+               
+       sscanf(buftmp, "%x%c%x%c%x%c%x%c%x%c%x", &getalarm[5],&cmd,&getalarm[4],&cmd,&getalarm[3],
+                                               &cmd,&getalarm[2],&cmd,&getalarm[1],&cmd,&getalarm[0]);
+       printk("year = %x\n", getalarm[5]);
+       printk("mon = %x\n", getalarm[4]);
+       printk("day = %x\n", getalarm[3]);
+       printk("hour = %x\n", getalarm[2]);
+       printk("min = %x\n", getalarm[1]);
+       printk("sec = %x\n", getalarm[0]);
+        return n;
+
+}
+
+static ssize_t rk808_alarm_show(struct kobject *kobj, struct kobj_attribute *attr,
+                               char *buf)
+{
+       return sprintf(buf, "%x%c%x%c%x%c%x%c%x%c%x\n", getalarm[5], '_', getalarm[4], '_', getalarm[3],
+                                                       '_', getalarm[2], '_', getalarm[1], '_', getalarm[0]);
+}
+
static struct kobject *rk808_kobj;
struct rk808_attribute {
        struct attribute        attr;
@@ -1029,6 +1054,7 @@ struct rk808_attribute {
static struct rk808_attribute rk808_attrs[] = {
        /*     node_name        permision               show_func       store_func */
        __ATTR(rk808_test,      S_IRUGO | S_IWUSR,      rk808_test_show,        rk808_test_store),
+       __ATTR(rk808_alarm,     S_IRUGO | S_IWUSR,      rk808_alarm_show,       rk808_alarm_store),
};
#endif
#if 0
@@ -1141,8 +1167,10 @@ static void rk808_shutdown(void)
        printk("%s,line=%d dc[%d]= %d\n", __func__,__LINE__,(i+1),val);
        }
        /*****************************************************/
-       ret = rk808_set_bits(rk808, RK808_INT_STS_MSK_REG1,(0x3<<5),(0x3<<5)); //close rtc int when power off
-       ret = rk808_clear_bits(rk808, RK808_RTC_INT_REG,(0x3<<2)); //close rtc int when power off
+       //ret = rk808_set_bits(rk808, RK808_INT_STS_MSK_REG1,(0x3<<5),(0x3<<5)); //close rtc int when power off
+       //ret = rk808_clear_bits(rk808, RK808_RTC_INT_REG,(0x3<<2)); //close rtc int when power off
+       ret = rk808_clear_bits(rk808, RK808_INT_STS_MSK_REG1,(0x3<<5)); //open rtc int when power on
+       ret = rk808_set_bits(rk808, RK808_RTC_INT_REG,(0x1<<3),(0x1<<3)); //open rtc int when power on
        mutex_lock(&rk808->io_lock);
        mdelay(100);
}
@@ -1153,9 +1181,23 @@ static struct syscore_ops rk808_syscore_ops = {

static void rk808_device_shutdown(void)
{
-       int ret,i;
+       int ret,i,j;
        u8 reg = 0;
        struct rk808 *rk808 = g_rk808;
+            
+       for(j=0x0d; j>=0x08; j--)
+       {
+               ret = rk808_i2c_write(rk808, j, 1,getalarm[j-8]);
+               if (ret <0)
+                        printk("write alarm reg error!\n");
+       }
+       for (j = 0; j < 0x13; j++)
+       {
+               ret=rk808_i2c_read(rk808,j,1,&reg);
+               if (ret <0)
+                       printk("read rtc & alarm reg error!\n");
+               printk("reg[0x%x]:%x\n",j,reg);
+       }
        for(i=0;i < 10;i++){
                printk("%s\n",__func__);
                ret = rk808_i2c_read(rk808,RK808_DEVCTRL_REG,1,&reg);
@@ -1169,6 +1211,7 @@ static void rk808_device_shutdown(void)
        }
        while(1)wfi();  
}
+
EXPORT_SYMBOL_GPL(rk808_device_shutdown);

__weak void  rk808_device_suspend(void) {}

二、测试方法

用adb或者串口都行

# su 
# echo +60 > /sys/class/rtc/rtc0/wakealarm cat /sys/class/rtc/rtc0/wakealarm 
#reboot -p 

关机之后等60S系统自动开机了,验证成功

总结

1.在底层做一个独立的alarm接口(本patch中是提供的接口为rk808_rtc_setalarm_pwron),上层设定开机时间;
2.上层设置的时间会调到该接口,然后保存开机时间;
3.等到真正关机时,在关机函数里将rtc/alarm中断全部打开,并将开机时间写进alarm寄存器;
4.一旦到达设定的时间,rtc通过唤醒pmu达到给整个系统上电的效果;
5.定时关机的功能比较简单,自己根据需求调用关机函数即可,不在赘述;补丁是以4.4kernel的rk808为例实现的,上层只需通过ioctl方法往接口里写入开机时间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那肯定是很多年以后!

你的鼓励就我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值