1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#include <autoconf.h> 14#include <platsupport/gen_config.h> 15 16/* To extend support, provide platform specific i2c.h and gpio.h and delay.c */ 17#if defined(CONFIG_PLAT_EXYNOS5) || defined(CONFIG_PLAT_EXYNOS4) || defined(CONFIG_PLAT_IMX6) 18 19#include <platsupport/i2c.h> 20#include <platsupport/delay.h> 21#include "../../services.h" 22 23#define DEFAULT_SPEED 100*1000 24 25static inline struct i2c_bb* 26i2c_bus_get_priv(struct i2c_bus* i2c_bus) { 27 return (struct i2c_bb*)i2c_bus->priv; 28} 29 30static inline void 31_hold(struct i2c_bb* d) 32{ 33 ps_udelay(1000000 / d->speed + 1); 34} 35 36static inline void 37pin_l(struct i2c_bb* d, int gpio) 38{ 39 gpio_t g; 40 gpio_new(d->gpio_sys, gpio, GPIO_DIR_OUT, &g); 41 gpio_clr(&g); 42} 43 44static inline int 45pin_r(struct i2c_bb* d, int gpio) 46{ 47 gpio_t g; 48 gpio_new(d->gpio_sys, gpio, GPIO_DIR_IN, &g); 49 return gpio_get(&g); 50} 51 52static inline void 53pin_h(struct i2c_bb* d, int gpio) 54{ 55 pin_r(d, gpio); 56} 57 58static inline int sda_r (struct i2c_bb* d) 59{ 60 return pin_r(d, d->sda); 61} 62static inline void sda_l (struct i2c_bb* d) 63{ 64 pin_l(d, d->sda); 65} 66static inline void sda_h (struct i2c_bb* d) 67{ 68 pin_h(d, d->sda); 69} 70 71static inline void scl_l (struct i2c_bb* d) 72{ 73 pin_l(d, d->scl); 74} 75static inline void scl_h (struct i2c_bb* d) 76{ 77 while (!pin_r(d, d->scl)); 78} 79 80static inline void 81clk(struct i2c_bb* d) 82{ 83 _hold (d); 84 scl_h (d); 85 _hold (d); 86 scl_l (d); 87} 88 89static inline void 90i2c_bb_start(struct i2c_bb* d) 91{ 92 /* init */ 93 while (!sda_r(d)); 94 _hold (d); 95 /* Start */ 96 sda_l (d); 97 _hold (d); 98 scl_l (d); 99} 100 101static inline void 102i2c_bb_stop(struct i2c_bb* d) 103{ 104 sda_l (d); 105 _hold (d); 106 scl_h (d); 107 ps_udelay(1000); 108 while (!sda_r(d)); 109 _hold (d); 110} 111 112static inline void 113i2c_bb_sendbit(struct i2c_bb* d, int bit) 114{ 115 /* Setup bit */ 116 if (bit) { 117 sda_h (d); 118 } else { 119 sda_l (d); 120 } 121 _hold (d); 122 /* Raise clock, wait for clock stretching */ 123 scl_h (d); 124 _hold (d); 125 /* Lower clock */ 126 scl_l (d); 127} 128 129static inline int 130i2c_bb_readbit(struct i2c_bb* d) 131{ 132 int bit; 133 /* Release SDA */ 134 sda_r (d); 135 _hold (d); 136 /* Raise clock, wait for clock stretching */ 137 scl_h (d); 138 /* Data now read to be read */ 139 bit = sda_r(d); 140 _hold (d); 141 scl_l (d); 142 return bit; 143} 144 145static int 146i2c_bb_sendbyte(struct i2c_bb* d, char b) 147{ 148 int i; 149 unsigned char mask = 0x80; 150 for (i = 0; i < 8; i++) { 151 i2c_bb_sendbit(d, !!(b & mask)); 152 mask >>= 1; 153 } 154 /* ACK */ 155 return i2c_bb_readbit(d); 156} 157 158static int 159i2c_bb_readbyte(struct i2c_bb* d, int send_nak) 160{ 161 int i; 162 char data = 0; 163 for (i = 0; i < 8; i++) { 164 data <<= 1; 165 data |= (i2c_bb_readbit(d)) ? 1 : 0; 166 } 167 i2c_bb_sendbit(d, send_nak); 168 return data; 169} 170 171static int 172i2c_bb_read(i2c_bus_t* bus, void* buf, size_t size, 173 UNUSED bool end_with_repeat_start, 174 i2c_callback_fn cb, void* token) 175{ 176 assert(!"Not implemented\n"); 177 return -1; 178} 179 180static int 181i2c_bb_write(i2c_bus_t* bus, const void* buf, size_t size, 182 UNUSED bool end_with_repeat_start, 183 i2c_callback_fn cb, void* token) 184{ 185 assert(!"Not implemented\n"); 186 return -1; 187} 188 189static int 190i2c_bb_master_stop(i2c_bus_t* bus) 191{ 192 assert(!"Not implemented\n"); 193 return -1; 194} 195 196static int 197i2c_bb_start_read(i2c_slave_t *sl, 198 void* vdata, size_t size, 199 UNUSED bool end_with_repeat_start, 200 i2c_callback_fn cb, void* token) 201{ 202 struct i2c_bb* d; 203 int nak; 204 int count; 205 char* data = (char*)vdata; 206 207 assert(sl != NULL && sl->bus != NULL); 208 209 d = i2c_bus_get_priv(sl->bus); 210 211 i2c_bb_start(d); 212 nak = i2c_bb_sendbyte(d, sl->address | 1); 213 if (nak) { 214 i2c_bb_stop(d); 215 return -1; 216 } 217 218 for (count = 0; !nak && count < size; count++) { 219 *data++ = i2c_bb_readbyte(d, count + 1 == size); 220 } 221 222 i2c_bb_stop(d); 223 if (cb) { 224 cb(sl->bus, I2CSTAT_COMPLETE, size, token); 225 } 226 return count; 227} 228 229static int 230i2c_bb_start_write(i2c_slave_t *sl, 231 const void* vdata, size_t size, 232 UNUSED bool end_with_repeat_start, 233 i2c_callback_fn cb, void* token) 234{ 235 struct i2c_bb* d; 236 int nak; 237 int count; 238 const char* data = (const char*)vdata; 239 240 assert(sl != NULL && sl->bus != NULL); 241 242 d = i2c_bus_get_priv(sl->bus); 243 244 i2c_bb_start(d); 245 nak = i2c_bb_sendbyte(d, sl->address & ~1); 246 if (nak) { 247 return -1; 248 } 249 250 for (count = 0; !nak && count < size; count++) { 251 i2c_bb_sendbyte(d, *data++); 252 } 253 254 i2c_bb_stop(d); 255 if (cb) { 256 cb(sl->bus, I2CSTAT_COMPLETE, size, token); 257 } 258 return count; 259} 260 261static void 262i2c_bb_handle_irq(i2c_bus_t* i2c_bus) 263{ 264 struct i2c_bb* d; 265 /* BB is a blocking call, but in case someone tried to poll, we ignore the call */ 266 d = i2c_bus_get_priv(i2c_bus); 267 (void)d; 268} 269 270static int 271i2c_bb_set_self_slave_address(i2c_bus_t *i2c_bus, int addr) 272{ 273 struct i2c_bb* d; 274 d = i2c_bus_get_priv(i2c_bus); 275 (void)d; 276 assert(!"Not implemented"); 277 return -1; 278} 279 280static void 281i2c_bb_register_slave_event_handler(i2c_bus_t *bus, 282 i2c_aas_callback_fn aas_cb, void* aas_token) 283{ 284 assert(bus != NULL); 285 bus->aas_cb = aas_cb; 286 bus->aas_token = aas_token; 287} 288 289static const uint32_t i2c_speed_freqs[] = { 290 [I2C_SLAVE_SPEED_STANDARD] = 100000, 291 [I2C_SLAVE_SPEED_FAST] = 400000, 292 [I2C_SLAVE_SPEED_FASTPLUS] = 1000000, 293 [I2C_SLAVE_SPEED_HIGHSPEED] = 3400000 294}; 295 296static long 297i2c_bb_set_speed(i2c_bus_t* i2c_bus, enum i2c_slave_speed speed) 298{ 299 struct i2c_bb* d; 300 d = i2c_bus_get_priv(i2c_bus); 301 302 if (speed < I2C_SLAVE_SPEED_STANDARD || speed > I2C_SLAVE_SPEED_HIGHSPEED) { 303 ZF_LOGE("lib I2C-bitbang: Unsupported speed %d.", speed); 304 return -1; 305 } 306 307 d->speed = i2c_speed_freqs[speed]; 308 return speed; 309} 310 311static int 312i2c_bb_slave_init(i2c_bus_t* i2c_bus, int address, 313 enum i2c_slave_address_size address_size, 314 enum i2c_slave_speed max_speed, 315 uint32_t flags, 316 i2c_slave_t* sl) 317{ 318 assert(sl != NULL); 319 320 sl->address = address; 321 sl->address_size = address_size; 322 sl->max_speed = max_speed; 323 sl->i2c_opts = 0; 324 sl->bus = i2c_bus; 325 326 sl->slave_read = &i2c_bb_start_read; 327 sl->slave_write = &i2c_bb_start_write; 328 329 return 0; 330} 331 332int 333i2c_bb_init(gpio_sys_t* gpio_sys, gpio_id_t scl, gpio_id_t sda, 334 struct i2c_bb* i2c_bb, struct i2c_bus* i2c) 335{ 336 /* Initialise the BB structure */ 337 i2c_bb->scl = scl; 338 i2c_bb->sda = sda; 339 i2c_bb->speed = DEFAULT_SPEED; 340 i2c_bb->gpio_sys = gpio_sys; 341 /* Initialise the I2C bus structure */ 342 i2c->slave_init = i2c_bb_slave_init; 343 i2c->read = i2c_bb_read; 344 i2c->write = i2c_bb_write; 345 i2c->set_speed = i2c_bb_set_speed; 346 i2c->set_self_slave_address = i2c_bb_set_self_slave_address; 347 i2c->register_slave_event_handler = i2c_bb_register_slave_event_handler; 348 i2c->master_stop = i2c_bb_master_stop; 349 i2c->handle_irq = i2c_bb_handle_irq; 350 i2c->priv = (void*)i2c_bb; 351 /* Done */ 352 return 0; 353} 354 355#endif 356