| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for I2C adapter in Rockchip RK3xxx SoC |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Max Schwarz <max.schwarz@online.de> |
|---|
| 5 | 6 | * based on the patches by Rockchip Inc. |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 7 | */ |
|---|
| 11 | 8 | |
|---|
| 9 | +#include <linux/acpi.h> |
|---|
| 12 | 10 | #include <linux/kernel.h> |
|---|
| 13 | 11 | #include <linux/module.h> |
|---|
| 14 | 12 | #include <linux/i2c.h> |
|---|
| 15 | 13 | #include <linux/interrupt.h> |
|---|
| 14 | +#include <linux/iopoll.h> |
|---|
| 16 | 15 | #include <linux/errno.h> |
|---|
| 17 | 16 | #include <linux/err.h> |
|---|
| 18 | 17 | #include <linux/platform_device.h> |
|---|
| .. | .. |
|---|
| 27 | 26 | #include <linux/math64.h> |
|---|
| 28 | 27 | #include <linux/reboot.h> |
|---|
| 29 | 28 | #include <linux/delay.h> |
|---|
| 29 | +#include <linux/soc/rockchip/rockchip_thunderboot_service.h> |
|---|
| 30 | 30 | |
|---|
| 31 | 31 | |
|---|
| 32 | 32 | /* Register Map */ |
|---|
| .. | .. |
|---|
| 39 | 39 | #define REG_IEN 0x18 /* interrupt enable */ |
|---|
| 40 | 40 | #define REG_IPD 0x1c /* interrupt pending */ |
|---|
| 41 | 41 | #define REG_FCNT 0x20 /* finished count */ |
|---|
| 42 | +#define REG_CON1 0x228 /* control register1 */ |
|---|
| 42 | 43 | |
|---|
| 43 | 44 | /* Data buffer offsets */ |
|---|
| 44 | 45 | #define TXBUFFER_BASE 0x100 |
|---|
| .. | .. |
|---|
| 66 | 67 | #define REG_CON_STA_CFG(cfg) ((cfg) << 12) |
|---|
| 67 | 68 | #define REG_CON_STO_CFG(cfg) ((cfg) << 14) |
|---|
| 68 | 69 | |
|---|
| 70 | +enum { |
|---|
| 71 | + RK_I2C_VERSION0 = 0, |
|---|
| 72 | + RK_I2C_VERSION1, |
|---|
| 73 | + RK_I2C_VERSION5 = 5, |
|---|
| 74 | +}; |
|---|
| 75 | + |
|---|
| 76 | +#define REG_CON_VERSION GENMASK_ULL(24, 16) |
|---|
| 77 | +#define REG_CON_VERSION_SHIFT 16 |
|---|
| 78 | + |
|---|
| 69 | 79 | /* REG_MRXADDR bits */ |
|---|
| 70 | 80 | #define REG_MRXADDR_VALID(x) BIT(24 + (x)) /* [x*8+7:x*8] of MRX[R]ADDR valid */ |
|---|
| 71 | 81 | |
|---|
| .. | .. |
|---|
| 81 | 91 | |
|---|
| 82 | 92 | /* Disable i2c all irqs */ |
|---|
| 83 | 93 | #define IEN_ALL_DISABLE 0 |
|---|
| 94 | + |
|---|
| 95 | +#define REG_CON1_AUTO_STOP BIT(0) |
|---|
| 96 | +#define REG_CON1_TRANSFER_AUTO_STOP BIT(1) |
|---|
| 97 | +#define REG_CON1_NACK_AUTO_STOP BIT(2) |
|---|
| 84 | 98 | |
|---|
| 85 | 99 | /* Constants */ |
|---|
| 86 | 100 | #define WAIT_TIMEOUT 1000 /* ms */ |
|---|
| .. | .. |
|---|
| 197 | 211 | * @error: error code for i2c transfer |
|---|
| 198 | 212 | * @i2c_restart_nb: make sure the i2c transfer to be finished |
|---|
| 199 | 213 | * @system_restarting: true if system is restarting |
|---|
| 214 | + * @tb_cl: client for rockchip thunder boot service |
|---|
| 200 | 215 | */ |
|---|
| 201 | 216 | struct rk3x_i2c { |
|---|
| 202 | 217 | struct i2c_adapter adap; |
|---|
| .. | .. |
|---|
| 208 | 223 | struct clk *clk; |
|---|
| 209 | 224 | struct clk *pclk; |
|---|
| 210 | 225 | struct notifier_block clk_rate_nb; |
|---|
| 226 | + bool autostop_supported; |
|---|
| 211 | 227 | |
|---|
| 212 | 228 | /* Settings */ |
|---|
| 213 | 229 | struct i2c_timings t; |
|---|
| .. | .. |
|---|
| 231 | 247 | |
|---|
| 232 | 248 | struct notifier_block i2c_restart_nb; |
|---|
| 233 | 249 | bool system_restarting; |
|---|
| 250 | + struct rk_tb_client tb_cl; |
|---|
| 251 | + int irq; |
|---|
| 234 | 252 | }; |
|---|
| 235 | 253 | |
|---|
| 236 | | -static int rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c, bool sended); |
|---|
| 237 | 254 | static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c); |
|---|
| 255 | +static int rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c, bool sended); |
|---|
| 238 | 256 | |
|---|
| 239 | 257 | static inline void rk3x_i2c_wake_up(struct rk3x_i2c *i2c) |
|---|
| 240 | 258 | { |
|---|
| .. | .. |
|---|
| 271 | 289 | i2c_writel(i2c, val, REG_CON); |
|---|
| 272 | 290 | } |
|---|
| 273 | 291 | |
|---|
| 292 | +static bool rk3x_i2c_auto_stop(struct rk3x_i2c *i2c) |
|---|
| 293 | +{ |
|---|
| 294 | + unsigned int len, con1 = 0; |
|---|
| 295 | + |
|---|
| 296 | + if (!i2c->autostop_supported) |
|---|
| 297 | + return false; |
|---|
| 298 | + |
|---|
| 299 | + if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) |
|---|
| 300 | + con1 = REG_CON1_NACK_AUTO_STOP | REG_CON1_AUTO_STOP; |
|---|
| 301 | + |
|---|
| 302 | + if (!i2c->is_last_msg) |
|---|
| 303 | + goto out; |
|---|
| 304 | + |
|---|
| 305 | + len = i2c->msg->len - i2c->processed; |
|---|
| 306 | + |
|---|
| 307 | + if (len > 32) |
|---|
| 308 | + goto out; |
|---|
| 309 | + |
|---|
| 310 | + i2c->state = STATE_STOP; |
|---|
| 311 | + |
|---|
| 312 | + con1 |= REG_CON1_TRANSFER_AUTO_STOP | REG_CON1_AUTO_STOP; |
|---|
| 313 | + i2c_writel(i2c, con1, REG_CON1); |
|---|
| 314 | + if (con1 & REG_CON1_NACK_AUTO_STOP) |
|---|
| 315 | + i2c_writel(i2c, REG_INT_STOP, REG_IEN); |
|---|
| 316 | + else |
|---|
| 317 | + i2c_writel(i2c, REG_INT_STOP | REG_INT_NAKRCV, REG_IEN); |
|---|
| 318 | + |
|---|
| 319 | + return true; |
|---|
| 320 | + |
|---|
| 321 | +out: |
|---|
| 322 | + i2c_writel(i2c, con1, REG_CON1); |
|---|
| 323 | + return false; |
|---|
| 324 | +} |
|---|
| 325 | + |
|---|
| 274 | 326 | /** |
|---|
| 275 | 327 | * Generate a START condition, which triggers a REG_INT_START interrupt. |
|---|
| 276 | 328 | */ |
|---|
| 277 | 329 | static void rk3x_i2c_start(struct rk3x_i2c *i2c) |
|---|
| 278 | 330 | { |
|---|
| 279 | 331 | u32 val = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK; |
|---|
| 332 | + bool auto_stop = rk3x_i2c_auto_stop(i2c); |
|---|
| 280 | 333 | int length = 0; |
|---|
| 281 | 334 | |
|---|
| 282 | 335 | /* enable appropriate interrupts */ |
|---|
| 283 | 336 | if (i2c->mode == REG_CON_MOD_TX) { |
|---|
| 284 | | - i2c_writel(i2c, REG_INT_MBTF | REG_INT_NAKRCV, REG_IEN); |
|---|
| 285 | | - i2c->state = STATE_WRITE; |
|---|
| 337 | + if (!auto_stop) { |
|---|
| 338 | + i2c_writel(i2c, REG_INT_MBTF | REG_INT_NAKRCV, REG_IEN); |
|---|
| 339 | + i2c->state = STATE_WRITE; |
|---|
| 340 | + } |
|---|
| 286 | 341 | length = rk3x_i2c_fill_transmit_buf(i2c, false); |
|---|
| 287 | 342 | } else { |
|---|
| 288 | 343 | /* in any other case, we are going to be reading. */ |
|---|
| 289 | | - i2c_writel(i2c, REG_INT_MBRF | REG_INT_NAKRCV, REG_IEN); |
|---|
| 290 | | - i2c->state = STATE_READ; |
|---|
| 344 | + if (!auto_stop) { |
|---|
| 345 | + i2c_writel(i2c, REG_INT_MBRF | REG_INT_NAKRCV, REG_IEN); |
|---|
| 346 | + i2c->state = STATE_READ; |
|---|
| 347 | + } |
|---|
| 291 | 348 | } |
|---|
| 292 | 349 | |
|---|
| 293 | 350 | /* enable adapter with correct mode, send START condition */ |
|---|
| .. | .. |
|---|
| 424 | 481 | { |
|---|
| 425 | 482 | if (!(ipd & REG_INT_MBTF)) { |
|---|
| 426 | 483 | rk3x_i2c_stop(i2c, -EIO); |
|---|
| 427 | | - dev_err(i2c->dev, "unexpected irq in WRITE: 0x%x\n", ipd); |
|---|
| 484 | + dev_warn_ratelimited(i2c->dev, "unexpected irq in WRITE: 0x%x\n", ipd); |
|---|
| 428 | 485 | rk3x_i2c_clean_ipd(i2c); |
|---|
| 429 | 486 | return; |
|---|
| 430 | 487 | } |
|---|
| .. | .. |
|---|
| 432 | 489 | /* ack interrupt */ |
|---|
| 433 | 490 | i2c_writel(i2c, REG_INT_MBTF, REG_IPD); |
|---|
| 434 | 491 | |
|---|
| 492 | + rk3x_i2c_auto_stop(i2c); |
|---|
| 435 | 493 | /* are we finished? */ |
|---|
| 436 | 494 | if (i2c->processed == i2c->msg->len) |
|---|
| 437 | 495 | rk3x_i2c_stop(i2c, i2c->error); |
|---|
| .. | .. |
|---|
| 439 | 497 | rk3x_i2c_fill_transmit_buf(i2c, true); |
|---|
| 440 | 498 | } |
|---|
| 441 | 499 | |
|---|
| 442 | | -static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) |
|---|
| 500 | +static void rk3x_i2c_read(struct rk3x_i2c *i2c) |
|---|
| 443 | 501 | { |
|---|
| 444 | 502 | unsigned int i; |
|---|
| 445 | 503 | unsigned int len = i2c->msg->len - i2c->processed; |
|---|
| 446 | | - u32 uninitialized_var(val); |
|---|
| 504 | + u32 val; |
|---|
| 447 | 505 | u8 byte; |
|---|
| 448 | | - |
|---|
| 449 | | - /* we only care for MBRF here. */ |
|---|
| 450 | | - if (!(ipd & REG_INT_MBRF)) |
|---|
| 451 | | - return; |
|---|
| 452 | | - |
|---|
| 453 | | - /* ack interrupt (read also produces a spurious START flag, clear it too) */ |
|---|
| 454 | | - i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD); |
|---|
| 455 | 506 | |
|---|
| 456 | 507 | /* Can only handle a maximum of 32 bytes at a time */ |
|---|
| 457 | 508 | if (len > 32) |
|---|
| .. | .. |
|---|
| 465 | 516 | byte = (val >> ((i % 4) * 8)) & 0xff; |
|---|
| 466 | 517 | i2c->msg->buf[i2c->processed++] = byte; |
|---|
| 467 | 518 | } |
|---|
| 519 | +} |
|---|
| 468 | 520 | |
|---|
| 521 | +static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) |
|---|
| 522 | +{ |
|---|
| 523 | + /* we only care for MBRF here. */ |
|---|
| 524 | + if (!(ipd & REG_INT_MBRF)) |
|---|
| 525 | + return; |
|---|
| 526 | + |
|---|
| 527 | + /* ack interrupt (read also produces a spurious START flag, clear it too) */ |
|---|
| 528 | + i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD); |
|---|
| 529 | + |
|---|
| 530 | + /* read the data from receive buffer */ |
|---|
| 531 | + rk3x_i2c_read(i2c); |
|---|
| 532 | + |
|---|
| 533 | + rk3x_i2c_auto_stop(i2c); |
|---|
| 469 | 534 | /* are we finished? */ |
|---|
| 470 | 535 | if (i2c->processed == i2c->msg->len) |
|---|
| 471 | 536 | rk3x_i2c_stop(i2c, i2c->error); |
|---|
| .. | .. |
|---|
| 479 | 544 | |
|---|
| 480 | 545 | if (!(ipd & REG_INT_STOP)) { |
|---|
| 481 | 546 | rk3x_i2c_stop(i2c, -EIO); |
|---|
| 482 | | - dev_err(i2c->dev, "unexpected irq in STOP: 0x%x\n", ipd); |
|---|
| 547 | + dev_warn_ratelimited(i2c->dev, "unexpected irq in STOP: 0x%x\n", ipd); |
|---|
| 483 | 548 | rk3x_i2c_clean_ipd(i2c); |
|---|
| 484 | 549 | return; |
|---|
| 550 | + } |
|---|
| 551 | + |
|---|
| 552 | + if (i2c->autostop_supported && !i2c->error) { |
|---|
| 553 | + if (i2c->mode != REG_CON_MOD_TX && i2c->msg) { |
|---|
| 554 | + if ((i2c->msg->len - i2c->processed) > 0) |
|---|
| 555 | + rk3x_i2c_read(i2c); |
|---|
| 556 | + } |
|---|
| 557 | + |
|---|
| 558 | + i2c->processed = 0; |
|---|
| 559 | + i2c->msg = NULL; |
|---|
| 485 | 560 | } |
|---|
| 486 | 561 | |
|---|
| 487 | 562 | /* ack interrupt */ |
|---|
| .. | .. |
|---|
| 490 | 565 | /* disable STOP bit */ |
|---|
| 491 | 566 | con = i2c_readl(i2c, REG_CON); |
|---|
| 492 | 567 | con &= ~REG_CON_STOP; |
|---|
| 568 | + if (i2c->autostop_supported) |
|---|
| 569 | + con &= ~REG_CON_START; |
|---|
| 493 | 570 | i2c_writel(i2c, con, REG_CON); |
|---|
| 494 | 571 | |
|---|
| 495 | 572 | i2c->busy = false; |
|---|
| .. | .. |
|---|
| 531 | 608 | ipd &= ~REG_INT_NAKRCV; |
|---|
| 532 | 609 | |
|---|
| 533 | 610 | if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) { |
|---|
| 534 | | - rk3x_i2c_stop(i2c, -ENXIO); |
|---|
| 535 | | - goto out; |
|---|
| 611 | + if (i2c->autostop_supported) { |
|---|
| 612 | + i2c->error = -ENXIO; |
|---|
| 613 | + i2c->state = STATE_STOP; |
|---|
| 614 | + } else { |
|---|
| 615 | + rk3x_i2c_stop(i2c, -ENXIO); |
|---|
| 616 | + goto out; |
|---|
| 617 | + } |
|---|
| 536 | 618 | } |
|---|
| 537 | 619 | } |
|---|
| 538 | 620 | |
|---|
| .. | .. |
|---|
| 568 | 650 | */ |
|---|
| 569 | 651 | static const struct i2c_spec_values *rk3x_i2c_get_spec(unsigned int speed) |
|---|
| 570 | 652 | { |
|---|
| 571 | | - if (speed <= 100000) |
|---|
| 653 | + if (speed <= I2C_MAX_STANDARD_MODE_FREQ) |
|---|
| 572 | 654 | return &standard_mode_spec; |
|---|
| 573 | | - else if (speed <= 400000) |
|---|
| 655 | + else if (speed <= I2C_MAX_FAST_MODE_FREQ) |
|---|
| 574 | 656 | return &fast_mode_spec; |
|---|
| 575 | 657 | else |
|---|
| 576 | 658 | return &fast_mode_plus_spec; |
|---|
| .. | .. |
|---|
| 607 | 689 | int ret = 0; |
|---|
| 608 | 690 | |
|---|
| 609 | 691 | /* Only support standard-mode and fast-mode */ |
|---|
| 610 | | - if (WARN_ON(t->bus_freq_hz > 400000)) |
|---|
| 611 | | - t->bus_freq_hz = 400000; |
|---|
| 692 | + if (WARN_ON(t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ)) |
|---|
| 693 | + t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ; |
|---|
| 612 | 694 | |
|---|
| 613 | 695 | /* prevent scl_rate_khz from becoming 0 */ |
|---|
| 614 | 696 | if (WARN_ON(t->bus_freq_hz < 1000)) |
|---|
| .. | .. |
|---|
| 787 | 869 | int ret = 0; |
|---|
| 788 | 870 | |
|---|
| 789 | 871 | /* Support standard-mode, fast-mode and fast-mode plus */ |
|---|
| 790 | | - if (WARN_ON(t->bus_freq_hz > 1000000)) |
|---|
| 791 | | - t->bus_freq_hz = 1000000; |
|---|
| 872 | + if (WARN_ON(t->bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ)) |
|---|
| 873 | + t->bus_freq_hz = I2C_MAX_FAST_MODE_PLUS_FREQ; |
|---|
| 792 | 874 | |
|---|
| 793 | 875 | /* prevent scl_rate_khz from becoming 0 */ |
|---|
| 794 | 876 | if (WARN_ON(t->bus_freq_hz < 1000)) |
|---|
| .. | .. |
|---|
| 1064 | 1146 | i2c->error = 0; |
|---|
| 1065 | 1147 | |
|---|
| 1066 | 1148 | rk3x_i2c_clean_ipd(i2c); |
|---|
| 1149 | + if (i2c->autostop_supported) |
|---|
| 1150 | + i2c_writel(i2c, 0, REG_CON1); |
|---|
| 1067 | 1151 | |
|---|
| 1068 | 1152 | return ret; |
|---|
| 1069 | 1153 | } |
|---|
| 1070 | 1154 | |
|---|
| 1071 | | -static int rk3x_i2c_xfer(struct i2c_adapter *adap, |
|---|
| 1072 | | - struct i2c_msg *msgs, int num) |
|---|
| 1155 | +static int rk3x_i2c_wait_xfer_poll(struct rk3x_i2c *i2c, unsigned long xfer_time) |
|---|
| 1156 | +{ |
|---|
| 1157 | + ktime_t timeout = ktime_add_ms(ktime_get(), xfer_time); |
|---|
| 1158 | + |
|---|
| 1159 | + while (READ_ONCE(i2c->busy) && |
|---|
| 1160 | + ktime_compare(ktime_get(), timeout) < 0) { |
|---|
| 1161 | + udelay(5); |
|---|
| 1162 | + rk3x_i2c_irq(0, i2c); |
|---|
| 1163 | + } |
|---|
| 1164 | + |
|---|
| 1165 | + return !i2c->busy; |
|---|
| 1166 | +} |
|---|
| 1167 | + |
|---|
| 1168 | +static int rk3x_i2c_xfer_common(struct i2c_adapter *adap, |
|---|
| 1169 | + struct i2c_msg *msgs, int num, bool polling) |
|---|
| 1073 | 1170 | { |
|---|
| 1074 | 1171 | struct rk3x_i2c *i2c = (struct rk3x_i2c *)adap->algo_data; |
|---|
| 1075 | 1172 | unsigned long timeout, flags; |
|---|
| .. | .. |
|---|
| 1092 | 1189 | * rk3x_i2c_setup()). |
|---|
| 1093 | 1190 | */ |
|---|
| 1094 | 1191 | for (i = 0; i < num; i += ret) { |
|---|
| 1095 | | - ret = rk3x_i2c_setup(i2c, msgs + i, num - i); |
|---|
| 1192 | + unsigned long xfer_time = 100; |
|---|
| 1193 | + int len; |
|---|
| 1096 | 1194 | |
|---|
| 1195 | + ret = rk3x_i2c_setup(i2c, msgs + i, num - i); |
|---|
| 1097 | 1196 | if (ret < 0) { |
|---|
| 1098 | 1197 | dev_err(i2c->dev, "rk3x_i2c_setup() failed\n"); |
|---|
| 1099 | 1198 | break; |
|---|
| 1100 | 1199 | } |
|---|
| 1200 | + |
|---|
| 1201 | + /* |
|---|
| 1202 | + * Transfer time in mSec = Total bits / transfer rate + interval time |
|---|
| 1203 | + * Total bits = 9 bits per byte (including ACK bit) + Start & stop bits |
|---|
| 1204 | + */ |
|---|
| 1205 | + if (ret == 2) |
|---|
| 1206 | + len = msgs[i + 1].len; |
|---|
| 1207 | + else |
|---|
| 1208 | + len = msgs[i].len; |
|---|
| 1209 | + xfer_time += len / 64; |
|---|
| 1210 | + xfer_time += DIV_ROUND_CLOSEST(((len * 9) + 2) * MSEC_PER_SEC, |
|---|
| 1211 | + i2c->t.bus_freq_hz); |
|---|
| 1101 | 1212 | |
|---|
| 1102 | 1213 | if (i + ret >= num) |
|---|
| 1103 | 1214 | i2c->is_last_msg = true; |
|---|
| .. | .. |
|---|
| 1106 | 1217 | |
|---|
| 1107 | 1218 | spin_unlock_irqrestore(&i2c->lock, flags); |
|---|
| 1108 | 1219 | |
|---|
| 1109 | | - timeout = wait_event_timeout(i2c->wait, !i2c->busy, |
|---|
| 1110 | | - msecs_to_jiffies(WAIT_TIMEOUT)); |
|---|
| 1220 | + if (!polling) { |
|---|
| 1221 | + timeout = wait_event_timeout(i2c->wait, !i2c->busy, |
|---|
| 1222 | + msecs_to_jiffies(xfer_time)); |
|---|
| 1223 | + } else { |
|---|
| 1224 | + timeout = rk3x_i2c_wait_xfer_poll(i2c, xfer_time); |
|---|
| 1225 | + } |
|---|
| 1111 | 1226 | |
|---|
| 1112 | 1227 | spin_lock_irqsave(&i2c->lock, flags); |
|---|
| 1113 | 1228 | |
|---|
| .. | .. |
|---|
| 1144 | 1259 | return ret < 0 ? ret : num; |
|---|
| 1145 | 1260 | } |
|---|
| 1146 | 1261 | |
|---|
| 1262 | +static int rk3x_i2c_xfer(struct i2c_adapter *adap, |
|---|
| 1263 | + struct i2c_msg *msgs, int num) |
|---|
| 1264 | +{ |
|---|
| 1265 | + return rk3x_i2c_xfer_common(adap, msgs, num, false); |
|---|
| 1266 | +} |
|---|
| 1267 | + |
|---|
| 1268 | +static int rk3x_i2c_xfer_polling(struct i2c_adapter *adap, |
|---|
| 1269 | + struct i2c_msg *msgs, int num) |
|---|
| 1270 | +{ |
|---|
| 1271 | + return rk3x_i2c_xfer_common(adap, msgs, num, true); |
|---|
| 1272 | +} |
|---|
| 1273 | + |
|---|
| 1147 | 1274 | static int rk3x_i2c_restart_notify(struct notifier_block *this, |
|---|
| 1148 | 1275 | unsigned long mode, void *cmd) |
|---|
| 1149 | 1276 | { |
|---|
| .. | .. |
|---|
| 1177 | 1304 | |
|---|
| 1178 | 1305 | return NOTIFY_DONE; |
|---|
| 1179 | 1306 | } |
|---|
| 1307 | + |
|---|
| 1308 | +static unsigned int rk3x_i2c_get_version(struct rk3x_i2c *i2c) |
|---|
| 1309 | +{ |
|---|
| 1310 | + unsigned int version; |
|---|
| 1311 | + |
|---|
| 1312 | + clk_enable(i2c->pclk); |
|---|
| 1313 | + version = i2c_readl(i2c, REG_CON) & REG_CON_VERSION; |
|---|
| 1314 | + clk_disable(i2c->pclk); |
|---|
| 1315 | + version >>= REG_CON_VERSION_SHIFT; |
|---|
| 1316 | + |
|---|
| 1317 | + return version; |
|---|
| 1318 | +} |
|---|
| 1319 | + |
|---|
| 1320 | +static int rk3x_i2c_of_get_bus_id(struct device *dev, struct rk3x_i2c *priv) |
|---|
| 1321 | +{ |
|---|
| 1322 | + int bus_id = -1; |
|---|
| 1323 | + |
|---|
| 1324 | + if (IS_ENABLED(CONFIG_OF) && dev->of_node) |
|---|
| 1325 | + bus_id = of_alias_get_id(dev->of_node, "i2c"); |
|---|
| 1326 | + |
|---|
| 1327 | + return bus_id; |
|---|
| 1328 | +} |
|---|
| 1329 | + |
|---|
| 1330 | +#ifdef CONFIG_ACPI |
|---|
| 1331 | +static int rk3x_i2c_acpi_get_bus_id(struct device *dev, struct rk3x_i2c *priv) |
|---|
| 1332 | +{ |
|---|
| 1333 | + struct acpi_device *adev; |
|---|
| 1334 | + unsigned long bus_id = -1; |
|---|
| 1335 | + const char *uid; |
|---|
| 1336 | + int ret; |
|---|
| 1337 | + |
|---|
| 1338 | + adev = ACPI_COMPANION(dev); |
|---|
| 1339 | + if (!adev) |
|---|
| 1340 | + return -ENXIO; |
|---|
| 1341 | + |
|---|
| 1342 | + uid = acpi_device_uid(adev); |
|---|
| 1343 | + if (!uid || !(*uid)) { |
|---|
| 1344 | + dev_err(dev, "Cannot retrieve UID\n"); |
|---|
| 1345 | + return -ENODEV; |
|---|
| 1346 | + } |
|---|
| 1347 | + |
|---|
| 1348 | + ret = kstrtoul(uid, 0, &bus_id); |
|---|
| 1349 | + |
|---|
| 1350 | + return !ret ? bus_id : -ERANGE; |
|---|
| 1351 | +} |
|---|
| 1352 | +#else |
|---|
| 1353 | +static int rk3x_i2c_acpi_get_bus_id(struct device *dev, struct rk3x_i2c *priv) |
|---|
| 1354 | +{ |
|---|
| 1355 | + return -ENOENT; |
|---|
| 1356 | +} |
|---|
| 1357 | +#endif /* CONFIG_ACPI */ |
|---|
| 1180 | 1358 | |
|---|
| 1181 | 1359 | static __maybe_unused int rk3x_i2c_suspend_noirq(struct device *dev) |
|---|
| 1182 | 1360 | { |
|---|
| .. | .. |
|---|
| 1217 | 1395 | |
|---|
| 1218 | 1396 | static const struct i2c_algorithm rk3x_i2c_algorithm = { |
|---|
| 1219 | 1397 | .master_xfer = rk3x_i2c_xfer, |
|---|
| 1398 | + .master_xfer_atomic = rk3x_i2c_xfer_polling, |
|---|
| 1220 | 1399 | .functionality = rk3x_i2c_func, |
|---|
| 1221 | 1400 | }; |
|---|
| 1222 | 1401 | |
|---|
| .. | .. |
|---|
| 1288 | 1467 | }; |
|---|
| 1289 | 1468 | MODULE_DEVICE_TABLE(of, rk3x_i2c_match); |
|---|
| 1290 | 1469 | |
|---|
| 1470 | +static void rk3x_i2c_tb_cb(void *data) |
|---|
| 1471 | +{ |
|---|
| 1472 | + unsigned long clk_rate; |
|---|
| 1473 | + int ret; |
|---|
| 1474 | + struct rk3x_i2c *i2c = (struct rk3x_i2c *)data; |
|---|
| 1475 | + |
|---|
| 1476 | + if (i2c->clk) { |
|---|
| 1477 | + i2c->clk_rate_nb.notifier_call = rk3x_i2c_clk_notifier_cb; |
|---|
| 1478 | + ret = clk_notifier_register(i2c->clk, &i2c->clk_rate_nb); |
|---|
| 1479 | + if (ret != 0) { |
|---|
| 1480 | + dev_err(i2c->dev, "Unable to register clock notifier\n"); |
|---|
| 1481 | + clk_unprepare(i2c->pclk); |
|---|
| 1482 | + clk_unprepare(i2c->clk); |
|---|
| 1483 | + return; |
|---|
| 1484 | + } |
|---|
| 1485 | + } |
|---|
| 1486 | + |
|---|
| 1487 | + clk_rate = clk_get_rate(i2c->clk); |
|---|
| 1488 | + if (!clk_rate) |
|---|
| 1489 | + device_property_read_u32(i2c->dev, "i2c,clk-rate", (u32 *)&clk_rate); |
|---|
| 1490 | + |
|---|
| 1491 | + rk3x_i2c_adapt_div(i2c, clk_rate); |
|---|
| 1492 | + if (rk3x_i2c_get_version(i2c) >= RK_I2C_VERSION5) |
|---|
| 1493 | + i2c->autostop_supported = true; |
|---|
| 1494 | + enable_irq(i2c->irq); |
|---|
| 1495 | +} |
|---|
| 1496 | + |
|---|
| 1291 | 1497 | static int rk3x_i2c_probe(struct platform_device *pdev) |
|---|
| 1292 | 1498 | { |
|---|
| 1499 | + struct fwnode_handle *fw = dev_fwnode(&pdev->dev); |
|---|
| 1293 | 1500 | struct device_node *np = pdev->dev.of_node; |
|---|
| 1294 | | - const struct of_device_id *match; |
|---|
| 1295 | 1501 | struct rk3x_i2c *i2c; |
|---|
| 1296 | | - struct resource *mem; |
|---|
| 1297 | 1502 | int ret = 0; |
|---|
| 1298 | 1503 | u32 value; |
|---|
| 1299 | 1504 | int irq; |
|---|
| .. | .. |
|---|
| 1303 | 1508 | if (!i2c) |
|---|
| 1304 | 1509 | return -ENOMEM; |
|---|
| 1305 | 1510 | |
|---|
| 1306 | | - match = of_match_node(rk3x_i2c_match, np); |
|---|
| 1307 | | - i2c->soc_data = match->data; |
|---|
| 1511 | + i2c->soc_data = (struct rk3x_i2c_soc_data *)device_get_match_data(&pdev->dev); |
|---|
| 1512 | + |
|---|
| 1513 | + ret = rk3x_i2c_acpi_get_bus_id(&pdev->dev, i2c); |
|---|
| 1514 | + if (ret < 0) { |
|---|
| 1515 | + ret = rk3x_i2c_of_get_bus_id(&pdev->dev, i2c); |
|---|
| 1516 | + if (ret < 0) |
|---|
| 1517 | + return ret; |
|---|
| 1518 | + } |
|---|
| 1519 | + |
|---|
| 1520 | + i2c->adap.nr = ret; |
|---|
| 1308 | 1521 | |
|---|
| 1309 | 1522 | /* use common interface to get I2C timing properties */ |
|---|
| 1310 | 1523 | i2c_parse_fw_timings(&pdev->dev, &i2c->t, true); |
|---|
| .. | .. |
|---|
| 1313 | 1526 | i2c->adap.owner = THIS_MODULE; |
|---|
| 1314 | 1527 | i2c->adap.algo = &rk3x_i2c_algorithm; |
|---|
| 1315 | 1528 | i2c->adap.retries = 3; |
|---|
| 1316 | | - i2c->adap.dev.of_node = np; |
|---|
| 1529 | + i2c->adap.dev.of_node = pdev->dev.of_node; |
|---|
| 1317 | 1530 | i2c->adap.algo_data = i2c; |
|---|
| 1318 | 1531 | i2c->adap.dev.parent = &pdev->dev; |
|---|
| 1532 | + i2c->adap.dev.fwnode = fw; |
|---|
| 1319 | 1533 | |
|---|
| 1320 | 1534 | i2c->dev = &pdev->dev; |
|---|
| 1321 | 1535 | |
|---|
| .. | .. |
|---|
| 1330 | 1544 | return ret; |
|---|
| 1331 | 1545 | } |
|---|
| 1332 | 1546 | |
|---|
| 1333 | | - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 1334 | | - i2c->regs = devm_ioremap_resource(&pdev->dev, mem); |
|---|
| 1547 | + i2c->regs = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 1335 | 1548 | if (IS_ERR(i2c->regs)) |
|---|
| 1336 | 1549 | return PTR_ERR(i2c->regs); |
|---|
| 1337 | 1550 | |
|---|
| .. | .. |
|---|
| 1344 | 1557 | |
|---|
| 1345 | 1558 | grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); |
|---|
| 1346 | 1559 | if (!IS_ERR(grf)) { |
|---|
| 1347 | | - int bus_nr; |
|---|
| 1348 | | - |
|---|
| 1349 | | - /* Try to set the I2C adapter number from dt */ |
|---|
| 1350 | | - bus_nr = of_alias_get_id(np, "i2c"); |
|---|
| 1351 | | - if (bus_nr < 0) { |
|---|
| 1352 | | - dev_err(&pdev->dev, "rk3x-i2c needs i2cX alias"); |
|---|
| 1353 | | - return -EINVAL; |
|---|
| 1354 | | - } |
|---|
| 1560 | + int bus_nr = i2c->adap.nr; |
|---|
| 1355 | 1561 | |
|---|
| 1356 | 1562 | if (i2c->soc_data == &rv1108_soc_data && bus_nr == 2) |
|---|
| 1357 | 1563 | /* rv1108 i2c2 set grf offset-0x408, bit-10 */ |
|---|
| .. | .. |
|---|
| 1376 | 1582 | |
|---|
| 1377 | 1583 | /* IRQ setup */ |
|---|
| 1378 | 1584 | irq = platform_get_irq(pdev, 0); |
|---|
| 1379 | | - if (irq < 0) { |
|---|
| 1380 | | - dev_err(&pdev->dev, "cannot find rk3x IRQ\n"); |
|---|
| 1585 | + if (irq < 0) |
|---|
| 1381 | 1586 | return irq; |
|---|
| 1587 | + i2c->irq = irq; |
|---|
| 1588 | + |
|---|
| 1589 | + if (IS_ENABLED(CONFIG_ROCKCHIP_THUNDER_BOOT_SERVICE) && |
|---|
| 1590 | + device_property_read_bool(&pdev->dev, "rockchip,amp-shared")) { |
|---|
| 1591 | + i2c->tb_cl.data = i2c; |
|---|
| 1592 | + i2c->tb_cl.cb = rk3x_i2c_tb_cb; |
|---|
| 1593 | + irq_set_status_flags(irq, IRQ_NOAUTOEN); |
|---|
| 1382 | 1594 | } |
|---|
| 1383 | 1595 | |
|---|
| 1384 | 1596 | ret = devm_request_irq(&pdev->dev, irq, rk3x_i2c_irq, |
|---|
| .. | .. |
|---|
| 1390 | 1602 | |
|---|
| 1391 | 1603 | platform_set_drvdata(pdev, i2c); |
|---|
| 1392 | 1604 | |
|---|
| 1393 | | - if (i2c->soc_data->calc_timings == rk3x_i2c_v0_calc_timings) { |
|---|
| 1394 | | - /* Only one clock to use for bus clock and peripheral clock */ |
|---|
| 1395 | | - i2c->clk = devm_clk_get(&pdev->dev, NULL); |
|---|
| 1396 | | - i2c->pclk = i2c->clk; |
|---|
| 1397 | | - } else { |
|---|
| 1398 | | - i2c->clk = devm_clk_get(&pdev->dev, "i2c"); |
|---|
| 1399 | | - i2c->pclk = devm_clk_get(&pdev->dev, "pclk"); |
|---|
| 1400 | | - } |
|---|
| 1605 | + if (!has_acpi_companion(&pdev->dev)) { |
|---|
| 1606 | + if (i2c->soc_data->calc_timings == rk3x_i2c_v0_calc_timings) { |
|---|
| 1607 | + /* Only one clock to use for bus clock and peripheral clock */ |
|---|
| 1608 | + i2c->clk = devm_clk_get(&pdev->dev, NULL); |
|---|
| 1609 | + i2c->pclk = i2c->clk; |
|---|
| 1610 | + } else { |
|---|
| 1611 | + i2c->clk = devm_clk_get(&pdev->dev, "i2c"); |
|---|
| 1612 | + i2c->pclk = devm_clk_get(&pdev->dev, "pclk"); |
|---|
| 1613 | + } |
|---|
| 1401 | 1614 | |
|---|
| 1402 | | - if (IS_ERR(i2c->clk)) { |
|---|
| 1403 | | - ret = PTR_ERR(i2c->clk); |
|---|
| 1404 | | - if (ret != -EPROBE_DEFER) |
|---|
| 1405 | | - dev_err(&pdev->dev, "Can't get bus clk: %d\n", ret); |
|---|
| 1406 | | - return ret; |
|---|
| 1407 | | - } |
|---|
| 1408 | | - if (IS_ERR(i2c->pclk)) { |
|---|
| 1409 | | - ret = PTR_ERR(i2c->pclk); |
|---|
| 1410 | | - if (ret != -EPROBE_DEFER) |
|---|
| 1411 | | - dev_err(&pdev->dev, "Can't get periph clk: %d\n", ret); |
|---|
| 1412 | | - return ret; |
|---|
| 1615 | + if (IS_ERR(i2c->clk)) |
|---|
| 1616 | + return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk), |
|---|
| 1617 | + "Can't get bus clk\n"); |
|---|
| 1618 | + |
|---|
| 1619 | + if (IS_ERR(i2c->pclk)) |
|---|
| 1620 | + return dev_err_probe(&pdev->dev, PTR_ERR(i2c->pclk), |
|---|
| 1621 | + "Can't get periph clk\n"); |
|---|
| 1413 | 1622 | } |
|---|
| 1414 | 1623 | |
|---|
| 1415 | 1624 | ret = clk_prepare(i2c->clk); |
|---|
| .. | .. |
|---|
| 1423 | 1632 | goto err_clk; |
|---|
| 1424 | 1633 | } |
|---|
| 1425 | 1634 | |
|---|
| 1426 | | - i2c->clk_rate_nb.notifier_call = rk3x_i2c_clk_notifier_cb; |
|---|
| 1427 | | - ret = clk_notifier_register(i2c->clk, &i2c->clk_rate_nb); |
|---|
| 1428 | | - if (ret != 0) { |
|---|
| 1429 | | - dev_err(&pdev->dev, "Unable to register clock notifier\n"); |
|---|
| 1430 | | - goto err_pclk; |
|---|
| 1635 | + if (IS_ENABLED(CONFIG_ROCKCHIP_THUNDER_BOOT_SERVICE) && i2c->tb_cl.cb) { |
|---|
| 1636 | + rk_tb_client_register_cb(&i2c->tb_cl); |
|---|
| 1637 | + } else { |
|---|
| 1638 | + if (i2c->clk) { |
|---|
| 1639 | + i2c->clk_rate_nb.notifier_call = rk3x_i2c_clk_notifier_cb; |
|---|
| 1640 | + ret = clk_notifier_register(i2c->clk, &i2c->clk_rate_nb); |
|---|
| 1641 | + if (ret != 0) { |
|---|
| 1642 | + dev_err(&pdev->dev, "Unable to register clock notifier\n"); |
|---|
| 1643 | + goto err_pclk; |
|---|
| 1644 | + } |
|---|
| 1645 | + } |
|---|
| 1646 | + |
|---|
| 1647 | + clk_rate = clk_get_rate(i2c->clk); |
|---|
| 1648 | + if (!clk_rate) |
|---|
| 1649 | + device_property_read_u32(&pdev->dev, "i2c,clk-rate", (u32 *)&clk_rate); |
|---|
| 1650 | + |
|---|
| 1651 | + rk3x_i2c_adapt_div(i2c, clk_rate); |
|---|
| 1652 | + |
|---|
| 1653 | + if (rk3x_i2c_get_version(i2c) >= RK_I2C_VERSION5) |
|---|
| 1654 | + i2c->autostop_supported = true; |
|---|
| 1431 | 1655 | } |
|---|
| 1432 | 1656 | |
|---|
| 1433 | | - clk_rate = clk_get_rate(i2c->clk); |
|---|
| 1434 | | - rk3x_i2c_adapt_div(i2c, clk_rate); |
|---|
| 1435 | | - |
|---|
| 1436 | | - ret = i2c_add_adapter(&i2c->adap); |
|---|
| 1657 | + ret = i2c_add_numbered_adapter(&i2c->adap); |
|---|
| 1437 | 1658 | if (ret < 0) |
|---|
| 1438 | 1659 | goto err_clk_notifier; |
|---|
| 1439 | 1660 | |
|---|
| .. | .. |
|---|
| 1462 | 1683 | return 0; |
|---|
| 1463 | 1684 | } |
|---|
| 1464 | 1685 | |
|---|
| 1465 | | -const static struct dev_pm_ops rk3x_i2c_pm_ops = { |
|---|
| 1686 | +static const struct dev_pm_ops rk3x_i2c_pm_ops = { |
|---|
| 1466 | 1687 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rk3x_i2c_suspend_noirq, |
|---|
| 1467 | 1688 | rk3x_i2c_resume_noirq) |
|---|
| 1468 | 1689 | }; |
|---|
| .. | .. |
|---|
| 1482 | 1703 | { |
|---|
| 1483 | 1704 | return platform_driver_register(&rk3x_i2c_driver); |
|---|
| 1484 | 1705 | } |
|---|
| 1706 | +#ifdef CONFIG_INITCALL_ASYNC |
|---|
| 1485 | 1707 | subsys_initcall_sync(rk3x_i2c_driver_init); |
|---|
| 1708 | +#else |
|---|
| 1709 | +subsys_initcall(rk3x_i2c_driver_init); |
|---|
| 1710 | +#endif |
|---|
| 1486 | 1711 | |
|---|
| 1487 | 1712 | static void __exit rk3x_i2c_driver_exit(void) |
|---|
| 1488 | 1713 | { |
|---|