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