Lines Matching full:i2c
7 * This is a driver for the i2c adapter in Cavium Networks' OCTEON processors.
21 #include <linux/i2c.h>
28 #define DRV_NAME "i2c-octeon"
77 * octeon_i2c_write_sw - write an I2C core register.
78 * @i2c: The struct octeon_i2c.
82 * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
84 static void octeon_i2c_write_sw(struct octeon_i2c *i2c, in octeon_i2c_write_sw() argument
90 __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI); in octeon_i2c_write_sw()
92 tmp = __raw_readq(i2c->twsi_base + SW_TWSI); in octeon_i2c_write_sw()
97 * octeon_i2c_read_sw - write an I2C core register.
98 * @i2c: The struct octeon_i2c.
103 * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
105 static u8 octeon_i2c_read_sw(struct octeon_i2c *i2c, u64 eop_reg) in octeon_i2c_read_sw() argument
109 __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI); in octeon_i2c_read_sw()
111 tmp = __raw_readq(i2c->twsi_base + SW_TWSI); in octeon_i2c_read_sw()
119 * @i2c: The struct octeon_i2c.
122 static void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data) in octeon_i2c_write_int() argument
126 __raw_writeq(data, i2c->twsi_base + TWSI_INT); in octeon_i2c_write_int()
127 tmp = __raw_readq(i2c->twsi_base + TWSI_INT); in octeon_i2c_write_int()
132 * @i2c: The struct octeon_i2c.
137 static void octeon_i2c_int_enable(struct octeon_i2c *i2c) in octeon_i2c_int_enable() argument
139 octeon_i2c_write_int(i2c, 0x40); in octeon_i2c_int_enable()
144 * @i2c: The struct octeon_i2c.
146 static void octeon_i2c_int_disable(struct octeon_i2c *i2c) in octeon_i2c_int_disable() argument
148 octeon_i2c_write_int(i2c, 0); in octeon_i2c_int_disable()
153 * @i2c: The struct octeon_i2c.
159 static void octeon_i2c_unblock(struct octeon_i2c *i2c) in octeon_i2c_unblock() argument
163 dev_dbg(i2c->dev, "%s\n", __func__); in octeon_i2c_unblock()
165 octeon_i2c_write_int(i2c, 0x0); in octeon_i2c_unblock()
167 octeon_i2c_write_int(i2c, 0x200); in octeon_i2c_unblock()
170 octeon_i2c_write_int(i2c, 0x300); in octeon_i2c_unblock()
172 octeon_i2c_write_int(i2c, 0x100); in octeon_i2c_unblock()
174 octeon_i2c_write_int(i2c, 0x0); in octeon_i2c_unblock()
184 struct octeon_i2c *i2c = dev_id; in octeon_i2c_isr() local
186 octeon_i2c_int_disable(i2c); in octeon_i2c_isr()
187 wake_up_interruptible(&i2c->queue); in octeon_i2c_isr()
193 static int octeon_i2c_test_iflg(struct octeon_i2c *i2c) in octeon_i2c_test_iflg() argument
195 return (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_CTL) & TWSI_CTL_IFLG) != 0; in octeon_i2c_test_iflg()
200 * @i2c: The struct octeon_i2c.
204 static int octeon_i2c_wait(struct octeon_i2c *i2c) in octeon_i2c_wait() argument
208 octeon_i2c_int_enable(i2c); in octeon_i2c_wait()
210 result = wait_event_interruptible_timeout(i2c->queue, in octeon_i2c_wait()
211 octeon_i2c_test_iflg(i2c), in octeon_i2c_wait()
212 i2c->adap.timeout); in octeon_i2c_wait()
214 octeon_i2c_int_disable(i2c); in octeon_i2c_wait()
217 dev_dbg(i2c->dev, "%s: wait interrupted\n", __func__); in octeon_i2c_wait()
220 dev_dbg(i2c->dev, "%s: timeout\n", __func__); in octeon_i2c_wait()
229 * @i2c: The struct octeon_i2c.
233 static int octeon_i2c_start(struct octeon_i2c *i2c) in octeon_i2c_start() argument
238 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_start()
241 result = octeon_i2c_wait(i2c); in octeon_i2c_start()
243 if (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT) == STAT_IDLE) { in octeon_i2c_start()
249 octeon_i2c_unblock(i2c); in octeon_i2c_start()
250 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_start()
253 result = octeon_i2c_wait(i2c); in octeon_i2c_start()
259 data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_start()
261 dev_err(i2c->dev, "%s: bad status (0x%x)\n", __func__, data); in octeon_i2c_start()
270 * @i2c: The struct octeon_i2c.
274 static int octeon_i2c_stop(struct octeon_i2c *i2c) in octeon_i2c_stop() argument
278 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_stop()
281 data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_stop()
284 dev_err(i2c->dev, "%s: bad status(0x%x)\n", __func__, data); in octeon_i2c_stop()
292 * @i2c: The struct octeon_i2c.
301 static int octeon_i2c_write(struct octeon_i2c *i2c, int target, in octeon_i2c_write() argument
307 result = octeon_i2c_start(i2c); in octeon_i2c_write()
311 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, target << 1); in octeon_i2c_write()
312 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); in octeon_i2c_write()
314 result = octeon_i2c_wait(i2c); in octeon_i2c_write()
319 tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_write()
321 dev_err(i2c->dev, in octeon_i2c_write()
327 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, data[i]); in octeon_i2c_write()
328 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); in octeon_i2c_write()
330 result = octeon_i2c_wait(i2c); in octeon_i2c_write()
340 * @i2c: The struct octeon_i2c.
349 static int octeon_i2c_read(struct octeon_i2c *i2c, int target, in octeon_i2c_read() argument
358 result = octeon_i2c_start(i2c); in octeon_i2c_read()
362 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, (target<<1) | 1); in octeon_i2c_read()
363 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); in octeon_i2c_read()
365 result = octeon_i2c_wait(i2c); in octeon_i2c_read()
370 tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_read()
372 dev_err(i2c->dev, in octeon_i2c_read()
379 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_read()
382 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_read()
385 result = octeon_i2c_wait(i2c); in octeon_i2c_read()
389 data[i] = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_DATA); in octeon_i2c_read()
410 struct octeon_i2c *i2c = i2c_get_adapdata(adap); in octeon_i2c_xfer() local
414 dev_dbg(i2c->dev, in octeon_i2c_xfer()
419 ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf, in octeon_i2c_xfer()
422 ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf, in octeon_i2c_xfer()
425 octeon_i2c_stop(i2c); in octeon_i2c_xfer()
450 static int __devinit octeon_i2c_setclock(struct octeon_i2c *i2c) in octeon_i2c_setclock() argument
466 tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10; in octeon_i2c_setclock()
468 thp_base = (i2c->sys_freq / (tclk * 2)) - 1; in octeon_i2c_setclock()
474 foscl = i2c->sys_freq / (2 * (thp_idx + 1)); in octeon_i2c_setclock()
477 diff = abs(foscl - i2c->twsi_freq); in octeon_i2c_setclock()
487 octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp); in octeon_i2c_setclock()
488 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv); in octeon_i2c_setclock()
493 static int __devinit octeon_i2c_initlowlevel(struct octeon_i2c *i2c) in octeon_i2c_initlowlevel() argument
499 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); in octeon_i2c_initlowlevel()
502 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0); in octeon_i2c_initlowlevel()
506 status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_initlowlevel()
510 dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status); in octeon_i2c_initlowlevel()
517 struct octeon_i2c *i2c; in octeon_i2c_probe() local
526 i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); in octeon_i2c_probe()
527 if (!i2c) { in octeon_i2c_probe()
532 i2c->dev = &pdev->dev; in octeon_i2c_probe()
538 dev_err(i2c->dev, "found no memory resource\n"); in octeon_i2c_probe()
544 dev_err(i2c->dev, "no I2C frequency data\n"); in octeon_i2c_probe()
549 i2c->twsi_phys = res_mem->start; in octeon_i2c_probe()
550 i2c->regsize = resource_size(res_mem); in octeon_i2c_probe()
551 i2c->twsi_freq = i2c_data->i2c_freq; in octeon_i2c_probe()
552 i2c->sys_freq = i2c_data->sys_freq; in octeon_i2c_probe()
554 if (!request_mem_region(i2c->twsi_phys, i2c->regsize, res_mem->name)) { in octeon_i2c_probe()
555 dev_err(i2c->dev, "request_mem_region failed\n"); in octeon_i2c_probe()
558 i2c->twsi_base = ioremap(i2c->twsi_phys, i2c->regsize); in octeon_i2c_probe()
560 init_waitqueue_head(&i2c->queue); in octeon_i2c_probe()
562 i2c->irq = irq; in octeon_i2c_probe()
564 result = request_irq(i2c->irq, octeon_i2c_isr, 0, DRV_NAME, i2c); in octeon_i2c_probe()
566 dev_err(i2c->dev, "failed to attach interrupt\n"); in octeon_i2c_probe()
570 result = octeon_i2c_initlowlevel(i2c); in octeon_i2c_probe()
572 dev_err(i2c->dev, "init low level failed\n"); in octeon_i2c_probe()
576 result = octeon_i2c_setclock(i2c); in octeon_i2c_probe()
578 dev_err(i2c->dev, "clock init failed\n"); in octeon_i2c_probe()
582 i2c->adap = octeon_i2c_ops; in octeon_i2c_probe()
583 i2c->adap.dev.parent = &pdev->dev; in octeon_i2c_probe()
584 i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0; in octeon_i2c_probe()
585 i2c_set_adapdata(&i2c->adap, i2c); in octeon_i2c_probe()
586 platform_set_drvdata(pdev, i2c); in octeon_i2c_probe()
588 result = i2c_add_numbered_adapter(&i2c->adap); in octeon_i2c_probe()
590 dev_err(i2c->dev, "failed to add adapter\n"); in octeon_i2c_probe()
594 dev_info(i2c->dev, "version %s\n", DRV_VERSION); in octeon_i2c_probe()
600 free_irq(i2c->irq, i2c); in octeon_i2c_probe()
602 iounmap(i2c->twsi_base); in octeon_i2c_probe()
603 release_mem_region(i2c->twsi_phys, i2c->regsize); in octeon_i2c_probe()
605 kfree(i2c); in octeon_i2c_probe()
612 struct octeon_i2c *i2c = platform_get_drvdata(pdev); in octeon_i2c_remove() local
614 i2c_del_adapter(&i2c->adap); in octeon_i2c_remove()
616 free_irq(i2c->irq, i2c); in octeon_i2c_remove()
617 iounmap(i2c->twsi_base); in octeon_i2c_remove()
618 release_mem_region(i2c->twsi_phys, i2c->regsize); in octeon_i2c_remove()
619 kfree(i2c); in octeon_i2c_remove()
635 MODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors");