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