[BACK]Return to bktr_tuner.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci / bktr

Annotation of sys/dev/pci/bktr/bktr_tuner.c, Revision 1.1.1.1

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

CVSweb