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