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