|
@@ -5,65 +5,6 @@
|
|
|
#include "errno.h"
|
|
#include "errno.h"
|
|
|
#include "access_module.h"
|
|
#include "access_module.h"
|
|
|
|
|
|
|
|
-/* RTC registers */
|
|
|
|
|
-#define RTC_CTL 0x00 /*control register*/
|
|
|
|
|
-#define RTC_ANAWEN 0x04 /*analog block write enable register*/
|
|
|
|
|
-#define RTC_ANACTL 0x08 /*analog block control register*/
|
|
|
|
|
-#define RTC_IM 0x0c /*interrupt mode register*/
|
|
|
|
|
-#define RTC_STA 0x10 /*rtc status register*/
|
|
|
|
|
-#define RTC_ALMDAT 0x14 /*alarm data register*/
|
|
|
|
|
-#define RTC_DONT 0x18 /*delay on timer register*/
|
|
|
|
|
-#define RTC_RAM 0x1c /*ram bit register*/
|
|
|
|
|
-#define RTC_CNTL 0x20 /*rtc counter register*/
|
|
|
|
|
-#define RTC_CNTH 0x24 /*rtc sec counter register*/
|
|
|
|
|
-
|
|
|
|
|
-//RTC_CTL register fields defination
|
|
|
|
|
-#define CTL_CTL3_VALUE(x) (x<<23)
|
|
|
|
|
-#define CTL_CTL2_VALUE(x) (x<<22)
|
|
|
|
|
-#define CTL_BIAS_TRM_VALUE(x) (x<<21)
|
|
|
|
|
-#define CTL_SOFT_SEL_VALUE(x) (x<<20)
|
|
|
|
|
-#define CTL_CTL1_VALUE(x) (x<<19)
|
|
|
|
|
-#define CTL_CTL0_VALUE(x) (x<<18)
|
|
|
|
|
-#define CTL_SOFT_STR_VALUE(x) (x<<17)
|
|
|
|
|
-#define CTL_OSC_EN_VALUE(x) (x<<16)
|
|
|
|
|
-#define CTL_CTL3_SET (1<<15)
|
|
|
|
|
-#define CTL_CTL2_SET (1<<14)
|
|
|
|
|
-#define CTL_BIAS_TRM_SET (1<<13)
|
|
|
|
|
-#define CTL_SOFT_SEL_SET (1<<12)
|
|
|
|
|
-#define CTL_CTL1_SET (1<<11)
|
|
|
|
|
-#define CTL_CTL0_SET (1<<10)
|
|
|
|
|
-#define CTL_SOFT_STR_SET (1<<9)
|
|
|
|
|
-#define CTL_OSC_EN_SET (1<<8)
|
|
|
|
|
-#define CTL_ALM_DATA_WEN (1<<3)
|
|
|
|
|
-#define CTL_PERIOD_INT_EN (1<<2)
|
|
|
|
|
-#define CTL_ALARM_INT_EN (1<<1)
|
|
|
|
|
-#define CTL_RESET (1<<0)
|
|
|
|
|
-
|
|
|
|
|
-//RTC_ANAWEN register fields defination
|
|
|
|
|
-#define ANA_CNT_WEN (1<<7)
|
|
|
|
|
-#define ANA_RAM_WEN (1<<6)
|
|
|
|
|
-#define ANA_DELAY_TIMER_WEN (1<<5)
|
|
|
|
|
-#define ANA_CLR_PWR_DET_WEN (1<<4)
|
|
|
|
|
-#define ANA_DELAY_POWER_ON_WEN (1<<3)
|
|
|
|
|
-#define ANA_FORCE_POWER_OFF_WEN (1<<2)
|
|
|
|
|
-#define ANA_FORCE_POWER_ON_WEN (1<<1)
|
|
|
|
|
-#define ANA_RTC_WEN (1<<0)
|
|
|
|
|
-
|
|
|
|
|
-//RTC_ANACTL register fields defination
|
|
|
|
|
-#define ANACTL_CLR_PWR (1<<4)
|
|
|
|
|
-#define ANACTL_DELAY_POWER_ON (1<<3)
|
|
|
|
|
-#define ANACTL_FORCE_POWER_OFF (1<<2)
|
|
|
|
|
-#define ANACTL_FORCE_POWER_ON (1<<1)
|
|
|
|
|
-#define ANACTL_COUNTER_EN (1<<0)
|
|
|
|
|
-
|
|
|
|
|
-/* STATUS_REG */
|
|
|
|
|
-#define STA_PWR_DET (1<<6)
|
|
|
|
|
-#define STA_DELAY_ON (1<<5)
|
|
|
|
|
-#define STA_FORCE_OFF (1<<4)
|
|
|
|
|
-#define STA_FORCE_ON (1<<3)
|
|
|
|
|
-#define STA_RCT_BUSY (1<<2)
|
|
|
|
|
-#define STA_PERIOD_INT (1<<1)
|
|
|
|
|
-#define STA_ALARM_INT (1<<0)
|
|
|
|
|
|
|
|
|
|
/* 2020-01-01 Wednesday */
|
|
/* 2020-01-01 Wednesday */
|
|
|
static struct rtc_time default_tm = {
|
|
static struct rtc_time default_tm = {
|
|
@@ -216,92 +157,7 @@ uint32_t mktime(const unsigned int year0, const unsigned int mon0,
|
|
|
uint32_t rtc_tm_to_time(struct rtc_time *tm)
|
|
uint32_t rtc_tm_to_time(struct rtc_time *tm)
|
|
|
{
|
|
{
|
|
|
return mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
|
return mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
|
|
- tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static __INLINE void rtc_clear_interrupt(void)
|
|
|
|
|
-{
|
|
|
|
|
- unsigned int val;
|
|
|
|
|
-
|
|
|
|
|
- val = readl(REGS_RTC_BASE + RTC_STA);
|
|
|
|
|
- val &= ~CTL_ALARM_INT_EN;
|
|
|
|
|
- writel(val, REGS_RTC_BASE + RTC_STA);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static __INLINE void rtc_enable_interrupt(void)
|
|
|
|
|
-{
|
|
|
|
|
- unsigned int val;
|
|
|
|
|
-
|
|
|
|
|
- val = readl(REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- if (!(val & CTL_ALARM_INT_EN)) {
|
|
|
|
|
- rtc_clear_interrupt();
|
|
|
|
|
- val |= CTL_ALARM_INT_EN;
|
|
|
|
|
- writel(val, REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static __INLINE void rtc_disable_interrupt(void)
|
|
|
|
|
-{
|
|
|
|
|
- unsigned int val;
|
|
|
|
|
-
|
|
|
|
|
- val = readl(REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- if (val & CTL_ALARM_INT_EN) {
|
|
|
|
|
- val &= ~CTL_ALARM_INT_EN;
|
|
|
|
|
- writel(val, REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static void rtc_wait_not_busy(void)
|
|
|
|
|
-{
|
|
|
|
|
- int status, count = 0;
|
|
|
|
|
-
|
|
|
|
|
- /* Assuming BUSY may stay active for 80 msec) */
|
|
|
|
|
- for (count = 0; count < 0x1000; count++) {
|
|
|
|
|
- status = readl(REGS_RTC_BASE + RTC_STA);
|
|
|
|
|
- if ((status & STA_RCT_BUSY) == 0)
|
|
|
|
|
- break;
|
|
|
|
|
- /* check status busy, after each msec */
|
|
|
|
|
- vTaskDelay(pdMS_TO_TICKS(1));
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static void rtc_isr(void *para)
|
|
|
|
|
-{
|
|
|
|
|
- unsigned int irq_data;
|
|
|
|
|
-
|
|
|
|
|
- irq_data = readl(REGS_RTC_BASE + RTC_STA);
|
|
|
|
|
-
|
|
|
|
|
- if ((irq_data & CTL_ALARM_INT_EN)) {
|
|
|
|
|
- rtc_clear_interrupt();
|
|
|
|
|
- return;
|
|
|
|
|
- } else
|
|
|
|
|
- return;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-static void rtc_update_time(unsigned int time)
|
|
|
|
|
-{
|
|
|
|
|
- unsigned int val;
|
|
|
|
|
- int timeout = 100000;
|
|
|
|
|
-
|
|
|
|
|
- val = readl(REGS_RTC_BASE + RTC_ANAWEN);
|
|
|
|
|
- writel(val | ANA_RTC_WEN, REGS_RTC_BASE + RTC_ANAWEN);
|
|
|
|
|
- val = readl(REGS_RTC_BASE + RTC_ANACTL);
|
|
|
|
|
- writel(val | ANACTL_COUNTER_EN, REGS_RTC_BASE + RTC_ANACTL);
|
|
|
|
|
-
|
|
|
|
|
- //wait rtc_busy;
|
|
|
|
|
- rtc_wait_not_busy();
|
|
|
|
|
-
|
|
|
|
|
- val = readl(REGS_RTC_BASE + RTC_ANAWEN);
|
|
|
|
|
- writel(val | ANA_CNT_WEN, REGS_RTC_BASE + RTC_ANAWEN);
|
|
|
|
|
- writel(time, REGS_RTC_BASE + RTC_CNTH);
|
|
|
|
|
-
|
|
|
|
|
- //wait rtc_busy;
|
|
|
|
|
- rtc_wait_not_busy();
|
|
|
|
|
- while(readl(REGS_RTC_BASE + RTC_CNTH) != time) {
|
|
|
|
|
- if (timeout-- == 0)
|
|
|
|
|
- break;
|
|
|
|
|
- taskYIELD();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -317,10 +173,7 @@ static int rtc_read_time(struct rtc_time *tm)
|
|
|
#ifdef ACCESS_RTC_SUPPORT
|
|
#ifdef ACCESS_RTC_SUPPORT
|
|
|
AccessRTC(ART_GET_TIME, &time);
|
|
AccessRTC(ART_GET_TIME, &time);
|
|
|
#else
|
|
#else
|
|
|
- /* we don't report wday/yday/isdst ... */
|
|
|
|
|
- rtc_wait_not_busy();
|
|
|
|
|
-
|
|
|
|
|
- time = readl(REGS_RTC_BASE + RTC_CNTH);
|
|
|
|
|
|
|
+ //
|
|
|
#endif
|
|
#endif
|
|
|
rtc_time_to_tm(time, tm);
|
|
rtc_time_to_tm(time, tm);
|
|
|
|
|
|
|
@@ -346,135 +199,14 @@ static int rtc_set_time(struct rtc_time *tm)
|
|
|
#ifdef ACCESS_RTC_SUPPORT
|
|
#ifdef ACCESS_RTC_SUPPORT
|
|
|
return AccessRTC(ART_SET_TIME, &time);
|
|
return AccessRTC(ART_SET_TIME, &time);
|
|
|
#else
|
|
#else
|
|
|
- rtc_update_time(time);
|
|
|
|
|
-#endif
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-#if 0
|
|
|
|
|
-static void rtc_update_alarm_time(unsigned int time)
|
|
|
|
|
-{
|
|
|
|
|
- unsigned int val;
|
|
|
|
|
- int timeout = 100000;
|
|
|
|
|
-
|
|
|
|
|
- val = readl(REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- writel(val | CTL_ALM_DATA_WEN, REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
-
|
|
|
|
|
- writel(time, REGS_RTC_BASE + RTC_ALMDAT);
|
|
|
|
|
-
|
|
|
|
|
- //wait rtc_busy;
|
|
|
|
|
- rtc_wait_not_busy();
|
|
|
|
|
- while(readl(REGS_RTC_BASE + RTC_ALMDAT) != time) {
|
|
|
|
|
- if (timeout-- == 0)
|
|
|
|
|
- break;
|
|
|
|
|
- taskYIELD();
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/*
|
|
|
|
|
- * rtc_read_alarm - read the alarm time
|
|
|
|
|
- * @alm: holds alarm date and time
|
|
|
|
|
- *
|
|
|
|
|
- * This function read alarm time and date. On success it will return 0
|
|
|
|
|
- * otherwise -ve error is returned.
|
|
|
|
|
- */
|
|
|
|
|
-static int rtc_read_alarm(struct rtc_wkalrm *alm)
|
|
|
|
|
-{
|
|
|
|
|
- unsigned int time;
|
|
|
|
|
-
|
|
|
|
|
- rtc_wait_not_busy();
|
|
|
|
|
-
|
|
|
|
|
- time = readl(REGS_RTC_BASE + RTC_ALMDAT);
|
|
|
|
|
-
|
|
|
|
|
- rtc_time_to_tm(time, &alm->time);
|
|
|
|
|
-
|
|
|
|
|
- alm->enabled = readl(REGS_RTC_BASE + RTC_CTL) & CTL_ALARM_INT_EN;
|
|
|
|
|
-
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/*
|
|
|
|
|
- * rtc_set_alarm - set the alarm time
|
|
|
|
|
- * @alm: holds alarm date and time
|
|
|
|
|
- *
|
|
|
|
|
- * This function set alarm time and date. On success it will return 0
|
|
|
|
|
- * otherwise -ve error is returned.
|
|
|
|
|
- */
|
|
|
|
|
-static int rtc_set_alarm(struct rtc_wkalrm *alm)
|
|
|
|
|
-{
|
|
|
|
|
- long unsigned int time;
|
|
|
|
|
-
|
|
|
|
|
- if (rtc_valid_tm(&alm->time) < 0)
|
|
|
|
|
- return -EINVAL;
|
|
|
|
|
-
|
|
|
|
|
- /* convert tm to seconds. */
|
|
|
|
|
- time = rtc_tm_to_time(&alm->time);
|
|
|
|
|
-
|
|
|
|
|
- rtc_update_alarm_time(time);
|
|
|
|
|
-
|
|
|
|
|
- if (alm->enabled)
|
|
|
|
|
- rtc_enable_interrupt();
|
|
|
|
|
- else
|
|
|
|
|
- rtc_disable_interrupt();
|
|
|
|
|
-
|
|
|
|
|
- return 0;
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ //
|
|
|
#endif
|
|
#endif
|
|
|
-
|
|
|
|
|
-static int alarm_irq_enable(unsigned int enabled)
|
|
|
|
|
-{
|
|
|
|
|
- int ret = 0;
|
|
|
|
|
-
|
|
|
|
|
- rtc_clear_interrupt();
|
|
|
|
|
-
|
|
|
|
|
- switch (enabled) {
|
|
|
|
|
- case 0:
|
|
|
|
|
- /* alarm off */
|
|
|
|
|
- rtc_disable_interrupt();
|
|
|
|
|
- break;
|
|
|
|
|
- case 1:
|
|
|
|
|
- /* alarm on */
|
|
|
|
|
- rtc_enable_interrupt();
|
|
|
|
|
- break;
|
|
|
|
|
- default:
|
|
|
|
|
- ret = -EINVAL;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return ret;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-int rtc_init(void)
|
|
|
|
|
-{
|
|
|
|
|
- struct rtc_time tm;
|
|
|
|
|
-
|
|
|
|
|
- writel(0, REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- writel(CTL_SOFT_STR_SET|CTL_SOFT_STR_VALUE(1), REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- writel(CTL_OSC_EN_SET|CTL_OSC_EN_VALUE(0), REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- writel(CTL_CTL0_SET|CTL_CTL0_VALUE(0), REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- writel(CTL_CTL1_SET|CTL_CTL1_VALUE(0), REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- writel(CTL_CTL2_SET|CTL_CTL2_VALUE(0), REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- writel(CTL_CTL3_SET|CTL_CTL3_VALUE(0), REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- writel(CTL_BIAS_TRM_SET|CTL_BIAS_TRM_VALUE(1)|CTL_CTL3_VALUE(0), REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- udelay(1000);
|
|
|
|
|
- writel(CTL_OSC_EN_SET|CTL_OSC_EN_VALUE(1), REGS_RTC_BASE + RTC_CTL);
|
|
|
|
|
- udelay(1000);
|
|
|
|
|
-
|
|
|
|
|
- request_irq(RTC_PRD_IRQn, 0, rtc_isr, NULL);
|
|
|
|
|
- alarm_irq_enable(0);
|
|
|
|
|
-
|
|
|
|
|
- rtc_read_time(&tm);
|
|
|
|
|
- if (tm.tm_year == 70) {
|
|
|
|
|
- rtc_set_time(&default_tm);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int iGetLocalTime(SystemTime_t *tm)
|
|
int iGetLocalTime(SystemTime_t *tm)
|
|
|
{
|
|
{
|
|
|
- if(tm == NULL)
|
|
|
|
|
|
|
+ if (tm == NULL)
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
|
|
rtc_read_time(tm);
|
|
rtc_read_time(tm);
|
|
@@ -485,7 +217,7 @@ int iGetLocalTime(SystemTime_t *tm)
|
|
|
|
|
|
|
|
int iSetLocalTime(SystemTime_t *tm)
|
|
int iSetLocalTime(SystemTime_t *tm)
|
|
|
{
|
|
{
|
|
|
- if(tm == NULL)
|
|
|
|
|
|
|
+ if (tm == NULL)
|
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
|
|
tm->tm_year -= 1900;
|
|
tm->tm_year -= 1900;
|