1 1.11 wiz /* $Sourceforge: bktr_tuner.c,v 1.5 2003/03/13 22:21:04 emsi Exp $ */ 2 1.1 wiz 3 1.13 andvar /* $NetBSD: bktr_tuner.c,v 1.13 2021/12/19 22:03:41 andvar Exp $ */ 4 1.10 wiz /* $FreeBSD: src/sys/dev/bktr/bktr_tuner.c,v 1.9 2000/10/19 07:33:28 roger Exp$ */ 5 1.1 wiz 6 1.1 wiz /* 7 1.1 wiz * This is part of the Driver for Video Capture Cards (Frame grabbers) 8 1.1 wiz * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 9 1.1 wiz * chipset. 10 1.1 wiz * Copyright Roger Hardiman and Amancio Hasty. 11 1.1 wiz * 12 1.1 wiz * bktr_tuner : This deals with controlling the tuner fitted to TV cards. 13 1.1 wiz * 14 1.1 wiz */ 15 1.1 wiz 16 1.1 wiz /* 17 1.1 wiz * 1. Redistributions of source code must retain the 18 1.1 wiz * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman 19 1.1 wiz * All rights reserved. 20 1.1 wiz * 21 1.1 wiz * Redistribution and use in source and binary forms, with or without 22 1.1 wiz * modification, are permitted provided that the following conditions 23 1.1 wiz * are met: 24 1.1 wiz * 1. Redistributions of source code must retain the above copyright 25 1.1 wiz * notice, this list of conditions and the following disclaimer. 26 1.1 wiz * 2. Redistributions in binary form must reproduce the above copyright 27 1.1 wiz * notice, this list of conditions and the following disclaimer in the 28 1.1 wiz * documentation and/or other materials provided with the distribution. 29 1.1 wiz * 3. All advertising materials mentioning features or use of this software 30 1.1 wiz * must display the following acknowledgement: 31 1.1 wiz * This product includes software developed by Amancio Hasty and 32 1.1 wiz * Roger Hardiman 33 1.1 wiz * 4. The name of the author may not be used to endorse or promote products 34 1.1 wiz * derived from this software without specific prior written permission. 35 1.1 wiz * 36 1.1 wiz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 37 1.1 wiz * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 38 1.1 wiz * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 1.1 wiz * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 40 1.1 wiz * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 41 1.1 wiz * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 42 1.1 wiz * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 1.1 wiz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 1.1 wiz * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 45 1.1 wiz * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 46 1.1 wiz * POSSIBILITY OF SUCH DAMAGE. 47 1.1 wiz */ 48 1.1 wiz 49 1.9 lukem #include <sys/cdefs.h> 50 1.13 andvar __KERNEL_RCSID(0, "$NetBSD: bktr_tuner.c,v 1.13 2021/12/19 22:03:41 andvar Exp $"); 51 1.1 wiz 52 1.1 wiz #include <sys/param.h> 53 1.1 wiz #include <sys/systm.h> 54 1.1 wiz #include <sys/kernel.h> 55 1.1 wiz #include <sys/vnode.h> 56 1.1 wiz #ifdef __NetBSD__ 57 1.1 wiz #include <sys/proc.h> 58 1.1 wiz #endif 59 1.1 wiz 60 1.1 wiz #ifdef __FreeBSD__ 61 1.1 wiz #include <pci/pcivar.h> 62 1.6 wiz 63 1.6 wiz #if (__FreeBSD_version < 500000) 64 1.6 wiz #include <machine/clock.h> /* for DELAY */ 65 1.6 wiz #endif 66 1.1 wiz 67 1.1 wiz #if (__FreeBSD_version >=300000) 68 1.1 wiz #include <machine/bus_memio.h> /* for bus space */ 69 1.12 ad #include <sys/bus.h> 70 1.1 wiz #include <sys/bus.h> 71 1.1 wiz #endif 72 1.2 wiz #endif 73 1.1 wiz 74 1.1 wiz #ifdef __NetBSD__ 75 1.2 wiz #include <dev/ic/bt8xx.h> /* NetBSD .h file location */ 76 1.2 wiz #include <dev/pci/bktr/bktr_reg.h> 77 1.2 wiz #include <dev/pci/bktr/bktr_tuner.h> 78 1.2 wiz #include <dev/pci/bktr/bktr_card.h> 79 1.2 wiz #include <dev/pci/bktr/bktr_core.h> 80 1.1 wiz #else 81 1.1 wiz #include <machine/ioctl_meteor.h> /* Traditional .h file location */ 82 1.1 wiz #include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ 83 1.1 wiz #include <dev/bktr/bktr_reg.h> 84 1.1 wiz #include <dev/bktr/bktr_tuner.h> 85 1.1 wiz #include <dev/bktr/bktr_card.h> 86 1.1 wiz #include <dev/bktr/bktr_core.h> 87 1.2 wiz #endif 88 1.1 wiz 89 1.1 wiz 90 1.1 wiz 91 1.10 wiz #if defined(TUNER_AFC) 92 1.13 andvar #define AFC_DELAY 10000 /* 10 milliseconds delay */ 93 1.1 wiz #define AFC_BITS 0x07 94 1.1 wiz #define AFC_FREQ_MINUS_125 0x00 95 1.1 wiz #define AFC_FREQ_MINUS_62 0x01 96 1.1 wiz #define AFC_FREQ_CENTERED 0x02 97 1.1 wiz #define AFC_FREQ_PLUS_62 0x03 98 1.1 wiz #define AFC_FREQ_PLUS_125 0x04 99 1.1 wiz #define AFC_MAX_STEP (5 * FREQFACTOR) /* no more than 5 MHz */ 100 1.1 wiz #endif /* TUNER_AFC */ 101 1.1 wiz 102 1.10 wiz 103 1.1 wiz #define TTYPE_XXX 0 104 1.1 wiz #define TTYPE_NTSC 1 105 1.1 wiz #define TTYPE_NTSC_J 2 106 1.1 wiz #define TTYPE_PAL 3 107 1.1 wiz #define TTYPE_PAL_M 4 108 1.1 wiz #define TTYPE_PAL_N 5 109 1.1 wiz #define TTYPE_SECAM 6 110 1.10 wiz 111 1.1 wiz #define TSA552x_CB_MSB (0x80) 112 1.1 wiz #define TSA552x_CB_CP (1<<6) /* set this for fast tuning */ 113 1.1 wiz #define TSA552x_CB_T2 (1<<5) /* test mode - Normally set to 0 */ 114 1.1 wiz #define TSA552x_CB_T1 (1<<4) /* test mode - Normally set to 0 */ 115 1.1 wiz #define TSA552x_CB_T0 (1<<3) /* test mode - Normally set to 1 */ 116 1.10 wiz #define TSA552x_CB_RSA (1<<2) /* 0 for 31.25 kHz, 1 for 62.5 kHz */ 117 1.1 wiz #define TSA552x_CB_RSB (1<<1) /* 0 for FM 50kHz steps, 1 = Use RSA*/ 118 1.1 wiz #define TSA552x_CB_OS (1<<0) /* Set to 0 for normal operation */ 119 1.1 wiz 120 1.1 wiz #define TSA552x_RADIO (TSA552x_CB_MSB | \ 121 1.1 wiz TSA552x_CB_T0) 122 1.1 wiz 123 1.1 wiz /* raise the charge pump voltage for fast tuning */ 124 1.1 wiz #define TSA552x_FCONTROL (TSA552x_CB_MSB | \ 125 1.1 wiz TSA552x_CB_CP | \ 126 1.1 wiz TSA552x_CB_T0 | \ 127 1.1 wiz TSA552x_CB_RSA | \ 128 1.1 wiz TSA552x_CB_RSB) 129 1.10 wiz 130 1.1 wiz /* lower the charge pump voltage for better residual oscillator FM */ 131 1.1 wiz #define TSA552x_SCONTROL (TSA552x_CB_MSB | \ 132 1.1 wiz TSA552x_CB_T0 | \ 133 1.1 wiz TSA552x_CB_RSA | \ 134 1.1 wiz TSA552x_CB_RSB) 135 1.10 wiz 136 1.1 wiz /* The control value for the ALPS TSCH5 Tuner */ 137 1.1 wiz #define TSCH5_FCONTROL 0x82 138 1.1 wiz #define TSCH5_RADIO 0x86 139 1.10 wiz 140 1.1 wiz /* The control value for the ALPS TSBH1 Tuner */ 141 1.1 wiz #define TSBH1_FCONTROL 0xce 142 1.1 wiz 143 1.1 wiz 144 1.1 wiz static const struct TUNER tuners[] = { 145 1.1 wiz /* XXX FIXME: fill in the band-switch crosspoints */ 146 1.1 wiz /* NO_TUNER */ 147 1.1 wiz { "<no>", /* the 'name' */ 148 1.1 wiz TTYPE_XXX, /* input type */ 149 1.1 wiz { 0x00, /* control byte for Tuner PLL */ 150 1.1 wiz 0x00, 151 1.1 wiz 0x00, 152 1.1 wiz 0x00 }, 153 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 154 1.1 wiz { 0x00, 0x00, 0x00,0x00} }, /* the band-switch values */ 155 1.1 wiz 156 1.1 wiz /* TEMIC_NTSC */ 157 1.1 wiz { "Temic NTSC", /* the 'name' */ 158 1.1 wiz TTYPE_NTSC, /* input type */ 159 1.1 wiz { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 160 1.1 wiz TSA552x_SCONTROL, 161 1.1 wiz TSA552x_SCONTROL, 162 1.1 wiz 0x00 }, 163 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 164 1.1 wiz { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */ 165 1.1 wiz 166 1.1 wiz /* TEMIC_PAL */ 167 1.1 wiz { "Temic PAL", /* the 'name' */ 168 1.1 wiz TTYPE_PAL, /* input type */ 169 1.1 wiz { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 170 1.1 wiz TSA552x_SCONTROL, 171 1.1 wiz TSA552x_SCONTROL, 172 1.1 wiz 0x00 }, 173 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 174 1.1 wiz { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */ 175 1.1 wiz 176 1.1 wiz /* TEMIC_SECAM */ 177 1.1 wiz { "Temic SECAM", /* the 'name' */ 178 1.1 wiz TTYPE_SECAM, /* input type */ 179 1.1 wiz { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 180 1.1 wiz TSA552x_SCONTROL, 181 1.1 wiz TSA552x_SCONTROL, 182 1.1 wiz 0x00 }, 183 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 184 1.1 wiz { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */ 185 1.1 wiz 186 1.1 wiz /* PHILIPS_NTSC */ 187 1.1 wiz { "Philips NTSC", /* the 'name' */ 188 1.1 wiz TTYPE_NTSC, /* input type */ 189 1.1 wiz { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 190 1.1 wiz TSA552x_SCONTROL, 191 1.1 wiz TSA552x_SCONTROL, 192 1.1 wiz 0x00 }, 193 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 194 1.1 wiz { 0xa0, 0x90, 0x30, 0x00 } }, /* the band-switch values */ 195 1.1 wiz 196 1.1 wiz /* PHILIPS_PAL */ 197 1.1 wiz { "Philips PAL", /* the 'name' */ 198 1.1 wiz TTYPE_PAL, /* input type */ 199 1.1 wiz { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 200 1.1 wiz TSA552x_SCONTROL, 201 1.1 wiz TSA552x_SCONTROL, 202 1.1 wiz 0x00 }, 203 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 204 1.1 wiz { 0xa0, 0x90, 0x30, 0x00 } }, /* the band-switch values */ 205 1.1 wiz 206 1.1 wiz /* PHILIPS_SECAM */ 207 1.1 wiz { "Philips SECAM", /* the 'name' */ 208 1.1 wiz TTYPE_SECAM, /* input type */ 209 1.1 wiz { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 210 1.1 wiz TSA552x_SCONTROL, 211 1.1 wiz TSA552x_SCONTROL, 212 1.1 wiz 0x00 }, 213 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 214 1.1 wiz { 0xa7, 0x97, 0x37, 0x00 } }, /* the band-switch values */ 215 1.1 wiz 216 1.1 wiz /* TEMIC_PAL I */ 217 1.1 wiz { "Temic PAL I", /* the 'name' */ 218 1.1 wiz TTYPE_PAL, /* input type */ 219 1.1 wiz { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 220 1.1 wiz TSA552x_SCONTROL, 221 1.1 wiz TSA552x_SCONTROL, 222 1.1 wiz 0x00 }, 223 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 224 1.1 wiz { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */ 225 1.1 wiz 226 1.1 wiz /* PHILIPS_PALI */ 227 1.1 wiz { "Philips PAL I", /* the 'name' */ 228 1.1 wiz TTYPE_PAL, /* input type */ 229 1.1 wiz { TSA552x_SCONTROL, /* control byte for Tuner PLL */ 230 1.1 wiz TSA552x_SCONTROL, 231 1.1 wiz TSA552x_SCONTROL, 232 1.1 wiz 0x00 }, 233 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 234 1.1 wiz { 0xa0, 0x90, 0x30,0x00 } }, /* the band-switch values */ 235 1.1 wiz 236 1.1 wiz /* PHILIPS_FR1236_NTSC */ 237 1.1 wiz { "Philips FR1236 NTSC FM", /* the 'name' */ 238 1.1 wiz TTYPE_NTSC, /* input type */ 239 1.1 wiz { TSA552x_FCONTROL, /* control byte for Tuner PLL */ 240 1.1 wiz TSA552x_FCONTROL, 241 1.1 wiz TSA552x_FCONTROL, 242 1.1 wiz TSA552x_RADIO }, 243 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 244 1.1 wiz { 0xa0, 0x90, 0x30,0xa4 } }, /* the band-switch values */ 245 1.1 wiz 246 1.1 wiz /* PHILIPS_FR1216_PAL */ 247 1.1 wiz { "Philips FR1216 PAL FM" , /* the 'name' */ 248 1.1 wiz TTYPE_PAL, /* input type */ 249 1.1 wiz { TSA552x_FCONTROL, /* control byte for Tuner PLL */ 250 1.1 wiz TSA552x_FCONTROL, 251 1.1 wiz TSA552x_FCONTROL, 252 1.1 wiz TSA552x_RADIO }, 253 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 254 1.1 wiz { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */ 255 1.1 wiz 256 1.1 wiz /* PHILIPS_FR1236_SECAM */ 257 1.1 wiz { "Philips FR1236 SECAM FM", /* the 'name' */ 258 1.1 wiz TTYPE_SECAM, /* input type */ 259 1.1 wiz { TSA552x_FCONTROL, /* control byte for Tuner PLL */ 260 1.1 wiz TSA552x_FCONTROL, 261 1.1 wiz TSA552x_FCONTROL, 262 1.1 wiz TSA552x_RADIO }, 263 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 264 1.1 wiz { 0xa7, 0x97, 0x37, 0xa4 } }, /* the band-switch values */ 265 1.1 wiz 266 1.1 wiz /* ALPS TSCH5 NTSC */ 267 1.1 wiz { "ALPS TSCH5 NTSC FM", /* the 'name' */ 268 1.1 wiz TTYPE_NTSC, /* input type */ 269 1.1 wiz { TSCH5_FCONTROL, /* control byte for Tuner PLL */ 270 1.1 wiz TSCH5_FCONTROL, 271 1.1 wiz TSCH5_FCONTROL, 272 1.1 wiz TSCH5_RADIO }, 273 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 274 1.1 wiz { 0x14, 0x12, 0x11, 0x04 } }, /* the band-switch values */ 275 1.1 wiz 276 1.1 wiz /* ALPS TSBH1 NTSC */ 277 1.1 wiz { "ALPS TSBH1 NTSC", /* the 'name' */ 278 1.1 wiz TTYPE_NTSC, /* input type */ 279 1.1 wiz { TSBH1_FCONTROL, /* control byte for Tuner PLL */ 280 1.1 wiz TSBH1_FCONTROL, 281 1.1 wiz TSBH1_FCONTROL, 282 1.1 wiz 0x00 }, 283 1.11 wiz { 160, 454 }, /* band-switch crosspoints */ 284 1.1 wiz { 0x01, 0x02, 0x08, 0x00 } } /* the band-switch values */ 285 1.1 wiz }; 286 1.1 wiz 287 1.1 wiz 288 1.1 wiz /* scaling factor for frequencies expressed as ints */ 289 1.1 wiz #define FREQFACTOR 16 290 1.1 wiz 291 1.1 wiz /* 292 1.1 wiz * Format: 293 1.1 wiz * entry 0: MAX legal channel 294 1.1 wiz * entry 1: IF frequency 295 1.10 wiz * expressed as fi{MHz} * 16, 296 1.10 wiz * eg 45.75MHz == 45.75 * 16 = 732 297 1.1 wiz * entry 2: [place holder/future] 298 1.1 wiz * entry 3: base of channel record 0 299 1.1 wiz * entry 3 + (x*3): base of channel record 'x' 300 1.1 wiz * entry LAST: NULL channel entry marking end of records 301 1.1 wiz * 302 1.1 wiz * Record: 303 1.1 wiz * int 0: base channel 304 1.1 wiz * int 1: frequency of base channel, 305 1.10 wiz * expressed as fb{MHz} * 16, 306 1.1 wiz * int 2: offset frequency between channels, 307 1.10 wiz * expressed as fo{MHz} * 16, 308 1.1 wiz */ 309 1.1 wiz 310 1.1 wiz /* 311 1.1 wiz * North American Broadcast Channels: 312 1.1 wiz * 313 1.10 wiz * 2: 55.25 MHz - 4: 67.25 MHz 314 1.10 wiz * 5: 77.25 MHz - 6: 83.25 MHz 315 1.10 wiz * 7: 175.25 MHz - 13: 211.25 MHz 316 1.10 wiz * 14: 471.25 MHz - 83: 885.25 MHz 317 1.1 wiz * 318 1.10 wiz * IF freq: 45.75 MHz 319 1.1 wiz */ 320 1.1 wiz #define OFFSET 6.00 321 1.8 jdolecek static const int nabcst[] = { 322 1.1 wiz 83, (int)( 45.75 * FREQFACTOR), 0, 323 1.1 wiz 14, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 324 1.1 wiz 7, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 325 1.1 wiz 5, (int)( 77.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 326 1.1 wiz 2, (int)( 55.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 327 1.1 wiz 0 328 1.1 wiz }; 329 1.1 wiz #undef OFFSET 330 1.1 wiz 331 1.1 wiz /* 332 1.1 wiz * North American Cable Channels, IRC: 333 1.1 wiz * 334 1.10 wiz * 2: 55.25 MHz - 4: 67.25 MHz 335 1.10 wiz * 5: 77.25 MHz - 6: 83.25 MHz 336 1.10 wiz * 7: 175.25 MHz - 13: 211.25 MHz 337 1.10 wiz * 14: 121.25 MHz - 22: 169.25 MHz 338 1.10 wiz * 23: 217.25 MHz - 94: 643.25 MHz 339 1.10 wiz * 95: 91.25 MHz - 99: 115.25 MHz 340 1.1 wiz * 341 1.10 wiz * IF freq: 45.75 MHz 342 1.1 wiz */ 343 1.1 wiz #define OFFSET 6.00 344 1.8 jdolecek static const int irccable[] = { 345 1.10 wiz 116, (int)( 45.75 * FREQFACTOR), 0, 346 1.10 wiz 100, (int)(649.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 347 1.10 wiz 95, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 348 1.10 wiz 23, (int)(217.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 349 1.10 wiz 14, (int)(121.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 350 1.10 wiz 7, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 351 1.10 wiz 5, (int)( 77.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 352 1.10 wiz 2, (int)( 55.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 353 1.10 wiz 0 354 1.1 wiz }; 355 1.1 wiz #undef OFFSET 356 1.1 wiz 357 1.1 wiz /* 358 1.1 wiz * North American Cable Channels, HRC: 359 1.1 wiz * 360 1.10 wiz * 2: 54 MHz - 4: 66 MMz 361 1.10 wiz * 5: 78 MHz - 6: 84 MHz 362 1.10 wiz * 7: 174 MHz - 13: 210 MHz 363 1.10 wiz * 14: 120 MHz - 22: 168 MHz 364 1.10 wiz * 23: 216 MHz - 94: 642 MHz 365 1.10 wiz * 95: 90 MHz - 99: 114 MHz 366 1.1 wiz * 367 1.10 wiz * IF freq: 45.75 MHz 368 1.1 wiz */ 369 1.1 wiz #define OFFSET 6.00 370 1.8 jdolecek static const int hrccable[] = { 371 1.10 wiz 116, (int)( 45.75 * FREQFACTOR), 0, 372 1.10 wiz 100, (int)(648.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 373 1.10 wiz 95, (int)( 90.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 374 1.10 wiz 23, (int)(216.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 375 1.10 wiz 14, (int)(120.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 376 1.10 wiz 7, (int)(174.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 377 1.10 wiz 5, (int)( 78.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 378 1.10 wiz 2, (int)( 54.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 379 1.10 wiz 0 380 1.1 wiz }; 381 1.1 wiz #undef OFFSET 382 1.1 wiz 383 1.1 wiz /* 384 1.1 wiz * Western European broadcast channels: 385 1.1 wiz * 386 1.1 wiz * (there are others that appear to vary between countries - rmt) 387 1.1 wiz * 388 1.1 wiz * here's the table Philips provides: 389 1.1 wiz * caution, some of the offsets don't compute... 390 1.1 wiz * 391 1.1 wiz * 1 4525 700 N21 392 1.10 wiz * 393 1.1 wiz * 2 4825 700 E2 394 1.1 wiz * 3 5525 700 E3 395 1.1 wiz * 4 6225 700 E4 396 1.10 wiz * 397 1.1 wiz * 5 17525 700 E5 398 1.1 wiz * 6 18225 700 E6 399 1.1 wiz * 7 18925 700 E7 400 1.1 wiz * 8 19625 700 E8 401 1.1 wiz * 9 20325 700 E9 402 1.1 wiz * 10 21025 700 E10 403 1.1 wiz * 11 21725 700 E11 404 1.1 wiz * 12 22425 700 E12 405 1.10 wiz * 406 1.1 wiz * 13 5375 700 ITA 407 1.1 wiz * 14 6225 700 ITB 408 1.10 wiz * 409 1.1 wiz * 15 8225 700 ITC 410 1.10 wiz * 411 1.1 wiz * 16 17525 700 ITD 412 1.1 wiz * 17 18325 700 ITE 413 1.10 wiz * 414 1.1 wiz * 18 19225 700 ITF 415 1.1 wiz * 19 20125 700 ITG 416 1.1 wiz * 20 21025 700 ITH 417 1.10 wiz * 418 1.1 wiz * 21 47125 800 E21 419 1.1 wiz * 22 47925 800 E22 420 1.1 wiz * 23 48725 800 E23 421 1.1 wiz * 24 49525 800 E24 422 1.1 wiz * 25 50325 800 E25 423 1.1 wiz * 26 51125 800 E26 424 1.1 wiz * 27 51925 800 E27 425 1.1 wiz * 28 52725 800 E28 426 1.1 wiz * 29 53525 800 E29 427 1.1 wiz * 30 54325 800 E30 428 1.1 wiz * 31 55125 800 E31 429 1.1 wiz * 32 55925 800 E32 430 1.1 wiz * 33 56725 800 E33 431 1.1 wiz * 34 57525 800 E34 432 1.1 wiz * 35 58325 800 E35 433 1.1 wiz * 36 59125 800 E36 434 1.1 wiz * 37 59925 800 E37 435 1.1 wiz * 38 60725 800 E38 436 1.1 wiz * 39 61525 800 E39 437 1.1 wiz * 40 62325 800 E40 438 1.1 wiz * 41 63125 800 E41 439 1.1 wiz * 42 63925 800 E42 440 1.1 wiz * 43 64725 800 E43 441 1.1 wiz * 44 65525 800 E44 442 1.1 wiz * 45 66325 800 E45 443 1.1 wiz * 46 67125 800 E46 444 1.1 wiz * 47 67925 800 E47 445 1.1 wiz * 48 68725 800 E48 446 1.1 wiz * 49 69525 800 E49 447 1.1 wiz * 50 70325 800 E50 448 1.1 wiz * 51 71125 800 E51 449 1.1 wiz * 52 71925 800 E52 450 1.1 wiz * 53 72725 800 E53 451 1.1 wiz * 54 73525 800 E54 452 1.1 wiz * 55 74325 800 E55 453 1.1 wiz * 56 75125 800 E56 454 1.1 wiz * 57 75925 800 E57 455 1.1 wiz * 58 76725 800 E58 456 1.1 wiz * 59 77525 800 E59 457 1.1 wiz * 60 78325 800 E60 458 1.1 wiz * 61 79125 800 E61 459 1.1 wiz * 62 79925 800 E62 460 1.1 wiz * 63 80725 800 E63 461 1.1 wiz * 64 81525 800 E64 462 1.1 wiz * 65 82325 800 E65 463 1.1 wiz * 66 83125 800 E66 464 1.1 wiz * 67 83925 800 E67 465 1.1 wiz * 68 84725 800 E68 466 1.1 wiz * 69 85525 800 E69 467 1.10 wiz * 468 1.1 wiz * 70 4575 800 IA 469 1.1 wiz * 71 5375 800 IB 470 1.1 wiz * 72 6175 800 IC 471 1.10 wiz * 472 1.1 wiz * 74 6925 700 S01 473 1.1 wiz * 75 7625 700 S02 474 1.1 wiz * 76 8325 700 S03 475 1.10 wiz * 476 1.1 wiz * 80 10525 700 S1 477 1.1 wiz * 81 11225 700 S2 478 1.1 wiz * 82 11925 700 S3 479 1.1 wiz * 83 12625 700 S4 480 1.1 wiz * 84 13325 700 S5 481 1.1 wiz * 85 14025 700 S6 482 1.1 wiz * 86 14725 700 S7 483 1.1 wiz * 87 15425 700 S8 484 1.1 wiz * 88 16125 700 S9 485 1.1 wiz * 89 16825 700 S10 486 1.1 wiz * 90 23125 700 S11 487 1.1 wiz * 91 23825 700 S12 488 1.1 wiz * 92 24525 700 S13 489 1.1 wiz * 93 25225 700 S14 490 1.1 wiz * 94 25925 700 S15 491 1.1 wiz * 95 26625 700 S16 492 1.1 wiz * 96 27325 700 S17 493 1.1 wiz * 97 28025 700 S18 494 1.1 wiz * 98 28725 700 S19 495 1.1 wiz * 99 29425 700 S20 496 1.1 wiz * 497 1.1 wiz * 498 1.1 wiz * Channels S21 - S41 are taken from 499 1.1 wiz * http://gemma.apple.com:80/dev/technotes/tn/tn1012.html 500 1.1 wiz * 501 1.1 wiz * 100 30325 800 S21 502 1.1 wiz * 101 31125 800 S22 503 1.1 wiz * 102 31925 800 S23 504 1.1 wiz * 103 32725 800 S24 505 1.1 wiz * 104 33525 800 S25 506 1.10 wiz * 105 34325 800 S26 507 1.10 wiz * 106 35125 800 S27 508 1.10 wiz * 107 35925 800 S28 509 1.10 wiz * 108 36725 800 S29 510 1.10 wiz * 109 37525 800 S30 511 1.10 wiz * 110 38325 800 S31 512 1.10 wiz * 111 39125 800 S32 513 1.10 wiz * 112 39925 800 S33 514 1.10 wiz * 113 40725 800 S34 515 1.10 wiz * 114 41525 800 S35 516 1.10 wiz * 115 42325 800 S36 517 1.10 wiz * 116 43125 800 S37 518 1.10 wiz * 117 43925 800 S38 519 1.10 wiz * 118 44725 800 S39 520 1.10 wiz * 119 45525 800 S40 521 1.1 wiz * 120 46325 800 S41 522 1.10 wiz * 523 1.1 wiz * 121 3890 000 IFFREQ 524 1.10 wiz * 525 1.1 wiz */ 526 1.8 jdolecek static const int weurope[] = { 527 1.10 wiz 121, (int)( 38.90 * FREQFACTOR), 0, 528 1.10 wiz 100, (int)(303.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 529 1.10 wiz 90, (int)(231.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 530 1.10 wiz 80, (int)(105.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 531 1.10 wiz 74, (int)( 69.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 532 1.10 wiz 21, (int)(471.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 533 1.10 wiz 17, (int)(183.25 * FREQFACTOR), (int)(9.00 * FREQFACTOR), 534 1.10 wiz 16, (int)(175.25 * FREQFACTOR), (int)(9.00 * FREQFACTOR), 535 1.10 wiz 15, (int)( 82.25 * FREQFACTOR), (int)(8.50 * FREQFACTOR), 536 1.10 wiz 13, (int)( 53.75 * FREQFACTOR), (int)(8.50 * FREQFACTOR), 537 1.10 wiz 5, (int)(175.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 538 1.10 wiz 2, (int)( 48.25 * FREQFACTOR), (int)(7.00 * FREQFACTOR), 539 1.10 wiz 0 540 1.1 wiz }; 541 1.1 wiz 542 1.1 wiz /* 543 1.1 wiz * Japanese Broadcast Channels: 544 1.1 wiz * 545 1.1 wiz * 1: 91.25MHz - 3: 103.25MHz 546 1.1 wiz * 4: 171.25MHz - 7: 189.25MHz 547 1.1 wiz * 8: 193.25MHz - 12: 217.25MHz (VHF) 548 1.1 wiz * 13: 471.25MHz - 62: 765.25MHz (UHF) 549 1.1 wiz * 550 1.10 wiz * IF freq: 45.75 MHz 551 1.1 wiz * OR 552 1.10 wiz * IF freq: 58.75 MHz 553 1.1 wiz */ 554 1.1 wiz #define OFFSET 6.00 555 1.1 wiz #define IF_FREQ 45.75 556 1.8 jdolecek static const int jpnbcst[] = { 557 1.10 wiz 62, (int)(IF_FREQ * FREQFACTOR), 0, 558 1.10 wiz 13, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 559 1.10 wiz 8, (int)(193.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 560 1.10 wiz 4, (int)(171.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 561 1.10 wiz 1, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 562 1.1 wiz 0 563 1.1 wiz }; 564 1.1 wiz #undef IF_FREQ 565 1.1 wiz #undef OFFSET 566 1.1 wiz 567 1.1 wiz /* 568 1.1 wiz * Japanese Cable Channels: 569 1.1 wiz * 570 1.1 wiz * 1: 91.25MHz - 3: 103.25MHz 571 1.1 wiz * 4: 171.25MHz - 7: 189.25MHz 572 1.1 wiz * 8: 193.25MHz - 12: 217.25MHz 573 1.1 wiz * 13: 109.25MHz - 21: 157.25MHz 574 1.1 wiz * 22: 165.25MHz 575 1.1 wiz * 23: 223.25MHz - 63: 463.25MHz 576 1.1 wiz * 577 1.10 wiz * IF freq: 45.75 MHz 578 1.1 wiz */ 579 1.1 wiz #define OFFSET 6.00 580 1.1 wiz #define IF_FREQ 45.75 581 1.8 jdolecek static const int jpncable[] = { 582 1.10 wiz 63, (int)(IF_FREQ * FREQFACTOR), 0, 583 1.10 wiz 23, (int)(223.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 584 1.10 wiz 22, (int)(165.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 585 1.10 wiz 13, (int)(109.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 586 1.10 wiz 8, (int)(193.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 587 1.10 wiz 4, (int)(171.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 588 1.10 wiz 1, (int)( 91.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 589 1.1 wiz 0 590 1.1 wiz }; 591 1.1 wiz #undef IF_FREQ 592 1.1 wiz #undef OFFSET 593 1.1 wiz 594 1.1 wiz /* 595 1.1 wiz * xUSSR Broadcast Channels: 596 1.1 wiz * 597 1.1 wiz * 1: 49.75MHz - 2: 59.25MHz 598 1.1 wiz * 3: 77.25MHz - 5: 93.25MHz 599 1.1 wiz * 6: 175.25MHz - 12: 223.25MHz 600 1.1 wiz * 13-20 - not exist 601 1.1 wiz * 21: 471.25MHz - 34: 575.25MHz 602 1.1 wiz * 35: 583.25MHz - 69: 855.25MHz 603 1.1 wiz * 604 1.1 wiz * Cable channels 605 1.1 wiz * 606 1.1 wiz * 70: 111.25MHz - 77: 167.25MHz 607 1.1 wiz * 78: 231.25MHz -107: 463.25MHz 608 1.1 wiz * 609 1.1 wiz * IF freq: 38.90 MHz 610 1.1 wiz */ 611 1.1 wiz #define IF_FREQ 38.90 612 1.8 jdolecek static const int xussr[] = { 613 1.10 wiz 107, (int)(IF_FREQ * FREQFACTOR), 0, 614 1.10 wiz 78, (int)(231.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 615 1.10 wiz 70, (int)(111.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 616 1.10 wiz 35, (int)(583.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 617 1.10 wiz 21, (int)(471.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 618 1.10 wiz 6, (int)(175.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 619 1.10 wiz 3, (int)( 77.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR), 620 1.10 wiz 1, (int)( 49.75 * FREQFACTOR), (int)(9.50 * FREQFACTOR), 621 1.10 wiz 0 622 1.1 wiz }; 623 1.1 wiz #undef IF_FREQ 624 1.1 wiz 625 1.1 wiz /* 626 1.1 wiz * Australian broadcast channels 627 1.1 wiz */ 628 1.1 wiz #define OFFSET 7.00 629 1.10 wiz #define IF_FREQ 38.90 630 1.8 jdolecek static const int australia[] = { 631 1.10 wiz 83, (int)(IF_FREQ * FREQFACTOR), 0, 632 1.10 wiz 28, (int)(527.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 633 1.10 wiz 10, (int)(209.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 634 1.10 wiz 6, (int)(175.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 635 1.10 wiz 4, (int)( 95.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 636 1.10 wiz 3, (int)( 86.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 637 1.10 wiz 1, (int)( 57.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), 638 1.10 wiz 0 639 1.1 wiz }; 640 1.1 wiz #undef OFFSET 641 1.1 wiz #undef IF_FREQ 642 1.1 wiz 643 1.10 wiz /* 644 1.1 wiz * France broadcast channels 645 1.1 wiz */ 646 1.1 wiz #define OFFSET 8.00 647 1.1 wiz #define IF_FREQ 38.90 648 1.8 jdolecek static const int france[] = { 649 1.10 wiz 69, (int)(IF_FREQ * FREQFACTOR), 0, 650 1.10 wiz 21, (int)(471.25 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), /* 21 -> 69 */ 651 1.10 wiz 5, (int)(176.00 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), /* 5 -> 10 */ 652 1.10 wiz 4, (int)( 63.75 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), /* 4 */ 653 1.10 wiz 3, (int)( 60.50 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), /* 3 */ 654 1.10 wiz 1, (int)( 47.75 * FREQFACTOR), (int)(OFFSET * FREQFACTOR), /* 1 2 */ 655 1.10 wiz 0 656 1.10 wiz }; 657 1.1 wiz #undef OFFSET 658 1.1 wiz #undef IF_FREQ 659 1.1 wiz 660 1.8 jdolecek static const struct { 661 1.8 jdolecek const int *ptr; 662 1.8 jdolecek const char name[BT848_MAX_CHNLSET_NAME_LEN]; 663 1.1 wiz } freqTable[] = { 664 1.1 wiz {NULL, ""}, 665 1.1 wiz {nabcst, "nabcst"}, 666 1.1 wiz {irccable, "cableirc"}, 667 1.1 wiz {hrccable, "cablehrc"}, 668 1.1 wiz {weurope, "weurope"}, 669 1.1 wiz {jpnbcst, "jpnbcst"}, 670 1.1 wiz {jpncable, "jpncable"}, 671 1.1 wiz {xussr, "xussr"}, 672 1.1 wiz {australia, "australia"}, 673 1.1 wiz {france, "france"}, 674 1.10 wiz 675 1.1 wiz }; 676 1.1 wiz 677 1.10 wiz #define TBL_CHNL freqTable[bktr->tuner.chnlset].ptr[x] 678 1.10 wiz #define TBL_BASE_FREQ freqTable[bktr->tuner.chnlset].ptr[x + 1] 679 1.10 wiz #define TBL_OFFSET freqTable[bktr->tuner.chnlset].ptr[x + 2] 680 1.1 wiz static int 681 1.10 wiz frequency_lookup(bktr_ptr_t bktr, int channel) 682 1.1 wiz { 683 1.1 wiz int x; 684 1.1 wiz 685 1.1 wiz /* check for "> MAX channel" */ 686 1.1 wiz x = 0; 687 1.10 wiz if (channel > TBL_CHNL) 688 1.10 wiz return(-1); 689 1.1 wiz 690 1.1 wiz /* search the table for data */ 691 1.10 wiz for (x = 3; TBL_CHNL; x += 3) { 692 1.10 wiz if (channel >= TBL_CHNL) { 693 1.10 wiz return(TBL_BASE_FREQ + 694 1.10 wiz ((channel - TBL_CHNL) * TBL_OFFSET)); 695 1.1 wiz } 696 1.1 wiz } 697 1.1 wiz 698 1.1 wiz /* not found, must be below the MIN channel */ 699 1.10 wiz return(-1); 700 1.1 wiz } 701 1.1 wiz #undef TBL_OFFSET 702 1.1 wiz #undef TBL_BASE_FREQ 703 1.1 wiz #undef TBL_CHNL 704 1.1 wiz 705 1.1 wiz 706 1.10 wiz #define TBL_IF freqTable[bktr->tuner.chnlset].ptr[1] 707 1.1 wiz 708 1.1 wiz 709 1.1 wiz /* Initialise the tuner structures in the bktr_softc */ 710 1.1 wiz /* This is needed as the tuner details are no longer globally declared */ 711 1.1 wiz 712 1.10 wiz void select_tuner(bktr_ptr_t bktr, int tuner_type) { 713 1.1 wiz if (tuner_type < Bt848_MAX_TUNER) { 714 1.10 wiz bktr->card.tuner = &tuners[tuner_type]; 715 1.1 wiz } else { 716 1.1 wiz bktr->card.tuner = NULL; 717 1.1 wiz } 718 1.1 wiz } 719 1.1 wiz 720 1.1 wiz /* 721 1.1 wiz * Tuner Notes: 722 1.1 wiz * Programming the tuner properly is quite complicated. 723 1.1 wiz * Here are some notes, based on a FM1246 data sheet for a PAL-I tuner. 724 1.10 wiz * The tuner (front end) covers 45.75 MHz - 855.25 MHz and an FM band of 725 1.10 wiz * 87.5 MHz to 108.0 MHz. 726 1.1 wiz * 727 1.1 wiz * RF and IF. RF = radio frequencies, it is the transmitted signal. 728 1.1 wiz * IF is the Intermediate Frequency (the offset from the base 729 1.1 wiz * signal where the video, color, audio and NICAM signals are. 730 1.1 wiz * 731 1.10 wiz * Eg, Picture at 38.9 MHz, Colour at 34.47 MHz, sound at 32.9 MHz 732 1.10 wiz * NICAM at 32.348 MHz. 733 1.1 wiz * Strangely enough, there is an IF (intermediate frequency) for 734 1.10 wiz * FM Radio which is 10.7 MHz. 735 1.1 wiz * 736 1.1 wiz * The tuner also works in Bands. Philips bands are 737 1.1 wiz * FM radio band 87.50 to 108.00 MHz 738 1.1 wiz * Low band 45.75 to 170.00 MHz 739 1.1 wiz * Mid band 170.00 to 450.00 MHz 740 1.1 wiz * High band 450.00 to 855.25 MHz 741 1.1 wiz * 742 1.1 wiz * 743 1.13 andvar * Now we need to set the PLL on the tuner to the required frequency. 744 1.1 wiz * It has a programmable divisor. 745 1.1 wiz * For TV we want 746 1.1 wiz * N = 16 (freq RF(pc) + freq IF(pc)) pc is picture carrier and RF and IF 747 1.1 wiz * are in MHz. 748 1.1 wiz 749 1.1 wiz * For RADIO we want a different equation. 750 1.1 wiz * freq IF is 10.70 MHz (so the data sheet tells me) 751 1.1 wiz * N = (freq RF + freq IF) / step size 752 1.10 wiz * The step size must be set to 50 kHz (so the data sheet tells me) 753 1.1 wiz * (note this is 50 kHz, the other things are in MHz) 754 1.1 wiz * so we end up with N = 20x(freq RF + 10.7) 755 1.1 wiz * 756 1.1 wiz */ 757 1.1 wiz 758 1.1 wiz #define LOW_BAND 0 759 1.1 wiz #define MID_BAND 1 760 1.1 wiz #define HIGH_BAND 2 761 1.1 wiz #define FM_RADIO_BAND 3 762 1.1 wiz 763 1.1 wiz 764 1.1 wiz /* Check if these are correct for other than Philips PAL */ 765 1.1 wiz #define STATUSBIT_COLD 0x80 766 1.1 wiz #define STATUSBIT_LOCK 0x40 767 1.1 wiz #define STATUSBIT_TV 0x20 768 1.1 wiz #define STATUSBIT_STEREO 0x10 /* valid if FM (aka not TV) */ 769 1.1 wiz #define STATUSBIT_ADC 0x07 770 1.1 wiz 771 1.1 wiz /* 772 1.1 wiz * set the frequency of the tuner 773 1.1 wiz * If 'type' is TV_FREQUENCY, the frequency is freq MHz*16 774 1.10 wiz * If 'type' is FM_RADIO_FREQUENCY, the frequency is freq MHz * 100 775 1.1 wiz * (note *16 gives is 4 bits of fraction, eg steps of nnn.0625) 776 1.1 wiz * 777 1.1 wiz */ 778 1.1 wiz int 779 1.10 wiz tv_freq(bktr_ptr_t bktr, int frequency, int type) 780 1.1 wiz { 781 1.1 wiz const struct TUNER* tuner; 782 1.1 wiz u_char addr; 783 1.1 wiz u_char control; 784 1.1 wiz u_char band; 785 1.1 wiz int N; 786 1.1 wiz int band_select = 0; 787 1.10 wiz #if defined(TEST_TUNER_AFC) 788 1.1 wiz int oldFrequency, afcDelta; 789 1.1 wiz #endif 790 1.1 wiz 791 1.1 wiz tuner = bktr->card.tuner; 792 1.10 wiz if (tuner == NULL) 793 1.10 wiz return(-1); 794 1.1 wiz 795 1.1 wiz if (type == TV_FREQUENCY) { 796 1.1 wiz /* 797 1.1 wiz * select the band based on frequency 798 1.1 wiz */ 799 1.11 wiz if (frequency < (tuner->bandLimits[0] * FREQFACTOR)) 800 1.1 wiz band_select = LOW_BAND; 801 1.11 wiz else if (frequency < (tuner->bandLimits[1] * FREQFACTOR)) 802 1.1 wiz band_select = MID_BAND; 803 1.1 wiz else 804 1.1 wiz band_select = HIGH_BAND; 805 1.1 wiz 806 1.10 wiz #if defined(TEST_TUNER_AFC) 807 1.10 wiz if (bktr->tuner.afc) 808 1.1 wiz frequency -= 4; 809 1.1 wiz #endif 810 1.1 wiz /* 811 1.1 wiz * N = 16 * { fRF(pc) + fIF(pc) } 812 1.1 wiz * or N = 16* fRF(pc) + 16*fIF(pc) } 813 1.1 wiz * where: 814 1.1 wiz * pc is picture carrier, fRF & fIF are in MHz 815 1.1 wiz * 816 1.13 andvar * fortunately, frequency is passed in as MHz * 16 817 1.1 wiz * and the TBL_IF frequency is also stored in MHz * 16 818 1.1 wiz */ 819 1.1 wiz N = frequency + TBL_IF; 820 1.1 wiz 821 1.1 wiz /* set the address of the PLL */ 822 1.1 wiz addr = bktr->card.tuner_pllAddr; 823 1.10 wiz control = tuner->pllControl[band_select]; 824 1.10 wiz band = tuner->bandAddrs[band_select]; 825 1.1 wiz 826 1.1 wiz if(!(band && control)) /* Don't try to set un- */ 827 1.1 wiz return(-1); /* supported modes. */ 828 1.1 wiz 829 1.10 wiz if (frequency > bktr->tuner.frequency) { 830 1.10 wiz i2cWrite(bktr, addr, (N>>8) & 0x7f, N & 0xff); 831 1.10 wiz i2cWrite(bktr, addr, control, band); 832 1.1 wiz } 833 1.1 wiz else { 834 1.10 wiz i2cWrite(bktr, addr, control, band); 835 1.10 wiz i2cWrite(bktr, addr, (N>>8) & 0x7f, N & 0xff); 836 1.1 wiz } 837 1.1 wiz 838 1.10 wiz #if defined(TUNER_AFC) 839 1.10 wiz if (bktr->tuner.afc == TRUE) { 840 1.10 wiz #if defined(TEST_TUNER_AFC) 841 1.1 wiz oldFrequency = frequency; 842 1.1 wiz #endif 843 1.10 wiz if ((N = do_afc(bktr, addr, N)) < 0) { 844 1.1 wiz /* AFC failed, restore requested frequency */ 845 1.1 wiz N = frequency + TBL_IF; 846 1.10 wiz #if defined(TEST_TUNER_AFC) 847 1.3 wiz printf("%s: do_afc: failed to lock\n", 848 1.3 wiz bktr_name(bktr)); 849 1.1 wiz #endif 850 1.10 wiz i2cWrite(bktr, addr, (N>>8) & 0x7f, N & 0xff); 851 1.1 wiz } 852 1.1 wiz else 853 1.1 wiz frequency = N - TBL_IF; 854 1.10 wiz #if defined(TEST_TUNER_AFC) 855 1.4 wiz printf("%s: do_afc: returned freq %d (%d %% %d)\n", bktr_name(bktr), frequency, frequency / 16, frequency % 16); 856 1.1 wiz afcDelta = frequency - oldFrequency; 857 1.3 wiz printf("%s: changed by: %d clicks (%d mod %d)\n", bktr_name(bktr), afcDelta, afcDelta / 16, afcDelta % 16); 858 1.1 wiz #endif 859 1.1 wiz } 860 1.1 wiz #endif /* TUNER_AFC */ 861 1.1 wiz 862 1.1 wiz bktr->tuner.frequency = frequency; 863 1.1 wiz } 864 1.1 wiz 865 1.10 wiz if (type == FM_RADIO_FREQUENCY) { 866 1.1 wiz band_select = FM_RADIO_BAND; 867 1.1 wiz 868 1.1 wiz /* 869 1.1 wiz * N = { fRF(pc) + fIF(pc) }/step_size 870 1.1 wiz * The step size is 50kHz for FM radio. 871 1.1 wiz * (eg after 102.35MHz comes 102.40 MHz) 872 1.1 wiz * fIF is 10.7 MHz (as detailed in the specs) 873 1.1 wiz * 874 1.1 wiz * frequency is passed in as MHz * 100 875 1.1 wiz * 876 1.1 wiz * So, we have N = (frequency/100 + 10.70) /(50/1000) 877 1.1 wiz */ 878 1.1 wiz N = (frequency + 1070)/5; 879 1.1 wiz 880 1.1 wiz /* set the address of the PLL */ 881 1.1 wiz addr = bktr->card.tuner_pllAddr; 882 1.10 wiz control = tuner->pllControl[band_select]; 883 1.10 wiz band = tuner->bandAddrs[band_select]; 884 1.1 wiz 885 1.1 wiz if(!(band && control)) /* Don't try to set un- */ 886 1.1 wiz return(-1); /* supported modes. */ 887 1.10 wiz 888 1.1 wiz band |= bktr->tuner.radio_mode; /* tuner.radio_mode is set in 889 1.1 wiz * the ioctls RADIO_SETMODE 890 1.1 wiz * and RADIO_GETMODE */ 891 1.1 wiz 892 1.10 wiz i2cWrite(bktr, addr, control, band); 893 1.10 wiz i2cWrite(bktr, addr, (N>>8) & 0x7f, N & 0xff); 894 1.1 wiz 895 1.1 wiz bktr->tuner.frequency = (N * 5) - 1070; 896 1.1 wiz 897 1.1 wiz 898 1.1 wiz } 899 1.1 wiz 900 1.10 wiz 901 1.10 wiz return(0); 902 1.1 wiz } 903 1.1 wiz 904 1.1 wiz 905 1.1 wiz 906 1.10 wiz #if defined(TUNER_AFC) 907 1.1 wiz /* 908 1.10 wiz * 909 1.1 wiz */ 910 1.1 wiz int 911 1.10 wiz do_afc(bktr_ptr_t bktr, int addr, int frequency) 912 1.1 wiz { 913 1.1 wiz int step; 914 1.1 wiz int status; 915 1.1 wiz int origFrequency; 916 1.1 wiz 917 1.1 wiz origFrequency = frequency; 918 1.1 wiz 919 1.1 wiz /* wait for first setting to take effect */ 920 1.10 wiz tsleep(BKTR_SLEEP, PZERO, "tuning", hz/8); 921 1.1 wiz 922 1.10 wiz if ((status = i2cRead(bktr, addr + 1)) < 0) 923 1.10 wiz return(-1); 924 1.1 wiz 925 1.10 wiz #if defined(TEST_TUNER_AFC) 926 1.10 wiz printf("%s: Original freq: %d, status: 0x%02x\n", bktr_name(bktr), frequency, status); 927 1.1 wiz #endif 928 1.10 wiz for (step = 0; step < AFC_MAX_STEP; ++step) { 929 1.10 wiz if ((status = i2cRead(bktr, addr + 1)) < 0) 930 1.1 wiz goto fubar; 931 1.10 wiz if (!(status & 0x40)) { 932 1.10 wiz #if defined(TEST_TUNER_AFC) 933 1.10 wiz printf("%s: no lock!\n", bktr_name(bktr)); 934 1.1 wiz #endif 935 1.1 wiz goto fubar; 936 1.1 wiz } 937 1.1 wiz 938 1.10 wiz switch(status & AFC_BITS) { 939 1.1 wiz case AFC_FREQ_CENTERED: 940 1.10 wiz #if defined(TEST_TUNER_AFC) 941 1.10 wiz printf("%s: Centered, freq: %d, status: 0x%02x\n", bktr_name(bktr), frequency, status); 942 1.1 wiz #endif 943 1.10 wiz return(frequency); 944 1.1 wiz 945 1.1 wiz case AFC_FREQ_MINUS_125: 946 1.1 wiz case AFC_FREQ_MINUS_62: 947 1.10 wiz #if defined(TEST_TUNER_AFC) 948 1.10 wiz printf("%s: Low, freq: %d, status: 0x%02x\n", bktr_name(bktr), frequency, status); 949 1.1 wiz #endif 950 1.1 wiz --frequency; 951 1.1 wiz break; 952 1.1 wiz 953 1.1 wiz case AFC_FREQ_PLUS_62: 954 1.1 wiz case AFC_FREQ_PLUS_125: 955 1.10 wiz #if defined(TEST_TUNER_AFC) 956 1.10 wiz printf("%s: Hi, freq: %d, status: 0x%02x\n", bktr_name(bktr), frequency, status); 957 1.1 wiz #endif 958 1.1 wiz ++frequency; 959 1.1 wiz break; 960 1.1 wiz } 961 1.1 wiz 962 1.10 wiz i2cWrite(bktr, addr, 963 1.10 wiz (frequency>>8) & 0x7f, frequency & 0xff); 964 1.10 wiz DELAY(AFC_DELAY); 965 1.1 wiz } 966 1.1 wiz 967 1.1 wiz fubar: 968 1.10 wiz i2cWrite(bktr, addr, 969 1.10 wiz (origFrequency>>8) & 0x7f, origFrequency & 0xff); 970 1.1 wiz 971 1.10 wiz return(-1); 972 1.1 wiz } 973 1.1 wiz #endif /* TUNER_AFC */ 974 1.1 wiz #undef TBL_IF 975 1.1 wiz 976 1.1 wiz 977 1.1 wiz /* 978 1.1 wiz * Get the Tuner status and signal strength 979 1.1 wiz */ 980 1.10 wiz int get_tuner_status(bktr_ptr_t bktr) { 981 1.10 wiz return i2cRead(bktr, bktr->card.tuner_pllAddr + 1); 982 1.1 wiz } 983 1.1 wiz 984 1.1 wiz /* 985 1.1 wiz * set the channel of the tuner 986 1.1 wiz */ 987 1.1 wiz int 988 1.10 wiz tv_channel(bktr_ptr_t bktr, int channel) 989 1.1 wiz { 990 1.1 wiz int frequency; 991 1.1 wiz 992 1.1 wiz /* calculate the frequency according to tuner type */ 993 1.10 wiz if ((frequency = frequency_lookup(bktr, channel)) < 0) 994 1.10 wiz return(-1); 995 1.1 wiz 996 1.1 wiz /* set the new frequency */ 997 1.10 wiz if (tv_freq(bktr, frequency, TV_FREQUENCY) < 0) 998 1.10 wiz return(-1); 999 1.1 wiz 1000 1.1 wiz /* OK to update records */ 1001 1.10 wiz return((bktr->tuner.channel = channel)); 1002 1.1 wiz } 1003 1.1 wiz 1004 1.1 wiz /* 1005 1.1 wiz * get channelset name 1006 1.1 wiz */ 1007 1.1 wiz int 1008 1.1 wiz tuner_getchnlset(struct bktr_chnlset *chnlset) 1009 1.1 wiz { 1010 1.10 wiz if ((chnlset->index < CHNLSET_MIN) || 1011 1.10 wiz (chnlset->index > CHNLSET_MAX)) 1012 1.10 wiz return(EINVAL); 1013 1.1 wiz 1014 1.1 wiz memcpy(&chnlset->name, &freqTable[chnlset->index].name, 1015 1.1 wiz BT848_MAX_CHNLSET_NAME_LEN); 1016 1.1 wiz 1017 1.1 wiz chnlset->max_channel=freqTable[chnlset->index].ptr[0]; 1018 1.10 wiz return(0); 1019 1.1 wiz } 1020