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