NV50: A minor change.
[platform/upstream/libdrm.git] / linux-core / intel_sdvo.c
1 /*
2  * Copyright © 2006-2007 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *      Eric Anholt <eric@anholt.net>
25  */
26 /*
27  * Copyright 2006 Dave Airlie <airlied@linux.ie>
28  *   Jesse Barnes <jesse.barnes@intel.com>
29  */
30
31 #include <linux/i2c.h>
32 #include <linux/delay.h>
33 #include "drmP.h"
34 #include "drm.h"
35 #include "drm_crtc.h"
36 #include "intel_drv.h"
37 #include "i915_drm.h"
38 #include "i915_drv.h"
39 #include "intel_sdvo_regs.h"
40
41 struct intel_sdvo_priv {
42         struct intel_i2c_chan *i2c_bus;
43         int slaveaddr;
44         int output_device;
45
46         u16 active_outputs;
47
48         struct intel_sdvo_caps caps;
49         int pixel_clock_min, pixel_clock_max;
50
51         int save_sdvo_mult;
52         u16 save_active_outputs;
53         struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
54         struct intel_sdvo_dtd save_output_dtd[16];
55         u32 save_SDVOX;
56 };
57
58 /**
59  * Writes the SDVOB or SDVOC with the given value, but always writes both
60  * SDVOB and SDVOC to work around apparent hardware issues (according to
61  * comments in the BIOS).
62  */
63 void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
64 {
65         struct drm_device *dev = intel_output->base.dev;
66         struct drm_i915_private *dev_priv = dev->dev_private;
67         struct intel_sdvo_priv   *sdvo_priv = intel_output->dev_priv;
68         u32 bval = val, cval = val;
69         int i;
70
71         if (sdvo_priv->output_device == SDVOB) {
72                 cval = I915_READ(SDVOC);
73         } else {
74                 bval = I915_READ(SDVOB);
75         }
76         /*
77          * Write the registers twice for luck. Sometimes,
78          * writing them only once doesn't appear to 'stick'.
79          * The BIOS does this too. Yay, magic
80          */
81         for (i = 0; i < 2; i++)
82         {
83                 I915_WRITE(SDVOB, bval);
84                 I915_READ(SDVOB);
85                 I915_WRITE(SDVOC, cval);
86                 I915_READ(SDVOC);
87         }
88 }
89
90 static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
91                                  u8 *ch)
92 {
93         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
94         u8 out_buf[2];
95         u8 buf[2];
96         int ret;
97
98         struct i2c_msg msgs[] = {
99                 { 
100                         .addr = sdvo_priv->i2c_bus->slave_addr,
101                         .flags = 0,
102                         .len = 1,
103                         .buf = out_buf,
104                 }, 
105                 {
106                         .addr = sdvo_priv->i2c_bus->slave_addr,
107                         .flags = I2C_M_RD,
108                         .len = 1,
109                         .buf = buf,
110                 }
111         };
112
113         out_buf[0] = addr;
114         out_buf[1] = 0;
115
116         if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2)
117         {
118 //              DRM_DEBUG("got back from addr %02X = %02x\n", out_buf[0], buf[0]); 
119                 *ch = buf[0];
120                 return true;
121         }
122
123         DRM_DEBUG("i2c transfer returned %d\n", ret);
124         return false;
125 }
126
127 static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
128                                   u8 ch)
129 {
130         u8 out_buf[2];
131         struct i2c_msg msgs[] = {
132                 { 
133                         .addr = intel_output->i2c_bus->slave_addr,
134                         .flags = 0,
135                         .len = 2,
136                         .buf = out_buf,
137                 }
138         };
139
140         out_buf[0] = addr;
141         out_buf[1] = ch;
142
143         if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1)
144         {
145                 return true;
146         }
147         return false;
148 }
149
150 #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
151 /** Mapping of command numbers to names, for debug output */
152 const static struct _sdvo_cmd_name {
153     u8 cmd;
154     char *name;
155 } sdvo_cmd_names[] = {
156     SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
157     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
158     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
159     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
160     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
161     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
162     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
163     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
164     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
165     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
166     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
167     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
168     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
169     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
170     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
171     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
172     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
173     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
174     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
175     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
176     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
177     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
178     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
179     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
180     SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
181     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
182     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
183     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
184     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
185     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
186     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
187     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
188     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
189     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
190     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
191     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
192     SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
193 };
194
195 #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
196 #define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
197
198 static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
199                                  void *args, int args_len)
200 {
201         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
202         int i;
203
204         if (1) {
205                 DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
206                 for (i = 0; i < args_len; i++)
207                         printk("%02X ", ((u8 *)args)[i]);
208                 for (; i < 8; i++)
209                         printk("   ");
210                 for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) {
211                         if (cmd == sdvo_cmd_names[i].cmd) {
212                                 printk("(%s)", sdvo_cmd_names[i].name);
213                                 break;
214                         }
215                 }
216                 if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0]))
217                         printk("(%02X)",cmd);
218                 printk("\n");
219         }
220                         
221         for (i = 0; i < args_len; i++) {
222                 intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i, ((u8*)args)[i]);
223         }
224
225         intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
226 }
227
228 static const char *cmd_status_names[] = {
229         "Power on",
230         "Success",
231         "Not supported",
232         "Invalid arg",
233         "Pending",
234         "Target not specified",
235         "Scaling not supported"
236 };
237
238 static u8 intel_sdvo_read_response(struct intel_output *intel_output, void *response,
239                                    int response_len)
240 {
241         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
242         int i;
243         u8 status;
244         u8 retry = 50;
245
246         while (retry--) {
247                 /* Read the command response */
248                 for (i = 0; i < response_len; i++) {
249                         intel_sdvo_read_byte(intel_output, SDVO_I2C_RETURN_0 + i,
250                                      &((u8 *)response)[i]);
251                 }
252
253                 /* read the return status */
254                 intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS, &status);
255
256                 if (1) {
257                         DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
258                         for (i = 0; i < response_len; i++)
259                                 printk("%02X ", ((u8 *)response)[i]);
260                         for (; i < 8; i++)
261                                 printk("   ");
262                         if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
263                                 printk("(%s)", cmd_status_names[status]);
264                         else
265                                 printk("(??? %d)", status);
266                         printk("\n");
267                 }
268
269                 if (status != SDVO_CMD_STATUS_PENDING)
270                         return status;
271
272                 mdelay(50);
273         }
274
275         return status;
276 }
277
278 int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
279 {
280         if (mode->clock >= 100000)
281                 return 1;
282         else if (mode->clock >= 50000)
283                 return 2;
284         else
285                 return 4;
286 }
287
288 /**
289  * Don't check status code from this as it switches the bus back to the
290  * SDVO chips which defeats the purpose of doing a bus switch in the first
291  * place.
292  */
293 void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, u8 target)
294 {
295         intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
296 }
297
298 static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
299 {
300         struct intel_sdvo_set_target_input_args targets = {0};
301         u8 status;
302
303         if (target_0 && target_1)
304                 return SDVO_CMD_STATUS_NOTSUPP;
305
306         if (target_1)
307                 targets.target_1 = 1;
308
309         intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
310                              sizeof(targets));
311
312         status = intel_sdvo_read_response(intel_output, NULL, 0);
313
314         return (status == SDVO_CMD_STATUS_SUCCESS);
315 }
316
317 /**
318  * Return whether each input is trained.
319  *
320  * This function is making an assumption about the layout of the response,
321  * which should be checked against the docs.
322  */
323 static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
324 {
325         struct intel_sdvo_get_trained_inputs_response response;
326         u8 status;
327
328         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
329         status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
330         if (status != SDVO_CMD_STATUS_SUCCESS)
331                 return false;
332
333         *input_1 = response.input0_trained;
334         *input_2 = response.input1_trained;
335         return true;
336 }
337
338 static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
339                                           u16 *outputs)
340 {
341         u8 status;
342
343         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
344         status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
345
346         return (status == SDVO_CMD_STATUS_SUCCESS);
347 }
348
349 static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
350                                           u16 outputs)
351 {
352         u8 status;
353
354         intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
355                              sizeof(outputs));
356         status = intel_sdvo_read_response(intel_output, NULL, 0);
357         return (status == SDVO_CMD_STATUS_SUCCESS);
358 }
359
360 static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
361                                                int mode)
362 {
363         u8 status, state = SDVO_ENCODER_STATE_ON;
364
365         switch (mode) {
366         case DPMSModeOn:
367                 state = SDVO_ENCODER_STATE_ON;
368                 break;
369         case DPMSModeStandby:
370                 state = SDVO_ENCODER_STATE_STANDBY;
371                 break;
372         case DPMSModeSuspend:
373                 state = SDVO_ENCODER_STATE_SUSPEND;
374                 break;
375         case DPMSModeOff:
376                 state = SDVO_ENCODER_STATE_OFF;
377                 break;
378         }
379         
380         intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
381                              sizeof(state));
382         status = intel_sdvo_read_response(intel_output, NULL, 0);
383
384         return (status == SDVO_CMD_STATUS_SUCCESS);
385 }
386
387 static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
388                                                    int *clock_min,
389                                                    int *clock_max)
390 {
391         struct intel_sdvo_pixel_clock_range clocks;
392         u8 status;
393
394         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
395                              NULL, 0);
396
397         status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
398
399         if (status != SDVO_CMD_STATUS_SUCCESS)
400                 return false;
401
402         /* Convert the values from units of 10 kHz to kHz. */
403         *clock_min = clocks.min * 10;
404         *clock_max = clocks.max * 10;
405
406         return true;
407 }
408
409 static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
410                                          u16 outputs)
411 {
412         u8 status;
413
414         intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
415                              sizeof(outputs));
416
417         status = intel_sdvo_read_response(intel_output, NULL, 0);
418         return (status == SDVO_CMD_STATUS_SUCCESS);
419 }
420
421 static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
422                                   struct intel_sdvo_dtd *dtd)
423 {
424         u8 status;
425
426         intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
427         status = intel_sdvo_read_response(intel_output, &dtd->part1,
428                                           sizeof(dtd->part1));
429         if (status != SDVO_CMD_STATUS_SUCCESS)
430                 return false;
431
432         intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
433         status = intel_sdvo_read_response(intel_output, &dtd->part2,
434                                           sizeof(dtd->part2));
435         if (status != SDVO_CMD_STATUS_SUCCESS)
436                 return false;
437
438         return true;
439 }
440
441 static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
442                                          struct intel_sdvo_dtd *dtd)
443 {
444         return intel_sdvo_get_timing(intel_output,
445                                      SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
446 }
447
448 static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
449                                          struct intel_sdvo_dtd *dtd)
450 {
451         return intel_sdvo_get_timing(intel_output,
452                                      SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
453 }
454
455 static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
456                                   struct intel_sdvo_dtd *dtd)
457 {
458         u8 status;
459
460         intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
461         status = intel_sdvo_read_response(intel_output, NULL, 0);
462         if (status != SDVO_CMD_STATUS_SUCCESS)
463                 return false;
464
465         intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
466         status = intel_sdvo_read_response(intel_output, NULL, 0);
467         if (status != SDVO_CMD_STATUS_SUCCESS)
468                 return false;
469
470         return true;
471 }
472
473 static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
474                                          struct intel_sdvo_dtd *dtd)
475 {
476         return intel_sdvo_set_timing(intel_output,
477                                      SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
478 }
479
480 static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
481                                          struct intel_sdvo_dtd *dtd)
482 {
483         return intel_sdvo_set_timing(intel_output,
484                                      SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
485 }
486
487 #if 0
488 static bool intel_sdvo_get_preferred_input_timing(struct intel_output *intel_output,
489                                                   struct intel_sdvo_dtd *dtd)
490 {
491         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
492         u8 status;
493
494         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
495                              NULL, 0);
496
497         status = intel_sdvo_read_response(intel_output, &dtd->part1,
498                                           sizeof(dtd->part1));
499         if (status != SDVO_CMD_STATUS_SUCCESS)
500                 return false;
501
502         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
503                              NULL, 0);
504         status = intel_sdvo_read_response(intel_output, &dtd->part2,
505                                           sizeof(dtd->part2));
506         if (status != SDVO_CMD_STATUS_SUCCESS)
507                 return false;
508
509         return true;
510 }
511 #endif
512
513 static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
514 {
515         u8 response, status;
516
517         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
518         status = intel_sdvo_read_response(intel_output, &response, 1);
519
520         if (status != SDVO_CMD_STATUS_SUCCESS) {
521                 DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
522                 return SDVO_CLOCK_RATE_MULT_1X;
523         } else {
524                 DRM_DEBUG("Current clock rate multiplier: %d\n", response);
525         }
526
527         return response;
528 }
529
530 static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
531 {
532         u8 status;
533
534         intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
535         status = intel_sdvo_read_response(intel_output, NULL, 0);
536         if (status != SDVO_CMD_STATUS_SUCCESS)
537                 return false;
538
539         return true;
540 }
541
542 static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
543                                   struct drm_display_mode *mode,
544                                   struct drm_display_mode *adjusted_mode)
545 {
546         /* Make the CRTC code factor in the SDVO pixel multiplier.  The SDVO
547          * device will be told of the multiplier during mode_set.
548          */
549         adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
550         return true;
551 }
552
553 static void intel_sdvo_mode_set(struct drm_encoder *encoder,
554                                 struct drm_display_mode *mode,
555                                 struct drm_display_mode *adjusted_mode)
556 {
557         struct drm_device *dev = encoder->dev;
558         struct drm_i915_private *dev_priv = dev->dev_private;
559         struct drm_crtc *crtc = encoder->crtc;
560         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
561         struct intel_output *intel_output = enc_to_intel_output(encoder);
562         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
563         u16 width, height;
564         u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
565         u16 h_sync_offset, v_sync_offset;
566         u32 sdvox;
567         struct intel_sdvo_dtd output_dtd;
568         int sdvo_pixel_multiply;
569
570         if (!mode)
571                 return;
572
573         width = mode->crtc_hdisplay;
574         height = mode->crtc_vdisplay;
575
576         /* do some mode translations */
577         h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
578         h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
579
580         v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
581         v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
582
583         h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
584         v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
585
586         output_dtd.part1.clock = mode->clock / 10;
587         output_dtd.part1.h_active = width & 0xff;
588         output_dtd.part1.h_blank = h_blank_len & 0xff;
589         output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
590                 ((h_blank_len >> 8) & 0xf);
591         output_dtd.part1.v_active = height & 0xff;
592         output_dtd.part1.v_blank = v_blank_len & 0xff;
593         output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
594                 ((v_blank_len >> 8) & 0xf);
595         
596         output_dtd.part2.h_sync_off = h_sync_offset;
597         output_dtd.part2.h_sync_width = h_sync_len & 0xff;
598         output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
599                 (v_sync_len & 0xf);
600         output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
601                 ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
602                 ((v_sync_len & 0x30) >> 4);
603         
604         output_dtd.part2.dtd_flags = 0x18;
605         if (mode->flags & V_PHSYNC)
606                 output_dtd.part2.dtd_flags |= 0x2;
607         if (mode->flags & V_PVSYNC)
608                 output_dtd.part2.dtd_flags |= 0x4;
609
610         output_dtd.part2.sdvo_flags = 0;
611         output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
612         output_dtd.part2.reserved = 0;
613
614         /* Set the output timing to the screen */
615         intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs);
616         intel_sdvo_set_output_timing(intel_output, &output_dtd);
617
618         /* Set the input timing to the screen. Assume always input 0. */
619         intel_sdvo_set_target_input(intel_output, true, false);
620
621         /* We would like to use i830_sdvo_create_preferred_input_timing() to
622          * provide the device with a timing it can support, if it supports that
623          * feature.  However, presumably we would need to adjust the CRTC to
624          * output the preferred timing, and we don't support that currently.
625          */
626 #if 0
627         success = intel_sdvo_create_preferred_input_timing(intel_output, clock,
628                                                            width, height);
629         if (success) {
630                 struct intel_sdvo_dtd *input_dtd;
631                 
632                 intel_sdvo_get_preferred_input_timing(intel_output, &input_dtd);
633                 intel_sdvo_set_input_timing(intel_output, &input_dtd);
634         }
635 #else
636         intel_sdvo_set_input_timing(intel_output, &output_dtd);
637 #endif  
638
639         switch (intel_sdvo_get_pixel_multiplier(mode)) {
640         case 1:
641                 intel_sdvo_set_clock_rate_mult(intel_output,
642                                                SDVO_CLOCK_RATE_MULT_1X);
643                 break;
644         case 2:
645                 intel_sdvo_set_clock_rate_mult(intel_output,
646                                                SDVO_CLOCK_RATE_MULT_2X);
647                 break;
648         case 4:
649                 intel_sdvo_set_clock_rate_mult(intel_output,
650                                                SDVO_CLOCK_RATE_MULT_4X);
651                 break;
652         }       
653
654         /* Set the SDVO control regs. */
655         if (0/*IS_I965GM(dev)*/) {
656                 sdvox = SDVO_BORDER_ENABLE;
657         } else {
658                 sdvox = I915_READ(sdvo_priv->output_device);
659                 switch (sdvo_priv->output_device) {
660                 case SDVOB:
661                         sdvox &= SDVOB_PRESERVE_MASK;
662                         break;
663                 case SDVOC:
664                         sdvox &= SDVOC_PRESERVE_MASK;
665                         break;
666                 }
667                 sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
668         }
669         if (intel_crtc->pipe == 1)
670                 sdvox |= SDVO_PIPE_B_SELECT;
671
672         sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
673         if (IS_I965G(dev)) {
674                 /* done in crtc_mode_set as the dpll_md reg must be written 
675                    early */
676         } else if (IS_I945G(dev) || IS_I945GM(dev)) {
677                 /* done in crtc_mode_set as it lives inside the 
678                    dpll register */
679         } else {
680                 sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
681         }
682
683         intel_sdvo_write_sdvox(intel_output, sdvox);
684 }
685
686 static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
687 {
688         struct drm_device *dev = encoder->dev;
689         struct drm_i915_private *dev_priv = dev->dev_private;
690         struct intel_output *intel_output = enc_to_intel_output(encoder);
691         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
692         u32 temp;
693
694         if (mode != DPMSModeOn) {
695                 intel_sdvo_set_active_outputs(intel_output, 0);
696                 if (0)
697                         intel_sdvo_set_encoder_power_state(intel_output, mode);
698
699                 if (mode == DPMSModeOff) {
700                         temp = I915_READ(sdvo_priv->output_device);
701                         if ((temp & SDVO_ENABLE) != 0) {
702                                 intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
703                         }
704                 }
705         } else {
706                 bool input1, input2;
707                 int i;
708                 u8 status;
709                 
710                 temp = I915_READ(sdvo_priv->output_device);
711                 if ((temp & SDVO_ENABLE) == 0)
712                         intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
713                 for (i = 0; i < 2; i++)
714                   intel_wait_for_vblank(dev);
715                 
716                 status = intel_sdvo_get_trained_inputs(intel_output, &input1,
717                                                        &input2);
718
719                 
720                 /* Warn if the device reported failure to sync. 
721                  * A lot of SDVO devices fail to notify of sync, but it's
722                  * a given it the status is a success, we succeeded.
723                  */
724                 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
725                         DRM_DEBUG("First %s output reported failure to sync\n",
726                                    SDVO_NAME(sdvo_priv));
727                 }
728                 
729                 if (0)
730                         intel_sdvo_set_encoder_power_state(intel_output, mode);
731                 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs);
732         }       
733         return;
734 }
735
736 static void intel_sdvo_save(struct drm_connector *connector)
737 {
738         struct drm_device *dev = connector->dev;
739         struct drm_i915_private *dev_priv = dev->dev_private;
740         struct intel_output *intel_output = to_intel_output(connector);
741         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
742         int o;
743
744         sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
745         intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
746
747         if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
748                 intel_sdvo_set_target_input(intel_output, true, false);
749                 intel_sdvo_get_input_timing(intel_output,
750                                             &sdvo_priv->save_input_dtd_1);
751         }
752
753         if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
754                 intel_sdvo_set_target_input(intel_output, false, true);
755                 intel_sdvo_get_input_timing(intel_output,
756                                             &sdvo_priv->save_input_dtd_2);
757         }
758
759         for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
760         {
761                 u16  this_output = (1 << o);
762                 if (sdvo_priv->caps.output_flags & this_output)
763                 {
764                         intel_sdvo_set_target_output(intel_output, this_output);
765                         intel_sdvo_get_output_timing(intel_output,
766                                                      &sdvo_priv->save_output_dtd[o]);
767                 }
768         }
769
770         sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
771 }
772
773 static void intel_sdvo_restore(struct drm_connector *connector)
774 {
775         struct drm_device *dev = connector->dev;
776         struct drm_i915_private *dev_priv = dev->dev_private;
777         struct intel_output *intel_output = to_intel_output(connector);
778         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
779         int o;
780         int i;
781         bool input1, input2;
782         u8 status;
783
784         intel_sdvo_set_active_outputs(intel_output, 0);
785
786         for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
787         {
788                 u16  this_output = (1 << o);
789                 if (sdvo_priv->caps.output_flags & this_output) {
790                         intel_sdvo_set_target_output(intel_output, this_output);
791                         intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
792                 }
793         }
794
795         if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
796                 intel_sdvo_set_target_input(intel_output, true, false);
797                 intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
798         }
799
800         if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
801                 intel_sdvo_set_target_input(intel_output, false, true);
802                 intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
803         }
804         
805         intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
806         
807         I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
808         
809         if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
810         {
811                 for (i = 0; i < 2; i++)
812                         intel_wait_for_vblank(dev);
813                 status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
814                 if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
815                         DRM_DEBUG("First %s output reported failure to sync\n",
816                                    SDVO_NAME(sdvo_priv));
817         }
818         
819         intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
820 }
821
822 static int intel_sdvo_mode_valid(struct drm_connector *connector,
823                                  struct drm_display_mode *mode)
824 {
825         struct intel_output *intel_output = to_intel_output(connector);
826         struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
827
828         if (mode->flags & V_DBLSCAN)
829                 return MODE_NO_DBLESCAN;
830
831         if (sdvo_priv->pixel_clock_min > mode->clock)
832                 return MODE_CLOCK_LOW;
833
834         if (sdvo_priv->pixel_clock_max < mode->clock)
835                 return MODE_CLOCK_HIGH;
836
837         return MODE_OK;
838 }
839
840 static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
841 {
842         u8 status;
843
844         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
845         status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
846         if (status != SDVO_CMD_STATUS_SUCCESS)
847                 return false;
848
849         return true;
850 }
851
852 struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
853 {
854         struct drm_connector *connector = NULL;
855         struct intel_output *iout = NULL;
856         struct intel_sdvo_priv *sdvo;
857
858         /* find the sdvo connector */
859         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
860                 iout = to_intel_output(connector);
861
862                 if (iout->type != INTEL_OUTPUT_SDVO)
863                         continue;
864
865                 sdvo = iout->dev_priv;
866
867                 if (sdvo->output_device == SDVOB && sdvoB)
868                         return connector;
869
870                 if (sdvo->output_device == SDVOC && !sdvoB)
871                         return connector;
872
873         }
874         
875         return NULL;
876 }
877
878 int intel_sdvo_supports_hotplug(struct drm_connector *connector)
879 {
880         u8 response[2];
881         u8 status;
882         struct intel_output *intel_output;
883         DRM_DEBUG("\n");
884
885         if (!connector)
886                 return 0;
887
888         intel_output = to_intel_output(connector);
889
890         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
891         status = intel_sdvo_read_response(intel_output, &response, 2);
892
893         if (response[0] !=0)
894                 return 1;
895
896         return 0;
897 }
898
899 void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
900 {
901         u8 response[2];
902         u8 status;
903         struct intel_output *intel_output = to_intel_output(connector);
904
905         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
906         intel_sdvo_read_response(intel_output, &response, 2);
907
908         if (on) {
909                 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
910                 status = intel_sdvo_read_response(intel_output, &response, 2);
911
912                 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
913         } else {
914                 response[0] = 0;
915                 response[1] = 0;
916                 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
917         }
918
919         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
920         intel_sdvo_read_response(intel_output, &response, 2);
921 }
922
923 static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
924 {
925         u8 response[2];
926         u8 status;
927         struct intel_output *intel_output = to_intel_output(connector);
928
929         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
930         status = intel_sdvo_read_response(intel_output, &response, 2);
931
932         DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
933         if ((response[0] != 0) || (response[1] != 0))
934                 return connector_status_connected;
935         else
936                 return connector_status_disconnected;
937 }
938
939 static int intel_sdvo_get_modes(struct drm_connector *connector)
940 {
941         struct intel_output *intel_output = to_intel_output(connector);
942
943         /* set the bus switch and get the modes */
944         intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2);
945         intel_ddc_get_modes(intel_output);
946
947         if (list_empty(&connector->probed_modes))
948                 return 0;
949         return 1;
950 #if 0
951         /* Mac mini hack.  On this device, I get DDC through the analog, which
952          * load-detects as disconnected.  I fail to DDC through the SDVO DDC,
953          * but it does load-detect as connected.  So, just steal the DDC bits 
954          * from analog when we fail at finding it the right way.
955          */
956         /* TODO */
957         return NULL;
958
959         return NULL;
960 #endif
961 }
962
963 static void intel_sdvo_destroy(struct drm_connector *connector)
964 {
965         struct intel_output *intel_output = to_intel_output(connector);
966
967         if (intel_output->i2c_bus)
968                 intel_i2c_destroy(intel_output->i2c_bus);
969         drm_sysfs_connector_remove(connector);
970         drm_connector_cleanup(connector);
971         kfree(intel_output);
972 }
973
974 static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
975         .dpms = intel_sdvo_dpms,
976         .mode_fixup = intel_sdvo_mode_fixup,
977         .prepare = intel_encoder_prepare,
978         .mode_set = intel_sdvo_mode_set,
979         .commit = intel_encoder_commit,
980 };
981
982 static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
983         .save = intel_sdvo_save,
984         .restore = intel_sdvo_restore,
985         .detect = intel_sdvo_detect,
986         .fill_modes = drm_helper_probe_single_connector_modes,
987         .destroy = intel_sdvo_destroy,
988 };
989
990 static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
991         .get_modes = intel_sdvo_get_modes,
992         .mode_valid = intel_sdvo_mode_valid,
993         .best_encoder = intel_best_encoder,
994 };
995
996 void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
997 {
998         drm_encoder_cleanup(encoder);
999 }
1000
1001 static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
1002         .destroy = intel_sdvo_enc_destroy,
1003 };
1004
1005
1006 void intel_sdvo_init(struct drm_device *dev, int output_device)
1007 {
1008         struct drm_connector *connector;
1009         struct intel_output *intel_output;
1010         struct intel_sdvo_priv *sdvo_priv;
1011         struct intel_i2c_chan *i2cbus = NULL;
1012         int connector_type;
1013         u8 ch[0x40];
1014         int i;
1015         int encoder_type, output_id;
1016
1017         intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
1018         if (!intel_output) {
1019                 return;
1020         }
1021
1022         connector = &intel_output->base;
1023
1024         drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
1025                            DRM_MODE_CONNECTOR_Unknown);
1026         drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
1027         sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
1028         intel_output->type = INTEL_OUTPUT_SDVO;
1029
1030         connector->interlace_allowed = 0;
1031         connector->doublescan_allowed = 0;
1032
1033         /* setup the DDC bus. */
1034         if (output_device == SDVOB)
1035                 i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
1036         else
1037                 i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
1038
1039         if (!i2cbus)
1040                 goto err_connector;
1041
1042         sdvo_priv->i2c_bus = i2cbus;
1043
1044         if (output_device == SDVOB) {
1045                 output_id = 1;
1046                 sdvo_priv->i2c_bus->slave_addr = 0x38;
1047         } else {
1048                 output_id = 2;
1049                 sdvo_priv->i2c_bus->slave_addr = 0x39;
1050         }
1051
1052         sdvo_priv->output_device = output_device;
1053         intel_output->i2c_bus = i2cbus;
1054         intel_output->dev_priv = sdvo_priv;
1055
1056
1057         /* Read the regs to test if we can talk to the device */
1058         for (i = 0; i < 0x40; i++) {
1059                 if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
1060                         DRM_DEBUG("No SDVO device found on SDVO%c\n",
1061                                   output_device == SDVOB ? 'B' : 'C');
1062                         goto err_i2c;
1063                 }
1064         }
1065
1066         intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
1067
1068         memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs));
1069
1070         /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
1071         if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
1072         {
1073                 sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
1074                 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1075                 encoder_type = DRM_MODE_ENCODER_DAC;
1076                 connector_type = DRM_MODE_CONNECTOR_VGA;
1077         }
1078         else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
1079         {
1080                 sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
1081                 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1082                 encoder_type = DRM_MODE_ENCODER_DAC;
1083                 connector_type = DRM_MODE_CONNECTOR_VGA;
1084         }
1085         else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
1086         {
1087                 sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
1088                 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1089                 encoder_type = DRM_MODE_ENCODER_TMDS;
1090                 connector_type = DRM_MODE_CONNECTOR_DVID;
1091         }
1092         else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
1093         {
1094                 sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
1095                 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1096                 encoder_type = DRM_MODE_ENCODER_TMDS;
1097                 connector_type = DRM_MODE_CONNECTOR_DVID;
1098         }
1099         else
1100         {
1101                 unsigned char bytes[2];
1102                 
1103                 memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
1104                 DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
1105                           SDVO_NAME(sdvo_priv),
1106                           bytes[0], bytes[1]);
1107                 goto err_i2c;
1108         }
1109         
1110         drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type);
1111         drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
1112         connector->connector_type = connector_type;
1113
1114         drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
1115         drm_sysfs_connector_add(connector);
1116
1117         /* Set the input timing to the screen. Assume always input 0. */
1118         intel_sdvo_set_target_input(intel_output, true, false);
1119         
1120         intel_sdvo_get_input_pixel_clock_range(intel_output,
1121                                                &sdvo_priv->pixel_clock_min,
1122                                                &sdvo_priv->pixel_clock_max);
1123
1124
1125         DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, "
1126                   "clock range %dMHz - %dMHz, "
1127                   "input 1: %c, input 2: %c, "
1128                   "output 1: %c, output 2: %c\n",
1129                   SDVO_NAME(sdvo_priv),
1130                   sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
1131                   sdvo_priv->caps.device_rev_id,
1132                   sdvo_priv->pixel_clock_min / 1000,
1133                   sdvo_priv->pixel_clock_max / 1000,
1134                   (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
1135                   (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
1136                   /* check currently supported outputs */
1137                   sdvo_priv->caps.output_flags & 
1138                         (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
1139                   sdvo_priv->caps.output_flags & 
1140                         (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
1141
1142         intel_output->ddc_bus = i2cbus;
1143
1144         return;
1145
1146 err_i2c:
1147         intel_i2c_destroy(intel_output->i2c_bus);
1148 err_connector:
1149         drm_connector_cleanup(connector);
1150         kfree(intel_output);
1151
1152         return;
1153 }