aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sony-laptop.c
diff options
context:
space:
mode:
authormalattia@linux.it <malattia@linux.it>2007-04-28 10:18:45 -0400
committerLen Brown <len.brown@intel.com>2007-04-28 22:05:48 -0400
commit5f3d2898d79520bc8d8706ed3859060f9cbb969e (patch)
tree3889fe41f3c25a635781a78ea84b1060ac6e523c /drivers/misc/sony-laptop.c
parent7b153f366867a3b70daeaf3c6074e4a0594057a7 (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.c51
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);
107MODULE_PARM_DESC(mask, 107MODULE_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
110static int camera; /* = 0 */
111module_param(camera, int, 0444);
112MODULE_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
111static int minor = -1; 117static int minor = -1;
112module_param(minor, int, 0); 118module_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
1229static void sony_pic_camera_off(void) 1235static 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
1242static void sony_pic_camera_on(void) 1253static 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
1276static ssize_t sony_pic_camerapower_store(struct device *dev, 1293static 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;