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: */
|