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