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