pm_direct.c revision 1.9 1 1.9 briggs /* $NetBSD: pm_direct.c,v 1.9 1999/06/28 01:56:56 briggs Exp $ */
2 1.1 scottr
3 1.1 scottr /*
4 1.1 scottr * Copyright (C) 1997 Takashi Hamada
5 1.1 scottr * All rights reserved.
6 1.1 scottr *
7 1.1 scottr * Redistribution and use in source and binary forms, with or without
8 1.1 scottr * modification, are permitted provided that the following conditions
9 1.1 scottr * are met:
10 1.1 scottr * 1. Redistributions of source code must retain the above copyright
11 1.1 scottr * notice, this list of conditions and the following disclaimer.
12 1.1 scottr * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 scottr * notice, this list of conditions and the following disclaimer in the
14 1.1 scottr * documentation and/or other materials provided with the distribution.
15 1.1 scottr * 3. All advertising materials mentioning features or use of this software
16 1.1 scottr * must display the following acknowledgement:
17 1.5 scottr * This product includes software developed by Takashi Hamada
18 1.1 scottr * 4. The name of the author may not be used to endorse or promote products
19 1.1 scottr * derived from this software without specific prior written permission.
20 1.1 scottr *
21 1.1 scottr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.1 scottr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.1 scottr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.1 scottr * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.1 scottr * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.1 scottr * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.1 scottr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.1 scottr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.1 scottr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 1.1 scottr * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.1 scottr */
32 1.5 scottr /* From: pm_direct.c 1.3 03/18/98 Takashi Hamada */
33 1.1 scottr
34 1.3 scottr #include "opt_adb.h"
35 1.3 scottr
36 1.3 scottr #ifdef DEBUG
37 1.3 scottr #ifndef ADB_DEBUG
38 1.3 scottr #define ADB_DEBUG
39 1.3 scottr #endif
40 1.3 scottr #endif
41 1.1 scottr
42 1.1 scottr /* #define PM_GRAB_SI 1 */
43 1.1 scottr
44 1.1 scottr #include <sys/types.h>
45 1.1 scottr #include <sys/cdefs.h>
46 1.3 scottr #include <sys/systm.h>
47 1.1 scottr
48 1.1 scottr #include <machine/viareg.h>
49 1.1 scottr #include <machine/param.h>
50 1.1 scottr #include <machine/cpu.h>
51 1.1 scottr #include <machine/adbsys.h>
52 1.1 scottr
53 1.2 scottr #include <mac68k/mac68k/macrom.h>
54 1.2 scottr #include <mac68k/dev/adbvar.h>
55 1.2 scottr #include <mac68k/dev/pm_direct.h>
56 1.1 scottr
57 1.1 scottr /* hardware dependent values */
58 1.1 scottr extern u_short ADBDelay;
59 1.1 scottr extern u_int32_t HwCfgFlags3;
60 1.1 scottr extern struct mac68k_machine_S mac68k_machine;
61 1.1 scottr
62 1.1 scottr
63 1.1 scottr /* define the types of the Power Manager */
64 1.1 scottr #define PM_HW_UNKNOWN 0x00 /* don't know */
65 1.1 scottr #define PM_HW_PB1XX 0x01 /* PowerBook 1XX series */
66 1.1 scottr #define PM_HW_PB5XX 0x02 /* PowerBook Duo and 5XX series */
67 1.1 scottr
68 1.1 scottr /* useful macros */
69 1.1 scottr #define PM_SR() via_reg(VIA1, vSR)
70 1.1 scottr #define PM_VIA_INTR_ENABLE() via_reg(VIA1, vIER) = 0x90
71 1.1 scottr #define PM_VIA_INTR_DISABLE() via_reg(VIA1, vIER) = 0x10
72 1.1 scottr #define PM_VIA_CLR_INTR() via_reg(VIA1, vIFR) = 0x90
73 1.1 scottr #define PM_SET_STATE_ACKON() via_reg(VIA2, vBufB) |= 0x04
74 1.1 scottr #define PM_SET_STATE_ACKOFF() via_reg(VIA2, vBufB) &= ~0x04
75 1.4 scottr #define PM_IS_ON (0x02 == (via_reg(VIA2, vBufB) & 0x02))
76 1.4 scottr #define PM_IS_OFF (0x00 == (via_reg(VIA2, vBufB) & 0x02))
77 1.1 scottr
78 1.4 scottr /*
79 1.4 scottr * Variables for internal use
80 1.1 scottr */
81 1.1 scottr int pmHardware = PM_HW_UNKNOWN;
82 1.1 scottr u_short pm_existent_ADB_devices = 0x0; /* each bit expresses the existent ADB device */
83 1.1 scottr u_int pm_LCD_brightness = 0x0;
84 1.1 scottr u_int pm_LCD_contrast = 0x0;
85 1.1 scottr u_int pm_counter = 0; /* clock count */
86 1.1 scottr
87 1.1 scottr /* these values shows that number of data returned after 'send' cmd is sent */
88 1.1 scottr char pm_send_cmd_type[] = {
89 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
90 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
91 1.4 scottr 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
92 1.4 scottr 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
93 1.4 scottr 0xff, 0x00, 0x02, 0x01, 0x01, 0xff, 0xff, 0xff,
94 1.4 scottr 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
95 1.4 scottr 0x04, 0x14, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
96 1.4 scottr 0x00, 0x00, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff,
97 1.4 scottr 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
98 1.4 scottr 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
99 1.4 scottr 0x01, 0x00, 0x02, 0x02, 0xff, 0x01, 0x03, 0x01,
100 1.4 scottr 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
101 1.4 scottr 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
102 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
103 1.4 scottr 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
104 1.4 scottr 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x04, 0x04,
105 1.4 scottr 0x04, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
106 1.4 scottr 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
107 1.4 scottr 0x01, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108 1.4 scottr 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
109 1.4 scottr 0x02, 0x02, 0x02, 0x04, 0xff, 0x00, 0xff, 0xff,
110 1.4 scottr 0x01, 0x01, 0x03, 0x02, 0xff, 0xff, 0xff, 0xff,
111 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
112 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
113 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
114 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
115 1.4 scottr 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
116 1.4 scottr 0x01, 0x01, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
117 1.4 scottr 0xff, 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
118 1.4 scottr 0x03, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00,
119 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
120 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
121 1.1 scottr };
122 1.1 scottr
123 1.1 scottr /* these values shows that number of data returned after 'receive' cmd is sent */
124 1.1 scottr char pm_receive_cmd_type[] = {
125 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
127 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 1.4 scottr 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
129 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
131 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 1.4 scottr 0x05, 0x15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
133 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 1.4 scottr 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
135 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 1.4 scottr 0x02, 0x00, 0x03, 0x03, 0xff, 0xff, 0xff, 0xff,
137 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 1.4 scottr 0x04, 0x04, 0x03, 0x09, 0xff, 0xff, 0xff, 0xff,
139 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01,
141 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 1.4 scottr 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
143 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 1.4 scottr 0x02, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
145 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 1.4 scottr 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
147 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
149 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
151 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 1.4 scottr 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xff,
153 1.4 scottr 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
154 1.4 scottr 0xff, 0xff, 0x02, 0xff, 0xff, 0xff, 0xff, 0x00,
155 1.4 scottr 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 1.4 scottr 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
157 1.1 scottr };
158 1.1 scottr
159 1.1 scottr
160 1.1 scottr /*
161 1.1 scottr * Define the private functions
162 1.1 scottr */
163 1.1 scottr
164 1.1 scottr /* for debugging */
165 1.3 scottr #ifdef ADB_DEBUG
166 1.4 scottr void pm_printerr __P((char *, int, int, char *));
167 1.1 scottr #endif
168 1.1 scottr
169 1.4 scottr int pm_wait_busy __P((int));
170 1.4 scottr int pm_wait_free __P((int));
171 1.1 scottr
172 1.1 scottr /* these functions are for the PB1XX series */
173 1.4 scottr int pm_receive_pm1 __P((u_char *));
174 1.4 scottr int pm_send_pm1 __P((u_char,int));
175 1.4 scottr int pm_pmgrop_pm1 __P((PMData *));
176 1.9 briggs void pm_intr_pm1 __P((void *));
177 1.1 scottr
178 1.1 scottr /* these functions are for the PB Duo series and the PB 5XX series */
179 1.4 scottr int pm_receive_pm2 __P((u_char *));
180 1.4 scottr int pm_send_pm2 __P((u_char));
181 1.4 scottr int pm_pmgrop_pm2 __P((PMData *));
182 1.9 briggs void pm_intr_pm2 __P((void *));
183 1.1 scottr
184 1.1 scottr /* this function is MRG-Based (for testing) */
185 1.4 scottr int pm_pmgrop_mrg __P((PMData *));
186 1.1 scottr
187 1.1 scottr /* these functions are called from adb_direct.c */
188 1.4 scottr void pm_setup_adb __P((void));
189 1.4 scottr void pm_check_adb_devices __P((int));
190 1.9 briggs void pm_intr __P((void *));
191 1.4 scottr int pm_adb_op __P((u_char *, void *, void *, int));
192 1.9 briggs void pm_hw_setup __P((void));
193 1.1 scottr
194 1.1 scottr /* these functions also use the variables of adb_direct.c */
195 1.4 scottr void pm_adb_get_TALK_result __P((PMData *));
196 1.4 scottr void pm_adb_get_ADB_data __P((PMData *));
197 1.4 scottr void pm_adb_poll_next_device_pm1 __P((PMData *));
198 1.1 scottr
199 1.1 scottr
200 1.1 scottr /*
201 1.1 scottr * These variables are in adb_direct.c.
202 1.1 scottr */
203 1.1 scottr extern u_char *adbBuffer; /* pointer to user data area */
204 1.1 scottr extern void *adbCompRout; /* pointer to the completion routine */
205 1.1 scottr extern void *adbCompData; /* pointer to the completion routine data */
206 1.1 scottr extern int adbWaiting; /* waiting for return data from the device */
207 1.1 scottr extern int adbWaitingCmd; /* ADB command we are waiting for */
208 1.1 scottr extern int adbStarting; /* doing ADB reinit, so do "polling" differently */
209 1.1 scottr
210 1.5 scottr #define ADB_MAX_MSG_LENGTH 16
211 1.5 scottr #define ADB_MAX_HDR_LENGTH 8
212 1.5 scottr struct adbCommand {
213 1.5 scottr u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
214 1.5 scottr u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
215 1.5 scottr u_char *saveBuf; /* where to save result */
216 1.5 scottr u_char *compRout; /* completion routine pointer */
217 1.5 scottr u_char *compData; /* completion routine data pointer */
218 1.5 scottr u_int cmd; /* the original command for this data */
219 1.5 scottr u_int unsol; /* 1 if packet was unsolicited */
220 1.5 scottr u_int ack_only; /* 1 for no special processing */
221 1.5 scottr };
222 1.5 scottr extern void adb_pass_up __P((struct adbCommand *));
223 1.5 scottr
224 1.7 ender extern int ite_polling; /* Are we polling? (Debugger mode) */
225 1.5 scottr
226 1.6 scottr #if 0
227 1.1 scottr /*
228 1.1 scottr * Define the external functions
229 1.1 scottr */
230 1.4 scottr extern int zshard __P((int)); /* from zs.c */
231 1.6 scottr #endif
232 1.1 scottr
233 1.3 scottr #ifdef ADB_DEBUG
234 1.1 scottr /*
235 1.1 scottr * This function dumps contents of the PMData
236 1.1 scottr */
237 1.1 scottr void
238 1.1 scottr pm_printerr(ttl, rval, num, data)
239 1.4 scottr char *ttl;
240 1.4 scottr int rval;
241 1.4 scottr int num;
242 1.4 scottr char *data;
243 1.1 scottr {
244 1.1 scottr int i;
245 1.1 scottr
246 1.4 scottr printf("pm: %s:%04x %02x ", ttl, rval, num);
247 1.4 scottr for (i = 0; i < num; i++)
248 1.4 scottr printf("%02x ", data[i]);
249 1.4 scottr printf("\n");
250 1.1 scottr }
251 1.1 scottr #endif
252 1.1 scottr
253 1.1 scottr
254 1.1 scottr
255 1.1 scottr /*
256 1.1 scottr * Check the hardware type of the Power Manager
257 1.1 scottr */
258 1.1 scottr void
259 1.4 scottr pm_setup_adb()
260 1.1 scottr {
261 1.1 scottr switch (mac68k_machine.machineid) {
262 1.1 scottr case MACH_MACPB140:
263 1.1 scottr case MACH_MACPB145:
264 1.1 scottr case MACH_MACPB150:
265 1.1 scottr case MACH_MACPB160:
266 1.1 scottr case MACH_MACPB165:
267 1.1 scottr case MACH_MACPB165C:
268 1.1 scottr case MACH_MACPB170:
269 1.1 scottr case MACH_MACPB180:
270 1.1 scottr case MACH_MACPB180C:
271 1.1 scottr pmHardware = PM_HW_PB1XX;
272 1.1 scottr break;
273 1.1 scottr case MACH_MACPB210:
274 1.1 scottr case MACH_MACPB230:
275 1.1 scottr case MACH_MACPB250:
276 1.1 scottr case MACH_MACPB270:
277 1.1 scottr case MACH_MACPB280:
278 1.1 scottr case MACH_MACPB280C:
279 1.1 scottr case MACH_MACPB500:
280 1.1 scottr pmHardware = PM_HW_PB5XX;
281 1.1 scottr break;
282 1.1 scottr default:
283 1.1 scottr break;
284 1.1 scottr }
285 1.1 scottr }
286 1.1 scottr
287 1.1 scottr
288 1.1 scottr /*
289 1.1 scottr * Check the existent ADB devices
290 1.1 scottr */
291 1.1 scottr void
292 1.1 scottr pm_check_adb_devices(id)
293 1.1 scottr int id;
294 1.1 scottr {
295 1.1 scottr u_short ed = 0x1;
296 1.1 scottr
297 1.1 scottr ed <<= id;
298 1.1 scottr pm_existent_ADB_devices |= ed;
299 1.1 scottr }
300 1.1 scottr
301 1.1 scottr
302 1.1 scottr /*
303 1.1 scottr * Wait until PM IC is busy
304 1.1 scottr */
305 1.1 scottr int
306 1.1 scottr pm_wait_busy(delay)
307 1.1 scottr int delay;
308 1.1 scottr {
309 1.4 scottr while (PM_IS_ON) {
310 1.1 scottr #ifdef PM_GRAB_SI
311 1.6 scottr #if 0
312 1.1 scottr zshard(0); /* grab any serial interrupts */
313 1.6 scottr #else
314 1.6 scottr (void)intr_dispatch(0x70);
315 1.6 scottr #endif
316 1.1 scottr #endif
317 1.1 scottr if ((--delay) < 0)
318 1.5 scottr return 1; /* timeout */
319 1.1 scottr }
320 1.5 scottr return 0;
321 1.1 scottr }
322 1.1 scottr
323 1.1 scottr
324 1.1 scottr /*
325 1.1 scottr * Wait until PM IC is free
326 1.1 scottr */
327 1.1 scottr int
328 1.1 scottr pm_wait_free(delay)
329 1.1 scottr int delay;
330 1.1 scottr {
331 1.4 scottr while (PM_IS_OFF) {
332 1.1 scottr #ifdef PM_GRAB_SI
333 1.6 scottr #if 0
334 1.1 scottr zshard(0); /* grab any serial interrupts */
335 1.6 scottr #else
336 1.6 scottr (void)intr_dispatch(0x70);
337 1.6 scottr #endif
338 1.1 scottr #endif
339 1.1 scottr if ((--delay) < 0)
340 1.5 scottr return 0; /* timeout */
341 1.1 scottr }
342 1.5 scottr return 1;
343 1.1 scottr }
344 1.1 scottr
345 1.1 scottr
346 1.1 scottr
347 1.1 scottr /*
348 1.1 scottr * Functions for the PB1XX series
349 1.1 scottr */
350 1.1 scottr
351 1.1 scottr /*
352 1.1 scottr * Receive data from PM for the PB1XX series
353 1.1 scottr */
354 1.1 scottr int
355 1.1 scottr pm_receive_pm1(data)
356 1.1 scottr u_char *data;
357 1.1 scottr {
358 1.1 scottr int rval = 0xffffcd34;
359 1.1 scottr
360 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
361 1.1 scottr
362 1.4 scottr switch (1) {
363 1.1 scottr default:
364 1.4 scottr if (pm_wait_busy(0x40) != 0)
365 1.1 scottr break; /* timeout */
366 1.1 scottr
367 1.1 scottr PM_SET_STATE_ACKOFF();
368 1.1 scottr *data = via_reg(VIA2, 0x200);
369 1.1 scottr
370 1.1 scottr rval = 0xffffcd33;
371 1.4 scottr if (pm_wait_free(0x40) == 0)
372 1.1 scottr break; /* timeout */
373 1.1 scottr
374 1.1 scottr rval = 0x00;
375 1.1 scottr break;
376 1.1 scottr }
377 1.1 scottr
378 1.1 scottr PM_SET_STATE_ACKON();
379 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
380 1.1 scottr
381 1.5 scottr return rval;
382 1.1 scottr }
383 1.1 scottr
384 1.1 scottr
385 1.1 scottr
386 1.1 scottr /*
387 1.1 scottr * Send data to PM for the PB1XX series
388 1.1 scottr */
389 1.1 scottr int
390 1.1 scottr pm_send_pm1(data, delay)
391 1.1 scottr u_char data;
392 1.1 scottr int delay;
393 1.1 scottr {
394 1.4 scottr int rval;
395 1.1 scottr
396 1.1 scottr via_reg(VIA2, vDirA) = 0xff;
397 1.1 scottr via_reg(VIA2, 0x200) = data;
398 1.1 scottr
399 1.1 scottr PM_SET_STATE_ACKOFF();
400 1.4 scottr if (pm_wait_busy(0x400) != 0) {
401 1.1 scottr PM_SET_STATE_ACKON();
402 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
403 1.1 scottr
404 1.5 scottr return 0xffffcd36;
405 1.1 scottr }
406 1.1 scottr
407 1.1 scottr rval = 0x0;
408 1.1 scottr PM_SET_STATE_ACKON();
409 1.4 scottr if (pm_wait_free(0x40) == 0)
410 1.1 scottr rval = 0xffffcd35;
411 1.1 scottr
412 1.1 scottr PM_SET_STATE_ACKON();
413 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
414 1.1 scottr
415 1.5 scottr return rval;
416 1.1 scottr }
417 1.1 scottr
418 1.1 scottr
419 1.1 scottr /*
420 1.1 scottr * My PMgrOp routine for the PB1XX series
421 1.1 scottr */
422 1.1 scottr int
423 1.1 scottr pm_pmgrop_pm1(pmdata)
424 1.1 scottr PMData *pmdata;
425 1.1 scottr {
426 1.4 scottr int i;
427 1.4 scottr int s = 0x81815963;
428 1.4 scottr u_char via1_vIER, via1_vDirA;
429 1.4 scottr int rval = 0;
430 1.4 scottr int num_pm_data = 0;
431 1.4 scottr u_char pm_cmd;
432 1.4 scottr u_char pm_data;
433 1.4 scottr u_char *pm_buf;
434 1.1 scottr
435 1.1 scottr /* disable all inetrrupts but PM */
436 1.1 scottr via1_vIER = via_reg(VIA1, vIER);
437 1.1 scottr PM_VIA_INTR_DISABLE();
438 1.1 scottr
439 1.1 scottr via1_vDirA = via_reg(VIA1, vDirA);
440 1.1 scottr
441 1.4 scottr switch (pmdata->command) {
442 1.1 scottr default:
443 1.4 scottr for (i = 0; i < 7; i++) {
444 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
445 1.1 scottr
446 1.1 scottr /* wait until PM is free */
447 1.4 scottr if (pm_wait_free(ADBDelay) == 0) { /* timeout */
448 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
449 1.1 scottr /* restore formar value */
450 1.1 scottr via_reg(VIA1, vDirA) = via1_vDirA;
451 1.1 scottr via_reg(VIA1, vIER) = via1_vIER;
452 1.5 scottr return 0xffffcd38;
453 1.1 scottr }
454 1.1 scottr
455 1.4 scottr switch (mac68k_machine.machineid) {
456 1.1 scottr case MACH_MACPB160:
457 1.1 scottr case MACH_MACPB165:
458 1.1 scottr case MACH_MACPB165C:
459 1.8 scottr case MACH_MACPB170:
460 1.1 scottr case MACH_MACPB180:
461 1.1 scottr case MACH_MACPB180C:
462 1.1 scottr {
463 1.1 scottr int delay = ADBDelay * 16;
464 1.1 scottr
465 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
466 1.4 scottr while ((via_reg(VIA2, 0x200) == 0x7f) && (delay >= 0))
467 1.1 scottr delay--;
468 1.1 scottr
469 1.1 scottr if (delay < 0) { /* timeout */
470 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
471 1.1 scottr /* restore formar value */
472 1.1 scottr via_reg(VIA1, vIER) = via1_vIER;
473 1.5 scottr return 0xffffcd38;
474 1.1 scottr }
475 1.1 scottr }
476 1.1 scottr } /* end switch */
477 1.1 scottr
478 1.4 scottr s = splhigh();
479 1.1 scottr
480 1.1 scottr via1_vDirA = via_reg(VIA1, vDirA);
481 1.1 scottr via_reg(VIA1, vDirA) &= 0x7f;
482 1.1 scottr
483 1.1 scottr pm_cmd = (u_char)(pmdata->command & 0xff);
484 1.4 scottr if ((rval = pm_send_pm1(pm_cmd, ADBDelay * 8)) == 0)
485 1.4 scottr break; /* send command succeeded */
486 1.1 scottr
487 1.1 scottr via_reg(VIA1, vDirA) = via1_vDirA;
488 1.1 scottr splx(s);
489 1.1 scottr } /* end for */
490 1.1 scottr
491 1.1 scottr /* failed to send a command */
492 1.1 scottr if (i == 7) {
493 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
494 1.1 scottr /* restore formar value */
495 1.1 scottr via_reg(VIA1, vDirA) = via1_vDirA;
496 1.1 scottr via_reg(VIA1, vIER) = via1_vIER;
497 1.5 scottr return 0xffffcd38;
498 1.1 scottr }
499 1.1 scottr
500 1.1 scottr /* send # of PM data */
501 1.1 scottr num_pm_data = pmdata->num_data;
502 1.4 scottr if ((rval = pm_send_pm1((u_char)(num_pm_data & 0xff), ADBDelay * 8)) != 0)
503 1.1 scottr break; /* timeout */
504 1.1 scottr
505 1.1 scottr /* send PM data */
506 1.1 scottr pm_buf = (u_char *)pmdata->s_buf;
507 1.4 scottr for (i = 0; i < num_pm_data; i++)
508 1.4 scottr if ((rval = pm_send_pm1(pm_buf[i], ADBDelay * 8)) != 0)
509 1.4 scottr break; /* timeout */
510 1.1 scottr if ((i != num_pm_data) && (num_pm_data != 0))
511 1.4 scottr break; /* timeout */
512 1.1 scottr
513 1.1 scottr /* Will PM IC return data? */
514 1.1 scottr if ((pm_cmd & 0x08) == 0) {
515 1.1 scottr rval = 0;
516 1.4 scottr break; /* no returned data */
517 1.1 scottr }
518 1.1 scottr
519 1.1 scottr rval = 0xffffcd37;
520 1.4 scottr if (pm_wait_busy(ADBDelay) != 0)
521 1.1 scottr break; /* timeout */
522 1.1 scottr
523 1.1 scottr /* receive PM command */
524 1.4 scottr if ((rval = pm_receive_pm1(&pm_data)) != 0)
525 1.1 scottr break;
526 1.1 scottr
527 1.1 scottr pmdata->command = pm_data;
528 1.1 scottr
529 1.1 scottr /* receive number of PM data */
530 1.4 scottr if ((rval = pm_receive_pm1(&pm_data)) != 0)
531 1.4 scottr break; /* timeout */
532 1.1 scottr num_pm_data = pm_data;
533 1.1 scottr pmdata->num_data = num_pm_data;
534 1.1 scottr
535 1.1 scottr /* receive PM data */
536 1.1 scottr pm_buf = (u_char *)pmdata->r_buf;
537 1.4 scottr for (i = 0; i < num_pm_data; i++) {
538 1.4 scottr if ((rval = pm_receive_pm1(&pm_data)) != 0)
539 1.1 scottr break; /* timeout */
540 1.1 scottr pm_buf[i] = pm_data;
541 1.1 scottr }
542 1.1 scottr
543 1.1 scottr rval = 0;
544 1.1 scottr }
545 1.1 scottr
546 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
547 1.1 scottr
548 1.1 scottr /* restore formar value */
549 1.1 scottr via_reg(VIA1, vDirA) = via1_vDirA;
550 1.1 scottr via_reg(VIA1, vIER) = via1_vIER;
551 1.1 scottr if (s != 0x81815963)
552 1.1 scottr splx(s);
553 1.1 scottr
554 1.5 scottr return rval;
555 1.1 scottr }
556 1.1 scottr
557 1.1 scottr
558 1.1 scottr /*
559 1.5 scottr * My PM interrupt routine for PB1XX series
560 1.1 scottr */
561 1.1 scottr void
562 1.9 briggs pm_intr_pm1(arg)
563 1.9 briggs void *arg;
564 1.1 scottr {
565 1.4 scottr int s;
566 1.4 scottr int rval;
567 1.4 scottr PMData pmdata;
568 1.1 scottr
569 1.1 scottr s = splhigh();
570 1.1 scottr
571 1.1 scottr PM_VIA_CLR_INTR(); /* clear VIA1 interrupt */
572 1.1 scottr
573 1.1 scottr /* ask PM what happend */
574 1.1 scottr pmdata.command = 0x78;
575 1.1 scottr pmdata.num_data = 0;
576 1.1 scottr pmdata.data[0] = pmdata.data[1] = 0;
577 1.1 scottr pmdata.s_buf = &pmdata.data[2];
578 1.1 scottr pmdata.r_buf = &pmdata.data[2];
579 1.4 scottr rval = pm_pmgrop_pm1(&pmdata);
580 1.1 scottr if (rval != 0) {
581 1.3 scottr #ifdef ADB_DEBUG
582 1.3 scottr if (adb_debug)
583 1.3 scottr printf("pm: PM is not ready. error code=%08x\n", rval);
584 1.1 scottr #endif
585 1.1 scottr splx(s);
586 1.1 scottr }
587 1.1 scottr
588 1.1 scottr if ((pmdata.data[2] & 0x10) == 0x10) {
589 1.4 scottr if ((pmdata.data[2] & 0x0f) == 0) {
590 1.4 scottr /* ADB data that were requested by TALK command */
591 1.1 scottr pm_adb_get_TALK_result(&pmdata);
592 1.4 scottr } else if ((pmdata.data[2] & 0x08) == 0x8) {
593 1.4 scottr /* PM is requesting to poll */
594 1.1 scottr pm_adb_poll_next_device_pm1(&pmdata);
595 1.4 scottr } else if ((pmdata.data[2] & 0x04) == 0x4) {
596 1.4 scottr /* ADB device event */
597 1.1 scottr pm_adb_get_ADB_data(&pmdata);
598 1.1 scottr }
599 1.1 scottr } else {
600 1.3 scottr #ifdef ADB_DEBUG
601 1.3 scottr if (adb_debug)
602 1.3 scottr pm_printerr("driver does not supported this event.",
603 1.3 scottr rval, pmdata.num_data, pmdata.data);
604 1.1 scottr #endif
605 1.1 scottr }
606 1.1 scottr
607 1.1 scottr splx(s);
608 1.1 scottr }
609 1.1 scottr
610 1.1 scottr
611 1.1 scottr
612 1.1 scottr /*
613 1.1 scottr * Functions for the PB Duo series and the PB 5XX series
614 1.1 scottr */
615 1.1 scottr
616 1.1 scottr /*
617 1.1 scottr * Receive data from PM for the PB Duo series and the PB 5XX series
618 1.1 scottr */
619 1.1 scottr int
620 1.1 scottr pm_receive_pm2(data)
621 1.1 scottr u_char *data;
622 1.1 scottr {
623 1.4 scottr int i;
624 1.4 scottr int rval;
625 1.1 scottr
626 1.1 scottr rval = 0xffffcd34;
627 1.1 scottr
628 1.4 scottr switch (1) {
629 1.1 scottr default:
630 1.1 scottr /* set VIA SR to input mode */
631 1.1 scottr via_reg(VIA1, vACR) |= 0x0c;
632 1.1 scottr via_reg(VIA1, vACR) &= ~0x10;
633 1.1 scottr i = PM_SR();
634 1.1 scottr
635 1.1 scottr PM_SET_STATE_ACKOFF();
636 1.1 scottr if (pm_wait_busy((int)ADBDelay*32) != 0)
637 1.1 scottr break; /* timeout */
638 1.1 scottr
639 1.1 scottr PM_SET_STATE_ACKON();
640 1.1 scottr rval = 0xffffcd33;
641 1.1 scottr if (pm_wait_free((int)ADBDelay*32) == 0)
642 1.1 scottr break; /* timeout */
643 1.1 scottr
644 1.1 scottr *data = PM_SR();
645 1.1 scottr rval = 0;
646 1.1 scottr
647 1.1 scottr break;
648 1.1 scottr }
649 1.1 scottr
650 1.1 scottr PM_SET_STATE_ACKON();
651 1.1 scottr via_reg(VIA1, vACR) |= 0x1c;
652 1.1 scottr
653 1.5 scottr return rval;
654 1.1 scottr }
655 1.1 scottr
656 1.1 scottr
657 1.1 scottr
658 1.1 scottr /*
659 1.1 scottr * Send data to PM for the PB Duo series and the PB 5XX series
660 1.1 scottr */
661 1.1 scottr int
662 1.1 scottr pm_send_pm2(data)
663 1.1 scottr u_char data;
664 1.1 scottr {
665 1.4 scottr int rval;
666 1.1 scottr
667 1.1 scottr via_reg(VIA1, vACR) |= 0x1c;
668 1.1 scottr PM_SR() = data;
669 1.1 scottr
670 1.1 scottr PM_SET_STATE_ACKOFF();
671 1.1 scottr rval = 0xffffcd36;
672 1.1 scottr if (pm_wait_busy((int)ADBDelay*32) != 0) {
673 1.1 scottr PM_SET_STATE_ACKON();
674 1.1 scottr
675 1.1 scottr via_reg(VIA1, vACR) |= 0x1c;
676 1.1 scottr
677 1.5 scottr return rval;
678 1.1 scottr }
679 1.1 scottr
680 1.1 scottr PM_SET_STATE_ACKON();
681 1.1 scottr rval = 0xffffcd35;
682 1.1 scottr if (pm_wait_free((int)ADBDelay*32) != 0)
683 1.1 scottr rval = 0;
684 1.1 scottr
685 1.1 scottr PM_SET_STATE_ACKON();
686 1.1 scottr via_reg(VIA1, vACR) |= 0x1c;
687 1.1 scottr
688 1.5 scottr return rval;
689 1.1 scottr }
690 1.1 scottr
691 1.1 scottr
692 1.1 scottr
693 1.1 scottr /*
694 1.1 scottr * My PMgrOp routine for the PB Duo series and the PB 5XX series
695 1.1 scottr */
696 1.1 scottr int
697 1.1 scottr pm_pmgrop_pm2(pmdata)
698 1.1 scottr PMData *pmdata;
699 1.1 scottr {
700 1.4 scottr int i;
701 1.4 scottr int s;
702 1.4 scottr u_char via1_vIER;
703 1.4 scottr int rval = 0;
704 1.4 scottr int num_pm_data = 0;
705 1.4 scottr u_char pm_cmd;
706 1.4 scottr short pm_num_rx_data;
707 1.4 scottr u_char pm_data;
708 1.4 scottr u_char *pm_buf;
709 1.1 scottr
710 1.4 scottr s = splhigh();
711 1.1 scottr
712 1.1 scottr /* disable all inetrrupts but PM */
713 1.1 scottr via1_vIER = 0x10;
714 1.1 scottr via1_vIER &= via_reg(VIA1, vIER);
715 1.1 scottr via_reg(VIA1, vIER) = via1_vIER;
716 1.1 scottr if (via1_vIER != 0x0)
717 1.1 scottr via1_vIER |= 0x80;
718 1.1 scottr
719 1.4 scottr switch (pmdata->command) {
720 1.1 scottr default:
721 1.1 scottr /* wait until PM is free */
722 1.1 scottr pm_cmd = (u_char)(pmdata->command & 0xff);
723 1.1 scottr rval = 0xcd38;
724 1.4 scottr if (pm_wait_free(ADBDelay * 4) == 0)
725 1.1 scottr break; /* timeout */
726 1.1 scottr
727 1.4 scottr if (HwCfgFlags3 & 0x00200000) {
728 1.4 scottr /* PB 160, PB 165(c), PB 180(c)? */
729 1.4 scottr int delay = ADBDelay * 16;
730 1.1 scottr
731 1.1 scottr via_reg(VIA2, vDirA) = 0x00;
732 1.4 scottr while ((via_reg(VIA2, 0x200) == 0x07) &&
733 1.4 scottr (delay >= 0))
734 1.1 scottr delay--;
735 1.1 scottr
736 1.1 scottr if (delay < 0) {
737 1.1 scottr rval = 0xffffcd38;
738 1.1 scottr break; /* timeout */
739 1.1 scottr }
740 1.1 scottr }
741 1.1 scottr
742 1.1 scottr /* send PM command */
743 1.4 scottr if ((rval = pm_send_pm2((u_char)(pm_cmd & 0xff))))
744 1.1 scottr break; /* timeout */
745 1.1 scottr
746 1.1 scottr /* send number of PM data */
747 1.1 scottr num_pm_data = pmdata->num_data;
748 1.1 scottr if (HwCfgFlags3 & 0x00020000) { /* PB Duo, PB 5XX */
749 1.1 scottr if (pm_send_cmd_type[pm_cmd] < 0) {
750 1.4 scottr if ((rval = pm_send_pm2((u_char)(num_pm_data & 0xff))) != 0)
751 1.1 scottr break; /* timeout */
752 1.1 scottr pmdata->command = 0;
753 1.1 scottr }
754 1.1 scottr } else { /* PB 1XX series ? */
755 1.4 scottr if ((rval = pm_send_pm2((u_char)(num_pm_data & 0xff))) != 0)
756 1.1 scottr break; /* timeout */
757 1.1 scottr }
758 1.1 scottr /* send PM data */
759 1.1 scottr pm_buf = (u_char *)pmdata->s_buf;
760 1.4 scottr for (i = 0 ; i < num_pm_data; i++)
761 1.4 scottr if ((rval = pm_send_pm2(pm_buf[i])) != 0)
762 1.1 scottr break; /* timeout */
763 1.1 scottr if (i != num_pm_data)
764 1.1 scottr break; /* timeout */
765 1.1 scottr
766 1.1 scottr
767 1.1 scottr /* check if PM will send me data */
768 1.1 scottr pm_num_rx_data = pm_receive_cmd_type[pm_cmd];
769 1.1 scottr pmdata->num_data = pm_num_rx_data;
770 1.1 scottr if (pm_num_rx_data == 0) {
771 1.1 scottr rval = 0;
772 1.1 scottr break; /* no return data */
773 1.1 scottr }
774 1.1 scottr
775 1.1 scottr /* receive PM command */
776 1.1 scottr pm_data = pmdata->command;
777 1.1 scottr if (HwCfgFlags3 & 0x00020000) { /* PB Duo, PB 5XX */
778 1.1 scottr pm_num_rx_data--;
779 1.1 scottr if (pm_num_rx_data == 0)
780 1.4 scottr if ((rval = pm_receive_pm2(&pm_data)) != 0) {
781 1.1 scottr rval = 0xffffcd37;
782 1.1 scottr break;
783 1.1 scottr }
784 1.1 scottr pmdata->command = pm_data;
785 1.1 scottr } else { /* PB 1XX series ? */
786 1.4 scottr if ((rval = pm_receive_pm2(&pm_data)) != 0) {
787 1.1 scottr rval = 0xffffcd37;
788 1.1 scottr break;
789 1.1 scottr }
790 1.1 scottr pmdata->command = pm_data;
791 1.1 scottr }
792 1.1 scottr
793 1.1 scottr /* receive number of PM data */
794 1.1 scottr if (HwCfgFlags3 & 0x00020000) { /* PB Duo, PB 5XX */
795 1.1 scottr if (pm_num_rx_data < 0) {
796 1.4 scottr if ((rval = pm_receive_pm2(&pm_data)) != 0)
797 1.1 scottr break; /* timeout */
798 1.1 scottr num_pm_data = pm_data;
799 1.1 scottr } else
800 1.1 scottr num_pm_data = pm_num_rx_data;
801 1.1 scottr pmdata->num_data = num_pm_data;
802 1.1 scottr } else { /* PB 1XX serias ? */
803 1.4 scottr if ((rval = pm_receive_pm2(&pm_data)) != 0)
804 1.1 scottr break; /* timeout */
805 1.1 scottr num_pm_data = pm_data;
806 1.1 scottr pmdata->num_data = num_pm_data;
807 1.1 scottr }
808 1.1 scottr
809 1.1 scottr /* receive PM data */
810 1.1 scottr pm_buf = (u_char *)pmdata->r_buf;
811 1.4 scottr for (i = 0; i < num_pm_data; i++) {
812 1.4 scottr if ((rval = pm_receive_pm2(&pm_data)) != 0)
813 1.1 scottr break; /* timeout */
814 1.1 scottr pm_buf[i] = pm_data;
815 1.1 scottr }
816 1.1 scottr
817 1.1 scottr rval = 0;
818 1.1 scottr }
819 1.1 scottr
820 1.1 scottr /* restore former value */
821 1.1 scottr via_reg(VIA1, vIER) = via1_vIER;
822 1.1 scottr splx(s);
823 1.1 scottr
824 1.5 scottr return rval;
825 1.1 scottr }
826 1.1 scottr
827 1.1 scottr
828 1.1 scottr /*
829 1.1 scottr * My PM interrupt routine for the PB Duo series and the PB 5XX series
830 1.1 scottr */
831 1.1 scottr void
832 1.9 briggs pm_intr_pm2(arg)
833 1.9 briggs void *arg;
834 1.1 scottr {
835 1.4 scottr int s;
836 1.4 scottr int rval;
837 1.4 scottr PMData pmdata;
838 1.1 scottr
839 1.1 scottr s = splhigh();
840 1.1 scottr
841 1.4 scottr PM_VIA_CLR_INTR(); /* clear VIA1 interrupt */
842 1.4 scottr /* ask PM what happend */
843 1.1 scottr pmdata.command = 0x78;
844 1.1 scottr pmdata.num_data = 0;
845 1.1 scottr pmdata.s_buf = &pmdata.data[2];
846 1.1 scottr pmdata.r_buf = &pmdata.data[2];
847 1.4 scottr rval = pm_pmgrop_pm2(&pmdata);
848 1.1 scottr if (rval != 0) {
849 1.3 scottr #ifdef ADB_DEBUG
850 1.3 scottr if (adb_debug)
851 1.3 scottr printf("pm: PM is not ready. error code: %08x\n", rval);
852 1.1 scottr #endif
853 1.1 scottr splx(s);
854 1.1 scottr }
855 1.1 scottr
856 1.4 scottr switch ((u_int)(pmdata.data[2] & 0xff)) {
857 1.4 scottr case 0x00: /* 1 sec interrupt? */
858 1.1 scottr break;
859 1.4 scottr case 0x80: /* 1 sec interrupt? */
860 1.1 scottr pm_counter++;
861 1.1 scottr break;
862 1.4 scottr case 0x08: /* Brightness/Contrast button on LCD panel */
863 1.1 scottr /* get brightness and contrast of the LCD */
864 1.1 scottr pm_LCD_brightness = (u_int)pmdata.data[3] & 0xff;
865 1.1 scottr pm_LCD_contrast = (u_int)pmdata.data[4] & 0xff;
866 1.1 scottr /*
867 1.4 scottr pm_printerr("#08", rval, pmdata.num_data, pmdata.data);
868 1.1 scottr pmdata.command = 0x33;
869 1.1 scottr pmdata.num_data = 1;
870 1.1 scottr pmdata.s_buf = pmdata.data;
871 1.1 scottr pmdata.r_buf = pmdata.data;
872 1.1 scottr pmdata.data[0] = pm_LCD_contrast;
873 1.4 scottr rval = pm_pmgrop_pm2(&pmdata);
874 1.4 scottr pm_printerr("#33", rval, pmdata.num_data, pmdata.data);
875 1.1 scottr */
876 1.1 scottr /* this is an experimental code */
877 1.1 scottr pmdata.command = 0x41;
878 1.1 scottr pmdata.num_data = 1;
879 1.1 scottr pmdata.s_buf = pmdata.data;
880 1.1 scottr pmdata.r_buf = pmdata.data;
881 1.1 scottr pm_LCD_brightness = 0x7f - pm_LCD_brightness / 2;
882 1.4 scottr if (pm_LCD_brightness < 0x25)
883 1.4 scottr pm_LCD_brightness = 0x25;
884 1.4 scottr if (pm_LCD_brightness > 0x5a)
885 1.4 scottr pm_LCD_brightness = 0x7f;
886 1.1 scottr pmdata.data[0] = pm_LCD_brightness;
887 1.4 scottr rval = pm_pmgrop_pm2(&pmdata);
888 1.1 scottr break;
889 1.4 scottr case 0x10: /* ADB data that were requested by TALK command */
890 1.1 scottr case 0x14:
891 1.1 scottr pm_adb_get_TALK_result(&pmdata);
892 1.1 scottr break;
893 1.4 scottr case 0x16: /* ADB device event */
894 1.1 scottr case 0x18:
895 1.1 scottr case 0x1e:
896 1.1 scottr pm_adb_get_ADB_data(&pmdata);
897 1.1 scottr break;
898 1.1 scottr default:
899 1.3 scottr #ifdef ADB_DEBUG
900 1.3 scottr if (adb_debug)
901 1.3 scottr pm_printerr("driver does not supported this event.",
902 1.3 scottr pmdata.data[2], pmdata.num_data,
903 1.3 scottr pmdata.data);
904 1.1 scottr #endif
905 1.1 scottr break;
906 1.1 scottr }
907 1.1 scottr
908 1.1 scottr splx(s);
909 1.1 scottr }
910 1.1 scottr
911 1.1 scottr
912 1.1 scottr /*
913 1.1 scottr * MRG-based PMgrOp routine
914 1.1 scottr */
915 1.1 scottr int
916 1.1 scottr pm_pmgrop_mrg(pmdata)
917 1.1 scottr PMData *pmdata;
918 1.1 scottr {
919 1.1 scottr u_int32_t rval=0;
920 1.1 scottr
921 1.1 scottr asm("
922 1.1 scottr movl %1, a0
923 1.5 scottr .word 0xa085
924 1.1 scottr movl d0, %0"
925 1.1 scottr : "=g" (rval)
926 1.1 scottr : "g" (pmdata)
927 1.1 scottr : "a0", "d0" );
928 1.1 scottr
929 1.1 scottr return rval;
930 1.1 scottr }
931 1.1 scottr
932 1.1 scottr
933 1.1 scottr /*
934 1.1 scottr * My PMgrOp routine
935 1.1 scottr */
936 1.1 scottr int
937 1.1 scottr pmgrop(pmdata)
938 1.1 scottr PMData *pmdata;
939 1.1 scottr {
940 1.4 scottr switch (pmHardware) {
941 1.1 scottr case PM_HW_PB1XX:
942 1.4 scottr return (pm_pmgrop_pm1(pmdata));
943 1.1 scottr break;
944 1.1 scottr case PM_HW_PB5XX:
945 1.4 scottr return (pm_pmgrop_pm2(pmdata));
946 1.1 scottr break;
947 1.1 scottr default:
948 1.4 scottr /* return (pmgrop_mrg(pmdata)); */
949 1.5 scottr return 1;
950 1.1 scottr }
951 1.1 scottr }
952 1.1 scottr
953 1.1 scottr
954 1.1 scottr /*
955 1.1 scottr * My PM interrupt routine
956 1.1 scottr */
957 1.1 scottr void
958 1.9 briggs pm_intr(arg)
959 1.9 briggs void *arg;
960 1.1 scottr {
961 1.4 scottr switch (pmHardware) {
962 1.1 scottr case PM_HW_PB1XX:
963 1.9 briggs pm_intr_pm1(arg);
964 1.1 scottr break;
965 1.1 scottr case PM_HW_PB5XX:
966 1.9 briggs pm_intr_pm2(arg);
967 1.1 scottr break;
968 1.1 scottr default:
969 1.1 scottr break;
970 1.1 scottr }
971 1.1 scottr }
972 1.1 scottr
973 1.1 scottr
974 1.9 briggs void
975 1.9 briggs pm_hw_setup()
976 1.9 briggs {
977 1.9 briggs switch (pmHardware) {
978 1.9 briggs case PM_HW_PB1XX:
979 1.9 briggs via1_register_irq(4, pm_intr_pm1, (void *)0);
980 1.9 briggs PM_VIA_CLR_INTR();
981 1.9 briggs break;
982 1.9 briggs case PM_HW_PB5XX:
983 1.9 briggs via1_register_irq(4, pm_intr_pm2, (void *)0);
984 1.9 briggs PM_VIA_CLR_INTR();
985 1.9 briggs break;
986 1.9 briggs default:
987 1.9 briggs break;
988 1.9 briggs }
989 1.9 briggs }
990 1.9 briggs
991 1.1 scottr
992 1.1 scottr /*
993 1.1 scottr * Synchronous ADBOp routine for the Power Manager
994 1.1 scottr */
995 1.1 scottr int
996 1.1 scottr pm_adb_op(buffer, compRout, data, command)
997 1.1 scottr u_char *buffer;
998 1.1 scottr void *compRout;
999 1.1 scottr void *data;
1000 1.1 scottr int command;
1001 1.1 scottr {
1002 1.5 scottr int i;
1003 1.4 scottr int s;
1004 1.4 scottr int rval;
1005 1.4 scottr int delay;
1006 1.4 scottr PMData pmdata;
1007 1.5 scottr struct adbCommand packet;
1008 1.1 scottr
1009 1.1 scottr if (adbWaiting == 1)
1010 1.5 scottr return 1;
1011 1.1 scottr
1012 1.1 scottr s = splhigh();
1013 1.1 scottr via_reg(VIA1, vIER) = 0x10;
1014 1.1 scottr
1015 1.1 scottr adbBuffer = buffer;
1016 1.1 scottr adbCompRout = compRout;
1017 1.1 scottr adbCompData = data;
1018 1.1 scottr
1019 1.1 scottr pmdata.command = 0x20;
1020 1.1 scottr pmdata.s_buf = pmdata.data;
1021 1.1 scottr pmdata.r_buf = pmdata.data;
1022 1.1 scottr
1023 1.1 scottr if ((command & 0xc) == 0x8) { /* if the command is LISTEN, add number of ADB data to number of PM data */
1024 1.1 scottr if (buffer != (u_char *)0)
1025 1.1 scottr pmdata.num_data = buffer[0] + 3;
1026 1.1 scottr } else {
1027 1.1 scottr pmdata.num_data = 3;
1028 1.1 scottr }
1029 1.1 scottr
1030 1.1 scottr pmdata.data[0] = (u_char)(command & 0xff);
1031 1.1 scottr pmdata.data[1] = 0;
1032 1.1 scottr if ((command & 0xc) == 0x8) { /* if the command is LISTEN, copy ADB data to PM buffer */
1033 1.1 scottr if ((buffer != (u_char *)0) && (buffer[0] <= 24)) {
1034 1.1 scottr pmdata.data[2] = buffer[0]; /* number of data */
1035 1.4 scottr for (i = 0; i < buffer[0]; i++)
1036 1.1 scottr pmdata.data[3 + i] = buffer[1 + i];
1037 1.1 scottr } else
1038 1.1 scottr pmdata.data[2] = 0;
1039 1.1 scottr } else
1040 1.1 scottr pmdata.data[2] = 0;
1041 1.1 scottr
1042 1.5 scottr if ((command & 0xc) != 0xc) { /* if the command is not TALK */
1043 1.9 briggs /* set up stuff fNULLor adb_pass_up */
1044 1.5 scottr packet.data[0] = 1 + pmdata.data[2];
1045 1.5 scottr packet.data[1] = command;
1046 1.5 scottr for (i = 0; i < pmdata.data[2]; i++)
1047 1.5 scottr packet.data[i+2] = pmdata.data[i+3];
1048 1.5 scottr packet.saveBuf = adbBuffer;
1049 1.5 scottr packet.compRout = adbCompRout;
1050 1.5 scottr packet.compData = adbCompData;
1051 1.5 scottr packet.cmd = command;
1052 1.5 scottr packet.unsol = 0;
1053 1.5 scottr packet.ack_only = 1;
1054 1.7 ender ite_polling = 1;
1055 1.5 scottr adb_pass_up(&packet);
1056 1.7 ender ite_polling = 0;
1057 1.5 scottr }
1058 1.5 scottr
1059 1.4 scottr rval = pmgrop(&pmdata);
1060 1.1 scottr if (rval != 0)
1061 1.5 scottr return 1;
1062 1.1 scottr
1063 1.5 scottr adbWaiting = 1;
1064 1.5 scottr adbWaitingCmd = command;
1065 1.1 scottr
1066 1.1 scottr PM_VIA_INTR_ENABLE();
1067 1.1 scottr
1068 1.1 scottr /* wait until the PM interrupt is occured */
1069 1.1 scottr delay = 0x80000;
1070 1.4 scottr while (adbWaiting == 1) {
1071 1.1 scottr if ((via_reg(VIA1, vIFR) & 0x10) == 0x10)
1072 1.9 briggs pm_intr((void *)0);
1073 1.1 scottr #ifdef PM_GRAB_SI
1074 1.6 scottr #if 0
1075 1.1 scottr zshard(0); /* grab any serial interrupts */
1076 1.6 scottr #else
1077 1.6 scottr (void)intr_dispatch(0x70);
1078 1.6 scottr #endif
1079 1.1 scottr #endif
1080 1.1 scottr if ((--delay) < 0)
1081 1.5 scottr return 1;
1082 1.1 scottr }
1083 1.1 scottr
1084 1.4 scottr /* this command enables the interrupt by operating ADB devices */
1085 1.5 scottr if (HwCfgFlags3 & 0x00020000) { /* PB Duo series, PB 5XX series */
1086 1.1 scottr pmdata.command = 0x20;
1087 1.1 scottr pmdata.num_data = 4;
1088 1.1 scottr pmdata.s_buf = pmdata.data;
1089 1.1 scottr pmdata.r_buf = pmdata.data;
1090 1.1 scottr pmdata.data[0] = 0x00;
1091 1.1 scottr pmdata.data[1] = 0x86; /* magic spell for awaking the PM */
1092 1.1 scottr pmdata.data[2] = 0x00;
1093 1.1 scottr pmdata.data[3] = 0x0c; /* each bit may express the existent ADB device */
1094 1.5 scottr } else { /* PB 1XX series */
1095 1.1 scottr pmdata.command = 0x20;
1096 1.1 scottr pmdata.num_data = 3;
1097 1.1 scottr pmdata.s_buf = pmdata.data;
1098 1.1 scottr pmdata.r_buf = pmdata.data;
1099 1.1 scottr pmdata.data[0] = (u_char)(command & 0xf0) | 0xc;
1100 1.1 scottr pmdata.data[1] = 0x04;
1101 1.1 scottr pmdata.data[2] = 0x00;
1102 1.1 scottr }
1103 1.4 scottr rval = pmgrop(&pmdata);
1104 1.1 scottr
1105 1.1 scottr splx(s);
1106 1.5 scottr return rval;
1107 1.1 scottr }
1108 1.1 scottr
1109 1.1 scottr
1110 1.1 scottr void
1111 1.1 scottr pm_adb_get_TALK_result(pmdata)
1112 1.1 scottr PMData *pmdata;
1113 1.1 scottr {
1114 1.1 scottr int i;
1115 1.5 scottr struct adbCommand packet;
1116 1.1 scottr
1117 1.5 scottr /* set up data for adb_pass_up */
1118 1.5 scottr packet.data[0] = pmdata->num_data-1;
1119 1.5 scottr packet.data[1] = pmdata->data[3];
1120 1.5 scottr for (i = 0; i <packet.data[0]-1; i++)
1121 1.5 scottr packet.data[i+2] = pmdata->data[i+4];
1122 1.5 scottr
1123 1.5 scottr packet.saveBuf = adbBuffer;
1124 1.5 scottr packet.compRout = adbCompRout;
1125 1.5 scottr packet.compData = adbCompData;
1126 1.5 scottr packet.unsol = 0;
1127 1.5 scottr packet.ack_only = 0;
1128 1.7 ender ite_polling = 1;
1129 1.5 scottr adb_pass_up(&packet);
1130 1.7 ender ite_polling = 0;
1131 1.5 scottr
1132 1.5 scottr adbWaiting = 0;
1133 1.5 scottr adbBuffer = (long)0;
1134 1.5 scottr adbCompRout = (long)0;
1135 1.5 scottr adbCompData = (long)0;
1136 1.1 scottr }
1137 1.1 scottr
1138 1.1 scottr
1139 1.1 scottr void
1140 1.1 scottr pm_adb_get_ADB_data(pmdata)
1141 1.1 scottr PMData *pmdata;
1142 1.1 scottr {
1143 1.1 scottr int i;
1144 1.5 scottr struct adbCommand packet;
1145 1.1 scottr
1146 1.5 scottr /* set up data for adb_pass_up */
1147 1.5 scottr packet.data[0] = pmdata->num_data-1; /* number of raw data */
1148 1.5 scottr packet.data[1] = pmdata->data[3]; /* ADB command */
1149 1.5 scottr for (i = 0; i <packet.data[0]-1; i++)
1150 1.5 scottr packet.data[i+2] = pmdata->data[i+4];
1151 1.5 scottr packet.unsol = 1;
1152 1.5 scottr packet.ack_only = 0;
1153 1.5 scottr adb_pass_up(&packet);
1154 1.1 scottr }
1155 1.1 scottr
1156 1.1 scottr
1157 1.1 scottr void
1158 1.1 scottr pm_adb_poll_next_device_pm1(pmdata)
1159 1.1 scottr PMData *pmdata;
1160 1.1 scottr {
1161 1.1 scottr int i;
1162 1.1 scottr int ndid;
1163 1.1 scottr u_short bendid = 0x1;
1164 1.1 scottr int rval;
1165 1.1 scottr PMData tmp_pmdata;
1166 1.1 scottr
1167 1.1 scottr /* find another existent ADB device to poll */
1168 1.4 scottr for (i = 1; i < 16; i++) {
1169 1.1 scottr ndid = (((pmdata->data[3] & 0xf0) >> 4) + i) & 0xf;
1170 1.1 scottr bendid <<= ndid;
1171 1.1 scottr if ((pm_existent_ADB_devices & bendid) != 0)
1172 1.1 scottr break;
1173 1.1 scottr }
1174 1.1 scottr
1175 1.1 scottr /* poll the other device */
1176 1.1 scottr tmp_pmdata.command = 0x20;
1177 1.1 scottr tmp_pmdata.num_data = 3;
1178 1.1 scottr tmp_pmdata.s_buf = tmp_pmdata.data;
1179 1.1 scottr tmp_pmdata.r_buf = tmp_pmdata.data;
1180 1.1 scottr tmp_pmdata.data[0] = (u_char)(ndid << 4) | 0xc;
1181 1.1 scottr tmp_pmdata.data[1] = 0x04; /* magic spell for awaking the PM */
1182 1.1 scottr tmp_pmdata.data[2] = 0x00;
1183 1.4 scottr rval = pmgrop(&tmp_pmdata);
1184 1.1 scottr }
1185 1.5 scottr
1186 1.1 scottr
1187 1.1 scottr
1188