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