static bool mxms_checksum(struct drm_device *dev) { u16 size = mxms_headerlen(dev) + mxms_structlen(dev); u8 *mxms = mxms_data(dev), sum = 0; while (size--) sum += *mxms++; if (sum) { MXM_DBG(dev, "checksum invalid\n"); return false; } return true; }
static bool mxms_foreach(struct drm_device *dev, u8 types, bool (*exec)(struct drm_device *, u8 *, void *), void *info) { u8 *mxms = mxms_data(dev); u8 *desc = mxms + mxms_headerlen(dev); u8 *fini = desc + mxms_structlen(dev) - 1; while (desc < fini) { u8 type = desc[0] & 0x0f; u8 headerlen = 0; u8 recordlen = 0; u8 entries = 0; switch (type) { case 0: if (mxms_version(dev) >= 0x0300) headerlen = 8; else headerlen = 6; break; case 1: case 2: case 3: headerlen = 4; break; case 4: headerlen = 4; recordlen = 2; entries = (ROM32(desc[0]) & 0x01f00000) >> 20; break; case 5: headerlen = 8; break; case 6: if (mxms_version(dev) >= 0x0300) { headerlen = 4; recordlen = 8; entries = (desc[1] & 0xf0) >> 4; } else { headerlen = 8; } break; case 7: headerlen = 8; recordlen = 4; entries = desc[1] & 0x07; break; default: MXM_DBG(dev, "unknown descriptor type %d\n", type); return false; }
static bool mxms_foreach(struct drm_device *dev, u8 types, bool (*exec)(struct drm_device *, u8 *, void *), void *info) { u8 *mxms = mxms_data(dev); u8 *desc = mxms + mxms_headerlen(dev); u8 *fini = desc + mxms_structlen(dev) - 1; while (desc < fini) { u8 type = desc[0] & 0x0f; u8 headerlen = 0; u8 recordlen = 0; u8 entries = 0; switch (type) { case 0: /* Output Device Structure */ if (mxms_version(dev) >= 0x0300) headerlen = 8; else headerlen = 6; break; case 1: /* System Cooling Capability Structure */ case 2: /* Thermal Structure */ case 3: /* Input Power Structure */ headerlen = 4; break; case 4: /* GPIO Device Structure */ headerlen = 4; recordlen = 2; entries = (ROM32(desc[0]) & 0x01f00000) >> 20; break; case 5: /* Vendor Specific Structure */ headerlen = 8; break; case 6: /* Backlight Control Structure */ if (mxms_version(dev) >= 0x0300) { headerlen = 4; recordlen = 8; entries = (desc[1] & 0xf0) >> 4; } else { headerlen = 8; } break; case 7: /* Fan Control Structure */ headerlen = 8; recordlen = 4; entries = desc[1] & 0x07; break; default: MXM_DBG(dev, "unknown descriptor type %d\n", type); return false; }
static bool mxms_valid(struct drm_device *dev) { u8 *mxms = mxms_data(dev); if (*(u32 *)mxms != 0x5f4d584d) { MXM_DBG(dev, "signature invalid\n"); return false; } if (!mxms_version(dev) || !mxms_checksum(dev)) return false; return true; }
static u16 mxms_version(struct drm_device *dev) { u8 *mxms = mxms_data(dev); u16 version = (mxms[4] << 8) | mxms[5]; switch (version ) { case 0x0200: case 0x0201: case 0x0300: return version; default: break; } MXM_DBG(dev, "unknown version %d.%d\n", mxms[4], mxms[5]); return 0x0000; }