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