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