AMLOGIC 平台上移植RTC RV8803

在AMLOGIC平台上移植RTC RV8803时遇到电压低导致的数据丢失和时间获取错误的问题。调试过程中发现设备返回了无效日期2000-01-00。通过修改函数设定默认时间为2021年2月1日,成功解决了获取时间错误的问题。
摘要由CSDN通过智能技术生成

 common/drivers/rtc/rtc-rv8803.c

/*
 * RTC driver for the Micro Crystal RV8803
 *
 * Copyright (C) 2015 Micro Crystal SA
 *
 * Alexandre Belloni <alexandre.belloni@free-electrons.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
*/
#include <linux/bcd.h>
#include <linux/bitops.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/rtc.h>
#define RV8803_SEC                      0x00
#define RV8803_MIN                      0x01
#define RV8803_HOUR                     0x02
#define RV8803_WEEK                     0x03
#define RV8803_DAY                      0x04
#define RV8803_MONTH                    0x05
#define RV8803_YEAR                     0x06
#define RV8803_RAM                      0x07
#define RV8803_ALARM_MIN                0x08
#define RV8803_ALARM_HOUR               0x09
#define RV8803_ALARM_WEEK_OR_DAY        0x0A
#define RV8803_TIMER_CNT_0              0x0B
#define RV8803_TIMER_CNT_1              0x0C
#define RV8803_EXT                      0x0D
#define RV8803_FLAG                     0x0E
#define RV8803_CTRL                     0x0F

#define RV8803_EX2_OSC_OFFSET           0x2C

#define RV8803_EX2_EVENT_CTRL           0x2F

#define RV8803_EXT_TSEL0                BIT(0)
#define RV8803_EXT_TSEL1                BIT(1)
#define RV8803_EXT_FSEL0                BIT(2)
#define RV8803_EXT_FSEL1                BIT(3)
#define RV8803_EXT_TE                   BIT(4)
#define RV8803_EXT_USEL                 BIT(5)
#define RV8803_EXT_WADA                 BIT(6)
#define RV8803_EXT_TEST                 BIT(7)

#define RV8803_FLAG_V1F                 BIT(0)
#define RV8803_FLAG_V2F                 BIT(1)
#define RV8803_FLAG_EVF                 BIT(2)
#define RV8803_FLAG_AF                  BIT(3)
#define RV8803_FLAG_TF                  BIT(4)
#define RV8803_FLAG_UF                  BIT(5)

#define RV8803_CTRL_RESET               BIT(0)

#define RV8803_CTRL_EIE                 BIT(2)
#define RV8803_CTRL_AIE                 BIT(3)
#define RV8803_CTRL_TIE                 BIT(4)
#define RV8803_CTRL_UIE                 BIT(5)

struct rv8803_data {
        struct i2c_client *client;
        struct rtc_device *rtc;
        u8 ctrl;
};
/*
static irqreturn_t rv8803_handle_irq(int irq, void *dev_id)
{
        struct i2c_client *client = dev_id;
        struct rv8803_data *rv8803 = i2c_get_clientdata(client);
        unsigned long events = 0;
        u8 flags;

        flags = i2c_smbus_read_byte_data(client, RV8803_FLAG);
        if (flags <= 0)
                return IRQ_HANDLED;

        if (flags & RV8803_FLAG_V1F)
                dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");

        if (flags & RV8803_FLAG_V2F)
                dev_warn(&client->dev, "Voltage low, data loss detected.\n");

        if (flags & RV8803_FLAG_TF) {
                flags &= ~RV8803_FLAG_TF;
                rv8803->ctrl &= ~RV8803_CTRL_TIE;
                events |= RTC_PF;
        }

        if (flags & RV8803_FLAG_AF) {
                flags &= ~RV8803_FLAG_AF;
                rv8803->ctrl &= ~RV8803_CTRL_AIE;
                events |= RTC_AF;
        }

        if (flags & RV8803_FLAG_UF) {
                flags &= ~RV8803_FLAG_UF;
                rv8803->ctrl &= ~RV8803_CTRL_UIE;
                events |= RTC_UF;
        }

        if (events) {
                rtc_update_irq(rv8803->rtc, 1, events);
                i2c_smbus_write_byte_data(client, RV8803_FLAG, flags);
                i2c_smbus_write_byte_data(rv8803->client, RV8803_CTRL,
                                          rv8803->ctrl);
        }

        return IRQ_HANDLED;
}
*/
static int rv8803_get_time(struct device *dev, struct rtc_time *tm)
{
        struct rv8803_data *rv8803 = dev_get_drvdata(dev);
        u8 date1[7];
        u8 *date = date1;
        int ret, flags;

        flags = i2c_smbus_read_byte_data(rv8803->client, RV8803_FLAG);
        if (flags < 0)
                return flags;

        if (flags & RV8803_FLAG_V2F) {
                dev_warn(dev, "Voltage low, data is invalid.\n");
                return -EINVAL;
        }

        ret = i2c_smbus_read_i2c_block_data(rv880
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Keep Coding...

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值