xref: /netbsd-src/sys/arch/mac68k/mac68k/pram.c (revision 5f7096188587a2c7c95fa3c69b78e1ec9c7923d0)
1 /*-
2  * Copyright (C) 1993	Allen K. Briggs, Chris P. Caputo,
3  *			Michael L. Finch, Bradley A. Grantham, and
4  *			Lawrence A. Kesteloot
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the Alice Group.
18  * 4. The names of the Alice Group or any of its members may not be used
19  *    to endorse or promote products derived from this software without
20  *    specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 #ident "$Id: pram.c,v 1.1.1.1 1993/09/29 06:09:15 briggs Exp $"
35 
36 
37 /* #include "stand.h"  */
38 #include "../dev/via.h"
39 
40 #define PRAM_SIZE	256
41 #define PRAM_GET	256
42 #define RTC_DATA	0x1
43 #define RTC_CLOCK	0x2
44 #define RTC_ENB		0x4
45 
46 #define PRAMCMD_SEC0	0x01
47 #define PRAMCMD_SEC1	0x05
48 #define PRAMCMD_SEC2	0x09
49 #define PRAMCMD_SEC3	0x0D
50 #define PRAMCMD_TEST	0x31
51 #define PRAMCMD_WPRT	0x35
52 #define PRAMCMD_RA1x	0x21
53 #define	PRAMCMD_RA0x	0x41
54 #define	PRAMCMD_READ	0x80
55 #define PRAMBIT_WRIT	0xf0
56 #define PRAMADDR_SHF	2
57 
58 #define PRAMCMD_SEL	0x38
59 #define PRAMCMD_EXT	0x0
60 #define PRAM_SECT_MASK	0xE0 /* 0x1C0 */
61 #define PRAM_BYTE_MASK	0x1F /* 0x3F */
62 #define PRAM_SECT_SHF	5
63 #define PRAM_BYTE_SHF	2
64 
65 unsigned char pram_save[PRAM_SIZE];
66 int pram_chr = 0;
67 
68 
69 void pram_enable()
70 {
71 	/* enable serial function */
72    via_reg(VIA1, vDirB) = RTC_ENB;
73    via_reg(VIA1, vBufB) = RTC_ENB;	/* flush? */
74    via_reg(VIA1, vBufB) = 0;
75 }
76 
77 
78 void pram_disable()
79 {
80       /* disable serial function */
81    via_reg(VIA1, vDirB) = RTC_ENB | vDirA_ADBState;
82    via_reg(VIA1, vBufB) = RTC_ENB;
83 }
84 
85 
86 unsigned char pram_getbyte(void)
87 {
88    int bitnum;
89    unsigned char data;
90 
91    data = 0;
92 
93    via_reg(VIA1, vDirB) |= RTC_CLOCK;
94 
95    for(bitnum = 0; bitnum < 8; bitnum++){
96 
97          /* lower clock bit (please send data) */
98       via_reg(VIA1, vBufB) = 0;
99 
100          /* get data bit */
101       data = (data << 1) | (via_reg(VIA1, vBufB) & RTC_DATA);
102 
103          /* raise clock bit (please ready next data) */
104       via_reg(VIA1, vBufB) = RTC_CLOCK;
105    }
106 
107    via_reg(VIA1, vDirB) &= ~RTC_CLOCK;
108 
109    return(data);
110 }
111 
112 
113 void pram_putbyte(unsigned char data)
114 {
115    int bitnum;
116 
117    via_reg(VIA1, vDirB) |= RTC_CLOCK | RTC_DATA;
118 
119    for(bitnum = 0; bitnum < 8; bitnum++){
120 
121          /* lower clock bit (please accept data) */
122       via_reg(VIA1, vBufB) = 0;
123 
124          /* send data bit */
125       via_reg(VIA1, vBufB) = (data & (1 << (7 - bitnum))) ? RTC_DATA : 0;
126 
127          /* raise clock bit (please store the data) */
128       via_reg(VIA1, vBufB) = RTC_CLOCK;
129    }
130 
131    via_reg(VIA1, vDirB) &= ~(RTC_CLOCK | RTC_DATA);
132 }
133 
134 
135 unsigned char pram_read(unsigned char cmd)
136 {
137    unsigned char data=0;
138 
139    pram_enable();
140    pram_putbyte(cmd | PRAMCMD_READ);
141    data = pram_getbyte();
142    pram_disable();
143 
144    return(data);
145 }
146 
147 
148 void pram_write(unsigned char cmd, unsigned char val)
149 {
150    pram_enable();
151    pram_putbyte(cmd);
152    pram_putbyte(val);
153    pram_disable();
154 }
155 
156 
157 unsigned char pram_ext_read(int addr)
158 {
159    unsigned char data;
160    int sect, byte;
161 
162    sect = (addr & PRAM_SECT_MASK) >> PRAM_SECT_SHF;
163    byte = (addr & PRAM_BYTE_MASK) << PRAM_BYTE_SHF;
164    pram_enable();
165    pram_putbyte(PRAMCMD_READ | PRAMCMD_SEL | sect);
166    pram_putbyte(PRAMCMD_EXT | byte);
167    data = pram_getbyte();
168    pram_disable();
169 
170    return(data);
171 }
172 
173 
174 void pram_ext_write(int addr, unsigned char val)
175 {
176    int sect, byte;
177 
178    sect = (addr & PRAM_SECT_MASK) >> PRAM_SECT_SHF;
179    byte = (addr & PRAM_BYTE_MASK) << PRAM_BYTE_SHF;
180    pram_enable();
181    pram_putbyte(PRAMCMD_SEL | sect);
182    pram_putbyte(PRAMCMD_EXT | byte);
183    pram_putbyte(val);
184    pram_disable();
185 }
186 
187 
188 unsigned char *pram_get(void)
189 {
190    int byte_get;
191 
192    printf("PRAM contents:\n");
193    for(byte_get = 0; byte_get < PRAM_GET; byte_get++){
194 
195       pram_save[byte_get] = pram_ext_read(byte_get);
196 
197       if(byte_get % 16 == 0)
198          printf("\n(%x)", byte_get);
199       printf("%x%s", pram_save[byte_get], (byte_get == PRAM_GET - 1)?"":", ");
200    }
201    printf("\n");
202 }
203 
204 char *convtime(unsigned long t)
205 {
206   static long daypmon[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
207   static char *monstr[] = {"January","February","March","April","May","June",
208     "July","August","September","October","November","December" };
209   static char s[200];
210   long year,month,day,hour,minute,seconds,i,dayperyear;
211 
212   year=1904;
213   month=0;  /* Jan */
214   day=1;
215   hour=0;
216   minute=0;
217   seconds=0;
218 
219   if(t == 0xffffffff)
220      return("<time value is -1>");
221 
222   while (t > 0)
223   {
224     if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
225     {
226       dayperyear=366;
227       daypmon[1]=29;
228     }
229     else
230     {
231       dayperyear=365;
232       daypmon[1]=28;
233     }
234     i=dayperyear*60*60*24;
235     if (t >= i)
236     {
237       t-=i;
238       year++;
239       continue;
240     }
241     i=daypmon[month]*60*60*24;
242     if (t >= i)
243     {
244       t-=i;
245       month++;
246       continue;
247     }
248     i=60*60*24;
249     if (t >= i)
250     {
251       t-=i;
252       day++;
253       continue;
254     }
255     i=60*60;
256     if (t >= i)
257     {
258       t-=i;
259       hour++;
260       continue;
261     }
262     i=60;
263     if (t >= i)
264     {
265       t-=i;
266       minute++;
267       continue;
268     }
269     seconds=t;
270     t=0;
271   }
272 
273   sprintf(s,"%s %d, %d   %d:%d:%d",monstr[month],day,year,hour,minute,seconds);
274 
275   return s;
276 }
277 
278 unsigned long pram_readtime(void)
279 {
280    unsigned long timedata,otim;
281 
282    timedata = 0;
283    otim = 0xffffffff;
284    while(otim != timedata){
285       otim = timedata;
286 
287       timedata = pram_read(PRAMCMD_SEC3);
288       timedata = (timedata << 8) | pram_read(PRAMCMD_SEC2);
289       timedata = (timedata << 8) | pram_read(PRAMCMD_SEC1);
290       timedata = (timedata << 8) | pram_read(PRAMCMD_SEC0);
291 
292       /* printf("time read from PRAM: %d\n", timedata); */
293       /* printf("Date and time: %s\n",convtime(timedata)); */
294    }
295 
296    pram_write(PRAMCMD_WPRT, 0xff);
297 
298    return(timedata);
299 }
300 
301 
302 int pram_settime(unsigned long time)
303 {
304    unsigned char t1, t2, t3, t4, tmp;
305    unsigned char ret;
306 
307    t1 = time & 0xff;
308    t2 = (time >>= 8) & 0xff;
309    t3 = (time >>= 8) & 0xff;
310    t4 = (time >>= 8) & 0xff;
311 
312    pram_write(PRAMCMD_WPRT, 0);
313 
314    pram_write(PRAMCMD_SEC0, 0);
315    tmp = pram_read(PRAMCMD_SEC1);
316    pram_write(PRAMCMD_SEC1, (tmp + 1) & 0xff);
317    if((ret=pram_read(PRAMCMD_SEC1)) != ((tmp + 1) & 0xff))
318    {
319 printf("we read ret=%x, tmp=%x (tmp+1) &0xff= %x\n",ret,tmp,(tmp +1) & 0xff);
320       return(0);
321    }
322    pram_write(PRAMCMD_SEC3, t4);
323    pram_write(PRAMCMD_SEC2, t3);
324    pram_write(PRAMCMD_SEC1, t2);
325    pram_write(PRAMCMD_SEC0, t1);
326 
327    pram_write(PRAMCMD_WPRT, 0xff);
328 
329    return(-1);
330 }
331