示例#1
0
文件: cuda.c 项目: ryo/netbsd-src
static int
cuda_todr_get(todr_chip_handle_t tch, struct timeval *tvp)
{
	struct cuda_softc *sc = tch->cookie;
	int cnt = 0;
	uint8_t cmd[] = { CUDA_PSEUDO, CMD_READ_RTC};

	sc->sc_tod = 0;
	while (sc->sc_tod == 0) {
		cuda_send(sc, 0, 2, cmd);

		while ((sc->sc_tod == 0) && (cnt < 10)) {
			tsleep(&sc->sc_todev, 0, "todr", 10);
			cnt++;
		}

		if (sc->sc_tod == 0) {
			aprint_error_dev(sc->sc_dev,
			    "unable to read a sane RTC value\n");
			return EIO;
		}
		if ((sc->sc_tod > 0xf0000000UL) ||
		    (sc->sc_tod < DIFF19041970)) {
			/* huh? try again */
			sc->sc_tod = 0;
			aprint_verbose_dev(sc->sc_dev,
			    "got garbage reading RTC, trying again\n");
		}
	}

	tvp->tv_sec = sc->sc_tod - DIFF19041970;
	DPRINTF("tod: %" PRIo64 "\n", tvp->tv_sec);
	tvp->tv_usec = 0;
	return 0;
}
示例#2
0
static void
cuda_shutdown(void *xsc, int howto)
{
	struct cuda_softc *sc = xsc;
	uint8_t cmd[] = {CUDA_PSEUDO, 0};

	cmd[1] = (howto & RB_HALT) ? CMD_POWEROFF : CMD_RESET;
	cuda_poll(sc->sc_dev);
	cuda_send(sc, 1, 2, cmd);

	while (1)
		cuda_poll(sc->sc_dev);
}
示例#3
0
static int
cuda_settime(device_t dev, struct timespec *ts)
{
	struct cuda_softc *sc = device_get_softc(dev);
	uint8_t cmd[] = {CUDA_PSEUDO, CMD_WRITE_RTC, 0, 0, 0, 0};
	uint32_t sec;

	sec = ts->tv_sec + DIFF19041970;
	memcpy(&cmd[2], &sec, sizeof(sec));

	mtx_lock(&sc->sc_mutex);
	cuda_send(sc, 0, 6, cmd);
	mtx_unlock(&sc->sc_mutex);

	return (0);
}
示例#4
0
static int
cuda_gettime(device_t dev, struct timespec *ts)
{
	struct cuda_softc *sc = device_get_softc(dev);
	uint8_t cmd[] = {CUDA_PSEUDO, CMD_READ_RTC};

	mtx_lock(&sc->sc_mutex);
	sc->sc_rtc = -1;
	cuda_send(sc, 1, 2, cmd);
	if (sc->sc_rtc == -1)
		mtx_sleep(&sc->sc_rtc, &sc->sc_mutex, 0, "rtc", 100);

	ts->tv_sec = sc->sc_rtc - DIFF19041970;
	ts->tv_nsec = 0;
	mtx_unlock(&sc->sc_mutex);

	return (0);
}
示例#5
0
static u_int
cuda_adb_send(device_t dev, u_char command_byte, int len, u_char *data, 
    u_char poll)
{
	struct cuda_softc *sc = device_get_softc(dev);
	uint8_t packet[16];
	int i;

	/* construct an ADB command packet and send it */
	packet[0] = CUDA_ADB;
	packet[1] = command_byte;
	for (i = 0; i < len; i++)
		packet[i + 2] = data[i];

	cuda_send(sc, poll, len + 2, packet);

	return (0);
}
示例#6
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);
	}
}
示例#7
0
static int
cuda_todr_set(todr_chip_handle_t tch, volatile struct timeval *tvp)
{
	struct cuda_softc *sc = tch->cookie;
	uint32_t sec;
	uint8_t cmd[] = {CUDA_PSEUDO, CMD_WRITE_RTC, 0, 0, 0, 0};

	sec = tvp->tv_sec + DIFF19041970;
	memcpy(&cmd[2], &sec, 4);
	sc->sc_tod = 0;
	if (cuda_send(sc, 0, 6, cmd) == 0) {
		while (sc->sc_tod == 0) {
			tsleep(&sc->sc_todev, 0, "todr", 10);
		}
		return 0;
	}
	return -1;
		
}
示例#8
0
static u_int 
cuda_adb_autopoll(device_t dev, uint16_t mask) {
	struct cuda_softc *sc = device_get_softc(dev);

	uint8_t cmd[] = {CUDA_PSEUDO, CMD_AUTOPOLL, mask != 0};

	mtx_lock(&sc->sc_mutex);

	if (cmd[2] == sc->sc_autopoll) {
		mtx_unlock(&sc->sc_mutex);
		return (0);
	}

	sc->sc_autopoll = -1;
	cuda_send(sc, 1, 3, cmd);

	mtx_unlock(&sc->sc_mutex);

	return (0);
}
示例#9
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;
}
示例#10
0
static int
cuda_todr_get(todr_chip_handle_t tch, volatile struct timeval *tvp)
{
	struct cuda_softc *sc = tch->cookie;
	int cnt = 0;
	uint8_t cmd[] = { CUDA_PSEUDO, CMD_READ_RTC};

	sc->sc_tod = 0;
	cuda_send(sc, 0, 2, cmd);

	while ((sc->sc_tod == 0) && (cnt < 10)) {
		tsleep(&sc->sc_todev, 0, "todr", 10);
		cnt++;
	}

	if (sc->sc_tod == 0)
		return EIO;

	tvp->tv_sec = sc->sc_tod - DIFF19041970;
	DPRINTF("tod: %ld\n", tvp->tv_sec);
	tvp->tv_usec = 0;
	return 0;
}
示例#11
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;
}
示例#12
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;
}