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