dvo_ivch.c revision 1494
/*
*/
/*
* Copyright (c) 2006, 2013, 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,
* 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 <eric@anholt.net>
*
*/
#include "dvo.h"
/*
* register definitions for the i82807aa.
*
* Documentation on this chipset can be found in datasheet #29069001 at
* intel.com.
*/
/*
* VCH Revision & GMBus Base Addr
*/
#define VR00 0x00
# define VR00_BASE_ADDRESS_MASK 0x007f
/*
* Functionality Enable
*/
#define VR01 0x01
/*
* Enable the panel fitter
*/
/*
* Enables the LCD display.
*
* This must not be set while VR01_DVO_BYPASS_ENABLE is set.
*/
/** Enables the DVO repeater. */
/** Enables the DVO clock */
# define VR01_DVO_ENABLE (1 << 0)
/*
* LCD Interface Format
*/
#define VR10 0x10
/** Enables LVDS output instead of CMOS */
/** Enables 18-bit LVDS output. */
# define VR10_INTERFACE_1X18 (0 << 2)
/** Enables 24-bit LVDS or CMOS output */
/** Enables 2x18-bit LVDS or CMOS output. */
/** Enables 2x24-bit LVDS output */
/*
* VR20 LCD Horizontal Display Size
*/
#define VR20 0x20
/*
* LCD Vertical Display Size
*/
#define VR21 0x20
/*
* Panel power down status
*/
#define VR30 0x30
/** Read only bit indicating that the panel is not in a safe poweroff state. */
#define VR40 0x40
/*
* Panel Fitting Vertical Ratio
* (((image_height - 1) << 16) / ((panel_height - 1))) >> 2
*/
#define VR41 0x41
/*
* Panel Fitting Horizontal Ratio
* (((image_width - 1) << 16) / ((panel_width - 1))) >> 2
*/
#define VR42 0x42
/*
* Horizontal Image Size
*/
#define VR43 0x43
/* VR80 GPIO 0
*/
#define VR80 0x80
#define VR81 0x81
#define VR82 0x82
#define VR83 0x83
#define VR84 0x84
#define VR85 0x85
#define VR86 0x86
#define VR87 0x87
/* VR88 GPIO 8
*/
#define VR88 0x88
/* Graphics BIOS scratch 0
*/
#define VR8E 0x8E
# define VR8E_PANEL_TYPE_MASK (0xf << 0)
# define VR8E_PANEL_INTERFACE_CMOS (0 << 4)
/* Graphics BIOS scratch 1
*/
#define VR8F 0x8F
# define VR8F_VCH_PRESENT (1 << 0)
# define VR8F_POWER_MASK (0x3c)
# define VR8F_POWER_POS (2)
struct ivch_priv {
bool quiet;
};
/**
* Reads a register on the ivch.
*
* Each of the 256 registers are 16 bits long.
*/
{
{
.len = 0,
},
{
.addr = 0,
.flags = I2C_M_NOSTART,
.len = 1,
},
{
.len = 2,
}
};
return true;
};
DRM_DEBUG_KMS("Unable to read register 0x%02x from "
"%s:%02x.\n",
}
return false;
}
/** Writes a 16-bit register on the ivch */
{
.flags = 0,
.len = 3,
};
return true;
DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d.\n",
}
return false;
}
/** Probes the given bus and slave address for an ivch */
struct i2c_adapter *adapter)
{
return false;
goto out;
/* Since the identification bits are probably zeroes, which doesn't seem
* very unique, check that the value in the base address field matches
* the address it's responding on.
*/
DRM_DEBUG_KMS("ivch detect failed due to address mismatch "
"(%d vs %d)\n",
goto out;
}
return true;
out:
return false;
}
/* LINTED */
{
return connector_status_connected;
}
/* LINTED */
struct drm_display_mode *mode)
{
return MODE_CLOCK_HIGH;
return MODE_OK;
}
/** Sets the power state of the panel connected to the ivch */
{
int i;
/* Set the new power state of the panel. */
return;
if (enable)
backlight = 1;
else
backlight = 0;
if (enable)
else
/* Wait for the panel to make its state transition */
for (i = 0; i < 100; i++) {
break;
break;
udelay(1000);
}
/* wait some more; vch may fail to resync sometimes without this */
}
{
/* Set the new power state of the panel. */
return false;
if (vr01 & VR01_LCD_ENABLE)
return true;
else
return false;
}
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
vr01 = 0;
} else {
}
}
{
/* GPIO registers */
/* Scratch register 0 - AIM Panel type */
/* Scratch register 1 - Status register */
}
{
if (priv) {
}
}
struct intel_dvo_dev_ops ivch_ops= {
.detect = ivch_detect,
.destroy = ivch_destroy,
};