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