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