aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc/pwc-if.c
diff options
context:
space:
mode:
authorNam Phạm Thành <phamthanhnam.ptn@gmail.com>2009-01-12 00:50:17 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:22 -0400
commite32a7eccd7f016928dd864711ac654e6db62c5f3 (patch)
tree6eb71d883c91226c2f8dd0c7a6cc6a1c2c8e3c5f /drivers/media/video/pwc/pwc-if.c
parentbe4f4aecf8df39444535c9d9be2b74a8f34649b2 (diff)
V4L/DVB (10242): pwc: add support for webcam snapshot button
This patch adds support for Philips webcam snapshot button as an event input device, for consistency with other webcam drivers. Signed-off-by: Pham Thanh Nam <phamthanhnam.ptn@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pwc/pwc-if.c')
-rw-r--r--drivers/media/video/pwc/pwc-if.c77
1 files changed, 64 insertions, 13 deletions
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 0d810189dd87..a7c2e7284c20 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -53,6 +53,7 @@
53 - Xavier Roche: QuickCam Pro 4000 ID 53 - Xavier Roche: QuickCam Pro 4000 ID
54 - Jens Knudsen: QuickCam Zoom ID 54 - Jens Knudsen: QuickCam Zoom ID
55 - J. Debert: QuickCam for Notebooks ID 55 - J. Debert: QuickCam for Notebooks ID
56 - Pham Thanh Nam: webcam snapshot button as an event input device
56*/ 57*/
57 58
58#include <linux/errno.h> 59#include <linux/errno.h>
@@ -61,6 +62,9 @@
61#include <linux/module.h> 62#include <linux/module.h>
62#include <linux/poll.h> 63#include <linux/poll.h>
63#include <linux/slab.h> 64#include <linux/slab.h>
65#ifdef CONFIG_USB_PWC_INPUT_EVDEV
66#include <linux/usb/input.h>
67#endif
64#include <linux/vmalloc.h> 68#include <linux/vmalloc.h>
65#include <asm/io.h> 69#include <asm/io.h>
66 70
@@ -586,6 +590,23 @@ static void pwc_frame_dumped(struct pwc_device *pdev)
586 pdev->vframe_count); 590 pdev->vframe_count);
587} 591}
588 592
593static void pwc_snapshot_button(struct pwc_device *pdev, int down)
594{
595 if (down) {
596 PWC_TRACE("Snapshot button pressed.\n");
597 pdev->snapshot_button_status = 1;
598 } else {
599 PWC_TRACE("Snapshot button released.\n");
600 }
601
602#ifdef CONFIG_USB_PWC_INPUT_EVDEV
603 if (pdev->button_dev) {
604 input_report_key(pdev->button_dev, BTN_0, down);
605 input_sync(pdev->button_dev);
606 }
607#endif
608}
609
589static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf) 610static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf)
590{ 611{
591 int awake = 0; 612 int awake = 0;
@@ -603,13 +624,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
603 pdev->vframes_error++; 624 pdev->vframes_error++;
604 } 625 }
605 if ((ptr[0] ^ pdev->vmirror) & 0x01) { 626 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
606 if (ptr[0] & 0x01) { 627 pwc_snapshot_button(pdev, ptr[0] & 0x01);
607 pdev->snapshot_button_status = 1;
608 PWC_TRACE("Snapshot button pressed.\n");
609 }
610 else {
611 PWC_TRACE("Snapshot button released.\n");
612 }
613 } 628 }
614 if ((ptr[0] ^ pdev->vmirror) & 0x02) { 629 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
615 if (ptr[0] & 0x02) 630 if (ptr[0] & 0x02)
@@ -633,12 +648,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
633 else if (pdev->type == 740 || pdev->type == 720) { 648 else if (pdev->type == 740 || pdev->type == 720) {
634 unsigned char *ptr = (unsigned char *)fbuf->data; 649 unsigned char *ptr = (unsigned char *)fbuf->data;
635 if ((ptr[0] ^ pdev->vmirror) & 0x01) { 650 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
636 if (ptr[0] & 0x01) { 651 pwc_snapshot_button(pdev, ptr[0] & 0x01);
637 pdev->snapshot_button_status = 1;
638 PWC_TRACE("Snapshot button pressed.\n");
639 }
640 else
641 PWC_TRACE("Snapshot button released.\n");
642 } 652 }
643 pdev->vmirror = ptr[0] & 0x03; 653 pdev->vmirror = ptr[0] & 0x03;
644 } 654 }
@@ -1216,6 +1226,15 @@ static void pwc_cleanup(struct pwc_device *pdev)
1216{ 1226{
1217 pwc_remove_sysfs_files(pdev->vdev); 1227 pwc_remove_sysfs_files(pdev->vdev);
1218 video_unregister_device(pdev->vdev); 1228 video_unregister_device(pdev->vdev);
1229
1230#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1231 if (pdev->button_dev) {
1232 input_unregister_device(pdev->button_dev);
1233 input_free_device(pdev->button_dev);
1234 kfree(pdev->button_dev->phys);
1235 pdev->button_dev = NULL;
1236 }
1237#endif
1219} 1238}
1220 1239
1221/* Note that all cleanup is done in the reverse order as in _open */ 1240/* Note that all cleanup is done in the reverse order as in _open */
@@ -1483,6 +1502,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1483 int features = 0; 1502 int features = 0;
1484 int video_nr = -1; /* default: use next available device */ 1503 int video_nr = -1; /* default: use next available device */
1485 char serial_number[30], *name; 1504 char serial_number[30], *name;
1505#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1506 char *phys = NULL;
1507#endif
1486 1508
1487 vendor_id = le16_to_cpu(udev->descriptor.idVendor); 1509 vendor_id = le16_to_cpu(udev->descriptor.idVendor);
1488 product_id = le16_to_cpu(udev->descriptor.idProduct); 1510 product_id = le16_to_cpu(udev->descriptor.idProduct);
@@ -1807,6 +1829,35 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1807 pwc_set_leds(pdev, 0, 0); 1829 pwc_set_leds(pdev, 0, 0);
1808 pwc_camera_power(pdev, 0); 1830 pwc_camera_power(pdev, 0);
1809 1831
1832#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1833 /* register webcam snapshot button input device */
1834 pdev->button_dev = input_allocate_device();
1835 if (!pdev->button_dev) {
1836 PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
1837 return -ENOMEM;
1838 }
1839
1840 pdev->button_dev->name = "PWC snapshot button";
1841 phys = kasprintf(GFP_KERNEL,"usb-%s-%s", pdev->udev->bus->bus_name, pdev->udev->devpath);
1842 if (!phys) {
1843 input_free_device(pdev->button_dev);
1844 return -ENOMEM;
1845 }
1846 pdev->button_dev->phys = phys;
1847 usb_to_input_id(pdev->udev, &pdev->button_dev->id);
1848 pdev->button_dev->dev.parent = &pdev->udev->dev;
1849 pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
1850 pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
1851
1852 rc = input_register_device(pdev->button_dev);
1853 if (rc) {
1854 input_free_device(pdev->button_dev);
1855 kfree(pdev->button_dev->phys);
1856 pdev->button_dev = NULL;
1857 return rc;
1858 }
1859#endif
1860
1810 return 0; 1861 return 0;
1811 1862
1812err_unreg: 1863err_unreg: