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