/* ---- 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 */
static void 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 {
unsigned short 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.
*/
/* ----------------------------------------------------------------------- */
static void
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.
*
*/
/* ----------------------------------------------------------------------- */
static void
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! :)
*/
static void rv605_muxsel(struct bttv *btv, unsigned int input)
{
static const 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.
*/
static void tibetCS16_muxsel(struct bttv *btv, unsigned int 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.
*/
static void kodicom4400r_write(struct bttv *btv,
unsigned char xaddr,
unsigned char yaddr,
unsigned char data) {
unsigned int 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).
*/
static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input)
{
int xaddr, yaddr;
struct bttv *mctlr;
static unsigned char 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
*/
static void 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
static void xguard_muxsel(struct bttv *btv, unsigned int input)
{
static const int 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]);
}
static void 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*/
}
static void picolo_tetra_muxsel (struct bttv* btv, unsigned int 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
static void ivc120_muxsel(struct bttv *btv, unsigned int input)
{
/* Simple maths */
int key = input % 4;
int matrix = input / 4;
/* 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
static void PXC200_muxsel(struct bttv *btv, unsigned int input)
{
int rc;
long mux;
int bitmask;
unsigned char 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);
static void phytec_muxsel(struct bttv *btv, unsigned int input)
{
unsigned int mux = input % 4;
if (input == btv->svhs)
mux = 0;
gpio_bits(0x3, mux);
}
/*
* 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.
*/
static void gv800s_write(struct bttv *btv,
unsigned char xaddr,
unsigned char yaddr,
unsigned char 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.
*/
static void gv800s_muxsel(struct bttv *btv, unsigned int input)
{
struct bttv *mctlr;
int xaddr, yaddr;
static unsigned int 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))) {
unsigned char 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)
{
unsigned char 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
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.90Angebot
¤
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.