diff options
| -rw-r--r-- | drivers/i2c/busses/i2c-rcar.c | 124 |
1 files changed, 115 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index d826e82dd997..835057741aa6 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c | |||
| @@ -48,6 +48,12 @@ | |||
| 48 | #define ICMAR 0x20 /* master address */ | 48 | #define ICMAR 0x20 /* master address */ |
| 49 | #define ICRXTX 0x24 /* data port */ | 49 | #define ICRXTX 0x24 /* data port */ |
| 50 | 50 | ||
| 51 | /* ICSCR */ | ||
| 52 | #define SDBS (1 << 3) /* slave data buffer select */ | ||
| 53 | #define SIE (1 << 2) /* slave interface enable */ | ||
| 54 | #define GCAE (1 << 1) /* general call address enable */ | ||
| 55 | #define FNA (1 << 0) /* forced non acknowledgment */ | ||
| 56 | |||
| 51 | /* ICMCR */ | 57 | /* ICMCR */ |
| 52 | #define MDBS (1 << 7) /* non-fifo mode switch */ | 58 | #define MDBS (1 << 7) /* non-fifo mode switch */ |
| 53 | #define FSCL (1 << 6) /* override SCL pin */ | 59 | #define FSCL (1 << 6) /* override SCL pin */ |
| @@ -58,6 +64,15 @@ | |||
| 58 | #define FSB (1 << 1) /* force stop bit */ | 64 | #define FSB (1 << 1) /* force stop bit */ |
| 59 | #define ESG (1 << 0) /* en startbit gen */ | 65 | #define ESG (1 << 0) /* en startbit gen */ |
| 60 | 66 | ||
| 67 | /* ICSSR (also for ICSIER) */ | ||
| 68 | #define GCAR (1 << 6) /* general call received */ | ||
| 69 | #define STM (1 << 5) /* slave transmit mode */ | ||
| 70 | #define SSR (1 << 4) /* stop received */ | ||
| 71 | #define SDE (1 << 3) /* slave data empty */ | ||
| 72 | #define SDT (1 << 2) /* slave data transmitted */ | ||
| 73 | #define SDR (1 << 1) /* slave data received */ | ||
| 74 | #define SAR (1 << 0) /* slave addr received */ | ||
| 75 | |||
| 61 | /* ICMSR (also for ICMIE) */ | 76 | /* ICMSR (also for ICMIE) */ |
| 62 | #define MNR (1 << 6) /* nack received */ | 77 | #define MNR (1 << 6) /* nack received */ |
| 63 | #define MAL (1 << 5) /* arbitration lost */ | 78 | #define MAL (1 << 5) /* arbitration lost */ |
| @@ -103,6 +118,7 @@ struct rcar_i2c_priv { | |||
| 103 | u32 icccr; | 118 | u32 icccr; |
| 104 | u32 flags; | 119 | u32 flags; |
| 105 | enum rcar_i2c_type devtype; | 120 | enum rcar_i2c_type devtype; |
| 121 | struct i2c_client *slave; | ||
| 106 | }; | 122 | }; |
| 107 | 123 | ||
| 108 | #define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent) | 124 | #define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent) |
| @@ -126,15 +142,6 @@ static u32 rcar_i2c_read(struct rcar_i2c_priv *priv, int reg) | |||
| 126 | 142 | ||
| 127 | static void rcar_i2c_init(struct rcar_i2c_priv *priv) | 143 | static void rcar_i2c_init(struct rcar_i2c_priv *priv) |
| 128 | { | 144 | { |
| 129 | /* | ||
| 130 | * reset slave mode. | ||
| 131 | * slave mode is not used on this driver | ||
| 132 | */ | ||
| 133 | rcar_i2c_write(priv, ICSIER, 0); | ||
| 134 | rcar_i2c_write(priv, ICSAR, 0); | ||
| 135 | rcar_i2c_write(priv, ICSCR, 0); | ||
| 136 | rcar_i2c_write(priv, ICSSR, 0); | ||
| 137 | |||
| 138 | /* reset master mode */ | 145 | /* reset master mode */ |
| 139 | rcar_i2c_write(priv, ICMIER, 0); | 146 | rcar_i2c_write(priv, ICMIER, 0); |
| 140 | rcar_i2c_write(priv, ICMCR, 0); | 147 | rcar_i2c_write(priv, ICMCR, 0); |
| @@ -360,6 +367,63 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) | |||
| 360 | return 0; | 367 | return 0; |
| 361 | } | 368 | } |
| 362 | 369 | ||
| 370 | static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) | ||
| 371 | { | ||
| 372 | u32 ssr_raw, ssr_filtered; | ||
| 373 | u8 value; | ||
| 374 | |||
| 375 | ssr_raw = rcar_i2c_read(priv, ICSSR) & 0xff; | ||
| 376 | ssr_filtered = ssr_raw & rcar_i2c_read(priv, ICSIER); | ||
| 377 | |||
| 378 | if (!ssr_filtered) | ||
| 379 | return false; | ||
| 380 | |||
| 381 | /* address detected */ | ||
| 382 | if (ssr_filtered & SAR) { | ||
| 383 | /* read or write request */ | ||
| 384 | if (ssr_raw & STM) { | ||
| 385 | i2c_slave_event(priv->slave, I2C_SLAVE_REQ_READ_START, &value); | ||
| 386 | rcar_i2c_write(priv, ICRXTX, value); | ||
| 387 | rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR); | ||
| 388 | } else { | ||
| 389 | i2c_slave_event(priv->slave, I2C_SLAVE_REQ_WRITE_START, &value); | ||
| 390 | rcar_i2c_read(priv, ICRXTX); /* dummy read */ | ||
| 391 | rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR); | ||
| 392 | } | ||
| 393 | |||
| 394 | rcar_i2c_write(priv, ICSSR, ~SAR & 0xff); | ||
| 395 | } | ||
| 396 | |||
| 397 | /* master sent stop */ | ||
| 398 | if (ssr_filtered & SSR) { | ||
| 399 | i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value); | ||
| 400 | rcar_i2c_write(priv, ICSIER, SAR | SSR); | ||
| 401 | rcar_i2c_write(priv, ICSSR, ~SSR & 0xff); | ||
| 402 | } | ||
| 403 | |||
| 404 | /* master wants to write to us */ | ||
| 405 | if (ssr_filtered & SDR) { | ||
| 406 | int ret; | ||
| 407 | |||
| 408 | value = rcar_i2c_read(priv, ICRXTX); | ||
| 409 | ret = i2c_slave_event(priv->slave, I2C_SLAVE_REQ_WRITE_END, &value); | ||
| 410 | /* Send NACK in case of error */ | ||
| 411 | rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0)); | ||
| 412 | i2c_slave_event(priv->slave, I2C_SLAVE_REQ_WRITE_START, &value); | ||
| 413 | rcar_i2c_write(priv, ICSSR, ~SDR & 0xff); | ||
| 414 | } | ||
| 415 | |||
| 416 | /* master wants to read from us */ | ||
| 417 | if (ssr_filtered & SDE) { | ||
| 418 | i2c_slave_event(priv->slave, I2C_SLAVE_REQ_READ_END, &value); | ||
| 419 | i2c_slave_event(priv->slave, I2C_SLAVE_REQ_READ_START, &value); | ||
| 420 | rcar_i2c_write(priv, ICRXTX, value); | ||
| 421 | rcar_i2c_write(priv, ICSSR, ~SDE & 0xff); | ||
| 422 | } | ||
| 423 | |||
| 424 | return true; | ||
| 425 | } | ||
| 426 | |||
| 363 | static irqreturn_t rcar_i2c_irq(int irq, void *ptr) | 427 | static irqreturn_t rcar_i2c_irq(int irq, void *ptr) |
| 364 | { | 428 | { |
| 365 | struct rcar_i2c_priv *priv = ptr; | 429 | struct rcar_i2c_priv *priv = ptr; |
| @@ -369,6 +433,9 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) | |||
| 369 | /*-------------- spin lock -----------------*/ | 433 | /*-------------- spin lock -----------------*/ |
| 370 | spin_lock(&priv->lock); | 434 | spin_lock(&priv->lock); |
| 371 | 435 | ||
| 436 | if (rcar_i2c_slave_irq(priv)) | ||
| 437 | goto exit; | ||
| 438 | |||
| 372 | msr = rcar_i2c_read(priv, ICMSR); | 439 | msr = rcar_i2c_read(priv, ICMSR); |
| 373 | 440 | ||
| 374 | /* Only handle interrupts that are currently enabled */ | 441 | /* Only handle interrupts that are currently enabled */ |
| @@ -499,6 +566,43 @@ out: | |||
| 499 | return ret; | 566 | return ret; |
| 500 | } | 567 | } |
| 501 | 568 | ||
| 569 | static int rcar_reg_slave(struct i2c_client *slave) | ||
| 570 | { | ||
| 571 | struct rcar_i2c_priv *priv = i2c_get_adapdata(slave->adapter); | ||
| 572 | |||
| 573 | if (priv->slave) | ||
| 574 | return -EBUSY; | ||
| 575 | |||
| 576 | if (slave->flags & I2C_CLIENT_TEN) | ||
| 577 | return -EAFNOSUPPORT; | ||
| 578 | |||
| 579 | pm_runtime_forbid(rcar_i2c_priv_to_dev(priv)); | ||
| 580 | |||
| 581 | priv->slave = slave; | ||
| 582 | rcar_i2c_write(priv, ICSAR, slave->addr); | ||
| 583 | rcar_i2c_write(priv, ICSSR, 0); | ||
| 584 | rcar_i2c_write(priv, ICSIER, SAR | SSR); | ||
| 585 | rcar_i2c_write(priv, ICSCR, SIE | SDBS); | ||
| 586 | |||
| 587 | return 0; | ||
| 588 | } | ||
| 589 | |||
| 590 | static int rcar_unreg_slave(struct i2c_client *slave) | ||
| 591 | { | ||
| 592 | struct rcar_i2c_priv *priv = i2c_get_adapdata(slave->adapter); | ||
| 593 | |||
| 594 | WARN_ON(!priv->slave); | ||
| 595 | |||
| 596 | rcar_i2c_write(priv, ICSIER, 0); | ||
| 597 | rcar_i2c_write(priv, ICSCR, 0); | ||
| 598 | |||
| 599 | priv->slave = NULL; | ||
| 600 | |||
| 601 | pm_runtime_allow(rcar_i2c_priv_to_dev(priv)); | ||
| 602 | |||
| 603 | return 0; | ||
| 604 | } | ||
| 605 | |||
| 502 | static u32 rcar_i2c_func(struct i2c_adapter *adap) | 606 | static u32 rcar_i2c_func(struct i2c_adapter *adap) |
| 503 | { | 607 | { |
| 504 | /* This HW can't do SMBUS_QUICK and NOSTART */ | 608 | /* This HW can't do SMBUS_QUICK and NOSTART */ |
| @@ -508,6 +612,8 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap) | |||
| 508 | static const struct i2c_algorithm rcar_i2c_algo = { | 612 | static const struct i2c_algorithm rcar_i2c_algo = { |
| 509 | .master_xfer = rcar_i2c_master_xfer, | 613 | .master_xfer = rcar_i2c_master_xfer, |
| 510 | .functionality = rcar_i2c_func, | 614 | .functionality = rcar_i2c_func, |
| 615 | .reg_slave = rcar_reg_slave, | ||
| 616 | .unreg_slave = rcar_unreg_slave, | ||
| 511 | }; | 617 | }; |
| 512 | 618 | ||
| 513 | static const struct of_device_id rcar_i2c_dt_ids[] = { | 619 | static const struct of_device_id rcar_i2c_dt_ids[] = { |
