From patchwork Sun Feb 28 07:55:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TsODwqltZXRoIE3Dg8KhcnRvbg==?= X-Patchwork-Id: 82774 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o1S7tFV3026911 for ; Sun, 28 Feb 2010 07:55:15 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1031474Ab0B1HzN (ORCPT ); Sun, 28 Feb 2010 02:55:13 -0500 Received: from relay01.digicable.hu ([92.249.128.189]:58539 "EHLO relay01.digicable.hu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031462Ab0B1HzM (ORCPT ); Sun, 28 Feb 2010 02:55:12 -0500 Received: from [94.21.195.14] by relay01.digicable.hu with esmtpa id 1Nldzb-0001nQ-AB ; Sun, 28 Feb 2010 08:55:11 +0100 Message-ID: <4B8A215D.2070402@freemail.hu> Date: Sun, 28 Feb 2010 08:55:09 +0100 From: =?UTF-8?B?TsOpbWV0aCBNw6FydG9u?= User-Agent: Mozilla/5.0 (X11; U; Linux i686; hu-HU; rv:1.8.1.21) Gecko/20090402 SeaMonkey/1.1.16 MIME-Version: 1.0 To: Hans de Goede , Jean-Francois Moine CC: V4L Mailing List Subject: [PATCH 2/3] gspca pac7302: add LED control X-Original: 94.21.195.14 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sun, 28 Feb 2010 07:55:15 +0000 (UTC) diff -r d8fafa7d88dc linux/drivers/media/video/gspca/pac7302.c --- a/linux/drivers/media/video/gspca/pac7302.c Thu Feb 18 19:02:51 2010 +0100 +++ b/linux/drivers/media/video/gspca/pac7302.c Sun Feb 28 08:41:17 2010 +0100 @@ -6,6 +6,7 @@ * * Separated from Pixart PAC7311 library by Márton Németh * Camera button input handling by Márton Németh + * LED control by Márton Németh * Copyright (C) 2009-2010 Márton Németh * * This program is free software; you can redistribute it and/or modify @@ -62,6 +63,7 @@ 0 | 0xc6 | setwhitebalance() 0 | 0xc7 | setbluebalance() 0 | 0xdc | setbrightcont(), setcolors() + 1 | 0x78 | set_streaming_led() 3 | 0x02 | setexposure() 3 | 0x10 | setgain() 3 | 0x11 | setcolors(), setgain(), setexposure(), sethvflip() @@ -91,6 +93,7 @@ unsigned char gain; unsigned char exposure; unsigned char autogain; + unsigned char led; __u8 hflip; __u8 vflip; u8 flags; @@ -126,6 +129,8 @@ static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setled(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getled(struct gspca_dev *gspca_dev, __s32 *val); static const struct ctrl sd_ctrls[] = { /* This control is pac7302 only */ @@ -293,6 +298,20 @@ .set = sd_setvflip, .get = sd_getvflip, }, + { + { + .id = V4L2_CID_LED, + .type = V4L2_CTRL_TYPE_MENU, + .name = "LED", + .minimum = 0, + .maximum = 2, /* 0: Auto, 1: On, 2: Off */ + .step = 1, +#define LED_DEF V4L2_LED_AUTO + .default_value = LED_DEF, + }, + .set = sd_setled, + .get = sd_getled, + }, }; static const struct v4l2_pix_format vga_mode[] = { @@ -572,6 +591,7 @@ sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; sd->autogain = AUTOGAIN_DEF; + sd->led = LED_DEF; sd->hflip = HFLIP_DEF; sd->vflip = VFLIP_DEF; sd->flags = id->driver_info; @@ -716,6 +736,36 @@ reg_w(gspca_dev, 0x11, 0x01); } +static void set_streaming_led(struct gspca_dev *gspca_dev, u8 streaming) +{ + struct sd *sd = (struct sd *) gspca_dev; + u8 data = 0; + + switch (sd->led) { + case V4L2_LED_AUTO: + if (streaming) + data = 0x01; + else + data = 0x40; + break; + case V4L2_LED_ON: + if (streaming) + data = 0x01; + else + data = 0x00; + break; + case V4L2_LED_OFF: + if (streaming) + data = 0x41; + else + data = 0x40; + break; + } + + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x78, data); +} + /* this function is called at probe and resume time for pac7302 */ static int sd_init(struct gspca_dev *gspca_dev) { @@ -747,18 +797,15 @@ atomic_set(&sd->avg_lum, -1); /* start stream */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x01); + set_streaming_led(gspca_dev, 1); return gspca_dev->usb_err; } static void sd_stopN(struct gspca_dev *gspca_dev) { - /* stop stream */ - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x00); + set_streaming_led(gspca_dev, 0); } /* called on streamoff with alt 0 and on disconnect for pac7302 */ @@ -766,8 +813,7 @@ { if (!gspca_dev->present) return; - reg_w(gspca_dev, 0xff, 0x01); - reg_w(gspca_dev, 0x78, 0x40); + set_streaming_led(gspca_dev, 0); } /* Include pac common sof detection functions */ @@ -1121,6 +1167,44 @@ return 0; } +static int sd_setled(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->led = val; + set_streaming_led(gspca_dev, gspca_dev->streaming); + return gspca_dev->usb_err; +} + +static int sd_getled(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->led; + return 0; +} + +static int sd_querymenu(struct gspca_dev *gspca_dev, + struct v4l2_querymenu *menu) +{ + switch (menu->id) { + case V4L2_CID_LED: + switch (menu->index) { + case V4L2_LED_AUTO: + strcpy((char *)menu->name, "Auto"); + return 0; + case V4L2_LED_OFF: + strcpy((char *)menu->name, "Off"); + return 0; + case V4L2_LED_ON: + strcpy((char *)menu->name, "On"); + return 0; + } + break; + } + return -EINVAL; +} + #ifdef CONFIG_VIDEO_ADV_DEBUG static int sd_dbg_s_register(struct gspca_dev *gspca_dev, struct v4l2_dbg_register *reg) @@ -1210,6 +1294,7 @@ .stop0 = sd_stop0, .pkt_scan = sd_pkt_scan, .dq_callback = do_autogain, + .querymenu = sd_querymenu, #ifdef CONFIG_VIDEO_ADV_DEBUG .set_register = sd_dbg_s_register, .get_chip_ident = sd_chip_ident,