Home | History | Annotate | Line # | Download | only in boot
      1 /*	$NetBSD: getsecs.c,v 1.4 2022/08/24 14:22:35 nonaka Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2005 NONAKA Kimihiro
      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  *
     16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/param.h>
     30 #include <sys/types.h>
     31 
     32 #include <netinet/in.h>
     33 #include <netinet/in_systm.h>
     34 
     35 #include <lib/libsa/stand.h>
     36 #include <lib/libsa/net.h>
     37 #include <lib/libsa/netif.h>
     38 #include <lib/libkern/libkern.h>
     39 
     40 #include <sh3/devreg.h>
     41 #include <sh3/scireg.h>
     42 
     43 #include <dev/ic/rs5c313reg.h>
     44 
     45 /**
     46  * RICOH RS5C313
     47  *
     48  * Web page: http://www.ricoh.co.jp/LSI/product_rtc/3wire/5c313/
     49  *
     50  * How to control RS5C313 on LANDISK
     51  *   see http://www.mizore.jp/wiki/index.php?LANDISK/rtc
     52  */
     53 
     54 uint8_t rtc_read(uint32_t addr);
     55 void rtc_write(uint32_t addr, uint8_t data);
     56 
     57 static void
     58 rtc_init(void)
     59 {
     60 
     61 	SHREG_SCSPTR = SCSPTR_SPB1IO | SCSPTR_SPB1DT
     62 		       | SCSPTR_SPB0IO | SCSPTR_SPB0DT;
     63 }
     64 
     65 /* control RTC chip enable */
     66 static void
     67 rtc_ce(int onoff)
     68 {
     69 
     70 	if (onoff) {
     71 		_reg_write_1(0xb0000003, (1 << 1));
     72 	} else {
     73 		_reg_write_1(0xb0000003, (0 << 1));
     74 	}
     75 }
     76 
     77 static inline void
     78 rtc_clk(int onoff)
     79 {
     80 
     81 	if (onoff) {
     82 		SHREG_SCSPTR |= SCSPTR_SPB0DT;
     83 	} else {
     84 		SHREG_SCSPTR &= ~SCSPTR_SPB0DT;
     85 	}
     86 }
     87 
     88 static void
     89 rtc_dir(int output)
     90 {
     91 
     92 	if (output) {
     93 		SHREG_SCSPTR |= SCSPTR_SPB1IO;
     94 	} else {
     95 		SHREG_SCSPTR &= ~SCSPTR_SPB1IO;
     96 	}
     97 }
     98 
     99 /* data-out */
    100 static void
    101 rtc_do(int onoff)
    102 {
    103 
    104 	if (onoff) {
    105 		SHREG_SCSPTR |= SCSPTR_SPB1DT;
    106 	} else {
    107 		SHREG_SCSPTR &= ~SCSPTR_SPB1DT;
    108 	}
    109 
    110 	rtc_clk(0);
    111 	rtc_clk(1);
    112 }
    113 
    114 /* data-in */
    115 static int
    116 rtc_di(void)
    117 {
    118 	int d;
    119 
    120 	d = (SHREG_SCSPTR & SCSPTR_SPB1DT) ? 1 : 0;
    121 
    122 	rtc_clk(0);
    123 	rtc_clk(1);
    124 
    125 	return d;
    126 }
    127 
    128 uint8_t
    129 rtc_read(uint32_t addr)
    130 {
    131 	uint8_t data;
    132 
    133 	rtc_init();
    134 	rtc_ce(1);
    135 
    136 	rtc_dir(1);
    137 	rtc_do(1);		/* Don't care */
    138 	rtc_do(1);		/* R/#W = 1(READ) */
    139 	rtc_do(1);		/* AD = 1 */
    140 	rtc_do(0);		/* DT = 0 */
    141 	rtc_do(addr & 0x8);	/* A3 */
    142 	rtc_do(addr & 0x4);	/* A2 */
    143 	rtc_do(addr & 0x2);	/* A1 */
    144 	rtc_do(addr & 0x1);	/* A0 */
    145 
    146 	rtc_dir(0);
    147 	(void)rtc_di();
    148 	(void)rtc_di();
    149 	(void)rtc_di();
    150 	(void)rtc_di();
    151 	data = rtc_di();	/* D3 */
    152 	data <<= 1;
    153 	data |= rtc_di();	/* D2 */
    154 	data <<= 1;
    155 	data |= rtc_di();	/* D1 */
    156 	data <<= 1;
    157 	data |= rtc_di();	/* D0 */
    158 
    159 	rtc_ce(0);
    160 
    161 	return data & 0xf;
    162 }
    163 
    164 void
    165 rtc_write(uint32_t addr, uint8_t data)
    166 {
    167 
    168 	rtc_init();
    169 	rtc_ce(1);
    170 
    171 	rtc_dir(1);
    172 	rtc_do(1);		/* Don't care */
    173 	rtc_do(0);		/* R/#W = 0(WRITE) */
    174 	rtc_do(1);		/* AD = 1 */
    175 	rtc_do(0);		/* DT = 0 */
    176 	rtc_do(addr & 0x8);	/* A3 */
    177 	rtc_do(addr & 0x4);	/* A2 */
    178 	rtc_do(addr & 0x2);	/* A1 */
    179 	rtc_do(addr & 0x1);	/* A0 */
    180 
    181 	rtc_do(1);		/* Don't care */
    182 	rtc_do(0);		/* R/#W = 0(WRITE) */
    183 	rtc_do(0);		/* AD = 0 */
    184 	rtc_do(1);		/* DT = 1 */
    185 	rtc_do(data & 0x8);	/* D3 */
    186 	rtc_do(data & 0x4);	/* D2 */
    187 	rtc_do(data & 0x2);	/* D1 */
    188 	rtc_do(data & 0x1);	/* D0 */
    189 
    190 	rtc_ce(0);
    191 }
    192 
    193 satime_t
    194 getsecs(void)
    195 {
    196 	uint32_t sec, min, hour, day;
    197 #if 0
    198 	uint32_t mon, year;
    199 #endif
    200 	satime_t secs;
    201 
    202 	sec = rtc_read(RS5C313_SEC1);
    203 	sec += rtc_read(RS5C313_SEC10) * 10;
    204 	min = rtc_read(RS5C313_MIN1);
    205 	min += rtc_read(RS5C313_MIN10) * 10;
    206 	hour = rtc_read(RS5C313_HOUR1);
    207 	hour += rtc_read(RS5C313_HOUR10) * 10;
    208 	day = rtc_read(RS5C313_DAY1);
    209 	day += rtc_read(RS5C313_DAY10) * 10;
    210 #if 0
    211 	mon = rtc_read(RS5C313_MON1);
    212 	mon += rtc_read(RS5C313_MON10) * 10;
    213 	year = rtc_read(RS5C313_YEAR1);
    214 	year += rtc_read(RS5C313_YEAR10) * 10;
    215 #endif
    216 
    217 	secs = sec;
    218 	secs += min * 60;
    219 	secs += hour * 60 * 60;
    220 	secs += day * 60 * 60 * 24;
    221 #if 0
    222 	/* XXX mon, year */
    223 #endif
    224 
    225 #if defined(DEBUG)
    226 	printf("getsecs: secs = %d\n", (uint32_t)secs);
    227 #endif
    228 
    229 	return secs;
    230 }
    231