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