/*
 * Copyright (c) 2006-2007 Intel Corporation
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Authors:
 *	Eric Anholt <eric@anholt.net>
 */

#include <linux/i2c.h>
#include <linux/delay.h>
/* #include <drm/drm_crtc.h> */
#include <drm/drmP.h>
#include "psb_drv.h"
#include "psb_intel_drv.h"
#include "psb_intel_reg.h"
#include "psb_intel_sdvo_regs.h"

struct psb_intel_sdvo_priv {
	struct psb_intel_i2c_chan *i2c_bus;
	int slaveaddr;
	int output_device;

	u16 active_outputs;

	struct psb_intel_sdvo_caps caps;
	int pixel_clock_min, pixel_clock_max;

	int save_sdvo_mult;
	u16 save_active_outputs;
	struct psb_intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
	struct psb_intel_sdvo_dtd save_output_dtd[16];
	u32 save_SDVOX;
	u8 in_out_map[4];

	u8 by_input_wiring;
	u32 active_device;
};

/**
 * Writes the SDVOB or SDVOC with the given value, but always writes both
 * SDVOB and SDVOC to work around apparent hardware issues (according to
 * comments in the BIOS).
 */
void psb_intel_sdvo_write_sdvox(struct psb_intel_output *psb_intel_output,
				u32 val)
{
	struct drm_device *dev = psb_intel_output->base.dev;
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
	u32 bval = val, cval = val;
	int i;

	if (sdvo_priv->output_device == SDVOB)
		cval = REG_READ(SDVOC);
	else
		bval = REG_READ(SDVOB);
	/*
	 * Write the registers twice for luck. Sometimes,
	 * writing them only once doesn't appear to 'stick'.
	 * The BIOS does this too. Yay, magic
	 */
	for (i = 0; i < 2; i++) {
		REG_WRITE(SDVOB, bval);
		REG_READ(SDVOB);
		REG_WRITE(SDVOC, cval);
		REG_READ(SDVOC);
	}
}

static bool psb_intel_sdvo_read_byte(
				struct psb_intel_output *psb_intel_output,
				u8 addr, u8 *ch)
{
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
	u8 out_buf[2];
	u8 buf[2];
	int ret;

	struct i2c_msg msgs[] = {
		{
		 .addr = sdvo_priv->i2c_bus->slave_addr,
		 .flags = 0,
		 .len = 1,
		 .buf = out_buf,
		 },
		{
		 .addr = sdvo_priv->i2c_bus->slave_addr,
		 .flags = I2C_M_RD,
		 .len = 1,
		 .buf = buf,
		 }
	};

	out_buf[0] = addr;
	out_buf[1] = 0;

	ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2);
	if (ret == 2) {
		*ch = buf[0];
		return true;
	}

	return false;
}

static bool psb_intel_sdvo_write_byte(
			struct psb_intel_output *psb_intel_output,
			int addr, u8 ch)
{
	u8 out_buf[2];
	struct i2c_msg msgs[] = {
		{
		 .addr = psb_intel_output->i2c_bus->slave_addr,
		 .flags = 0,
		 .len = 2,
		 .buf = out_buf,
		 }
	};

	out_buf[0] = addr;
	out_buf[1] = ch;

	if (i2c_transfer(&psb_intel_output->i2c_bus->adapter, msgs, 1) == 1)
		return true;
	return false;
}

#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
/** Mapping of command numbers to names, for debug output */
static const struct _sdvo_cmd_name {
	u8 cmd;
	char *name;
} sdvo_cmd_names[] = {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
	    SDVO_CMD_NAME_ENTRY
	    (SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
	    SDVO_CMD_NAME_ENTRY
	    (SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
	    SDVO_CMD_NAME_ENTRY
	    (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
	    SDVO_CMD_NAME_ENTRY
	    (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
	    SDVO_CMD_NAME_ENTRY
	    (SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
	    SDVO_CMD_NAME_ENTRY
	    (SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
	    SDVO_CMD_NAME_ENTRY
	    (SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
	    SDVO_CMD_NAME_ENTRY
	    (SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
	    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),};

#define SDVO_NAME(dev_priv) \
		 ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
#define SDVO_PRIV(output)   ((struct psb_intel_sdvo_priv *) (output)->dev_priv)

static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output,
				     u8 cmd,
				     void *args,
				     int args_len)
{
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
	int i;

	if (0) {
		printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
		for (i = 0; i < args_len; i++)
			printk(KERN_CONT "%02X ", ((u8 *) args)[i]);
		for (; i < 8; i++)
			printk(KERN_CONT "   ");
		for (i = 0;
		     i <
		     sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]);
		     i++) {
			if (cmd == sdvo_cmd_names[i].cmd) {
				printk(KERN_CONT
					"(%s)", sdvo_cmd_names[i].name);
				break;
			}
		}
		if (i ==
		    sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]))
			printk(KERN_CONT "(%02X)", cmd);
		printk(KERN_CONT "\n");
	}

	for (i = 0; i < args_len; i++) {
		psb_intel_sdvo_write_byte(psb_intel_output,
					SDVO_I2C_ARG_0 - i,
					((u8 *) args)[i]);
	}

	psb_intel_sdvo_write_byte(psb_intel_output, SDVO_I2C_OPCODE, cmd);
}

static const char *const cmd_status_names[] = {
	"Power on",
	"Success",
	"Not supported",
	"Invalid arg",
	"Pending",
	"Target not specified",
	"Scaling not supported"
};

static u8 psb_intel_sdvo_read_response(
				struct psb_intel_output *psb_intel_output,
				void *response, int response_len)
{
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
	int i;
	u8 status;
	u8 retry = 50;

	while (retry--) {
		/* Read the command response */
		for (i = 0; i < response_len; i++) {
			psb_intel_sdvo_read_byte(psb_intel_output,
					     SDVO_I2C_RETURN_0 + i,
					     &((u8 *) response)[i]);
		}

		/* read the return status */
		psb_intel_sdvo_read_byte(psb_intel_output,
					 SDVO_I2C_CMD_STATUS,
					 &status);

		if (0) {
			pr_debug("%s: R: ", SDVO_NAME(sdvo_priv));
			for (i = 0; i < response_len; i++)
				printk(KERN_CONT "%02X ", ((u8 *) response)[i]);
			for (; i < 8; i++)
				printk("   ");
			if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
				printk(KERN_CONT "(%s)",
					 cmd_status_names[status]);
			else
				printk(KERN_CONT "(??? %d)", status);
			printk(KERN_CONT "\n");
		}

		if (status != SDVO_CMD_STATUS_PENDING)
			return status;

		mdelay(50);
	}

	return status;
}

int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
{
	if (mode->clock >= 100000)
		return 1;
	else if (mode->clock >= 50000)
		return 2;
	else
		return 4;
}

/**
 * Don't check status code from this as it switches the bus back to the
 * SDVO chips which defeats the purpose of doing a bus switch in the first
 * place.
 */
void psb_intel_sdvo_set_control_bus_switch(
				struct psb_intel_output *psb_intel_output,
				u8 target)
{
	psb_intel_sdvo_write_cmd(psb_intel_output,
				 SDVO_CMD_SET_CONTROL_BUS_SWITCH,
				 &target,
				 1);
}

static bool psb_intel_sdvo_set_target_input(
				struct psb_intel_output *psb_intel_output,
				bool target_0, bool target_1)
{
	struct psb_intel_sdvo_set_target_input_args targets = { 0 };
	u8 status;

	if (target_0 && target_1)
		return SDVO_CMD_STATUS_NOTSUPP;

	if (target_1)
		targets.target_1 = 1;

	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_INPUT,
			     &targets, sizeof(targets));

	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);

	return status == SDVO_CMD_STATUS_SUCCESS;
}

/**
 * Return whether each input is trained.
 *
 * This function is making an assumption about the layout of the response,
 * which should be checked against the docs.
 */
static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_output
					  *psb_intel_output, bool *input_1,
					  bool *input_2)
{
	struct psb_intel_sdvo_get_trained_inputs_response response;
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_TRAINED_INPUTS,
			     NULL, 0);
	status =
	    psb_intel_sdvo_read_response(psb_intel_output, &response,
				     sizeof(response));
	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;

	*input_1 = response.input0_trained;
	*input_2 = response.input1_trained;
	return true;
}

static bool psb_intel_sdvo_get_active_outputs(struct psb_intel_output
					  *psb_intel_output, u16 *outputs)
{
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS,
			     NULL, 0);
	status =
	    psb_intel_sdvo_read_response(psb_intel_output, outputs,
				     sizeof(*outputs));

	return status == SDVO_CMD_STATUS_SUCCESS;
}

static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_output
					  *psb_intel_output, u16 outputs)
{
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS,
			     &outputs, sizeof(outputs));
	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
	return status == SDVO_CMD_STATUS_SUCCESS;
}

static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_output
					       *psb_intel_output, int mode)
{
	u8 status, state = SDVO_ENCODER_STATE_ON;

	switch (mode) {
	case DRM_MODE_DPMS_ON:
		state = SDVO_ENCODER_STATE_ON;
		break;
	case DRM_MODE_DPMS_STANDBY:
		state = SDVO_ENCODER_STATE_STANDBY;
		break;
	case DRM_MODE_DPMS_SUSPEND:
		state = SDVO_ENCODER_STATE_SUSPEND;
		break;
	case DRM_MODE_DPMS_OFF:
		state = SDVO_ENCODER_STATE_OFF;
		break;
	}

	psb_intel_sdvo_write_cmd(psb_intel_output,
			     SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
			     sizeof(state));
	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);

	return status == SDVO_CMD_STATUS_SUCCESS;
}

static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_output
						   *psb_intel_output,
						   int *clock_min,
						   int *clock_max)
{
	struct psb_intel_sdvo_pixel_clock_range clocks;
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output,
			     SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL,
			     0);

	status =
	    psb_intel_sdvo_read_response(psb_intel_output, &clocks,
				     sizeof(clocks));

	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;

	/* Convert the values from units of 10 kHz to kHz. */
	*clock_min = clocks.min * 10;
	*clock_max = clocks.max * 10;

	return true;
}

static bool psb_intel_sdvo_set_target_output(
				struct psb_intel_output *psb_intel_output,
				u16 outputs)
{
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_OUTPUT,
			     &outputs, sizeof(outputs));

	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
	return status == SDVO_CMD_STATUS_SUCCESS;
}

static bool psb_intel_sdvo_get_timing(struct psb_intel_output *psb_intel_output,
				  u8 cmd, struct psb_intel_sdvo_dtd *dtd)
{
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output, cmd, NULL, 0);
	status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1,
					  sizeof(dtd->part1));
	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;

	psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, NULL, 0);
	status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2,
					  sizeof(dtd->part2));
	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;

	return true;
}

static bool psb_intel_sdvo_get_input_timing(
				struct psb_intel_output *psb_intel_output,
				struct psb_intel_sdvo_dtd *dtd)
{
	return psb_intel_sdvo_get_timing(psb_intel_output,
				     SDVO_CMD_GET_INPUT_TIMINGS_PART1,
				     dtd);
}

static bool psb_intel_sdvo_set_timing(
				struct psb_intel_output *psb_intel_output,
				u8 cmd,
				struct psb_intel_sdvo_dtd *dtd)
{
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output, cmd, &dtd->part1,
			     sizeof(dtd->part1));
	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;

	psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, &dtd->part2,
			     sizeof(dtd->part2));
	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;

	return true;
}

static bool psb_intel_sdvo_set_input_timing(
				struct psb_intel_output *psb_intel_output,
				struct psb_intel_sdvo_dtd *dtd)
{
	return psb_intel_sdvo_set_timing(psb_intel_output,
				     SDVO_CMD_SET_INPUT_TIMINGS_PART1,
				     dtd);
}

static bool psb_intel_sdvo_set_output_timing(
				struct psb_intel_output *psb_intel_output,
				struct psb_intel_sdvo_dtd *dtd)
{
	return psb_intel_sdvo_set_timing(psb_intel_output,
				     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1,
				     dtd);
}

static int psb_intel_sdvo_get_clock_rate_mult(struct psb_intel_output
						*psb_intel_output)
{
	u8 response, status;

	psb_intel_sdvo_write_cmd(psb_intel_output,
				 SDVO_CMD_GET_CLOCK_RATE_MULT,
				 NULL,
				 0);

	status = psb_intel_sdvo_read_response(psb_intel_output, &response, 1);

	if (status != SDVO_CMD_STATUS_SUCCESS) {
		DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
		return SDVO_CLOCK_RATE_MULT_1X;
	} else {
		DRM_DEBUG("Current clock rate multiplier: %d\n", response);
	}

	return response;
}

static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_output
						*psb_intel_output, u8 val)
{
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output,
				SDVO_CMD_SET_CLOCK_RATE_MULT,
				&val,
				1);

	status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;

	return true;
}

static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output,
					  u32 in0outputmask,
					  u32 in1outputmask)
{
	u8 byArgs[4];
	u8 status;
	int i;
	struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;

	/* Make all fields of the  args/ret to zero */
	memset(byArgs, 0, sizeof(byArgs));

	/* Fill up the argument values; */
	byArgs[0] = (u8) (in0outputmask & 0xFF);
	byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF);
	byArgs[2] = (u8) (in1outputmask & 0xFF);
	byArgs[3] = (u8) ((in1outputmask >> 8) & 0xFF);


	/*save inoutmap arg here*/
	for (i = 0; i < 4; i++)
		sdvo_priv->in_out_map[i] = byArgs[0];

	psb_intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, byArgs, 4);
	status = psb_intel_sdvo_read_response(output, NULL, 0);

	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;
	return true;
}


static void psb_intel_sdvo_set_iomap(struct psb_intel_output *output)
{
	u32 dwCurrentSDVOIn0 = 0;
	u32 dwCurrentSDVOIn1 = 0;
	u32 dwDevMask = 0;


	struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv;

	/* Please DO NOT change the following code. */
	/* SDVOB_IN0 or SDVOB_IN1 ==> sdvo_in0 */
	/* SDVOC_IN0 or SDVOC_IN1 ==> sdvo_in1 */
	if (sdvo_priv->by_input_wiring & (SDVOB_IN0 | SDVOC_IN0)) {
		switch (sdvo_priv->active_device) {
		case SDVO_DEVICE_LVDS:
			dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
			break;
		case SDVO_DEVICE_TMDS:
			dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
			break;
		case SDVO_DEVICE_TV:
			dwDevMask =
			SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
			SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
			SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
			SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
			break;
		case SDVO_DEVICE_CRT:
			dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
			break;
		}
		dwCurrentSDVOIn0 = (sdvo_priv->active_outputs & dwDevMask);
	} else if (sdvo_priv->by_input_wiring & (SDVOB_IN1 | SDVOC_IN1)) {
		switch (sdvo_priv->active_device) {
		case SDVO_DEVICE_LVDS:
			dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1;
			break;
		case SDVO_DEVICE_TMDS:
			dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1;
			break;
		case SDVO_DEVICE_TV:
			dwDevMask =
			SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 |
			SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 |
			SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 |
			SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1;
			break;
		case SDVO_DEVICE_CRT:
			dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1;
			break;
		}
		dwCurrentSDVOIn1 = (sdvo_priv->active_outputs & dwDevMask);
	}

	psb_sdvo_set_current_inoutmap(output, dwCurrentSDVOIn0,
					  dwCurrentSDVOIn1);
}


static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder,
				  struct drm_display_mode *mode,
				  struct drm_display_mode *adjusted_mode)
{
	/* Make the CRTC code factor in the SDVO pixel multiplier.  The SDVO
	 * device will be told of the multiplier during mode_set.
	 */
	adjusted_mode->clock *= psb_intel_sdvo_get_pixel_multiplier(mode);
	return true;
}

static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder,
				struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_crtc *crtc = encoder->crtc;
	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
	struct psb_intel_output *psb_intel_output =
					enc_to_psb_intel_output(encoder);
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
	u16 width, height;
	u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
	u16 h_sync_offset, v_sync_offset;
	u32 sdvox;
	struct psb_intel_sdvo_dtd output_dtd;
	int sdvo_pixel_multiply;

	if (!mode)
		return;

	psb_intel_sdvo_set_target_output(psb_intel_output, 0);

	width = mode->crtc_hdisplay;
	height = mode->crtc_vdisplay;

	/* do some mode translations */
	h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
	h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;

	v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
	v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;

	h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
	v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;

	output_dtd.part1.clock = mode->clock / 10;
	output_dtd.part1.h_active = width & 0xff;
	output_dtd.part1.h_blank = h_blank_len & 0xff;
	output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
	    ((h_blank_len >> 8) & 0xf);
	output_dtd.part1.v_active = height & 0xff;
	output_dtd.part1.v_blank = v_blank_len & 0xff;
	output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
	    ((v_blank_len >> 8) & 0xf);

	output_dtd.part2.h_sync_off = h_sync_offset;
	output_dtd.part2.h_sync_width = h_sync_len & 0xff;
	output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
	    (v_sync_len & 0xf);
	output_dtd.part2.sync_off_width_high =
	    ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) |
	    ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4);

	output_dtd.part2.dtd_flags = 0x18;
	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
		output_dtd.part2.dtd_flags |= 0x2;
	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
		output_dtd.part2.dtd_flags |= 0x4;

	output_dtd.part2.sdvo_flags = 0;
	output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
	output_dtd.part2.reserved = 0;

	/* Set the output timing to the screen */
	psb_intel_sdvo_set_target_output(psb_intel_output,
				     sdvo_priv->active_outputs);

	/* Set the input timing to the screen. Assume always input 0. */
	psb_intel_sdvo_set_target_input(psb_intel_output, true, false);

	psb_intel_sdvo_set_output_timing(psb_intel_output, &output_dtd);

	/* We would like to use i830_sdvo_create_preferred_input_timing() to
	 * provide the device with a timing it can support, if it supports that
	 * feature.  However, presumably we would need to adjust the CRTC to
	 * output the preferred timing, and we don't support that currently.
	 */
	psb_intel_sdvo_set_input_timing(psb_intel_output, &output_dtd);

	switch (psb_intel_sdvo_get_pixel_multiplier(mode)) {
	case 1:
		psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
					       SDVO_CLOCK_RATE_MULT_1X);
		break;
	case 2:
		psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
					       SDVO_CLOCK_RATE_MULT_2X);
		break;
	case 4:
		psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
					       SDVO_CLOCK_RATE_MULT_4X);
		break;
	}

	/* Set the SDVO control regs. */
	sdvox = REG_READ(sdvo_priv->output_device);
	switch (sdvo_priv->output_device) {
	case SDVOB:
		sdvox &= SDVOB_PRESERVE_MASK;
		break;
	case SDVOC:
		sdvox &= SDVOC_PRESERVE_MASK;
		break;
	}
	sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
	if (psb_intel_crtc->pipe == 1)
		sdvox |= SDVO_PIPE_B_SELECT;

	sdvo_pixel_multiply = psb_intel_sdvo_get_pixel_multiplier(mode);

	psb_intel_sdvo_write_sdvox(psb_intel_output, sdvox);

	 psb_intel_sdvo_set_iomap(psb_intel_output);
}

static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;
	struct psb_intel_output *psb_intel_output =
					enc_to_psb_intel_output(encoder);
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
	u32 temp;

	if (mode != DRM_MODE_DPMS_ON) {
		psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);
		if (0)
			psb_intel_sdvo_set_encoder_power_state(
							psb_intel_output,
							mode);

		if (mode == DRM_MODE_DPMS_OFF) {
			temp = REG_READ(sdvo_priv->output_device);
			if ((temp & SDVO_ENABLE) != 0) {
				psb_intel_sdvo_write_sdvox(psb_intel_output,
						       temp &
						       ~SDVO_ENABLE);
			}
		}
	} else {
		bool input1, input2;
		int i;
		u8 status;

		temp = REG_READ(sdvo_priv->output_device);
		if ((temp & SDVO_ENABLE) == 0)
			psb_intel_sdvo_write_sdvox(psb_intel_output,
					       temp | SDVO_ENABLE);
		for (i = 0; i < 2; i++)
			psb_intel_wait_for_vblank(dev);

		status =
		    psb_intel_sdvo_get_trained_inputs(psb_intel_output,
							&input1,
							&input2);


		/* Warn if the device reported failure to sync.
		 * A lot of SDVO devices fail to notify of sync, but it's
		 * a given it the status is a success, we succeeded.
		 */
		if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
			DRM_DEBUG
			    ("First %s output reported failure to sync\n",
			     SDVO_NAME(sdvo_priv));
		}

		if (0)
			psb_intel_sdvo_set_encoder_power_state(
							psb_intel_output,
							mode);
		psb_intel_sdvo_set_active_outputs(psb_intel_output,
					      sdvo_priv->active_outputs);
	}
	return;
}

static void psb_intel_sdvo_save(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
	struct psb_intel_output *psb_intel_output =
					to_psb_intel_output(connector);
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
	/*int o;*/

	sdvo_priv->save_sdvo_mult =
	    psb_intel_sdvo_get_clock_rate_mult(psb_intel_output);
	psb_intel_sdvo_get_active_outputs(psb_intel_output,
				      &sdvo_priv->save_active_outputs);

	if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
		psb_intel_sdvo_set_target_input(psb_intel_output,
						true,
						false);
		psb_intel_sdvo_get_input_timing(psb_intel_output,
					    &sdvo_priv->save_input_dtd_1);
	}

	if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
		psb_intel_sdvo_set_target_input(psb_intel_output,
						false,
						true);
		psb_intel_sdvo_get_input_timing(psb_intel_output,
					    &sdvo_priv->save_input_dtd_2);
	}
	sdvo_priv->save_SDVOX = REG_READ(sdvo_priv->output_device);

	/*TODO: save the in_out_map state*/
}

static void psb_intel_sdvo_restore(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
	struct psb_intel_output *psb_intel_output =
					to_psb_intel_output(connector);
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
	/*int o;*/
	int i;
	bool input1, input2;
	u8 status;

	psb_intel_sdvo_set_active_outputs(psb_intel_output, 0);

	if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
		psb_intel_sdvo_set_target_input(psb_intel_output, true, false);
		psb_intel_sdvo_set_input_timing(psb_intel_output,
					    &sdvo_priv->save_input_dtd_1);
	}

	if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
		psb_intel_sdvo_set_target_input(psb_intel_output, false, true);
		psb_intel_sdvo_set_input_timing(psb_intel_output,
					    &sdvo_priv->save_input_dtd_2);
	}

	psb_intel_sdvo_set_clock_rate_mult(psb_intel_output,
				       sdvo_priv->save_sdvo_mult);

	REG_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);

	if (sdvo_priv->save_SDVOX & SDVO_ENABLE) {
		for (i = 0; i < 2; i++)
			psb_intel_wait_for_vblank(dev);
		status =
		    psb_intel_sdvo_get_trained_inputs(psb_intel_output,
							&input1,
							&input2);
		if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
			DRM_DEBUG
			    ("First %s output reported failure to sync\n",
			     SDVO_NAME(sdvo_priv));
	}

	psb_intel_sdvo_set_active_outputs(psb_intel_output,
				      sdvo_priv->save_active_outputs);

	/*TODO: restore in_out_map*/
	psb_intel_sdvo_write_cmd(psb_intel_output,
				 SDVO_CMD_SET_IN_OUT_MAP,
				 sdvo_priv->in_out_map,
				 4);

	psb_intel_sdvo_read_response(psb_intel_output, NULL, 0);
}

static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
				 struct drm_display_mode *mode)
{
	struct psb_intel_output *psb_intel_output =
				to_psb_intel_output(connector);
	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;

	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
		return MODE_NO_DBLESCAN;

	if (sdvo_priv->pixel_clock_min > mode->clock)
		return MODE_CLOCK_LOW;

	if (sdvo_priv->pixel_clock_max < mode->clock)
		return MODE_CLOCK_HIGH;

	return MODE_OK;
}

static bool psb_intel_sdvo_get_capabilities(
				struct psb_intel_output *psb_intel_output,
				struct psb_intel_sdvo_caps *caps)
{
	u8 status;

	psb_intel_sdvo_write_cmd(psb_intel_output,
				 SDVO_CMD_GET_DEVICE_CAPS,
				 NULL,
				 0);
	status = psb_intel_sdvo_read_response(psb_intel_output,
						caps,
						sizeof(*caps));
	if (status != SDVO_CMD_STATUS_SUCCESS)
		return false;

	return true;
}

struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, int sdvoB)
{
	struct drm_connector *connector = NULL;
	struct psb_intel_output *iout = NULL;
	struct psb_intel_sdvo_priv *sdvo;

	/* find the sdvo connector */
	list_for_each_entry(connector, &dev->mode_config.connector_list,
			    head) {
		iout = to_psb_intel_output(connector);

		if (iout->type != INTEL_OUTPUT_SDVO)
			continue;

		sdvo = iout->dev_priv;

		if (sdvo->output_device == SDVOB && sdvoB)
			return connector;

		if (sdvo->output_device == SDVOC && !sdvoB)
			return connector;

	}

	return NULL;
}

int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector)
{
	u8 response[2];
	u8 status;
	struct psb_intel_output *psb_intel_output;

	if (!connector)
		return 0;

	psb_intel_output = to_psb_intel_output(connector);

	psb_intel_sdvo_write_cmd(psb_intel_output,
				 SDVO_CMD_GET_HOT_PLUG_SUPPORT,
				 NULL,
				 0);
	status = psb_intel_sdvo_read_response(psb_intel_output,
						&response,
						2);

	if (response[0] != 0)
		return 1;

	return 0;
}

void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
{
	u8 response[2];
	u8 status;
	struct psb_intel_output *psb_intel_output =
					to_psb_intel_output(connector);

	psb_intel_sdvo_write_cmd(psb_intel_output,
				 SDVO_CMD_GET_ACTIVE_HOT_PLUG,
				 NULL,
				 0);
	psb_intel_sdvo_read_response(psb_intel_output, &response, 2);

	if (on) {
		psb_intel_sdvo_write_cmd(psb_intel_output,
				     SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL,
				     0);
		status = psb_intel_sdvo_read_response(psb_intel_output,
						      &response,
						      2);

		psb_intel_sdvo_write_cmd(psb_intel_output,
				     SDVO_CMD_SET_ACTIVE_HOT_PLUG,
				     &response, 2);
	} else {
		response[0] = 0;
		response[1] = 0;
		psb_intel_sdvo_write_cmd(psb_intel_output,
				     SDVO_CMD_SET_ACTIVE_HOT_PLUG,
				     &response, 2);
	}

	psb_intel_sdvo_write_cmd(psb_intel_output,
				 SDVO_CMD_GET_ACTIVE_HOT_PLUG,
				 NULL,
				 0);
	psb_intel_sdvo_read_response(psb_intel_output, &response, 2);
}

static enum drm_connector_status psb_intel_sdvo_detect(struct drm_connector
						   *connector, bool force)
{
	u8 response[2];
	u8 status;
	struct psb_intel_output *psb_intel_output =
					to_psb_intel_output(connector);

	psb_intel_sdvo_write_cmd(psb_intel_output,
				 SDVO_CMD_GET_ATTACHED_DISPLAYS,
				 NULL,
				 0);
	status = psb_intel_sdvo_read_response(psb_intel_output, &response, 2);

	DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
	if ((response[0] != 0) || (response[1] != 0))
		return connector_status_connected;
	else
		return connector_status_disconnected;
}

static int psb_intel_sdvo_get_modes(struct drm_connector *connector)
{
	struct psb_intel_output *psb_intel_output =
					to_psb_intel_output(connector);

	/* set the bus switch and get the modes */
	psb_intel_sdvo_set_control_bus_switch(psb_intel_output,
					  SDVO_CONTROL_BUS_DDC2);
	psb_intel_ddc_get_modes(psb_intel_output);

	if (list_empty(&connector->probed_modes))
		return 0;
	return 1;
}

static void psb_intel_sdvo_destroy(struct drm_connector *connector)
{
	struct psb_intel_output *psb_intel_output =
				to_psb_intel_output(connector);

	if (psb_intel_output->i2c_bus)
		psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
	drm_sysfs_connector_remove(connector);
	drm_connector_cleanup(connector);
	kfree(psb_intel_output);
}

static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = {
	.dpms = psb_intel_sdvo_dpms,
	.mode_fixup = psb_intel_sdvo_mode_fixup,
	.prepare = psb_intel_encoder_prepare,
	.mode_set = psb_intel_sdvo_mode_set,
	.commit = psb_intel_encoder_commit,
};

static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
	.save = psb_intel_sdvo_save,
	.restore = psb_intel_sdvo_restore,
	.detect = psb_intel_sdvo_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = psb_intel_sdvo_destroy,
};

static const struct drm_connector_helper_funcs
				psb_intel_sdvo_connector_helper_funcs = {
	.get_modes = psb_intel_sdvo_get_modes,
	.mode_valid = psb_intel_sdvo_mode_valid,
	.best_encoder = psb_intel_best_encoder,
};

void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder)
{
	drm_encoder_cleanup(encoder);
}

static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = {
	.destroy = psb_intel_sdvo_enc_destroy,
};


void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
{
	struct drm_connector *connector;
	struct psb_intel_output *psb_intel_output;
	struct psb_intel_sdvo_priv *sdvo_priv;
	struct psb_intel_i2c_chan *i2cbus = NULL;
	int connector_type;
	u8 ch[0x40];
	int i;
	int encoder_type, output_id;

	psb_intel_output =
	    kcalloc(sizeof(struct psb_intel_output) +
		    sizeof(struct psb_intel_sdvo_priv), 1, GFP_KERNEL);
	if (!psb_intel_output)
		return;

	connector = &psb_intel_output->base;

	drm_connector_init(dev, connector, &psb_intel_sdvo_connector_funcs,
			   DRM_MODE_CONNECTOR_Unknown);
	drm_connector_helper_add(connector,
				 &psb_intel_sdvo_connector_helper_funcs);
	sdvo_priv = (struct psb_intel_sdvo_priv *) (psb_intel_output + 1);
	psb_intel_output->type = INTEL_OUTPUT_SDVO;

	connector->interlace_allowed = 0;
	connector->doublescan_allowed = 0;

	/* setup the DDC bus. */
	if (output_device == SDVOB)
		i2cbus =
		    psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
	else
		i2cbus =
		    psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");

	if (!i2cbus)
		goto err_connector;

	sdvo_priv->i2c_bus = i2cbus;

	if (output_device == SDVOB) {
		output_id = 1;
		sdvo_priv->by_input_wiring = SDVOB_IN0;
		sdvo_priv->i2c_bus->slave_addr = 0x38;
	} else {
		output_id = 2;
		sdvo_priv->i2c_bus->slave_addr = 0x39;
	}

	sdvo_priv->output_device = output_device;
	psb_intel_output->i2c_bus = i2cbus;
	psb_intel_output->dev_priv = sdvo_priv;


	/* Read the regs to test if we can talk to the device */
	for (i = 0; i < 0x40; i++) {
		if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) {
			dev_dbg(dev->dev, "No SDVO device found on SDVO%c\n",
				  output_device == SDVOB ? 'B' : 'C');
			goto err_i2c;
		}
	}

	psb_intel_sdvo_get_capabilities(psb_intel_output, &sdvo_priv->caps);

	memset(&sdvo_priv->active_outputs, 0,
	       sizeof(sdvo_priv->active_outputs));

	/* TODO, CVBS, SVID, YPRPB & SCART outputs. */
	if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) {
		sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
		sdvo_priv->active_device = SDVO_DEVICE_CRT;
		connector->display_info.subpixel_order =
		    SubPixelHorizontalRGB;
		encoder_type = DRM_MODE_ENCODER_DAC;
		connector_type = DRM_MODE_CONNECTOR_VGA;
	} else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) {
		sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
		sdvo_priv->active_outputs = SDVO_DEVICE_CRT;
		connector->display_info.subpixel_order =
		    SubPixelHorizontalRGB;
		encoder_type = DRM_MODE_ENCODER_DAC;
		connector_type = DRM_MODE_CONNECTOR_VGA;
	} else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) {
		sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
		sdvo_priv->active_device = SDVO_DEVICE_TMDS;
		connector->display_info.subpixel_order =
		    SubPixelHorizontalRGB;
		encoder_type = DRM_MODE_ENCODER_TMDS;
		connector_type = DRM_MODE_CONNECTOR_DVID;
	} else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) {
		sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
		sdvo_priv->active_device = SDVO_DEVICE_TMDS;
		connector->display_info.subpixel_order =
		    SubPixelHorizontalRGB;
		encoder_type = DRM_MODE_ENCODER_TMDS;
		connector_type = DRM_MODE_CONNECTOR_DVID;
	} else {
		unsigned char bytes[2];

		memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
		dev_dbg(dev->dev, "%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
		     SDVO_NAME(sdvo_priv), bytes[0], bytes[1]);
		goto err_i2c;
	}

	drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_sdvo_enc_funcs,
			 encoder_type);
	drm_encoder_helper_add(&psb_intel_output->enc,
			       &psb_intel_sdvo_helper_funcs);
	connector->connector_type = connector_type;

	drm_mode_connector_attach_encoder(&psb_intel_output->base,
					  &psb_intel_output->enc);
	drm_sysfs_connector_add(connector);

	/* Set the input timing to the screen. Assume always input 0. */
	psb_intel_sdvo_set_target_input(psb_intel_output, true, false);

	psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_output,
					       &sdvo_priv->pixel_clock_min,
					       &sdvo_priv->
					       pixel_clock_max);


	dev_dbg(dev->dev, "%s device VID/DID: %02X:%02X.%02X, "
		  "clock range %dMHz - %dMHz, "
		  "input 1: %c, input 2: %c, "
		  "output 1: %c, output 2: %c\n",
		  SDVO_NAME(sdvo_priv),
		  sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
		  sdvo_priv->caps.device_rev_id,
		  sdvo_priv->pixel_clock_min / 1000,
		  sdvo_priv->pixel_clock_max / 1000,
		  (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
		  (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
		  /* check currently supported outputs */
		  sdvo_priv->caps.output_flags &
		  (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
		  sdvo_priv->caps.output_flags &
		  (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');

	psb_intel_output->ddc_bus = i2cbus;

	return;

err_i2c:
	psb_intel_i2c_destroy(psb_intel_output->i2c_bus);
err_connector:
	drm_connector_cleanup(connector);
	kfree(psb_intel_output);

	return;
}
