root/dev/pci/bktr/bktr_tuner.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. frequency_lookup
  2. select_tuner
  3. tv_freq
  4. do_afc
  5. get_tuner_status
  6. tv_channel
  7. tuner_getchnlset

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

/* [<][>][^][v][top][bottom][index][help] */