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