From patchwork Mon Apr 23 13:21:07 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Ospite X-Patchwork-Id: 10825 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1SMJD0-00086O-4c for patchwork@linuxtv.org; Mon, 23 Apr 2012 15:21:38 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.75/mailfrontend-3) with esmtp for id 1SMJCz-0000Hc-En; Mon, 23 Apr 2012 15:21:38 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754991Ab2DWNVf (ORCPT ); Mon, 23 Apr 2012 09:21:35 -0400 Received: from smtp205.alice.it ([82.57.200.101]:47068 "EHLO smtp205.alice.it" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753778Ab2DWNVe (ORCPT ); Mon, 23 Apr 2012 09:21:34 -0400 Received: from jcn (79.2.146.32) by smtp205.alice.it (8.6.023.02) id 4F421F7B072DA9B1; Mon, 23 Apr 2012 15:21:31 +0200 Received: from ao2 by jcn with local (Exim 4.77) (envelope-from ) id 1SMJCo-0007HL-EL; Mon, 23 Apr 2012 15:21:26 +0200 From: Antonio Ospite To: linux-media@vger.kernel.org Cc: Antonio Ospite , Jean-Francois Moine , linux-input@vger.kernel.org, Dmitry Torokhov , Johann Deneux , Anssi Hannula , Jonathan Corbet Subject: [PATCH 3/3] [media] gspca - ov534: Add Hue control Date: Mon, 23 Apr 2012 15:21:07 +0200 Message-Id: <1335187267-27940-4-git-send-email-ospite@studenti.unina.it> X-Mailer: git-send-email 1.7.10 In-Reply-To: <1335187267-27940-1-git-send-email-ospite@studenti.unina.it> References: <1335187267-27940-1-git-send-email-ospite@studenti.unina.it> X-Face: z*RaLf`X<@C75u6Ig9}{oW$H; 1_\2t5)({*|jhM/Vb; ]yA5\I~93>J<_`<4)A{':UrE Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2012.4.23.125720 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, BODY_SIZE_3000_3999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_MEDIA_BODY 0, __CP_URI_IN_BODY 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __MIME_TEXT_ONLY 0, __MULTIPLE_RCPTS_CC_X2 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS ' Signed-off-by: Antonio Ospite --- drivers/media/video/gspca/ov534.c | 61 ++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 45139b5..1a437b5 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -34,6 +34,8 @@ #include "gspca.h" +#include + #define OV534_REG_ADDRESS 0xf1 /* sensor address */ #define OV534_REG_SUBADDR 0xf2 #define OV534_REG_WRITE 0xf3 @@ -53,6 +55,7 @@ MODULE_LICENSE("GPL"); /* controls */ enum e_ctrl { + HUE, SATURATION, BRIGHTNESS, CONTRAST, @@ -88,6 +91,7 @@ enum sensors { }; /* V4L2 controls supported by the driver */ +static void sethue(struct gspca_dev *gspca_dev); static void setsaturation(struct gspca_dev *gspca_dev); static void setbrightness(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev); @@ -105,6 +109,18 @@ static int sd_start(struct gspca_dev *gspca_dev); static void sd_stopN(struct gspca_dev *gspca_dev); static const struct ctrl sd_ctrls[] = { +[HUE] = { + { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = -90, + .maximum = 90, + .step = 1, + .default_value = 0, + }, + .set_control = sethue + }, [SATURATION] = { { .id = V4L2_CID_SATURATION, @@ -698,7 +714,7 @@ static const u8 sensor_init_772x[][2] = { { 0x9c, 0x20 }, { 0x9e, 0x81 }, - { 0xa6, 0x06 }, + { 0xa6, 0x07 }, { 0x7e, 0x0c }, { 0x7f, 0x16 }, { 0x80, 0x2a }, @@ -969,6 +985,48 @@ static void set_frame_rate(struct gspca_dev *gspca_dev) PDEBUG(D_PROBE, "frame_rate: %d", r->fps); } +static void sethue(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int val; + + val = sd->ctrls[HUE].val; + if (sd->sensor == SENSOR_OV767x) { + /* TBD */ + } else { + s16 huesin; + s16 huecos; + + /* fixp_sin and fixp_cos accept only positive values, while + * our val is between -90 and 90 + */ + val += 360; + + /* According to the datasheet the registers expect HUESIN and + * HUECOS to be the result of the trigonometric functions, + * scaled by 0x80. + * + * The 0x100 here represents the maximun absolute value + * returned byt fixp_sin and fixp_cos, so the scaling will + * consider the result like in the interval [-1.0, 1.0]. + */ + huesin = fixp_sin(val) * 0x80 / 0x100; + huecos = fixp_cos(val) * 0x80 / 0x100; + + if (huesin < 0) { + sccb_reg_write(gspca_dev, 0xab, + sccb_reg_read(gspca_dev, 0xab) | 0x2); + huesin = -huesin; + } else { + sccb_reg_write(gspca_dev, 0xab, + sccb_reg_read(gspca_dev, 0xab) & ~0x2); + + } + sccb_reg_write(gspca_dev, 0xa9, (u8)huecos); + sccb_reg_write(gspca_dev, 0xaa, (u8)huesin); + } +} + static void setsaturation(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -1337,6 +1395,7 @@ static int sd_start(struct gspca_dev *gspca_dev) if (!(gspca_dev->ctrl_dis & (1 << GAIN))) setgain(gspca_dev); setexposure(gspca_dev); + sethue(gspca_dev); setsaturation(gspca_dev); setbrightness(gspca_dev); setcontrast(gspca_dev);