From patchwork Wed Nov 9 11:57:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Romain Perier X-Patchwork-Id: 692719 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3tDPmy2BwLz9t1L for ; Wed, 9 Nov 2016 22:57:22 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752650AbcKIL5U (ORCPT ); Wed, 9 Nov 2016 06:57:20 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:39965 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751454AbcKIL5T (ORCPT ); Wed, 9 Nov 2016 06:57:19 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 3D88F20CBC; Wed, 9 Nov 2016 12:57:17 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from latitudeE7470 (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 1A96520454; Wed, 9 Nov 2016 12:57:17 +0100 (CET) From: Romain Perier To: Wolfram Sang , linux-i2c@vger.kernel.org Cc: devicetree@vger.kernel.org, Rob Herring , Ian Campbell , Pawel Moll , Mark Rutland , Kumar Gala , Jason Cooper , Andrew Lunn , Sebastian Hesselbarth , Gregory Clement , linux-arm-kernel@lists.infradead.org, Thomas Petazzoni , Nadav Haklai , Omri Itach , Shadi Ammouri , Yahuda Yitschak , Hanna Hawa , Neta Zur Hershkovits , Igal Liberman , Marcin Wojtas Subject: [PATCH v4 1/3] i2c: pxa: Add support for the I2C units found in Armada 3700 Date: Wed, 9 Nov 2016 12:57:13 +0100 Message-Id: <20161109115715.2557-2-romain.perier@free-electrons.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161109115715.2557-1-romain.perier@free-electrons.com> References: <20161109115715.2557-1-romain.perier@free-electrons.com> Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org The Armada 3700 has two I2C controllers that is compliant with the I2C Bus Specificiation 2.1, supports multi-master and different bus speed: Standard mode (up to 100 KHz), Fast mode (up to 400 KHz), High speed mode (up to 3.4 Mhz). This IP block has a lot of similarity with the PXA, except some register offsets and bitfield. This commits adds a basic support for this I2C unit. Signed-off-by: Romain Perier Tested-by: Gregory CLEMENT --- Changes in v4: - Replaced the type of hs_mask and fm_mask by u32, instead of unsigned int, As writel() take an u32 as first argument... Changes in v3: - Replaced the type of hs_mask and fm_mask by unsigned int, instead of unsigned long. drivers/i2c/busses/Kconfig | 2 +- drivers/i2c/busses/i2c-pxa.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index d252276..2f56a26 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -763,7 +763,7 @@ config I2C_PUV3 config I2C_PXA tristate "Intel PXA2XX I2C adapter" - depends on ARCH_PXA || ARCH_MMP || (X86_32 && PCI && OF) + depends on ARCH_PXA || ARCH_MMP || ARCH_MVEBU || (X86_32 && PCI && OF) help If you have devices in the PXA I2C bus, say yes to this option. This driver can also be built as a module. If so, the module diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index e28b825..09b4705 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -55,6 +55,7 @@ enum pxa_i2c_types { REGS_PXA3XX, REGS_CE4100, REGS_PXA910, + REGS_A3700, }; /* @@ -91,6 +92,13 @@ static struct pxa_reg_layout pxa_reg_layout[] = { .ilcr = 0x28, .iwcr = 0x30, }, + [REGS_A3700] = { + .ibmr = 0x00, + .idbr = 0x04, + .icr = 0x08, + .isr = 0x0c, + .isar = 0x10, + }, }; static const struct platform_device_id i2c_pxa_id_table[] = { @@ -98,6 +106,7 @@ static const struct platform_device_id i2c_pxa_id_table[] = { { "pxa3xx-pwri2c", REGS_PXA3XX }, { "ce4100-i2c", REGS_CE4100 }, { "pxa910-i2c", REGS_PXA910 }, + { "armada-3700-i2c", REGS_A3700 }, { }, }; MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table); @@ -122,7 +131,9 @@ MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table); #define ICR_SADIE (1 << 13) /* slave address detected int enable */ #define ICR_UR (1 << 14) /* unit reset */ #define ICR_FM (1 << 15) /* fast mode */ +#define ICR_BUSMODE_FM (1 << 16) /* shifted fast mode for armada-3700 */ #define ICR_HS (1 << 16) /* High Speed mode */ +#define ICR_BUSMODE_HS (1 << 17) /* shifted high speed mode for armada-3700 */ #define ICR_GPIOEN (1 << 19) /* enable GPIO mode for SCL in HS */ #define ISR_RWM (1 << 0) /* read/write mode */ @@ -193,6 +204,8 @@ struct pxa_i2c { unsigned char master_code; unsigned long rate; bool highmode_enter; + u32 fm_mask; + u32 hs_mask; }; #define _IBMR(i2c) ((i2c)->reg_ibmr) @@ -503,8 +516,8 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c) writel(i2c->slave_addr, _ISAR(i2c)); /* set control register values */ - writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c)); - writel(readl(_ICR(i2c)) | (i2c->high_mode ? ICR_HS : 0), _ICR(i2c)); + writel(I2C_ICR_INIT | (i2c->fast_mode ? i2c->fm_mask : 0), _ICR(i2c)); + writel(readl(_ICR(i2c)) | (i2c->high_mode ? i2c->hs_mask : 0), _ICR(i2c)); #ifdef CONFIG_I2C_PXA_SLAVE dev_info(&i2c->adap.dev, "Enabling slave mode\n"); @@ -1137,6 +1150,7 @@ static const struct of_device_id i2c_pxa_dt_ids[] = { { .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX }, { .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX }, { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 }, + { .compatible = "marvell,armada-3700-i2c", .data = (void *)REGS_A3700 }, {} }; MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids); @@ -1158,6 +1172,13 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c, i2c->use_pio = 1; if (of_get_property(np, "mrvl,i2c-fast-mode", NULL)) i2c->fast_mode = 1; + if (of_device_is_compatible(np, "marvell,armada-3700-i2c")) { + i2c->fm_mask = ICR_BUSMODE_FM; + i2c->hs_mask = ICR_BUSMODE_HS; + } else { + i2c->fm_mask = ICR_FM; + i2c->hs_mask = ICR_HS; + } *i2c_types = (enum pxa_i2c_types)(of_id->data);