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