⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 via-cuda.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Device driver for the via-cuda on Apple Powermacs. * * The VIA (versatile interface adapter) interfaces to the CUDA, * a 6805 microprocessor core which controls the ADB (Apple Desktop * Bus) which connects to the keyboard and mouse.  The CUDA also * controls system power and the RTC (real time clock) chip. * * Copyright (C) 1996 Paul Mackerras. */#include <stdarg.h>#include <linux/config.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/sched.h>#include <linux/adb.h>#include <linux/cuda.h>#include <linux/spinlock.h>#include <linux/interrupt.h>#ifdef CONFIG_PPC#include <asm/prom.h>#include <asm/machdep.h>#else#include <asm/macintosh.h>#include <asm/macints.h>#include <asm/machw.h>#include <asm/mac_via.h>#endif#include <asm/io.h>#include <asm/system.h>#include <linux/init.h>static volatile unsigned char *via;static spinlock_t cuda_lock = SPIN_LOCK_UNLOCKED;#ifdef CONFIG_MAC#define CUDA_IRQ IRQ_MAC_ADB#define __openfirmware#define eieio()#else#define CUDA_IRQ vias->intrs[0].line#endif/* VIA registers - spaced 0x200 bytes apart */#define RS		0x200		/* skip between registers */#define B		0		/* B-side data */#define A		RS		/* A-side data */#define DIRB		(2*RS)		/* B-side direction (1=output) */#define DIRA		(3*RS)		/* A-side direction (1=output) */#define T1CL		(4*RS)		/* Timer 1 ctr/latch (low 8 bits) */#define T1CH		(5*RS)		/* Timer 1 counter (high 8 bits) */#define T1LL		(6*RS)		/* Timer 1 latch (low 8 bits) */#define T1LH		(7*RS)		/* Timer 1 latch (high 8 bits) */#define T2CL		(8*RS)		/* Timer 2 ctr/latch (low 8 bits) */#define T2CH		(9*RS)		/* Timer 2 counter (high 8 bits) */#define SR		(10*RS)		/* Shift register */#define ACR		(11*RS)		/* Auxiliary control register */#define PCR		(12*RS)		/* Peripheral control register */#define IFR		(13*RS)		/* Interrupt flag register */#define IER		(14*RS)		/* Interrupt enable register */#define ANH		(15*RS)		/* A-side data, no handshake *//* Bits in B data register: all active low */#define TREQ		0x08		/* Transfer request (input) */#define TACK		0x10		/* Transfer acknowledge (output) */#define TIP		0x20		/* Transfer in progress (output) *//* Bits in ACR */#define SR_CTRL		0x1c		/* Shift register control bits */#define SR_EXT		0x0c		/* Shift on external clock */#define SR_OUT		0x10		/* Shift out if 1 *//* Bits in IFR and IER */#define IER_SET		0x80		/* set bits in IER */#define IER_CLR		0		/* clear bits in IER */#define SR_INT		0x04		/* Shift register full/empty */static enum cuda_state {    idle,    sent_first_byte,    sending,    reading,    read_done,    awaiting_reply} cuda_state;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;static int data_index;#ifdef CONFIG_PPCstatic struct device_node *vias;#endifstatic int cuda_fully_inited = 0;#ifdef CONFIG_ADBstatic int cuda_probe(void);static int cuda_init(void);static int cuda_send_request(struct adb_request *req, int sync);static int cuda_adb_autopoll(int devs);static int cuda_reset_adb_bus(void);#endif /* CONFIG_ADB */static int cuda_init_via(void);static void cuda_start(void);static irqreturn_t cuda_interrupt(int irq, void *arg, struct pt_regs *regs);static void cuda_input(unsigned char *buf, int nb, struct pt_regs *regs);void cuda_poll(void);static int cuda_write(struct adb_request *req);int cuda_request(struct adb_request *req,		 void (*done)(struct adb_request *), int nbytes, ...);#ifdef CONFIG_ADBstruct adb_driver via_cuda_driver = {	"CUDA",	cuda_probe,	cuda_init,	cuda_send_request,	cuda_adb_autopoll,	cuda_poll,	cuda_reset_adb_bus};#endif /* CONFIG_ADB */#ifdef CONFIG_PPCint __initfind_via_cuda(void){    int err;    struct adb_request req;    if (vias != 0)	return 1;    vias = find_devices("via-cuda");    if (vias == 0)	return 0;    if (vias->next != 0)	printk(KERN_WARNING "Warning: only using 1st via-cuda\n");#if 0    { int i;    printk("find_via_cuda: node = %p, addrs =", vias->node);    for (i = 0; i < vias->n_addrs; ++i)	printk(" %x(%x)", vias->addrs[i].address, vias->addrs[i].size);    printk(", intrs =");    for (i = 0; i < vias->n_intrs; ++i)	printk(" %x", vias->intrs[i].line);    printk("\n"); }#endif    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 0;    }    via = (volatile unsigned char *) ioremap(vias->addrs->address, 0x2000);    cuda_state = idle;    sys_ctrler = SYS_CTRLER_CUDA;    err = cuda_init_via();    if (err) {	printk(KERN_ERR "cuda_init_via() failed\n");	via = NULL;	return 0;    }    /* Clear and enable interrupts, but only on PPC. On 68K it's done  */    /* for us by the main VIA driver in arch/m68k/mac/via.c        */#ifndef CONFIG_MAC    out_8(&via[IFR], 0x7f);	/* clear interrupts by writing 1s */    out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */#endif    /* enable autopoll */    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);    while (!req.complete)	cuda_poll();    return 1;}#endif /* CONFIG_PPC */static int __init via_cuda_start(void){    if (via == NULL)	return -ENODEV;#ifdef CONFIG_PPC    request_OF_resource(vias, 0, NULL);#endif    if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) {	printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ);	return -EAGAIN;    }    printk("Macintosh CUDA driver v0.5 for Unified ADB.\n");    cuda_fully_inited = 1;    return 0;}device_initcall(via_cuda_start);#ifdef CONFIG_ADBstatic intcuda_probe(void){#ifdef CONFIG_PPC    if (sys_ctrler != SYS_CTRLER_CUDA)	return -ENODEV;#else    if (macintosh_config->adb_type != MAC_ADB_CUDA)	return -ENODEV;    via = via1;#endif    return 0;}static int __initcuda_init(void){#ifdef CONFIG_PPC    if (via == NULL)	return -ENODEV;    return 0;#else     int err = cuda_init_via();    if (err) {	printk(KERN_ERR "cuda_init_via() failed\n");	return -ENODEV;    }    return via_cuda_start();#endif}#endif /* CONFIG_ADB */#define WAIT_FOR(cond, what)					\    do {                                                        \    	int x;							\	for (x = 1000; !(cond); --x) {				\	    if (x == 0) {					\		printk("Timeout waiting for " what "\n");	\		return -ENXIO;					\	    }							\	    udelay(100);					\	}							\    } while (0)static intcuda_init_via(void){    out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ);	/* TACK & TIP out */    out_8(&via[B], in_8(&via[B]) | TACK | TIP);			/* negate them */    out_8(&via[ACR] ,(in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT);	/* SR data in */    (void)in_8(&via[SR]);						/* clear any left-over data */#ifndef CONFIG_MAC    out_8(&via[IER], 0x7f);					/* disable interrupts from VIA */    (void)in_8(&via[IER]);#endif    /* delay 4ms and then clear any pending interrupt */    mdelay(4);    (void)in_8(&via[SR]);    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);    /* sync with the CUDA - assert TACK without TIP */    out_8(&via[B], in_8(&via[B]) & ~TACK);    /* wait for the CUDA to assert TREQ in response */    WAIT_FOR((in_8(&via[B]) & TREQ) == 0, "CUDA response to sync");    /* wait for the interrupt and then clear it */    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)");    (void)in_8(&via[SR]);    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);    /* finish the sync by negating TACK */    out_8(&via[B], in_8(&via[B]) | TACK);    /* wait for the CUDA to negate TREQ and the corresponding interrupt */    WAIT_FOR(in_8(&via[B]) & TREQ, "CUDA response to sync (3)");    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)");    (void)in_8(&via[SR]);    out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);    out_8(&via[B], in_8(&via[B]) | TIP);	/* should be unnecessary */    return 0;}#ifdef CONFIG_ADB/* Send an ADB command */static intcuda_send_request(struct adb_request *req, int sync){    int i;    if ((via == NULL) || !cuda_fully_inited) {	req->complete = 1;	return -ENXIO;    }      req->reply_expected = 1;    i = cuda_write(req);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -