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