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