示例#1
0
/* Reset adb bus - how do we do this?? */
static int
cuda_reset_adb_bus(void)
{
    struct adb_request req;

    if ((via == NULL) || !cuda_fully_inited)
	return -ENXIO;

    cuda_request(&req, NULL, 2, ADB_PACKET, 0);		/* maybe? */
    while (!req.complete)
	cuda_poll();
    return 0;
}
示例#2
0
/* Enable/disable autopolling */
static int
cuda_adb_autopoll(int devs)
{
    struct adb_request req;

    if ((via == NULL) || !cuda_fully_inited)
	return -ENXIO;

    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, (devs? 1: 0));
    while (!req.complete)
	cuda_poll();
    return 0;
}
示例#3
0
static int
cuda_adb_send(void *cookie, int poll, int command, int len, uint8_t *data)
{
	struct cuda_softc *sc = cookie;
	int i, s = 0;
	uint8_t packet[16];

	/* construct an ADB command packet and send it */
	packet[0] = CUDA_ADB;
	packet[1] = command;
	for (i = 0; i < len; i++)
		packet[i + 2] = data[i];
	if (poll || cold) {
		s = splhigh();
		cuda_poll(sc);
	}
	cuda_send(sc, poll, len + 2, packet);
	if (poll || cold) {
		cuda_poll(sc);
		splx(s);
	}
	return 0;
}
示例#4
0
static int
cuda_send(void *cookie, int poll, int length, uint8_t *msg)
{
	struct cuda_softc *sc = cookie;
	int s;

	DPRINTF("cuda_send %08x\n", (uint32_t)cookie);
	if (sc->sc_state == CUDA_NOTREADY)
		return -1;

	s = splhigh();

	if ((sc->sc_state == CUDA_IDLE) /*&& 
	    ((cuda_read_reg(sc, vBufB) & vPB3) == vPB3)*/) {
		/* fine */
		DPRINTF("chip is idle\n");
	} else {
		DPRINTF("cuda state is %d\n", sc->sc_state);
		if (sc->sc_waiting == 0) {
			sc->sc_waiting = 1;
		} else {
			splx(s);
			return -1;
		}
	}

	sc->sc_error = 0;
	memcpy(sc->sc_out, msg, length);
	sc->sc_out_length = length;
	sc->sc_sent = 0;

	if (sc->sc_waiting != 1) {

		delay(150);
		sc->sc_state = CUDA_OUT;
		cuda_out(sc);
		cuda_write_reg(sc, vSR, sc->sc_out[0]);
		cuda_ack_off(sc);
		cuda_tip(sc);
	}
	sc->sc_waiting = 1;

	if (sc->sc_polling || poll || cold) {
		cuda_poll(sc);
	}

	splx(s);

	return 0;
}
示例#5
0
static void
cuda_autopoll(void *cookie, int flag)
{
	struct cuda_softc *sc = cookie;
	uint8_t cmd[] = {CUDA_PSEUDO, CMD_AUTOPOLL, (flag != 0)};

	if (cmd[2] == sc->sc_autopoll)
		return;

	sc->sc_autopoll = -1;
	cuda_send(sc, 0, 3, cmd);
	while(sc->sc_autopoll == -1) {
		if (sc->sc_polling || cold) {
			cuda_poll(sc);
		} else
			tsleep(&sc->sc_todev, 0, "autopoll", 100);
	}
}
示例#6
0
static int
cuda_send(void *cookie, int poll, int length, uint8_t *msg)
{
	struct cuda_softc *sc = cookie;
	device_t dev = sc->sc_dev;
	struct cuda_packet *pkt;

	if (sc->sc_state == CUDA_NOTREADY)
		return (-1);

	mtx_lock(&sc->sc_mutex);

	pkt = STAILQ_FIRST(&sc->sc_freeq);
	if (pkt == NULL) {
		mtx_unlock(&sc->sc_mutex);
		return (-1);
	}

	pkt->len = length - 1;
	pkt->type = msg[0];
	memcpy(pkt->data, &msg[1], pkt->len);

	STAILQ_REMOVE_HEAD(&sc->sc_freeq, pkt_q);
	STAILQ_INSERT_TAIL(&sc->sc_outq, pkt, pkt_q);

	/*
	 * If we already are sending a packet, we should bail now that this
	 * one has been added to the queue.
	 */

	if (sc->sc_waiting) {
		mtx_unlock(&sc->sc_mutex);
		return (0);
	}

	cuda_send_outbound(sc);
	mtx_unlock(&sc->sc_mutex);

	if (sc->sc_polling || poll || cold)
		cuda_poll(dev);

	return (0);
}
示例#7
0
/* Send an ADB command */
static int
cuda_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);
    if (i)
	return i;

    if (sync) {
	while (!req->complete)
	    cuda_poll();
    }
    return 0;
}
示例#8
0
int
find_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 the main VIA driver in arch/m68k/mac/via.c        */

#ifndef CONFIG_MAC
    via[IFR] = 0x7f;
    eieio();	/* clear interrupts by writing 1s */
    via[IER] = IER_SET|SR_INT;
    eieio();	/* enable interrupt from SR */
#endif

    /* enable autopoll */
    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
    while (!req.complete)
        cuda_poll();

    return 1;
}
示例#9
0
static int
cuda_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *_send,
    size_t send_len, void *_recv, size_t recv_len, int flags)
{
	struct cuda_softc *sc = cookie;
	const uint8_t *send = _send;
	uint8_t *recv = _recv;
	uint8_t command[16] = {CUDA_PSEUDO, CMD_IIC};

	DPRINTF("cuda_i2c_exec(%02x)\n", addr);
	command[2] = addr;

	memcpy(&command[3], send, min((int)send_len, 12));

	sc->sc_iic_done = 0;
	cuda_send(sc, sc->sc_polling, send_len + 3, command);

	while ((sc->sc_iic_done == 0) && (sc->sc_error == 0)) {
		if (sc->sc_polling || cold) {
			cuda_poll(sc);
		} else
			tsleep(&sc->sc_todev, 0, "i2c", 1000);
	}

	if (sc->sc_error) {
		sc->sc_error = 0;
		return -1;
	}

	/* see if we're supposed to do a read */
	if (recv_len > 0) {
		sc->sc_iic_done = 0;
		command[2] |= 1;
		command[3] = 0;

		/*
		 * XXX we need to do something to limit the size of the answer
		 * - apparently the chip keeps sending until we tell it to stop
		 */
		sc->sc_i2c_read_len = recv_len;
		DPRINTF("rcv_len: %d\n", recv_len);
		cuda_send(sc, sc->sc_polling, 3, command);
		while ((sc->sc_iic_done == 0) && (sc->sc_error == 0)) {
			if (sc->sc_polling || cold) {
				cuda_poll(sc);
			} else
				tsleep(&sc->sc_todev, 0, "i2c", 1000);
		}

		if (sc->sc_error) {
			printf("error trying to read\n");
			sc->sc_error = 0;
			return -1;
		}
	}

	DPRINTF("received: %d\n", sc->sc_iic_done);
	if ((sc->sc_iic_done > 3) && (recv_len > 0)) {
		int rlen;

		/* we got an answer */
		rlen = min(sc->sc_iic_done - 3, recv_len);
		memcpy(recv, &sc->sc_in[4], rlen);
#ifdef CUDA_DEBUG
		{
			int i;
			printf("ret:");
			for (i = 0; i < rlen; i++)
				printf(" %02x", recv[i]);
			printf("\n");
		}
#endif
		return rlen;
	}
	return 0;
}
示例#10
0
文件: cuda.c 项目: ryo/netbsd-src
static int
cuda_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *_send,
    size_t send_len, void *_recv, size_t recv_len, int flags)
{
	struct cuda_softc *sc = cookie;
	const uint8_t *send = _send;
	uint8_t *recv = _recv;
	uint8_t command[16] = {CUDA_PSEUDO, CMD_IIC};

	DPRINTF("cuda_i2c_exec(%02x)\n", addr);
	command[2] = addr;

	/* Copy command and output data bytes, if any, to buffer */
	if (send_len > 0)
		memcpy(&command[3], send, min((int)send_len, 12));
	else if (I2C_OP_READ_P(op) && (recv_len == 0)) {
		/*
		 * If no data bytes in either direction, it's a "quick"
		 * i2c operation.  We don't know how to do a quick_read
		 * since that requires us to set the low bit of the
		 * address byte after it has been left-shifted.
		 */
		sc->sc_error = 0;
		return -1;
	}

	sc->sc_iic_done = 0;
	cuda_send(sc, sc->sc_polling, send_len + 3, command);

	while ((sc->sc_iic_done == 0) && (sc->sc_error == 0)) {
		if (sc->sc_polling || cold) {
			cuda_poll(sc);
		} else
			tsleep(&sc->sc_todev, 0, "i2c", 1000);
	}

	if (sc->sc_error) {
		sc->sc_error = 0;
		aprint_error_dev(sc->sc_dev, "error doing I2C\n");
		return -1;
	}

	/* see if we're supposed to do a read */
	if (recv_len > 0) {
		sc->sc_iic_done = 0;
		command[2] |= 1;
		command[3] = 0;

		/*
		 * XXX we need to do something to limit the size of the answer
		 * - apparently the chip keeps sending until we tell it to stop
		 */
		sc->sc_i2c_read_len = recv_len;
		DPRINTF("rcv_len: %d\n", recv_len);
		cuda_send(sc, sc->sc_polling, 3, command);
		while ((sc->sc_iic_done == 0) && (sc->sc_error == 0)) {
			if (sc->sc_polling || cold) {
				cuda_poll(sc);
			} else
				tsleep(&sc->sc_todev, 0, "i2c", 1000);
		}

		if (sc->sc_error) {
			aprint_error_dev(sc->sc_dev, 
			    "error trying to read from I2C\n");
			sc->sc_error = 0;
			return -1;
		}
	}

	DPRINTF("received: %d\n", sc->sc_iic_done);
	if ((sc->sc_iic_done > 3) && (recv_len > 0)) {
		int rlen;

		/* we got an answer */
		rlen = min(sc->sc_iic_done - 3, recv_len);
		memcpy(recv, &sc->sc_in[4], rlen);
#ifdef CUDA_DEBUG
		{
			int i;
			printf("ret:");
			for (i = 0; i < rlen; i++)
				printf(" %02x", recv[i]);
			printf("\n");
		}
#endif
		return rlen;
	}
	return 0;
}