diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 19:55:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 19:55:45 -0400 |
commit | 38da590bef19f23d4b610aecaad4f32de483890d (patch) | |
tree | 4a1dbd0f6e1d171d5d366677e70b76f2e0d437e5 | |
parent | 7505cb60c2d26301630b052852d484decf07aef1 (diff) | |
parent | 07e729ce894487e92405d3b221cffe587420a376 (diff) |
Merge branch 'next-i2c' of git://git.fluff.org/bjdooks/linux
* 'next-i2c' of git://git.fluff.org/bjdooks/linux:
i2c-eg20t : Fix the issue of Combined R/W transfer mode
i2c-eg20t : Support Combined R/W transfer mode
i2c: Tegra: Add DeviceTree support
-rw-r--r-- | drivers/i2c/busses/i2c-eg20t.c | 41 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 17 |
2 files changed, 37 insertions, 21 deletions
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 8abfa4a03ce1..ce1a32b71e47 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c | |||
@@ -673,32 +673,33 @@ static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
673 | /* transfer not completed */ | 673 | /* transfer not completed */ |
674 | adap->pch_i2c_xfer_in_progress = true; | 674 | adap->pch_i2c_xfer_in_progress = true; |
675 | 675 | ||
676 | pmsg = &msgs[0]; | 676 | for (i = 0; i < num && ret >= 0; i++) { |
677 | pmsg->flags |= adap->pch_buff_mode_en; | 677 | pmsg = &msgs[i]; |
678 | status = pmsg->flags; | 678 | pmsg->flags |= adap->pch_buff_mode_en; |
679 | pch_dbg(adap, | 679 | status = pmsg->flags; |
680 | "After invoking I2C_MODE_SEL :flag= 0x%x\n", status); | 680 | pch_dbg(adap, |
681 | /* calculate sub address length and message length */ | 681 | "After invoking I2C_MODE_SEL :flag= 0x%x\n", status); |
682 | /* these are applicable only for buffer mode */ | 682 | /* calculate sub address length and message length */ |
683 | subaddrlen = pmsg->buf[0]; | 683 | /* these are applicable only for buffer mode */ |
684 | /* calculate actual message length excluding | 684 | subaddrlen = pmsg->buf[0]; |
685 | * the sub address fields */ | 685 | /* calculate actual message length excluding |
686 | msglen = (pmsg->len) - (subaddrlen + 1); | 686 | * the sub address fields */ |
687 | if (status & (I2C_M_RD)) { | 687 | msglen = (pmsg->len) - (subaddrlen + 1); |
688 | pch_dbg(adap, "invoking pch_i2c_readbytes\n"); | 688 | |
689 | ret = pch_i2c_readbytes(i2c_adap, pmsg, (i + 1 == num), | 689 | if ((status & (I2C_M_RD)) != false) { |
690 | (i == 0)); | 690 | ret = pch_i2c_readbytes(i2c_adap, pmsg, (i + 1 == num), |
691 | } else { | 691 | (i == 0)); |
692 | pch_dbg(adap, "invoking pch_i2c_writebytes\n"); | 692 | } else { |
693 | ret = pch_i2c_writebytes(i2c_adap, pmsg, (i + 1 == num), | 693 | ret = pch_i2c_writebytes(i2c_adap, pmsg, (i + 1 == num), |
694 | (i == 0)); | 694 | (i == 0)); |
695 | } | ||
695 | } | 696 | } |
696 | 697 | ||
697 | adap->pch_i2c_xfer_in_progress = false; /* transfer completed */ | 698 | adap->pch_i2c_xfer_in_progress = false; /* transfer completed */ |
698 | 699 | ||
699 | mutex_unlock(&pch_mutex); | 700 | mutex_unlock(&pch_mutex); |
700 | 701 | ||
701 | return ret; | 702 | return (ret < 0) ? ret : num; |
702 | } | 703 | } |
703 | 704 | ||
704 | /** | 705 | /** |
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index fb3b4f8f8152..2440b7411978 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/i2c-tegra.h> | 28 | #include <linux/i2c-tegra.h> |
29 | #include <linux/of_i2c.h> | ||
29 | 30 | ||
30 | #include <asm/unaligned.h> | 31 | #include <asm/unaligned.h> |
31 | 32 | ||
@@ -546,6 +547,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) | |||
546 | struct resource *iomem; | 547 | struct resource *iomem; |
547 | struct clk *clk; | 548 | struct clk *clk; |
548 | struct clk *i2c_clk; | 549 | struct clk *i2c_clk; |
550 | const unsigned int *prop; | ||
549 | void *base; | 551 | void *base; |
550 | int irq; | 552 | int irq; |
551 | int ret = 0; | 553 | int ret = 0; |
@@ -603,7 +605,17 @@ static int tegra_i2c_probe(struct platform_device *pdev) | |||
603 | i2c_dev->irq = irq; | 605 | i2c_dev->irq = irq; |
604 | i2c_dev->cont_id = pdev->id; | 606 | i2c_dev->cont_id = pdev->id; |
605 | i2c_dev->dev = &pdev->dev; | 607 | i2c_dev->dev = &pdev->dev; |
606 | i2c_dev->bus_clk_rate = pdata ? pdata->bus_clk_rate : 100000; | 608 | |
609 | i2c_dev->bus_clk_rate = 100000; /* default clock rate */ | ||
610 | if (pdata) { | ||
611 | i2c_dev->bus_clk_rate = pdata->bus_clk_rate; | ||
612 | |||
613 | } else if (i2c_dev->dev->of_node) { /* if there is a device tree node ... */ | ||
614 | prop = of_get_property(i2c_dev->dev->of_node, | ||
615 | "clock-frequency", NULL); | ||
616 | if (prop) | ||
617 | i2c_dev->bus_clk_rate = be32_to_cpup(prop); | ||
618 | } | ||
607 | 619 | ||
608 | if (pdev->id == 3) | 620 | if (pdev->id == 3) |
609 | i2c_dev->is_dvc = 1; | 621 | i2c_dev->is_dvc = 1; |
@@ -633,6 +645,7 @@ static int tegra_i2c_probe(struct platform_device *pdev) | |||
633 | i2c_dev->adapter.algo = &tegra_i2c_algo; | 645 | i2c_dev->adapter.algo = &tegra_i2c_algo; |
634 | i2c_dev->adapter.dev.parent = &pdev->dev; | 646 | i2c_dev->adapter.dev.parent = &pdev->dev; |
635 | i2c_dev->adapter.nr = pdev->id; | 647 | i2c_dev->adapter.nr = pdev->id; |
648 | i2c_dev->adapter.dev.of_node = pdev->dev.of_node; | ||
636 | 649 | ||
637 | ret = i2c_add_numbered_adapter(&i2c_dev->adapter); | 650 | ret = i2c_add_numbered_adapter(&i2c_dev->adapter); |
638 | if (ret) { | 651 | if (ret) { |
@@ -640,6 +653,8 @@ static int tegra_i2c_probe(struct platform_device *pdev) | |||
640 | goto err_free_irq; | 653 | goto err_free_irq; |
641 | } | 654 | } |
642 | 655 | ||
656 | of_i2c_register_devices(&i2c_dev->adapter); | ||
657 | |||
643 | return 0; | 658 | return 0; |
644 | err_free_irq: | 659 | err_free_irq: |
645 | free_irq(i2c_dev->irq, i2c_dev); | 660 | free_irq(i2c_dev->irq, i2c_dev); |