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