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