示例#1
0
static int
alpm_quick(device_t dev, u_char slave, int how)
{
	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
	int error;

	ALPM_LOCK(sc);
	alpm_clear(sc);
	if (!alpm_idle(sc)) {
		ALPM_UNLOCK(sc);
		return (EBUSY);
	}

	switch (how) {
	case SMB_QWRITE:
		ALPM_DEBUG(kprintf("alpm: QWRITE to 0x%x", slave));
		ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
		break;
	case SMB_QREAD:
		ALPM_DEBUG(kprintf("alpm: QREAD to 0x%x", slave));
		ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
		break;
	default:
		panic("%s: unknown QUICK command (%x)!", __func__, how);
	}
	ALPM_SMBOUTB(sc, SMBCMD, SMBQUICK);
	ALPM_SMBOUTB(sc, SMBSTART, 0xff);

	error = alpm_wait(sc);

	ALPM_DEBUG(kprintf(", error=0x%x\n", error));
	ALPM_UNLOCK(sc);

	return (error);
}
示例#2
0
static int
alpm_readw(device_t dev, u_char slave, char cmd, short *word)
{
	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
	int error;
	u_char high, low;

	ALPM_LOCK(sc);
	alpm_clear(sc);
	if (!alpm_idle(sc)) {
		ALPM_UNLOCK(sc);
		return (SMB_EBUSY);
	}

	ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
	ALPM_SMBOUTB(sc, SMBCMD, SMBWRWORD);
	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
	ALPM_SMBOUTB(sc, SMBSTART, 0xff);

	if ((error = alpm_wait(sc)) == SMB_ENOERR) {
		low = ALPM_SMBINB(sc, SMBHDATA);
		high = ALPM_SMBINB(sc, SMBHDATB);

		*word = ((high & 0xff) << 8) | (low & 0xff);
	}

	ALPM_DEBUG(printf("alpm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error));
	ALPM_UNLOCK(sc);

	return (error);
}
示例#3
0
static int
alpm_writew(device_t dev, u_char slave, char cmd, short word)
{
	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
	int error;

	ALPM_LOCK(sc);
	alpm_clear(sc);
	if (!alpm_idle(sc)) {
		ALPM_UNLOCK(sc);
		return (SMB_EBUSY);
	}

	ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
	ALPM_SMBOUTB(sc, SMBCMD, SMBWRWORD);
	ALPM_SMBOUTB(sc, SMBHDATA, word & 0x00ff);
	ALPM_SMBOUTB(sc, SMBHDATB, (word & 0xff00) >> 8);
	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
	ALPM_SMBOUTB(sc, SMBSTART, 0xff);

	error = alpm_wait(sc);

	ALPM_DEBUG(printf("alpm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
	ALPM_UNLOCK(sc);

	return (error);
}
示例#4
0
static int
alpm_readb(device_t dev, u_char slave, char cmd, char *byte)
{
	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
	int error;

	ALPM_LOCK(sc);
	alpm_clear(sc);
	if (!alpm_idle(sc)) {
		ALPM_UNLOCK(sc);
		return (SMB_EBUSY);
	}

	ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
	ALPM_SMBOUTB(sc, SMBCMD, SMBWRBYTE);
	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
	ALPM_SMBOUTB(sc, SMBSTART, 0xff);

	if ((error = alpm_wait(sc)) == SMB_ENOERR)
		*byte = ALPM_SMBINB(sc, SMBHDATA);

	ALPM_DEBUG(printf("alpm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
	ALPM_UNLOCK(sc);

	return (error);
}
示例#5
0
static int
alpm_writeb(device_t dev, u_char slave, char cmd, char byte)
{
	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
	int error;

	ALPM_LOCK(sc);
	alpm_clear(sc);
	if (!alpm_idle(sc)) {
		ALPM_UNLOCK(sc);
		return (SMB_EBUSY);
	}

	ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
	ALPM_SMBOUTB(sc, SMBCMD, SMBWRBYTE);
	ALPM_SMBOUTB(sc, SMBHDATA, byte);
	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
	ALPM_SMBOUTB(sc, SMBSTART, 0xff);

	error = alpm_wait(sc);

	ALPM_DEBUG(printf("alpm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
	ALPM_UNLOCK(sc);

	return (error);
}
示例#6
0
static int
alpm_idle(struct alpm_softc *sc)
{
	u_char sts;

	sts = ALPM_SMBINB(sc, SMBSTS);

	ALPM_DEBUG(printf("alpm: idle? STS=0x%x\n", sts));

	return (sts & IDL_STS);
}
示例#7
0
static int
alpm_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
{
	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
	u_char data, len, i;
	int error;

	if (*count < 1 || *count > 32)
		return (SMB_EINVAL);

	ALPM_LOCK(sc);
	alpm_clear(sc);
	if (!alpm_idle(sc)) {
		ALPM_UNLOCK(sc);
		return (SMB_EBUSY);
	}

	ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
	
	/* set the cmd and reset the
	 * 32-byte long internal buffer */
	ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR);

	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
	ALPM_SMBOUTB(sc, SMBSTART, 0xff);

	if ((error = alpm_wait(sc)) != SMB_ENOERR)
			goto error;

	len = ALPM_SMBINB(sc, SMBHDATA);

	/* read the 32-byte internal buffer */
	for (i = 0; i < len; i++) {
		data = ALPM_SMBINB(sc, SMBHBLOCK);
		if (i < *count)
			buf[i] = data;
		DELAY(2);
	}
	*count = len;

error:
	ALPM_DEBUG(printf("alpm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error));
	ALPM_UNLOCK(sc);

	return (error);
}
示例#8
0
static int
alpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
{
	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
	u_char i;
	int error;

	if (count < 1 || count > 32)
		return (SMB_EINVAL);

	ALPM_LOCK(sc);
	alpm_clear(sc);
	if(!alpm_idle(sc)) {
		ALPM_UNLOCK(sc);
		return (SMB_EBUSY);
	}

	ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
	
	/* set the cmd and reset the
	 * 32-byte long internal buffer */
	ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR);

	ALPM_SMBOUTB(sc, SMBHDATA, count);

	/* fill the 32-byte internal buffer */
	for (i = 0; i < count; i++) {
		ALPM_SMBOUTB(sc, SMBHBLOCK, buf[i]);
		DELAY(2);
	}
	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
	ALPM_SMBOUTB(sc, SMBSTART, 0xff);

	error = alpm_wait(sc);

	ALPM_DEBUG(printf("alpm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
	ALPM_UNLOCK(sc);

	return (error);
}
示例#9
0
/*
 * Poll the SMBus controller
 */
static int
alpm_wait(struct alpm_softc *sc)
{
	int count = 10000;
	u_char sts = 0;
	int error;

	/* wait for command to complete and SMBus controller is idle */
	while (count--) {
		DELAY(10);
		sts = ALPM_SMBINB(sc, SMBSTS);
		if (sts & SMI_I_STS)
			break;
	}

	ALPM_DEBUG(printf("alpm: STS=0x%x\n", sts));

	error = SMB_ENOERR;

	if (!count)
		error |= SMB_ETIMEOUT;

	if (sts & TERMINATE)
		error |= SMB_EABORT;

	if (sts & BUS_COLLI)
		error |= SMB_ENOACK;

	if (sts & DEVICE_ERR)
		error |= SMB_EBUSERR;

	if (error != SMB_ENOERR)
		alpm_clear(sc);

	return (error);
}