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