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