Message ID | 1251687432-15345-1-git-send-email-yakui.zhao@intel.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
On Mon, 2009-08-31 at 10:57 +0800, Zhao, Yakui wrote: > From: Zhao Yakui <yakui.zhao@intel.com> Hi, Eric It seems that you already pick up two patches about TV property(select TV format according to connector type, Enable PAL and SECAM format and add the TV format propery for SDVO-TV) Will you please also pick up the two patches that add the property for SDVO-TV/LVDS? Patch 1: add the property for SDVO-TV(window control/saturation/hue/brightness/contrast, which is similar to what we have done for integrated TV) Patch 2: add the brightness property for SDVO-LVDS Thanks. > > When the sdvo device is detected as SDVO-TV, we will check whether the > sepecific picture enhancement is supported. If it is supported, we will > add the corresponnding property for SDVO-TV. We will add the following > property for the SDVO-TV enhancements if they are supported: > Contrast/Brightness/Saturation/Hue: > left/right/top/bottom margin: This is implemented by using the horizontal/ > vertical overscan enhancements. When the overscan enhancements are supported, > the above properties will be added. This is to be compatible with what we have > done in integrated-TV. > horizontal pos/vertical pos: > > http://bugs.freedesktop.org/show_bug.cgi?id=22891 > > Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> > --- > drivers/gpu/drm/i915/intel_sdvo.c | 482 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 478 insertions(+), 4 deletions(-) > > Index: linux-2.6/drivers/gpu/drm/i915/intel_sdvo.c > =================================================================== > --- linux-2.6.orig/drivers/gpu/drm/i915/intel_sdvo.c 2009-08-31 10:36:49.000000000 +0800 > +++ linux-2.6/drivers/gpu/drm/i915/intel_sdvo.c 2009-08-31 10:53:12.000000000 +0800 > @@ -132,6 +132,30 @@ > struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; > struct intel_sdvo_dtd save_output_dtd[16]; > u32 save_SDVOX; > + /* add the property for the SDVO-TV */ > + struct drm_property *left_property; > + struct drm_property *right_property; > + struct drm_property *top_property; > + struct drm_property *bottom_property; > + struct drm_property *hpos_property; > + struct drm_property *vpos_property; > + > + /* add the property for the SDVO-TV/LVDS */ > + struct drm_property *brightness_property; > + struct drm_property *contrast_property; > + struct drm_property *saturation_property; > + struct drm_property *hue_property; > + > + /* Add variable to record current setting for the above property */ > + u32 left_margin, right_margin, top_margin, bottom_margin; > + /* this is to get the range of margin.*/ > + u32 max_hscan, max_vscan; > + u32 max_hpos, cur_hpos; > + u32 max_vpos, cur_vpos; > + u32 cur_brightness, max_brightness; > + u32 cur_contrast, max_contrast; > + u32 cur_saturation, max_saturation; > + u32 cur_hue, max_hue; > }; > > static bool > @@ -278,6 +302,31 @@ > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), > + /* Add the op code for SDVO enhancements */ > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), > /* HDMI op code */ > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), > @@ -1749,6 +1798,42 @@ > return 1; > } > > +static > +void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) > +{ > + struct intel_output *intel_output = to_intel_output(connector); > + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; > + struct drm_device *dev = connector->dev; > + > + if (sdvo_priv->is_tv) { > + if (sdvo_priv->left_property) > + drm_property_destroy(dev, sdvo_priv->left_property); > + if (sdvo_priv->right_property) > + drm_property_destroy(dev, sdvo_priv->right_property); > + if (sdvo_priv->top_property) > + drm_property_destroy(dev, sdvo_priv->top_property); > + if (sdvo_priv->bottom_property) > + drm_property_destroy(dev, sdvo_priv->bottom_property); > + if (sdvo_priv->hpos_property) > + drm_property_destroy(dev, sdvo_priv->hpos_property); > + if (sdvo_priv->vpos_property) > + drm_property_destroy(dev, sdvo_priv->vpos_property); > + } > + if (sdvo_priv->is_tv) { > + if (sdvo_priv->saturation_property) > + drm_property_destroy(dev, sdvo_priv->saturation_property); > + if (sdvo_priv->contrast_property) > + drm_property_destroy(dev, sdvo_priv->contrast_property); > + if (sdvo_priv->hue_property) > + drm_property_destroy(dev, sdvo_priv->hue_property); > + } > + if (sdvo_priv->is_tv) { > + if (sdvo_priv->brightness_property) > + drm_property_destroy(dev, sdvo_priv->brightness_property); > + } > + return; > +} > + > static void intel_sdvo_destroy(struct drm_connector *connector) > { > struct intel_output *intel_output = to_intel_output(connector); > @@ -1767,6 +1852,9 @@ > drm_property_destroy(connector->dev, > sdvo_priv->tv_format_property); > > + if (sdvo_priv->is_tv) > + intel_sdvo_destroy_enhance_property(connector); > + > drm_sysfs_connector_remove(connector); > drm_connector_cleanup(connector); > > @@ -1784,6 +1872,8 @@ > struct drm_crtc *crtc = encoder->crtc; > int ret = 0; > bool changed = false; > + uint8_t cmd, status; > + uint16_t temp_value; > > ret = drm_connector_property_set_value(connector, property, val); > if (ret < 0) > @@ -1800,11 +1890,101 @@ > > sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; > changed = true; > - } else { > - ret = -EINVAL; > - goto out; > } > > + if (sdvo_priv->is_tv) { > + cmd = 0; > + temp_value = val; > + if (sdvo_priv->left_property == property) { > + drm_connector_property_set_value(connector, > + sdvo_priv->right_property, val); > + if (sdvo_priv->left_margin == temp_value) > + goto out; > + > + sdvo_priv->left_margin = temp_value; > + sdvo_priv->right_margin = temp_value; > + temp_value = sdvo_priv->max_hscan - > + sdvo_priv->left_margin; > + cmd = SDVO_CMD_SET_OVERSCAN_H; > + } else if (sdvo_priv->right_property == property) { > + drm_connector_property_set_value(connector, > + sdvo_priv->left_property, val); > + if (sdvo_priv->right_margin == temp_value) > + goto out; > + > + sdvo_priv->left_margin = temp_value; > + sdvo_priv->right_margin = temp_value; > + temp_value = sdvo_priv->max_hscan - > + sdvo_priv->left_margin; > + cmd = SDVO_CMD_SET_OVERSCAN_H; > + } else if (sdvo_priv->top_property == property) { > + drm_connector_property_set_value(connector, > + sdvo_priv->bottom_property, val); > + if (sdvo_priv->top_margin == temp_value) > + goto out; > + > + sdvo_priv->top_margin = temp_value; > + sdvo_priv->bottom_margin = temp_value; > + temp_value = sdvo_priv->max_vscan - > + sdvo_priv->top_margin; > + cmd = SDVO_CMD_SET_OVERSCAN_V; > + } else if (sdvo_priv->bottom_property == property) { > + drm_connector_property_set_value(connector, > + sdvo_priv->top_property, val); > + if (sdvo_priv->bottom_margin == temp_value) > + goto out; > + sdvo_priv->top_margin = temp_value; > + sdvo_priv->bottom_margin = temp_value; > + temp_value = sdvo_priv->max_vscan - > + sdvo_priv->top_margin; > + cmd = SDVO_CMD_SET_OVERSCAN_V; > + } else if (sdvo_priv->hpos_property == property) { > + if (sdvo_priv->cur_hpos == temp_value) > + goto out; > + > + cmd = SDVO_CMD_SET_POSITION_H; > + sdvo_priv->cur_hpos = temp_value; > + } else if (sdvo_priv->vpos_property == property) { > + if (sdvo_priv->cur_vpos == temp_value) > + goto out; > + > + cmd = SDVO_CMD_SET_POSITION_V; > + sdvo_priv->cur_vpos = temp_value; > + } else if (sdvo_priv->saturation_property == property) { > + if (sdvo_priv->cur_saturation == temp_value) > + goto out; > + > + cmd = SDVO_CMD_SET_SATURATION; > + sdvo_priv->cur_saturation = temp_value; > + } else if (sdvo_priv->contrast_property == property) { > + if (sdvo_priv->cur_contrast == temp_value) > + goto out; > + > + cmd = SDVO_CMD_SET_CONTRAST; > + sdvo_priv->cur_contrast = temp_value; > + } else if (sdvo_priv->hue_property == property) { > + if (sdvo_priv->cur_hue == temp_value) > + goto out; > + > + cmd = SDVO_CMD_SET_HUE; > + sdvo_priv->cur_hue = temp_value; > + } else if (sdvo_priv->brightness_property == property) { > + if (sdvo_priv->cur_brightness == temp_value) > + goto out; > + > + cmd = SDVO_CMD_SET_BRIGHTNESS; > + sdvo_priv->cur_brightness = temp_value; > + } > + if (cmd) { > + intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2); > + status = intel_sdvo_read_response(intel_output, NULL, 0); > + if (status != SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO command \n"); > + return -EINVAL; > + } > + changed = true; > + } > + } > if (changed && crtc) > drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, > crtc->y, crtc->fb); > @@ -2132,6 +2312,298 @@ > > } > > +static void intel_sdvo_create_enhance_property(struct drm_connector *connector) > +{ > + struct intel_output *intel_output = to_intel_output(connector); > + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; > + struct intel_sdvo_enhancements_reply sdvo_data; > + struct drm_device *dev = connector->dev; > + uint8_t status; > + uint16_t response, data_value[2]; > + > + intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, > + NULL, 0); > + status = intel_sdvo_read_response(intel_output, &sdvo_data, > + sizeof(sdvo_data)); > + if (status != SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG(" incorrect response is returned\n"); > + return; > + } > + response = *((uint16_t *)&sdvo_data); > + if (!response) { > + DRM_DEBUG("No enhancement is supported\n"); > + return; > + } > + if (sdvo_priv->is_tv) { > + /* when horizontal overscan is supported, Add the left/right > + * property > + */ > + if (sdvo_data.overscan_h) { > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &data_value, 4); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO h_overscan\n"); > + return; > + } > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_OVERSCAN_H, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &response, 2); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO h_overscan\n"); > + return; > + } > + sdvo_priv->max_hscan = data_value[0]; > + sdvo_priv->left_margin = data_value[0] - response; > + sdvo_priv->right_margin = sdvo_priv->left_margin; > + sdvo_priv->left_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "left_margin", 2); > + sdvo_priv->left_property->values[0] = 0; > + sdvo_priv->left_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->left_property, > + sdvo_priv->left_margin); > + sdvo_priv->right_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "right_margin", 2); > + sdvo_priv->right_property->values[0] = 0; > + sdvo_priv->right_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->right_property, > + sdvo_priv->right_margin); > + DRM_DEBUG("h_overscan: max %d, default %d, current %d\n", > + data_value[0], data_value[1], response); > + } > + if (sdvo_data.overscan_v) { > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &data_value, 4); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO v_overscan\n"); > + return; > + } > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_OVERSCAN_V, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &response, 2); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO v_overscan\n"); > + return; > + } > + sdvo_priv->max_vscan = data_value[0]; > + sdvo_priv->top_margin = data_value[0] - response; > + sdvo_priv->bottom_margin = sdvo_priv->top_margin; > + sdvo_priv->top_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "top_margin", 2); > + sdvo_priv->top_property->values[0] = 0; > + sdvo_priv->top_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->top_property, > + sdvo_priv->top_margin); > + sdvo_priv->bottom_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "bottom_margin", 2); > + sdvo_priv->bottom_property->values[0] = 0; > + sdvo_priv->bottom_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->bottom_property, > + sdvo_priv->bottom_margin); > + DRM_DEBUG("v_overscan: max %d, default %d, current %d\n", > + data_value[0], data_value[1], response); > + } > + if (sdvo_data.position_h) { > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &data_value, 4); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > + return; > + } > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_POSITION_H, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &response, 2); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > + return; > + } > + sdvo_priv->max_hpos = data_value[0]; > + sdvo_priv->cur_hpos = response; > + sdvo_priv->hpos_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "hpos", 2); > + sdvo_priv->hpos_property->values[0] = 0; > + sdvo_priv->hpos_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->hpos_property, > + sdvo_priv->cur_hpos); > + DRM_DEBUG("h_position: max %d, default %d, current %d\n", > + data_value[0], data_value[1], response); > + } > + if (sdvo_data.position_v) { > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &data_value, 4); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > + return; > + } > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_POSITION_V, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &response, 2); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > + return; > + } > + sdvo_priv->max_vpos = data_value[0]; > + sdvo_priv->cur_vpos = response; > + sdvo_priv->vpos_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "vpos", 2); > + sdvo_priv->vpos_property->values[0] = 0; > + sdvo_priv->vpos_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->vpos_property, > + sdvo_priv->cur_vpos); > + DRM_DEBUG("v_position: max %d, default %d, current %d\n", > + data_value[0], data_value[1], response); > + } > + } > + if (sdvo_priv->is_tv) { > + if (sdvo_data.saturation) { > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_MAX_SATURATION, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &data_value, 4); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > + return; > + } > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_SATURATION, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &response, 2); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > + return; > + } > + sdvo_priv->max_saturation = data_value[0]; > + sdvo_priv->cur_saturation = response; > + sdvo_priv->saturation_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "saturation", 2); > + sdvo_priv->saturation_property->values[0] = 0; > + sdvo_priv->saturation_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->saturation_property, > + sdvo_priv->cur_saturation); > + DRM_DEBUG("saturation: max %d, default %d, current %d\n", > + data_value[0], data_value[1], response); > + } > + if (sdvo_data.contrast) { > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &data_value, 4); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > + return; > + } > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_CONTRAST, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &response, 2); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > + return; > + } > + sdvo_priv->max_contrast = data_value[0]; > + sdvo_priv->cur_contrast = response; > + sdvo_priv->contrast_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "contrast", 2); > + sdvo_priv->contrast_property->values[0] = 0; > + sdvo_priv->contrast_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->contrast_property, > + sdvo_priv->cur_contrast); > + DRM_DEBUG("contrast: max %d, default %d, current %d\n", > + data_value[0], data_value[1], response); > + } > + if (sdvo_data.hue) { > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_MAX_HUE, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &data_value, 4); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > + return; > + } > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_HUE, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &response, 2); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > + return; > + } > + sdvo_priv->max_hue = data_value[0]; > + sdvo_priv->cur_hue = response; > + sdvo_priv->hue_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "hue", 2); > + sdvo_priv->hue_property->values[0] = 0; > + sdvo_priv->hue_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->hue_property, > + sdvo_priv->cur_hue); > + DRM_DEBUG("hue: max %d, default %d, current %d\n", > + data_value[0], data_value[1], response); > + } > + } > + if (sdvo_priv->is_tv) { > + if (sdvo_data.brightness) { > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &data_value, 4); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > + return; > + } > + intel_sdvo_write_cmd(intel_output, > + SDVO_CMD_GET_BRIGHTNESS, NULL, 0); > + status = intel_sdvo_read_response(intel_output, > + &response, 2); > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > + return; > + } > + sdvo_priv->max_brightness = data_value[0]; > + sdvo_priv->cur_brightness = response; > + sdvo_priv->brightness_property = > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > + "brightness", 2); > + sdvo_priv->brightness_property->values[0] = 0; > + sdvo_priv->brightness_property->values[1] = data_value[0]; > + drm_connector_attach_property(connector, > + sdvo_priv->brightness_property, > + sdvo_priv->cur_brightness); > + DRM_DEBUG("brightness: max %d, default %d, current %d\n", > + data_value[0], data_value[1], response); > + } > + } > + return; > +} > + > bool intel_sdvo_init(struct drm_device *dev, int output_device) > { > struct drm_connector *connector; > @@ -2214,8 +2686,10 @@ > drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); > > drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); > - if (sdvo_priv->is_tv) > + if (sdvo_priv->is_tv) { > intel_sdvo_tv_create_property(connector); > + intel_sdvo_create_enhance_property(connector); > + } > drm_sysfs_connector_add(connector); > > intel_sdvo_select_ddc_bus(sdvo_priv);
On Mon, 2009-08-31 at 11:02 +0800, ykzhao wrote: > On Mon, 2009-08-31 at 10:57 +0800, Zhao, Yakui wrote: > > From: Zhao Yakui <yakui.zhao@intel.com> > > Hi, Eric > It seems that you already pick up two patches about TV > property(select TV format according to connector type, Enable PAL and > SECAM format and add the TV format propery for SDVO-TV) > Will you please also pick up the two patches that add the property > for SDVO-TV/LVDS? > Patch 1: add the property for SDVO-TV(window > control/saturation/hue/brightness/contrast, which is similar to what we > have done for integrated TV) > Patch 2: add the brightness property for SDVO-LVDS Hi, Eric How about the two patches about adding the property for SDVO-TV/LVDS? One bug with P1 priority is blocked by this patch. thanks. > > Thanks. > > > > When the sdvo device is detected as SDVO-TV, we will check whether the > > sepecific picture enhancement is supported. If it is supported, we will > > add the corresponnding property for SDVO-TV. We will add the following > > property for the SDVO-TV enhancements if they are supported: > > Contrast/Brightness/Saturation/Hue: > > left/right/top/bottom margin: This is implemented by using the horizontal/ > > vertical overscan enhancements. When the overscan enhancements are supported, > > the above properties will be added. This is to be compatible with what we have > > done in integrated-TV. > > horizontal pos/vertical pos: > > > > http://bugs.freedesktop.org/show_bug.cgi?id=22891 > > > > Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> > > --- > > drivers/gpu/drm/i915/intel_sdvo.c | 482 +++++++++++++++++++++++++++++++++++++- > > 1 file changed, 478 insertions(+), 4 deletions(-) > > > > Index: linux-2.6/drivers/gpu/drm/i915/intel_sdvo.c > > =================================================================== > > --- linux-2.6.orig/drivers/gpu/drm/i915/intel_sdvo.c 2009-08-31 10:36:49.000000000 +0800 > > +++ linux-2.6/drivers/gpu/drm/i915/intel_sdvo.c 2009-08-31 10:53:12.000000000 +0800 > > @@ -132,6 +132,30 @@ > > struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; > > struct intel_sdvo_dtd save_output_dtd[16]; > > u32 save_SDVOX; > > + /* add the property for the SDVO-TV */ > > + struct drm_property *left_property; > > + struct drm_property *right_property; > > + struct drm_property *top_property; > > + struct drm_property *bottom_property; > > + struct drm_property *hpos_property; > > + struct drm_property *vpos_property; > > + > > + /* add the property for the SDVO-TV/LVDS */ > > + struct drm_property *brightness_property; > > + struct drm_property *contrast_property; > > + struct drm_property *saturation_property; > > + struct drm_property *hue_property; > > + > > + /* Add variable to record current setting for the above property */ > > + u32 left_margin, right_margin, top_margin, bottom_margin; > > + /* this is to get the range of margin.*/ > > + u32 max_hscan, max_vscan; > > + u32 max_hpos, cur_hpos; > > + u32 max_vpos, cur_vpos; > > + u32 cur_brightness, max_brightness; > > + u32 cur_contrast, max_contrast; > > + u32 cur_saturation, max_saturation; > > + u32 cur_hue, max_hue; > > }; > > > > static bool > > @@ -278,6 +302,31 @@ > > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), > > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), > > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), > > + /* Add the op code for SDVO enhancements */ > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), > > + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), > > /* HDMI op code */ > > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), > > SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), > > @@ -1749,6 +1798,42 @@ > > return 1; > > } > > > > +static > > +void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) > > +{ > > + struct intel_output *intel_output = to_intel_output(connector); > > + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; > > + struct drm_device *dev = connector->dev; > > + > > + if (sdvo_priv->is_tv) { > > + if (sdvo_priv->left_property) > > + drm_property_destroy(dev, sdvo_priv->left_property); > > + if (sdvo_priv->right_property) > > + drm_property_destroy(dev, sdvo_priv->right_property); > > + if (sdvo_priv->top_property) > > + drm_property_destroy(dev, sdvo_priv->top_property); > > + if (sdvo_priv->bottom_property) > > + drm_property_destroy(dev, sdvo_priv->bottom_property); > > + if (sdvo_priv->hpos_property) > > + drm_property_destroy(dev, sdvo_priv->hpos_property); > > + if (sdvo_priv->vpos_property) > > + drm_property_destroy(dev, sdvo_priv->vpos_property); > > + } > > + if (sdvo_priv->is_tv) { > > + if (sdvo_priv->saturation_property) > > + drm_property_destroy(dev, sdvo_priv->saturation_property); > > + if (sdvo_priv->contrast_property) > > + drm_property_destroy(dev, sdvo_priv->contrast_property); > > + if (sdvo_priv->hue_property) > > + drm_property_destroy(dev, sdvo_priv->hue_property); > > + } > > + if (sdvo_priv->is_tv) { > > + if (sdvo_priv->brightness_property) > > + drm_property_destroy(dev, sdvo_priv->brightness_property); > > + } > > + return; > > +} > > + > > static void intel_sdvo_destroy(struct drm_connector *connector) > > { > > struct intel_output *intel_output = to_intel_output(connector); > > @@ -1767,6 +1852,9 @@ > > drm_property_destroy(connector->dev, > > sdvo_priv->tv_format_property); > > > > + if (sdvo_priv->is_tv) > > + intel_sdvo_destroy_enhance_property(connector); > > + > > drm_sysfs_connector_remove(connector); > > drm_connector_cleanup(connector); > > > > @@ -1784,6 +1872,8 @@ > > struct drm_crtc *crtc = encoder->crtc; > > int ret = 0; > > bool changed = false; > > + uint8_t cmd, status; > > + uint16_t temp_value; > > > > ret = drm_connector_property_set_value(connector, property, val); > > if (ret < 0) > > @@ -1800,11 +1890,101 @@ > > > > sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; > > changed = true; > > - } else { > > - ret = -EINVAL; > > - goto out; > > } > > > > + if (sdvo_priv->is_tv) { > > + cmd = 0; > > + temp_value = val; > > + if (sdvo_priv->left_property == property) { > > + drm_connector_property_set_value(connector, > > + sdvo_priv->right_property, val); > > + if (sdvo_priv->left_margin == temp_value) > > + goto out; > > + > > + sdvo_priv->left_margin = temp_value; > > + sdvo_priv->right_margin = temp_value; > > + temp_value = sdvo_priv->max_hscan - > > + sdvo_priv->left_margin; > > + cmd = SDVO_CMD_SET_OVERSCAN_H; > > + } else if (sdvo_priv->right_property == property) { > > + drm_connector_property_set_value(connector, > > + sdvo_priv->left_property, val); > > + if (sdvo_priv->right_margin == temp_value) > > + goto out; > > + > > + sdvo_priv->left_margin = temp_value; > > + sdvo_priv->right_margin = temp_value; > > + temp_value = sdvo_priv->max_hscan - > > + sdvo_priv->left_margin; > > + cmd = SDVO_CMD_SET_OVERSCAN_H; > > + } else if (sdvo_priv->top_property == property) { > > + drm_connector_property_set_value(connector, > > + sdvo_priv->bottom_property, val); > > + if (sdvo_priv->top_margin == temp_value) > > + goto out; > > + > > + sdvo_priv->top_margin = temp_value; > > + sdvo_priv->bottom_margin = temp_value; > > + temp_value = sdvo_priv->max_vscan - > > + sdvo_priv->top_margin; > > + cmd = SDVO_CMD_SET_OVERSCAN_V; > > + } else if (sdvo_priv->bottom_property == property) { > > + drm_connector_property_set_value(connector, > > + sdvo_priv->top_property, val); > > + if (sdvo_priv->bottom_margin == temp_value) > > + goto out; > > + sdvo_priv->top_margin = temp_value; > > + sdvo_priv->bottom_margin = temp_value; > > + temp_value = sdvo_priv->max_vscan - > > + sdvo_priv->top_margin; > > + cmd = SDVO_CMD_SET_OVERSCAN_V; > > + } else if (sdvo_priv->hpos_property == property) { > > + if (sdvo_priv->cur_hpos == temp_value) > > + goto out; > > + > > + cmd = SDVO_CMD_SET_POSITION_H; > > + sdvo_priv->cur_hpos = temp_value; > > + } else if (sdvo_priv->vpos_property == property) { > > + if (sdvo_priv->cur_vpos == temp_value) > > + goto out; > > + > > + cmd = SDVO_CMD_SET_POSITION_V; > > + sdvo_priv->cur_vpos = temp_value; > > + } else if (sdvo_priv->saturation_property == property) { > > + if (sdvo_priv->cur_saturation == temp_value) > > + goto out; > > + > > + cmd = SDVO_CMD_SET_SATURATION; > > + sdvo_priv->cur_saturation = temp_value; > > + } else if (sdvo_priv->contrast_property == property) { > > + if (sdvo_priv->cur_contrast == temp_value) > > + goto out; > > + > > + cmd = SDVO_CMD_SET_CONTRAST; > > + sdvo_priv->cur_contrast = temp_value; > > + } else if (sdvo_priv->hue_property == property) { > > + if (sdvo_priv->cur_hue == temp_value) > > + goto out; > > + > > + cmd = SDVO_CMD_SET_HUE; > > + sdvo_priv->cur_hue = temp_value; > > + } else if (sdvo_priv->brightness_property == property) { > > + if (sdvo_priv->cur_brightness == temp_value) > > + goto out; > > + > > + cmd = SDVO_CMD_SET_BRIGHTNESS; > > + sdvo_priv->cur_brightness = temp_value; > > + } > > + if (cmd) { > > + intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2); > > + status = intel_sdvo_read_response(intel_output, NULL, 0); > > + if (status != SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO command \n"); > > + return -EINVAL; > > + } > > + changed = true; > > + } > > + } > > if (changed && crtc) > > drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, > > crtc->y, crtc->fb); > > @@ -2132,6 +2312,298 @@ > > > > } > > > > +static void intel_sdvo_create_enhance_property(struct drm_connector *connector) > > +{ > > + struct intel_output *intel_output = to_intel_output(connector); > > + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; > > + struct intel_sdvo_enhancements_reply sdvo_data; > > + struct drm_device *dev = connector->dev; > > + uint8_t status; > > + uint16_t response, data_value[2]; > > + > > + intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, > > + NULL, 0); > > + status = intel_sdvo_read_response(intel_output, &sdvo_data, > > + sizeof(sdvo_data)); > > + if (status != SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG(" incorrect response is returned\n"); > > + return; > > + } > > + response = *((uint16_t *)&sdvo_data); > > + if (!response) { > > + DRM_DEBUG("No enhancement is supported\n"); > > + return; > > + } > > + if (sdvo_priv->is_tv) { > > + /* when horizontal overscan is supported, Add the left/right > > + * property > > + */ > > + if (sdvo_data.overscan_h) { > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &data_value, 4); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO h_overscan\n"); > > + return; > > + } > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_OVERSCAN_H, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &response, 2); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO h_overscan\n"); > > + return; > > + } > > + sdvo_priv->max_hscan = data_value[0]; > > + sdvo_priv->left_margin = data_value[0] - response; > > + sdvo_priv->right_margin = sdvo_priv->left_margin; > > + sdvo_priv->left_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "left_margin", 2); > > + sdvo_priv->left_property->values[0] = 0; > > + sdvo_priv->left_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->left_property, > > + sdvo_priv->left_margin); > > + sdvo_priv->right_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "right_margin", 2); > > + sdvo_priv->right_property->values[0] = 0; > > + sdvo_priv->right_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->right_property, > > + sdvo_priv->right_margin); > > + DRM_DEBUG("h_overscan: max %d, default %d, current %d\n", > > + data_value[0], data_value[1], response); > > + } > > + if (sdvo_data.overscan_v) { > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &data_value, 4); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO v_overscan\n"); > > + return; > > + } > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_OVERSCAN_V, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &response, 2); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO v_overscan\n"); > > + return; > > + } > > + sdvo_priv->max_vscan = data_value[0]; > > + sdvo_priv->top_margin = data_value[0] - response; > > + sdvo_priv->bottom_margin = sdvo_priv->top_margin; > > + sdvo_priv->top_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "top_margin", 2); > > + sdvo_priv->top_property->values[0] = 0; > > + sdvo_priv->top_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->top_property, > > + sdvo_priv->top_margin); > > + sdvo_priv->bottom_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "bottom_margin", 2); > > + sdvo_priv->bottom_property->values[0] = 0; > > + sdvo_priv->bottom_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->bottom_property, > > + sdvo_priv->bottom_margin); > > + DRM_DEBUG("v_overscan: max %d, default %d, current %d\n", > > + data_value[0], data_value[1], response); > > + } > > + if (sdvo_data.position_h) { > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &data_value, 4); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > > + return; > > + } > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_POSITION_H, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &response, 2); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > > + return; > > + } > > + sdvo_priv->max_hpos = data_value[0]; > > + sdvo_priv->cur_hpos = response; > > + sdvo_priv->hpos_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "hpos", 2); > > + sdvo_priv->hpos_property->values[0] = 0; > > + sdvo_priv->hpos_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->hpos_property, > > + sdvo_priv->cur_hpos); > > + DRM_DEBUG("h_position: max %d, default %d, current %d\n", > > + data_value[0], data_value[1], response); > > + } > > + if (sdvo_data.position_v) { > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &data_value, 4); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > > + return; > > + } > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_POSITION_V, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &response, 2); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > > + return; > > + } > > + sdvo_priv->max_vpos = data_value[0]; > > + sdvo_priv->cur_vpos = response; > > + sdvo_priv->vpos_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "vpos", 2); > > + sdvo_priv->vpos_property->values[0] = 0; > > + sdvo_priv->vpos_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->vpos_property, > > + sdvo_priv->cur_vpos); > > + DRM_DEBUG("v_position: max %d, default %d, current %d\n", > > + data_value[0], data_value[1], response); > > + } > > + } > > + if (sdvo_priv->is_tv) { > > + if (sdvo_data.saturation) { > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_MAX_SATURATION, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &data_value, 4); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > > + return; > > + } > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_SATURATION, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &response, 2); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > > + return; > > + } > > + sdvo_priv->max_saturation = data_value[0]; > > + sdvo_priv->cur_saturation = response; > > + sdvo_priv->saturation_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "saturation", 2); > > + sdvo_priv->saturation_property->values[0] = 0; > > + sdvo_priv->saturation_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->saturation_property, > > + sdvo_priv->cur_saturation); > > + DRM_DEBUG("saturation: max %d, default %d, current %d\n", > > + data_value[0], data_value[1], response); > > + } > > + if (sdvo_data.contrast) { > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &data_value, 4); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > > + return; > > + } > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_CONTRAST, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &response, 2); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > > + return; > > + } > > + sdvo_priv->max_contrast = data_value[0]; > > + sdvo_priv->cur_contrast = response; > > + sdvo_priv->contrast_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "contrast", 2); > > + sdvo_priv->contrast_property->values[0] = 0; > > + sdvo_priv->contrast_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->contrast_property, > > + sdvo_priv->cur_contrast); > > + DRM_DEBUG("contrast: max %d, default %d, current %d\n", > > + data_value[0], data_value[1], response); > > + } > > + if (sdvo_data.hue) { > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_MAX_HUE, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &data_value, 4); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > > + return; > > + } > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_HUE, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &response, 2); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > > + return; > > + } > > + sdvo_priv->max_hue = data_value[0]; > > + sdvo_priv->cur_hue = response; > > + sdvo_priv->hue_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "hue", 2); > > + sdvo_priv->hue_property->values[0] = 0; > > + sdvo_priv->hue_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->hue_property, > > + sdvo_priv->cur_hue); > > + DRM_DEBUG("hue: max %d, default %d, current %d\n", > > + data_value[0], data_value[1], response); > > + } > > + } > > + if (sdvo_priv->is_tv) { > > + if (sdvo_data.brightness) { > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &data_value, 4); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); > > + return; > > + } > > + intel_sdvo_write_cmd(intel_output, > > + SDVO_CMD_GET_BRIGHTNESS, NULL, 0); > > + status = intel_sdvo_read_response(intel_output, > > + &response, 2); > > + if (status !=SDVO_CMD_STATUS_SUCCESS) { > > + DRM_DEBUG("Incorrect SDVO get h_postion\n"); > > + return; > > + } > > + sdvo_priv->max_brightness = data_value[0]; > > + sdvo_priv->cur_brightness = response; > > + sdvo_priv->brightness_property = > > + drm_property_create(dev, DRM_MODE_PROP_RANGE, > > + "brightness", 2); > > + sdvo_priv->brightness_property->values[0] = 0; > > + sdvo_priv->brightness_property->values[1] = data_value[0]; > > + drm_connector_attach_property(connector, > > + sdvo_priv->brightness_property, > > + sdvo_priv->cur_brightness); > > + DRM_DEBUG("brightness: max %d, default %d, current %d\n", > > + data_value[0], data_value[1], response); > > + } > > + } > > + return; > > +} > > + > > bool intel_sdvo_init(struct drm_device *dev, int output_device) > > { > > struct drm_connector *connector; > > @@ -2214,8 +2686,10 @@ > > drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); > > > > drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); > > - if (sdvo_priv->is_tv) > > + if (sdvo_priv->is_tv) { > > intel_sdvo_tv_create_property(connector); > > + intel_sdvo_create_enhance_property(connector); > > + } > > drm_sysfs_connector_add(connector); > > > > intel_sdvo_select_ddc_bus(sdvo_priv); > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Index: linux-2.6/drivers/gpu/drm/i915/intel_sdvo.c =================================================================== --- linux-2.6.orig/drivers/gpu/drm/i915/intel_sdvo.c 2009-08-31 10:36:49.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/i915/intel_sdvo.c 2009-08-31 10:53:12.000000000 +0800 @@ -132,6 +132,30 @@ struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; struct intel_sdvo_dtd save_output_dtd[16]; u32 save_SDVOX; + /* add the property for the SDVO-TV */ + struct drm_property *left_property; + struct drm_property *right_property; + struct drm_property *top_property; + struct drm_property *bottom_property; + struct drm_property *hpos_property; + struct drm_property *vpos_property; + + /* add the property for the SDVO-TV/LVDS */ + struct drm_property *brightness_property; + struct drm_property *contrast_property; + struct drm_property *saturation_property; + struct drm_property *hue_property; + + /* Add variable to record current setting for the above property */ + u32 left_margin, right_margin, top_margin, bottom_margin; + /* this is to get the range of margin.*/ + u32 max_hscan, max_vscan; + u32 max_hpos, cur_hpos; + u32 max_vpos, cur_vpos; + u32 cur_brightness, max_brightness; + u32 cur_contrast, max_contrast; + u32 cur_saturation, max_saturation; + u32 cur_hue, max_hue; }; static bool @@ -278,6 +302,31 @@ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), + /* Add the op code for SDVO enhancements */ + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), /* HDMI op code */ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), @@ -1749,6 +1798,42 @@ return 1; } +static +void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) +{ + struct intel_output *intel_output = to_intel_output(connector); + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct drm_device *dev = connector->dev; + + if (sdvo_priv->is_tv) { + if (sdvo_priv->left_property) + drm_property_destroy(dev, sdvo_priv->left_property); + if (sdvo_priv->right_property) + drm_property_destroy(dev, sdvo_priv->right_property); + if (sdvo_priv->top_property) + drm_property_destroy(dev, sdvo_priv->top_property); + if (sdvo_priv->bottom_property) + drm_property_destroy(dev, sdvo_priv->bottom_property); + if (sdvo_priv->hpos_property) + drm_property_destroy(dev, sdvo_priv->hpos_property); + if (sdvo_priv->vpos_property) + drm_property_destroy(dev, sdvo_priv->vpos_property); + } + if (sdvo_priv->is_tv) { + if (sdvo_priv->saturation_property) + drm_property_destroy(dev, sdvo_priv->saturation_property); + if (sdvo_priv->contrast_property) + drm_property_destroy(dev, sdvo_priv->contrast_property); + if (sdvo_priv->hue_property) + drm_property_destroy(dev, sdvo_priv->hue_property); + } + if (sdvo_priv->is_tv) { + if (sdvo_priv->brightness_property) + drm_property_destroy(dev, sdvo_priv->brightness_property); + } + return; +} + static void intel_sdvo_destroy(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); @@ -1767,6 +1852,9 @@ drm_property_destroy(connector->dev, sdvo_priv->tv_format_property); + if (sdvo_priv->is_tv) + intel_sdvo_destroy_enhance_property(connector); + drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); @@ -1784,6 +1872,8 @@ struct drm_crtc *crtc = encoder->crtc; int ret = 0; bool changed = false; + uint8_t cmd, status; + uint16_t temp_value; ret = drm_connector_property_set_value(connector, property, val); if (ret < 0) @@ -1800,11 +1890,101 @@ sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; changed = true; - } else { - ret = -EINVAL; - goto out; } + if (sdvo_priv->is_tv) { + cmd = 0; + temp_value = val; + if (sdvo_priv->left_property == property) { + drm_connector_property_set_value(connector, + sdvo_priv->right_property, val); + if (sdvo_priv->left_margin == temp_value) + goto out; + + sdvo_priv->left_margin = temp_value; + sdvo_priv->right_margin = temp_value; + temp_value = sdvo_priv->max_hscan - + sdvo_priv->left_margin; + cmd = SDVO_CMD_SET_OVERSCAN_H; + } else if (sdvo_priv->right_property == property) { + drm_connector_property_set_value(connector, + sdvo_priv->left_property, val); + if (sdvo_priv->right_margin == temp_value) + goto out; + + sdvo_priv->left_margin = temp_value; + sdvo_priv->right_margin = temp_value; + temp_value = sdvo_priv->max_hscan - + sdvo_priv->left_margin; + cmd = SDVO_CMD_SET_OVERSCAN_H; + } else if (sdvo_priv->top_property == property) { + drm_connector_property_set_value(connector, + sdvo_priv->bottom_property, val); + if (sdvo_priv->top_margin == temp_value) + goto out; + + sdvo_priv->top_margin = temp_value; + sdvo_priv->bottom_margin = temp_value; + temp_value = sdvo_priv->max_vscan - + sdvo_priv->top_margin; + cmd = SDVO_CMD_SET_OVERSCAN_V; + } else if (sdvo_priv->bottom_property == property) { + drm_connector_property_set_value(connector, + sdvo_priv->top_property, val); + if (sdvo_priv->bottom_margin == temp_value) + goto out; + sdvo_priv->top_margin = temp_value; + sdvo_priv->bottom_margin = temp_value; + temp_value = sdvo_priv->max_vscan - + sdvo_priv->top_margin; + cmd = SDVO_CMD_SET_OVERSCAN_V; + } else if (sdvo_priv->hpos_property == property) { + if (sdvo_priv->cur_hpos == temp_value) + goto out; + + cmd = SDVO_CMD_SET_POSITION_H; + sdvo_priv->cur_hpos = temp_value; + } else if (sdvo_priv->vpos_property == property) { + if (sdvo_priv->cur_vpos == temp_value) + goto out; + + cmd = SDVO_CMD_SET_POSITION_V; + sdvo_priv->cur_vpos = temp_value; + } else if (sdvo_priv->saturation_property == property) { + if (sdvo_priv->cur_saturation == temp_value) + goto out; + + cmd = SDVO_CMD_SET_SATURATION; + sdvo_priv->cur_saturation = temp_value; + } else if (sdvo_priv->contrast_property == property) { + if (sdvo_priv->cur_contrast == temp_value) + goto out; + + cmd = SDVO_CMD_SET_CONTRAST; + sdvo_priv->cur_contrast = temp_value; + } else if (sdvo_priv->hue_property == property) { + if (sdvo_priv->cur_hue == temp_value) + goto out; + + cmd = SDVO_CMD_SET_HUE; + sdvo_priv->cur_hue = temp_value; + } else if (sdvo_priv->brightness_property == property) { + if (sdvo_priv->cur_brightness == temp_value) + goto out; + + cmd = SDVO_CMD_SET_BRIGHTNESS; + sdvo_priv->cur_brightness = temp_value; + } + if (cmd) { + intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2); + status = intel_sdvo_read_response(intel_output, NULL, 0); + if (status != SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO command \n"); + return -EINVAL; + } + changed = true; + } + } if (changed && crtc) drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->fb); @@ -2132,6 +2312,298 @@ } +static void intel_sdvo_create_enhance_property(struct drm_connector *connector) +{ + struct intel_output *intel_output = to_intel_output(connector); + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; + struct intel_sdvo_enhancements_reply sdvo_data; + struct drm_device *dev = connector->dev; + uint8_t status; + uint16_t response, data_value[2]; + + intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, + NULL, 0); + status = intel_sdvo_read_response(intel_output, &sdvo_data, + sizeof(sdvo_data)); + if (status != SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG(" incorrect response is returned\n"); + return; + } + response = *((uint16_t *)&sdvo_data); + if (!response) { + DRM_DEBUG("No enhancement is supported\n"); + return; + } + if (sdvo_priv->is_tv) { + /* when horizontal overscan is supported, Add the left/right + * property + */ + if (sdvo_data.overscan_h) { + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &data_value, 4); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO h_overscan\n"); + return; + } + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_OVERSCAN_H, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &response, 2); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO h_overscan\n"); + return; + } + sdvo_priv->max_hscan = data_value[0]; + sdvo_priv->left_margin = data_value[0] - response; + sdvo_priv->right_margin = sdvo_priv->left_margin; + sdvo_priv->left_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "left_margin", 2); + sdvo_priv->left_property->values[0] = 0; + sdvo_priv->left_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->left_property, + sdvo_priv->left_margin); + sdvo_priv->right_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "right_margin", 2); + sdvo_priv->right_property->values[0] = 0; + sdvo_priv->right_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->right_property, + sdvo_priv->right_margin); + DRM_DEBUG("h_overscan: max %d, default %d, current %d\n", + data_value[0], data_value[1], response); + } + if (sdvo_data.overscan_v) { + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &data_value, 4); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO v_overscan\n"); + return; + } + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_OVERSCAN_V, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &response, 2); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO v_overscan\n"); + return; + } + sdvo_priv->max_vscan = data_value[0]; + sdvo_priv->top_margin = data_value[0] - response; + sdvo_priv->bottom_margin = sdvo_priv->top_margin; + sdvo_priv->top_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "top_margin", 2); + sdvo_priv->top_property->values[0] = 0; + sdvo_priv->top_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->top_property, + sdvo_priv->top_margin); + sdvo_priv->bottom_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "bottom_margin", 2); + sdvo_priv->bottom_property->values[0] = 0; + sdvo_priv->bottom_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->bottom_property, + sdvo_priv->bottom_margin); + DRM_DEBUG("v_overscan: max %d, default %d, current %d\n", + data_value[0], data_value[1], response); + } + if (sdvo_data.position_h) { + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &data_value, 4); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); + return; + } + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_POSITION_H, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &response, 2); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO get h_postion\n"); + return; + } + sdvo_priv->max_hpos = data_value[0]; + sdvo_priv->cur_hpos = response; + sdvo_priv->hpos_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "hpos", 2); + sdvo_priv->hpos_property->values[0] = 0; + sdvo_priv->hpos_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->hpos_property, + sdvo_priv->cur_hpos); + DRM_DEBUG("h_position: max %d, default %d, current %d\n", + data_value[0], data_value[1], response); + } + if (sdvo_data.position_v) { + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &data_value, 4); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); + return; + } + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_POSITION_V, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &response, 2); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO get h_postion\n"); + return; + } + sdvo_priv->max_vpos = data_value[0]; + sdvo_priv->cur_vpos = response; + sdvo_priv->vpos_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "vpos", 2); + sdvo_priv->vpos_property->values[0] = 0; + sdvo_priv->vpos_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->vpos_property, + sdvo_priv->cur_vpos); + DRM_DEBUG("v_position: max %d, default %d, current %d\n", + data_value[0], data_value[1], response); + } + } + if (sdvo_priv->is_tv) { + if (sdvo_data.saturation) { + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_MAX_SATURATION, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &data_value, 4); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); + return; + } + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_SATURATION, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &response, 2); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO get h_postion\n"); + return; + } + sdvo_priv->max_saturation = data_value[0]; + sdvo_priv->cur_saturation = response; + sdvo_priv->saturation_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "saturation", 2); + sdvo_priv->saturation_property->values[0] = 0; + sdvo_priv->saturation_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->saturation_property, + sdvo_priv->cur_saturation); + DRM_DEBUG("saturation: max %d, default %d, current %d\n", + data_value[0], data_value[1], response); + } + if (sdvo_data.contrast) { + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &data_value, 4); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); + return; + } + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_CONTRAST, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &response, 2); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO get h_postion\n"); + return; + } + sdvo_priv->max_contrast = data_value[0]; + sdvo_priv->cur_contrast = response; + sdvo_priv->contrast_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "contrast", 2); + sdvo_priv->contrast_property->values[0] = 0; + sdvo_priv->contrast_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->contrast_property, + sdvo_priv->cur_contrast); + DRM_DEBUG("contrast: max %d, default %d, current %d\n", + data_value[0], data_value[1], response); + } + if (sdvo_data.hue) { + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_MAX_HUE, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &data_value, 4); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); + return; + } + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_HUE, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &response, 2); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO get h_postion\n"); + return; + } + sdvo_priv->max_hue = data_value[0]; + sdvo_priv->cur_hue = response; + sdvo_priv->hue_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "hue", 2); + sdvo_priv->hue_property->values[0] = 0; + sdvo_priv->hue_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->hue_property, + sdvo_priv->cur_hue); + DRM_DEBUG("hue: max %d, default %d, current %d\n", + data_value[0], data_value[1], response); + } + } + if (sdvo_priv->is_tv) { + if (sdvo_data.brightness) { + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &data_value, 4); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO Max h_positin\n"); + return; + } + intel_sdvo_write_cmd(intel_output, + SDVO_CMD_GET_BRIGHTNESS, NULL, 0); + status = intel_sdvo_read_response(intel_output, + &response, 2); + if (status !=SDVO_CMD_STATUS_SUCCESS) { + DRM_DEBUG("Incorrect SDVO get h_postion\n"); + return; + } + sdvo_priv->max_brightness = data_value[0]; + sdvo_priv->cur_brightness = response; + sdvo_priv->brightness_property = + drm_property_create(dev, DRM_MODE_PROP_RANGE, + "brightness", 2); + sdvo_priv->brightness_property->values[0] = 0; + sdvo_priv->brightness_property->values[1] = data_value[0]; + drm_connector_attach_property(connector, + sdvo_priv->brightness_property, + sdvo_priv->cur_brightness); + DRM_DEBUG("brightness: max %d, default %d, current %d\n", + data_value[0], data_value[1], response); + } + } + return; +} + bool intel_sdvo_init(struct drm_device *dev, int output_device) { struct drm_connector *connector; @@ -2214,8 +2686,10 @@ drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); - if (sdvo_priv->is_tv) + if (sdvo_priv->is_tv) { intel_sdvo_tv_create_property(connector); + intel_sdvo_create_enhance_property(connector); + } drm_sysfs_connector_add(connector); intel_sdvo_select_ddc_bus(sdvo_priv);