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