1 /* 2 * i2c driver for Freescale mx31 3 * 4 * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> 5 * 6 * See file CREDITS for list of people who contributed to this 7 * project. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22 * MA 02111-1307 USA 23 */ 24 25 #include <common.h> 26 27 #if defined(CONFIG_HARD_I2C) 28 29 #if defined(CONFIG_MX31) 30 #include <asm/arch/mx31.h> 31 #include <asm/arch/mx31-regs.h> 32 #endif 33 34 #if defined(CONFIG_MX53) 35 #include <asm/arch/clock.h> 36 #endif 37 38 #define IADR 0x00 39 #define IFDR 0x04 40 #define I2CR 0x08 41 #define I2SR 0x0c 42 #define I2DR 0x10 43 44 #define I2CR_IEN (1 << 7) 45 #define I2CR_IIEN (1 << 6) 46 #define I2CR_MSTA (1 << 5) 47 #define I2CR_MTX (1 << 4) 48 #define I2CR_TX_NO_AK (1 << 3) 49 #define I2CR_RSTA (1 << 2) 50 51 #define I2SR_ICF (1 << 7) 52 #define I2SR_IBB (1 << 5) 53 #define I2SR_IIF (1 << 1) 54 #define I2SR_RX_NO_AK (1 << 0) 55 56 #if defined(CONFIG_SYS_I2C_MX31_PORT1) 57 #define I2C_BASE 0x43f80000 58 #define I2C_CLK_OFFSET 26 59 #elif defined (CONFIG_SYS_I2C_MX31_PORT2) 60 #define I2C_BASE 0x43f98000 61 #define I2C_CLK_OFFSET 28 62 #elif defined (CONFIG_SYS_I2C_MX31_PORT3) 63 #define I2C_BASE 0x43f84000 64 #define I2C_CLK_OFFSET 30 65 #elif defined(CONFIG_SYS_I2C_MX53_PORT1) 66 #define I2C_BASE I2C1_BASE_ADDR 67 #elif defined(CONFIG_SYS_I2C_MX53_PORT2) 68 #define I2C_BASE I2C2_BASE_ADDR 69 #else 70 #error "define CONFIG_SYS_I2C_MXxx_PORTx to use the I2C driver" 71 #endif 72 73 #ifdef DEBUG 74 #define DPRINTF(args...) printf(args) 75 #else 76 #define DPRINTF(args...) 77 #endif 78 79 static u16 div[] = { 30, 32, 36, 42, 48, 52, 60, 72, 80, 88, 104, 128, 144, 80 160, 192, 240, 288, 320, 384, 480, 576, 640, 768, 960, 81 1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840}; 82 83 void i2c_init(int speed, int unused) 84 { 85 int freq; 86 int i; 87 88 #if defined(CONFIG_MX31) 89 freq = mx31_get_ipg_clk(); 90 /* start the required I2C clock */ 91 __REG(CCM_CGR0) = __REG(CCM_CGR0) | (3 << I2C_CLK_OFFSET); 92 #else 93 freq = mxc_get_clock(MXC_IPG_PERCLK); 94 #endif 95 96 for (i = 0; i < 0x1f; i++) 97 if (freq / div[i] <= speed) 98 break; 99 100 DPRINTF("%s: speed: %d\n",__FUNCTION__, speed); 101 102 __REG16(I2C_BASE + I2CR) = 0; /* Reset module */ 103 __REG16(I2C_BASE + IFDR) = i; 104 __REG16(I2C_BASE + I2CR) = I2CR_IEN; 105 __REG16(I2C_BASE + I2SR) = 0; 106 } 107 108 static int wait_busy(void) 109 { 110 int timeout = 10000; 111 112 while (!(__REG16(I2C_BASE + I2SR) & I2SR_IIF) && --timeout) 113 udelay(1); 114 __REG16(I2C_BASE + I2SR) = 0; /* clear interrupt */ 115 116 return timeout; 117 } 118 119 static int tx_byte(u8 byte) 120 { 121 __REG16(I2C_BASE + I2DR) = byte; 122 123 if (!wait_busy() || __REG16(I2C_BASE + I2SR) & I2SR_RX_NO_AK) 124 return -1; 125 return 0; 126 } 127 128 static int rx_byte(void) 129 { 130 if (!wait_busy()) 131 return -1; 132 133 return __REG16(I2C_BASE + I2DR); 134 } 135 136 int i2c_probe(uchar chip) 137 { 138 int ret; 139 140 __REG16(I2C_BASE + I2CR) = 0; /* Reset module */ 141 __REG16(I2C_BASE + I2CR) = I2CR_IEN; 142 143 __REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX; 144 ret = tx_byte(chip << 1); 145 __REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MTX; 146 147 return ret; 148 } 149 150 static int i2c_addr(uchar chip, uint addr, int alen) 151 { 152 __REG16(I2C_BASE + I2SR) = 0; /* clear interrupt */ 153 __REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX; 154 155 if (tx_byte(chip << 1)) 156 return -1; 157 158 while (alen--) 159 if (tx_byte((addr >> (alen * 8)) & 0xff)) 160 return -1; 161 return 0; 162 } 163 164 int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) 165 { 166 int timeout = 10000; 167 int ret; 168 169 DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",__FUNCTION__, chip, addr, alen, len); 170 171 if (i2c_addr(chip, addr, alen)) { 172 printf("i2c_addr failed\n"); 173 return -1; 174 } 175 176 __REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_MTX | I2CR_RSTA; 177 178 if (tx_byte(chip << 1 | 1)) 179 return -1; 180 181 __REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | ((len == 1) ? I2CR_TX_NO_AK : 0); 182 183 ret = __REG16(I2C_BASE + I2DR); 184 185 while (len--) { 186 if ((ret = rx_byte()) < 0) 187 return -1; 188 *buf++ = ret; 189 if (len <= 1) 190 __REG16(I2C_BASE + I2CR) = I2CR_IEN | I2CR_MSTA | I2CR_TX_NO_AK; 191 } 192 193 wait_busy(); 194 195 __REG16(I2C_BASE + I2CR) = I2CR_IEN; 196 197 while (__REG16(I2C_BASE + I2SR) & I2SR_IBB && --timeout) 198 udelay(1); 199 200 return 0; 201 } 202 203 int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) 204 { 205 int timeout = 10000; 206 DPRINTF("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",__FUNCTION__, chip, addr, alen, len); 207 208 if (i2c_addr(chip, addr, alen)) 209 return -1; 210 211 while (len--) 212 if (tx_byte(*buf++)) 213 return -1; 214 215 __REG16(I2C_BASE + I2CR) = I2CR_IEN; 216 217 while (__REG16(I2C_BASE + I2SR) & I2SR_IBB && --timeout) 218 udelay(1); 219 220 return 0; 221 } 222 223 #endif /* CONFIG_HARD_I2C */ 224