xref: /netbsd-src/sys/arch/mac68k/mac68k/pram.c (revision 38023541164cff097d5fadec63134189b1453b8c)
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 
35 
36 /* #include "stand.h"  */
37 #include "../dev/via.h"
38 
39 #define PRAM_SIZE	256
40 #define PRAM_GET	256
41 #define RTC_DATA	0x1
42 #define RTC_CLOCK	0x2
43 #define RTC_ENB		0x4
44 
45 #define PRAMCMD_SEC0	0x01
46 #define PRAMCMD_SEC1	0x05
47 #define PRAMCMD_SEC2	0x09
48 #define PRAMCMD_SEC3	0x0D
49 #define PRAMCMD_TEST	0x31
50 #define PRAMCMD_WPRT	0x35
51 #define PRAMCMD_RA1x	0x21
52 #define	PRAMCMD_RA0x	0x41
53 #define	PRAMCMD_READ	0x80
54 #define PRAMBIT_WRIT	0xf0
55 #define PRAMADDR_SHF	2
56 
57 #define PRAMCMD_SEL	0x38
58 #define PRAMCMD_EXT	0x0
59 #define PRAM_SECT_MASK	0xE0 /* 0x1C0 */
60 #define PRAM_BYTE_MASK	0x1F /* 0x3F */
61 #define PRAM_SECT_SHF	5
62 #define PRAM_BYTE_SHF	2
63 
64 unsigned char pram_save[PRAM_SIZE];
65 int pram_chr = 0;
66 
67 void pram_enable()
68 {
69 	/* enable serial function */
70    via_reg(VIA1, vDirB) = RTC_ENB;
71    via_reg(VIA1, vBufB) = RTC_ENB;	/* flush? */
72    via_reg(VIA1, vBufB) = 0;
73 }
74 
75 
76 void pram_disable()
77 {
78       /* disable serial function */
79    via_reg(VIA1, vDirB) = RTC_ENB | vDirA_ADBState;
80    via_reg(VIA1, vBufB) = RTC_ENB;
81 }
82 
83 
84 unsigned char pram_getbyte(void)
85 {
86    int bitnum;
87    unsigned char data;
88 
89    data = 0;
90 
91    via_reg(VIA1, vDirB) |= RTC_CLOCK;
92 
93    for(bitnum = 0; bitnum < 8; bitnum++){
94 
95          /* lower clock bit (please send data) */
96       via_reg(VIA1, vBufB) = 0;
97 
98          /* get data bit */
99       data = (data << 1) | (via_reg(VIA1, vBufB) & RTC_DATA);
100 
101          /* raise clock bit (please ready next data) */
102       via_reg(VIA1, vBufB) = RTC_CLOCK;
103    }
104 
105    via_reg(VIA1, vDirB) &= ~RTC_CLOCK;
106 
107    return(data);
108 }
109 
110 
111 void pram_putbyte(unsigned char data)
112 {
113    int bitnum;
114 
115    via_reg(VIA1, vDirB) |= RTC_CLOCK | RTC_DATA;
116 
117    for(bitnum = 0; bitnum < 8; bitnum++){
118 
119          /* lower clock bit (please accept data) */
120       via_reg(VIA1, vBufB) = 0;
121 
122          /* send data bit */
123       via_reg(VIA1, vBufB) = (data & (1 << (7 - bitnum))) ? RTC_DATA : 0;
124 
125          /* raise clock bit (please store the data) */
126       via_reg(VIA1, vBufB) = RTC_CLOCK;
127    }
128 
129    via_reg(VIA1, vDirB) &= ~(RTC_CLOCK | RTC_DATA);
130 }
131 
132 
133 unsigned char pram_read(unsigned char cmd)
134 {
135    unsigned char data=0;
136 
137    pram_enable();
138    pram_putbyte(cmd | PRAMCMD_READ);
139    data = pram_getbyte();
140    pram_disable();
141 
142    return(data);
143 }
144 
145 
146 void pram_write(unsigned char cmd, unsigned char val)
147 {
148    pram_enable();
149    pram_putbyte(cmd);
150    pram_putbyte(val);
151    pram_disable();
152 }
153 
154 
155 unsigned char pram_ext_read(int addr)
156 {
157    unsigned char data;
158    int sect, byte;
159 
160    sect = (addr & PRAM_SECT_MASK) >> PRAM_SECT_SHF;
161    byte = (addr & PRAM_BYTE_MASK) << PRAM_BYTE_SHF;
162    pram_enable();
163    pram_putbyte(PRAMCMD_READ | PRAMCMD_SEL | sect);
164    pram_putbyte(PRAMCMD_EXT | byte);
165    data = pram_getbyte();
166    pram_disable();
167 
168    return(data);
169 }
170 
171 
172 void pram_ext_write(int addr, unsigned char val)
173 {
174    int sect, byte;
175 
176    sect = (addr & PRAM_SECT_MASK) >> PRAM_SECT_SHF;
177    byte = (addr & PRAM_BYTE_MASK) << PRAM_BYTE_SHF;
178    pram_enable();
179    pram_putbyte(PRAMCMD_SEL | sect);
180    pram_putbyte(PRAMCMD_EXT | byte);
181    pram_putbyte(val);
182    pram_disable();
183 }
184 
185 
186 unsigned char *pram_get(void)
187 {
188    int byte_get;
189 
190    printf("PRAM contents:\n");
191    for(byte_get = 0; byte_get < PRAM_GET; byte_get++){
192 
193       pram_save[byte_get] = pram_ext_read(byte_get);
194 
195       if(byte_get % 16 == 0)
196          printf("\n(%x)", byte_get);
197       printf("%x%s", pram_save[byte_get], (byte_get == PRAM_GET - 1)?"":", ");
198    }
199    printf("\n");
200 }
201 
202 char *convtime(unsigned long t)
203 {
204   static long daypmon[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
205   static char *monstr[] = {"January","February","March","April","May","June",
206     "July","August","September","October","November","December" };
207   static char s[200];
208   long year,month,day,hour,minute,seconds,i,dayperyear;
209 
210   year=1904;
211   month=0;  /* Jan */
212   day=1;
213   hour=0;
214   minute=0;
215   seconds=0;
216 
217   if(t == 0xffffffff)
218      return("<time value is -1>");
219 
220   while (t > 0)
221   {
222     if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
223     {
224       dayperyear=366;
225       daypmon[1]=29;
226     }
227     else
228     {
229       dayperyear=365;
230       daypmon[1]=28;
231     }
232     i=dayperyear*60*60*24;
233     if (t >= i)
234     {
235       t-=i;
236       year++;
237       continue;
238     }
239     i=daypmon[month]*60*60*24;
240     if (t >= i)
241     {
242       t-=i;
243       month++;
244       continue;
245     }
246     i=60*60*24;
247     if (t >= i)
248     {
249       t-=i;
250       day++;
251       continue;
252     }
253     i=60*60;
254     if (t >= i)
255     {
256       t-=i;
257       hour++;
258       continue;
259     }
260     i=60;
261     if (t >= i)
262     {
263       t-=i;
264       minute++;
265       continue;
266     }
267     seconds=t;
268     t=0;
269   }
270 
271   sprintf(s,"%s %d, %d   %d:%d:%d",monstr[month],day,year,hour,minute,seconds);
272 
273   return s;
274 }
275 
276 unsigned long pram_readtime(void)
277 {
278    unsigned long timedata,otim;
279 
280    timedata = 0;
281    otim = 0xffffffff;
282    while(otim != timedata){
283       otim = timedata;
284 
285       timedata = pram_read(PRAMCMD_SEC3);
286       timedata = (timedata << 8) | pram_read(PRAMCMD_SEC2);
287       timedata = (timedata << 8) | pram_read(PRAMCMD_SEC1);
288       timedata = (timedata << 8) | pram_read(PRAMCMD_SEC0);
289 
290       /* printf("time read from PRAM: %d\n", timedata); */
291       /* printf("Date and time: %s\n",convtime(timedata)); */
292    }
293 
294    pram_write(PRAMCMD_WPRT, 0xff);
295 
296    return(timedata);
297 }
298 
299 
300 int pram_settime(unsigned long time)
301 {
302    unsigned char t1, t2, t3, t4, tmp;
303    unsigned char ret;
304 
305    t1 = time & 0xff;
306    t2 = (time >>= 8) & 0xff;
307    t3 = (time >>= 8) & 0xff;
308    t4 = (time >>= 8) & 0xff;
309 
310    pram_write(PRAMCMD_WPRT, 0);
311 
312    pram_write(PRAMCMD_SEC0, 0);
313    tmp = pram_read(PRAMCMD_SEC1);
314    pram_write(PRAMCMD_SEC1, (tmp + 1) & 0xff);
315    if((ret=pram_read(PRAMCMD_SEC1)) != ((tmp + 1) & 0xff))
316    {
317 printf("we read ret=%x, tmp=%x (tmp+1) &0xff= %x\n",ret,tmp,(tmp +1) & 0xff);
318       return(0);
319    }
320    pram_write(PRAMCMD_SEC3, t4);
321    pram_write(PRAMCMD_SEC2, t3);
322    pram_write(PRAMCMD_SEC1, t2);
323    pram_write(PRAMCMD_SEC0, t1);
324 
325    pram_write(PRAMCMD_WPRT, 0xff);
326 
327    return(-1);
328 }
329