aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pwc')
-rw-r--r--drivers/media/video/pwc/pwc-if.c129
1 files changed, 2 insertions, 127 deletions
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index a07df4e4aa04..a691cf821747 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -133,12 +133,6 @@ static struct usb_driver pwc_driver = {
133#endif 133#endif
134static int power_save = -1; 134static int power_save = -1;
135static int led_on = 100, led_off; /* defaults to LED that is on while in use */ 135static int led_on = 100, led_off; /* defaults to LED that is on while in use */
136static struct {
137 int type;
138 char serial_number[30];
139 int device_node;
140 struct pwc_device *pdev;
141} device_hint[MAX_DEV_HINTS];
142 136
143/***/ 137/***/
144 138
@@ -596,15 +590,8 @@ leave:
596static void pwc_video_release(struct v4l2_device *v) 590static void pwc_video_release(struct v4l2_device *v)
597{ 591{
598 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); 592 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
599 int hint;
600
601 /* search device_hint[] table if we occupy a slot, by any chance */
602 for (hint = 0; hint < MAX_DEV_HINTS; hint++)
603 if (device_hint[hint].pdev == pdev)
604 device_hint[hint].pdev = NULL;
605 593
606 v4l2_ctrl_handler_free(&pdev->ctrl_handler); 594 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
607
608 kfree(pdev->ctrl_buf); 595 kfree(pdev->ctrl_buf);
609 kfree(pdev); 596 kfree(pdev);
610} 597}
@@ -805,10 +792,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
805 struct usb_device *udev = interface_to_usbdev(intf); 792 struct usb_device *udev = interface_to_usbdev(intf);
806 struct pwc_device *pdev = NULL; 793 struct pwc_device *pdev = NULL;
807 int vendor_id, product_id, type_id; 794 int vendor_id, product_id, type_id;
808 int hint, rc; 795 int rc;
809 int features = 0; 796 int features = 0;
810 int compression = 0; 797 int compression = 0;
811 int video_nr = -1; /* default: use next available device */
812 int my_power_save = power_save; 798 int my_power_save = power_save;
813 char serial_number[30], *name; 799 char serial_number[30], *name;
814 800
@@ -1098,24 +1084,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1098 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); 1084 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
1099 PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); 1085 PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
1100 1086
1101 /* Now search device_hint[] table for a match, so we can hint a node number. */
1102 for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
1103 if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) &&
1104 (device_hint[hint].pdev == NULL)) {
1105 /* so far, so good... try serial number */
1106 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
1107 /* match! */
1108 video_nr = device_hint[hint].device_node;
1109 PWC_DEBUG_PROBE("Found hint, will try to register as /dev/video%d\n", video_nr);
1110 break;
1111 }
1112 }
1113 }
1114
1115 /* occupy slot */
1116 if (hint < MAX_DEV_HINTS)
1117 device_hint[hint].pdev = pdev;
1118
1119 /* Allocate USB command buffers */ 1087 /* Allocate USB command buffers */
1120 pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL); 1088 pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL);
1121 if (!pdev->ctrl_buf) { 1089 if (!pdev->ctrl_buf) {
@@ -1163,7 +1131,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1163 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; 1131 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
1164 pdev->vdev.v4l2_dev = &pdev->v4l2_dev; 1132 pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
1165 1133
1166 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); 1134 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
1167 if (rc < 0) { 1135 if (rc < 0) {
1168 PWC_ERROR("Failed to register as video device (%d).\n", rc); 1136 PWC_ERROR("Failed to register as video device (%d).\n", rc);
1169 goto err_unregister_v4l2_dev; 1137 goto err_unregister_v4l2_dev;
@@ -1206,8 +1174,6 @@ err_unregister_v4l2_dev:
1206err_free_controls: 1174err_free_controls:
1207 v4l2_ctrl_handler_free(&pdev->ctrl_handler); 1175 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
1208err_free_mem: 1176err_free_mem:
1209 if (hint < MAX_DEV_HINTS)
1210 device_hint[hint].pdev = NULL;
1211 kfree(pdev->ctrl_buf); 1177 kfree(pdev->ctrl_buf);
1212 kfree(pdev); 1178 kfree(pdev);
1213 return rc; 1179 return rc;
@@ -1245,22 +1211,18 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1245 1211
1246static int leds[2] = { -1, -1 }; 1212static int leds[2] = { -1, -1 };
1247static unsigned int leds_nargs; 1213static unsigned int leds_nargs;
1248static char *dev_hint[MAX_DEV_HINTS];
1249static unsigned int dev_hint_nargs;
1250 1214
1251#ifdef CONFIG_USB_PWC_DEBUG 1215#ifdef CONFIG_USB_PWC_DEBUG
1252module_param_named(trace, pwc_trace, int, 0644); 1216module_param_named(trace, pwc_trace, int, 0644);
1253#endif 1217#endif
1254module_param(power_save, int, 0644); 1218module_param(power_save, int, 0644);
1255module_param_array(leds, int, &leds_nargs, 0444); 1219module_param_array(leds, int, &leds_nargs, 0444);
1256module_param_array(dev_hint, charp, &dev_hint_nargs, 0444);
1257 1220
1258#ifdef CONFIG_USB_PWC_DEBUG 1221#ifdef CONFIG_USB_PWC_DEBUG
1259MODULE_PARM_DESC(trace, "For debugging purposes"); 1222MODULE_PARM_DESC(trace, "For debugging purposes");
1260#endif 1223#endif
1261MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); 1224MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
1262MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); 1225MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
1263MODULE_PARM_DESC(dev_hint, "Device node hints");
1264 1226
1265MODULE_DESCRIPTION("Philips & OEM USB webcam driver"); 1227MODULE_DESCRIPTION("Philips & OEM USB webcam driver");
1266MODULE_AUTHOR("Luc Saillard <luc@saillard.org>"); 1228MODULE_AUTHOR("Luc Saillard <luc@saillard.org>");
@@ -1270,105 +1232,18 @@ MODULE_VERSION( PWC_VERSION );
1270 1232
1271static int __init usb_pwc_init(void) 1233static int __init usb_pwc_init(void)
1272{ 1234{
1273 int i;
1274
1275#ifdef CONFIG_USB_PWC_DEBUG
1276 PWC_INFO("Philips webcam module version " PWC_VERSION " loaded.\n");
1277 PWC_INFO("Supports Philips PCA645/646, PCVC675/680/690, PCVC720[40]/730/740/750 & PCVC830/840.\n");
1278 PWC_INFO("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
1279 PWC_INFO("the Creative WebCam 5 & Pro Ex, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
1280
1281 if (pwc_trace >= 0) {
1282 PWC_DEBUG_MODULE("Trace options: 0x%04x\n", pwc_trace);
1283 }
1284#endif
1285
1286 if (leds[0] >= 0) 1235 if (leds[0] >= 0)
1287 led_on = leds[0]; 1236 led_on = leds[0];
1288 if (leds[1] >= 0) 1237 if (leds[1] >= 0)
1289 led_off = leds[1]; 1238 led_off = leds[1];
1290 1239
1291 /* Big device node whoopla. Basically, it allows you to assign a
1292 device node (/dev/videoX) to a camera, based on its type
1293 & serial number. The format is [type[.serialnumber]:]node.
1294
1295 Any camera that isn't matched by these rules gets the next
1296 available free device node.
1297 */
1298 for (i = 0; i < MAX_DEV_HINTS; i++) {
1299 char *s, *colon, *dot;
1300
1301 /* This loop also initializes the array */
1302 device_hint[i].pdev = NULL;
1303 s = dev_hint[i];
1304 if (s != NULL && *s != '\0') {
1305 device_hint[i].type = -1; /* wildcard */
1306 strcpy(device_hint[i].serial_number, "*");
1307
1308 /* parse string: chop at ':' & '/' */
1309 colon = dot = s;
1310 while (*colon != '\0' && *colon != ':')
1311 colon++;
1312 while (*dot != '\0' && *dot != '.')
1313 dot++;
1314 /* Few sanity checks */
1315 if (*dot != '\0' && dot > colon) {
1316 PWC_ERROR("Malformed camera hint: the colon must be after the dot.\n");
1317 return -EINVAL;
1318 }
1319
1320 if (*colon == '\0') {
1321 /* No colon */
1322 if (*dot != '\0') {
1323 PWC_ERROR("Malformed camera hint: no colon + device node given.\n");
1324 return -EINVAL;
1325 }
1326 else {
1327 /* No type or serial number specified, just a number. */
1328 device_hint[i].device_node =
1329 simple_strtol(s, NULL, 10);
1330 }
1331 }
1332 else {
1333 /* There's a colon, so we have at least a type and a device node */
1334 device_hint[i].type =
1335 simple_strtol(s, NULL, 10);
1336 device_hint[i].device_node =
1337 simple_strtol(colon + 1, NULL, 10);
1338 if (*dot != '\0') {
1339 /* There's a serial number as well */
1340 int k;
1341
1342 dot++;
1343 k = 0;
1344 while (*dot != ':' && k < 29) {
1345 device_hint[i].serial_number[k++] = *dot;
1346 dot++;
1347 }
1348 device_hint[i].serial_number[k] = '\0';
1349 }
1350 }
1351 PWC_TRACE("device_hint[%d]:\n", i);
1352 PWC_TRACE(" type : %d\n", device_hint[i].type);
1353 PWC_TRACE(" serial# : %s\n", device_hint[i].serial_number);
1354 PWC_TRACE(" node : %d\n", device_hint[i].device_node);
1355 }
1356 else
1357 device_hint[i].type = 0; /* not filled */
1358 } /* ..for MAX_DEV_HINTS */
1359
1360 PWC_DEBUG_PROBE("Registering driver at address 0x%p.\n", &pwc_driver);
1361 return usb_register(&pwc_driver); 1240 return usb_register(&pwc_driver);
1362} 1241}
1363 1242
1364static void __exit usb_pwc_exit(void) 1243static void __exit usb_pwc_exit(void)
1365{ 1244{
1366 PWC_DEBUG_MODULE("Deregistering driver.\n");
1367 usb_deregister(&pwc_driver); 1245 usb_deregister(&pwc_driver);
1368 PWC_INFO("Philips webcam module removed.\n");
1369} 1246}
1370 1247
1371module_init(usb_pwc_init); 1248module_init(usb_pwc_init);
1372module_exit(usb_pwc_exit); 1249module_exit(usb_pwc_exit);
1373
1374/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */