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