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