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