12373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie/* 22373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Synopsys DesignWare I2C adapter driver (master only). 32373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 42373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Based on the TI DAVINCI I2C adapter driver. 52373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 62373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Copyright (C) 2006 Texas Instruments. 72373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Copyright (C) 2007 MontaVista Software Inc. 82373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Copyright (C) 2009 Provigent Ltd. 92373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 102373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * ---------------------------------------------------------------------------- 112373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 122373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * This program is free software; you can redistribute it and/or modify 132373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * it under the terms of the GNU General Public License as published by 142373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * the Free Software Foundation; either version 2 of the License, or 152373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * (at your option) any later version. 162373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 172373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * This program is distributed in the hope that it will be useful, 182373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * but WITHOUT ANY WARRANTY; without even the implied warranty of 192373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 202373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * GNU General Public License for more details. 212373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 222373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * You should have received a copy of the GNU General Public License 232373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * along with this program; if not, write to the Free Software 242373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 252373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * ---------------------------------------------------------------------------- 262373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 272373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 282373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie#include <linux/clk.h> 292373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie#include <linux/errno.h> 302373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie#include <linux/err.h> 312373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie#include <linux/i2c.h> 322373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie#include <linux/interrupt.h> 332373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie#include <linux/io.h> 3418dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie#include <linux/pm_runtime.h> 352373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie#include <linux/delay.h> 362373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie#include "i2c-designware-core.h" 372373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 38f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie/* 39f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie * Registers offset 40f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie */ 41f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CON 0x0 42f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TAR 0x4 43f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_DATA_CMD 0x10 44f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_SS_SCL_HCNT 0x14 45f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_SS_SCL_LCNT 0x18 46f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_FS_SCL_HCNT 0x1c 47f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_FS_SCL_LCNT 0x20 48f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_STAT 0x2c 49f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_MASK 0x30 50f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_RAW_INTR_STAT 0x34 51f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_RX_TL 0x38 52f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_TL 0x3c 53f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_INTR 0x40 54f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_RX_UNDER 0x44 55f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_RX_OVER 0x48 56f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_TX_OVER 0x4c 57f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_RD_REQ 0x50 58f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_TX_ABRT 0x54 59f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_RX_DONE 0x58 60f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_ACTIVITY 0x5c 61f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_STOP_DET 0x60 62f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_START_DET 0x64 63f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_CLR_GEN_CALL 0x68 64f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_ENABLE 0x6c 65f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_STATUS 0x70 66f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TXFLR 0x74 67f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_RXFLR 0x78 68f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_SOURCE 0x80 69f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_COMP_PARAM_1 0xf4 70f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_COMP_TYPE 0xfc 71f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_COMP_TYPE_VALUE 0x44570140 72f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 73f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_RX_UNDER 0x001 74f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_RX_OVER 0x002 75f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_RX_FULL 0x004 76f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_TX_OVER 0x008 77f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_TX_EMPTY 0x010 78f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_RD_REQ 0x020 79f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_TX_ABRT 0x040 80f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_RX_DONE 0x080 81f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_ACTIVITY 0x100 82f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_STOP_DET 0x200 83f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_START_DET 0x400 84f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_GEN_CALL 0x800 85f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 86f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ 87f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie DW_IC_INTR_TX_EMPTY | \ 88f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie DW_IC_INTR_TX_ABRT | \ 89f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie DW_IC_INTR_STOP_DET) 90f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 91f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_STATUS_ACTIVITY 0x1 92f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 93f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_ERR_TX_ABRT 0x1 94f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 95f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie/* 96f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie * status codes 97f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie */ 98f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define STATUS_IDLE 0x0 99f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define STATUS_WRITE_IN_PROGRESS 0x1 100f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define STATUS_READ_IN_PROGRESS 0x2 101f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 102f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define TIMEOUT 20 /* ms */ 103f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 104f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie/* 105f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register 106f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie * 107f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie * only expected abort codes are listed here 108f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie * refer to the datasheet for the full list 109f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie */ 110f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_7B_ADDR_NOACK 0 111f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_10ADDR1_NOACK 1 112f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_10ADDR2_NOACK 2 113f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_TXDATA_NOACK 3 114f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_GCALL_NOACK 4 115f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_GCALL_READ 5 116f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_SBYTE_ACKDET 7 117f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_SBYTE_NORSTRT 9 118f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_10B_RD_NORSTRT 10 119f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ABRT_MASTER_DIS 11 120f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define ARB_LOST 12 121f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 122f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK) 123f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK) 124f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK) 125f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK) 126f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK) 127f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ) 128f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET) 129f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT) 130f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT) 131f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS) 132f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST) 133f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 134f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \ 135f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie DW_IC_TX_ABRT_10ADDR1_NOACK | \ 136f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie DW_IC_TX_ABRT_10ADDR2_NOACK | \ 137f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie DW_IC_TX_ABRT_TXDATA_NOACK | \ 138f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie DW_IC_TX_ABRT_GCALL_NOACK) 139f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 1402373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiestatic char *abort_sources[] = { 1412373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_7B_ADDR_NOACK] = 1422373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "slave address not acknowledged (7bit mode)", 1432373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_10ADDR1_NOACK] = 1442373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "first address byte not acknowledged (10bit mode)", 1452373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_10ADDR2_NOACK] = 1462373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "second address byte not acknowledged (10bit mode)", 1472373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_TXDATA_NOACK] = 1482373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "data not acknowledged", 1492373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_GCALL_NOACK] = 1502373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "no acknowledgement for a general call", 1512373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_GCALL_READ] = 1522373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "read after general call", 1532373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_SBYTE_ACKDET] = 1542373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "start byte acknowledged", 1552373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_SBYTE_NORSTRT] = 1562373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "trying to send start byte when restart is disabled", 1572373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_10B_RD_NORSTRT] = 1582373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "trying to read when restart is disabled (10bit mode)", 1592373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ABRT_MASTER_DIS] = 1602373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "trying to use disabled adapter", 1612373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie [ARB_LOST] = 1622373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "lost arbitration", 1632373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie}; 1642373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 1652373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewieu32 dw_readl(struct dw_i2c_dev *dev, int offset) 1662373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 1672373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u32 value = readl(dev->base + offset); 1682373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 1692373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (dev->swab) 1702373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return swab32(value); 1712373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie else 1722373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return value; 1732373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 1742373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 1752373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewievoid dw_writel(struct dw_i2c_dev *dev, u32 b, int offset) 1762373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 1772373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (dev->swab) 1782373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie b = swab32(b); 1792373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 1802373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie writel(b, dev->base + offset); 1812373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 1822373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 1832373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiestatic u32 1842373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiei2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) 1852373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 1862373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 1872373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * DesignWare I2C core doesn't seem to have solid strategy to meet 1882373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * the tHD;STA timing spec. Configuring _HCNT based on tHIGH spec 1892373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * will result in violation of the tHD;STA spec. 1902373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 1912373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (cond) 1922373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 1932373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Conditional expression: 1942373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 1952373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH 1962373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 1972373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * This is based on the DW manuals, and represents an ideal 1982373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * configuration. The resulting I2C bus speed will be 1992373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * faster than any of the others. 2002373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 2012373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * If your hardware is free from tHD;STA issue, try this one. 2022373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 2032373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset; 2042373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie else 2052373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 2062373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Conditional expression: 2072373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 2082373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf) 2092373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 2102373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * This is just experimental rule; the tHD;STA period turned 2112373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * out to be proportinal to (_HCNT + 3). With this setting, 2122373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * we could meet both tHIGH and tHD;STA timing specs. 2132373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 2142373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * If unsure, you'd better to take this alternative. 2152373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 2162373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * The reason why we need to take into account "tf" here, 2172373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * is the same as described in i2c_dw_scl_lcnt(). 2182373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 2192373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset; 2202373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 2212373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 2222373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiestatic u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) 2232373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 2242373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 2252373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Conditional expression: 2262373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 2272373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf) 2282373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 2292373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * DW I2C core starts counting the SCL CNTs for the LOW period 2302373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * of the SCL clock (tLOW) as soon as it pulls the SCL line. 2312373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * In order to meet the tLOW timing spec, we need to take into 2322373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * account the fall time of SCL signal (tf). Default tf value 2332373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * should be 0.3 us, for safety. 2342373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 2352373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset; 2362373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 2372373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 2382373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie/** 2392373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * i2c_dw_init() - initialize the designware i2c master hardware 2402373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * @dev: device private data 2412373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 2422373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * This functions configures and enables the I2C master. 2432373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * This function is called during I2C init function, and in case of timeout at 2442373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * run time. 2452373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 2462373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewieint i2c_dw_init(struct dw_i2c_dev *dev) 2472373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 2481d31b58f648c4f754b23fed4d57acc941080e5eeDirk Brandewie u32 input_clock_khz; 249e18563fc560aba0d95a5a73145812a081fb38facDirk Brandewie u32 hcnt, lcnt; 2502373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u32 reg; 2512373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 2521d31b58f648c4f754b23fed4d57acc941080e5eeDirk Brandewie input_clock_khz = dev->get_clk_rate_khz(dev); 2531d31b58f648c4f754b23fed4d57acc941080e5eeDirk Brandewie 2542373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Configure register endianess access */ 2552373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie reg = dw_readl(dev, DW_IC_COMP_TYPE); 2562373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) { 2572373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->swab = 1; 2582373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie reg = DW_IC_COMP_TYPE_VALUE; 2592373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 2602373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 2612373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (reg != DW_IC_COMP_TYPE_VALUE) { 2622373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_err(dev->dev, "Unknown Synopsys component type: " 2632373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "0x%08x\n", reg); 2642373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return -ENODEV; 2652373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 2662373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 2672373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Disable the adapter */ 2682373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, 0, DW_IC_ENABLE); 2692373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 2702373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* set standard and fast speed deviders for high/low periods */ 2712373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 2722373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Standard-mode */ 2732373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie hcnt = i2c_dw_scl_hcnt(input_clock_khz, 2742373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 40, /* tHD;STA = tHIGH = 4.0 us */ 2752373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3, /* tf = 0.3 us */ 2762373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 0, /* 0: DW default, 1: Ideal */ 2772373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 0); /* No offset */ 2782373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie lcnt = i2c_dw_scl_lcnt(input_clock_khz, 2792373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 47, /* tLOW = 4.7 us */ 2802373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3, /* tf = 0.3 us */ 2812373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 0); /* No offset */ 2822373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT); 2832373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT); 2842373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); 2852373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 2862373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Fast-mode */ 2872373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie hcnt = i2c_dw_scl_hcnt(input_clock_khz, 2882373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6, /* tHD;STA = tHIGH = 0.6 us */ 2892373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3, /* tf = 0.3 us */ 2902373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 0, /* 0: DW default, 1: Ideal */ 2912373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 0); /* No offset */ 2922373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie lcnt = i2c_dw_scl_lcnt(input_clock_khz, 2932373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 13, /* tLOW = 1.3 us */ 2942373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3, /* tf = 0.3 us */ 2952373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 0); /* No offset */ 2962373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT); 2972373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT); 2982373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); 2992373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3002373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Configure Tx/Rx FIFO threshold levels */ 3012373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, dev->tx_fifo_depth - 1, DW_IC_TX_TL); 3022373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, 0, DW_IC_RX_TL); 3032373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3042373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* configure the i2c master */ 305e18563fc560aba0d95a5a73145812a081fb38facDirk Brandewie dw_writel(dev, dev->master_cfg , DW_IC_CON); 3062373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return 0; 3072373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 3082373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3092373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie/* 3102373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Waiting for bus not busy 3112373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 3122373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiestatic int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) 3132373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 3142373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie int timeout = TIMEOUT; 3152373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3162373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { 3172373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (timeout <= 0) { 3182373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_warn(dev->dev, "timeout waiting for bus ready\n"); 3192373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return -ETIMEDOUT; 3202373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 3212373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie timeout--; 3222373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie mdelay(1); 3232373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 3242373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3252373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return 0; 3262373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 3272373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3282373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiestatic void i2c_dw_xfer_init(struct dw_i2c_dev *dev) 3292373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 3302373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie struct i2c_msg *msgs = dev->msgs; 3312373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u32 ic_con; 3322373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3332373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Disable the adapter */ 3342373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, 0, DW_IC_ENABLE); 3352373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3362373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* set the slave (target) address */ 3372373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); 3382373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3392373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* if the slave address is ten bit address, enable 10BITADDR */ 3402373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ic_con = dw_readl(dev, DW_IC_CON); 3412373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) 3422373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ic_con |= DW_IC_CON_10BITADDR_MASTER; 3432373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie else 3442373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ic_con &= ~DW_IC_CON_10BITADDR_MASTER; 3452373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, ic_con, DW_IC_CON); 3462373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3472373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Enable the adapter */ 3482373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, 1, DW_IC_ENABLE); 3492373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3502373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Enable interrupts */ 3512373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); 3522373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 3532373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3542373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie/* 3552373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Initiate (and continue) low level master read/write transaction. 3562373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * This function is only called from i2c_dw_isr, and pumping i2c_msg 3572373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * messages into the tx buffer. Even if the size of i2c_msg data is 3582373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * longer than the size of the tx buffer, it handles everything. 3592373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 3602373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewievoid 3612373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiei2c_dw_xfer_msg(struct dw_i2c_dev *dev) 3622373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 3632373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie struct i2c_msg *msgs = dev->msgs; 3642373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u32 intr_mask; 3652373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie int tx_limit, rx_limit; 3662373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u32 addr = msgs[dev->msg_write_idx].addr; 3672373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u32 buf_len = dev->tx_buf_len; 3682373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u8 *buf = dev->tx_buf; 3692373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3702373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie intr_mask = DW_IC_INTR_DEFAULT_MASK; 3712373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3722373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { 3732373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 3742373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * if target address has changed, we need to 3752373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * reprogram the target address in the i2c 3762373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * adapter when we are done with this transfer 3772373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 3782373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (msgs[dev->msg_write_idx].addr != addr) { 3792373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_err(dev->dev, 3802373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "%s: invalid target address\n", __func__); 3812373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->msg_err = -EINVAL; 3822373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie break; 3832373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 3842373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3852373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (msgs[dev->msg_write_idx].len == 0) { 3862373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_err(dev->dev, 3872373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "%s: invalid message length\n", __func__); 3882373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->msg_err = -EINVAL; 3892373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie break; 3902373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 3912373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3922373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { 3932373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* new i2c_msg */ 3942373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie buf = msgs[dev->msg_write_idx].buf; 3952373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie buf_len = msgs[dev->msg_write_idx].len; 3962373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 3972373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 3982373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR); 3992373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR); 4002373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4012373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { 4022373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { 4032373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, 0x100, DW_IC_DATA_CMD); 4042373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie rx_limit--; 4052373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } else 4062373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, *buf++, DW_IC_DATA_CMD); 4072373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie tx_limit--; buf_len--; 4082373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 4092373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4102373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->tx_buf = buf; 4112373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->tx_buf_len = buf_len; 4122373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4132373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (buf_len > 0) { 4142373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* more bytes to be written */ 4152373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->status |= STATUS_WRITE_IN_PROGRESS; 4162373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie break; 4172373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } else 4182373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->status &= ~STATUS_WRITE_IN_PROGRESS; 4192373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 4202373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4212373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 4222373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * If i2c_msg index search is completed, we don't need TX_EMPTY 4232373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * interrupt any more. 4242373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 4252373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (dev->msg_write_idx == dev->msgs_num) 4262373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie intr_mask &= ~DW_IC_INTR_TX_EMPTY; 4272373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4282373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (dev->msg_err) 4292373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie intr_mask = 0; 4302373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4312373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, intr_mask, DW_IC_INTR_MASK); 4322373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 4332373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4342373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiestatic void 4352373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiei2c_dw_read(struct dw_i2c_dev *dev) 4362373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 4372373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie struct i2c_msg *msgs = dev->msgs; 4382373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie int rx_valid; 4392373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4402373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { 4412373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u32 len; 4422373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u8 *buf; 4432373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4442373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) 4452373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie continue; 4462373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4472373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (!(dev->status & STATUS_READ_IN_PROGRESS)) { 4482373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie len = msgs[dev->msg_read_idx].len; 4492373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie buf = msgs[dev->msg_read_idx].buf; 4502373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } else { 4512373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie len = dev->rx_buf_len; 4522373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie buf = dev->rx_buf; 4532373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 4542373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4552373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie rx_valid = dw_readl(dev, DW_IC_RXFLR); 4562373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4572373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie for (; len > 0 && rx_valid > 0; len--, rx_valid--) 4582373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie *buf++ = dw_readl(dev, DW_IC_DATA_CMD); 4592373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4602373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (len > 0) { 4612373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->status |= STATUS_READ_IN_PROGRESS; 4622373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->rx_buf_len = len; 4632373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->rx_buf = buf; 4642373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return; 4652373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } else 4662373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->status &= ~STATUS_READ_IN_PROGRESS; 4672373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 4682373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 4692373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4702373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiestatic int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) 4712373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 4722373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie unsigned long abort_source = dev->abort_source; 4732373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie int i; 4742373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4752373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (abort_source & DW_IC_TX_ABRT_NOACK) { 4762373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) 4772373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_dbg(dev->dev, 4782373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie "%s: %s\n", __func__, abort_sources[i]); 4792373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return -EREMOTEIO; 4802373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 4812373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4822373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) 4832373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); 4842373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4852373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (abort_source & DW_IC_TX_ARB_LOST) 4862373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return -EAGAIN; 4872373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie else if (abort_source & DW_IC_TX_ABRT_GCALL_READ) 4882373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return -EINVAL; /* wrong msgs[] data */ 4892373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie else 4902373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return -EIO; 4912373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 4922373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 4932373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie/* 4942373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Prepare controller for a transaction and call i2c_dw_xfer_msg 4952373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 4962373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewieint 4972373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiei2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) 4982373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 4992373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 5002373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie int ret; 5012373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5022373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); 5032373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5042373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie mutex_lock(&dev->lock); 50518dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie pm_runtime_get_sync(dev->dev); 5062373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5072373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie INIT_COMPLETION(dev->cmd_complete); 5082373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->msgs = msgs; 5092373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->msgs_num = num; 5102373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->cmd_err = 0; 5112373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->msg_write_idx = 0; 5122373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->msg_read_idx = 0; 5132373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->msg_err = 0; 5142373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->status = STATUS_IDLE; 5152373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->abort_source = 0; 5162373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5172373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ret = i2c_dw_wait_bus_not_busy(dev); 5182373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (ret < 0) 5192373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie goto done; 5202373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5212373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* start the transfers */ 5222373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie i2c_dw_xfer_init(dev); 5232373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5242373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* wait for tx to complete */ 5252373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ); 5262373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (ret == 0) { 5272373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev_err(dev->dev, "controller timed out\n"); 5282373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie i2c_dw_init(dev); 5292373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ret = -ETIMEDOUT; 5302373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie goto done; 5312373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } else if (ret < 0) 5322373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie goto done; 5332373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5342373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (dev->msg_err) { 5352373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ret = dev->msg_err; 5362373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie goto done; 5372373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 5382373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5392373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* no error */ 5402373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (likely(!dev->cmd_err)) { 5412373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* Disable the adapter */ 5422373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, 0, DW_IC_ENABLE); 5432373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ret = num; 5442373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie goto done; 5452373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 5462373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5472373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* We have an error */ 5482373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (dev->cmd_err == DW_IC_ERR_TX_ABRT) { 5492373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ret = i2c_dw_handle_tx_abort(dev); 5502373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie goto done; 5512373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 5522373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie ret = -EIO; 5532373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5542373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiedone: 55518dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie pm_runtime_put(dev->dev); 5562373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie mutex_unlock(&dev->lock); 5572373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5582373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return ret; 5592373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 5602373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5612373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewieu32 i2c_dw_func(struct i2c_adapter *adap) 5622373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 5632fa8326b4b1e5fdc889b57b03b1313f3229cb438Dirk Brandewie struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 5642fa8326b4b1e5fdc889b57b03b1313f3229cb438Dirk Brandewie return dev->functionality; 5652373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 5662373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5672373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewiestatic u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) 5682373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 5692373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie u32 stat; 5702373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5712373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 5722373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * The IC_INTR_STAT register just indicates "enabled" interrupts. 5732373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Ths unmasked raw version of interrupt status bits are available 5742373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * in the IC_RAW_INTR_STAT register. 5752373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 5762373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * That is, 5772373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * stat = dw_readl(IC_INTR_STAT); 5782373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * equals to, 5792373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK); 5802373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 5812373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * The raw version might be useful for debugging purposes. 5822373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 5832373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie stat = dw_readl(dev, DW_IC_INTR_STAT); 5842373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 5852373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 5862373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Do not use the IC_CLR_INTR register to clear interrupts, or 5872373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * you'll miss some interrupts, triggered during the period from 5882373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR). 5892373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * 5902373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Instead, use the separately-prepared IC_CLR_* registers. 5912373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 5922373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_RX_UNDER) 5932373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_RX_UNDER); 5942373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_RX_OVER) 5952373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_RX_OVER); 5962373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_TX_OVER) 5972373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_TX_OVER); 5982373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_RD_REQ) 5992373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_RD_REQ); 6002373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_TX_ABRT) { 6012373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 6022373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * The IC_TX_ABRT_SOURCE register is cleared whenever 6032373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * the IC_CLR_TX_ABRT is read. Preserve it beforehand. 6042373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 6052373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->abort_source = dw_readl(dev, DW_IC_TX_ABRT_SOURCE); 6062373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_TX_ABRT); 6072373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 6082373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_RX_DONE) 6092373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_RX_DONE); 6102373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_ACTIVITY) 6112373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_ACTIVITY); 6122373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_STOP_DET) 6132373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_STOP_DET); 6142373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_START_DET) 6152373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_START_DET); 6162373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_GEN_CALL) 6172373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_readl(dev, DW_IC_CLR_GEN_CALL); 6182373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6192373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return stat; 6202373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 6212373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6222373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie/* 6232373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Interrupt service routine. This gets called whenever an I2C interrupt 6242373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * occurs. 6252373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 6262373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewieirqreturn_t i2c_dw_isr(int this_irq, void *dev_id) 6272373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie{ 6282373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie struct dw_i2c_dev *dev = dev_id; 629af06cf6c8cb600803951ddabe6fb034126752488Dirk Brandewie u32 stat, enabled; 630af06cf6c8cb600803951ddabe6fb034126752488Dirk Brandewie 631af06cf6c8cb600803951ddabe6fb034126752488Dirk Brandewie enabled = dw_readl(dev, DW_IC_ENABLE); 632af06cf6c8cb600803951ddabe6fb034126752488Dirk Brandewie stat = dw_readl(dev, DW_IC_RAW_INTR_STAT); 633af06cf6c8cb600803951ddabe6fb034126752488Dirk Brandewie dev_dbg(dev->dev, "%s: %s enabled= 0x%x stat=0x%x\n", __func__, 634af06cf6c8cb600803951ddabe6fb034126752488Dirk Brandewie dev->adapter.name, enabled, stat); 635af06cf6c8cb600803951ddabe6fb034126752488Dirk Brandewie if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) 636af06cf6c8cb600803951ddabe6fb034126752488Dirk Brandewie return IRQ_NONE; 6372373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6382373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie stat = i2c_dw_read_clear_intrbits(dev); 6392373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6402373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_TX_ABRT) { 6412373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->cmd_err |= DW_IC_ERR_TX_ABRT; 6422373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dev->status = STATUS_IDLE; 6432373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6442373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 6452373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * Anytime TX_ABRT is set, the contents of the tx/rx 6462373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * buffers are flushed. Make sure to skip them. 6472373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 6482373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie dw_writel(dev, 0, DW_IC_INTR_MASK); 6492373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie goto tx_aborted; 6502373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie } 6512373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6522373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_RX_FULL) 6532373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie i2c_dw_read(dev); 6542373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6552373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if (stat & DW_IC_INTR_TX_EMPTY) 6562373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie i2c_dw_xfer_msg(dev); 6572373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6582373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie /* 6592373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * No need to modify or disable the interrupt mask here. 6602373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * i2c_dw_xfer_msg() will take care of it according to 6612373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie * the current transmit status. 6622373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie */ 6632373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6642373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewietx_aborted: 6652373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) 6662373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie complete(&dev->cmd_complete); 6672373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie 6682373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie return IRQ_HANDLED; 6692373f6b9744d5373b886f3ce1a985193cca0a356Dirk Brandewie} 670f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 671f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewievoid i2c_dw_enable(struct dw_i2c_dev *dev) 672f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie{ 673f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie /* Enable the adapter */ 674f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie dw_writel(dev, 1, DW_IC_ENABLE); 675f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie} 676f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 67718dbdda89f5cf0540e577280395f16079308e87dDirk Brandewieu32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) 678f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie{ 67918dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie return dw_readl(dev, DW_IC_ENABLE); 68018dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie} 681f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 68218dbdda89f5cf0540e577280395f16079308e87dDirk Brandewievoid i2c_dw_disable(struct dw_i2c_dev *dev) 68318dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie{ 684f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie /* Disable controller */ 685f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie dw_writel(dev, 0, DW_IC_ENABLE); 686f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 687f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie /* Disable all interupts */ 688f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie dw_writel(dev, 0, DW_IC_INTR_MASK); 689f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie dw_readl(dev, DW_IC_CLR_INTR); 690f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie} 691f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 692f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewievoid i2c_dw_clear_int(struct dw_i2c_dev *dev) 693f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie{ 694f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie dw_readl(dev, DW_IC_CLR_INTR); 695f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie} 696f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 697f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewievoid i2c_dw_disable_int(struct dw_i2c_dev *dev) 698f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie{ 699f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie dw_writel(dev, 0, DW_IC_INTR_MASK); 700f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie} 701f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie 702f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewieu32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) 703f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie{ 704f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie return dw_readl(dev, DW_IC_COMP_PARAM_1); 705f3fa9f3da5621154323775ff0efdba99dcebcee4Dirk Brandewie} 706