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

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

 



Hello Aidan,

good work!
the patch looks fine to me, though can you send it as a file please?

thanks,
Markus

On 5/20/06, Aidan Thornton <makomk@xxxxxxxxxxx> wrote:
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



--
Markus Rechberger

_______________________________________________

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