V4L/DVB (7596): em28xx-dvb: Add support for HVR950
[linux-2.6] / drivers / macintosh / via-pmu68k.c
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
81 static enum pmu_state {
82         idle,
83         sending,
84         intack,
85         reading,
86         reading_intr,
87 } pmu_state;
88
89 static struct adb_request *current_req;
90 static struct adb_request *last_req;
91 static struct adb_request *req_awaiting_reply;
92 static unsigned char interrupt_data[32];
93 static unsigned char *reply_ptr;
94 static int data_index;
95 static int data_len;
96 static int adb_int_pending;
97 static int pmu_adb_flags;
98 static int adb_dev_map;
99 static struct adb_request bright_req_1, bright_req_2, bright_req_3;
100 static int pmu_kind = PMU_UNKNOWN;
101 static int pmu_fully_inited;
102
103 int asleep;
104 BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
105
106 static int pmu_probe(void);
107 static int pmu_init(void);
108 static void pmu_start(void);
109 static irqreturn_t pmu_interrupt(int irq, void *arg);
110 static int pmu_send_request(struct adb_request *req, int sync);
111 static int pmu_autopoll(int devs);
112 void pmu_poll(void);
113 static int pmu_reset_bus(void);
114
115 static void pmu_start(void);
116 static void send_byte(int x);
117 static void recv_byte(void);
118 static void pmu_done(struct adb_request *req);
119 static void pmu_handle_data(unsigned char *data, int len);
120 static void set_volume(int level);
121 static void pmu_enable_backlight(int on);
122 static void pmu_set_brightness(int level);
123
124 struct 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  */
141 static 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
177 int 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
192 static int 
193 pmu_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
268 int
269 pmu_get_model(void)
270 {
271         return pmu_kind;
272 }
273
274 /* Send an ADB command */
275 static int 
276 pmu_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 */
383 static int 
384 pmu_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 */
405 static int 
406 pmu_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 */
450 int 
451 pmu_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
477 int
478 pmu_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
512 static void 
513 send_byte(int x)
514 {
515         via1[ACR] |= SR_CTRL;
516         via1[SR] = x;
517         via2[B] &= ~TREQ;               /* assert TREQ */
518 }
519
520 static void 
521 recv_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
530 static void 
531 pmu_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
551 out:
552         local_irq_restore(flags);
553 }
554
555 void 
556 pmu_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
572 static irqreturn_t
573 pmu_interrupt(int irq, void *dev_id)
574 {
575         struct adb_request *req;
576         int timeout, bite = 0;  /* to prevent compiler warning */
577
578 #if 0
579         printk("pmu_interrupt: irq %d state %d acr %02X, b %02X data_index %d/%d adb_int_pending %d\n",
580                 irq, pmu_state, (uint) via1[ACR], (uint) via2[B], data_index, data_len, adb_int_pending);
581 #endif
582
583         if (irq == IRQ_MAC_ADB_CL) {            /* CB1 interrupt */
584                 adb_int_pending = 1;
585         } else if (irq == IRQ_MAC_ADB_SR) {     /* SR interrupt  */
586                 if (via2[B] & TACK) {
587                         printk(KERN_DEBUG "PMU: SR_INT but ack still high! (%x)\n", via2[B]);
588                 }
589
590                 /* if reading grab the byte */
591                 if ((via1[ACR] & SR_OUT) == 0) bite = via1[SR];
592
593                 /* reset TREQ and wait for TACK to go high */
594                 via2[B] |= TREQ;
595                 timeout = 3200;
596                 while (!(via2[B] & TACK)) {
597                         if (--timeout < 0) {
598                                 printk(KERN_ERR "PMU not responding (!ack)\n");
599                                 goto finish;
600                         }
601                         udelay(10);
602                 }
603
604                 switch (pmu_state) {
605                 case sending:
606                         req = current_req;
607                         if (data_len < 0) {
608                                 data_len = req->nbytes - 1;
609                                 send_byte(data_len);
610                                 break;
611                         }
612                         if (data_index <= data_len) {
613                                 send_byte(req->data[data_index++]);
614                                 break;
615                         }
616                         req->sent = 1;
617                         data_len = pmu_data_len[req->data[0]][1];
618                         if (data_len == 0) {
619                                 pmu_state = idle;
620                                 current_req = req->next;
621                                 if (req->reply_expected)
622                                         req_awaiting_reply = req;
623                                 else
624                                         pmu_done(req);
625                         } else {
626                                 pmu_state = reading;
627                                 data_index = 0;
628                                 reply_ptr = req->reply + req->reply_len;
629                                 recv_byte();
630                         }
631                         break;
632
633                 case intack:
634                         data_index = 0;
635                         data_len = -1;
636                         pmu_state = reading_intr;
637                         reply_ptr = interrupt_data;
638                         recv_byte();
639                         break;
640
641                 case reading:
642                 case reading_intr:
643                         if (data_len == -1) {
644                                 data_len = bite;
645                                 if (bite > 32)
646                                         printk(KERN_ERR "PMU: bad reply len %d\n",
647                                                bite);
648                         } else {
649                                 reply_ptr[data_index++] = bite;
650                         }
651                         if (data_index < data_len) {
652                                 recv_byte();
653                                 break;
654                         }
655
656                         if (pmu_state == reading_intr) {
657                                 pmu_handle_data(interrupt_data, data_index);
658                         } else {
659                                 req = current_req;
660                                 current_req = req->next;
661                                 req->reply_len += data_index;
662                                 pmu_done(req);
663                         }
664                         pmu_state = idle;
665
666                         break;
667
668                 default:
669                         printk(KERN_ERR "pmu_interrupt: unknown state %d?\n",
670                                pmu_state);
671                 }
672         }
673 finish:
674         if (pmu_state == idle) {
675                 if (adb_int_pending) {
676                         pmu_state = intack;
677                         send_byte(PMU_INT_ACK);
678                         adb_int_pending = 0;
679                 } else if (current_req) {
680                         pmu_start();
681                 }
682         }
683
684 #if 0
685         printk("pmu_interrupt: exit state %d acr %02X, b %02X data_index %d/%d adb_int_pending %d\n",
686                 pmu_state, (uint) via1[ACR], (uint) via2[B], data_index, data_len, adb_int_pending);
687 #endif
688         return IRQ_HANDLED;
689 }
690
691 static void 
692 pmu_done(struct adb_request *req)
693 {
694         req->complete = 1;
695         if (req->done)
696                 (*req->done)(req);
697 }
698
699 /* Interrupt data could be the result data from an ADB cmd */
700 static void 
701 pmu_handle_data(unsigned char *data, int len)
702 {
703         static int show_pmu_ints = 1;
704
705         asleep = 0;
706         if (len < 1) {
707                 adb_int_pending = 0;
708                 return;
709         }
710         if (data[0] & PMU_INT_ADB) {
711                 if ((data[0] & PMU_INT_ADB_AUTO) == 0) {
712                         struct adb_request *req = req_awaiting_reply;
713                         if (req == 0) {
714                                 printk(KERN_ERR "PMU: extra ADB reply\n");
715                                 return;
716                         }
717                         req_awaiting_reply = NULL;
718                         if (len <= 2)
719                                 req->reply_len = 0;
720                         else {
721                                 memcpy(req->reply, data + 1, len - 1);
722                                 req->reply_len = len - 1;
723                         }
724                         pmu_done(req);
725                 } else {
726                         adb_input(data+1, len-1, 1);
727                 }
728         } else {
729                 if (data[0] == 0x08 && len == 3) {
730                         /* sound/brightness buttons pressed */
731                         pmu_set_brightness(data[1] >> 3);
732                         set_volume(data[2]);
733                 } else if (show_pmu_ints
734                            && !(data[0] == PMU_INT_TICK && len == 1)) {
735                         int i;
736                         printk(KERN_DEBUG "pmu intr");
737                         for (i = 0; i < len; ++i)
738                                 printk(" %.2x", data[i]);
739                         printk("\n");
740                 }
741         }
742 }
743
744 int backlight_level = -1;
745 int backlight_enabled = 0;
746
747 #define LEVEL_TO_BRIGHT(lev)    ((lev) < 1? 0x7f: 0x4a - ((lev) << 1))
748
749 static void 
750 pmu_enable_backlight(int on)
751 {
752         struct adb_request req;
753
754         if (on) {
755             /* first call: get current backlight value */
756             if (backlight_level < 0) {
757                 switch(pmu_kind) {
758                     case PMU_68K_V1:
759                     case PMU_68K_V2:
760                         pmu_request(&req, NULL, 3, PMU_READ_NVRAM, 0x14, 0xe);
761                         while (!req.complete)
762                                 pmu_poll();
763                         printk(KERN_DEBUG "pmu: nvram returned bright: %d\n", (int)req.reply[1]);
764                         backlight_level = req.reply[1];
765                         break;
766                     default:
767                         backlight_enabled = 0;
768                         return;
769                 }
770             }
771             pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT,
772                 LEVEL_TO_BRIGHT(backlight_level));
773             while (!req.complete)
774                 pmu_poll();
775         }
776         pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
777             PMU_POW_BACKLIGHT | (on ? PMU_POW_ON : PMU_POW_OFF));
778         while (!req.complete)
779                 pmu_poll();
780         backlight_enabled = on;
781 }
782
783 static void 
784 pmu_set_brightness(int level)
785 {
786         int bright;
787
788         backlight_level = level;
789         bright = LEVEL_TO_BRIGHT(level);
790         if (!backlight_enabled)
791                 return;
792         if (bright_req_1.complete)
793                 pmu_request(&bright_req_1, NULL, 2, PMU_BACKLIGHT_BRIGHT,
794                     bright);
795         if (bright_req_2.complete)
796                 pmu_request(&bright_req_2, NULL, 2, PMU_POWER_CTRL,
797                     PMU_POW_BACKLIGHT | (bright < 0x7f ? PMU_POW_ON : PMU_POW_OFF));
798 }
799
800 void 
801 pmu_enable_irled(int on)
802 {
803         struct adb_request req;
804
805         pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED |
806             (on ? PMU_POW_ON : PMU_POW_OFF));
807         while (!req.complete)
808                 pmu_poll();
809 }
810
811 static void 
812 set_volume(int level)
813 {
814 }
815
816 int
817 pmu_present(void)
818 {
819         return (pmu_kind != PMU_UNKNOWN);
820 }