From 0522921c0f89f274a99d5084ca0a6fd370749cc8 Mon Sep 17 00:00:00 2001 From: Daniel Drake <dsd@laptop.org> Date: Fri, 11 Feb 2011 18:15:02 -0300 Subject: [PATCH] [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> --- drivers/media/video/via-camera.c | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) 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 = { /* * Power management. */ +#ifdef CONFIG_PM + +static int viacam_suspend(void *priv) +{ + struct via_camera *cam = priv; + enum viacam_opstate state = cam->opstate; + + if (cam->opstate != S_IDLE) { + viacam_stop_engine(cam); + cam->opstate = state; /* So resume restarts */ + } + + return 0; +} + +static int viacam_resume(void *priv) +{ + struct via_camera *cam = priv; + int ret = 0; + + /* + * Get back to a reasonable operating state. + */ + via_write_reg_mask(VIASR, 0x78, 0, 0x80); + via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0); + viacam_int_disable(cam); + set_bit(CF_CONFIG_NEEDED, &cam->flags); + /* + * Make sure the sensor's power state is correct + */ + if (cam->users > 0) + via_sensor_power_up(cam); + else + via_sensor_power_down(cam); + /* + * If it was operating, try to restart it. + */ + if (cam->opstate != S_IDLE) { + mutex_lock(&cam->lock); + ret = viacam_configure_sensor(cam); + if (!ret) + ret = viacam_config_controller(cam); + mutex_unlock(&cam->lock); + if (!ret) + viacam_start_engine(cam); + } + + return ret; +} + +static struct viafb_pm_hooks viacam_pm_hooks = { + .suspend = viacam_suspend, + .resume = viacam_resume +}; + +#endif /* CONFIG_PM */ /* * Setup stuff. @@ -1369,6 +1425,14 @@ static __devinit int viacam_probe(struct platform_device *pdev) goto out_irq; video_set_drvdata(&cam->vdev, cam); +#ifdef CONFIG_PM + /* + * Hook into PM events + */ + viacam_pm_hooks.private = cam; + viafb_pm_register(&viacam_pm_hooks); +#endif + /* Power the sensor down until somebody opens the device */ via_sensor_power_down(cam); return 0;