From patchwork Wed Nov 29 17:11:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hugues FRUCHET X-Patchwork-Id: 10082861 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 663E26020B for ; Wed, 29 Nov 2017 17:12:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E41229A74 for ; Wed, 29 Nov 2017 17:12:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4312329B8E; Wed, 29 Nov 2017 17:12:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D214B29B9A for ; Wed, 29 Nov 2017 17:12:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933724AbdK2RL7 (ORCPT ); Wed, 29 Nov 2017 12:11:59 -0500 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:54312 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932649AbdK2RL7 (ORCPT ); Wed, 29 Nov 2017 12:11:59 -0500 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vATH9Qn3001243; Wed, 29 Nov 2017 18:11:32 +0100 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2ef09he0aj-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 29 Nov 2017 18:11:32 +0100 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id E001934; Wed, 29 Nov 2017 17:11:31 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas24.st.com [10.75.90.94]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 8EB9D53F7; Wed, 29 Nov 2017 17:11:31 +0000 (GMT) Received: from SAFEX1HUBCAS22.st.com (10.75.90.93) by Safex1hubcas24.st.com (10.75.90.94) with Microsoft SMTP Server (TLS) id 14.3.352.0; Wed, 29 Nov 2017 18:11:31 +0100 Received: from localhost (10.201.23.73) by Webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.352.0; Wed, 29 Nov 2017 18:11:30 +0100 From: Hugues Fruchet To: Steve Longerbeam , Sakari Ailus , Hans Verkuil , "Mauro Carvalho Chehab" CC: , Hugues Fruchet , Benjamin Gaignard Subject: [PATCH v2 3/4] media: ov5640: add support of DVP parallel interface Date: Wed, 29 Nov 2017 18:11:11 +0100 Message-ID: <1511975472-26659-4-git-send-email-hugues.fruchet@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1511975472-26659-1-git-send-email-hugues.fruchet@st.com> References: <1511975472-26659-1-git-send-email-hugues.fruchet@st.com> MIME-Version: 1.0 X-Originating-IP: [10.201.23.73] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-11-29_06:, , signatures=0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add support of DVP parallel mode in addition of existing MIPI CSI mode. The choice between two modes and configuration is made through device tree. Signed-off-by: Hugues Fruchet --- drivers/media/i2c/ov5640.c | 101 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 18 deletions(-) diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c index a576d11..826b102 100644 --- a/drivers/media/i2c/ov5640.c +++ b/drivers/media/i2c/ov5640.c @@ -34,14 +34,20 @@ #define OV5640_DEFAULT_SLAVE_ID 0x3c +#define OV5640_REG_SYS_CTRL0 0x3008 #define OV5640_REG_CHIP_ID_HIGH 0x300a #define OV5640_REG_CHIP_ID_LOW 0x300b +#define OV5640_REG_IO_MIPI_CTRL00 0x300e +#define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017 +#define OV5640_REG_PAD_OUTPUT_ENABLE02 0x3018 #define OV5640_REG_PAD_OUTPUT00 0x3019 +#define OV5640_REG_SYSTEM_CONTROL1 0x302e #define OV5640_REG_SC_PLL_CTRL0 0x3034 #define OV5640_REG_SC_PLL_CTRL1 0x3035 #define OV5640_REG_SC_PLL_CTRL2 0x3036 #define OV5640_REG_SC_PLL_CTRL3 0x3037 #define OV5640_REG_SLAVE_ID 0x3100 +#define OV5640_REG_SCCB_SYS_CTRL1 0x3103 #define OV5640_REG_SYS_ROOT_DIVIDER 0x3108 #define OV5640_REG_AWB_R_GAIN 0x3400 #define OV5640_REG_AWB_G_GAIN 0x3402 @@ -1006,7 +1012,65 @@ static int ov5640_get_gain(struct ov5640_dev *sensor) return gain & 0x3ff; } -static int ov5640_set_stream(struct ov5640_dev *sensor, bool on) +static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on) +{ + int ret; + + if (on) { + /* + * reset MIPI PCLK/SERCLK divider + * + * SC PLL CONTRL1 0 + * - [3..0]: MIPI PCLK/SERCLK divider + */ + ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1, 0xF, 0); + if (ret) + return ret; + } + + /* + * powerdown MIPI TX/RX PHY & disable MIPI + * + * MIPI CONTROL 00 + * 4: PWDN PHY TX + * 3: PWDN PHY RX + * 2: MIPI enable + */ + ret = ov5640_write_reg(sensor, + OV5640_REG_IO_MIPI_CTRL00, on ? 0x18 : 0); + if (ret) + return ret; + + /* + * enable VSYNC/HREF/PCLK DVP control lines + * & D[9:6] DVP data lines + * + * PAD OUTPUT ENABLE 01 + * - 6: VSYNC output enable + * - 5: HREF output enable + * - 4: PCLK output enable + * - [3:0]: D[9:6] output enable + */ + ret = ov5640_write_reg(sensor, + OV5640_REG_PAD_OUTPUT_ENABLE01, on ? 0x7f : 0); + if (ret) + return ret; + + /* + * enable D[5:2] DVP data lines (D[0:1] are unused with 8 bits + * parallel mode, 8 bits output are mapped on D[9:2]) + * + * PAD OUTPUT ENABLE 02 + * - [7:4]: D[5:2] output enable + * 0:1 are unused with 8 bits + * parallel mode (8 bits output + * are on D[9:2]) + */ + return ov5640_write_reg(sensor, + OV5640_REG_PAD_OUTPUT_ENABLE02, on ? 0xf0 : 0); +} + +static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on) { int ret; @@ -1598,17 +1662,19 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on) if (ret) goto power_off; - /* - * start streaming briefly followed by stream off in - * order to coax the clock lane into LP-11 state. - */ - ret = ov5640_set_stream(sensor, true); - if (ret) - goto power_off; - usleep_range(1000, 2000); - ret = ov5640_set_stream(sensor, false); - if (ret) - goto power_off; + if (sensor->ep.bus_type == V4L2_MBUS_CSI2) { + /* + * start streaming briefly followed by stream off in + * order to coax the clock lane into LP-11 state. + */ + ret = ov5640_set_stream_mipi(sensor, true); + if (ret) + goto power_off; + usleep_range(1000, 2000); + ret = ov5640_set_stream_mipi(sensor, false); + if (ret) + goto power_off; + } return 0; } @@ -2185,7 +2251,11 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable) goto out; } - ret = ov5640_set_stream(sensor, enable); + if (sensor->ep.bus_type == V4L2_MBUS_CSI2) + ret = ov5640_set_stream_mipi(sensor, enable); + else + ret = ov5640_set_stream_dvp(sensor, enable); + if (!ret) sensor->streaming = enable; } @@ -2270,11 +2340,6 @@ static int ov5640_probe(struct i2c_client *client, return ret; } - if (sensor->ep.bus_type != V4L2_MBUS_CSI2) { - dev_err(dev, "invalid bus type, must be MIPI CSI2\n"); - return -EINVAL; - } - /* get system clock (xclk) */ sensor->xclk = devm_clk_get(dev, "xclk"); if (IS_ERR(sensor->xclk)) {