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