diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2014-03-04 11:28:38 -0500 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2014-03-05 11:30:11 -0500 |
commit | c7dcb1fec059c429f5096d20ab9e0f439fcfa909 (patch) | |
tree | 433f6711c2b155bd92fc63199d964b547f5794a7 /drivers/i2c | |
parent | 370136bc67c3f502ec96446e502ba80b94150f9d (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>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-mv64xxx.c | 11 |
1 files changed, 11 insertions, 0 deletions
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 | ||
155 | static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { | 156 | static 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 | */ |
688 | static const struct of_device_id mv64xxx_i2c_of_match_table[] = { | 694 | static 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 | |||
798 | out: | 809 | out: |
799 | return rc; | 810 | return rc; |
800 | #endif | 811 | #endif |