3 * Bus should be run at max. 100kHz: see original Philips I2C specification
5 * Rudolf Cornelissen 12/2002-10/2009
8 #define MODULE_BIT 0x00004000
12 static void i2c_DumpSpecsEDID(edid_specs
* specs
);
14 char i2c_flag_error (char ErrNo
)
17 //1 - SCL locked low by device (bus is still busy)
18 //2 - SDA locked low by device (bus is still busy)
19 //3 - No Acknowledge from device (no handshake)
20 //4 - SDA not released for master to generate STOP bit
22 static char I2CError
= 0;
24 if (!I2CError
) I2CError
= ErrNo
;
25 if (ErrNo
== -1) I2CError
= 0;
29 static void i2c_select_bus_set(bool set
)
31 /* I/O pins set selection is only valid on dualhead cards */
32 if (!si
->ps
.secondary_head
) return;
34 /* select GPU I/O pins set to connect to I2C 'registers' */
36 /* this setup wires the 'I2C registers' to unknown I/O pins on the GPU? */
37 NV_REG32(NV32_FUNCSEL
) &= ~0x00000010;
38 NV_REG32(NV32_2FUNCSEL
) |= 0x00000010;
40 /* this setup wires the 'I2C registers' to the I2C buses */
41 NV_REG32(NV32_2FUNCSEL
) &= ~0x00000010;
42 NV_REG32(NV32_FUNCSEL
) |= 0x00000010;
46 static void OutSCL(uint8 BusNR
, bool Bit
)
52 data
= (CRTCR(WR_I2CBUS_0
) & 0xf0) | 0x01;
54 CRTCW(WR_I2CBUS_0
, (data
| 0x20));
56 CRTCW(WR_I2CBUS_0
, (data
& ~0x20));
59 data
= (CRTCR(WR_I2CBUS_1
) & 0xf0) | 0x01;
61 CRTCW(WR_I2CBUS_1
, (data
| 0x20));
63 CRTCW(WR_I2CBUS_1
, (data
& ~0x20));
66 data
= (CRTCR(WR_I2CBUS_2
) & 0xf0) | 0x01;
68 CRTCW(WR_I2CBUS_2
, (data
| 0x20));
70 CRTCW(WR_I2CBUS_2
, (data
& ~0x20));
75 static void OutSDA(uint8 BusNR
, bool Bit
)
81 data
= (CRTCR(WR_I2CBUS_0
) & 0xf0) | 0x01;
83 CRTCW(WR_I2CBUS_0
, (data
| 0x10));
85 CRTCW(WR_I2CBUS_0
, (data
& ~0x10));
88 data
= (CRTCR(WR_I2CBUS_1
) & 0xf0) | 0x01;
90 CRTCW(WR_I2CBUS_1
, (data
| 0x10));
92 CRTCW(WR_I2CBUS_1
, (data
& ~0x10));
95 data
= (CRTCR(WR_I2CBUS_2
) & 0xf0) | 0x01;
97 CRTCW(WR_I2CBUS_2
, (data
| 0x10));
99 CRTCW(WR_I2CBUS_2
, (data
& ~0x10));
104 static bool InSCL(uint8 BusNR
)
108 if ((CRTCR(RD_I2CBUS_0
) & 0x04)) return true;
111 if ((CRTCR(RD_I2CBUS_1
) & 0x04)) return true;
114 if ((CRTCR(RD_I2CBUS_2
) & 0x04)) return true;
121 static bool InSDA(uint8 BusNR
)
125 if ((CRTCR(RD_I2CBUS_0
) & 0x08)) return true;
128 if ((CRTCR(RD_I2CBUS_1
) & 0x08)) return true;
131 if ((CRTCR(RD_I2CBUS_2
) & 0x08)) return true;
138 static void TXBit (uint8 BusNR
, bool Bit
)
140 /* send out databit */
144 if (!InSDA(BusNR
)) i2c_flag_error (2);
146 OutSDA(BusNR
, false);
148 /* generate clock pulse */
152 if (!InSCL(BusNR
)) i2c_flag_error (1);
154 OutSCL(BusNR
, false);
158 static uint8
RXBit (uint8 BusNR
)
162 /* set SDA so input is possible */
164 /* generate clock pulse */
168 if (!InSCL(BusNR
)) i2c_flag_error (1);
171 if (InSDA(BusNR
)) Bit
= 1;
172 /* finish clockpulse */
173 OutSCL(BusNR
, false);
179 void i2c_bstart (uint8 BusNR
)
181 /* enable access to primary head */
184 /* make sure SDA is high */
189 if (!InSCL(BusNR
)) i2c_flag_error (1);
191 /* clear SDA while SCL set (bus-start condition) */
192 OutSDA(BusNR
, false);
194 OutSCL(BusNR
, false);
197 LOG(4,("I2C: START condition generated on bus %d; status is %d\n",
198 BusNR
, i2c_flag_error (0)));
201 void i2c_bstop (uint8 BusNR
)
203 /* enable access to primary head */
206 /* make sure SDA is low */
207 OutSDA(BusNR
, false);
211 if (!InSCL(BusNR
)) i2c_flag_error (1);
213 /* set SDA while SCL set (bus-stop condition) */
216 if (!InSDA(BusNR
)) i2c_flag_error (4);
219 LOG(4,("I2C: STOP condition generated on bus %d; status is %d\n",
220 BusNR
, i2c_flag_error (0)));
223 uint8
i2c_readbyte(uint8 BusNR
, bool Ack
)
225 uint8 cnt
, bit
, byte
= 0;
227 /* enable access to primary head */
231 for (cnt
= 8; cnt
> 0; cnt
--) {
236 /* send acknowledge */
239 LOG(4,("I2C: read byte ($%02x) from bus #%d; status is %d\n",
240 byte
, BusNR
, i2c_flag_error(0)));
245 bool i2c_writebyte (uint8 BusNR
, uint8 byte
)
251 /* enable access to primary head */
255 for (cnt
= 8; cnt
> 0; cnt
--) {
260 /* read acknowledge */
262 if (bit
) i2c_flag_error (3);
264 LOG(4,("I2C: written byte ($%02x) to bus #%d; status is %d\n",
265 byte
, BusNR
, i2c_flag_error(0)));
270 void i2c_readbuffer (uint8 BusNR
, uint8
* buf
, uint8 size
)
274 for (cnt
= 0; cnt
< size
; cnt
++)
275 buf
[cnt
] = i2c_readbyte(BusNR
, buf
[cnt
]);
278 void i2c_writebuffer (uint8 BusNR
, uint8
* buf
, uint8 size
)
282 for (cnt
= 0; cnt
< size
; cnt
++)
283 i2c_writebyte(BusNR
, buf
[cnt
]);
286 status_t
i2c_init(void)
289 bool *i2c_bus
= &(si
->ps
.i2c_bus0
);
290 status_t result
= B_ERROR
;
292 LOG(4,("I2C: searching for wired I2C buses...\n"));
294 /* select GPU I/O pins for I2C buses */
295 i2c_select_bus_set(false);
297 /* enable access to primary head */
300 /* on some NV40 architecture cards the i2c busses can be disabled: enable them */
301 if (si
->ps
.card_arch
== NV40A
)
302 CRTCW(I2C_LOCK
,(CRTCR(I2C_LOCK
) | 0x04));
304 /* preset no board wired buses */
305 si
->ps
.i2c_bus0
= false;
306 si
->ps
.i2c_bus1
= false;
307 si
->ps
.i2c_bus2
= false;
309 /* set number of buses to test for */
312 /* newer cards (can) have a third bus.. */
313 if (((si
->ps
.card_arch
== NV10A
) && (si
->ps
.card_type
>= NV17
)) || (si
->ps
.card_arch
>= NV30A
))
316 /* find existing buses */
317 for (bus
= 0; bus
< buses
; bus
++) {
321 /* init and/or stop I2C bus */
323 /* check for hardware coupling of SCL and SDA -out and -in lines */
329 if (InSCL(bus
) || !InSDA(bus
)) continue;
335 if (!InSCL(bus
) || InSDA(bus
)) continue;
342 for (bus
= 0; bus
< buses
; bus
++) {
344 LOG(4,("I2C: bus #%d wiring check: passed\n", bus
));
347 LOG(4,("I2C: bus #%d wiring check: failed\n", bus
));
352 LOG(4,("I2C: dumping EDID specs for connector 1:\n"));
353 i2c_DumpSpecsEDID(&si
->ps
.con1_screen
);
354 LOG(4,("I2C: dumping EDID specs for connector 2:\n"));
355 i2c_DumpSpecsEDID(&si
->ps
.con2_screen
);
360 /*** DDC/EDID library use ***/
365 /* Dump EDID info in driver's logfile */
367 i2c_DumpEDID(edid1_info
*edid
)
371 LOG(4,("Vendor: %s\n", edid
->vendor
.manufacturer
));
372 LOG(4,("Product ID: %d\n", (int)edid
->vendor
.prod_id
));
373 LOG(4,("Serial #: %d\n", (int)edid
->vendor
.serial
));
374 LOG(4,("Produced in week/year: %d/%d\n", edid
->vendor
.week
, edid
->vendor
.year
));
376 LOG(4,("EDID version: %d.%d\n", edid
->version
.version
, edid
->version
.revision
));
378 LOG(4,("Type: %s\n", edid
->display
.input_type
? "Digital" : "Analog"));
379 LOG(4,("Size: %d cm x %d cm\n", edid
->display
.h_size
, edid
->display
.v_size
));
380 LOG(4,("Gamma=%.3f\n", (edid
->display
.gamma
+ 100) / 100.0));
381 LOG(4,("White (X,Y)=(%.3f,%.3f)\n", edid
->display
.white_x
/ 1024.0,
382 edid
->display
.white_y
/ 1024.0));
384 LOG(4,("Supported Future Video Modes:\n"));
385 for (i
= 0; i
< EDID1_NUM_STD_TIMING
; ++i
) {
386 if (edid
->std_timing
[i
].h_size
<= 256)
389 LOG(4,("%dx%d@%dHz (id=%d)\n",
390 edid
->std_timing
[i
].h_size
, edid
->std_timing
[i
].v_size
,
391 edid
->std_timing
[i
].refresh
, edid
->std_timing
[i
].id
));
394 LOG(4,("Supported VESA Video Modes:\n"));
395 if (edid
->established_timing
.res_720x400x70
)
396 LOG(4,("720x400@70\n"));
397 if (edid
->established_timing
.res_720x400x88
)
398 LOG(4,("720x400@88\n"));
399 if (edid
->established_timing
.res_640x480x60
)
400 LOG(4,("640x480@60\n"));
401 if (edid
->established_timing
.res_640x480x67
)
402 LOG(4,("640x480x67\n"));
403 if (edid
->established_timing
.res_640x480x72
)
404 LOG(4,("640x480x72\n"));
405 if (edid
->established_timing
.res_640x480x75
)
406 LOG(4,("640x480x75\n"));
407 if (edid
->established_timing
.res_800x600x56
)
408 LOG(4,("800x600@56\n"));
409 if (edid
->established_timing
.res_800x600x60
)
410 LOG(4,("800x600@60\n"));
412 if (edid
->established_timing
.res_800x600x72
)
413 LOG(4,("800x600@72\n"));
414 if (edid
->established_timing
.res_800x600x75
)
415 LOG(4,("800x600@75\n"));
416 if (edid
->established_timing
.res_832x624x75
)
417 LOG(4,("832x624@75\n"));
418 if (edid
->established_timing
.res_1024x768x87i
)
419 LOG(4,("1024x768@87 interlaced\n"));
420 if (edid
->established_timing
.res_1024x768x60
)
421 LOG(4,("1024x768@60\n"));
422 if (edid
->established_timing
.res_1024x768x70
)
423 LOG(4,("1024x768@70\n"));
424 if (edid
->established_timing
.res_1024x768x75
)
425 LOG(4,("1024x768@75\n"));
426 if (edid
->established_timing
.res_1280x1024x75
)
427 LOG(4,("1280x1024@75\n"));
429 if (edid
->established_timing
.res_1152x870x75
)
430 LOG(4,("1152x870@75\n"));
432 for (i
= 0; i
< EDID1_NUM_DETAILED_MONITOR_DESC
; ++i
) {
433 edid1_detailed_monitor
*monitor
= &edid
->detailed_monitor
[i
];
435 switch(monitor
->monitor_desc_type
) {
436 case EDID1_SERIAL_NUMBER
:
437 LOG(4,("Serial Number: %s\n", monitor
->data
.serial_number
));
440 case EDID1_ASCII_DATA
:
441 LOG(4,("Ascii Data: %s\n", monitor
->data
.ascii_data
));
444 case EDID1_MONITOR_RANGES
:
446 edid1_monitor_range monitor_range
= monitor
->data
.monitor_range
;
448 LOG(4,("Horizontal frequency range = %d..%d kHz\n",
449 monitor_range
.min_h
, monitor_range
.max_h
));
450 LOG(4,("Vertical frequency range = %d..%d Hz\n",
451 monitor_range
.min_v
, monitor_range
.max_v
));
452 LOG(4,("Maximum pixel clock = %d MHz\n", (uint16
)monitor_range
.max_clock
* 10));
456 case EDID1_MONITOR_NAME
:
457 LOG(4,("Monitor Name: %s\n", monitor
->data
.monitor_name
));
460 case EDID1_ADD_COLOUR_POINTER
:
462 for (j
= 0; j
< EDID1_NUM_EXTRA_WHITEPOINTS
; ++j
) {
463 edid1_whitepoint
*whitepoint
= &monitor
->data
.whitepoint
[j
];
465 if (whitepoint
->index
== 0)
468 LOG(4,("Additional whitepoint: (X,Y)=(%f,%f) gamma=%f index=%i\n",
469 whitepoint
->white_x
/ 1024.0,
470 whitepoint
->white_y
/ 1024.0,
471 (whitepoint
->gamma
+ 100) / 100.0,
477 case EDID1_ADD_STD_TIMING
:
479 for (j
= 0; j
< EDID1_NUM_EXTRA_STD_TIMING
; ++j
) {
480 edid1_std_timing
*timing
= &monitor
->data
.std_timing
[j
];
482 if (timing
->h_size
<= 256)
485 LOG(4,("%dx%d@%dHz (id=%d)\n",
486 timing
->h_size
, timing
->v_size
,
487 timing
->refresh
, timing
->id
));
492 case EDID1_IS_DETAILED_TIMING
:
494 edid1_detailed_timing
*timing
= &monitor
->data
.detailed_timing
;
496 LOG(4,("Additional Video Mode:\n"));
497 LOG(4,("clock=%f MHz\n", timing
->pixel_clock
/ 100.0));
498 LOG(4,("h: (%d, %d, %d, %d)\n",
499 timing
->h_active
, timing
->h_active
+ timing
->h_sync_off
,
500 timing
->h_active
+ timing
->h_sync_off
+ timing
->h_sync_width
,
501 timing
->h_active
+ timing
->h_blank
));
502 LOG(4,("v: (%d, %d, %d, %d)\n",
503 timing
->v_active
, timing
->v_active
+ timing
->v_sync_off
,
504 timing
->v_active
+ timing
->v_sync_off
+ timing
->v_sync_width
,
505 timing
->v_active
+ timing
->v_blank
));
506 LOG(4,("size: %.1f cm x %.1f cm\n",
507 timing
->h_size
/ 10.0, timing
->v_size
/ 10.0));
508 LOG(4,("border: %.1f cm x %.1f cm\n",
509 timing
->h_border
/ 10.0, timing
->v_border
/ 10.0));
516 /* callback for getting signals from I2C bus */
518 get_signals(void *cookie
, int *clk
, int *data
)
520 ddc_port_info
*info
= (ddc_port_info
*)cookie
;
522 *clk
= *data
= 0x0000;
523 if (InSCL(info
->port
)) *clk
= 0x0001;
524 if (InSDA(info
->port
)) *data
= 0x0001;
529 /* callback for setting signals on I2C bus */
531 set_signals(void *cookie
, int clk
, int data
)
533 ddc_port_info
*info
= (ddc_port_info
*)cookie
;
536 OutSCL(info
->port
, true);
538 OutSCL(info
->port
, false);
541 OutSDA(info
->port
, true);
543 OutSDA(info
->port
, false);
548 /* Read EDID information from monitor via the display data channel (DDC) */
550 i2c_ReadEDID(uint8 BusNR
, edid1_info
*edid
)
558 bus
.set_signals
= &set_signals
;
559 bus
.get_signals
= &get_signals
;
560 ddc2_init_timing(&bus
);
562 /* select GPU I/O pins for I2C buses */
563 i2c_select_bus_set(false);
565 /* enable access to primary head */
568 if (ddc2_read_edid1(&bus
, edid
, NULL
, NULL
) == B_OK
) {
569 LOG(4,("I2C: EDID succesfully read from monitor at bus %d\n", BusNR
));
570 LOG(4,("I2C: EDID dump follows (bus %d):\n", BusNR
));
572 LOG(4,("I2C: end EDID dump (bus %d).\n", BusNR
));
574 LOG(4,("I2C: reading EDID failed at bus %d!\n", BusNR
));
581 void i2c_TestEDID(void)
585 bool *i2c_bus
= &(si
->ps
.i2c_bus0
);
587 /* test wired bus(es) */
588 for (bus
= 0; bus
< 3; bus
++) {
590 i2c_ReadEDID(bus
, &edid
);
595 i2c_ExtractSpecsEDID(edid1_info
* edid
, edid_specs
* specs
)
598 edid1_detailed_timing edid_timing
;
600 specs
->have_full_edid
= false;
601 specs
->have_native_edid
= false;
602 specs
->timing
.h_display
= 0;
603 specs
->timing
.v_display
= 0;
605 /* find the optimum (native) modeline */
606 for (i
= 0; i
< EDID1_NUM_DETAILED_MONITOR_DESC
; ++i
) {
607 switch(edid
->detailed_monitor
[i
].monitor_desc_type
) {
608 case EDID1_IS_DETAILED_TIMING
:
609 // TODO: handle flags correctly!
610 edid_timing
= edid
->detailed_monitor
[i
].data
.detailed_timing
;
612 if (edid_timing
.pixel_clock
<= 0/* || edid_timing.sync != 3*/)
615 /* we want the optimum (native) modeline only, widescreen if possible.
616 * So only check for horizontal display, not for vertical display. */
617 if (edid_timing
.h_active
<= specs
->timing
.h_display
)
620 specs
->timing
.pixel_clock
= edid_timing
.pixel_clock
* 10;
621 specs
->timing
.h_display
= edid_timing
.h_active
;
622 specs
->timing
.h_sync_start
= edid_timing
.h_active
+ edid_timing
.h_sync_off
;
623 specs
->timing
.h_sync_end
= specs
->timing
.h_sync_start
+ edid_timing
.h_sync_width
;
624 specs
->timing
.h_total
= specs
->timing
.h_display
+ edid_timing
.h_blank
;
625 specs
->timing
.v_display
= edid_timing
.v_active
;
626 specs
->timing
.v_sync_start
= edid_timing
.v_active
+ edid_timing
.v_sync_off
;
627 specs
->timing
.v_sync_end
= specs
->timing
.v_sync_start
+ edid_timing
.v_sync_width
;
628 specs
->timing
.v_total
= specs
->timing
.v_display
+ edid_timing
.v_blank
;
629 specs
->timing
.flags
= 0;
630 if (edid_timing
.sync
== 3) {
631 if (edid_timing
.misc
& 1)
632 specs
->timing
.flags
|= B_POSITIVE_HSYNC
;
633 if (edid_timing
.misc
& 2)
634 specs
->timing
.flags
|= B_POSITIVE_VSYNC
;
636 if (edid_timing
.interlaced
)
637 specs
->timing
.flags
|= B_TIMING_INTERLACED
;
642 /* check if we actually got a modeline */
643 if (!specs
->timing
.h_display
|| !specs
->timing
.v_display
) return B_ERROR
;
645 /* check if the mode is at least VGA. If it's not, ignore specs */
646 if ((specs
->timing
.h_display
< 640) || (specs
->timing
.v_display
< 480)) {
647 LOG(4,("I2C: specsEDID: screen reports lower than VGA native mode, ignoring specs!\n"));
651 /* determine screen aspect ratio */
653 (specs
->timing
.h_display
/ ((float)specs
->timing
.v_display
));
655 /* determine connection type */
656 specs
->digital
= false;
657 if (edid
->display
.input_type
) specs
->digital
= true;
659 /* and also copy full edid1_info for reference */
660 memcpy(&(specs
->full_edid
), edid
, sizeof(specs
->full_edid
));
662 /* we succesfully fetched the specs we need */
663 specs
->have_native_edid
= true;
664 /* we also got full and valid EDID via DDC */
665 specs
->have_full_edid
= true;
670 /* Dump EDID info in driver's logfile */
672 i2c_DumpSpecsEDID(edid_specs
* specs
)
674 LOG(4,("I2C: specsEDID: have_native_edid: %s\n", specs
->have_native_edid
? "True" : "False"));
675 if (!specs
->have_native_edid
) return;
676 LOG(4,("I2C: specsEDID: timing.pixel_clock %.3f Mhz\n", specs
->timing
.pixel_clock
/ 1000.0));
677 LOG(4,("I2C: specsEDID: timing.h_display %d\n", specs
->timing
.h_display
));
678 LOG(4,("I2C: specsEDID: timing.h_sync_start %d\n", specs
->timing
.h_sync_start
));
679 LOG(4,("I2C: specsEDID: timing.h_sync_end %d\n", specs
->timing
.h_sync_end
));
680 LOG(4,("I2C: specsEDID: timing.h_total %d\n", specs
->timing
.h_total
));
681 LOG(4,("I2C: specsEDID: timing.v_display %d\n", specs
->timing
.v_display
));
682 LOG(4,("I2C: specsEDID: timing.v_sync_start %d\n", specs
->timing
.v_sync_start
));
683 LOG(4,("I2C: specsEDID: timing.v_sync_end %d\n", specs
->timing
.v_sync_end
));
684 LOG(4,("I2C: specsEDID: timing.v_total %d\n", specs
->timing
.v_total
));
685 LOG(4,("I2C: specsEDID: timing.flags $%08x\n", specs
->timing
.flags
));
686 LOG(4,("I2C: specsEDID: aspect: %1.2f\n", specs
->aspect
));
687 LOG(4,("I2C: specsEDID: digital: %s\n", specs
->digital
? "True" : "False"));
691 * - con1 resides closest to the mainboard on for example NV25 and NV28, while for
692 * example on NV34 con2 sits closest to the mainboard.
693 * - i2c bus0 is connected to con1, and i2c bus1 is connected to con2 on all pre-NV40
694 * architecture cards. On later cards it's vice versa. These connections do not depend
695 * on the analog VGA switch setting (see nv_general_output_select()). It also does
696 * not depend on the way screens are connected to the cards (DVI/VGA, 1 or 2 screens).
697 * - on some NV40 architecture cards i2c bus2 connects to con2 instead of i2c bus0. This
698 * is confirmed on GeForce FX 6600 (NV43, id 0x0141) and GeForce 7300 (G72, id 0x01d1).
699 * - on pre-NV40 laptops i2c bus2 can connect to con2 as well: confirmed on a Geforce FX
700 * 5200 Go (NV34, id 0x0324).
701 * - con1 has CRTC1 and DAC1, and con2 has CRTC2 and DAC2 if nv_general_output_select()
702 * is set to 'straight' and there are only VGA type screens connected. */
703 void i2c_DetectScreens(void)
707 si
->ps
.con1_screen
.have_native_edid
= false;
708 si
->ps
.con2_screen
.have_native_edid
= false;
709 si
->ps
.con1_screen
.have_full_edid
= false;
710 si
->ps
.con2_screen
.have_full_edid
= false;
711 si
->ps
.con1_screen
.aspect
= 0;
712 si
->ps
.con2_screen
.aspect
= 0;
714 /* check existance of bus 0 */
715 if (si
->ps
.i2c_bus0
) {
716 /* check I2C bus 0 for an EDID capable screen */
717 if (i2c_ReadEDID(0, &edid
) == B_OK
) {
718 /* fetch optimum (native) modeline */
719 switch (si
->ps
.card_arch
) {
721 i2c_ExtractSpecsEDID(&edid
, &si
->ps
.con2_screen
);
724 i2c_ExtractSpecsEDID(&edid
, &si
->ps
.con1_screen
);
730 /* check existance of bus 1 */
731 if (si
->ps
.i2c_bus1
) {
732 /* check I2C bus 1 for an EDID screen */
733 if (i2c_ReadEDID(1, &edid
) == B_OK
) {
734 /* fetch optimum (native) modeline */
735 switch (si
->ps
.card_arch
) {
737 i2c_ExtractSpecsEDID(&edid
, &si
->ps
.con1_screen
);
740 i2c_ExtractSpecsEDID(&edid
, &si
->ps
.con2_screen
);
746 /* check existance of bus 2 */
747 if (si
->ps
.i2c_bus2
) {
748 /* check I2C bus 2 for an EDID screen */
749 if (i2c_ReadEDID(2, &edid
) == B_OK
) {
750 /* fetch optimum (native) modeline */
751 switch (si
->ps
.card_arch
) {
753 if (!si
->ps
.con2_screen
.have_native_edid
) {
754 i2c_ExtractSpecsEDID(&edid
, &si
->ps
.con2_screen
);
756 LOG(4,("I2C: DetectScreens: WARNING, unexpected behaviour detected!\n"));
760 if (!si
->ps
.con2_screen
.have_native_edid
&& si
->ps
.laptop
) {
761 i2c_ExtractSpecsEDID(&edid
, &si
->ps
.con2_screen
);
763 LOG(4,("I2C: DetectScreens: WARNING, unexpected behaviour detected!\n"));