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