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/resource.h>
57 #include <machine/clock.h>
59 #include <dev/video/meteor/ioctl_meteor.h>
60 #include <dev/video/bktr/ioctl_bt848.h>
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
65 #include <dev/video/cxm/cxm.h>
67 #include <bus/iicbus/iiconf.h>
70 * Various supported device vendors/types and their names.
72 static struct cxm_dev cxm_devs
[] = {
73 { PCI_VENDOR_ICOMPRESSION
, PCI_PRODUCT_ICOMPRESSION_ITVC15
,
74 "Conexant iTVC15 MPEG Coder" },
75 { PCI_VENDOR_ICOMPRESSION
, PCI_PRODUCT_ICOMPRESSION_ITVC16
,
76 "Conexant iTVC16 MPEG Coder" },
81 static int cxm_probe(device_t dev
);
82 static int cxm_attach(device_t dev
);
83 static int cxm_detach(device_t dev
);
84 static int cxm_shutdown(device_t dev
);
85 static void cxm_intr(void *arg
);
87 static void cxm_child_detached(device_t dev
, device_t child
);
88 static int cxm_read_ivar(device_t bus
, device_t dev
,
89 int index
, uintptr_t* val
);
90 static int cxm_write_ivar(device_t bus
, device_t dev
,
91 int index
, uintptr_t val
);
94 static device_method_t cxm_methods
[] = {
95 /* Device interface */
96 DEVMETHOD(device_probe
, cxm_probe
),
97 DEVMETHOD(device_attach
, cxm_attach
),
98 DEVMETHOD(device_detach
, cxm_detach
),
99 DEVMETHOD(device_shutdown
, cxm_shutdown
),
102 DEVMETHOD(bus_child_detached
, cxm_child_detached
),
103 DEVMETHOD(bus_print_child
, bus_generic_print_child
),
104 DEVMETHOD(bus_driver_added
, bus_generic_driver_added
),
105 DEVMETHOD(bus_read_ivar
, cxm_read_ivar
),
106 DEVMETHOD(bus_write_ivar
, cxm_write_ivar
),
111 static driver_t cxm_driver
= {
114 sizeof(struct cxm_softc
),
117 static devclass_t cxm_devclass
;
119 static d_open_t cxm_open
;
120 static d_close_t cxm_close
;
121 static d_read_t cxm_read
;
122 static d_ioctl_t cxm_ioctl
;
123 static d_kqfilter_t cxm_kqfilter
;
125 static void cxm_filter_detach(struct knote
*);
126 static int cxm_filter(struct knote
*, long);
128 static struct dev_ops cxm_ops
= {
131 .d_close
= cxm_close
,
133 .d_ioctl
= cxm_ioctl
,
134 .d_kqfilter
= cxm_kqfilter
137 MODULE_DEPEND(cxm
, cxm_iic
, 1, 1, 1);
138 DRIVER_MODULE(cxm
, pci
, cxm_driver
, cxm_devclass
, NULL
, NULL
);
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 */
150 static struct cxm_codec_profile vcd_ntsc_profile
= {
151 "MPEG-1 VideoCD NTSC video and MPEG audio",
152 CXM_FW_STREAM_TYPE_VCD
,
161 * Spatial filter = Manual, Temporal filter = Manual
162 * Median filter = Horizontal / Vertical
163 * Spatial filter value = 1, Temporal filter value = 4
169 static struct cxm_codec_profile vcd_pal_profile
= {
170 "MPEG-1 VideoCD PAL video and MPEG audio",
171 CXM_FW_STREAM_TYPE_VCD
,
180 * Spatial filter = Manual, Temporal filter = Manual
181 * Median filter = Horizontal / Vertical
182 * Spatial filter value = 1, Temporal filter value = 4
188 static struct cxm_codec_profile svcd_ntsc_profile
= {
189 "MPEG-2 SuperVCD NTSC video and MPEG audio",
190 CXM_FW_STREAM_TYPE_SVCD
,
196 /* 2.5 Mb/s peak limit to keep bbdmux followed by mplex -f 4 happy */
197 { 0, 1150000, 2500000 },
200 * Spatial filter = Manual, Temporal filter = Manual
201 * Median filter = Horizontal / Vertical
202 * Spatial filter value = 1, Temporal filter value = 4
208 static struct cxm_codec_profile svcd_pal_profile
= {
209 "MPEG-2 SuperVCD PAL video and MPEG audio",
210 CXM_FW_STREAM_TYPE_SVCD
,
216 /* 2.5 Mb/s peak limit to keep bbdmux followed by mplex -f 4 happy */
217 { 0, 1150000, 2500000 },
220 * Spatial filter = Manual, Temporal filter = Manual
221 * Median filter = Horizontal / Vertical
222 * Spatial filter value = 1, Temporal filter value = 4
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
,
236 { 0, 4000000, 4520000 }, /* 4 hours on 8.54 GB media */
239 * Spatial filter = Manual, Temporal filter = Manual
240 * Median filter = Horizontal / Vertical
241 * Spatial filter value = 1, Temporal filter value = 4
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
,
255 { 0, 4000000, 4520000 }, /* 4 hours on 8.54 GB media */
258 * Spatial filter = Manual, Temporal filter = Manual
259 * Median filter = Horizontal / Vertical
260 * Spatial filter value = 1, Temporal filter value = 4
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
,
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 */
278 * Spatial filter = Manual, Temporal filter = Manual
279 * Median filter = Horizontal / Vertical
280 * Spatial filter value = 1, Temporal filter value = 4
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
,
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 */
298 * Spatial filter = Manual, Temporal filter = Manual
299 * Median filter = Horizontal / Vertical
300 * Spatial filter value = 1, Temporal filter value = 4
307 static const struct cxm_codec_profile
308 *codec_profiles
[] = {
313 &dvd_half_d1_ntsc_profile
,
314 &dvd_half_d1_pal_profile
,
315 &dvd_full_d1_ntsc_profile
,
316 &dvd_full_d1_pal_profile
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
)
326 unsigned int mailbox
;
327 uint32_t completed_command
;
330 if (nparameters
> CXM_MBX_MAX_PARAMETERS
) {
331 device_printf(sc
->dev
, "too many parameters for mailbox\n");
338 case cxm_dec_mailbox
:
339 mailbox
= sc
->dec_mbx
340 + CXM_MBX_FW_CMD_MAILBOX
*sizeof(struct cxm_mailbox
);
343 case cxm_enc_mailbox
:
344 mailbox
= sc
->enc_mbx
345 + CXM_MBX_FW_CMD_MAILBOX
*sizeof(struct cxm_mailbox
);
353 for (i
= 0; i
< CXM_MBX_FW_CMD_MAILBOXES
; i
++) {
354 flags
= CSR_READ_4(sc
,
356 + offsetof(struct cxm_mailbox
, flags
));
357 if (!(flags
& CXM_MBX_FLAG_IN_USE
))
361 * Mail boxes containing certain completed commands
362 * for which the results are never needed can be reused.
365 if ((flags
& (CXM_MBX_FLAG_DRV_DONE
| CXM_MBX_FLAG_FW_DONE
))
366 == (CXM_MBX_FLAG_DRV_DONE
| CXM_MBX_FLAG_FW_DONE
)) {
370 + offsetof(struct cxm_mailbox
, command
));
373 * DMA results are always check by reading the
374 * DMA status register ... never by checking
375 * the mailbox after the command has completed.
378 if (completed_command
== CXM_FW_CMD_SCHED_DMA_TO_HOST
)
382 mailbox
+= sizeof(struct cxm_mailbox
);
385 if (i
>= CXM_MBX_FW_CMD_MAILBOXES
) {
390 CSR_WRITE_4(sc
, mailbox
+ offsetof(struct cxm_mailbox
, flags
),
391 CXM_MBX_FLAG_IN_USE
);
394 * PCI writes may be buffered so force the
395 * write to complete by reading the last
399 CSR_READ_4(sc
, mailbox
+ offsetof(struct cxm_mailbox
, flags
));
403 CSR_WRITE_4(sc
, mailbox
+ offsetof(struct cxm_mailbox
, command
), cmd
);
404 CSR_WRITE_4(sc
, mailbox
+ offsetof(struct cxm_mailbox
, timeout
),
407 for (i
= 0; i
< nparameters
; i
++)
410 + offsetof(struct cxm_mailbox
, parameters
)
411 + i
* sizeof(uint32_t),
414 for (; i
< CXM_MBX_MAX_PARAMETERS
; i
++)
417 + offsetof(struct cxm_mailbox
, parameters
)
418 + i
* sizeof(uint32_t), 0);
420 CSR_WRITE_4(sc
, mailbox
+ offsetof(struct cxm_mailbox
, flags
),
421 CXM_MBX_FLAG_IN_USE
| CXM_MBX_FLAG_DRV_DONE
);
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
)
435 unsigned int mailbox
;
443 case cxm_dec_mailbox
:
448 case cxm_enc_mailbox
:
457 mailbox
= cxm_queue_firmware_command(sc
, mbx_name
, cmd
,
458 parameters
, nparameters
);
460 device_printf(sc
->dev
, "no free mailboxes\n");
464 /* Give the firmware a chance to start processing the request */
465 tsleep(bmp
, 0, wmesg
, hz
/ 100);
467 for (i
= 0; i
< 100; i
++) {
468 flags
= CSR_READ_4(sc
,
470 + offsetof(struct cxm_mailbox
, flags
));
471 if ((flags
& CXM_MBX_FLAG_FW_DONE
))
475 tsleep(bmp
, 0, wmesg
, hz
/ 100);
479 device_printf(sc
->dev
, "timeout\n");
483 result
= CSR_READ_4(sc
,
485 + offsetof(struct cxm_mailbox
, result
));
487 for (i
= 0; i
< nparameters
; i
++)
491 + offsetof(struct cxm_mailbox
, parameters
)
492 + i
* sizeof(uint32_t));
494 CSR_WRITE_4(sc
, mailbox
+ offsetof(struct cxm_mailbox
, flags
), 0);
496 return result
== 0 ? 0 : -1;
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
)
506 unsigned int mailbox
;
510 for (i
= 0; i
< 100; i
++) {
511 mailbox
= cxm_queue_firmware_command(sc
, mbx_name
, cmd
,
512 parameters
, nparameters
);
521 device_printf(sc
->dev
, "no free mailboxes\n");
525 /* Give the firmware a chance to start processing the request */
528 for (i
= 0; i
< 100; i
++) {
529 flags
= CSR_READ_4(sc
,
531 + offsetof(struct cxm_mailbox
, flags
));
532 if ((flags
& CXM_MBX_FLAG_FW_DONE
))
540 device_printf(sc
->dev
, "timeout\n");
544 result
= CSR_READ_4(sc
,
546 + offsetof(struct cxm_mailbox
, result
));
548 for (i
= 0; i
< nparameters
; i
++)
552 + offsetof(struct cxm_mailbox
, parameters
)
553 + i
* sizeof(uint32_t));
555 CSR_WRITE_4(sc
, mailbox
+ offsetof(struct cxm_mailbox
, flags
), 0);
557 return result
== 0 ? 0 : -1;
562 cxm_stop_firmware(struct cxm_softc
*sc
)
565 if (cxm_firmware_command_nosleep(sc
, cxm_enc_mailbox
,
566 CXM_FW_CMD_ENC_HALT_FW
, NULL
, 0) < 0)
569 if (sc
->type
== cxm_iTVC15_type
570 && cxm_firmware_command_nosleep(sc
, cxm_dec_mailbox
,
571 CXM_FW_CMD_DEC_HALT_FW
,
583 cxm_set_irq_mask(struct cxm_softc
*sc
, uint32_t mask
)
587 CSR_WRITE_4(sc
, CXM_REG_IRQ_MASK
, mask
);
590 * PCI writes may be buffered so force the
591 * write to complete by reading the last
595 CSR_READ_4(sc
, CXM_REG_IRQ_MASK
);
604 cxm_set_irq_status(struct cxm_softc
*sc
, uint32_t status
)
607 CSR_WRITE_4(sc
, CXM_REG_IRQ_STATUS
, status
);
610 * PCI writes may be buffered so force the
611 * write to complete by reading the last
615 CSR_READ_4(sc
, CXM_REG_IRQ_STATUS
);
620 cxm_stop_hardware(struct cxm_softc
*sc
)
623 if (cxm_saa7115_mute(sc
) < 0)
625 if (cxm_msp_mute(sc
) < 0)
629 /* Halt the firmware */
630 if (sc
->enc_mbx
!= -1) {
631 if (cxm_stop_firmware(sc
) < 0)
635 /* Mask all interrupts */
636 cxm_set_irq_mask(sc
, 0xffffffff);
639 CSR_WRITE_4(sc
, CXM_REG_VDM
, CXM_CMD_VDM_STOP
);
642 CSR_WRITE_4(sc
, CXM_REG_AO
, CXM_CMD_AO_STOP
);
645 CSR_WRITE_4(sc
, CXM_REG_APU
, CXM_CMD_APU_PING
);
648 CSR_WRITE_4(sc
, CXM_REG_VPU
, sc
->type
== cxm_iTVC15_type
650 : CXM_CMD_VPU_STOP16
);
652 /* Reset Hw Blocks */
653 CSR_WRITE_4(sc
, CXM_REG_HW_BLOCKS
, CXM_CMD_HW_BLOCKS_RST
);
656 CSR_WRITE_4(sc
, CXM_REG_SPU
, CXM_CMD_SPU_STOP
);
666 cxm_download_firmware(struct cxm_softc
*sc
)
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");
675 } else if (strncmp((const char *)cxm_dec_fw
, "NOFW", 4) == 0) {
676 device_printf(sc
->dev
, "decoder firmware not compiled in\n");
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
++);
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
++);
697 cxm_init_hardware(struct cxm_softc
*sc
)
700 unsigned int mailbox
;
703 if (cxm_stop_hardware(sc
) < 0)
706 /* Initialize encoder SDRAM pre-charge */
707 CSR_WRITE_4(sc
, CXM_REG_ENC_SDRAM_PRECHARGE
,
708 CXM_CMD_SDRAM_PRECHARGE_INIT
);
710 /* Initialize encoder SDRAM refresh to 1us */
711 CSR_WRITE_4(sc
, CXM_REG_ENC_SDRAM_REFRESH
,
712 CXM_CMD_SDRAM_REFRESH_INIT
);
714 /* Initialize decoder SDRAM pre-charge */
715 CSR_WRITE_4(sc
, CXM_REG_DEC_SDRAM_PRECHARGE
,
716 CXM_CMD_SDRAM_PRECHARGE_INIT
);
718 /* Initialize decoder SDRAM refresh to 1us */
719 CSR_WRITE_4(sc
, CXM_REG_DEC_SDRAM_REFRESH
,
720 CXM_CMD_SDRAM_REFRESH_INIT
);
725 if (cxm_download_firmware(sc
) < 0)
729 CSR_WRITE_4(sc
, CXM_REG_SPU
,
730 CSR_READ_4(sc
, CXM_REG_SPU
) & CXM_MASK_SPU_ENABLE
);
732 /* Wait for 1 second */
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
));
742 /* Wait for 1 second */
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)
754 if (i
>= CXM_MEM_ENC_SIZE
)
757 sc
->enc_mbx
= mailbox
+ i
+ 16;
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)
769 if (i
>= CXM_MEM_DEC_SIZE
)
772 sc
->dec_mbx
= mailbox
+ i
+ 16;
775 /* Get encoder firmware version */
777 if (cxm_firmware_command_nosleep(sc
, cxm_enc_mailbox
,
778 CXM_FW_CMD_ENC_GET_FW_VER
,
782 device_printf(sc
->dev
, "encoder firmware version %#x\n",
783 (unsigned int)parameter
);
785 /* Get decoder firmware version */
786 if (sc
->type
== cxm_iTVC15_type
) {
788 if (cxm_firmware_command_nosleep(sc
, cxm_dec_mailbox
,
789 CXM_FW_CMD_DEC_GET_FW_VER
,
793 device_printf(sc
->dev
, "decoder firmware version %#x\n",
794 (unsigned int)parameter
);
802 cxm_configure_encoder(struct cxm_softc
*sc
)
806 uint32_t parameters
[12];
807 const struct cxm_codec_profile
*cpp
;
809 if (sc
->source
== cxm_fm_source
)
810 switch (cxm_tuner_selected_channel_set(sc
)) {
812 case CHNLSET_CABLEIRC
:
813 case CHNLSET_JPNBCST
:
814 case CHNLSET_JPNCABLE
:
823 fps
= cxm_saa7115_detected_fps(sc
);
828 if (sc
->profile
->fps
!= fps
) {
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.
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
)
843 if (i
>= NUM_ELEMENTS(codec_profiles
))
846 sc
->profile
= codec_profiles
[i
];
851 if (cxm_saa7115_configure(sc
,
852 cpp
->width
, cpp
->source_height
, fps
,
853 cpp
->audio_sample_rate
) < 0)
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
957 * assign audio properties
960 for (i
= 0; i
< NUM_ELEMENTS(codec_audio_formats
); i
++)
961 if (codec_audio_formats
[i
].sample_rate
962 == cpp
->audio_sample_rate
)
965 if (i
>= NUM_ELEMENTS(codec_audio_formats
))
968 parameters
[0] = codec_audio_formats
[i
].format
;
969 if (cxm_firmware_command(sc
, cxm_enc_mailbox
,
970 CXM_FW_CMD_ASSIGN_AUDIO_PROPERTIES
,
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
,
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
,
992 /* assign frame drop rate */
994 if (cxm_firmware_command(sc
, cxm_enc_mailbox
,
995 CXM_FW_CMD_ASSIGN_FRAME_DROP_RATE
,
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)
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)
1030 /* assign VBI lines */
1031 parameters
[0] = 0xffffffff; /* all lines */
1032 parameters
[1] = 0; /* disable VBI features */
1036 if (cxm_firmware_command(sc
, cxm_enc_mailbox
,
1037 CXM_FW_CMD_ASSIGN_VBI_LINE
,
1038 parameters
, 5) != 0)
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)
1054 cxm_start_encoder(struct cxm_softc
*sc
)
1056 uint32_t parameters
[4];
1064 if (cxm_configure_encoder(sc
) < 0)
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)
1074 /* Clear pending encoder interrupts (which are currently masked) */
1075 cxm_set_irq_status(sc
, CXM_IRQ_ENC
);
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)
1087 if (cxm_saa7115_mute(sc
) < 0)
1089 if (cxm_msp_mute(sc
) < 0)
1092 if (cxm_firmware_command(sc
, cxm_enc_mailbox
,
1093 CXM_FW_CMD_INITIALIZE_VIDEO_INPUT
,
1097 if (cxm_saa7115_unmute(sc
) < 0)
1099 if (cxm_msp_unmute(sc
) < 0)
1102 /* Wait for 100ms */
1103 tsleep(&sc
->encoding
, 0, "cxmce", hz
/ 10);
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);
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)
1119 sc
->enc_pool
.offset
= 0;
1120 sc
->enc_pool
.read
= 0;
1121 sc
->enc_pool
.write
= 0;
1123 sc
->encoding_eos
= 0;
1127 /* Enable interrupts */
1128 cxm_set_irq_mask(sc
, sc
->irq_mask
& ~CXM_IRQ_ENC
);
1135 cxm_stop_encoder(struct cxm_softc
*sc
)
1137 uint32_t parameters
[4];
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);
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)
1159 /* Wait for up to 1 second */
1161 if (!sc
->encoding_eos
)
1162 tsleep(&sc
->encoding_eos
, 0, "cxmeos", hz
);
1165 if (sc
->mpeg
&& !sc
->encoding_eos
)
1166 device_printf(sc
->dev
, "missing encoder EOS\n");
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)
1178 /* Disable interrupts */
1179 cxm_set_irq_mask(sc
, sc
->irq_mask
| CXM_IRQ_ENC
);
1188 cxm_pause_encoder(struct cxm_softc
*sc
)
1192 /* Pause the encoder */
1194 if (cxm_firmware_command(sc
, cxm_enc_mailbox
,
1195 CXM_FW_CMD_PAUSE_ENCODER
, ¶meter
, 1) != 0)
1203 cxm_unpause_encoder(struct cxm_softc
*sc
)
1207 /* Unpause the encoder */
1209 if (cxm_firmware_command(sc
, cxm_enc_mailbox
,
1210 CXM_FW_CMD_PAUSE_ENCODER
, ¶meter
, 1) != 0)
1218 cxm_encoder_fixup_byte_order(struct cxm_softc
*sc
,
1219 unsigned int current
, size_t offset
)
1221 unsigned int strips
;
1225 unsigned int macroblocks_per_line
;
1226 unsigned int scratch
;
1227 unsigned int words_per_line
;
1232 switch (sc
->enc_pool
.bufs
[current
].byte_order
) {
1233 case cxm_device_mpeg_byte_order
:
1236 * Convert each 32 bit word to the proper byte ordering.
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
);
1246 case cxm_device_yuv12_byte_order
:
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).
1255 scratch
= (current
+ (CXM_SG_BUFFERS
- 1)) % CXM_SG_BUFFERS
;
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
);
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
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
1278 *(ptr
+ k
* words_per_line
)
1280 *(ptr
+ k
* words_per_line
+ 1)
1282 *(ptr
+ k
* words_per_line
+ 2)
1284 *(ptr
+ k
* words_per_line
+ 3)
1287 ptr
+= CXM_MACROBLOCK_WIDTH
/ sizeof(*ptr
);
1291 sc
->enc_pool
.bufs
[scratch
].size
1292 = sc
->enc_pool
.bufs
[current
].size
;
1301 sc
->enc_pool
.bufs
[current
].byte_order
= cxm_host_byte_order
;
1308 cxm_encoder_dma_discard(struct cxm_softc
*sc
)
1310 uint32_t parameters
[3];
1312 /* Discard the DMA request */
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");
1324 sc
->encoding_dma
= -1;
1329 cxm_encoder_dma_done(struct cxm_softc
*sc
)
1331 int buffers_pending
;
1334 if (!sc
->encoding_dma
) {
1335 device_printf(sc
->dev
,
1336 "encoder dma not already in progress\n");
1340 buffers_pending
= sc
->encoding_dma
;
1341 sc
->encoding_dma
= 0;
1343 if (buffers_pending
< 0)
1346 status
= CSR_READ_4(sc
, CXM_REG_DMA_STATUS
) & 0x0000000f;
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
);
1356 /* Update the books */
1358 sc
->enc_pool
.write
= (sc
->enc_pool
.write
+ buffers_pending
)
1362 /* signal anyone requesting notification */
1364 ksignal (sc
->enc_proc
, sc
->enc_signal
);
1366 /* wakeup anyone waiting for data */
1367 wakeup(&sc
->enc_pool
.read
);
1369 /* wakeup anyone polling for data */
1370 KNOTE(&sc
->enc_kq
.ki_note
, 0);
1375 cxm_encoder_dma_request(struct cxm_softc
*sc
)
1377 enum cxm_byte_order byte_order
;
1379 int buffers_pending
;
1380 unsigned int current
;
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
];
1388 size_t max_sg_segment
;
1394 if (sc
->encoding_dma
) {
1395 device_printf(sc
->dev
, "encoder dma already in progress\n");
1396 cxm_encoder_dma_discard(sc
);
1400 mailbox
= sc
->enc_mbx
1401 + CXM_MBX_FW_DMA_MAILBOX
* sizeof(struct cxm_mailbox
);
1403 for (i
= 0; i
< CXM_MBX_MAX_PARAMETERS
; i
++)
1407 + offsetof(struct cxm_mailbox
, parameters
)
1408 + i
* sizeof(uint32_t)
1411 byte_order
= cxm_device_mpeg_byte_order
;
1412 max_sg_segment
= CXM_SG_SEGMENT
;
1414 type
= parameters
[0];
1418 requests
[nrequests
].offset
= parameters
[1];
1419 requests
[nrequests
++].size
= parameters
[2];
1423 byte_order
= cxm_device_yuv12_byte_order
;
1426 * Simplify macroblock unpacking by ensuring
1427 * that strips don't span buffers.
1430 #if CXM_MACROBLOCK_SIZE % 256
1431 # error CXM_MACROBLOCK_SIZE not a multiple of 256
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
;
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];
1447 case 2: /* PCM (audio) */
1450 device_printf(sc
->dev
, "encoder dma type %#x unsupported\n",
1451 (unsigned int)type
);
1452 cxm_encoder_dma_discard(sc
);
1457 * Determine the number of buffers free at this * instant *
1458 * taking into consideration that the ring buffer wraps.
1461 buffers_free
= sc
->enc_pool
.read
- sc
->enc_pool
.write
;
1462 if (buffers_free
<= 0)
1463 buffers_free
+= CXM_SG_BUFFERS
;
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.
1474 buffers_pending
= 0;
1475 current
= sc
->enc_pool
.write
;
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
);
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
;
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)
1498 requests
[i
].offset
+= sc
->enc_pool
.bufs
[current
].size
;
1499 requests
[i
].size
-= sc
->enc_pool
.bufs
[current
].size
;
1501 current
= (current
+ 1) % CXM_SG_BUFFERS
;
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
);
1512 /* Mark the last transfer in the list */
1513 sc
->enc_sg
.vaddr
[buffers_pending
- 1].size
|= 0x80000000;
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");
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.
1535 sc
->encoding_dma
= buffers_pending
;
1540 cxm_encoder_wait_for_lock(struct cxm_softc
*sc
)
1549 * Wait for the tuner to lock.
1551 if (sc
->source
== cxm_fm_source
|| sc
->source
== cxm_tuner_source
) {
1552 result
= cxm_tuner_wait_for_lock(sc
);
1558 * Wait for the video decoder to lock.
1560 if (sc
->source
!= cxm_fm_source
) {
1561 result
= cxm_saa7115_wait_for_lock(sc
);
1564 else if (result
== 0)
1569 * Wait for the audio decoder to lock.
1571 if (sc
->source
== cxm_tuner_source
) {
1572 muted
= cxm_msp_is_muted(sc
);
1574 result
= cxm_msp_autodetect_standard(sc
);
1577 else if (result
== 0)
1580 if (muted
== 0 && cxm_msp_unmute(sc
) < 0)
1589 cxm_mapmem(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int error
)
1591 bus_addr_t
*busaddrp
;
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.
1599 busaddrp
= (bus_addr_t
*)arg
;
1600 *busaddrp
= segs
->ds_addr
;
1605 * the boot time probe routine.
1608 cxm_probe(device_t dev
)
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
);
1628 * the attach routine.
1631 cxm_attach(device_t dev
)
1638 struct cxm_softc
*sc
;
1640 /* Get the device data */
1641 sc
= device_get_softc(dev
);
1642 unit
= device_get_unit(dev
);
1645 sc
->type
= cxm_iTVC15_type
;
1647 switch(pci_get_device(dev
)) {
1648 case PCI_PRODUCT_ICOMPRESSION_ITVC16
:
1649 sc
->type
= cxm_iTVC16_type
;
1657 * Enable bus mastering and memory mapped I/O.
1659 pci_enable_busmaster(dev
);
1660 pci_enable_io(dev
, SYS_RES_MEMORY
);
1661 command
= pci_read_config(dev
, PCIR_COMMAND
, 4);
1663 if (!(command
& PCIM_CMD_MEMEN
)) {
1664 device_printf(dev
, "failed to enable memory mappings\n");
1670 * Map control/status registers.
1673 sc
->mem_res
= bus_alloc_resource(dev
, SYS_RES_MEMORY
, &rid
,
1674 0, ~0, 1, RF_ACTIVE
);
1677 device_printf(dev
, "could not map memory\n");
1682 sc
->btag
= rman_get_bustag(sc
->mem_res
);
1683 sc
->bhandle
= rman_get_bushandle(sc
->mem_res
);
1686 * Attach the I2C bus.
1688 sc
->cxm_iic
= device_add_child(dev
, "cxm_iic", unit
);
1691 device_printf(dev
, "could not add cxm_iic\n");
1696 error
= device_probe_and_attach(sc
->cxm_iic
);
1699 device_printf(dev
, "could not attach cxm_iic\n");
1704 * Initialize the tuner.
1706 if (cxm_tuner_init(sc
) < 0) {
1707 device_printf(dev
, "could not initialize tuner\n");
1713 * Initialize the SAA7115.
1715 if (cxm_saa7115_init(sc
) < 0) {
1716 device_printf(dev
, "could not initialize video decoder\n");
1722 * Initialize the MSP3400.
1724 if (cxm_msp_init(sc
) < 0) {
1725 device_printf(dev
, "could not initialize audio decoder\n");
1731 * Initialize the IR Remote.
1733 if (cxm_ir_init(sc
) < 0) {
1734 device_printf(dev
, "could not initialize IR remote\n");
1743 * Disable the Conexant device.
1745 * This is done * after * attaching the I2C bus so
1746 * cxm_stop_hardware can mute the video and audio
1749 cxm_stop_hardware(sc
);
1752 * Allocate our interrupt.
1755 sc
->irq_res
= bus_alloc_resource(dev
, SYS_RES_IRQ
, &rid
,
1756 0, ~0, 1, RF_SHAREABLE
| RF_ACTIVE
);
1758 if (sc
->irq_res
== NULL
) {
1759 device_printf(dev
, "could not map interrupt\n");
1764 error
= bus_setup_intr(dev
, sc
->irq_res
, 0,
1765 cxm_intr
, sc
, &sc
->ih_cookie
, NULL
);
1767 device_printf(dev
, "could not setup irq\n");
1773 * Allocate a DMA tag for the parent bus.
1775 error
= bus_dma_tag_create(NULL
, 1, 0,
1776 BUS_SPACE_MAXADDR_32BIT
,
1778 BUS_SPACE_MAXSIZE_32BIT
, 1,
1779 BUS_SPACE_MAXSIZE_32BIT
, 0,
1782 device_printf(dev
, "could not create parent bus DMA tag\n");
1787 * Allocate a DMA tag for the encoder buffers.
1789 error
= bus_dma_tag_create(sc
->parent_dmat
, 256, 0,
1790 BUS_SPACE_MAXADDR_32BIT
,
1793 BUS_SPACE_MAXSIZE_32BIT
, 0,
1794 &sc
->enc_pool
.dmat
);
1797 "could not create encoder buffer DMA tag\n");
1801 for (i
= 0; i
< CXM_SG_BUFFERS
; i
++) {
1804 * Allocate the encoder buffer.
1806 error
= bus_dmamem_alloc(sc
->enc_pool
.dmat
,
1807 (void **)&sc
->enc_pool
.bufs
[i
].vaddr
,
1809 &sc
->enc_pool
.bufs
[i
].dmamap
);
1812 "could not allocate encoder buffer\n");
1817 * Map the encoder buffer.
1819 error
= bus_dmamap_load(sc
->enc_pool
.dmat
,
1820 sc
->enc_pool
.bufs
[i
].dmamap
,
1821 sc
->enc_pool
.bufs
[i
].vaddr
,
1824 &sc
->enc_pool
.bufs
[i
].baddr
, 0);
1826 device_printf(dev
, "could not map encoder buffer\n");
1832 * Allocate a DMA tag for the scatter / gather list.
1834 error
= bus_dma_tag_create(sc
->parent_dmat
, 1, 0,
1835 BUS_SPACE_MAXADDR_32BIT
,
1838 * sizeof(struct cxm_sg_entry
), 1,
1839 BUS_SPACE_MAXSIZE_32BIT
, 0,
1843 "could not create scatter / gather DMA tag\n");
1848 * Allocate the scatter / gather list.
1850 error
= bus_dmamem_alloc(sc
->enc_sg
.dmat
, (void **)&sc
->enc_sg
.vaddr
,
1851 BUS_DMA_NOWAIT
, &sc
->enc_sg
.dmamap
);
1854 "could not allocate scatter / gather list\n");
1859 * Map the scatter / gather list.
1861 error
= bus_dmamap_load(sc
->enc_sg
.dmat
, sc
->enc_sg
.dmamap
,
1863 CXM_SG_BUFFERS
* sizeof(struct cxm_sg_entry
),
1864 cxm_mapmem
, &sc
->enc_sg
.baddr
, 0);
1866 device_printf(dev
, "could not map scatter / gather list\n");
1871 * Initialize the hardware.
1873 if (cxm_init_hardware(sc
) < 0) {
1874 device_printf(dev
, "could not initialize hardware\n");
1879 sc
->profile
= &dvd_full_d1_ntsc_profile
;
1881 sc
->source
= cxm_tuner_source
;
1884 /* make the device entries */
1885 sc
->cxm_dev_t
= make_dev(&cxm_ops
, unit
,
1886 0, 0, 0444, "cxm%d", unit
);
1891 if (sc
->enc_sg
.baddr
)
1892 bus_dmamap_unload(sc
->enc_sg
.dmat
, sc
->enc_sg
.dmamap
);
1893 if (sc
->enc_sg
.vaddr
)
1894 bus_dmamem_free(sc
->enc_sg
.dmat
, sc
->enc_sg
.vaddr
,
1896 if (sc
->enc_sg
.dmat
)
1897 bus_dma_tag_destroy(sc
->enc_sg
.dmat
);
1899 for (i
= 0; i
< CXM_SG_BUFFERS
; i
++) {
1900 if (sc
->enc_pool
.bufs
[i
].baddr
)
1901 bus_dmamap_unload(sc
->enc_pool
.dmat
,
1902 sc
->enc_pool
.bufs
[i
].dmamap
);
1903 if (sc
->enc_pool
.bufs
[i
].vaddr
)
1904 bus_dmamem_free(sc
->enc_pool
.dmat
,
1905 sc
->enc_pool
.bufs
[i
].vaddr
,
1906 sc
->enc_pool
.bufs
[i
].dmamap
);
1909 if (sc
->enc_pool
.dmat
)
1910 bus_dma_tag_destroy(sc
->enc_pool
.dmat
);
1912 if (sc
->parent_dmat
)
1913 bus_dma_tag_destroy(sc
->parent_dmat
);
1916 * Detach the I2C bus.
1918 * This is done * after * deallocating the scatter / gather
1919 * list and buffers so the kernel has a better chance of
1920 * gracefully handling a memory shortage.
1922 * Detach the children before recursively deleting
1923 * in case a child has a pointer to a grandchild
1924 * which is used by the child's detach routine.
1926 bus_generic_detach(dev
);
1928 device_delete_child(dev
, sc
->cxm_iic
);
1931 bus_teardown_intr(dev
, sc
->irq_res
, sc
->ih_cookie
);
1933 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->irq_res
);
1935 bus_release_resource(dev
, SYS_RES_MEMORY
, CXM_RID
, sc
->mem_res
);
1941 * the detach routine.
1944 cxm_detach(device_t dev
)
1947 struct cxm_softc
*sc
;
1950 /* Get the device data */
1951 sc
= device_get_softc(dev
);
1953 /* Disable the Conexant device. */
1954 cxm_stop_hardware(sc
);
1956 /* Unregister the /dev/cxmN device. */
1957 dev_ops_remove_minor(&cxm_ops
, /*0, */device_get_unit(dev
));
1960 * Deallocate scatter / gather list and buffers.
1962 bus_dmamap_unload(sc
->enc_sg
.dmat
, sc
->enc_sg
.dmamap
);
1963 bus_dmamem_free(sc
->enc_sg
.dmat
, sc
->enc_sg
.vaddr
, sc
->enc_sg
.dmamap
);
1965 bus_dma_tag_destroy(sc
->enc_sg
.dmat
);
1967 for (i
= 0; i
< CXM_SG_BUFFERS
; i
++) {
1968 bus_dmamap_unload(sc
->enc_pool
.dmat
,
1969 sc
->enc_pool
.bufs
[i
].dmamap
);
1970 bus_dmamem_free(sc
->enc_pool
.dmat
, sc
->enc_pool
.bufs
[i
].vaddr
,
1971 sc
->enc_pool
.bufs
[i
].dmamap
);
1974 bus_dma_tag_destroy(sc
->enc_pool
.dmat
);
1976 bus_dma_tag_destroy(sc
->parent_dmat
);
1979 * Detach the I2C bus.
1981 * This is done * after * deallocating the scatter / gather
1982 * list and buffers so the kernel has a better chance of
1983 * gracefully handling a memory shortage.
1985 * Detach the children before recursively deleting
1986 * in case a child has a pointer to a grandchild
1987 * which is used by the child's detach routine.
1989 * Remember the child before detaching so we can
1990 * delete it (bus_generic_detach indirectly zeroes
1993 child
= sc
->cxm_iic
;
1994 bus_generic_detach(dev
);
1996 device_delete_child(dev
, child
);
1998 /* Deallocate resources. */
1999 bus_teardown_intr(dev
, sc
->irq_res
, sc
->ih_cookie
);
2000 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->irq_res
);
2001 bus_release_resource(dev
, SYS_RES_MEMORY
, CXM_RID
, sc
->mem_res
);
2007 * the shutdown routine.
2010 cxm_shutdown(device_t dev
)
2012 struct cxm_softc
*sc
= device_get_softc(dev
);
2014 /* Disable the Conexant device. */
2015 cxm_stop_hardware(sc
);
2021 * the interrupt routine.
2027 struct cxm_softc
*sc
;
2029 /* Get the device data */
2030 sc
= (struct cxm_softc
*)arg
;
2032 status
= CSR_READ_4(sc
, CXM_REG_IRQ_STATUS
);
2034 status
&= ~sc
->irq_mask
;
2039 /* Process DMA done before handling a new DMA request or EOS */
2040 if (status
& CXM_IRQ_ENC_DMA_DONE
)
2041 cxm_encoder_dma_done(sc
);
2043 if (status
& CXM_IRQ_ENC_DMA_REQUEST
)
2044 cxm_encoder_dma_request(sc
);
2046 if (status
& CXM_IRQ_ENC_EOS
) {
2047 sc
->encoding_eos
= 1;
2048 wakeup(&sc
->encoding_eos
);
2051 cxm_set_irq_status(sc
, status
);
2056 * the child detached routine.
2059 cxm_child_detached(device_t dev
, device_t child
)
2061 struct cxm_softc
*sc
;
2063 /* Get the device data */
2064 sc
= device_get_softc(dev
);
2066 if (child
== sc
->cxm_iic
)
2072 cxm_read_ivar(device_t dev
, device_t child
, int index
, uintptr_t* val
)
2074 struct cxm_softc
*sc
;
2076 /* Get the device data */
2077 sc
= device_get_softc(dev
);
2080 case CXM_IVAR_BHANDLE
:
2081 *(bus_space_handle_t
**)val
= &sc
->bhandle
;
2085 *(bus_space_tag_t
**)val
= &sc
->btag
;
2088 case CXM_IVAR_IICBUS
:
2089 *(device_t
**)val
= &sc
->iicbus
;
2101 cxm_write_ivar(device_t dev
, device_t child
, int index
, uintptr_t val
)
2103 struct cxm_softc
*sc
;
2105 /* Get the device data */
2106 sc
= device_get_softc(dev
);
2109 case CXM_IVAR_BHANDLE
:
2115 case CXM_IVAR_IICBUS
:
2118 sc
->iicbus
= val
? *(device_t
*)val
: NULL
;
2129 /*---------------------------------------------------------
2131 ** Conexant iTVC15 / iTVC16 character device driver routines
2133 **---------------------------------------------------------
2136 #define UNIT(x) ((x) & 0x0f)
2137 #define FUNCTION(x) (x >> 4)
2143 cxm_open(struct dev_open_args
*ap
)
2145 cdev_t dev
= ap
->a_head
.a_dev
;
2147 struct cxm_softc
*sc
;
2149 unit
= UNIT(minor(dev
));
2151 /* Get the device data */
2152 sc
= (struct cxm_softc
*)devclass_get_softc(cxm_devclass
, unit
);
2154 /* the device is no longer valid/functioning */
2164 /* Record that the device is now busy */
2165 device_busy(devclass_get_device(cxm_devclass
, unit
));
2175 cxm_close(struct dev_close_args
*ap
)
2177 cdev_t dev
= ap
->a_head
.a_dev
;
2179 struct cxm_softc
*sc
;
2181 unit
= UNIT(minor(dev
));
2183 /* Get the device data */
2184 sc
= (struct cxm_softc
*)devclass_get_softc(cxm_devclass
, unit
);
2186 /* the device is no longer valid/functioning */
2190 if (cxm_stop_encoder(sc
) < 0)
2193 sc
->enc_pool
.offset
= 0;
2194 sc
->enc_pool
.read
= 0;
2195 sc
->enc_pool
.write
= 0;
2197 sc
->enc_proc
= NULL
;
2200 device_unbusy(devclass_get_device(cxm_devclass
, unit
));
2212 cxm_read(struct dev_read_args
*ap
)
2214 cdev_t dev
= ap
->a_head
.a_dev
;
2215 int buffers_available
;
2219 unsigned int current
;
2223 struct cxm_softc
*sc
;
2225 unit
= UNIT(minor(dev
));
2227 /* Get the device data */
2228 sc
= (struct cxm_softc
*)devclass_get_softc(cxm_devclass
, unit
);
2230 /* the device is no longer valid/functioning */
2234 /* Only trigger the encoder if the ring buffer is empty */
2235 if (!sc
->encoding
&& sc
->enc_pool
.read
== sc
->enc_pool
.write
) {
2236 if (cxm_start_encoder(sc
) < 0)
2238 if (ap
->a_ioflag
& IO_NDELAY
)
2242 buffers_available
= 0;
2245 while (sc
->enc_pool
.read
== sc
->enc_pool
.write
) {
2246 error
= tsleep(&sc
->enc_pool
.read
, PCATCH
, "cxmrd", 0);
2254 * Determine the number of buffers available at this * instant *
2255 * taking in consideration that the ring buffer wraps.
2257 buffers_available
= sc
->enc_pool
.write
- sc
->enc_pool
.read
;
2258 if (buffers_available
< 0)
2259 buffers_available
+= CXM_SG_BUFFERS
;
2262 offset
= sc
->enc_pool
.offset
;
2264 for (buffers_read
= 0, i
= sc
->enc_pool
.read
;
2265 buffers_read
!= buffers_available
&& ap
->a_uio
->uio_resid
;
2266 buffers_read
++, i
= (i
+ 1) % CXM_SG_BUFFERS
) {
2268 current
= cxm_encoder_fixup_byte_order (sc
, i
, offset
);
2270 nbytes
= sc
->enc_pool
.bufs
[current
].size
- offset
;
2272 /* Don't transfer more than requested */
2273 if (nbytes
> ap
->a_uio
->uio_resid
)
2274 nbytes
= ap
->a_uio
->uio_resid
;
2276 error
= uiomove(sc
->enc_pool
.bufs
[current
].vaddr
+ offset
,
2283 /* Handle a partial read of a buffer */
2284 if (!ap
->a_uio
->uio_resid
&& offset
!= sc
->enc_pool
.bufs
[i
].size
)
2290 sc
->enc_pool
.offset
= offset
;
2292 /* Update the books */
2294 sc
->enc_pool
.read
= (sc
->enc_pool
.read
+ buffers_read
)
2306 cxm_ioctl(struct dev_ioctl_args
*ap
)
2308 cdev_t dev
= ap
->a_head
.a_dev
;
2310 int chroma_saturation
;
2320 struct cxm_softc
*sc
;
2321 enum cxm_source source
;
2322 struct bktr_capture_area
*cap
;
2323 struct bktr_remote
*remote
;
2325 unit
= UNIT(minor(dev
));
2327 /* Get the device data */
2328 sc
= (struct cxm_softc
*)devclass_get_softc(cxm_devclass
, unit
);
2330 /* the device is no longer valid/functioning */
2334 switch (ap
->a_cmd
) {
2336 switch (cxm_msp_selected_source(sc
)) {
2337 case cxm_tuner_source
:
2338 *(int *) ap
->a_data
= AUDIO_TUNER
;
2341 case cxm_line_in_source_composite
:
2342 case cxm_line_in_source_svideo
:
2343 *(int *) ap
->a_data
= AUDIO_EXTERN
;
2347 *(int *) ap
->a_data
= AUDIO_INTERN
;
2354 if (cxm_msp_is_muted(sc
) == 1)
2355 *(int *) ap
->a_data
|= AUDIO_MUTE
;
2359 source
= cxm_unknown_source
;
2361 switch (*(int *) ap
->a_data
) {
2363 source
= cxm_tuner_source
;
2367 source
= cxm_line_in_source_composite
;
2371 source
= cxm_fm_source
;
2375 if (cxm_msp_mute(sc
) < 0)
2380 if (cxm_msp_unmute(sc
) < 0)
2391 * Switching between audio + video and audio only
2392 * subtypes isn't supported while encoding.
2395 if (source
!= sc
->source
2396 && (source
== cxm_fm_source
2397 || sc
->source
== cxm_fm_source
))
2401 if (cxm_pause_encoder(sc
) < 0)
2404 if (cxm_msp_select_source(sc
, source
) < 0)
2407 if (source
== cxm_fm_source
)
2408 sc
->source
= source
;
2410 result
= cxm_encoder_wait_for_lock(sc
);
2413 else if (result
== 0)
2416 if (cxm_unpause_encoder(sc
) < 0)
2421 brightness
= cxm_saa7115_get_brightness(sc
);
2427 * Brooktree brightness:
2428 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6%
2430 *(int *)ap
->a_data
= (int)(unsigned char)brightness
- 128;
2436 * Brooktree brightness:
2437 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6%
2439 brightness
= *(int *)ap
->a_data
+ 128;
2441 if (cxm_saa7115_set_brightness(sc
, brightness
) < 0)
2446 brightness
= cxm_saa7115_get_brightness(sc
);
2451 *(unsigned char *)ap
->a_data
= (unsigned char)brightness
;
2455 brightness
= *(unsigned char *)ap
->a_data
;
2457 if (cxm_saa7115_set_brightness(sc
, brightness
) < 0)
2462 chroma_saturation
= cxm_saa7115_get_chroma_saturation(sc
);
2464 if (chroma_saturation
< 0)
2468 * Brooktree chroma saturation:
2469 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18%
2471 *(int *)ap
->a_data
= ((signed char)chroma_saturation
> 0)
2472 ? (chroma_saturation
* 4 - 2) : 0;
2478 * Brooktree chroma saturation:
2479 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18%
2481 chroma_saturation
= (*(int *)ap
->a_data
& 0x1ff) < 510
2482 ? ((*(int *)ap
->a_data
& 0x1ff) + 2) / 4 : 127;
2484 if (cxm_saa7115_set_chroma_saturation(sc
, chroma_saturation
)
2491 chroma_saturation
= cxm_saa7115_get_chroma_saturation(sc
);
2493 if (chroma_saturation
< 0)
2496 *(unsigned char *)ap
->a_data
= (unsigned char)chroma_saturation
;
2500 chroma_saturation
= *(unsigned char *)ap
->a_data
;
2502 if (cxm_saa7115_set_chroma_saturation(sc
, chroma_saturation
)
2508 contrast
= cxm_saa7115_get_contrast(sc
);
2513 *(unsigned char *)ap
->a_data
= (unsigned char)contrast
;
2517 contrast
= *(unsigned char *)ap
->a_data
;
2519 if (cxm_saa7115_set_contrast(sc
, contrast
) < 0)
2524 hue
= cxm_saa7115_get_hue(sc
);
2529 *(int *)ap
->a_data
= (signed char)hue
;
2533 hue
= *(int *)ap
->a_data
;
2535 if (cxm_saa7115_set_hue(sc
, hue
) < 0)
2540 hue
= cxm_saa7115_get_hue(sc
);
2545 *(signed char *)ap
->a_data
= (signed char)hue
;
2549 hue
= *(signed char *)ap
->a_data
;
2551 if (cxm_saa7115_set_hue(sc
, hue
) < 0)
2556 switch (*(int *) ap
->a_data
) {
2557 case METEOR_CAP_CONTINOUS
:
2558 if (cxm_start_encoder(sc
) < 0)
2562 case METEOR_CAP_STOP_CONT
:
2563 if (cxm_stop_encoder(sc
) < 0)
2572 case BT848_GCAPAREA
:
2573 cap
= (struct bktr_capture_area
*)ap
->a_data
;
2574 memset (cap
, 0, sizeof (*cap
));
2577 cap
->x_size
= sc
->profile
->width
;
2578 cap
->y_size
= sc
->profile
->height
;
2581 case BT848_SCAPAREA
:
2585 cap
= (struct bktr_capture_area
*)ap
->a_data
;
2586 if (cap
->x_offset
|| cap
->y_offset
2587 || (cap
->x_size
% CXM_MACROBLOCK_WIDTH
)
2588 || (cap
->y_size
% CXM_MACROBLOCK_HEIGHT
))
2592 * Setting the width and height has the side effect of
2593 * chosing between the VCD, SVCD, and DVD profiles.
2596 for (i
= 0; i
< NUM_ELEMENTS(codec_profiles
); i
++)
2597 if (codec_profiles
[i
]->width
== cap
->x_size
2598 && codec_profiles
[i
]->height
== cap
->y_size
)
2601 if (i
>= NUM_ELEMENTS(codec_profiles
))
2604 sc
->profile
= codec_profiles
[i
];
2608 switch (cxm_saa7115_detected_format(sc
)) {
2609 case cxm_ntsc_60hz_source_format
:
2610 *(unsigned long *)ap
->a_data
= BT848_IFORM_F_NTSCM
;
2613 case cxm_pal_50hz_source_format
:
2614 *(unsigned long *)ap
->a_data
= BT848_IFORM_F_PALBDGHI
;
2617 case cxm_secam_50hz_source_format
:
2618 *(unsigned long *)ap
->a_data
= BT848_IFORM_F_SECAM
;
2621 case cxm_pal_60hz_source_format
:
2622 *(unsigned long *)ap
->a_data
= BT848_IFORM_F_PALM
;
2625 case cxm_bw_50hz_source_format
:
2626 case cxm_bw_60hz_source_format
:
2627 case cxm_ntsc_50hz_source_format
:
2628 *(unsigned long *)ap
->a_data
= BT848_IFORM_F_AUTO
;
2637 switch (cxm_saa7115_detected_format(sc
)) {
2638 case cxm_ntsc_60hz_source_format
:
2639 *(unsigned long *)ap
->a_data
= METEOR_FMT_NTSC
;
2642 case cxm_pal_50hz_source_format
:
2643 *(unsigned long *)ap
->a_data
= METEOR_FMT_PAL
;
2646 case cxm_secam_50hz_source_format
:
2647 *(unsigned long *)ap
->a_data
= METEOR_FMT_SECAM
;
2650 case cxm_bw_50hz_source_format
:
2651 case cxm_bw_60hz_source_format
:
2652 case cxm_ntsc_50hz_source_format
:
2653 case cxm_pal_60hz_source_format
:
2654 *(unsigned long *)ap
->a_data
= METEOR_FMT_AUTOMODE
;
2663 fps
= cxm_saa7115_detected_fps(sc
);
2668 *(unsigned short *)ap
->a_data
= fps
;
2672 switch (sc
->source
) {
2673 case cxm_tuner_source
:
2674 *(unsigned long *)ap
->a_data
= METEOR_INPUT_DEV1
;
2677 case cxm_line_in_source_composite
:
2678 *(unsigned long *)ap
->a_data
= METEOR_INPUT_DEV2
;
2681 case cxm_line_in_source_svideo
:
2682 *(unsigned long *)ap
->a_data
= METEOR_INPUT_DEV_SVIDEO
;
2691 source
= cxm_unknown_source
;
2693 switch (*(unsigned long *)ap
->a_data
& 0xf000) {
2694 case METEOR_INPUT_DEV1
:
2695 source
= cxm_tuner_source
;
2698 case METEOR_INPUT_DEV2
:
2699 source
= cxm_line_in_source_composite
;
2702 case METEOR_INPUT_DEV_SVIDEO
:
2703 source
= cxm_line_in_source_svideo
;
2713 * Switching between audio + video and audio only
2714 * subtypes isn't supported while encoding.
2717 if (source
!= sc
->source
2718 && (source
== cxm_fm_source
2719 || sc
->source
== cxm_fm_source
))
2723 if (cxm_pause_encoder(sc
) < 0)
2726 if (cxm_saa7115_select_source(sc
, source
) < 0)
2728 if (cxm_msp_select_source(sc
, source
) < 0)
2730 sc
->source
= source
;
2732 result
= cxm_encoder_wait_for_lock(sc
);
2735 else if (result
== 0)
2738 if (cxm_unpause_encoder(sc
) < 0)
2743 *(unsigned int *)ap
->a_data
= sc
->enc_signal
;
2747 sig
= *(unsigned int *)ap
->a_data
;
2749 if (!_SIG_VALID(sig
))
2753 * Historically, applications used METEOR_SIG_MODE_MASK
2754 * to reset signal delivery.
2756 if (sig
== METEOR_SIG_MODE_MASK
)
2760 sc
->enc_proc
= sig
? curproc
: NULL
;
2761 sc
->enc_signal
= sig
;
2766 /* Convert from kHz to MHz * 100 */
2767 freq
= sc
->tuner_freq
/ 10;
2769 *(unsigned int *)ap
->a_data
= freq
;
2773 if (sc
->source
== cxm_fm_source
)
2774 if (cxm_pause_encoder(sc
) < 0)
2777 /* Convert from MHz * 100 to kHz */
2778 freq
= *(unsigned int *)ap
->a_data
* 10;
2780 if (cxm_tuner_select_frequency(sc
, cxm_tuner_fm_freq_type
,
2785 * Explicitly wait for the tuner lock so we
2786 * can indicate if there's a station present.
2788 if (cxm_tuner_wait_for_lock(sc
) < 0)
2791 result
= cxm_encoder_wait_for_lock(sc
);
2794 else if (result
== 0)
2797 if (sc
->source
== cxm_fm_source
)
2798 if (cxm_unpause_encoder(sc
) < 0)
2802 case TVTUNER_GETAFC
:
2803 *(int *)ap
->a_data
= sc
->tuner_afc
;
2806 case TVTUNER_SETAFC
:
2807 sc
->tuner_afc
= (*(int *)ap
->a_data
!= 0);
2810 case TVTUNER_GETTYPE
:
2811 *(unsigned int *)ap
->a_data
= cxm_tuner_selected_channel_set(sc
);
2814 case TVTUNER_SETTYPE
:
2815 if (cxm_tuner_select_channel_set(sc
, *(unsigned int *)ap
->a_data
) < 0)
2819 case TVTUNER_SETCHNL
:
2820 if (sc
->source
== cxm_tuner_source
)
2821 if (cxm_pause_encoder(sc
) < 0)
2824 if (cxm_tuner_select_channel(sc
, *(unsigned int *)ap
->a_data
) < 0)
2828 if (cxm_tuner_apply_afc(sc
) < 0)
2832 * Explicitly wait for the tuner lock so we
2833 * can indicate if there's a station present.
2835 if (cxm_tuner_wait_for_lock(sc
) < 0)
2838 result
= cxm_encoder_wait_for_lock(sc
);
2841 else if (result
== 0)
2844 if (sc
->source
== cxm_tuner_source
)
2845 if (cxm_unpause_encoder(sc
) < 0)
2849 case TVTUNER_GETFREQ
:
2850 /* Convert from kHz to MHz * 16 */
2851 freq
= (sc
->tuner_freq
* 16) / 1000;
2853 *(unsigned int *)ap
->a_data
= freq
;
2856 case TVTUNER_SETFREQ
:
2857 if (sc
->source
== cxm_tuner_source
)
2858 if (cxm_pause_encoder(sc
) < 0)
2861 /* Convert from MHz * 16 to kHz */
2862 freq
= (*(unsigned int *)ap
->a_data
* 1000) / 16;
2864 if (cxm_tuner_select_frequency(sc
, cxm_tuner_tv_freq_type
,
2869 * Explicitly wait for the tuner lock so we
2870 * can indicate if there's a station present.
2872 if (cxm_tuner_wait_for_lock(sc
) < 0)
2875 result
= cxm_encoder_wait_for_lock(sc
);
2878 else if (result
== 0)
2881 if (sc
->source
== cxm_tuner_source
)
2882 if (cxm_unpause_encoder(sc
) < 0)
2887 case TVTUNER_GETSTATUS
:
2888 status
= cxm_tuner_status(sc
);
2891 *(unsigned long *)ap
->a_data
= status
& 0xff;
2895 remote
= (struct bktr_remote
*)ap
->a_data
;
2896 if (cxm_ir_key(sc
, (char *)remote
, sizeof(*remote
)) < 0)
2907 static struct filterops cxm_filterops
=
2908 { FILTEROP_ISFD
, NULL
, cxm_filter_detach
, cxm_filter
};
2911 cxm_kqfilter(struct dev_kqfilter_args
*ap
)
2913 cdev_t dev
= ap
->a_head
.a_dev
;
2914 struct knote
*kn
= ap
->a_kn
;
2915 struct cxm_softc
*sc
;
2916 struct klist
*klist
;
2921 switch (kn
->kn_filter
) {
2923 unit
= UNIT(minor(dev
));
2924 /* Get the device data */
2925 sc
= (struct cxm_softc
*)devclass_get_softc(cxm_devclass
, unit
);
2926 kn
->kn_fop
= &cxm_filterops
;
2927 kn
->kn_hook
= (caddr_t
)sc
;
2930 ap
->a_result
= EOPNOTSUPP
;
2934 klist
= &sc
->enc_kq
.ki_note
;
2935 knote_insert(klist
, kn
);
2941 cxm_filter_detach(struct knote
*kn
)
2943 struct cxm_softc
*sc
= (struct cxm_softc
*)kn
->kn_hook
;
2944 struct klist
*klist
= &sc
->enc_kq
.ki_note
;
2946 knote_remove(klist
, kn
);
2950 cxm_filter(struct knote
*kn
, long hint
)
2952 struct cxm_softc
*sc
= (struct cxm_softc
*)kn
->kn_hook
;
2956 /* the device is no longer valid/functioning */
2957 kn
->kn_flags
|= (EV_EOF
| EV_NODATA
);
2962 if (sc
->enc_pool
.read
!= sc
->enc_pool
.write
)