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/poll.h> 49 #include <sys/proc.h> 50 #include <sys/signalvar.h> 51 #include <sys/thread2.h> 52 #include <sys/vnode.h> 53 #include <sys/select.h> 54 #include <sys/resource.h> 55 #include <sys/bus.h> 56 #include <sys/rman.h> 57 58 #include <machine/clock.h> 59 60 #include <dev/video/meteor/ioctl_meteor.h> 61 #include <dev/video/bktr/ioctl_bt848.h> 62 63 #include <bus/pci/pcireg.h> 64 #include <bus/pci/pcivar.h> 65 66 #include <dev/video/cxm/cxm.h> 67 68 #include <bus/iicbus/iiconf.h> 69 70 /* 71 * Various supported device vendors/types and their names. 72 */ 73 static struct cxm_dev cxm_devs[] = { 74 { PCI_VENDOR_ICOMPRESSION, PCI_PRODUCT_ICOMPRESSION_ITVC15, 75 "Conexant iTVC15 MPEG Coder" }, 76 { PCI_VENDOR_ICOMPRESSION, PCI_PRODUCT_ICOMPRESSION_ITVC16, 77 "Conexant iTVC16 MPEG Coder" }, 78 { 0, 0, NULL } 79 }; 80 81 82 static int cxm_probe(device_t dev); 83 static int cxm_attach(device_t dev); 84 static int cxm_detach(device_t dev); 85 static int cxm_shutdown(device_t dev); 86 static void cxm_intr(void *arg); 87 88 static void cxm_child_detached(device_t dev, device_t child); 89 static int cxm_read_ivar(device_t bus, device_t dev, 90 int index, uintptr_t* val); 91 static int cxm_write_ivar(device_t bus, device_t dev, 92 int index, uintptr_t val); 93 94 95 static device_method_t cxm_methods[] = { 96 /* Device interface */ 97 DEVMETHOD(device_probe, cxm_probe), 98 DEVMETHOD(device_attach, cxm_attach), 99 DEVMETHOD(device_detach, cxm_detach), 100 DEVMETHOD(device_shutdown, cxm_shutdown), 101 102 /* bus interface */ 103 DEVMETHOD(bus_child_detached, cxm_child_detached), 104 DEVMETHOD(bus_print_child, bus_generic_print_child), 105 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 106 DEVMETHOD(bus_read_ivar, cxm_read_ivar), 107 DEVMETHOD(bus_write_ivar, cxm_write_ivar), 108 109 { 0, 0 } 110 }; 111 112 static driver_t cxm_driver = { 113 "cxm", 114 cxm_methods, 115 sizeof(struct cxm_softc), 116 }; 117 118 static devclass_t cxm_devclass; 119 120 static d_open_t cxm_open; 121 static d_close_t cxm_close; 122 static d_read_t cxm_read; 123 static d_ioctl_t cxm_ioctl; 124 static d_poll_t cxm_poll; 125 126 #define CDEV_MAJOR 93 127 128 static struct dev_ops cxm_ops = { 129 { "cxm", CDEV_MAJOR, 0 }, 130 .d_open = cxm_open, 131 .d_close = cxm_close, 132 .d_read = cxm_read, 133 .d_ioctl = cxm_ioctl, 134 .d_poll = cxm_poll 135 }; 136 137 MODULE_DEPEND(cxm, cxm_iic, 1, 1, 1); 138 DRIVER_MODULE(cxm, pci, cxm_driver, cxm_devclass, 0, 0); 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 selwakeup(&sc->enc_sel); 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 dev_ops_add(&cxm_ops, -1, unit); 1886 sc->cxm_dev_t = make_dev(&cxm_ops, unit, 1887 0, 0, 0444, "cxm%d", unit); 1888 1889 return 0; 1890 1891 fail: 1892 if (sc->enc_sg.baddr) 1893 bus_dmamap_unload(sc->enc_sg.dmat, sc->enc_sg.dmamap); 1894 if (sc->enc_sg.vaddr) 1895 bus_dmamem_free(sc->enc_sg.dmat, sc->enc_sg.vaddr, 1896 sc->enc_sg.dmamap); 1897 if (sc->enc_sg.dmat) 1898 bus_dma_tag_destroy(sc->enc_sg.dmat); 1899 1900 for (i = 0; i < CXM_SG_BUFFERS; i++) { 1901 if (sc->enc_pool.bufs[i].baddr) 1902 bus_dmamap_unload(sc->enc_pool.dmat, 1903 sc->enc_pool.bufs[i].dmamap); 1904 if (sc->enc_pool.bufs[i].vaddr) 1905 bus_dmamem_free(sc->enc_pool.dmat, 1906 sc->enc_pool.bufs[i].vaddr, 1907 sc->enc_pool.bufs[i].dmamap); 1908 } 1909 1910 if (sc->enc_pool.dmat) 1911 bus_dma_tag_destroy(sc->enc_pool.dmat); 1912 1913 if (sc->parent_dmat) 1914 bus_dma_tag_destroy(sc->parent_dmat); 1915 1916 /* 1917 * Detach the I2C bus. 1918 * 1919 * This is done * after * deallocating the scatter / gather 1920 * list and buffers so the kernel has a better chance of 1921 * gracefully handling a memory shortage. 1922 * 1923 * Detach the children before recursively deleting 1924 * in case a child has a pointer to a grandchild 1925 * which is used by the child's detach routine. 1926 */ 1927 bus_generic_detach(dev); 1928 if (sc->cxm_iic) 1929 device_delete_child(dev, sc->cxm_iic); 1930 1931 if (sc->ih_cookie) 1932 bus_teardown_intr(dev, sc->irq_res, sc->ih_cookie); 1933 if (sc->irq_res) 1934 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); 1935 if (sc->mem_res) 1936 bus_release_resource(dev, SYS_RES_MEMORY, CXM_RID, sc->mem_res); 1937 1938 return error; 1939 } 1940 1941 /* 1942 * the detach routine. 1943 */ 1944 static int 1945 cxm_detach(device_t dev) 1946 { 1947 unsigned int i; 1948 struct cxm_softc *sc; 1949 device_t child; 1950 1951 /* Get the device data */ 1952 sc = device_get_softc(dev); 1953 1954 /* Disable the Conexant device. */ 1955 cxm_stop_hardware(sc); 1956 1957 /* Unregister the /dev/cxmN device. */ 1958 dev_ops_remove(&cxm_ops, 0, device_get_unit(dev)); 1959 1960 /* 1961 * Deallocate scatter / gather list and buffers. 1962 */ 1963 bus_dmamap_unload(sc->enc_sg.dmat, sc->enc_sg.dmamap); 1964 bus_dmamem_free(sc->enc_sg.dmat, sc->enc_sg.vaddr, sc->enc_sg.dmamap); 1965 1966 bus_dma_tag_destroy(sc->enc_sg.dmat); 1967 1968 for (i = 0; i < CXM_SG_BUFFERS; i++) { 1969 bus_dmamap_unload(sc->enc_pool.dmat, 1970 sc->enc_pool.bufs[i].dmamap); 1971 bus_dmamem_free(sc->enc_pool.dmat, sc->enc_pool.bufs[i].vaddr, 1972 sc->enc_pool.bufs[i].dmamap); 1973 } 1974 1975 bus_dma_tag_destroy(sc->enc_pool.dmat); 1976 1977 bus_dma_tag_destroy(sc->parent_dmat); 1978 1979 /* 1980 * Detach the I2C bus. 1981 * 1982 * This is done * after * deallocating the scatter / gather 1983 * list and buffers so the kernel has a better chance of 1984 * gracefully handling a memory shortage. 1985 * 1986 * Detach the children before recursively deleting 1987 * in case a child has a pointer to a grandchild 1988 * which is used by the child's detach routine. 1989 * 1990 * Remember the child before detaching so we can 1991 * delete it (bus_generic_detach indirectly zeroes 1992 * sc->child_dev). 1993 */ 1994 child = sc->cxm_iic; 1995 bus_generic_detach(dev); 1996 if (child) 1997 device_delete_child(dev, child); 1998 1999 /* Deallocate resources. */ 2000 bus_teardown_intr(dev, sc->irq_res, sc->ih_cookie); 2001 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); 2002 bus_release_resource(dev, SYS_RES_MEMORY, CXM_RID, sc->mem_res); 2003 2004 return 0; 2005 } 2006 2007 /* 2008 * the shutdown routine. 2009 */ 2010 static int 2011 cxm_shutdown(device_t dev) 2012 { 2013 struct cxm_softc *sc = device_get_softc(dev); 2014 2015 /* Disable the Conexant device. */ 2016 cxm_stop_hardware(sc); 2017 2018 return 0; 2019 } 2020 2021 /* 2022 * the interrupt routine. 2023 */ 2024 static void 2025 cxm_intr(void *arg) 2026 { 2027 uint32_t status; 2028 struct cxm_softc *sc; 2029 2030 /* Get the device data */ 2031 sc = (struct cxm_softc *)arg; 2032 2033 status = CSR_READ_4(sc, CXM_REG_IRQ_STATUS); 2034 2035 status &= ~sc->irq_mask; 2036 2037 if (!status) 2038 return; 2039 2040 /* Process DMA done before handling a new DMA request or EOS */ 2041 if (status & CXM_IRQ_ENC_DMA_DONE) 2042 cxm_encoder_dma_done(sc); 2043 2044 if (status & CXM_IRQ_ENC_DMA_REQUEST) 2045 cxm_encoder_dma_request(sc); 2046 2047 if (status & CXM_IRQ_ENC_EOS) { 2048 sc->encoding_eos = 1; 2049 wakeup(&sc->encoding_eos); 2050 } 2051 2052 cxm_set_irq_status(sc, status); 2053 } 2054 2055 2056 /* 2057 * the child detached routine. 2058 */ 2059 static void 2060 cxm_child_detached(device_t dev, device_t child) 2061 { 2062 struct cxm_softc *sc; 2063 2064 /* Get the device data */ 2065 sc = device_get_softc(dev); 2066 2067 if (child == sc->cxm_iic) 2068 sc->cxm_iic = NULL; 2069 } 2070 2071 2072 static int 2073 cxm_read_ivar(device_t dev, device_t child, int index, uintptr_t* val) 2074 { 2075 struct cxm_softc *sc; 2076 2077 /* Get the device data */ 2078 sc = device_get_softc(dev); 2079 2080 switch (index) { 2081 case CXM_IVAR_BHANDLE: 2082 *(bus_space_handle_t **)val = &sc->bhandle; 2083 break; 2084 2085 case CXM_IVAR_BTAG: 2086 *(bus_space_tag_t **)val = &sc->btag; 2087 break; 2088 2089 case CXM_IVAR_IICBUS: 2090 *(device_t **)val = &sc->iicbus; 2091 break; 2092 2093 default: 2094 return ENOENT; 2095 } 2096 2097 return 0; 2098 } 2099 2100 2101 static int 2102 cxm_write_ivar(device_t dev, device_t child, int index, uintptr_t val) 2103 { 2104 struct cxm_softc *sc; 2105 2106 /* Get the device data */ 2107 sc = device_get_softc(dev); 2108 2109 switch (index) { 2110 case CXM_IVAR_BHANDLE: 2111 return EINVAL; 2112 2113 case CXM_IVAR_BTAG: 2114 return EINVAL; 2115 2116 case CXM_IVAR_IICBUS: 2117 if (sc->iicbus) 2118 return EINVAL; 2119 sc->iicbus = val ? *(device_t *)val : NULL; 2120 break; 2121 2122 default: 2123 return ENOENT; 2124 } 2125 2126 return 0; 2127 } 2128 2129 2130 /*--------------------------------------------------------- 2131 ** 2132 ** Conexant iTVC15 / iTVC16 character device driver routines 2133 ** 2134 **--------------------------------------------------------- 2135 */ 2136 2137 #define UNIT(x) ((x) & 0x0f) 2138 #define FUNCTION(x) (x >> 4) 2139 2140 /* 2141 * 2142 */ 2143 int 2144 cxm_open(struct dev_open_args *ap) 2145 { 2146 cdev_t dev = ap->a_head.a_dev; 2147 int unit; 2148 struct cxm_softc *sc; 2149 2150 unit = UNIT(minor(dev)); 2151 2152 /* Get the device data */ 2153 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2154 if (sc == NULL) { 2155 /* the device is no longer valid/functioning */ 2156 return ENXIO; 2157 } 2158 2159 if (sc->is_opened) 2160 return EBUSY; 2161 2162 sc->is_opened = 1; 2163 sc->mpeg = 1; 2164 2165 /* Record that the device is now busy */ 2166 device_busy(devclass_get_device(cxm_devclass, unit)); 2167 2168 return 0; 2169 } 2170 2171 2172 /* 2173 * 2174 */ 2175 int 2176 cxm_close(struct dev_close_args *ap) 2177 { 2178 cdev_t dev = ap->a_head.a_dev; 2179 int unit; 2180 struct cxm_softc *sc; 2181 2182 unit = UNIT(minor(dev)); 2183 2184 /* Get the device data */ 2185 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2186 if (sc == NULL) { 2187 /* the device is no longer valid/functioning */ 2188 return ENXIO; 2189 } 2190 2191 if (cxm_stop_encoder(sc) < 0) 2192 return ENXIO; 2193 2194 sc->enc_pool.offset = 0; 2195 sc->enc_pool.read = 0; 2196 sc->enc_pool.write = 0; 2197 2198 sc->enc_proc = NULL; 2199 sc->enc_signal = 0; 2200 2201 device_unbusy(devclass_get_device(cxm_devclass, unit)); 2202 2203 sc->is_opened = 0; 2204 2205 return 0; 2206 } 2207 2208 2209 /* 2210 * 2211 */ 2212 int 2213 cxm_read(struct dev_read_args *ap) 2214 { 2215 cdev_t dev = ap->a_head.a_dev; 2216 int buffers_available; 2217 int buffers_read; 2218 int error; 2219 int unit; 2220 unsigned int current; 2221 unsigned int i; 2222 size_t nbytes; 2223 size_t offset; 2224 struct cxm_softc *sc; 2225 2226 unit = UNIT(minor(dev)); 2227 2228 /* Get the device data */ 2229 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2230 if (sc == NULL) { 2231 /* the device is no longer valid/functioning */ 2232 return ENXIO; 2233 } 2234 2235 /* Only trigger the encoder if the ring buffer is empty */ 2236 if (!sc->encoding && sc->enc_pool.read == sc->enc_pool.write) { 2237 if (cxm_start_encoder(sc) < 0) 2238 return ENXIO; 2239 if (ap->a_ioflag & IO_NDELAY) 2240 return EWOULDBLOCK; 2241 } 2242 2243 buffers_available = 0; 2244 2245 crit_enter(); 2246 while (sc->enc_pool.read == sc->enc_pool.write) { 2247 error = tsleep(&sc->enc_pool.read, PCATCH, "cxmrd", 0); 2248 if (error) { 2249 crit_exit(); 2250 return error; 2251 } 2252 } 2253 2254 /* 2255 * Determine the number of buffers available at this * instant * 2256 * taking in consideration that the ring buffer wraps. 2257 */ 2258 buffers_available = sc->enc_pool.write - sc->enc_pool.read; 2259 if (buffers_available < 0) 2260 buffers_available += CXM_SG_BUFFERS; 2261 crit_exit(); 2262 2263 offset = sc->enc_pool.offset; 2264 2265 for (buffers_read = 0, i = sc->enc_pool.read; 2266 buffers_read != buffers_available && ap->a_uio->uio_resid; 2267 buffers_read++, i = (i + 1) % CXM_SG_BUFFERS) { 2268 2269 current = cxm_encoder_fixup_byte_order (sc, i, offset); 2270 2271 nbytes = sc->enc_pool.bufs[current].size - offset; 2272 2273 /* Don't transfer more than requested */ 2274 if (nbytes > ap->a_uio->uio_resid) 2275 nbytes = ap->a_uio->uio_resid; 2276 2277 error = uiomove(sc->enc_pool.bufs[current].vaddr + offset, 2278 nbytes, ap->a_uio); 2279 if (error) 2280 return error; 2281 2282 offset += nbytes; 2283 2284 /* Handle a partial read of a buffer */ 2285 if (!ap->a_uio->uio_resid && offset != sc->enc_pool.bufs[i].size) 2286 break; 2287 2288 offset = 0; 2289 } 2290 2291 sc->enc_pool.offset = offset; 2292 2293 /* Update the books */ 2294 crit_enter(); 2295 sc->enc_pool.read = (sc->enc_pool.read + buffers_read) 2296 % CXM_SG_BUFFERS; 2297 crit_exit(); 2298 2299 return 0; 2300 } 2301 2302 2303 /* 2304 * 2305 */ 2306 int 2307 cxm_ioctl(struct dev_ioctl_args *ap) 2308 { 2309 cdev_t dev = ap->a_head.a_dev; 2310 int brightness; 2311 int chroma_saturation; 2312 int contrast; 2313 int fps; 2314 int hue; 2315 int result; 2316 int status; 2317 int unit; 2318 unsigned int i; 2319 unsigned int sig; 2320 unsigned long freq; 2321 struct cxm_softc *sc; 2322 enum cxm_source source; 2323 struct bktr_capture_area *cap; 2324 struct bktr_remote *remote; 2325 2326 unit = UNIT(minor(dev)); 2327 2328 /* Get the device data */ 2329 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2330 if (sc == NULL) { 2331 /* the device is no longer valid/functioning */ 2332 return ENXIO; 2333 } 2334 2335 switch (ap->a_cmd) { 2336 case BT848_GAUDIO: 2337 switch (cxm_msp_selected_source(sc)) { 2338 case cxm_tuner_source: 2339 *(int *) ap->a_data = AUDIO_TUNER; 2340 break; 2341 2342 case cxm_line_in_source_composite: 2343 case cxm_line_in_source_svideo: 2344 *(int *) ap->a_data = AUDIO_EXTERN; 2345 break; 2346 2347 case cxm_fm_source: 2348 *(int *) ap->a_data = AUDIO_INTERN; 2349 break; 2350 2351 default: 2352 return ENXIO; 2353 } 2354 2355 if (cxm_msp_is_muted(sc) == 1) 2356 *(int *) ap->a_data |= AUDIO_MUTE; 2357 break; 2358 2359 case BT848_SAUDIO: 2360 source = cxm_unknown_source; 2361 2362 switch (*(int *) ap->a_data) { 2363 case AUDIO_TUNER: 2364 source = cxm_tuner_source; 2365 break; 2366 2367 case AUDIO_EXTERN: 2368 source = cxm_line_in_source_composite; 2369 break; 2370 2371 case AUDIO_INTERN: 2372 source = cxm_fm_source; 2373 break; 2374 2375 case AUDIO_MUTE: 2376 if (cxm_msp_mute(sc) < 0) 2377 return ENXIO; 2378 return 0; 2379 2380 case AUDIO_UNMUTE: 2381 if (cxm_msp_unmute(sc) < 0) 2382 return ENXIO; 2383 return 0; 2384 2385 default: 2386 return EINVAL; 2387 } 2388 2389 if (sc->encoding) { 2390 2391 /* 2392 * Switching between audio + video and audio only 2393 * subtypes isn't supported while encoding. 2394 */ 2395 2396 if (source != sc->source 2397 && (source == cxm_fm_source 2398 || sc->source == cxm_fm_source)) 2399 return EBUSY; 2400 } 2401 2402 if (cxm_pause_encoder(sc) < 0) 2403 return ENXIO; 2404 2405 if (cxm_msp_select_source(sc, source) < 0) 2406 return ENXIO; 2407 2408 if (source == cxm_fm_source) 2409 sc->source = source; 2410 2411 result = cxm_encoder_wait_for_lock(sc); 2412 if (result < 0) 2413 return ENXIO; 2414 else if (result == 0) 2415 return EINVAL; 2416 2417 if (cxm_unpause_encoder(sc) < 0) 2418 return ENXIO; 2419 break; 2420 2421 case BT848_GBRIG: 2422 brightness = cxm_saa7115_get_brightness(sc); 2423 2424 if (brightness < 0) 2425 return ENXIO; 2426 2427 /* 2428 * Brooktree brightness: 2429 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6% 2430 */ 2431 *(int *)ap->a_data = (int)(unsigned char)brightness - 128; 2432 break; 2433 2434 case BT848_SBRIG: 2435 2436 /* 2437 * Brooktree brightness: 2438 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6% 2439 */ 2440 brightness = *(int *)ap->a_data + 128; 2441 2442 if (cxm_saa7115_set_brightness(sc, brightness) < 0) 2443 return ENXIO; 2444 break; 2445 2446 case METEORGBRIG: 2447 brightness = cxm_saa7115_get_brightness(sc); 2448 2449 if (brightness < 0) 2450 return ENXIO; 2451 2452 *(unsigned char *)ap->a_data = (unsigned char)brightness; 2453 break; 2454 2455 case METEORSBRIG: 2456 brightness = *(unsigned char *)ap->a_data; 2457 2458 if (cxm_saa7115_set_brightness(sc, brightness) < 0) 2459 return ENXIO; 2460 break; 2461 2462 case BT848_GCSAT: 2463 chroma_saturation = cxm_saa7115_get_chroma_saturation(sc); 2464 2465 if (chroma_saturation < 0) 2466 return ENXIO; 2467 2468 /* 2469 * Brooktree chroma saturation: 2470 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18% 2471 */ 2472 *(int *)ap->a_data = ((signed char)chroma_saturation > 0) 2473 ? (chroma_saturation * 4 - 2) : 0; 2474 break; 2475 2476 case BT848_SCSAT: 2477 2478 /* 2479 * Brooktree chroma saturation: 2480 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18% 2481 */ 2482 chroma_saturation = (*(int *)ap->a_data & 0x1ff) < 510 2483 ? ((*(int *)ap->a_data & 0x1ff) + 2) / 4 : 127; 2484 2485 if (cxm_saa7115_set_chroma_saturation(sc, chroma_saturation) 2486 < 0) 2487 return ENXIO; 2488 2489 break; 2490 2491 case METEORGCSAT: 2492 chroma_saturation = cxm_saa7115_get_chroma_saturation(sc); 2493 2494 if (chroma_saturation < 0) 2495 return ENXIO; 2496 2497 *(unsigned char *)ap->a_data = (unsigned char)chroma_saturation; 2498 break; 2499 2500 case METEORSCSAT: 2501 chroma_saturation = *(unsigned char *)ap->a_data; 2502 2503 if (cxm_saa7115_set_chroma_saturation(sc, chroma_saturation) 2504 < 0) 2505 return ENXIO; 2506 break; 2507 2508 case METEORGCONT: 2509 contrast = cxm_saa7115_get_contrast(sc); 2510 2511 if (contrast < 0) 2512 return ENXIO; 2513 2514 *(unsigned char *)ap->a_data = (unsigned char)contrast; 2515 break; 2516 2517 case METEORSCONT: 2518 contrast = *(unsigned char *)ap->a_data; 2519 2520 if (cxm_saa7115_set_contrast(sc, contrast) < 0) 2521 return ENXIO; 2522 break; 2523 2524 case BT848_GHUE: 2525 hue = cxm_saa7115_get_hue(sc); 2526 2527 if (hue < 0) 2528 return ENXIO; 2529 2530 *(int *)ap->a_data = (signed char)hue; 2531 break; 2532 2533 case BT848_SHUE: 2534 hue = *(int *)ap->a_data; 2535 2536 if (cxm_saa7115_set_hue(sc, hue) < 0) 2537 return ENXIO; 2538 break; 2539 2540 case METEORGHUE: 2541 hue = cxm_saa7115_get_hue(sc); 2542 2543 if (hue < 0) 2544 return ENXIO; 2545 2546 *(signed char *)ap->a_data = (signed char)hue; 2547 break; 2548 2549 case METEORSHUE: 2550 hue = *(signed char *)ap->a_data; 2551 2552 if (cxm_saa7115_set_hue(sc, hue) < 0) 2553 return ENXIO; 2554 break; 2555 2556 case METEORCAPTUR: 2557 switch (*(int *) ap->a_data) { 2558 case METEOR_CAP_CONTINOUS: 2559 if (cxm_start_encoder(sc) < 0) 2560 return ENXIO; 2561 break; 2562 2563 case METEOR_CAP_STOP_CONT: 2564 if (cxm_stop_encoder(sc) < 0) 2565 return ENXIO; 2566 break; 2567 2568 default: 2569 return EINVAL; 2570 } 2571 break; 2572 2573 case BT848_GCAPAREA: 2574 cap = (struct bktr_capture_area *)ap->a_data; 2575 memset (cap, 0, sizeof (*cap)); 2576 cap->x_offset = 0; 2577 cap->y_offset = 0; 2578 cap->x_size = sc->profile->width; 2579 cap->y_size = sc->profile->height; 2580 break; 2581 2582 case BT848_SCAPAREA: 2583 if (sc->encoding) 2584 return EBUSY; 2585 2586 cap = (struct bktr_capture_area *)ap->a_data; 2587 if (cap->x_offset || cap->y_offset 2588 || (cap->x_size % CXM_MACROBLOCK_WIDTH) 2589 || (cap->y_size % CXM_MACROBLOCK_HEIGHT)) 2590 return EINVAL; 2591 2592 /* 2593 * Setting the width and height has the side effect of 2594 * chosing between the VCD, SVCD, and DVD profiles. 2595 */ 2596 2597 for (i = 0; i < NUM_ELEMENTS(codec_profiles); i++) 2598 if (codec_profiles[i]->width == cap->x_size 2599 && codec_profiles[i]->height == cap->y_size) 2600 break; 2601 2602 if (i >= NUM_ELEMENTS(codec_profiles)) 2603 return EINVAL; 2604 2605 sc->profile = codec_profiles[i]; 2606 break; 2607 2608 case BT848GFMT: 2609 switch (cxm_saa7115_detected_format(sc)) { 2610 case cxm_ntsc_60hz_source_format: 2611 *(unsigned long *)ap->a_data = BT848_IFORM_F_NTSCM; 2612 break; 2613 2614 case cxm_pal_50hz_source_format: 2615 *(unsigned long *)ap->a_data = BT848_IFORM_F_PALBDGHI; 2616 break; 2617 2618 case cxm_secam_50hz_source_format: 2619 *(unsigned long *)ap->a_data = BT848_IFORM_F_SECAM; 2620 break; 2621 2622 case cxm_pal_60hz_source_format: 2623 *(unsigned long *)ap->a_data = BT848_IFORM_F_PALM; 2624 break; 2625 2626 case cxm_bw_50hz_source_format: 2627 case cxm_bw_60hz_source_format: 2628 case cxm_ntsc_50hz_source_format: 2629 *(unsigned long *)ap->a_data = BT848_IFORM_F_AUTO; 2630 break; 2631 2632 default: 2633 return ENXIO; 2634 } 2635 break; 2636 2637 case METEORGFMT: 2638 switch (cxm_saa7115_detected_format(sc)) { 2639 case cxm_ntsc_60hz_source_format: 2640 *(unsigned long *)ap->a_data = METEOR_FMT_NTSC; 2641 break; 2642 2643 case cxm_pal_50hz_source_format: 2644 *(unsigned long *)ap->a_data = METEOR_FMT_PAL; 2645 break; 2646 2647 case cxm_secam_50hz_source_format: 2648 *(unsigned long *)ap->a_data = METEOR_FMT_SECAM; 2649 break; 2650 2651 case cxm_bw_50hz_source_format: 2652 case cxm_bw_60hz_source_format: 2653 case cxm_ntsc_50hz_source_format: 2654 case cxm_pal_60hz_source_format: 2655 *(unsigned long *)ap->a_data = METEOR_FMT_AUTOMODE; 2656 break; 2657 2658 default: 2659 return ENXIO; 2660 } 2661 break; 2662 2663 case METEORGFPS: 2664 fps = cxm_saa7115_detected_fps(sc); 2665 2666 if (fps < 0) 2667 return ENXIO; 2668 2669 *(unsigned short *)ap->a_data = fps; 2670 break; 2671 2672 case METEORGINPUT: 2673 switch (sc->source) { 2674 case cxm_tuner_source: 2675 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV1; 2676 break; 2677 2678 case cxm_line_in_source_composite: 2679 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV2; 2680 break; 2681 2682 case cxm_line_in_source_svideo: 2683 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV_SVIDEO; 2684 break; 2685 2686 default: 2687 return ENXIO; 2688 } 2689 break; 2690 2691 case METEORSINPUT: 2692 source = cxm_unknown_source; 2693 2694 switch (*(unsigned long *)ap->a_data & 0xf000) { 2695 case METEOR_INPUT_DEV1: 2696 source = cxm_tuner_source; 2697 break; 2698 2699 case METEOR_INPUT_DEV2: 2700 source = cxm_line_in_source_composite; 2701 break; 2702 2703 case METEOR_INPUT_DEV_SVIDEO: 2704 source = cxm_line_in_source_svideo; 2705 break; 2706 2707 default: 2708 return EINVAL; 2709 } 2710 2711 if (sc->encoding) { 2712 2713 /* 2714 * Switching between audio + video and audio only 2715 * subtypes isn't supported while encoding. 2716 */ 2717 2718 if (source != sc->source 2719 && (source == cxm_fm_source 2720 || sc->source == cxm_fm_source)) 2721 return EBUSY; 2722 } 2723 2724 if (cxm_pause_encoder(sc) < 0) 2725 return ENXIO; 2726 2727 if (cxm_saa7115_select_source(sc, source) < 0) 2728 return ENXIO; 2729 if (cxm_msp_select_source(sc, source) < 0) 2730 return ENXIO; 2731 sc->source = source; 2732 2733 result = cxm_encoder_wait_for_lock(sc); 2734 if (result < 0) 2735 return ENXIO; 2736 else if (result == 0) 2737 return EINVAL; 2738 2739 if (cxm_unpause_encoder(sc) < 0) 2740 return ENXIO; 2741 break; 2742 2743 case METEORGSIGNAL: 2744 *(unsigned int *)ap->a_data = sc->enc_signal; 2745 break; 2746 2747 case METEORSSIGNAL: 2748 sig = *(unsigned int *)ap->a_data; 2749 2750 if (!_SIG_VALID(sig)) 2751 return EINVAL; 2752 2753 /* 2754 * Historically, applications used METEOR_SIG_MODE_MASK 2755 * to reset signal delivery. 2756 */ 2757 if (sig == METEOR_SIG_MODE_MASK) 2758 sig = 0; 2759 2760 crit_enter(); 2761 sc->enc_proc = sig ? curproc : NULL; 2762 sc->enc_signal = sig; 2763 crit_exit(); 2764 break; 2765 2766 case RADIO_GETFREQ: 2767 /* Convert from kHz to MHz * 100 */ 2768 freq = sc->tuner_freq / 10; 2769 2770 *(unsigned int *)ap->a_data = freq; 2771 break; 2772 2773 case RADIO_SETFREQ: 2774 if (sc->source == cxm_fm_source) 2775 if (cxm_pause_encoder(sc) < 0) 2776 return ENXIO; 2777 2778 /* Convert from MHz * 100 to kHz */ 2779 freq = *(unsigned int *)ap->a_data * 10; 2780 2781 if (cxm_tuner_select_frequency(sc, cxm_tuner_fm_freq_type, 2782 freq) < 0) 2783 return ENXIO; 2784 2785 /* 2786 * Explicitly wait for the tuner lock so we 2787 * can indicate if there's a station present. 2788 */ 2789 if (cxm_tuner_wait_for_lock(sc) < 0) 2790 return EINVAL; 2791 2792 result = cxm_encoder_wait_for_lock(sc); 2793 if (result < 0) 2794 return ENXIO; 2795 else if (result == 0) 2796 return EINVAL; 2797 2798 if (sc->source == cxm_fm_source) 2799 if (cxm_unpause_encoder(sc) < 0) 2800 return ENXIO; 2801 break; 2802 2803 case TVTUNER_GETAFC: 2804 *(int *)ap->a_data = sc->tuner_afc; 2805 break; 2806 2807 case TVTUNER_SETAFC: 2808 sc->tuner_afc = (*(int *)ap->a_data != 0); 2809 break; 2810 2811 case TVTUNER_GETTYPE: 2812 *(unsigned int *)ap->a_data = cxm_tuner_selected_channel_set(sc); 2813 break; 2814 2815 case TVTUNER_SETTYPE: 2816 if (cxm_tuner_select_channel_set(sc, *(unsigned int *)ap->a_data) < 0) 2817 return EINVAL; 2818 break; 2819 2820 case TVTUNER_SETCHNL: 2821 if (sc->source == cxm_tuner_source) 2822 if (cxm_pause_encoder(sc) < 0) 2823 return ENXIO; 2824 2825 if (cxm_tuner_select_channel(sc, *(unsigned int *)ap->a_data) < 0) 2826 return ENXIO; 2827 2828 if (sc->tuner_afc) 2829 if (cxm_tuner_apply_afc(sc) < 0) 2830 return EINVAL; 2831 2832 /* 2833 * Explicitly wait for the tuner lock so we 2834 * can indicate if there's a station present. 2835 */ 2836 if (cxm_tuner_wait_for_lock(sc) < 0) 2837 return EINVAL; 2838 2839 result = cxm_encoder_wait_for_lock(sc); 2840 if (result < 0) 2841 return ENXIO; 2842 else if (result == 0) 2843 return EINVAL; 2844 2845 if (sc->source == cxm_tuner_source) 2846 if (cxm_unpause_encoder(sc) < 0) 2847 return ENXIO; 2848 break; 2849 2850 case TVTUNER_GETFREQ: 2851 /* Convert from kHz to MHz * 16 */ 2852 freq = (sc->tuner_freq * 16) / 1000; 2853 2854 *(unsigned int *)ap->a_data = freq; 2855 break; 2856 2857 case TVTUNER_SETFREQ: 2858 if (sc->source == cxm_tuner_source) 2859 if (cxm_pause_encoder(sc) < 0) 2860 return ENXIO; 2861 2862 /* Convert from MHz * 16 to kHz */ 2863 freq = (*(unsigned int *)ap->a_data * 1000) / 16; 2864 2865 if (cxm_tuner_select_frequency(sc, cxm_tuner_tv_freq_type, 2866 freq) < 0) 2867 return ENXIO; 2868 2869 /* 2870 * Explicitly wait for the tuner lock so we 2871 * can indicate if there's a station present. 2872 */ 2873 if (cxm_tuner_wait_for_lock(sc) < 0) 2874 return EINVAL; 2875 2876 result = cxm_encoder_wait_for_lock(sc); 2877 if (result < 0) 2878 return ENXIO; 2879 else if (result == 0) 2880 return EINVAL; 2881 2882 if (sc->source == cxm_tuner_source) 2883 if (cxm_unpause_encoder(sc) < 0) 2884 return ENXIO; 2885 2886 break; 2887 2888 case TVTUNER_GETSTATUS: 2889 status = cxm_tuner_status(sc); 2890 if (status < 0) 2891 return ENXIO; 2892 *(unsigned long *)ap->a_data = status & 0xff; 2893 break; 2894 2895 case REMOTE_GETKEY: 2896 remote = (struct bktr_remote *)ap->a_data; 2897 if (cxm_ir_key(sc, (char *)remote, sizeof(*remote)) < 0) 2898 return ENXIO; 2899 break; 2900 2901 default: 2902 return ENOTTY; 2903 } 2904 2905 return 0; 2906 } 2907 2908 2909 int 2910 cxm_poll(struct dev_poll_args *ap) 2911 { 2912 cdev_t dev = ap->a_head.a_dev; 2913 int revents; 2914 int unit; 2915 struct cxm_softc *sc; 2916 2917 unit = UNIT(minor(dev)); 2918 2919 /* Get the device data */ 2920 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit); 2921 if (sc == NULL) { 2922 /* the device is no longer valid/functioning */ 2923 return POLLHUP; 2924 } 2925 2926 revents = 0; 2927 2928 crit_enter(); 2929 if (ap->a_events & (POLLIN | POLLRDNORM)) { 2930 if (sc->enc_pool.read == sc->enc_pool.write) 2931 selrecord(curthread, &sc->enc_sel); 2932 else 2933 revents = ap->a_events & (POLLIN | POLLRDNORM); 2934 } 2935 crit_exit(); 2936 2937 return revents; 2938 } 2939