* [PATCHv4 1/9] i2c: mv64xxx: Add macros to access parts of registers
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2013-06-12 8:07 ` Maxime Ripard
2013-06-12 8:07 ` [PATCHv4 2/9] i2c: mv64xxx: make the registers offset configurable Maxime Ripard
` (8 subsequent siblings)
9 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
These macros make it more comprehensive to access to useful masked and
shifted area of the various registers used.
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
drivers/i2c/busses/i2c-mv64xxx.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 6356439..d70a2fda 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -33,6 +33,10 @@
#define MV64XXX_I2C_REG_EXT_SLAVE_ADDR 0x10
#define MV64XXX_I2C_REG_SOFT_RESET 0x1c
+#define MV64XXX_I2C_ADDR_ADDR(val) ((val & 0x7f) << 1)
+#define MV64XXX_I2C_BAUD_DIV_N(val) (val & 0x7)
+#define MV64XXX_I2C_BAUD_DIV_M(val) ((val & 0xf) << 3)
+
#define MV64XXX_I2C_REG_CONTROL_ACK 0x00000004
#define MV64XXX_I2C_REG_CONTROL_IFLG 0x00000008
#define MV64XXX_I2C_REG_CONTROL_STOP 0x00000010
@@ -133,7 +137,7 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
drv_data->addr2 = (u32)msg->addr & 0xff;
} else {
- drv_data->addr1 = ((u32)msg->addr & 0x7f) << 1 | dir;
+ drv_data->addr1 = MV64XXX_I2C_ADDR_ADDR((u32)msg->addr) | dir;
drv_data->addr2 = 0;
}
}
@@ -151,7 +155,7 @@ static void
mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
{
writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET);
- writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)),
+ writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n),
drv_data->reg_base + MV64XXX_I2C_REG_BAUD);
writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR);
writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR);
--
1.8.3
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCHv4 2/9] i2c: mv64xxx: make the registers offset configurable
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2013-06-12 8:07 ` [PATCHv4 1/9] i2c: mv64xxx: Add macros to access parts of registers Maxime Ripard
@ 2013-06-12 8:07 ` Maxime Ripard
2013-06-12 10:54 ` Andrew Lunn
[not found] ` <1371024438-16631-3-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2013-06-12 8:07 ` [PATCHv4 3/9] ARM: orion: pass the i2c registers definition through the platform data Maxime Ripard
` (7 subsequent siblings)
9 siblings, 2 replies; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
The Allwinner i2c controller uses the same logic as the Marvell one, but
with slightly different register offsets.
Introduce a structure that will be passed by either the pdata or
associated to the compatible strings, and that holds the various
registers that might be needed.
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
drivers/i2c/busses/i2c-mv64xxx.c | 81 +++++++++++++++++++++-------------------
include/linux/mv643xx_i2c.h | 27 ++++++++++++--
2 files changed, 66 insertions(+), 42 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index d70a2fda..f9e076e 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -19,20 +19,12 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/of_i2c.h>
#include <linux/clk.h>
#include <linux/err.h>
-/* Register defines */
-#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00
-#define MV64XXX_I2C_REG_DATA 0x04
-#define MV64XXX_I2C_REG_CONTROL 0x08
-#define MV64XXX_I2C_REG_STATUS 0x0c
-#define MV64XXX_I2C_REG_BAUD 0x0c
-#define MV64XXX_I2C_REG_EXT_SLAVE_ADDR 0x10
-#define MV64XXX_I2C_REG_SOFT_RESET 0x1c
-
#define MV64XXX_I2C_ADDR_ADDR(val) ((val & 0x7f) << 1)
#define MV64XXX_I2C_BAUD_DIV_N(val) (val & 0x7)
#define MV64XXX_I2C_BAUD_DIV_M(val) ((val & 0xf) << 3)
@@ -98,6 +90,7 @@ struct mv64xxx_i2c_data {
u32 aborting;
u32 cntl_bits;
void __iomem *reg_base;
+ struct mv64xxx_i2c_regs *regs;
u32 addr1;
u32 addr2;
u32 bytes_left;
@@ -154,13 +147,13 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
static void
mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
{
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET);
+ writel(0, drv_data->reg_base + drv_data->regs->soft_reset);
writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n),
- drv_data->reg_base + MV64XXX_I2C_REG_BAUD);
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR);
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR);
+ drv_data->reg_base + drv_data->regs->clock);
+ writel(0, drv_data->reg_base + drv_data->regs->addr);
+ writel(0, drv_data->reg_base + drv_data->regs->ext_addr);
writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
drv_data->state = MV64XXX_I2C_STATE_IDLE;
}
@@ -282,7 +275,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
drv_data->msgs++;
drv_data->num_msgs--;
@@ -300,48 +293,48 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
case MV64XXX_I2C_ACTION_CONTINUE:
writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
break;
case MV64XXX_I2C_ACTION_SEND_START:
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
break;
case MV64XXX_I2C_ACTION_SEND_ADDR_1:
writel(drv_data->addr1,
- drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+ drv_data->reg_base + drv_data->regs->data);
writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
break;
case MV64XXX_I2C_ACTION_SEND_ADDR_2:
writel(drv_data->addr2,
- drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+ drv_data->reg_base + drv_data->regs->data);
writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
break;
case MV64XXX_I2C_ACTION_SEND_DATA:
writel(drv_data->msg->buf[drv_data->byte_posn++],
- drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+ drv_data->reg_base + drv_data->regs->data);
writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
break;
case MV64XXX_I2C_ACTION_RCV_DATA:
drv_data->msg->buf[drv_data->byte_posn++] =
- readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+ readl(drv_data->reg_base + drv_data->regs->data);
writel(drv_data->cntl_bits,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
break;
case MV64XXX_I2C_ACTION_RCV_DATA_STOP:
drv_data->msg->buf[drv_data->byte_posn++] =
- readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA);
+ readl(drv_data->reg_base + drv_data->regs->data);
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
drv_data->block = 0;
wake_up(&drv_data->waitq);
break;
@@ -356,7 +349,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
case MV64XXX_I2C_ACTION_SEND_STOP:
drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->reg_base + drv_data->regs->control);
drv_data->block = 0;
wake_up(&drv_data->waitq);
break;
@@ -372,9 +365,9 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
irqreturn_t rc = IRQ_NONE;
spin_lock_irqsave(&drv_data->lock, flags);
- while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) &
+ while (readl(drv_data->reg_base + drv_data->regs->control) &
MV64XXX_I2C_REG_CONTROL_IFLG) {
- status = readl(drv_data->reg_base + MV64XXX_I2C_REG_STATUS);
+ status = readl(drv_data->reg_base + drv_data->regs->status);
mv64xxx_i2c_fsm(drv_data, status);
mv64xxx_i2c_do_action(drv_data);
rc = IRQ_HANDLED;
@@ -496,6 +489,12 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = {
*****************************************************************************
*/
#ifdef CONFIG_OF
+static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
+ { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
+ {}
+};
+MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
+
static int
mv64xxx_calc_freq(const int tclk, const int n, const int m)
{
@@ -528,8 +527,10 @@ mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n,
static int
mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
- struct device_node *np)
+ struct device *dev)
{
+ const struct of_device_id *device;
+ struct device_node *np = dev->of_node;
u32 bus_freq, tclk;
int rc = 0;
@@ -558,6 +559,13 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
* So hard code the value to 1 second.
*/
drv_data->adapter.timeout = HZ;
+
+ device = of_match_device(mv64xxx_i2c_of_match_table, dev);
+ if (!device)
+ return -ENODEV;
+
+ drv_data->regs = (struct mv64xxx_i2c_regs *)device->data;
+
out:
return rc;
#endif
@@ -565,7 +573,7 @@ out:
#else /* CONFIG_OF */
static int
mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
- struct device_node *np)
+ struct device *dev)
{
return -ENODEV;
}
@@ -611,8 +619,9 @@ mv64xxx_i2c_probe(struct platform_device *pd)
drv_data->freq_n = pdata->freq_n;
drv_data->irq = platform_get_irq(pd, 0);
drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
+ drv_data->regs = pdata->regs;
} else if (pd->dev.of_node) {
- rc = mv64xxx_of_config(drv_data, pd->dev.of_node);
+ rc = mv64xxx_of_config(drv_data, &pd->dev);
if (rc)
goto exit_clk;
}
@@ -680,12 +689,6 @@ mv64xxx_i2c_remove(struct platform_device *dev)
return 0;
}
-static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
- { .compatible = "marvell,mv64xxx-i2c", },
- {}
-};
-MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
-
static struct platform_driver mv64xxx_i2c_driver = {
.probe = mv64xxx_i2c_probe,
.remove = mv64xxx_i2c_remove,
diff --git a/include/linux/mv643xx_i2c.h b/include/linux/mv643xx_i2c.h
index 5db5152..9304c94 100644
--- a/include/linux/mv643xx_i2c.h
+++ b/include/linux/mv643xx_i2c.h
@@ -12,11 +12,32 @@
#define MV64XXX_I2C_CTLR_NAME "mv64xxx_i2c"
+struct mv64xxx_i2c_regs {
+ u8 addr;
+ u8 ext_addr;
+ u8 data;
+ u8 control;
+ u8 status;
+ u8 clock;
+ u8 soft_reset;
+};
+
+struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
+ .addr = 0x00,
+ .ext_addr = 0x10,
+ .data = 0x04,
+ .control = 0x08,
+ .status = 0x0c,
+ .clock = 0x0c,
+ .soft_reset = 0x1c,
+};
+
/* i2c Platform Device, Driver Data */
struct mv64xxx_i2c_pdata {
- u32 freq_m;
- u32 freq_n;
- u32 timeout; /* In milliseconds */
+ u32 freq_m;
+ u32 freq_n;
+ struct mv64xxx_i2c_regs *regs;
+ u32 timeout; /* In milliseconds */
};
#endif /*_MV64XXX_I2C_H_*/
--
1.8.3
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCHv4 2/9] i2c: mv64xxx: make the registers offset configurable
2013-06-12 8:07 ` [PATCHv4 2/9] i2c: mv64xxx: make the registers offset configurable Maxime Ripard
@ 2013-06-12 10:54 ` Andrew Lunn
[not found] ` <20130612105431.GS16502-g2DYL2Zd6BY@public.gmane.org>
[not found] ` <1371024438-16631-3-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
1 sibling, 1 reply; 30+ messages in thread
From: Andrew Lunn @ 2013-06-12 10:54 UTC (permalink / raw)
To: Maxime Ripard
Cc: Andrew Lunn, Jason Cooper, Wolfram Sang, Emilio Lopez,
Tomasz Figa, linux-sunxi, linux-i2c, sunny, shuge, kevin,
linux-arm-kernel
On Wed, Jun 12, 2013 at 10:07:11AM +0200, Maxime Ripard wrote:
> The Allwinner i2c controller uses the same logic as the Marvell one, but
> with slightly different register offsets.
>
> Introduce a structure that will be passed by either the pdata or
> associated to the compatible strings, and that holds the various
> registers that might be needed.
Hi Maxime
I don't think this change is bisectable. It assumes the platform data
passes the registers, which is not true until the next patch.
Please can you re-arrange the order. Add the extra information to the
platform data, and then make use of it, not the other way around.
Thanks
Andrew
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
> drivers/i2c/busses/i2c-mv64xxx.c | 81 +++++++++++++++++++++-------------------
> include/linux/mv643xx_i2c.h | 27 ++++++++++++--
> 2 files changed, 66 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
> index d70a2fda..f9e076e 100644
> --- a/drivers/i2c/busses/i2c-mv64xxx.c
> +++ b/drivers/i2c/busses/i2c-mv64xxx.c
> @@ -19,20 +19,12 @@
> #include <linux/platform_device.h>
> #include <linux/io.h>
> #include <linux/of.h>
> +#include <linux/of_device.h>
> #include <linux/of_irq.h>
> #include <linux/of_i2c.h>
> #include <linux/clk.h>
> #include <linux/err.h>
>
> -/* Register defines */
> -#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00
> -#define MV64XXX_I2C_REG_DATA 0x04
> -#define MV64XXX_I2C_REG_CONTROL 0x08
> -#define MV64XXX_I2C_REG_STATUS 0x0c
> -#define MV64XXX_I2C_REG_BAUD 0x0c
> -#define MV64XXX_I2C_REG_EXT_SLAVE_ADDR 0x10
> -#define MV64XXX_I2C_REG_SOFT_RESET 0x1c
> -
> #define MV64XXX_I2C_ADDR_ADDR(val) ((val & 0x7f) << 1)
> #define MV64XXX_I2C_BAUD_DIV_N(val) (val & 0x7)
> #define MV64XXX_I2C_BAUD_DIV_M(val) ((val & 0xf) << 3)
> @@ -98,6 +90,7 @@ struct mv64xxx_i2c_data {
> u32 aborting;
> u32 cntl_bits;
> void __iomem *reg_base;
> + struct mv64xxx_i2c_regs *regs;
> u32 addr1;
> u32 addr2;
> u32 bytes_left;
> @@ -154,13 +147,13 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
> static void
> mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
> {
> - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET);
> + writel(0, drv_data->reg_base + drv_data->regs->soft_reset);
> writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n),
> - drv_data->reg_base + MV64XXX_I2C_REG_BAUD);
> - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR);
> - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR);
> + drv_data->reg_base + drv_data->regs->clock);
> + writel(0, drv_data->reg_base + drv_data->regs->addr);
> + writel(0, drv_data->reg_base + drv_data->regs->ext_addr);
> writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> drv_data->state = MV64XXX_I2C_STATE_IDLE;
> }
>
> @@ -282,7 +275,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>
> drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
> writel(drv_data->cntl_bits,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
>
> drv_data->msgs++;
> drv_data->num_msgs--;
> @@ -300,48 +293,48 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>
> case MV64XXX_I2C_ACTION_CONTINUE:
> writel(drv_data->cntl_bits,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> break;
>
> case MV64XXX_I2C_ACTION_SEND_START:
> writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> break;
>
> case MV64XXX_I2C_ACTION_SEND_ADDR_1:
> writel(drv_data->addr1,
> - drv_data->reg_base + MV64XXX_I2C_REG_DATA);
> + drv_data->reg_base + drv_data->regs->data);
> writel(drv_data->cntl_bits,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> break;
>
> case MV64XXX_I2C_ACTION_SEND_ADDR_2:
> writel(drv_data->addr2,
> - drv_data->reg_base + MV64XXX_I2C_REG_DATA);
> + drv_data->reg_base + drv_data->regs->data);
> writel(drv_data->cntl_bits,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> break;
>
> case MV64XXX_I2C_ACTION_SEND_DATA:
> writel(drv_data->msg->buf[drv_data->byte_posn++],
> - drv_data->reg_base + MV64XXX_I2C_REG_DATA);
> + drv_data->reg_base + drv_data->regs->data);
> writel(drv_data->cntl_bits,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> break;
>
> case MV64XXX_I2C_ACTION_RCV_DATA:
> drv_data->msg->buf[drv_data->byte_posn++] =
> - readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA);
> + readl(drv_data->reg_base + drv_data->regs->data);
> writel(drv_data->cntl_bits,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> break;
>
> case MV64XXX_I2C_ACTION_RCV_DATA_STOP:
> drv_data->msg->buf[drv_data->byte_posn++] =
> - readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA);
> + readl(drv_data->reg_base + drv_data->regs->data);
> drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
> writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> drv_data->block = 0;
> wake_up(&drv_data->waitq);
> break;
> @@ -356,7 +349,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
> case MV64XXX_I2C_ACTION_SEND_STOP:
> drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
> writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
> - drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
> + drv_data->reg_base + drv_data->regs->control);
> drv_data->block = 0;
> wake_up(&drv_data->waitq);
> break;
> @@ -372,9 +365,9 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
> irqreturn_t rc = IRQ_NONE;
>
> spin_lock_irqsave(&drv_data->lock, flags);
> - while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) &
> + while (readl(drv_data->reg_base + drv_data->regs->control) &
> MV64XXX_I2C_REG_CONTROL_IFLG) {
> - status = readl(drv_data->reg_base + MV64XXX_I2C_REG_STATUS);
> + status = readl(drv_data->reg_base + drv_data->regs->status);
> mv64xxx_i2c_fsm(drv_data, status);
> mv64xxx_i2c_do_action(drv_data);
> rc = IRQ_HANDLED;
> @@ -496,6 +489,12 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = {
> *****************************************************************************
> */
> #ifdef CONFIG_OF
> +static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
> + { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
> +
> static int
> mv64xxx_calc_freq(const int tclk, const int n, const int m)
> {
> @@ -528,8 +527,10 @@ mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n,
>
> static int
> mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
> - struct device_node *np)
> + struct device *dev)
> {
> + const struct of_device_id *device;
> + struct device_node *np = dev->of_node;
> u32 bus_freq, tclk;
> int rc = 0;
>
> @@ -558,6 +559,13 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
> * So hard code the value to 1 second.
> */
> drv_data->adapter.timeout = HZ;
> +
> + device = of_match_device(mv64xxx_i2c_of_match_table, dev);
> + if (!device)
> + return -ENODEV;
> +
> + drv_data->regs = (struct mv64xxx_i2c_regs *)device->data;
> +
> out:
> return rc;
> #endif
> @@ -565,7 +573,7 @@ out:
> #else /* CONFIG_OF */
> static int
> mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
> - struct device_node *np)
> + struct device *dev)
> {
> return -ENODEV;
> }
> @@ -611,8 +619,9 @@ mv64xxx_i2c_probe(struct platform_device *pd)
> drv_data->freq_n = pdata->freq_n;
> drv_data->irq = platform_get_irq(pd, 0);
> drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
> + drv_data->regs = pdata->regs;
> } else if (pd->dev.of_node) {
> - rc = mv64xxx_of_config(drv_data, pd->dev.of_node);
> + rc = mv64xxx_of_config(drv_data, &pd->dev);
> if (rc)
> goto exit_clk;
> }
> @@ -680,12 +689,6 @@ mv64xxx_i2c_remove(struct platform_device *dev)
> return 0;
> }
>
> -static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
> - { .compatible = "marvell,mv64xxx-i2c", },
> - {}
> -};
> -MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
> -
> static struct platform_driver mv64xxx_i2c_driver = {
> .probe = mv64xxx_i2c_probe,
> .remove = mv64xxx_i2c_remove,
> diff --git a/include/linux/mv643xx_i2c.h b/include/linux/mv643xx_i2c.h
> index 5db5152..9304c94 100644
> --- a/include/linux/mv643xx_i2c.h
> +++ b/include/linux/mv643xx_i2c.h
> @@ -12,11 +12,32 @@
>
> #define MV64XXX_I2C_CTLR_NAME "mv64xxx_i2c"
>
> +struct mv64xxx_i2c_regs {
> + u8 addr;
> + u8 ext_addr;
> + u8 data;
> + u8 control;
> + u8 status;
> + u8 clock;
> + u8 soft_reset;
> +};
> +
> +struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
> + .addr = 0x00,
> + .ext_addr = 0x10,
> + .data = 0x04,
> + .control = 0x08,
> + .status = 0x0c,
> + .clock = 0x0c,
> + .soft_reset = 0x1c,
> +};
> +
> /* i2c Platform Device, Driver Data */
> struct mv64xxx_i2c_pdata {
> - u32 freq_m;
> - u32 freq_n;
> - u32 timeout; /* In milliseconds */
> + u32 freq_m;
> + u32 freq_n;
> + struct mv64xxx_i2c_regs *regs;
> + u32 timeout; /* In milliseconds */
> };
>
> #endif /*_MV64XXX_I2C_H_*/
> --
> 1.8.3
>
^ permalink raw reply [flat|nested] 30+ messages in thread[parent not found: <1371024438-16631-3-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>]
* Re: [PATCHv4 2/9] i2c: mv64xxx: make the registers offset configurable
[not found] ` <1371024438-16631-3-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
@ 2013-06-12 13:57 ` Russell King - ARM Linux
[not found] ` <20130612135735.GR18614-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
0 siblings, 1 reply; 30+ messages in thread
From: Russell King - ARM Linux @ 2013-06-12 13:57 UTC (permalink / raw)
To: Maxime Ripard
Cc: Wolfram Sang, Jason Cooper, Andrew Lunn, Emilio Lopez,
Tomasz Figa, linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
On Wed, Jun 12, 2013 at 10:07:11AM +0200, Maxime Ripard wrote:
> The Allwinner i2c controller uses the same logic as the Marvell one, but
> with slightly different register offsets.
>
> Introduce a structure that will be passed by either the pdata or
> associated to the compatible strings, and that holds the various
> registers that might be needed.
I don't like this change. It introduces further indirection where it's
not really necessary, and it's also using platform data to specify this
which is in the opposite direction to what's required for moving towards
DT.
> @@ -154,13 +147,13 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
> static void
> mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
> {
> - writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET);
> + writel(0, drv_data->reg_base + drv_data->regs->soft_reset);
It'd be much better to copy the offsets themselves in drv_data. You're
only talking about 7 bytes here, so there's no worry about bloating the
drv_data structure.
> @@ -611,8 +619,9 @@ mv64xxx_i2c_probe(struct platform_device *pd)
> drv_data->freq_n = pdata->freq_n;
> drv_data->irq = platform_get_irq(pd, 0);
> drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
> + drv_data->regs = pdata->regs;
> } else if (pd->dev.of_node) {
> - rc = mv64xxx_of_config(drv_data, pd->dev.of_node);
> + rc = mv64xxx_of_config(drv_data, &pd->dev);
I'd suggest making the default register offsets be the drivers existing
offsets, and allowing it to be overriden. That nicely sorts out the
next comment below, and also gets rid of it in platform data. Moreover,
if you're going to re-use this driver, you should do it via a different
"compatible" name in DT, which the driver can then use to identify the
different register set layout.
> +struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
> + .addr = 0x00,
> + .ext_addr = 0x10,
> + .data = 0x04,
> + .control = 0x08,
> + .status = 0x0c,
> + .clock = 0x0c,
> + .soft_reset = 0x1c,
> +};
No, this means every file which includes this header ends up defining
this structure, which is globally visiable, and therefore its a recipe
for link failures.
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCHv4 3/9] ARM: orion: pass the i2c registers definition through the platform data
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2013-06-12 8:07 ` [PATCHv4 1/9] i2c: mv64xxx: Add macros to access parts of registers Maxime Ripard
2013-06-12 8:07 ` [PATCHv4 2/9] i2c: mv64xxx: make the registers offset configurable Maxime Ripard
@ 2013-06-12 8:07 ` Maxime Ripard
[not found] ` <1371024438-16631-4-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2013-06-12 8:07 ` [PATCHv4 4/9] i2c: mv64xxx: Add Allwinner sun4i compatible Maxime Ripard
` (6 subsequent siblings)
9 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
Convert the existing platform data users of the MV64XXX i2c driver to
pass the registers offset structure along with the platform data.
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
arch/arm/plat-orion/common.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index c019b7a..c166fc9 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -509,6 +509,7 @@ void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq)
****************************************************************************/
static struct mv64xxx_i2c_pdata orion_i2c_pdata = {
.freq_n = 3,
+ .regs = &mv64xxx_i2c_regs_mv64xxx,
.timeout = 1000, /* Default timeout of 1 second */
};
@@ -524,6 +525,7 @@ static struct platform_device orion_i2c = {
static struct mv64xxx_i2c_pdata orion_i2c_1_pdata = {
.freq_n = 3,
+ .regs = &mv64xxx_i2c_regs_mv64xxx,
.timeout = 1000, /* Default timeout of 1 second */
};
--
1.8.3
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCHv4 4/9] i2c: mv64xxx: Add Allwinner sun4i compatible
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
` (2 preceding siblings ...)
2013-06-12 8:07 ` [PATCHv4 3/9] ARM: orion: pass the i2c registers definition through the platform data Maxime Ripard
@ 2013-06-12 8:07 ` Maxime Ripard
[not found] ` <1371024438-16631-5-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2013-06-12 8:07 ` [PATCHv4 5/9] ARM: sunxi: dt: Add i2c controller nodes to the DTSI Maxime Ripard
` (5 subsequent siblings)
9 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
Add the compatible string for the Allwinner A10 i2c controller and the
associated register layout.
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
drivers/i2c/busses/Kconfig | 3 ++-
drivers/i2c/busses/i2c-mv64xxx.c | 1 +
include/linux/mv643xx_i2c.h | 10 ++++++++++
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 631736e..5dc4148 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -507,10 +507,11 @@ config I2C_MPC
config I2C_MV64XXX
tristate "Marvell mv64xxx I2C Controller"
- depends on (MV64X60 || PLAT_ORION)
+ depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI)
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Marvell 64xxx line of host bridges.
+ This driver is also used for Allwinner SoCs I2C controllers.
This driver can also be built as a module. If so, the module
will be called i2c-mv64xxx.
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index f9e076e..febf5ba 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -490,6 +490,7 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = {
*/
#ifdef CONFIG_OF
static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
+ { .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i},
{ .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
{}
};
diff --git a/include/linux/mv643xx_i2c.h b/include/linux/mv643xx_i2c.h
index 9304c94..737108e 100644
--- a/include/linux/mv643xx_i2c.h
+++ b/include/linux/mv643xx_i2c.h
@@ -32,6 +32,16 @@ struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
.soft_reset = 0x1c,
};
+struct mv64xxx_i2c_regs mv64xxx_i2c_regs_sun4i = {
+ .addr = 0x00,
+ .ext_addr = 0x04,
+ .data = 0x08,
+ .control = 0x0c,
+ .status = 0x10,
+ .clock = 0x14,
+ .soft_reset = 0x18,
+};
+
/* i2c Platform Device, Driver Data */
struct mv64xxx_i2c_pdata {
u32 freq_m;
--
1.8.3
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCHv4 5/9] ARM: sunxi: dt: Add i2c controller nodes to the DTSI
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
` (3 preceding siblings ...)
2013-06-12 8:07 ` [PATCHv4 4/9] i2c: mv64xxx: Add Allwinner sun4i compatible Maxime Ripard
@ 2013-06-12 8:07 ` Maxime Ripard
2013-06-12 8:07 ` [PATCHv4 6/9] ARM: sun4i: dt: Add i2c muxing options Maxime Ripard
` (4 subsequent siblings)
9 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
The Allwinner A10 and A13 both have 3 i2c controller embedded.
Add those to the common sunxi dtsi.
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Reviewed-by: Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 27 +++++++++++++++++++++++++++
arch/arm/boot/dts/sun5i-a13.dtsi | 27 +++++++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 04ff62a..f7e4a96 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -321,5 +321,32 @@
clocks = <&apb1_gates 23>;
status = "disabled";
};
+
+ i2c0: i2c@01c2ac00 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <7>;
+ clocks = <&apb1_gates 0>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@01c2b000 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <8>;
+ clocks = <&apb1_gates 1>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@01c2b400 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <9>;
+ clocks = <&apb1_gates 2>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index f34db19..31ebfd7 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -217,5 +217,32 @@
clocks = <&apb1_gates 19>;
status = "disabled";
};
+
+ i2c0: i2c@01c2ac00 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2ac00 0x400>;
+ interrupts = <7>;
+ clocks = <&apb1_gates 0>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@01c2b000 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2b000 0x400>;
+ interrupts = <8>;
+ clocks = <&apb1_gates 1>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@01c2b400 {
+ compatible = "allwinner,sun4i-i2c";
+ reg = <0x01c2b400 0x400>;
+ interrupts = <9>;
+ clocks = <&apb1_gates 2>;
+ clock-frequency = <100000>;
+ status = "disabled";
+ };
};
};
--
1.8.3
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCHv4 6/9] ARM: sun4i: dt: Add i2c muxing options
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
` (4 preceding siblings ...)
2013-06-12 8:07 ` [PATCHv4 5/9] ARM: sunxi: dt: Add i2c controller nodes to the DTSI Maxime Ripard
@ 2013-06-12 8:07 ` Maxime Ripard
2013-06-12 8:07 ` [PATCHv4 7/9] ARM: sun5i: " Maxime Ripard
` (3 subsequent siblings)
9 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
The i2c controller found on the Allwinner A10 has only one muxing option
available for each controller. Add them to the dtsi
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Reviewed-by: Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/arm/boot/dts/sun4i-a10.dtsi | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index f7e4a96..c2adc74 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -227,6 +227,26 @@
allwinner,function = "emac";
allwinner,drive = <0>;
allwinner,pull = <0>;
+
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PB0", "PB1";
+ allwinner,function = "i2c0";
+ allwinner,drive = <0>;
+ allwinner,pull = <1>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PB18", "PB19";
+ allwinner,function = "i2c1";
+ allwinner,drive = <0>;
+ allwinner,pull = <1>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PB20", "PB21";
+ allwinner,function = "i2c2";
+ allwinner,drive = <0>;
+ allwinner,pull = <1>;
};
};
--
1.8.3
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCHv4 7/9] ARM: sun5i: dt: Add i2c muxing options
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
` (5 preceding siblings ...)
2013-06-12 8:07 ` [PATCHv4 6/9] ARM: sun4i: dt: Add i2c muxing options Maxime Ripard
@ 2013-06-12 8:07 ` Maxime Ripard
[not found] ` <1371024438-16631-8-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2013-06-12 8:07 ` [PATCHv4 8/9] ARM: sun5i: olinuxino: Enable the i2c controllers Maxime Ripard
` (2 subsequent siblings)
9 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
The i2c controller found on the Allwinner A13 has only one muxing option
available for each controller. Add them to the dtsi
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Reviewed-by: Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/arm/boot/dts/sun5i-a13.dtsi | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index 31ebfd7..bca0af3 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -184,6 +184,27 @@
allwinner,drive = <0>;
allwinner,pull = <0>;
};
+
+ i2c0_pins_a: i2c0@0 {
+ allwinner,pins = "PB0", "PB1";
+ allwinner,function = "i2c0";
+ allwinner,drive = <0>;
+ allwinner,pull = <0>;
+ };
+
+ i2c1_pins_a: i2c1@0 {
+ allwinner,pins = "PB15", "PB16";
+ allwinner,function = "i2c1";
+ allwinner,drive = <0>;
+ allwinner,pull = <1>;
+ };
+
+ i2c2_pins_a: i2c2@0 {
+ allwinner,pins = "PB17", "PB18";
+ allwinner,function = "i2c2";
+ allwinner,drive = <0>;
+ allwinner,pull = <1>;
+ };
};
timer@01c20c00 {
--
1.8.3
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCHv4 8/9] ARM: sun5i: olinuxino: Enable the i2c controllers
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
` (6 preceding siblings ...)
2013-06-12 8:07 ` [PATCHv4 7/9] ARM: sun5i: " Maxime Ripard
@ 2013-06-12 8:07 ` Maxime Ripard
2013-06-12 8:07 ` [PATCHv4 9/9] ARM: sun4i: cubieboard: " Maxime Ripard
2013-06-12 11:26 ` [PATCHv4 0/9] Add I2C support for Allwinner SoCs Arnd Bergmann
9 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
The A13-Olinuxino makes use of the 3 i2c controllers found on the Allwinner
A13. Enable them in the device tree.
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Reviewed-by: Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index 3ca5506..80497e3 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -37,6 +37,24 @@
pinctrl-0 = <&uart1_pins_b>;
status = "okay";
};
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
+
+ i2c2: i2c@01c2b400 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins_a>;
+ status = "okay";
+ };
};
leds {
--
1.8.3
^ permalink raw reply related [flat|nested] 30+ messages in thread* [PATCHv4 9/9] ARM: sun4i: cubieboard: Enable the i2c controllers
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
` (7 preceding siblings ...)
2013-06-12 8:07 ` [PATCHv4 8/9] ARM: sun5i: olinuxino: Enable the i2c controllers Maxime Ripard
@ 2013-06-12 8:07 ` Maxime Ripard
2013-06-12 11:26 ` [PATCHv4 0/9] Add I2C support for Allwinner SoCs Arnd Bergmann
9 siblings, 0 replies; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 8:07 UTC (permalink / raw)
To: Wolfram Sang, Jason Cooper, Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Emilio Lopez,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tomasz Figa, Maxime Ripard
From: Emilio López <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
The Cubieboard makes use of the first two i2c controllers found on the
Allwinner A10; i2c-0 is used internally for the PMIC, while i2c-1
is exposed on the board headers. This patch enables them in the device
tree.
Signed-off-by: Emilio López <emilio-0Z03zUJReD5OxF6Tv1QG9Q@public.gmane.org>
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Reviewed-by: Tomasz Figa <tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index e752b57..757c4cd 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -56,6 +56,18 @@
pinctrl-0 = <&uart0_pins_a>;
status = "okay";
};
+
+ i2c0: i2c@01c2ac00 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+ };
+
+ i2c1: i2c@01c2b000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins_a>;
+ status = "okay";
+ };
};
leds {
--
1.8.3
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/groups/opt_out.
^ permalink raw reply related [flat|nested] 30+ messages in thread* Re: [PATCHv4 0/9] Add I2C support for Allwinner SoCs
[not found] ` <1371024438-16631-1-git-send-email-maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
` (8 preceding siblings ...)
2013-06-12 8:07 ` [PATCHv4 9/9] ARM: sun4i: cubieboard: " Maxime Ripard
@ 2013-06-12 11:26 ` Arnd Bergmann
2013-06-12 11:38 ` Maxime Ripard
9 siblings, 1 reply; 30+ messages in thread
From: Arnd Bergmann @ 2013-06-12 11:26 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Maxime Ripard, Wolfram Sang, Jason Cooper, Andrew Lunn,
Emilio Lopez, Tomasz Figa, linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf
On Wednesday 12 June 2013 10:07:09 Maxime Ripard wrote:
>
> This patchset adds support for the I2C controller found on most of the
> Allwinner SoCs, especially the already supported A10 and A13, and the
> yet to come A31.
>
> This driver leverages the Marvel mv64xxx i2c controller driver, that has
> an almost identical logic, with a slightly different register layout.
>
> It has been tested on a A13-Olinuxino and an A10s-Olinuxino.
It doesn't really matter, but can someone clarify why this driver can
be reused? Did marvell and allwinner license the same hardware block
or is just a really simple driver that does things in an obvious way?
Arnd
^ permalink raw reply [flat|nested] 30+ messages in thread* Re: [PATCHv4 0/9] Add I2C support for Allwinner SoCs
2013-06-12 11:26 ` [PATCHv4 0/9] Add I2C support for Allwinner SoCs Arnd Bergmann
@ 2013-06-12 11:38 ` Maxime Ripard
2013-06-12 12:38 ` Arnd Bergmann
0 siblings, 1 reply; 30+ messages in thread
From: Maxime Ripard @ 2013-06-12 11:38 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Wolfram Sang,
Jason Cooper, Andrew Lunn, Emilio Lopez, Tomasz Figa,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf
Hi Arnd,
On Wed, Jun 12, 2013 at 01:26:56PM +0200, Arnd Bergmann wrote:
> On Wednesday 12 June 2013 10:07:09 Maxime Ripard wrote:
> >
> > This patchset adds support for the I2C controller found on most of the
> > Allwinner SoCs, especially the already supported A10 and A13, and the
> > yet to come A31.
> >
> > This driver leverages the Marvel mv64xxx i2c controller driver, that has
> > an almost identical logic, with a slightly different register layout.
> >
> > It has been tested on a A13-Olinuxino and an A10s-Olinuxino.
>
> It doesn't really matter, but can someone clarify why this driver can
> be reused? Did marvell and allwinner license the same hardware block
> or is just a really simple driver that does things in an obvious way?
The Marvell and Allwinner controllers share the exact same logic (which
is definitely not trivial), based on a finite state machine that
triggers interrupts at each change of state, each state being a state in
the I2C protocol (like address sent, data received with an ACK, etc.).
The weird thing is that the only difference between the two controllers
is the register offsets, and that's it. The state numbers, bit index,
etc, are exactly the same.
So yes, I think they both licensed the same IP.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCHv4 0/9] Add I2C support for Allwinner SoCs
2013-06-12 11:38 ` Maxime Ripard
@ 2013-06-12 12:38 ` Arnd Bergmann
[not found] ` <201306121438.12549.arnd-r2nGTMty4D4@public.gmane.org>
0 siblings, 1 reply; 30+ messages in thread
From: Arnd Bergmann @ 2013-06-12 12:38 UTC (permalink / raw)
To: Maxime Ripard
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Wolfram Sang,
Jason Cooper, Andrew Lunn, Emilio Lopez, Tomasz Figa,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
sunny-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
shuge-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf,
kevin-0TFLnhJekD6UEPyfVivIlAC/G2K4zDHf
On Wednesday 12 June 2013, Maxime Ripard wrote:
> The Marvell and Allwinner controllers share the exact same logic (which
> is definitely not trivial), based on a finite state machine that
> triggers interrupts at each change of state, each state being a state in
> the I2C protocol (like address sent, data received with an ACK, etc.).
>
> The weird thing is that the only difference between the two controllers
> is the register offsets, and that's it. The state numbers, bit index,
> etc, are exactly the same.
Ok, cool. Great someone noticed!
> So yes, I think they both licensed the same IP.
I wonder if it's the Mentor Graphics Inventra mi2c block, which
would make sense given that Allwinner also uses musb.
Arnd
^ permalink raw reply [flat|nested] 30+ messages in thread