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