Commit 893887ed authored by Ben Skeggs's avatar Ben Skeggs

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: default avatarBen Skeggs <bskeggs@redhat.com>
parent 04f542c0
...@@ -1448,12 +1448,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ...@@ -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_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]; uint8_t count = bios->data[offset + 3];
int len = 4 + count * 3;
struct nouveau_i2c_chan *chan; struct nouveau_i2c_chan *chan;
struct i2c_msg msg; int len = 4 + count * 3;
int i; int ret, i;
if (!iexec->execute) if (!iexec->execute)
return len; return len;
...@@ -1467,32 +1466,31 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ...@@ -1467,32 +1466,31 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
return -ENODEV; return -ENODEV;
for (i = 0; i < count; i++) { 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 mask = bios->data[offset + 5 + i * 3];
uint8_t data = bios->data[offset + 6 + i * 3]; uint8_t data = bios->data[offset + 6 + i * 3];
uint8_t value; union i2c_smbus_data val;
msg.addr = i2c_address; ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
msg.flags = I2C_M_RD; I2C_SMBUS_READ, reg,
msg.len = 1; I2C_SMBUS_BYTE_DATA, &val);
msg.buf = &value; if (ret < 0)
if (i2c_transfer(&chan->adapter, &msg, 1) != 1) return ret;
return -EIO;
BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
"Mask: 0x%02X, Data: 0x%02X\n", "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) { val.byte &= mask;
msg.addr = i2c_address; val.byte |= data;
msg.flags = 0; ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
msg.len = 1; I2C_SMBUS_WRITE, reg,
msg.buf = &value; I2C_SMBUS_BYTE_DATA, &val);
if (i2c_transfer(&chan->adapter, &msg, 1) != 1) if (ret < 0)
return -EIO; return ret;
}
} }
return len; return len;
...@@ -1518,12 +1516,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ...@@ -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_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]; uint8_t count = bios->data[offset + 3];
int len = 4 + count * 2;
struct nouveau_i2c_chan *chan; struct nouveau_i2c_chan *chan;
struct i2c_msg msg; int len = 4 + count * 2;
int i; int ret, i;
if (!iexec->execute) if (!iexec->execute)
return len; return len;
...@@ -1537,20 +1534,22 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ...@@ -1537,20 +1534,22 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
return -ENODEV; return -ENODEV;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; uint8_t reg = bios->data[offset + 4 + i * 2];
uint8_t data = bios->data[offset + 5 + 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", BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n",
offset, i2c_reg, data); offset, reg, val.byte);
if (bios->execute) { if (!bios->execute)
msg.addr = i2c_address; continue;
msg.flags = 0;
msg.len = 1; ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
msg.buf = &data; I2C_SMBUS_WRITE, reg,
if (i2c_transfer(&chan->adapter, &msg, 1) != 1) I2C_SMBUS_BYTE_DATA, &val);
return -EIO; if (ret < 0)
} return ret;
} }
return len; return len;
...@@ -1574,7 +1573,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) ...@@ -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_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]; uint8_t count = bios->data[offset + 3];
int len = 4 + count; int len = 4 + count;
struct nouveau_i2c_chan *chan; struct nouveau_i2c_chan *chan;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment