s2255drv: cleanup of device structure
PATCH 1/1 s2255drv: cleanup of device structure
s2255drv: cleanup of device structure
From: Dean Anderson <[email protected]>
cleanup of device structure.
single channel array instead of multiple arrays in device for each channel property.
simplifies open callback by removing search for channel index.
Priority: normal
Signed-off-by Dean Anderson <[email protected]>
drivers/media/video/s2255drv.c | 724 +++++++++++++++++++--------------------- 1 files changed, 352 insertions(+), 372 deletions(-)
---
drivers/media/video/s2255drv.c +352 -372
@@ -191,7 +191,6 @@ struct s2255_bufferi {struct s2255_dmaqueue {struct list_head active;struct s2255_dev *dev; -int channel; };/* for firmware loading, fw_state */
@@ -226,51 +225,60 @@ struct s2255_pipeinfo { };struct s2255_fmt ;/*forward declaration */ +struct s2255_dev ; + +struct s2255_channel { +struct video_device vdev; +int resources; +struct s2255_dmaqueue vidq; +struct s2255_bufferi buffer; +struct s2255_mode mode; +/* jpeg compression */ +struct v4l2_jpegcompression jc; +/* capture parameters (for high quality mode full size) */ +struct v4l2_captureparm cap_parm; +int cur_frame; +int last_frame; + +int b_acquire; +/* allocated image size */ +unsigned long req_image_size; +/* received packet size */ +unsigned long pkt_size; +int bad_payload; +unsigned long frame_count; +/* if JPEG image */ +int jpg_size; +/* if channel configured to default state */ +int configured; +wait_queue_head_t wait_setmode; +int setmode_ready; +/* video status items */ +int vidstatus; +wait_queue_head_t wait_vidstatus; +int vidstatus_ready; +unsigned int width; +unsigned int height; +const struct s2255_fmt *fmt; +int idx;/* channel number on device, 0-3 */ +}; +struct s2255_dev { -struct video_device vdev[MAX_CHANNELS ]; +struct s2255_channel channel[MAX_CHANNELS ];struct v4l2_device v4l2_dev; -atomic_t channels;/* number of channels registered */ +atomic_t num_channels;int frames;struct mutex lock;struct mutex open_lock; -int resources[MAX_CHANNELS ];struct usb_device *udev;struct usb_interface *interface;u8 read_endpoint; - -struct s2255_dmaqueue vidq[MAX_CHANNELS ];struct timer_list timer;struct s2255_fw *fw_data;struct s2255_pipeinfo pipe; -struct s2255_bufferi buffer[MAX_CHANNELS ]; -struct s2255_mode mode[MAX_CHANNELS ]; -/* jpeg compression */ -struct v4l2_jpegcompression jc[MAX_CHANNELS ]; -/* capture parameters (for high quality mode full size) */ -struct v4l2_captureparm cap_parm[MAX_CHANNELS ]; -const struct s2255_fmt *cur_fmt[MAX_CHANNELS ]; -int cur_frame[MAX_CHANNELS ]; -int last_frame[MAX_CHANNELS ];u32 cc;/* current channel */ -int b_acquire[MAX_CHANNELS ]; -/* allocated image size */ -unsigned long req_image_size[MAX_CHANNELS ]; -/* received packet size */ -unsigned long pkt_size[MAX_CHANNELS ]; -int bad_payload[MAX_CHANNELS ]; -unsigned long frame_count[MAX_CHANNELS ];int frame_ready; -/* if JPEG image */ -int jpg_size[MAX_CHANNELS ]; -/* if channel configured to default state */ -int chn_configured[MAX_CHANNELS ]; -wait_queue_head_t wait_setmode[MAX_CHANNELS ]; -int setmode_ready[MAX_CHANNELS ]; -/* video status items */ -int vidstatus[MAX_CHANNELS ]; -wait_queue_head_t wait_vidstatus[MAX_CHANNELS ]; -int vidstatus_ready[MAX_CHANNELS ];int chn_ready;spinlock_t slock;/* dsp firmware version (f2255usb.bin) */
@@ -298,16 +306,10 @@ struct s2255_buffer {struct s2255_fh {struct s2255_dev *dev; -const struct s2255_fmt *fmt; -unsigned int width; -unsigned int height;struct videobuf_queue vb_vidq;enum v4l2_buf_type type; -int channel; -/* mode below is the desired mode. -mode in s2255_dev is the current mode that was last set */ -struct s2255_mode mode; -int resources[MAX_CHANNELS ]; +struct s2255_channel *channel; +int resources; };/* current cypress EEPROM firmware version */
@@ -360,12 +362,11 @@ static int *s2255_debug = &debug;static int s2255_start_readpipe (struct s2255_dev *dev);static void s2255_stop_readpipe (struct s2255_dev *dev); -static int s2255_start_acquire (struct s2255_dev *dev,unsigned long chn); -static int s2255_stop_acquire (struct s2255_dev *dev,unsigned long chn); -static void s2255_fillbuff (struct s2255_dev *dev,struct s2255_buffer *buf, -int chn,int jpgsize); -static int s2255_set_mode (struct s2255_dev *dev,unsigned long chn, -struct s2255_mode *mode); +static int s2255_start_acquire (struct s2255_channel *channel); +static int s2255_stop_acquire (struct s2255_channel *channel); +static void s2255_fillbuff (struct s2255_channel *chn,struct s2255_buffer *buf, +int jpgsize); +static int s2255_set_mode (struct s2255_channel *chan,struct s2255_mode *mode);static int s2255_board_shutdown (struct s2255_dev *dev);static void s2255_fwload_start (struct s2255_dev *dev,int reset);static void s2255_destroy (struct s2255_dev *dev);
@@ -577,10 +578,11 @@ static void s2255_fwchunk_complete(struct urb *urb) } -static int s2255_got_frame (struct s2255_dev *dev,int chn,int jpgsize) +static int s2255_got_frame (struct s2255_channel *channel,int jpgsize) { -struct s2255_dmaqueue *dma_q = &dev->vidq[chn]; +struct s2255_dmaqueue *dma_q = &channel->vidq;struct s2255_buffer *buf; +struct s2255_dev *dev =to_s2255_dev (channel->vdev.v4l2_dev);unsigned long flags =0 ;int rc =0 ;spin_lock_irqsave (&dev->slock, flags);
@@ -593,7 +595,7 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize) struct s2255_buffer, vb.queue);list_del (&buf->vb.queue);do_gettimeofday (&buf->vb.ts); -s2255_fillbuff (dev, buf, dma_q->channel, jpgsize); +s2255_fillbuff (channel, buf, jpgsize);wake_up (&buf->vb.done);dprintk (2 ,"%s: [buf/i] [%p/%d]\n" , __func__, buf, buf->vb.i); unlock:
@@ -621,8 +623,8 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc)* http://v4l.videotechnology.com/ * */ -static void s2255_fillbuff (struct s2255_dev *dev,struct s2255_buffer *buf, -int chn,int jpgsize) +static void s2255_fillbuff (struct s2255_channel *channel, +struct s2255_buffer *buf,int jpgsize) {int pos =0 ;struct timeval ts;
@@ -633,12 +635,11 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,if (!vbuf)return ; - - last_frame = dev->last_frame[chn]; + last_frame = channel->last_frame;if (last_frame !=-1 ) { - frm = &dev->buffer[chn].frame[last_frame]; + frm = &channel->buffer.frame[last_frame]; tmpbuf = - (const char *)dev->buffer[chn].frame[last_frame].lpvbits; + (const char *)channel->buffer.frame[last_frame].lpvbits;switch (buf->fmt->fourcc) {case V4L2_PIX_FMT_YUYV :case V4L2_PIX_FMT_UYVY :
@@ -661,7 +662,7 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,default :printk (KERN_DEBUG "s2255: unknown format?\n" ); } - dev->last_frame[chn] =-1 ; + channel->last_frame =-1 ; }else {printk (KERN_ERR "s2255: =======no frame\n" );return ;
@@ -671,7 +672,7 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, (unsigned long)vbuf, pos);/* tell v4l buffer was filled */ - buf->vb.field_count = dev->frame_count[chn] *2 ; + buf->vb.field_count = channel->frame_count *2 ;do_gettimeofday (&ts); buf->vb.ts = ts; buf->vb.state =VIDEOBUF_DONE ;
@@ -686,8 +687,8 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) {struct s2255_fh *fh = vq->priv_data; - - *size = fh->width * fh->height * (fh->fmt->depth >>3 ); +struct s2255_channel *channel = fh->channel; + *size = channel->width * channel->height * (channel->fmt->depth >>3 );if (0 == *count) *count =S2255_DEF_BUFS ;
@@ -710,30 +711,31 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) {struct s2255_fh *fh = vq->priv_data; +struct s2255_channel *channel = fh->channel; struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);int rc; +int w = channel->width; +int h = channel->height;dprintk (4 ,"%s, field=%d\n" , __func__, field); -if (fh->fmt ==NULL ) +if (channel->fmt ==NULL )return -EINVAL ; -if ((fh->width <norm_minw (&fh->dev->vdev[fh->channel])) || - (fh->width >norm_maxw (&fh->dev->vdev[fh->channel])) || - (fh->height <norm_minh (&fh->dev->vdev[fh->channel])) || - (fh->height >norm_maxh (&fh->dev->vdev[fh->channel]))) { +if ((w <norm_minw (&channel->vdev)) || + (w >norm_maxw (&channel->vdev)) || + (h <norm_minh (&channel->vdev)) || + (h >norm_maxh (&channel->vdev))) {dprintk (4 ,"invalid buffer prepare\n" );return -EINVAL ; } - - buf->vb.size = fh->width * fh->height * (fh->fmt->depth >>3 ); - + buf->vb.size = w * h * (channel->fmt->depth >>3 );if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {dprintk (4 ,"invalid buffer prepare\n" );return -EINVAL ; } - buf->fmt = fh->fmt; - buf->vb.width = fh->width; - buf->vb.height = fh->height; + buf->fmt = channel->fmt; + buf->vb.width = w; + buf->vb.height = h; buf->vb.field = field;if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
@@ -753,8 +755,8 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) { struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);struct s2255_fh *fh = vq->priv_data; -struct s2255_dev *dev = fh->dev; -struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel]; +struct s2255_channel *channel = fh->channel; +struct s2255_dmaqueue *vidq = &channel->vidq;dprintk (1 ,"%s\n" , __func__); buf->vb.state =VIDEOBUF_QUEUED ;list_add_tail (&buf->vb.queue, &vidq->active);
@@ -765,7 +767,7 @@ static void buffer_release(struct videobuf_queue *vq, { struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);struct s2255_fh *fh = vq->priv_data; -dprintk (4 ,"%s %d\n" , __func__, fh->channel); +dprintk (4 ,"%s %d\n" , __func__, fh->channel->idx);free_buffer (vq, buf); }
@@ -777,39 +779,43 @@ static struct videobuf_queue_ops s2255_video_qops = { }; -static int res_get (struct s2255_dev *dev,struct s2255_fh *fh) +static int res_get (struct s2255_fh *fh) { +struct s2255_dev *dev = fh->dev;/* is it free? */ +struct s2255_channel *channel = fh->channel;mutex_lock (&dev->lock); -if (dev->resources[fh->channel]) { +if (channel->resources) {/* no, someone else uses it */ mutex_unlock (&dev->lock);return 0 ; }/* it's free, grab it */ - dev->resources[fh->channel] =1 ; - fh->resources[fh->channel] =1 ; + channel->resources =1 ; + fh->resources =1 ;dprintk (1 ,"s2255: res: get\n" );mutex_unlock (&dev->lock);return 1 ; } -static int res_locked (struct s2255_dev *dev,struct s2255_fh *fh) +static int res_locked (struct s2255_fh *fh) { -return dev->resources[fh->channel]; +return fh->channel->resources; }static int res_check (struct s2255_fh *fh) { -return fh->resources[fh->channel]; +return fh->resources; } -static void res_free (struct s2255_dev *dev,struct s2255_fh *fh) +static void res_free (struct s2255_fh *fh) { +struct s2255_channel *channel = fh->channel; +struct s2255_dev *dev = fh->dev;mutex_lock (&dev->lock); - dev->resources[fh->channel] =0 ; - fh->resources[fh->channel] =0 ; + channel->resources =0 ; + fh->resources =0 ;mutex_unlock (&dev->lock);dprintk (1 ,"res: put\n" ); }
@@ -869,12 +875,13 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) {struct s2255_fh *fh = priv; +struct s2255_channel *channel = fh->channel; - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; + f->fmt.pix.width = channel->width; + f->fmt.pix.height = channel->height; f->fmt.pix.field = fh->vb_vidq.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >>3 ); + f->fmt.pix.pixelformat = channel->fmt->fourcc; + f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >>3 ); f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;return 0 ; }
@@ -886,11 +893,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,enum v4l2_field field;int b_any_field =0 ;struct s2255_fh *fh = priv; -struct s2255_dev *dev = fh->dev; +struct s2255_channel *channel = fh->channel;int is_ntsc; - is_ntsc = - (dev->vdev[fh->channel].current_norm &V4L2_STD_NTSC ) ?1 :0 ; + (channel->vdev.current_norm &V4L2_STD_NTSC ) ?1 :0 ; fmt =format_by_fourcc (f->fmt.pix.pixelformat);
@@ -982,8 +988,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) {struct s2255_fh *fh = priv; +struct s2255_channel *channel = fh->channel;const struct s2255_fmt *fmt;struct videobuf_queue *q = &fh->vb_vidq; +struct s2255_mode mode;int ret;int norm;
@@ -1005,54 +1013,61 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, goto out_s_fmt; } -if (res_locked (fh->dev, fh)) { +if (res_locked (fh)) {dprintk (1 ,"%s: channel busy\n" , __func__); ret = -EBUSY ; goto out_s_fmt; } - - fh->fmt = fmt; - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; + mode = channel->mode; + channel->fmt = fmt; + channel->width = f->fmt.pix.width; + channel->height = f->fmt.pix.height; fh->vb_vidq.field = f->fmt.pix.field; fh->type = f->type; - norm =norm_minw (&fh->dev->vdev[fh->channel]); -if (fh->width >norm_minw (&fh->dev->vdev[fh->channel])) { -if (fh->height >norm_minh (&fh->dev->vdev[fh->channel])) { -if (fh->dev->cap_parm[fh->channel].capturemode & + norm =norm_minw (&channel->vdev); +if (channel->width >norm_minw (&channel->vdev)) { +if (channel->height >norm_minh (&channel->vdev)) { +if (channel->cap_parm.capturemode &V4L2_MODE_HIGHQUALITY ) - fh->mode.scale =SCALE_4CIFSI ; + mode.scale =SCALE_4CIFSI ;else - fh->mode.scale =SCALE_4CIFS ; + mode.scale =SCALE_4CIFS ; }else - fh->mode.scale =SCALE_2CIFS ; + mode.scale =SCALE_2CIFS ; }else { - fh->mode.scale =SCALE_1CIFS ; + mode.scale =SCALE_1CIFS ; } -/* color mode */ -switch (fh->fmt->fourcc) { +switch (channel->fmt->fourcc) {case V4L2_PIX_FMT_GREY : - fh->mode.color &= ~MASK_COLOR ; - fh->mode.color |=COLOR_Y8 ; + mode.color &= ~MASK_COLOR ; + mode.color |=COLOR_Y8 ;break ;case V4L2_PIX_FMT_JPEG : - fh->mode.color &= ~MASK_COLOR ; - fh->mode.color |=COLOR_JPG ; - fh->mode.color |= (fh->dev->jc[fh->channel].quality <<8 ); + mode.color &= ~MASK_COLOR ; + mode.color |=COLOR_JPG ; + mode.color |= (channel->jc.quality <<8 );break ;case V4L2_PIX_FMT_YUV422P : - fh->mode.color &= ~MASK_COLOR ; - fh->mode.color |=COLOR_YUVPL ; + mode.color &= ~MASK_COLOR ; + mode.color |=COLOR_YUVPL ;break ;case V4L2_PIX_FMT_YUYV :case V4L2_PIX_FMT_UYVY :default : - fh->mode.color &= ~MASK_COLOR ; - fh->mode.color |=COLOR_YUVPK ; + mode.color &= ~MASK_COLOR ; + mode.color |=COLOR_YUVPK ;break ; } +if ((mode.color &MASK_COLOR ) != (channel->mode.color &MASK_COLOR )) + mode.restart =1 ; +else if (mode.scale != channel->mode.scale) + mode.restart =1 ; +else if (mode.format != channel->mode.format) + mode.restart =1 ; + channel->mode = mode; + (void )s2255_set_mode (channel, &mode); ret =0 ; out_s_fmt:mutex_unlock (&q->vb_lock);
@@ -1197,26 +1212,27 @@ static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)* When the restart parameter is set, we sleep for ONE frame to allow the * DSP time to get the new frame */ -static int s2255_set_mode (struct s2255_dev *dev,unsigned long chn, +static int s2255_set_mode (struct s2255_channel *channel,struct s2255_mode *mode) {int res;__le32 *buffer;unsigned long chn_rev; +struct s2255_dev *dev =to_s2255_dev (channel->vdev.v4l2_dev);mutex_lock (&dev->lock); - chn_rev = G_chnmap[chn]; -dprintk (3 ,"%s channel %lu\n" , __func__, chn); + chn_rev = G_chnmap[channel->idx]; +dprintk (3 ,"%s channel: %d\n" , __func__, channel->idx);/* if JPEG, set the quality */ if ((mode->color &MASK_COLOR ) ==COLOR_JPG ) { mode->color &= ~MASK_COLOR ; mode->color |=COLOR_JPG ; mode->color &= ~MASK_JPG_QUALITY ; - mode->color |= (dev->jc[chn].quality <<8 ); + mode->color |= (channel->jc.quality <<8 ); }/* save the mode */ - dev->mode[chn] = *mode; - dev->req_image_size[chn] =get_transfer_size (mode); -dprintk (1 ,"%s: reqsize %ld\n" , __func__, dev->req_image_size[chn]); + channel->mode = *mode; + channel->req_image_size =get_transfer_size (mode); +dprintk (1 ,"%s: reqsize %ld\n" , __func__, channel->req_image_size); buffer =kzalloc (512 ,GFP_KERNEL );if (buffer ==NULL ) {dev_err (&dev->udev->dev,"out of mem\n" );
@@ -1227,38 +1243,38 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, buffer[0 ] =IN_DATA_TOKEN ; buffer[1 ] = (__le32 )cpu_to_le32 (chn_rev); buffer[2 ] =CMD_SET_MODE ; -memcpy (&buffer[3 ], &dev->mode[chn],sizeof (struct s2255_mode )); - dev->setmode_ready[chn] =0 ; +memcpy (&buffer[3 ], &channel->mode,sizeof (struct s2255_mode )); + channel->setmode_ready =0 ; res =s2255_write_config (dev->udev, (unsigned char *)buffer,512 );if (debug)s2255_print_cfg (dev, mode);kfree (buffer);/* wait at least 3 frames before continuing */ if (mode->restart) { -wait_event_timeout (dev->wait_setmode[chn], - (dev->setmode_ready[chn] !=0 ), +wait_event_timeout (channel->wait_setmode, + (channel->setmode_ready !=0 ),msecs_to_jiffies (S2255_SETMODE_TIMEOUT )); -if (dev->setmode_ready[chn] !=1 ) { +if (channel->setmode_ready !=1 ) {printk (KERN_DEBUG "s2255: no set mode response\n" ); res = -EFAULT ; } }/* clear the restart flag */ - dev->mode[chn].restart =0 ; + channel->mode.restart =0 ;mutex_unlock (&dev->lock); -dprintk (1 ,"%s chn %lu, result: %d\n" , __func__, chn, res); +dprintk (1 ,"%s chn %d, result: %d\n" , __func__, channel->idx, res);return res; } -static int s2255_cmd_status (struct s2255_dev *dev,unsigned long chn, -u32 *pstatus) +static int s2255_cmd_status (struct s2255_channel *channel,u32 *pstatus) {int res;__le32 *buffer;u32 chn_rev; +struct s2255_dev *dev =to_s2255_dev (channel->vdev.v4l2_dev);mutex_lock (&dev->lock); - chn_rev = G_chnmap[chn]; -dprintk (4 ,"%s chan %lu\n" , __func__, chn); + chn_rev = G_chnmap[channel->idx]; +dprintk (4 ,"%s chan %d\n" , __func__, channel->idx); buffer =kzalloc (512 ,GFP_KERNEL );if (buffer ==NULL ) {dev_err (&dev->udev->dev,"out of mem\n" );
@@ -1270,17 +1286,17 @@ static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn, buffer[1 ] = (__le32 )cpu_to_le32 (chn_rev); buffer[2 ] =CMD_STATUS ; *pstatus =0 ; - dev->vidstatus_ready[chn] =0 ; + channel->vidstatus_ready =0 ; res =s2255_write_config (dev->udev, (unsigned char *)buffer,512 );kfree (buffer); -wait_event_timeout (dev->wait_vidstatus[chn], - (dev->vidstatus_ready[chn] !=0 ), +wait_event_timeout (channel->wait_vidstatus, + (channel->vidstatus_ready !=0 ),msecs_to_jiffies (S2255_VIDSTATUS_TIMEOUT )); -if (dev->vidstatus_ready[chn] !=1 ) { +if (channel->vidstatus_ready !=1 ) {printk (KERN_DEBUG "s2255: no vidstatus response\n" ); res = -EFAULT ; } - *pstatus = dev->vidstatus[chn]; + *pstatus = channel->vidstatus;dprintk (4 ,"%s, vid status %d\n" , __func__, *pstatus);mutex_unlock (&dev->lock);return res;
@@ -1291,9 +1307,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)int res;struct s2255_fh *fh = priv;struct s2255_dev *dev = fh->dev; -struct s2255_mode *new_mode; -struct s2255_mode *old_mode; -int chn; +struct s2255_channel *channel = fh->channel;int j;dprintk (4 ,"%s\n" , __func__);if (fh->type !=V4L2_BUF_TYPE_VIDEO_CAPTURE ) {
@@ -1305,51 +1319,32 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)return -EINVAL ; } -if (!res_get (dev, fh)) { +if (!res_get (fh)) {s2255_dev_err (&dev->udev->dev,"stream busy\n" );return -EBUSY ; } - -/* send a set mode command everytime with restart. -in case we switch resolutions or other parameters */ - chn = fh->channel; - new_mode = &fh->mode; - old_mode = &fh->dev->mode[chn]; - -if ((new_mode->color &MASK_COLOR ) != (old_mode->color &MASK_COLOR )) - new_mode->restart =1 ; -else if (new_mode->scale != old_mode->scale) - new_mode->restart =1 ; -else if (new_mode->format != old_mode->format) - new_mode->restart =1 ; - -s2255_set_mode (dev, chn, new_mode); - new_mode->restart =0 ; - *old_mode = *new_mode; - dev->cur_fmt[chn] = fh->fmt; - dev->last_frame[chn] =-1 ; - dev->bad_payload[chn] =0 ; - dev->cur_frame[chn] =0 ; - dev->frame_count[chn] =0 ; + channel->last_frame =-1 ; + channel->bad_payload =0 ; + channel->cur_frame =0 ; + channel->frame_count =0 ;for (j =0 ; j <SYS_FRAMES ; j++) { - dev->buffer[chn].frame[j].ulState =S2255_READ_IDLE ; - dev->buffer[chn].frame[j].cur_size =0 ; + channel->buffer.frame[j].ulState =S2255_READ_IDLE ; + channel->buffer.frame[j].cur_size =0 ; } res =videobuf_streamon (&fh->vb_vidq);if (res ==0 ) { -s2255_start_acquire (dev, chn); - dev->b_acquire[chn] =1 ; - }else { -res_free (dev, fh); - } +s2255_start_acquire (channel); + channel->b_acquire =1 ; + }else +res_free (fh); +return res; }static int vidioc_streamoff (struct file *file,void *priv,enum v4l2_buf_type i) {struct s2255_fh *fh = priv; -struct s2255_dev *dev = fh->dev; -dprintk (4 ,"%s\n, channel: %d" , __func__, fh->channel); +dprintk (4 ,"%s\n, channel: %d" , __func__, fh->channel->idx);if (fh->type !=V4L2_BUF_TYPE_VIDEO_CAPTURE ) {printk (KERN_ERR "invalid fh type0\n" );return -EINVAL ;
@@ -1358,16 +1353,16 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)printk (KERN_ERR "invalid type i\n" );return -EINVAL ; } -s2255_stop_acquire (dev, fh->channel); +s2255_stop_acquire (fh->channel);videobuf_streamoff (&fh->vb_vidq); -res_free (dev, fh); +res_free (fh);return 0 ; }static int vidioc_s_std (struct file *file,void *priv,v4l2_std_id *i) {struct s2255_fh *fh = priv; -struct s2255_mode *mode; +struct s2255_mode mode;struct videobuf_queue *q = &fh->vb_vidq;int ret =0 ;mutex_lock (&q->vb_lock);
@@ -1376,29 +1371,32 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) ret = -EBUSY ; goto out_s_std; } -if (res_locked (fh->dev, fh)) { +if (res_locked (fh)) {dprintk (1 ,"can't change standard after started\n" ); ret = -EBUSY ; goto out_s_std; } - mode = &fh->mode; + mode = fh->channel->mode;if (*i &V4L2_STD_NTSC ) {dprintk (4 ,"%s NTSC\n" , __func__);/* if changing format, reset frame decimation/intervals */ -if (mode->format !=FORMAT_NTSC ) { - mode->format =FORMAT_NTSC ; - mode->fdec =FDEC_1 ; +if (mode.format !=FORMAT_NTSC ) { + mode.restart =1 ; + mode.format =FORMAT_NTSC ; + mode.fdec =FDEC_1 ; } }else if (*i &V4L2_STD_PAL ) {dprintk (4 ,"%s PAL\n" , __func__); - mode->format =FORMAT_PAL ; -if (mode->format !=FORMAT_PAL ) { - mode->format =FORMAT_PAL ; - mode->fdec =FDEC_1 ; +if (mode.format !=FORMAT_PAL ) { + mode.restart =1 ; + mode.format =FORMAT_PAL ; + mode.fdec =FDEC_1 ; } }else { ret = -EINVAL ; } +if (mode.restart) +s2255_set_mode (fh->channel, &mode); out_s_std:mutex_unlock (&q->vb_lock);return ret;
@@ -1416,6 +1414,7 @@ static int vidioc_enum_input(struct file *file, void *priv, {struct s2255_fh *fh = priv;struct s2255_dev *dev = fh->dev; +struct s2255_channel *channel = fh->channel;u32 status =0 ;if (inp->index !=0 )return -EINVAL ;
@@ -1424,7 +1423,7 @@ static int vidioc_enum_input(struct file *file, void *priv, inp->status =0 ;if (dev->dsp_fw_ver >=S2255_MIN_DSP_STATUS ) {int rc; - rc =s2255_cmd_status (dev, fh->channel, &status); + rc =s2255_cmd_status (fh->channel, &status);dprintk (4 ,"s2255_cmd_status rc: %d status %x\n" , rc, status);if (rc ==0 ) inp->status = (status & 0x01) ? 0
@@ -1436,7 +1435,7 @@ static int vidioc_enum_input(struct file *file, void *priv,strlcpy (inp->name,"Composite" ,sizeof (inp->name));break ;case 0x2257 : -strlcpy (inp->name, (fh->channel <2 ) ?"Composite" :"S-Video" , +strlcpy (inp->name, (channel->idx <2 ) ?"Composite" :"S-Video" ,sizeof (inp->name));break ; }
@@ -1460,6 +1459,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qc) {struct s2255_fh *fh = priv; +struct s2255_channel *channel = fh->channel;struct s2255_dev *dev = fh->dev;switch (qc->id) {case V4L2_CID_BRIGHTNESS :
@@ -1477,7 +1477,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,case V4L2_CID_PRIVATE_COLORFILTER :if (dev->dsp_fw_ver <S2255_MIN_DSP_COLORFILTER )return -EINVAL ; -if ((dev->pid ==0x2257 ) && (fh->channel >1 )) +if ((dev->pid ==0x2257 ) && (channel->idx >1 ))return -EINVAL ;strlcpy (qc->name,"Color Filter" ,sizeof (qc->name)); qc->type =V4L2_CTRL_TYPE_MENU ;
@@ -1499,25 +1499,26 @@ static int vidioc_g_ctrl(struct file *file, void *priv, {struct s2255_fh *fh = priv;struct s2255_dev *dev = fh->dev; +struct s2255_channel *channel = fh->channel;switch (ctrl->id) {case V4L2_CID_BRIGHTNESS : - ctrl->value = fh->mode.bright; + ctrl->value = channel->mode.bright;break ;case V4L2_CID_CONTRAST : - ctrl->value = fh->mode.contrast; + ctrl->value = channel->mode.contrast;break ;case V4L2_CID_SATURATION : - ctrl->value = fh->mode.saturation; + ctrl->value = channel->mode.saturation;break ;case V4L2_CID_HUE : - ctrl->value = fh->mode.hue; + ctrl->value = channel->mode.hue;break ;case V4L2_CID_PRIVATE_COLORFILTER :if (dev->dsp_fw_ver <S2255_MIN_DSP_COLORFILTER )return -EINVAL ; -if ((dev->pid ==0x2257 ) && (fh->channel >1 )) +if ((dev->pid ==0x2257 ) && (channel->idx >1 ))return -EINVAL ; - ctrl->value = !((fh->mode.color &MASK_INPUT_TYPE ) >>16 ); + ctrl->value = !((channel->mode.color &MASK_INPUT_TYPE ) >>16 );break ;default :return -EINVAL ;
@@ -1530,41 +1531,42 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) {struct s2255_fh *fh = priv; -struct s2255_dev *dev = fh->dev; -struct s2255_mode *mode; - mode = &fh->mode; +struct s2255_channel *channel = fh->channel; +struct s2255_dev *dev =to_s2255_dev (channel->vdev.v4l2_dev); +struct s2255_mode mode; + mode = channel->mode;dprintk (4 ,"%s\n" , __func__);/* update the mode to the corresponding value */ switch (ctrl->id) {case V4L2_CID_BRIGHTNESS : - mode->bright = ctrl->value; + mode.bright = ctrl->value;break ;case V4L2_CID_CONTRAST : - mode->contrast = ctrl->value; + mode.contrast = ctrl->value;break ;case V4L2_CID_HUE : - mode->hue = ctrl->value; + mode.hue = ctrl->value;break ;case V4L2_CID_SATURATION : - mode->saturation = ctrl->value; + mode.saturation = ctrl->value;break ;case V4L2_CID_PRIVATE_COLORFILTER :if (dev->dsp_fw_ver <S2255_MIN_DSP_COLORFILTER )return -EINVAL ; -if ((dev->pid ==0x2257 ) && (fh->channel >1 )) +if ((dev->pid ==0x2257 ) && (channel->idx >1 ))return -EINVAL ; - mode->color &= ~MASK_INPUT_TYPE ; - mode->color |= ((ctrl->value ?0 :1 ) <<16 ); + mode.color &= ~MASK_INPUT_TYPE ; + mode.color |= ((ctrl->value ?0 :1 ) <<16 );break ;default :return -EINVAL ; } - mode->restart =0 ; + mode.restart =0 ;/* set mode here. Note: stream does not need restarted. some V4L programs restart stream unnecessarily after a s_crtl. */ -s2255_set_mode (dev, fh->channel, mode); +s2255_set_mode (fh->channel, &mode);return 0 ; }
@@ -1572,8 +1574,8 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, struct v4l2_jpegcompression *jc) {struct s2255_fh *fh = priv; -struct s2255_dev *dev = fh->dev; - *jc = dev->jc[fh->channel]; +struct s2255_channel *channel = fh->channel; + *jc = channel->jc;dprintk (2 ,"%s: quality %d\n" , __func__, jc->quality);return 0 ; }
@@ -1582,10 +1584,10 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, struct v4l2_jpegcompression *jc) {struct s2255_fh *fh = priv; -struct s2255_dev *dev = fh->dev; +struct s2255_channel *channel = fh->channel;if (jc->quality <0 || jc->quality >100 )return -EINVAL ; - dev->jc[fh->channel].quality = jc->quality; + channel->jc.quality = jc->quality;dprintk (2 ,"%s: quality %d\n" , __func__, jc->quality);return 0 ; }
@@ -1594,17 +1596,17 @@ static int vidioc_g_parm(struct file *file, void *priv, struct v4l2_streamparm *sp) {struct s2255_fh *fh = priv; -struct s2255_dev *dev = fh->dev;__u32 def_num, def_dem; +struct s2255_channel *channel = fh->channel;if (sp->type !=V4L2_BUF_TYPE_VIDEO_CAPTURE )return -EINVAL ;memset (sp,0 ,sizeof (struct v4l2_streamparm )); sp->parm.capture.capability =V4L2_CAP_TIMEPERFRAME ; - sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode; - def_num = (fh->mode.format ==FORMAT_NTSC ) ?1001 :1000 ; - def_dem = (fh->mode.format ==FORMAT_NTSC ) ?30000 :25000 ; + sp->parm.capture.capturemode = channel->cap_parm.capturemode; + def_num = (channel->mode.format ==FORMAT_NTSC ) ?1001 :1000 ; + def_dem = (channel->mode.format ==FORMAT_NTSC ) ?30000 :25000 ; sp->parm.capture.timeperframe.denominator = def_dem; -switch (fh->mode.fdec) { +switch (channel->mode.fdec) {default :case FDEC_1 : sp->parm.capture.timeperframe.numerator = def_num;
@@ -1630,17 +1632,19 @@ static int vidioc_s_parm(struct file *file, void *priv, struct v4l2_streamparm *sp) {struct s2255_fh *fh = priv; -struct s2255_dev *dev = fh->dev; +struct s2255_channel *channel = fh->channel; +struct s2255_mode mode;int fdec =FDEC_1 ;__u32 def_num, def_dem;if (sp->type !=V4L2_BUF_TYPE_VIDEO_CAPTURE )return -EINVAL ; + mode = channel->mode;/* high quality capture mode requires a stream restart */ -if (dev->cap_parm[fh->channel].capturemode - != sp->parm.capture.capturemode &&res_locked (fh->dev, fh)) +if (channel->cap_parm.capturemode + != sp->parm.capture.capturemode &&res_locked (fh))return -EBUSY ; - def_num = (fh->mode.format ==FORMAT_NTSC ) ?1001 :1000 ; - def_dem = (fh->mode.format ==FORMAT_NTSC ) ?30000 :25000 ; + def_num = (mode.format ==FORMAT_NTSC ) ?1001 :1000 ; + def_dem = (mode.format ==FORMAT_NTSC ) ?30000 :25000 ;if (def_dem != sp->parm.capture.timeperframe.denominator) sp->parm.capture.timeperframe.numerator = def_num;else if (sp->parm.capture.timeperframe.numerator <= def_num)
@@ -1655,9 +1659,9 @@ static int vidioc_s_parm(struct file *file, void *priv, sp->parm.capture.timeperframe.numerator = def_num *5 ; fdec =FDEC_5 ; } - fh->mode.fdec = fdec; + mode.fdec = fdec; sp->parm.capture.timeperframe.denominator = def_dem; -s2255_set_mode (dev, fh->channel, &fh->mode); +s2255_set_mode (channel, &mode); dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n", __func__, sp->parm.capture.capturemode,
@@ -1707,24 +1711,13 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,static int s2255_open (struct file *file) {struct video_device *vdev =video_devdata (file); -struct s2255_dev *dev =video_drvdata (file); +struct s2255_channel *channel =video_drvdata (file); +struct s2255_dev *dev =to_s2255_dev (vdev->v4l2_dev);struct s2255_fh *fh;enum v4l2_buf_type type =V4L2_BUF_TYPE_VIDEO_CAPTURE ; -int i =0 ; -int cur_channel =-1 ;int state;dprintk (1 ,"s2255: open called (dev=%s)\n" ,video_device_node_name (vdev)); - -for (i =0 ; i <MAX_CHANNELS ; i++) { -if (&dev->vdev[i] == vdev) { - cur_channel = i; -break ; - } - } -if (i ==MAX_CHANNELS ) -return -ENODEV ; -/* * open lock necessary to prevent multiple instances * of v4l-conf (or other programs) from simultaneously
@@ -1806,24 +1799,20 @@ static int s2255_open(struct file *file) file->private_data = fh; fh->dev = dev; fh->type =V4L2_BUF_TYPE_VIDEO_CAPTURE ; - fh->mode = dev->mode[cur_channel]; - fh->fmt = dev->cur_fmt[cur_channel]; -/* default 4CIF NTSC */ - fh->width =LINE_SZ_4CIFS_NTSC ; - fh->height =NUM_LINES_4CIFS_NTSC *2 ; - fh->channel = cur_channel; -/* configure channel to default state */ -if (!dev->chn_configured[cur_channel]) { -s2255_set_mode (dev, cur_channel, &fh->mode); - dev->chn_configured[cur_channel] =1 ; + fh->channel = channel; +if (!channel->configured) { +/* configure channel to default state */ + channel->fmt = &formats[0 ]; +s2255_set_mode (channel, &channel->mode); + channel->configured =1 ; }dprintk (1 ,"%s: dev=%s type=%s\n" , __func__,video_device_node_name (vdev), v4l2_type_names[type]);dprintk (2 ,"%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n" , __func__, (unsigned long )fh, (unsigned long )dev, - (unsigned long )&dev->vidq[cur_channel]); + (unsigned long )&channel->vidq);dprintk (4 ,"%s: list_empty active=%d\n" , __func__, -list_empty (&dev->vidq[cur_channel].active)); +list_empty (&channel->vidq.active)); videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops, NULL, &dev->slock, fh->type,
@@ -1865,6 +1854,7 @@ static void s2255_destroy(struct s2255_dev *dev)mutex_destroy (&dev->open_lock);mutex_destroy (&dev->lock);usb_put_dev (dev->udev); +v4l2_device_unregister (&dev->v4l2_dev);dprintk (1 ,"%s" , __func__);kfree (dev); }
@@ -1874,14 +1864,15 @@ static int s2255_release(struct file *file)struct s2255_fh *fh = file->private_data;struct s2255_dev *dev = fh->dev;struct video_device *vdev =video_devdata (file); +struct s2255_channel *channel = fh->channel;if (!dev)return -ENODEV ;/* turn off stream */ if (res_check (fh)) { -if (dev->b_acquire[fh->channel]) -s2255_stop_acquire (dev, fh->channel); +if (channel->b_acquire) +s2255_stop_acquire (fh->channel);videobuf_streamoff (&fh->vb_vidq); -res_free (dev, fh); +res_free (fh); }videobuf_mmap_free (&fh->vb_vidq);dprintk (1 ,"%s (dev=%s)\n" , __func__,video_device_node_name (vdev));
@@ -1945,9 +1936,10 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {static void s2255_video_device_release (struct video_device *vdev) { -struct s2255_dev *dev =video_get_drvdata (vdev); -dprintk (4 ,"%s, chnls: %d \n" , __func__,atomic_read (&dev->channels)); -if (atomic_dec_and_test (&dev->channels)) +struct s2255_dev *dev =to_s2255_dev (vdev->v4l2_dev); +dprintk (4 ,"%s, chnls: %d \n" , __func__, +atomic_read (&dev->num_channels)); +if (atomic_dec_and_test (&dev->num_channels))s2255_destroy (dev);return ; }
@@ -1966,47 +1958,48 @@ static int s2255_probe_v4l(struct s2255_dev *dev)int ret;int i;int cur_nr = video_nr; +struct s2255_channel *channel; ret =v4l2_device_register (&dev->interface->dev, &dev->v4l2_dev);if (ret)return ret;/* initialize all video 4 linux */ /* register 4 video devices */ for (i =0 ; i <MAX_CHANNELS ; i++) { -INIT_LIST_HEAD (&dev->vidq[i].active); - dev->vidq[i].dev = dev; - dev->vidq[i].channel = i; + channel = &dev->channel[i]; +INIT_LIST_HEAD (&channel->vidq.active); + channel->vidq.dev = dev;/* register 4 video devices */ -memcpy (&dev->vdev[i], &template,sizeof (struct video_device )); - dev->vdev[i].v4l2_dev = &dev->v4l2_dev; -video_set_drvdata (&dev->vdev[i], dev); + channel->vdev = template; + channel->vdev.v4l2_dev = &dev->v4l2_dev; +video_set_drvdata (&channel->vdev, channel);if (video_nr ==-1 ) - ret =video_register_device (&dev->vdev[i], + ret =video_register_device (&channel->vdev,VFL_TYPE_GRABBER , video_nr);else - ret =video_register_device (&dev->vdev[i], + ret =video_register_device (&channel->vdev,VFL_TYPE_GRABBER , cur_nr + i); +if (ret) {dev_err (&dev->udev->dev,"failed to register video device!\n" );break ; } -atomic_inc (&dev->channels); +atomic_inc (&dev->num_channels);v4l2_info (&dev->v4l2_dev,"V4L2 device registered as %s\n" , -video_device_node_name (&dev->vdev[i])); +video_device_node_name (&channel->vdev)); } -printk (KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n" ,S2255_MAJOR_VERSION ,S2255_MINOR_VERSION );/* if no channels registered, return error and probe will fail*/ -if (atomic_read (&dev->channels) ==0 ) { +if (atomic_read (&dev->num_channels) ==0 ) {v4l2_device_unregister (&dev->v4l2_dev);return ret; } -if (atomic_read (&dev->channels) !=MAX_CHANNELS ) +if (atomic_read (&dev->num_channels) !=MAX_CHANNELS )printk (KERN_WARNING "s2255: Not all channels available.\n" );return 0 ; }
@@ -2033,12 +2026,11 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)s32 idx =-1 ;struct s2255_framei *frm;unsigned char *pdata; - +struct s2255_channel *channel;dprintk (100 ,"buffer to user\n" ); - - idx = dev->cur_frame[dev->cc]; - frm = &dev->buffer[dev->cc].frame[idx]; - + channel = &dev->channel[dev->cc]; + idx = channel->cur_frame; + frm = &channel->buffer.frame[idx];if (frm->ulState ==S2255_READ_IDLE ) {int jj;unsigned int cc;
@@ -2063,16 +2055,18 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) }/* reverse it */ dev->cc = G_chnmap[cc]; + channel = &dev->channel[dev->cc]; payload = pdword[3 ]; -if (payload > dev->req_image_size[dev->cc]) { - dev->bad_payload[dev->cc]++; +if (payload > channel->req_image_size) { + channel->bad_payload++;/* discard the bad frame */ return -EINVAL ; } - dev->pkt_size[dev->cc] = payload; - dev->jpg_size[dev->cc] = pdword[4 ]; + channel->pkt_size = payload; + channel->jpg_size = pdword[4 ];break ;case S2255_MARKER_RESPONSE : + pdata +=DEF_USB_BLOCK ; jj +=DEF_USB_BLOCK ;if (pdword[1 ] >=MAX_CHANNELS )
@@ -2080,12 +2074,13 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) cc = G_chnmap[pdword[1 ]];if (cc >=MAX_CHANNELS )break ; + channel = &dev->channel[cc];switch (pdword[2 ]) {case S2255_RESPONSE_SETMODE :/* check if channel valid */ /* set mode ready */ - dev->setmode_ready[cc] =1 ; -wake_up (&dev->wait_setmode[cc]); + channel->setmode_ready =1 ; +wake_up (&channel->wait_setmode);dprintk (5 ,"setmode ready %d\n" , cc);break ;case S2255_RESPONSE_FW :
@@ -2099,9 +2094,9 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)wake_up (&dev->fw_data->wait_fw);break ;case S2255_RESPONSE_STATUS : - dev->vidstatus[cc] = pdword[3 ]; - dev->vidstatus_ready[cc] =1 ; -wake_up (&dev->wait_vidstatus[cc]); + channel->vidstatus = pdword[3 ]; + channel->vidstatus_ready =1 ; +wake_up (&channel->wait_vidstatus);dprintk (5 ,"got vidstatus %x chan %d\n" , pdword[3 ], cc);break ;
@@ -2118,13 +2113,11 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)if (!bframe)return -EINVAL ; } - - - idx = dev->cur_frame[dev->cc]; - frm = &dev->buffer[dev->cc].frame[idx]; - + channel = &dev->channel[dev->cc]; + idx = channel->cur_frame; + frm = &channel->buffer.frame[idx];/* search done. now find out if should be acquiring on this channel */ -if (!dev->b_acquire[dev->cc]) { +if (!channel->b_acquire) {/* we found a frame, but this channel is turned off */ frm->ulState =S2255_READ_IDLE ;return -EINVAL ;
@@ -2149,30 +2142,28 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) copy_size = (pipe_info->cur_transfer_size - offset); - size = dev->pkt_size[dev->cc] -PREFIX_SIZE ; + size = channel->pkt_size -PREFIX_SIZE ;/* sanity check on pdest */ -if ((copy_size + frm->cur_size) < dev->req_image_size[dev->cc]) +if ((copy_size + frm->cur_size) < channel->req_image_size)memcpy (pdest, psrc, copy_size); frm->cur_size += copy_size;dprintk (4 ,"cur_size size %lu size %lu \n" , frm->cur_size, size);if (frm->cur_size >= size) { - -u32 cc = dev->cc;dprintk (2 ,"****************[%d]Buffer[%d]full*************\n" , - cc, idx); - dev->last_frame[cc] = dev->cur_frame[cc]; - dev->cur_frame[cc]++; + dev->cc, idx); + channel->last_frame = channel->cur_frame; + channel->cur_frame++;/* end of system frame ring buffer, start at zero */ -if ((dev->cur_frame[cc] ==SYS_FRAMES ) || - (dev->cur_frame[cc] == dev->buffer[cc].dwFrames)) - dev->cur_frame[cc] =0 ; +if ((channel->cur_frame ==SYS_FRAMES ) || + (channel->cur_frame == channel->buffer.dwFrames)) + channel->cur_frame =0 ;/* frame ready */ -if (dev->b_acquire[cc]) -s2255_got_frame (dev, cc, dev->jpg_size[cc]); - dev->frame_count[cc]++; +if (channel->b_acquire) +s2255_got_frame (channel, channel->jpg_size); + channel->frame_count++; frm->ulState =S2255_READ_IDLE ; frm->cur_size =0 ;
@@ -2245,16 +2236,12 @@ static int s2255_get_fx2fw(struct s2255_dev *dev)* Create the system ring buffer to copy frames into from the * usb read pipe. */ -static int s2255_create_sys_buffers (struct s2255_dev *dev,unsigned long chn) +static int s2255_create_sys_buffers (struct s2255_channel *channel) {unsigned long i;unsigned long reqsize;dprintk (1 ,"create sys buffers\n" ); -if (chn >=MAX_CHANNELS ) -return -1 ; - - dev->buffer[chn].dwFrames =SYS_FRAMES ; - + channel->buffer.dwFrames =SYS_FRAMES ;/* always allocate maximum size(PAL) for system buffers */ reqsize =SYS_FRAMES_MAXSIZE ;
@@ -2263,42 +2250,40 @@ static int s2255_create_sys_buffers(struct s2255_dev *dev, unsigned long chn)for (i =0 ; i <SYS_FRAMES ; i++) {/* allocate the frames */ - dev->buffer[chn].frame[i].lpvbits =vmalloc (reqsize); - -dprintk (1 ,"valloc %p chan %lu, idx %lu, pdata %p\n" , - &dev->buffer[chn].frame[i], chn, i, - dev->buffer[chn].frame[i].lpvbits); - dev->buffer[chn].frame[i].size = reqsize; -if (dev->buffer[chn].frame[i].lpvbits ==NULL ) { + channel->buffer.frame[i].lpvbits =vmalloc (reqsize); +dprintk (1 ,"valloc %p chan %d, idx %lu, pdata %p\n" , + &channel->buffer.frame[i], channel->idx, i, + channel->buffer.frame[i].lpvbits); + channel->buffer.frame[i].size = reqsize; +if (channel->buffer.frame[i].lpvbits ==NULL ) {printk (KERN_INFO "out of memory. using less frames\n" ); - dev->buffer[chn].dwFrames = i; + channel->buffer.dwFrames = i;break ; } }/* make sure internal states are set */ for (i =0 ; i <SYS_FRAMES ; i++) { - dev->buffer[chn].frame[i].ulState =0 ; - dev->buffer[chn].frame[i].cur_size =0 ; + channel->buffer.frame[i].ulState =0 ; + channel->buffer.frame[i].cur_size =0 ; } - dev->cur_frame[chn] =0 ; - dev->last_frame[chn] =-1 ; + channel->cur_frame =0 ; + channel->last_frame =-1 ;return 0 ; } -static int s2255_release_sys_buffers (struct s2255_dev *dev, -unsigned long channel) +static int s2255_release_sys_buffers (struct s2255_channel *channel) {unsigned long i;dprintk (1 ,"release sys buffers\n" );for (i =0 ; i <SYS_FRAMES ; i++) { -if (dev->buffer[channel].frame[i].lpvbits) { +if (channel->buffer.frame[i].lpvbits) {dprintk (1 ,"vfree %p\n" , - dev->buffer[channel].frame[i].lpvbits); -vfree (dev->buffer[channel].frame[i].lpvbits); + channel->buffer.frame[i].lpvbits); +vfree (channel->buffer.frame[i].lpvbits); } - dev->buffer[channel].frame[i].lpvbits =NULL ; + channel->buffer.frame[i].lpvbits =NULL ; }return 0 ; }
@@ -2335,17 +2320,20 @@ static int s2255_board_init(struct s2255_dev *dev) fw_ver & 0xff);for (j =0 ; j <MAX_CHANNELS ; j++) { - dev->b_acquire[j] =0 ; - dev->mode[j] = mode_def; +struct s2255_channel *channel = &dev->channel[j]; + channel->b_acquire =0 ; + channel->mode = mode_def;if (dev->pid ==0x2257 && j >1 ) - dev->mode[j].color |= (1 <<16 ); - dev->jc[j].quality =S2255_DEF_JPEG_QUAL ; - dev->cur_fmt[j] = &formats[0 ]; - dev->mode[j].restart =1 ; - dev->req_image_size[j] =get_transfer_size (&mode_def); - dev->frame_count[j] =0 ; + channel->mode.color |= (1 <<16 ); + channel->jc.quality =S2255_DEF_JPEG_QUAL ; + channel->width =LINE_SZ_4CIFS_NTSC ; + channel->height =NUM_LINES_4CIFS_NTSC *2 ; + channel->fmt = &formats[0 ]; + channel->mode.restart =1 ; + channel->req_image_size =get_transfer_size (&mode_def); + channel->frame_count =0 ;/* create the system buffers */ -s2255_create_sys_buffers (dev, j); +s2255_create_sys_buffers (channel); }/* start read pipe */ s2255_start_readpipe (dev);
@@ -2359,14 +2347,12 @@ static int s2255_board_shutdown(struct s2255_dev *dev)dprintk (1 ,"%s: dev: %p" , __func__, dev);for (i =0 ; i <MAX_CHANNELS ; i++) { -if (dev->b_acquire[i]) -s2255_stop_acquire (dev, i); +if (dev->channel[i].b_acquire) +s2255_stop_acquire (&dev->channel[i]); } -s2255_stop_readpipe (dev); -for (i =0 ; i <MAX_CHANNELS ; i++) -s2255_release_sys_buffers (dev, i); +s2255_release_sys_buffers (&dev->channel[i]);/* release transfer buffer */ kfree (dev->pipe.transfer_buffer);return 0 ;
@@ -2459,29 +2445,26 @@ static int s2255_start_readpipe(struct s2255_dev *dev) }/* starts acquisition process */ -static int s2255_start_acquire (struct s2255_dev *dev,unsigned long chn) +static int s2255_start_acquire (struct s2255_channel *channel) {unsigned char *buffer;int res;unsigned long chn_rev;int j; -if (chn >=MAX_CHANNELS ) { -dprintk (2 ,"start acquire failed, bad channel %lu\n" , chn); -return -1 ; - } - chn_rev = G_chnmap[chn]; +struct s2255_dev *dev =to_s2255_dev (channel->vdev.v4l2_dev); + chn_rev = G_chnmap[channel->idx]; buffer =kzalloc (512 ,GFP_KERNEL );if (buffer ==NULL ) {dev_err (&dev->udev->dev,"out of mem\n" );return -ENOMEM ; } - dev->last_frame[chn] =-1 ; - dev->bad_payload[chn] =0 ; - dev->cur_frame[chn] =0 ; + channel->last_frame =-1 ; + channel->bad_payload =0 ; + channel->cur_frame =0 ;for (j =0 ; j <SYS_FRAMES ; j++) { - dev->buffer[chn].frame[j].ulState =0 ; - dev->buffer[chn].frame[j].cur_size =0 ; + channel->buffer.frame[j].ulState =0 ; + channel->buffer.frame[j].cur_size =0 ; }/* send the start command */
@@ -2492,21 +2475,18 @@ static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)if (res !=0 )dev_err (&dev->udev->dev,"CMD_START error\n" ); -dprintk (2 ,"start acquire exit[%lu] %d \n" , chn, res); +dprintk (2 ,"start acquire exit[%d] %d \n" , channel->idx, res);kfree (buffer);return 0 ; } -static int s2255_stop_acquire (struct s2255_dev *dev,unsigned long chn) +static int s2255_stop_acquire (struct s2255_channel *channel) {unsigned char *buffer;int res;unsigned long chn_rev; -if (chn >=MAX_CHANNELS ) { -dprintk (2 ,"stop acquire failed, bad channel %lu\n" , chn); -return -1 ; - } - chn_rev = G_chnmap[chn]; +struct s2255_dev *dev =to_s2255_dev (channel->vdev.v4l2_dev); + chn_rev = G_chnmap[channel->idx]; buffer =kzalloc (512 ,GFP_KERNEL );if (buffer ==NULL ) {dev_err (&dev->udev->dev,"out of mem\n" );
@@ -2520,8 +2500,8 @@ static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn)if (res !=0 )dev_err (&dev->udev->dev,"CMD_STOP error\n" );kfree (buffer); - dev->b_acquire[chn] =0 ; -dprintk (4 ,"%s: chn %lu, res %d\n" , __func__, chn, res); + channel->b_acquire =0 ; +dprintk (4 ,"%s: chn %d, res %d\n" , __func__, channel->idx, res);return res; }
@@ -2575,7 +2555,7 @@ static int s2255_probe(struct usb_interface *interface,s2255_dev_err (&interface->dev,"out of memory\n" );return -ENOMEM ; } -atomic_set (&dev->channels,0 ); +atomic_set (&dev->num_channels,0 ); dev->pid = id->idProduct; dev->fw_data =kzalloc (sizeof (struct s2255_fw ),GFP_KERNEL );if (!dev->fw_data)
@@ -2612,8 +2592,10 @@ static int s2255_probe(struct usb_interface *interface, dev->timer.data = (unsigned long )dev->fw_data;init_waitqueue_head (&dev->fw_data->wait_fw);for (i =0 ; i <MAX_CHANNELS ; i++) { -init_waitqueue_head (&dev->wait_setmode[i]); -init_waitqueue_head (&dev->wait_vidstatus[i]); +struct s2255_channel *channel = &dev->channel[i]; + dev->channel[i].idx = i; +init_waitqueue_head (&channel->wait_setmode); +init_waitqueue_head (&channel->wait_vidstatus); } dev->fw_data->fw_urb =usb_alloc_urb (0 ,GFP_KERNEL );
@@ -2651,7 +2633,7 @@ static int s2255_probe(struct usb_interface *interface,printk (KERN_INFO "s2255: f2255usb.bin out of date.\n" );if (dev->pid ==0x2257 && *pRel <S2255_MIN_DSP_COLORFILTER )printk (KERN_WARNING "s2255: 2257 requires firmware %d" -"or above.\n" ,S2255_MIN_DSP_COLORFILTER ); +" or above.\n" ,S2255_MIN_DSP_COLORFILTER ); }usb_reset_device (dev->udev);/* load 2255 board specific */
@@ -2693,25 +2675,23 @@ static void s2255_disconnect(struct usb_interface *interface) {struct s2255_dev *dev =to_s2255_dev (usb_get_intfdata (interface));int i; -int channels =atomic_read (&dev->channels); -v4l2_device_unregister (&dev->v4l2_dev); +int channels =atomic_read (&dev->num_channels); +v4l2_device_disconnect (&dev->v4l2_dev);/*see comments in the uvc_driver.c usb disconnect function */ -atomic_inc (&dev->channels); +atomic_inc (&dev->num_channels);/* unregister each video device. */ -for (i =0 ; i < channels; i++) { -if (video_is_registered (&dev->vdev[i])) -video_unregister_device (&dev->vdev[i]); - } +for (i =0 ; i < channels; i++) +video_unregister_device (&dev->channel[i].vdev);/* wake up any of our timers */ atomic_set (&dev->fw_data->fw_state,S2255_FW_DISCONNECTING );wake_up (&dev->fw_data->wait_fw);for (i =0 ; i <MAX_CHANNELS ; i++) { - dev->setmode_ready[i] =1 ; -wake_up (&dev->wait_setmode[i]); - dev->vidstatus_ready[i] =1 ; -wake_up (&dev->wait_vidstatus[i]); + dev->channel[i].setmode_ready =1 ; +wake_up (&dev->channel[i].wait_setmode); + dev->channel[i].vidstatus_ready =1 ; +wake_up (&dev->channel[i].wait_vidstatus); } -if (atomic_dec_and_test (&dev->channels)) +if (atomic_dec_and_test (&dev->num_channels))s2255_destroy (dev);dev_info (&interface->dev,"%s\n" , __func__); }