Example #1
0
/* All specifically VIA-related initialization goes here */
static int
maciisi_init_via(void)
{
	/* Set the lines up. We want TREQ as input TACK|TIP as output */
	via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
	/* Shift register on input */
	via[ACR]  = (via[ACR] & ~SR_CTRL) | SR_EXT;
	printk(KERN_DEBUG "maciisi_init_via: initial status %x\n", via[B] & (TIP|TREQ));
	/* Set initial state: idle */
	via[B] &= ~(TACK|TIP);
	/* Wipe any pending data and int */
	via[SR];
	if (!(via[B] & TREQ))
		maciisi_stfu();
	via[IER] = IER_SET | SR_INT;
	maciisi_state = idle;
	return 0;
}
Example #2
0
/* All specifically VIA-related initialization goes here */
static int
maciisi_init_via(void)
{
    int    i;
    
    /* Set the lines up. We want TREQ as input TACK|TIP as output */
    via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
    /* Shift register on input */
    via[ACR]  = (via[ACR] & ~SR_CTRL) | SR_EXT;
#ifdef DEBUG_MACIISI_ADB
    printk(KERN_DEBUG "maciisi_init_via: initial status %x\n", via[B] & (TIP|TREQ));
#endif
    /* Wipe any pending data and int */
    tmp = via[SR];
    /* Enable keyboard interrupts */
    via[IER] = IER_SET | SR_INT;
    /* Set initial state: idle */
    via[B] &= ~(TACK|TIP);
    /* Clear interrupt bit */
    via[IFR] = SR_INT;

    for(i = 0; i < 60; i++) {
        udelay(ADB_DELAY);
        maciisi_stfu();
        udelay(ADB_DELAY);
        if(via[B] & TREQ)
            break;
    }
    if (i == 60)
        printk(KERN_ERR "maciisi_init_via: bus jam?\n");

    maciisi_state = idle;
    need_sync = 0;

    return 0;
}
static int
maciisi_init_via(void)
{
	int	i;
	
	
	via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
	
	via[ACR]  = (via[ACR] & ~SR_CTRL) | SR_EXT;
#ifdef DEBUG_MACIISI_ADB
	printk(KERN_DEBUG "maciisi_init_via: initial status %x\n", via[B] & (TIP|TREQ));
#endif
	
	tmp = via[SR];
	
	via[IER] = IER_SET | SR_INT;
	
	via[B] &= ~(TACK|TIP);
	
	via[IFR] = SR_INT;

	for(i = 0; i < 60; i++) {
		udelay(ADB_DELAY);
		maciisi_stfu();
		udelay(ADB_DELAY);
		if(via[B] & TREQ)
			break;
	}
	if (i == 60)
		printk(KERN_ERR "maciisi_init_via: bus jam?\n");

	maciisi_state = idle;
	need_sync = 0;

	return 0;
}
Example #4
0
/* Shift register interrupt - this is *supposed* to mean that the
   register is either full or empty. In practice, I have no idea what
   it means :( */
static void
maciisi_interrupt(int irq, void* arg, struct pt_regs* regs)
{
	int status;
	struct adb_request *req;
	static int dump_reply = 1;

	if (!(via[IFR] & SR_INT)) {
		/* Shouldn't happen, we hope */
		printk(KERN_DEBUG "maciisi_interrupt: called without interrupt flag set\n");
		return;
	}

	status = via[B] & (TIP|TREQ);
	printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);

 switch_start:
	switch (maciisi_state) {
	case idle:
		printk(KERN_DEBUG "maciisi_interrupt: state=idle, status %x\n", status);
		if (status & TIP)
			printk(KERN_DEBUG "maciisi_interrupt: state is idle but TIP asserted!\n");

		udelay(ADB_DELAY);
		/* Shift in */
		via[ACR] &= ~SR_OUT;
 		/* Signal start of frame */
		via[B] |= TIP;
		/* Clear the interrupt (throw this value on the floor, it's useless) */
		via[SR];
		/* ACK adb chip, high-low */
		via[B] |= TACK;
		udelay(ADB_DELAY);
		via[B] &= ~TACK;
		reply_len = 0;
		maciisi_state = reading;
		if (reading_reply) {
			reply_ptr = current_req->reply;
		} else {
			printk(KERN_DEBUG "maciisi_interrupt: received unsolicited packet\n");
			reply_ptr = maciisi_rbuf;
		}
		break;

	case sending:
		printk(KERN_DEBUG "maciisi_interrupt: state=sending, status=%x\n", status);
		/* Clear interrupt */
		via[SR];
		/* Set ACK off */
		via[B] &= ~TACK;
		req = current_req;

		if (!(status & TREQ)) {
			/* collision */
			printk(KERN_DEBUG "maciisi_interrupt: send collision\n");
			/* Set idle and input */
			via[B] &= ~TIP;
			via[ACR] &= ~SR_OUT;
			/* Must re-send */
			reading_reply = 0;
			reply_len = 0;
			maciisi_state = idle;
			/* process this now, because the IFR has been cleared */
			goto switch_start;
		}

		if (data_index >= req->nbytes) {
			/* Sent the whole packet, put the bus back in idle state */
			/* Shift in, we are about to read a reply (hopefully) */
			via[ACR] &= ~SR_OUT;
			/* End of frame */
			via[B] &= ~TIP;
			req->sent = 1;
			maciisi_state = idle;
			if (req->reply_expected) {
				/* Note: only set this once we've
                                   successfully sent the packet */
				reading_reply = 1;
			} else {
				current_req = req->next;
				if (req->done)
					(*req->done)(req);
			}
		} else {
			/* Sending more stuff */
			/* Shift out */
			via[ACR] |= SR_OUT;
			/* Delay */
			udelay(ADB_DELAY);
			/* Write */
			via[SR] = req->data[data_index++];
			/* Signal 'byte ready' */
			via[B] |= TACK;
		}
		break;

	case reading:
		printk(KERN_DEBUG "maciisi_interrupt: state=reading, status=%x\n", status);
		/* Shift in */
		via[ACR] &= ~SR_OUT;
		if (reply_len++ > 16) {
			printk(KERN_ERR "maciisi_interrupt: reply too long, aborting read\n");
			via[B] |= TACK;
			udelay(ADB_DELAY);
			via[B] &= ~(TACK|TIP);
			maciisi_state = idle;
			maciisi_start();
			break;
		}
		*reply_ptr++ = via[SR];
		status = via[B] & (TIP|TREQ);
		/* ACK on/off */
		via[B] |= TACK;
		udelay(ADB_DELAY);
		via[B] &= ~TACK;	
		if (!(status & TREQ))
			break; /* more stuff to deal with */
		
		/* end of frame */
		via[B] &= ~TIP;

		/* end of packet, deal with it */
		if (reading_reply) {
			req = current_req;
			req->reply_len = reply_ptr - req->reply;
			if (req->data[0] == ADB_PACKET) {
				/* Have to adjust the reply from ADB commands */
				if (req->reply_len <= 2 || (req->reply[1] & 2) != 0) {
					/* the 0x2 bit indicates no response */
					req->reply_len = 0;
				} else {
					/* leave just the command and result bytes in the reply */
					req->reply_len -= 2;
					memmove(req->reply, req->reply + 2, req->reply_len);
				}
			}
			if (dump_reply) {
				int i;
				printk(KERN_DEBUG "maciisi_interrupt: reply is ");
				for (i = 0; i < req->reply_len; ++i)
					printk(" %.2x", req->reply[i]);
				printk("\n");
			}
			req->complete = 1;
			current_req = req->next;
			if (req->done)
				(*req->done)(req);
			/* Obviously, we got it */
			reading_reply = 0;
		} else {
			maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf, regs);
		}
		maciisi_state = idle;
		status = via[B] & (TIP|TREQ);
		if (!(status & TREQ)) {
			/* Timeout?! */
			printk(KERN_DEBUG "extra data after packet: status %x ifr %x\n",
			       status, via[IFR]);
			maciisi_stfu();
		}
		/* Do any queued requests now if possible */
		maciisi_start();
		break;

	default:
		printk("maciisi_interrupt: unknown maciisi_state %d?\n", maciisi_state);
	}
}