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