backlight: Separate backlight properties from backlight ops pointers
[linux-2.6.git] / 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 static int pmu_queue_request(struct adb_request *req);
115
116 static void pmu_start(void);
117 static void send_byte(int x);
118 static void recv_byte(void);
119 static void pmu_done(struct adb_request *req);
120 static void pmu_handle_data(unsigned char *data, int len);
121 static void set_volume(int level);
122 static void pmu_enable_backlight(int on);
123 static void pmu_set_brightness(int level);
124
125 struct adb_driver via_pmu_driver = {
126         "68K PMU",
127         pmu_probe,
128         pmu_init,
129         pmu_send_request,
130         pmu_autopoll,
131         pmu_poll,
132         pmu_reset_bus
133 };
134
135 /*
136  * This table indicates for each PMU opcode:
137  * - the number of data bytes to be sent with the command, or -1
138  *   if a length byte should be sent,
139  * - the number of response bytes which the PMU will return, or
140  *   -1 if it will send a length byte.
141  */
142 static s8 pmu_data_len[256][2] = {
143 /*         0       1       2       3       4       5       6       7  */
144 /*00*/  {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
145 /*08*/  {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
146 /*10*/  { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
147 /*18*/  { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0, 0},
148 /*20*/  {-1, 0},{ 0, 0},{ 2, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},
149 /*28*/  { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{ 0,-1},
150 /*30*/  { 4, 0},{20, 0},{-1, 0},{ 3, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
151 /*38*/  { 0, 4},{ 0,20},{ 2,-1},{ 2, 1},{ 3,-1},{-1,-1},{-1,-1},{ 4, 0},
152 /*40*/  { 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
153 /*48*/  { 0, 1},{ 0, 1},{-1,-1},{ 1, 0},{ 1, 0},{-1,-1},{-1,-1},{-1,-1},
154 /*50*/  { 1, 0},{ 0, 0},{ 2, 0},{ 2, 0},{-1, 0},{ 1, 0},{ 3, 0},{ 1, 0},
155 /*58*/  { 0, 1},{ 1, 0},{ 0, 2},{ 0, 2},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},
156 /*60*/  { 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
157 /*68*/  { 0, 3},{ 0, 3},{ 0, 2},{ 0, 8},{ 0,-1},{ 0,-1},{-1,-1},{-1,-1},
158 /*70*/  { 1, 0},{ 1, 0},{ 1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
159 /*78*/  { 0,-1},{ 0,-1},{-1,-1},{-1,-1},{-1,-1},{ 5, 1},{ 4, 1},{ 4, 1},
160 /*80*/  { 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
161 /*88*/  { 0, 5},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
162 /*90*/  { 1, 0},{ 2, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
163 /*98*/  { 0, 1},{ 0, 1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
164 /*a0*/  { 2, 0},{ 2, 0},{ 2, 0},{ 4, 0},{-1, 0},{ 0, 0},{-1, 0},{-1, 0},
165 /*a8*/  { 1, 1},{ 1, 0},{ 3, 0},{ 2, 0},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
166 /*b0*/  {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
167 /*b8*/  {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
168 /*c0*/  {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
169 /*c8*/  {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
170 /*d0*/  { 0, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
171 /*d8*/  { 1, 1},{ 1, 1},{-1,-1},{-1,-1},{ 0, 1},{ 0,-1},{-1,-1},{-1,-1},
172 /*e0*/  {-1, 0},{ 4, 0},{ 0, 1},{-1, 0},{-1, 0},{ 4, 0},{-1, 0},{-1, 0},
173 /*e8*/  { 3,-1},{-1,-1},{ 0, 1},{-1,-1},{ 0,-1},{-1,-1},{-1,-1},{ 0, 0},
174 /*f0*/  {-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},{-1, 0},
175 /*f8*/  {-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1},
176 };
177
178 int pmu_probe(void)
179 {
180         if (macintosh_config->adb_type == MAC_ADB_PB1) {
181                 pmu_kind = PMU_68K_V1;
182         } else if (macintosh_config->adb_type == MAC_ADB_PB2) {
183                 pmu_kind = PMU_68K_V2;
184         } else {
185                 return -ENODEV;
186         }
187
188         pmu_state = idle;
189
190         return 0;
191 }
192
193 static int 
194 pmu_init(void)
195 {
196         int timeout;
197         volatile struct adb_request req;
198
199         via2[B] |= TREQ;                                /* negate TREQ */
200         via2[DIRB] = (via2[DIRB] | TREQ) & ~TACK;       /* TACK in, TREQ out */
201
202         pmu_request((struct adb_request *) &req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB);
203         timeout =  100000;
204         while (!req.complete) {
205                 if (--timeout < 0) {
206                         printk(KERN_ERR "pmu_init: no response from PMU\n");
207                         return -EAGAIN;
208                 }
209                 udelay(10);
210                 pmu_poll();
211         }
212
213         /* ack all pending interrupts */
214         timeout = 100000;
215         interrupt_data[0] = 1;
216         while (interrupt_data[0] || pmu_state != idle) {
217                 if (--timeout < 0) {
218                         printk(KERN_ERR "pmu_init: timed out acking intrs\n");
219                         return -EAGAIN;
220                 }
221                 if (pmu_state == idle) {
222                         adb_int_pending = 1;
223                         pmu_interrupt(0, NULL);
224                 }
225                 pmu_poll();
226                 udelay(10);
227         }
228
229         pmu_request((struct adb_request *) &req, NULL, 2, PMU_SET_INTR_MASK,
230                         PMU_INT_ADB_AUTO|PMU_INT_SNDBRT|PMU_INT_ADB);
231         timeout =  100000;
232         while (!req.complete) {
233                 if (--timeout < 0) {
234                         printk(KERN_ERR "pmu_init: no response from PMU\n");
235                         return -EAGAIN;
236                 }
237                 udelay(10);
238                 pmu_poll();
239         }
240
241         bright_req_1.complete = 1;
242         bright_req_2.complete = 1;
243         bright_req_3.complete = 1;
244
245         if (request_irq(IRQ_MAC_ADB_SR, pmu_interrupt, 0, "pmu-shift",
246                         pmu_interrupt)) {
247                 printk(KERN_ERR "pmu_init: can't get irq %d\n",
248                         IRQ_MAC_ADB_SR);
249                 return -EAGAIN;
250         }
251         if (request_irq(IRQ_MAC_ADB_CL, pmu_interrupt, 0, "pmu-clock",
252                         pmu_interrupt)) {
253                 printk(KERN_ERR "pmu_init: can't get irq %d\n",
254                         IRQ_MAC_ADB_CL);
255                 free_irq(IRQ_MAC_ADB_SR, pmu_interrupt);
256                 return -EAGAIN;
257         }
258
259         pmu_fully_inited = 1;
260         
261         /* Enable backlight */
262         pmu_enable_backlight(1);
263
264         printk("adb: PMU 68K driver v0.5 for Unified ADB.\n");
265
266         return 0;
267 }
268
269 int
270 pmu_get_model(void)
271 {
272         return pmu_kind;
273 }
274
275 /* Send an ADB command */
276 static int 
277 pmu_send_request(struct adb_request *req, int sync)
278 {
279     int i, ret;
280
281     if (!pmu_fully_inited)
282     {
283         req->complete = 1;
284         return -ENXIO;
285    }
286
287     ret = -EINVAL;
288         
289     switch (req->data[0]) {
290     case PMU_PACKET:
291                 for (i = 0; i < req->nbytes - 1; ++i)
292                         req->data[i] = req->data[i+1];
293                 --req->nbytes;
294                 if (pmu_data_len[req->data[0]][1] != 0) {
295                         req->reply[0] = ADB_RET_OK;
296                         req->reply_len = 1;
297                 } else
298                         req->reply_len = 0;
299                 ret = pmu_queue_request(req);
300                 break;
301     case CUDA_PACKET:
302                 switch (req->data[1]) {
303                 case CUDA_GET_TIME:
304                         if (req->nbytes != 2)
305                                 break;
306                         req->data[0] = PMU_READ_RTC;
307                         req->nbytes = 1;
308                         req->reply_len = 3;
309                         req->reply[0] = CUDA_PACKET;
310                         req->reply[1] = 0;
311                         req->reply[2] = CUDA_GET_TIME;
312                         ret = pmu_queue_request(req);
313                         break;
314                 case CUDA_SET_TIME:
315                         if (req->nbytes != 6)
316                                 break;
317                         req->data[0] = PMU_SET_RTC;
318                         req->nbytes = 5;
319                         for (i = 1; i <= 4; ++i)
320                                 req->data[i] = req->data[i+1];
321                         req->reply_len = 3;
322                         req->reply[0] = CUDA_PACKET;
323                         req->reply[1] = 0;
324                         req->reply[2] = CUDA_SET_TIME;
325                         ret = pmu_queue_request(req);
326                         break;
327                 case CUDA_GET_PRAM:
328                         if (req->nbytes != 4)
329                                 break;
330                         req->data[0] = PMU_READ_NVRAM;
331                         req->data[1] = req->data[2];
332                         req->data[2] = req->data[3];
333                         req->nbytes = 3;
334                         req->reply_len = 3;
335                         req->reply[0] = CUDA_PACKET;
336                         req->reply[1] = 0;
337                         req->reply[2] = CUDA_GET_PRAM;
338                         ret = pmu_queue_request(req);
339                         break;
340                 case CUDA_SET_PRAM:
341                         if (req->nbytes != 5)
342                                 break;
343                         req->data[0] = PMU_WRITE_NVRAM;
344                         req->data[1] = req->data[2];
345                         req->data[2] = req->data[3];
346                         req->data[3] = req->data[4];
347                         req->nbytes = 4;
348                         req->reply_len = 3;
349                         req->reply[0] = CUDA_PACKET;
350                         req->reply[1] = 0;
351                         req->reply[2] = CUDA_SET_PRAM;
352                         ret = pmu_queue_request(req);
353                         break;
354                 }
355                 break;
356     case ADB_PACKET:
357                 for (i = req->nbytes - 1; i > 1; --i)
358                         req->data[i+2] = req->data[i];
359                 req->data[3] = req->nbytes - 2;
360                 req->data[2] = pmu_adb_flags;
361                 /*req->data[1] = req->data[1];*/
362                 req->data[0] = PMU_ADB_CMD;
363                 req->nbytes += 2;
364                 req->reply_expected = 1;
365                 req->reply_len = 0;
366                 ret = pmu_queue_request(req);
367                 break;
368     }
369     if (ret)
370     {
371         req->complete = 1;
372         return ret;
373     }
374         
375     if (sync) {
376         while (!req->complete)
377                 pmu_poll();
378     }
379
380     return 0;
381 }
382
383 /* Enable/disable autopolling */
384 static int 
385 pmu_autopoll(int devs)
386 {
387         struct adb_request req;
388
389         if (!pmu_fully_inited) return -ENXIO;
390
391         if (devs) {
392                 adb_dev_map = devs;
393                 pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86,
394                             adb_dev_map >> 8, adb_dev_map);
395                 pmu_adb_flags = 2;
396         } else {
397                 pmu_request(&req, NULL, 1, PMU_ADB_POLL_OFF);
398                 pmu_adb_flags = 0;
399         }
400         while (!req.complete)
401                 pmu_poll();
402         return 0;
403 }
404
405 /* Reset the ADB bus */
406 static int 
407 pmu_reset_bus(void)
408 {
409         struct adb_request req;
410         long timeout;
411         int save_autopoll = adb_dev_map;
412
413         if (!pmu_fully_inited) return -ENXIO;
414
415         /* anyone got a better idea?? */
416         pmu_autopoll(0);
417
418         req.nbytes = 5;
419         req.done = NULL;
420         req.data[0] = PMU_ADB_CMD;
421         req.data[1] = 0;
422         req.data[2] = 3; /* ADB_BUSRESET ??? */
423         req.data[3] = 0;
424         req.data[4] = 0;
425         req.reply_len = 0;
426         req.reply_expected = 1;
427         if (pmu_queue_request(&req) != 0)
428         {
429                 printk(KERN_ERR "pmu_adb_reset_bus: pmu_queue_request failed\n");
430                 return -EIO;
431         }
432         while (!req.complete)
433                 pmu_poll();
434         timeout = 100000;
435         while (!req.complete) {
436                 if (--timeout < 0) {
437                         printk(KERN_ERR "pmu_adb_reset_bus (reset): no response from PMU\n");
438                         return -EIO;
439                 }
440                 udelay(10);
441                 pmu_poll();
442         }
443
444         if (save_autopoll != 0)
445                 pmu_autopoll(save_autopoll);
446                 
447         return 0;
448 }
449
450 /* Construct and send a pmu request */
451 int 
452 pmu_request(struct adb_request *req, void (*done)(struct adb_request *),
453             int nbytes, ...)
454 {
455         va_list list;
456         int i;
457
458         if (nbytes < 0 || nbytes > 32) {
459                 printk(KERN_ERR "pmu_request: bad nbytes (%d)\n", nbytes);
460                 req->complete = 1;
461                 return -EINVAL;
462         }
463         req->nbytes = nbytes;
464         req->done = done;
465         va_start(list, nbytes);
466         for (i = 0; i < nbytes; ++i)
467                 req->data[i] = va_arg(list, int);
468         va_end(list);
469         if (pmu_data_len[req->data[0]][1] != 0) {
470                 req->reply[0] = ADB_RET_OK;
471                 req->reply_len = 1;
472         } else
473                 req->reply_len = 0;
474         req->reply_expected = 0;
475         return pmu_queue_request(req);
476 }
477
478 static int 
479 pmu_queue_request(struct adb_request *req)
480 {
481         unsigned long flags;
482         int nsend;
483
484         if (req->nbytes <= 0) {
485                 req->complete = 1;
486                 return 0;
487         }
488         nsend = pmu_data_len[req->data[0]][0];
489         if (nsend >= 0 && req->nbytes != nsend + 1) {
490                 req->complete = 1;
491                 return -EINVAL;
492         }
493
494         req->next = NULL;
495         req->sent = 0;
496         req->complete = 0;
497         local_irq_save(flags);
498
499         if (current_req != 0) {
500                 last_req->next = req;
501                 last_req = req;
502         } else {
503                 current_req = req;
504                 last_req = req;
505                 if (pmu_state == idle)
506                         pmu_start();
507         }
508
509         local_irq_restore(flags);
510         return 0;
511 }
512
513 static void 
514 send_byte(int x)
515 {
516         via1[ACR] |= SR_CTRL;
517         via1[SR] = x;
518         via2[B] &= ~TREQ;               /* assert TREQ */
519 }
520
521 static void 
522 recv_byte(void)
523 {
524         char c;
525
526         via1[ACR] = (via1[ACR] | SR_EXT) & ~SR_OUT;
527         c = via1[SR];           /* resets SR */
528         via2[B] &= ~TREQ;
529 }
530
531 static void 
532 pmu_start(void)
533 {
534         unsigned long flags;
535         struct adb_request *req;
536
537         /* assert pmu_state == idle */
538         /* get the packet to send */
539         local_irq_save(flags);
540         req = current_req;
541         if (req == 0 || pmu_state != idle
542             || (req->reply_expected && req_awaiting_reply))
543                 goto out;
544
545         pmu_state = sending;
546         data_index = 1;
547         data_len = pmu_data_len[req->data[0]][0];
548
549         /* set the shift register to shift out and send a byte */
550         send_byte(req->data[0]);
551
552 out:
553         local_irq_restore(flags);
554 }
555
556 void 
557 pmu_poll(void)
558 {
559         unsigned long flags;
560
561         local_irq_save(flags);
562         if (via1[IFR] & SR_INT) {
563                 via1[IFR] = SR_INT;
564                 pmu_interrupt(IRQ_MAC_ADB_SR, NULL);
565         }
566         if (via1[IFR] & CB1_INT) {
567                 via1[IFR] = CB1_INT;
568                 pmu_interrupt(IRQ_MAC_ADB_CL, NULL);
569         }
570         local_irq_restore(flags);
571 }
572
573 static irqreturn_t
574 pmu_interrupt(int irq, void *dev_id)
575 {
576         struct adb_request *req;
577         int timeout, bite = 0;  /* to prevent compiler warning */
578
579 #if 0
580         printk("pmu_interrupt: irq %d state %d acr %02X, b %02X data_index %d/%d adb_int_pending %d\n",
581                 irq, pmu_state, (uint) via1[ACR], (uint) via2[B], data_index, data_len, adb_int_pending);
582 #endif
583
584         if (irq == IRQ_MAC_ADB_CL) {            /* CB1 interrupt */
585                 adb_int_pending = 1;
586         } else if (irq == IRQ_MAC_ADB_SR) {     /* SR interrupt  */
587                 if (via2[B] & TACK) {
588                         printk(KERN_DEBUG "PMU: SR_INT but ack still high! (%x)\n", via2[B]);
589                 }
590
591                 /* if reading grab the byte */
592                 if ((via1[ACR] & SR_OUT) == 0) bite = via1[SR];
593
594                 /* reset TREQ and wait for TACK to go high */
595                 via2[B] |= TREQ;
596                 timeout = 3200;
597                 while (!(via2[B] & TACK)) {
598                         if (--timeout < 0) {
599                                 printk(KERN_ERR "PMU not responding (!ack)\n");
600                                 goto finish;
601                         }
602                         udelay(10);
603                 }
604
605                 switch (pmu_state) {
606                 case sending:
607                         req = current_req;
608                         if (data_len < 0) {
609                                 data_len = req->nbytes - 1;
610                                 send_byte(data_len);
611                                 break;
612                         }
613                         if (data_index <= data_len) {
614                                 send_byte(req->data[data_index++]);
615                                 break;
616                         }
617                         req->sent = 1;
618                         data_len = pmu_data_len[req->data[0]][1];
619                         if (data_len == 0) {
620                                 pmu_state = idle;
621                                 current_req = req->next;
622                                 if (req->reply_expected)
623                                         req_awaiting_reply = req;
624                                 else
625                                         pmu_done(req);
626                         } else {
627                                 pmu_state = reading;
628                                 data_index = 0;
629                                 reply_ptr = req->reply + req->reply_len;
630                                 recv_byte();
631                         }
632                         break;
633
634                 case intack:
635                         data_index = 0;
636                         data_len = -1;
637                         pmu_state = reading_intr;
638                         reply_ptr = interrupt_data;
639                         recv_byte();
640                         break;
641
642                 case reading:
643                 case reading_intr:
644                         if (data_len == -1) {
645                                 data_len = bite;
646                                 if (bite > 32)
647                                         printk(KERN_ERR "PMU: bad reply len %d\n",
648                                                bite);
649                         } else {
650                                 reply_ptr[data_index++] = bite;
651                         }
652                         if (data_index < data_len) {
653                                 recv_byte();
654                                 break;
655                         }
656
657                         if (pmu_state == reading_intr) {
658                                 pmu_handle_data(interrupt_data, data_index);
659                         } else {
660                                 req = current_req;
661                                 current_req = req->next;
662                                 req->reply_len += data_index;
663                                 pmu_done(req);
664                         }
665                         pmu_state = idle;
666
667                         break;
668
669                 default:
670                         printk(KERN_ERR "pmu_interrupt: unknown state %d?\n",
671                                pmu_state);
672                 }
673         }
674 finish:
675         if (pmu_state == idle) {
676                 if (adb_int_pending) {
677                         pmu_state = intack;
678                         send_byte(PMU_INT_ACK);
679                         adb_int_pending = 0;
680                 } else if (current_req) {
681                         pmu_start();
682                 }
683         }
684
685 #if 0
686         printk("pmu_interrupt: exit state %d acr %02X, b %02X data_index %d/%d adb_int_pending %d\n",
687                 pmu_state, (uint) via1[ACR], (uint) via2[B], data_index, data_len, adb_int_pending);
688 #endif
689         return IRQ_HANDLED;
690 }
691
692 static void 
693 pmu_done(struct adb_request *req)
694 {
695         req->complete = 1;
696         if (req->done)
697                 (*req->done)(req);
698 }
699
700 /* Interrupt data could be the result data from an ADB cmd */
701 static void 
702 pmu_handle_data(unsigned char *data, int len)
703 {
704         static int show_pmu_ints = 1;
705
706         asleep = 0;
707         if (len < 1) {
708                 adb_int_pending = 0;
709                 return;
710         }
711         if (data[0] & PMU_INT_ADB) {
712                 if ((data[0] & PMU_INT_ADB_AUTO) == 0) {
713                         struct adb_request *req = req_awaiting_reply;
714                         if (req == 0) {
715                                 printk(KERN_ERR "PMU: extra ADB reply\n");
716                                 return;
717                         }
718                         req_awaiting_reply = NULL;
719                         if (len <= 2)
720                                 req->reply_len = 0;
721                         else {
722                                 memcpy(req->reply, data + 1, len - 1);
723                                 req->reply_len = len - 1;
724                         }
725                         pmu_done(req);
726                 } else {
727                         adb_input(data+1, len-1, 1);
728                 }
729         } else {
730                 if (data[0] == 0x08 && len == 3) {
731                         /* sound/brightness buttons pressed */
732                         pmu_set_brightness(data[1] >> 3);
733                         set_volume(data[2]);
734                 } else if (show_pmu_ints
735                            && !(data[0] == PMU_INT_TICK && len == 1)) {
736                         int i;
737                         printk(KERN_DEBUG "pmu intr");
738                         for (i = 0; i < len; ++i)
739                                 printk(" %.2x", data[i]);
740                         printk("\n");
741                 }
742         }
743 }
744
745 int backlight_level = -1;
746 int backlight_enabled = 0;
747
748 #define LEVEL_TO_BRIGHT(lev)    ((lev) < 1? 0x7f: 0x4a - ((lev) << 1))
749
750 static void 
751 pmu_enable_backlight(int on)
752 {
753         struct adb_request req;
754
755         if (on) {
756             /* first call: get current backlight value */
757             if (backlight_level < 0) {
758                 switch(pmu_kind) {
759                     case PMU_68K_V1:
760                     case PMU_68K_V2:
761                         pmu_request(&req, NULL, 3, PMU_READ_NVRAM, 0x14, 0xe);
762                         while (!req.complete)
763                                 pmu_poll();
764                         printk(KERN_DEBUG "pmu: nvram returned bright: %d\n", (int)req.reply[1]);
765                         backlight_level = req.reply[1];
766                         break;
767                     default:
768                         backlight_enabled = 0;
769                         return;
770                 }
771             }
772             pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT,
773                 LEVEL_TO_BRIGHT(backlight_level));
774             while (!req.complete)
775                 pmu_poll();
776         }
777         pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
778             PMU_POW_BACKLIGHT | (on ? PMU_POW_ON : PMU_POW_OFF));
779         while (!req.complete)
780                 pmu_poll();
781         backlight_enabled = on;
782 }
783
784 static void 
785 pmu_set_brightness(int level)
786 {
787         int bright;
788
789         backlight_level = level;
790         bright = LEVEL_TO_BRIGHT(level);
791         if (!backlight_enabled)
792                 return;
793         if (bright_req_1.complete)
794                 pmu_request(&bright_req_1, NULL, 2, PMU_BACKLIGHT_BRIGHT,
795                     bright);
796         if (bright_req_2.complete)
797                 pmu_request(&bright_req_2, NULL, 2, PMU_POWER_CTRL,
798                     PMU_POW_BACKLIGHT | (bright < 0x7f ? PMU_POW_ON : PMU_POW_OFF));
799 }
800
801 void 
802 pmu_enable_irled(int on)
803 {
804         struct adb_request req;
805
806         pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED |
807             (on ? PMU_POW_ON : PMU_POW_OFF));
808         while (!req.complete)
809                 pmu_poll();
810 }
811
812 static void 
813 set_volume(int level)
814 {
815 }
816
817 int
818 pmu_present(void)
819 {
820         return (pmu_kind != PMU_UNKNOWN);
821 }
822
823 #if 0 /* needs some work for 68K */
824
825 /*
826  * This struct is used to store config register values for
827  * PCI devices which may get powered off when we sleep.
828  */
829 static struct pci_save {
830         u16     command;
831         u16     cache_lat;
832         u16     intr;
833 } *pbook_pci_saves;
834 static int n_pbook_pci_saves;
835
836 static inline void
837 pbook_pci_save(void)
838 {
839         int npci;
840         struct pci_dev *pd = NULL;
841         struct pci_save *ps;
842
843         npci = 0;
844         while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL)
845                 ++npci;
846         n_pbook_pci_saves = npci;
847         if (npci == 0)
848                 return;
849         ps = kmalloc(npci * sizeof(*ps), GFP_KERNEL);
850         pbook_pci_saves = ps;
851         if (ps == NULL)
852                 return;
853
854         pd = NULL;
855         while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
856                 pci_read_config_word(pd, PCI_COMMAND, &ps->command);
857                 pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
858                 pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr);
859                 ++ps;
860                 --npci;
861         }
862 }
863
864 static inline void
865 pbook_pci_restore(void)
866 {
867         u16 cmd;
868         struct pci_save *ps = pbook_pci_saves;
869         struct pci_dev *pd = NULL;
870         int j;
871
872         while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
873                 if (ps->command == 0)
874                         continue;
875                 pci_read_config_word(pd, PCI_COMMAND, &cmd);
876                 if ((ps->command & ~cmd) == 0)
877                         continue;
878                 switch (pd->hdr_type) {
879                 case PCI_HEADER_TYPE_NORMAL:
880                         for (j = 0; j < 6; ++j)
881                                 pci_write_config_dword(pd,
882                                         PCI_BASE_ADDRESS_0 + j*4,
883                                         pd->resource[j].start);
884                         pci_write_config_dword(pd, PCI_ROM_ADDRESS,
885                                pd->resource[PCI_ROM_RESOURCE].start);
886                         pci_write_config_word(pd, PCI_CACHE_LINE_SIZE,
887                                 ps->cache_lat);
888                         pci_write_config_word(pd, PCI_INTERRUPT_LINE,
889                                 ps->intr);
890                         pci_write_config_word(pd, PCI_COMMAND, ps->command);
891                         break;
892                         /* other header types not restored at present */
893                 }
894         }
895 }
896
897 /*
898  * Put the powerbook to sleep.
899  */
900 #define IRQ_ENABLE      ((unsigned int *)0xf3000024)
901 #define MEM_CTRL        ((unsigned int *)0xf8000070)
902
903 int powerbook_sleep(void)
904 {
905         int ret, i, x;
906         static int save_backlight;
907         static unsigned int save_irqen;
908         unsigned long msr;
909         unsigned int hid0;
910         unsigned long p, wait;
911         struct adb_request sleep_req;
912
913         /* Notify device drivers */
914         ret = blocking_notifier_call_chain(&sleep_notifier_list,
915                         PBOOK_SLEEP, NULL);
916         if (ret & NOTIFY_STOP_MASK)
917                 return -EBUSY;
918
919         /* Sync the disks. */
920         /* XXX It would be nice to have some way to ensure that
921          * nobody is dirtying any new buffers while we wait. */
922         sys_sync();
923
924         /* Turn off the display backlight */
925         save_backlight = backlight_enabled;
926         if (save_backlight)
927                 pmu_enable_backlight(0);
928
929         /* Give the disks a little time to actually finish writing */
930         for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
931                 mb();
932
933         /* Disable all interrupts except pmu */
934         save_irqen = in_le32(IRQ_ENABLE);
935         for (i = 0; i < 32; ++i)
936                 if (i != vias->intrs[0].line && (save_irqen & (1 << i)))
937                         disable_irq(i);
938         asm volatile("mtdec %0" : : "r" (0x7fffffff));
939
940         /* Save the state of PCI config space for some slots */
941         pbook_pci_save();
942
943         /* Set the memory controller to keep the memory refreshed
944            while we're asleep */
945         for (i = 0x403f; i >= 0x4000; --i) {
946                 out_be32(MEM_CTRL, i);
947                 do {
948                         x = (in_be32(MEM_CTRL) >> 16) & 0x3ff;
949                 } while (x == 0);
950                 if (x >= 0x100)
951                         break;
952         }
953
954         /* Ask the PMU to put us to sleep */
955         pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
956         while (!sleep_req.complete)
957                 mb();
958         /* displacement-flush the L2 cache - necessary? */
959         for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000)
960                 i = *(volatile int *)p;
961         asleep = 1;
962
963         /* Put the CPU into sleep mode */
964         asm volatile("mfspr %0,1008" : "=r" (hid0) :);
965         hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
966         asm volatile("mtspr 1008,%0" : : "r" (hid0));
967         local_save_flags(msr);
968         msr |= MSR_POW | MSR_EE;
969         local_irq_restore(msr);
970         udelay(10);
971
972         /* OK, we're awake again, start restoring things */
973         out_be32(MEM_CTRL, 0x3f);
974         pbook_pci_restore();
975
976         /* wait for the PMU interrupt sequence to complete */
977         while (asleep)
978                 mb();
979
980         /* reenable interrupts */
981         for (i = 0; i < 32; ++i)
982                 if (i != vias->intrs[0].line && (save_irqen & (1 << i)))
983                         enable_irq(i);
984
985         /* Notify drivers */
986         blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL);
987
988         /* reenable ADB autopoll */
989         pmu_adb_autopoll(adb_dev_map);
990
991         /* Turn on the screen backlight, if it was on before */
992         if (save_backlight)
993                 pmu_enable_backlight(1);
994
995         /* Wait for the hard disk to spin up */
996
997         return 0;
998 }
999
1000 /*
1001  * Support for /dev/pmu device
1002  */
1003 static int pmu_open(struct inode *inode, struct file *file)
1004 {
1005         return 0;
1006 }
1007
1008 static ssize_t pmu_read(struct file *file, char *buf,
1009                         size_t count, loff_t *ppos)
1010 {
1011         return 0;
1012 }
1013
1014 static ssize_t pmu_write(struct file *file, const char *buf,
1015                          size_t count, loff_t *ppos)
1016 {
1017         return 0;
1018 }
1019
1020 static int pmu_ioctl(struct inode * inode, struct file *filp,
1021                      u_int cmd, u_long arg)
1022 {
1023         int error;
1024         __u32 value;
1025
1026         switch (cmd) {
1027             case PMU_IOC_SLEEP:
1028                 return -ENOSYS;
1029             case PMU_IOC_GET_BACKLIGHT:
1030                 return put_user(backlight_level, (__u32 *)arg);
1031             case PMU_IOC_SET_BACKLIGHT:
1032                 error = get_user(value, (__u32 *)arg);
1033                 if (!error)
1034                         pmu_set_brightness(value);
1035                 return error;
1036             case PMU_IOC_GET_MODEL:
1037                 return put_user(pmu_kind, (__u32 *)arg);
1038         }
1039         return -EINVAL;
1040 }
1041
1042 static const struct file_operations pmu_device_fops = {
1043         .read           = pmu_read,
1044         .write          = pmu_write,
1045         .ioctl          = pmu_ioctl,
1046         .open           = pmu_open,
1047 };
1048
1049 static struct miscdevice pmu_device = {
1050         PMU_MINOR, "pmu", &pmu_device_fops
1051 };
1052
1053 void pmu_device_init(void)
1054 {
1055         if (!via)
1056                 return;
1057         if (misc_register(&pmu_device) < 0)
1058                 printk(KERN_ERR "via-pmu68k: cannot register misc device.\n");
1059 }
1060 #endif /* CONFIG_PMAC_PBOOK */
1061