Update the bktr driver to match the current state of FreeBSD-current,
[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
SS
64 * $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.138 2005/01/09 17:42:03 cognet Exp
65 * $DragonFly: src/sys/dev/video/bktr/bktr_core.c,v 1.14 2005/03/12 11:35:27 corecode 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>
984263bc 117
a35cc233
JS
118#include <dev/video/meteor/ioctl_meteor.h>
119#include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
120#include <dev/video/bktr/bktr_reg.h>
121#include <dev/video/bktr/bktr_tuner.h>
122#include <dev/video/bktr/bktr_card.h>
123#include <dev/video/bktr/bktr_audio.h>
124#include <dev/video/bktr/bktr_os.h>
125#include <dev/video/bktr/bktr_core.h>
984263bc 126#if defined(BKTR_FREEBSD_MODULE)
a35cc233 127#include <dev/video/bktr/bktr_mem.h>
984263bc
MD
128#endif
129
130#if defined(BKTR_USE_FREEBSD_SMBUS)
a35cc233 131#include <dev/video/bktr/bktr_i2c.h>
1f2de5d4
MD
132#include <bus/smbus/smbconf.h>
133#include <bus/iicbus/iiconf.h>
984263bc
MD
134#include "smbus_if.h"
135#include "iicbus_if.h"
136#endif
137
138const char *
139bktr_name(bktr_ptr_t bktr)
140{
141 return bktr->bktr_xname;
142}
143
a35cc233 144typedef u_char bool_t;
984263bc 145
a35cc233
JS
146#define BKTRPRI PCATCH
147#define VBIPRI PCATCH
984263bc
MD
148
149
984263bc
MD
150/*
151 * memory allocated for DMA programs
152 */
153#define DMA_PROG_ALLOC (8 * PAGE_SIZE)
154
155/* When to split a dma transfer , the bt848 has timing as well as
156 dma transfer size limitations so that we have to split dma
157 transfers into two dma requests
158 */
159#define DMA_BT848_SPLIT 319*2
160
161/*
162 * Allocate enough memory for:
163 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
164 *
165 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
166 * in your kernel configuration file.
167 */
168
169#ifndef BROOKTREE_ALLOC_PAGES
170#define BROOKTREE_ALLOC_PAGES 217*4
171#endif
172#define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
173
174/* Definitions for VBI capture.
175 * There are 16 VBI lines in a PAL video field (32 in a frame),
176 * and we take 2044 samples from each line (placed in a 2048 byte buffer
177 * for alignment).
178 * VBI lines are held in a circular buffer before being read by a
179 * user program from /dev/vbi.
180 */
181
182#define MAX_VBI_LINES 16 /* Maximum for all vidoe formats */
183#define VBI_LINE_SIZE 2048 /* Store upto 2048 bytes per line */
184#define VBI_BUFFER_ITEMS 20 /* Number of frames we buffer */
185#define VBI_DATA_SIZE (VBI_LINE_SIZE * MAX_VBI_LINES * 2)
186#define VBI_BUFFER_SIZE (VBI_DATA_SIZE * VBI_BUFFER_ITEMS)
187
188
189/* Defines for fields */
190#define ODD_F 0x01
191#define EVEN_F 0x02
192
193
194/*
195 * Parameters describing size of transmitted image.
196 */
197
198static struct format_params format_params[] = {
199/* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
200 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO,
201 12, 1600 },
202/* # define BT848_IFORM_F_NTSCM (0x1) */
203 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
204 12, 1600 },
205/* # define BT848_IFORM_F_NTSCJ (0x2) */
206 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
207 12, 1600 },
208/* # define BT848_IFORM_F_PALBDGHI (0x3) */
209 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
210 16, 2044 },
211/* # define BT848_IFORM_F_PALM (0x4) */
212 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0,
213 12, 1600 },
214/* # define BT848_IFORM_F_PALN (0x5) */
215 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1,
216 16, 2044 },
217/* # define BT848_IFORM_F_SECAM (0x6) */
218 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1,
219 16, 2044 },
220/* # define BT848_IFORM_F_RSVD (0x7) - ???? */
221 { 625, 32, 576, 1135, 186, 924, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0,
222 16, 2044 },
223};
224
225/*
226 * Table of supported Pixel Formats
227 */
228
229static struct meteor_pixfmt_internal {
230 struct meteor_pixfmt public;
231 u_int color_fmt;
232} pixfmt_table[] = {
233
234{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
235{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
236
237{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
238{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
239
240{ { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
241
242{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
243{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
244{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
245{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
246{ { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
247{ { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
248{ { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
249
250};
251#define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
252
253/*
254 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
255 */
256
257/* FIXME: Also add YUV_422 and YUV_PACKED as well */
258static struct {
259 u_long meteor_format;
260 struct meteor_pixfmt public;
261} meteor_pixfmt_table[] = {
262 { METEOR_GEO_YUV_12,
263 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
264 },
265
266 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
267 { METEOR_GEO_YUV_422,
268 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
269 },
270 { METEOR_GEO_YUV_PACKED,
271 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
272 },
273 { METEOR_GEO_RGB16,
274 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
275 },
276 { METEOR_GEO_RGB24,
277 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
278 },
279
280};
281#define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
282 sizeof(meteor_pixfmt_table[0]) )
283
284
285#define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
286#define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
287
288
289
290/* sync detect threshold */
291#if 0
292#define SYNC_LEVEL (BT848_ADC_RESERVED | \
293 BT848_ADC_CRUSH) /* threshold ~125 mV */
294#else
295#define SYNC_LEVEL (BT848_ADC_RESERVED | \
296 BT848_ADC_SYNC_T) /* threshold ~75 mV */
297#endif
298
299
300
301
302/* debug utility for holding previous INT_STAT contents */
303#define STATUS_SUM
304static u_long status_sum = 0;
305
306/*
307 * defines to make certain bit-fiddles understandable
308 */
309#define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
310#define RISC_ENABLED BT848_DMA_CTL_RISC_EN
311#define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
312#define FIFO_RISC_DISABLED 0
313
314#define ALL_INTS_DISABLED 0
315#define ALL_INTS_CLEARED 0xffffffff
316#define CAPTURE_OFF 0
317
318#define BIT_SEVEN_HIGH (1<<7)
319#define BIT_EIGHT_HIGH (1<<8)
320
321#define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
322#define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
323
324
325
326static int oformat_meteor_to_bt( u_long format );
327
328static u_int pixfmt_swap_flags( int pixfmt );
329
330/*
331 * bt848 RISC programming routines.
332 */
333#ifdef BT848_DUMP
334static int dump_bt848( bktr_ptr_t bktr );
335#endif
336
337static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
338 int rows, int interlace );
339static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
340 int rows, int interlace );
341static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
342 int rows, int interlace );
343static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
344 int rows, int interlace );
345static void rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols,
346 int rows, int interlace );
347static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
348
349static bool_t getline(bktr_reg_t *, int);
350static bool_t notclipped(bktr_reg_t * , int , int);
7f5487a0 351static bool_t split(bktr_reg_t *, volatile uint32_t **, int, u_long, int,
984263bc
MD
352 volatile u_char ** , int );
353
354static void start_capture( bktr_ptr_t bktr, unsigned type );
355static void set_fps( bktr_ptr_t bktr, u_short fps );
356
357
358
359/*
360 * Remote Control Functions
361 */
362static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote);
363
364
365/*
366 * ioctls common to both video & tuner.
367 */
368static int common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg );
369
370
371#if !defined(BKTR_USE_FREEBSD_SMBUS)
372/*
373 * i2c primitives for low level control of i2c bus. Added for MSP34xx control
374 */
375static void i2c_start( bktr_ptr_t bktr);
376static void i2c_stop( bktr_ptr_t bktr);
377static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data);
378static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last );
379#endif
380
381
382
383/*
384 * the common attach code, used by all OS versions.
385 */
386void
387common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
388{
389 vm_offset_t buf = 0;
390 int need_to_allocate_memory = 1;
a35cc233
JS
391#ifdef BKTR_NEW_MSP34XX_DRIVER
392 int err;
984263bc
MD
393#endif
394
984263bc
MD
395/* If this is a module, check if there is any currently saved contiguous memory */
396#if defined(BKTR_FREEBSD_MODULE)
397 if (bktr_has_stored_addresses(unit) == 1) {
398 /* recover the addresses */
399 bktr->dma_prog = bktr_retrieve_address(unit, BKTR_MEM_DMA_PROG);
400 bktr->odd_dma_prog = bktr_retrieve_address(unit, BKTR_MEM_ODD_DMA_PROG);
401 bktr->vbidata = bktr_retrieve_address(unit, BKTR_MEM_VBIDATA);
402 bktr->vbibuffer = bktr_retrieve_address(unit, BKTR_MEM_VBIBUFFER);
403 buf = bktr_retrieve_address(unit, BKTR_MEM_BUF);
404 need_to_allocate_memory = 0;
405 }
406#endif
407
408 if (need_to_allocate_memory == 1) {
409 /* allocate space for dma program */
410 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
411 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
412
413 /* allocte space for the VBI buffer */
414 bktr->vbidata = get_bktr_mem(unit, VBI_DATA_SIZE);
415 bktr->vbibuffer = get_bktr_mem(unit, VBI_BUFFER_SIZE);
416
417 /* allocate space for pixel buffer */
418 if ( BROOKTREE_ALLOC )
419 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
420 else
421 buf = 0;
422 }
984263bc 423
a35cc233
JS
424#ifdef USE_VBIMUTEX
425 mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
426#endif
984263bc
MD
427
428/* If this is a module, save the current contiguous memory */
429#if defined(BKTR_FREEBSD_MODULE)
430bktr_store_address(unit, BKTR_MEM_DMA_PROG, bktr->dma_prog);
431bktr_store_address(unit, BKTR_MEM_ODD_DMA_PROG, bktr->odd_dma_prog);
432bktr_store_address(unit, BKTR_MEM_VBIDATA, bktr->vbidata);
433bktr_store_address(unit, BKTR_MEM_VBIBUFFER, bktr->vbibuffer);
434bktr_store_address(unit, BKTR_MEM_BUF, buf);
435#endif
436
437
438 if ( bootverbose ) {
a7d4e7e7 439 printf("%s: buffer size %d, addr %p\n",
a35cc233 440 bktr_name(bktr), BROOKTREE_ALLOC,
a7d4e7e7 441 (void *)(uintptr_t)vtophys(buf));
984263bc
MD
442 }
443
444 if ( buf != 0 ) {
445 bktr->bigbuf = buf;
446 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
447 bzero((caddr_t) bktr->bigbuf, BROOKTREE_ALLOC);
448 } else {
449 bktr->alloc_pages = 0;
450 }
451
452
453 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
454 METEOR_DEV0 | METEOR_RGB16;
455 bktr->dma_prog_loaded = FALSE;
456 bktr->cols = 640;
457 bktr->rows = 480;
458 bktr->frames = 1; /* one frame */
459 bktr->format = METEOR_GEO_RGB16;
460 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
461 bktr->pixfmt_compat = TRUE;
462
463
464 bktr->vbiinsert = 0;
465 bktr->vbistart = 0;
466 bktr->vbisize = 0;
467 bktr->vbiflags = 0;
468
469
470 /* using the pci device id and revision id */
471 /* and determine the card type */
472 if (PCI_VENDOR(pci_id) == PCI_VENDOR_BROOKTREE)
473 {
474 switch (PCI_PRODUCT(pci_id)) {
475 case PCI_PRODUCT_BROOKTREE_BT848:
476 if (rev == 0x12)
477 bktr->id = BROOKTREE_848A;
478 else
479 bktr->id = BROOKTREE_848;
480 break;
481 case PCI_PRODUCT_BROOKTREE_BT849:
482 bktr->id = BROOKTREE_849A;
483 break;
484 case PCI_PRODUCT_BROOKTREE_BT878:
485 bktr->id = BROOKTREE_878;
486 break;
487 case PCI_PRODUCT_BROOKTREE_BT879:
488 bktr->id = BROOKTREE_879;
489 break;
490 }
491 };
492
493 bktr->clr_on_start = FALSE;
494
495 /* defaults for the tuner section of the card */
496 bktr->tflags = TUNER_INITALIZED;
497 bktr->tuner.frequency = 0;
498 bktr->tuner.channel = 0;
499 bktr->tuner.chnlset = DEFAULT_CHNLSET;
500 bktr->tuner.afc = 0;
501 bktr->tuner.radio_mode = 0;
502 bktr->audio_mux_select = 0;
503 bktr->audio_mute_state = FALSE;
504 bktr->bt848_card = -1;
505 bktr->bt848_tuner = -1;
506 bktr->reverse_mute = -1;
507 bktr->slow_msp_audio = 0;
508 bktr->msp_use_mono_source = 0;
509 bktr->msp_source_selected = -1;
510 bktr->audio_mux_present = 1;
511
a35cc233
JS
512#ifdef BKTR_NEW_MSP34XX_DRIVER
513 /* get hint on short programming of the msp34xx, so we know */
514 /* if the decision what thread to start should be overwritten */
515 if ( (err = resource_int_value("bktr", unit, "mspsimple",
516 &(bktr->mspsimple)) ) != 0 )
517 bktr->mspsimple = -1; /* fall back to default */
518#endif
519
984263bc
MD
520 probeCard( bktr, TRUE, unit );
521
522 /* Initialise any MSP34xx or TDA98xx audio chips */
523 init_audio_devices( bktr );
524
a35cc233
JS
525#ifdef BKTR_NEW_MSP34XX_DRIVER
526 /* setup the kenrel thread */
527 err = msp_attach( bktr );
528 if ( err != 0 ) /* error doing kernel thread stuff, disable msp3400c */
529 bktr->card.msp3400c = 0;
530#endif
531
532
984263bc
MD
533}
534
535
536/* Copy the vbi lines from 'vbidata' into the circular buffer, 'vbibuffer'.
537 * The circular buffer holds 'n' fixed size data blocks.
538 * vbisize is the number of bytes in the circular buffer
539 * vbiread is the point we reading data out of the circular buffer
540 * vbiinsert is the point we insert data into the circular buffer
541 */
542static void vbidecode(bktr_ptr_t bktr) {
543 unsigned char *dest;
544 unsigned int *seq_dest;
545
546 /* Check if there is room in the buffer to insert the data. */
547 if (bktr->vbisize + VBI_DATA_SIZE > VBI_BUFFER_SIZE) return;
548
549 /* Copy the VBI data into the next free slot in the buffer. */
550 /* 'dest' is the point in vbibuffer where we want to insert new data */
551 dest = (unsigned char *)bktr->vbibuffer + bktr->vbiinsert;
552 memcpy(dest, (unsigned char*)bktr->vbidata, VBI_DATA_SIZE);
553
554 /* Write the VBI sequence number to the end of the vbi data */
555 /* This is used by the AleVT teletext program */
556 seq_dest = (unsigned int *)((unsigned char *)bktr->vbibuffer
557 + bktr->vbiinsert
558 + (VBI_DATA_SIZE - sizeof(bktr->vbi_sequence_number)));
559 *seq_dest = bktr->vbi_sequence_number;
560
561 /* And increase the VBI sequence number */
562 /* This can wrap around */
563 bktr->vbi_sequence_number++;
564
565
566 /* Increment the vbiinsert pointer */
567 /* This can wrap around */
568 bktr->vbiinsert += VBI_DATA_SIZE;
569 bktr->vbiinsert = (bktr->vbiinsert % VBI_BUFFER_SIZE);
570
571 /* And increase the amount of vbi data in the buffer */
572 bktr->vbisize = bktr->vbisize + VBI_DATA_SIZE;
573
574}
575
576
577/*
578 * the common interrupt handler.
579 * Returns a 0 or 1 depending on whether the interrupt has handled.
580 * In the OS specific section, bktr_intr() is defined which calls this
581 * common interrupt handler.
582 */
583int
584common_bktr_intr( void *arg )
585{
586 bktr_ptr_t bktr;
587 u_long bktr_status;
588 u_char dstatus;
589 u_long field;
590 u_long w_field;
591 u_long req_field;
592
593 bktr = (bktr_ptr_t) arg;
594
595 /*
596 * check to see if any interrupts are unmasked on this device. If
597 * none are, then we likely got here by way of being on a PCI shared
598 * interrupt dispatch list.
599 */
600 if (INL(bktr, BKTR_INT_MASK) == ALL_INTS_DISABLED)
601 return 0; /* bail out now, before we do something we
602 shouldn't */
603
604 if (!(bktr->flags & METEOR_OPEN)) {
605 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
606 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
607 /* return; ?? */
608 }
609
610 /* record and clear the INTerrupt status bits */
611 bktr_status = INL(bktr, BKTR_INT_STAT);
612 OUTL(bktr, BKTR_INT_STAT, bktr_status & ~I2C_BITS); /* don't touch i2c */
613
614 /* record and clear the device status register */
615 dstatus = INB(bktr, BKTR_DSTATUS);
616 OUTB(bktr, BKTR_DSTATUS, 0x00);
617
618#if defined( STATUS_SUM )
619 /* add any new device status or INTerrupt status bits */
620 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
621 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
622#endif /* STATUS_SUM */
623 /* printf( "%s: STATUS %x %x %x \n", bktr_name(bktr),
624 dstatus, bktr_status, INL(bktr, BKTR_RISC_COUNT) );
625 */
626
627
628 /* if risc was disabled re-start process again */
629 /* if there was one of the following errors re-start again */
630 if ( !(bktr_status & BT848_INT_RISC_EN) ||
631 ((bktr_status &(/* BT848_INT_FBUS | */
632 /* BT848_INT_FTRGT | */
633 /* BT848_INT_FDSR | */
634 BT848_INT_PPERR |
635 BT848_INT_RIPERR | BT848_INT_PABORT |
636 BT848_INT_OCERR | BT848_INT_SCERR) ) != 0)
637 || ((INB(bktr, BKTR_TDEC) == 0) && (bktr_status & TDEC_BITS)) ) {
638
639 u_short tdec_save = INB(bktr, BKTR_TDEC);
640
641 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
642 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
643
644 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
645
646 /* Reset temporal decimation counter */
647 OUTB(bktr, BKTR_TDEC, 0);
648 OUTB(bktr, BKTR_TDEC, tdec_save);
649
650 /* Reset to no-fields captured state */
651 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
652 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
653 case METEOR_ONLY_ODD_FIELDS:
654 bktr->flags |= METEOR_WANT_ODD;
655 break;
656 case METEOR_ONLY_EVEN_FIELDS:
657 bktr->flags |= METEOR_WANT_EVEN;
658 break;
659 default:
660 bktr->flags |= METEOR_WANT_MASK;
661 break;
662 }
663 }
664
665 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
666 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
667 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
668
669 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
670 BT848_INT_RISCI |
671 BT848_INT_VSYNC |
672 BT848_INT_FMTCHG);
673
674 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
675 return 1;
676 }
677
678 /* If this is not a RISC program interrupt, return */
679 if (!(bktr_status & BT848_INT_RISCI))
680 return 0;
681
682/**
683 printf( "%s: intr status %x %x %x\n", bktr_name(bktr),
684 bktr_status, dstatus, INL(bktr, BKTR_RISC_COUNT) );
685 */
686
687
688 /*
689 * Disable future interrupts if a capture mode is not selected.
690 * This can happen when we are in the process of closing or
691 * changing capture modes, otherwise it shouldn't happen.
692 */
693 if (!(bktr->flags & METEOR_CAP_MASK))
694 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
695
696
697 /* Determine which field generated this interrupt */
698 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
699
700
701 /*
702 * Process the VBI data if it is being captured. We do this once
703 * both Odd and Even VBI data is captured. Therefore we do this
704 * in the Even field interrupt handler.
705 */
a35cc233 706 LOCK_VBI(bktr);
984263bc
MD
707 if ( (bktr->vbiflags & VBI_CAPTURE)
708 &&(bktr->vbiflags & VBI_OPEN)
709 &&(field==EVEN_F)) {
710 /* Put VBI data into circular buffer */
711 vbidecode(bktr);
712
713 /* If someone is blocked on reading from /dev/vbi, wake them */
714 if (bktr->vbi_read_blocked) {
715 bktr->vbi_read_blocked = FALSE;
716 wakeup(VBI_SLEEP);
717 }
718
719 /* If someone has a select() on /dev/vbi, inform them */
720 if (bktr->vbi_select.si_pid) {
721 selwakeup(&bktr->vbi_select);
722 }
723
724
725 }
a35cc233 726 UNLOCK_VBI(bktr);
984263bc
MD
727
728 /*
729 * Register the completed field
730 * (For dual-field mode, require fields from the same frame)
731 */
732 switch ( bktr->flags & METEOR_WANT_MASK ) {
733 case METEOR_WANT_ODD : w_field = ODD_F ; break;
734 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
735 default : w_field = (ODD_F|EVEN_F); break;
736 }
737 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
738 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
739 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
740 default : req_field = (ODD_F|EVEN_F);
741 break;
742 }
743
744 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
745 bktr->flags &= ~METEOR_WANT_EVEN;
746 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
747 ( w_field == ODD_F ))
748 bktr->flags &= ~METEOR_WANT_ODD;
749 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
750 ( w_field == (ODD_F|EVEN_F) ))
751 bktr->flags &= ~METEOR_WANT_ODD;
752 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
753 ( w_field == ODD_F )) {
754 bktr->flags &= ~METEOR_WANT_ODD;
755 bktr->flags |= METEOR_WANT_EVEN;
756 }
757 else {
758 /* We're out of sync. Start over. */
759 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
760 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
761 case METEOR_ONLY_ODD_FIELDS:
762 bktr->flags |= METEOR_WANT_ODD;
763 break;
764 case METEOR_ONLY_EVEN_FIELDS:
765 bktr->flags |= METEOR_WANT_EVEN;
766 break;
767 default:
768 bktr->flags |= METEOR_WANT_MASK;
769 break;
770 }
771 }
772 return 1;
773 }
774
775 /*
776 * If we have a complete frame.
777 */
778 if (!(bktr->flags & METEOR_WANT_MASK)) {
779 bktr->frames_captured++;
780 /*
781 * post the completion time.
782 */
783 if (bktr->flags & METEOR_WANT_TS) {
784 struct timeval *ts;
785
786 if ((u_int) bktr->alloc_pages * PAGE_SIZE
787 <= (bktr->frame_size + sizeof(struct timeval))) {
788 ts =(struct timeval *)bktr->bigbuf +
789 bktr->frame_size;
790 /* doesn't work in synch mode except
791 * for first frame */
792 /* XXX */
793 microtime(ts);
794 }
795 }
796
797
798 /*
799 * Wake up the user in single capture mode.
800 */
801 if (bktr->flags & METEOR_SINGLE) {
802
803 /* stop dma */
804 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
805
806 /* disable risc, leave fifo running */
807 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
808 wakeup(BKTR_SLEEP);
809 }
810
811 /*
812 * If the user requested to be notified via signal,
813 * let them know the frame is complete.
814 */
815
a35cc233
JS
816 if (bktr->proc != NULL) {
817 PROC_LOCK(bktr->proc);
818 psignal( bktr->proc, bktr->signal);
819 PROC_UNLOCK(bktr->proc);
cd4a700d 820 }
984263bc
MD
821
822 /*
823 * Reset the want flags if in continuous or
824 * synchronous capture mode.
825 */
826/*
827* XXX NOTE (Luigi):
828* currently we only support 3 capture modes: odd only, even only,
829* odd+even interlaced (odd field first). A fourth mode (non interlaced,
830* either even OR odd) could provide 60 (50 for PAL) pictures per
831* second, but it would require this routine to toggle the desired frame
832* each time, and one more different DMA program for the Bt848.
833* As a consequence, this fourth mode is currently unsupported.
834*/
835
836 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
837 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
838 case METEOR_ONLY_ODD_FIELDS:
839 bktr->flags |= METEOR_WANT_ODD;
840 break;
841 case METEOR_ONLY_EVEN_FIELDS:
842 bktr->flags |= METEOR_WANT_EVEN;
843 break;
844 default:
845 bktr->flags |= METEOR_WANT_MASK;
846 break;
847 }
848 }
849 }
850
851 return 1;
852}
853
854
855
856
857/*
858 *
859 */
860extern int bt848_format; /* used to set the default format, PAL or NTSC */
861int
862video_open( bktr_ptr_t bktr )
863{
864 int frame_rate, video_format=0;
865
866 if (bktr->flags & METEOR_OPEN) /* device is busy */
867 return( EBUSY );
868
869 bktr->flags |= METEOR_OPEN;
870
871#ifdef BT848_DUMP
872 dump_bt848( bt848 );
873#endif
874
875 bktr->clr_on_start = FALSE;
876
877 OUTB(bktr, BKTR_DSTATUS, 0x00); /* clear device status reg. */
878
879 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
880
881#if BKTR_SYSTEM_DEFAULT == BROOKTREE_PAL
882 video_format = 0;
883#else
884 video_format = 1;
885#endif
886
887 if (bt848_format == 0 )
888 video_format = 0;
889
890 if (bt848_format == 1 )
891 video_format = 1;
892
893 if (video_format == 1 ) {
894 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_NTSCM);
895 bktr->format_params = BT848_IFORM_F_NTSCM;
896
897 } else {
898 OUTB(bktr, BKTR_IFORM, BT848_IFORM_F_PALBDGHI);
899 bktr->format_params = BT848_IFORM_F_PALBDGHI;
900
901 }
902
903 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | format_params[bktr->format_params].iform_xtsel);
904
905 /* work around for new Hauppauge 878 cards */
906 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
907 (bktr->id==BROOKTREE_878 || bktr->id==BROOKTREE_879) )
908 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
909 else
910 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
911
912 OUTB(bktr, BKTR_ADELAY, format_params[bktr->format_params].adelay);
913 OUTB(bktr, BKTR_BDELAY, format_params[bktr->format_params].bdelay);
914 frame_rate = format_params[bktr->format_params].frame_rate;
915
916 /* enable PLL mode using 28Mhz crystal for PAL/SECAM users */
917 if (bktr->xtal_pll_mode == BT848_USE_PLL) {
918 OUTB(bktr, BKTR_TGCTRL, 0);
919 OUTB(bktr, BKTR_PLL_F_LO, 0xf9);
920 OUTB(bktr, BKTR_PLL_F_HI, 0xdc);
921 OUTB(bktr, BKTR_PLL_F_XCI, 0x8e);
922 }
923
924 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
925
926 bktr->max_clip_node = 0;
927
928 OUTB(bktr, BKTR_COLOR_CTL, BT848_COLOR_CTL_GAMMA | BT848_COLOR_CTL_RGB_DED);
929
930 OUTB(bktr, BKTR_E_HSCALE_LO, 170);
931 OUTB(bktr, BKTR_O_HSCALE_LO, 170);
932
933 OUTB(bktr, BKTR_E_DELAY_LO, 0x72);
934 OUTB(bktr, BKTR_O_DELAY_LO, 0x72);
935 OUTB(bktr, BKTR_E_SCLOOP, 0);
936 OUTB(bktr, BKTR_O_SCLOOP, 0);
937
938 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
939 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
940
941 bktr->fifo_errors = 0;
942 bktr->dma_errors = 0;
943 bktr->frames_captured = 0;
944 bktr->even_fields_captured = 0;
945 bktr->odd_fields_captured = 0;
a35cc233 946 bktr->proc = NULL;
984263bc
MD
947 set_fps(bktr, frame_rate);
948 bktr->video.addr = 0;
949 bktr->video.width = 0;
950 bktr->video.banksize = 0;
951 bktr->video.ramsize = 0;
952 bktr->pixfmt_compat = TRUE;
953 bktr->format = METEOR_GEO_RGB16;
954 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
955
956 bktr->capture_area_enabled = FALSE;
957
958 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT); /* if you take this out triton
959 based motherboards will
960 operate unreliably */
961 return( 0 );
962}
963
964int
965vbi_open( bktr_ptr_t bktr )
966{
a35cc233
JS
967
968 LOCK_VBI(bktr);
969
970 if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
971 UNLOCK_VBI(bktr);
984263bc 972 return( EBUSY );
a35cc233 973 }
984263bc
MD
974
975 bktr->vbiflags |= VBI_OPEN;
976
977 /* reset the VBI circular buffer pointers and clear the buffers */
978 bktr->vbiinsert = 0;
979 bktr->vbistart = 0;
980 bktr->vbisize = 0;
981 bktr->vbi_sequence_number = 0;
982 bktr->vbi_read_blocked = FALSE;
983
984 bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
985 bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
986
a35cc233
JS
987 UNLOCK_VBI(bktr);
988
984263bc
MD
989 return( 0 );
990}
991
992/*
993 *
994 */
995int
996tuner_open( bktr_ptr_t bktr )
997{
998 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
999 return( ENXIO );
1000
1001 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1002 return( 0 );
1003
1004 bktr->tflags |= TUNER_OPEN;
1005 bktr->tuner.frequency = 0;
1006 bktr->tuner.channel = 0;
1007 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1008 bktr->tuner.afc = 0;
1009 bktr->tuner.radio_mode = 0;
1010
1011 /* enable drivers on the GPIO port that control the MUXes */
1012 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) | bktr->card.gpio_mux_bits);
1013
1014 /* unmute the audio stream */
1015 set_audio( bktr, AUDIO_UNMUTE );
1016
1017 /* Initialise any audio chips, eg MSP34xx or TDA98xx */
1018 init_audio_devices( bktr );
1019
1020 return( 0 );
1021}
1022
1023
1024
1025
1026/*
1027 *
1028 */
1029int
1030video_close( bktr_ptr_t bktr )
1031{
1032 bktr->flags &= ~(METEOR_OPEN |
1033 METEOR_SINGLE |
1034 METEOR_CAP_MASK |
1035 METEOR_WANT_MASK);
1036
1037 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1038 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1039
1040 bktr->dma_prog_loaded = FALSE;
1041 OUTB(bktr, BKTR_TDEC, 0);
1042 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1043
1044/** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1045 OUTL(bktr, BKTR_SRESET, 0xf);
1046 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1047
1048 return( 0 );
1049}
1050
1051
1052/*
1053 * tuner close handle,
1054 * place holder for tuner specific operations on a close.
1055 */
1056int
1057tuner_close( bktr_ptr_t bktr )
1058{
1059 bktr->tflags &= ~TUNER_OPEN;
1060
1061 /* mute the audio by switching the mux */
1062 set_audio( bktr, AUDIO_MUTE );
1063
1064 /* disable drivers on the GPIO port that control the MUXes */
1065 OUTL(bktr, BKTR_GPIO_OUT_EN, INL(bktr, BKTR_GPIO_OUT_EN) & ~bktr->card.gpio_mux_bits);
1066
1067 return( 0 );
1068}
1069
1070int
1071vbi_close( bktr_ptr_t bktr )
1072{
1073
a35cc233
JS
1074 LOCK_VBI(bktr);
1075
984263bc
MD
1076 bktr->vbiflags &= ~VBI_OPEN;
1077
a35cc233
JS
1078 UNLOCK_VBI(bktr);
1079
984263bc
MD
1080 return( 0 );
1081}
1082
1083/*
1084 *
1085 */
1086int
1087video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
1088{
1089 int status;
1090 int count;
1091
1092
1093 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1094 return( ENOMEM );
1095
1096 if (bktr->flags & METEOR_CAP_MASK)
1097 return( EIO ); /* already capturing */
1098
1099 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1100
1101
1102 count = bktr->rows * bktr->cols *
1103 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1104
1105 if ((int) uio->uio_iov->iov_len < count)
1106 return( EINVAL );
1107
1108 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1109
1110 /* capture one frame */
1111 start_capture(bktr, METEOR_SINGLE);
1112 /* wait for capture to complete */
1113 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1114 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1115 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1116 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1117 BT848_INT_RISCI |
1118 BT848_INT_VSYNC |
1119 BT848_INT_FMTCHG);
1120
1121
a35cc233 1122 status = tsleep(BKTR_SLEEP, BKTRPRI, "captur", 0);
984263bc
MD
1123 if (!status) /* successful capture */
1124 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1125 else
1126 printf ("%s: read: tsleep error %d\n",
1127 bktr_name(bktr), status);
1128
1129 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1130
1131 return( status );
1132}
1133
1134/*
1135 * Read VBI data from the vbi circular buffer
1136 * The buffer holds vbi data blocks which are the same size
1137 * vbiinsert is the position we will insert the next item into the buffer
1138 * vbistart is the actual position in the buffer we want to read from
1139 * vbisize is the exact number of bytes in the buffer left to read
1140 */
1141int
1142vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1143{
a7d4e7e7 1144 int readsize, readsize2, start;
984263bc
MD
1145 int status;
1146
a35cc233
JS
1147 /*
1148 * XXX - vbi_read() should be protected against being re-entered
1149 * while it is unlocked for the uiomove.
1150 */
1151 LOCK_VBI(bktr);
984263bc
MD
1152
1153 while(bktr->vbisize == 0) {
1154 if (ioflag & IO_NDELAY) {
a35cc233
JS
1155 status = EWOULDBLOCK;
1156 goto out;
984263bc
MD
1157 }
1158
1159 bktr->vbi_read_blocked = TRUE;
a35cc233
JS
1160#ifdef USE_VBIMUTEX
1161 if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
1162 0))) {
1163 goto out;
984263bc 1164 }
a35cc233
JS
1165#else
1166 if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
1167 goto out;
1168 }
1169#endif
984263bc
MD
1170 }
1171
1172 /* Now we have some data to give to the user */
1173
1174 /* We cannot read more bytes than there are in
1175 * the circular buffer
1176 */
1177 readsize = (int)uio->uio_iov->iov_len;
1178
1179 if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1180
1181 /* Check if we can read this number of bytes without having
1182 * to wrap around the circular buffer */
1183 if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1184 /* We need to wrap around */
1185
1186 readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
a35cc233
JS
1187 start = bktr->vbistart;
1188 UNLOCK_VBI(bktr);
a7d4e7e7
MD
1189 status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
1190 if (status == 0)
1191 status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
984263bc 1192 } else {
a35cc233 1193 UNLOCK_VBI(bktr);
984263bc
MD
1194 /* We do not need to wrap around */
1195 status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1196 }
1197
a35cc233
JS
1198 LOCK_VBI(bktr);
1199
984263bc
MD
1200 /* Update the number of bytes left to read */
1201 bktr->vbisize -= readsize;
1202
1203 /* Update vbistart */
1204 bktr->vbistart += readsize;
1205 bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1206
a35cc233
JS
1207out:
1208 UNLOCK_VBI(bktr);
1209
984263bc
MD
1210 return( status );
1211
1212}
1213
1214
1215
1216/*
1217 * video ioctls
1218 */
1219int
a35cc233 1220video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
984263bc
MD
1221{
1222 volatile u_char c_temp;
1223 unsigned int temp;
1224 unsigned int temp_iform;
1225 unsigned int error;
1226 struct meteor_geomet *geo;
1227 struct meteor_counts *counts;
1228 struct meteor_video *video;
1229 struct bktr_capture_area *cap_area;
1230 vm_offset_t buf;
1231 int i;
a7d4e7e7 1232 int sig;
984263bc
MD
1233 char char_temp;
1234
1235 switch ( cmd ) {
1236
1237 case BT848SCLIP: /* set clip region */
1238 bktr->max_clip_node = 0;
1239 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1240
1241 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1242 if (bktr->clip_list[i].y_min == 0 &&
1243 bktr->clip_list[i].y_max == 0)
1244 break;
1245 }
1246 bktr->max_clip_node = i;
1247
1248 /* make sure that the list contains a valid clip secquence */
1249 /* the clip rectangles should be sorted by x then by y as the
1250 second order sort key */
1251
1252 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1253
1254 /* to disable clipping set y_min and y_max to 0 in the first
1255 clip rectangle . The first clip rectangle is clip_list[0].
1256 */
1257
1258
1259
1260 if (bktr->max_clip_node == 0 &&
1261 (bktr->clip_list[0].y_min != 0 &&
1262 bktr->clip_list[0].y_max != 0)) {
1263 return EINVAL;
1264 }
1265
1266 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1267 if (bktr->clip_list[i].y_min == 0 &&
1268 bktr->clip_list[i].y_max == 0) {
1269 break;
1270 }
1271 if ( bktr->clip_list[i+1].y_min != 0 &&
1272 bktr->clip_list[i+1].y_max != 0 &&
1273 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1274
1275 bktr->max_clip_node = 0;
1276 return (EINVAL);
1277
1278 }
1279
1280 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1281 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1282 bktr->clip_list[i].x_min < 0 ||
1283 bktr->clip_list[i].x_max < 0 ||
1284 bktr->clip_list[i].y_min < 0 ||
1285 bktr->clip_list[i].y_max < 0 ) {
1286 bktr->max_clip_node = 0;
1287 return (EINVAL);
1288 }
1289 }
1290
1291 bktr->dma_prog_loaded = FALSE;
1292
1293 break;
1294
1295 case METEORSTATUS: /* get Bt848 status */
1296 c_temp = INB(bktr, BKTR_DSTATUS);
1297 temp = 0;
1298 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1299 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1300 *(u_short *)arg = temp;
1301 break;
1302
1303 case BT848SFMT: /* set input format */
1304 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
1305 temp_iform = INB(bktr, BKTR_IFORM);
1306 temp_iform &= ~BT848_IFORM_FORMAT;
1307 temp_iform &= ~BT848_IFORM_XTSEL;
1308 OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1309 switch( temp ) {
1310 case BT848_IFORM_F_AUTO:
1311 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1312 METEOR_AUTOMODE;
1313 break;
1314
1315 case BT848_IFORM_F_NTSCM:
1316 case BT848_IFORM_F_NTSCJ:
1317 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1318 METEOR_NTSC;
1319 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1320 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1321 bktr->format_params = temp;
1322 break;
1323
1324 case BT848_IFORM_F_PALBDGHI:
1325 case BT848_IFORM_F_PALN:
1326 case BT848_IFORM_F_SECAM:
1327 case BT848_IFORM_F_RSVD:
1328 case BT848_IFORM_F_PALM:
1329 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1330 METEOR_PAL;
1331 OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1332 OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1333 bktr->format_params = temp;
1334 break;
1335
1336 }
1337 bktr->dma_prog_loaded = FALSE;
1338 break;
1339
1340 case METEORSFMT: /* set input format */
1341 temp_iform = INB(bktr, BKTR_IFORM);
1342 temp_iform &= ~BT848_IFORM_FORMAT;
1343 temp_iform &= ~BT848_IFORM_XTSEL;
1344 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
1345 case 0: /* default */
1346 case METEOR_FMT_NTSC:
1347 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1348 METEOR_NTSC;
1349 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1350 format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1351 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1352 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1353 bktr->format_params = BT848_IFORM_F_NTSCM;
1354 break;
1355
1356 case METEOR_FMT_PAL:
1357 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1358 METEOR_PAL;
1359 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1360 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1361 OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1362 OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1363 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1364 break;
1365
1366 case METEOR_FMT_AUTOMODE:
1367 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1368 METEOR_AUTOMODE;
1369 OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1370 format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1371 break;
1372
1373 default:
1374 return( EINVAL );
1375 }
1376 bktr->dma_prog_loaded = FALSE;
1377 break;
1378
1379 case METEORGFMT: /* get input format */
1380 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
1381 break;
1382
1383
1384 case BT848GFMT: /* get input format */
1385 *(u_long *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1386 break;
1387
1388 case METEORSCOUNT: /* (re)set error counts */
1389 counts = (struct meteor_counts *) arg;
1390 bktr->fifo_errors = counts->fifo_errors;
1391 bktr->dma_errors = counts->dma_errors;
1392 bktr->frames_captured = counts->frames_captured;
1393 bktr->even_fields_captured = counts->even_fields_captured;
1394 bktr->odd_fields_captured = counts->odd_fields_captured;
1395 break;
1396
1397 case METEORGCOUNT: /* get error counts */
1398 counts = (struct meteor_counts *) arg;
1399 counts->fifo_errors = bktr->fifo_errors;
1400 counts->dma_errors = bktr->dma_errors;
1401 counts->frames_captured = bktr->frames_captured;
1402 counts->even_fields_captured = bktr->even_fields_captured;
1403 counts->odd_fields_captured = bktr->odd_fields_captured;
1404 break;
1405
1406 case METEORGVIDEO:
1407 video = (struct meteor_video *)arg;
1408 video->addr = bktr->video.addr;
1409 video->width = bktr->video.width;
1410 video->banksize = bktr->video.banksize;
1411 video->ramsize = bktr->video.ramsize;
1412 break;
1413
1414 case METEORSVIDEO:
1415 video = (struct meteor_video *)arg;
1416 bktr->video.addr = video->addr;
1417 bktr->video.width = video->width;
1418 bktr->video.banksize = video->banksize;
1419 bktr->video.ramsize = video->ramsize;
1420 break;
1421
1422 case METEORSFPS:
1423 set_fps(bktr, *(u_short *)arg);
1424 break;
1425
1426 case METEORGFPS:
1427 *(u_short *)arg = bktr->fps;
1428 break;
1429
1430 case METEORSHUE: /* set hue */
1431 OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1432 break;
1433
1434 case METEORGHUE: /* get hue */
1435 *(u_char *)arg = INB(bktr, BKTR_HUE);
1436 break;
1437
1438 case METEORSBRIG: /* set brightness */
1439 char_temp = ( *(u_char *)arg & 0xff) - 128;
1440 OUTB(bktr, BKTR_BRIGHT, char_temp);
1441
1442 break;
1443
1444 case METEORGBRIG: /* get brightness */
1445 *(u_char *)arg = INB(bktr, BKTR_BRIGHT);
1446 break;
1447
1448 case METEORSCSAT: /* set chroma saturation */
1449 temp = (int)*(u_char *)arg;
1450
1451 OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1452 OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1453 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1454 & ~(BT848_E_CONTROL_SAT_U_MSB
1455 | BT848_E_CONTROL_SAT_V_MSB));
1456 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1457 & ~(BT848_O_CONTROL_SAT_U_MSB |
1458 BT848_O_CONTROL_SAT_V_MSB));
1459
1460 if ( temp & BIT_SEVEN_HIGH ) {
1461 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1462 | (BT848_E_CONTROL_SAT_U_MSB
1463 | BT848_E_CONTROL_SAT_V_MSB));
1464 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1465 | (BT848_O_CONTROL_SAT_U_MSB
1466 | BT848_O_CONTROL_SAT_V_MSB));
1467 }
1468 break;
1469
1470 case METEORGCSAT: /* get chroma saturation */
1471 temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1472 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1473 temp |= BIT_SEVEN_HIGH;
1474 *(u_char *)arg = (u_char)temp;
1475 break;
1476
1477 case METEORSCONT: /* set contrast */
1478 temp = (int)*(u_char *)arg & 0xff;
1479 temp <<= 1;
1480 OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1481 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1482 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1483 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1484 (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1485 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1486 (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1487 break;
1488
1489 case METEORGCONT: /* get contrast */
1490 temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1491 temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1492 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1493 break;
1494
1495 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1496 bktr->clr_on_start = (*(int *)arg != 0);
1497 break;
1498
1499 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1500 *(int *)arg = (int) bktr->clr_on_start;
1501 break;
1502
1503 case METEORSSIGNAL:
a7d4e7e7 1504 sig = *(int *)arg;
a35cc233 1505 /* Historically, applications used METEOR_SIG_MODE_MASK
a7d4e7e7
MD
1506 * to reset signal delivery.
1507 */
1508 if (sig == METEOR_SIG_MODE_MASK)
1509 sig = 0;
1510 if (sig < 0 || sig > _SIG_MAXSIG)
a35cc233 1511 return (EINVAL);
a7d4e7e7 1512 bktr->signal = sig;
a35cc233 1513 bktr->proc = sig ? td->td_proc : NULL;
984263bc
MD
1514 break;
1515
1516 case METEORGSIGNAL:
1517 *(int *)arg = bktr->signal;
1518 break;
1519
1520 case METEORCAPTUR:
1521 temp = bktr->flags;
1522 switch (*(int *) arg) {
1523 case METEOR_CAP_SINGLE:
1524
1525 if (bktr->bigbuf==0) /* no frame buffer allocated */
1526 return( ENOMEM );
1527 /* already capturing */
1528 if (temp & METEOR_CAP_MASK)
1529 return( EIO );
1530
1531
1532
1533 start_capture(bktr, METEOR_SINGLE);
1534
1535 /* wait for capture to complete */
1536 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1537 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1538 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1539
1540 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1541 BT848_INT_RISCI |
1542 BT848_INT_VSYNC |
1543 BT848_INT_FMTCHG);
1544
1545 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
a35cc233 1546 error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
984263bc
MD
1547 if (error && (error != ERESTART)) {
1548 /* Here if we didn't get complete frame */
1549#ifdef DIAGNOSTIC
1550 printf( "%s: ioctl: tsleep error %d %x\n",
1551 bktr_name(bktr), error,
1552 INL(bktr, BKTR_RISC_COUNT));
1553#endif
1554
1555 /* stop dma */
1556 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1557
1558 /* disable risc, leave fifo running */
1559 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1560 }
1561
1562 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
1563 /* FIXME: should we set bt848->int_stat ??? */
1564 break;
1565
1566 case METEOR_CAP_CONTINOUS:
1567 if (bktr->bigbuf==0) /* no frame buffer allocated */
1568 return( ENOMEM );
1569 /* already capturing */
1570 if (temp & METEOR_CAP_MASK)
1571 return( EIO );
1572
1573
1574 start_capture(bktr, METEOR_CONTIN);
1575
1576 /* Clear the interrypt status register */
1577 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1578
1579 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1580 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1581 OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1582
1583 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1584 BT848_INT_RISCI |
1585 BT848_INT_VSYNC |
1586 BT848_INT_FMTCHG);
1587#ifdef BT848_DUMP
1588 dump_bt848( bt848 );
1589#endif
1590 break;
1591
1592 case METEOR_CAP_STOP_CONT:
1593 if (bktr->flags & METEOR_CONTIN) {
1594 /* turn off capture */
1595 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1596 OUTB(bktr, BKTR_CAP_CTL, CAPTURE_OFF);
1597 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1598 bktr->flags &=
1599 ~(METEOR_CONTIN | METEOR_WANT_MASK);
1600
1601 }
1602 }
1603 break;
1604
1605 case METEORSETGEO:
1606 /* can't change parameters while capturing */
1607 if (bktr->flags & METEOR_CAP_MASK)
1608 return( EBUSY );
1609
1610
1611 geo = (struct meteor_geomet *) arg;
1612
1613 error = 0;
1614 /* Either even or odd, if even & odd, then these a zero */
1615 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
1616 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
1617 printf( "%s: ioctl: Geometry odd or even only.\n",
1618 bktr_name(bktr));
1619 return( EINVAL );
1620 }
1621
1622 /* set/clear even/odd flags */
1623 if (geo->oformat & METEOR_GEO_ODD_ONLY)
1624 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
1625 else
1626 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
1627 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
1628 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
1629 else
1630 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
1631
1632 if (geo->columns <= 0) {
1633 printf(
1634 "%s: ioctl: %d: columns must be greater than zero.\n",
1635 bktr_name(bktr), geo->columns);
1636 error = EINVAL;
1637 }
1638 else if ((geo->columns & 0x3fe) != geo->columns) {
1639 printf(
1640 "%s: ioctl: %d: columns too large or not even.\n",
1641 bktr_name(bktr), geo->columns);
1642 error = EINVAL;
1643 }
1644
1645 if (geo->rows <= 0) {
1646 printf(
1647 "%s: ioctl: %d: rows must be greater than zero.\n",
1648 bktr_name(bktr), geo->rows);
1649 error = EINVAL;
1650 }
1651 else if (((geo->rows & 0x7fe) != geo->rows) ||
1652 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
1653 ((geo->rows & 0x3fe) != geo->rows)) ) {
1654 printf(
1655 "%s: ioctl: %d: rows too large or not even.\n",
1656 bktr_name(bktr), geo->rows);
1657 error = EINVAL;
1658 }
1659
1660 if (geo->frames > 32) {
1661 printf("%s: ioctl: too many frames.\n",
1662 bktr_name(bktr));
1663
1664 error = EINVAL;
1665 }
1666
1667 if (error)
1668 return( error );
1669
1670 bktr->dma_prog_loaded = FALSE;
1671 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
1672
1673 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
1674
1675 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
1676 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
1677
1678 /* meteor_mem structure for SYNC Capture */
1679 if (geo->frames > 1) temp += PAGE_SIZE;
1680
1681 temp = btoc(temp);
1682 if ((int) temp > bktr->alloc_pages
1683 && bktr->video.addr == 0) {
1684
984263bc
MD
1685 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1686 if (buf != 0) {
1687 kmem_free(kernel_map, bktr->bigbuf,
1688 (bktr->alloc_pages * PAGE_SIZE));
984263bc
MD
1689
1690 bktr->bigbuf = buf;
1691 bktr->alloc_pages = temp;
1692 if (bootverbose)
1693 printf(
1694 "%s: ioctl: Allocating %d bytes\n",
1695 bktr_name(bktr), temp*PAGE_SIZE);
1696 }
1697 else
1698 error = ENOMEM;
1699 }
1700 }
1701
1702 if (error)
1703 return error;
1704
1705 bktr->rows = geo->rows;
1706 bktr->cols = geo->columns;
1707 bktr->frames = geo->frames;
1708
1709 /* Pixel format (if in meteor pixfmt compatibility mode) */
1710 if ( bktr->pixfmt_compat ) {
1711 bktr->format = METEOR_GEO_YUV_422;
1712 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
1713 case 0: /* default */
1714 case METEOR_GEO_RGB16:
1715 bktr->format = METEOR_GEO_RGB16;
1716 break;
1717 case METEOR_GEO_RGB24:
1718 bktr->format = METEOR_GEO_RGB24;
1719 break;
1720 case METEOR_GEO_YUV_422:
1721 bktr->format = METEOR_GEO_YUV_422;
1722 if (geo->oformat & METEOR_GEO_YUV_12)
1723 bktr->format = METEOR_GEO_YUV_12;
1724 break;
1725 case METEOR_GEO_YUV_PACKED:
1726 bktr->format = METEOR_GEO_YUV_PACKED;
1727 break;
1728 }
1729 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1730 }
1731
1732 if (bktr->flags & METEOR_CAP_MASK) {
1733
1734 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
1735 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1736 case METEOR_ONLY_ODD_FIELDS:
1737 bktr->flags |= METEOR_WANT_ODD;
1738 break;
1739 case METEOR_ONLY_EVEN_FIELDS:
1740 bktr->flags |= METEOR_WANT_EVEN;
1741 break;
1742 default:
1743 bktr->flags |= METEOR_WANT_MASK;
1744 break;
1745 }
1746
1747 start_capture(bktr, METEOR_CONTIN);
1748 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
1749 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1750 OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1751 OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1752 BT848_INT_VSYNC |
1753 BT848_INT_FMTCHG);
1754 }
1755 }
1756 break;
1757 /* end of METEORSETGEO */
1758
1759 /* FIXME. The Capture Area currently has the following restrictions:
1760 GENERAL
1761 y_offset may need to be even in interlaced modes
1762 RGB24 - Interlaced mode
1763 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1764 y_size must be greater than or equal to METEORSETGEO height (rows)
1765 RGB24 - Even Only (or Odd Only) mode
1766 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
1767 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1768 YUV12 - Interlaced mode
1769 x_size must be greater than or equal to METEORSETGEO width (cols)
1770 y_size must be greater than or equal to METEORSETGEO height (rows)
1771 YUV12 - Even Only (or Odd Only) mode
1772 x_size must be greater than or equal to METEORSETGEO width (cols)
1773 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
1774 */
1775
1776 case BT848_SCAPAREA: /* set capture area of each video frame */
1777 /* can't change parameters while capturing */
1778 if (bktr->flags & METEOR_CAP_MASK)
1779 return( EBUSY );
1780
1781 cap_area = (struct bktr_capture_area *) arg;
1782 bktr->capture_area_x_offset = cap_area->x_offset;
1783 bktr->capture_area_y_offset = cap_area->y_offset;
1784 bktr->capture_area_x_size = cap_area->x_size;
1785 bktr->capture_area_y_size = cap_area->y_size;
1786 bktr->capture_area_enabled = TRUE;
1787
1788 bktr->dma_prog_loaded = FALSE;
1789 break;
1790
1791 case BT848_GCAPAREA: /* get capture area of each video frame */
1792 cap_area = (struct bktr_capture_area *) arg;
1793 if (bktr->capture_area_enabled == FALSE) {
1794 cap_area->x_offset = 0;
1795 cap_area->y_offset = 0;
1796 cap_area->x_size = format_params[
1797 bktr->format_params].scaled_hactive;
1798 cap_area->y_size = format_params[
1799 bktr->format_params].vactive;
1800 } else {
1801 cap_area->x_offset = bktr->capture_area_x_offset;
1802 cap_area->y_offset = bktr->capture_area_y_offset;
1803 cap_area->x_size = bktr->capture_area_x_size;
1804 cap_area->y_size = bktr->capture_area_y_size;
1805 }
1806 break;
1807
1808 default:
1809 return common_ioctl( bktr, cmd, arg );
1810 }
1811
1812 return( 0 );
1813}
1814
1815/*
1816 * tuner ioctls
1817 */
1818int
a35cc233 1819tuner_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct thread* td )
984263bc
MD
1820{
1821 int tmp_int;
1822 unsigned int temp, temp1;
1823 int offset;
1824 int count;
1825 u_char *buf;
1826 u_long par;
1827 u_char write;
1828 int i2c_addr;
1829 int i2c_port;
1830 u_long data;
1831
1832 switch ( cmd ) {
1833
1834 case REMOTE_GETKEY:
1835 /* Read the last key pressed by the Remote Control */
1836 if (bktr->remote_control == 0) return (EINVAL);
1837 remote_read(bktr, (struct bktr_remote *)arg);
1838 break;
1839
1840#if defined( TUNER_AFC )
1841 case TVTUNER_SETAFC:
1842 bktr->tuner.afc = (*(int *)arg != 0);
1843 break;
1844
1845 case TVTUNER_GETAFC:
1846 *(int *)arg = bktr->tuner.afc;
1847 /* XXX Perhaps use another bit to indicate AFC success? */
1848 break;
1849#endif /* TUNER_AFC */
1850
1851 case TVTUNER_SETCHNL:
1852 temp_mute( bktr, TRUE );
1853 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
1854 if ( temp < 0 ) {
1855 temp_mute( bktr, FALSE );
1856 return( EINVAL );
1857 }
1858 *(unsigned long *)arg = temp;
1859
1860 /* after every channel change, we must restart the MSP34xx */
1861 /* audio chip to reselect NICAM STEREO or MONO audio */
1862 if ( bktr->card.msp3400c )
1863 msp_autodetect( bktr );
1864
1865 /* after every channel change, we must restart the DPL35xx */
1866 if ( bktr->card.dpl3518a )
1867 dpl_autodetect( bktr );
1868
1869 temp_mute( bktr, FALSE );
1870 break;
1871
1872 case TVTUNER_GETCHNL:
1873 *(unsigned long *)arg = bktr->tuner.channel;
1874 break;
1875
1876 case TVTUNER_SETTYPE:
1877 temp = *(unsigned long *)arg;
1878 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
1879 return( EINVAL );
1880 bktr->tuner.chnlset = temp;
1881 break;
1882
1883 case TVTUNER_GETTYPE:
1884 *(unsigned long *)arg = bktr->tuner.chnlset;
1885 break;
1886
1887 case TVTUNER_GETSTATUS:
1888 temp = get_tuner_status( bktr );
1889 *(unsigned long *)arg = temp & 0xff;
1890 break;
1891
1892 case TVTUNER_SETFREQ:
1893 temp_mute( bktr, TRUE );
1894 temp = tv_freq( bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1895 temp_mute( bktr, FALSE );
1896 if ( temp < 0 ) {
1897 temp_mute( bktr, FALSE );
1898 return( EINVAL );
1899 }
1900 *(unsigned long *)arg = temp;
1901
1902 /* after every channel change, we must restart the MSP34xx */
1903 /* audio chip to reselect NICAM STEREO or MONO audio */
1904 if ( bktr->card.msp3400c )
1905 msp_autodetect( bktr );
1906
1907 /* after every channel change, we must restart the DPL35xx */
1908 if ( bktr->card.dpl3518a )
1909 dpl_autodetect( bktr );
1910
1911 temp_mute( bktr, FALSE );
1912 break;
1913
1914 case TVTUNER_GETFREQ:
1915 *(unsigned long *)arg = bktr->tuner.frequency;
1916 break;
1917
1918 case TVTUNER_GETCHNLSET:
1919 return tuner_getchnlset((struct bktr_chnlset *)arg);
1920
1921 case BT848_SAUDIO: /* set audio channel */
1922 if ( set_audio( bktr, *(int*)arg ) < 0 )
1923 return( EIO );
1924 break;
1925
1926 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
1927 case BT848_SHUE: /* set hue */
1928 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
1929 break;
1930
1931 case BT848_GHUE: /* get hue */
1932 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
1933 break;
1934
1935 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
1936 case BT848_SBRIG: /* set brightness */
1937 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
1938 break;
1939
1940 case BT848_GBRIG: /* get brightness */
1941 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
1942 break;
1943
1944 /* */
1945 case BT848_SCSAT: /* set chroma saturation */
1946 tmp_int = *(int*)arg;
1947
1948 temp = INB(bktr, BKTR_E_CONTROL);
1949 temp1 = INB(bktr, BKTR_O_CONTROL);
1950 if ( tmp_int & BIT_EIGHT_HIGH ) {
1951 temp |= (BT848_E_CONTROL_SAT_U_MSB |
1952 BT848_E_CONTROL_SAT_V_MSB);
1953 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
1954 BT848_O_CONTROL_SAT_V_MSB);
1955 }
1956 else {
1957 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
1958 BT848_E_CONTROL_SAT_V_MSB);
1959 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
1960 BT848_O_CONTROL_SAT_V_MSB);
1961 }
1962
1963 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
1964 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1965 OUTB(bktr, BKTR_E_CONTROL, temp);
1966 OUTB(bktr, BKTR_O_CONTROL, temp1);
1967 break;
1968
1969 case BT848_GCSAT: /* get chroma saturation */
1970 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
1971 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1972 tmp_int |= BIT_EIGHT_HIGH;
1973 *(int*)arg = tmp_int;
1974 break;
1975
1976 /* */
1977 case BT848_SVSAT: /* set chroma V saturation */
1978 tmp_int = *(int*)arg;
1979
1980 temp = INB(bktr, BKTR_E_CONTROL);
1981 temp1 = INB(bktr, BKTR_O_CONTROL);
1982 if ( tmp_int & BIT_EIGHT_HIGH) {
1983 temp |= BT848_E_CONTROL_SAT_V_MSB;
1984 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
1985 }
1986 else {
1987 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
1988 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
1989 }
1990
1991 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
1992 OUTB(bktr, BKTR_E_CONTROL, temp);
1993 OUTB(bktr, BKTR_O_CONTROL, temp1);
1994 break;
1995
1996 case BT848_GVSAT: /* get chroma V saturation */
1997 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
1998 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1999 tmp_int |= BIT_EIGHT_HIGH;
2000 *(int*)arg = tmp_int;
2001 break;
2002
2003 /* */
2004 case BT848_SUSAT: /* set chroma U saturation */
2005 tmp_int = *(int*)arg;
2006
2007 temp = INB(bktr, BKTR_E_CONTROL);
2008 temp1 = INB(bktr, BKTR_O_CONTROL);
2009 if ( tmp_int & BIT_EIGHT_HIGH ) {
2010 temp |= BT848_E_CONTROL_SAT_U_MSB;
2011 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2012 }
2013 else {
2014 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2015 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2016 }
2017
2018 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2019 OUTB(bktr, BKTR_E_CONTROL, temp);
2020 OUTB(bktr, BKTR_O_CONTROL, temp1);
2021 break;
2022
2023 case BT848_GUSAT: /* get chroma U saturation */
2024 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2025 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB )
2026 tmp_int |= BIT_EIGHT_HIGH;
2027 *(int*)arg = tmp_int;
2028 break;
2029
2030/* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2031
2032 case BT848_SLNOTCH: /* set luma notch */
2033 tmp_int = (*(int *)arg & 0x7) << 5 ;
2034 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2035 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2036 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2037 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2038 break;
2039
2040 case BT848_GLNOTCH: /* get luma notch */
2041 *(int *)arg = (int) ( (INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5) ;
2042 break;
2043
2044
2045 /* */
2046 case BT848_SCONT: /* set contrast */
2047 tmp_int = *(int*)arg;
2048
2049 temp = INB(bktr, BKTR_E_CONTROL);
2050 temp1 = INB(bktr, BKTR_O_CONTROL);
2051 if ( tmp_int & BIT_EIGHT_HIGH ) {
2052 temp |= BT848_E_CONTROL_CON_MSB;
2053 temp1 |= BT848_O_CONTROL_CON_MSB;
2054 }
2055 else {
2056 temp &= ~BT848_E_CONTROL_CON_MSB;
2057 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2058 }
2059
2060 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2061 OUTB(bktr, BKTR_E_CONTROL, temp);
2062 OUTB(bktr, BKTR_O_CONTROL, temp1);
2063 break;
2064
2065 case BT848_GCONT: /* get contrast */
2066 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2067 if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB )
2068 tmp_int |= BIT_EIGHT_HIGH;
2069 *(int*)arg = tmp_int;
2070 break;
2071
2072 /* FIXME: SCBARS and CCBARS require a valid int * */
2073 /* argument to succeed, but its not used; consider */
2074 /* using the arg to store the on/off state so */
2075 /* there's only one ioctl() needed to turn cbars on/off */
2076 case BT848_SCBARS: /* set colorbar output */
2077 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2078 break;
2079
2080 case BT848_CCBARS: /* clear colorbar output */
2081 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2082 break;
2083
2084 case BT848_GAUDIO: /* get audio channel */
2085 temp = bktr->audio_mux_select;
2086 if ( bktr->audio_mute_state == TRUE )
2087 temp |= AUDIO_MUTE;
2088 *(int*)arg = temp;
2089 break;
2090
2091 case BT848_SBTSC: /* set audio channel */
2092 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2093 return( EIO );
2094 break;
2095
2096 case BT848_WEEPROM: /* write eeprom */
2097 offset = (((struct eeProm *)arg)->offset);
2098 count = (((struct eeProm *)arg)->count);
2099 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2100 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2101 return( EIO );
2102 break;
2103
2104 case BT848_REEPROM: /* read eeprom */
2105 offset = (((struct eeProm *)arg)->offset);
2106 count = (((struct eeProm *)arg)->count);
2107 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2108 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2109 return( EIO );
2110 break;
2111
2112 case BT848_SIGNATURE:
2113 offset = (((struct eeProm *)arg)->offset);
2114 count = (((struct eeProm *)arg)->count);
2115 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2116 if ( signCard( bktr, offset, count, buf ) < 0 )
2117 return( EIO );
2118 break;
2119
2120 /* Ioctl's for direct gpio access */
2121#ifdef BKTR_GPIO_ACCESS
2122 case BT848_GPIO_GET_EN:
2123 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2124 break;
2125
2126 case BT848_GPIO_SET_EN:
2127 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2128 break;
2129
2130 case BT848_GPIO_GET_DATA:
2131 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2132 break;
2133
2134 case BT848_GPIO_SET_DATA:
2135 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2136 break;
2137#endif /* BKTR_GPIO_ACCESS */
2138
2139 /* Ioctl's for running the tuner device in radio mode */
2140
2141 case RADIO_GETMODE:
2142 *(unsigned char *)arg = bktr->tuner.radio_mode;
2143 break;
2144
2145 case RADIO_SETMODE:
2146 bktr->tuner.radio_mode = *(unsigned char *)arg;
2147 break;
2148
2149 case RADIO_GETFREQ:
2150 *(unsigned long *)arg = bktr->tuner.frequency;
2151 break;
2152
2153 case RADIO_SETFREQ:
2154 /* The argument to this ioctl is NOT freq*16. It is
2155 ** freq*100.
2156 */
2157
2158 temp=(int)*(unsigned long *)arg;
2159
2160#ifdef BKTR_RADIO_DEBUG
2161 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2162 (int)*(unsigned long *)arg, temp);
2163#endif
2164
2165#ifndef BKTR_RADIO_NOFREQCHECK
2166 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2167 /* is supported. */
2168 if(temp<8750 || temp>10800) {
2169 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2170 return(EINVAL);
2171 }
2172#endif
2173 temp_mute( bktr, TRUE );
2174 temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2175 temp_mute( bktr, FALSE );
2176#ifdef BKTR_RADIO_DEBUG
2177 if(temp)
2178 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2179#endif
2180 if ( temp < 0 )
2181 return( EINVAL );
2182 *(unsigned long *)arg = temp;
2183 break;
2184
2185 /* Luigi's I2CWR ioctl */
2186 case BT848_I2CWR:
2187 par = *(u_long *)arg;
2188 write = (par >> 24) & 0xff ;
2189 i2c_addr = (par >> 16) & 0xff ;
2190 i2c_port = (par >> 8) & 0xff ;
2191 data = (par) & 0xff ;
2192
2193 if (write) {
2194 i2cWrite( bktr, i2c_addr, i2c_port, data);
2195 } else {
2196 data = i2cRead( bktr, i2c_addr);
2197 }
2198 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2199 break;
2200
2201
2202#ifdef BT848_MSP_READ
2203 /* I2C ioctls to allow userland access to the MSP chip */
2204 case BT848_MSP_READ:
2205 {
2206 struct bktr_msp_control *msp;
2207 msp = (struct bktr_msp_control *) arg;
2208 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2209 msp->function, msp->address);
2210 break;
2211 }
2212
2213 case BT848_MSP_WRITE:
2214 {
2215 struct bktr_msp_control *msp;
2216 msp = (struct bktr_msp_control *) arg;
2217 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2218 msp->address, msp->data );
2219 break;
2220 }
2221
2222 case BT848_MSP_RESET:
2223 msp_dpl_reset(bktr, bktr->msp_addr);
2224 break;
2225#endif
2226
2227 default:
2228 return common_ioctl( bktr, cmd, arg );
2229 }
2230
2231 return( 0 );
2232}
2233
2234
2235/*
2236 * common ioctls
2237 */
a7d4e7e7 2238static int
984263bc
MD
2239common_ioctl( bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg )
2240{
2241 int pixfmt;
2242 unsigned int temp;
2243 struct meteor_pixfmt *pf_pub;
2244
2245 switch (cmd) {
2246
2247 case METEORSINPUT: /* set input device */
2248 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2249 /* On the original bt848 boards, */
2250 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2251 /* On the Hauppauge bt878 boards, */
2252 /* Tuner is MUX0, RCA is MUX3 */
2253 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2254 /* stick with this system in our Meteor Emulation */
2255
2256 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2257
2258 /* this is the RCA video input */
2259 case 0: /* default */
2260 case METEOR_INPUT_DEV0:
2261 /* METEOR_INPUT_DEV_RCA: */
2262 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2263 | METEOR_DEV0;
2264 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2265 & ~BT848_IFORM_MUXSEL);
2266
2267 /* work around for new Hauppauge 878 cards */
2268 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2269 (bktr->id==BROOKTREE_878 ||
2270 bktr->id==BROOKTREE_879) )
2271 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2272 else
2273 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2274
2275 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2276 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2277 set_audio( bktr, AUDIO_EXTERN );
2278 break;
2279
2280 /* this is the tuner input */
2281 case METEOR_INPUT_DEV1:
2282 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2283 | METEOR_DEV1;
2284 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2285 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2286 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2287 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2288 set_audio( bktr, AUDIO_TUNER );
2289 break;
2290
2291 /* this is the S-VHS input, but with a composite camera */
2292 case METEOR_INPUT_DEV2:
2293 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2294 | METEOR_DEV2;
2295 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2296 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2297 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2298 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2299 set_audio( bktr, AUDIO_EXTERN );
2300 break;
2301
2302 /* this is the S-VHS input */
2303 case METEOR_INPUT_DEV_SVIDEO:
2304 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2305 | METEOR_DEV_SVIDEO;
2306 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2307 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2308 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2309 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2310 set_audio( bktr, AUDIO_EXTERN );
2311 break;
2312
2313 case METEOR_INPUT_DEV3:
2314 if ((bktr->id == BROOKTREE_848A) ||
2315 (bktr->id == BROOKTREE_849A) ||
2316 (bktr->id == BROOKTREE_878) ||
2317 (bktr->id == BROOKTREE_879) ) {
2318 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2319 | METEOR_DEV3;
2320 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2321
2322 /* work around for new Hauppauge 878 cards */
2323 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2324 (bktr->id==BROOKTREE_878 ||
2325 bktr->id==BROOKTREE_879) )
2326 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2327 else
2328 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2329
2330 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2331 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2332 set_audio( bktr, AUDIO_EXTERN );
2333
2334 break;
2335 }
2336
2337 default:
2338 return( EINVAL );
2339 }
2340 break;
2341
2342 case METEORGINPUT: /* get input device */
2343 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2344 break;
2345
2346 case METEORSACTPIXFMT:
2347 if (( *(int *)arg < 0 ) ||
2348 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2349 return( EINVAL );
2350
2351 bktr->pixfmt = *(int *)arg;
2352 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2353 | pixfmt_swap_flags( bktr->pixfmt ));
2354 bktr->pixfmt_compat = FALSE;
2355 break;
2356
2357 case METEORGACTPIXFMT:
2358 *(int *)arg = bktr->pixfmt;
2359 break;
2360
2361 case METEORGSUPPIXFMT :
2362 pf_pub = (struct meteor_pixfmt *)arg;
2363 pixfmt = pf_pub->index;
2364
2365 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2366 return( EINVAL );
2367
2368 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2369 sizeof( *pf_pub ) );
2370
2371 /* Patch in our format index */
2372 pf_pub->index = pixfmt;
2373 break;
2374
2375#if defined( STATUS_SUM )
2376 case BT848_GSTATUS: /* reap status */
2377 {
2378 DECLARE_INTR_MASK(s);
2379 DISABLE_INTR(s);
2380 temp = status_sum;
2381 status_sum = 0;
2382 ENABLE_INTR(s);
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 */
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);
3746 }
3747
3748 /* return OK */
3749 return( 0 );
3750}
3751
3752int
3753i2cRead( bktr_ptr_t bktr, int addr )
3754{
3755 char result;
3756 char cmd;