1 /* 2 * Faraday I2C Controller 3 * 4 * (C) Copyright 2010 Faraday Technology 5 * Dante Su <dantesu@faraday-tech.com> 6 * 7 * This file is released under the terms of GPL v2 and any later version. 8 * See the file COPYING in the root directory of the source tree for details. 9 */ 10 11 #include <common.h> 12 #include <asm/io.h> 13 #include <i2c.h> 14 15 #include "fti2c010.h" 16 17 #ifndef CONFIG_HARD_I2C 18 #error "fti2c010: CONFIG_HARD_I2C is not defined" 19 #endif 20 21 #ifndef CONFIG_SYS_I2C_SPEED 22 #define CONFIG_SYS_I2C_SPEED 50000 23 #endif 24 25 #ifndef CONFIG_FTI2C010_FREQ 26 #define CONFIG_FTI2C010_FREQ clk_get_rate("I2C") 27 #endif 28 29 /* command timeout */ 30 #define CFG_CMD_TIMEOUT 10 /* ms */ 31 32 /* 7-bit chip address + 1-bit read/write */ 33 #define I2C_RD(chip) ((((chip) << 1) & 0xff) | 1) 34 #define I2C_WR(chip) (((chip) << 1) & 0xff) 35 36 struct fti2c010_chip { 37 void __iomem *regs; 38 uint bus; 39 uint speed; 40 }; 41 42 static struct fti2c010_chip chip_list[] = { 43 { 44 .bus = 0, 45 .regs = (void __iomem *)CONFIG_FTI2C010_BASE, 46 }, 47 #ifdef CONFIG_I2C_MULTI_BUS 48 # ifdef CONFIG_FTI2C010_BASE1 49 { 50 .bus = 1, 51 .regs = (void __iomem *)CONFIG_FTI2C010_BASE1, 52 }, 53 # endif 54 # ifdef CONFIG_FTI2C010_BASE2 55 { 56 .bus = 2, 57 .regs = (void __iomem *)CONFIG_FTI2C010_BASE2, 58 }, 59 # endif 60 # ifdef CONFIG_FTI2C010_BASE3 61 { 62 .bus = 3, 63 .regs = (void __iomem *)CONFIG_FTI2C010_BASE3, 64 }, 65 # endif 66 #endif /* #ifdef CONFIG_I2C_MULTI_BUS */ 67 }; 68 69 static struct fti2c010_chip *curr = chip_list; 70 71 static int fti2c010_wait(uint32_t mask) 72 { 73 int ret = -1; 74 uint32_t stat, ts; 75 struct fti2c010_regs *regs = curr->regs; 76 77 for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { 78 stat = readl(®s->sr); 79 if ((stat & mask) == mask) { 80 ret = 0; 81 break; 82 } 83 } 84 85 return ret; 86 } 87 88 /* 89 * u-boot I2C API 90 */ 91 92 /* 93 * Initialization, must be called once on start up, may be called 94 * repeatedly to change the speed and slave addresses. 95 */ 96 void i2c_init(int speed, int slaveaddr) 97 { 98 if (speed || !curr->speed) 99 i2c_set_bus_speed(speed); 100 101 /* if slave mode disabled */ 102 if (!slaveaddr) 103 return; 104 105 /* 106 * TODO: 107 * Implement slave mode, but is it really necessary? 108 */ 109 } 110 111 /* 112 * Probe the given I2C chip address. Returns 0 if a chip responded, 113 * not 0 on failure. 114 */ 115 int i2c_probe(uchar chip) 116 { 117 int ret; 118 struct fti2c010_regs *regs = curr->regs; 119 120 i2c_init(0, 0); 121 122 /* 1. Select slave device (7bits Address + 1bit R/W) */ 123 writel(I2C_WR(chip), ®s->dr); 124 writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); 125 ret = fti2c010_wait(SR_DT); 126 if (ret) 127 return ret; 128 129 /* 2. Select device register */ 130 writel(0, ®s->dr); 131 writel(CR_ENABLE | CR_TBEN, ®s->cr); 132 ret = fti2c010_wait(SR_DT); 133 134 return ret; 135 } 136 137 /* 138 * Read/Write interface: 139 * chip: I2C chip address, range 0..127 140 * addr: Memory (register) address within the chip 141 * alen: Number of bytes to use for addr (typically 1, 2 for larger 142 * memories, 0 for register type devices with only one 143 * register) 144 * buffer: Where to read/write the data 145 * len: How many bytes to read/write 146 * 147 * Returns: 0 on success, not 0 on failure 148 */ 149 int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) 150 { 151 int ret, pos; 152 uchar paddr[4]; 153 struct fti2c010_regs *regs = curr->regs; 154 155 i2c_init(0, 0); 156 157 paddr[0] = (addr >> 0) & 0xFF; 158 paddr[1] = (addr >> 8) & 0xFF; 159 paddr[2] = (addr >> 16) & 0xFF; 160 paddr[3] = (addr >> 24) & 0xFF; 161 162 /* 163 * Phase A. Set register address 164 */ 165 166 /* A.1 Select slave device (7bits Address + 1bit R/W) */ 167 writel(I2C_WR(chip), ®s->dr); 168 writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); 169 ret = fti2c010_wait(SR_DT); 170 if (ret) 171 return ret; 172 173 /* A.2 Select device register */ 174 for (pos = 0; pos < alen; ++pos) { 175 uint32_t ctrl = CR_ENABLE | CR_TBEN; 176 177 writel(paddr[pos], ®s->dr); 178 writel(ctrl, ®s->cr); 179 ret = fti2c010_wait(SR_DT); 180 if (ret) 181 return ret; 182 } 183 184 /* 185 * Phase B. Get register data 186 */ 187 188 /* B.1 Select slave device (7bits Address + 1bit R/W) */ 189 writel(I2C_RD(chip), ®s->dr); 190 writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); 191 ret = fti2c010_wait(SR_DT); 192 if (ret) 193 return ret; 194 195 /* B.2 Get register data */ 196 for (pos = 0; pos < len; ++pos) { 197 uint32_t ctrl = CR_ENABLE | CR_TBEN; 198 uint32_t stat = SR_DR; 199 200 if (pos == len - 1) { 201 ctrl |= CR_NAK | CR_STOP; 202 stat |= SR_ACK; 203 } 204 writel(ctrl, ®s->cr); 205 ret = fti2c010_wait(stat); 206 if (ret) 207 break; 208 buf[pos] = (uchar)(readl(®s->dr) & 0xFF); 209 } 210 211 return ret; 212 } 213 214 /* 215 * Read/Write interface: 216 * chip: I2C chip address, range 0..127 217 * addr: Memory (register) address within the chip 218 * alen: Number of bytes to use for addr (typically 1, 2 for larger 219 * memories, 0 for register type devices with only one 220 * register) 221 * buffer: Where to read/write the data 222 * len: How many bytes to read/write 223 * 224 * Returns: 0 on success, not 0 on failure 225 */ 226 int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) 227 { 228 int ret, pos; 229 uchar paddr[4]; 230 struct fti2c010_regs *regs = curr->regs; 231 232 i2c_init(0, 0); 233 234 paddr[0] = (addr >> 0) & 0xFF; 235 paddr[1] = (addr >> 8) & 0xFF; 236 paddr[2] = (addr >> 16) & 0xFF; 237 paddr[3] = (addr >> 24) & 0xFF; 238 239 /* 240 * Phase A. Set register address 241 * 242 * A.1 Select slave device (7bits Address + 1bit R/W) 243 */ 244 writel(I2C_WR(chip), ®s->dr); 245 writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); 246 ret = fti2c010_wait(SR_DT); 247 if (ret) 248 return ret; 249 250 /* A.2 Select device register */ 251 for (pos = 0; pos < alen; ++pos) { 252 uint32_t ctrl = CR_ENABLE | CR_TBEN; 253 254 writel(paddr[pos], ®s->dr); 255 writel(ctrl, ®s->cr); 256 ret = fti2c010_wait(SR_DT); 257 if (ret) 258 return ret; 259 } 260 261 /* 262 * Phase B. Set register data 263 */ 264 for (pos = 0; pos < len; ++pos) { 265 uint32_t ctrl = CR_ENABLE | CR_TBEN; 266 267 if (pos == len - 1) 268 ctrl |= CR_STOP; 269 writel(buf[pos], ®s->dr); 270 writel(ctrl, ®s->cr); 271 ret = fti2c010_wait(SR_DT); 272 if (ret) 273 break; 274 } 275 276 return ret; 277 } 278 279 /* 280 * Functions for setting the current I2C bus and its speed 281 */ 282 #ifdef CONFIG_I2C_MULTI_BUS 283 284 /* 285 * i2c_set_bus_num: 286 * 287 * Change the active I2C bus. Subsequent read/write calls will 288 * go to this one. 289 * 290 * bus - bus index, zero based 291 * 292 * Returns: 0 on success, not 0 on failure 293 */ 294 int i2c_set_bus_num(uint bus) 295 { 296 if (bus >= ARRAY_SIZE(chip_list)) 297 return -1; 298 curr = chip_list + bus; 299 i2c_init(0, 0); 300 return 0; 301 } 302 303 /* 304 * i2c_get_bus_num: 305 * 306 * Returns index of currently active I2C bus. Zero-based. 307 */ 308 309 uint i2c_get_bus_num(void) 310 { 311 return curr->bus; 312 } 313 314 #endif /* #ifdef CONFIG_I2C_MULTI_BUS */ 315 316 /* 317 * i2c_set_bus_speed: 318 * 319 * Change the speed of the active I2C bus 320 * 321 * speed - bus speed in Hz 322 * 323 * Returns: 0 on success, not 0 on failure 324 */ 325 int i2c_set_bus_speed(uint speed) 326 { 327 struct fti2c010_regs *regs = curr->regs; 328 uint clk = CONFIG_FTI2C010_FREQ; 329 uint gsr = 0, tsr = 32; 330 uint spd, div; 331 332 if (!speed) 333 speed = CONFIG_SYS_I2C_SPEED; 334 335 for (div = 0; div < 0x3ffff; ++div) { 336 /* SCLout = PCLK/(2*(COUNT + 2) + GSR) */ 337 spd = clk / (2 * (div + 2) + gsr); 338 if (spd <= speed) 339 break; 340 } 341 342 if (curr->speed == spd) 343 return 0; 344 345 writel(CR_I2CRST, ®s->cr); 346 mdelay(100); 347 if (readl(®s->cr) & CR_I2CRST) { 348 printf("fti2c010: reset timeout\n"); 349 return -1; 350 } 351 352 curr->speed = spd; 353 354 writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr); 355 writel(CDR_DIV(div), ®s->cdr); 356 357 return 0; 358 } 359 360 /* 361 * i2c_get_bus_speed: 362 * 363 * Returns speed of currently active I2C bus in Hz 364 */ 365 366 uint i2c_get_bus_speed(void) 367 { 368 return curr->speed; 369 } 370