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