diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-05-12 16:30:50 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-05-19 16:22:08 +1000 |
commit | 893887ed75cacbfe1a855c63659838e0261d17e8 (patch) | |
tree | 76cb9de8fc0886fa3799faeb9560869533c5425e | |
parent | 04f542c07e9376c732c72b40de7cdc71801f8cd5 (diff) |
drm/nouveau: fix i2c-related init table handlers
Mutliple issues. INIT_ZM_I2C_BYTE/INIT_I2C_BYTE didn't even try and
use the register value, and all the handlers were using the wrong
slave address.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.c | 77 |
1 files changed, 38 insertions, 39 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 327f6f34d78d..e7e69ccce5c9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -1448,12 +1448,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) */ uint8_t i2c_index = bios->data[offset + 1]; - uint8_t i2c_address = bios->data[offset + 2]; + uint8_t i2c_address = bios->data[offset + 2] >> 1; uint8_t count = bios->data[offset + 3]; - int len = 4 + count * 3; struct nouveau_i2c_chan *chan; - struct i2c_msg msg; - int i; + int len = 4 + count * 3; + int ret, i; if (!iexec->execute) return len; @@ -1467,32 +1466,31 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) return -ENODEV; for (i = 0; i < count; i++) { - uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; + uint8_t reg = bios->data[offset + 4 + i * 3]; uint8_t mask = bios->data[offset + 5 + i * 3]; uint8_t data = bios->data[offset + 6 + i * 3]; - uint8_t value; + union i2c_smbus_data val; - msg.addr = i2c_address; - msg.flags = I2C_M_RD; - msg.len = 1; - msg.buf = &value; - if (i2c_transfer(&chan->adapter, &msg, 1) != 1) - return -EIO; + ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, + I2C_SMBUS_READ, reg, + I2C_SMBUS_BYTE_DATA, &val); + if (ret < 0) + return ret; BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " "Mask: 0x%02X, Data: 0x%02X\n", - offset, i2c_reg, value, mask, data); + offset, reg, val.byte, mask, data); - value = (value & mask) | data; + if (!bios->execute) + continue; - if (bios->execute) { - msg.addr = i2c_address; - msg.flags = 0; - msg.len = 1; - msg.buf = &value; - if (i2c_transfer(&chan->adapter, &msg, 1) != 1) - return -EIO; - } + val.byte &= mask; + val.byte |= data; + ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_BYTE_DATA, &val); + if (ret < 0) + return ret; } return len; @@ -1518,12 +1516,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) */ uint8_t i2c_index = bios->data[offset + 1]; - uint8_t i2c_address = bios->data[offset + 2]; + uint8_t i2c_address = bios->data[offset + 2] >> 1; uint8_t count = bios->data[offset + 3]; - int len = 4 + count * 2; struct nouveau_i2c_chan *chan; - struct i2c_msg msg; - int i; + int len = 4 + count * 2; + int ret, i; if (!iexec->execute) return len; @@ -1537,20 +1534,22 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) return -ENODEV; for (i = 0; i < count; i++) { - uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; - uint8_t data = bios->data[offset + 5 + i * 2]; + uint8_t reg = bios->data[offset + 4 + i * 2]; + union i2c_smbus_data val; + + val.byte = bios->data[offset + 5 + i * 2]; BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n", - offset, i2c_reg, data); - - if (bios->execute) { - msg.addr = i2c_address; - msg.flags = 0; - msg.len = 1; - msg.buf = &data; - if (i2c_transfer(&chan->adapter, &msg, 1) != 1) - return -EIO; - } + offset, reg, val.byte); + + if (!bios->execute) + continue; + + ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_BYTE_DATA, &val); + if (ret < 0) + return ret; } return len; @@ -1574,7 +1573,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) */ uint8_t i2c_index = bios->data[offset + 1]; - uint8_t i2c_address = bios->data[offset + 2]; + uint8_t i2c_address = bios->data[offset + 2] >> 1; uint8_t count = bios->data[offset + 3]; int len = 4 + count; struct nouveau_i2c_chan *chan; |