Wed Dec 31 08:00:31 2008 UTC ()
Search all of mfp(4)'s children automatically, instead of
attaching hard-coded children.  mfp(4) was trying to attach
pow(4) though pow(4) was a pseudo-device for a long time.


(isaki)
diff -r1.20 -r1.21 src/sys/arch/x68k/dev/mfp.c

cvs diff -r1.20 -r1.21 src/sys/arch/x68k/dev/mfp.c (switch to unified diff)

--- src/sys/arch/x68k/dev/mfp.c 2008/12/18 02:27:41 1.20
+++ src/sys/arch/x68k/dev/mfp.c 2008/12/31 08:00:31 1.21
@@ -1,217 +1,224 @@ @@ -1,217 +1,224 @@
1/* $NetBSD: mfp.c,v 1.20 2008/12/18 02:27:41 isaki Exp $ */ 1/* $NetBSD: mfp.c,v 1.21 2008/12/31 08:00:31 isaki Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998 NetBSD Foundation, Inc. 4 * Copyright (c) 1998 NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by the NetBSD 17 * This product includes software developed by the NetBSD
18 * Foundation, Inc. and its contributors. 18 * Foundation, Inc. and its contributors.
19 * 4. The name of the author may not be used to endorse or promote products 19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE. 32 * POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * MC68901 MFP (multi function periferal) driver for NetBSD/x68k 36 * MC68901 MFP (multi function periferal) driver for NetBSD/x68k
37 */ 37 */
38 38
39/* 39/*
40 * MFP is used as keyboard controller, which may be used before 40 * MFP is used as keyboard controller, which may be used before
41 * ordinary initialization. 41 * ordinary initialization.
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45__KERNEL_RCSID(0, "$NetBSD: mfp.c,v 1.20 2008/12/18 02:27:41 isaki Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: mfp.c,v 1.21 2008/12/31 08:00:31 isaki Exp $");
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/systm.h> 48#include <sys/systm.h>
49#include <sys/device.h> 49#include <sys/device.h>
50#include <sys/malloc.h> 50#include <sys/malloc.h>
51 51
52#include <machine/bus.h> 52#include <machine/bus.h>
53#include <machine/cpu.h> 53#include <machine/cpu.h>
54 54
55#include <arch/x68k/dev/intiovar.h> 55#include <arch/x68k/dev/intiovar.h>
56#include <arch/x68k/dev/mfp.h> 56#include <arch/x68k/dev/mfp.h>
57 57
58static int mfp_match(struct device *, struct cfdata *, void *); 58static int mfp_match(struct device *, struct cfdata *, void *);
59static void mfp_attach(struct device *, struct device *, void *); 59static void mfp_attach(struct device *, struct device *, void *);
 60static int mfp_search(device_t, cfdata_t, const int *, void *);
60static void mfp_init(void); 61static void mfp_init(void);
61static void mfp_calibrate_delay(void); 62static void mfp_calibrate_delay(void);
62 63
63CFATTACH_DECL(mfp, sizeof(struct mfp_softc), 64CFATTACH_DECL(mfp, sizeof(struct mfp_softc),
64 mfp_match, mfp_attach, NULL, NULL); 65 mfp_match, mfp_attach, NULL, NULL);
65 66
66static int mfp_attached; 67static int mfp_attached;
67 68
68static int 69static int
69mfp_match(struct device *parent, struct cfdata *cf, void *aux) 70mfp_match(struct device *parent, struct cfdata *cf, void *aux)
70{ 71{
71 struct intio_attach_args *ia = aux; 72 struct intio_attach_args *ia = aux;
72 73
73 /* mfp0 */ 74 /* mfp0 */
74 if (strcmp(ia->ia_name, "mfp") != 0) 75 if (strcmp(ia->ia_name, "mfp") != 0)
75 return 0; 76 return 0;
76 if (mfp_attached) 77 if (mfp_attached)
77 return (0); 78 return (0);
78 79
79 if (ia->ia_addr == INTIOCF_ADDR_DEFAULT) 80 if (ia->ia_addr == INTIOCF_ADDR_DEFAULT)
80 ia->ia_addr = MFP_ADDR; 81 ia->ia_addr = MFP_ADDR;
81 if (ia->ia_intr == INTIOCF_INTR_DEFAULT) 82 if (ia->ia_intr == INTIOCF_INTR_DEFAULT)
82 ia->ia_addr = MFP_INTR; 83 ia->ia_addr = MFP_INTR;
83 84
84 /* fixed address */ 85 /* fixed address */
85 if (ia->ia_addr != MFP_ADDR) 86 if (ia->ia_addr != MFP_ADDR)
86 return (0); 87 return (0);
87 if (ia->ia_intr != MFP_INTR) 88 if (ia->ia_intr != MFP_INTR)
88 return (0); 89 return (0);
89 90
90 return (1); 91 return (1);
91} 92}
92 93
93 94
94static void 95static void
95mfp_attach(struct device *parent, struct device *self, void *aux) 96mfp_attach(struct device *parent, struct device *self, void *aux)
96{ 97{
97 struct mfp_softc *sc = (struct mfp_softc *)self; 98 struct mfp_softc *sc = (struct mfp_softc *)self;
98 struct intio_attach_args *ia = aux; 99 struct intio_attach_args *ia = aux;
99 100
100 mfp_init(); 101 mfp_init();
101 102
102 if (sc != NULL) { 103 if (sc != NULL) {
103 /* realconfig */ 104 /* realconfig */
104 int r; 105 int r;
105 106
106 printf("\n"); 107 printf("\n");
107 108
108 mfp_attached = 1; 109 mfp_attached = 1;
109 sc->sc_bst = ia->ia_bst; 110 sc->sc_bst = ia->ia_bst;
110 sc->sc_intr = ia->ia_intr; 111 sc->sc_intr = ia->ia_intr;
111 ia->ia_size = 0x30; 112 ia->ia_size = 0x30;
112 r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE); 113 r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE);
113#ifdef DIAGNOSTIC 114#ifdef DIAGNOSTIC
114 if (r) 115 if (r)
115 panic("IO map for MFP corruption??"); 116 panic("IO map for MFP corruption??");
116#endif 117#endif
117 bus_space_map(ia->ia_bst, ia->ia_addr, 0x2000, 0, &sc->sc_bht); 118 bus_space_map(ia->ia_bst, ia->ia_addr, 0x2000, 0, &sc->sc_bht);
118 config_found(self, __UNCONST("kbd"), NULL); 119 config_search_ia(mfp_search, self, "mfp", NULL);
119 config_found(self, __UNCONST("clock"), NULL); 
120 config_found(self, __UNCONST("pow"), NULL); 
121 } else { 120 } else {
122 /* 121 /*
123 * Called from config_console; 122 * Called from config_console;
124 * calibrate the DELAY loop counter 123 * calibrate the DELAY loop counter
125 */ 124 */
126 mfp_calibrate_delay(); 125 mfp_calibrate_delay();
127 } 126 }
128} 127}
129 128
 129static int
 130mfp_search(device_t parent, cfdata_t cf, const int *loc, void *aux)
 131{
 132 if (config_match(parent, cf, __UNCONST(cf->cf_name)) > 0)
 133 config_attach(parent, cf, __UNCONST(cf->cf_name), NULL);
 134 return 0;
 135}
 136
130static void 137static void
131mfp_init(void) 138mfp_init(void)
132{ 139{
133 mfp_set_vr(MFP_INTR); 140 mfp_set_vr(MFP_INTR);
134 141
135 /* stop all interrupts */ 142 /* stop all interrupts */
136 mfp_set_iera(0); 143 mfp_set_iera(0);
137 mfp_set_ierb(0); 144 mfp_set_ierb(0);
138 145
139 /* make MSCTRL 'High', XXX where should I do it? */ 146 /* make MSCTRL 'High', XXX where should I do it? */
140 mfp_send_usart(0x41); 147 mfp_send_usart(0x41);
141 148
142 /* Timer A settings */ 149 /* Timer A settings */
143 mfp_set_tacr(MFP_TIMERA_RESET | MFP_TIMERA_STOP); 150 mfp_set_tacr(MFP_TIMERA_RESET | MFP_TIMERA_STOP);
144 151
145 /* Timer B settings: used for USART clock */ 152 /* Timer B settings: used for USART clock */
146 mfp_set_tbcr(MFP_TIMERB_RESET | MFP_TIMERB_STOP); 153 mfp_set_tbcr(MFP_TIMERB_RESET | MFP_TIMERB_STOP);
147 154
148 /* Timer C/D settings */ 155 /* Timer C/D settings */
149 mfp_set_tcdcr(0); 156 mfp_set_tcdcr(0);
150} 157}
151 158
152extern int delay_divisor; 159extern int delay_divisor;
153void _delay(u_int); 160void _delay(u_int);
154 161
155static void 162static void
156mfp_calibrate_delay(void) 163mfp_calibrate_delay(void)
157{ 164{
158 /* 165 /*
159 * Stolen from mvme68k. 166 * Stolen from mvme68k.
160 */ 167 */
161 /* 168 /*
162 * X68k provides 4MHz clock (= 0.25usec) for MFP timer C. 169 * X68k provides 4MHz clock (= 0.25usec) for MFP timer C.
163 * 10000usec = 0.25usec * 200 * 200 170 * 10000usec = 0.25usec * 200 * 200
164 * Our slowest clock is 20MHz (?). Its delay_divisor value 171 * Our slowest clock is 20MHz (?). Its delay_divisor value
165 * should be about 102. Start from 140 here. 172 * should be about 102. Start from 140 here.
166 */ 173 */
167 for (delay_divisor = 140; delay_divisor > 0; delay_divisor--) { 174 for (delay_divisor = 140; delay_divisor > 0; delay_divisor--) {
168 mfp_set_tcdr(255-0); 175 mfp_set_tcdr(255-0);
169 mfp_set_tcdcr(0x70); /* 1/200 delay mode */ 176 mfp_set_tcdcr(0x70); /* 1/200 delay mode */
170 _delay(10000 << 8); 177 _delay(10000 << 8);
171 mfp_set_tcdcr(0); /* stop timer */ 178 mfp_set_tcdcr(0); /* stop timer */
172 if ((255 - mfp_get_tcdr()) > 200) 179 if ((255 - mfp_get_tcdr()) > 200)
173 break; /* got it! */ 180 break; /* got it! */
174 /* retry! */ 181 /* retry! */
175 } 182 }
176} 183}
177 184
178/* 185/*
179 * MFP utility functions 186 * MFP utility functions
180 */ 187 */
181 188
182/* 189/*
183 * wait for built-in display hsync. 190 * wait for built-in display hsync.
184 * should be called before writing to frame buffer. 191 * should be called before writing to frame buffer.
185 * might be called before realconfig. 192 * might be called before realconfig.
186 */ 193 */
187void 194void
188mfp_wait_for_hsync(void) 195mfp_wait_for_hsync(void)
189{ 196{
190 /* wait for CRT HSYNC */ 197 /* wait for CRT HSYNC */
191 while (mfp_get_gpip() & MFP_GPIP_HSYNC) 198 while (mfp_get_gpip() & MFP_GPIP_HSYNC)
192 __asm("nop"); 199 __asm("nop");
193 while (!(mfp_get_gpip() & MFP_GPIP_HSYNC)) 200 while (!(mfp_get_gpip() & MFP_GPIP_HSYNC))
194 __asm("nop"); 201 __asm("nop");
195} 202}
196 203
197/* 204/*
198 * send COMMAND to the MFP USART. 205 * send COMMAND to the MFP USART.
199 * USART is attached to the keyboard. 206 * USART is attached to the keyboard.
200 * might be called before realconfig. 207 * might be called before realconfig.
201 */ 208 */
202int 209int
203mfp_send_usart(int command) 210mfp_send_usart(int command)
204{ 211{
205 while (!(mfp_get_tsr() & MFP_TSR_BE)); 212 while (!(mfp_get_tsr() & MFP_TSR_BE));
206 mfp_set_udr(command); 213 mfp_set_udr(command);
207 214
208 return 0; 215 return 0;
209} 216}
210 217
211int 218int
212mfp_receive_usart(void) 219mfp_receive_usart(void)
213{ 220{
214 while (!(mfp_get_rsr() & MFP_RSR_BF)) 221 while (!(mfp_get_rsr() & MFP_RSR_BF))
215 __asm("nop"); 222 __asm("nop");
216 return mfp_get_udr(); 223 return mfp_get_udr();
217} 224}