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