1e3adcf8fSFrançois Tigeot /* 2e3adcf8fSFrançois Tigeot * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> 3e3adcf8fSFrançois Tigeot * Copyright (c) 2007, 2010 Intel Corporation 4e3adcf8fSFrançois Tigeot * Jesse Barnes <jesse.barnes@intel.com> 5e3adcf8fSFrançois Tigeot * 6e3adcf8fSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 7e3adcf8fSFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 8e3adcf8fSFrançois Tigeot * to deal in the Software without restriction, including without limitation 9e3adcf8fSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10e3adcf8fSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 11e3adcf8fSFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 12e3adcf8fSFrançois Tigeot * 13e3adcf8fSFrançois Tigeot * The above copyright notice and this permission notice (including the next 14e3adcf8fSFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 15e3adcf8fSFrançois Tigeot * Software. 16e3adcf8fSFrançois Tigeot * 17e3adcf8fSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18e3adcf8fSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19e3adcf8fSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20e3adcf8fSFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21e3adcf8fSFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22e3adcf8fSFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23e3adcf8fSFrançois Tigeot * DEALINGS IN THE SOFTWARE. 24e3adcf8fSFrançois Tigeot * 25e3adcf8fSFrançois Tigeot * $FreeBSD: head/sys/dev/drm2/i915/intel_modes.c 249041 2013-04-03 08:27:35Z dumbbell $ 26e3adcf8fSFrançois Tigeot */ 27e3adcf8fSFrançois Tigeot 2818e26a6dSFrançois Tigeot #include <drm/drmP.h> 2918e26a6dSFrançois Tigeot #include <drm/drm_edid.h> 30e3adcf8fSFrançois Tigeot #include "intel_drv.h" 3118e26a6dSFrançois Tigeot #include "i915_drv.h" 32e3adcf8fSFrançois Tigeot #include <bus/iicbus/iiconf.h> 33e3adcf8fSFrançois Tigeot 34e3adcf8fSFrançois Tigeot /** 35e3adcf8fSFrançois Tigeot * intel_ddc_probe 36e3adcf8fSFrançois Tigeot * 37e3adcf8fSFrançois Tigeot */ 38e3adcf8fSFrançois Tigeot bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus) 39e3adcf8fSFrançois Tigeot { 40e3adcf8fSFrançois Tigeot struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private; 41e3adcf8fSFrançois Tigeot u8 out_buf[] = { 0x0, 0x0}; 42e3adcf8fSFrançois Tigeot u8 buf[2]; 43e3adcf8fSFrançois Tigeot struct iic_msg msgs[] = { 44e3adcf8fSFrançois Tigeot { 45e3adcf8fSFrançois Tigeot .slave = DDC_ADDR << 1, 46e3adcf8fSFrançois Tigeot .flags = IIC_M_WR, 47e3adcf8fSFrançois Tigeot .len = 1, 48e3adcf8fSFrançois Tigeot .buf = out_buf, 49e3adcf8fSFrançois Tigeot }, 50e3adcf8fSFrançois Tigeot { 51e3adcf8fSFrançois Tigeot .slave = DDC_ADDR << 1, 52e3adcf8fSFrançois Tigeot .flags = IIC_M_RD, 53e3adcf8fSFrançois Tigeot .len = 1, 54e3adcf8fSFrançois Tigeot .buf = buf, 55e3adcf8fSFrançois Tigeot } 56e3adcf8fSFrançois Tigeot }; 57e3adcf8fSFrançois Tigeot 58e3adcf8fSFrançois Tigeot return (iicbus_transfer(dev_priv->gmbus[ddc_bus], msgs, 2) 59e3adcf8fSFrançois Tigeot == 0/* XXXKIB 2*/); 60e3adcf8fSFrançois Tigeot } 61e3adcf8fSFrançois Tigeot 62e3adcf8fSFrançois Tigeot /** 63e3adcf8fSFrançois Tigeot * intel_ddc_get_modes - get modelist from monitor 64e3adcf8fSFrançois Tigeot * @connector: DRM connector device to use 65e3adcf8fSFrançois Tigeot * @adapter: i2c adapter 66e3adcf8fSFrançois Tigeot * 67e3adcf8fSFrançois Tigeot * Fetch the EDID information from @connector using the DDC bus. 68e3adcf8fSFrançois Tigeot */ 69e3adcf8fSFrançois Tigeot int 70e3adcf8fSFrançois Tigeot intel_ddc_get_modes(struct drm_connector *connector, device_t adapter) 71e3adcf8fSFrançois Tigeot { 72e3adcf8fSFrançois Tigeot struct edid *edid; 73e3adcf8fSFrançois Tigeot int ret = 0; 74e3adcf8fSFrançois Tigeot 75e3adcf8fSFrançois Tigeot edid = drm_get_edid(connector, adapter); 76e3adcf8fSFrançois Tigeot if (edid) { 77e3adcf8fSFrançois Tigeot drm_mode_connector_update_edid_property(connector, edid); 78e3adcf8fSFrançois Tigeot ret = drm_add_edid_modes(connector, edid); 79e3adcf8fSFrançois Tigeot drm_edid_to_eld(connector, edid); 80e3adcf8fSFrançois Tigeot drm_free(edid, DRM_MEM_KMS); 81e3adcf8fSFrançois Tigeot } 82e3adcf8fSFrançois Tigeot 83e3adcf8fSFrançois Tigeot return ret; 84e3adcf8fSFrançois Tigeot } 85e3adcf8fSFrançois Tigeot 86e3adcf8fSFrançois Tigeot static const struct drm_prop_enum_list force_audio_names[] = { 87e3adcf8fSFrançois Tigeot { HDMI_AUDIO_OFF_DVI, "force-dvi" }, 88e3adcf8fSFrançois Tigeot { HDMI_AUDIO_OFF, "off" }, 89e3adcf8fSFrançois Tigeot { HDMI_AUDIO_AUTO, "auto" }, 90e3adcf8fSFrançois Tigeot { HDMI_AUDIO_ON, "on" }, 91e3adcf8fSFrançois Tigeot }; 92e3adcf8fSFrançois Tigeot 93e3adcf8fSFrançois Tigeot void 94e3adcf8fSFrançois Tigeot intel_attach_force_audio_property(struct drm_connector *connector) 95e3adcf8fSFrançois Tigeot { 96e3adcf8fSFrançois Tigeot struct drm_device *dev = connector->dev; 97e3adcf8fSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 98e3adcf8fSFrançois Tigeot struct drm_property *prop; 99e3adcf8fSFrançois Tigeot 100e3adcf8fSFrançois Tigeot prop = dev_priv->force_audio_property; 101e3adcf8fSFrançois Tigeot if (prop == NULL) { 102e3adcf8fSFrançois Tigeot prop = drm_property_create_enum(dev, 0, 103e3adcf8fSFrançois Tigeot "audio", 104e3adcf8fSFrançois Tigeot force_audio_names, 105e3adcf8fSFrançois Tigeot DRM_ARRAY_SIZE(force_audio_names)); 106e3adcf8fSFrançois Tigeot if (prop == NULL) 107e3adcf8fSFrançois Tigeot return; 108e3adcf8fSFrançois Tigeot 109e3adcf8fSFrançois Tigeot dev_priv->force_audio_property = prop; 110e3adcf8fSFrançois Tigeot } 111*b5162e19SFrançois Tigeot drm_object_attach_property(&connector->base, prop, 0); 112e3adcf8fSFrançois Tigeot } 113e3adcf8fSFrançois Tigeot 114e3adcf8fSFrançois Tigeot static const struct drm_prop_enum_list broadcast_rgb_names[] = { 115e3adcf8fSFrançois Tigeot { 0, "Full" }, 116e3adcf8fSFrançois Tigeot { 1, "Limited 16:235" }, 117e3adcf8fSFrançois Tigeot }; 118e3adcf8fSFrançois Tigeot 119e3adcf8fSFrançois Tigeot void 120e3adcf8fSFrançois Tigeot intel_attach_broadcast_rgb_property(struct drm_connector *connector) 121e3adcf8fSFrançois Tigeot { 122e3adcf8fSFrançois Tigeot struct drm_device *dev = connector->dev; 123e3adcf8fSFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 124e3adcf8fSFrançois Tigeot struct drm_property *prop; 125e3adcf8fSFrançois Tigeot 126e3adcf8fSFrançois Tigeot prop = dev_priv->broadcast_rgb_property; 127e3adcf8fSFrançois Tigeot if (prop == NULL) { 128e3adcf8fSFrançois Tigeot prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, 129e3adcf8fSFrançois Tigeot "Broadcast RGB", 130e3adcf8fSFrançois Tigeot broadcast_rgb_names, 131e3adcf8fSFrançois Tigeot DRM_ARRAY_SIZE(broadcast_rgb_names)); 132e3adcf8fSFrançois Tigeot if (prop == NULL) 133e3adcf8fSFrançois Tigeot return; 134e3adcf8fSFrançois Tigeot 135e3adcf8fSFrançois Tigeot dev_priv->broadcast_rgb_property = prop; 136e3adcf8fSFrançois Tigeot } 137e3adcf8fSFrançois Tigeot 138*b5162e19SFrançois Tigeot drm_object_attach_property(&connector->base, prop, 0); 139e3adcf8fSFrançois Tigeot } 140