Annotation of sys/dev/pci/bktr/bktr_core.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: bktr_core.c,v 1.24 2007/07/25 23:11:52 art 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 pograms.
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: #include <sys/stdint.h> /* uintptr_t */
104:
105: #include <dev/rndvar.h>
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 *
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
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%x\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_INITALIZED | 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_INITALIZED;
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
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
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: add_video_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: add_video_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: #else
657: if (bktr->vbi_select.si_selpid) {
658: #endif
659: selwakeup(&bktr->vbi_select);
660: }
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
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 = (struct proc *)0;
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
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
925: tuner_open( bktr_ptr_t bktr )
926: {
927: if ( !(bktr->tflags & TUNER_INITALIZED) ) /* 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
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
972: tuner_close( bktr_ptr_t bktr )
973: {
974: bktr->tflags &= ~TUNER_OPEN;
975:
976: return( 0 );
977: }
978:
979: int
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
992: video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
993: {
994: int status;
995: int 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 ((int) uio->uio_iov->iov_len < 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(BKTR_SLEEP, BKTRPRI, "captur", 0);
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
1047: vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
1048: {
1049: int 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(VBI_SLEEP, VBIPRI, "vbi", 0))) {
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 = (int)uio->uio_iov->iov_len;
1070:
1071: if (readsize > bktr->vbisize) readsize = bktr->vbisize;
1072:
1073: /* Check if we can read this number of bytes without having
1074: * to wrap around the circular buffer */
1075: if((bktr->vbistart + readsize) >= VBI_BUFFER_SIZE) {
1076: /* We need to wrap around */
1077:
1078: readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
1079: status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio);
1080: status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
1081: } else {
1082: /* We do not need to wrap around */
1083: status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
1084: }
1085:
1086: /* Update the number of bytes left to read */
1087: bktr->vbisize -= readsize;
1088:
1089: /* Update vbistart */
1090: bktr->vbistart += readsize;
1091: bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
1092:
1093: return( status );
1094:
1095: }
1096:
1097:
1098:
1099: /*
1100: * video ioctls
1101: */
1102: int
1103: video_ioctl( bktr_ptr_t bktr, int unit, ioctl_cmd_t cmd, caddr_t arg, struct proc* pr )
1104: {
1105: volatile u_char c_temp;
1106: unsigned int temp;
1107: unsigned int temp_iform;
1108: unsigned int error;
1109: struct meteor_geomet *geo;
1110: struct meteor_counts *counts;
1111: struct meteor_video *video;
1112: struct bktr_capture_area *cap_area;
1113: vaddr_t buf;
1114: int i;
1115: char char_temp;
1116:
1117: switch ( cmd ) {
1118:
1119: case BT848SCLIP: /* set clip region */
1120: bktr->max_clip_node = 0;
1121: memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1122:
1123: for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1124: if (bktr->clip_list[i].y_min == 0 &&
1125: bktr->clip_list[i].y_max == 0)
1126: break;
1127: }
1128: bktr->max_clip_node = i;
1129:
1130: /* make sure that the list contains a valid clip secquence */
1131: /* the clip rectangles should be sorted by x then by y as the
1132: second order sort key */
1133:
1134: /* clip rectangle list is terminated by y_min and y_max set to 0 */
1135:
1136: /* to disable clipping set y_min and y_max to 0 in the first
1137: clip rectangle . The first clip rectangle is clip_list[0].
1138: */
1139:
1140: if (bktr->max_clip_node == 0 &&
1141: (bktr->clip_list[0].y_min != 0 &&
1142: bktr->clip_list[0].y_max != 0)) {
1143: return EINVAL;
1144: }
1145:
1146: for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
1147: if (bktr->clip_list[i].y_min == 0 &&
1148: bktr->clip_list[i].y_max == 0) {
1149: break;
1150: }
1151: if ( bktr->clip_list[i+1].y_min != 0 &&
1152: bktr->clip_list[i+1].y_max != 0 &&
1153: bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
1154:
1155: bktr->max_clip_node = 0;
1156: return (EINVAL);
1157:
1158: }
1159:
1160: if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
1161: bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
1162: bktr->clip_list[i].x_min < 0 ||
1163: bktr->clip_list[i].x_max < 0 ||
1164: bktr->clip_list[i].y_min < 0 ||
1165: bktr->clip_list[i].y_max < 0 ) {
1166: bktr->max_clip_node = 0;
1167: return (EINVAL);
1168: }
1169: }
1170:
1171: bktr->dma_prog_loaded = FALSE;
1172:
1173: break;
1174:
1175: case METEORSTATUS: /* get Bt848 status */
1176: c_temp = INB(bktr, BKTR_DSTATUS);
1177: temp = 0;
1178: if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
1179: if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
1180: *(u_short *)arg = temp;
1181: break;
1182:
1183: case BT848SFMT: /* set input format */
1184: temp = *(unsigned int *)arg & BT848_IFORM_FORMAT;
1185: temp_iform = INB(bktr, BKTR_IFORM);
1186: temp_iform &= ~BT848_IFORM_FORMAT;
1187: temp_iform &= ~BT848_IFORM_XTSEL;
1188: OUTB(bktr, BKTR_IFORM, (temp_iform | temp | format_params[temp].iform_xtsel));
1189: switch( temp ) {
1190: case BT848_IFORM_F_AUTO:
1191: bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1192: METEOR_AUTOMODE;
1193: break;
1194:
1195: case BT848_IFORM_F_NTSCM:
1196: case BT848_IFORM_F_NTSCJ:
1197: bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1198: METEOR_NTSC;
1199: OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1200: OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1201: bktr->format_params = temp;
1202: break;
1203:
1204: case BT848_IFORM_F_PALBDGHI:
1205: case BT848_IFORM_F_PALN:
1206: case BT848_IFORM_F_SECAM:
1207: case BT848_IFORM_F_RSVD:
1208: case BT848_IFORM_F_PALM:
1209: bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1210: METEOR_PAL;
1211: OUTB(bktr, BKTR_ADELAY, format_params[temp].adelay);
1212: OUTB(bktr, BKTR_BDELAY, format_params[temp].bdelay);
1213: bktr->format_params = temp;
1214: break;
1215:
1216: }
1217: bktr->dma_prog_loaded = FALSE;
1218: break;
1219:
1220: case METEORSFMT: /* set input format */
1221: temp_iform = INB(bktr, BKTR_IFORM);
1222: temp_iform &= ~BT848_IFORM_FORMAT;
1223: temp_iform &= ~BT848_IFORM_XTSEL;
1224: switch(*(unsigned int *)arg & METEOR_FORM_MASK ) {
1225: case 0: /* default */
1226: case METEOR_FMT_NTSC:
1227: bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1228: METEOR_NTSC;
1229: OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_NTSCM |
1230: format_params[BT848_IFORM_F_NTSCM].iform_xtsel);
1231: OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_NTSCM].adelay);
1232: OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_NTSCM].bdelay);
1233: bktr->format_params = BT848_IFORM_F_NTSCM;
1234: break;
1235:
1236: case METEOR_FMT_PAL:
1237: bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1238: METEOR_PAL;
1239: OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_PALBDGHI |
1240: format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel);
1241: OUTB(bktr, BKTR_ADELAY, format_params[BT848_IFORM_F_PALBDGHI].adelay);
1242: OUTB(bktr, BKTR_BDELAY, format_params[BT848_IFORM_F_PALBDGHI].bdelay);
1243: bktr->format_params = BT848_IFORM_F_PALBDGHI;
1244: break;
1245:
1246: case METEOR_FMT_AUTOMODE:
1247: bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
1248: METEOR_AUTOMODE;
1249: OUTB(bktr, BKTR_IFORM, temp_iform | BT848_IFORM_F_AUTO |
1250: format_params[BT848_IFORM_F_AUTO].iform_xtsel);
1251: break;
1252:
1253: default:
1254: return( EINVAL );
1255: }
1256: bktr->dma_prog_loaded = FALSE;
1257: break;
1258:
1259: case METEORGFMT: /* get input format */
1260: *(u_int *)arg = bktr->flags & METEOR_FORM_MASK;
1261: break;
1262:
1263:
1264: case BT848GFMT: /* get input format */
1265: *(u_int *)arg = INB(bktr, BKTR_IFORM) & BT848_IFORM_FORMAT;
1266: break;
1267:
1268: case METEORSCOUNT: /* (re)set error counts */
1269: counts = (struct meteor_counts *) arg;
1270: bktr->fifo_errors = counts->fifo_errors;
1271: bktr->dma_errors = counts->dma_errors;
1272: bktr->frames_captured = counts->frames_captured;
1273: bktr->even_fields_captured = counts->even_fields_captured;
1274: bktr->odd_fields_captured = counts->odd_fields_captured;
1275: break;
1276:
1277: case METEORGCOUNT: /* get error counts */
1278: counts = (struct meteor_counts *) arg;
1279: counts->fifo_errors = bktr->fifo_errors;
1280: counts->dma_errors = bktr->dma_errors;
1281: counts->frames_captured = bktr->frames_captured;
1282: counts->even_fields_captured = bktr->even_fields_captured;
1283: counts->odd_fields_captured = bktr->odd_fields_captured;
1284: break;
1285:
1286: case METEORGVIDEO:
1287: video = (struct meteor_video *)arg;
1288: video->addr = bktr->video.addr;
1289: video->width = bktr->video.width;
1290: video->banksize = bktr->video.banksize;
1291: video->ramsize = bktr->video.ramsize;
1292: break;
1293:
1294: case METEORSVIDEO:
1295: video = (struct meteor_video *)arg;
1296: bktr->video.addr = video->addr;
1297: bktr->video.width = video->width;
1298: bktr->video.banksize = video->banksize;
1299: bktr->video.ramsize = video->ramsize;
1300: break;
1301:
1302: case METEORSFPS:
1303: set_fps(bktr, *(u_short *)arg);
1304: break;
1305:
1306: case METEORGFPS:
1307: *(u_short *)arg = bktr->fps;
1308: break;
1309:
1310: case METEORSHUE: /* set hue */
1311: OUTB(bktr, BKTR_HUE, (*(u_char *) arg) & 0xff);
1312: break;
1313:
1314: case METEORGHUE: /* get hue */
1315: *(u_char *)arg = INB(bktr, BKTR_HUE);
1316: break;
1317:
1318: case METEORSBRIG: /* set brightness */
1319: char_temp = ( *(u_char *)arg & 0xff) - 128;
1320: OUTB(bktr, BKTR_BRIGHT, char_temp);
1321:
1322: break;
1323:
1324: case METEORGBRIG: /* get brightness */
1325: *(u_char *)arg = INB(bktr, BKTR_BRIGHT) + 128;
1326: break;
1327:
1328: case METEORSCSAT: /* set chroma saturation */
1329: temp = (int)*(u_char *)arg;
1330:
1331: OUTB(bktr, BKTR_SAT_U_LO, (temp << 1) & 0xff);
1332: OUTB(bktr, BKTR_SAT_V_LO, (temp << 1) & 0xff);
1333: OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1334: & ~(BT848_E_CONTROL_SAT_U_MSB
1335: | BT848_E_CONTROL_SAT_V_MSB));
1336: OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1337: & ~(BT848_O_CONTROL_SAT_U_MSB |
1338: BT848_O_CONTROL_SAT_V_MSB));
1339:
1340: if ( temp & BIT_SEVEN_HIGH ) {
1341: OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL)
1342: | (BT848_E_CONTROL_SAT_U_MSB
1343: | BT848_E_CONTROL_SAT_V_MSB));
1344: OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL)
1345: | (BT848_O_CONTROL_SAT_U_MSB
1346: | BT848_O_CONTROL_SAT_V_MSB));
1347: }
1348: break;
1349:
1350: case METEORGCSAT: /* get chroma saturation */
1351: temp = (INB(bktr, BKTR_SAT_V_LO) >> 1) & 0xff;
1352: if ( INB(bktr, BKTR_E_CONTROL) & BT848_E_CONTROL_SAT_V_MSB )
1353: temp |= BIT_SEVEN_HIGH;
1354: *(u_char *)arg = (u_char)temp;
1355: break;
1356:
1357: case METEORSCONT: /* set contrast */
1358: temp = (int)*(u_char *)arg & 0xff;
1359: temp <<= 1;
1360: OUTB(bktr, BKTR_CONTRAST_LO, temp & 0xff);
1361: OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) & ~BT848_E_CONTROL_CON_MSB);
1362: OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) & ~BT848_O_CONTROL_CON_MSB);
1363: OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) |
1364: (((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB));
1365: OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) |
1366: (((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB));
1367: break;
1368:
1369: case METEORGCONT: /* get contrast */
1370: temp = (int)INB(bktr, BKTR_CONTRAST_LO) & 0xff;
1371: temp |= ((int)INB(bktr, BKTR_O_CONTROL) & 0x04) << 6;
1372: *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
1373: break;
1374:
1375: case BT848SCBUF: /* set Clear-Buffer-on-start flag */
1376: bktr->clr_on_start = (*(int *)arg != 0);
1377: break;
1378:
1379: case BT848GCBUF: /* get Clear-Buffer-on-start flag */
1380: *(int *)arg = (int) bktr->clr_on_start;
1381: break;
1382:
1383: case METEORSSIGNAL:
1384: if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
1385: return( EINVAL );
1386: break;
1387: }
1388: bktr->signal = *(int *) arg;
1389: bktr->proc = pr;
1390: break;
1391:
1392: case METEORGSIGNAL:
1393: *(int *)arg = bktr->signal;
1394: break;
1395:
1396: case METEORCAPTUR:
1397: temp = bktr->flags;
1398: switch (*(int *) arg) {
1399: case METEOR_CAP_SINGLE:
1400:
1401: if (bktr->bigbuf==0) /* no frame buffer allocated */
1402: return( ENOMEM );
1403: /* already capturing */
1404: if (temp & METEOR_CAP_MASK)
1405: return( EIO );
1406:
1407:
1408:
1409: start_capture(bktr, METEOR_SINGLE);
1410:
1411: /* wait for capture to complete */
1412: OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
1413: OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_ENABLED);
1414: OUTW(bktr, BKTR_GPIO_DMA_CTL, bktr->capcontrol);
1415:
1416: OUTL(bktr, BKTR_INT_MASK, BT848_INT_MYSTERYBIT |
1417: BT848_INT_RISCI |
1418: BT848_INT_VSYNC |
1419: BT848_INT_FMTCHG);
1420:
1421: OUTB(bktr, BKTR_CAP_CTL, bktr->bktr_cap_ctl);
1422: error = tsleep(BKTR_SLEEP, BKTRPRI, "captur", hz);
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 = btoc(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
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: temp = tv_channel( bktr, (int)*(unsigned int *)arg );
1736: if ( temp < 0 ) {
1737: temp_mute( bktr, FALSE );
1738: return( EINVAL );
1739: }
1740: *(unsigned int *)arg = temp;
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: temp = tv_freq( bktr, (int)*(unsigned int *)arg, TV_FREQUENCY);
1777: temp_mute( bktr, FALSE );
1778: if ( temp < 0 ) {
1779: temp_mute( bktr, FALSE );
1780: return( EINVAL );
1781: }
1782: *(unsigned int *)arg = temp;
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: temp = tv_freq( bktr, temp, FM_RADIO_FREQUENCY );
2057: temp_mute( bktr, FALSE );
2058: #ifdef BKTR_RADIO_DEBUG
2059: if(temp)
2060: printf("%s: tv_freq returned: %d\n", bktr_name(bktr), temp);
2061: #endif
2062: if ( temp < 0 )
2063: return( EINVAL );
2064: *(unsigned long *)arg = temp;
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
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: /* Unfortunatly 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
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 (1 << 28)
2365: #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2366: #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2367: #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2368:
2369: static bool_t
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
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
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
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
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
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 = 1 << 6 | 1 << 4 | 1 << 2 | 3;
2868: bktr->capcontrol = 3 << 2 | 3;
2869:
2870: dma_prog = (u_int *) bktr->dma_prog;
2871:
2872: /* Construct Write */
2873:
2874: /* write , sol, eol */
2875: inst = OP_WRITE | OP_SOL | (cols);
2876: /* write , sol, eol */
2877: inst3 = OP_WRITE | OP_EOL | (cols);
2878:
2879: if (bktr->video.addr)
2880: target_buffer = bktr->video.addr;
2881: else
2882: target_buffer = bktr->dm_mem->dm_segs->ds_addr;
2883:
2884: buffer = target_buffer;
2885:
2886: /* contruct sync : for video packet format */
2887: /* sync, mode indicator packed data */
2888: *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2889: *dma_prog++ = htole32(0); /* NULL WORD */
2890:
2891: b = cols;
2892:
2893: for (i = 0; i < (rows/interlace); i++) {
2894: *dma_prog++ = htole32(inst);
2895: *dma_prog++ = htole32(target_buffer);
2896: *dma_prog++ = htole32(inst3);
2897: *dma_prog++ = htole32(target_buffer + b);
2898: target_buffer += interlace*(cols * 2);
2899: }
2900:
2901: switch (i_flag) {
2902: case 1:
2903: /* sync vre */
2904: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
2905: *dma_prog++ = htole32(0); /* NULL WORD */
2906: *dma_prog++ = htole32(OP_JUMP);
2907: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2908: return;
2909:
2910: case 2:
2911: /* sync vro */
2912: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
2913: *dma_prog++ = htole32(0); /* NULL WORD */
2914: *dma_prog++ = htole32(OP_JUMP);
2915: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2916: return;
2917:
2918: case 3:
2919: /* sync vro */
2920: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2921: *dma_prog++ = htole32(0); /* NULL WORD */
2922: *dma_prog++ = htole32(OP_JUMP);
2923: *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
2924: break;
2925: }
2926:
2927: if (interlace == 2) {
2928:
2929: target_buffer = buffer + cols*2;
2930:
2931: dma_prog = (u_int * ) bktr->odd_dma_prog;
2932:
2933: /* sync vre */
2934: *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2935: *dma_prog++ = htole32(0); /* NULL WORD */
2936:
2937: for (i = 0; i < (rows/interlace) ; i++) {
2938: *dma_prog++ = htole32(inst);
2939: *dma_prog++ = htole32(target_buffer);
2940: *dma_prog++ = htole32(inst3);
2941: *dma_prog++ = htole32(target_buffer + b);
2942: target_buffer += interlace * ( cols*2);
2943: }
2944: }
2945:
2946: /* sync vro IRQ bit */
2947: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2948: *dma_prog++ = htole32(0); /* NULL WORD */
2949: *dma_prog++ = htole32(OP_JUMP);
2950: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2951:
2952: *dma_prog++ = htole32(OP_JUMP);
2953: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
2954: *dma_prog++ = htole32(0); /* NULL WORD */
2955: }
2956:
2957:
2958: /*
2959: *
2960: */
2961: static void
2962: yuv422_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2963: {
2964: int i;
2965: u_int inst;
2966: u_int target_buffer, t1, buffer;
2967: u_int *dma_prog;
2968: const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
2969:
2970: OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2971:
2972: dma_prog = (u_int *) bktr->dma_prog;
2973:
2974: bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
2975:
2976: OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2977: OUTB(bktr, BKTR_OFORM, 0x00);
2978:
2979: OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
2980: OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
2981:
2982: OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
2983: OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
2984:
2985: OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2986: OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2987: OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2988: OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2989:
2990: /* disable gamma correction removal */
2991: OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2992:
2993: /* Construct Write */
2994: inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
2995: if (bktr->video.addr)
2996: target_buffer = (u_int) bktr->video.addr;
2997: else
2998: target_buffer = bktr->dm_mem->dm_segs->ds_addr;
2999:
3000: buffer = target_buffer;
3001:
3002: t1 = buffer;
3003:
3004: /* contruct sync : for video packet format */
3005: /* sync, mode indicator packed data*/
3006: *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3007: *dma_prog++ = htole32(0); /* NULL WORD */
3008:
3009: for (i = 0; i < (rows/interlace ) ; i++) {
3010: *dma_prog++ = htole32(inst);
3011: *dma_prog++ = htole32(cols/2 | cols/2 << 16);
3012: *dma_prog++ = htole32(target_buffer);
3013: *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3014: *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) +
3015: i*cols/2 * interlace);
3016: target_buffer += interlace*cols;
3017: }
3018:
3019: switch (i_flag) {
3020: case 1:
3021: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/
3022: *dma_prog++ = htole32(0); /* NULL WORD */
3023:
3024: *dma_prog++ = htole32(OP_JUMP);
3025: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3026: return;
3027:
3028: case 2:
3029: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vre*/
3030: *dma_prog++ = htole32(0); /* NULL WORD */
3031:
3032: *dma_prog++ = htole32(OP_JUMP);
3033: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3034: return;
3035:
3036: case 3:
3037: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3038: *dma_prog++ = htole32(0); /* NULL WORD */
3039:
3040: *dma_prog++ = htole32(OP_JUMP);
3041: *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
3042: break;
3043: }
3044:
3045: if (interlace == 2) {
3046:
3047: dma_prog = (u_int * ) bktr->odd_dma_prog;
3048:
3049: target_buffer = (u_int) buffer + cols;
3050: t1 = buffer + cols/2;
3051: *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3052: *dma_prog++ = htole32(0); /* NULL WORD */
3053:
3054: for (i = 0; i < (rows/interlace ) ; i++) {
3055: *dma_prog++ = htole32(inst);
3056: *dma_prog++ = htole32(cols/2 | cols/2 << 16);
3057: *dma_prog++ = htole32(target_buffer);
3058: *dma_prog++ = htole32(t1 + (cols*rows) +
3059: i*cols/2 * interlace);
3060: *dma_prog++ = htole32(t1 + (cols*rows) +
3061: (cols*rows/2) + i*cols/2 * interlace);
3062: target_buffer += interlace*cols;
3063: }
3064: }
3065:
3066: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3067: *dma_prog++ = htole32(0); /* NULL WORD */
3068: *dma_prog++ = htole32(OP_JUMP);
3069: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3070: *dma_prog++ = htole32(0); /* NULL WORD */
3071: }
3072:
3073:
3074: /*
3075: *
3076: */
3077: static void
3078: yuv12_prog( bktr_ptr_t bktr, char i_flag,
3079: int cols, int rows, int interlace ){
3080:
3081: int i;
3082: u_int inst;
3083: u_int inst1;
3084: u_int target_buffer, t1, buffer;
3085: u_int *dma_prog;
3086: const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3087:
3088: OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3089:
3090: dma_prog = (u_int *) bktr->dma_prog;
3091:
3092: bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3093:
3094: OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3095: OUTB(bktr, BKTR_OFORM, 0x0);
3096:
3097: /* Construct Write */
3098: inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3099: inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3100: if (bktr->video.addr)
3101: target_buffer = (u_int) bktr->video.addr;
3102: else
3103: target_buffer = bktr->dm_mem->dm_segs->ds_addr;
3104:
3105: buffer = target_buffer;
3106: t1 = buffer;
3107:
3108: /* sync, mode indicator packed data*/
3109: *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3110: *dma_prog++ = htole32(0); /* NULL WORD */
3111:
3112: for (i = 0; i < (rows/interlace )/2 ; i++) {
3113: *dma_prog++ = htole32(inst);
3114: *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3115: *dma_prog++ = htole32(target_buffer);
3116: *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3117: *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) +
3118: i*cols/2 * interlace);
3119: target_buffer += interlace*cols;
3120: *dma_prog++ = htole32(inst1);
3121: *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3122: *dma_prog++ = htole32(target_buffer);
3123: target_buffer += interlace*cols;
3124:
3125: }
3126:
3127: switch (i_flag) {
3128: case 1:
3129: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/
3130: *dma_prog++ = htole32(0); /* NULL WORD */
3131:
3132: *dma_prog++ = htole32(OP_JUMP);
3133: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3134: return;
3135:
3136: case 2:
3137: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vro*/
3138: *dma_prog++ = htole32(0); /* NULL WORD */
3139:
3140: *dma_prog++ = htole32(OP_JUMP);
3141: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3142: return;
3143:
3144: case 3:
3145: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3146: *dma_prog++ = htole32(0); /* NULL WORD */
3147: *dma_prog++ = htole32(OP_JUMP);
3148: *dma_prog++ = htole32(bktr->dm_oprog->dm_segs->ds_addr);
3149: break;
3150: }
3151:
3152: if (interlace == 2) {
3153:
3154: dma_prog = (u_int *)bktr->odd_dma_prog;
3155:
3156: target_buffer = (u_int) buffer + cols;
3157: t1 = buffer + cols/2;
3158: *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3159: *dma_prog++ = htole32(0); /* NULL WORD */
3160:
3161: for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3162: *dma_prog++ = htole32(inst);
3163: *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3164: *dma_prog++ = htole32(target_buffer);
3165: *dma_prog++ = htole32(t1 + (cols*rows) +
3166: i*cols/2 * interlace);
3167: *dma_prog++ = htole32(t1 + (cols*rows) +
3168: (cols*rows/4) + i*cols/2 * interlace);
3169: target_buffer += interlace*cols;
3170: *dma_prog++ = htole32(inst1);
3171: *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3172: *dma_prog++ = htole32(target_buffer);
3173: target_buffer += interlace*cols;
3174: }
3175: }
3176:
3177: *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3178: *dma_prog++ = htole32(0); /* NULL WORD */
3179: *dma_prog++ = htole32(OP_JUMP);
3180: *dma_prog++ = htole32(bktr->dm_prog->dm_segs->ds_addr);
3181: *dma_prog++ = htole32(0); /* NULL WORD */
3182: }
3183:
3184:
3185: /*
3186: *
3187: */
3188: static void
3189: build_dma_prog( bktr_ptr_t bktr, char i_flag )
3190: {
3191: int rows, cols, interlace;
3192: int tmp_int;
3193: unsigned int temp;
3194: const struct format_params *fp;
3195: const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3196:
3197:
3198: fp = &format_params[bktr->format_params];
3199:
3200: OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3201:
3202: /* disable FIFO & RISC, leave other bits alone */
3203: OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3204:
3205: /* set video parameters */
3206: if (bktr->capture_area_enabled)
3207: temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3208: / fp->scaled_htotal / bktr->cols) - 4096;
3209: else
3210: temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3211: / fp->scaled_htotal / bktr->cols) - 4096;
3212:
3213: /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3214: OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3215: OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3216: OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3217: OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3218:
3219: /* horizontal active */
3220: temp = bktr->cols;
3221: /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3222: OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3223: OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3224: OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3225: OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3226: OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3227: OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3228:
3229: /* horizontal delay */
3230: if (bktr->capture_area_enabled)
3231: temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3232: * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3233: else
3234: temp = (fp->hdelay * bktr->cols) / fp->hactive;
3235:
3236: temp = temp & 0x3fe;
3237:
3238: /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3239: OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3240: OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3241: OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3242: OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3243: OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3244: OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3245:
3246: /* vertical scale */
3247:
3248: if (bktr->capture_area_enabled) {
3249: if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3250: bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3251: tmp_int = 65536 -
3252: (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3253: else {
3254: tmp_int = 65536 -
3255: (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3256: }
3257: } else {
3258: if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3259: bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3260: tmp_int = 65536 -
3261: (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3262: else {
3263: tmp_int = 65536 -
3264: (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3265: }
3266: }
3267:
3268: tmp_int &= 0x1fff;
3269: /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3270: OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3271: OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3272: OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3273: OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3274: OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3275: OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3276:
3277:
3278: /* vertical active */
3279: if (bktr->capture_area_enabled)
3280: temp = bktr->capture_area_y_size;
3281: else
3282: temp = fp->vactive;
3283: /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3284: OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3285: OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3286: OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3287: OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3288: OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3289: OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3290:
3291: /* vertical delay */
3292: if (bktr->capture_area_enabled)
3293: temp = fp->vdelay + (bktr->capture_area_y_offset);
3294: else
3295: temp = fp->vdelay;
3296: /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3297: OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3298: OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3299: OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3300: OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3301: OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3302: OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3303:
3304: /* end of video params */
3305:
3306: if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3307: && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3308: OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3309: } else {
3310: OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3311: }
3312:
3313: /* capture control */
3314: switch (i_flag) {
3315: case 1:
3316: bktr->bktr_cap_ctl =
3317: (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3318: OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3319: OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3320: interlace = 1;
3321: break;
3322: case 2:
3323: bktr->bktr_cap_ctl =
3324: (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3325: OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3326: OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3327: interlace = 1;
3328: break;
3329: default:
3330: bktr->bktr_cap_ctl =
3331: (BT848_CAP_CTL_DITH_FRAME |
3332: BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3333: OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3334: OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3335: interlace = 2;
3336: break;
3337: }
3338:
3339: OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
3340:
3341: rows = bktr->rows;
3342: cols = bktr->cols;
3343:
3344: bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3345:
3346: /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3347: /* user, then use the rgb_vbi RISC program. */
3348: /* Otherwise, use the normal rgb RISC program */
3349: if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3350: if ( (bktr->vbiflags & VBI_OPEN)
3351: ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3352: ||(bktr->format_params == BT848_IFORM_F_SECAM)
3353: ){
3354: bktr->bktr_cap_ctl |=
3355: BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3356: bktr->vbiflags |= VBI_CAPTURE;
3357: rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3358: return;
3359: } else {
3360: rgb_prog(bktr, i_flag, cols, rows, interlace);
3361: return;
3362: }
3363: }
3364:
3365: if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3366: yuv422_prog(bktr, i_flag, cols, rows, interlace);
3367: OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3368: | pixfmt_swap_flags( bktr->pixfmt ));
3369: return;
3370: }
3371:
3372: if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3373: yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3374: OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3375: | pixfmt_swap_flags( bktr->pixfmt ));
3376: return;
3377: }
3378:
3379: if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3380: yuv12_prog(bktr, i_flag, cols, rows, interlace);
3381: OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3382: | pixfmt_swap_flags( bktr->pixfmt ));
3383: return;
3384: }
3385: return;
3386: }
3387:
3388:
3389: /******************************************************************************
3390: * video & video capture specific routines:
3391: */
3392:
3393:
3394: /*
3395: *
3396: */
3397: static void
3398: start_capture( bktr_ptr_t bktr, unsigned type )
3399: {
3400: u_char i_flag;
3401: const struct format_params *fp;
3402:
3403: fp = &format_params[bktr->format_params];
3404:
3405: /* If requested, clear out capture buf first */
3406: if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3407: bzero((caddr_t)bktr->bigbuf,
3408: (size_t)bktr->rows * bktr->cols * bktr->frames *
3409: pixfmt_table[ bktr->pixfmt ].public.Bpp);
3410: }
3411:
3412: OUTB(bktr, BKTR_DSTATUS, 0);
3413: OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3414:
3415: bktr->flags |= type;
3416: bktr->flags &= ~METEOR_WANT_MASK;
3417: switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3418: case METEOR_ONLY_EVEN_FIELDS:
3419: bktr->flags |= METEOR_WANT_EVEN;
3420: i_flag = 1;
3421: break;
3422: case METEOR_ONLY_ODD_FIELDS:
3423: bktr->flags |= METEOR_WANT_ODD;
3424: i_flag = 2;
3425: break;
3426: default:
3427: bktr->flags |= METEOR_WANT_MASK;
3428: i_flag = 3;
3429: break;
3430: }
3431:
3432: /* TDEC is only valid for continuous captures */
3433: if ( type == METEOR_SINGLE ) {
3434: u_short fps_save = bktr->fps;
3435:
3436: set_fps(bktr, fp->frame_rate);
3437: bktr->fps = fps_save;
3438: }
3439: else
3440: set_fps(bktr, bktr->fps);
3441:
3442: if (bktr->dma_prog_loaded == FALSE) {
3443: build_dma_prog(bktr, i_flag);
3444: bktr->dma_prog_loaded = TRUE;
3445: }
3446:
3447:
3448: OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs->ds_addr);
3449: }
3450:
3451:
3452: /*
3453: *
3454: */
3455: static void
3456: set_fps( bktr_ptr_t bktr, u_short fps )
3457: {
3458: const struct format_params *fp;
3459: int i_flag;
3460:
3461: fp = &format_params[bktr->format_params];
3462:
3463: switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3464: case METEOR_ONLY_EVEN_FIELDS:
3465: bktr->flags |= METEOR_WANT_EVEN;
3466: i_flag = 1;
3467: break;
3468: case METEOR_ONLY_ODD_FIELDS:
3469: bktr->flags |= METEOR_WANT_ODD;
3470: i_flag = 1;
3471: break;
3472: default:
3473: bktr->flags |= METEOR_WANT_MASK;
3474: i_flag = 2;
3475: break;
3476: }
3477:
3478: OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3479: OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3480:
3481: bktr->fps = fps;
3482: OUTB(bktr, BKTR_TDEC, 0);
3483:
3484: if (fps < fp->frame_rate)
3485: OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3486: else
3487: OUTB(bktr, BKTR_TDEC, 0);
3488: return;
3489:
3490: }
3491:
3492:
3493:
3494:
3495:
3496: /*
3497: * Given a pixfmt index, compute the bt848 swap_flags necessary to
3498: * achieve the specified swapping.
3499: * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3500: * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3501: * and read R->L).
3502: * Note also that for 3Bpp, we may additionally need to do some creative
3503: * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3504: * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3505: * as one would expect.
3506: */
3507:
3508: static u_int 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: {
3547: int i;
3548: const struct meteor_pixfmt *pf1, *pf2;
3549:
3550: /* Find format in compatibility table */
3551: for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
3552: if ( meteor_pixfmt_table[i].meteor_format == format )
3553: break;
3554:
3555: if ( i >= METEOR_PIXFMT_TABLE_SIZE )
3556: return -1;
3557: pf1 = &meteor_pixfmt_table[i].public;
3558:
3559: /* Match it with an entry in master pixel format table */
3560: for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
3561: pf2 = &pixfmt_table[i].public;
3562:
3563: if (( pf1->type == pf2->type ) &&
3564: ( pf1->Bpp == pf2->Bpp ) &&
3565: !bcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
3566: ( pf1->swap_bytes == pf2->swap_bytes ) &&
3567: ( pf1->swap_shorts == pf2->swap_shorts ))
3568: break;
3569: }
3570: if ( i >= PIXFMT_TABLE_SIZE )
3571: return -1;
3572:
3573: return i;
3574: }
3575:
3576: /******************************************************************************
3577: * i2c primitives:
3578: */
3579:
3580: /* */
3581: #define I2CBITTIME (0x5) /* 5 * 0.48uS */
3582: #define I2CBITTIME_878 (0x8)
3583: #define I2C_READ 0x01
3584: #define I2C_COMMAND ((I2CBITTIME << 4) | \
3585: BT848_DATA_CTL_I2CSCL | \
3586: BT848_DATA_CTL_I2CSDA)
3587:
3588: #define I2C_COMMAND_878 ((I2CBITTIME_878 << 4) | \
3589: BT848_DATA_CTL_I2CSCL | \
3590: BT848_DATA_CTL_I2CSDA)
3591:
3592: /*
3593: * Program the i2c bus directly
3594: */
3595: int
3596: i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
3597: {
3598: u_int x;
3599: u_int data;
3600:
3601: /* clear status bits */
3602: OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3603:
3604: /* build the command datum */
3605: if (bktr->id == BROOKTREE_848 ||
3606: bktr->id == BROOKTREE_848A ||
3607: bktr->id == BROOKTREE_849A) {
3608: data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
3609: } else {
3610: data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
3611: }
3612: if ( byte2 != -1 ) {
3613: data |= ((byte2 & 0xff) << 8);
3614: data |= BT848_DATA_CTL_I2CW3B;
3615: }
3616:
3617: /* write the address and data */
3618: OUTL(bktr, BKTR_I2C_DATA_CTL, data);
3619:
3620: /* wait for completion */
3621: for ( x = 0x7fffffff; x; --x ) { /* safety valve */
3622: if ( INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE )
3623: break;
3624: }
3625:
3626: /* check for ACK */
3627: if ( !x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK) )
3628: return( -1 );
3629:
3630: /* return OK */
3631: return( 0 );
3632: }
3633:
3634:
3635: /*
3636: *
3637: */
3638: int
3639: i2cRead( bktr_ptr_t bktr, int addr )
3640: {
3641: u_int32_t x, stat;
3642:
3643: /* clear status bits */
3644: OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
3645:
3646: /* write the READ address */
3647: /* The Bt878 and Bt879 differed on the treatment of i2c commands */
3648:
3649: if (bktr->id == BROOKTREE_848 ||
3650: bktr->id == BROOKTREE_848A ||
3651: bktr->id == BROOKTREE_849A)
3652: OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
3653: else
3654: OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
3655:
3656: /* wait for completion */
3657: for (x = 5000; x--; DELAY(1)) /* 5 msec, safety valve */
3658: if ((stat = INL(bktr, BKTR_INT_STAT)) & BT848_INT_I2CDONE)
3659: break;
3660:
3661: /* check for ACK */
3662: if ((stat & (I2C_BITS)) != (I2C_BITS))
3663: return (-1);
3664:
3665: /* it was a read */
3666: x = INL(bktr, BKTR_I2C_DATA_CTL);
3667: return ((x >> 8) & 0xff);
3668: }
3669:
3670: /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
3671: /* bt848 automated i2c bus controller cannot handle */
3672: /* Therefore we need low level control of the i2c bus hardware */
3673: /* Idea for the following functions are from elsewhere in this driver and */
3674: /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
3675:
3676: #define BITD 40
3677: static void i2c_start( bktr_ptr_t bktr) {
3678: OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3679: OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3680: OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3681: OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3682: }
3683:
3684: static void i2c_stop( bktr_ptr_t bktr) {
3685: OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3686: OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3687: OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3688: }
3689:
3690: static int i2c_write_byte( bktr_ptr_t bktr, unsigned char data) {
3691: int x;
3692: int status;
3693:
3694: /* write out the byte */
3695: for ( x = 7; x >= 0; --x ) {
3696: if ( data & (1<<x) ) {
3697: OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3698: DELAY( BITD ); /* assert HI data */
3699: OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3700: DELAY( BITD ); /* strobe clock */
3701: OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3702: DELAY( BITD ); /* release clock */
3703: }
3704: else {
3705: OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3706: DELAY( BITD ); /* assert LO data */
3707: OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3708: DELAY( BITD ); /* strobe clock */
3709: OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3710: DELAY( BITD ); /* release clock */
3711: }
3712: }
3713:
3714: /* look for an ACK */
3715: OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3716: OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3717: status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3718: OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3719:
3720: return( status );
3721: }
3722:
3723: static int i2c_read_byte( bktr_ptr_t bktr, unsigned char *data, int last ) {
3724: int x;
3725: int bit;
3726: int byte = 0;
3727:
3728: /* read in the byte */
3729: OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3730: DELAY( BITD ); /* float data */
3731: for ( x = 7; x >= 0; --x ) {
3732: OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3733: DELAY( BITD ); /* strobe clock */
3734: bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
3735: if ( bit ) byte |= (1<<x);
3736: OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3737: DELAY( BITD ); /* release clock */
3738: }
3739: /* After reading the byte, send an ACK */
3740: /* (unless that was the last byte, for which we send a NAK */
3741: if (last) { /* send NAK - same a writing a 1 */
3742: OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3743: DELAY( BITD ); /* set data bit */
3744: OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3745: DELAY( BITD ); /* strobe clock */
3746: OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3747: DELAY( BITD ); /* release clock */
3748: } else { /* send ACK - same as writing a 0 */
3749: OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3750: DELAY( BITD ); /* set data bit */
3751: OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3752: DELAY( BITD ); /* strobe clock */
3753: OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3754: DELAY( BITD ); /* release clock */
3755: }
3756:
3757: *data=byte;
3758: return 0;
3759: }
3760: #undef BITD
3761:
3762: /* Write to the MSP or DPL registers */
3763: void msp_dpl_write( bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
3764: unsigned int data){
3765: unsigned int msp_w_addr = i2c_addr;
3766: unsigned char addr_l, addr_h, data_h, data_l ;
3767: addr_h = (addr >>8) & 0xff;
3768: addr_l = addr & 0xff;
3769: data_h = (data >>8) & 0xff;
3770: data_l = data & 0xff;
3771:
3772: i2c_start(bktr);
3773: i2c_write_byte(bktr, msp_w_addr);
3774: i2c_write_byte(bktr, dev);
3775: i2c_write_byte(bktr, addr_h);
3776: i2c_write_byte(bktr, addr_l);
3777: i2c_write_byte(bktr, data_h);
3778: i2c_write_byte(bktr, data_l);
3779: i2c_stop(bktr);
3780: }
3781:
3782: /* Read from the MSP or DPL registers */
3783: unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr){
3784: unsigned int data;
3785: unsigned char addr_l, addr_h, data_1, data_2, dev_r ;
3786: addr_h = (addr >>8) & 0xff;
3787: addr_l = addr & 0xff;
3788: dev_r = dev+1;
3789:
3790: i2c_start(bktr);
3791: i2c_write_byte(bktr,i2c_addr);
3792: i2c_write_byte(bktr,dev_r);
3793: i2c_write_byte(bktr,addr_h);
3794: i2c_write_byte(bktr,addr_l);
3795:
3796: i2c_start(bktr);
3797: i2c_write_byte(bktr,i2c_addr+1);
3798: i2c_read_byte(bktr,&data_1, 0);
3799: i2c_read_byte(bktr,&data_2, 1);
3800: i2c_stop(bktr);
3801: data = (data_1<<8) | data_2;
3802: return data;
3803: }
3804:
3805: /* Reset the MSP or DPL chip */
3806: /* The user can block the reset (which is handy if you initialise the
3807: * MSP audio in another operating system first (eg in Windows)
3808: */
3809: void msp_dpl_reset( bktr_ptr_t bktr, int i2c_addr ) {
3810:
3811: #ifndef BKTR_NO_MSP_RESET
3812: /* put into reset mode */
3813: i2c_start(bktr);
3814: i2c_write_byte(bktr, i2c_addr);
3815: i2c_write_byte(bktr, 0x00);
3816: i2c_write_byte(bktr, 0x80);
3817: i2c_write_byte(bktr, 0x00);
3818: i2c_stop(bktr);
3819:
3820: /* put back to operational mode */
3821: i2c_start(bktr);
3822: i2c_write_byte(bktr, i2c_addr);
3823: i2c_write_byte(bktr, 0x00);
3824: i2c_write_byte(bktr, 0x00);
3825: i2c_write_byte(bktr, 0x00);
3826: i2c_stop(bktr);
3827: #endif
3828: return;
3829:
3830: }
3831:
3832: static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3833:
3834: /* XXX errors ignored */
3835: i2c_start(bktr);
3836: i2c_write_byte(bktr,bktr->remote_control_addr);
3837: i2c_read_byte(bktr,&(remote->data[0]), 0);
3838: i2c_read_byte(bktr,&(remote->data[1]), 0);
3839: i2c_read_byte(bktr,&(remote->data[2]), 0);
3840: i2c_stop(bktr);
3841:
3842: return;
3843: }
3844:
3845: #if defined( I2C_SOFTWARE_PROBE )
3846:
3847: /*
3848: * we are keeping this around for any parts that we need to probe
3849: * but that CANNOT be probed via an i2c read.
3850: * this is necessary because the hardware i2c mechanism
3851: * cannot be programmed for 1 byte writes.
3852: * currently there are no known i2c parts that we need to probe
3853: * and that cannot be safely read.
3854: */
3855: static int i2cProbe( bktr_ptr_t bktr, int addr );
3856: #define BITD 40
3857: #define EXTRA_START
3858:
3859: /*
3860: * probe for an I2C device at addr.
3861: */
3862: static int
3863: i2cProbe( bktr_ptr_t bktr, int addr )
3864: {
3865: int x, status;
3866:
3867: /* the START */
3868: #if defined( EXTRA_START )
3869: OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release data */
3870: OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release clock */
3871: #endif /* EXTRA_START */
3872: OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* lower data */
3873: OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock */
3874:
3875: /* write addr */
3876: for ( x = 7; x >= 0; --x ) {
3877: if ( addr & (1<<x) ) {
3878: OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3879: DELAY( BITD ); /* assert HI data */
3880: OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
3881: DELAY( BITD ); /* strobe clock */
3882: OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
3883: DELAY( BITD ); /* release clock */
3884: }
3885: else {
3886: OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3887: DELAY( BITD ); /* assert LO data */
3888: OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
3889: DELAY( BITD ); /* strobe clock */
3890: OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
3891: DELAY( BITD ); /* release clock */
3892: }
3893: }
3894:
3895: /* look for an ACK */
3896: OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* float data */
3897: OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* strobe clock */
3898: status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
3899: OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY( BITD ); /* release clock */
3900:
3901: /* the STOP */
3902: OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY( BITD ); /* lower clock & data */
3903: OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY( BITD ); /* release clock */
3904: OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY( BITD ); /* release data */
3905:
3906: return( status );
3907: }
3908: #undef EXTRA_START
3909: #undef BITD
3910:
3911: #endif /* I2C_SOFTWARE_PROBE */
CVSweb