aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <j.w.r.degoede@hhs.nl>2008-04-23 07:09:12 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:14:32 -0400
commite2997a72ddfafc25bd0c8f1f52bcf41979d5a559 (patch)
treebe39e1c2f946a5d3c2e82fe7a2d663f54fda11d4
parent63eb9546dcb5e9dc39ab88a603dede8fdd18e717 (diff)
V4L/DVB (8153): Subdriver pac207 added and minor changes.
pac207 added. Check status on mutex lock. Call back on frame dequeue. Free the resources on last close only. Avoid URB and ISOC errors on close. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/gspca/Makefile3
-rw-r--r--drivers/media/video/gspca/gspca.c121
-rw-r--r--drivers/media/video/gspca/gspca.h17
-rw-r--r--drivers/media/video/gspca/pac207.c939
4 files changed, 1018 insertions, 62 deletions
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 885d4454d8e..81170c19ba4 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_GSPCA) += gspca_main.o gspca_stk014.o 1obj-$(CONFIG_GSPCA) += gspca_main.o gspca_pac207.o gspca_stk014.o
2 2
3gspca_main-objs := gspca.o 3gspca_main-objs := gspca.o
4gspca_pac207-objs := pac207.o
4gspca_stk014-objs := stk014.o 5gspca_stk014-objs := stk014.o
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 4fe082ff707..c4735e13361 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -39,8 +39,8 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
39MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 39MODULE_DESCRIPTION("GSPCA USB Camera Driver");
40MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
41 41
42#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 26) 42#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 30)
43static const char version[] = "0.0.26"; 43static const char version[] = "0.0.30";
44 44
45static int video_nr = -1; 45static int video_nr = -1;
46 46
@@ -172,8 +172,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
172{ 172{
173 int i, j; 173 int i, j;
174 174
175 PDEBUG(D_PACK, "add t:%d l:%d %02x %02x %02x %02x...", 175 PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
176 packet_type, len, data[0], data[1], data[2], data[3]);
177 176
178 /* when start of a new frame, if the current frame buffer 177 /* when start of a new frame, if the current frame buffer
179 * is not queued, discard the whole frame */ 178 * is not queued, discard the whole frame */
@@ -346,7 +345,6 @@ static int gspca_kill_transfer(struct gspca_dev *gspca_dev)
346 unsigned int i; 345 unsigned int i;
347 346
348 PDEBUG(D_STREAM, "kill transfer"); 347 PDEBUG(D_STREAM, "kill transfer");
349 gspca_dev->streaming = 0;
350 for (i = 0; i < NURBS; ++i) { 348 for (i = 0; i < NURBS; ++i) {
351 urb = gspca_dev->pktbuf[i].urb; 349 urb = gspca_dev->pktbuf[i].urb;
352 if (urb == NULL) 350 if (urb == NULL)
@@ -501,9 +499,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
501 struct usb_host_endpoint *ep; 499 struct usb_host_endpoint *ep;
502 int n, ret; 500 int n, ret;
503 501
504 ret = mutex_lock_interruptible(&gspca_dev->usb_lock); 502 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
505 if (ret < 0) 503 return -ERESTARTSYS;
506 return ret;
507 504
508 /* set the max alternate setting and loop until urb submit succeeds */ 505 /* set the max alternate setting and loop until urb submit succeeds */
509 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); 506 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
@@ -531,6 +528,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
531 if (ret < 0) { 528 if (ret < 0) {
532 PDEBUG(D_ERR|D_STREAM, 529 PDEBUG(D_ERR|D_STREAM,
533 "usb_submit_urb [%d] err %d", n, ret); 530 "usb_submit_urb [%d] err %d", n, ret);
531 gspca_dev->streaming = 0;
534 gspca_kill_transfer(gspca_dev); 532 gspca_kill_transfer(gspca_dev);
535 if (ret == -ENOSPC) 533 if (ret == -ENOSPC)
536 break; /* try the previous alt */ 534 break; /* try the previous alt */
@@ -555,9 +553,9 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
555 return ret; 553 return ret;
556} 554}
557 555
556/* Note both the queue and the usb lock should be hold when calling this */
558static void gspca_stream_off(struct gspca_dev *gspca_dev) 557static void gspca_stream_off(struct gspca_dev *gspca_dev)
559{ 558{
560 mutex_lock_interruptible(&gspca_dev->usb_lock);
561 gspca_dev->streaming = 0; 559 gspca_dev->streaming = 0;
562 if (gspca_dev->present) { 560 if (gspca_dev->present) {
563 gspca_dev->sd_desc->stopN(gspca_dev); 561 gspca_dev->sd_desc->stopN(gspca_dev);
@@ -571,7 +569,6 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
571 wake_up_interruptible(&gspca_dev->wq); 569 wake_up_interruptible(&gspca_dev->wq);
572 PDEBUG(D_ERR|D_STREAM, "stream off no device ??"); 570 PDEBUG(D_ERR|D_STREAM, "stream off no device ??");
573 } 571 }
574 mutex_unlock(&gspca_dev->usb_lock);
575} 572}
576 573
577static int gspca_set_default_mode(struct gspca_dev *gspca_dev) 574static int gspca_set_default_mode(struct gspca_dev *gspca_dev)
@@ -791,9 +788,7 @@ static int vidioc_try_fmt_cap(struct file *file,
791{ 788{
792 int ret; 789 int ret;
793 790
794/* mutex_lock_interruptible(&gspca_dev->queue_lock); */
795 ret = try_fmt_cap(file, priv, fmt); 791 ret = try_fmt_cap(file, priv, fmt);
796/* mutex_unlock(&gspca_dev->queue_lock); */
797 if (ret < 0) 792 if (ret < 0)
798 return ret; 793 return ret;
799 return 0; 794 return 0;
@@ -812,7 +807,8 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv,
812 fmt->fmt.pix.width, fmt->fmt.pix.height); 807 fmt->fmt.pix.width, fmt->fmt.pix.height);
813 } 808 }
814#endif 809#endif
815 mutex_lock_interruptible(&gspca_dev->queue_lock); 810 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
811 return -ERESTARTSYS;
816 ret = try_fmt_cap(file, priv, fmt); 812 ret = try_fmt_cap(file, priv, fmt);
817 if (ret < 0) 813 if (ret < 0)
818 goto out; 814 goto out;
@@ -820,8 +816,14 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv,
820 if (ret == gspca_dev->curr_mode) 816 if (ret == gspca_dev->curr_mode)
821 goto out; /* same mode */ 817 goto out; /* same mode */
822 was_streaming = gspca_dev->streaming; 818 was_streaming = gspca_dev->streaming;
823 if (was_streaming != 0) 819 if (was_streaming != 0) {
820 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
821 ret = -ERESTARTSYS;
822 goto out;
823 }
824 gspca_stream_off(gspca_dev); 824 gspca_stream_off(gspca_dev);
825 mutex_unlock(&gspca_dev->usb_lock);
826 }
825 gspca_dev->width = (int) fmt->fmt.pix.width; 827 gspca_dev->width = (int) fmt->fmt.pix.width;
826 gspca_dev->height = (int) fmt->fmt.pix.height; 828 gspca_dev->height = (int) fmt->fmt.pix.height;
827 gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; 829 gspca_dev->pixfmt = fmt->fmt.pix.pixelformat;
@@ -840,9 +842,8 @@ static int dev_open(struct inode *inode, struct file *file)
840 842
841 PDEBUG(D_STREAM, "opening"); 843 PDEBUG(D_STREAM, "opening");
842 gspca_dev = (struct gspca_dev *) video_devdata(file); 844 gspca_dev = (struct gspca_dev *) video_devdata(file);
843 ret = mutex_lock_interruptible(&gspca_dev->queue_lock); 845 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
844 if (ret < 0) 846 return -ERESTARTSYS;
845 return ret;
846 if (!gspca_dev->present) { 847 if (!gspca_dev->present) {
847 ret = -ENODEV; 848 ret = -ENODEV;
848 goto out; 849 goto out;
@@ -850,16 +851,17 @@ static int dev_open(struct inode *inode, struct file *file)
850 851
851 /* if not done yet, initialize the sensor */ 852 /* if not done yet, initialize the sensor */
852 if (gspca_dev->users == 0) { 853 if (gspca_dev->users == 0) {
853 ret = mutex_lock_interruptible(&gspca_dev->usb_lock); 854 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
854 if (ret < 0) 855 ret = -ERESTARTSYS;
855 goto out; 856 goto out;
857 }
856 ret = gspca_dev->sd_desc->open(gspca_dev); 858 ret = gspca_dev->sd_desc->open(gspca_dev);
857 mutex_unlock(&gspca_dev->usb_lock); 859 mutex_unlock(&gspca_dev->usb_lock);
858 if (ret != 0) { 860 if (ret != 0) {
859 PDEBUG(D_ERR|D_CONF, "init device failed %d", ret); 861 PDEBUG(D_ERR|D_CONF, "init device failed %d", ret);
860 goto out; 862 goto out;
861 } 863 }
862 } else if (gspca_dev->users > 8) { /* (arbitrary value) */ 864 } else if (gspca_dev->users > 4) { /* (arbitrary value) */
863 ret = -EBUSY; 865 ret = -EBUSY;
864 goto out; 866 goto out;
865 } 867 }
@@ -886,21 +888,20 @@ static int dev_close(struct inode *inode, struct file *file)
886 struct gspca_dev *gspca_dev = file->private_data; 888 struct gspca_dev *gspca_dev = file->private_data;
887 889
888 PDEBUG(D_STREAM, "closing"); 890 PDEBUG(D_STREAM, "closing");
889 if (gspca_dev->streaming) { 891 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
890 mutex_lock_interruptible(&gspca_dev->queue_lock); 892 return -ERESTARTSYS;
891 gspca_stream_off(gspca_dev); 893 gspca_dev->users--;
894 if (gspca_dev->users > 0) {
892 mutex_unlock(&gspca_dev->queue_lock); 895 mutex_unlock(&gspca_dev->queue_lock);
896 return 0;
893 } 897 }
894 mutex_lock_interruptible(&gspca_dev->usb_lock); 898
899 if (gspca_dev->streaming)
900 gspca_stream_off(gspca_dev);
895 gspca_dev->sd_desc->close(gspca_dev); 901 gspca_dev->sd_desc->close(gspca_dev);
896 mutex_unlock(&gspca_dev->usb_lock); 902
897 atomic_inc(&gspca_dev->nevent);
898 wake_up_interruptible(&gspca_dev->wq); /* wake blocked processes */
899 schedule();
900 mutex_lock_interruptible(&gspca_dev->queue_lock);
901 frame_free(gspca_dev); 903 frame_free(gspca_dev);
902 file->private_data = NULL; 904 file->private_data = NULL;
903 gspca_dev->users--;
904 mutex_unlock(&gspca_dev->queue_lock); 905 mutex_unlock(&gspca_dev->queue_lock);
905 PDEBUG(D_STREAM, "closed"); 906 PDEBUG(D_STREAM, "closed");
906 return 0; 907 return 0;
@@ -964,7 +965,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
964 && ctrl->value > ctrls->qctrl.maximum) 965 && ctrl->value > ctrls->qctrl.maximum)
965 return -ERANGE; 966 return -ERANGE;
966 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); 967 PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
967 mutex_lock_interruptible(&gspca_dev->usb_lock); 968 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
969 return -ERESTARTSYS;
968 ret = ctrls->set(gspca_dev, ctrl->value); 970 ret = ctrls->set(gspca_dev, ctrl->value);
969 mutex_unlock(&gspca_dev->usb_lock); 971 mutex_unlock(&gspca_dev->usb_lock);
970 return ret; 972 return ret;
@@ -985,7 +987,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
985 i++, ctrls++) { 987 i++, ctrls++) {
986 if (ctrl->id != ctrls->qctrl.id) 988 if (ctrl->id != ctrls->qctrl.id)
987 continue; 989 continue;
988 mutex_lock_interruptible(&gspca_dev->usb_lock); 990 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
991 return -ERESTARTSYS;
989 ret = ctrls->get(gspca_dev, &ctrl->value); 992 ret = ctrls->get(gspca_dev, &ctrl->value);
990 mutex_unlock(&gspca_dev->usb_lock); 993 mutex_unlock(&gspca_dev->usb_lock);
991 return ret; 994 return ret;
@@ -1047,9 +1050,8 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1047 frsz = gspca_get_buff_size(gspca_dev); 1050 frsz = gspca_get_buff_size(gspca_dev);
1048 if (frsz < 0) 1051 if (frsz < 0)
1049 return frsz; 1052 return frsz;
1050 ret = mutex_lock_interruptible(&gspca_dev->queue_lock); 1053 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1051 if (ret < 0) 1054 return -ERESTARTSYS;
1052 return ret;
1053 ret = frame_alloc(gspca_dev, 1055 ret = frame_alloc(gspca_dev,
1054 rb->count, 1056 rb->count,
1055 (unsigned int) frsz, 1057 (unsigned int) frsz,
@@ -1087,9 +1089,8 @@ static int vidioc_streamon(struct file *file, void *priv,
1087 PDEBUG(D_STREAM, "stream on"); 1089 PDEBUG(D_STREAM, "stream on");
1088 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1090 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1089 return -EINVAL; 1091 return -EINVAL;
1090 ret = mutex_lock_interruptible(&gspca_dev->queue_lock); 1092 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1091 if (ret < 0) 1093 return -ERESTARTSYS;
1092 return ret;
1093 if (!gspca_dev->present) { 1094 if (!gspca_dev->present) {
1094 ret = -ENODEV; 1095 ret = -ENODEV;
1095 goto out; 1096 goto out;
@@ -1111,6 +1112,7 @@ static int vidioc_streamon(struct file *file, void *priv,
1111 gspca_dev->height); 1112 gspca_dev->height);
1112 } 1113 }
1113#endif 1114#endif
1115 ret = 0;
1114out: 1116out:
1115 mutex_unlock(&gspca_dev->queue_lock); 1117 mutex_unlock(&gspca_dev->queue_lock);
1116 return ret; 1118 return ret;
@@ -1125,8 +1127,14 @@ static int vidioc_streamoff(struct file *file, void *priv,
1125 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1127 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1126 return -EINVAL; 1128 return -EINVAL;
1127 if (gspca_dev->streaming) { 1129 if (gspca_dev->streaming) {
1128 mutex_lock_interruptible(&gspca_dev->queue_lock); 1130 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1131 return -ERESTARTSYS;
1132 if (mutex_lock_interruptible(&gspca_dev->usb_lock)) {
1133 mutex_unlock(&gspca_dev->queue_lock);
1134 return -ERESTARTSYS;
1135 }
1129 gspca_stream_off(gspca_dev); 1136 gspca_stream_off(gspca_dev);
1137 mutex_unlock(&gspca_dev->usb_lock);
1130 mutex_unlock(&gspca_dev->queue_lock); 1138 mutex_unlock(&gspca_dev->queue_lock);
1131 } 1139 }
1132 return 0; 1140 return 0;
@@ -1140,7 +1148,8 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
1140 1148
1141 if (!gspca_dev->sd_desc->get_jcomp) 1149 if (!gspca_dev->sd_desc->get_jcomp)
1142 return -EINVAL; 1150 return -EINVAL;
1143 mutex_lock_interruptible(&gspca_dev->usb_lock); 1151 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1152 return -ERESTARTSYS;
1144 ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); 1153 ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
1145 mutex_unlock(&gspca_dev->usb_lock); 1154 mutex_unlock(&gspca_dev->usb_lock);
1146 return ret; 1155 return ret;
@@ -1152,7 +1161,8 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
1152 struct gspca_dev *gspca_dev = priv; 1161 struct gspca_dev *gspca_dev = priv;
1153 int ret; 1162 int ret;
1154 1163
1155 mutex_lock_interruptible(&gspca_dev->usb_lock); 1164 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1165 return -ERESTARTSYS;
1156 if (!gspca_dev->sd_desc->set_jcomp) 1166 if (!gspca_dev->sd_desc->set_jcomp)
1157 return -EINVAL; 1167 return -EINVAL;
1158 ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); 1168 ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
@@ -1177,7 +1187,8 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1177 struct gspca_dev *gspca_dev = priv; 1187 struct gspca_dev *gspca_dev = priv;
1178 int n; 1188 int n;
1179 1189
1180 mutex_lock_interruptible(&gspca_dev->usb_lock); 1190 if (mutex_lock_interruptible(&gspca_dev->usb_lock))
1191 return -ERESTARTSYS;
1181 n = parm->parm.capture.readbuffers; 1192 n = parm->parm.capture.readbuffers;
1182 if (n == 0 || n > GSPCA_MAX_FRAMES) 1193 if (n == 0 || n > GSPCA_MAX_FRAMES)
1183 parm->parm.capture.readbuffers = gspca_dev->nbufread; 1194 parm->parm.capture.readbuffers = gspca_dev->nbufread;
@@ -1230,10 +1241,8 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1230 size = vma->vm_end - vma->vm_start; 1241 size = vma->vm_end - vma->vm_start;
1231 PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size); 1242 PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size);
1232 1243
1233 ret = mutex_lock_interruptible(&gspca_dev->queue_lock); 1244 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1234 if (ret < 0) 1245 return -ERESTARTSYS;
1235 return ret;
1236/* sanity check disconnect, in use, no memory available */
1237 if (!gspca_dev->present) { 1246 if (!gspca_dev->present) {
1238 ret = -ENODEV; 1247 ret = -ENODEV;
1239 goto done; 1248 goto done;
@@ -1294,6 +1303,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1294 V4L2_BUF_FLAG_MAPPED; 1303 V4L2_BUF_FLAG_MAPPED;
1295 } 1304 }
1296#endif 1305#endif
1306 ret = 0;
1297done: 1307done:
1298 mutex_unlock(&gspca_dev->queue_lock); 1308 mutex_unlock(&gspca_dev->queue_lock);
1299 return ret; 1309 return ret;
@@ -1350,6 +1360,8 @@ static int gspca_frame_wait(struct gspca_dev *gspca_dev,
1350 atomic_read(&gspca_dev->nevent) > 0); 1360 atomic_read(&gspca_dev->nevent) > 0);
1351 if (ret != 0) 1361 if (ret != 0)
1352 return ret; 1362 return ret;
1363 if (!gspca_dev->streaming || !gspca_dev->present)
1364 return -EIO;
1353 i = gspca_dev->fr_o; 1365 i = gspca_dev->fr_o;
1354 j = gspca_dev->fr_queue[i]; 1366 j = gspca_dev->fr_queue[i];
1355 frame = &gspca_dev->frame[j]; 1367 frame = &gspca_dev->frame[j];
@@ -1364,6 +1376,10 @@ ok:
1364 gspca_dev->fr_q, 1376 gspca_dev->fr_q,
1365 gspca_dev->fr_i, 1377 gspca_dev->fr_i,
1366 gspca_dev->fr_o); 1378 gspca_dev->fr_o);
1379
1380 if (gspca_dev->sd_desc->dq_callback)
1381 gspca_dev->sd_desc->dq_callback(gspca_dev);
1382
1367 return j; 1383 return j;
1368} 1384}
1369 1385
@@ -1435,9 +1451,9 @@ static int vidioc_qbuf(struct file *file, void *priv,
1435 return -EINVAL; 1451 return -EINVAL;
1436 } 1452 }
1437 1453
1438 ret = mutex_lock_interruptible(&gspca_dev->queue_lock); 1454 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1439 if (ret < 0) 1455 return -ERESTARTSYS;
1440 return ret; 1456
1441 if (frame->v4l2_buf.flags 1457 if (frame->v4l2_buf.flags
1442 & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) { 1458 & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) {
1443 PDEBUG(D_STREAM, "qbuf bad state"); 1459 PDEBUG(D_STREAM, "qbuf bad state");
@@ -1708,11 +1724,12 @@ void gspca_disconnect(struct usb_interface *intf)
1708 if (!gspca_dev) 1724 if (!gspca_dev)
1709 return; 1725 return;
1710 gspca_dev->present = 0; 1726 gspca_dev->present = 0;
1711 mutex_lock_interruptible(&gspca_dev->queue_lock); 1727 mutex_lock(&gspca_dev->queue_lock);
1712 mutex_lock_interruptible(&gspca_dev->usb_lock); 1728 mutex_lock(&gspca_dev->usb_lock);
1729 gspca_dev->streaming = 0;
1713 gspca_kill_transfer(gspca_dev); 1730 gspca_kill_transfer(gspca_dev);
1714 mutex_unlock(&gspca_dev->queue_lock);
1715 mutex_unlock(&gspca_dev->usb_lock); 1731 mutex_unlock(&gspca_dev->usb_lock);
1732 mutex_unlock(&gspca_dev->queue_lock);
1716 while (gspca_dev->users != 0) { /* wait until fully closed */ 1733 while (gspca_dev->users != 0) { /* wait until fully closed */
1717 atomic_inc(&gspca_dev->nevent); 1734 atomic_inc(&gspca_dev->nevent);
1718 wake_up_interruptible(&gspca_dev->wq); /* wake processes */ 1735 wake_up_interruptible(&gspca_dev->wq); /* wake processes */
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 1394ab13f1f..3bfb3641cf3 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -90,17 +90,18 @@ struct ctrl {
90/* subdriver description */ 90/* subdriver description */
91struct sd_desc { 91struct sd_desc {
92/* information */ 92/* information */
93 char *name; /* sub-driver name */ 93 char *name; /* sub-driver name */
94/* controls */ 94/* controls */
95 struct ctrl *ctrls; 95 struct ctrl *ctrls;
96 int nctrls; 96 int nctrls;
97/* operations */ 97/* operations */
98 cam_cf_op config; /* called on probe */ 98 cam_cf_op config; /* called on probe */
99 cam_op open; /* called on open */ 99 cam_op open; /* called on open */
100 cam_v_op start; /* called on stream on */ 100 cam_v_op start; /* called on stream on */
101 cam_v_op stopN; /* called on stream off - main alt */ 101 cam_v_op stopN; /* called on stream off - main alt */
102 cam_v_op stop0; /* called on stream off - alt 0 */ 102 cam_v_op stop0; /* called on stream off - alt 0 */
103 cam_v_op close; /* called on close */ 103 cam_v_op close; /* called on close */
104 cam_v_op dq_callback; /* called when a frame has been dequeued */
104 cam_pkt_op pkt_scan; 105 cam_pkt_op pkt_scan;
105 cam_jpg_op get_jcomp; 106 cam_jpg_op get_jcomp;
106 cam_jpg_op set_jcomp; 107 cam_jpg_op set_jcomp;
@@ -167,8 +168,6 @@ int gspca_dev_probe(struct usb_interface *intf,
167 const struct usb_device_id *id, 168 const struct usb_device_id *id,
168 const struct sd_desc *sd_desc, 169 const struct sd_desc *sd_desc,
169 int dev_size); 170 int dev_size);
170int gspca_dev_init(struct gspca_dev *gspca_dev,
171 struct usb_interface *intf);
172void gspca_disconnect(struct usb_interface *intf); 171void gspca_disconnect(struct usb_interface *intf);
173struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, 172struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
174 int packet_type, 173 int packet_type,
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
new file mode 100644
index 00000000000..ac16c735289
--- /dev/null
+++ b/drivers/media/video/gspca/pac207.c
@@ -0,0 +1,939 @@
1/*
2 * Pixart PAC207BCA library
3 *
4 * Copyright (C) 2008 Hans de Goede <j.w.r.degoede@hhs.nl>
5 * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
6 * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr
7 *
8 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#define MODULE_NAME "pac207"
27
28#include "gspca.h"
29
30#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 30)
31static const char version[] = "0.0.30";
32
33MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
34MODULE_DESCRIPTION("Pixart PAC207");
35MODULE_LICENSE("GPL");
36
37#define PAC207_CTRL_TIMEOUT 100 /* ms */
38
39#define PAC207_BRIGHTNESS_MIN 0
40#define PAC207_BRIGHTNESS_MAX 255
41#define PAC207_BRIGHTNESS_DEFAULT 4 /* power on default: 4 */
42
43#define PAC207_EXPOSURE_MIN 4
44#define PAC207_EXPOSURE_MAX 26
45#define PAC207_EXPOSURE_DEFAULT 4 /* power on default: 3 ?? */
46#define PAC207_EXPOSURE_KNEE 11 /* 4 = 30 fps, 11 = 8, 15 = 6 */
47
48#define PAC207_GAIN_MIN 0
49#define PAC207_GAIN_MAX 31
50#define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */
51#define PAC207_GAIN_KNEE 20
52
53#define PAC207_AUTOGAIN_DEADZONE 30
54/* We calculating the autogain at the end of the transfer of a frame, at this
55 moment a frame with the old settings is being transmitted, and a frame is
56 being captured with the old settings. So if we adjust the autogain we must
57 ignore atleast the 2 next frames for the new settings to come into effect
58 before doing any other adjustments */
59#define PAC207_AUTOGAIN_IGNORE_FRAMES 3
60
61enum pac207_line_state {
62 LINE_HEADER1,
63 LINE_HEADER2,
64 LINE_UNCOMPRESSED,
65 LINE_COMPRESSED,
66};
67
68struct pac207_decoder_state {
69 /* generic state */
70 u16 line_read;
71 u16 line_marker;
72 u8 line_state;
73 u8 header_read;
74 /* compression state */
75 u16 processed_bytes;
76 u8 remaining_bits;
77 s8 no_remaining_bits;
78 u8 get_abs;
79 u8 discard_byte;
80 u8 line_decode_buf[352];
81};
82
83/* specific webcam descriptor */
84struct sd {
85 struct gspca_dev gspca_dev; /* !! must be the first item */
86
87 struct pac207_decoder_state decoder_state;
88
89 u8 mode;
90
91 u8 brightness;
92 u8 exposure;
93 u8 autogain;
94 u8 gain;
95
96 u8 sof_read;
97 u8 autogain_ignore_frames;
98
99 atomic_t avg_lum;
100};
101
102/* V4L2 controls supported by the driver */
103static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
105static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
106static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
107static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
108static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
109static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
110static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
111
112static struct ctrl sd_ctrls[] = {
113#define SD_BRIGHTNESS 0
114 {
115 {
116 .id = V4L2_CID_BRIGHTNESS,
117 .type = V4L2_CTRL_TYPE_INTEGER,
118 .name = "Brightness",
119 .minimum = PAC207_BRIGHTNESS_MIN,
120 .maximum = PAC207_BRIGHTNESS_MAX,
121 .step = 1,
122 .default_value = PAC207_BRIGHTNESS_DEFAULT,
123 .flags = 0,
124 },
125 .set = sd_setbrightness,
126 .get = sd_getbrightness,
127 },
128#define SD_EXPOSURE 1
129 {
130 {
131 .id = V4L2_CID_EXPOSURE,
132 .type = V4L2_CTRL_TYPE_INTEGER,
133 .name = "exposure",
134 .minimum = PAC207_EXPOSURE_MIN,
135 .maximum = PAC207_EXPOSURE_MAX,
136 .step = 1,
137 .default_value = PAC207_EXPOSURE_DEFAULT,
138 .flags = 0,
139 },
140 .set = sd_setexposure,
141 .get = sd_getexposure,
142 },
143#define SD_AUTOGAIN 2
144 {
145 {
146 .id = V4L2_CID_AUTOGAIN,
147 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 .name = "Auto Gain",
149 .minimum = 0,
150 .maximum = 1,
151 .step = 1,
152 .default_value = 1,
153 .flags = 0,
154 },
155 .set = sd_setautogain,
156 .get = sd_getautogain,
157 },
158#define SD_GAIN 3
159 {
160 {
161 .id = V4L2_CID_GAIN,
162 .type = V4L2_CTRL_TYPE_INTEGER,
163 .name = "gain",
164 .minimum = PAC207_GAIN_MIN,
165 .maximum = PAC207_GAIN_MAX,
166 .step = 1,
167 .default_value = PAC207_GAIN_DEFAULT,
168 .flags = 0,
169 },
170 .set = sd_setgain,
171 .get = sd_getgain,
172 },
173};
174
175static struct cam_mode sif_mode[] = {
176 {V4L2_PIX_FMT_SBGGR8, 176, 144, 1},
177 {V4L2_PIX_FMT_SBGGR8, 352, 288, 0},
178};
179
180static const __u8 pac207_sensor_init[][8] = {
181 {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0},
182 {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
183 {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
184 {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02},
185 {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
186};
187
188 /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
189static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
190
191static const char pac207_sof_marker[5] = { 0xff, 0xff, 0x00, 0xff, 0x96 };
192
193int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
194 const u8 *buffer, u16 length)
195{
196 struct usb_device *udev = gspca_dev->dev;
197 int err;
198 u8 kbuf[8];
199
200 memcpy(kbuf, buffer, length);
201
202 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
203 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
204 0x00, index, kbuf, length, PAC207_CTRL_TIMEOUT);
205 if (err < 0)
206 PDEBUG(D_ERR,
207 "Failed to write registers to index 0x%04X, error %d)",
208 index, err);
209
210 return err;
211}
212
213
214int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value)
215{
216 struct usb_device *udev = gspca_dev->dev;
217 int err;
218
219 err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00,
220 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
221 value, index, NULL, 0, PAC207_CTRL_TIMEOUT);
222 if (err)
223 PDEBUG(D_ERR, "Failed to write a register (index 0x%04X,"
224 " value 0x%02X, error %d)", index, value, err);
225
226 return err;
227}
228
229
230int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index)
231{
232 struct usb_device *udev = gspca_dev->dev;
233 u8 buff;
234 int res;
235
236 res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00,
237 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
238 0x00, index, &buff, 1, PAC207_CTRL_TIMEOUT);
239 if (res < 0) {
240 PDEBUG(D_ERR,
241 "Failed to read a register (index 0x%04X, error %d)",
242 index, res);
243 return res;
244 }
245
246 return buff;
247}
248
249
250/* this function is called at probe time */
251static int sd_config(struct gspca_dev *gspca_dev,
252 const struct usb_device_id *id)
253{
254 struct cam *cam;
255 u8 idreg[2];
256
257 idreg[0] = pac207_read_reg(gspca_dev, 0x0000);
258 idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
259 idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4);
260 idreg[1] = idreg[1] & 0x0f;
261 PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
262 idreg[0], idreg[1]);
263
264 if (idreg[0] != 0x27) {
265 PDEBUG(D_PROBE, "Error invalid sensor ID!");
266 return -ENODEV;
267 }
268
269 pac207_write_reg(gspca_dev, 0x41, 0x00);
270 /* Bit_0=Image Format,
271 * Bit_1=LED,
272 * Bit_2=Compression test mode enable */
273 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
274 pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
275
276 PDEBUG(D_PROBE,
277 "Pixart PAC207BCA Image Processor and Control Chip detected"
278 " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
279
280 cam = &gspca_dev->cam;
281 cam->dev_name = (char *) id->driver_info;
282 cam->epaddr = 0x05;
283 cam->cam_mode = sif_mode;
284 cam->nmodes = ARRAY_SIZE(sif_mode);
285
286 return 0;
287}
288
289/* this function is called at open time */
290static int sd_open(struct gspca_dev *gspca_dev)
291{
292 struct sd *sd = (struct sd *) gspca_dev;
293
294 sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
295 sd->exposure = PAC207_EXPOSURE_DEFAULT;
296 sd->gain = PAC207_GAIN_DEFAULT;
297 sd->autogain = 1;
298
299 return 0;
300}
301
302/* -- start the camera -- */
303static void sd_start(struct gspca_dev *gspca_dev)
304{
305 struct sd *sd = (struct sd *) gspca_dev;
306 __u8 mode;
307
308 pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */
309 pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
310 pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
311 pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
312 pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8);
313 pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8);
314 pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4);
315
316 /* Compression Balance */
317 if (gspca_dev->width == 176)
318 pac207_write_reg(gspca_dev, 0x4a, 0xff);
319 else
320 pac207_write_reg(gspca_dev, 0x4a, 0x88);
321 pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
322 pac207_write_reg(gspca_dev, 0x08, sd->brightness);
323
324 /* PGA global gain (Bit 4-0) */
325 pac207_write_reg(gspca_dev, 0x0e, sd->gain);
326 pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */
327
328 mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */
329 if (gspca_dev->width == 176) { /* 176x144 */
330 mode |= 0x01;
331 PDEBUG(D_STREAM, "pac207_start mode 176x144");
332 } else/* 352x288 */
333 PDEBUG(D_STREAM, "pac207_start mode 352x288");
334 pac207_write_reg(gspca_dev, 0x41, mode);
335
336 pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
337 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
338 udelay(1000); /* taken from gspca */
339 pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */
340
341 sd->sof_read = 0;
342 sd->autogain_ignore_frames = 0;
343 atomic_set(&sd->avg_lum, -1);
344}
345
346static void sd_stopN(struct gspca_dev *gspca_dev)
347{
348 pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */
349 pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */
350 pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
351}
352
353static void sd_stop0(struct gspca_dev *gspca_dev)
354{
355}
356
357/* this function is called at close time */
358static void sd_close(struct gspca_dev *gspca_dev)
359{
360}
361
362/* -- convert pixart frames to Bayer -- */
363/* Sonix decompressor struct B.S.(2004) */
364static struct {
365 u8 is_abs;
366 u8 len;
367 s8 val;
368} table[256];
369
370void init_pixart_decoder(void)
371{
372 int i, is_abs, val, len;
373
374 for (i = 0; i < 256; i++) {
375 is_abs = 0;
376 val = 0;
377 len = 0;
378 if ((i & 0xC0) == 0) {
379 /* code 00 */
380 val = 0;
381 len = 2;
382 } else if ((i & 0xC0) == 0x40) {
383 /* code 01 */
384 val = -5;
385 len = 2;
386 } else if ((i & 0xC0) == 0x80) {
387 /* code 10 */
388 val = 5;
389 len = 2;
390 } else if ((i & 0xF0) == 0xC0) {
391 /* code 1100 */
392 val = -10;
393 len = 4;
394 } else if ((i & 0xF0) == 0xD0) {
395 /* code 1101 */
396 val = 10;
397 len = 4;
398 } else if ((i & 0xF8) == 0xE0) {
399 /* code 11100 */
400 val = -15;
401 len = 5;
402 } else if ((i & 0xF8) == 0xE8) {
403 /* code 11101 */
404 val = 15;
405 len = 5;
406 } else if ((i & 0xFC) == 0xF0) {
407 /* code 111100 */
408 val = -20;
409 len = 6;
410 } else if ((i & 0xFC) == 0xF4) {
411 /* code 111101 */
412 val = 20;
413 len = 6;
414 } else if ((i & 0xF8) == 0xF8) {
415 /* code 11111xxxxxx */
416 is_abs = 1;
417 val = 0;
418 len = 5;
419 }
420 table[i].is_abs = is_abs;
421 table[i].val = val;
422 table[i].len = len;
423 }
424}
425
426/* auto gain and exposure algorithm based on the knee algorithm described here:
427 http://ytse.tricolour.net/docs/LowLightOptimization.html */
428static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
429{
430 struct sd *sd = (struct sd *) gspca_dev;
431 int i, steps, desired_avg_lum;
432 int orig_gain = sd->gain;
433 int orig_exposure = sd->exposure;
434 int avg_lum = atomic_read(&sd->avg_lum);
435
436 if (!sd->autogain || avg_lum == -1)
437 return;
438
439 if (sd->autogain_ignore_frames > 0) {
440 sd->autogain_ignore_frames--;
441 return;
442 }
443
444 /* correct desired lumination for the configured brightness */
445 desired_avg_lum = 100 + sd->brightness / 2;
446
447 /* If we are of a multiple of deadzone, do multiple step to reach the
448 desired lumination fast (with the risc of a slight overshoot) */
449 steps = abs(desired_avg_lum - avg_lum) / PAC207_AUTOGAIN_DEADZONE;
450
451 for (i = 0; i < steps; i++) {
452 if (avg_lum > desired_avg_lum) {
453 if (sd->gain > PAC207_GAIN_KNEE) {
454 sd->gain--;
455 } else if (sd->exposure > PAC207_EXPOSURE_KNEE) {
456 sd->exposure--;
457 } else if (sd->gain > PAC207_GAIN_DEFAULT) {
458 sd->gain--;
459 } else if (sd->exposure > PAC207_EXPOSURE_MIN) {
460 sd->exposure--;
461 } else if (sd->gain > PAC207_GAIN_MIN) {
462 sd->gain--;
463 } else
464 break;
465 } else {
466 if (sd->gain < PAC207_GAIN_DEFAULT) {
467 sd->gain++;
468 } else if (sd->exposure < PAC207_EXPOSURE_KNEE) {
469 sd->exposure++;
470 } else if (sd->gain < PAC207_GAIN_KNEE) {
471 sd->gain++;
472 } else if (sd->exposure < PAC207_EXPOSURE_MAX) {
473 sd->exposure++;
474 } else if (sd->gain < PAC207_GAIN_MAX) {
475 sd->gain++;
476 } else
477 break;
478 }
479 }
480
481 if (sd->exposure != orig_exposure || sd->gain != orig_gain) {
482 if (sd->exposure != orig_exposure)
483 pac207_write_reg(gspca_dev, 0x0002, sd->exposure);
484 if (sd->gain != orig_gain)
485 pac207_write_reg(gspca_dev, 0x000e, sd->gain);
486 pac207_write_reg(gspca_dev, 0x13, 0x01); /* load reg to sen */
487 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
488 sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES;
489 }
490}
491
492static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
493 unsigned char *m, int len)
494{
495 struct sd *sd = (struct sd *) gspca_dev;
496 int i;
497
498 /* Search for the SOF marker (fixed part) in the header */
499 for (i = 0; i < len; i++) {
500 if (m[i] == pac207_sof_marker[sd->sof_read]) {
501 sd->sof_read++;
502 if (sd->sof_read == sizeof(pac207_sof_marker)) {
503 PDEBUG(D_STREAM,
504 "SOF found, bytes to analyze: %u."
505 " Frame starts at byte #%u",
506 len, i + 1);
507 sd->sof_read = 0;
508 return m + i + 1;
509 }
510 } else
511 sd->sof_read = 0;
512 }
513
514 return NULL;
515}
516
517static int pac207_decompress_row(struct gspca_dev *gspca_dev,
518 struct gspca_frame *f, unsigned char *cdata, int len)
519{
520 struct sd *sd = (struct sd *) gspca_dev;
521 struct pac207_decoder_state *decoder_state = &sd->decoder_state;
522 unsigned char *outp = decoder_state->line_decode_buf +
523 decoder_state->line_read;
524 int val, bitlen, bitpos = -decoder_state->no_remaining_bits;
525 u8 code;
526
527 /* first two pixels are stored as raw 8-bit */
528 while (decoder_state->line_read < 2) {
529 *outp++ = *cdata++;
530 decoder_state->line_read++;
531 len--;
532 if (len == 0)
533 return 0;
534 }
535
536 while (decoder_state->line_read < gspca_dev->width) {
537 if (bitpos < 0) {
538 code = decoder_state->remaining_bits << (8 + bitpos) |
539 cdata[0] >> -bitpos;
540 } else {
541 u8 *addr = cdata + bitpos / 8;
542 code = addr[0] << (bitpos & 7) |
543 addr[1] >> (8 - (bitpos & 7));
544 }
545
546 bitlen = decoder_state->get_abs ?
547 6 : table[code].len;
548
549 /* Stop decompressing if we're out of input data */
550 if ((bitpos + bitlen) > (len * 8))
551 break;
552
553 if (decoder_state->get_abs) {
554 *outp++ = code & 0xFC;
555 decoder_state->line_read++;
556 decoder_state->get_abs = 0;
557 } else {
558 if (table[code].is_abs)
559 decoder_state->get_abs = 1;
560 else {
561 /* relative to left pixel */
562 val = outp[-2] +
563 table[code].val;
564 if (val > 0xff)
565 val = 0xff;
566 else if (val < 0)
567 val = 0;
568 *outp++ = val;
569 decoder_state->line_read++;
570 }
571 }
572 bitpos += bitlen;
573 }
574
575 if (decoder_state->line_read == gspca_dev->width) {
576 int compressed_line_len;
577
578 gspca_frame_add(gspca_dev, INTER_PACKET, f,
579 decoder_state->line_decode_buf,
580 gspca_dev->width);
581
582 /* completely decompressed line, round pos to nearest word */
583 compressed_line_len = ((decoder_state->processed_bytes * 8 +
584 bitpos + 15) / 16) * 2;
585
586 len -= compressed_line_len - decoder_state->processed_bytes;
587 if (len < 0) {
588 decoder_state->discard_byte = 1;
589 len = 0;
590 }
591 } else {
592 decoder_state->processed_bytes += len;
593 decoder_state->remaining_bits = cdata[bitpos/8];
594 decoder_state->no_remaining_bits = (8 - bitpos) & 7;
595 len = 0;
596 }
597
598 return len;
599}
600
601static void pac207_decode_line_init(struct gspca_dev *gspca_dev)
602{
603 struct sd *sd = (struct sd *) gspca_dev;
604 struct pac207_decoder_state *decoder_state = &sd->decoder_state;
605
606 decoder_state->line_read = 0;
607 decoder_state->line_state = LINE_HEADER1;
608 decoder_state->processed_bytes = 0;
609 decoder_state->no_remaining_bits = 0;
610 decoder_state->get_abs = 0;
611}
612
613static void pac207_decode_frame_init(struct gspca_dev *gspca_dev)
614{
615 struct sd *sd = (struct sd *) gspca_dev;
616 struct pac207_decoder_state *decoder_state = &sd->decoder_state;
617
618 decoder_state->header_read = 0;
619 decoder_state->discard_byte = 0;
620
621 pac207_decode_line_init(gspca_dev);
622}
623
624static int pac207_decode_frame_data(struct gspca_dev *gspca_dev,
625 struct gspca_frame *f, unsigned char *data, int len)
626{
627 struct sd *sd = (struct sd *) gspca_dev;
628 struct pac207_decoder_state *decoder_state = &sd->decoder_state;
629 int needed = 0;
630
631 /* first 11 bytes after sof marker: frame header */
632 if (decoder_state->header_read < 11) {
633 /* get average lumination from frame header (byte 5) */
634 if (decoder_state->header_read < 5) {
635 needed = 5 - decoder_state->header_read;
636 if (len >= needed)
637 atomic_set(&sd->avg_lum, data[needed-1]);
638 }
639 /* skip the rest of the header */
640 needed = 11 - decoder_state->header_read;
641 if (len <= needed) {
642 decoder_state->header_read += len;
643 return 0;
644 }
645 data += needed;
646 len -= needed;
647 decoder_state->header_read = 11;
648 }
649
650 while (len) {
651 if (decoder_state->discard_byte) {
652 data++;
653 len--;
654 decoder_state->discard_byte = 0;
655 continue;
656 }
657
658 switch (decoder_state->line_state) {
659 case LINE_HEADER1:
660 decoder_state->line_marker = data[0] << 8;
661 decoder_state->line_state = LINE_HEADER2;
662 needed = 1;
663 break;
664 case LINE_HEADER2:
665 decoder_state->line_marker |= data[0];
666 switch (decoder_state->line_marker) {
667 case 0x0FF0:
668 decoder_state->line_state = LINE_UNCOMPRESSED;
669 break;
670 case 0x1EE1:
671 decoder_state->line_state = LINE_COMPRESSED;
672 break;
673 default:
674 PDEBUG(D_STREAM,
675 "Error unknown line-header %04X",
676 (int) decoder_state->line_marker);
677 gspca_dev->last_packet_type = DISCARD_PACKET;
678 return 0;
679 }
680 needed = 1;
681 break;
682 case LINE_UNCOMPRESSED:
683 needed = gspca_dev->width - decoder_state->line_read;
684 if (needed > len)
685 needed = len;
686 gspca_frame_add(gspca_dev, INTER_PACKET, f, data,
687 needed);
688 decoder_state->line_read += needed;
689 break;
690 case LINE_COMPRESSED:
691 needed = len -
692 pac207_decompress_row(gspca_dev, f, data, len);
693 break;
694 }
695
696 data += needed;
697 len -= needed;
698
699 if (decoder_state->line_read == gspca_dev->width) {
700 if ((f->data_end - f->data) ==
701 (gspca_dev->width * gspca_dev->height)) {
702 /* eureka we've got a frame */
703 return 1;
704 }
705 pac207_decode_line_init(gspca_dev);
706 }
707 }
708
709 return 0;
710}
711
712static void sd_pkt_scan(struct gspca_dev *gspca_dev,
713 struct gspca_frame *frame,
714 unsigned char *data,
715 int len)
716{
717 unsigned char *sof;
718 int n;
719
720 sof = pac207_find_sof(gspca_dev, data, len);
721
722 if (sof) {
723 /* finish decoding current frame */
724 if (gspca_dev->last_packet_type == INTER_PACKET) {
725 n = sof - data;
726 if (n > sizeof(pac207_sof_marker))
727 n -= sizeof(pac207_sof_marker);
728 else
729 n = 0;
730 n = pac207_decode_frame_data(gspca_dev, frame,
731 data, n);
732 if (n)
733 frame = gspca_frame_add(gspca_dev,
734 LAST_PACKET,
735 frame,
736 NULL,
737 0);
738 else
739 PDEBUG(D_STREAM, "Incomplete frame");
740 }
741 pac207_decode_frame_init(gspca_dev);
742 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL,
743 0);
744 len -= sof - data;
745 data = sof;
746 }
747
748 if (gspca_dev->last_packet_type == DISCARD_PACKET)
749 return;
750
751 n = pac207_decode_frame_data(gspca_dev, frame, data, len);
752 if (n)
753 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
754 frame, NULL, 0);
755}
756
757static void setbrightness(struct gspca_dev *gspca_dev)
758{
759 struct sd *sd = (struct sd *) gspca_dev;
760
761 pac207_write_reg(gspca_dev, 0x08, sd->brightness);
762 pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
763 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
764}
765
766static void setexposure(struct gspca_dev *gspca_dev)
767{
768 struct sd *sd = (struct sd *) gspca_dev;
769
770 pac207_write_reg(gspca_dev, 0x02, sd->exposure);
771 pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
772 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
773}
774
775static void setgain(struct gspca_dev *gspca_dev)
776{
777 struct sd *sd = (struct sd *) gspca_dev;
778
779 pac207_write_reg(gspca_dev, 0x0e, sd->gain);
780 pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */
781 pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
782}
783
784static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
785{
786 struct sd *sd = (struct sd *) gspca_dev;
787
788 sd->brightness = val;
789 if (gspca_dev->streaming)
790 setbrightness(gspca_dev);
791 return 0;
792}
793
794static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
795{
796 struct sd *sd = (struct sd *) gspca_dev;
797
798 *val = sd->brightness;
799 return 0;
800}
801
802static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
803{
804 struct sd *sd = (struct sd *) gspca_dev;
805
806 /* don't allow mucking with exposure when using autogain */
807 if (sd->autogain)
808 return -EINVAL;
809
810 sd->exposure = val;
811 if (gspca_dev->streaming)
812 setexposure(gspca_dev);
813 return 0;
814}
815
816static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
817{
818 struct sd *sd = (struct sd *) gspca_dev;
819
820 *val = sd->exposure;
821 return 0;
822}
823
824static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
825{
826 struct sd *sd = (struct sd *) gspca_dev;
827
828 /* don't allow mucking with gain when using autogain */
829 if (sd->autogain)
830 return -EINVAL;
831
832 sd->gain = val;
833 if (gspca_dev->streaming)
834 setgain(gspca_dev);
835 return 0;
836}
837
838static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
839{
840 struct sd *sd = (struct sd *) gspca_dev;
841
842 *val = sd->gain;
843 return 0;
844}
845
846static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
847{
848 struct sd *sd = (struct sd *) gspca_dev;
849
850 sd->autogain = val;
851 /* when switching to autogain set defaults to make sure
852 we are on a valid point of the autogain gain /
853 exposure knee graph, and give this change time to
854 take effect before doing autogain. */
855 if (sd->autogain) {
856 sd->exposure = PAC207_EXPOSURE_DEFAULT;
857 sd->gain = PAC207_GAIN_DEFAULT;
858 if (gspca_dev->streaming) {
859 sd->autogain_ignore_frames =
860 PAC207_AUTOGAIN_IGNORE_FRAMES;
861 setexposure(gspca_dev);
862 setgain(gspca_dev);
863 }
864 }
865
866 return 0;
867}
868
869static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
870{
871 struct sd *sd = (struct sd *) gspca_dev;
872
873 *val = sd->autogain;
874 return 0;
875}
876
877/* sub-driver description */
878static struct sd_desc sd_desc = {
879 .name = MODULE_NAME,
880 .ctrls = sd_ctrls,
881 .nctrls = ARRAY_SIZE(sd_ctrls),
882 .config = sd_config,
883 .open = sd_open,
884 .start = sd_start,
885 .stopN = sd_stopN,
886 .stop0 = sd_stop0,
887 .close = sd_close,
888 .dq_callback = pac207_do_auto_gain,
889 .pkt_scan = sd_pkt_scan,
890};
891
892/* -- module initialisation -- */
893#define DVNM(name) .driver_info = (kernel_ulong_t) name
894static __devinitdata struct usb_device_id device_table[] = {
895 {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")},
896 {USB_DEVICE(0x093a, 0x2460), DVNM("PAC207 Qtec Webcam 100")},
897 {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")},
898 {USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")},
899 {USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")},
900 {USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")},
901 {USB_DEVICE(0x093a, 0x2471), DVNM("PAC207 Genius VideoCam ge111")},
902 {USB_DEVICE(0x093a, 0x2472), DVNM("PAC207 Genius VideoCam ge110")},
903 {USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")},
904 {}
905};
906MODULE_DEVICE_TABLE(usb, device_table);
907
908/* -- device connect -- */
909static int sd_probe(struct usb_interface *intf,
910 const struct usb_device_id *id)
911{
912 PDEBUG(D_PROBE, "camera probe");
913 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd));
914}
915
916static struct usb_driver sd_driver = {
917 .name = MODULE_NAME,
918 .id_table = device_table,
919 .probe = sd_probe,
920 .disconnect = gspca_disconnect,
921};
922
923/* -- module insert / remove -- */
924static int __init sd_mod_init(void)
925{
926 init_pixart_decoder();
927 if (usb_register(&sd_driver) < 0)
928 return -1;
929 PDEBUG(D_PROBE, "v%s registered", version);
930 return 0;
931}
932static void __exit sd_mod_exit(void)
933{
934 usb_deregister(&sd_driver);
935 PDEBUG(D_PROBE, "deregistered");
936}
937
938module_init(sd_mod_init);
939module_exit(sd_mod_exit);