Пример #1
0
int
pcf_read(device_t dev, char *buf, int len, int *read, int last,
	 int delay /* us */)
{
	struct pcf_softc *sc = DEVTOSOFTC(dev);
	int bytes, error = 0;
#ifdef PCFDEBUG
	char *obuf = buf;

	device_printf(dev, " << reading %d bytes\n", len);
#endif

	PCF_LOCK(sc);
	/* trig the bus to get the first data byte in S0 */
	if (len) {
		if (len == 1 && last)
			/* just one byte to read */
			pcf_set_S1(sc, ESO);		/* no ack */

		dummy_read(sc);
	}

	bytes = 0;
	while (len) {

		/* XXX delay needed here */

		/* wait for trigged byte */
		if ((error = pcf_wait_byte(sc))) {
			pcf_stop_locked(sc);
			goto error;
		}

		if (len == 1 && last)
			/* ok, last data byte already in S0, no I2C activity
			 * on next pcf_get_S0() */
			pcf_stop_locked(sc);

		else if (len == 2 && last)
			/* next trigged byte with no ack */
			pcf_set_S1(sc, ESO);

		/* receive byte, trig next byte */
		*buf++ = pcf_get_S0(sc);

		len --;
		bytes ++;
	};

error:
	*read = bytes;
	PCF_UNLOCK(sc);

#ifdef PCFDEBUG
	device_printf(dev, " << %d bytes read (%d): %#x%s\n", bytes, error,
		      (unsigned)obuf[0], bytes > 1? "...": "");
#endif

	return (error);
}
Пример #2
0
static int
pcf_start(device_t pcfdev, u_char slave, int timeout)
{
	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
	int error = 0;

	if ((PCF_GET_S1(pcf) & nBB) == 0)
		return (IIC_EBUSBSY);

	/* set slave address to PCF. Last bit (LSB) must be set correctly
	 * according to transfer direction */
	PCF_SET_S0(pcf, slave);

	/* START only */
	PCF_SET_S1(pcf, PIN|ES0|STA|ACK);

	pcf->pcf_started = 1;

	/* wait for address sent, polling */
	if ((error = pcf_wait_byte(pcf)))
		goto error;

	/* check for ACK */
	if (pcf_noack(pcf, timeout)) {
		error = IIC_ENOACK;
		goto error;
	}

	return (0);

error:
	pcf_stop(pcfdev);
	return (error);
}
Пример #3
0
static int
pcf_repeated_start(device_t pcfdev, u_char slave, int timeout)
{
	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
	int error = 0;

	/* repeated start */
	PCF_SET_S1(pcf, ES0|STA|STO|ACK);

	/* set slave address to PCF. Last bit (LSB) must be set correctly
	 * according to transfer direction */
	PCF_SET_S0(pcf, slave);

	/* wait for address sent, polling */
	if ((error = pcf_wait_byte(pcf)))
		goto error;

	/* check for ack */
	if (pcf_noack(pcf, timeout)) {
		error = IIC_ENOACK;
		goto error;
	}

	return (0);

error:
	pcf_stop(pcfdev);
	return (error);
}
Пример #4
0
static int
pcf_read(device_t pcfdev, char *buf, int len, int *read, int last,
							int delay /* us */)
{
	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
	int bytes, error = 0;

#ifdef PCFDEBUG
	kprintf("pcf%d: << reading %d bytes\n", device_get_unit(pcfdev), len);
#endif

	/* trig the bus to get the first data byte in S0 */
	if (len) {
		if (len == 1 && last)
			/* just one byte to read */
			PCF_SET_S1(pcf, ES0);		/* no ack */

		dummy_read(pcf);
	}

	bytes = 0;
	while (len) {

		/* XXX delay needed here */

		/* wait for trigged byte */
		if ((error = pcf_wait_byte(pcf))) {
			pcf_stop(pcfdev);
			goto error;
		}

		if (len == 1 && last)
			/* ok, last data byte already in S0, no I2C activity
			 * on next PCF_GET_S0() */
			pcf_stop(pcfdev);

		else if (len == 2 && last)
			/* next trigged byte with no ack */
			PCF_SET_S1(pcf, ES0);

		/* receive byte, trig next byte */
		*buf++ = PCF_GET_S0(pcf);

		len --;
		bytes ++;
	}

error:
	*read = bytes;

#ifdef PCFDEBUG
	kprintf("pcf%d: << %d bytes read (%d)\n",
		device_get_unit(pcfdev), bytes, error);
#endif

	return (error);
}
Пример #5
0
int
pcf_start(device_t dev, u_char slave, int timeout)
{
	struct pcf_softc *sc = DEVTOSOFTC(dev);
	int error = 0;

	PCF_LOCK(sc);
#ifdef PCFDEBUG
	device_printf(dev, " >> start for slave %#x\n", (unsigned)slave);
#endif
	if ((pcf_get_S1(sc) & nBB) == 0) {
#ifdef PCFDEBUG
		printf("pcf: busy!\n");
#endif
		PCF_UNLOCK(sc);
		return (IIC_EBUSBSY);
	}

	/* set slave address to PCF. Last bit (LSB) must be set correctly
	 * according to transfer direction */
	pcf_set_S0(sc, slave);

	/* START only */
	pcf_set_S1(sc, PIN|ESO|STA|ACK);

	sc->pcf_started = 1;

	/* wait for address sent, polling */
	if ((error = pcf_wait_byte(sc)))
		goto error;

	/* check for ACK */
	if (pcf_noack(sc, timeout)) {
		error = IIC_ENOACK;
#ifdef PCFDEBUG
		printf("pcf: no ack on start!\n");
#endif
		goto error;
	}

	PCF_UNLOCK(sc);
	return (0);

error:
	pcf_stop_locked(sc);
	PCF_UNLOCK(sc);
	return (error);
}
Пример #6
0
int
pcf_write(device_t dev, const char *buf, int len, int *sent, int timeout /* us */)
{
	struct pcf_softc *sc = DEVTOSOFTC(dev);
	int bytes, error = 0;

#ifdef PCFDEBUG
	device_printf(dev, " >> writing %d bytes: %#x%s\n", len,
		      (unsigned)buf[0], len > 1? "...": "");
#endif

	bytes = 0;
	PCF_LOCK(sc);
	while (len) {

		pcf_set_S0(sc, *buf++);

		/* wait for the byte to be send */
		if ((error = pcf_wait_byte(sc)))
			goto error;

		/* check if ack received */
		if (pcf_noack(sc, timeout)) {
			error = IIC_ENOACK;
			goto error;
		}

		len --;
		bytes ++;
	}

error:
	*sent = bytes;
	PCF_UNLOCK(sc);

#ifdef PCFDEBUG
	device_printf(dev, " >> %d bytes written (%d)\n", bytes, error);
#endif

	return (error);
}
Пример #7
0
static int
pcf_write(device_t pcfdev, const char *buf, int len, int *sent,
	  int timeout /* us */)
{
	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
	int bytes, error = 0;

#ifdef PCFDEBUG
	kprintf("pcf%d: >> writing %d bytes\n", device_get_unit(pcfdev), len);
#endif

	bytes = 0;
	while (len) {

		PCF_SET_S0(pcf, *buf++);

		/* wait for the byte to be send */
		if ((error = pcf_wait_byte(pcf)))
			goto error;

		/* check if ack received */
		if (pcf_noack(pcf, timeout)) {
			error = IIC_ENOACK;
			goto error;
		}

		len --;
		bytes ++;
	}

error:
	*sent = bytes;

#ifdef PCFDEBUG
	kprintf("pcf%d: >> %d bytes written (%d)\n",
		device_get_unit(pcfdev), bytes, error);
#endif

	return (error);
}
Пример #8
0
int
pcf_repeated_start(device_t dev, u_char slave, int timeout)
{
	struct pcf_softc *sc = DEVTOSOFTC(dev);
	int error = 0;

	PCF_LOCK(sc);
#ifdef PCFDEBUG
	device_printf(dev, " >> repeated start for slave %#x\n",
		      (unsigned)slave);
#endif
	/* repeated start */
	pcf_set_S1(sc, ESO|STA|STO|ACK);

	/* set slave address to PCF. Last bit (LSB) must be set correctly
	 * according to transfer direction */
	pcf_set_S0(sc, slave);

	/* wait for address sent, polling */
	if ((error = pcf_wait_byte(sc)))
		goto error;

	/* check for ack */
	if (pcf_noack(sc, timeout)) {
		error = IIC_ENOACK;
#ifdef PCFDEBUG
		printf("pcf: no ack on repeated_start!\n");
#endif
		goto error;
	}

	PCF_UNLOCK(sc);
	return (0);

error:
	pcf_stop_locked(sc);
	PCF_UNLOCK(sc);
	return (error);
}