The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/video/bktr/bktr_tuner.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * 1. Redistributions of source code must retain the
    3  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Amancio Hasty and
   17  *      Roger Hardiman
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   24  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   31  * POSSIBILITY OF SUCH DAMAGE.
   32  *
   33  * $FreeBSD: src/sys/dev/bktr/bktr_tuner.c,v 1.20 2005/11/13 13:26:37 netchild Exp $
   34  */
   35 
   36 
   37 /*
   38  * This is part of the Driver for Video Capture Cards (Frame grabbers)
   39  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
   40  * chipset.
   41  * Copyright Roger Hardiman and Amancio Hasty.
   42  *
   43  * bktr_tuner : This deals with controlling the tuner fitted to TV cards.
   44  */
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/kernel.h>
   49 #include <sys/bus.h>
   50 #include <sys/event.h>
   51 
   52 #include <bus/pci/pcivar.h>
   53 
   54 #include <dev/video/meteor/ioctl_meteor.h>
   55 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
   56 #include <dev/video/bktr/bktr_reg.h>
   57 #include <dev/video/bktr/bktr_tuner.h>
   58 #include <dev/video/bktr/bktr_card.h>
   59 #include <dev/video/bktr/bktr_core.h>
   60 
   61 
   62 
   63 #if defined( TUNER_AFC )
   64 #define AFC_DELAY               10000   /* 10 millisend delay */
   65 #define AFC_BITS                0x07
   66 #define AFC_FREQ_MINUS_125      0x00
   67 #define AFC_FREQ_MINUS_62       0x01
   68 #define AFC_FREQ_CENTERED       0x02
   69 #define AFC_FREQ_PLUS_62        0x03
   70 #define AFC_FREQ_PLUS_125       0x04
   71 #define AFC_MAX_STEP            (5 * FREQFACTOR) /* no more than 5 MHz */
   72 #endif /* TUNER_AFC */
   73 
   74   
   75 #define TTYPE_XXX               0
   76 #define TTYPE_NTSC              1
   77 #define TTYPE_NTSC_J            2
   78 #define TTYPE_PAL               3
   79 #define TTYPE_PAL_M             4
   80 #define TTYPE_PAL_N             5
   81 #define TTYPE_SECAM             6
   82   
   83 #define TSA552x_CB_MSB          (0x80)
   84 #define TSA552x_CB_CP           (1<<6)  /* set this for fast tuning */
   85 #define TSA552x_CB_T2           (1<<5)  /* test mode - Normally set to 0 */
   86 #define TSA552x_CB_T1           (1<<4)  /* test mode - Normally set to 0 */
   87 #define TSA552x_CB_T0           (1<<3)  /* test mode - Normally set to 1 */
   88 #define TSA552x_CB_RSA          (1<<2)  /* 0 for 31.25 khz, 1 for 62.5 kHz */
   89 #define TSA552x_CB_RSB          (1<<1)  /* 0 for FM 50kHz steps, 1 = Use RSA*/
   90 #define TSA552x_CB_OS           (1<<0)  /* Set to 0 for normal operation */
   91 
   92 #define TSA552x_RADIO           (TSA552x_CB_MSB |       \
   93                                  TSA552x_CB_T0)
   94 
   95 /* raise the charge pump voltage for fast tuning */
   96 #define TSA552x_FCONTROL        (TSA552x_CB_MSB |       \
   97                                  TSA552x_CB_CP  |       \
   98                                  TSA552x_CB_T0  |       \
   99                                  TSA552x_CB_RSA |       \
  100                                  TSA552x_CB_RSB)
  101   
  102 /* lower the charge pump voltage for better residual oscillator FM */
  103 #define TSA552x_SCONTROL        (TSA552x_CB_MSB |       \
  104                                  TSA552x_CB_T0  |       \
  105                                  TSA552x_CB_RSA |       \
  106                                  TSA552x_CB_RSB)
  107   
  108 /* The control value for the ALPS TSCH5 Tuner */
  109 #define TSCH5_FCONTROL          0x82
  110 #define TSCH5_RADIO             0x86
  111   
  112 /* The control value for the ALPS TSBH1 Tuner */
  113 #define TSBH1_FCONTROL          0xce
  114 
  115 
  116 static void mt2032_set_tv_freq(bktr_ptr_t bktr, unsigned int freq);
  117 
  118 
  119 static const struct TUNER tuners[] = {
  120 /* XXX FIXME: fill in the band-switch crosspoints */
  121         /* NO_TUNER */
  122         { "<no>",                               /* the 'name' */
  123            TTYPE_XXX,                           /* input type */
  124            { 0x00,                              /* control byte for Tuner PLL */
  125              0x00,
  126              0x00,
  127              0x00 },
  128            { 0x00, 0x00 },                      /* band-switch crosspoints */
  129            { 0x00, 0x00, 0x00,0x00} },          /* the band-switch values */
  130 
  131         /* TEMIC_NTSC */
  132         { "Temic NTSC",                         /* the 'name' */
  133            TTYPE_NTSC,                          /* input type */
  134            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  135              TSA552x_SCONTROL,
  136              TSA552x_SCONTROL,
  137              0x00 },
  138            { 0x00, 0x00},                       /* band-switch crosspoints */
  139            { 0x02, 0x04, 0x01, 0x00 } },        /* the band-switch values */
  140 
  141         /* TEMIC_PAL */
  142         { "Temic PAL",                          /* the 'name' */
  143            TTYPE_PAL,                           /* input type */
  144            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  145              TSA552x_SCONTROL,
  146              TSA552x_SCONTROL,
  147              0x00 },
  148            { 0x00, 0x00 },                      /* band-switch crosspoints */
  149            { 0x02, 0x04, 0x01, 0x00 } },        /* the band-switch values */
  150 
  151         /* TEMIC_SECAM */
  152         { "Temic SECAM",                        /* the 'name' */
  153            TTYPE_SECAM,                         /* input type */
  154            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  155              TSA552x_SCONTROL,
  156              TSA552x_SCONTROL,
  157              0x00 },
  158            { 0x00, 0x00 },                      /* band-switch crosspoints */
  159            { 0x02, 0x04, 0x01,0x00 } },         /* the band-switch values */
  160 
  161         /* PHILIPS_NTSC */
  162         { "Philips NTSC",                       /* the 'name' */
  163            TTYPE_NTSC,                          /* input type */
  164            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  165              TSA552x_SCONTROL,
  166              TSA552x_SCONTROL,
  167              0x00 },
  168            { 0x00, 0x00 },                      /* band-switch crosspoints */
  169            { 0xa0, 0x90, 0x30, 0x00 } },        /* the band-switch values */
  170 
  171         /* PHILIPS_PAL */
  172         { "Philips PAL",                        /* the 'name' */
  173            TTYPE_PAL,                           /* input type */
  174            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  175              TSA552x_SCONTROL,
  176              TSA552x_SCONTROL,
  177              0x00 },
  178            { 0x00, 0x00 },                      /* band-switch crosspoints */
  179            { 0xa0, 0x90, 0x30, 0x00 } },        /* the band-switch values */
  180 
  181         /* PHILIPS_SECAM */
  182         { "Philips SECAM",                      /* the 'name' */
  183            TTYPE_SECAM,                         /* input type */
  184            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  185              TSA552x_SCONTROL,
  186              TSA552x_SCONTROL,
  187              0x00 },
  188            { 0x00, 0x00 },                      /* band-switch crosspoints */
  189            { 0xa7, 0x97, 0x37, 0x00 } },        /* the band-switch values */
  190 
  191         /* TEMIC_PAL I */
  192         { "Temic PAL I",                        /* the 'name' */
  193            TTYPE_PAL,                           /* input type */
  194            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  195              TSA552x_SCONTROL,
  196              TSA552x_SCONTROL,
  197              0x00 },
  198            { 0x00, 0x00 },                      /* band-switch crosspoints */
  199            { 0x02, 0x04, 0x01,0x00 } },         /* the band-switch values */
  200 
  201         /* PHILIPS_PALI */
  202         { "Philips PAL I",                      /* the 'name' */
  203            TTYPE_PAL,                           /* input type */
  204            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  205              TSA552x_SCONTROL,
  206              TSA552x_SCONTROL,
  207              0x00 },
  208           { 0x00, 0x00 },                      /* band-switch crosspoints */
  209           { 0xa0, 0x90, 0x30,0x00 } },         /* the band-switch values */
  210 
  211        /* PHILIPS_FR1236_NTSC */
  212        { "Philips FR1236 NTSC FM",             /* the 'name' */
  213           TTYPE_NTSC,                          /* input type */
  214           { TSA552x_FCONTROL,                   /* control byte for Tuner PLL */
  215             TSA552x_FCONTROL,
  216             TSA552x_FCONTROL,
  217             TSA552x_RADIO  },
  218           { 0x00, 0x00 },                       /* band-switch crosspoints */
  219           { 0xa0, 0x90, 0x30,0xa4 } },          /* the band-switch values */
  220 
  221         /* PHILIPS_FR1216_PAL */
  222         { "Philips FR1216 PAL FM" ,             /* the 'name' */
  223            TTYPE_PAL,                           /* input type */
  224            { TSA552x_FCONTROL,                  /* control byte for Tuner PLL */
  225              TSA552x_FCONTROL,
  226              TSA552x_FCONTROL,
  227              TSA552x_RADIO },
  228            { 0x00, 0x00 },                      /* band-switch crosspoints */
  229            { 0xa0, 0x90, 0x30, 0xa4 } },        /* the band-switch values */
  230 
  231         /* PHILIPS_FR1236_SECAM */
  232         { "Philips FR1236 SECAM FM",            /* the 'name' */
  233            TTYPE_SECAM,                         /* input type */
  234            { TSA552x_FCONTROL,                  /* control byte for Tuner PLL */
  235              TSA552x_FCONTROL,
  236              TSA552x_FCONTROL,
  237              TSA552x_RADIO },
  238            { 0x00, 0x00 },                      /* band-switch crosspoints */
  239            { 0xa7, 0x97, 0x37, 0xa4 } },        /* the band-switch values */
  240 
  241         /* ALPS TSCH5 NTSC */
  242         { "ALPS TSCH5 NTSC FM",                 /* the 'name' */
  243            TTYPE_NTSC,                          /* input type */
  244            { TSCH5_FCONTROL,                    /* control byte for Tuner PLL */
  245              TSCH5_FCONTROL,
  246              TSCH5_FCONTROL,
  247              TSCH5_RADIO },
  248            { 0x00, 0x00 },                      /* band-switch crosspoints */
  249            { 0x14, 0x12, 0x11, 0x04 } },        /* the band-switch values */
  250 
  251         /* ALPS TSBH1 NTSC */
  252         { "ALPS TSBH1 NTSC",                    /* the 'name' */
  253            TTYPE_NTSC,                          /* input type */
  254            { TSBH1_FCONTROL,                    /* control byte for Tuner PLL */
  255              TSBH1_FCONTROL,
  256              TSBH1_FCONTROL,
  257              0x00 },
  258            { 0x00, 0x00 },                      /* band-switch crosspoints */
  259            { 0x01, 0x02, 0x08, 0x00 } },        /* the band-switch values */
  260 
  261         /* MT2032 Microtune */
  262         { "MT2032",                             /* the 'name' */
  263            TTYPE_PAL,                           /* input type */
  264            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  265              TSA552x_SCONTROL,
  266              TSA552x_SCONTROL,
  267              0x00 },
  268            { 0x00, 0x00 },                      /* band-switch crosspoints */
  269            { 0xa0, 0x90, 0x30, 0x00 } },        /* the band-switch values */
  270 
  271          /* LG TPI8PSB12P PAL */
  272          { "LG TPI8PSB12P PAL",                 /* the 'name' */
  273            TTYPE_PAL,                           /* input type */
  274            { TSA552x_SCONTROL,                  /* control byte for Tuner PLL */
  275              TSA552x_SCONTROL,
  276              TSA552x_SCONTROL,
  277              0x00 },
  278            { 0x00, 0x00 },                      /* band-switch crosspoints */
  279            { 0xa0, 0x90, 0x30, 0x8e } },        /* the band-switch values */
  280 };
  281 
  282 
  283 /* scaling factor for frequencies expressed as ints */
  284 #define FREQFACTOR              16
  285 
  286 /*
  287  * Format:
  288  *      entry 0:         MAX legal channel
  289  *      entry 1:         IF frequency
  290  *                       expressed as fi{mHz} * 16,
  291  *                       eg 45.75mHz == 45.75 * 16 = 732
  292  *      entry 2:         [place holder/future]
  293  *      entry 3:         base of channel record 0
  294  *      entry 3 + (x*3): base of channel record 'x'
  295  *      entry LAST:      NULL channel entry marking end of records
  296  *
  297  * Record:
  298  *      int 0:          base channel
  299  *      int 1:          frequency of base channel,
  300  *                       expressed as fb{mHz} * 16,
  301  *      int 2:          offset frequency between channels,
  302  *                       expressed as fo{mHz} * 16,
  303  */
  304 
  305 /*
  306  * North American Broadcast Channels:
  307  *
  308  *  2:  55.25 mHz -  4:  67.25 mHz
  309  *  5:  77.25 mHz -  6:  83.25 mHz
  310  *  7: 175.25 mHz - 13: 211.25 mHz
  311  * 14: 471.25 mHz - 83: 885.25 mHz
  312  *
  313  * IF freq: 45.75 mHz
  314  */
  315 #define OFFSET  6.00
  316 static int nabcst[] = {
  317         83,     (int)( 45.75 * FREQFACTOR),     0,
  318         14,     (int)(471.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  319          7,     (int)(175.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  320          5,     (int)( 77.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  321          2,     (int)( 55.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  322          0
  323 };
  324 #undef OFFSET
  325 
  326 /*
  327  * North American Cable Channels, IRC:
  328  *
  329  *  2:  55.25 mHz -  4:  67.25 mHz
  330  *  5:  77.25 mHz -  6:  83.25 mHz
  331  *  7: 175.25 mHz - 13: 211.25 mHz
  332  * 14: 121.25 mHz - 22: 169.25 mHz
  333  * 23: 217.25 mHz - 94: 643.25 mHz
  334  * 95:  91.25 mHz - 99: 115.25 mHz
  335  *
  336  * IF freq: 45.75 mHz
  337  */
  338 #define OFFSET  6.00
  339 static int irccable[] = {
  340         116,    (int)( 45.75 * FREQFACTOR),     0,
  341         100,    (int)(649.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  342         95,     (int)( 91.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  343         23,     (int)(217.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  344         14,     (int)(121.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  345          7,     (int)(175.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  346          5,     (int)( 77.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  347          2,     (int)( 55.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  348          0
  349 };
  350 #undef OFFSET
  351 
  352 /*
  353  * North American Cable Channels, HRC:
  354  *
  355  * 2:   54 mHz  - 4:    66 mHz
  356  * 5:   78 mHz  - 6:    84 mHz
  357  * 7:  174 mHz  - 13:  210 mHz
  358  * 14: 120 mHz  - 22:  168 mHz
  359  * 23: 216 mHz  - 94:  642 mHz
  360  * 95:  90 mHz  - 99:  114 mHz
  361  *
  362  * IF freq: 45.75 mHz
  363  */
  364 #define OFFSET  6.00
  365 static int hrccable[] = {
  366         116,    (int)( 45.75 * FREQFACTOR),     0,
  367         100,    (int)(648.00 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  368         95,     (int)( 90.00 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  369         23,     (int)(216.00 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  370         14,     (int)(120.00 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  371         7,      (int)(174.00 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  372         5,      (int)( 78.00 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  373         2,      (int)( 54.00 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  374         0
  375 };
  376 #undef OFFSET
  377 
  378 /*
  379  * Western European broadcast channels:
  380  *
  381  * (there are others that appear to vary between countries - rmt)
  382  *
  383  * here's the table Philips provides:
  384  * caution, some of the offsets don't compute...
  385  *
  386  *  1    4525   700     N21
  387  * 
  388  *  2    4825   700     E2
  389  *  3    5525   700     E3
  390  *  4    6225   700     E4
  391  * 
  392  *  5   17525   700     E5
  393  *  6   18225   700     E6
  394  *  7   18925   700     E7
  395  *  8   19625   700     E8
  396  *  9   20325   700     E9
  397  * 10   21025   700     E10
  398  * 11   21725   700     E11
  399  * 12   22425   700     E12
  400  * 
  401  * 13    5375   700     ITA
  402  * 14    6225   700     ITB
  403  * 
  404  * 15    8225   700     ITC
  405  * 
  406  * 16   17525   700     ITD
  407  * 17   18325   700     ITE
  408  * 
  409  * 18   19225   700     ITF
  410  * 19   20125   700     ITG
  411  * 20   21025   700     ITH
  412  * 
  413  * 21   47125   800     E21
  414  * 22   47925   800     E22
  415  * 23   48725   800     E23
  416  * 24   49525   800     E24
  417  * 25   50325   800     E25
  418  * 26   51125   800     E26
  419  * 27   51925   800     E27
  420  * 28   52725   800     E28
  421  * 29   53525   800     E29
  422  * 30   54325   800     E30
  423  * 31   55125   800     E31
  424  * 32   55925   800     E32
  425  * 33   56725   800     E33
  426  * 34   57525   800     E34
  427  * 35   58325   800     E35
  428  * 36   59125   800     E36
  429  * 37   59925   800     E37
  430  * 38   60725   800     E38
  431  * 39   61525   800     E39
  432  * 40   62325   800     E40
  433  * 41   63125   800     E41
  434  * 42   63925   800     E42
  435  * 43   64725   800     E43
  436  * 44   65525   800     E44
  437  * 45   66325   800     E45
  438  * 46   67125   800     E46
  439  * 47   67925   800     E47
  440  * 48   68725   800     E48
  441  * 49   69525   800     E49
  442  * 50   70325   800     E50
  443  * 51   71125   800     E51
  444  * 52   71925   800     E52
  445  * 53   72725   800     E53
  446  * 54   73525   800     E54
  447  * 55   74325   800     E55
  448  * 56   75125   800     E56
  449  * 57   75925   800     E57
  450  * 58   76725   800     E58
  451  * 59   77525   800     E59
  452  * 60   78325   800     E60
  453  * 61   79125   800     E61
  454  * 62   79925   800     E62
  455  * 63   80725   800     E63
  456  * 64   81525   800     E64
  457  * 65   82325   800     E65
  458  * 66   83125   800     E66
  459  * 67   83925   800     E67
  460  * 68   84725   800     E68
  461  * 69   85525   800     E69
  462  * 
  463  * 70    4575   800     IA
  464  * 71    5375   800     IB
  465  * 72    6175   800     IC
  466  * 
  467  * 74    6925   700     S01
  468  * 75    7625   700     S02
  469  * 76    8325   700     S03
  470  * 
  471  * 80   10525   700     S1
  472  * 81   11225   700     S2
  473  * 82   11925   700     S3
  474  * 83   12625   700     S4
  475  * 84   13325   700     S5
  476  * 85   14025   700     S6
  477  * 86   14725   700     S7
  478  * 87   15425   700     S8
  479  * 88   16125   700     S9
  480  * 89   16825   700     S10
  481  * 90   23125   700     S11
  482  * 91   23825   700     S12
  483  * 92   24525   700     S13
  484  * 93   25225   700     S14
  485  * 94   25925   700     S15
  486  * 95   26625   700     S16
  487  * 96   27325   700     S17
  488  * 97   28025   700     S18
  489  * 98   28725   700     S19
  490  * 99   29425   700     S20
  491  *
  492  *
  493  * Channels S21 - S41 are taken from
  494  * http://gemma.apple.com:80/dev/technotes/tn/tn1012.html
  495  *
  496  * 100  30325   800     S21
  497  * 101  31125   800     S22
  498  * 102  31925   800     S23
  499  * 103  32725   800     S24
  500  * 104  33525   800     S25
  501  * 105  34325   800     S26         
  502  * 106  35125   800     S27         
  503  * 107  35925   800     S28         
  504  * 108  36725   800     S29         
  505  * 109  37525   800     S30         
  506  * 110  38325   800     S31         
  507  * 111  39125   800     S32         
  508  * 112  39925   800     S33         
  509  * 113  40725   800     S34         
  510  * 114  41525   800     S35         
  511  * 115  42325   800     S36         
  512  * 116  43125   800     S37         
  513  * 117  43925   800     S38         
  514  * 118  44725   800     S39         
  515  * 119  45525   800     S40         
  516  * 120  46325   800     S41
  517  * 
  518  * 121   3890   000     IFFREQ
  519  * 
  520  */
  521 static int weurope[] = {
  522        121,     (int)( 38.90 * FREQFACTOR),     0, 
  523        100,     (int)(303.25 * FREQFACTOR),     (int)(8.00 * FREQFACTOR), 
  524         90,     (int)(231.25 * FREQFACTOR),     (int)(7.00 * FREQFACTOR),
  525         80,     (int)(105.25 * FREQFACTOR),     (int)(7.00 * FREQFACTOR),  
  526         74,     (int)( 69.25 * FREQFACTOR),     (int)(7.00 * FREQFACTOR),  
  527         21,     (int)(471.25 * FREQFACTOR),     (int)(8.00 * FREQFACTOR),
  528         17,     (int)(183.25 * FREQFACTOR),     (int)(9.00 * FREQFACTOR),
  529         16,     (int)(175.25 * FREQFACTOR),     (int)(9.00 * FREQFACTOR),
  530         15,     (int)(82.25 * FREQFACTOR),      (int)(8.50 * FREQFACTOR),
  531         13,     (int)(53.75 * FREQFACTOR),      (int)(8.50 * FREQFACTOR),
  532          5,     (int)(175.25 * FREQFACTOR),     (int)(7.00 * FREQFACTOR),
  533          2,     (int)(48.25 * FREQFACTOR),      (int)(7.00 * FREQFACTOR),
  534          0
  535 };
  536 
  537 /*
  538  * Japanese Broadcast Channels:
  539  *
  540  *  1:  91.25MHz -  3: 103.25MHz
  541  *  4: 171.25MHz -  7: 189.25MHz
  542  *  8: 193.25MHz - 12: 217.25MHz  (VHF)
  543  * 13: 471.25MHz - 62: 765.25MHz  (UHF)
  544  *
  545  * IF freq: 45.75 mHz
  546  *  OR
  547  * IF freq: 58.75 mHz
  548  */
  549 #define OFFSET  6.00
  550 #define IF_FREQ 45.75
  551 static int jpnbcst[] = {
  552         62,     (int)(IF_FREQ * FREQFACTOR),    0,
  553         13,     (int)(471.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  554          8,     (int)(193.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  555          4,     (int)(171.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  556          1,     (int)( 91.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  557          0
  558 };
  559 #undef IF_FREQ
  560 #undef OFFSET
  561 
  562 /*
  563  * Japanese Cable Channels:
  564  *
  565  *  1:  91.25MHz -  3: 103.25MHz
  566  *  4: 171.25MHz -  7: 189.25MHz
  567  *  8: 193.25MHz - 12: 217.25MHz
  568  * 13: 109.25MHz - 21: 157.25MHz
  569  * 22: 165.25MHz
  570  * 23: 223.25MHz - 63: 463.25MHz
  571  *
  572  * IF freq: 45.75 mHz
  573  */
  574 #define OFFSET  6.00
  575 #define IF_FREQ 45.75
  576 static int jpncable[] = {
  577         63,     (int)(IF_FREQ * FREQFACTOR),    0,
  578         23,     (int)(223.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  579         22,     (int)(165.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  580         13,     (int)(109.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  581          8,     (int)(193.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  582          4,     (int)(171.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  583          1,     (int)( 91.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  584          0
  585 };
  586 #undef IF_FREQ
  587 #undef OFFSET
  588 
  589 /*
  590  * xUSSR Broadcast Channels:
  591  *
  592  *  1:  49.75MHz -  2:  59.25MHz
  593  *  3:  77.25MHz -  5:  93.25MHz
  594  *  6: 175.25MHz - 12: 223.25MHz
  595  * 13-20 - not exist
  596  * 21: 471.25MHz - 34: 575.25MHz
  597  * 35: 583.25MHz - 69: 855.25MHz
  598  *
  599  * Cable channels
  600  *
  601  * 70: 111.25MHz - 77: 167.25MHz
  602  * 78: 231.25MHz -107: 463.25MHz
  603  *
  604  * IF freq: 38.90 MHz
  605  */
  606 #define IF_FREQ 38.90
  607 static int xussr[] = {
  608       107,     (int)(IF_FREQ * FREQFACTOR),    0,
  609        78,     (int)(231.25 * FREQFACTOR),     (int)(8.00 * FREQFACTOR), 
  610        70,     (int)(111.25 * FREQFACTOR),     (int)(8.00 * FREQFACTOR),
  611        35,     (int)(583.25 * FREQFACTOR),     (int)(8.00 * FREQFACTOR), 
  612        21,     (int)(471.25 * FREQFACTOR),     (int)(8.00 * FREQFACTOR),
  613         6,     (int)(175.25 * FREQFACTOR),     (int)(8.00 * FREQFACTOR),  
  614         3,     (int)( 77.25 * FREQFACTOR),     (int)(8.00 * FREQFACTOR),  
  615         1,     (int)( 49.75 * FREQFACTOR),     (int)(9.50 * FREQFACTOR),
  616         0
  617 };
  618 #undef IF_FREQ
  619 
  620 /*
  621  * Australian broadcast channels
  622  */
  623 #define OFFSET  7.00
  624 #define IF_FREQ 38.90 
  625 static int australia[] = {
  626        83,     (int)(IF_FREQ * FREQFACTOR),    0,
  627        28,     (int)(527.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  628        10,     (int)(209.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  629         6,     (int)(175.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  630         4,     (int)( 95.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  631         3,     (int)( 86.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  632         1,     (int)( 57.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR),
  633         0
  634 };
  635 #undef OFFSET
  636 #undef IF_FREQ
  637 
  638 /* 
  639  * France broadcast channels
  640  */
  641 #define OFFSET 8.00
  642 #define IF_FREQ 38.90
  643 static int france[] = {
  644         69,     (int)(IF_FREQ * FREQFACTOR),     0,
  645         21,     (int)(471.25 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR), /* 21 -> 69 */
  646          5,     (int)(176.00 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR), /* 5 -> 10 */
  647          4,     (int)( 63.75 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR), /* 4    */
  648          3,     (int)( 60.50 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR), /* 3    */
  649          1,     (int)( 47.75 * FREQFACTOR),     (int)(OFFSET * FREQFACTOR), /* 1  2 */
  650          0
  651 }; 
  652 #undef OFFSET
  653 #undef IF_FREQ
  654 
  655 static struct {
  656         int     *ptr;
  657         char    name[BT848_MAX_CHNLSET_NAME_LEN];
  658 } freqTable[] = {
  659         {NULL,          ""},
  660         {nabcst,        "nabcst"},
  661         {irccable,      "cableirc"},
  662         {hrccable,      "cablehrc"},
  663         {weurope,       "weurope"},
  664         {jpnbcst,       "jpnbcst"},
  665         {jpncable,      "jpncable"},
  666         {xussr,         "xussr"},
  667         {australia,     "australia"},
  668         {france,        "france"},
  669  
  670 };
  671 
  672 #define TBL_CHNL        freqTable[ bktr->tuner.chnlset ].ptr[ x ]
  673 #define TBL_BASE_FREQ   freqTable[ bktr->tuner.chnlset ].ptr[ x + 1 ]
  674 #define TBL_OFFSET      freqTable[ bktr->tuner.chnlset ].ptr[ x + 2 ]
  675 static int
  676 frequency_lookup( bktr_ptr_t bktr, int channel )
  677 {
  678         int     x;
  679 
  680         /* check for "> MAX channel" */
  681         x = 0;
  682         if ( channel > TBL_CHNL )
  683                 return( -1 );
  684 
  685         /* search the table for data */
  686         for ( x = 3; TBL_CHNL; x += 3 ) {
  687                 if ( channel >= TBL_CHNL ) {
  688                         return( TBL_BASE_FREQ +
  689                                  ((channel - TBL_CHNL) * TBL_OFFSET) );
  690                 }
  691         }
  692 
  693         /* not found, must be below the MIN channel */
  694         return( -1 );
  695 }
  696 #undef TBL_OFFSET
  697 #undef TBL_BASE_FREQ
  698 #undef TBL_CHNL
  699 
  700 
  701 #define TBL_IF  (bktr->format_params == BT848_IFORM_F_NTSCJ || \
  702                  bktr->format_params == BT848_IFORM_F_NTSCM ? \
  703                  nabcst[1] : weurope[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 (tuner == &tuners[TUNER_MT2032]) {
  793                 mt2032_set_tv_freq(bktr, frequency);
  794                 return 0;
  795         }
  796         if (type == TV_FREQUENCY) {
  797                 /*
  798                  * select the band based on frequency
  799                  * XXX FIXME: get the cross-over points from the tuner struct
  800                  */
  801                 if ( frequency < (160 * FREQFACTOR  ) )
  802                     band_select = LOW_BAND;
  803                 else if ( frequency < (454 * FREQFACTOR ) )
  804                     band_select = MID_BAND;
  805                 else
  806                     band_select = HIGH_BAND;
  807 
  808 #if defined( TEST_TUNER_AFC )
  809                 if ( bktr->tuner.afc )
  810                         frequency -= 4;
  811 #endif
  812                 /*
  813                  * N = 16 * { fRF(pc) + fIF(pc) }
  814                  * or N = 16* fRF(pc) + 16*fIF(pc) }
  815                  * where:
  816                  *  pc is picture carrier, fRF & fIF are in MHz
  817                  *
  818                  * fortunatly, frequency is passed in as MHz * 16
  819                  * and the TBL_IF frequency is also stored in MHz * 16
  820                  */
  821                 N = frequency + TBL_IF;
  822 
  823                 /* set the address of the PLL */
  824                 addr    = bktr->card.tuner_pllAddr;
  825                 control = tuner->pllControl[ band_select ];
  826                 band    = tuner->bandAddrs[ band_select ];
  827 
  828                 if(!(band && control))          /* Don't try to set un- */
  829                   return(-1);                   /* supported modes.     */
  830 
  831                 if ( frequency > bktr->tuner.frequency ) {
  832                         i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff );
  833                         i2cWrite( bktr, addr, control, band );
  834                 }
  835                 else {
  836                         i2cWrite( bktr, addr, control, band );
  837                         i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff );
  838                 }
  839 
  840 #if defined( TUNER_AFC )
  841                 if ( bktr->tuner.afc == TRUE ) {
  842 #if defined( TEST_TUNER_AFC )
  843                         oldFrequency = frequency;
  844 #endif
  845                         if ( (N = do_afc( bktr, addr, N )) < 0 ) {
  846                             /* AFC failed, restore requested frequency */
  847                             N = frequency + TBL_IF;
  848 #if defined( TEST_TUNER_AFC )
  849                             kprintf("%s: do_afc: failed to lock\n",
  850                                    bktr_name(bktr));
  851 #endif
  852                             i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff );
  853                         }
  854                         else
  855                             frequency = N - TBL_IF;
  856 #if defined( TEST_TUNER_AFC )
  857  kprintf("%s: do_afc: returned freq %d (%d %% %d)\n", bktr_name(bktr), frequency, frequency / 16, frequency % 16);
  858                             afcDelta = frequency - oldFrequency;
  859  kprintf("%s: changed by: %d clicks (%d mod %d)\n", bktr_name(bktr), afcDelta, afcDelta / 16, afcDelta % 16);
  860 #endif
  861                         }
  862 #endif /* TUNER_AFC */
  863 
  864                 bktr->tuner.frequency = frequency;
  865         }
  866 
  867         if ( type == FM_RADIO_FREQUENCY ) {
  868                 band_select = FM_RADIO_BAND;
  869 
  870                 /*
  871                  * N = { fRF(pc) + fIF(pc) }/step_size
  872                  * The step size is 50kHz for FM radio.
  873                  * (eg after 102.35MHz comes 102.40 MHz)
  874                  * fIF is 10.7 MHz (as detailed in the specs)
  875                  *
  876                  * frequency is passed in as MHz * 100
  877                  *
  878                  * So, we have N = (frequency/100 + 10.70)  /(50/1000)
  879                  */
  880                 N = (frequency + 1070)/5;
  881 
  882                 /* set the address of the PLL */
  883                 addr    = bktr->card.tuner_pllAddr;
  884                 control = tuner->pllControl[ band_select ];
  885                 band    = tuner->bandAddrs[ band_select ];
  886 
  887                 if(!(band && control))          /* Don't try to set un- */
  888                   return(-1);                   /* supported modes.     */
  889           
  890                 band |= bktr->tuner.radio_mode; /* tuner.radio_mode is set in
  891                                                  * the ioctls RADIO_SETMODE
  892                                                  * and RADIO_GETMODE */
  893 
  894                 i2cWrite( bktr, addr, control, band );
  895                 i2cWrite( bktr, addr, (N>>8) & 0x7f, N & 0xff );
  896 
  897                 bktr->tuner.frequency = (N * 5) - 1070;
  898 
  899 
  900         }
  901  
  902 
  903         return( 0 );
  904 }
  905 
  906 
  907 
  908 #if defined( TUNER_AFC )
  909 /*
  910  * 
  911  */
  912 int
  913 do_afc( bktr_ptr_t bktr, int addr, int frequency )
  914 {
  915         int step;
  916         int status;
  917         int origFrequency;
  918 
  919         origFrequency = frequency;
  920 
  921         /* wait for first setting to take effect */
  922         tsleep( BKTR_SLEEP, 0, "tuning", hz/8 );
  923 
  924         if ( (status = i2cRead( bktr, addr + 1 )) < 0 )
  925                 return( -1 );
  926 
  927 #if defined( TEST_TUNER_AFC )
  928  kprintf( "%s: Original freq: %d, status: 0x%02x\n", bktr_name(bktr), frequency, status );
  929 #endif
  930         for ( step = 0; step < AFC_MAX_STEP; ++step ) {
  931                 if ( (status = i2cRead( bktr, addr + 1 )) < 0 )
  932                         goto fubar;
  933                 if ( !(status & 0x40) ) {
  934 #if defined( TEST_TUNER_AFC )
  935  kprintf( "%s: no lock!\n", bktr_name(bktr) );
  936 #endif
  937                         goto fubar;
  938                 }
  939 
  940                 switch( status & AFC_BITS ) {
  941                 case AFC_FREQ_CENTERED:
  942 #if defined( TEST_TUNER_AFC )
  943  kprintf( "%s: Centered, freq: %d, status: 0x%02x\n", bktr_name(bktr), frequency, status );
  944 #endif
  945                         return( frequency );
  946 
  947                 case AFC_FREQ_MINUS_125:
  948                 case AFC_FREQ_MINUS_62:
  949 #if defined( TEST_TUNER_AFC )
  950  kprintf( "%s: Low, freq: %d, status: 0x%02x\n", bktr_name(bktr), frequency, status );
  951 #endif
  952                         --frequency;
  953                         break;
  954 
  955                 case AFC_FREQ_PLUS_62:
  956                 case AFC_FREQ_PLUS_125:
  957 #if defined( TEST_TUNER_AFC )
  958  kprintf( "%s: Hi, freq: %d, status: 0x%02x\n", bktr_name(bktr), frequency, status );
  959 #endif
  960                         ++frequency;
  961                         break;
  962                 }
  963 
  964                 i2cWrite( bktr, addr,
  965                           (frequency>>8) & 0x7f, frequency & 0xff );
  966                 DELAY( AFC_DELAY );
  967         }
  968 
  969  fubar:
  970         i2cWrite( bktr, addr,
  971                   (origFrequency>>8) & 0x7f, origFrequency & 0xff );
  972 
  973         return( -1 );
  974 }
  975 #endif /* TUNER_AFC */
  976 #undef TBL_IF
  977 
  978 
  979 /*
  980  * Get the Tuner status and signal strength
  981  */
  982 int     get_tuner_status( bktr_ptr_t bktr ) {
  983         if (bktr->card.tuner == &tuners[TUNER_MT2032])
  984                 return 0;
  985         return i2cRead( bktr, bktr->card.tuner_pllAddr + 1 );
  986 }
  987 
  988 /*
  989  * set the channel of the tuner
  990  */
  991 int
  992 tv_channel( bktr_ptr_t bktr, int channel )
  993 {
  994         int frequency;
  995 
  996         /* calculate the frequency according to tuner type */
  997         if ( (frequency = frequency_lookup( bktr, channel )) < 0 )
  998                 return( -1 );
  999 
 1000         /* set the new frequency */
 1001         if ( tv_freq( bktr, frequency, TV_FREQUENCY ) < 0 )
 1002                 return( -1 );
 1003 
 1004         /* OK to update records */
 1005         return( (bktr->tuner.channel = channel) );
 1006 }
 1007 
 1008 /*
 1009  * get channelset name
 1010  */
 1011 int
 1012 tuner_getchnlset(struct bktr_chnlset *chnlset)
 1013 {
 1014        if (( chnlset->index < CHNLSET_MIN ) ||
 1015                ( chnlset->index > CHNLSET_MAX ))
 1016                        return( EINVAL );
 1017 
 1018        memcpy(&chnlset->name, &freqTable[chnlset->index].name,
 1019                BT848_MAX_CHNLSET_NAME_LEN);
 1020 
 1021        chnlset->max_channel=freqTable[chnlset->index].ptr[0];
 1022        return( 0 );
 1023 }
 1024 
 1025 
 1026 
 1027 
 1028 #define TDA9887_ADDR    0x86
 1029 
 1030 static int
 1031 TDA9887_init(bktr_ptr_t bktr, int output2_enable)
 1032 {
 1033         u_char addr = TDA9887_ADDR;
 1034 
 1035         i2cWrite(bktr, addr, 0, output2_enable ? 0x50 : 0xd0);
 1036         i2cWrite(bktr, addr, 1, 0x6e); /* takeover point / de-emphasis */
 1037 
 1038         /* PAL BG: 0x09  PAL I: 0x0a  NTSC: 0x04 */
 1039 #ifdef MT2032_NTSC
 1040         i2cWrite(bktr, addr, 2, 0x04);
 1041 #else
 1042         i2cWrite(bktr, addr, 2, 0x09);
 1043 #endif
 1044         return 0;
 1045 }
 1046 
 1047 
 1048 
 1049 #define MT2032_OPTIMIZE_VCO      1
 1050 
 1051 /* holds the value of XOGC register after init */
 1052 static int      MT2032_XOGC = 4;
 1053 
 1054 /* card.tuner_pllAddr not set during init */
 1055 #define MT2032_ADDR             0xc0
 1056 
 1057 #ifndef MT2032_ADDR
 1058 #define MT2032_ADDR             (bktr->card.tuner_pllAddr)
 1059 #endif
 1060 
 1061 static int 
 1062 _MT2032_GetRegister(bktr_ptr_t bktr, u_char regNum)
 1063 {
 1064         int             ch;
 1065 
 1066         if (i2cWrite(bktr, MT2032_ADDR, regNum, -1) == -1) {
 1067                 if (bootverbose)
 1068                         kprintf("%s: MT2032 write failed (i2c addr %#x)\n",
 1069                                 bktr_name(bktr), MT2032_ADDR);
 1070                 return -1;
 1071         }
 1072         if ((ch = i2cRead(bktr, MT2032_ADDR + 1)) == -1) {
 1073                 if (bootverbose)
 1074                         kprintf("%s: MT2032 get register %d failed\n",
 1075                                 bktr_name(bktr), regNum);
 1076                 return -1;
 1077         }
 1078         return ch;
 1079 }
 1080 
 1081 static void 
 1082 _MT2032_SetRegister(bktr_ptr_t bktr, u_char regNum, u_char data)
 1083 {
 1084         i2cWrite(bktr, MT2032_ADDR, regNum, data);
 1085 }
 1086 
 1087 #define MT2032_GetRegister(r)           _MT2032_GetRegister(bktr,r)
 1088 #define MT2032_SetRegister(r,d)         _MT2032_SetRegister(bktr,r,d)
 1089 
 1090 
 1091 int 
 1092 mt2032_init(bktr_ptr_t bktr)
 1093 {
 1094         u_char            rdbuf[22];
 1095         int             xogc, xok = 0;
 1096         int             i;
 1097         int             x;
 1098 
 1099         TDA9887_init(bktr, 0);
 1100 
 1101         for (i = 0; i < 21; i++) {
 1102                 if ((x = MT2032_GetRegister(i)) == -1)
 1103                         break;
 1104                 rdbuf[i] = x;
 1105         }
 1106         if (i < 21)
 1107                 return -1;
 1108 
 1109         kprintf("%s: MT2032: Companycode=%02x%02x Part=%02x Revision=%02x\n",
 1110                 bktr_name(bktr),
 1111                 rdbuf[0x11], rdbuf[0x12], rdbuf[0x13], rdbuf[0x14]);
 1112         if (rdbuf[0x13] != 4) {
 1113                 kprintf("%s: MT2032 not found or unknown type\n", bktr_name(bktr));
 1114                 return -1;
 1115         }
 1116 
 1117         /* Initialize Registers per spec. */
 1118         MT2032_SetRegister(2, 0xff);
 1119         MT2032_SetRegister(3, 0x0f);
 1120         MT2032_SetRegister(4, 0x1f);
 1121         MT2032_SetRegister(6, 0xe4);
 1122         MT2032_SetRegister(7, 0x8f);
 1123         MT2032_SetRegister(8, 0xc3);
 1124         MT2032_SetRegister(9, 0x4e);
 1125         MT2032_SetRegister(10, 0xec);
 1126         MT2032_SetRegister(13, 0x32);
 1127 
 1128         /* Adjust XOGC (register 7), wait for XOK */
 1129         xogc = 7;
 1130         do {
 1131                 DELAY(10000);
 1132                 xok = MT2032_GetRegister(0x0e) & 0x01;
 1133                 if (xok == 1) {
 1134                         break;
 1135                 }
 1136                 xogc--;
 1137                 if (xogc == 3) {
 1138                         xogc = 4;       /* min. 4 per spec */
 1139                         break;
 1140                 }
 1141                 MT2032_SetRegister(7, 0x88 + xogc);
 1142         } while (xok != 1);
 1143 
 1144         TDA9887_init(bktr, 1);
 1145 
 1146         MT2032_XOGC = xogc;
 1147 
 1148         return 0;
 1149 }
 1150 
 1151 static int 
 1152 MT2032_SpurCheck(int f1, int f2, int spectrum_from, int spectrum_to)
 1153 {
 1154         int             n1 = 1, n2, f;
 1155 
 1156         f1 = f1 / 1000;         /* scale to kHz to avoid 32bit overflows */
 1157         f2 = f2 / 1000;
 1158         spectrum_from /= 1000;
 1159         spectrum_to /= 1000;
 1160 
 1161         do {
 1162                 n2 = -n1;
 1163                 f = n1 * (f1 - f2);
 1164                 do {
 1165                         n2--;
 1166                         f = f - f2;
 1167                         if ((f > spectrum_from) && (f < spectrum_to)) {
 1168                                 return 1;
 1169                         }
 1170                 } while ((f > (f2 - spectrum_to)) || (n2 > -5));
 1171                 n1++;
 1172         } while (n1 < 5);
 1173 
 1174         return 0;
 1175 }
 1176 
 1177 static int
 1178 MT2032_ComputeFreq(
 1179                    int rfin,
 1180                    int if1,
 1181                    int if2,
 1182                    int spectrum_from,
 1183                    int spectrum_to,
 1184                    unsigned char *buf,
 1185                    int *ret_sel,
 1186                    int xogc
 1187 )
 1188 {                               /* all in Hz */
 1189         int             fref, lo1, lo1n, lo1a, s, sel;
 1190         int             lo1freq, desired_lo1, desired_lo2, lo2, lo2n, lo2a,
 1191                         lo2num;
 1192         int             nLO1adjust;
 1193 
 1194         fref = 5250 * 1000;     /* 5.25MHz */
 1195 
 1196         /* per spec 2.3.1 */
 1197         desired_lo1 = rfin + if1;
 1198         lo1 = (2 * (desired_lo1 / 1000) + (fref / 1000)) / (2 * fref / 1000);
 1199         lo1freq = lo1 * fref;
 1200         desired_lo2 = lo1freq - rfin - if2;
 1201 
 1202         /* per spec 2.3.2 */
 1203         for (nLO1adjust = 1; nLO1adjust < 3; nLO1adjust++) {
 1204                 if (!MT2032_SpurCheck(lo1freq, desired_lo2, spectrum_from, spectrum_to)) {
 1205                         break;
 1206                 }
 1207                 if (lo1freq < desired_lo1) {
 1208                         lo1 += nLO1adjust;
 1209                 } else {
 1210                         lo1 -= nLO1adjust;
 1211                 }
 1212 
 1213                 lo1freq = lo1 * fref;
 1214                 desired_lo2 = lo1freq - rfin - if2;
 1215         }
 1216 
 1217         /* per spec 2.3.3 */
 1218         s = lo1freq / 1000 / 1000;
 1219 
 1220         if (MT2032_OPTIMIZE_VCO) {
 1221                 if (s > 1890) {
 1222                         sel = 0;
 1223                 } else if (s > 1720) {
 1224                         sel = 1;
 1225                 } else if (s > 1530) {
 1226                         sel = 2;
 1227                 } else if (s > 1370) {
 1228                         sel = 3;
 1229                 } else {
 1230                         sel = 4;/* >1090 */
 1231                 }
 1232         } else {
 1233                 if (s > 1790) {
 1234                         sel = 0;/* <1958 */
 1235                 } else if (s > 1617) {
 1236                         sel = 1;
 1237                 } else if (s > 1449) {
 1238                         sel = 2;
 1239                 } else if (s > 1291) {
 1240                         sel = 3;
 1241                 } else {
 1242                         sel = 4;/* >1090 */
 1243                 }
 1244         }
 1245 
 1246         *ret_sel = sel;
 1247 
 1248         /* per spec 2.3.4 */
 1249         lo1n = lo1 / 8;
 1250         lo1a = lo1 - (lo1n * 8);
 1251         lo2 = desired_lo2 / fref;
 1252         lo2n = lo2 / 8;
 1253         lo2a = lo2 - (lo2n * 8);
 1254         /* scale to fit in 32bit arith */
 1255         lo2num = ((desired_lo2 / 1000) % (fref / 1000)) * 3780 / (fref / 1000);
 1256 
 1257         if (lo1a < 0 || lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a < 0 ||
 1258             lo2a > 7 || lo2n < 17 || lo2n > 30) {
 1259                 kprintf("MT2032: parameter out of range\n");
 1260                 return -1;
 1261         }
 1262         /* set up MT2032 register map for transfer over i2c */
 1263         buf[0] = lo1n - 1;
 1264         buf[1] = lo1a | (sel << 4);
 1265         buf[2] = 0x86;          /* LOGC */
 1266         buf[3] = 0x0f;          /* reserved */
 1267         buf[4] = 0x1f;
 1268         buf[5] = (lo2n - 1) | (lo2a << 5);
 1269         if (rfin < 400 * 1000 * 1000) {
 1270                 buf[6] = 0xe4;
 1271         } else {
 1272                 buf[6] = 0xf4;  /* set PKEN per rev 1.2 */
 1273         }
 1274 
 1275         buf[7] = 8 + xogc;
 1276         buf[8] = 0xc3;          /* reserved */
 1277         buf[9] = 0x4e;          /* reserved */
 1278         buf[10] = 0xec;         /* reserved */
 1279         buf[11] = (lo2num & 0xff);
 1280         buf[12] = (lo2num >> 8) | 0x80; /* Lo2RST */
 1281 
 1282         return 0;
 1283 }
 1284 
 1285 static int 
 1286 MT2032_CheckLOLock(bktr_ptr_t bktr)
 1287 {
 1288         int             t, lock = 0;
 1289         for (t = 0; t < 10; t++) {
 1290                 lock = MT2032_GetRegister(0x0e) & 0x06;
 1291                 if (lock == 6) {
 1292                         break;
 1293                 }
 1294                 DELAY(1000);
 1295         }
 1296         return lock;
 1297 }
 1298 
 1299 static int 
 1300 MT2032_OptimizeVCO(bktr_ptr_t bktr, int sel, int lock)
 1301 {
 1302         int             tad1, lo1a;
 1303 
 1304         tad1 = MT2032_GetRegister(0x0f) & 0x07;
 1305 
 1306         if (tad1 == 0) {
 1307                 return lock;
 1308         }
 1309         if (tad1 == 1) {
 1310                 return lock;
 1311         }
 1312         if (tad1 == 2) {
 1313                 if (sel == 0) {
 1314                         return lock;
 1315                 } else {
 1316                         sel--;
 1317                 }
 1318         } else {
 1319                 if (sel < 4) {
 1320                         sel++;
 1321                 } else {
 1322                         return lock;
 1323                 }
 1324         }
 1325         lo1a = MT2032_GetRegister(0x01) & 0x07;
 1326         MT2032_SetRegister(0x01, lo1a | (sel << 4));
 1327         lock = MT2032_CheckLOLock(bktr);
 1328         return lock;
 1329 }
 1330 
 1331 static int
 1332 MT2032_SetIFFreq(bktr_ptr_t bktr, int rfin, int if1, int if2, int from, int to)
 1333 {
 1334         u_char          buf[21];
 1335         int             lint_try, sel, lock = 0;
 1336 
 1337         if (MT2032_ComputeFreq(rfin, if1, if2, from, to, &buf[0], &sel, MT2032_XOGC) == -1)
 1338                 return -1;
 1339 
 1340         TDA9887_init(bktr, 0);
 1341 
 1342         /* send only the relevant registers per Rev. 1.2 */
 1343         MT2032_SetRegister(0, buf[0x00]);
 1344         MT2032_SetRegister(1, buf[0x01]);
 1345         MT2032_SetRegister(2, buf[0x02]);
 1346 
 1347         MT2032_SetRegister(5, buf[0x05]);
 1348         MT2032_SetRegister(6, buf[0x06]);
 1349         MT2032_SetRegister(7, buf[0x07]);
 1350 
 1351         MT2032_SetRegister(11, buf[0x0B]);
 1352         MT2032_SetRegister(12, buf[0x0C]);
 1353 
 1354         /* wait for PLLs to lock (per manual), retry LINT if not. */
 1355         for (lint_try = 0; lint_try < 2; lint_try++) {
 1356                 lock = MT2032_CheckLOLock(bktr);
 1357 
 1358                 if (MT2032_OPTIMIZE_VCO) {
 1359                         lock = MT2032_OptimizeVCO(bktr, sel, lock);
 1360                 }
 1361                 if (lock == 6) {
 1362                         break;
 1363                 }
 1364                 /* set LINT to re-init PLLs */
 1365                 MT2032_SetRegister(7, 0x80 + 8 + MT2032_XOGC);
 1366                 DELAY(10000);
 1367                 MT2032_SetRegister(7, 8 + MT2032_XOGC);
 1368         }
 1369         if (lock != 6)
 1370                 kprintf("%s: PLL didn't lock\n", bktr_name(bktr));
 1371 
 1372         MT2032_SetRegister(2, 0x20);
 1373 
 1374         TDA9887_init(bktr, 1);
 1375         return 0;
 1376 }
 1377 
 1378 static void
 1379 mt2032_set_tv_freq(bktr_ptr_t bktr, unsigned int freq)
 1380 {
 1381         int if2,from,to;
 1382         int stat, tad;
 1383 
 1384 #ifdef MT2032_NTSC
 1385         from=40750*1000;
 1386         to=46750*1000;
 1387         if2=45750*1000;
 1388 #else
 1389         from=32900*1000;
 1390         to=39900*1000;
 1391         if2=38900*1000;
 1392 #endif
 1393 
 1394         if (MT2032_SetIFFreq(bktr, freq*62500 /* freq*1000*1000/16 */,
 1395                         1090*1000*1000, if2, from, to) == 0) {
 1396                 bktr->tuner.frequency = freq;
 1397                 stat = MT2032_GetRegister(0x0e);
 1398                 tad = MT2032_GetRegister(0x0f);
 1399                 if (bootverbose)
 1400                         kprintf("%s: frequency set to %d, st = %#x, tad = %#x\n",
 1401                                 bktr_name(bktr), freq*62500, stat, tad);
 1402         }
 1403 }

Cache object: 522ae42a0d0516b968a0c9dd78cc794e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.