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

Cache object: 7436a6430552a129050182986ef20139


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