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