Deleted Added
sdiff udiff text old ( 39040 ) new ( 39041 )
full compact
1/* BT848 1.52 Driver for Brooktree's Bt848 based cards.
2 The Brooktree BT848 Driver driver is based upon Mark Tinguely and
3 Jim Lowe's driver for the Matrox Meteor PCI card . The
4 Philips SAA 7116 and SAA 7196 are very different chipsets than
5 the BT848. For starters, the BT848 is a one chipset solution and
6 it incorporates a RISC engine to control the DMA transfers --
7 that is it the actual dma process is control by a program which
8 resides in the hosts memory also the register definitions between
9 the Philips chipsets and the Bt848 are very different.
10
11 The original copyright notice by Mark and Jim is included mostly
12 to honor their fantastic work in the Matrox Meteor driver!
13
14 Enjoy,
15 Amancio
16
17 */
18
19/*
20 * 1. Redistributions of source code must retain the
21 * Copyright (c) 1997 Amancio Hasty
22 * All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
32 * 3. All advertising materials mentioning features or use of this software
33 * must display the following acknowledgement:
34 * This product includes software developed by Amancio Hasty
35 * 4. The name of the author may not be used to endorse or promote products
36 * derived from this software without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
39 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
40 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
42 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
44 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
47 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
48 * POSSIBILITY OF SUCH DAMAGE.
49 */
50
51
52
53
54/*
55 * 1. Redistributions of source code must retain the
56 * Copyright (c) 1995 Mark Tinguely and Jim Lowe
57 * All rights reserved.
58 *
59 * Redistribution and use in source and binary forms, with or without
60 * modification, are permitted provided that the following conditions
61 * are met:
62 * 1. Redistributions of source code must retain the above copyright
63 * notice, this list of conditions and the following disclaimer.
64 * 2. Redistributions in binary form must reproduce the above copyright
65 * notice, this list of conditions and the following disclaimer in the
66 * documentation and/or other materials provided with the distribution.
67 * 3. All advertising materials mentioning features or use of this software
68 * must display the following acknowledgement:
69 * This product includes software developed by Mark Tinguely and Jim Lowe
70 * 4. The name of the author may not be used to endorse or promote products
71 * derived from this software without specific prior written permission.
72 *
73 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
74 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
77 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
79 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
81 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
82 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
83 * POSSIBILITY OF SUCH DAMAGE.
84 */
85
86/* Change History:
871.0 1/24/97 First Alpha release
88
891.1 2/20/97 Added video ioctl so we can do PCI To PCI
90 data transfers. This is for capturing data
91 directly to a vga frame buffer which has
92 a linear frame buffer. Minor code clean-up.
93
941.3 2/23/97 Fixed system lock-up reported by
95 Randall Hopper <rhh@ct.picker.com>. This
96 problem seems somehow to be exhibited only
97 in his system. I changed the setting of
98 INT_MASK for CAP_CONTINUOUS to be exactly
99 the same as CAP_SINGLE apparently setting
100 bit 23 cleared the system lock up.
101 version 1.1 of the driver has been reported
102 to work with STB's WinTv, Hauppage's Wincast/Tv
103 and last but not least with the Intel Smart
104 Video Recorder.
105
1061.4 3/9/97 fsmp@freefall.org
107 Merged code to support tuners on STB and WinCast
108 cards.
109 Modifications to the contrast and chroma ioctls.
110 Textual cleanup.
111
1121.5 3/15/97 fsmp@freefall.org
113 new bt848 specific versions of hue/bright/
114 contrast/satu/satv.
115 Amancio's patch to fix "screen freeze" problem.
116
1171.6 3/19/97 fsmp@freefall.org
118 new table-driven frequency lookup.
119 removed disable_intr()/enable_intr() calls from i2c.
120 misc. cleanup.
121
1221.7 3/19/97 fsmp@freefall.org
123 added audio support submitted by:
124 Michael Petry <petry@netwolf.NetMasters.com>
125
1261.8 3/20/97 fsmp@freefall.org
127 extended audio support.
128 card auto-detection.
129 major cleanup, order of routines, declarations, etc.
130
1311.9 3/22/97 fsmp@freefall.org
132 merged in Amancio's minor unit for tuner control
133 mods.
134 misc. cleanup, especially in the _intr routine.
135 made AUDIO_SUPPORT mainline code.
136
1371.10 3/23/97 fsmp@freefall.org
138 added polled hardware i2c routines,
139 removed all existing software i2c routines.
140 created software i2cProbe() routine.
141 Randall Hopper's fixes of BT848_GHUE & BT848_GBRIG.
142 eeprom support.
143
1441.11 3/24/97 fsmp@freefall.org
145 Louis Mamakos's new bt848 struct.
146
1471.12 3/25/97 fsmp@freefall.org
148 japanese freq table from Naohiro Shichijo.
149 new table structs for tuner lookups.
150 major scrub for "magic numbers".
151
1521.13 3/28/97 fsmp@freefall.org
153 1st PAL support.
154 MAGIC_[1-4] demarcates magic #s needing PAL work.
155 AFC code submitted by Richard Tobin
156 <richard@cogsci.ed.ac.uk>.
157
1581.14 3/29/97 richard@cogsci.ed.ac.uk
159 PAL support: magic numbers moved into
160 format_params structure.
161 Revised AFC interface.
162 fixed DMA_PROG_ALLOC size misdefinition.
163
1641.15 4/18/97 John-Mark Gurney <gurney_j@resnet.uoregon.edu>
165 Added [SR]RGBMASKs ioctl for byte swapping.
166
1671.16 4/20/97 Randall Hopper <rhh@ct.picker.com>
168 Generalized RGBMASK ioctls for general pixel
169 format setting [SG]ACTPIXFMT, and added query API
170 to return driver-supported pix fmts GSUPPIXFMT.
171
1721.17 4/21/97 hasty@rah.star-gate.com
173 Clipping support added.
174
1751.18 4/23/97 Clean up after failed CAP_SINGLEs where bt
176 interrupt isn't delivered, and fixed fixing
177 CAP_SINGLEs that for ODD_ONLY fields.
1781.19 9/8/97 improved yuv support , cleaned up weurope
179 channel table, incorporated cleanup work from
180 Luigi, fixed pci interface bug due to a
181 change in the pci interface which disables
182 interrupts from a PCI device by default,
183 Added Luigi's, ioctl's BT848_SLNOTCH,
184 BT848_GLNOTCH (set luma notch and get luma not)
1851.20 10/5/97 Keith Sklower <sklower@CS.Berkeley.EDU> submitted
186 a patch to fix compilation of the BSDI's PCI
187 interface.
188 Hideyuki Suzuki <hideyuki@sat.t.u-tokyo.ac.jp>
189 Submitted a patch for Japanese cable channels
190 Joao Carlos Mendes Luis jonny@gta.ufrj.br
191 Submitted general ioctl to set video broadcast
192 formats (PAL, NTSC, etc..) previously we depended
193 on the Bt848 auto video detect feature.
1941.21 10/24/97 Randall Hopper <rhh@ct.picker.com>
195 Fix temporal decimation, disable it when
196 doing CAP_SINGLEs, and in dual-field capture, don't
197 capture fields for different frames
1981.22 11/08/97 Randall Hopper <rhh@ct.picker.com>
199 Fixes for packed 24bpp - FIFO alignment
2001.23 11/17/97 Amancio <hasty@star-gate.com>
201 Added yuv support mpeg encoding
2021.24 12/27/97 Jonathan Hanna <pangolin@rogers.wave.ca>
203 Patch to support Philips FR1236MK2 tuner
2041.25 02/02/98 Takeshi Ohashi
205 <ohashi@atohasi.mickey.ai.kyutech.ac.jp> submitted
206 code to support bktr_read .
207 Flemming Jacobsen <fj@schizo.dk.tfs.com>
208 submitted code to support radio available with in
209 some bt848 based cards;additionally, wrote code to
210 correctly recognized his bt848 card.
211 Roger Hardiman <roger@cs.strath.ac.uk> submitted
212 various fixes to smooth out the microcode and made
213 all modes consistent.
2141.26 Moved Luigi's I2CWR ioctl from the video_ioctl
215 section to the tuner_ioctl section
216 Changed Major device from 79 to 92 and reserved
217 our Major device number -- hasty@star-gate.com
2181.27 Last batch of patches for radio support from
219 Flemming Jacobsen <fj@trw.nl>.
220 Added B849 PCI ID submitted by:
221 Tomi Vainio <tomppa@fidata.fi>
2221.28 Frank Nobis <fn@Radio-do.de> added tuner support
223 for the German Phillips PAL tuner and
224 additional channels for german cable tv.
2251.29 Roger Hardiman <roger@cs.strath.ac.uk>
226 Revised autodetection code to correctly handle both
227 old and new VideoLogic Captivator PCI cards.
228 Added tsleep of 2 seconds to initialistion code
229 for PAL users.Corrected clock selection code on
230 format change.
2311.30 Bring back Frank Nobis <fn@Radio-do.de>'s opt_bktr.h
232
2331.31 Randall Hopper <rhh@ct.picker.com>
234 submitted ioctl to clear the video buffer
235 prior to starting video capture
236 Amancio : clean up yuv12 so that it does not
237 affect rgb capture. Basically, fxtv after
238 capturing in yuv12 mode , switching to rgb
239 would cause the video capture to be too bright.
2401.32 disable inverse gamma function for rgb and yuv
241 capture. fixed meteor brightness ioctl it now
242 converts the brightness value from unsigned to
243 signed.
2441.33 added sysctl: hw.bt848.tuner, hw.bt848.reverse_mute,
245 hw.bt848.card
246 card takes a value from 0 to bt848_max_card
247 tuner takes a value from 0 to bt848_max_tuner
248 reverse_mute : 0 no effect, 1 reverse tuner
249 mute function some tuners are wired reversed :(
2501.34 reverse mute function for ims turbo card
251
2521.35 Roger Hardiman <roger@cs.strath.ac.uk>
253 options BROOKTREE_SYSTEM_DEFAULT=BROOKTREE_PAL
254 in the kernel config file makes the driver's
255 video_open() function select PAL rather than NTSC.
256 This fixed all the hangs on my Dual Crystal card
257 when using a PAL video signal. As a result, you
258 can loose the tsleep (of 2 seconds - now 0.25!!)
259 which I previously added. (Unless someone else
260 wanted the 0.25 second tsleep).
261
2621.36 added bt848.format sysctl variable.
263 1 denotes NTSC , 0 denotes PAL
264
2651.37 added support for Bt878 and improved Hauppauge's
266 bt848 tuner recognition
2671.38 Further improvements on Hauppauge's rely on
268 eeprom[9] to determine the tuner type 8)
269
270 AVerMedia card type added <sos@freebsd.org>
271
2721.39 08/05/98 Roger Hardiman <roger@cs.strath.ac.uk>
273 Updated Hauppauge detection code for Tuner ID 0x0a
274 for newer NTSC WinCastTV 404 with Bt878 chipset.
275 Tidied up PAL default in video_open()
276
2771.49 10 August 1998 Roger Hardiman <roger@cs.strath.ac.uk>
278 Added Capture Area ioctl - BT848[SG]CAPAREA.
279 Normally the full 640x480 (768x576 PAL) image
280 is grabbed. This ioctl allows a smaller area
281 from anywhere within the video image to be
282 grabbed, eg a 400x300 image from (50,10).
283 See restrictions in BT848SCAPAREA.
284
2851.50 31 August 1998 Roger Hardiman <roger@cs.strath.ac.uk>
286 Renamed BT848[SG]CAPAREA to BT848_[SG]CAPAREA.
287 Added PR kern/7177 for SECAM Video Highway Xtreme
288 with single crystal PLL configuration
289 submitted by Vsevolod Lobko <seva@alex-ua.com>.
290 In kernel configuration file add
291 options OVERRIDE_CARD=2
292 options OVERRIDE_TUNER=11
293 options BKTR_USE_PLL
294
2951.51 31 August 1998 Roger Hardiman <roger@cs.strath.ac.uk>
296 Fixed bug in Miro Tuner detection. Missing Goto.
297 Removed Hauppauge EEPROM 0x10 detection as I think
298 0x10 should be a PAL tuner, not NTSC.
299 Reinstated some Tuner Guesswork code from 1.27
300
3011.52 3 Sep 1998 Roger Hardiman <roger@cs.strath.ac.uk>
302 Submitted patch by Vsevolod Lobko <seva@alex-ua.com>
303 to correct SECAM B-Delay and add XUSSR channel set.
304
305
306
307*/
308
309#define DDB(x) x
310#define DEB(x)
311
312#ifdef __FreeBSD__
313#include "bktr.h"
314#include "opt_bktr.h"
315#include "opt_devfs.h"
316#include "pci.h"
317#endif /* __FreeBSD__ */
318
319#if !defined(__FreeBSD__) || (NBKTR > 0 && NPCI > 0)
320
321#include <sys/param.h>
322#include <sys/systm.h>
323#include <sys/conf.h>
324#include <sys/uio.h>
325#include <sys/kernel.h>
326#include <sys/signalvar.h>
327#include <sys/mman.h>
328
329#include <vm/vm.h>
330#include <vm/vm_kern.h>
331#include <vm/pmap.h>
332#include <vm/vm_extern.h>
333
334#ifdef __FreeBSD__
335#ifdef DEVFS
336#include <sys/devfsext.h>
337#endif /* DEVFS */
338#include <machine/clock.h>
339#include <pci/pcivar.h>
340#include <pci/pcireg.h>
341
342#include <machine/ioctl_meteor.h>
343#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
344#include <pci/brktree_reg.h>
345#include <sys/sysctl.h>
346static int bt848_card = -1;
347static int bt848_tuner = -1;
348static int bt848_reverse_mute = -1;
349static int bt848_format = -1;
350
351SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
352SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
353SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
354SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
355SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
356
357typedef u_long ioctl_cmd_t;
358#endif /* __FreeBSD__ */
359
360#ifdef __bsdi__
361#include <sys/device.h>
362#include <i386/isa/isa.h>
363#include <i386/isa/isavar.h>
364#include <i386/isa/icu.h>
365#include <i386/pci/pci.h>
366#include <i386/isa/dma.h>
367#include <i386/eisa/eisa.h>
368#include "ioctl_meteor.h"
369#include "ioctl_bt848.h"
370#include "bt848_reg.h"
371
372typedef u_long ioctl_cmd_t;
373
374#define pci_conf_read(a, r) pci_inl(a, r)
375#define pci_conf_write(a, r, v) pci_outl(a, r, v)
376#include <sys/reboot.h>
377#define bootverbose (autoprint & (AC_VERBOSE|AC_DEBUG))
378#endif /* __bsdi__ */
379
380typedef u_char bool_t;
381
382#define BKTRPRI (PZERO+8)|PCATCH
383
384static void bktr_intr __P((void *arg));
385
386/*
387 * memory allocated for DMA programs
388 */
389#define DMA_PROG_ALLOC (8 * PAGE_SIZE)
390
391/* When to split a dma transfer , the bt848 has timing as well as
392 dma transfer size limitations so that we have to split dma
393 transfers into two dma requests
394 */
395#define DMA_BT848_SPLIT 319*2
396
397/*
398 * Allocate enough memory for:
399 * 768x576 RGB 16 or YUV (16 storage bits/pixel) = 884736 = 216 pages
400 *
401 * You may override this using the options "BROOKTREE_ALLOC_PAGES=value"
402 * in your kernel configuration file.
403 */
404
405#ifndef BROOKTREE_ALLOC_PAGES
406#define BROOKTREE_ALLOC_PAGES 217*4
407#endif
408#define BROOKTREE_ALLOC (BROOKTREE_ALLOC_PAGES * PAGE_SIZE)
409
410/* Defines for fields */
411#define ODD_F 0x01
412#define EVEN_F 0x02
413
414#ifdef __FreeBSD__
415
416static bktr_reg_t brooktree[ NBKTR ];
417#define BROOKTRE_NUM(mtr) ((bktr - &brooktree[0])/sizeof(bktr_reg_t))
418
419#define UNIT(x) ((x) & 0x0f)
420#define MINOR(x) ((x >> 4) & 0x0f)
421#define ATTACH_ARGS pcici_t tag, int unit
422
423static char* bktr_probe( pcici_t tag, pcidi_t type );
424static void bktr_attach( ATTACH_ARGS );
425
426static u_long bktr_count;
427
428static struct pci_device bktr_device = {
429 "bktr",
430 bktr_probe,
431 bktr_attach,
432 &bktr_count
433};
434
435DATA_SET (pcidevice_set, bktr_device);
436
437static d_open_t bktr_open;
438static d_close_t bktr_close;
439static d_read_t bktr_read;
440static d_write_t bktr_write;
441static d_ioctl_t bktr_ioctl;
442static d_mmap_t bktr_mmap;
443
444#define CDEV_MAJOR 92
445static struct cdevsw bktr_cdevsw =
446{
447 bktr_open, bktr_close, bktr_read, bktr_write,
448 bktr_ioctl, nostop, nullreset, nodevtotty,
449 seltrue, bktr_mmap, NULL, "bktr",
450 NULL, -1
451};
452#endif /* __FreeBSD__ */
453
454#ifdef __bsdi__
455#define UNIT dv_unit
456#define MINOR dv_subunit
457#define ATTACH_ARGS \
458 struct device * const parent, struct device * const self, void * const aux
459
460#define PCI_COMMAND_STATUS_REG PCI_COMMAND
461
462static void bktr_attach( ATTACH_ARGS );
463#define NBKTR bktrcd.cd_ndevs
464#define brooktree *((bktr_ptr_t *)bktrcd.cd_devs)
465
466static int bktr_spl;
467static int bktr_intr_returning_1(void *arg) { bktr_intr(arg); return (1);}
468#define disable_intr() { bktr_spl = splhigh(); }
469#define enable_intr() { splx(bktr_spl); }
470
471static int
472bktr_pci_match(pci_devaddr_t *pa)
473{
474 unsigned id;
475
476 id = pci_inl(pa, PCI_VENDOR_ID);
477
478 switch (id) {
479 BROOKTREE_848_ID:
480 BROOKTREE_849_ID:
481 BROOKTREE_878_ID:
482 BROOKTREE_879_ID:
483 return 1;
484 }
485 aprint_debug("bktr_pci_match got %x\n", id);
486 return 0;
487
488}
489
490pci_devres_t bktr_res; /* XXX only remembers last one, helps debug */
491
492static int
493bktr_probe(struct device *parent, struct cfdata *cf, void *aux)
494{
495 pci_devaddr_t *pa;
496 pci_devres_t res;
497 struct isa_attach_args *ia = aux;
498
499 if (ia->ia_bustype != BUS_PCI)
500 return (0);
501
502 if ((pa = pci_scan(bktr_pci_match)) == NULL)
503 return (0);
504
505 pci_getres(pa, &bktr_res, 1, ia);
506 if (ia->ia_maddr == 0) {
507 printf("bktr%d: no mem attached\n", cf->cf_unit);
508 return (0);
509 }
510 ia->ia_aux = pa;
511 return 1;
512}
513
514
515struct cfdriver bktrcd =
516{ 0, "bktr", bktr_probe, bktr_attach, DV_DULL, sizeof(bktr_reg_t) };
517
518int bktr_open __P((dev_t, int, int, struct proc *));
519int bktr_close __P((dev_t, int, int, struct proc *));
520int bktr_read __P((dev_t, struct uio *, int));
521int bktr_write __P((dev_t, struct uio *, int));
522int bktr_ioctl __P((dev_t, ioctl_cmd_t, caddr_t, int, struct proc *));
523int bktr_mmap __P((dev_t, int, int));
524
525struct devsw bktrsw = {
526 &bktrcd,
527 bktr_open, bktr_close, bktr_read, bktr_write, bktr_ioctl,
528 seltrue, bktr_mmap, NULL, nodump, NULL, 0, nostop
529};
530#endif /* __bsdi__ */
531
532/*
533 * This is for start-up convenience only, NOT mandatory.
534 */
535#if !defined( DEFAULT_CHNLSET )
536#define DEFAULT_CHNLSET CHNLSET_WEUROPE
537#endif
538
539/*
540 * Parameters describing size of transmitted image.
541 */
542
543static struct format_params format_params[] = {
544/* # define BT848_IFORM_F_AUTO (0x0) - don't matter. */
545 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_AUTO },
546/* # define BT848_IFORM_F_NTSCM (0x1) */
547 { 525, 26, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0 },
548/* # define BT848_IFORM_F_NTSCJ (0x2) */
549 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0 },
550/* # define BT848_IFORM_F_PALBDGHI (0x3) */
551 { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1 },
552/* # define BT848_IFORM_F_PALM (0x4) */
553 { 525, 22, 480, 910, 135, 754, 640, 780, 30, 0x68, 0x5d, BT848_IFORM_X_XT0 },
554/*{ 625, 32, 576, 910, 186, 922, 640, 780, 25, 0x68, 0x5d, BT848_IFORM_X_XT0 }, */
555/* # define BT848_IFORM_F_PALN (0x5) */
556 { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1 },
557/* # define BT848_IFORM_F_SECAM (0x6) */
558 { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1 },
559/* # define BT848_IFORM_F_RSVD (0x7) - ???? */
560 { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0 },
561};
562
563/*
564 * Table of supported Pixel Formats
565 */
566
567static struct meteor_pixfmt_internal {
568 struct meteor_pixfmt public;
569 u_int color_fmt;
570} pixfmt_table[] = {
571
572{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0,0 }, 0x33 },
573{ { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 1,0 }, 0x33 },
574
575{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 0,0 }, 0x22 },
576{ { 0, METEOR_PIXTYPE_RGB, 2, { 0xf800, 0x07e0, 0x001f }, 1,0 }, 0x22 },
577
578{ { 0, METEOR_PIXTYPE_RGB, 3, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x11 },
579
580{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,0 }, 0x00 },
581{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x00 },
582{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,0 }, 0x00 },
583{ { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x00 },
584{ { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
585{ { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }, 0x44 },
586{ { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }, 0x88 },
587
588};
589#define PIXFMT_TABLE_SIZE ( sizeof(pixfmt_table) / sizeof(pixfmt_table[0]) )
590
591/*
592 * Table of Meteor-supported Pixel Formats (for SETGEO compatibility)
593 */
594
595/* FIXME: Also add YUV_422 and YUV_PACKED as well */
596static struct {
597 u_long meteor_format;
598 struct meteor_pixfmt public;
599} meteor_pixfmt_table[] = {
600 { METEOR_GEO_YUV_12,
601 { 0, METEOR_PIXTYPE_YUV_12, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
602 },
603
604 /* FIXME: Should byte swap flag be on for this one; negative in drvr? */
605 { METEOR_GEO_YUV_422,
606 { 0, METEOR_PIXTYPE_YUV, 2, { 0xff0000,0x00ff00,0x0000ff }, 1,1 }
607 },
608 { METEOR_GEO_YUV_PACKED,
609 { 0, METEOR_PIXTYPE_YUV_PACKED, 2, { 0xff0000,0x00ff00,0x0000ff }, 0,1 }
610 },
611 { METEOR_GEO_RGB16,
612 { 0, METEOR_PIXTYPE_RGB, 2, { 0x7c00, 0x03e0, 0x001f }, 0, 0 }
613 },
614 { METEOR_GEO_RGB24,
615 { 0, METEOR_PIXTYPE_RGB, 4, { 0xff0000, 0x00ff00, 0x0000ff }, 0, 0 }
616 },
617
618};
619#define METEOR_PIXFMT_TABLE_SIZE ( sizeof(meteor_pixfmt_table) / \
620 sizeof(meteor_pixfmt_table[0]) )
621
622
623#define BSWAP (BT848_COLOR_CTL_BSWAP_ODD | BT848_COLOR_CTL_BSWAP_EVEN)
624#define WSWAP (BT848_COLOR_CTL_WSWAP_ODD | BT848_COLOR_CTL_WSWAP_EVEN)
625
626
627/* experimental code for Automatic Frequency Control */
628#define TUNER_AFC
629#define TEST_TUNER_AFC_NOT
630
631#if defined( TUNER_AFC )
632#define AFC_DELAY 10000 /* 10 millisend delay */
633#define AFC_BITS 0x07
634#define AFC_FREQ_MINUS_125 0x00
635#define AFC_FREQ_MINUS_62 0x01
636#define AFC_FREQ_CENTERED 0x02
637#define AFC_FREQ_PLUS_62 0x03
638#define AFC_FREQ_PLUS_125 0x04
639#define AFC_MAX_STEP (5 * FREQFACTOR) /* no more than 5 MHz */
640#endif /* TUNER_AFC */
641
642/*
643 * i2c things:
644 */
645
646/* PLL on a Temic NTSC tuner: 4032FY5 */
647#define TEMIC_NTSC_WADDR 0xc0
648#define TEMIC_NTSC_RADDR 0xc1
649
650/* PLL on a Temic PAL I tuner: 4062FY5 */
651#define TEMIC_PALI_WADDR 0xc2
652#define TEMIC_PALI_RADDR 0xc3
653
654/* PLL on a Philips tuner */
655#define PHILIPS_NTSC_WADDR 0xc6
656#define PHILIPS_NTSC_RADDR 0xc7
657
658/* PLL on a the Philips FR1236MK2 tuner */
659#define PHILIPS_FR1236_NTSC_WADDR 0xc2
660#define PHILIPS_FR1236_NTSC_RADDR 0xc3
661
662/* PLL on a the Philips FR1236MK2 tuner */
663#define PHILIPS_FR1236_SECAM_WADDR 0xc0
664#define PHILIPS_FR1236_SECAM_RADDR 0xc1
665
666/* PLL on a the Philips FR1216MK2 tuner,
667 yes, the european version of the tuner is 1216 */
668#define PHILIPS_FR1216_PAL_WADDR 0xc2
669#define PHILIPS_FR1216_PAL_RADDR 0xc3
670
671/* guaranteed address for any TSA5522/3 (PLL on all(?) tuners) */
672#define TSA552x_WADDR 0xc2
673#define TSA552x_RADDR 0xc3
674
675#define PHILIPS_PAL_WADDR 0xc2
676#define PHILIPS_PAL_RADDR 0xc3
677
678
679#define TSA552x_CB_MSB (0x80)
680#define TSA552x_CB_CP (1<<6)
681#define TSA552x_CB_T2 (1<<5)
682#define TSA552x_CB_T1 (1<<4)
683#define TSA552x_CB_T0 (1<<3)
684#define TSA552x_CB_RSA (1<<2)
685#define TSA552x_CB_RSB (1<<1)
686#define TSA552x_CB_OS (1<<0)
687#define TSA552x_RADIO (TSA552x_CB_MSB | \
688 TSA552x_CB_T0)
689
690/* Add RADIO_OFFSET to the "frequency" to indicate that we want to tune */
691/* the radio (if present) not the TV tuner. */
692/* 20000 is equivalent to 20000MHz/16 = 1.25GHz - this area is unused. */
693#define RADIO_OFFSET 20000
694
695
696/* address of BTSC/SAP decoder chip */
697#define TDA9850_WADDR 0xb6
698#define TDA9850_RADDR 0xb7
699
700/* address of MSP3400C chip */
701#define MSP3400C_WADDR 0x80
702#define MSP3400C_RADDR 0x81
703
704
705/* EEProm (128 * 8) on an STB card */
706#define X24C01_WADDR 0xae
707#define X24C01_RADDR 0xaf
708
709
710/* EEProm (256 * 8) on a Hauppauge card */
711#define PFC8582_WADDR 0xa0
712#define PFC8582_RADDR 0xa1
713
714
715/* registers in the BTSC/dbx chip */
716#define CON1ADDR 0x04
717#define CON2ADDR 0x05
718#define CON3ADDR 0x06
719#define CON4ADDR 0x07
720
721
722/* raise the charge pump voltage for fast tuning */
723#define TSA552x_FCONTROL (TSA552x_CB_MSB | \
724 TSA552x_CB_CP | \
725 TSA552x_CB_T0 | \
726 TSA552x_CB_RSA | \
727 TSA552x_CB_RSB)
728
729/* lower the charge pump voltage for better residual oscillator FM */
730#define TSA552x_SCONTROL (TSA552x_CB_MSB | \
731 TSA552x_CB_T0 | \
732 TSA552x_CB_RSA | \
733 TSA552x_CB_RSB)
734
735/* sync detect threshold */
736#if 0
737#define SYNC_LEVEL (BT848_ADC_RESERVED | \
738 BT848_ADC_CRUSH) /* threshold ~125 mV */
739#else
740#define SYNC_LEVEL (BT848_ADC_RESERVED | \
741 BT848_ADC_SYNC_T) /* threshold ~75 mV */
742#endif
743
744
745/* the GPIO bits that control the audio MUXes */
746#define GPIO_AUDIOMUX_BITS 0x0f
747
748/*
749 * the data for each type of tuner
750 *
751 * if probeCard() fails to detect the proper tuner on boot you can
752 * override it by setting the following define to the tuner present:
753 *
754#define OVERRIDE_TUNER <tuner type>
755 *
756 * where <tuner type> is one of the following tuner defines.
757 */
758
759/* indexes into tuners[] */
760#define NO_TUNER 0
761#define TEMIC_NTSC 1
762#define TEMIC_PAL 2
763#define TEMIC_SECAM 3
764#define PHILIPS_NTSC 4
765#define PHILIPS_PAL 5
766#define PHILIPS_SECAM 6
767#define TEMIC_PALI 7
768#define PHILIPS_PALI 8
769#define PHILIPS_FR1236_NTSC 9
770#define PHILIPS_FR1216_PAL 10
771#define PHILIPS_FR1236_SECAM 11
772#define Bt848_MAX_TUNER 12
773
774/* XXX FIXME: this list is incomplete */
775
776/* input types */
777#define TTYPE_XXX 0
778#define TTYPE_NTSC 1
779#define TTYPE_NTSC_J 2
780#define TTYPE_PAL 3
781#define TTYPE_PAL_M 4
782#define TTYPE_PAL_N 5
783#define TTYPE_SECAM 6
784
785/**
786struct TUNER {
787 char* name;
788 u_char type;
789 u_char pllAddr;
790 u_char pllControl;
791 u_char bandLimits[ 2 ];
792 u_char bandAddrs[ 3 ];
793};
794 */
795static const struct TUNER tuners[] = {
796/* XXX FIXME: fill in the band-switch crosspoints */
797 /* NO_TUNER */
798 { "<none>", /* the 'name' */
799 TTYPE_XXX, /* input type */
800 0x00, /* PLL write address */
801 { 0x00, /* control byte for PLL */
802 0x00,
803 0x00,
804 0x00 },
805 { 0x00, 0x00 }, /* band-switch crosspoints */
806 { 0x00, 0x00, 0x00,0x00} }, /* the band-switch values */
807
808 /* TEMIC_NTSC */
809 { "Temic NTSC", /* the 'name' */
810 TTYPE_NTSC, /* input type */
811 TEMIC_NTSC_WADDR, /* PLL write address */
812 { TSA552x_SCONTROL, /* control byte for PLL */
813 TSA552x_SCONTROL,
814 TSA552x_SCONTROL,
815 0x00 },
816 { 0x00, 0x00 }, /* band-switch crosspoints */
817 { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */
818
819 /* TEMIC_PAL */
820 { "Temic PAL", /* the 'name' */
821 TTYPE_PAL, /* input type */
822 TEMIC_PALI_WADDR, /* PLL write address */
823 { TSA552x_SCONTROL, /* control byte for PLL */
824 TSA552x_SCONTROL,
825 TSA552x_SCONTROL,
826 0x00 },
827 { 0x00, 0x00 }, /* band-switch crosspoints */
828 { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */
829
830 /* TEMIC_SECAM */
831 { "Temic SECAM", /* the 'name' */
832 TTYPE_SECAM, /* input type */
833 0x00, /* PLL write address */
834 { TSA552x_SCONTROL, /* control byte for PLL */
835 TSA552x_SCONTROL,
836 TSA552x_SCONTROL,
837 0x00 },
838 { 0x00, 0x00 }, /* band-switch crosspoints */
839 { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */
840
841 /* PHILIPS_NTSC */
842 { "Philips NTSC", /* the 'name' */
843 TTYPE_NTSC, /* input type */
844 PHILIPS_NTSC_WADDR, /* PLL write address */
845 { TSA552x_SCONTROL, /* control byte for PLL */
846 TSA552x_SCONTROL,
847 TSA552x_SCONTROL,
848 0x00 },
849 { 0x00, 0x00 }, /* band-switch crosspoints */
850 { 0xa0, 0x90, 0x30, 0x00 } }, /* the band-switch values */
851
852 /* PHILIPS_PAL */
853 { "Philips PAL", /* the 'name' */
854 TTYPE_PAL, /* input type */
855 PHILIPS_PAL_WADDR, /* PLL write address */
856 { TSA552x_FCONTROL, /* control byte for PLL */
857 TSA552x_FCONTROL,
858 TSA552x_FCONTROL,
859 TSA552x_RADIO },
860 { 0x00, 0x00 }, /* band-switch crosspoints */
861 { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */
862
863 /* PHILIPS_SECAM */
864 { "Philips SECAM", /* the 'name' */
865 TTYPE_SECAM, /* input type */
866 0x00, /* PLL write address */
867 { TSA552x_SCONTROL, /* control byte for PLL */
868 TSA552x_SCONTROL,
869 TSA552x_SCONTROL,
870 TSA552x_RADIO },
871 { 0x00, 0x00 }, /* band-switch crosspoints */
872 { 0xa0, 0x90, 0x30,0xa4 } }, /* the band-switch values */
873
874 /* TEMIC_PAL I */
875 { "Temic PAL I", /* the 'name' */
876 TTYPE_PAL, /* input type */
877 TEMIC_PALI_WADDR, /* PLL write address */
878 { TSA552x_SCONTROL, /* control byte for PLL */
879 TSA552x_SCONTROL,
880 TSA552x_SCONTROL,
881 0x00 },
882 { 0x00, 0x00 }, /* band-switch crosspoints */
883 { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */
884
885 /* PHILIPS_PAL */
886 { "Philips PAL I", /* the 'name' */
887 TTYPE_PAL, /* input type */
888 TEMIC_PALI_WADDR, /* PLL write address */
889 { TSA552x_SCONTROL, /* control byte for PLL */
890 TSA552x_SCONTROL,
891 TSA552x_SCONTROL,
892 0x00 },
893 { 0x00, 0x00 }, /* band-switch crosspoints */
894 { 0xa0, 0x90, 0x30,0x00 } }, /* the band-switch values */
895
896 /* PHILIPS_FR1236_NTSC */
897 { "Philips FR1236 NTSC FM", /* the 'name' */
898 TTYPE_NTSC, /* input type */
899 PHILIPS_FR1236_NTSC_WADDR, /* PLL write address */
900 { TSA552x_SCONTROL, /* control byte for PLL */
901 TSA552x_SCONTROL,
902 TSA552x_SCONTROL,
903 TSA552x_RADIO },
904 { 0x00, 0x00 }, /* band-switch crosspoints */
905 { 0xa0, 0x90, 0x30,0xa4 } }, /* the band-switch values */
906
907 /* PHILIPS_FR1216_PAL */
908 { "Philips FR1216 PAL" , /* the 'name' */
909 TTYPE_PAL, /* input type */
910 PHILIPS_FR1216_PAL_WADDR, /* PLL write address */
911 { TSA552x_FCONTROL, /* control byte for PLL */
912 TSA552x_FCONTROL,
913 TSA552x_FCONTROL,
914 TSA552x_RADIO },
915 { 0x00, 0x00 }, /* band-switch crosspoints */
916 { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */
917
918 /* PHILIPS_FR1236_SECAM */
919 { "Philips FR1236 SECAM FM", /* the 'name' */
920 TTYPE_SECAM, /* input type */
921 PHILIPS_FR1236_SECAM_WADDR, /* PLL write address */
922 { TSA552x_FCONTROL, /* control byte for PLL */
923 TSA552x_FCONTROL,
924 TSA552x_FCONTROL,
925 TSA552x_RADIO },
926 { 0x00, 0x00 }, /* band-switch crosspoints */
927 { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */
928};
929
930/******************************************************************************
931 * card probe
932 */
933
934
935/*
936 * the recognized cards, used as indexes of several tables.
937 *
938 * if probeCard() fails to detect the proper card on boot you can
939 * override it by setting the following define to the card you are using:
940 *
941#define OVERRIDE_CARD <card type>
942 *
943 * where <card type> is one of the following card defines.
944 */
945#define CARD_UNKNOWN 0
946#define CARD_MIRO 1
947#define CARD_HAUPPAUGE 2
948#define CARD_STB 3
949#define CARD_INTEL 4
950#define CARD_IMS_TURBO 5
951#define CARD_AVER_MEDIA 6
952#define Bt848_MAX_CARD 7
953
954/*
955 * the data for each type of card
956 *
957 * Note:
958 * these entried MUST be kept in the order defined by the CARD_XXX defines!
959 */
960static const struct CARDTYPE cards[] = {
961
962 /* CARD_UNKNOWN */
963 { "Unknown", /* the 'name' */
964 NULL, /* the tuner */
965 0, /* dbx unknown */
966 0,
967 0, /* EEProm unknown */
968 0, /* EEProm unknown */
969 { 0, 0, 0, 0, 0 } },
970
971 /* CARD_MIRO */
972 { "Miro TV", /* the 'name' */
973 NULL, /* the tuner */
974 0, /* dbx unknown */
975 0,
976 0, /* EEProm unknown */
977 0, /* size unknown */
978 { 0x02, 0x01, 0x00, 0x0a, 1 } }, /* XXX ??? */
979
980 /* CARD_HAUPPAUGE */
981 { "Hauppauge WinCast/TV", /* the 'name' */
982 NULL, /* the tuner */
983 0, /* dbx is optional */
984 0,
985 PFC8582_WADDR, /* EEProm type */
986 (u_char)(256 / EEPROMBLOCKSIZE), /* 256 bytes */
987 { 0x00, 0x02, 0x01, 0x01, 1 } }, /* audio MUX values */
988
989 /* CARD_STB */
990 { "STB TV/PCI", /* the 'name' */
991 NULL, /* the tuner */
992 0, /* dbx is optional */
993 0,
994 X24C01_WADDR, /* EEProm type */
995 (u_char)(128 / EEPROMBLOCKSIZE), /* 128 bytes */
996 { 0x00, 0x01, 0x02, 0x02, 1 } }, /* audio MUX values */
997
998 /* CARD_INTEL */
999 { "Intel Smart Video III/VideoLogic Captivator PCI", /* the 'name' */
1000 NULL, /* the tuner */
1001 0,
1002 0,
1003 0,
1004 0,
1005 { 0, 0, 0, 0, 0 } },
1006
1007 /* CARD_IMS_TURBO */
1008 { "IMS TV Turbo", /* the 'name' */
1009 NULL, /* the tuner */
1010 0, /* dbx is optional */
1011 0,
1012 PFC8582_WADDR, /* EEProm type */
1013 (u_char)(256 / EEPROMBLOCKSIZE), /* 256 bytes */
1014 { 0x01, 0x02, 0x01, 0x00, 1 } }, /* audio MUX values */
1015
1016 /* CARD_AVER_MEDIA */
1017 { "AVer Media TV/FM", /* the 'name' */
1018 NULL, /* the tuner */
1019 0, /* dbx is optional */
1020 0,
1021 0, /* EEProm type */
1022 0, /* EEProm size */
1023 { 0x0c, 0x00, 0x0b, 0x0b, 1 } }, /* audio MUX values */
1024};
1025
1026struct bt848_card_sig bt848_card_signature[1]= {
1027 /* IMS TURBO TV : card 5 */
1028 { 5,9, {00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 02, 00, 00, 00}}
1029
1030
1031};
1032
1033
1034/* debug utility for holding previous INT_STAT contents */
1035#define STATUS_SUM
1036static u_long status_sum = 0;
1037
1038/*
1039 * defines to make certain bit-fiddles understandable
1040 */
1041#define FIFO_ENABLED BT848_DMA_CTL_FIFO_EN
1042#define RISC_ENABLED BT848_DMA_CTL_RISC_EN
1043#define FIFO_RISC_ENABLED (BT848_DMA_CTL_FIFO_EN | BT848_DMA_CTL_RISC_EN)
1044#define FIFO_RISC_DISABLED 0
1045
1046#define ALL_INTS_DISABLED 0
1047#define ALL_INTS_CLEARED 0xffffffff
1048#define CAPTURE_OFF 0
1049
1050#define BIT_SEVEN_HIGH (1<<7)
1051#define BIT_EIGHT_HIGH (1<<8)
1052
1053#define I2C_BITS (BT848_INT_RACK | BT848_INT_I2CDONE)
1054#define TDEC_BITS (BT848_INT_FDSR | BT848_INT_FBUS)
1055
1056
1057/*
1058 * misc. support routines.
1059 */
1060static int signCard( bktr_ptr_t bktr, int offset,
1061 int count, u_char* sig );
1062static void probeCard( bktr_ptr_t bktr, int verbose );
1063
1064static vm_offset_t get_bktr_mem( int unit, unsigned size );
1065
1066static int oformat_meteor_to_bt( u_long format );
1067
1068static u_int pixfmt_swap_flags( int pixfmt );
1069
1070/*
1071 * bt848 RISC programming routines.
1072 */
1073#ifdef BT848_DUMP
1074static int dump_bt848( bt848_ptr_t bt848 );
1075#endif
1076
1077static void yuvpack_prog( bktr_ptr_t bktr, char i_flag, int cols,
1078 int rows, int interlace );
1079static void yuv422_prog( bktr_ptr_t bktr, char i_flag, int cols,
1080 int rows, int interlace );
1081static void yuv12_prog( bktr_ptr_t bktr, char i_flag, int cols,
1082 int rows, int interlace );
1083static void rgb_prog( bktr_ptr_t bktr, char i_flag, int cols,
1084 int rows, int interlace );
1085static void build_dma_prog( bktr_ptr_t bktr, char i_flag );
1086
1087static bool_t getline(bktr_reg_t *, int);
1088static bool_t notclipped(bktr_reg_t * , int , int);
1089static bool_t split(bktr_reg_t *, volatile u_long **, int, u_long, int,
1090 volatile u_char ** , int );
1091
1092/*
1093 * video & video capture specific routines.
1094 */
1095static int video_open( bktr_ptr_t bktr );
1096static int video_close( bktr_ptr_t bktr );
1097static int video_ioctl( bktr_ptr_t bktr, int unit,
1098 int cmd, caddr_t arg, struct proc* pr );
1099
1100static void start_capture( bktr_ptr_t bktr, unsigned type );
1101static void set_fps( bktr_ptr_t bktr, u_short fps );
1102
1103
1104/*
1105 * tuner specific functions.
1106 */
1107static int tuner_open( bktr_ptr_t bktr );
1108static int tuner_close( bktr_ptr_t bktr );
1109static int tuner_ioctl( bktr_ptr_t bktr, int unit,
1110 int cmd, caddr_t arg, struct proc* pr );
1111
1112static int tv_channel( bktr_ptr_t bktr, int channel );
1113static int tv_freq( bktr_ptr_t bktr, int frequency );
1114#if defined( TUNER_AFC )
1115static int do_afc( bktr_ptr_t bktr, int addr, int frequency );
1116#endif /* TUNER_AFC */
1117
1118
1119/*
1120 * audio specific functions.
1121 */
1122static int set_audio( bktr_ptr_t bktr, int mode );
1123static void temp_mute( bktr_ptr_t bktr, int flag );
1124static int set_BTSC( bktr_ptr_t bktr, int control );
1125
1126
1127/*
1128 * ioctls common to both video & tuner.
1129 */
1130static int common_ioctl( bktr_ptr_t bktr, bt848_ptr_t bt848,
1131 int cmd, caddr_t arg );
1132
1133
1134/*
1135 * i2c primitives
1136 */
1137static int i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 );
1138static int i2cRead( bktr_ptr_t bktr, int addr );
1139static int writeEEProm( bktr_ptr_t bktr, int offset, int count,
1140 u_char* data );
1141static int readEEProm( bktr_ptr_t bktr, int offset, int count,
1142 u_char* data );
1143
1144
1145#ifdef __FreeBSD__
1146/*
1147 * the boot time probe routine.
1148 */
1149static char*
1150bktr_probe( pcici_t tag, pcidi_t type )
1151{
1152 switch (type) {
1153 case BROOKTREE_848_ID:
1154 return("BrookTree 848");
1155 case BROOKTREE_849_ID:
1156 return("BrookTree 849");
1157 case BROOKTREE_878_ID:
1158 return("BrookTree 878");
1159 case BROOKTREE_879_ID:
1160 return("BrookTree 879");
1161 };
1162
1163 return ((char *)0);
1164}
1165#endif /* __FreeBSD__ */
1166
1167
1168
1169
1170/*
1171 * the attach routine.
1172 */
1173static void
1174bktr_attach( ATTACH_ARGS )
1175{
1176 bktr_ptr_t bktr;
1177 bt848_ptr_t bt848;
1178#ifdef BROOKTREE_IRQ
1179 u_long old_irq, new_irq;
1180#endif
1181 vm_offset_t buf;
1182 u_long latency;
1183 u_long fun;
1184
1185
1186#ifdef __FreeBSD__
1187 bktr = &brooktree[unit];
1188
1189 if (unit >= NBKTR) {
1190 printf("brooktree%d: attach: only %d units configured.\n",
1191 unit, NBKTR);
1192 printf("brooktree%d: attach: invalid unit number.\n", unit);
1193 return;
1194 }
1195
1196 bktr->tag = tag;
1197 pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base,
1198 &bktr->phys_base );
1199 fun = pci_conf_read(tag, 0x40);
1200 pci_conf_write(tag, 0x40, fun | 1);
1201
1202
1203#ifdef BROOKTREE_IRQ /* from the configuration file */
1204 old_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
1205 pci_conf_write(tag, PCI_INTERRUPT_REG, BROOKTREE_IRQ);
1206 new_irq = pci_conf_read(tag, PCI_INTERRUPT_REG);
1207 printf("bktr%d: attach: irq changed from %d to %d\n",
1208 unit, (old_irq & 0xff), (new_irq & 0xff));
1209#endif
1210 /* setup the interrupt handling routine */
1211 pci_map_int(tag, bktr_intr, (void*) bktr, &net_imask);
1212#endif /* __FreeBSD__ */
1213
1214#ifdef __bsdi__
1215 struct isa_attach_args * const ia = (struct isa_attach_args *)aux;
1216 pci_devaddr_t *tag = (pci_devaddr_t *) ia->ia_aux;
1217 int unit = bktr->bktr_dev.dv_unit;
1218
1219 bktr = (bktr_reg_t *) self;
1220 bktr->base = (bt848_ptr_t) bktr_res.pci_vaddr;
1221 isa_establish(&bktr->bktr_id, &bktr->bktr_dev);
1222 bktr->bktr_ih.ih_fun = bktr_intr_returning_1;
1223 bktr->bktr_ih.ih_arg = (void *)bktr;
1224 intr_establish(ia->ia_irq, &bktr->bktr_ih, DV_DULL);
1225#endif /* __bsdi__ */
1226
1227/*
1228 * PCI latency timer. 32 is a good value for 4 bus mastering slots, if
1229 * you have more than four, then 16 would probably be a better value.
1230 */
1231#ifndef BROOKTREE_DEF_LATENCY_VALUE
1232#define BROOKTREE_DEF_LATENCY_VALUE 10
1233#endif
1234 latency = pci_conf_read(tag, PCI_LATENCY_TIMER);
1235 latency = (latency >> 8) & 0xff;
1236 if ( bootverbose ) {
1237 if (latency)
1238 printf("brooktree%d: PCI bus latency is", unit);
1239 else
1240 printf("brooktree%d: PCI bus latency was 0 changing to",
1241 unit);
1242 }
1243 if ( !latency ) {
1244 latency = BROOKTREE_DEF_LATENCY_VALUE;
1245 pci_conf_write(tag, PCI_LATENCY_TIMER, latency<<8);
1246 }
1247 if ( bootverbose ) {
1248 printf(" %d.\n", (int) latency);
1249 }
1250
1251
1252 /* allocate space for dma program */
1253 bktr->dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
1254 bktr->odd_dma_prog = get_bktr_mem(unit, DMA_PROG_ALLOC);
1255
1256 /* allocate space for pixel buffer */
1257 if ( BROOKTREE_ALLOC )
1258 buf = get_bktr_mem(unit, BROOKTREE_ALLOC);
1259 else
1260 buf = 0;
1261
1262 if ( bootverbose ) {
1263 printf("bktr%d: buffer size %d, addr 0x%x\n",
1264 unit, BROOKTREE_ALLOC, vtophys(buf));
1265 }
1266
1267 bktr->bigbuf = buf;
1268 bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
1269
1270 fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
1271 pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 2);
1272
1273 if ( buf != 0 ) {
1274 bzero((caddr_t) buf, BROOKTREE_ALLOC);
1275 buf = vtophys(buf);
1276 bktr->flags = METEOR_INITALIZED | METEOR_AUTOMODE |
1277 METEOR_DEV0 | METEOR_RGB16;
1278 bktr->dma_prog_loaded = FALSE;
1279 bktr->cols = 640;
1280 bktr->rows = 480;
1281 bktr->frames = 1; /* one frame */
1282 bktr->format = METEOR_GEO_RGB16;
1283 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1284 bktr->pixfmt_compat = TRUE;
1285 bt848 = bktr->base;
1286 bt848->int_mask = ALL_INTS_DISABLED;
1287 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
1288 }
1289
1290 /* save pci id */
1291 fun = pci_conf_read(tag, PCI_ID_REG);
1292 bktr->id = fun;
1293
1294
1295
1296 bktr->clr_on_start = FALSE;
1297 /* defaults for the tuner section of the card */
1298 bktr->tflags = TUNER_INITALIZED;
1299 bktr->tuner.frequency = 0;
1300 bktr->tuner.channel = 0;
1301 bktr->tuner.chnlset = DEFAULT_CHNLSET;
1302 bktr->audio_mux_select = 0;
1303 bktr->audio_mute_state = FALSE;
1304 bktr->bt848_card = -1;
1305 bktr->bt848_tuner = -1;
1306 bktr->reverse_mute = -1;
1307
1308 probeCard( bktr, TRUE );
1309
1310#ifdef DEVFS
1311 /* XXX This just throw away the token, which should probably be fixed when
1312 DEVFS is finally made really operational. */
1313 devfs_add_devswf(&bktr_cdevsw, unit, DV_CHR, 0, 0, 0444, "bktr%d", unit);
1314 devfs_add_devswf(&bktr_cdevsw, unit+16, DV_CHR, 0, 0, 0444, "tuner%d", unit);
1315#endif /* DEVFS */
1316#if __FreeBSD__ > 2
1317 fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
1318 pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 4);
1319#endif
1320
1321}
1322
1323
1324/*
1325 * interrupt handling routine complete bktr_read() if using interrupts.
1326 */
1327static void
1328bktr_intr( void *arg )
1329{
1330 bktr_ptr_t bktr;
1331 bt848_ptr_t bt848;
1332 u_long bktr_status;
1333 u_char dstatus;
1334 u_long field;
1335 u_long w_field;
1336 u_long req_field;
1337
1338 bktr = (bktr_ptr_t) arg;
1339 bt848 = bktr->base;
1340
1341 /*
1342 * check to see if any interrupts are unmasked on this device. If
1343 * none are, then we likely got here by way of being on a PCI shared
1344 * interrupt dispatch list.
1345 */
1346 if (bt848->int_mask == ALL_INTS_DISABLED)
1347 return; /* bail out now, before we do something we
1348 shouldn't */
1349
1350 if (!(bktr->flags & METEOR_OPEN)) {
1351 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
1352 bt848->int_mask = ALL_INTS_DISABLED;
1353 /* return; ?? */
1354 }
1355
1356 /* record and clear the INTerrupt status bits */
1357 bktr_status = bt848->int_stat;
1358 bt848->int_stat = bktr_status & ~I2C_BITS; /* don't touch i2c */
1359
1360 /* record and clear the device status register */
1361 dstatus = bt848->dstatus;
1362 bt848->dstatus = 0x00;
1363
1364#if defined( STATUS_SUM )
1365 /* add any new device status or INTerrupt status bits */
1366 status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
1367 status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
1368#endif /* STATUS_SUM */
1369 /* printf( " STATUS %x %x %x \n",
1370 dstatus, bktr_status, bt848->risc_count );
1371 */
1372 /* if risc was disabled re-start process again */
1373 if ( !(bktr_status & BT848_INT_RISC_EN) ||
1374 ((bktr_status &(BT848_INT_FBUS |
1375 BT848_INT_FTRGT |
1376 BT848_INT_FDSR |
1377 BT848_INT_PPERR |
1378 BT848_INT_RIPERR |
1379 BT848_INT_PABORT |
1380 BT848_INT_OCERR |
1381 BT848_INT_SCERR) ) != 0) ||
1382 ((bt848->tdec == 0) && (bktr_status & TDEC_BITS)) ) {
1383
1384 u_short tdec_save = bt848->tdec;
1385
1386 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
1387
1388 bt848->int_mask = ALL_INTS_DISABLED;
1389
1390 /* Reset temporal decimation ctr */
1391 bt848->tdec = 0;
1392 bt848->tdec = tdec_save;
1393
1394 /* Reset to no-fields captured state */
1395 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
1396 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1397 case METEOR_ONLY_ODD_FIELDS:
1398 bktr->flags |= METEOR_WANT_ODD;
1399 break;
1400 case METEOR_ONLY_EVEN_FIELDS:
1401 bktr->flags |= METEOR_WANT_EVEN;
1402 break;
1403 default:
1404 bktr->flags |= METEOR_WANT_MASK;
1405 break;
1406 }
1407 }
1408
1409 bt848->risc_strt_add = vtophys(bktr->dma_prog);
1410 bt848->gpio_dma_ctl = FIFO_ENABLED;
1411 bt848->gpio_dma_ctl = bktr->capcontrol;
1412
1413 bt848->int_mask = BT848_INT_MYSTERYBIT |
1414 BT848_INT_RISCI |
1415 BT848_INT_VSYNC |
1416 BT848_INT_FMTCHG;
1417
1418 bt848->cap_ctl = bktr->bktr_cap_ctl;
1419
1420 return;
1421 }
1422
1423 if (!(bktr_status & BT848_INT_RISCI))
1424 return;
1425/**
1426 printf( "intr status %x %x %x\n",
1427 bktr_status, dstatus, bt848->risc_count );
1428 */
1429
1430 /*
1431 * Disable future interrupts if a capture mode is not selected.
1432 * This can happen when we are in the process of closing or
1433 * changing capture modes, otherwise it shouldn't happen.
1434 */
1435 if (!(bktr->flags & METEOR_CAP_MASK))
1436 bt848->cap_ctl = CAPTURE_OFF;
1437
1438 /*
1439 * Register the completed field
1440 * (For dual-field mode, require fields from the same frame)
1441 */
1442 field = ( bktr_status & BT848_INT_FIELD ) ? EVEN_F : ODD_F;
1443 switch ( bktr->flags & METEOR_WANT_MASK ) {
1444 case METEOR_WANT_ODD : w_field = ODD_F ; break;
1445 case METEOR_WANT_EVEN : w_field = EVEN_F ; break;
1446 default : w_field = (ODD_F|EVEN_F); break;
1447 }
1448 switch ( bktr->flags & METEOR_ONLY_FIELDS_MASK ) {
1449 case METEOR_ONLY_ODD_FIELDS : req_field = ODD_F ; break;
1450 case METEOR_ONLY_EVEN_FIELDS : req_field = EVEN_F ; break;
1451 default : req_field = (ODD_F|EVEN_F);
1452 break;
1453 }
1454
1455 if (( field == EVEN_F ) && ( w_field == EVEN_F ))
1456 bktr->flags &= ~METEOR_WANT_EVEN;
1457 else if (( field == ODD_F ) && ( req_field == ODD_F ) &&
1458 ( w_field == ODD_F ))
1459 bktr->flags &= ~METEOR_WANT_ODD;
1460 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
1461 ( w_field == (ODD_F|EVEN_F) ))
1462 bktr->flags &= ~METEOR_WANT_ODD;
1463 else if (( field == ODD_F ) && ( req_field == (ODD_F|EVEN_F) ) &&
1464 ( w_field == ODD_F )) {
1465 bktr->flags &= ~METEOR_WANT_ODD;
1466 bktr->flags |= METEOR_WANT_EVEN;
1467 }
1468 else {
1469 /* We're out of sync. Start over. */
1470 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
1471 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1472 case METEOR_ONLY_ODD_FIELDS:
1473 bktr->flags |= METEOR_WANT_ODD;
1474 break;
1475 case METEOR_ONLY_EVEN_FIELDS:
1476 bktr->flags |= METEOR_WANT_EVEN;
1477 break;
1478 default:
1479 bktr->flags |= METEOR_WANT_MASK;
1480 break;
1481 }
1482 }
1483 return;
1484 }
1485
1486 /*
1487 * If we have a complete frame.
1488 */
1489 if (!(bktr->flags & METEOR_WANT_MASK)) {
1490 bktr->frames_captured++;
1491 /*
1492 * post the completion time.
1493 */
1494 if (bktr->flags & METEOR_WANT_TS) {
1495 struct timeval *ts;
1496
1497 if ((u_int) bktr->alloc_pages * PAGE_SIZE
1498 <= (bktr->frame_size + sizeof(struct timeval))) {
1499 ts =(struct timeval *)bktr->bigbuf +
1500 bktr->frame_size;
1501 /* doesn't work in synch mode except
1502 * for first frame */
1503 /* XXX */
1504 microtime(ts);
1505 }
1506 }
1507
1508 /*
1509 * Wake up the user in single capture mode.
1510 */
1511 if (bktr->flags & METEOR_SINGLE) {
1512
1513 /* stop dma */
1514 bt848->int_mask = ALL_INTS_DISABLED;
1515
1516 /* disable risc, leave fifo running */
1517 bt848->gpio_dma_ctl = FIFO_ENABLED;
1518 wakeup((caddr_t)bktr);
1519 }
1520
1521 /*
1522 * If the user requested to be notified via signal,
1523 * let them know the frame is complete.
1524 */
1525
1526 if (bktr->proc && !(bktr->signal & METEOR_SIG_MODE_MASK))
1527 psignal( bktr->proc,
1528 bktr->signal&(~METEOR_SIG_MODE_MASK) );
1529
1530 /*
1531 * Reset the want flags if in continuous or
1532 * synchronous capture mode.
1533 */
1534/*
1535* XXX NOTE (Luigi):
1536* currently we only support 3 capture modes: odd only, even only,
1537* odd+even interlaced (odd field first). A fourth mode (non interlaced,
1538* either even OR odd) could provide 60 (50 for PAL) pictures per
1539* second, but it would require this routine to toggle the desired frame
1540* each time, and one more different DMA program for the Bt848.
1541* As a consequence, this fourth mode is currently unsupported.
1542*/
1543
1544 if (bktr->flags & (METEOR_CONTIN | METEOR_SYNCAP)) {
1545 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
1546 case METEOR_ONLY_ODD_FIELDS:
1547 bktr->flags |= METEOR_WANT_ODD;
1548 break;
1549 case METEOR_ONLY_EVEN_FIELDS:
1550 bktr->flags |= METEOR_WANT_EVEN;
1551 break;
1552 default:
1553 bktr->flags |= METEOR_WANT_MASK;
1554 break;
1555 }
1556 }
1557 }
1558
1559 return;
1560}
1561
1562
1563/*---------------------------------------------------------
1564**
1565** BrookTree 848 character device driver routines
1566**
1567**---------------------------------------------------------
1568*/
1569
1570
1571#define VIDEO_DEV 0x00
1572#define TUNER_DEV 0x01
1573
1574/*
1575 *
1576 */
1577int
1578bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
1579{
1580 bktr_ptr_t bktr;
1581 int unit;
1582
1583 unit = UNIT( minor(dev) );
1584 if (unit >= NBKTR) /* unit out of range */
1585 return( ENXIO );
1586
1587 bktr = &(brooktree[ unit ]);
1588
1589 if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
1590 return( ENXIO );
1591
1592
1593 if (bt848_card != -1) {
1594 if ((bt848_card >> 8 == unit ) &&
1595 ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
1596 if ( bktr->bt848_card != (bt848_card & 0xff) ) {
1597 bktr->bt848_card = (bt848_card & 0xff);
1598 probeCard(bktr, FALSE);
1599 }
1600 }
1601 }
1602
1603 if (bt848_tuner != -1) {
1604 if ((bt848_tuner >> 8 == unit ) &&
1605 ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
1606 if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
1607 bktr->bt848_tuner = (bt848_tuner & 0xff);
1608 probeCard(bktr, FALSE);
1609 }
1610 }
1611 }
1612
1613 if (bt848_reverse_mute != -1) {
1614 if (((bt848_reverse_mute >> 8) == unit ) &&
1615 ((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) {
1616 bktr->reverse_mute = bt848_reverse_mute & 0xff;
1617 bt848_reverse_mute = -1;
1618 }
1619 }
1620
1621
1622 switch ( MINOR( minor(dev) ) ) {
1623 case VIDEO_DEV:
1624 return( video_open( bktr ) );
1625
1626 case TUNER_DEV:
1627 return( tuner_open( bktr ) );
1628 }
1629
1630 return( ENXIO );
1631}
1632
1633
1634/*
1635 *
1636 */
1637static int
1638video_open( bktr_ptr_t bktr )
1639{
1640 bt848_ptr_t bt848;
1641 int frame_rate, video_format=0;
1642
1643 if (bktr->flags & METEOR_OPEN) /* device is busy */
1644 return( EBUSY );
1645
1646 bktr->flags |= METEOR_OPEN;
1647
1648 bt848 = bktr->base;
1649
1650#ifdef BT848_DUMP
1651 dump_bt848( bt848 );
1652#endif
1653
1654 bktr->clr_on_start = FALSE;
1655
1656 bt848->dstatus = 0x00; /* clear device status reg. */
1657
1658 bt848->adc = SYNC_LEVEL;
1659
1660#if BROOKTREE_SYSTEM_DEFAULT == BROOKTREE_PAL
1661 video_format = 0;
1662#else
1663 video_format = 1;
1664#endif
1665
1666 if (bt848_format == 0 )
1667 video_format = 0;
1668
1669 if (bt848_format == 1 )
1670 video_format = 1;
1671
1672 if (video_format == 1 ) {
1673 bt848->iform = BT848_IFORM_M_MUX1 |
1674 BT848_IFORM_X_XT0 |
1675 BT848_IFORM_F_NTSCM;
1676 bktr->format_params = BT848_IFORM_F_NTSCM;
1677
1678 } else {
1679 bt848->iform = BT848_IFORM_M_MUX1 |
1680 BT848_IFORM_X_XT1 |
1681 BT848_IFORM_F_PALBDGHI;
1682 bktr->format_params = BT848_IFORM_F_PALBDGHI;
1683
1684 }
1685
1686 bt848->adelay = format_params[bktr->format_params].adelay;
1687 bt848->bdelay = format_params[bktr->format_params].bdelay;
1688 frame_rate = format_params[bktr->format_params].frame_rate;
1689
1690#ifdef BKTR_USE_PLL
1691 bt848->tgctrl=0;
1692 bt848->pll_f_lo=0xf9;
1693 bt848->pll_f_hi=0xdc;
1694 bt848->pll_f_xci=0x8e;
1695#endif
1696
1697 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
1698
1699 bktr->max_clip_node = 0;
1700
1701 bt848->color_ctl_gamma = 1;
1702 bt848->color_ctl_rgb_ded = 1;
1703 bt848->color_ctl_color_bars = 0;
1704 bt848->color_ctl_ext_frmrate = 0;
1705 bt848->color_ctl_swap = 0;
1706
1707 bt848->e_hscale_lo = 170;
1708 bt848->o_hscale_lo = 170;
1709
1710 bt848->e_delay_lo = 0x72;
1711 bt848->o_delay_lo = 0x72;
1712 bt848->e_scloop = 0;
1713 bt848->o_scloop = 0;
1714
1715 bt848->vbi_pack_size = 0;
1716 bt848->vbi_pack_del = 0;
1717
1718 bktr->fifo_errors = 0;
1719 bktr->dma_errors = 0;
1720 bktr->frames_captured = 0;
1721 bktr->even_fields_captured = 0;
1722 bktr->odd_fields_captured = 0;
1723 bktr->proc = (struct proc *)0;
1724 set_fps(bktr, frame_rate);
1725 bktr->video.addr = 0;
1726 bktr->video.width = 0;
1727 bktr->video.banksize = 0;
1728 bktr->video.ramsize = 0;
1729 bktr->pixfmt_compat = TRUE;
1730 bktr->format = METEOR_GEO_RGB16;
1731 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
1732
1733 bktr->capture_area_enabled = FALSE;
1734
1735 bt848->int_mask = BT848_INT_MYSTERYBIT; /* if you take this out triton
1736 based motherboards will
1737 operate unreliably */
1738 return( 0 );
1739}
1740
1741
1742/*
1743 *
1744 */
1745static int
1746tuner_open( bktr_ptr_t bktr )
1747{
1748 if ( !(bktr->tflags & TUNER_INITALIZED) ) /* device not found */
1749 return( ENXIO );
1750
1751 if ( bktr->tflags & TUNER_OPEN ) /* already open */
1752 return( 0 );
1753
1754 bktr->tflags |= TUNER_OPEN;
1755 bktr->tuner.radio_mode = 0;
1756
1757 /* enable drivers on the GPIO port that control the MUXes */
1758 bktr->base->gpio_out_en = GPIO_AUDIOMUX_BITS;
1759
1760 /* unmute the audio stream */
1761 set_audio( bktr, AUDIO_UNMUTE );
1762
1763 /* enable stereo if appropriate */
1764 if ( bktr->card.dbx )
1765 set_BTSC( bktr, 0 );
1766
1767 return( 0 );
1768}
1769
1770
1771/*
1772 *
1773 */
1774int
1775bktr_close( dev_t dev, int flags, int fmt, struct proc *p )
1776{
1777 bktr_ptr_t bktr;
1778 int unit;
1779
1780 unit = UNIT( minor(dev) );
1781 if (unit >= NBKTR) /* unit out of range */
1782 return( ENXIO );
1783
1784 bktr = &(brooktree[ unit ]);
1785
1786 switch ( MINOR( minor(dev) ) ) {
1787 case VIDEO_DEV:
1788 return( video_close( bktr ) );
1789
1790 case TUNER_DEV:
1791 return( tuner_close( bktr ) );
1792 }
1793
1794 return( ENXIO );
1795}
1796
1797
1798/*
1799 *
1800 */
1801static int
1802video_close( bktr_ptr_t bktr )
1803{
1804 bt848_ptr_t bt848;
1805
1806 bktr->flags &= ~(METEOR_OPEN |
1807 METEOR_SINGLE |
1808 METEOR_CAP_MASK |
1809 METEOR_WANT_MASK);
1810
1811 bt848 = bktr->base;
1812 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
1813 bt848->cap_ctl = CAPTURE_OFF;
1814
1815 bktr->dma_prog_loaded = FALSE;
1816 bt848->tdec = 0;
1817 bt848->int_mask = ALL_INTS_DISABLED;
1818
1819/** FIXME: is 0xf magic, wouldn't 0x00 work ??? */
1820 bt848->sreset = 0xf;
1821 bt848->int_stat = ALL_INTS_CLEARED;
1822
1823 return( 0 );
1824}
1825
1826
1827/*
1828 * tuner close handle,
1829 * place holder for tuner specific operations on a close.
1830 */
1831static int
1832tuner_close( bktr_ptr_t bktr )
1833{
1834 bktr->tflags &= ~TUNER_OPEN;
1835
1836 /* mute the audio by switching the mux */
1837 set_audio( bktr, AUDIO_MUTE );
1838
1839 /* disable drivers on the GPIO port that control the MUXes */
1840 bktr->base->gpio_out_en = 0;
1841
1842 return( 0 );
1843}
1844
1845
1846/*
1847 *
1848 */
1849int
1850bktr_read( dev_t dev, struct uio *uio, int ioflag )
1851{
1852 bktr_ptr_t bktr;
1853 bt848_ptr_t bt848;
1854 int unit;
1855 int status;
1856 int count;
1857
1858 if (MINOR(minor(dev)) > 0)
1859 return( ENXIO );
1860
1861 unit = UNIT(minor(dev));
1862 if (unit >= NBKTR) /* unit out of range */
1863 return( ENXIO );
1864
1865 bktr = &(brooktree[unit]);
1866 bt848 = bktr->base;
1867
1868 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1869 return( ENOMEM );
1870
1871 if (bktr->flags & METEOR_CAP_MASK)
1872 return( EIO ); /* already capturing */
1873
1874 bt848->cap_ctl = bktr->bktr_cap_ctl;
1875
1876
1877 count = bktr->rows * bktr->cols *
1878 pixfmt_table[ bktr->pixfmt ].public.Bpp;
1879
1880 if ((int) uio->uio_iov->iov_len < count)
1881 return( EINVAL );
1882
1883 bktr->flags &= ~(METEOR_CAP_MASK | METEOR_WANT_MASK);
1884
1885 /* capture one frame */
1886 start_capture(bktr, METEOR_SINGLE);
1887 /* wait for capture to complete */
1888 bt848->int_stat = ALL_INTS_CLEARED;
1889 bt848->gpio_dma_ctl = FIFO_ENABLED;
1890 bt848->gpio_dma_ctl = bktr->capcontrol;
1891 bt848->int_mask = BT848_INT_MYSTERYBIT |
1892 BT848_INT_RISCI |
1893 BT848_INT_VSYNC |
1894 BT848_INT_FMTCHG;
1895
1896
1897 status = tsleep((caddr_t)bktr, BKTRPRI, "captur", 0);
1898 if (!status) /* successful capture */
1899 status = uiomove((caddr_t)bktr->bigbuf, count, uio);
1900 else
1901 printf ("bktr%d: read: tsleep error %d\n", unit, status);
1902
1903 bktr->flags &= ~(METEOR_SINGLE | METEOR_WANT_MASK);
1904
1905 return( status );
1906}
1907
1908
1909/*
1910 *
1911 */
1912int
1913bktr_write( dev_t dev, struct uio *uio, int ioflag )
1914{
1915 return( EINVAL ); /* XXX or ENXIO ? */
1916}
1917
1918
1919/*
1920 *
1921 */
1922int
1923bktr_ioctl( dev_t dev, ioctl_cmd_t cmd, caddr_t arg, int flag, struct proc* pr )
1924{
1925 bktr_ptr_t bktr;
1926 int unit;
1927
1928 unit = UNIT(minor(dev));
1929 if (unit >= NBKTR) /* unit out of range */
1930 return( ENXIO );
1931
1932 bktr = &(brooktree[ unit ]);
1933
1934 if (bktr->bigbuf == 0) /* no frame buffer allocated (ioctl failed) */
1935 return( ENOMEM );
1936
1937 switch ( MINOR( minor(dev) ) ) {
1938 case VIDEO_DEV:
1939 return( video_ioctl( bktr, unit, cmd, arg, pr ) );
1940
1941 case TUNER_DEV:
1942 return( tuner_ioctl( bktr, unit, cmd, arg, pr ) );
1943 }
1944
1945 return( ENXIO );
1946}
1947
1948
1949/*
1950 * video ioctls
1951 */
1952static int
1953video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
1954{
1955 int tmp_int;
1956 bt848_ptr_t bt848;
1957 volatile u_char c_temp;
1958 unsigned int temp;
1959 unsigned int temp_iform;
1960 unsigned int error;
1961 struct meteor_geomet *geo;
1962 struct meteor_counts *cnt;
1963 struct meteor_video *video;
1964 struct bktr_capture_area *cap_area;
1965 vm_offset_t buf;
1966 struct format_params *fp;
1967 int i;
1968 char char_temp;
1969
1970 bt848 = bktr->base;
1971
1972 switch ( cmd ) {
1973
1974 case BT848SCLIP: /* set clip region */
1975 bktr->max_clip_node = 0;
1976 memcpy(&bktr->clip_list, arg, sizeof(bktr->clip_list));
1977
1978 for (i = 0; i < BT848_MAX_CLIP_NODE; i++) {
1979 if (bktr->clip_list[i].y_min == 0 &&
1980 bktr->clip_list[i].y_max == 0)
1981 break;
1982 }
1983 bktr->max_clip_node = i;
1984
1985 /* make sure that the list contains a valid clip secquence */
1986 /* the clip rectangles should be sorted by x then by y as the
1987 second order sort key */
1988
1989 /* clip rectangle list is terminated by y_min and y_max set to 0 */
1990
1991 /* to disable clipping set y_min and y_max to 0 in the first
1992 clip rectangle . The first clip rectangle is clip_list[0].
1993 */
1994
1995
1996
1997 if (bktr->max_clip_node == 0 &&
1998 (bktr->clip_list[0].y_min != 0 &&
1999 bktr->clip_list[0].y_max != 0)) {
2000 return EINVAL;
2001 }
2002
2003 for (i = 0; i < BT848_MAX_CLIP_NODE - 1 ; i++) {
2004 if (bktr->clip_list[i].y_min == 0 &&
2005 bktr->clip_list[i].y_max == 0) {
2006 break;
2007 }
2008 if ( bktr->clip_list[i+1].y_min != 0 &&
2009 bktr->clip_list[i+1].y_max != 0 &&
2010 bktr->clip_list[i].x_min > bktr->clip_list[i+1].x_min ) {
2011
2012 bktr->max_clip_node = 0;
2013 return (EINVAL);
2014
2015 }
2016
2017 if (bktr->clip_list[i].x_min >= bktr->clip_list[i].x_max ||
2018 bktr->clip_list[i].y_min >= bktr->clip_list[i].y_max ||
2019 bktr->clip_list[i].x_min < 0 ||
2020 bktr->clip_list[i].x_max < 0 ||
2021 bktr->clip_list[i].y_min < 0 ||
2022 bktr->clip_list[i].y_max < 0 ) {
2023 bktr->max_clip_node = 0;
2024 return (EINVAL);
2025 }
2026 }
2027
2028 bktr->dma_prog_loaded = FALSE;
2029
2030 break;
2031
2032 case METEORSTATUS: /* get Bt848 status */
2033 c_temp = bt848->dstatus;
2034 temp = 0;
2035 if (!(c_temp & 0x40)) temp |= METEOR_STATUS_HCLK;
2036 if (!(c_temp & 0x10)) temp |= METEOR_STATUS_FIDT;
2037 *(u_short *)arg = temp;
2038 break;
2039
2040 case BT848SFMT: /* set input format */
2041 temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
2042 temp_iform = bt848->iform;
2043 temp_iform &= ~BT848_IFORM_FORMAT;
2044 temp_iform &= ~BT848_IFORM_XTSEL;
2045 bt848->iform = (temp_iform | temp | format_params[temp].iform_xtsel);
2046 switch( temp ) {
2047 case BT848_IFORM_F_AUTO:
2048 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
2049 METEOR_AUTOMODE;
2050 break;
2051
2052 case BT848_IFORM_F_NTSCM:
2053 case BT848_IFORM_F_NTSCJ:
2054 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
2055 METEOR_NTSC;
2056 bt848->adelay = format_params[temp].adelay;
2057 bt848->bdelay = format_params[temp].bdelay;
2058 bktr->format_params = temp;
2059 break;
2060
2061 case BT848_IFORM_F_PALBDGHI:
2062 case BT848_IFORM_F_PALN:
2063 case BT848_IFORM_F_SECAM:
2064 case BT848_IFORM_F_RSVD:
2065 case BT848_IFORM_F_PALM:
2066 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
2067 METEOR_PAL;
2068 bt848->adelay = format_params[temp].adelay;
2069 bt848->bdelay = format_params[temp].bdelay;
2070 bktr->format_params = temp;
2071 break;
2072
2073 }
2074 bktr->dma_prog_loaded = FALSE;
2075 break;
2076
2077 case METEORSFMT: /* set input format */
2078 temp_iform = bt848->iform;
2079 temp_iform &= ~BT848_IFORM_FORMAT;
2080 temp_iform &= ~BT848_IFORM_XTSEL;
2081 switch(*(unsigned long *)arg & METEOR_FORM_MASK ) {
2082 case 0: /* default */
2083 case METEOR_FMT_NTSC:
2084 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
2085 METEOR_NTSC;
2086 bt848->iform = temp_iform | BT848_IFORM_F_NTSCM |
2087 format_params[BT848_IFORM_F_NTSCM].iform_xtsel;
2088 bt848->adelay = format_params[BT848_IFORM_F_NTSCM].adelay;
2089 bt848->bdelay = format_params[BT848_IFORM_F_NTSCM].bdelay;
2090 bktr->format_params = BT848_IFORM_F_NTSCM;
2091 break;
2092
2093 case METEOR_FMT_PAL:
2094 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
2095 METEOR_PAL;
2096 bt848->iform = temp_iform | BT848_IFORM_F_PALBDGHI |
2097 format_params[BT848_IFORM_F_PALBDGHI].iform_xtsel;
2098 bt848->adelay = format_params[BT848_IFORM_F_PALBDGHI].adelay;
2099 bt848->bdelay = format_params[BT848_IFORM_F_PALBDGHI].bdelay;
2100 bktr->format_params = BT848_IFORM_F_PALBDGHI;
2101 break;
2102
2103 case METEOR_FMT_AUTOMODE:
2104 bktr->flags = (bktr->flags & ~METEOR_FORM_MASK) |
2105 METEOR_AUTOMODE;
2106 bt848->iform = temp_iform | BT848_IFORM_F_AUTO |
2107 format_params[BT848_IFORM_F_AUTO].iform_xtsel;
2108 break;
2109
2110 default:
2111 return( EINVAL );
2112 }
2113 bktr->dma_prog_loaded = FALSE;
2114 break;
2115
2116 case METEORGFMT: /* get input format */
2117 *(u_long *)arg = bktr->flags & METEOR_FORM_MASK;
2118 break;
2119
2120
2121 case BT848GFMT: /* get input format */
2122 *(u_long *)arg = bt848->iform & BT848_IFORM_FORMAT;
2123 break;
2124
2125 case METEORSCOUNT: /* (re)set error counts */
2126 cnt = (struct meteor_counts *) arg;
2127 bktr->fifo_errors = cnt->fifo_errors;
2128 bktr->dma_errors = cnt->dma_errors;
2129 bktr->frames_captured = cnt->frames_captured;
2130 bktr->even_fields_captured = cnt->even_fields_captured;
2131 bktr->odd_fields_captured = cnt->odd_fields_captured;
2132 break;
2133
2134 case METEORGCOUNT: /* get error counts */
2135 cnt = (struct meteor_counts *) arg;
2136 cnt->fifo_errors = bktr->fifo_errors;
2137 cnt->dma_errors = bktr->dma_errors;
2138 cnt->frames_captured = bktr->frames_captured;
2139 cnt->even_fields_captured = bktr->even_fields_captured;
2140 cnt->odd_fields_captured = bktr->odd_fields_captured;
2141 break;
2142
2143 case METEORGVIDEO:
2144 video = (struct meteor_video *)arg;
2145 video->addr = bktr->video.addr;
2146 video->width = bktr->video.width;
2147 video->banksize = bktr->video.banksize;
2148 video->ramsize = bktr->video.ramsize;
2149 break;
2150
2151 case METEORSVIDEO:
2152 video = (struct meteor_video *)arg;
2153 bktr->video.addr = video->addr;
2154 bktr->video.width = video->width;
2155 bktr->video.banksize = video->banksize;
2156 bktr->video.ramsize = video->ramsize;
2157 break;
2158
2159 case METEORSFPS:
2160 set_fps(bktr, *(u_short *)arg);
2161 break;
2162
2163 case METEORGFPS:
2164 *(u_short *)arg = bktr->fps;
2165 break;
2166
2167 case METEORSHUE: /* set hue */
2168 bt848->hue = (*(u_char *) arg) & 0xff;
2169 break;
2170
2171 case METEORGHUE: /* get hue */
2172 *(u_char *)arg = bt848->hue;
2173 break;
2174
2175 case METEORSBRIG: /* set brightness */
2176 char_temp = ( *(u_char *)arg & 0xff) - 128;
2177 bt848->bright = char_temp;
2178
2179 break;
2180
2181 case METEORGBRIG: /* get brightness */
2182 *(u_char *)arg = bt848->bright;
2183 break;
2184
2185 case METEORSCSAT: /* set chroma saturation */
2186 temp = (int)*(u_char *)arg;
2187
2188 bt848->sat_u_lo = bt848->sat_v_lo = (temp << 1) & 0xff;
2189
2190 bt848->e_control &= ~(BT848_E_CONTROL_SAT_U_MSB |
2191 BT848_E_CONTROL_SAT_V_MSB);
2192 bt848->o_control &= ~(BT848_O_CONTROL_SAT_U_MSB |
2193 BT848_O_CONTROL_SAT_V_MSB);
2194
2195 if ( temp & BIT_SEVEN_HIGH ) {
2196 bt848->e_control |= (BT848_E_CONTROL_SAT_U_MSB |
2197 BT848_E_CONTROL_SAT_V_MSB);
2198 bt848->o_control |= (BT848_O_CONTROL_SAT_U_MSB |
2199 BT848_O_CONTROL_SAT_V_MSB);
2200 }
2201 break;
2202
2203 case METEORGCSAT: /* get chroma saturation */
2204 temp = (bt848->sat_v_lo >> 1) & 0xff;
2205 if ( bt848->e_control & BT848_E_CONTROL_SAT_V_MSB )
2206 temp |= BIT_SEVEN_HIGH;
2207 *(u_char *)arg = (u_char)temp;
2208 break;
2209
2210 case METEORSCONT: /* set contrast */
2211 temp = (int)*(u_char *)arg & 0xff;
2212 temp <<= 1;
2213 bt848->contrast_lo = temp & 0xff;
2214 bt848->e_control &= ~BT848_E_CONTROL_CON_MSB;
2215 bt848->o_control &= ~BT848_O_CONTROL_CON_MSB;
2216 bt848->e_control |=
2217 ((temp & 0x100) >> 6 ) & BT848_E_CONTROL_CON_MSB;
2218 bt848->o_control |=
2219 ((temp & 0x100) >> 6 ) & BT848_O_CONTROL_CON_MSB;
2220 break;
2221
2222 case METEORGCONT: /* get contrast */
2223 temp = (int)bt848->contrast_lo & 0xff;
2224 temp |= ((int)bt848->o_control & 0x04) << 6;
2225 *(u_char *)arg = (u_char)((temp >> 1) & 0xff);
2226 break;
2227
2228 case BT848SCBUF: /* set Clear-Buffer-on-start flag */
2229 bktr->clr_on_start = (*(int *)arg != 0);
2230 break;
2231
2232 case BT848GCBUF: /* get Clear-Buffer-on-start flag */
2233 *(int *)arg = (int) bktr->clr_on_start;
2234 break;
2235
2236 case METEORSSIGNAL:
2237 if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
2238 return( EINVAL );
2239 break;
2240 }
2241 bktr->signal = *(int *) arg;
2242 bktr->proc = pr;
2243 break;
2244
2245 case METEORGSIGNAL:
2246 *(int *)arg = bktr->signal;
2247 break;
2248
2249 case METEORCAPTUR:
2250 temp = bktr->flags;
2251 switch (*(int *) arg) {
2252 case METEOR_CAP_SINGLE:
2253
2254 if (bktr->bigbuf==0) /* no frame buffer allocated */
2255 return( ENOMEM );
2256 /* already capturing */
2257 if (temp & METEOR_CAP_MASK)
2258 return( EIO );
2259
2260
2261
2262 start_capture(bktr, METEOR_SINGLE);
2263
2264 /* wait for capture to complete */
2265 bt848->int_stat = ALL_INTS_CLEARED;
2266 bt848->gpio_dma_ctl = FIFO_ENABLED;
2267 bt848->gpio_dma_ctl = bktr->capcontrol;
2268
2269 bt848->int_mask = BT848_INT_MYSTERYBIT |
2270 BT848_INT_RISCI |
2271 BT848_INT_VSYNC |
2272 BT848_INT_FMTCHG;
2273
2274 bt848->cap_ctl = bktr->bktr_cap_ctl;
2275 error = tsleep((caddr_t)bktr, BKTRPRI, "captur", hz);
2276 if (error && (error != ERESTART)) {
2277 /* Here if we didn't get complete frame */
2278#ifdef DIAGNOSTIC
2279 printf( "bktr%d: ioctl: tsleep error %d %x\n",
2280 unit, error, bt848->risc_count);
2281#endif
2282
2283 /* stop dma */
2284 bt848->int_mask = ALL_INTS_DISABLED;
2285
2286 /* disable risc, leave fifo running */
2287 bt848->gpio_dma_ctl = FIFO_ENABLED;
2288 }
2289
2290 bktr->flags &= ~(METEOR_SINGLE|METEOR_WANT_MASK);
2291 /* FIXME: should we set bt848->int_stat ??? */
2292 break;
2293
2294 case METEOR_CAP_CONTINOUS:
2295 if (bktr->bigbuf==0) /* no frame buffer allocated */
2296 return( ENOMEM );
2297 /* already capturing */
2298 if (temp & METEOR_CAP_MASK)
2299 return( EIO );
2300
2301
2302 start_capture(bktr, METEOR_CONTIN);
2303 bt848->int_stat = bt848->int_stat;
2304
2305 bt848->gpio_dma_ctl = FIFO_ENABLED;
2306 bt848->gpio_dma_ctl = bktr->capcontrol;
2307 bt848->cap_ctl = bktr->bktr_cap_ctl;
2308
2309 bt848->int_mask = BT848_INT_MYSTERYBIT |
2310 BT848_INT_RISCI |
2311 BT848_INT_VSYNC |
2312 BT848_INT_FMTCHG;
2313#ifdef BT848_DUMP
2314 dump_bt848( bt848 );
2315#endif
2316 break;
2317
2318 case METEOR_CAP_STOP_CONT:
2319 if (bktr->flags & METEOR_CONTIN) {
2320 /* turn off capture */
2321 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
2322 bt848->cap_ctl = CAPTURE_OFF;
2323 bt848->int_mask = ALL_INTS_DISABLED;
2324 bktr->flags &=
2325 ~(METEOR_CONTIN | METEOR_WANT_MASK);
2326
2327 }
2328 }
2329 break;
2330
2331 case METEORSETGEO:
2332 /* can't change parameters while capturing */
2333 if (bktr->flags & METEOR_CAP_MASK)
2334 return( EBUSY );
2335
2336
2337 geo = (struct meteor_geomet *) arg;
2338
2339 error = 0;
2340 /* Either even or odd, if even & odd, then these a zero */
2341 if ((geo->oformat & METEOR_GEO_ODD_ONLY) &&
2342 (geo->oformat & METEOR_GEO_EVEN_ONLY)) {
2343 printf( "bktr%d: ioctl: Geometry odd or even only.\n",
2344 unit);
2345 return( EINVAL );
2346 }
2347
2348 /* set/clear even/odd flags */
2349 if (geo->oformat & METEOR_GEO_ODD_ONLY)
2350 bktr->flags |= METEOR_ONLY_ODD_FIELDS;
2351 else
2352 bktr->flags &= ~METEOR_ONLY_ODD_FIELDS;
2353 if (geo->oformat & METEOR_GEO_EVEN_ONLY)
2354 bktr->flags |= METEOR_ONLY_EVEN_FIELDS;
2355 else
2356 bktr->flags &= ~METEOR_ONLY_EVEN_FIELDS;
2357
2358 if ((geo->columns & 0x3fe) != geo->columns) {
2359 printf(
2360 "bktr%d: ioctl: %d: columns too large or not even.\n",
2361 unit, geo->columns);
2362 error = EINVAL;
2363 }
2364 if (((geo->rows & 0x7fe) != geo->rows) ||
2365 ((geo->oformat & METEOR_GEO_FIELD_MASK) &&
2366 ((geo->rows & 0x3fe) != geo->rows)) ) {
2367 printf(
2368 "bktr%d: ioctl: %d: rows too large or not even.\n",
2369 unit, geo->rows);
2370 error = EINVAL;
2371 }
2372 if (geo->frames > 32) {
2373 printf("bktr%d: ioctl: too many frames.\n", unit);
2374
2375 error = EINVAL;
2376 }
2377
2378 if (error)
2379 return( error );
2380
2381 bktr->dma_prog_loaded = FALSE;
2382 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
2383
2384 bt848->int_mask = ALL_INTS_DISABLED;
2385
2386 if ((temp=(geo->rows * geo->columns * geo->frames * 2))) {
2387 if (geo->oformat & METEOR_GEO_RGB24) temp = temp * 2;
2388
2389 /* meteor_mem structure for SYNC Capture */
2390 if (geo->frames > 1) temp += PAGE_SIZE;
2391
2392 temp = btoc(temp);
2393 if ((int) temp > bktr->alloc_pages
2394 && bktr->video.addr == 0) {
2395 buf = get_bktr_mem(unit, temp*PAGE_SIZE);
2396 if (buf != 0) {
2397 kmem_free(kernel_map, bktr->bigbuf,
2398 (bktr->alloc_pages * PAGE_SIZE));
2399 bktr->bigbuf = buf;
2400 bktr->alloc_pages = temp;
2401 if (bootverbose)
2402 printf(
2403 "bktr%d: ioctl: Allocating %d bytes\n",
2404 unit, temp*PAGE_SIZE);
2405 }
2406 else
2407 error = ENOMEM;
2408 }
2409 }
2410
2411 if (error)
2412 return error;
2413
2414 bktr->rows = geo->rows;
2415 bktr->cols = geo->columns;
2416 bktr->frames = geo->frames;
2417
2418 /* Pixel format (if in meteor pixfmt compatibility mode) */
2419 if ( bktr->pixfmt_compat ) {
2420 bktr->format = METEOR_GEO_YUV_422;
2421 switch (geo->oformat & METEOR_GEO_OUTPUT_MASK) {
2422 case 0: /* default */
2423 case METEOR_GEO_RGB16:
2424 bktr->format = METEOR_GEO_RGB16;
2425 break;
2426 case METEOR_GEO_RGB24:
2427 bktr->format = METEOR_GEO_RGB24;
2428 break;
2429 case METEOR_GEO_YUV_422:
2430 bktr->format = METEOR_GEO_YUV_422;
2431 if (geo->oformat & METEOR_GEO_YUV_12)
2432 bktr->format = METEOR_GEO_YUV_12;
2433 break;
2434 case METEOR_GEO_YUV_PACKED:
2435 bktr->format = METEOR_GEO_YUV_PACKED;
2436 break;
2437 }
2438 bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
2439 }
2440
2441 if (bktr->flags & METEOR_CAP_MASK) {
2442
2443 if (bktr->flags & (METEOR_CONTIN|METEOR_SYNCAP)) {
2444 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
2445 case METEOR_ONLY_ODD_FIELDS:
2446 bktr->flags |= METEOR_WANT_ODD;
2447 break;
2448 case METEOR_ONLY_EVEN_FIELDS:
2449 bktr->flags |= METEOR_WANT_EVEN;
2450 break;
2451 default:
2452 bktr->flags |= METEOR_WANT_MASK;
2453 break;
2454 }
2455
2456 start_capture(bktr, METEOR_CONTIN);
2457 bt848->int_stat = bt848->int_stat;
2458 bt848->gpio_dma_ctl = FIFO_ENABLED;
2459 bt848->gpio_dma_ctl = bktr->capcontrol;
2460 bt848->int_mask = BT848_INT_MYSTERYBIT |
2461 BT848_INT_VSYNC |
2462 BT848_INT_FMTCHG;
2463 }
2464 }
2465 break;
2466 /* end of METEORSETGEO */
2467
2468 /* FIXME. The Capture Area currently has the following restrictions:
2469 GENERAL
2470 y_offset may need to be even in interlaced modes
2471 RGB24 - Interlaced mode
2472 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
2473 y_size must be greater than or equal to METEORSETGEO height (rows)
2474 RGB24 - Even Only (or Odd Only) mode
2475 x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
2476 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
2477 YUV12 - Interlaced mode
2478 x_size must be greater than or equal to METEORSETGEO width (cols)
2479 y_size must be greater than or equal to METEORSETGEO height (rows)
2480 YUV12 - Even Only (or Odd Only) mode
2481 x_size must be greater than or equal to METEORSETGEO width (cols)
2482 y_size must be greater than or equal to 2*METEORSETGEO height (rows)
2483 */
2484
2485 case BT848_SCAPAREA: /* set capture area of each video frame */
2486 /* can't change parameters while capturing */
2487 if (bktr->flags & METEOR_CAP_MASK)
2488 return( EBUSY );
2489
2490 cap_area = (struct bktr_capture_area *) arg;
2491 bktr->capture_area_x_offset = cap_area->x_offset;
2492 bktr->capture_area_y_offset = cap_area->y_offset;
2493 bktr->capture_area_x_size = cap_area->x_size;
2494 bktr->capture_area_y_size = cap_area->y_size;
2495 bktr->capture_area_enabled = TRUE;
2496
2497 bktr->dma_prog_loaded = FALSE;
2498 break;
2499
2500 case BT848_GCAPAREA: /* get capture area of each video frame */
2501 cap_area = (struct bktr_capture_area *) arg;
2502 if (bktr->capture_area_enabled == FALSE) {
2503 cap_area->x_offset = 0;
2504 cap_area->y_offset = 0;
2505 cap_area->x_size = format_params[
2506 bktr->format_params].scaled_hactive;
2507 cap_area->y_size = format_params[
2508 bktr->format_params].vactive;
2509 } else {
2510 cap_area->x_offset = bktr->capture_area_x_offset;
2511 cap_area->y_offset = bktr->capture_area_y_offset;
2512 cap_area->x_size = bktr->capture_area_x_size;
2513 cap_area->y_size = bktr->capture_area_y_size;
2514 }
2515 break;
2516
2517 default:
2518 return common_ioctl( bktr, bt848, cmd, arg );
2519 }
2520
2521 return( 0 );
2522}
2523
2524/*
2525 * tuner ioctls
2526 */
2527static int
2528tuner_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
2529{
2530 bt848_ptr_t bt848;
2531 int tmp_int;
2532 unsigned int temp, temp1;
2533 int offset;
2534 int count;
2535 u_char *buf;
2536 u_long par;
2537 u_char write;
2538 int i2c_addr;
2539 int i2c_port;
2540 u_long data;
2541
2542 bt848 = bktr->base;
2543
2544 switch ( cmd ) {
2545
2546#if defined( TUNER_AFC )
2547 case TVTUNER_SETAFC:
2548 bktr->tuner.afc = (*(int *)arg != 0);
2549 break;
2550
2551 case TVTUNER_GETAFC:
2552 *(int *)arg = bktr->tuner.afc;
2553 /* XXX Perhaps use another bit to indicate AFC success? */
2554 break;
2555#endif /* TUNER_AFC */
2556
2557 case TVTUNER_SETCHNL:
2558 temp_mute( bktr, TRUE );
2559 temp = tv_channel( bktr, (int)*(unsigned long *)arg );
2560 temp_mute( bktr, FALSE );
2561 if ( temp < 0 )
2562 return( EINVAL );
2563 *(unsigned long *)arg = temp;
2564 break;
2565
2566 case TVTUNER_GETCHNL:
2567 *(unsigned long *)arg = bktr->tuner.channel;
2568 break;
2569
2570 case TVTUNER_SETTYPE:
2571 temp = *(unsigned long *)arg;
2572 if ( (temp < CHNLSET_MIN) || (temp > CHNLSET_MAX) )
2573 return( EINVAL );
2574 bktr->tuner.chnlset = temp;
2575 break;
2576
2577 case TVTUNER_GETTYPE:
2578 *(unsigned long *)arg = bktr->tuner.chnlset;
2579 break;
2580
2581 case TVTUNER_GETSTATUS:
2582 temp = i2cRead( bktr, TSA552x_RADDR );
2583 *(unsigned long *)arg = temp & 0xff;
2584 break;
2585
2586 case TVTUNER_SETFREQ:
2587 temp_mute( bktr, TRUE );
2588 temp = tv_freq( bktr, (int)*(unsigned long *)arg );
2589 temp_mute( bktr, FALSE );
2590 if ( temp < 0 )
2591 return( EINVAL );
2592 *(unsigned long *)arg = temp;
2593 break;
2594
2595 case TVTUNER_GETFREQ:
2596 *(unsigned long *)arg = bktr->tuner.frequency;
2597 break;
2598
2599 case BT848_SAUDIO: /* set audio channel */
2600 if ( set_audio( bktr, *(int*)arg ) < 0 )
2601 return( EIO );
2602 break;
2603
2604 /* hue is a 2's compliment number, -90' to +89.3' in 0.7' steps */
2605 case BT848_SHUE: /* set hue */
2606 bt848->hue = (u_char)(*(int*)arg & 0xff);
2607 break;
2608
2609 case BT848_GHUE: /* get hue */
2610 *(int*)arg = (signed char)(bt848->hue & 0xff);
2611 break;
2612
2613 /* brightness is a 2's compliment #, -50 to +%49.6% in 0.39% steps */
2614 case BT848_SBRIG: /* set brightness */
2615 bt848->bright = (u_char)(*(int *)arg & 0xff);
2616 break;
2617
2618 case BT848_GBRIG: /* get brightness */
2619 *(int *)arg = (signed char)(bt848->bright & 0xff);
2620 break;
2621
2622 /* */
2623 case BT848_SCSAT: /* set chroma saturation */
2624 tmp_int = *(int*)arg;
2625
2626 temp = bt848->e_control;
2627 temp1 = bt848->o_control;
2628 if ( tmp_int & BIT_EIGHT_HIGH ) {
2629 temp |= (BT848_E_CONTROL_SAT_U_MSB |
2630 BT848_E_CONTROL_SAT_V_MSB);
2631 temp1 |= (BT848_O_CONTROL_SAT_U_MSB |
2632 BT848_O_CONTROL_SAT_V_MSB);
2633 }
2634 else {
2635 temp &= ~(BT848_E_CONTROL_SAT_U_MSB |
2636 BT848_E_CONTROL_SAT_V_MSB);
2637 temp1 &= ~(BT848_O_CONTROL_SAT_U_MSB |
2638 BT848_O_CONTROL_SAT_V_MSB);
2639 }
2640
2641 bt848->sat_u_lo = (u_char)(tmp_int & 0xff);
2642 bt848->sat_v_lo = (u_char)(tmp_int & 0xff);
2643 bt848->e_control = temp;
2644 bt848->o_control = temp1;
2645 break;
2646
2647 case BT848_GCSAT: /* get chroma saturation */
2648 tmp_int = (int)(bt848->sat_v_lo & 0xff);
2649 if ( bt848->e_control & BT848_E_CONTROL_SAT_V_MSB )
2650 tmp_int |= BIT_EIGHT_HIGH;
2651 *(int*)arg = tmp_int;
2652 break;
2653
2654 /* */
2655 case BT848_SVSAT: /* set chroma V saturation */
2656 tmp_int = *(int*)arg;
2657
2658 temp = bt848->e_control;
2659 temp1 = bt848->o_control;
2660 if ( tmp_int & BIT_EIGHT_HIGH) {
2661 temp |= BT848_E_CONTROL_SAT_V_MSB;
2662 temp1 |= BT848_O_CONTROL_SAT_V_MSB;
2663 }
2664 else {
2665 temp &= ~BT848_E_CONTROL_SAT_V_MSB;
2666 temp1 &= ~BT848_O_CONTROL_SAT_V_MSB;
2667 }
2668
2669 bt848->sat_v_lo = (u_char)(tmp_int & 0xff);
2670 bt848->e_control = temp;
2671 bt848->o_control = temp1;
2672 break;
2673
2674 case BT848_GVSAT: /* get chroma V saturation */
2675 tmp_int = (int)bt848->sat_v_lo & 0xff;
2676 if ( bt848->e_control & BT848_E_CONTROL_SAT_V_MSB )
2677 tmp_int |= BIT_EIGHT_HIGH;
2678 *(int*)arg = tmp_int;
2679 break;
2680
2681 /* */
2682 case BT848_SUSAT: /* set chroma U saturation */
2683 tmp_int = *(int*)arg;
2684
2685 temp = bt848->e_control;
2686 temp1 = bt848->o_control;
2687 if ( tmp_int & BIT_EIGHT_HIGH ) {
2688 temp |= BT848_E_CONTROL_SAT_U_MSB;
2689 temp1 |= BT848_O_CONTROL_SAT_U_MSB;
2690 }
2691 else {
2692 temp &= ~BT848_E_CONTROL_SAT_U_MSB;
2693 temp1 &= ~BT848_O_CONTROL_SAT_U_MSB;
2694 }
2695
2696 bt848->sat_u_lo = (u_char)(tmp_int & 0xff);
2697 bt848->e_control = temp;
2698 bt848->o_control = temp1;
2699 break;
2700
2701 case BT848_GUSAT: /* get chroma U saturation */
2702 tmp_int = (int)bt848->sat_u_lo & 0xff;
2703 if ( bt848->e_control & BT848_E_CONTROL_SAT_U_MSB )
2704 tmp_int |= BIT_EIGHT_HIGH;
2705 *(int*)arg = tmp_int;
2706 break;
2707
2708/* lr 970528 luma notch etc - 3 high bits of e_control/o_control */
2709
2710 case BT848_SLNOTCH: /* set luma notch */
2711 tmp_int = (*(int *)arg & 0x7) << 5 ;
2712 bt848->e_control &= ~0xe0 ;
2713 bt848->o_control &= ~0xe0 ;
2714 bt848->e_control |= tmp_int ;
2715 bt848->o_control |= tmp_int ;
2716 break;
2717
2718 case BT848_GLNOTCH: /* get luma notch */
2719 *(int *)arg = (int) ( (bt848->e_control & 0xe0) >> 5) ;
2720 break;
2721
2722
2723 /* */
2724 case BT848_SCONT: /* set contrast */
2725 tmp_int = *(int*)arg;
2726
2727 temp = bt848->e_control;
2728 temp1 = bt848->o_control;
2729 if ( tmp_int & BIT_EIGHT_HIGH ) {
2730 temp |= BT848_E_CONTROL_CON_MSB;
2731 temp1 |= BT848_O_CONTROL_CON_MSB;
2732 }
2733 else {
2734 temp &= ~BT848_E_CONTROL_CON_MSB;
2735 temp1 &= ~BT848_O_CONTROL_CON_MSB;
2736 }
2737
2738 bt848->contrast_lo = (u_char)(tmp_int & 0xff);
2739 bt848->e_control = temp;
2740 bt848->o_control = temp1;
2741 break;
2742
2743 case BT848_GCONT: /* get contrast */
2744 tmp_int = (int)bt848->contrast_lo & 0xff;
2745 if ( bt848->e_control & BT848_E_CONTROL_CON_MSB )
2746 tmp_int |= BIT_EIGHT_HIGH;
2747 *(int*)arg = tmp_int;
2748 break;
2749
2750 /* FIXME: SCBARS and CCBARS require a valid int * */
2751 /* argument to succeed, but its not used; consider */
2752 /* using the arg to store the on/off state so */
2753 /* there's only one ioctl() needed to turn cbars on/off */
2754 case BT848_SCBARS: /* set colorbar output */
2755 bt848->color_ctl_color_bars = 1;
2756 break;
2757
2758 case BT848_CCBARS: /* clear colorbar output */
2759 bt848->color_ctl_color_bars = 0;
2760 break;
2761
2762 case BT848_GAUDIO: /* get audio channel */
2763 temp = bktr->audio_mux_select;
2764 if ( bktr->audio_mute_state == TRUE )
2765 temp |= AUDIO_MUTE;
2766 *(int*)arg = temp;
2767 break;
2768
2769 case BT848_SBTSC: /* set audio channel */
2770 if ( set_BTSC( bktr, *(int*)arg ) < 0 )
2771 return( EIO );
2772 break;
2773
2774 case BT848_WEEPROM: /* write eeprom */
2775 offset = (((struct eeProm *)arg)->offset);
2776 count = (((struct eeProm *)arg)->count);
2777 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2778 if ( writeEEProm( bktr, offset, count, buf ) < 0 )
2779 return( EIO );
2780 break;
2781
2782 case BT848_REEPROM: /* read eeprom */
2783 offset = (((struct eeProm *)arg)->offset);
2784 count = (((struct eeProm *)arg)->count);
2785 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2786 if ( readEEProm( bktr, offset, count, buf ) < 0 )
2787 return( EIO );
2788 break;
2789
2790 case BT848_SIGNATURE:
2791 offset = (((struct eeProm *)arg)->offset);
2792 count = (((struct eeProm *)arg)->count);
2793 buf = &(((struct eeProm *)arg)->bytes[ 0 ]);
2794 if ( signCard( bktr, offset, count, buf ) < 0 )
2795 return( EIO );
2796 break;
2797 /* Ioctl's for running the tuner device in radio mode */
2798
2799 case RADIO_GETMODE:
2800 *(unsigned char *)arg = bktr->tuner.radio_mode;
2801 break;
2802
2803 case RADIO_SETMODE:
2804 bktr->tuner.radio_mode = *(unsigned char *)arg;
2805 break;
2806
2807 case RADIO_GETFREQ:
2808 *(unsigned long *)arg = (bktr->tuner.frequency+407)*5;
2809 break;
2810
2811 case RADIO_SETFREQ:
2812 /* The argument to this ioctl is NOT freq*16. It is
2813 ** freq*100.
2814 */
2815
2816 /* The radio in my stereo and the linear regression function
2817 ** in my HP48 have reached the conclusion that in order to
2818 ** set the radio tuner of the FM1216 to f MHz, the value to
2819 ** enter into the PLL is: f*20-407
2820 ** If anyone has the exact values from the spec. sheet
2821 ** please forward them -- fj@login.dknet.dk
2822 */
2823 temp=(int)*(unsigned long *)arg/5-407 +RADIO_OFFSET;
2824
2825#ifdef BKTR_RADIO_DEBUG
2826 printf("bktr%d: arg=%d temp=%d\n",unit,(int)*(unsigned long *)arg,temp);
2827#endif
2828
2829#ifndef BKTR_RADIO_NOFREQCHECK
2830 /* According to the spec. sheet the band: 87.5MHz-108MHz */
2831 /* is supported. */
2832 if(temp<1343+RADIO_OFFSET || temp>1753+RADIO_OFFSET) {
2833 printf("bktr%d: Radio frequency out of range\n",unit);
2834 return(EINVAL);
2835 }
2836#endif
2837 temp_mute( bktr, TRUE );
2838 temp = tv_freq( bktr, temp );
2839 temp_mute( bktr, FALSE );
2840#ifdef BKTR_RADIO_DEBUG
2841 if(temp)
2842 printf("bktr%d: tv_freq returned: %d\n",unit,temp);
2843#endif
2844 if ( temp < 0 )
2845 return( EINVAL );
2846 *(unsigned long *)arg = temp;
2847 break;
2848 /* Luigi's I2CWR ioctl */
2849 case BT848_I2CWR:
2850 par = *(u_long *)arg;
2851 write = (par >> 24) & 0xff ;
2852 i2c_addr = (par >> 16) & 0xff ;
2853 i2c_port = (par >> 8) & 0xff ;
2854 data = (par) & 0xff ;
2855
2856 if (write) {
2857 i2cWrite( bktr, i2c_addr, i2c_port, data);
2858 } else {
2859 data = i2cRead( bktr, i2c_addr);
2860 }
2861 *(u_long *)arg = (par & 0xffffff00) | ( data & 0xff );
2862 break;
2863
2864
2865 default:
2866 return common_ioctl( bktr, bt848, cmd, arg );
2867 }
2868
2869 return( 0 );
2870}
2871
2872
2873/*
2874 * common ioctls
2875 */
2876int
2877common_ioctl( bktr_ptr_t bktr, bt848_ptr_t bt848, int cmd, caddr_t arg )
2878{
2879 int pixfmt;
2880 unsigned int temp;
2881 struct meteor_pixfmt *pf_pub;
2882
2883 switch (cmd) {
2884
2885 case METEORSINPUT: /* set input device */
2886 switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
2887
2888 /* this is the RCA video input */
2889 case 0: /* default */
2890 case METEOR_INPUT_DEV0:
2891 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2892 | METEOR_DEV0;
2893 bt848->iform &= ~BT848_IFORM_MUXSEL;
2894 bt848->iform |= BT848_IFORM_M_MUX1;
2895 bt848->e_control &= ~BT848_E_CONTROL_COMP;
2896 bt848->o_control &= ~BT848_O_CONTROL_COMP;
2897 set_audio( bktr, AUDIO_EXTERN );
2898 break;
2899
2900 /* this is the tuner input */
2901 case METEOR_INPUT_DEV1:
2902 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2903 | METEOR_DEV1;
2904 bt848->iform &= ~BT848_IFORM_MUXSEL;
2905 bt848->iform |= BT848_IFORM_M_MUX0;
2906 bt848->e_control &= ~BT848_E_CONTROL_COMP;
2907 bt848->o_control &= ~BT848_O_CONTROL_COMP;
2908 set_audio( bktr, AUDIO_TUNER );
2909 break;
2910
2911 /* this is the S-VHS input */
2912 case METEOR_INPUT_DEV2:
2913 case METEOR_INPUT_DEV_SVIDEO:
2914 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2915 | METEOR_DEV2;
2916 bt848->iform &= ~BT848_IFORM_MUXSEL;
2917 bt848->iform |= BT848_IFORM_M_MUX2;
2918 bt848->e_control |= BT848_E_CONTROL_COMP;
2919 bt848->o_control |= BT848_O_CONTROL_COMP;
2920 set_audio( bktr, AUDIO_EXTERN );
2921 break;
2922
2923 case METEOR_INPUT_DEV3:
2924 if (bktr->id == BROOKTREE_878_ID ||
2925 bktr->id == BROOKTREE_879_ID ) {
2926 bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
2927 | METEOR_DEV3;
2928 bt848->iform &= ~BT848_IFORM_MUXSEL;
2929 bt848->iform |= BT848_IFORM_M_MUX3;
2930 bt848->e_control &= ~BT848_E_CONTROL_COMP;
2931 bt848->o_control &= ~BT848_O_CONTROL_COMP;
2932 set_audio( bktr, AUDIO_EXTERN );
2933
2934 break;
2935 }
2936
2937 default:
2938 return( EINVAL );
2939 }
2940 break;
2941
2942 case METEORGINPUT: /* get input device */
2943 *(u_long *)arg = bktr->flags & METEOR_DEV_MASK;
2944 break;
2945
2946 case METEORSACTPIXFMT:
2947 if (( *(int *)arg < 0 ) ||
2948 ( *(int *)arg >= PIXFMT_TABLE_SIZE ))
2949 return( EINVAL );
2950
2951 bktr->pixfmt = *(int *)arg;
2952 bt848->color_ctl_swap = pixfmt_swap_flags( bktr->pixfmt );
2953 bktr->pixfmt_compat = FALSE;
2954 break;
2955
2956 case METEORGACTPIXFMT:
2957 *(int *)arg = bktr->pixfmt;
2958 break;
2959
2960 case METEORGSUPPIXFMT :
2961 pf_pub = (struct meteor_pixfmt *)arg;
2962 pixfmt = pf_pub->index;
2963
2964 if (( pixfmt < 0 ) || ( pixfmt >= PIXFMT_TABLE_SIZE ))
2965 return( EINVAL );
2966
2967 memcpy( pf_pub, &pixfmt_table[ pixfmt ].public,
2968 sizeof( *pf_pub ) );
2969
2970 /* Patch in our format index */
2971 pf_pub->index = pixfmt;
2972 break;
2973
2974#if defined( STATUS_SUM )
2975 case BT848_GSTATUS: /* reap status */
2976 disable_intr();
2977 temp = status_sum;
2978 status_sum = 0;
2979 enable_intr();
2980 *(u_int*)arg = temp;
2981 break;
2982#endif /* STATUS_SUM */
2983
2984 default:
2985 return( ENOTTY );
2986 }
2987
2988 return( 0 );
2989}
2990
2991
2992/*
2993 *
2994 */
2995int
2996bktr_mmap( dev_t dev, int offset, int nprot )
2997{
2998 int unit;
2999 bktr_ptr_t bktr;
3000
3001 unit = UNIT(minor(dev));
3002
3003 if (unit >= NBKTR || MINOR(minor(dev)) > 0)/* could this happen here? */
3004 return( -1 );
3005
3006 bktr = &(brooktree[ unit ]);
3007
3008 if (nprot & PROT_EXEC)
3009 return( -1 );
3010
3011 if (offset >= bktr->alloc_pages * PAGE_SIZE)
3012 return( -1 );
3013
3014 return( i386_btop(vtophys(bktr->bigbuf) + offset) );
3015}
3016
3017
3018/******************************************************************************
3019 * bt848 RISC programming routines:
3020 */
3021
3022
3023/*
3024 *
3025 */
3026#ifdef BT848_DEBUG
3027static int
3028dump_bt848( bt848_ptr_t bt848 )
3029{
3030 volatile u_char *bt848r = (u_char *)bt848;
3031 int r[60]={
3032 4, 8, 0xc, 0x8c, 0x10, 0x90, 0x14, 0x94,
3033 0x18, 0x98, 0x1c, 0x9c, 0x20, 0xa0, 0x24, 0xa4,
3034 0x28, 0x2c, 0xac, 0x30, 0x34, 0x38, 0x3c, 0x40,
3035 0xc0, 0x48, 0x4c, 0xcc, 0x50, 0xd0, 0xd4, 0x60,
3036 0x64, 0x68, 0x6c, 0xec, 0xd8, 0xdc, 0xe0, 0xe4,
3037 0, 0, 0, 0
3038 };
3039 int i;
3040
3041 for (i = 0; i < 40; i+=4) {
3042 printf(" Reg:value : \t%x:%x \t%x:%x \t %x:%x \t %x:%x\n",
3043 r[i], bt848r[r[i]],
3044 r[i+1], bt848r[r[i+1]],
3045 r[i+2], bt848r[r[i+2]],
3046 r[i+3], bt848r[r[i+3]]);
3047 }
3048
3049 printf(" INT STAT %x \n", bt848->int_stat);
3050 printf(" Reg INT_MASK %x \n", bt848->int_mask);
3051 printf(" Reg GPIO_DMA_CTL %x \n", bt848->gpio_dma_ctl);
3052
3053 return( 0 );
3054}
3055
3056#endif
3057
3058/*
3059 * build write instruction
3060 */
3061#define BKTR_FM1 0x6 /* packed data to follow */
3062#define BKTR_FM3 0xe /* planar data to follow */
3063#define BKTR_VRE 0x4 /* even field to follow */
3064#define BKTR_VRO 0xC /* odd field to follow */
3065#define BKTR_PXV 0x0 /* valid word (never used) */
3066#define BKTR_EOL 0x1 /* last dword, 4 bytes */
3067#define BKTR_SOL 0x2 /* first dword */
3068
3069#define OP_WRITE (0x1 << 28)
3070#define OP_SKIP (0x2 << 28)
3071#define OP_WRITEC (0x5 << 28)
3072#define OP_JUMP (0x7 << 28)
3073#define OP_SYNC (0x8 << 28)
3074#define OP_WRITE123 (0x9 << 28)
3075#define OP_WRITES123 (0xb << 28)
3076#define OP_SOL (1 << 27) /* first instr for scanline */
3077#define OP_EOL (1 << 26)
3078
3079bool_t notclipped (bktr_reg_t * bktr, int x, int width) {
3080 int i;
3081 bktr_clip_t * clip_node;
3082 bktr->clip_start = -1;
3083 bktr->last_y = 0;
3084 bktr->y = 0;
3085 bktr->y2 = width;
3086 bktr->line_length = width;
3087 bktr->yclip = -1;
3088 bktr->yclip2 = -1;
3089 bktr->current_col = 0;
3090
3091 if (bktr->max_clip_node == 0 ) return TRUE;
3092 clip_node = (bktr_clip_t *) &bktr->clip_list[0];
3093
3094
3095 for (i = 0; i < bktr->max_clip_node; i++ ) {
3096 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
3097 if (x >= clip_node->x_min && x <= clip_node->x_max ) {
3098 bktr->clip_start = i;
3099 return FALSE;
3100 }
3101 }
3102
3103 return TRUE;
3104}
3105
3106bool_t getline(bktr_reg_t *bktr, int x ) {
3107 int i, j;
3108 bktr_clip_t * clip_node ;
3109
3110 if (bktr->line_length == 0 ||
3111 bktr->current_col >= bktr->line_length) return FALSE;
3112
3113 bktr->y = min(bktr->last_y, bktr->line_length);
3114 bktr->y2 = bktr->line_length;
3115
3116 bktr->yclip = bktr->yclip2 = -1;
3117 for (i = bktr->clip_start; i < bktr->max_clip_node; i++ ) {
3118 clip_node = (bktr_clip_t *) &bktr->clip_list[i];
3119 if (x >= clip_node->x_min && x <= clip_node->x_max) {
3120 if (bktr->last_y <= clip_node->y_min) {
3121 bktr->y = min(bktr->last_y, bktr->line_length);
3122 bktr->y2 = min(clip_node->y_min, bktr->line_length);
3123 bktr->yclip = min(clip_node->y_min, bktr->line_length);
3124 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
3125 bktr->last_y = bktr->yclip2;
3126 bktr->clip_start = i;
3127
3128 for (j = i+1; j < bktr->max_clip_node; j++ ) {
3129 clip_node = (bktr_clip_t *) &bktr->clip_list[j];
3130 if (x >= clip_node->x_min && x <= clip_node->x_max) {
3131 if (bktr->last_y >= clip_node->y_min) {
3132 bktr->yclip2 = min(clip_node->y_max, bktr->line_length);
3133 bktr->last_y = bktr->yclip2;
3134 bktr->clip_start = j;
3135 }
3136 } else break ;
3137 }
3138 return TRUE;
3139 }
3140 }
3141 }
3142
3143 if (bktr->current_col <= bktr->line_length) {
3144 bktr->current_col = bktr->line_length;
3145 return TRUE;
3146 }
3147 return FALSE;
3148}
3149
3150static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
3151 u_long operation, int pixel_width,
3152 volatile u_char ** target_buffer, int cols ) {
3153
3154 u_long flag, flag2;
3155 struct meteor_pixfmt *pf = &pixfmt_table[ bktr->pixfmt ].public;
3156 u_int skip, start_skip;
3157
3158 /* For RGB24, we need to align the component in FIFO Byte Lane 0 */
3159 /* to the 1st byte in the mem dword containing our start addr. */
3160 /* BTW, we know this pixfmt's 1st byte is Blue; thus the start addr */
3161 /* must be Blue. */
3162 start_skip = 0;
3163 if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
3164 switch ( ((uintptr_t) (void *) *target_buffer) % 4 ) {
3165 case 2 : start_skip = 4 ; break;
3166 case 1 : start_skip = 8 ; break;
3167 }
3168
3169 if ((width * pixel_width) < DMA_BT848_SPLIT ) {
3170 if ( width == cols) {
3171 flag = OP_SOL | OP_EOL;
3172 } else if (bktr->current_col == 0 ) {
3173 flag = OP_SOL;
3174 } else if (bktr->current_col == cols) {
3175 flag = OP_EOL;
3176 } else flag = 0;
3177
3178 skip = 0;
3179 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
3180 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
3181 flag &= ~OP_SOL;
3182 skip = start_skip;
3183 }
3184
3185 *(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
3186 if (operation != OP_SKIP )
3187 *(*dma_prog)++ = (uintptr_t) (void *) *target_buffer;
3188
3189 *target_buffer += width * pixel_width;
3190 bktr->current_col += width;
3191
3192 } else {
3193
3194 if (bktr->current_col == 0 && width == cols) {
3195 flag = OP_SOL ;
3196 flag2 = OP_EOL;
3197 } else if (bktr->current_col == 0 ) {
3198 flag = OP_SOL;
3199 flag2 = 0;
3200 } else if (bktr->current_col >= cols) {
3201 flag = 0;
3202 flag2 = OP_EOL;
3203 } else {
3204 flag = 0;
3205 flag2 = 0;
3206 }
3207
3208 skip = 0;
3209 if (( flag & OP_SOL ) && ( start_skip > 0 )) {
3210 *(*dma_prog)++ = OP_SKIP | OP_SOL | start_skip;
3211 flag &= ~OP_SOL;
3212 skip = start_skip;
3213 }
3214
3215 *(*dma_prog)++ = operation | flag |
3216 (width * pixel_width / 2 - skip);
3217 if (operation != OP_SKIP )
3218 *(*dma_prog)++ = (uintptr_t) (void *) *target_buffer ;
3219 *target_buffer += (width * pixel_width / 2) ;
3220
3221 if ( operation == OP_WRITE )
3222 operation = OP_WRITEC;
3223 *(*dma_prog)++ = operation | flag2 |
3224 (width * pixel_width / 2);
3225 *target_buffer += (width * pixel_width / 2) ;
3226 bktr->current_col += width;
3227
3228 }
3229 return TRUE;
3230}
3231
3232
3233
3234
3235static void
3236rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
3237{
3238 int i;
3239 bt848_ptr_t bt848;
3240 volatile u_long target_buffer, buffer, target,width;
3241 volatile u_long pitch;
3242 volatile u_long *dma_prog;
3243 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3244 u_int Bpp = pf_int->public.Bpp;
3245
3246 bt848 = bktr->base;
3247
3248 bt848->color_fmt = pf_int->color_fmt;
3249 bt848->vbi_pack_size = 0;
3250 bt848->vbi_pack_del = 0;
3251 bt848->adc = SYNC_LEVEL;
3252
3253 bt848->oform = 0x00;
3254
3255 bt848->e_vscale_hi |= 0x40; /* set chroma comb */
3256 bt848->o_vscale_hi |= 0x40;
3257 bt848->e_vscale_hi &= ~0x80; /* clear Ycomb */
3258 bt848->o_vscale_hi &= ~0x80;
3259
3260 /* disable gamma correction removal */
3261 bt848->color_ctl_gamma = 1;
3262
3263
3264 if (cols > 385 ) {
3265 bt848->e_vtc = 0;
3266 bt848->o_vtc = 0;
3267 } else {
3268 bt848->e_vtc = 1;
3269 bt848->o_vtc = 1;
3270 }
3271 bktr->capcontrol = 3 << 2 | 3;
3272
3273 dma_prog = (u_long *) bktr->dma_prog;
3274
3275 /* Construct Write */
3276
3277 if (bktr->video.addr) {
3278 target_buffer = (u_long) bktr->video.addr;
3279 pitch = bktr->video.width;
3280 }
3281 else {
3282 target_buffer = (u_long) vtophys(bktr->bigbuf);
3283 pitch = cols*Bpp;
3284 }
3285
3286 buffer = target_buffer;
3287
3288
3289 /* contruct sync : for video packet format */
3290 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1;
3291
3292 /* sync, mode indicator packed data */
3293 *dma_prog++ = 0; /* NULL WORD */
3294 width = cols;
3295 for (i = 0; i < (rows/interlace); i++) {
3296 target = target_buffer;
3297 if ( notclipped(bktr, i, width)) {
3298 split(bktr, (volatile u_long **) &dma_prog,
3299 bktr->y2 - bktr->y, OP_WRITE,
3300 Bpp, (volatile u_char **) &target, cols);
3301
3302 } else {
3303 while(getline(bktr, i)) {
3304 if (bktr->y != bktr->y2 ) {
3305 split(bktr, (volatile u_long **) &dma_prog,
3306 bktr->y2 - bktr->y, OP_WRITE,
3307 Bpp, (volatile u_char **) &target, cols);
3308 }
3309 if (bktr->yclip != bktr->yclip2 ) {
3310 split(bktr,(volatile u_long **) &dma_prog,
3311 bktr->yclip2 - bktr->yclip,
3312 OP_SKIP,
3313 Bpp, (volatile u_char **) &target, cols);
3314 }
3315 }
3316
3317 }
3318
3319 target_buffer += interlace * pitch;
3320
3321 }
3322
3323 switch (i_flag) {
3324 case 1:
3325 /* sync vre */
3326 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO;
3327 *dma_prog++ = 0; /* NULL WORD */
3328
3329 *dma_prog++ = OP_JUMP;
3330 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3331 return;
3332
3333 case 2:
3334 /* sync vro */
3335 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
3336 *dma_prog++ = 0; /* NULL WORD */
3337
3338 *dma_prog++ = OP_JUMP;
3339 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3340 return;
3341
3342 case 3:
3343 /* sync vro */
3344 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3345 *dma_prog++ = 0; /* NULL WORD */
3346 *dma_prog++ = OP_JUMP; ;
3347 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3348 break;
3349 }
3350
3351 if (interlace == 2) {
3352
3353 target_buffer = buffer + pitch;
3354
3355 dma_prog = (u_long *) bktr->odd_dma_prog;
3356
3357
3358 /* sync vre IRQ bit */
3359 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1;
3360 *dma_prog++ = 0; /* NULL WORD */
3361 width = cols;
3362 for (i = 0; i < (rows/interlace); i++) {
3363 target = target_buffer;
3364 if ( notclipped(bktr, i, width)) {
3365 split(bktr, (volatile u_long **) &dma_prog,
3366 bktr->y2 - bktr->y, OP_WRITE,
3367 Bpp, (volatile u_char **) &target, cols);
3368 } else {
3369 while(getline(bktr, i)) {
3370 if (bktr->y != bktr->y2 ) {
3371 split(bktr, (volatile u_long **) &dma_prog,
3372 bktr->y2 - bktr->y, OP_WRITE,
3373 Bpp, (volatile u_char **) &target,
3374 cols);
3375 }
3376 if (bktr->yclip != bktr->yclip2 ) {
3377 split(bktr, (volatile u_long **) &dma_prog,
3378 bktr->yclip2 - bktr->yclip, OP_SKIP,
3379 Bpp, (volatile u_char **) &target, cols);
3380 }
3381
3382 }
3383
3384 }
3385
3386 target_buffer += interlace * pitch;
3387
3388 }
3389 }
3390
3391 /* sync vre IRQ bit */
3392 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3393 *dma_prog++ = 0; /* NULL WORD */
3394 *dma_prog++ = OP_JUMP ;
3395 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3396 *dma_prog++ = 0; /* NULL WORD */
3397}
3398
3399
3400/*
3401 *
3402 */
3403static void
3404yuvpack_prog( bktr_ptr_t bktr, char i_flag,
3405 int cols, int rows, int interlace )
3406{
3407 int i;
3408 volatile unsigned int inst;
3409 volatile unsigned int inst3;
3410 volatile u_long target_buffer, buffer;
3411 bt848_ptr_t bt848;
3412 volatile u_long *dma_prog;
3413 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3414 int b;
3415
3416 bt848 = bktr->base;
3417
3418 bt848->color_fmt = pf_int->color_fmt;
3419
3420 bt848->e_scloop |= BT848_E_SCLOOP_CAGC; /* enable chroma comb */
3421 bt848->o_scloop |= BT848_O_SCLOOP_CAGC;
3422
3423 bt848->color_ctl_rgb_ded = 1;
3424 bt848->color_ctl_gamma = 1;
3425 bt848->adc = SYNC_LEVEL;
3426
3427 bktr->capcontrol = 1 << 6 | 1 << 4 | 1 << 2 | 3;
3428 bktr->capcontrol = 3 << 2 | 3;
3429
3430 dma_prog = (u_long *) bktr->dma_prog;
3431
3432 /* Construct Write */
3433
3434 /* write , sol, eol */
3435 inst = OP_WRITE | OP_SOL | (cols);
3436 /* write , sol, eol */
3437 inst3 = OP_WRITE | OP_EOL | (cols);
3438
3439 if (bktr->video.addr)
3440 target_buffer = (u_long) bktr->video.addr;
3441 else
3442 target_buffer = (u_long) vtophys(bktr->bigbuf);
3443
3444 buffer = target_buffer;
3445
3446 /* contruct sync : for video packet format */
3447 /* sync, mode indicator packed data */
3448 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM1;
3449 *dma_prog++ = 0; /* NULL WORD */
3450
3451 b = cols;
3452
3453 for (i = 0; i < (rows/interlace); i++) {
3454 *dma_prog++ = inst;
3455 *dma_prog++ = target_buffer;
3456 *dma_prog++ = inst3;
3457 *dma_prog++ = target_buffer + b;
3458 target_buffer += interlace*(cols * 2);
3459 }
3460
3461 switch (i_flag) {
3462 case 1:
3463 /* sync vre */
3464 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
3465 *dma_prog++ = 0; /* NULL WORD */
3466
3467 *dma_prog++ = OP_JUMP;
3468 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3469 return;
3470
3471 case 2:
3472 /* sync vro */
3473 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO;
3474 *dma_prog++ = 0; /* NULL WORD */
3475 *dma_prog++ = OP_JUMP;
3476 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3477 return;
3478
3479 case 3:
3480 /* sync vro */
3481 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3482 *dma_prog++ = 0; /* NULL WORD */
3483 *dma_prog++ = OP_JUMP ;
3484 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3485 break;
3486 }
3487
3488 if (interlace == 2) {
3489
3490 target_buffer = (u_long) buffer + cols*2;
3491
3492 dma_prog = (u_long * ) bktr->odd_dma_prog;
3493
3494 /* sync vre */
3495 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_FM1;
3496 *dma_prog++ = 0; /* NULL WORD */
3497
3498 for (i = 0; i < (rows/interlace) ; i++) {
3499 *dma_prog++ = inst;
3500 *dma_prog++ = target_buffer;
3501 *dma_prog++ = inst3;
3502 *dma_prog++ = target_buffer + b;
3503 target_buffer += interlace * ( cols*2);
3504 }
3505 }
3506
3507 /* sync vro IRQ bit */
3508 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3509 *dma_prog++ = 0; /* NULL WORD */
3510 *dma_prog++ = OP_JUMP ;
3511 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3512
3513 *dma_prog++ = OP_JUMP;
3514 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3515 *dma_prog++ = 0; /* NULL WORD */
3516}
3517
3518
3519/*
3520 *
3521 */
3522static void
3523yuv422_prog( bktr_ptr_t bktr, char i_flag,
3524 int cols, int rows, int interlace ){
3525
3526 int i;
3527 volatile unsigned int inst;
3528 volatile u_long target_buffer, t1, buffer;
3529 bt848_ptr_t bt848;
3530 volatile u_long *dma_prog;
3531 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3532
3533 bt848 = bktr->base;
3534
3535 bt848->color_fmt = pf_int->color_fmt;
3536
3537 dma_prog = (u_long *) bktr->dma_prog;
3538
3539 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3540
3541 bt848->adc = SYNC_LEVEL;
3542 bt848->oform = 0x00;
3543
3544 bt848->e_control |= BT848_E_CONTROL_LDEC; /* disable luma decimation */
3545 bt848->o_control |= BT848_O_CONTROL_LDEC;
3546
3547 bt848->e_scloop |= BT848_O_SCLOOP_CAGC; /* chroma agc enable */
3548 bt848->o_scloop |= BT848_O_SCLOOP_CAGC;
3549
3550 bt848->e_vscale_hi &= ~0x80; /* clear Ycomb */
3551 bt848->o_vscale_hi &= ~0x80;
3552 bt848->e_vscale_hi |= 0x40; /* set chroma comb */
3553 bt848->o_vscale_hi |= 0x40;
3554
3555 /* disable gamma correction removal */
3556 bt848->color_ctl_gamma = 1;
3557
3558 /* Construct Write */
3559 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3560 if (bktr->video.addr)
3561 target_buffer = (u_long) bktr->video.addr;
3562 else
3563 target_buffer = (u_long) vtophys(bktr->bigbuf);
3564
3565 buffer = target_buffer;
3566
3567 t1 = buffer;
3568
3569 /* contruct sync : for video packet format */
3570 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3571 *dma_prog++ = 0; /* NULL WORD */
3572
3573 for (i = 0; i < (rows/interlace ) ; i++) {
3574 *dma_prog++ = inst;
3575 *dma_prog++ = cols/2 | cols/2 << 16;
3576 *dma_prog++ = target_buffer;
3577 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3578 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3579 target_buffer += interlace*cols;
3580 }
3581
3582 switch (i_flag) {
3583 case 1:
3584 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3585 *dma_prog++ = 0; /* NULL WORD */
3586
3587 *dma_prog++ = OP_JUMP ;
3588 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3589 return;
3590
3591 case 2:
3592 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vre*/
3593 *dma_prog++ = 0; /* NULL WORD */
3594
3595 *dma_prog++ = OP_JUMP;
3596 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3597 return;
3598
3599 case 3:
3600 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3601 *dma_prog++ = 0; /* NULL WORD */
3602
3603 *dma_prog++ = OP_JUMP ;
3604 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3605 break;
3606 }
3607
3608 if (interlace == 2) {
3609
3610 dma_prog = (u_long * ) bktr->odd_dma_prog;
3611
3612 target_buffer = (u_long) buffer + cols;
3613 t1 = buffer + cols/2;
3614 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3615 *dma_prog++ = 0; /* NULL WORD */
3616
3617 for (i = 0; i < (rows/interlace ) ; i++) {
3618 *dma_prog++ = inst;
3619 *dma_prog++ = cols/2 | cols/2 << 16;
3620 *dma_prog++ = target_buffer;
3621 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3622 *dma_prog++ = t1 + (cols*rows) + (cols*rows/2) + i*cols/2 * interlace;
3623 target_buffer += interlace*cols;
3624 }
3625 }
3626
3627 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3628 *dma_prog++ = 0; /* NULL WORD */
3629 *dma_prog++ = OP_JUMP ;
3630 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog) ;
3631 *dma_prog++ = 0; /* NULL WORD */
3632}
3633
3634
3635/*
3636 *
3637 */
3638static void
3639yuv12_prog( bktr_ptr_t bktr, char i_flag,
3640 int cols, int rows, int interlace ){
3641
3642 int i;
3643 volatile unsigned int inst;
3644 volatile unsigned int inst1;
3645 volatile u_long target_buffer, t1, buffer;
3646 bt848_ptr_t bt848;
3647 volatile u_long *dma_prog;
3648 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3649
3650 bt848 = bktr->base;
3651
3652 bt848->color_fmt = pf_int->color_fmt;
3653
3654 dma_prog = (u_long *) bktr->dma_prog;
3655
3656 bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
3657
3658 bt848->adc = SYNC_LEVEL;
3659 bt848->oform = 0x0;
3660
3661 /* Construct Write */
3662 inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
3663 inst1 = OP_WRITES123 | OP_SOL | OP_EOL | (cols);
3664 if (bktr->video.addr)
3665 target_buffer = (u_long) bktr->video.addr;
3666 else
3667 target_buffer = (u_long) vtophys(bktr->bigbuf);
3668
3669 buffer = target_buffer;
3670 t1 = buffer;
3671
3672 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3; /*sync, mode indicator packed data*/
3673 *dma_prog++ = 0; /* NULL WORD */
3674
3675 for (i = 0; i < (rows/interlace )/2 ; i++) {
3676 *dma_prog++ = inst;
3677 *dma_prog++ = cols/2 | (cols/2 << 16);
3678 *dma_prog++ = target_buffer;
3679 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3680 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3681 target_buffer += interlace*cols;
3682 *dma_prog++ = inst1;
3683 *dma_prog++ = cols/2 | (cols/2 << 16);
3684 *dma_prog++ = target_buffer;
3685 target_buffer += interlace*cols;
3686
3687 }
3688
3689 switch (i_flag) {
3690 case 1:
3691 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE; /*sync vre*/
3692 *dma_prog++ = 0; /* NULL WORD */
3693
3694 *dma_prog++ = OP_JUMP;
3695 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3696 return;
3697
3698 case 2:
3699 *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO; /*sync vro*/
3700 *dma_prog++ = 0; /* NULL WORD */
3701
3702 *dma_prog++ = OP_JUMP;
3703 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3704 return;
3705
3706 case 3:
3707 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRO;
3708 *dma_prog++ = 0; /* NULL WORD */
3709 *dma_prog++ = OP_JUMP ;
3710 *dma_prog = (u_long ) vtophys(bktr->odd_dma_prog);
3711 break;
3712 }
3713
3714 if (interlace == 2) {
3715
3716 dma_prog = (u_long * ) bktr->odd_dma_prog;
3717
3718 target_buffer = (u_long) buffer + cols;
3719 t1 = buffer + cols/2;
3720 *dma_prog++ = OP_SYNC | 1 << 15 | BKTR_FM3;
3721 *dma_prog++ = 0; /* NULL WORD */
3722
3723 for (i = 0; i < ((rows/interlace )/2 ) ; i++) {
3724 *dma_prog++ = inst;
3725 *dma_prog++ = cols/2 | (cols/2 << 16);
3726 *dma_prog++ = target_buffer;
3727 *dma_prog++ = t1 + (cols*rows) + i*cols/2 * interlace;
3728 *dma_prog++ = t1 + (cols*rows) + (cols*rows/4) + i*cols/2 * interlace;
3729 target_buffer += interlace*cols;
3730 *dma_prog++ = inst1;
3731 *dma_prog++ = cols/2 | (cols/2 << 16);
3732 *dma_prog++ = target_buffer;
3733 target_buffer += interlace*cols;
3734
3735 }
3736
3737
3738 }
3739
3740 *dma_prog++ = OP_SYNC | 1 << 24 | 1 << 15 | BKTR_VRE;
3741 *dma_prog++ = 0; /* NULL WORD */
3742 *dma_prog++ = OP_JUMP;
3743 *dma_prog++ = (u_long ) vtophys(bktr->dma_prog);
3744 *dma_prog++ = 0; /* NULL WORD */
3745}
3746
3747
3748
3749/*
3750 *
3751 */
3752static void
3753build_dma_prog( bktr_ptr_t bktr, char i_flag )
3754{
3755 int rows, cols, interlace;
3756 bt848_ptr_t bt848;
3757 int tmp_int;
3758 unsigned int temp;
3759 struct format_params *fp;
3760 struct meteor_pixfmt_internal *pf_int = &pixfmt_table[ bktr->pixfmt ];
3761
3762
3763 fp = &format_params[bktr->format_params];
3764
3765 bt848 = bktr->base;
3766 bt848->int_mask = ALL_INTS_DISABLED;
3767
3768 /* disable FIFO & RISC, leave other bits alone */
3769 bt848->gpio_dma_ctl &= ~FIFO_RISC_ENABLED;
3770
3771 /* set video parameters */
3772 if (bktr->capture_area_enabled)
3773 temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
3774 / fp->scaled_htotal / bktr->cols) - 4096;
3775 else
3776 temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
3777 / fp->scaled_htotal / bktr->cols) - 4096;
3778
3779 /* printf("HSCALE value is %d\n",temp); */
3780 bt848->e_hscale_lo = temp & 0xff;
3781 bt848->o_hscale_lo = temp & 0xff;
3782 bt848->e_hscale_hi = (temp >> 8) & 0xff;
3783 bt848->o_hscale_hi = (temp >> 8) & 0xff;
3784
3785 /* horizontal active */
3786 temp = bktr->cols;
3787 /* printf("HACTIVE value is %d\n",temp); */
3788 bt848->e_hactive_lo = temp & 0xff;
3789 bt848->o_hactive_lo = temp & 0xff;
3790 bt848->e_crop &= ~0x3;
3791 bt848->o_crop &= ~0x3;
3792 bt848->e_crop |= (temp >> 8) & 0x3;
3793 bt848->o_crop |= (temp >> 8) & 0x3;
3794
3795 /* horizontal delay */
3796 if (bktr->capture_area_enabled)
3797 temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
3798 * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
3799 else
3800 temp = (fp->hdelay * bktr->cols) / fp->hactive;
3801
3802 temp = temp & 0x3fe;
3803
3804 /* printf("HDELAY value is %d\n",temp); */
3805 bt848->e_delay_lo = temp & 0xff;
3806 bt848->o_delay_lo = temp & 0xff;
3807 bt848->e_crop &= ~0xc;
3808 bt848->o_crop &= ~0xc;
3809 bt848->e_crop |= (temp >> 6) & 0xc;
3810 bt848->o_crop |= (temp >> 6) & 0xc;
3811
3812 /* vertical scale */
3813
3814 if (bktr->capture_area_enabled) {
3815 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3816 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3817 tmp_int = 65536 -
3818 (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3819 else {
3820 tmp_int = 65536 -
3821 (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3822 }
3823 } else {
3824 if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
3825 bktr->flags & METEOR_ONLY_EVEN_FIELDS)
3826 tmp_int = 65536 -
3827 (((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
3828 else {
3829 tmp_int = 65536 -
3830 (((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
3831 }
3832 }
3833
3834 tmp_int &= 0x1fff;
3835 /* printf("VSCALE value is %d\n",tmp_int); */
3836 bt848->e_vscale_lo = tmp_int & 0xff;
3837 bt848->o_vscale_lo = tmp_int & 0xff;
3838 bt848->e_vscale_hi &= ~0x1f;
3839 bt848->o_vscale_hi &= ~0x1f;
3840 bt848->e_vscale_hi |= (tmp_int >> 8) & 0x1f;
3841 bt848->o_vscale_hi |= (tmp_int >> 8) & 0x1f;
3842
3843
3844 /* vertical active */
3845 if (bktr->capture_area_enabled)
3846 temp = bktr->capture_area_y_size;
3847 else
3848 temp = fp->vactive;
3849 /* printf("VACTIVE is %d\n",temp); */
3850 bt848->e_crop &= ~0x30;
3851 bt848->e_crop |= (temp >> 4) & 0x30;
3852 bt848->e_vactive_lo = temp & 0xff;
3853 bt848->o_crop &= ~0x30;
3854 bt848->o_crop |= (temp >> 4) & 0x30;
3855 bt848->o_vactive_lo = temp & 0xff;
3856
3857 /* vertical delay */
3858 if (bktr->capture_area_enabled)
3859 temp = fp->vdelay + (bktr->capture_area_y_offset);
3860 else
3861 temp = fp->vdelay;
3862 /* printf("VDELAY is %d\n",temp); */
3863 bt848->e_crop &= ~0xC0;
3864 bt848->e_crop |= (temp >> 2) & 0xC0;
3865 bt848->e_vdelay_lo = temp & 0xff;
3866 bt848->o_crop &= ~0xC0;
3867 bt848->o_crop |= (temp >> 2) & 0xC0;
3868 bt848->o_vdelay_lo = temp & 0xff;
3869
3870 /* end of video params */
3871
3872#ifdef BKTR_USE_PLL
3873 if (fp->iform_xtsel==BT848_IFORM_X_XT1) {
3874 bt848->tgctrl=8; /* Select PLL mode */
3875 } else {
3876 bt848->tgctrl=0; /* Select Normal xtal 0/xtal 1 mode */
3877 }
3878#endif
3879
3880 /* capture control */
3881 switch (i_flag) {
3882 case 1:
3883 bktr->bktr_cap_ctl =
3884 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_EVEN);
3885 bt848->e_vscale_hi &= ~0x20;
3886 bt848->o_vscale_hi &= ~0x20;
3887 interlace = 1;
3888 break;
3889 case 2:
3890 bktr->bktr_cap_ctl =
3891 (BT848_CAP_CTL_DITH_FRAME | BT848_CAP_CTL_ODD);
3892 bt848->e_vscale_hi &= ~0x20;
3893 bt848->o_vscale_hi &= ~0x20;
3894 interlace = 1;
3895 break;
3896 default:
3897 bktr->bktr_cap_ctl =
3898 (BT848_CAP_CTL_DITH_FRAME |
3899 BT848_CAP_CTL_EVEN | BT848_CAP_CTL_ODD);
3900 bt848->e_vscale_hi |= 0x20;
3901 bt848->o_vscale_hi |= 0x20;
3902 interlace = 2;
3903 break;
3904 }
3905
3906 bt848->risc_strt_add = vtophys(bktr->dma_prog);
3907
3908 rows = bktr->rows;
3909 cols = bktr->cols;
3910
3911 if ( pf_int->public.type == METEOR_PIXTYPE_RGB ) {
3912 rgb_prog(bktr, i_flag, cols, rows, interlace);
3913 return;
3914 }
3915
3916 if ( pf_int->public.type == METEOR_PIXTYPE_YUV ) {
3917 yuv422_prog(bktr, i_flag, cols, rows, interlace);
3918 bt848->color_ctl_swap = pixfmt_swap_flags( bktr->pixfmt );
3919 return;
3920 }
3921
3922 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_PACKED ) {
3923 yuvpack_prog(bktr, i_flag, cols, rows, interlace);
3924 bt848->color_ctl_swap = pixfmt_swap_flags( bktr->pixfmt );
3925 return;
3926 }
3927
3928 if ( pf_int->public.type == METEOR_PIXTYPE_YUV_12 ) {
3929 yuv12_prog(bktr, i_flag, cols, rows, interlace);
3930 bt848->color_ctl_swap = pixfmt_swap_flags( bktr->pixfmt );
3931 return;
3932 }
3933 return;
3934}
3935
3936
3937/******************************************************************************
3938 * video & video capture specific routines:
3939 */
3940
3941
3942/*
3943 *
3944 */
3945static void
3946start_capture( bktr_ptr_t bktr, unsigned type )
3947{
3948 bt848_ptr_t bt848;
3949 u_char i_flag;
3950 struct format_params *fp;
3951
3952 fp = &format_params[bktr->format_params];
3953
3954 /* If requested, clear out capture buf first */
3955 if (bktr->clr_on_start && (bktr->video.addr == 0)) {
3956 bzero((caddr_t)bktr->bigbuf,
3957 (size_t)bktr->rows * bktr->cols * bktr->frames *
3958 pixfmt_table[ bktr->pixfmt ].public.Bpp);
3959 }
3960
3961 bt848 = bktr->base;
3962
3963 bt848->dstatus = 0;
3964 bt848->int_stat = bt848->int_stat;
3965
3966 bktr->flags |= type;
3967 bktr->flags &= ~METEOR_WANT_MASK;
3968 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
3969 case METEOR_ONLY_EVEN_FIELDS:
3970 bktr->flags |= METEOR_WANT_EVEN;
3971 i_flag = 1;
3972 break;
3973 case METEOR_ONLY_ODD_FIELDS:
3974 bktr->flags |= METEOR_WANT_ODD;
3975 i_flag = 2;
3976 break;
3977 default:
3978 bktr->flags |= METEOR_WANT_MASK;
3979 i_flag = 3;
3980 break;
3981 }
3982
3983 /* TDEC is only valid for continuous captures */
3984 if ( type == METEOR_SINGLE ) {
3985 u_short fps_save = bktr->fps;
3986
3987 set_fps(bktr, fp->frame_rate);
3988 bktr->fps = fps_save;
3989 }
3990 else
3991 set_fps(bktr, bktr->fps);
3992
3993 if (bktr->dma_prog_loaded == FALSE) {
3994 build_dma_prog(bktr, i_flag);
3995 bktr->dma_prog_loaded = TRUE;
3996 }
3997
3998
3999 bt848->risc_strt_add = vtophys(bktr->dma_prog);
4000
4001}
4002
4003
4004/*
4005 *
4006 */
4007static void
4008set_fps( bktr_ptr_t bktr, u_short fps )
4009{
4010 bt848_ptr_t bt848;
4011 struct format_params *fp;
4012 int i_flag;
4013
4014 fp = &format_params[bktr->format_params];
4015
4016 bt848 = bktr->base;
4017
4018 switch(bktr->flags & METEOR_ONLY_FIELDS_MASK) {
4019 case METEOR_ONLY_EVEN_FIELDS:
4020 bktr->flags |= METEOR_WANT_EVEN;
4021 i_flag = 1;
4022 break;
4023 case METEOR_ONLY_ODD_FIELDS:
4024 bktr->flags |= METEOR_WANT_ODD;
4025 i_flag = 1;
4026 break;
4027 default:
4028 bktr->flags |= METEOR_WANT_MASK;
4029 i_flag = 2;
4030 break;
4031 }
4032
4033 bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
4034 bt848->int_stat = ALL_INTS_CLEARED;
4035
4036 bktr->fps = fps;
4037 bt848->tdec = 0;
4038
4039 if (fps < fp->frame_rate)
4040 bt848->tdec = i_flag*(fp->frame_rate - fps) & 0x3f;
4041 else
4042 bt848->tdec = 0;
4043 return;
4044
4045}
4046
4047
4048/*
4049 * There is also a problem with range checking on the 7116.
4050 * It seems to only work for 22 bits, so the max size we can allocate
4051 * is 22 bits long or 4194304 bytes assuming that we put the beginning
4052 * of the buffer on a 2^24 bit boundary. The range registers will use
4053 * the top 8 bits of the dma start registers along with the bottom 22
4054 * bits of the range register to determine if we go out of range.
4055 * This makes getting memory a real kludge.
4056 *
4057 */
4058
4059#define RANGE_BOUNDARY (1<<22)
4060static vm_offset_t
4061get_bktr_mem( int unit, unsigned size )
4062{
4063 vm_offset_t addr = 0;
4064
4065 addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff, 1<<24);
4066 if (addr == 0)
4067 addr = vm_page_alloc_contig(size, 0x100000, 0xffffffff,
4068 PAGE_SIZE);
4069 if (addr == 0) {
4070 printf("bktr%d: Unable to allocate %d bytes of memory.\n",
4071 unit, size);
4072 }
4073
4074 return( addr );
4075}
4076
4077
4078
4079/*
4080 * Given a pixfmt index, compute the bt848 swap_flags necessary to
4081 * achieve the specified swapping.
4082 * Note that without bt swapping, 2Bpp and 3Bpp modes are written
4083 * byte-swapped, and 4Bpp modes are byte and word swapped (see Table 6
4084 * and read R->L).
4085 * Note also that for 3Bpp, we may additionally need to do some creative
4086 * SKIPing to align the FIFO bytelines with the target buffer (see split()).
4087 * This is abstracted here: e.g. no swaps = RGBA; byte & short swap = ABGR
4088 * as one would expect.
4089 */
4090
4091static u_int pixfmt_swap_flags( int pixfmt )
4092{
4093 struct meteor_pixfmt *pf = &pixfmt_table[ pixfmt ].public;
4094 u_int swapf = 0;
4095
4096 switch ( pf->Bpp ) {
4097 case 2 : swapf = ( pf->swap_bytes ? 0 : BSWAP );
4098 break;
4099
4100 case 3 : /* no swaps supported for 3bpp - makes no sense w/ bt848 */
4101 break;
4102
4103 case 4 : if ( pf->swap_bytes )
4104 swapf = pf->swap_shorts ? 0 : WSWAP;
4105 else
4106 swapf = pf->swap_shorts ? BSWAP : (BSWAP | WSWAP);
4107 break;
4108 }
4109 return swapf;
4110}
4111
4112
4113
4114/*
4115 * Converts meteor-defined pixel formats (e.g. METEOR_GEO_RGB16) into
4116 * our pixfmt_table indices.
4117 */
4118
4119static int oformat_meteor_to_bt( u_long format )
4120{
4121 int i;
4122 struct meteor_pixfmt *pf1, *pf2;
4123
4124 /* Find format in compatibility table */
4125 for ( i = 0; i < METEOR_PIXFMT_TABLE_SIZE; i++ )
4126 if ( meteor_pixfmt_table[i].meteor_format == format )
4127 break;
4128
4129 if ( i >= METEOR_PIXFMT_TABLE_SIZE )
4130 return -1;
4131 pf1 = &meteor_pixfmt_table[i].public;
4132
4133 /* Match it with an entry in master pixel format table */
4134 for ( i = 0; i < PIXFMT_TABLE_SIZE; i++ ) {
4135 pf2 = &pixfmt_table[i].public;
4136
4137 if (( pf1->type == pf2->type ) &&
4138 ( pf1->Bpp == pf2->Bpp ) &&
4139 !memcmp( pf1->masks, pf2->masks, sizeof( pf1->masks )) &&
4140 ( pf1->swap_bytes == pf2->swap_bytes ) &&
4141 ( pf1->swap_shorts == pf2->swap_shorts ))
4142 break;
4143 }
4144 if ( i >= PIXFMT_TABLE_SIZE )
4145 return -1;
4146
4147 return i;
4148}
4149
4150/******************************************************************************
4151 * i2c primitives:
4152 */
4153
4154/* */
4155#define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
4156#define I2CBITTIME_878 (1 << 7)
4157#define I2C_READ 0x01
4158#define I2C_COMMAND (I2CBITTIME | \
4159 BT848_DATA_CTL_I2CSCL | \
4160 BT848_DATA_CTL_I2CSDA)
4161
4162#define I2C_COMMAND_878 (I2CBITTIME_878 | \
4163 BT848_DATA_CTL_I2CSCL | \
4164 BT848_DATA_CTL_I2CSDA)
4165
4166
4167/*
4168 *
4169 */
4170static int
4171i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
4172{
4173 u_long x;
4174 u_long data;
4175 bt848_ptr_t bt848;
4176
4177 bt848 = bktr->base;
4178
4179 /* clear status bits */
4180 bt848->int_stat = (BT848_INT_RACK | BT848_INT_I2CDONE);
4181
4182 /* build the command datum */
4183 if (bktr->id == BROOKTREE_848_ID ||
4184 bktr->id == BROOKTREE_849_ID) {
4185 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
4186 } else {
4187 data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
4188 }
4189 if ( byte2 != -1 ) {
4190 data |= ((byte2 & 0xff) << 8);
4191 data |= BT848_DATA_CTL_I2CW3B;
4192 }
4193
4194 /* write the address and data */
4195 bt848->i2c_data_ctl = data;
4196
4197 /* wait for completion */
4198 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4199 if ( bt848->int_stat & BT848_INT_I2CDONE )
4200 break;
4201 }
4202
4203 /* check for ACK */
4204 if ( !x || !(bt848->int_stat & BT848_INT_RACK) )
4205 return( -1 );
4206
4207 /* return OK */
4208 return( 0 );
4209}
4210
4211
4212/*
4213 *
4214 */
4215static int
4216i2cRead( bktr_ptr_t bktr, int addr )
4217{
4218 u_long x;
4219 bt848_ptr_t bt848;
4220
4221 bt848 = bktr->base;
4222
4223 /* clear status bits */
4224 bt848->int_stat = (BT848_INT_RACK | BT848_INT_I2CDONE);
4225
4226 /* write the READ address */
4227 /* The Bt878 and Bt879 differed on the treatment of i2c commands */
4228
4229 if (bktr->id == BROOKTREE_848_ID ||
4230 bktr->id == BROOKTREE_849_ID) {
4231 bt848->i2c_data_ctl = ((addr & 0xff) << 24) | I2C_COMMAND;
4232 } else {
4233 bt848->i2c_data_ctl = ((addr & 0xff) << 24) | I2C_COMMAND_878;
4234 }
4235
4236 /* wait for completion */
4237 for ( x = 0x7fffffff; x; --x ) { /* safety valve */
4238 if ( bt848->int_stat & BT848_INT_I2CDONE )
4239 break;
4240 }
4241
4242 /* check for ACK */
4243 if ( !x || !(bt848->int_stat & BT848_INT_RACK) )
4244 return( -1 );
4245
4246 /* it was a read */
4247 return( (bt848->i2c_data_ctl >> 8) & 0xff );
4248}
4249
4250#if defined( I2C_SOFTWARE_PROBE )
4251
4252/*
4253 * we are keeping this around for any parts that we need to probe
4254 * but that CANNOT be probed via an i2c read.
4255 * this is necessary because the hardware i2c mechanism
4256 * cannot be programmed for 1 byte writes.
4257 * currently there are no known i2c parts that we need to probe
4258 * and that cannot be safely read.
4259 */
4260static int i2cProbe( bktr_ptr_t bktr, int addr );
4261#define BITD 40
4262#define EXTRA_START
4263
4264/*
4265 * probe for an I2C device at addr.
4266 */
4267static int
4268i2cProbe( bktr_ptr_t bktr, int addr )
4269{
4270 int x, status;
4271 bt848_ptr_t bt848;
4272
4273 bt848 = bktr->base;
4274
4275 /* the START */
4276#if defined( EXTRA_START )
4277 bt848->i2c_data_ctl = 1; DELAY( BITD ); /* release data */
4278 bt848->i2c_data_ctl = 3; DELAY( BITD ); /* release clock */
4279#endif /* EXTRA_START */
4280 bt848->i2c_data_ctl = 2; DELAY( BITD ); /* lower data */
4281 bt848->i2c_data_ctl = 0; DELAY( BITD ); /* lower clock */
4282
4283 /* write addr */
4284 for ( x = 7; x >= 0; --x ) {
4285 if ( addr & (1<<x) ) {
4286 bt848->i2c_data_ctl = 1;
4287 DELAY( BITD ); /* assert HI data */
4288 bt848->i2c_data_ctl = 3;
4289 DELAY( BITD ); /* strobe clock */
4290 bt848->i2c_data_ctl = 1;
4291 DELAY( BITD ); /* release clock */
4292 }
4293 else {
4294 bt848->i2c_data_ctl = 0;
4295 DELAY( BITD ); /* assert LO data */
4296 bt848->i2c_data_ctl = 2;
4297 DELAY( BITD ); /* strobe clock */
4298 bt848->i2c_data_ctl = 0;
4299 DELAY( BITD ); /* release clock */
4300 }
4301 }
4302
4303 /* look for an ACK */
4304 bt848->i2c_data_ctl = 1; DELAY( BITD ); /* float data */
4305 bt848->i2c_data_ctl = 3; DELAY( BITD ); /* strobe clock */
4306 status = bt848->i2c_data_ctl & 1; /* read the ACK bit */
4307 bt848->i2c_data_ctl = 1; DELAY( BITD ); /* release clock */
4308
4309 /* the STOP */
4310 bt848->i2c_data_ctl = 0; DELAY( BITD ); /* lower clock & data */
4311 bt848->i2c_data_ctl = 2; DELAY( BITD ); /* release clock */
4312 bt848->i2c_data_ctl = 3; DELAY( BITD ); /* release data */
4313
4314 return( status );
4315}
4316#undef EXTRA_START
4317#undef BITD
4318
4319#endif /* I2C_SOFTWARE_PROBE */
4320
4321
4322/*
4323 *
4324 */
4325static int
4326writeEEProm( bktr_ptr_t bktr, int offset, int count, u_char *data )
4327{
4328 return( -1 );
4329}
4330
4331
4332/*
4333 *
4334 */
4335static int
4336readEEProm( bktr_ptr_t bktr, int offset, int count, u_char *data )
4337{
4338 int x;
4339 int addr;
4340 int max;
4341 int byte;
4342
4343 /* get the address of the EEProm */
4344 addr = (int)(bktr->card.eepromAddr & 0xff);
4345 if ( addr == 0 )
4346 return( -1 );
4347
4348 max = (int)(bktr->card.eepromSize * EEPROMBLOCKSIZE);
4349 if ( (offset + count) > max )
4350 return( -1 );
4351
4352 /* set the start address */
4353 if ( i2cWrite( bktr, addr, offset, -1 ) == -1 )
4354 return( -1 );
4355
4356 /* the read cycle */
4357 for ( x = 0; x < count; ++x ) {
4358 if ( (byte = i2cRead( bktr, (addr | 1) )) == -1 )
4359 return( -1 );
4360 data[ x ] = byte;
4361 }
4362
4363 return( 0 );
4364}
4365
4366/*
4367 * get a signature of the card
4368 * read all 128 possible i2c read addresses from 0x01 thru 0xff
4369 * build a bit array with a 1 bit for each i2c device that responds
4370 *
4371 * XXX FIXME: use offset & count args
4372 */
4373#define ABSENT (-1)
4374static int
4375signCard( bktr_ptr_t bktr, int offset, int count, u_char* sig )
4376{
4377 int x;
4378
4379 for ( x = 0; x < 16; ++x )
4380 sig[ x ] = 0;
4381
4382 for ( x = 0; x < count; ++x ) {
4383 if ( i2cRead( bktr, (2 * x) + 1 ) != ABSENT ) {
4384 sig[ x / 8 ] |= (1 << (x % 8) );
4385 }
4386 }
4387
4388 return( 0 );
4389}
4390
4391/*
4392 * any_i2c_devices.
4393 * Some BT848/BT848A cards have no tuner and no additional i2c devices
4394 * eg stereo decoder. These are used for video conferencing or capture from
4395 * a video camera. (VideoLogic Captivator PCI, Intel SmartCapture card).
4396 *
4397 * Determine if there are any i2c devices present. There are none present if
4398 * a) reading from all 128 devices returns ABSENT (-1) for each one
4399 * (eg VideoLogic Captivator PCI with BT848)
4400 * b) reading from all 128 devices returns 0 for each one
4401 * (eg VideoLogic Captivator PCI rev. 2F with BT848A)
4402 */
4403static int check_for_i2c_devices( bktr_ptr_t bktr ){
4404 int x, temp_read;
4405 int i2c_all_0 = 1;
4406 int i2c_all_absent = 1;
4407 for ( x = 0; x < 128; ++x ) {
4408 temp_read = i2cRead( bktr, (2 * x) + 1 );
4409 if (temp_read != 0) i2c_all_0 = 0;
4410 if (temp_read != ABSENT) i2c_all_absent = 0;
4411 }
4412
4413 if ((i2c_all_0) || (i2c_all_absent)) return 0;
4414 else return 1;
4415}
4416#undef ABSENT
4417
4418/*
4419 * determine the card brand/model
4420 * OVERRIDE_CARD, OVERRIDE_TUNER, OVERRIDE_DBX and OVERRIDE_MSP
4421 * can be used to select a specific device, regardless of the
4422 * autodetection and i2c device checks.
4423 */
4424#define ABSENT (-1)
4425static void
4426probeCard( bktr_ptr_t bktr, int verbose )
4427{
4428 int card, i,j, card_found;
4429 int status, *test;
4430 bt848_ptr_t bt848;
4431 u_char probe_signature[128], *probe_temp;
4432 int any_i2c_devices;
4433 u_char probe_eeprom[128];
4434 u_long tuner_code = 0;
4435
4436
4437 any_i2c_devices = check_for_i2c_devices( bktr );
4438 bt848 = bktr->base;
4439
4440 bt848->gpio_out_en = 0;
4441 if (bootverbose)
4442 printf("bktr: GPIO is 0x%08x\n", bt848->gpio_data);
4443
4444#if defined( OVERRIDE_CARD )
4445 bktr->card = cards[ (card = OVERRIDE_CARD) ];
4446 goto checkTuner;
4447#endif
4448 if (bktr->bt848_card != -1 ) {
4449 bktr->card = cards[ (card = bktr->bt848_card) ];
4450 goto checkTuner;
4451 }
4452
4453
4454 /* Check for i2c devices */
4455 if (!any_i2c_devices) {
4456 bktr->card = cards[ (card = CARD_INTEL) ];
4457 goto checkTuner;
4458 }
4459
4460 /* look for a tuner */
4461 if ( i2cRead( bktr, TSA552x_RADDR ) == ABSENT ) {
4462 bktr->card = cards[ (card = CARD_INTEL) ];
4463 bktr->card.tuner = &tuners[ NO_TUNER ];
4464 goto checkDBX;
4465 }
4466
4467 /* look for a hauppauge card */
4468 if ( (status = i2cRead( bktr, PFC8582_RADDR )) != ABSENT ) {
4469 bktr->card = cards[ (card = CARD_HAUPPAUGE) ];
4470 goto checkTuner;
4471 }
4472
4473 /* look for an STB card */
4474 if ( (status = i2cRead( bktr, X24C01_RADDR )) != ABSENT ) {
4475 bktr->card = cards[ (card = CARD_STB) ];
4476 goto checkTuner;
4477 }
4478
4479 signCard( bktr, 1, 128, (u_char *) &probe_signature );
4480
4481 if (bootverbose) {
4482 printf("card signature \n");
4483 for (j = 0; j < Bt848_MAX_SIGN; j++) {
4484 printf(" %02x ", probe_signature[j]);
4485 }
4486 printf("\n\n");
4487 }
4488 for (i = 0;
4489 i < (sizeof bt848_card_signature)/ sizeof (struct bt848_card_sig);
4490 i++ ) {
4491
4492 card_found = 1;
4493 probe_temp = (u_char *) &bt848_card_signature[i].signature;
4494
4495 for (j = 0; j < Bt848_MAX_SIGN; j++) {
4496 if ((probe_temp[j] & 0xf) != (probe_signature[j] & 0xf)) {
4497 card_found = 0;
4498 break;
4499 }
4500
4501 }
4502 if (card_found) {
4503 bktr->card = cards[ card = bt848_card_signature[i].card];
4504 bktr->card.tuner = &tuners[ bt848_card_signature[i].tuner];
4505 goto checkDBX;
4506 }
4507 }
4508 /* XXX FIXME: (how do I) look for a Miro card */
4509 bktr->card = cards[ (card = CARD_MIRO) ];
4510
4511checkTuner:
4512#if defined( OVERRIDE_TUNER )
4513 bktr->card.tuner = &tuners[ OVERRIDE_TUNER ];
4514 goto checkDBX;
4515#endif
4516 if (bktr->bt848_tuner != -1 ) {
4517 bktr->card.tuner = &tuners[ bktr->bt848_tuner & 0xff ];
4518 goto checkDBX;
4519 }
4520
4521 /* Check for i2c devices */
4522 if (!any_i2c_devices) {
4523 bktr->card.tuner = &tuners[ NO_TUNER ];
4524 goto checkDBX;
4525 }
4526
4527 /* differentiate type of tuner */
4528
4529 switch (card) {
4530 case CARD_MIRO:
4531 switch (((bt848->gpio_data >> 10)-1)&7) {
4532 case 0: bktr->card.tuner = &tuners[ TEMIC_PAL ]; break;
4533 case 1: bktr->card.tuner = &tuners[ PHILIPS_PAL ]; break;
4534 case 2: bktr->card.tuner = &tuners[ PHILIPS_NTSC ]; break;
4535 case 3: bktr->card.tuner = &tuners[ PHILIPS_SECAM ]; break;
4536 case 4: bktr->card.tuner = &tuners[ NO_TUNER ]; break;
4537 case 5: bktr->card.tuner = &tuners[ PHILIPS_PALI ]; break;
4538 case 6: bktr->card.tuner = &tuners[ TEMIC_NTSC ]; break;
4539 case 7: bktr->card.tuner = &tuners[ TEMIC_PALI ]; break;
4540 }
4541 goto checkDBX;
4542 break;
4543
4544 case CARD_HAUPPAUGE:
4545 /* The Hauppauge Windows driver gives the following Tuner Table */
4546 /* To the right of this is the tuner models we select */
4547 /*
4548 1 External
4549 2 Unspecified
4550 3 Phillips FI1216
4551 4 Phillips FI1216MF
4552 5 Phillips FI1236 PHILIPS_NTSC
4553 6 Phillips FI1246
4554 7 Phillips FI1256
4555 8 Phillips FI1216 MK2 PHILIPS_PALI
4556 9 Phillips FI1216MF MK2
4557 a Phillips FI1236 MK2 PHILIPS_FR1236_NTSC
4558 b Phillips FI1246 MK2 PHILIPS_PALI
4559 c Phillips FI1256 MK2
4560 d Temic 4032FY5
4561 e Temic 4002FH5 TEMIC_PAL
4562 f Temic 4062FY5 TEMIC_PALI
4563 10 Phillips FR1216 MK2
4564 11 Phillips FR1216MF MK2
4565 12 Phillips FR1236 MK2 PHILIPS_FR1236_NTSC
4566 13 Phillips FR1246 MK2
4567 14 Phillips FR1256 MK2
4568 15 Phillips FM1216 PHILIPS_FR1216_PAL
4569 16 Phillips FM1216MF
4570 17 Phillips FM1236 PHILIPS_FR1236_NTSC
4571 */
4572
4573 readEEProm(bktr, 0, 128, (u_char *) &probe_eeprom );
4574
4575 tuner_code = probe_eeprom[9];
4576 switch (tuner_code) {
4577
4578 case 0x5:
4579 bktr->card.tuner = &tuners[ PHILIPS_NTSC ];
4580 goto checkDBX;
4581
4582 case 0x0a:
4583 case 0x12:
4584 case 0x17:
4585 bktr->card.tuner = &tuners[ PHILIPS_FR1236_NTSC ];
4586 goto checkDBX;
4587
4588 case 0x8:
4589 case 0xb:
4590 bktr->card.tuner = &tuners[ PHILIPS_PALI ];
4591 goto checkDBX;
4592
4593 case 0xe:
4594 bktr->card.tuner = &tuners[ TEMIC_PAL];
4595 goto checkDBX;
4596
4597 case 0xf:
4598 bktr->card.tuner = &tuners[ TEMIC_PALI ];
4599 goto checkDBX;
4600
4601 case 0x15:
4602 bktr->card.tuner = &tuners[ PHILIPS_FR1216_PAL];
4603 goto checkDBX;
4604 }
4605 /* Unknown Tuner Byte */
4606 break;
4607
4608 } /* end switch(card) */
4609
4610 /* At this point, a goto checkDBX has not occured */
4611 /* We have not been able to select a Tuner */
4612 /* We could simply go for No Tuner, but by some guesswork */
4613 /* we can try and select a suitable tuner */
4614
4615
4616 /* At address 0xc0/0xc1 is TEMIC NTSC and PHILIPS_FR1236_SECAM tuner*/
4617 /* If we find a tuner at this address, assume it is TEMIC NTSC */
4618 /* Sorry SECAM users */
4619
4620 if ( i2cRead( bktr, TEMIC_NTSC_RADDR ) != ABSENT ) {
4621 bktr->card.tuner = &tuners[ TEMIC_NTSC ];
4622 goto checkDBX;
4623 }
4624
4625 /* At address 0xc6/0xc7 is the PHILIPS NTSC Tuner */
4626 /* If we find a tuner at this address, assume it is PHILIPS NTSC */
4627 /* PHILIPS NTSC Tuner is at address 0xc6 / 0xc7 */
4628
4629 if ( i2cRead( bktr, PHILIPS_NTSC_RADDR ) != ABSENT ) {
4630 bktr->card.tuner = &tuners[ PHILIPS_NTSC ];
4631 goto checkDBX;
4632 }
4633
4634 /* At address 0xc2/0xc3 is the TEMIC_PALI, PHILIPS_PAL, */
4635 /* PHILIPS_FR_NTSC and PHILIPS_FR_PAL Tuners */
4636 /* and we cannot tell which is which. */
4637 /* Default to No Tuner */
4638
4639
4640 /* no tuner found */
4641 bktr->card.tuner = &tuners[ NO_TUNER ];
4642
4643
4644checkDBX:
4645#if defined( OVERRIDE_DBX )
4646 bktr->card.dbx = OVERRIDE_DBX;
4647 goto checkMSP;
4648#endif
4649 /* Check for i2c devices */
4650 if (!any_i2c_devices) {
4651 goto checkMSP;
4652 }
4653
4654 /* probe for BTSC (dbx) chip */
4655 if ( i2cRead( bktr, TDA9850_RADDR ) != ABSENT )
4656 bktr->card.dbx = 1;
4657
4658checkMSP:
4659#if defined( OVERRIDE_MSP )
4660 bktr->card.msp3400c = OVERRIDE_MSP;
4661 goto checkEnd;
4662#endif
4663 /* Check for i2c devices */
4664 if (!any_i2c_devices) {
4665 goto checkEnd;
4666 }
4667
4668 if ( i2cRead( bktr, MSP3400C_RADDR ) != ABSENT )
4669 bktr->card.msp3400c = 1;
4670
4671checkEnd:
4672
4673 if ( verbose ) {
4674 printf( "%s", bktr->card.name );
4675 if ( bktr->card.tuner )
4676 printf( ", %s tuner", bktr->card.tuner->name );
4677 if ( bktr->card.dbx )
4678 printf( ", dbx stereo" );
4679 if ( bktr->card.msp3400c )
4680 printf( ", msp3400c stereo" );
4681 printf( ".\n" );
4682 }
4683}
4684#undef ABSENT
4685
4686
4687/******************************************************************************
4688 * tuner specific routines:
4689 */
4690
4691
4692/* scaling factor for frequencies expressed as ints */
4693#define FREQFACTOR 16
4694
4695/*
4696 * Format:
4697 * entry 0: MAX legal channel
4698 * entry 1: IF frequency
4699 * expressed as fi{mHz} * 16,
4700 * eg 45.75mHz == 45.75 * 16 = 732
4701 * entry 2: [place holder/future]
4702 * entry 3: base of channel record 0
4703 * entry 3 + (x*3): base of channel record 'x'
4704 * entry LAST: NULL channel entry marking end of records
4705 *
4706 * Record:
4707 * int 0: base channel
4708 * int 1: frequency of base channel,
4709 * expressed as fb{mHz} * 16,
4710 * int 2: offset frequency between channels,
4711 * expressed as fo{mHz} * 16,
4712 */
4713
4714/*
4715 * North American Broadcast Channels:
4716 *
4717 * 2: 55.25 mHz - 4: 67.25 mHz
4718 * 5: 77.25 mHz - 6: 83.25 mHz
4719 * 7: 175.25 mHz - 13: 211.25 mHz
4720 * 14: 471.25 mHz - 83: 885.25 mHz
4721 *
4722 * IF freq: 45.75 mHz
4723 */
4724#define OFFSET 6.00
4725static int nabcst[] = {
4726 83, (int)( 45.75 * FREQFACTOR), 0,
4727 14, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4728 7, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4729 5, (int)( 77.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4730 2, (int)( 55.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4731 0
4732};
4733#undef OFFSET
4734
4735/*
4736 * North American Cable Channels, IRC:
4737 *
4738 * 2: 55.25 mHz - 4: 67.25 mHz
4739 * 5: 77.25 mHz - 6: 83.25 mHz
4740 * 7: 175.25 mHz - 13: 211.25 mHz
4741 * 14: 121.25 mHz - 22: 169.25 mHz
4742 * 23: 217.25 mHz - 94: 643.25 mHz
4743 * 95: 91.25 mHz - 99: 115.25 mHz
4744 *
4745 * IF freq: 45.75 mHz
4746 */
4747#define OFFSET 6.00
4748static int irccable[] = {
4749 99, (int)( 45.75 * FREQFACTOR), 0,
4750 95, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4751 23, (int)(217.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4752 14, (int)(121.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4753 7, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4754 5, (int)( 77.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4755 2, (int)( 55.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4756 0
4757};
4758#undef OFFSET
4759
4760/*
4761 * North American Cable Channels, HRC:
4762 *
4763 * 2: 54 mHz - 4: 66 mHz
4764 * 5: 78 mHz - 6: 84 mHz
4765 * 7: 174 mHz - 13: 210 mHz
4766 * 14: 120 mHz - 22: 168 mHz
4767 * 23: 216 mHz - 94: 642 mHz
4768 * 95: 90 mHz - 99: 114 mHz
4769 *
4770 * IF freq: 45.75 mHz
4771 */
4772#define OFFSET 6.00
4773static int hrccable[] = {
4774 99, (int)( 45.75 * FREQFACTOR), 0,
4775 95, (int)( 90.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4776 23, (int)(216.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4777 14, (int)(120.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4778 7, (int)(174.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4779 5, (int)( 78.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4780 2, (int)( 54.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4781 0
4782};
4783#undef OFFSET
4784
4785/*
4786 * Western European broadcast channels:
4787 *
4788 * (there are others that appear to vary between countries - rmt)
4789 *
4790 * here's the table Philips provides:
4791 * caution, some of the offsets don't compute...
4792 *
4793 * 1 4525 700 N21
4794 *
4795 * 2 4825 700 E2
4796 * 3 5525 700 E3
4797 * 4 6225 700 E4
4798 *
4799 * 5 17525 700 E5
4800 * 6 18225 700 E6
4801 * 7 18925 700 E7
4802 * 8 19625 700 E8
4803 * 9 20325 700 E9
4804 * 10 21025 700 E10
4805 * 11 21725 700 E11
4806 * 12 22425 700 E12
4807 *
4808 * 13 5375 700 ITA
4809 * 14 6225 700 ITB
4810 *
4811 * 15 8225 700 ITC
4812 *
4813 * 16 17525 700 ITD
4814 * 17 18325 700 ITE
4815 *
4816 * 18 19225 700 ITF
4817 * 19 20125 700 ITG
4818 * 20 21025 700 ITH
4819 *
4820 * 21 47125 800 E21
4821 * 22 47925 800 E22
4822 * 23 48725 800 E23
4823 * 24 49525 800 E24
4824 * 25 50325 800 E25
4825 * 26 51125 800 E26
4826 * 27 51925 800 E27
4827 * 28 52725 800 E28
4828 * 29 53525 800 E29
4829 * 30 54325 800 E30
4830 * 31 55125 800 E31
4831 * 32 55925 800 E32
4832 * 33 56725 800 E33
4833 * 34 57525 800 E34
4834 * 35 58325 800 E35
4835 * 36 59125 800 E36
4836 * 37 59925 800 E37
4837 * 38 60725 800 E38
4838 * 39 61525 800 E39
4839 * 40 62325 800 E40
4840 * 41 63125 800 E41
4841 * 42 63925 800 E42
4842 * 43 64725 800 E43
4843 * 44 65525 800 E44
4844 * 45 66325 800 E45
4845 * 46 67125 800 E46
4846 * 47 67925 800 E47
4847 * 48 68725 800 E48
4848 * 49 69525 800 E49
4849 * 50 70325 800 E50
4850 * 51 71125 800 E51
4851 * 52 71925 800 E52
4852 * 53 72725 800 E53
4853 * 54 73525 800 E54
4854 * 55 74325 800 E55
4855 * 56 75125 800 E56
4856 * 57 75925 800 E57
4857 * 58 76725 800 E58
4858 * 59 77525 800 E59
4859 * 60 78325 800 E60
4860 * 61 79125 800 E61
4861 * 62 79925 800 E62
4862 * 63 80725 800 E63
4863 * 64 81525 800 E64
4864 * 65 82325 800 E65
4865 * 66 83125 800 E66
4866 * 67 83925 800 E67
4867 * 68 84725 800 E68
4868 * 69 85525 800 E69
4869 *
4870 * 70 4575 800 IA
4871 * 71 5375 800 IB
4872 * 72 6175 800 IC
4873 *
4874 * 74 6925 700 S01
4875 * 75 7625 700 S02
4876 * 76 8325 700 S03
4877 *
4878 * 80 10525 700 S1
4879 * 81 11225 700 S2
4880 * 82 11925 700 S3
4881 * 83 12625 700 S4
4882 * 84 13325 700 S5
4883 * 85 14025 700 S6
4884 * 86 14725 700 S7
4885 * 87 15425 700 S8
4886 * 88 16125 700 S9
4887 * 89 16825 700 S10
4888 * 90 23125 700 S11
4889 * 91 23825 700 S12
4890 * 92 24525 700 S13
4891 * 93 25225 700 S14
4892 * 94 25925 700 S15
4893 * 95 26625 700 S16
4894 * 96 27325 700 S17
4895 * 97 28025 700 S18
4896 * 98 28725 700 S19
4897 * 99 29425 700 S20
4898 *
4899 *
4900 * Channels S21 - S41 are taken from
4901 * http://gemma.apple.com:80/dev/technotes/tn/tn1012.html
4902 *
4903 * 100 30325 800 S21
4904 * 101 31125 800 S22
4905 * 102 31925 800 S23
4906 * 103 32725 800 S24
4907 * 104 33525 800 S25
4908 * 105 34325 800 S26
4909 * 106 35125 800 S27
4910 * 107 35925 800 S28
4911 * 108 36725 800 S29
4912 * 109 37525 800 S30
4913 * 110 38325 800 S31
4914 * 111 39125 800 S32
4915 * 112 39925 800 S33
4916 * 113 40725 800 S34
4917 * 114 41525 800 S35
4918 * 115 42325 800 S36
4919 * 116 43125 800 S37
4920 * 117 43925 800 S38
4921 * 118 44725 800 S39
4922 * 119 45525 800 S40
4923 * 120 46325 800 S41
4924 *
4925 * 121 3890 000 IFFREQ
4926 *
4927 */
4928static int weurope[] = {
4929 121, (int)( 38.90 * FREQFACTOR), 0,
4930 100, (int)(303.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
4931 90, (int)(231.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR),
4932 80, (int)(105.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR),
4933 74, (int)( 69.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR),
4934 21, (int)(471.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
4935 17, (int)(183.25 * FREQFACTOR), (int)(9.00 * FREQFACTOR),
4936 16, (int)(175.25 * FREQFACTOR), (int)(9.00 * FREQFACTOR),
4937 15, (int)(82.25 * FREQFACTOR), (int)(8.50 * FREQFACTOR),
4938 13, (int)(53.75 * FREQFACTOR), (int)(8.50 * FREQFACTOR),
4939 5, (int)(175.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR),
4940 2, (int)(48.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR),
4941 0
4942};
4943
4944/*
4945 * Japanese Broadcast Channels:
4946 *
4947 * 1: 91.25MHz - 3: 103.25MHz
4948 * 4: 171.25MHz - 7: 189.25MHz
4949 * 8: 193.25MHz - 12: 217.25MHz (VHF)
4950 * 13: 471.25MHz - 62: 765.25MHz (UHF)
4951 *
4952 * IF freq: 45.75 mHz
4953 * OR
4954 * IF freq: 58.75 mHz
4955 */
4956#define OFFSET 6.00
4957#define IF_FREQ 45.75
4958static int jpnbcst[] = {
4959 62, (int)(IF_FREQ * FREQFACTOR), 0,
4960 13, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4961 8, (int)(193.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4962 4, (int)(171.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4963 1, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4964 0
4965};
4966#undef IF_FREQ
4967#undef OFFSET
4968
4969/*
4970 * Japanese Cable Channels:
4971 *
4972 * 1: 91.25MHz - 3: 103.25MHz
4973 * 4: 171.25MHz - 7: 189.25MHz
4974 * 8: 193.25MHz - 12: 217.25MHz
4975 * 13: 109.25MHz - 21: 157.25MHz
4976 * 22: 165.25MHz
4977 * 23: 223.25MHz - 63: 463.25MHz
4978 *
4979 * IF freq: 45.75 mHz
4980 */
4981#define OFFSET 6.00
4982#define IF_FREQ 45.75
4983static int jpncable[] = {
4984 63, (int)(IF_FREQ * FREQFACTOR), 0,
4985 23, (int)(223.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4986 22, (int)(165.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4987 13, (int)(109.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4988 8, (int)(193.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4989 4, (int)(171.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4990 1, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR),
4991 0
4992};
4993#undef IF_FREQ
4994#undef OFFSET
4995
4996/*
4997 * xUSSR Broadcast Channels:
4998 *
4999 * 1: 49.75MHz - 2: 59.25MHz
5000 * 3: 77.25MHz - 5: 93.25MHz
5001 * 6: 175.25MHz - 12: 223.25MHz
5002 * 13-20 - not exist
5003 * 21: 471.25MHz - 34: 575.25MHz
5004 * 35: 583.25MHz - 60: 775.25MHz
5005 *
5006 * IF freq: 38.90 MHz
5007 */
5008#define IF_FREQ 38.90
5009static int xussr[] = {
5010 60, (int)(IF_FREQ * FREQFACTOR), 0,
5011 35, (int)(583.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
5012 21, (int)(471.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
5013 6, (int)(175.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
5014 3, (int)( 77.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
5015 1, (int)( 49.75 * FREQFACTOR), (int)(9.50 * FREQFACTOR),
5016 0
5017};
5018#undef IF_FREQ
5019
5020static int* freqTable[] = {
5021 NULL,
5022 nabcst,
5023 irccable,
5024 hrccable,
5025 weurope,
5026 jpnbcst,
5027 jpncable,
5028 xussr
5029
5030};
5031
5032
5033#define TBL_CHNL freqTable[ bktr->tuner.chnlset ][ x ]
5034#define TBL_BASE_FREQ freqTable[ bktr->tuner.chnlset ][ x + 1 ]
5035#define TBL_OFFSET freqTable[ bktr->tuner.chnlset ][ x + 2 ]
5036static int
5037frequency_lookup( bktr_ptr_t bktr, int channel )
5038{
5039 int x;
5040
5041 /* check for "> MAX channel" */
5042 x = 0;
5043 if ( channel > TBL_CHNL )
5044 return( -1 );
5045
5046 /* search the table for data */
5047 for ( x = 3; TBL_CHNL; x += 3 ) {
5048 if ( channel >= TBL_CHNL ) {
5049 return( TBL_BASE_FREQ +
5050 ((channel - TBL_CHNL) * TBL_OFFSET) );
5051 }
5052 }
5053
5054 /* not found, must be below the MIN channel */
5055 return( -1 );
5056}
5057#undef TBL_OFFSET
5058#undef TBL_BASE_FREQ
5059#undef TBL_CHNL
5060
5061
5062#define TBL_IF freqTable[ bktr->tuner.chnlset ][ 1 ]
5063/*
5064 * set the frequency of the tuner
5065 */
5066static int
5067tv_freq( bktr_ptr_t bktr, int frequency )
5068{
5069 const struct TUNER* tuner;
5070 u_char addr;
5071 u_char control;
5072 u_char band;
5073 int N;
5074
5075 tuner = bktr->card.tuner;
5076 if ( tuner == NULL )
5077 return( -1 );
5078
5079 /*
5080 * select the band based on frequency
5081 * XXX FIXME: get the cross-over points from the tuner struct
5082 */
5083 if ( frequency < (160 * FREQFACTOR) )
5084 N = 0;
5085 else if ( frequency < (454 * FREQFACTOR) )
5086 N = 1;
5087 else
5088 N = 2;
5089
5090 if(frequency > RADIO_OFFSET) {
5091 N=3;
5092 frequency -= RADIO_OFFSET;
5093 }
5094
5095 /* set the address of the PLL */
5096 addr = tuner->pllAddr;
5097 control = tuner->pllControl[ N ];
5098 band = tuner->bandAddrs[ N ];
5099 if(!(band && control)) /* Don't try to set un- */
5100 return(-1); /* supported modes. */
5101
5102 if(N==3)
5103 band |= bktr->tuner.radio_mode;
5104
5105 /*
5106 * N = 16 * { fRF(pc) + fIF(pc) }
5107 * where:
5108 * pc is picture carrier, fRF & fIF are in mHz
5109 *
5110 * frequency was passed in as mHz * 16
5111 */
5112#if defined( TEST_TUNER_AFC )
5113 if ( bktr->tuner.afc )
5114 frequency -= 4;
5115#endif
5116 N = frequency + TBL_IF;
5117
5118 if ( frequency > bktr->tuner.frequency ) {
5119 i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff );
5120 i2cWrite( bktr, addr, control, band );
5121 }
5122 else {
5123 i2cWrite( bktr, addr, control, band );
5124 i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff );
5125 }
5126
5127#if defined( TUNER_AFC )
5128 if ( bktr->tuner.afc == TRUE ) {
5129 if ( (N = do_afc( bktr, addr, N )) < 0 ) {
5130 /* AFC failed, restore requested frequency */
5131 N = frequency + TBL_IF;
5132 i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff );
5133 }
5134 else
5135 frequency = N - TBL_IF;
5136 }
5137#endif /* TUNER_AFC */
5138
5139 /* update frequency */
5140 bktr->tuner.frequency = frequency;
5141
5142 return( 0 );
5143}
5144
5145#if defined( TUNER_AFC )
5146/*
5147 *
5148 */
5149static int
5150do_afc( bktr_ptr_t bktr, int addr, int frequency )
5151{
5152 int step;
5153 int status;
5154 int origFrequency;
5155
5156 origFrequency = frequency;
5157
5158 /* wait for first setting to take effect */
5159 tsleep( (caddr_t)bktr, PZERO, "tuning", hz/8 );
5160
5161 if ( (status = i2cRead( bktr, addr + 1 )) < 0 )
5162 return( -1 );
5163
5164#if defined( TEST_TUNER_AFC )
5165 printf( "\nOriginal freq: %d, status: 0x%02x\n", frequency, status );
5166#endif
5167 for ( step = 0; step < AFC_MAX_STEP; ++step ) {
5168 if ( (status = i2cRead( bktr, addr + 1 )) < 0 )
5169 goto fubar;
5170 if ( !(status & 0x40) ) {
5171#if defined( TEST_TUNER_AFC )
5172 printf( "no lock!\n" );
5173#endif
5174 goto fubar;
5175 }
5176
5177 switch( status & AFC_BITS ) {
5178 case AFC_FREQ_CENTERED:
5179#if defined( TEST_TUNER_AFC )
5180 printf( "Centered, freq: %d, status: 0x%02x\n", frequency, status );
5181#endif
5182 return( frequency );
5183
5184 case AFC_FREQ_MINUS_125:
5185 case AFC_FREQ_MINUS_62:
5186#if defined( TEST_TUNER_AFC )
5187 printf( "Low, freq: %d, status: 0x%02x\n", frequency, status );
5188#endif
5189 --frequency;
5190 break;
5191
5192 case AFC_FREQ_PLUS_62:
5193 case AFC_FREQ_PLUS_125:
5194#if defined( TEST_TUNER_AFC )
5195 printf( "Hi, freq: %d, status: 0x%02x\n", frequency, status );
5196#endif
5197 ++frequency;
5198 break;
5199 }
5200
5201 i2cWrite( bktr, addr,
5202 (frequency>>8) & 0x7f, frequency & 0xff );
5203 DELAY( AFC_DELAY );
5204 }
5205
5206 fubar:
5207 i2cWrite( bktr, addr,
5208 (origFrequency>>8) & 0x7f, origFrequency & 0xff );
5209
5210 return( -1 );
5211}
5212#endif /* TUNER_AFC */
5213#undef TBL_IF
5214
5215
5216/*
5217 * set the channel of the tuner
5218 */
5219static int
5220tv_channel( bktr_ptr_t bktr, int channel )
5221{
5222 int frequency;
5223
5224 /* calculate the frequency according to tuner type */
5225 if ( (frequency = frequency_lookup( bktr, channel )) < 0 )
5226 return( -1 );
5227
5228 /* set the new frequency */
5229 if ( tv_freq( bktr, frequency ) < 0 )
5230 return( -1 );
5231
5232 /* OK to update records */
5233 return( (bktr->tuner.channel = channel) );
5234}
5235
5236
5237/******************************************************************************
5238 * audio specific routines:
5239 */
5240
5241
5242/*
5243 *
5244 */
5245#define AUDIOMUX_DISCOVER_NOT
5246static int
5247set_audio( bktr_ptr_t bktr, int cmd )
5248{
5249 bt848_ptr_t bt848;
5250 u_long temp;
5251 volatile u_char idx;
5252
5253#if defined( AUDIOMUX_DISCOVER )
5254 if ( cmd >= 200 )
5255 cmd -= 200;
5256 else
5257#endif /* AUDIOMUX_DISCOVER */
5258
5259 /* check for existance of audio MUXes */
5260 if ( !bktr->card.audiomuxs[ 4 ] )
5261 return( -1 );
5262
5263 switch (cmd) {
5264 case AUDIO_TUNER:
5265#ifdef BKTR_REVERSEMUTE
5266 bktr->audio_mux_select = 3;
5267#else
5268 bktr->audio_mux_select = 0;
5269#endif
5270
5271 if (bktr->reverse_mute )
5272 bktr->audio_mux_select = 0;
5273 else
5274 bktr->audio_mux_select = 3;
5275
5276 break;
5277 case AUDIO_EXTERN:
5278 bktr->audio_mux_select = 1;
5279 break;
5280 case AUDIO_INTERN:
5281 bktr->audio_mux_select = 2;
5282 break;
5283 case AUDIO_MUTE:
5284 bktr->audio_mute_state = TRUE; /* set mute */
5285 break;
5286 case AUDIO_UNMUTE:
5287 bktr->audio_mute_state = FALSE; /* clear mute */
5288 break;
5289 default:
5290 printf("bktr: audio cmd error %02x\n", cmd);
5291 return( -1 );
5292 }
5293
5294 bt848 = bktr->base;
5295
5296 /*
5297 * Leave the upper bits of the GPIO port alone in case they control
5298 * something like the dbx or teletext chips. This doesn't guarantee
5299 * success, but follows the rule of least astonishment.
5300 */
5301
5302 /* XXX FIXME: this was an 8 bit reference before new struct ??? */
5303 bt848->gpio_reg_inp = (~GPIO_AUDIOMUX_BITS & 0xff);
5304
5305 if ( bktr->audio_mute_state == TRUE ) {
5306#ifdef BKTR_REVERSEMUTE
5307 idx = 0;
5308#else
5309 idx = 3;
5310#endif
5311
5312 if (bktr->reverse_mute )
5313 idx = 3;
5314 else
5315 idx = 0;
5316
5317 }
5318 else
5319 idx = bktr->audio_mux_select;
5320
5321 temp = bt848->gpio_data & ~GPIO_AUDIOMUX_BITS;
5322 bt848->gpio_data =
5323#if defined( AUDIOMUX_DISCOVER )
5324 bt848->gpio_data = temp | (cmd & 0xff);
5325 printf("cmd: %d audio mux %x temp %x \n", cmd,bktr->card.audiomuxs[ idx ], temp );
5326#else
5327 temp | bktr->card.audiomuxs[ idx ];
5328#endif /* AUDIOMUX_DISCOVER */
5329
5330 return( 0 );
5331}
5332
5333
5334/*
5335 *
5336 */
5337static void
5338temp_mute( bktr_ptr_t bktr, int flag )
5339{
5340 static int muteState = FALSE;
5341
5342 if ( flag == TRUE ) {
5343 muteState = bktr->audio_mute_state;
5344 set_audio( bktr, AUDIO_MUTE ); /* prevent 'click' */
5345 }
5346 else {
5347 tsleep( (caddr_t)bktr, PZERO, "tuning", hz/8 );
5348 if ( muteState == FALSE )
5349 set_audio( bktr, AUDIO_UNMUTE );
5350 }
5351}
5352
5353
5354/*
5355 * setup the dbx chip
5356 * XXX FIXME: alot of work to be done here, this merely unmutes it.
5357 */
5358static int
5359set_BTSC( bktr_ptr_t bktr, int control )
5360{
5361 return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) );
5362}
5363
5364
5365/******************************************************************************
5366 * magic:
5367 */
5368
5369
5370#ifdef __FreeBSD__
5371static bktr_devsw_installed = 0;
5372
5373static void
5374bktr_drvinit( void *unused )
5375{
5376 dev_t dev;
5377
5378 if ( ! bktr_devsw_installed ) {
5379 dev = makedev(CDEV_MAJOR, 0);
5380 cdevsw_add(&dev,&bktr_cdevsw, NULL);
5381 bktr_devsw_installed = 1;
5382 }
5383}
5384
5385SYSINIT(bktrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bktr_drvinit,NULL)
5386
5387#endif /* __FreeBSD__ */
5388#endif /* !defined(__FreeBSD__) || (NBKTR > 0 && NPCI > 0) */
5389
5390/* Local Variables: */
5391/* mode: C */
5392/* c-indent-level: 8 */
5393/* c-brace-offset: -8 */
5394/* c-argdecl-indent: 8 */
5395/* c-label-offset: -8 */
5396/* c-continued-statement-offset: 8 */
5397/* c-tab-always-indent: nil */
5398/* tab-width: 8 */
5399/* End: */