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