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