aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-05-12 02:30:50 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-05-19 02:22:08 -0400
commit893887ed75cacbfe1a855c63659838e0261d17e8 (patch)
tree76cb9de8fc0886fa3799faeb9560869533c5425e
parent04f542c07e9376c732c72b40de7cdc71801f8cd5 (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.c77
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)
1448 */ 1448 */
1449 1449
1450 uint8_t i2c_index = bios->data[offset + 1]; 1450 uint8_t i2c_index = bios->data[offset + 1];
1451 uint8_t i2c_address = bios->data[offset + 2]; 1451 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1452 uint8_t count = bios->data[offset + 3]; 1452 uint8_t count = bios->data[offset + 3];
1453 int len = 4 + count * 3;
1454 struct nouveau_i2c_chan *chan; 1453 struct nouveau_i2c_chan *chan;
1455 struct i2c_msg msg; 1454 int len = 4 + count * 3;
1456 int i; 1455 int ret, i;
1457 1456
1458 if (!iexec->execute) 1457 if (!iexec->execute)
1459 return len; 1458 return len;
@@ -1467,32 +1466,31 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1467 return -ENODEV; 1466 return -ENODEV;
1468 1467
1469 for (i = 0; i < count; i++) { 1468 for (i = 0; i < count; i++) {
1470 uint8_t i2c_reg = bios->data[offset + 4 + i * 3]; 1469 uint8_t reg = bios->data[offset + 4 + i * 3];
1471 uint8_t mask = bios->data[offset + 5 + i * 3]; 1470 uint8_t mask = bios->data[offset + 5 + i * 3];
1472 uint8_t data = bios->data[offset + 6 + i * 3]; 1471 uint8_t data = bios->data[offset + 6 + i * 3];
1473 uint8_t value; 1472 union i2c_smbus_data val;
1474 1473
1475 msg.addr = i2c_address; 1474 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1476 msg.flags = I2C_M_RD; 1475 I2C_SMBUS_READ, reg,
1477 msg.len = 1; 1476 I2C_SMBUS_BYTE_DATA, &val);
1478 msg.buf = &value; 1477 if (ret < 0)
1479 if (i2c_transfer(&chan->adapter, &msg, 1) != 1) 1478 return ret;
1480 return -EIO;
1481 1479
1482 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, " 1480 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
1483 "Mask: 0x%02X, Data: 0x%02X\n", 1481 "Mask: 0x%02X, Data: 0x%02X\n",
1484 offset, i2c_reg, value, mask, data); 1482 offset, reg, val.byte, mask, data);
1485 1483
1486 value = (value & mask) | data; 1484 if (!bios->execute)
1485 continue;
1487 1486
1488 if (bios->execute) { 1487 val.byte &= mask;
1489 msg.addr = i2c_address; 1488 val.byte |= data;
1490 msg.flags = 0; 1489 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1491 msg.len = 1; 1490 I2C_SMBUS_WRITE, reg,
1492 msg.buf = &value; 1491 I2C_SMBUS_BYTE_DATA, &val);
1493 if (i2c_transfer(&chan->adapter, &msg, 1) != 1) 1492 if (ret < 0)
1494 return -EIO; 1493 return ret;
1495 }
1496 } 1494 }
1497 1495
1498 return len; 1496 return len;
@@ -1518,12 +1516,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1518 */ 1516 */
1519 1517
1520 uint8_t i2c_index = bios->data[offset + 1]; 1518 uint8_t i2c_index = bios->data[offset + 1];
1521 uint8_t i2c_address = bios->data[offset + 2]; 1519 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1522 uint8_t count = bios->data[offset + 3]; 1520 uint8_t count = bios->data[offset + 3];
1523 int len = 4 + count * 2;
1524 struct nouveau_i2c_chan *chan; 1521 struct nouveau_i2c_chan *chan;
1525 struct i2c_msg msg; 1522 int len = 4 + count * 2;
1526 int i; 1523 int ret, i;
1527 1524
1528 if (!iexec->execute) 1525 if (!iexec->execute)
1529 return len; 1526 return len;
@@ -1537,20 +1534,22 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1537 return -ENODEV; 1534 return -ENODEV;
1538 1535
1539 for (i = 0; i < count; i++) { 1536 for (i = 0; i < count; i++) {
1540 uint8_t i2c_reg = bios->data[offset + 4 + i * 2]; 1537 uint8_t reg = bios->data[offset + 4 + i * 2];
1541 uint8_t data = bios->data[offset + 5 + i * 2]; 1538 union i2c_smbus_data val;
1539
1540 val.byte = bios->data[offset + 5 + i * 2];
1542 1541
1543 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n", 1542 BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Data: 0x%02X\n",
1544 offset, i2c_reg, data); 1543 offset, reg, val.byte);
1545 1544
1546 if (bios->execute) { 1545 if (!bios->execute)
1547 msg.addr = i2c_address; 1546 continue;
1548 msg.flags = 0; 1547
1549 msg.len = 1; 1548 ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
1550 msg.buf = &data; 1549 I2C_SMBUS_WRITE, reg,
1551 if (i2c_transfer(&chan->adapter, &msg, 1) != 1) 1550 I2C_SMBUS_BYTE_DATA, &val);
1552 return -EIO; 1551 if (ret < 0)
1553 } 1552 return ret;
1554 } 1553 }
1555 1554
1556 return len; 1555 return len;
@@ -1574,7 +1573,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1574 */ 1573 */
1575 1574
1576 uint8_t i2c_index = bios->data[offset + 1]; 1575 uint8_t i2c_index = bios->data[offset + 1];
1577 uint8_t i2c_address = bios->data[offset + 2]; 1576 uint8_t i2c_address = bios->data[offset + 2] >> 1;
1578 uint8_t count = bios->data[offset + 3]; 1577 uint8_t count = bios->data[offset + 3];
1579 int len = 4 + count; 1578 int len = 4 + count;
1580 struct nouveau_i2c_chan *chan; 1579 struct nouveau_i2c_chan *chan;