summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYi Sun <yi.sun@intel.com>2011-08-03 23:31:19 +0800
committerYi Sun <yi.sun@intel.com>2011-08-03 23:31:19 +0800
commit38b003efdb505da87a882f5c96807bbe2e9101ec (patch)
treecf518cb60cb99e8145406a8bf9b208df17b01091
parent9235677fa10c631e8dd4a652234d761aad667f8f (diff)
Basicly finished the rewrite.
-rw-r--r--[-rwxr-xr-x]testedid.c910
1 files changed, 472 insertions, 438 deletions
diff --git a/testedid.c b/testedid.c
index a7e03a8..9e5deac 100755..100644
--- a/testedid.c
+++ b/testedid.c
@@ -1,6 +1,6 @@
/*
* Copyright 2010 Intel Corporation
- * Jesse Barnes <jesse.barnes@intel.com>
+ * Yi Sun <yi.sun@Intel.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -30,12 +30,12 @@
#include <stdio.h>
#include <stddef.h> /*dir */
-#include <sys/types.h>
+#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
-#include <fcntl.h> /*open */
+#include <fcntl.h> /*open */
#include <unistd.h> /*read */
#include <sys/stat.h>
#include "drm_edid.h"
@@ -46,132 +46,281 @@
#define MAXEDID 256
struct mode_line {
- char mode[12];
- int freq;
+ char mode[12];
+ int freq;
};
-int get_card_list(struct dirent *cardlist[])
+union VendorProduct {
+ struct {
+ int c:5;
+ int b:5;
+ int a:5;
+ } idchr;
+ struct {
+ int lb:8;
+ int hb:8;
+ } singlechr;
+};
+
+union VideoInputDefinition {
+ struct {
+ char serrationvsync:1;
+ char syncongreen:1;
+ char compositesync:1;
+ char separatesyncs:1;
+ char blanktoblacksetup:1;
+ char videolevel:2;
+ char analogordigital:1;
+ } inputdef_a;
+
+ struct {
+ char InterfaceStandardSupported:4;
+ char colorbitdepth:3;
+ char analogordigital:1;
+ } inputdef_d;
+};
+
+struct PowerManSupport {
+ char GTFSupport:1;
+ char perfertimemod:1;
+ char stdcolorspace:1;
+ char monchrome:2;
+ char activeoff:1;
+ char suspend:1;
+ char standby:1;
+};
+
+char edid_head[] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
+
+int bitsperprimarycolor[] = {0, 6, 8, 10, 12, 14, 16, 0};
+
+char *interfacetpye[] = {
+ "",
+ "DVI",
+ "HDMI-a",
+ "HDMI-b",
+ "MDDI",
+ "DisplayPort"
+};
+
+struct mode_line estmode[] = {
+ {"1280x1024",75},
+ {"1024x768",75},
+ {"1024x768",70},
+ {"1024x768",60},
+ {"1024x768",87},
+ {"832x624",75},
+ {"800x600",75},
+ {"800x600",72},
+ {"800x600",60},
+ {"800x600",56},
+ {"640x480",75},
+ {"640x480",72},
+ {"640x480",67},
+ {"640x480",60},
+ {"720x400",88},
+ {"720x400",70}
+};
+
+struct StdTiming {
+ int vertfrequency:6;
+ int aspectratio:2;
+};
+
+union PixelClock {
+ struct {
+ int clkl:8;
+ int clkh:8;
+ int :16;
+ } clkchr;
+ int clk;
+};
+
+union Disp {
+ struct {
+ int vdispl:8;
+ int vdisph:4;
+ int :0;
+ } vdispchr;
+ int value;
+};
+
+union Sync {
+ struct {
+ int syncl:8;
+ int synch:2;
+ } syncchr;
+ int value;
+};
+
+union H4bit {
+ struct {
+ char blank:4;
+ char disp:4;
+ } h4bitchr;
+ char value;
+};
+
+union H2bit {
+ struct {
+ char vsync:2;
+ char dsync:2;
+ char hsync:2;
+ } chr;
+ char value;
+};
+
+char *bppinfo[] = {
+ "DVI_Dual",
+ "",
+ "",
+ "DC_Y444",
+ "DC_30bit",
+ "DC_36bit",
+ "DC_48bit",
+ "Supports_AI"
+};
+
+
+static char*
+get_edid(char *edid_file_name)
{
- DIR* drm_dir_ptr;
- struct dirent *dirent_ptr;
- int card_count=0;
- drm_dir_ptr = opendir(EDIDPATH);
+ char *edid_block;
+ int edid_fp;
+ int read_count = 0;
- if(drm_dir_ptr != NULL) {
- dirent_ptr = readdir(drm_dir_ptr);
- while(dirent_ptr) {
- if( strstr(dirent_ptr->d_name,"card0-")>0 ){
- memcpy(cardlist[card_count],dirent_ptr,sizeof(struct dirent));
- card_count++;
- }
- dirent_ptr = readdir(drm_dir_ptr);
- }
- closedir(drm_dir_ptr);
- }
- else
- puts("Couldn't open the directory.");
-
- return card_count;
+ edid_fp = open(edid_file_name,O_RDONLY);
+
+ if (edid_fp < 0) {
+ printf("open edid file error:%s\n", edid_file_name);
+ return NULL;
+ }
+
+ edid_block = (char *)malloc(MAXEDID);
+ memset(edid_block, 0 , MAXEDID);
+
+ read_count = read(edid_fp, edid_block, MAXEDID);
+
+ if (read_count > 0)
+ return edid_block;
+ else
+ return NULL;
}
-int get_edid(char edid_file[],char edid[])
+
+static void print_edid(char *edid)
{
- int edid_fp = open(edid_file,O_RDONLY);
- if(edid_fp < 0) {
- printf("open edid file error:%s\n",edid_file);
- return 1;
+ for (int j=0; j < MAXEDID; j++) {
+ if (j % 16 == 0)
+ printf("\t%04hhx: ", j);
+ if (j % 16 == 8)
+ printf(" ");
+ printf("%02hhx ", *(edid+j));
+ if (j % 16 == 15)
+ printf("\n");
}
- int cun = read(edid_fp, edid, MAXEDID);
- return cun;
+ printf("\n");
}
-int get_connected_card_list(struct dirent *connected_card_list[],char *connected_edid[])
+
+static int
+get_connected_card_list(char *** connected_card_list )
{
- int connecter_count=0;
- struct dirent *cardlist[MAXCARD];
- char edid[MAXEDID];
- char edid_file[MAXFILENAME];
- for(int i=0; i<MAXCARD; i++) {
- cardlist[i] = (struct dirent*)malloc(sizeof(struct dirent));
- }
- int card_count =get_card_list(cardlist);
-
- for (int i=0; i<card_count;i++) {
- memset(edid,0,MAXEDID);
- sprintf(edid_file,"%s%s/edid",EDIDPATH,cardlist[i]->d_name);
- int cun = get_edid(edid_file,edid);
- if(cun !=0) {
- memcpy(connected_card_list[connecter_count],cardlist[i],sizeof(struct dirent));
- memcpy(connected_edid[connecter_count],edid,MAXEDID);
- connecter_count++;
+ struct dirent *dirent_ptr;
+ DIR* drm_dir_ptr;
+ int connected_count = 0;
+ char edid_file[MAXFILENAME];
+ char *new_edid;
+
+ drm_dir_ptr = opendir(EDIDPATH);
+
+ if (drm_dir_ptr == NULL){
+ printf("Error: fail to open the directory %s\n", EDIDPATH);
+ return 1;
+ }
+
+ (*connected_card_list)= malloc(MAXCARD * sizeof(char*));
+ dirent_ptr = readdir(drm_dir_ptr);
+
+ while (dirent_ptr) {
+ if (strstr(dirent_ptr->d_name, "card0-") >0 ) {
+ sprintf(edid_file, "%s%s/edid", EDIDPATH, dirent_ptr->d_name);
+
+ new_edid = get_edid(edid_file);
+
+ if (new_edid != NULL){
+ (*connected_card_list)[connected_count] = malloc(MAXFILENAME);
+ memcpy((*connected_card_list)[connected_count], edid_file, strlen(edid_file) );
+ connected_count++;
+ }
}
- }
+ dirent_ptr = readdir(drm_dir_ptr);
+ }
+ closedir(drm_dir_ptr);
- for(int i=0; i<MAXCARD; i++) {
- if(cardlist[i] != NULL)
- free(cardlist[i]);
- }
- return connecter_count;
+ return connected_count;
}
-void print_edid(char edid[])
+
+static int
+get_connected_edid_list (char ***edid_list)
{
- // printf("\t%0004hhx: ",0);
- for(int j=0;j<MAXEDID;j++) {
- if(j%16 ==0 )
- printf("\t%04hhx: ",j);
- if(j%16 == 8)
- printf(" ");
- printf("%02hhx ",edid[j]);
- if(j%16 ==15)
- printf("\n");
- }
- printf("\n");
+ char **connected_card_list;
+ int connected_count;
+
+ connected_count = get_connected_card_list( & connected_card_list );
+
+ for (int i = 0; i < connected_count; i++)
+ {
+ //sprintf(edid_file, "%s%s/edid", EDIDPATH, dirent_ptr->d_name);
+
+ (*edid_list)[i] = get_edid(connected_card_list[i]);
+ }
+ return connected_count;
}
-char chrmap(char ch)
+
+
+static char chrmap(char ch)
{
- return 'A'+ch-1;
+ return 'A'+ch-1;
}
/*
Get the whole mode line declared in DRM by mode and frequency.
*/
-void find_dmt_mode(struct mode_line* m,struct drm_display_mode* rmode)
+static void find_dmt_mode(struct mode_line* m, struct drm_display_mode* rmode)
{
- for(int i=0;i<sizeof(dmt_modes)/sizeof(struct drm_display_mode);i++) {
- if(strcmp(m->mode,dmt_modes[i].name) == 0 && m->freq==dmt_modes[i].freq) {
- memcpy(rmode,&dmt_modes[i],sizeof(struct drm_display_mode));
- }
- }
+ for (int i=0; i < sizeof(dmt_modes) / sizeof(struct drm_display_mode); i++) {
+ if (strcmp(m->mode, dmt_modes[i].name) == 0 && m->freq==dmt_modes[i].freq) {
+ memcpy(rmode, &dmt_modes[i], sizeof(struct drm_display_mode));
+ }
+ }
}
-void find_est_mode(struct mode_line* m,struct drm_display_mode* rmode)
+static void find_est_mode(struct mode_line* m, struct drm_display_mode* rmode)
{
- for(int i=0;i<16;i++) {
- if(strcmp(m->mode,est_modes[i].name) == 0 && m->freq==est_modes[i].freq) {
- memcpy(rmode,&est_modes[i],sizeof(struct drm_display_mode));
- }
- }
+ for (int i=0; i < 16; i++) {
+ if (strcmp(m->mode, est_modes[i].name) == 0 && m->freq == est_modes[i].freq) {
+ memcpy(rmode, &est_modes[i], sizeof(struct drm_display_mode));
+ }
+ }
}
-int gethdmiblock(char edid[])
+static int gethdmiblock(char edid[])
{
- for(int i=0;i<MAXEDID;i++) {
- if(edid[i] == 0x03 && edid[i+1] == 0x0c && edid[i+2] == 0) {
+ for (int i=0; i < MAXEDID; i++) {
+ if (edid[i] == 0x03 && edid[i+1] == 0x0c && edid[i+2] == 0) {
return i;
- }
+ }
}
return -1;
}
-int check_edid(char edid[])
+static int check_edid(char edid[])
{
- char edid_head[]={0x0,0xff,0xff,0xff,0xff,0xff,0xff,0x0};
- if( memcmp(edid, edid_head,8) !=0) {
+ if( memcmp(edid, edid_head, 8) !=0 ) {
puts("Bad edid file\n");
return 1;
}
return 0;
}
-int parse_edid(char edid[])
+static int parse_edid_vendor_product(char edid[])
{
- if (check_edid(edid))
- return 1;
/*
* Vendor & Product ID: 10 Bytes
* 08h, 09h 2 ID Manufacturer Name Section 3.4.1
@@ -179,26 +328,21 @@ int parse_edid(char edid[])
* 0Ch → 0Fh 4 ID Serial Number Section 3.4.3
* 10h, 11h 2 Week of Manufacture or Model Year Flag,
*/
- union VendorProduct {
- struct {
- int c:5;
- int b:5;
- int a:5;
- } idchr;
- struct {
- int lb:8;
- int hb:8;
- } singlechr;
- } mfid;
- mfid.singlechr.hb = edid[8];
- mfid.singlechr.lb = edid[9];
-
- printf("\tManufactureID: %c%c%c\t",chrmap(mfid.idchr.a),chrmap(mfid.idchr.b),chrmap(mfid.idchr.c));
- printf("\tMonitorID: %hhx%hhx\t",edid[0xb],edid[0xa]);
- printf("\tSerialNumber: %c%c%c%c\n",edid[0xf],edid[0xe],edid[0xd],edid[0xc]);
- printf("\tProductWeek/year: %d/%d\n",edid[0x10],edid[0x11]+1990);
- printf("\tEdidVersion: %hhx.%hhx\n",edid[0x12],edid[0x13]);
+ union VendorProduct mfid;
+ mfid.singlechr.hb = edid[8];
+ mfid.singlechr.lb = edid[9];
+
+ printf("\tManufactureID: %c%c%c\t", chrmap(mfid.idchr.a), chrmap(mfid.idchr.b), chrmap(mfid.idchr.c));
+ printf("\tMonitorID: %hhx%hhx\t", edid[0xb], edid[0xa]);
+ printf("\tSerialNumber: %c%c%c%c\n", edid[0xf], edid[0xe], edid[0xd], edid[0xc]);
+ printf("\tProductWeek/year: %d/%d\n", edid[0x10], edid[0x11]+1990);
+ printf("\tEdidVersion: %hhx.%hhx\n", edid[0x12], edid[0x13]);
+ return 0;
+}
+static int
+parse_edid_video_input(char edid[])
+{
/*
* Address Bit Definitions Description
* 7 _ _ _ _ _ _ _ Video Signal Interface: Bit 7
@@ -243,36 +387,24 @@ int parse_edid(char edid[])
* 14h
* 1 _ _ _ → → → → All remaining values for Bits 3 → 0 are Reserved: Do Not Use
*/
- union VideoInputDefinition {
- struct {
- char serrationvsync:1;
- char syncongreen:1;
- char compositesync:1;
- char separatesyncs:1;
- char blanktoblacksetup:1;
- char videolevel:2;
- char analogordigital:1;
- } inputdef_a;
- struct {
- char InterfaceStandardSupported:4;
- char colorbitdepth:3;
- char analogordigital:1;
- } inputdef_d;
- } inputdef;
- memcpy(&inputdef,&edid[0x14],1);
-
- if(inputdef.inputdef_a.analogordigital) {
- int bitsperprimarycolor[]={0,6,8,10,12,14,16,0};
- char *interfacetpye[]={"","DVI","HDMI-a","HDMI-b","MDDI","DisplayPort"};
- printf("\tMonitorType: %s\n","Digital");
- printf("\tColorBitDepth: %d Bits per Primary Color\n",bitsperprimarycolor[inputdef.inputdef_d.colorbitdepth]);
- printf("\tInterfaceStandardSupported: %s\n",interfacetpye[inputdef.inputdef_d.InterfaceStandardSupported]);
+ union VideoInputDefinition inputdef;
+ memcpy(&inputdef, &edid[0x14], 1);
+
+ if (inputdef.inputdef_a.analogordigital) {
+ printf("\tMonitorType: %s\n", "Digital");
+ printf("\tColorBitDepth: %d Bits per Primary Color\n", bitsperprimarycolor[inputdef.inputdef_d.colorbitdepth]);
+ printf("\tInterfaceStandardSupported: %s\n", interfacetpye[inputdef.inputdef_d.InterfaceStandardSupported]);
}
- else {
- printf("\tMonitorType: %s\n","Analogor");
- printf("\tMaxImagesize: %hhdcm x %hhdcm\n",edid[0x15],edid[0x16]);
- printf("\tMonitorGamma: %.2f\n",((edid[0x17]+100)*1.0/100.0));
+ else {
+ printf("\tMonitorType: %s\n","Analogor");
+ printf("\tMaxImagesize: %hhdcm x %hhdcm\n", edid[0x15], edid[0x16]);
+ printf("\tMonitorGamma: %.2f\n", (edid[0x17] + 100) * 1.0 / 100.0);
}
+
+ return 0;
+}
+static int parse_edid_power_support(char edid[])
+{
/*
* Address Bits Definitions Description
* 7 6 5 _ _ _ _ _ Display Power Management: (See Note 1) Bits 7 → 5
@@ -302,33 +434,28 @@ int parse_edid(char edid[])
* _ _ 1 Display is continuous frequency. (See Note 5) Bit 0
* _ _ 0 Display is non-continuous frequency (multi-mode). Bit 0
*/
- struct {
- char GTFSupport:1;
- char perfertimemod:1;
- char stdcolorspace:1;
- char monchrome:2;
- char activeoff:1;
- char suspend:1;
- char standby:1;
- } powman;
- memcpy(&powman,&edid[0x18],1);
-
- char msg[256];
- memset(msg,0,sizeof(msg));
- memset(msg,0,256);
- if(powman.standby) strcat(msg,"standby ");
- if(powman.suspend) strcat(msg,"suspend ");
- if(powman.activeoff) strcat(msg,"activeoff ");
- if(!(powman.monchrome & 3)) strcat(msg,"monochrome ");
- else if(powman.activeoff & 1) strcat(msg,"RGB ");
- else if(powman.activeoff & 2) strcat(msg,"Non RGB ");
- else if(powman.activeoff & 3) strcat(msg,"Undefineed ");
-
- printf("\tPowerSupport: %s\n",msg);
- printf("\tChromaInfo: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx \n",edid[0x19],edid[0x1a],edid[0x1b],edid[0x1c],edid[0x1d],edid[0x1e],edid[0x1f],edid[0x20],edid[0x21],edid[0x22]);
-
- // char estiming[16][256];
+ struct PowerManSupport powman;
+ memcpy(&powman, &edid[0x18], 1);
+
+ char msg[256];
+ memset(msg, 0, sizeof(msg));
+ memset(msg, 0, 256);
+ if(powman.standby) strcat(msg, "standby ");
+ if(powman.suspend) strcat(msg, "suspend ");
+ if(powman.activeoff) strcat(msg, "activeoff ");
+ if(!(powman.monchrome & 3)) strcat(msg, "monochrome ");
+ else if(powman.activeoff & 1) strcat(msg, "RGB ");
+ else if(powman.activeoff & 2) strcat(msg, "Non RGB ");
+ else if(powman.activeoff & 3) strcat(msg, "Undefineed ");
+
+ printf("\tPowerSupport: %s\n", msg);
+ printf("\tChromaInfo: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx \n", edid[0x19], edid[0x1a], edid[0x1b], edid[0x1c], edid[0x1d], edid[0x1e], edid[0x1f], edid[0x20], edid[0x21], edid[0x22]);
+
+ return 0;
+}
+static int parse_edid_established_timing(char edid[])
+{
/*
* 23h 1 Established Timing I
* 7 720 x 400 @ 70Hz IBM, VGA
@@ -351,49 +478,36 @@ int parse_edid(char edid[])
* 25h 1 Manufacturer's Timings
* 7 1152 x 870 @ 75Hz Apple, Mac II
*/
- struct mode_line estmode[]={
- {"1280x1024",75} ,
- {"1024x768",75} ,
- {"1024x768",70} ,
- {"1024x768",60} ,
- {"1024x768",87} ,
- {"832x624",75} ,
- {"800x600",75} ,
- {"800x600",72} ,
- {"800x600",60} ,
- {"800x600",56} ,
- {"640x480",75} ,
- {"640x480",72} ,
- {"640x480",67} ,
- {"640x480",60} ,
- {"720x400",88} ,
- {"720x400",70}
- };
- struct mode_line curestmode[80];
- printf("\tEstablishedTiming: \n");
- char es = edid[0x24];
- int escount=0;
- for(int i=0;i<8;i++) {
- if(es & 0x01) {
- memcpy(&curestmode[escount],&estmode[i],sizeof(struct mode_line));
- escount++;
- }
- es = es >> 1;
- }
- es = edid[0x23];
- for(int i=0;i<8;i++) {
- if(es & 0x01) {
- memcpy(&curestmode[escount],&estmode[i+8],sizeof(struct mode_line));
- escount++;
- }
- es = es >> 1;
- }
- for(int i=0;i<escount;i++) {
- struct drm_display_mode rmodeline;
- find_est_mode(&curestmode[i],&rmodeline);
- printf("\t\t%s @ %d %d %d %d\n",rmodeline.name,rmodeline.freq,rmodeline.pclock, rmodeline.htot,rmodeline.vtot);
- }
+ struct mode_line curestmode[80];
+ printf("\tEstablishedTiming: \n");
+ char es = edid[0x24];
+ int escount=0;
+ for (int i=0; i < 8; i++) {
+ if (es & 0x01) {
+ memcpy(&curestmode[escount], &estmode[i], sizeof(struct mode_line));
+ escount++;
+ }
+ es = es >> 1;
+ }
+ es = edid[0x23];
+ for (int i=0; i<8; i++) {
+ if (es & 0x01) {
+ memcpy(&curestmode[escount], &estmode[i+8], sizeof(struct mode_line));
+ escount++;
+ }
+ es = es >> 1;
+ }
+ for (int i = 0; i < escount; i++) {
+ struct drm_display_mode rmodeline;
+ find_est_mode(&curestmode[i], &rmodeline);
+ printf("\t\t%s @ %d %d %d %d\n", rmodeline.name, rmodeline.freq, rmodeline.pclock, rmodeline.htot, rmodeline.vtot);
+ }
+
+ return 0;
+}
+static int parse_edid_standar_timing(char edid[])
+{
/*
* 26h 1 256 pixels → 2288 pixels, in increments of 8 pixels
* 00h Reserved: Do not use.
@@ -409,246 +523,166 @@ int parse_edid(char edid[])
* n n n n n n
* Range: 60 Hz → 123Hz
*/
- //char stdtiming[8][256];
- struct {
- int vertfrequency:6;
- int aspectratio:2;
- } stdtiminginfo;
-
- printf("\r\tStandTiming:\n");
- memset(curestmode,0,80*sizeof(struct mode_line));
- escount = 0;
- struct mode_line tdmtmode;
- struct drm_display_mode rmodeline;
- char tmod[20];
- char ratio[2][6];
- for(int i=0;i<8;i++) {
- int tem=0;
- memcpy(&tem,&edid[38+2*i],1);
- memcpy(&stdtiminginfo,&edid[39+2*i],1);
- memset(msg,0,256);
- memset(ratio,0,sizeof(ratio));
- if(!(stdtiminginfo.aspectratio & 3)) strcat(msg,"16:10");
- else if(stdtiminginfo.aspectratio & 1) strcat(msg,"4:3");
- else if(stdtiminginfo.aspectratio & 2) strcat(msg,"5:4");
- else if(stdtiminginfo.aspectratio & 3) strcat(msg,"16:9");
- char *msgp = strstr(msg,":");
- memcpy(ratio[0],msg,msgp-msg);
- memcpy(ratio[1],msgp+1,strlen(msgp));
- int hratio = atoi(ratio[0]);
- int vratio = atoi(ratio[1]);
- if(tem != 1) {
- memset(&rmodeline,0,sizeof(struct drm_display_mode));
- memset(&tdmtmode,0,sizeof(struct mode_line));
- memset(tmod,0,20);
- //sprintf(tmod,"%dx%d",tem*8+248, (int)(((tem*8+248)*1.0*vratio+0.5)/hratio),stdtiminginfo.vertfrequency+60);
- sprintf(tmod,"%dx%d",tem*8+248, (int)(((tem*8+248)*1.0*vratio+0.5)/hratio));
- strcat(tdmtmode.mode,tmod);
- tdmtmode.freq=stdtiminginfo.vertfrequency+60;
-
- // printf("\t\t%s @ %d\n",tdmtmode.mode,tdmtmode.freq);
- find_dmt_mode(&tdmtmode,&rmodeline);
-
- printf("\t\t%s @ %d %d %d %d (%s)\n",rmodeline.name, rmodeline.freq, rmodeline.pclock, rmodeline.htot, rmodeline.vtot, msg);
- }
- }
-/*
- * Value Detailed Timing Definitions
- * (00 01)h → (FF FF)h
- * Stored Value = Pixel clock ÷ 10,000
- * LSB stored in byte 0 and MSB stored in byte 1
- * 0, 1 2 Range: 10 kHz to 655.35 MHz in 10 kHz steps
- * (00 00)h Reserved: Do not use for Detailed Timing Descriptor
- * 2 1 00h → FFh Horizontal Addressable Video in pixels --- contains lower 8 bits
- * 3 1 00h → FFh Horizontal Blanking in pixels --- contains lower 8 bits
- * ({HA}h, {HB}h)
- * where
- * Horizontal Addressable Video in pixels –
- * 4 1 -- stored in Upper Nibble : contains upper 4 bits
- * 0h ≤ HA ≤ Fh and
- * 0h ≤ HB ≤ Fh
- * Horizontal Blanking in pixels --- stored in Lower Nibble : contains
- * upper 4 bits
- * 5 1 00h → FFh Vertical Addressable Video in lines --- contains lower 8 bits
- * 6 1 00h → FFh Vertical Blanking in lines --- contains lower 8 bits
- * ({VA}h, {VB}h)
- * where
- * Vertical Addressable Video in lines -- stored in Upper Nibble :
- * 7 1 contains upper 4 bits
- * 0h ≤ VA ≤ Fh and
- * 0h ≤ VB ≤ Fh
- * Vertical Blanking in lines --- stored in Lower Nibble : contains
- * upper 4 bits
- * 8 1 00h → FFh Horizontal Front Porch in pixels --- contains lower 8 bits
- * 9 1 00h → FFh Horizontal Sync Pulse Width in pixels --- contains lower 8 bits
- * ({VF}h, {VS}h)
- * where
- * Vertical Front Porch in Lines --- stored in Upper Nibble : contains
- * 10 1 lower 4 bits
- * 0h ≤ VF ≤ Fh and
- * 0h ≤ VS ≤ Fh
- * Vertical Sync Pulse Width in Lines --- stored in Lower Nibble :
- * contains lower 4 bits
- * 7 6 5 4 3 2 1 0 Bit Definitions
- * n n _ _ _ _ _ _ Horizontal Front Porch in pixels --- contains upper 2 bits
- * _ _ n n _ _ _ _ Horizontal Sync Pulse Width in Pixels --- contains upper 2 bits
- * _ _ _ _ n n _ _ Vertical Front Porch in lines --- contains upper 2 bits
- * 11 1
- * _ _ _ _ _ _ n n Vertical Sync Pulse Width in lines --- contains upper 2 bits
- * Value Video Image Size & Border Definitions
- * 12 1 00h → FFh Horizontal Addressable Video Image Size in mm --- contains lower
- * 8 bits
- * 13 1 00h → FFh Vertical Addressable Video Image Size in mm --- contains lower 8
- * bits
- * ({HI}h, {VI}h)
- * where
- * Horizontal Addressable Video Image Size in mm --- stored in Upper
- * 14 1 Nibble : contains upper 4 bits
- * 0h ≤ HI ≤ Fh and
- * 0h ≤ VI ≤ Fh
- * Vertical Addressable Video Image Size in mm --- stored in Lower
- * Nibble : contains upper 4 bits
- * 15 1 00h → FFh Right Horizontal Border or Left Horizontal Border in pixels --- refer
- * to Section 3.12 – Right Border is equal to Left Border
- * 16 1 00h → FFh Top Vertical Border or Bottom Vertical Border in Lines --- refer to
- * Section 3.12 – Top Border is equal to Bottom Border
-*/
- union {
- struct {
- int clkl:8;
- int clkh:8;
- int :16;
- }clkchr;
- int clk;
- }pixclk;
-
- union {
- struct {
- int vdispl:8;
- int vdisph:4;
- int :0;
- }vdispchr;
- int value;
- }vdisp;
-
- union {
- struct {
- int syncl:8;
- int synch:2;
- }syncchr;
- int value;
- }sync;
-
- for(int i=0;i<4;i++) {
- int Hdisp,Vdisp,Hblank,Vblank;
- float freq;
- pixclk.clkchr.clkl =edid[0x36 +i*18];
- pixclk.clkchr.clkh=edid[0x37 + i*18];
- if(pixclk.clk == 0) continue;
- //printf("pixel clock: %d\n",pixclk.clk*10);
-
- union {
- struct {
- char blank:4;
- char disp:4;
- }h4bitchr;
- char value;
- }h4bit;
- vdisp.vdispchr.vdispl=edid[0x36+ i*18+ 2];
- h4bit.value = edid[0x36+ i*18+ 4];
- vdisp.vdispchr.vdispl=edid[0x36+ i*18+ 2];
- vdisp.vdispchr.vdisph=h4bit.h4bitchr.disp;
- Hdisp = vdisp.value;
- // printf("Hdisplay: %d\n",vdisp.value);
-
- memset(&h4bit,0,1);
- memset(&vdisp,0,4);
- vdisp.vdispchr.vdispl=edid[0x36+ i*18+ 5];
- h4bit.value = edid[0x36+ i*18+ 7];
- vdisp.vdispchr.vdispl=edid[0x36+ i*18+ 5];
- vdisp.vdispchr.vdisph=h4bit.h4bitchr.disp;
- Vdisp = vdisp.value;
- //printf("Vdisplay: %d\n",vdisp.value);
-
- memset(&h4bit,0,1);
- memset(&vdisp,0,4);
- vdisp.vdispchr.vdispl=edid[0x36+ i*18+ 3];
- h4bit.value = edid[0x36+ i*18+ 4];
- vdisp.vdispchr.vdispl=edid[0x36+ i*18+ 3];
- vdisp.vdispchr.vdisph=h4bit.h4bitchr.blank;
- Hblank = vdisp.value;
- //printf("Hblank:: %d\n",vdisp.value);
-
- memset(&h4bit,0,1);
- memset(&vdisp,0,4);
- vdisp.vdispchr.vdispl=edid[0x36+ i*18+ 6];
- h4bit.value = edid[0x36+ i*18+ 7];
- vdisp.vdispchr.vdispl=edid[0x36+ i*18+ 6];
- vdisp.vdispchr.vdisph=h4bit.h4bitchr.blank;
- Vblank = vdisp.value;
- freq = pixclk.clk*10000.0/(Hdisp+Hblank)/(Vdisp+Vblank);
- //printf("Vblank: %d\n",vdisp.value);
- printf("\tDetailTiming:\n\t\t%dx%d @ %.2f %d %d %d\n",Hdisp,Vdisp,freq,pixclk.clk*10,Hdisp+Hblank,Vdisp+Vblank);
-
- union {
- struct {
- char vsync:2;
- char dsync:2;
- char hsync:2;
- }chr;
- char value;
- }h2bit;
-
- h2bit.value=edid[0x36+i*18+11];
- memset(&sync,0,4);
- sync.syncchr.syncl=edid[0x36+i*18+8];
- sync.syncchr.synch=h2bit.chr.vsync;
- // printf("VSync: %d\n",sync.value);
- }
+ struct StdTiming stdtiminginfo;
+
+ struct mode_line curestmode[80];
+ printf("\r\tStandarTiming:\n");
+ memset(curestmode, 0, 80 * sizeof(struct mode_line));
+// int escount = 0;
+ struct mode_line tdmtmode;
+ struct drm_display_mode rmodeline;
+ char tmod[20];
+ char msg[512];
+ char ratio[2][6];
+ for (int i = 0; i < 8; i++) {
+ int tem = 0;
+ memcpy(&tem, &edid[38 + 2 * i], 1);
+ memcpy(&stdtiminginfo, &edid[39 + 2 * i], 1);
+ memset(msg, 0, 256);
+ memset(ratio, 0, sizeof(ratio));
+ if(!(stdtiminginfo.aspectratio & 3)) strcat(msg, "16:10");
+ else if(stdtiminginfo.aspectratio & 1) strcat(msg, "4:3");
+ else if(stdtiminginfo.aspectratio & 2) strcat(msg, "5:4");
+ else if(stdtiminginfo.aspectratio & 3) strcat(msg, "16:9");
+ char *msgp = strstr(msg, ":");
+ memcpy(ratio[0], msg, msgp-msg);
+ memcpy(ratio[1], msgp+1, strlen(msgp));
+ int hratio = atoi(ratio[0]);
+ int vratio = atoi(ratio[1]);
+ if (tem != 1) {
+ memset(&rmodeline, 0, sizeof(struct drm_display_mode));
+ memset(&tdmtmode, 0, sizeof(struct mode_line));
+ memset(tmod, 0, 20);
+ //sprintf(tmod,"%dx%d",tem*8+248, (int)(((tem*8+248)*1.0*vratio+0.5)/hratio),stdtiminginfo.vertfrequency+60);
+ sprintf(tmod, "%dx%d", tem * 8 + 248, (int)(((tem * 8 + 248) * 1.0 * vratio + 0.5) / hratio));
+ strcat(tdmtmode.mode , tmod);
+ tdmtmode.freq = stdtiminginfo.vertfrequency + 60;
+
+ // printf("\t\t%s @ %d\n",tdmtmode.mode,tdmtmode.freq);
+ find_dmt_mode(&tdmtmode, &rmodeline);
+
+ printf("\t\t%s @ %d %d %d %d (%s)\n", rmodeline.name, rmodeline.freq, rmodeline.pclock, rmodeline.htot, rmodeline.vtot, msg);
+ }
+ }
+ return 0;
+}
+static int parse_edid_detail_timing(char edid[])
+{
+ union PixelClock pixclk;
+ union Disp vdisp;
+ union Sync sync;
+
+ memset(&pixclk, 0, sizeof(union PixelClock));
+ for(int i = 0; i < 4; i++) {
+ int Hdisp, Vdisp, Hblank, Vblank;
+ float freq;
+ pixclk.clkchr.clkl = edid[0x36 + i*18];
+ pixclk.clkchr.clkh = edid[0x37 + i*18];
+ if (pixclk.clk == 0) continue;
+ //printf("pixel clock: %d\n",pixclk.clk*10);
+
+ union H4bit h4bit;
+ vdisp.vdispchr.vdispl = edid[0x36 + i*18 + 2];
+ h4bit.value = edid[0x36 + i*18 + 4];
+ vdisp.vdispchr.vdispl = edid[0x36+ i*18 + 2];
+ vdisp.vdispchr.vdisph = h4bit.h4bitchr.disp;
+ Hdisp = vdisp.value;
+ // printf("Hdisplay: %d\n",vdisp.value);
+
+ memset(&h4bit, 0, 1);
+ memset(&vdisp, 0, 4);
+ vdisp.vdispchr.vdispl=edid[0x36+ i*18 + 5];
+ h4bit.value = edid[0x36+ i*18 + 7];
+ vdisp.vdispchr.vdispl = edid[0x36+ i*18 + 5];
+ vdisp.vdispchr.vdisph = h4bit.h4bitchr.disp;
+ Vdisp = vdisp.value;
+ //printf("Vdisplay: %d\n",vdisp.value);
+
+ memset(&h4bit,0,1);
+ memset(&vdisp,0,4);
+ vdisp.vdispchr.vdispl = edid[0x36+ i*18 + 3];
+ h4bit.value = edid[0x36+ i*18 + 4];
+ vdisp.vdispchr.vdispl = edid[0x36+ i*18 + 3];
+ vdisp.vdispchr.vdisph = h4bit.h4bitchr.blank;
+ Hblank = vdisp.value;
+ //printf("Hblank:: %d\n",vdisp.value);
+
+ memset(&h4bit,0,1);
+ memset(&vdisp,0,4);
+ vdisp.vdispchr.vdispl = edid[0x36+ i*18 + 6];
+ h4bit.value = edid[0x36+ i*18 + 7];
+ vdisp.vdispchr.vdispl = edid[0x36+ i*18 + 6];
+ vdisp.vdispchr.vdisph = h4bit.h4bitchr.blank;
+ Vblank = vdisp.value;
+ freq = pixclk.clk * 10000.0 / (Hdisp+Hblank) / (Vdisp+Vblank);
+ //printf("Vblank: %d\n",vdisp.value);
+ printf("\tDetailTiming:\n\t\t%dx%d @ %.2f %d %d %d\n", Hdisp, Vdisp, freq, pixclk.clk * 10, Hdisp + Hblank, Vdisp + Vblank);
+
+ union H2bit h2bit;
+ h2bit.value = edid[0x36 + i*18 + 11];
+ memset(&sync, 0, 4);
+ sync.syncchr.syncl = edid[0x36 + i*18 + 8];
+ sync.syncchr.synch = h2bit.chr.vsync;
+ // printf("VSync: %d\n",sync.value);
+ }
+ return 0;
+}
+static int parse_edid_hdmi_bpp(char edid[])
+{
/*
* Extended block for HDMI
*/
- char *bppinfo[]={ "DVI_Dual" , "", "", "DC_Y444", "DC_30bit", "DC_36bit", "DC_48bit", "Supports_AI"};
- int phdmiindex = gethdmiblock(edid);
- if(phdmiindex != -1) {
- printf("\tHaving a hdmi block, start position is:%2hhx\n",phdmiindex);
- char bppbyte=edid[phdmiindex + 5];
- for(int i=0;i<8;i++) {
- if(bppbyte & 0x01) {
- printf("\tHDMI bpp supports: %s\n",bppinfo[i]);
- }
- bppbyte = bppbyte >> 1;
- }
- }
+ int phdmiindex = gethdmiblock(edid);
+ if (phdmiindex != -1) {
+ printf("\tHaving a hdmi block, start position is:%2hhx\n", phdmiindex);
+ char bppbyte = edid[phdmiindex + 5];
+ for (int i = 0; i < 8; i++) {
+ if (bppbyte & 0x01) {
+ printf("\tHDMI bpp supports: %s\n", bppinfo[i]);
+ }
+ bppbyte = bppbyte >> 1;
+ }
+ }
return 0;
}
-int main(void)
-{
- struct dirent *cardlist[MAXCARD];
- char *edid[MAXCARD];
- for(int i=0; i<MAXCARD; i++) {
- cardlist[i] = (struct dirent*)malloc(sizeof(struct dirent));
- edid[i] = (char *)malloc(MAXEDID);
- }
-
- int connecter_count = get_connected_card_list(cardlist,edid);
- printf("\33[1;;32mThe connected monitor number: %d\n\33[0m",connecter_count);
-
- for(int i=0;i<connecter_count;i++) {
- printf("\33[1;;32m%d. Connected monitor card: %s\n\33[0m",i+1,cardlist[i]->d_name);
- print_edid(edid[i]);
- parse_edid(edid[i]);
- }
-
- for(int i=0; i<MAXCARD; i++) {
- if(cardlist[i] != NULL)
- free(cardlist[i]);
- if(edid[i] != NULL)
- free(edid[i]);
+static int parse_edid(char edid[])
+{
+ if (check_edid(edid))
+ return 1;
+ parse_edid_vendor_product(edid);
+ parse_edid_video_input(edid);
+ parse_edid_power_support(edid);
+ parse_edid_established_timing(edid);
+ parse_edid_standar_timing(edid);
+ parse_edid_detail_timing(edid);
+ parse_edid_hdmi_bpp(edid);
+ return 0;
+}
+
+
+
+
+int main(void)
+{
+ int connected_count;
+ char **edid_list;
+ char **connected_card_list;
+
+ connected_count = get_connected_edid_list( & edid_list);
+ connected_count = get_connected_card_list( & connected_card_list );
+
+ printf("\33[1;;32mThe connected monitor number: %d\n\33[0m", connected_count);
+
+ for (int i = 0; i < connected_count; i++) {
+ printf("\33[1;;32m%d. Connected monitor card: %s\n\33[0m", 1, connected_card_list[0]);
+
+ print_edid(edid_list[i]);
+ parse_edid(edid_list[i]);
}
+
return 0;
}