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