1 /* 2 * Copyright 2003, Thomas Kurschel. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 /*! 7 DDC communication 8 */ 9 10 11 #include "ddc_int.h" 12 #include "ddc.h" 13 #include "i2c.h" 14 15 #include <KernelExport.h> 16 #include <OS.h> 17 18 #include <stdlib.h> 19 20 21 #define READ_RETRIES 4 22 // number of retries to read ddc data 23 24 #if 0 25 /*! Verify checksum of ddc data 26 (some monitors have a broken checksum - bad luck for them) 27 */ 28 static status_t 29 verify_checksum(const uint8 *data, size_t len) 30 { 31 uint32 index; 32 uint8 sum = 0; 33 uint8 all_or = 0; 34 35 for (index = 0; index < len; ++index, ++data) { 36 sum += *data; 37 all_or |= *data; 38 } 39 40 if (all_or == 0) { 41 SHOW_ERROR0(2, "DDC information contains zeros only"); 42 return B_ERROR; 43 } 44 45 if (sum != 0) { 46 SHOW_ERROR0(2, "Checksum error of DDC information"); 47 return B_IO_ERROR; 48 } 49 50 return B_OK; 51 } 52 #endif 53 54 55 //! Read ddc2 data from monitor 56 static status_t 57 ddc2_read(const i2c_bus *bus, int start, uint8 *buffer, size_t length) 58 { 59 status_t status = B_OK; 60 uint8 writeBuffer[2]; 61 int i; 62 63 writeBuffer[0] = start & 0xff; 64 writeBuffer[1] = (start >> 8) & 0xff; 65 66 for (i = 0; i < READ_RETRIES; ++i) { 67 status = i2c_send_receive(bus, 0xa0, writeBuffer, 68 start < 0x100 ? 1 : 2, buffer, length); 69 // don't verify checksum - it's often broken 70 if (status == B_OK /*&& verify_checksum( buffer, len ) == B_OK*/) 71 break; 72 73 status = B_ERROR; 74 } 75 76 return status; 77 } 78 79 80 /*! 81 Reading VDIF has not been tested. 82 it seems that almost noone supports VDIF which makes testing hard, 83 but what's the point anyway? 84 */ 85 #if 0 86 static status_t 87 ddc2_read_vdif(const i2c_bus *bus, int start, 88 void **vdif, size_t *vdif_len) 89 { 90 status_t res; 91 uint8 *data, *cur_data; 92 int i; 93 uint8 buffer[64]; 94 95 *vdif = NULL; 96 *vdif_len = 0; 97 98 res = ddc2_read(bus, start, buffer, 64); 99 SHOW_INFO(2, "%x", buffer[0]); 100 if (res != B_OK || buffer[0] == 0) 101 return B_OK; 102 103 // each block is 63 bytes plus 1 checksum long 104 // we strip the checksum but store data directly into 105 // buffer, so we need an extra byte for checksum of the last block 106 data = malloc(buffer[0] * 63 + 1); 107 if (data == NULL) 108 return B_NO_MEMORY; 109 110 cur_data = data; 111 for (i = 0; i < buffer[0]; ++i) { 112 ddc2_read(bus, start + i * 64, cur_data, 64); 113 // strip checksum byte 114 cur_data += 63; 115 } 116 117 *vdif_len = buffer[0] * 63; 118 *vdif = data; 119 return B_OK; 120 } 121 #endif 122 123 124 void 125 ddc2_init_timing(i2c_bus *bus) 126 { 127 i2c_get100k_timing(&bus->timing); 128 129 // VESA standard 130 bus->timing.start_timeout = 550; 131 bus->timing.byte_timeout = 2200; 132 bus->timing.bit_timeout = 40; 133 bus->timing.ack_start_timeout = 40; 134 bus->timing.ack_timeout = 40; 135 } 136 137 138 //! Read EDID and VDIF from monitor via ddc2 139 status_t 140 ddc2_read_edid1(const i2c_bus *bus, edid1_info *edid, 141 void **vdif, size_t *vdifLength) 142 { 143 edid1_raw raw; 144 status_t status = ddc2_read(bus, 0, (uint8 *)&raw, sizeof(raw)); 145 if (status != B_OK) 146 return status; 147 148 edid_decode(edid, &raw); 149 150 if (vdif != NULL) 151 *vdif = NULL; 152 if (vdifLength != NULL) 153 *vdifLength = 0; 154 155 // skip vdif as long as it's not tested 156 #if 0 157 status = ddc2_read_vdif(bus, sizeof(raw) * (edid->num_sections + 1), 158 vdif, vdifLength); 159 if (status != B_OK) 160 return status; 161 #endif 162 163 return B_OK; 164 } 165