val |= RTL9300_I2C_MST_CTRL1_I2C_TRIG;
mask |= RTL9300_I2C_MST_CTRL1_I2C_TRIG;
ret = regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, mask, val); if (ret) return ret;
ret = regmap_read_poll_timeout(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1,
val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 100000); if (ret) return ret;
if (val & RTL9300_I2C_MST_CTRL1_I2C_FAIL) return -EIO;
if (read_write == I2C_SMBUS_READ) { if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA) {
ret = regmap_read(i2c->regmap,
i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val); if (ret) return ret;
data->byte = val & 0xff;
} elseif (size == I2C_SMBUS_WORD_DATA) {
ret = regmap_read(i2c->regmap,
i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val); if (ret) return ret;
data->word = val & 0xffff;
} else {
ret = rtl9300_i2c_read(i2c, &data->block[0], len); if (ret) return ret;
}
}
return 0;
}
staticint rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsignedshort flags, char read_write, u8 command, int size, union i2c_smbus_data *data)
{ struct rtl9300_i2c_chan *chan = i2c_get_adapdata(adap); struct rtl9300_i2c *i2c = chan->i2c; int len = 0, ret;
mutex_lock(&i2c->lock); if (chan->sda_pin != i2c->sda_pin) {
ret = rtl9300_i2c_config_io(i2c, chan->sda_pin); if (ret) goto out_unlock;
i2c->sda_pin = chan->sda_pin;
}
switch (size) { case I2C_SMBUS_BYTE: if (read_write == I2C_SMBUS_WRITE) {
ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0); if (ret) goto out_unlock;
ret = rtl9300_i2c_reg_addr_set(i2c, command, 1); if (ret) goto out_unlock;
} else {
ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 1); if (ret) goto out_unlock;
ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0); if (ret) goto out_unlock;
} break;
case I2C_SMBUS_BYTE_DATA:
ret = rtl9300_i2c_reg_addr_set(i2c, command, 1); if (ret) goto out_unlock;
ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 1); if (ret) goto out_unlock; if (read_write == I2C_SMBUS_WRITE) {
ret = rtl9300_i2c_writel(i2c, data->byte); if (ret) goto out_unlock;
} break;
case I2C_SMBUS_WORD_DATA:
ret = rtl9300_i2c_reg_addr_set(i2c, command, 1); if (ret) goto out_unlock;
ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 2); if (ret) goto out_unlock; if (read_write == I2C_SMBUS_WRITE) {
ret = rtl9300_i2c_writel(i2c, data->word); if (ret) goto out_unlock;
} break;
case I2C_SMBUS_BLOCK_DATA:
ret = rtl9300_i2c_reg_addr_set(i2c, command, 1); if (ret) goto out_unlock; if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) {
ret = -EINVAL; goto out_unlock;
}
ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0] + 1); if (ret) goto out_unlock; if (read_write == I2C_SMBUS_WRITE) {
ret = rtl9300_i2c_write(i2c, &data->block[0], data->block[0] + 1); if (ret) goto out_unlock;
}
len = data->block[0] + 1; break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.