1 1.1 riastrad /* $NetBSD: dvo_ch7017.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2006 Intel Corporation 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice (including the next 14 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the 15 1.1 riastrad * Software. 16 1.1 riastrad * 17 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 1.1 riastrad * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 1.1 riastrad * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 1.1 riastrad * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 1.1 riastrad * DEALINGS IN THE SOFTWARE. 24 1.1 riastrad * 25 1.1 riastrad * Authors: 26 1.1 riastrad * Eric Anholt <eric (at) anholt.net> 27 1.1 riastrad * 28 1.1 riastrad */ 29 1.1 riastrad 30 1.1 riastrad #include <sys/cdefs.h> 31 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: dvo_ch7017.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $"); 32 1.1 riastrad 33 1.1 riastrad #include "intel_display_types.h" 34 1.1 riastrad #include "intel_dvo_dev.h" 35 1.1 riastrad 36 1.1 riastrad #define CH7017_TV_DISPLAY_MODE 0x00 37 1.1 riastrad #define CH7017_FLICKER_FILTER 0x01 38 1.1 riastrad #define CH7017_VIDEO_BANDWIDTH 0x02 39 1.1 riastrad #define CH7017_TEXT_ENHANCEMENT 0x03 40 1.1 riastrad #define CH7017_START_ACTIVE_VIDEO 0x04 41 1.1 riastrad #define CH7017_HORIZONTAL_POSITION 0x05 42 1.1 riastrad #define CH7017_VERTICAL_POSITION 0x06 43 1.1 riastrad #define CH7017_BLACK_LEVEL 0x07 44 1.1 riastrad #define CH7017_CONTRAST_ENHANCEMENT 0x08 45 1.1 riastrad #define CH7017_TV_PLL 0x09 46 1.1 riastrad #define CH7017_TV_PLL_M 0x0a 47 1.1 riastrad #define CH7017_TV_PLL_N 0x0b 48 1.1 riastrad #define CH7017_SUB_CARRIER_0 0x0c 49 1.1 riastrad #define CH7017_CIV_CONTROL 0x10 50 1.1 riastrad #define CH7017_CIV_0 0x11 51 1.1 riastrad #define CH7017_CHROMA_BOOST 0x14 52 1.1 riastrad #define CH7017_CLOCK_MODE 0x1c 53 1.1 riastrad #define CH7017_INPUT_CLOCK 0x1d 54 1.1 riastrad #define CH7017_GPIO_CONTROL 0x1e 55 1.1 riastrad #define CH7017_INPUT_DATA_FORMAT 0x1f 56 1.1 riastrad #define CH7017_CONNECTION_DETECT 0x20 57 1.1 riastrad #define CH7017_DAC_CONTROL 0x21 58 1.1 riastrad #define CH7017_BUFFERED_CLOCK_OUTPUT 0x22 59 1.1 riastrad #define CH7017_DEFEAT_VSYNC 0x47 60 1.1 riastrad #define CH7017_TEST_PATTERN 0x48 61 1.1 riastrad 62 1.1 riastrad #define CH7017_POWER_MANAGEMENT 0x49 63 1.1 riastrad /** Enables the TV output path. */ 64 1.1 riastrad #define CH7017_TV_EN (1 << 0) 65 1.1 riastrad #define CH7017_DAC0_POWER_DOWN (1 << 1) 66 1.1 riastrad #define CH7017_DAC1_POWER_DOWN (1 << 2) 67 1.1 riastrad #define CH7017_DAC2_POWER_DOWN (1 << 3) 68 1.1 riastrad #define CH7017_DAC3_POWER_DOWN (1 << 4) 69 1.1 riastrad /** Powers down the TV out block, and DAC0-3 */ 70 1.1 riastrad #define CH7017_TV_POWER_DOWN_EN (1 << 5) 71 1.1 riastrad 72 1.1 riastrad #define CH7017_VERSION_ID 0x4a 73 1.1 riastrad 74 1.1 riastrad #define CH7017_DEVICE_ID 0x4b 75 1.1 riastrad #define CH7017_DEVICE_ID_VALUE 0x1b 76 1.1 riastrad #define CH7018_DEVICE_ID_VALUE 0x1a 77 1.1 riastrad #define CH7019_DEVICE_ID_VALUE 0x19 78 1.1 riastrad 79 1.1 riastrad #define CH7017_XCLK_D2_ADJUST 0x53 80 1.1 riastrad #define CH7017_UP_SCALER_COEFF_0 0x55 81 1.1 riastrad #define CH7017_UP_SCALER_COEFF_1 0x56 82 1.1 riastrad #define CH7017_UP_SCALER_COEFF_2 0x57 83 1.1 riastrad #define CH7017_UP_SCALER_COEFF_3 0x58 84 1.1 riastrad #define CH7017_UP_SCALER_COEFF_4 0x59 85 1.1 riastrad #define CH7017_UP_SCALER_VERTICAL_INC_0 0x5a 86 1.1 riastrad #define CH7017_UP_SCALER_VERTICAL_INC_1 0x5b 87 1.1 riastrad #define CH7017_GPIO_INVERT 0x5c 88 1.1 riastrad #define CH7017_UP_SCALER_HORIZONTAL_INC_0 0x5d 89 1.1 riastrad #define CH7017_UP_SCALER_HORIZONTAL_INC_1 0x5e 90 1.1 riastrad 91 1.1 riastrad #define CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT 0x5f 92 1.1 riastrad /**< Low bits of horizontal active pixel input */ 93 1.1 riastrad 94 1.1 riastrad #define CH7017_ACTIVE_INPUT_LINE_OUTPUT 0x60 95 1.1 riastrad /** High bits of horizontal active pixel input */ 96 1.1 riastrad #define CH7017_LVDS_HAP_INPUT_MASK (0x7 << 0) 97 1.1 riastrad /** High bits of vertical active line output */ 98 1.1 riastrad #define CH7017_LVDS_VAL_HIGH_MASK (0x7 << 3) 99 1.1 riastrad 100 1.1 riastrad #define CH7017_VERTICAL_ACTIVE_LINE_OUTPUT 0x61 101 1.1 riastrad /**< Low bits of vertical active line output */ 102 1.1 riastrad 103 1.1 riastrad #define CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT 0x62 104 1.1 riastrad /**< Low bits of horizontal active pixel output */ 105 1.1 riastrad 106 1.1 riastrad #define CH7017_LVDS_POWER_DOWN 0x63 107 1.1 riastrad /** High bits of horizontal active pixel output */ 108 1.1 riastrad #define CH7017_LVDS_HAP_HIGH_MASK (0x7 << 0) 109 1.1 riastrad /** Enables the LVDS power down state transition */ 110 1.1 riastrad #define CH7017_LVDS_POWER_DOWN_EN (1 << 6) 111 1.1 riastrad /** Enables the LVDS upscaler */ 112 1.1 riastrad #define CH7017_LVDS_UPSCALER_EN (1 << 7) 113 1.1 riastrad #define CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED 0x08 114 1.1 riastrad 115 1.1 riastrad #define CH7017_LVDS_ENCODING 0x64 116 1.1 riastrad #define CH7017_LVDS_DITHER_2D (1 << 2) 117 1.1 riastrad #define CH7017_LVDS_DITHER_DIS (1 << 3) 118 1.1 riastrad #define CH7017_LVDS_DUAL_CHANNEL_EN (1 << 4) 119 1.1 riastrad #define CH7017_LVDS_24_BIT (1 << 5) 120 1.1 riastrad 121 1.1 riastrad #define CH7017_LVDS_ENCODING_2 0x65 122 1.1 riastrad 123 1.1 riastrad #define CH7017_LVDS_PLL_CONTROL 0x66 124 1.1 riastrad /** Enables the LVDS panel output path */ 125 1.1 riastrad #define CH7017_LVDS_PANEN (1 << 0) 126 1.1 riastrad /** Enables the LVDS panel backlight */ 127 1.1 riastrad #define CH7017_LVDS_BKLEN (1 << 3) 128 1.1 riastrad 129 1.1 riastrad #define CH7017_POWER_SEQUENCING_T1 0x67 130 1.1 riastrad #define CH7017_POWER_SEQUENCING_T2 0x68 131 1.1 riastrad #define CH7017_POWER_SEQUENCING_T3 0x69 132 1.1 riastrad #define CH7017_POWER_SEQUENCING_T4 0x6a 133 1.1 riastrad #define CH7017_POWER_SEQUENCING_T5 0x6b 134 1.1 riastrad #define CH7017_GPIO_DRIVER_TYPE 0x6c 135 1.1 riastrad #define CH7017_GPIO_DATA 0x6d 136 1.1 riastrad #define CH7017_GPIO_DIRECTION_CONTROL 0x6e 137 1.1 riastrad 138 1.1 riastrad #define CH7017_LVDS_PLL_FEEDBACK_DIV 0x71 139 1.1 riastrad # define CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT 4 140 1.1 riastrad # define CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT 0 141 1.1 riastrad # define CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED 0x80 142 1.1 riastrad 143 1.1 riastrad #define CH7017_LVDS_PLL_VCO_CONTROL 0x72 144 1.1 riastrad # define CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED 0x80 145 1.1 riastrad # define CH7017_LVDS_PLL_VCO_SHIFT 4 146 1.1 riastrad # define CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT 0 147 1.1 riastrad 148 1.1 riastrad #define CH7017_OUTPUTS_ENABLE 0x73 149 1.1 riastrad # define CH7017_CHARGE_PUMP_LOW 0x0 150 1.1 riastrad # define CH7017_CHARGE_PUMP_HIGH 0x3 151 1.1 riastrad # define CH7017_LVDS_CHANNEL_A (1 << 3) 152 1.1 riastrad # define CH7017_LVDS_CHANNEL_B (1 << 4) 153 1.1 riastrad # define CH7017_TV_DAC_A (1 << 5) 154 1.1 riastrad # define CH7017_TV_DAC_B (1 << 6) 155 1.1 riastrad # define CH7017_DDC_SELECT_DC2 (1 << 7) 156 1.1 riastrad 157 1.1 riastrad #define CH7017_LVDS_OUTPUT_AMPLITUDE 0x74 158 1.1 riastrad #define CH7017_LVDS_PLL_EMI_REDUCTION 0x75 159 1.1 riastrad #define CH7017_LVDS_POWER_DOWN_FLICKER 0x76 160 1.1 riastrad 161 1.1 riastrad #define CH7017_LVDS_CONTROL_2 0x78 162 1.1 riastrad # define CH7017_LOOP_FILTER_SHIFT 5 163 1.1 riastrad # define CH7017_PHASE_DETECTOR_SHIFT 0 164 1.1 riastrad 165 1.1 riastrad #define CH7017_BANG_LIMIT_CONTROL 0x7f 166 1.1 riastrad 167 1.1 riastrad struct ch7017_priv { 168 1.1 riastrad u8 dummy; 169 1.1 riastrad }; 170 1.1 riastrad 171 1.1 riastrad static void ch7017_dump_regs(struct intel_dvo_device *dvo); 172 1.1 riastrad static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable); 173 1.1 riastrad 174 1.1 riastrad static bool ch7017_read(struct intel_dvo_device *dvo, u8 addr, u8 *val) 175 1.1 riastrad { 176 1.1 riastrad struct i2c_msg msgs[] = { 177 1.1 riastrad { 178 1.1 riastrad .addr = dvo->slave_addr, 179 1.1 riastrad .flags = 0, 180 1.1 riastrad .len = 1, 181 1.1 riastrad .buf = &addr, 182 1.1 riastrad }, 183 1.1 riastrad { 184 1.1 riastrad .addr = dvo->slave_addr, 185 1.1 riastrad .flags = I2C_M_RD, 186 1.1 riastrad .len = 1, 187 1.1 riastrad .buf = val, 188 1.1 riastrad } 189 1.1 riastrad }; 190 1.1 riastrad return i2c_transfer(dvo->i2c_bus, msgs, 2) == 2; 191 1.1 riastrad } 192 1.1 riastrad 193 1.1 riastrad static bool ch7017_write(struct intel_dvo_device *dvo, u8 addr, u8 val) 194 1.1 riastrad { 195 1.1 riastrad u8 buf[2] = { addr, val }; 196 1.1 riastrad struct i2c_msg msg = { 197 1.1 riastrad .addr = dvo->slave_addr, 198 1.1 riastrad .flags = 0, 199 1.1 riastrad .len = 2, 200 1.1 riastrad .buf = buf, 201 1.1 riastrad }; 202 1.1 riastrad return i2c_transfer(dvo->i2c_bus, &msg, 1) == 1; 203 1.1 riastrad } 204 1.1 riastrad 205 1.1 riastrad /** Probes for a CH7017 on the given bus and slave address. */ 206 1.1 riastrad static bool ch7017_init(struct intel_dvo_device *dvo, 207 1.1 riastrad struct i2c_adapter *adapter) 208 1.1 riastrad { 209 1.1 riastrad struct ch7017_priv *priv; 210 1.1 riastrad const char *str; 211 1.1 riastrad u8 val; 212 1.1 riastrad 213 1.1 riastrad priv = kzalloc(sizeof(struct ch7017_priv), GFP_KERNEL); 214 1.1 riastrad if (priv == NULL) 215 1.1 riastrad return false; 216 1.1 riastrad 217 1.1 riastrad dvo->i2c_bus = adapter; 218 1.1 riastrad dvo->dev_priv = priv; 219 1.1 riastrad 220 1.1 riastrad if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val)) 221 1.1 riastrad goto fail; 222 1.1 riastrad 223 1.1 riastrad switch (val) { 224 1.1 riastrad case CH7017_DEVICE_ID_VALUE: 225 1.1 riastrad str = "ch7017"; 226 1.1 riastrad break; 227 1.1 riastrad case CH7018_DEVICE_ID_VALUE: 228 1.1 riastrad str = "ch7018"; 229 1.1 riastrad break; 230 1.1 riastrad case CH7019_DEVICE_ID_VALUE: 231 1.1 riastrad str = "ch7019"; 232 1.1 riastrad break; 233 1.1 riastrad default: 234 1.1 riastrad DRM_DEBUG_KMS("ch701x not detected, got %d: from %s " 235 1.1 riastrad "slave %d.\n", 236 1.1 riastrad val, adapter->name, dvo->slave_addr); 237 1.1 riastrad goto fail; 238 1.1 riastrad } 239 1.1 riastrad 240 1.1 riastrad DRM_DEBUG_KMS("%s detected on %s, addr %d\n", 241 1.1 riastrad str, adapter->name, dvo->slave_addr); 242 1.1 riastrad return true; 243 1.1 riastrad 244 1.1 riastrad fail: 245 1.1 riastrad kfree(priv); 246 1.1 riastrad return false; 247 1.1 riastrad } 248 1.1 riastrad 249 1.1 riastrad static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo) 250 1.1 riastrad { 251 1.1 riastrad return connector_status_connected; 252 1.1 riastrad } 253 1.1 riastrad 254 1.1 riastrad static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo, 255 1.1 riastrad struct drm_display_mode *mode) 256 1.1 riastrad { 257 1.1 riastrad if (mode->clock > 160000) 258 1.1 riastrad return MODE_CLOCK_HIGH; 259 1.1 riastrad 260 1.1 riastrad return MODE_OK; 261 1.1 riastrad } 262 1.1 riastrad 263 1.1 riastrad static void ch7017_mode_set(struct intel_dvo_device *dvo, 264 1.1 riastrad const struct drm_display_mode *mode, 265 1.1 riastrad const struct drm_display_mode *adjusted_mode) 266 1.1 riastrad { 267 1.1 riastrad u8 lvds_pll_feedback_div, lvds_pll_vco_control; 268 1.1 riastrad u8 outputs_enable, lvds_control_2, lvds_power_down; 269 1.1 riastrad u8 horizontal_active_pixel_input; 270 1.1 riastrad u8 horizontal_active_pixel_output, vertical_active_line_output; 271 1.1 riastrad u8 active_input_line_output; 272 1.1 riastrad 273 1.1 riastrad DRM_DEBUG_KMS("Registers before mode setting\n"); 274 1.1 riastrad ch7017_dump_regs(dvo); 275 1.1 riastrad 276 1.1 riastrad /* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/ 277 1.1 riastrad if (mode->clock < 100000) { 278 1.1 riastrad outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_LOW; 279 1.1 riastrad lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED | 280 1.1 riastrad (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) | 281 1.1 riastrad (13 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT); 282 1.1 riastrad lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | 283 1.1 riastrad (2 << CH7017_LVDS_PLL_VCO_SHIFT) | 284 1.1 riastrad (3 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); 285 1.1 riastrad lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) | 286 1.1 riastrad (0 << CH7017_PHASE_DETECTOR_SHIFT); 287 1.1 riastrad } else { 288 1.1 riastrad outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_HIGH; 289 1.1 riastrad lvds_pll_feedback_div = 290 1.1 riastrad CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED | 291 1.1 riastrad (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) | 292 1.1 riastrad (3 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT); 293 1.1 riastrad lvds_control_2 = (3 << CH7017_LOOP_FILTER_SHIFT) | 294 1.1 riastrad (0 << CH7017_PHASE_DETECTOR_SHIFT); 295 1.1 riastrad if (1) { /* XXX: dual channel panel detection. Assume yes for now. */ 296 1.1 riastrad outputs_enable |= CH7017_LVDS_CHANNEL_B; 297 1.1 riastrad lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | 298 1.1 riastrad (2 << CH7017_LVDS_PLL_VCO_SHIFT) | 299 1.1 riastrad (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); 300 1.1 riastrad } else { 301 1.1 riastrad lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | 302 1.1 riastrad (1 << CH7017_LVDS_PLL_VCO_SHIFT) | 303 1.1 riastrad (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); 304 1.1 riastrad } 305 1.1 riastrad } 306 1.1 riastrad 307 1.1 riastrad horizontal_active_pixel_input = mode->hdisplay & 0x00ff; 308 1.1 riastrad 309 1.1 riastrad vertical_active_line_output = mode->vdisplay & 0x00ff; 310 1.1 riastrad horizontal_active_pixel_output = mode->hdisplay & 0x00ff; 311 1.1 riastrad 312 1.1 riastrad active_input_line_output = ((mode->hdisplay & 0x0700) >> 8) | 313 1.1 riastrad (((mode->vdisplay & 0x0700) >> 8) << 3); 314 1.1 riastrad 315 1.1 riastrad lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED | 316 1.1 riastrad (mode->hdisplay & 0x0700) >> 8; 317 1.1 riastrad 318 1.1 riastrad ch7017_dpms(dvo, false); 319 1.1 riastrad ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, 320 1.1 riastrad horizontal_active_pixel_input); 321 1.1 riastrad ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT, 322 1.1 riastrad horizontal_active_pixel_output); 323 1.1 riastrad ch7017_write(dvo, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, 324 1.1 riastrad vertical_active_line_output); 325 1.1 riastrad ch7017_write(dvo, CH7017_ACTIVE_INPUT_LINE_OUTPUT, 326 1.1 riastrad active_input_line_output); 327 1.1 riastrad ch7017_write(dvo, CH7017_LVDS_PLL_VCO_CONTROL, lvds_pll_vco_control); 328 1.1 riastrad ch7017_write(dvo, CH7017_LVDS_PLL_FEEDBACK_DIV, lvds_pll_feedback_div); 329 1.1 riastrad ch7017_write(dvo, CH7017_LVDS_CONTROL_2, lvds_control_2); 330 1.1 riastrad ch7017_write(dvo, CH7017_OUTPUTS_ENABLE, outputs_enable); 331 1.1 riastrad 332 1.1 riastrad /* Turn the LVDS back on with new settings. */ 333 1.1 riastrad ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, lvds_power_down); 334 1.1 riastrad 335 1.1 riastrad DRM_DEBUG_KMS("Registers after mode setting\n"); 336 1.1 riastrad ch7017_dump_regs(dvo); 337 1.1 riastrad } 338 1.1 riastrad 339 1.1 riastrad /* set the CH7017 power state */ 340 1.1 riastrad static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable) 341 1.1 riastrad { 342 1.1 riastrad u8 val; 343 1.1 riastrad 344 1.1 riastrad ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &val); 345 1.1 riastrad 346 1.1 riastrad /* Turn off TV/VGA, and never turn it on since we don't support it. */ 347 1.1 riastrad ch7017_write(dvo, CH7017_POWER_MANAGEMENT, 348 1.1 riastrad CH7017_DAC0_POWER_DOWN | 349 1.1 riastrad CH7017_DAC1_POWER_DOWN | 350 1.1 riastrad CH7017_DAC2_POWER_DOWN | 351 1.1 riastrad CH7017_DAC3_POWER_DOWN | 352 1.1 riastrad CH7017_TV_POWER_DOWN_EN); 353 1.1 riastrad 354 1.1 riastrad if (enable) { 355 1.1 riastrad /* Turn on the LVDS */ 356 1.1 riastrad ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, 357 1.1 riastrad val & ~CH7017_LVDS_POWER_DOWN_EN); 358 1.1 riastrad } else { 359 1.1 riastrad /* Turn off the LVDS */ 360 1.1 riastrad ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, 361 1.1 riastrad val | CH7017_LVDS_POWER_DOWN_EN); 362 1.1 riastrad } 363 1.1 riastrad 364 1.1 riastrad /* XXX: Should actually wait for update power status somehow */ 365 1.1 riastrad msleep(20); 366 1.1 riastrad } 367 1.1 riastrad 368 1.1 riastrad static bool ch7017_get_hw_state(struct intel_dvo_device *dvo) 369 1.1 riastrad { 370 1.1 riastrad u8 val; 371 1.1 riastrad 372 1.1 riastrad ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &val); 373 1.1 riastrad 374 1.1 riastrad if (val & CH7017_LVDS_POWER_DOWN_EN) 375 1.1 riastrad return false; 376 1.1 riastrad else 377 1.1 riastrad return true; 378 1.1 riastrad } 379 1.1 riastrad 380 1.1 riastrad static void ch7017_dump_regs(struct intel_dvo_device *dvo) 381 1.1 riastrad { 382 1.1 riastrad u8 val; 383 1.1 riastrad 384 1.1 riastrad #define DUMP(reg) \ 385 1.1 riastrad do { \ 386 1.1 riastrad ch7017_read(dvo, reg, &val); \ 387 1.1 riastrad DRM_DEBUG_KMS(#reg ": %02x\n", val); \ 388 1.1 riastrad } while (0) 389 1.1 riastrad 390 1.1 riastrad DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT); 391 1.1 riastrad DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT); 392 1.1 riastrad DUMP(CH7017_VERTICAL_ACTIVE_LINE_OUTPUT); 393 1.1 riastrad DUMP(CH7017_ACTIVE_INPUT_LINE_OUTPUT); 394 1.1 riastrad DUMP(CH7017_LVDS_PLL_VCO_CONTROL); 395 1.1 riastrad DUMP(CH7017_LVDS_PLL_FEEDBACK_DIV); 396 1.1 riastrad DUMP(CH7017_LVDS_CONTROL_2); 397 1.1 riastrad DUMP(CH7017_OUTPUTS_ENABLE); 398 1.1 riastrad DUMP(CH7017_LVDS_POWER_DOWN); 399 1.1 riastrad } 400 1.1 riastrad 401 1.1 riastrad static void ch7017_destroy(struct intel_dvo_device *dvo) 402 1.1 riastrad { 403 1.1 riastrad struct ch7017_priv *priv = dvo->dev_priv; 404 1.1 riastrad 405 1.1 riastrad if (priv) { 406 1.1 riastrad kfree(priv); 407 1.1 riastrad dvo->dev_priv = NULL; 408 1.1 riastrad } 409 1.1 riastrad } 410 1.1 riastrad 411 1.1 riastrad const struct intel_dvo_dev_ops ch7017_ops = { 412 1.1 riastrad .init = ch7017_init, 413 1.1 riastrad .detect = ch7017_detect, 414 1.1 riastrad .mode_valid = ch7017_mode_valid, 415 1.1 riastrad .mode_set = ch7017_mode_set, 416 1.1 riastrad .dpms = ch7017_dpms, 417 1.1 riastrad .get_hw_state = ch7017_get_hw_state, 418 1.1 riastrad .dump_regs = ch7017_dump_regs, 419 1.1 riastrad .destroy = ch7017_destroy, 420 1.1 riastrad }; 421