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