ddc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /* xf86DDC.c
  2. *
  3. * Copyright 1998,1999 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
  4. */
  5. /*
  6. * A note on terminology. DDC1 is the original dumb serial protocol, and
  7. * can only do up to 128 bytes of EDID. DDC2 is I2C-encapsulated and
  8. * introduces extension blocks. EDID is the old display identification
  9. * block, DisplayID is the new one.
  10. */
  11. #ifdef HAVE_XORG_CONFIG_H
  12. #include <xorg-config.h>
  13. #endif
  14. #include "misc.h"
  15. #include "xf86.h"
  16. #include "xf86_OSproc.h"
  17. #include "xf86DDC.h"
  18. #include <string.h>
  19. #define RETRIES 4
  20. typedef enum {
  21. DDCOPT_NODDC1,
  22. DDCOPT_NODDC2,
  23. DDCOPT_NODDC
  24. } DDCOpts;
  25. static const OptionInfoRec DDCOptions[] = {
  26. {DDCOPT_NODDC1, "NoDDC1", OPTV_BOOLEAN, {0}, FALSE},
  27. {DDCOPT_NODDC2, "NoDDC2", OPTV_BOOLEAN, {0}, FALSE},
  28. {DDCOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE},
  29. {-1, NULL, OPTV_NONE, {0}, FALSE},
  30. };
  31. /* DDC1 */
  32. static int
  33. find_start(unsigned int *ptr)
  34. {
  35. unsigned int comp[9], test[9];
  36. int i, j;
  37. for (i = 0; i < 9; i++) {
  38. comp[i] = *(ptr++);
  39. test[i] = 1;
  40. }
  41. for (i = 0; i < 127; i++) {
  42. for (j = 0; j < 9; j++) {
  43. test[j] = test[j] & !(comp[j] ^ *(ptr++));
  44. }
  45. }
  46. for (i = 0; i < 9; i++)
  47. if (test[i])
  48. return i + 1;
  49. return -1;
  50. }
  51. static unsigned char *
  52. find_header(unsigned char *block)
  53. {
  54. unsigned char *ptr, *head_ptr, *end;
  55. unsigned char header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
  56. ptr = block;
  57. end = block + EDID1_LEN;
  58. while (ptr < end) {
  59. int i;
  60. head_ptr = ptr;
  61. for (i = 0; i < 8; i++) {
  62. if (header[i] != *(head_ptr++))
  63. break;
  64. if (head_ptr == end)
  65. head_ptr = block;
  66. }
  67. if (i == 8)
  68. break;
  69. ptr++;
  70. }
  71. if (ptr == end)
  72. return NULL;
  73. return ptr;
  74. }
  75. static unsigned char *
  76. resort(unsigned char *s_block)
  77. {
  78. unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end;
  79. unsigned char tmp;
  80. s_ptr = find_header(s_block);
  81. if (!s_ptr)
  82. return NULL;
  83. s_end = s_block + EDID1_LEN;
  84. d_new = malloc(EDID1_LEN);
  85. if (!d_new)
  86. return NULL;
  87. d_end = d_new + EDID1_LEN;
  88. for (d_ptr = d_new; d_ptr < d_end; d_ptr++) {
  89. tmp = *(s_ptr++);
  90. *d_ptr = tmp;
  91. if (s_ptr == s_end)
  92. s_ptr = s_block;
  93. }
  94. free(s_block);
  95. return d_new;
  96. }
  97. static int
  98. DDC_checksum(const unsigned char *block, int len)
  99. {
  100. int i, result = 0;
  101. int not_null = 0;
  102. for (i = 0; i < len; i++) {
  103. not_null |= block[i];
  104. result += block[i];
  105. }
  106. #ifdef DEBUG
  107. if (result & 0xFF)
  108. ErrorF("DDC checksum not correct\n");
  109. if (!not_null)
  110. ErrorF("DDC read all Null\n");
  111. #endif
  112. /* catch the trivial case where all bytes are 0 */
  113. if (!not_null)
  114. return 1;
  115. return result & 0xFF;
  116. }
  117. static unsigned char *
  118. GetEDID_DDC1(unsigned int *s_ptr)
  119. {
  120. unsigned char *d_block, *d_pos;
  121. unsigned int *s_pos, *s_end;
  122. int s_start;
  123. int i, j;
  124. s_start = find_start(s_ptr);
  125. if (s_start == -1)
  126. return NULL;
  127. s_end = s_ptr + NUM;
  128. s_pos = s_ptr + s_start;
  129. d_block = malloc(EDID1_LEN);
  130. if (!d_block)
  131. return NULL;
  132. d_pos = d_block;
  133. for (i = 0; i < EDID1_LEN; i++) {
  134. for (j = 0; j < 8; j++) {
  135. *d_pos <<= 1;
  136. if (*s_pos) {
  137. *d_pos |= 0x01;
  138. }
  139. s_pos++;
  140. if (s_pos == s_end)
  141. s_pos = s_ptr;
  142. };
  143. s_pos++;
  144. if (s_pos == s_end)
  145. s_pos = s_ptr;
  146. d_pos++;
  147. }
  148. free(s_ptr);
  149. if (d_block && DDC_checksum(d_block, EDID1_LEN)) {
  150. free(d_block);
  151. return NULL;
  152. }
  153. return (resort(d_block));
  154. }
  155. /* fetch entire EDID record; DDC bit needs to be masked */
  156. static unsigned int *
  157. FetchEDID_DDC1(register ScrnInfoPtr pScrn,
  158. register unsigned int (*read_DDC) (ScrnInfoPtr))
  159. {
  160. int count = NUM;
  161. unsigned int *ptr, *xp;
  162. ptr = xp = malloc(sizeof(int) * NUM);
  163. if (!ptr)
  164. return NULL;
  165. do {
  166. /* wait for next retrace */
  167. *xp = read_DDC(pScrn);
  168. xp++;
  169. } while (--count);
  170. return ptr;
  171. }
  172. /* test if DDC1 return 0 if not */
  173. static Bool
  174. TestDDC1(ScrnInfoPtr pScrn, unsigned int (*read_DDC) (ScrnInfoPtr))
  175. {
  176. int old, count;
  177. old = read_DDC(pScrn);
  178. count = HEADER * BITS_PER_BYTE;
  179. do {
  180. /* wait for next retrace */
  181. if (old != read_DDC(pScrn))
  182. break;
  183. } while (count--);
  184. return count;
  185. }
  186. /*
  187. * read EDID record , pass it to callback function to interpret.
  188. * callback function will store it for further use by calling
  189. * function; it will also decide if we need to reread it
  190. */
  191. static unsigned char *
  192. EDIDRead_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDCSpeed,
  193. unsigned int (*read_DDC) (ScrnInfoPtr))
  194. {
  195. unsigned char *EDID_block = NULL;
  196. int count = RETRIES;
  197. if (!read_DDC) {
  198. xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
  199. "chipset doesn't support DDC1\n");
  200. return NULL;
  201. };
  202. if (TestDDC1(pScrn, read_DDC) == -1) {
  203. xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No DDC signal\n");
  204. return NULL;
  205. };
  206. if (DDCSpeed)
  207. DDCSpeed(pScrn, DDC_FAST);
  208. do {
  209. EDID_block = GetEDID_DDC1(FetchEDID_DDC1(pScrn, read_DDC));
  210. count--;
  211. } while (!EDID_block && count);
  212. if (DDCSpeed)
  213. DDCSpeed(pScrn, DDC_SLOW);
  214. return EDID_block;
  215. }
  216. /**
  217. * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC1 are
  218. * unset. EDID information blocks are interpreted and the results returned in
  219. * an xf86MonPtr.
  220. *
  221. * This function does not affect the list of modes used by drivers -- it is up
  222. * to the driver to decide policy on what to do with EDID information.
  223. *
  224. * @return pointer to a new xf86MonPtr containing the EDID information.
  225. * @return NULL if no monitor attached or failure to interpret the EDID.
  226. */
  227. xf86MonPtr
  228. xf86DoEDID_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDC1SetSpeed,
  229. unsigned int (*DDC1Read) (ScrnInfoPtr))
  230. {
  231. unsigned char *EDID_block = NULL;
  232. xf86MonPtr tmp = NULL;
  233. /* Default DDC and DDC1 to enabled. */
  234. Bool noddc = FALSE, noddc1 = FALSE;
  235. OptionInfoPtr options;
  236. options = xnfalloc(sizeof(DDCOptions));
  237. (void) memcpy(options, DDCOptions, sizeof(DDCOptions));
  238. xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
  239. xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
  240. xf86GetOptValBool(options, DDCOPT_NODDC1, &noddc1);
  241. free(options);
  242. if (noddc || noddc1)
  243. return NULL;
  244. OsBlockSignals();
  245. EDID_block = EDIDRead_DDC1(pScrn, DDC1SetSpeed, DDC1Read);
  246. OsReleaseSignals();
  247. if (EDID_block) {
  248. tmp = xf86InterpretEDID(pScrn->scrnIndex, EDID_block);
  249. }
  250. #ifdef DEBUG
  251. else
  252. ErrorF("No EDID block returned\n");
  253. if (!tmp)
  254. ErrorF("Cannot interpret EDID block\n");
  255. #endif
  256. return tmp;
  257. }
  258. /* DDC2 */
  259. static I2CDevPtr
  260. DDC2MakeDevice(I2CBusPtr pBus, int address, const char *name)
  261. {
  262. I2CDevPtr dev = NULL;
  263. if (!(dev = xf86I2CFindDev(pBus, address))) {
  264. dev = xf86CreateI2CDevRec();
  265. dev->DevName = name;
  266. dev->SlaveAddr = address;
  267. dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
  268. dev->StartTimeout = 550;
  269. dev->BitTimeout = 40;
  270. dev->AcknTimeout = 40;
  271. dev->pI2CBus = pBus;
  272. if (!xf86I2CDevInit(dev)) {
  273. xf86DrvMsg(pBus->scrnIndex, X_PROBED, "No DDC2 device\n");
  274. return NULL;
  275. }
  276. }
  277. return dev;
  278. }
  279. static I2CDevPtr
  280. DDC2Init(I2CBusPtr pBus)
  281. {
  282. I2CDevPtr dev = NULL;
  283. /*
  284. * Slow down the bus so that older monitors don't
  285. * miss things.
  286. */
  287. pBus->RiseFallTime = 20;
  288. dev = DDC2MakeDevice(pBus, 0x00A0, "ddc2");
  289. if (xf86I2CProbeAddress(pBus, 0x0060))
  290. DDC2MakeDevice(pBus, 0x0060, "E-EDID segment register");
  291. return dev;
  292. }
  293. /* Mmmm, smell the hacks */
  294. static void
  295. EEDIDStop(I2CDevPtr d)
  296. {
  297. }
  298. /* block is the EDID block number. a segment is two blocks. */
  299. static Bool
  300. DDC2Read(I2CDevPtr dev, int block, unsigned char *R_Buffer)
  301. {
  302. unsigned char W_Buffer[1];
  303. int i, segment;
  304. I2CDevPtr seg;
  305. void (*stop) (I2CDevPtr);
  306. for (i = 0; i < RETRIES; i++) {
  307. /* Stop bits reset the segment pointer to 0, so be careful here. */
  308. segment = block >> 1;
  309. if (segment) {
  310. Bool b;
  311. if (!(seg = xf86I2CFindDev(dev->pI2CBus, 0x0060)))
  312. return FALSE;
  313. W_Buffer[0] = segment;
  314. stop = dev->pI2CBus->I2CStop;
  315. dev->pI2CBus->I2CStop = EEDIDStop;
  316. b = xf86I2CWriteRead(seg, W_Buffer, 1, NULL, 0);
  317. dev->pI2CBus->I2CStop = stop;
  318. if (!b) {
  319. dev->pI2CBus->I2CStop(dev);
  320. continue;
  321. }
  322. }
  323. W_Buffer[0] = (block & 0x01) * EDID1_LEN;
  324. if (xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, EDID1_LEN)) {
  325. if (!DDC_checksum(R_Buffer, EDID1_LEN))
  326. return TRUE;
  327. }
  328. }
  329. return FALSE;
  330. }
  331. /**
  332. * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are
  333. * unset. EDID information blocks are interpreted and the results returned in
  334. * an xf86MonPtr. Unlike xf86DoEDID_DDC[12](), this function will return
  335. * the complete EDID data, including all extension blocks, if the 'complete'
  336. * parameter is TRUE;
  337. *
  338. * This function does not affect the list of modes used by drivers -- it is up
  339. * to the driver to decide policy on what to do with EDID information.
  340. *
  341. * @return pointer to a new xf86MonPtr containing the EDID information.
  342. * @return NULL if no monitor attached or failure to interpret the EDID.
  343. */
  344. xf86MonPtr
  345. xf86DoEEDID(ScrnInfoPtr pScrn, I2CBusPtr pBus, Bool complete)
  346. {
  347. unsigned char *EDID_block = NULL;
  348. xf86MonPtr tmp = NULL;
  349. I2CDevPtr dev = NULL;
  350. /* Default DDC and DDC2 to enabled. */
  351. Bool noddc = FALSE, noddc2 = FALSE;
  352. OptionInfoPtr options;
  353. options = malloc(sizeof(DDCOptions));
  354. if (!options)
  355. return NULL;
  356. memcpy(options, DDCOptions, sizeof(DDCOptions));
  357. xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
  358. xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
  359. xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2);
  360. free(options);
  361. if (noddc || noddc2)
  362. return NULL;
  363. if (!(dev = DDC2Init(pBus)))
  364. return NULL;
  365. EDID_block = calloc(1, EDID1_LEN);
  366. if (!EDID_block)
  367. return NULL;
  368. if (DDC2Read(dev, 0, EDID_block)) {
  369. int i, n = EDID_block[0x7e];
  370. if (complete && n) {
  371. EDID_block = realloc(EDID_block, EDID1_LEN * (1 + n));
  372. for (i = 0; i < n; i++)
  373. DDC2Read(dev, i + 1, EDID_block + (EDID1_LEN * (1 + i)));
  374. }
  375. tmp = xf86InterpretEEDID(pScrn->scrnIndex, EDID_block);
  376. }
  377. if (tmp && complete)
  378. tmp->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
  379. return tmp;
  380. }
  381. /**
  382. * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are
  383. * unset. EDID information blocks are interpreted and the results returned in
  384. * an xf86MonPtr.
  385. *
  386. * This function does not affect the list of modes used by drivers -- it is up
  387. * to the driver to decide policy on what to do with EDID information.
  388. *
  389. * @return pointer to a new xf86MonPtr containing the EDID information.
  390. * @return NULL if no monitor attached or failure to interpret the EDID.
  391. */
  392. xf86MonPtr
  393. xf86DoEDID_DDC2(ScrnInfoPtr pScrn, I2CBusPtr pBus)
  394. {
  395. return xf86DoEEDID(pScrn, pBus, FALSE);
  396. }
  397. /* XXX write me */
  398. static void *
  399. DDC2ReadDisplayID(void)
  400. {
  401. return FALSE;
  402. }
  403. /**
  404. * Attempts to probe the monitor for DisplayID information, if NoDDC and
  405. * NoDDC2 are unset. DisplayID blocks are interpreted and the results
  406. * returned in an xf86MonPtr.
  407. *
  408. * This function does not affect the list of modes used by drivers -- it is up
  409. * to the driver to decide policy on what to do with DisplayID information.
  410. *
  411. * @return pointer to a new xf86MonPtr containing the DisplayID information.
  412. * @return NULL if no monitor attached or failure to interpret the DisplayID.
  413. */
  414. xf86MonPtr
  415. xf86DoDisplayID(ScrnInfoPtr pScrn, I2CBusPtr pBus)
  416. {
  417. unsigned char *did = NULL;
  418. xf86MonPtr tmp = NULL;
  419. I2CDevPtr dev = NULL;
  420. /* Default DDC and DDC2 to enabled. */
  421. Bool noddc = FALSE, noddc2 = FALSE;
  422. OptionInfoPtr options;
  423. options = malloc(sizeof(DDCOptions));
  424. if (!options)
  425. return NULL;
  426. memcpy(options, DDCOptions, sizeof(DDCOptions));
  427. xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
  428. xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
  429. xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2);
  430. free(options);
  431. if (noddc || noddc2)
  432. return NULL;
  433. if (!(dev = DDC2Init(pBus)))
  434. return NULL;
  435. if ((did = DDC2ReadDisplayID())) {
  436. tmp = calloc(1, sizeof(*tmp));
  437. if (!tmp)
  438. return NULL;
  439. tmp->scrnIndex = pScrn->scrnIndex;
  440. tmp->flags |= MONITOR_DISPLAYID;
  441. tmp->rawData = did;
  442. }
  443. return tmp;
  444. }