Lines Matching full:i2c

2  * linux/drivers/i2c/busses/i2c-nuc900.c
6 …* This driver based on S3C2410 I2C driver of Ben Dooks <ben-Y5A6D6n0/KfQXOPxS62xeg@public.gmane.or…
18 #include <linux/i2c.h>
32 #include <mach/i2c.h>
34 /* nuc900 i2c registers offset */
43 /* nuc900 i2c CSR register bits */
52 /* nuc900 i2c CMDR register bits */
60 /* i2c controller state */
70 /* i2c controller private data */
97 static inline void nuc900_i2c_master_complete(struct nuc900_i2c *i2c, int ret) in nuc900_i2c_master_complete() argument
99 dev_dbg(i2c->dev, "master_complete %d\n", ret); in nuc900_i2c_master_complete()
101 i2c->msg_ptr = 0; in nuc900_i2c_master_complete()
102 i2c->msg = NULL; in nuc900_i2c_master_complete()
103 i2c->msg_idx++; in nuc900_i2c_master_complete()
104 i2c->msg_num = 0; in nuc900_i2c_master_complete()
106 i2c->msg_idx = ret; in nuc900_i2c_master_complete()
108 wake_up(&i2c->wait); in nuc900_i2c_master_complete()
113 static inline void nuc900_i2c_disable_irq(struct nuc900_i2c *i2c) in nuc900_i2c_disable_irq() argument
117 tmp = readl(i2c->regs + CSR); in nuc900_i2c_disable_irq()
118 writel(tmp & ~IRQEN, i2c->regs + CSR); in nuc900_i2c_disable_irq()
121 static inline void nuc900_i2c_enable_irq(struct nuc900_i2c *i2c) in nuc900_i2c_enable_irq() argument
125 tmp = readl(i2c->regs + CSR); in nuc900_i2c_enable_irq()
126 writel(tmp | IRQEN, i2c->regs + CSR); in nuc900_i2c_enable_irq()
135 static void nuc900_i2c_message_start(struct nuc900_i2c *i2c, in nuc900_i2c_message_start() argument
142 writel(addr & 0xff, i2c->regs + TXR); in nuc900_i2c_message_start()
143 writel(I2C_CMD_START | I2C_CMD_WRITE, i2c->regs + CMDR); in nuc900_i2c_message_start()
146 static inline void nuc900_i2c_stop(struct nuc900_i2c *i2c, int ret) in nuc900_i2c_stop() argument
149 dev_dbg(i2c->dev, "STOP\n"); in nuc900_i2c_stop()
152 i2c->state = STATE_STOP; in nuc900_i2c_stop()
153 writel(I2C_CMD_STOP, i2c->regs + CMDR); in nuc900_i2c_stop()
155 nuc900_i2c_master_complete(i2c, ret); in nuc900_i2c_stop()
156 nuc900_i2c_disable_irq(i2c); in nuc900_i2c_stop()
168 static inline int is_lastmsg(struct nuc900_i2c *i2c) in is_lastmsg() argument
170 return i2c->msg_idx >= (i2c->msg_num - 1); in is_lastmsg()
178 static inline int is_msglast(struct nuc900_i2c *i2c) in is_msglast() argument
180 return i2c->msg_ptr == i2c->msg->len-1; in is_msglast()
188 static inline int is_msgend(struct nuc900_i2c *i2c) in is_msgend() argument
190 return i2c->msg_ptr >= i2c->msg->len; in is_msgend()
198 static void i2c_nuc900_irq_nextbyte(struct nuc900_i2c *i2c, in i2c_nuc900_irq_nextbyte() argument
203 switch (i2c->state) { in i2c_nuc900_irq_nextbyte()
206 dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__); in i2c_nuc900_irq_nextbyte()
210 dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__); in i2c_nuc900_irq_nextbyte()
211 nuc900_i2c_disable_irq(i2c); in i2c_nuc900_irq_nextbyte()
216 * bus, or started a new i2c message in i2c_nuc900_irq_nextbyte()
220 !(i2c->msg->flags & I2C_M_IGNORE_NAK)) { in i2c_nuc900_irq_nextbyte()
223 dev_dbg(i2c->dev, "ack was not received\n"); in i2c_nuc900_irq_nextbyte()
224 nuc900_i2c_stop(i2c, -ENXIO); in i2c_nuc900_irq_nextbyte()
228 if (i2c->msg->flags & I2C_M_RD) in i2c_nuc900_irq_nextbyte()
229 i2c->state = STATE_READ; in i2c_nuc900_irq_nextbyte()
231 i2c->state = STATE_WRITE; in i2c_nuc900_irq_nextbyte()
234 * as this is used by the i2c probe to find devices. in i2c_nuc900_irq_nextbyte()
237 if (is_lastmsg(i2c) && i2c->msg->len == 0) { in i2c_nuc900_irq_nextbyte()
238 nuc900_i2c_stop(i2c, 0); in i2c_nuc900_irq_nextbyte()
242 if (i2c->state == STATE_READ) in i2c_nuc900_irq_nextbyte()
254 if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) { in i2c_nuc900_irq_nextbyte()
256 dev_dbg(i2c->dev, "WRITE: No Ack\n"); in i2c_nuc900_irq_nextbyte()
258 nuc900_i2c_stop(i2c, -ECONNREFUSED); in i2c_nuc900_irq_nextbyte()
265 if (!is_msgend(i2c)) { in i2c_nuc900_irq_nextbyte()
266 byte = i2c->msg->buf[i2c->msg_ptr++]; in i2c_nuc900_irq_nextbyte()
267 writeb(byte, i2c->regs + TXR); in i2c_nuc900_irq_nextbyte()
268 writel(I2C_CMD_WRITE, i2c->regs + CMDR); in i2c_nuc900_irq_nextbyte()
270 } else if (!is_lastmsg(i2c)) { in i2c_nuc900_irq_nextbyte()
271 /* we need to go to the next i2c message */ in i2c_nuc900_irq_nextbyte()
273 dev_dbg(i2c->dev, "WRITE: Next Message\n"); in i2c_nuc900_irq_nextbyte()
275 i2c->msg_ptr = 0; in i2c_nuc900_irq_nextbyte()
276 i2c->msg_idx++; in i2c_nuc900_irq_nextbyte()
277 i2c->msg++; in i2c_nuc900_irq_nextbyte()
280 if (i2c->msg->flags & I2C_M_NOSTART) { in i2c_nuc900_irq_nextbyte()
282 if (i2c->msg->flags & I2C_M_RD) { in i2c_nuc900_irq_nextbyte()
288 nuc900_i2c_stop(i2c, -EINVAL); in i2c_nuc900_irq_nextbyte()
294 nuc900_i2c_message_start(i2c, i2c->msg); in i2c_nuc900_irq_nextbyte()
295 i2c->state = STATE_START; in i2c_nuc900_irq_nextbyte()
301 nuc900_i2c_stop(i2c, 0); in i2c_nuc900_irq_nextbyte()
311 byte = readb(i2c->regs + RXR); in i2c_nuc900_irq_nextbyte()
312 i2c->msg->buf[i2c->msg_ptr++] = byte; in i2c_nuc900_irq_nextbyte()
315 if (is_msglast(i2c)) { in i2c_nuc900_irq_nextbyte()
318 if (is_lastmsg(i2c)) in i2c_nuc900_irq_nextbyte()
320 i2c->regs + CMDR); in i2c_nuc900_irq_nextbyte()
322 } else if (is_msgend(i2c)) { in i2c_nuc900_irq_nextbyte()
327 if (is_lastmsg(i2c)) { in i2c_nuc900_irq_nextbyte()
329 dev_dbg(i2c->dev, "READ: Send Stop\n"); in i2c_nuc900_irq_nextbyte()
331 nuc900_i2c_stop(i2c, 0); in i2c_nuc900_irq_nextbyte()
334 dev_dbg(i2c->dev, "READ: Next Transfer\n"); in i2c_nuc900_irq_nextbyte()
336 i2c->msg_ptr = 0; in i2c_nuc900_irq_nextbyte()
337 i2c->msg_idx++; in i2c_nuc900_irq_nextbyte()
338 i2c->msg++; in i2c_nuc900_irq_nextbyte()
340 writel(I2C_CMD_READ, i2c->regs + CMDR); in i2c_nuc900_irq_nextbyte()
344 writel(I2C_CMD_READ, i2c->regs + CMDR); in i2c_nuc900_irq_nextbyte()
358 struct nuc900_i2c *i2c = dev_id; in nuc900_i2c_irq() local
361 status = readl(i2c->regs + CSR); in nuc900_i2c_irq()
362 writel(status | IRQFLAG, i2c->regs + CSR); in nuc900_i2c_irq()
366 dev_err(i2c->dev, "deal with arbitration loss\n"); in nuc900_i2c_irq()
370 if (i2c->state == STATE_IDLE) { in nuc900_i2c_irq()
371 dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n"); in nuc900_i2c_irq()
379 i2c_nuc900_irq_nextbyte(i2c, status); in nuc900_i2c_irq()
388 * get the i2c bus for a master transaction
391 static int nuc900_i2c_set_master(struct nuc900_i2c *i2c) in nuc900_i2c_set_master() argument
396 if (((readl(i2c->regs + SWR) & I2CSTART) == I2CSTART) && in nuc900_i2c_set_master()
397 ((readl(i2c->regs + CSR) & I2CBUSY) == 0)) { in nuc900_i2c_set_master()
409 * this starts an i2c transfer
412 static int nuc900_i2c_doxfer(struct nuc900_i2c *i2c, in nuc900_i2c_doxfer() argument
419 ret = nuc900_i2c_set_master(i2c); in nuc900_i2c_doxfer()
421 dev_err(i2c->dev, "cannot get bus (error %d)\n", ret); in nuc900_i2c_doxfer()
426 spin_lock_irq(&i2c->lock); in nuc900_i2c_doxfer()
428 i2c->msg = msgs; in nuc900_i2c_doxfer()
429 i2c->msg_num = num; in nuc900_i2c_doxfer()
430 i2c->msg_ptr = 0; in nuc900_i2c_doxfer()
431 i2c->msg_idx = 0; in nuc900_i2c_doxfer()
432 i2c->state = STATE_START; in nuc900_i2c_doxfer()
434 nuc900_i2c_message_start(i2c, msgs); in nuc900_i2c_doxfer()
435 spin_unlock_irq(&i2c->lock); in nuc900_i2c_doxfer()
437 timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); in nuc900_i2c_doxfer()
439 ret = i2c->msg_idx; in nuc900_i2c_doxfer()
446 dev_dbg(i2c->dev, "timeout\n"); in nuc900_i2c_doxfer()
448 dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); in nuc900_i2c_doxfer()
452 dev_dbg(i2c->dev, "waiting for bus idle\n"); in nuc900_i2c_doxfer()
456 iicstat = readl(i2c->regs + CSR); in nuc900_i2c_doxfer()
462 iicstat = readl(i2c->regs + CSR); in nuc900_i2c_doxfer()
466 dev_warn(i2c->dev, "timeout waiting for bus idle\n"); in nuc900_i2c_doxfer()
474 * first port of call from the i2c bus code when an message needs
475 * transferring across the i2c bus.
481 struct nuc900_i2c *i2c = (struct nuc900_i2c *)adap->algo_data; in nuc900_i2c_xfer() local
485 nuc900_i2c_enable_irq(i2c); in nuc900_i2c_xfer()
489 ret = nuc900_i2c_doxfer(i2c, msgs, num); in nuc900_i2c_xfer()
494 dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry); in nuc900_i2c_xfer()
502 /* declare our i2c functionality */
508 /* i2c bus registration info */
522 struct nuc900_i2c *i2c; in nuc900_i2c_probe() local
533 i2c = kzalloc(sizeof(struct nuc900_i2c), GFP_KERNEL); in nuc900_i2c_probe()
534 if (!i2c) { in nuc900_i2c_probe()
539 strlcpy(i2c->adap.name, "nuc900-i2c0", sizeof(i2c->adap.name)); in nuc900_i2c_probe()
540 i2c->adap.owner = THIS_MODULE; in nuc900_i2c_probe()
541 i2c->adap.algo = &nuc900_i2c_algorithm; in nuc900_i2c_probe()
542 i2c->adap.retries = 2; in nuc900_i2c_probe()
543 i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; in nuc900_i2c_probe()
545 spin_lock_init(&i2c->lock); in nuc900_i2c_probe()
546 init_waitqueue_head(&i2c->wait); in nuc900_i2c_probe()
550 i2c->dev = &pdev->dev; in nuc900_i2c_probe()
551 i2c->clk = clk_get(&pdev->dev, NULL); in nuc900_i2c_probe()
552 if (IS_ERR(i2c->clk)) { in nuc900_i2c_probe()
558 dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk); in nuc900_i2c_probe()
560 clk_enable(i2c->clk); in nuc900_i2c_probe()
571 i2c->ioarea = request_mem_region(res->start, resource_size(res), in nuc900_i2c_probe()
574 if (i2c->ioarea == NULL) { in nuc900_i2c_probe()
580 i2c->regs = ioremap(res->start, resource_size(res)); in nuc900_i2c_probe()
582 if (i2c->regs == NULL) { in nuc900_i2c_probe()
589 i2c->regs, i2c->ioarea, res); in nuc900_i2c_probe()
591 /* setup info block for the i2c core */ in nuc900_i2c_probe()
593 i2c->adap.algo_data = i2c; in nuc900_i2c_probe()
594 i2c->adap.dev.parent = &pdev->dev; in nuc900_i2c_probe()
598 clk_get_rate(i2c->clk); in nuc900_i2c_probe()
600 ret = (i2c->clk.apbfreq)/(pdata->bus_freq * 5) - 1; in nuc900_i2c_probe()
601 writel(ret & 0xffff, i2c->regs + DIVIDER); in nuc900_i2c_probe()
607 i2c->irq = ret = platform_get_irq(pdev, 0); in nuc900_i2c_probe()
613 ret = request_irq(i2c->irq, nuc900_i2c_irq, IRQF_SHARED, in nuc900_i2c_probe()
614 dev_name(&pdev->dev), i2c); in nuc900_i2c_probe()
617 dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq); in nuc900_i2c_probe()
627 i2c->adap.nr = pdata->bus_num; in nuc900_i2c_probe()
629 ret = i2c_add_numbered_adapter(&i2c->adap); in nuc900_i2c_probe()
631 dev_err(&pdev->dev, "failed to add bus to i2c core\n"); in nuc900_i2c_probe()
635 platform_set_drvdata(pdev, i2c); in nuc900_i2c_probe()
637 dev_info(&pdev->dev, "%s: NUC900 I2C adapter\n", in nuc900_i2c_probe()
638 dev_name(&i2c->adap.dev)); in nuc900_i2c_probe()
642 free_irq(i2c->irq, i2c); in nuc900_i2c_probe()
645 iounmap(i2c->regs); in nuc900_i2c_probe()
648 release_resource(i2c->ioarea); in nuc900_i2c_probe()
649 kfree(i2c->ioarea); in nuc900_i2c_probe()
652 clk_disable(i2c->clk); in nuc900_i2c_probe()
653 clk_put(i2c->clk); in nuc900_i2c_probe()
656 kfree(i2c); in nuc900_i2c_probe()
667 struct nuc900_i2c *i2c = platform_get_drvdata(pdev); in nuc900_i2c_remove() local
669 i2c_del_adapter(&i2c->adap); in nuc900_i2c_remove()
670 free_irq(i2c->irq, i2c); in nuc900_i2c_remove()
672 clk_disable(i2c->clk); in nuc900_i2c_remove()
673 clk_put(i2c->clk); in nuc900_i2c_remove()
675 iounmap(i2c->regs); in nuc900_i2c_remove()
677 release_resource(i2c->ioarea); in nuc900_i2c_remove()
678 kfree(i2c->ioarea); in nuc900_i2c_remove()
679 kfree(i2c); in nuc900_i2c_remove()
705 MODULE_DESCRIPTION("NUC900 I2C Bus driver");