[BACK]Return to bktr_core.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pci / bktr

Annotation of src/sys/dev/pci/bktr/bktr_core.c, Revision 1.46.2.1

1.28      wiz         1: /* $SourceForge: bktr_core.c,v 1.6 2003/03/11 23:11:22 thomasklausner Exp $ */
1.1       wiz         2:
1.46.2.1! keiichi     3: /*     $NetBSD: bktr_core.c,v 1.47 2008/03/01 14:16:50 rmind Exp $     */
1.28      wiz         4: /* $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.114 2000/10/31 13:09:56 roger Exp$ */
1.1       wiz         5:
                      6: /*
                      7:  * This is part of the Driver for Video Capture Cards (Frame grabbers)
                      8:  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
                      9:  * chipset.
                     10:  * Copyright Roger Hardiman and Amancio Hasty.
                     11:  *
                     12:  * bktr_core : This deals with the Bt848/849/878/879 PCI Frame Grabber,
                     13:  *               Handles all the open, close, ioctl and read userland calls.
                     14:  *               Sets the Bt848 registers and generates RISC pograms.
                     15:  *               Controls the i2c bus and GPIO interface.
                     16:  *               Contains the interface to the kernel.
                     17:  *               (eg probe/attach and open/close/ioctl)
                     18:  *
                     19:  */
                     20:
                     21:  /*
                     22:    The Brooktree BT848 Driver driver is based upon Mark Tinguely and
1.28      wiz        23:    Jim Lowe's driver for the Matrox Meteor PCI card . The
1.1       wiz        24:    Philips SAA 7116 and SAA 7196 are very different chipsets than
                     25:    the BT848.
                     26:
                     27:    The original copyright notice by Mark and Jim is included mostly
                     28:    to honor their fantastic work in the Matrox Meteor driver!
                     29:
                     30:  */
                     31:
                     32: /*
1.28      wiz        33:  * 1. Redistributions of source code must retain the
1.1       wiz        34:  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
                     35:  * All rights reserved.
                     36:  *
                     37:  * Redistribution and use in source and binary forms, with or without
                     38:  * modification, are permitted provided that the following conditions
                     39:  * are met:
                     40:  * 1. Redistributions of source code must retain the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer.
                     42:  * 2. Redistributions in binary form must reproduce the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer in the
                     44:  *    documentation and/or other materials provided with the distribution.
                     45:  * 3. All advertising materials mentioning features or use of this software
                     46:  *    must display the following acknowledgement:
                     47:  *     This product includes software developed by Amancio Hasty and
                     48:  *      Roger Hardiman
1.28      wiz        49:  * 4. The name of the author may not be used to endorse or promote products
1.1       wiz        50:  *    derived from this software without specific prior written permission.
                     51:  *
                     52:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     53:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     54:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     55:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     56:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     57:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     58:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     59:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     60:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     61:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     62:  * POSSIBILITY OF SUCH DAMAGE.
                     63:  */
                     64:
                     65:
                     66:
                     67:
                     68: /*
1.28      wiz        69:  * 1. Redistributions of source code must retain the
1.1       wiz        70:  * Copyright (c) 1995 Mark Tinguely and Jim Lowe
                     71:  * All rights reserved.
                     72:  *
                     73:  * Redistribution and use in source and binary forms, with or without
                     74:  * modification, are permitted provided that the following conditions
                     75:  * are met:
                     76:  * 1. Redistributions of source code must retain the above copyright
                     77:  *    notice, this list of conditions and the following disclaimer.
                     78:  * 2. Redistributions in binary form must reproduce the above copyright
                     79:  *    notice, this list of conditions and the following disclaimer in the
                     80:  *    documentation and/or other materials provided with the distribution.
                     81:  * 3. All advertising materials mentioning features or use of this software
                     82:  *    must display the following acknowledgement:
                     83:  *     This product includes software developed by Mark Tinguely and Jim Lowe
1.28      wiz        84:  * 4. The name of the author may not be used to endorse or promote products
1.1       wiz        85:  *    derived from this software without specific prior written permission.
                     86:  *
                     87:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     88:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     89:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     90:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     91:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     92:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     93:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     94:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     95:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     96:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     97:  * POSSIBILITY OF SUCH DAMAGE.
                     98:  */
1.20      lukem      99:
                    100: #include <sys/cdefs.h>
1.46.2.1! keiichi   101: __KERNEL_RCSID(0, "$NetBSD: bktr_core.c,v 1.47 2008/03/01 14:16:50 rmind Exp $");
1.1       wiz       102:
                    103: #include "opt_bktr.h"          /* Include any kernel config options */
                    104:
1.8       wiz       105:
                    106: /*******************/
                    107: /* *** FreeBSD *** */
                    108: /*******************/
                    109: #ifdef __FreeBSD__
                    110:
1.1       wiz       111: #include <sys/param.h>
                    112: #include <sys/systm.h>
                    113: #include <sys/kernel.h>
1.28      wiz       114: #include <sys/mutex.h>
                    115: #include <sys/proc.h>
1.1       wiz       116: #include <sys/signalvar.h>
                    117: #include <sys/vnode.h>
                    118:
1.7       veego     119: #include <vm/vm.h>
1.1       wiz       120: #include <vm/vm_kern.h>
                    121: #include <vm/pmap.h>
                    122: #include <vm/vm_extern.h>
                    123:
                    124: #if (__FreeBSD_version >=400000) || (NSMBUS > 0)
                    125: #include <sys/bus.h>           /* used by smbus and newbus */
                    126: #endif
                    127:
1.12      wiz       128: #if (__FreeBSD_version < 500000)
                    129: #include <machine/clock.h>              /* for DELAY */
1.28      wiz       130: #define                PROC_LOCK(p)
                    131: #define                PROC_UNLOCK(p)
1.12      wiz       132: #endif
                    133:
1.1       wiz       134: #include <pci/pcivar.h>
                    135:
                    136: #if (__FreeBSD_version >=300000)
                    137: #include <machine/bus_memio.h> /* for bus space */
1.44      ad        138: #include <sys/bus.h>
1.1       wiz       139: #include <sys/bus.h>
                    140: #endif
                    141:
                    142: #include <machine/ioctl_meteor.h>
                    143: #include <machine/ioctl_bt848.h>       /* extensions to ioctl_meteor.h */
                    144: #include <dev/bktr/bktr_reg.h>
                    145: #include <dev/bktr/bktr_tuner.h>
                    146: #include <dev/bktr/bktr_card.h>
                    147: #include <dev/bktr/bktr_audio.h>
                    148: #include <dev/bktr/bktr_os.h>
                    149: #include <dev/bktr/bktr_core.h>
1.12      wiz       150: #if defined(BKTR_FREEBSD_MODULE)
                    151: #include <dev/bktr/bktr_mem.h>
                    152: #endif
1.1       wiz       153:
1.12      wiz       154: #if defined(BKTR_USE_FREEBSD_SMBUS)
1.1       wiz       155: #include <dev/bktr/bktr_i2c.h>
                    156: #include <dev/smbus/smbconf.h>
                    157: #include <dev/iicbus/iiconf.h>
                    158: #include "smbus_if.h"
                    159: #include "iicbus_if.h"
                    160: #endif
                    161:
1.8       wiz       162: const char *
1.4       wiz       163: bktr_name(bktr_ptr_t bktr)
                    164: {
1.8       wiz       165:   return bktr->bktr_xname;
1.4       wiz       166: }
                    167:
1.1       wiz       168:
                    169: #endif  /* __FreeBSD__ */
                    170:
                    171:
                    172: /****************/
                    173: /* *** BSDI *** */
                    174: /****************/
                    175: #ifdef __bsdi__
1.28      wiz       176: #define                PROC_LOCK(p)
                    177: #define                PROC_UNLOCK(p)
1.1       wiz       178: #endif /* __bsdi__ */
                    179:
                    180:
                    181: /**************************/
                    182: /* *** OpenBSD/NetBSD *** */
                    183: /**************************/
                    184: #if defined(__NetBSD__) || defined(__OpenBSD__)
                    185:
1.28      wiz       186: /* Emulate FreeBSD's SEL_WAITING macro */
                    187: #define        SEL_WAITING(b)  ((b)->sel_pid)
                    188:
1.8       wiz       189: #include <sys/param.h>
                    190: #include <sys/systm.h>
                    191: #include <sys/kernel.h>
                    192: #include <sys/signalvar.h>
                    193: #include <sys/vnode.h>
1.19      chs       194: #include <sys/proc.h>
1.8       wiz       195:
                    196: #ifdef __NetBSD__
                    197: #include <uvm/uvm_extern.h>
1.13      wiz       198: #include <dev/pci/pcidevs.h>
                    199: #include <dev/pci/pcireg.h>
1.8       wiz       200: #else
                    201: #include <vm/vm.h>
                    202: #include <vm/vm_kern.h>
                    203: #include <vm/pmap.h>
                    204: #include <vm/vm_extern.h>
                    205: #endif
                    206:
1.1       wiz       207: #include <sys/inttypes.h>              /* uintptr_t */
1.2       wiz       208: #include <dev/ic/bt8xx.h>
                    209: #include <dev/pci/bktr/bktr_reg.h>
                    210: #include <dev/pci/bktr/bktr_tuner.h>
                    211: #include <dev/pci/bktr/bktr_card.h>
                    212: #include <dev/pci/bktr/bktr_audio.h>
                    213: #include <dev/pci/bktr/bktr_core.h>
                    214: #include <dev/pci/bktr/bktr_os.h>
1.1       wiz       215:
                    216: static int bt848_format = -1;
                    217:
1.8       wiz       218: const char *
1.4       wiz       219: bktr_name(bktr_ptr_t bktr)
                    220: {
                    221:         return (bktr->bktr_dev.dv_xname);
                    222: }
                    223:
1.28      wiz       224: #define                PROC_LOCK(p)
                    225: #define                PROC_UNLOCK(p)
                    226:
1.1       wiz       227: #endif /* __NetBSD__ || __OpenBSD__ */
                    228:
                    229:
                    230:
                    231: typedef u_char bool_t;
                    232:
                    233: #define BKTRPRI (PZERO+8)|PCATCH
                    234: #define VBIPRI  (PZERO-4)|PCATCH
                    235:
                    236:
                    237: /*
                    238:  * memory allocated for DMA programs
                    239:  */
                    240: #define DMA_PROG_ALLOC         (8 * PAGE_SIZE)
                    241:
1.31      wiz       242: /* When to split a DMA transfer , the bt848 has timing as well as
                    243:    DMA transfer size limitations so that we have to split DMA
                    244:    transfers into two DMA requests
1.1       wiz       245:    */
                    246: #define DMA_BT848_SPLIT 319*2
                    247:
1.28      wiz       248: /*
1.1       wiz       249:  * Allocate enough memory for:
                    250:  *     768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
                    251:  *
                    252:  * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
                    253:  * in your  kernel configuration file.
                    254:  */
                    255:
                    256: #ifndef BROOKTREE_ALLOC_PAGES
                    257: #define BROOKTREE_ALLOC_PAGES  217*4
                    258: #endif
                    259: #define BROOKTREE_ALLOC                (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
                    260:
                    261: /* Definitions for VBI capture.
                    262:  * There are 16 VBI lines in a PAL video field (32 in a frame),
                    263:  * and we take 2044 samples from each line (placed in a 2048 byte buffer
                    264:  * for alignment).
                    265:  * VBI lines are held in a circular buffer before being read by a
                    266:  * user program from /dev/vbi.
                    267:  */
                    268:
                    269: #define MAX_VBI_LINES        16   /* Maximum for all vidoe formats */
                    270: #define VBI_LINE_SIZE         2048 /* Store upto 2048 bytes per line */
                    271: #define VBI_BUFFER_ITEMS      20   /* Number of frames we buffer */
                    272: #define VBI_DATA_SIZE         (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
                    273: #define VBI_BUFFER_SIZE       (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
                    274:
                    275:
                    276: /*  Defines for fields  */
                    277: #define ODD_F  0x01
                    278: #define EVEN_F 0x02
                    279:
                    280:
                    281: /*
                    282:  * Parameters describing size of transmitted image.
                    283:  */
                    284:
1.15      jdolecek  285: static const struct format_params format_params[] = {
1.1       wiz       286: /* # define BT848_IFORM_F_AUTO             (0x0) - don't matter. */
                    287:   { 525, 26, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
                    288:     12,  1600 },
                    289: /* # define BT848_IFORM_F_NTSCM            (0x1) */
                    290:   { 525, 26, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
                    291:     12, 1600 },
                    292: /* # define BT848_IFORM_F_NTSCJ            (0x2) */
                    293:   { 525, 22, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
                    294:     12, 1600 },
                    295: /* # define BT848_IFORM_F_PALBDGHI         (0x3) */
                    296:   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
                    297:     16,  2044 },
                    298: /* # define BT848_IFORM_F_PALM             (0x4) */
                    299:   { 525, 22, 480,  910, 135, 754, 640,  780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
                    300:     12, 1600 },
                    301: /* # define BT848_IFORM_F_PALN             (0x5) */
                    302:   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
                    303:     16, 2044 },
                    304: /* # define BT848_IFORM_F_SECAM            (0x6) */
                    305:   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
                    306:     16, 2044 },
                    307: /* # define BT848_IFORM_F_RSVD             (0x7) - ???? */
                    308:   { 625, 32, 576, 1135, 186, 924, 768,  944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
                    309:     16, 2044 },
                    310: };
                    311:
                    312: /*
1.28      wiz       313:  * Table of supported Pixel Formats
1.1       wiz       314:  */
                    315:
1.15      jdolecek  316: static const struct meteor_pixfmt_internal {
1.1       wiz       317:        struct meteor_pixfmt public;
                    318:        u_int                color_fmt;
                    319: } pixfmt_table[] = {
                    320:
                    321: { { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,  0x03e0,  0x001f }, 0,0 }, 0x33 },
                    322: { { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,  0x03e0,  0x001f }, 1,0 }, 0x33 },
                    323:
                    324: { { 0, METEOR_PIXTYPE_RGB, 2, {   0xf800,  0x07e0,  0x001f }, 0,0 }, 0x22 },
                    325: { { 0, METEOR_PIXTYPE_RGB, 2, {   0xf800,  0x07e0,  0x001f }, 1,0 }, 0x22 },
                    326:
                    327: { { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
                    328:
                    329: { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
                    330: { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
                    331: { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
                    332: { { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
                    333: { { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
                    334: { { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
                    335: { { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
                    336:
                    337: };
1.28      wiz       338: #define PIXFMT_TABLE_SIZE (sizeof(pixfmt_table) / sizeof(pixfmt_table[0]))
1.1       wiz       339:
                    340: /*
                    341:  * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
                    342:  */
                    343:
                    344: /*  FIXME:  Also add YUV_422 and YUV_PACKED as well  */
1.15      jdolecek  345: static const struct {
1.46      jmcneill  346:        u_int               meteor_format;
1.1       wiz       347:        struct meteor_pixfmt public;
                    348: } meteor_pixfmt_table[] = {
                    349:     { METEOR_GEO_YUV_12,
                    350:       { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
                    351:     },
                    352:
                    353:       /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
                    354:     { METEOR_GEO_YUV_422,
                    355:       { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
                    356:     },
                    357:     { METEOR_GEO_YUV_PACKED,
                    358:       { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
                    359:     },
                    360:     { METEOR_GEO_RGB16,
                    361:       { 0, METEOR_PIXTYPE_RGB, 2, {   0x7c00,   0x03e0,   0x001f }, 0, 0 }
                    362:     },
                    363:     { METEOR_GEO_RGB24,
                    364:       { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
                    365:     },
                    366:
                    367: };
1.28      wiz       368: #define METEOR_PIXFMT_TABLE_SIZE (sizeof(meteor_pixfmt_table) / \
                    369:                                   sizeof(meteor_pixfmt_table[0]))
1.1       wiz       370:
                    371:
                    372: #define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
                    373: #define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
                    374:
                    375:
                    376:
                    377: /* sync detect threshold */
                    378: #if 0
                    379: #define SYNC_LEVEL             (BT848_ADC_RESERVED |   \
                    380:                                 BT848_ADC_CRUSH)       /* threshold ~125 mV */
                    381: #else
                    382: #define SYNC_LEVEL             (BT848_ADC_RESERVED |   \
                    383:                                 BT848_ADC_SYNC_T)      /* threshold ~75 mV */
                    384: #endif
                    385:
                    386:
                    387:
                    388:
                    389: /* debug utility for holding previous INT_STAT contents */
                    390: #define STATUS_SUM
1.46      jmcneill  391: static u_int   status_sum = 0;
1.1       wiz       392:
                    393: /*
                    394:  * defines to make certain bit-fiddles understandable
                    395:  */
                    396: #define FIFO_ENABLED           BT848_DMA_CTL_FIFO_EN
                    397: #define RISC_ENABLED           BT848_DMA_CTL_RISC_EN
                    398: #define FIFO_RISC_ENABLED      (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
                    399: #define FIFO_RISC_DISABLED     0
                    400:
                    401: #define ALL_INTS_DISABLED      0
                    402: #define ALL_INTS_CLEARED       0xffffffff
                    403: #define CAPTURE_OFF            0
                    404:
                    405: #define BIT_SEVEN_HIGH         (1<<7)
                    406: #define BIT_EIGHT_HIGH         (1<<8)
                    407:
                    408: #define I2C_BITS               (BT848_INT_RACK | BT848_INT_I2CDONE)
                    409: #define TDEC_BITS               (BT848_INT_FDSR | BT848_INT_FBUS)
                    410:
                    411:
                    412:
1.46      jmcneill  413: static int             oformat_meteor_to_bt(u_int format);
1.1       wiz       414:
1.28      wiz       415: static u_int           pixfmt_swap_flags(int pixfmt);
1.1       wiz       416:
                    417: /*
                    418:  * bt848 RISC programming routines.
                    419:  */
                    420: #ifdef BT848_DUMP
1.28      wiz       421: static int     dump_bt848(bktr_ptr_t bktr);
1.1       wiz       422: #endif
                    423:
1.28      wiz       424: static void    yuvpack_prog(bktr_ptr_t bktr, char i_flag, int cols,
                    425:                              int rows,  int interlace);
                    426: static void    yuv422_prog(bktr_ptr_t bktr, char i_flag, int cols,
                    427:                             int rows, int interlace);
                    428: static void    yuv12_prog(bktr_ptr_t bktr, char i_flag, int cols,
                    429:                             int rows, int interlace);
                    430: static void    rgb_prog(bktr_ptr_t bktr, char i_flag, int cols,
                    431:                          int rows, int interlace);
                    432: static void    rgb_vbi_prog(bktr_ptr_t bktr, char i_flag, int cols,
                    433:                          int rows, int interlace);
                    434: static void    build_dma_prog(bktr_ptr_t bktr, char i_flag);
1.1       wiz       435:
                    436: static bool_t   getline(bktr_reg_t *, int);
1.28      wiz       437: static bool_t   notclipped(bktr_reg_t * , int , int);
1.46      jmcneill  438: static bool_t   split(bktr_reg_t *, volatile u_int **, int, u_int, int,
1.28      wiz       439:                      volatile u_char ** , int);
1.1       wiz       440:
1.28      wiz       441: static void    start_capture(bktr_ptr_t bktr, unsigned type);
                    442: static void    set_fps(bktr_ptr_t bktr, u_short fps);
1.1       wiz       443:
                    444:
                    445:
                    446: /*
                    447:  * Remote Control Functions
                    448:  */
                    449: static void    remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
                    450:
                    451:
                    452: /*
                    453:  * ioctls common to both video & tuner.
                    454:  */
1.42      christos  455: static int     common_ioctl(bktr_ptr_t bktr, ioctl_cmd_t cmd, void *arg);
1.1       wiz       456:
                    457:
1.12      wiz       458: #if !defined(BKTR_USE_FREEBSD_SMBUS)
1.1       wiz       459: /*
                    460:  * i2c primitives for low level control of i2c bus. Added for MSP34xx control
                    461:  */
1.28      wiz       462: static void     i2c_start(bktr_ptr_t bktr);
                    463: static void     i2c_stop(bktr_ptr_t bktr);
                    464: static int      i2c_write_byte(bktr_ptr_t bktr, unsigned char data);
                    465: static int      i2c_read_byte(bktr_ptr_t bktr, unsigned char *data, int last);
1.1       wiz       466: #endif
                    467:
                    468:
                    469:
                    470: /*
                    471:  * the common attach code, used by all OS versions.
                    472:  */
1.38      bouyer    473: int
1.46      jmcneill  474: common_bktr_attach(bktr_ptr_t bktr, int unit, u_int pci_id, u_int rev)
1.1       wiz       475: {
1.13      wiz       476: #if defined(__NetBSD__)
1.34      christos  477:        vaddr_t         sbuf = 0;
1.13      wiz       478: #else
1.34      christos  479:        vm_offset_t     sbuf = 0;
1.13      wiz       480: #endif
1.1       wiz       481:
                    482: /***************************************/
                    483: /* *** OS Specific memory routines *** */
                    484: /***************************************/
                    485: #if defined(__NetBSD__) || defined(__OpenBSD__)
1.31      wiz       486:         /* allocate space for DMA program */
1.2       wiz       487:         bktr->dma_prog = get_bktr_mem(bktr, &bktr->dm_prog,
                    488:                                      DMA_PROG_ALLOC);
1.38      bouyer    489:        if (bktr->dma_prog == 0)
                    490:                return 0;
1.2       wiz       491:         bktr->odd_dma_prog = get_bktr_mem(bktr, &bktr->dm_oprog,
                    492:                                          DMA_PROG_ALLOC);
1.38      bouyer    493:        if (bktr->odd_dma_prog == 0)
                    494:                return 0;
1.2       wiz       495:
                    496:        /* allocate space for the VBI buffer */
                    497:        bktr->vbidata  = get_bktr_mem(bktr, &bktr->dm_vbidata,
                    498:                                      VBI_DATA_SIZE);
1.38      bouyer    499:        if (bktr->vbidata == 0)
                    500:                return 0;
1.2       wiz       501:        bktr->vbibuffer = get_bktr_mem(bktr, &bktr->dm_vbibuffer,
                    502:                                       VBI_BUFFER_SIZE);
1.38      bouyer    503:        if (bktr->vbibuffer == 0)
                    504:                return 0;
1.1       wiz       505:
                    506:         /* allocate space for pixel buffer */
1.38      bouyer    507:         if (BROOKTREE_ALLOC) {
1.34      christos  508:                 sbuf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
1.38      bouyer    509:                if (sbuf == 0)
                    510:                        return 0;
                    511:         } else
1.34      christos  512:                 sbuf = 0;
1.1       wiz       513: #endif
                    514:
                    515: #if defined(__FreeBSD__) || defined(__bsdi__)
1.13      wiz       516:        int             need_to_allocate_memory = 1;
1.12      wiz       517:
                    518: /* If this is a module, check if there is any currently saved contiguous memory */
                    519: #if defined(BKTR_FREEBSD_MODULE)
                    520:        if (bktr_has_stored_addresses(unit) == 1) {
                    521:                /* recover the addresses */
                    522:                bktr->dma_prog     = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
                    523:                bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
                    524:                bktr->vbidata      = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
                    525:                bktr->vbibuffer    = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
1.34      christos  526:                sbuf                = bktr_retrieve_address(unit, BKTR_MEM_BUF);
1.12      wiz       527:                need_to_allocate_memory = 0;
                    528:        }
                    529: #endif
                    530:
                    531:        if (need_to_allocate_memory == 1) {
1.31      wiz       532:                /* allocate space for DMA program */
1.12      wiz       533:                bktr->dma_prog     = get_bktr_mem(unit, DMA_PROG_ALLOC);
                    534:                bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
                    535:
                    536:                /* allocte space for the VBI buffer */
                    537:                bktr->vbidata  = get_bktr_mem(unit, VBI_DATA_SIZE);
                    538:                bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
                    539:
                    540:                /* allocate space for pixel buffer */
1.28      wiz       541:                if (BROOKTREE_ALLOC)
1.34      christos  542:                        sbuf = get_bktr_mem(unit, BROOKTREE_ALLOC);
1.12      wiz       543:                else
1.34      christos  544:                        sbuf = 0;
1.12      wiz       545:        }
                    546: #endif /* FreeBSD or BSDi */
                    547:
                    548:
                    549: /* If this is a module, save the current contiguous memory */
                    550: #if defined(BKTR_FREEBSD_MODULE)
                    551: bktr_store_address(unit, BKTR_MEM_DMA_PROG,     bktr->dma_prog);
                    552: bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
                    553: bktr_store_address(unit, BKTR_MEM_VBIDATA,      bktr->vbidata);
                    554: bktr_store_address(unit, BKTR_MEM_VBIBUFFER,    bktr->vbibuffer);
1.34      christos  555: bktr_store_address(unit, BKTR_MEM_BUF,          sbuf);
1.1       wiz       556: #endif
                    557:
1.12      wiz       558:
1.28      wiz       559:        if (bootverbose) {
                    560:                printf("%s: buffer size %d, addr %p\n",
1.11      thorpej   561:                        bktr_name(bktr), BROOKTREE_ALLOC,
1.38      bouyer    562:                        (void *)(uintptr_t)bktr->dm_mem->dm_segs[0].ds_addr);
1.1       wiz       563:        }
                    564:
1.34      christos  565:        if (sbuf != 0) {
                    566:                bktr->bigbuf = sbuf;
1.1       wiz       567:                bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
1.42      christos  568:                bzero((void *) bktr->bigbuf, BROOKTREE_ALLOC);
1.1       wiz       569:        } else {
                    570:                bktr->alloc_pages = 0;
                    571:        }
1.28      wiz       572:
1.1       wiz       573:
1.18      wiz       574:        bktr->flags = METEOR_INITIALIZED | METEOR_AUTOMODE |
1.1       wiz       575:                      METEOR_DEV0 | METEOR_RGB16;
                    576:        bktr->dma_prog_loaded = FALSE;
                    577:        bktr->cols = 640;
                    578:        bktr->rows = 480;
                    579:        bktr->frames = 1;               /* one frame */
                    580:        bktr->format = METEOR_GEO_RGB16;
1.28      wiz       581:        bktr->pixfmt = oformat_meteor_to_bt(bktr->format);
1.1       wiz       582:        bktr->pixfmt_compat = TRUE;
                    583:
                    584:
                    585:        bktr->vbiinsert = 0;
                    586:        bktr->vbistart = 0;
                    587:        bktr->vbisize = 0;
                    588:        bktr->vbiflags = 0;
                    589:
1.28      wiz       590:
1.1       wiz       591:        /* using the pci device id and revision id */
                    592:        /* and determine the card type            */
1.10      wiz       593:        if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
                    594:        {
                    595:                switch (PCI_PRODUCT(pci_id)) {
                    596:                case PCI_PRODUCT_BROOKTREE_BT848:
                    597:                        if (rev == 0x12)
                    598:                                bktr->id = BROOKTREE_848A;
                    599:                        else
                    600:                                bktr->id = BROOKTREE_848;
                    601:                        break;
                    602:                case PCI_PRODUCT_BROOKTREE_BT849:
                    603:                        bktr->id = BROOKTREE_849A;
                    604:                        break;
                    605:                case PCI_PRODUCT_BROOKTREE_BT878:
                    606:                        bktr->id = BROOKTREE_878;
                    607:                        break;
                    608:                case PCI_PRODUCT_BROOKTREE_BT879:
                    609:                        bktr->id = BROOKTREE_879;
                    610:                        break;
                    611:                }
1.1       wiz       612:        };
                    613:
                    614:        bktr->clr_on_start = FALSE;
                    615:
                    616:        /* defaults for the tuner section of the card */
1.18      wiz       617:        bktr->tflags = TUNER_INITIALIZED;
1.1       wiz       618:        bktr->tuner.frequency = 0;
                    619:        bktr->tuner.channel = 0;
                    620:        bktr->tuner.chnlset = DEFAULT_CHNLSET;
                    621:        bktr->tuner.afc = 0;
                    622:        bktr->tuner.radio_mode = 0;
                    623:        bktr->audio_mux_select = 0;
                    624:        bktr->audio_mute_state = FALSE;
                    625:        bktr->bt848_card = -1;
                    626:        bktr->bt848_tuner = -1;
                    627:        bktr->reverse_mute = -1;
                    628:        bktr->slow_msp_audio = 0;
1.14      wiz       629:        bktr->msp_use_mono_source = 0;
                    630:         bktr->msp_source_selected = -1;
                    631:        bktr->audio_mux_present = 1;
1.1       wiz       632:
1.28      wiz       633:        probeCard(bktr, TRUE, unit);
1.1       wiz       634:
                    635:        /* Initialise any MSP34xx or TDA98xx audio chips */
1.28      wiz       636:        init_audio_devices(bktr);
1.38      bouyer    637:        return 1;
1.1       wiz       638: }
                    639:
                    640:
                    641: /* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
1.28      wiz       642:  * The circular buffer holds 'n' fixed size data blocks.
                    643:  * vbisize   is the number of bytes in the circular buffer
                    644:  * vbiread   is the point we reading data out of the circular buffer
                    645:  * vbiinsert is the point we insert data into the circular buffer
1.1       wiz       646:  */
                    647: static void vbidecode(bktr_ptr_t bktr) {
                    648:         unsigned char *dest;
                    649:        unsigned int *seq_dest;
                    650:
                    651:        /* Check if there is room in the buffer to insert the data. */
                    652:        if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
                    653:
                    654:        /* Copy the VBI data into the next free slot in the buffer. */
                    655:        /* 'dest' is the point in vbibuffer where we want to insert new data */
                    656:         dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
                    657:         memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
                    658:
                    659:        /* Write the VBI sequence number to the end of the vbi data */
                    660:        /* This is used by the AleVT teletext program */
                    661:        seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
                    662:                        + bktr->vbiinsert
                    663:                        + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
                    664:        *seq_dest = bktr->vbi_sequence_number;
                    665:
                    666:        /* And increase the VBI sequence number */
                    667:        /* This can wrap around */
                    668:        bktr->vbi_sequence_number++;
                    669:
                    670:
                    671:        /* Increment the vbiinsert pointer */
                    672:        /* This can wrap around */
                    673:        bktr->vbiinsert += VBI_DATA_SIZE;
                    674:        bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
                    675:
                    676:        /* And increase the amount of vbi data in the buffer */
                    677:        bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
                    678:
                    679: }
                    680:
                    681:
                    682: /*
                    683:  * the common interrupt handler.
                    684:  * Returns a 0 or 1 depending on whether the interrupt has handled.
                    685:  * In the OS specific section, bktr_intr() is defined which calls this
                    686:  * common interrupt handler.
                    687:  */
1.28      wiz       688: int
                    689: common_bktr_intr(void *arg)
                    690: {
1.1       wiz       691:        bktr_ptr_t              bktr;
1.46      jmcneill  692:        u_int                   bktr_status;
1.1       wiz       693:        u_char                  dstatus;
1.46      jmcneill  694:        u_int                  field;
                    695:        u_int                  w_field;
                    696:        u_int                  req_field;
1.1       wiz       697:
                    698:        bktr = (bktr_ptr_t) arg;
                    699:
                    700:        /*
                    701:         * check to see if any interrupts are unmasked on this device.  If
                    702:         * none are, then we likely got here by way of being on a PCI shared
                    703:         * interrupt dispatch list.
                    704:         */
                    705:        if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
1.25      toshii    706:                return 0;       /* bail out now, before we do something we
1.1       wiz       707:                                   shouldn't */
                    708:
                    709:        if (!(bktr->flags & METEOR_OPEN)) {
                    710:                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
                    711:                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
                    712:                /* return; ?? */
                    713:        }
                    714:
                    715:        /* record and clear the INTerrupt status bits */
                    716:        bktr_status = INL(bktr, BKTR_INT_STAT);
                    717:        OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS);     /* don't touch i2c */
                    718:
                    719:        /* record and clear the device status register */
                    720:        dstatus = INB(bktr, BKTR_DSTATUS);
                    721:        OUTB(bktr, BKTR_DSTATUS, 0x00);
                    722:
1.28      wiz       723: #if defined(STATUS_SUM)
1.1       wiz       724:        /* add any new device status or INTerrupt status bits */
                    725:        status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
                    726:        status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
                    727: #endif /* STATUS_SUM */
1.28      wiz       728:        /* printf("%s: STATUS %x %x %x \n", bktr_name(bktr),
                    729:                dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT));
1.1       wiz       730:        */
                    731:
                    732:
                    733:        /* if risc was disabled re-start process again */
                    734:        /* if there was one of the following errors re-start again */
1.28      wiz       735:        if (!(bktr_status & BT848_INT_RISC_EN) ||
1.1       wiz       736:             ((bktr_status &(/* BT848_INT_FBUS   | */
                    737:                             /* BT848_INT_FTRGT  | */
                    738:                             /* BT848_INT_FDSR   | */
                    739:                              BT848_INT_PPERR  |
                    740:                              BT848_INT_RIPERR | BT848_INT_PABORT |
1.28      wiz       741:                              BT848_INT_OCERR  | BT848_INT_SCERR)) != 0)
                    742:                || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS))) {
1.1       wiz       743:
                    744:                u_short tdec_save = INB(bktr, BKTR_TDEC);
                    745:
                    746:                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
                    747:                OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
                    748:
                    749:                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
                    750:
                    751:                /*  Reset temporal decimation counter  */
                    752:                OUTB(bktr, BKTR_TDEC, 0);
                    753:                OUTB(bktr, BKTR_TDEC, tdec_save);
1.28      wiz       754:
1.1       wiz       755:                /*  Reset to no-fields captured state  */
                    756:                if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
                    757:                        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
                    758:                        case METEOR_ONLY_ODD_FIELDS:
                    759:                                bktr->flags |= METEOR_WANT_ODD;
                    760:                                break;
                    761:                        case METEOR_ONLY_EVEN_FIELDS:
                    762:                                bktr->flags |= METEOR_WANT_EVEN;
                    763:                                break;
                    764:                        default:
                    765:                                bktr->flags |= METEOR_WANT_MASK;
                    766:                                break;
                    767:                        }
                    768:                }
                    769:
1.38      bouyer    770:                OUTL(bktr, BKTR_RISC_STRT_ADD,
                    771:                    bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz       772:                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
                    773:                OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
                    774:
                    775:                OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
                    776:                                    BT848_INT_RISCI      |
                    777:                                    BT848_INT_VSYNC      |
                    778:                                    BT848_INT_FMTCHG);
                    779:
                    780:                OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
                    781:                return 1;
                    782:        }
                    783:
                    784:        /* If this is not a RISC program interrupt, return */
                    785:        if (!(bktr_status & BT848_INT_RISCI))
                    786:                return 0;
                    787:
                    788: /**
1.28      wiz       789:        printf("%s: intr status %x %x %x\n", bktr_name(bktr),
                    790:                bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT));
1.1       wiz       791:  */
                    792:
                    793:
                    794:        /*
                    795:         * Disable future interrupts if a capture mode is not selected.
1.28      wiz       796:         * This can happen when we are in the process of closing or
1.1       wiz       797:         * changing capture modes, otherwise it shouldn't happen.
                    798:         */
                    799:        if (!(bktr->flags & METEOR_CAP_MASK))
                    800:                OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
                    801:
                    802:
                    803:        /* Determine which field generated this interrupt */
1.28      wiz       804:        field = (bktr_status & BT848_INT_FIELD) ? EVEN_F : ODD_F;
1.1       wiz       805:
                    806:
                    807:        /*
                    808:         * Process the VBI data if it is being captured. We do this once
                    809:         * both Odd and Even VBI data is captured. Therefore we do this
                    810:         * in the Even field interrupt handler.
                    811:         */
1.28      wiz       812:        if ((bktr->vbiflags & VBI_CAPTURE)
1.1       wiz       813:            &&(bktr->vbiflags & VBI_OPEN)
                    814:             &&(field==EVEN_F)) {
                    815:                /* Put VBI data into circular buffer */
1.25      toshii    816:                vbidecode(bktr);
1.1       wiz       817:
                    818:                /* If someone is blocked on reading from /dev/vbi, wake them */
                    819:                if (bktr->vbi_read_blocked) {
                    820:                        bktr->vbi_read_blocked = FALSE;
1.25      toshii    821:                        wakeup(VBI_SLEEP);
1.1       wiz       822:                }
                    823:
                    824:                /* If someone has a select() on /dev/vbi, inform them */
1.46.2.1! keiichi   825:                selnotify(&bktr->vbi_select, 0, 0);
1.1       wiz       826:        }
                    827:
                    828:        /*
                    829:         *  Register the completed field
                    830:         *    (For dual-field mode, require fields from the same frame)
                    831:         */
1.28      wiz       832:        switch (bktr->flags & METEOR_WANT_MASK) {
1.1       wiz       833:                case METEOR_WANT_ODD  : w_field = ODD_F         ;  break;
                    834:                case METEOR_WANT_EVEN : w_field = EVEN_F        ;  break;
                    835:                default               : w_field = (ODD_F|EVEN_F);  break;
                    836:        }
1.28      wiz       837:        switch (bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1.1       wiz       838:                case METEOR_ONLY_ODD_FIELDS  : req_field = ODD_F  ;  break;
                    839:                case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ;  break;
1.28      wiz       840:                default                      : req_field = (ODD_F|EVEN_F);
1.1       wiz       841:                                               break;
                    842:        }
                    843:
1.28      wiz       844:        if ((field == EVEN_F) && (w_field == EVEN_F))
1.1       wiz       845:                bktr->flags &= ~METEOR_WANT_EVEN;
1.28      wiz       846:        else if ((field == ODD_F) && (req_field == ODD_F) &&
                    847:                 (w_field == ODD_F))
1.1       wiz       848:                bktr->flags &= ~METEOR_WANT_ODD;
1.28      wiz       849:        else if ((field == ODD_F) && (req_field == (ODD_F|EVEN_F)) &&
                    850:                 (w_field == (ODD_F|EVEN_F)))
1.1       wiz       851:                bktr->flags &= ~METEOR_WANT_ODD;
1.28      wiz       852:        else if ((field == ODD_F) && (req_field == (ODD_F|EVEN_F)) &&
                    853:                 (w_field == ODD_F)) {
1.1       wiz       854:                bktr->flags &= ~METEOR_WANT_ODD;
                    855:                bktr->flags |=  METEOR_WANT_EVEN;
                    856:        }
                    857:        else {
                    858:                /*  We're out of sync.  Start over.  */
                    859:                if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
                    860:                        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
                    861:                        case METEOR_ONLY_ODD_FIELDS:
                    862:                                bktr->flags |= METEOR_WANT_ODD;
                    863:                                break;
                    864:                        case METEOR_ONLY_EVEN_FIELDS:
                    865:                                bktr->flags |= METEOR_WANT_EVEN;
                    866:                                break;
                    867:                        default:
                    868:                                bktr->flags |= METEOR_WANT_MASK;
                    869:                                break;
                    870:                        }
                    871:                }
                    872:                return 1;
                    873:        }
                    874:
                    875:        /*
                    876:         * If we have a complete frame.
                    877:         */
                    878:        if (!(bktr->flags & METEOR_WANT_MASK)) {
                    879:                bktr->frames_captured++;
                    880:                /*
1.28      wiz       881:                 * post the completion time.
1.1       wiz       882:                 */
                    883:                if (bktr->flags & METEOR_WANT_TS) {
                    884:                        struct timeval *ts;
1.28      wiz       885:
1.1       wiz       886:                        if ((u_int) bktr->alloc_pages * PAGE_SIZE
                    887:                           <= (bktr->frame_size + sizeof(struct timeval))) {
                    888:                                ts =(struct timeval *)bktr->bigbuf +
                    889:                                  bktr->frame_size;
                    890:                                /* doesn't work in synch mode except
                    891:                                 *  for first frame */
                    892:                                /* XXX */
                    893:                                microtime(ts);
                    894:                        }
                    895:                }
1.28      wiz       896:
1.1       wiz       897:
                    898:                /*
                    899:                 * Wake up the user in single capture mode.
                    900:                 */
                    901:                if (bktr->flags & METEOR_SINGLE) {
                    902:
1.31      wiz       903:                        /* stop DMA */
1.1       wiz       904:                        OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
                    905:
                    906:                        /* disable risc, leave fifo running */
                    907:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
                    908:                        wakeup(BKTR_SLEEP);
                    909:                }
                    910:
                    911:                /*
                    912:                 * If the user requested to be notified via signal,
                    913:                 * let them know the frame is complete.
                    914:                 */
                    915:
1.28      wiz       916:                if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK)) {
1.41      ad        917:                        mutex_enter(&proclist_mutex);
1.28      wiz       918:                        PROC_LOCK(bktr->proc);
                    919:                        psignal(bktr->proc,
                    920:                                 bktr->signal&(~METEOR_SIG_MODE_MASK));
                    921:                        PROC_UNLOCK(bktr->proc);
1.41      ad        922:                        mutex_exit(&proclist_mutex);
1.28      wiz       923:                }
1.1       wiz       924:
                    925:                /*
                    926:                 * Reset the want flags if in continuous or
                    927:                 * synchronous capture mode.
                    928:                 */
                    929: /*
                    930: * XXX NOTE (Luigi):
                    931: * currently we only support 3 capture modes: odd only, even only,
                    932: * odd+even interlaced (odd field first). A fourth mode (non interlaced,
                    933: * either even OR odd) could provide 60 (50 for PAL) pictures per
                    934: * second, but it would require this routine to toggle the desired frame
                    935: * each time, and one more different DMA program for the Bt848.
                    936: * As a consequence, this fourth mode is currently unsupported.
                    937: */
                    938:
                    939:                if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
                    940:                        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
                    941:                        case METEOR_ONLY_ODD_FIELDS:
                    942:                                bktr->flags |= METEOR_WANT_ODD;
                    943:                                break;
                    944:                        case METEOR_ONLY_EVEN_FIELDS:
                    945:                                bktr->flags |= METEOR_WANT_EVEN;
                    946:                                break;
                    947:                        default:
                    948:                                bktr->flags |= METEOR_WANT_MASK;
                    949:                                break;
                    950:                        }
                    951:                }
                    952:        }
                    953:
                    954:        return 1;
                    955: }
                    956:
                    957:
                    958:
                    959:
                    960: /*
1.28      wiz       961:  *
1.1       wiz       962:  */
                    963: extern int bt848_format; /* used to set the default format, PAL or NTSC */
                    964: int
1.28      wiz       965: video_open(bktr_ptr_t bktr)
1.1       wiz       966: {
                    967:        int frame_rate, video_format=0;
                    968:
                    969:        if (bktr->flags & METEOR_OPEN)          /* device is busy */
1.28      wiz       970:                return(EBUSY);
1.1       wiz       971:
                    972:        bktr->flags |= METEOR_OPEN;
                    973:
                    974: #ifdef BT848_DUMP
1.28      wiz       975:        dump_bt848(bt848);
1.1       wiz       976: #endif
                    977:
                    978:         bktr->clr_on_start = FALSE;
                    979:
                    980:        OUTB(bktr, BKTR_DSTATUS, 0x00);                 /* clear device status reg. */
                    981:
                    982:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
                    983:
1.5       wiz       984: #if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
1.1       wiz       985:        video_format = 0;
                    986: #else
                    987:        video_format = 1;
                    988: #endif
                    989:
1.28      wiz       990:        if (bt848_format == 0)
1.1       wiz       991:          video_format = 0;
                    992:
1.28      wiz       993:        if (bt848_format == 1)
1.1       wiz       994:          video_format = 1;
                    995:
1.28      wiz       996:        if (video_format == 1) {
1.1       wiz       997:          OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
                    998:          bktr->format_params = BT848_IFORM_F_NTSCM;
                    999:
                   1000:        } else {
                   1001:          OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
                   1002:          bktr->format_params = BT848_IFORM_F_PALBDGHI;
                   1003:
                   1004:        }
                   1005:
                   1006:        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
                   1007:
                   1008:        /* work around for new Hauppauge 878 cards */
                   1009:        if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
1.28      wiz      1010:            (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879))
1.1       wiz      1011:                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
                   1012:        else
                   1013:                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
                   1014:
                   1015:        OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
                   1016:        OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
                   1017:        frame_rate    = format_params[bktr->format_params].frame_rate;
                   1018:
1.28      wiz      1019:        /* enable PLL mode using 28MHz crystal for PAL/SECAM users */
1.1       wiz      1020:        if (bktr->xtal_pll_mode == BT848_USE_PLL) {
                   1021:                OUTB(bktr, BKTR_TGCTRL, 0);
                   1022:                OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
                   1023:                OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
                   1024:                OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
                   1025:        }
                   1026:
                   1027:        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
                   1028:
                   1029:        bktr->max_clip_node = 0;
                   1030:
                   1031:        OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
                   1032:
                   1033:        OUTB(bktr, BKTR_E_HSCALE_LO, 170);
                   1034:        OUTB(bktr, BKTR_O_HSCALE_LO, 170);
                   1035:
                   1036:        OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
                   1037:        OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
                   1038:        OUTB(bktr, BKTR_E_SCLOOP, 0);
                   1039:        OUTB(bktr, BKTR_O_SCLOOP, 0);
                   1040:
                   1041:        OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
                   1042:        OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
                   1043:
                   1044:        bktr->fifo_errors = 0;
                   1045:        bktr->dma_errors = 0;
                   1046:        bktr->frames_captured = 0;
                   1047:        bktr->even_fields_captured = 0;
                   1048:        bktr->odd_fields_captured = 0;
1.28      wiz      1049:        bktr->proc = NULL;
1.1       wiz      1050:        set_fps(bktr, frame_rate);
                   1051:        bktr->video.addr = 0;
                   1052:        bktr->video.width = 0;
                   1053:        bktr->video.banksize = 0;
                   1054:        bktr->video.ramsize = 0;
                   1055:        bktr->pixfmt_compat = TRUE;
                   1056:        bktr->format = METEOR_GEO_RGB16;
1.28      wiz      1057:        bktr->pixfmt = oformat_meteor_to_bt(bktr->format);
1.1       wiz      1058:
                   1059:        bktr->capture_area_enabled = FALSE;
                   1060:
                   1061:        OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT);        /* if you take this out triton
1.28      wiz      1062:                                                    based motherboards will
1.1       wiz      1063:                                                   operate unreliably */
1.28      wiz      1064:        return(0);
1.1       wiz      1065: }
                   1066:
                   1067: int
1.28      wiz      1068: vbi_open(bktr_ptr_t bktr)
1.1       wiz      1069: {
                   1070:        if (bktr->vbiflags & VBI_OPEN)          /* device is busy */
1.28      wiz      1071:                return(EBUSY);
1.1       wiz      1072:
                   1073:        bktr->vbiflags |= VBI_OPEN;
                   1074:
                   1075:        /* reset the VBI circular buffer pointers and clear the buffers */
                   1076:        bktr->vbiinsert = 0;
                   1077:        bktr->vbistart = 0;
                   1078:        bktr->vbisize = 0;
                   1079:        bktr->vbi_sequence_number = 0;
                   1080:        bktr->vbi_read_blocked = FALSE;
                   1081:
1.42      christos 1082:        bzero((void *) bktr->vbibuffer, VBI_BUFFER_SIZE);
                   1083:        bzero((void *) bktr->vbidata,  VBI_DATA_SIZE);
1.1       wiz      1084:
1.28      wiz      1085:        return(0);
1.1       wiz      1086: }
                   1087:
                   1088: /*
1.28      wiz      1089:  *
1.1       wiz      1090:  */
                   1091: int
1.28      wiz      1092: tuner_open(bktr_ptr_t bktr)
1.1       wiz      1093: {
1.28      wiz      1094:        if (!(bktr->tflags & TUNER_INITIALIZED))        /* device not found */
                   1095:                return(ENXIO);
1.1       wiz      1096:
1.28      wiz      1097:        if (bktr->tflags & TUNER_OPEN)          /* already open */
                   1098:                return(0);
1.1       wiz      1099:
                   1100:        bktr->tflags |= TUNER_OPEN;
                   1101:        bktr->tuner.frequency = 0;
                   1102:        bktr->tuner.channel = 0;
                   1103:        bktr->tuner.chnlset = DEFAULT_CHNLSET;
                   1104:        bktr->tuner.afc = 0;
                   1105:        bktr->tuner.radio_mode = 0;
                   1106:
                   1107:        /* enable drivers on the GPIO port that control the MUXes */
                   1108:        OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
                   1109:
                   1110:        /* unmute the audio stream */
1.28      wiz      1111:        set_audio(bktr, AUDIO_UNMUTE);
1.1       wiz      1112:
                   1113:        /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1.28      wiz      1114:        init_audio_devices(bktr);
                   1115:
                   1116:        return(0);
1.1       wiz      1117: }
                   1118:
                   1119:
                   1120:
                   1121:
                   1122: /*
1.28      wiz      1123:  *
1.1       wiz      1124:  */
                   1125: int
1.28      wiz      1126: video_close(bktr_ptr_t bktr)
1.1       wiz      1127: {
                   1128:        bktr->flags &= ~(METEOR_OPEN     |
                   1129:                         METEOR_SINGLE   |
                   1130:                         METEOR_CAP_MASK |
                   1131:                         METEOR_WANT_MASK);
                   1132:
                   1133:        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
                   1134:        OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
                   1135:
                   1136:        bktr->dma_prog_loaded = FALSE;
                   1137:        OUTB(bktr, BKTR_TDEC, 0);
                   1138:        OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
                   1139:
                   1140: /** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
                   1141:        OUTL(bktr, BKTR_SRESET, 0xf);
                   1142:        OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
                   1143:
1.28      wiz      1144:        return(0);
1.1       wiz      1145: }
                   1146:
                   1147:
                   1148: /*
                   1149:  * tuner close handle,
                   1150:  *  place holder for tuner specific operations on a close.
                   1151:  */
                   1152: int
1.28      wiz      1153: tuner_close(bktr_ptr_t bktr)
1.1       wiz      1154: {
                   1155:        bktr->tflags &= ~TUNER_OPEN;
                   1156:
                   1157:        /* mute the audio by switching the mux */
1.28      wiz      1158:        set_audio(bktr, AUDIO_MUTE);
1.1       wiz      1159:
                   1160:        /* disable drivers on the GPIO port that control the MUXes */
                   1161:        OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
                   1162:
1.28      wiz      1163:        return(0);
1.1       wiz      1164: }
                   1165:
                   1166: int
1.28      wiz      1167: vbi_close(bktr_ptr_t bktr)
1.1       wiz      1168: {
                   1169:
                   1170:        bktr->vbiflags &= ~VBI_OPEN;
                   1171:
1.28      wiz      1172:        return(0);
1.1       wiz      1173: }
                   1174:
                   1175: /*
                   1176:  *
                   1177:  */
                   1178: int
1.40      christos 1179: video_read(bktr_ptr_t bktr, int unit, dev_t dev,
1.39      christos 1180:     struct uio *uio)
1.1       wiz      1181: {
                   1182:         int             status;
                   1183:         int             count;
                   1184:
                   1185:
                   1186:        if (bktr->bigbuf == 0)  /* no frame buffer allocated (ioctl failed) */
1.28      wiz      1187:                return(ENOMEM);
1.1       wiz      1188:
                   1189:        if (bktr->flags & METEOR_CAP_MASK)
1.28      wiz      1190:                return(EIO);    /* already capturing */
1.1       wiz      1191:
                   1192:         OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
                   1193:
                   1194:
1.28      wiz      1195:        count = bktr->rows * bktr->cols *
                   1196:                pixfmt_table[bktr->pixfmt].public.Bpp;
1.1       wiz      1197:
                   1198:        if ((int) uio->uio_iov->iov_len < count)
1.28      wiz      1199:                return(EINVAL);
1.1       wiz      1200:
                   1201:        bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
                   1202:
                   1203:        /* capture one frame */
                   1204:        start_capture(bktr, METEOR_SINGLE);
                   1205:        /* wait for capture to complete */
                   1206:        OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
                   1207:        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
                   1208:        OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
                   1209:        OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
                   1210:                             BT848_INT_RISCI      |
                   1211:                             BT848_INT_VSYNC      |
                   1212:                             BT848_INT_FMTCHG);
                   1213:
                   1214:
                   1215:        status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
                   1216:        if (!status)            /* successful capture */
1.42      christos 1217:                status = uiomove((void *)bktr->bigbuf, count, uio);
1.1       wiz      1218:        else
1.4       wiz      1219:                printf ("%s: read: tsleep error %d\n",
                   1220:                        bktr_name(bktr), status);
1.1       wiz      1221:
                   1222:        bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
                   1223:
1.28      wiz      1224:        return(status);
1.1       wiz      1225: }
                   1226:
                   1227: /*
                   1228:  * Read VBI data from the vbi circular buffer
                   1229:  * The buffer holds vbi data blocks which are the same size
                   1230:  * vbiinsert is the position we will insert the next item into the buffer
                   1231:  * vbistart is the actual position in the buffer we want to read from
1.28      wiz      1232:  * vbisize is the exact number of bytes in the buffer left to read
1.1       wiz      1233:  */
                   1234: int
                   1235: vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
                   1236: {
                   1237:        int             readsize, readsize2;
                   1238:        int             status;
                   1239:
                   1240:
                   1241:        while(bktr->vbisize == 0) {
                   1242:                if (ioflag & IO_NDELAY) {
                   1243:                        return EWOULDBLOCK;
                   1244:                }
                   1245:
                   1246:                bktr->vbi_read_blocked = TRUE;
                   1247:                if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
                   1248:                        return status;
                   1249:                }
                   1250:        }
                   1251:
                   1252:        /* Now we have some data to give to the user */
1.28      wiz      1253:
1.1       wiz      1254:        /* We cannot read more bytes than there are in
                   1255:         * the circular buffer
                   1256:         */
                   1257:        readsize = (int)uio->uio_iov->iov_len;
                   1258:
                   1259:        if (readsize > bktr->vbisize) readsize = bktr->vbisize;
                   1260:
                   1261:        /* Check if we can read this number of bytes without having
                   1262:         * to wrap around the circular buffer */
                   1263:        if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
                   1264:                /* We need to wrap around */
                   1265:
                   1266:                readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1.42      christos 1267:                status = uiomove((char *)bktr->vbibuffer + bktr->vbistart, readsize2, uio);
                   1268:                status += uiomove((char *)bktr->vbibuffer, (readsize - readsize2), uio);
1.1       wiz      1269:        } else {
                   1270:                /* We do not need to wrap around */
1.42      christos 1271:                status = uiomove((char *)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1.1       wiz      1272:        }
                   1273:
                   1274:        /* Update the number of bytes left to read */
                   1275:        bktr->vbisize -= readsize;
                   1276:
                   1277:        /* Update vbistart */
                   1278:        bktr->vbistart += readsize;
                   1279:        bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
                   1280:
1.28      wiz      1281:        return(status);
1.1       wiz      1282:
                   1283: }
                   1284:
                   1285:
                   1286:
                   1287: /*
                   1288:  * video ioctls
                   1289:  */
1.28      wiz      1290: #ifdef __FreeBSD__
                   1291: int
1.42      christos 1292: video_ioctl(bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, void *arg, struct thread* td)
1.28      wiz      1293: #else
1.1       wiz      1294: int
1.42      christos 1295: video_ioctl(bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, void *arg,
1.39      christos 1296:     struct lwp* l)
1.28      wiz      1297: #endif
1.1       wiz      1298: {
                   1299:        volatile u_char         c_temp;
                   1300:        unsigned int            temp;
                   1301:        unsigned int            temp_iform;
                   1302:        unsigned int            error;
                   1303:        struct meteor_geomet    *geo;
                   1304:        struct meteor_counts    *counts;
                   1305:        struct meteor_video     *video;
                   1306:        struct bktr_capture_area *cap_area;
1.13      wiz      1307: #if defined(__NetBSD__)
1.34      christos 1308:        vaddr_t                 sbuf;
1.13      wiz      1309: #else
1.34      christos 1310:        vm_offset_t             sbuf;
1.13      wiz      1311: #endif
1.1       wiz      1312:        int                     i;
                   1313:        char                    char_temp;
                   1314:
1.28      wiz      1315:        switch (cmd) {
1.1       wiz      1316:
                   1317:        case BT848SCLIP: /* set clip region */
                   1318:            bktr->max_clip_node = 0;
                   1319:            memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
                   1320:
                   1321:            for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
                   1322:                if (bktr->clip_list[i].y_min ==  0 &&
                   1323:                    bktr->clip_list[i].y_max == 0)
                   1324:                    break;
                   1325:            }
                   1326:            bktr->max_clip_node = i;
                   1327:
                   1328:            /* make sure that the list contains a valid clip secquence */
                   1329:            /* the clip rectangles should be sorted by x then by y as the
                   1330:                second order sort key */
                   1331:
                   1332:            /* clip rectangle list is terminated by y_min and y_max set to 0 */
                   1333:
                   1334:            /* to disable clipping set  y_min and y_max to 0 in the first
                   1335:                clip rectangle . The first clip rectangle is clip_list[0].
                   1336:              */
                   1337:
1.28      wiz      1338:
                   1339:
                   1340:            if (bktr->max_clip_node == 0 &&
                   1341:                (bktr->clip_list[0].y_min != 0 &&
1.1       wiz      1342:                 bktr->clip_list[0].y_max != 0)) {
                   1343:                return EINVAL;
                   1344:            }
                   1345:
1.27      mjl      1346:            for (i = 0; i < BT848_MAX_CLIP_NODE - 1; i++) {
1.1       wiz      1347:                if (bktr->clip_list[i].y_min == 0 &&
                   1348:                    bktr->clip_list[i].y_max == 0) {
                   1349:                    break;
                   1350:                }
1.28      wiz      1351:                if (bktr->clip_list[i+1].y_min != 0 &&
1.1       wiz      1352:                     bktr->clip_list[i+1].y_max != 0 &&
1.28      wiz      1353:                     bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min) {
1.1       wiz      1354:
                   1355:                    bktr->max_clip_node = 0;
                   1356:                    return (EINVAL);
                   1357:
                   1358:                 }
                   1359:
                   1360:                if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
                   1361:                    bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
                   1362:                    bktr->clip_list[i].x_min < 0 ||
1.28      wiz      1363:                    bktr->clip_list[i].x_max < 0 ||
1.1       wiz      1364:                    bktr->clip_list[i].y_min < 0 ||
1.28      wiz      1365:                    bktr->clip_list[i].y_max < 0) {
1.1       wiz      1366:                    bktr->max_clip_node = 0;
                   1367:                    return (EINVAL);
                   1368:                }
                   1369:            }
                   1370:
                   1371:            bktr->dma_prog_loaded = FALSE;
                   1372:
                   1373:            break;
                   1374:
                   1375:        case METEORSTATUS:      /* get Bt848 status */
                   1376:                c_temp = INB(bktr, BKTR_DSTATUS);
                   1377:                temp = 0;
                   1378:                if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
                   1379:                if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
                   1380:                *(u_short *)arg = temp;
                   1381:                break;
                   1382:
                   1383:        case BT848SFMT:         /* set input format */
1.46      jmcneill 1384:                temp = *(unsigned int*)arg & BT848_IFORM_FORMAT;
1.1       wiz      1385:                temp_iform = INB(bktr, BKTR_IFORM);
                   1386:                temp_iform &= ~BT848_IFORM_FORMAT;
                   1387:                temp_iform &= ~BT848_IFORM_XTSEL;
                   1388:                OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1.28      wiz      1389:                switch(temp) {
1.1       wiz      1390:                case BT848_IFORM_F_AUTO:
                   1391:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
                   1392:                        METEOR_AUTOMODE;
                   1393:                        break;
                   1394:
                   1395:                case BT848_IFORM_F_NTSCM:
                   1396:                case BT848_IFORM_F_NTSCJ:
                   1397:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
                   1398:                                METEOR_NTSC;
                   1399:                        OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
                   1400:                        OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
                   1401:                        bktr->format_params = temp;
                   1402:                        break;
                   1403:
                   1404:                case BT848_IFORM_F_PALBDGHI:
                   1405:                case BT848_IFORM_F_PALN:
                   1406:                case BT848_IFORM_F_SECAM:
                   1407:                case BT848_IFORM_F_RSVD:
                   1408:                case BT848_IFORM_F_PALM:
                   1409:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
                   1410:                                METEOR_PAL;
                   1411:                        OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
                   1412:                        OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
                   1413:                        bktr->format_params = temp;
                   1414:                        break;
                   1415:
                   1416:                }
1.28      wiz      1417:                bktr->dma_prog_loaded = FALSE;
1.1       wiz      1418:                break;
                   1419:
                   1420:        case METEORSFMT:        /* set input format */
                   1421:                temp_iform = INB(bktr, BKTR_IFORM);
                   1422:                temp_iform &= ~BT848_IFORM_FORMAT;
                   1423:                temp_iform &= ~BT848_IFORM_XTSEL;
1.46      jmcneill 1424:                switch(*(unsigned int *)arg & METEOR_FORM_MASK) {
1.1       wiz      1425:                case 0:         /* default */
                   1426:                case METEOR_FMT_NTSC:
                   1427:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
                   1428:                                METEOR_NTSC;
1.28      wiz      1429:                        OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1.1       wiz      1430:                                         format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
                   1431:                        OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
                   1432:                        OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
                   1433:                        bktr->format_params = BT848_IFORM_F_NTSCM;
                   1434:                        break;
                   1435:
                   1436:                case METEOR_FMT_PAL:
                   1437:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
                   1438:                                METEOR_PAL;
                   1439:                        OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
                   1440:                                         format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
                   1441:                        OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
                   1442:                        OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
                   1443:                        bktr->format_params = BT848_IFORM_F_PALBDGHI;
                   1444:                        break;
                   1445:
                   1446:                case METEOR_FMT_AUTOMODE:
                   1447:                        bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
                   1448:                                METEOR_AUTOMODE;
                   1449:                        OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
                   1450:                                         format_params[BT848_IFORM_F_AUTO].iform_xtsel);
                   1451:                        break;
                   1452:
                   1453:                default:
1.28      wiz      1454:                        return(EINVAL);
1.1       wiz      1455:                }
1.28      wiz      1456:                bktr->dma_prog_loaded = FALSE;
1.1       wiz      1457:                break;
                   1458:
                   1459:        case METEORGFMT:        /* get input format */
1.46      jmcneill 1460:                *(u_int *)arg = bktr->flags & METEOR_FORM_MASK;
1.1       wiz      1461:                break;
                   1462:
                   1463:
                   1464:        case BT848GFMT:         /* get input format */
1.46      jmcneill 1465:                *(u_int *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1.1       wiz      1466:                break;
1.28      wiz      1467:
1.1       wiz      1468:        case METEORSCOUNT:      /* (re)set error counts */
                   1469:                counts = (struct meteor_counts *) arg;
                   1470:                bktr->fifo_errors = counts->fifo_errors;
                   1471:                bktr->dma_errors = counts->dma_errors;
                   1472:                bktr->frames_captured = counts->frames_captured;
                   1473:                bktr->even_fields_captured = counts->even_fields_captured;
                   1474:                bktr->odd_fields_captured = counts->odd_fields_captured;
                   1475:                break;
                   1476:
                   1477:        case METEORGCOUNT:      /* get error counts */
                   1478:                counts = (struct meteor_counts *) arg;
                   1479:                counts->fifo_errors = bktr->fifo_errors;
                   1480:                counts->dma_errors = bktr->dma_errors;
                   1481:                counts->frames_captured = bktr->frames_captured;
                   1482:                counts->even_fields_captured = bktr->even_fields_captured;
                   1483:                counts->odd_fields_captured = bktr->odd_fields_captured;
                   1484:                break;
                   1485:
                   1486:        case METEORGVIDEO:
                   1487:                video = (struct meteor_video *)arg;
                   1488:                video->addr = bktr->video.addr;
                   1489:                video->width = bktr->video.width;
                   1490:                video->banksize = bktr->video.banksize;
                   1491:                video->ramsize = bktr->video.ramsize;
                   1492:                break;
                   1493:
                   1494:        case METEORSVIDEO:
                   1495:                video = (struct meteor_video *)arg;
                   1496:                bktr->video.addr = video->addr;
                   1497:                bktr->video.width = video->width;
                   1498:                bktr->video.banksize = video->banksize;
                   1499:                bktr->video.ramsize = video->ramsize;
                   1500:                break;
                   1501:
                   1502:        case METEORSFPS:
                   1503:                set_fps(bktr, *(u_short *)arg);
                   1504:                break;
                   1505:
                   1506:        case METEORGFPS:
                   1507:                *(u_short *)arg = bktr->fps;
                   1508:                break;
                   1509:
                   1510:        case METEORSHUE:        /* set hue */
                   1511:                OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
                   1512:                break;
                   1513:
                   1514:        case METEORGHUE:        /* get hue */
                   1515:                *(u_char *)arg = INB(bktr, BKTR_HUE);
                   1516:                break;
                   1517:
                   1518:        case METEORSBRIG:       /* set brightness */
1.28      wiz      1519:                char_temp =    (*(u_char *)arg & 0xff) - 128;
1.1       wiz      1520:                OUTB(bktr, BKTR_BRIGHT, char_temp);
1.28      wiz      1521:
1.1       wiz      1522:                break;
                   1523:
                   1524:        case METEORGBRIG:       /* get brightness */
1.28      wiz      1525:                *(u_char *)arg = INB(bktr, BKTR_BRIGHT) + 128;
1.1       wiz      1526:                break;
                   1527:
                   1528:        case METEORSCSAT:       /* set chroma saturation */
                   1529:                temp = (int)*(u_char *)arg;
                   1530:
                   1531:                OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
                   1532:                OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
                   1533:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
                   1534:                                     & ~(BT848_E_CONTROL_SAT_U_MSB
                   1535:                                         | BT848_E_CONTROL_SAT_V_MSB));
                   1536:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
                   1537:                                     & ~(BT848_O_CONTROL_SAT_U_MSB |
                   1538:                                         BT848_O_CONTROL_SAT_V_MSB));
                   1539:
1.28      wiz      1540:                if (temp & BIT_SEVEN_HIGH) {
1.1       wiz      1541:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
                   1542:                                             | (BT848_E_CONTROL_SAT_U_MSB
                   1543:                                                | BT848_E_CONTROL_SAT_V_MSB));
                   1544:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
                   1545:                                             | (BT848_O_CONTROL_SAT_U_MSB
                   1546:                                                | BT848_O_CONTROL_SAT_V_MSB));
                   1547:                }
                   1548:                break;
                   1549:
                   1550:        case METEORGCSAT:       /* get chroma saturation */
                   1551:                temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1.28      wiz      1552:                if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB)
1.1       wiz      1553:                        temp |= BIT_SEVEN_HIGH;
                   1554:                *(u_char *)arg = (u_char)temp;
                   1555:                break;
                   1556:
                   1557:        case METEORSCONT:       /* set contrast */
                   1558:                temp = (int)*(u_char *)arg & 0xff;
                   1559:                temp <<= 1;
                   1560:                OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
                   1561:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
                   1562:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
                   1563:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1.28      wiz      1564:                        (((temp & 0x100) >> 6) & BT848_E_CONTROL_CON_MSB));
1.1       wiz      1565:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1.28      wiz      1566:                        (((temp & 0x100) >> 6) & BT848_O_CONTROL_CON_MSB));
1.1       wiz      1567:                break;
                   1568:
                   1569:        case METEORGCONT:       /* get contrast */
                   1570:                temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
                   1571:                temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
                   1572:                *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
                   1573:                break;
                   1574:
                   1575:        case BT848SCBUF:        /* set Clear-Buffer-on-start flag */
                   1576:                bktr->clr_on_start = (*(int *)arg != 0);
                   1577:                break;
                   1578:
                   1579:        case BT848GCBUF:        /* get Clear-Buffer-on-start flag */
                   1580:                *(int *)arg = (int) bktr->clr_on_start;
                   1581:                break;
                   1582:
                   1583:        case METEORSSIGNAL:
                   1584:                if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
1.28      wiz      1585:                        return(EINVAL);
1.1       wiz      1586:                        break;
                   1587:                }
                   1588:                bktr->signal = *(int *) arg;
1.28      wiz      1589: #ifdef __FreeBSD__
                   1590:                bktr->proc = td->td_proc;
                   1591: #else
1.36      christos 1592:                bktr->proc = l->l_proc;
1.28      wiz      1593: #endif
1.1       wiz      1594:                break;
                   1595:
                   1596:        case METEORGSIGNAL:
                   1597:                *(int *)arg = bktr->signal;
                   1598:                break;
                   1599:
                   1600:        case METEORCAPTUR:
                   1601:                temp = bktr->flags;
                   1602:                switch (*(int *) arg) {
                   1603:                case METEOR_CAP_SINGLE:
                   1604:
                   1605:                        if (bktr->bigbuf==0)    /* no frame buffer allocated */
1.28      wiz      1606:                                return(ENOMEM);
1.1       wiz      1607:                        /* already capturing */
                   1608:                        if (temp & METEOR_CAP_MASK)
1.28      wiz      1609:                                return(EIO);
1.1       wiz      1610:
                   1611:
                   1612:
                   1613:                        start_capture(bktr, METEOR_SINGLE);
                   1614:
                   1615:                        /* wait for capture to complete */
                   1616:                        OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
                   1617:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
                   1618:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
                   1619:
                   1620:                        OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1.25      toshii   1621:                                            BT848_INT_RISCI      |
1.1       wiz      1622:                                            BT848_INT_VSYNC      |
                   1623:                                            BT848_INT_FMTCHG);
                   1624:
                   1625:                        OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
                   1626:                        error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
                   1627:                        if (error && (error != ERESTART)) {
                   1628:                                /*  Here if we didn't get complete frame  */
                   1629: #ifdef DIAGNOSTIC
1.28      wiz      1630:                                printf("%s: ioctl: tsleep error %d %x\n",
1.4       wiz      1631:                                        bktr_name(bktr), error,
                   1632:                                        INL(bktr, BKTR_RISC_COUNT));
1.1       wiz      1633: #endif
                   1634:
1.31      wiz      1635:                                /* stop DMA */
1.1       wiz      1636:                                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
                   1637:
                   1638:                                /* disable risc, leave fifo running */
                   1639:                                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
                   1640:                        }
                   1641:
                   1642:                        bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
                   1643:                        /* FIXME: should we set bt848->int_stat ??? */
                   1644:                        break;
                   1645:
                   1646:                case METEOR_CAP_CONTINOUS:
                   1647:                        if (bktr->bigbuf==0)    /* no frame buffer allocated */
1.28      wiz      1648:                                return(ENOMEM);
1.1       wiz      1649:                        /* already capturing */
                   1650:                        if (temp & METEOR_CAP_MASK)
1.28      wiz      1651:                            return(EIO);
1.1       wiz      1652:
                   1653:
                   1654:                        start_capture(bktr, METEOR_CONTIN);
                   1655:
                   1656:                        /* Clear the interrypt status register */
                   1657:                        OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
                   1658:
                   1659:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
                   1660:                        OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
                   1661:                        OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
                   1662:
                   1663:                        OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
                   1664:                                            BT848_INT_RISCI      |
                   1665:                                            BT848_INT_VSYNC      |
                   1666:                                            BT848_INT_FMTCHG);
                   1667: #ifdef BT848_DUMP
1.28      wiz      1668:                        dump_bt848(bt848);
1.1       wiz      1669: #endif
                   1670:                        break;
1.28      wiz      1671:
1.1       wiz      1672:                case METEOR_CAP_STOP_CONT:
                   1673:                        if (bktr->flags & METEOR_CONTIN) {
                   1674:                                /* turn off capture */
                   1675:                                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
                   1676:                                OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
                   1677:                                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
                   1678:                                bktr->flags &=
                   1679:                                        ~(METEOR_CONTIN | METEOR_WANT_MASK);
                   1680:
                   1681:                        }
                   1682:                }
                   1683:                break;
                   1684:
                   1685:        case METEORSETGEO:
                   1686:                /* can't change parameters while capturing */
                   1687:                if (bktr->flags & METEOR_CAP_MASK)
1.28      wiz      1688:                        return(EBUSY);
1.1       wiz      1689:
                   1690:
                   1691:                geo = (struct meteor_geomet *) arg;
                   1692:
                   1693:                error = 0;
                   1694:                /* Either even or odd, if even & odd, then these a zero */
                   1695:                if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
                   1696:                        (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1.28      wiz      1697:                        printf("%s: ioctl: Geometry odd or even only.\n",
1.4       wiz      1698:                                bktr_name(bktr));
1.28      wiz      1699:                        return(EINVAL);
1.1       wiz      1700:                }
                   1701:
                   1702:                /* set/clear even/odd flags */
                   1703:                if (geo->oformat & METEOR_GEO_ODD_ONLY)
                   1704:                        bktr->flags |= METEOR_ONLY_ODD_FIELDS;
                   1705:                else
                   1706:                        bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
                   1707:                if (geo->oformat & METEOR_GEO_EVEN_ONLY)
                   1708:                        bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
                   1709:                else
                   1710:                        bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
                   1711:
                   1712:                if (geo->columns <= 0) {
                   1713:                        printf(
1.4       wiz      1714:                        "%s: ioctl: %d: columns must be greater than zero.\n",
                   1715:                                bktr_name(bktr), geo->columns);
1.1       wiz      1716:                        error = EINVAL;
                   1717:                }
                   1718:                else if ((geo->columns & 0x3fe) != geo->columns) {
                   1719:                        printf(
1.4       wiz      1720:                        "%s: ioctl: %d: columns too large or not even.\n",
                   1721:                                bktr_name(bktr), geo->columns);
1.1       wiz      1722:                        error = EINVAL;
                   1723:                }
                   1724:
                   1725:                if (geo->rows <= 0) {
                   1726:                        printf(
1.4       wiz      1727:                        "%s: ioctl: %d: rows must be greater than zero.\n",
                   1728:                                bktr_name(bktr), geo->rows);
1.1       wiz      1729:                        error = EINVAL;
                   1730:                }
                   1731:                else if (((geo->rows & 0x7fe) != geo->rows) ||
                   1732:                        ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1.28      wiz      1733:                                ((geo->rows & 0x3fe) != geo->rows))) {
1.1       wiz      1734:                        printf(
1.4       wiz      1735:                        "%s: ioctl: %d: rows too large or not even.\n",
                   1736:                                bktr_name(bktr), geo->rows);
1.1       wiz      1737:                        error = EINVAL;
                   1738:                }
                   1739:
                   1740:                if (geo->frames > 32) {
1.4       wiz      1741:                        printf("%s: ioctl: too many frames.\n",
                   1742:                               bktr_name(bktr));
1.1       wiz      1743:
                   1744:                        error = EINVAL;
                   1745:                }
                   1746:
                   1747:                if (error)
1.28      wiz      1748:                        return(error);
1.1       wiz      1749:
                   1750:                bktr->dma_prog_loaded = FALSE;
                   1751:                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
                   1752:
                   1753:                OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
                   1754:
                   1755:                if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
                   1756:                        if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
                   1757:
                   1758:                        /* meteor_mem structure for SYNC Capture */
                   1759:                        if (geo->frames > 1) temp += PAGE_SIZE;
                   1760:
                   1761:                        temp = btoc(temp);
                   1762:                        if ((int) temp > bktr->alloc_pages
                   1763:                            && bktr->video.addr == 0) {
                   1764:
                   1765: /*****************************/
                   1766: /* *** OS Dependant code *** */
                   1767: /*****************************/
                   1768: #if defined(__NetBSD__) || defined(__OpenBSD__)
                   1769:                                 bus_dmamap_t dmamap;
                   1770:
1.34      christos 1771:                                 sbuf = get_bktr_mem(bktr, &dmamap,
1.1       wiz      1772:                                                    temp * PAGE_SIZE);
1.34      christos 1773:                                 if (sbuf != 0) {
1.1       wiz      1774:                                         free_bktr_mem(bktr, bktr->dm_mem,
                   1775:                                                       bktr->bigbuf);
                   1776:                                         bktr->dm_mem = dmamap;
                   1777:
                   1778: #else
1.34      christos 1779:                                 sbuf = get_bktr_mem(unit, temp*PAGE_SIZE);
                   1780:                                 if (sbuf != 0) {
1.1       wiz      1781:                                         kmem_free(kernel_map, bktr->bigbuf,
                   1782:                                           (bktr->alloc_pages * PAGE_SIZE));
1.28      wiz      1783: #endif
1.1       wiz      1784:
1.34      christos 1785:                                        bktr->bigbuf = sbuf;
1.1       wiz      1786:                                        bktr->alloc_pages = temp;
                   1787:                                        if (bootverbose)
                   1788:                                                printf(
1.4       wiz      1789:                                "%s: ioctl: Allocating %d bytes\n",
                   1790:                                                        bktr_name(bktr), temp*PAGE_SIZE);
1.1       wiz      1791:                                }
                   1792:                                else
                   1793:                                        error = ENOMEM;
                   1794:                        }
                   1795:                }
                   1796:
                   1797:                if (error)
                   1798:                        return error;
                   1799:
                   1800:                bktr->rows = geo->rows;
                   1801:                bktr->cols = geo->columns;
                   1802:                bktr->frames = geo->frames;
                   1803:
                   1804:                /*  Pixel format (if in meteor pixfmt compatibility mode)  */
1.28      wiz      1805:                if (bktr->pixfmt_compat) {
1.1       wiz      1806:                        bktr->format = METEOR_GEO_YUV_422;
                   1807:                        switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
                   1808:                        case 0:                 /* default */
                   1809:                        case METEOR_GEO_RGB16:
                   1810:                                    bktr->format = METEOR_GEO_RGB16;
                   1811:                                    break;
                   1812:                        case METEOR_GEO_RGB24:
                   1813:                                    bktr->format = METEOR_GEO_RGB24;
                   1814:                                    break;
                   1815:                        case METEOR_GEO_YUV_422:
                   1816:                                    bktr->format = METEOR_GEO_YUV_422;
1.28      wiz      1817:                                     if (geo->oformat & METEOR_GEO_YUV_12)
1.1       wiz      1818:                                        bktr->format = METEOR_GEO_YUV_12;
                   1819:                                    break;
                   1820:                        case METEOR_GEO_YUV_PACKED:
                   1821:                                    bktr->format = METEOR_GEO_YUV_PACKED;
                   1822:                                    break;
                   1823:                        }
1.28      wiz      1824:                        bktr->pixfmt = oformat_meteor_to_bt(bktr->format);
1.1       wiz      1825:                }
                   1826:
                   1827:                if (bktr->flags & METEOR_CAP_MASK) {
                   1828:
                   1829:                        if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
                   1830:                                switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
                   1831:                                case METEOR_ONLY_ODD_FIELDS:
                   1832:                                        bktr->flags |= METEOR_WANT_ODD;
                   1833:                                        break;
                   1834:                                case METEOR_ONLY_EVEN_FIELDS:
                   1835:                                        bktr->flags |= METEOR_WANT_EVEN;
                   1836:                                        break;
                   1837:                                default:
                   1838:                                        bktr->flags |= METEOR_WANT_MASK;
                   1839:                                        break;
                   1840:                                }
                   1841:
                   1842:                                start_capture(bktr, METEOR_CONTIN);
                   1843:                                OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
                   1844:                                OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
                   1845:                                OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
                   1846:                                OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
                   1847:                                                    BT848_INT_VSYNC      |
                   1848:                                                    BT848_INT_FMTCHG);
                   1849:                        }
                   1850:                }
                   1851:                break;
                   1852:        /* end of METEORSETGEO */
                   1853:
                   1854:        /* FIXME. The Capture Area currently has the following restrictions:
                   1855:        GENERAL
                   1856:         y_offset may need to be even in interlaced modes
                   1857:        RGB24 - Interlaced mode
                   1858:         x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
                   1859:         y_size must be greater than or equal to METEORSETGEO height (rows)
                   1860:        RGB24 - Even Only (or Odd Only) mode
                   1861:         x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
                   1862:         y_size must be greater than or equal to 2*METEORSETGEO height (rows)
                   1863:        YUV12 - Interlaced mode
                   1864:         x_size must be greater than or equal to METEORSETGEO width (cols)
                   1865:         y_size must be greater than or equal to METEORSETGEO height (rows)
                   1866:        YUV12 - Even Only (or Odd Only) mode
                   1867:         x_size must be greater than or equal to METEORSETGEO width (cols)
                   1868:         y_size must be greater than or equal to 2*METEORSETGEO height (rows)
                   1869:        */
                   1870:
                   1871:        case BT848_SCAPAREA: /* set capture area of each video frame */
                   1872:                /* can't change parameters while capturing */
                   1873:                if (bktr->flags & METEOR_CAP_MASK)
1.28      wiz      1874:                        return(EBUSY);
1.1       wiz      1875:
                   1876:                cap_area = (struct bktr_capture_area *) arg;
                   1877:                bktr->capture_area_x_offset = cap_area->x_offset;
                   1878:                bktr->capture_area_y_offset = cap_area->y_offset;
                   1879:                bktr->capture_area_x_size   = cap_area->x_size;
                   1880:                bktr->capture_area_y_size   = cap_area->y_size;
                   1881:                bktr->capture_area_enabled  = TRUE;
1.28      wiz      1882:
1.1       wiz      1883:                bktr->dma_prog_loaded = FALSE;
                   1884:                break;
1.28      wiz      1885:
1.1       wiz      1886:        case BT848_GCAPAREA: /* get capture area of each video frame */
                   1887:                cap_area = (struct bktr_capture_area *) arg;
                   1888:                if (bktr->capture_area_enabled == FALSE) {
                   1889:                        cap_area->x_offset = 0;
                   1890:                        cap_area->y_offset = 0;
                   1891:                        cap_area->x_size   = format_params[
                   1892:                                bktr->format_params].scaled_hactive;
                   1893:                        cap_area->y_size   = format_params[
                   1894:                                bktr->format_params].vactive;
                   1895:                } else {
                   1896:                        cap_area->x_offset = bktr->capture_area_x_offset;
                   1897:                        cap_area->y_offset = bktr->capture_area_y_offset;
                   1898:                        cap_area->x_size   = bktr->capture_area_x_size;
                   1899:                        cap_area->y_size   = bktr->capture_area_y_size;
                   1900:                }
                   1901:                break;
                   1902:
                   1903:        default:
1.28      wiz      1904:                return common_ioctl(bktr, cmd, arg);
1.1       wiz      1905:        }
                   1906:
1.28      wiz      1907:        return(0);
1.1       wiz      1908: }
                   1909:
                   1910: /*
                   1911:  * tuner ioctls
                   1912:  */
1.28      wiz      1913: #ifdef __FreeBSD__
                   1914: int
1.42      christos 1915: tuner_ioctl(bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, void *arg, struct thread* td)
1.28      wiz      1916: #else
1.1       wiz      1917: int
1.42      christos 1918: tuner_ioctl(bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, void *arg,
1.40      christos 1919:     struct lwp* l)
1.28      wiz      1920: #endif
1.1       wiz      1921: {
                   1922:        int             tmp_int;
                   1923:        unsigned int    temp, temp1;
                   1924:        int             offset;
                   1925:        int             count;
1.34      christos 1926:        u_char          *sbuf;
1.46      jmcneill 1927:        u_int          par;
1.1       wiz      1928:        u_char          write;
                   1929:        int             i2c_addr;
                   1930:        int             i2c_port;
1.46      jmcneill 1931:        u_int          data;
1.1       wiz      1932:
1.28      wiz      1933:        switch (cmd) {
1.1       wiz      1934:
                   1935:        case REMOTE_GETKEY:
                   1936:                /* Read the last key pressed by the Remote Control */
                   1937:                if (bktr->remote_control == 0) return (EINVAL);
                   1938:                remote_read(bktr, (struct bktr_remote *)arg);
                   1939:                break;
                   1940:
1.28      wiz      1941: #if defined(TUNER_AFC)
1.1       wiz      1942:        case TVTUNER_SETAFC:
                   1943:                bktr->tuner.afc = (*(int *)arg != 0);
                   1944:                break;
                   1945:
                   1946:        case TVTUNER_GETAFC:
                   1947:                *(int *)arg = bktr->tuner.afc;
                   1948:                /* XXX Perhaps use another bit to indicate AFC success? */
                   1949:                break;
                   1950: #endif /* TUNER_AFC */
                   1951:
                   1952:        case TVTUNER_SETCHNL:
1.28      wiz      1953:                temp_mute(bktr, TRUE);
1.46      jmcneill 1954:                temp = tv_channel(bktr, (int)*(unsigned int *)arg);
                   1955:                *(unsigned int *)arg = temp;
1.1       wiz      1956:
                   1957:                /* after every channel change, we must restart the MSP34xx */
                   1958:                /* audio chip to reselect NICAM STEREO or MONO audio */
1.28      wiz      1959:                if (bktr->card.msp3400c)
                   1960:                  msp_autodetect(bktr);
1.1       wiz      1961:
                   1962:                /* after every channel change, we must restart the DPL35xx */
1.28      wiz      1963:                if (bktr->card.dpl3518a)
                   1964:                  dpl_autodetect(bktr);
1.1       wiz      1965:
1.28      wiz      1966:                temp_mute(bktr, FALSE);
1.1       wiz      1967:                break;
                   1968:
                   1969:        case TVTUNER_GETCHNL:
1.46      jmcneill 1970:                *(unsigned int *)arg = bktr->tuner.channel;
1.1       wiz      1971:                break;
                   1972:
                   1973:        case TVTUNER_SETTYPE:
1.46      jmcneill 1974:                temp = *(unsigned int *)arg;
1.28      wiz      1975:                if ((temp < CHNLSET_MIN) || (temp > CHNLSET_MAX))
                   1976:                        return(EINVAL);
1.1       wiz      1977:                bktr->tuner.chnlset = temp;
                   1978:                break;
                   1979:
                   1980:        case TVTUNER_GETTYPE:
1.46      jmcneill 1981:                *(unsigned int *)arg = bktr->tuner.chnlset;
1.1       wiz      1982:                break;
                   1983:
                   1984:        case TVTUNER_GETSTATUS:
1.28      wiz      1985:                temp = get_tuner_status(bktr);
1.46      jmcneill 1986:                *(unsigned int *)arg = temp & 0xff;
1.1       wiz      1987:                break;
                   1988:
                   1989:        case TVTUNER_SETFREQ:
1.28      wiz      1990:                temp_mute(bktr, TRUE);
1.46      jmcneill 1991:                temp = tv_freq(bktr, (int)*(unsigned int *)arg, TV_FREQUENCY);
1.28      wiz      1992:                temp_mute(bktr, FALSE);
1.46      jmcneill 1993:                *(unsigned int *)arg = temp;
1.1       wiz      1994:
                   1995:                /* after every channel change, we must restart the MSP34xx */
                   1996:                /* audio chip to reselect NICAM STEREO or MONO audio */
1.28      wiz      1997:                if (bktr->card.msp3400c)
                   1998:                  msp_autodetect(bktr);
1.1       wiz      1999:
                   2000:                /* after every channel change, we must restart the DPL35xx */
1.28      wiz      2001:                if (bktr->card.dpl3518a)
                   2002:                  dpl_autodetect(bktr);
1.1       wiz      2003:
1.28      wiz      2004:                temp_mute(bktr, FALSE);
1.1       wiz      2005:                break;
                   2006:
                   2007:        case TVTUNER_GETFREQ:
1.46      jmcneill 2008:                *(unsigned int *)arg = bktr->tuner.frequency;
1.1       wiz      2009:                break;
                   2010:
                   2011:        case TVTUNER_GETCHNLSET:
                   2012:                return tuner_getchnlset((struct bktr_chnlset *)arg);
                   2013:
                   2014:        case BT848_SAUDIO:      /* set audio channel */
1.28      wiz      2015:                if (set_audio(bktr, *(int*)arg) < 0)
                   2016:                        return(EIO);
1.1       wiz      2017:                break;
                   2018:
                   2019:        /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
                   2020:        case BT848_SHUE:        /* set hue */
                   2021:                OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
                   2022:                break;
                   2023:
                   2024:        case BT848_GHUE:        /* get hue */
                   2025:                *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
                   2026:                break;
                   2027:
                   2028:        /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
                   2029:        case BT848_SBRIG:       /* set brightness */
                   2030:                OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
                   2031:                break;
                   2032:
                   2033:        case BT848_GBRIG:       /* get brightness */
                   2034:                *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
                   2035:                break;
                   2036:
                   2037:        /*  */
                   2038:        case BT848_SCSAT:       /* set chroma saturation */
                   2039:                tmp_int = *(int*)arg;
                   2040:
                   2041:                temp = INB(bktr, BKTR_E_CONTROL);
                   2042:                temp1 = INB(bktr, BKTR_O_CONTROL);
1.28      wiz      2043:                if (tmp_int & BIT_EIGHT_HIGH) {
1.1       wiz      2044:                        temp |= (BT848_E_CONTROL_SAT_U_MSB |
                   2045:                                 BT848_E_CONTROL_SAT_V_MSB);
                   2046:                        temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
                   2047:                                  BT848_O_CONTROL_SAT_V_MSB);
                   2048:                }
                   2049:                else {
                   2050:                        temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
                   2051:                                  BT848_E_CONTROL_SAT_V_MSB);
                   2052:                        temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
                   2053:                                   BT848_O_CONTROL_SAT_V_MSB);
                   2054:                }
                   2055:
                   2056:                OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
                   2057:                OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
                   2058:                OUTB(bktr, BKTR_E_CONTROL, temp);
                   2059:                OUTB(bktr, BKTR_O_CONTROL, temp1);
                   2060:                break;
                   2061:
                   2062:        case BT848_GCSAT:       /* get chroma saturation */
                   2063:                tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1.28      wiz      2064:                if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB)
1.1       wiz      2065:                        tmp_int |= BIT_EIGHT_HIGH;
                   2066:                *(int*)arg = tmp_int;
                   2067:                break;
                   2068:
                   2069:        /*  */
                   2070:        case BT848_SVSAT:       /* set chroma V saturation */
                   2071:                tmp_int = *(int*)arg;
                   2072:
                   2073:                temp = INB(bktr, BKTR_E_CONTROL);
                   2074:                temp1 = INB(bktr, BKTR_O_CONTROL);
1.28      wiz      2075:                if (tmp_int & BIT_EIGHT_HIGH) {
1.1       wiz      2076:                        temp |= BT848_E_CONTROL_SAT_V_MSB;
                   2077:                        temp1 |= BT848_O_CONTROL_SAT_V_MSB;
                   2078:                }
                   2079:                else {
                   2080:                        temp &= ~BT848_E_CONTROL_SAT_V_MSB;
                   2081:                        temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
                   2082:                }
                   2083:
                   2084:                OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
                   2085:                OUTB(bktr, BKTR_E_CONTROL, temp);
                   2086:                OUTB(bktr, BKTR_O_CONTROL, temp1);
                   2087:                break;
                   2088:
                   2089:        case BT848_GVSAT:       /* get chroma V saturation */
                   2090:                tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1.28      wiz      2091:                if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB)
1.1       wiz      2092:                        tmp_int |= BIT_EIGHT_HIGH;
                   2093:                *(int*)arg = tmp_int;
                   2094:                break;
                   2095:
                   2096:        /*  */
                   2097:        case BT848_SUSAT:       /* set chroma U saturation */
                   2098:                tmp_int = *(int*)arg;
                   2099:
                   2100:                temp = INB(bktr, BKTR_E_CONTROL);
                   2101:                temp1 = INB(bktr, BKTR_O_CONTROL);
1.28      wiz      2102:                if (tmp_int & BIT_EIGHT_HIGH) {
1.1       wiz      2103:                        temp |= BT848_E_CONTROL_SAT_U_MSB;
                   2104:                        temp1 |= BT848_O_CONTROL_SAT_U_MSB;
                   2105:                }
                   2106:                else {
                   2107:                        temp &= ~BT848_E_CONTROL_SAT_U_MSB;
                   2108:                        temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
                   2109:                }
                   2110:
                   2111:                OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
                   2112:                OUTB(bktr, BKTR_E_CONTROL, temp);
                   2113:                OUTB(bktr, BKTR_O_CONTROL, temp1);
                   2114:                break;
                   2115:
                   2116:        case BT848_GUSAT:       /* get chroma U saturation */
                   2117:                tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
1.28      wiz      2118:                if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB)
1.1       wiz      2119:                        tmp_int |= BIT_EIGHT_HIGH;
                   2120:                *(int*)arg = tmp_int;
                   2121:                break;
                   2122:
                   2123: /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
                   2124:
                   2125:        case BT848_SLNOTCH:     /* set luma notch */
1.27      mjl      2126:                tmp_int = (*(int *)arg & 0x7) << 5;
1.1       wiz      2127:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
                   2128:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
                   2129:                OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
                   2130:                OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
                   2131:                break;
                   2132:
                   2133:        case BT848_GLNOTCH:     /* get luma notch */
1.28      wiz      2134:                *(int *)arg = (int) ((INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5);
1.1       wiz      2135:                break;
                   2136:
                   2137:
                   2138:        /*  */
                   2139:        case BT848_SCONT:       /* set contrast */
                   2140:                tmp_int = *(int*)arg;
                   2141:
                   2142:                temp = INB(bktr, BKTR_E_CONTROL);
                   2143:                temp1 = INB(bktr, BKTR_O_CONTROL);
1.28      wiz      2144:                if (tmp_int & BIT_EIGHT_HIGH) {
1.1       wiz      2145:                        temp |= BT848_E_CONTROL_CON_MSB;
                   2146:                        temp1 |= BT848_O_CONTROL_CON_MSB;
                   2147:                }
                   2148:                else {
                   2149:                        temp &= ~BT848_E_CONTROL_CON_MSB;
                   2150:                        temp1 &= ~BT848_O_CONTROL_CON_MSB;
                   2151:                }
                   2152:
                   2153:                OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
                   2154:                OUTB(bktr, BKTR_E_CONTROL, temp);
                   2155:                OUTB(bktr, BKTR_O_CONTROL, temp1);
                   2156:                break;
                   2157:
                   2158:        case BT848_GCONT:       /* get contrast */
                   2159:                tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1.28      wiz      2160:                if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB)
1.1       wiz      2161:                        tmp_int |= BIT_EIGHT_HIGH;
                   2162:                *(int*)arg = tmp_int;
                   2163:                break;
                   2164:
                   2165:                /*  FIXME:  SCBARS and CCBARS require a valid int *        */
                   2166:                /*    argument to succeed, but its not used; consider      */
                   2167:                /*    using the arg to store the on/off state so           */
                   2168:                /*    there's only one ioctl() needed to turn cbars on/off */
                   2169:        case BT848_SCBARS:      /* set colorbar output */
                   2170:                OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
                   2171:                break;
                   2172:
                   2173:        case BT848_CCBARS:      /* clear colorbar output */
                   2174:                OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
                   2175:                break;
                   2176:
                   2177:        case BT848_GAUDIO:      /* get audio channel */
                   2178:                temp = bktr->audio_mux_select;
1.28      wiz      2179:                if (bktr->audio_mute_state == TRUE)
1.1       wiz      2180:                        temp |= AUDIO_MUTE;
                   2181:                *(int*)arg = temp;
                   2182:                break;
                   2183:
                   2184:        case BT848_SBTSC:       /* set audio channel */
1.28      wiz      2185:                if (set_BTSC(bktr, *(int*)arg) < 0)
                   2186:                        return(EIO);
1.1       wiz      2187:                break;
                   2188:
                   2189:        case BT848_WEEPROM:     /* write eeprom */
                   2190:                offset = (((struct eeProm *)arg)->offset);
                   2191:                count = (((struct eeProm *)arg)->count);
1.34      christos 2192:                sbuf = &(((struct eeProm *)arg)->bytes[0]);
                   2193:                if (writeEEProm(bktr, offset, count, sbuf) < 0)
1.28      wiz      2194:                        return(EIO);
1.1       wiz      2195:                break;
                   2196:
                   2197:        case BT848_REEPROM:     /* read eeprom */
                   2198:                offset = (((struct eeProm *)arg)->offset);
                   2199:                count = (((struct eeProm *)arg)->count);
1.34      christos 2200:                sbuf = &(((struct eeProm *)arg)->bytes[0]);
                   2201:                if (readEEProm(bktr, offset, count, sbuf) < 0)
1.28      wiz      2202:                        return(EIO);
1.1       wiz      2203:                break;
                   2204:
                   2205:        case BT848_SIGNATURE:
                   2206:                offset = (((struct eeProm *)arg)->offset);
                   2207:                count = (((struct eeProm *)arg)->count);
1.34      christos 2208:                sbuf = &(((struct eeProm *)arg)->bytes[0]);
                   2209:                if (signCard(bktr, offset, count, sbuf) < 0)
1.28      wiz      2210:                        return(EIO);
1.1       wiz      2211:                break;
                   2212:
                   2213:         /* Ioctl's for direct gpio access */
                   2214: #ifdef BKTR_GPIO_ACCESS
                   2215:         case BT848_GPIO_GET_EN:
                   2216:                 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
                   2217:                 break;
                   2218:
                   2219:         case BT848_GPIO_SET_EN:
                   2220:                 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
                   2221:                 break;
                   2222:
                   2223:         case BT848_GPIO_GET_DATA:
                   2224:                 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
                   2225:                 break;
                   2226:
                   2227:         case BT848_GPIO_SET_DATA:
                   2228:                 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
                   2229:                 break;
                   2230: #endif /* BKTR_GPIO_ACCESS */
                   2231:
                   2232:        /* Ioctl's for running the tuner device in radio mode           */
                   2233:
                   2234:        case RADIO_GETMODE:
                   2235:             *(unsigned char *)arg = bktr->tuner.radio_mode;
                   2236:            break;
                   2237:
                   2238:        case RADIO_SETMODE:
                   2239:             bktr->tuner.radio_mode = *(unsigned char *)arg;
                   2240:             break;
                   2241:
1.25      toshii   2242:        case RADIO_GETFREQ:
1.46      jmcneill 2243:             *(unsigned int *)arg = bktr->tuner.frequency;
1.1       wiz      2244:             break;
                   2245:
                   2246:        case RADIO_SETFREQ:
                   2247:            /* The argument to this ioctl is NOT freq*16. It is
                   2248:            ** freq*100.
                   2249:            */
                   2250:
1.46      jmcneill 2251:             temp=(int)*(unsigned int *)arg;
1.1       wiz      2252:
                   2253: #ifdef BKTR_RADIO_DEBUG
1.4       wiz      2254:            printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
1.46      jmcneill 2255:                   (int)*(unsigned int *)arg, temp);
1.1       wiz      2256: #endif
                   2257:
                   2258: #ifndef BKTR_RADIO_NOFREQCHECK
                   2259:            /* According to the spec. sheet the band: 87.5MHz-108MHz    */
                   2260:            /* is supported.                                            */
                   2261:            if(temp<8750 || temp>10800) {
1.4       wiz      2262:              printf("%s: Radio frequency out of range\n", bktr_name(bktr));
1.1       wiz      2263:              return(EINVAL);
                   2264:              }
                   2265: #endif
1.28      wiz      2266:            temp_mute(bktr, TRUE);
                   2267:            temp = tv_freq(bktr, temp, FM_RADIO_FREQUENCY);
                   2268:            temp_mute(bktr, FALSE);
1.1       wiz      2269: #ifdef BKTR_RADIO_DEBUG
                   2270:   if(temp)
1.4       wiz      2271:     printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
1.1       wiz      2272: #endif
1.46      jmcneill 2273:            *(unsigned int *)arg = temp;
1.1       wiz      2274:            break;
                   2275:
1.28      wiz      2276:        /* Luigi's I2CWR ioctl */
1.1       wiz      2277:        case BT848_I2CWR:
1.46      jmcneill 2278:                par = *(u_int *)arg;
1.27      mjl      2279:                write = (par >> 24) & 0xff;
                   2280:                i2c_addr = (par >> 16) & 0xff;
                   2281:                i2c_port = (par >> 8) & 0xff;
                   2282:                data = (par) & 0xff;
1.28      wiz      2283:
                   2284:                if (write) {
                   2285:                        i2cWrite(bktr, i2c_addr, i2c_port, data);
1.1       wiz      2286:                } else {
1.28      wiz      2287:                        data = i2cRead(bktr, i2c_addr);
1.1       wiz      2288:                }
1.46      jmcneill 2289:                *(u_int *)arg = (par & 0xffffff00) | (data & 0xff);
1.1       wiz      2290:                break;
                   2291:
1.14      wiz      2292:
                   2293: #ifdef BT848_MSP_READ
                   2294:        /* I2C ioctls to allow userland access to the MSP chip */
                   2295:        case BT848_MSP_READ:
                   2296:                {
                   2297:                struct bktr_msp_control *msp;
                   2298:                msp = (struct bktr_msp_control *) arg;
                   2299:                msp->data = msp_dpl_read(bktr, bktr->msp_addr,
                   2300:                                         msp->function, msp->address);
                   2301:                break;
                   2302:                }
                   2303:
                   2304:        case BT848_MSP_WRITE:
                   2305:                {
                   2306:                struct bktr_msp_control *msp;
                   2307:                msp = (struct bktr_msp_control *) arg;
                   2308:                msp_dpl_write(bktr, bktr->msp_addr, msp->function,
1.28      wiz      2309:                             msp->address, msp->data);
1.14      wiz      2310:                break;
                   2311:                }
                   2312:
                   2313:        case BT848_MSP_RESET:
                   2314:                msp_dpl_reset(bktr, bktr->msp_addr);
                   2315:                break;
                   2316: #endif
1.1       wiz      2317:
                   2318:        default:
1.28      wiz      2319:                return common_ioctl(bktr, cmd, arg);
1.1       wiz      2320:        }
                   2321:
1.28      wiz      2322:        return(0);
1.1       wiz      2323: }
                   2324:
                   2325:
                   2326: /*
                   2327:  * common ioctls
                   2328:  */
1.24      toshii   2329: static int
1.42      christos 2330: common_ioctl(bktr_ptr_t bktr, ioctl_cmd_t cmd, void *arg)
1.1       wiz      2331: {
                   2332:         int                           pixfmt;
                   2333:        unsigned int                  temp;
                   2334:        struct meteor_pixfmt          *pf_pub;
                   2335:
                   2336:        switch (cmd) {
                   2337:
                   2338:        case METEORSINPUT:      /* set input device */
                   2339:                /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
                   2340:                /* On the original bt848 boards, */
                   2341:                /*   Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
                   2342:                /* On the Hauppauge bt878 boards, */
                   2343:                /*   Tuner is MUX0, RCA is MUX3 */
                   2344:                /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
                   2345:                /* stick with this system in our Meteor Emulation */
                   2346:
1.46      jmcneill 2347:                switch(*(unsigned int *)arg & METEOR_DEV_MASK) {
1.1       wiz      2348:
                   2349:                /* this is the RCA video input */
                   2350:                case 0:         /* default */
                   2351:                case METEOR_INPUT_DEV0:
                   2352:                  /* METEOR_INPUT_DEV_RCA: */
                   2353:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
                   2354:                          | METEOR_DEV0;
                   2355:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
                   2356:                                         & ~BT848_IFORM_MUXSEL);
                   2357:
                   2358:                        /* work around for new Hauppauge 878 cards */
                   2359:                        if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
                   2360:                                (bktr->id==BROOKTREE_878 ||
1.28      wiz      2361:                                 bktr->id==BROOKTREE_879))
1.1       wiz      2362:                                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
                   2363:                        else
                   2364:                                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
                   2365:
                   2366:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
                   2367:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
1.28      wiz      2368:                        set_audio(bktr, AUDIO_EXTERN);
1.1       wiz      2369:                        break;
                   2370:
                   2371:                /* this is the tuner input */
                   2372:                case METEOR_INPUT_DEV1:
                   2373:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
                   2374:                                | METEOR_DEV1;
                   2375:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
                   2376:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
                   2377:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
                   2378:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
1.28      wiz      2379:                        set_audio(bktr, AUDIO_TUNER);
1.1       wiz      2380:                        break;
                   2381:
                   2382:                /* this is the S-VHS input, but with a composite camera */
                   2383:                case METEOR_INPUT_DEV2:
                   2384:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
                   2385:                                | METEOR_DEV2;
                   2386:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
                   2387:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
                   2388:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
                   2389:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
1.28      wiz      2390:                        set_audio(bktr, AUDIO_EXTERN);
1.1       wiz      2391:                        break;
                   2392:
                   2393:                /* this is the S-VHS input */
                   2394:                case METEOR_INPUT_DEV_SVIDEO:
                   2395:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
                   2396:                                | METEOR_DEV_SVIDEO;
                   2397:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
                   2398:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
                   2399:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
                   2400:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
1.28      wiz      2401:                        set_audio(bktr, AUDIO_EXTERN);
1.1       wiz      2402:                        break;
                   2403:
                   2404:                case METEOR_INPUT_DEV3:
                   2405:                  if ((bktr->id == BROOKTREE_848A) ||
                   2406:                      (bktr->id == BROOKTREE_849A) ||
                   2407:                      (bktr->id == BROOKTREE_878) ||
1.28      wiz      2408:                      (bktr->id == BROOKTREE_879)) {
1.1       wiz      2409:                        bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
                   2410:                                | METEOR_DEV3;
                   2411:                        OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
                   2412:
                   2413:                        /* work around for new Hauppauge 878 cards */
                   2414:                        if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
                   2415:                                (bktr->id==BROOKTREE_878 ||
1.28      wiz      2416:                                 bktr->id==BROOKTREE_879))
1.1       wiz      2417:                                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
                   2418:                        else
                   2419:                                OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
                   2420:
                   2421:                        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
                   2422:                        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
1.28      wiz      2423:                        set_audio(bktr, AUDIO_EXTERN);
1.1       wiz      2424:
                   2425:                        break;
1.28      wiz      2426:                  }
1.1       wiz      2427:
                   2428:                default:
1.28      wiz      2429:                        return(EINVAL);
1.1       wiz      2430:                }
                   2431:                break;
                   2432:
                   2433:        case METEORGINPUT:      /* get input device */
1.46      jmcneill 2434:                *(u_int *)arg = bktr->flags & METEOR_DEV_MASK;
1.1       wiz      2435:                break;
                   2436:
                   2437:        case METEORSACTPIXFMT:
1.28      wiz      2438:                if ((*(int *)arg < 0) ||
                   2439:                    (*(int *)arg >= PIXFMT_TABLE_SIZE))
                   2440:                        return(EINVAL);
1.1       wiz      2441:
                   2442:                bktr->pixfmt          = *(int *)arg;
                   2443:                OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
1.28      wiz      2444:                     | pixfmt_swap_flags(bktr->pixfmt));
1.1       wiz      2445:                bktr->pixfmt_compat   = FALSE;
                   2446:                break;
1.28      wiz      2447:
1.1       wiz      2448:        case METEORGACTPIXFMT:
                   2449:                *(int *)arg = bktr->pixfmt;
                   2450:                break;
                   2451:
                   2452:        case METEORGSUPPIXFMT :
                   2453:                pf_pub = (struct meteor_pixfmt *)arg;
                   2454:                pixfmt = pf_pub->index;
                   2455:
1.28      wiz      2456:                if ((pixfmt < 0) || (pixfmt >= PIXFMT_TABLE_SIZE))
                   2457:                        return(EINVAL);
1.1       wiz      2458:
1.28      wiz      2459:                memcpy(pf_pub, &pixfmt_table[pixfmt].public,
                   2460:                        sizeof(*pf_pub));
1.1       wiz      2461:
                   2462:                /*  Patch in our format index  */
                   2463:                pf_pub->index       = pixfmt;
                   2464:                break;
                   2465:
1.28      wiz      2466: #if defined(STATUS_SUM)
1.1       wiz      2467:        case BT848_GSTATUS:     /* reap status */
                   2468:                {
                   2469:                 DECLARE_INTR_MASK(s);
                   2470:                DISABLE_INTR(s);
                   2471:                temp = status_sum;
                   2472:                status_sum = 0;
                   2473:                ENABLE_INTR(s);
                   2474:                *(u_int*)arg = temp;
                   2475:                break;
                   2476:                }
                   2477: #endif /* STATUS_SUM */
                   2478:
                   2479:        default:
1.28      wiz      2480:                return(ENOTTY);
1.1       wiz      2481:        }
                   2482:
1.28      wiz      2483:        return(0);
1.1       wiz      2484: }
                   2485:
                   2486:
                   2487:
                   2488:
                   2489: /******************************************************************************
                   2490:  * bt848 RISC programming routines:
                   2491:  */
                   2492:
                   2493:
                   2494: /*
1.28      wiz      2495:  *
1.1       wiz      2496:  */
1.28      wiz      2497: #ifdef BT848_DEBUG
1.1       wiz      2498: static int
1.28      wiz      2499: dump_bt848(bktr_ptr_t bktr)
1.1       wiz      2500: {
                   2501:        int     r[60]={
1.28      wiz      2502:                           4,    8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
1.1       wiz      2503:                        0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
                   2504:                        0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
                   2505:                        0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
                   2506:                        0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
                   2507:                        0,       0,    0,    0
                   2508:                   };
                   2509:        int     i;
                   2510:
                   2511:        for (i = 0; i < 40; i+=4) {
1.4       wiz      2512:                printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
1.28      wiz      2513:                       bktr_name(bktr),
1.1       wiz      2514:                       r[i], INL(bktr, r[i]),
                   2515:                       r[i+1], INL(bktr, r[i+1]),
                   2516:                       r[i+2], INL(bktr, r[i+2]),
1.16      mjl      2517:                       r[i+3], INL(bktr, r[i+3]));
1.1       wiz      2518:        }
                   2519:
1.4       wiz      2520:        printf("%s: INT STAT %x \n", bktr_name(bktr),
1.28      wiz      2521:               INL(bktr, BKTR_INT_STAT));
1.4       wiz      2522:        printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
                   2523:               INL(bktr, BKTR_INT_MASK));
                   2524:        printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
                   2525:               INW(bktr, BKTR_GPIO_DMA_CTL));
1.1       wiz      2526:
1.28      wiz      2527:        return(0);
1.1       wiz      2528: }
                   2529:
                   2530: #endif
                   2531:
                   2532: /*
                   2533:  * build write instruction
                   2534:  */
                   2535: #define BKTR_FM1      0x6      /* packed data to follow */
                   2536: #define BKTR_FM3      0xe      /* planar data to follow */
                   2537: #define BKTR_VRE      0x4      /* Marks the end of the even field */
                   2538: #define BKTR_VRO      0xC      /* Marks the end of the odd field */
                   2539: #define BKTR_PXV      0x0      /* valid word (never used) */
                   2540: #define BKTR_EOL      0x1      /* last dword, 4 bytes */
                   2541: #define BKTR_SOL      0x2      /* first dword */
                   2542:
                   2543: #define OP_WRITE      (0x1 << 28)
                   2544: #define OP_SKIP       (0x2 << 28)
                   2545: #define OP_WRITEC     (0x5 << 28)
                   2546: #define OP_JUMP              (0x7 << 28)
                   2547: #define OP_SYNC              (0x8 << 28)
                   2548: #define OP_WRITE123   (0x9 << 28)
                   2549: #define OP_WRITES123  (0xb << 28)
                   2550: #define OP_SOL       (1 << 27)         /* first instr for scanline */
                   2551: #define OP_EOL       (1 << 26)
                   2552:
                   2553: #define BKTR_RESYNC   (1 << 15)
                   2554: #define BKTR_GEN_IRQ  (1 << 24)
                   2555:
                   2556: /*
                   2557:  * The RISC status bits can be set/cleared in the RISC programs
                   2558:  * and tested in the Interrupt Handler
                   2559:  */
                   2560: #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
                   2561: #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
                   2562: #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
                   2563: #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
                   2564:
                   2565: #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
                   2566: #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
                   2567: #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
                   2568: #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
                   2569:
                   2570: #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
                   2571: #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
                   2572: #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
                   2573: #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
                   2574:
1.24      toshii   2575: static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
1.1       wiz      2576:     int i;
                   2577:     bktr_clip_t * clip_node;
                   2578:     bktr->clip_start = -1;
                   2579:     bktr->last_y = 0;
                   2580:     bktr->y = 0;
                   2581:     bktr->y2 = width;
                   2582:     bktr->line_length = width;
                   2583:     bktr->yclip = -1;
                   2584:     bktr->yclip2 = -1;
                   2585:     bktr->current_col = 0;
1.28      wiz      2586:
                   2587:     if (bktr->max_clip_node == 0) return TRUE;
1.1       wiz      2588:     clip_node = (bktr_clip_t *) &bktr->clip_list[0];
                   2589:
                   2590:
1.28      wiz      2591:     for (i = 0; i < bktr->max_clip_node; i++) {
1.1       wiz      2592:        clip_node = (bktr_clip_t *) &bktr->clip_list[i];
1.28      wiz      2593:        if (x >= clip_node->x_min && x <= clip_node->x_max) {
1.1       wiz      2594:            bktr->clip_start = i;
                   2595:            return FALSE;
                   2596:        }
1.28      wiz      2597:     }
                   2598:
1.1       wiz      2599:     return TRUE;
1.28      wiz      2600: }
1.1       wiz      2601:
1.28      wiz      2602: static bool_t getline(bktr_reg_t *bktr, int x) {
1.1       wiz      2603:     int i, j;
1.27      mjl      2604:     bktr_clip_t * clip_node;
1.28      wiz      2605:
                   2606:     if (bktr->line_length == 0 ||
1.1       wiz      2607:        bktr->current_col >= bktr->line_length) return FALSE;
                   2608:
                   2609:     bktr->y = min(bktr->last_y, bktr->line_length);
                   2610:     bktr->y2 = bktr->line_length;
                   2611:
                   2612:     bktr->yclip = bktr->yclip2 = -1;
1.28      wiz      2613:     for (i = bktr->clip_start; i < bktr->max_clip_node; i++) {
1.1       wiz      2614:        clip_node = (bktr_clip_t *) &bktr->clip_list[i];
                   2615:        if (x >= clip_node->x_min && x <= clip_node->x_max) {
                   2616:            if (bktr->last_y <= clip_node->y_min) {
                   2617:                bktr->y =      min(bktr->last_y, bktr->line_length);
                   2618:                bktr->y2 =     min(clip_node->y_min, bktr->line_length);
                   2619:                bktr->yclip =  min(clip_node->y_min, bktr->line_length);
                   2620:                bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
                   2621:                bktr->last_y = bktr->yclip2;
                   2622:                bktr->clip_start = i;
1.28      wiz      2623:
                   2624:                for (j = i+1; j < bktr->max_clip_node; j++) {
1.1       wiz      2625:                    clip_node = (bktr_clip_t *) &bktr->clip_list[j];
                   2626:                    if (x >= clip_node->x_min && x <= clip_node->x_max) {
                   2627:                        if (bktr->last_y >= clip_node->y_min) {
                   2628:                            bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
                   2629:                            bktr->last_y = bktr->yclip2;
                   2630:                            bktr->clip_start = j;
1.28      wiz      2631:                        }
1.27      mjl      2632:                    } else break;
1.28      wiz      2633:                }
1.1       wiz      2634:                return TRUE;
1.28      wiz      2635:            }
1.1       wiz      2636:        }
                   2637:     }
                   2638:
                   2639:     if (bktr->current_col <= bktr->line_length) {
                   2640:        bktr->current_col = bktr->line_length;
                   2641:        return TRUE;
                   2642:     }
                   2643:     return FALSE;
                   2644: }
1.28      wiz      2645:
1.46      jmcneill 2646: static bool_t split(bktr_reg_t * bktr, volatile u_int **dma_prog, int width ,
                   2647:                    u_int operation, int pixel_width,
1.28      wiz      2648:                    volatile u_char ** target_buffer, int cols) {
1.1       wiz      2649:
1.46      jmcneill 2650:  u_int flag, flag2;
1.28      wiz      2651:  const struct meteor_pixfmt *pf = &pixfmt_table[bktr->pixfmt].public;
1.1       wiz      2652:  u_int  skip, start_skip;
                   2653:
                   2654:   /*  For RGB24, we need to align the component in FIFO Byte Lane 0         */
                   2655:   /*    to the 1st byte in the mem dword containing our start addr.         */
                   2656:   /*    BTW, we know this pixfmt's 1st byte is Blue; thus the start addr    */
                   2657:   /*     must be Blue.                                                      */
                   2658:   start_skip = 0;
1.28      wiz      2659:   if ((pf->type == METEOR_PIXTYPE_RGB) && (pf->Bpp == 3))
                   2660:          switch (((uintptr_t) (volatile void *) *target_buffer) % 4) {
1.27      mjl      2661:          case 2 : start_skip = 4; break;
                   2662:          case 1 : start_skip = 8; break;
1.1       wiz      2663:          }
                   2664:
1.28      wiz      2665:  if ((width * pixel_width) < DMA_BT848_SPLIT) {
                   2666:      if (width == cols) {
1.1       wiz      2667:         flag = OP_SOL | OP_EOL;
1.28      wiz      2668:        } else if (bktr->current_col == 0) {
1.1       wiz      2669:            flag  = OP_SOL;
                   2670:        } else if (bktr->current_col == cols) {
                   2671:            flag = OP_EOL;
1.28      wiz      2672:        } else flag = 0;
1.1       wiz      2673:
                   2674:      skip = 0;
1.28      wiz      2675:      if ((flag & OP_SOL) && (start_skip > 0)) {
1.27      mjl      2676:             *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
1.1       wiz      2677:             flag &= ~OP_SOL;
                   2678:             skip = start_skip;
                   2679:      }
                   2680:
1.27      mjl      2681:      *(*dma_prog)++ = htole32(operation | flag  |
                   2682:        (width * pixel_width - skip));
1.28      wiz      2683:      if (operation != OP_SKIP)
1.27      mjl      2684:         *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
1.1       wiz      2685:
                   2686:      *target_buffer += width * pixel_width;
                   2687:      bktr->current_col += width;
                   2688:
                   2689:  } else {
                   2690:
                   2691:        if (bktr->current_col == 0 && width == cols) {
1.27      mjl      2692:            flag = OP_SOL;
1.1       wiz      2693:            flag2 = OP_EOL;
1.28      wiz      2694:         } else if (bktr->current_col == 0) {
1.1       wiz      2695:            flag = OP_SOL;
                   2696:            flag2 = 0;
                   2697:        } else if (bktr->current_col >= cols)  {
                   2698:            flag =  0;
                   2699:            flag2 = OP_EOL;
                   2700:        } else {
                   2701:            flag =  0;
                   2702:            flag2 = 0;
                   2703:        }
                   2704:
                   2705:        skip = 0;
1.28      wiz      2706:        if ((flag & OP_SOL) && (start_skip > 0)) {
1.27      mjl      2707:                *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
1.1       wiz      2708:                flag &= ~OP_SOL;
                   2709:                skip = start_skip;
                   2710:        }
                   2711:
1.27      mjl      2712:        *(*dma_prog)++ = htole32(operation  | flag |
                   2713:              (width * pixel_width / 2 - skip));
1.28      wiz      2714:        if (operation != OP_SKIP)
1.27      mjl      2715:              *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
                   2716:        *target_buffer +=  (width * pixel_width / 2);
1.1       wiz      2717:
1.28      wiz      2718:        if (operation == OP_WRITE)
1.1       wiz      2719:                operation = OP_WRITEC;
1.27      mjl      2720:        *(*dma_prog)++ = htole32(operation | flag2 |
                   2721:            (width * pixel_width / 2));
                   2722:        *target_buffer +=  (width * pixel_width / 2);
1.1       wiz      2723:          bktr->current_col += width;
                   2724:
                   2725:     }
                   2726:  return TRUE;
                   2727: }
                   2728:
                   2729:
                   2730: /*
                   2731:  * Generate the RISC instructions to capture both VBI and video images
                   2732:  */
                   2733: static void
1.28      wiz      2734: rgb_vbi_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
1.1       wiz      2735: {
                   2736:        int                     i;
1.46      jmcneill 2737:        volatile u_int          target_buffer, buffer, target,width;
                   2738:        volatile u_int          pitch;
                   2739:        volatile u_int          *dma_prog;      /* DMA prog is an array of
1.1       wiz      2740:                                                32 bit RISC instructions */
1.38      bouyer   2741:        volatile bus_addr_t     loop_point;
1.28      wiz      2742:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
1.1       wiz      2743:        u_int                   Bpp = pf_int->public.Bpp;
                   2744:        unsigned int            vbisamples;     /* VBI samples per line */
                   2745:        unsigned int            vbilines;       /* VBI lines per field */
                   2746:        unsigned int            num_dwords;     /* DWORDS per line */
                   2747:
                   2748:        vbisamples = format_params[bktr->format_params].vbi_num_samples;
                   2749:        vbilines   = format_params[bktr->format_params].vbi_num_lines;
                   2750:        num_dwords = vbisamples/4;
                   2751:
                   2752:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
                   2753:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
                   2754:        OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
                   2755:        OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay    */
                   2756:                                                            /* no ext frame */
                   2757:
                   2758:        OUTB(bktr, BKTR_OFORM, 0x00);
                   2759:
1.25      toshii   2760:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
                   2761:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
1.1       wiz      2762:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
                   2763:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
                   2764:
1.25      toshii   2765:        /* disable gamma correction removal */
                   2766:        OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
1.1       wiz      2767:
1.28      wiz      2768:        if (cols > 385) {
1.1       wiz      2769:            OUTB(bktr, BKTR_E_VTC, 0);
                   2770:            OUTB(bktr, BKTR_O_VTC, 0);
                   2771:        } else {
                   2772:            OUTB(bktr, BKTR_E_VTC, 1);
                   2773:            OUTB(bktr, BKTR_O_VTC, 1);
                   2774:        }
                   2775:        bktr->capcontrol = 3 << 2 |  3;
                   2776:
1.46      jmcneill 2777:        dma_prog = (u_int *) bktr->dma_prog;
1.1       wiz      2778:
                   2779:        /* Construct Write */
                   2780:
                   2781:        if (bktr->video.addr) {
1.46      jmcneill 2782:                target_buffer = (u_int) bktr->video.addr;
1.1       wiz      2783:                pitch = bktr->video.width;
                   2784:        }
                   2785:        else {
1.46      jmcneill 2786:                target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
1.1       wiz      2787:                pitch = cols*Bpp;
                   2788:        }
                   2789:
                   2790:        buffer = target_buffer;
                   2791:
                   2792:        /* Wait for the VRE sync marking the end of the Even and
                   2793:         * the start of the Odd field. Resync here.
                   2794:         */
1.27      mjl      2795:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_VRE);
                   2796:        *dma_prog++ = htole32(0);
1.1       wiz      2797:
1.38      bouyer   2798:        loop_point = bktr->dm_prog->dm_segs[0].ds_addr;
1.1       wiz      2799:
                   2800:        /* store the VBI data */
                   2801:        /* look for sync with packed data */
1.27      mjl      2802:        *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
                   2803:        *dma_prog++ = htole32(0);
1.1       wiz      2804:        for(i = 0; i < vbilines; i++) {
1.27      mjl      2805:                *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
1.46      jmcneill 2806:                *dma_prog++ = htole32((u_int)
1.38      bouyer   2807:                    bktr->dm_vbidata->dm_segs[0].ds_addr + (i * VBI_LINE_SIZE));
1.1       wiz      2808:        }
                   2809:
1.28      wiz      2810:        if ((i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/) {
1.1       wiz      2811:                /* store the Odd field video image */
                   2812:                /* look for sync with packed data */
1.27      mjl      2813:                *dma_prog++ = htole32(OP_SYNC  | BKTR_FM1);
                   2814:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      2815:                width = cols;
                   2816:                for (i = 0; i < (rows/interlace); i++) {
                   2817:                    target = target_buffer;
1.28      wiz      2818:                    if (notclipped(bktr, i, width)) {
1.46      jmcneill 2819:                        split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      2820:                              bktr->y2 - bktr->y, OP_WRITE,
1.28      wiz      2821:                              Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
                   2822:
1.1       wiz      2823:                    } else {
                   2824:                        while(getline(bktr, i)) {
1.28      wiz      2825:                            if (bktr->y != bktr->y2) {
1.46      jmcneill 2826:                                split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      2827:                                      bktr->y2 - bktr->y, OP_WRITE,
1.30      fvdl     2828:                                      Bpp, (volatile u_char **) (uintptr_t)&target, cols);
1.1       wiz      2829:                            }
1.28      wiz      2830:                            if (bktr->yclip != bktr->yclip2) {
1.46      jmcneill 2831:                                split(bktr,(volatile u_int **) &dma_prog,
1.1       wiz      2832:                                      bktr->yclip2 - bktr->yclip,
                   2833:                                      OP_SKIP,
1.28      wiz      2834:                                      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
1.1       wiz      2835:                            }
                   2836:                        }
1.28      wiz      2837:
1.1       wiz      2838:                    }
1.28      wiz      2839:
1.1       wiz      2840:                    target_buffer += interlace * pitch;
1.28      wiz      2841:
1.1       wiz      2842:                }
                   2843:
                   2844:        } /* end if */
                   2845:
                   2846:        /* Grab the Even field */
                   2847:        /* Look for the VRO, end of Odd field, marker */
1.27      mjl      2848:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
                   2849:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      2850:
                   2851:        /* store the VBI data */
                   2852:        /* look for sync with packed data */
1.27      mjl      2853:        *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
                   2854:        *dma_prog++ = htole32(0);
1.1       wiz      2855:        for(i = 0; i < vbilines; i++) {
1.27      mjl      2856:                *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
1.46      jmcneill 2857:                *dma_prog++ = htole32((u_int)
1.38      bouyer   2858:                    bktr->dm_vbidata->dm_segs[0].ds_addr +
                   2859:                    ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
1.1       wiz      2860:        }
                   2861:
                   2862:        /* store the video image */
                   2863:        if (i_flag == 1) /*Even Only*/
                   2864:                target_buffer = buffer;
                   2865:        if (i_flag == 3) /*interlaced*/
                   2866:                target_buffer = buffer+pitch;
                   2867:
                   2868:
                   2869:        if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
                   2870:                /* look for sync with packed data */
1.27      mjl      2871:                *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
                   2872:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      2873:                width = cols;
                   2874:                for (i = 0; i < (rows/interlace); i++) {
                   2875:                    target = target_buffer;
1.28      wiz      2876:                    if (notclipped(bktr, i, width)) {
1.46      jmcneill 2877:                        split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      2878:                              bktr->y2 - bktr->y, OP_WRITE,
1.28      wiz      2879:                              Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
1.1       wiz      2880:                    } else {
                   2881:                        while(getline(bktr, i)) {
1.28      wiz      2882:                            if (bktr->y != bktr->y2) {
1.46      jmcneill 2883:                                split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      2884:                                      bktr->y2 - bktr->y, OP_WRITE,
1.28      wiz      2885:                                      Bpp, (volatile u_char **)(uintptr_t)&target,
1.1       wiz      2886:                                      cols);
1.28      wiz      2887:                            }
                   2888:                            if (bktr->yclip != bktr->yclip2) {
1.46      jmcneill 2889:                                split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      2890:                                      bktr->yclip2 - bktr->yclip, OP_SKIP,
1.28      wiz      2891:                                      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
                   2892:                            }
1.1       wiz      2893:
1.28      wiz      2894:                        }
1.1       wiz      2895:
                   2896:                    }
                   2897:
                   2898:                    target_buffer += interlace * pitch;
                   2899:
                   2900:                }
                   2901:        }
                   2902:
                   2903:        /* Look for end of 'Even Field' */
1.27      mjl      2904:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
                   2905:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      2906:
1.27      mjl      2907:        *dma_prog++ = htole32(OP_JUMP);
1.38      bouyer   2908:        *dma_prog++ = htole32(loop_point);
1.27      mjl      2909:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      2910:
                   2911: }
                   2912:
                   2913:
                   2914:
                   2915:
                   2916: static void
1.28      wiz      2917: rgb_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
1.1       wiz      2918: {
                   2919:        int                     i;
1.46      jmcneill 2920:        volatile u_int          target_buffer, buffer, target,width;
                   2921:        volatile u_int          pitch;
                   2922:        volatile  u_int *dma_prog;
1.28      wiz      2923:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
1.1       wiz      2924:        u_int                   Bpp = pf_int->public.Bpp;
                   2925:
                   2926:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
                   2927:        OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
                   2928:        OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
                   2929:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
                   2930:
                   2931:        OUTB(bktr, BKTR_OFORM, 0x00);
                   2932:
1.25      toshii   2933:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
                   2934:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
1.1       wiz      2935:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
                   2936:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
                   2937:
1.25      toshii   2938:        /* disable gamma correction removal */
1.1       wiz      2939:        OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
                   2940:
1.28      wiz      2941:        if (cols > 385) {
1.1       wiz      2942:            OUTB(bktr, BKTR_E_VTC, 0);
                   2943:            OUTB(bktr, BKTR_O_VTC, 0);
                   2944:        } else {
                   2945:            OUTB(bktr, BKTR_E_VTC, 1);
                   2946:            OUTB(bktr, BKTR_O_VTC, 1);
                   2947:        }
                   2948:        bktr->capcontrol = 3 << 2 |  3;
                   2949:
1.46      jmcneill 2950:        dma_prog = (u_int *) bktr->dma_prog;
1.1       wiz      2951:
                   2952:        /* Construct Write */
                   2953:
                   2954:        if (bktr->video.addr) {
1.46      jmcneill 2955:                target_buffer = (u_int) bktr->video.addr;
1.1       wiz      2956:                pitch = bktr->video.width;
                   2957:        }
                   2958:        else {
1.46      jmcneill 2959:                target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
1.1       wiz      2960:                pitch = cols*Bpp;
                   2961:        }
                   2962:
                   2963:        buffer = target_buffer;
                   2964:
                   2965:        /* contruct sync : for video packet format */
1.27      mjl      2966:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
1.1       wiz      2967:
                   2968:        /* sync, mode indicator packed data */
1.27      mjl      2969:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      2970:        width = cols;
                   2971:        for (i = 0; i < (rows/interlace); i++) {
                   2972:            target = target_buffer;
1.28      wiz      2973:            if (notclipped(bktr, i, width)) {
1.46      jmcneill 2974:                split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      2975:                      bktr->y2 - bktr->y, OP_WRITE,
1.28      wiz      2976:                      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
1.1       wiz      2977:
                   2978:            } else {
                   2979:                while(getline(bktr, i)) {
1.28      wiz      2980:                    if (bktr->y != bktr->y2) {
1.46      jmcneill 2981:                        split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      2982:                              bktr->y2 - bktr->y, OP_WRITE,
1.28      wiz      2983:                              Bpp, (volatile u_char **)(uintptr_t)&target, cols);
1.1       wiz      2984:                    }
1.28      wiz      2985:                    if (bktr->yclip != bktr->yclip2) {
1.46      jmcneill 2986:                        split(bktr,(volatile u_int **) &dma_prog,
1.1       wiz      2987:                              bktr->yclip2 - bktr->yclip,
                   2988:                              OP_SKIP,
1.28      wiz      2989:                              Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
1.1       wiz      2990:                    }
                   2991:                }
                   2992:
                   2993:            }
                   2994:
                   2995:            target_buffer += interlace * pitch;
                   2996:
                   2997:        }
                   2998:
                   2999:        switch (i_flag) {
                   3000:        case 1:
                   3001:                /* sync vre */
1.27      mjl      3002:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
                   3003:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3004:
1.27      mjl      3005:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3006:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3007:                                bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz      3008:                return;
                   3009:
                   3010:        case 2:
                   3011:                /* sync vro */
1.27      mjl      3012:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
                   3013:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3014:
1.27      mjl      3015:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3016:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3017:                                bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz      3018:                return;
                   3019:
                   3020:        case 3:
                   3021:                /* sync vro */
1.27      mjl      3022:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
                   3023:                *dma_prog++ = htole32(0);  /* NULL WORD */
                   3024:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3025:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3026:                                bktr->dm_oprog->dm_segs[0].ds_addr);
1.1       wiz      3027:                break;
                   3028:        }
                   3029:
                   3030:        if (interlace == 2) {
                   3031:
1.28      wiz      3032:                target_buffer = buffer + pitch;
1.1       wiz      3033:
1.46      jmcneill 3034:                dma_prog = (u_int *) bktr->odd_dma_prog;
1.1       wiz      3035:
                   3036:                /* sync vre IRQ bit */
1.27      mjl      3037:                *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
                   3038:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3039:                 width = cols;
                   3040:                for (i = 0; i < (rows/interlace); i++) {
                   3041:                    target = target_buffer;
1.28      wiz      3042:                    if (notclipped(bktr, i, width)) {
1.46      jmcneill 3043:                        split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      3044:                              bktr->y2 - bktr->y, OP_WRITE,
1.28      wiz      3045:                              Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
1.1       wiz      3046:                    } else {
                   3047:                        while(getline(bktr, i)) {
1.28      wiz      3048:                            if (bktr->y != bktr->y2) {
1.46      jmcneill 3049:                                split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      3050:                                      bktr->y2 - bktr->y, OP_WRITE,
1.28      wiz      3051:                                      Bpp, (volatile u_char **)(uintptr_t)&target,
1.1       wiz      3052:                                      cols);
1.28      wiz      3053:                            }
                   3054:                            if (bktr->yclip != bktr->yclip2) {
1.46      jmcneill 3055:                                split(bktr, (volatile u_int **) &dma_prog,
1.1       wiz      3056:                                      bktr->yclip2 - bktr->yclip, OP_SKIP,
1.28      wiz      3057:                                      Bpp, (volatile u_char **)(uintptr_t)&target,  cols);
                   3058:                            }
1.1       wiz      3059:
1.28      wiz      3060:                        }
1.1       wiz      3061:
                   3062:                    }
                   3063:
                   3064:                    target_buffer += interlace * pitch;
                   3065:
                   3066:                }
                   3067:        }
                   3068:
                   3069:        /* sync vre IRQ bit */
1.27      mjl      3070:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
                   3071:        *dma_prog++ = htole32(0);  /* NULL WORD */
                   3072:        *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3073:        *dma_prog++ = htole32((u_int) bktr->dm_prog->dm_segs[0].ds_addr);
1.27      mjl      3074:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3075: }
                   3076:
                   3077:
                   3078: /*
1.28      wiz      3079:  *
1.1       wiz      3080:  */
                   3081: static void
1.28      wiz      3082: yuvpack_prog(bktr_ptr_t bktr, char i_flag,
                   3083:              int cols, int rows, int interlace)
1.1       wiz      3084: {
                   3085:        int                     i;
                   3086:        volatile unsigned int   inst;
                   3087:        volatile unsigned int   inst3;
1.46      jmcneill 3088:        volatile u_int          target_buffer, buffer;
                   3089:        volatile  u_int *dma_prog;
1.28      wiz      3090:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
1.1       wiz      3091:        int                     b;
                   3092:
                   3093:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
                   3094:
                   3095:        OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
                   3096:        OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
                   3097:
                   3098:        OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
                   3099:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
                   3100:
                   3101:        bktr->capcontrol =   1 << 6 | 1 << 4 | 1 << 2 | 3;
                   3102:        bktr->capcontrol = 3 << 2 |  3;
                   3103:
1.46      jmcneill 3104:        dma_prog = (u_int *) bktr->dma_prog;
1.1       wiz      3105:
                   3106:        /* Construct Write */
1.28      wiz      3107:
1.1       wiz      3108:        /* write , sol, eol */
                   3109:        inst = OP_WRITE  | OP_SOL | (cols);
                   3110:        /* write , sol, eol */
                   3111:        inst3 = OP_WRITE | OP_EOL | (cols);
                   3112:
                   3113:        if (bktr->video.addr)
1.46      jmcneill 3114:                target_buffer = (u_int) bktr->video.addr;
1.1       wiz      3115:        else
1.46      jmcneill 3116:                target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
1.1       wiz      3117:
                   3118:        buffer = target_buffer;
                   3119:
                   3120:        /* contruct sync : for video packet format */
                   3121:        /* sync, mode indicator packed data */
1.27      mjl      3122:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
                   3123:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3124:
                   3125:        b = cols;
                   3126:
                   3127:        for (i = 0; i < (rows/interlace); i++) {
1.27      mjl      3128:                *dma_prog++ = htole32(inst);
                   3129:                *dma_prog++ = htole32(target_buffer);
                   3130:                *dma_prog++ = htole32(inst3);
1.28      wiz      3131:                *dma_prog++ = htole32(target_buffer + b);
1.1       wiz      3132:                target_buffer += interlace*(cols * 2);
                   3133:        }
                   3134:
                   3135:        switch (i_flag) {
                   3136:        case 1:
                   3137:                /* sync vre */
1.27      mjl      3138:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
                   3139:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3140:
1.27      mjl      3141:                *dma_prog++ = htole32(OP_JUMP);
1.38      bouyer   3142:                *dma_prog++ = htole32(
1.46      jmcneill 3143:                                (u_int)bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz      3144:                return;
                   3145:
                   3146:        case 2:
                   3147:                /* sync vro */
1.27      mjl      3148:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
                   3149:                *dma_prog++ = htole32(0);  /* NULL WORD */
                   3150:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3151:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3152:                                bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz      3153:                return;
                   3154:
                   3155:        case 3:
                   3156:                /* sync vro */
1.27      mjl      3157:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
                   3158:                *dma_prog++ = htole32(0);  /* NULL WORD */
                   3159:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3160:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3161:                                bktr->dm_oprog->dm_segs[0].ds_addr);
1.1       wiz      3162:                break;
                   3163:        }
                   3164:
                   3165:        if (interlace == 2) {
                   3166:
1.46      jmcneill 3167:                target_buffer =  (u_int) buffer + cols*2;
1.1       wiz      3168:
1.46      jmcneill 3169:                dma_prog = (u_int *) bktr->odd_dma_prog;
1.1       wiz      3170:
                   3171:                /* sync vre */
1.27      mjl      3172:                *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
                   3173:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3174:
1.27      mjl      3175:                for (i = 0; i < (rows/interlace); i++) {
                   3176:                        *dma_prog++ = htole32(inst);
                   3177:                        *dma_prog++ = htole32(target_buffer);
                   3178:                        *dma_prog++ = htole32(inst3);
                   3179:                        *dma_prog++ = htole32(target_buffer + b);
1.28      wiz      3180:                        target_buffer += interlace * (cols*2);
1.1       wiz      3181:                }
                   3182:        }
                   3183:
                   3184:        /* sync vro IRQ bit */
1.27      mjl      3185:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
                   3186:        *dma_prog++ = htole32(0);  /* NULL WORD */
                   3187:        *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3188:        *dma_prog++ = htole32((u_int) bktr->dm_prog->dm_segs[0].ds_addr);
1.27      mjl      3189:
                   3190:        *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3191:        *dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
1.27      mjl      3192:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3193: }
                   3194:
                   3195:
                   3196: /*
1.28      wiz      3197:  *
1.1       wiz      3198:  */
                   3199: static void
1.28      wiz      3200: yuv422_prog(bktr_ptr_t bktr, char i_flag,
                   3201:             int cols, int rows, int interlace) {
1.1       wiz      3202:
                   3203:        int                     i;
                   3204:        volatile unsigned int   inst;
1.46      jmcneill 3205:        volatile u_int          target_buffer, t1, buffer;
                   3206:        volatile u_int          *dma_prog;
1.28      wiz      3207:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
1.1       wiz      3208:
                   3209:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
                   3210:
1.46      jmcneill 3211:        dma_prog = (u_int *) bktr->dma_prog;
1.1       wiz      3212:
                   3213:        bktr->capcontrol =   1 << 6 | 1 << 4 |  3;
                   3214:
                   3215:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
                   3216:        OUTB(bktr, BKTR_OFORM, 0x00);
                   3217:
                   3218:        OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
                   3219:        OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
                   3220:
                   3221:        OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC);      /* chroma agc enable */
                   3222:        OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
                   3223:
                   3224:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
                   3225:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
1.26      toshii   3226:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
                   3227:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
1.1       wiz      3228:
                   3229:        /* disable gamma correction removal */
                   3230:        OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
                   3231:
                   3232:        /* Construct Write */
1.28      wiz      3233:        inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
1.1       wiz      3234:        if (bktr->video.addr)
1.46      jmcneill 3235:                target_buffer = (u_int) bktr->video.addr;
1.1       wiz      3236:        else
1.46      jmcneill 3237:                target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
1.28      wiz      3238:
1.1       wiz      3239:        buffer = target_buffer;
                   3240:
                   3241:        t1 = buffer;
                   3242:
                   3243:        /* contruct sync : for video packet format */
1.27      mjl      3244:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
                   3245:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3246:
1.28      wiz      3247:        for (i = 0; i < (rows/interlace); i++) {
1.27      mjl      3248:                *dma_prog++ = htole32(inst);
                   3249:                *dma_prog++ = htole32(cols/2 | cols/2 << 16);
                   3250:                *dma_prog++ = htole32(target_buffer);
                   3251:                *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
                   3252:                *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
1.1       wiz      3253:                target_buffer += interlace*cols;
                   3254:        }
                   3255:
                   3256:        switch (i_flag) {
                   3257:        case 1:
1.27      mjl      3258:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
                   3259:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3260:
1.27      mjl      3261:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3262:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3263:                                bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz      3264:                return;
                   3265:
                   3266:        case 2:
1.27      mjl      3267:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vre*/
                   3268:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3269:
1.27      mjl      3270:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3271:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3272:                                bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz      3273:                return;
                   3274:
                   3275:        case 3:
1.28      wiz      3276:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
1.27      mjl      3277:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3278:
1.27      mjl      3279:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3280:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3281:                                bktr->dm_oprog->dm_segs[0].ds_addr);
1.1       wiz      3282:                break;
                   3283:        }
                   3284:
                   3285:        if (interlace == 2) {
                   3286:
1.46      jmcneill 3287:                dma_prog = (u_int *) bktr->odd_dma_prog;
1.1       wiz      3288:
1.46      jmcneill 3289:                target_buffer  = (u_int) buffer + cols;
1.1       wiz      3290:                t1 = buffer + cols/2;
1.28      wiz      3291:                *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
1.27      mjl      3292:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3293:
1.28      wiz      3294:                for (i = 0; i < (rows/interlace); i++) {
1.27      mjl      3295:                        *dma_prog++ = htole32(inst);
                   3296:                        *dma_prog++ = htole32(cols/2 | cols/2 << 16);
                   3297:                        *dma_prog++ = htole32(target_buffer);
                   3298:                        *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
                   3299:                        *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
1.1       wiz      3300:                        target_buffer += interlace*cols;
                   3301:                }
                   3302:        }
1.28      wiz      3303:
                   3304:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
1.27      mjl      3305:        *dma_prog++ = htole32(0);  /* NULL WORD */
                   3306:        *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3307:        *dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
1.27      mjl      3308:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3309: }
                   3310:
                   3311:
                   3312: /*
1.28      wiz      3313:  *
1.1       wiz      3314:  */
                   3315: static void
1.28      wiz      3316: yuv12_prog(bktr_ptr_t bktr, char i_flag,
                   3317:             int cols, int rows, int interlace) {
1.1       wiz      3318:
                   3319:        int                     i;
                   3320:        volatile unsigned int   inst;
                   3321:        volatile unsigned int   inst1;
1.46      jmcneill 3322:        volatile u_int          target_buffer, t1, buffer;
                   3323:        volatile u_int          *dma_prog;
1.28      wiz      3324:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
1.1       wiz      3325:
                   3326:        OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
                   3327:
1.46      jmcneill 3328:        dma_prog = (u_int *) bktr->dma_prog;
1.1       wiz      3329:
                   3330:        bktr->capcontrol =   1 << 6 | 1 << 4 |  3;
                   3331:
                   3332:        OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
                   3333:        OUTB(bktr, BKTR_OFORM, 0x0);
1.28      wiz      3334:
1.1       wiz      3335:        /* Construct Write */
1.28      wiz      3336:        inst  = OP_WRITE123  | OP_SOL | OP_EOL |  (cols);
                   3337:        inst1  = OP_WRITES123  | OP_SOL | OP_EOL |  (cols);
1.25      toshii   3338:        if (bktr->video.addr)
1.46      jmcneill 3339:                target_buffer = (u_int) bktr->video.addr;
1.25      toshii   3340:        else
1.46      jmcneill 3341:                target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
1.28      wiz      3342:
1.1       wiz      3343:        buffer = target_buffer;
1.25      toshii   3344:        t1 = buffer;
1.28      wiz      3345:
1.27      mjl      3346:        *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
                   3347:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.28      wiz      3348:
                   3349:        for (i = 0; i < (rows/interlace)/2; i++) {
1.27      mjl      3350:                *dma_prog++ = htole32(inst);
                   3351:                *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
                   3352:                *dma_prog++ = htole32(target_buffer);
                   3353:                *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
                   3354:                *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
1.25      toshii   3355:                target_buffer += interlace*cols;
1.27      mjl      3356:                *dma_prog++ = htole32(inst1);
                   3357:                *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
                   3358:                *dma_prog++ = htole32(target_buffer);
1.25      toshii   3359:                target_buffer += interlace*cols;
1.28      wiz      3360:
1.25      toshii   3361:        }
1.28      wiz      3362:
1.25      toshii   3363:        switch (i_flag) {
                   3364:        case 1:
1.27      mjl      3365:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);  /*sync vre*/
                   3366:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3367:
1.27      mjl      3368:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3369:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3370:                                bktr->dm_prog->dm_segs[0].ds_addr);
1.25      toshii   3371:                return;
1.1       wiz      3372:
1.25      toshii   3373:        case 2:
1.27      mjl      3374:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);  /*sync vro*/
                   3375:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3376:
1.27      mjl      3377:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3378:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3379:                                bktr->dm_prog->dm_segs[0].ds_addr);
1.25      toshii   3380:                return;
1.28      wiz      3381:
1.25      toshii   3382:        case 3:
1.27      mjl      3383:                *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
                   3384:                *dma_prog++ = htole32(0);  /* NULL WORD */
                   3385:                *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3386:                *dma_prog++ = htole32((u_int)
1.38      bouyer   3387:                                bktr->dm_oprog->dm_segs[0].ds_addr);
1.1       wiz      3388:                break;
                   3389:        }
                   3390:
                   3391:        if (interlace == 2) {
                   3392:
1.46      jmcneill 3393:                dma_prog = (u_int *) bktr->odd_dma_prog;
1.1       wiz      3394:
1.46      jmcneill 3395:                target_buffer  = (u_int) buffer + cols;
1.1       wiz      3396:                t1 = buffer + cols/2;
1.28      wiz      3397:                *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
1.27      mjl      3398:                *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3399:
1.28      wiz      3400:                for (i = 0; i < ((rows/interlace)/2); i++) {
1.27      mjl      3401:                    *dma_prog++ = htole32(inst);
                   3402:                    *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
                   3403:                    *dma_prog++ = htole32(target_buffer);
                   3404:                    *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
                   3405:                    *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
1.1       wiz      3406:                    target_buffer += interlace*cols;
1.27      mjl      3407:                    *dma_prog++ = htole32(inst1);
                   3408:                    *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
                   3409:                    *dma_prog++ = htole32(target_buffer);
1.1       wiz      3410:                    target_buffer += interlace*cols;
                   3411:
1.28      wiz      3412:                }
                   3413:
1.1       wiz      3414:
                   3415:        }
1.28      wiz      3416:
1.27      mjl      3417:        *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
                   3418:        *dma_prog++ = htole32(0);  /* NULL WORD */
                   3419:        *dma_prog++ = htole32(OP_JUMP);
1.46      jmcneill 3420:        *dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
1.27      mjl      3421:        *dma_prog++ = htole32(0);  /* NULL WORD */
1.1       wiz      3422: }
1.29      wiz      3423:
1.1       wiz      3424:
                   3425:
                   3426: /*
1.28      wiz      3427:  *
1.1       wiz      3428:  */
                   3429: static void
1.28      wiz      3430: build_dma_prog(bktr_ptr_t bktr, char i_flag)
1.1       wiz      3431: {
                   3432:        int                     rows, cols,  interlace;
                   3433:        int                     tmp_int;
1.28      wiz      3434:        unsigned int            temp;
1.15      jdolecek 3435:        const struct format_params      *fp;
1.28      wiz      3436:         const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
                   3437:
1.1       wiz      3438:
                   3439:        fp = &format_params[bktr->format_params];
                   3440:
                   3441:        OUTL(bktr, BKTR_INT_MASK,  ALL_INTS_DISABLED);
                   3442:
                   3443:        /* disable FIFO & RISC, leave other bits alone */
                   3444:        OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
                   3445:
                   3446:        /* set video parameters */
                   3447:        if (bktr->capture_area_enabled)
1.28      wiz      3448:          temp = ((quad_t) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
1.1       wiz      3449:                  / fp->scaled_htotal / bktr->cols) -  4096;
                   3450:        else
1.28      wiz      3451:          temp = ((quad_t) fp->htotal* (quad_t) fp->scaled_hactive * 4096
1.1       wiz      3452:                  / fp->scaled_htotal / bktr->cols) -  4096;
                   3453:
1.4       wiz      3454:        /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
1.1       wiz      3455:        OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
                   3456:        OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
                   3457:        OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
                   3458:        OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
1.28      wiz      3459:
1.1       wiz      3460:        /* horizontal active */
                   3461:        temp = bktr->cols;
1.4       wiz      3462:        /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
1.1       wiz      3463:        OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
                   3464:        OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
                   3465:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
                   3466:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
                   3467:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
                   3468:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
1.28      wiz      3469:
1.1       wiz      3470:        /* horizontal delay */
                   3471:        if (bktr->capture_area_enabled)
1.28      wiz      3472:          temp = ((fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
1.1       wiz      3473:                 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
                   3474:        else
                   3475:          temp = (fp->hdelay * bktr->cols) / fp->hactive;
                   3476:
                   3477:        temp = temp & 0x3fe;
                   3478:
1.4       wiz      3479:        /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
1.1       wiz      3480:        OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
                   3481:        OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
                   3482:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
                   3483:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
                   3484:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
                   3485:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
                   3486:
                   3487:        /* vertical scale */
                   3488:
                   3489:        if (bktr->capture_area_enabled) {
                   3490:          if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
                   3491:              bktr->flags & METEOR_ONLY_EVEN_FIELDS)
                   3492:            tmp_int = 65536 -
                   3493:            (((bktr->capture_area_y_size  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
                   3494:          else {
                   3495:            tmp_int = 65536 -
                   3496:            (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
                   3497:          }
                   3498:        } else {
                   3499:          if (bktr->flags  & METEOR_ONLY_ODD_FIELDS ||
                   3500:              bktr->flags & METEOR_ONLY_EVEN_FIELDS)
                   3501:            tmp_int = 65536 -
                   3502:            (((fp->vactive  * 256 + (bktr->rows/2)) / bktr->rows) - 512);
                   3503:          else {
                   3504:            tmp_int = 65536  -
                   3505:            (((fp->vactive * 512 + (bktr->rows / 2)) /  bktr->rows) - 512);
                   3506:          }
                   3507:        }
                   3508:
                   3509:        tmp_int &= 0x1fff;
1.4       wiz      3510:        /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
1.1       wiz      3511:        OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
                   3512:        OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
                   3513:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
                   3514:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
                   3515:        OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
                   3516:        OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
                   3517:
                   3518:
                   3519:        /* vertical active */
                   3520:        if (bktr->capture_area_enabled)
                   3521:          temp = bktr->capture_area_y_size;
                   3522:        else
                   3523:          temp = fp->vactive;
1.4       wiz      3524:        /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
1.1       wiz      3525:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
                   3526:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
                   3527:        OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
                   3528:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
                   3529:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
                   3530:        OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
1.28      wiz      3531:
1.1       wiz      3532:        /* vertical delay */
                   3533:        if (bktr->capture_area_enabled)
                   3534:          temp = fp->vdelay + (bktr->capture_area_y_offset);
                   3535:        else
                   3536:          temp = fp->vdelay;
1.4       wiz      3537:        /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
1.1       wiz      3538:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
                   3539:        OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
                   3540:        OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
                   3541:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
                   3542:        OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
                   3543:        OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
                   3544:
                   3545:        /* end of video params */
                   3546:
                   3547:        if ((bktr->xtal_pll_mode == BT848_USE_PLL)
                   3548:           && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
                   3549:                OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
                   3550:        } else {
                   3551:                OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
                   3552:        }
                   3553:
                   3554:        /* capture control */
                   3555:        switch (i_flag) {
                   3556:        case 1:
1.28      wiz      3557:                bktr->bktr_cap_ctl =
1.1       wiz      3558:                    (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
                   3559:                OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
                   3560:                OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
                   3561:                interlace = 1;
                   3562:                break;
                   3563:         case 2:
1.25      toshii   3564:                bktr->bktr_cap_ctl =
1.1       wiz      3565:                        (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
                   3566:                OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
                   3567:                OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
                   3568:                interlace = 1;
                   3569:                break;
                   3570:         default:
1.28      wiz      3571:                bktr->bktr_cap_ctl =
1.1       wiz      3572:                        (BT848_CAP_CTL_DITH_FRAME |
                   3573:                         BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
                   3574:                OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
                   3575:                OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
                   3576:                interlace = 2;
                   3577:                break;
                   3578:        }
                   3579:
1.38      bouyer   3580:        OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz      3581:
                   3582:        rows = bktr->rows;
                   3583:        cols = bktr->cols;
                   3584:
                   3585:        bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
                   3586:
                   3587:        /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
                   3588:        /* user, then use the rgb_vbi RISC program. */
                   3589:        /* Otherwise, use the normal rgb RISC program */
                   3590:        if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
1.28      wiz      3591:                if ((bktr->vbiflags & VBI_OPEN)
1.1       wiz      3592:                   ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
1.28      wiz      3593:                   ||(bktr->format_params == BT848_IFORM_F_SECAM)) {
1.1       wiz      3594:                        bktr->bktr_cap_ctl |=
                   3595:                                BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
                   3596:                        bktr->vbiflags |= VBI_CAPTURE;
                   3597:                        rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
                   3598:                        return;
                   3599:                } else {
                   3600:                        rgb_prog(bktr, i_flag, cols, rows, interlace);
                   3601:                        return;
                   3602:                }
                   3603:        }
                   3604:
1.28      wiz      3605:        if (pf_int->public.type  == METEOR_PIXTYPE_YUV) {
1.1       wiz      3606:                yuv422_prog(bktr, i_flag, cols, rows, interlace);
                   3607:                OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
1.28      wiz      3608:                     | pixfmt_swap_flags(bktr->pixfmt));
1.1       wiz      3609:                return;
                   3610:        }
                   3611:
1.28      wiz      3612:        if (pf_int->public.type  == METEOR_PIXTYPE_YUV_PACKED) {
1.1       wiz      3613:                yuvpack_prog(bktr, i_flag, cols, rows, interlace);
                   3614:                OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
1.28      wiz      3615:                     | pixfmt_swap_flags(bktr->pixfmt));
1.1       wiz      3616:                return;
                   3617:        }
                   3618:
1.28      wiz      3619:        if (pf_int->public.type  == METEOR_PIXTYPE_YUV_12) {
1.1       wiz      3620:                yuv12_prog(bktr, i_flag, cols, rows, interlace);
                   3621:                OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
1.28      wiz      3622:                     | pixfmt_swap_flags(bktr->pixfmt));
1.1       wiz      3623:                return;
                   3624:        }
                   3625:        return;
                   3626: }
                   3627:
                   3628:
                   3629: /******************************************************************************
                   3630:  * video & video capture specific routines:
                   3631:  */
                   3632:
                   3633:
                   3634: /*
1.28      wiz      3635:  *
1.1       wiz      3636:  */
                   3637: static void
1.28      wiz      3638: start_capture(bktr_ptr_t bktr, unsigned type)
1.1       wiz      3639: {
                   3640:        u_char                  i_flag;
1.15      jdolecek 3641:        const struct format_params   *fp;
1.1       wiz      3642:
                   3643:        fp = &format_params[bktr->format_params];
                   3644:
1.35      wiz      3645:        /*  If requested, clear out capture buf first  */
1.1       wiz      3646:        if (bktr->clr_on_start && (bktr->video.addr == 0)) {
1.42      christos 3647:                bzero((void *)bktr->bigbuf,
1.1       wiz      3648:                      (size_t)bktr->rows * bktr->cols * bktr->frames *
1.28      wiz      3649:                        pixfmt_table[bktr->pixfmt].public.Bpp);
1.1       wiz      3650:        }
                   3651:
                   3652:        OUTB(bktr, BKTR_DSTATUS,  0);
                   3653:        OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
                   3654:
                   3655:        bktr->flags |= type;
                   3656:        bktr->flags &= ~METEOR_WANT_MASK;
                   3657:        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
                   3658:        case METEOR_ONLY_EVEN_FIELDS:
                   3659:                bktr->flags |= METEOR_WANT_EVEN;
                   3660:                i_flag = 1;
                   3661:                break;
                   3662:        case METEOR_ONLY_ODD_FIELDS:
                   3663:                bktr->flags |= METEOR_WANT_ODD;
                   3664:                i_flag = 2;
                   3665:                break;
                   3666:        default:
                   3667:                bktr->flags |= METEOR_WANT_MASK;
                   3668:                i_flag = 3;
                   3669:                break;
                   3670:        }
                   3671:
                   3672:        /*  TDEC is only valid for continuous captures  */
1.28      wiz      3673:        if (type == METEOR_SINGLE) {
1.1       wiz      3674:                u_short fps_save = bktr->fps;
                   3675:
                   3676:                set_fps(bktr, fp->frame_rate);
                   3677:                bktr->fps = fps_save;
                   3678:        }
                   3679:        else
                   3680:                set_fps(bktr, bktr->fps);
                   3681:
                   3682:        if (bktr->dma_prog_loaded == FALSE) {
                   3683:                build_dma_prog(bktr, i_flag);
                   3684:                bktr->dma_prog_loaded = TRUE;
                   3685:        }
1.28      wiz      3686:
1.1       wiz      3687:
1.38      bouyer   3688:        OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs[0].ds_addr);
1.1       wiz      3689:
                   3690: }
                   3691:
                   3692:
                   3693: /*
1.28      wiz      3694:  *
1.1       wiz      3695:  */
                   3696: static void
1.28      wiz      3697: set_fps(bktr_ptr_t bktr, u_short fps)
1.1       wiz      3698: {
1.15      jdolecek 3699:        const struct format_params      *fp;
1.1       wiz      3700:        int i_flag;
                   3701:
                   3702:        fp = &format_params[bktr->format_params];
                   3703:
                   3704:        switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
                   3705:        case METEOR_ONLY_EVEN_FIELDS:
                   3706:                bktr->flags |= METEOR_WANT_EVEN;
                   3707:                i_flag = 1;
                   3708:                break;
                   3709:        case METEOR_ONLY_ODD_FIELDS:
                   3710:                bktr->flags |= METEOR_WANT_ODD;
                   3711:                i_flag = 1;
                   3712:                break;
                   3713:        default:
                   3714:                bktr->flags |= METEOR_WANT_MASK;
                   3715:                i_flag = 2;
                   3716:                break;
                   3717:        }
                   3718:
                   3719:        OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
                   3720:        OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
                   3721:
                   3722:        bktr->fps = fps;
                   3723:        OUTB(bktr, BKTR_TDEC, 0);
                   3724:
                   3725:        if (fps < fp->frame_rate)
                   3726:                OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
                   3727:        else
                   3728:                OUTB(bktr, BKTR_TDEC, 0);
                   3729:        return;
                   3730:
                   3731: }
                   3732:
                   3733:
                   3734:
                   3735:
                   3736:
1.28      wiz      3737: /*
                   3738:  * Given a pixfmt index, compute the bt848 swap_flags necessary to
1.1       wiz      3739:  *   achieve the specified swapping.
1.28      wiz      3740:  * Note that without bt swapping, 2Bpp and 3Bpp modes are written
                   3741:  *   byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
                   3742:  *   and read R->L).
                   3743:  * Note also that for 3Bpp, we may additionally need to do some creative
1.1       wiz      3744:  *   SKIPing to align the FIFO bytelines with the target buffer (see split()).
                   3745:  * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
                   3746:  *   as one would expect.
                   3747:  */
                   3748:
1.28      wiz      3749: static u_int pixfmt_swap_flags(int pixfmt)
1.1       wiz      3750: {
1.28      wiz      3751:        const struct meteor_pixfmt *pf = &pixfmt_table[pixfmt].public;
1.1       wiz      3752:        u_int                 swapf = 0;
1.27      mjl      3753:        int swap_bytes, swap_shorts;
1.28      wiz      3754:
1.27      mjl      3755: #if BYTE_ORDER == LITTLE_ENDIAN
                   3756:        swap_bytes = pf->swap_bytes;
                   3757:        swap_shorts = pf->swap_shorts;
                   3758: #else
                   3759:        swap_bytes = !pf->swap_bytes;
                   3760:        swap_shorts = !pf->swap_shorts;
                   3761: #endif
1.28      wiz      3762:        switch (pf->Bpp) {
                   3763:        case 2 : swapf = (swap_bytes ? 0 : BSWAP);
1.1       wiz      3764:                 break;
                   3765:
                   3766:        case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
                   3767:                 break;
1.28      wiz      3768:
1.27      mjl      3769:        case 4 :
                   3770:                swapf  = swap_bytes  ? 0 : BSWAP;
                   3771:                swapf |= swap_shorts ? 0 : WSWAP;
                   3772:                break;
1.1       wiz      3773:        }
                   3774:        return swapf;
                   3775: }
                   3776:
                   3777:
                   3778:
1.28      wiz      3779: /*
1.1       wiz      3780:  * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
                   3781:  *   our pixfmt_table indices.
                   3782:  */
                   3783:
1.46      jmcneill 3784: static int oformat_meteor_to_bt(u_int format)
1.1       wiz      3785: {
                   3786:        int    i;
1.15      jdolecek 3787:         const struct meteor_pixfmt *pf1, *pf2;
1.1       wiz      3788:
                   3789:        /*  Find format in compatibility table  */
1.28      wiz      3790:        for (i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++)
                   3791:                if (meteor_pixfmt_table[i].meteor_format == format)
1.1       wiz      3792:                        break;
                   3793:
1.28      wiz      3794:        if (i >= METEOR_PIXFMT_TABLE_SIZE)
1.1       wiz      3795:                return -1;
                   3796:        pf1 = &meteor_pixfmt_table[i].public;
                   3797:
                   3798:        /*  Match it with an entry in master pixel format table  */
1.28      wiz      3799:        for (i = 0; i < PIXFMT_TABLE_SIZE; i++) {
1.1       wiz      3800:                pf2 = &pixfmt_table[i].public;
                   3801:
1.28      wiz      3802:                if ((pf1->type        == pf2->type) &&
                   3803:                    (pf1->Bpp         == pf2->Bpp) &&
                   3804:                    !memcmp(pf1->masks, pf2->masks, sizeof(pf1->masks)) &&
                   3805:                    (pf1->swap_bytes  == pf2->swap_bytes) &&
                   3806:                    (pf1->swap_shorts == pf2->swap_shorts))
1.1       wiz      3807:                        break;
                   3808:        }
1.28      wiz      3809:        if (i >= PIXFMT_TABLE_SIZE)
1.1       wiz      3810:                return -1;
                   3811:
                   3812:        return i;
                   3813: }
                   3814:
                   3815: /******************************************************************************
                   3816:  * i2c primitives:
                   3817:  */
                   3818:
                   3819: /* */
                   3820: #define I2CBITTIME             (0x5<<4)        /* 5 * 0.48uS */
                   3821: #define I2CBITTIME_878              (1 << 7)
                   3822: #define I2C_READ               0x01
                   3823: #define I2C_COMMAND            (I2CBITTIME |                   \
                   3824:                                 BT848_DATA_CTL_I2CSCL |        \
                   3825:                                 BT848_DATA_CTL_I2CSDA)
                   3826:
                   3827: #define I2C_COMMAND_878                (I2CBITTIME_878 |                       \
                   3828:                                 BT848_DATA_CTL_I2CSCL |        \
                   3829:                                 BT848_DATA_CTL_I2CSDA)
                   3830:
                   3831: /* Select between old i2c code and new iicbus / smbus code */
1.12      wiz      3832: #if defined(BKTR_USE_FREEBSD_SMBUS)
1.1       wiz      3833:
                   3834: /*
                   3835:  * The hardware interface is actually SMB commands
                   3836:  */
                   3837: int
1.28      wiz      3838: i2cWrite(bktr_ptr_t bktr, int addr, int byte1, int byte2)
1.1       wiz      3839: {
                   3840:        char cmd;
                   3841:
                   3842:        if (bktr->id == BROOKTREE_848  ||
                   3843:            bktr->id == BROOKTREE_848A ||
                   3844:            bktr->id == BROOKTREE_849A)
                   3845:                cmd = I2C_COMMAND;
                   3846:        else
                   3847:                cmd = I2C_COMMAND_878;
                   3848:
                   3849:        if (byte2 != -1) {
                   3850:                if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
                   3851:                        (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
                   3852:                        return (-1);
                   3853:        } else {
                   3854:                if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
                   3855:                        (char)(byte1 & 0xff)))
                   3856:                        return (-1);
                   3857:        }
                   3858:
                   3859:        /* return OK */
1.28      wiz      3860:        return(0);
1.1       wiz      3861: }
                   3862:
                   3863: int
1.28      wiz      3864: i2cRead(bktr_ptr_t bktr, int addr)
1.1       wiz      3865: {
                   3866:        char result;
                   3867:        char cmd;
                   3868:
                   3869:        if (bktr->id == BROOKTREE_848  ||
                   3870:            bktr->id == BROOKTREE_848A ||
                   3871:            bktr->id == BROOKTREE_849A)
                   3872:                cmd = I2C_COMMAND;
                   3873:        else
                   3874:                cmd = I2C_COMMAND_878;
                   3875:
                   3876:        if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
                   3877:                return (-1);
                   3878:
                   3879:        return ((int)((unsigned char)result));
                   3880: }
                   3881:
                   3882: #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
                   3883:
                   3884: /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
                   3885: /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
                   3886: /* Therefore we need low level control of the i2c bus hardware */
                   3887:
                   3888: /* Write to the MSP or DPL registers */
                   3889: void
                   3890: msp_dpl_write(bktr_ptr_t bktr, int i2c_addr,  unsigned char dev, unsigned int addr, unsigned int data)
                   3891: {
1.27      mjl      3892:        unsigned char addr_l, addr_h, data_h, data_l;
1.1       wiz      3893:
                   3894:        addr_h = (addr >>8) & 0xff;
                   3895:        addr_l = addr & 0xff;
                   3896:        data_h = (data >>8) & 0xff;
                   3897:        data_l = data & 0xff;
                   3898:
                   3899:        iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
                   3900:
                   3901:        iicbus_write_byte(IICBUS(bktr), dev, 0);
                   3902:        iicbus_write_byte(IICBUS(bktr), addr_h, 0);
                   3903:        iicbus_write_byte(IICBUS(bktr), addr_l, 0);
                   3904:        iicbus_write_byte(IICBUS(bktr), data_h, 0);
                   3905:        iicbus_write_byte(IICBUS(bktr), data_l, 0);
                   3906:
                   3907:        iicbus_stop(IICBUS(bktr));
                   3908:
                   3909:        return;
                   3910: }
                   3911:
                   3912: /* Read from the MSP or DPL registers */
                   3913: unsigned int
                   3914: msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
                   3915: {
                   3916:        unsigned int data;
                   3917:        unsigned char addr_l, addr_h, dev_r;
                   3918:        int read;
                   3919:        u_char data_read[2];
                   3920:
                   3921:        addr_h = (addr >>8) & 0xff;
                   3922:        addr_l = addr & 0xff;
                   3923:        dev_r = dev+1;
                   3924:
                   3925:        /* XXX errors ignored */
                   3926:        iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
                   3927:
                   3928:        iicbus_write_byte(IICBUS(bktr), dev_r, 0);
                   3929:        iicbus_write_byte(IICBUS(bktr), addr_h, 0);
                   3930:        iicbus_write_byte(IICBUS(bktr), addr_l, 0);
                   3931:
                   3932:        iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
                   3933:        iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
                   3934:        iicbus_stop(IICBUS(bktr));
                   3935:
                   3936:        data = (data_read[0]<<8) | data_read[1];
                   3937:
                   3938:        return (data);
                   3939: }
                   3940:
                   3941: /* Reset the MSP or DPL chip */
                   3942: /* The user can block the reset (which is handy if you initialise the
                   3943:  * MSP and/or DPL audio in another operating system first (eg in Windows)
                   3944:  */
                   3945: void
1.28      wiz      3946: msp_dpl_reset(bktr_ptr_t bktr, int i2c_addr)
1.1       wiz      3947: {
                   3948:
                   3949: #ifndef BKTR_NO_MSP_RESET
                   3950:        /* put into reset mode */
                   3951:        iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
                   3952:        iicbus_write_byte(IICBUS(bktr), 0x00, 0);
                   3953:        iicbus_write_byte(IICBUS(bktr), 0x80, 0);
                   3954:        iicbus_write_byte(IICBUS(bktr), 0x00, 0);
                   3955:        iicbus_stop(IICBUS(bktr));
                   3956:
                   3957:        /* put back to operational mode */
                   3958:        iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
                   3959:        iicbus_write_byte(IICBUS(bktr), 0x00, 0);
                   3960:        iicbus_write_byte(IICBUS(bktr), 0x00, 0);
                   3961:        iicbus_write_byte(IICBUS(bktr), 0x00, 0);
                   3962:        iicbus_stop(IICBUS(bktr));
                   3963: #endif
                   3964:        return;
                   3965: }
                   3966:
                   3967: static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
                   3968:        int read;
                   3969:
                   3970:        /* XXX errors ignored */
                   3971:        iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
                   3972:        iicbus_read(IICBUS(bktr),  remote->data, 3, &read, IIC_LAST_READ, 0);
                   3973:        iicbus_stop(IICBUS(bktr));
                   3974:
                   3975:        return;
                   3976: }
                   3977:
1.12      wiz      3978: #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
1.1       wiz      3979:
                   3980: /*
                   3981:  * Program the i2c bus directly
                   3982:  */
                   3983: int
1.28      wiz      3984: i2cWrite(bktr_ptr_t bktr, int addr, int byte1, int byte2)
1.1       wiz      3985: {
1.46      jmcneill 3986:        u_int           x;
                   3987:        u_int           data;
1.1       wiz      3988:
                   3989:        /* clear status bits */
                   3990:        OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
                   3991:
                   3992:        /* build the command datum */
                   3993:        if (bktr->id == BROOKTREE_848  ||
                   3994:            bktr->id == BROOKTREE_848A ||
                   3995:            bktr->id == BROOKTREE_849A) {
                   3996:          data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
                   3997:        } else {
                   3998:          data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
                   3999:        }
1.28      wiz      4000:        if (byte2 != -1) {
1.1       wiz      4001:                data |= ((byte2 & 0xff) << 8);
                   4002:                data |= BT848_DATA_CTL_I2CW3B;
                   4003:        }
                   4004:
                   4005:        /* write the address and data */
                   4006:        OUTL(bktr, BKTR_I2C_DATA_CTL, data);
                   4007:
                   4008:        /* wait for completion */
1.28      wiz      4009:        for (x = 0x7fffffff; x; --x) {  /* safety valve */
                   4010:                if (INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE)
1.1       wiz      4011:                        break;
                   4012:        }
                   4013:
                   4014:        /* check for ACK */
1.28      wiz      4015:        if (!x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK))
                   4016:                return(-1);
1.1       wiz      4017:
                   4018:        /* return OK */
1.28      wiz      4019:        return(0);
1.1       wiz      4020: }
                   4021:
                   4022:
                   4023: /*
1.28      wiz      4024:  *
1.1       wiz      4025:  */
                   4026: int
1.28      wiz      4027: i2cRead(bktr_ptr_t bktr, int addr)
1.1       wiz      4028: {
1.46      jmcneill 4029:        u_int           x;
1.1       wiz      4030:
                   4031:        /* clear status bits */
                   4032:        OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
                   4033:
                   4034:        /* write the READ address */
                   4035:        /* The Bt878 and Bt879  differed on the treatment of i2c commands */
1.28      wiz      4036:
1.1       wiz      4037:        if (bktr->id == BROOKTREE_848  ||
                   4038:            bktr->id == BROOKTREE_848A ||
                   4039:            bktr->id == BROOKTREE_849A) {
                   4040:                OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
                   4041:        } else {
                   4042:                OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
                   4043:        }
                   4044:
                   4045:        /* wait for completion */
1.28      wiz      4046:        for (x = 5000; x--; DELAY(1)) { /* 5msec, safety valve */
                   4047:                if (INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE)
1.1       wiz      4048:                        break;
                   4049:        }
                   4050:
                   4051:        /* check for ACK */
1.28      wiz      4052:        if (!x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK))
                   4053:                return(-1);
1.1       wiz      4054:
                   4055:        /* it was a read */
1.28      wiz      4056:        return((INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff);
1.1       wiz      4057: }
                   4058:
                   4059: /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
                   4060: /* bt848 automated i2c bus controller cannot handle */
                   4061: /* Therefore we need low level control of the i2c bus hardware */
                   4062: /* Idea for the following functions are from elsewhere in this driver and */
                   4063: /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
                   4064:
                   4065: #define BITD    40
1.28      wiz      4066: static void i2c_start(bktr_ptr_t bktr) {
                   4067:         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release data */
                   4068:         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release clock */
                   4069:         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* lower data */
                   4070:         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock */
1.1       wiz      4071: }
                   4072:
1.28      wiz      4073: static void i2c_stop(bktr_ptr_t bktr) {
                   4074:         OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock & data */
                   4075:         OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* release clock */
                   4076:         OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release data */
1.1       wiz      4077: }
                   4078:
1.28      wiz      4079: static int i2c_write_byte(bktr_ptr_t bktr, unsigned char data) {
1.1       wiz      4080:         int x;
                   4081:         int status;
                   4082:
                   4083:         /* write out the byte */
1.28      wiz      4084:         for (x = 7; x >= 0; --x) {
                   4085:                 if (data & (1<<x)) {
1.1       wiz      4086:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
1.28      wiz      4087:                         DELAY(BITD);          /* assert HI data */
1.1       wiz      4088:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
1.28      wiz      4089:                         DELAY(BITD);          /* strobe clock */
1.1       wiz      4090:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
1.28      wiz      4091:                         DELAY(BITD);          /* release clock */
1.1       wiz      4092:                 }
                   4093:                 else {
                   4094:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
1.28      wiz      4095:                         DELAY(BITD);          /* assert LO data */
1.1       wiz      4096:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
1.28      wiz      4097:                         DELAY(BITD);          /* strobe clock */
1.1       wiz      4098:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
1.28      wiz      4099:                         DELAY(BITD);          /* release clock */
1.1       wiz      4100:                 }
                   4101:         }
                   4102:
                   4103:         /* look for an ACK */
1.28      wiz      4104:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* float data */
                   4105:        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* strobe clock */
1.1       wiz      4106:         status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;       /* read the ACK bit */
1.28      wiz      4107:         OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release clock */
1.1       wiz      4108:
1.28      wiz      4109:         return(status);
1.1       wiz      4110: }
                   4111:
1.28      wiz      4112: static int i2c_read_byte(bktr_ptr_t bktr, unsigned char *data, int last) {
1.1       wiz      4113:         int x;
                   4114:         int bit;
                   4115:         int byte = 0;
                   4116:
                   4117:         /* read in the byte */
                   4118:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
1.28      wiz      4119:         DELAY(BITD);                          /* float data */
                   4120:         for (x = 7; x >= 0; --x) {
1.1       wiz      4121:                OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
1.28      wiz      4122:                 DELAY(BITD);                  /* strobe clock */
1.1       wiz      4123:                 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1;  /* read the data bit */
1.28      wiz      4124:                 if (bit) byte |= (1<<x);
1.1       wiz      4125:                OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
1.28      wiz      4126:                 DELAY(BITD);                  /* release clock */
1.1       wiz      4127:         }
                   4128:         /* After reading the byte, send an ACK */
                   4129:         /* (unless that was the last byte, for which we send a NAK */
                   4130:         if (last) { /* send NAK - same a writing a 1 */
                   4131:                OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
1.28      wiz      4132:                 DELAY(BITD);                  /* set data bit */
1.1       wiz      4133:                OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
1.28      wiz      4134:                 DELAY(BITD);                  /* strobe clock */
1.1       wiz      4135:                OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
1.28      wiz      4136:                 DELAY(BITD);                  /* release clock */
1.1       wiz      4137:         } else { /* send ACK - same as writing a 0 */
                   4138:                OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
1.28      wiz      4139:                 DELAY(BITD);                  /* set data bit */
1.1       wiz      4140:                OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
1.28      wiz      4141:                 DELAY(BITD);                  /* strobe clock */
1.1       wiz      4142:                OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
1.28      wiz      4143:                 DELAY(BITD);                  /* release clock */
1.1       wiz      4144:         }
                   4145:
                   4146:         *data=byte;
                   4147:        return 0;
                   4148: }
                   4149: #undef BITD
                   4150:
                   4151: /* Write to the MSP or DPL registers */
1.28      wiz      4152: void msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
                   4153:                    unsigned int data) {
1.1       wiz      4154:        unsigned int msp_w_addr = i2c_addr;
1.27      mjl      4155:        unsigned char addr_l, addr_h, data_h, data_l;
1.1       wiz      4156:        addr_h = (addr >>8) & 0xff;
                   4157:        addr_l = addr & 0xff;
                   4158:        data_h = (data >>8) & 0xff;
                   4159:        data_l = data & 0xff;
                   4160:
                   4161:        i2c_start(bktr);
                   4162:        i2c_write_byte(bktr, msp_w_addr);
                   4163:        i2c_write_byte(bktr, dev);
                   4164:        i2c_write_byte(bktr, addr_h);
                   4165:        i2c_write_byte(bktr, addr_l);
                   4166:        i2c_write_byte(bktr, data_h);
                   4167:        i2c_write_byte(bktr, data_l);
                   4168:        i2c_stop(bktr);
                   4169: }
                   4170:
                   4171: /* Read from the MSP or DPL registers */
1.28      wiz      4172: unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr) {
1.1       wiz      4173:        unsigned int data;
1.27      mjl      4174:        unsigned char addr_l, addr_h, data_1, data_2, dev_r;
1.1       wiz      4175:        addr_h = (addr >>8) & 0xff;
                   4176:        addr_l = addr & 0xff;
                   4177:        dev_r = dev+1;
                   4178:
                   4179:        i2c_start(bktr);
                   4180:        i2c_write_byte(bktr,i2c_addr);
                   4181:        i2c_write_byte(bktr,dev_r);
                   4182:        i2c_write_byte(bktr,addr_h);
                   4183:        i2c_write_byte(bktr,addr_l);
                   4184:
                   4185:        i2c_start(bktr);
                   4186:        i2c_write_byte(bktr,i2c_addr+1);
                   4187:        i2c_read_byte(bktr,&data_1, 0);
                   4188:        i2c_read_byte(bktr,&data_2, 1);
                   4189:        i2c_stop(bktr);
                   4190:        data = (data_1<<8) | data_2;
                   4191:        return data;
                   4192: }
                   4193:
                   4194: /* Reset the MSP or DPL chip */
                   4195: /* The user can block the reset (which is handy if you initialise the
                   4196:  * MSP audio in another operating system first (eg in Windows)
                   4197:  */
1.28      wiz      4198: void msp_dpl_reset(bktr_ptr_t bktr, int i2c_addr) {
1.1       wiz      4199:
                   4200: #ifndef BKTR_NO_MSP_RESET
                   4201:        /* put into reset mode */
                   4202:        i2c_start(bktr);
                   4203:        i2c_write_byte(bktr, i2c_addr);
                   4204:        i2c_write_byte(bktr, 0x00);
                   4205:        i2c_write_byte(bktr, 0x80);
                   4206:        i2c_write_byte(bktr, 0x00);
                   4207:        i2c_stop(bktr);
                   4208:
                   4209:        /* put back to operational mode */
                   4210:        i2c_start(bktr);
                   4211:        i2c_write_byte(bktr, i2c_addr);
                   4212:        i2c_write_byte(bktr, 0x00);
                   4213:        i2c_write_byte(bktr, 0x00);
                   4214:        i2c_write_byte(bktr, 0x00);
                   4215:        i2c_stop(bktr);
                   4216: #endif
                   4217:        return;
                   4218:
                   4219: }
                   4220:
                   4221: static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
                   4222:
                   4223:        /* XXX errors ignored */
                   4224:        i2c_start(bktr);
                   4225:        i2c_write_byte(bktr,bktr->remote_control_addr);
                   4226:        i2c_read_byte(bktr,&(remote->data[0]), 0);
                   4227:        i2c_read_byte(bktr,&(remote->data[1]), 0);
                   4228:        i2c_read_byte(bktr,&(remote->data[2]), 0);
                   4229:        i2c_stop(bktr);
                   4230:
                   4231:        return;
                   4232: }
                   4233:
1.12      wiz      4234: #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
1.1       wiz      4235:
                   4236:
1.28      wiz      4237: #if defined(I2C_SOFTWARE_PROBE)
1.1       wiz      4238:
                   4239: /*
                   4240:  * we are keeping this around for any parts that we need to probe
                   4241:  * but that CANNOT be probed via an i2c read.
                   4242:  * this is necessary because the hardware i2c mechanism
                   4243:  * cannot be programmed for 1 byte writes.
                   4244:  * currently there are no known i2c parts that we need to probe
                   4245:  * and that cannot be safely read.
                   4246:  */
1.28      wiz      4247: static int     i2cProbe(bktr_ptr_t bktr, int addr);
1.1       wiz      4248: #define BITD           40
                   4249: #define EXTRA_START
                   4250:
                   4251: /*
                   4252:  * probe for an I2C device at addr.
                   4253:  */
                   4254: static int
1.28      wiz      4255: i2cProbe(bktr_ptr_t bktr, int addr)
1.1       wiz      4256: {
                   4257:        int             x, status;
                   4258:
                   4259:        /* the START */
1.28      wiz      4260: #if defined(EXTRA_START)
                   4261:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD);  /* release data */
                   4262:        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD);  /* release clock */
1.1       wiz      4263: #endif /* EXTRA_START */
1.28      wiz      4264:        OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD);  /* lower data */
                   4265:        OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD);  /* lower clock */
1.1       wiz      4266:
                   4267:        /* write addr */
1.28      wiz      4268:        for (x = 7; x >= 0; --x) {
                   4269:                if (addr & (1<<x)) {
1.1       wiz      4270:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
1.28      wiz      4271:                        DELAY(BITD);            /* assert HI data */
1.1       wiz      4272:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
1.28      wiz      4273:                        DELAY(BITD);            /* strobe clock */
1.1       wiz      4274:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
1.28      wiz      4275:                        DELAY(BITD);            /* release clock */
1.1       wiz      4276:                }
                   4277:                else {
1.2       wiz      4278:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
1.28      wiz      4279:                        DELAY(BITD);            /* assert LO data */
1.1       wiz      4280:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
1.28      wiz      4281:                        DELAY(BITD);            /* strobe clock */
1.1       wiz      4282:                        OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
1.28      wiz      4283:                        DELAY(BITD);            /* release clock */
1.1       wiz      4284:                }
                   4285:        }
                   4286:
                   4287:        /* look for an ACK */
1.28      wiz      4288:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD);  /* float data */
                   4289:        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD);  /* strobe clock */
1.1       wiz      4290:        status = INL(bktr, BKTR_I2C_DATA_CTL) & 1;      /* read the ACK bit */
1.28      wiz      4291:        OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD);  /* release clock */
1.1       wiz      4292:
                   4293:        /* the STOP */
1.28      wiz      4294:        OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD);  /* lower clock & data */
                   4295:        OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD);  /* release clock */
                   4296:        OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD);  /* release data */
1.1       wiz      4297:
1.28      wiz      4298:        return(status);
1.1       wiz      4299: }
                   4300: #undef EXTRA_START
                   4301: #undef BITD
                   4302:
                   4303: #endif /* I2C_SOFTWARE_PROBE */

CVSweb <webmaster@jp.NetBSD.org>