[PATCH] Modify em2880_dvb to use dvb_frontend.c/dvb-core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following patch (against the ~mrechberger/v4l-dvb branch, since
it's the only one that contains this driver) modifies em2880_dvb.c so
that it uses dvb_frontend.c to handle ioctls instead of its own code.
This decreases the amount of code required and means that FE_GET_EVENT
now works correctly.

Fixing FE_GET_EVENT fixes a problem where xine-lib-1.1.2_pre20060328
would hang forever trying to watch DVB using this driver (playback now
works with this), and a similar problem with the MythTV 0.19 scanner
(though this still doesn't find any channels, and MythTV still doesn't
work). I have also tested the patched driver successfully with Kaffeine
0.8.1 and MPlayer CVS.

Note that I haven't been able to test this on any hardware other than
the HVR-900. It probably won't break on other hardware, but I can't
guarantee it (and I wouldn't even say it's that unlikely).

I'd still like to get rid of the code overriding
frontend->ops->set_frontend and frontend->ops->sleep, if at all
possible. Suggestions?

Signed-off-by: Aidan Thornton <makomk@xxxxxxxxxxx>

diff -r 0253666e17d2 linux/drivers/media/video/em28xx/em2880-dvb.c
--- a/linux/drivers/media/video/em28xx/em2880-dvb.c	Sun May 14 19:45:53 2006 +0200
+++ b/linux/drivers/media/video/em28xx/em2880-dvb.c	Sat May 20 00:29:11 2006 +0100
@@ -59,132 +59,29 @@ static int em2880_set_alternate(struct e
 static int em2880_set_alternate(struct em2880_dvb *dvb_dev);
 static int em2880_zl10353_pinnacle_pll(struct em2880_dvb *dvb_dev,unsigned int frequency);
 
-static int em2880_ioctl (struct inode *inode, struct file *file,unsigned cmd, unsigned long arg)
-{
-	struct dvb_device *dvbdev = file->private_data;
-	struct em28xx *dev=dvbdev->priv;
+static int em2880_set_frontend(struct dvb_frontend *fe,
+				  struct dvb_frontend_parameters *p)
+{
+
+	struct em28xx *dev = fe->dvb->priv;
 	struct em2880_dvb *dvb_dev=dev->dvb_dev;
-	switch(cmd){
-		case FE_GET_INFO:
-			{
-				struct dvb_frontend_info *info=(struct dvb_frontend_info*)arg;
-				dprintk(1,"em2880-dvb.c: FE_GET_INFO\n");
-				memcpy(info, &dvb_dev->frontend->ops->info, sizeof(struct dvb_frontend_info));
-				info->caps |= FE_CAN_INVERSION_AUTO;
-				return 0;
+
+	if(p != NULL) {
+		mutex_lock(&dev->lock);
+		if(dvb_dev->mod_type==EM28XX_ZL10353){
+			if(dev->model==EM2870_BOARD_PINNACLE_PCTV_DVB){
+				em2880_zl10353_pinnacle_pll(dvb_dev,
+							    p->frequency);
+			} else {
+				em2880_zl10353_pll(dvb_dev,p->frequency);
 			}
-		case FE_READ_SIGNAL_STRENGTH:
-			if(dvb_dev->frontend->ops->read_signal_strength){
-				dprintk(1,"em2880-dvb.c: reading signal strength\n");
-				return dvb_dev->frontend->ops->read_signal_strength(dvb_dev->frontend, (__u16*) arg);
-			}
-			break;
-		case FE_READ_UNCORRECTED_BLOCKS:
-#if 0
-			if(dvb_dev->frontend->ops->read_ucblocks)
-				dprintk(1,"em2880-dvb.c: reading uncorrected blocks\n");
-				return dvb_dev->frontend->ops->read_ucblocks(dvb_dev->frontend, (__u32*)arg);
-#endif
-			break;
-		case FE_SET_FRONTEND:
-			{
-				/* FIXME .. put this into a callback function and use the dvb_frontend.h framework! */
-				struct dvb_frontend_parameters *p = (struct dvb_frontend_parameters*)arg;
-				mutex_lock(&dev->lock);
-				if(dvb_dev->mod_type==EM28XX_ZL10353){
-					if(dev->model==EM2870_BOARD_PINNACLE_PCTV_DVB){
-						em2880_zl10353_pinnacle_pll(dvb_dev,p->frequency);
-					} else {
-						em2880_zl10353_pll(dvb_dev,p->frequency);
-					}
-				}
-				else
-					em2880_mt352_pll(dvb_dev,p->frequency);
-				mutex_unlock(&dev->lock);
-				return 0;
-
-			}
-		case FE_READ_SNR:
-			if(dvb_dev->frontend->ops->read_snr){
-				dprintk(1,"em2880-dvb.c: read signal to noise ratio\n");
-				dvb_dev->frontend->ops->read_snr(dvb_dev->frontend,(__u16*)arg);
-			}
-			return 0;
-		case FE_READ_STATUS: {
-					     int status2;
-					     fe_status_t* status = (fe_status_t*)arg;
-
-					     dprintk(1,"em2880-dvb.c: FE_READ_STATUS\n");
-
-					     if (dvb_dev->frontend->ops->read_status){
-						     status2=dvb_dev->frontend->ops->read_status(dvb_dev->frontend, status);
-						     return status2;
-					     }
-					     break;
-				     }
-		case FE_GET_EVENT:
-				     {
-					     struct dvb_frontend_event __user *e = (void __user *) arg;
-					     return em2880_ioctl(inode, file, FE_READ_STATUS, (unsigned long) &e->status);
-				     }
-
-
-		default:
-				     {
-					     dprintk(1,"em2880-dvb.c: unknown command!\n");
-					     return -EINVAL;
-				     }
-	}
-	dprintk(1,"em2880-dvb.c: returning -EINVAL!\n");
-	return -EINVAL;
-}
-
-static int em2880_open (struct inode *inode, struct file *file){
-	struct dvb_device *dvbdev = file->private_data;
-	struct em28xx *dev = dvbdev->priv;
-	struct em2880_dvb *dvb_dev = dev->dvb_dev;
-	int err = -ERESTARTSYS;
-	dprintk(1,"em2880-dvb.c: open!\n");
-	dvb_dev->frontend->ops->init(dvb_dev->frontend);
-
-	if (( err = dvb_generic_open(inode,file))) {
-		mutex_unlock(&dvb_dev->sem);
-		return err;
-	}
-
-	mutex_unlock(&dvb_dev->sem);
-	return 0;
-}
-
-static int em2880_release (struct inode *inode, struct file *file){
-	struct dvb_device *dvbdev = file->private_data;
-	struct em28xx *dev = dvbdev->priv;
-	struct em2880_dvb *dvb_dev = dev->dvb_dev;
-
-	dprintk(1,"em2880-dvb.c: close!\n");
-
-	if(mutex_lock_interruptible(&dvb_dev->sem))
-		return -ERESTARTSYS;
-
-	mutex_unlock(&dvb_dev->sem);
-
-	return dvb_generic_release(inode,file);
-}
-
-static struct file_operations em2880_fops = {
-	.owner = THIS_MODULE,
-	.ioctl = em2880_ioctl,
-	.open  = em2880_open,
-	.release = em2880_release,
-};
-
-static struct dvb_device em2880_fe_template = {
-	.users = ~0,
-	.writers = 1,
-	.readers = (~0)-1,
-	.fops = &em2880_fops
-};
-
+		}
+		else
+			em2880_mt352_pll(dvb_dev,p->frequency);
+		mutex_unlock(&dev->lock);
+	}
+	return 0;		
+}
 
 /* ------------------------------------------------------------------ */
 
@@ -601,9 +498,16 @@ static int em2880_dvb_init(struct em28xx
 	} else
 		dvb_dev->mod_type=EM28XX_ZL10353;
 
+	// Override ops->set_frontend; this is currently used to set
+	// the tuner frequency, but we also do the frontend stuff too (ugh)
+	// [FIXME] We can't wake the frontend (at least not zl10353) yet
+	dvb_dev->frontend->ops->set_frontend = em2880_set_frontend;
+	dvb_dev->frontend->ops->sleep = NULL; 
+
+	dvb_register_adapter(&dvb_dev->adapter, "em2880 DVB-T", THIS_MODULE);
 	dvb_dev->adapter.priv=dev;
 
-	dvb_register_adapter(&dvb_dev->adapter, "em2880 DVB-T", THIS_MODULE);
+	dvb_register_frontend(&dvb_dev->adapter, dvb_dev->frontend);
 
 	dvb_dev->demux.priv = dvb_dev;
 	dvb_dev->demux.filternum = 256;
@@ -625,7 +529,6 @@ static int em2880_dvb_init(struct em28xx
 		return -1;
 	}
 
-	dvb_register_device(&dvb_dev->adapter, &dvb_dev->fedev,&em2880_fe_template,dev,DVB_DEVICE_FRONTEND);
 	dvb_dev->udev=dev->udev;
 	dvb_dev->em28xx_dev=dev; /* FIXME get rid of this */
 
@@ -653,7 +556,7 @@ static int em2880_dvb_fini(struct em28xx
 	dvb_dmxdev_release(&dvb_dev->dmxdev);
 	dvb_dmx_release(&dvb_dev->demux);
 
-	dvb_unregister_device(dvb_dev->fedev);
+	dvb_unregister_frontend(dvb_dev->frontend);
 	dvb_unregister_adapter(&dvb_dev->adapter);
 
 	dprintk(1,"dvb_fini!\n");



_______________________________________________

linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux