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