Statistics
| Branch: | Revision:

root / prex-0.9.0 / bsp / drv / dev / rtc / mc146818.c @ 03e9c04a

History | View | Annotate | Download (3.79 KB)

1
/*-
2
 * Copyright (c) 2005-2009, Kohsuke Ohtani
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
/*
31
 * mc146818.c - mc146818 and compatible RTC
32
 */
33

    
34
#include <sys/time.h>
35
#include <sys/ioctl.h>
36

    
37
#include <driver.h>
38
#include <rtc.h>
39

    
40

    
41
#define RTC_INDEX        (CONFIG_MC146818_BASE + 0)
42
#define RTC_DATA        (CONFIG_MC146818_BASE + 1)
43

    
44
#define RTC_SEC                0x00
45
#define RTC_MIN                0x02
46
#define RTC_HOUR        0x04
47
#define RTC_DOW                0x06        /* day of week */
48
#define RTC_DAY                0x07
49
#define RTC_MON                0x08
50
#define RTC_YEAR        0x09
51
#define RTC_STS_A        0x0a
52
#define RTC_UIP                  0x80
53
#define RTC_STS_B        0x0b
54
#define RTC_BCD                  0x04
55

    
56
static int        mc146818_init(struct driver *);
57
static int        mc146818_gettime(void *, struct timeval *);
58
static int        mc146818_settime(void *, struct timeval *);
59

    
60

    
61
struct driver mc146818_driver = {
62
        /* name */        "mc146818",
63
        /* devops */        NULL,
64
        /* devsz */        0,
65
        /* flags */        0,
66
        /* probe */        NULL,
67
        /* init */        mc146818_init,
68
        /* shutdown */        NULL,
69
};
70

    
71
struct rtc_ops mc146818_ops = {
72
        /* gettime */        mc146818_gettime,
73
        /* settime */        mc146818_settime,
74
};
75

    
76
static u_char
77
mc_read(u_char index)
78
{
79
        u_char val;
80
        int s;
81

    
82
        s = splhigh();
83
        bus_write_8(RTC_INDEX, index);
84
        val = bus_read_8(RTC_DATA);
85
        splx(s);
86
        return val;
87
}
88

    
89
#if 0
90
static void
91
mc_write(u_char index, u_char val)
92
{
93
        int s;
94

95
        s = splhigh();
96
        bus_write_8(RTC_INDEX, index);
97
        bus_write_8(RTC_DATA, val);
98
        splx(s);
99
}
100
#endif
101

    
102
static int
103
mc146818_gettime(void *aux, struct timeval *tv)
104
{
105
        struct clock_ymdhms cy;
106
        int i;
107

    
108
        /* Wait until data ready */
109
        for (i = 0; i < 1000000; i++)
110
                if (!(mc_read(RTC_STS_A) & RTC_UIP))
111
                        break;
112

    
113
        cy.nsec = 0;
114
        cy.sec = mc_read(RTC_SEC);
115
        cy.min = mc_read(RTC_MIN);
116
        cy.hour = mc_read(RTC_HOUR);
117
        cy.dow = mc_read(RTC_DOW);
118
        cy.day = mc_read(RTC_DAY);
119
        cy.mon = mc_read(RTC_MON);
120
        cy.year = mc_read(RTC_YEAR);
121

    
122
        if (!(mc_read(RTC_STS_B) & RTC_BCD)) {
123
                cy.sec = FROMBCD(cy.sec);
124
                cy.min = FROMBCD(cy.min);
125
                cy.hour = FROMBCD(cy.hour);
126
                cy.day = FROMBCD(cy.day);
127
                cy.mon = FROMBCD(cy.mon);
128
                cy.year = FROMBCD(cy.year);
129
        }
130
        if (cy.year < 80)
131
                cy.year += 2000;
132
        else
133
                cy.year += 1900;
134
#ifdef DEBUG
135
        printf("rtc: system time was %d/%d/%d %d:%d:%d\n",
136
                cy.year, cy.mon, cy.day, cy.hour, cy.min, cy.sec);
137
#endif
138
        tv->tv_usec = 0;
139
        tv->tv_sec = rtc_ymdhms_to_secs(&cy);
140
        return 0;
141
}
142

    
143
static int
144
mc146818_settime(void *aux, struct timeval *ts)
145
{
146
        return 0;
147
}
148

    
149
static int
150
mc146818_init(struct driver *self)
151
{
152

    
153
        rtc_attach(&mc146818_ops, NULL);
154
        return 0;
155
}