1 /* $SourceForge: bktr_core.c,v 1.6 2003/03/11 23:11:22 thomasklausner Exp $ */
2
3 /* $NetBSD: bktr_core.c,v 1.59 2021/12/19 22:03:41 andvar 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 programs.
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.59 2021/12/19 22:03:41 andvar 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 video 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 sequence */
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 interrupt 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 /* Unfortunately 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 /* FALLTHROUGH */
2443 default:
2444 return(EINVAL);
2445 }
2446 break;
2447
2448 case METEORGINPUT: /* get input device */
2449 *(u_int *)arg = bktr->flags & METEOR_DEV_MASK;
2450 break;
2451
2452 case METEORSACTPIXFMT:
2453 if ((*(int *)arg < 0) ||
2454 (*(int *)arg >= PIXFMT_TABLE_SIZE))
2455 return(EINVAL);
2456
2457 bktr->pixfmt = *(int *)arg;
2458 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
2459 | pixfmt_swap_flags(bktr->pixfmt));
2460 bktr->pixfmt_compat = FALSE;
2461 break;
2462
2463 case METEORGACTPIXFMT:
2464 *(int *)arg = bktr->pixfmt;
2465 break;
2466
2467 case METEORGSUPPIXFMT :
2468 pf_pub = (struct meteor_pixfmt *)arg;
2469 pixfmt = pf_pub->index;
2470
2471 if ((pixfmt < 0) || (pixfmt >= PIXFMT_TABLE_SIZE))
2472 return(EINVAL);
2473
2474 memcpy(pf_pub, &pixfmt_table[pixfmt].public,
2475 sizeof(*pf_pub));
2476
2477 /* Patch in our format index */
2478 pf_pub->index = pixfmt;
2479 break;
2480
2481 #if defined(STATUS_SUM)
2482 case BT848_GSTATUS: /* reap status */
2483 {
2484 DECLARE_INTR_MASK(s);
2485 DISABLE_INTR(s);
2486 temp = status_sum;
2487 status_sum = 0;
2488 ENABLE_INTR(s);
2489 *(u_int*)arg = temp;
2490 break;
2491 }
2492 #endif /* STATUS_SUM */
2493
2494 default:
2495 return(ENOTTY);
2496 }
2497
2498 return(0);
2499 }
2500
2501
2502
2503
2504 /******************************************************************************
2505 * bt848 RISC programming routines:
2506 */
2507
2508
2509 /*
2510 *
2511 */
2512 #ifdef BT848_DEBUG
2513 static int
2514 dump_bt848(bktr_ptr_t bktr)
2515 {
2516 int r[60]={
2517 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
2518 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
2519 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
2520 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
2521 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
2522 0, 0, 0, 0
2523 };
2524 int i;
2525
2526 for (i = 0; i < 40; i+=4) {
2527 printf("%s: Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
2528 bktr_name(bktr),
2529 r[i], INL(bktr, r[i]),
2530 r[i+1], INL(bktr, r[i+1]),
2531 r[i+2], INL(bktr, r[i+2]),
2532 r[i+3], INL(bktr, r[i+3]));
2533 }
2534
2535 printf("%s: INT STAT %x \n", bktr_name(bktr),
2536 INL(bktr, BKTR_INT_STAT));
2537 printf("%s: Reg INT_MASK %x \n", bktr_name(bktr),
2538 INL(bktr, BKTR_INT_MASK));
2539 printf("%s: Reg GPIO_DMA_CTL %x \n", bktr_name(bktr),
2540 INW(bktr, BKTR_GPIO_DMA_CTL));
2541
2542 return(0);
2543 }
2544
2545 #endif
2546
2547 /*
2548 * build write instruction
2549 */
2550 #define BKTR_FM1 0x6 /* packed data to follow */
2551 #define BKTR_FM3 0xe /* planar data to follow */
2552 #define BKTR_VRE 0x4 /* Marks the end of the even field */
2553 #define BKTR_VRO 0xC /* Marks the end of the odd field */
2554 #define BKTR_PXV 0x0 /* valid word (never used) */
2555 #define BKTR_EOL 0x1 /* last dword, 4 bytes */
2556 #define BKTR_SOL 0x2 /* first dword */
2557
2558 #define OP_WRITE (0x1 << 28)
2559 #define OP_SKIP (0x2 << 28)
2560 #define OP_WRITEC (0x5 << 28)
2561 #define OP_JUMP (0x7 << 28)
2562 #define OP_SYNC (0x8 << 28)
2563 #define OP_WRITE123 (0x9 << 28)
2564 #define OP_WRITES123 (0xb << 28)
2565 #define OP_SOL (1 << 27) /* first instr for scanline */
2566 #define OP_EOL (1 << 26)
2567
2568 #define BKTR_RESYNC (1 << 15)
2569 #define BKTR_GEN_IRQ (1 << 24)
2570
2571 /*
2572 * The RISC status bits can be set/cleared in the RISC programs
2573 * and tested in the Interrupt Handler
2574 */
2575 #define BKTR_SET_RISC_STATUS_BIT0 (1 << 16)
2576 #define BKTR_SET_RISC_STATUS_BIT1 (1 << 17)
2577 #define BKTR_SET_RISC_STATUS_BIT2 (1 << 18)
2578 #define BKTR_SET_RISC_STATUS_BIT3 (1 << 19)
2579
2580 #define BKTR_CLEAR_RISC_STATUS_BIT0 (1 << 20)
2581 #define BKTR_CLEAR_RISC_STATUS_BIT1 (1 << 21)
2582 #define BKTR_CLEAR_RISC_STATUS_BIT2 (1 << 22)
2583 #define BKTR_CLEAR_RISC_STATUS_BIT3 (1 << 23)
2584
2585 #define BKTR_TEST_RISC_STATUS_BIT0 (1 << 28)
2586 #define BKTR_TEST_RISC_STATUS_BIT1 (1 << 29)
2587 #define BKTR_TEST_RISC_STATUS_BIT2 (1 << 30)
2588 #define BKTR_TEST_RISC_STATUS_BIT3 (1 << 31)
2589
2590 static bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
2591 int i;
2592 bktr_clip_t * clip_node;
2593 bktr->clip_start = -1;
2594 bktr->last_y = 0;
2595 bktr->y = 0;
2596 bktr->y2 = width;
2597 bktr->line_length = width;
2598 bktr->yclip = -1;
2599 bktr->yclip2 = -1;
2600 bktr->current_col = 0;
2601
2602 if (bktr->max_clip_node == 0) return TRUE;
2603 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
2604
2605
2606 for (i = 0; i < bktr->max_clip_node; i++) {
2607 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2608 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2609 bktr->clip_start = i;
2610 return FALSE;
2611 }
2612 }
2613
2614 return TRUE;
2615 }
2616
2617 static bool_t getline(bktr_reg_t *bktr, int x) {
2618 int i, j;
2619 bktr_clip_t * clip_node;
2620
2621 if (bktr->line_length == 0 ||
2622 bktr->current_col >= bktr->line_length) return FALSE;
2623
2624 bktr->y = uimin(bktr->last_y, bktr->line_length);
2625 bktr->y2 = bktr->line_length;
2626
2627 bktr->yclip = bktr->yclip2 = -1;
2628 for (i = bktr->clip_start; i < bktr->max_clip_node; i++) {
2629 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
2630 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2631 if (bktr->last_y <= clip_node->y_min) {
2632 bktr->y = uimin(bktr->last_y, bktr->line_length);
2633 bktr->y2 = uimin(clip_node->y_min, bktr->line_length);
2634 bktr->yclip = uimin(clip_node->y_min, bktr->line_length);
2635 bktr->yclip2 = uimin(clip_node->y_max, bktr->line_length);
2636 bktr->last_y = bktr->yclip2;
2637 bktr->clip_start = i;
2638
2639 for (j = i+1; j < bktr->max_clip_node; j++) {
2640 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
2641 if (x >= clip_node->x_min && x <= clip_node->x_max) {
2642 if (bktr->last_y >= clip_node->y_min) {
2643 bktr->yclip2 = uimin(clip_node->y_max, bktr->line_length);
2644 bktr->last_y = bktr->yclip2;
2645 bktr->clip_start = j;
2646 }
2647 } else break;
2648 }
2649 return TRUE;
2650 }
2651 }
2652 }
2653
2654 if (bktr->current_col <= bktr->line_length) {
2655 bktr->current_col = bktr->line_length;
2656 return TRUE;
2657 }
2658 return FALSE;
2659 }
2660
2661 static bool_t split(bktr_reg_t * bktr, volatile u_int **dma_prog, int width ,
2662 u_int operation, int pixel_width,
2663 volatile u_char ** target_buffer, int cols) {
2664
2665 u_int flag, flag2;
2666 const struct meteor_pixfmt *pf = &pixfmt_table[bktr->pixfmt].public;
2667 u_int skip, start_skip;
2668
2669 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
2670 /* to the 1st byte in the mem dword containing our start addr. */
2671 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
2672 /* must be Blue. */
2673 start_skip = 0;
2674 if ((pf->type == METEOR_PIXTYPE_RGB) && (pf->Bpp == 3))
2675 switch (((uintptr_t) (volatile void *) *target_buffer) % 4) {
2676 case 2 : start_skip = 4; break;
2677 case 1 : start_skip = 8; break;
2678 }
2679
2680 if ((width * pixel_width) < DMA_BT848_SPLIT) {
2681 if (width == cols) {
2682 flag = OP_SOL | OP_EOL;
2683 } else if (bktr->current_col == 0) {
2684 flag = OP_SOL;
2685 } else if (bktr->current_col == cols) {
2686 flag = OP_EOL;
2687 } else flag = 0;
2688
2689 skip = 0;
2690 if ((flag & OP_SOL) && (start_skip > 0)) {
2691 *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2692 flag &= ~OP_SOL;
2693 skip = start_skip;
2694 }
2695
2696 *(*dma_prog)++ = htole32(operation | flag |
2697 (width * pixel_width - skip));
2698 if (operation != OP_SKIP)
2699 *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
2700
2701 *target_buffer += width * pixel_width;
2702 bktr->current_col += width;
2703
2704 } else {
2705
2706 if (bktr->current_col == 0 && width == cols) {
2707 flag = OP_SOL;
2708 flag2 = OP_EOL;
2709 } else if (bktr->current_col == 0) {
2710 flag = OP_SOL;
2711 flag2 = 0;
2712 } else if (bktr->current_col >= cols) {
2713 flag = 0;
2714 flag2 = OP_EOL;
2715 } else {
2716 flag = 0;
2717 flag2 = 0;
2718 }
2719
2720 skip = 0;
2721 if ((flag & OP_SOL) && (start_skip > 0)) {
2722 *(*dma_prog)++ = htole32(OP_SKIP | OP_SOL | start_skip);
2723 flag &= ~OP_SOL;
2724 skip = start_skip;
2725 }
2726
2727 *(*dma_prog)++ = htole32(operation | flag |
2728 (width * pixel_width / 2 - skip));
2729 if (operation != OP_SKIP)
2730 *(*dma_prog)++ = htole32((uintptr_t) (volatile void *) *target_buffer);
2731 *target_buffer += (width * pixel_width / 2);
2732
2733 if (operation == OP_WRITE)
2734 operation = OP_WRITEC;
2735 *(*dma_prog)++ = htole32(operation | flag2 |
2736 (width * pixel_width / 2));
2737 *target_buffer += (width * pixel_width / 2);
2738 bktr->current_col += width;
2739
2740 }
2741 return TRUE;
2742 }
2743
2744
2745 /*
2746 * Generate the RISC instructions to capture both VBI and video images
2747 */
2748 static void
2749 rgb_vbi_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2750 {
2751 int i;
2752 volatile u_int target_buffer, buffer, target,width;
2753 volatile u_int pitch;
2754 volatile u_int *dma_prog; /* DMA prog is an array of
2755 32 bit RISC instructions */
2756 volatile bus_addr_t loop_point;
2757 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
2758 u_int Bpp = pf_int->public.Bpp;
2759 unsigned int vbisamples; /* VBI samples per line */
2760 unsigned int vbilines; /* VBI lines per field */
2761 unsigned int num_dwords; /* DWORDS per line */
2762
2763 vbisamples = format_params[bktr->format_params].vbi_num_samples;
2764 vbilines = format_params[bktr->format_params].vbi_num_lines;
2765 num_dwords = vbisamples/4;
2766
2767 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2768 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2769 OUTB(bktr, BKTR_VBI_PACK_SIZE, ((num_dwords)) & 0xff);
2770 OUTB(bktr, BKTR_VBI_PACK_DEL, ((num_dwords)>> 8) & 0x01); /* no hdelay */
2771 /* no ext frame */
2772
2773 OUTB(bktr, BKTR_OFORM, 0x00);
2774
2775 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2776 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2777 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2778 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2779
2780 /* disable gamma correction removal */
2781 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2782
2783 if (cols > 385) {
2784 OUTB(bktr, BKTR_E_VTC, 0);
2785 OUTB(bktr, BKTR_O_VTC, 0);
2786 } else {
2787 OUTB(bktr, BKTR_E_VTC, 1);
2788 OUTB(bktr, BKTR_O_VTC, 1);
2789 }
2790 bktr->capcontrol = 3 << 2 | 3;
2791
2792 dma_prog = (u_int *) bktr->dma_prog;
2793
2794 /* Construct Write */
2795
2796 if (bktr->video.addr) {
2797 target_buffer = (u_int) bktr->video.addr;
2798 pitch = bktr->video.width;
2799 }
2800 else {
2801 target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
2802 pitch = cols*Bpp;
2803 }
2804
2805 buffer = target_buffer;
2806
2807 /* Wait for the VRE sync marking the end of the Even and
2808 * the start of the Odd field. Resync here.
2809 */
2810 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_VRE);
2811 *dma_prog++ = htole32(0);
2812
2813 loop_point = bktr->dm_prog->dm_segs[0].ds_addr;
2814
2815 /* store the VBI data */
2816 /* look for sync with packed data */
2817 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2818 *dma_prog++ = htole32(0);
2819 for(i = 0; i < vbilines; i++) {
2820 *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2821 *dma_prog++ = htole32((u_int)
2822 bktr->dm_vbidata->dm_segs[0].ds_addr + (i * VBI_LINE_SIZE));
2823 }
2824
2825 if ((i_flag == 2/*Odd*/) || (i_flag==3) /*interlaced*/) {
2826 /* store the Odd field video image */
2827 /* look for sync with packed data */
2828 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2829 *dma_prog++ = htole32(0); /* NULL WORD */
2830 width = cols;
2831 for (i = 0; i < (rows/interlace); i++) {
2832 target = target_buffer;
2833 if (notclipped(bktr, i, width)) {
2834 split(bktr, (volatile u_int **) &dma_prog,
2835 bktr->y2 - bktr->y, OP_WRITE,
2836 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2837
2838 } else {
2839 while(getline(bktr, i)) {
2840 if (bktr->y != bktr->y2) {
2841 split(bktr, (volatile u_int **) &dma_prog,
2842 bktr->y2 - bktr->y, OP_WRITE,
2843 Bpp, (volatile u_char **) (uintptr_t)&target, cols);
2844 }
2845 if (bktr->yclip != bktr->yclip2) {
2846 split(bktr,(volatile u_int **) &dma_prog,
2847 bktr->yclip2 - bktr->yclip,
2848 OP_SKIP,
2849 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2850 }
2851 }
2852
2853 }
2854
2855 target_buffer += interlace * pitch;
2856
2857 }
2858
2859 } /* end if */
2860
2861 /* Grab the Even field */
2862 /* Look for the VRO, end of Odd field, marker */
2863 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
2864 *dma_prog++ = htole32(0); /* NULL WORD */
2865
2866 /* store the VBI data */
2867 /* look for sync with packed data */
2868 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2869 *dma_prog++ = htole32(0);
2870 for(i = 0; i < vbilines; i++) {
2871 *dma_prog++ = htole32(OP_WRITE | OP_SOL | OP_EOL | vbisamples);
2872 *dma_prog++ = htole32((u_int)
2873 bktr->dm_vbidata->dm_segs[0].ds_addr +
2874 ((i+MAX_VBI_LINES) * VBI_LINE_SIZE));
2875 }
2876
2877 /* store the video image */
2878 if (i_flag == 1) /*Even Only*/
2879 target_buffer = buffer;
2880 if (i_flag == 3) /*interlaced*/
2881 target_buffer = buffer+pitch;
2882
2883
2884 if ((i_flag == 1) /*Even Only*/ || (i_flag==3) /*interlaced*/) {
2885 /* look for sync with packed data */
2886 *dma_prog++ = htole32(OP_SYNC | BKTR_FM1);
2887 *dma_prog++ = htole32(0); /* NULL WORD */
2888 width = cols;
2889 for (i = 0; i < (rows/interlace); i++) {
2890 target = target_buffer;
2891 if (notclipped(bktr, i, width)) {
2892 split(bktr, (volatile u_int **) &dma_prog,
2893 bktr->y2 - bktr->y, OP_WRITE,
2894 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2895 } else {
2896 while(getline(bktr, i)) {
2897 if (bktr->y != bktr->y2) {
2898 split(bktr, (volatile u_int **) &dma_prog,
2899 bktr->y2 - bktr->y, OP_WRITE,
2900 Bpp, (volatile u_char **)(uintptr_t)&target,
2901 cols);
2902 }
2903 if (bktr->yclip != bktr->yclip2) {
2904 split(bktr, (volatile u_int **) &dma_prog,
2905 bktr->yclip2 - bktr->yclip, OP_SKIP,
2906 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2907 }
2908
2909 }
2910
2911 }
2912
2913 target_buffer += interlace * pitch;
2914
2915 }
2916 }
2917
2918 /* Look for end of 'Even Field' */
2919 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
2920 *dma_prog++ = htole32(0); /* NULL WORD */
2921
2922 *dma_prog++ = htole32(OP_JUMP);
2923 *dma_prog++ = htole32(loop_point);
2924 *dma_prog++ = htole32(0); /* NULL WORD */
2925
2926 }
2927
2928
2929
2930
2931 static void
2932 rgb_prog(bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace)
2933 {
2934 int i;
2935 volatile u_int target_buffer, buffer, target,width;
2936 volatile u_int pitch;
2937 volatile u_int *dma_prog;
2938 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
2939 u_int Bpp = pf_int->public.Bpp;
2940
2941 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
2942 OUTB(bktr, BKTR_VBI_PACK_SIZE, 0);
2943 OUTB(bktr, BKTR_VBI_PACK_DEL, 0);
2944 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
2945
2946 OUTB(bktr, BKTR_OFORM, 0x00);
2947
2948 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
2949 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
2950 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
2951 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
2952
2953 /* disable gamma correction removal */
2954 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
2955
2956 if (cols > 385) {
2957 OUTB(bktr, BKTR_E_VTC, 0);
2958 OUTB(bktr, BKTR_O_VTC, 0);
2959 } else {
2960 OUTB(bktr, BKTR_E_VTC, 1);
2961 OUTB(bktr, BKTR_O_VTC, 1);
2962 }
2963 bktr->capcontrol = 3 << 2 | 3;
2964
2965 dma_prog = (u_int *) bktr->dma_prog;
2966
2967 /* Construct Write */
2968
2969 if (bktr->video.addr) {
2970 target_buffer = (u_int) bktr->video.addr;
2971 pitch = bktr->video.width;
2972 }
2973 else {
2974 target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
2975 pitch = cols*Bpp;
2976 }
2977
2978 buffer = target_buffer;
2979
2980 /* construct sync : for video packet format */
2981 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
2982
2983 /* sync, mode indicator packed data */
2984 *dma_prog++ = htole32(0); /* NULL WORD */
2985 width = cols;
2986 for (i = 0; i < (rows/interlace); i++) {
2987 target = target_buffer;
2988 if (notclipped(bktr, i, width)) {
2989 split(bktr, (volatile u_int **) &dma_prog,
2990 bktr->y2 - bktr->y, OP_WRITE,
2991 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2992
2993 } else {
2994 while(getline(bktr, i)) {
2995 if (bktr->y != bktr->y2) {
2996 split(bktr, (volatile u_int **) &dma_prog,
2997 bktr->y2 - bktr->y, OP_WRITE,
2998 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
2999 }
3000 if (bktr->yclip != bktr->yclip2) {
3001 split(bktr,(volatile u_int **) &dma_prog,
3002 bktr->yclip2 - bktr->yclip,
3003 OP_SKIP,
3004 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3005 }
3006 }
3007
3008 }
3009
3010 target_buffer += interlace * pitch;
3011
3012 }
3013
3014 switch (i_flag) {
3015 case 1:
3016 /* sync vre */
3017 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
3018 *dma_prog++ = htole32(0); /* NULL WORD */
3019
3020 *dma_prog++ = htole32(OP_JUMP);
3021 *dma_prog++ = htole32((u_int)
3022 bktr->dm_prog->dm_segs[0].ds_addr);
3023 return;
3024
3025 case 2:
3026 /* sync vro */
3027 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
3028 *dma_prog++ = htole32(0); /* NULL WORD */
3029
3030 *dma_prog++ = htole32(OP_JUMP);
3031 *dma_prog++ = htole32((u_int)
3032 bktr->dm_prog->dm_segs[0].ds_addr);
3033 return;
3034
3035 case 3:
3036 /* sync vro */
3037 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3038 *dma_prog++ = htole32(0); /* NULL WORD */
3039 *dma_prog++ = htole32(OP_JUMP);
3040 *dma_prog++ = htole32((u_int)
3041 bktr->dm_oprog->dm_segs[0].ds_addr);
3042 break;
3043 }
3044
3045 if (interlace == 2) {
3046
3047 target_buffer = buffer + pitch;
3048
3049 dma_prog = (u_int *) bktr->odd_dma_prog;
3050
3051 /* sync vre IRQ bit */
3052 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3053 *dma_prog++ = htole32(0); /* NULL WORD */
3054 width = cols;
3055 for (i = 0; i < (rows/interlace); i++) {
3056 target = target_buffer;
3057 if (notclipped(bktr, i, width)) {
3058 split(bktr, (volatile u_int **) &dma_prog,
3059 bktr->y2 - bktr->y, OP_WRITE,
3060 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3061 } else {
3062 while(getline(bktr, i)) {
3063 if (bktr->y != bktr->y2) {
3064 split(bktr, (volatile u_int **) &dma_prog,
3065 bktr->y2 - bktr->y, OP_WRITE,
3066 Bpp, (volatile u_char **)(uintptr_t)&target,
3067 cols);
3068 }
3069 if (bktr->yclip != bktr->yclip2) {
3070 split(bktr, (volatile u_int **) &dma_prog,
3071 bktr->yclip2 - bktr->yclip, OP_SKIP,
3072 Bpp, (volatile u_char **)(uintptr_t)&target, cols);
3073 }
3074
3075 }
3076
3077 }
3078
3079 target_buffer += interlace * pitch;
3080
3081 }
3082 }
3083
3084 /* sync vre IRQ bit */
3085 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3086 *dma_prog++ = htole32(0); /* NULL WORD */
3087 *dma_prog++ = htole32(OP_JUMP);
3088 *dma_prog++ = htole32((u_int) bktr->dm_prog->dm_segs[0].ds_addr);
3089 *dma_prog++ = htole32(0); /* NULL WORD */
3090 }
3091
3092
3093 /*
3094 *
3095 */
3096 static void
3097 yuvpack_prog(bktr_ptr_t bktr, char i_flag,
3098 int cols, int rows, int interlace)
3099 {
3100 int i;
3101 volatile unsigned int inst;
3102 volatile unsigned int inst3;
3103 volatile u_int target_buffer, buffer;
3104 volatile u_int *dma_prog;
3105 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3106 int b;
3107
3108 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3109
3110 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* enable chroma comb */
3111 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3112
3113 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_RGB_DED | BT848_COLOR_CTL_GAMMA);
3114 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3115
3116 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3117 bktr->capcontrol = 3 << 2 | 3;
3118
3119 dma_prog = (u_int *) bktr->dma_prog;
3120
3121 /* Construct Write */
3122
3123 /* write , sol, eol */
3124 inst = OP_WRITE | OP_SOL | (cols);
3125 /* write , sol, eol */
3126 inst3 = OP_WRITE | OP_EOL | (cols);
3127
3128 if (bktr->video.addr)
3129 target_buffer = (u_int) bktr->video.addr;
3130 else
3131 target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
3132
3133 buffer = target_buffer;
3134
3135 /* construct sync : for video packet format */
3136 /* sync, mode indicator packed data */
3137 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3138 *dma_prog++ = htole32(0); /* NULL WORD */
3139
3140 b = cols;
3141
3142 for (i = 0; i < (rows/interlace); i++) {
3143 *dma_prog++ = htole32(inst);
3144 *dma_prog++ = htole32(target_buffer);
3145 *dma_prog++ = htole32(inst3);
3146 *dma_prog++ = htole32(target_buffer + b);
3147 target_buffer += interlace*(cols * 2);
3148 }
3149
3150 switch (i_flag) {
3151 case 1:
3152 /* sync vre */
3153 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE);
3154 *dma_prog++ = htole32(0); /* NULL WORD */
3155
3156 *dma_prog++ = htole32(OP_JUMP);
3157 *dma_prog++ = htole32(
3158 (u_int)bktr->dm_prog->dm_segs[0].ds_addr);
3159 return;
3160
3161 case 2:
3162 /* sync vro */
3163 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO);
3164 *dma_prog++ = htole32(0); /* NULL WORD */
3165 *dma_prog++ = htole32(OP_JUMP);
3166 *dma_prog++ = htole32((u_int)
3167 bktr->dm_prog->dm_segs[0].ds_addr);
3168 return;
3169
3170 case 3:
3171 /* sync vro */
3172 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3173 *dma_prog++ = htole32(0); /* NULL WORD */
3174 *dma_prog++ = htole32(OP_JUMP);
3175 *dma_prog++ = htole32((u_int)
3176 bktr->dm_oprog->dm_segs[0].ds_addr);
3177 break;
3178 }
3179
3180 if (interlace == 2) {
3181
3182 target_buffer = (u_int) buffer + cols*2;
3183
3184 dma_prog = (u_int *) bktr->odd_dma_prog;
3185
3186 /* sync vre */
3187 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM1);
3188 *dma_prog++ = htole32(0); /* NULL WORD */
3189
3190 for (i = 0; i < (rows/interlace); i++) {
3191 *dma_prog++ = htole32(inst);
3192 *dma_prog++ = htole32(target_buffer);
3193 *dma_prog++ = htole32(inst3);
3194 *dma_prog++ = htole32(target_buffer + b);
3195 target_buffer += interlace * (cols*2);
3196 }
3197 }
3198
3199 /* sync vro IRQ bit */
3200 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3201 *dma_prog++ = htole32(0); /* NULL WORD */
3202 *dma_prog++ = htole32(OP_JUMP);
3203 *dma_prog++ = htole32((u_int) bktr->dm_prog->dm_segs[0].ds_addr);
3204
3205 *dma_prog++ = htole32(OP_JUMP);
3206 *dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
3207 *dma_prog++ = htole32(0); /* NULL WORD */
3208 }
3209
3210
3211 /*
3212 *
3213 */
3214 static void
3215 yuv422_prog(bktr_ptr_t bktr, char i_flag,
3216 int cols, int rows, int interlace) {
3217
3218 int i;
3219 volatile unsigned int inst;
3220 volatile u_int target_buffer, t1, buffer;
3221 volatile u_int *dma_prog;
3222 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3223
3224 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3225
3226 dma_prog = (u_int *) bktr->dma_prog;
3227
3228 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3229
3230 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3231 OUTB(bktr, BKTR_OFORM, 0x00);
3232
3233 OUTB(bktr, BKTR_E_CONTROL, INB(bktr, BKTR_E_CONTROL) | BT848_E_CONTROL_LDEC); /* disable luma decimation */
3234 OUTB(bktr, BKTR_O_CONTROL, INB(bktr, BKTR_O_CONTROL) | BT848_O_CONTROL_LDEC);
3235
3236 OUTB(bktr, BKTR_E_SCLOOP, INB(bktr, BKTR_E_SCLOOP) | BT848_E_SCLOOP_CAGC); /* chroma agc enable */
3237 OUTB(bktr, BKTR_O_SCLOOP, INB(bktr, BKTR_O_SCLOOP) | BT848_O_SCLOOP_CAGC);
3238
3239 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x80); /* clear Ycomb */
3240 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x80);
3241 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x40); /* set chroma comb */
3242 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x40);
3243
3244 /* disable gamma correction removal */
3245 OUTB(bktr, BKTR_COLOR_CTL, INB(bktr, BKTR_COLOR_CTL) | BT848_COLOR_CTL_GAMMA);
3246
3247 /* Construct Write */
3248 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3249 if (bktr->video.addr)
3250 target_buffer = (u_int) bktr->video.addr;
3251 else
3252 target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
3253
3254 buffer = target_buffer;
3255
3256 t1 = buffer;
3257
3258 /* construct sync : for video packet format */
3259 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
3260 *dma_prog++ = htole32(0); /* NULL WORD */
3261
3262 for (i = 0; i < (rows/interlace); i++) {
3263 *dma_prog++ = htole32(inst);
3264 *dma_prog++ = htole32(cols/2 | cols/2 << 16);
3265 *dma_prog++ = htole32(target_buffer);
3266 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3267 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
3268 target_buffer += interlace*cols;
3269 }
3270
3271 switch (i_flag) {
3272 case 1:
3273 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/
3274 *dma_prog++ = htole32(0); /* NULL WORD */
3275
3276 *dma_prog++ = htole32(OP_JUMP);
3277 *dma_prog++ = htole32((u_int)
3278 bktr->dm_prog->dm_segs[0].ds_addr);
3279 return;
3280
3281 case 2:
3282 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vre*/
3283 *dma_prog++ = htole32(0); /* NULL WORD */
3284
3285 *dma_prog++ = htole32(OP_JUMP);
3286 *dma_prog++ = htole32((u_int)
3287 bktr->dm_prog->dm_segs[0].ds_addr);
3288 return;
3289
3290 case 3:
3291 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3292 *dma_prog++ = htole32(0); /* NULL WORD */
3293
3294 *dma_prog++ = htole32(OP_JUMP);
3295 *dma_prog++ = htole32((u_int)
3296 bktr->dm_oprog->dm_segs[0].ds_addr);
3297 break;
3298 }
3299
3300 if (interlace == 2) {
3301
3302 dma_prog = (u_int *) bktr->odd_dma_prog;
3303
3304 target_buffer = (u_int) buffer + cols;
3305 t1 = buffer + cols/2;
3306 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3307 *dma_prog++ = htole32(0); /* NULL WORD */
3308
3309 for (i = 0; i < (rows/interlace); i++) {
3310 *dma_prog++ = htole32(inst);
3311 *dma_prog++ = htole32(cols/2 | cols/2 << 16);
3312 *dma_prog++ = htole32(target_buffer);
3313 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3314 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace);
3315 target_buffer += interlace*cols;
3316 }
3317 }
3318
3319 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3320 *dma_prog++ = htole32(0); /* NULL WORD */
3321 *dma_prog++ = htole32(OP_JUMP);
3322 *dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
3323 *dma_prog++ = htole32(0); /* NULL WORD */
3324 }
3325
3326
3327 /*
3328 *
3329 */
3330 static void
3331 yuv12_prog(bktr_ptr_t bktr, char i_flag,
3332 int cols, int rows, int interlace) {
3333
3334 int i;
3335 volatile unsigned int inst;
3336 volatile unsigned int inst1;
3337 volatile u_int target_buffer, t1, buffer;
3338 volatile u_int *dma_prog;
3339 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3340
3341 OUTB(bktr, BKTR_COLOR_FMT, pf_int->color_fmt);
3342
3343 dma_prog = (u_int *) bktr->dma_prog;
3344
3345 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3346
3347 OUTB(bktr, BKTR_ADC, SYNC_LEVEL);
3348 OUTB(bktr, BKTR_OFORM, 0x0);
3349
3350 /* Construct Write */
3351 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3352 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3353 if (bktr->video.addr)
3354 target_buffer = (u_int) bktr->video.addr;
3355 else
3356 target_buffer = (u_int) bktr->dm_mem->dm_segs[0].ds_addr;
3357
3358 buffer = target_buffer;
3359 t1 = buffer;
3360
3361 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3); /*sync, mode indicator packed data*/
3362 *dma_prog++ = htole32(0); /* NULL WORD */
3363
3364 for (i = 0; i < (rows/interlace)/2; i++) {
3365 *dma_prog++ = htole32(inst);
3366 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3367 *dma_prog++ = htole32(target_buffer);
3368 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3369 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
3370 target_buffer += interlace*cols;
3371 *dma_prog++ = htole32(inst1);
3372 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3373 *dma_prog++ = htole32(target_buffer);
3374 target_buffer += interlace*cols;
3375
3376 }
3377
3378 switch (i_flag) {
3379 case 1:
3380 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRE); /*sync vre*/
3381 *dma_prog++ = htole32(0); /* NULL WORD */
3382
3383 *dma_prog++ = htole32(OP_JUMP);
3384 *dma_prog++ = htole32((u_int)
3385 bktr->dm_prog->dm_segs[0].ds_addr);
3386 return;
3387
3388 case 2:
3389 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_VRO); /*sync vro*/
3390 *dma_prog++ = htole32(0); /* NULL WORD */
3391
3392 *dma_prog++ = htole32(OP_JUMP);
3393 *dma_prog++ = htole32((u_int)
3394 bktr->dm_prog->dm_segs[0].ds_addr);
3395 return;
3396
3397 case 3:
3398 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRO);
3399 *dma_prog++ = htole32(0); /* NULL WORD */
3400 *dma_prog++ = htole32(OP_JUMP);
3401 *dma_prog++ = htole32((u_int)
3402 bktr->dm_oprog->dm_segs[0].ds_addr);
3403 break;
3404 }
3405
3406 if (interlace == 2) {
3407
3408 dma_prog = (u_int *) bktr->odd_dma_prog;
3409
3410 target_buffer = (u_int) buffer + cols;
3411 t1 = buffer + cols/2;
3412 *dma_prog++ = htole32(OP_SYNC | BKTR_RESYNC | BKTR_FM3);
3413 *dma_prog++ = htole32(0); /* NULL WORD */
3414
3415 for (i = 0; i < ((rows/interlace)/2); i++) {
3416 *dma_prog++ = htole32(inst);
3417 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3418 *dma_prog++ = htole32(target_buffer);
3419 *dma_prog++ = htole32(t1 + (cols*rows) + i*cols/2 * interlace);
3420 *dma_prog++ = htole32(t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace);
3421 target_buffer += interlace*cols;
3422 *dma_prog++ = htole32(inst1);
3423 *dma_prog++ = htole32(cols/2 | (cols/2 << 16));
3424 *dma_prog++ = htole32(target_buffer);
3425 target_buffer += interlace*cols;
3426
3427 }
3428
3429
3430 }
3431
3432 *dma_prog++ = htole32(OP_SYNC | BKTR_GEN_IRQ | BKTR_RESYNC | BKTR_VRE);
3433 *dma_prog++ = htole32(0); /* NULL WORD */
3434 *dma_prog++ = htole32(OP_JUMP);
3435 *dma_prog++ = htole32((u_int)bktr->dm_prog->dm_segs[0].ds_addr);
3436 *dma_prog++ = htole32(0); /* NULL WORD */
3437 }
3438
3439
3440
3441 /*
3442 *
3443 */
3444 static void
3445 build_dma_prog(bktr_ptr_t bktr, char i_flag)
3446 {
3447 int rows, cols, interlace;
3448 int tmp_int;
3449 unsigned int temp;
3450 const struct format_params *fp;
3451 const struct meteor_pixfmt_internal *pf_int = &pixfmt_table[bktr->pixfmt];
3452
3453
3454 fp = &format_params[bktr->format_params];
3455
3456 OUTL(bktr, BKTR_INT_MASK, ALL_INTS_DISABLED);
3457
3458 /* disable FIFO & RISC, leave other bits alone */
3459 OUTW(bktr, BKTR_GPIO_DMA_CTL, INW(bktr, BKTR_GPIO_DMA_CTL) & ~FIFO_RISC_ENABLED);
3460
3461 /* set video parameters */
3462 if (bktr->capture_area_enabled)
3463 temp = ((quad_t) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3464 / fp->scaled_htotal / bktr->cols) - 4096;
3465 else
3466 temp = ((quad_t) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3467 / fp->scaled_htotal / bktr->cols) - 4096;
3468
3469 /* printf("%s: HSCALE value is %d\n", bktr_name(bktr), temp); */
3470 OUTB(bktr, BKTR_E_HSCALE_LO, temp & 0xff);
3471 OUTB(bktr, BKTR_O_HSCALE_LO, temp & 0xff);
3472 OUTB(bktr, BKTR_E_HSCALE_HI, (temp >> 8) & 0xff);
3473 OUTB(bktr, BKTR_O_HSCALE_HI, (temp >> 8) & 0xff);
3474
3475 /* horizontal active */
3476 temp = bktr->cols;
3477 /* printf("%s: HACTIVE value is %d\n", bktr_name(bktr), temp); */
3478 OUTB(bktr, BKTR_E_HACTIVE_LO, temp & 0xff);
3479 OUTB(bktr, BKTR_O_HACTIVE_LO, temp & 0xff);
3480 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x3);
3481 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x3);
3482 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 8) & 0x3));
3483 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 8) & 0x3));
3484
3485 /* horizontal delay */
3486 if (bktr->capture_area_enabled)
3487 temp = ((fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3488 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3489 else
3490 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3491
3492 temp = temp & 0x3fe;
3493
3494 /* printf("%s: HDELAY value is %d\n", bktr_name(bktr), temp); */
3495 OUTB(bktr, BKTR_E_DELAY_LO, temp & 0xff);
3496 OUTB(bktr, BKTR_O_DELAY_LO, temp & 0xff);
3497 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xc);
3498 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xc);
3499 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 6) & 0xc));
3500 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 6) & 0xc));
3501
3502 /* vertical scale */
3503
3504 if (bktr->capture_area_enabled) {
3505 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3506 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3507 tmp_int = 65536 -
3508 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3509 else {
3510 tmp_int = 65536 -
3511 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3512 }
3513 } else {
3514 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3515 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3516 tmp_int = 65536 -
3517 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3518 else {
3519 tmp_int = 65536 -
3520 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3521 }
3522 }
3523
3524 tmp_int &= 0x1fff;
3525 /* printf("%s: VSCALE value is %d\n", bktr_name(bktr), tmp_int); */
3526 OUTB(bktr, BKTR_E_VSCALE_LO, tmp_int & 0xff);
3527 OUTB(bktr, BKTR_O_VSCALE_LO, tmp_int & 0xff);
3528 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x1f);
3529 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x1f);
3530 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3531 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | ((tmp_int >> 8) & 0x1f));
3532
3533
3534 /* vertical active */
3535 if (bktr->capture_area_enabled)
3536 temp = bktr->capture_area_y_size;
3537 else
3538 temp = fp->vactive;
3539 /* printf("%s: VACTIVE is %d\n", bktr_name(bktr), temp); */
3540 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0x30);
3541 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 4) & 0x30));
3542 OUTB(bktr, BKTR_E_VACTIVE_LO, temp & 0xff);
3543 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0x30);
3544 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 4) & 0x30));
3545 OUTB(bktr, BKTR_O_VACTIVE_LO, temp & 0xff);
3546
3547 /* vertical delay */
3548 if (bktr->capture_area_enabled)
3549 temp = fp->vdelay + (bktr->capture_area_y_offset);
3550 else
3551 temp = fp->vdelay;
3552 /* printf("%s: VDELAY is %d\n", bktr_name(bktr), temp); */
3553 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) & ~0xC0);
3554 OUTB(bktr, BKTR_E_CROP, INB(bktr, BKTR_E_CROP) | ((temp >> 2) & 0xC0));
3555 OUTB(bktr, BKTR_E_VDELAY_LO, temp & 0xff);
3556 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) & ~0xC0);
3557 OUTB(bktr, BKTR_O_CROP, INB(bktr, BKTR_O_CROP) | ((temp >> 2) & 0xC0));
3558 OUTB(bktr, BKTR_O_VDELAY_LO, temp & 0xff);
3559
3560 /* end of video params */
3561
3562 if ((bktr->xtal_pll_mode == BT848_USE_PLL)
3563 && (fp->iform_xtsel==BT848_IFORM_X_XT1)) {
3564 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_PLL); /* Select PLL mode */
3565 } else {
3566 OUTB(bktr, BKTR_TGCTRL, BT848_TGCTRL_TGCKI_XTAL); /* Select Normal xtal 0/xtal 1 mode */
3567 }
3568
3569 /* capture control */
3570 switch (i_flag) {
3571 case 1:
3572 bktr->bktr_cap_ctl =
3573 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3574 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3575 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3576 interlace = 1;
3577 break;
3578 case 2:
3579 bktr->bktr_cap_ctl =
3580 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3581 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) & ~0x20);
3582 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) & ~0x20);
3583 interlace = 1;
3584 break;
3585 default:
3586 bktr->bktr_cap_ctl =
3587 (BT848_CAP_CTL_DITH_FRAME |
3588 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3589 OUTB(bktr, BKTR_E_VSCALE_HI, INB(bktr, BKTR_E_VSCALE_HI) | 0x20);
3590 OUTB(bktr, BKTR_O_VSCALE_HI, INB(bktr, BKTR_O_VSCALE_HI) | 0x20);
3591 interlace = 2;
3592 break;
3593 }
3594
3595 OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs[0].ds_addr);
3596
3597 rows = bktr->rows;
3598 cols = bktr->cols;
3599
3600 bktr->vbiflags &= ~VBI_CAPTURE; /* default - no vbi capture */
3601
3602 /* RGB Grabs. If /dev/vbi is already open, or we are a PAL/SECAM */
3603 /* user, then use the rgb_vbi RISC program. */
3604 /* Otherwise, use the normal rgb RISC program */
3605 if (pf_int->public.type == METEOR_PIXTYPE_RGB) {
3606 if ((bktr->vbiflags & VBI_OPEN)
3607 ||(bktr->format_params == BT848_IFORM_F_PALBDGHI)
3608 ||(bktr->format_params == BT848_IFORM_F_SECAM)) {
3609 bktr->bktr_cap_ctl |=
3610 BT848_CAP_CTL_VBI_EVEN | BT848_CAP_CTL_VBI_ODD;
3611 bktr->vbiflags |= VBI_CAPTURE;
3612 rgb_vbi_prog(bktr, i_flag, cols, rows, interlace);
3613 return;
3614 } else {
3615 rgb_prog(bktr, i_flag, cols, rows, interlace);
3616 return;
3617 }
3618 }
3619
3620 if (pf_int->public.type == METEOR_PIXTYPE_YUV) {
3621 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3622 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3623 | pixfmt_swap_flags(bktr->pixfmt));
3624 return;
3625 }
3626
3627 if (pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED) {
3628 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3629 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3630 | pixfmt_swap_flags(bktr->pixfmt));
3631 return;
3632 }
3633
3634 if (pf_int->public.type == METEOR_PIXTYPE_YUV_12) {
3635 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3636 OUTB(bktr, BKTR_COLOR_CTL, (INB(bktr, BKTR_COLOR_CTL) & 0xf0)
3637 | pixfmt_swap_flags(bktr->pixfmt));
3638 return;
3639 }
3640 return;
3641 }
3642
3643
3644 /******************************************************************************
3645 * video & video capture specific routines:
3646 */
3647
3648
3649 /*
3650 *
3651 */
3652 static void
3653 start_capture(bktr_ptr_t bktr, unsigned type)
3654 {
3655 u_char i_flag;
3656 const struct format_params *fp;
3657
3658 fp = &format_params[bktr->format_params];
3659
3660 /* If requested, clear out capture buf first */
3661 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3662 memset((void *)bktr->bigbuf, 0,
3663 (size_t)bktr->rows * bktr->cols * bktr->frames *
3664 pixfmt_table[bktr->pixfmt].public.Bpp);
3665 }
3666
3667 OUTB(bktr, BKTR_DSTATUS, 0);
3668 OUTL(bktr, BKTR_INT_STAT, INL(bktr, BKTR_INT_STAT));
3669
3670 bktr->flags |= type;
3671 bktr->flags &= ~METEOR_WANT_MASK;
3672 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3673 case METEOR_ONLY_EVEN_FIELDS:
3674 bktr->flags |= METEOR_WANT_EVEN;
3675 i_flag = 1;
3676 break;
3677 case METEOR_ONLY_ODD_FIELDS:
3678 bktr->flags |= METEOR_WANT_ODD;
3679 i_flag = 2;
3680 break;
3681 default:
3682 bktr->flags |= METEOR_WANT_MASK;
3683 i_flag = 3;
3684 break;
3685 }
3686
3687 /* TDEC is only valid for continuous captures */
3688 if (type == METEOR_SINGLE) {
3689 u_short fps_save = bktr->fps;
3690
3691 set_fps(bktr, fp->frame_rate);
3692 bktr->fps = fps_save;
3693 }
3694 else
3695 set_fps(bktr, bktr->fps);
3696
3697 if (bktr->dma_prog_loaded == FALSE) {
3698 build_dma_prog(bktr, i_flag);
3699 bktr->dma_prog_loaded = TRUE;
3700 }
3701
3702
3703 OUTL(bktr, BKTR_RISC_STRT_ADD, bktr->dm_prog->dm_segs[0].ds_addr);
3704
3705 }
3706
3707
3708 /*
3709 *
3710 */
3711 static void
3712 set_fps(bktr_ptr_t bktr, u_short fps)
3713 {
3714 const struct format_params *fp;
3715 int i_flag;
3716
3717 fp = &format_params[bktr->format_params];
3718
3719 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3720 case METEOR_ONLY_EVEN_FIELDS:
3721 bktr->flags |= METEOR_WANT_EVEN;
3722 i_flag = 1;
3723 break;
3724 case METEOR_ONLY_ODD_FIELDS:
3725 bktr->flags |= METEOR_WANT_ODD;
3726 i_flag = 1;
3727 break;
3728 default:
3729 bktr->flags |= METEOR_WANT_MASK;
3730 i_flag = 2;
3731 break;
3732 }
3733
3734 OUTW(bktr, BKTR_GPIO_DMA_CTL, FIFO_RISC_DISABLED);
3735 OUTL(bktr, BKTR_INT_STAT, ALL_INTS_CLEARED);
3736
3737 bktr->fps = fps;
3738 OUTB(bktr, BKTR_TDEC, 0);
3739
3740 if (fps < fp->frame_rate)
3741 OUTB(bktr, BKTR_TDEC, i_flag*(fp->frame_rate - fps) & 0x3f);
3742 else
3743 OUTB(bktr, BKTR_TDEC, 0);
3744 return;
3745
3746 }
3747
3748
3749
3750
3751
3752 /*
3753 * Given a pixfmt index, compute the bt848 swap_flags necessary to
3754 * achieve the specified swapping.
3755 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
3756 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
3757 * and read R->L).
3758 * Note also that for 3Bpp, we may additionally need to do some creative
3759 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
3760 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
3761 * as one would expect.
3762 */
3763
3764 static u_int pixfmt_swap_flags(int pixfmt)
3765 {
3766 const struct meteor_pixfmt *pf = &pixfmt_table[pixfmt].public;
3767 u_int swapf = 0;
3768 int swap_bytes, swap_shorts;
3769
3770 #if BYTE_ORDER == LITTLE_ENDIAN
3771 swap_bytes = pf->swap_bytes;
3772 swap_shorts = pf->swap_shorts;
3773 #else
3774 swap_bytes = !pf->swap_bytes;
3775 swap_shorts = !pf->swap_shorts;
3776 #endif
3777 switch (pf->Bpp) {
3778 case 2 : swapf = (swap_bytes ? 0 : BSWAP);
3779 break;
3780
3781 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
3782 break;
3783
3784 case 4 :
3785 swapf = swap_bytes ? 0 : BSWAP;
3786 swapf |= swap_shorts ? 0 : WSWAP;
3787 break;
3788 }
3789 return swapf;
3790 }
3791
3792
3793
3794 /*
3795 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
3796 * our pixfmt_table indices.
3797 */
3798
3799 static int oformat_meteor_to_bt(u_int format)
3800 {
3801 int i;
3802 const struct meteor_pixfmt *pf1, *pf2;
3803
3804 /* Find format in compatibility table */
3805 for (i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++)
3806 if (meteor_pixfmt_table[i].meteor_format == format)
3807 break;
3808
3809 if (i >= METEOR_PIXFMT_TABLE_SIZE)
3810 return -1;
3811 pf1 = &meteor_pixfmt_table[i].public;
3812
3813 /* Match it with an entry in master pixel format table */
3814 for (i = 0; i < PIXFMT_TABLE_SIZE; i++) {
3815 pf2 = &pixfmt_table[i].public;
3816
3817 if ((pf1->type == pf2->type) &&
3818 (pf1->Bpp == pf2->Bpp) &&
3819 !memcmp(pf1->masks, pf2->masks, sizeof(pf1->masks)) &&
3820 (pf1->swap_bytes == pf2->swap_bytes) &&
3821 (pf1->swap_shorts == pf2->swap_shorts))
3822 break;
3823 }
3824 if (i >= PIXFMT_TABLE_SIZE)
3825 return -1;
3826
3827 return i;
3828 }
3829
3830 /******************************************************************************
3831 * i2c primitives:
3832 */
3833
3834 /* */
3835 #define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
3836 #define I2CBITTIME_878 (1 << 7)
3837 #define I2C_READ 0x01
3838 #define I2C_COMMAND (I2CBITTIME | \
3839 BT848_DATA_CTL_I2CSCL | \
3840 BT848_DATA_CTL_I2CSDA)
3841
3842 #define I2C_COMMAND_878 (I2CBITTIME_878 | \
3843 BT848_DATA_CTL_I2CSCL | \
3844 BT848_DATA_CTL_I2CSDA)
3845
3846 /* Select between old i2c code and new iicbus / smbus code */
3847 #if defined(BKTR_USE_FREEBSD_SMBUS)
3848
3849 /*
3850 * The hardware interface is actually SMB commands
3851 */
3852 int
3853 i2cWrite(bktr_ptr_t bktr, int addr, int byte1, int byte2)
3854 {
3855 char cmd;
3856
3857 if (bktr->id == BROOKTREE_848 ||
3858 bktr->id == BROOKTREE_848A ||
3859 bktr->id == BROOKTREE_849A)
3860 cmd = I2C_COMMAND;
3861 else
3862 cmd = I2C_COMMAND_878;
3863
3864 if (byte2 != -1) {
3865 if (smbus_writew(bktr->i2c_sc.smbus, addr, cmd,
3866 (short)(((byte2 & 0xff) << 8) | (byte1 & 0xff))))
3867 return (-1);
3868 } else {
3869 if (smbus_writeb(bktr->i2c_sc.smbus, addr, cmd,
3870 (char)(byte1 & 0xff)))
3871 return (-1);
3872 }
3873
3874 /* return OK */
3875 return(0);
3876 }
3877
3878 int
3879 i2cRead(bktr_ptr_t bktr, int addr)
3880 {
3881 char result;
3882 char cmd;
3883
3884 if (bktr->id == BROOKTREE_848 ||
3885 bktr->id == BROOKTREE_848A ||
3886 bktr->id == BROOKTREE_849A)
3887 cmd = I2C_COMMAND;
3888 else
3889 cmd = I2C_COMMAND_878;
3890
3891 if (smbus_readb(bktr->i2c_sc.smbus, addr, cmd, &result))
3892 return (-1);
3893
3894 return ((int)((unsigned char)result));
3895 }
3896
3897 #define IICBUS(bktr) ((bktr)->i2c_sc.iicbus)
3898
3899 /* The MSP34xx and DPL35xx Audio chip require i2c bus writes of up */
3900 /* to 5 bytes which the bt848 automated i2c bus controller cannot handle */
3901 /* Therefore we need low level control of the i2c bus hardware */
3902
3903 /* Write to the MSP or DPL registers */
3904 void
3905 msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr, unsigned int data)
3906 {
3907 unsigned char addr_l, addr_h, data_h, data_l;
3908
3909 addr_h = (addr >>8) & 0xff;
3910 addr_l = addr & 0xff;
3911 data_h = (data >>8) & 0xff;
3912 data_l = data & 0xff;
3913
3914 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3915
3916 iicbus_write_byte(IICBUS(bktr), dev, 0);
3917 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3918 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3919 iicbus_write_byte(IICBUS(bktr), data_h, 0);
3920 iicbus_write_byte(IICBUS(bktr), data_l, 0);
3921
3922 iicbus_stop(IICBUS(bktr));
3923
3924 return;
3925 }
3926
3927 /* Read from the MSP or DPL registers */
3928 unsigned int
3929 msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr)
3930 {
3931 unsigned int data;
3932 unsigned char addr_l, addr_h, dev_r;
3933 int read;
3934 u_char data_read[2];
3935
3936 addr_h = (addr >>8) & 0xff;
3937 addr_l = addr & 0xff;
3938 dev_r = dev+1;
3939
3940 /* XXX errors ignored */
3941 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3942
3943 iicbus_write_byte(IICBUS(bktr), dev_r, 0);
3944 iicbus_write_byte(IICBUS(bktr), addr_h, 0);
3945 iicbus_write_byte(IICBUS(bktr), addr_l, 0);
3946
3947 iicbus_repeated_start(IICBUS(bktr), i2c_addr +1, 0 /* no timeout? */);
3948 iicbus_read(IICBUS(bktr), data_read, 2, &read, IIC_LAST_READ, 0);
3949 iicbus_stop(IICBUS(bktr));
3950
3951 data = (data_read[0]<<8) | data_read[1];
3952
3953 return (data);
3954 }
3955
3956 /* Reset the MSP or DPL chip */
3957 /* The user can block the reset (which is handy if you initialise the
3958 * MSP and/or DPL audio in another operating system first (eg in Windows)
3959 */
3960 void
3961 msp_dpl_reset(bktr_ptr_t bktr, int i2c_addr)
3962 {
3963
3964 #ifndef BKTR_NO_MSP_RESET
3965 /* put into reset mode */
3966 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3967 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3968 iicbus_write_byte(IICBUS(bktr), 0x80, 0);
3969 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3970 iicbus_stop(IICBUS(bktr));
3971
3972 /* put back to operational mode */
3973 iicbus_start(IICBUS(bktr), i2c_addr, 0 /* no timeout? */);
3974 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3975 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3976 iicbus_write_byte(IICBUS(bktr), 0x00, 0);
3977 iicbus_stop(IICBUS(bktr));
3978 #endif
3979 return;
3980 }
3981
3982 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
3983 int read;
3984
3985 /* XXX errors ignored */
3986 iicbus_start(IICBUS(bktr), bktr->remote_control_addr, 0 /* no timeout? */);
3987 iicbus_read(IICBUS(bktr), remote->data, 3, &read, IIC_LAST_READ, 0);
3988 iicbus_stop(IICBUS(bktr));
3989
3990 return;
3991 }
3992
3993 #else /* defined(BKTR_USE_FREEBSD_SMBUS) */
3994
3995 /*
3996 * Program the i2c bus directly
3997 */
3998 int
3999 i2cWrite(bktr_ptr_t bktr, int addr, int byte1, int byte2)
4000 {
4001 u_int x;
4002 u_int data;
4003
4004 /* clear status bits */
4005 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4006
4007 /* build the command datum */
4008 if (bktr->id == BROOKTREE_848 ||
4009 bktr->id == BROOKTREE_848A ||
4010 bktr->id == BROOKTREE_849A) {
4011 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
4012 } else {
4013 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
4014 }
4015 if (byte2 != -1) {
4016 data |= ((byte2 & 0xff) << 8);
4017 data |= BT848_DATA_CTL_I2CW3B;
4018 }
4019
4020 /* write the address and data */
4021 OUTL(bktr, BKTR_I2C_DATA_CTL, data);
4022
4023 /* wait for completion */
4024 for (x = 0x7fffffff; x; --x) { /* safety valve */
4025 if (INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE)
4026 break;
4027 }
4028
4029 /* check for ACK */
4030 if (!x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK))
4031 return(-1);
4032
4033 /* return OK */
4034 return(0);
4035 }
4036
4037
4038 /*
4039 *
4040 */
4041 int
4042 i2cRead(bktr_ptr_t bktr, int addr)
4043 {
4044 u_int x;
4045
4046 /* clear status bits */
4047 OUTL(bktr, BKTR_INT_STAT, BT848_INT_RACK | BT848_INT_I2CDONE);
4048
4049 /* write the READ address */
4050 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
4051
4052 if (bktr->id == BROOKTREE_848 ||
4053 bktr->id == BROOKTREE_848A ||
4054 bktr->id == BROOKTREE_849A) {
4055 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND);
4056 } else {
4057 OUTL(bktr, BKTR_I2C_DATA_CTL, ((addr & 0xff) << 24) | I2C_COMMAND_878);
4058 }
4059
4060 /* wait for completion */
4061 for (x = 5000; x--; DELAY(1)) { /* 5msec, safety valve */
4062 if (INL(bktr, BKTR_INT_STAT) & BT848_INT_I2CDONE)
4063 break;
4064 }
4065
4066 /* check for ACK */
4067 if (!x || !(INL(bktr, BKTR_INT_STAT) & BT848_INT_RACK))
4068 return(-1);
4069
4070 /* it was a read */
4071 return((INL(bktr, BKTR_I2C_DATA_CTL) >> 8) & 0xff);
4072 }
4073
4074 /* The MSP34xx Audio chip require i2c bus writes of up to 5 bytes which the */
4075 /* bt848 automated i2c bus controller cannot handle */
4076 /* Therefore we need low level control of the i2c bus hardware */
4077 /* Idea for the following functions are from elsewhere in this driver and */
4078 /* from the Linux BTTV i2c driver by Gerd Knorr <kraxel@cs.tu-berlin.de> */
4079
4080 #define BITD 40
4081 static void i2c_start(bktr_ptr_t bktr) {
4082 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release data */
4083 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release clock */
4084 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* lower data */
4085 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock */
4086 }
4087
4088 static void i2c_stop(bktr_ptr_t bktr) {
4089 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock & data */
4090 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* release clock */
4091 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release data */
4092 }
4093
4094 static int i2c_write_byte(bktr_ptr_t bktr, unsigned char data) {
4095 int x;
4096 int status;
4097
4098 /* write out the byte */
4099 for (x = 7; x >= 0; --x) {
4100 if (data & (1<<x)) {
4101 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4102 DELAY(BITD); /* assert HI data */
4103 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4104 DELAY(BITD); /* strobe clock */
4105 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4106 DELAY(BITD); /* release clock */
4107 }
4108 else {
4109 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4110 DELAY(BITD); /* assert LO data */
4111 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4112 DELAY(BITD); /* strobe clock */
4113 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4114 DELAY(BITD); /* release clock */
4115 }
4116 }
4117
4118 /* look for an ACK */
4119 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* float data */
4120 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* strobe clock */
4121 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4122 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release clock */
4123
4124 return(status);
4125 }
4126
4127 static int i2c_read_byte(bktr_ptr_t bktr, unsigned char *data, int last) {
4128 int x;
4129 int bit;
4130 int byte = 0;
4131
4132 /* read in the byte */
4133 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4134 DELAY(BITD); /* float data */
4135 for (x = 7; x >= 0; --x) {
4136 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4137 DELAY(BITD); /* strobe clock */
4138 bit = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the data bit */
4139 if (bit) byte |= (1<<x);
4140 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4141 DELAY(BITD); /* release clock */
4142 }
4143 /* After reading the byte, send an ACK */
4144 /* (unless that was the last byte, for which we send a NAK */
4145 if (last) { /* send NAK - same a writing a 1 */
4146 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4147 DELAY(BITD); /* set data bit */
4148 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4149 DELAY(BITD); /* strobe clock */
4150 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4151 DELAY(BITD); /* release clock */
4152 } else { /* send ACK - same as writing a 0 */
4153 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4154 DELAY(BITD); /* set data bit */
4155 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4156 DELAY(BITD); /* strobe clock */
4157 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4158 DELAY(BITD); /* release clock */
4159 }
4160
4161 *data=byte;
4162 return 0;
4163 }
4164 #undef BITD
4165
4166 /* Write to the MSP or DPL registers */
4167 void msp_dpl_write(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr,
4168 unsigned int data) {
4169 unsigned int msp_w_addr = i2c_addr;
4170 unsigned char addr_l, addr_h, data_h, data_l;
4171 addr_h = (addr >>8) & 0xff;
4172 addr_l = addr & 0xff;
4173 data_h = (data >>8) & 0xff;
4174 data_l = data & 0xff;
4175
4176 i2c_start(bktr);
4177 i2c_write_byte(bktr, msp_w_addr);
4178 i2c_write_byte(bktr, dev);
4179 i2c_write_byte(bktr, addr_h);
4180 i2c_write_byte(bktr, addr_l);
4181 i2c_write_byte(bktr, data_h);
4182 i2c_write_byte(bktr, data_l);
4183 i2c_stop(bktr);
4184 }
4185
4186 /* Read from the MSP or DPL registers */
4187 unsigned int msp_dpl_read(bktr_ptr_t bktr, int i2c_addr, unsigned char dev, unsigned int addr) {
4188 unsigned int data;
4189 unsigned char addr_l, addr_h, data_1, data_2, dev_r;
4190 addr_h = (addr >>8) & 0xff;
4191 addr_l = addr & 0xff;
4192 dev_r = dev+1;
4193
4194 i2c_start(bktr);
4195 i2c_write_byte(bktr,i2c_addr);
4196 i2c_write_byte(bktr,dev_r);
4197 i2c_write_byte(bktr,addr_h);
4198 i2c_write_byte(bktr,addr_l);
4199
4200 i2c_start(bktr);
4201 i2c_write_byte(bktr,i2c_addr+1);
4202 i2c_read_byte(bktr,&data_1, 0);
4203 i2c_read_byte(bktr,&data_2, 1);
4204 i2c_stop(bktr);
4205 data = (data_1<<8) | data_2;
4206 return data;
4207 }
4208
4209 /* Reset the MSP or DPL chip */
4210 /* The user can block the reset (which is handy if you initialise the
4211 * MSP audio in another operating system first (eg in Windows)
4212 */
4213 void msp_dpl_reset(bktr_ptr_t bktr, int i2c_addr) {
4214
4215 #ifndef BKTR_NO_MSP_RESET
4216 /* put into reset mode */
4217 i2c_start(bktr);
4218 i2c_write_byte(bktr, i2c_addr);
4219 i2c_write_byte(bktr, 0x00);
4220 i2c_write_byte(bktr, 0x80);
4221 i2c_write_byte(bktr, 0x00);
4222 i2c_stop(bktr);
4223
4224 /* put back to operational mode */
4225 i2c_start(bktr);
4226 i2c_write_byte(bktr, i2c_addr);
4227 i2c_write_byte(bktr, 0x00);
4228 i2c_write_byte(bktr, 0x00);
4229 i2c_write_byte(bktr, 0x00);
4230 i2c_stop(bktr);
4231 #endif
4232 return;
4233
4234 }
4235
4236 static void remote_read(bktr_ptr_t bktr, struct bktr_remote *remote) {
4237
4238 /* XXX errors ignored */
4239 i2c_start(bktr);
4240 i2c_write_byte(bktr,bktr->remote_control_addr);
4241 i2c_read_byte(bktr,&(remote->data[0]), 0);
4242 i2c_read_byte(bktr,&(remote->data[1]), 0);
4243 i2c_read_byte(bktr,&(remote->data[2]), 0);
4244 i2c_stop(bktr);
4245
4246 return;
4247 }
4248
4249 #endif /* defined(BKTR_USE_FREEBSD_SMBUS) */
4250
4251
4252 #if defined(I2C_SOFTWARE_PROBE)
4253
4254 /*
4255 * we are keeping this around for any parts that we need to probe
4256 * but that CANNOT be probed via an i2c read.
4257 * this is necessary because the hardware i2c mechanism
4258 * cannot be programmed for 1 byte writes.
4259 * currently there are no known i2c parts that we need to probe
4260 * and that cannot be safely read.
4261 */
4262 static int i2cProbe(bktr_ptr_t bktr, int addr);
4263 #define BITD 40
4264 #define EXTRA_START
4265
4266 /*
4267 * probe for an I2C device at addr.
4268 */
4269 static int
4270 i2cProbe(bktr_ptr_t bktr, int addr)
4271 {
4272 int x, status;
4273
4274 /* the START */
4275 #if defined(EXTRA_START)
4276 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release data */
4277 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release clock */
4278 #endif /* EXTRA_START */
4279 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* lower data */
4280 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock */
4281
4282 /* write addr */
4283 for (x = 7; x >= 0; --x) {
4284 if (addr & (1<<x)) {
4285 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4286 DELAY(BITD); /* assert HI data */
4287 OUTL(bktr, BKTR_I2C_DATA_CTL, 3);
4288 DELAY(BITD); /* strobe clock */
4289 OUTL(bktr, BKTR_I2C_DATA_CTL, 1);
4290 DELAY(BITD); /* release clock */
4291 }
4292 else {
4293 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4294 DELAY(BITD); /* assert LO data */
4295 OUTL(bktr, BKTR_I2C_DATA_CTL, 2);
4296 DELAY(BITD); /* strobe clock */
4297 OUTL(bktr, BKTR_I2C_DATA_CTL, 0);
4298 DELAY(BITD); /* release clock */
4299 }
4300 }
4301
4302 /* look for an ACK */
4303 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* float data */
4304 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* strobe clock */
4305 status = INL(bktr, BKTR_I2C_DATA_CTL) & 1; /* read the ACK bit */
4306 OUTL(bktr, BKTR_I2C_DATA_CTL, 1); DELAY(BITD); /* release clock */
4307
4308 /* the STOP */
4309 OUTL(bktr, BKTR_I2C_DATA_CTL, 0); DELAY(BITD); /* lower clock & data */
4310 OUTL(bktr, BKTR_I2C_DATA_CTL, 2); DELAY(BITD); /* release clock */
4311 OUTL(bktr, BKTR_I2C_DATA_CTL, 3); DELAY(BITD); /* release data */
4312
4313 return(status);
4314 }
4315 #undef EXTRA_START
4316 #undef BITD
4317
4318 #endif /* I2C_SOFTWARE_PROBE */
4319