diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-05-12 02:30:50 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-05-19 02:22:08 -0400 |
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) | |||
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; |