1*c7fb772bSthorpej /* $NetBSD: ioblix_zbus.c,v 1.21 2021/08/07 16:18:41 thorpej Exp $ */
26288edb5Sis
3128258c1Sis /*-
4128258c1Sis * Copyright (c) 2000 The NetBSD Foundation, Inc.
5128258c1Sis * All rights reserved.
6128258c1Sis *
7128258c1Sis * This code is derived from software contributed to The NetBSD Foundation
8128258c1Sis * by Ignatios Souvatzis.
9128258c1Sis *
10128258c1Sis * Redistribution and use in source and binary forms, with or without
11128258c1Sis * modification, are permitted provided that the following conditions
12128258c1Sis * are met:
13128258c1Sis * 1. Redistributions of source code must retain the above copyright
14128258c1Sis * notice, this list of conditions and the following disclaimer.
15128258c1Sis * 2. Redistributions in binary form must reproduce the above copyright
16128258c1Sis * notice, this list of conditions and the following disclaimer in the
17128258c1Sis * documentation and/or other materials provided with the distribution.
18128258c1Sis *
19128258c1Sis * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20128258c1Sis * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21128258c1Sis * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22128258c1Sis * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23128258c1Sis * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24128258c1Sis * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25128258c1Sis * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26128258c1Sis * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27128258c1Sis * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28128258c1Sis * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29128258c1Sis * POSSIBILITY OF SUCH DAMAGE.
30128258c1Sis */
31128258c1Sis
321ea4df81Saymeric #include <sys/cdefs.h>
33*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: ioblix_zbus.c,v 1.21 2021/08/07 16:18:41 thorpej Exp $");
341ea4df81Saymeric
35128258c1Sis /* IOBlix Zorro driver */
36128258c1Sis /* XXX to be done: we need to probe the com clock speed! */
37128258c1Sis
38128258c1Sis #include <sys/types.h>
39128258c1Sis
40128258c1Sis #include <sys/device.h>
41c2dfc316Sphx #include <sys/conf.h>
42128258c1Sis #include <sys/systm.h>
43128258c1Sis #include <sys/param.h>
443a45360bSdyoung #include <sys/bus.h>
45128258c1Sis
46128258c1Sis #include <amiga/include/cpu.h>
47128258c1Sis
48128258c1Sis #include <amiga/amiga/device.h>
49128258c1Sis #include <amiga/amiga/drcustom.h>
50128258c1Sis
51128258c1Sis #include <amiga/dev/supio.h>
52128258c1Sis #include <amiga/dev/zbusvar.h>
53128258c1Sis
54c0c4b308Sjklos #include "opt_iobzclock.h"
55128258c1Sis
56128258c1Sis struct iobz_softc {
57128258c1Sis struct bus_space_tag sc_bst;
58128258c1Sis };
59128258c1Sis
60cbab9cadSchs int iobzmatch(device_t, cfdata_t, void *);
61cbab9cadSchs void iobzattach(device_t, device_t, void *);
62cbab9cadSchs int iobzprint(void *, const char *);
63637649faSis void iobz_shutdown(void *);
64128258c1Sis
65cbab9cadSchs CFATTACH_DECL_NEW(iobl_zbus, sizeof(struct iobz_softc),
66c5e91d44Sthorpej iobzmatch, iobzattach, NULL, NULL);
67128258c1Sis
68128258c1Sis int
iobzmatch(device_t parent,cfdata_t cf,void * aux)69cbab9cadSchs iobzmatch(device_t parent, cfdata_t cf, void *aux)
70128258c1Sis {
71128258c1Sis
72128258c1Sis struct zbus_args *zap;
73128258c1Sis
74cbab9cadSchs zap = aux;
75128258c1Sis
76128258c1Sis if (zap->manid != 4711)
77128258c1Sis return (0);
78128258c1Sis
79128258c1Sis if (zap->prodid != 1)
80128258c1Sis return (0);
81128258c1Sis
82128258c1Sis return (1);
83128258c1Sis }
84128258c1Sis
85128258c1Sis struct iobz_devs {
86803a5ae1Sjmc const char *name;
87128258c1Sis unsigned off;
88128258c1Sis int arg;
89128258c1Sis } iobzdevices[] = {
9071def5d3Sjklos { "com", 0x108, 24000000 }, /* XXX see below */
9171def5d3Sjklos { "com", 0x100, 24000000 },
92128258c1Sis { "com", 0x118, 24000000 },
9371def5d3Sjklos { "com", 0x110, 24000000 },
94128258c1Sis { "lpt", 0x200, 0 },
95128258c1Sis { "lpt", 0x300, 0 },
96128258c1Sis { 0, 0, 0}
97128258c1Sis };
98128258c1Sis
99782a7670Sis #ifndef IOBZCLOCK
100782a7670Sis #define IOBZCLOCK 22118400;
101782a7670Sis #endif
102782a7670Sis int iobzclock = IOBZCLOCK; /* patchable! */
103128258c1Sis
104128258c1Sis void
iobzattach(device_t parent,device_t self,void * aux)105cbab9cadSchs iobzattach(device_t parent, device_t self, void *aux)
106128258c1Sis {
107128258c1Sis struct iobz_softc *iobzsc;
108128258c1Sis struct iobz_devs *iobzd;
109128258c1Sis struct zbus_args *zap;
110128258c1Sis struct supio_attach_args supa;
111128258c1Sis extern const struct amiga_bus_space_methods amiga_bus_stride_16;
112128258c1Sis volatile u_int8_t *p;
113128258c1Sis
114128258c1Sis
115cbab9cadSchs iobzsc = device_private(self);
116cbab9cadSchs zap = aux;
117128258c1Sis
118128258c1Sis if (parent)
119128258c1Sis printf("\n");
120128258c1Sis
121128258c1Sis iobzsc->sc_bst.base = (u_long)zap->va;
122128258c1Sis iobzsc->sc_bst.absm = &amiga_bus_stride_16;
123128258c1Sis
124128258c1Sis supa.supio_iot = &iobzsc->sc_bst;
125128258c1Sis supa.supio_ipl = 6;
126128258c1Sis
127128258c1Sis iobzd = iobzdevices;
128128258c1Sis
129128258c1Sis while (iobzd->name) {
130128258c1Sis supa.supio_name = iobzd->name;
131128258c1Sis supa.supio_iobase = iobzd->off;
132c0c4b308Sjklos supa.supio_arg = iobzd->arg ? iobzclock : 0 /* XXX iobzd->arg */;
133*c7fb772bSthorpej config_found(self, &supa, iobzprint, CFARGS_NONE); /* XXX */
134128258c1Sis ++iobzd;
135128258c1Sis }
136128258c1Sis
137128258c1Sis p = (volatile u_int8_t *)zap->va + 2;
138803a5ae1Sjmc (void)shutdownhook_establish(iobz_shutdown, __UNVOLATILE(p));
139128258c1Sis *p = ((*p) & 0x1F) | 0x80;
140128258c1Sis }
141128258c1Sis
142128258c1Sis int
iobzprint(void * aux,const char * pnp)143cbab9cadSchs iobzprint(void *aux, const char *pnp)
144128258c1Sis {
145128258c1Sis struct supio_attach_args *supa;
146cbab9cadSchs supa = aux;
147128258c1Sis
148128258c1Sis if (pnp == NULL)
149128258c1Sis return(QUIET);
150128258c1Sis
1515001cdafSthorpej aprint_normal("%s at %s port 0x%02x",
152128258c1Sis supa->supio_name, pnp, supa->supio_iobase);
153128258c1Sis
154128258c1Sis return(UNCONF);
155128258c1Sis }
156637649faSis
157637649faSis /*
1587e681f70Swiz * Disable board interrupts at shutdown time.
159637649faSis */
160637649faSis
161637649faSis void
iobz_shutdown(void * p)162637649faSis iobz_shutdown(void *p) {
163637649faSis volatile int8_t *q;
164637649faSis
165637649faSis q = p;
166637649faSis
167637649faSis *q &= 0x1F;
168637649faSis }
169