Merge commit 'origin/master' into projective-965

This commit is contained in:
Keith Packard 2008-04-04 19:19:35 -07:00
commit dcbdc901d6
2 changed files with 481 additions and 42 deletions

View File

@ -59,7 +59,7 @@ struct i830_sdvo_priv {
int output_device;
/** Active outputs controlled by this SDVO output */
uint16_t active_outputs;
uint16_t controlled_output;
/**
* Capabilities of the SDVO device returned by i830_sdvo_get_capabilities()
@ -69,6 +69,32 @@ struct i830_sdvo_priv {
/** Pixel clock limitations reported by the SDVO device, in kHz */
int pixel_clock_min, pixel_clock_max;
/**
* This is set if we're going to treat the device as TV-out.
*
* While we have these nice friendly flags for output types that ought to
* decide this for us, the S-Video output on our HDMI+S-Video card shows
* up as RGB1 (VGA).
*/
Bool is_tv;
/**
* Returned SDTV resolutions allowed for the current format, if the
* device reported it.
*/
struct i830_sdvo_sdtv_resolution_reply sdtv_resolutions;
/**
* Current selected TV format.
*
* This is stored in the same structure that's passed to the device, for
* convenience.
*/
struct i830_sdvo_tv_format tv_format;
/** DDC bus used by this SDVO output */
uint8_t ddc_bus;
/** State for save/restore */
/** @{ */
int save_sdvo_mult;
@ -201,11 +227,13 @@ const static struct _sdvo_cmd_name {
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT),
SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS),
};
static I2CSlaveAddr slaveAddr;
#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVO" : "SDVO")
#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
#define SDVO_PRIV(output) ((struct i830_sdvo_priv *) (output)->dev_priv)
/**
@ -643,13 +671,26 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
uint16_t width, height;
uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
uint16_t h_sync_offset, v_sync_offset;
struct i830_sdvo_in_out_map in_out;
struct i830_sdvo_dtd output_dtd;
uint16_t no_outputs;
no_outputs = 0;
uint8_t status;
if (!mode)
return;
/* First, set the input mapping for the first input to our controlled
* output. This is only correct if we're a single-input device, in
* which case the first input is the output from the appropriate SDVO
* channel on the motherboard. In a two-input device, the first input
* will be SDVOB and the second SDVOC.
*/
in_out.in0 = dev_priv->controlled_output;
in_out.in1 = 0;
i830_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
&in_out, sizeof(in_out));
status = i830_sdvo_read_response(output, NULL, 0);
width = mode->CrtcHDisplay;
height = mode->CrtcVDisplay;
@ -692,7 +733,7 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
output_dtd.part2.reserved = 0;
/* Set the output timing to the screen */
i830_sdvo_set_target_output(output, dev_priv->active_outputs);
i830_sdvo_set_target_output(output, dev_priv->controlled_output);
i830_sdvo_set_output_timing(output, &output_dtd);
/* Set the input timing to the screen. Assume always input 0. */
@ -800,7 +841,7 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode)
if (0)
i830_sdvo_set_encoder_power_state(output, mode);
i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
i830_sdvo_set_active_outputs(output, dev_priv->controlled_output);
}
}
@ -818,12 +859,10 @@ i830_sdvo_save(xf86OutputPtr output)
dev_priv->save_sdvo_mult = i830_sdvo_get_clock_rate_mult(output);
i830_sdvo_get_active_outputs(output, &dev_priv->save_active_outputs);
if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
i830_sdvo_set_target_input(output, TRUE, FALSE);
i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_1);
}
i830_sdvo_set_target_input(output, TRUE, FALSE);
i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_1);
if (dev_priv->caps.sdvo_inputs_mask & 0x2) {
if (dev_priv->caps.sdvo_input_count >= 2) {
i830_sdvo_set_target_input(output, FALSE, TRUE);
i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_2);
}
@ -837,6 +876,9 @@ i830_sdvo_save(xf86OutputPtr output)
i830_sdvo_get_output_timing(output, &dev_priv->save_output_dtd[o]);
}
}
if (dev_priv->is_tv) {
/* XXX: Save TV format/enhancements. */
}
dev_priv->save_SDVOX = INREG(dev_priv->output_device);
}
@ -864,18 +906,20 @@ i830_sdvo_restore(xf86OutputPtr output)
}
}
if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
i830_sdvo_set_target_input(output, TRUE, FALSE);
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
}
i830_sdvo_set_target_input(output, TRUE, FALSE);
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
if (dev_priv->caps.sdvo_inputs_mask & 0x2) {
if (dev_priv->caps.sdvo_input_count >= 2) {
i830_sdvo_set_target_input(output, FALSE, TRUE);
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2);
}
i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult);
if (dev_priv->is_tv) {
/* XXX: Restore TV format/enhancements. */
}
i830_sdvo_write_sdvox(output, dev_priv->save_SDVOX);
if (dev_priv->save_SDVOX & SDVO_ENABLE)
@ -970,8 +1014,9 @@ i830_sdvo_ddc_i2c_start(I2CBusPtr b, int timeout)
xf86OutputPtr output = b->DriverPrivate.ptr;
I830OutputPrivatePtr intel_output = output->driver_private;
I2CBusPtr i2cbus = intel_output->pI2CBus;
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
i830_sdvo_set_control_bus_switch(output, SDVO_CONTROL_BUS_DDC2);
i830_sdvo_set_control_bus_switch(output, dev_priv->ddc_bus);
return i2cbus->I2CStart(i2cbus, timeout);
}
@ -1052,6 +1097,8 @@ i830_sdvo_dump_device(xf86OutputPtr output)
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_CLOCK_RATE_MULT);
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_TV_FORMATS);
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_TV_FORMAT);
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT);
i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS);
}
void
@ -1098,7 +1145,7 @@ i830_sdvo_detect(xf86OutputPtr output)
}
static DisplayModePtr
i830_sdvo_get_modes(xf86OutputPtr output)
i830_sdvo_get_ddc_modes(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@ -1130,6 +1177,128 @@ i830_sdvo_get_modes(xf86OutputPtr output)
return modes;
}
/**
* Constructs a DisplayModeRec for the given widht/height/refresh, which will
* be programmed into the display pipe. The TV encoder's scaler will filter
* this to the format actually required by the display.
*/
static void
i830_sdvo_get_tv_mode(DisplayModePtr *head, int width, int height,
float refresh)
{
DisplayModePtr mode;
mode = xcalloc(1, sizeof(*mode));
if (mode == NULL)
return;
mode->name = XNFprintf("%dx%d@%.2f", width, height, refresh);
mode->HDisplay = width;
mode->HSyncStart = width + 1;
mode->HSyncEnd = width + 64;
mode->HTotal = width + 96;
mode->VDisplay = height;
mode->VSyncStart = height + 1;
mode->VSyncEnd = height + 32;
mode->VTotal = height + 33;
mode->Clock = (int) (refresh * mode->VTotal * mode->HTotal / 1000.0);
mode->type = M_T_DRIVER;
mode->next = NULL;
mode->prev = NULL;
mode->next = NULL;
mode->prev = *head;
if (*head != NULL)
(*head)->next = mode;
else
*head = mode;
}
/**
* This function checks the current TV format, and chooses a default if
* it hasn't been set.
*/
static void
i830_sdvo_check_tv_format(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
I830OutputPrivatePtr intel_output = output->driver_private;
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
struct i830_sdvo_tv_format format, unset;
uint8_t status;
i830_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
status = i830_sdvo_read_response(output, &format, sizeof(format));
if (status != SDVO_CMD_STATUS_SUCCESS)
return;
memset(&unset, 0, sizeof(unset));
if (memcmp(&format, &unset, sizeof(format))) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"%s: Choosing default TV format of NTSC-M\n",
SDVO_NAME(dev_priv));
format.ntsc_m = TRUE;
i830_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0);
status = i830_sdvo_read_response(output, NULL, 0);
}
}
static DisplayModePtr
i830_sdvo_get_tv_modes(xf86OutputPtr output)
{
I830OutputPrivatePtr intel_output = output->driver_private;
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
DisplayModePtr modes = NULL;
struct i830_sdvo_sdtv_resolution_reply *res = &dev_priv->sdtv_resolutions;
uint8_t status;
float refresh = 60; /* XXX */
i830_sdvo_check_tv_format(output);
/* Read the list of supported input resolutions for the selected TV format.
*/
i830_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, NULL, 0);
status = i830_sdvo_read_response(output, res, sizeof(*res));
if (status != SDVO_CMD_STATUS_SUCCESS)
return NULL;
if (res->res_320x200) i830_sdvo_get_tv_mode(&modes, 320, 200, refresh);
if (res->res_320x240) i830_sdvo_get_tv_mode(&modes, 320, 240, refresh);
if (res->res_400x300) i830_sdvo_get_tv_mode(&modes, 400, 300, refresh);
if (res->res_640x350) i830_sdvo_get_tv_mode(&modes, 640, 350, refresh);
if (res->res_640x400) i830_sdvo_get_tv_mode(&modes, 640, 400, refresh);
if (res->res_640x480) i830_sdvo_get_tv_mode(&modes, 640, 480, refresh);
if (res->res_704x480) i830_sdvo_get_tv_mode(&modes, 704, 480, refresh);
if (res->res_704x576) i830_sdvo_get_tv_mode(&modes, 704, 576, refresh);
if (res->res_720x350) i830_sdvo_get_tv_mode(&modes, 720, 350, refresh);
if (res->res_720x400) i830_sdvo_get_tv_mode(&modes, 720, 400, refresh);
if (res->res_720x480) i830_sdvo_get_tv_mode(&modes, 720, 480, refresh);
if (res->res_720x540) i830_sdvo_get_tv_mode(&modes, 720, 540, refresh);
if (res->res_720x576) i830_sdvo_get_tv_mode(&modes, 720, 576, refresh);
if (res->res_800x600) i830_sdvo_get_tv_mode(&modes, 800, 600, refresh);
if (res->res_832x624) i830_sdvo_get_tv_mode(&modes, 832, 624, refresh);
if (res->res_920x766) i830_sdvo_get_tv_mode(&modes, 920, 766, refresh);
if (res->res_1024x768) i830_sdvo_get_tv_mode(&modes, 1024, 768, refresh);
if (res->res_1280x1024) i830_sdvo_get_tv_mode(&modes, 1280, 1024, refresh);
return modes;
}
static DisplayModePtr
i830_sdvo_get_modes(xf86OutputPtr output)
{
I830OutputPrivatePtr intel_output = output->driver_private;
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
if (dev_priv->is_tv)
return i830_sdvo_get_tv_modes(output);
else
return i830_sdvo_get_ddc_modes(output);
}
static void
i830_sdvo_destroy (xf86OutputPtr output)
{
@ -1177,6 +1346,60 @@ static const xf86OutputFuncsRec i830_sdvo_output_funcs = {
#endif
};
static unsigned int count_bits(uint32_t mask)
{
unsigned int n;
for (n = 0; mask; n++)
mask &= mask - 1;
return n;
}
/**
* Choose the appropriate DDC bus for control bus switch command for this
* SDVO output based on the controlled output.
*
* DDC bus number assignment is in a priority order of RGB outputs, then TMDS
* outputs, then LVDS outputs.
*/
static void
i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv)
{
uint16_t mask = 0;
unsigned int num_bits;
/* Make a mask of outputs less than or equal to our own priority in the
* list.
*/
switch (dev_priv->controlled_output) {
case SDVO_OUTPUT_LVDS1:
mask |= SDVO_OUTPUT_LVDS1;
case SDVO_OUTPUT_LVDS0:
mask |= SDVO_OUTPUT_LVDS0;
case SDVO_OUTPUT_TMDS1:
mask |= SDVO_OUTPUT_TMDS1;
case SDVO_OUTPUT_TMDS0:
mask |= SDVO_OUTPUT_TMDS0;
case SDVO_OUTPUT_RGB1:
mask |= SDVO_OUTPUT_RGB1;
case SDVO_OUTPUT_RGB0:
mask |= SDVO_OUTPUT_RGB0;
break;
}
/* Count bits to find what number we are in the priority list. */
mask &= dev_priv->caps.output_flags;
num_bits = count_bits(mask);
if (num_bits > 3) {
/* if more than 3 outputs, default to DDC bus 3 for now */
num_bits = 3;
}
/* Corresponds to SDVO_CONTROL_BUS_DDCx */
dev_priv->ddc_bus = 1 << num_bits;
}
void
i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
{
@ -1294,28 +1517,34 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
i830_sdvo_get_capabilities(output, &dev_priv->caps);
memset(&dev_priv->active_outputs, 0, sizeof(dev_priv->active_outputs));
if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
{
dev_priv->active_outputs = SDVO_OUTPUT_TMDS0;
dev_priv->controlled_output = SDVO_OUTPUT_TMDS0;
output->subpixel_order = SubPixelHorizontalRGB;
name_prefix="TMDS";
}
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
{
dev_priv->active_outputs = SDVO_OUTPUT_TMDS1;
dev_priv->controlled_output = SDVO_OUTPUT_TMDS1;
output->subpixel_order = SubPixelHorizontalRGB;
name_prefix="TMDS";
}
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
{
dev_priv->controlled_output = SDVO_OUTPUT_SVID0;
output->subpixel_order = SubPixelHorizontalRGB; /* XXX */
name_prefix="TV";
dev_priv->is_tv = TRUE;
}
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
{
dev_priv->active_outputs = SDVO_OUTPUT_RGB0;
dev_priv->controlled_output = SDVO_OUTPUT_RGB0;
output->subpixel_order = SubPixelHorizontalRGB;
name_prefix="VGA";
}
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
{
dev_priv->active_outputs = SDVO_OUTPUT_RGB1;
dev_priv->controlled_output = SDVO_OUTPUT_RGB1;
output->subpixel_order = SubPixelHorizontalRGB;
name_prefix="VGA";
}
@ -1323,13 +1552,15 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
{
unsigned char bytes[2];
dev_priv->controlled_output = 0;
memcpy (bytes, &dev_priv->caps.output_flags, 2);
xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR,
"%s: No active TMDS outputs (0x%02x%02x)\n",
xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING,
"%s: Unknown SDVO output type (0x%02x%02x)\n",
SDVO_NAME(dev_priv),
bytes[0], bytes[1]);
name_prefix="Unknown";
}
strcpy (name, name_prefix);
strcat (name, name_suffix);
if (!xf86OutputRename (output, name))
@ -1337,8 +1568,9 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
xf86OutputDestroy (output);
return;
}
i830_sdvo_select_ddc_bus(dev_priv);
/* Set the input timing to the screen. Assume always input 0. */
i830_sdvo_set_target_input(output, TRUE, FALSE);
@ -1346,17 +1578,40 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
&dev_priv->pixel_clock_max);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"%s device VID/DID: %02X:%02X.%02X, "
"clock range %.1fMHz - %.1fMHz, "
"input 1: %c, input 2: %c, "
"output 1: %c, output 2: %c\n",
"%s: device VID/DID: %02X:%02X.%02X, "
"clock range %.1fMHz - %.1fMHz\n",
SDVO_NAME(dev_priv),
dev_priv->caps.vendor_id, dev_priv->caps.device_id,
dev_priv->caps.device_rev_id,
dev_priv->pixel_clock_min / 1000.0,
dev_priv->pixel_clock_max / 1000.0,
(dev_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
(dev_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_TMDS0) ? 'Y' : 'N',
dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB1 | SDVO_OUTPUT_TMDS1) ? 'Y' : 'N');
dev_priv->pixel_clock_max / 1000.0);
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"%s: %d input channel%s\n",
SDVO_NAME(dev_priv), dev_priv->caps.sdvo_input_count,
dev_priv->caps.sdvo_input_count >= 2 ? "s" : "");
#define REPORT_OUTPUT_FLAG(flag, name) do { \
if (dev_priv->caps.output_flags & flag) { \
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: %s output reported\n", \
SDVO_NAME(dev_priv), name); \
} \
} while (0)
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_TMDS0, "TMDS0");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_RGB0, "RGB0");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_CVBS0, "CVBS0");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SVID0, "SVID0");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_YPRPB0, "YPRPB0");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART0, "SCART0");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS0, "LVDS0");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_TMDS1, "TMDS1");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_RGB1, "RGB1");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_CVBS1, "CVBS1");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SVID1, "SVID1");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_YPRPB1, "YPRPB1");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART1, "SCART1");
REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS1, "LVDS1");
}

View File

@ -52,7 +52,7 @@ struct i830_sdvo_caps {
uint8_t device_rev_id;
uint8_t sdvo_version_major;
uint8_t sdvo_version_minor;
unsigned int sdvo_inputs_mask:2;
unsigned int sdvo_input_count:2;
unsigned int smooth_scaling:1;
unsigned int sharp_scaling:1;
unsigned int up_scaling:1;
@ -174,6 +174,9 @@ struct i830_sdvo_get_trained_inputs_response {
* Returns two struct i830_sdvo_output_flags structures.
*/
#define SDVO_CMD_GET_IN_OUT_MAP 0x06
struct i830_sdvo_in_out_map {
uint16_t in0, in1;
};
/**
* Sets the current mapping of SDVO inputs to outputs on the device.
@ -306,11 +309,107 @@ struct i830_sdvo_set_target_input_args {
# define SDVO_CLOCK_RATE_MULT_4X (1 << 3)
#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27
/** 5 bytes of bit flags for TV formats shared by all TV format functions */
struct i830_sdvo_tv_format {
unsigned int ntsc_m:1;
unsigned int ntsc_j:1;
unsigned int ntsc_443:1;
unsigned int pal_b:1;
unsigned int pal_d:1;
unsigned int pal_g:1;
unsigned int pal_h:1;
unsigned int pal_i:1;
unsigned int pal_m:1;
unsigned int pal_n:1;
unsigned int pal_nc:1;
unsigned int pal_60:1;
unsigned int secam_b:1;
unsigned int secam_d:1;
unsigned int secam_g:1;
unsigned int secam_k:1;
unsigned int secam_k1:1;
unsigned int secam_l:1;
unsigned int secam_60:1;
unsigned int hdtv_std_smpte_240m_1080i_59:1;
unsigned int hdtv_std_smpte_240m_1080i_60:1;
unsigned int hdtv_std_smpte_260m_1080i_59:1;
unsigned int hdtv_std_smpte_260m_1080i_60:1;
unsigned int hdtv_std_smpte_270m_1080i_50:1;
unsigned int hdtv_std_smpte_274m_1080i_50:1;
unsigned int hdtv_std_smpte_274m_1080i_59:1;
unsigned int hdtv_std_smpte_274m_1080i_60:1;
unsigned int hdtv_std_smpte_274m_1080p_23:1;
unsigned int hdtv_std_smpte_274m_1080p_24:1;
unsigned int hdtv_std_smpte_274m_1080p_25:1;
unsigned int hdtv_std_smpte_274m_1080p_29:1;
unsigned int hdtv_std_smpte_274m_1080p_50:1;
unsigned int hdtv_std_smpte_274m_1080p_59:1;
unsigned int hdtv_std_smpte_274m_1080p_60:1;
unsigned int hdtv_std_smpte_295m_1080i_50:1;
unsigned int hdtv_std_smpte_295m_1080p_50:1;
unsigned int hdtv_std_smpte_296m_720p_59:1;
unsigned int hdtv_std_smpte_296m_720p_60:1;
unsigned int hdtv_std_smpte_296m_720p_50:1;
unsigned int hdtv_std_smpte_293m_480p_59:1;
unsigned int hdtv_std_smpte_270m_480i_59:1;
unsigned int hdtv_std_iturbt601_576i_50:1;
unsigned int hdtv_std_iturbt601_576p_50:1;
unsigned int hdtv_std_eia_7702a_480i_60:1;
unsigned int hdtv_std_eia_7702a_480p_60:1;
unsigned int pad:3;
} __attribute__((packed));
#define SDVO_CMD_GET_TV_FORMAT 0x28
/** This command should be run before SetOutputTimingsPart[12] */
#define SDVO_CMD_SET_TV_FORMAT 0x29
/** Returns the resolutiosn that can be used with the given TV format */
#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83
struct i830_sdvo_sdtv_resolution_request {
unsigned int ntsc_m:1;
unsigned int ntsc_j:1;
unsigned int ntsc_443:1;
unsigned int pal_b:1;
unsigned int pal_d:1;
unsigned int pal_g:1;
unsigned int pal_h:1;
unsigned int pal_i:1;
unsigned int pal_m:1;
unsigned int pal_n:1;
unsigned int pal_nc:1;
unsigned int pal_60:1;
} __attribute__((packed));
struct i830_sdvo_sdtv_resolution_reply {
unsigned int res_320x200:1;
unsigned int res_320x240:1;
unsigned int res_400x300:1;
unsigned int res_640x350:1;
unsigned int res_640x400:1;
unsigned int res_640x480:1;
unsigned int res_704x480:1;
unsigned int res_704x576:1;
unsigned int res_720x350:1;
unsigned int res_720x400:1;
unsigned int res_720x480:1;
unsigned int res_720x540:1;
unsigned int res_720x576:1;
unsigned int res_800x600:1;
unsigned int res_832x624:1;
unsigned int res_920x766:1;
unsigned int res_1024x768:1;
unsigned int res_1280x1024:1;
unsigned int pad:5;
} __attribute__((packed));
#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a
#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b
#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c
@ -319,11 +418,96 @@ struct i830_sdvo_set_target_input_args {
# define SDVO_ENCODER_STATE_SUSPEND (1 << 2)
# define SDVO_ENCODER_STATE_OFF (1 << 3)
#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84
struct i830_sdvo_enhancements_reply {
unsigned int flicker_filter:1;
unsigned int flicker_filter_adaptive:1;
unsigned int flicker_filter_2d:1;
unsigned int saturation:1;
unsigned int hue:1;
unsigned int brightness:1;
unsigned int contrast:1;
unsigned int overscan_h:1;
unsigned int overscan_v:1;
unsigned int position_h:1;
unsigned int position_v:1;
unsigned int sharpness:1;
unsigned int dot_crawl:1;
unsigned int dither:1;
unsigned int max_tv_chroma_filter:1;
unsigned int max_tv_luma_filter:1;
} __attribute__((packed));
/* Picture enhancement limits below are dependent on the current TV format,
* and thus need to be queried and set after it.
*/
#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d
#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b
#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52
#define SDVO_CMD_GET_MAX_SATURATION 0x55
#define SDVO_CMD_GET_MAX_HUE 0x58
#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5c
#define SDVO_CMD_GET_MAX_CONTRAST 0x5e
#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61
#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64
#define SDVO_CMD_GET_MAX_POSITION_H 0x67
#define SDVO_CMD_GET_MAX_POSITION_V 0x6a
#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d
#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74
#define SDVO_CMD_GET_MAX_TV_LUMA 0x77
struct i830_sdvo_enhancement_limits_reply {
uint16_t max_value;
uint16_t default_value;
} __attribute__((packed));
#define SDVO_CMD_GET_FLICKER_FITER 0x4d
#define SDVO_CMD_SET_FLICKER_FITER 0x4e
#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50
#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51
#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53
#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54
#define SDVO_CMD_GET_SATURATION 0x56
#define SDVO_CMD_SET_SATURATION 0x57
#define SDVO_CMD_GET_HUE 0x59
#define SDVO_CMD_SET_HUE 0x5a
#define SDVO_CMD_GET_BRIGHTNESS 0x5c
#define SDVO_CMD_SET_BRIGHTNESS 0x5d
#define SDVO_CMD_GET_CONTRAST 0x5f
#define SDVO_CMD_SET_CONTRAST 0x60
#define SDVO_CMD_GET_OVERSCAN_H 0x62
#define SDVO_CMD_SET_OVERSCAN_H 0x63
#define SDVO_CMD_GET_OVERSCAN_V 0x65
#define SDVO_CMD_SET_OVERSCAN_V 0x66
#define SDVO_CMD_GET_POSITION_H 0x68
#define SDVO_CMD_SET_POSITION_H 0x69
#define SDVO_CMD_GET_POSITION_V 0x6b
#define SDVO_CMD_SET_POSITION_V 0x6c
#define SDVO_CMD_GET_SHARPNESS 0x6e
#define SDVO_CMD_SET_SHARPNESS 0x6f
#define SDVO_CMD_GET_TV_CHROMA 0x75
#define SDVO_CMD_SET_TV_CHROMA 0x76
#define SDVO_CMD_GET_TV_LUMA 0x78
#define SDVO_CMD_SET_TV_LUMA 0x79
struct i830_sdvo_enhancements_arg {
uint16_t value;
}__attribute__((packed));
#define SDVO_CMD_GET_DOT_CRAWL 0x70
#define SDVO_CMD_SET_DOT_CRAWL 0x71
# define SDVO_DOT_CRAWL_ON (1 << 0)
# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1)
#define SDVO_CMD_GET_DITHER 0x72
#define SDVO_CMD_SET_DITHER 0x73
# define SDVO_DITHER_ON (1 << 0)
# define SDVO_DITHER_DEFAULT_ON (1 << 1)
#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93
#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a
# define SDVO_CONTROL_BUS_PROM 0x0
# define SDVO_CONTROL_BUS_DDC1 0x1
# define SDVO_CONTROL_BUS_DDC2 0x2
# define SDVO_CONTROL_BUS_DDC3 0x3
# define SDVO_CONTROL_BUS_PROM (1 << 0)
# define SDVO_CONTROL_BUS_DDC1 (1 << 1)
# define SDVO_CONTROL_BUS_DDC2 (1 << 2)
# define SDVO_CONTROL_BUS_DDC3 (1 << 3)