1 1.22 thorpej /* $NetBSD: drbbc.c,v 1.22 2025/09/07 21:45:10 thorpej Exp $ */ 2 1.1 is 3 1.3 is /*- 4 1.4 is * Copyright (c) 1997 The NetBSD Foundation, Inc. 5 1.1 is * All rights reserved. 6 1.1 is * 7 1.3 is * This code is derived from software contributed to The NetBSD Foundation 8 1.3 is * by Ignatios Souvatzis. 9 1.3 is * 10 1.1 is * Redistribution and use in source and binary forms, with or without 11 1.1 is * modification, are permitted provided that the following conditions 12 1.1 is * are met: 13 1.1 is * 1. Redistributions of source code must retain the above copyright 14 1.1 is * notice, this list of conditions and the following disclaimer. 15 1.1 is * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 is * notice, this list of conditions and the following disclaimer in the 17 1.1 is * documentation and/or other materials provided with the distribution. 18 1.1 is * 19 1.3 is * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.3 is * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.3 is * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.3 is * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.3 is * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.3 is * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.3 is * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.3 is * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.3 is * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.3 is * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.3 is * POSSIBILITY OF SUCH DAMAGE. 30 1.1 is */ 31 1.8 aymeric 32 1.8 aymeric #include <sys/cdefs.h> 33 1.22 thorpej __KERNEL_RCSID(0, "$NetBSD: drbbc.c,v 1.22 2025/09/07 21:45:10 thorpej Exp $"); 34 1.1 is 35 1.1 is #include <sys/param.h> 36 1.1 is #include <sys/kernel.h> 37 1.1 is #include <sys/device.h> 38 1.1 is #include <sys/systm.h> 39 1.11 thorpej 40 1.1 is #if 0 41 1.1 is #include <machine/psl.h> 42 1.1 is #endif 43 1.1 is #include <machine/cpu.h> 44 1.1 is #include <amiga/amiga/device.h> 45 1.1 is #include <amiga/amiga/custom.h> 46 1.1 is #include <amiga/amiga/cia.h> 47 1.1 is #include <amiga/amiga/drcustom.h> 48 1.1 is #include <amiga/dev/rtc.h> 49 1.1 is 50 1.15 mhitch #include <dev/clock_subr.h> 51 1.1 is #include <dev/ic/ds.h> 52 1.1 is 53 1.21 thorpej static int draco_ds_read_bit(void *); 54 1.21 thorpej static void draco_ds_write_bit(void *, int); 55 1.21 thorpej static void draco_ds_reset(void *); 56 1.1 is 57 1.21 thorpej static void drbbc_attach(device_t, device_t, void *); 58 1.21 thorpej static int drbbc_match(device_t, cfdata_t, void *); 59 1.1 is 60 1.21 thorpej static int dracougettod(todr_chip_handle_t, struct timeval *); 61 1.21 thorpej static int dracousettod(todr_chip_handle_t, struct timeval *); 62 1.1 is 63 1.1 is struct drbbc_softc { 64 1.21 thorpej device_t sc_dev; 65 1.1 is struct ds_handle sc_dsh; 66 1.21 thorpej struct todr_chip_handle sc_todr; 67 1.1 is }; 68 1.1 is 69 1.20 chs CFATTACH_DECL_NEW(drbbc, sizeof(struct drbbc_softc), 70 1.10 thorpej drbbc_match, drbbc_attach, NULL, NULL); 71 1.1 is 72 1.21 thorpej static int 73 1.20 chs drbbc_match(device_t parent, cfdata_t cf, void *aux) 74 1.1 is { 75 1.6 kleink static int drbbc_matched = 0; 76 1.6 kleink 77 1.6 kleink /* Allow only one instance. */ 78 1.20 chs if (!is_draco() || !matchname(aux, "drbbc") || drbbc_matched) 79 1.1 is return (0); 80 1.6 kleink 81 1.6 kleink drbbc_matched = 1; 82 1.6 kleink return (1); 83 1.1 is } 84 1.1 is 85 1.21 thorpej static void 86 1.20 chs drbbc_attach(device_t parent, device_t self, void *aux) 87 1.1 is { 88 1.1 is int i; 89 1.1 is struct drbbc_softc *sc; 90 1.1 is u_int8_t rombuf[8]; 91 1.1 is 92 1.20 chs sc = device_private(self); 93 1.21 thorpej sc->sc_dev = self; 94 1.1 is 95 1.1 is sc->sc_dsh.ds_read_bit = draco_ds_read_bit; 96 1.1 is sc->sc_dsh.ds_write_bit = draco_ds_write_bit; 97 1.1 is sc->sc_dsh.ds_reset = draco_ds_reset; 98 1.11 thorpej sc->sc_dsh.ds_hw_handle = (void *)(DRCCADDR + DRIOCTLPG*PAGE_SIZE); 99 1.1 is 100 1.1 is sc->sc_dsh.ds_reset(sc->sc_dsh.ds_hw_handle); 101 1.1 is 102 1.1 is ds_write_byte(&sc->sc_dsh, DS_ROM_READ); 103 1.7 aymeric for (i=0; i<8; ++i) 104 1.1 is rombuf[i] = ds_read_byte(&sc->sc_dsh); 105 1.1 is 106 1.1 is hostid = (rombuf[3] << 24) + (rombuf[2] << 16) + 107 1.1 is (rombuf[1] << 8) + rombuf[7]; 108 1.1 is 109 1.1 is printf(": ROM %02x %02x%02x%02x%02x%02x%02x %02x (DraCo sernum %ld)\n", 110 1.7 aymeric rombuf[7], rombuf[6], rombuf[5], rombuf[4], 111 1.1 is rombuf[3], rombuf[2], rombuf[1], rombuf[0], 112 1.7 aymeric hostid); 113 1.7 aymeric 114 1.22 thorpej sc->sc_todr.todr_dev = self; 115 1.21 thorpej sc->sc_todr.todr_gettime = dracougettod; 116 1.21 thorpej sc->sc_todr.todr_settime = dracousettod; 117 1.21 thorpej todr_attach(&sc->sc_todr); 118 1.1 is } 119 1.1 is 120 1.21 thorpej static int 121 1.7 aymeric draco_ds_read_bit(void *p) 122 1.1 is { 123 1.12 jmc struct drioct *draco_ioctl; 124 1.1 is 125 1.12 jmc draco_ioctl = p; 126 1.1 is 127 1.12 jmc while (draco_ioctl->io_status & DRSTAT_CLKBUSY); 128 1.1 is 129 1.12 jmc draco_ioctl->io_clockw1 = 0; 130 1.1 is 131 1.12 jmc while (draco_ioctl->io_status & DRSTAT_CLKBUSY); 132 1.1 is 133 1.12 jmc return (draco_ioctl->io_status & DRSTAT_CLKDAT); 134 1.1 is } 135 1.1 is 136 1.21 thorpej static void 137 1.7 aymeric draco_ds_write_bit(void *p, int b) 138 1.1 is { 139 1.12 jmc struct drioct *draco_ioctl; 140 1.1 is 141 1.12 jmc draco_ioctl = p; 142 1.1 is 143 1.12 jmc while (draco_ioctl->io_status & DRSTAT_CLKBUSY); 144 1.1 is 145 1.1 is if (b) 146 1.12 jmc draco_ioctl->io_clockw1 = 0; 147 1.1 is else 148 1.12 jmc draco_ioctl->io_clockw0 = 0; 149 1.1 is } 150 1.1 is 151 1.21 thorpej static void 152 1.7 aymeric draco_ds_reset(void *p) 153 1.1 is { 154 1.12 jmc struct drioct *draco_ioctl; 155 1.1 is 156 1.12 jmc draco_ioctl = p; 157 1.1 is 158 1.12 jmc draco_ioctl->io_clockrst = 0; 159 1.1 is } 160 1.1 is 161 1.21 thorpej static int 162 1.18 tsutsui dracougettod(todr_chip_handle_t h, struct timeval *tvp) 163 1.1 is { 164 1.22 thorpej struct drbbc_softc *sc = device_private(h->todr_dev); 165 1.1 is u_int32_t clkbuf; 166 1.5 is u_int32_t usecs; 167 1.1 is 168 1.21 thorpej sc->sc_dsh.ds_reset(sc->sc_dsh.ds_hw_handle); 169 1.1 is 170 1.21 thorpej ds_write_byte(&sc->sc_dsh, DS_ROM_SKIP); 171 1.1 is 172 1.21 thorpej ds_write_byte(&sc->sc_dsh, DS_MEM_READ_MEMORY); 173 1.5 is /* address of seconds/256: */ 174 1.21 thorpej ds_write_byte(&sc->sc_dsh, 0x02); 175 1.21 thorpej ds_write_byte(&sc->sc_dsh, 0x02); 176 1.7 aymeric 177 1.21 thorpej usecs = (ds_read_byte(&sc->sc_dsh) * 1000000) / 256; 178 1.21 thorpej clkbuf = ds_read_byte(&sc->sc_dsh) 179 1.21 thorpej + (ds_read_byte(&sc->sc_dsh)<<8) 180 1.21 thorpej + (ds_read_byte(&sc->sc_dsh)<<16) 181 1.21 thorpej + (ds_read_byte(&sc->sc_dsh)<<24); 182 1.1 is 183 1.14 is /* BSD time is wrt. 1.1.1970; AmigaOS time wrt. 1.1.1978 */ 184 1.1 is 185 1.7 aymeric clkbuf += (8*365 + 2) * 86400; 186 1.1 is 187 1.5 is tvp->tv_sec = clkbuf; 188 1.5 is tvp->tv_usec = usecs; 189 1.5 is 190 1.15 mhitch return (0); 191 1.15 mhitch } 192 1.15 mhitch 193 1.21 thorpej static int 194 1.18 tsutsui dracousettod(todr_chip_handle_t h, struct timeval *tvp) 195 1.15 mhitch { 196 1.16 mhitch return (ENXIO); 197 1.1 is } 198