patch-2.1.79 linux/drivers/macintosh/via-cuda.c
Next file: linux/drivers/net/3c59x.c
Previous file: linux/drivers/macintosh/valkyrie.c
Back to the patch index
Back to the overall index
- Lines: 237
- Date:
Mon Jan 12 15:18:14 1998
- Orig file:
v2.1.78/linux/drivers/macintosh/via-cuda.c
- Orig date:
Mon Aug 18 18:19:46 1997
diff -u --recursive --new-file v2.1.78/linux/drivers/macintosh/via-cuda.c linux/drivers/macintosh/via-cuda.c
@@ -6,9 +6,6 @@
* Bus) which connects to the keyboard and mouse. The CUDA also
* controls system power and the RTC (real time clock) chip.
*
- * This file also contains routines to support access to ADB
- * devices via the /dev/adb interface.
- *
* Copyright (C) 1996 Paul Mackerras.
*/
#include <stdarg.h>
@@ -18,6 +15,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <asm/prom.h>
+#include <asm/adb.h>
#include <asm/cuda.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -58,10 +56,6 @@
#define IER_CLR 0 /* clear bits in IER */
#define SR_INT 0x04 /* Shift register full/empty */
-static struct adb_handler {
- void (*handler)(unsigned char *, int, struct pt_regs *);
-} adb_handler[16];
-
static enum cuda_state {
idle,
sent_first_byte,
@@ -71,8 +65,8 @@
awaiting_reply
} cuda_state;
-static struct cuda_request *current_req;
-static struct cuda_request *last_req;
+static struct adb_request *current_req;
+static struct adb_request *last_req;
static unsigned char cuda_rbuf[16];
static unsigned char *reply_ptr;
static int reading_reply;
@@ -82,6 +76,8 @@
static void cuda_start(void);
static void via_interrupt(int irq, void *arg, struct pt_regs *regs);
static void cuda_input(unsigned char *buf, int nb, struct pt_regs *regs);
+static int cuda_adb_send_request(struct adb_request *req, int sync);
+static int cuda_adb_autopoll(int on);
void
via_cuda_init()
@@ -89,15 +85,10 @@
struct device_node *vias;
vias = find_devices("via-cuda");
- if (vias == 0) {
- printk(KERN_WARNING "Warning: no via-cuda\n");
- vias = find_devices("via-pmu");
- if (vias == 0)
- return;
- printk(KERN_WARNING "Found via-pmu, using it as via-cuda\n");
- }
+ if (vias == 0)
+ return;
if (vias->next != 0)
- printk("Warning: only using 1st via-cuda\n");
+ printk(KERN_WARNING "Warning: only using 1st via-cuda\n");
#if 0
{ int i;
@@ -111,21 +102,34 @@
printk("\n"); }
#endif
- if (vias->n_addrs != 1 || vias->n_intrs != 1)
- panic("via-cuda: expecting 1 address and 1 interrupt");
+ if (vias->n_addrs != 1 || vias->n_intrs != 1) {
+ printk(KERN_ERR "via-cuda: expecting 1 address (%d) and 1 interrupt (%d)\n",
+ vias->n_addrs, vias->n_intrs);
+ if (vias->n_addrs < 1 || vias->n_intrs < 1)
+ return;
+ }
via = (volatile unsigned char *) vias->addrs->address;
- if (!init_via())
- panic("init_via failed");
+ if (!init_via()) {
+ printk(KERN_ERR "init_via failed\n");
+ return;
+ }
cuda_state = idle;
- if (request_irq(vias->intrs[0], via_interrupt, 0, "VIA", (void *)0))
- panic("VIA: can't get irq %d\n", vias->intrs[0]);
+ if (request_irq(vias->intrs[0], via_interrupt, 0, "VIA", (void *)0)) {
+ printk(KERN_ERR "VIA: can't get irq %d\n", vias->intrs[0]);
+ return;
+ }
/* Clear and enable interrupts */
via[IFR] = 0x7f; eieio(); /* clear interrupts by writing 1s */
via[IER] = IER_SET|SR_INT; eieio(); /* enable interrupt from SR */
+
+ /* Set function pointers */
+ adb_hardware = ADB_VIACUDA;
+ adb_send_request = cuda_adb_send_request;
+ adb_autopoll = cuda_adb_autopoll;
}
#define WAIT_FOR(cond, what) \
@@ -178,9 +182,42 @@
return 1;
}
+/* Send an ADB command */
+static int
+cuda_adb_send_request(struct adb_request *req, int sync)
+{
+ int i;
+
+ for (i = req->nbytes; i > 0; --i)
+ req->data[i] = req->data[i-1];
+ req->data[0] = ADB_PACKET;
+ ++req->nbytes;
+ req->reply_expected = 1;
+ i = cuda_send_request(req);
+ if (i)
+ return i;
+ if (sync) {
+ while (!req->complete)
+ cuda_poll();
+ }
+ return 0;
+}
+
+/* Enable/disable autopolling */
+static int
+cuda_adb_autopoll(int on)
+{
+ struct adb_request req;
+
+ cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, on);
+ while (!req.complete)
+ cuda_poll();
+ return 0;
+}
+
/* Construct and send a cuda request */
int
-cuda_request(struct cuda_request *req, void (*done)(struct cuda_request *),
+cuda_request(struct adb_request *req, void (*done)(struct adb_request *),
int nbytes, ...)
{
va_list list;
@@ -197,13 +234,13 @@
}
int
-cuda_send_request(struct cuda_request *req)
+cuda_send_request(struct adb_request *req)
{
unsigned long flags;
req->next = 0;
req->sent = 0;
- req->got_reply = 0;
+ req->complete = 0;
req->reply_len = 0;
save_flags(flags); cli();
@@ -225,7 +262,7 @@
cuda_start()
{
unsigned long flags;
- struct cuda_request *req;
+ struct adb_request *req;
/* assert cuda_state == idle */
/* get the packet to send */
@@ -261,7 +298,7 @@
via_interrupt(int irq, void *arg, struct pt_regs *regs)
{
int x, status;
- struct cuda_request *req;
+ struct adb_request *req;
if ((via[IFR] & SR_INT) == 0)
return;
@@ -351,7 +388,7 @@
if (reading_reply) {
req = current_req;
req->reply_len = reply_ptr - req->reply;
- req->got_reply = 1;
+ req->complete = 1;
current_req = req->next;
if (req->done)
(*req->done)(req);
@@ -377,21 +414,11 @@
static void
cuda_input(unsigned char *buf, int nb, struct pt_regs *regs)
{
- int i, id;
- static int dump_cuda_input = 0;
+ int i;
switch (buf[0]) {
case ADB_PACKET:
- id = buf[2] >> 4;
- if (dump_cuda_input) {
- printk(KERN_INFO "adb packet: ");
- for (i = 0; i < nb; ++i)
- printk(" %x", buf[i]);
- printk(", id = %d\n", id);
- }
- if (adb_handler[id].handler != 0) {
- (*adb_handler[id].handler)(buf, nb, regs);
- }
+ adb_input(buf+2, nb-2, regs, buf[1] & 0x40);
break;
default:
@@ -400,16 +427,4 @@
printk(" %.2x", buf[i]);
printk("\n");
}
-}
-
-/* Ultimately this should return the number of devices with
- the given default id. */
-int
-adb_register(int default_id,
- void (*handler)(unsigned char *, int, struct pt_regs *))
-{
- if (adb_handler[default_id].handler != 0)
- panic("Two handlers for ADB device %d\n", default_id);
- adb_handler[default_id].handler = handler;
- return 1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov