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