bktr_core.c revision 1.30 1 /* $SourceForge: bktr_core.c,v 1.6 2003/03/11 23:11:22 thomasklausner Exp $ */
2
3 /* $NetBSD: bktr_core.c,v 1.30 2003/04/28 14:43:32 fvdl 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.30 2003/04/28 14:43:32 fvdl 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 buf = 0;
479 #else
480 vm_offset_t buf = 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 buf = get_bktr_mem(bktr, &bktr->dm_mem, BROOKTREE_ALLOC);
502 else
503 buf = 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 buf = 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 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
534 else
535 buf = 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, buf);
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(buf));
554 }
555
556 if (buf != 0) {
557 bktr->bigbuf = buf;
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 proc* pr)
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 buf;
1297 #else
1298 vm_offset_t buf;
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 = pr;
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 buf = get_bktr_mem(bktr, &dmamap,
1760 temp * PAGE_SIZE);
1761 if (buf != 0) {
1762 free_bktr_mem(bktr, bktr->dm_mem,
1763 bktr->bigbuf);
1764 bktr->dm_mem = dmamap;
1765
1766 #else
1767 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
1768 if (buf != 0) {
1769 kmem_free(kernel_map, bktr->bigbuf,
1770 (bktr->alloc_pages * PAGE_SIZE));
1771 #endif
1772
1773 bktr->bigbuf = buf;
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 proc* pr)
1907 #endif
1908 {
1909 int tmp_int;
1910 unsigned int temp, temp1;
1911 int offset;
1912 int count;
1913 u_char *buf;
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 if (temp < 0) {
1943 temp_mute(bktr, FALSE);
1944 return(EINVAL);
1945 }
1946 *(unsigned long *)arg = temp;
1947
1948 /* after every channel change, we must restart the MSP34xx */
1949 /* audio chip to reselect NICAM STEREO or MONO audio */
1950 if (bktr->card.msp3400c)
1951 msp_autodetect(bktr);
1952
1953 /* after every channel change, we must restart the DPL35xx */
1954 if (bktr->card.dpl3518a)
1955 dpl_autodetect(bktr);
1956
1957 temp_mute(bktr, FALSE);
1958 break;
1959
1960 case TVTUNER_GETCHNL:
1961 *(unsigned long *)arg = bktr->tuner.channel;
1962 break;
1963
1964 case TVTUNER_SETTYPE:
1965 temp = *(unsigned long *)arg;
1966 if ((temp < CHNLSET_MIN) || (temp > CHNLSET_MAX))
1967 return(EINVAL);
1968 bktr->tuner.chnlset = temp;
1969 break;
1970
1971 case TVTUNER_GETTYPE:
1972 *(unsigned long *)arg = bktr->tuner.chnlset;
1973 break;
1974
1975 case TVTUNER_GETSTATUS:
1976 temp = get_tuner_status(bktr);
1977 *(unsigned long *)arg = temp & 0xff;
1978 break;
1979
1980 case TVTUNER_SETFREQ:
1981 temp_mute(bktr, TRUE);
1982 temp = tv_freq(bktr, (int)*(unsigned long *)arg, TV_FREQUENCY);
1983 temp_mute(bktr, FALSE);
1984 if (temp < 0) {
1985 temp_mute(bktr, FALSE);
1986 return(EINVAL);
1987 }
1988 *(unsigned long *)arg = temp;
1989
1990 /* after every channel change, we must restart the MSP34xx */
1991 /* audio chip to reselect NICAM STEREO or MONO audio */
1992 if (bktr->card.msp3400c)
1993 msp_autodetect(bktr);
1994
1995 /* after every channel change, we must restart the DPL35xx */
1996 if (bktr->card.dpl3518a)
1997 dpl_autodetect(bktr);
1998
1999 temp_mute(bktr, FALSE);
2000 break;
2001
2002 case TVTUNER_GETFREQ:
2003 *(unsigned long *)arg = bktr->tuner.frequency;
2004 break;
2005
2006 case TVTUNER_GETCHNLSET:
2007 return tuner_getchnlset((struct bktr_chnlset *)arg);
2008
2009 case BT848_SAUDIO: /* set audio channel */
2010 if (set_audio(bktr, *(int*)arg) < 0)
2011 return(EIO);
2012 break;
2013
2014 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
2015 case BT848_SHUE: /* set hue */
2016 OUTB(bktr, BKTR_HUE, (u_char)(*(int*)arg & 0xff));
2017 break;
2018
2019 case BT848_GHUE: /* get hue */
2020 *(int*)arg = (signed char)(INB(bktr, BKTR_HUE) & 0xff);
2021 break;
2022
2023 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
2024 case BT848_SBRIG: /* set brightness */
2025 OUTB(bktr, BKTR_BRIGHT, (u_char)(*(int *)arg & 0xff));
2026 break;
2027
2028 case BT848_GBRIG: /* get brightness */
2029 *(int *)arg = (signed char)(INB(bktr, BKTR_BRIGHT) & 0xff);
2030 break;
2031
2032 /* */
2033 case BT848_SCSAT: /* set chroma saturation */
2034 tmp_int = *(int*)arg;
2035
2036 temp = INB(bktr, BKTR_E_CONTROL);
2037 temp1 = INB(bktr, BKTR_O_CONTROL);
2038 if (tmp_int & BIT_EIGHT_HIGH) {
2039 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2040 BT848_E_CONTROL_SAT_V_MSB);
2041 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2042 BT848_O_CONTROL_SAT_V_MSB);
2043 }
2044 else {
2045 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2046 BT848_E_CONTROL_SAT_V_MSB);
2047 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2048 BT848_O_CONTROL_SAT_V_MSB);
2049 }
2050
2051 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2052 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2053 OUTB(bktr, BKTR_E_CONTROL, temp);
2054 OUTB(bktr, BKTR_O_CONTROL, temp1);
2055 break;
2056
2057 case BT848_GCSAT: /* get chroma saturation */
2058 tmp_int = (int)(INB(bktr, BKTR_SAT_V_LO) & 0xff);
2059 if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB)
2060 tmp_int |= BIT_EIGHT_HIGH;
2061 *(int*)arg = tmp_int;
2062 break;
2063
2064 /* */
2065 case BT848_SVSAT: /* set chroma V saturation */
2066 tmp_int = *(int*)arg;
2067
2068 temp = INB(bktr, BKTR_E_CONTROL);
2069 temp1 = INB(bktr, BKTR_O_CONTROL);
2070 if (tmp_int & BIT_EIGHT_HIGH) {
2071 temp |= BT848_E_CONTROL_SAT_V_MSB;
2072 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2073 }
2074 else {
2075 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2076 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2077 }
2078
2079 OUTB(bktr, BKTR_SAT_V_LO, (u_char)(tmp_int & 0xff));
2080 OUTB(bktr, BKTR_E_CONTROL, temp);
2081 OUTB(bktr, BKTR_O_CONTROL, temp1);
2082 break;
2083
2084 case BT848_GVSAT: /* get chroma V saturation */
2085 tmp_int = (int)INB(bktr, BKTR_SAT_V_LO) & 0xff;
2086 if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB)
2087 tmp_int |= BIT_EIGHT_HIGH;
2088 *(int*)arg = tmp_int;
2089 break;
2090
2091 /* */
2092 case BT848_SUSAT: /* set chroma U saturation */
2093 tmp_int = *(int*)arg;
2094
2095 temp = INB(bktr, BKTR_E_CONTROL);
2096 temp1 = INB(bktr, BKTR_O_CONTROL);
2097 if (tmp_int & BIT_EIGHT_HIGH) {
2098 temp |= BT848_E_CONTROL_SAT_U_MSB;
2099 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2100 }
2101 else {
2102 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2103 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2104 }
2105
2106 OUTB(bktr, BKTR_SAT_U_LO, (u_char)(tmp_int & 0xff));
2107 OUTB(bktr, BKTR_E_CONTROL, temp);
2108 OUTB(bktr, BKTR_O_CONTROL, temp1);
2109 break;
2110
2111 case BT848_GUSAT: /* get chroma U saturation */
2112 tmp_int = (int)INB(bktr, BKTR_SAT_U_LO) & 0xff;
2113 if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_U_MSB)
2114 tmp_int |= BIT_EIGHT_HIGH;
2115 *(int*)arg = tmp_int;
2116 break;
2117
2118 /* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2119
2120 case BT848_SLNOTCH: /* set luma notch */
2121 tmp_int = (*(int *)arg & 0x7) << 5;
2122 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~0xe0);
2123 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~0xe0);
2124 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | tmp_int);
2125 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | tmp_int);
2126 break;
2127
2128 case BT848_GLNOTCH: /* get luma notch */
2129 *(int *)arg = (int) ((INB(bktr, BKTR_E_CONTROL) & 0xe0) >> 5);
2130 break;
2131
2132
2133 /* */
2134 case BT848_SCONT: /* set contrast */
2135 tmp_int = *(int*)arg;
2136
2137 temp = INB(bktr, BKTR_E_CONTROL);
2138 temp1 = INB(bktr, BKTR_O_CONTROL);
2139 if (tmp_int & BIT_EIGHT_HIGH) {
2140 temp |= BT848_E_CONTROL_CON_MSB;
2141 temp1 |= BT848_O_CONTROL_CON_MSB;
2142 }
2143 else {
2144 temp &= ~BT848_E_CONTROL_CON_MSB;
2145 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2146 }
2147
2148 OUTB(bktr, BKTR_CONTRAST_LO, (u_char)(tmp_int & 0xff));
2149 OUTB(bktr, BKTR_E_CONTROL, temp);
2150 OUTB(bktr, BKTR_O_CONTROL, temp1);
2151 break;
2152
2153 case BT848_GCONT: /* get contrast */
2154 tmp_int = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
2155 if (INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_CON_MSB)
2156 tmp_int |= BIT_EIGHT_HIGH;
2157 *(int*)arg = tmp_int;
2158 break;
2159
2160 /* FIXME: SCBARS and CCBARS require a valid int * */
2161 /* argument to succeed, but its not used; consider */
2162 /* using the arg to store the on/off state so */
2163 /* there's only one ioctl() needed to turn cbars on/off */
2164 case BT848_SCBARS: /* set colorbar output */
2165 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_COLOR_BARS);
2166 break;
2167
2168 case BT848_CCBARS: /* clear colorbar output */
2169 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) & ~(BT848_COLOR_CTL_COLOR_BARS));
2170 break;
2171
2172 case BT848_GAUDIO: /* get audio channel */
2173 temp = bktr->audio_mux_select;
2174 if (bktr->audio_mute_state == TRUE)
2175 temp |= AUDIO_MUTE;
2176 *(int*)arg = temp;
2177 break;
2178
2179 case BT848_SBTSC: /* set audio channel */
2180 if (set_BTSC(bktr, *(int*)arg) < 0)
2181 return(EIO);
2182 break;
2183
2184 case BT848_WEEPROM: /* write eeprom */
2185 offset = (((struct eeProm *)arg)->offset);
2186 count = (((struct eeProm *)arg)->count);
2187 buf = &(((struct eeProm *)arg)->bytes[0]);
2188 if (writeEEProm(bktr, offset, count, buf) < 0)
2189 return(EIO);
2190 break;
2191
2192 case BT848_REEPROM: /* read eeprom */
2193 offset = (((struct eeProm *)arg)->offset);
2194 count = (((struct eeProm *)arg)->count);
2195 buf = &(((struct eeProm *)arg)->bytes[0]);
2196 if (readEEProm(bktr, offset, count, buf) < 0)
2197 return(EIO);
2198 break;
2199
2200 case BT848_SIGNATURE:
2201 offset = (((struct eeProm *)arg)->offset);
2202 count = (((struct eeProm *)arg)->count);
2203 buf = &(((struct eeProm *)arg)->bytes[0]);
2204 if (signCard(bktr, offset, count, buf) < 0)
2205 return(EIO);
2206 break;
2207
2208 /* Ioctl's for direct gpio access */
2209 #ifdef BKTR_GPIO_ACCESS
2210 case BT848_GPIO_GET_EN:
2211 *(int*)arg = INL(bktr, BKTR_GPIO_OUT_EN);
2212 break;
2213
2214 case BT848_GPIO_SET_EN:
2215 OUTL(bktr, BKTR_GPIO_OUT_EN, *(int*)arg);
2216 break;
2217
2218 case BT848_GPIO_GET_DATA:
2219 *(int*)arg = INL(bktr, BKTR_GPIO_DATA);
2220 break;
2221
2222 case BT848_GPIO_SET_DATA:
2223 OUTL(bktr, BKTR_GPIO_DATA, *(int*)arg);
2224 break;
2225 #endif /* BKTR_GPIO_ACCESS */
2226
2227 /* Ioctl's for running the tuner device in radio mode */
2228
2229 case RADIO_GETMODE:
2230 *(unsigned char *)arg = bktr->tuner.radio_mode;
2231 break;
2232
2233 case RADIO_SETMODE:
2234 bktr->tuner.radio_mode = *(unsigned char *)arg;
2235 break;
2236
2237 case RADIO_GETFREQ:
2238 *(unsigned long *)arg = bktr->tuner.frequency;
2239 break;
2240
2241 case RADIO_SETFREQ:
2242 /* The argument to this ioctl is NOT freq*16. It is
2243 ** freq*100.
2244 */
2245
2246 temp=(int)*(unsigned long *)arg;
2247
2248 #ifdef BKTR_RADIO_DEBUG
2249 printf("%s: arg=%d temp=%d\n", bktr_name(bktr),
2250 (int)*(unsigned long *)arg, temp);
2251 #endif
2252
2253 #ifndef BKTR_RADIO_NOFREQCHECK
2254 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2255 /* is supported. */
2256 if(temp<8750 || temp>10800) {
2257 printf("%s: Radio frequency out of range\n", bktr_name(bktr));
2258 return(EINVAL);
2259 }
2260 #endif
2261 temp_mute(bktr, TRUE);
2262 temp = tv_freq(bktr, temp, FM_RADIO_FREQUENCY);
2263 temp_mute(bktr, FALSE);
2264 #ifdef BKTR_RADIO_DEBUG
2265 if(temp)
2266 printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2267 #endif
2268 if (temp < 0)
2269 return(EINVAL);
2270 *(unsigned long *)arg = temp;
2271 break;
2272
2273 /* Luigi's I2CWR ioctl */
2274 case BT848_I2CWR:
2275 par = *(u_long *)arg;
2276 write = (par >> 24) & 0xff;
2277 i2c_addr = (par >> 16) & 0xff;
2278 i2c_port = (par >> 8) & 0xff;
2279 data = (par) & 0xff;
2280
2281 if (write) {
2282 i2cWrite(bktr, i2c_addr, i2c_port, data);
2283 } else {
2284 data = i2cRead(bktr, i2c_addr);
2285 }
2286 *(u_long *)arg = (par & 0xffffff00) | (data & 0xff);
2287 break;
2288
2289
2290 #ifdef BT848_MSP_READ
2291 /* I2C ioctls to allow userland access to the MSP chip */
2292 case BT848_MSP_READ:
2293 {
2294 struct bktr_msp_control *msp;
2295 msp = (struct bktr_msp_control *) arg;
2296 msp->data = msp_dpl_read(bktr, bktr->msp_addr,
2297 msp->function, msp->address);
2298 break;
2299 }
2300
2301 case BT848_MSP_WRITE:
2302 {
2303 struct bktr_msp_control *msp;
2304 msp = (struct bktr_msp_control *) arg;
2305 msp_dpl_write(bktr, bktr->msp_addr, msp->function,
2306 msp->address, msp->data);
2307 break;
2308 }
2309
2310 case BT848_MSP_RESET:
2311 msp_dpl_reset(bktr, bktr->msp_addr);
2312 break;
2313 #endif
2314
2315 default:
2316 return common_ioctl(bktr, cmd, arg);
2317 }
2318
2319 return(0);
2320 }
2321
2322
2323 /*
2324 * common ioctls
2325 */
2326 static int
2327 common_ioctl(bktr_ptr_t bktr, ioctl_cmd_t cmd, caddr_t arg)
2328 {
2329 int pixfmt;
2330 unsigned int temp;
2331 struct meteor_pixfmt *pf_pub;
2332
2333 switch (cmd) {
2334
2335 case METEORSINPUT: /* set input device */
2336 /*Bt848 has 3 MUX Inputs. Bt848A/849A/878/879 has 4 MUX Inputs*/
2337 /* On the original bt848 boards, */
2338 /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
2339 /* On the Hauppauge bt878 boards, */
2340 /* Tuner is MUX0, RCA is MUX3 */
2341 /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
2342 /* stick with this system in our Meteor Emulation */
2343
2344 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2345
2346 /* this is the RCA video input */
2347 case 0: /* default */
2348 case METEOR_INPUT_DEV0:
2349 /* METEOR_INPUT_DEV_RCA: */
2350 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2351 | METEOR_DEV0;
2352 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM)
2353 & ~BT848_IFORM_MUXSEL);
2354
2355 /* work around for new Hauppauge 878 cards */
2356 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2357 (bktr->id==BROOKTREE_878 ||
2358 bktr->id==BROOKTREE_879))
2359 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2360 else
2361 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2362
2363 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2364 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2365 set_audio(bktr, AUDIO_EXTERN);
2366 break;
2367
2368 /* this is the tuner input */
2369 case METEOR_INPUT_DEV1:
2370 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2371 | METEOR_DEV1;
2372 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2373 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX0);
2374 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2375 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2376 set_audio(bktr, AUDIO_TUNER);
2377 break;
2378
2379 /* this is the S-VHS input, but with a composite camera */
2380 case METEOR_INPUT_DEV2:
2381 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2382 | METEOR_DEV2;
2383 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2384 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2385 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2386 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_O_CONTROL_COMP);
2387 set_audio(bktr, AUDIO_EXTERN);
2388 break;
2389
2390 /* this is the S-VHS input */
2391 case METEOR_INPUT_DEV_SVIDEO:
2392 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2393 | METEOR_DEV_SVIDEO;
2394 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2395 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX2);
2396 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_COMP);
2397 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_COMP);
2398 set_audio(bktr, AUDIO_EXTERN);
2399 break;
2400
2401 case METEOR_INPUT_DEV3:
2402 if ((bktr->id == BROOKTREE_848A) ||
2403 (bktr->id == BROOKTREE_849A) ||
2404 (bktr->id == BROOKTREE_878) ||
2405 (bktr->id == BROOKTREE_879)) {
2406 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2407 | METEOR_DEV3;
2408 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) & ~BT848_IFORM_MUXSEL);
2409
2410 /* work around for new Hauppauge 878 cards */
2411 if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
2412 (bktr->id==BROOKTREE_878 ||
2413 bktr->id==BROOKTREE_879))
2414 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX1);
2415 else
2416 OUTB(bktr, BKTR_IFORM, INB(bktr, BKTR_IFORM) | BT848_IFORM_M_MUX3);
2417
2418 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_COMP);
2419 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_COMP);
2420 set_audio(bktr, AUDIO_EXTERN);
2421
2422 break;
2423 }
2424
2425 default:
2426 return(EINVAL);
2427 }
2428 break;
2429
2430 case METEORGINPUT: /* get input device */
2431 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2432 break;
2433
2434 case METEORSACTPIXFMT:
2435 if ((*(int *)arg < 0) ||
2436 (*(int *)arg >= PIXFMT_TABLE_SIZE))
2437 return(EINVAL);
2438
2439 bktr->pixfmt = *(int *)arg;
2440 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2441 | pixfmt_swap_flags(bktr->pixfmt));
2442 bktr->pixfmt_compat = FALSE;
2443 break;
2444
2445 case METEORGACTPIXFMT:
2446 *(int *)arg = bktr->pixfmt;
2447 break;
2448
2449 case METEORGSUPPIXFMT :
2450 pf_pub = (struct meteor_pixfmt *)arg;
2451 pixfmt = pf_pub->index;
2452
2453 if ((pixfmt < 0) || (pixfmt >= PIXFMT_TABLE_SIZE))
2454 return(EINVAL);
2455
2456 memcpy(pf_pub, &pixfmt_table[pixfmt].public,
2457 sizeof(*pf_pub));
2458
2459 /* Patch in our format index */
2460 pf_pub->index = pixfmt;
2461 break;
2462
2463 #if defined(STATUS_SUM)
2464 case BT848_GSTATUS: /* reap status */
2465 {
2466 DECLARE_INTR_MASK(s);
2467 DISABLE_INTR(s);
2468 temp = status_sum;
2469 status_sum = 0;
2470 ENABLE_INTR(s);
2471 *(u_int*)arg = temp;
2472 break;
2473 }
2474 #endif /* STATUS_SUM */
2475
2476 default:
2477 return(ENOTTY);
2478 }
2479
2480 return(0);
2481 }
2482
2483
2484
2485
2486 /******************************************************************************
2487 * bt848 RISC programming routines:
2488 */
2489
2490
2491 /*
2492 *
2493 */
2494 #ifdef BT848_DEBUG
2495 static int
2496 dump_bt848(bktr_ptr_t bktr)
2497 {
2498 int r[60]={
2499 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2500 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2501 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2502 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2503 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2504 0, 0, 0, 0
2505 };
2506 int i;
2507
2508 for (i = 0; i < 40; i+=4) {
2509 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2510 bktr_name(bktr),
2511 r[i], INL(bktr, r[i]),
2512 r[i+1], INL(bktr, r[i+1]),
2513 r[i+2], INL(bktr, r[i+2]),
2514 r[i+3], INL(bktr, r[i+3]));
2515 }
2516
2517 printf("%s: INT STAT %x \n", bktr_name(bktr),
2518 INL(bktr, BKTR_INT_STAT));
2519 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2520 INL(bktr, BKTR_INT_MASK));
2521 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2522 INW(bktr, BKTR_GPIO_DMA_CTL));
2523
2524 return(0);
2525 }
2526
2527 #endif
2528
2529 /*
2530 * build write instruction
2531 */
2532 #define BKTR_FM1 0x6 /* packed data to follow */
2533 #define BKTR_FM3 0xe /* planar data to follow */
2534 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2535 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2536 #define BKTR_PXV 0x0 /* valid word (never used) */
2537 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2538 #define BKTR_SOL 0x2 /* first dword */
2539
2540 #define OP_WRITE (0x1 << 28)
2541 #define OP_SKIP (0x2 << 28)
2542 #define OP_WRITEC (0x5 << 28)
2543 #define OP_JUMP (0x7 << 28)
2544 #define OP_SYNC (0x8 << 28)
2545 #define OP_WRITE123 (0x9 << 28)
2546 #define OP_WRITES123 (0xb << 28)
2547 #define OP_SOL (1 << 27) /* first instr for scanline */
2548 #define OP_EOL (1 << 26)
2549
2550 #define BKTR_RESYNC (1 << 15)
2551 #define BKTR_GEN_IRQ (1 << 24)
2552
2553 /*
2554 * The RISC status bits can be set/cleared in the RISC programs
2555 * and tested in the Interrupt Handler
2556 */
2557 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2558 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2559 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2560 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2561
2562 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2563 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2564 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2565 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2566
2567 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2568 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2569 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2570 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2571
2572 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2573 int i;
2574 bktr_clip_t * clip_node;
2575 bktr->clip_start = -1;
2576 bktr->last_y = 0;
2577 bktr->y = 0;
2578 bktr->y2 = width;
2579 bktr->line_length = width;
2580 bktr->yclip = -1;
2581 bktr->yclip2 = -1;
2582 bktr->current_col = 0;
2583
2584 if (bktr->max_clip_node == 0) return TRUE;
2585 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2586
2587
2588 for (i = 0; i < bktr->max_clip_node; i++) {
2589 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2590 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2591 bktr->clip_start = i;
2592 return FALSE;
2593 }
2594 }
2595
2596 return TRUE;
2597 }
2598
2599 static bool_t getline(bktr_reg_t *bktr, int x) {
2600 int i, j;
2601 bktr_clip_t * clip_node;
2602
2603 if (bktr->line_length == 0 ||
2604 bktr->current_col >= bktr->line_length) return FALSE;
2605
2606 bktr->y = min(bktr->last_y, bktr->line_length);
2607 bktr->y2 = bktr->line_length;
2608
2609 bktr->yclip = bktr->yclip2 = -1;
2610 for (i = bktr->clip_start; i < bktr->max_clip_node; i++) {
2611 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2612 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2613 if (bktr->last_y <= clip_node->y_min) {
2614 bktr->y = min(bktr->last_y, bktr->line_length);
2615 bktr->y2 = min(clip_node->y_min, bktr->line_length);
2616 bktr->yclip = min(clip_node->y_min, bktr->line_length);
2617 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2618 bktr->last_y = bktr->yclip2;
2619 bktr->clip_start = i;
2620
2621 for (j = i+1; j < bktr->max_clip_node; j++) {
2622 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2623 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2624 if (bktr->last_y >= clip_node->y_min) {
2625 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
2626 bktr->last_y = bktr->yclip2;
2627 bktr->clip_start = j;
2628 }
2629 } else break;
2630 }
2631 return TRUE;
2632 }
2633 }
2634 }
2635
2636 if (bktr->current_col <= bktr->line_length) {
2637 bktr->current_col = bktr->line_length;
2638 return TRUE;
2639 }
2640 return FALSE;
2641 }
2642
2643 static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
2644 u_long operation, int pixel_width,
2645 volatile u_char ** target_buffer, int cols) {
2646
2647 u_long flag, flag2;
2648 const struct meteor_pixfmt *pf = &pixfmt_table[bktr->pixfmt].public;
2649 u_int skip, start_skip;
2650
2651 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2652 /* to the 1st byte in the mem dword containing our start addr. */
2653 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2654 /* must be Blue. */
2655 start_skip = 0;
2656 if ((pf->type == METEOR_PIXTYPE_RGB) && (pf->Bpp == 3))
2657 switch (((uintptr_t) (volatile void *) *target_buffer) % 4) {
2658 case 2 : start_skip = 4; break;
2659 case 1 : start_skip = 8; break;
2660 }
2661
2662 if ((width * pixel_width) < DMA_BT848_SPLIT) {
2663 if (width == cols) {
2664 flag = OP_SOL | OP_EOL;
2665 } else if (bktr->current_col == 0) {
2666 flag = OP_SOL;
2667 } else if (bktr->current_col == cols) {
2668 flag = OP_EOL;
2669 } else flag = 0;
2670
2671 skip = 0;
2672 if ((flag & OP_SOL) && (start_skip > 0)) {
2673 *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2674 flag &= ~OP_SOL;
2675 skip = start_skip;
2676 }
2677
2678 *(*dma_prog)++ = htole32(operation | flag |
2679 (width * pixel_width - skip));
2680 if (operation != OP_SKIP)
2681 *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
2682
2683 *target_buffer += width * pixel_width;
2684 bktr->current_col += width;
2685
2686 } else {
2687
2688 if (bktr->current_col == 0 && width == cols) {
2689 flag = OP_SOL;
2690 flag2 = OP_EOL;
2691 } else if (bktr->current_col == 0) {
2692 flag = OP_SOL;
2693 flag2 = 0;
2694 } else if (bktr->current_col >= cols) {
2695 flag = 0;
2696 flag2 = OP_EOL;
2697 } else {
2698 flag = 0;
2699 flag2 = 0;
2700 }
2701
2702 skip = 0;
2703 if ((flag & OP_SOL) && (start_skip > 0)) {
2704 *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2705 flag &= ~OP_SOL;
2706 skip = start_skip;
2707 }
2708
2709 *(*dma_prog)++ = htole32(operation | flag |
2710 (width * pixel_width / 2 - skip));
2711 if (operation != OP_SKIP)
2712 *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
2713 *target_buffer += (width * pixel_width / 2);
2714
2715 if (operation == OP_WRITE)
2716 operation = OP_WRITEC;
2717 *(*dma_prog)++ = htole32(operation | flag2 |
2718 (width * pixel_width / 2));
2719 *target_buffer += (width * pixel_width / 2);
2720 bktr->current_col += width;
2721
2722 }
2723 return TRUE;
2724 }
2725
2726
2727 /*
2728 * Generate the RISC instructions to capture both VBI and video images
2729 */
2730 static void
2731 rgb_vbi_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2732 {
2733 int i;
2734 volatile u_long target_buffer, buffer, target,width;
2735 volatile u_long pitch;
2736 volatile u_long *dma_prog; /* DMA prog is an array of
2737 32 bit RISC instructions */
2738 volatile u_long *loop_point;
2739 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
2740 u_int Bpp = pf_int->public.Bpp;
2741 unsigned int vbisamples; /* VBI samples per line */
2742 unsigned int vbilines; /* VBI lines per field */
2743 unsigned int num_dwords; /* DWORDS per line */
2744
2745 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2746 vbilines = format_params[bktr->format_params].vbi_num_lines;
2747 num_dwords = vbisamples/4;
2748
2749 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2750 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2751 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2752 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2753 /* no ext frame */
2754
2755 OUTB(bktr, BKTR_OFORM, 0x00);
2756
2757 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2758 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2759 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2760 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2761
2762 /* disable gamma correction removal */
2763 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2764
2765 if (cols > 385) {
2766 OUTB(bktr, BKTR_E_VTC, 0);
2767 OUTB(bktr, BKTR_O_VTC, 0);
2768 } else {
2769 OUTB(bktr, BKTR_E_VTC, 1);
2770 OUTB(bktr, BKTR_O_VTC, 1);
2771 }
2772 bktr->capcontrol = 3 << 2 | 3;
2773
2774 dma_prog = (u_long *) bktr->dma_prog;
2775
2776 /* Construct Write */
2777
2778 if (bktr->video.addr) {
2779 target_buffer = (u_long) bktr->video.addr;
2780 pitch = bktr->video.width;
2781 }
2782 else {
2783 target_buffer = (u_long) vtophys(bktr->bigbuf);
2784 pitch = cols*Bpp;
2785 }
2786
2787 buffer = target_buffer;
2788
2789 /* Wait for the VRE sync marking the end of the Even and
2790 * the start of the Odd field. Resync here.
2791 */
2792 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_VRE);
2793 *dma_prog++ = htole32(0);
2794
2795 loop_point = dma_prog;
2796
2797 /* store the VBI data */
2798 /* look for sync with packed data */
2799 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2800 *dma_prog++ = htole32(0);
2801 for(i = 0; i < vbilines; i++) {
2802 *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2803 *dma_prog++ = htole32((u_long) vtophys(bktr->vbidata +
2804 (i * VBI_LINE_SIZE)));
2805 }
2806
2807 if ((i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/) {
2808 /* store the Odd field video image */
2809 /* look for sync with packed data */
2810 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2811 *dma_prog++ = htole32(0); /* NULL WORD */
2812 width = cols;
2813 for (i = 0; i < (rows/interlace); i++) {
2814 target = target_buffer;
2815 if (notclipped(bktr, i, width)) {
2816 split(bktr, (volatile u_long **) &dma_prog,
2817 bktr->y2 - bktr->y, OP_WRITE,
2818 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2819
2820 } else {
2821 while(getline(bktr, i)) {
2822 if (bktr->y != bktr->y2) {
2823 split(bktr, (volatile u_long **) &dma_prog,
2824 bktr->y2 - bktr->y, OP_WRITE,
2825 Bpp, (volatile u_char **) (uintptr_t)&target, cols);
2826 }
2827 if (bktr->yclip != bktr->yclip2) {
2828 split(bktr,(volatile u_long **) &dma_prog,
2829 bktr->yclip2 - bktr->yclip,
2830 OP_SKIP,
2831 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2832 }
2833 }
2834
2835 }
2836
2837 target_buffer += interlace * pitch;
2838
2839 }
2840
2841 } /* end if */
2842
2843 /* Grab the Even field */
2844 /* Look for the VRO, end of Odd field, marker */
2845 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2846 *dma_prog++ = htole32(0); /* NULL WORD */
2847
2848 /* store the VBI data */
2849 /* look for sync with packed data */
2850 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2851 *dma_prog++ = htole32(0);
2852 for(i = 0; i < vbilines; i++) {
2853 *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2854 *dma_prog++ = htole32((u_long) vtophys(bktr->vbidata +
2855 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE)));
2856 }
2857
2858 /* store the video image */
2859 if (i_flag == 1) /*Even Only*/
2860 target_buffer = buffer;
2861 if (i_flag == 3) /*interlaced*/
2862 target_buffer = buffer+pitch;
2863
2864
2865 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2866 /* look for sync with packed data */
2867 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2868 *dma_prog++ = htole32(0); /* NULL WORD */
2869 width = cols;
2870 for (i = 0; i < (rows/interlace); i++) {
2871 target = target_buffer;
2872 if (notclipped(bktr, i, width)) {
2873 split(bktr, (volatile u_long **) &dma_prog,
2874 bktr->y2 - bktr->y, OP_WRITE,
2875 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2876 } else {
2877 while(getline(bktr, i)) {
2878 if (bktr->y != bktr->y2) {
2879 split(bktr, (volatile u_long **) &dma_prog,
2880 bktr->y2 - bktr->y, OP_WRITE,
2881 Bpp, (volatile u_char **)(uintptr_t)&target,
2882 cols);
2883 }
2884 if (bktr->yclip != bktr->yclip2) {
2885 split(bktr, (volatile u_long **) &dma_prog,
2886 bktr->yclip2 - bktr->yclip, OP_SKIP,
2887 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2888 }
2889
2890 }
2891
2892 }
2893
2894 target_buffer += interlace * pitch;
2895
2896 }
2897 }
2898
2899 /* Look for end of 'Even Field' */
2900 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2901 *dma_prog++ = htole32(0); /* NULL WORD */
2902
2903 *dma_prog++ = htole32(OP_JUMP);
2904 *dma_prog++ = htole32((u_long) vtophys((vaddr_t)loop_point));
2905 *dma_prog++ = htole32(0); /* NULL WORD */
2906
2907 }
2908
2909
2910
2911
2912 static void
2913 rgb_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2914 {
2915 int i;
2916 volatile u_long target_buffer, buffer, target,width;
2917 volatile u_long pitch;
2918 volatile u_long *dma_prog;
2919 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
2920 u_int Bpp = pf_int->public.Bpp;
2921
2922 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2923 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2924 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2925 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2926
2927 OUTB(bktr, BKTR_OFORM, 0x00);
2928
2929 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2930 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2931 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2932 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2933
2934 /* disable gamma correction removal */
2935 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2936
2937 if (cols > 385) {
2938 OUTB(bktr, BKTR_E_VTC, 0);
2939 OUTB(bktr, BKTR_O_VTC, 0);
2940 } else {
2941 OUTB(bktr, BKTR_E_VTC, 1);
2942 OUTB(bktr, BKTR_O_VTC, 1);
2943 }
2944 bktr->capcontrol = 3 << 2 | 3;
2945
2946 dma_prog = (u_long *) bktr->dma_prog;
2947
2948 /* Construct Write */
2949
2950 if (bktr->video.addr) {
2951 target_buffer = (u_long) bktr->video.addr;
2952 pitch = bktr->video.width;
2953 }
2954 else {
2955 target_buffer = (u_long) vtophys(bktr->bigbuf);
2956 pitch = cols*Bpp;
2957 }
2958
2959 buffer = target_buffer;
2960
2961 /* contruct sync : for video packet format */
2962 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2963
2964 /* sync, mode indicator packed data */
2965 *dma_prog++ = htole32(0); /* NULL WORD */
2966 width = cols;
2967 for (i = 0; i < (rows/interlace); i++) {
2968 target = target_buffer;
2969 if (notclipped(bktr, i, width)) {
2970 split(bktr, (volatile u_long **) &dma_prog,
2971 bktr->y2 - bktr->y, OP_WRITE,
2972 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2973
2974 } else {
2975 while(getline(bktr, i)) {
2976 if (bktr->y != bktr->y2) {
2977 split(bktr, (volatile u_long **) &dma_prog,
2978 bktr->y2 - bktr->y, OP_WRITE,
2979 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2980 }
2981 if (bktr->yclip != bktr->yclip2) {
2982 split(bktr,(volatile u_long **) &dma_prog,
2983 bktr->yclip2 - bktr->yclip,
2984 OP_SKIP,
2985 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2986 }
2987 }
2988
2989 }
2990
2991 target_buffer += interlace * pitch;
2992
2993 }
2994
2995 switch (i_flag) {
2996 case 1:
2997 /* sync vre */
2998 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
2999 *dma_prog++ = htole32(0); /* NULL WORD */
3000
3001 *dma_prog++ = htole32(OP_JUMP);
3002 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3003 return;
3004
3005 case 2:
3006 /* sync vro */
3007 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
3008 *dma_prog++ = htole32(0); /* NULL WORD */
3009
3010 *dma_prog++ = htole32(OP_JUMP);
3011 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3012 return;
3013
3014 case 3:
3015 /* sync vro */
3016 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3017 *dma_prog++ = htole32(0); /* NULL WORD */
3018 *dma_prog++ = htole32(OP_JUMP);
3019 *dma_prog++ = htole32((u_long) vtophys(bktr->odd_dma_prog));
3020 break;
3021 }
3022
3023 if (interlace == 2) {
3024
3025 target_buffer = buffer + pitch;
3026
3027 dma_prog = (u_long *) bktr->odd_dma_prog;
3028
3029 /* sync vre IRQ bit */
3030 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3031 *dma_prog++ = htole32(0); /* NULL WORD */
3032 width = cols;
3033 for (i = 0; i < (rows/interlace); i++) {
3034 target = target_buffer;
3035 if (notclipped(bktr, i, width)) {
3036 split(bktr, (volatile u_long **) &dma_prog,
3037 bktr->y2 - bktr->y, OP_WRITE,
3038 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3039 } else {
3040 while(getline(bktr, i)) {
3041 if (bktr->y != bktr->y2) {
3042 split(bktr, (volatile u_long **) &dma_prog,
3043 bktr->y2 - bktr->y, OP_WRITE,
3044 Bpp, (volatile u_char **)(uintptr_t)&target,
3045 cols);
3046 }
3047 if (bktr->yclip != bktr->yclip2) {
3048 split(bktr, (volatile u_long **) &dma_prog,
3049 bktr->yclip2 - bktr->yclip, OP_SKIP,
3050 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3051 }
3052
3053 }
3054
3055 }
3056
3057 target_buffer += interlace * pitch;
3058
3059 }
3060 }
3061
3062 /* sync vre IRQ bit */
3063 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3064 *dma_prog++ = htole32(0); /* NULL WORD */
3065 *dma_prog++ = htole32(OP_JUMP);
3066 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3067 *dma_prog++ = htole32(0); /* NULL WORD */
3068 }
3069
3070
3071 /*
3072 *
3073 */
3074 static void
3075 yuvpack_prog(bktr_ptr_t bktr, char i_flag,
3076 int cols, int rows, int interlace)
3077 {
3078 int i;
3079 volatile unsigned int inst;
3080 volatile unsigned int inst3;
3081 volatile u_long target_buffer, buffer;
3082 volatile u_long *dma_prog;
3083 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3084 int b;
3085
3086 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3087
3088 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3089 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3090
3091 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3092 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3093
3094 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3095 bktr->capcontrol = 3 << 2 | 3;
3096
3097 dma_prog = (u_long *) bktr->dma_prog;
3098
3099 /* Construct Write */
3100
3101 /* write , sol, eol */
3102 inst = OP_WRITE | OP_SOL | (cols);
3103 /* write , sol, eol */
3104 inst3 = OP_WRITE | OP_EOL | (cols);
3105
3106 if (bktr->video.addr)
3107 target_buffer = (u_long) bktr->video.addr;
3108 else
3109 target_buffer = (u_long) vtophys(bktr->bigbuf);
3110
3111 buffer = target_buffer;
3112
3113 /* contruct sync : for video packet format */
3114 /* sync, mode indicator packed data */
3115 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3116 *dma_prog++ = htole32(0); /* NULL WORD */
3117
3118 b = cols;
3119
3120 for (i = 0; i < (rows/interlace); i++) {
3121 *dma_prog++ = htole32(inst);
3122 *dma_prog++ = htole32(target_buffer);
3123 *dma_prog++ = htole32(inst3);
3124 *dma_prog++ = htole32(target_buffer + b);
3125 target_buffer += interlace*(cols * 2);
3126 }
3127
3128 switch (i_flag) {
3129 case 1:
3130 /* sync vre */
3131 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
3132 *dma_prog++ = htole32(0); /* NULL WORD */
3133
3134 *dma_prog++ = htole32(OP_JUMP);
3135 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3136 return;
3137
3138 case 2:
3139 /* sync vro */
3140 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
3141 *dma_prog++ = htole32(0); /* NULL WORD */
3142 *dma_prog++ = htole32(OP_JUMP);
3143 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3144 return;
3145
3146 case 3:
3147 /* sync vro */
3148 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3149 *dma_prog++ = htole32(0); /* NULL WORD */
3150 *dma_prog++ = htole32(OP_JUMP);
3151 *dma_prog++ = htole32((u_long) vtophys(bktr->odd_dma_prog));
3152 break;
3153 }
3154
3155 if (interlace == 2) {
3156
3157 target_buffer = (u_long) buffer + cols*2;
3158
3159 dma_prog = (u_long *) bktr->odd_dma_prog;
3160
3161 /* sync vre */
3162 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3163 *dma_prog++ = htole32(0); /* NULL WORD */
3164
3165 for (i = 0; i < (rows/interlace); i++) {
3166 *dma_prog++ = htole32(inst);
3167 *dma_prog++ = htole32(target_buffer);
3168 *dma_prog++ = htole32(inst3);
3169 *dma_prog++ = htole32(target_buffer + b);
3170 target_buffer += interlace * (cols*2);
3171 }
3172 }
3173
3174 /* sync vro IRQ bit */
3175 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3176 *dma_prog++ = htole32(0); /* NULL WORD */
3177 *dma_prog++ = htole32(OP_JUMP);
3178 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3179
3180 *dma_prog++ = htole32(OP_JUMP);
3181 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3182 *dma_prog++ = htole32(0); /* NULL WORD */
3183 }
3184
3185
3186 /*
3187 *
3188 */
3189 static void
3190 yuv422_prog(bktr_ptr_t bktr, char i_flag,
3191 int cols, int rows, int interlace) {
3192
3193 int i;
3194 volatile unsigned int inst;
3195 volatile u_long target_buffer, t1, buffer;
3196 volatile u_long *dma_prog;
3197 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3198
3199 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3200
3201 dma_prog = (u_long *) bktr->dma_prog;
3202
3203 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3204
3205 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3206 OUTB(bktr, BKTR_OFORM, 0x00);
3207
3208 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3209 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3210
3211 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3212 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3213
3214 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3215 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3216 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3217 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3218
3219 /* disable gamma correction removal */
3220 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3221
3222 /* Construct Write */
3223 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3224 if (bktr->video.addr)
3225 target_buffer = (u_long) bktr->video.addr;
3226 else
3227 target_buffer = (u_long) vtophys(bktr->bigbuf);
3228
3229 buffer = target_buffer;
3230
3231 t1 = buffer;
3232
3233 /* contruct sync : for video packet format */
3234 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
3235 *dma_prog++ = htole32(0); /* NULL WORD */
3236
3237 for (i = 0; i < (rows/interlace); i++) {
3238 *dma_prog++ = htole32(inst);
3239 *dma_prog++ = htole32(cols/2 | cols/2 << 16);
3240 *dma_prog++ = htole32(target_buffer);
3241 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3242 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
3243 target_buffer += interlace*cols;
3244 }
3245
3246 switch (i_flag) {
3247 case 1:
3248 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/
3249 *dma_prog++ = htole32(0); /* NULL WORD */
3250
3251 *dma_prog++ = htole32(OP_JUMP);
3252 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3253 return;
3254
3255 case 2:
3256 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vre*/
3257 *dma_prog++ = htole32(0); /* NULL WORD */
3258
3259 *dma_prog++ = htole32(OP_JUMP);
3260 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3261 return;
3262
3263 case 3:
3264 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3265 *dma_prog++ = htole32(0); /* NULL WORD */
3266
3267 *dma_prog++ = htole32(OP_JUMP);
3268 *dma_prog++ = htole32((u_long) vtophys(bktr->odd_dma_prog));
3269 break;
3270 }
3271
3272 if (interlace == 2) {
3273
3274 dma_prog = (u_long *) bktr->odd_dma_prog;
3275
3276 target_buffer = (u_long) buffer + cols;
3277 t1 = buffer + cols/2;
3278 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3279 *dma_prog++ = htole32(0); /* NULL WORD */
3280
3281 for (i = 0; i < (rows/interlace); i++) {
3282 *dma_prog++ = htole32(inst);
3283 *dma_prog++ = htole32(cols/2 | cols/2 << 16);
3284 *dma_prog++ = htole32(target_buffer);
3285 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3286 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
3287 target_buffer += interlace*cols;
3288 }
3289 }
3290
3291 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3292 *dma_prog++ = htole32(0); /* NULL WORD */
3293 *dma_prog++ = htole32(OP_JUMP);
3294 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3295 *dma_prog++ = htole32(0); /* NULL WORD */
3296 }
3297
3298
3299 /*
3300 *
3301 */
3302 static void
3303 yuv12_prog(bktr_ptr_t bktr, char i_flag,
3304 int cols, int rows, int interlace) {
3305
3306 int i;
3307 volatile unsigned int inst;
3308 volatile unsigned int inst1;
3309 volatile u_long target_buffer, t1, buffer;
3310 volatile u_long *dma_prog;
3311 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3312
3313 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3314
3315 dma_prog = (u_long *) bktr->dma_prog;
3316
3317 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3318
3319 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3320 OUTB(bktr, BKTR_OFORM, 0x0);
3321
3322 /* Construct Write */
3323 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3324 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3325 if (bktr->video.addr)
3326 target_buffer = (u_long) bktr->video.addr;
3327 else
3328 target_buffer = (u_long) vtophys(bktr->bigbuf);
3329
3330 buffer = target_buffer;
3331 t1 = buffer;
3332
3333 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
3334 *dma_prog++ = htole32(0); /* NULL WORD */
3335
3336 for (i = 0; i < (rows/interlace)/2; i++) {
3337 *dma_prog++ = htole32(inst);
3338 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3339 *dma_prog++ = htole32(target_buffer);
3340 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3341 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
3342 target_buffer += interlace*cols;
3343 *dma_prog++ = htole32(inst1);
3344 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3345 *dma_prog++ = htole32(target_buffer);
3346 target_buffer += interlace*cols;
3347
3348 }
3349
3350 switch (i_flag) {
3351 case 1:
3352 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/
3353 *dma_prog++ = htole32(0); /* NULL WORD */
3354
3355 *dma_prog++ = htole32(OP_JUMP);
3356 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3357 return;
3358
3359 case 2:
3360 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vro*/
3361 *dma_prog++ = htole32(0); /* NULL WORD */
3362
3363 *dma_prog++ = htole32(OP_JUMP);
3364 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3365 return;
3366
3367 case 3:
3368 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3369 *dma_prog++ = htole32(0); /* NULL WORD */
3370 *dma_prog++ = htole32(OP_JUMP);
3371 *dma_prog++ = htole32((u_long) vtophys(bktr->odd_dma_prog));
3372 break;
3373 }
3374
3375 if (interlace == 2) {
3376
3377 dma_prog = (u_long *) bktr->odd_dma_prog;
3378
3379 target_buffer = (u_long) buffer + cols;
3380 t1 = buffer + cols/2;
3381 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3382 *dma_prog++ = htole32(0); /* NULL WORD */
3383
3384 for (i = 0; i < ((rows/interlace)/2); i++) {
3385 *dma_prog++ = htole32(inst);
3386 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3387 *dma_prog++ = htole32(target_buffer);
3388 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3389 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
3390 target_buffer += interlace*cols;
3391 *dma_prog++ = htole32(inst1);
3392 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3393 *dma_prog++ = htole32(target_buffer);
3394 target_buffer += interlace*cols;
3395
3396 }
3397
3398
3399 }
3400
3401 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3402 *dma_prog++ = htole32(0); /* NULL WORD */
3403 *dma_prog++ = htole32(OP_JUMP);
3404 *dma_prog++ = htole32((u_long) vtophys(bktr->dma_prog));
3405 *dma_prog++ = htole32(0); /* NULL WORD */
3406 }
3407
3408
3409
3410 /*
3411 *
3412 */
3413 static void
3414 build_dma_prog(bktr_ptr_t bktr, char i_flag)
3415 {
3416 int rows, cols, interlace;
3417 int tmp_int;
3418 unsigned int temp;
3419 const struct format_params *fp;
3420 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3421
3422
3423 fp = &format_params[bktr->format_params];
3424
3425 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3426
3427 /* disable FIFO & RISC, leave other bits alone */
3428 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3429
3430 /* set video parameters */
3431 if (bktr->capture_area_enabled)
3432 temp = ((quad_t) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3433 / fp->scaled_htotal / bktr->cols) - 4096;
3434 else
3435 temp = ((quad_t) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3436 / fp->scaled_htotal / bktr->cols) - 4096;
3437
3438 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3439 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3440 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3441 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3442 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3443
3444 /* horizontal active */
3445 temp = bktr->cols;
3446 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3447 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3448 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3449 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3450 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3451 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3452 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3453
3454 /* horizontal delay */
3455 if (bktr->capture_area_enabled)
3456 temp = ((fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3457 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3458 else
3459 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3460
3461 temp = temp & 0x3fe;
3462
3463 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3464 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3465 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3466 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3467 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3468 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3469 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3470
3471 /* vertical scale */
3472
3473 if (bktr->capture_area_enabled) {
3474 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3475 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3476 tmp_int = 65536 -
3477 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3478 else {
3479 tmp_int = 65536 -
3480 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3481 }
3482 } else {
3483 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3484 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3485 tmp_int = 65536 -
3486 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3487 else {
3488 tmp_int = 65536 -
3489 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3490 }
3491 }
3492
3493 tmp_int &= 0x1fff;
3494 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3495 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3496 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3497 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3498 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3499 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3500 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3501
3502
3503 /* vertical active */
3504 if (bktr->capture_area_enabled)
3505 temp = bktr->capture_area_y_size;
3506 else
3507 temp = fp->vactive;
3508 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3509 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3510 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3511 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3512 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3513 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3514 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3515
3516 /* vertical delay */
3517 if (bktr->capture_area_enabled)
3518 temp = fp->vdelay + (bktr->capture_area_y_offset);
3519 else
3520 temp = fp->vdelay;
3521 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3522 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3523 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3524 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3525 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3526 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3527 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3528
3529 /* end of video params */
3530
3531 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3532 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3533 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3534 } else {
3535 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3536 }
3537
3538 /* capture control */
3539 switch (i_flag) {
3540 case 1:
3541 bktr->bktr_cap_ctl =
3542 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3543 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3544 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3545 interlace = 1;
3546 break;
3547 case 2:
3548 bktr->bktr_cap_ctl =
3549 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3550 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3551 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3552 interlace = 1;
3553 break;
3554 default:
3555 bktr->bktr_cap_ctl =
3556 (BT848_CAP_CTL_DITH_FRAME |
3557 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3558 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3559 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3560 interlace = 2;
3561 break;
3562 }
3563
3564 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3565
3566 rows = bktr->rows;
3567 cols = bktr->cols;
3568
3569 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3570
3571 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3572 /* user, then use the rgb_vbi RISC program. */
3573 /* Otherwise, use the normal rgb RISC program */
3574 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3575 if ((bktr->vbiflags & VBI_OPEN)
3576 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3577 ||(bktr->format_params == BT848_IFORM_F_SECAM)) {
3578 bktr->bktr_cap_ctl |=
3579 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3580 bktr->vbiflags |= VBI_CAPTURE;
3581 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3582 return;
3583 } else {
3584 rgb_prog(bktr, i_flag, cols, rows, interlace);
3585 return;
3586 }
3587 }
3588
3589 if (pf_int->public.type == METEOR_PIXTYPE_YUV) {
3590 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3591 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3592 | pixfmt_swap_flags(bktr->pixfmt));
3593 return;
3594 }
3595
3596 if (pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED) {
3597 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3598 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3599 | pixfmt_swap_flags(bktr->pixfmt));
3600 return;
3601 }
3602
3603 if (pf_int->public.type == METEOR_PIXTYPE_YUV_12) {
3604 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3605 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3606 | pixfmt_swap_flags(bktr->pixfmt));
3607 return;
3608 }
3609 return;
3610 }
3611
3612
3613 /******************************************************************************
3614 * video & video capture specific routines:
3615 */
3616
3617
3618 /*
3619 *
3620 */
3621 static void
3622 start_capture(bktr_ptr_t bktr, unsigned type)
3623 {
3624 u_char i_flag;
3625 const struct format_params *fp;
3626
3627 fp = &format_params[bktr->format_params];
3628
3629 /* If requested, clear out capture buf first */
3630 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3631 bzero((caddr_t)bktr->bigbuf,
3632 (size_t)bktr->rows * bktr->cols * bktr->frames *
3633 pixfmt_table[bktr->pixfmt].public.Bpp);
3634 }
3635
3636 OUTB(bktr, BKTR_DSTATUS, 0);
3637 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3638
3639 bktr->flags |= type;
3640 bktr->flags &= ~METEOR_WANT_MASK;
3641 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3642 case METEOR_ONLY_EVEN_FIELDS:
3643 bktr->flags |= METEOR_WANT_EVEN;
3644 i_flag = 1;
3645 break;
3646 case METEOR_ONLY_ODD_FIELDS:
3647 bktr->flags |= METEOR_WANT_ODD;
3648 i_flag = 2;
3649 break;
3650 default:
3651 bktr->flags |= METEOR_WANT_MASK;
3652 i_flag = 3;
3653 break;
3654 }
3655
3656 /* TDEC is only valid for continuous captures */
3657 if (type == METEOR_SINGLE) {
3658 u_short fps_save = bktr->fps;
3659
3660 set_fps(bktr, fp->frame_rate);
3661 bktr->fps = fps_save;
3662 }
3663 else
3664 set_fps(bktr, bktr->fps);
3665
3666 if (bktr->dma_prog_loaded == FALSE) {
3667 build_dma_prog(bktr, i_flag);
3668 bktr->dma_prog_loaded = TRUE;
3669 }
3670
3671
3672 OUTL(bktr, BKTR_RISC_STRT_ADD, vtophys(bktr->dma_prog));
3673
3674 }
3675
3676
3677 /*
3678 *
3679 */
3680 static void
3681 set_fps(bktr_ptr_t bktr, u_short fps)
3682 {
3683 const struct format_params *fp;
3684 int i_flag;
3685
3686 fp = &format_params[bktr->format_params];
3687
3688 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3689 case METEOR_ONLY_EVEN_FIELDS:
3690 bktr->flags |= METEOR_WANT_EVEN;
3691 i_flag = 1;
3692 break;
3693 case METEOR_ONLY_ODD_FIELDS:
3694 bktr->flags |= METEOR_WANT_ODD;
3695 i_flag = 1;
3696 break;
3697 default:
3698 bktr->flags |= METEOR_WANT_MASK;
3699 i_flag = 2;
3700 break;
3701 }
3702
3703 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3704 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3705
3706 bktr->fps = fps;
3707 OUTB(bktr, BKTR_TDEC, 0);
3708
3709 if (fps < fp->frame_rate)
3710 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3711 else
3712 OUTB(bktr, BKTR_TDEC, 0);
3713 return;
3714
3715 }
3716
3717
3718
3719
3720
3721 /*
3722 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3723 * achieve the specified swapping.
3724 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3725 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3726 * and read R->L).
3727 * Note also that for 3Bpp, we may additionally need to do some creative
3728 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3729 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3730 * as one would expect.
3731 */
3732
3733 static u_int pixfmt_swap_flags(int pixfmt)
3734 {
3735 const struct meteor_pixfmt *pf = &pixfmt_table[pixfmt].public;
3736 u_int swapf = 0;
3737 int swap_bytes, swap_shorts;
3738
3739 #if BYTE_ORDER == LITTLE_ENDIAN
3740 swap_bytes = pf->swap_bytes;
3741 swap_shorts = pf->swap_shorts;
3742 #else
3743 swap_bytes = !pf->swap_bytes;
3744 swap_shorts = !pf->swap_shorts;
3745 #endif
3746 switch (pf->Bpp) {
3747 case 2 : swapf = (swap_bytes ? 0 : BSWAP);
3748 break;
3749
3750 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3751 break;
3752
3753 case 4 :
3754 swapf = swap_bytes ? 0 : BSWAP;
3755 swapf |= swap_shorts ? 0 : WSWAP;
3756 break;
3757 }
3758 return swapf;
3759 }
3760
3761
3762
3763 /*
3764 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3765 * our pixfmt_table indices.
3766 */
3767
3768 static int oformat_meteor_to_bt(u_long format)
3769 {
3770 int i;
3771 const struct meteor_pixfmt *pf1, *pf2;
3772
3773 /* Find format in compatibility table */
3774 for (i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++)
3775 if (meteor_pixfmt_table[i].meteor_format == format)
3776 break;
3777
3778 if (i >= METEOR_PIXFMT_TABLE_SIZE)
3779 return -1;
3780 pf1 = &meteor_pixfmt_table[i].public;
3781
3782 /* Match it with an entry in master pixel format table */
3783 for (i = 0; i < PIXFMT_TABLE_SIZE; i++) {
3784 pf2 = &pixfmt_table[i].public;
3785
3786 if ((pf1->type == pf2->type) &&
3787 (pf1->Bpp == pf2->Bpp) &&
3788 !memcmp(pf1->masks, pf2->masks, sizeof(pf1->masks)) &&
3789 (pf1->swap_bytes == pf2->swap_bytes) &&
3790 (pf1->swap_shorts == pf2->swap_shorts))
3791 break;
3792 }
3793 if (i >= PIXFMT_TABLE_SIZE)
3794 return -1;
3795
3796 return i;
3797 }
3798
3799 /******************************************************************************
3800 * i2c primitives:
3801 */
3802
3803 /* */
3804 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3805 #define I2CBITTIME_878 (1 << 7)
3806 #define I2C_READ 0x01
3807 #define I2C_COMMAND (I2CBITTIME | \
3808 BT848_DATA_CTL_I2CSCL | \
3809 BT848_DATA_CTL_I2CSDA)
3810
3811 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3812 BT848_DATA_CTL_I2CSCL | \
3813 BT848_DATA_CTL_I2CSDA)
3814
3815 /* Select between old i2c code and new iicbus / smbus code */
3816 #if defined(BKTR_USE_FREEBSD_SMBUS)
3817
3818 /*
3819 * The hardware interface is actually SMB commands
3820 */
3821 int
3822 i2cWrite(bktr_ptr_t bktr, int addr, int byte1, int byte2)
3823 {
3824 char cmd;
3825
3826 if (bktr->id == BROOKTREE_848 ||
3827 bktr->id == BROOKTREE_848A ||
3828 bktr->id == BROOKTREE_849A)
3829 cmd = I2C_COMMAND;
3830 else
3831 cmd = I2C_COMMAND_878;
3832
3833 if (byte2 != -1) {
3834 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3835 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3836 return (-1);
3837 } else {
3838 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3839 (char)(byte1 & 0xff)))
3840 return (-1);
3841 }
3842
3843 /* return OK */
3844 return(0);
3845 }
3846
3847 int
3848 i2cRead(bktr_ptr_t bktr, int addr)
3849 {
3850 char result;
3851 char cmd;
3852
3853 if (bktr->id == BROOKTREE_848 ||
3854 bktr->id == BROOKTREE_848A ||
3855 bktr->id == BROOKTREE_849A)
3856 cmd = I2C_COMMAND;
3857 else
3858 cmd = I2C_COMMAND_878;
3859
3860 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3861 return (-1);
3862
3863 return ((int)((unsigned char)result));
3864 }
3865
3866 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3867
3868 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3869 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3870 /* Therefore we need low level control of the i2c bus hardware */
3871
3872 /* Write to the MSP or DPL registers */
3873 void
3874 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3875 {
3876 unsigned char addr_l, addr_h, data_h, data_l;
3877
3878 addr_h = (addr >>8) & 0xff;
3879 addr_l = addr & 0xff;
3880 data_h = (data >>8) & 0xff;
3881 data_l = data & 0xff;
3882
3883 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3884
3885 iicbus_write_byte(IICBUS(bktr), dev, 0);
3886 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3887 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3888 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3889 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3890
3891 iicbus_stop(IICBUS(bktr));
3892
3893 return;
3894 }
3895
3896 /* Read from the MSP or DPL registers */
3897 unsigned int
3898 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3899 {
3900 unsigned int data;
3901 unsigned char addr_l, addr_h, dev_r;
3902 int read;
3903 u_char data_read[2];
3904
3905 addr_h = (addr >>8) & 0xff;
3906 addr_l = addr & 0xff;
3907 dev_r = dev+1;
3908
3909 /* XXX errors ignored */
3910 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3911
3912 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3913 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3914 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3915
3916 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3917 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3918 iicbus_stop(IICBUS(bktr));
3919
3920 data = (data_read[0]<<8) | data_read[1];
3921
3922 return (data);
3923 }
3924
3925 /* Reset the MSP or DPL chip */
3926 /* The user can block the reset (which is handy if you initialise the
3927 * MSP and/or DPL audio in another operating system first (eg in Windows)
3928 */
3929 void
3930 msp_dpl_reset(bktr_ptr_t bktr, int i2c_addr)
3931 {
3932
3933 #ifndef BKTR_NO_MSP_RESET
3934 /* put into reset mode */
3935 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3936 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3937 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3938 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3939 iicbus_stop(IICBUS(bktr));
3940
3941 /* put back to operational mode */
3942 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3943 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3944 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3945 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3946 iicbus_stop(IICBUS(bktr));
3947 #endif
3948 return;
3949 }
3950
3951 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3952 int read;
3953
3954 /* XXX errors ignored */
3955 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3956 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3957 iicbus_stop(IICBUS(bktr));
3958
3959 return;
3960 }
3961
3962 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3963
3964 /*
3965 * Program the i2c bus directly
3966 */
3967 int
3968 i2cWrite(bktr_ptr_t bktr, int addr, int byte1, int byte2)
3969 {
3970 u_long x;
3971 u_long data;
3972
3973 /* clear status bits */
3974 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3975
3976 /* build the command datum */
3977 if (bktr->id == BROOKTREE_848 ||
3978 bktr->id == BROOKTREE_848A ||
3979 bktr->id == BROOKTREE_849A) {
3980 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3981 } else {
3982 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3983 }
3984 if (byte2 != -1) {
3985 data |= ((byte2 & 0xff) << 8);
3986 data |= BT848_DATA_CTL_I2CW3B;
3987 }
3988
3989 /* write the address and data */
3990 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3991
3992 /* wait for completion */
3993 for (x = 0x7fffffff; x; --x) { /* safety valve */
3994 if (INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE)
3995 break;
3996 }
3997
3998 /* check for ACK */
3999 if (!x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK))
4000 return(-1);
4001
4002 /* return OK */
4003 return(0);
4004 }
4005
4006
4007 /*
4008 *
4009 */
4010 int
4011 i2cRead(bktr_ptr_t bktr, int addr)
4012 {
4013 u_long x;
4014
4015 /* clear status bits */
4016 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4017
4018 /* write the READ address */
4019 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
4020
4021 if (bktr->id == BROOKTREE_848 ||
4022 bktr->id == BROOKTREE_848A ||
4023 bktr->id == BROOKTREE_849A) {
4024 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
4025 } else {
4026 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
4027 }
4028
4029 /* wait for completion */
4030 for (x = 5000; x--; DELAY(1)) { /* 5msec, safety valve */
4031 if (INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE)
4032 break;
4033 }
4034
4035 /* check for ACK */
4036 if (!x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK))
4037 return(-1);
4038
4039 /* it was a read */
4040 return((INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff);
4041 }
4042
4043 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4044 /* bt848 automated i2c bus controller cannot handle */
4045 /* Therefore we need low level control of the i2c bus hardware */
4046 /* Idea for the following functions are from elsewhere in this driver and */
4047 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel (at) cs.tu-berlin.de> */
4048
4049 #define BITD 40
4050 static void i2c_start(bktr_ptr_t bktr) {
4051 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release data */
4052 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release clock */
4053 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* lower data */
4054 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock */
4055 }
4056
4057 static void i2c_stop(bktr_ptr_t bktr) {
4058 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock & data */
4059 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* release clock */
4060 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release data */
4061 }
4062
4063 static int i2c_write_byte(bktr_ptr_t bktr, unsigned char data) {
4064 int x;
4065 int status;
4066
4067 /* write out the byte */
4068 for (x = 7; x >= 0; --x) {
4069 if (data & (1<<x)) {
4070 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4071 DELAY(BITD); /* assert HI data */
4072 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4073 DELAY(BITD); /* strobe clock */
4074 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4075 DELAY(BITD); /* release clock */
4076 }
4077 else {
4078 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4079 DELAY(BITD); /* assert LO data */
4080 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4081 DELAY(BITD); /* strobe clock */
4082 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4083 DELAY(BITD); /* release clock */
4084 }
4085 }
4086
4087 /* look for an ACK */
4088 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* float data */
4089 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* strobe clock */
4090 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4091 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release clock */
4092
4093 return(status);
4094 }
4095
4096 static int i2c_read_byte(bktr_ptr_t bktr, unsigned char *data, int last) {
4097 int x;
4098 int bit;
4099 int byte = 0;
4100
4101 /* read in the byte */
4102 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4103 DELAY(BITD); /* float data */
4104 for (x = 7; x >= 0; --x) {
4105 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4106 DELAY(BITD); /* strobe clock */
4107 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4108 if (bit) byte |= (1<<x);
4109 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4110 DELAY(BITD); /* release clock */
4111 }
4112 /* After reading the byte, send an ACK */
4113 /* (unless that was the last byte, for which we send a NAK */
4114 if (last) { /* send NAK - same a writing a 1 */
4115 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4116 DELAY(BITD); /* set data bit */
4117 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4118 DELAY(BITD); /* strobe clock */
4119 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4120 DELAY(BITD); /* release clock */
4121 } else { /* send ACK - same as writing a 0 */
4122 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4123 DELAY(BITD); /* set data bit */
4124 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4125 DELAY(BITD); /* strobe clock */
4126 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4127 DELAY(BITD); /* release clock */
4128 }
4129
4130 *data=byte;
4131 return 0;
4132 }
4133 #undef BITD
4134
4135 /* Write to the MSP or DPL registers */
4136 void msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4137 unsigned int data) {
4138 unsigned int msp_w_addr = i2c_addr;
4139 unsigned char addr_l, addr_h, data_h, data_l;
4140 addr_h = (addr >>8) & 0xff;
4141 addr_l = addr & 0xff;
4142 data_h = (data >>8) & 0xff;
4143 data_l = data & 0xff;
4144
4145 i2c_start(bktr);
4146 i2c_write_byte(bktr, msp_w_addr);
4147 i2c_write_byte(bktr, dev);
4148 i2c_write_byte(bktr, addr_h);
4149 i2c_write_byte(bktr, addr_l);
4150 i2c_write_byte(bktr, data_h);
4151 i2c_write_byte(bktr, data_l);
4152 i2c_stop(bktr);
4153 }
4154
4155 /* Read from the MSP or DPL registers */
4156 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr) {
4157 unsigned int data;
4158 unsigned char addr_l, addr_h, data_1, data_2, dev_r;
4159 addr_h = (addr >>8) & 0xff;
4160 addr_l = addr & 0xff;
4161 dev_r = dev+1;
4162
4163 i2c_start(bktr);
4164 i2c_write_byte(bktr,i2c_addr);
4165 i2c_write_byte(bktr,dev_r);
4166 i2c_write_byte(bktr,addr_h);
4167 i2c_write_byte(bktr,addr_l);
4168
4169 i2c_start(bktr);
4170 i2c_write_byte(bktr,i2c_addr+1);
4171 i2c_read_byte(bktr,&data_1, 0);
4172 i2c_read_byte(bktr,&data_2, 1);
4173 i2c_stop(bktr);
4174 data = (data_1<<8) | data_2;
4175 return data;
4176 }
4177
4178 /* Reset the MSP or DPL chip */
4179 /* The user can block the reset (which is handy if you initialise the
4180 * MSP audio in another operating system first (eg in Windows)
4181 */
4182 void msp_dpl_reset(bktr_ptr_t bktr, int i2c_addr) {
4183
4184 #ifndef BKTR_NO_MSP_RESET
4185 /* put into reset mode */
4186 i2c_start(bktr);
4187 i2c_write_byte(bktr, i2c_addr);
4188 i2c_write_byte(bktr, 0x00);
4189 i2c_write_byte(bktr, 0x80);
4190 i2c_write_byte(bktr, 0x00);
4191 i2c_stop(bktr);
4192
4193 /* put back to operational mode */
4194 i2c_start(bktr);
4195 i2c_write_byte(bktr, i2c_addr);
4196 i2c_write_byte(bktr, 0x00);
4197 i2c_write_byte(bktr, 0x00);
4198 i2c_write_byte(bktr, 0x00);
4199 i2c_stop(bktr);
4200 #endif
4201 return;
4202
4203 }
4204
4205 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4206
4207 /* XXX errors ignored */
4208 i2c_start(bktr);
4209 i2c_write_byte(bktr,bktr->remote_control_addr);
4210 i2c_read_byte(bktr,&(remote->data[0]), 0);
4211 i2c_read_byte(bktr,&(remote->data[1]), 0);
4212 i2c_read_byte(bktr,&(remote->data[2]), 0);
4213 i2c_stop(bktr);
4214
4215 return;
4216 }
4217
4218 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4219
4220
4221 #if defined(I2C_SOFTWARE_PROBE)
4222
4223 /*
4224 * we are keeping this around for any parts that we need to probe
4225 * but that CANNOT be probed via an i2c read.
4226 * this is necessary because the hardware i2c mechanism
4227 * cannot be programmed for 1 byte writes.
4228 * currently there are no known i2c parts that we need to probe
4229 * and that cannot be safely read.
4230 */
4231 static int i2cProbe(bktr_ptr_t bktr, int addr);
4232 #define BITD 40
4233 #define EXTRA_START
4234
4235 /*
4236 * probe for an I2C device at addr.
4237 */
4238 static int
4239 i2cProbe(bktr_ptr_t bktr, int addr)
4240 {
4241 int x, status;
4242
4243 /* the START */
4244 #if defined(EXTRA_START)
4245 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release data */
4246 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release clock */
4247 #endif /* EXTRA_START */
4248 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* lower data */
4249 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock */
4250
4251 /* write addr */
4252 for (x = 7; x >= 0; --x) {
4253 if (addr & (1<<x)) {
4254 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4255 DELAY(BITD); /* assert HI data */
4256 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4257 DELAY(BITD); /* strobe clock */
4258 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4259 DELAY(BITD); /* release clock */
4260 }
4261 else {
4262 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4263 DELAY(BITD); /* assert LO data */
4264 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4265 DELAY(BITD); /* strobe clock */
4266 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4267 DELAY(BITD); /* release clock */
4268 }
4269 }
4270
4271 /* look for an ACK */
4272 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* float data */
4273 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* strobe clock */
4274 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4275 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release clock */
4276
4277 /* the STOP */
4278 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock & data */
4279 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* release clock */
4280 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release data */
4281
4282 return(status);
4283 }
4284 #undef EXTRA_START
4285 #undef BITD
4286
4287 #endif /* I2C_SOFTWARE_PROBE */
4288