1235783Skib/* 2235783Skib * Copyright (c) 2007 Dave Airlie <airlied@linux.ie> 3235783Skib * Copyright (c) 2007, 2010 Intel Corporation 4235783Skib * Jesse Barnes <jesse.barnes@intel.com> 5235783Skib * 6235783Skib * Permission is hereby granted, free of charge, to any person obtaining a 7235783Skib * copy of this software and associated documentation files (the "Software"), 8235783Skib * to deal in the Software without restriction, including without limitation 9235783Skib * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10235783Skib * and/or sell copies of the Software, and to permit persons to whom the 11235783Skib * Software is furnished to do so, subject to the following conditions: 12235783Skib * 13235783Skib * The above copyright notice and this permission notice (including the next 14235783Skib * paragraph) shall be included in all copies or substantial portions of the 15235783Skib * Software. 16235783Skib * 17235783Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18235783Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19235783Skib * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20235783Skib * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21235783Skib * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22235783Skib * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23235783Skib * DEALINGS IN THE SOFTWARE. 24235783Skib */ 25235783Skib 26235783Skib#include <sys/cdefs.h> 27235783Skib__FBSDID("$FreeBSD$"); 28235783Skib 29235783Skib#include <dev/drm2/drmP.h> 30235783Skib#include <dev/drm2/drm.h> 31235783Skib#include <dev/drm2/i915/i915_drm.h> 32235783Skib#include <dev/drm2/i915/i915_drv.h> 33235783Skib#include <dev/drm2/i915/intel_drv.h> 34235783Skib#include <dev/drm2/drm_edid.h> 35235783Skib#include <dev/iicbus/iiconf.h> 36235783Skib 37235783Skib/** 38235783Skib * intel_ddc_probe 39235783Skib * 40235783Skib */ 41235783Skibbool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus) 42235783Skib{ 43235783Skib struct drm_i915_private *dev_priv = intel_encoder->base.dev->dev_private; 44235783Skib u8 out_buf[] = { 0x0, 0x0}; 45235783Skib u8 buf[2]; 46235783Skib struct iic_msg msgs[] = { 47235783Skib { 48261625Sdumbbell .slave = DDC_ADDR << 1, 49235783Skib .flags = IIC_M_WR, 50235783Skib .len = 1, 51235783Skib .buf = out_buf, 52235783Skib }, 53235783Skib { 54261625Sdumbbell .slave = DDC_ADDR << 1, 55235783Skib .flags = IIC_M_RD, 56235783Skib .len = 1, 57235783Skib .buf = buf, 58235783Skib } 59235783Skib }; 60235783Skib 61235783Skib return (iicbus_transfer(dev_priv->gmbus[ddc_bus], msgs, 2) 62235783Skib == 0/* XXXKIB 2*/); 63235783Skib} 64235783Skib 65235783Skib/** 66235783Skib * intel_ddc_get_modes - get modelist from monitor 67235783Skib * @connector: DRM connector device to use 68235783Skib * @adapter: i2c adapter 69235783Skib * 70235783Skib * Fetch the EDID information from @connector using the DDC bus. 71235783Skib */ 72235783Skibint 73235783Skibintel_ddc_get_modes(struct drm_connector *connector, device_t adapter) 74235783Skib{ 75235783Skib struct edid *edid; 76235783Skib int ret = 0; 77235783Skib 78235783Skib edid = drm_get_edid(connector, adapter); 79235783Skib if (edid) { 80235783Skib drm_mode_connector_update_edid_property(connector, edid); 81235783Skib ret = drm_add_edid_modes(connector, edid); 82235783Skib drm_edid_to_eld(connector, edid); 83235783Skib connector->display_info.raw_edid = NULL; 84235783Skib free(edid, DRM_MEM_KMS); 85235783Skib } 86235783Skib 87235783Skib return ret; 88235783Skib} 89235783Skib 90235783Skibstatic const struct drm_prop_enum_list force_audio_names[] = { 91235783Skib { HDMI_AUDIO_OFF_DVI, "force-dvi" }, 92235783Skib { HDMI_AUDIO_OFF, "off" }, 93235783Skib { HDMI_AUDIO_AUTO, "auto" }, 94235783Skib { HDMI_AUDIO_ON, "on" }, 95235783Skib}; 96235783Skib 97235783Skibvoid 98235783Skibintel_attach_force_audio_property(struct drm_connector *connector) 99235783Skib{ 100235783Skib struct drm_device *dev = connector->dev; 101235783Skib struct drm_i915_private *dev_priv = dev->dev_private; 102235783Skib struct drm_property *prop; 103235783Skib 104235783Skib prop = dev_priv->force_audio_property; 105235783Skib if (prop == NULL) { 106235783Skib prop = drm_property_create_enum(dev, 0, 107235783Skib "audio", 108235783Skib force_audio_names, 109235783Skib DRM_ARRAY_SIZE(force_audio_names)); 110235783Skib if (prop == NULL) 111235783Skib return; 112235783Skib 113235783Skib dev_priv->force_audio_property = prop; 114235783Skib } 115235783Skib drm_connector_attach_property(connector, prop, 0); 116235783Skib} 117235783Skib 118235783Skibstatic const struct drm_prop_enum_list broadcast_rgb_names[] = { 119235783Skib { 0, "Full" }, 120235783Skib { 1, "Limited 16:235" }, 121235783Skib}; 122235783Skib 123235783Skibvoid 124235783Skibintel_attach_broadcast_rgb_property(struct drm_connector *connector) 125235783Skib{ 126235783Skib struct drm_device *dev = connector->dev; 127235783Skib struct drm_i915_private *dev_priv = dev->dev_private; 128235783Skib struct drm_property *prop; 129235783Skib 130235783Skib prop = dev_priv->broadcast_rgb_property; 131235783Skib if (prop == NULL) { 132235783Skib prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, 133235783Skib "Broadcast RGB", 134235783Skib broadcast_rgb_names, 135235783Skib DRM_ARRAY_SIZE(broadcast_rgb_names)); 136235783Skib if (prop == NULL) 137235783Skib return; 138235783Skib 139235783Skib dev_priv->broadcast_rgb_property = prop; 140235783Skib } 141235783Skib 142235783Skib drm_connector_attach_property(connector, prop, 0); 143235783Skib} 144