mv_twsi.c revision 295622
1/*- 2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 3 * All rights reserved. 4 * 5 * Developed by Semihalf. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of MARVELL nor the names of contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32/* 33 * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell 34 * SoCs. Supports master operation only, and works in polling mode. 35 * 36 * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software 37 * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices". 38 */ 39 40#include <sys/cdefs.h> 41__FBSDID("$FreeBSD: head/sys/dev/iicbus/twsi/twsi.c 295622 2016-02-14 23:51:13Z andrew $"); 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/bus.h> 46#include <sys/kernel.h> 47#include <sys/module.h> 48#include <sys/resource.h> 49 50#include <machine/_inttypes.h> 51#include <machine/bus.h> 52#include <machine/resource.h> 53 54#include <sys/rman.h> 55 56#include <sys/lock.h> 57#include <sys/mutex.h> 58 59#include <dev/iicbus/iiconf.h> 60#include <dev/iicbus/iicbus.h> 61#include <dev/fdt/fdt_common.h> 62#include <dev/ofw/ofw_bus.h> 63#include <dev/ofw/ofw_bus_subr.h> 64 65#include <arm/mv/mvvar.h> 66 67#include "iicbus_if.h" 68 69#define MV_TWSI_NAME "twsi" 70#define IICBUS_DEVNAME "iicbus" 71 72#define TWSI_SLAVE_ADDR 0x00 73#define TWSI_EXT_SLAVE_ADDR 0x10 74#define TWSI_DATA 0x04 75 76#define TWSI_CONTROL 0x08 77#define TWSI_CONTROL_ACK (1 << 2) 78#define TWSI_CONTROL_IFLG (1 << 3) 79#define TWSI_CONTROL_STOP (1 << 4) 80#define TWSI_CONTROL_START (1 << 5) 81#define TWSI_CONTROL_TWSIEN (1 << 6) 82#define TWSI_CONTROL_INTEN (1 << 7) 83 84#define TWSI_STATUS 0x0c 85#define TWSI_STATUS_START 0x08 86#define TWSI_STATUS_RPTD_START 0x10 87#define TWSI_STATUS_ADDR_W_ACK 0x18 88#define TWSI_STATUS_DATA_WR_ACK 0x28 89#define TWSI_STATUS_ADDR_R_ACK 0x40 90#define TWSI_STATUS_DATA_RD_ACK 0x50 91#define TWSI_STATUS_DATA_RD_NOACK 0x58 92 93#define TWSI_BAUD_RATE 0x0c 94#define TWSI_BAUD_RATE_PARAM(M,N) ((((M) << 3) | ((N) & 0x7)) & 0x7f) 95#define TWSI_BAUD_RATE_RAW(C,M,N) ((C)/((10*(M+1))<<(N+1))) 96#define TWSI_BAUD_RATE_SLOW 50000 /* 50kHz */ 97#define TWSI_BAUD_RATE_FAST 100000 /* 100kHz */ 98 99#define TWSI_SOFT_RESET 0x1c 100 101#define TWSI_DEBUG 102#undef TWSI_DEBUG 103 104#ifdef TWSI_DEBUG 105#define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0) 106#else 107#define debugf(fmt, args...) 108#endif 109 110struct mv_twsi_softc { 111 device_t dev; 112 struct resource *res[1]; /* SYS_RES_MEMORY */ 113 struct mtx mutex; 114 device_t iicbus; 115}; 116 117static struct mv_twsi_baud_rate { 118 uint32_t raw; 119 int param; 120 int m; 121 int n; 122} baud_rate[IIC_FASTEST + 1]; 123 124static int mv_twsi_probe(device_t); 125static int mv_twsi_attach(device_t); 126static int mv_twsi_detach(device_t); 127 128static int mv_twsi_reset(device_t dev, u_char speed, u_char addr, 129 u_char *oldaddr); 130static int mv_twsi_repeated_start(device_t dev, u_char slave, int timeout); 131static int mv_twsi_start(device_t dev, u_char slave, int timeout); 132static int mv_twsi_stop(device_t dev); 133static int mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, 134 int delay); 135static int mv_twsi_write(device_t dev, const char *buf, int len, int *sent, 136 int timeout); 137 138static struct resource_spec res_spec[] = { 139 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 140 { -1, 0 } 141}; 142 143static struct ofw_compat_data compat_data[] = { 144 { "mrvl,twsi", true }, 145 { "marvell,mv64xxx-i2c", true }, 146 { NULL, false } 147}; 148 149static device_method_t mv_twsi_methods[] = { 150 /* device interface */ 151 DEVMETHOD(device_probe, mv_twsi_probe), 152 DEVMETHOD(device_attach, mv_twsi_attach), 153 DEVMETHOD(device_detach, mv_twsi_detach), 154 155 /* iicbus interface */ 156 DEVMETHOD(iicbus_callback, iicbus_null_callback), 157 DEVMETHOD(iicbus_repeated_start, mv_twsi_repeated_start), 158 DEVMETHOD(iicbus_start, mv_twsi_start), 159 DEVMETHOD(iicbus_stop, mv_twsi_stop), 160 DEVMETHOD(iicbus_write, mv_twsi_write), 161 DEVMETHOD(iicbus_read, mv_twsi_read), 162 DEVMETHOD(iicbus_reset, mv_twsi_reset), 163 DEVMETHOD(iicbus_transfer, iicbus_transfer_gen), 164 { 0, 0 } 165}; 166 167static devclass_t mv_twsi_devclass; 168 169static driver_t mv_twsi_driver = { 170 MV_TWSI_NAME, 171 mv_twsi_methods, 172 sizeof(struct mv_twsi_softc), 173}; 174 175DRIVER_MODULE(twsi, simplebus, mv_twsi_driver, mv_twsi_devclass, 0, 0); 176DRIVER_MODULE(iicbus, twsi, iicbus_driver, iicbus_devclass, 0, 0); 177MODULE_DEPEND(twsi, iicbus, 1, 1, 1); 178 179static __inline uint32_t 180TWSI_READ(struct mv_twsi_softc *sc, bus_size_t off) 181{ 182 183 return (bus_read_4(sc->res[0], off)); 184} 185 186static __inline void 187TWSI_WRITE(struct mv_twsi_softc *sc, bus_size_t off, uint32_t val) 188{ 189 190 bus_write_4(sc->res[0], off, val); 191} 192 193static __inline void 194twsi_control_clear(struct mv_twsi_softc *sc, uint32_t mask) 195{ 196 uint32_t val; 197 198 val = TWSI_READ(sc, TWSI_CONTROL); 199 val &= ~mask; 200 TWSI_WRITE(sc, TWSI_CONTROL, val); 201} 202 203static __inline void 204twsi_control_set(struct mv_twsi_softc *sc, uint32_t mask) 205{ 206 uint32_t val; 207 208 val = TWSI_READ(sc, TWSI_CONTROL); 209 val |= mask; 210 TWSI_WRITE(sc, TWSI_CONTROL, val); 211} 212 213static __inline void 214twsi_clear_iflg(struct mv_twsi_softc *sc) 215{ 216 217 DELAY(1000); 218 twsi_control_clear(sc, TWSI_CONTROL_IFLG); 219 DELAY(1000); 220} 221 222 223/* 224 * timeout given in us 225 * returns 226 * 0 on sucessfull mask change 227 * non-zero on timeout 228 */ 229static int 230twsi_poll_ctrl(struct mv_twsi_softc *sc, int timeout, uint32_t mask) 231{ 232 233 timeout /= 10; 234 while (!(TWSI_READ(sc, TWSI_CONTROL) & mask)) { 235 DELAY(10); 236 if (--timeout < 0) 237 return (timeout); 238 } 239 return (0); 240} 241 242 243/* 244 * 'timeout' is given in us. Note also that timeout handling is not exact -- 245 * twsi_locked_start() total wait can be more than 2 x timeout 246 * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START 247 * or TWSI_STATUS_RPTD_START 248 */ 249static int 250twsi_locked_start(device_t dev, struct mv_twsi_softc *sc, int32_t mask, 251 u_char slave, int timeout) 252{ 253 int read_access, iflg_set = 0; 254 uint32_t status; 255 256 mtx_assert(&sc->mutex, MA_OWNED); 257 258 if (mask == TWSI_STATUS_RPTD_START) 259 /* read IFLG to know if it should be cleared later; from NBSD */ 260 iflg_set = TWSI_READ(sc, TWSI_CONTROL) & TWSI_CONTROL_IFLG; 261 262 twsi_control_set(sc, TWSI_CONTROL_START); 263 264 if (mask == TWSI_STATUS_RPTD_START && iflg_set) { 265 debugf("IFLG set, clearing\n"); 266 twsi_clear_iflg(sc); 267 } 268 269 /* 270 * Without this delay we timeout checking IFLG if the timeout is 0. 271 * NBSD driver always waits here too. 272 */ 273 DELAY(1000); 274 275 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 276 debugf("timeout sending %sSTART condition\n", 277 mask == TWSI_STATUS_START ? "" : "repeated "); 278 return (IIC_ETIMEOUT); 279 } 280 281 status = TWSI_READ(sc, TWSI_STATUS); 282 if (status != mask) { 283 debugf("wrong status (%02x) after sending %sSTART condition\n", 284 status, mask == TWSI_STATUS_START ? "" : "repeated "); 285 return (IIC_ESTATUS); 286 } 287 288 TWSI_WRITE(sc, TWSI_DATA, slave); 289 DELAY(1000); 290 twsi_clear_iflg(sc); 291 292 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 293 debugf("timeout sending slave address\n"); 294 return (IIC_ETIMEOUT); 295 } 296 297 read_access = (slave & 0x1) ? 1 : 0; 298 status = TWSI_READ(sc, TWSI_STATUS); 299 if (status != (read_access ? 300 TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) { 301 debugf("no ACK (status: %02x) after sending slave address\n", 302 status); 303 return (IIC_ENOACK); 304 } 305 306 return (IIC_NOERR); 307} 308 309static int 310mv_twsi_probe(device_t dev) 311{ 312 313 if (!ofw_bus_status_okay(dev)) 314 return (ENXIO); 315 316 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) 317 return (ENXIO); 318 319 device_set_desc(dev, "Marvell Integrated I2C Bus Controller"); 320 return (BUS_PROBE_DEFAULT); 321} 322 323#define ABSSUB(a,b) (((a) > (b)) ? (a) - (b) : (b) - (a)) 324static void 325mv_twsi_cal_baud_rate(const uint32_t target, struct mv_twsi_baud_rate *rate) 326{ 327 uint32_t clk, cur, diff, diff0; 328 int m, n, m0, n0; 329 330 /* Calculate baud rate. */ 331 m0 = n0 = 4; /* Default values on reset */ 332 diff0 = 0xffffffff; 333 clk = get_tclk(); 334 335 for (n = 0; n < 8; n++) { 336 for (m = 0; m < 16; m++) { 337 cur = TWSI_BAUD_RATE_RAW(clk,m,n); 338 diff = ABSSUB(target, cur); 339 if (diff < diff0) { 340 m0 = m; 341 n0 = n; 342 diff0 = diff; 343 } 344 } 345 } 346 rate->raw = TWSI_BAUD_RATE_RAW(clk, m0, n0); 347 rate->param = TWSI_BAUD_RATE_PARAM(m0, n0); 348 rate->m = m0; 349 rate->n = n0; 350} 351 352static int 353mv_twsi_attach(device_t dev) 354{ 355 struct mv_twsi_softc *sc; 356 phandle_t child, iicbusnode; 357 device_t childdev; 358 struct iicbus_ivar *devi; 359 char dname[32]; /* 32 is taken from struct u_device */ 360 uint32_t paddr; 361 int len, error; 362 363 sc = device_get_softc(dev); 364 sc->dev = dev; 365 bzero(baud_rate, sizeof(baud_rate)); 366 367 mtx_init(&sc->mutex, device_get_nameunit(dev), MV_TWSI_NAME, MTX_DEF); 368 369 /* Allocate IO resources */ 370 if (bus_alloc_resources(dev, res_spec, sc->res)) { 371 device_printf(dev, "could not allocate resources\n"); 372 mv_twsi_detach(dev); 373 return (ENXIO); 374 } 375 376 mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_SLOW, &baud_rate[IIC_SLOW]); 377 mv_twsi_cal_baud_rate(TWSI_BAUD_RATE_FAST, &baud_rate[IIC_FAST]); 378 if (bootverbose) 379 device_printf(dev, "calculated baud rates are:\n" 380 " %" PRIu32 " kHz (M=%d, N=%d) for slow,\n" 381 " %" PRIu32 " kHz (M=%d, N=%d) for fast.\n", 382 baud_rate[IIC_SLOW].raw / 1000, 383 baud_rate[IIC_SLOW].m, 384 baud_rate[IIC_SLOW].n, 385 baud_rate[IIC_FAST].raw / 1000, 386 baud_rate[IIC_FAST].m, 387 baud_rate[IIC_FAST].n); 388 389 sc->iicbus = device_add_child(dev, IICBUS_DEVNAME, -1); 390 if (sc->iicbus == NULL) { 391 device_printf(dev, "could not add iicbus child\n"); 392 mv_twsi_detach(dev); 393 return (ENXIO); 394 } 395 /* Attach iicbus. */ 396 bus_generic_attach(dev); 397 398 iicbusnode = 0; 399 /* Find iicbus as the child devices in the device tree. */ 400 for (child = OF_child(ofw_bus_get_node(dev)); child != 0; 401 child = OF_peer(child)) { 402 len = OF_getproplen(child, "model"); 403 if (len <= 0 || len > sizeof(dname)) 404 continue; 405 error = OF_getprop(child, "model", &dname, len); 406 if (error == -1) 407 continue; 408 len = strlen(dname); 409 if (len == strlen(IICBUS_DEVNAME) && 410 strncasecmp(dname, IICBUS_DEVNAME, len) == 0) { 411 iicbusnode = child; 412 break; 413 } 414 } 415 if (iicbusnode == 0) 416 goto attach_end; 417 418 /* Attach child devices onto iicbus. */ 419 for (child = OF_child(iicbusnode); child != 0; child = OF_peer(child)) { 420 /* Get slave address. */ 421 error = OF_getprop(child, "i2c-address", &paddr, sizeof(paddr)); 422 if (error == -1) 423 error = OF_getprop(child, "reg", &paddr, sizeof(paddr)); 424 if (error == -1) 425 continue; 426 427 /* Get device driver name. */ 428 len = OF_getproplen(child, "model"); 429 if (len <= 0 || len > sizeof(dname)) 430 continue; 431 OF_getprop(child, "model", &dname, len); 432 433 if (bootverbose) 434 device_printf(dev, "adding a device %s at %d.\n", 435 dname, fdt32_to_cpu(paddr)); 436 childdev = BUS_ADD_CHILD(sc->iicbus, 0, dname, -1); 437 devi = IICBUS_IVAR(childdev); 438 devi->addr = fdt32_to_cpu(paddr); 439 } 440 441attach_end: 442 bus_generic_attach(sc->iicbus); 443 444 return (0); 445} 446 447static int 448mv_twsi_detach(device_t dev) 449{ 450 struct mv_twsi_softc *sc; 451 int rv; 452 453 sc = device_get_softc(dev); 454 455 if ((rv = bus_generic_detach(dev)) != 0) 456 return (rv); 457 458 if (sc->iicbus != NULL) 459 if ((rv = device_delete_child(dev, sc->iicbus)) != 0) 460 return (rv); 461 462 bus_release_resources(dev, res_spec, sc->res); 463 464 mtx_destroy(&sc->mutex); 465 return (0); 466} 467 468/* 469 * Only slave mode supported, disregard [old]addr 470 */ 471static int 472mv_twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 473{ 474 struct mv_twsi_softc *sc; 475 uint32_t param; 476 477 sc = device_get_softc(dev); 478 479 switch (speed) { 480 case IIC_SLOW: 481 case IIC_FAST: 482 param = baud_rate[speed].param; 483 break; 484 case IIC_FASTEST: 485 case IIC_UNKNOWN: 486 default: 487 param = baud_rate[IIC_FAST].param; 488 break; 489 } 490 491 mtx_lock(&sc->mutex); 492 TWSI_WRITE(sc, TWSI_SOFT_RESET, 0x0); 493 DELAY(2000); 494 TWSI_WRITE(sc, TWSI_BAUD_RATE, param); 495 TWSI_WRITE(sc, TWSI_CONTROL, TWSI_CONTROL_TWSIEN | TWSI_CONTROL_ACK); 496 DELAY(1000); 497 mtx_unlock(&sc->mutex); 498 499 return (0); 500} 501 502/* 503 * timeout is given in us 504 */ 505static int 506mv_twsi_repeated_start(device_t dev, u_char slave, int timeout) 507{ 508 struct mv_twsi_softc *sc; 509 int rv; 510 511 sc = device_get_softc(dev); 512 513 mtx_lock(&sc->mutex); 514 rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave, 515 timeout); 516 mtx_unlock(&sc->mutex); 517 518 if (rv) { 519 mv_twsi_stop(dev); 520 return (rv); 521 } else 522 return (IIC_NOERR); 523} 524 525/* 526 * timeout is given in us 527 */ 528static int 529mv_twsi_start(device_t dev, u_char slave, int timeout) 530{ 531 struct mv_twsi_softc *sc; 532 int rv; 533 534 sc = device_get_softc(dev); 535 536 mtx_lock(&sc->mutex); 537 rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout); 538 mtx_unlock(&sc->mutex); 539 540 if (rv) { 541 mv_twsi_stop(dev); 542 return (rv); 543 } else 544 return (IIC_NOERR); 545} 546 547static int 548mv_twsi_stop(device_t dev) 549{ 550 struct mv_twsi_softc *sc; 551 552 sc = device_get_softc(dev); 553 554 mtx_lock(&sc->mutex); 555 twsi_control_set(sc, TWSI_CONTROL_STOP); 556 DELAY(1000); 557 twsi_clear_iflg(sc); 558 mtx_unlock(&sc->mutex); 559 560 return (IIC_NOERR); 561} 562 563static int 564mv_twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay) 565{ 566 struct mv_twsi_softc *sc; 567 uint32_t status; 568 int last_byte, rv; 569 570 sc = device_get_softc(dev); 571 572 mtx_lock(&sc->mutex); 573 *read = 0; 574 while (*read < len) { 575 /* 576 * Check if we are reading last byte of the last buffer, 577 * do not send ACK then, per I2C specs 578 */ 579 last_byte = ((*read == len - 1) && last) ? 1 : 0; 580 if (last_byte) 581 twsi_control_clear(sc, TWSI_CONTROL_ACK); 582 else 583 twsi_control_set(sc, TWSI_CONTROL_ACK); 584 585 DELAY (1000); 586 twsi_clear_iflg(sc); 587 588 if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) { 589 debugf("timeout reading data\n"); 590 rv = IIC_ETIMEOUT; 591 goto out; 592 } 593 594 status = TWSI_READ(sc, TWSI_STATUS); 595 if (status != (last_byte ? 596 TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) { 597 debugf("wrong status (%02x) while reading\n", status); 598 rv = IIC_ESTATUS; 599 goto out; 600 } 601 602 *buf++ = TWSI_READ(sc, TWSI_DATA); 603 (*read)++; 604 } 605 rv = IIC_NOERR; 606out: 607 mtx_unlock(&sc->mutex); 608 return (rv); 609} 610 611static int 612mv_twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout) 613{ 614 struct mv_twsi_softc *sc; 615 uint32_t status; 616 int rv; 617 618 sc = device_get_softc(dev); 619 620 mtx_lock(&sc->mutex); 621 *sent = 0; 622 while (*sent < len) { 623 TWSI_WRITE(sc, TWSI_DATA, *buf++); 624 625 twsi_clear_iflg(sc); 626 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) { 627 debugf("timeout writing data\n"); 628 rv = IIC_ETIMEOUT; 629 goto out; 630 } 631 632 status = TWSI_READ(sc, TWSI_STATUS); 633 if (status != TWSI_STATUS_DATA_WR_ACK) { 634 debugf("wrong status (%02x) while writing\n", status); 635 rv = IIC_ESTATUS; 636 goto out; 637 } 638 (*sent)++; 639 } 640 rv = IIC_NOERR; 641out: 642 mtx_unlock(&sc->mutex); 643 return (rv); 644} 645