1 /* 2 * Copyright (C) 2009 Sergey Kubushyn <ksi@koi8.net> 3 * 4 * (C) Copyright 2012 5 * Heiko Schocher, DENX Software Engineering, hs@denx.de. 6 * 7 * Multibus/multiadapter I2C core functions (wrappers) 8 * 9 * SPDX-License-Identifier: GPL-2.0+ 10 */ 11 #include <common.h> 12 #include <i2c.h> 13 14 struct i2c_adapter *i2c_get_adapter(int index) 15 { 16 struct i2c_adapter *i2c_adap_p = ll_entry_start(struct i2c_adapter, 17 i2c); 18 int max = ll_entry_count(struct i2c_adapter, i2c); 19 int i; 20 21 if (index >= max) { 22 printf("Error, wrong i2c adapter %d max %d possible\n", 23 index, max); 24 return i2c_adap_p; 25 } 26 if (index == 0) 27 return i2c_adap_p; 28 29 for (i = 0; i < index; i++) 30 i2c_adap_p++; 31 32 return i2c_adap_p; 33 } 34 35 #if !defined(CONFIG_SYS_I2C_DIRECT_BUS) 36 struct i2c_bus_hose i2c_bus[CONFIG_SYS_NUM_I2C_BUSES] = 37 CONFIG_SYS_I2C_BUSES; 38 #endif 39 40 DECLARE_GLOBAL_DATA_PTR; 41 42 void i2c_reloc_fixup(void) 43 { 44 #if defined(CONFIG_NEEDS_MANUAL_RELOC) 45 struct i2c_adapter *i2c_adap_p = ll_entry_start(struct i2c_adapter, 46 i2c); 47 struct i2c_adapter *tmp = i2c_adap_p; 48 int max = ll_entry_count(struct i2c_adapter, i2c); 49 int i; 50 unsigned long addr; 51 52 if (gd->reloc_off == 0) 53 return; 54 55 for (i = 0; i < max; i++) { 56 /* i2c_init() */ 57 addr = (unsigned long)i2c_adap_p->init; 58 addr += gd->reloc_off; 59 i2c_adap_p->init = (void (*)(int, int))addr; 60 /* i2c_probe() */ 61 addr = (unsigned long)i2c_adap_p->probe; 62 addr += gd->reloc_off; 63 i2c_adap_p->probe = (int (*)(uint8_t))addr; 64 /* i2c_read() */ 65 addr = (unsigned long)i2c_adap_p->read; 66 addr += gd->reloc_off; 67 i2c_adap_p->read = (int (*)(uint8_t, uint, int, uint8_t *, 68 int))addr; 69 /* i2c_write() */ 70 addr = (unsigned long)i2c_adap_p->write; 71 addr += gd->reloc_off; 72 i2c_adap_p->write = (int (*)(uint8_t, uint, int, uint8_t *, 73 int))addr; 74 /* i2c_set_bus_speed() */ 75 addr = (unsigned long)i2c_adap_p->set_bus_speed; 76 addr += gd->reloc_off; 77 i2c_adap_p->set_bus_speed = (uint (*)(uint))addr; 78 /* name */ 79 addr = (unsigned long)i2c_adap_p->name; 80 addr += gd->reloc_off; 81 i2c_adap_p->name = (char *)addr; 82 tmp++; 83 i2c_adap_p = tmp; 84 } 85 #endif 86 } 87 88 #ifndef CONFIG_SYS_I2C_DIRECT_BUS 89 /* 90 * i2c_mux_set() 91 * ------------- 92 * 93 * This turns on the given channel on I2C multiplexer chip connected to 94 * a given I2C adapter directly or via other multiplexers. In the latter 95 * case the entire multiplexer chain must be initialized first starting 96 * with the one connected directly to the adapter. When disabling a chain 97 * muxes must be programmed in reverse order, starting with the one 98 * farthest from the adapter. 99 * 100 * mux_id is the multiplexer chip type from defined in i2c.h. So far only 101 * NXP (Philips) PCA954x multiplexers are supported. Switches are NOT 102 * supported (anybody uses them?) 103 */ 104 105 static int i2c_mux_set(struct i2c_adapter *adap, int mux_id, int chip, 106 int channel) 107 { 108 uint8_t buf; 109 int ret; 110 111 /* channel < 0 - turn off the mux */ 112 if (channel < 0) { 113 buf = 0; 114 ret = adap->write(adap, chip, 0, 0, &buf, 1); 115 if (ret) 116 printf("%s: Could not turn off the mux.\n", __func__); 117 return ret; 118 } 119 120 switch (mux_id) { 121 case I2C_MUX_PCA9540_ID: 122 case I2C_MUX_PCA9542_ID: 123 if (channel > 1) 124 return -1; 125 buf = (uint8_t)((channel & 0x01) | (1 << 2)); 126 break; 127 case I2C_MUX_PCA9544_ID: 128 if (channel > 3) 129 return -1; 130 buf = (uint8_t)((channel & 0x03) | (1 << 2)); 131 break; 132 case I2C_MUX_PCA9547_ID: 133 if (channel > 7) 134 return -1; 135 buf = (uint8_t)((channel & 0x07) | (1 << 3)); 136 break; 137 case I2C_MUX_PCA9548_ID: 138 if (channel > 7) 139 return -1; 140 buf = (uint8_t)(0x01 << channel); 141 break; 142 default: 143 printf("%s: wrong mux id: %d\n", __func__, mux_id); 144 return -1; 145 } 146 147 ret = adap->write(adap, chip, 0, 0, &buf, 1); 148 if (ret) 149 printf("%s: could not set mux: id: %d chip: %x channel: %d\n", 150 __func__, mux_id, chip, channel); 151 return ret; 152 } 153 154 static int i2c_mux_set_all(void) 155 { 156 struct i2c_bus_hose *i2c_bus_tmp = &i2c_bus[I2C_BUS]; 157 int i; 158 159 /* Connect requested bus if behind muxes */ 160 if (i2c_bus_tmp->next_hop[0].chip != 0) { 161 /* Set all muxes along the path to that bus */ 162 for (i = 0; i < CONFIG_SYS_I2C_MAX_HOPS; i++) { 163 int ret; 164 165 if (i2c_bus_tmp->next_hop[i].chip == 0) 166 break; 167 168 ret = i2c_mux_set(I2C_ADAP, 169 i2c_bus_tmp->next_hop[i].mux.id, 170 i2c_bus_tmp->next_hop[i].chip, 171 i2c_bus_tmp->next_hop[i].channel); 172 if (ret != 0) 173 return ret; 174 } 175 } 176 return 0; 177 } 178 179 static int i2c_mux_disconnet_all(void) 180 { 181 struct i2c_bus_hose *i2c_bus_tmp = &i2c_bus[I2C_BUS]; 182 int i; 183 uint8_t buf; 184 185 if (I2C_ADAP->init_done == 0) 186 return 0; 187 188 /* Disconnect current bus (turn off muxes if any) */ 189 if ((i2c_bus_tmp->next_hop[0].chip != 0) && 190 (I2C_ADAP->init_done != 0)) { 191 i = CONFIG_SYS_I2C_MAX_HOPS; 192 do { 193 uint8_t chip; 194 int ret; 195 196 chip = i2c_bus_tmp->next_hop[--i].chip; 197 if (chip == 0) 198 continue; 199 200 ret = I2C_ADAP->write(I2C_ADAP, chip, 0, 0, &buf, 1); 201 if (ret != 0) { 202 printf("i2c: mux diconnect error\n"); 203 return ret; 204 } 205 } while (i > 0); 206 } 207 208 return 0; 209 } 210 #endif 211 212 /* 213 * i2c_init_bus(): 214 * --------------- 215 * 216 * Initializes one bus. Will initialize the parent adapter. No current bus 217 * changes, no mux (if any) setup. 218 */ 219 static void i2c_init_bus(unsigned int bus_no, int speed, int slaveaddr) 220 { 221 if (bus_no >= CONFIG_SYS_NUM_I2C_BUSES) 222 return; 223 224 I2C_ADAP->init(I2C_ADAP, speed, slaveaddr); 225 226 if (gd->flags & GD_FLG_RELOC) { 227 I2C_ADAP->init_done = 1; 228 I2C_ADAP->speed = speed; 229 I2C_ADAP->slaveaddr = slaveaddr; 230 } 231 } 232 233 /* implement possible board specific board init */ 234 static void __def_i2c_init_board(void) 235 { 236 } 237 void i2c_init_board(void) 238 __attribute__((weak, alias("__def_i2c_init_board"))); 239 240 /* 241 * i2c_init_all(): 242 * 243 * not longer needed, will deleted. Actual init the SPD_BUS 244 * for compatibility. 245 * i2c_adap[] must be initialized beforehead with function pointers and 246 * data, including speed and slaveaddr. 247 */ 248 void i2c_init_all(void) 249 { 250 i2c_init_board(); 251 i2c_set_bus_num(CONFIG_SYS_SPD_BUS_NUM); 252 return; 253 } 254 255 /* 256 * i2c_get_bus_num(): 257 * ------------------ 258 * 259 * Returns index of currently active I2C bus. Zero-based. 260 */ 261 unsigned int i2c_get_bus_num(void) 262 { 263 return gd->cur_i2c_bus; 264 } 265 266 /* 267 * i2c_set_bus_num(): 268 * ------------------ 269 * 270 * Change the active I2C bus. Subsequent read/write calls will 271 * go to this one. Sets all of the muxes in a proper condition 272 * if that bus is behind muxes. 273 * If previously selected bus is behind the muxes turns off all the 274 * muxes along the path to that bus. 275 * 276 * bus - bus index, zero based 277 * 278 * Returns: 0 on success, not 0 on failure 279 */ 280 int i2c_set_bus_num(unsigned int bus) 281 { 282 int max; 283 284 if ((bus == I2C_BUS) && (I2C_ADAP->init_done > 0)) 285 return 0; 286 287 #ifndef CONFIG_SYS_I2C_DIRECT_BUS 288 if (bus >= CONFIG_SYS_NUM_I2C_BUSES) 289 return -1; 290 #endif 291 292 max = ll_entry_count(struct i2c_adapter, i2c); 293 if (I2C_ADAPTER(bus) >= max) { 294 printf("Error, wrong i2c adapter %d max %d possible\n", 295 I2C_ADAPTER(bus), max); 296 return -2; 297 } 298 299 #ifndef CONFIG_SYS_I2C_DIRECT_BUS 300 i2c_mux_disconnet_all(); 301 #endif 302 303 gd->cur_i2c_bus = bus; 304 if (I2C_ADAP->init_done == 0) 305 i2c_init_bus(bus, I2C_ADAP->speed, I2C_ADAP->slaveaddr); 306 307 #ifndef CONFIG_SYS_I2C_DIRECT_BUS 308 i2c_mux_set_all(); 309 #endif 310 return 0; 311 } 312 313 /* 314 * Probe the given I2C chip address. Returns 0 if a chip responded, 315 * not 0 on failure. 316 */ 317 int i2c_probe(uint8_t chip) 318 { 319 return I2C_ADAP->probe(I2C_ADAP, chip); 320 } 321 322 /* 323 * Read/Write interface: 324 * chip: I2C chip address, range 0..127 325 * addr: Memory (register) address within the chip 326 * alen: Number of bytes to use for addr (typically 1, 2 for larger 327 * memories, 0 for register type devices with only one 328 * register) 329 * buffer: Where to read/write the data 330 * len: How many bytes to read/write 331 * 332 * Returns: 0 on success, not 0 on failure 333 */ 334 int i2c_read(uint8_t chip, unsigned int addr, int alen, 335 uint8_t *buffer, int len) 336 { 337 return I2C_ADAP->read(I2C_ADAP, chip, addr, alen, buffer, len); 338 } 339 340 int i2c_write(uint8_t chip, unsigned int addr, int alen, 341 uint8_t *buffer, int len) 342 { 343 return I2C_ADAP->write(I2C_ADAP, chip, addr, alen, buffer, len); 344 } 345 346 unsigned int i2c_set_bus_speed(unsigned int speed) 347 { 348 unsigned int ret; 349 350 if (I2C_ADAP->set_bus_speed == NULL) 351 return 0; 352 ret = I2C_ADAP->set_bus_speed(I2C_ADAP, speed); 353 if (gd->flags & GD_FLG_RELOC) 354 I2C_ADAP->speed = ret; 355 356 return ret; 357 } 358 359 unsigned int i2c_get_bus_speed(void) 360 { 361 struct i2c_adapter *cur = I2C_ADAP; 362 return cur->speed; 363 } 364 365 uint8_t i2c_reg_read(uint8_t addr, uint8_t reg) 366 { 367 uint8_t buf; 368 369 #ifdef CONFIG_8xx 370 /* MPC8xx needs this. Maybe one day we can get rid of it. */ 371 /* maybe it is now the time for it ... */ 372 i2c_set_bus_num(i2c_get_bus_num()); 373 #endif 374 i2c_read(addr, reg, 1, &buf, 1); 375 376 #ifdef DEBUG 377 printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n", 378 __func__, i2c_get_bus_num(), addr, reg, buf); 379 #endif 380 381 return buf; 382 } 383 384 void i2c_reg_write(uint8_t addr, uint8_t reg, uint8_t val) 385 { 386 #ifdef CONFIG_8xx 387 /* MPC8xx needs this. Maybe one day we can get rid of it. */ 388 /* maybe it is now the time for it ... */ 389 i2c_set_bus_num(i2c_get_bus_num()); 390 #endif 391 392 #ifdef DEBUG 393 printf("%s: bus=%d addr=0x%02x, reg=0x%02x, val=0x%02x\n", 394 __func__, i2c_get_bus_num(), addr, reg, val); 395 #endif 396 397 i2c_write(addr, reg, 1, &val, 1); 398 } 399 400 void __i2c_init(int speed, int slaveaddr) 401 { 402 i2c_init_bus(i2c_get_bus_num(), speed, slaveaddr); 403 } 404 void i2c_init(int speed, int slaveaddr) 405 __attribute__((weak, alias("__i2c_init"))); 406