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