From patchwork Wed Aug 27 09:45:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naveen Krishna Chatradhi X-Patchwork-Id: 4786921 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 091409F383 for ; Wed, 27 Aug 2014 09:50:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 06FC62015E for ; Wed, 27 Aug 2014 09:50:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id ED7942017D for ; Wed, 27 Aug 2014 09:50:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932871AbaH0JuH (ORCPT ); Wed, 27 Aug 2014 05:50:07 -0400 Received: from mailout2.samsung.com ([203.254.224.25]:33528 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932642AbaH0JuE (ORCPT ); Wed, 27 Aug 2014 05:50:04 -0400 Received: from epcpsbgr5.samsung.com (u145.gpu120.samsung.co.kr [203.254.230.145]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NAY00ETFLZEO3C0@mailout2.samsung.com>; Wed, 27 Aug 2014 18:50:02 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [172.20.52.124]) by epcpsbgr5.samsung.com (EPCPMTA) with SMTP id 0D.2B.04513.AC9ADF35; Wed, 27 Aug 2014 18:50:02 +0900 (KST) X-AuditID: cbfee691-f79546d0000011a1-a4-53fda9caf096 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 28.64.05196.AC9ADF35; Wed, 27 Aug 2014 18:50:02 +0900 (KST) Received: from chnaveen-ubuntu.sisodomain.com ([107.108.83.161]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NAY00KEWLZ3NF90@mmp1.samsung.com>; Wed, 27 Aug 2014 18:50:02 +0900 (KST) From: Naveen Krishna Chatradhi Cc: naveenkrishna.ch@gmail.com, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org, cpgs@samsung.com, broonie@kernel.org, Wolfram Sang Subject: [PATCH 07/14] i2c: exynos: add support for HSI2C module on Exynos7 Date: Wed, 27 Aug 2014 15:15:39 +0530 Message-id: <1409132740-1954-1-git-send-email-ch.naveen@samsung.com> X-Mailer: git-send-email 1.7.9.5 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrOLMWRmVeSWpSXmKPExsWyRsSkRvfUyr/BBrP6pSymPnzCZvHykKbF /CPnWC02Pb7GajHj/D4mi0Xb/jNbrDwxi9mB3WPnrLvsHptWdbJ5bF5S79G3ZRWjx8lTT1g8 Pm+SC2CL4rJJSc3JLEst0rdL4Mr4cX8bW8Elo4q5p84xNjCu1Ohi5OSQEDCR+P/tGiuELSZx 4d56ti5GLg4hgaWMEifePWWFKbqz4CE7RGIRo8SDLZuZIZx+Jont35ayg1SxCZhJHFy0GswW EWCWWDD1PCNIEbPAeUaJ/4tA5nJyCAt4SzxYdpUZxGYRUJW4d3w+2ApeAReJs7dnATVwAK1T kJgzyQakV0KgnV3i6dWN7BD1AhLfJh9igaiRldh0gBniOkmJgytusExgFFzAyLCKUTS1ILmg OCm9yFSvODG3uDQvXS85P3cTIzB8T/97NnEH4/0D1ocYBTgYlXh4Pyz4EyzEmlhWXJl7iNEU aMNEZinR5HxglOSVxBsamxlZmJqYGhuZW5opifPqSP8MFhJITyxJzU5NLUgtii8qzUktPsTI xMEp1cAYUPHes134+P7Vv55lnf7jEpPwZff7K10vn72LMnim6C0esu71+0Ulck/dOn08Y9Mi T/NPN65Y164otjyysz4oMSew7vfevJVLJRJuSX8JedsUENyVcLx0lwEzNzs/+8KdU5vlhE0P XpuoZf/zhdqpk8y9TXo/DaJE2aevcxY5um3BjQN5N8qUWIozEg21mIuKEwGPdoHdWgIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprIIsWRmVeSWpSXmKPExsVy+t9jAd1TK/8GG6w+IWAx9eETNouXhzQt 5h85x2qx6fE1VosZ5/cxWSza9p/ZYuWJWcwO7B47Z91l99i0qpPNY/OSeo++LasYPU6eesLi 8XmTXABbVAOjTUZqYkpqkUJqXnJ+SmZeuq2Sd3C8c7ypmYGhrqGlhbmSQl5ibqqtkotPgK5b Zg7QKUoKZYk5pUChgMTiYiV9O0wTQkPcdC1gGiN0fUOC4HqMDNBAwhrGjB/3t7EVXDKqmHvq HGMD40qNLkZODgkBE4k7Cx6yQ9hiEhfurWfrYuTiEBJYxCjxYMtmZginn0li+7elYFVsAmYS BxetBrNFBJglFkw9zwhSxCxwnlHi/yKQdk4OYQFviQfLrjKD2CwCqhL3js9nBbF5BVwkzt6e BdTAAbROQWLOJJsJjNwLGBlWMYqmFiQXFCel5xrpFSfmFpfmpesl5+duYgRHxzPpHYyrGiwO MQpwMCrx8H5Y8CdYiDWxrLgy9xCjBAezkggv+6y/wUK8KYmVValF+fFFpTmpxYcYTYGWT2SW Ek3OB0ZuXkm8obGJuamxqaWJhYmZpZI478FW60AhgfTEktTs1NSC1CKYPiYOTqkGxiL5d91K AlsnW/y2V5kqH/5swy0Tq0rn2tWLHght8Ni+Isqu5o7/0zt7RFr+J9d2VP3uDWMTslJpXffl i8Bl0d6w4h+lB8MX6HmZTOCeE7M9SEP//NJzghkLp7DbhSyOmZwVkM99uuJF227tuTxnXq4P exM2ZTnDgfSlXwuvLpyVdF8g5OOq9UosxRmJhlrMRcWJADAEWdikAgAA DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected To: unlisted-recipients:; (no To-header on input) Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The HSI2C module on Exynos7 differs in the transfer status bits. Transfer status bits were moved to INT_ENABLE and INT_STATUS registers This patch adds support for the HSI2C module on Exynos7. 1. Implementes a "hw" field in the variant struct to distinguish the hardware. 2. Updates the dt-new compatible in dt-binding documenation Signed-off-by: Naveen Krishna Chatradhi To: linux-i2c@vger.kernel.org Cc: Wolfram Sang --- .../devicetree/bindings/i2c/i2c-exynos5.txt | 2 + drivers/i2c/busses/i2c-exynos5.c | 71 ++++++++++++++++++-- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-exynos5.txt b/Documentation/devicetree/bindings/i2c/i2c-exynos5.txt index d4745e3..2dbc0b6 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-exynos5.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-exynos5.txt @@ -12,6 +12,8 @@ Required properties: on Exynos5250 and Exynos5420 SoCs. -> "samsung,exynos5260-hsi2c", for i2c compatible with HSI2C available on Exynos5260 SoCs. + -> "samsung,exynos7-hsi2c", for i2c compatible with HSI2C available + on Exynos7 SoCs. - reg: physical base address of the controller and length of memory mapped region. diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index 28073f1..81e6263 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -83,7 +83,6 @@ #define HSI2C_INT_TX_ALMOSTEMPTY_EN (1u << 0) #define HSI2C_INT_RX_ALMOSTFULL_EN (1u << 1) #define HSI2C_INT_TRAILING_EN (1u << 6) -#define HSI2C_INT_I2C_EN (1u << 9) /* I2C_INT_STAT Register bits */ #define HSI2C_INT_TX_ALMOSTEMPTY (1u << 0) @@ -95,6 +94,17 @@ #define HSI2C_INT_TRAILING (1u << 6) #define HSI2C_INT_I2C (1u << 9) +#define HSI2C_INT_TRANS_DONE (1u << 7) +#define HSI2C_INT_TRANS_ABORT (1u << 8) +#define HSI2C_INT_NO_DEV_ACK (1u << 9) +#define HSI2C_INT_NO_DEV (1u << 10) +#define HSI2C_INT_TIMEOUT (1u << 11) +#define HSI2C_INT_I2C_TRANS (HSI2C_INT_TRANS_DONE | \ + HSI2C_INT_TRANS_ABORT | \ + HSI2C_INT_NO_DEV_ACK | \ + HSI2C_INT_NO_DEV | \ + HSI2C_INT_TIMEOUT) + /* I2C_FIFO_STAT Register bits */ #define HSI2C_RX_FIFO_EMPTY (1u << 24) #define HSI2C_RX_FIFO_FULL (1u << 23) @@ -143,6 +153,8 @@ #define EXYNOS5_I2C_TIMEOUT (msecs_to_jiffies(1000)) +#define HSI2C_EXYNOS7 BIT(0) + struct exynos5_i2c { struct i2c_adapter adap; unsigned int suspended:1; @@ -192,6 +204,7 @@ struct exynos5_i2c { */ struct exynos_hsi2c_variant { unsigned int fifo_depth; + unsigned int hw; }; static const struct exynos_hsi2c_variant exynos5250_hsi2c_data = { @@ -202,6 +215,11 @@ static const struct exynos_hsi2c_variant exynos5260_hsi2c_data = { .fifo_depth = 16, }; +static const struct exynos_hsi2c_variant exynos7_hsi2c_data = { + .fifo_depth = 16, + .hw = HSI2C_EXYNOS7, +}; + static const struct of_device_id exynos5_i2c_match[] = { { .compatible = "samsung,exynos5-hsi2c", @@ -212,6 +230,9 @@ static const struct of_device_id exynos5_i2c_match[] = { }, { .compatible = "samsung,exynos5260-hsi2c", .data = &exynos5260_hsi2c_data + }, { + .compatible = "samsung,exynos7-hsi2c", + .data = &exynos7_hsi2c_data }, {}, }; MODULE_DEVICE_TABLE(of, exynos5_i2c_match); @@ -256,13 +277,24 @@ static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode) i2c->hs_clock : i2c->fs_clock; /* + * In case of HSI2C controller in Exynos5 series * FPCLK / FI2C = * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE + * + * In case of HSI2C controllers in Exynos7 series + * FPCLK / FI2C = + * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + FLT_CYCLE + * * utemp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) * utemp1 = (TSCLK_L + TSCLK_H + 2) */ t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7; - utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle; + utemp0 = (clkin / op_clk) - 8; + + if (i2c->variant->hw == HSI2C_EXYNOS7) + utemp0 -= t_ftl_cycle; + else + utemp0 -= 2 * t_ftl_cycle; /* CLK_DIV max is 256 */ for (div = 0; div < 256; div++) { @@ -407,7 +439,28 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) writel(int_status, i2c->regs + HSI2C_INT_STATUS); /* handle interrupt related to the transfer status */ - if (int_status & HSI2C_INT_I2C) { + if (i2c->variant->hw == HSI2C_EXYNOS7) { + if (int_status & HSI2C_INT_TRANS_DONE) { + i2c->trans_done = 1; + i2c->state = 0; + } else if (int_status & HSI2C_INT_TRANS_ABORT) { + dev_dbg(i2c->dev, "Deal with arbitration lose\n"); + i2c->state = -EAGAIN; + goto stop; + } else if (int_status & HSI2C_INT_NO_DEV_ACK) { + dev_dbg(i2c->dev, "No ACK from device\n"); + i2c->state = -ENXIO; + goto stop; + } else if (int_status & HSI2C_INT_NO_DEV) { + dev_dbg(i2c->dev, "No device\n"); + i2c->state = -ENXIO; + goto stop; + } else if (int_status & HSI2C_INT_TIMEOUT) { + dev_dbg(i2c->dev, "Accessing device timed out\n"); + i2c->state = -EAGAIN; + goto stop; + } + } else if (int_status & HSI2C_INT_I2C) { trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); if (trans_status & HSI2C_NO_DEV_ACK) { dev_dbg(i2c->dev, "No ACK from device\n"); @@ -512,12 +565,17 @@ static int exynos5_i2c_wait_bus_idle(struct exynos5_i2c *i2c) static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop) { u32 i2c_ctl; - u32 int_en = HSI2C_INT_I2C_EN; + u32 int_en = 0; u32 i2c_auto_conf = 0; u32 fifo_ctl; unsigned long flags; unsigned short trig_lvl; + if (i2c->variant->hw == HSI2C_EXYNOS7) + int_en |= HSI2C_INT_I2C_TRANS; + else + int_en |= HSI2C_INT_I2C; + i2c_ctl = readl(i2c->regs + HSI2C_CTL); i2c_ctl &= ~(HSI2C_TXCHON | HSI2C_RXCHON); fifo_ctl = HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN; @@ -724,12 +782,13 @@ static int exynos5_i2c_probe(struct platform_device *pdev) goto err_clk; } + /* Need to check the variant before setting up. */ + i2c->variant = exynos5_i2c_get_variant(pdev); + ret = exynos5_hsi2c_clock_setup(i2c); if (ret) goto err_clk; - i2c->variant = exynos5_i2c_get_variant(pdev); - exynos5_i2c_reset(i2c); ret = i2c_add_adapter(&i2c->adap);