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 54uint8_t rtc_read(uint32_t addr); 55void rtc_write(uint32_t addr, uint8_t data); 56 57static void 58rtc_init(void) 59{ 60 61 SHREG_SCSPTR = SCSPTR_SPB1IO | SCSPTR_SPB1DT 62 | SCSPTR_SPB0IO | SCSPTR_SPB0DT; 63} 64 65/* control RTC chip enable */ 66static void 67rtc_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 77static inline void 78rtc_clk(int onoff) 79{ 80 81 if (onoff) { 82 SHREG_SCSPTR |= SCSPTR_SPB0DT; 83 } else { 84 SHREG_SCSPTR &= ~SCSPTR_SPB0DT; 85 } 86} 87 88static void 89rtc_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 */ 100static void 101rtc_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 */ 115static int 116rtc_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 128uint8_t 129rtc_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 164void 165rtc_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 193satime_t 194getsecs(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