Merge branches 'acpi-resources', 'acpi-battery', 'acpi-doc' and 'acpi-pnp'
[linux-2.6-block.git] / drivers / gpu / drm / radeon / radeon_audio.c
index b21ef69a34ac2a2703f7adad0ee20a15f07d3509..8b82abb78df159d877f27c1ec67cd7502010634d 100644 (file)
@@ -102,7 +102,6 @@ static void radeon_audio_dp_mode_set(struct drm_encoder *encoder,
 void r600_hdmi_enable(struct drm_encoder *encoder, bool enable);
 void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable);
 void evergreen_dp_enable(struct drm_encoder *encoder, bool enable);
-void dce6_dp_enable(struct drm_encoder *encoder, bool enable);
 
 static const u32 pin_offsets[7] =
 {
@@ -240,7 +239,7 @@ static struct radeon_audio_funcs dce6_dp_funcs = {
        .set_avi_packet = evergreen_set_avi_packet,
        .set_audio_packet = dce4_set_audio_packet,
        .mode_set = radeon_audio_dp_mode_set,
-       .dpms = dce6_dp_enable,
+       .dpms = evergreen_dp_enable,
 };
 
 static void radeon_audio_interface_init(struct radeon_device *rdev)
@@ -461,30 +460,33 @@ void radeon_audio_detect(struct drm_connector *connector,
        if (!connector || !connector->encoder)
                return;
 
+       if (!radeon_encoder_is_digital(connector->encoder))
+               return;
+
        rdev = connector->encoder->dev->dev_private;
        radeon_encoder = to_radeon_encoder(connector->encoder);
        dig = radeon_encoder->enc_priv;
 
-       if (status == connector_status_connected) {
-               struct radeon_connector *radeon_connector;
-               int sink_type;
-
-               if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) {
-                       radeon_encoder->audio = NULL;
-                       return;
-               }
+       if (!dig->afmt)
+               return;
 
-               radeon_connector = to_radeon_connector(connector);
-               sink_type = radeon_dp_getsinktype(radeon_connector);
+       if (status == connector_status_connected) {
+               struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 
                if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort &&
-                       sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
+                   radeon_dp_getsinktype(radeon_connector) ==
+                   CONNECTOR_OBJECT_ID_DISPLAYPORT)
                        radeon_encoder->audio = rdev->audio.dp_funcs;
                else
                        radeon_encoder->audio = rdev->audio.hdmi_funcs;
 
                dig->afmt->pin = radeon_audio_get_pin(connector->encoder);
-               radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
+               if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
+                       radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
+               } else {
+                       radeon_audio_enable(rdev, dig->afmt->pin, 0);
+                       dig->afmt->pin = NULL;
+               }
        } else {
                radeon_audio_enable(rdev, dig->afmt->pin, 0);
                dig->afmt->pin = NULL;
@@ -520,16 +522,40 @@ static int radeon_audio_set_avi_packet(struct drm_encoder *encoder,
        struct radeon_device *rdev = encoder->dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+       struct drm_connector *connector;
+       struct radeon_connector *radeon_connector = NULL;
        u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
        struct hdmi_avi_infoframe frame;
        int err;
 
+       list_for_each_entry(connector,
+               &encoder->dev->mode_config.connector_list, head) {
+               if (connector->encoder == encoder) {
+                       radeon_connector = to_radeon_connector(connector);
+                       break;
+               }
+       }
+
+       if (!radeon_connector) {
+               DRM_ERROR("Couldn't find encoder's connector\n");
+               return -ENOENT;
+       }
+
        err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
        if (err < 0) {
                DRM_ERROR("failed to setup AVI infoframe: %d\n", err);
                return err;
        }
 
+       if (drm_rgb_quant_range_selectable(radeon_connector_edid(connector))) {
+               if (radeon_encoder->output_csc == RADEON_OUTPUT_CSC_TVRGB)
+                       frame.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED;
+               else
+                       frame.quantization_range = HDMI_QUANTIZATION_RANGE_FULL;
+       } else {
+               frame.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
+       }
+
        err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
        if (err < 0) {
                DRM_ERROR("failed to pack AVI infoframe: %d\n", err);