1/* $OpenBSD: getsecs.c,v 1.8 2023/04/13 02:19:04 jsg Exp $ */ 2/* $NetBSD: getsecs.c,v 1.4 2022/08/24 14:22:35 nonaka Exp $ */ 3 4/*- 5 * Copyright (c) 2005 NONAKA Kimihiro 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/param.h> 31 32#include <libsa.h> 33 34#include <sh/devreg.h> 35#include <arch/sh/dev/scireg.h> 36 37#include <arch/landisk/dev/rs5c313reg.h> 38 39/** 40 * RICOH RS5C313 41 * 42 * Web page: http://www.ricoh.co.jp/LSI/product_rtc/3wire/5c313/ 43 * 44 * How to control RS5C313 on LANDISK 45 * see http://www.mizore.jp/wiki/index.php?LANDISK/rtc 46 */ 47 48uint8_t rtc_read(uint32_t addr); 49 50static void 51rtc_init(void) 52{ 53 54 SHREG_SCSPTR = SCSPTR_SPB1IO | SCSPTR_SPB1DT 55 | SCSPTR_SPB0IO | SCSPTR_SPB0DT; 56 delay(1); 57} 58 59/* control RTC chip enable */ 60static void 61rtc_ce(int onoff) 62{ 63 64 if (onoff) { 65 _reg_write_1(0xb0000003, (1 << 1)); 66 } else { 67 _reg_write_1(0xb0000003, (0 << 1)); 68 } 69 delay(1); 70} 71 72static inline void 73rtc_clk(int onoff) 74{ 75 76 if (onoff) { 77 SHREG_SCSPTR |= SCSPTR_SPB0DT; 78 } else { 79 SHREG_SCSPTR &= ~SCSPTR_SPB0DT; 80 } 81 delay(1); 82} 83 84static void 85rtc_dir(int output) 86{ 87 88 if (output) { 89 SHREG_SCSPTR |= SCSPTR_SPB1IO; 90 } else { 91 SHREG_SCSPTR &= ~SCSPTR_SPB1IO; 92 } 93 delay(1); 94} 95 96/* data-out */ 97static void 98rtc_do(int onoff) 99{ 100 101 if (onoff) { 102 SHREG_SCSPTR |= SCSPTR_SPB1DT; 103 } else { 104 SHREG_SCSPTR &= ~SCSPTR_SPB1DT; 105 } 106 delay(1); 107 108 rtc_clk(0); 109 rtc_clk(1); 110} 111 112/* data-in */ 113static int 114rtc_di(void) 115{ 116 int d; 117 118 d = (SHREG_SCSPTR & SCSPTR_SPB1DT) ? 1 : 0; 119 120 rtc_clk(0); 121 rtc_clk(1); 122 123 return d; 124} 125 126uint8_t 127rtc_read(uint32_t addr) 128{ 129 uint8_t data; 130 131 rtc_init(); 132 rtc_ce(1); 133 134 rtc_dir(1); 135 rtc_do(1); /* Don't care */ 136 rtc_do(1); /* R/#W = 1(READ) */ 137 rtc_do(1); /* AD = 1 */ 138 rtc_do(0); /* DT = 0 */ 139 rtc_do(addr & 0x8); /* A3 */ 140 rtc_do(addr & 0x4); /* A2 */ 141 rtc_do(addr & 0x2); /* A1 */ 142 rtc_do(addr & 0x1); /* A0 */ 143 144 rtc_dir(0); 145 (void)rtc_di(); 146 (void)rtc_di(); 147 (void)rtc_di(); 148 (void)rtc_di(); 149 data = rtc_di(); /* D3 */ 150 data <<= 1; 151 data |= rtc_di(); /* D2 */ 152 data <<= 1; 153 data |= rtc_di(); /* D1 */ 154 data <<= 1; 155 data |= rtc_di(); /* D0 */ 156 157 rtc_ce(0); 158 159 return data & 0xf; 160} 161 162time_t 163getsecs(void) 164{ 165 uint32_t sec, min, hour, day; 166#if 0 167 uint32_t mon, year; 168#endif 169 time_t secs; 170 171 sec = rtc_read(RS5C313_SEC1); 172 sec += rtc_read(RS5C313_SEC10) * 10; 173 min = rtc_read(RS5C313_MIN1); 174 min += rtc_read(RS5C313_MIN10) * 10; 175 hour = rtc_read(RS5C313_HOUR1); 176 hour += rtc_read(RS5C313_HOUR10) * 10; 177 day = rtc_read(RS5C313_DAY1); 178 day += rtc_read(RS5C313_DAY10) * 10; 179#if 0 180 mon = rtc_read(RS5C313_MON1); 181 mon += rtc_read(RS5C313_MON10) * 10; 182 year = rtc_read(RS5C313_YEAR1); 183 year += rtc_read(RS5C313_YEAR10) * 10; 184#endif 185 186 secs = sec; 187 secs += min * 60; 188 secs += hour * 60 * 60; 189 secs += day * 60 * 60 * 24; 190#if 0 191 /* XXX mon, year */ 192#endif 193 194#if defined(DEBUG) 195 printf("getsecs: secs = %d\n", (uint32_t)secs); 196#endif 197 198 return secs; 199} 200