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