diff options
author | malattia@linux.it <malattia@linux.it> | 2007-04-28 10:18:45 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-04-28 22:05:48 -0400 |
commit | 5f3d2898d79520bc8d8706ed3859060f9cbb969e (patch) | |
tree | 3889fe41f3c25a635781a78ea84b1060ac6e523c /drivers/misc/sony-laptop.c | |
parent | 7b153f366867a3b70daeaf3c6074e4a0594057a7 (diff) |
sony-laptop: add camera enable/disable parameter, better handle possible infinite loop
Use a parameter to enable/disable motion eye camera (for C1VE/C1VN models)
controls and avoid entering an infinite loop if the camera is not present
and the HW doesn't answer as we expect on io commands.
Signed-off-by: Mattia Dongili <malattia@linux.it>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/misc/sony-laptop.c')
-rw-r--r-- | drivers/misc/sony-laptop.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 8cc041182a11..09e75390ac98 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
@@ -107,6 +107,12 @@ module_param(mask, ulong, 0644); | |||
107 | MODULE_PARM_DESC(mask, | 107 | MODULE_PARM_DESC(mask, |
108 | "set this to the mask of event you want to enable (see doc)"); | 108 | "set this to the mask of event you want to enable (see doc)"); |
109 | 109 | ||
110 | static int camera; /* = 0 */ | ||
111 | module_param(camera, int, 0444); | ||
112 | MODULE_PARM_DESC(camera, | ||
113 | "set this to 1 to enable Motion Eye camera controls " | ||
114 | "(only use it if you have a C1VE or C1VN model)"); | ||
115 | |||
110 | #ifdef CONFIG_SONY_LAPTOP_OLD | 116 | #ifdef CONFIG_SONY_LAPTOP_OLD |
111 | static int minor = -1; | 117 | static int minor = -1; |
112 | module_param(minor, int, 0); | 118 | module_param(minor, int, 0); |
@@ -1226,29 +1232,39 @@ static int sony_pic_camera_ready(void) | |||
1226 | return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY)); | 1232 | return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY)); |
1227 | } | 1233 | } |
1228 | 1234 | ||
1229 | static void sony_pic_camera_off(void) | 1235 | static int sony_pic_camera_off(void) |
1230 | { | 1236 | { |
1237 | if (!camera) { | ||
1238 | printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); | ||
1239 | return -ENODEV; | ||
1240 | } | ||
1241 | |||
1231 | wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, | 1242 | wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_PICTURE, |
1232 | SONYPI_CAMERA_MUTE_MASK), | 1243 | SONYPI_CAMERA_MUTE_MASK), |
1233 | ITERATIONS_SHORT); | 1244 | ITERATIONS_SHORT); |
1234 | 1245 | ||
1235 | if (!spic_dev.camera_power) | 1246 | if (spic_dev.camera_power) { |
1236 | return; | 1247 | sony_pic_call2(0x91, 0); |
1237 | 1248 | spic_dev.camera_power = 0; | |
1238 | sony_pic_call2(0x91, 0); | 1249 | } |
1239 | spic_dev.camera_power = 0; | 1250 | return 0; |
1240 | } | 1251 | } |
1241 | 1252 | ||
1242 | static void sony_pic_camera_on(void) | 1253 | static int sony_pic_camera_on(void) |
1243 | { | 1254 | { |
1244 | int i, j; | 1255 | int i, j, x; |
1256 | |||
1257 | if (!camera) { | ||
1258 | printk(KERN_WARNING DRV_PFX "camera control not enabled\n"); | ||
1259 | return -ENODEV; | ||
1260 | } | ||
1245 | 1261 | ||
1246 | if (spic_dev.camera_power) | 1262 | if (spic_dev.camera_power) |
1247 | return; | 1263 | return 0; |
1248 | 1264 | ||
1249 | for (j = 5; j > 0; j--) { | 1265 | for (j = 5; j > 0; j--) { |
1250 | 1266 | ||
1251 | while (sony_pic_call2(0x91, 0x1)) | 1267 | for (x = 0; x < 100 && sony_pic_call2(0x91, 0x1); x++) |
1252 | msleep(10); | 1268 | msleep(10); |
1253 | sony_pic_call1(0x93); | 1269 | sony_pic_call1(0x93); |
1254 | 1270 | ||
@@ -1262,8 +1278,8 @@ static void sony_pic_camera_on(void) | |||
1262 | } | 1278 | } |
1263 | 1279 | ||
1264 | if (j == 0) { | 1280 | if (j == 0) { |
1265 | printk(KERN_WARNING "sonypi: failed to power on camera\n"); | 1281 | printk(KERN_WARNING DRV_PFX "failed to power on camera\n"); |
1266 | return; | 1282 | return -ENODEV; |
1267 | } | 1283 | } |
1268 | 1284 | ||
1269 | wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL, | 1285 | wait_on_command(sony_pic_call3(0x90, SONYPI_CAMERA_CONTROL, |
@@ -1271,6 +1287,7 @@ static void sony_pic_camera_on(void) | |||
1271 | ITERATIONS_SHORT); | 1287 | ITERATIONS_SHORT); |
1272 | 1288 | ||
1273 | spic_dev.camera_power = 1; | 1289 | spic_dev.camera_power = 1; |
1290 | return 0; | ||
1274 | } | 1291 | } |
1275 | 1292 | ||
1276 | static ssize_t sony_pic_camerapower_store(struct device *dev, | 1293 | static ssize_t sony_pic_camerapower_store(struct device *dev, |
@@ -1278,14 +1295,18 @@ static ssize_t sony_pic_camerapower_store(struct device *dev, | |||
1278 | const char *buffer, size_t count) | 1295 | const char *buffer, size_t count) |
1279 | { | 1296 | { |
1280 | unsigned long value; | 1297 | unsigned long value; |
1298 | int result; | ||
1281 | if (count > 31) | 1299 | if (count > 31) |
1282 | return -EINVAL; | 1300 | return -EINVAL; |
1283 | 1301 | ||
1284 | value = simple_strtoul(buffer, NULL, 10); | 1302 | value = simple_strtoul(buffer, NULL, 10); |
1285 | if (value) | 1303 | if (value) |
1286 | sony_pic_camera_on(); | 1304 | result = sony_pic_camera_on(); |
1287 | else | 1305 | else |
1288 | sony_pic_camera_off(); | 1306 | result = sony_pic_camera_off(); |
1307 | |||
1308 | if (result) | ||
1309 | return result; | ||
1289 | 1310 | ||
1290 | return count; | 1311 | return count; |
1291 | } | 1312 | } |
@@ -1662,7 +1683,7 @@ static int sonypi_compat_init(void) | |||
1662 | goto err_free_kfifo; | 1683 | goto err_free_kfifo; |
1663 | } | 1684 | } |
1664 | if (minor == -1) | 1685 | if (minor == -1) |
1665 | printk(KERN_INFO "sonypi: device allocated minor is %d\n", | 1686 | printk(KERN_INFO DRV_PFX "device allocated minor is %d\n", |
1666 | sonypi_misc_device.minor); | 1687 | sonypi_misc_device.minor); |
1667 | 1688 | ||
1668 | return 0; | 1689 | return 0; |