patch-2.4.19 linux-2.4.19/drivers/media/video/bttv-driver.c

Next file: linux-2.4.19/drivers/media/video/bttv.h
Previous file: linux-2.4.19/drivers/media/video/bttv-cards.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/drivers/media/video/bttv-driver.c linux-2.4.19/drivers/media/video/bttv-driver.c
@@ -37,7 +37,6 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <linux/sched.h>
-#include <asm/segment.h>
 #include <linux/types.h>
 #include <linux/wrapper.h>
 #include <linux/interrupt.h>
@@ -70,6 +69,9 @@
 static unsigned int gbufsize = BTTV_MAX_FBUF;
 static unsigned int combfilter = 0;
 static unsigned int lumafilter = 0;
+static unsigned int automute = 1;
+static unsigned int chroma_agc = 0;
+static unsigned int adc_crush = 1;
 static int video_nr = -1;
 static int radio_nr = -1;
 static int vbi_nr = -1;
@@ -96,8 +98,15 @@
 MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (64 max)");
 MODULE_PARM(gbufsize,"i");
 MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
+
 MODULE_PARM(combfilter,"i");
 MODULE_PARM(lumafilter,"i");
+MODULE_PARM(automute,"i");
+MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");
+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(video_nr,"i");
 MODULE_PARM(radio_nr,"i");
@@ -279,7 +288,7 @@
 static char *audio_modes[] = { "audio: tuner", "audio: radio", "audio: extern",
 			       "audio: intern", "audio: off" };
 
-static void audio(struct bttv *btv, int mode, int no_irq_context)
+static void audio(struct bttv *btv, int mode)
 {
 	btaor(bttv_tvcards[btv->type].gpiomask, ~bttv_tvcards[btv->type].gpiomask,
               BT848_GPIO_OUT_EN);
@@ -313,12 +322,12 @@
               ~bttv_tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,audio_modes[mode]);
-	if (no_irq_context)
+	if (!in_interrupt())
 		bttv_call_i2c_clients(btv,AUDC_SET_INPUT,&(mode));
 }
 
 
-extern inline void bt848_dma(struct bttv *btv, uint state)
+static inline void bt848_dma(struct bttv *btv, uint state)
 {
 	if (state)
 		btor(3, BT848_GPIO_DMA_CTL);
@@ -425,18 +434,16 @@
 
 static void bt848_muxsel(struct bttv *btv, unsigned int input)
 {
-
-#if 0 /* seems no card uses this ... */
+        /* needed by RemoteVideo MX */
 	btaor(bttv_tvcards[btv->type].gpiomask2,~bttv_tvcards[btv->type].gpiomask2,
               BT848_GPIO_OUT_EN);
-#endif
 
 	/* This seems to get rid of some synchronization problems */
 	btand(~(3<<5), BT848_IFORM);
-	mdelay(10); 
-        
+	mdelay(10);
+
 	input %= bttv_tvcards[btv->type].video_inputs;
-	if (input==bttv_tvcards[btv->type].svhs) 
+	if (input==bttv_tvcards[btv->type].svhs)
 	{
 		btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
 		btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
@@ -446,20 +453,25 @@
 		btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
 		btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
 	}
-	btaor((bttv_tvcards[btv->type].muxsel[input&7]&3)<<5, ~(3<<5), BT848_IFORM);
-	audio(btv, (input!=bttv_tvcards[btv->type].tuner) ? 
-              AUDIO_EXTERN : AUDIO_TUNER, 1);
 
-#if 0 /* seems no card uses this ... */
+	btaor((bttv_tvcards[btv->type].muxsel[input]&3)<<5, ~(3<<5), BT848_IFORM);
+	audio(btv, (input!=bttv_tvcards[btv->type].tuner) ?
+              AUDIO_EXTERN : AUDIO_TUNER);
+
 	btaor(bttv_tvcards[btv->type].muxsel[input]>>4,
 		~bttv_tvcards[btv->type].gpiomask2, BT848_GPIO_DATA);
+
+	/* card specific hook */
+	if( bttv_tvcards[btv->type].muxsel_hook )
+		bttv_tvcards[btv->type].muxsel_hook ( btv, input );
+
 	if (bttv_gpio)
 		bttv_gpio_tracking(btv,"muxsel");
-#endif
+
 }
 
 
-struct tvnorm 
+struct tvnorm
 {
         u32 Fsc;
         u16 swidth, sheight; /* scaled standard width, height */
@@ -582,7 +594,7 @@
 #define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int))
 
 static int make_rawrisctab(struct bttv *btv, unsigned int *ro,
-                            unsigned int *re, unsigned int *vbuf)
+			   unsigned int *re, unsigned int *vbuf)
 {
         unsigned long line;
 	unsigned long bpl=1024;		/* bytes per line */
@@ -1054,8 +1066,7 @@
 }
 
 
-static void bt848_set_geo(struct bttv *btv,
-			  int no_irq_context)
+static void bt848_set_geo(struct bttv *btv)
 {
 	u16 ewidth, eheight, owidth, oheight;
 	u16 format, bswap;
@@ -1070,7 +1081,7 @@
 	btwrite(1, BT848_VBI_PACK_DEL);
 
         btv->pll.pll_ofreq = tvn->Fsc;
-	if (no_irq_context)
+	if (!in_interrupt())
 		set_pll(btv);
 
 	btv->win.interlace = (btv->win.height>tvn->sheight/2) ? 1 : 0;
@@ -1162,7 +1173,7 @@
 	else
 	        btor(BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
 
-        bt848_set_geo(btv,1);
+        bt848_set_geo(btv);
 }
 
 /*
@@ -1194,7 +1205,7 @@
 	if (mp->height*mp->width*fmtbppx2[palette2fmt[mp->format]&0x0f]/2
 	    > gbufsize)
 		return -EINVAL;
-	if(-1 == palette2fmt[mp->format])
+	if (-1 == palette2fmt[mp->format])
 		return -EINVAL;
 
 	/*
@@ -1352,7 +1363,7 @@
 	spin_lock_irqsave(&btv->s_lock, irq_flags);
 	btv->errors = 0;
 	btv->needs_restart = 0;
-	bt848_set_geo(btv,0);
+	bt848_set_geo(btv);
 	bt848_set_risc_jmps(btv,-1);
 	spin_unlock_irqrestore(&btv->s_lock, irq_flags);
 }
@@ -1452,17 +1463,17 @@
 /* ioctls and supporting functions */
 /***********************************/
 
-extern inline void bt848_bright(struct bttv *btv, uint bright)
+static inline void bt848_bright(struct bttv *btv, uint bright)
 {
 	btwrite(bright&0xff, BT848_BRIGHT);
 }
 
-extern inline void bt848_hue(struct bttv *btv, uint hue)
+static inline void bt848_hue(struct bttv *btv, uint hue)
 {
 	btwrite(hue&0xff, BT848_HUE);
 }
 
-extern inline void bt848_contrast(struct bttv *btv, uint cont)
+static inline void bt848_contrast(struct bttv *btv, uint cont)
 {
 	unsigned int conthi;
 
@@ -1472,7 +1483,7 @@
 	btaor(conthi, ~4, BT848_O_CONTROL);
 }
 
-extern inline void bt848_sat_u(struct bttv *btv, unsigned long data)
+static inline void bt848_sat_u(struct bttv *btv, unsigned long data)
 {
 	u32 datahi;
 
@@ -1495,7 +1506,6 @@
 /*
  *	ioctl routine
  */
- 
 
 static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
@@ -1573,6 +1583,8 @@
 		bt848_muxsel(btv, v.channel);
 		btv->channel=v.channel;
 		if (btv->win.norm != v.norm) {
+			if(btv->type== BTTV_VOODOOTV_FM)
+				bttv_tda9880_setnorm(btv,v.norm);
 			btv->win.norm = v.norm;
 			make_vbitab(btv);
 			spin_lock_irqsave(&btv->s_lock, irq_flags);
@@ -1638,10 +1650,12 @@
 	case VIDIOCSPICT:
 	{
 		struct video_picture p;
-		if(copy_from_user(&p, arg,sizeof(p)))
+		if (copy_from_user(&p, arg,sizeof(p)))
 			return -EFAULT;
 		if (p.palette > PALETTEFMT_MAX)
 			return -EINVAL;
+		if (-1 == palette2fmt[p.palette])
+			return -EINVAL;
 		down(&btv->lock);
 		/* We want -128 to 127 we get 0-65535 */
 		bt848_bright(btv, (p.brightness>>8)-128);
@@ -1875,7 +1889,7 @@
 			return -EFAULT;
 		down(&btv->lock);
 		if(v.flags&VIDEO_AUDIO_MUTE)
-			audio(btv, AUDIO_MUTE, 1);
+			audio(btv, AUDIO_MUTE);
 		/* One audio source per tuner -- huh? <GA> */
 		if(v.audio<0 || v.audio >= bttv_tvcards[btv->type].audio_inputs) {
 			up(&btv->lock);
@@ -1883,7 +1897,7 @@
 		}
 		/* bt848_muxsel(btv,v.audio); */
 		if(!(v.flags&VIDEO_AUDIO_MUTE))
-			audio(btv, AUDIO_UNMUTE, 1);
+			audio(btv, AUDIO_UNMUTE);
 
 		bttv_call_i2c_clients(btv,cmd,&v);
 		
@@ -2368,6 +2382,12 @@
 			flags |= 0x03;
 		if (btv->vbi_on)
 			flags |= 0x0c;
+#if 0
+		/* Hmm ... */
+		if ((0 != btv->risc_cap_even) ||
+		    (0 != btv->risc_cap_odd))
+			flags |= 0x0c;
+#endif
 	}
 
 	if (bttv_debug > 1)
@@ -2467,15 +2487,19 @@
 
 static int __devinit init_video_dev(struct bttv *btv)
 {
-	audio(btv, AUDIO_MUTE, 1);
+	audio(btv, AUDIO_MUTE);
         
 	if(do_video_register(&btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
 		return -1;
+	printk(KERN_INFO "bttv%d: registered device video%d\n",
+	       btv->nr,btv->video_dev.minor & 0x1f);
 	if(do_video_register(&btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 
         {
 	        video_unregister_device(&btv->video_dev);
 		return -1;
 	}
+	printk(KERN_INFO "bttv%d: registered device vbi%d\n",
+	       btv->nr,btv->vbi_dev.minor & 0x1f);
 	if (btv->has_radio)
 	{
 		if(do_video_register(&btv->radio_dev, VFL_TYPE_RADIO, radio_nr)<0) 
@@ -2484,13 +2508,15 @@
 		        video_unregister_device(&btv->video_dev);
 			return -1;
 		}
+		printk(KERN_INFO "bttv%d: registered device radio%d\n",
+		       btv->nr,btv->radio_dev.minor & 0x1f);
 	}
         return 1;
 }
 
 static int __devinit init_bt848(struct bttv *btv)
 {
-	int j;
+	int j,val;
  	unsigned long irq_flags;
 
 	btv->user=0; 
@@ -2592,8 +2618,8 @@
 
 	btwrite(0x20, BT848_E_VSCALE_HI);
 	btwrite(0x20, BT848_O_VSCALE_HI);
-	btwrite(/*BT848_ADC_SYNC_T|*/
-		BT848_ADC_RESERVED|BT848_ADC_CRUSH, BT848_ADC);
+	btwrite(BT848_ADC_RESERVED | (adc_crush ? BT848_ADC_CRUSH : 0),
+		BT848_ADC);
 
 	if (lumafilter) {
 		btwrite(0, BT848_E_CONTROL);
@@ -2608,8 +2634,9 @@
 	btv->picture.hue=128<<8;
 	btv->picture.contrast=0xd8<<7;
 
-	btwrite(0x00, BT848_E_SCLOOP);
-	btwrite(0x00, BT848_O_SCLOOP);
+	val = chroma_agc ? BT848_SCLOOP_CAGC : 0;
+        btwrite(val, BT848_E_SCLOOP);
+        btwrite(val, BT848_O_SCLOOP);
 
 	/* clear interrupt status */
 	btwrite(0xfffffUL, BT848_INT_STAT);
@@ -2633,17 +2660,14 @@
 	spin_unlock_irqrestore(&btv->s_lock, irq_flags);
 
 	/* needs to be done before i2c is registered */
-        if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878)
-                bttv_boot_msp34xx(btv,5);
-	if (btv->type == BTTV_VOODOOTV_FM)
-		bttv_boot_msp34xx(btv,20);
+	bttv_init_card1(btv);
 
 	/* register i2c */
         btv->tuner_type=-1;
         init_bttv_i2c(btv);
 
 	/* some card-specific stuff (needs working i2c) */
-	bttv_init_card(btv);
+	bttv_init_card2(btv);
 
 	/*
 	 *	Now add the template and register the device unit.
@@ -2722,7 +2746,7 @@
 				btand(~15, BT848_GPIO_DMA_CTL);
 				btwrite(virt_to_bus(btv->risc_jmp+2),
 					BT848_RISC_STRT_ADD);
-				bt848_set_geo(btv,0);
+				bt848_set_geo(btv);
 				bt848_set_risc_jmps(btv,-1);
 				spin_unlock(&btv->s_lock);
 			} else {
@@ -2764,14 +2788,14 @@
                                         btv->risc_cap_odd  = btv->gbuf[btv->gq_grab].ro;
 					btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
 					bt848_set_risc_jmps(btv,-1);
-					bt848_set_geo(btv,0);
+					bt848_set_geo(btv);
 					btwrite(BT848_COLOR_CTL_GAMMA,
 						BT848_COLOR_CTL);
 				} else {
                                         btv->risc_cap_odd  = 0;
 					btv->risc_cap_even = 0;
 					bt848_set_risc_jmps(btv,-1);
-                                        bt848_set_geo(btv,0);
+                                        bt848_set_geo(btv);
 					btwrite(btv->fb_color_ctl | BT848_COLOR_CTL_GAMMA,
 						BT848_COLOR_CTL);
 				}
@@ -2790,18 +2814,18 @@
 				btv->risc_cap_odd  = btv->gbuf[btv->gq_grab].ro;
 				btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
 				bt848_set_risc_jmps(btv,-1);
-				bt848_set_geo(btv,0);
+				bt848_set_geo(btv);
 				btwrite(BT848_COLOR_CTL_GAMMA,
 					BT848_COLOR_CTL);
 				spin_unlock(&btv->s_lock);
 			}
 		}
 
-		if (astat&BT848_INT_HLOCK) {
+		if (automute && (astat&BT848_INT_HLOCK)) {
 			if ((dstat&BT848_DSTATUS_HLOC) || (btv->radio))
-				audio(btv, AUDIO_ON,0);
+				audio(btv, AUDIO_ON);
 			else
-				audio(btv, AUDIO_OFF,0);
+				audio(btv, AUDIO_OFF);
 		}
     
 		count++;
@@ -2869,7 +2893,7 @@
         if (btv->vbibuf)
                 vfree((void *) btv->vbibuf);
 
-        free_irq(btv->irq,btv);
+        free_irq(btv->dev->irq,btv);
         DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%p.\n", btv->bt848_mem));
         if (btv->bt848_mem)
                 iounmap(btv->bt848_mem);
@@ -2904,6 +2928,8 @@
         unsigned int cmd;
 #endif
 
+	if (bttv_num == BTTV_MAX)
+		return -ENOMEM;
 	printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
 
         btv=&bttvs[bttv_num];
@@ -2926,10 +2952,17 @@
 	memcpy(&btv->radio_dev,&radio_template,sizeof(radio_template));
 	
         btv->id=dev->device;
-        btv->irq=dev->irq;
 	btv->bt848_adr=pci_resource_start(dev,0);
-	if (pci_enable_device(dev))
+	if (pci_enable_device(dev)) {
+                printk(KERN_WARNING "bttv%d: Can't enable device.\n",
+		       btv->nr);
+		return -EIO;
+	}
+        if (pci_set_dma_mask(dev, 0xffffffff)) {
+                printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
+		       btv->nr);
 		return -EIO;
+        }
 	if (!request_mem_region(pci_resource_start(dev,0),
 				pci_resource_len(dev,0),
 				"bttv")) {
@@ -2946,7 +2979,7 @@
                bttv_num,btv->id, btv->revision, dev->bus->number,
 	       PCI_SLOT(dev->devfn),PCI_FUNC(dev->devfn));
         printk("irq: %d, latency: %d, memory: 0x%lx\n",
-	       btv->irq, lat, btv->bt848_adr);
+	       btv->dev->irq, lat, btv->bt848_adr);
 	
 	bttv_idcard(btv);
 
@@ -2967,7 +3000,7 @@
         /* clear interrupt mask */
 	btwrite(0, BT848_INT_MASK);
 
-        result = request_irq(btv->irq, bttv_irq,
+        result = request_irq(btv->dev->irq, bttv_irq,
                              SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
         if (result==-EINVAL) 
         {
@@ -2977,7 +3010,7 @@
         }
         if (result==-EBUSY)
         {
-                printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
+                printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->dev->irq);
 		goto fail1;
         }
         if (result < 0) 
@@ -3000,7 +3033,7 @@
         return 0;
 
  fail2:
-        free_irq(btv->irq,btv);
+        free_irq(btv->dev->irq,btv);
  fail1:
 	release_mem_region(pci_resource_start(btv->dev,0),
 			   pci_resource_len(btv->dev,0));
@@ -3028,7 +3061,7 @@
         remove:   bttv_remove,
 };
 
-int bttv_init_module(void)
+static int bttv_init_module(void)
 {
 	bttv_num = 0;
 
@@ -3049,7 +3082,7 @@
 	return pci_module_init(&bttv_pci_driver);
 }
 
-void bttv_cleanup_module(void)
+static void bttv_cleanup_module(void)
 {
 	pci_unregister_driver(&bttv_pci_driver);
 	return;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)