2 * Copyright (c) 2003, 2004, 2005
3 * John Wehle <john@feith.com>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
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.
37 * This driver was written using the invaluable information
38 * compiled by The IvyTV Project (ivtv.sourceforge.net).
41 #include <sys/param.h>
42 #include <sys/systm.h>
45 #include <sys/kernel.h>
47 #include <sys/module.h>
48 #include <sys/event.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>
58 #include <machine/clock.h>
60 #include <dev/video/meteor/ioctl_meteor.h>
61 #include <dev/video/bktr/ioctl_bt848.h>
63 #include <bus/pci/pcireg.h>
64 #include <bus/pci/pcivar.h>
66 #include <dev/video/cxm/cxm.h>
68 #include <bus/iicbus/iiconf.h>
71 * Various supported device vendors/types and their names.
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" },
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);
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);
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),
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),
112 static driver_t cxm_driver = {
115 sizeof(struct cxm_softc),
118 static devclass_t cxm_devclass;
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_kqfilter_t cxm_kqfilter;
126 static void cxm_filter_detach(struct knote *);
127 static int cxm_filter(struct knote *, long);
129 #define CDEV_MAJOR 93
131 static struct dev_ops cxm_ops = {
132 { "cxm", CDEV_MAJOR, D_KQFILTER },
134 .d_close = cxm_close,
136 .d_ioctl = cxm_ioctl,
137 .d_kqfilter = cxm_kqfilter
140 MODULE_DEPEND(cxm, cxm_iic, 1, 1, 1);
141 DRIVER_MODULE(cxm, pci, cxm_driver, cxm_devclass, 0, 0);
144 static struct cxm_codec_audio_format codec_audio_formats[] = {
145 { 44100, 0xb8 }, /* 44.1 Khz, MPEG-1 Layer II, 224 kb/s */
146 { 48000, 0xe9 } /* 48 Khz, MPEG-1 Layer II, 384 kb/s */
153 static struct cxm_codec_profile vcd_ntsc_profile = {
154 "MPEG-1 VideoCD NTSC video and MPEG audio",
155 CXM_FW_STREAM_TYPE_VCD,
164 * Spatial filter = Manual, Temporal filter = Manual
165 * Median filter = Horizontal / Vertical
166 * Spatial filter value = 1, Temporal filter value = 4
172 static struct cxm_codec_profile vcd_pal_profile = {
173 "MPEG-1 VideoCD PAL video and MPEG audio",
174 CXM_FW_STREAM_TYPE_VCD,
183 * Spatial filter = Manual, Temporal filter = Manual
184 * Median filter = Horizontal / Vertical
185 * Spatial filter value = 1, Temporal filter value = 4
191 static struct cxm_codec_profile svcd_ntsc_profile = {
192 "MPEG-2 SuperVCD NTSC video and MPEG audio",
193 CXM_FW_STREAM_TYPE_SVCD,
199 /* 2.5 Mb/s peak limit to keep bbdmux followed by mplex -f 4 happy */
200 { 0, 1150000, 2500000 },
203 * Spatial filter = Manual, Temporal filter = Manual
204 * Median filter = Horizontal / Vertical
205 * Spatial filter value = 1, Temporal filter value = 4
211 static struct cxm_codec_profile svcd_pal_profile = {
212 "MPEG-2 SuperVCD PAL video and MPEG audio",
213 CXM_FW_STREAM_TYPE_SVCD,
219 /* 2.5 Mb/s peak limit to keep bbdmux followed by mplex -f 4 happy */
220 { 0, 1150000, 2500000 },
223 * Spatial filter = Manual, Temporal filter = Manual
224 * Median filter = Horizontal / Vertical
225 * Spatial filter value = 1, Temporal filter value = 4
231 static struct cxm_codec_profile dvd_half_d1_ntsc_profile = {
232 "MPEG-2 DVD NTSC video and MPEG audio",
233 CXM_FW_STREAM_TYPE_DVD,
239 { 0, 4000000, 4520000 }, /* 4 hours on 8.54 GB media */
242 * Spatial filter = Manual, Temporal filter = Manual
243 * Median filter = Horizontal / Vertical
244 * Spatial filter value = 1, Temporal filter value = 4
250 static struct cxm_codec_profile dvd_half_d1_pal_profile = {
251 "MPEG-2 DVD PAL video and MPEG audio",
252 CXM_FW_STREAM_TYPE_DVD,
258 { 0, 4000000, 4520000 }, /* 4 hours on 8.54 GB media */
261 * Spatial filter = Manual, Temporal filter = Manual
262 * Median filter = Horizontal / Vertical
263 * Spatial filter value = 1, Temporal filter value = 4
269 static struct cxm_codec_profile dvd_full_d1_ntsc_profile = {
270 "MPEG-2 DVD NTSC video and MPEG audio",
271 CXM_FW_STREAM_TYPE_DVD,
277 /* 9.52 Mb/s peak limit to keep bbdmux followed by mplex -f 8 happy */
278 { 0, 9000000, 9520000 }, /* 1 hour on 4.7 GB media */
281 * Spatial filter = Manual, Temporal filter = Manual
282 * Median filter = Horizontal / Vertical
283 * Spatial filter value = 1, Temporal filter value = 4
289 static struct cxm_codec_profile dvd_full_d1_pal_profile = {
290 "MPEG-2 DVD PAL video and MPEG audio",
291 CXM_FW_STREAM_TYPE_DVD,
297 /* 9.52 Mb/s peak limit to keep bbdmux followed by mplex -f 8 happy */
298 { 0, 9000000, 9520000 }, /* 1 hour on 4.7 GB media */
301 * Spatial filter = Manual, Temporal filter = Manual
302 * Median filter = Horizontal / Vertical
303 * Spatial filter value = 1, Temporal filter value = 4
310 static const struct cxm_codec_profile
311 *codec_profiles[] = {
316 &dvd_half_d1_ntsc_profile,
317 &dvd_half_d1_pal_profile,
318 &dvd_full_d1_ntsc_profile,
319 &dvd_full_d1_pal_profile
324 cxm_queue_firmware_command(struct cxm_softc *sc,
325 enum cxm_mailbox_name mbx_name, uint32_t cmd,
326 uint32_t *parameters, unsigned int nparameters)
329 unsigned int mailbox;
330 uint32_t completed_command;
333 if (nparameters > CXM_MBX_MAX_PARAMETERS) {
334 device_printf(sc->dev, "too many parameters for mailbox\n");
341 case cxm_dec_mailbox:
342 mailbox = sc->dec_mbx
343 + CXM_MBX_FW_CMD_MAILBOX *sizeof(struct cxm_mailbox);
346 case cxm_enc_mailbox:
347 mailbox = sc->enc_mbx
348 + CXM_MBX_FW_CMD_MAILBOX *sizeof(struct cxm_mailbox);
356 for (i = 0; i < CXM_MBX_FW_CMD_MAILBOXES; i++) {
357 flags = CSR_READ_4(sc,
359 + offsetof(struct cxm_mailbox, flags));
360 if (!(flags & CXM_MBX_FLAG_IN_USE))
364 * Mail boxes containing certain completed commands
365 * for which the results are never needed can be reused.
368 if ((flags & (CXM_MBX_FLAG_DRV_DONE | CXM_MBX_FLAG_FW_DONE))
369 == (CXM_MBX_FLAG_DRV_DONE | CXM_MBX_FLAG_FW_DONE)) {
373 + offsetof(struct cxm_mailbox, command));
376 * DMA results are always check by reading the
377 * DMA status register ... never by checking
378 * the mailbox after the command has completed.
381 if (completed_command == CXM_FW_CMD_SCHED_DMA_TO_HOST)
385 mailbox += sizeof(struct cxm_mailbox);
388 if (i >= CXM_MBX_FW_CMD_MAILBOXES) {
393 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags),
394 CXM_MBX_FLAG_IN_USE);
397 * PCI writes may be buffered so force the
398 * write to complete by reading the last
402 CSR_READ_4(sc, mailbox + offsetof(struct cxm_mailbox, flags));
406 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, command), cmd);
407 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, timeout),
410 for (i = 0; i < nparameters; i++)
413 + offsetof(struct cxm_mailbox, parameters)
414 + i * sizeof(uint32_t),
417 for (; i < CXM_MBX_MAX_PARAMETERS; i++)
420 + offsetof(struct cxm_mailbox, parameters)
421 + i * sizeof(uint32_t), 0);
423 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags),
424 CXM_MBX_FLAG_IN_USE | CXM_MBX_FLAG_DRV_DONE);
431 cxm_firmware_command(struct cxm_softc *sc,
432 enum cxm_mailbox_name mbx_name, uint32_t cmd,
433 uint32_t *parameters, unsigned int nparameters)
438 unsigned int mailbox;
446 case cxm_dec_mailbox:
451 case cxm_enc_mailbox:
460 mailbox = cxm_queue_firmware_command(sc, mbx_name, cmd,
461 parameters, nparameters);
463 device_printf(sc->dev, "no free mailboxes\n");
467 /* Give the firmware a chance to start processing the request */
468 tsleep(bmp, 0, wmesg, hz / 100);
470 for (i = 0; i < 100; i++) {
471 flags = CSR_READ_4(sc,
473 + offsetof(struct cxm_mailbox, flags));
474 if ((flags & CXM_MBX_FLAG_FW_DONE))
478 tsleep(bmp, 0, wmesg, hz / 100);
482 device_printf(sc->dev, "timeout\n");
486 result = CSR_READ_4(sc,
488 + offsetof(struct cxm_mailbox, result));
490 for (i = 0; i < nparameters; i++)
494 + offsetof(struct cxm_mailbox, parameters)
495 + i * sizeof(uint32_t));
497 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), 0);
499 return result == 0 ? 0 : -1;
504 cxm_firmware_command_nosleep(struct cxm_softc *sc,
505 enum cxm_mailbox_name mbx_name, uint32_t cmd,
506 uint32_t *parameters, unsigned int nparameters)
509 unsigned int mailbox;
513 for (i = 0; i < 100; i++) {
514 mailbox = cxm_queue_firmware_command(sc, mbx_name, cmd,
515 parameters, nparameters);
524 device_printf(sc->dev, "no free mailboxes\n");
528 /* Give the firmware a chance to start processing the request */
531 for (i = 0; i < 100; i++) {
532 flags = CSR_READ_4(sc,
534 + offsetof(struct cxm_mailbox, flags));
535 if ((flags & CXM_MBX_FLAG_FW_DONE))
543 device_printf(sc->dev, "timeout\n");
547 result = CSR_READ_4(sc,
549 + offsetof(struct cxm_mailbox, result));
551 for (i = 0; i < nparameters; i++)
555 + offsetof(struct cxm_mailbox, parameters)
556 + i * sizeof(uint32_t));
558 CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), 0);
560 return result == 0 ? 0 : -1;
565 cxm_stop_firmware(struct cxm_softc *sc)
568 if (cxm_firmware_command_nosleep(sc, cxm_enc_mailbox,
569 CXM_FW_CMD_ENC_HALT_FW, NULL, 0) < 0)
572 if (sc->type == cxm_iTVC15_type
573 && cxm_firmware_command_nosleep(sc, cxm_dec_mailbox,
574 CXM_FW_CMD_DEC_HALT_FW,
586 cxm_set_irq_mask(struct cxm_softc *sc, uint32_t mask)
590 CSR_WRITE_4(sc, CXM_REG_IRQ_MASK, mask);
593 * PCI writes may be buffered so force the
594 * write to complete by reading the last
598 CSR_READ_4(sc, CXM_REG_IRQ_MASK);
607 cxm_set_irq_status(struct cxm_softc *sc, uint32_t status)
610 CSR_WRITE_4(sc, CXM_REG_IRQ_STATUS, status);
613 * PCI writes may be buffered so force the
614 * write to complete by reading the last
618 CSR_READ_4(sc, CXM_REG_IRQ_STATUS);
623 cxm_stop_hardware(struct cxm_softc *sc)
626 if (cxm_saa7115_mute(sc) < 0)
628 if (cxm_msp_mute(sc) < 0)
632 /* Halt the firmware */
633 if (sc->enc_mbx != -1) {
634 if (cxm_stop_firmware(sc) < 0)
638 /* Mask all interrupts */
639 cxm_set_irq_mask(sc, 0xffffffff);
642 CSR_WRITE_4(sc, CXM_REG_VDM, CXM_CMD_VDM_STOP);
645 CSR_WRITE_4(sc, CXM_REG_AO, CXM_CMD_AO_STOP);
648 CSR_WRITE_4(sc, CXM_REG_APU, CXM_CMD_APU_PING);
651 CSR_WRITE_4(sc, CXM_REG_VPU, sc->type == cxm_iTVC15_type
653 : CXM_CMD_VPU_STOP16);
655 /* Reset Hw Blocks */
656 CSR_WRITE_4(sc, CXM_REG_HW_BLOCKS, CXM_CMD_HW_BLOCKS_RST);
659 CSR_WRITE_4(sc, CXM_REG_SPU, CXM_CMD_SPU_STOP);
669 cxm_download_firmware(struct cxm_softc *sc)
674 /* Check if firmware is compiled in */
675 if (strncmp((const char *)cxm_enc_fw, "NOFW", 4) == 0) {
676 device_printf(sc->dev, "encoder firmware not compiled in\n");
678 } else if (strncmp((const char *)cxm_dec_fw, "NOFW", 4) == 0) {
679 device_printf(sc->dev, "decoder firmware not compiled in\n");
683 /* Download the encoder firmware */
684 fw = (const uint32_t *)cxm_enc_fw;
685 for (i = 0; i < CXM_FW_SIZE; i += sizeof(*fw))
686 CSR_WRITE_4(sc, CXM_MEM_ENC + i, *fw++);
688 /* Download the decoder firmware */
689 if (sc->type == cxm_iTVC15_type) {
690 fw = (const uint32_t *)cxm_dec_fw;
691 for (i = 0; i < CXM_FW_SIZE; i += sizeof(*fw))
692 CSR_WRITE_4(sc, CXM_MEM_DEC + i, *fw++);
700 cxm_init_hardware(struct cxm_softc *sc)
703 unsigned int mailbox;
706 if (cxm_stop_hardware(sc) < 0)
709 /* Initialize encoder SDRAM pre-charge */
710 CSR_WRITE_4(sc, CXM_REG_ENC_SDRAM_PRECHARGE,
711 CXM_CMD_SDRAM_PRECHARGE_INIT);
713 /* Initialize encoder SDRAM refresh to 1us */
714 CSR_WRITE_4(sc, CXM_REG_ENC_SDRAM_REFRESH,
715 CXM_CMD_SDRAM_REFRESH_INIT);
717 /* Initialize decoder SDRAM pre-charge */
718 CSR_WRITE_4(sc, CXM_REG_DEC_SDRAM_PRECHARGE,
719 CXM_CMD_SDRAM_PRECHARGE_INIT);
721 /* Initialize decoder SDRAM refresh to 1us */
722 CSR_WRITE_4(sc, CXM_REG_DEC_SDRAM_REFRESH,
723 CXM_CMD_SDRAM_REFRESH_INIT);
728 if (cxm_download_firmware(sc) < 0)
732 CSR_WRITE_4(sc, CXM_REG_SPU,
733 CSR_READ_4(sc, CXM_REG_SPU) & CXM_MASK_SPU_ENABLE);
735 /* Wait for 1 second */
739 CSR_WRITE_4(sc, CXM_REG_VPU,
740 CSR_READ_4(sc, CXM_REG_VPU)
741 & (sc->type == cxm_iTVC15_type
742 ? CXM_MASK_VPU_ENABLE15
743 : CXM_MASK_VPU_ENABLE16));
745 /* Wait for 1 second */
748 /* Locate encoder mailbox */
749 mailbox = CXM_MEM_ENC;
750 for (i = 0; i < CXM_MEM_ENC_SIZE; i += 0x100)
751 if (CSR_READ_4(sc, mailbox + i) == 0x12345678
752 && CSR_READ_4(sc, mailbox + i + 4) == 0x34567812
753 && CSR_READ_4(sc, mailbox + i + 8) == 0x56781234
754 && CSR_READ_4(sc, mailbox + i + 12) == 0x78123456)
757 if (i >= CXM_MEM_ENC_SIZE)
760 sc->enc_mbx = mailbox + i + 16;
762 /* Locate decoder mailbox */
763 if (sc->type == cxm_iTVC15_type) {
764 mailbox = CXM_MEM_DEC;
765 for (i = 0; i < CXM_MEM_DEC_SIZE; i += 0x100)
766 if (CSR_READ_4(sc, mailbox + i) == 0x12345678
767 && CSR_READ_4(sc, mailbox + i + 4) == 0x34567812
768 && CSR_READ_4(sc, mailbox + i + 8) == 0x56781234
769 && CSR_READ_4(sc, mailbox + i + 12) == 0x78123456)
772 if (i >= CXM_MEM_DEC_SIZE)
775 sc->dec_mbx = mailbox + i + 16;
778 /* Get encoder firmware version */
780 if (cxm_firmware_command_nosleep(sc, cxm_enc_mailbox,
781 CXM_FW_CMD_ENC_GET_FW_VER,
785 device_printf(sc->dev, "encoder firmware version %#x\n",
786 (unsigned int)parameter);
788 /* Get decoder firmware version */
789 if (sc->type == cxm_iTVC15_type) {
791 if (cxm_firmware_command_nosleep(sc, cxm_dec_mailbox,
792 CXM_FW_CMD_DEC_GET_FW_VER,
796 device_printf(sc->dev, "decoder firmware version %#x\n",
797 (unsigned int)parameter);
805 cxm_configure_encoder(struct cxm_softc *sc)
809 uint32_t parameters[12];
810 const struct cxm_codec_profile *cpp;
812 if (sc->source == cxm_fm_source)
813 switch (cxm_tuner_selected_channel_set(sc)) {
815 case CHNLSET_CABLEIRC:
816 case CHNLSET_JPNBCST:
817 case CHNLSET_JPNCABLE:
826 fps = cxm_saa7115_detected_fps(sc);
831 if (sc->profile->fps != fps) {
834 * Pick a profile with the correct fps using the
835 * chosen stream type and width to decide between
836 * the VCD, SVCD, or DVD profiles.
839 for (i = 0; i < NUM_ELEMENTS(codec_profiles); i++)
840 if (codec_profiles[i]->fps == fps
841 && codec_profiles[i]->stream_type
842 == sc->profile->stream_type
843 && codec_profiles[i]->width == sc->profile->width)
846 if (i >= NUM_ELEMENTS(codec_profiles))
849 sc->profile = codec_profiles[i];
854 if (cxm_saa7115_configure(sc,
855 cpp->width, cpp->source_height, fps,
856 cpp->audio_sample_rate) < 0)
859 /* assign dma block len */
860 parameters[0] = 1; /* Transfer block size = 1 */
861 parameters[1] = 1; /* Units = 1 (frames) */
862 if (cxm_firmware_command(sc, cxm_enc_mailbox,
863 CXM_FW_CMD_ASSIGN_DMA_BLOCKLEN,
868 /* assign program index info */
869 parameters[0] = 0; /* Picture mask = 0 (don't generate index) */
870 parameters[1] = 0; /* Num_req = 0 */
871 if (cxm_firmware_command(sc, cxm_enc_mailbox,
872 CXM_FW_CMD_ASSIGN_PGM_INDEX_INFO,
876 /* assign stream type */
877 parameters[0] = cpp->stream_type;
878 if (cxm_firmware_command(sc, cxm_enc_mailbox,
879 CXM_FW_CMD_ASSIGN_STREAM_TYPE,
883 /* assign output port */
884 parameters[0] = 0; /* 0 (Memory) */
885 if (cxm_firmware_command(sc, cxm_enc_mailbox,
886 CXM_FW_CMD_ASSIGN_OUTPUT_PORT,
890 /* assign framerate */
891 parameters[0] = cpp->fps == 30 ? 0 : 1;
892 if (cxm_firmware_command(sc, cxm_enc_mailbox,
893 CXM_FW_CMD_ASSIGN_FRAME_RATE,
897 /* assign frame size */
898 parameters[0] = cpp->height;
899 parameters[1] = cpp->width;
900 if (cxm_firmware_command(sc, cxm_enc_mailbox,
901 CXM_FW_CMD_ASSIGN_FRAME_SIZE,
905 /* assign aspect ratio */
906 parameters[0] = cpp->aspect;
907 if (cxm_firmware_command(sc, cxm_enc_mailbox,
908 CXM_FW_CMD_ASSIGN_ASPECT_RATIO,
912 /* assign bitrates */
913 parameters[0] = cpp->bitrate.mode;
914 parameters[1] = cpp->bitrate.average;
915 parameters[2] = cpp->bitrate.peak / 400;
916 if (cxm_firmware_command(sc, cxm_enc_mailbox,
917 CXM_FW_CMD_ASSIGN_BITRATES,
921 /* assign gop closure */
922 parameters[0] = cpp->gop.closure;
923 if (cxm_firmware_command(sc, cxm_enc_mailbox,
924 CXM_FW_CMD_ASSIGN_GOP_CLOSURE,
928 /* assign gop properties */
929 parameters[0] = cpp->gop.frames;
930 parameters[1] = cpp->gop.bframes;
931 if (cxm_firmware_command(sc, cxm_enc_mailbox,
932 CXM_FW_CMD_ASSIGN_GOP_PROPERTIES,
936 /* assign 3 2 pulldown */
937 parameters[0] = cpp->pulldown;
938 if (cxm_firmware_command(sc, cxm_enc_mailbox,
939 CXM_FW_CMD_ASSIGN_3_2_PULLDOWN,
943 /* assign dnr filter mode */
944 parameters[0] = cpp->dnr.mode;
945 parameters[1] = cpp->dnr.type;
946 if (cxm_firmware_command(sc, cxm_enc_mailbox,
947 CXM_FW_CMD_ASSIGN_DNR_FILTER_MODE,
951 /* assign dnr filter props */
952 parameters[0] = cpp->dnr.spatial;
953 parameters[1] = cpp->dnr.temporal;
954 if (cxm_firmware_command(sc, cxm_enc_mailbox,
955 CXM_FW_CMD_ASSIGN_DNR_FILTER_PROPERTIES,
960 * assign audio properties
963 for (i = 0; i < NUM_ELEMENTS(codec_audio_formats); i++)
964 if (codec_audio_formats[i].sample_rate
965 == cpp->audio_sample_rate)
968 if (i >= NUM_ELEMENTS(codec_audio_formats))
971 parameters[0] = codec_audio_formats[i].format;
972 if (cxm_firmware_command(sc, cxm_enc_mailbox,
973 CXM_FW_CMD_ASSIGN_AUDIO_PROPERTIES,
977 /* assign coring levels */
978 parameters[0] = 0; /* luma_h */
979 parameters[1] = 255; /* luma_l */
980 parameters[2] = 0; /* chroma_h */
981 parameters[3] = 255; /* chroma_l */
982 if (cxm_firmware_command(sc, cxm_enc_mailbox,
983 CXM_FW_CMD_ASSIGN_CORING_LEVELS,
987 /* assign spatial filter type */
988 parameters[0] = 3; /* Luminance filter = 3 (2D H/V Separable) */
989 parameters[1] = 1; /* Chrominance filter = 1 (1D Horizontal) */
990 if (cxm_firmware_command(sc, cxm_enc_mailbox,
991 CXM_FW_CMD_ASSIGN_SPATIAL_FILTER_TYPE,
995 /* assign frame drop rate */
997 if (cxm_firmware_command(sc, cxm_enc_mailbox,
998 CXM_FW_CMD_ASSIGN_FRAME_DROP_RATE,
1002 /* assign placeholder */
1003 parameters[0] = 0; /* type = 0 (Extension / UserData) */
1004 parameters[1] = 0; /* period */
1005 parameters[2] = 0; /* size_t */
1006 parameters[3] = 0; /* arg0 */
1007 parameters[4] = 0; /* arg1 */
1008 parameters[5] = 0; /* arg2 */
1009 parameters[6] = 0; /* arg3 */
1010 parameters[7] = 0; /* arg4 */
1011 parameters[8] = 0; /* arg5 */
1012 parameters[9] = 0; /* arg6 */
1013 parameters[10] = 0; /* arg7 */
1014 parameters[11] = 0; /* arg8 */
1015 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1016 CXM_FW_CMD_ASSIGN_PLACEHOLDER,
1017 parameters, 12) != 0)
1020 /* assign VBI properties */
1021 parameters[0] = 0xbd04; /* mode = 0 (sliced), stream and user data */
1022 parameters[1] = 0; /* frames per interrupt (only valid in raw mode) */
1023 parameters[2] = 0; /* total raw VBI frames (only valid in raw mode) */
1024 parameters[3] = 0x25256262; /* ITU 656 start codes (saa7115 table 24)*/
1025 parameters[4] = 0x38387f7f; /* ITU 656 stop codes (saa7115 table 24) */
1026 parameters[5] = cpp->vbi.nlines; /* lines per frame */
1027 parameters[6] = 1440; /* bytes per line = 720 pixels */
1028 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1029 CXM_FW_CMD_ASSIGN_VBI_PROPERTIES,
1030 parameters, 7) != 0)
1033 /* assign VBI lines */
1034 parameters[0] = 0xffffffff; /* all lines */
1035 parameters[1] = 0; /* disable VBI features */
1039 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1040 CXM_FW_CMD_ASSIGN_VBI_LINE,
1041 parameters, 5) != 0)
1044 /* assign number of lines in fields 1 and 2 */
1045 parameters[0] = cpp->source_height / 2 + cpp->vbi.nlines;
1046 parameters[1] = cpp->source_height / 2 + cpp->vbi.nlines;
1047 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1048 CXM_FW_CMD_ASSIGN_NUM_VSYNC_LINES,
1049 parameters, 2) != 0)
1057 cxm_start_encoder(struct cxm_softc *sc)
1059 uint32_t parameters[4];
1067 if (cxm_configure_encoder(sc) < 0)
1070 /* Mute the video input if necessary. */
1071 parameters[0] = sc->source == cxm_fm_source ? 1 : 0;
1072 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1073 CXM_FW_CMD_MUTE_VIDEO_INPUT,
1074 parameters, 1) != 0)
1077 /* Clear pending encoder interrupts (which are currently masked) */
1078 cxm_set_irq_status(sc, CXM_IRQ_ENC);
1080 /* Enable event notification */
1081 parameters[0] = 0; /* Event = 0 (refresh encoder input) */
1082 parameters[1] = 1; /* Notification = 1 (enable) */
1083 parameters[2] = 0x10000000; /* Interrupt bit */
1084 parameters[3] = -1; /* Mailbox = -1 (no mailbox) */
1085 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1086 CXM_FW_CMD_ENC_EVENT_NOTIFICATION,
1087 parameters, 4) != 0)
1090 if (cxm_saa7115_mute(sc) < 0)
1092 if (cxm_msp_mute(sc) < 0)
1095 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1096 CXM_FW_CMD_INITIALIZE_VIDEO_INPUT,
1100 if (cxm_saa7115_unmute(sc) < 0)
1102 if (cxm_msp_unmute(sc) < 0)
1105 /* Wait for 100ms */
1106 tsleep(&sc->encoding, 0, "cxmce", hz / 10);
1108 type = sc->mpeg ? CXM_FW_CAPTURE_STREAM_TYPE_MPEG
1109 : CXM_FW_CAPTURE_STREAM_TYPE_RAW;
1110 subtype = ((sc->mpeg || sc->source == cxm_fm_source)
1111 ? CXM_FW_CAPTURE_STREAM_PCM_AUDIO : 0)
1112 | ((sc->mpeg || sc->source != cxm_fm_source)
1113 ? CXM_FW_CAPTURE_STREAM_YUV : 0);
1115 /* Start the encoder */
1116 parameters[0] = type;
1117 parameters[1] = subtype;
1118 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1119 CXM_FW_CMD_BEGIN_CAPTURE, parameters, 2) != 0)
1122 sc->enc_pool.offset = 0;
1123 sc->enc_pool.read = 0;
1124 sc->enc_pool.write = 0;
1126 sc->encoding_eos = 0;
1130 /* Enable interrupts */
1131 cxm_set_irq_mask(sc, sc->irq_mask & ~CXM_IRQ_ENC);
1138 cxm_stop_encoder(struct cxm_softc *sc)
1140 uint32_t parameters[4];
1147 type = sc->mpeg ? CXM_FW_CAPTURE_STREAM_TYPE_MPEG
1148 : CXM_FW_CAPTURE_STREAM_TYPE_RAW;
1149 subtype = ((sc->mpeg || sc->source == cxm_fm_source)
1150 ? CXM_FW_CAPTURE_STREAM_PCM_AUDIO : 0)
1151 | ((sc->mpeg || sc->source != cxm_fm_source)
1152 ? CXM_FW_CAPTURE_STREAM_YUV : 0);
1154 /* Stop the encoder */
1155 parameters[0] = sc->mpeg ? 0 : 1; /* When = 0 (end of GOP) */
1156 parameters[1] = type;
1157 parameters[2] = subtype;
1158 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1159 CXM_FW_CMD_END_CAPTURE, parameters, 3) != 0)
1162 /* Wait for up to 1 second */
1164 if (!sc->encoding_eos)
1165 tsleep(&sc->encoding_eos, 0, "cxmeos", hz);
1168 if (sc->mpeg && !sc->encoding_eos)
1169 device_printf(sc->dev, "missing encoder EOS\n");
1171 /* Disable event notification */
1172 parameters[0] = 0; /* Event = 0 (refresh encoder input) */
1173 parameters[1] = 0; /* Notification = 0 (disable) */
1174 parameters[2] = 0x10000000; /* Interrupt bit */
1175 parameters[3] = -1; /* Mailbox = -1 (no mailbox) */
1176 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1177 CXM_FW_CMD_ENC_EVENT_NOTIFICATION,
1178 parameters, 4) != 0)
1181 /* Disable interrupts */
1182 cxm_set_irq_mask(sc, sc->irq_mask | CXM_IRQ_ENC);
1191 cxm_pause_encoder(struct cxm_softc *sc)
1195 /* Pause the encoder */
1197 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1198 CXM_FW_CMD_PAUSE_ENCODER, ¶meter, 1) != 0)
1206 cxm_unpause_encoder(struct cxm_softc *sc)
1210 /* Unpause the encoder */
1212 if (cxm_firmware_command(sc, cxm_enc_mailbox,
1213 CXM_FW_CMD_PAUSE_ENCODER, ¶meter, 1) != 0)
1221 cxm_encoder_fixup_byte_order(struct cxm_softc *sc,
1222 unsigned int current, size_t offset)
1224 unsigned int strips;
1228 unsigned int macroblocks_per_line;
1229 unsigned int scratch;
1230 unsigned int words_per_line;
1235 switch (sc->enc_pool.bufs[current].byte_order) {
1236 case cxm_device_mpeg_byte_order:
1239 * Convert each 32 bit word to the proper byte ordering.
1243 ptr = (uint32_t *)sc->enc_pool.bufs[current].vaddr;
1244 nbytes != sc->enc_pool.bufs[current].size;
1245 nbytes += sizeof(*ptr), ptr++)
1246 *ptr = bswap32(*ptr);
1249 case cxm_device_yuv12_byte_order:
1252 * Convert each macro block to planar using
1253 * a scratch buffer (the buffer prior to the
1254 * current buffer is always free since it marks
1255 * the end of the ring buffer).
1258 scratch = (current + (CXM_SG_BUFFERS - 1)) % CXM_SG_BUFFERS;
1265 src = (uint32_t *)sc->enc_pool.bufs[current].vaddr;
1266 words_per_line = sc->profile->width / sizeof(*ptr);
1267 macroblocks_per_line
1268 = sc->profile->width / CXM_MACROBLOCK_WIDTH;
1269 strips = sc->enc_pool.bufs[current].size
1270 / (macroblocks_per_line * CXM_MACROBLOCK_SIZE);
1272 for (i = 0; i < strips; i++) {
1273 ptr = (uint32_t *)sc->enc_pool.bufs[scratch].vaddr
1274 + i * macroblocks_per_line * CXM_MACROBLOCK_SIZE
1276 for (j = 0; j < macroblocks_per_line; j++) {
1277 for (k = 0; k < CXM_MACROBLOCK_HEIGHT; k++) {
1278 #if CXM_MACROBLOCK_WIDTH != 16
1279 # error CXM_MACROBLOCK_WIDTH != 16
1281 *(ptr + k * words_per_line)
1283 *(ptr + k * words_per_line + 1)
1285 *(ptr + k * words_per_line + 2)
1287 *(ptr + k * words_per_line + 3)
1290 ptr += CXM_MACROBLOCK_WIDTH / sizeof(*ptr);
1294 sc->enc_pool.bufs[scratch].size
1295 = sc->enc_pool.bufs[current].size;
1304 sc->enc_pool.bufs[current].byte_order = cxm_host_byte_order;
1311 cxm_encoder_dma_discard(struct cxm_softc *sc)
1313 uint32_t parameters[3];
1315 /* Discard the DMA request */
1319 if (cxm_queue_firmware_command(sc, cxm_enc_mailbox,
1320 CXM_FW_CMD_SCHED_DMA_TO_HOST,
1321 parameters, 3) == -1) {
1322 device_printf(sc->dev,
1323 "failed to discard encoder dma request\n");
1327 sc->encoding_dma = -1;
1332 cxm_encoder_dma_done(struct cxm_softc *sc)
1334 int buffers_pending;
1337 if (!sc->encoding_dma) {
1338 device_printf(sc->dev,
1339 "encoder dma not already in progress\n");
1343 buffers_pending = sc->encoding_dma;
1344 sc->encoding_dma = 0;
1346 if (buffers_pending < 0)
1349 status = CSR_READ_4(sc, CXM_REG_DMA_STATUS) & 0x0000000f;
1352 & (CXM_DMA_ERROR_LIST | CXM_DMA_ERROR_WRITE | CXM_DMA_SUCCESS))
1353 != CXM_DMA_SUCCESS) {
1354 device_printf(sc->dev, "encoder dma status %#x\n",
1355 (unsigned int)status);
1359 /* Update the books */
1361 sc->enc_pool.write = (sc->enc_pool.write + buffers_pending)
1365 /* signal anyone requesting notification */
1367 ksignal (sc->enc_proc, sc->enc_signal);
1369 /* wakeup anyone waiting for data */
1370 wakeup(&sc->enc_pool.read);
1372 /* wakeup anyone polling for data */
1373 KNOTE(&sc->enc_sel.si_note, 0);
1378 cxm_encoder_dma_request(struct cxm_softc *sc)
1380 enum cxm_byte_order byte_order;
1382 int buffers_pending;
1383 unsigned int current;
1385 unsigned int mailbox;
1386 unsigned int macroblocks_per_line;
1387 unsigned int nrequests;
1388 unsigned int strips;
1389 uint32_t parameters[CXM_MBX_MAX_PARAMETERS];
1391 size_t max_sg_segment;
1397 if (sc->encoding_dma) {
1398 device_printf(sc->dev, "encoder dma already in progress\n");
1399 cxm_encoder_dma_discard(sc);
1403 mailbox = sc->enc_mbx
1404 + CXM_MBX_FW_DMA_MAILBOX * sizeof(struct cxm_mailbox);
1406 for (i = 0; i < CXM_MBX_MAX_PARAMETERS; i++)
1410 + offsetof(struct cxm_mailbox, parameters)
1411 + i * sizeof(uint32_t)
1414 byte_order = cxm_device_mpeg_byte_order;
1415 max_sg_segment = CXM_SG_SEGMENT;
1417 type = parameters[0];
1421 requests[nrequests].offset = parameters[1];
1422 requests[nrequests++].size = parameters[2];
1426 byte_order = cxm_device_yuv12_byte_order;
1429 * Simplify macroblock unpacking by ensuring
1430 * that strips don't span buffers.
1433 #if CXM_MACROBLOCK_SIZE % 256
1434 # error CXM_MACROBLOCK_SIZE not a multiple of 256
1437 macroblocks_per_line = sc->profile->width
1438 / CXM_MACROBLOCK_WIDTH;
1439 strips = CXM_SG_SEGMENT
1440 / (macroblocks_per_line * CXM_MACROBLOCK_SIZE);
1441 max_sg_segment = strips
1442 * macroblocks_per_line * CXM_MACROBLOCK_SIZE;
1444 requests[nrequests].offset = parameters[1]; /* Y */
1445 requests[nrequests++].size = parameters[2];
1446 requests[nrequests].offset = parameters[3]; /* UV */
1447 requests[nrequests++].size = parameters[4];
1450 case 2: /* PCM (audio) */
1453 device_printf(sc->dev, "encoder dma type %#x unsupported\n",
1454 (unsigned int)type);
1455 cxm_encoder_dma_discard(sc);
1460 * Determine the number of buffers free at this * instant *
1461 * taking into consideration that the ring buffer wraps.
1464 buffers_free = sc->enc_pool.read - sc->enc_pool.write;
1465 if (buffers_free <= 0)
1466 buffers_free += CXM_SG_BUFFERS;
1470 * Build the scatter / gather list taking in
1471 * consideration that the ring buffer wraps,
1472 * at least one free buffer must always be
1473 * present to mark the end of the ring buffer,
1474 * and each transfer must be a multiple of 256.
1477 buffers_pending = 0;
1478 current = sc->enc_pool.write;
1480 for (i = 0; i < nrequests; i++) {
1481 if (!requests[i].size) {
1482 device_printf(sc->dev, "encoder dma size is zero\n");
1483 cxm_encoder_dma_discard(sc);
1487 while (requests[i].size) {
1488 sc->enc_pool.bufs[current].size
1489 = requests[i].size > max_sg_segment
1490 ? max_sg_segment : requests[i].size;
1491 sc->enc_pool.bufs[current].byte_order = byte_order;
1493 sc->enc_sg.vaddr[buffers_pending].src
1494 = requests[i].offset;
1495 sc->enc_sg.vaddr[buffers_pending].dst
1496 = sc->enc_pool.bufs[current].baddr;
1497 sc->enc_sg.vaddr[buffers_pending].size
1498 = (sc->enc_pool.bufs[current].size + 0x000000ff)
1501 requests[i].offset += sc->enc_pool.bufs[current].size;
1502 requests[i].size -= sc->enc_pool.bufs[current].size;
1504 current = (current + 1) % CXM_SG_BUFFERS;
1506 if (buffers_pending >= buffers_free) {
1507 device_printf(sc->dev,
1508 "encoder dma not enough buffer space free\n");
1509 cxm_encoder_dma_discard(sc);
1515 /* Mark the last transfer in the list */
1516 sc->enc_sg.vaddr[buffers_pending - 1].size |= 0x80000000;
1518 /* Schedule the DMA */
1519 parameters[0] = sc->enc_sg.baddr;
1520 parameters[1] = buffers_pending * sizeof(sc->enc_sg.vaddr[0]);
1521 parameters[2] = type;
1522 if (cxm_queue_firmware_command(sc, cxm_enc_mailbox,
1523 CXM_FW_CMD_SCHED_DMA_TO_HOST,
1524 parameters, 3) == -1) {
1525 device_printf(sc->dev,
1526 "failed to schedule encoder dma request\n");
1531 * Record the number of pending buffers for the
1532 * benefit of cxm_encoder_dma_done. Doing this
1533 * after queuing the command doesn't introduce
1534 * a race condition since we're already in the
1535 * interrupt handler.
1538 sc->encoding_dma = buffers_pending;
1543 cxm_encoder_wait_for_lock(struct cxm_softc *sc)
1552 * Wait for the tuner to lock.
1554 if (sc->source == cxm_fm_source || sc->source == cxm_tuner_source) {
1555 result = cxm_tuner_wait_for_lock(sc);
1561 * Wait for the video decoder to lock.
1563 if (sc->source != cxm_fm_source) {
1564 result = cxm_saa7115_wait_for_lock(sc);
1567 else if (result == 0)
1572 * Wait for the audio decoder to lock.
1574 if (sc->source == cxm_tuner_source) {
1575 muted = cxm_msp_is_muted(sc);
1577 result = cxm_msp_autodetect_standard(sc);
1580 else if (result == 0)
1583 if (muted == 0 && cxm_msp_unmute(sc) < 0)
1592 cxm_mapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1594 bus_addr_t *busaddrp;
1597 * Only the first bus space address is needed
1598 * since it's known that the memory is physically
1599 * contiguous due to bus_dmamem_alloc.
1602 busaddrp = (bus_addr_t *)arg;
1603 *busaddrp = segs->ds_addr;
1608 * the boot time probe routine.
1611 cxm_probe(device_t dev)
1617 while(t->name != NULL) {
1618 if ((pci_get_vendor(dev) == t->vid) &&
1619 (pci_get_device(dev) == t->did)) {
1620 device_set_desc(dev, t->name);
1631 * the attach routine.
1634 cxm_attach(device_t dev)
1641 struct cxm_softc *sc;
1643 /* Get the device data */
1644 sc = device_get_softc(dev);
1645 unit = device_get_unit(dev);
1648 sc->type = cxm_iTVC15_type;
1650 switch(pci_get_device(dev)) {
1651 case PCI_PRODUCT_ICOMPRESSION_ITVC16:
1652 sc->type = cxm_iTVC16_type;
1660 * Enable bus mastering and memory mapped I/O.
1662 pci_enable_busmaster(dev);
1663 pci_enable_io(dev, SYS_RES_MEMORY);
1664 command = pci_read_config(dev, PCIR_COMMAND, 4);
1666 if (!(command & PCIM_CMD_MEMEN)) {
1667 device_printf(dev, "failed to enable memory mappings\n");
1673 * Map control/status registers.
1676 sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
1677 0, ~0, 1, RF_ACTIVE);
1680 device_printf(dev, "could not map memory\n");
1685 sc->btag = rman_get_bustag(sc->mem_res);
1686 sc->bhandle = rman_get_bushandle(sc->mem_res);
1689 * Attach the I2C bus.
1691 sc->cxm_iic = device_add_child(dev, "cxm_iic", unit);
1694 device_printf(dev, "could not add cxm_iic\n");
1699 error = device_probe_and_attach(sc->cxm_iic);
1702 device_printf(dev, "could not attach cxm_iic\n");
1707 * Initialize the tuner.
1709 if (cxm_tuner_init(sc) < 0) {
1710 device_printf(dev, "could not initialize tuner\n");
1716 * Initialize the SAA7115.
1718 if (cxm_saa7115_init(sc) < 0) {
1719 device_printf(dev, "could not initialize video decoder\n");
1725 * Initialize the MSP3400.
1727 if (cxm_msp_init(sc) < 0) {
1728 device_printf(dev, "could not initialize audio decoder\n");
1734 * Initialize the IR Remote.
1736 if (cxm_ir_init(sc) < 0) {
1737 device_printf(dev, "could not initialize IR remote\n");
1746 * Disable the Conexant device.
1748 * This is done * after * attaching the I2C bus so
1749 * cxm_stop_hardware can mute the video and audio
1752 cxm_stop_hardware(sc);
1755 * Allocate our interrupt.
1758 sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
1759 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
1761 if (sc->irq_res == NULL) {
1762 device_printf(dev, "could not map interrupt\n");
1767 error = bus_setup_intr(dev, sc->irq_res, 0,
1768 cxm_intr, sc, &sc->ih_cookie, NULL);
1770 device_printf(dev, "could not setup irq\n");
1776 * Allocate a DMA tag for the parent bus.
1778 error = bus_dma_tag_create(NULL, 1, 0,
1779 BUS_SPACE_MAXADDR_32BIT,
1780 BUS_SPACE_MAXADDR, NULL, NULL,
1781 BUS_SPACE_MAXSIZE_32BIT, 1,
1782 BUS_SPACE_MAXSIZE_32BIT, 0,
1785 device_printf(dev, "could not create parent bus DMA tag\n");
1790 * Allocate a DMA tag for the encoder buffers.
1792 error = bus_dma_tag_create(sc->parent_dmat, 256, 0,
1793 BUS_SPACE_MAXADDR_32BIT,
1794 BUS_SPACE_MAXADDR, NULL, NULL,
1796 BUS_SPACE_MAXSIZE_32BIT, 0,
1797 &sc->enc_pool.dmat);
1800 "could not create encoder buffer DMA tag\n");
1804 for (i = 0; i < CXM_SG_BUFFERS; i++) {
1807 * Allocate the encoder buffer.
1809 error = bus_dmamem_alloc(sc->enc_pool.dmat,
1810 (void **)&sc->enc_pool.bufs[i].vaddr,
1812 &sc->enc_pool.bufs[i].dmamap);
1815 "could not allocate encoder buffer\n");
1820 * Map the encoder buffer.
1822 error = bus_dmamap_load(sc->enc_pool.dmat,
1823 sc->enc_pool.bufs[i].dmamap,
1824 sc->enc_pool.bufs[i].vaddr,
1827 &sc->enc_pool.bufs[i].baddr, 0);
1829 device_printf(dev, "could not map encoder buffer\n");
1835 * Allocate a DMA tag for the scatter / gather list.
1837 error = bus_dma_tag_create(sc->parent_dmat, 1, 0,
1838 BUS_SPACE_MAXADDR_32BIT,
1839 BUS_SPACE_MAXADDR, NULL, NULL,
1841 * sizeof(struct cxm_sg_entry), 1,
1842 BUS_SPACE_MAXSIZE_32BIT, 0,
1846 "could not create scatter / gather DMA tag\n");
1851 * Allocate the scatter / gather list.
1853 error = bus_dmamem_alloc(sc->enc_sg.dmat, (void **)&sc->enc_sg.vaddr,
1854 BUS_DMA_NOWAIT, &sc->enc_sg.dmamap);
1857 "could not allocate scatter / gather list\n");
1862 * Map the scatter / gather list.
1864 error = bus_dmamap_load(sc->enc_sg.dmat, sc->enc_sg.dmamap,
1866 CXM_SG_BUFFERS * sizeof(struct cxm_sg_entry),
1867 cxm_mapmem, &sc->enc_sg.baddr, 0);
1869 device_printf(dev, "could not map scatter / gather list\n");
1874 * Initialize the hardware.
1876 if (cxm_init_hardware(sc) < 0) {
1877 device_printf(dev, "could not initialize hardware\n");
1882 sc->profile = &dvd_full_d1_ntsc_profile;
1884 sc->source = cxm_tuner_source;
1887 /* make the device entries */
1888 sc->cxm_dev_t = make_dev(&cxm_ops, unit,
1889 0, 0, 0444, "cxm%d", unit);
1894 if (sc->enc_sg.baddr)
1895 bus_dmamap_unload(sc->enc_sg.dmat, sc->enc_sg.dmamap);
1896 if (sc->enc_sg.vaddr)
1897 bus_dmamem_free(sc->enc_sg.dmat, sc->enc_sg.vaddr,
1899 if (sc->enc_sg.dmat)
1900 bus_dma_tag_destroy(sc->enc_sg.dmat);
1902 for (i = 0; i < CXM_SG_BUFFERS; i++) {
1903 if (sc->enc_pool.bufs[i].baddr)
1904 bus_dmamap_unload(sc->enc_pool.dmat,
1905 sc->enc_pool.bufs[i].dmamap);
1906 if (sc->enc_pool.bufs[i].vaddr)
1907 bus_dmamem_free(sc->enc_pool.dmat,
1908 sc->enc_pool.bufs[i].vaddr,
1909 sc->enc_pool.bufs[i].dmamap);
1912 if (sc->enc_pool.dmat)
1913 bus_dma_tag_destroy(sc->enc_pool.dmat);
1915 if (sc->parent_dmat)
1916 bus_dma_tag_destroy(sc->parent_dmat);
1919 * Detach the I2C bus.
1921 * This is done * after * deallocating the scatter / gather
1922 * list and buffers so the kernel has a better chance of
1923 * gracefully handling a memory shortage.
1925 * Detach the children before recursively deleting
1926 * in case a child has a pointer to a grandchild
1927 * which is used by the child's detach routine.
1929 bus_generic_detach(dev);
1931 device_delete_child(dev, sc->cxm_iic);
1934 bus_teardown_intr(dev, sc->irq_res, sc->ih_cookie);
1936 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
1938 bus_release_resource(dev, SYS_RES_MEMORY, CXM_RID, sc->mem_res);
1944 * the detach routine.
1947 cxm_detach(device_t dev)
1950 struct cxm_softc *sc;
1953 /* Get the device data */
1954 sc = device_get_softc(dev);
1956 /* Disable the Conexant device. */
1957 cxm_stop_hardware(sc);
1959 /* Unregister the /dev/cxmN device. */
1960 dev_ops_remove_minor(&cxm_ops, /*0, */device_get_unit(dev));
1963 * Deallocate scatter / gather list and buffers.
1965 bus_dmamap_unload(sc->enc_sg.dmat, sc->enc_sg.dmamap);
1966 bus_dmamem_free(sc->enc_sg.dmat, sc->enc_sg.vaddr, sc->enc_sg.dmamap);
1968 bus_dma_tag_destroy(sc->enc_sg.dmat);
1970 for (i = 0; i < CXM_SG_BUFFERS; i++) {
1971 bus_dmamap_unload(sc->enc_pool.dmat,
1972 sc->enc_pool.bufs[i].dmamap);
1973 bus_dmamem_free(sc->enc_pool.dmat, sc->enc_pool.bufs[i].vaddr,
1974 sc->enc_pool.bufs[i].dmamap);
1977 bus_dma_tag_destroy(sc->enc_pool.dmat);
1979 bus_dma_tag_destroy(sc->parent_dmat);
1982 * Detach the I2C bus.
1984 * This is done * after * deallocating the scatter / gather
1985 * list and buffers so the kernel has a better chance of
1986 * gracefully handling a memory shortage.
1988 * Detach the children before recursively deleting
1989 * in case a child has a pointer to a grandchild
1990 * which is used by the child's detach routine.
1992 * Remember the child before detaching so we can
1993 * delete it (bus_generic_detach indirectly zeroes
1996 child = sc->cxm_iic;
1997 bus_generic_detach(dev);
1999 device_delete_child(dev, child);
2001 /* Deallocate resources. */
2002 bus_teardown_intr(dev, sc->irq_res, sc->ih_cookie);
2003 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
2004 bus_release_resource(dev, SYS_RES_MEMORY, CXM_RID, sc->mem_res);
2010 * the shutdown routine.
2013 cxm_shutdown(device_t dev)
2015 struct cxm_softc *sc = device_get_softc(dev);
2017 /* Disable the Conexant device. */
2018 cxm_stop_hardware(sc);
2024 * the interrupt routine.
2030 struct cxm_softc *sc;
2032 /* Get the device data */
2033 sc = (struct cxm_softc *)arg;
2035 status = CSR_READ_4(sc, CXM_REG_IRQ_STATUS);
2037 status &= ~sc->irq_mask;
2042 /* Process DMA done before handling a new DMA request or EOS */
2043 if (status & CXM_IRQ_ENC_DMA_DONE)
2044 cxm_encoder_dma_done(sc);
2046 if (status & CXM_IRQ_ENC_DMA_REQUEST)
2047 cxm_encoder_dma_request(sc);
2049 if (status & CXM_IRQ_ENC_EOS) {
2050 sc->encoding_eos = 1;
2051 wakeup(&sc->encoding_eos);
2054 cxm_set_irq_status(sc, status);
2059 * the child detached routine.
2062 cxm_child_detached(device_t dev, device_t child)
2064 struct cxm_softc *sc;
2066 /* Get the device data */
2067 sc = device_get_softc(dev);
2069 if (child == sc->cxm_iic)
2075 cxm_read_ivar(device_t dev, device_t child, int index, uintptr_t* val)
2077 struct cxm_softc *sc;
2079 /* Get the device data */
2080 sc = device_get_softc(dev);
2083 case CXM_IVAR_BHANDLE:
2084 *(bus_space_handle_t **)val = &sc->bhandle;
2088 *(bus_space_tag_t **)val = &sc->btag;
2091 case CXM_IVAR_IICBUS:
2092 *(device_t **)val = &sc->iicbus;
2104 cxm_write_ivar(device_t dev, device_t child, int index, uintptr_t val)
2106 struct cxm_softc *sc;
2108 /* Get the device data */
2109 sc = device_get_softc(dev);
2112 case CXM_IVAR_BHANDLE:
2118 case CXM_IVAR_IICBUS:
2121 sc->iicbus = val ? *(device_t *)val : NULL;
2132 /*---------------------------------------------------------
2134 ** Conexant iTVC15 / iTVC16 character device driver routines
2136 **---------------------------------------------------------
2139 #define UNIT(x) ((x) & 0x0f)
2140 #define FUNCTION(x) (x >> 4)
2146 cxm_open(struct dev_open_args *ap)
2148 cdev_t dev = ap->a_head.a_dev;
2150 struct cxm_softc *sc;
2152 unit = UNIT(minor(dev));
2154 /* Get the device data */
2155 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2157 /* the device is no longer valid/functioning */
2167 /* Record that the device is now busy */
2168 device_busy(devclass_get_device(cxm_devclass, unit));
2178 cxm_close(struct dev_close_args *ap)
2180 cdev_t dev = ap->a_head.a_dev;
2182 struct cxm_softc *sc;
2184 unit = UNIT(minor(dev));
2186 /* Get the device data */
2187 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2189 /* the device is no longer valid/functioning */
2193 if (cxm_stop_encoder(sc) < 0)
2196 sc->enc_pool.offset = 0;
2197 sc->enc_pool.read = 0;
2198 sc->enc_pool.write = 0;
2200 sc->enc_proc = NULL;
2203 device_unbusy(devclass_get_device(cxm_devclass, unit));
2215 cxm_read(struct dev_read_args *ap)
2217 cdev_t dev = ap->a_head.a_dev;
2218 int buffers_available;
2222 unsigned int current;
2226 struct cxm_softc *sc;
2228 unit = UNIT(minor(dev));
2230 /* Get the device data */
2231 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2233 /* the device is no longer valid/functioning */
2237 /* Only trigger the encoder if the ring buffer is empty */
2238 if (!sc->encoding && sc->enc_pool.read == sc->enc_pool.write) {
2239 if (cxm_start_encoder(sc) < 0)
2241 if (ap->a_ioflag & IO_NDELAY)
2245 buffers_available = 0;
2248 while (sc->enc_pool.read == sc->enc_pool.write) {
2249 error = tsleep(&sc->enc_pool.read, PCATCH, "cxmrd", 0);
2257 * Determine the number of buffers available at this * instant *
2258 * taking in consideration that the ring buffer wraps.
2260 buffers_available = sc->enc_pool.write - sc->enc_pool.read;
2261 if (buffers_available < 0)
2262 buffers_available += CXM_SG_BUFFERS;
2265 offset = sc->enc_pool.offset;
2267 for (buffers_read = 0, i = sc->enc_pool.read;
2268 buffers_read != buffers_available && ap->a_uio->uio_resid;
2269 buffers_read++, i = (i + 1) % CXM_SG_BUFFERS) {
2271 current = cxm_encoder_fixup_byte_order (sc, i, offset);
2273 nbytes = sc->enc_pool.bufs[current].size - offset;
2275 /* Don't transfer more than requested */
2276 if (nbytes > ap->a_uio->uio_resid)
2277 nbytes = ap->a_uio->uio_resid;
2279 error = uiomove(sc->enc_pool.bufs[current].vaddr + offset,
2286 /* Handle a partial read of a buffer */
2287 if (!ap->a_uio->uio_resid && offset != sc->enc_pool.bufs[i].size)
2293 sc->enc_pool.offset = offset;
2295 /* Update the books */
2297 sc->enc_pool.read = (sc->enc_pool.read + buffers_read)
2309 cxm_ioctl(struct dev_ioctl_args *ap)
2311 cdev_t dev = ap->a_head.a_dev;
2313 int chroma_saturation;
2323 struct cxm_softc *sc;
2324 enum cxm_source source;
2325 struct bktr_capture_area *cap;
2326 struct bktr_remote *remote;
2328 unit = UNIT(minor(dev));
2330 /* Get the device data */
2331 sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2333 /* the device is no longer valid/functioning */
2337 switch (ap->a_cmd) {
2339 switch (cxm_msp_selected_source(sc)) {
2340 case cxm_tuner_source:
2341 *(int *) ap->a_data = AUDIO_TUNER;
2344 case cxm_line_in_source_composite:
2345 case cxm_line_in_source_svideo:
2346 *(int *) ap->a_data = AUDIO_EXTERN;
2350 *(int *) ap->a_data = AUDIO_INTERN;
2357 if (cxm_msp_is_muted(sc) == 1)
2358 *(int *) ap->a_data |= AUDIO_MUTE;
2362 source = cxm_unknown_source;
2364 switch (*(int *) ap->a_data) {
2366 source = cxm_tuner_source;
2370 source = cxm_line_in_source_composite;
2374 source = cxm_fm_source;
2378 if (cxm_msp_mute(sc) < 0)
2383 if (cxm_msp_unmute(sc) < 0)
2394 * Switching between audio + video and audio only
2395 * subtypes isn't supported while encoding.
2398 if (source != sc->source
2399 && (source == cxm_fm_source
2400 || sc->source == cxm_fm_source))
2404 if (cxm_pause_encoder(sc) < 0)
2407 if (cxm_msp_select_source(sc, source) < 0)
2410 if (source == cxm_fm_source)
2411 sc->source = source;
2413 result = cxm_encoder_wait_for_lock(sc);
2416 else if (result == 0)
2419 if (cxm_unpause_encoder(sc) < 0)
2424 brightness = cxm_saa7115_get_brightness(sc);
2430 * Brooktree brightness:
2431 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6%
2433 *(int *)ap->a_data = (int)(unsigned char)brightness - 128;
2439 * Brooktree brightness:
2440 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6%
2442 brightness = *(int *)ap->a_data + 128;
2444 if (cxm_saa7115_set_brightness(sc, brightness) < 0)
2449 brightness = cxm_saa7115_get_brightness(sc);
2454 *(unsigned char *)ap->a_data = (unsigned char)brightness;
2458 brightness = *(unsigned char *)ap->a_data;
2460 if (cxm_saa7115_set_brightness(sc, brightness) < 0)
2465 chroma_saturation = cxm_saa7115_get_chroma_saturation(sc);
2467 if (chroma_saturation < 0)
2471 * Brooktree chroma saturation:
2472 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18%
2474 *(int *)ap->a_data = ((signed char)chroma_saturation > 0)
2475 ? (chroma_saturation * 4 - 2) : 0;
2481 * Brooktree chroma saturation:
2482 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18%
2484 chroma_saturation = (*(int *)ap->a_data & 0x1ff) < 510
2485 ? ((*(int *)ap->a_data & 0x1ff) + 2) / 4 : 127;
2487 if (cxm_saa7115_set_chroma_saturation(sc, chroma_saturation)
2494 chroma_saturation = cxm_saa7115_get_chroma_saturation(sc);
2496 if (chroma_saturation < 0)
2499 *(unsigned char *)ap->a_data = (unsigned char)chroma_saturation;
2503 chroma_saturation = *(unsigned char *)ap->a_data;
2505 if (cxm_saa7115_set_chroma_saturation(sc, chroma_saturation)
2511 contrast = cxm_saa7115_get_contrast(sc);
2516 *(unsigned char *)ap->a_data = (unsigned char)contrast;
2520 contrast = *(unsigned char *)ap->a_data;
2522 if (cxm_saa7115_set_contrast(sc, contrast) < 0)
2527 hue = cxm_saa7115_get_hue(sc);
2532 *(int *)ap->a_data = (signed char)hue;
2536 hue = *(int *)ap->a_data;
2538 if (cxm_saa7115_set_hue(sc, hue) < 0)
2543 hue = cxm_saa7115_get_hue(sc);
2548 *(signed char *)ap->a_data = (signed char)hue;
2552 hue = *(signed char *)ap->a_data;
2554 if (cxm_saa7115_set_hue(sc, hue) < 0)
2559 switch (*(int *) ap->a_data) {
2560 case METEOR_CAP_CONTINOUS:
2561 if (cxm_start_encoder(sc) < 0)
2565 case METEOR_CAP_STOP_CONT:
2566 if (cxm_stop_encoder(sc) < 0)
2575 case BT848_GCAPAREA:
2576 cap = (struct bktr_capture_area *)ap->a_data;
2577 memset (cap, 0, sizeof (*cap));
2580 cap->x_size = sc->profile->width;
2581 cap->y_size = sc->profile->height;
2584 case BT848_SCAPAREA:
2588 cap = (struct bktr_capture_area *)ap->a_data;
2589 if (cap->x_offset || cap->y_offset
2590 || (cap->x_size % CXM_MACROBLOCK_WIDTH)
2591 || (cap->y_size % CXM_MACROBLOCK_HEIGHT))
2595 * Setting the width and height has the side effect of
2596 * chosing between the VCD, SVCD, and DVD profiles.
2599 for (i = 0; i < NUM_ELEMENTS(codec_profiles); i++)
2600 if (codec_profiles[i]->width == cap->x_size
2601 && codec_profiles[i]->height == cap->y_size)
2604 if (i >= NUM_ELEMENTS(codec_profiles))
2607 sc->profile = codec_profiles[i];
2611 switch (cxm_saa7115_detected_format(sc)) {
2612 case cxm_ntsc_60hz_source_format:
2613 *(unsigned long *)ap->a_data = BT848_IFORM_F_NTSCM;
2616 case cxm_pal_50hz_source_format:
2617 *(unsigned long *)ap->a_data = BT848_IFORM_F_PALBDGHI;
2620 case cxm_secam_50hz_source_format:
2621 *(unsigned long *)ap->a_data = BT848_IFORM_F_SECAM;
2624 case cxm_pal_60hz_source_format:
2625 *(unsigned long *)ap->a_data = BT848_IFORM_F_PALM;
2628 case cxm_bw_50hz_source_format:
2629 case cxm_bw_60hz_source_format:
2630 case cxm_ntsc_50hz_source_format:
2631 *(unsigned long *)ap->a_data = BT848_IFORM_F_AUTO;
2640 switch (cxm_saa7115_detected_format(sc)) {
2641 case cxm_ntsc_60hz_source_format:
2642 *(unsigned long *)ap->a_data = METEOR_FMT_NTSC;
2645 case cxm_pal_50hz_source_format:
2646 *(unsigned long *)ap->a_data = METEOR_FMT_PAL;
2649 case cxm_secam_50hz_source_format:
2650 *(unsigned long *)ap->a_data = METEOR_FMT_SECAM;
2653 case cxm_bw_50hz_source_format:
2654 case cxm_bw_60hz_source_format:
2655 case cxm_ntsc_50hz_source_format:
2656 case cxm_pal_60hz_source_format:
2657 *(unsigned long *)ap->a_data = METEOR_FMT_AUTOMODE;
2666 fps = cxm_saa7115_detected_fps(sc);
2671 *(unsigned short *)ap->a_data = fps;
2675 switch (sc->source) {
2676 case cxm_tuner_source:
2677 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV1;
2680 case cxm_line_in_source_composite:
2681 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV2;
2684 case cxm_line_in_source_svideo:
2685 *(unsigned long *)ap->a_data = METEOR_INPUT_DEV_SVIDEO;
2694 source = cxm_unknown_source;
2696 switch (*(unsigned long *)ap->a_data & 0xf000) {
2697 case METEOR_INPUT_DEV1:
2698 source = cxm_tuner_source;
2701 case METEOR_INPUT_DEV2:
2702 source = cxm_line_in_source_composite;
2705 case METEOR_INPUT_DEV_SVIDEO:
2706 source = cxm_line_in_source_svideo;
2716 * Switching between audio + video and audio only
2717 * subtypes isn't supported while encoding.
2720 if (source != sc->source
2721 && (source == cxm_fm_source
2722 || sc->source == cxm_fm_source))
2726 if (cxm_pause_encoder(sc) < 0)
2729 if (cxm_saa7115_select_source(sc, source) < 0)
2731 if (cxm_msp_select_source(sc, source) < 0)
2733 sc->source = source;
2735 result = cxm_encoder_wait_for_lock(sc);
2738 else if (result == 0)
2741 if (cxm_unpause_encoder(sc) < 0)
2746 *(unsigned int *)ap->a_data = sc->enc_signal;
2750 sig = *(unsigned int *)ap->a_data;
2752 if (!_SIG_VALID(sig))
2756 * Historically, applications used METEOR_SIG_MODE_MASK
2757 * to reset signal delivery.
2759 if (sig == METEOR_SIG_MODE_MASK)
2763 sc->enc_proc = sig ? curproc : NULL;
2764 sc->enc_signal = sig;
2769 /* Convert from kHz to MHz * 100 */
2770 freq = sc->tuner_freq / 10;
2772 *(unsigned int *)ap->a_data = freq;
2776 if (sc->source == cxm_fm_source)
2777 if (cxm_pause_encoder(sc) < 0)
2780 /* Convert from MHz * 100 to kHz */
2781 freq = *(unsigned int *)ap->a_data * 10;
2783 if (cxm_tuner_select_frequency(sc, cxm_tuner_fm_freq_type,
2788 * Explicitly wait for the tuner lock so we
2789 * can indicate if there's a station present.
2791 if (cxm_tuner_wait_for_lock(sc) < 0)
2794 result = cxm_encoder_wait_for_lock(sc);
2797 else if (result == 0)
2800 if (sc->source == cxm_fm_source)
2801 if (cxm_unpause_encoder(sc) < 0)
2805 case TVTUNER_GETAFC:
2806 *(int *)ap->a_data = sc->tuner_afc;
2809 case TVTUNER_SETAFC:
2810 sc->tuner_afc = (*(int *)ap->a_data != 0);
2813 case TVTUNER_GETTYPE:
2814 *(unsigned int *)ap->a_data = cxm_tuner_selected_channel_set(sc);
2817 case TVTUNER_SETTYPE:
2818 if (cxm_tuner_select_channel_set(sc, *(unsigned int *)ap->a_data) < 0)
2822 case TVTUNER_SETCHNL:
2823 if (sc->source == cxm_tuner_source)
2824 if (cxm_pause_encoder(sc) < 0)
2827 if (cxm_tuner_select_channel(sc, *(unsigned int *)ap->a_data) < 0)
2831 if (cxm_tuner_apply_afc(sc) < 0)
2835 * Explicitly wait for the tuner lock so we
2836 * can indicate if there's a station present.
2838 if (cxm_tuner_wait_for_lock(sc) < 0)
2841 result = cxm_encoder_wait_for_lock(sc);
2844 else if (result == 0)
2847 if (sc->source == cxm_tuner_source)
2848 if (cxm_unpause_encoder(sc) < 0)
2852 case TVTUNER_GETFREQ:
2853 /* Convert from kHz to MHz * 16 */
2854 freq = (sc->tuner_freq * 16) / 1000;
2856 *(unsigned int *)ap->a_data = freq;
2859 case TVTUNER_SETFREQ:
2860 if (sc->source == cxm_tuner_source)
2861 if (cxm_pause_encoder(sc) < 0)
2864 /* Convert from MHz * 16 to kHz */
2865 freq = (*(unsigned int *)ap->a_data * 1000) / 16;
2867 if (cxm_tuner_select_frequency(sc, cxm_tuner_tv_freq_type,
2872 * Explicitly wait for the tuner lock so we
2873 * can indicate if there's a station present.
2875 if (cxm_tuner_wait_for_lock(sc) < 0)
2878 result = cxm_encoder_wait_for_lock(sc);
2881 else if (result == 0)
2884 if (sc->source == cxm_tuner_source)
2885 if (cxm_unpause_encoder(sc) < 0)
2890 case TVTUNER_GETSTATUS:
2891 status = cxm_tuner_status(sc);
2894 *(unsigned long *)ap->a_data = status & 0xff;
2898 remote = (struct bktr_remote *)ap->a_data;
2899 if (cxm_ir_key(sc, (char *)remote, sizeof(*remote)) < 0)
2910 static struct filterops cxm_filterops =
2911 { 1, NULL, cxm_filter_detach, cxm_filter };
2914 cxm_kqfilter(struct dev_kqfilter_args *ap)
2916 cdev_t dev = ap->a_head.a_dev;
2917 struct knote *kn = ap->a_kn;
2918 struct cxm_softc *sc;
2919 struct klist *klist;
2924 switch (kn->kn_filter) {
2926 unit = UNIT(minor(dev));
2927 /* Get the device data */
2928 sc = (struct cxm_softc *)devclass_get_softc(cxm_devclass, unit);
2929 kn->kn_fop = &cxm_filterops;
2930 kn->kn_hook = (caddr_t)sc;
2933 ap->a_result = EOPNOTSUPP;
2938 klist = &sc->enc_sel.si_note;
2939 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
2946 cxm_filter_detach(struct knote *kn)
2948 struct cxm_softc *sc = (struct cxm_softc *)kn->kn_hook;
2949 struct klist *klist;
2952 klist = &sc->enc_sel.si_note;
2953 SLIST_REMOVE(klist, kn, knote, kn_selnext);
2958 cxm_filter(struct knote *kn, long hint)
2960 struct cxm_softc *sc = (struct cxm_softc *)kn->kn_hook;
2964 /* the device is no longer valid/functioning */
2965 kn->kn_flags |= EV_EOF;
2970 if (sc->enc_pool.read != sc->enc_pool.write)