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