aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2014-03-04 11:28:38 -0500
committerWolfram Sang <wsa@the-dreams.de>2014-03-05 11:30:11 -0500
commitc7dcb1fec059c429f5096d20ab9e0f439fcfa909 (patch)
tree433f6711c2b155bd92fc63199d964b547f5794a7
parent370136bc67c3f502ec96446e502ba80b94150f9d (diff)
i2c: mv64xxx: Add support for the Allwinner A31 I2C driver
The Allwinner A31 I2C controller is almost identical to the one used in the other Allwinner SoCs, except for the fact that it needs to clear the interrupt by setting the INT_FLAGS bit in the control register, instead of clearing it. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt21
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c11
2 files changed, 25 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
index 21062bc3408d..befd4fb4764f 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
@@ -4,19 +4,26 @@
4Required properties : 4Required properties :
5 5
6 - reg : Offset and length of the register set for the device 6 - reg : Offset and length of the register set for the device
7 - compatible : Should be "marvell,mv64xxx-i2c" or "allwinner,sun4i-i2c" 7 - compatible : Should be either:
8 or "marvell,mv78230-i2c" or "marvell,mv78230-a0-i2c" 8 - "allwinner,sun4i-i2c"
9 Note: Only use "marvell,mv78230-a0-i2c" for a very rare, 9 - "allwinner,sun6i-a31-i2c"
10 initial version of the SoC which had broken offload 10 - "marvell,mv64xxx-i2c"
11 support. Linux auto-detects this and sets it 11 - "marvell,mv78230-i2c"
12 appropriately. 12 - "marvell,mv78230-a0-i2c"
13 * Note: Only use "marvell,mv78230-a0-i2c" for a
14 very rare, initial version of the SoC which
15 had broken offload support. Linux
16 auto-detects this and sets it appropriately.
13 - interrupts : The interrupt number 17 - interrupts : The interrupt number
14 18
15Optional properties : 19Optional properties :
16 20
17 - clock-frequency : Desired I2C bus clock frequency in Hz. If not set the 21 - clock-frequency : Desired I2C bus clock frequency in Hz. If not set the
18default frequency is 100kHz 22default frequency is 100kHz
19 - resets : phandle to the parent reset controller 23
24 - resets : phandle to the parent reset controller. Mandatory
25 whenever you're using the "allwinner,sun6i-a31-i2c"
26 compatible.
20 27
21Examples: 28Examples:
22 29
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 1bb69b6f746d..203a5482a866 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -150,6 +150,7 @@ struct mv64xxx_i2c_data {
150/* 5us delay in order to avoid repeated start timing violation */ 150/* 5us delay in order to avoid repeated start timing violation */
151 bool errata_delay; 151 bool errata_delay;
152 struct reset_control *rstc; 152 struct reset_control *rstc;
153 bool irq_clear_inverted;
153}; 154};
154 155
155static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { 156static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@@ -568,6 +569,11 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
568 status = readl(drv_data->reg_base + drv_data->reg_offsets.status); 569 status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
569 mv64xxx_i2c_fsm(drv_data, status); 570 mv64xxx_i2c_fsm(drv_data, status);
570 mv64xxx_i2c_do_action(drv_data); 571 mv64xxx_i2c_do_action(drv_data);
572
573 if (drv_data->irq_clear_inverted)
574 writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_IFLG,
575 drv_data->reg_base + drv_data->reg_offsets.control);
576
571 rc = IRQ_HANDLED; 577 rc = IRQ_HANDLED;
572 } 578 }
573 spin_unlock_irqrestore(&drv_data->lock, flags); 579 spin_unlock_irqrestore(&drv_data->lock, flags);
@@ -687,6 +693,7 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = {
687 */ 693 */
688static const struct of_device_id mv64xxx_i2c_of_match_table[] = { 694static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
689 { .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i}, 695 { .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i},
696 { .compatible = "allwinner,sun6i-a31-i2c", .data = &mv64xxx_i2c_regs_sun4i},
690 { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, 697 { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
691 { .compatible = "marvell,mv78230-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, 698 { .compatible = "marvell,mv78230-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
692 { .compatible = "marvell,mv78230-a0-i2c", .data = &mv64xxx_i2c_regs_mv64xxx}, 699 { .compatible = "marvell,mv78230-a0-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
@@ -795,6 +802,10 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
795 drv_data->offload_enabled = false; 802 drv_data->offload_enabled = false;
796 drv_data->errata_delay = true; 803 drv_data->errata_delay = true;
797 } 804 }
805
806 if (of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
807 drv_data->irq_clear_inverted = true;
808
798out: 809out:
799 return rc; 810 return rc;
800#endif 811#endif