diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/Makefile 780-bttv/drivers/media/video/Makefile --- 770-tuner/drivers/media/video/Makefile Tue Sep 2 09:55:45 2003 +++ 780-bttv/drivers/media/video/Makefile Fri Jan 9 23:11:34 2004 @@ -3,7 +3,7 @@ # bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ - bttv-risc.o bttv-vbi.o + bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bt848.h 780-bttv/drivers/media/video/bt848.h --- 770-tuner/drivers/media/video/bt848.h Mon Nov 17 18:29:29 2003 +++ 780-bttv/drivers/media/video/bt848.h Fri Jan 9 23:11:34 2004 @@ -158,6 +158,9 @@ #define BT848_ADC_C_SLEEP (1<<1) #define BT848_ADC_CRUSH (1<<0) +#define BT848_WC_UP 0x044 +#define BT848_WC_DOWN 0x078 + #define BT848_E_VTC 0x06C #define BT848_O_VTC 0x0EC #define BT848_VTC_HSFMT (1<<7) diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttv-cards.c 780-bttv/drivers/media/video/bttv-cards.c --- 770-tuner/drivers/media/video/bttv-cards.c Mon Dec 8 09:55:51 2003 +++ 780-bttv/drivers/media/video/bttv-cards.c Fri Jan 9 23:11:34 2004 @@ -53,6 +53,8 @@ static void winview_audio(struct bttv *b static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set); static void avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v, int set); +static void avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, + int set); static void terratv_audio(struct bttv *btv, struct video_audio *v, int set); static void gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set); static void winfast2000_audio(struct bttv *btv, struct video_audio *v, int set); @@ -64,6 +66,7 @@ static void rv605_muxsel(struct bttv *bt static void eagle_muxsel(struct bttv *btv, unsigned int input); static void xguard_muxsel(struct bttv *btv, unsigned int input); static void ivc120_muxsel(struct bttv *btv, unsigned int input); +static void gvc1100_muxsel(struct bttv *btv, unsigned int input); static int terratec_active_radio_upgrade(struct bttv *btv); static int tea5757_read(struct bttv *btv); @@ -77,10 +80,11 @@ static unsigned int vsfx=0; static unsigned int latency = UNSET; 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}; -static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET}; -static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET}; +static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; +static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; +static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; +static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; +static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; #ifdef MODULE static unsigned int autoload = 1; #else @@ -108,6 +112,10 @@ MODULE_PARM(tuner,"1-" __stringify(BTTV_ 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-5i"); @@ -155,12 +163,13 @@ static struct CARD { { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" }, { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, - { 0x6607107d, BTTV_WINFAST2000, "Leadtek WinFast VC 100" }, + { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" }, { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, + { 0xd01810fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, @@ -175,16 +184,15 @@ static struct 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" }, - + { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" }, + { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, + { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" }, { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" }, { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" }, - { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" }, - { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, - { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" }, { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, @@ -253,16 +261,24 @@ static struct CARD { { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, + { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" }, { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, + { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" }, { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" }, { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" }, - { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, + { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"}, + { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" }, // 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" }, + { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, + { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB-T" }, + { 0, -1, NULL } }; @@ -352,6 +368,7 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .tuner_type = -1, .audio_hook = avermedia_tvphone_audio, + .has_remote = 1, },{ .name = "MATRIX-Vision MV-Delta", .video_inputs = 5, @@ -438,6 +455,7 @@ struct tvcard bttv_tvcards[] = { .msp34xx_alt = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, + .audio_hook = avermedia_tv_stereo_audio, },{ .name = "Aimslab Video Highway Xtreme (VHX)", .video_inputs = 3, @@ -471,7 +489,13 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x01fe00, .muxsel = { 2, 3, 1, 1}, +#if 0 + // old .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }, +#else + // 2003-10-20 by "Anton A. Arapov" + .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, +#endif .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = -1, @@ -733,6 +757,7 @@ struct tvcard bttv_tvcards[] = { .has_radio = 1, .tuner_type = 5, // default for now, gpio reads BFFF06 for Pal bg+dk .audio_hook = winfast2000_audio, + .has_remote = 1, },{ .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", .video_inputs = 4, @@ -1248,6 +1273,7 @@ struct tvcard bttv_tvcards[] = { .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = 25, + .has_remote = 1, /* GPIO wiring: GPIO0: U4.A0 (hef4052bt) GPIO1: U4.A1 @@ -1283,6 +1309,7 @@ struct tvcard bttv_tvcards[] = { .tuner_type = 5, .audio_hook = pvbt878p9b_audio, // Note: not all cards have stereo .has_radio = 1, // Note: not all cards have radio + .has_remote = 1, /* GPIO wiring: GPIO0: A0 hef4052 GPIO1: A1 hef4052 @@ -1751,7 +1778,8 @@ struct tvcard bttv_tvcards[] = { .no_tda7432 = 1, .pll = PLL_28, .tuner_type = -1, - .no_video = 1, + .has_dvb = 1, + .no_gpioirq = 1, },{ /* Jorge Boncompte - DTI2 */ .name = "ProVideo PV143", @@ -1850,6 +1878,62 @@ struct tvcard bttv_tvcards[] = { 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, .muxsel_hook = ivc120_muxsel, .pll = PLL_28, +},{ + + /* ---- card 0x70 ---------------------------------- */ + .name = "pcHDTV HD-2000 TV", + .video_inputs = 4, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .muxsel = { 2, 3, 1, 0}, + .tuner_type = TUNER_PHILIPS_ATSC, +},{ + .name = "Twinhan DST + clones", + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .tuner_type = TUNER_ABSENT, + .no_video = 1, + .has_dvb = 1, +},{ + .name = "Winfast VC100", + .video_inputs = 3, + .audio_inputs = 0, + .svhs = 1, + .tuner = -1, // no tuner + .muxsel = { 3, 1, 1, 3}, // Vid In, SVid In, Vid over SVid in connector + .no_msp34xx = 1, + .no_tda9875 = 1, + .no_tda7432 = 1, + .tuner_type = TUNER_ABSENT, + .no_video = 1, + .pll = PLL_28, +},{ + .name = "Teppro TEV-560/InterVision IV-560", + .video_inputs = 3, + .audio_inputs = 1, + .tuner = 0, + .svhs = 2, + .gpiomask = 3, + .muxsel = { 2, 3, 1, 1}, + .audiomux = { 1, 1, 1, 1, 0}, + .needs_tvaudio = 1, + .tuner_type = TUNER_PHILIPS_PAL, + .pll = PLL_35, +},{ + + /* ---- card 0x74 ---------------------------------- */ + .name = "SIMUS GVC1100", + .video_inputs = 4, + .audio_inputs = 0, + .tuner = -1, + .svhs = -1, + .tuner_type = -1, + .pll = PLL_28, + .muxsel = { 2, 2, 2, 2}, + .gpiomask = 0x3F, + .muxsel_hook = gvc1100_muxsel, }}; const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -1868,9 +1952,9 @@ void __devinit bttv_idcard(struct bttv * unsigned short tmp; /* read PCI subsystem ID */ - pci_read_config_word(btv->dev, PCI_SUBSYSTEM_ID, &tmp); + pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_ID, &tmp); btv->cardid = tmp << 16; - pci_read_config_word(btv->dev, PCI_SUBSYSTEM_VENDOR_ID, &tmp); + pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_VENDOR_ID, &tmp); btv->cardid |= tmp; if (0 != btv->cardid && 0xffffffff != btv->cardid) { @@ -1883,14 +1967,14 @@ void __devinit bttv_idcard(struct bttv * /* found it */ printk(KERN_INFO "bttv%d: detected: %s [card=%d], " "PCI subsystem ID is %04x:%04x\n", - btv->nr,cards[type].name,cards[type].cardnr, + btv->c.nr,cards[type].name,cards[type].cardnr, btv->cardid & 0xffff, (btv->cardid >> 16) & 0xffff); - btv->type = cards[type].cardnr; + btv->c.type = cards[type].cardnr; } else { /* 404 */ printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n", - btv->nr, btv->cardid & 0xffff, + btv->c.nr, btv->cardid & 0xffff, (btv->cardid >> 16) & 0xffff); printk(KERN_DEBUG "please mail id, board name and " "the correct card= insmod option to kraxel@bytesex.org\n"); @@ -1898,13 +1982,13 @@ void __devinit bttv_idcard(struct bttv * } /* let the user override the autodetected type */ - if (card[btv->nr] < bttv_num_tvcards) - btv->type=card[btv->nr]; + 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->nr, - bttv_tvcards[btv->type].name, btv->type, - card[btv->nr] < bttv_num_tvcards + printk(KERN_INFO "bttv%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"); /* overwrite gpio stuff ?? */ @@ -1914,20 +1998,20 @@ void __devinit bttv_idcard(struct bttv * if (UNSET != audiomux[0]) { gpiobits = 0; for (i = 0; i < 5; i++) { - bttv_tvcards[btv->type].audiomux[i] = audiomux[i]; + bttv_tvcards[btv->c.type].audiomux[i] = audiomux[i]; gpiobits |= audiomux[i]; } } else { gpiobits = audioall; for (i = 0; i < 5; i++) { - bttv_tvcards[btv->type].audiomux[i] = audioall; + bttv_tvcards[btv->c.type].audiomux[i] = audioall; } } - bttv_tvcards[btv->type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits; + bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits; printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=", - btv->nr,bttv_tvcards[btv->type].gpiomask); + btv->c.nr,bttv_tvcards[btv->c.type].gpiomask); for (i = 0; i < 5; i++) { - printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->type].audiomux[i]); + printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].audiomux[i]); } printk("\n"); } @@ -1941,7 +2025,7 @@ void identify_by_eeprom(struct bttv *btv { int type = -1; - if (0 == strncmp(eeprom_data,"GET.MM20xPCTV",13)) + if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) type = BTTV_MODTEC_205; else if (0 == strncmp(eeprom_data+20,"Picolo",7)) type = BTTV_EURESYS_PICOLO; @@ -1949,22 +2033,22 @@ void identify_by_eeprom(struct bttv *btv type = BTTV_HAUPPAUGE; /* old bt848 */ if (-1 != type) { - btv->type = type; + btv->c.type = type; printk("bttv%d: detected by eeprom: %s [card=%d]\n", - btv->nr, bttv_tvcards[btv->type].name, btv->type); + btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type); } } static void flyvideo_gpio(struct bttv *btv) { - int gpio,outbits,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821; + int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821; int tuner=-1,ttype; - - outbits = btread(BT848_GPIO_OUT_EN); - btwrite(0x00, BT848_GPIO_OUT_EN); + + gpio_inout(0xffffff, 0); udelay(8); // without this we would see the 0x1800 mask - gpio=btread(BT848_GPIO_DATA); - btwrite(outbits, BT848_GPIO_OUT_EN); + 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. @@ -1989,7 +2073,7 @@ static void flyvideo_gpio(struct bttv *b case 0xC: tuner=3; // Philips SECAM(+PAL) FQ1216ME or FI1216MF break; default: - printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->nr); + printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr); } has_remote = gpio & 0x800000; @@ -2005,9 +2089,9 @@ static void flyvideo_gpio(struct bttv *b tuner=4; // No tuner present printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", - btv->nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio); + 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->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 @@ -2031,8 +2115,8 @@ static void miro_pinnacle_gpio(struct bt int id,msp,gpio; char *info; - btwrite(0,BT848_GPIO_OUT_EN); - gpio = btread(BT848_GPIO_DATA); + gpio_inout(0xffffff, 0); + gpio = gpio_read(); id = ((gpio>>10) & 63) -1; msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); if (id < 32) { @@ -2051,14 +2135,14 @@ static void miro_pinnacle_gpio(struct bt btv->has_radio = 0; } if (-1 != msp) { - if (btv->type == BTTV_MIRO) - btv->type = BTTV_MIROPRO; - if (btv->type == BTTV_PINNACLE) - btv->type = BTTV_PINNACLEPRO; + if (btv->c.type == BTTV_MIRO) + btv->c.type = BTTV_MIROPRO; + if (btv->c.type == BTTV_PINNACLE) + btv->c.type = BTTV_PINNACLEPRO; } printk(KERN_INFO "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", - btv->nr, id+1, btv->tuner_type, + btv->c.nr, id+1, btv->tuner_type, !btv->has_radio ? "no" : (btv->has_matchbox ? "matchbox" : "fmtuner"), (-1 == msp) ? "no" : "yes"); @@ -2092,10 +2176,10 @@ static void miro_pinnacle_gpio(struct bt break; } if (-1 != msp) - btv->type = BTTV_PINNACLEPRO; + btv->c.type = BTTV_PINNACLEPRO; printk(KERN_INFO "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", - btv->nr, id, info, btv->has_radio ? "yes" : "no"); + btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); btv->tuner_type = 33; btv->pinnacle_id = id; } @@ -2106,16 +2190,14 @@ static void miro_pinnacle_gpio(struct bt static void init_ids_eagle(struct bttv *btv) { - btwrite(0xFFFF37, BT848_GPIO_OUT_EN); - btwrite(0x000000, BT848_GPIO_REG_INP); - - btwrite(0x200020, BT848_GPIO_DATA); + gpio_inout(0xffffff,0xFFFF37); + gpio_write(0x200020); /* flash strobe inverter ?! */ - btwrite(0x200024, BT848_GPIO_DATA); + gpio_write(0x200024); /* switch sync drive off */ - btor(LM1882_SYNC_DRIVE, BT848_GPIO_DATA); + gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE); /* set BT848 muxel to 2 */ btaor((2)<<5, ~(2<<5), BT848_IFORM); @@ -2127,8 +2209,7 @@ static void init_ids_eagle(struct bttv * static void eagle_muxsel(struct bttv *btv, unsigned int input) { btaor((2)<<5, ~(3<<5), BT848_IFORM); - btaor((bttv_tvcards[btv->type].muxsel[input&7]&3), - ~3, BT848_GPIO_DATA); + gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]); #if 0 /* svhs */ @@ -2147,7 +2228,13 @@ static void eagle_muxsel(struct bttv *bt #endif /* switch sync drive off */ - btor(LM1882_SYNC_DRIVE, BT848_GPIO_DATA); + gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE); +} + +static void gvc1100_muxsel(struct bttv *btv, unsigned int input) +{ + static const int masks[] = {0x30, 0x01, 0x12, 0x23}; + gpio_write(masks[input%4]); } /* ----------------------------------------------------------------------- */ @@ -2167,7 +2254,7 @@ void bttv_reset_audio(struct bttv *btv) return; if (bttv_debug) - printk("bttv%d: BT878A ARESET\n",btv->nr); + printk("bttv%d: BT878A ARESET\n",btv->c.nr); btwrite((1<<7), 0x058); udelay(10); btwrite( 0, 0x058); @@ -2176,7 +2263,7 @@ void bttv_reset_audio(struct bttv *btv) /* initialization part one -- before registering i2c bus */ void __devinit bttv_init_card1(struct bttv *btv) { - switch (btv->type) { + switch (btv->c.type) { case BTTV_HAUPPAUGE: case BTTV_HAUPPAUGE878: boot_msp34xx(btv,5); @@ -2198,12 +2285,12 @@ void __devinit bttv_init_card2(struct bt { btv->tuner_type = -1; - if (BTTV_UNKNOWN == btv->type) { + if (BTTV_UNKNOWN == btv->c.type) { bttv_readee(btv,eeprom_data,0xa0); identify_by_eeprom(btv,eeprom_data); } - switch (btv->type) { + switch (btv->c.type) { case BTTV_MIRO: case BTTV_MIROPRO: case BTTV_PINNACLE: @@ -2255,7 +2342,7 @@ void __devinit bttv_init_card2(struct bt case BTTV_MAGICTVIEW061: if (btv->cardid == 0x3002144f) { btv->has_radio=1; - printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->nr); + printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr); } break; case BTTV_STB2: @@ -2292,16 +2379,16 @@ void __devinit bttv_init_card2(struct bt /* pll configuration */ if (!(btv->id==848 && btv->revision==0x11)) { /* defaults from card list */ - if (PLL_28 == bttv_tvcards[btv->type].pll) { + 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->type].pll) { + if (PLL_35 == bttv_tvcards[btv->c.type].pll) { btv->pll.pll_ifreq=35468950; btv->pll.pll_crystal=BT848_IFORM_XT1; } /* insmod options can override */ - switch (pll[btv->nr]) { + switch (pll[btv->c.nr]) { case 0: /* none */ btv->pll.pll_crystal = 0; btv->pll.pll_ifreq = 0; @@ -2324,27 +2411,33 @@ void __devinit bttv_init_card2(struct bt btv->pll.pll_current = -1; /* tuner configuration (from card list / autodetect / insmod option) */ - if (UNSET != bttv_tvcards[btv->type].tuner_type) + if (UNSET != bttv_tvcards[btv->c.type].tuner_type) if(UNSET == btv->tuner_type) - btv->tuner_type = bttv_tvcards[btv->type].tuner_type; - if (UNSET != tuner[btv->nr]) - btv->tuner_type = tuner[btv->nr]; - printk("bttv%d: using tuner=%d\n",btv->nr,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]; + printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); if (btv->pinnacle_id != UNSET) bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE, &btv->pinnacle_id); if (btv->tuner_type != UNSET) bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type); - btv->svhs = bttv_tvcards[btv->type].svhs; - if (svhs[btv->nr] != UNSET) - btv->svhs = svhs[btv->nr]; + btv->svhs = bttv_tvcards[btv->c.type].svhs; + if (svhs[btv->c.nr] != UNSET) + btv->svhs = svhs[btv->c.nr]; + if (remote[btv->c.nr] != UNSET) + btv->has_remote = remote[btv->c.nr]; - if (bttv_tvcards[btv->type].has_radio) + if (bttv_tvcards[btv->c.type].has_radio) btv->has_radio=1; - if (bttv_tvcards[btv->type].audio_hook) - btv->audio_hook=bttv_tvcards[btv->type].audio_hook; + if (bttv_tvcards[btv->c.type].has_remote) + btv->has_remote=1; + if (bttv_tvcards[btv->c.type].no_gpioirq) + btv->gpioirq=0; + if (bttv_tvcards[btv->c.type].audio_hook) + btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; - if (bttv_tvcards[btv->type].digital_mode == DIGITAL_MODE_CAMERA) { + if (bttv_tvcards[btv->c.type].digital_mode == DIGITAL_MODE_CAMERA) { /* detect Bt832 chip for quartzsight digital camera */ if ((bttv_I2CRead(btv, I2C_BT832_ALT1, "Bt832") >=0) || (bttv_I2CRead(btv, I2C_BT832_ALT2, "Bt832") >=0)) @@ -2352,31 +2445,31 @@ void __devinit bttv_init_card2(struct bt } /* try to detect audio/fader chips */ - if (!bttv_tvcards[btv->type].no_msp34xx && + if (!bttv_tvcards[btv->c.type].no_msp34xx && bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) { if (autoload) request_module("msp3400"); } - if (bttv_tvcards[btv->type].msp34xx_alt && + if (bttv_tvcards[btv->c.type].msp34xx_alt && bttv_I2CRead(btv, I2C_MSP3400_ALT, "MSP34xx (alternate address)") >=0) { if (autoload) request_module("msp3400"); } - if (!bttv_tvcards[btv->type].no_tda9875 && + if (!bttv_tvcards[btv->c.type].no_tda9875 && bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) { if (autoload) request_module("tda9875"); } - if (!bttv_tvcards[btv->type].no_tda7432 && + if (!bttv_tvcards[btv->c.type].no_tda7432 && bttv_I2CRead(btv, I2C_TDA7432, "TDA7432") >=0) { if (autoload) request_module("tda7432"); } - if (bttv_tvcards[btv->type].needs_tvaudio) { + if (bttv_tvcards[btv->c.type].needs_tvaudio) { if (autoload) request_module("tvaudio"); } @@ -2460,11 +2553,15 @@ static void modtec_eeprom(struct bttv *b { if( strncmp(&(eeprom_data[0x1e]),"Temic 4066 FY5",14) ==0) { btv->tuner_type=TUNER_TEMIC_4066FY5_PAL_I; - printk("bttv Modtec: Tuner autodetected %s\n", - &eeprom_data[0x1e]); + printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", + btv->c.nr,&eeprom_data[0x1e]); + } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) { + btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; + printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", + btv->c.nr,&eeprom_data[0x1e]); } else { - printk("bttv Modtec: Unknown TunerString:%s\n", - &eeprom_data[0x1e]); + printk("bttv%d: Modtec: Unknown TunerString: %s\n", + btv->c.nr,&eeprom_data[0x1e]); } } @@ -2474,7 +2571,7 @@ static void __devinit hauppauge_eeprom(s if (eeprom_data[0] != 0x84 || eeprom_data[2] != 0) printk(KERN_WARNING "bttv%d: Hauppauge eeprom: invalid\n", - btv->nr); + btv->c.nr); /* Block 2 starts after len+3 bytes header */ blk2 = eeprom_data[1] + 3; @@ -2492,7 +2589,7 @@ static void __devinit hauppauge_eeprom(s if (bttv_verbose) printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, " "tuner=%s (%d), radio=%s\n", - btv->nr, model, hauppauge_tuner[tuner].name, + btv->c.nr, model, hauppauge_tuner[tuner].name, btv->tuner_type, radio ? "yes" : "no"); } @@ -2516,7 +2613,7 @@ static int terratec_active_radio_upgrade tea5757_write(btv, 5 * freq + 0x358); // write 0x1ed8 if (0x1ed8 == tea5757_read(btv)) { printk("bttv%d: Terratec Active Radio Upgrade found.\n", - btv->nr); + btv->c.nr); btv->has_radio = 1; btv->has_matchbox = 1; } else { @@ -2547,36 +2644,35 @@ static int __devinit pvr_altera_load(str u32 n; u8 bits; int i; - - btwrite(BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG, - BT848_GPIO_OUT_EN); - btwrite(0,BT848_GPIO_DATA); + + gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); + gpio_write(0); udelay(PVR_GPIO_DELAY); - btwrite(BTTV_ALT_NCONFIG,BT848_GPIO_DATA); + gpio_write(BTTV_ALT_NCONFIG); udelay(PVR_GPIO_DELAY); for (n = 0; n < microlen; n++) { bits = micro[n]; for ( i = 0 ; i < 8 ; i++ ) { - btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA); - if (bits & 0x01) - btor(BTTV_ALT_DATA,BT848_GPIO_DATA); + gpio_bits(BTTV_ALT_DCLK,0); + if (bits & 0x01) + gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA); else - btand(~BTTV_ALT_DATA,BT848_GPIO_DATA); - btor(BTTV_ALT_DCLK,BT848_GPIO_DATA); + gpio_bits(BTTV_ALT_DATA,0); + gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK); bits >>= 1; } } - btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA); + 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++) { - btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA); - btor(BTTV_ALT_DCLK,BT848_GPIO_DATA); + gpio_bits(BTTV_ALT_DCLK,0); + gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK); } - btand(~BTTV_ALT_DCLK,BT848_GPIO_DATA); + gpio_bits(BTTV_ALT_DCLK,0); return 0; } @@ -2599,15 +2695,15 @@ int __devinit pvr_boot(struct bttv *btv) microlen = mod_firmware_load(firm_altera, (char**) µ); if (!microlen) { printk(KERN_WARNING "bttv%d: altera firmware not found [%s]\n", - btv->nr, firm_altera); + btv->c.nr, firm_altera); return -1; } printk(KERN_INFO "bttv%d: uploading altera firmware [%s] ...\n", - btv->nr, firm_altera); + btv->c.nr, firm_altera); result = pvr_altera_load(btv, micro, microlen); printk(KERN_INFO "bttv%d: ... upload %s\n", - btv->nr, (result < 0) ? "failed" : "ok"); + btv->c.nr, (result < 0) ? "failed" : "ok"); vfree(micro); return result; } @@ -2619,15 +2715,15 @@ int __devinit pvr_boot(struct bttv *btv) const struct firmware *fw_entry; int rc; - rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->dev->dev); + rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); if (rc != 0) { printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", - btv->nr); + btv->c.nr); return rc; } rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); printk(KERN_INFO "bttv%d: altera firmware upload %s\n", - btv->nr, (rc < 0) ? "failed" : "ok"); + btv->c.nr, (rc < 0) ? "failed" : "ok"); release_firmware(fw_entry); return rc; } @@ -2642,7 +2738,7 @@ static void __devinit osprey_eeprom(stru unsigned char *ee = eeprom_data; unsigned long serial = 0; - if (btv->type == 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')) { unsigned char checksum = 0; @@ -2650,7 +2746,7 @@ static void __devinit osprey_eeprom(stru checksum += ee[i]; if (checksum != ee[21]) return; - btv->type = BTTV_OSPREY1x0_848; + btv->c.type = BTTV_OSPREY1x0_848; for (i = 12; i < 21; i++) serial *= 10, serial += ee[i] - '0'; } @@ -2679,49 +2775,49 @@ static void __devinit osprey_eeprom(stru /* 848 based */ case 0x0004: - btv->type = BTTV_OSPREY1x0_848; + btv->c.type = BTTV_OSPREY1x0_848; break; case 0x0005: - btv->type = BTTV_OSPREY101_848; + btv->c.type = BTTV_OSPREY101_848; break; /* 878 based */ case 0x0012: case 0x0013: - btv->type = BTTV_OSPREY1x0; + btv->c.type = BTTV_OSPREY1x0; break; case 0x0014: case 0x0015: - btv->type = BTTV_OSPREY1x1; + btv->c.type = BTTV_OSPREY1x1; break; case 0x0016: case 0x0017: case 0x0020: - btv->type = BTTV_OSPREY1x1_SVID; + btv->c.type = BTTV_OSPREY1x1_SVID; break; case 0x0018: case 0x0019: case 0x001E: case 0x001F: - btv->type = BTTV_OSPREY2xx; + btv->c.type = BTTV_OSPREY2xx; break; case 0x001A: case 0x001B: - btv->type = BTTV_OSPREY2x0_SVID; + btv->c.type = BTTV_OSPREY2x0_SVID; break; case 0x0040: - btv->type = BTTV_OSPREY500; + btv->c.type = BTTV_OSPREY500; break; case 0x0050: case 0x0056: - btv->type = BTTV_OSPREY540; + btv->c.type = BTTV_OSPREY540; /* bttv_osprey_540_init(btv); */ break; case 0x0060: case 0x0070: - btv->type = BTTV_OSPREY2x0; + btv->c.type = BTTV_OSPREY2x0; //enable output on select control lines - btwrite(0x000303, BT848_GPIO_OUT_EN); + gpio_inout(0xffffff,0x000303); break; default: /* unknown...leave generic, but get serial # */ @@ -2734,7 +2830,7 @@ static void __devinit osprey_eeprom(stru } printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n", - btv->nr, btv->type, bttv_tvcards[btv->type].name,serial); + btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial); } /* ----------------------------------------------------------------------- */ @@ -2779,7 +2875,7 @@ static void __devinit avermedia_eeprom(s tuner = tuner_1_table[tuner_format]; printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=", - btv->nr,eeprom_data[0x41],eeprom_data[0x42]); + btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]); if(tuner) { btv->tuner_type=tuner; printk("%d",tuner); @@ -2805,8 +2901,8 @@ void bttv_tda9880_setnorm(struct bttv *b dprintk("bttv_tda9880_setnorm to PAL\n"); } // set GPIO according - btaor(bttv_tvcards[btv->type].audiomux[btv->audio], - ~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA); + gpio_bits(bttv_tvcards[btv->c.type].gpiomask, + bttv_tvcards[btv->c.type].audiomux[btv->audio]); } @@ -2821,23 +2917,23 @@ static void __devinit boot_msp34xx(struc { int mask = (1 << pin); - btaor(mask, ~mask, BT848_GPIO_OUT_EN); - btaor(0, ~mask, BT848_GPIO_DATA); + gpio_inout(mask,mask); + gpio_bits(mask,0); udelay(2500); - btaor(mask, ~mask, BT848_GPIO_DATA); + gpio_bits(mask,mask); + if (bttv_gpio) bttv_gpio_tracking(btv,"msp34xx"); - if (bttv_verbose) printk(KERN_INFO "bttv%d: Hauppauge/Voodoo msp34xx: reset line " - "init [%d]\n", btv->nr, pin); + "init [%d]\n", btv->c.nr, pin); } static void __devinit boot_bt832(struct bttv *btv) { - int outbits,databits,resetbit=0; + int resetbit=0; - switch (btv->type) { + switch (btv->c.type) { case BTTV_PXELVWPLTVPAK: resetbit = 0x400000; break; @@ -2851,18 +2947,14 @@ static void __devinit boot_bt832(struct request_module("bt832"); bttv_call_i2c_clients(btv, BT832_HEXDUMP, NULL); - printk("bttv%d: Reset Bt832 [line=0x%x]\n",btv->nr,resetbit); - btwrite(0, BT848_GPIO_DATA); - outbits = btread(BT848_GPIO_OUT_EN); - databits= btread(BT848_GPIO_DATA); - btwrite(resetbit, BT848_GPIO_OUT_EN); + printk("bttv%d: Reset Bt832 [line=0x%x]\n",btv->c.nr,resetbit); + gpio_write(0); + gpio_inout(resetbit, resetbit); udelay(5); - btwrite(resetbit, BT848_GPIO_DATA); + gpio_bits(resetbit, resetbit); udelay(5); - btwrite(0, BT848_GPIO_DATA); + gpio_bits(resetbit, 0); udelay(5); - btwrite(outbits, BT848_GPIO_OUT_EN); - btwrite(databits, BT848_GPIO_DATA); // bt832 on pixelview changes from i2c 0x8a to 0x88 after // being reset as above. So we must follow by this: @@ -2885,13 +2977,13 @@ static void __devinit init_PXC200(struct u32 val; /* Initialise GPIO-connevted stuff */ - btwrite(1<<13,BT848_GPIO_OUT_EN); /* Reset pin only */ - btwrite(0,BT848_GPIO_DATA); + gpio_bits(0xffffff, (1<<13)); + gpio_write(0); udelay(3); - btwrite(1<<13,BT848_GPIO_DATA); + gpio_write(1<<13); /* GPIO inputs are pulled up, so no need to drive * reset pin any longer */ - btwrite(0,BT848_GPIO_OUT_EN); + gpio_bits(0xffffff, 0); if (bttv_gpio) bttv_gpio_tracking(btv,"pxc200"); @@ -2926,10 +3018,10 @@ static void __devinit init_PXC200(struct * 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? */ - btwrite( (1<<2), BT848_GPIO_OUT_EN); /* only the reset pin */ - btwrite(0, BT848_GPIO_DATA); + gpio_inout(0xffffff,(1<<2)); + gpio_write(0); udelay(10); - btwrite(1<<2, BT848_GPIO_DATA); + gpio_write(1<<2); for (i = 0; i < ARRAY_SIZE(vals); i++) { tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); @@ -2956,17 +3048,16 @@ static void __devinit init_PXC200(struct void bus_low(struct bttv *btv, int bit) { if (btv->mbox_ior) { - btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - BT848_GPIO_DATA); + gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, + btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); udelay(5); } - btand(~(bit), BT848_GPIO_DATA); + gpio_bits(bit,0); udelay(5); if (btv->mbox_ior) { - btand(~(btv->mbox_iow | btv->mbox_csel), - BT848_GPIO_DATA); + gpio_bits(btv->mbox_iow | btv->mbox_csel, 0); udelay(5); } } @@ -2974,17 +3065,16 @@ void bus_low(struct bttv *btv, int bit) void bus_high(struct bttv *btv, int bit) { if (btv->mbox_ior) { - btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - BT848_GPIO_DATA); + gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, + btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); udelay(5); } - btor((bit), BT848_GPIO_DATA); + gpio_bits(bit,bit); udelay(5); if (btv->mbox_ior) { - btand(~(btv->mbox_iow | btv->mbox_csel), - BT848_GPIO_DATA); + gpio_bits(btv->mbox_iow | btv->mbox_csel, 0); udelay(5); } } @@ -2992,15 +3082,14 @@ void bus_high(struct bttv *btv, int bit) int bus_in(struct bttv *btv, int bit) { if (btv->mbox_ior) { - btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - BT848_GPIO_DATA); + gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, + btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); udelay(5); - btand(~(btv->mbox_ior | btv->mbox_csel), - BT848_GPIO_DATA); + gpio_bits(btv->mbox_iow | btv->mbox_csel, 0); udelay(5); } - return btread(BT848_GPIO_DATA) & (bit); + return gpio_read() & (bit); } /* TEA5757 register bits */ @@ -3038,12 +3127,11 @@ static int tea5757_read(struct bttv *btv int i; /* better safe than sorry */ - btaor((btv->mbox_clk | btv->mbox_we), - ~btv->mbox_mask, BT848_GPIO_OUT_EN); + gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we); if (btv->mbox_ior) { - btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - BT848_GPIO_DATA); + gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, + btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); udelay(5); } @@ -3060,11 +3148,11 @@ static int tea5757_read(struct bttv *btv while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout)) schedule(); if (bus_in(btv,btv->mbox_data)) { - printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->nr); + printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->c.nr); return -1; } - dprintk("bttv%d: tea5757:",btv->nr); + dprintk("bttv%d: tea5757:",btv->c.nr); for(i = 0; i < 24; i++) { udelay(5); @@ -3076,7 +3164,7 @@ static int tea5757_read(struct bttv *btv value |= (bus_in(btv,btv->mbox_data) == 0)?0:1; /* MSB first */ dprintk("%c", (bus_in(btv,btv->mbox_most) == 0)?'S':'M'); } - dprintk("\nbttv%d: tea5757: read 0x%X\n", btv->nr, value); + dprintk("\nbttv%d: tea5757: read 0x%X\n", btv->c.nr, value); return value; } @@ -3085,18 +3173,17 @@ static int tea5757_write(struct bttv *bt int i; int reg = value; - btaor(btv->mbox_clk | btv->mbox_we | btv->mbox_data, - ~btv->mbox_mask, BT848_GPIO_OUT_EN); + gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we | btv->mbox_data); if (btv->mbox_ior) { - btor(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, - BT848_GPIO_DATA); + gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel, + btv->mbox_ior | btv->mbox_iow | btv->mbox_csel); udelay(5); } if (bttv_gpio) bttv_gpio_tracking(btv,"tea5757 write"); - dprintk("bttv%d: tea5757: write 0x%X\n", btv->nr, value); + dprintk("bttv%d: tea5757: write 0x%X\n", btv->c.nr, value); bus_low(btv,btv->mbox_clk); bus_high(btv,btv->mbox_we); for(i = 0; i < 25; i++) @@ -3122,7 +3209,7 @@ void tea5757_set_freq(struct bttv *btv, #if 0 /* breaks Miro PCTV */ value = tea5757_read(btv); - dprintk("bttv%d: tea5757 readback=0x%x\n",btv->nr,value); + dprintk("bttv%d: tea5757 readback=0x%x\n",btv->c.nr,value); #endif } @@ -3148,7 +3235,7 @@ void winview_audio(struct bttv *btv, str /* tens */ bits_out |= (PT2254_DBS_IN_10>>(vol/5)); bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL; - data = btread(BT848_GPIO_DATA); + data = gpio_read(); data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA| WINVIEW_PT2254_STROBE); for (loops = 17; loops >= 0 ; loops--) { @@ -3156,20 +3243,20 @@ void winview_audio(struct bttv *btv, str data |= WINVIEW_PT2254_DATA; else data &= ~WINVIEW_PT2254_DATA; - btwrite(data, BT848_GPIO_DATA); + gpio_write(data); udelay(5); data |= WINVIEW_PT2254_CLK; - btwrite(data, BT848_GPIO_DATA); + gpio_write(data); udelay(5); data &= ~WINVIEW_PT2254_CLK; - btwrite(data, BT848_GPIO_DATA); + gpio_write(data); } data |= WINVIEW_PT2254_STROBE; data &= ~WINVIEW_PT2254_DATA; - btwrite(data, BT848_GPIO_DATA); + gpio_write(data); udelay(10); data &= ~WINVIEW_PT2254_STROBE; - btwrite(data, BT848_GPIO_DATA); + gpio_write(data); } /* ----------------------------------------------------------------------- */ @@ -3182,7 +3269,7 @@ gvbctv3pci_audio(struct bttv *btv, struc unsigned int con = 0; if (set) { - btor(0x300, BT848_GPIO_OUT_EN); + gpio_inout(0x300, 0x300); if (v->mode & VIDEO_SOUND_LANG1) con = 0x000; if (v->mode & VIDEO_SOUND_LANG2) @@ -3191,7 +3278,7 @@ gvbctv3pci_audio(struct bttv *btv, struc con = 0x200; // if (v->mode & VIDEO_SOUND_MONO) // con = 0x100; - btaor(con, ~0x300, BT848_GPIO_DATA); + gpio_bits(0x300, con); } else { v->mode = VIDEO_SOUND_STEREO | VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; @@ -3217,12 +3304,12 @@ avermedia_tvphone_audio(struct bttv *btv int val = 0; if (set) { - if (v->mode & VIDEO_SOUND_LANG1) /* SAP */ + if (v->mode & VIDEO_SOUND_LANG2) /* SAP */ val = 0x02; if (v->mode & VIDEO_SOUND_STEREO) val = 0x01; if (val) { - btaor(val, ~0x03, BT848_GPIO_DATA); + gpio_bits(0x03,val); if (bttv_gpio) bttv_gpio_tracking(btv,"avermedia"); } @@ -3233,13 +3320,33 @@ avermedia_tvphone_audio(struct bttv *btv } } +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; + if (v->mode & VIDEO_SOUND_STEREO) /* STEREO */ + val = 0x02; + btaor(val, ~0x03, BT848_GPIO_DATA); + if (bttv_gpio) + bttv_gpio_tracking(btv,"avermedia"); + } else { + v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | + VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; + return; + } +} + /* Lifetec 9415 handling */ static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set) { int val = 0; - if (btread(BT848_GPIO_DATA) & 0x4000) { + if (gpio_read() & 0x4000) { v->mode = VIDEO_SOUND_MONO; return; } @@ -3252,7 +3359,7 @@ lt9415_audio(struct bttv *btv, struct vi if ((v->mode & VIDEO_SOUND_LANG1) || (v->mode & VIDEO_SOUND_MONO)) val = 0; - btaor(val, ~0x0880, BT848_GPIO_DATA); + gpio_bits(0x0880, val); if (bttv_gpio) bttv_gpio_tracking(btv,"lt9415"); } else { @@ -3270,12 +3377,12 @@ terratv_audio(struct bttv *btv, struct v unsigned int con = 0; if (set) { - btor(0x180000, BT848_GPIO_OUT_EN); + gpio_inout(0x180000,0x180000); if (v->mode & VIDEO_SOUND_LANG2) con = 0x080000; if (v->mode & VIDEO_SOUND_STEREO) con = 0x180000; - btaor(con, ~0x180000, BT848_GPIO_DATA); + gpio_bits(0x180000, con); if (bttv_gpio) bttv_gpio_tracking(btv,"terratv"); } else { @@ -3300,7 +3407,7 @@ winfast2000_audio(struct bttv *btv, stru if (v->mode & VIDEO_SOUND_STEREO) /* Stereo */ val = 0x020000; if (val) { - btaor(val, ~0x430000, BT848_GPIO_DATA); + gpio_bits(0x430000, val); if (bttv_gpio) bttv_gpio_tracking(btv,"winfast2000"); } @@ -3340,7 +3447,7 @@ pvbt878p9b_audio(struct bttv *btv, struc val = 0x02; } if (val) { - btaor(val, ~0x03, BT848_GPIO_DATA); + gpio_bits(0x03,val); if (bttv_gpio) bttv_gpio_tracking(btv,"pvbt878p9b"); } @@ -3376,7 +3483,7 @@ fv2000s_audio(struct bttv *btv, struct v val = 0x1080; //-dk-???: 0x0880, 0x0080, 0x1800 ... } if (val != 0xffff) { - btaor(val, ~0x1800, BT848_GPIO_DATA); + gpio_bits(0x1800, val); if (bttv_gpio) bttv_gpio_tracking(btv,"fv2000s"); } @@ -3405,7 +3512,7 @@ windvr_audio(struct bttv *btv, struct vi if (v->mode & VIDEO_SOUND_STEREO) val = 0; if (val) { - btaor(val, ~0x140000, BT848_GPIO_DATA); + gpio_bits(0x140000, val); if (bttv_gpio) bttv_gpio_tracking(btv,"windvr"); } @@ -3437,7 +3544,7 @@ adtvk503_audio(struct bttv *btv, struct if (v->mode & VIDEO_SOUND_MONO) con = 0x00060000; if (con != 0xffffff) { - btaor(con, ~0x1e0000, BT848_GPIO_DATA); + gpio_bits(0x1e0000,con); if (bttv_gpio) bttv_gpio_tracking(btv, "adtvk503"); } @@ -3474,16 +3581,16 @@ adtvk503_audio(struct bttv *btv, struct static void rv605_muxsel(struct bttv *btv, unsigned int input) { /* reset all conections */ - btaor(0x200,~0x200, BT848_GPIO_DATA); + gpio_bits(0x200,0x200); mdelay(1); - btaor(0x000,~0x200, BT848_GPIO_DATA); + gpio_bits(0x200,0x000); mdelay(1); /* create a new conection */ - btaor(0x080,~0x480, BT848_GPIO_DATA); - btaor(0x480,~0x480, BT848_GPIO_DATA); + gpio_bits(0x480,0x080); + gpio_bits(0x480,0x480); mdelay(1); - btaor(0x080,~0x480, BT848_GPIO_DATA); + gpio_bits(0x480,0x080); mdelay(1); } @@ -3513,7 +3620,7 @@ static void xguard_muxsel(struct bttv *b ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, }; - btwrite(masks[input%16], BT848_GPIO_DATA); + gpio_write(masks[input%16]); } /* @@ -3555,7 +3662,7 @@ static void ivc120_muxsel(struct bttv *b int matrix = input / 4; dprintk("bttv%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n", - btv->nr, input, matrix, key); + btv->c.nr, input, matrix, key); // Handles the input selection on the TDA8540's bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00, @@ -3641,12 +3748,12 @@ int __devinit bttv_handle_chipset(struct if (bttv_verbose) { if (triton1) - printk(KERN_INFO "bttv%d: enabling ETBF (430FX/VP3 compatibilty)\n",btv->nr); + printk(KERN_INFO "bttv%d: enabling ETBF (430FX/VP3 compatibilty)\n",btv->c.nr); if (vsfx && btv->id >= 878) - printk(KERN_INFO "bttv%d: enabling VSFX\n",btv->nr); + printk(KERN_INFO "bttv%d: enabling VSFX\n",btv->c.nr); if (UNSET != latency) printk(KERN_INFO "bttv%d: setting pci timer to %d\n", - btv->nr,latency); + btv->c.nr,latency); } if (btv->id < 878) { @@ -3655,15 +3762,15 @@ int __devinit bttv_handle_chipset(struct btv->triton1 = BT848_INT_ETBF; } else { /* bt878 has a bit in the pci config space for it */ - pci_read_config_byte(btv->dev, BT878_DEVCTRL, &command); + 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->dev, BT878_DEVCTRL, command); + pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command); } if (UNSET != latency) - pci_write_config_byte(btv->dev, PCI_LATENCY_TIMER, latency); + pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); return 0; } diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttv-driver.c 780-bttv/drivers/media/video/bttv-driver.c --- 770-tuner/drivers/media/video/bttv-driver.c Mon Nov 17 18:29:48 2003 +++ 780-bttv/drivers/media/video/bttv-driver.c Fri Jan 9 23:11:34 2004 @@ -68,11 +68,12 @@ static unsigned int lumafilter = 0; static unsigned int automute = 1; static unsigned int chroma_agc = 0; static unsigned int adc_crush = 1; +static unsigned int whitecrush_upper = 0xCF; +static unsigned int whitecrush_lower = 0x7F; static unsigned int vcr_hack = 0; static unsigned int irq_iswitch = 0; /* API features (turn on/off stuff for testing) */ -static unsigned int sloppy = 0; static unsigned int v4l2 = 1; @@ -108,12 +109,15 @@ MODULE_PARM(chroma_agc,"i"); MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)"); MODULE_PARM(adc_crush,"i"); MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)"); +MODULE_PARM(whitecrush_upper,"i"); +MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207"); +MODULE_PARM(whitecrush_lower,"i"); +MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127"); MODULE_PARM(vcr_hack,"i"); MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); MODULE_PARM(irq_iswitch,"i"); MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); -MODULE_PARM(sloppy,"i"); MODULE_PARM(v4l2,"i"); MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards"); @@ -133,7 +137,7 @@ static ssize_t show_card(struct class_de { struct video_device *vfd = to_video_device(cd); struct bttv *btv = dev_get_drvdata(vfd->dev); - return sprintf(buf, "%d\n", btv ? btv->type : UNSET); + return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET); } static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL); @@ -479,7 +483,9 @@ const unsigned int BTTV_FORMATS = ARRAY_ #define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_PRIVATE_BASE + 3) #define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_PRIVATE_BASE + 4) #define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5) -#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 6) +#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6) +#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7) +#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 8) static const struct v4l2_queryctrl no_ctl = { .name = "42", @@ -597,7 +603,24 @@ static const struct v4l2_queryctrl bttv_ .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER, + .name = "whitecrush upper", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 0xCF, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER, + .name = "whitecrush lower", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 0x7F, + .type = V4L2_CTRL_TYPE_INTEGER, } + }; const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); @@ -695,7 +718,7 @@ static void set_pll(struct bttv *btv) return; if (btv->pll.pll_ofreq == btv->pll.pll_current) { - dprintk("bttv%d: PLL: no change required\n",btv->nr); + dprintk("bttv%d: PLL: no change required\n",btv->c.nr); return; } @@ -704,22 +727,22 @@ static void set_pll(struct bttv *btv) if (btv->pll.pll_current == 0) return; vprintk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n", - btv->nr,btv->pll.pll_ifreq); + btv->c.nr,btv->pll.pll_ifreq); btwrite(0x00,BT848_TGCTRL); btwrite(0x00,BT848_PLL_XCI); btv->pll.pll_current = 0; return; } - vprintk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->nr, + vprintk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr, btv->pll.pll_ifreq, btv->pll.pll_ofreq); set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq); for (i=0; i<10; i++) { /* Let other people run while the PLL stabilizes */ vprintk("."); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ/10); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/50); if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) { btwrite(0,BT848_DSTATUS); @@ -742,9 +765,9 @@ void bt848A_set_timing(struct bttv *btv) int table_idx = bttv_tvnorms[btv->tvnorm].sram; int fsc = bttv_tvnorms[btv->tvnorm].Fsc; - if (UNSET == bttv_tvcards[btv->type].muxsel[btv->input]) { + if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) { dprintk("bttv%d: load digital timing table (table_idx=%d)\n", - btv->nr,table_idx); + btv->c.nr,table_idx); /* timing change...reset timing generator address */ btwrite(0x00, BT848_TGCTRL); @@ -828,13 +851,13 @@ video_mux(struct bttv *btv, unsigned int { int mux,mask2; - if (input >= bttv_tvcards[btv->type].video_inputs) + if (input >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; /* needed by RemoteVideo MX */ - mask2 = bttv_tvcards[btv->type].gpiomask2; + mask2 = bttv_tvcards[btv->c.type].gpiomask2; if (mask2) - btaor(mask2,~mask2,BT848_GPIO_OUT_EN); + gpio_inout(mask2,mask2); if (input == btv->svhs) { btor(BT848_CONTROL_COMP, BT848_E_CONTROL); @@ -843,14 +866,14 @@ video_mux(struct bttv *btv, unsigned int btand(~BT848_CONTROL_COMP, BT848_E_CONTROL); btand(~BT848_CONTROL_COMP, BT848_O_CONTROL); } - mux = bttv_tvcards[btv->type].muxsel[input] & 3; + mux = bttv_tvcards[btv->c.type].muxsel[input] & 3; btaor(mux<<5, ~(3<<5), BT848_IFORM); dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n", - btv->nr,input,mux); + btv->c.nr,input,mux); /* card specific hook */ - if(bttv_tvcards[btv->type].muxsel_hook) - bttv_tvcards[btv->type].muxsel_hook (btv, input); + if(bttv_tvcards[btv->c.type].muxsel_hook) + bttv_tvcards[btv->c.type].muxsel_hook (btv, input); return 0; } @@ -863,9 +886,9 @@ static int audio_mux(struct bttv *btv, int mode) { int val,mux,i2c_mux,signal; - - btaor(bttv_tvcards[btv->type].gpiomask, - ~bttv_tvcards[btv->type].gpiomask,BT848_GPIO_OUT_EN); + + gpio_inout(bttv_tvcards[btv->c.type].gpiomask, + bttv_tvcards[btv->c.type].gpiomask); signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; switch (mode) { @@ -887,12 +910,12 @@ audio_mux(struct bttv *btv, int mode) mux = AUDIO_OFF; #if 0 printk("bttv%d: amux: mode=%d audio=%d signal=%s mux=%d/%d irq=%s\n", - btv->nr, mode, btv->audio, signal ? "yes" : "no", + btv->c.nr, mode, btv->audio, signal ? "yes" : "no", mux, i2c_mux, in_interrupt() ? "yes" : "no"); #endif - val = bttv_tvcards[btv->type].audiomux[mux]; - btaor(val,~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA); + val = bttv_tvcards[btv->c.type].audiomux[mux]; + gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val); if (bttv_gpio) bttv_gpio_tracking(btv,audio_modes[mux]); if (!in_interrupt()) @@ -909,7 +932,7 @@ i2c_vidiocschan(struct bttv *btv) c.norm = btv->tvnorm; c.channel = btv->input; bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); - if (btv->type == BTTV_VOODOOTV_FM) + if (btv->c.type == BTTV_VOODOOTV_FM) bttv_tda9880_setnorm(btv,c.norm); } @@ -932,7 +955,7 @@ set_tvnorm(struct bttv *btv, unsigned in btwrite(1, BT848_VBI_PACK_DEL); bt848A_set_timing(btv); - switch (btv->type) { + switch (btv->c.type) { case BTTV_VOODOOTV_FM: bttv_tda9880_setnorm(btv,norm); break; @@ -963,7 +986,7 @@ set_input(struct bttv *btv, unsigned int } else { video_mux(btv,input); } - audio_mux(btv,(input == bttv_tvcards[btv->type].tuner ? + audio_mux(btv,(input == bttv_tvcards[btv->c.type].tuner ? AUDIO_TUNER : AUDIO_EXTERN)); set_tvnorm(btv,btv->tvnorm); } @@ -972,7 +995,14 @@ static void init_bt848(struct bttv *btv) { int val; - btwrite(0, BT848_SRESET); + if (bttv_tvcards[btv->c.type].no_video) { + /* very basic init only */ + btwrite(0xfffffUL, BT848_INT_STAT); + btwrite(BT848_INT_I2CDONE, + BT848_INT_MASK); + return; + } + btwrite(0x00, BT848_CAP_CTL); btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); @@ -995,6 +1025,9 @@ static void init_bt848(struct bttv *btv) btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), BT848_ADC); + btwrite(whitecrush_upper, BT848_WC_UP); + btwrite(whitecrush_lower, BT848_WC_DOWN); + if (btv->opt_lumafilter) { btwrite(0, BT848_E_CONTROL); btwrite(0, BT848_O_CONTROL); @@ -1006,11 +1039,12 @@ static void init_bt848(struct bttv *btv) /* interrupt */ btwrite(0xfffffUL, BT848_INT_STAT); btwrite((btv->triton1) | - BT848_INT_GPINT | + (btv->gpioirq ? BT848_INT_GPINT : 0) | BT848_INT_SCERR | (fdsr ? BT848_INT_FDSR : 0) | BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES| - BT848_INT_FMTCHG|BT848_INT_HLOCK, + BT848_INT_FMTCHG|BT848_INT_HLOCK| + BT848_INT_I2CDONE, BT848_INT_MASK); } @@ -1019,7 +1053,7 @@ extern void bttv_reinit_bt848(struct btt unsigned long flags; if (bttv_verbose) - printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->nr); + printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->c.nr); spin_lock_irqsave(&btv->s_lock,flags); btv->errors=0; bttv_set_dma(btv,0,0); @@ -1094,6 +1128,12 @@ static int get_control(struct bttv *btv, case V4L2_CID_PRIVATE_VCR_HACK: c->value = btv->opt_vcr_hack; break; + case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: + c->value = btv->opt_whitecrush_upper; + break; + case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: + c->value = btv->opt_whitecrush_lower; + break; default: return -EINVAL; } @@ -1182,6 +1222,14 @@ static int set_control(struct bttv *btv, case V4L2_CID_PRIVATE_VCR_HACK: btv->opt_vcr_hack = c->value; break; + case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: + btv->opt_whitecrush_upper = c->value; + btwrite(c->value, BT848_WC_UP); + break; + case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: + btv->opt_whitecrush_lower = c->value; + btwrite(c->value, BT848_WC_DOWN); + break; default: return -EINVAL; } @@ -1201,7 +1249,7 @@ void bttv_gpio_tracking(struct bttv *btv outbits = btread(BT848_GPIO_OUT_EN); data = btread(BT848_GPIO_DATA); printk(KERN_DEBUG "bttv%d: gpio: en=%08x, out=%08x in=%08x [%s]\n", - btv->nr,outbits,data & outbits, data & ~outbits, comment); + btv->c.nr,outbits,data & outbits, data & ~outbits, comment); } void bttv_field_count(struct bttv *btv) @@ -1325,7 +1373,7 @@ static int bttv_prepare_buffer(struct bt /* alloc risc memory */ if (STATE_NEEDS_INIT == buf->vb.state) { redo_dma_risc = 1; - if (0 != (rc = videobuf_iolock(btv->dev,&buf->vb,&btv->fbuf))) + if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf))) goto fail; } @@ -1428,7 +1476,7 @@ int bttv_common_ioctls(struct bttv *btv, { struct video_tuner *v = arg; - if (UNSET == bttv_tvcards[btv->type].tuner) + if (UNSET == bttv_tvcards[btv->c.type].tuner) return -EINVAL; if (v->tuner) /* Only tuner 0 */ return -EINVAL; @@ -1462,13 +1510,13 @@ int bttv_common_ioctls(struct bttv *btv, struct video_channel *v = arg; unsigned int channel = v->channel; - if (channel >= bttv_tvcards[btv->type].video_inputs) + if (channel >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; v->tuners=0; v->flags = VIDEO_VC_AUDIO; v->type = VIDEO_TYPE_CAMERA; v->norm = btv->tvnorm; - if (channel == bttv_tvcards[btv->type].tuner) { + if (channel == bttv_tvcards[btv->c.type].tuner) { strcpy(v->name,"Television"); v->flags|=VIDEO_VC_TUNER; v->type=VIDEO_TYPE_TV; @@ -1485,7 +1533,7 @@ int bttv_common_ioctls(struct bttv *btv, struct video_channel *v = arg; unsigned int channel = v->channel; - if (channel >= bttv_tvcards[btv->type].video_inputs) + if (channel >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; if (v->norm >= BTTV_TVNORMS) return -EINVAL; @@ -1528,7 +1576,7 @@ int bttv_common_ioctls(struct bttv *btv, struct video_audio *v = arg; unsigned int audio = v->audio; - if (audio >= bttv_tvcards[btv->type].audio_inputs) + if (audio >= bttv_tvcards[btv->c.type].audio_inputs) return -EINVAL; down(&btv->lock); @@ -1596,13 +1644,13 @@ int bttv_common_ioctls(struct bttv *btv, unsigned int n; n = i->index; - if (n >= bttv_tvcards[btv->type].video_inputs) + if (n >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; memset(i,0,sizeof(*i)); i->index = n; i->type = V4L2_INPUT_TYPE_CAMERA; i->audioset = 1; - if (i->index == bttv_tvcards[btv->type].tuner) { + if (i->index == bttv_tvcards[btv->c.type].tuner) { sprintf(i->name, "Television"); i->type = V4L2_INPUT_TYPE_TUNER; i->tuner = 0; @@ -1632,7 +1680,7 @@ int bttv_common_ioctls(struct bttv *btv, { unsigned int *i = arg; - if (*i > bttv_tvcards[btv->type].video_inputs) + if (*i > bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; down(&btv->lock); set_input(btv,*i); @@ -1645,7 +1693,7 @@ int bttv_common_ioctls(struct bttv *btv, { struct v4l2_tuner *t = arg; - if (UNSET == bttv_tvcards[btv->type].tuner) + if (UNSET == bttv_tvcards[btv->c.type].tuner) return -EINVAL; if (0 != t->index) return -EINVAL; @@ -1683,7 +1731,7 @@ int bttv_common_ioctls(struct bttv *btv, { struct v4l2_tuner *t = arg; - if (UNSET == bttv_tvcards[btv->type].tuner) + if (UNSET == bttv_tvcards[btv->c.type].tuner) return -EINVAL; if (0 != t->index) return -EINVAL; @@ -2061,16 +2109,16 @@ static int bttv_do_ioctl(struct inode *i switch (_IOC_TYPE(cmd)) { case 'v': printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n", - btv->nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ? + btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ? v4l1_ioctls[_IOC_NR(cmd)] : "???"); break; case 'V': printk("bttv%d: ioctl 0x%x (v4l2, %s)\n", - btv->nr, cmd, v4l2_ioctl_names[_IOC_NR(cmd)]); + btv->c.nr, cmd, v4l2_ioctl_names[_IOC_NR(cmd)]); break; default: printk("bttv%d: ioctl 0x%x (???)\n", - btv->nr, cmd); + btv->c.nr, cmd); } } if (btv->errors) @@ -2110,8 +2158,8 @@ static int bttv_do_ioctl(struct inode *i VID_TYPE_OVERLAY| VID_TYPE_CLIPPING| VID_TYPE_SCALES; - cap->channels = bttv_tvcards[btv->type].video_inputs; - cap->audios = bttv_tvcards[btv->type].audio_inputs; + cap->channels = bttv_tvcards[btv->c.type].video_inputs; + cap->audios = bttv_tvcards[btv->c.type].audio_inputs; cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth; cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight; cap->minwidth = 48; @@ -2144,7 +2192,7 @@ static int bttv_do_ioctl(struct inode *i if (NULL == fmt) return -EINVAL; down(&fh->cap.lock); - if (fmt->depth != pic->depth && !sloppy) { + if (fmt->depth != pic->depth) { retval = -EINVAL; goto fh_unlock_and_return; } @@ -2228,43 +2276,35 @@ static int bttv_do_ioctl(struct inode *i fbuf->height * fbuf->bytesperline; down(&fh->cap.lock); retval = -EINVAL; - if (sloppy) { - /* also set the default palette -- for backward - compatibility with older versions */ - switch (fbuf->depth) { - case 8: - fmt = format_by_palette(VIDEO_PALETTE_HI240); - break; - case 16: - fmt = format_by_palette(VIDEO_PALETTE_RGB565); - break; - case 24: - fmt = format_by_palette(VIDEO_PALETTE_RGB24); - break; - case 32: - fmt = format_by_palette(VIDEO_PALETTE_RGB32); - break; - case 15: - fbuf->depth = 16; - fmt = format_by_palette(VIDEO_PALETTE_RGB555); - break; - default: - fmt = NULL; - break; - } - if (NULL == fmt) - goto fh_unlock_and_return; - fh->ovfmt = fmt; - fh->fmt = fmt; - btv->init.ovfmt = fmt; - btv->init.fmt = fmt; - } else { - if (15 == fbuf->depth) - fbuf->depth = 16; - if (fbuf->depth != 8 && fbuf->depth != 16 && - fbuf->depth != 24 && fbuf->depth != 32) - goto fh_unlock_and_return; + + switch (fbuf->depth) { + case 8: + fmt = format_by_palette(VIDEO_PALETTE_HI240); + break; + case 16: + fmt = format_by_palette(VIDEO_PALETTE_RGB565); + break; + case 24: + fmt = format_by_palette(VIDEO_PALETTE_RGB24); + break; + case 32: + fmt = format_by_palette(VIDEO_PALETTE_RGB32); + break; + case 15: + fbuf->depth = 16; + fmt = format_by_palette(VIDEO_PALETTE_RGB555); + break; + default: + fmt = NULL; + break; } + if (NULL == fmt) + goto fh_unlock_and_return; + + fh->ovfmt = fmt; + fh->fmt = fmt; + btv->init.ovfmt = fmt; + btv->init.fmt = fmt; btv->fbuf.base = fbuf->base; btv->fbuf.fmt.width = fbuf->width; btv->fbuf.fmt.height = fbuf->height; @@ -2287,7 +2327,7 @@ static int bttv_do_ioctl(struct inode *i if (NULL == btv->fbuf.base) return -EINVAL; if (!fh->ov.setup_ok) { - dprintk("bttv%d: overlay: !setup_ok\n",btv->nr); + dprintk("bttv%d: overlay: !setup_ok\n",btv->c.nr); return -EINVAL; } } @@ -2383,7 +2423,7 @@ static int bttv_do_ioctl(struct inode *i retval = -EIO; /* fall through */ case STATE_DONE: - videobuf_dma_pci_sync(btv->dev,&buf->vb.dma); + videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma); bttv_dma_free(btv,buf); break; default: @@ -2464,7 +2504,7 @@ static int bttv_do_ioctl(struct inode *i return -EINVAL; strcpy(cap->driver,"bttv"); strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card)); - sprintf(cap->bus_info,"PCI:%s",pci_name(btv->dev)); + sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); cap->version = BTTV_VERSION_CODE; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | @@ -2768,7 +2808,7 @@ static ssize_t bttv_read(struct file *fi if (fh->btv->errors) bttv_reinit_bt848(fh->btv); dprintk("bttv%d: read count=%d type=%s\n", - fh->btv->nr,(int)count,v4l2_type_names[fh->type]); + fh->btv->c.nr,(int)count,v4l2_type_names[fh->type]); switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -2849,12 +2889,14 @@ static int bttv_open(struct inode *inode dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor); for (i = 0; i < bttv_num; i++) { - if (bttvs[i].video_dev->minor == minor) { + if (bttvs[i].video_dev && + bttvs[i].video_dev->minor == minor) { btv = &bttvs[i]; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; break; } - if (bttvs[i].vbi_dev->minor == minor) { + if (bttvs[i].vbi_dev && + bttvs[i].vbi_dev->minor == minor) { btv = &bttvs[i]; type = V4L2_BUF_TYPE_VBI_CAPTURE; break; @@ -2864,7 +2906,7 @@ static int bttv_open(struct inode *inode return -ENODEV; dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n", - btv->nr,v4l2_type_names[type]); + btv->c.nr,v4l2_type_names[type]); /* allocate per filehandle data */ fh = kmalloc(sizeof(*fh),GFP_KERNEL); @@ -2879,12 +2921,12 @@ static int bttv_open(struct inode *inode #endif videobuf_queue_init(&fh->cap, &bttv_video_qops, - btv->dev, &btv->s_lock, + btv->c.pci, &btv->s_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct bttv_buffer)); videobuf_queue_init(&fh->vbi, &bttv_vbi_qops, - btv->dev, &btv->s_lock, + btv->c.pci, &btv->s_lock, V4L2_BUF_TYPE_VBI_CAPTURE, V4L2_FIELD_SEQ_TB, sizeof(struct bttv_buffer)); @@ -2942,7 +2984,7 @@ bttv_mmap(struct file *file, struct vm_a struct bttv_fh *fh = file->private_data; dprintk("bttv%d: mmap type=%s 0x%lx+%ld\n", - fh->btv->nr, v4l2_type_names[fh->type], + fh->btv->c.nr, v4l2_type_names[fh->type], vma->vm_start, vma->vm_end - vma->vm_start); return videobuf_mmap_mapper(vma,bttv_queue(fh)); } @@ -2998,7 +3040,7 @@ static int radio_open(struct inode *inod if (NULL == btv) return -ENODEV; - dprintk("bttv%d: open called (radio)\n",btv->nr); + dprintk("bttv%d: open called (radio)\n",btv->c.nr); down(&btv->lock); if (btv->radio_user) { up(&btv->lock); @@ -3196,7 +3238,7 @@ bttv_irq_next_set(struct bttv *btv, stru dprintk("bttv%d: next set: top=%p bottom=%p vbi=%p " "[screen=%p,irq=%d,%d]\n", - btv->nr,set->top, set->bottom, set->vbi, + btv->c.nr,set->top, set->bottom, set->vbi, btv->screen,set->irqflags,set->topirq); return 0; } @@ -3218,7 +3260,7 @@ bttv_irq_wakeup_set(struct bttv *btv, st if (wakeup->top == wakeup->bottom) { if (NULL != wakeup->top && curr->top != wakeup->top) { if (irq_debug > 1) - printk("bttv%d: wakeup: both=%p\n",btv->nr,wakeup->top); + printk("bttv%d: wakeup: both=%p\n",btv->c.nr,wakeup->top); wakeup->top->vb.ts = ts; wakeup->top->vb.field_count = btv->field_count; wakeup->top->vb.state = state; @@ -3227,7 +3269,7 @@ bttv_irq_wakeup_set(struct bttv *btv, st } else { if (NULL != wakeup->top && curr->top != wakeup->top) { if (irq_debug > 1) - printk("bttv%d: wakeup: top=%p\n",btv->nr,wakeup->top); + printk("bttv%d: wakeup: top=%p\n",btv->c.nr,wakeup->top); wakeup->top->vb.ts = ts; wakeup->top->vb.field_count = btv->field_count; wakeup->top->vb.state = state; @@ -3235,7 +3277,7 @@ bttv_irq_wakeup_set(struct bttv *btv, st } if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) { if (irq_debug > 1) - printk("bttv%d: wakeup: bottom=%p\n",btv->nr,wakeup->bottom); + printk("bttv%d: wakeup: bottom=%p\n",btv->c.nr,wakeup->bottom); wakeup->bottom->vb.ts = ts; wakeup->bottom->vb.field_count = btv->field_count; wakeup->bottom->vb.state = state; @@ -3249,15 +3291,16 @@ static void bttv_irq_timeout(unsigned lo struct bttv *btv = (struct bttv *)data; struct bttv_buffer_set old,new; struct bttv_buffer *item; + unsigned long flags; if (bttv_verbose) { printk(KERN_INFO "bttv%d: timeout: risc=%08x, ", - btv->nr,btread(BT848_RISC_COUNT)); + btv->c.nr,btread(BT848_RISC_COUNT)); bttv_print_irqbits(btread(BT848_INT_STAT),0); printk("\n"); } - spin_lock(&btv->s_lock); + spin_lock_irqsave(&btv->s_lock,flags); /* deactivate stuff */ memset(&new,0,sizeof(new)); @@ -3284,7 +3327,7 @@ static void bttv_irq_timeout(unsigned lo } btv->errors++; - spin_unlock(&btv->s_lock); + spin_unlock_irqrestore(&btv->s_lock,flags); } static void @@ -3321,8 +3364,11 @@ bttv_irq_switch_fields(struct bttv *btv) rc = btread(BT848_RISC_COUNT); if (rc < btv->main.dma || rc > btv->main.dma + 0x100) { if (1 /* irq_debug */) - printk("bttv%d: skipped frame. no signal? high irq latency?\n", - btv->nr); + printk("bttv%d: skipped frame. no signal? high irq latency? " + "[main=%lx,o_vbi=%lx,rc=%lx]\n", btv->c.nr, + (unsigned long)btv->main.dma, + (unsigned long)btv->main.cpu[RISC_SLOT_O_VBI+1], + (unsigned long)rc); spin_unlock(&btv->s_lock); return; } @@ -3369,7 +3415,7 @@ static irqreturn_t bttv_irq(int irq, voi if (irq_debug) { printk(KERN_DEBUG "bttv%d: irq loop=%d fc=%d " "riscs=%x, riscc=%08x, ", - btv->nr, count, btv->field_count, + btv->c.nr, count, btv->field_count, stat>>28, btread(BT848_RISC_COUNT)); bttv_print_irqbits(stat,astat); if (stat & BT848_INT_HLOCK) @@ -3388,11 +3434,13 @@ static irqreturn_t bttv_irq(int irq, voi btv->field_count++; if (astat & BT848_INT_GPINT) { -#ifdef CONFIG_VIDEO_IR - if (btv->remote) - bttv_input_irq(btv); -#endif wake_up(&btv->gpioq); + bttv_gpio_irq(&btv->c); + } + + if (astat & BT848_INT_I2CDONE) { + btv->i2c_done = stat; + wake_up(&btv->i2c_queue); } if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) @@ -3405,7 +3453,7 @@ static irqreturn_t bttv_irq(int irq, voi audio_mux(btv, -1); if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) { - printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->nr, + printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr, (astat & BT848_INT_SCERR) ? "SCERR" : "", (astat & BT848_INT_OCERR) ? "OCERR" : "", btread(BT848_RISC_COUNT)); @@ -3416,7 +3464,7 @@ static irqreturn_t bttv_irq(int irq, voi } if (fdsr && astat & BT848_INT_FDSR) { printk(KERN_INFO "bttv%d: FDSR @ %08x\n", - btv->nr,btread(BT848_RISC_COUNT)); + btv->c.nr,btread(BT848_RISC_COUNT)); if (bttv_debug) bttv_print_riscaddr(btv); } @@ -3425,7 +3473,7 @@ static irqreturn_t bttv_irq(int irq, voi if (count > 4) { btwrite(0, BT848_INT_MASK); printk(KERN_ERR - "bttv%d: IRQ lockup, cleared int mask [", btv->nr); + "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr); bttv_print_irqbits(stat,astat); printk("]\n"); } @@ -3448,11 +3496,11 @@ static struct video_device *vdev_init(st return NULL; *vfd = *template; vfd->minor = -1; - vfd->dev = &btv->dev->dev; + vfd->dev = &btv->c.pci->dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", - type, bttv_tvcards[btv->type].name); + type, bttv_tvcards[btv->c.type].name); return vfd; } @@ -3491,7 +3539,7 @@ static int __devinit bttv_register_video if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) goto err; printk(KERN_INFO "bttv%d: registered device video%d\n", - btv->nr,btv->video_dev->minor & 0x1f); + btv->c.nr,btv->video_dev->minor & 0x1f); video_device_create_file(btv->video_dev, &class_device_attr_card); /* vbi */ @@ -3501,7 +3549,7 @@ static int __devinit bttv_register_video if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) goto err; printk(KERN_INFO "bttv%d: registered device vbi%d\n", - btv->nr,btv->vbi_dev->minor & 0x1f); + btv->c.nr,btv->vbi_dev->minor & 0x1f); if (!btv->has_radio) return 0; @@ -3512,7 +3560,7 @@ static int __devinit bttv_register_video if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) goto err; printk(KERN_INFO "bttv%d: registered device radio%d\n", - btv->nr,btv->radio_dev->minor & 0x1f); + btv->c.nr,btv->radio_dev->minor & 0x1f); /* all done */ return 0; @@ -3548,14 +3596,17 @@ static int __devinit bttv_probe(struct p printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); btv=&bttvs[bttv_num]; memset(btv,0,sizeof(*btv)); - btv->nr = bttv_num; - sprintf(btv->name,"bttv%d",btv->nr); + btv->c.nr = bttv_num; + sprintf(btv->c.name,"bttv%d",btv->c.nr); /* initialize structs / fill in defaults */ init_MUTEX(&btv->lock); init_MUTEX(&btv->reslock); - btv->s_lock = SPIN_LOCK_UNLOCKED; + btv->s_lock = SPIN_LOCK_UNLOCKED; + btv->gpio_lock = SPIN_LOCK_UNLOCKED; init_waitqueue_head(&btv->gpioq); + init_waitqueue_head(&btv->i2c_queue); + INIT_LIST_HEAD(&btv->c.subs); INIT_LIST_HEAD(&btv->capture); INIT_LIST_HEAD(&btv->vcapture); #ifdef VIDIOC_G_PRIORITY @@ -3570,33 +3621,34 @@ static int __devinit bttv_probe(struct p btv->tuner_type = UNSET; btv->pinnacle_id = UNSET; btv->new_input = UNSET; - btv->has_radio=radio[btv->nr]; + btv->gpioirq = 1; + btv->has_radio=radio[btv->c.nr]; /* pci stuff (init, get irq/mmio, ... */ - btv->dev = dev; + btv->c.pci = dev; btv->id = dev->device; if (pci_enable_device(dev)) { printk(KERN_WARNING "bttv%d: Can't enable device.\n", - btv->nr); + btv->c.nr); return -EIO; } if (pci_set_dma_mask(dev, 0xffffffff)) { printk(KERN_WARNING "bttv%d: No suitable DMA available.\n", - btv->nr); + btv->c.nr); return -EIO; } if (!request_mem_region(pci_resource_start(dev,0), pci_resource_len(dev,0), - btv->name)) { + btv->c.name)) { printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", - btv->nr, pci_resource_start(dev,0)); + btv->c.nr, pci_resource_start(dev,0)); return -EBUSY; } pci_set_master(dev); pci_set_command(dev); pci_set_drvdata(dev,btv); if (!pci_dma_supported(dev,0xffffffff)) { - printk("bttv%d: Oops: no 32bit PCI DMA ???\n", btv->nr); + printk("bttv%d: Oops: no 32bit PCI DMA ???\n", btv->c.nr); result = -EIO; goto fail1; } @@ -3606,12 +3658,12 @@ static int __devinit bttv_probe(struct p printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", bttv_num,btv->id, btv->revision, pci_name(dev)); printk("irq: %d, latency: %d, mmio: 0x%lx\n", - btv->dev->irq, lat, pci_resource_start(dev,0)); + btv->c.pci->irq, lat, pci_resource_start(dev,0)); schedule(); btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000); if (NULL == ioremap(pci_resource_start(dev,0), 0x1000)) { - printk("bttv%d: ioremap() failed\n", btv->nr); + printk("bttv%d: ioremap() failed\n", btv->c.nr); result = -EIO; goto fail1; } @@ -3621,11 +3673,11 @@ static int __devinit bttv_probe(struct p /* disable irqs, register irq handler */ btwrite(0, BT848_INT_MASK); - result = request_irq(btv->dev->irq, bttv_irq, - SA_SHIRQ | SA_INTERRUPT,btv->name,(void *)btv); + result = request_irq(btv->c.pci->irq, bttv_irq, + SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv); if (result < 0) { printk(KERN_ERR "bttv%d: can't get IRQ %d\n", - bttv_num,btv->dev->irq); + bttv_num,btv->c.pci->irq); goto fail1; } @@ -3641,6 +3693,8 @@ static int __devinit bttv_probe(struct p btv->opt_chroma_agc = chroma_agc; btv->opt_adc_crush = adc_crush; btv->opt_vcr_hack = vcr_hack; + btv->opt_whitecrush_upper = whitecrush_upper; + btv->opt_whitecrush_lower = whitecrush_lower; /* fill struct bttv with some useful defaults */ btv->init.btv = btv; @@ -3657,31 +3711,26 @@ static int __devinit bttv_probe(struct p bttv_gpio_tracking(btv,"pre-init"); bttv_risc_init_main(btv); - if (!bttv_tvcards[btv->type].no_video) - init_bt848(btv); + init_bt848(btv); /* gpio */ btwrite(0x00, BT848_GPIO_REG_INP); btwrite(0x00, BT848_GPIO_OUT_EN); - if (bttv_gpio) + if (bttv_verbose) bttv_gpio_tracking(btv,"init"); /* needs to be done before i2c is registered */ bttv_init_card1(btv); - /* register i2c */ + /* register i2c + gpio */ init_bttv_i2c(btv); /* some card-specific stuff (needs working i2c) */ bttv_init_card2(btv); /* register video4linux + input */ - if (!bttv_tvcards[btv->type].no_video) { + if (!bttv_tvcards[btv->c.type].no_video) { bttv_register_video(btv); -#ifdef CONFIG_VIDEO_IR - bttv_input_init(btv); -#endif - bt848_bright(btv,32768); bt848_contrast(btv,32768); bt848_hue(btv,32768); @@ -3690,18 +3739,24 @@ static int __devinit bttv_probe(struct p set_input(btv,0); } + /* add subdevices */ + if (btv->has_remote) + bttv_sub_add_device(&btv->c, "remote"); + if (bttv_tvcards[btv->c.type].has_dvb) + bttv_sub_add_device(&btv->c, "dvb"); + /* everything is fine */ bttv_num++; return 0; fail2: - free_irq(btv->dev->irq,btv); + free_irq(btv->c.pci->irq,btv); fail1: if (btv->bt848_mmio) iounmap(btv->bt848_mmio); - release_mem_region(pci_resource_start(btv->dev,0), - pci_resource_len(btv->dev,0)); + release_mem_region(pci_resource_start(btv->c.pci,0), + pci_resource_len(btv->c.pci,0)); pci_set_drvdata(dev,NULL); return result; } @@ -3711,7 +3766,7 @@ static void __devexit bttv_remove(struct struct bttv *btv = pci_get_drvdata(pci_dev); if (bttv_verbose) - printk("bttv%d: unloading\n",btv->nr); + printk("bttv%d: unloading\n",btv->c.nr); /* shutdown everything (DMA+IRQs) */ btand(~15, BT848_GPIO_DMA_CTL); @@ -3724,29 +3779,92 @@ static void __devexit bttv_remove(struct /* tell gpio modules we are leaving ... */ btv->shutdown=1; wake_up(&btv->gpioq); - + bttv_sub_del_devices(&btv->c); + /* unregister i2c_bus + input */ fini_bttv_i2c(btv); -#ifdef CONFIG_VIDEO_IR - bttv_input_fini(btv); -#endif /* unregister video4linux */ bttv_unregister_video(btv); /* free allocated memory */ - btcx_riscmem_free(btv->dev,&btv->main); + btcx_riscmem_free(btv->c.pci,&btv->main); /* free ressources */ - free_irq(btv->dev->irq,btv); + free_irq(btv->c.pci->irq,btv); iounmap(btv->bt848_mmio); - release_mem_region(pci_resource_start(btv->dev,0), - pci_resource_len(btv->dev,0)); + release_mem_region(pci_resource_start(btv->c.pci,0), + pci_resource_len(btv->c.pci,0)); pci_set_drvdata(pci_dev, NULL); return; } +static int bttv_suspend(struct pci_dev *pci_dev, u32 state) +{ + struct bttv *btv = pci_get_drvdata(pci_dev); + struct bttv_buffer_set idle; + unsigned long flags; + + printk("bttv%d: suspend %d\n", btv->c.nr, state); + + /* stop dma + irqs */ + spin_lock_irqsave(&btv->s_lock,flags); + memset(&idle, 0, sizeof(idle)); + btv->state.set = btv->curr; + btv->curr = idle; + bttv_buffer_set_activate(btv, &idle); + bttv_set_dma(btv, 0, 0); + btwrite(0, BT848_INT_MASK); + spin_unlock_irqrestore(&btv->s_lock,flags); + + /* save bt878 state */ + btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN); + btv->state.gpio_data = gpio_read(); + + /* save pci state */ + pci_save_state(pci_dev, btv->state.pci_cfg); + if (0 != pci_set_power_state(pci_dev, state)) { + pci_disable_device(pci_dev); + btv->state.disabled = 1; + } + return 0; +} + +static int bttv_resume(struct pci_dev *pci_dev) +{ + struct bttv *btv = pci_get_drvdata(pci_dev); + unsigned long flags; + + printk("bttv%d: resume\n", btv->c.nr); + + /* restore pci state */ + if (btv->state.disabled) { + pci_enable_device(pci_dev); + btv->state.disabled = 0; + } + pci_set_power_state(pci_dev, 0); + pci_restore_state(pci_dev, btv->state.pci_cfg); + + /* restore bt878 state */ + bttv_reinit_bt848(btv); + gpio_inout(0xffffff, btv->state.gpio_enable); + gpio_write(btv->state.gpio_data); + + bt848_bright(btv, btv->bright); + bt848_hue(btv, btv->hue); + bt848_contrast(btv, btv->contrast); + bt848_sat(btv, btv->saturation); + + /* restart dma */ + spin_lock_irqsave(&btv->s_lock,flags); + btv->curr = btv->state.set; + bttv_buffer_set_activate(btv, &btv->curr); + bttv_set_dma(btv, 0, btv->curr.irqflags); + spin_unlock_irqrestore(&btv->s_lock,flags); + return 0; +} + static struct pci_device_id bttv_pci_tbl[] = { {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -3766,6 +3884,9 @@ static struct pci_driver bttv_pci_driver .id_table = bttv_pci_tbl, .probe = bttv_probe, .remove = __devexit_p(bttv_remove), + + .suspend = bttv_suspend, + .resume = bttv_resume, }; static int bttv_init_module(void) @@ -3777,6 +3898,10 @@ static int bttv_init_module(void) (BTTV_VERSION_CODE >> 16) & 0xff, (BTTV_VERSION_CODE >> 8) & 0xff, BTTV_VERSION_CODE & 0xff); +#ifdef SNAPSHOT + printk(KERN_INFO "bttv: snapshot date %04d-%02d-%02d\n", + SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); +#endif if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) gbuffers = 2; if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF) @@ -3788,6 +3913,7 @@ static int bttv_init_module(void) bttv_check_chipset(); + bus_register(&bttv_sub_bus_type); rc = pci_module_init(&bttv_pci_driver); if (-ENODEV == rc) { /* plenty of people trying to use bttv for the cx2388x ... */ @@ -3800,6 +3926,7 @@ static int bttv_init_module(void) static void bttv_cleanup_module(void) { pci_unregister_driver(&bttv_pci_driver); + bus_unregister(&bttv_sub_bus_type); return; } diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttv-gpio.c 780-bttv/drivers/media/video/bttv-gpio.c --- 770-tuner/drivers/media/video/bttv-gpio.c Wed Dec 31 16:00:00 1969 +++ 780-bttv/drivers/media/video/bttv-gpio.c Fri Jan 9 23:11:34 2004 @@ -0,0 +1,183 @@ +/* + bttv-gpio.c -- gpio sub drivers + + sysfs-based sub driver interface for bttv + mainly intented for gpio access + + + Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + & Marcus Metzler (mocm@thp.uni-koeln.de) + (c) 1999-2003 Gerd Knorr + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include + +#include "bttvp.h" + +/* ----------------------------------------------------------------------- */ +/* internal: the bttv "bus" */ + +static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv) +{ + struct bttv_sub_driver *sub = to_bttv_sub_drv(drv); + int len = strlen(sub->wanted); + + if (0 == strncmp(dev->bus_id, sub->wanted, len)) + return 1; + return 0; +} + +struct bus_type bttv_sub_bus_type = { + .name = "bttv-sub", + .match = &bttv_sub_bus_match, +}; +EXPORT_SYMBOL(bttv_sub_bus_type); + +static void release_sub_device(struct device *dev) +{ + struct bttv_sub_device *sub = to_bttv_sub_dev(dev); + kfree(sub); +} + +int bttv_sub_add_device(struct bttv_core *core, char *name) +{ + struct bttv_sub_device *sub; + + sub = kmalloc(sizeof(*sub),GFP_KERNEL); + if (NULL == sub) + return -ENOMEM; + memset(sub,0,sizeof(*sub)); + + sub->core = core; + sub->dev.parent = &core->pci->dev; + sub->dev.bus = &bttv_sub_bus_type; + sub->dev.release = release_sub_device; + snprintf(sub->dev.bus_id,sizeof(sub->dev.bus_id),"%s%d", + name, core->nr); + + printk("bttv%d: add subdevice \"%s\"\n", core->nr, sub->dev.bus_id); + list_add_tail(&sub->list,&core->subs); + device_register(&sub->dev); + return 0; +} + +int bttv_sub_del_devices(struct bttv_core *core) +{ + struct bttv_sub_device *sub; + struct list_head *item,*save; + + list_for_each_safe(item,save,&core->subs) { + sub = list_entry(item,struct bttv_sub_device,list); + device_unregister(&sub->dev); + } + return 0; +} + +void bttv_gpio_irq(struct bttv_core *core) +{ + struct bttv_sub_driver *drv; + struct bttv_sub_device *dev; + struct list_head *item; + + list_for_each(item,&core->subs) { + dev = list_entry(item,struct bttv_sub_device,list); + drv = to_bttv_sub_drv(dev->dev.driver); + if (drv && drv->gpio_irq) + drv->gpio_irq(dev); + } +} + +/* ----------------------------------------------------------------------- */ +/* external: sub-driver register/unregister */ + +int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted) +{ + sub->drv.bus = &bttv_sub_bus_type; + snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted); + driver_register(&sub->drv); + return 0; +} +EXPORT_SYMBOL(bttv_sub_register); + +int bttv_sub_unregister(struct bttv_sub_driver *sub) +{ + driver_unregister(&sub->drv); + return 0; +} +EXPORT_SYMBOL(bttv_sub_unregister); + +/* ----------------------------------------------------------------------- */ +/* external: gpio access functions */ + +void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits) +{ + struct bttv *btv = container_of(core, struct bttv, c); + unsigned long flags; + u32 data; + + spin_lock_irqsave(&btv->gpio_lock,flags); + data = btread(BT848_GPIO_OUT_EN); + data = data & ~mask; + data = data | (mask & outbits); + btwrite(data,BT848_GPIO_OUT_EN); + spin_unlock_irqrestore(&btv->gpio_lock,flags); +} +EXPORT_SYMBOL(bttv_gpio_inout); + +u32 bttv_gpio_read(struct bttv_core *core) +{ + struct bttv *btv = container_of(core, struct bttv, c); + u32 value; + + value = btread(BT848_GPIO_DATA); + return value; +} +EXPORT_SYMBOL(bttv_gpio_read); + +void bttv_gpio_write(struct bttv_core *core, u32 value) +{ + struct bttv *btv = container_of(core, struct bttv, c); + + btwrite(value,BT848_GPIO_DATA); +} +EXPORT_SYMBOL(bttv_gpio_write); + +void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits) +{ + struct bttv *btv = container_of(core, struct bttv, c); + unsigned long flags; + u32 data; + + spin_lock_irqsave(&btv->gpio_lock,flags); + data = btread(BT848_GPIO_DATA); + data = data & ~mask; + data = data | (mask & bits); + btwrite(data,BT848_GPIO_DATA); + spin_unlock_irqrestore(&btv->gpio_lock,flags); +} +EXPORT_SYMBOL(bttv_gpio_bits); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttv-i2c.c 780-bttv/drivers/media/video/bttv-i2c.c --- 770-tuner/drivers/media/video/bttv-i2c.c Wed Dec 31 16:00:00 1969 +++ 780-bttv/drivers/media/video/bttv-i2c.c Fri Jan 9 23:11:34 2004 @@ -0,0 +1,471 @@ +/* + bttv-i2c.c -- all the i2c code is here + + bttv - Bt848 frame grabber driver + + Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + & Marcus Metzler (mocm@thp.uni-koeln.de) + (c) 1999-2003 Gerd Knorr + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include + +#include "bttvp.h" + +static struct i2c_algo_bit_data bttv_i2c_algo_bit_template; +static struct i2c_adapter bttv_i2c_adap_sw_template; +static struct i2c_adapter bttv_i2c_adap_hw_template; +static struct i2c_client bttv_i2c_client_template; + +#ifndef I2C_PEC +static void bttv_inc_use(struct i2c_adapter *adap); +static void bttv_dec_use(struct i2c_adapter *adap); +#endif +static int attach_inform(struct i2c_client *client); + +static int i2c_debug = 0; +static int i2c_hw = 0; +MODULE_PARM(i2c_debug,"i"); +MODULE_PARM(i2c_hw,"i"); + +/* ----------------------------------------------------------------------- */ +/* I2C functions - bitbanging adapter (software i2c) */ + +void bttv_bit_setscl(void *data, int state) +{ + struct bttv *btv = (struct bttv*)data; + + if (state) + btv->i2c_state |= 0x02; + else + btv->i2c_state &= ~0x02; + btwrite(btv->i2c_state, BT848_I2C); + btread(BT848_I2C); +} + +void bttv_bit_setsda(void *data, int state) +{ + struct bttv *btv = (struct bttv*)data; + + if (state) + btv->i2c_state |= 0x01; + else + btv->i2c_state &= ~0x01; + btwrite(btv->i2c_state, BT848_I2C); + btread(BT848_I2C); +} + +static int bttv_bit_getscl(void *data) +{ + struct bttv *btv = (struct bttv*)data; + int state; + + state = btread(BT848_I2C) & 0x02 ? 1 : 0; + return state; +} + +static int bttv_bit_getsda(void *data) +{ + struct bttv *btv = (struct bttv*)data; + int state; + + state = btread(BT848_I2C) & 0x01; + return state; +} + +static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { + .setsda = bttv_bit_setsda, + .setscl = bttv_bit_setscl, + .getsda = bttv_bit_getsda, + .getscl = bttv_bit_getscl, + .udelay = 16, + .mdelay = 10, + .timeout = 200, +}; + +static struct i2c_adapter bttv_i2c_adap_sw_template = { +#ifdef I2C_PEC + .owner = THIS_MODULE, +#else + .inc_use = bttv_inc_use, + .dec_use = bttv_dec_use, +#endif +#ifdef I2C_ADAP_CLASS_TV_ANALOG + .class = I2C_ADAP_CLASS_TV_ANALOG, +#endif + I2C_DEVNAME("bt848"), + .id = I2C_HW_B_BT848, + .client_register = attach_inform, +}; + +/* ----------------------------------------------------------------------- */ +/* I2C functions - hardware i2c */ + +static int algo_control(struct i2c_adapter *adapter, + unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static u32 functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_SMBUS_EMUL; +} + +static int +bttv_i2c_wait_done(struct bttv *btv) +{ + DECLARE_WAITQUEUE(wait, current); + int rc = 0; + + add_wait_queue(&btv->i2c_queue, &wait); + set_current_state(TASK_INTERRUPTIBLE); + if (0 == btv->i2c_done) + schedule_timeout(HZ/50+1); + set_current_state(TASK_RUNNING); + remove_wait_queue(&btv->i2c_queue, &wait); + + if (0 == btv->i2c_done) + /* timeout */ + rc = -EIO; + if (btv->i2c_done & BT848_INT_RACK) + rc = 1; + btv->i2c_done = 0; + return rc; +} + +#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\ + BT848_I2C_SCL | BT848_I2C_SDA) + +static int +bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last) +{ + u32 xmit; + int retval,cnt; + + /* sanity checks */ + if (0 == msg->len) + return -EINVAL; + + /* start, address + first byte */ + xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW; + if (msg->len > 1 || !last) + xmit |= BT878_I2C_NOSTOP; + btwrite(xmit, BT848_I2C); + retval = bttv_i2c_wait_done(btv); + if (retval < 0) + goto err; + if (retval == 0) + goto eio; + if (i2c_debug) { + printk(" addr << 1, msg->buf[0]); + if (!(xmit & BT878_I2C_NOSTOP)) + printk(" >\n"); + } + + for (cnt = 1; cnt < msg->len; cnt++ ) { + /* following bytes */ + xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART; + if (cnt < msg->len-1 || !last) + xmit |= BT878_I2C_NOSTOP; + btwrite(xmit, BT848_I2C); + retval = bttv_i2c_wait_done(btv); + if (retval < 0) + goto err; + if (retval == 0) + goto eio; + if (i2c_debug) { + printk(" %02x", msg->buf[cnt]); + if (!(xmit & BT878_I2C_NOSTOP)) + printk(" >\n"); + } + } + return msg->len; + + eio: + retval = -EIO; + err: + if (i2c_debug) + printk(" ERR: %d\n",retval); + return retval; +} + +static int +bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last) +{ + u32 xmit; + u32 cnt; + int retval; + + for(cnt = 0; cnt < msg->len; cnt++) { + xmit = (msg->addr << 25) | (1 << 24) | I2C_HW; + if (cnt < msg->len-1) + xmit |= BT848_I2C_W3B; + if (cnt < msg->len-1 || !last) + xmit |= BT878_I2C_NOSTOP; + if (cnt) + xmit |= BT878_I2C_NOSTART; + btwrite(xmit, BT848_I2C); + retval = bttv_i2c_wait_done(btv); + if (retval < 0) + goto err; + if (retval == 0) + goto eio; + msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff; + if (i2c_debug) { + if (!(xmit & BT878_I2C_NOSTART)) + printk(" addr << 1) +1); + printk(" =%02x", msg->buf[cnt]); + if (!(xmit & BT878_I2C_NOSTOP)) + printk(" >\n"); + } + } + return msg->len; + + eio: + retval = -EIO; + err: + if (i2c_debug) + printk(" ERR: %d\n",retval); + return retval; +} + +int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +{ + struct bttv *btv = i2c_get_adapdata(i2c_adap); + int retval = 0; + int i; + + if (i2c_debug) + printk("bt-i2c:"); + btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT); + for (i = 0 ; i < num; i++) { + if (msgs[i].flags & I2C_M_RD) { + /* read */ + retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num); + if (retval < 0) + goto err; + } else { + /* write */ + retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num); + if (retval < 0) + goto err; + } + } + return num; + + err: + return retval; +} + +static struct i2c_algorithm bttv_algo = { + .name = "bt878", + .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, + .master_xfer = bttv_i2c_xfer, + .algo_control = algo_control, + .functionality = functionality, +}; + +static struct i2c_adapter bttv_i2c_adap_hw_template = { +#ifdef I2C_PEC + .owner = THIS_MODULE, +#else + .inc_use = bttv_inc_use, + .dec_use = bttv_dec_use, +#endif +#ifdef I2C_ADAP_CLASS_TV_ANALOG + .class = I2C_ADAP_CLASS_TV_ANALOG, +#endif + I2C_DEVNAME("bt878"), + .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, + .algo = &bttv_algo, + .client_register = attach_inform, +}; + +/* ----------------------------------------------------------------------- */ +/* I2C functions - common stuff */ + +#ifndef I2C_PEC +static void bttv_inc_use(struct i2c_adapter *adap) +{ + MOD_INC_USE_COUNT; +} + +static void bttv_dec_use(struct i2c_adapter *adap) +{ + MOD_DEC_USE_COUNT; +} +#endif + +static int attach_inform(struct i2c_client *client) +{ + struct bttv *btv = i2c_get_adapdata(client->adapter); + + if (btv->tuner_type != UNSET) + bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type); + if (btv->pinnacle_id != UNSET) + bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE, + &btv->pinnacle_id); + + if (bttv_debug) + printk("bttv%d: i2c attach [client=%s]\n", + btv->c.nr, i2c_clientname(client)); + return 0; +} + +void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) +{ + if (0 != btv->i2c_rc) + return; + i2c_clients_command(&btv->c.i2c_adap, cmd, arg); +} + +void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg) +{ + if (card >= bttv_num) + return; + bttv_call_i2c_clients(&bttvs[card], cmd, arg); +} + +static struct i2c_client bttv_i2c_client_template = { + I2C_DEVNAME("bttv internal"), + .id = -1, +}; + + +/* read I2C */ +int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) +{ + unsigned char buffer = 0; + + if (0 != btv->i2c_rc) + return -1; + if (bttv_verbose && NULL != probe_for) + printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", + btv->c.nr,probe_for,addr); + btv->i2c_client.addr = addr >> 1; + if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { + if (NULL != probe_for) { + if (bttv_verbose) + printk("not found\n"); + } else + printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", + btv->c.nr,addr); + return -1; + } + if (bttv_verbose && NULL != probe_for) + printk("found\n"); + return buffer; +} + +/* write I2C */ +int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, + unsigned char b2, int both) +{ + unsigned char buffer[2]; + int bytes = both ? 2 : 1; + + if (0 != btv->i2c_rc) + return -1; + btv->i2c_client.addr = addr >> 1; + buffer[0] = b1; + buffer[1] = b2; + if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) + return -1; + return 0; +} + +/* read EEPROM content */ +void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) +{ + int i; + + if (bttv_I2CWrite(btv, addr, 0, -1, 0)<0) { + printk(KERN_WARNING "bttv: readee error\n"); + return; + } + btv->i2c_client.addr = addr >> 1; + for (i=0; i<256; i+=16) { + if (16 != i2c_master_recv(&btv->i2c_client,eedata+i,16)) { + printk(KERN_WARNING "bttv: readee error\n"); + break; + } + } +} + +/* init + register i2c algo-bit adapter */ +int __devinit init_bttv_i2c(struct bttv *btv) +{ + int use_hw = (btv->id == 878) && i2c_hw; + + memcpy(&btv->i2c_client, &bttv_i2c_client_template, + sizeof(bttv_i2c_client_template)); + + if (use_hw) { + /* bt878 */ + memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_hw_template, + sizeof(bttv_i2c_adap_hw_template)); + } else { + /* bt848 */ + memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template, + sizeof(bttv_i2c_adap_sw_template)); + memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template, + sizeof(bttv_i2c_algo_bit_template)); + btv->i2c_algo.data = btv; + btv->c.i2c_adap.algo_data = &btv->i2c_algo; + } + + btv->c.i2c_adap.dev.parent = &btv->c.pci->dev; + snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name), + "bt%d #%d [%s]", btv->id, btv->c.nr, use_hw ? "hw" : "sw"); + + i2c_set_adapdata(&btv->c.i2c_adap, btv); + btv->i2c_client.adapter = &btv->c.i2c_adap; + + if (use_hw) { + btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); + } else { + bttv_bit_setscl(btv,1); + bttv_bit_setsda(btv,1); + btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap); + } + return btv->i2c_rc; +} + +int __devexit fini_bttv_i2c(struct bttv *btv) +{ + int use_hw = (btv->id == 878) && i2c_hw; + + if (0 != btv->i2c_rc) + return 0; + + if (use_hw) { + return i2c_del_adapter(&btv->c.i2c_adap); + } else { + return i2c_bit_del_bus(&btv->c.i2c_adap); + } +} + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttv-if.c 780-bttv/drivers/media/video/bttv-if.c --- 770-tuner/drivers/media/video/bttv-if.c Mon Dec 8 09:55:51 2003 +++ 780-bttv/drivers/media/video/bttv-if.c Fri Jan 9 23:11:34 2004 @@ -1,7 +1,7 @@ /* - bttv-if.c -- interfaces to other kernel modules - all the i2c code is here - also the gpio interface exported by bttv (used by lirc) + bttv-if.c -- old gpio interface to other kernel modules + don't use in new code, will go away in 2.7 + have a look at bttv-gpio.c instead. bttv - Bt848 frame grabber driver @@ -28,22 +28,10 @@ #include #include #include - #include #include "bttvp.h" -static struct i2c_algo_bit_data bttv_i2c_algo_bit_template; -static struct i2c_adapter bttv_i2c_adap_sw_template; -static struct i2c_adapter bttv_i2c_adap_hw_template; -static struct i2c_client bttv_i2c_client_template; - -#ifndef I2C_PEC -static void bttv_inc_use(struct i2c_adapter *adap); -static void bttv_dec_use(struct i2c_adapter *adap); -#endif -static int attach_inform(struct i2c_client *client); - EXPORT_SYMBOL(bttv_get_cardinfo); EXPORT_SYMBOL(bttv_get_pcidev); EXPORT_SYMBOL(bttv_get_id); @@ -53,11 +41,6 @@ EXPORT_SYMBOL(bttv_write_gpio); EXPORT_SYMBOL(bttv_get_gpio_queue); EXPORT_SYMBOL(bttv_i2c_call); -static int i2c_debug = 0; -static int i2c_hw = 0; -MODULE_PARM(i2c_debug,"i"); -MODULE_PARM(i2c_hw,"i"); - /* ----------------------------------------------------------------------- */ /* Exported functions - for other modules which want to access the */ /* gpio ports (IR for example) */ @@ -68,7 +51,7 @@ int bttv_get_cardinfo(unsigned int card, if (card >= bttv_num) { return -1; } - *type = bttvs[card].type; + *type = bttvs[card].c.type; *cardid = bttvs[card].cardid; return 0; } @@ -77,7 +60,7 @@ struct pci_dev* bttv_get_pcidev(unsigned { if (card >= bttv_num) return NULL; - return bttvs[card].dev; + return bttvs[card].c.pci; } int bttv_get_id(unsigned int card) @@ -86,7 +69,7 @@ int bttv_get_id(unsigned int card) if (card >= bttv_num) { return -1; } - return bttvs[card].type; + return bttvs[card].c.type; } @@ -99,7 +82,7 @@ int bttv_gpio_enable(unsigned int card, } btv = &bttvs[card]; - btaor(data, ~mask, BT848_GPIO_OUT_EN); + gpio_inout(mask,data); if (bttv_gpio) bttv_gpio_tracking(btv,"extern enable"); return 0; @@ -121,7 +104,7 @@ int bttv_read_gpio(unsigned int card, un /* prior setting BT848_GPIO_REG_INP is (probably) not needed because we set direct input on init */ - *data = btread(BT848_GPIO_DATA); + *data = gpio_read(); return 0; } @@ -137,7 +120,7 @@ int bttv_write_gpio(unsigned int card, u /* prior setting BT848_GPIO_REG_INP is (probably) not needed because direct input is set on init */ - btaor(data & mask, ~mask, BT848_GPIO_DATA); + gpio_bits(mask,data); if (bttv_gpio) bttv_gpio_tracking(btv,"extern write"); return 0; @@ -156,418 +139,6 @@ wait_queue_head_t* bttv_get_gpio_queue(u return NULL; } return &btv->gpioq; -} - - -/* ----------------------------------------------------------------------- */ -/* I2C functions - bitbanging adapter (software i2c) */ - -void bttv_bit_setscl(void *data, int state) -{ - struct bttv *btv = (struct bttv*)data; - - if (state) - btv->i2c_state |= 0x02; - else - btv->i2c_state &= ~0x02; - btwrite(btv->i2c_state, BT848_I2C); - btread(BT848_I2C); -} - -void bttv_bit_setsda(void *data, int state) -{ - struct bttv *btv = (struct bttv*)data; - - if (state) - btv->i2c_state |= 0x01; - else - btv->i2c_state &= ~0x01; - btwrite(btv->i2c_state, BT848_I2C); - btread(BT848_I2C); -} - -static int bttv_bit_getscl(void *data) -{ - struct bttv *btv = (struct bttv*)data; - int state; - - state = btread(BT848_I2C) & 0x02 ? 1 : 0; - return state; -} - -static int bttv_bit_getsda(void *data) -{ - struct bttv *btv = (struct bttv*)data; - int state; - - state = btread(BT848_I2C) & 0x01; - return state; -} - -static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { - .setsda = bttv_bit_setsda, - .setscl = bttv_bit_setscl, - .getsda = bttv_bit_getsda, - .getscl = bttv_bit_getscl, - .udelay = 16, - .mdelay = 10, - .timeout = 200, -}; - -static struct i2c_adapter bttv_i2c_adap_sw_template = { -#ifdef I2C_PEC - .owner = THIS_MODULE, -#else - .inc_use = bttv_inc_use, - .dec_use = bttv_dec_use, -#endif -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, -#endif - I2C_DEVNAME("bt848"), - .id = I2C_HW_B_BT848, - .client_register = attach_inform, -}; - -/* ----------------------------------------------------------------------- */ -/* I2C functions - hardware i2c */ - -static int algo_control(struct i2c_adapter *adapter, - unsigned int cmd, unsigned long arg) -{ - return 0; -} - -static u32 functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL; -} - -static int -bttv_i2c_wait_done(struct bttv *btv) -{ - u32 stat; - unsigned long timeout; - - timeout = jiffies + HZ/100 + 1; /* 10ms */ - for (;;) { - stat = btread(BT848_INT_STAT); - if (stat & BT848_INT_I2CDONE) - break; - if (time_after(jiffies,timeout)) - return -EIO; - udelay(10); - } - btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT); - return ((stat & BT848_INT_RACK) ? 1 : 0); -} - -#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\ - BT848_I2C_SCL | BT848_I2C_SDA) - -static int -bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last) -{ - u32 xmit; - int retval,cnt; - - /* start, address + first byte */ - xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW; - if (msg->len > 1 || !last) - xmit |= BT878_I2C_NOSTOP; - btwrite(xmit, BT848_I2C); - retval = bttv_i2c_wait_done(btv); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - if (i2c_debug) { - printk(" addr << 1, msg->buf[0]); - if (!(xmit & BT878_I2C_NOSTOP)) - printk(" >\n"); - } - - for (cnt = 1; cnt < msg->len; cnt++ ) { - /* following bytes */ - xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART; - if (cnt < msg->len-1 || !last) - xmit |= BT878_I2C_NOSTOP; - btwrite(xmit, BT848_I2C); - retval = bttv_i2c_wait_done(btv); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - if (i2c_debug) { - printk(" %02x", msg->buf[cnt]); - if (!(xmit & BT878_I2C_NOSTOP)) - printk(" >\n"); - } - } - return msg->len; - - eio: - retval = -EIO; - err: - if (i2c_debug) - printk(" ERR: %d\n",retval); - return retval; -} - -static int -bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last) -{ - u32 xmit; - u32 cnt; - int retval; - - for(cnt = 0; cnt < msg->len; cnt++) { - xmit = (msg->addr << 25) | (1 << 24) | I2C_HW; - if (cnt < msg->len-1) - xmit |= BT848_I2C_W3B; - if (cnt < msg->len-1 || !last) - xmit |= BT878_I2C_NOSTOP; - if (cnt) - xmit |= BT878_I2C_NOSTART; - btwrite(xmit, BT848_I2C); - retval = bttv_i2c_wait_done(btv); - if (retval < 0) - goto err; - if (retval == 0) - goto eio; - msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff; - if (i2c_debug) { - if (!(xmit & BT878_I2C_NOSTART)) - printk(" addr << 1) +1); - printk(" =%02x", msg->buf[cnt]); - if (!(xmit & BT878_I2C_NOSTOP)) - printk(" >\n"); - } - } - return msg->len; - - eio: - retval = -EIO; - err: - if (i2c_debug) - printk(" ERR: %d\n",retval); - return retval; -} - -int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) -{ - struct bttv *btv = i2c_get_adapdata(i2c_adap); - int retval = 0; - int i; - - if (i2c_debug) - printk("bt-i2c:"); - btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT); - for (i = 0 ; i < num; i++) { - if (msgs[i].flags & I2C_M_RD) { - /* read */ - retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num); - if (retval < 0) - goto err; - } else { - /* write */ - retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num); - if (retval < 0) - goto err; - } - } - return num; - - err: - return retval; -} - -static struct i2c_algorithm bttv_algo = { - .name = "bt878", - .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, - .master_xfer = bttv_i2c_xfer, - .algo_control = algo_control, - .functionality = functionality, -}; - -static struct i2c_adapter bttv_i2c_adap_hw_template = { -#ifdef I2C_PEC - .owner = THIS_MODULE, -#else - .inc_use = bttv_inc_use, - .dec_use = bttv_dec_use, -#endif -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, -#endif - I2C_DEVNAME("bt878"), - .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, - .algo = &bttv_algo, - .client_register = attach_inform, -}; - -/* ----------------------------------------------------------------------- */ -/* I2C functions - common stuff */ - -#ifndef I2C_PEC -static void bttv_inc_use(struct i2c_adapter *adap) -{ - MOD_INC_USE_COUNT; -} - -static void bttv_dec_use(struct i2c_adapter *adap) -{ - MOD_DEC_USE_COUNT; -} -#endif - -static int attach_inform(struct i2c_client *client) -{ - struct bttv *btv = i2c_get_adapdata(client->adapter); - - if (btv->tuner_type != UNSET) - bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type); - if (btv->pinnacle_id != UNSET) - bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE, - &btv->pinnacle_id); - - if (bttv_debug) - printk("bttv%d: i2c attach [client=%s]\n", - btv->nr, i2c_clientname(client)); - return 0; -} - -void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) -{ - if (0 != btv->i2c_rc) - return; - i2c_clients_command(&btv->i2c_adap, cmd, arg); -} - -void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg) -{ - if (card >= bttv_num) - return; - bttv_call_i2c_clients(&bttvs[card], cmd, arg); -} - -static struct i2c_client bttv_i2c_client_template = { - I2C_DEVNAME("bttv internal"), - .id = -1, -}; - - -/* read I2C */ -int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) -{ - unsigned char buffer = 0; - - if (0 != btv->i2c_rc) - return -1; - if (bttv_verbose && NULL != probe_for) - printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", - btv->nr,probe_for,addr); - btv->i2c_client.addr = addr >> 1; - if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { - if (NULL != probe_for) { - if (bttv_verbose) - printk("not found\n"); - } else - printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", - btv->nr,addr); - return -1; - } - if (bttv_verbose && NULL != probe_for) - printk("found\n"); - return buffer; -} - -/* write I2C */ -int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, - unsigned char b2, int both) -{ - unsigned char buffer[2]; - int bytes = both ? 2 : 1; - - if (0 != btv->i2c_rc) - return -1; - btv->i2c_client.addr = addr >> 1; - buffer[0] = b1; - buffer[1] = b2; - if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) - return -1; - return 0; -} - -/* read EEPROM content */ -void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) -{ - int i; - - if (bttv_I2CWrite(btv, addr, 0, -1, 0)<0) { - printk(KERN_WARNING "bttv: readee error\n"); - return; - } - btv->i2c_client.addr = addr >> 1; - for (i=0; i<256; i+=16) { - if (16 != i2c_master_recv(&btv->i2c_client,eedata+i,16)) { - printk(KERN_WARNING "bttv: readee error\n"); - break; - } - } -} - -/* init + register i2c algo-bit adapter */ -int __devinit init_bttv_i2c(struct bttv *btv) -{ - int use_hw = (btv->id == 878) && i2c_hw; - - memcpy(&btv->i2c_client, &bttv_i2c_client_template, - sizeof(bttv_i2c_client_template)); - - if (use_hw) { - /* bt878 */ - memcpy(&btv->i2c_adap, &bttv_i2c_adap_hw_template, - sizeof(bttv_i2c_adap_hw_template)); - } else { - /* bt848 */ - memcpy(&btv->i2c_adap, &bttv_i2c_adap_sw_template, - sizeof(bttv_i2c_adap_sw_template)); - memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template, - sizeof(bttv_i2c_algo_bit_template)); - btv->i2c_algo.data = btv; - btv->i2c_adap.algo_data = &btv->i2c_algo; - } - - btv->i2c_adap.dev.parent = &btv->dev->dev; - snprintf(btv->i2c_adap.name, sizeof(btv->i2c_adap.name), - "bt%d #%d [%s]", btv->id, btv->nr, use_hw ? "hw" : "sw"); - - i2c_set_adapdata(&btv->i2c_adap, btv); - btv->i2c_client.adapter = &btv->i2c_adap; - - if (use_hw) { - btv->i2c_rc = i2c_add_adapter(&btv->i2c_adap); - } else { - bttv_bit_setscl(btv,1); - bttv_bit_setsda(btv,1); - btv->i2c_rc = i2c_bit_add_bus(&btv->i2c_adap); - } - return btv->i2c_rc; -} - -int __devexit fini_bttv_i2c(struct bttv *btv) -{ - int use_hw = (btv->id == 878) && i2c_hw; - - if (0 != btv->i2c_rc) - return 0; - - if (use_hw) { - return i2c_del_adapter(&btv->i2c_adap); - } else { - return i2c_bit_del_bus(&btv->i2c_adap); - } } /* diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttv-risc.c 780-bttv/drivers/media/video/bttv-risc.c --- 770-tuner/drivers/media/video/bttv-risc.c Mon Nov 17 18:29:29 2003 +++ 780-bttv/drivers/media/video/bttv-risc.c Fri Jan 9 23:11:34 2004 @@ -53,7 +53,7 @@ bttv_risc_packed(struct bttv *btv, struc one write per scan line + sync + jump (all 2 dwords) */ instructions = (bpl * lines) / PAGE_SIZE + lines; instructions += 2; - if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*8)) < 0) + if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) return rc; /* sync instruction */ @@ -100,7 +100,7 @@ bttv_risc_packed(struct bttv *btv, struc } offset += padding; } - dprintk("bttv%d: risc planar: %d sglist elems\n", btv->nr, (int)(sg-sglist)); + dprintk("bttv%d: risc planar: %d sglist elems\n", btv->c.nr, (int)(sg-sglist)); /* save pointer to jmp instruction address */ risc->jmp = rp; @@ -128,7 +128,7 @@ bttv_risc_planar(struct bttv *btv, struc plus sync + jump (2 dwords) */ instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines; instructions += 2; - if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*4*5)) < 0) + if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0) return rc; /* sync instruction */ @@ -227,7 +227,7 @@ bttv_risc_overlay(struct bttv *btv, stru instructions = (ov->nclips + 1) * ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height); instructions += 2; - if ((rc = btcx_riscmem_alloc(btv->dev,risc,instructions*8)) < 0) { + if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) { kfree(skips); return rc; } @@ -247,9 +247,6 @@ bttv_risc_overlay(struct bttv *btv, stru if ((btv->opt_vcr_hack) && (line >= (ov->w.height - VCR_HACK_LINES))) continue; - if ((line%2) == 0 && skip_even) - continue; - if ((line%2) == 1 && skip_odd) if ((line%2) == 0 && skip_even) continue; if ((line%2) == 1 && skip_odd) @@ -310,7 +307,7 @@ bttv_calc_geo(struct bttv *btv, struct b int totalwidth = tvnorm->totalwidth; int scaledtwidth = tvnorm->scaledtwidth; - if (bttv_tvcards[btv->type].muxsel[btv->input] < 0) { + if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) { swidth = 720; totalwidth = 858; scaledtwidth = 858; @@ -391,7 +388,7 @@ bttv_set_dma(struct bttv *btv, int overr d2printk(KERN_DEBUG "bttv%d: capctl=%x irq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n", - btv->nr,capctl,irqflags, + btv->c.nr,capctl,irqflags, btv->curr.vbi ? (unsigned long long)btv->curr.vbi->top.dma : 0, btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, btv->curr.vbi ? (unsigned long long)btv->curr.vbi->bottom.dma : 0, @@ -429,10 +426,10 @@ bttv_risc_init_main(struct bttv *btv) { int rc; - if ((rc = btcx_riscmem_alloc(btv->dev,&btv->main,PAGE_SIZE)) < 0) + if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0) return rc; dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n", - btv->nr,(unsigned long long)btv->main.dma); + btv->c.nr,(unsigned long long)btv->main.dma); btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | BT848_FIFO_STATUS_VRE); @@ -472,11 +469,11 @@ bttv_risc_hook(struct bttv *btv, int slo if (NULL == risc) { d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n", - btv->nr,risc,slot); + btv->c.nr,risc,slot); btv->main.cpu[slot+1] = cpu_to_le32(next); } else { d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n", - btv->nr,risc,slot,(unsigned long long)risc->dma,irqflags); + btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags); cmd = BT848_RISC_JUMP; if (irqflags) { cmd |= BT848_RISC_IRQ; @@ -496,10 +493,10 @@ bttv_dma_free(struct bttv *btv, struct b if (in_interrupt()) BUG(); videobuf_waiton(&buf->vb,0,0); - videobuf_dma_pci_unmap(btv->dev, &buf->vb.dma); + videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma); videobuf_dma_free(&buf->vb.dma); - btcx_riscmem_free(btv->dev,&buf->bottom); - btcx_riscmem_free(btv->dev,&buf->top); + btcx_riscmem_free(btv->c.pci,&buf->bottom); + btcx_riscmem_free(btv->c.pci,&buf->top); buf->vb.state = STATE_NEEDS_INIT; } @@ -577,7 +574,7 @@ bttv_buffer_risc(struct bttv *btv, struc dprintk(KERN_DEBUG "bttv%d: buffer field: %s format: %s size: %dx%d\n", - btv->nr, v4l2_field_names[buf->vb.field], + btv->c.nr, v4l2_field_names[buf->vb.field], buf->fmt->name, buf->vb.width, buf->vb.height); /* packed pixel modes */ @@ -731,7 +728,7 @@ bttv_overlay_risc(struct bttv *btv, /* check interleave, bottom+top fields */ dprintk(KERN_DEBUG "bttv%d: overlay fields: %s format: %s size: %dx%d\n", - btv->nr, v4l2_field_names[buf->vb.field], + btv->c.nr, v4l2_field_names[buf->vb.field], fmt->name,ov->w.width,ov->w.height); /* calculate geometry */ diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttv-vbi.c 780-bttv/drivers/media/video/bttv-vbi.c --- 770-tuner/drivers/media/video/bttv-vbi.c Mon Nov 17 18:29:29 2003 +++ 780-bttv/drivers/media/video/bttv-vbi.c Fri Jan 9 23:11:34 2004 @@ -44,7 +44,7 @@ MODULE_PARM_DESC(vbi_debug,"vbi code deb # undef dprintk #endif #define dprintk(fmt, arg...) if (vbi_debug) \ - printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->nr, ## arg) + printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg) /* ----------------------------------------------------------------------- */ /* vbi risc code + mm */ @@ -87,7 +87,7 @@ static int vbi_buffer_prepare(struct fil return -EINVAL; if (STATE_NEEDS_INIT == buf->vb.state) { - if (0 != (rc = videobuf_iolock(btv->dev, &buf->vb, NULL))) + if (0 != (rc = videobuf_iolock(btv->c.pci, &buf->vb, NULL))) goto fail; if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines))) goto fail; diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttv.h 780-bttv/drivers/media/video/bttv.h --- 770-tuner/drivers/media/video/bttv.h Mon Nov 17 18:29:29 2003 +++ 780-bttv/drivers/media/video/bttv.h Fri Jan 9 23:11:34 2004 @@ -14,6 +14,7 @@ #define _BTTV_H_ #include +#include /* ---------------------------------------------------------- */ /* exported by bttv-cards.c */ @@ -117,6 +118,10 @@ #define BTTV_PV143 0x69 #define BTTV_IVC100 0x6e #define BTTV_IVC120 0x6f +#define BTTV_PC_HDTV 0x70 +#define BTTV_TWINHAN_DST 0x71 +#define BTTV_WINFASTVC100 0x72 +#define BTTV_SIMUS_GVC1100 0x74 /* i2c address list */ #define I2C_TSA5522 0xc2 @@ -150,6 +155,18 @@ #define DIGITAL_MODE_VIDEO 1 #define DIGITAL_MODE_CAMERA 2 +struct bttv_core { + /* device structs */ + struct pci_dev *pci; + struct i2c_adapter i2c_adap; + struct list_head subs; /* struct bttv_sub_device */ + + /* device config */ + unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ + unsigned int type; /* card type (pointer into tvcards[]) */ + char name[8]; /* dev name */ +}; + struct bttv; struct tvcard @@ -173,7 +190,10 @@ struct tvcard unsigned int msp34xx_alt:1; /* flag: video pci function is unused */ - unsigned int no_video; + unsigned int no_video:1; + unsigned int has_dvb:1; + unsigned int has_remote:1; + unsigned int no_gpioirq:1; /* other settings */ unsigned int pll; @@ -208,7 +228,9 @@ extern int bttv_handle_chipset(struct bt /* ---------------------------------------------------------- */ /* exported by bttv-if.c */ -/* interface for gpio access by other modules */ + +/* this obsolete -- please use the sysfs-based + interface below for new code */ /* returns card type + card ID (for bt878-based ones) for possible values see lines below beginning with #define BTTV_UNKNOWN @@ -256,7 +278,43 @@ extern wait_queue_head_t* bttv_get_gpio_ extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg); -/* i2c */ + +/* ---------------------------------------------------------- */ +/* sysfs/driver-moded based gpio access interface */ + + +struct bttv_sub_device { + struct device dev; + struct bttv_core *core; + struct list_head list; +}; +#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev) + +struct bttv_sub_driver { + struct device_driver drv; + char wanted[BUS_ID_SIZE]; + void (*gpio_irq)(struct bttv_sub_device *sub); +}; +#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) + +int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted); +int bttv_sub_unregister(struct bttv_sub_driver *drv); + +/* gpio access functions */ +void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits); +u32 bttv_gpio_read(struct bttv_core *core); +void bttv_gpio_write(struct bttv_core *core, u32 value); +void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); + +#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits) +#define gpio_read() bttv_gpio_read(&btv->c) +#define gpio_write(value) bttv_gpio_write(&btv->c, value) +#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits) + + +/* ---------------------------------------------------------- */ +/* i2c */ + extern void bttv_bit_setscl(void *data, int state); extern void bttv_bit_setsda(void *data, int state); extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); diff -aurpN -X /home/fletch/.diff.exclude 770-tuner/drivers/media/video/bttvp.h 780-bttv/drivers/media/video/bttvp.h --- 770-tuner/drivers/media/video/bttvp.h Mon Nov 17 18:29:29 2003 +++ 780-bttv/drivers/media/video/bttvp.h Fri Jan 9 23:11:34 2004 @@ -41,13 +41,11 @@ #include #include #include +#include #include "bt848.h" #include "bttv.h" #include "btcx-risc.h" -#ifdef CONFIG_VIDEO_IR -#include "ir-common.h" -#endif #ifdef __KERNEL__ @@ -219,11 +217,14 @@ void bttv_vbi_setlines(struct bttv_fh *f extern struct videobuf_queue_ops bttv_vbi_qops; /* ---------------------------------------------------------- */ -/* bttv-input.c */ +/* bttv-gpio.c */ + + +extern struct bus_type bttv_sub_bus_type; +int bttv_sub_add_device(struct bttv_core *core, char *name); +int bttv_sub_del_devices(struct bttv_core *core); +void bttv_gpio_irq(struct bttv_core *core); -int bttv_input_init(struct bttv *btv); -void bttv_input_fini(struct bttv *btv); -void bttv_input_irq(struct bttv *btv); /* ---------------------------------------------------------- */ /* bttv-driver.c */ @@ -263,7 +264,6 @@ struct bttv_pll_info { unsigned int pll_current; /* Currently programmed ofreq */ }; -#ifdef CONFIG_VIDEO_IR /* for gpio-connected remote control */ struct bttv_input { struct input_dev dev; @@ -273,36 +273,46 @@ struct bttv_input { u32 mask_keycode; u32 mask_keydown; }; -#endif + +struct bttv_suspend_state { + u32 pci_cfg[64 / sizeof(u32)]; + u32 gpio_enable; + u32 gpio_data; + int disabled; + struct bttv_buffer_set set; +}; struct bttv { + struct bttv_core c; + /* pci device config */ - struct pci_dev *dev; unsigned short id; unsigned char revision; unsigned char *bt848_mmio; /* pointer to mmio */ /* card configuration info */ - unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ - char name[8]; /* dev name */ unsigned int cardid; /* pci subsystem id (bt878 based ones) */ - unsigned int type; /* card type (pointer into tvcards[]) */ unsigned int tuner_type; /* tuner chip type */ unsigned int pinnacle_id; unsigned int svhs; struct bttv_pll_info pll; int triton1; + int gpioirq; - /* gpio interface */ + /* old gpio interface */ wait_queue_head_t gpioq; int shutdown; void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); - + + /* new gpio interface */ + spinlock_t gpio_lock; + /* i2c layer */ - struct i2c_adapter i2c_adap; struct i2c_algo_bit_data i2c_algo; struct i2c_client i2c_client; int i2c_state, i2c_rc; + int i2c_done; + wait_queue_head_t i2c_queue; /* video4linux (1) */ struct video_device *video_dev; @@ -311,9 +321,7 @@ struct bttv { /* infrared remote */ int has_remote; -#ifdef CONFIG_VIDEO_IR struct bttv_input *remote; -#endif /* locking */ spinlock_t s_lock; @@ -339,6 +347,8 @@ struct bttv { int opt_chroma_agc; int opt_adc_crush; int opt_vcr_hack; + int opt_whitecrush_upper; + int opt_whitecrush_lower; /* radio data/state */ int has_radio; @@ -372,6 +382,7 @@ struct bttv { unsigned long dma_on; struct timer_list timeout; unsigned int errors; + struct bttv_suspend_state state; unsigned int users; struct bttv_fh init;