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