/* ---- card 0x80 ---------------------------------- */
[BTTV_BOARD_DVICO_DVBT_LITE] = { /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
.name = "DViCO FusionHDTV DVB-T Lite",
.no_msp34xx = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.no_video = 1,
.has_dvb = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
[BTTV_BOARD_VGEAR_MYVCD] = { /* Steven <photon38@pchome.com.tw> */
.name = "V-Gear MyVCD",
.video_inputs = 3, /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
.muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x31, 0x31, 0x31, 0x31 },
.gpiomute = 0x31,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
.tuner_addr = ADDR_UNSET,
.has_radio = 0,
},
[BTTV_BOARD_SUPER_TV] = { /* Rick C <cryptdragoon@gmail.com> */
.name = "Super TV Tuner",
.video_inputs = 4, /* .audio_inputs= 1, */
.svhs = 2,
.muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
.gpiomask = 0x008007,
.gpiomux = { 0, 0x000001,0,0 },
.has_radio = 1,
},
[BTTV_BOARD_TIBET_CS16] = { /* Chris Fanning <video4linux@haydon.net> */
.name = "Tibet Systems 'Progress DVR' CS16",
.video_inputs = 16, /* .audio_inputs= 0, */
.svhs = NO_SVHS,
.muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.muxsel_hook = tibetCS16_muxsel,
},
[BTTV_BOARD_KODICOM_4400R] = { /* Bill Brack <wbrack@mmm.com.hk> */ /* * Note that, because of the card's wiring, the "master" * BT878A chip (i.e. the one which controls the analog switch * and must use this card type) is the 2nd one detected. The * other 3 chips should use card type 0x85, whose description * follows this one. There is a EEPROM on the card (which is * connected to the I2C of one of those other chips), but is * not currently handled. There is also a facility for a * "monitor", which is also not currently implemented.
*/
.name = "Kodicom 4400R (master)",
.video_inputs = 16, /* .audio_inputs= 0, */
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.svhs = NO_SVHS, /* GPIO bits 0-9 used for analog switch: * 00 - 03: camera selector * 04 - 06: channel (controller) selector * 07: data (1->on, 0->off) * 08: strobe * 09: reset * bit 16 is input from sync separator for the channel
*/
.gpiomask = 0x0003ff,
.no_gpioirq = 1,
.muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
.muxsel_hook = kodicom4400r_muxsel,
},
[BTTV_BOARD_KODICOM_4400R_SL] = { /* Bill Brack <wbrack@mmm.com.hk> */ /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the * one which controls the analog switch, and must use the card type) * is the 2nd one detected. The other 3 chips should use this card * type
*/
.name = "Kodicom 4400R (slave)",
.video_inputs = 16, /* .audio_inputs= 0, */
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.svhs = NO_SVHS,
.gpiomask = 0x010000,
.no_gpioirq = 1,
.muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
.muxsel_hook = kodicom4400r_muxsel,
}, /* ---- card 0x86---------------------------------- */
[BTTV_BOARD_ADLINK_RTV24] = { /* Michael Henson <mhenson@clarityvi.com> */ /* Adlink RTV24 with special unlock codes */
.name = "Adlink RTV24",
.video_inputs = 4, /* .audio_inputs= 1, */
.svhs = 2,
.muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
.pll = PLL_28,
}, /* ---- card 0x87---------------------------------- */
[BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { /* Michael Krufky <mkrufky@linuxtv.org> */
.name = "DViCO FusionHDTV 5 Lite",
.tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
.tuner_addr = ADDR_UNSET,
.video_inputs = 3, /* .audio_inputs= 1, */
.svhs = 2,
.muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
.no_msp34xx = 1,
.no_tda7432 = 1,
.has_dvb = 1,
}, /* ---- card 0x88---------------------------------- */
[BTTV_BOARD_ACORP_Y878F] = { /* Mauro Carvalho Chehab <mchehab@kernel.org> */
.name = "Acorp Y878F",
.video_inputs = 3, /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x01fe00,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
.gpiomute = 0x002000,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
.tuner_addr = 0xc1 >>1,
.has_radio = 1,
}, /* ---- card 0x89 ---------------------------------- */
[BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
.name = "Conceptronic CTVFMi v2",
.video_inputs = 3, /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x001c0007,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 3,
.pll = PLL_28,
.tuner_type = TUNER_TENA_9533_DI,
.tuner_addr = ADDR_UNSET,
.has_remote = 1,
.has_radio = 1,
}, /* ---- card 0x8a ---------------------------------- */
[BTTV_BOARD_PV_BT878P_2E] = {
.name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
.video_inputs = 5, /* .audio_inputs= 1, */
.svhs = 3,
.has_dig_in = 1,
.gpiomask = 0x01fe00,
.muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */
.gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
.gpiomute = 0x12400,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_LG_PAL_FM,
.tuner_addr = ADDR_UNSET,
.has_remote = 1,
}, /* ---- card 0x8b ---------------------------------- */
[BTTV_BOARD_PV_M4900] = { /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
.name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
.video_inputs = 3, /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x21, 0x20, 0x24, 0x2c },
.gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF_5533MF,
.tuner_addr = ADDR_UNSET,
.has_radio = 1,
.has_remote = 1,
}, /* ---- card 0x8c ---------------------------------- */ /* Has four Bt878 chips behind a PCI bridge, each chip has: one external BNC composite input (mux 2) three internal composite inputs (unknown muxes) an 18-bit stereo A/D (CS5331A), which has: one external stereo unbalanced (RCA) audio connection one (or 3?) internal stereo balanced (XLR) audio connection input is selected via gpio to a 14052B mux (mask=0x300, unbal=0x000, bal=0x100, ??=0x200,0x300) gain is controlled via an X9221A chip on the I2C bus @0x28 sample rate is controlled via gpio to an MK1413S (mask=0x3, 32kHz=0x0, 44.1kHz=0x1, 48kHz=0x2, ??=0x3)
There is neither a tuner nor an svideo input. */
[BTTV_BOARD_OSPREY440] = {
.name = "Osprey 440",
.video_inputs = 4, /* .audio_inputs= 2, */
.svhs = NO_SVHS,
.muxsel = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */
.gpiomask = 0x303,
.gpiomute = 0x000, /* int + 32kHz */
.gpiomux = { 0, 0, 0x000, 0x100},
.pll = PLL_28,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda7432 = 1,
}, /* ---- card 0x8d ---------------------------------- */
[BTTV_BOARD_ASOUND_SKYEYE] = {
.name = "Asound Skyeye PCTV",
.video_inputs = 3, /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
}, /* ---- card 0x8e ---------------------------------- */
[BTTV_BOARD_SABRENT_TVFM] = {
.name = "Sabrent TV-FM (bttv version)",
.video_inputs = 3, /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x108007,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 100000, 100002, 100002, 100000 },
.no_msp34xx = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.tuner_type = TUNER_TNF_5335MF,
.tuner_addr = ADDR_UNSET,
.has_radio = 1,
}, /* ---- card 0x8f ---------------------------------- */
[BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
.name = "Hauppauge ImpactVCB (bt878)",
.video_inputs = 4, /* .audio_inputs= 0, */
.svhs = NO_SVHS,
.gpiomask = 0x0f, /* old: 7 */
.muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
.no_msp34xx = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
[BTTV_BOARD_MACHTV_MAGICTV] = { /* Julian Calaby <julian.calaby@gmail.com> * Slightly different from original MachTV definition (0x60)
* FIXME: RegSpy says gpiomask should be "0x001c800f", but it * stuffs up remote chip. Bug is a pin on the jaecs is not set
* properly (methinks) causing no keyup bits being set */
if (0 != btv->cardid && 0xffffffff != btv->cardid) { /* look for the card */ for (type = -1, i = 0; cards[i].id != 0; i++) if (cards[i].id == btv->cardid)
type = i;
if (type != -1) { /* found it */
pr_info("%d: detected: %s [card=%d], PCI subsystem ID is %04x:%04x\n",
btv->c.nr, cards[type].name, cards[type].cardnr,
btv->cardid & 0xffff,
(btv->cardid >> 16) & 0xffff);
btv->c.type = cards[type].cardnr;
} else { /* 404 */
pr_info("%d: subsystem: %04x:%04x (UNKNOWN)\n",
btv->c.nr, btv->cardid & 0xffff,
(btv->cardid >> 16) & 0xffff);
pr_debug("please mail id, board name and the correct card= insmod option to linux-media@vger.kernel.org\n");
}
}
/* let the user override the autodetected type */ if (card[btv->c.nr] < bttv_num_tvcards)
btv->c.type=card[btv->c.nr];
/* print which card config we are using */
pr_info("%d: using: %s [card=%d,%s]\n",
btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type,
card[btv->c.nr] < bttv_num_tvcards
? "insmod option" : "autodetected");
if (UNSET != audiomux[0]) {
gpiobits = 0; for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i];
gpiobits |= audiomux[i];
}
} else {
gpiobits = audioall; for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
bttv_tvcards[btv->c.type].gpiomux[i] = audioall;
}
}
bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
pr_info("%d: gpio config override: mask=0x%x, mux=",
btv->c.nr, bttv_tvcards[btv->c.type].gpiomask); for (i = 0; i < ARRAY_SIZE(bttv_tvcards->gpiomux); i++) {
pr_cont("%s0x%x",
i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]);
}
pr_cont("\n");
}
/* * (most) board specific initialisations goes here
*/
/* Some Modular Technology cards have an eeprom, but no subsystem ID */ staticvoid identify_by_eeprom(struct bttv *btv, unsignedchar eeprom_data[256])
{ int type = -1;
if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
type = BTTV_BOARD_MODTEC_205; elseif (0 == strncmp(eeprom_data+20,"Picolo",7))
type = BTTV_BOARD_EURESYS_PICOLO; elseif (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */
if (-1 != type) {
btv->c.type = type;
pr_info("%d: detected by eeprom: %s [card=%d]\n",
btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type);
}
}
staticvoid flyvideo_gpio(struct bttv *btv)
{ int gpio, has_remote, has_radio, is_capture_only; int is_lr90, has_tda9820_tda9821; int tuner_type = UNSET, ttype;
gpio_inout(0xffffff, 0);
udelay(8); /* without this we would see the 0x1800 mask */
gpio = gpio_read(); /* FIXME: must restore OUR_EN ??? */
/* all cards provide GPIO info, some have an additional eeprom * LR50: GPIO coding can be found lower right CP1 .. CP9 * CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1. * GPIO14-12: n.c. * LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
* lowest 3 bytes are remote control codes (no handshake needed) * xxxFFF: No remote control chip soldered * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered * Note: Some bits are Audio_Mask !
*/
ttype = (gpio & 0x0f0000) >> 16; switch (ttype) { case 0x0:
tuner_type = 2; /* NTSC, e.g. TPI8NSR11P */ break; case 0x2:
tuner_type = 39; /* LG NTSC (newer TAPC series) TAPC-H701P */ break; case 0x4:
tuner_type = 5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ break; case 0x6:
tuner_type = 37; /* LG PAL (newer TAPC series) TAPC-G702P */ break; case 0xC:
tuner_type = 3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */ break; default:
pr_info("%d: FlyVideo_gpio: unknown tuner type\n", btv->c.nr); break;
}
if (tuner_type != UNSET) /* only set if known tuner autodetected, else let insmod option through */
btv->tuner_type = tuner_type;
btv->has_radio = has_radio;
/* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80 * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
* Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */ if (has_tda9820_tda9821)
btv->audio_mode_gpio = lt9415_audio; /* todo: if(has_tda9874) btv->audio_mode_gpio = fv2000s_audio; */
}
/* switch sync drive off */
gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
/* set BT848 muxel to 2 */
btaor((2)<<5, ~(2<<5), BT848_IFORM);
}
/* Muxsel helper for the IDS Eagle. * the eagles does not use the standard muxsel-bits but
* has its own multiplexer */ staticvoid eagle_muxsel(struct bttv *btv, unsignedint input)
{
gpio_bits(3, input & 3);
/* composite */ /* set chroma ADC to sleep */
btor(BT848_ADC_C_SLEEP, BT848_ADC); /* set to composite video */
btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
/* switch sync drive off */
gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
}
/* * The TD3116 has 2 74HC4051 muxes wired to the MUX0 input of a bt878. * The first 74HC4051 has the lower 8 inputs, the second one the higher 8. * The muxes are controlled via a 74HC373 latch which is connected to * GPIOs 0-7. GPIO 18 is connected to the LE signal of the latch. * Q0 of the latch is connected to the Enable (~E) input of the first * 74HC4051. Q1 - Q3 are connected to S0 - S2 of the same 74HC4051. * Q4 - Q7 are connected to the second 74HC4051 in the same way.
*/
/* Disable outputs and set value in the mux */
value = 0x11; /* Disable outputs */
value |= ((input & 0x7) << 1) << (4 * highbit);
td3116_latch_value(btv, value);
/* Enable the correct output */
value &= ~0x11;
value |= ((highbit ^ 0x1) << 4) | highbit;
td3116_latch_value(btv, value);
}
staticvoid bttv_reset_audio(struct bttv *btv)
{ /* * BT878A has a audio-reset register. * 1. This register is an audio reset function but it is in * function-0 (video capture) address space. * 2. It is enough to do this once per power-up of the card. * 3. There is a typo in the Conexant doc -- it is not at * 0x5B, but at 0x058. (B is an odd-number, obviously a typo!). * --//Shrikumar 030609
*/ if (btv->id != 878) return;
/* initialization part one -- before registering i2c bus */ void bttv_init_card1(struct bttv *btv)
{ switch (btv->c.type) { case BTTV_BOARD_HAUPPAUGE: case BTTV_BOARD_HAUPPAUGE878:
boot_msp34xx(btv,5); break; case BTTV_BOARD_VOODOOTV_200: case BTTV_BOARD_VOODOOTV_FM:
boot_msp34xx(btv,20); break; case BTTV_BOARD_AVERMEDIA98:
boot_msp34xx(btv,11); break; case BTTV_BOARD_HAUPPAUGEPVR:
pvr_boot(btv); break; case BTTV_BOARD_TWINHAN_DST: case BTTV_BOARD_AVDVBT_771: case BTTV_BOARD_PINNACLESAT:
btv->use_i2c_hw = 1; break; case BTTV_BOARD_ADLINK_RTV24:
init_RTV24( btv ); break; case BTTV_BOARD_PCI_8604PW:
init_PCI8604PW(btv); break;
} if (!bttv_tvcards[btv->c.type].has_dvb)
bttv_reset_audio(btv);
}
/* initialization part two -- after registering i2c bus */ void bttv_init_card2(struct bttv *btv)
{
btv->tuner_type = UNSET;
if (BTTV_BOARD_UNKNOWN == btv->c.type) {
bttv_readee(btv,eeprom_data,0xa0);
identify_by_eeprom(btv,eeprom_data);
}
switch (btv->c.type) { case BTTV_BOARD_MIRO: case BTTV_BOARD_MIROPRO: case BTTV_BOARD_PINNACLE: case BTTV_BOARD_PINNACLEPRO: /* miro/pinnacle */
miro_pinnacle_gpio(btv); break; case BTTV_BOARD_FLYVIDEO_98: case BTTV_BOARD_MAXI: case BTTV_BOARD_LIFE_FLYKIT: case BTTV_BOARD_FLYVIDEO: case BTTV_BOARD_TYPHOON_TVIEW: case BTTV_BOARD_CHRONOS_VS2: case BTTV_BOARD_FLYVIDEO_98FM: case BTTV_BOARD_FLYVIDEO2000: case BTTV_BOARD_FLYVIDEO98EZ: case BTTV_BOARD_CONFERENCETV: case BTTV_BOARD_LIFETEC_9415:
flyvideo_gpio(btv); break; case BTTV_BOARD_HAUPPAUGE: case BTTV_BOARD_HAUPPAUGE878: case BTTV_BOARD_HAUPPAUGEPVR: /* pick up some config infos from the eeprom */
bttv_readee(btv,eeprom_data,0xa0);
hauppauge_eeprom(btv); break; case BTTV_BOARD_AVERMEDIA98: case BTTV_BOARD_AVPHONE98:
bttv_readee(btv,eeprom_data,0xa0);
avermedia_eeprom(btv); break; case BTTV_BOARD_PXC200:
init_PXC200(btv); break; case BTTV_BOARD_PICOLO_TETRA_CHIP:
picolo_tetra_init(btv); break; case BTTV_BOARD_VHX:
btv->has_radio = 1;
btv->has_tea575x = 1;
btv->tea_gpio.wren = 5;
btv->tea_gpio.most = 6;
btv->tea_gpio.clk = 3;
btv->tea_gpio.data = 4;
tea575x_init(btv); break; case BTTV_BOARD_VOBIS_BOOSTAR: case BTTV_BOARD_TERRATV:
terratec_active_radio_upgrade(btv); break; case BTTV_BOARD_MAGICTVIEW061: if (btv->cardid == 0x3002144f) {
btv->has_radio=1;
pr_info("%d: radio detected by subsystem id (CPH05x)\n",
btv->c.nr);
} break; case BTTV_BOARD_STB2: if (btv->cardid == 0x3060121a) { /* Fix up entry for 3DFX VoodooTV 100,
which is an OEM STB card variant. */
btv->has_radio=0;
btv->tuner_type=TUNER_TEMIC_NTSC;
} break; case BTTV_BOARD_OSPREY1x0: case BTTV_BOARD_OSPREY1x0_848: case BTTV_BOARD_OSPREY101_848: case BTTV_BOARD_OSPREY1x1: case BTTV_BOARD_OSPREY1x1_SVID: case BTTV_BOARD_OSPREY2xx: case BTTV_BOARD_OSPREY2x0_SVID: case BTTV_BOARD_OSPREY2x0: case BTTV_BOARD_OSPREY440: case BTTV_BOARD_OSPREY500: case BTTV_BOARD_OSPREY540: case BTTV_BOARD_OSPREY2000:
bttv_readee(btv,eeprom_data,0xa0);
osprey_eeprom(btv, eeprom_data); break; case BTTV_BOARD_IDS_EAGLE:
init_ids_eagle(btv); break; case BTTV_BOARD_MODTEC_205:
bttv_readee(btv,eeprom_data,0xa0);
modtec_eeprom(btv); break; case BTTV_BOARD_LMLBT4:
init_lmlbt4x(btv); break; case BTTV_BOARD_TIBET_CS16:
tibetCS16_init(btv); break; case BTTV_BOARD_KODICOM_4400R:
kodicom4400r_init(btv); break; case BTTV_BOARD_GEOVISION_GV800S:
gv800s_init(btv); break;
}
/* pll configuration */ if (!(btv->id==848 && btv->revision==0x11)) { /* defaults from card list */ if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
btv->pll.pll_ifreq=28636363;
btv->pll.pll_crystal=BT848_IFORM_XT0;
} if (PLL_35 == bttv_tvcards[btv->c.type].pll) {
btv->pll.pll_ifreq=35468950;
btv->pll.pll_crystal=BT848_IFORM_XT1;
} if (PLL_14 == bttv_tvcards[btv->c.type].pll) {
btv->pll.pll_ifreq = 14318181;
btv->pll.pll_crystal = BT848_IFORM_XT0;
} /* insmod options can override */ switch (pll[btv->c.nr]) { case 0: /* none */
btv->pll.pll_crystal = 0;
btv->pll.pll_ifreq = 0;
btv->pll.pll_ofreq = 0; break; case 1: /* 28 MHz */ case 28:
btv->pll.pll_ifreq = 28636363;
btv->pll.pll_ofreq = 0;
btv->pll.pll_crystal = BT848_IFORM_XT0; break; case 2: /* 35 MHz */ case 35:
btv->pll.pll_ifreq = 35468950;
btv->pll.pll_ofreq = 0;
btv->pll.pll_crystal = BT848_IFORM_XT1; break; case 3: /* 14 MHz */ case 14:
btv->pll.pll_ifreq = 14318181;
btv->pll.pll_ofreq = 0;
btv->pll.pll_crystal = BT848_IFORM_XT0; break;
}
}
btv->pll.pll_current = -1;
/* tuner configuration (from card list / autodetect / insmod option) */ if (UNSET != bttv_tvcards[btv->c.type].tuner_type) if (UNSET == btv->tuner_type)
btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; if (UNSET != tuner[btv->c.nr])
btv->tuner_type = tuner[btv->c.nr];
if (autoload != UNSET) {
pr_warn("%d: the autoload option is obsolete\n", btv->c.nr);
pr_warn("%d: use option msp3400, tda7432 or tvaudio to override which audio module should be used\n",
btv->c.nr);
}
if (UNSET == btv->tuner_type)
btv->tuner_type = TUNER_ABSENT;
if (bttv_tvcards[btv->c.type].has_radio)
btv->has_radio = 1; if (bttv_tvcards[btv->c.type].has_remote)
btv->has_remote = 1; if (!bttv_tvcards[btv->c.type].no_gpioirq)
btv->gpioirq = 1; if (bttv_tvcards[btv->c.type].volume_gpio)
btv->volume_gpio = bttv_tvcards[btv->c.type].volume_gpio; if (bttv_tvcards[btv->c.type].audio_mode_gpio)
btv->audio_mode_gpio = bttv_tvcards[btv->c.type].audio_mode_gpio;
if (btv->tuner_type == TUNER_ABSENT) return; /* no tuner or related drivers to load */
/* First check if the user specified the audio chip via a module
option. */
switch (audiodev[btv->c.nr]) { case -1: return; /* do not load any audio module */
case 0: /* autodetect */ break;
case 1: { /* The user specified that we should probe for msp3400 */ staticconstunsignedshort addrs[] = {
I2C_ADDR_MSP3400 >> 1,
I2C_ADDR_MSP3400_ALT >> 1,
I2C_CLIENT_END
};
case 2: { /* The user specified that we should probe for tda7432 */ staticconstunsignedshort addrs[] = {
I2C_ADDR_TDA7432 >> 1,
I2C_CLIENT_END
};
if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
&btv->c.i2c_adap, "tda7432", 0, addrs)) return; goto no_audio;
}
case 3: { /* The user specified that we should probe for tvaudio */
btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
&btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); if (btv->sd_tvaudio) return; goto no_audio;
}
/* There were no overrides, so now we try to discover this through the
card definition */
/* probe for msp3400 first: this driver can detect whether or not it really is a msp3400, so it will return NULL when the device
found is really something else (e.g. a tea6300). */ if (!bttv_tvcards[btv->c.type].no_msp34xx) {
btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
&btv->c.i2c_adap, "msp3400",
0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
} elseif (bttv_tvcards[btv->c.type].msp34xx_alt) {
btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
&btv->c.i2c_adap, "msp3400",
0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
}
/* If we found a msp34xx, then we're done. */ if (btv->sd_msp34xx) return;
/* Now see if we can find one of the tvaudio devices. */
btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
&btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs()); if (btv->sd_tvaudio) { /* There may be two tvaudio chips on the card, so try to
find another. */
v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
&btv->c.i2c_adap, "tvaudio", 0, tvaudio_addrs());
}
/* it might also be a tda7432. */ if (!bttv_tvcards[btv->c.type].no_tda7432) { staticconstunsignedshort addrs[] = {
I2C_ADDR_TDA7432 >> 1,
I2C_CLIENT_END
};
btv->sd_tda7432 = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
&btv->c.i2c_adap, "tda7432", 0, addrs); if (btv->sd_tda7432) return;
} if (btv->sd_tvaudio) return;
no_audio:
pr_warn("%d: audio absent, no audio device found!\n", btv->c.nr);
}
/* initialize the tuner */ void bttv_init_tuner(struct bttv *btv)
{ int addr = ADDR_UNSET;
if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
addr = bttv_tvcards[btv->c.type].tuner_addr;
if (btv->tuner_type != TUNER_ABSENT) { struct tuner_setup tun_setup;
/* * Some of the 878 boards have duplicate PCI IDs. Switch the board * type based on model #.
*/ if(tv.model == 64900) {
pr_info("%d: Switching board type from %s to %s\n",
btv->c.nr,
bttv_tvcards[btv->c.type].name,
bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name);
btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB;
}
/* The 61334 needs the msp3410 to do the radio demod to get sound */ if (tv.model == 61334)
btv->radio_uses_msp_demodulator = 1;
}
/* * minimal bootstrap for the WinTV/PVR -- upload altera firmware. * * The hcwamc.rbf firmware file is on the Hauppauge driver CD. Have * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be * unpacked with unzip).
*/ #define PVR_GPIO_DELAY 10
/* ----------------------------------------------------------------------- */ /* some osprey specific stuff */
staticvoid osprey_eeprom(struct bttv *btv, const u8 ee[256])
{ int i;
u32 serial = 0; int cardid = -1;
/* This code will never actually get called in this case.... */ if (btv->c.type == BTTV_BOARD_UNKNOWN) { /* this might be an antique... check for MMAC label in eeprom */ if (!strncmp(ee, "MMAC", 4)) {
u8 checksum = 0; for (i = 0; i < 21; i++)
checksum += ee[i]; if (checksum != ee[21]) return;
cardid = BTTV_BOARD_OSPREY1x0_848; for (i = 12; i < 21; i++) {
serial *= 10;
serial += ee[i] - '0';
}
}
} else { unsignedshort type;
for (i = 4 * 16; i < 8 * 16; i += 16) {
u16 checksum = (__force u16)ip_compute_csum(ee + i, 16);
if ((checksum & 0xff) + (checksum >> 8) == 0xff) break;
} if (i >= 8*16) return;
ee += i;
/* found a valid descriptor */
type = get_unaligned_be16((__be16 *)(ee+4));
switch(type) { /* 848 based */ case 0x0004:
cardid = BTTV_BOARD_OSPREY1x0_848; break; case 0x0005:
cardid = BTTV_BOARD_OSPREY101_848; break;
/* 878 based */ case 0x0012: case 0x0013:
cardid = BTTV_BOARD_OSPREY1x0; break; case 0x0014: case 0x0015:
cardid = BTTV_BOARD_OSPREY1x1; break; case 0x0016: case 0x0017: case 0x0020:
cardid = BTTV_BOARD_OSPREY1x1_SVID; break; case 0x0018: case 0x0019: case 0x001E: case 0x001F:
cardid = BTTV_BOARD_OSPREY2xx; break; case 0x001A: case 0x001B:
cardid = BTTV_BOARD_OSPREY2x0_SVID; break; case 0x0040:
cardid = BTTV_BOARD_OSPREY500; break; case 0x0050: case 0x0056:
cardid = BTTV_BOARD_OSPREY540; /* bttv_osprey_540_init(btv); */ break; case 0x0060: case 0x0070: case 0x00A0:
cardid = BTTV_BOARD_OSPREY2x0; /* enable output on select control lines */
gpio_inout(0xffffff,0x000303); break; case 0x00D8:
cardid = BTTV_BOARD_OSPREY440; break; default: /* unknown...leave generic, but get serial # */
pr_info("%d: osprey eeprom: unknown card type 0x%04x\n",
btv->c.nr, type); break;
}
serial = get_unaligned_be32((__be32 *)(ee+6));
}
/* * For Voodoo TV/FM and Voodoo 200. These cards' tuners use a TDA9880 * analog demod, which is not I2C controlled like the newer and more common * TDA9887 series. Instead it has two tri-state input pins, S0 and S1, * that control the IF for the video and audio. Apparently, bttv GPIO * 0x10000 is connected to S0. S0 low selects a 38.9 MHz VIF for B/G/D/K/I * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC).
*/
u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits)
{
if (btv->audio_input == TVAUDIO_INPUT_TUNER) { if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN)
gpiobits |= 0x10000; else
gpiobits &= ~0x10000;
}
if (bttv_gpio)
bttv_gpio_tracking(btv,"msp34xx"); if (bttv_verbose)
pr_info("%d: Hauppauge/Voodoo msp34xx: reset line init [%d]\n",
btv->c.nr, pin);
}
/* ----------------------------------------------------------------------- */ /* Imagenation L-Model PXC200 Framegrabber */ /* This is basically the same procedure as * used by Alessandro Rubini in his pxc200
* driver, but using BTTV functions */
/* Initialise GPIO-connected stuff */
gpio_inout(0xffffff, (1<<13));
gpio_write(0);
udelay(3);
gpio_write(1<<13); /* GPIO inputs are pulled up, so no need to drive
* reset pin any longer */
gpio_bits(0xffffff, 0); if (bttv_gpio)
bttv_gpio_tracking(btv,"pxc200");
/* we could/should try and reset/control the AD pots? but right now we simply turned off the crushing. Without this the AGC drifts drifts remember the EN is reverse logic --> setting BT848_ADC_AGC_EN disable the AGC tboult@eecs.lehigh.edu
*/
/* Initialise 12C508 PIC */ /* The I2CWrite and I2CRead commands are actually to the * same chips - but the R/W bit is included in the address
* argument so the numbers are different */
pr_info("Initialising 12C508 PIC chip ...\n");
/* First of all, enable the clock line. This is used in the PXC200-F */
val = btread(BT848_GPIO_DMA_CTL);
val |= BT848_GPIO_DMA_CTL_GPCLKMODE;
btwrite(val, BT848_GPIO_DMA_CTL);
/* Then, push to 0 the reset pin long enough to reset the * * device same as above for the reset line, but not the same * value sent to the GPIO-connected stuff
* which one is the good one? */
gpio_inout(0xffffff,(1<<2));
gpio_write(0);
udelay(10);
gpio_write(1<<2);
for (i = 0; i < ARRAY_SIZE(vals); i++) {
tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); if (tmp != -1) {
pr_info("I2C Write(%2.2x) = %i\nI2C Read () = %2.2x\n\n",
vals[i],tmp,bttv_I2CRead(btv,0x1F,NULL));
}
}
pr_info("PXC200 Initialised\n");
}
/* ----------------------------------------------------------------------- */ /* * The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock * it. This apparently involves the following procedure for each 878 chip: * * 1) write 0x00C3FEFF to the GPIO_OUT_EN register * * 2) write to GPIO_DATA * - 0x0E * - sleep 1ms * - 0x10 + 0x0E * - sleep 10ms * - 0x0E * read from GPIO_DATA into buf (uint_32) * - if ( data>>18 & 0x01 != 0) || ( buf>>19 & 0x01 != 1 ) * error. ERROR_CPLD_Check_Failed stop. * * 3) write to GPIO_DATA * - write 0x4400 + 0x0E * - sleep 10ms * - write 0x4410 + 0x0E * - sleep 1ms * - write 0x0E * read from GPIO_DATA into buf (uint_32) * - if ( buf>>18 & 0x01 ) || ( buf>>19 & 0x01 != 0 ) * error. ERROR_CPLD_Check_Failed.
*/ /* ----------------------------------------------------------------------- */ staticvoid
init_RTV24 (struct bttv *btv)
{
uint32_t dataRead = 0; long watchdog_value = 0x0E;
pr_info("%d: Adlink RTV-24 initialisation in progress ...\n",
btv->c.nr);
/* ----------------------------------------------------------------------- */ /* * The PCI-8604PW contains a CPLD, probably an ispMACH 4A, that filters * the PCI REQ signals coming from the four BT878 chips. After power * up, the CPLD does not forward requests to the bus, which prevents * the BT878 from fetching RISC instructions from memory. While the * CPLD is connected to most of the GPIOs of PCI device 0xD, only * five appear to play a role in unlocking the REQ signal. The following * sequence has been determined by trial and error without access to the * original driver. * * Eight GPIOs of device 0xC are provided on connector CN4 (4 in, 4 out). * Devices 0xE and 0xF do not appear to have anything connected to their * GPIOs. * * The correct GPIO_OUT_EN value might have some more bits set. It should * be possible to derive it from a boundary scan of the CPLD. Its JTAG * pins are routed to test points. *
*/ /* ----------------------------------------------------------------------- */ staticvoid
init_PCI8604PW(struct bttv *btv)
{ int state;
if ((PCI_SLOT(btv->c.pci->devfn) & ~3) != 0xC) {
pr_warn("This is not a PCI-8604PW\n"); return;
}
if (PCI_SLOT(btv->c.pci->devfn) != 0xD) return;
btwrite(0x080002, BT848_GPIO_OUT_EN);
state = (btread(BT848_GPIO_DATA) >> 21) & 7;
for (;;) { switch (state) { case 1: case 5: case 6: case 4:
pr_debug("PCI-8604PW in state %i, toggling pin\n",
state);
btwrite(0x080000, BT848_GPIO_DATA);
msleep(1);
btwrite(0x000000, BT848_GPIO_DATA);
msleep(1); break; case 7:
pr_info("PCI-8604PW unlocked\n"); return; case 0: /* FIXME: If we are in state 7 and toggle GPIO[19] one more time, the CPLD goes into state 0, where PCI bus mastering is inhibited again. We have not managed to
get out of that state. */
pr_err("PCI-8604PW locked until reset\n"); return; default:
pr_err("PCI-8604PW in unknown state %i\n", state); return;
}
switch (state) { case 0x15: case 0x56: case 0x64: case 0x47: /* The transition from state 7 to state 0 is, as explained above, valid but undesired and with this code impossible as we exit as soon as we are in state 7.
case 0x70: */ break; default:
pr_err("PCI-8604PW invalid transition %i -> %i\n",
state >> 4, state & 7); return;
}
state &= 7;
}
}
/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas] * * This is needed because rv605 don't use a normal multiplex, but a crosspoint * switch instead (CD22M3494E). This IC can have multiple active connections * between Xn (input) and Yn (output) pins. We need to clear any existing * connection prior to establish a new one, pulsing the STROBE pin. * * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin. * GPIO pins are wired as: * GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroller) * GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroller) * GPIO[7] - DATA (xpoint) - P1[7] (microcontroller) * GPIO[8] - - P3[5] (microcontroller) * GPIO[9] - RESET (xpoint) - P3[6] (microcontroller) * GPIO[10] - STROBE (xpoint) - P3[7] (microcontroller) * GPINTR - - P3[4] (microcontroller) * * The microcontroller is a 80C32 like. It should be possible to change xpoint * configuration either directly (as we are doing) or using the microcontroller * which is also wired to I2C interface. I have no further info on the * microcontroller features, one would need to disassembly the firmware. * note: the vendor refused to give any information on this product, all * that stuff was found using a multimeter! :)
*/ staticvoid rv605_muxsel(struct bttv *btv, unsignedint input)
{ staticconst u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0,
0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa };
gpio_bits(0x07f, muxgpio[input]);
/* reset all connections */
gpio_bits(0x200,0x200);
mdelay(1);
gpio_bits(0x200,0x000);
mdelay(1);
/* create a new connection */
gpio_bits(0x480,0x480);
mdelay(1);
gpio_bits(0x480,0x080);
mdelay(1);
}
/* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning] * * The CS16 (available on eBay cheap) is a PCI board with four Fusion * 878A chips, a PCI bridge, an Atmel microcontroller, four sync separator * chips, ten eight input analog multiplexors, a not chip and a few * other components. * * 16 inputs on a secondary bracket are provided and can be selected * from each of the four capture chips. Two of the eight input * multiplexors are used to select from any of the 16 input signals. * * Unsupported hardware capabilities: * . A video output monitor on the secondary bracket can be selected from * one of the 878A chips. * . Another passthrough but I haven't spent any time investigating it. * . Digital I/O (logic level connected to GPIO) is available from an * onboard header. * * The on chip input mux should always be set to 2. * GPIO[16:19] - Video input selection * GPIO[0:3] - Video output monitor select (only available from one 878A) * GPIO[?:?] - Digital I/O. * * There is an ATMEL microcontroller with an 8031 core on board. I have not * determined what function (if any) it provides. With the microcontroller * and sync separator chips a guess is that it might have to do with video * switching and maybe some digital I/O.
*/ staticvoid tibetCS16_muxsel(struct bttv *btv, unsignedint input)
{ /* video mux */
gpio_bits(0x0f0000, input << 16);
}
/* * The following routines for the Kodicom-4400r get a little mind-twisting. * There is a "master" controller and three "slave" controllers, together * an analog switch which connects any of 16 cameras to any of the BT87A's. * The analog switch is controlled by the "master", but the detection order * of the four BT878A chips is in an order which I just don't understand. * The "master" is actually the second controller to be detected. The * logic on the board uses logical numbers for the 4 controllers, but * those numbers are different from the detection sequence. When working * with the analog switch, we need to "map" from the detection sequence * over to the board's logical controller number. This mapping sequence * is {3, 0, 2, 1}, i.e. the first controller to be detected is logical * unit 3, the second (which is the master) is logical unit 0, etc. * We need to maintain the status of the analog switch (which of the 16 * cameras is connected to which of the 4 controllers) in sw_status array.
*/
/* * First a routine to set the analog switch, which controls which camera * is routed to which controller. The switch comprises an X-address * (gpio bits 0-3, representing the camera, ranging from 0-15), and a * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3). * A data value (gpio bit 7) of '1' enables the switch, and '0' disables * the switch. A STROBE bit (gpio bit 8) latches the data value into the * specified address. The idea is to set the address and data, then bring * STROBE high, and finally bring STROBE back to low.
*/ staticvoid kodicom4400r_write(struct bttv *btv, unsignedchar xaddr, unsignedchar yaddr, unsignedchar data) { unsignedint udata;
/* * Next the mux select. Both the "master" and "slave" 'cards' (controllers) * use this routine. The routine finds the "master" for the card, maps * the controller number from the detected position over to the logical * number, writes the appropriate data to the analog switch, and housekeeps * the local copy of the switch information. The parameter 'input' is the * requested camera number (0 - 15).
*/ staticvoid kodicom4400r_muxsel(struct bttv *btv, unsignedint input)
{ int xaddr, yaddr; struct bttv *mctlr; staticunsignedchar map[4] = {3, 0, 2, 1};
mctlr = master[btv->c.nr]; if (mctlr == NULL) { /* ignore if master not yet detected */ return;
}
yaddr = (btv->c.nr - mctlr->c.nr + 1) & 3; /* the '&' is for safety */
yaddr = map[yaddr];
xaddr = input & 0xf; /* Check if the controller/camera pair has changed, else ignore */ if (mctlr->sw_status[yaddr] != xaddr)
{ /* "open" the old switch, "close" the new one, save the new */
kodicom4400r_write(mctlr, mctlr->sw_status[yaddr], yaddr, 0);
mctlr->sw_status[yaddr] = xaddr;
kodicom4400r_write(mctlr, xaddr, yaddr, 1);
}
}
/* * During initialisation, we need to reset the analog switch. We * also preset the switch to map the 4 connectors on the card to the * *user's* (see above description of kodicom4400r_muxsel) channels * 0 through 3
*/ staticvoid kodicom4400r_init(struct bttv *btv)
{ int ix;
gpio_inout(0x0003ff, 0x0003ff);
gpio_write(1 << 9); /* reset MUX */
gpio_write(0); /* Preset camera 0 to the 4 controllers */ for (ix = 0; ix < 4; ix++) {
btv->sw_status[ix] = ix;
kodicom4400r_write(btv, ix, ix, 1);
} /* * Since this is the "master", we need to set up the * other three controller chips' pointers to this structure * for later use in the muxsel routine.
*/ if ((btv->c.nr<1) || (btv->c.nr>BTTV_MAX-3)) return;
master[btv->c.nr-1] = btv;
master[btv->c.nr] = btv;
master[btv->c.nr+1] = btv;
master[btv->c.nr+2] = btv;
}
/* The Grandtec X-Guard framegrabber card uses two Dual 4-channel * video multiplexers to provide up to 16 video inputs. These * multiplexers are controlled by the lower 8 GPIO pins of the * bt878. The multiplexers probably Pericom PI5V331Q or similar.
* xxx0 is pin xxx of multiplexer U5, * yyy1 is pin yyy of multiplexer U2
*/ #define ENA0 0x01 #define ENB0 0x02 #define ENA1 0x04 #define ENB1 0x08
staticvoid xguard_muxsel(struct bttv *btv, unsignedint input)
{ staticconstint masks[] = {
ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
};
gpio_write(masks[input%16]);
} staticvoid picolo_tetra_init(struct bttv *btv)
{ /*This is the video input redirection functionality : I DID NOT USE IT. */
btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */
btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A] set to 1*/
} staticvoid picolo_tetra_muxsel (struct bttv* btv, unsignedint input)
{
dprintk("%d : picolo_tetra_muxsel => input = %d\n", btv->c.nr, input); /*Just set the right path in the analog multiplexers : channel 1 -> 4 ==> Analog Mux ==> MUX0*/ /*GPIO[20]&GPIO[21] used to choose the right input*/
btwrite (input<<20,BT848_GPIO_DATA);
}
/* * ivc120_muxsel [Added by Alan Garfield <alan@fromorbit.com>] * * The IVC120G security card has 4 i2c controlled TDA8540 matrix * switchers to provide 16 channels to MUX0. The TDA8540's have * 4 independent outputs and as such the IVC120G also has the * optional "Monitor Out" bus. This allows the card to be looking * at one input while the monitor is looking at another. * * Since I've couldn't be bothered figuring out how to add an * independent muxsel for the monitor bus, I've just set it to * whatever the card is looking at. * * OUT0 of the TDA8540's is connected to MUX0 (0x03) * OUT1 of the TDA8540's is connected to "Monitor Out" (0x0C) * * TDA8540_ALT3 IN0-3 = Channel 13 - 16 (0x03) * TDA8540_ALT4 IN0-3 = Channel 1 - 4 (0x03) * TDA8540_ALT5 IN0-3 = Channel 5 - 8 (0x03) * TDA8540_ALT6 IN0-3 = Channel 9 - 12 (0x03) *
*/
/* All 7 possible sub-ids for the TDA8540 Matrix Switcher */ #define I2C_TDA8540 0x90 #define I2C_TDA8540_ALT1 0x92 #define I2C_TDA8540_ALT2 0x94 #define I2C_TDA8540_ALT3 0x96 #define I2C_TDA8540_ALT4 0x98 #define I2C_TDA8540_ALT5 0x9a #define I2C_TDA8540_ALT6 0x9c
/* 878's MUX0 is already selected for input via muxsel values */
}
/* PXC200 muxsel helper * luke@syseng.anu.edu.au * another transplant * from Alessandro Rubini (rubini@linux.it) * * There are 4 kinds of cards: * PXC200L which is bt848 * PXC200F which is bt848 with PIC controlling mux * PXC200AL which is bt878 * PXC200AF which is bt878 with PIC controlling mux
*/ #define PX_CFG_PXC200F 0x01 #define PX_FLAG_PXC200A 0x00001000 /* a pxc200A is bt-878 based */ #define PX_I2C_PIC 0x0f #define PX_PXC200A_CARDID 0x200a1295 #define PX_I2C_CMD_CFG 0x00
staticvoid PXC200_muxsel(struct bttv *btv, unsignedint input)
{ int rc; long mux; int bitmask; unsignedchar buf[2];
/* Read PIC config to determine if this is a PXC200F */ /* PX_I2C_CMD_CFG*/
buf[0]=0;
buf[1]=0;
rc=bttv_I2CWrite(btv,(PX_I2C_PIC<<1),buf[0],buf[1],1); if (rc) {
pr_debug("%d: PXC200_muxsel: pic cfg write failed:%d\n",
btv->c.nr, rc); /* not PXC ? do nothing */ return;
}
rc=bttv_I2CRead(btv,(PX_I2C_PIC<<1),NULL); if (!(rc & PX_CFG_PXC200F)) {
pr_debug("%d: PXC200_muxsel: not PXC200F rc:%d\n",
btv->c.nr, rc); return;
}
/* The multiplexer in the 200F is handled by the GPIO port */ /* get correct mapping between inputs */ /* mux = bttv_tvcards[btv->type].muxsel[input] & 3; */ /* ** not needed!? */
mux = input;
/* make sure output pins are enabled */ /* bitmask=0x30f; */
bitmask=0x302; /* check whether we have a PXC200A */ if (btv->cardid == PX_PXC200A_CARDID) {
bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
bitmask |= 7<<4; /* the DAC */
}
btwrite(bitmask, BT848_GPIO_OUT_EN);
/* * Was "to be safe, set the bt848 to input 0" * Actually, since it's ok at load time, better not messing * with these bits (on PXC200AF you need to set mux 2 here) * * needed because bttv-driver sets mux before calling this function
*/ if (btv->cardid == PX_PXC200A_CARDID)
btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); else/* older device */
btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
/* * GeoVision GV-800(S) functions * Bruno Christo <bchristo@inf.ufsm.br>
*/
/* This is a function to control the analog switch, which determines which * camera is routed to which controller. The switch comprises an X-address * (gpio bits 0-3, representing the camera, ranging from 0-15), and a * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3). * A data value (gpio bit 18) of '1' enables the switch, and '0' disables * the switch. A STROBE bit (gpio bit 17) latches the data value into the * specified address. There is also a chip select (gpio bit 16). * The idea is to set the address and chip select together, bring * STROBE high, write the data, and finally bring STROBE back to low.
*/ staticvoid gv800s_write(struct bttv *btv, unsignedchar xaddr, unsignedchar yaddr, unsignedchar data) { /* On the "master" 878A: * GPIO bits 0-9 are used for the analog switch: * 00 - 03: camera selector * 04 - 06: 878A (controller) selector * 16: cselect * 17: strobe * 18: data (1->on, 0->off) * 19: reset
*/ const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4); const u32 CSELECT = 1<<16; const u32 STROBE = 1<<17; const u32 DATA = data<<18;
gpio_bits(0x1007f, ADDRESS | CSELECT); /* write ADDRESS and CSELECT */
gpio_bits(0x20000, STROBE); /* STROBE high */
gpio_bits(0x40000, DATA); /* write DATA */
gpio_bits(0x20000, ~STROBE); /* STROBE low */
}
/* * GeoVision GV-800(S) muxsel * * Each of the 4 cards (controllers) use this function. * The controller using this function selects the input through the GPIO pins * of the "master" card. A pointer to this card is stored in master[btv->c.nr]. * * The parameter 'input' is the requested camera number (0-4) on the controller. * The map array has the address of each input. Note that the addresses in the * array are in the sequence the original GeoVision driver uses, that is, set * every controller to input 0, then to input 1, 2, 3, repeat. This means that * the physical "camera 1" connector corresponds to controller 0 input 0, * "camera 2" corresponds to controller 1 input 0, and so on. * * After getting the input address, the function then writes the appropriate * data to the analog switch, and housekeeps the local copy of the switch * information.
*/ staticvoid gv800s_muxsel(struct bttv *btv, unsignedint input)
{ struct bttv *mctlr; int xaddr, yaddr; staticunsignedint map[4][4] = { { 0x0, 0x4, 0xa, 0x6 },
{ 0x1, 0x5, 0xb, 0x7 },
{ 0x2, 0x8, 0xc, 0xe },
{ 0x3, 0x9, 0xd, 0xf } };
input = input%4;
mctlr = master[btv->c.nr]; if (mctlr == NULL) { /* do nothing until the "master" is detected */ return;
}
yaddr = (btv->c.nr - mctlr->c.nr) & 3;
xaddr = map[yaddr][input] & 0xf;
/* Check if the controller/camera pair has changed, ignore otherwise */ if (mctlr->sw_status[yaddr] != xaddr) { /* disable the old switch, enable the new one and save status */
gv800s_write(mctlr, mctlr->sw_status[yaddr], yaddr, 0);
mctlr->sw_status[yaddr] = xaddr;
gv800s_write(mctlr, xaddr, yaddr, 1);
}
}
gpio_inout(0xf107f, 0xf107f);
gpio_write(1<<19); /* reset the analog MUX */
gpio_write(0);
/* Preset camera 0 to the 4 controllers */ for (ix = 0; ix < 4; ix++) {
btv->sw_status[ix] = ix;
gv800s_write(btv, ix, ix, 1);
}
/* Inputs on the "master" controller need this brightness fix */
bttv_I2CWrite(btv, 0x18, 0x5, 0x90, 1);
if (btv->c.nr > BTTV_MAX-4) return; /* * Store the "master" controller pointer in the master * array for later use in the muxsel function.
*/
master[btv->c.nr] = btv;
master[btv->c.nr+1] = btv;
master[btv->c.nr+2] = btv;
master[btv->c.nr+3] = btv;
}
/* ----------------------------------------------------------------------- */ /* motherboard chipset specific stuff */
if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
triton1 = 1; if (pci_pci_problems & PCIPCI_VSFX)
vsfx = 1; #ifdef PCIPCI_ALIMAGIK if (pci_pci_problems & PCIPCI_ALIMAGIK)
latency = 0x0A; #endif
/* print warnings about any quirks found */ if (triton1)
pr_info("Host bridge needs ETBF enabled\n"); if (vsfx)
pr_info("Host bridge needs VSFX enabled\n"); if (UNSET != latency)
pr_info("pci latency fixup [%d]\n", latency); while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82441, dev))) { unsignedchar b;
pci_read_config_byte(dev, 0x53, &b); if (bttv_debug)
pr_info("Host bridge: 82441FX Natoma, bufcon=0x%02x\n",
b);
}
}
int bttv_handle_chipset(struct bttv *btv)
{ unsignedchar command;
if (!triton1 && !vsfx && UNSET == latency) return 0;
if (bttv_verbose) { if (triton1)
pr_info("%d: enabling ETBF (430FX/VP3 compatibility)\n",
btv->c.nr); if (vsfx && btv->id >= 878)
pr_info("%d: enabling VSFX\n", btv->c.nr); if (UNSET != latency)
pr_info("%d: setting pci timer to %d\n",
btv->c.nr, latency);
}
if (btv->id < 878) { /* bt848 (mis)uses a bit in the irq mask for etbf */ if (triton1)
btv->triton1 = BT848_INT_ETBF;
} else { /* bt878 has a bit in the pci config space for it */
pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command); if (triton1)
command |= BT878_EN_TBFX; if (vsfx)
command |= BT878_EN_VSFX;
pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
} if (UNSET != latency)
pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); return 0;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.78 Sekunden
(vorverarbeitet am 2026-04-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.