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