From patchwork Fri Sep 4 05:15:07 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 45515 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n845DVKD021737 for ; Fri, 4 Sep 2009 05:15:20 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754885AbZIDFPQ (ORCPT ); Fri, 4 Sep 2009 01:15:16 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754993AbZIDFPQ (ORCPT ); Fri, 4 Sep 2009 01:15:16 -0400 Received: from mail-pz0-f190.google.com ([209.85.222.190]:44691 "EHLO mail-pz0-f190.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750999AbZIDFPO (ORCPT ); Fri, 4 Sep 2009 01:15:14 -0400 Received: by pzk28 with SMTP id 28so486222pzk.27 for ; Thu, 03 Sep 2009 22:15:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:date:from:to:cc:subject :mime-version:content-type:content-disposition:user-agent:message-id; bh=3ahn+sj+M8B0Ivdjoe6xxqh2hp13uH3OLx9bgkTj1CA=; b=ti+m0os/nTogLs6RrTF8VcDvM2fFWeYbet2qlyUFC4cVr0q98ARV1SwOihqGqlAuj4 kAmL02v+2qL9qkgEE+Xf2ZzUypWKKTGRDOSM91GM5gFQHtuYbbADLwOcj6K8HrkbXhyK hli7nhN0IRaCFJlelqYcZPm5EIpIIjZemBPso= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:mime-version:content-type :content-disposition:user-agent:message-id; b=HV0lcDa/07uv8iApdXWfrEm2Nd/sbaNEK72Cg8BoSF/ZDe3d3jjhQPzPm/UucfNyb2 mB4eoAJV08eb51JhZcClm7Qv1eGvZQqW2ogd1eK0oGKjA8gNNr5bt3f4q0ttOVG4oYTS SaFxTnj/Cx/YX0aEGRJJNZXLw+jGBNh98CNDw= Received: by 10.114.165.27 with SMTP id n27mr9367503wae.167.1252041311429; Thu, 03 Sep 2009 22:15:11 -0700 (PDT) Received: from mailhub.coreip.homeip.net (c-24-6-153-137.hsd1.ca.comcast.net [24.6.153.137]) by mx.google.com with ESMTPS id 21sm198060pxi.15.2009.09.03.22.15.10 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 03 Sep 2009 22:15:10 -0700 (PDT) Date: Thu, 3 Sep 2009 22:15:07 -0700 From: Dmitry Torokhov To: Mauro Carvalho Chehab Cc: Linux Media Mailing List Subject: [PATCH] DVB/V4L: ov511 - export snapshot button through input layer MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.19 (2009-01-05) Message-Id: <20090904054805.5C944526EA5@mailhub.coreip.homeip.net> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Bastien Nocera Register an input device with one button, and for the supported OV511 webcams, poll and check whether the snapshot button has been pressed on each new frame. [dtor@mail.ru: fix freeing of phys, plug into Kconfig, make compile] Signed-off-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- Mauro, This is something that's been sitting in my queue for quite some time, please consider applying. Thanks! drivers/media/video/Kconfig | 8 +++ drivers/media/video/ov511.c | 109 +++++++++++++++++++++++++++++++++++++++---- drivers/media/video/ov511.h | 8 +++ 3 files changed, 116 insertions(+), 9 deletions(-) diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index dcf9fa9..42573e0 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -888,6 +888,14 @@ config USB_OV511 To compile this driver as a module, choose M here: the module will be called ov511. +config USB_OV511_SNAPSHOT_BUTTON + bool "USB OV511 Snapshot Button support" + depends on USB_OV511 + depends on INPUT + ---help--- + Say Y here if you want the driver to report snapshot button through + input layer. + config USB_SE401 tristate "USB SE401 Camera support" depends on VIDEO_V4L1 diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 0bc2cf5..484165c 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -44,6 +44,8 @@ #include #include #include +#include +#include #if defined (__i386__) #include @@ -92,7 +94,7 @@ static int cams = 1; static int compress; static int testpat; static int dumppix; -static int led = 1; +static int led = 1; static int dump_bridge; static int dump_sensor; static int printph; @@ -352,6 +354,83 @@ rvfree(void *mem, unsigned long size) /********************************************************************** * + * Input device + * + **********************************************************************/ +#ifdef CONFIG_USB_OV511_SNAPSHOT_BUTTON + +static int ov511_input_init(struct usb_ov511 *ov) +{ + struct usb_device *udev = ov->dev; + struct input_dev *input; + int err = -ENOMEM; + + input = input_allocate_device(); + if (!input) + goto err_out; + + usb_make_path(udev, ov->key_phys, OV511_KEY_PHYS_SIZE); + strlcat(ov->key_phys, "/input0", OV511_KEY_PHYS_SIZE); + + input->name = "OV511 Snapshot Button"; + input->phys = ov->key_phys; + usb_to_input_id(udev, &input->id); + input->dev.parent = &udev->dev; + + __set_bit(EV_KEY, input->evbit); + __set_bit(KEY_CAMERA, input->keybit); + + err = input_register_device(input); + if (err) + goto err_out; + + ov->key_input = input; + return 0; + +err_out: + input_free_device(input); + return err; +} + +static void ov511_input_cleanup(struct usb_ov511 *ov) +{ + if (ov->key_input) { + input_unregister_device(ov->key_input); + ov->key_input = NULL; + } +} + +static void ov511_input_report_key(struct usb_ov511 *ov) +{ + struct input_dev *input = ov->key_input; + + if (input) { + input_report_key(input, KEY_CAMERA, 1); + input_sync(input); + input_report_key(input, KEY_CAMERA, 0); + input_sync(input); + } +} + +#else + +static inline int ov511_input_init(struct usb_ov511 *ov) +{ + return 0; +} + +static inline void ov511_input_cleanup(struct usb_ov511 *ov) +{ +} + +static inline void ov511_input_report_key(struct usb_ov511 *ov) +{ +} + +#endif /* CONFIG_USB_OV511_SNAPSHOT_BUTTON */ + +/********************************************************************** + * * Register I/O * **********************************************************************/ @@ -1105,7 +1184,6 @@ ov51x_clear_snapshot(struct usb_ov511 *ov) } } -#if 0 /* Checks the status of the snapshot button. Returns 1 if it was pressed since * it was last cleared, and zero in all other cases (including errors) */ static int @@ -1130,7 +1208,6 @@ ov51x_check_snapshot(struct usb_ov511 *ov) return status; } -#endif /* This does an initial reset of an OmniVision sensor and ensures that I2C * is synchronized. Returns <0 for failure. @@ -3149,10 +3226,10 @@ ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame) } /* Post-processes the specified frame. This consists of: - * 1. Decompress frame, if necessary + * 1. Decompress frame, if necessary * 2. Deinterlace frame and scale to proper size, if necessary - * 3. Convert from YUV planar to destination format, if necessary - * 4. Fix the RGB offset, if necessary + * 3. Convert from YUV planar to destination format, if necessary + * 4. Fix the RGB offset, if necessary */ static void ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame) @@ -4387,6 +4464,11 @@ redo: if ((ov->snap_enabled) && (frame->snapshot)) { frame->snapshot = 0; ov51x_clear_snapshot(ov); + } else if (!ov->snap_enabled && ov->bclass == BCL_OV511) { + if (ov51x_check_snapshot(ov) == 1) { + ov511_input_report_key(ov); + ov51x_clear_snapshot(ov); + } } /* Decompression, format conversion, etc... */ @@ -5237,7 +5319,7 @@ ov511_configure(struct usb_ov511 *ov) }; static struct ov511_regvals aRegvalsNorm511[] = { - { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 }, + { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 }, { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, @@ -5400,7 +5482,7 @@ ov518_configure(struct usb_ov511 *ov) static struct ov511_regvals aRegvalsNorm518[] = { { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */ - { OV511_REG_BUS, 0x31, 0x0f }, + { OV511_REG_BUS, 0x31, 0x0f }, { OV511_REG_BUS, 0x5d, 0x03 }, { OV511_REG_BUS, 0x24, 0x9f }, { OV511_REG_BUS, 0x25, 0x90 }, @@ -5413,7 +5495,7 @@ ov518_configure(struct usb_ov511 *ov) static struct ov511_regvals aRegvalsNorm518Plus[] = { { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */ - { OV511_REG_BUS, 0x31, 0x0f }, + { OV511_REG_BUS, 0x31, 0x0f }, { OV511_REG_BUS, 0x5d, 0x03 }, { OV511_REG_BUS, 0x24, 0x9f }, { OV511_REG_BUS, 0x25, 0x90 }, @@ -5880,6 +5962,13 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) mutex_lock(&ov->lock); + /* Snapshot is currently only supported on OV511, + * so no need to register the input device if it's not supported */ + if (!ov->snap_enabled && ov->bclass == BCL_OV511) { + if (ov511_input_init(ov) < 0) + dev_warn(&ov->dev->dev, "Could not register input device\n"); + } + return 0; error: @@ -5928,6 +6017,8 @@ ov51x_disconnect(struct usb_interface *intf) if (ov->vdev) video_unregister_device(ov->vdev); + ov511_input_cleanup(ov); + for (n = 0; n < OV511_NUMFRAMES; n++) ov->frame[n].grabstate = FRAME_ERROR; diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h index c450c92..7c0ade1 100644 --- a/drivers/media/video/ov511.h +++ b/drivers/media/video/ov511.h @@ -259,6 +259,9 @@ /* Size of usb_make_path() buffer */ #define OV511_USB_PATH_LEN 64 +/* Size of 'phys' field for the snapshot button input device */ +#define OV511_KEY_PHYS_SIZE 64 + /* Bridge types */ enum { BRG_UNKNOWN, @@ -469,6 +472,11 @@ struct usb_ov511 { int snap_enabled; /* Snapshot mode enabled */ +#ifdef CONFIG_USB_OV511_SNAPSHOT_BUTTON + struct input_dev *key_input; + char key_phys[OV511_KEY_PHYS_SIZE]; +#endif + int bridge; /* Type of bridge (BRG_*) */ int bclass; /* Class of bridge (BCL_*) */ int sensor; /* Type of image sensor chip (SEN_*) */