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