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