Lines Matching +full:ext +full:- +full:irq +full:- +full:range

2  * (C) Copyright 2009-2010
3 * Nokia Siemens Networks, michael.lawnick.ext@nsn.com
5 * Portions Copyright (C) 2010 - 2016 Cavium, Inc.
22 #include "i2c-octeon-core.h"
29 irqreturn_t octeon_i2c_isr(int irq, void *dev_id) in octeon_i2c_isr() argument
33 i2c->int_disable(i2c); in octeon_i2c_isr()
34 wake_up(&i2c->queue); in octeon_i2c_isr()
45 * octeon_i2c_wait - wait for the IFLG to be set
55 * Some chip revisions don't assert the irq in the interrupt in octeon_i2c_wait()
58 if (i2c->broken_irq_mode) { in octeon_i2c_wait()
59 u64 end = get_jiffies_64() + i2c->adap.timeout; in octeon_i2c_wait()
65 return octeon_i2c_test_iflg(i2c) ? 0 : -ETIMEDOUT; in octeon_i2c_wait()
68 i2c->int_enable(i2c); in octeon_i2c_wait()
69 time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_iflg(i2c), in octeon_i2c_wait()
70 i2c->adap.timeout); in octeon_i2c_wait()
71 i2c->int_disable(i2c); in octeon_i2c_wait()
73 if (i2c->broken_irq_check && !time_left && in octeon_i2c_wait()
75 dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n"); in octeon_i2c_wait()
76 i2c->broken_irq_mode = true; in octeon_i2c_wait()
81 return -ETIMEDOUT; in octeon_i2c_wait()
88 return (__raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)) & SW_TWSI_V) == 0; in octeon_i2c_hlc_test_valid()
98 * Cleanup low-level state & enable high-level controller.
105 if (i2c->hlc_enabled) in octeon_i2c_hlc_enable()
107 i2c->hlc_enabled = true; in octeon_i2c_hlc_enable()
131 if (!i2c->hlc_enabled) in octeon_i2c_hlc_disable()
134 i2c->hlc_enabled = false; in octeon_i2c_hlc_disable()
139 * octeon_i2c_hlc_wait - wait for an HLC operation to complete
142 * Returns 0 on success, otherwise -ETIMEDOUT.
149 * Some cn38xx boards don't assert the irq in the interrupt in octeon_i2c_hlc_wait()
152 if (i2c->broken_irq_mode) { in octeon_i2c_hlc_wait()
153 u64 end = get_jiffies_64() + i2c->adap.timeout; in octeon_i2c_hlc_wait()
159 return octeon_i2c_hlc_test_valid(i2c) ? 0 : -ETIMEDOUT; in octeon_i2c_hlc_wait()
162 i2c->hlc_int_enable(i2c); in octeon_i2c_hlc_wait()
163 time_left = wait_event_timeout(i2c->queue, in octeon_i2c_hlc_wait()
165 i2c->adap.timeout); in octeon_i2c_hlc_wait()
166 i2c->hlc_int_disable(i2c); in octeon_i2c_hlc_wait()
170 if (i2c->broken_irq_check && !time_left && in octeon_i2c_hlc_wait()
172 dev_err(i2c->dev, "broken irq connection detected, switching to polling mode.\n"); in octeon_i2c_hlc_wait()
173 i2c->broken_irq_mode = true; in octeon_i2c_hlc_wait()
178 return -ETIMEDOUT; in octeon_i2c_hlc_wait()
191 if (i2c->hlc_enabled) in octeon_i2c_check_status()
192 stat = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_check_status()
205 /* ACK allowed on pre-terminal bytes only */ in octeon_i2c_check_status()
209 return -EIO; in octeon_i2c_check_status()
215 return -EIO; in octeon_i2c_check_status()
222 return -EAGAIN; in octeon_i2c_check_status()
229 return -EOPNOTSUPP; in octeon_i2c_check_status()
239 return -EOPNOTSUPP; in octeon_i2c_check_status()
243 return -EIO; in octeon_i2c_check_status()
247 return -ENXIO; in octeon_i2c_check_status()
250 mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_check_status()
253 octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_check_status()
254 return -EIO; in octeon_i2c_check_status()
256 dev_err(i2c->dev, "unhandled state: %d\n", stat); in octeon_i2c_check_status()
257 return -EIO; in octeon_i2c_check_status()
265 ret = i2c_recover_bus(&i2c->adap); in octeon_i2c_recovery()
267 /* recover failed, try hardware re-init */ in octeon_i2c_recovery()
273 * octeon_i2c_start - send START to the bus
298 return (ret) ? ret : -EAGAIN; in octeon_i2c_start()
308 * octeon_i2c_read - receive data from the bus via low-level controller
364 return -EPROTO; in octeon_i2c_read()
377 * octeon_i2c_write - send data to the bus via low-level controller
415 /* high-level-controller pure read of up to 8 bytes */
426 cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT; in octeon_i2c_hlc_read()
435 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_read()
440 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_read()
444 for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--) in octeon_i2c_hlc_read()
448 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_read()
449 for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--) in octeon_i2c_hlc_read()
457 /* high-level-controller pure write of up to 8 bytes */
468 cmd |= (u64)(msgs[0].len - 1) << SW_TWSI_SIZE_SHIFT; in octeon_i2c_hlc_write()
477 for (i = 0, j = msgs[0].len - 1; i < msgs[0].len && i < 4; i++, j--) in octeon_i2c_hlc_write()
481 u64 ext = 0; in octeon_i2c_hlc_write() local
483 for (i = 0; i < msgs[0].len - 4 && i < 4; i++, j--) in octeon_i2c_hlc_write()
484 ext |= (u64)msgs[0].buf[j] << (8 * i); in octeon_i2c_hlc_write()
485 octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_write()
488 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_write()
493 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_write()
501 /* high-level-controller composite write+read, msg0=addr, msg1=data */
511 cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT; in octeon_i2c_hlc_comp_read()
521 u64 ext = 0; in octeon_i2c_hlc_comp_read() local
524 ext = (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT; in octeon_i2c_hlc_comp_read()
526 octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_comp_read()
532 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_comp_read()
538 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_comp_read()
542 for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--) in octeon_i2c_hlc_comp_read()
546 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_comp_read()
547 for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--) in octeon_i2c_hlc_comp_read()
555 /* high-level-controller composite write+write, m[0]len<=2, m[1]len<=8 */
560 u64 cmd, ext = 0; in octeon_i2c_hlc_comp_write() local
566 cmd |= (u64)(msgs[1].len - 1) << SW_TWSI_SIZE_SHIFT; in octeon_i2c_hlc_comp_write()
577 ext |= (u64)msgs[0].buf[0] << SW_TWSI_IA_SHIFT; in octeon_i2c_hlc_comp_write()
584 for (i = 0, j = msgs[1].len - 1; i < msgs[1].len && i < 4; i++, j--) in octeon_i2c_hlc_comp_write()
588 for (i = 0; i < msgs[1].len - 4 && i < 4; i++, j--) in octeon_i2c_hlc_comp_write()
589 ext |= (u64)msgs[1].buf[j] << (8 * i); in octeon_i2c_hlc_comp_write()
593 octeon_i2c_writeq_flush(ext, i2c->twsi_base + OCTEON_REG_SW_TWSI_EXT(i2c)); in octeon_i2c_hlc_comp_write()
596 octeon_i2c_writeq_flush(cmd, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_comp_write()
602 cmd = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c)); in octeon_i2c_hlc_comp_write()
611 * octeon_i2c_xfer - The driver's xfer function
623 if (IS_LS_FREQ(i2c->twsi_freq)) { in octeon_i2c_xfer()
650 /* zero-length messages are not supported */ in octeon_i2c_xfer()
651 if (!pmsg->len) { in octeon_i2c_xfer()
652 ret = -EOPNOTSUPP; in octeon_i2c_xfer()
660 if (pmsg->flags & I2C_M_RD) in octeon_i2c_xfer()
661 ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf, in octeon_i2c_xfer()
662 &pmsg->len, pmsg->flags & I2C_M_RECV_LEN); in octeon_i2c_xfer()
664 ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf, in octeon_i2c_xfer()
665 pmsg->len); in octeon_i2c_xfer()
679 * to cover wider range of divisors, note thp = TCLK half period and in octeon_i2c_set_clock()
685 is_plat_otx2 = octeon_i2c_is_otx2(to_pci_dev(i2c->dev)); in octeon_i2c_set_clock()
690 if (!IS_LS_FREQ(i2c->twsi_freq)) in octeon_i2c_set_clock()
702 for (mdiv_idx = 15; mdiv_idx >= mdiv_min && delta_hz != 0; mdiv_idx--) { in octeon_i2c_set_clock()
707 tclk = i2c->twsi_freq * (mdiv_idx + 1) * ds; in octeon_i2c_set_clock()
710 thp_base = (i2c->sys_freq / tclk) - 2; in octeon_i2c_set_clock()
712 thp_base = (i2c->sys_freq / (tclk * 2)) - 1; in octeon_i2c_set_clock()
720 foscl = i2c->sys_freq / (thp_idx + 2); in octeon_i2c_set_clock()
722 foscl = i2c->sys_freq / in octeon_i2c_set_clock()
726 if (foscl > i2c->twsi_freq) in octeon_i2c_set_clock()
728 diff = abs(foscl - i2c->twsi_freq); in octeon_i2c_set_clock()
748 mode = __raw_readq(i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_set_clock()
750 if (!IS_LS_FREQ(i2c->twsi_freq)) in octeon_i2c_set_clock()
754 octeon_i2c_writeq_flush(mode, i2c->twsi_base + OCTEON_REG_MODE(i2c)); in octeon_i2c_set_clock()
766 for (tries = 10; tries && status != STAT_IDLE; tries--) { in octeon_i2c_init_lowlevel()
774 dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", in octeon_i2c_init_lowlevel()
776 return -EIO; in octeon_i2c_init_lowlevel()