1 /* 2 * Faraday I2C Controller 3 * 4 * (C) Copyright 2010 Faraday Technology 5 * Dante Su <dantesu@faraday-tech.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 * 9 * NOTE: This driver should be converted to driver model before June 2017. 10 * Please see doc/driver-model/i2c-howto.txt for instructions. 11 */ 12 13 #include <common.h> 14 #include <asm/io.h> 15 #include <i2c.h> 16 17 #include "fti2c010.h" 18 19 #ifndef CONFIG_SYS_I2C_SPEED 20 #define CONFIG_SYS_I2C_SPEED 5000 21 #endif 22 23 #ifndef CONFIG_SYS_I2C_SLAVE 24 #define CONFIG_SYS_I2C_SLAVE 0 25 #endif 26 27 #ifndef CONFIG_FTI2C010_CLOCK 28 #define CONFIG_FTI2C010_CLOCK clk_get_rate("I2C") 29 #endif 30 31 #ifndef CONFIG_FTI2C010_TIMEOUT 32 #define CONFIG_FTI2C010_TIMEOUT 10 /* ms */ 33 #endif 34 35 /* 7-bit dev address + 1-bit read/write */ 36 #define I2C_RD(dev) ((((dev) << 1) & 0xfe) | 1) 37 #define I2C_WR(dev) (((dev) << 1) & 0xfe) 38 39 struct fti2c010_chip { 40 struct fti2c010_regs *regs; 41 }; 42 43 static struct fti2c010_chip chip_list[] = { 44 { 45 .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE, 46 }, 47 #ifdef CONFIG_FTI2C010_BASE1 48 { 49 .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE1, 50 }, 51 #endif 52 #ifdef CONFIG_FTI2C010_BASE2 53 { 54 .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE2, 55 }, 56 #endif 57 #ifdef CONFIG_FTI2C010_BASE3 58 { 59 .regs = (struct fti2c010_regs *)CONFIG_FTI2C010_BASE3, 60 }, 61 #endif 62 }; 63 64 static int fti2c010_reset(struct fti2c010_chip *chip) 65 { 66 ulong ts; 67 int ret = -1; 68 struct fti2c010_regs *regs = chip->regs; 69 70 writel(CR_I2CRST, ®s->cr); 71 for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) { 72 if (!(readl(®s->cr) & CR_I2CRST)) { 73 ret = 0; 74 break; 75 } 76 } 77 78 if (ret) 79 printf("fti2c010: reset timeout\n"); 80 81 return ret; 82 } 83 84 static int fti2c010_wait(struct fti2c010_chip *chip, uint32_t mask) 85 { 86 int ret = -1; 87 uint32_t stat, ts; 88 struct fti2c010_regs *regs = chip->regs; 89 90 for (ts = get_timer(0); get_timer(ts) < CONFIG_FTI2C010_TIMEOUT; ) { 91 stat = readl(®s->sr); 92 if ((stat & mask) == mask) { 93 ret = 0; 94 break; 95 } 96 } 97 98 return ret; 99 } 100 101 static unsigned int set_i2c_bus_speed(struct fti2c010_chip *chip, 102 unsigned int speed) 103 { 104 struct fti2c010_regs *regs = chip->regs; 105 unsigned int clk = CONFIG_FTI2C010_CLOCK; 106 unsigned int gsr = 0; 107 unsigned int tsr = 32; 108 unsigned int div, rate; 109 110 for (div = 0; div < 0x3ffff; ++div) { 111 /* SCLout = PCLK/(2*(COUNT + 2) + GSR) */ 112 rate = clk / (2 * (div + 2) + gsr); 113 if (rate <= speed) 114 break; 115 } 116 117 writel(TGSR_GSR(gsr) | TGSR_TSR(tsr), ®s->tgsr); 118 writel(CDR_DIV(div), ®s->cdr); 119 120 return rate; 121 } 122 123 /* 124 * Initialization, must be called once on start up, may be called 125 * repeatedly to change the speed and slave addresses. 126 */ 127 static void fti2c010_init(struct i2c_adapter *adap, int speed, int slaveaddr) 128 { 129 struct fti2c010_chip *chip = chip_list + adap->hwadapnr; 130 131 if (adap->init_done) 132 return; 133 134 #ifdef CONFIG_SYS_I2C_INIT_BOARD 135 /* Call board specific i2c bus reset routine before accessing the 136 * environment, which might be in a chip on that bus. For details 137 * about this problem see doc/I2C_Edge_Conditions. 138 */ 139 i2c_init_board(); 140 #endif 141 142 /* master init */ 143 144 fti2c010_reset(chip); 145 146 set_i2c_bus_speed(chip, speed); 147 148 /* slave init, don't care */ 149 150 #ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT 151 /* Call board specific i2c bus reset routine AFTER the bus has been 152 * initialized. Use either this callpoint or i2c_init_board; 153 * which is called before fti2c010_init operations. 154 * For details about this problem see doc/I2C_Edge_Conditions. 155 */ 156 i2c_board_late_init(); 157 #endif 158 } 159 160 /* 161 * Probe the given I2C chip address. Returns 0 if a chip responded, 162 * not 0 on failure. 163 */ 164 static int fti2c010_probe(struct i2c_adapter *adap, u8 dev) 165 { 166 struct fti2c010_chip *chip = chip_list + adap->hwadapnr; 167 struct fti2c010_regs *regs = chip->regs; 168 int ret; 169 170 /* 1. Select slave device (7bits Address + 1bit R/W) */ 171 writel(I2C_WR(dev), ®s->dr); 172 writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); 173 ret = fti2c010_wait(chip, SR_DT); 174 if (ret) 175 return ret; 176 177 /* 2. Select device register */ 178 writel(0, ®s->dr); 179 writel(CR_ENABLE | CR_TBEN, ®s->cr); 180 ret = fti2c010_wait(chip, SR_DT); 181 182 return ret; 183 } 184 185 static void to_i2c_addr(u8 *buf, uint32_t addr, int alen) 186 { 187 int i, shift; 188 189 if (!buf || alen <= 0) 190 return; 191 192 /* MSB first */ 193 i = 0; 194 shift = (alen - 1) * 8; 195 while (alen-- > 0) { 196 buf[i] = (u8)(addr >> shift); 197 shift -= 8; 198 } 199 } 200 201 static int fti2c010_read(struct i2c_adapter *adap, 202 u8 dev, uint addr, int alen, uchar *buf, int len) 203 { 204 struct fti2c010_chip *chip = chip_list + adap->hwadapnr; 205 struct fti2c010_regs *regs = chip->regs; 206 int ret, pos; 207 uchar paddr[4] = { 0 }; 208 209 to_i2c_addr(paddr, addr, alen); 210 211 /* 212 * Phase A. Set register address 213 */ 214 215 /* A.1 Select slave device (7bits Address + 1bit R/W) */ 216 writel(I2C_WR(dev), ®s->dr); 217 writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); 218 ret = fti2c010_wait(chip, SR_DT); 219 if (ret) 220 return ret; 221 222 /* A.2 Select device register */ 223 for (pos = 0; pos < alen; ++pos) { 224 uint32_t ctrl = CR_ENABLE | CR_TBEN; 225 226 writel(paddr[pos], ®s->dr); 227 writel(ctrl, ®s->cr); 228 ret = fti2c010_wait(chip, SR_DT); 229 if (ret) 230 return ret; 231 } 232 233 /* 234 * Phase B. Get register data 235 */ 236 237 /* B.1 Select slave device (7bits Address + 1bit R/W) */ 238 writel(I2C_RD(dev), ®s->dr); 239 writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); 240 ret = fti2c010_wait(chip, SR_DT); 241 if (ret) 242 return ret; 243 244 /* B.2 Get register data */ 245 for (pos = 0; pos < len; ++pos) { 246 uint32_t ctrl = CR_ENABLE | CR_TBEN; 247 uint32_t stat = SR_DR; 248 249 if (pos == len - 1) { 250 ctrl |= CR_NAK | CR_STOP; 251 stat |= SR_ACK; 252 } 253 writel(ctrl, ®s->cr); 254 ret = fti2c010_wait(chip, stat); 255 if (ret) 256 break; 257 buf[pos] = (uchar)(readl(®s->dr) & 0xFF); 258 } 259 260 return ret; 261 } 262 263 static int fti2c010_write(struct i2c_adapter *adap, 264 u8 dev, uint addr, int alen, u8 *buf, int len) 265 { 266 struct fti2c010_chip *chip = chip_list + adap->hwadapnr; 267 struct fti2c010_regs *regs = chip->regs; 268 int ret, pos; 269 uchar paddr[4] = { 0 }; 270 271 to_i2c_addr(paddr, addr, alen); 272 273 /* 274 * Phase A. Set register address 275 * 276 * A.1 Select slave device (7bits Address + 1bit R/W) 277 */ 278 writel(I2C_WR(dev), ®s->dr); 279 writel(CR_ENABLE | CR_TBEN | CR_START, ®s->cr); 280 ret = fti2c010_wait(chip, SR_DT); 281 if (ret) 282 return ret; 283 284 /* A.2 Select device register */ 285 for (pos = 0; pos < alen; ++pos) { 286 uint32_t ctrl = CR_ENABLE | CR_TBEN; 287 288 writel(paddr[pos], ®s->dr); 289 writel(ctrl, ®s->cr); 290 ret = fti2c010_wait(chip, SR_DT); 291 if (ret) 292 return ret; 293 } 294 295 /* 296 * Phase B. Set register data 297 */ 298 for (pos = 0; pos < len; ++pos) { 299 uint32_t ctrl = CR_ENABLE | CR_TBEN; 300 301 if (pos == len - 1) 302 ctrl |= CR_STOP; 303 writel(buf[pos], ®s->dr); 304 writel(ctrl, ®s->cr); 305 ret = fti2c010_wait(chip, SR_DT); 306 if (ret) 307 break; 308 } 309 310 return ret; 311 } 312 313 static unsigned int fti2c010_set_bus_speed(struct i2c_adapter *adap, 314 unsigned int speed) 315 { 316 struct fti2c010_chip *chip = chip_list + adap->hwadapnr; 317 int ret; 318 319 fti2c010_reset(chip); 320 ret = set_i2c_bus_speed(chip, speed); 321 322 return ret; 323 } 324 325 /* 326 * Register i2c adapters 327 */ 328 U_BOOT_I2C_ADAP_COMPLETE(i2c_0, fti2c010_init, fti2c010_probe, fti2c010_read, 329 fti2c010_write, fti2c010_set_bus_speed, 330 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 331 0) 332 #ifdef CONFIG_FTI2C010_BASE1 333 U_BOOT_I2C_ADAP_COMPLETE(i2c_1, fti2c010_init, fti2c010_probe, fti2c010_read, 334 fti2c010_write, fti2c010_set_bus_speed, 335 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 336 1) 337 #endif 338 #ifdef CONFIG_FTI2C010_BASE2 339 U_BOOT_I2C_ADAP_COMPLETE(i2c_2, fti2c010_init, fti2c010_probe, fti2c010_read, 340 fti2c010_write, fti2c010_set_bus_speed, 341 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 342 2) 343 #endif 344 #ifdef CONFIG_FTI2C010_BASE3 345 U_BOOT_I2C_ADAP_COMPLETE(i2c_3, fti2c010_init, fti2c010_probe, fti2c010_read, 346 fti2c010_write, fti2c010_set_bus_speed, 347 CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 348 3) 349 #endif 350