aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca')
-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 885d4454d8e5..81170c19ba47 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 4fe082ff7074..c4735e133611 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 1394ab13f1f4..3bfb3641cf36 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 000000000000..ac16c7352892
--- /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);