xref: /dragonfly/sys/dev/video/cxm/cxm.c (revision 9f3fc534)
1 /*
2  * Copyright (c) 2003, 2004, 2005
3  *	John Wehle <john@feith.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by John Wehle.
16  * 4. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Conexant MPEG-2 Codec driver. Supports the CX23415 / CX23416
34  * chips that are on the Hauppauge PVR-250 and PVR-350 video
35  * capture cards.  Currently only the encoder is supported.
36  *
37  * This driver was written using the invaluable information
38  * compiled by The IvyTV Project (ivtv.sourceforge.net).
39  */
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/conf.h>
44 #include <sys/uio.h>
45 #include <sys/kernel.h>
46 #include <sys/mman.h>
47 #include <sys/module.h>
48 #include <sys/poll.h>
49 #include <sys/proc.h>
50 #include <sys/signalvar.h>
51 #include <sys/thread2.h>
52 #include <sys/vnode.h>
53 #include <sys/select.h>
54 #include <sys/resource.h>
55 #include <sys/bus.h>
56 #include <sys/rman.h>
57 
58 #include <machine/clock.h>
59 
60 #include <dev/video/meteor/ioctl_meteor.h>
61 #include <dev/video/bktr/ioctl_bt848.h>
62 
63 #include <bus/pci/pcireg.h>
64 #include <bus/pci/pcivar.h>
65 
66 #include <dev/video/cxm/cxm.h>
67 
68 #include <bus/iicbus/iiconf.h>
69 
70 /*
71  * Various supported device vendors/types and their names.
72  */
73 static struct cxm_dev cxm_devs[] = {
74 	{ PCI_VENDOR_ICOMPRESSION, PCI_PRODUCT_ICOMPRESSION_ITVC15,
75 		"Conexant iTVC15 MPEG Coder" },
76 	{ PCI_VENDOR_ICOMPRESSION, PCI_PRODUCT_ICOMPRESSION_ITVC16,
77 		"Conexant iTVC16 MPEG Coder" },
78 	{ 0, 0, NULL }
79 };
80 
81 
82 static int	cxm_probe(device_t dev);
83 static int	cxm_attach(device_t dev);
84 static int	cxm_detach(device_t dev);
85 static int	cxm_shutdown(device_t dev);
86 static void	cxm_intr(void *arg);
87 
88 static void	cxm_child_detached(device_t dev, device_t child);
89 static int	cxm_read_ivar(device_t bus, device_t dev,
90 			       int index, uintptr_t* val);
91 static int	cxm_write_ivar(device_t bus, device_t dev,
92 				int index, uintptr_t val);
93 
94 
95 static device_method_t cxm_methods[] = {
96 	/* Device interface */
97 	DEVMETHOD(device_probe,         cxm_probe),
98 	DEVMETHOD(device_attach,        cxm_attach),
99 	DEVMETHOD(device_detach,        cxm_detach),
100 	DEVMETHOD(device_shutdown,      cxm_shutdown),
101 
102 	/* bus interface */
103 	DEVMETHOD(bus_child_detached,   cxm_child_detached),
104 	DEVMETHOD(bus_print_child,      bus_generic_print_child),
105 	DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
106 	DEVMETHOD(bus_read_ivar,        cxm_read_ivar),
107 	DEVMETHOD(bus_write_ivar,       cxm_write_ivar),
108 
109 	{ 0, 0 }
110 };
111 
112 static driver_t cxm_driver = {
113 	"cxm",
114 	cxm_methods,
115 	sizeof(struct cxm_softc),
116 };
117 
118 static devclass_t cxm_devclass;
119 
120 static	d_open_t	cxm_open;
121 static	d_close_t	cxm_close;
122 static	d_read_t	cxm_read;
123 static	d_ioctl_t	cxm_ioctl;
124 static	d_poll_t	cxm_poll;
125 
126 #define CDEV_MAJOR 93
127 
128 static struct dev_ops cxm_ops = {
129 	{ "cxm", CDEV_MAJOR, 0 },
130 	.d_open =	cxm_open,
131 	.d_close =	cxm_close,
132 	.d_read =	cxm_read,
133 	.d_ioctl =	cxm_ioctl,
134 	.d_poll =	cxm_poll
135 };
136 
137 MODULE_DEPEND(cxm, cxm_iic, 1, 1, 1);
138 DRIVER_MODULE(cxm, pci, cxm_driver, cxm_devclass, 0, 0);
139 
140 
141 static struct cxm_codec_audio_format codec_audio_formats[] = {
142 	{ 44100, 0xb8 }, /* 44.1 Khz, MPEG-1 Layer II, 224 kb/s */
143 	{ 48000, 0xe9 }  /* 48 Khz, MPEG-1 Layer II, 384 kb/s */
144 };
145 
146 
147 /*
148  * Various profiles.
149  */
150 static struct cxm_codec_profile vcd_ntsc_profile = {
151 	"MPEG-1 VideoCD NTSC video and MPEG audio",
152 	CXM_FW_STREAM_TYPE_VCD,
153 	30,
154 	352, 240, 480,
155 	{ 10, 12, 21 },
156 	12,
157 	0,
158 	{ 1, 1150000, 0 },
159 	{ 1, 15, 3},
160 	/*
161 	 * Spatial filter = Manual, Temporal filter = Manual
162 	 * Median filter = Horizontal / Vertical
163 	 * Spatial filter value = 1, Temporal filter value = 4
164 	 */
165 	{ 0, 3, 1, 4 },
166 	44100
167 };
168 
169 static struct cxm_codec_profile vcd_pal_profile = {
170 	"MPEG-1 VideoCD PAL video and MPEG audio",
171 	CXM_FW_STREAM_TYPE_VCD,
172 	25,
173 	352, 288, 576,
174 	{ 6, 17, 22 },
175 	8,
176 	0,
177 	{ 1, 1150000, 0 },
178 	{ 1, 12, 3},
179 	/*
180 	 * Spatial filter = Manual, Temporal filter = Manual
181 	 * Median filter = Horizontal / Vertical
182 	 * Spatial filter value = 1, Temporal filter value = 4
183 	 */
184 	{ 0, 3, 1, 4 },
185 	44100
186 };
187 
188 static struct cxm_codec_profile svcd_ntsc_profile = {
189 	"MPEG-2 SuperVCD NTSC video and MPEG audio",
190 	CXM_FW_STREAM_TYPE_SVCD,
191 	30,
192 	480, 480, 480,
193 	{ 10, 12, 21 },
194 	2,
195 	0,
196 	/* 2.5 Mb/s peak limit to keep bbdmux followed by mplex -f 4 happy */
197 	{ 0, 1150000, 2500000 },
198 	{ 1, 15, 3},
199 	/*
200 	 * Spatial filter = Manual, Temporal filter = Manual
201 	 * Median filter = Horizontal / Vertical
202 	 * Spatial filter value = 1, Temporal filter value = 4
203 	 */
204 	{ 0, 3, 1, 4 },
205 	44100
206 };
207 
208 static struct cxm_codec_profile svcd_pal_profile = {
209 	"MPEG-2 SuperVCD PAL video and MPEG audio",
210 	CXM_FW_STREAM_TYPE_SVCD,
211 	25,
212 	480, 576, 576,
213 	{ 6, 17, 22 },
214 	2,
215 	0,
216 	/* 2.5 Mb/s peak limit to keep bbdmux followed by mplex -f 4 happy */
217 	{ 0, 1150000, 2500000 },
218 	{ 1, 12, 3},
219 	/*
220 	 * Spatial filter = Manual, Temporal filter = Manual
221 	 * Median filter = Horizontal / Vertical
222 	 * Spatial filter value = 1, Temporal filter value = 4
223 	 */
224 	{ 0, 3, 1, 4 },
225 	44100
226 };
227 
228 static struct cxm_codec_profile dvd_half_d1_ntsc_profile = {
229 	"MPEG-2 DVD NTSC video and MPEG audio",
230 	CXM_FW_STREAM_TYPE_DVD,
231 	30,
232 	352, 480, 480,
233 	{ 10, 12, 21 },
234 	2,
235 	0,
236 	{ 0, 4000000, 4520000 }, /* 4 hours on 8.54 GB media */
237 	{ 1, 15, 3},
238 	/*
239 	 * Spatial filter = Manual, Temporal filter = Manual
240 	 * Median filter = Horizontal / Vertical
241 	 * Spatial filter value = 1, Temporal filter value = 4
242 	 */
243 	{ 0, 3, 1, 4 },
244 	48000
245 };
246 
247 static struct cxm_codec_profile dvd_half_d1_pal_profile = {
248 	"MPEG-2 DVD PAL video and MPEG audio",
249 	CXM_FW_STREAM_TYPE_DVD,
250 	25,
251 	352, 576, 576,
252 	{ 6, 17, 22 },
253 	2,
254 	0,
255 	{ 0, 4000000, 4520000 }, /* 4 hours on 8.54 GB media */
256 	{ 1, 12, 3},
257 	/*
258 	 * Spatial filter = Manual, Temporal filter = Manual
259 	 * Median filter = Horizontal / Vertical
260 	 * Spatial filter value = 1, Temporal filter value = 4
261 	 */
262 	{ 0, 3, 1, 4 },
263 	48000
264 };
265 
266 static struct cxm_codec_profile dvd_full_d1_ntsc_profile = {
267 	"MPEG-2 DVD NTSC video and MPEG audio",
268 	CXM_FW_STREAM_TYPE_DVD,
269 	30,
270 	720, 480, 480,
271 	{ 10, 12, 21 },
272 	2,
273 	0,
274 	/* 9.52 Mb/s peak limit to keep bbdmux followed by mplex -f 8 happy */
275 	{ 0, 9000000, 9520000 }, /* 1 hour on 4.7 GB media */
276 	{ 1, 15, 3},
277 	/*
278 	 * Spatial filter = Manual, Temporal filter = Manual
279 	 * Median filter = Horizontal / Vertical
280 	 * Spatial filter value = 1, Temporal filter value = 4
281 	 */
282 	{ 0, 3, 1, 4 },
283 	48000
284 };
285 
286 static struct cxm_codec_profile dvd_full_d1_pal_profile = {
287 	"MPEG-2 DVD PAL video and MPEG audio",
288 	CXM_FW_STREAM_TYPE_DVD,
289 	25,
290 	720, 576, 576,
291 	{ 6, 17, 22 },
292 	2,
293 	0,
294 	/* 9.52 Mb/s peak limit to keep bbdmux followed by mplex -f 8 happy */
295 	{ 0, 9000000, 9520000 }, /* 1 hour on 4.7 GB media */
296 	{ 1, 12, 3},
297 	/*
298 	 * Spatial filter = Manual, Temporal filter = Manual
299 	 * Median filter = Horizontal / Vertical
300 	 * Spatial filter value = 1, Temporal filter value = 4
301 	 */
302 	{ 0, 3, 1, 4 },
303 	48000
304 };
305 
306 
307 static const struct cxm_codec_profile
308 *codec_profiles[] = {
309 	&vcd_ntsc_profile,
310 	&vcd_pal_profile,
311 	&svcd_ntsc_profile,
312 	&svcd_pal_profile,
313 	&dvd_half_d1_ntsc_profile,
314 	&dvd_half_d1_pal_profile,
315 	&dvd_full_d1_ntsc_profile,
316 	&dvd_full_d1_pal_profile
317 };
318 
319 
320 static unsigned int
321 cxm_queue_firmware_command(struct cxm_softc *sc,
322 			    enum cxm_mailbox_name mbx_name, uint32_t cmd,
323 			    uint32_t *parameters, unsigned int nparameters)
324 {
325 	unsigned int i;
326 	unsigned int mailbox;
327 	uint32_t completed_command;
328 	uint32_t flags;
329 
330 	if (nparameters > CXM_MBX_MAX_PARAMETERS) {
331 		device_printf(sc->dev, "too many parameters for mailbox\n");
332 		return -1;
333 	}
334 
335 	mailbox = 0;
336 
337 	switch (mbx_name) {
338 	case cxm_dec_mailbox:
339 		mailbox = sc->dec_mbx
340 			  + CXM_MBX_FW_CMD_MAILBOX *sizeof(struct cxm_mailbox);
341 		break;
342 
343 	case cxm_enc_mailbox:
344 		mailbox = sc->enc_mbx
345 			  + CXM_MBX_FW_CMD_MAILBOX *sizeof(struct cxm_mailbox);
346 		break;
347 
348 	default:
349 		return -1;
350 	}
351 
352 	crit_enter();
353 	for (i = 0; i < CXM_MBX_FW_CMD_MAILBOXES; i++) {
354 		flags = CSR_READ_4(sc,
355 				   mailbox
356 				   + offsetof(struct cxm_mailbox, flags));
357 		if (!(flags & CXM_MBX_FLAG_IN_USE))
358 			break;
359 
360 		/*
361 		 * Mail boxes containing certain completed commands
362 		 * for which the results are never needed can be reused.
363 		 */
364 
365 		if ((flags & (CXM_MBX_FLAG_DRV_DONE | CXM_MBX_FLAG_FW_DONE))
366 		    == (CXM_MBX_FLAG_DRV_DONE | CXM_MBX_FLAG_FW_DONE)) {
367 			completed_command
368 			 = CSR_READ_4(sc,
369 				      mailbox
370 				      + offsetof(struct cxm_mailbox, command));
371 
372 			/*
373 			 * DMA results are always check by reading the
374 			 * DMA status register ... never by checking
375 			 * the mailbox after the command has completed.
376 			 */
377 
378 			if (completed_command == CXM_FW_CMD_SCHED_DMA_TO_HOST)
379 				break;
380 		}
381 
382 		mailbox += sizeof(struct cxm_mailbox);
383 	}
384 
385 	if (i >= CXM_MBX_FW_CMD_MAILBOXES) {
386 		crit_exit();
387 		return -1;
388 	}
389 
390 	CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags),
391 		    CXM_MBX_FLAG_IN_USE);
392 
393 	/*
394 	 * PCI writes may be buffered so force the
395 	 * write to complete by reading the last
396 	 * location written.
397 	 */
398 
399 	CSR_READ_4(sc, mailbox + offsetof(struct cxm_mailbox, flags));
400 
401 	crit_exit();
402 
403 	CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, command), cmd);
404 	CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, timeout),
405 		    CXM_FW_STD_TIMEOUT);
406 
407 	for (i = 0; i < nparameters; i++)
408 		CSR_WRITE_4(sc,
409 			    mailbox
410 			    + offsetof(struct cxm_mailbox, parameters)
411 			    + i * sizeof(uint32_t),
412 			    *(parameters + i));
413 
414 	for (; i < CXM_MBX_MAX_PARAMETERS; i++)
415 		CSR_WRITE_4(sc,
416 			    mailbox
417 			    + offsetof(struct cxm_mailbox, parameters)
418 			    + i * sizeof(uint32_t), 0);
419 
420 	CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags),
421 		    CXM_MBX_FLAG_IN_USE | CXM_MBX_FLAG_DRV_DONE);
422 
423 	return mailbox;
424 }
425 
426 
427 static int
428 cxm_firmware_command(struct cxm_softc *sc,
429 		      enum cxm_mailbox_name mbx_name, uint32_t cmd,
430 		      uint32_t *parameters, unsigned int nparameters)
431 {
432 	const char *wmesg;
433 	unsigned int *bmp;
434 	unsigned int i;
435 	unsigned int mailbox;
436 	uint32_t flags;
437 	uint32_t result;
438 
439 	bmp = NULL;
440 	wmesg = "";
441 
442 	switch (mbx_name) {
443 	case cxm_dec_mailbox:
444 		bmp = &sc->dec_mbx;
445 		wmesg = "cxmdfw";
446 		break;
447 
448 	case cxm_enc_mailbox:
449 		bmp = &sc->enc_mbx;
450 		wmesg = "cxmefw";
451 		break;
452 
453 	default:
454 		return -1;
455 	}
456 
457 	mailbox = cxm_queue_firmware_command(sc, mbx_name, cmd,
458 					     parameters, nparameters);
459 	if (mailbox == -1) {
460 		device_printf(sc->dev, "no free mailboxes\n");
461 		return -1;
462 	}
463 
464 	/* Give the firmware a chance to start processing the request */
465 	tsleep(bmp, 0, wmesg, hz / 100);
466 
467 	for (i = 0; i < 100; i++) {
468 		flags = CSR_READ_4(sc,
469 				   mailbox
470 				   + offsetof(struct cxm_mailbox, flags));
471 		if ((flags & CXM_MBX_FLAG_FW_DONE))
472 			break;
473 
474 		/* Wait for 10ms */
475 		tsleep(bmp, 0, wmesg, hz / 100);
476 	}
477 
478 	if (i >= 100) {
479 		device_printf(sc->dev, "timeout\n");
480 		return -1;
481 	}
482 
483 	result = CSR_READ_4(sc,
484 			    mailbox
485 			    + offsetof(struct cxm_mailbox, result));
486 
487 	for (i = 0; i < nparameters; i++)
488 		*(parameters + i)
489 		  = CSR_READ_4(sc,
490 			       mailbox
491 			       + offsetof(struct cxm_mailbox, parameters)
492 			       + i * sizeof(uint32_t));
493 
494 	CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), 0);
495 
496 	return result == 0 ? 0 : -1;
497 }
498 
499 
500 static int
501 cxm_firmware_command_nosleep(struct cxm_softc *sc,
502 			      enum cxm_mailbox_name mbx_name, uint32_t cmd,
503 			      uint32_t *parameters, unsigned int nparameters)
504 {
505 	unsigned int i;
506 	unsigned int mailbox;
507 	uint32_t flags;
508 	uint32_t result;
509 
510 	for (i = 0; i < 100; i++) {
511 		mailbox = cxm_queue_firmware_command(sc, mbx_name, cmd,
512 						     parameters, nparameters);
513 		if (mailbox != -1)
514 			break;
515 
516 		/* Wait for 10ms */
517 		DELAY(10000);
518 		}
519 
520 	if (i >= 100) {
521 		device_printf(sc->dev, "no free mailboxes\n");
522 		return -1;
523 	}
524 
525 	/* Give the firmware a chance to start processing the request */
526 	DELAY(10000);
527 
528 	for (i = 0; i < 100; i++) {
529 		flags = CSR_READ_4(sc,
530 				   mailbox
531 				   + offsetof(struct cxm_mailbox, flags));
532 		if ((flags & CXM_MBX_FLAG_FW_DONE))
533 			break;
534 
535 		/* Wait for 10ms */
536 		DELAY(10000);
537 	}
538 
539 	if (i >= 100) {
540 		device_printf(sc->dev, "timeout\n");
541 		return -1;
542 	}
543 
544 	result = CSR_READ_4(sc,
545 			    mailbox
546 			    + offsetof(struct cxm_mailbox, result));
547 
548 	for (i = 0; i < nparameters; i++)
549 		*(parameters + i)
550 		  = CSR_READ_4(sc,
551 			       mailbox
552 			       + offsetof(struct cxm_mailbox, parameters)
553 			       + i * sizeof(uint32_t));
554 
555 	CSR_WRITE_4(sc, mailbox + offsetof(struct cxm_mailbox, flags), 0);
556 
557 	return result == 0 ? 0 : -1;
558 }
559 
560 
561 static int
562 cxm_stop_firmware(struct cxm_softc *sc)
563 {
564 
565 	if (cxm_firmware_command_nosleep(sc, cxm_enc_mailbox,
566 					 CXM_FW_CMD_ENC_HALT_FW, NULL, 0) < 0)
567 		return -1;
568 
569 	if (sc->type == cxm_iTVC15_type
570 	    && cxm_firmware_command_nosleep(sc, cxm_dec_mailbox,
571 					    CXM_FW_CMD_DEC_HALT_FW,
572 					    NULL, 0) < 0)
573 		return -1;
574 
575 	/* Wait for 10ms */
576 	DELAY(10000);
577 
578 	return 0;
579 }
580 
581 
582 static void
583 cxm_set_irq_mask(struct cxm_softc *sc, uint32_t mask)
584 {
585 	crit_enter();
586 
587 	CSR_WRITE_4(sc, CXM_REG_IRQ_MASK, mask);
588 
589 	/*
590 	 * PCI writes may be buffered so force the
591 	 * write to complete by reading the last
592 	 * location written.
593 	 */
594 
595 	CSR_READ_4(sc, CXM_REG_IRQ_MASK);
596 
597 	sc->irq_mask = mask;
598 
599 	crit_exit();
600 }
601 
602 
603 static void
604 cxm_set_irq_status(struct cxm_softc *sc, uint32_t status)
605 {
606 
607 	CSR_WRITE_4(sc, CXM_REG_IRQ_STATUS, status);
608 
609 	/*
610 	 * PCI writes may be buffered so force the
611 	 * write to complete by reading the last
612 	 * location written.
613 	 */
614 
615 	CSR_READ_4(sc, CXM_REG_IRQ_STATUS);
616 }
617 
618 
619 static int
620 cxm_stop_hardware(struct cxm_softc *sc)
621 {
622 	if (sc->cxm_iic) {
623 		if (cxm_saa7115_mute(sc) < 0)
624 			return -1;
625 		if (cxm_msp_mute(sc) < 0)
626 			return -1;
627 	}
628 
629 	/* Halt the firmware */
630 	if (sc->enc_mbx != -1) {
631 		if (cxm_stop_firmware(sc) < 0)
632 			return -1;
633 	}
634 
635 	/* Mask all interrupts */
636 	cxm_set_irq_mask(sc, 0xffffffff);
637 
638 	/* Stop VDM */
639 	CSR_WRITE_4(sc, CXM_REG_VDM, CXM_CMD_VDM_STOP);
640 
641 	/* Stop AO */
642 	CSR_WRITE_4(sc, CXM_REG_AO, CXM_CMD_AO_STOP);
643 
644 	/* Ping (?) APU */
645 	CSR_WRITE_4(sc, CXM_REG_APU, CXM_CMD_APU_PING);
646 
647 	/* Stop VPU */
648 	CSR_WRITE_4(sc, CXM_REG_VPU, sc->type == cxm_iTVC15_type
649 					? CXM_CMD_VPU_STOP15
650 					: CXM_CMD_VPU_STOP16);
651 
652 	/* Reset Hw Blocks */
653 	CSR_WRITE_4(sc, CXM_REG_HW_BLOCKS, CXM_CMD_HW_BLOCKS_RST);
654 
655 	/* Stop SPU */
656 	CSR_WRITE_4(sc, CXM_REG_SPU, CXM_CMD_SPU_STOP);
657 
658 	/* Wait for 10ms */
659 	DELAY(10000);
660 
661 	return 0;
662 }
663 
664 
665 static int
666 cxm_download_firmware(struct cxm_softc *sc)
667 {
668 	unsigned int i;
669 	const uint32_t *fw;
670 
671 	/* Check if firmware is compiled in */
672 	if (strncmp((const char *)cxm_enc_fw, "NOFW", 4) == 0) {
673 		device_printf(sc->dev, "encoder firmware not compiled in\n");
674 		return -1;
675 	} else if (strncmp((const char *)cxm_dec_fw, "NOFW", 4) == 0) {
676 		device_printf(sc->dev, "decoder firmware not compiled in\n");
677 		return -1;
678 	}
679 
680 	/* Download the encoder firmware */
681 	fw = (const uint32_t *)cxm_enc_fw;
682 	for (i = 0; i < CXM_FW_SIZE; i += sizeof(*fw))
683 		CSR_WRITE_4(sc, CXM_MEM_ENC + i, *fw++);
684 
685 	/* Download the decoder firmware */
686 	if (sc->type == cxm_iTVC15_type) {
687 		fw = (const uint32_t *)cxm_dec_fw;
688 		for (i = 0; i < CXM_FW_SIZE; i += sizeof(*fw))
689 			CSR_WRITE_4(sc, CXM_MEM_DEC + i, *fw++);
690 	}
691 
692 	return 0;
693 }
694 
695 
696 static int
697 cxm_init_hardware(struct cxm_softc *sc)
698 {
699 	unsigned int i;
700 	unsigned int mailbox;
701 	uint32_t parameter;
702 
703 	if (cxm_stop_hardware(sc) < 0)
704 		return -1;
705 
706 	/* Initialize encoder SDRAM pre-charge */
707 	CSR_WRITE_4(sc, CXM_REG_ENC_SDRAM_PRECHARGE,
708 			CXM_CMD_SDRAM_PRECHARGE_INIT);
709 
710 	/* Initialize encoder SDRAM refresh to 1us */
711 	CSR_WRITE_4(sc, CXM_REG_ENC_SDRAM_REFRESH,
712 			CXM_CMD_SDRAM_REFRESH_INIT);
713 
714 	/* Initialize decoder SDRAM pre-charge */
715 	CSR_WRITE_4(sc, CXM_REG_DEC_SDRAM_PRECHARGE,
716 			CXM_CMD_SDRAM_PRECHARGE_INIT);
717 
718 	/* Initialize decoder SDRAM refresh to 1us */
719 	CSR_WRITE_4(sc, CXM_REG_DEC_SDRAM_REFRESH,
720 			CXM_CMD_SDRAM_REFRESH_INIT);
721 
722 	/* Wait for 600ms */
723 	DELAY(600000);
724 
725 	if (cxm_download_firmware(sc) < 0)
726 		return -1;
727 
728 	/* Enable SPU */
729 	CSR_WRITE_4(sc, CXM_REG_SPU,
730 			CSR_READ_4(sc, CXM_REG_SPU) & CXM_MASK_SPU_ENABLE);
731 
732 	/* Wait for 1 second */
733 	DELAY(1000000);
734 
735 	/* Enable VPU */
736 	CSR_WRITE_4(sc, CXM_REG_VPU,
737 			CSR_READ_4(sc, CXM_REG_VPU)
738 			& (sc->type == cxm_iTVC15_type
739 				? CXM_MASK_VPU_ENABLE15
740 				: CXM_MASK_VPU_ENABLE16));
741 
742 	/* Wait for 1 second */
743 	DELAY(1000000);
744 
745 	/* Locate encoder mailbox */
746 	mailbox = CXM_MEM_ENC;
747 	for (i = 0; i < CXM_MEM_ENC_SIZE; i += 0x100)
748 		if (CSR_READ_4(sc, mailbox + i) == 0x12345678
749 		    && CSR_READ_4(sc, mailbox + i + 4) == 0x34567812
750 		    && CSR_READ_4(sc, mailbox + i + 8) == 0x56781234
751 		    && CSR_READ_4(sc, mailbox + i + 12) == 0x78123456)
752 			break;
753 
754 	if (i >= CXM_MEM_ENC_SIZE)
755 		return -1;
756 
757 	sc->enc_mbx = mailbox + i + 16;
758 
759 	/* Locate decoder mailbox */
760 	if (sc->type == cxm_iTVC15_type) {
761 		mailbox = CXM_MEM_DEC;
762 		for (i = 0; i < CXM_MEM_DEC_SIZE; i += 0x100)
763 			if (CSR_READ_4(sc, mailbox + i) == 0x12345678
764 			    && CSR_READ_4(sc, mailbox + i + 4) == 0x34567812
765 			    && CSR_READ_4(sc, mailbox + i + 8) == 0x56781234
766 			    && CSR_READ_4(sc, mailbox + i + 12) == 0x78123456)
767 				break;
768 
769 		if (i >= CXM_MEM_DEC_SIZE)
770 			return -1;
771 
772 		sc->dec_mbx = mailbox + i + 16;
773 	}
774 
775 	/* Get encoder firmware version */
776 	parameter = 0;
777 	if (cxm_firmware_command_nosleep(sc, cxm_enc_mailbox,
778 					 CXM_FW_CMD_ENC_GET_FW_VER,
779 					 &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 	selwakeup(&sc->enc_sel);
1371 }
1372 
1373 
1374 static void
1375 cxm_encoder_dma_request(struct cxm_softc *sc)
1376 {
1377 	enum cxm_byte_order byte_order;
1378 	int buffers_free;
1379 	int buffers_pending;
1380 	unsigned int current;
1381 	unsigned int i;
1382 	unsigned int mailbox;
1383 	unsigned int macroblocks_per_line;
1384 	unsigned int nrequests;
1385 	unsigned int strips;
1386 	uint32_t parameters[CXM_MBX_MAX_PARAMETERS];
1387 	uint32_t type;
1388 	size_t max_sg_segment;
1389 	struct {
1390 		size_t offset;
1391 		size_t size;
1392 	} requests[2];
1393 
1394 	if (sc->encoding_dma) {
1395 		device_printf(sc->dev, "encoder dma already in progress\n");
1396 		cxm_encoder_dma_discard(sc);
1397 		return;
1398 	}
1399 
1400 	mailbox = sc->enc_mbx
1401 		  + CXM_MBX_FW_DMA_MAILBOX * sizeof(struct cxm_mailbox);
1402 
1403 	for (i = 0; i < CXM_MBX_MAX_PARAMETERS; i++)
1404 		parameters[i]
1405 		  = CSR_READ_4(sc,
1406 			       mailbox
1407 			       + offsetof(struct cxm_mailbox, parameters)
1408 			       + i * sizeof(uint32_t)
1409 			      );
1410 
1411 	byte_order = cxm_device_mpeg_byte_order;
1412 	max_sg_segment = CXM_SG_SEGMENT;
1413 	nrequests = 0;
1414 	type = parameters[0];
1415 
1416 	switch (type) {
1417 	case 0: /* MPEG */
1418 		requests[nrequests].offset = parameters[1];
1419 		requests[nrequests++].size = parameters[2];
1420 		break;
1421 
1422 	case 1: /* YUV */
1423 		byte_order = cxm_device_yuv12_byte_order;
1424 
1425 		/*
1426 		 * Simplify macroblock unpacking by ensuring
1427 		 * that strips don't span buffers.
1428 		 */
1429 
1430 #if CXM_MACROBLOCK_SIZE % 256
1431 #  error CXM_MACROBLOCK_SIZE not a multiple of 256
1432 #endif
1433 
1434 		macroblocks_per_line = sc->profile->width
1435 				       / CXM_MACROBLOCK_WIDTH;
1436 		strips = CXM_SG_SEGMENT
1437 			 / (macroblocks_per_line * CXM_MACROBLOCK_SIZE);
1438 		max_sg_segment = strips
1439 				 * macroblocks_per_line * CXM_MACROBLOCK_SIZE;
1440 
1441 		requests[nrequests].offset = parameters[1]; /* Y */
1442 		requests[nrequests++].size = parameters[2];
1443 		requests[nrequests].offset = parameters[3]; /* UV */
1444 		requests[nrequests++].size = parameters[4];
1445 		break;
1446 
1447 	case 2: /* PCM (audio) */
1448 	case 3: /* VBI */
1449 	default:
1450 		device_printf(sc->dev, "encoder dma type %#x unsupported\n",
1451 		    (unsigned int)type);
1452 		cxm_encoder_dma_discard(sc);
1453 		return;
1454 	}
1455 
1456 	/*
1457 	 * Determine the number of buffers free at this * instant *
1458 	 * taking into consideration that the ring buffer wraps.
1459 	 */
1460 	crit_enter();
1461 	buffers_free = sc->enc_pool.read - sc->enc_pool.write;
1462 	if (buffers_free <= 0)
1463 		buffers_free += CXM_SG_BUFFERS;
1464 	crit_exit();
1465 
1466 	/*
1467 	 * Build the scatter / gather list taking in
1468 	 * consideration that the ring buffer wraps,
1469 	 * at least one free buffer must always be
1470 	 * present to mark the end of the ring buffer,
1471 	 * and each transfer must be a multiple of 256.
1472 	 */
1473 
1474 	buffers_pending = 0;
1475 	current = sc->enc_pool.write;
1476 
1477 	for (i = 0; i < nrequests; i++) {
1478 		if (!requests[i].size) {
1479 			device_printf(sc->dev, "encoder dma size is zero\n");
1480 			cxm_encoder_dma_discard(sc);
1481 			return;
1482 		}
1483 
1484 		while (requests[i].size) {
1485 			sc->enc_pool.bufs[current].size
1486 			  = requests[i].size > max_sg_segment
1487 			    ? max_sg_segment : requests[i].size;
1488 			sc->enc_pool.bufs[current].byte_order = byte_order;
1489 
1490 			sc->enc_sg.vaddr[buffers_pending].src
1491 			  = requests[i].offset;
1492 			sc->enc_sg.vaddr[buffers_pending].dst
1493 			  = sc->enc_pool.bufs[current].baddr;
1494 			sc->enc_sg.vaddr[buffers_pending].size
1495 			  = (sc->enc_pool.bufs[current].size + 0x000000ff)
1496 			    & 0xffffff00;
1497 
1498 			requests[i].offset += sc->enc_pool.bufs[current].size;
1499 			requests[i].size -= sc->enc_pool.bufs[current].size;
1500 			buffers_pending++;
1501 			current = (current + 1) % CXM_SG_BUFFERS;
1502 
1503 			if (buffers_pending >= buffers_free) {
1504 				device_printf(sc->dev,
1505 				    "encoder dma not enough buffer space free\n");
1506 				cxm_encoder_dma_discard(sc);
1507 				return;
1508 			}
1509 		}
1510 	}
1511 
1512 	/* Mark the last transfer in the list */
1513 	sc->enc_sg.vaddr[buffers_pending - 1].size |= 0x80000000;
1514 
1515 	/* Schedule the DMA */
1516 	parameters[0] = sc->enc_sg.baddr;
1517 	parameters[1] = buffers_pending * sizeof(sc->enc_sg.vaddr[0]);
1518 	parameters[2] = type;
1519 	if (cxm_queue_firmware_command(sc, cxm_enc_mailbox,
1520 				       CXM_FW_CMD_SCHED_DMA_TO_HOST,
1521 				       parameters, 3) == -1) {
1522 		device_printf(sc->dev,
1523 		    "failed to schedule encoder dma request\n");
1524 		return;
1525 	}
1526 
1527 	/*
1528 	 * Record the number of pending buffers for the
1529 	 * benefit of cxm_encoder_dma_done.  Doing this
1530 	 * after queuing the command doesn't introduce
1531 	 * a race condition since we're already in the
1532 	 * interrupt handler.
1533 	 */
1534 
1535 	sc->encoding_dma = buffers_pending;
1536 }
1537 
1538 
1539 static int
1540 cxm_encoder_wait_for_lock(struct cxm_softc *sc)
1541 {
1542 	int muted;
1543 	int locked;
1544 	int result;
1545 
1546 	locked = 1;
1547 
1548 	/*
1549 	 * Wait for the tuner to lock.
1550 	 */
1551 	if (sc->source == cxm_fm_source || sc->source == cxm_tuner_source) {
1552 		result = cxm_tuner_wait_for_lock(sc);
1553 		if (result <= 0)
1554 			return result;
1555 	}
1556 
1557 	/*
1558 	 * Wait for the video decoder to lock.
1559 	 */
1560 	if (sc->source != cxm_fm_source) {
1561 		result = cxm_saa7115_wait_for_lock(sc);
1562 		if (result < 0)
1563 			return result;
1564 		else if (result == 0)
1565 			locked = 0;
1566 		}
1567 
1568 	/*
1569 	 * Wait for the audio decoder to lock.
1570 	 */
1571 	if (sc->source == cxm_tuner_source) {
1572 		muted = cxm_msp_is_muted(sc);
1573 
1574 		result = cxm_msp_autodetect_standard(sc);
1575 		if (result < 0)
1576 			return result;
1577 		else if (result == 0)
1578 			locked = 0;
1579 
1580 		if (muted == 0 && cxm_msp_unmute(sc) < 0)
1581 			return -1;
1582 	}
1583 
1584 	return locked;
1585 }
1586 
1587 
1588 static void
1589 cxm_mapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1590 {
1591 	bus_addr_t *busaddrp;
1592 
1593 	/*
1594 	 * Only the first bus space address is needed
1595 	 * since it's known that the memory is physically
1596 	 * contiguous due to bus_dmamem_alloc.
1597 	 */
1598 
1599 	busaddrp = (bus_addr_t *)arg;
1600 	*busaddrp = segs->ds_addr;
1601 }
1602 
1603 
1604 /*
1605  * the boot time probe routine.
1606  */
1607 static int
1608 cxm_probe(device_t dev)
1609 {
1610 	struct cxm_dev		*t;
1611 
1612 	t = cxm_devs;
1613 
1614 	while(t->name != NULL) {
1615 		if ((pci_get_vendor(dev) == t->vid) &&
1616 		    (pci_get_device(dev) == t->did)) {
1617 			device_set_desc(dev, t->name);
1618 			return 0;
1619 		}
1620 		t++;
1621 	}
1622 
1623 	return ENXIO;
1624 }
1625 
1626 
1627 /*
1628  * the attach routine.
1629  */
1630 static int
1631 cxm_attach(device_t dev)
1632 {
1633 	int		error;
1634 	int		rid;
1635 	int		unit;
1636 	unsigned int	i;
1637 	uint32_t	command;
1638 	struct cxm_softc *sc;
1639 
1640 	/* Get the device data */
1641 	sc = device_get_softc(dev);
1642 	unit = device_get_unit(dev);
1643 
1644 	sc->dev = dev;
1645 	sc->type = cxm_iTVC15_type;
1646 
1647 	switch(pci_get_device(dev)) {
1648 	case PCI_PRODUCT_ICOMPRESSION_ITVC16:
1649 		sc->type = cxm_iTVC16_type;
1650 		break;
1651 
1652 	default:
1653 		break;
1654 	}
1655 
1656 	/*
1657 	 * Enable bus mastering and memory mapped I/O.
1658 	 */
1659 	pci_enable_busmaster(dev);
1660 	pci_enable_io(dev, SYS_RES_MEMORY);
1661 	command = pci_read_config(dev, PCIR_COMMAND, 4);
1662 
1663 	if (!(command & PCIM_CMD_MEMEN)) {
1664 		device_printf(dev, "failed to enable memory mappings\n");
1665 		error = ENXIO;
1666 		goto fail;
1667 	}
1668 
1669 	/*
1670 	 * Map control/status registers.
1671 	 */
1672 	rid = CXM_RID;
1673 	sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
1674 					0, ~0, 1, RF_ACTIVE);
1675 
1676 	if (!sc->mem_res) {
1677 		device_printf(dev, "could not map memory\n");
1678 		error = ENXIO;
1679 		goto fail;
1680 	}
1681 
1682 	sc->btag = rman_get_bustag(sc->mem_res);
1683 	sc->bhandle = rman_get_bushandle(sc->mem_res);
1684 
1685 	/*
1686 	 * Attach the I2C bus.
1687 	 */
1688 	sc->cxm_iic = device_add_child(dev, "cxm_iic", unit);
1689 
1690 	if (!sc->cxm_iic) {
1691 		device_printf(dev, "could not add cxm_iic\n");
1692 		error = ENXIO;
1693 		goto fail;
1694 	}
1695 
1696 	error = device_probe_and_attach(sc->cxm_iic);
1697 
1698 	if (error) {
1699 		device_printf(dev, "could not attach cxm_iic\n");
1700 		goto fail;
1701 	}
1702 
1703 	/*
1704 	 * Initialize the tuner.
1705 	 */
1706 	if (cxm_tuner_init(sc) < 0) {
1707 		device_printf(dev, "could not initialize tuner\n");
1708 		error = ENXIO;
1709 		goto fail;
1710 	}
1711 
1712 	/*
1713 	 * Initialize the SAA7115.
1714 	 */
1715 	if (cxm_saa7115_init(sc) < 0) {
1716 		device_printf(dev, "could not initialize video decoder\n");
1717 		error = ENXIO;
1718 		goto fail;
1719 	}
1720 
1721 	/*
1722 	 * Initialize the MSP3400.
1723 	 */
1724 	if (cxm_msp_init(sc) < 0) {
1725 		device_printf(dev, "could not initialize audio decoder\n");
1726 		error = ENXIO;
1727 		goto fail;
1728 	}
1729 
1730 	/*
1731 	 * Initialize the IR Remote.
1732 	 */
1733 	if (cxm_ir_init(sc) < 0) {
1734 		device_printf(dev, "could not initialize IR remote\n");
1735 		error = ENXIO;
1736 		goto fail;
1737 	}
1738 
1739 	sc->dec_mbx = -1;
1740 	sc->enc_mbx = -1;
1741 
1742 	/*
1743 	 * Disable the Conexant device.
1744 	 *
1745 	 * This is done * after * attaching the I2C bus so
1746 	 * cxm_stop_hardware can mute the video and audio
1747 	 * decoders.
1748 	 */
1749 	cxm_stop_hardware(sc);
1750 
1751 	/*
1752 	 * Allocate our interrupt.
1753 	 */
1754 	rid = 0;
1755 	sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
1756 				0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
1757 
1758 	if (sc->irq_res == NULL) {
1759 		device_printf(dev, "could not map interrupt\n");
1760 		error = ENXIO;
1761 		goto fail;
1762 	}
1763 
1764 	error = bus_setup_intr(dev, sc->irq_res, 0,
1765 			       cxm_intr, sc, &sc->ih_cookie, NULL);
1766 	if (error) {
1767 		device_printf(dev, "could not setup irq\n");
1768 		goto fail;
1769 
1770 	}
1771 
1772 	/*
1773 	 * Allocate a DMA tag for the parent bus.
1774 	 */
1775 	error = bus_dma_tag_create(NULL, 1, 0,
1776 				   BUS_SPACE_MAXADDR_32BIT,
1777 				   BUS_SPACE_MAXADDR, NULL, NULL,
1778 				   BUS_SPACE_MAXSIZE_32BIT, 1,
1779 				   BUS_SPACE_MAXSIZE_32BIT, 0,
1780 				   &sc->parent_dmat);
1781 	if (error) {
1782 		device_printf(dev, "could not create parent bus DMA tag\n");
1783 		goto fail;
1784 	}
1785 
1786 	/*
1787 	 * Allocate a DMA tag for the encoder buffers.
1788 	 */
1789 	error = bus_dma_tag_create(sc->parent_dmat, 256, 0,
1790 				   BUS_SPACE_MAXADDR_32BIT,
1791 				   BUS_SPACE_MAXADDR, NULL, NULL,
1792 				   CXM_SG_SEGMENT, 1,
1793 				   BUS_SPACE_MAXSIZE_32BIT, 0,
1794 				   &sc->enc_pool.dmat);
1795 	if (error) {
1796 		device_printf(dev,
1797 			      "could not create encoder buffer DMA tag\n");
1798 		goto fail;
1799 	}
1800 
1801 	for (i = 0; i < CXM_SG_BUFFERS; i++) {
1802 
1803 		/*
1804 		 * Allocate the encoder buffer.
1805 		 */
1806 		error = bus_dmamem_alloc(sc->enc_pool.dmat,
1807 					 (void **)&sc->enc_pool.bufs[i].vaddr,
1808 					 BUS_DMA_NOWAIT,
1809 					 &sc->enc_pool.bufs[i].dmamap);
1810 		if (error) {
1811 			device_printf(dev,
1812 				      "could not allocate encoder buffer\n");
1813 			goto fail;
1814 		}
1815 
1816 		/*
1817 		 * Map the encoder buffer.
1818 		 */
1819 		error = bus_dmamap_load(sc->enc_pool.dmat,
1820 					sc->enc_pool.bufs[i].dmamap,
1821 					sc->enc_pool.bufs[i].vaddr,
1822 					CXM_SG_SEGMENT,
1823 					cxm_mapmem,
1824 					&sc->enc_pool.bufs[i].baddr, 0);
1825 		if (error) {
1826 			device_printf(dev, "could not map encoder buffer\n");
1827 			goto fail;
1828 		}
1829 	}
1830 
1831 	/*
1832 	 * Allocate a DMA tag for the scatter / gather list.
1833 	 */
1834 	error = bus_dma_tag_create(sc->parent_dmat, 1, 0,
1835 				   BUS_SPACE_MAXADDR_32BIT,
1836 				   BUS_SPACE_MAXADDR, NULL, NULL,
1837 				   CXM_SG_BUFFERS
1838 				   * sizeof(struct cxm_sg_entry), 1,
1839 				   BUS_SPACE_MAXSIZE_32BIT, 0,
1840 				   &sc->enc_sg.dmat);
1841 	if (error) {
1842 		device_printf(dev,
1843 			      "could not create scatter / gather DMA tag\n");
1844 		goto fail;
1845 	}
1846 
1847 	/*
1848 	 * Allocate the scatter / gather list.
1849 	 */
1850 	error = bus_dmamem_alloc(sc->enc_sg.dmat, (void **)&sc->enc_sg.vaddr,
1851 				 BUS_DMA_NOWAIT, &sc->enc_sg.dmamap);
1852 	if (error) {
1853 		device_printf(dev,
1854 			      "could not allocate scatter / gather list\n");
1855 		goto fail;
1856 	}
1857 
1858 	/*
1859 	 * Map the scatter / gather list.
1860 	 */
1861 	error = bus_dmamap_load(sc->enc_sg.dmat, sc->enc_sg.dmamap,
1862 				sc->enc_sg.vaddr,
1863 				CXM_SG_BUFFERS * sizeof(struct cxm_sg_entry),
1864 				cxm_mapmem, &sc->enc_sg.baddr, 0);
1865 	if (error) {
1866 		device_printf(dev, "could not map scatter / gather list\n");
1867 		goto fail;
1868 	}
1869 
1870 	/*
1871 	 * Initialize the hardware.
1872 	 */
1873 	if (cxm_init_hardware(sc) < 0) {
1874 		device_printf(dev, "could not initialize hardware\n");
1875 		error = ENXIO;
1876 		goto fail;
1877 	}
1878 
1879 	sc->profile = &dvd_full_d1_ntsc_profile;
1880 
1881 	sc->source = cxm_tuner_source;
1882 
1883 
1884 	/* make the device entries */
1885 	dev_ops_add(&cxm_ops, -1, unit);
1886 	sc->cxm_dev_t = make_dev(&cxm_ops, unit,
1887 				0, 0, 0444, "cxm%d",  unit);
1888 
1889 	return 0;
1890 
1891 fail:
1892 	if (sc->enc_sg.baddr)
1893 		bus_dmamap_unload(sc->enc_sg.dmat, sc->enc_sg.dmamap);
1894 	if (sc->enc_sg.vaddr)
1895 		bus_dmamem_free(sc->enc_sg.dmat, sc->enc_sg.vaddr,
1896 				sc->enc_sg.dmamap);
1897 	if (sc->enc_sg.dmat)
1898 		bus_dma_tag_destroy(sc->enc_sg.dmat);
1899 
1900 	for (i = 0; i < CXM_SG_BUFFERS; i++) {
1901 		if (sc->enc_pool.bufs[i].baddr)
1902 			bus_dmamap_unload(sc->enc_pool.dmat,
1903 					  sc->enc_pool.bufs[i].dmamap);
1904 		if (sc->enc_pool.bufs[i].vaddr)
1905 			bus_dmamem_free(sc->enc_pool.dmat,
1906 					sc->enc_pool.bufs[i].vaddr,
1907 					sc->enc_pool.bufs[i].dmamap);
1908 	}
1909 
1910 	if (sc->enc_pool.dmat)
1911 		bus_dma_tag_destroy(sc->enc_pool.dmat);
1912 
1913 	if (sc->parent_dmat)
1914 		bus_dma_tag_destroy(sc->parent_dmat);
1915 
1916 	/*
1917 	 * Detach the I2C bus.
1918 	 *
1919 	 * This is done * after * deallocating the scatter / gather
1920 	 * list and buffers so the kernel has a better chance of
1921 	 * gracefully handling a memory shortage.
1922 	 *
1923 	 * Detach the children before recursively deleting
1924 	 * in case a child has a pointer to a grandchild
1925 	 * which is used by the child's detach routine.
1926 	 */
1927 	bus_generic_detach(dev);
1928 	if (sc->cxm_iic)
1929 		device_delete_child(dev, sc->cxm_iic);
1930 
1931 	if (sc->ih_cookie)
1932 		bus_teardown_intr(dev, sc->irq_res, sc->ih_cookie);
1933 	if (sc->irq_res)
1934 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
1935 	if (sc->mem_res)
1936 		bus_release_resource(dev, SYS_RES_MEMORY, CXM_RID, sc->mem_res);
1937 
1938 	return error;
1939 }
1940 
1941 /*
1942  * the detach routine.
1943  */
1944 static int
1945 cxm_detach(device_t dev)
1946 {
1947 	unsigned int i;
1948 	struct cxm_softc *sc;
1949 	device_t child;
1950 
1951 	/* Get the device data */
1952 	sc = device_get_softc(dev);
1953 
1954 	/* Disable the Conexant device. */
1955 	cxm_stop_hardware(sc);
1956 
1957 	/* Unregister the /dev/cxmN device. */
1958 	dev_ops_remove(&cxm_ops, 0, device_get_unit(dev));
1959 
1960 	/*
1961 	 * Deallocate scatter / gather list and buffers.
1962 	 */
1963 	bus_dmamap_unload(sc->enc_sg.dmat, sc->enc_sg.dmamap);
1964 	bus_dmamem_free(sc->enc_sg.dmat, sc->enc_sg.vaddr, sc->enc_sg.dmamap);
1965 
1966 	bus_dma_tag_destroy(sc->enc_sg.dmat);
1967 
1968 	for (i = 0; i < CXM_SG_BUFFERS; i++) {
1969 		bus_dmamap_unload(sc->enc_pool.dmat,
1970 				  sc->enc_pool.bufs[i].dmamap);
1971 		bus_dmamem_free(sc->enc_pool.dmat, sc->enc_pool.bufs[i].vaddr,
1972 				sc->enc_pool.bufs[i].dmamap);
1973 	}
1974 
1975 	bus_dma_tag_destroy(sc->enc_pool.dmat);
1976 
1977 	bus_dma_tag_destroy(sc->parent_dmat);
1978 
1979 	/*
1980 	 * Detach the I2C bus.
1981 	 *
1982 	 * This is done * after * deallocating the scatter / gather
1983 	 * list and buffers so the kernel has a better chance of
1984 	 * gracefully handling a memory shortage.
1985 	 *
1986 	 * Detach the children before recursively deleting
1987 	 * in case a child has a pointer to a grandchild
1988 	 * which is used by the child's detach routine.
1989 	 *
1990 	 * Remember the child before detaching so we can
1991 	 * delete it (bus_generic_detach indirectly zeroes
1992 	 * sc->child_dev).
1993 	 */
1994 	child = sc->cxm_iic;
1995 	bus_generic_detach(dev);
1996 	if (child)
1997 		device_delete_child(dev, child);
1998 
1999 	/* Deallocate resources. */
2000 	bus_teardown_intr(dev, sc->irq_res, sc->ih_cookie);
2001 	bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
2002 	bus_release_resource(dev, SYS_RES_MEMORY, CXM_RID, sc->mem_res);
2003 
2004 	return 0;
2005 }
2006 
2007 /*
2008  * the shutdown routine.
2009  */
2010 static int
2011 cxm_shutdown(device_t dev)
2012 {
2013 	struct cxm_softc *sc = device_get_softc(dev);
2014 
2015 	/* Disable the Conexant device. */
2016 	cxm_stop_hardware(sc);
2017 
2018 	return 0;
2019 }
2020 
2021 /*
2022  * the interrupt routine.
2023  */
2024 static void
2025 cxm_intr(void *arg)
2026 {
2027 	uint32_t status;
2028 	struct cxm_softc *sc;
2029 
2030 	/* Get the device data */
2031 	sc = (struct cxm_softc *)arg;
2032 
2033 	status = CSR_READ_4(sc, CXM_REG_IRQ_STATUS);
2034 
2035 	status &= ~sc->irq_mask;
2036 
2037 	if (!status)
2038 		return;
2039 
2040 	/* Process DMA done before handling a new DMA request or EOS */
2041 	if (status & CXM_IRQ_ENC_DMA_DONE)
2042 		cxm_encoder_dma_done(sc);
2043 
2044 	if (status & CXM_IRQ_ENC_DMA_REQUEST)
2045 		cxm_encoder_dma_request(sc);
2046 
2047 	if (status & CXM_IRQ_ENC_EOS) {
2048 		sc->encoding_eos = 1;
2049 		wakeup(&sc->encoding_eos);
2050 	}
2051 
2052 	cxm_set_irq_status(sc, status);
2053 }
2054 
2055 
2056 /*
2057  * the child detached routine.
2058  */
2059 static void
2060 cxm_child_detached(device_t dev, device_t child)
2061 {
2062 	struct cxm_softc *sc;
2063 
2064 	/* Get the device data */
2065 	sc = device_get_softc(dev);
2066 
2067 	if (child == sc->cxm_iic)
2068 		sc->cxm_iic = NULL;
2069 }
2070 
2071 
2072 static int
2073 cxm_read_ivar(device_t dev, device_t child, int index, uintptr_t* val)
2074 {
2075 	struct cxm_softc *sc;
2076 
2077 	/* Get the device data */
2078 	sc = device_get_softc(dev);
2079 
2080 	switch (index) {
2081 	case CXM_IVAR_BHANDLE:
2082 		*(bus_space_handle_t **)val = &sc->bhandle;
2083 		break;
2084 
2085 	case CXM_IVAR_BTAG:
2086 		*(bus_space_tag_t **)val = &sc->btag;
2087 		break;
2088 
2089 	case CXM_IVAR_IICBUS:
2090 		*(device_t **)val = &sc->iicbus;
2091 		break;
2092 
2093 	default:
2094 		return ENOENT;
2095 	}
2096 
2097 	return 0;
2098 }
2099 
2100 
2101 static int
2102 cxm_write_ivar(device_t dev, device_t child, int index, uintptr_t val)
2103 {
2104 	struct cxm_softc *sc;
2105 
2106 	/* Get the device data */
2107 	sc = device_get_softc(dev);
2108 
2109 	switch (index) {
2110 	case CXM_IVAR_BHANDLE:
2111 		return EINVAL;
2112 
2113 	case CXM_IVAR_BTAG:
2114 		return EINVAL;
2115 
2116 	case CXM_IVAR_IICBUS:
2117 		if (sc->iicbus)
2118 			return EINVAL;
2119 		sc->iicbus = val ? *(device_t *)val : NULL;
2120 		break;
2121 
2122 	default:
2123 		return ENOENT;
2124 	}
2125 
2126 	return 0;
2127 }
2128 
2129 
2130 /*---------------------------------------------------------
2131 **
2132 **	Conexant iTVC15 / iTVC16 character device driver routines
2133 **
2134 **---------------------------------------------------------
2135 */
2136 
2137 #define UNIT(x)		((x) & 0x0f)
2138 #define FUNCTION(x)	(x >> 4)
2139 
2140 /*
2141  *
2142  */
2143 int
2144 cxm_open(struct dev_open_args *ap)
2145 {
2146 	cdev_t		dev = ap->a_head.a_dev;
2147 	int		unit;
2148 	struct cxm_softc *sc;
2149 
2150 	unit = UNIT(minor(dev));
2151 
2152 	/* Get the device data */
2153 	sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2154 	if (sc == NULL) {
2155 		/* the device is no longer valid/functioning */
2156 		return ENXIO;
2157 	}
2158 
2159 	if (sc->is_opened)
2160 		return EBUSY;
2161 
2162 	sc->is_opened = 1;
2163 	sc->mpeg = 1;
2164 
2165 	/* Record that the device is now busy */
2166 	device_busy(devclass_get_device(cxm_devclass, unit));
2167 
2168 	return 0;
2169 }
2170 
2171 
2172 /*
2173  *
2174  */
2175 int
2176 cxm_close(struct dev_close_args *ap)
2177 {
2178 	cdev_t		dev = ap->a_head.a_dev;
2179 	int		unit;
2180 	struct cxm_softc *sc;
2181 
2182 	unit = UNIT(minor(dev));
2183 
2184 	/* Get the device data */
2185 	sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2186 	if (sc == NULL) {
2187 		/* the device is no longer valid/functioning */
2188 		return ENXIO;
2189 	}
2190 
2191 	if (cxm_stop_encoder(sc) < 0)
2192 		return ENXIO;
2193 
2194 	sc->enc_pool.offset = 0;
2195 	sc->enc_pool.read = 0;
2196 	sc->enc_pool.write = 0;
2197 
2198 	sc->enc_proc = NULL;
2199 	sc->enc_signal = 0;
2200 
2201 	device_unbusy(devclass_get_device(cxm_devclass, unit));
2202 
2203 	sc->is_opened = 0;
2204 
2205 	return 0;
2206 }
2207 
2208 
2209 /*
2210  *
2211  */
2212 int
2213 cxm_read(struct dev_read_args *ap)
2214 {
2215 	cdev_t		dev = ap->a_head.a_dev;
2216 	int		buffers_available;
2217 	int		buffers_read;
2218 	int		error;
2219 	int		unit;
2220 	unsigned int	current;
2221 	unsigned int	i;
2222 	size_t		nbytes;
2223 	size_t		offset;
2224 	struct cxm_softc *sc;
2225 
2226 	unit = UNIT(minor(dev));
2227 
2228 	/* Get the device data */
2229 	sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2230 	if (sc == NULL) {
2231 		/* the device is no longer valid/functioning */
2232 		return ENXIO;
2233 	}
2234 
2235 	/* Only trigger the encoder if the ring buffer is empty */
2236 	if (!sc->encoding && sc->enc_pool.read == sc->enc_pool.write) {
2237 		if (cxm_start_encoder(sc) < 0)
2238 			return ENXIO;
2239 		if (ap->a_ioflag & IO_NDELAY)
2240 			return EWOULDBLOCK;
2241 	}
2242 
2243 	buffers_available = 0;
2244 
2245 	crit_enter();
2246 	while (sc->enc_pool.read == sc->enc_pool.write) {
2247 		error = tsleep(&sc->enc_pool.read, PCATCH, "cxmrd", 0);
2248 		if (error) {
2249 			crit_exit();
2250 			return error;
2251 		}
2252 	}
2253 
2254 	/*
2255 	 * Determine the number of buffers available at this * instant *
2256 	 * taking in consideration that the ring buffer wraps.
2257 	 */
2258 	buffers_available = sc->enc_pool.write - sc->enc_pool.read;
2259 	if (buffers_available < 0)
2260 		buffers_available += CXM_SG_BUFFERS;
2261 	crit_exit();
2262 
2263 	offset = sc->enc_pool.offset;
2264 
2265 	for (buffers_read = 0, i = sc->enc_pool.read;
2266 	     buffers_read != buffers_available && ap->a_uio->uio_resid;
2267 	     buffers_read++, i = (i + 1) % CXM_SG_BUFFERS) {
2268 
2269 		current = cxm_encoder_fixup_byte_order (sc, i, offset);
2270 
2271 		nbytes = sc->enc_pool.bufs[current].size - offset;
2272 
2273 		/* Don't transfer more than requested */
2274 		if (nbytes > ap->a_uio->uio_resid)
2275 			nbytes = ap->a_uio->uio_resid;
2276 
2277 		error = uiomove(sc->enc_pool.bufs[current].vaddr + offset,
2278 				nbytes, ap->a_uio);
2279 		if (error)
2280 			return error;
2281 
2282 		offset += nbytes;
2283 
2284 		/* Handle a partial read of a buffer */
2285 		if (!ap->a_uio->uio_resid && offset != sc->enc_pool.bufs[i].size)
2286 			break;
2287 
2288 		offset = 0;
2289 	}
2290 
2291 	sc->enc_pool.offset = offset;
2292 
2293 	/* Update the books */
2294 	crit_enter();
2295 	sc->enc_pool.read = (sc->enc_pool.read + buffers_read)
2296 			    % CXM_SG_BUFFERS;
2297 	crit_exit();
2298 
2299 	return 0;
2300 }
2301 
2302 
2303 /*
2304  *
2305  */
2306 int
2307 cxm_ioctl(struct dev_ioctl_args *ap)
2308 {
2309 	cdev_t		dev = ap->a_head.a_dev;
2310 	int		brightness;
2311 	int		chroma_saturation;
2312 	int		contrast;
2313 	int		fps;
2314 	int		hue;
2315 	int		result;
2316 	int		status;
2317 	int		unit;
2318 	unsigned int	i;
2319 	unsigned int	sig;
2320 	unsigned long	freq;
2321 	struct cxm_softc *sc;
2322 	enum cxm_source	source;
2323 	struct bktr_capture_area *cap;
2324 	struct bktr_remote *remote;
2325 
2326 	unit = UNIT(minor(dev));
2327 
2328 	/* Get the device data */
2329 	sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2330 	if (sc == NULL) {
2331 		/* the device is no longer valid/functioning */
2332 		return ENXIO;
2333 	}
2334 
2335 	switch (ap->a_cmd) {
2336 	case BT848_GAUDIO:
2337 		switch (cxm_msp_selected_source(sc)) {
2338 		case cxm_tuner_source:
2339 			*(int *) ap->a_data = AUDIO_TUNER;
2340 			break;
2341 
2342 		case cxm_line_in_source_composite:
2343 		case cxm_line_in_source_svideo:
2344 			*(int *) ap->a_data = AUDIO_EXTERN;
2345 			break;
2346 
2347 		case cxm_fm_source:
2348 			*(int *) ap->a_data = AUDIO_INTERN;
2349 			break;
2350 
2351 		default:
2352 			return ENXIO;
2353 		}
2354 
2355 		if (cxm_msp_is_muted(sc) == 1)
2356 			*(int *) ap->a_data |= AUDIO_MUTE;
2357 		break;
2358 
2359 	case BT848_SAUDIO:
2360 		source = cxm_unknown_source;
2361 
2362 		switch (*(int *) ap->a_data) {
2363 		case AUDIO_TUNER:
2364 			source = cxm_tuner_source;
2365 			break;
2366 
2367 		case AUDIO_EXTERN:
2368 			source = cxm_line_in_source_composite;
2369 			break;
2370 
2371 		case AUDIO_INTERN:
2372 			source = cxm_fm_source;
2373 			break;
2374 
2375 		case AUDIO_MUTE:
2376 			if (cxm_msp_mute(sc) < 0)
2377 				return ENXIO;
2378 			return 0;
2379 
2380 		case AUDIO_UNMUTE:
2381 			if (cxm_msp_unmute(sc) < 0)
2382 				return ENXIO;
2383 			return 0;
2384 
2385 		default:
2386 			return EINVAL;
2387 		}
2388 
2389 		if (sc->encoding) {
2390 
2391 			/*
2392 			 * Switching between audio + video and audio only
2393 			 * subtypes isn't supported while encoding.
2394 			 */
2395 
2396 			if (source != sc->source
2397 			    && (source == cxm_fm_source
2398 				|| sc->source == cxm_fm_source))
2399 				return EBUSY;
2400 		}
2401 
2402 		if (cxm_pause_encoder(sc) < 0)
2403 			return ENXIO;
2404 
2405 		if (cxm_msp_select_source(sc, source) < 0)
2406 			return ENXIO;
2407 
2408 		if (source == cxm_fm_source)
2409 			sc->source = source;
2410 
2411 		result = cxm_encoder_wait_for_lock(sc);
2412 		if (result < 0)
2413 			return ENXIO;
2414 		else if (result == 0)
2415 			return EINVAL;
2416 
2417 		if (cxm_unpause_encoder(sc) < 0)
2418 			return ENXIO;
2419 		break;
2420 
2421 	case BT848_GBRIG:
2422 		brightness = cxm_saa7115_get_brightness(sc);
2423 
2424 		if (brightness < 0)
2425 			return ENXIO;
2426 
2427 		/*
2428 		 * Brooktree brightness:
2429 		 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6%
2430 		 */
2431 		*(int *)ap->a_data = (int)(unsigned char)brightness - 128;
2432 		break;
2433 
2434 	case BT848_SBRIG:
2435 
2436 		/*
2437 		 * Brooktree brightness:
2438 		 * 0x80 = -50.0%, 0x00 = +0.0%, 0x7f = +49.6%
2439 		 */
2440 		brightness = *(int *)ap->a_data + 128;
2441 
2442 		if (cxm_saa7115_set_brightness(sc, brightness) < 0)
2443 			return ENXIO;
2444 		break;
2445 
2446 	case METEORGBRIG:
2447 		brightness = cxm_saa7115_get_brightness(sc);
2448 
2449 		if (brightness < 0)
2450 			return ENXIO;
2451 
2452 		*(unsigned char *)ap->a_data = (unsigned char)brightness;
2453 		break;
2454 
2455 	case METEORSBRIG:
2456 		brightness = *(unsigned char *)ap->a_data;
2457 
2458 		if (cxm_saa7115_set_brightness(sc, brightness) < 0)
2459 			return ENXIO;
2460 		break;
2461 
2462 	case BT848_GCSAT:
2463 		chroma_saturation = cxm_saa7115_get_chroma_saturation(sc);
2464 
2465 		if (chroma_saturation < 0)
2466 			return ENXIO;
2467 
2468 		/*
2469 		 * Brooktree chroma saturation:
2470 		 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18%
2471 		 */
2472 		*(int *)ap->a_data = ((signed char)chroma_saturation > 0)
2473 				? (chroma_saturation * 4 - 2) : 0;
2474 		break;
2475 
2476 	case BT848_SCSAT:
2477 
2478 		/*
2479 		 * Brooktree chroma saturation:
2480 		 * 0x000 = 0%, 0x0fe = 100%, 0x1ff = 201.18%
2481 		 */
2482 		chroma_saturation = (*(int *)ap->a_data & 0x1ff) < 510
2483 				      ? ((*(int *)ap->a_data & 0x1ff) + 2) / 4 : 127;
2484 
2485 		if (cxm_saa7115_set_chroma_saturation(sc, chroma_saturation)
2486 		    < 0)
2487 			return ENXIO;
2488 
2489 		break;
2490 
2491 	case METEORGCSAT:
2492 		chroma_saturation = cxm_saa7115_get_chroma_saturation(sc);
2493 
2494 		if (chroma_saturation < 0)
2495 			return ENXIO;
2496 
2497 		*(unsigned char *)ap->a_data = (unsigned char)chroma_saturation;
2498 		break;
2499 
2500 	case METEORSCSAT:
2501 		chroma_saturation = *(unsigned char *)ap->a_data;
2502 
2503 		if (cxm_saa7115_set_chroma_saturation(sc, chroma_saturation)
2504 		    < 0)
2505 			return ENXIO;
2506 		break;
2507 
2508 	case METEORGCONT:
2509 		contrast = cxm_saa7115_get_contrast(sc);
2510 
2511 		if (contrast < 0)
2512 			return ENXIO;
2513 
2514 		*(unsigned char *)ap->a_data = (unsigned char)contrast;
2515 		break;
2516 
2517 	case METEORSCONT:
2518 		contrast = *(unsigned char *)ap->a_data;
2519 
2520 		if (cxm_saa7115_set_contrast(sc, contrast) < 0)
2521 			return ENXIO;
2522 		break;
2523 
2524 	case BT848_GHUE:
2525 		hue = cxm_saa7115_get_hue(sc);
2526 
2527 		if (hue < 0)
2528 			return ENXIO;
2529 
2530 		*(int *)ap->a_data = (signed char)hue;
2531 		break;
2532 
2533 	case BT848_SHUE:
2534 		hue = *(int *)ap->a_data;
2535 
2536 		if (cxm_saa7115_set_hue(sc, hue) < 0)
2537 			return ENXIO;
2538 		break;
2539 
2540 	case METEORGHUE:
2541 		hue = cxm_saa7115_get_hue(sc);
2542 
2543 		if (hue < 0)
2544 			return ENXIO;
2545 
2546 		*(signed char *)ap->a_data = (signed char)hue;
2547 		break;
2548 
2549 	case METEORSHUE:
2550 		hue = *(signed char *)ap->a_data;
2551 
2552 		if (cxm_saa7115_set_hue(sc, hue) < 0)
2553 			return ENXIO;
2554 		break;
2555 
2556 	case METEORCAPTUR:
2557 		switch (*(int *) ap->a_data) {
2558 		case METEOR_CAP_CONTINOUS:
2559 			if (cxm_start_encoder(sc) < 0)
2560 				return ENXIO;
2561 			break;
2562 
2563 		case METEOR_CAP_STOP_CONT:
2564 			if (cxm_stop_encoder(sc) < 0)
2565 				return ENXIO;
2566 			break;
2567 
2568 		default:
2569 			return EINVAL;
2570 		}
2571 		break;
2572 
2573 	case BT848_GCAPAREA:
2574 		cap = (struct bktr_capture_area *)ap->a_data;
2575 		memset (cap, 0, sizeof (*cap));
2576 		cap->x_offset = 0;
2577 		cap->y_offset = 0;
2578 		cap->x_size = sc->profile->width;
2579 		cap->y_size = sc->profile->height;
2580 		break;
2581 
2582 	case BT848_SCAPAREA:
2583 		if (sc->encoding)
2584 			return EBUSY;
2585 
2586 		cap = (struct bktr_capture_area *)ap->a_data;
2587 		if (cap->x_offset || cap->y_offset
2588 		    || (cap->x_size % CXM_MACROBLOCK_WIDTH)
2589 		    || (cap->y_size % CXM_MACROBLOCK_HEIGHT))
2590 			return EINVAL;
2591 
2592 		/*
2593 		 * Setting the width and height has the side effect of
2594 		 * chosing between the VCD, SVCD, and DVD profiles.
2595 		 */
2596 
2597 		for (i = 0; i < NUM_ELEMENTS(codec_profiles); i++)
2598 			if (codec_profiles[i]->width == cap->x_size
2599 			    && codec_profiles[i]->height == cap->y_size)
2600 				break;
2601 
2602 		if (i >= NUM_ELEMENTS(codec_profiles))
2603 			return EINVAL;
2604 
2605 		sc->profile = codec_profiles[i];
2606 		break;
2607 
2608 	case BT848GFMT:
2609 		switch (cxm_saa7115_detected_format(sc)) {
2610 		case cxm_ntsc_60hz_source_format:
2611 			*(unsigned long *)ap->a_data = BT848_IFORM_F_NTSCM;
2612 			break;
2613 
2614 		case cxm_pal_50hz_source_format:
2615 			*(unsigned long *)ap->a_data = BT848_IFORM_F_PALBDGHI;
2616 			break;
2617 
2618 		case cxm_secam_50hz_source_format:
2619 			*(unsigned long *)ap->a_data = BT848_IFORM_F_SECAM;
2620 			break;
2621 
2622 		case cxm_pal_60hz_source_format:
2623 			*(unsigned long *)ap->a_data = BT848_IFORM_F_PALM;
2624 			break;
2625 
2626 		case cxm_bw_50hz_source_format:
2627 		case cxm_bw_60hz_source_format:
2628 		case cxm_ntsc_50hz_source_format:
2629 			*(unsigned long *)ap->a_data = BT848_IFORM_F_AUTO;
2630 			break;
2631 
2632 		default:
2633 			return ENXIO;
2634 		}
2635 		break;
2636 
2637 	case METEORGFMT:
2638 		switch (cxm_saa7115_detected_format(sc)) {
2639 		case cxm_ntsc_60hz_source_format:
2640 			*(unsigned long *)ap->a_data = METEOR_FMT_NTSC;
2641 			break;
2642 
2643 		case cxm_pal_50hz_source_format:
2644 			*(unsigned long *)ap->a_data = METEOR_FMT_PAL;
2645 			break;
2646 
2647 		case cxm_secam_50hz_source_format:
2648 			*(unsigned long *)ap->a_data = METEOR_FMT_SECAM;
2649 			break;
2650 
2651 		case cxm_bw_50hz_source_format:
2652 		case cxm_bw_60hz_source_format:
2653 		case cxm_ntsc_50hz_source_format:
2654 		case cxm_pal_60hz_source_format:
2655 			*(unsigned long *)ap->a_data = METEOR_FMT_AUTOMODE;
2656 			break;
2657 
2658 		default:
2659 			return ENXIO;
2660 		}
2661 		break;
2662 
2663 	case METEORGFPS:
2664 		fps = cxm_saa7115_detected_fps(sc);
2665 
2666 		if (fps < 0)
2667 			return ENXIO;
2668 
2669 		*(unsigned short *)ap->a_data = fps;
2670 		break;
2671 
2672 	case METEORGINPUT:
2673 		switch (sc->source) {
2674 		case cxm_tuner_source:
2675 			*(unsigned long *)ap->a_data = METEOR_INPUT_DEV1;
2676 			break;
2677 
2678 		case cxm_line_in_source_composite:
2679 			*(unsigned long *)ap->a_data = METEOR_INPUT_DEV2;
2680 			break;
2681 
2682 		case cxm_line_in_source_svideo:
2683 			*(unsigned long *)ap->a_data = METEOR_INPUT_DEV_SVIDEO;
2684 			break;
2685 
2686 		default:
2687 			return ENXIO;
2688 		}
2689 		break;
2690 
2691 	case METEORSINPUT:
2692 		source = cxm_unknown_source;
2693 
2694 		switch (*(unsigned long *)ap->a_data & 0xf000) {
2695 		case METEOR_INPUT_DEV1:
2696 			source = cxm_tuner_source;
2697 			break;
2698 
2699 		case METEOR_INPUT_DEV2:
2700 			source = cxm_line_in_source_composite;
2701 			break;
2702 
2703 		case METEOR_INPUT_DEV_SVIDEO:
2704 			source = cxm_line_in_source_svideo;
2705 			break;
2706 
2707 		default:
2708 			 return EINVAL;
2709 		}
2710 
2711 		if (sc->encoding) {
2712 
2713 			/*
2714 			 * Switching between audio + video and audio only
2715 			 * subtypes isn't supported while encoding.
2716 			 */
2717 
2718 			if (source != sc->source
2719 			    && (source == cxm_fm_source
2720 				|| sc->source == cxm_fm_source))
2721 				return EBUSY;
2722 		}
2723 
2724 		if (cxm_pause_encoder(sc) < 0)
2725 			return ENXIO;
2726 
2727 		if (cxm_saa7115_select_source(sc, source) < 0)
2728 			return ENXIO;
2729 		if (cxm_msp_select_source(sc, source) < 0)
2730 			return ENXIO;
2731 		sc->source = source;
2732 
2733 		result = cxm_encoder_wait_for_lock(sc);
2734 		if (result < 0)
2735 			return ENXIO;
2736 		else if (result == 0)
2737 			return EINVAL;
2738 
2739 		if (cxm_unpause_encoder(sc) < 0)
2740 			return ENXIO;
2741 		break;
2742 
2743 	case METEORGSIGNAL:
2744 		*(unsigned int *)ap->a_data = sc->enc_signal;
2745 		break;
2746 
2747 	case METEORSSIGNAL:
2748 		sig = *(unsigned int *)ap->a_data;
2749 
2750 		if (!_SIG_VALID(sig))
2751 			return EINVAL;
2752 
2753 		/*
2754 		 * Historically, applications used METEOR_SIG_MODE_MASK
2755 		 * to reset signal delivery.
2756 		 */
2757 		if (sig == METEOR_SIG_MODE_MASK)
2758 			sig = 0;
2759 
2760 		crit_enter();
2761 		sc->enc_proc = sig ? curproc : NULL;
2762 		sc->enc_signal = sig;
2763 		crit_exit();
2764 		break;
2765 
2766 	case RADIO_GETFREQ:
2767 		/* Convert from kHz to MHz * 100 */
2768 		freq = sc->tuner_freq / 10;
2769 
2770 		*(unsigned int *)ap->a_data = freq;
2771 		break;
2772 
2773 	case RADIO_SETFREQ:
2774 		if (sc->source == cxm_fm_source)
2775 			if (cxm_pause_encoder(sc) < 0)
2776 				return ENXIO;
2777 
2778 		/* Convert from MHz * 100 to kHz */
2779 		freq = *(unsigned int *)ap->a_data * 10;
2780 
2781 		if (cxm_tuner_select_frequency(sc, cxm_tuner_fm_freq_type,
2782 					       freq) < 0)
2783 			return ENXIO;
2784 
2785 		/*
2786 		 * Explicitly wait for the tuner lock so we
2787 		 * can indicate if there's a station present.
2788 		 */
2789 		if (cxm_tuner_wait_for_lock(sc) < 0)
2790 			return EINVAL;
2791 
2792 		result = cxm_encoder_wait_for_lock(sc);
2793 		if (result < 0)
2794 			return ENXIO;
2795 		else if (result == 0)
2796 			return EINVAL;
2797 
2798 		if (sc->source == cxm_fm_source)
2799 			if (cxm_unpause_encoder(sc) < 0)
2800 				return ENXIO;
2801 		break;
2802 
2803 	case TVTUNER_GETAFC:
2804 		*(int *)ap->a_data = sc->tuner_afc;
2805 		break;
2806 
2807 	case TVTUNER_SETAFC:
2808 		sc->tuner_afc = (*(int *)ap->a_data != 0);
2809 		break;
2810 
2811 	case TVTUNER_GETTYPE:
2812 		*(unsigned int *)ap->a_data = cxm_tuner_selected_channel_set(sc);
2813 		break;
2814 
2815 	case TVTUNER_SETTYPE:
2816 		if (cxm_tuner_select_channel_set(sc, *(unsigned int *)ap->a_data) < 0)
2817 			return EINVAL;
2818 		break;
2819 
2820 	case TVTUNER_SETCHNL:
2821 		if (sc->source == cxm_tuner_source)
2822 			if (cxm_pause_encoder(sc) < 0)
2823 				return ENXIO;
2824 
2825 		if (cxm_tuner_select_channel(sc, *(unsigned int *)ap->a_data) < 0)
2826 			return ENXIO;
2827 
2828 		if (sc->tuner_afc)
2829 			if (cxm_tuner_apply_afc(sc) < 0)
2830 				return EINVAL;
2831 
2832 		/*
2833 		 * Explicitly wait for the tuner lock so we
2834 		 * can indicate if there's a station present.
2835 		 */
2836 		if (cxm_tuner_wait_for_lock(sc) < 0)
2837 			return EINVAL;
2838 
2839 		result = cxm_encoder_wait_for_lock(sc);
2840 		if (result < 0)
2841 			return ENXIO;
2842 		else if (result == 0)
2843 			return EINVAL;
2844 
2845 		if (sc->source == cxm_tuner_source)
2846 			if (cxm_unpause_encoder(sc) < 0)
2847 				return ENXIO;
2848 		break;
2849 
2850 	case TVTUNER_GETFREQ:
2851 		/* Convert from kHz to MHz * 16 */
2852 		freq = (sc->tuner_freq * 16) / 1000;
2853 
2854 		*(unsigned int *)ap->a_data = freq;
2855 		break;
2856 
2857 	case TVTUNER_SETFREQ:
2858 		if (sc->source == cxm_tuner_source)
2859 			if (cxm_pause_encoder(sc) < 0)
2860 				return ENXIO;
2861 
2862 		/* Convert from MHz * 16 to kHz */
2863 		freq = (*(unsigned int *)ap->a_data * 1000) / 16;
2864 
2865 		if (cxm_tuner_select_frequency(sc, cxm_tuner_tv_freq_type,
2866 					       freq) < 0)
2867 			return ENXIO;
2868 
2869 		/*
2870 		 * Explicitly wait for the tuner lock so we
2871 		 * can indicate if there's a station present.
2872 		 */
2873 		if (cxm_tuner_wait_for_lock(sc) < 0)
2874 			return EINVAL;
2875 
2876 		result = cxm_encoder_wait_for_lock(sc);
2877 		if (result < 0)
2878 			return ENXIO;
2879 		else if (result == 0)
2880 			return EINVAL;
2881 
2882 		if (sc->source == cxm_tuner_source)
2883 			if (cxm_unpause_encoder(sc) < 0)
2884 				return ENXIO;
2885 
2886 		break;
2887 
2888 	case TVTUNER_GETSTATUS:
2889 		status = cxm_tuner_status(sc);
2890 		if (status < 0)
2891 			return ENXIO;
2892 		*(unsigned long *)ap->a_data = status & 0xff;
2893 		break;
2894 
2895 	case REMOTE_GETKEY:
2896 		remote = (struct bktr_remote *)ap->a_data;
2897 		if (cxm_ir_key(sc, (char *)remote, sizeof(*remote)) < 0)
2898 			return ENXIO;
2899 		break;
2900 
2901 	default:
2902 		return ENOTTY;
2903 	}
2904 
2905 	return 0;
2906 }
2907 
2908 
2909 int
2910 cxm_poll(struct dev_poll_args *ap)
2911 {
2912 	cdev_t		dev = ap->a_head.a_dev;
2913 	int		revents;
2914 	int		unit;
2915 	struct cxm_softc *sc;
2916 
2917 	unit = UNIT(minor(dev));
2918 
2919 	/* Get the device data */
2920 	sc = (struct cxm_softc*)devclass_get_softc(cxm_devclass, unit);
2921 	if (sc == NULL) {
2922 		/* the device is no longer valid/functioning */
2923 		return POLLHUP;
2924 	}
2925 
2926 	revents = 0;
2927 
2928 	crit_enter();
2929 	if (ap->a_events & (POLLIN | POLLRDNORM)) {
2930 		if (sc->enc_pool.read == sc->enc_pool.write)
2931 			selrecord(curthread, &sc->enc_sel);
2932 		else
2933 			revents = ap->a_events & (POLLIN | POLLRDNORM);
2934 	}
2935 	crit_exit();
2936 
2937 	return revents;
2938 }
2939