diff options
author | Yi Sun <yi.sun@intel.com> | 2011-08-03 23:31:19 +0800 |
---|---|---|
committer | Yi Sun <yi.sun@intel.com> | 2011-08-03 23:31:19 +0800 |
commit | 38b003efdb505da87a882f5c96807bbe2e9101ec (patch) | |
tree | cf518cb60cb99e8145406a8bf9b208df17b01091 | |
parent | 9235677fa10c631e8dd4a652234d761aad667f8f (diff) |
Basicly finished the rewrite.
-rw-r--r--[-rwxr-xr-x] | testedid.c | 910 |
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; } |