summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2009-10-02 15:47:31 -0400
committerAdam Jackson <ajax@redhat.com>2009-10-02 15:47:31 -0400
commit485ba446deaa76204a1aae2ef601a1fc3375034b (patch)
treedc73adaac7da3119b598578d2408540e1ad44e61
parentbd43914f8f614ca176afe0eebeccf38c8bb9d547 (diff)
EDID detailed standard mode decode
-rw-r--r--edid.c64
1 files changed, 39 insertions, 25 deletions
diff --git a/edid.c b/edid.c
index 0ddcd0f..bf8a565 100644
--- a/edid.c
+++ b/edid.c
@@ -151,13 +151,30 @@ edid_standard_get_vsize(uint8_t *block, uint32_t hsize, uint32_t aspect)
}
}
+static int
+bad_standard_code(uint8_t b1, uint8_t b2)
+{
+ return (b1 == 0x00 && b2 == 0x00) ||
+ (b1 == 0x01 && b2 == 0x01) ||
+ (b1 == 0x20 && b2 == 0x20);
+}
+
static struct mt_mode *
-edid_standard_mode(uint8_t *block, uint32_t hsize, uint32_t aspect,
- uint32_t refresh)
+edid_standard_mode(uint8_t *block, uint8_t *x)
{
struct mt_mode *mode;
- uint32_t vsize = edid_standard_get_vsize(block, hsize, aspect);
- uint32_t rb = edid_monitor_supports_reduced_blanking(block);
+ uint32_t hsize, vsize, aspect, refresh;
+ uint32_t rb;
+
+ if (bad_standard_code(x[0], x[1]))
+ return NULL;
+
+ hsize = (x[0] + 31) * 8;
+ aspect = (x[1] >> 6) & 0x3;
+ refresh = 60 + (x[1] & 0x3f);
+
+ vsize = edid_standard_get_vsize(block, hsize, aspect);
+ rb = edid_monitor_supports_reduced_blanking(block);
if (hsize == 1360 && vsize == 765 && refresh == 60) {
mode = mt_cvt_mode(1366, 768, 60, 0);
@@ -181,31 +198,14 @@ edid_standard_mode(uint8_t *block, uint32_t hsize, uint32_t aspect,
return NULL;
}
-static int
-bad_standard_code(uint8_t b1, uint8_t b2)
-{
- return (b1 == 0x00 && b2 == 0x00) ||
- (b1 == 0x01 && b2 == 0x01) ||
- (b1 == 0x20 && b2 == 0x20);
-}
-
static struct mt_mode *
edid_standard_modes(struct mt_monitor *mon, struct mt_mode *list)
{
uint8_t i, *block = mon->block;
- for (i = 0; i < 8; i++) {
- uint8_t b1 = block[0x26 + i * 2], b2 = block[0x26 + i * 2 + 1];
-
- if (bad_standard_code(b1, b2))
- continue;
-
+ for (i = 0; i < 8; i++)
list = mt_modes_add(list,
- edid_standard_mode(block,
- (b1 + 31) * 8,
- (b2 >> 6) & 0x3,
- 60 + (b2 & 0x3f)));
- }
+ edid_standard_mode(block, block + (0x26 + i * 2)));
return list;
}
@@ -369,6 +369,18 @@ edid_cvt_modes(uint8_t *x)
}
static struct mt_mode *
+edid_detailed_standard_modes(uint8_t *block, uint8_t *x)
+{
+ struct mt_mode *ret = NULL;
+ uint8_t i;
+
+ for (i = 0; i < 6; i++)
+ ret = mt_modes_add(ret, edid_standard_mode(block, x + i*2));
+
+ return ret;
+}
+
+static struct mt_mode *
edid_do_detailed_mode(uint8_t *x)
{
uint32_t ha, hbl, hso, hspw, hborder, va, vbl, vso, vspw, vborder;
@@ -420,7 +432,7 @@ edid_do_detailed_mode(uint8_t *x)
}
static struct mt_mode *
-edid_do_detailed_block(uint8_t *x)
+edid_do_detailed_block(uint8_t *block, uint8_t *x)
{
if (x[0] == 0 && x[1] == 0) {
switch (x[3]) {
@@ -429,6 +441,7 @@ edid_do_detailed_block(uint8_t *x)
case 0xF8: /* CVT */
return edid_cvt_modes(x);
case 0xFA: /* standard */
+ return edid_detailed_standard_modes(block, x + 6);
default:
return NULL;
}
@@ -445,7 +458,8 @@ edid_detailed_block_modes(struct mt_monitor *mon, struct mt_mode *list)
for (i = 0; i < 4; i++)
list = mt_modes_add(list,
- edid_do_detailed_block(block + 0x36 + (i*18)));
+ edid_do_detailed_block(block,
+ block + 0x36 + (i*18)));
return list;
}