/* * * Copyright (c) 2012 Gilles Dartiguelongue, Thomas Richter * * All Rights Reserved. * * 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, sub license, 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 NON-INFRINGEMENT. * IN NO EVENT SHALL THE AUTHOR 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. * */ #include "i915_drv.h" #include "intel_display_types.h" #include "intel_dvo_dev.h" #define NS2501_VID … #define NS2501_DID … #define NS2501_VID_LO … #define NS2501_VID_HI … #define NS2501_DID_LO … #define NS2501_DID_HI … #define NS2501_REV … #define NS2501_RSVD … #define NS2501_FREQ_LO … #define NS2501_FREQ_HI … #define NS2501_REG8 … #define NS2501_8_VEN … #define NS2501_8_HEN … #define NS2501_8_DSEL … #define NS2501_8_BPAS … #define NS2501_8_RSVD … #define NS2501_8_PD … #define NS2501_REG9 … #define NS2501_9_VLOW … #define NS2501_9_MSEL_MASK … #define NS2501_9_TSEL … #define NS2501_9_RSEN … #define NS2501_9_RSVD … #define NS2501_9_MDI … #define NS2501_REGC … /* * The following registers are not part of the official datasheet * and are the result of reverse engineering. */ /* * Register c0 controls how the DVO synchronizes with * its input. */ #define NS2501_REGC0 … #define NS2501_C0_ENABLE … #define NS2501_C0_HSYNC … #define NS2501_C0_VSYNC … #define NS2501_C0_RESET … /* * Register 41 is somehow related to the sync register and sync * configuration. It should be 0x32 whenever regC0 is 0x05 (hsync off) * and 0x00 otherwise. */ #define NS2501_REG41 … /* * this register controls the dithering of the DVO * One bit enables it, the other define the dithering depth. * The higher the value, the lower the dithering depth. */ #define NS2501_F9_REG … #define NS2501_F9_ENABLE … #define NS2501_F9_DITHER_MASK … #define NS2501_F9_DITHER_SHIFT … /* * PLL configuration register. This is a pair of registers, * one single byte register at 1B, and a pair at 1C,1D. * These registers are counters/dividers. */ #define NS2501_REG1B … #define NS2501_REG1C … #define NS2501_REG1D … /* * Scaler control registers. Horizontal at b8,b9, * vertical at 10,11. The scale factor is computed as * 2^16/control-value. The low-byte comes first. */ #define NS2501_REG10 … #define NS2501_REG11 … #define NS2501_REGB8 … #define NS2501_REGB9 … /* * Display window definition. This consists of four registers * per dimension. One register pair defines the start of the * display, one the end. * As far as I understand, this defines the window within which * the scaler samples the input. */ #define NS2501_REGC1 … #define NS2501_REGC2 … #define NS2501_REGC3 … #define NS2501_REGC4 … #define NS2501_REGC5 … #define NS2501_REGC6 … #define NS2501_REGC7 … #define NS2501_REGC8 … /* * The following register pair seems to define the start of * the vertical sync. If automatic syncing is enabled, and the * register value defines a sync pulse that is later than the * incoming sync, then the register value is ignored and the * external hsync triggers the synchronization. */ #define NS2501_REG80 … #define NS2501_REG81 … /* * The following register pair seems to define the total number * of lines created at the output side of the scaler. * This is again a low-high register pair. */ #define NS2501_REG82 … #define NS2501_REG83 … /* * The following registers define the end of the front-porch * in horizontal and vertical position and hence allow to shift * the image left/right or up/down. */ #define NS2501_REG98 … #define NS2501_REG99 … #define NS2501_REG8E … #define NS2501_REG8F … /* * The following register pair control the function of the * backlight and the DVO output. To enable the corresponding * function, the corresponding bit must be set in both registers. */ #define NS2501_REG34 … #define NS2501_REG35 … #define NS2501_34_ENABLE_OUTPUT … #define NS2501_34_ENABLE_BACKLIGHT … /* * Registers 9C and 9D define the vertical output offset * of the visible region. */ #define NS2501_REG9C … #define NS2501_REG9D … /* * The register 9F defines the dithering. This requires the * scaler to be ON. Bit 0 enables dithering, the remaining * bits control the depth of the dither. The higher the value, * the LOWER the dithering amplitude. A good value seems to be * 15 (total register value). */ #define NS2501_REGF9 … #define NS2501_F9_ENABLE_DITHER … #define NS2501_F9_DITHER_MASK … #define NS2501_F9_DITHER_SHIFT … enum { … }; struct ns2501_reg { … }; /* * The following structure keeps the complete configuration of * the DVO, given a specific output configuration. * This is pretty much guess-work from reverse-engineering, so * read all this with a grain of salt. */ struct ns2501_configuration { … }; /* * DVO configuration values, partially based on what the BIOS * of the Fujitsu Lifebook S6010 writes into registers, * partially found by manual tweaking. These configurations assume * a 1024x768 panel. */ static const struct ns2501_configuration ns2501_modes[] = …; /* * Other configuration values left by the BIOS of the * Fujitsu S6010 in the DVO control registers. Their * value does not depend on the BIOS and their meaning * is unknown. */ static const struct ns2501_reg mode_agnostic_values[] = …; static const struct ns2501_reg regs_init[] = …; struct ns2501_priv { … }; #define NSPTR(d) … /* ** Read a register from the ns2501. ** Returns true if successful, false otherwise. ** If it returns false, it might be wise to enable the ** DVO with the above function. */ static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, u8 *ch) { … } /* ** Write a register to the ns2501. ** Returns true if successful, false otherwise. ** If it returns false, it might be wise to enable the ** DVO with the above function. */ static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, u8 ch) { … } /* National Semiconductor 2501 driver for chip on i2c bus * scan for the chip on the bus. * Hope the VBIOS initialized the PLL correctly so we can * talk to it. If not, it will not be seen and not detected. * Bummer! */ static bool ns2501_init(struct intel_dvo_device *dvo, struct i2c_adapter *adapter) { … } static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo) { … } static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo, struct drm_display_mode *mode) { … } static void ns2501_mode_set(struct intel_dvo_device *dvo, const struct drm_display_mode *mode, const struct drm_display_mode *adjusted_mode) { … } /* set the NS2501 power state */ static bool ns2501_get_hw_state(struct intel_dvo_device *dvo) { … } /* set the NS2501 power state */ static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable) { … } static void ns2501_destroy(struct intel_dvo_device *dvo) { … } const struct intel_dvo_dev_ops ns2501_ops = …;