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