summaryrefslogtreecommitdiff
path: root/nvkm/subdev/bios/i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'nvkm/subdev/bios/i2c.c')
-rw-r--r--nvkm/subdev/bios/i2c.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/nvkm/subdev/bios/i2c.c b/nvkm/subdev/bios/i2c.c
index cfb9288c6..19ac30b28 100644
--- a/nvkm/subdev/bios/i2c.c
+++ b/nvkm/subdev/bios/i2c.c
@@ -39,6 +39,11 @@ dcb_i2c_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
i2c = nv_ro16(bios, dcb + 4);
}
+ if (i2c && *ver >= 0x41) {
+ nv_warn(bios, "ccb %02x not supported\n", *ver);
+ return 0x0000;
+ }
+
if (i2c && *ver >= 0x30) {
*ver = nv_ro08(bios, i2c + 0);
*hdr = nv_ro08(bios, i2c + 1);
@@ -70,14 +75,19 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info)
u8 ver, len;
u16 ent = dcb_i2c_entry(bios, idx, &ver, &len);
if (ent) {
- info->type = nv_ro08(bios, ent + 3);
- info->share = DCB_I2C_UNUSED;
- if (ver < 0x30) {
- info->type &= 0x07;
+ if (ver >= 0x30) {
+ info->type = nv_ro08(bios, ent + 0x03);
+ } else {
+ info->type = nv_ro08(bios, ent + 0x03) & 0x07;
if (info->type == 0x07)
info->type = DCB_I2C_UNUSED;
}
+ info->drive = DCB_I2C_UNUSED;
+ info->sense = DCB_I2C_UNUSED;
+ info->share = DCB_I2C_UNUSED;
+ info->auxch = DCB_I2C_UNUSED;
+
switch (info->type) {
case DCB_I2C_NV04_BIT:
info->drive = nv_ro08(bios, ent + 0);
@@ -87,12 +97,14 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info)
info->drive = nv_ro08(bios, ent + 1);
return 0;
case DCB_I2C_NVIO_BIT:
- case DCB_I2C_NVIO_AUX:
info->drive = nv_ro08(bios, ent + 0) & 0x0f;
- if (nv_ro08(bios, ent + 1) & 0x01) {
- info->share = nv_ro08(bios, ent + 1) >> 1;
- info->share &= 0x0f;
- }
+ if (nv_ro08(bios, ent + 1) & 0x01)
+ info->share = nv_ro08(bios, ent + 1) >> 1;
+ return 0;
+ case DCB_I2C_NVIO_AUX:
+ info->auxch = nv_ro08(bios, ent + 0) & 0x0f;
+ if (nv_ro08(bios, ent + 1) & 0x01)
+ info->share = info->auxch;
return 0;
case DCB_I2C_UNUSED:
return 0;