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