diff options
author | Catalin Climov <devnull@localhost> | 2005-08-16 15:49:31 +0000 |
---|---|---|
committer | Catalin Climov <devnull@localhost> | 2005-08-16 15:49:31 +0000 |
commit | 3c689849d35cbee41c7b8271e1f59b3205c6dbe3 (patch) | |
tree | fe6b6c28d3cd643bb6e25c2dd9f6aabf4b845e53 /linux/drivers/media/video/cx88/cx88-video.c | |
parent | b9c8314916a547aefded0e96a6e5adfcc85a7c14 (diff) | |
download | mediapointer-dvb-s2-3c689849d35cbee41c7b8271e1f59b3205c6dbe3.tar.gz mediapointer-dvb-s2-3c689849d35cbee41c7b8271e1f59b3205c6dbe3.tar.bz2 |
Some reorg: move some bits to struct cx88_core, factor out common ioctl's
to cx88_do_ioctl.
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-video.c')
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-video.c | 310 |
1 files changed, 175 insertions, 135 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index e2b3aa241..35ec3f3b2 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1,5 +1,5 @@ /* - * $Id: cx88-video.c,v 1.84 2005/08/16 14:49:21 catalin Exp $ + * $Id: cx88-video.c,v 1.85 2005/08/16 15:49:31 catalin Exp $ * * device driver for Conexant 2388x based TV cards * video4linux video interface @@ -343,22 +343,23 @@ static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit) { + struct cx88_core *core = dev->core; if (fh->resources & bit) /* have it already allocated */ return 1; /* is it free? */ - down(&dev->lock); + down(&core->lock); if (dev->resources & bit) { /* no, someone else uses it */ - up(&dev->lock); + up(&core->lock); return 0; } /* it's free, grab it */ fh->resources |= bit; dev->resources |= bit; dprintk(1,"res: get %d\n",bit); - up(&dev->lock); + up(&core->lock); return 1; } @@ -377,21 +378,23 @@ int res_locked(struct cx8800_dev *dev, unsigned int bit) static void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) { + struct cx88_core *core = dev->core; if ((fh->resources & bits) != bits) BUG(); - down(&dev->lock); + down(&core->lock); fh->resources &= ~bits; dev->resources &= ~bits; dprintk(1,"res: put %d\n",bits); - up(&dev->lock); + up(&core->lock); } /* ------------------------------------------------------------------ */ -static int video_mux(struct cx8800_dev *dev, unsigned int input) +/* static int video_mux(struct cx8800_dev *dev, unsigned int input) */ +static int video_mux(struct cx88_core *core, unsigned int input) { - struct cx88_core *core = dev->core; + /* struct cx88_core *core = dev->core; */ dcprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n", input, INPUT(input)->vmux, @@ -1120,9 +1123,10 @@ video_mmap(struct file *file, struct vm_area_struct * vma) /* ------------------------------------------------------------------ */ -static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) +/* static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */ +static int get_control(struct cx88_core *core, struct v4l2_control *ctl) { - struct cx88_core *core = dev->core; + /* struct cx88_core *core = dev->core; */ struct cx88_ctrl *c = NULL; u32 value; int i; @@ -1148,9 +1152,10 @@ static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) return 0; } -static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) +/* static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */ +static int set_control(struct cx88_core *core, struct v4l2_control *ctl) { - struct cx88_core *core = dev->core; + /* struct cx88_core *core = dev->core; */ struct cx88_ctrl *c = NULL; u32 v_sat_value; u32 value; @@ -1163,9 +1168,17 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) return -EINVAL; if (ctl->value < c->v.minimum) +#if 0 return -ERANGE; +#else + ctl->value = c->v.minimum; +#endif if (ctl->value > c->v.maximum) +#if 0 return -ERANGE; +#else + ctl->value = c->v.maximum; +#endif switch (ctl->id) { case V4L2_CID_AUDIO_BALANCE: value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; @@ -1196,7 +1209,8 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) return 0; } -static void init_controls(struct cx8800_dev *dev) +/* static void init_controls(struct cx8800_dev *dev) */ +static void init_controls(struct cx88_core *core) { static struct v4l2_control mute = { .id = V4L2_CID_AUDIO_MUTE, @@ -1219,11 +1233,11 @@ static void init_controls(struct cx8800_dev *dev) .value = 0x80, }; - set_control(dev,&mute); - set_control(dev,&volume); - set_control(dev,&hue); - set_control(dev,&contrast); - set_control(dev,&brightness); + set_control(core,&mute); + set_control(core,&volume); + set_control(core,&hue); + set_control(core,&contrast); + set_control(core,&brightness); } /* ------------------------------------------------------------------ */ @@ -1378,6 +1392,126 @@ static int video_do_ioctl(struct inode *inode, struct file *file, return 0; } + /* --- capture ioctls ---------------------------------------- */ + case VIDIOC_ENUM_FMT: + { + struct v4l2_fmtdesc *f = arg; + enum v4l2_buf_type type; + unsigned int index; + + index = f->index; + type = f->type; + switch (type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (index >= ARRAY_SIZE(formats)) + return -EINVAL; + memset(f,0,sizeof(*f)); + f->index = index; + f->type = type; + strlcpy(f->description,formats[index].name,sizeof(f->description)); + f->pixelformat = formats[index].fourcc; + break; + default: + return -EINVAL; + } + return 0; + } + case VIDIOC_G_FMT: + { + struct v4l2_format *f = arg; + return cx8800_g_fmt(dev,fh,f); + } + case VIDIOC_S_FMT: + { + struct v4l2_format *f = arg; + return cx8800_s_fmt(dev,fh,f); + } + case VIDIOC_TRY_FMT: + { + struct v4l2_format *f = arg; + return cx8800_try_fmt(dev,fh,f); + } + + /* --- streaming capture ------------------------------------- */ + case VIDIOCGMBUF: + { + struct video_mbuf *mbuf = arg; + struct videobuf_queue *q; + struct v4l2_requestbuffers req; + unsigned int i; + + q = get_queue(fh); + memset(&req,0,sizeof(req)); + req.type = q->type; + req.count = 8; + req.memory = V4L2_MEMORY_MMAP; + err = videobuf_reqbufs(q,&req); + if (err < 0) + return err; + memset(mbuf,0,sizeof(*mbuf)); + mbuf->frames = req.count; + mbuf->size = 0; + for (i = 0; i < mbuf->frames; i++) { + mbuf->offsets[i] = q->bufs[i]->boff; + mbuf->size += q->bufs[i]->bsize; + } + return 0; + } + case VIDIOC_REQBUFS: + return videobuf_reqbufs(get_queue(fh), arg); + + case VIDIOC_QUERYBUF: + return videobuf_querybuf(get_queue(fh), arg); + + case VIDIOC_QBUF: + return videobuf_qbuf(get_queue(fh), arg); + + case VIDIOC_DQBUF: + return videobuf_dqbuf(get_queue(fh), arg, + file->f_flags & O_NONBLOCK); + + case VIDIOC_STREAMON: + { + int res = get_ressource(fh); + + if (!res_get(dev,fh,res)) + return -EBUSY; + return videobuf_streamon(get_queue(fh)); + } + case VIDIOC_STREAMOFF: + { + int res = get_ressource(fh); + + err = videobuf_streamoff(get_queue(fh)); + if (err < 0) + return err; + res_free(dev,fh,res); + return 0; + } + + default: + return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl ); + } + return 0; +} + +int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, + struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) +{ +#if 0 + unsigned long flags; +#endif + int err; + + if (video_debug > 1) + cx88_print_ioctl(core->name,cmd); +#if 1 + printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd ); + cx88_print_ioctl(core->name,cmd); +#endif + dcprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); + + switch (cmd) { /* ---------- tv norms ---------- */ case VIDIOC_ENUMSTD: { @@ -1412,9 +1546,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, if (i == ARRAY_SIZE(tvnorms)) return -EINVAL; - down(&dev->lock); + down(&core->lock); cx88_set_tvnorm(core,&tvnorms[i]); - up(&dev->lock); + up(&core->lock); return 0; } @@ -1464,10 +1598,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file, if (*i >= 4) return -EINVAL; - down(&dev->lock); + down(&core->lock); cx88_newstation(core); - video_mux(dev,*i); - up(&dev->lock); + video_mux(core,*i); + up(&core->lock); return 0; } @@ -1503,46 +1637,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file, } #endif - /* --- capture ioctls ---------------------------------------- */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - enum v4l2_buf_type type; - unsigned int index; - - index = f->index; - type = f->type; - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (index >= ARRAY_SIZE(formats)) - return -EINVAL; - memset(f,0,sizeof(*f)); - f->index = index; - f->type = type; - strlcpy(f->description,formats[index].name,sizeof(f->description)); - f->pixelformat = formats[index].fourcc; - break; - default: - return -EINVAL; - } - return 0; - } - case VIDIOC_G_FMT: - { - struct v4l2_format *f = arg; - return cx8800_g_fmt(dev,fh,f); - } - case VIDIOC_S_FMT: - { - struct v4l2_format *f = arg; - return cx8800_s_fmt(dev,fh,f); - } - case VIDIOC_TRY_FMT: - { - struct v4l2_format *f = arg; - return cx8800_try_fmt(dev,fh,f); - } - /* --- controls ---------------------------------------------- */ case VIDIOC_QUERYCTRL: { @@ -1563,9 +1657,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, return 0; } case VIDIOC_G_CTRL: - return get_control(dev,arg); + return get_control(core,arg); case VIDIOC_S_CTRL: - return set_control(dev,arg); + return set_control(core,arg); /* --- tuner ioctls ------------------------------------------ */ case VIDIOC_G_TUNER: @@ -1609,8 +1703,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, if (UNSET == core->tuner_type) return -EINVAL; - f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - f->frequency = dev->freq; + /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */ + f->type = radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + f->frequency = core->freq; cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f); @@ -1624,12 +1719,12 @@ static int video_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; if (f->tuner != 0) return -EINVAL; - if (0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV) + if (0 == radio && f->type != V4L2_TUNER_ANALOG_TV) return -EINVAL; - if (1 == fh->radio && f->type != V4L2_TUNER_RADIO) + if (1 == radio && f->type != V4L2_TUNER_RADIO) return -EINVAL; - down(&dev->lock); - dev->freq = f->frequency; + down(&core->lock); + core->freq = f->frequency; cx88_newstation(core); cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); @@ -1637,70 +1732,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file, msleep (10); cx88_set_tvaudio(core); - up(&dev->lock); - return 0; - } - - /* --- streaming capture ------------------------------------- */ - case VIDIOCGMBUF: - { - struct video_mbuf *mbuf = arg; - struct videobuf_queue *q; - struct v4l2_requestbuffers req; - unsigned int i; - - q = get_queue(fh); - memset(&req,0,sizeof(req)); - req.type = q->type; - req.count = 8; - req.memory = V4L2_MEMORY_MMAP; - err = videobuf_reqbufs(q,&req); - if (err < 0) - return err; - memset(mbuf,0,sizeof(*mbuf)); - mbuf->frames = req.count; - mbuf->size = 0; - for (i = 0; i < mbuf->frames; i++) { - mbuf->offsets[i] = q->bufs[i]->boff; - mbuf->size += q->bufs[i]->bsize; - } - return 0; - } - case VIDIOC_REQBUFS: - return videobuf_reqbufs(get_queue(fh), arg); - - case VIDIOC_QUERYBUF: - return videobuf_querybuf(get_queue(fh), arg); - - case VIDIOC_QBUF: - return videobuf_qbuf(get_queue(fh), arg); - - case VIDIOC_DQBUF: - return videobuf_dqbuf(get_queue(fh), arg, - file->f_flags & O_NONBLOCK); - - case VIDIOC_STREAMON: - { - int res = get_ressource(fh); - - if (!res_get(dev,fh,res)) - return -EBUSY; - return videobuf_streamon(get_queue(fh)); - } - case VIDIOC_STREAMOFF: - { - int res = get_ressource(fh); - - err = videobuf_streamoff(get_queue(fh)); - if (err < 0) - return err; - res_free(dev,fh,res); + up(&core->lock); return 0; } default: return v4l_compat_translate_ioctl(inode,file,cmd,arg, - video_do_ioctl); + driver_ioctl); } return 0; } @@ -2087,7 +2125,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, } /* initialize driver struct */ - init_MUTEX(&dev->lock); + /* init_MUTEX(&dev->lock); // moved to cx88_core_get */ spin_lock_init(&dev->slock); core->tvnorm = tvnorms; @@ -2168,11 +2206,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, pci_set_drvdata(pci_dev,dev); /* initial device configuration */ - down(&dev->lock); - init_controls(dev); + down(&core->lock); + init_controls(core); cx88_set_tvnorm(core,tvnorms); - video_mux(dev,0); - up(&dev->lock); + video_mux(core,0); + up(&core->lock); /* start tvaudio thread */ if (core->tuner_type != TUNER_ABSENT) @@ -2332,6 +2370,8 @@ static void cx8800_fini(void) module_init(cx8800_init); module_exit(cx8800_fini); +EXPORT_SYMBOL(cx88_do_ioctl); + /* ----------------------------------------------------------- */ /* * Local variables: |