From patchwork Mon Jul 3 09:16:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hugues FRUCHET X-Patchwork-Id: 9822357 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 99D9760237 for ; Mon, 3 Jul 2017 09:24:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 89D4828505 for ; Mon, 3 Jul 2017 09:24:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7AB5B2853F; Mon, 3 Jul 2017 09:24:50 +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=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C4CA128505 for ; Mon, 3 Jul 2017 09:24:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=aUVoCZbU+MbTzxHCA0KNPVXsQ2HC0kLMJZu/y2KfyzQ=; b=IPLVSmLgN2tJel T/v5gnWYOaWdQ0h9YwJvAlrGEcLEw6x0t0v/2yFLUrjiiahSxrR5RClk3D3UqE5KibSZi3ktaTY89 fGbJ0WahCry58ME6CTAkh/Ha5CWOCZ9vj6FlcGVcm6ONOh6XoYD9kyuhPP3jEWcT8HaazcA0Ptj4C 1OL9NIpuNcAwp+Zsxvz+sMPV836kUlKrUQ+92XbxzBKIoLsH4kDJgGqAlATRS/rQPTPphqP9MT7PO JXqZ6UnrxY57TlHC5w9oYBO5Axv1jdrUHUyW04IGdO8EsJE3h8wnPFsyEeWnO8WgaO0fH/6Ld59sX u9ZBzgRDaCXjWFvmDuDg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dRxb5-0003IB-9L; Mon, 03 Jul 2017 09:24:47 +0000 Received: from mx07-00178001.pphosted.com ([62.209.51.94]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dRxTT-0006Wa-27 for linux-arm-kernel@lists.infradead.org; Mon, 03 Jul 2017 09:16:57 +0000 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v6398Vvr012624; Mon, 3 Jul 2017 11:16:26 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-.pphosted.com with ESMTP id 2be16v2ryy-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Mon, 03 Jul 2017 11:16:26 +0200 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 59B8C31; Mon, 3 Jul 2017 09:16:25 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas23.st.com [10.75.90.46]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 2657E13AA; Mon, 3 Jul 2017 09:16:25 +0000 (GMT) Received: from localhost (10.201.23.73) by webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.339.0; Mon, 3 Jul 2017 11:16:24 +0200 From: Hugues Fruchet To: Sylwester Nawrocki , " H. Nikolaus Schaller" , Guennadi Liakhovetski , Rob Herring , Mark Rutland , Maxime Coquelin , Alexandre Torgue , Mauro Carvalho Chehab , Hans Verkuil Subject: [PATCH v2 3/7] [media] ov9650: add device tree support Date: Mon, 3 Jul 2017 11:16:04 +0200 Message-ID: <1499073368-31905-4-git-send-email-hugues.fruchet@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1499073368-31905-1-git-send-email-hugues.fruchet@st.com> References: <1499073368-31905-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-07-03_06:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170703_021655_556778_77D3B592 X-CRM114-Status: GOOD ( 20.15 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Yannick Fertre , Benjamin Gaignard , Hugues Fruchet , linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Allows use of device tree configuration data. If no device tree data is there, configuration is taken from platform data. In order to keep GPIOs configuration compatible between both way of doing, GPIOs are switched to descriptor-based interface. Signed-off-by: H. Nikolaus Schaller Signed-off-by: Hugues Fruchet --- drivers/media/i2c/Kconfig | 2 +- drivers/media/i2c/ov9650.c | 77 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 121b3b5..168115c 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -615,7 +615,7 @@ config VIDEO_OV7670 config VIDEO_OV9650 tristate "OmniVision OV9650/OV9652 sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on GPIOLIB && I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API ---help--- This is a V4L2 sensor-level driver for the Omnivision OV9650 and OV9652 camera sensors. diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c index 1e4e99e..7e9a902 100644 --- a/drivers/media/i2c/ov9650.c +++ b/drivers/media/i2c/ov9650.c @@ -11,12 +11,14 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include #include #include #include #include +#include #include #include #include @@ -249,9 +251,10 @@ struct ov965x { struct v4l2_subdev sd; struct media_pad pad; enum v4l2_mbus_type bus_type; - int gpios[NUM_GPIOS]; + struct gpio_desc *gpios[NUM_GPIOS]; /* External master clock frequency */ unsigned long mclk_frequency; + struct clk *clk; /* Protects the struct fields below */ struct mutex lock; @@ -511,10 +514,10 @@ static int ov965x_set_color_matrix(struct ov965x *ov965x) return 0; } -static void ov965x_gpio_set(int gpio, int val) +static void ov965x_gpio_set(struct gpio_desc *gpio, int val) { - if (gpio_is_valid(gpio)) - gpio_set_value(gpio, val); + if (gpio) + gpiod_set_value_cansleep(gpio, val); } static void __ov965x_set_power(struct ov965x *ov965x, int on) @@ -1406,24 +1409,28 @@ static int ov965x_configure_gpios(struct ov965x *ov965x, const struct ov9650_platform_data *pdata) { int ret, i; + int gpios[NUM_GPIOS]; - ov965x->gpios[GPIO_PWDN] = pdata->gpio_pwdn; - ov965x->gpios[GPIO_RST] = pdata->gpio_reset; + gpios[GPIO_PWDN] = pdata->gpio_pwdn; + gpios[GPIO_RST] = pdata->gpio_reset; - for (i = 0; i < ARRAY_SIZE(ov965x->gpios); i++) { - int gpio = ov965x->gpios[i]; + for (i = 0; i < ARRAY_SIZE(gpios); i++) { + int gpio = gpios[i]; if (!gpio_is_valid(gpio)) continue; ret = devm_gpio_request_one(&ov965x->client->dev, gpio, - GPIOF_OUT_INIT_HIGH, "OV965X"); - if (ret < 0) + GPIOF_OUT_INIT_HIGH, DRIVER_NAME); + if (ret < 0) { + dev_err(&ov965x->client->dev, + "Failed to request gpio%d (%d)\n", gpio, ret); return ret; + } v4l2_dbg(1, debug, &ov965x->sd, "set gpio %d to 1\n", gpio); gpio_set_value(gpio, 1); gpio_export(gpio, 0); - ov965x->gpios[i] = gpio; + ov965x->gpios[i] = gpio_to_desc(gpio); } return 0; @@ -1469,14 +1476,10 @@ static int ov965x_probe(struct i2c_client *client, struct v4l2_subdev *sd; struct ov965x *ov965x; int ret; + struct device_node *np = client->dev.of_node; - if (pdata == NULL) { - dev_err(&client->dev, "platform data not specified\n"); - return -EINVAL; - } - - if (pdata->mclk_frequency == 0) { - dev_err(&client->dev, "MCLK frequency not specified\n"); + if (!pdata && !np) { + dev_err(&client->dev, "Platform data or device tree data must be provided\n"); return -EINVAL; } @@ -1486,7 +1489,35 @@ static int ov965x_probe(struct i2c_client *client, mutex_init(&ov965x->lock); ov965x->client = client; - ov965x->mclk_frequency = pdata->mclk_frequency; + mutex_init(&ov965x->lock); + + if (np) { + /* Device tree */ + ov965x->gpios[GPIO_RST] = + devm_gpiod_get_optional(&client->dev, "resetb", + GPIOD_OUT_LOW); + ov965x->gpios[GPIO_PWDN] = + devm_gpiod_get_optional(&client->dev, "pwdn", + GPIOD_OUT_HIGH); + + ov965x->clk = devm_clk_get(&client->dev, NULL); + if (IS_ERR(ov965x->clk)) { + dev_err(&client->dev, "Could not get clock\n"); + return PTR_ERR(ov965x->clk); + } + ov965x->mclk_frequency = clk_get_rate(ov965x->clk); + } else { + /* Platform data */ + ret = ov965x_configure_gpios(ov965x, pdata); + if (ret < 0) + return ret; + + if (pdata->mclk_frequency == 0) { + dev_err(&client->dev, "MCLK frequency is mandatory\n"); + return -EINVAL; + } + ov965x->mclk_frequency = pdata->mclk_frequency; + } sd = &ov965x->sd; v4l2_i2c_subdev_init(sd, client, &ov965x_subdev_ops); @@ -1551,9 +1582,17 @@ static int ov965x_remove(struct i2c_client *client) }; MODULE_DEVICE_TABLE(i2c, ov965x_id); +static const struct of_device_id ov965x_of_match[] = { + { .compatible = "ovti,ov9650", }, + { .compatible = "ovti,ov9652", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ov965x_of_match); + static struct i2c_driver ov965x_i2c_driver = { .driver = { .name = DRIVER_NAME, + .of_match_table = of_match_ptr(ov965x_of_match), }, .probe = ov965x_probe, .remove = ov965x_remove,