1 /* 2 * Copyright (c) 2003, 2004, 2005 3 * John Wehle <john@feith.com>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by John Wehle. 16 * 4. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Conexant MPEG-2 Codec driver. Supports the CX23415 / CX23416 34 * chips that are on the Hauppauge PVR-250 and PVR-350 video 35 * capture cards. Currently only the encoder is supported. 36 * 37 * This driver was written using the invaluable information 38 * compiled by The IvyTV Project (ivtv.sourceforge.net). 39 */ 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/conf.h> 44 #include <sys/uio.h> 45 #include <sys/kernel.h> 46 #include <sys/mman.h> 47 #include <sys/module.h> 48 #include <sys/event.h> 49 #include <sys/proc.h> 50 #include <sys/signalvar.h> 51 #include <sys/thread2.h> 52 #include <sys/vnode.h> 53 #include <sys/resource.h> 54 #include <sys/bus.h> 55 #include <sys/rman.h> 56 57 #include <machine/clock.h> 58 59 #include <dev/video/meteor/ioctl_meteor.h> 60 #include <dev/video/bktr/ioctl_bt848.h> 61 62 #include <bus/pci/pcireg.h> 63 #include <bus/pci/pcivar.h> 64 65 #include <dev/video/cxm/cxm.h> 66 67 #include <bus/iicbus/iiconf.h> 68 69 /* 70 * Various supported device vendors/types and their names. 71 */ 72 static struct cxm_dev cxm_devs[] = { 73 { PCI_VENDOR_ICOMPRESSION, PCI_PRODUCT_ICOMPRESSION_ITVC15, 74 "Conexant iTVC15 MPEG Coder" }, 75 { PCI_VENDOR_ICOMPRESSION, PCI_PRODUCT_ICOMPRESSION_ITVC16, 76 "Conexant iTVC16 MPEG Coder" }, 77 { 0, 0, NULL } 78 }; 79 80 81 static int cxm_probe(device_t dev); 82 static int cxm_attach(device_t dev); 83 static int cxm_detach(device_t dev); 84 static int cxm_shutdown(device_t dev); 85 static void cxm_intr(void *arg); 86 87 static void cxm_child_detached(device_t dev, device_t child); 88 static int cxm_read_ivar(device_t bus, device_t dev, 89 int index, uintptr_t* val); 90 static int cxm_write_ivar(device_t bus, device_t dev, 91 int index, uintptr_t val); 92 93 94 static device_method_t cxm_methods[] = { 95 /* Device interface */ 96 DEVMETHOD(device_probe, cxm_probe), 97 DEVMETHOD(device_attach, cxm_attach), 98 DEVMETHOD(device_detach, cxm_detach), 99 DEVMETHOD(device_shutdown, cxm_shutdown), 100 101 /* bus interface */ 102 DEVMETHOD(bus_child_detached, cxm_child_detached), 103 DEVMETHOD(bus_print_child, bus_generic_print_child), 104 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 105 DEVMETHOD(bus_read_ivar, cxm_read_ivar), 106 DEVMETHOD(bus_write_ivar, cxm_write_ivar), 107 108 DEVMETHOD_END 109 }; 110 111 static driver_t cxm_driver = { 112 "cxm", 113 cxm_methods, 114 sizeof(struct cxm_softc), 115 }; 116 117 static devclass_t cxm_devclass; 118 119 static d_open_t cxm_open; 120 static d_close_t cxm_close; 121 static d_read_t cxm_read; 122 static d_ioctl_t cxm_ioctl; 123 static d_kqfilter_t cxm_kqfilter; 124 125 static void cxm_filter_detach(struct knote *); 126 static int cxm_filter(struct knote *, long); 127 128 static struct dev_ops cxm_ops = { 129 { "cxm", 0, 0 }, 130 .d_open = cxm_open, 131 .d_close = cxm_close, 132 .d_read = cxm_read, 133 .d_ioctl = cxm_ioctl, 134 .d_kqfilter = cxm_kqfilter 135 }; 136 137 MODULE_DEPEND(cxm, cxm_iic, 1, 1, 1); 138 DRIVER_MODULE(cxm, pci, cxm_driver, cxm_devclass, NULL, NULL); 139 140 141 static struct cxm_codec_audio_format codec_audio_formats[] = { 142 { 44100, 0xb8 }, /* 44.1 Khz, MPEG-1 Layer II, 224 kb/s */ 143 { 48000, 0xe9 } /* 48 Khz, MPEG-1 Layer II, 384 kb/s */ 144 }; 145 146 147 /* 148 * Various profiles. 149 */ 150 static struct cxm_codec_profile vcd_ntsc_profile = { 151 "MPEG-1 VideoCD NTSC video and MPEG audio", 152 CXM_FW_STREAM_TYPE_VCD, 153 30, 154 352, 240, 480, 155 { 10, 12, 21 }, 156 12, 157 0, 158 { 1, 1150000, 0 }, 159 { 1, 15, 3}, 160 /* 161 * Spatial filter = Manual, Temporal filter = Manual 162 * Median filter = Horizontal / Vertical 163 * Spatial filter value = 1, Temporal filter value = 4 164 */ 165 { 0, 3, 1, 4 }, 166 44100 167 }; 168 169 static struct cxm_codec_profile vcd_pal_profile = { 170 "MPEG-1 VideoCD PAL video and MPEG audio", 171 CXM_FW_STREAM_TYPE_VCD, 172 25, 173 352, 288, 576, 174 { 6, 17, 22 }, 175 8, 176 0, 177 { 1, 1150000, 0 }, 178 { 1, 12, 3}, 179 /* 180 * Spatial filter = Manual, Temporal filter = Manual 181 * Median filter = Horizontal / Vertical 182 * Spatial filter value = 1, Temporal filter value = 4 183 */ 184 { 0, 3, 1, 4 }, 185 44100 186 }; 187 188 static struct cxm_codec_profile svcd_ntsc_profile = { 189 "MPEG-2 SuperVCD NTSC video and MPEG audio", 190 CXM_FW_STREAM_TYPE_SVCD, 191 30, 192 480, 480, 480, 193 { 10, 12, 21 }, 194 2, 195 0, 196 /* 2.5 Mb/s peak limit to keep bbdmux followed by mplex -f 4 happy */ 197 { 0, 1150000, 2500000 }, 198 { 1, 15, 3}, 199 /* 200 * Spatial filter = Manual, Temporal filter = Manual 201 * Median filter = Horizontal / Vertical 202 * Spatial filter value = 1, Temporal filter value = 4 203 */ 204 { 0, 3, 1, 4 }, 205 44100 206 }; 207 208 static struct cxm_codec_profile svcd_pal_profile = { 209 "MPEG-2 SuperVCD PAL video and MPEG audio", 210 CXM_FW_STREAM_TYPE_SVCD, 211 25, 212 480, 576, 576, 213 { 6, 17, 22 }, 214 2, 215 0, 216 /* 2.5 Mb/s peak limit to keep bbdmux followed by mplex -f 4 happy */ 217 { 0, 1150000, 2500000 }, 218 { 1, 12, 3}, 219 /* 220 * Spatial filter = Manual, Temporal filter = Manual 221 * Median filter = Horizontal / Vertical 222 * Spatial filter value = 1, Temporal filter value = 4 223 */ 224 { 0, 3, 1, 4 }, 225 44100 226 }; 227 228 static struct cxm_codec_profile dvd_half_d1_ntsc_profile = { 229 "MPEG-2 DVD NTSC video and MPEG audio", 230 CXM_FW_STREAM_TYPE_DVD, 231 30, 232 352, 480, 480, 233 { 10, 12, 21 }, 234 2, 235 0, 236 { 0, 4000000, 4520000 }, /* 4 hours on 8.54 GB media */ 237 { 1, 15, 3}, 238 /* 239 * Spatial filter = Manual, Temporal filter = Manual 240 * Median filter = Horizontal / Vertical 241 * Spatial filter value = 1, Temporal filter value = 4 242 */ 243 { 0, 3, 1, 4 }, 244 48000 245 }; 246 247 static struct cxm_codec_profile dvd_half_d1_pal_profile = { 248 "MPEG-2 DVD PAL video and MPEG audio", 249 CXM_FW_STREAM_TYPE_DVD, 250 25, 251 352, 576, 576, 252 { 6, 17, 22 }, 253 2, 254 0, 255 { 0, 4000000, 4520000 }, /* 4 hours on 8.54 GB media */ 256 { 1, 12, 3}, 257 /* 258 * Spatial filter = Manual, Temporal filter = Manual 259 * Median filter = Horizontal / Vertical 260 * Spatial filter value = 1, Temporal filter value = 4 261 */ 262 { 0, 3, 1, 4 }, 263 48000 264 }; 265 266 static struct cxm_codec_profile dvd_full_d1_ntsc_profile = { 267 "MPEG-2 DVD NTSC video and MPEG audio", 268 CXM_FW_STREAM_TYPE_DVD, 269 30, 270 720, 480, 480, 271 { 10, 12, 21 }, 272 2, 273 0, 274 /* 9.52 Mb/s peak limit to keep bbdmux followed by mplex -f 8 happy */ 275 { 0, 9000000, 9520000 }, /* 1 hour on 4.7 GB media */ 276 { 1, 15, 3}, 277 /* 278 * Spatial filter = Manual, Temporal filter = Manual 279 * Median filter = Horizontal / Vertical 280 * Spatial filter value = 1, Temporal filter value = 4 281 */ 282 { 0, 3, 1, 4 }, 283 48000 284 }; 285 286 static struct cxm_codec_profile dvd_full_d1_pal_profile = { 287 "MPEG-2 DVD PAL video and MPEG audio", 288 CXM_FW_STREAM_TYPE_DVD, 289 25, 290 720, 576, 576, 291 { 6, 17, 22 }, 292 2, 293 0, 294 /* 9.52 Mb/s peak limit to keep bbdmux followed by mplex -f 8 happy */ 295 { 0, 9000000, 9520000 }, /* 1 hour on 4.7 GB media */ 296 { 1, 12, 3}, 297 /* 298 * Spatial filter = Manual, Temporal filter = Manual 299 * Median filter = Horizontal / Vertical 300 * Spatial filter value = 1, Temporal filter value = 4 301 */ 302 { 0, 3, 1, 4 }, 303 48000 304 }; 305 306 307 static const struct cxm_codec_profile 308 *codec_profiles[] = { 309 &vcd_ntsc_profile, 310 &vcd_pal_profile, 311 &svcd_ntsc_profile, 312 &svcd_pal_profile, 313 &dvd_half_d1_ntsc_profile, 314 &dvd_half_d1_pal_profile, 315 &dvd_full_d1_ntsc_profile, 316 &dvd_full_d1_pal_profile 317 }; 318 319 320 static unsigned int 321 cxm_queue_firmware_command(struct cxm_softc *sc, 322 enum cxm_mailbox_name mbx_name, uint32_t cmd, 323 uint32_t *parameters, unsigned int nparameters) 324 { 325 unsigned int i; 326 unsigned int mailbox; 327 uint32_t completed_command; 328 uint32_t flags; 329 330 if (nparameters > CXM_MBX_MAX_PARAMETERS) { 331 device_printf(sc->dev, "too many parameters for mailbox\n"); 332 return -1; 333 } 334 335 mailbox = 0; 336 337 switch (mbx_name) { 338 case cxm_dec_mailbox: 339 mailbox = sc->dec_mbx 340 + CXM_MBX_FW_CMD_MAILBOX *sizeof(struct cxm_mailbox); 341 break; 342 343 case cxm_enc_mailbox: 344 mailbox = sc->enc_mbx 345 + CXM_MBX_FW_CMD_MAILBOX *sizeof(struct cxm_mailbox); 346 break; 347 348 default: 349 return -1; 350 } 351 352 crit_enter(); 353 for (i = 0; i < CXM_MBX_FW_CMD_MAILBOXES; i++) { 354 flags = CSR_READ_4(sc, 355 mailbox 356 + offsetof(struct cxm_mailbox, flags)); 357 if (!(flags & CXM_MBX_FLAG_IN_USE)) 358 break; 359 360 /* 361 * Mail boxes containing certain completed commands 362 * for which the results are never needed can be reused. 363 */ 364 365 if ((flags & (CXM_MBX_FLAG_DRV_DONE | CXM_MBX_FLAG_FW_DONE)) 366 == (CXM_MBX_FLAG_DRV_DONE | CXM_MBX_FLAG_FW_DONE)) { 367 completed_command 368 = CSR_READ_4(sc, 369 mailbox 370 + offsetof(struct cxm_mailbox, command)); 371 372 /* 373 * DMA results are always check by reading the 374 * DMA status register ... never by checking 375 * the mailbox after the command has completed. 376 */ 377 378 if (completed_command == CXM_FW_CMD_SCHED_DMA_TO_HOST) 379 break; 380 } 381 382 mailbox += sizeof(struct cxm_mailbox); 383 } 384 385 if (i >= CXM_MBX_FW_CMD_MAILBOXES) { 386 crit_exit(); 387 return -1; 388 } 389 390 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), 391 CXM_MBX_FLAG_IN_USE); 392 393 /* 394 * PCI writes may be buffered so force the 395 * write to complete by reading the last 396 * location written. 397 */ 398 399 CSR_READ_4(sc, mailbox + offsetof(struct cxm_mailbox, flags)); 400 401 crit_exit(); 402 403 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, command), cmd); 404 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, timeout), 405 CXM_FW_STD_TIMEOUT); 406 407 for (i = 0; i < nparameters; i++) 408 CSR_WRITE_4(sc, 409 mailbox 410 + offsetof(struct cxm_mailbox, parameters) 411 + i * sizeof(uint32_t), 412 *(parameters + i)); 413 414 for (; i < CXM_MBX_MAX_PARAMETERS; i++) 415 CSR_WRITE_4(sc, 416 mailbox 417 + offsetof(struct cxm_mailbox, parameters) 418 + i * sizeof(uint32_t), 0); 419 420 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), 421 CXM_MBX_FLAG_IN_USE | CXM_MBX_FLAG_DRV_DONE); 422 423 return mailbox; 424 } 425 426 427 static int 428 cxm_firmware_command(struct cxm_softc *sc, 429 enum cxm_mailbox_name mbx_name, uint32_t cmd, 430 uint32_t *parameters, unsigned int nparameters) 431 { 432 const char *wmesg; 433 unsigned int *bmp; 434 unsigned int i; 435 unsigned int mailbox; 436 uint32_t flags; 437 uint32_t result; 438 439 bmp = NULL; 440 wmesg = ""; 441 442 switch (mbx_name) { 443 case cxm_dec_mailbox: 444 bmp = &sc->dec_mbx; 445 wmesg = "cxmdfw"; 446 break; 447 448 case cxm_enc_mailbox: 449 bmp = &sc->enc_mbx; 450 wmesg = "cxmefw"; 451 break; 452 453 default: 454 return -1; 455 } 456 457 mailbox = cxm_queue_firmware_command(sc, mbx_name, cmd, 458 parameters, nparameters); 459 if (mailbox == -1) { 460 device_printf(sc->dev, "no free mailboxes\n"); 461 return -1; 462 } 463 464 /* Give the firmware a chance to start processing the request */ 465 tsleep(bmp, 0, wmesg, hz / 100); 466 467 for (i = 0; i < 100; i++) { 468 flags = CSR_READ_4(sc, 469 mailbox 470 + offsetof(struct cxm_mailbox, flags)); 471 if ((flags & CXM_MBX_FLAG_FW_DONE)) 472 break; 473 474 /* Wait for 10ms */ 475 tsleep(bmp, 0, wmesg, hz / 100); 476 } 477 478 if (i >= 100) { 479 device_printf(sc->dev, "timeout\n"); 480 return -1; 481 } 482 483 result = CSR_READ_4(sc, 484 mailbox 485 + offsetof(struct cxm_mailbox, result)); 486 487 for (i = 0; i < nparameters; i++) 488 *(parameters + i) 489 = CSR_READ_4(sc, 490 mailbox 491 + offsetof(struct cxm_mailbox, parameters) 492 + i * sizeof(uint32_t)); 493 494 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), 0); 495 496 return result == 0 ? 0 : -1; 497 } 498 499 500 static int 501 cxm_firmware_command_nosleep(struct cxm_softc *sc, 502 enum cxm_mailbox_name mbx_name, uint32_t cmd, 503 uint32_t *parameters, unsigned int nparameters) 504 { 505 unsigned int i; 506 unsigned int mailbox; 507 uint32_t flags; 508 uint32_t result; 509 510 for (i = 0; i < 100; i++) { 511 mailbox = cxm_queue_firmware_command(sc, mbx_name, cmd, 512 parameters, nparameters); 513 if (mailbox != -1) 514 break; 515 516 /* Wait for 10ms */ 517 DELAY(10000); 518 } 519 520 if (i >= 100) { 521 device_printf(sc->dev, "no free mailboxes\n"); 522 return -1; 523 } 524 525 /* Give the firmware a chance to start processing the request */ 526 DELAY(10000); 527 528 for (i = 0; i < 100; i++) { 529 flags = CSR_READ_4(sc, 530 mailbox 531 + offsetof(struct cxm_mailbox, flags)); 532 if ((flags & CXM_MBX_FLAG_FW_DONE)) 533 break; 534 535 /* Wait for 10ms */ 536 DELAY(10000); 537 } 538 539 if (i >= 100) { 540 device_printf(sc->dev, "timeout\n"); 541 return -1; 542 } 543 544 result = CSR_READ_4(sc, 545 mailbox 546 + offsetof(struct cxm_mailbox, result)); 547 548 for (i = 0; i < nparameters; i++) 549 *(parameters + i) 550 = CSR_READ_4(sc, 551 mailbox 552 + offsetof(struct cxm_mailbox, parameters) 553 + i * sizeof(uint32_t)); 554 555 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), 0); 556 557 return result == 0 ? 0 : -1; 558 } 559 560 561 static int 562 cxm_stop_firmware(struct cxm_softc *sc) 563 { 564 565 if (cxm_firmware_command_nosleep(sc, cxm_enc_mailbox, 566 CXM_FW_CMD_ENC_HALT_FW, NULL, 0) < 0) 567 return -1; 568 569 if (sc->type == cxm_iTVC15_type 570 && cxm_firmware_command_nosleep(sc, cxm_dec_mailbox, 571 CXM_FW_CMD_DEC_HALT_FW, 572 NULL, 0) < 0) 573 return -1; 574 575 /* Wait for 10ms */ 576 DELAY(10000); 577 578 return 0; 579 } 580 581 582 static void 583 cxm_set_irq_mask(struct cxm_softc *sc, uint32_t mask) 584 { 585 crit_enter(); 586 587 CSR_WRITE_4(sc, CXM_REG_IRQ_MASK, mask); 588 589 /* 590 * PCI writes may be buffered so force the 591 * write to complete by reading the last 592 * location written. 593 */ 594 595 CSR_READ_4(sc, CXM_REG_IRQ_MASK); 596 597 sc->irq_mask = mask; 598 599 crit_exit(); 600 } 601 602 603 static void 604 cxm_set_irq_status(struct cxm_softc *sc, uint32_t status) 605 { 606 607 CSR_WRITE_4(sc, CXM_REG_IRQ_STATUS, status); 608 609 /* 610 * PCI writes may be buffered so force the 611 * write to complete by reading the last 612 * location written. 613 */ 614 615 CSR_READ_4(sc, CXM_REG_IRQ_STATUS); 616 } 617 618 619 static int 620 cxm_stop_hardware(struct cxm_softc *sc) 621 { 622 if (sc->cxm_iic) { 623 if (cxm_saa7115_mute(sc) < 0) 624 return -1; 625 if (cxm_msp_mute(sc) < 0) 626 return -1; 627 } 628 629 /* Halt the firmware */ 630 if (sc->enc_mbx != -1) { 631 if (cxm_stop_firmware(sc) < 0) 632 return -1; 633 } 634 635 /* Mask all interrupts */ 636 cxm_set_irq_mask(sc, 0xffffffff); 637 638 /* Stop VDM */ 639 CSR_WRITE_4(sc, CXM_REG_VDM, CXM_CMD_VDM_STOP); 640 641 /* Stop AO */ 642 CSR_WRITE_4(sc, CXM_REG_AO, CXM_CMD_AO_STOP); 643 644 /* Ping (?) APU */ 645 CSR_WRITE_4(sc, CXM_REG_APU, CXM_CMD_APU_PING); 646 647 /* Stop VPU */ 648 CSR_WRITE_4(sc, CXM_REG_VPU, sc->type == cxm_iTVC15_type 649 ? CXM_CMD_VPU_STOP15 650 : CXM_CMD_VPU_STOP16); 651 652 /* Reset Hw Blocks */ 653 CSR_WRITE_4(sc, CXM_REG_HW_BLOCKS, CXM_CMD_HW_BLOCKS_RST); 654 655 /* Stop SPU */ 656 CSR_WRITE_4(sc, CXM_REG_SPU, CXM_CMD_SPU_STOP); 657 658 /* Wait for 10ms */ 659 DELAY(10000); 660 661 return 0; 662 } 663 664 665 static int 666 cxm_download_firmware(struct cxm_softc *sc) 667 { 668 unsigned int i; 669 const uint32_t *fw; 670 671 /* Check if firmware is compiled in */ 672 if (strncmp((const char *)cxm_enc_fw, "NOFW", 4) == 0) { 673 device_printf(sc->dev, "encoder firmware not compiled in\n"); 674 return -1; 675 } else if (strncmp((const char *)cxm_dec_fw, "NOFW", 4) == 0) { 676 device_printf(sc->dev, "decoder firmware not compiled in\n"); 677 return -1; 678 } 679 680 /* Download the encoder firmware */ 681 fw = (const uint32_t *)cxm_enc_fw; 682 for (i = 0; i < CXM_FW_SIZE; i += sizeof(*fw)) 683 CSR_WRITE_4(sc, CXM_MEM_ENC + i, *fw++); 684 685 /* Download the decoder firmware */ 686 if (sc->type == cxm_iTVC15_type) { 687 fw = (const uint32_t *)cxm_dec_fw; 688 for (i = 0; i < CXM_FW_SIZE; i += sizeof(*fw)) 689 CSR_WRITE_4(sc, CXM_MEM_DEC + i, *fw++); 690 } 691 692 return 0; 693 } 694 695 696 static int 697 cxm_init_hardware(struct cxm_softc *sc) 698 { 699 unsigned int i; 700 unsigned int mailbox; 701 uint32_t parameter; 702 703 if (cxm_stop_hardware(sc) < 0) 704 return -1; 705 706 /* Initialize encoder SDRAM pre-charge */ 707 CSR_WRITE_4(sc, CXM_REG_ENC_SDRAM_PRECHARGE, 708 CXM_CMD_SDRAM_PRECHARGE_INIT); 709 710 /* Initialize encoder SDRAM refresh to 1us */ 711 CSR_WRITE_4(sc, CXM_REG_ENC_SDRAM_REFRESH, 712 CXM_CMD_SDRAM_REFRESH_INIT); 713 714 /* Initialize decoder SDRAM pre-charge */ 715 CSR_WRITE_4(sc, CXM_REG_DEC_SDRAM_PRECHARGE, 716 CXM_CMD_SDRAM_PRECHARGE_INIT); 717 718 /* Initialize decoder SDRAM refresh to 1us */ 719 CSR_WRITE_4(sc, CXM_REG_DEC_SDRAM_REFRESH, 720 CXM_CMD_SDRAM_REFRESH_INIT); 721 722 /* Wait for 600ms */ 723 DELAY(600000); 724 725 if (cxm_download_firmware(sc) < 0) 726 return -1; 727 728 /* Enable SPU */ 729 CSR_WRITE_4(sc, CXM_REG_SPU, 730 CSR_READ_4(sc, CXM_REG_SPU) & CXM_MASK_SPU_ENABLE); 731 732 /* Wait for 1 second */ 733 DELAY(1000000); 734 735 /* Enable VPU */ 736 CSR_WRITE_4(sc, CXM_REG_VPU, 737 CSR_READ_4(sc, CXM_REG_VPU) 738 & (sc->type == cxm_iTVC15_type 739 ? CXM_MASK_VPU_ENABLE15 740 : CXM_MASK_VPU_ENABLE16)); 741 742 /* Wait for 1 second */ 743 DELAY(1000000); 744 745 /* Locate encoder mailbox */ 746 mailbox = CXM_MEM_ENC; 747 for (i = 0; i < CXM_MEM_ENC_SIZE; i += 0x100) 748 if (CSR_READ_4(sc, mailbox + i) == 0x12345678 749 && CSR_READ_4(sc, mailbox + i + 4) == 0x34567812 750 && CSR_READ_4(sc, mailbox + i + 8) == 0x56781234 751 && CSR_READ_4(sc, mailbox + i + 12) == 0x78123456) 752 break; 753 754 if (i >= CXM_MEM_ENC_SIZE) 755 return -1; 756 757 sc->enc_mbx = mailbox + i + 16; 758 759 /* Locate decoder mailbox */ 760 if (sc->type == cxm_iTVC15_type) { 761 mailbox = CXM_MEM_DEC; 762 for (i = 0; i < CXM_MEM_DEC_SIZE; i += 0x100) 763 if (CSR_READ_4(sc, mailbox + i) == 0x12345678 764 && CSR_READ_4(sc, mailbox + i + 4) == 0x34567812 765 && CSR_READ_4(sc, mailbox + i + 8) == 0x56781234 766 && CSR_READ_4(sc, mailbox + i + 12) == 0x78123456) 767 break; 768 769 if (i >= CXM_MEM_DEC_SIZE) 770 return -1; 771 772 sc->dec_mbx = mailbox + i + 16; 773 } 774 775 /* Get encoder firmware version */ 776 parameter = 0; 777 if (cxm_firmware_command_nosleep(sc, cxm_enc_mailbox, 778 CXM_FW_CMD_ENC_GET_FW_VER, 779 ¶meter, 1) < 0) 780 return -1; 781 782 device_printf(sc->dev, "encoder firmware version %#x\n", 783 (unsigned int)parameter); 784 785 /* Get decoder firmware version */ 786 if (sc->type == cxm_iTVC15_type) { 787 parameter = 0; 788 if (cxm_firmware_command_nosleep(sc, cxm_dec_mailbox, 789 CXM_FW_CMD_DEC_GET_FW_VER, 790 ¶meter, 1) < 0) 791 return -1; 792 793 device_printf(sc->dev, "decoder firmware version %#x\n", 794 (unsigned int)parameter); 795 } 796 797 return 0; 798 } 799 800 801 static int 802 cxm_configure_encoder(struct cxm_softc *sc) 803 { 804 int fps; 805 unsigned int i; 806 uint32_t parameters[12]; 807 const struct cxm_codec_profile *cpp; 808 809 if (sc->source == cxm_fm_source) 810 switch (cxm_tuner_selected_channel_set(sc)) { 811 case CHNLSET_NABCST: 812 case CHNLSET_CABLEIRC: 813 case CHNLSET_JPNBCST: 814 case CHNLSET_JPNCABLE: 815 fps = 30; 816 break; 817 818 default: 819 fps = 25; 820 break; 821 } 822 else 823 fps = cxm_saa7115_detected_fps(sc); 824 825 if (fps < 0) 826 return -1; 827 828 if (sc->profile->fps != fps) { 829 830 /* 831 * Pick a profile with the correct fps using the 832 * chosen stream type and width to decide between 833 * the VCD, SVCD, or DVD profiles. 834 */ 835 836 for (i = 0; i < NUM_ELEMENTS(codec_profiles); i++) 837 if (codec_profiles[i]->fps == fps 838 && codec_profiles[i]->stream_type 839 == sc->profile->stream_type 840 && codec_profiles[i]->width == sc->profile->width) 841 break; 842 843 if (i >= NUM_ELEMENTS(codec_profiles)) 844 return -1; 845 846 sc->profile = codec_profiles[i]; 847 } 848 849 cpp = sc->profile; 850 851 if (cxm_saa7115_configure(sc, 852 cpp->width, cpp->source_height, fps, 853 cpp->audio_sample_rate) < 0) 854 return -1; 855 856 /* assign dma block len */ 857 parameters[0] = 1; /* Transfer block size = 1 */ 858 parameters[1] = 1; /* Units = 1 (frames) */ 859 if (cxm_firmware_command(sc, cxm_enc_mailbox, 860 CXM_FW_CMD_ASSIGN_DMA_BLOCKLEN, 861 parameters, 2) != 0) 862 return -1; 863 864 865 /* assign program index info */ 866 parameters[0] = 0; /* Picture mask = 0 (don't generate index) */ 867 parameters[1] = 0; /* Num_req = 0 */ 868 if (cxm_firmware_command(sc, cxm_enc_mailbox, 869 CXM_FW_CMD_ASSIGN_PGM_INDEX_INFO, 870 parameters, 2) != 0) 871 return -1; 872 873 /* assign stream type */ 874 parameters[0] = cpp->stream_type; 875 if (cxm_firmware_command(sc, cxm_enc_mailbox, 876 CXM_FW_CMD_ASSIGN_STREAM_TYPE, 877 parameters, 1) != 0) 878 return -1; 879 880 /* assign output port */ 881 parameters[0] = 0; /* 0 (Memory) */ 882 if (cxm_firmware_command(sc, cxm_enc_mailbox, 883 CXM_FW_CMD_ASSIGN_OUTPUT_PORT, 884 parameters, 1) != 0) 885 return -1; 886 887 /* assign framerate */ 888 parameters[0] = cpp->fps == 30 ? 0 : 1; 889 if (cxm_firmware_command(sc, cxm_enc_mailbox, 890 CXM_FW_CMD_ASSIGN_FRAME_RATE, 891 parameters, 1) != 0) 892 return -1; 893 894 /* assign frame size */ 895 parameters[0] = cpp->height; 896 parameters[1] = cpp->width; 897 if (cxm_firmware_command(sc, cxm_enc_mailbox, 898 CXM_FW_CMD_ASSIGN_FRAME_SIZE, 899 parameters, 2) != 0) 900 return -1; 901 902 /* assign aspect ratio */ 903 parameters[0] = cpp->aspect; 904 if (cxm_firmware_command(sc, cxm_enc_mailbox, 905 CXM_FW_CMD_ASSIGN_ASPECT_RATIO, 906 parameters, 1) != 0) 907 return -1; 908 909 /* assign bitrates */ 910 parameters[0] = cpp->bitrate.mode; 911 parameters[1] = cpp->bitrate.average; 912 parameters[2] = cpp->bitrate.peak / 400; 913 if (cxm_firmware_command(sc, cxm_enc_mailbox, 914 CXM_FW_CMD_ASSIGN_BITRATES, 915 parameters, 3) != 0) 916 return -1; 917 918 /* assign gop closure */ 919 parameters[0] = cpp->gop.closure; 920 if (cxm_firmware_command(sc, cxm_enc_mailbox, 921 CXM_FW_CMD_ASSIGN_GOP_CLOSURE, 922 parameters, 1) != 0) 923 return -1; 924 925 /* assign gop properties */ 926 parameters[0] = cpp->gop.frames; 927 parameters[1] = cpp->gop.bframes; 928 if (cxm_firmware_command(sc, cxm_enc_mailbox, 929 CXM_FW_CMD_ASSIGN_GOP_PROPERTIES, 930 parameters, 2) != 0) 931 return -1; 932 933 /* assign 3 2 pulldown */ 934 parameters[0] = cpp->pulldown; 935 if (cxm_firmware_command(sc, cxm_enc_mailbox, 936 CXM_FW_CMD_ASSIGN_3_2_PULLDOWN, 937 parameters, 1) != 0) 938 return -1; 939 940 /* assign dnr filter mode */ 941 parameters[0] = cpp->dnr.mode; 942 parameters[1] = cpp->dnr.type; 943 if (cxm_firmware_command(sc, cxm_enc_mailbox, 944 CXM_FW_CMD_ASSIGN_DNR_FILTER_MODE, 945 parameters, 2) != 0) 946 return -1; 947 948 /* assign dnr filter props */ 949 parameters[0] = cpp->dnr.spatial; 950 parameters[1] = cpp->dnr.temporal; 951 if (cxm_firmware_command(sc, cxm_enc_mailbox, 952 CXM_FW_CMD_ASSIGN_DNR_FILTER_PROPERTIES, 953 parameters, 2) != 0) 954 return -1; 955 956 /* 957 * assign audio properties 958 */ 959 960 for (i = 0; i < NUM_ELEMENTS(codec_audio_formats); i++) 961 if (codec_audio_formats[i].sample_rate 962 == cpp->audio_sample_rate) 963 break; 964 965 if (i >= NUM_ELEMENTS(codec_audio_formats)) 966 return -1; 967 968 parameters[0] = codec_audio_formats[i].format; 969 if (cxm_firmware_command(sc, cxm_enc_mailbox, 970 CXM_FW_CMD_ASSIGN_AUDIO_PROPERTIES, 971 parameters, 1) != 0) 972 return -1; 973 974 /* assign coring levels */ 975 parameters[0] = 0; /* luma_h */ 976 parameters[1] = 255; /* luma_l */ 977 parameters[2] = 0; /* chroma_h */ 978 parameters[3] = 255; /* chroma_l */ 979 if (cxm_firmware_command(sc, cxm_enc_mailbox, 980 CXM_FW_CMD_ASSIGN_CORING_LEVELS, 981 parameters, 4) != 0) 982 return -1; 983 984 /* assign spatial filter type */ 985 parameters[0] = 3; /* Luminance filter = 3 (2D H/V Separable) */ 986 parameters[1] = 1; /* Chrominance filter = 1 (1D Horizontal) */ 987 if (cxm_firmware_command(sc, cxm_enc_mailbox, 988 CXM_FW_CMD_ASSIGN_SPATIAL_FILTER_TYPE, 989 parameters, 2) != 0) 990 return -1; 991 992 /* assign frame drop rate */ 993 parameters[0] = 0; 994 if (cxm_firmware_command(sc, cxm_enc_mailbox, 995 CXM_FW_CMD_ASSIGN_FRAME_DROP_RATE, 996 parameters, 1) != 0) 997 return -1; 998 999 /* assign placeholder */ 1000 parameters[0] = 0; /* type = 0 (Extension / UserData) */ 1001 parameters[1] = 0; /* period */ 1002 parameters[2] = 0; /* size_t */ 1003 parameters[3] = 0; /* arg0 */ 1004 parameters[4] = 0; /* arg1 */ 1005 parameters[5] = 0; /* arg2 */ 1006 parameters[6] = 0; /* arg3 */ 1007 parameters[7] = 0; /* arg4 */ 1008 parameters[8] = 0; /* arg5 */ 1009 parameters[9] = 0; /* arg6 */ 1010 parameters[10] = 0; /* arg7 */ 1011 parameters[11] = 0; /* arg8 */ 1012 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1013 CXM_FW_CMD_ASSIGN_PLACEHOLDER, 1014 parameters, 12) != 0) 1015 return -1; 1016 1017 /* assign VBI properties */ 1018 parameters[0] = 0xbd04; /* mode = 0 (sliced), stream and user data */ 1019 parameters[1] = 0; /* frames per interrupt (only valid in raw mode) */ 1020 parameters[2] = 0; /* total raw VBI frames (only valid in raw mode) */ 1021 parameters[3] = 0x25256262; /* ITU 656 start codes (saa7115 table 24)*/ 1022 parameters[4] = 0x38387f7f; /* ITU 656 stop codes (saa7115 table 24) */ 1023 parameters[5] = cpp->vbi.nlines; /* lines per frame */ 1024 parameters[6] = 1440; /* bytes per line = 720 pixels */ 1025 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1026 CXM_FW_CMD_ASSIGN_VBI_PROPERTIES, 1027 parameters, 7) != 0) 1028 return -1; 1029 1030 /* assign VBI lines */ 1031 parameters[0] = 0xffffffff; /* all lines */ 1032 parameters[1] = 0; /* disable VBI features */ 1033 parameters[2] = 0; 1034 parameters[3] = 0; 1035 parameters[4] = 0; 1036 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1037 CXM_FW_CMD_ASSIGN_VBI_LINE, 1038 parameters, 5) != 0) 1039 return -1; 1040 1041 /* assign number of lines in fields 1 and 2 */ 1042 parameters[0] = cpp->source_height / 2 + cpp->vbi.nlines; 1043 parameters[1] = cpp->source_height / 2 + cpp->vbi.nlines; 1044 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1045 CXM_FW_CMD_ASSIGN_NUM_VSYNC_LINES, 1046 parameters, 2) != 0) 1047 return -1; 1048 1049 return 0; 1050 } 1051 1052 1053 static int 1054 cxm_start_encoder(struct cxm_softc *sc) 1055 { 1056 uint32_t parameters[4]; 1057 uint32_t subtype; 1058 uint32_t type; 1059 1060 1061 if (sc->encoding) 1062 return 0; 1063 1064 if (cxm_configure_encoder(sc) < 0) 1065 return -1; 1066 1067 /* Mute the video input if necessary. */ 1068 parameters[0] = sc->source == cxm_fm_source ? 1 : 0; 1069 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1070 CXM_FW_CMD_MUTE_VIDEO_INPUT, 1071 parameters, 1) != 0) 1072 return -1; 1073 1074 /* Clear pending encoder interrupts (which are currently masked) */ 1075 cxm_set_irq_status(sc, CXM_IRQ_ENC); 1076 1077 /* Enable event notification */ 1078 parameters[0] = 0; /* Event = 0 (refresh encoder input) */ 1079 parameters[1] = 1; /* Notification = 1 (enable) */ 1080 parameters[2] = 0x10000000; /* Interrupt bit */ 1081 parameters[3] = -1; /* Mailbox = -1 (no mailbox) */ 1082 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1083 CXM_FW_CMD_ENC_EVENT_NOTIFICATION, 1084 parameters, 4) != 0) 1085 return -1; 1086 1087 if (cxm_saa7115_mute(sc) < 0) 1088 return -1; 1089 if (cxm_msp_mute(sc) < 0) 1090 return -1; 1091 1092 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1093 CXM_FW_CMD_INITIALIZE_VIDEO_INPUT, 1094 NULL, 0) < 0) 1095 return -1; 1096 1097 if (cxm_saa7115_unmute(sc) < 0) 1098 return -1; 1099 if (cxm_msp_unmute(sc) < 0) 1100 return -1; 1101 1102 /* Wait for 100ms */ 1103 tsleep(&sc->encoding, 0, "cxmce", hz / 10); 1104 1105 type = sc->mpeg ? CXM_FW_CAPTURE_STREAM_TYPE_MPEG 1106 : CXM_FW_CAPTURE_STREAM_TYPE_RAW; 1107 subtype = ((sc->mpeg || sc->source == cxm_fm_source) 1108 ? CXM_FW_CAPTURE_STREAM_PCM_AUDIO : 0) 1109 | ((sc->mpeg || sc->source != cxm_fm_source) 1110 ? CXM_FW_CAPTURE_STREAM_YUV : 0); 1111 1112 /* Start the encoder */ 1113 parameters[0] = type; 1114 parameters[1] = subtype; 1115 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1116 CXM_FW_CMD_BEGIN_CAPTURE, parameters, 2) != 0) 1117 return -1; 1118 1119 sc->enc_pool.offset = 0; 1120 sc->enc_pool.read = 0; 1121 sc->enc_pool.write = 0; 1122 1123 sc->encoding_eos = 0; 1124 1125 sc->encoding = 1; 1126 1127 /* Enable interrupts */ 1128 cxm_set_irq_mask(sc, sc->irq_mask & ~CXM_IRQ_ENC); 1129 1130 return 0; 1131 } 1132 1133 1134 static int 1135 cxm_stop_encoder(struct cxm_softc *sc) 1136 { 1137 uint32_t parameters[4]; 1138 uint32_t subtype; 1139 uint32_t type; 1140 1141 if (!sc->encoding) 1142 return 0; 1143 1144 type = sc->mpeg ? CXM_FW_CAPTURE_STREAM_TYPE_MPEG 1145 : CXM_FW_CAPTURE_STREAM_TYPE_RAW; 1146 subtype = ((sc->mpeg || sc->source == cxm_fm_source) 1147 ? CXM_FW_CAPTURE_STREAM_PCM_AUDIO : 0) 1148 | ((sc->mpeg || sc->source != cxm_fm_source) 1149 ? CXM_FW_CAPTURE_STREAM_YUV : 0); 1150 1151 /* Stop the encoder */ 1152 parameters[0] = sc->mpeg ? 0 : 1; /* When = 0 (end of GOP) */ 1153 parameters[1] = type; 1154 parameters[2] = subtype; 1155 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1156 CXM_FW_CMD_END_CAPTURE, parameters, 3) != 0) 1157 return -1; 1158 1159 /* Wait for up to 1 second */ 1160 crit_enter(); 1161 if (!sc->encoding_eos) 1162 tsleep(&sc->encoding_eos, 0, "cxmeos", hz); 1163 crit_exit(); 1164 1165 if (sc->mpeg && !sc->encoding_eos) 1166 device_printf(sc->dev, "missing encoder EOS\n"); 1167 1168 /* Disable event notification */ 1169 parameters[0] = 0; /* Event = 0 (refresh encoder input) */ 1170 parameters[1] = 0; /* Notification = 0 (disable) */ 1171 parameters[2] = 0x10000000; /* Interrupt bit */ 1172 parameters[3] = -1; /* Mailbox = -1 (no mailbox) */ 1173 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1174 CXM_FW_CMD_ENC_EVENT_NOTIFICATION, 1175 parameters, 4) != 0) 1176 return -1; 1177 1178 /* Disable interrupts */ 1179 cxm_set_irq_mask(sc, sc->irq_mask | CXM_IRQ_ENC); 1180 1181 sc->encoding = 0; 1182 1183 return 0; 1184 } 1185 1186 1187 static int 1188 cxm_pause_encoder(struct cxm_softc *sc) 1189 { 1190 uint32_t parameter; 1191 1192 /* Pause the encoder */ 1193 parameter = 0; 1194 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1195 CXM_FW_CMD_PAUSE_ENCODER, ¶meter, 1) != 0) 1196 return -1; 1197 1198 return 0; 1199 } 1200 1201 1202 static int 1203 cxm_unpause_encoder(struct cxm_softc *sc) 1204 { 1205 uint32_t parameter; 1206 1207 /* Unpause the encoder */ 1208 parameter = 1; 1209 if (cxm_firmware_command(sc, cxm_enc_mailbox, 1210 CXM_FW_CMD_PAUSE_ENCODER, ¶meter, 1) != 0) 1211 return -1; 1212 1213 return 0; 1214 } 1215 1216 1217 static unsigned int 1218 cxm_encoder_fixup_byte_order(struct cxm_softc *sc, 1219 unsigned int current, size_t offset) 1220 { 1221 unsigned int strips; 1222 unsigned int i; 1223 unsigned int j; 1224 unsigned int k; 1225 unsigned int macroblocks_per_line; 1226 unsigned int scratch; 1227 unsigned int words_per_line; 1228 uint32_t *ptr; 1229 uint32_t *src; 1230 size_t nbytes; 1231 1232 switch (sc->enc_pool.bufs[current].byte_order) { 1233 case cxm_device_mpeg_byte_order: 1234 1235 /* 1236 * Convert each 32 bit word to the proper byte ordering. 1237 */ 1238 1239 for (nbytes = 0, 1240 ptr = (uint32_t *)sc->enc_pool.bufs[current].vaddr; 1241 nbytes != sc->enc_pool.bufs[current].size; 1242 nbytes += sizeof(*ptr), ptr++) 1243 *ptr = bswap32(*ptr); 1244 break; 1245 1246 case cxm_device_yuv12_byte_order: 1247 1248 /* 1249 * Convert each macro block to planar using 1250 * a scratch buffer (the buffer prior to the 1251 * current buffer is always free since it marks 1252 * the end of the ring buffer). 1253 */ 1254 1255 scratch = (current + (CXM_SG_BUFFERS - 1)) % CXM_SG_BUFFERS; 1256 1257 if (offset) { 1258 current = scratch; 1259 break; 1260 } 1261 1262 src = (uint32_t *)sc->enc_pool.bufs[current].vaddr; 1263 words_per_line = sc->profile->width / sizeof(*ptr); 1264 macroblocks_per_line 1265 = sc->profile->width / CXM_MACROBLOCK_WIDTH; 1266 strips = sc->enc_pool.bufs[current].size 1267 / (macroblocks_per_line * CXM_MACROBLOCK_SIZE); 1268 1269 for (i = 0; i < strips; i++) { 1270 ptr = (uint32_t *)sc->enc_pool.bufs[scratch].vaddr 1271 + i * macroblocks_per_line * CXM_MACROBLOCK_SIZE 1272 / sizeof(*ptr); 1273 for (j = 0; j < macroblocks_per_line; j++) { 1274 for (k = 0; k < CXM_MACROBLOCK_HEIGHT; k++) { 1275 #if CXM_MACROBLOCK_WIDTH != 16 1276 # error CXM_MACROBLOCK_WIDTH != 16 1277 #endif 1278 *(ptr + k * words_per_line) 1279 = *src++; 1280 *(ptr + k * words_per_line + 1) 1281 = *src++; 1282 *(ptr + k * words_per_line + 2) 1283 = *src++; 1284 *(ptr + k * words_per_line + 3) 1285 = *src++; 1286 } 1287 ptr += CXM_MACROBLOCK_WIDTH / sizeof(*ptr); 1288 } 1289 } 1290 1291 sc->enc_pool.bufs[scratch].size 1292 = sc->enc_pool.bufs[current].size; 1293 1294 current = scratch; 1295 break; 1296 1297 default: 1298 break; 1299 } 1300 1301 sc->enc_pool.bufs[current].byte_order = cxm_host_byte_order; 1302 1303 return current; 1304 } 1305 1306 1307 static void 1308 cxm_encoder_dma_discard(struct cxm_softc *sc) 1309 { 1310 uint32_t parameters[3]; 1311 1312 /* Discard the DMA request */ 1313 parameters[0] = 0; 1314 parameters[1] = 0; 1315 parameters[2] = 0; 1316 if (cxm_queue_firmware_command(sc, cxm_enc_mailbox, 1317 CXM_FW_CMD_SCHED_DMA_TO_HOST, 1318 parameters, 3) == -1) { 1319 device_printf(sc->dev, 1320 "failed to discard encoder dma request\n"); 1321 return; 1322 } 1323 1324 sc->encoding_dma = -1; 1325 } 1326 1327 1328 static void 1329 cxm_encoder_dma_done(struct cxm_softc *sc) 1330 { 1331 int buffers_pending; 1332 uint32_t status; 1333 1334 if (!sc->encoding_dma) { 1335 device_printf(sc->dev, 1336 "encoder dma not already in progress\n"); 1337 return; 1338 } 1339 1340 buffers_pending = sc->encoding_dma; 1341 sc->encoding_dma = 0; 1342 1343 if (buffers_pending < 0) 1344 return; 1345 1346 status = CSR_READ_4(sc, CXM_REG_DMA_STATUS) & 0x0000000f; 1347 1348 if ((status 1349 & (CXM_DMA_ERROR_LIST | CXM_DMA_ERROR_WRITE | CXM_DMA_SUCCESS)) 1350 != CXM_DMA_SUCCESS) { 1351 device_printf(sc->dev, "encoder dma status %#x\n", 1352 (unsigned int)status); 1353 return; 1354 } 1355 1356 /* Update the books */ 1357 crit_enter(); 1358 sc->enc_pool.write = (sc->enc_pool.write + buffers_pending) 1359 % CXM_SG_BUFFERS; 1360 crit_exit(); 1361 1362 /* signal anyone requesting notification */ 1363 if (sc->enc_proc) 1364 ksignal (sc->enc_proc, sc->enc_signal); 1365 1366 /* wakeup anyone waiting for data */ 1367 wakeup(&sc->enc_pool.read); 1368 1369 /* wakeup anyone polling for data */ 1370 KNOTE(&sc->enc_kq.ki_note, 0); 1371 } 1372 1373 1374 static void 1375 cxm_encoder_dma_request(struct cxm_softc *sc) 1376 { 1377 enum cxm_byte_order byte_order; 1378 int buffers_free; 1379 int buffers_pending; 1380 unsigned int current; 1381 unsigned int i; 1382 unsigned int mailbox; 1383 unsigned int macroblocks_per_line; 1384 unsigned int nrequests; 1385 unsigned int strips; 1386 uint32_t parameters[CXM_MBX_MAX_PARAMETERS]; 1387 uint32_t type; 1388 size_t max_sg_segment; 1389 struct { 1390 size_t offset; 1391 size_t size; 1392 } requests[2]; 1393 1394 if (sc->encoding_dma) { 1395 device_printf(sc->dev, "encoder dma already in progress\n"); 1396 cxm_encoder_dma_discard(sc); 1397 return; 1398 } 1399 1400 mailbox = sc->enc_mbx 1401 + CXM_MBX_FW_DMA_MAILBOX * sizeof(struct cxm_mailbox); 1402 1403 for (i = 0; i < CXM_MBX_MAX_PARAMETERS; i++) 1404 parameters[i] 1405 = CSR_READ_4(sc, 1406 mailbox 1407 + offsetof(struct cxm_mailbox, parameters) 1408 + i * sizeof(uint32_t) 1409 ); 1410 1411 byte_order = cxm_device_mpeg_byte_order; 1412 max_sg_segment = CXM_SG_SEGMENT; 1413 nrequests = 0; 1414 type = parameters[0]; 1415 1416 switch (type) { 1417 case 0: /* MPEG */ 1418 requests[nrequests].offset = parameters[1]; 1419 requests[nrequests++].size = parameters[2]; 1420 break; 1421 1422 case 1: /* YUV */ 1423 byte_order = cxm_device_yuv12_byte_order; 1424 1425 /* 1426 * Simplify macroblock unpacking by ensuring 1427 * that strips don't span buffers. 1428 */ 1429 1430 #if CXM_MACROBLOCK_SIZE % 256 1431 # error CXM_MACROBLOCK_SIZE not a multiple of 256 1432 #endif 1433 1434 macroblocks_per_line = sc->profile->width 1435 / CXM_MACROBLOCK_WIDTH; 1436 strips = CXM_SG_SEGMENT 1437 / (macroblocks_per_line * CXM_MACROBLOCK_SIZE); 1438 max_sg_segment = strips 1439 * macroblocks_per_line * CXM_MACROBLOCK_SIZE; 1440 1441 requests[nrequests].offset = parameters[1]; /* Y */ 1442 requests[nrequests++].size = parameters[2]; 1443 requests[nrequests].offset = parameters[3]; /* UV */ 1444 requests[nrequests++].size = parameters[4]; 1445 break; 1446 1447 case 2: /* PCM (audio) */ 1448 case 3: /* VBI */ 1449 default: 1450 device_printf(sc->dev, "encoder dma type %#x unsupported\n", 1451 (unsigned int)type); 1452 cxm_encoder_dma_discard(sc); 1453 return; 1454 } 1455 1456 /* 1457 * Determine the number of buffers free at this * instant * 1458 * taking into consideration that the ring buffer wraps. 1459 */ 1460 crit_enter(); 1461 buffers_free = sc->enc_pool.read - sc->enc_pool.write; 1462 if (buffers_free <= 0) 1463 buffers_free += CXM_SG_BUFFERS; 1464 crit_exit(); 1465 1466 /* 1467 * Build the scatter / gather list taking in 1468 * consideration that the ring buffer wraps, 1469 * at least one free buffer must always be 1470 * present to mark the end of the ring buffer, 1471 * and each transfer must be a multiple of 256. 1472 */ 1473 1474 buffers_pending = 0; 1475 current = sc->enc_pool.write; 1476 1477 for (i = 0; i < nrequests; i++) { 1478 if (!requests[i].size) { 1479 device_printf(sc->dev, "encoder dma size is zero\n"); 1480 cxm_encoder_dma_discard(sc); 1481 return; 1482 } 1483 1484 while (requests[i].size) { 1485 sc->enc_pool.bufs[current].size 1486 = requests[i].size > max_sg_segment 1487 ? max_sg_segment : requests[i].size; 1488 sc->enc_pool.bufs[current].byte_order = byte_order; 1489 1490 sc->enc_sg.vaddr[buffers_pending].src 1491 = requests[i].offset; 1492 sc->enc_sg.vaddr[buffers_pending].dst 1493 = sc->enc_pool.bufs[current].baddr; 1494 sc->enc_sg.vaddr[buffers_pending].size 1495 = (sc->enc_pool.bufs[current].size + 0x000000ff) 1496 & 0xffffff00; 1497 1498 requests[i].offset += sc->enc_pool.bufs[current].size; 1499 requests[i].size -= sc->enc_pool.bufs[current].size; 1500 buffers_pending++; 1501 current = (current + 1) % CXM_SG_BUFFERS; 1502 1503 if (buffers_pending >= buffers_free) { 1504 device_printf(sc->dev, 1505 "encoder dma not enough buffer space free\n"); 1506 cxm_encoder_dma_discard(sc); 1507 return; 1508 } 1509 } 1510 } 1511 1512 /* Mark the last transfer in the list */ 1513 sc->enc_sg.vaddr[buffers_pending - 1].size |= 0x80000000; 1514 1515 /* Schedule the DMA */ 1516 parameters[0] = sc->enc_sg.baddr; 1517 parameters[1] = buffers_pending * sizeof(sc->enc_sg.vaddr[0]); 1518 parameters[2] = type; 1519 if (cxm_queue_firmware_command(sc, cxm_enc_mailbox, 1520 CXM_FW_CMD_SCHED_DMA_TO_HOST, 1521 parameters, 3) == -1) { 1522 device_printf(sc->dev, 1523 "failed to schedule encoder dma request\n"); 1524 return; 1525 } 1526 1527 /* 1528 * Record the number of pending buffers for the 1529 * benefit of cxm_encoder_dma_done. Doing this 1530 * after queuing the command doesn't introduce 1531 * a race condition since we're already in the 1532 * interrupt handler. 1533 */ 1534 1535 sc->encoding_dma = buffers_pending; 1536 } 1537 1538 1539 static int 1540 cxm_encoder_wait_for_lock(struct cxm_softc *sc) 1541 { 1542 int muted; 1543 int locked; 1544 int result; 1545 1546 locked = 1; 1547 1548 /* 1549 * Wait for the tuner to lock. 1550 */ 1551 if (sc->source == cxm_fm_source || sc->source == cxm_tuner_source) { 1552 result = cxm_tuner_wait_for_lock(sc); 1553 if (result <= 0) 1554 return result; 1555 } 1556 1557 /* 1558 * Wait for the video decoder to lock. 1559 */ 1560 if (sc->source != cxm_fm_source) { 1561 result = cxm_saa7115_wait_for_lock(sc); 1562 if (result < 0) 1563 return result; 1564 else if (result == 0) 1565 locked = 0; 1566 } 1567 1568 /* 1569 * Wait for the audio decoder to lock. 1570 */ 1571 if (sc->source == cxm_tuner_source) { 1572 muted = cxm_msp_is_muted(sc); 1573 1574 result = cxm_msp_autodetect_standard(sc); 1575 if (result < 0) 1576 return result; 1577 else if (result == 0) 1578 locked = 0; 1579 1580 if (muted == 0 && cxm_msp_unmute(sc) < 0) 1581 return -1; 1582 } 1583 1584 return locked; 1585 } 1586 1587 1588 static void 1589 cxm_mapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1590 { 1591 bus_addr_t *busaddrp; 1592 1593 /* 1594 * Only the first bus space address is needed 1595 * since it's known that the memory is physically 1596 * contiguous due to bus_dmamem_alloc. 1597 */ 1598 1599 busaddrp = (bus_addr_t *)arg; 1600 *busaddrp = segs->ds_addr; 1601 } 1602 1603 1604 /* 1605 * the boot time probe routine. 1606 */ 1607 static int 1608 cxm_probe(device_t dev) 1609 { 1610 struct cxm_dev *t; 1611 1612 t = cxm_devs; 1613 1614 while(t->name != NULL) { 1615 if ((pci_get_vendor(dev) == t->vid) && 1616 (pci_get_device(dev) == t->did)) { 1617 device_set_desc(dev, t->name); 1618 return 0; 1619 } 1620 t++; 1621 } 1622 1623 return ENXIO; 1624 } 1625 1626 1627 /* 1628 * the attach routine. 1629 */ 1630 static int 1631 cxm_attach(device_t dev) 1632 { 1633 int error; 1634 int rid; 1635 int unit; 1636 unsigned int i; 1637 uint32_t command; 1638 struct cxm_softc *sc; 1639 1640 /* Get the device data */ 1641 sc = device_get_softc(dev); 1642 unit = device_get_unit(dev); 1643 1644 sc->dev = dev; 1645 sc->type = cxm_iTVC15_type; 1646 1647 switch(pci_get_device(dev)) { 1648 case PCI_PRODUCT_ICOMPRESSION_ITVC16: 1649 sc->type = cxm_iTVC16_type; 1650 break; 1651 1652 default: 1653 break; 1654 } 1655 1656 /* 1657 * Enable bus mastering and memory mapped I/O. 1658 */ 1659 pci_enable_busmaster(dev); 1660 pci_enable_io(dev, SYS_RES_MEMORY); 1661 command = pci_read_config(dev, PCIR_COMMAND, 4); 1662 1663 if (!(command & PCIM_CMD_MEMEN)) { 1664 device_printf(dev, "failed to enable memory mappings\n"); 1665 error = ENXIO; 1666 goto fail; 1667 } 1668 1669 /* 1670 * Map control/status registers. 1671 */ 1672 rid = CXM_RID; 1673 sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 1674 0, ~0, 1, RF_ACTIVE); 1675 1676 if (!sc->mem_res) { 1677 device_printf(dev, "could not map memory\n"); 1678 error = ENXIO; 1679 goto fail; 1680 } 1681 1682 sc->btag = rman_get_bustag(sc->mem_res); 1683 sc->bhandle = rman_get_bushandle(sc->mem_res); 1684 1685 /* 1686 * Attach the I2C bus. 1687 */ 1688 sc->cxm_iic = device_add_child(dev, "cxm_iic", unit); 1689 1690 if (!sc->cxm_iic) { 1691 device_printf(dev, "could not add cxm_iic\n"); 1692 error = ENXIO; 1693 goto fail; 1694 } 1695 1696 error = device_probe_and_attach(sc->cxm_iic); 1697 1698 if (error) { 1699 device_printf(dev, "could not attach cxm_iic\n"); 1700 goto fail; 1701 } 1702 1703 /* 1704 * Initialize the tuner. 1705 */ 1706 if (cxm_tuner_init(sc) < 0) { 1707 device_printf(dev, "could not initialize tuner\n"); 1708 error = ENXIO; 1709 goto fail; 1710 } 1711 1712 /* 1713 * Initialize the SAA7115. 1714 */ 1715 if (cxm_saa7115_init(sc) < 0) { 1716 device_printf(dev, "could not initialize video decoder\n"); 1717 error = ENXIO; 1718 goto fail; 1719 } 1720 1721 /* 1722 * Initialize the MSP3400. 1723 */ 1724 if (cxm_msp_init(sc) < 0) { 1725 device_printf(dev, "could not initialize audio decoder\n"); 1726 error = ENXIO; 1727 goto fail; 1728 } 1729 1730 /* 1731 * Initialize the IR Remote. 1732 */ 1733 if (cxm_ir_init(sc) < 0) { 1734 device_printf(dev, "could not initialize IR remote\n"); 1735 error = ENXIO; 1736 goto fail; 1737 } 1738 1739 sc->dec_mbx = -1; 1740 sc->enc_mbx = -1; 1741 1742 /* 1743 * Disable the Conexant device. 1744 * 1745 * This is done * after * attaching the I2C bus so 1746 * cxm_stop_hardware can mute the video and audio 1747 * decoders. 1748 */ 1749 cxm_stop_hardware(sc); 1750 1751 /* 1752 * Allocate our interrupt. 1753 */ 1754 rid = 0; 1755 sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1756 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); 1757 1758 if (sc->irq_res == NULL) { 1759 device_printf(dev, "could not map interrupt\n"); 1760 error = ENXIO; 1761 goto fail; 1762 } 1763 1764 error = bus_setup_intr(dev, sc->irq_res, 0, 1765 cxm_intr, sc, &sc->ih_cookie, NULL); 1766 if (error) { 1767 device_printf(dev, "could not setup irq\n"); 1768 goto fail; 1769 1770 } 1771 1772 /* 1773 * Allocate a DMA tag for the parent bus. 1774 */ 1775 error = bus_dma_tag_create(NULL, 1, 0, 1776 BUS_SPACE_MAXADDR_32BIT, 1777 BUS_SPACE_MAXADDR, NULL, NULL, 1778 BUS_SPACE_MAXSIZE_32BIT, 1, 1779 BUS_SPACE_MAXSIZE_32BIT, 0, 1780 &sc->parent_dmat); 1781 if (error) { 1782 device_printf(dev, "could not create parent bus DMA tag\n"); 1783 goto fail; 1784 } 1785 1786 /* 1787 * Allocate a DMA tag for the encoder buffers. 1788 */ 1789 error = bus_dma_tag_create(sc->parent_dmat, 256, 0, 1790 BUS_SPACE_MAXADDR_32BIT, 1791 BUS_SPACE_MAXADDR, NULL, NULL, 1792 CXM_SG_SEGMENT, 1, 1793 BUS_SPACE_MAXSIZE_32BIT, 0, 1794 &sc->enc_pool.dmat); 1795 if (error) { 1796 device_printf(dev, 1797 "could not create encoder buffer DMA tag\n"); 1798 goto fail; 1799 } 1800 1801 for (i = 0; i < CXM_SG_BUFFERS; i++) { 1802 1803 /* 1804 * Allocate the encoder buffer. 1805 */ 1806 error = bus_dmamem_alloc(sc->enc_pool.dmat, 1807 (void **)&sc->enc_pool.bufs[i].vaddr, 1808 BUS_DMA_NOWAIT, 1809 &sc->enc_pool.bufs[i].dmamap); 1810 if (error) { 1811 device_printf(dev, 1812 "could not allocate encoder buffer\n"); 1813 goto fail; 1814 } 1815 1816 /* 1817 * Map the encoder buffer. 1818 */ 1819 error = bus_dmamap_load(sc->enc_pool.dmat, 1820 sc->enc_pool.bufs[i].dmamap, 1821 sc->enc_pool.bufs[i].vaddr, 1822 CXM_SG_SEGMENT, 1823 cxm_mapmem, 1824 &sc->enc_pool.bufs[i].baddr, 0); 1825 if (error) { 1826 device_printf(dev, "could not map encoder buffer\n"); 1827 goto fail; 1828 } 1829 } 1830 1831 /* 1832 * Allocate a DMA tag for the scatter / gather list. 1833 */ 1834 error = bus_dma_tag_create(sc->parent_dmat, 1, 0, 1835 BUS_SPACE_MAXADDR_32BIT, 1836 BUS_SPACE_MAXADDR, NULL, NULL, 1837 CXM_SG_BUFFERS 1838 * sizeof(struct cxm_sg_entry), 1, 1839 BUS_SPACE_MAXSIZE_32BIT, 0, 1840 &sc->enc_sg.dmat); 1841 if (error) { 1842 device_printf(dev, 1843 "could not create scatter / gather DMA tag\n"); 1844 goto fail; 1845 } 1846 1847 /* 1848 * Allocate the scatter / gather list. 1849 */ 1850 error = bus_dmamem_alloc(sc->enc_sg.dmat, (void **)&sc->enc_sg.vaddr, 1851 BUS_DMA_NOWAIT, &sc->enc_sg.dmamap); 1852 if (error) { 1853 device_printf(dev, 1854 "could not allocate scatter / gather list\n"); 1855 goto fail; 1856 } 1857 1858 /* 1859 * Map the scatter / gather list. 1860 */ 1861 error = bus_dmamap_load(sc->enc_sg.dmat, sc->enc_sg.dmamap, 1862 sc->enc_sg.vaddr, 1863 CXM_SG_BUFFERS * sizeof(struct cxm_sg_entry), 1864 cxm_mapmem, &sc->enc_sg.baddr, 0); 1865 if (error) { 1866 device_printf(dev, "could not map scatter / gather list\n"); 1867 goto fail; 1868 } 1869 1870 /* 1871 * Initialize the hardware. 1872 */ 1873 if (cxm_init_hardware(sc) < 0) { 1874 device_printf(dev, "could not initialize hardware\n"); 1875 error = ENXIO; 1876 goto fail; 1877 } 1878 1879 sc->profile = &dvd_full_d1_ntsc_profile; 1880 1881 sc->source = cxm_tuner_source; 1882 1883 1884 /* make the device entries */ 1885 sc->cxm_dev_t = make_dev(&cxm_ops, unit, 1886 0, 0, 0444, "cxm%d", unit); 1887 1888 return 0; 1889 1890 fail: 1891 if (sc->enc_sg.baddr) 1892 bus_dmamap_unload(sc->enc_sg.dmat, sc->enc_sg.dmamap); 1893 if (sc->enc_sg.vaddr) 1894 bus_dmamem_free(sc->enc_sg.dmat, sc->enc_sg.vaddr, 1895 sc->enc_sg.dmamap); 1896 if (sc->enc_sg.dmat) 1897 bus_dma_tag_destroy(sc->enc_sg.dmat); 1898 1899 for (i = 0; i < CXM_SG_BUFFERS; i++) { 1900 if (sc->enc_pool.bufs[i].baddr) 1901 bus_dmamap_unload(sc->enc_pool.dmat, 1902 sc->enc_pool.bufs[i].dmamap); 1903 if (sc->enc_pool.bufs[i].vaddr) 1904 bus_dmamem_free(sc->enc_pool.dmat, 1905 sc->enc_pool.bufs[i].vaddr, 1906 sc->enc_pool.bufs[i].dmamap); 1907 } 1908 1909 if (sc->enc_pool.dmat) 1910 bus_dma_tag_destroy(sc->enc_pool.dmat); 1911 1912 if (sc->parent_dmat) 1913 bus_dma_tag_destroy(sc->parent_dmat); 1914 1915 /* 1916 * Detach the I2C bus. 1917 * 1918 * This is done * after * deallocating the scatter / gather 1919 * list and buffers so the kernel has a better chance of 1920 * gracefully handling a memory shortage. 1921 * 1922 * Detach the children before recursively deleting 1923 * in case a child has a pointer to a grandchild 1924 * which is used by the child's detach routine. 1925 */ 1926 bus_generic_detach(dev); 1927 if (sc->cxm_iic) 1928 device_delete_child(dev, sc->cxm_iic); 1929 1930 if (sc->ih_cookie) 1931 bus_teardown_intr(dev, sc->irq_res, sc->ih_cookie); 1932 if (sc->irq_res) 1933 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); 1934 if (sc->mem_res) 1935 bus_release_resource(dev, SYS_RES_MEMORY, CXM_RID, sc->mem_res); 1936 1937 return error; 1938 } 1939 1940 /* 1941 * the detach routine. 1942 */ 1943 static int 1944 cxm_detach(device_t dev) 1945 { 1946 unsigned int i; 1947 struct cxm_softc *sc; 1948 device_t child; 1949 1950 /* Get the device data */ 1951 sc = device_get_softc(dev); 1952 1953 /* Disable the Conexant device. */ 1954 cxm_stop_hardware(sc); 1955 1956 /* Unregister the /dev/cxmN device. */ 1957 dev_ops_remove_minor(&cxm_ops, /*0, */device_get_unit(dev)); 1958 1959 /* 1960 * Deallocate scatter / gather list and buffers. 1961 */ 1962 bus_dmamap_unload(sc->enc_sg.dmat, sc->enc_sg.dmamap); 1963 bus_dmamem_free(sc->enc_sg.dmat, sc->enc_sg.vaddr, sc->enc_sg.dmamap); 1964 1965 bus_dma_tag_destroy(sc->enc_sg.dmat); 1966 1967 for (i = 0; i < CXM_SG_BUFFERS; i++) { 1968 bus_dmamap_unload(sc->enc_pool.dmat, 1969 sc->enc_pool.bufs[i].dmamap); 1970 bus_dmamem_free(sc->enc_pool.dmat, sc->enc_pool.bufs[i].vaddr, 1971 sc->enc_pool.bufs[i].dmamap); 1972 } 1973 1974 bus_dma_tag_destroy(sc->enc_pool.dmat); 1975 1976 bus_dma_tag_destroy(sc->parent_dmat); 1977 1978 /* 1979 * Detach the I2C bus. 1980 * 1981 * This is done * after * deallocating the scatter / gather 1982 * list and buffers so the kernel has a better chance of 1983 * gracefully handling a memory shortage. 1984 * 1985 * Detach the children before recursively deleting 1986 * in case a child has a pointer to a grandchild 1987 * which is used by the child's detach routine. 1988 * 1989 * Remember the child before detaching so we can 1990 * delete it (bus_generic_detach indirectly zeroes 1991 * sc->child_dev). 1992 */ 1993 child = sc->cxm_iic; 1994 bus_generic_detach(dev); 1995 if (child) 1996 device_delete_child(dev, child); 1997 1998 /* Deallocate resources. */ 1999 bus_teardown_intr(dev, sc->irq_res, sc->ih_cookie); 2000 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); 2001 bus_release_resource(dev, SYS_RES_MEMORY, CXM_RID, sc->mem_res); 2002 2003 return 0; 2004 } 2005 2006 /* 2007 * the shutdown routine. 2008 */ 2009 static int 2010 cxm_shutdown(device_t dev) 2011 { 2012 struct cxm_softc *sc = device_get_softc(dev); 2013 2014 /* Disable the Conexant device. */ 2015 cxm_stop_hardware(sc); 2016 2017 return 0; 2018 } 2019 2020 /* 2021 * the interrupt routine. 2022 */ 2023 static void 2024 cxm_intr(void *arg) 2025 { 2026 uint32_t status; 2027 struct cxm_softc *sc; 2028 2029 /* Get the device data */ 2030 sc = (struct cxm_softc *)arg; 2031 2032 status = CSR_READ_4(sc, CXM_REG_IRQ_STATUS); 2033 2034 status &= ~sc->irq_mask; 2035 2036 if (!status) 2037 return; 2038 2039 /* Process DMA done before handling a new DMA request or EOS */ 2040 if (status & CXM_IRQ_ENC_DMA_DONE) 2041 cxm_encoder_dma_done(sc); 2042 2043 if (status & CXM_IRQ_ENC_DMA_REQUEST) 2044 cxm_encoder_dma_request(sc); 2045 2046 if (status & CXM_IRQ_ENC_EOS) { 2047 sc->encoding_eos = 1; 2048 wakeup(&sc->encoding_eos); 2049 } 2050 2051 cxm_set_irq_status(sc, status); 2052 } 2053 2054 2055 /* 2056 * the child detached routine. 2057 */ 2058 static void 2059 cxm_child_detached(device_t dev, device_t child) 2060 { 2061 struct cxm_softc *sc; 2062 2063 /* Get the device data */ 2064 sc = device_get_softc(dev); 2065 2066 if (child == sc->cxm_iic) 2067 sc->cxm_iic = NULL; 2068 } 2069 2070 2071 static int 2072 cxm_read_ivar(device_t dev, device_t child, int index, uintptr_t* val) 2073 { 2074 struct cxm_softc *sc; 2075 2076 /* Get the device data */ 2077 sc = device_get_softc(dev); 2078 2079 switch (index) { 2080 case CXM_IVAR_BHANDLE: 2081 *(bus_space_handle_t **)val = &sc->bhandle; 2082 break; 2083 2084 case CXM_IVAR_BTAG: 2085 *(bus_space_tag_t **)val = &sc->btag; 2086 break; 2087 2088 case CXM_IVAR_IICBUS: 2089 *(device_t **)val = &sc->iicbus; 2090 break; 2091 2092 default: 2093 return ENOENT; 2094 } 2095 2096 return 0; 2097 } 2098 2099 2100 static int 2101 cxm_write_ivar(device_t dev, device_t child, int index, uintptr_t val) 2102 { 2103 struct cxm_softc *sc; 2104 2105 /* Get the device data */ 2106 sc = device_get_softc(dev); 2107 2108 switch (index) { 2109 case CXM_IVAR_BHANDLE: 2110 return EINVAL; 2111 2112 case CXM_IVAR_BTAG: 2113 return EINVAL; 2114 2115 case CXM_IVAR_IICBUS: 2116 if (sc->iicbus) 2117 return EINVAL; 2118 sc->iicbus = val ? *(device_t *)val : NULL; 2119 break; 2120 2121 default: 2122 return ENOENT; 2123 } 2124 2125 return 0; 2126 } 2127 2128 2129 /*--------------------------------------------------------- 2130 ** 2131 ** Conexant iTVC15 / iTVC16 character device driver routines 2132 ** 2133 **--------------------------------------------------------- 2134 */ 2135 2136 #define UNIT(x) ((x) & 0x0f) 2137 #define FUNCTION(x) (x >> 4) 2138 2139 /* 2140 * 2141 */ 2142 static int 2143 cxm_open(struct dev_open_args *ap) 2144 { 2145 cdev_t dev = ap->a_head.a_dev; 2146 int unit; 2147 struct cxm_softc *sc; 2148 2149 unit = UNIT(minor(dev)); 2150 2151 /* Get the device data */ 2152 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2153 if (sc == NULL) { 2154 /* the device is no longer valid/functioning */ 2155 return ENXIO; 2156 } 2157 2158 if (sc->is_opened) 2159 return EBUSY; 2160 2161 sc->is_opened = 1; 2162 sc->mpeg = 1; 2163 2164 /* Record that the device is now busy */ 2165 device_busy(devclass_get_device(cxm_devclass, unit)); 2166 2167 return 0; 2168 } 2169 2170 2171 /* 2172 * 2173 */ 2174 static int 2175 cxm_close(struct dev_close_args *ap) 2176 { 2177 cdev_t dev = ap->a_head.a_dev; 2178 int unit; 2179 struct cxm_softc *sc; 2180 2181 unit = UNIT(minor(dev)); 2182 2183 /* Get the device data */ 2184 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2185 if (sc == NULL) { 2186 /* the device is no longer valid/functioning */ 2187 return ENXIO; 2188 } 2189 2190 if (cxm_stop_encoder(sc) < 0) 2191 return ENXIO; 2192 2193 sc->enc_pool.offset = 0; 2194 sc->enc_pool.read = 0; 2195 sc->enc_pool.write = 0; 2196 2197 sc->enc_proc = NULL; 2198 sc->enc_signal = 0; 2199 2200 device_unbusy(devclass_get_device(cxm_devclass, unit)); 2201 2202 sc->is_opened = 0; 2203 2204 return 0; 2205 } 2206 2207 2208 /* 2209 * 2210 */ 2211 static int 2212 cxm_read(struct dev_read_args *ap) 2213 { 2214 cdev_t dev = ap->a_head.a_dev; 2215 int buffers_available; 2216 int buffers_read; 2217 int error; 2218 int unit; 2219 unsigned int current; 2220 unsigned int i; 2221 size_t nbytes; 2222 size_t offset; 2223 struct cxm_softc *sc; 2224 2225 unit = UNIT(minor(dev)); 2226 2227 /* Get the device data */ 2228 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2229 if (sc == NULL) { 2230 /* the device is no longer valid/functioning */ 2231 return ENXIO; 2232 } 2233 2234 /* Only trigger the encoder if the ring buffer is empty */ 2235 if (!sc->encoding && sc->enc_pool.read == sc->enc_pool.write) { 2236 if (cxm_start_encoder(sc) < 0) 2237 return ENXIO; 2238 if (ap->a_ioflag & IO_NDELAY) 2239 return EWOULDBLOCK; 2240 } 2241 2242 buffers_available = 0; 2243 2244 crit_enter(); 2245 while (sc->enc_pool.read == sc->enc_pool.write) { 2246 error = tsleep(&sc->enc_pool.read, PCATCH, "cxmrd", 0); 2247 if (error) { 2248 crit_exit(); 2249 return error; 2250 } 2251 } 2252 2253 /* 2254 * Determine the number of buffers available at this * instant * 2255 * taking in consideration that the ring buffer wraps. 2256 */ 2257 buffers_available = sc->enc_pool.write - sc->enc_pool.read; 2258 if (buffers_available < 0) 2259 buffers_available += CXM_SG_BUFFERS; 2260 crit_exit(); 2261 2262 offset = sc->enc_pool.offset; 2263 2264 for (buffers_read = 0, i = sc->enc_pool.read; 2265 buffers_read != buffers_available && ap->a_uio->uio_resid; 2266 buffers_read++, i = (i + 1) % CXM_SG_BUFFERS) { 2267 2268 current = cxm_encoder_fixup_byte_order (sc, i, offset); 2269 2270 nbytes = sc->enc_pool.bufs[current].size - offset; 2271 2272 /* Don't transfer more than requested */ 2273 if (nbytes > ap->a_uio->uio_resid) 2274 nbytes = ap->a_uio->uio_resid; 2275 2276 error = uiomove(sc->enc_pool.bufs[current].vaddr + offset, 2277 nbytes, ap->a_uio); 2278 if (error) 2279 return error; 2280 2281 offset += nbytes; 2282 2283 /* Handle a partial read of a buffer */ 2284 if (!ap->a_uio->uio_resid && offset != sc->enc_pool.bufs[i].size) 2285 break; 2286 2287 offset = 0; 2288 } 2289 2290 sc->enc_pool.offset = offset; 2291 2292 /* Update the books */ 2293 crit_enter(); 2294 sc->enc_pool.read = (sc->enc_pool.read + buffers_read) 2295 % CXM_SG_BUFFERS; 2296 crit_exit(); 2297 2298 return 0; 2299 } 2300 2301 2302 /* 2303 * 2304 */ 2305 static int 2306 cxm_ioctl(struct dev_ioctl_args *ap) 2307 { 2308 cdev_t dev = ap->a_head.a_dev; 2309 int brightness; 2310 int chroma_saturation; 2311 int contrast; 2312 int fps; 2313 int hue; 2314 int result; 2315 int status; 2316 int unit; 2317 unsigned int i; 2318 unsigned int sig; 2319 unsigned long freq; 2320 struct cxm_softc *sc; 2321 enum cxm_source source; 2322 struct bktr_capture_area *cap; 2323 struct bktr_remote *remote; 2324 2325 unit = UNIT(minor(dev)); 2326 2327 /* Get the device data */ 2328 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2329 if (sc == NULL) { 2330 /* the device is no longer valid/functioning */ 2331 return ENXIO; 2332 } 2333 2334 switch (ap->a_cmd) { 2335 case BT848_GAUDIO: 2336 switch (cxm_msp_selected_source(sc)) { 2337 case cxm_tuner_source: 2338 *(int *) ap->a_data = AUDIO_TUNER; 2339 break; 2340 2341 case cxm_line_in_source_composite: 2342 case cxm_line_in_source_svideo: 2343 *(int *) ap->a_data = AUDIO_EXTERN; 2344 break; 2345 2346 case cxm_fm_source: 2347 *(int *) ap->a_data = AUDIO_INTERN; 2348 break; 2349 2350 default: 2351 return ENXIO; 2352 } 2353 2354 if (cxm_msp_is_muted(sc) == 1) 2355 *(int *) ap->a_data |= AUDIO_MUTE; 2356 break; 2357 2358 case BT848_SAUDIO: 2359 source = cxm_unknown_source; 2360 2361 switch (*(int *) ap->a_data) { 2362 case AUDIO_TUNER: 2363 source = cxm_tuner_source; 2364 break; 2365 2366 case AUDIO_EXTERN: 2367 source = cxm_line_in_source_composite; 2368 break; 2369 2370 case AUDIO_INTERN: 2371 source = cxm_fm_source; 2372 break; 2373 2374 case AUDIO_MUTE: 2375 if (cxm_msp_mute(sc) < 0) 2376 return ENXIO; 2377 return 0; 2378 2379 case AUDIO_UNMUTE: 2380 if (cxm_msp_unmute(sc) < 0) 2381 return ENXIO; 2382 return 0; 2383 2384 default: 2385 return EINVAL; 2386 } 2387 2388 if (sc->encoding) { 2389 2390 /* 2391 * Switching between audio + video and audio only 2392 * subtypes isn't supported while encoding. 2393 */ 2394 2395 if (source != sc->source 2396 && (source == cxm_fm_source 2397 || sc->source == cxm_fm_source)) 2398 return EBUSY; 2399 } 2400 2401 if (cxm_pause_encoder(sc) < 0) 2402 return ENXIO; 2403 2404 if (cxm_msp_select_source(sc, source) < 0) 2405 return ENXIO; 2406 2407 if (source == cxm_fm_source) 2408 sc->source = source; 2409 2410 result = cxm_encoder_wait_for_lock(sc); 2411 if (result < 0) 2412 return ENXIO; 2413 else if (result == 0) 2414 return EINVAL; 2415 2416 if (cxm_unpause_encoder(sc) < 0) 2417 return ENXIO; 2418 break; 2419 2420 case BT848_GBRIG: 2421 brightness = cxm_saa7115_get_brightness(sc); 2422 2423 if (brightness < 0) 2424 return ENXIO; 2425 2426 /* 2427 * Brooktree brightness: 2428 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6% 2429 */ 2430 *(int *)ap->a_data = (int)(unsigned char)brightness - 128; 2431 break; 2432 2433 case BT848_SBRIG: 2434 2435 /* 2436 * Brooktree brightness: 2437 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6% 2438 */ 2439 brightness = *(int *)ap->a_data + 128; 2440 2441 if (cxm_saa7115_set_brightness(sc, brightness) < 0) 2442 return ENXIO; 2443 break; 2444 2445 case METEORGBRIG: 2446 brightness = cxm_saa7115_get_brightness(sc); 2447 2448 if (brightness < 0) 2449 return ENXIO; 2450 2451 *(unsigned char *)ap->a_data = (unsigned char)brightness; 2452 break; 2453 2454 case METEORSBRIG: 2455 brightness = *(unsigned char *)ap->a_data; 2456 2457 if (cxm_saa7115_set_brightness(sc, brightness) < 0) 2458 return ENXIO; 2459 break; 2460 2461 case BT848_GCSAT: 2462 chroma_saturation = cxm_saa7115_get_chroma_saturation(sc); 2463 2464 if (chroma_saturation < 0) 2465 return ENXIO; 2466 2467 /* 2468 * Brooktree chroma saturation: 2469 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18% 2470 */ 2471 *(int *)ap->a_data = ((signed char)chroma_saturation > 0) 2472 ? (chroma_saturation * 4 - 2) : 0; 2473 break; 2474 2475 case BT848_SCSAT: 2476 2477 /* 2478 * Brooktree chroma saturation: 2479 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18% 2480 */ 2481 chroma_saturation = (*(int *)ap->a_data & 0x1ff) < 510 2482 ? ((*(int *)ap->a_data & 0x1ff) + 2) / 4 : 127; 2483 2484 if (cxm_saa7115_set_chroma_saturation(sc, chroma_saturation) 2485 < 0) 2486 return ENXIO; 2487 2488 break; 2489 2490 case METEORGCSAT: 2491 chroma_saturation = cxm_saa7115_get_chroma_saturation(sc); 2492 2493 if (chroma_saturation < 0) 2494 return ENXIO; 2495 2496 *(unsigned char *)ap->a_data = (unsigned char)chroma_saturation; 2497 break; 2498 2499 case METEORSCSAT: 2500 chroma_saturation = *(unsigned char *)ap->a_data; 2501 2502 if (cxm_saa7115_set_chroma_saturation(sc, chroma_saturation) 2503 < 0) 2504 return ENXIO; 2505 break; 2506 2507 case METEORGCONT: 2508 contrast = cxm_saa7115_get_contrast(sc); 2509 2510 if (contrast < 0) 2511 return ENXIO; 2512 2513 *(unsigned char *)ap->a_data = (unsigned char)contrast; 2514 break; 2515 2516 case METEORSCONT: 2517 contrast = *(unsigned char *)ap->a_data; 2518 2519 if (cxm_saa7115_set_contrast(sc, contrast) < 0) 2520 return ENXIO; 2521 break; 2522 2523 case BT848_GHUE: 2524 hue = cxm_saa7115_get_hue(sc); 2525 2526 if (hue < 0) 2527 return ENXIO; 2528 2529 *(int *)ap->a_data = (signed char)hue; 2530 break; 2531 2532 case BT848_SHUE: 2533 hue = *(int *)ap->a_data; 2534 2535 if (cxm_saa7115_set_hue(sc, hue) < 0) 2536 return ENXIO; 2537 break; 2538 2539 case METEORGHUE: 2540 hue = cxm_saa7115_get_hue(sc); 2541 2542 if (hue < 0) 2543 return ENXIO; 2544 2545 *(signed char *)ap->a_data = (signed char)hue; 2546 break; 2547 2548 case METEORSHUE: 2549 hue = *(signed char *)ap->a_data; 2550 2551 if (cxm_saa7115_set_hue(sc, hue) < 0) 2552 return ENXIO; 2553 break; 2554 2555 case METEORCAPTUR: 2556 switch (*(int *) ap->a_data) { 2557 case METEOR_CAP_CONTINOUS: 2558 if (cxm_start_encoder(sc) < 0) 2559 return ENXIO; 2560 break; 2561 2562 case METEOR_CAP_STOP_CONT: 2563 if (cxm_stop_encoder(sc) < 0) 2564 return ENXIO; 2565 break; 2566 2567 default: 2568 return EINVAL; 2569 } 2570 break; 2571 2572 case BT848_GCAPAREA: 2573 cap = (struct bktr_capture_area *)ap->a_data; 2574 memset (cap, 0, sizeof (*cap)); 2575 cap->x_offset = 0; 2576 cap->y_offset = 0; 2577 cap->x_size = sc->profile->width; 2578 cap->y_size = sc->profile->height; 2579 break; 2580 2581 case BT848_SCAPAREA: 2582 if (sc->encoding) 2583 return EBUSY; 2584 2585 cap = (struct bktr_capture_area *)ap->a_data; 2586 if (cap->x_offset || cap->y_offset 2587 || (cap->x_size % CXM_MACROBLOCK_WIDTH) 2588 || (cap->y_size % CXM_MACROBLOCK_HEIGHT)) 2589 return EINVAL; 2590 2591 /* 2592 * Setting the width and height has the side effect of 2593 * chosing between the VCD, SVCD, and DVD profiles. 2594 */ 2595 2596 for (i = 0; i < NUM_ELEMENTS(codec_profiles); i++) 2597 if (codec_profiles[i]->width == cap->x_size 2598 && codec_profiles[i]->height == cap->y_size) 2599 break; 2600 2601 if (i >= NUM_ELEMENTS(codec_profiles)) 2602 return EINVAL; 2603 2604 sc->profile = codec_profiles[i]; 2605 break; 2606 2607 case BT848GFMT: 2608 switch (cxm_saa7115_detected_format(sc)) { 2609 case cxm_ntsc_60hz_source_format: 2610 *(unsigned long *)ap->a_data = BT848_IFORM_F_NTSCM; 2611 break; 2612 2613 case cxm_pal_50hz_source_format: 2614 *(unsigned long *)ap->a_data = BT848_IFORM_F_PALBDGHI; 2615 break; 2616 2617 case cxm_secam_50hz_source_format: 2618 *(unsigned long *)ap->a_data = BT848_IFORM_F_SECAM; 2619 break; 2620 2621 case cxm_pal_60hz_source_format: 2622 *(unsigned long *)ap->a_data = BT848_IFORM_F_PALM; 2623 break; 2624 2625 case cxm_bw_50hz_source_format: 2626 case cxm_bw_60hz_source_format: 2627 case cxm_ntsc_50hz_source_format: 2628 *(unsigned long *)ap->a_data = BT848_IFORM_F_AUTO; 2629 break; 2630 2631 default: 2632 return ENXIO; 2633 } 2634 break; 2635 2636 case METEORGFMT: 2637 switch (cxm_saa7115_detected_format(sc)) { 2638 case cxm_ntsc_60hz_source_format: 2639 *(unsigned long *)ap->a_data = METEOR_FMT_NTSC; 2640 break; 2641 2642 case cxm_pal_50hz_source_format: 2643 *(unsigned long *)ap->a_data = METEOR_FMT_PAL; 2644 break; 2645 2646 case cxm_secam_50hz_source_format: 2647 *(unsigned long *)ap->a_data = METEOR_FMT_SECAM; 2648 break; 2649 2650 case cxm_bw_50hz_source_format: 2651 case cxm_bw_60hz_source_format: 2652 case cxm_ntsc_50hz_source_format: 2653 case cxm_pal_60hz_source_format: 2654 *(unsigned long *)ap->a_data = METEOR_FMT_AUTOMODE; 2655 break; 2656 2657 default: 2658 return ENXIO; 2659 } 2660 break; 2661 2662 case METEORGFPS: 2663 fps = cxm_saa7115_detected_fps(sc); 2664 2665 if (fps < 0) 2666 return ENXIO; 2667 2668 *(unsigned short *)ap->a_data = fps; 2669 break; 2670 2671 case METEORGINPUT: 2672 switch (sc->source) { 2673 case cxm_tuner_source: 2674 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV1; 2675 break; 2676 2677 case cxm_line_in_source_composite: 2678 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV2; 2679 break; 2680 2681 case cxm_line_in_source_svideo: 2682 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV_SVIDEO; 2683 break; 2684 2685 default: 2686 return ENXIO; 2687 } 2688 break; 2689 2690 case METEORSINPUT: 2691 source = cxm_unknown_source; 2692 2693 switch (*(unsigned long *)ap->a_data & 0xf000) { 2694 case METEOR_INPUT_DEV1: 2695 source = cxm_tuner_source; 2696 break; 2697 2698 case METEOR_INPUT_DEV2: 2699 source = cxm_line_in_source_composite; 2700 break; 2701 2702 case METEOR_INPUT_DEV_SVIDEO: 2703 source = cxm_line_in_source_svideo; 2704 break; 2705 2706 default: 2707 return EINVAL; 2708 } 2709 2710 if (sc->encoding) { 2711 2712 /* 2713 * Switching between audio + video and audio only 2714 * subtypes isn't supported while encoding. 2715 */ 2716 2717 if (source != sc->source 2718 && (source == cxm_fm_source 2719 || sc->source == cxm_fm_source)) 2720 return EBUSY; 2721 } 2722 2723 if (cxm_pause_encoder(sc) < 0) 2724 return ENXIO; 2725 2726 if (cxm_saa7115_select_source(sc, source) < 0) 2727 return ENXIO; 2728 if (cxm_msp_select_source(sc, source) < 0) 2729 return ENXIO; 2730 sc->source = source; 2731 2732 result = cxm_encoder_wait_for_lock(sc); 2733 if (result < 0) 2734 return ENXIO; 2735 else if (result == 0) 2736 return EINVAL; 2737 2738 if (cxm_unpause_encoder(sc) < 0) 2739 return ENXIO; 2740 break; 2741 2742 case METEORGSIGNAL: 2743 *(unsigned int *)ap->a_data = sc->enc_signal; 2744 break; 2745 2746 case METEORSSIGNAL: 2747 sig = *(unsigned int *)ap->a_data; 2748 2749 if (!_SIG_VALID(sig)) 2750 return EINVAL; 2751 2752 /* 2753 * Historically, applications used METEOR_SIG_MODE_MASK 2754 * to reset signal delivery. 2755 */ 2756 if (sig == METEOR_SIG_MODE_MASK) 2757 sig = 0; 2758 2759 crit_enter(); 2760 sc->enc_proc = sig ? curproc : NULL; 2761 sc->enc_signal = sig; 2762 crit_exit(); 2763 break; 2764 2765 case RADIO_GETFREQ: 2766 /* Convert from kHz to MHz * 100 */ 2767 freq = sc->tuner_freq / 10; 2768 2769 *(unsigned int *)ap->a_data = freq; 2770 break; 2771 2772 case RADIO_SETFREQ: 2773 if (sc->source == cxm_fm_source) 2774 if (cxm_pause_encoder(sc) < 0) 2775 return ENXIO; 2776 2777 /* Convert from MHz * 100 to kHz */ 2778 freq = *(unsigned int *)ap->a_data * 10; 2779 2780 if (cxm_tuner_select_frequency(sc, cxm_tuner_fm_freq_type, 2781 freq) < 0) 2782 return ENXIO; 2783 2784 /* 2785 * Explicitly wait for the tuner lock so we 2786 * can indicate if there's a station present. 2787 */ 2788 if (cxm_tuner_wait_for_lock(sc) < 0) 2789 return EINVAL; 2790 2791 result = cxm_encoder_wait_for_lock(sc); 2792 if (result < 0) 2793 return ENXIO; 2794 else if (result == 0) 2795 return EINVAL; 2796 2797 if (sc->source == cxm_fm_source) 2798 if (cxm_unpause_encoder(sc) < 0) 2799 return ENXIO; 2800 break; 2801 2802 case TVTUNER_GETAFC: 2803 *(int *)ap->a_data = sc->tuner_afc; 2804 break; 2805 2806 case TVTUNER_SETAFC: 2807 sc->tuner_afc = (*(int *)ap->a_data != 0); 2808 break; 2809 2810 case TVTUNER_GETTYPE: 2811 *(unsigned int *)ap->a_data = cxm_tuner_selected_channel_set(sc); 2812 break; 2813 2814 case TVTUNER_SETTYPE: 2815 if (cxm_tuner_select_channel_set(sc, *(unsigned int *)ap->a_data) < 0) 2816 return EINVAL; 2817 break; 2818 2819 case TVTUNER_SETCHNL: 2820 if (sc->source == cxm_tuner_source) 2821 if (cxm_pause_encoder(sc) < 0) 2822 return ENXIO; 2823 2824 if (cxm_tuner_select_channel(sc, *(unsigned int *)ap->a_data) < 0) 2825 return ENXIO; 2826 2827 if (sc->tuner_afc) 2828 if (cxm_tuner_apply_afc(sc) < 0) 2829 return EINVAL; 2830 2831 /* 2832 * Explicitly wait for the tuner lock so we 2833 * can indicate if there's a station present. 2834 */ 2835 if (cxm_tuner_wait_for_lock(sc) < 0) 2836 return EINVAL; 2837 2838 result = cxm_encoder_wait_for_lock(sc); 2839 if (result < 0) 2840 return ENXIO; 2841 else if (result == 0) 2842 return EINVAL; 2843 2844 if (sc->source == cxm_tuner_source) 2845 if (cxm_unpause_encoder(sc) < 0) 2846 return ENXIO; 2847 break; 2848 2849 case TVTUNER_GETFREQ: 2850 /* Convert from kHz to MHz * 16 */ 2851 freq = (sc->tuner_freq * 16) / 1000; 2852 2853 *(unsigned int *)ap->a_data = freq; 2854 break; 2855 2856 case TVTUNER_SETFREQ: 2857 if (sc->source == cxm_tuner_source) 2858 if (cxm_pause_encoder(sc) < 0) 2859 return ENXIO; 2860 2861 /* Convert from MHz * 16 to kHz */ 2862 freq = (*(unsigned int *)ap->a_data * 1000) / 16; 2863 2864 if (cxm_tuner_select_frequency(sc, cxm_tuner_tv_freq_type, 2865 freq) < 0) 2866 return ENXIO; 2867 2868 /* 2869 * Explicitly wait for the tuner lock so we 2870 * can indicate if there's a station present. 2871 */ 2872 if (cxm_tuner_wait_for_lock(sc) < 0) 2873 return EINVAL; 2874 2875 result = cxm_encoder_wait_for_lock(sc); 2876 if (result < 0) 2877 return ENXIO; 2878 else if (result == 0) 2879 return EINVAL; 2880 2881 if (sc->source == cxm_tuner_source) 2882 if (cxm_unpause_encoder(sc) < 0) 2883 return ENXIO; 2884 2885 break; 2886 2887 case TVTUNER_GETSTATUS: 2888 status = cxm_tuner_status(sc); 2889 if (status < 0) 2890 return ENXIO; 2891 *(unsigned long *)ap->a_data = status & 0xff; 2892 break; 2893 2894 case REMOTE_GETKEY: 2895 remote = (struct bktr_remote *)ap->a_data; 2896 if (cxm_ir_key(sc, (char *)remote, sizeof(*remote)) < 0) 2897 return ENXIO; 2898 break; 2899 2900 default: 2901 return ENOTTY; 2902 } 2903 2904 return 0; 2905 } 2906 2907 static struct filterops cxm_filterops = 2908 { FILTEROP_ISFD, NULL, cxm_filter_detach, cxm_filter }; 2909 2910 static int 2911 cxm_kqfilter(struct dev_kqfilter_args *ap) 2912 { 2913 cdev_t dev = ap->a_head.a_dev; 2914 struct knote *kn = ap->a_kn; 2915 struct cxm_softc *sc; 2916 struct klist *klist; 2917 int unit; 2918 2919 ap->a_result = 0; 2920 2921 switch (kn->kn_filter) { 2922 case EVFILT_READ: 2923 unit = UNIT(minor(dev)); 2924 /* Get the device data */ 2925 sc = (struct cxm_softc *)devclass_get_softc(cxm_devclass, unit); 2926 kn->kn_fop = &cxm_filterops; 2927 kn->kn_hook = (caddr_t)sc; 2928 break; 2929 default: 2930 ap->a_result = EOPNOTSUPP; 2931 return (0); 2932 } 2933 2934 klist = &sc->enc_kq.ki_note; 2935 knote_insert(klist, kn); 2936 2937 return (0); 2938 } 2939 2940 static void 2941 cxm_filter_detach(struct knote *kn) 2942 { 2943 struct cxm_softc *sc = (struct cxm_softc *)kn->kn_hook; 2944 struct klist *klist = &sc->enc_kq.ki_note; 2945 2946 knote_remove(klist, kn); 2947 } 2948 2949 static int 2950 cxm_filter(struct knote *kn, long hint) 2951 { 2952 struct cxm_softc *sc = (struct cxm_softc *)kn->kn_hook; 2953 int ready = 0; 2954 2955 if (sc == NULL) { 2956 /* the device is no longer valid/functioning */ 2957 kn->kn_flags |= (EV_EOF | EV_NODATA); 2958 return (1); 2959 } 2960 2961 crit_enter(); 2962 if (sc->enc_pool.read != sc->enc_pool.write) 2963 ready = 1; 2964 crit_exit(); 2965 2966 return (ready); 2967 } 2968