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