Lines Matching refs:i2c

249 static void exynos5_i2c_clr_pend_irq(struct exynos5_i2c *i2c)  in exynos5_i2c_clr_pend_irq()  argument
251 writel(readl(i2c->regs + HSI2C_INT_STATUS), in exynos5_i2c_clr_pend_irq()
252 i2c->regs + HSI2C_INT_STATUS); in exynos5_i2c_clr_pend_irq()
262 static int exynos5_i2c_set_timing(struct exynos5_i2c *i2c, int mode) in exynos5_i2c_set_timing() argument
274 unsigned int clkin = clk_get_rate(i2c->clk); in exynos5_i2c_set_timing()
277 i2c->hs_clock : i2c->fs_clock; in exynos5_i2c_set_timing()
291 t_ftl_cycle = (readl(i2c->regs + HSI2C_CONF) >> 16) & 0x7; in exynos5_i2c_set_timing()
294 if (i2c->variant->hw == HSI2C_EXYNOS7) in exynos5_i2c_set_timing()
312 dev_warn(i2c->dev, "Failed to calculate divisor"); in exynos5_i2c_set_timing()
331 dev_dbg(i2c->dev, "tSTART_SU: %X, tSTART_HD: %X, tSTOP_SU: %X\n", in exynos5_i2c_set_timing()
333 dev_dbg(i2c->dev, "tDATA_SU: %X, tSCL_L: %X, tSCL_H: %X\n", in exynos5_i2c_set_timing()
335 dev_dbg(i2c->dev, "nClkDiv: %X, tSR_RELEASE: %X\n", in exynos5_i2c_set_timing()
337 dev_dbg(i2c->dev, "tDATA_HD: %X\n", t_data_hd); in exynos5_i2c_set_timing()
340 writel(i2c_timing_s1, i2c->regs + HSI2C_TIMING_HS1); in exynos5_i2c_set_timing()
341 writel(i2c_timing_s2, i2c->regs + HSI2C_TIMING_HS2); in exynos5_i2c_set_timing()
342 writel(i2c_timing_s3, i2c->regs + HSI2C_TIMING_HS3); in exynos5_i2c_set_timing()
344 writel(i2c_timing_s1, i2c->regs + HSI2C_TIMING_FS1); in exynos5_i2c_set_timing()
345 writel(i2c_timing_s2, i2c->regs + HSI2C_TIMING_FS2); in exynos5_i2c_set_timing()
346 writel(i2c_timing_s3, i2c->regs + HSI2C_TIMING_FS3); in exynos5_i2c_set_timing()
348 writel(i2c_timing_sla, i2c->regs + HSI2C_TIMING_SLA); in exynos5_i2c_set_timing()
353 static int exynos5_hsi2c_clock_setup(struct exynos5_i2c *i2c) in exynos5_hsi2c_clock_setup() argument
359 if (exynos5_i2c_set_timing(i2c, HSI2C_FAST_SPD)) { in exynos5_hsi2c_clock_setup()
360 dev_err(i2c->dev, "HSI2C FS Clock set up failed\n"); in exynos5_hsi2c_clock_setup()
365 if (i2c->speed_mode == HSI2C_HIGH_SPD) { in exynos5_hsi2c_clock_setup()
366 if (exynos5_i2c_set_timing(i2c, HSI2C_HIGH_SPD)) { in exynos5_hsi2c_clock_setup()
367 dev_err(i2c->dev, "HSI2C HS Clock set up failed\n"); in exynos5_hsi2c_clock_setup()
379 static void exynos5_i2c_init(struct exynos5_i2c *i2c) in exynos5_i2c_init() argument
381 u32 i2c_conf = readl(i2c->regs + HSI2C_CONF); in exynos5_i2c_init()
382 u32 i2c_timeout = readl(i2c->regs + HSI2C_TIMEOUT); in exynos5_i2c_init()
386 writel(i2c_timeout, i2c->regs + HSI2C_TIMEOUT); in exynos5_i2c_init()
389 i2c->regs + HSI2C_CTL); in exynos5_i2c_init()
390 writel(HSI2C_TRAILING_COUNT, i2c->regs + HSI2C_TRAILIG_CTL); in exynos5_i2c_init()
392 if (i2c->speed_mode == HSI2C_HIGH_SPD) { in exynos5_i2c_init()
393 writel(HSI2C_MASTER_ID(MASTER_ID(i2c->adap.nr)), in exynos5_i2c_init()
394 i2c->regs + HSI2C_ADDR); in exynos5_i2c_init()
398 writel(i2c_conf | HSI2C_AUTO_MODE, i2c->regs + HSI2C_CONF); in exynos5_i2c_init()
401 static void exynos5_i2c_reset(struct exynos5_i2c *i2c) in exynos5_i2c_reset() argument
406 i2c_ctl = readl(i2c->regs + HSI2C_CTL); in exynos5_i2c_reset()
408 writel(i2c_ctl, i2c->regs + HSI2C_CTL); in exynos5_i2c_reset()
410 i2c_ctl = readl(i2c->regs + HSI2C_CTL); in exynos5_i2c_reset()
412 writel(i2c_ctl, i2c->regs + HSI2C_CTL); in exynos5_i2c_reset()
415 exynos5_hsi2c_clock_setup(i2c); in exynos5_i2c_reset()
417 exynos5_i2c_init(i2c); in exynos5_i2c_reset()
429 struct exynos5_i2c *i2c = dev_id; in exynos5_i2c_irq() local
434 i2c->state = -EINVAL; in exynos5_i2c_irq()
436 spin_lock(&i2c->lock); in exynos5_i2c_irq()
438 int_status = readl(i2c->regs + HSI2C_INT_STATUS); in exynos5_i2c_irq()
439 writel(int_status, i2c->regs + HSI2C_INT_STATUS); in exynos5_i2c_irq()
442 if (i2c->variant->hw == HSI2C_EXYNOS7) { in exynos5_i2c_irq()
444 i2c->trans_done = 1; in exynos5_i2c_irq()
445 i2c->state = 0; in exynos5_i2c_irq()
447 dev_dbg(i2c->dev, "Deal with arbitration lose\n"); in exynos5_i2c_irq()
448 i2c->state = -EAGAIN; in exynos5_i2c_irq()
451 dev_dbg(i2c->dev, "No ACK from device\n"); in exynos5_i2c_irq()
452 i2c->state = -ENXIO; in exynos5_i2c_irq()
455 dev_dbg(i2c->dev, "No device\n"); in exynos5_i2c_irq()
456 i2c->state = -ENXIO; in exynos5_i2c_irq()
459 dev_dbg(i2c->dev, "Accessing device timed out\n"); in exynos5_i2c_irq()
460 i2c->state = -ETIMEDOUT; in exynos5_i2c_irq()
464 trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); in exynos5_i2c_irq()
466 dev_dbg(i2c->dev, "No ACK from device\n"); in exynos5_i2c_irq()
467 i2c->state = -ENXIO; in exynos5_i2c_irq()
470 dev_dbg(i2c->dev, "No device\n"); in exynos5_i2c_irq()
471 i2c->state = -ENXIO; in exynos5_i2c_irq()
474 dev_dbg(i2c->dev, "Deal with arbitration lose\n"); in exynos5_i2c_irq()
475 i2c->state = -EAGAIN; in exynos5_i2c_irq()
478 dev_dbg(i2c->dev, "Accessing device timed out\n"); in exynos5_i2c_irq()
479 i2c->state = -ETIMEDOUT; in exynos5_i2c_irq()
482 i2c->trans_done = 1; in exynos5_i2c_irq()
483 i2c->state = 0; in exynos5_i2c_irq()
487 if ((i2c->msg->flags & I2C_M_RD) && (int_status & in exynos5_i2c_irq()
489 fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS); in exynos5_i2c_irq()
491 len = min(fifo_level, i2c->msg->len - i2c->msg_ptr); in exynos5_i2c_irq()
495 readl(i2c->regs + HSI2C_RX_DATA); in exynos5_i2c_irq()
496 i2c->msg->buf[i2c->msg_ptr++] = byte; in exynos5_i2c_irq()
499 i2c->state = 0; in exynos5_i2c_irq()
501 fifo_status = readl(i2c->regs + HSI2C_FIFO_STATUS); in exynos5_i2c_irq()
504 len = i2c->variant->fifo_depth - fifo_level; in exynos5_i2c_irq()
505 if (len > (i2c->msg->len - i2c->msg_ptr)) in exynos5_i2c_irq()
506 len = i2c->msg->len - i2c->msg_ptr; in exynos5_i2c_irq()
509 byte = i2c->msg->buf[i2c->msg_ptr++]; in exynos5_i2c_irq()
510 writel(byte, i2c->regs + HSI2C_TX_DATA); in exynos5_i2c_irq()
513 i2c->state = 0; in exynos5_i2c_irq()
517 if ((i2c->trans_done && (i2c->msg->len == i2c->msg_ptr)) || in exynos5_i2c_irq()
518 (i2c->state < 0)) { in exynos5_i2c_irq()
519 writel(0, i2c->regs + HSI2C_INT_ENABLE); in exynos5_i2c_irq()
520 exynos5_i2c_clr_pend_irq(i2c); in exynos5_i2c_irq()
521 complete(&i2c->msg_complete); in exynos5_i2c_irq()
524 spin_unlock(&i2c->lock); in exynos5_i2c_irq()
537 static int exynos5_i2c_wait_bus_idle(struct exynos5_i2c *i2c) in exynos5_i2c_wait_bus_idle() argument
545 trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); in exynos5_i2c_wait_bus_idle()
565 static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop) in exynos5_i2c_message_start() argument
574 if (i2c->variant->hw == HSI2C_EXYNOS7) in exynos5_i2c_message_start()
579 i2c_ctl = readl(i2c->regs + HSI2C_CTL); in exynos5_i2c_message_start()
583 if (i2c->msg->flags & I2C_M_RD) { in exynos5_i2c_message_start()
588 trig_lvl = (i2c->msg->len > i2c->variant->fifo_depth) ? in exynos5_i2c_message_start()
589 (i2c->variant->fifo_depth * 3 / 4) : i2c->msg->len; in exynos5_i2c_message_start()
597 trig_lvl = (i2c->msg->len > i2c->variant->fifo_depth) ? in exynos5_i2c_message_start()
598 (i2c->variant->fifo_depth * 1 / 4) : i2c->msg->len; in exynos5_i2c_message_start()
604 writel(HSI2C_SLV_ADDR_MAS(i2c->msg->addr), i2c->regs + HSI2C_ADDR); in exynos5_i2c_message_start()
606 writel(fifo_ctl, i2c->regs + HSI2C_FIFO_CTL); in exynos5_i2c_message_start()
607 writel(i2c_ctl, i2c->regs + HSI2C_CTL); in exynos5_i2c_message_start()
613 spin_lock_irqsave(&i2c->lock, flags); in exynos5_i2c_message_start()
614 writel(int_en, i2c->regs + HSI2C_INT_ENABLE); in exynos5_i2c_message_start()
618 i2c_auto_conf |= i2c->msg->len; in exynos5_i2c_message_start()
620 writel(i2c_auto_conf, i2c->regs + HSI2C_AUTO_CONF); in exynos5_i2c_message_start()
621 spin_unlock_irqrestore(&i2c->lock, flags); in exynos5_i2c_message_start()
624 static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c, in exynos5_i2c_xfer_msg() argument
630 i2c->msg = msgs; in exynos5_i2c_xfer_msg()
631 i2c->msg_ptr = 0; in exynos5_i2c_xfer_msg()
632 i2c->trans_done = 0; in exynos5_i2c_xfer_msg()
634 reinit_completion(&i2c->msg_complete); in exynos5_i2c_xfer_msg()
636 exynos5_i2c_message_start(i2c, stop); in exynos5_i2c_xfer_msg()
638 timeout = wait_for_completion_timeout(&i2c->msg_complete, in exynos5_i2c_xfer_msg()
643 ret = i2c->state; in exynos5_i2c_xfer_msg()
650 ret = exynos5_i2c_wait_bus_idle(i2c); in exynos5_i2c_xfer_msg()
653 exynos5_i2c_reset(i2c); in exynos5_i2c_xfer_msg()
655 dev_warn(i2c->dev, "%s timeout\n", in exynos5_i2c_xfer_msg()
666 struct exynos5_i2c *i2c = adap->algo_data; in exynos5_i2c_xfer() local
669 if (i2c->suspended) { in exynos5_i2c_xfer()
670 dev_err(i2c->dev, "HS-I2C is not initialized.\n"); in exynos5_i2c_xfer()
674 ret = clk_enable(i2c->clk); in exynos5_i2c_xfer()
681 ret = exynos5_i2c_xfer_msg(i2c, msgs, stop); in exynos5_i2c_xfer()
696 dev_warn(i2c->dev, "xfer message failed\n"); in exynos5_i2c_xfer()
700 clk_disable(i2c->clk); in exynos5_i2c_xfer()
717 struct exynos5_i2c *i2c; in exynos5_i2c_probe() local
722 i2c = devm_kzalloc(&pdev->dev, sizeof(struct exynos5_i2c), GFP_KERNEL); in exynos5_i2c_probe()
723 if (!i2c) in exynos5_i2c_probe()
727 i2c->speed_mode = HSI2C_FAST_SPD; in exynos5_i2c_probe()
728 i2c->fs_clock = HSI2C_FS_TX_CLOCK; in exynos5_i2c_probe()
731 i2c->speed_mode = HSI2C_HIGH_SPD; in exynos5_i2c_probe()
732 i2c->fs_clock = HSI2C_FS_TX_CLOCK; in exynos5_i2c_probe()
733 i2c->hs_clock = op_clock; in exynos5_i2c_probe()
735 i2c->speed_mode = HSI2C_FAST_SPD; in exynos5_i2c_probe()
736 i2c->fs_clock = op_clock; in exynos5_i2c_probe()
740 strlcpy(i2c->adap.name, "exynos5-i2c", sizeof(i2c->adap.name)); in exynos5_i2c_probe()
741 i2c->adap.owner = THIS_MODULE; in exynos5_i2c_probe()
742 i2c->adap.algo = &exynos5_i2c_algorithm; in exynos5_i2c_probe()
743 i2c->adap.retries = 3; in exynos5_i2c_probe()
745 i2c->dev = &pdev->dev; in exynos5_i2c_probe()
746 i2c->clk = devm_clk_get(&pdev->dev, "hsi2c"); in exynos5_i2c_probe()
747 if (IS_ERR(i2c->clk)) { in exynos5_i2c_probe()
752 ret = clk_prepare_enable(i2c->clk); in exynos5_i2c_probe()
757 i2c->regs = devm_ioremap_resource(&pdev->dev, mem); in exynos5_i2c_probe()
758 if (IS_ERR(i2c->regs)) { in exynos5_i2c_probe()
759 ret = PTR_ERR(i2c->regs); in exynos5_i2c_probe()
763 i2c->adap.dev.of_node = np; in exynos5_i2c_probe()
764 i2c->adap.algo_data = i2c; in exynos5_i2c_probe()
765 i2c->adap.dev.parent = &pdev->dev; in exynos5_i2c_probe()
768 exynos5_i2c_clr_pend_irq(i2c); in exynos5_i2c_probe()
770 spin_lock_init(&i2c->lock); in exynos5_i2c_probe()
771 init_completion(&i2c->msg_complete); in exynos5_i2c_probe()
773 i2c->irq = ret = platform_get_irq(pdev, 0); in exynos5_i2c_probe()
780 ret = devm_request_irq(&pdev->dev, i2c->irq, exynos5_i2c_irq, in exynos5_i2c_probe()
782 dev_name(&pdev->dev), i2c); in exynos5_i2c_probe()
785 dev_err(&pdev->dev, "cannot request HS-I2C IRQ %d\n", i2c->irq); in exynos5_i2c_probe()
790 i2c->variant = exynos5_i2c_get_variant(pdev); in exynos5_i2c_probe()
792 ret = exynos5_hsi2c_clock_setup(i2c); in exynos5_i2c_probe()
796 exynos5_i2c_reset(i2c); in exynos5_i2c_probe()
798 ret = i2c_add_adapter(&i2c->adap); in exynos5_i2c_probe()
804 platform_set_drvdata(pdev, i2c); in exynos5_i2c_probe()
806 clk_disable(i2c->clk); in exynos5_i2c_probe()
811 clk_disable_unprepare(i2c->clk); in exynos5_i2c_probe()
817 struct exynos5_i2c *i2c = platform_get_drvdata(pdev); in exynos5_i2c_remove() local
819 i2c_del_adapter(&i2c->adap); in exynos5_i2c_remove()
821 clk_unprepare(i2c->clk); in exynos5_i2c_remove()
830 struct exynos5_i2c *i2c = platform_get_drvdata(pdev); in exynos5_i2c_suspend_noirq() local
832 i2c->suspended = 1; in exynos5_i2c_suspend_noirq()
834 clk_unprepare(i2c->clk); in exynos5_i2c_suspend_noirq()
842 struct exynos5_i2c *i2c = platform_get_drvdata(pdev); in exynos5_i2c_resume_noirq() local
845 ret = clk_prepare_enable(i2c->clk); in exynos5_i2c_resume_noirq()
849 ret = exynos5_hsi2c_clock_setup(i2c); in exynos5_i2c_resume_noirq()
851 clk_disable_unprepare(i2c->clk); in exynos5_i2c_resume_noirq()
855 exynos5_i2c_init(i2c); in exynos5_i2c_resume_noirq()
856 clk_disable(i2c->clk); in exynos5_i2c_resume_noirq()
857 i2c->suspended = 0; in exynos5_i2c_resume_noirq()