diff options
author | Daniel Drake <dsd@laptop.org> | 2011-02-11 16:15:02 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:32:37 -0400 |
commit | 0522921c0f89f274a99d5084ca0a6fd370749cc8 (patch) | |
tree | c3990b5d1574f404720910783b6bbbba2eb5345a /drivers | |
parent | 498e677cfd78b098342640f382293782bfa0bd63 (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.c | 64 |
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 | |||
1251 | static 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 | |||
1264 | static 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 | |||
1299 | static 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; |