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