1 /* 2 * (C) Copyright 2009 3 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 #include <asm/io.h> 26 #include <asm/arch/hardware.h> 27 #include "designware_i2c.h" 28 29 static struct i2c_regs *const i2c_regs_p = 30 (struct i2c_regs *)CONFIG_SYS_I2C_BASE; 31 32 /* 33 * set_speed - Set the i2c speed mode (standard, high, fast) 34 * @i2c_spd: required i2c speed mode 35 * 36 * Set the i2c speed mode (standard, high, fast) 37 */ 38 static void set_speed(int i2c_spd) 39 { 40 unsigned int cntl; 41 unsigned int hcnt, lcnt; 42 unsigned int high, low; 43 44 cntl = (readl(&i2c_regs_p->ic_con) & (~IC_CON_SPD_MSK)); 45 46 switch (i2c_spd) { 47 case IC_SPEED_MODE_MAX: 48 cntl |= IC_CON_SPD_HS; 49 high = MIN_HS_SCL_HIGHTIME; 50 low = MIN_HS_SCL_LOWTIME; 51 break; 52 53 case IC_SPEED_MODE_STANDARD: 54 cntl |= IC_CON_SPD_SS; 55 high = MIN_SS_SCL_HIGHTIME; 56 low = MIN_SS_SCL_LOWTIME; 57 break; 58 59 case IC_SPEED_MODE_FAST: 60 default: 61 cntl |= IC_CON_SPD_FS; 62 high = MIN_FS_SCL_HIGHTIME; 63 low = MIN_FS_SCL_LOWTIME; 64 break; 65 } 66 67 writel(cntl, &i2c_regs_p->ic_con); 68 69 hcnt = (IC_CLK * high) / NANO_TO_MICRO; 70 writel(hcnt, &i2c_regs_p->ic_fs_scl_hcnt); 71 72 lcnt = (IC_CLK * low) / NANO_TO_MICRO; 73 writel(lcnt, &i2c_regs_p->ic_fs_scl_lcnt); 74 } 75 76 /* 77 * i2c_set_bus_speed - Set the i2c speed 78 * @speed: required i2c speed 79 * 80 * Set the i2c speed. 81 */ 82 void i2c_set_bus_speed(int speed) 83 { 84 if (speed >= I2C_MAX_SPEED) 85 set_speed(IC_SPEED_MODE_MAX); 86 else if (speed >= I2C_FAST_SPEED) 87 set_speed(IC_SPEED_MODE_FAST); 88 else 89 set_speed(IC_SPEED_MODE_STANDARD); 90 } 91 92 /* 93 * i2c_get_bus_speed - Gets the i2c speed 94 * 95 * Gets the i2c speed. 96 */ 97 int i2c_get_bus_speed(void) 98 { 99 u32 cntl; 100 101 cntl = (readl(&i2c_regs_p->ic_con) & IC_CON_SPD_MSK); 102 103 if (cntl == IC_CON_SPD_HS) 104 return I2C_MAX_SPEED; 105 else if (cntl == IC_CON_SPD_FS) 106 return I2C_FAST_SPEED; 107 else if (cntl == IC_CON_SPD_SS) 108 return I2C_STANDARD_SPEED; 109 110 return 0; 111 } 112 113 /* 114 * i2c_init - Init function 115 * @speed: required i2c speed 116 * @slaveadd: slave address for the device 117 * 118 * Initialization function. 119 */ 120 void i2c_init(int speed, int slaveadd) 121 { 122 unsigned int enbl; 123 124 /* Disable i2c */ 125 enbl = readl(&i2c_regs_p->ic_enable); 126 enbl &= ~IC_ENABLE_0B; 127 writel(enbl, &i2c_regs_p->ic_enable); 128 129 writel((IC_CON_SD | IC_CON_SPD_FS | IC_CON_MM), &i2c_regs_p->ic_con); 130 writel(IC_RX_TL, &i2c_regs_p->ic_rx_tl); 131 writel(IC_TX_TL, &i2c_regs_p->ic_tx_tl); 132 i2c_set_bus_speed(speed); 133 writel(IC_STOP_DET, &i2c_regs_p->ic_intr_mask); 134 writel(slaveadd, &i2c_regs_p->ic_sar); 135 136 /* Enable i2c */ 137 enbl = readl(&i2c_regs_p->ic_enable); 138 enbl |= IC_ENABLE_0B; 139 writel(enbl, &i2c_regs_p->ic_enable); 140 } 141 142 /* 143 * i2c_setaddress - Sets the target slave address 144 * @i2c_addr: target i2c address 145 * 146 * Sets the target slave address. 147 */ 148 static void i2c_setaddress(unsigned int i2c_addr) 149 { 150 writel(i2c_addr, &i2c_regs_p->ic_tar); 151 } 152 153 /* 154 * i2c_flush_rxfifo - Flushes the i2c RX FIFO 155 * 156 * Flushes the i2c RX FIFO 157 */ 158 static void i2c_flush_rxfifo(void) 159 { 160 while (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) 161 readl(&i2c_regs_p->ic_cmd_data); 162 } 163 164 /* 165 * i2c_wait_for_bb - Waits for bus busy 166 * 167 * Waits for bus busy 168 */ 169 static int i2c_wait_for_bb(void) 170 { 171 unsigned long start_time_bb = get_timer(0); 172 173 while ((readl(&i2c_regs_p->ic_status) & IC_STATUS_MA) || 174 !(readl(&i2c_regs_p->ic_status) & IC_STATUS_TFE)) { 175 176 /* Evaluate timeout */ 177 if (get_timer(start_time_bb) > (unsigned long)(I2C_BYTE_TO_BB)) 178 return 1; 179 } 180 181 return 0; 182 } 183 184 /* check parameters for i2c_read and i2c_write */ 185 static int check_params(uint addr, int alen, uchar *buffer, int len) 186 { 187 if (buffer == NULL) { 188 printf("Buffer is invalid\n"); 189 return 1; 190 } 191 192 if (alen > 1) { 193 printf("addr len %d not supported\n", alen); 194 return 1; 195 } 196 197 if (addr + len > 256) { 198 printf("address out of range\n"); 199 return 1; 200 } 201 202 return 0; 203 } 204 205 static int i2c_xfer_init(uchar chip, uint addr) 206 { 207 if (i2c_wait_for_bb()) { 208 printf("Timed out waiting for bus\n"); 209 return 1; 210 } 211 212 i2c_setaddress(chip); 213 writel(addr, &i2c_regs_p->ic_cmd_data); 214 215 return 0; 216 } 217 218 static int i2c_xfer_finish(void) 219 { 220 ulong start_stop_det = get_timer(0); 221 222 while (1) { 223 if ((readl(&i2c_regs_p->ic_raw_intr_stat) & IC_STOP_DET)) { 224 readl(&i2c_regs_p->ic_clr_stop_det); 225 break; 226 } else if (get_timer(start_stop_det) > I2C_STOPDET_TO) { 227 break; 228 } 229 } 230 231 if (i2c_wait_for_bb()) { 232 printf("Timed out waiting for bus\n"); 233 return 1; 234 } 235 236 i2c_flush_rxfifo(); 237 238 /* Wait for read/write operation to complete on actual memory */ 239 udelay(10000); 240 241 return 0; 242 } 243 244 /* 245 * i2c_read - Read from i2c memory 246 * @chip: target i2c address 247 * @addr: address to read from 248 * @alen: 249 * @buffer: buffer for read data 250 * @len: no of bytes to be read 251 * 252 * Read from i2c memory. 253 */ 254 int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) 255 { 256 unsigned long start_time_rx; 257 258 if (check_params(addr, alen, buffer, len)) 259 return 1; 260 261 if (i2c_xfer_init(chip, addr)) 262 return 1; 263 264 start_time_rx = get_timer(0); 265 while (len) { 266 writel(IC_CMD, &i2c_regs_p->ic_cmd_data); 267 268 if (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) { 269 *buffer++ = (uchar)readl(&i2c_regs_p->ic_cmd_data); 270 len--; 271 start_time_rx = get_timer(0); 272 273 } else if (get_timer(start_time_rx) > I2C_BYTE_TO) { 274 printf("Timed out. i2c read Failed\n"); 275 return 1; 276 } 277 } 278 279 return i2c_xfer_finish(); 280 } 281 282 /* 283 * i2c_write - Write to i2c memory 284 * @chip: target i2c address 285 * @addr: address to read from 286 * @alen: 287 * @buffer: buffer for read data 288 * @len: no of bytes to be read 289 * 290 * Write to i2c memory. 291 */ 292 int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) 293 { 294 int nb = len; 295 unsigned long start_time_tx; 296 297 if (check_params(addr, alen, buffer, len)) 298 return 1; 299 300 if (i2c_xfer_init(chip, addr)) 301 return 1; 302 303 start_time_tx = get_timer(0); 304 while (len) { 305 if (readl(&i2c_regs_p->ic_status) & IC_STATUS_TFNF) { 306 writel(*buffer, &i2c_regs_p->ic_cmd_data); 307 buffer++; 308 len--; 309 start_time_tx = get_timer(0); 310 311 } else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) { 312 printf("Timed out. i2c write Failed\n"); 313 return 1; 314 } 315 } 316 317 return i2c_xfer_finish(); 318 } 319 320 /* 321 * i2c_probe - Probe the i2c chip 322 */ 323 int i2c_probe(uchar chip) 324 { 325 u32 tmp; 326 327 /* 328 * Try to read the first location of the chip. 329 */ 330 return i2c_read(chip, 0, 1, (uchar *)&tmp, 1); 331 } 332