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