]>
Commit | Line | Data |
---|---|---|
b58d8b48 MF |
1 | /* |
2 | * Copyright (c) 2004-2008 Analog Devices Inc. | |
3 | * | |
4 | * (C) Copyright 2001 | |
5 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
6 | * | |
7 | * Licensed under the GPL-2 or later. | |
8 | */ | |
9 | ||
10 | #include <common.h> | |
11 | #include <command.h> | |
12 | #include <rtc.h> | |
13 | ||
871c18dd | 14 | #if defined(CONFIG_CMD_DATE) |
b58d8b48 MF |
15 | |
16 | #include <asm/blackfin.h> | |
17 | #include <asm/mach-common/bits/rtc.h> | |
18 | ||
19 | #define pr_stamp() debug("%s:%s:%i: here i am\n", __FILE__, __func__, __LINE__) | |
20 | ||
21 | #define MIN_TO_SECS(x) (60 * (x)) | |
22 | #define HRS_TO_SECS(x) (60 * MIN_TO_SECS(x)) | |
23 | #define DAYS_TO_SECS(x) (24 * HRS_TO_SECS(x)) | |
24 | ||
25 | #define NUM_SECS_IN_MIN MIN_TO_SECS(1) | |
26 | #define NUM_SECS_IN_HR HRS_TO_SECS(1) | |
27 | #define NUM_SECS_IN_DAY DAYS_TO_SECS(1) | |
28 | ||
3c879898 | 29 | /* Enable the RTC prescaler enable register */ |
c6577f72 | 30 | void rtc_init(void) |
3c879898 MF |
31 | { |
32 | if (!(bfin_read_RTC_PREN() & 0x1)) | |
33 | bfin_write_RTC_PREN(0x1); | |
34 | } | |
35 | ||
b58d8b48 MF |
36 | /* Our on-chip RTC has no notion of "reset" */ |
37 | void rtc_reset(void) | |
38 | { | |
3c879898 | 39 | rtc_init(); |
b58d8b48 MF |
40 | } |
41 | ||
42 | /* Wait for pending writes to complete */ | |
43 | static void wait_for_complete(void) | |
44 | { | |
45 | pr_stamp(); | |
46 | while (!(bfin_read_RTC_ISTAT() & WRITE_COMPLETE)) | |
47 | if (!(bfin_read_RTC_ISTAT() & WRITE_PENDING)) | |
48 | break; | |
49 | bfin_write_RTC_ISTAT(WRITE_COMPLETE); | |
50 | } | |
51 | ||
b58d8b48 MF |
52 | /* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers |
53 | * based on this value. | |
54 | */ | |
d1e23194 | 55 | int rtc_set(struct rtc_time *tmp) |
b58d8b48 MF |
56 | { |
57 | unsigned long remain, days, hrs, mins, secs; | |
58 | ||
59 | pr_stamp(); | |
60 | ||
61 | if (tmp == NULL) { | |
62 | puts("Error setting the date/time\n"); | |
d1e23194 | 63 | return -1; |
b58d8b48 MF |
64 | } |
65 | ||
3c879898 | 66 | rtc_init(); |
b58d8b48 MF |
67 | wait_for_complete(); |
68 | ||
69 | /* Calculate number of seconds this incoming time represents */ | |
71420983 | 70 | remain = rtc_mktime(tmp); |
b58d8b48 MF |
71 | |
72 | /* Figure out how many days since epoch */ | |
73 | days = remain / NUM_SECS_IN_DAY; | |
74 | ||
75 | /* From the remaining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */ | |
76 | remain = remain % NUM_SECS_IN_DAY; | |
77 | hrs = remain / NUM_SECS_IN_HR; | |
78 | remain = remain % NUM_SECS_IN_HR; | |
79 | mins = remain / NUM_SECS_IN_MIN; | |
80 | secs = remain % NUM_SECS_IN_MIN; | |
81 | ||
82 | /* Encode these time values into our RTC_STAT register */ | |
83 | bfin_write_RTC_STAT(SET_ALARM(days, hrs, mins, secs)); | |
d1e23194 JCPV |
84 | |
85 | return 0; | |
b58d8b48 MF |
86 | } |
87 | ||
88 | /* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */ | |
b73a19e1 | 89 | int rtc_get(struct rtc_time *tmp) |
b58d8b48 MF |
90 | { |
91 | uint32_t cur_rtc_stat; | |
92 | int time_in_sec; | |
93 | int tm_sec, tm_min, tm_hr, tm_day; | |
94 | ||
95 | pr_stamp(); | |
96 | ||
97 | if (tmp == NULL) { | |
98 | puts("Error getting the date/time\n"); | |
b73a19e1 | 99 | return -1; |
b58d8b48 MF |
100 | } |
101 | ||
3c879898 | 102 | rtc_init(); |
b58d8b48 MF |
103 | wait_for_complete(); |
104 | ||
105 | /* Read the RTC_STAT register */ | |
106 | cur_rtc_stat = bfin_read_RTC_STAT(); | |
107 | ||
108 | /* Convert our encoded format into actual time values */ | |
109 | tm_sec = (cur_rtc_stat & RTC_SEC) >> RTC_SEC_P; | |
110 | tm_min = (cur_rtc_stat & RTC_MIN) >> RTC_MIN_P; | |
111 | tm_hr = (cur_rtc_stat & RTC_HR ) >> RTC_HR_P; | |
112 | tm_day = (cur_rtc_stat & RTC_DAY) >> RTC_DAY_P; | |
113 | ||
114 | /* Calculate the total number of seconds since epoch */ | |
115 | time_in_sec = (tm_sec) + MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hr) + DAYS_TO_SECS(tm_day); | |
9f9276c3 | 116 | rtc_to_tm(time_in_sec, tmp); |
b73a19e1 YT |
117 | |
118 | return 0; | |
b58d8b48 MF |
119 | } |
120 | ||
121 | #endif |