bktr_core.c revision 1.17.2.8 1 /* $NetBSD: bktr_core.c,v 1.17.2.8 2003/01/15 18:44:22 thorpej 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.17.2.8 2003/01/15 18:44:22 thorpej 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)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2660 flag &= ~OP_SOL;
2661 skip = start_skip;
2662 }
2663
2664 *(*dma_prog)++ = htole32(operation | flag |
2665 (width * pixel_width - skip));
2666 if (operation != OP_SKIP )
2667 *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
2668
2669 *target_buffer += width * pixel_width;
2670 bktr->current_col += width;
2671
2672 } else {
2673
2674 if (bktr->current_col == 0 && width == cols) {
2675 flag = OP_SOL;
2676 flag2 = OP_EOL;
2677 } else if (bktr->current_col == 0 ) {
2678 flag = OP_SOL;
2679 flag2 = 0;
2680 } else if (bktr->current_col >= cols) {
2681 flag = 0;
2682 flag2 = OP_EOL;
2683 } else {
2684 flag = 0;
2685 flag2 = 0;
2686 }
2687
2688 skip = 0;
2689 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
2690 *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2691 flag &= ~OP_SOL;
2692 skip = start_skip;
2693 }
2694
2695 *(*dma_prog)++ = htole32(operation | flag |
2696 (width * pixel_width / 2 - skip));
2697 if (operation != OP_SKIP )
2698 *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
2699 *target_buffer += (width * pixel_width / 2);
2700
2701 if ( operation == OP_WRITE )
2702 operation = OP_WRITEC;
2703 *(*dma_prog)++ = htole32(operation | flag2 |
2704 (width * pixel_width / 2));
2705 *target_buffer += (width * pixel_width / 2);
2706 bktr->current_col += width;
2707
2708 }
2709 return TRUE;
2710 }
2711
2712
2713 /*
2714 * Generate the RISC instructions to capture both VBI and video images
2715 */
2716 static void
2717 rgb_vbi_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2718 {
2719 int i;
2720 volatile u_long target_buffer, buffer, target,width;
2721 volatile u_long pitch;
2722 volatile u_long *dma_prog; /* DMA prog is an array of
2723 32 bit RISC instructions */
2724 volatile u_long *loop_point;
2725 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2726 u_int Bpp = pf_int->public.Bpp;
2727 unsigned int vbisamples; /* VBI samples per line */
2728 unsigned int vbilines; /* VBI lines per field */
2729 unsigned int num_dwords; /* DWORDS per line */
2730
2731 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2732 vbilines = format_params[bktr->format_params].vbi_num_lines;
2733 num_dwords = vbisamples/4;
2734
2735 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2736 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2737 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2738 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2739 /* no ext frame */
2740
2741 OUTB(bktr, BKTR_OFORM, 0x00);
2742
2743 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2744 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2745 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2746 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2747
2748 /* disable gamma correction removal */
2749 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2750
2751 if (cols > 385 ) {
2752 OUTB(bktr, BKTR_E_VTC, 0);
2753 OUTB(bktr, BKTR_O_VTC, 0);
2754 } else {
2755 OUTB(bktr, BKTR_E_VTC, 1);
2756 OUTB(bktr, BKTR_O_VTC, 1);
2757 }
2758 bktr->capcontrol = 3 << 2 | 3;
2759
2760 dma_prog = (u_long *) bktr->dma_prog;
2761
2762 /* Construct Write */
2763
2764 if (bktr->video.addr) {
2765 target_buffer = (u_long) bktr->video.addr;
2766 pitch = bktr->video.width;
2767 }
2768 else {
2769 target_buffer = (u_long) vtophys(bktr->bigbuf);
2770 pitch = cols*Bpp;
2771 }
2772
2773 buffer = target_buffer;
2774
2775 /* Wait for the VRE sync marking the end of the Even and
2776 * the start of the Odd field. Resync here.
2777 */
2778 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_VRE);
2779 *dma_prog++ = htole32(0);
2780
2781 loop_point = dma_prog;
2782
2783 /* store the VBI data */
2784 /* look for sync with packed data */
2785 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2786 *dma_prog++ = htole32(0);
2787 for(i = 0; i < vbilines; i++) {
2788 *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2789 *dma_prog++ = htole32((u_long) vtophys(bktr->vbidata +
2790 (i * VBI_LINE_SIZE)));
2791 }
2792
2793 if ( (i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/ ) {
2794 /* store the Odd field video image */
2795 /* look for sync with packed data */
2796 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2797 *dma_prog++ = htole32(0); /* NULL WORD */
2798 width = cols;
2799 for (i = 0; i < (rows/interlace); i++) {
2800 target = target_buffer;
2801 if ( notclipped(bktr, i, width)) {
2802 split(bktr, (volatile u_long **) &dma_prog,
2803 bktr->y2 - bktr->y, OP_WRITE,
2804 Bpp, (volatile u_char **) &target, cols);
2805
2806 } else {
2807 while(getline(bktr, i)) {
2808 if (bktr->y != bktr->y2 ) {
2809 split(bktr, (volatile u_long **) &dma_prog,
2810 bktr->y2 - bktr->y, OP_WRITE,
2811 Bpp, (volatile u_char **) &target, cols);
2812 }
2813 if (bktr->yclip != bktr->yclip2 ) {
2814 split(bktr,(volatile u_long **) &dma_prog,
2815 bktr->yclip2 - bktr->yclip,
2816 OP_SKIP,
2817 Bpp, (volatile u_char **) &target, cols);
2818 }
2819 }
2820
2821 }
2822
2823 target_buffer += interlace * pitch;
2824
2825 }
2826
2827 } /* end if */
2828
2829 /* Grab the Even field */
2830 /* Look for the VRO, end of Odd field, marker */
2831 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2832 *dma_prog++ = htole32(0); /* NULL WORD */
2833
2834 /* store the VBI data */
2835 /* look for sync with packed data */
2836 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2837 *dma_prog++ = htole32(0);
2838 for(i = 0; i < vbilines; i++) {
2839 *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2840 *dma_prog++ = htole32((u_long) vtophys(bktr->vbidata +
2841 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE)));
2842 }
2843
2844 /* store the video image */
2845 if (i_flag == 1) /*Even Only*/
2846 target_buffer = buffer;
2847 if (i_flag == 3) /*interlaced*/
2848 target_buffer = buffer+pitch;
2849
2850
2851 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2852 /* look for sync with packed data */
2853 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2854 *dma_prog++ = htole32(0); /* NULL WORD */
2855 width = cols;
2856 for (i = 0; i < (rows/interlace); i++) {
2857 target = target_buffer;
2858 if ( notclipped(bktr, i, width)) {
2859 split(bktr, (volatile u_long **) &dma_prog,
2860 bktr->y2 - bktr->y, OP_WRITE,
2861 Bpp, (volatile u_char **) &target, cols);
2862 } else {
2863 while(getline(bktr, i)) {
2864 if (bktr->y != bktr->y2 ) {
2865 split(bktr, (volatile u_long **) &dma_prog,
2866 bktr->y2 - bktr->y, OP_WRITE,
2867 Bpp, (volatile u_char **) &target,
2868 cols);
2869 }
2870 if (bktr->yclip != bktr->yclip2 ) {
2871 split(bktr, (volatile u_long **) &dma_prog,
2872 bktr->yclip2 - bktr->yclip, OP_SKIP,
2873 Bpp, (volatile u_char **) &target, cols);
2874 }
2875
2876 }
2877
2878 }
2879
2880 target_buffer += interlace * pitch;
2881
2882 }
2883 }
2884
2885 /* Look for end of 'Even Field' */
2886 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2887 *dma_prog++ = htole32(0); /* NULL WORD */
2888
2889 *dma_prog++ = htole32(OP_JUMP);
2890 *dma_prog++ = htole32((u_long) vtophys((vaddr_t)loop_point));
2891 *dma_prog++ = htole32(0); /* NULL WORD */
2892
2893 }
2894
2895
2896
2897
2898 static void
2899 rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
2900 {
2901 int i;
2902 volatile u_long target_buffer, buffer, target,width;
2903 volatile u_long pitch;
2904 volatile u_long *dma_prog;
2905 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2906 u_int Bpp = pf_int->public.Bpp;
2907
2908 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2909 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2910 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2911 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2912
2913 OUTB(bktr, BKTR_OFORM, 0x00);
2914
2915 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2916 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2917 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2918 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2919
2920 /* disable gamma correction removal */
2921 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2922
2923 if (cols > 385 ) {
2924 OUTB(bktr, BKTR_E_VTC, 0);
2925 OUTB(bktr, BKTR_O_VTC, 0);
2926 } else {
2927 OUTB(bktr, BKTR_E_VTC, 1);
2928 OUTB(bktr, BKTR_O_VTC, 1);
2929 }
2930 bktr->capcontrol = 3 << 2 | 3;
2931
2932 dma_prog = (u_long *) bktr->dma_prog;
2933
2934 /* Construct Write */
2935
2936 if (bktr->video.addr) {
2937 target_buffer = (u_long) bktr->video.addr;
2938 pitch = bktr->video.width;
2939 }
2940 else {
2941 target_buffer = (u_long) vtophys(bktr->bigbuf);
2942 pitch = cols*Bpp;
2943 }
2944
2945 buffer = target_buffer;
2946
2947 /* contruct sync : for video packet format */
2948 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2949
2950 /* sync, mode indicator packed data */
2951 *dma_prog++ = htole32(0); /* NULL WORD */
2952 width = cols;
2953 for (i = 0; i < (rows/interlace); i++) {
2954 target = target_buffer;
2955 if ( notclipped(bktr, i, width)) {
2956 split(bktr, (volatile u_long **) &dma_prog,
2957 bktr->y2 - bktr->y, OP_WRITE,
2958 Bpp, (volatile u_char **) &target, cols);
2959
2960 } else {
2961 while(getline(bktr, i)) {
2962 if (bktr->y != bktr->y2 ) {
2963 split(bktr, (volatile u_long **) &dma_prog,
2964 bktr->y2 - bktr->y, OP_WRITE,
2965 Bpp, (volatile u_char **) &target, cols);
2966 }
2967 if (bktr->yclip != bktr->yclip2 ) {
2968 split(bktr,(volatile u_long **) &dma_prog,
2969 bktr->yclip2 - bktr->yclip,
2970 OP_SKIP,
2971 Bpp, (volatile u_char **) &target, cols);
2972 }
2973 }
2974
2975 }
2976
2977 target_buffer += interlace * pitch;
2978
2979 }
2980
2981 switch (i_flag) {
2982 case 1:
2983 /* sync vre */
2984 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
2985 *dma_prog++ = htole32(0); /* NULL WORD */
2986
2987 *dma_prog++ = htole32(OP_JUMP);
2988 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
2989 return;
2990
2991 case 2:
2992 /* sync vro */
2993 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
2994 *dma_prog++ = htole32(0); /* NULL WORD */
2995
2996 *dma_prog++ = htole32(OP_JUMP);
2997 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
2998 return;
2999
3000 case 3:
3001 /* sync vro */
3002 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3003 *dma_prog++ = htole32(0); /* NULL WORD */
3004 *dma_prog++ = htole32(OP_JUMP);
3005 *dma_prog++ = htole32((u_long) vtophys(bktr->odd_dma_prog));
3006 break;
3007 }
3008
3009 if (interlace == 2) {
3010
3011 target_buffer = buffer + pitch;
3012
3013 dma_prog = (u_long *) bktr->odd_dma_prog;
3014
3015 /* sync vre IRQ bit */
3016 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3017 *dma_prog++ = htole32(0); /* NULL WORD */
3018 width = cols;
3019 for (i = 0; i < (rows/interlace); i++) {
3020 target = target_buffer;
3021 if ( notclipped(bktr, i, width)) {
3022 split(bktr, (volatile u_long **) &dma_prog,
3023 bktr->y2 - bktr->y, OP_WRITE,
3024 Bpp, (volatile u_char **) &target, cols);
3025 } else {
3026 while(getline(bktr, i)) {
3027 if (bktr->y != bktr->y2 ) {
3028 split(bktr, (volatile u_long **) &dma_prog,
3029 bktr->y2 - bktr->y, OP_WRITE,
3030 Bpp, (volatile u_char **) &target,
3031 cols);
3032 }
3033 if (bktr->yclip != bktr->yclip2 ) {
3034 split(bktr, (volatile u_long **) &dma_prog,
3035 bktr->yclip2 - bktr->yclip, OP_SKIP,
3036 Bpp, (volatile u_char **) &target, cols);
3037 }
3038
3039 }
3040
3041 }
3042
3043 target_buffer += interlace * pitch;
3044
3045 }
3046 }
3047
3048 /* sync vre IRQ bit */
3049 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3050 *dma_prog++ = htole32(0); /* NULL WORD */
3051 *dma_prog++ = htole32(OP_JUMP);
3052 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3053 *dma_prog++ = htole32(0); /* NULL WORD */
3054 }
3055
3056
3057 /*
3058 *
3059 */
3060 static void
3061 yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3062 int cols, int rows, int interlace )
3063 {
3064 int i;
3065 volatile unsigned int inst;
3066 volatile unsigned int inst3;
3067 volatile u_long target_buffer, buffer;
3068 volatile u_long *dma_prog;
3069 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3070 int b;
3071
3072 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3073
3074 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3075 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3076
3077 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3078 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3079
3080 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3081 bktr->capcontrol = 3 << 2 | 3;
3082
3083 dma_prog = (u_long *) bktr->dma_prog;
3084
3085 /* Construct Write */
3086
3087 /* write , sol, eol */
3088 inst = OP_WRITE | OP_SOL | (cols);
3089 /* write , sol, eol */
3090 inst3 = OP_WRITE | OP_EOL | (cols);
3091
3092 if (bktr->video.addr)
3093 target_buffer = (u_long) bktr->video.addr;
3094 else
3095 target_buffer = (u_long) vtophys(bktr->bigbuf);
3096
3097 buffer = target_buffer;
3098
3099 /* contruct sync : for video packet format */
3100 /* sync, mode indicator packed data */
3101 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3102 *dma_prog++ = htole32(0); /* NULL WORD */
3103
3104 b = cols;
3105
3106 for (i = 0; i < (rows/interlace); i++) {
3107 *dma_prog++ = htole32(inst);
3108 *dma_prog++ = htole32(target_buffer);
3109 *dma_prog++ = htole32(inst3);
3110 *dma_prog++ = htole32(target_buffer + b);
3111 target_buffer += interlace*(cols * 2);
3112 }
3113
3114 switch (i_flag) {
3115 case 1:
3116 /* sync vre */
3117 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
3118 *dma_prog++ = htole32(0); /* NULL WORD */
3119
3120 *dma_prog++ = htole32(OP_JUMP);
3121 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3122 return;
3123
3124 case 2:
3125 /* sync vro */
3126 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
3127 *dma_prog++ = htole32(0); /* NULL WORD */
3128 *dma_prog++ = htole32(OP_JUMP);
3129 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3130 return;
3131
3132 case 3:
3133 /* sync vro */
3134 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3135 *dma_prog++ = htole32(0); /* NULL WORD */
3136 *dma_prog++ = htole32(OP_JUMP);
3137 *dma_prog++ = htole32((u_long) vtophys(bktr->odd_dma_prog));
3138 break;
3139 }
3140
3141 if (interlace == 2) {
3142
3143 target_buffer = (u_long) buffer + cols*2;
3144
3145 dma_prog = (u_long * ) bktr->odd_dma_prog;
3146
3147 /* sync vre */
3148 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3149 *dma_prog++ = htole32(0); /* NULL WORD */
3150
3151 for (i = 0; i < (rows/interlace); i++) {
3152 *dma_prog++ = htole32(inst);
3153 *dma_prog++ = htole32(target_buffer);
3154 *dma_prog++ = htole32(inst3);
3155 *dma_prog++ = htole32(target_buffer + b);
3156 target_buffer += interlace * ( cols*2);
3157 }
3158 }
3159
3160 /* sync vro IRQ bit */
3161 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3162 *dma_prog++ = htole32(0); /* NULL WORD */
3163 *dma_prog++ = htole32(OP_JUMP);
3164 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3165
3166 *dma_prog++ = htole32(OP_JUMP);
3167 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3168 *dma_prog++ = htole32(0); /* NULL WORD */
3169 }
3170
3171
3172 /*
3173 *
3174 */
3175 static void
3176 yuv422_prog( bktr_ptr_t bktr, char i_flag,
3177 int cols, int rows, int interlace ){
3178
3179 int i;
3180 volatile unsigned int inst;
3181 volatile u_long target_buffer, t1, buffer;
3182 volatile u_long *dma_prog;
3183 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3184
3185 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3186
3187 dma_prog = (u_long *) bktr->dma_prog;
3188
3189 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3190
3191 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3192 OUTB(bktr, BKTR_OFORM, 0x00);
3193
3194 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3195 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3196
3197 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3198 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3199
3200 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3201 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3202 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3203 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3204
3205 /* disable gamma correction removal */
3206 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3207
3208 /* Construct Write */
3209 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3210 if (bktr->video.addr)
3211 target_buffer = (u_long) bktr->video.addr;
3212 else
3213 target_buffer = (u_long) vtophys(bktr->bigbuf);
3214
3215 buffer = target_buffer;
3216
3217 t1 = buffer;
3218
3219 /* contruct sync : for video packet format */
3220 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
3221 *dma_prog++ = htole32(0); /* NULL WORD */
3222
3223 for (i = 0; i < (rows/interlace ); i++) {
3224 *dma_prog++ = htole32(inst);
3225 *dma_prog++ = htole32(cols/2 | cols/2 << 16);
3226 *dma_prog++ = htole32(target_buffer);
3227 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3228 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
3229 target_buffer += interlace*cols;
3230 }
3231
3232 switch (i_flag) {
3233 case 1:
3234 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/
3235 *dma_prog++ = htole32(0); /* NULL WORD */
3236
3237 *dma_prog++ = htole32(OP_JUMP);
3238 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3239 return;
3240
3241 case 2:
3242 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vre*/
3243 *dma_prog++ = htole32(0); /* NULL WORD */
3244
3245 *dma_prog++ = htole32(OP_JUMP);
3246 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3247 return;
3248
3249 case 3:
3250 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3251 *dma_prog++ = htole32(0); /* NULL WORD */
3252
3253 *dma_prog++ = htole32(OP_JUMP);
3254 *dma_prog++ = htole32((u_long) vtophys(bktr->odd_dma_prog));
3255 break;
3256 }
3257
3258 if (interlace == 2) {
3259
3260 dma_prog = (u_long * ) bktr->odd_dma_prog;
3261
3262 target_buffer = (u_long) buffer + cols;
3263 t1 = buffer + cols/2;
3264 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3265 *dma_prog++ = htole32(0); /* NULL WORD */
3266
3267 for (i = 0; i < (rows/interlace ); i++) {
3268 *dma_prog++ = htole32(inst);
3269 *dma_prog++ = htole32(cols/2 | cols/2 << 16);
3270 *dma_prog++ = htole32(target_buffer);
3271 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3272 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
3273 target_buffer += interlace*cols;
3274 }
3275 }
3276
3277 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3278 *dma_prog++ = htole32(0); /* NULL WORD */
3279 *dma_prog++ = htole32(OP_JUMP);
3280 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3281 *dma_prog++ = htole32(0); /* NULL WORD */
3282 }
3283
3284
3285 /*
3286 *
3287 */
3288 static void
3289 yuv12_prog( bktr_ptr_t bktr, char i_flag,
3290 int cols, int rows, int interlace ){
3291
3292 int i;
3293 volatile unsigned int inst;
3294 volatile unsigned int inst1;
3295 volatile u_long target_buffer, t1, buffer;
3296 volatile u_long *dma_prog;
3297 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3298
3299 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3300
3301 dma_prog = (u_long *) bktr->dma_prog;
3302
3303 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3304
3305 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3306 OUTB(bktr, BKTR_OFORM, 0x0);
3307
3308 /* Construct Write */
3309 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3310 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3311 if (bktr->video.addr)
3312 target_buffer = (u_long) bktr->video.addr;
3313 else
3314 target_buffer = (u_long) vtophys(bktr->bigbuf);
3315
3316 buffer = target_buffer;
3317 t1 = buffer;
3318
3319 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
3320 *dma_prog++ = htole32(0); /* NULL WORD */
3321
3322 for (i = 0; i < (rows/interlace )/2; i++) {
3323 *dma_prog++ = htole32(inst);
3324 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3325 *dma_prog++ = htole32(target_buffer);
3326 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3327 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
3328 target_buffer += interlace*cols;
3329 *dma_prog++ = htole32(inst1);
3330 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3331 *dma_prog++ = htole32(target_buffer);
3332 target_buffer += interlace*cols;
3333
3334 }
3335
3336 switch (i_flag) {
3337 case 1:
3338 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/
3339 *dma_prog++ = htole32(0); /* NULL WORD */
3340
3341 *dma_prog++ = htole32(OP_JUMP);
3342 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3343 return;
3344
3345 case 2:
3346 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vro*/
3347 *dma_prog++ = htole32(0); /* NULL WORD */
3348
3349 *dma_prog++ = htole32(OP_JUMP);
3350 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3351 return;
3352
3353 case 3:
3354 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3355 *dma_prog++ = htole32(0); /* NULL WORD */
3356 *dma_prog++ = htole32(OP_JUMP);
3357 *dma_prog++ = htole32((u_long) vtophys(bktr->odd_dma_prog));
3358 break;
3359 }
3360
3361 if (interlace == 2) {
3362
3363 dma_prog = (u_long * ) bktr->odd_dma_prog;
3364
3365 target_buffer = (u_long) buffer + cols;
3366 t1 = buffer + cols/2;
3367 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3368 *dma_prog++ = htole32(0); /* NULL WORD */
3369
3370 for (i = 0; i < ((rows/interlace )/2 ); i++) {
3371 *dma_prog++ = htole32(inst);
3372 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3373 *dma_prog++ = htole32(target_buffer);
3374 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3375 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
3376 target_buffer += interlace*cols;
3377 *dma_prog++ = htole32(inst1);
3378 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3379 *dma_prog++ = htole32(target_buffer);
3380 target_buffer += interlace*cols;
3381
3382 }
3383
3384
3385 }
3386
3387 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3388 *dma_prog++ = htole32(0); /* NULL WORD */
3389 *dma_prog++ = htole32(OP_JUMP);
3390 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3391 *dma_prog++ = htole32(0); /* NULL WORD */
3392 }
3393
3394
3395
3396 /*
3397 *
3398 */
3399 static void
3400 build_dma_prog( bktr_ptr_t bktr, char i_flag )
3401 {
3402 int rows, cols, interlace;
3403 int tmp_int;
3404 unsigned int temp;
3405 const struct format_params *fp;
3406 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3407
3408
3409 fp = &format_params[bktr->format_params];
3410
3411 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3412
3413 /* disable FIFO & RISC, leave other bits alone */
3414 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3415
3416 /* set video parameters */
3417 if (bktr->capture_area_enabled)
3418 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3419 / fp->scaled_htotal / bktr->cols) - 4096;
3420 else
3421 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3422 / fp->scaled_htotal / bktr->cols) - 4096;
3423
3424 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3425 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3426 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3427 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3428 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3429
3430 /* horizontal active */
3431 temp = bktr->cols;
3432 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3433 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3434 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3435 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3436 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3437 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3438 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3439
3440 /* horizontal delay */
3441 if (bktr->capture_area_enabled)
3442 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3443 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3444 else
3445 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3446
3447 temp = temp & 0x3fe;
3448
3449 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3450 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3451 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3452 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3453 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3454 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3455 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3456
3457 /* vertical scale */
3458
3459 if (bktr->capture_area_enabled) {
3460 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3461 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3462 tmp_int = 65536 -
3463 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3464 else {
3465 tmp_int = 65536 -
3466 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3467 }
3468 } else {
3469 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3470 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3471 tmp_int = 65536 -
3472 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3473 else {
3474 tmp_int = 65536 -
3475 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3476 }
3477 }
3478
3479 tmp_int &= 0x1fff;
3480 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3481 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3482 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3483 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3484 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3485 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3486 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3487
3488
3489 /* vertical active */
3490 if (bktr->capture_area_enabled)
3491 temp = bktr->capture_area_y_size;
3492 else
3493 temp = fp->vactive;
3494 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3495 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3496 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3497 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3498 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3499 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3500 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3501
3502 /* vertical delay */
3503 if (bktr->capture_area_enabled)
3504 temp = fp->vdelay + (bktr->capture_area_y_offset);
3505 else
3506 temp = fp->vdelay;
3507 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3508 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3509 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3510 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3511 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3512 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3513 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3514
3515 /* end of video params */
3516
3517 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3518 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3519 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3520 } else {
3521 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3522 }
3523
3524 /* capture control */
3525 switch (i_flag) {
3526 case 1:
3527 bktr->bktr_cap_ctl =
3528 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3529 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3530 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3531 interlace = 1;
3532 break;
3533 case 2:
3534 bktr->bktr_cap_ctl =
3535 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3536 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3537 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3538 interlace = 1;
3539 break;
3540 default:
3541 bktr->bktr_cap_ctl =
3542 (BT848_CAP_CTL_DITH_FRAME |
3543 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3544 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3545 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3546 interlace = 2;
3547 break;
3548 }
3549
3550 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3551
3552 rows = bktr->rows;
3553 cols = bktr->cols;
3554
3555 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3556
3557 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3558 /* user, then use the rgb_vbi RISC program. */
3559 /* Otherwise, use the normal rgb RISC program */
3560 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3561 if ( (bktr->vbiflags & VBI_OPEN)
3562 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3563 ||(bktr->format_params == BT848_IFORM_F_SECAM)
3564 ){
3565 bktr->bktr_cap_ctl |=
3566 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3567 bktr->vbiflags |= VBI_CAPTURE;
3568 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3569 return;
3570 } else {
3571 rgb_prog(bktr, i_flag, cols, rows, interlace);
3572 return;
3573 }
3574 }
3575
3576 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3577 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3578 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3579 | pixfmt_swap_flags( bktr->pixfmt ));
3580 return;
3581 }
3582
3583 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3584 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3585 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3586 | pixfmt_swap_flags( bktr->pixfmt ));
3587 return;
3588 }
3589
3590 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3591 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3592 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3593 | pixfmt_swap_flags( bktr->pixfmt ));
3594 return;
3595 }
3596 return;
3597 }
3598
3599
3600 /******************************************************************************
3601 * video & video capture specific routines:
3602 */
3603
3604
3605 /*
3606 *
3607 */
3608 static void
3609 start_capture( bktr_ptr_t bktr, unsigned type )
3610 {
3611 u_char i_flag;
3612 const struct format_params *fp;
3613
3614 fp = &format_params[bktr->format_params];
3615
3616 /* If requested, clear out capture buf first */
3617 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3618 bzero((caddr_t)bktr->bigbuf,
3619 (size_t)bktr->rows * bktr->cols * bktr->frames *
3620 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3621 }
3622
3623 OUTB(bktr, BKTR_DSTATUS, 0);
3624 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3625
3626 bktr->flags |= type;
3627 bktr->flags &= ~METEOR_WANT_MASK;
3628 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3629 case METEOR_ONLY_EVEN_FIELDS:
3630 bktr->flags |= METEOR_WANT_EVEN;
3631 i_flag = 1;
3632 break;
3633 case METEOR_ONLY_ODD_FIELDS:
3634 bktr->flags |= METEOR_WANT_ODD;
3635 i_flag = 2;
3636 break;
3637 default:
3638 bktr->flags |= METEOR_WANT_MASK;
3639 i_flag = 3;
3640 break;
3641 }
3642
3643 /* TDEC is only valid for continuous captures */
3644 if ( type == METEOR_SINGLE ) {
3645 u_short fps_save = bktr->fps;
3646
3647 set_fps(bktr, fp->frame_rate);
3648 bktr->fps = fps_save;
3649 }
3650 else
3651 set_fps(bktr, bktr->fps);
3652
3653 if (bktr->dma_prog_loaded == FALSE) {
3654 build_dma_prog(bktr, i_flag);
3655 bktr->dma_prog_loaded = TRUE;
3656 }
3657
3658
3659 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3660
3661 }
3662
3663
3664 /*
3665 *
3666 */
3667 static void
3668 set_fps( bktr_ptr_t bktr, u_short fps )
3669 {
3670 const struct format_params *fp;
3671 int i_flag;
3672
3673 fp = &format_params[bktr->format_params];
3674
3675 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3676 case METEOR_ONLY_EVEN_FIELDS:
3677 bktr->flags |= METEOR_WANT_EVEN;
3678 i_flag = 1;
3679 break;
3680 case METEOR_ONLY_ODD_FIELDS:
3681 bktr->flags |= METEOR_WANT_ODD;
3682 i_flag = 1;
3683 break;
3684 default:
3685 bktr->flags |= METEOR_WANT_MASK;
3686 i_flag = 2;
3687 break;
3688 }
3689
3690 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3691 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3692
3693 bktr->fps = fps;
3694 OUTB(bktr, BKTR_TDEC, 0);
3695
3696 if (fps < fp->frame_rate)
3697 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3698 else
3699 OUTB(bktr, BKTR_TDEC, 0);
3700 return;
3701
3702 }
3703
3704
3705
3706
3707
3708 /*
3709 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3710 * achieve the specified swapping.
3711 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3712 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3713 * and read R->L).
3714 * Note also that for 3Bpp, we may additionally need to do some creative
3715 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3716 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3717 * as one would expect.
3718 */
3719
3720 static u_int pixfmt_swap_flags( int pixfmt )
3721 {
3722 const struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
3723 u_int swapf = 0;
3724 int swap_bytes, swap_shorts;
3725
3726 #if BYTE_ORDER == LITTLE_ENDIAN
3727 swap_bytes = pf->swap_bytes;
3728 swap_shorts = pf->swap_shorts;
3729 #else
3730 swap_bytes = !pf->swap_bytes;
3731 swap_shorts = !pf->swap_shorts;
3732 #endif
3733 switch ( pf->Bpp ) {
3734 case 2 : swapf = ( swap_bytes ? 0 : BSWAP );
3735 break;
3736
3737 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3738 break;
3739
3740 case 4 :
3741 swapf = swap_bytes ? 0 : BSWAP;
3742 swapf |= swap_shorts ? 0 : WSWAP;
3743 break;
3744 }
3745 return swapf;
3746 }
3747
3748
3749
3750 /*
3751 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3752 * our pixfmt_table indices.
3753 */
3754
3755 static int oformat_meteor_to_bt( u_long format )
3756 {
3757 int i;
3758 const struct meteor_pixfmt *pf1, *pf2;
3759
3760 /* Find format in compatibility table */
3761 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3762 if ( meteor_pixfmt_table[i].meteor_format == format )
3763 break;
3764
3765 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3766 return -1;
3767 pf1 = &meteor_pixfmt_table[i].public;
3768
3769 /* Match it with an entry in master pixel format table */
3770 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3771 pf2 = &pixfmt_table[i].public;
3772
3773 if (( pf1->type == pf2->type ) &&
3774 ( pf1->Bpp == pf2->Bpp ) &&
3775 !memcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3776 ( pf1->swap_bytes == pf2->swap_bytes ) &&
3777 ( pf1->swap_shorts == pf2->swap_shorts ))
3778 break;
3779 }
3780 if ( i >= PIXFMT_TABLE_SIZE )
3781 return -1;
3782
3783 return i;
3784 }
3785
3786 /******************************************************************************
3787 * i2c primitives:
3788 */
3789
3790 /* */
3791 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3792 #define I2CBITTIME_878 (1 << 7)
3793 #define I2C_READ 0x01
3794 #define I2C_COMMAND (I2CBITTIME | \
3795 BT848_DATA_CTL_I2CSCL | \
3796 BT848_DATA_CTL_I2CSDA)
3797
3798 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3799 BT848_DATA_CTL_I2CSCL | \
3800 BT848_DATA_CTL_I2CSDA)
3801
3802 /* Select between old i2c code and new iicbus / smbus code */
3803 #if defined(BKTR_USE_FREEBSD_SMBUS)
3804
3805 /*
3806 * The hardware interface is actually SMB commands
3807 */
3808 int
3809 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3810 {
3811 char cmd;
3812
3813 if (bktr->id == BROOKTREE_848 ||
3814 bktr->id == BROOKTREE_848A ||
3815 bktr->id == BROOKTREE_849A)
3816 cmd = I2C_COMMAND;
3817 else
3818 cmd = I2C_COMMAND_878;
3819
3820 if (byte2 != -1) {
3821 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3822 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3823 return (-1);
3824 } else {
3825 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3826 (char)(byte1 & 0xff)))
3827 return (-1);
3828 }
3829
3830 /* return OK */
3831 return( 0 );
3832 }
3833
3834 int
3835 i2cRead( bktr_ptr_t bktr, int addr )
3836 {
3837 char result;
3838 char cmd;
3839
3840 if (bktr->id == BROOKTREE_848 ||
3841 bktr->id == BROOKTREE_848A ||
3842 bktr->id == BROOKTREE_849A)
3843 cmd = I2C_COMMAND;
3844 else
3845 cmd = I2C_COMMAND_878;
3846
3847 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3848 return (-1);
3849
3850 return ((int)((unsigned char)result));
3851 }
3852
3853 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3854
3855 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3856 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3857 /* Therefore we need low level control of the i2c bus hardware */
3858
3859 /* Write to the MSP or DPL registers */
3860 void
3861 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3862 {
3863 unsigned char addr_l, addr_h, data_h, data_l;
3864
3865 addr_h = (addr >>8) & 0xff;
3866 addr_l = addr & 0xff;
3867 data_h = (data >>8) & 0xff;
3868 data_l = data & 0xff;
3869
3870 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3871
3872 iicbus_write_byte(IICBUS(bktr), dev, 0);
3873 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3874 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3875 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3876 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3877
3878 iicbus_stop(IICBUS(bktr));
3879
3880 return;
3881 }
3882
3883 /* Read from the MSP or DPL registers */
3884 unsigned int
3885 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3886 {
3887 unsigned int data;
3888 unsigned char addr_l, addr_h, dev_r;
3889 int read;
3890 u_char data_read[2];
3891
3892 addr_h = (addr >>8) & 0xff;
3893 addr_l = addr & 0xff;
3894 dev_r = dev+1;
3895
3896 /* XXX errors ignored */
3897 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3898
3899 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3900 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3901 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3902
3903 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3904 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3905 iicbus_stop(IICBUS(bktr));
3906
3907 data = (data_read[0]<<8) | data_read[1];
3908
3909 return (data);
3910 }
3911
3912 /* Reset the MSP or DPL chip */
3913 /* The user can block the reset (which is handy if you initialise the
3914 * MSP and/or DPL audio in another operating system first (eg in Windows)
3915 */
3916 void
3917 msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr )
3918 {
3919
3920 #ifndef BKTR_NO_MSP_RESET
3921 /* put into reset mode */
3922 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3923 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3924 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3925 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3926 iicbus_stop(IICBUS(bktr));
3927
3928 /* put back to operational mode */
3929 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3930 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3931 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3932 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3933 iicbus_stop(IICBUS(bktr));
3934 #endif
3935 return;
3936 }
3937
3938 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3939 int read;
3940
3941 /* XXX errors ignored */
3942 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3943 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3944 iicbus_stop(IICBUS(bktr));
3945
3946 return;
3947 }
3948
3949 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3950
3951 /*
3952 * Program the i2c bus directly
3953 */
3954 int
3955 i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3956 {
3957 u_long x;
3958 u_long data;
3959
3960 /* clear status bits */
3961 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3962
3963 /* build the command datum */
3964 if (bktr->id == BROOKTREE_848 ||
3965 bktr->id == BROOKTREE_848A ||
3966 bktr->id == BROOKTREE_849A) {
3967 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3968 } else {
3969 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3970 }
3971 if ( byte2 != -1 ) {
3972 data |= ((byte2 & 0xff) << 8);
3973 data |= BT848_DATA_CTL_I2CW3B;
3974 }
3975
3976 /* write the address and data */
3977 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3978
3979 /* wait for completion */
3980 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3981 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3982 break;
3983 }
3984
3985 /* check for ACK */
3986 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3987 return( -1 );
3988
3989 /* return OK */
3990 return( 0 );
3991 }
3992
3993
3994 /*
3995 *
3996 */
3997 int
3998 i2cRead( bktr_ptr_t bktr, int addr )
3999 {
4000 u_long x;
4001
4002 /* clear status bits */
4003 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4004
4005 /* write the READ address */
4006 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
4007
4008 if (bktr->id == BROOKTREE_848 ||
4009 bktr->id == BROOKTREE_848A ||
4010 bktr->id == BROOKTREE_849A) {
4011 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
4012 } else {
4013 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
4014 }
4015
4016 /* wait for completion */
4017 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4018 if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
4019 break;
4020 }
4021
4022 /* check for ACK */
4023 if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
4024 return( -1 );
4025
4026 /* it was a read */
4027 return( (INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff );
4028 }
4029
4030 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4031 /* bt848 automated i2c bus controller cannot handle */
4032 /* Therefore we need low level control of the i2c bus hardware */
4033 /* Idea for the following functions are from elsewhere in this driver and */
4034 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel (at) cs.tu-berlin.de> */
4035
4036 #define BITD 40
4037 static void i2c_start( bktr_ptr_t bktr) {
4038 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4039 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4040 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4041 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4042 }
4043
4044 static void i2c_stop( bktr_ptr_t bktr) {
4045 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4046 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4047 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4048 }
4049
4050 static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
4051 int x;
4052 int status;
4053
4054 /* write out the byte */
4055 for ( x = 7; x >= 0; --x ) {
4056 if ( data & (1<<x) ) {
4057 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4058 DELAY( BITD ); /* assert HI data */
4059 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4060 DELAY( BITD ); /* strobe clock */
4061 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4062 DELAY( BITD ); /* release clock */
4063 }
4064 else {
4065 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4066 DELAY( BITD ); /* assert LO data */
4067 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4068 DELAY( BITD ); /* strobe clock */
4069 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4070 DELAY( BITD ); /* release clock */
4071 }
4072 }
4073
4074 /* look for an ACK */
4075 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4076 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4077 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4078 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4079
4080 return( status );
4081 }
4082
4083 static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
4084 int x;
4085 int bit;
4086 int byte = 0;
4087
4088 /* read in the byte */
4089 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4090 DELAY( BITD ); /* float data */
4091 for ( x = 7; x >= 0; --x ) {
4092 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4093 DELAY( BITD ); /* strobe clock */
4094 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4095 if ( bit ) byte |= (1<<x);
4096 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4097 DELAY( BITD ); /* release clock */
4098 }
4099 /* After reading the byte, send an ACK */
4100 /* (unless that was the last byte, for which we send a NAK */
4101 if (last) { /* send NAK - same a writing a 1 */
4102 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4103 DELAY( BITD ); /* set data bit */
4104 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4105 DELAY( BITD ); /* strobe clock */
4106 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4107 DELAY( BITD ); /* release clock */
4108 } else { /* send ACK - same as writing a 0 */
4109 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4110 DELAY( BITD ); /* set data bit */
4111 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4112 DELAY( BITD ); /* strobe clock */
4113 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4114 DELAY( BITD ); /* release clock */
4115 }
4116
4117 *data=byte;
4118 return 0;
4119 }
4120 #undef BITD
4121
4122 /* Write to the MSP or DPL registers */
4123 void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4124 unsigned int data){
4125 unsigned int msp_w_addr = i2c_addr;
4126 unsigned char addr_l, addr_h, data_h, data_l;
4127 addr_h = (addr >>8) & 0xff;
4128 addr_l = addr & 0xff;
4129 data_h = (data >>8) & 0xff;
4130 data_l = data & 0xff;
4131
4132 i2c_start(bktr);
4133 i2c_write_byte(bktr, msp_w_addr);
4134 i2c_write_byte(bktr, dev);
4135 i2c_write_byte(bktr, addr_h);
4136 i2c_write_byte(bktr, addr_l);
4137 i2c_write_byte(bktr, data_h);
4138 i2c_write_byte(bktr, data_l);
4139 i2c_stop(bktr);
4140 }
4141
4142 /* Read from the MSP or DPL registers */
4143 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
4144 unsigned int data;
4145 unsigned char addr_l, addr_h, data_1, data_2, dev_r;
4146 addr_h = (addr >>8) & 0xff;
4147 addr_l = addr & 0xff;
4148 dev_r = dev+1;
4149
4150 i2c_start(bktr);
4151 i2c_write_byte(bktr,i2c_addr);
4152 i2c_write_byte(bktr,dev_r);
4153 i2c_write_byte(bktr,addr_h);
4154 i2c_write_byte(bktr,addr_l);
4155
4156 i2c_start(bktr);
4157 i2c_write_byte(bktr,i2c_addr+1);
4158 i2c_read_byte(bktr,&data_1, 0);
4159 i2c_read_byte(bktr,&data_2, 1);
4160 i2c_stop(bktr);
4161 data = (data_1<<8) | data_2;
4162 return data;
4163 }
4164
4165 /* Reset the MSP or DPL chip */
4166 /* The user can block the reset (which is handy if you initialise the
4167 * MSP audio in another operating system first (eg in Windows)
4168 */
4169 void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
4170
4171 #ifndef BKTR_NO_MSP_RESET
4172 /* put into reset mode */
4173 i2c_start(bktr);
4174 i2c_write_byte(bktr, i2c_addr);
4175 i2c_write_byte(bktr, 0x00);
4176 i2c_write_byte(bktr, 0x80);
4177 i2c_write_byte(bktr, 0x00);
4178 i2c_stop(bktr);
4179
4180 /* put back to operational mode */
4181 i2c_start(bktr);
4182 i2c_write_byte(bktr, i2c_addr);
4183 i2c_write_byte(bktr, 0x00);
4184 i2c_write_byte(bktr, 0x00);
4185 i2c_write_byte(bktr, 0x00);
4186 i2c_stop(bktr);
4187 #endif
4188 return;
4189
4190 }
4191
4192 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4193
4194 /* XXX errors ignored */
4195 i2c_start(bktr);
4196 i2c_write_byte(bktr,bktr->remote_control_addr);
4197 i2c_read_byte(bktr,&(remote->data[0]), 0);
4198 i2c_read_byte(bktr,&(remote->data[1]), 0);
4199 i2c_read_byte(bktr,&(remote->data[2]), 0);
4200 i2c_stop(bktr);
4201
4202 return;
4203 }
4204
4205 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4206
4207
4208 #if defined( I2C_SOFTWARE_PROBE )
4209
4210 /*
4211 * we are keeping this around for any parts that we need to probe
4212 * but that CANNOT be probed via an i2c read.
4213 * this is necessary because the hardware i2c mechanism
4214 * cannot be programmed for 1 byte writes.
4215 * currently there are no known i2c parts that we need to probe
4216 * and that cannot be safely read.
4217 */
4218 static int i2cProbe( bktr_ptr_t bktr, int addr );
4219 #define BITD 40
4220 #define EXTRA_START
4221
4222 /*
4223 * probe for an I2C device at addr.
4224 */
4225 static int
4226 i2cProbe( bktr_ptr_t bktr, int addr )
4227 {
4228 int x, status;
4229
4230 /* the START */
4231 #if defined( EXTRA_START )
4232 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
4233 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
4234 #endif /* EXTRA_START */
4235 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
4236 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
4237
4238 /* write addr */
4239 for ( x = 7; x >= 0; --x ) {
4240 if ( addr & (1<<x) ) {
4241 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4242 DELAY( BITD ); /* assert HI data */
4243 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4244 DELAY( BITD ); /* strobe clock */
4245 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4246 DELAY( BITD ); /* release clock */
4247 }
4248 else {
4249 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4250 DELAY( BITD ); /* assert LO data */
4251 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4252 DELAY( BITD ); /* strobe clock */
4253 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4254 DELAY( BITD ); /* release clock */
4255 }
4256 }
4257
4258 /* look for an ACK */
4259 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
4260 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
4261 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4262 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
4263
4264 /* the STOP */
4265 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
4266 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
4267 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
4268
4269 return( status );
4270 }
4271 #undef EXTRA_START
4272 #undef BITD
4273
4274 #endif /* I2C_SOFTWARE_PROBE */
4275
4276
4277 #define ABSENT (-1)
4278
4279 #endif /* FreeBSD, BSDI, NetBSD, OpenBSD */
4280
4281