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