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