0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "i915_drv.h"
0030 #include "i915_reg.h"
0031 #include "intel_display_types.h"
0032 #include "intel_dvo_dev.h"
0033
0034 #define NS2501_VID 0x1305
0035 #define NS2501_DID 0x6726
0036
0037 #define NS2501_VID_LO 0x00
0038 #define NS2501_VID_HI 0x01
0039 #define NS2501_DID_LO 0x02
0040 #define NS2501_DID_HI 0x03
0041 #define NS2501_REV 0x04
0042 #define NS2501_RSVD 0x05
0043 #define NS2501_FREQ_LO 0x06
0044 #define NS2501_FREQ_HI 0x07
0045
0046 #define NS2501_REG8 0x08
0047 #define NS2501_8_VEN (1<<5)
0048 #define NS2501_8_HEN (1<<4)
0049 #define NS2501_8_DSEL (1<<3)
0050 #define NS2501_8_BPAS (1<<2)
0051 #define NS2501_8_RSVD (1<<1)
0052 #define NS2501_8_PD (1<<0)
0053
0054 #define NS2501_REG9 0x09
0055 #define NS2501_9_VLOW (1<<7)
0056 #define NS2501_9_MSEL_MASK (0x7<<4)
0057 #define NS2501_9_TSEL (1<<3)
0058 #define NS2501_9_RSEN (1<<2)
0059 #define NS2501_9_RSVD (1<<1)
0060 #define NS2501_9_MDI (1<<0)
0061
0062 #define NS2501_REGC 0x0c
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 #define NS2501_REGC0 0xc0
0074 #define NS2501_C0_ENABLE (1<<0)
0075 #define NS2501_C0_HSYNC (1<<1)
0076 #define NS2501_C0_VSYNC (1<<2)
0077 #define NS2501_C0_RESET (1<<7)
0078
0079
0080
0081
0082
0083
0084 #define NS2501_REG41 0x41
0085
0086
0087
0088
0089
0090
0091 #define NS2501_F9_REG 0xf9
0092 #define NS2501_F9_ENABLE (1<<0)
0093 #define NS2501_F9_DITHER_MASK (0x7f<<1)
0094 #define NS2501_F9_DITHER_SHIFT 1
0095
0096
0097
0098
0099
0100
0101 #define NS2501_REG1B 0x1b
0102 #define NS2501_REG1C 0x1c
0103 #define NS2501_REG1D 0x1d
0104
0105
0106
0107
0108
0109
0110 #define NS2501_REG10 0x10
0111 #define NS2501_REG11 0x11
0112 #define NS2501_REGB8 0xb8
0113 #define NS2501_REGB9 0xb9
0114
0115
0116
0117
0118
0119
0120
0121
0122 #define NS2501_REGC1 0xc1
0123 #define NS2501_REGC2 0xc2
0124 #define NS2501_REGC3 0xc3
0125 #define NS2501_REGC4 0xc4
0126 #define NS2501_REGC5 0xc5
0127 #define NS2501_REGC6 0xc6
0128 #define NS2501_REGC7 0xc7
0129 #define NS2501_REGC8 0xc8
0130
0131
0132
0133
0134
0135
0136
0137
0138 #define NS2501_REG80 0x80
0139 #define NS2501_REG81 0x81
0140
0141
0142
0143
0144
0145
0146 #define NS2501_REG82 0x82
0147 #define NS2501_REG83 0x83
0148
0149
0150
0151
0152
0153
0154 #define NS2501_REG98 0x98
0155 #define NS2501_REG99 0x99
0156 #define NS2501_REG8E 0x8e
0157 #define NS2501_REG8F 0x8f
0158
0159
0160
0161
0162
0163
0164 #define NS2501_REG34 0x34
0165 #define NS2501_REG35 0x35
0166 #define NS2501_34_ENABLE_OUTPUT (1<<0)
0167 #define NS2501_34_ENABLE_BACKLIGHT (1<<1)
0168
0169
0170
0171
0172
0173 #define NS2501_REG9C 0x9c
0174 #define NS2501_REG9D 0x9d
0175
0176
0177
0178
0179
0180
0181
0182
0183 #define NS2501_REGF9 0xf9
0184 #define NS2501_F9_ENABLE_DITHER (1<<0)
0185 #define NS2501_F9_DITHER_MASK (0x7f<<1)
0186 #define NS2501_F9_DITHER_SHIFT 1
0187
0188 enum {
0189 MODE_640x480,
0190 MODE_800x600,
0191 MODE_1024x768,
0192 };
0193
0194 struct ns2501_reg {
0195 u8 offset;
0196 u8 value;
0197 };
0198
0199
0200
0201
0202
0203
0204
0205 struct ns2501_configuration {
0206 u8 sync;
0207 u8 conf;
0208 u8 syncb;
0209 u8 dither;
0210 u8 pll_a;
0211 u16 pll_b;
0212 u16 hstart;
0213 u16 hstop;
0214 u16 vstart;
0215 u16 vstop;
0216 u16 vsync;
0217 u16 vtotal;
0218 u16 hpos;
0219 u16 vpos;
0220 u16 voffs;
0221 u16 hscale;
0222 u16 vscale;
0223 };
0224
0225
0226
0227
0228
0229
0230
0231 static const struct ns2501_configuration ns2501_modes[] = {
0232 [MODE_640x480] = {
0233 .sync = NS2501_C0_ENABLE | NS2501_C0_VSYNC,
0234 .conf = NS2501_8_VEN | NS2501_8_HEN | NS2501_8_PD,
0235 .syncb = 0x32,
0236 .dither = 0x0f,
0237 .pll_a = 17,
0238 .pll_b = 852,
0239 .hstart = 144,
0240 .hstop = 783,
0241 .vstart = 22,
0242 .vstop = 514,
0243 .vsync = 2047,
0244 .vtotal = 1341,
0245 .hpos = 0,
0246 .vpos = 16,
0247 .voffs = 36,
0248 .hscale = 40960,
0249 .vscale = 40960
0250 },
0251 [MODE_800x600] = {
0252 .sync = NS2501_C0_ENABLE |
0253 NS2501_C0_HSYNC | NS2501_C0_VSYNC,
0254 .conf = NS2501_8_VEN | NS2501_8_HEN | NS2501_8_PD,
0255 .syncb = 0x00,
0256 .dither = 0x0f,
0257 .pll_a = 25,
0258 .pll_b = 612,
0259 .hstart = 215,
0260 .hstop = 1016,
0261 .vstart = 26,
0262 .vstop = 627,
0263 .vsync = 807,
0264 .vtotal = 1341,
0265 .hpos = 0,
0266 .vpos = 4,
0267 .voffs = 35,
0268 .hscale = 51248,
0269 .vscale = 51232
0270 },
0271 [MODE_1024x768] = {
0272 .sync = NS2501_C0_ENABLE | NS2501_C0_VSYNC,
0273 .conf = NS2501_8_VEN | NS2501_8_HEN | NS2501_8_PD,
0274 .syncb = 0x32,
0275 .dither = 0x0f,
0276 .pll_a = 11,
0277 .pll_b = 1350,
0278 .hstart = 276,
0279 .hstop = 1299,
0280 .vstart = 15,
0281 .vstop = 1056,
0282 .vsync = 2047,
0283 .vtotal = 1341,
0284 .hpos = 0,
0285 .vpos = 7,
0286 .voffs = 27,
0287 .hscale = 65535,
0288 .vscale = 65535
0289 }
0290 };
0291
0292
0293
0294
0295
0296
0297
0298
0299 static const struct ns2501_reg mode_agnostic_values[] = {
0300
0301 [0] = { .offset = 0x0a, .value = 0x81, },
0302
0303 [1] = { .offset = 0x12, .value = 0x02, },
0304 [2] = { .offset = 0x18, .value = 0x07, },
0305 [3] = { .offset = 0x19, .value = 0x00, },
0306 [4] = { .offset = 0x1a, .value = 0x00, },
0307
0308 [5] = { .offset = 0x1e, .value = 0x02, },
0309 [6] = { .offset = 0x1f, .value = 0x40, },
0310 [7] = { .offset = 0x20, .value = 0x00, },
0311 [8] = { .offset = 0x21, .value = 0x00, },
0312 [9] = { .offset = 0x22, .value = 0x00, },
0313 [10] = { .offset = 0x23, .value = 0x00, },
0314 [11] = { .offset = 0x24, .value = 0x00, },
0315 [12] = { .offset = 0x25, .value = 0x00, },
0316 [13] = { .offset = 0x26, .value = 0x00, },
0317 [14] = { .offset = 0x27, .value = 0x00, },
0318 [15] = { .offset = 0x7e, .value = 0x18, },
0319
0320 [16] = { .offset = 0x84, .value = 0x00, },
0321 [17] = { .offset = 0x85, .value = 0x00, },
0322 [18] = { .offset = 0x86, .value = 0x00, },
0323 [19] = { .offset = 0x87, .value = 0x00, },
0324 [20] = { .offset = 0x88, .value = 0x00, },
0325 [21] = { .offset = 0x89, .value = 0x00, },
0326 [22] = { .offset = 0x8a, .value = 0x00, },
0327 [23] = { .offset = 0x8b, .value = 0x00, },
0328 [24] = { .offset = 0x8c, .value = 0x10, },
0329 [25] = { .offset = 0x8d, .value = 0x02, },
0330
0331 [26] = { .offset = 0x90, .value = 0xff, },
0332 [27] = { .offset = 0x91, .value = 0x07, },
0333 [28] = { .offset = 0x92, .value = 0xa0, },
0334 [29] = { .offset = 0x93, .value = 0x02, },
0335 [30] = { .offset = 0x94, .value = 0x00, },
0336 [31] = { .offset = 0x95, .value = 0x00, },
0337 [32] = { .offset = 0x96, .value = 0x05, },
0338 [33] = { .offset = 0x97, .value = 0x00, },
0339
0340 [34] = { .offset = 0x9a, .value = 0x88, },
0341 [35] = { .offset = 0x9b, .value = 0x00, },
0342
0343 [36] = { .offset = 0x9e, .value = 0x25, },
0344 [37] = { .offset = 0x9f, .value = 0x03, },
0345 [38] = { .offset = 0xa0, .value = 0x28, },
0346 [39] = { .offset = 0xa1, .value = 0x01, },
0347 [40] = { .offset = 0xa2, .value = 0x28, },
0348 [41] = { .offset = 0xa3, .value = 0x05, },
0349
0350 [42] = { .offset = 0xa4, .value = 0x84, },
0351 [43] = { .offset = 0xa5, .value = 0x00, },
0352 [44] = { .offset = 0xa6, .value = 0x00, },
0353 [45] = { .offset = 0xa7, .value = 0x00, },
0354 [46] = { .offset = 0xa8, .value = 0x00, },
0355
0356 [47] = { .offset = 0xa9, .value = 0x04, },
0357 [48] = { .offset = 0xaa, .value = 0x70, },
0358 [49] = { .offset = 0xab, .value = 0x4f, },
0359 [50] = { .offset = 0xac, .value = 0x00, },
0360 [51] = { .offset = 0xad, .value = 0x00, },
0361 [52] = { .offset = 0xb6, .value = 0x09, },
0362 [53] = { .offset = 0xb7, .value = 0x03, },
0363
0364 [54] = { .offset = 0xba, .value = 0x00, },
0365 [55] = { .offset = 0xbb, .value = 0x20, },
0366 [56] = { .offset = 0xf3, .value = 0x90, },
0367 [57] = { .offset = 0xf4, .value = 0x00, },
0368 [58] = { .offset = 0xf7, .value = 0x88, },
0369
0370 [59] = { .offset = 0xf8, .value = 0x0a, },
0371 [60] = { .offset = 0xf9, .value = 0x00, }
0372 };
0373
0374 static const struct ns2501_reg regs_init[] = {
0375 [0] = { .offset = 0x35, .value = 0xff, },
0376 [1] = { .offset = 0x34, .value = 0x00, },
0377 [2] = { .offset = 0x08, .value = 0x30, },
0378 };
0379
0380 struct ns2501_priv {
0381 bool quiet;
0382 const struct ns2501_configuration *conf;
0383 };
0384
0385 #define NSPTR(d) ((NS2501Ptr)(d->DriverPrivate.ptr))
0386
0387
0388
0389
0390
0391
0392
0393 static bool ns2501_readb(struct intel_dvo_device *dvo, int addr, u8 *ch)
0394 {
0395 struct ns2501_priv *ns = dvo->dev_priv;
0396 struct i2c_adapter *adapter = dvo->i2c_bus;
0397 u8 out_buf[2];
0398 u8 in_buf[2];
0399
0400 struct i2c_msg msgs[] = {
0401 {
0402 .addr = dvo->slave_addr,
0403 .flags = 0,
0404 .len = 1,
0405 .buf = out_buf,
0406 },
0407 {
0408 .addr = dvo->slave_addr,
0409 .flags = I2C_M_RD,
0410 .len = 1,
0411 .buf = in_buf,
0412 }
0413 };
0414
0415 out_buf[0] = addr;
0416 out_buf[1] = 0;
0417
0418 if (i2c_transfer(adapter, msgs, 2) == 2) {
0419 *ch = in_buf[0];
0420 return true;
0421 }
0422
0423 if (!ns->quiet) {
0424 DRM_DEBUG_KMS
0425 ("Unable to read register 0x%02x from %s:0x%02x.\n", addr,
0426 adapter->name, dvo->slave_addr);
0427 }
0428
0429 return false;
0430 }
0431
0432
0433
0434
0435
0436
0437
0438 static bool ns2501_writeb(struct intel_dvo_device *dvo, int addr, u8 ch)
0439 {
0440 struct ns2501_priv *ns = dvo->dev_priv;
0441 struct i2c_adapter *adapter = dvo->i2c_bus;
0442 u8 out_buf[2];
0443
0444 struct i2c_msg msg = {
0445 .addr = dvo->slave_addr,
0446 .flags = 0,
0447 .len = 2,
0448 .buf = out_buf,
0449 };
0450
0451 out_buf[0] = addr;
0452 out_buf[1] = ch;
0453
0454 if (i2c_transfer(adapter, &msg, 1) == 1) {
0455 return true;
0456 }
0457
0458 if (!ns->quiet) {
0459 DRM_DEBUG_KMS("Unable to write register 0x%02x to %s:%d\n",
0460 addr, adapter->name, dvo->slave_addr);
0461 }
0462
0463 return false;
0464 }
0465
0466
0467
0468
0469
0470
0471
0472 static bool ns2501_init(struct intel_dvo_device *dvo,
0473 struct i2c_adapter *adapter)
0474 {
0475
0476 struct ns2501_priv *ns;
0477 unsigned char ch;
0478
0479 ns = kzalloc(sizeof(struct ns2501_priv), GFP_KERNEL);
0480 if (ns == NULL)
0481 return false;
0482
0483 dvo->i2c_bus = adapter;
0484 dvo->dev_priv = ns;
0485 ns->quiet = true;
0486
0487 if (!ns2501_readb(dvo, NS2501_VID_LO, &ch))
0488 goto out;
0489
0490 if (ch != (NS2501_VID & 0xff)) {
0491 DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
0492 ch, adapter->name, dvo->slave_addr);
0493 goto out;
0494 }
0495
0496 if (!ns2501_readb(dvo, NS2501_DID_LO, &ch))
0497 goto out;
0498
0499 if (ch != (NS2501_DID & 0xff)) {
0500 DRM_DEBUG_KMS("ns2501 not detected got %d: from %s Slave %d.\n",
0501 ch, adapter->name, dvo->slave_addr);
0502 goto out;
0503 }
0504 ns->quiet = false;
0505
0506 DRM_DEBUG_KMS("init ns2501 dvo controller successfully!\n");
0507
0508 return true;
0509
0510 out:
0511 kfree(ns);
0512 return false;
0513 }
0514
0515 static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo)
0516 {
0517
0518
0519
0520
0521
0522
0523
0524 return connector_status_connected;
0525 }
0526
0527 static enum drm_mode_status ns2501_mode_valid(struct intel_dvo_device *dvo,
0528 struct drm_display_mode *mode)
0529 {
0530 DRM_DEBUG_KMS
0531 ("is mode valid (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d)\n",
0532 mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);
0533
0534
0535
0536
0537
0538
0539
0540 if ((mode->hdisplay == 640 && mode->vdisplay == 480 && mode->clock == 25175) ||
0541 (mode->hdisplay == 800 && mode->vdisplay == 600 && mode->clock == 40000) ||
0542 (mode->hdisplay == 1024 && mode->vdisplay == 768 && mode->clock == 65000)) {
0543 return MODE_OK;
0544 } else {
0545 return MODE_ONE_SIZE;
0546 }
0547 }
0548
0549 static void ns2501_mode_set(struct intel_dvo_device *dvo,
0550 const struct drm_display_mode *mode,
0551 const struct drm_display_mode *adjusted_mode)
0552 {
0553 const struct ns2501_configuration *conf;
0554 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
0555 int mode_idx, i;
0556
0557 DRM_DEBUG_KMS
0558 ("set mode (hdisplay=%d,htotal=%d,vdisplay=%d,vtotal=%d).\n",
0559 mode->hdisplay, mode->htotal, mode->vdisplay, mode->vtotal);
0560
0561 DRM_DEBUG_KMS("Detailed requested mode settings are:\n"
0562 "clock : %d kHz\n"
0563 "hdisplay : %d\n"
0564 "hblank start : %d\n"
0565 "hblank end : %d\n"
0566 "hsync start : %d\n"
0567 "hsync end : %d\n"
0568 "htotal : %d\n"
0569 "hskew : %d\n"
0570 "vdisplay : %d\n"
0571 "vblank start : %d\n"
0572 "hblank end : %d\n"
0573 "vsync start : %d\n"
0574 "vsync end : %d\n"
0575 "vtotal : %d\n",
0576 adjusted_mode->crtc_clock,
0577 adjusted_mode->crtc_hdisplay,
0578 adjusted_mode->crtc_hblank_start,
0579 adjusted_mode->crtc_hblank_end,
0580 adjusted_mode->crtc_hsync_start,
0581 adjusted_mode->crtc_hsync_end,
0582 adjusted_mode->crtc_htotal,
0583 adjusted_mode->crtc_hskew,
0584 adjusted_mode->crtc_vdisplay,
0585 adjusted_mode->crtc_vblank_start,
0586 adjusted_mode->crtc_vblank_end,
0587 adjusted_mode->crtc_vsync_start,
0588 adjusted_mode->crtc_vsync_end,
0589 adjusted_mode->crtc_vtotal);
0590
0591 if (mode->hdisplay == 640 && mode->vdisplay == 480)
0592 mode_idx = MODE_640x480;
0593 else if (mode->hdisplay == 800 && mode->vdisplay == 600)
0594 mode_idx = MODE_800x600;
0595 else if (mode->hdisplay == 1024 && mode->vdisplay == 768)
0596 mode_idx = MODE_1024x768;
0597 else
0598 return;
0599
0600
0601 for (i = 0; i < ARRAY_SIZE(regs_init); i++)
0602 ns2501_writeb(dvo, regs_init[i].offset, regs_init[i].value);
0603
0604
0605 for (i = 0; i < ARRAY_SIZE(mode_agnostic_values); i++)
0606 ns2501_writeb(dvo, mode_agnostic_values[i].offset,
0607 mode_agnostic_values[i].value);
0608
0609
0610 conf = ns2501_modes + mode_idx;
0611 ns->conf = conf;
0612
0613 ns2501_writeb(dvo, NS2501_REG8, conf->conf);
0614 ns2501_writeb(dvo, NS2501_REG1B, conf->pll_a);
0615 ns2501_writeb(dvo, NS2501_REG1C, conf->pll_b & 0xff);
0616 ns2501_writeb(dvo, NS2501_REG1D, conf->pll_b >> 8);
0617 ns2501_writeb(dvo, NS2501_REGC1, conf->hstart & 0xff);
0618 ns2501_writeb(dvo, NS2501_REGC2, conf->hstart >> 8);
0619 ns2501_writeb(dvo, NS2501_REGC3, conf->hstop & 0xff);
0620 ns2501_writeb(dvo, NS2501_REGC4, conf->hstop >> 8);
0621 ns2501_writeb(dvo, NS2501_REGC5, conf->vstart & 0xff);
0622 ns2501_writeb(dvo, NS2501_REGC6, conf->vstart >> 8);
0623 ns2501_writeb(dvo, NS2501_REGC7, conf->vstop & 0xff);
0624 ns2501_writeb(dvo, NS2501_REGC8, conf->vstop >> 8);
0625 ns2501_writeb(dvo, NS2501_REG80, conf->vsync & 0xff);
0626 ns2501_writeb(dvo, NS2501_REG81, conf->vsync >> 8);
0627 ns2501_writeb(dvo, NS2501_REG82, conf->vtotal & 0xff);
0628 ns2501_writeb(dvo, NS2501_REG83, conf->vtotal >> 8);
0629 ns2501_writeb(dvo, NS2501_REG98, conf->hpos & 0xff);
0630 ns2501_writeb(dvo, NS2501_REG99, conf->hpos >> 8);
0631 ns2501_writeb(dvo, NS2501_REG8E, conf->vpos & 0xff);
0632 ns2501_writeb(dvo, NS2501_REG8F, conf->vpos >> 8);
0633 ns2501_writeb(dvo, NS2501_REG9C, conf->voffs & 0xff);
0634 ns2501_writeb(dvo, NS2501_REG9D, conf->voffs >> 8);
0635 ns2501_writeb(dvo, NS2501_REGB8, conf->hscale & 0xff);
0636 ns2501_writeb(dvo, NS2501_REGB9, conf->hscale >> 8);
0637 ns2501_writeb(dvo, NS2501_REG10, conf->vscale & 0xff);
0638 ns2501_writeb(dvo, NS2501_REG11, conf->vscale >> 8);
0639 ns2501_writeb(dvo, NS2501_REGF9, conf->dither);
0640 ns2501_writeb(dvo, NS2501_REG41, conf->syncb);
0641 ns2501_writeb(dvo, NS2501_REGC0, conf->sync);
0642 }
0643
0644
0645 static bool ns2501_get_hw_state(struct intel_dvo_device *dvo)
0646 {
0647 unsigned char ch;
0648
0649 if (!ns2501_readb(dvo, NS2501_REG8, &ch))
0650 return false;
0651
0652 return ch & NS2501_8_PD;
0653 }
0654
0655
0656 static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable)
0657 {
0658 struct ns2501_priv *ns = (struct ns2501_priv *)(dvo->dev_priv);
0659
0660 DRM_DEBUG_KMS("Trying set the dpms of the DVO to %i\n", enable);
0661
0662 if (enable) {
0663 ns2501_writeb(dvo, NS2501_REGC0, ns->conf->sync | 0x08);
0664
0665 ns2501_writeb(dvo, NS2501_REG41, ns->conf->syncb);
0666
0667 ns2501_writeb(dvo, NS2501_REG34, NS2501_34_ENABLE_OUTPUT);
0668 msleep(15);
0669
0670 ns2501_writeb(dvo, NS2501_REG8,
0671 ns->conf->conf | NS2501_8_BPAS);
0672 if (!(ns->conf->conf & NS2501_8_BPAS))
0673 ns2501_writeb(dvo, NS2501_REG8, ns->conf->conf);
0674 msleep(200);
0675
0676 ns2501_writeb(dvo, NS2501_REG34,
0677 NS2501_34_ENABLE_OUTPUT | NS2501_34_ENABLE_BACKLIGHT);
0678
0679 ns2501_writeb(dvo, NS2501_REGC0, ns->conf->sync);
0680 } else {
0681 ns2501_writeb(dvo, NS2501_REG34, NS2501_34_ENABLE_OUTPUT);
0682 msleep(200);
0683
0684 ns2501_writeb(dvo, NS2501_REG8, NS2501_8_VEN | NS2501_8_HEN |
0685 NS2501_8_BPAS);
0686 msleep(15);
0687
0688 ns2501_writeb(dvo, NS2501_REG34, 0x00);
0689 }
0690 }
0691
0692 static void ns2501_destroy(struct intel_dvo_device *dvo)
0693 {
0694 struct ns2501_priv *ns = dvo->dev_priv;
0695
0696 if (ns) {
0697 kfree(ns);
0698 dvo->dev_priv = NULL;
0699 }
0700 }
0701
0702 const struct intel_dvo_dev_ops ns2501_ops = {
0703 .init = ns2501_init,
0704 .detect = ns2501_detect,
0705 .mode_valid = ns2501_mode_valid,
0706 .mode_set = ns2501_mode_set,
0707 .dpms = ns2501_dpms,
0708 .get_hw_state = ns2501_get_hw_state,
0709 .destroy = ns2501_destroy,
0710 };