aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Drake <dsd@laptop.org>2011-02-11 16:15:02 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:37 -0400
commit0522921c0f89f274a99d5084ca0a6fd370749cc8 (patch)
treec3990b5d1574f404720910783b6bbbba2eb5345a /drivers
parent498e677cfd78b098342640f382293782bfa0bd63 (diff)
[media] via-camera: Add suspend/resume support
Add suspend/resume support to the via-camera driver, so that the video continues streaming over a suspend-resume cycle. Originally implemented by Jon Corbet. [mchehab@redhat.com: fix a small CodingStyle issue] Signed-off-by: Daniel Drake <dsd@laptop.org> Acked-by: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/via-camera.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 2f973cd56408..3f0146fcf752 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -1246,6 +1246,62 @@ static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
1246/* 1246/*
1247 * Power management. 1247 * Power management.
1248 */ 1248 */
1249#ifdef CONFIG_PM
1250
1251static int viacam_suspend(void *priv)
1252{
1253 struct via_camera *cam = priv;
1254 enum viacam_opstate state = cam->opstate;
1255
1256 if (cam->opstate != S_IDLE) {
1257 viacam_stop_engine(cam);
1258 cam->opstate = state; /* So resume restarts */
1259 }
1260
1261 return 0;
1262}
1263
1264static int viacam_resume(void *priv)
1265{
1266 struct via_camera *cam = priv;
1267 int ret = 0;
1268
1269 /*
1270 * Get back to a reasonable operating state.
1271 */
1272 via_write_reg_mask(VIASR, 0x78, 0, 0x80);
1273 via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
1274 viacam_int_disable(cam);
1275 set_bit(CF_CONFIG_NEEDED, &cam->flags);
1276 /*
1277 * Make sure the sensor's power state is correct
1278 */
1279 if (cam->users > 0)
1280 via_sensor_power_up(cam);
1281 else
1282 via_sensor_power_down(cam);
1283 /*
1284 * If it was operating, try to restart it.
1285 */
1286 if (cam->opstate != S_IDLE) {
1287 mutex_lock(&cam->lock);
1288 ret = viacam_configure_sensor(cam);
1289 if (!ret)
1290 ret = viacam_config_controller(cam);
1291 mutex_unlock(&cam->lock);
1292 if (!ret)
1293 viacam_start_engine(cam);
1294 }
1295
1296 return ret;
1297}
1298
1299static struct viafb_pm_hooks viacam_pm_hooks = {
1300 .suspend = viacam_suspend,
1301 .resume = viacam_resume
1302};
1303
1304#endif /* CONFIG_PM */
1249 1305
1250/* 1306/*
1251 * Setup stuff. 1307 * Setup stuff.
@@ -1369,6 +1425,14 @@ static __devinit int viacam_probe(struct platform_device *pdev)
1369 goto out_irq; 1425 goto out_irq;
1370 video_set_drvdata(&cam->vdev, cam); 1426 video_set_drvdata(&cam->vdev, cam);
1371 1427
1428#ifdef CONFIG_PM
1429 /*
1430 * Hook into PM events
1431 */
1432 viacam_pm_hooks.private = cam;
1433 viafb_pm_register(&viacam_pm_hooks);
1434#endif
1435
1372 /* Power the sensor down until somebody opens the device */ 1436 /* Power the sensor down until somebody opens the device */
1373 via_sensor_power_down(cam); 1437 via_sensor_power_down(cam);
1374 return 0; 1438 return 0;