diff options
Diffstat (limited to 'drivers/media/video/s2255drv.c')
-rw-r--r-- | drivers/media/video/s2255drv.c | 572 |
1 files changed, 335 insertions, 237 deletions
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 92b83feae366..5272926db73e 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -58,6 +58,8 @@ | |||
58 | 58 | ||
59 | 59 | ||
60 | 60 | ||
61 | /* default JPEG quality */ | ||
62 | #define S2255_DEF_JPEG_QUAL 50 | ||
61 | /* vendor request in */ | 63 | /* vendor request in */ |
62 | #define S2255_VR_IN 0 | 64 | #define S2255_VR_IN 0 |
63 | /* vendor request out */ | 65 | /* vendor request out */ |
@@ -67,20 +69,21 @@ | |||
67 | /* USB endpoint number for configuring the device */ | 69 | /* USB endpoint number for configuring the device */ |
68 | #define S2255_CONFIG_EP 2 | 70 | #define S2255_CONFIG_EP 2 |
69 | /* maximum time for DSP to start responding after last FW word loaded(ms) */ | 71 | /* maximum time for DSP to start responding after last FW word loaded(ms) */ |
70 | #define S2255_DSP_BOOTTIME 400 | 72 | #define S2255_DSP_BOOTTIME 800 |
71 | /* maximum time to wait for firmware to load (ms) */ | 73 | /* maximum time to wait for firmware to load (ms) */ |
72 | #define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) | 74 | #define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) |
73 | #define S2255_DEF_BUFS 16 | 75 | #define S2255_DEF_BUFS 16 |
76 | #define S2255_SETMODE_TIMEOUT 500 | ||
74 | #define MAX_CHANNELS 4 | 77 | #define MAX_CHANNELS 4 |
75 | #define FRAME_MARKER 0x2255DA4AL | 78 | #define S2255_MARKER_FRAME 0x2255DA4AL |
76 | #define MAX_PIPE_USBBLOCK (40 * 1024) | 79 | #define S2255_MARKER_RESPONSE 0x2255ACACL |
77 | #define DEFAULT_PIPE_USBBLOCK (16 * 1024) | 80 | #define S2255_USB_XFER_SIZE (16 * 1024) |
78 | #define MAX_CHANNELS 4 | 81 | #define MAX_CHANNELS 4 |
79 | #define MAX_PIPE_BUFFERS 1 | 82 | #define MAX_PIPE_BUFFERS 1 |
80 | #define SYS_FRAMES 4 | 83 | #define SYS_FRAMES 4 |
81 | /* maximum size is PAL full size plus room for the marker header(s) */ | 84 | /* maximum size is PAL full size plus room for the marker header(s) */ |
82 | #define SYS_FRAMES_MAXSIZE (720 * 288 * 2 * 2 + 4096) | 85 | #define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) |
83 | #define DEF_USB_BLOCK (4096) | 86 | #define DEF_USB_BLOCK S2255_USB_XFER_SIZE |
84 | #define LINE_SZ_4CIFS_NTSC 640 | 87 | #define LINE_SZ_4CIFS_NTSC 640 |
85 | #define LINE_SZ_2CIFS_NTSC 640 | 88 | #define LINE_SZ_2CIFS_NTSC 640 |
86 | #define LINE_SZ_1CIFS_NTSC 320 | 89 | #define LINE_SZ_1CIFS_NTSC 320 |
@@ -108,6 +111,9 @@ | |||
108 | #define COLOR_YUVPL 1 /* YUV planar */ | 111 | #define COLOR_YUVPL 1 /* YUV planar */ |
109 | #define COLOR_YUVPK 2 /* YUV packed */ | 112 | #define COLOR_YUVPK 2 /* YUV packed */ |
110 | #define COLOR_Y8 4 /* monochrome */ | 113 | #define COLOR_Y8 4 /* monochrome */ |
114 | #define COLOR_JPG 5 /* JPEG */ | ||
115 | #define MASK_COLOR 0xff | ||
116 | #define MASK_JPG_QUALITY 0xff00 | ||
111 | 117 | ||
112 | /* frame decimation. Not implemented by V4L yet(experimental in V4L) */ | 118 | /* frame decimation. Not implemented by V4L yet(experimental in V4L) */ |
113 | #define FDEC_1 1 /* capture every frame. default */ | 119 | #define FDEC_1 1 /* capture every frame. default */ |
@@ -148,16 +154,14 @@ struct s2255_mode { | |||
148 | u32 restart; /* if DSP requires restart */ | 154 | u32 restart; /* if DSP requires restart */ |
149 | }; | 155 | }; |
150 | 156 | ||
151 | /* frame structure */ | ||
152 | #define FRAME_STATE_UNUSED 0 | ||
153 | #define FRAME_STATE_FILLING 1 | ||
154 | #define FRAME_STATE_FULL 2 | ||
155 | 157 | ||
158 | #define S2255_READ_IDLE 0 | ||
159 | #define S2255_READ_FRAME 1 | ||
156 | 160 | ||
161 | /* frame structure */ | ||
157 | struct s2255_framei { | 162 | struct s2255_framei { |
158 | unsigned long size; | 163 | unsigned long size; |
159 | 164 | unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/ | |
160 | unsigned long ulState; /* ulState ==0 unused, 1 being filled, 2 full */ | ||
161 | void *lpvbits; /* image data */ | 165 | void *lpvbits; /* image data */ |
162 | unsigned long cur_size; /* current data copied to it */ | 166 | unsigned long cur_size; /* current data copied to it */ |
163 | }; | 167 | }; |
@@ -188,6 +192,10 @@ struct s2255_dmaqueue { | |||
188 | #define S2255_FW_FAILED 3 | 192 | #define S2255_FW_FAILED 3 |
189 | #define S2255_FW_DISCONNECTING 4 | 193 | #define S2255_FW_DISCONNECTING 4 |
190 | 194 | ||
195 | #define S2255_FW_MARKER 0x22552f2f | ||
196 | /* 2255 read states */ | ||
197 | #define S2255_READ_IDLE 0 | ||
198 | #define S2255_READ_FRAME 1 | ||
191 | struct s2255_fw { | 199 | struct s2255_fw { |
192 | int fw_loaded; | 200 | int fw_loaded; |
193 | int fw_size; | 201 | int fw_size; |
@@ -195,7 +203,6 @@ struct s2255_fw { | |||
195 | atomic_t fw_state; | 203 | atomic_t fw_state; |
196 | void *pfw_data; | 204 | void *pfw_data; |
197 | wait_queue_head_t wait_fw; | 205 | wait_queue_head_t wait_fw; |
198 | struct timer_list dsp_wait; | ||
199 | const struct firmware *fw; | 206 | const struct firmware *fw; |
200 | }; | 207 | }; |
201 | 208 | ||
@@ -237,15 +244,27 @@ struct s2255_dev { | |||
237 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; | 244 | struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; |
238 | struct s2255_bufferi buffer[MAX_CHANNELS]; | 245 | struct s2255_bufferi buffer[MAX_CHANNELS]; |
239 | struct s2255_mode mode[MAX_CHANNELS]; | 246 | struct s2255_mode mode[MAX_CHANNELS]; |
247 | /* jpeg compression */ | ||
248 | struct v4l2_jpegcompression jc[MAX_CHANNELS]; | ||
240 | const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; | 249 | const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; |
241 | int cur_frame[MAX_CHANNELS]; | 250 | int cur_frame[MAX_CHANNELS]; |
242 | int last_frame[MAX_CHANNELS]; | 251 | int last_frame[MAX_CHANNELS]; |
243 | u32 cc; /* current channel */ | 252 | u32 cc; /* current channel */ |
244 | int b_acquire[MAX_CHANNELS]; | 253 | int b_acquire[MAX_CHANNELS]; |
254 | /* allocated image size */ | ||
245 | unsigned long req_image_size[MAX_CHANNELS]; | 255 | unsigned long req_image_size[MAX_CHANNELS]; |
256 | /* received packet size */ | ||
257 | unsigned long pkt_size[MAX_CHANNELS]; | ||
246 | int bad_payload[MAX_CHANNELS]; | 258 | int bad_payload[MAX_CHANNELS]; |
247 | unsigned long frame_count[MAX_CHANNELS]; | 259 | unsigned long frame_count[MAX_CHANNELS]; |
248 | int frame_ready; | 260 | int frame_ready; |
261 | /* if JPEG image */ | ||
262 | int jpg_size[MAX_CHANNELS]; | ||
263 | /* if channel configured to default state */ | ||
264 | int chn_configured[MAX_CHANNELS]; | ||
265 | wait_queue_head_t wait_setmode[MAX_CHANNELS]; | ||
266 | int setmode_ready[MAX_CHANNELS]; | ||
267 | int chn_ready; | ||
249 | struct kref kref; | 268 | struct kref kref; |
250 | spinlock_t slock; | 269 | spinlock_t slock; |
251 | }; | 270 | }; |
@@ -306,12 +325,16 @@ static void s2255_stop_readpipe(struct s2255_dev *dev); | |||
306 | static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn); | 325 | static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn); |
307 | static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn); | 326 | static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn); |
308 | static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, | 327 | static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, |
309 | int chn); | 328 | int chn, int jpgsize); |
310 | static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, | 329 | static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, |
311 | struct s2255_mode *mode); | 330 | struct s2255_mode *mode); |
312 | static int s2255_board_shutdown(struct s2255_dev *dev); | 331 | static int s2255_board_shutdown(struct s2255_dev *dev); |
313 | static void s2255_exit_v4l(struct s2255_dev *dev); | 332 | static void s2255_exit_v4l(struct s2255_dev *dev); |
314 | static void s2255_fwload_start(struct s2255_dev *dev); | 333 | static void s2255_fwload_start(struct s2255_dev *dev, int reset); |
334 | static void s2255_destroy(struct kref *kref); | ||
335 | static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req, | ||
336 | u16 index, u16 value, void *buf, | ||
337 | s32 buf_len, int bOut); | ||
315 | 338 | ||
316 | #define dprintk(level, fmt, arg...) \ | 339 | #define dprintk(level, fmt, arg...) \ |
317 | do { \ | 340 | do { \ |
@@ -407,6 +430,10 @@ static const struct s2255_fmt formats[] = { | |||
407 | .fourcc = V4L2_PIX_FMT_UYVY, | 430 | .fourcc = V4L2_PIX_FMT_UYVY, |
408 | .depth = 16 | 431 | .depth = 16 |
409 | }, { | 432 | }, { |
433 | .name = "JPG", | ||
434 | .fourcc = V4L2_PIX_FMT_JPEG, | ||
435 | .depth = 24 | ||
436 | }, { | ||
410 | .name = "8bpp GREY", | 437 | .name = "8bpp GREY", |
411 | .fourcc = V4L2_PIX_FMT_GREY, | 438 | .fourcc = V4L2_PIX_FMT_GREY, |
412 | .depth = 8 | 439 | .depth = 8 |
@@ -464,6 +491,13 @@ static void planar422p_to_yuv_packed(const unsigned char *in, | |||
464 | return; | 491 | return; |
465 | } | 492 | } |
466 | 493 | ||
494 | static void s2255_reset_dsppower(struct s2255_dev *dev) | ||
495 | { | ||
496 | s2255_vendor_req(dev, 0x40, 0x0b0b, 0x0b0b, NULL, 0, 1); | ||
497 | msleep(10); | ||
498 | s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1); | ||
499 | return; | ||
500 | } | ||
467 | 501 | ||
468 | /* kickstarts the firmware loading. from probe | 502 | /* kickstarts the firmware loading. from probe |
469 | */ | 503 | */ |
@@ -480,18 +514,6 @@ static void s2255_timer(unsigned long user_data) | |||
480 | } | 514 | } |
481 | } | 515 | } |
482 | 516 | ||
483 | /* called when DSP is up and running. DSP is guaranteed to | ||
484 | be running after S2255_DSP_BOOTTIME */ | ||
485 | static void s2255_dsp_running(unsigned long user_data) | ||
486 | { | ||
487 | struct s2255_fw *data = (struct s2255_fw *)user_data; | ||
488 | dprintk(1, "dsp running\n"); | ||
489 | atomic_set(&data->fw_state, S2255_FW_SUCCESS); | ||
490 | wake_up(&data->wait_fw); | ||
491 | printk(KERN_INFO "s2255: firmware loaded successfully\n"); | ||
492 | return; | ||
493 | } | ||
494 | |||
495 | 517 | ||
496 | /* this loads the firmware asynchronously. | 518 | /* this loads the firmware asynchronously. |
497 | Originally this was done synchroously in probe. | 519 | Originally this was done synchroously in probe. |
@@ -549,19 +571,14 @@ static void s2255_fwchunk_complete(struct urb *urb) | |||
549 | } | 571 | } |
550 | data->fw_loaded += len; | 572 | data->fw_loaded += len; |
551 | } else { | 573 | } else { |
552 | init_timer(&data->dsp_wait); | ||
553 | data->dsp_wait.function = s2255_dsp_running; | ||
554 | data->dsp_wait.data = (unsigned long)data; | ||
555 | atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); | 574 | atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); |
556 | mod_timer(&data->dsp_wait, msecs_to_jiffies(S2255_DSP_BOOTTIME) | ||
557 | + jiffies); | ||
558 | } | 575 | } |
559 | dprintk(100, "2255 complete done\n"); | 576 | dprintk(100, "2255 complete done\n"); |
560 | return; | 577 | return; |
561 | 578 | ||
562 | } | 579 | } |
563 | 580 | ||
564 | static int s2255_got_frame(struct s2255_dev *dev, int chn) | 581 | static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize) |
565 | { | 582 | { |
566 | struct s2255_dmaqueue *dma_q = &dev->vidq[chn]; | 583 | struct s2255_dmaqueue *dma_q = &dev->vidq[chn]; |
567 | struct s2255_buffer *buf; | 584 | struct s2255_buffer *buf; |
@@ -586,8 +603,7 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn) | |||
586 | list_del(&buf->vb.queue); | 603 | list_del(&buf->vb.queue); |
587 | do_gettimeofday(&buf->vb.ts); | 604 | do_gettimeofday(&buf->vb.ts); |
588 | dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i); | 605 | dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i); |
589 | 606 | s2255_fillbuff(dev, buf, dma_q->channel, jpgsize); | |
590 | s2255_fillbuff(dev, buf, dma_q->channel); | ||
591 | wake_up(&buf->vb.done); | 607 | wake_up(&buf->vb.done); |
592 | dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); | 608 | dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); |
593 | unlock: | 609 | unlock: |
@@ -621,7 +637,7 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc) | |||
621 | * | 637 | * |
622 | */ | 638 | */ |
623 | static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, | 639 | static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, |
624 | int chn) | 640 | int chn, int jpgsize) |
625 | { | 641 | { |
626 | int pos = 0; | 642 | int pos = 0; |
627 | struct timeval ts; | 643 | struct timeval ts; |
@@ -649,6 +665,10 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, | |||
649 | case V4L2_PIX_FMT_GREY: | 665 | case V4L2_PIX_FMT_GREY: |
650 | memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height); | 666 | memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height); |
651 | break; | 667 | break; |
668 | case V4L2_PIX_FMT_JPEG: | ||
669 | buf->vb.size = jpgsize; | ||
670 | memcpy(vbuf, tmpbuf, buf->vb.size); | ||
671 | break; | ||
652 | case V4L2_PIX_FMT_YUV422P: | 672 | case V4L2_PIX_FMT_YUV422P: |
653 | memcpy(vbuf, tmpbuf, | 673 | memcpy(vbuf, tmpbuf, |
654 | buf->vb.width * buf->vb.height * 2); | 674 | buf->vb.width * buf->vb.height * 2); |
@@ -657,9 +677,6 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, | |||
657 | printk(KERN_DEBUG "s2255: unknown format?\n"); | 677 | printk(KERN_DEBUG "s2255: unknown format?\n"); |
658 | } | 678 | } |
659 | dev->last_frame[chn] = -1; | 679 | dev->last_frame[chn] = -1; |
660 | /* done with the frame, free it */ | ||
661 | frm->ulState = 0; | ||
662 | dprintk(4, "freeing buffer\n"); | ||
663 | } else { | 680 | } else { |
664 | printk(KERN_ERR "s2255: =======no frame\n"); | 681 | printk(KERN_ERR "s2255: =======no frame\n"); |
665 | return; | 682 | return; |
@@ -1021,6 +1038,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1021 | case V4L2_PIX_FMT_GREY: | 1038 | case V4L2_PIX_FMT_GREY: |
1022 | fh->mode.color = COLOR_Y8; | 1039 | fh->mode.color = COLOR_Y8; |
1023 | break; | 1040 | break; |
1041 | case V4L2_PIX_FMT_JPEG: | ||
1042 | fh->mode.color = COLOR_JPG | | ||
1043 | (fh->dev->jc[fh->channel].quality << 8); | ||
1044 | break; | ||
1024 | case V4L2_PIX_FMT_YUV422P: | 1045 | case V4L2_PIX_FMT_YUV422P: |
1025 | fh->mode.color = COLOR_YUVPL; | 1046 | fh->mode.color = COLOR_YUVPL; |
1026 | break; | 1047 | break; |
@@ -1139,7 +1160,7 @@ static u32 get_transfer_size(struct s2255_mode *mode) | |||
1139 | } | 1160 | } |
1140 | } | 1161 | } |
1141 | outImageSize = linesPerFrame * pixelsPerLine; | 1162 | outImageSize = linesPerFrame * pixelsPerLine; |
1142 | if (mode->color != COLOR_Y8) { | 1163 | if ((mode->color & MASK_COLOR) != COLOR_Y8) { |
1143 | /* 2 bytes/pixel if not monochrome */ | 1164 | /* 2 bytes/pixel if not monochrome */ |
1144 | outImageSize *= 2; | 1165 | outImageSize *= 2; |
1145 | } | 1166 | } |
@@ -1185,12 +1206,17 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, | |||
1185 | u32 *buffer; | 1206 | u32 *buffer; |
1186 | unsigned long chn_rev; | 1207 | unsigned long chn_rev; |
1187 | 1208 | ||
1209 | mutex_lock(&dev->lock); | ||
1188 | chn_rev = G_chnmap[chn]; | 1210 | chn_rev = G_chnmap[chn]; |
1189 | dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale); | 1211 | dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale); |
1190 | dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn], | 1212 | dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn], |
1191 | dev->mode[chn].scale); | 1213 | dev->mode[chn].scale); |
1192 | dprintk(2, "mode contrast %x\n", mode->contrast); | 1214 | dprintk(2, "mode contrast %x\n", mode->contrast); |
1193 | 1215 | ||
1216 | /* if JPEG, set the quality */ | ||
1217 | if ((mode->color & MASK_COLOR) == COLOR_JPG) | ||
1218 | mode->color = (dev->jc[chn].quality << 8) | COLOR_JPG; | ||
1219 | |||
1194 | /* save the mode */ | 1220 | /* save the mode */ |
1195 | dev->mode[chn] = *mode; | 1221 | dev->mode[chn] = *mode; |
1196 | dev->req_image_size[chn] = get_transfer_size(mode); | 1222 | dev->req_image_size[chn] = get_transfer_size(mode); |
@@ -1199,6 +1225,7 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, | |||
1199 | buffer = kzalloc(512, GFP_KERNEL); | 1225 | buffer = kzalloc(512, GFP_KERNEL); |
1200 | if (buffer == NULL) { | 1226 | if (buffer == NULL) { |
1201 | dev_err(&dev->udev->dev, "out of mem\n"); | 1227 | dev_err(&dev->udev->dev, "out of mem\n"); |
1228 | mutex_unlock(&dev->lock); | ||
1202 | return -ENOMEM; | 1229 | return -ENOMEM; |
1203 | } | 1230 | } |
1204 | 1231 | ||
@@ -1214,12 +1241,20 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, | |||
1214 | dprintk(1, "set mode done chn %lu, %d\n", chn, res); | 1241 | dprintk(1, "set mode done chn %lu, %d\n", chn, res); |
1215 | 1242 | ||
1216 | /* wait at least 3 frames before continuing */ | 1243 | /* wait at least 3 frames before continuing */ |
1217 | if (mode->restart) | 1244 | if (mode->restart) { |
1218 | msleep(125); | 1245 | dev->setmode_ready[chn] = 0; |
1246 | wait_event_timeout(dev->wait_setmode[chn], | ||
1247 | (dev->setmode_ready[chn] != 0), | ||
1248 | msecs_to_jiffies(S2255_SETMODE_TIMEOUT)); | ||
1249 | if (dev->setmode_ready[chn] != 1) { | ||
1250 | printk(KERN_DEBUG "s2255: no set mode response\n"); | ||
1251 | res = -EFAULT; | ||
1252 | } | ||
1253 | } | ||
1219 | 1254 | ||
1220 | /* clear the restart flag */ | 1255 | /* clear the restart flag */ |
1221 | dev->mode[chn].restart = 0; | 1256 | dev->mode[chn].restart = 0; |
1222 | 1257 | mutex_unlock(&dev->lock); | |
1223 | return res; | 1258 | return res; |
1224 | } | 1259 | } |
1225 | 1260 | ||
@@ -1270,7 +1305,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1270 | dev->cur_frame[chn] = 0; | 1305 | dev->cur_frame[chn] = 0; |
1271 | dev->frame_count[chn] = 0; | 1306 | dev->frame_count[chn] = 0; |
1272 | for (j = 0; j < SYS_FRAMES; j++) { | 1307 | for (j = 0; j < SYS_FRAMES; j++) { |
1273 | dev->buffer[chn].frame[j].ulState = 0; | 1308 | dev->buffer[chn].frame[j].ulState = S2255_READ_IDLE; |
1274 | dev->buffer[chn].frame[j].cur_size = 0; | 1309 | dev->buffer[chn].frame[j].cur_size = 0; |
1275 | } | 1310 | } |
1276 | res = videobuf_streamon(&fh->vb_vidq); | 1311 | res = videobuf_streamon(&fh->vb_vidq); |
@@ -1446,6 +1481,27 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1446 | return -EINVAL; | 1481 | return -EINVAL; |
1447 | } | 1482 | } |
1448 | 1483 | ||
1484 | static int vidioc_g_jpegcomp(struct file *file, void *priv, | ||
1485 | struct v4l2_jpegcompression *jc) | ||
1486 | { | ||
1487 | struct s2255_fh *fh = priv; | ||
1488 | struct s2255_dev *dev = fh->dev; | ||
1489 | *jc = dev->jc[fh->channel]; | ||
1490 | dprintk(2, "getting jpegcompression, quality %d\n", jc->quality); | ||
1491 | return 0; | ||
1492 | } | ||
1493 | |||
1494 | static int vidioc_s_jpegcomp(struct file *file, void *priv, | ||
1495 | struct v4l2_jpegcompression *jc) | ||
1496 | { | ||
1497 | struct s2255_fh *fh = priv; | ||
1498 | struct s2255_dev *dev = fh->dev; | ||
1499 | if (jc->quality < 0 || jc->quality > 100) | ||
1500 | return -EINVAL; | ||
1501 | dev->jc[fh->channel].quality = jc->quality; | ||
1502 | dprintk(2, "setting jpeg quality %d\n", jc->quality); | ||
1503 | return 0; | ||
1504 | } | ||
1449 | static int s2255_open(struct inode *inode, struct file *file) | 1505 | static int s2255_open(struct inode *inode, struct file *file) |
1450 | { | 1506 | { |
1451 | int minor = iminor(inode); | 1507 | int minor = iminor(inode); |
@@ -1455,8 +1511,10 @@ static int s2255_open(struct inode *inode, struct file *file) | |||
1455 | enum v4l2_buf_type type = 0; | 1511 | enum v4l2_buf_type type = 0; |
1456 | int i = 0; | 1512 | int i = 0; |
1457 | int cur_channel = -1; | 1513 | int cur_channel = -1; |
1514 | int state; | ||
1458 | dprintk(1, "s2255: open called (minor=%d)\n", minor); | 1515 | dprintk(1, "s2255: open called (minor=%d)\n", minor); |
1459 | 1516 | ||
1517 | lock_kernel(); | ||
1460 | list_for_each(list, &s2255_devlist) { | 1518 | list_for_each(list, &s2255_devlist) { |
1461 | h = list_entry(list, struct s2255_dev, s2255_devlist); | 1519 | h = list_entry(list, struct s2255_dev, s2255_devlist); |
1462 | for (i = 0; i < MAX_CHANNELS; i++) { | 1520 | for (i = 0; i < MAX_CHANNELS; i++) { |
@@ -1469,45 +1527,78 @@ static int s2255_open(struct inode *inode, struct file *file) | |||
1469 | } | 1527 | } |
1470 | 1528 | ||
1471 | if ((NULL == dev) || (cur_channel == -1)) { | 1529 | if ((NULL == dev) || (cur_channel == -1)) { |
1472 | dprintk(1, "s2255: openv4l no dev\n"); | 1530 | unlock_kernel(); |
1531 | printk(KERN_INFO "s2255: openv4l no dev\n"); | ||
1473 | return -ENODEV; | 1532 | return -ENODEV; |
1474 | } | 1533 | } |
1475 | 1534 | ||
1535 | if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_DISCONNECTING) { | ||
1536 | unlock_kernel(); | ||
1537 | printk(KERN_INFO "disconnecting\n"); | ||
1538 | return -ENODEV; | ||
1539 | } | ||
1540 | kref_get(&dev->kref); | ||
1476 | mutex_lock(&dev->open_lock); | 1541 | mutex_lock(&dev->open_lock); |
1477 | 1542 | ||
1478 | dev->users[cur_channel]++; | 1543 | dev->users[cur_channel]++; |
1479 | dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]); | 1544 | dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]); |
1480 | 1545 | ||
1481 | if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_FAILED) { | 1546 | switch (atomic_read(&dev->fw_data->fw_state)) { |
1547 | case S2255_FW_FAILED: | ||
1482 | err("2255 firmware load failed. retrying.\n"); | 1548 | err("2255 firmware load failed. retrying.\n"); |
1483 | s2255_fwload_start(dev); | 1549 | s2255_fwload_start(dev, 1); |
1484 | wait_event_timeout(dev->fw_data->wait_fw, | 1550 | wait_event_timeout(dev->fw_data->wait_fw, |
1485 | (atomic_read(&dev->fw_data->fw_state) | 1551 | ((atomic_read(&dev->fw_data->fw_state) |
1486 | != S2255_FW_NOTLOADED), | 1552 | == S2255_FW_SUCCESS) || |
1553 | (atomic_read(&dev->fw_data->fw_state) | ||
1554 | == S2255_FW_DISCONNECTING)), | ||
1487 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); | 1555 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); |
1488 | if (atomic_read(&dev->fw_data->fw_state) | 1556 | break; |
1489 | != S2255_FW_SUCCESS) { | 1557 | case S2255_FW_NOTLOADED: |
1490 | printk(KERN_INFO "2255 FW load failed.\n"); | 1558 | case S2255_FW_LOADED_DSPWAIT: |
1491 | dev->users[cur_channel]--; | ||
1492 | mutex_unlock(&dev->open_lock); | ||
1493 | return -EFAULT; | ||
1494 | } | ||
1495 | } else if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_NOTLOADED) { | ||
1496 | /* give S2255_LOAD_TIMEOUT time for firmware to load in case | 1559 | /* give S2255_LOAD_TIMEOUT time for firmware to load in case |
1497 | driver loaded and then device immediately opened */ | 1560 | driver loaded and then device immediately opened */ |
1498 | printk(KERN_INFO "%s waiting for firmware load\n", __func__); | 1561 | printk(KERN_INFO "%s waiting for firmware load\n", __func__); |
1499 | wait_event_timeout(dev->fw_data->wait_fw, | 1562 | wait_event_timeout(dev->fw_data->wait_fw, |
1500 | (atomic_read(&dev->fw_data->fw_state) | 1563 | ((atomic_read(&dev->fw_data->fw_state) |
1501 | != S2255_FW_NOTLOADED), | 1564 | == S2255_FW_SUCCESS) || |
1502 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); | 1565 | (atomic_read(&dev->fw_data->fw_state) |
1503 | if (atomic_read(&dev->fw_data->fw_state) | 1566 | == S2255_FW_DISCONNECTING)), |
1504 | != S2255_FW_SUCCESS) { | 1567 | msecs_to_jiffies(S2255_LOAD_TIMEOUT)); |
1505 | printk(KERN_INFO "2255 firmware not loaded" | 1568 | break; |
1506 | "try again\n"); | 1569 | case S2255_FW_SUCCESS: |
1507 | dev->users[cur_channel]--; | 1570 | default: |
1508 | mutex_unlock(&dev->open_lock); | 1571 | break; |
1509 | return -EBUSY; | 1572 | } |
1573 | state = atomic_read(&dev->fw_data->fw_state); | ||
1574 | if (state != S2255_FW_SUCCESS) { | ||
1575 | int rc; | ||
1576 | switch (state) { | ||
1577 | case S2255_FW_FAILED: | ||
1578 | printk(KERN_INFO "2255 FW load failed. %d\n", state); | ||
1579 | rc = -ENODEV; | ||
1580 | break; | ||
1581 | case S2255_FW_DISCONNECTING: | ||
1582 | printk(KERN_INFO "%s: disconnecting\n", __func__); | ||
1583 | rc = -ENODEV; | ||
1584 | break; | ||
1585 | case S2255_FW_LOADED_DSPWAIT: | ||
1586 | case S2255_FW_NOTLOADED: | ||
1587 | printk(KERN_INFO "%s: firmware not loaded yet" | ||
1588 | "please try again later\n", | ||
1589 | __func__); | ||
1590 | rc = -EAGAIN; | ||
1591 | break; | ||
1592 | default: | ||
1593 | printk(KERN_INFO "%s: unknown state\n", __func__); | ||
1594 | rc = -EFAULT; | ||
1595 | break; | ||
1510 | } | 1596 | } |
1597 | dev->users[cur_channel]--; | ||
1598 | mutex_unlock(&dev->open_lock); | ||
1599 | kref_put(&dev->kref, s2255_destroy); | ||
1600 | unlock_kernel(); | ||
1601 | return rc; | ||
1511 | } | 1602 | } |
1512 | 1603 | ||
1513 | /* allocate + initialize per filehandle data */ | 1604 | /* allocate + initialize per filehandle data */ |
@@ -1515,6 +1606,8 @@ static int s2255_open(struct inode *inode, struct file *file) | |||
1515 | if (NULL == fh) { | 1606 | if (NULL == fh) { |
1516 | dev->users[cur_channel]--; | 1607 | dev->users[cur_channel]--; |
1517 | mutex_unlock(&dev->open_lock); | 1608 | mutex_unlock(&dev->open_lock); |
1609 | kref_put(&dev->kref, s2255_destroy); | ||
1610 | unlock_kernel(); | ||
1518 | return -ENOMEM; | 1611 | return -ENOMEM; |
1519 | } | 1612 | } |
1520 | 1613 | ||
@@ -1528,6 +1621,13 @@ static int s2255_open(struct inode *inode, struct file *file) | |||
1528 | fh->height = NUM_LINES_4CIFS_NTSC * 2; | 1621 | fh->height = NUM_LINES_4CIFS_NTSC * 2; |
1529 | fh->channel = cur_channel; | 1622 | fh->channel = cur_channel; |
1530 | 1623 | ||
1624 | /* configure channel to default state */ | ||
1625 | if (!dev->chn_configured[cur_channel]) { | ||
1626 | s2255_set_mode(dev, cur_channel, &fh->mode); | ||
1627 | dev->chn_configured[cur_channel] = 1; | ||
1628 | } | ||
1629 | |||
1630 | |||
1531 | /* Put all controls at a sane state */ | 1631 | /* Put all controls at a sane state */ |
1532 | for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) | 1632 | for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) |
1533 | qctl_regs[i] = s2255_qctrl[i].default_value; | 1633 | qctl_regs[i] = s2255_qctrl[i].default_value; |
@@ -1546,8 +1646,8 @@ static int s2255_open(struct inode *inode, struct file *file) | |||
1546 | V4L2_FIELD_INTERLACED, | 1646 | V4L2_FIELD_INTERLACED, |
1547 | sizeof(struct s2255_buffer), fh); | 1647 | sizeof(struct s2255_buffer), fh); |
1548 | 1648 | ||
1549 | kref_get(&dev->kref); | ||
1550 | mutex_unlock(&dev->open_lock); | 1649 | mutex_unlock(&dev->open_lock); |
1650 | unlock_kernel(); | ||
1551 | return 0; | 1651 | return 0; |
1552 | } | 1652 | } |
1553 | 1653 | ||
@@ -1569,30 +1669,24 @@ static unsigned int s2255_poll(struct file *file, | |||
1569 | static void s2255_destroy(struct kref *kref) | 1669 | static void s2255_destroy(struct kref *kref) |
1570 | { | 1670 | { |
1571 | struct s2255_dev *dev = to_s2255_dev(kref); | 1671 | struct s2255_dev *dev = to_s2255_dev(kref); |
1672 | struct list_head *list; | ||
1673 | int i; | ||
1572 | if (!dev) { | 1674 | if (!dev) { |
1573 | printk(KERN_ERR "s2255drv: kref problem\n"); | 1675 | printk(KERN_ERR "s2255drv: kref problem\n"); |
1574 | return; | 1676 | return; |
1575 | } | 1677 | } |
1576 | |||
1577 | /* | ||
1578 | * Wake up any firmware load waiting (only done in .open, | ||
1579 | * which holds the open_lock mutex) | ||
1580 | */ | ||
1581 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); | 1678 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); |
1582 | wake_up(&dev->fw_data->wait_fw); | 1679 | wake_up(&dev->fw_data->wait_fw); |
1583 | 1680 | for (i = 0; i < MAX_CHANNELS; i++) { | |
1584 | /* prevent s2255_disconnect from racing s2255_open */ | 1681 | dev->setmode_ready[i] = 1; |
1682 | wake_up(&dev->wait_setmode[i]); | ||
1683 | } | ||
1585 | mutex_lock(&dev->open_lock); | 1684 | mutex_lock(&dev->open_lock); |
1685 | /* reset the DSP so firmware can be reload next time */ | ||
1686 | s2255_reset_dsppower(dev); | ||
1586 | s2255_exit_v4l(dev); | 1687 | s2255_exit_v4l(dev); |
1587 | /* | ||
1588 | * device unregistered so no longer possible to open. open_mutex | ||
1589 | * can be unlocked and timers deleted afterwards. | ||
1590 | */ | ||
1591 | mutex_unlock(&dev->open_lock); | ||
1592 | |||
1593 | /* board shutdown stops the read pipe if it is running */ | 1688 | /* board shutdown stops the read pipe if it is running */ |
1594 | s2255_board_shutdown(dev); | 1689 | s2255_board_shutdown(dev); |
1595 | |||
1596 | /* make sure firmware still not trying to load */ | 1690 | /* make sure firmware still not trying to load */ |
1597 | del_timer(&dev->timer); /* only started in .probe and .open */ | 1691 | del_timer(&dev->timer); /* only started in .probe and .open */ |
1598 | 1692 | ||
@@ -1602,23 +1696,19 @@ static void s2255_destroy(struct kref *kref) | |||
1602 | usb_free_urb(dev->fw_data->fw_urb); | 1696 | usb_free_urb(dev->fw_data->fw_urb); |
1603 | dev->fw_data->fw_urb = NULL; | 1697 | dev->fw_data->fw_urb = NULL; |
1604 | } | 1698 | } |
1605 | |||
1606 | /* | ||
1607 | * delete the dsp_wait timer, which sets the firmware | ||
1608 | * state on completion. This is done before fw_data | ||
1609 | * is freed below. | ||
1610 | */ | ||
1611 | |||
1612 | del_timer(&dev->fw_data->dsp_wait); /* only started in .open */ | ||
1613 | |||
1614 | if (dev->fw_data->fw) | 1699 | if (dev->fw_data->fw) |
1615 | release_firmware(dev->fw_data->fw); | 1700 | release_firmware(dev->fw_data->fw); |
1616 | kfree(dev->fw_data->pfw_data); | 1701 | kfree(dev->fw_data->pfw_data); |
1617 | kfree(dev->fw_data); | 1702 | kfree(dev->fw_data); |
1618 | |||
1619 | usb_put_dev(dev->udev); | 1703 | usb_put_dev(dev->udev); |
1620 | dprintk(1, "%s", __func__); | 1704 | dprintk(1, "%s", __func__); |
1621 | kfree(dev); | 1705 | kfree(dev); |
1706 | |||
1707 | while (!list_empty(&s2255_devlist)) { | ||
1708 | list = s2255_devlist.next; | ||
1709 | list_del(list); | ||
1710 | } | ||
1711 | mutex_unlock(&dev->open_lock); | ||
1622 | } | 1712 | } |
1623 | 1713 | ||
1624 | static int s2255_close(struct inode *inode, struct file *file) | 1714 | static int s2255_close(struct inode *inode, struct file *file) |
@@ -1702,6 +1792,8 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
1702 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1792 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1703 | .vidiocgmbuf = vidioc_cgmbuf, | 1793 | .vidiocgmbuf = vidioc_cgmbuf, |
1704 | #endif | 1794 | #endif |
1795 | .vidioc_s_jpegcomp = vidioc_s_jpegcomp, | ||
1796 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, | ||
1705 | }; | 1797 | }; |
1706 | 1798 | ||
1707 | static struct video_device template = { | 1799 | static struct video_device template = { |
@@ -1740,7 +1832,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1740 | ret = video_register_device(dev->vdev[i], | 1832 | ret = video_register_device(dev->vdev[i], |
1741 | VFL_TYPE_GRABBER, | 1833 | VFL_TYPE_GRABBER, |
1742 | cur_nr + i); | 1834 | cur_nr + i); |
1743 | dev->vdev[i]->priv = dev; | 1835 | video_set_drvdata(dev->vdev[i], dev); |
1744 | 1836 | ||
1745 | if (ret != 0) { | 1837 | if (ret != 0) { |
1746 | dev_err(&dev->udev->dev, | 1838 | dev_err(&dev->udev->dev, |
@@ -1754,18 +1846,16 @@ static int s2255_probe_v4l(struct s2255_dev *dev) | |||
1754 | 1846 | ||
1755 | static void s2255_exit_v4l(struct s2255_dev *dev) | 1847 | static void s2255_exit_v4l(struct s2255_dev *dev) |
1756 | { | 1848 | { |
1757 | struct list_head *list; | 1849 | |
1758 | int i; | 1850 | int i; |
1759 | /* unregister the video devices */ | ||
1760 | while (!list_empty(&s2255_devlist)) { | ||
1761 | list = s2255_devlist.next; | ||
1762 | list_del(list); | ||
1763 | } | ||
1764 | for (i = 0; i < MAX_CHANNELS; i++) { | 1851 | for (i = 0; i < MAX_CHANNELS; i++) { |
1765 | if (-1 != dev->vdev[i]->minor) | 1852 | if (-1 != dev->vdev[i]->minor) { |
1766 | video_unregister_device(dev->vdev[i]); | 1853 | video_unregister_device(dev->vdev[i]); |
1767 | else | 1854 | printk(KERN_INFO "s2255 unregistered\n"); |
1855 | } else { | ||
1768 | video_device_release(dev->vdev[i]); | 1856 | video_device_release(dev->vdev[i]); |
1857 | printk(KERN_INFO "s2255 released\n"); | ||
1858 | } | ||
1769 | } | 1859 | } |
1770 | } | 1860 | } |
1771 | 1861 | ||
@@ -1775,134 +1865,123 @@ static void s2255_exit_v4l(struct s2255_dev *dev) | |||
1775 | * function again). | 1865 | * function again). |
1776 | * | 1866 | * |
1777 | * Received frame structure: | 1867 | * Received frame structure: |
1778 | * bytes 0-3: marker : 0x2255DA4AL (FRAME_MARKER) | 1868 | * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME) |
1779 | * bytes 4-7: channel: 0-3 | 1869 | * bytes 4-7: channel: 0-3 |
1780 | * bytes 8-11: payload size: size of the frame | 1870 | * bytes 8-11: payload size: size of the frame |
1781 | * bytes 12-payloadsize+12: frame data | 1871 | * bytes 12-payloadsize+12: frame data |
1782 | */ | 1872 | */ |
1783 | static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | 1873 | static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) |
1784 | { | 1874 | { |
1785 | static int dbgsync; /* = 0; */ | ||
1786 | char *pdest; | 1875 | char *pdest; |
1787 | u32 offset = 0; | 1876 | u32 offset = 0; |
1788 | int bsync = 0; | 1877 | int bframe = 0; |
1789 | int btrunc = 0; | ||
1790 | char *psrc; | 1878 | char *psrc; |
1791 | unsigned long copy_size; | 1879 | unsigned long copy_size; |
1792 | unsigned long size; | 1880 | unsigned long size; |
1793 | s32 idx = -1; | 1881 | s32 idx = -1; |
1794 | struct s2255_framei *frm; | 1882 | struct s2255_framei *frm; |
1795 | unsigned char *pdata; | 1883 | unsigned char *pdata; |
1796 | unsigned long cur_size; | 1884 | |
1797 | int bsearch = 0; | ||
1798 | struct s2255_bufferi *buf; | ||
1799 | dprintk(100, "buffer to user\n"); | 1885 | dprintk(100, "buffer to user\n"); |
1800 | 1886 | ||
1801 | idx = dev->cur_frame[dev->cc]; | 1887 | idx = dev->cur_frame[dev->cc]; |
1802 | buf = &dev->buffer[dev->cc]; | 1888 | frm = &dev->buffer[dev->cc].frame[idx]; |
1803 | frm = &buf->frame[idx]; | ||
1804 | |||
1805 | if (frm->ulState == 0) { | ||
1806 | frm->ulState = 1; | ||
1807 | frm->cur_size = 0; | ||
1808 | bsearch = 1; | ||
1809 | } else if (frm->ulState == 2) { | ||
1810 | /* system frame was not freed */ | ||
1811 | dprintk(2, "sys frame not free. overrun ringbuf\n"); | ||
1812 | bsearch = 1; | ||
1813 | frm->ulState = 1; | ||
1814 | frm->cur_size = 0; | ||
1815 | } | ||
1816 | |||
1817 | if (bsearch) { | ||
1818 | if (*(s32 *) pipe_info->transfer_buffer != FRAME_MARKER) { | ||
1819 | u32 jj; | ||
1820 | if (dbgsync == 0) { | ||
1821 | dprintk(3, "not synched, discarding all packets" | ||
1822 | "until marker\n"); | ||
1823 | 1889 | ||
1824 | dbgsync++; | 1890 | if (frm->ulState == S2255_READ_IDLE) { |
1825 | } | 1891 | int jj; |
1826 | pdata = (unsigned char *)pipe_info->transfer_buffer; | 1892 | unsigned int cc; |
1827 | for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); | 1893 | s32 *pdword; |
1828 | jj++) { | 1894 | int payload; |
1829 | if (*(s32 *) pdata == FRAME_MARKER) { | 1895 | /* search for marker codes */ |
1830 | int cc; | 1896 | pdata = (unsigned char *)pipe_info->transfer_buffer; |
1831 | dprintk(3, | 1897 | for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) { |
1832 | "found frame marker at offset:" | 1898 | switch (*(s32 *) pdata) { |
1833 | " %d [%x %x]\n", jj, pdata[0], | 1899 | case S2255_MARKER_FRAME: |
1834 | pdata[1]); | 1900 | pdword = (s32 *)pdata; |
1835 | offset = jj; | 1901 | dprintk(4, "found frame marker at offset:" |
1836 | bsync = 1; | 1902 | " %d [%x %x]\n", jj, pdata[0], |
1837 | cc = *(u32 *) (pdata + sizeof(u32)); | 1903 | pdata[1]); |
1838 | if (cc >= MAX_CHANNELS) { | 1904 | offset = jj + PREFIX_SIZE; |
1839 | printk(KERN_ERR | 1905 | bframe = 1; |
1840 | "bad channel\n"); | 1906 | cc = pdword[1]; |
1841 | return -EINVAL; | 1907 | if (cc >= MAX_CHANNELS) { |
1842 | } | 1908 | printk(KERN_ERR |
1843 | /* reverse it */ | 1909 | "bad channel\n"); |
1844 | dev->cc = G_chnmap[cc]; | 1910 | return -EINVAL; |
1911 | } | ||
1912 | /* reverse it */ | ||
1913 | dev->cc = G_chnmap[cc]; | ||
1914 | payload = pdword[3]; | ||
1915 | if (payload > dev->req_image_size[dev->cc]) { | ||
1916 | dev->bad_payload[dev->cc]++; | ||
1917 | /* discard the bad frame */ | ||
1918 | return -EINVAL; | ||
1919 | } | ||
1920 | dev->pkt_size[dev->cc] = payload; | ||
1921 | dev->jpg_size[dev->cc] = pdword[4]; | ||
1922 | break; | ||
1923 | case S2255_MARKER_RESPONSE: | ||
1924 | pdword = (s32 *)pdata; | ||
1925 | pdata += DEF_USB_BLOCK; | ||
1926 | jj += DEF_USB_BLOCK; | ||
1927 | if (pdword[1] >= MAX_CHANNELS) | ||
1928 | break; | ||
1929 | cc = G_chnmap[pdword[1]]; | ||
1930 | if (!(cc >= 0 && cc < MAX_CHANNELS)) | ||
1931 | break; | ||
1932 | switch (pdword[2]) { | ||
1933 | case 0x01: | ||
1934 | /* check if channel valid */ | ||
1935 | /* set mode ready */ | ||
1936 | dev->setmode_ready[cc] = 1; | ||
1937 | wake_up(&dev->wait_setmode[cc]); | ||
1938 | dprintk(5, "setmode ready %d\n", cc); | ||
1845 | break; | 1939 | break; |
1940 | case 0x10: | ||
1941 | |||
1942 | dev->chn_ready |= (1 << cc); | ||
1943 | if ((dev->chn_ready & 0x0f) != 0x0f) | ||
1944 | break; | ||
1945 | /* all channels ready */ | ||
1946 | printk(KERN_INFO "s2255: fw loaded\n"); | ||
1947 | atomic_set(&dev->fw_data->fw_state, | ||
1948 | S2255_FW_SUCCESS); | ||
1949 | wake_up(&dev->fw_data->wait_fw); | ||
1950 | break; | ||
1951 | default: | ||
1952 | printk(KERN_INFO "s2255 unknwn resp\n"); | ||
1846 | } | 1953 | } |
1954 | default: | ||
1847 | pdata++; | 1955 | pdata++; |
1956 | break; | ||
1848 | } | 1957 | } |
1849 | if (bsync == 0) | 1958 | if (bframe) |
1850 | return -EINVAL; | 1959 | break; |
1851 | } else { | 1960 | } /* for */ |
1852 | u32 *pword; | 1961 | if (!bframe) |
1853 | u32 payload; | 1962 | return -EINVAL; |
1854 | int cc; | ||
1855 | dbgsync = 0; | ||
1856 | bsync = 1; | ||
1857 | pword = (u32 *) pipe_info->transfer_buffer; | ||
1858 | cc = pword[1]; | ||
1859 | |||
1860 | if (cc >= MAX_CHANNELS) { | ||
1861 | printk("invalid channel found. " | ||
1862 | "throwing out data!\n"); | ||
1863 | return -EINVAL; | ||
1864 | } | ||
1865 | dev->cc = G_chnmap[cc]; | ||
1866 | payload = pword[2]; | ||
1867 | if (payload != dev->req_image_size[dev->cc]) { | ||
1868 | dprintk(1, "[%d][%d]unexpected payload: %d" | ||
1869 | "required: %lu \n", cc, dev->cc, | ||
1870 | payload, dev->req_image_size[dev->cc]); | ||
1871 | dev->bad_payload[dev->cc]++; | ||
1872 | /* discard the bad frame */ | ||
1873 | return -EINVAL; | ||
1874 | } | ||
1875 | |||
1876 | } | ||
1877 | } | ||
1878 | /* search done. now find out if should be acquiring | ||
1879 | on this channel */ | ||
1880 | if (!dev->b_acquire[dev->cc]) { | ||
1881 | frm->ulState = 0; | ||
1882 | return -EINVAL; | ||
1883 | } | 1963 | } |
1884 | 1964 | ||
1965 | |||
1885 | idx = dev->cur_frame[dev->cc]; | 1966 | idx = dev->cur_frame[dev->cc]; |
1886 | frm = &dev->buffer[dev->cc].frame[idx]; | 1967 | frm = &dev->buffer[dev->cc].frame[idx]; |
1887 | 1968 | ||
1888 | if (frm->ulState == 0) { | 1969 | /* search done. now find out if should be acquiring on this channel */ |
1889 | frm->ulState = 1; | 1970 | if (!dev->b_acquire[dev->cc]) { |
1890 | frm->cur_size = 0; | 1971 | /* we found a frame, but this channel is turned off */ |
1891 | } else if (frm->ulState == 2) { | 1972 | frm->ulState = S2255_READ_IDLE; |
1892 | /* system frame ring buffer overrun */ | 1973 | return -EINVAL; |
1893 | dprintk(2, "sys frame overrun. overwriting frame %d %d\n", | ||
1894 | dev->cc, idx); | ||
1895 | frm->ulState = 1; | ||
1896 | frm->cur_size = 0; | ||
1897 | } | 1974 | } |
1898 | 1975 | ||
1899 | if (bsync) { | 1976 | if (frm->ulState == S2255_READ_IDLE) { |
1900 | /* skip the marker 512 bytes (and offset if out of sync) */ | 1977 | frm->ulState = S2255_READ_FRAME; |
1901 | psrc = (u8 *)pipe_info->transfer_buffer + offset + PREFIX_SIZE; | 1978 | frm->cur_size = 0; |
1902 | } else { | ||
1903 | psrc = (u8 *)pipe_info->transfer_buffer; | ||
1904 | } | 1979 | } |
1905 | 1980 | ||
1981 | /* skip the marker 512 bytes (and offset if out of sync) */ | ||
1982 | psrc = (u8 *)pipe_info->transfer_buffer + offset; | ||
1983 | |||
1984 | |||
1906 | if (frm->lpvbits == NULL) { | 1985 | if (frm->lpvbits == NULL) { |
1907 | dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d", | 1986 | dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d", |
1908 | frm, dev, dev->cc, idx); | 1987 | frm, dev, dev->cc, idx); |
@@ -1911,33 +1990,20 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | |||
1911 | 1990 | ||
1912 | pdest = frm->lpvbits + frm->cur_size; | 1991 | pdest = frm->lpvbits + frm->cur_size; |
1913 | 1992 | ||
1914 | if (bsync) { | 1993 | copy_size = (pipe_info->cur_transfer_size - offset); |
1915 | copy_size = | ||
1916 | (pipe_info->cur_transfer_size - offset) - PREFIX_SIZE; | ||
1917 | if (copy_size > pipe_info->cur_transfer_size) { | ||
1918 | printk("invalid copy size, overflow!\n"); | ||
1919 | return -ENOMEM; | ||
1920 | } | ||
1921 | } else { | ||
1922 | copy_size = pipe_info->cur_transfer_size; | ||
1923 | } | ||
1924 | 1994 | ||
1925 | cur_size = frm->cur_size; | 1995 | size = dev->pkt_size[dev->cc] - PREFIX_SIZE; |
1926 | size = dev->req_image_size[dev->cc]; | ||
1927 | 1996 | ||
1928 | if ((copy_size + cur_size) > size) { | 1997 | /* sanity check on pdest */ |
1929 | copy_size = size - cur_size; | 1998 | if ((copy_size + frm->cur_size) < dev->req_image_size[dev->cc]) |
1930 | btrunc = 1; | 1999 | memcpy(pdest, psrc, copy_size); |
1931 | } | ||
1932 | 2000 | ||
1933 | memcpy(pdest, psrc, copy_size); | ||
1934 | cur_size += copy_size; | ||
1935 | frm->cur_size += copy_size; | 2001 | frm->cur_size += copy_size; |
1936 | dprintk(50, "cur_size size %lu size %lu \n", cur_size, size); | 2002 | dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size); |
2003 | |||
2004 | if (frm->cur_size >= size) { | ||
1937 | 2005 | ||
1938 | if (cur_size >= (size - PREFIX_SIZE)) { | ||
1939 | u32 cc = dev->cc; | 2006 | u32 cc = dev->cc; |
1940 | frm->ulState = 2; | ||
1941 | dprintk(2, "****************[%d]Buffer[%d]full*************\n", | 2007 | dprintk(2, "****************[%d]Buffer[%d]full*************\n", |
1942 | cc, idx); | 2008 | cc, idx); |
1943 | dev->last_frame[cc] = dev->cur_frame[cc]; | 2009 | dev->last_frame[cc] = dev->cur_frame[cc]; |
@@ -1946,16 +2012,13 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) | |||
1946 | if ((dev->cur_frame[cc] == SYS_FRAMES) || | 2012 | if ((dev->cur_frame[cc] == SYS_FRAMES) || |
1947 | (dev->cur_frame[cc] == dev->buffer[cc].dwFrames)) | 2013 | (dev->cur_frame[cc] == dev->buffer[cc].dwFrames)) |
1948 | dev->cur_frame[cc] = 0; | 2014 | dev->cur_frame[cc] = 0; |
1949 | 2015 | /* frame ready */ | |
1950 | /* signal the semaphore for this channel */ | ||
1951 | if (dev->b_acquire[cc]) | 2016 | if (dev->b_acquire[cc]) |
1952 | s2255_got_frame(dev, cc); | 2017 | s2255_got_frame(dev, cc, dev->jpg_size[cc]); |
1953 | dev->frame_count[cc]++; | 2018 | dev->frame_count[cc]++; |
1954 | } | 2019 | frm->ulState = S2255_READ_IDLE; |
1955 | /* frame was truncated */ | 2020 | frm->cur_size = 0; |
1956 | if (btrunc) { | 2021 | |
1957 | /* return more data to process */ | ||
1958 | return EAGAIN; | ||
1959 | } | 2022 | } |
1960 | /* done successfully */ | 2023 | /* done successfully */ |
1961 | return 0; | 2024 | return 0; |
@@ -1974,8 +2037,8 @@ static void s2255_read_video_callback(struct s2255_dev *dev, | |||
1974 | } | 2037 | } |
1975 | /* otherwise copy to the system buffers */ | 2038 | /* otherwise copy to the system buffers */ |
1976 | res = save_frame(dev, pipe_info); | 2039 | res = save_frame(dev, pipe_info); |
1977 | if (res == EAGAIN) | 2040 | if (res != 0) |
1978 | save_frame(dev, pipe_info); | 2041 | dprintk(4, "s2255: read callback failed\n"); |
1979 | 2042 | ||
1980 | dprintk(50, "callback read video done\n"); | 2043 | dprintk(50, "callback read video done\n"); |
1981 | return; | 2044 | return; |
@@ -2095,11 +2158,9 @@ static int s2255_board_init(struct s2255_dev *dev) | |||
2095 | 2158 | ||
2096 | memset(pipe, 0, sizeof(*pipe)); | 2159 | memset(pipe, 0, sizeof(*pipe)); |
2097 | pipe->dev = dev; | 2160 | pipe->dev = dev; |
2098 | pipe->cur_transfer_size = DEFAULT_PIPE_USBBLOCK; | 2161 | pipe->cur_transfer_size = S2255_USB_XFER_SIZE; |
2099 | pipe->max_transfer_size = MAX_PIPE_USBBLOCK; | 2162 | pipe->max_transfer_size = S2255_USB_XFER_SIZE; |
2100 | 2163 | ||
2101 | if (pipe->cur_transfer_size > pipe->max_transfer_size) | ||
2102 | pipe->cur_transfer_size = pipe->max_transfer_size; | ||
2103 | pipe->transfer_buffer = kzalloc(pipe->max_transfer_size, | 2164 | pipe->transfer_buffer = kzalloc(pipe->max_transfer_size, |
2104 | GFP_KERNEL); | 2165 | GFP_KERNEL); |
2105 | if (pipe->transfer_buffer == NULL) { | 2166 | if (pipe->transfer_buffer == NULL) { |
@@ -2119,6 +2180,7 @@ static int s2255_board_init(struct s2255_dev *dev) | |||
2119 | for (j = 0; j < MAX_CHANNELS; j++) { | 2180 | for (j = 0; j < MAX_CHANNELS; j++) { |
2120 | dev->b_acquire[j] = 0; | 2181 | dev->b_acquire[j] = 0; |
2121 | dev->mode[j] = mode_def; | 2182 | dev->mode[j] = mode_def; |
2183 | dev->jc[j].quality = S2255_DEF_JPEG_QUAL; | ||
2122 | dev->cur_fmt[j] = &formats[0]; | 2184 | dev->cur_fmt[j] = &formats[0]; |
2123 | dev->mode[j].restart = 1; | 2185 | dev->mode[j].restart = 1; |
2124 | dev->req_image_size[j] = get_transfer_size(&mode_def); | 2186 | dev->req_image_size[j] = get_transfer_size(&mode_def); |
@@ -2323,7 +2385,7 @@ static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn) | |||
2323 | kfree(buffer); | 2385 | kfree(buffer); |
2324 | dev->b_acquire[chn] = 0; | 2386 | dev->b_acquire[chn] = 0; |
2325 | 2387 | ||
2326 | return 0; | 2388 | return res; |
2327 | } | 2389 | } |
2328 | 2390 | ||
2329 | static void s2255_stop_readpipe(struct s2255_dev *dev) | 2391 | static void s2255_stop_readpipe(struct s2255_dev *dev) |
@@ -2359,8 +2421,10 @@ static void s2255_stop_readpipe(struct s2255_dev *dev) | |||
2359 | return; | 2421 | return; |
2360 | } | 2422 | } |
2361 | 2423 | ||
2362 | static void s2255_fwload_start(struct s2255_dev *dev) | 2424 | static void s2255_fwload_start(struct s2255_dev *dev, int reset) |
2363 | { | 2425 | { |
2426 | if (reset) | ||
2427 | s2255_reset_dsppower(dev); | ||
2364 | dev->fw_data->fw_size = dev->fw_data->fw->size; | 2428 | dev->fw_data->fw_size = dev->fw_data->fw->size; |
2365 | atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED); | 2429 | atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED); |
2366 | memcpy(dev->fw_data->pfw_data, | 2430 | memcpy(dev->fw_data->pfw_data, |
@@ -2383,6 +2447,8 @@ static int s2255_probe(struct usb_interface *interface, | |||
2383 | struct usb_endpoint_descriptor *endpoint; | 2447 | struct usb_endpoint_descriptor *endpoint; |
2384 | int i; | 2448 | int i; |
2385 | int retval = -ENOMEM; | 2449 | int retval = -ENOMEM; |
2450 | __le32 *pdata; | ||
2451 | int fw_size; | ||
2386 | 2452 | ||
2387 | dprintk(2, "s2255: probe\n"); | 2453 | dprintk(2, "s2255: probe\n"); |
2388 | 2454 | ||
@@ -2437,6 +2503,8 @@ static int s2255_probe(struct usb_interface *interface, | |||
2437 | dev->timer.data = (unsigned long)dev->fw_data; | 2503 | dev->timer.data = (unsigned long)dev->fw_data; |
2438 | 2504 | ||
2439 | init_waitqueue_head(&dev->fw_data->wait_fw); | 2505 | init_waitqueue_head(&dev->fw_data->wait_fw); |
2506 | for (i = 0; i < MAX_CHANNELS; i++) | ||
2507 | init_waitqueue_head(&dev->wait_setmode[i]); | ||
2440 | 2508 | ||
2441 | 2509 | ||
2442 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); | 2510 | dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); |
@@ -2456,16 +2524,30 @@ static int s2255_probe(struct usb_interface *interface, | |||
2456 | printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); | 2524 | printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); |
2457 | goto error; | 2525 | goto error; |
2458 | } | 2526 | } |
2527 | /* check the firmware is valid */ | ||
2528 | fw_size = dev->fw_data->fw->size; | ||
2529 | pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8]; | ||
2459 | 2530 | ||
2531 | if (*pdata != S2255_FW_MARKER) { | ||
2532 | printk(KERN_INFO "Firmware invalid.\n"); | ||
2533 | retval = -ENODEV; | ||
2534 | goto error; | ||
2535 | } else { | ||
2536 | /* make sure firmware is the latest */ | ||
2537 | __le32 *pRel; | ||
2538 | pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4]; | ||
2539 | printk(KERN_INFO "s2255 dsp fw version %x\n", *pRel); | ||
2540 | } | ||
2460 | /* loads v4l specific */ | 2541 | /* loads v4l specific */ |
2461 | s2255_probe_v4l(dev); | 2542 | s2255_probe_v4l(dev); |
2543 | usb_reset_device(dev->udev); | ||
2462 | /* load 2255 board specific */ | 2544 | /* load 2255 board specific */ |
2463 | s2255_board_init(dev); | 2545 | s2255_board_init(dev); |
2464 | 2546 | ||
2465 | dprintk(4, "before probe done %p\n", dev); | 2547 | dprintk(4, "before probe done %p\n", dev); |
2466 | spin_lock_init(&dev->slock); | 2548 | spin_lock_init(&dev->slock); |
2467 | 2549 | ||
2468 | s2255_fwload_start(dev); | 2550 | s2255_fwload_start(dev, 0); |
2469 | dev_info(&interface->dev, "Sensoray 2255 detected\n"); | 2551 | dev_info(&interface->dev, "Sensoray 2255 detected\n"); |
2470 | return 0; | 2552 | return 0; |
2471 | error: | 2553 | error: |
@@ -2476,14 +2558,30 @@ error: | |||
2476 | static void s2255_disconnect(struct usb_interface *interface) | 2558 | static void s2255_disconnect(struct usb_interface *interface) |
2477 | { | 2559 | { |
2478 | struct s2255_dev *dev = NULL; | 2560 | struct s2255_dev *dev = NULL; |
2561 | int i; | ||
2479 | dprintk(1, "s2255: disconnect interface %p\n", interface); | 2562 | dprintk(1, "s2255: disconnect interface %p\n", interface); |
2480 | dev = usb_get_intfdata(interface); | 2563 | dev = usb_get_intfdata(interface); |
2564 | |||
2565 | /* | ||
2566 | * wake up any of the timers to allow open_lock to be | ||
2567 | * acquired sooner | ||
2568 | */ | ||
2569 | atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); | ||
2570 | wake_up(&dev->fw_data->wait_fw); | ||
2571 | for (i = 0; i < MAX_CHANNELS; i++) { | ||
2572 | dev->setmode_ready[i] = 1; | ||
2573 | wake_up(&dev->wait_setmode[i]); | ||
2574 | } | ||
2575 | |||
2576 | mutex_lock(&dev->open_lock); | ||
2577 | usb_set_intfdata(interface, NULL); | ||
2578 | mutex_unlock(&dev->open_lock); | ||
2579 | |||
2481 | if (dev) { | 2580 | if (dev) { |
2482 | kref_put(&dev->kref, s2255_destroy); | 2581 | kref_put(&dev->kref, s2255_destroy); |
2483 | dprintk(1, "s2255drv: disconnect\n"); | 2582 | dprintk(1, "s2255drv: disconnect\n"); |
2484 | dev_info(&interface->dev, "s2255usb now disconnected\n"); | 2583 | dev_info(&interface->dev, "s2255usb now disconnected\n"); |
2485 | } | 2584 | } |
2486 | usb_set_intfdata(interface, NULL); | ||
2487 | } | 2585 | } |
2488 | 2586 | ||
2489 | static struct usb_driver s2255_driver = { | 2587 | static struct usb_driver s2255_driver = { |