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