From patchwork Tue Oct 13 05:49:27 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 1831 Return-path: Envelope-to: mchehab@infradead.org Delivery-date: Tue, 13 Oct 2009 05:53:53 +0000 Received: from bombadil.infradead.org [18.85.46.34] by pedra.chehab.org with IMAP (fetchmail-6.3.6) for (single-drop); Tue, 13 Oct 2009 16:49:20 -0300 (BRT) Received: from vger.kernel.org ([209.132.176.167]) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1MxaKW-0004PK-Oe; Tue, 13 Oct 2009 05:53:52 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755328AbZJMFuK (ORCPT + 1 other); Tue, 13 Oct 2009 01:50:10 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754886AbZJMFuK (ORCPT ); Tue, 13 Oct 2009 01:50:10 -0400 Received: from mail.renesas.com ([202.234.163.13]:59077 "EHLO mail03.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1755328AbZJMFuI (ORCPT ); Tue, 13 Oct 2009 01:50:08 -0400 X-AuditID: ac140386-0000000700003037-f5-4ad414e74872 Received: from guardian01.idc.renesas.com ([172.20.8.200]) by mail03.idc.renesas.com (sendmail) with ESMTP id n9D5nRH7015861; Tue, 13 Oct 2009 14:49:27 +0900 (JST) Received: (from root@localhost) by guardian01.idc.renesas.com with id n9D5nSP0011603; Tue, 13 Oct 2009 14:49:28 +0900 (JST) Received: from mta01.idc.renesas.com (localhost [127.0.0.1]) by mta01.idc.renesas.com with ESMTP id n9D5nQtT006585; Tue, 13 Oct 2009 14:49:26 +0900 (JST) Received: from PG10870.renesas.com ([172.30.8.159]) by ims05.idc.renesas.com (Sendmail) with ESMTPA id <0KRF00H31UUFSH@ims05.idc.renesas.com>; Tue, 13 Oct 2009 14:49:27 +0900 (JST) Date: Tue, 13 Oct 2009 14:49:27 +0900 From: Kuninori Morimoto Subject: [PATCH 3/5] soc-camera: tw9910: Add output pin control. To: Guennadi Liakhovetski Cc: Linux Media Mailing List Message-id: MIME-version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-type: text/plain; charset=US-ASCII User-Agent: SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?ISO-8859-4?Q?Goj=F2?=) APEL/10.7 Emacs/22.3 (i386-msvc-nt5.1.2600) MULE/5.0 (SAKAKI) Meadow/3.02-dev (RINDOU) (2009-06-17 Rev.4261) X-Brightmail-Tracker: AAAAAA== Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org tw9910 can select output pin width and vs/hs pin feature. This patch add new flags definition to control it. Signed-off-by: Kuninori Morimoto --- drivers/media/video/tw9910.c | 72 ++++++++++++++++-------------------------- include/media/tw9910.h | 21 +++++++++++- 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c index 8bda689..bdabc9a 100644 --- a/drivers/media/video/tw9910.c +++ b/drivers/media/video/tw9910.c @@ -201,12 +201,6 @@ /* * structure */ - -struct regval_list { - unsigned char reg_num; - unsigned char value; -}; - struct tw9910_scale_ctrl { char *name; unsigned short width; @@ -229,18 +223,6 @@ struct tw9910_priv { int rev; }; -/* - * register settings - */ - -#define ENDMARKER { 0xff, 0xff } - -static const struct regval_list tw9910_default_regs[] = -{ - { OUTCTR1, VSP_LO | VSSL_VVALID | HSP_HI | HSSL_HSYNC }, - ENDMARKER, -}; - static const struct soc_camera_data_format tw9910_color_fmt[] = { { .name = "VYUY", @@ -442,20 +424,6 @@ static int tw9910_set_hsync(struct i2c_client *client, return ret; } -static int tw9910_write_array(struct i2c_client *client, - const struct regval_list *vals) -{ - while (vals->reg_num != 0xff) { - int ret = i2c_smbus_write_byte_data(client, - vals->reg_num, - vals->value); - if (ret < 0) - return ret; - vals++; - } - return 0; -} - static int tw9910_mask_set(struct i2c_client *client, u8 command, u8 mask, u8 set) { @@ -469,6 +437,24 @@ static int tw9910_mask_set(struct i2c_client *client, u8 command, return i2c_smbus_write_byte_data(client, command, val); } +static int tw9910_set_outputcontrol(struct i2c_client *client) +{ + struct tw9910_priv *priv = to_tw9910(client); + u32 flags = priv->info->flags; + u8 val = 0; + + if (flags & TW9910_FLG_VS_ACTIVE_HIGH) + val |= (1 << 7); + + if (flags & TW9910_FLG_HS_ACTIVE_HIGH) + val |= (1 << 3); + + val |= ((flags & TW9910_FLG_VS_MASK) >> TW9910_FLG_VS_SHIFT) << 4; + val |= ((flags & TW9910_FLG_HS_MASK) >> TW9910_FLG_HS_SHIFT) << 0; + + return tw9910_mask_set(client, OUTCTR1, 0xff, val); +} + static void tw9910_reset(struct i2c_client *client) { i2c_smbus_write_byte_data(client, ACNTL1, SRESET); @@ -513,7 +499,7 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) { struct i2c_client *client = sd->priv; struct tw9910_priv *priv = to_tw9910(client); - u8 val; + u8 val = OEN; if (!enable) { switch (priv->rev) { @@ -556,7 +542,12 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) struct soc_camera_link *icl = to_soc_camera_link(icd); unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; + SOCAM_DATA_ACTIVE_HIGH; + + if (TW9910_FLG_DATAWIDTH_16 & priv->info->flags) + flags |= SOCAM_DATAWIDTH_16; + else + flags |= SOCAM_DATAWIDTH_8; return soc_camera_apply_sensor_flags(icl, flags); } @@ -648,7 +639,7 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) * reset hardware */ tw9910_reset(client); - ret = tw9910_write_array(client, tw9910_default_regs); + ret = tw9910_set_outputcontrol(client); if (ret < 0) goto tw9910_set_fmt_error; @@ -656,7 +647,7 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) * set bus width */ val = 0x00; - if (SOCAM_DATAWIDTH_16 == priv->info->buswidth) + if (TW9910_FLG_DATAWIDTH_16 & priv->info->flags) val = LEN; ret = tw9910_mask_set(client, OPFORM, LEN, val); @@ -888,15 +879,6 @@ static int tw9910_video_probe(struct soc_camera_device *icd, to_soc_camera_host(icd->dev.parent)->nr != icd->iface) return -ENODEV; - /* - * tw9910 only use 8 or 16 bit bus width - */ - if (SOCAM_DATAWIDTH_16 != priv->info->buswidth && - SOCAM_DATAWIDTH_8 != priv->info->buswidth) { - dev_err(&client->dev, "bus width error\n"); - return -ENODEV; - } - icd->formats = tw9910_color_fmt; icd->num_formats = ARRAY_SIZE(tw9910_color_fmt); diff --git a/include/media/tw9910.h b/include/media/tw9910.h index 6ddb654..494ac53 100644 --- a/include/media/tw9910.h +++ b/include/media/tw9910.h @@ -18,6 +18,25 @@ #include +#define TW9910_FLG_DATAWIDTH_16 (1 << 0) /* default 8 */ +#define TW9910_FLG_VS_ACTIVE_HIGH (1 << 1) /* default Low */ +#define TW9910_FLG_HS_ACTIVE_HIGH (1 << 2) /* default Low */ + +#define TW9910_FLG_VS_SHIFT (4) +#define TW9910_FLG_VS_MASK (0xF << TW9910_FLG_VS_SHIFT) +#define TW9910_FLG_VS_VSYNC (0 << TW9910_FLG_VS_SHIFT) +#define TW9910_FLG_VS_VACT (1 << TW9910_FLG_VS_SHIFT) +#define TW9910_FLG_VS_FIELD (2 << TW9910_FLG_VS_SHIFT) +#define TW9910_FLG_VS_VVALID (3 << TW9910_FLG_VS_SHIFT) + +#define TW9910_FLG_HS_SHIFT (8) +#define TW9910_FLG_HS_MASK (0xF << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_HACT (0 << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_HSYNC (1 << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_DVALID (2 << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_HLOCK (3 << TW9910_FLG_HS_SHIFT) +#define TW9910_FLG_HS_ASYNCW (4 << TW9910_FLG_HS_SHIFT) + enum tw9910_mpout_pin { TW9910_MPO_VLOSS, TW9910_MPO_HLOCK, @@ -30,7 +49,7 @@ enum tw9910_mpout_pin { }; struct tw9910_video_info { - unsigned long buswidth; + u32 flags; enum tw9910_mpout_pin mpout; struct soc_camera_link link; u16 start_offset;