From patchwork Fri Jun 2 23:44:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Hilman X-Patchwork-Id: 9763691 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 19DF460360 for ; Fri, 2 Jun 2017 23:45:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0AC072857B for ; Fri, 2 Jun 2017 23:45:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F25C4285DC; Fri, 2 Jun 2017 23:45:18 +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=ham 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 4DC5F2857B for ; Fri, 2 Jun 2017 23:45:18 +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=tpx/+OyZdjC8chT9c/1a0ajH24V/+XPWjhWbBTFBqyY=; b=aA5FlXEkhVABsj V2FujrcwdaC/isRLtyRLZ/Twk8r1tOYv1rU71zbnjFvXoeeC7sUrnboatZhMHUA3De03nTdCx+OrW Tf6cCNkZnhkjzjPaI1qqoBVup8FxirimPmF7voqX7lT6HQfMQzohqZebSRT8qsQex33DDm/8jNzLb BCkVhffvJA/jlAjW0y72DjG1kFXXPDtGevFAqTE716Xx0Q1S3utW4N4ObeU3jgDob2bbJTIcn6IIw n1IEZoRk4OBqga+9265wz+oeoadMreTxnka/ewTiMDNHPhWtNKl6pDeygESFhF9v8RCViyBpyW9xv PRxa26OalFacCgguNUbA==; 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 1dGwFo-0001vv-5y; Fri, 02 Jun 2017 23:45:16 +0000 Received: from mail-pg0-x22f.google.com ([2607:f8b0:400e:c05::22f]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dGwFK-0008HU-Cp for linux-arm-kernel@lists.infradead.org; Fri, 02 Jun 2017 23:44:51 +0000 Received: by mail-pg0-x22f.google.com with SMTP id t185so1625919pgd.1 for ; Fri, 02 Jun 2017 16:44:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=H4m9O34XRMvgp6koXGGwBs8Z8lynvhprg1V0GXZwGt8=; b=jWA9bC6xFqJcqmUDOnBKDRpMy8mKwgRyRcuawkREgqtPZ8lZ88wqXAPR/beblMx4Mv QMgpUTAk/mdoLFAyLmRWTDw0rvMJaxIJapppPzeMqtXgIIquPC7ueW3F5lvC78IWJsWC Lcd11BGNlZVDd2/AE+gnWpSL8joh50us1YKan/S7ytYSQmRulLa78BiM8ShL9hARKXJb Sm+crBWnMxaLn92Iypr1aDVTd4vqYfj627OWaLbBFuUt3ztPx/JR97yz6WQ7iP8br6MT THVVY+IVEQ1ft+2nJis71Q18rbdTUEWr7lpjrNEhUrZNclrQNX/a+QsHbFPkBVX+XWrq QGkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=H4m9O34XRMvgp6koXGGwBs8Z8lynvhprg1V0GXZwGt8=; b=bXmd/5pTtFpZpu4roIZnjgfJ5xPdg2ZPQ2EbZ01G9cFA/4U1ijiNt2exGjcMDJUcTi oqccvl21DPsVR6WRKlIWZMGetgK4z7mhMOrJtfbPs2+Buz17vkBQ9LSLJ4cIJpPwAi4C NEL5eJtV57eLbiEiPf4L7rtfr2TrNVkKFmUbPeyKOgX1FnSN8ULYC0j3wimX6HtbHCjJ LUxrv3oMdXP9A9N+ttdQFPCWGn0Q0X8DEP3WTAGXvns3nED0frd5A8LuYuq2rqb87nvB cSnwGG3oTjkZKT4fgyrtlTqaYqQGFqxUppqZKBICkgLt/a39mEhl0tOFprp4WuKHHbw/ cd8g== X-Gm-Message-State: AODbwcCGG8Gt3iE4LYpLuJf1UK0blriQR325fr490uJkgD94RI7QiFg9 RGUcfDqPkbNFaEWq X-Received: by 10.99.153.26 with SMTP id d26mr8089952pge.133.1496447065762; Fri, 02 Jun 2017 16:44:25 -0700 (PDT) Received: from localhost (c-98-203-232-209.hsd1.wa.comcast.net. [98.203.232.209]) by smtp.gmail.com with ESMTPSA id x12sm40335153pgc.47.2017.06.02.16.44.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Jun 2017 16:44:25 -0700 (PDT) From: Kevin Hilman To: Sekhar Nori Subject: [PATCH/RFT 3/3] HACK: ARM: davinci: add cdce913 clock controller Date: Fri, 2 Jun 2017 16:44:01 -0700 Message-Id: <20170602234401.24721-4-khilman@baylibre.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170602234401.24721-1-khilman@baylibre.com> References: <20170602234401.24721-1-khilman@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170602_164447_739867_15601009 X-CRM114-Status: GOOD ( 21.62 ) 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: linux-arm-kernel@lists.infradead.org, David Lechner , Patrick Titiano 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 The da850-evm UI board has a ti,cdce913 clock controller with a 27MHz crystal to provide the master clock to the camera connector. While there is an upstream driver for the ti,cdce913, it is CCF only, and since davinci does not currently support CCF, an alternate driver is needed to make camera sensors that depend on the clock API to work correctly. Note that the current driver is very dumb and doesn't even implement .set_rate, because the default, power-on defaults are sufficient to provide the 27 MHz clock expected by the aptina,mt9v032 which was used for testing. --- arch/arm/mach-davinci/Makefile | 2 +- arch/arm/mach-davinci/cdce913.c | 164 +++++++++++++++++++++++++++++++++++ arch/arm/mach-davinci/pdata-quirks.c | 8 +- 3 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-davinci/cdce913.c diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index df96ca9eab6d..c91e3a323488 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_AINTC) += irq.o obj-$(CONFIG_CP_INTC) += cp_intc.o # Board specific -obj-$(CONFIG_MACH_DA8XX_DT) += da8xx-dt.o pdata-quirks.o +obj-$(CONFIG_MACH_DA8XX_DT) += da8xx-dt.o pdata-quirks.o cdce913.o obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o diff --git a/arch/arm/mach-davinci/cdce913.c b/arch/arm/mach-davinci/cdce913.c new file mode 100644 index 000000000000..ef306707f283 --- /dev/null +++ b/arch/arm/mach-davinci/cdce913.c @@ -0,0 +1,164 @@ +#include +#include +#include + +#include +#include +#include "clock.h" + +static struct i2c_client *cdce913; + +static void cdce_enable(struct clk *clk) +{ + pr_debug("%s: %s\n", __func__, clk->name); + return; +} + +static void cdce_disable(struct clk *clk) +{ + pr_debug("%s: %s\n", __func__, clk->name); + return; +} + +int cdce_set_rate(struct clk *clk, unsigned long rate) +{ + WARN_ON(!cdce913); + pr_warn("%s: %s: rate = %lu; WARNING not implemented\n", + __func__, clk->name, rate); + return 0; +} + +#define CAMERA_XTAL_FREQ 27000000 + +static struct clk cdce913_clk = { + .name = "cdce913", + .clk_enable = cdce_enable, + .clk_disable = cdce_disable, + .rate = CAMERA_XTAL_FREQ, + .set_rate = cdce_set_rate, +}; + +static struct clk_lookup cdce913_clks[] = { + /* HACK: needs i2c address as dev name for proper lookup */ + CLK("1-004c", NULL, &cdce913_clk), +}; + +#define CDCE925_I2C_COMMAND_BLOCK_TRANSFER 0x00 +#define CDCE925_I2C_COMMAND_BYTE_TRANSFER 0x80 + +static int cdce925_i2c_write(const void *data, size_t count) +{ + struct i2c_client *i2c = cdce913; + int ret; + u8 reg_data[2]; + + if (count != 2) + return -ENOTSUPP; + + /* First byte is command code */ + reg_data[0] = CDCE925_I2C_COMMAND_BYTE_TRANSFER | ((u8 *)data)[0]; + reg_data[1] = ((u8 *)data)[1]; + + ret = i2c_master_send(i2c, reg_data, count); + if (likely(ret == count)) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + +/* + * NOTE: i2c read/write functions lifted directly from CCF driver: + * drivers/clk/clk-cdce925.c + */ + +static int cdce925_i2c_read( + const void *reg, size_t reg_size, void *val, size_t val_size) +{ + struct i2c_client *i2c = cdce913; + struct i2c_msg xfer[2]; + int ret; + u8 reg_data[2]; + + if (reg_size != 1) + return -ENOTSUPP; + + xfer[0].addr = i2c->addr; + xfer[0].flags = 0; + xfer[0].buf = reg_data; + if (val_size == 1) { + reg_data[0] = + CDCE925_I2C_COMMAND_BYTE_TRANSFER | ((u8 *)reg)[0]; + xfer[0].len = 1; + } else { + reg_data[0] = + CDCE925_I2C_COMMAND_BLOCK_TRANSFER | ((u8 *)reg)[0]; + reg_data[1] = val_size; + xfer[0].len = 2; + } + + xfer[1].addr = i2c->addr; + xfer[1].flags = I2C_M_RD; + xfer[1].len = val_size; + xfer[1].buf = val; + + ret = i2c_transfer(i2c->adapter, xfer, 2); + if (likely(ret == 2)) { + return 0; + } else if (ret < 0) + return ret; + else + return -EIO; +} + +static int cdce913_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + u8 data[16], reg; + + if (cdce913) { + dev_warn(&client->dev, "already probed !!\n"); + return 0; + } + cdce913 = client; + davinci_clk_init(cdce913_clks); + + for (reg = 0; reg < 4; reg++) { + cdce925_i2c_read(®, 1, &data, 1); + dev_dbg(&client->dev, "reg 0x%02x: val=0x%02x\n", reg, data[0]); + } + + return 0; +} + +static int cdce913_remove(struct i2c_client *client) +{ + cdce913 = NULL; + return 0; +} + +static const struct i2c_device_id cdce913_ids[] = { + { "cdce913", 0, }, + { /* end of list */ }, +}; + +static const struct of_device_id cdce913_of_match[] = { + { .compatible = "ti,cdce913", }, + { }, +}; + +static struct i2c_driver cdce913_driver = { + .driver = { + .name = "cdce913", + .of_match_table = of_match_ptr(cdce913_of_match), + }, + .id_table = cdce913_ids, + .probe = cdce913_probe, + .remove = cdce913_remove, +}; + +void __init da850_evm_camera_capture_init(void) +{ + i2c_add_driver(&cdce913_driver); +} diff --git a/arch/arm/mach-davinci/pdata-quirks.c b/arch/arm/mach-davinci/pdata-quirks.c index 4858b1cdf31b..2d0c8586f6f0 100644 --- a/arch/arm/mach-davinci/pdata-quirks.c +++ b/arch/arm/mach-davinci/pdata-quirks.c @@ -191,6 +191,9 @@ static void __init da850_vpif_display_legacy_init_evm(void) __func__, ret); } + +extern void __init da850_evm_camera_capture_init(void); + static void pdata_quirks_check(struct pdata_init *quirks) { while (quirks->compatible) { @@ -204,8 +207,9 @@ static void pdata_quirks_check(struct pdata_init *quirks) static struct pdata_init pdata_quirks[] __initdata = { { "ti,da850-lcdk", da850_vpif_capture_legacy_init_lcdk, }, - { "ti,da850-evm", da850_vpif_display_legacy_init_evm, }, - { "ti,da850-evm", da850_vpif_capture_legacy_init_evm, }, + { "ti,da850-evm", da850_evm_camera_capture_init, }, + /* { "ti,da850-evm", da850_vpif_display_legacy_init_evm, }, */ + /* { "ti,da850-evm", da850_vpif_capture_legacy_init_evm, }, */ { /* sentinel */ }, };