/* * Copyright © 2006-2007 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Eric Anholt */ /* * Copyright (c) 2006 Dave Airlie * Jesse Barnes */ #include #include "drmP.h" #include "drm.h" #include "drm_crtc.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" /** * Sets the backlight level. * * \param level backlight level, from 0 to i830_lvds_get_max_backlight(). */ static void lvds_set_backlight(drm_device_t *dev, u32 level) { drm_i915_private_t *dev_priv = dev->dev_private; unsigned long blc_pwm_ctl; level &= BACKLIGHT_DUTY_CYCLE_MASK; blc_pwm_ctl = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); } /** * Returns the maximum level of the backlight duty cycle field. */ static u32 lvds_get_max_backlight(drm_device_t *dev) { drm_i915_private_t *dev_priv = dev->dev_private; return ((I915_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >> BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; } int lvds_backlight(DRM_IOCTL_ARGS) { DRM_DEVICE; unsigned long dvoa_enabled, dvob_enabled, dvoc_enabled, lvds_enabled; drm_i915_private_t *dev_priv = dev->dev_private; printk(KERN_ERR "max backlight value: %d\n", lvds_get_max_backlight(dev)); dvoa_enabled = I915_READ(DVOA); dvob_enabled = I915_READ(DVOB); dvoc_enabled = I915_READ(DVOC); lvds_enabled = I915_READ(LVDS); printk(KERN_ERR "dvoa_enabled: 0x%08lx\n", dvoa_enabled); printk(KERN_ERR "dvob_enabled: 0x%08lx\n", dvob_enabled); printk(KERN_ERR "dvoc_enabled: 0x%08lx\n", dvoc_enabled); printk(KERN_ERR "lvds_enabled: 0x%08lx\n", lvds_enabled); printk(KERN_ERR "BLC_PWM_CTL: 0x%08x\n", I915_READ(BLC_PWM_CTL)); return 0; } static const struct drm_output_funcs intel_lvds_output_funcs; /** * intel_lvds_init - setup LVDS outputs on this device * @dev: drm device * * Create the output, register the LVDS DDC bus, and try to figure out what * modes we can display on the LVDS panel (if present). */ void intel_lvds_init(drm_device_t *dev) { struct drm_output *output; struct intel_output *intel_output; int modes; output = drm_output_create(dev, &intel_lvds_output_funcs, "LVDS"); if (!output) return; intel_output = kmalloc(sizeof(struct intel_output), GFP_KERNEL); if (!intel_output) { drm_output_destroy(output); return; } intel_output->type = INTEL_OUTPUT_LVDS; output->driver_private = intel_output; output->subpixel_order = SubPixelHorizontalRGB; output->interlace_allowed = 0; output->doublescan_allowed = 0; intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); if (!intel_output->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); return; } modes = intel_ddc_get_modes(output); intel_i2c_destroy(intel_output->ddc_bus); drm_output_destroy(output); }