* Fixed a warning.
* Removed unused include. * Minor cleanup to match our style guide better. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19575 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,43 +1,50 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2003, Thomas Kurschel
|
* Copyright (c) 2003, Thomas Kurschel. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
Part of DDC driver
|
Part of DDC driver
|
||||||
|
|
||||||
EDID decoder.
|
EDID decoder.
|
||||||
|
|
||||||
The EDID information is tightly packed; this file takes care of
|
The EDID information is tightly packed; this file takes care of
|
||||||
converting it to a usable structure.
|
converting it to a usable structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "edid.h"
|
#include "edid.h"
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include "ddc_int.h"
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// from hereon a bunch of decoders follow for each EDID section
|
// from hereon a bunch of decoders follow for each EDID section
|
||||||
//
|
//
|
||||||
|
|
||||||
static void decode_vendor( edid1_vendor *vendor, const edid1_vendor_raw *raw )
|
static void
|
||||||
|
decode_vendor(edid1_vendor *vendor, const edid1_vendor_raw *raw)
|
||||||
{
|
{
|
||||||
vendor->manufacturer[0] = raw->c1 + '@';
|
vendor->manufacturer[0] = raw->c1 + '@';
|
||||||
vendor->manufacturer[1] =
|
vendor->manufacturer[1] = ((raw->c2_high << 3) | raw->c2_low) + '@';
|
||||||
((raw->c2_high << 3) | raw->c2_low) + '@';
|
|
||||||
vendor->manufacturer[2] = raw->c3 + '@';
|
vendor->manufacturer[2] = raw->c3 + '@';
|
||||||
vendor->manufacturer[3] = 0;
|
vendor->manufacturer[3] = 0;
|
||||||
vendor->prod_id = B_LENDIAN_TO_HOST_INT16( raw->prod_id );
|
vendor->prod_id = B_LENDIAN_TO_HOST_INT16(raw->prod_id);
|
||||||
vendor->serial = B_LENDIAN_TO_HOST_INT32( raw->serial );
|
vendor->serial = B_LENDIAN_TO_HOST_INT32(raw->serial);
|
||||||
vendor->week = raw->week;
|
vendor->week = raw->week;
|
||||||
vendor->year = raw->year + 1990;
|
vendor->year = raw->year + 1990;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_version( edid1_version *version, const edid1_version_raw *raw )
|
|
||||||
|
static void
|
||||||
|
decode_version(edid1_version *version, const edid1_version_raw *raw)
|
||||||
{
|
{
|
||||||
version->version = raw->version;
|
version->version = raw->version;
|
||||||
version->revision = raw->revision;
|
version->revision = raw->revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_display( edid1_display *display, const edid1_display_raw *raw )
|
|
||||||
|
static void
|
||||||
|
decode_display(edid1_display *display, const edid1_display_raw *raw)
|
||||||
{
|
{
|
||||||
display->input_type = raw->input_type;
|
display->input_type = raw->input_type;
|
||||||
display->input_voltage = raw->input_voltage;
|
display->input_voltage = raw->input_voltage;
|
||||||
@@ -46,7 +53,7 @@ static void decode_display( edid1_display *display, const edid1_display_raw *raw
|
|||||||
display->comp_sync = raw->comp_sync;
|
display->comp_sync = raw->comp_sync;
|
||||||
display->sync_on_green = raw->sync_on_green;
|
display->sync_on_green = raw->sync_on_green;
|
||||||
display->sync_serr = raw->sync_serr;
|
display->sync_serr = raw->sync_serr;
|
||||||
|
|
||||||
display->h_size = raw->h_size;
|
display->h_size = raw->h_size;
|
||||||
display->v_size = raw->v_size;
|
display->v_size = raw->v_size;
|
||||||
display->gamma = raw->gamma;
|
display->gamma = raw->gamma;
|
||||||
@@ -69,45 +76,50 @@ static void decode_display( edid1_display *display, const edid1_display_raw *raw
|
|||||||
display->white_y = ((uint16)raw->white_y << 2) | raw->white_y_low;
|
display->white_y = ((uint16)raw->white_y << 2) | raw->white_y_low;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_std_timing( edid1_std_timing *timing,
|
|
||||||
const edid1_std_timing_raw *raw )
|
static void
|
||||||
|
decode_std_timing(edid1_std_timing *timing, const edid1_std_timing_raw *raw)
|
||||||
{
|
{
|
||||||
timing->h_size = (raw->timing.h_size + 31) * 8;
|
timing->h_size = (raw->timing.h_size + 31) * 8;
|
||||||
timing->ratio = raw->timing.ratio;
|
timing->ratio = raw->timing.ratio;
|
||||||
switch( raw->timing.ratio ) {
|
|
||||||
case 0:
|
switch (raw->timing.ratio) {
|
||||||
timing->v_size = timing->h_size;
|
case 0:
|
||||||
break;
|
timing->v_size = timing->h_size;
|
||||||
case 1:
|
break;
|
||||||
timing->v_size = timing->h_size * 3 / 4;
|
case 1:
|
||||||
break;
|
timing->v_size = timing->h_size * 3 / 4;
|
||||||
case 2:
|
break;
|
||||||
timing->v_size = timing->h_size * 4 / 5;
|
case 2:
|
||||||
break;
|
timing->v_size = timing->h_size * 4 / 5;
|
||||||
case 3:
|
break;
|
||||||
timing->v_size = timing->h_size * 9 / 16;
|
case 3:
|
||||||
break;
|
timing->v_size = timing->h_size * 9 / 16;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
timing->refresh = raw->timing.refresh + 60;
|
timing->refresh = raw->timing.refresh + 60;
|
||||||
timing->id = raw->id;
|
timing->id = raw->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_whitepoint( edid1_whitepoint *whitepoint,
|
|
||||||
const edid1_whitepoint_raw *raw )
|
static void
|
||||||
|
decode_whitepoint(edid1_whitepoint *whitepoint, const edid1_whitepoint_raw *raw)
|
||||||
{
|
{
|
||||||
whitepoint[0].index = raw->index1;
|
whitepoint[0].index = raw->index1;
|
||||||
whitepoint[0].white_x = ((uint16)raw->white_x1 << 2) | raw->white_x1_low;
|
whitepoint[0].white_x = ((uint16)raw->white_x1 << 2) | raw->white_x1_low;
|
||||||
whitepoint[0].white_y = ((uint16)raw->white_y1 << 2) | raw->white_y1_low;
|
whitepoint[0].white_y = ((uint16)raw->white_y1 << 2) | raw->white_y1_low;
|
||||||
whitepoint[0].gamma = raw->gamma1;
|
whitepoint[0].gamma = raw->gamma1;
|
||||||
|
|
||||||
whitepoint[1].index = raw->index2;
|
whitepoint[1].index = raw->index2;
|
||||||
whitepoint[1].white_x = ((uint16)raw->white_x2 << 2) | raw->white_x2_low;
|
whitepoint[1].white_x = ((uint16)raw->white_x2 << 2) | raw->white_x2_low;
|
||||||
whitepoint[1].white_y = ((uint16)raw->white_y2 << 2) | raw->white_y2_low;
|
whitepoint[1].white_y = ((uint16)raw->white_y2 << 2) | raw->white_y2_low;
|
||||||
whitepoint[1].gamma = raw->gamma2;
|
whitepoint[1].gamma = raw->gamma2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_detailed_timing( edid1_detailed_timing *timing,
|
|
||||||
const edid1_detailed_timing_raw *raw )
|
static void
|
||||||
|
decode_detailed_timing( edid1_detailed_timing *timing,
|
||||||
|
const edid1_detailed_timing_raw *raw)
|
||||||
{
|
{
|
||||||
timing->pixel_clock = raw->pixel_clock;
|
timing->pixel_clock = raw->pixel_clock;
|
||||||
timing->h_active = ((uint16)raw->h_active_high << 8) | raw->h_active;
|
timing->h_active = ((uint16)raw->h_active_high << 8) | raw->h_active;
|
||||||
@@ -128,96 +140,105 @@ static void decode_detailed_timing( edid1_detailed_timing *timing,
|
|||||||
timing->misc = raw->misc;
|
timing->misc = raw->misc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy string until 0xa, removing trailing spaces
|
|
||||||
static void copy_str( char *dest, const uint8 *src, size_t len )
|
//! copy string until 0xa, removing trailing spaces
|
||||||
|
static void
|
||||||
|
copy_str(char *dest, const uint8 *src, size_t len)
|
||||||
{
|
{
|
||||||
int i;
|
uint32 i;
|
||||||
|
|
||||||
// copy until 0xa
|
// copy until 0xa
|
||||||
for( i = 0; i < len; ++i ) {
|
for (i = 0; i < len; ++i) {
|
||||||
if( *src == 0xa )
|
if (*src == 0xa)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
*dest++ = *src++;
|
*dest++ = *src++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove trailing spaces
|
// remove trailing spaces
|
||||||
for( i = i - 1; i >= 0; --i ) {
|
for (i = i - 1; i >= 0; --i) {
|
||||||
if( *dest-- != ' ' )
|
if (*dest-- != ' ')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*++dest = 0;
|
*++dest = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void decode_detailed_monitor( edid1_detailed_monitor *monitor,
|
|
||||||
const edid1_detailed_monitor_raw *raw, bool enable_extra )
|
static void
|
||||||
|
decode_detailed_monitor( edid1_detailed_monitor *monitor,
|
||||||
|
const edid1_detailed_monitor_raw *raw, bool enableExtra)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for( i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i, ++monitor, ++raw ) {
|
for (i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i, ++monitor, ++raw) {
|
||||||
monitor->monitor_desc_type = edid1_is_detailed_timing;
|
monitor->monitor_desc_type = edid1_is_detailed_timing;
|
||||||
|
|
||||||
// workaround: normally, all four bytes must be zero for detailed
|
// workaround: normally, all four bytes must be zero for detailed
|
||||||
// description, but at least some Formac monitors violate that:
|
// description, but at least some Formac monitors violate that:
|
||||||
// they have some additional info that start at zero_4(!),
|
// they have some additional info that start at zero_4(!),
|
||||||
// so even if only the first two _or_ the other two bytes are
|
// so even if only the first two _or_ the other two bytes are
|
||||||
// zero, we accept it as a monitor description block
|
// zero, we accept it as a monitor description block
|
||||||
if( enable_extra &&
|
if (enableExtra
|
||||||
((raw->extra.zero_0[0] == 0 && raw->extra.zero_0[1] == 0) ||
|
&& ((raw->extra.zero_0[0] == 0 && raw->extra.zero_0[1] == 0)
|
||||||
(raw->extra.zero_0[2] == 0 && raw->extra.zero_4 == 0)) )
|
|| (raw->extra.zero_0[2] == 0 && raw->extra.zero_4 == 0))) {
|
||||||
{
|
|
||||||
monitor->monitor_desc_type = raw->extra.monitor_desc_type;
|
monitor->monitor_desc_type = raw->extra.monitor_desc_type;
|
||||||
|
|
||||||
switch( raw->extra.monitor_desc_type ) {
|
switch (raw->extra.monitor_desc_type) {
|
||||||
case edid1_serial_number:
|
case edid1_serial_number:
|
||||||
copy_str( monitor->data.serial_number,
|
copy_str( monitor->data.serial_number,
|
||||||
raw->extra.data.serial_number, EDID1_EXTRA_STRING_LEN );
|
raw->extra.data.serial_number, EDID1_EXTRA_STRING_LEN );
|
||||||
break;
|
break;
|
||||||
case edid1_ascii_data:
|
case edid1_ascii_data:
|
||||||
copy_str( monitor->data.ascii_data,
|
copy_str( monitor->data.ascii_data,
|
||||||
raw->extra.data.ascii_data, EDID1_EXTRA_STRING_LEN );
|
raw->extra.data.ascii_data, EDID1_EXTRA_STRING_LEN );
|
||||||
break;
|
break;
|
||||||
case edid1_monitor_ranges:
|
case edid1_monitor_ranges:
|
||||||
monitor->data.monitor_range = raw->extra.data.monitor_range;
|
monitor->data.monitor_range = raw->extra.data.monitor_range;
|
||||||
break;
|
break;
|
||||||
case edid1_monitor_name:
|
case edid1_monitor_name:
|
||||||
copy_str( monitor->data.monitor_name,
|
copy_str( monitor->data.monitor_name,
|
||||||
raw->extra.data.monitor_name, EDID1_EXTRA_STRING_LEN );
|
raw->extra.data.monitor_name, EDID1_EXTRA_STRING_LEN );
|
||||||
break;
|
break;
|
||||||
case edid1_add_colour_pointer:
|
case edid1_add_colour_pointer:
|
||||||
decode_whitepoint( monitor->data.whitepoint,
|
decode_whitepoint( monitor->data.whitepoint,
|
||||||
&raw->extra.data.whitepoint );
|
&raw->extra.data.whitepoint );
|
||||||
break;
|
break;
|
||||||
case edid1_add_std_timing:
|
case edid1_add_std_timing:
|
||||||
for( j = 0; j < EDID1_NUM_EXTRA_STD_TIMING; ++j )
|
for (j = 0; j < EDID1_NUM_EXTRA_STD_TIMING; ++j) {
|
||||||
decode_std_timing( &monitor->data.std_timing[j],
|
decode_std_timing(&monitor->data.std_timing[j],
|
||||||
&raw->extra.data.std_timing[j] );
|
&raw->extra.data.std_timing[j]);
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
decode_detailed_timing( &monitor->data.detailed_timing,
|
decode_detailed_timing(&monitor->data.detailed_timing,
|
||||||
&raw->detailed_timing );
|
&raw->detailed_timing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// main function to decode edid data
|
|
||||||
void edid_decode( edid1_info *edid, const edid1_raw *raw )
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
//! main function to decode edid data
|
||||||
|
void
|
||||||
|
edid_decode(edid1_info *edid, const edid1_raw *raw)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
memset(edid, 0, sizeof(edid));
|
||||||
|
|
||||||
|
decode_vendor(&edid->vendor, &raw->vendor);
|
||||||
|
decode_version(&edid->version, &raw->version);
|
||||||
|
decode_display(&edid->display, &raw->display);
|
||||||
|
|
||||||
memset( edid, 0, sizeof( edid ));
|
|
||||||
|
|
||||||
decode_vendor( &edid->vendor, &raw->vendor );
|
|
||||||
decode_version( &edid->version, &raw->version );
|
|
||||||
decode_display( &edid->display, &raw->display );
|
|
||||||
|
|
||||||
edid->established_timing = raw->established_timing;
|
edid->established_timing = raw->established_timing;
|
||||||
|
|
||||||
for( i = 0; i < EDID1_NUM_STD_TIMING; ++i )
|
for (i = 0; i < EDID1_NUM_STD_TIMING; ++i) {
|
||||||
decode_std_timing( &edid->std_timing[i], &raw->std_timing[i] );
|
decode_std_timing(&edid->std_timing[i], &raw->std_timing[i]);
|
||||||
|
}
|
||||||
|
|
||||||
decode_detailed_monitor( edid->detailed_monitor, raw->detailed_monitor,
|
decode_detailed_monitor(edid->detailed_monitor, raw->detailed_monitor,
|
||||||
edid->version.version == 1 && edid->version.revision >= 1 );
|
edid->version.version == 1 && edid->version.revision >= 1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user