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