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