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