~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/macintosh/via-pmu68k.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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/sched.h>
 26 #include <linux/miscdevice.h>
 27 #include <linux/blkdev.h>
 28 #include <linux/pci.h>
 29 #include <linux/malloc.h>
 30 #include <linux/init.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 = 0;
 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 = 0;
102 
103 int asleep;
104 struct notifier_block *sleep_notifier_list;
105 
106 static int pmu_probe(void);
107 static int pmu_init(void);
108 static void pmu_start(void);
109 static void pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
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                             struct pt_regs *regs);
122 static void set_volume(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()
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, 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 static 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 = 0;
494         req->sent = 0;
495         req->complete = 0;
496         save_flags(flags); cli();
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         restore_flags(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()
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()
532 {
533         unsigned long flags;
534         struct adb_request *req;
535 
536         /* assert pmu_state == idle */
537         /* get the packet to send */
538         save_flags(flags); cli();
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         restore_flags(flags);
553 }
554 
555 void 
556 pmu_poll()
557 {
558         unsigned long cpu_flags;
559 
560         save_flags(cpu_flags);
561         cli();
562         if (via1[IFR] & SR_INT) {
563                 via1[IFR] = SR_INT;
564                 pmu_interrupt(IRQ_MAC_ADB_SR, NULL, NULL);
565         }
566         if (via1[IFR] & CB1_INT) {
567                 via1[IFR] = CB1_INT;
568                 pmu_interrupt(IRQ_MAC_ADB_CL, NULL, NULL);
569         }
570         restore_flags(cpu_flags);
571 }
572 
573 static void 
574 pmu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
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, regs);
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 }
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, struct pt_regs *regs)
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 = 0;
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, regs, 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 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 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 }
821 
822 #if 0 /* needs some work for 68K */
823 
824 /*
825  * This struct is used to store config register values for
826  * PCI devices which may get powered off when we sleep.
827  */
828 static struct pci_save {
829         u16     command;
830         u16     cache_lat;
831         u16     intr;
832 } *pbook_pci_saves;
833 static int n_pbook_pci_saves;
834 
835 static inline void __openfirmware
836 pbook_pci_save(void)
837 {
838         int npci;
839         struct pci_dev *pd;
840         struct pci_save *ps;
841 
842         npci = 0;
843         for (pd = pci_devices; pd != NULL; pd = pd->next)
844                 ++npci;
845         n_pbook_pci_saves = npci;
846         if (npci == 0)
847                 return;
848         ps = (struct pci_save *) kmalloc(npci * sizeof(*ps), GFP_KERNEL);
849         pbook_pci_saves = ps;
850         if (ps == NULL)
851                 return;
852 
853         for (pd = pci_devices; pd != NULL && npci != 0; pd = pd->next) {
854                 pci_read_config_word(pd, PCI_COMMAND, &ps->command);
855                 pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
856                 pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr);
857                 ++ps;
858                 --npci;
859         }
860 }
861 
862 static inline void __openfirmware
863 pbook_pci_restore(void)
864 {
865         u16 cmd;
866         struct pci_save *ps = pbook_pci_saves;
867         struct pci_dev *pd;
868         int j;
869 
870         for (pd = pci_devices; pd != NULL; pd = pd->next, ++ps) {
871                 if (ps->command == 0)
872                         continue;
873                 pci_read_config_word(pd, PCI_COMMAND, &cmd);
874                 if ((ps->command & ~cmd) == 0)
875                         continue;
876                 switch (pd->hdr_type) {
877                 case PCI_HEADER_TYPE_NORMAL:
878                         for (j = 0; j < 6; ++j)
879                                 pci_write_config_dword(pd,
880                                         PCI_BASE_ADDRESS_0 + j*4,
881                                         pd->resource[j].start);
882                         pci_write_config_dword(pd, PCI_ROM_ADDRESS,
883                                pd->resource[PCI_ROM_RESOURCE].start);
884                         pci_write_config_word(pd, PCI_CACHE_LINE_SIZE,
885                                 ps->cache_lat);
886                         pci_write_config_word(pd, PCI_INTERRUPT_LINE,
887                                 ps->intr);
888                         pci_write_config_word(pd, PCI_COMMAND, ps->command);
889                         break;
890                         /* other header types not restored at present */
891                 }
892         }
893 }
894 
895 /*
896  * Put the powerbook to sleep.
897  */
898 #define IRQ_ENABLE      ((unsigned int *)0xf3000024)
899 #define MEM_CTRL        ((unsigned int *)0xf8000070)
900 
901 int __openfirmware powerbook_sleep(void)
902 {
903         int ret, i, x;
904         static int save_backlight;
905         static unsigned int save_irqen;
906         unsigned long msr;
907         unsigned int hid0;
908         unsigned long p, wait;
909         struct adb_request sleep_req;
910 
911         /* Notify device drivers */
912         ret = notifier_call_chain(&sleep_notifier_list, PBOOK_SLEEP, NULL);
913         if (ret & NOTIFY_STOP_MASK)
914                 return -EBUSY;
915 
916         /* Sync the disks. */
917         /* XXX It would be nice to have some way to ensure that
918          * nobody is dirtying any new buffers while we wait. */
919         fsync_dev(0);
920 
921         /* Turn off the display backlight */
922         save_backlight = backlight_enabled;
923         if (save_backlight)
924                 pmu_enable_backlight(0);
925 
926         /* Give the disks a little time to actually finish writing */
927         for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
928                 mb();
929 
930         /* Disable all interrupts except pmu */
931         save_irqen = in_le32(IRQ_ENABLE);
932         for (i = 0; i < 32; ++i)
933                 if (i != vias->intrs[0].line && (save_irqen & (1 << i)))
934                         disable_irq(i);
935         asm volatile("mtdec %0" : : "r" (0x7fffffff));
936 
937         /* Save the state of PCI config space for some slots */
938         pbook_pci_save();
939 
940         /* Set the memory controller to keep the memory refreshed
941            while we're asleep */
942         for (i = 0x403f; i >= 0x4000; --i) {
943                 out_be32(MEM_CTRL, i);
944                 do {
945                         x = (in_be32(MEM_CTRL) >> 16) & 0x3ff;
946                 } while (x == 0);
947                 if (x >= 0x100)
948                         break;
949         }
950 
951         /* Ask the PMU to put us to sleep */
952         pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
953         while (!sleep_req.complete)
954                 mb();
955         /* displacement-flush the L2 cache - necessary? */
956         for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000)
957                 i = *(volatile int *)p;
958         asleep = 1;
959 
960         /* Put the CPU into sleep mode */
961         asm volatile("mfspr %0,1008" : "=r" (hid0) :);
962         hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
963         asm volatile("mtspr 1008,%0" : : "r" (hid0));
964         save_flags(msr);
965         msr |= MSR_POW | MSR_EE;
966         restore_flags(msr);
967         udelay(10);
968 
969         /* OK, we're awake again, start restoring things */
970         out_be32(MEM_CTRL, 0x3f);
971         pbook_pci_restore();
972 
973         /* wait for the PMU interrupt sequence to complete */
974         while (asleep)
975                 mb();
976 
977         /* reenable interrupts */
978         for (i = 0; i < 32; ++i)
979                 if (i != vias->intrs[0].line && (save_irqen & (1 << i)))
980                         enable_irq(i);
981 
982         /* Notify drivers */
983         notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL);
984 
985         /* reenable ADB autopoll */
986         pmu_adb_autopoll(adb_dev_map);
987 
988         /* Turn on the screen backlight, if it was on before */
989         if (save_backlight)
990                 pmu_enable_backlight(1);
991 
992         /* Wait for the hard disk to spin up */
993 
994         return 0;
995 }
996 
997 /*
998  * Support for /dev/pmu device
999  */
1000 static int __openfirmware pmu_open(struct inode *inode, struct file *file)
1001 {
1002         return 0;
1003 }
1004 
1005 static ssize_t __openfirmware pmu_read(struct file *file, char *buf,
1006                         size_t count, loff_t *ppos)
1007 {
1008         return 0;
1009 }
1010 
1011 static ssize_t __openfirmware pmu_write(struct file *file, const char *buf,
1012                          size_t count, loff_t *ppos)
1013 {
1014         return 0;
1015 }
1016 
1017 /* Note: removed __openfirmware here since it causes link errors */
1018 static int /*__openfirmware*/ pmu_ioctl(struct inode * inode, struct file *filp,
1019                      u_int cmd, u_long arg)
1020 {
1021         int error;
1022         __u32 value;
1023 
1024         switch (cmd) {
1025             case PMU_IOC_SLEEP:
1026                 return -ENOSYS;
1027             case PMU_IOC_GET_BACKLIGHT:
1028                 return put_user(backlight_level, (__u32 *)arg);
1029             case PMU_IOC_SET_BACKLIGHT:
1030                 error = get_user(value, (__u32 *)arg);
1031                 if (!error)
1032                         pmu_set_brightness(value);
1033                 return error;
1034             case PMU_IOC_GET_MODEL:
1035                 return put_user(pmu_kind, (__u32 *)arg);
1036         }
1037         return -EINVAL;
1038 }
1039 
1040 static struct file_operations pmu_device_fops = {
1041         read:           pmu_read,
1042         write:          pmu_write,
1043         ioctl:          pmu_ioctl,
1044         open:           pmu_open,
1045 };
1046 
1047 static struct miscdevice pmu_device = {
1048         PMU_MINOR, "pmu", &pmu_device_fops
1049 };
1050 
1051 void pmu_device_init(void)
1052 {
1053         if (via)
1054                 misc_register(&pmu_device);
1055 }
1056 #endif /* CONFIG_PMAC_PBOOK */
1057 
1058 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.