0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/delay.h>
0016 #include <linux/i2c.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020
0021 #include "i2c-octeon-core.h"
0022
0023
0024 irqreturn_t octeon_i2c_isr(int irq, void *dev_id)
0025 {
0026 struct octeon_i2c *i2c = dev_id;
0027
0028 i2c->int_disable(i2c);
0029 wake_up(&i2c->queue);
0030
0031 return IRQ_HANDLED;
0032 }
0033
0034 static bool octeon_i2c_test_iflg(struct octeon_i2c *i2c)
0035 {
0036 return (octeon_i2c_ctl_read(i2c) & TWSI_CTL_IFLG);
0037 }
0038
0039
0040
0041
0042
0043
0044
0045 static int octeon_i2c_wait(struct octeon_i2c *i2c)
0046 {
0047 long time_left;
0048
0049
0050
0051
0052
0053 if (i2c->broken_irq_mode) {
0054 u64 end = get_jiffies_64() + i2c->adap.timeout;
0055
0056 while (!octeon_i2c_test_iflg(i2c) &&
0057 time_before64(get_jiffies_64(), end))
0058 usleep_range(I2C_OCTEON_EVENT_WAIT / 2, I2C_OCTEON_EVENT_WAIT);
0059
0060 return octeon_i2c_test_iflg(i2c) ? 0 : -ETIMEDOUT;
0061 }
0062
0063 i2c->int_enable(i2c);
0064 time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_iflg(i2c),
0065 i2c->adap.timeout);
0066 i2c->int_disable(i2c);
0067
0068 if (i2c->broken_irq_check && !time_left &&
0069 octeon_i2c_test_iflg(i2c)) {
0070 dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n");
0071 i2c->broken_irq_mode = true;
0072 return 0;
0073 }
0074
0075 if (!time_left)
0076 return -ETIMEDOUT;
0077
0078 return 0;
0079 }
0080
0081 static bool octeon_i2c_hlc_test_valid(struct octeon_i2c *i2c)
0082 {
0083 return (__raw_readq(i2c->twsi_base + SW_TWSI(i2c)) & SW_TWSI_V) == 0;
0084 }
0085
0086 static void octeon_i2c_hlc_int_clear(struct octeon_i2c *i2c)
0087 {
0088
0089 octeon_i2c_write_int(i2c, TWSI_INT_ST_INT | TWSI_INT_TS_INT);
0090 }
0091
0092
0093
0094
0095 static void octeon_i2c_hlc_enable(struct octeon_i2c *i2c)
0096 {
0097 int try = 0;
0098 u64 val;
0099
0100 if (i2c->hlc_enabled)
0101 return;
0102 i2c->hlc_enabled = true;
0103
0104 while (1) {
0105 val = octeon_i2c_ctl_read(i2c);
0106 if (!(val & (TWSI_CTL_STA | TWSI_CTL_STP)))
0107 break;
0108
0109
0110 if (val & TWSI_CTL_IFLG)
0111 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
0112
0113 if (try++ > 100) {
0114 pr_err("%s: giving up\n", __func__);
0115 break;
0116 }
0117
0118
0119 udelay(10);
0120 }
0121 octeon_i2c_ctl_write(i2c, TWSI_CTL_CE | TWSI_CTL_AAK | TWSI_CTL_ENAB);
0122 }
0123
0124 static void octeon_i2c_hlc_disable(struct octeon_i2c *i2c)
0125 {
0126 if (!i2c->hlc_enabled)
0127 return;
0128
0129 i2c->hlc_enabled = false;
0130 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
0131 }
0132
0133
0134
0135
0136
0137
0138
0139 static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c)
0140 {
0141 int time_left;
0142
0143
0144
0145
0146
0147 if (i2c->broken_irq_mode) {
0148 u64 end = get_jiffies_64() + i2c->adap.timeout;
0149
0150 while (!octeon_i2c_hlc_test_valid(i2c) &&
0151 time_before64(get_jiffies_64(), end))
0152 usleep_range(I2C_OCTEON_EVENT_WAIT / 2, I2C_OCTEON_EVENT_WAIT);
0153
0154 return octeon_i2c_hlc_test_valid(i2c) ? 0 : -ETIMEDOUT;
0155 }
0156
0157 i2c->hlc_int_enable(i2c);
0158 time_left = wait_event_timeout(i2c->queue,
0159 octeon_i2c_hlc_test_valid(i2c),
0160 i2c->adap.timeout);
0161 i2c->hlc_int_disable(i2c);
0162 if (!time_left)
0163 octeon_i2c_hlc_int_clear(i2c);
0164
0165 if (i2c->broken_irq_check && !time_left &&
0166 octeon_i2c_hlc_test_valid(i2c)) {
0167 dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n");
0168 i2c->broken_irq_mode = true;
0169 return 0;
0170 }
0171
0172 if (!time_left)
0173 return -ETIMEDOUT;
0174 return 0;
0175 }
0176
0177 static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read)
0178 {
0179 u8 stat;
0180
0181
0182
0183
0184
0185 if (i2c->hlc_enabled)
0186 stat = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
0187 else
0188 stat = octeon_i2c_stat_read(i2c);
0189
0190 switch (stat) {
0191
0192 case STAT_IDLE:
0193 case STAT_AD2W_ACK:
0194 case STAT_RXADDR_ACK:
0195 case STAT_TXADDR_ACK:
0196 case STAT_TXDATA_ACK:
0197 return 0;
0198
0199
0200 case STAT_RXDATA_ACK:
0201 if (!final_read)
0202 return 0;
0203 return -EIO;
0204
0205
0206 case STAT_RXDATA_NAK:
0207 if (final_read)
0208 return 0;
0209 return -EIO;
0210
0211
0212 case STAT_LOST_ARB_38:
0213 case STAT_LOST_ARB_68:
0214 case STAT_LOST_ARB_78:
0215 case STAT_LOST_ARB_B0:
0216 return -EAGAIN;
0217
0218
0219 case STAT_SLAVE_60:
0220 case STAT_SLAVE_70:
0221 case STAT_GENDATA_ACK:
0222 case STAT_GENDATA_NAK:
0223 return -EOPNOTSUPP;
0224
0225
0226 case STAT_SLAVE_80:
0227 case STAT_SLAVE_88:
0228 case STAT_SLAVE_A0:
0229 case STAT_SLAVE_A8:
0230 case STAT_SLAVE_LOST:
0231 case STAT_SLAVE_NAK:
0232 case STAT_SLAVE_ACK:
0233 return -EOPNOTSUPP;
0234
0235 case STAT_TXDATA_NAK:
0236 case STAT_BUS_ERROR:
0237 return -EIO;
0238 case STAT_TXADDR_NAK:
0239 case STAT_RXADDR_NAK:
0240 case STAT_AD2W_NAK:
0241 return -ENXIO;
0242 default:
0243 dev_err(i2c->dev, "unhandled state: %d\n", stat);
0244 return -EIO;
0245 }
0246 }
0247
0248 static int octeon_i2c_recovery(struct octeon_i2c *i2c)
0249 {
0250 int ret;
0251
0252 ret = i2c_recover_bus(&i2c->adap);
0253 if (ret)
0254
0255 ret = octeon_i2c_init_lowlevel(i2c);
0256 return ret;
0257 }
0258
0259
0260
0261
0262
0263
0264
0265 static int octeon_i2c_start(struct octeon_i2c *i2c)
0266 {
0267 int ret;
0268 u8 stat;
0269
0270 octeon_i2c_hlc_disable(i2c);
0271
0272 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STA);
0273 ret = octeon_i2c_wait(i2c);
0274 if (ret)
0275 goto error;
0276
0277 stat = octeon_i2c_stat_read(i2c);
0278 if (stat == STAT_START || stat == STAT_REP_START)
0279
0280 return 0;
0281
0282 error:
0283
0284 ret = octeon_i2c_recovery(i2c);
0285 return (ret) ? ret : -EAGAIN;
0286 }
0287
0288
0289 static void octeon_i2c_stop(struct octeon_i2c *i2c)
0290 {
0291 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_STP);
0292 }
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306 static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
0307 u8 *data, u16 *rlength, bool recv_len)
0308 {
0309 int i, result, length = *rlength;
0310 bool final_read = false;
0311
0312 octeon_i2c_data_write(i2c, (target << 1) | 1);
0313 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
0314
0315 result = octeon_i2c_wait(i2c);
0316 if (result)
0317 return result;
0318
0319
0320 result = octeon_i2c_check_status(i2c, false);
0321 if (result)
0322 return result;
0323
0324 for (i = 0; i < length; i++) {
0325
0326
0327
0328
0329
0330
0331
0332
0333 if ((i + 1 == length) && !(recv_len && i == 0))
0334 final_read = true;
0335
0336
0337 if (final_read)
0338 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
0339 else
0340 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB | TWSI_CTL_AAK);
0341
0342 result = octeon_i2c_wait(i2c);
0343 if (result)
0344 return result;
0345
0346 data[i] = octeon_i2c_data_read(i2c, &result);
0347 if (result)
0348 return result;
0349 if (recv_len && i == 0) {
0350 if (data[i] > I2C_SMBUS_BLOCK_MAX)
0351 return -EPROTO;
0352 length += data[i];
0353 }
0354
0355 result = octeon_i2c_check_status(i2c, final_read);
0356 if (result)
0357 return result;
0358 }
0359 *rlength = length;
0360 return 0;
0361 }
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374 static int octeon_i2c_write(struct octeon_i2c *i2c, int target,
0375 const u8 *data, int length)
0376 {
0377 int i, result;
0378
0379 octeon_i2c_data_write(i2c, target << 1);
0380 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
0381
0382 result = octeon_i2c_wait(i2c);
0383 if (result)
0384 return result;
0385
0386 for (i = 0; i < length; i++) {
0387 result = octeon_i2c_check_status(i2c, false);
0388 if (result)
0389 return result;
0390
0391 octeon_i2c_data_write(i2c, data[i]);
0392 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
0393
0394 result = octeon_i2c_wait(i2c);
0395 if (result)
0396 return result;
0397 }
0398
0399 return 0;
0400 }
0401
0402
0403 static int octeon_i2c_hlc_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
0404 {
0405 int i, j, ret = 0;
0406 u64 cmd;
0407
0408 octeon_i2c_hlc_enable(i2c);
0409 octeon_i2c_hlc_int_clear(i2c);
0410
0411 cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR;
0412
0413 cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT;
0414
0415 cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
0416
0417 if (msgs[0].flags & I2C_M_TEN)
0418 cmd |= SW_TWSI_OP_10;
0419 else
0420 cmd |= SW_TWSI_OP_7;
0421
0422 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
0423 ret = octeon_i2c_hlc_wait(i2c);
0424 if (ret)
0425 goto err;
0426
0427 cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
0428 if ((cmd & SW_TWSI_R) == 0)
0429 return octeon_i2c_check_status(i2c, false);
0430
0431 for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--)
0432 msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
0433
0434 if (msgs[0].len > 4) {
0435 cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT(i2c));
0436 for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--)
0437 msgs[0].buf[j] = (cmd >> (8 * i)) & 0xff;
0438 }
0439
0440 err:
0441 return ret;
0442 }
0443
0444
0445 static int octeon_i2c_hlc_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
0446 {
0447 int i, j, ret = 0;
0448 u64 cmd;
0449
0450 octeon_i2c_hlc_enable(i2c);
0451 octeon_i2c_hlc_int_clear(i2c);
0452
0453 cmd = SW_TWSI_V | SW_TWSI_SOVR;
0454
0455 cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT;
0456
0457 cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
0458
0459 if (msgs[0].flags & I2C_M_TEN)
0460 cmd |= SW_TWSI_OP_10;
0461 else
0462 cmd |= SW_TWSI_OP_7;
0463
0464 for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--)
0465 cmd |= (u64)msgs[0].buf[j] << (8 * i);
0466
0467 if (msgs[0].len > 4) {
0468 u64 ext = 0;
0469
0470 for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--)
0471 ext |= (u64)msgs[0].buf[j] << (8 * i);
0472 octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
0473 }
0474
0475 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
0476 ret = octeon_i2c_hlc_wait(i2c);
0477 if (ret)
0478 goto err;
0479
0480 cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
0481 if ((cmd & SW_TWSI_R) == 0)
0482 return octeon_i2c_check_status(i2c, false);
0483
0484 err:
0485 return ret;
0486 }
0487
0488
0489 static int octeon_i2c_hlc_comp_read(struct octeon_i2c *i2c, struct i2c_msg *msgs)
0490 {
0491 int i, j, ret = 0;
0492 u64 cmd;
0493
0494 octeon_i2c_hlc_enable(i2c);
0495
0496 cmd = SW_TWSI_V | SW_TWSI_R | SW_TWSI_SOVR;
0497
0498 cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT;
0499
0500 cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
0501
0502 if (msgs[0].flags & I2C_M_TEN)
0503 cmd |= SW_TWSI_OP_10_IA;
0504 else
0505 cmd |= SW_TWSI_OP_7_IA;
0506
0507 if (msgs[0].len == 2) {
0508 u64 ext = 0;
0509
0510 cmd |= SW_TWSI_EIA;
0511 ext = (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
0512 cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
0513 octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
0514 } else {
0515 cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
0516 }
0517
0518 octeon_i2c_hlc_int_clear(i2c);
0519 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
0520
0521 ret = octeon_i2c_hlc_wait(i2c);
0522 if (ret)
0523 goto err;
0524
0525 cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
0526 if ((cmd & SW_TWSI_R) == 0)
0527 return octeon_i2c_check_status(i2c, false);
0528
0529 for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--)
0530 msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
0531
0532 if (msgs[1].len > 4) {
0533 cmd = __raw_readq(i2c->twsi_base + SW_TWSI_EXT(i2c));
0534 for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--)
0535 msgs[1].buf[j] = (cmd >> (8 * i)) & 0xff;
0536 }
0537
0538 err:
0539 return ret;
0540 }
0541
0542
0543 static int octeon_i2c_hlc_comp_write(struct octeon_i2c *i2c, struct i2c_msg *msgs)
0544 {
0545 bool set_ext = false;
0546 int i, j, ret = 0;
0547 u64 cmd, ext = 0;
0548
0549 octeon_i2c_hlc_enable(i2c);
0550
0551 cmd = SW_TWSI_V | SW_TWSI_SOVR;
0552
0553 cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT;
0554
0555 cmd |= (u64)(msgs[0].addr & 0x7full) << SW_TWSI_ADDR_SHIFT;
0556
0557 if (msgs[0].flags & I2C_M_TEN)
0558 cmd |= SW_TWSI_OP_10_IA;
0559 else
0560 cmd |= SW_TWSI_OP_7_IA;
0561
0562 if (msgs[0].len == 2) {
0563 cmd |= SW_TWSI_EIA;
0564 ext |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
0565 set_ext = true;
0566 cmd |= (u64)msgs[0].buf[1] << SW_TWSI_IA_SHIFT;
0567 } else {
0568 cmd |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT;
0569 }
0570
0571 for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--)
0572 cmd |= (u64)msgs[1].buf[j] << (8 * i);
0573
0574 if (msgs[1].len > 4) {
0575 for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--)
0576 ext |= (u64)msgs[1].buf[j] << (8 * i);
0577 set_ext = true;
0578 }
0579 if (set_ext)
0580 octeon_i2c_writeq_flush(ext, i2c->twsi_base + SW_TWSI_EXT(i2c));
0581
0582 octeon_i2c_hlc_int_clear(i2c);
0583 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + SW_TWSI(i2c));
0584
0585 ret = octeon_i2c_hlc_wait(i2c);
0586 if (ret)
0587 goto err;
0588
0589 cmd = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
0590 if ((cmd & SW_TWSI_R) == 0)
0591 return octeon_i2c_check_status(i2c, false);
0592
0593 err:
0594 return ret;
0595 }
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 int octeon_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
0606 {
0607 struct octeon_i2c *i2c = i2c_get_adapdata(adap);
0608 int i, ret = 0;
0609
0610 if (num == 1) {
0611 if (msgs[0].len > 0 && msgs[0].len <= 8) {
0612 if (msgs[0].flags & I2C_M_RD)
0613 ret = octeon_i2c_hlc_read(i2c, msgs);
0614 else
0615 ret = octeon_i2c_hlc_write(i2c, msgs);
0616 goto out;
0617 }
0618 } else if (num == 2) {
0619 if ((msgs[0].flags & I2C_M_RD) == 0 &&
0620 (msgs[1].flags & I2C_M_RECV_LEN) == 0 &&
0621 msgs[0].len > 0 && msgs[0].len <= 2 &&
0622 msgs[1].len > 0 && msgs[1].len <= 8 &&
0623 msgs[0].addr == msgs[1].addr) {
0624 if (msgs[1].flags & I2C_M_RD)
0625 ret = octeon_i2c_hlc_comp_read(i2c, msgs);
0626 else
0627 ret = octeon_i2c_hlc_comp_write(i2c, msgs);
0628 goto out;
0629 }
0630 }
0631
0632 for (i = 0; ret == 0 && i < num; i++) {
0633 struct i2c_msg *pmsg = &msgs[i];
0634
0635
0636 if (!pmsg->len) {
0637 ret = -EOPNOTSUPP;
0638 break;
0639 }
0640
0641 ret = octeon_i2c_start(i2c);
0642 if (ret)
0643 return ret;
0644
0645 if (pmsg->flags & I2C_M_RD)
0646 ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf,
0647 &pmsg->len, pmsg->flags & I2C_M_RECV_LEN);
0648 else
0649 ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf,
0650 pmsg->len);
0651 }
0652 octeon_i2c_stop(i2c);
0653 out:
0654 return (ret != 0) ? ret : num;
0655 }
0656
0657
0658 void octeon_i2c_set_clock(struct octeon_i2c *i2c)
0659 {
0660 int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
0661 int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
0662
0663 for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) {
0664
0665
0666
0667
0668 for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) {
0669
0670
0671
0672
0673 tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10;
0674 tclk *= (1 << ndiv_idx);
0675 thp_base = (i2c->sys_freq / (tclk * 2)) - 1;
0676
0677 for (inc = 0; inc <= 1; inc++) {
0678 thp_idx = thp_base + inc;
0679 if (thp_idx < 5 || thp_idx > 0xff)
0680 continue;
0681
0682 foscl = i2c->sys_freq / (2 * (thp_idx + 1));
0683 foscl = foscl / (1 << ndiv_idx);
0684 foscl = foscl / (mdiv_idx + 1) / 10;
0685 diff = abs(foscl - i2c->twsi_freq);
0686 if (diff < delta_hz) {
0687 delta_hz = diff;
0688 thp = thp_idx;
0689 mdiv = mdiv_idx;
0690 ndiv = ndiv_idx;
0691 }
0692 }
0693 }
0694 }
0695 octeon_i2c_reg_write(i2c, SW_TWSI_OP_TWSI_CLK, thp);
0696 octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv);
0697 }
0698
0699 int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c)
0700 {
0701 u8 status = 0;
0702 int tries;
0703
0704
0705 octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_RST, 0);
0706
0707 for (tries = 10; tries && status != STAT_IDLE; tries--) {
0708 udelay(1);
0709 status = octeon_i2c_stat_read(i2c);
0710 if (status == STAT_IDLE)
0711 break;
0712 }
0713
0714 if (status != STAT_IDLE) {
0715 dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n",
0716 __func__, status);
0717 return -EIO;
0718 }
0719
0720
0721 octeon_i2c_hlc_enable(i2c);
0722 octeon_i2c_hlc_disable(i2c);
0723 return 0;
0724 }
0725
0726 static int octeon_i2c_get_scl(struct i2c_adapter *adap)
0727 {
0728 struct octeon_i2c *i2c = i2c_get_adapdata(adap);
0729 u64 state;
0730
0731 state = octeon_i2c_read_int(i2c);
0732 return state & TWSI_INT_SCL;
0733 }
0734
0735 static void octeon_i2c_set_scl(struct i2c_adapter *adap, int val)
0736 {
0737 struct octeon_i2c *i2c = i2c_get_adapdata(adap);
0738
0739 octeon_i2c_write_int(i2c, val ? 0 : TWSI_INT_SCL_OVR);
0740 }
0741
0742 static int octeon_i2c_get_sda(struct i2c_adapter *adap)
0743 {
0744 struct octeon_i2c *i2c = i2c_get_adapdata(adap);
0745 u64 state;
0746
0747 state = octeon_i2c_read_int(i2c);
0748 return state & TWSI_INT_SDA;
0749 }
0750
0751 static void octeon_i2c_prepare_recovery(struct i2c_adapter *adap)
0752 {
0753 struct octeon_i2c *i2c = i2c_get_adapdata(adap);
0754
0755 octeon_i2c_hlc_disable(i2c);
0756 octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_RST, 0);
0757
0758 udelay(5);
0759
0760
0761
0762
0763
0764 octeon_i2c_ctl_write(i2c, TWSI_CTL_ENAB);
0765
0766 octeon_i2c_write_int(i2c, 0);
0767 }
0768
0769 static void octeon_i2c_unprepare_recovery(struct i2c_adapter *adap)
0770 {
0771 struct octeon_i2c *i2c = i2c_get_adapdata(adap);
0772
0773
0774
0775
0776
0777
0778 octeon_i2c_write_int(i2c, TWSI_INT_SDA_OVR | TWSI_INT_SCL_OVR);
0779 udelay(5);
0780 octeon_i2c_write_int(i2c, TWSI_INT_SDA_OVR);
0781 udelay(5);
0782 octeon_i2c_write_int(i2c, 0);
0783 }
0784
0785 struct i2c_bus_recovery_info octeon_i2c_recovery_info = {
0786 .recover_bus = i2c_generic_scl_recovery,
0787 .get_scl = octeon_i2c_get_scl,
0788 .set_scl = octeon_i2c_set_scl,
0789 .get_sda = octeon_i2c_get_sda,
0790 .prepare_recovery = octeon_i2c_prepare_recovery,
0791 .unprepare_recovery = octeon_i2c_unprepare_recovery,
0792 };