aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
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
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')
-rw-r--r--drivers/media/video/pwc/Kconfig10
-rw-r--r--drivers/media/video/pwc/pwc-if.c77
-rw-r--r--drivers/media/video/pwc/pwc.h6
3 files changed, 80 insertions, 13 deletions
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 7298cf2e1650..8b9f0aa844a1 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -35,3 +35,13 @@ config USB_PWC_DEBUG
35 Say Y here in order to have the pwc driver generate verbose debugging 35 Say Y here in order to have the pwc driver generate verbose debugging
36 messages. 36 messages.
37 A special module options 'trace' is used to control the verbosity. 37 A special module options 'trace' is used to control the verbosity.
38
39config USB_PWC_INPUT_EVDEV
40 bool "USB Philips Cameras input events device support"
41 default y
42 depends on USB_PWC && INPUT
43 ---help---
44 This option makes USB Philips cameras register the snapshot button as
45 an input device to report button events.
46
47 If you are in doubt, say Y.
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:
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 01411fb2337a..0be6f814f539 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -37,6 +37,9 @@
37#include <linux/videodev.h> 37#include <linux/videodev.h>
38#include <media/v4l2-common.h> 38#include <media/v4l2-common.h>
39#include <media/v4l2-ioctl.h> 39#include <media/v4l2-ioctl.h>
40#ifdef CONFIG_USB_PWC_INPUT_EVDEV
41#include <linux/input.h>
42#endif
40 43
41#include "pwc-uncompress.h" 44#include "pwc-uncompress.h"
42#include <media/pwc-ioctl.h> 45#include <media/pwc-ioctl.h>
@@ -255,6 +258,9 @@ struct pwc_device
255 int pan_angle; /* in degrees * 100 */ 258 int pan_angle; /* in degrees * 100 */
256 int tilt_angle; /* absolute angle; 0,0 is home position */ 259 int tilt_angle; /* absolute angle; 0,0 is home position */
257 int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */ 260 int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */
261#ifdef CONFIG_USB_PWC_INPUT_EVDEV
262 struct input_dev *button_dev; /* webcam snapshot button input */
263#endif
258 264
259 /*** Misc. data ***/ 265 /*** Misc. data ***/
260 wait_queue_head_t frameq; /* When waiting for a frame to finish... */ 266 wait_queue_head_t frameq; /* When waiting for a frame to finish... */