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