OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [kernel/] [iic.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 * linux/arch/arm/kernel/iic.c
3
 *
4
 * Copyright (C) 1995, 1996 Russell King
5
 *
6
 * IIC is used to get the current time from the CMOS rtc.
7
 */
8
 
9
#include <asm/system.h>
10
#include <asm/delay.h>
11
#include <asm/io.h>
12
#include <asm/hardware.h>
13
 
14
#define FORCE_ONES      0xdc
15
 
16
/*
17
 * if delay loop has been calibrated then us that,
18
 * else use IOC timer 1.
19
 */
20
static void iic_delay (void)
21
{
22
        extern unsigned long loops_per_sec;
23
        if (loops_per_sec != (1 << 12)) {
24
                udelay(10);
25
                return;
26
        } else {
27
                unsigned long flags;
28
                save_flags_cli(flags);
29
 
30
                outb(254,  IOC_T1LTCHL);
31
                outb(255,  IOC_T1LTCHH);
32
                outb(0,    IOC_T1GO);
33
                outb(1<<6, IOC_IRQCLRA);                        /* clear T1 irq */
34
                outb(4,    IOC_T1LTCHL);
35
                outb(0,    IOC_T1LTCHH);
36
                outb(0,    IOC_T1GO);
37
                while ((inb(IOC_IRQSTATA) & (1<<6)) == 0);
38
                restore_flags(flags);
39
        }
40
}
41
 
42
static inline void iic_start (void)
43
{
44
        unsigned char out;
45
 
46
        out = inb(IOC_CONTROL) | FORCE_ONES | 0x02;
47
 
48
        outb(out, IOC_CONTROL);
49
        iic_delay();
50
 
51
        outb(out ^ 1, IOC_CONTROL);
52
        iic_delay();
53
}
54
 
55
static inline void iic_stop (void)
56
{
57
        unsigned char out;
58
 
59
        out = inb(IOC_CONTROL) | FORCE_ONES | 0x03;
60
 
61
        iic_delay();
62
        outb(out ^ 1, IOC_CONTROL);
63
 
64
        iic_delay();
65
        outb(out, IOC_CONTROL);
66
}
67
 
68
static int iic_sendbyte (unsigned char b)
69
{
70
        unsigned char out, in;
71
        int i;
72
 
73
        out = (inb(IOC_CONTROL) & 0xfc) | FORCE_ONES;
74
 
75
        outb(out, IOC_CONTROL);
76
        for (i = 7; i >= 0; i--) {
77
                unsigned char c;
78
                c = out | ((b & (1 << i)) ? 1 : 0);
79
 
80
                outb(c, IOC_CONTROL);
81
                iic_delay();
82
 
83
                outb(c | 2, IOC_CONTROL);
84
                iic_delay();
85
 
86
                outb(c, IOC_CONTROL);
87
        }
88
        outb(out | 1, IOC_CONTROL);
89
        iic_delay();
90
 
91
        outb(out | 3, IOC_CONTROL);
92
        iic_delay();
93
 
94
        in = inb(IOC_CONTROL) & 1;
95
 
96
        outb(out | 1, IOC_CONTROL);
97
        iic_delay();
98
 
99
        outb(out, IOC_CONTROL);
100
        iic_delay();
101
 
102
        if(in) {
103
                printk("No acknowledge from RTC\n");
104
                return 1;
105
        } else
106
                return 0;
107
}
108
 
109
static unsigned char iic_recvbyte (void)
110
{
111
        unsigned char out, in;
112
        int i;
113
 
114
        out = (inb(IOC_CONTROL) & 0xfc) | FORCE_ONES;
115
 
116
        outb(out, IOC_CONTROL);
117
        in = 0;
118
        for (i = 7; i >= 0; i--) {
119
                outb(out | 1, IOC_CONTROL);
120
                iic_delay();
121
                outb(out | 3, IOC_CONTROL);
122
                iic_delay();
123
                in = (in << 1) | (inb(IOC_CONTROL) & 1);
124
                outb(out | 1, IOC_CONTROL);
125
                iic_delay();
126
        }
127
        outb(out, IOC_CONTROL);
128
        iic_delay();
129
        outb(out | 2, IOC_CONTROL);
130
        iic_delay();
131
 
132
        return in;
133
}
134
 
135
void iic_control (unsigned char addr, unsigned char loc, unsigned char *buf, int len)
136
{
137
        iic_start();
138
 
139
        if (iic_sendbyte(addr & 0xfe))
140
                goto error;
141
 
142
        if (iic_sendbyte(loc))
143
                goto error;
144
 
145
        if (addr & 1) {
146
                int i;
147
 
148
                for (i = 0; i < len; i++)
149
                        if (iic_sendbyte (buf[i]))
150
                                break;
151
        } else {
152
                int i;
153
 
154
                iic_stop();
155
                iic_start();
156
                iic_sendbyte(addr|1);
157
                for (i = 0; i < len; i++)
158
                        buf[i] = iic_recvbyte ();
159
        }
160
error:
161
        iic_stop();
162
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.