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

Cache object: 88bc5a301417e6f29cd328d8ff295534


[ 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.