/* Block transaction function */
static int i801_block_transaction(struct i801_priv *priv,
                                  union i2c_smbus_data *data, char read_write,
                                  int command, int hwpec)
{
    int result = 0;
    unsigned char hostc;

    if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
        if (read_write == I2C_SMBUS_WRITE) {
            /* set I2C_EN bit in configuration register */
            pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &hostc);
            pci_write_config_byte(priv->pci_dev, SMBHSTCFG,
                                  hostc | SMBHSTCFG_I2C_EN);
        } else if (!(priv->features & FEATURE_I2C_BLOCK_READ)) {
            dev_err(&priv->pci_dev->dev,
                    "I2C block read is unsupported!\n");
            return -EOPNOTSUPP;
        }
    }

    if (read_write == I2C_SMBUS_WRITE
            || command == I2C_SMBUS_I2C_BLOCK_DATA) {
        if (data->block[0] < 1)
            data->block[0] = 1;
        if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
            data->block[0] = I2C_SMBUS_BLOCK_MAX;
    } else {
        data->block[0] = 32;	/* max for SMBus block reads */
    }

    /* Experience has shown that the block buffer can only be used for
       SMBus (not I2C) block transactions, even though the datasheet
       doesn't mention this limitation. */
    if ((priv->features & FEATURE_BLOCK_BUFFER)
            && command != I2C_SMBUS_I2C_BLOCK_DATA
            && i801_set_block_buffer_mode(priv) == 0)
        result = i801_block_transaction_by_block(priv, data,
                 read_write, hwpec);
    else
        result = i801_block_transaction_byte_by_byte(priv, data,
                 read_write,
                 command, hwpec);

    if (result == 0 && hwpec)
        i801_wait_hwpec(priv);

    if (command == I2C_SMBUS_I2C_BLOCK_DATA
            && read_write == I2C_SMBUS_WRITE) {
        /* restore saved configuration register value */
        pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc);
    }
    return result;
}
예제 #2
0
파일: i2c-i801.c 프로젝트: mecke/linux-2.6
/* Block transaction function */
static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
				  int command, int hwpec)
{
	int result = 0;
	unsigned char hostc;

	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
		if (read_write == I2C_SMBUS_WRITE) {
			/* set I2C_EN bit in configuration register */
			pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
			pci_write_config_byte(I801_dev, SMBHSTCFG,
					      hostc | SMBHSTCFG_I2C_EN);
		} else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) {
			dev_err(&I801_dev->dev,
				"I2C block read is unsupported!\n");
			return -EOPNOTSUPP;
		}
	}

	if (read_write == I2C_SMBUS_WRITE
	 || command == I2C_SMBUS_I2C_BLOCK_DATA) {
		if (data->block[0] < 1)
			data->block[0] = 1;
		if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
			data->block[0] = I2C_SMBUS_BLOCK_MAX;
	} else {
		data->block[0] = 32;	/* max for SMBus block reads */
	}

	if ((i801_features & FEATURE_BLOCK_BUFFER)
	 && !(command == I2C_SMBUS_I2C_BLOCK_DATA
	      && read_write == I2C_SMBUS_READ)
	 && i801_set_block_buffer_mode() == 0)
		result = i801_block_transaction_by_block(data, read_write,
							 hwpec);
	else
		result = i801_block_transaction_byte_by_byte(data, read_write,
							     command, hwpec);

	if (result == 0 && hwpec)
		i801_wait_hwpec();

	if (command == I2C_SMBUS_I2C_BLOCK_DATA
	 && read_write == I2C_SMBUS_WRITE) {
		/* restore saved configuration register value */
		pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
	}
	return result;
}