diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:49:44 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:49:44 -0400 |
| commit | a39db27a08ef85ae37beab261744d8b38f21225c (patch) | |
| tree | 7dc1964e1052f162977c45b6489b07b6f275887f | |
| parent | ad98c0f674796848c6fd8fe614ef83ef971ebfcf (diff) | |
V4L/DVB: gspca - sn9c20x: use gspca's input device handling
Drop custom code for handling the input button in
favor of using gspca's input hanlding mechinism.
Signed-off-by: Brian Johnson <brijohn@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/video/gspca/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/media/video/gspca/sn9c20x.c | 147 |
2 files changed, 34 insertions, 119 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index e0060c1f0544..5d920e584de7 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig | |||
| @@ -172,12 +172,6 @@ config USB_GSPCA_SN9C20X | |||
| 172 | To compile this driver as a module, choose M here: the | 172 | To compile this driver as a module, choose M here: the |
| 173 | module will be called gspca_sn9c20x. | 173 | module will be called gspca_sn9c20x. |
| 174 | 174 | ||
| 175 | config USB_GSPCA_SN9C20X_EVDEV | ||
| 176 | bool "Enable evdev support" | ||
| 177 | depends on USB_GSPCA_SN9C20X && INPUT | ||
| 178 | ---help--- | ||
| 179 | Say Y here in order to enable evdev support for sn9c20x webcam button. | ||
| 180 | |||
| 181 | config USB_GSPCA_SONIXB | 175 | config USB_GSPCA_SONIXB |
| 182 | tristate "SONIX Bayer USB Camera Driver" | 176 | tristate "SONIX Bayer USB Camera Driver" |
| 183 | depends on VIDEO_V4L2 && USB_GSPCA | 177 | depends on VIDEO_V4L2 && USB_GSPCA |
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 04bf80ddfbb8..1653567e992a 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c | |||
| @@ -18,10 +18,7 @@ | |||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | 21 | #ifdef CONFIG_INPUT |
| 22 | #include <linux/kthread.h> | ||
| 23 | #include <linux/freezer.h> | ||
| 24 | #include <linux/usb/input.h> | ||
| 25 | #include <linux/input.h> | 22 | #include <linux/input.h> |
| 26 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 27 | #endif | 24 | #endif |
| @@ -55,6 +52,9 @@ MODULE_LICENSE("GPL"); | |||
| 55 | #define SENSOR_HV7131R 10 | 52 | #define SENSOR_HV7131R 10 |
| 56 | #define SENSOR_MT9VPRB 20 | 53 | #define SENSOR_MT9VPRB 20 |
| 57 | 54 | ||
| 55 | /* camera flags */ | ||
| 56 | #define HAS_BUTTON 0x1 | ||
| 57 | |||
| 58 | /* specific webcam descriptor */ | 58 | /* specific webcam descriptor */ |
| 59 | struct sd { | 59 | struct sd { |
| 60 | struct gspca_dev gspca_dev; | 60 | struct gspca_dev gspca_dev; |
| @@ -88,11 +88,7 @@ struct sd { | |||
| 88 | u8 *jpeg_hdr; | 88 | u8 *jpeg_hdr; |
| 89 | u8 quality; | 89 | u8 quality; |
| 90 | 90 | ||
| 91 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | 91 | u8 flags; |
| 92 | struct input_dev *input_dev; | ||
| 93 | u8 input_gpio; | ||
| 94 | struct task_struct *input_task; | ||
| 95 | #endif | ||
| 96 | }; | 92 | }; |
| 97 | 93 | ||
| 98 | struct i2c_reg_u8 { | 94 | struct i2c_reg_u8 { |
| @@ -1421,87 +1417,6 @@ static int hv7131r_init_sensor(struct gspca_dev *gspca_dev) | |||
| 1421 | return 0; | 1417 | return 0; |
| 1422 | } | 1418 | } |
| 1423 | 1419 | ||
| 1424 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | ||
| 1425 | static int input_kthread(void *data) | ||
| 1426 | { | ||
| 1427 | struct gspca_dev *gspca_dev = (struct gspca_dev *)data; | ||
| 1428 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 1429 | |||
| 1430 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait); | ||
| 1431 | set_freezable(); | ||
| 1432 | for (;;) { | ||
| 1433 | if (kthread_should_stop()) | ||
| 1434 | break; | ||
| 1435 | |||
| 1436 | if (reg_r(gspca_dev, 0x1005, 1) < 0) | ||
| 1437 | continue; | ||
| 1438 | |||
| 1439 | input_report_key(sd->input_dev, | ||
| 1440 | KEY_CAMERA, | ||
| 1441 | gspca_dev->usb_buf[0] & sd->input_gpio); | ||
| 1442 | input_sync(sd->input_dev); | ||
| 1443 | |||
| 1444 | wait_event_freezable_timeout(wait, | ||
| 1445 | kthread_should_stop(), | ||
| 1446 | msecs_to_jiffies(100)); | ||
| 1447 | } | ||
| 1448 | return 0; | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | |||
| 1452 | static int sn9c20x_input_init(struct gspca_dev *gspca_dev) | ||
| 1453 | { | ||
| 1454 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 1455 | if (sd->input_gpio == 0) | ||
| 1456 | return 0; | ||
| 1457 | |||
| 1458 | sd->input_dev = input_allocate_device(); | ||
| 1459 | if (!sd->input_dev) | ||
| 1460 | return -ENOMEM; | ||
| 1461 | |||
| 1462 | sd->input_dev->name = "SN9C20X Webcam"; | ||
| 1463 | |||
| 1464 | sd->input_dev->phys = kasprintf(GFP_KERNEL, "usb-%s-%s", | ||
| 1465 | gspca_dev->dev->bus->bus_name, | ||
| 1466 | gspca_dev->dev->devpath); | ||
| 1467 | |||
| 1468 | if (!sd->input_dev->phys) | ||
| 1469 | return -ENOMEM; | ||
| 1470 | |||
| 1471 | usb_to_input_id(gspca_dev->dev, &sd->input_dev->id); | ||
| 1472 | sd->input_dev->dev.parent = &gspca_dev->dev->dev; | ||
| 1473 | |||
| 1474 | set_bit(EV_KEY, sd->input_dev->evbit); | ||
| 1475 | set_bit(KEY_CAMERA, sd->input_dev->keybit); | ||
| 1476 | |||
| 1477 | if (input_register_device(sd->input_dev)) | ||
| 1478 | return -EINVAL; | ||
| 1479 | |||
| 1480 | sd->input_task = kthread_run(input_kthread, gspca_dev, "sn9c20x/%s-%s", | ||
| 1481 | gspca_dev->dev->bus->bus_name, | ||
| 1482 | gspca_dev->dev->devpath); | ||
| 1483 | |||
| 1484 | if (IS_ERR(sd->input_task)) | ||
| 1485 | return -EINVAL; | ||
| 1486 | |||
| 1487 | return 0; | ||
| 1488 | } | ||
| 1489 | |||
| 1490 | static void sn9c20x_input_cleanup(struct gspca_dev *gspca_dev) | ||
| 1491 | { | ||
| 1492 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 1493 | if (sd->input_task != NULL && !IS_ERR(sd->input_task)) | ||
| 1494 | kthread_stop(sd->input_task); | ||
| 1495 | |||
| 1496 | if (sd->input_dev != NULL) { | ||
| 1497 | input_unregister_device(sd->input_dev); | ||
| 1498 | kfree(sd->input_dev->phys); | ||
| 1499 | input_free_device(sd->input_dev); | ||
| 1500 | sd->input_dev = NULL; | ||
| 1501 | } | ||
| 1502 | } | ||
| 1503 | #endif | ||
| 1504 | |||
| 1505 | static int set_cmatrix(struct gspca_dev *gspca_dev) | 1420 | static int set_cmatrix(struct gspca_dev *gspca_dev) |
| 1506 | { | 1421 | { |
| 1507 | struct sd *sd = (struct sd *) gspca_dev; | 1422 | struct sd *sd = (struct sd *) gspca_dev; |
| @@ -2005,6 +1920,7 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 2005 | 1920 | ||
| 2006 | sd->sensor = (id->driver_info >> 8) & 0xff; | 1921 | sd->sensor = (id->driver_info >> 8) & 0xff; |
| 2007 | sd->i2c_addr = id->driver_info & 0xff; | 1922 | sd->i2c_addr = id->driver_info & 0xff; |
| 1923 | sd->flags = (id->driver_info >> 16) & 0xff; | ||
| 2008 | 1924 | ||
| 2009 | switch (sd->sensor) { | 1925 | switch (sd->sensor) { |
| 2010 | case SENSOR_MT9M111: | 1926 | case SENSOR_MT9M111: |
| @@ -2039,11 +1955,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
| 2039 | 1955 | ||
| 2040 | sd->quality = 95; | 1956 | sd->quality = 95; |
| 2041 | 1957 | ||
| 2042 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | ||
| 2043 | sd->input_gpio = (id->driver_info >> 16) & 0xff; | ||
| 2044 | if (sn9c20x_input_init(gspca_dev) < 0) | ||
| 2045 | return -ENODEV; | ||
| 2046 | #endif | ||
| 2047 | return 0; | 1958 | return 0; |
| 2048 | } | 1959 | } |
| 2049 | 1960 | ||
| @@ -2343,6 +2254,24 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev) | |||
| 2343 | do_autoexposure(gspca_dev, avg_lum); | 2254 | do_autoexposure(gspca_dev, avg_lum); |
| 2344 | } | 2255 | } |
| 2345 | 2256 | ||
| 2257 | #ifdef CONFIG_INPUT | ||
| 2258 | static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, | ||
| 2259 | u8 *data, /* interrupt packet */ | ||
| 2260 | int len) /* interrupt packet length */ | ||
| 2261 | { | ||
| 2262 | struct sd *sd = (struct sd *) gspca_dev; | ||
| 2263 | int ret = -EINVAL; | ||
| 2264 | if (sd->flags & HAS_BUTTON && len == 1) { | ||
| 2265 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); | ||
| 2266 | input_sync(gspca_dev->input_dev); | ||
| 2267 | input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); | ||
| 2268 | input_sync(gspca_dev->input_dev); | ||
| 2269 | ret = 0; | ||
| 2270 | } | ||
| 2271 | return ret; | ||
| 2272 | } | ||
| 2273 | #endif | ||
| 2274 | |||
| 2346 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, | 2275 | static void sd_pkt_scan(struct gspca_dev *gspca_dev, |
| 2347 | u8 *data, /* isoc packet */ | 2276 | u8 *data, /* isoc packet */ |
| 2348 | int len) /* iso packet length */ | 2277 | int len) /* iso packet length */ |
| @@ -2409,6 +2338,9 @@ static const struct sd_desc sd_desc = { | |||
| 2409 | .stopN = sd_stopN, | 2338 | .stopN = sd_stopN, |
| 2410 | .stop0 = sd_stop0, | 2339 | .stop0 = sd_stop0, |
| 2411 | .pkt_scan = sd_pkt_scan, | 2340 | .pkt_scan = sd_pkt_scan, |
| 2341 | #ifdef CONFIG_INPUT | ||
| 2342 | .int_pkt_scan = sd_int_pkt_scan, | ||
| 2343 | #endif | ||
| 2412 | .dq_callback = sd_dqcallback, | 2344 | .dq_callback = sd_dqcallback, |
| 2413 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 2345 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 2414 | .set_register = sd_dbg_s_register, | 2346 | .set_register = sd_dbg_s_register, |
| @@ -2417,8 +2349,8 @@ static const struct sd_desc sd_desc = { | |||
| 2417 | .get_chip_ident = sd_chip_ident, | 2349 | .get_chip_ident = sd_chip_ident, |
| 2418 | }; | 2350 | }; |
| 2419 | 2351 | ||
| 2420 | #define SN9C20X(sensor, i2c_addr, button_mask) \ | 2352 | #define SN9C20X(sensor, i2c_addr, flags) \ |
| 2421 | .driver_info = (button_mask << 16) \ | 2353 | .driver_info = (flags << 16) \ |
| 2422 | | (SENSOR_ ## sensor << 8) \ | 2354 | | (SENSOR_ ## sensor << 8) \ |
| 2423 | | (i2c_addr) | 2355 | | (i2c_addr) |
| 2424 | 2356 | ||
| @@ -2426,7 +2358,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
| 2426 | {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, | 2358 | {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, |
| 2427 | {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, | 2359 | {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, |
| 2428 | {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, | 2360 | {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, |
| 2429 | {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, 0x10)}, | 2361 | {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, HAS_BUTTON)}, |
| 2430 | {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)}, | 2362 | {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 0)}, |
| 2431 | {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, | 2363 | {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, |
| 2432 | {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, | 2364 | {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, |
| @@ -2437,13 +2369,13 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
| 2437 | {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, | 2369 | {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, |
| 2438 | {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, | 2370 | {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, |
| 2439 | {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, | 2371 | {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, |
| 2440 | {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)}, | 2372 | {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, HAS_BUTTON)}, |
| 2441 | {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, | 2373 | {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, |
| 2442 | {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, | 2374 | {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, |
| 2443 | {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, | 2375 | {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, |
| 2444 | {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, | 2376 | {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, |
| 2445 | {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)}, | 2377 | {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)}, |
| 2446 | {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)}, | 2378 | {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, HAS_BUTTON)}, |
| 2447 | {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, | 2379 | {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, |
| 2448 | {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, | 2380 | {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, |
| 2449 | {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, | 2381 | {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, |
| @@ -2452,7 +2384,7 @@ static const __devinitdata struct usb_device_id device_table[] = { | |||
| 2452 | {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, | 2384 | {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, |
| 2453 | {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, | 2385 | {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, |
| 2454 | {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)}, | 2386 | {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)}, |
| 2455 | {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)}, | 2387 | {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, HAS_BUTTON)}, |
| 2456 | {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)}, | 2388 | {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)}, |
| 2457 | {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)}, | 2389 | {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)}, |
| 2458 | {} | 2390 | {} |
| @@ -2467,22 +2399,11 @@ static int sd_probe(struct usb_interface *intf, | |||
| 2467 | THIS_MODULE); | 2399 | THIS_MODULE); |
| 2468 | } | 2400 | } |
| 2469 | 2401 | ||
| 2470 | static void sd_disconnect(struct usb_interface *intf) | ||
| 2471 | { | ||
| 2472 | #ifdef CONFIG_USB_GSPCA_SN9C20X_EVDEV | ||
| 2473 | struct gspca_dev *gspca_dev = usb_get_intfdata(intf); | ||
| 2474 | |||
| 2475 | sn9c20x_input_cleanup(gspca_dev); | ||
| 2476 | #endif | ||
| 2477 | |||
| 2478 | gspca_disconnect(intf); | ||
| 2479 | } | ||
| 2480 | |||
| 2481 | static struct usb_driver sd_driver = { | 2402 | static struct usb_driver sd_driver = { |
| 2482 | .name = MODULE_NAME, | 2403 | .name = MODULE_NAME, |
| 2483 | .id_table = device_table, | 2404 | .id_table = device_table, |
| 2484 | .probe = sd_probe, | 2405 | .probe = sd_probe, |
| 2485 | .disconnect = sd_disconnect, | 2406 | .disconnect = gspca_disconnect, |
| 2486 | #ifdef CONFIG_PM | 2407 | #ifdef CONFIG_PM |
| 2487 | .suspend = gspca_suspend, | 2408 | .suspend = gspca_suspend, |
| 2488 | .resume = gspca_resume, | 2409 | .resume = gspca_resume, |
