aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJaime Velasco Juan <jsagarribay@gmail.com>2008-01-27 10:24:59 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-02-18 09:14:58 -0500
commit1fdd61c0228a32b9a5e10593b225851d8920595b (patch)
tree61a2134e8a05f10fe51b0904d361a4b1eafc6e37 /drivers/media
parent1112fb68ae9c838294d38e1f209fedbc0dbf11d5 (diff)
V4L/DVB (7089): V4L: stkwebcam: Power management support
Signed-off-by: Jaime Velasco Juan <jsagarribay@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/stk-webcam.c92
-rw-r--r--drivers/media/video/stk-webcam.h1
2 files changed, 73 insertions, 20 deletions
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index ba4fe934ee9e..f84e8d511763 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -682,6 +682,7 @@ static int v4l_stk_open(struct inode *inode, struct file *fp)
682 return -ENXIO; 682 return -ENXIO;
683 fp->private_data = vdev; 683 fp->private_data = vdev;
684 kref_get(&dev->kref); 684 kref_get(&dev->kref);
685 usb_autopm_get_interface(dev->interface);
685 686
686 return 0; 687 return 0;
687} 688}
@@ -703,6 +704,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
703 } 704 }
704 705
705 if (dev->owner != fp) { 706 if (dev->owner != fp) {
707 usb_autopm_put_interface(dev->interface);
706 kref_put(&dev->kref, stk_camera_cleanup); 708 kref_put(&dev->kref, stk_camera_cleanup);
707 return 0; 709 return 0;
708 } 710 }
@@ -713,6 +715,7 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
713 715
714 dev->owner = NULL; 716 dev->owner = NULL;
715 717
718 usb_autopm_put_interface(dev->interface);
716 kref_put(&dev->kref, stk_camera_cleanup); 719 kref_put(&dev->kref, stk_camera_cleanup);
717 720
718 return 0; 721 return 0;
@@ -1085,6 +1088,42 @@ static int stk_vidioc_try_fmt_cap(struct file *filp,
1085 return 0; 1088 return 0;
1086} 1089}
1087 1090
1091static int stk_setup_format(struct stk_camera *dev)
1092{
1093 int i = 0;
1094 int depth;
1095 if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
1096 depth = 1;
1097 else
1098 depth = 2;
1099 while (stk_sizes[i].m != dev->vsettings.mode
1100 && i < ARRAY_SIZE(stk_sizes))
1101 i++;
1102 if (i == ARRAY_SIZE(stk_sizes)) {
1103 STK_ERROR("Something is broken in %s\n", __FUNCTION__);
1104 return -EFAULT;
1105 }
1106 /* This registers controls some timings, not sure of what. */
1107 stk_camera_write_reg(dev, 0x001b, 0x0e);
1108 if (dev->vsettings.mode == MODE_SXGA)
1109 stk_camera_write_reg(dev, 0x001c, 0x0e);
1110 else
1111 stk_camera_write_reg(dev, 0x001c, 0x46);
1112 /*
1113 * Registers 0x0115 0x0114 are the size of each line (bytes),
1114 * regs 0x0117 0x0116 are the heigth of the image.
1115 */
1116 stk_camera_write_reg(dev, 0x0115,
1117 ((stk_sizes[i].w * depth) >> 8) & 0xff);
1118 stk_camera_write_reg(dev, 0x0114,
1119 (stk_sizes[i].w * depth) & 0xff);
1120 stk_camera_write_reg(dev, 0x0117,
1121 (stk_sizes[i].h >> 8) & 0xff);
1122 stk_camera_write_reg(dev, 0x0116,
1123 stk_sizes[i].h & 0xff);
1124 return stk_sensor_configure(dev);
1125}
1126
1088static int stk_vidioc_s_fmt_cap(struct file *filp, 1127static int stk_vidioc_s_fmt_cap(struct file *filp,
1089 void *priv, struct v4l2_format *fmtd) 1128 void *priv, struct v4l2_format *fmtd)
1090{ 1129{
@@ -1099,10 +1138,10 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
1099 return -EBUSY; 1138 return -EBUSY;
1100 if (dev->owner && dev->owner != filp) 1139 if (dev->owner && dev->owner != filp)
1101 return -EBUSY; 1140 return -EBUSY;
1102 dev->owner = filp;
1103 ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd); 1141 ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd);
1104 if (ret) 1142 if (ret)
1105 return ret; 1143 return ret;
1144 dev->owner = filp;
1106 1145
1107 dev->vsettings.palette = fmtd->fmt.pix.pixelformat; 1146 dev->vsettings.palette = fmtd->fmt.pix.pixelformat;
1108 stk_free_buffers(dev); 1147 stk_free_buffers(dev);
@@ -1110,25 +1149,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp,
1110 dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m; 1149 dev->vsettings.mode = stk_sizes[fmtd->fmt.pix.priv].m;
1111 1150
1112 stk_initialise(dev); 1151 stk_initialise(dev);
1113 /* This registers controls some timings, not sure of what. */ 1152 return stk_setup_format(dev);
1114 stk_camera_write_reg(dev, 0x001b, 0x0e);
1115 if (dev->vsettings.mode == MODE_SXGA)
1116 stk_camera_write_reg(dev, 0x001c, 0x0e);
1117 else
1118 stk_camera_write_reg(dev, 0x001c, 0x46);
1119 /*
1120 * Registers 0x0115 0x0114 are the size of each line (bytes),
1121 * regs 0x0117 0x0116 are the heigth of the image.
1122 */
1123 stk_camera_write_reg(dev, 0x0115,
1124 (fmtd->fmt.pix.bytesperline >> 8) & 0xff);
1125 stk_camera_write_reg(dev, 0x0114,
1126 fmtd->fmt.pix.bytesperline & 0xff);
1127 stk_camera_write_reg(dev, 0x0117,
1128 (fmtd->fmt.pix.height >> 8) & 0xff);
1129 stk_camera_write_reg(dev, 0x0116,
1130 fmtd->fmt.pix.height & 0xff);
1131 return stk_sensor_configure(dev);
1132} 1153}
1133 1154
1134static int stk_vidioc_reqbufs(struct file *filp, 1155static int stk_vidioc_reqbufs(struct file *filp,
@@ -1422,6 +1443,7 @@ static int stk_camera_probe(struct usb_interface *interface,
1422 } 1443 }
1423 1444
1424 stk_create_sysfs_files(&dev->vdev); 1445 stk_create_sysfs_files(&dev->vdev);
1446 usb_autopm_enable(dev->interface);
1425 1447
1426 return 0; 1448 return 0;
1427} 1449}
@@ -1439,11 +1461,41 @@ static void stk_camera_disconnect(struct usb_interface *interface)
1439 kref_put(&dev->kref, stk_camera_cleanup); 1461 kref_put(&dev->kref, stk_camera_cleanup);
1440} 1462}
1441 1463
1464#ifdef CONFIG_PM
1465int stk_camera_suspend(struct usb_interface *intf, pm_message_t message)
1466{
1467 struct stk_camera *dev = usb_get_intfdata(intf);
1468 if (is_streaming(dev)) {
1469 stk_stop_stream(dev);
1470 /* yes, this is ugly */
1471 set_streaming(dev);
1472 }
1473 return 0;
1474}
1475
1476int stk_camera_resume(struct usb_interface *intf)
1477{
1478 struct stk_camera *dev = usb_get_intfdata(intf);
1479 if (!is_initialised(dev))
1480 return 0;
1481 unset_initialised(dev);
1482 stk_initialise(dev);
1483 stk_setup_format(dev);
1484 if (is_streaming(dev))
1485 stk_start_stream(dev);
1486 return 0;
1487}
1488#endif
1489
1442static struct usb_driver stk_camera_driver = { 1490static struct usb_driver stk_camera_driver = {
1443 .name = "stkwebcam", 1491 .name = "stkwebcam",
1444 .probe = stk_camera_probe, 1492 .probe = stk_camera_probe,
1445 .disconnect = stk_camera_disconnect, 1493 .disconnect = stk_camera_disconnect,
1446 .id_table = stkwebcam_table, 1494 .id_table = stkwebcam_table,
1495#ifdef CONFIG_PM
1496 .suspend = stk_camera_suspend,
1497 .resume = stk_camera_resume,
1498#endif
1447}; 1499};
1448 1500
1449 1501
diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h
index 7e989d1ac1e0..a2164cb1ad26 100644
--- a/drivers/media/video/stk-webcam.h
+++ b/drivers/media/video/stk-webcam.h
@@ -79,6 +79,7 @@ enum stk_status {
79#define unset_present(dev) ((dev)->status &= \ 79#define unset_present(dev) ((dev)->status &= \
80 ~(S_PRESENT|S_INITIALISED|S_STREAMING)) 80 ~(S_PRESENT|S_INITIALISED|S_STREAMING))
81#define set_initialised(dev) ((dev)->status |= S_INITIALISED) 81#define set_initialised(dev) ((dev)->status |= S_INITIALISED)
82#define unset_initialised(dev) ((dev)->status &= ~S_INITIALISED)
82#define set_memallocd(dev) ((dev)->status |= S_MEMALLOCD) 83#define set_memallocd(dev) ((dev)->status |= S_MEMALLOCD)
83#define unset_memallocd(dev) ((dev)->status &= ~S_MEMALLOCD) 84#define unset_memallocd(dev) ((dev)->status &= ~S_MEMALLOCD)
84#define set_streaming(dev) ((dev)->status |= S_STREAMING) 85#define set_streaming(dev) ((dev)->status |= S_STREAMING)