X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fbttv-cards.c;h=4ee9026fc36b883e47a6645e1d5c01d9202d4236;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=a5a24309cb25039d8b045d5615525b286445820b;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index a5a24309c..4ee9026fc 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c @@ -1,4 +1,6 @@ /* + $Id: bttv-cards.c,v 1.42 2005/01/13 17:22:33 kraxel Exp $ + bttv-cards.c this file has configuration informations - card-specific stuff @@ -27,18 +29,19 @@ #include #include #include +#include #include #include #include #include -#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) -# include -#endif +#include #include #include "bttvp.h" +#if 0 /* not working yet */ #include "bt832.h" +#endif /* fwd decl */ static void boot_msp34xx(struct bttv *btv, int pin); @@ -74,6 +77,9 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input); static void picolo_tetra_muxsel(struct bttv *btv, unsigned int input); static void picolo_tetra_init(struct bttv *btv); +static void tibetCS16_muxsel(struct bttv *btv, unsigned int input); +static void tibetCS16_init(struct bttv *btv); + static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input); static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input); @@ -82,12 +88,13 @@ static int tea5757_read(struct bttv *btv); static int tea5757_write(struct bttv *btv, int value); static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256]); +static int __devinit pvr_boot(struct bttv *btv); /* config variables */ static unsigned int triton1=0; static unsigned int vsfx=0; static unsigned int latency = UNSET; -unsigned int no_overlay=-1; +static unsigned int no_overlay=-1; static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; @@ -104,53 +111,31 @@ static unsigned int audioall = UNSET; static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET }; /* insmod options */ -MODULE_PARM(triton1,"i"); +module_param(triton1, int, 0444); +module_param(vsfx, int, 0444); +module_param(no_overlay, int, 0444); +module_param(latency, int, 0444); +module_param(gpiomask, int, 0444); +module_param(audioall, int, 0444); +module_param(autoload, int, 0444); + +module_param_array(card, int, NULL, 0444); +module_param_array(pll, int, NULL, 0444); +module_param_array(tuner, int, NULL, 0444); +module_param_array(svhs, int, NULL, 0444); +module_param_array(remote, int, NULL, 0444); +module_param_array(audiomux, int, NULL, 0444); + MODULE_PARM_DESC(triton1,"set ETBF pci config bit " "[enable bug compatibility for triton1 + others]"); -MODULE_PARM(vsfx,"i"); MODULE_PARM_DESC(vsfx,"set VSFX pci config bit " "[yet another chipset flaw workaround]"); -MODULE_PARM(no_overlay,"i"); -MODULE_PARM(latency,"i"); MODULE_PARM_DESC(latency,"pci latency timer"); -MODULE_PARM(card,"1-" __stringify(BTTV_MAX) "i"); MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list"); -MODULE_PARM(pll,"1-" __stringify(BTTV_MAX) "i"); MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)"); -MODULE_PARM(tuner,"1-" __stringify(BTTV_MAX) "i"); MODULE_PARM_DESC(tuner,"specify installed tuner type"); -MODULE_PARM(autoload,"i"); MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)"); -MODULE_PARM(svhs,"1-" __stringify(BTTV_MAX) "i"); -MODULE_PARM(remote,"1-" __stringify(BTTV_MAX) "i"); - -MODULE_PARM(gpiomask,"i"); -MODULE_PARM(audioall,"i"); -MODULE_PARM(audiomux,"1-6i"); - -/* kernel args */ -#ifndef MODULE -static int __init p_card(char *str) { return bttv_parse(str,BTTV_MAX,card); } -static int __init p_pll(char *str) { return bttv_parse(str,BTTV_MAX,pll); } -static int __init p_tuner(char *str) { return bttv_parse(str,BTTV_MAX,tuner); } -__setup("bttv.card=", p_card); -__setup("bttv.pll=", p_pll); -__setup("bttv.tuner=", p_tuner); - -int __init bttv_parse(char *str, int max, int *vals) -{ - int i,number,res = 2; - - for (i = 0; res == 2 && i < max; i++) { - res = get_option(&str,&number); - if (res) - vals[i] = number; - } - return 1; -} -#endif - /* ----------------------------------------------------------------------- */ /* list of card IDs for bt878+ cards */ @@ -182,7 +167,6 @@ static struct CARD { { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, - { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, // some cards ship with byteswapped IDs ... { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, @@ -190,8 +174,9 @@ static struct CARD { { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" }, - + { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, + { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" }, { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" }, @@ -208,7 +193,7 @@ static struct CARD { { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" }, - + { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" }, { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" }, // clashes with FlyVideo @@ -244,7 +229,7 @@ static struct CARD { { 0xa1550000, BTTV_IVC200, "IVC-200" }, { 0xa1550001, BTTV_IVC200, "IVC-200" }, { 0xa1550002, BTTV_IVC200, "IVC-200" }, - { 0xa1550003, BTTV_IVC200, "IVC-200" }, + { 0xa1550003, BTTV_IVC200, "IVC-200" }, { 0xa1550100, BTTV_IVC200, "IVC-200G" }, { 0xa1550101, BTTV_IVC200, "IVC-200G" }, { 0xa1550102, BTTV_IVC200, "IVC-200G" }, @@ -265,10 +250,10 @@ static struct CARD { { 0xa182ff0d, BTTV_IVC120, "IVC-120G" }, { 0xa182ff0e, BTTV_IVC120, "IVC-120G" }, { 0xa182ff0f, BTTV_IVC120, "IVC-120G" }, - + { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" }, { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" }, - + { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, @@ -300,15 +285,17 @@ static struct CARD { // likely broken, vendor id doesn't match the other magic views ... //{ 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, - + // DVB cards (using pci function .1 for mpeg data xfer) { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, - { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T" }, + { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, + { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB-T" }, { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, - { 0x07711461, BTTV_AVDVBT_771, "AVermedia DVB-T 771" }, - + { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, + { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DVICO FusionHDTV DVB-T Lite" }, + { 0, -1, NULL } }; @@ -699,7 +686,7 @@ struct tvcard bttv_tvcards[] = { 10000 : ext. Video audio input 20000 : TV Mono a0000 : TV Mono/2 - 1a0000 : TV Stereo + 1a0000 : TV Stereo 30000 : Radio 40000 : Mute */ @@ -1114,7 +1101,7 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .tuner_type = 5, },{ - /* This is the ultimate cheapo capture card + /* This is the ultimate cheapo capture card * just a BT848A on a small PCB! * Steve Hosgood */ .name = "GrandTec 'Grand Video Capture' (Bt848)", @@ -1185,7 +1172,7 @@ struct tvcard bttv_tvcards[] = { .tuner_type = -1, },{ /* Miguel Angel Alvarez - new Easy TV BT878 version (model CPH061) + new Easy TV BT878 version (model CPH061) special thanks to Informatica Mieres for providing the card */ .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", .video_inputs = 3, @@ -1389,7 +1376,7 @@ struct tvcard bttv_tvcards[] = { },{ .name = "Powercolor MTV878/ MTV878R/ MTV878F", .video_inputs = 3, - .audio_inputs = 2, + .audio_inputs = 2, .tuner = 0, .svhs = 2, .gpiomask = 0x1C800F, // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset @@ -1567,7 +1554,7 @@ struct tvcard bttv_tvcards[] = { .no_tda9875 = 1, .no_tda7432 = 1, },{ - + /* ---- card 0x58 ---------------------------------- */ .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ .video_inputs = 2, @@ -1660,13 +1647,14 @@ struct tvcard bttv_tvcards[] = { .tuner_type = -1, .no_msp34xx = 1, .no_tda9875 = 1, - .no_tda7432 = 1, + .no_tda7432 = 1, .gpiomask = 0x01, .audiomux = { 0, 0, 0, 0, 1 }, .muxsel = { 3, 0, 1, 2}, - .needs_tvaudio = 0, + .needs_tvaudio = 0, .pll = PLL_28, .no_gpioirq = 1, + .has_dvb = 1, },{ .name = "Formac ProTV II (bt878)", .video_inputs = 4, @@ -1676,7 +1664,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 2, // TV, Comp1, Composite over SVID con, SVID .muxsel = { 2, 3, 1, 1}, - .audiomux = { 2, 2, 0, 0, 0 }, + .audiomux = { 2, 2, 0, 0, 0 }, .pll = PLL_28, .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, @@ -1761,7 +1749,7 @@ struct tvcard bttv_tvcards[] = { /* Notes: - card lacks subsystem ID - stereo variant w/ daughter board with tda9874a @0xb0 - - Audio Routing: + - Audio Routing: always from tda9874 independent of GPIO (?) external line in: unknown - Other chips: em78p156elp @ 0x96 (probably IR remote control) @@ -1845,7 +1833,7 @@ struct tvcard bttv_tvcards[] = { .audio_inputs = 0, .tuner = -1, /* card has no tuner */ .svhs = 3, - .gpiomask = 0x00, + .gpiomask = 0x00, .muxsel = { 2, 3, 1, 0}, .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ .needs_tvaudio = 1, @@ -1918,7 +1906,7 @@ struct tvcard bttv_tvcards[] = { .no_tda9875 = 1, .no_tda7432 = 1, .gpiomask = 0x00, - .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, .muxsel_hook = ivc120_muxsel, .pll = PLL_28, @@ -2081,18 +2069,16 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .has_dvb = 1, .no_gpioirq = 1, -#if 0 /* untested */ .has_remote = 1, -#endif },{ /* ---- card 0x7c ---------------------------------- */ /* Matt Jesson */ /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */ .name = "AverMedia AverTV DVB-T 761", - .video_inputs = 1, + .video_inputs = 2, .tuner = -1, - .svhs = -1, - .muxsel = { 2, 3, 1, 0}, + .svhs = 1, + .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */ .no_msp34xx = 1, .no_tda9875 = 1, .no_tda7432 = 1, @@ -2147,9 +2133,64 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_PHILIPS_PAL, .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ .has_radio = 1, /* not every card has radio */ +},{ + + /* ---- card 0x80 ---------------------------------- */ + /* Chris Pascoe */ + .name = "DVICO FusionHDTV DVB-T Lite", + .tuner = -1, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .pll = PLL_28, + .no_video = 1, + .has_dvb = 1, + .tuner_type = -1, +},{ + /* Steven */ + .name = "V-Gear MyVCD", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 0x3f, + .muxsel = {2, 3, 1, 0}, + .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31}, + .no_msp34xx = 1, + .pll = PLL_28, + .tuner_type = TUNER_PHILIPS_NTSC_M, + .has_radio = 0, + // .has_remote = 1, +},{ + /* Rick C */ + .name = "Super TV Tuner", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .muxsel = { 2, 3, 1, 0}, + .tuner_type = TUNER_PHILIPS_NTSC, + .gpiomask = 0x008007, + .audiomux = { 0, 0x000001,0,0, 0}, + .needs_tvaudio = 1, + .has_radio = 1, +},{ + /* Chris Fanning */ + .name = "Tibet Systems 'Progress DVR' CS16", + .video_inputs = 16, + .audio_inputs = 0, + .tuner = -1, + .svhs = -1, + .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + .pll = PLL_28, + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .tuner_type = -1, + .muxsel_hook = tibetCS16_muxsel, }}; -const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); +static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); /* ----------------------------------------------------------------------- */ @@ -2175,7 +2216,7 @@ void __devinit bttv_idcard(struct bttv *btv) for (type = -1, i = 0; cards[i].id != 0; i++) if (cards[i].id == btv->cardid) type = i; - + if (type != -1) { /* found it */ printk(KERN_INFO "bttv%d: detected: %s [card=%d], " @@ -2192,12 +2233,12 @@ void __devinit bttv_idcard(struct bttv *btv) printk(KERN_DEBUG "please mail id, board name and " "the correct card= insmod option to kraxel@bytesex.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 */ printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type, @@ -2237,7 +2278,7 @@ void __devinit bttv_idcard(struct bttv *btv) void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256]) { int type = -1; - + if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) type = BTTV_MODTEC_205; else if (0 == strncmp(eeprom_data+20,"Picolo",7)) @@ -2253,7 +2294,7 @@ void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256]) } static void flyvideo_gpio(struct bttv *btv) -{ +{ int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821; int tuner=-1,ttype; @@ -2267,10 +2308,10 @@ static void flyvideo_gpio(struct bttv *btv) // 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 + // xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered // Note: Some bits are Audio_Mask ! ttype=(gpio&0x0f0000)>>16; @@ -2298,18 +2339,18 @@ static void flyvideo_gpio(struct bttv *btv) is_lr90 = !(gpio & 0x002000); // else LR26/LR50 (LR38/LR51 f. capture only) // gpio & 0x001000 // output bit for audio routing - if(is_capture_only) - tuner=4; // No tuner present + if(is_capture_only) + tuner=4; // No tuner present - printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", - btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio); + printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", + btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio); printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n", - btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ", + btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ", is_capture_only?"yes":"no "); if(tuner!= -1) // only set if known tuner autodetected, else let insmod option through btv->tuner_type = tuner; - btv->has_radio = has_radio; + 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 @@ -2318,10 +2359,10 @@ static void flyvideo_gpio(struct bttv *btv) //todo: if(has_tda9874) btv->audio_hook = fv2000s_audio; } -int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1, - 14,2,17,1, 4,1,4,3, 1,2,16,1, 4,4,4,4 }; -int miro_fmtuner[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, - 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,1,0,0 }; +static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1, + 14,2,17,1, 4,1,4,3, 1,2,16,1, 4,4,4,4 }; +static int miro_fmtuner[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, + 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,1,0,0 }; static void miro_pinnacle_gpio(struct bttv *btv) { @@ -2408,13 +2449,13 @@ static void init_ids_eagle(struct bttv *btv) { gpio_inout(0xffffff,0xFFFF37); gpio_write(0x200020); - + /* flash strobe inverter ?! */ gpio_write(0x200024); - + /* switch sync drive off */ gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE); - + /* set BT848 muxel to 2 */ btaor((2)<<5, ~(2<<5), BT848_IFORM); } @@ -2490,7 +2531,7 @@ static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input) /* ----------------------------------------------------------------------- */ -void bttv_reset_audio(struct bttv *btv) +static void bttv_reset_audio(struct bttv *btv) { /* * BT878A has a audio-reset register. @@ -2503,7 +2544,7 @@ void bttv_reset_audio(struct bttv *btv) */ if (btv->id != 878) return; - + if (bttv_debug) printk("bttv%d: BT878A ARESET\n",btv->c.nr); btwrite((1<<7), 0x058); @@ -2533,11 +2574,14 @@ void __devinit bttv_init_card1(struct bttv *btv) btv->use_i2c_hw = 1; break; } + if (!bttv_tvcards[btv->c.type].has_dvb) + bttv_reset_audio(btv); } /* initialization part two -- after registering i2c bus */ void __devinit bttv_init_card2(struct bttv *btv) { + int tda9887; btv->tuner_type = -1; if (BTTV_UNKNOWN == btv->c.type) { @@ -2549,7 +2593,7 @@ void __devinit bttv_init_card2(struct bttv *btv) case BTTV_MIRO: case BTTV_MIROPRO: case BTTV_PINNACLE: - case BTTV_PINNACLEPRO: + case BTTV_PINNACLEPRO: /* miro/pinnacle */ miro_pinnacle_gpio(btv); break; @@ -2635,6 +2679,9 @@ void __devinit bttv_init_card2(struct bttv *btv) case BTTV_LMLBT4: init_lmlbt4x(btv); break; + case BTTV_TIBET_CS16: + tibetCS16_init(btv); + break; } /* pll configuration */ @@ -2671,9 +2718,11 @@ void __devinit bttv_init_card2(struct bttv *btv) } btv->pll.pll_current = -1; + bttv_reset_audio(btv); + /* tuner configuration (from card list / autodetect / insmod option) */ if (UNSET != bttv_tvcards[btv->c.type].tuner_type) - if(UNSET == btv->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]; @@ -2705,110 +2754,47 @@ void __devinit bttv_init_card2(struct bttv *btv) boot_bt832(btv); } + if (!autoload) + return; + /* try to detect audio/fader chips */ if (!bttv_tvcards[btv->c.type].no_msp34xx && - bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) { - if (autoload) - request_module("msp3400"); - } + bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) + request_module("msp3400"); if (bttv_tvcards[btv->c.type].msp34xx_alt && - bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0) { - if (autoload) - request_module("msp3400"); - } + bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0) + request_module("msp3400"); if (!bttv_tvcards[btv->c.type].no_tda9875 && - bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) { - if (autoload) - request_module("tda9875"); - } + bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) + request_module("tda9875"); - if (!bttv_tvcards[btv->c.type].no_tda7432 && - bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) { - if (autoload) - request_module("tda7432"); - } + if (!bttv_tvcards[btv->c.type].no_tda7432 && + bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) + request_module("tda7432"); - if (bttv_tvcards[btv->c.type].needs_tvaudio) { - if (autoload) - request_module("tvaudio"); - } + if (bttv_tvcards[btv->c.type].needs_tvaudio) + request_module("tvaudio"); /* tuner modules */ - if (btv->pinnacle_id != UNSET) { - if (autoload) - request_module("tda9887"); - } - if (btv->tuner_type != UNSET) { - if (autoload) - request_module("tuner"); - } + tda9887 = 0; + if (btv->pinnacle_id != UNSET) + tda9887 = 1; + if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && + bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) + tda9887 = 1; + if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) || + (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) || + (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) || + tda9887) + request_module("tda9887"); + if (btv->tuner_type != UNSET) + request_module("tuner"); } /* ----------------------------------------------------------------------- */ -/* some hauppauge specific stuff */ - -static struct HAUPPAUGE_TUNER -{ - int id; - char *name; -} -hauppauge_tuner[] __devinitdata = -{ - { TUNER_ABSENT, "" }, - { TUNER_ABSENT, "External" }, - { TUNER_ABSENT, "Unspecified" }, - { TUNER_PHILIPS_PAL, "Philips FI1216" }, - { TUNER_PHILIPS_SECAM, "Philips FI1216MF" }, - { TUNER_PHILIPS_NTSC, "Philips FI1236" }, - { TUNER_PHILIPS_PAL_I, "Philips FI1246" }, - { TUNER_PHILIPS_PAL_DK,"Philips FI1256" }, - { TUNER_PHILIPS_PAL, "Philips FI1216 MK2" }, - { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" }, - { TUNER_PHILIPS_NTSC, "Philips FI1236 MK2" }, - { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" }, - { TUNER_PHILIPS_PAL_DK,"Philips FI1256 MK2" }, - { TUNER_TEMIC_NTSC, "Temic 4032FY5" }, - { TUNER_TEMIC_PAL, "Temic 4002FH5" }, - { TUNER_TEMIC_PAL_I, "Temic 4062FY5" }, - { TUNER_PHILIPS_PAL, "Philips FR1216 MK2" }, - { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" }, - { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" }, - { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" }, - { TUNER_PHILIPS_PAL_DK,"Philips FR1256 MK2" }, - { TUNER_PHILIPS_PAL, "Philips FM1216" }, - { TUNER_PHILIPS_SECAM, "Philips FM1216MF" }, - { TUNER_PHILIPS_NTSC, "Philips FM1236" }, - { TUNER_PHILIPS_PAL_I, "Philips FM1246" }, - { TUNER_PHILIPS_PAL_DK,"Philips FM1256" }, - { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" }, - { TUNER_ABSENT, "Samsung TCPN9082D" }, - { TUNER_ABSENT, "Samsung TCPM9092P" }, - { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" }, - { TUNER_ABSENT, "Samsung TCPN9085D" }, - { TUNER_ABSENT, "Samsung TCPB9085P" }, - { TUNER_ABSENT, "Samsung TCPL9091P" }, - { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, - { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, - { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, - { TUNER_PHILIPS_NTSC, "Philips TD1536" }, - { TUNER_PHILIPS_NTSC, "Philips TD1536D" }, - { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ - { TUNER_ABSENT, "Philips FI1256MP" }, - { TUNER_ABSENT, "Samsung TCPQ9091P" }, - { TUNER_TEMIC_4006FN5_MULTI_PAL, "Temic 4006FN5" }, - { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" }, - { TUNER_TEMIC_4046FM5, "Temic 4046FM5" }, - { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" }, - { TUNER_ABSENT, "Philips TD1536D_FH_44"}, - { TUNER_LG_NTSC_FM, "LG TPI8NSR01F"}, - { TUNER_LG_PAL_FM, "LG TPI8PSB01D"}, - { TUNER_LG_PAL, "LG TPI8PSB11D"}, - { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"}, - { TUNER_LG_PAL_I, "LG TAPC-I701D"} -}; static void modtec_eeprom(struct bttv *btv) { @@ -2832,30 +2818,11 @@ static void modtec_eeprom(struct bttv *btv) static void __devinit hauppauge_eeprom(struct bttv *btv) { - unsigned int blk2,tuner,radio,model; - - if (eeprom_data[0] != 0x84 || eeprom_data[2] != 0) - printk(KERN_WARNING "bttv%d: Hauppauge eeprom: invalid\n", - btv->c.nr); + struct tveeprom tv; - /* Block 2 starts after len+3 bytes header */ - blk2 = eeprom_data[1] + 3; - - /* decode + use some config infos */ - model = eeprom_data[12] << 8 | eeprom_data[11]; - tuner = eeprom_data[9]; - radio = eeprom_data[blk2-1] & 0x01; - - if (tuner < ARRAY_SIZE(hauppauge_tuner)) - btv->tuner_type = hauppauge_tuner[tuner].id; - if (radio) - btv->has_radio = 1; - - if (bttv_verbose) - printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, " - "tuner=%s (%d), radio=%s\n", - btv->c.nr, model, hauppauge_tuner[tuner].name, - btv->tuner_type, radio ? "yes" : "no"); + tveeprom_hauppauge_analog(&tv, eeprom_data); + btv->tuner_type = tv.tuner_type; + btv->has_radio = tv.has_radio; } static int terratec_active_radio_upgrade(struct bttv *btv) @@ -2886,7 +2853,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv) btv->has_matchbox = 0; } return 0; -} +} /* ----------------------------------------------------------------------- */ @@ -2913,7 +2880,7 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); gpio_write(0); udelay(PVR_GPIO_DELAY); - + gpio_write(BTTV_ALT_NCONFIG); udelay(PVR_GPIO_DELAY); @@ -2923,7 +2890,7 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) gpio_bits(BTTV_ALT_DCLK,0); if (bits & 0x01) gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA); - else + else gpio_bits(BTTV_ALT_DATA,0); gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK); bits >>= 1; @@ -2931,7 +2898,7 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) } gpio_bits(BTTV_ALT_DCLK,0); udelay(PVR_GPIO_DELAY); - + /* begin Altera init loop (Not necessary,but doesn't hurt) */ for (i = 0 ; i < 30 ; i++) { gpio_bits(BTTV_ALT_DCLK,0); @@ -2941,41 +2908,7 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) return 0; } -#if !defined(CONFIG_FW_LOADER) && !defined(CONFIG_FW_LOADER_MODULE) -/* old 2.4.x way -- via soundcore's mod_firmware_load */ - -static char *firm_altera = "/usr/lib/video4linux/hcwamc.rbf"; -MODULE_PARM(firm_altera,"s"); -MODULE_PARM_DESC(firm_altera,"WinTV/PVR firmware " - "(driver CD => unzip pvr45xxx.exe => hcwamc.rbf)"); - -extern int mod_firmware_load(const char *fn, char **fp); - -int __devinit pvr_boot(struct bttv *btv) -{ - u32 microlen; - u8 *micro; - int result; - - microlen = mod_firmware_load(firm_altera, (char**) µ); - if (!microlen) { - printk(KERN_WARNING "bttv%d: altera firmware not found [%s]\n", - btv->c.nr, firm_altera); - return -1; - } - - printk(KERN_INFO "bttv%d: uploading altera firmware [%s] ...\n", - btv->c.nr, firm_altera); - result = pvr_altera_load(btv, micro, microlen); - printk(KERN_INFO "bttv%d: ... upload %s\n", - btv->c.nr, (result < 0) ? "failed" : "ok"); - vfree(micro); - return result; -} -#else -/* new 2.5.x way -- via hotplug firmware loader */ - -int __devinit pvr_boot(struct bttv *btv) +static int __devinit pvr_boot(struct bttv *btv) { const struct firmware *fw_entry; int rc; @@ -2991,8 +2924,7 @@ int __devinit pvr_boot(struct bttv *btv) btv->c.nr, (rc < 0) ? "failed" : "ok"); release_firmware(fw_entry); return rc; -} -#endif +} /* ----------------------------------------------------------------------- */ /* some osprey specific stuff */ @@ -3002,7 +2934,7 @@ static void __devinit osprey_eeprom(struct bttv *btv) int i = 0; unsigned char *ee = eeprom_data; unsigned long serial = 0; - + if (btv->c.type == 0) { /* this might be an antique... check for MMAC label in eeprom */ if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { @@ -3018,7 +2950,7 @@ static void __devinit osprey_eeprom(struct bttv *btv) } else { unsigned short type; int offset = 4*16; - + for(; offset < 8*16; offset += 16) { unsigned short checksum = 0; /* verify the checksum */ @@ -3029,13 +2961,13 @@ static void __devinit osprey_eeprom(struct bttv *btv) break; } } - + if (offset >= 8*16) return; /* found a valid descriptor */ type = (ee[offset+4]<<8) | (ee[offset+5]); - + switch(type) { /* 848 based */ @@ -3045,7 +2977,7 @@ static void __devinit osprey_eeprom(struct bttv *btv) case 0x0005: btv->c.type = BTTV_OSPREY101_848; break; - + /* 878 based */ case 0x0012: case 0x0013: @@ -3093,20 +3025,21 @@ static void __devinit osprey_eeprom(struct bttv *btv) | (ee[offset+8] << 8) | (ee[offset+9]); } - + printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n", btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial); -} +} /* ----------------------------------------------------------------------- */ /* AVermedia specific stuff, from bktr_card.c */ -int tuner_0_table[] = { +static int tuner_0_table[] = { TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/, TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/, TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, - TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL}; + TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL, + TUNER_PHILIPS_FM1216ME_MK3 }; #if 0 int tuner_0_fm_table[] = { PHILIPS_FR1236_NTSC, PHILIPS_FR1216_PAL, @@ -3116,7 +3049,7 @@ int tuner_0_fm_table[] = { PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL}; #endif -int tuner_1_table[] = { +static int tuner_1_table[] = { TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, @@ -3133,12 +3066,16 @@ static void __devinit avermedia_eeprom(struct bttv *btv) btv->has_remote = (eeprom_data[0x42] & 0x01); if (tuner_make == 0 || tuner_make == 2) - if(tuner_format <=9) + if(tuner_format <=0x0a) tuner = tuner_0_table[tuner_format]; if (tuner_make == 1) if(tuner_format <=9) tuner = tuner_1_table[tuner_format]; - + + if (tuner_make == 4) + if(tuner_format == 0x09) + tuner = TUNER_LG_NTSC_NEW_TAPC; // TAPC-G702P + printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=", btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]); if(tuner) { @@ -3196,6 +3133,7 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin) static void __devinit boot_bt832(struct bttv *btv) { +#if 0 /* not working yet */ int resetbit=0; switch (btv->c.type) { @@ -3224,12 +3162,13 @@ static void __devinit boot_bt832(struct bttv *btv) // bt832 on pixelview changes from i2c 0x8a to 0x88 after // being reset as above. So we must follow by this: bttv_call_i2c_clients(btv, BT832_REATTACH, NULL); +#endif } /* ----------------------------------------------------------------------- */ /* Imagenation L-Model PXC200 Framegrabber */ -/* This is basically the same procedure as - * used by Alessandro Rubini in his pxc200 +/* This is basically the same procedure as + * used by Alessandro Rubini in his pxc200 * driver, but using BTTV functions */ static void __devinit init_PXC200(struct bttv *btv) @@ -3240,13 +3179,13 @@ static void __devinit init_PXC200(struct bttv *btv) unsigned int i; int tmp; u32 val; - + /* Initialise GPIO-connevted 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 + /* GPIO inputs are pulled up, so no need to drive * reset pin any longer */ gpio_bits(0xffffff, 0); if (bttv_gpio) @@ -3261,16 +3200,16 @@ static void __devinit init_PXC200(struct bttv *btv) */ btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC); - + /* Initialise MAX517 DAC */ printk(KERN_INFO "Setting DAC reference voltage level ...\n"); bttv_I2CWrite(btv,0x5E,0,0x80,1); - + /* Initialise 12C508 PIC */ - /* The I2CWrite and I2CRead commmands are actually to the + /* The I2CWrite and I2CRead commmands are actually to the * same chips - but the R/W bit is included in the address * argument so the numbers are different */ - + printk(KERN_INFO "Initialising 12C508 PIC chip ...\n"); @@ -3278,7 +3217,7 @@ static void __devinit init_PXC200(struct bttv *btv) 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 @@ -3310,7 +3249,7 @@ static void __devinit init_PXC200(struct bttv *btv) * Brutally hacked by Dan Sheridan djs52 8/3/00 */ -void bus_low(struct bttv *btv, int bit) +static void bus_low(struct bttv *btv, int bit) { if (btv->mbox_ior) { gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, @@ -3327,7 +3266,7 @@ void bus_low(struct bttv *btv, int bit) } } -void bus_high(struct bttv *btv, int bit) +static void bus_high(struct bttv *btv, int bit) { if (btv->mbox_ior) { gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, @@ -3344,7 +3283,7 @@ void bus_high(struct bttv *btv, int bit) } } -int bus_in(struct bttv *btv, int bit) +static int bus_in(struct bttv *btv, int bit) { if (btv->mbox_ior) { gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, @@ -3390,7 +3329,7 @@ static int tea5757_read(struct bttv *btv) unsigned long timeout; int value = 0; int i; - + /* better safe than sorry */ gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we); @@ -3402,10 +3341,10 @@ static int tea5757_read(struct bttv *btv) if (bttv_gpio) bttv_gpio_tracking(btv,"tea5757 read"); - + bus_low(btv,btv->mbox_we); bus_low(btv,btv->mbox_clk); - + udelay(10); timeout= jiffies + HZ; @@ -3437,7 +3376,7 @@ static int tea5757_write(struct bttv *btv, int value) { int i; int reg = value; - + gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we | btv->mbox_data); if (btv->mbox_ior) { @@ -3492,7 +3431,7 @@ void winview_audio(struct bttv *btv, struct video_audio *v, int set) v->flags |= VIDEO_AUDIO_VOLUME; return; } - + /* 32 levels logarithmic */ vol = 32 - ((v->volume>>11)); /* units */ @@ -3519,7 +3458,7 @@ void winview_audio(struct bttv *btv, struct video_audio *v, int set) data |= WINVIEW_PT2254_STROBE; data &= ~WINVIEW_PT2254_DATA; gpio_write(data); - udelay(10); + udelay(10); data &= ~WINVIEW_PT2254_STROBE; gpio_write(data); } @@ -3644,7 +3583,7 @@ static void avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set) { int val = 0; - + if (set) { if (v->mode & VIDEO_SOUND_LANG2) /* SAP */ val = 0x01; @@ -3779,7 +3718,7 @@ pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set) /* * Dariusz Kowalewski - * sound control for FlyVideo 2000S (with tda9874 decoder) + * sound control for FlyVideo 2000S (with tda9874 decoder) * based on pvbt878p9b_audio() - this is not tested, please fix!!! */ static void @@ -3914,6 +3853,47 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input) 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 seperator + * 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 seperator 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); +} + +static void tibetCS16_init(struct bttv *btv) +{ + /* enable gpio bits, mask obtained via btSpy */ + gpio_inout(0xffffff, 0x0f7fff); + gpio_write(0x0f7fff); +} + // 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 @@ -3962,13 +3942,13 @@ static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input) * ivc120_muxsel [Added by Alan Garfield ] * * The IVC120G security card has 4 i2c controlled TDA8540 matrix - * swichers to provide 16 channels to MUX0. The TDA8540's have - * 4 indepedant outputs and as such the IVC120G also has the - * optional "Monitor Out" bus. This allows the card to be looking + * swichers to provide 16 channels to MUX0. The TDA8540's have + * 4 indepedant 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 - * independant muxsel for the monitor bus, I've just set it to + * independant 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) @@ -3993,12 +3973,12 @@ static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input) static void ivc120_muxsel(struct bttv *btv, unsigned int input) { // Simple maths - int key = input % 4; + int key = input % 4; int matrix = input / 4; - + dprintk("bttv%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n", btv->c.nr, input, matrix, key); - + // Handles the input selection on the TDA8540's bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00, ((matrix == 3) ? (key | key << 2) : 0x00), 1); @@ -4008,22 +3988,102 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input) ((matrix == 1) ? (key | key << 2) : 0x00), 1); bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00, ((matrix == 2) ? (key | key << 2) : 0x00), 1); - + // Handles the output enables on the TDA8540's bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02, ((matrix == 3) ? 0x03 : 0x00), 1); // 13 - 16 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02, ((matrix == 0) ? 0x03 : 0x00), 1); // 1-4 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02, - ((matrix == 1) ? 0x03 : 0x00), 1); // 5-8 + ((matrix == 1) ? 0x03 : 0x00), 1); // 5-8 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02, ((matrix == 2) ? 0x03 : 0x00), 1); // 9-12 - + // Selects MUX0 for input on the 878 btaor((0)<<5, ~(3<<5), BT848_IFORM); } +/* 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) { + printk(KERN_DEBUG "bttv%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)) { + printk(KERN_DEBUG "bttv%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); + + bitmask = btread(BT848_GPIO_DATA); + if (btv->cardid == PX_PXC200A_CARDID) + bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); + else /* older device */ + bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); + btwrite(bitmask,BT848_GPIO_DATA); + + /* + * 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); + + printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux); +} + /* ----------------------------------------------------------------------- */ /* motherboard chipset specific stuff */ @@ -4110,86 +4170,6 @@ int __devinit bttv_handle_chipset(struct bttv *btv) } -/* 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) { - printk(KERN_DEBUG "bttv%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),0); - if (!(rc & PX_CFG_PXC200F)) { - printk(KERN_DEBUG "bttv%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); - - bitmask = btread(BT848_GPIO_DATA); - if (btv->cardid == PX_PXC200A_CARDID) - bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); - else /* older device */ - bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); - btwrite(bitmask,BT848_GPIO_DATA); - - /* - * 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); - - printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux); -} - /* * Local variables: * c-basic-offset: 8