1 /* $NetBSD: cxdtv.c,v 1.9 2011/09/26 18:07:37 jakllsch Exp $ */ 2 3 /* 4 * Copyright (c) 2008, 2011 Jonathan A. Kollasch 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: cxdtv.c,v 1.9 2011/09/26 18:07:37 jakllsch Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/kernel.h> 34 #include <sys/device.h> 35 #include <sys/kmem.h> 36 #include <sys/mutex.h> 37 #include <sys/proc.h> 38 #include <sys/module.h> 39 #include <sys/bus.h> 40 41 #include <dev/pci/pcivar.h> 42 #include <dev/pci/pcireg.h> 43 #include <dev/pci/pcidevs.h> 44 #include <dev/i2c/i2cvar.h> 45 #include <dev/i2c/i2c_bitbang.h> 46 47 #include <dev/i2c/tvpllvar.h> 48 #include <dev/i2c/tvpll_tuners.h> 49 50 #include <dev/i2c/nxt2kvar.h> 51 #include <dev/i2c/lg3303var.h> 52 53 #include <dev/dtv/dtvif.h> 54 55 #include <dev/pci/cxdtvreg.h> 56 #include <dev/pci/cxdtvvar.h> 57 #include <dev/pci/cxdtv_boards.h> 58 59 #define CXDTV_MMBASE 0x10 60 61 #define CXDTV_SRAM_CH_MPEG 0 62 #define CXDTV_TS_PKTSIZE (188 * 8) 63 64 static int cxdtv_match(struct device *, struct cfdata *, void *); 65 static void cxdtv_attach(struct device *, struct device *, void *); 66 static int cxdtv_detach(struct device *, int); 67 static int cxdtv_rescan(struct device *, const char *, const int *); 68 static void cxdtv_childdet(struct device *, struct device *); 69 static int cxdtv_intr(void *); 70 71 static bool cxdtv_resume(device_t, const pmf_qual_t *); 72 73 static int cxdtv_iic_acquire_bus(void *, int); 74 static void cxdtv_iic_release_bus(void *, int); 75 static int cxdtv_iic_send_start(void *, int); 76 static int cxdtv_iic_send_stop(void *, int); 77 static int cxdtv_iic_initiate_xfer(void *, i2c_addr_t, int); 78 static int cxdtv_iic_read_byte(void *, uint8_t *, int); 79 static int cxdtv_iic_write_byte(void *, uint8_t, int); 80 81 static void cxdtv_i2cbb_set_bits(void *, uint32_t); 82 static void cxdtv_i2cbb_set_dir(void *, uint32_t); 83 static uint32_t cxdtv_i2cbb_read_bits(void *); 84 85 static int cxdtv_sram_ch_setup(struct cxdtv_softc *, 86 struct cxdtv_sram_ch *, uint32_t); 87 static int cxdtv_allocmem(struct cxdtv_softc *, size_t, size_t, 88 struct cxdtv_dma *); 89 static int cxdtv_freemem(struct cxdtv_softc *, struct cxdtv_dma *); 90 static int cxdtv_risc_buffer(struct cxdtv_softc *, uint32_t, uint32_t); 91 static int cxdtv_risc_field(struct cxdtv_softc *, uint32_t *, uint32_t); 92 93 static int cxdtv_mpeg_attach(struct cxdtv_softc *); 94 static int cxdtv_mpeg_detach(struct cxdtv_softc *, int flags); 95 static int cxdtv_mpeg_intr(struct cxdtv_softc *); 96 static int cxdtv_mpeg_reset(struct cxdtv_softc *); 97 98 static int cxdtv_mpeg_trigger(struct cxdtv_softc *, void *); 99 static int cxdtv_mpeg_halt(struct cxdtv_softc *); 100 static void * cxdtv_mpeg_malloc(struct cxdtv_softc *, size_t); 101 static void cxdtv_mpeg_free(struct cxdtv_softc *, void *); 102 103 static void cxdtv_card_init_hd5500(struct cxdtv_softc *); 104 static void cxdtv_card_init_hdtvwonder(struct cxdtv_softc *); 105 106 /* MPEG TS Port */ 107 static void cxdtv_dtv_get_devinfo(void *, struct dvb_frontend_info *); 108 static int cxdtv_dtv_open(void *, int); 109 static void cxdtv_dtv_close(void *); 110 static int cxdtv_dtv_set_tuner(void *, const struct dvb_frontend_parameters *); 111 static fe_status_t cxdtv_dtv_get_status(void *); 112 static uint16_t cxdtv_dtv_get_signal_strength(void *); 113 static uint16_t cxdtv_dtv_get_snr(void *); 114 static int cxdtv_dtv_start_transfer(void *, 115 void (*)(void *, const struct dtv_payload *), void *); 116 static int cxdtv_dtv_stop_transfer(void *); 117 118 static const struct dtv_hw_if cxdtv_dtv_if = { 119 .get_devinfo = cxdtv_dtv_get_devinfo, 120 .open = cxdtv_dtv_open, 121 .close = cxdtv_dtv_close, 122 .set_tuner = cxdtv_dtv_set_tuner, 123 .get_status = cxdtv_dtv_get_status, 124 .get_signal_strength = cxdtv_dtv_get_signal_strength, 125 .get_snr = cxdtv_dtv_get_snr, 126 .start_transfer = cxdtv_dtv_start_transfer, 127 .stop_transfer = cxdtv_dtv_stop_transfer, 128 }; 129 130 const struct i2c_bitbang_ops cxdtv_i2cbb_ops = { 131 cxdtv_i2cbb_set_bits, 132 cxdtv_i2cbb_set_dir, 133 cxdtv_i2cbb_read_bits, 134 { CXDTV_I2C_C_DATACONTROL_SDA, CXDTV_I2C_C_DATACONTROL_SCL, 0, 0 } 135 }; 136 137 /* Maybe make this dynamically allocated. */ 138 static struct cxdtv_sram_ch cxdtv_sram_chs[] = { 139 [CXDTV_SRAM_CH_MPEG] = { 140 .csc_cmds = 0x180200, /* CMDS for ch. 28 */ 141 .csc_iq = 0x180340, /* after last CMDS */ 142 .csc_iqsz = 0x40, /* 16 dwords */ 143 .csc_cdt = 0x180380, /* after iq */ 144 .csc_cdtsz = 0x40, /* cluster discriptor space */ 145 .csc_fifo = 0x180400, /* after cdt */ 146 .csc_fifosz = 0x001C00, /* let's just align this up */ 147 .csc_risc = 0x182000, /* after fifo */ 148 .csc_riscsz = 0x6000, /* room for dma programs */ 149 .csc_ptr1 = CXDTV_DMA28_PTR1, 150 .csc_ptr2 = CXDTV_DMA28_PTR2, 151 .csc_cnt1 = CXDTV_DMA28_CNT1, 152 .csc_cnt2 = CXDTV_DMA28_CNT2, 153 }, 154 }; 155 156 CFATTACH_DECL2_NEW(cxdtv, sizeof(struct cxdtv_softc), 157 cxdtv_match, cxdtv_attach, cxdtv_detach, NULL, 158 cxdtv_rescan, cxdtv_childdet); 159 160 static int 161 cxdtv_match(device_t parent, cfdata_t match, void *aux) 162 { 163 const struct pci_attach_args *pa; 164 165 pa = aux; 166 167 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_CONEXANT) 168 return 0; 169 170 switch (PCI_PRODUCT(pa->pa_id)) { 171 case PCI_PRODUCT_CONEXANT_CX2388XMPEG: 172 return 1; 173 } 174 175 /* XXX only match supported boards */ 176 177 return 0; 178 } 179 180 static void 181 cxdtv_attach(device_t parent, device_t self, void *aux) 182 { 183 struct cxdtv_softc *sc; 184 const struct pci_attach_args *pa = aux; 185 pci_intr_handle_t ih; 186 pcireg_t reg; 187 const char *intrstr; 188 char devinfo[76]; 189 struct i2cbus_attach_args iba; 190 191 sc = device_private(self); 192 193 sc->sc_dev = self; 194 sc->sc_pc = pa->pa_pc; 195 196 aprint_naive("\n"); 197 198 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); 199 200 sc->sc_vendor = PCI_VENDOR(reg); 201 sc->sc_product = PCI_PRODUCT(reg); 202 203 sc->sc_board = cxdtv_board_lookup(sc->sc_vendor, sc->sc_product); 204 205 if (sc->sc_board == NULL) { 206 aprint_error_dev(self ,"unsupported device 0x%08x\n", reg); 207 return; 208 } 209 210 pci_devinfo(reg, pa->pa_class, 0, devinfo, sizeof(devinfo)); 211 aprint_normal(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); 212 213 if (pci_mapreg_map(pa, CXDTV_MMBASE, PCI_MAPREG_TYPE_MEM, 0, 214 &sc->sc_memt, &sc->sc_memh, NULL, &sc->sc_mems)) { 215 aprint_error_dev(self, "couldn't map memory space\n"); 216 return; 217 } 218 219 sc->sc_dmat = pa->pa_dmat; 220 221 if (pci_intr_map(pa, &ih)) { 222 aprint_error_dev(self, "couldn't map interrupt\n"); 223 return; 224 } 225 intrstr = pci_intr_string(pa->pa_pc, ih); 226 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_VM, cxdtv_intr, sc); 227 if (sc->sc_ih == NULL) { 228 aprint_error_dev(self, "couldn't establish interrupt"); 229 if (intrstr != NULL) 230 aprint_error(" at %s", intrstr); 231 aprint_error("\n"); 232 return; 233 } 234 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 235 236 /* set master */ 237 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 238 reg |= PCI_COMMAND_MASTER_ENABLE; 239 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg); 240 241 mutex_init(&sc->sc_i2c_buslock, MUTEX_DRIVER, IPL_NONE); 242 sc->sc_i2c.ic_cookie = sc; 243 sc->sc_i2c.ic_exec = NULL; 244 sc->sc_i2c.ic_acquire_bus = cxdtv_iic_acquire_bus; 245 sc->sc_i2c.ic_release_bus = cxdtv_iic_release_bus; 246 sc->sc_i2c.ic_send_start = cxdtv_iic_send_start; 247 sc->sc_i2c.ic_send_stop = cxdtv_iic_send_stop; 248 sc->sc_i2c.ic_initiate_xfer = cxdtv_iic_initiate_xfer; 249 sc->sc_i2c.ic_read_byte = cxdtv_iic_read_byte; 250 sc->sc_i2c.ic_write_byte = cxdtv_iic_write_byte; 251 252 #if notyet 253 /* enable i2c compatible software mode */ 254 val = bus_space_read_4(sc->sc_memt, sc->sc_memh, 255 CXDTV_I2C_C_DATACONTROL); 256 val = CXDTV_I2C_C_DATACONTROL_SCL | CXDTV_I2C_C_DATACONTROL_SDA; 257 bus_space_write_4(sc->sc_memt, sc->sc_memh, 258 CXDTV_I2C_C_DATACONTROL, val); 259 #endif 260 261 cxdtv_mpeg_attach(sc); 262 263 /* attach other devices to iic(4) */ 264 memset(&iba, 0, sizeof(iba)); 265 iba.iba_tag = &sc->sc_i2c; 266 config_found_ia(self, "i2cbus", &iba, iicbus_print); 267 268 if (!pmf_device_register(self, NULL, cxdtv_resume)) 269 aprint_error_dev(self, "couldn't establish power handler\n"); 270 271 return; 272 } 273 274 static int 275 cxdtv_detach(device_t self, int flags) 276 { 277 struct cxdtv_softc *sc = device_private(self); 278 int error; 279 280 error = cxdtv_mpeg_detach(sc, flags); 281 if (error) 282 return error; 283 284 if (sc->sc_ih) 285 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 286 287 if (sc->sc_mems) 288 bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems); 289 290 mutex_destroy(&sc->sc_i2c_buslock); 291 292 return 0; 293 } 294 295 static int 296 cxdtv_rescan(device_t self, const char *ifattr, const int *locs) 297 { 298 struct cxdtv_softc *sc = device_private(self); 299 struct dtv_attach_args daa; 300 301 daa.hw = &cxdtv_dtv_if; 302 daa.priv = sc; 303 304 if (ifattr_match(ifattr, "dtvbus") && sc->sc_dtvdev == NULL) 305 sc->sc_dtvdev = config_found_ia(sc->sc_dev, "dtvbus", 306 &daa, dtv_print); 307 308 return 0; 309 } 310 311 static void 312 cxdtv_childdet(device_t self, device_t child) 313 { 314 struct cxdtv_softc *sc = device_private(self); 315 316 if (child == sc->sc_dtvdev) 317 sc->sc_dtvdev = NULL; 318 } 319 320 static bool 321 cxdtv_resume(device_t dv, const pmf_qual_t *qual) 322 { 323 struct cxdtv_softc *sc; 324 sc = device_private(dv); 325 326 /* XXX revisit */ 327 328 aprint_debug_dev(dv, "%s\n", __func__); 329 330 return true; 331 } 332 333 static int 334 cxdtv_intr(void *intarg) 335 { 336 struct cxdtv_softc *sc = intarg; 337 uint32_t val; 338 339 val = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MSTAT); 340 if (val == 0) { 341 return 0; /* not ours */ 342 } 343 344 if (val & CXT_PI_TS_INT) { 345 cxdtv_mpeg_intr(sc); 346 } 347 348 if (val & ~CXT_PI_TS_INT) { 349 device_printf(sc->sc_dev, "%s, %08x\n", __func__, val); 350 } 351 352 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_STAT, val); 353 354 return 1; 355 } 356 357 /* I2C interface */ 358 359 static void 360 cxdtv_i2cbb_set_bits(void *cookie, uint32_t bits) 361 { 362 struct cxdtv_softc *sc = cookie; 363 uint32_t value; 364 365 bus_space_write_4(sc->sc_memt, sc->sc_memh, 366 CXDTV_I2C_C_DATACONTROL, bits); 367 value = bus_space_read_4(sc->sc_memt, sc->sc_memh, 368 CXDTV_I2C_C_DATACONTROL); 369 370 return; 371 } 372 373 static void 374 cxdtv_i2cbb_set_dir(void *cookie, uint32_t bits) 375 { 376 return; 377 } 378 379 static uint32_t 380 cxdtv_i2cbb_read_bits(void *cookie) 381 { 382 struct cxdtv_softc *sc = cookie; 383 uint32_t value; 384 385 value = bus_space_read_4(sc->sc_memt, sc->sc_memh, 386 CXDTV_I2C_C_DATACONTROL); 387 388 return value; 389 } 390 391 static int 392 cxdtv_iic_acquire_bus(void *cookie, int flags) 393 { 394 struct cxdtv_softc *sc = cookie; 395 396 mutex_enter(&sc->sc_i2c_buslock); 397 398 return 0; 399 } 400 401 static void 402 cxdtv_iic_release_bus(void *cookie, int flags) 403 { 404 struct cxdtv_softc *sc = cookie; 405 406 mutex_exit(&sc->sc_i2c_buslock); 407 408 return; 409 } 410 411 static int 412 cxdtv_iic_send_start(void *cookie, int flags) 413 { 414 return i2c_bitbang_send_start(cookie, flags, &cxdtv_i2cbb_ops); 415 } 416 417 static int 418 cxdtv_iic_send_stop(void *cookie, int flags) 419 { 420 return i2c_bitbang_send_stop(cookie, flags, &cxdtv_i2cbb_ops); 421 } 422 423 static int 424 cxdtv_iic_initiate_xfer(void *cookie, i2c_addr_t addr, int flags) 425 { 426 return i2c_bitbang_initiate_xfer(cookie, addr, flags, &cxdtv_i2cbb_ops); 427 } 428 429 static int 430 cxdtv_iic_read_byte(void *cookie, uint8_t *data, int flags) 431 { 432 return i2c_bitbang_read_byte(cookie, data, flags, &cxdtv_i2cbb_ops); 433 } 434 435 static int 436 cxdtv_iic_write_byte(void *cookie, uint8_t data, int flags) 437 { 438 return i2c_bitbang_write_byte(cookie, data, flags, &cxdtv_i2cbb_ops); 439 } 440 441 int 442 cxdtv_mpeg_attach(struct cxdtv_softc *sc) 443 { 444 struct cxdtv_sram_ch *ch; 445 446 CX_DPRINTF(("cxdtv_mpeg_attach\n")); 447 448 ch = &cxdtv_sram_chs[CXDTV_SRAM_CH_MPEG]; 449 450 sc->sc_riscbufsz = ch->csc_riscsz; 451 sc->sc_riscbuf = kmem_alloc(ch->csc_riscsz, KM_SLEEP); 452 453 if ( sc->sc_riscbuf == NULL ) 454 panic("riscbuf null"); 455 456 aprint_debug_dev(sc->sc_dev, "attaching frontend...\n"); 457 458 switch(sc->sc_vendor) { 459 case PCI_VENDOR_ATI: 460 cxdtv_card_init_hdtvwonder(sc); 461 break; 462 case PCI_VENDOR_PCHDTV: 463 if (sc->sc_product == PCI_PRODUCT_PCHDTV_HD5500) { 464 cxdtv_card_init_hd5500(sc); 465 } 466 break; 467 } 468 469 KASSERT(sc->sc_tuner == NULL); 470 KASSERT(sc->sc_demod == NULL); 471 472 switch(sc->sc_board->cb_demod) { 473 case CXDTV_DEMOD_NXT2004: 474 sc->sc_demod = nxt2k_open(sc->sc_dev, &sc->sc_i2c, 0x0a, 0); 475 break; 476 case CXDTV_DEMOD_LG3303: 477 sc->sc_demod = lg3303_open(sc->sc_dev, &sc->sc_i2c, 0x59, 478 LG3303_CFG_SERIAL_INPUT); 479 break; 480 default: 481 break; 482 } 483 484 switch(sc->sc_board->cb_tuner) { 485 case CXDTV_TUNER_PLL: 486 if (sc->sc_vendor == PCI_VENDOR_ATI) 487 sc->sc_tuner = tvpll_open(sc->sc_dev, &sc->sc_i2c, 0x61, &tvpll_tuv1236d_pll); 488 if (sc->sc_vendor == PCI_VENDOR_PCHDTV) 489 sc->sc_tuner = tvpll_open(sc->sc_dev, &sc->sc_i2c, 0x61, &tvpll_tdvs_h06xf_pll); 490 break; 491 default: 492 break; 493 } 494 495 KASSERT(sc->sc_tuner != NULL); 496 KASSERT(sc->sc_demod != NULL); 497 498 cxdtv_rescan(sc->sc_dev, NULL, NULL); 499 500 return (sc->sc_dtvdev != NULL); 501 } 502 503 int 504 cxdtv_mpeg_detach(struct cxdtv_softc *sc, int flags) 505 { 506 int error = 0; 507 508 if (sc->sc_dtvdev) { 509 error = config_detach(sc->sc_dtvdev, flags); 510 if (error) 511 return error; 512 } 513 514 if (sc->sc_demod) { 515 switch (sc->sc_board->cb_demod) { 516 case CXDTV_DEMOD_NXT2004: 517 nxt2k_close(sc->sc_demod); 518 break; 519 case CXDTV_DEMOD_LG3303: 520 lg3303_close(sc->sc_demod); 521 break; 522 default: 523 break; 524 } 525 sc->sc_demod = NULL; 526 } 527 if (sc->sc_tuner) { 528 switch (sc->sc_board->cb_tuner) { 529 case CXDTV_TUNER_PLL: 530 tvpll_close(sc->sc_tuner); 531 break; 532 default: 533 break; 534 } 535 sc->sc_tuner = NULL; 536 } 537 538 if (sc->sc_riscbuf) { 539 kmem_free(sc->sc_riscbuf, sc->sc_riscbufsz); 540 sc->sc_riscbuf = NULL; 541 sc->sc_riscbufsz = 0; 542 } 543 544 return error; 545 } 546 547 static void 548 cxdtv_dtv_get_devinfo(void *priv, struct dvb_frontend_info *info) 549 { 550 memset(info, 0, sizeof(*info)); 551 strlcpy(info->name, "CX23880", sizeof(info->name)); 552 info->type = FE_ATSC; 553 info->frequency_min = 54000000; 554 info->frequency_max = 858000000; 555 info->frequency_stepsize = 62500; 556 info->caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB; 557 } 558 559 static int 560 cxdtv_dtv_open(void *priv, int flags) 561 { 562 struct cxdtv_softc *sc = priv; 563 564 KASSERT(sc->sc_tsbuf == NULL); 565 566 cxdtv_mpeg_reset(sc); 567 568 /* allocate two alternating DMA areas for MPEG TS packets */ 569 sc->sc_tsbuf = cxdtv_mpeg_malloc(sc, CXDTV_TS_PKTSIZE * 2); 570 571 if (sc->sc_tsbuf == NULL) 572 return ENOMEM; 573 574 return 0; 575 } 576 577 static void 578 cxdtv_dtv_close(void *priv) 579 { 580 struct cxdtv_softc *sc = priv; 581 582 cxdtv_dtv_stop_transfer(sc); 583 584 if (sc->sc_tsbuf != NULL) { 585 cxdtv_mpeg_free(sc, sc->sc_tsbuf); 586 sc->sc_tsbuf = NULL; 587 } 588 } 589 590 static int 591 cxdtv_dtv_set_tuner(void *priv, const struct dvb_frontend_parameters *params) 592 { 593 struct cxdtv_softc *sc = priv; 594 int error = -1; 595 596 switch(sc->sc_board->cb_tuner) { 597 case CXDTV_TUNER_PLL: 598 error = tvpll_tune_dtv(sc->sc_tuner, params); 599 } 600 if (error) 601 goto bad; 602 603 switch(sc->sc_board->cb_demod) { 604 case CXDTV_DEMOD_NXT2004: 605 error = nxt2k_set_modulation(sc->sc_demod, params->u.vsb.modulation); 606 break; 607 case CXDTV_DEMOD_LG3303: 608 error = lg3303_set_modulation(sc->sc_demod, params->u.vsb.modulation); 609 break; 610 default: 611 break; 612 } 613 614 bad: 615 return error; 616 } 617 618 static fe_status_t 619 cxdtv_dtv_get_status(void *priv) 620 { 621 struct cxdtv_softc *sc = priv; 622 623 switch(sc->sc_board->cb_demod) { 624 case CXDTV_DEMOD_NXT2004: 625 return nxt2k_get_dtv_status(sc->sc_demod); 626 case CXDTV_DEMOD_LG3303: 627 return lg3303_get_dtv_status(sc->sc_demod); 628 default: 629 return 0; 630 } 631 } 632 633 static uint16_t 634 cxdtv_dtv_get_signal_strength(void *priv) 635 { 636 struct cxdtv_softc *sc = priv; 637 638 switch(sc->sc_board->cb_demod) { 639 case CXDTV_DEMOD_NXT2004: 640 return 0; /* TODO */ 641 case CXDTV_DEMOD_LG3303: 642 return lg3303_get_signal_strength(sc->sc_demod); 643 } 644 645 return 0; 646 } 647 648 static uint16_t 649 cxdtv_dtv_get_snr(void *priv) 650 { 651 struct cxdtv_softc *sc = priv; 652 653 switch(sc->sc_board->cb_demod) { 654 case CXDTV_DEMOD_NXT2004: 655 return 0; /* TODO */ 656 case CXDTV_DEMOD_LG3303: 657 return lg3303_get_snr(sc->sc_demod); 658 } 659 660 return 0; 661 } 662 663 static int 664 cxdtv_dtv_start_transfer(void *priv, 665 void (*cb)(void *, const struct dtv_payload *), void *arg) 666 { 667 struct cxdtv_softc *sc = priv; 668 669 sc->sc_dtvsubmitcb = cb; 670 sc->sc_dtvsubmitarg = arg; 671 672 /* allocate two alternating DMA areas for MPEG TS packets */ 673 sc->sc_tsbuf = cxdtv_mpeg_malloc(sc, CXDTV_TS_PKTSIZE * 2); 674 675 cxdtv_mpeg_trigger(sc, sc->sc_tsbuf); 676 677 return 0; 678 } 679 680 static int 681 cxdtv_dtv_stop_transfer(void *priv) 682 { 683 struct cxdtv_softc *sc = priv; 684 685 cxdtv_mpeg_halt(sc); 686 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MASK, 0); 687 688 sc->sc_dtvsubmitcb = NULL; 689 sc->sc_dtvsubmitarg = NULL; 690 691 return 0; 692 } 693 694 int 695 cxdtv_mpeg_reset(struct cxdtv_softc *sc) 696 { 697 struct cxdtv_sram_ch *ch; 698 uint32_t v; 699 700 CX_DPRINTF(("cxdtv_mpeg_reset\n")); 701 702 ch = &cxdtv_sram_chs[CXDTV_SRAM_CH_MPEG]; 703 v = (uint32_t)-1; 704 705 /* shutdown */ 706 /* hold RISC in reset */ 707 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_DEV_CNTRL2, 0); 708 /* disable FIFO and RISC */ 709 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_DMA_CNTRL, 0); 710 /* mask off all interrupts */ 711 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MASK, 0); 712 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_MASK, 0); 713 714 /* clear interrupts */ 715 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_STAT, v); 716 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_STAT, v); 717 718 memset(sc->sc_riscbuf, 0, sc->sc_riscbufsz); 719 720 /* XXX magic */ 721 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PDMA_STHRSH, 0x0707); 722 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PDMA_DTHRSH, 0x0707); 723 724 /* reset external components*/ 725 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_SRST_IO, 0); 726 kpause("cxdtvrst", false, MAX(1, mstohz(1)), NULL); 727 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_SRST_IO, 1); 728 729 /* let error interrupts happen */ 730 v = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MASK); 731 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MASK, 732 v | 0x00fc00); /* XXX magic */ 733 734 return 0; 735 } 736 737 static int 738 cxdtv_risc_buffer(struct cxdtv_softc *sc, uint32_t bpl, uint32_t lines) 739 { 740 uint32_t *rm; 741 uint32_t size; 742 743 CX_DPRINTF(("cxdtv_risc_buffer: bpl=0x%x\n", bpl)); 744 745 size = 1 + (bpl * lines) / PAGE_SIZE + lines; 746 size += 2; 747 748 device_printf(sc->sc_dev, "%s: est. inst. %d\n", __func__, size); 749 750 size *= 8; 751 device_printf(sc->sc_dev, "%s: est. qword %d\n", __func__, size); 752 753 if (sc->sc_riscbuf == NULL) { 754 device_printf(sc->sc_dev, "not enough memory for RISC\n"); 755 return ENOMEM; 756 } 757 758 rm = (uint32_t *)sc->sc_riscbuf; 759 cxdtv_risc_field(sc, rm, bpl); 760 761 return 0; 762 } 763 764 static int 765 cxdtv_risc_field(struct cxdtv_softc *sc, uint32_t *rm, uint32_t bpl) 766 { 767 struct cxdtv_dma *p; 768 769 CX_DPRINTF(("cxdtv_risc_field: bpl=0x%x\n", bpl)); 770 771 for (p = sc->sc_dma; p && KERNADDR(p) != sc->sc_tsbuf; p = p->next) 772 continue; 773 if (p == NULL) { 774 device_printf(sc->sc_dev, "cxdtv_risc_field: bad addr %p\n", 775 sc->sc_tsbuf); 776 return ENOENT; 777 } 778 779 memset(sc->sc_riscbuf, 0, sc->sc_riscbufsz); 780 781 rm = sc->sc_riscbuf; 782 783 /* htole32 will be done when program is copied to chip SRAM */ 784 785 /* XXX */ 786 *(rm++) = (CX_RISC_SYNC|0); 787 788 *(rm++) = (CX_RISC_WRITE|CX_RISC_SOL|CX_RISC_EOL|CX_RISC_IRQ1|bpl); 789 *(rm++) = (DMAADDR(p) + 0 * bpl); 790 791 *(rm++) = (CX_RISC_WRITE|CX_RISC_SOL|CX_RISC_EOL|CX_RISC_IRQ2|bpl); 792 *(rm++) = (DMAADDR(p) + 1 * bpl); 793 794 *(rm++) = (CX_RISC_JUMP|1); 795 *(rm++) = (cxdtv_sram_chs[CXDTV_SRAM_CH_MPEG].csc_risc + 4); 796 797 return 0; 798 } 799 800 static int 801 cxdtv_sram_ch_setup(struct cxdtv_softc *sc, struct cxdtv_sram_ch *csc, 802 uint32_t bpl) 803 { 804 unsigned int i, lines; 805 uint32_t cdt; 806 807 CX_DPRINTF(("cxdtv_sram_ch_setup: bpl=0x%x\n", bpl)); 808 809 /* XXX why round? */ 810 bpl = (bpl + 7) & ~7; 811 CX_DPRINTF(("cxdtv_sram_ch_setup: bpl=0x%x\n", bpl)); 812 cdt = csc->csc_cdt; 813 lines = csc->csc_fifosz / bpl; 814 device_printf(sc->sc_dev, "%s %d lines\n", __func__, lines); 815 816 /* fill in CDT */ 817 for (i = 0; i < lines; i++) { 818 CX_DPRINTF(("CDT ent %08x, %08x\n", cdt + (16 * i), 819 csc->csc_fifo + (bpl * i))); 820 bus_space_write_4(sc->sc_memt, sc->sc_memh, 821 cdt + (16 * i), 822 csc->csc_fifo + (bpl * i)); 823 } 824 825 /* copy DMA program */ 826 827 /* converts program to little endian as it goes into SRAM */ 828 bus_space_write_region_4(sc->sc_memt, sc->sc_memh, 829 csc->csc_risc, (void *)sc->sc_riscbuf, sc->sc_riscbufsz >> 2); 830 831 /* fill in CMDS */ 832 bus_space_write_4(sc->sc_memt, sc->sc_memh, 833 csc->csc_cmds + CX_CMDS_O_IRPC, csc->csc_risc); 834 835 bus_space_write_4(sc->sc_memt, sc->sc_memh, 836 csc->csc_cmds + CX_CMDS_O_CDTB, csc->csc_cdt); 837 bus_space_write_4(sc->sc_memt, sc->sc_memh, 838 csc->csc_cmds + CX_CMDS_O_CDTS, (lines * 16) >> 3); /* XXX magic */ 839 840 bus_space_write_4(sc->sc_memt, sc->sc_memh, 841 csc->csc_cmds + CX_CMDS_O_IQB, csc->csc_iq); 842 bus_space_write_4(sc->sc_memt, sc->sc_memh, 843 csc->csc_cmds + CX_CMDS_O_IQS, 844 CX_CMDS_IQS_ISRP | (csc->csc_iqsz >> 2) ); 845 846 /* zero rest of CMDS */ 847 bus_space_set_region_4(sc->sc_memt, sc->sc_memh, 0x14, 0, 0x2c/4); 848 849 bus_space_write_4(sc->sc_memt, sc->sc_memh, 850 csc->csc_cnt1, (bpl >> 3) - 1); 851 852 bus_space_write_4(sc->sc_memt, sc->sc_memh, 853 csc->csc_ptr2, cdt); 854 bus_space_write_4(sc->sc_memt, sc->sc_memh, 855 csc->csc_cnt2, (lines * 16) >> 3); 856 857 return 0; 858 } 859 860 int 861 cxdtv_mpeg_trigger(struct cxdtv_softc *sc, void *buf) 862 { 863 struct cxdtv_dma *p; 864 struct cxdtv_sram_ch *ch; 865 uint32_t v; 866 867 ch = &cxdtv_sram_chs[CXDTV_SRAM_CH_MPEG]; 868 869 for (p = sc->sc_dma; p && KERNADDR(p) != buf; p = p->next) 870 continue; 871 if (p == NULL) { 872 device_printf(sc->sc_dev, "cxdtv_mpeg_trigger: bad addr %p\n", 873 buf); 874 return ENOENT; 875 } 876 877 CX_DPRINTF(("cxdtv_mpeg_trigger: buf=%p\n", buf)); 878 879 cxdtv_risc_buffer(sc, CXDTV_TS_PKTSIZE, 1); 880 cxdtv_sram_ch_setup(sc, ch, CXDTV_TS_PKTSIZE); 881 882 /* software reset */ 883 884 switch(sc->sc_vendor) { 885 case PCI_VENDOR_ATI: 886 /* both ATI boards with DTV are the same */ 887 bus_space_write_4(sc->sc_memt, sc->sc_memh, 888 CXDTV_TS_GEN_CONTROL, IPB_SW_RST); 889 delay(100); 890 /* parallel MPEG port */ 891 bus_space_write_4(sc->sc_memt, sc->sc_memh, 892 CXDTV_PINMUX_IO, MPEG_PAR_EN); 893 break; 894 case PCI_VENDOR_PCHDTV: 895 if (sc->sc_product == PCI_PRODUCT_PCHDTV_HD5500) { 896 bus_space_write_4(sc->sc_memt, sc->sc_memh, 897 CXDTV_TS_GEN_CONTROL, IPB_SW_RST|IPB_SMODE); 898 delay(100); 899 bus_space_write_4(sc->sc_memt, sc->sc_memh, 900 CXDTV_PINMUX_IO, 0x00); /* serial MPEG port */ 901 /* byte-width start-of-packet */ 902 bus_space_write_4(sc->sc_memt, sc->sc_memh, 903 CXDTV_HW_SOP_CONTROL, 904 0x47 << 16 | 188 << 4 | 1); 905 bus_space_write_4(sc->sc_memt, sc->sc_memh, 906 CXDTV_TS_SOP_STATUS, IPB_SOP_BYTEWIDE); 907 /* serial MPEG port on HD5500 */ 908 bus_space_write_4(sc->sc_memt, sc->sc_memh, 909 CXDTV_TS_GEN_CONTROL, IPB_SMODE); 910 } 911 break; 912 default: 913 break; 914 } 915 916 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_LNGTH, 917 CXDTV_TS_PKTSIZE); 918 919 /* Configure for standard MPEG TS, 1 good packet to sync */ 920 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_HW_SOP_CONTROL, 921 0x47 << 16 | 188 << 4 | 1); 922 923 /* zero counter */ 924 bus_space_write_4(sc->sc_memt, sc->sc_memh, 925 CXDTV_TS_GP_CNT_CNTRL, 0x03); 926 927 /* enable bad packet interrupt */ 928 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_BD_PKT_STATUS, 929 0x1000); 930 931 /* enable overflow counter */ 932 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_FIFO_OVFL_STAT, 933 0x1000); 934 935 /* unmask TS interrupt */ 936 v = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MASK); 937 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MASK, 938 v | CXT_PI_TS_INT); 939 940 /* unmask all TS interrupts */ 941 v = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_MASK); 942 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_MASK, 943 v | 0x1f1011); 944 945 /* enable RISC DMA engine */ 946 v = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_DEV_CNTRL2); 947 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_DEV_CNTRL2, 948 v | CXDTV_DEV_CNTRL2_RUN_RISC); 949 950 v = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_DMA_CNTRL); 951 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_DMA_CNTRL, 952 v | CXDTV_TS_RISC_EN | CXDTV_TS_FIFO_EN); 953 954 return 0; 955 } 956 957 int 958 cxdtv_mpeg_halt(struct cxdtv_softc *sc) 959 { 960 uint32_t v; 961 962 CX_DPRINTF(("cxdtv_mpeg_halt\n")); 963 964 v = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_DMA_CNTRL); 965 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_DMA_CNTRL, 966 v & ~(CXDTV_TS_RISC_EN|CXDTV_TS_FIFO_EN)); 967 968 v = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MASK); 969 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_PCI_INT_MASK, 970 v & ~CXT_PI_TS_INT); 971 972 v = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_MASK); 973 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_MASK, 974 v & ~0x1f1011); 975 976 return 0; 977 } 978 979 int 980 cxdtv_mpeg_intr(struct cxdtv_softc *sc) 981 { 982 struct dtv_payload payload; 983 uint32_t s, m; 984 985 s = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_STAT); 986 m = bus_space_read_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_MASK); 987 if ((s & m) == 0) 988 return 0; 989 990 if ( (s & ~CXDTV_TS_RISCI) != 0 ) 991 device_printf(sc->sc_dev, "unexpected TS IS %08x\n", s); 992 993 if (sc->sc_dtvsubmitcb == NULL) 994 goto done; 995 996 if ((s & CXDTV_TS_RISCI1) == CXDTV_TS_RISCI1) { 997 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma->map, 998 0, CXDTV_TS_PKTSIZE, 999 BUS_DMASYNC_POSTREAD); 1000 payload.data = KERNADDR(sc->sc_dma); 1001 payload.size = CXDTV_TS_PKTSIZE; 1002 sc->sc_dtvsubmitcb(sc->sc_dtvsubmitarg, &payload); 1003 } 1004 1005 if ((s & CXDTV_TS_RISCI2) == CXDTV_TS_RISCI2) { 1006 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma->map, 1007 CXDTV_TS_PKTSIZE, CXDTV_TS_PKTSIZE, 1008 BUS_DMASYNC_POSTREAD); 1009 payload.data = (char *)(KERNADDR(sc->sc_dma)) + (uintptr_t)CXDTV_TS_PKTSIZE; 1010 payload.size = CXDTV_TS_PKTSIZE; 1011 sc->sc_dtvsubmitcb(sc->sc_dtvsubmitarg, &payload); 1012 } 1013 1014 done: 1015 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_TS_INT_STAT, s); 1016 1017 return 1; 1018 } 1019 1020 static int 1021 cxdtv_allocmem(struct cxdtv_softc *sc, size_t size, size_t align, 1022 struct cxdtv_dma *p) 1023 { 1024 int err; 1025 1026 p->size = size; 1027 err = bus_dmamem_alloc(sc->sc_dmat, p->size, align, 0, 1028 p->segs, __arraycount(p->segs), 1029 &p->nsegs, BUS_DMA_NOWAIT); 1030 if (err) 1031 return err; 1032 err = bus_dmamem_map(sc->sc_dmat, p->segs, p->nsegs, p->size, 1033 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 1034 if (err) 1035 goto free; 1036 err = bus_dmamap_create(sc->sc_dmat, p->size, 1, p->size, 0, 1037 BUS_DMA_NOWAIT, &p->map); 1038 if (err) 1039 goto unmap; 1040 err = bus_dmamap_load(sc->sc_dmat, p->map, p->addr, p->size, NULL, 1041 BUS_DMA_NOWAIT); 1042 if (err) 1043 goto destroy; 1044 1045 return 0; 1046 1047 destroy: 1048 bus_dmamap_destroy(sc->sc_dmat, p->map); 1049 unmap: 1050 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 1051 free: 1052 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 1053 1054 return err; 1055 } 1056 1057 static int 1058 cxdtv_freemem(struct cxdtv_softc *sc, struct cxdtv_dma *p) 1059 { 1060 1061 bus_dmamap_unload(sc->sc_dmat, p->map); 1062 bus_dmamap_destroy(sc->sc_dmat, p->map); 1063 bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size); 1064 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 1065 1066 return 0; 1067 } 1068 1069 void * 1070 cxdtv_mpeg_malloc(struct cxdtv_softc *sc, size_t size) 1071 { 1072 struct cxdtv_dma *p; 1073 int err; 1074 1075 p = kmem_alloc(sizeof(*p), KM_SLEEP); 1076 if (p == NULL) { 1077 return NULL; 1078 } 1079 1080 err = cxdtv_allocmem(sc, size, 16, p); 1081 if (err) { 1082 kmem_free(p, sizeof(*p)); 1083 device_printf(sc->sc_dev, "not enough memory\n"); 1084 return NULL; 1085 } 1086 1087 p->next = sc->sc_dma; 1088 sc->sc_dma = p; 1089 1090 return KERNADDR(p); 1091 } 1092 1093 static void 1094 cxdtv_mpeg_free(struct cxdtv_softc *sc, void *addr) 1095 { 1096 struct cxdtv_dma *p; 1097 struct cxdtv_dma **pp; 1098 1099 for (pp = &sc->sc_dma; (p = *pp) != NULL; pp = &p->next) { 1100 if (KERNADDR(p) == addr) { 1101 cxdtv_freemem(sc, p); 1102 *pp = p->next; 1103 kmem_free(p, sizeof(*p)); 1104 return; 1105 } 1106 } 1107 1108 device_printf(sc->sc_dev, "%p is already free\n", addr); 1109 1110 return; 1111 } 1112 1113 1114 /* ATI HDTV Wonder */ 1115 static void 1116 cxdtv_card_init_hdtvwonder(struct cxdtv_softc *sc) 1117 { 1118 int i, x; 1119 i2c_addr_t na; 1120 uint8_t nb[5][2] = { 1121 {0x10, 0x12}, {0x13, 0x04}, {0x16, 0x00}, 1122 {0x14, 0x04}, {0x17, 0x00} 1123 }; 1124 1125 /* prepare TUV1236D/TU1236F NIM */ 1126 1127 na = 0x0a; /* Nxt2004 address */ 1128 x = 0; 1129 1130 iic_acquire_bus(&sc->sc_i2c, I2C_F_POLL); 1131 1132 for(i = 0; i < 5; i++) 1133 x |= iic_exec(&sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, na, 1134 nb[i], 2, NULL, 0, I2C_F_POLL); 1135 1136 iic_release_bus(&sc->sc_i2c, I2C_F_POLL); 1137 1138 if (x) 1139 aprint_error_dev(sc->sc_dev, "HDTV Wonder tuner init failed"); 1140 } 1141 1142 /* pcHDTV HD5500 */ 1143 #define cxdtv_write_field(_mask, _shift, _value) \ 1144 (((_value) & (_mask)) << (_shift)) 1145 1146 static void 1147 cxdtv_write_gpio(struct cxdtv_softc *sc, uint32_t mask, uint32_t value) 1148 { 1149 uint32_t v = 0; 1150 v |= cxdtv_write_field(0xff, 16, mask); 1151 v |= cxdtv_write_field(0xff, 8, mask); 1152 v |= cxdtv_write_field(0xff, 0, (mask & value)); 1153 bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_GP0_IO, v); 1154 } 1155 1156 static void 1157 cxdtv_card_init_hd5500(struct cxdtv_softc *sc) 1158 { 1159 /* hardware (demod) reset */ 1160 cxdtv_write_gpio(sc, 1, 0); 1161 delay(100000); 1162 cxdtv_write_gpio(sc, 1, 1); 1163 delay(200000); 1164 } 1165 1166 MODULE(MODULE_CLASS_DRIVER, cxdtv, "tvpll,nxt2k,lg3303,pci"); 1167 1168 #ifdef _MODULE 1169 #include "ioconf.c" 1170 #endif 1171 1172 static int 1173 cxdtv_modcmd(modcmd_t cmd, void *opaque) 1174 { 1175 switch (cmd) { 1176 case MODULE_CMD_INIT: 1177 #ifdef _MODULE 1178 return config_init_component(cfdriver_ioconf_cxdtv, 1179 cfattach_ioconf_cxdtv, cfdata_ioconf_cxdtv); 1180 #else 1181 return 0; 1182 #endif 1183 case MODULE_CMD_FINI: 1184 #ifdef _MODULE 1185 return config_fini_component(cfdriver_ioconf_cxdtv, 1186 cfattach_ioconf_cxdtv, cfdata_ioconf_cxdtv); 1187 #else 1188 return 0; 1189 #endif 1190 default: 1191 return ENOTTY; 1192 } 1193 } 1194