Lines Matching refs:i2c
83 static void octeon_i2c_write_sw(struct octeon_i2c *i2c, in octeon_i2c_write_sw() argument
89 __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI); in octeon_i2c_write_sw()
91 tmp = __raw_readq(i2c->twsi_base + SW_TWSI); in octeon_i2c_write_sw()
104 static u8 octeon_i2c_read_sw(struct octeon_i2c *i2c, u64 eop_reg) in octeon_i2c_read_sw() argument
108 __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI); in octeon_i2c_read_sw()
110 tmp = __raw_readq(i2c->twsi_base + SW_TWSI); in octeon_i2c_read_sw()
121 static void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data) in octeon_i2c_write_int() argument
123 __raw_writeq(data, i2c->twsi_base + TWSI_INT); in octeon_i2c_write_int()
124 __raw_readq(i2c->twsi_base + TWSI_INT); in octeon_i2c_write_int()
134 static void octeon_i2c_int_enable(struct octeon_i2c *i2c) in octeon_i2c_int_enable() argument
136 octeon_i2c_write_int(i2c, 0x40); in octeon_i2c_int_enable()
143 static void octeon_i2c_int_disable(struct octeon_i2c *i2c) in octeon_i2c_int_disable() argument
145 octeon_i2c_write_int(i2c, 0); in octeon_i2c_int_disable()
156 static void octeon_i2c_unblock(struct octeon_i2c *i2c) in octeon_i2c_unblock() argument
160 dev_dbg(i2c->dev, "%s\n", __func__); in octeon_i2c_unblock()
162 octeon_i2c_write_int(i2c, 0x0); in octeon_i2c_unblock()
164 octeon_i2c_write_int(i2c, 0x200); in octeon_i2c_unblock()
167 octeon_i2c_write_int(i2c, 0x300); in octeon_i2c_unblock()
169 octeon_i2c_write_int(i2c, 0x100); in octeon_i2c_unblock()
171 octeon_i2c_write_int(i2c, 0x0); in octeon_i2c_unblock()
181 struct octeon_i2c *i2c = dev_id; in octeon_i2c_isr() local
183 octeon_i2c_int_disable(i2c); in octeon_i2c_isr()
184 wake_up(&i2c->queue); in octeon_i2c_isr()
190 static int octeon_i2c_test_iflg(struct octeon_i2c *i2c) in octeon_i2c_test_iflg() argument
192 return (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_CTL) & TWSI_CTL_IFLG) != 0; in octeon_i2c_test_iflg()
201 static int octeon_i2c_wait(struct octeon_i2c *i2c) in octeon_i2c_wait() argument
205 octeon_i2c_int_enable(i2c); in octeon_i2c_wait()
207 result = wait_event_timeout(i2c->queue, in octeon_i2c_wait()
208 octeon_i2c_test_iflg(i2c), in octeon_i2c_wait()
209 i2c->adap.timeout); in octeon_i2c_wait()
211 octeon_i2c_int_disable(i2c); in octeon_i2c_wait()
214 dev_dbg(i2c->dev, "%s: timeout\n", __func__); in octeon_i2c_wait()
227 static int octeon_i2c_start(struct octeon_i2c *i2c) in octeon_i2c_start() argument
232 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_start()
235 result = octeon_i2c_wait(i2c); in octeon_i2c_start()
237 if (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT) == STAT_IDLE) { in octeon_i2c_start()
243 octeon_i2c_unblock(i2c); in octeon_i2c_start()
244 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_start()
247 result = octeon_i2c_wait(i2c); in octeon_i2c_start()
253 data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_start()
255 dev_err(i2c->dev, "%s: bad status (0x%x)\n", __func__, data); in octeon_i2c_start()
268 static int octeon_i2c_stop(struct octeon_i2c *i2c) in octeon_i2c_stop() argument
272 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_stop()
275 data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_stop()
278 dev_err(i2c->dev, "%s: bad status(0x%x)\n", __func__, data); in octeon_i2c_stop()
295 static int octeon_i2c_write(struct octeon_i2c *i2c, int target, in octeon_i2c_write() argument
301 result = octeon_i2c_start(i2c); in octeon_i2c_write()
305 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, target << 1); in octeon_i2c_write()
306 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); in octeon_i2c_write()
308 result = octeon_i2c_wait(i2c); in octeon_i2c_write()
313 tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_write()
315 dev_err(i2c->dev, in octeon_i2c_write()
321 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, data[i]); in octeon_i2c_write()
322 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); in octeon_i2c_write()
324 result = octeon_i2c_wait(i2c); in octeon_i2c_write()
343 static int octeon_i2c_read(struct octeon_i2c *i2c, int target, in octeon_i2c_read() argument
352 result = octeon_i2c_start(i2c); in octeon_i2c_read()
356 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, (target<<1) | 1); in octeon_i2c_read()
357 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); in octeon_i2c_read()
359 result = octeon_i2c_wait(i2c); in octeon_i2c_read()
364 tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_read()
366 dev_err(i2c->dev, in octeon_i2c_read()
373 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_read()
376 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, in octeon_i2c_read()
379 result = octeon_i2c_wait(i2c); in octeon_i2c_read()
383 data[i] = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_DATA); in octeon_i2c_read()
404 struct octeon_i2c *i2c = i2c_get_adapdata(adap); in octeon_i2c_xfer() local
408 dev_dbg(i2c->dev, in octeon_i2c_xfer()
413 ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf, in octeon_i2c_xfer()
416 ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf, in octeon_i2c_xfer()
419 octeon_i2c_stop(i2c); in octeon_i2c_xfer()
444 static int octeon_i2c_setclock(struct octeon_i2c *i2c) in octeon_i2c_setclock() argument
460 tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10; in octeon_i2c_setclock()
462 thp_base = (i2c->sys_freq / (tclk * 2)) - 1; in octeon_i2c_setclock()
468 foscl = i2c->sys_freq / (2 * (thp_idx + 1)); in octeon_i2c_setclock()
471 diff = abs(foscl - i2c->twsi_freq); in octeon_i2c_setclock()
481 octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp); in octeon_i2c_setclock()
482 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv); in octeon_i2c_setclock()
487 static int octeon_i2c_initlowlevel(struct octeon_i2c *i2c) in octeon_i2c_initlowlevel() argument
493 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); in octeon_i2c_initlowlevel()
496 octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0); in octeon_i2c_initlowlevel()
500 status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); in octeon_i2c_initlowlevel()
504 dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status); in octeon_i2c_initlowlevel()
511 struct octeon_i2c *i2c; in octeon_i2c_probe() local
519 i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); in octeon_i2c_probe()
520 if (!i2c) { in octeon_i2c_probe()
525 i2c->dev = &pdev->dev; in octeon_i2c_probe()
530 dev_err(i2c->dev, "found no memory resource\n"); in octeon_i2c_probe()
534 i2c->twsi_phys = res_mem->start; in octeon_i2c_probe()
535 i2c->regsize = resource_size(res_mem); in octeon_i2c_probe()
543 "clock-frequency", &i2c->twsi_freq) && in octeon_i2c_probe()
545 "clock-rate", &i2c->twsi_freq)) { in octeon_i2c_probe()
546 dev_err(i2c->dev, in octeon_i2c_probe()
552 i2c->sys_freq = octeon_get_io_clock_rate(); in octeon_i2c_probe()
554 if (!devm_request_mem_region(&pdev->dev, i2c->twsi_phys, i2c->regsize, in octeon_i2c_probe()
556 dev_err(i2c->dev, "request_mem_region failed\n"); in octeon_i2c_probe()
559 i2c->twsi_base = devm_ioremap(&pdev->dev, i2c->twsi_phys, i2c->regsize); in octeon_i2c_probe()
561 init_waitqueue_head(&i2c->queue); in octeon_i2c_probe()
563 i2c->irq = irq; in octeon_i2c_probe()
565 result = devm_request_irq(&pdev->dev, i2c->irq, in octeon_i2c_probe()
566 octeon_i2c_isr, 0, DRV_NAME, i2c); in octeon_i2c_probe()
568 dev_err(i2c->dev, "failed to attach interrupt\n"); in octeon_i2c_probe()
572 result = octeon_i2c_initlowlevel(i2c); in octeon_i2c_probe()
574 dev_err(i2c->dev, "init low level failed\n"); in octeon_i2c_probe()
578 result = octeon_i2c_setclock(i2c); in octeon_i2c_probe()
580 dev_err(i2c->dev, "clock init failed\n"); in octeon_i2c_probe()
584 i2c->adap = octeon_i2c_ops; in octeon_i2c_probe()
585 i2c->adap.dev.parent = &pdev->dev; in octeon_i2c_probe()
586 i2c->adap.dev.of_node = pdev->dev.of_node; in octeon_i2c_probe()
587 i2c_set_adapdata(&i2c->adap, i2c); in octeon_i2c_probe()
588 platform_set_drvdata(pdev, i2c); in octeon_i2c_probe()
590 result = i2c_add_adapter(&i2c->adap); in octeon_i2c_probe()
592 dev_err(i2c->dev, "failed to add adapter\n"); in octeon_i2c_probe()
595 dev_info(i2c->dev, "version %s\n", DRV_VERSION); in octeon_i2c_probe()
605 struct octeon_i2c *i2c = platform_get_drvdata(pdev); in octeon_i2c_remove() local
607 i2c_del_adapter(&i2c->adap); in octeon_i2c_remove()