~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/drivers/rtc/ds1337.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2001-2008
 
3
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
4
 * Keith Outwater, keith_outwater@mvis.com`
 
5
 *
 
6
 * SPDX-License-Identifier:     GPL-2.0+
 
7
 */
 
8
 
 
9
/*
 
10
 * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
 
11
 * DS1337 Real Time Clock (RTC).
 
12
 */
 
13
 
 
14
#include <common.h>
 
15
#include <command.h>
 
16
#include <rtc.h>
 
17
#include <i2c.h>
 
18
 
 
19
#if defined(CONFIG_CMD_DATE)
 
20
 
 
21
/*
 
22
 * RTC register addresses
 
23
 */
 
24
#if defined CONFIG_RTC_DS1337
 
25
#define RTC_SEC_REG_ADDR        0x0
 
26
#define RTC_MIN_REG_ADDR        0x1
 
27
#define RTC_HR_REG_ADDR         0x2
 
28
#define RTC_DAY_REG_ADDR        0x3
 
29
#define RTC_DATE_REG_ADDR       0x4
 
30
#define RTC_MON_REG_ADDR        0x5
 
31
#define RTC_YR_REG_ADDR         0x6
 
32
#define RTC_CTL_REG_ADDR        0x0e
 
33
#define RTC_STAT_REG_ADDR       0x0f
 
34
#define RTC_TC_REG_ADDR         0x10
 
35
#elif defined CONFIG_RTC_DS1388
 
36
#define RTC_SEC_REG_ADDR        0x1
 
37
#define RTC_MIN_REG_ADDR        0x2
 
38
#define RTC_HR_REG_ADDR         0x3
 
39
#define RTC_DAY_REG_ADDR        0x4
 
40
#define RTC_DATE_REG_ADDR       0x5
 
41
#define RTC_MON_REG_ADDR        0x6
 
42
#define RTC_YR_REG_ADDR         0x7
 
43
#define RTC_CTL_REG_ADDR        0x0c
 
44
#define RTC_STAT_REG_ADDR       0x0b
 
45
#define RTC_TC_REG_ADDR         0x0a
 
46
#endif
 
47
 
 
48
/*
 
49
 * RTC control register bits
 
50
 */
 
51
#define RTC_CTL_BIT_A1IE        0x1     /* Alarm 1 interrupt enable     */
 
52
#define RTC_CTL_BIT_A2IE        0x2     /* Alarm 2 interrupt enable     */
 
53
#define RTC_CTL_BIT_INTCN       0x4     /* Interrupt control            */
 
54
#define RTC_CTL_BIT_RS1         0x8     /* Rate select 1                */
 
55
#define RTC_CTL_BIT_RS2         0x10    /* Rate select 2                */
 
56
#define RTC_CTL_BIT_DOSC        0x80    /* Disable Oscillator           */
 
57
 
 
58
/*
 
59
 * RTC status register bits
 
60
 */
 
61
#define RTC_STAT_BIT_A1F        0x1     /* Alarm 1 flag                 */
 
62
#define RTC_STAT_BIT_A2F        0x2     /* Alarm 2 flag                 */
 
63
#define RTC_STAT_BIT_OSF        0x80    /* Oscillator stop flag         */
 
64
 
 
65
 
 
66
static uchar rtc_read (uchar reg);
 
67
static void rtc_write (uchar reg, uchar val);
 
68
 
 
69
/*
 
70
 * Get the current time from the RTC
 
71
 */
 
72
int rtc_get (struct rtc_time *tmp)
 
73
{
 
74
        int rel = 0;
 
75
        uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
 
76
 
 
77
        control = rtc_read (RTC_CTL_REG_ADDR);
 
78
        status = rtc_read (RTC_STAT_REG_ADDR);
 
79
        sec = rtc_read (RTC_SEC_REG_ADDR);
 
80
        min = rtc_read (RTC_MIN_REG_ADDR);
 
81
        hour = rtc_read (RTC_HR_REG_ADDR);
 
82
        wday = rtc_read (RTC_DAY_REG_ADDR);
 
83
        mday = rtc_read (RTC_DATE_REG_ADDR);
 
84
        mon_cent = rtc_read (RTC_MON_REG_ADDR);
 
85
        year = rtc_read (RTC_YR_REG_ADDR);
 
86
 
 
87
        /* No century bit, assume year 2000 */
 
88
#ifdef CONFIG_RTC_DS1388
 
89
        mon_cent |= 0x80;
 
90
#endif
 
91
 
 
92
        debug("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
 
93
                "hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
 
94
                year, mon_cent, mday, wday, hour, min, sec, control, status);
 
95
 
 
96
        if (status & RTC_STAT_BIT_OSF) {
 
97
                printf ("### Warning: RTC oscillator has stopped\n");
 
98
                /* clear the OSF flag */
 
99
                rtc_write (RTC_STAT_REG_ADDR,
 
100
                           rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
 
101
                rel = -1;
 
102
        }
 
103
 
 
104
        tmp->tm_sec  = bcd2bin (sec & 0x7F);
 
105
        tmp->tm_min  = bcd2bin (min & 0x7F);
 
106
        tmp->tm_hour = bcd2bin (hour & 0x3F);
 
107
        tmp->tm_mday = bcd2bin (mday & 0x3F);
 
108
        tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
 
109
        tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
 
110
        tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
 
111
        tmp->tm_yday = 0;
 
112
        tmp->tm_isdst= 0;
 
113
 
 
114
        debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 
115
                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 
116
                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 
117
 
 
118
        return rel;
 
119
}
 
120
 
 
121
 
 
122
/*
 
123
 * Set the RTC
 
124
 */
 
125
int rtc_set (struct rtc_time *tmp)
 
126
{
 
127
        uchar century;
 
128
 
 
129
        debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
 
130
                tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
 
131
                tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
 
132
 
 
133
        rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
 
134
 
 
135
        century = (tmp->tm_year >= 2000) ? 0x80 : 0;
 
136
        rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
 
137
 
 
138
        rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
 
139
        rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
 
140
        rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
 
141
        rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
 
142
        rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
 
143
 
 
144
        return 0;
 
145
}
 
146
 
 
147
 
 
148
/*
 
149
 * Reset the RTC.  We also enable the oscillator output on the
 
150
 * SQW/INTB* pin and program it for 32,768 Hz output. Note that
 
151
 * according to the datasheet, turning on the square wave output
 
152
 * increases the current drain on the backup battery from about
 
153
 * 600 nA to 2uA. Define CONFIG_SYS_RTC_DS1337_NOOSC if you wish to turn
 
154
 * off the OSC output.
 
155
 */
 
156
 
 
157
#ifdef CONFIG_SYS_RTC_DS1337_NOOSC
 
158
 #define RTC_DS1337_RESET_VAL \
 
159
        (RTC_CTL_BIT_INTCN | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2)
 
160
#else
 
161
 #define RTC_DS1337_RESET_VAL (RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2)
 
162
#endif
 
163
void rtc_reset (void)
 
164
{
 
165
#ifdef CONFIG_SYS_RTC_DS1337
 
166
        rtc_write (RTC_CTL_REG_ADDR, RTC_DS1337_RESET_VAL);
 
167
#elif defined CONFIG_SYS_RTC_DS1388
 
168
        rtc_write(RTC_CTL_REG_ADDR, 0x0); /* hw default */
 
169
#endif
 
170
#ifdef CONFIG_SYS_DS1339_TCR_VAL
 
171
        rtc_write (RTC_TC_REG_ADDR, CONFIG_SYS_DS1339_TCR_VAL);
 
172
#endif
 
173
#ifdef CONFIG_SYS_DS1388_TCR_VAL
 
174
        rtc_write(RTC_TC_REG_ADDR, CONFIG_SYS_DS1388_TCR_VAL);
 
175
#endif
 
176
}
 
177
 
 
178
 
 
179
/*
 
180
 * Helper functions
 
181
 */
 
182
 
 
183
static
 
184
uchar rtc_read (uchar reg)
 
185
{
 
186
        return (i2c_reg_read (CONFIG_SYS_I2C_RTC_ADDR, reg));
 
187
}
 
188
 
 
189
 
 
190
static void rtc_write (uchar reg, uchar val)
 
191
{
 
192
        i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
 
193
}
 
194
 
 
195
#endif