OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [macintosh/] [via-pmu68k.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.