• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Device driver for the PMU on 68K-based Apple PowerBooks
3  *
4  * The VIA (versatile interface adapter) interfaces to the PMU,
5  * a 6805 microprocessor core whose primary function is to control
6  * battery charging and system power on the PowerBooks.
7  * The PMU also controls the ADB (Apple Desktop Bus) which connects
8  * to the keyboard and mouse, as well as the non-volatile RAM
9  * and the RTC (real time clock) chip.
10  *
11  * Adapted for 68K PMU by Joshua M. Thompson
12  *
13  * Based largely on the PowerMac PMU code by Paul Mackerras and
14  * Fabio Riccardi.
15  *
16  * Also based on the PMU driver from MkLinux by Apple Computer, Inc.
17  * and the Open Software Foundation, Inc.
18  */
19 
20 #include <stdarg.h>
21 #include <linux/types.h>
22 #include <linux/errno.h>
23 #include <linux/kernel.h>
24 #include <linux/delay.h>
25 #include <linux/miscdevice.h>
26 #include <linux/blkdev.h>
27 #include <linux/pci.h>
28 #include <linux/slab.h>
29 #include <linux/init.h>
30 #include <linux/interrupt.h>
31 
32 #include <linux/adb.h>
33 #include <linux/pmu.h>
34 #include <linux/cuda.h>
35 
36 #include <asm/macintosh.h>
37 #include <asm/macints.h>
38 #include <asm/mac_via.h>
39 
40 #include <asm/pgtable.h>
41 #include <asm/system.h>
42 #include <asm/irq.h>
43 #include <asm/uaccess.h>
44 
45 /* Misc minor number allocated for /dev/pmu */
46 #define PMU_MINOR	154
47 
48 /* VIA registers - spaced 0x200 bytes apart */
49 #define RS		0x200		/* skip between registers */
50 #define B		0		/* B-side data */
51 #define A		RS		/* A-side data */
52 #define DIRB		(2*RS)		/* B-side direction (1=output) */
53 #define DIRA		(3*RS)		/* A-side direction (1=output) */
54 #define T1CL		(4*RS)		/* Timer 1 ctr/latch (low 8 bits) */
55 #define T1CH		(5*RS)		/* Timer 1 counter (high 8 bits) */
56 #define T1LL		(6*RS)		/* Timer 1 latch (low 8 bits) */
57 #define T1LH		(7*RS)		/* Timer 1 latch (high 8 bits) */
58 #define T2CL		(8*RS)		/* Timer 2 ctr/latch (low 8 bits) */
59 #define T2CH		(9*RS)		/* Timer 2 counter (high 8 bits) */
60 #define SR		(10*RS)		/* Shift register */
61 #define ACR		(11*RS)		/* Auxiliary control register */
62 #define PCR		(12*RS)		/* Peripheral control register */
63 #define IFR		(13*RS)		/* Interrupt flag register */
64 #define IER		(14*RS)		/* Interrupt enable register */
65 #define ANH		(15*RS)		/* A-side data, no handshake */
66 
67 /* Bits in B data register: both active low */
68 #define TACK		0x02		/* Transfer acknowledge (input) */
69 #define TREQ		0x04		/* Transfer request (output) */
70 
71 /* Bits in ACR */
72 #define SR_CTRL		0x1c		/* Shift register control bits */
73 #define SR_EXT		0x0c		/* Shift on external clock */
74 #define SR_OUT		0x10		/* Shift out if 1 */
75 
76 /* Bits in IFR and IER */
77 #define SR_INT		0x04		/* Shift register full/empty */
78 #define CB1_INT		0x10		/* transition on CB1 input */
79 
80 static enum pmu_state {
81 	idle,
82 	sending,
83 	intack,
84 	reading,
85 	reading_intr,
86 } pmu_state;
87 
88 static struct adb_request *current_req;
89 static struct adb_request *last_req;
90 static struct adb_request *req_awaiting_reply;
91 static unsigned char interrupt_data[32];
92 static unsigned char *reply_ptr;
93 static int data_index;
94 static int data_len;
95 static int adb_int_pending;
96 static int pmu_adb_flags;
97 static int adb_dev_map;
98 static struct adb_request bright_req_1, bright_req_2, bright_req_3;
99 static int pmu_kind = PMU_UNKNOWN;
100 static int pmu_fully_inited;
101 
102 int asleep;
103 
104 static int pmu_probe(void);
105 static int pmu_init(void);
106 static void pmu_start(void);
107 static irqreturn_t pmu_interrupt(int irq, void *arg);
108 static int pmu_send_request(struct adb_request *req, int sync);
109 static int pmu_autopoll(int devs);
110 void pmu_poll(void);
111 static int pmu_reset_bus(void);
112 
113 static void pmu_start(void);
114 static void send_byte(int x);
115 static void recv_byte(void);
116 static void pmu_done(struct adb_request *req);
117 static void pmu_handle_data(unsigned char *data, int len);
118 static void set_volume(int level);
119 static void pmu_enable_backlight(int on);
120 static void pmu_set_brightness(int level);
121 
122 struct adb_driver via_pmu_driver = {
123 	"68K PMU",
124 	pmu_probe,
125 	pmu_init,
126 	pmu_send_request,
127 	pmu_autopoll,
128 	pmu_poll,
129 	pmu_reset_bus
130 };
131 
132 /*
133  * This table indicates for each PMU opcode:
134  * - the number of data bytes to be sent with the command, or -1
135  *   if a length byte should be sent,
136  * - the number of response bytes which the PMU will return, or
137  *   -1 if it will send a length byte.
138  */
139 static s8 pmu_data_len[256][2] = {
140 /*	   0	   1	   2	   3	   4	   5	   6	   7  */
141 /*00*/	{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
142 /*08*/	{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
143 /*10*/	{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
144 /*18*/	{ 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0, 0},
145 /*20*/	{-1, 0},{ 0, 0},{ 2, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},
146 /*28*/	{ 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0,-1},
147 /*30*/	{ 4, 0},{20, 0},{-1, 0},{ 3, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
148 /*38*/	{ 0, 4},{ 0,20},{ 2,-1},{ 2, 1},{ 3,-1},{-1,-1},{-1,-1},{ 4, 0},
149 /*40*/	{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
150 /*48*/	{ 0, 1},{ 0, 1},{-1,-1},{ 1, 0},{ 1, 0},{-1,-1},{-1,-1},{-1,-1},
151 /*50*/	{ 1, 0},{ 0, 0},{ 2, 0},{ 2, 0},{-1, 0},{ 1, 0},{ 3, 0},{ 1, 0},
152 /*58*/	{ 0, 1},{ 1, 0},{ 0, 2},{ 0, 2},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},
153 /*60*/	{ 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
154 /*68*/	{ 0, 3},{ 0, 3},{ 0, 2},{ 0, 8},{ 0,-1},{ 0,-1},{-1,-1},{-1,-1},
155 /*70*/	{ 1, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
156 /*78*/	{ 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{ 5, 1},{ 4, 1},{ 4, 1},
157 /*80*/	{ 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
158 /*88*/	{ 0, 5},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
159 /*90*/	{ 1, 0},{ 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
160 /*98*/	{ 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
161 /*a0*/	{ 2, 0},{ 2, 0},{ 2, 0},{ 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},
162 /*a8*/	{ 1, 1},{ 1, 0},{ 3, 0},{ 2, 0},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
163 /*b0*/	{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
164 /*b8*/	{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
165 /*c0*/	{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
166 /*c8*/	{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
167 /*d0*/	{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
168 /*d8*/	{ 1, 1},{ 1, 1},{-1,-1},{-1,-1},{ 0, 1},{ 0,-1},{-1,-1},{-1,-1},
169 /*e0*/	{-1, 0},{ 4, 0},{ 0, 1},{-1, 0},{-1, 0},{ 4, 0},{-1, 0},{-1, 0},
170 /*e8*/	{ 3,-1},{-1,-1},{ 0, 1},{-1,-1},{ 0,-1},{-1,-1},{-1,-1},{ 0, 0},
171 /*f0*/	{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
172 /*f8*/	{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
173 };
174 
pmu_probe(void)175 int pmu_probe(void)
176 {
177 	if (macintosh_config->adb_type == MAC_ADB_PB1) {
178 		pmu_kind = PMU_68K_V1;
179 	} else if (macintosh_config->adb_type == MAC_ADB_PB2) {
180 		pmu_kind = PMU_68K_V2;
181 	} else {
182 		return -ENODEV;
183 	}
184 
185 	pmu_state = idle;
186 
187 	return 0;
188 }
189 
190 static int
pmu_init(void)191 pmu_init(void)
192 {
193 	int timeout;
194 	volatile struct adb_request req;
195 
196 	via2[B] |= TREQ;				/* negate TREQ */
197 	via2[DIRB] = (via2[DIRB] | TREQ) & ~TACK;	/* TACK in, TREQ out */
198 
199 	pmu_request((struct adb_request *) &req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB);
200 	timeout =  100000;
201 	while (!req.complete) {
202 		if (--timeout < 0) {
203 			printk(KERN_ERR "pmu_init: no response from PMU\n");
204 			return -EAGAIN;
205 		}
206 		udelay(10);
207 		pmu_poll();
208 	}
209 
210 	/* ack all pending interrupts */
211 	timeout = 100000;
212 	interrupt_data[0] = 1;
213 	while (interrupt_data[0] || pmu_state != idle) {
214 		if (--timeout < 0) {
215 			printk(KERN_ERR "pmu_init: timed out acking intrs\n");
216 			return -EAGAIN;
217 		}
218 		if (pmu_state == idle) {
219 			adb_int_pending = 1;
220 			pmu_interrupt(0, NULL);
221 		}
222 		pmu_poll();
223 		udelay(10);
224 	}
225 
226 	pmu_request((struct adb_request *) &req, NULL, 2, PMU_SET_INTR_MASK,
227 			PMU_INT_ADB_AUTO|PMU_INT_SNDBRT|PMU_INT_ADB);
228 	timeout =  100000;
229 	while (!req.complete) {
230 		if (--timeout < 0) {
231 			printk(KERN_ERR "pmu_init: no response from PMU\n");
232 			return -EAGAIN;
233 		}
234 		udelay(10);
235 		pmu_poll();
236 	}
237 
238 	bright_req_1.complete = 1;
239 	bright_req_2.complete = 1;
240 	bright_req_3.complete = 1;
241 
242 	if (request_irq(IRQ_MAC_ADB_SR, pmu_interrupt, 0, "pmu-shift",
243 			pmu_interrupt)) {
244 		printk(KERN_ERR "pmu_init: can't get irq %d\n",
245 			IRQ_MAC_ADB_SR);
246 		return -EAGAIN;
247 	}
248 	if (request_irq(IRQ_MAC_ADB_CL, pmu_interrupt, 0, "pmu-clock",
249 			pmu_interrupt)) {
250 		printk(KERN_ERR "pmu_init: can't get irq %d\n",
251 			IRQ_MAC_ADB_CL);
252 		free_irq(IRQ_MAC_ADB_SR, pmu_interrupt);
253 		return -EAGAIN;
254 	}
255 
256 	pmu_fully_inited = 1;
257 
258 	/* Enable backlight */
259 	pmu_enable_backlight(1);
260 
261 	printk("adb: PMU 68K driver v0.5 for Unified ADB.\n");
262 
263 	return 0;
264 }
265 
266 int
pmu_get_model(void)267 pmu_get_model(void)
268 {
269 	return pmu_kind;
270 }
271 
272 /* Send an ADB command */
273 static int
pmu_send_request(struct adb_request * req,int sync)274 pmu_send_request(struct adb_request *req, int sync)
275 {
276     int i, ret;
277 
278     if (!pmu_fully_inited)
279     {
280  	req->complete = 1;
281    	return -ENXIO;
282    }
283 
284     ret = -EINVAL;
285 
286     switch (req->data[0]) {
287     case PMU_PACKET:
288 		for (i = 0; i < req->nbytes - 1; ++i)
289 			req->data[i] = req->data[i+1];
290 		--req->nbytes;
291 		if (pmu_data_len[req->data[0]][1] != 0) {
292 			req->reply[0] = ADB_RET_OK;
293 			req->reply_len = 1;
294 		} else
295 			req->reply_len = 0;
296 		ret = pmu_queue_request(req);
297 		break;
298     case CUDA_PACKET:
299 		switch (req->data[1]) {
300 		case CUDA_GET_TIME:
301 			if (req->nbytes != 2)
302 				break;
303 			req->data[0] = PMU_READ_RTC;
304 			req->nbytes = 1;
305 			req->reply_len = 3;
306 			req->reply[0] = CUDA_PACKET;
307 			req->reply[1] = 0;
308 			req->reply[2] = CUDA_GET_TIME;
309 			ret = pmu_queue_request(req);
310 			break;
311 		case CUDA_SET_TIME:
312 			if (req->nbytes != 6)
313 				break;
314 			req->data[0] = PMU_SET_RTC;
315 			req->nbytes = 5;
316 			for (i = 1; i <= 4; ++i)
317 				req->data[i] = req->data[i+1];
318 			req->reply_len = 3;
319 			req->reply[0] = CUDA_PACKET;
320 			req->reply[1] = 0;
321 			req->reply[2] = CUDA_SET_TIME;
322 			ret = pmu_queue_request(req);
323 			break;
324 		case CUDA_GET_PRAM:
325 			if (req->nbytes != 4)
326 				break;
327 			req->data[0] = PMU_READ_NVRAM;
328 			req->data[1] = req->data[2];
329 			req->data[2] = req->data[3];
330 			req->nbytes = 3;
331 			req->reply_len = 3;
332 			req->reply[0] = CUDA_PACKET;
333 			req->reply[1] = 0;
334 			req->reply[2] = CUDA_GET_PRAM;
335 			ret = pmu_queue_request(req);
336 			break;
337 		case CUDA_SET_PRAM:
338 			if (req->nbytes != 5)
339 				break;
340 			req->data[0] = PMU_WRITE_NVRAM;
341 			req->data[1] = req->data[2];
342 			req->data[2] = req->data[3];
343 			req->data[3] = req->data[4];
344 			req->nbytes = 4;
345 			req->reply_len = 3;
346 			req->reply[0] = CUDA_PACKET;
347 			req->reply[1] = 0;
348 			req->reply[2] = CUDA_SET_PRAM;
349 			ret = pmu_queue_request(req);
350 			break;
351 		}
352 		break;
353     case ADB_PACKET:
354 		for (i = req->nbytes - 1; i > 1; --i)
355 			req->data[i+2] = req->data[i];
356 		req->data[3] = req->nbytes - 2;
357 		req->data[2] = pmu_adb_flags;
358 		/*req->data[1] = req->data[1];*/
359 		req->data[0] = PMU_ADB_CMD;
360 		req->nbytes += 2;
361 		req->reply_expected = 1;
362 		req->reply_len = 0;
363 		ret = pmu_queue_request(req);
364 		break;
365     }
366     if (ret)
367     {
368     	req->complete = 1;
369     	return ret;
370     }
371 
372     if (sync) {
373 	while (!req->complete)
374 		pmu_poll();
375     }
376 
377     return 0;
378 }
379 
380 /* Enable/disable autopolling */
381 static int
pmu_autopoll(int devs)382 pmu_autopoll(int devs)
383 {
384 	struct adb_request req;
385 
386 	if (!pmu_fully_inited) return -ENXIO;
387 
388 	if (devs) {
389 		adb_dev_map = devs;
390 		pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86,
391 			    adb_dev_map >> 8, adb_dev_map);
392 		pmu_adb_flags = 2;
393 	} else {
394 		pmu_request(&req, NULL, 1, PMU_ADB_POLL_OFF);
395 		pmu_adb_flags = 0;
396 	}
397 	while (!req.complete)
398 		pmu_poll();
399 	return 0;
400 }
401 
402 /* Reset the ADB bus */
403 static int
pmu_reset_bus(void)404 pmu_reset_bus(void)
405 {
406 	struct adb_request req;
407 	long timeout;
408 	int save_autopoll = adb_dev_map;
409 
410 	if (!pmu_fully_inited) return -ENXIO;
411 
412 	/* anyone got a better idea?? */
413 	pmu_autopoll(0);
414 
415 	req.nbytes = 5;
416 	req.done = NULL;
417 	req.data[0] = PMU_ADB_CMD;
418 	req.data[1] = 0;
419 	req.data[2] = 3; /* ADB_BUSRESET ??? */
420 	req.data[3] = 0;
421 	req.data[4] = 0;
422 	req.reply_len = 0;
423 	req.reply_expected = 1;
424 	if (pmu_queue_request(&req) != 0)
425 	{
426 		printk(KERN_ERR "pmu_adb_reset_bus: pmu_queue_request failed\n");
427 		return -EIO;
428 	}
429 	while (!req.complete)
430 		pmu_poll();
431 	timeout = 100000;
432 	while (!req.complete) {
433 		if (--timeout < 0) {
434 			printk(KERN_ERR "pmu_adb_reset_bus (reset): no response from PMU\n");
435 			return -EIO;
436 		}
437 		udelay(10);
438 		pmu_poll();
439 	}
440 
441 	if (save_autopoll != 0)
442 		pmu_autopoll(save_autopoll);
443 
444 	return 0;
445 }
446 
447 /* Construct and send a pmu request */
448 int
pmu_request(struct adb_request * req,void (* done)(struct adb_request *),int nbytes,...)449 pmu_request(struct adb_request *req, void (*done)(struct adb_request *),
450 	    int nbytes, ...)
451 {
452 	va_list list;
453 	int i;
454 
455 	if (nbytes < 0 || nbytes > 32) {
456 		printk(KERN_ERR "pmu_request: bad nbytes (%d)\n", nbytes);
457 		req->complete = 1;
458 		return -EINVAL;
459 	}
460 	req->nbytes = nbytes;
461 	req->done = done;
462 	va_start(list, nbytes);
463 	for (i = 0; i < nbytes; ++i)
464 		req->data[i] = va_arg(list, int);
465 	va_end(list);
466 	if (pmu_data_len[req->data[0]][1] != 0) {
467 		req->reply[0] = ADB_RET_OK;
468 		req->reply_len = 1;
469 	} else
470 		req->reply_len = 0;
471 	req->reply_expected = 0;
472 	return pmu_queue_request(req);
473 }
474 
475 int
pmu_queue_request(struct adb_request * req)476 pmu_queue_request(struct adb_request *req)
477 {
478 	unsigned long flags;
479 	int nsend;
480 
481 	if (req->nbytes <= 0) {
482 		req->complete = 1;
483 		return 0;
484 	}
485 	nsend = pmu_data_len[req->data[0]][0];
486 	if (nsend >= 0 && req->nbytes != nsend + 1) {
487 		req->complete = 1;
488 		return -EINVAL;
489 	}
490 
491 	req->next = NULL;
492 	req->sent = 0;
493 	req->complete = 0;
494 	local_irq_save(flags);
495 
496 	if (current_req != 0) {
497 		last_req->next = req;
498 		last_req = req;
499 	} else {
500 		current_req = req;
501 		last_req = req;
502 		if (pmu_state == idle)
503 			pmu_start();
504 	}
505 
506 	local_irq_restore(flags);
507 	return 0;
508 }
509 
510 static void
send_byte(int x)511 send_byte(int x)
512 {
513 	via1[ACR] |= SR_CTRL;
514 	via1[SR] = x;
515 	via2[B] &= ~TREQ;		/* assert TREQ */
516 }
517 
518 static void
recv_byte(void)519 recv_byte(void)
520 {
521 	char c;
522 
523 	via1[ACR] = (via1[ACR] | SR_EXT) & ~SR_OUT;
524 	c = via1[SR];		/* resets SR */
525 	via2[B] &= ~TREQ;
526 }
527 
528 static void
pmu_start(void)529 pmu_start(void)
530 {
531 	unsigned long flags;
532 	struct adb_request *req;
533 
534 	/* assert pmu_state == idle */
535 	/* get the packet to send */
536 	local_irq_save(flags);
537 	req = current_req;
538 	if (req == 0 || pmu_state != idle
539 	    || (req->reply_expected && req_awaiting_reply))
540 		goto out;
541 
542 	pmu_state = sending;
543 	data_index = 1;
544 	data_len = pmu_data_len[req->data[0]][0];
545 
546 	/* set the shift register to shift out and send a byte */
547 	send_byte(req->data[0]);
548 
549 out:
550 	local_irq_restore(flags);
551 }
552 
553 void
pmu_poll(void)554 pmu_poll(void)
555 {
556 	unsigned long flags;
557 
558 	local_irq_save(flags);
559 	if (via1[IFR] & SR_INT) {
560 		via1[IFR] = SR_INT;
561 		pmu_interrupt(IRQ_MAC_ADB_SR, NULL);
562 	}
563 	if (via1[IFR] & CB1_INT) {
564 		via1[IFR] = CB1_INT;
565 		pmu_interrupt(IRQ_MAC_ADB_CL, NULL);
566 	}
567 	local_irq_restore(flags);
568 }
569 
570 static irqreturn_t
pmu_interrupt(int irq,void * dev_id)571 pmu_interrupt(int irq, void *dev_id)
572 {
573 	struct adb_request *req;
574 	int timeout, bite = 0;	/* to prevent compiler warning */
575 
576 #if 0
577 	printk("pmu_interrupt: irq %d state %d acr %02X, b %02X data_index %d/%d adb_int_pending %d\n",
578 		irq, pmu_state, (uint) via1[ACR], (uint) via2[B], data_index, data_len, adb_int_pending);
579 #endif
580 
581 	if (irq == IRQ_MAC_ADB_CL) {		/* CB1 interrupt */
582 		adb_int_pending = 1;
583 	} else if (irq == IRQ_MAC_ADB_SR) {	/* SR interrupt  */
584 		if (via2[B] & TACK) {
585 			printk(KERN_DEBUG "PMU: SR_INT but ack still high! (%x)\n", via2[B]);
586 		}
587 
588 		/* if reading grab the byte */
589 		if ((via1[ACR] & SR_OUT) == 0) bite = via1[SR];
590 
591 		/* reset TREQ and wait for TACK to go high */
592 		via2[B] |= TREQ;
593 		timeout = 3200;
594 		while (!(via2[B] & TACK)) {
595 			if (--timeout < 0) {
596 				printk(KERN_ERR "PMU not responding (!ack)\n");
597 				goto finish;
598 			}
599 			udelay(10);
600 		}
601 
602 		switch (pmu_state) {
603 		case sending:
604 			req = current_req;
605 			if (data_len < 0) {
606 				data_len = req->nbytes - 1;
607 				send_byte(data_len);
608 				break;
609 			}
610 			if (data_index <= data_len) {
611 				send_byte(req->data[data_index++]);
612 				break;
613 			}
614 			req->sent = 1;
615 			data_len = pmu_data_len[req->data[0]][1];
616 			if (data_len == 0) {
617 				pmu_state = idle;
618 				current_req = req->next;
619 				if (req->reply_expected)
620 					req_awaiting_reply = req;
621 				else
622 					pmu_done(req);
623 			} else {
624 				pmu_state = reading;
625 				data_index = 0;
626 				reply_ptr = req->reply + req->reply_len;
627 				recv_byte();
628 			}
629 			break;
630 
631 		case intack:
632 			data_index = 0;
633 			data_len = -1;
634 			pmu_state = reading_intr;
635 			reply_ptr = interrupt_data;
636 			recv_byte();
637 			break;
638 
639 		case reading:
640 		case reading_intr:
641 			if (data_len == -1) {
642 				data_len = bite;
643 				if (bite > 32)
644 					printk(KERN_ERR "PMU: bad reply len %d\n",
645 					       bite);
646 			} else {
647 				reply_ptr[data_index++] = bite;
648 			}
649 			if (data_index < data_len) {
650 				recv_byte();
651 				break;
652 			}
653 
654 			if (pmu_state == reading_intr) {
655 				pmu_handle_data(interrupt_data, data_index);
656 			} else {
657 				req = current_req;
658 				current_req = req->next;
659 				req->reply_len += data_index;
660 				pmu_done(req);
661 			}
662 			pmu_state = idle;
663 
664 			break;
665 
666 		default:
667 			printk(KERN_ERR "pmu_interrupt: unknown state %d?\n",
668 			       pmu_state);
669 		}
670 	}
671 finish:
672 	if (pmu_state == idle) {
673 		if (adb_int_pending) {
674 			pmu_state = intack;
675 			send_byte(PMU_INT_ACK);
676 			adb_int_pending = 0;
677 		} else if (current_req) {
678 			pmu_start();
679 		}
680 	}
681 
682 #if 0
683 	printk("pmu_interrupt: exit state %d acr %02X, b %02X data_index %d/%d adb_int_pending %d\n",
684 		pmu_state, (uint) via1[ACR], (uint) via2[B], data_index, data_len, adb_int_pending);
685 #endif
686 	return IRQ_HANDLED;
687 }
688 
689 static void
pmu_done(struct adb_request * req)690 pmu_done(struct adb_request *req)
691 {
692 	req->complete = 1;
693 	if (req->done)
694 		(*req->done)(req);
695 }
696 
697 /* Interrupt data could be the result data from an ADB cmd */
698 static void
pmu_handle_data(unsigned char * data,int len)699 pmu_handle_data(unsigned char *data, int len)
700 {
701 	static int show_pmu_ints = 1;
702 
703 	asleep = 0;
704 	if (len < 1) {
705 		adb_int_pending = 0;
706 		return;
707 	}
708 	if (data[0] & PMU_INT_ADB) {
709 		if ((data[0] & PMU_INT_ADB_AUTO) == 0) {
710 			struct adb_request *req = req_awaiting_reply;
711 			if (req == 0) {
712 				printk(KERN_ERR "PMU: extra ADB reply\n");
713 				return;
714 			}
715 			req_awaiting_reply = NULL;
716 			if (len <= 2)
717 				req->reply_len = 0;
718 			else {
719 				memcpy(req->reply, data + 1, len - 1);
720 				req->reply_len = len - 1;
721 			}
722 			pmu_done(req);
723 		} else {
724 			adb_input(data+1, len-1, 1);
725 		}
726 	} else {
727 		if (data[0] == 0x08 && len == 3) {
728 			/* sound/brightness buttons pressed */
729 			pmu_set_brightness(data[1] >> 3);
730 			set_volume(data[2]);
731 		} else if (show_pmu_ints
732 			   && !(data[0] == PMU_INT_TICK && len == 1)) {
733 			int i;
734 			printk(KERN_DEBUG "pmu intr");
735 			for (i = 0; i < len; ++i)
736 				printk(" %.2x", data[i]);
737 			printk("\n");
738 		}
739 	}
740 }
741 
742 static int backlight_level = -1;
743 static int backlight_enabled = 0;
744 
745 #define LEVEL_TO_BRIGHT(lev)	((lev) < 1? 0x7f: 0x4a - ((lev) << 1))
746 
747 static void
pmu_enable_backlight(int on)748 pmu_enable_backlight(int on)
749 {
750 	struct adb_request req;
751 
752 	if (on) {
753 	    /* first call: get current backlight value */
754 	    if (backlight_level < 0) {
755 		switch(pmu_kind) {
756 		    case PMU_68K_V1:
757 		    case PMU_68K_V2:
758 			pmu_request(&req, NULL, 3, PMU_READ_NVRAM, 0x14, 0xe);
759 			while (!req.complete)
760 				pmu_poll();
761 			printk(KERN_DEBUG "pmu: nvram returned bright: %d\n", (int)req.reply[1]);
762 			backlight_level = req.reply[1];
763 			break;
764 		    default:
765 		        backlight_enabled = 0;
766 		        return;
767 		}
768 	    }
769 	    pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT,
770 	    	LEVEL_TO_BRIGHT(backlight_level));
771 	    while (!req.complete)
772 		pmu_poll();
773 	}
774 	pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
775 	    PMU_POW_BACKLIGHT | (on ? PMU_POW_ON : PMU_POW_OFF));
776 	while (!req.complete)
777 		pmu_poll();
778 	backlight_enabled = on;
779 }
780 
781 static void
pmu_set_brightness(int level)782 pmu_set_brightness(int level)
783 {
784 	int bright;
785 
786 	backlight_level = level;
787 	bright = LEVEL_TO_BRIGHT(level);
788 	if (!backlight_enabled)
789 		return;
790 	if (bright_req_1.complete)
791 		pmu_request(&bright_req_1, NULL, 2, PMU_BACKLIGHT_BRIGHT,
792 		    bright);
793 	if (bright_req_2.complete)
794 		pmu_request(&bright_req_2, NULL, 2, PMU_POWER_CTRL,
795 		    PMU_POW_BACKLIGHT | (bright < 0x7f ? PMU_POW_ON : PMU_POW_OFF));
796 }
797 
798 void
pmu_enable_irled(int on)799 pmu_enable_irled(int on)
800 {
801 	struct adb_request req;
802 
803 	pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED |
804 	    (on ? PMU_POW_ON : PMU_POW_OFF));
805 	while (!req.complete)
806 		pmu_poll();
807 }
808 
809 static void
set_volume(int level)810 set_volume(int level)
811 {
812 }
813 
814 int
pmu_present(void)815 pmu_present(void)
816 {
817 	return (pmu_kind != PMU_UNKNOWN);
818 }
819