linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Matthew McClintock <mcclintock@freescale.com>
To: Adrian Cox <adrian@humboldt.co.uk>
Cc: Embedded Linux PPC list <linuxppc-embedded@lists.linuxppc.org>,
	"Kumar K. Gala" <kumar.gala@motorola.com>,
	Matthew McClintock <mcclintock@motorola.com>
Subject: Re: [PATCH][RFC]Updated MPC I2C driver
Date: Thu, 01 Jul 2004 14:59:47 +0000	[thread overview]
Message-ID: <1088693987.7555.60.camel@matthew-laptop> (raw)
In-Reply-To: <1088705955.28598.168.camel@localhost>

[-- Attachment #1: Type: text/plain, Size: 1106 bytes --]

Hi Adrian,

	The driver works well on both an mpc8540ads and a sandpoint here.
However, I just learned yesterday that i2c 32-bit read/writes on the
85xx will not always be guaranteed to work. So there does in fact need
to be an abstraction there for 8-bit/32-bit read/writes. I wrote up a
patch that does just that and it is attached, any suggestions or
different ways to implement it I would be glad to take a go at it if
your busy. I tested the patch on our mpc8540ads and sandpoint here, and
it seems to work well. One note: the FS_I2C_32BIT needs to be set in the
flags. Let me know what you think.

Regards,
Matthew

On Thu, 2004-07-01 at 18:19, Adrian Cox wrote:
> This version should support MPC8540 as well as MPC8245 and MPC107. I
> don't have MPC85xx hardware, so I'd like feedback from people who do.
> To use it on MPC107/824x requires the OCP patch that went by on the list
> on Tuesday. The support for MPC85xx is already in the kernel.
> If nobody has any complaints I'm ready to send it to Greg K-H.
> - Adrian Cox
> Humboldt Solutions Ltd.
--
Matthew McClintock <mcclintock@freescale.com>

[-- Attachment #2: mpc-i2c-byte-word.patch --]
[-- Type: text/x-patch, Size: 4820 bytes --]

diff -purN linuxppc-2.5-i2c-bak/drivers/i2c/busses/i2c-mpc.c linuxppc-2.5-i2c/drivers/i2c/busses/i2c-mpc.c
--- linuxppc-2.5-i2c-bak/drivers/i2c/busses/i2c-mpc.c	2004-07-01 14:16:22.000000000 -0500
+++ linuxppc-2.5-i2c/drivers/i2c/busses/i2c-mpc.c	2004-07-01 14:47:39.000000000 -0500
@@ -72,18 +72,40 @@ struct mpc_i2c {
 	struct i2c_adapter adap;
 };

+static u32 mpc_i2c_read(struct mpc_i2c *i2c, char *addr)
+{
+	struct ocp_fs_i2c_data *i2c_data = i2c->ocpdef->additions;
+
+	if (i2c_data && (i2c_data->flags & FS_I2C_32BIT)) {
+		return readl(addr);
+	} else {
+		return readb(addr);
+	}
+}
+
+static void mpc_i2c_write(struct mpc_i2c *i2c, u32 val, char *addr)
+{
+	struct ocp_fs_i2c_data *i2c_data = i2c->ocpdef->additions;
+
+	if (i2c_data && (i2c_data->flags & FS_I2C_32BIT)) {
+		writel(val, addr);
+	} else {
+		writeb(val & 0xff, addr);
+	}
+}
+
 static __inline__ void writeccr(struct mpc_i2c *i2c, u32 x)
 {
-	writel(x, i2c->base + MPC_I2C_CR);
+	mpc_i2c_write(i2c, x, i2c->base + MPC_I2C_CR);
 }

 static irqreturn_t mpc_i2c_isr(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct mpc_i2c *i2c = dev_id;
-	if (readl(i2c->base + MPC_I2C_SR) & CSR_MIF) {
+	if (mpc_i2c_read(i2c, i2c->base + MPC_I2C_SR) & CSR_MIF) {
 		/* Read again to allow register to stabilise */
-		i2c->interrupt = readl(i2c->base + MPC_I2C_SR);
-		writel(0, i2c->base + MPC_I2C_SR);
+		i2c->interrupt = mpc_i2c_read(i2c, i2c->base + MPC_I2C_SR);
+		mpc_i2c_write(i2c, 0, i2c->base + MPC_I2C_SR);
 		wake_up_interruptible(&i2c->queue);
 	}
 	return IRQ_HANDLED;
@@ -97,7 +119,7 @@ static int i2c_wait(struct mpc_i2c *i2c,
 	int result = 0;

 	if (i2c->ocpdef->irq == OCP_IRQ_NA) {
-		while(! (readl(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
+		while(! (mpc_i2c_read(i2c, i2c->base + MPC_I2C_SR) & CSR_MIF)) {
 			schedule();
 			if (orig_jiffies + timeout < jiffies) {
 				DPRINTK("I2C: timeout\n");
@@ -105,8 +127,8 @@ static int i2c_wait(struct mpc_i2c *i2c,
 				break;
 			}
 		}
-		x = readl(i2c->base + MPC_I2C_SR);
-		writel(0, i2c->base + MPC_I2C_SR);
+		x = mpc_i2c_read(i2c, i2c->base + MPC_I2C_SR);
+		mpc_i2c_write(i2c, 0, i2c->base + MPC_I2C_SR);
 	} else {
 		add_wait_queue(&i2c->queue, &wait);
 		while ( ! (i2c->interrupt & CSR_MIF)) {
@@ -158,12 +180,12 @@ static void mpc_i2c_start(struct mpc_i2c
 	struct ocp_fs_i2c_data *i2c_data = i2c->ocpdef->additions;
         /* Set clock and filters */
 	if (i2c_data && (i2c_data->flags & FS_I2C_SEPARATE_DFSRR)) {
-		writel(0x31, i2c->base + MPC_I2C_FDR);
-		writel(0x10, i2c->base + MPC_I2C_DFSRR);
+		mpc_i2c_write(i2c, 0x31, i2c->base + MPC_I2C_FDR);
+		mpc_i2c_write(i2c, 0x10, i2c->base + MPC_I2C_DFSRR);
 	} else
-		writel(0x1031, i2c->base + MPC_I2C_FDR);
+		mpc_i2c_write(i2c, 0x1031, i2c->base + MPC_I2C_FDR);
         /* Clear arbitration */
-        writel(0, i2c->base + MPC_I2C_SR);
+        mpc_i2c_write(i2c, 0, i2c->base + MPC_I2C_SR);
        	/* Start with MEN */
 	writeccr(i2c, CCR_MEN);
 }
@@ -187,14 +209,14 @@ static int mpc_write(struct mpc_i2c *i2c
 	writeccr(i2c, CCR_MIEN | CCR_MEN |
 		      CCR_MSTA | CCR_MTX | flags);
 	/* Write target byte */
-	writel((target << 1), i2c->base + MPC_I2C_DR);
+	mpc_i2c_write(i2c, (target << 1), i2c->base + MPC_I2C_DR);

 	if (i2c_wait(i2c, timeout, 1) < 0)
 	    return -1;

         for(i = 0; i < length; i++) {
 	        /* Write data byte */
-	        writel(data[i], i2c->base + MPC_I2C_DR);
+	        mpc_i2c_write(i2c, data[i], i2c->base + MPC_I2C_DR);

 	        if (i2c_wait(i2c, timeout, 1) < 0)
 	            return -1;
@@ -217,7 +239,7 @@ static int mpc_read(struct mpc_i2c *i2c,
 	writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA |
 		      CCR_MTX | flags);
 	/* Write target address byte - this time with the read flag set */
-	writel((target << 1) | 1, i2c->base + MPC_I2C_DR);
+	mpc_i2c_write(i2c, (target << 1) | 1, i2c->base + MPC_I2C_DR);

 	if (i2c_wait(i2c, timeout, 0) < 0)
 	    return -1;
@@ -228,7 +250,7 @@ static int mpc_read(struct mpc_i2c *i2c,
 	else
 	    writeccr(i2c, CCR_MIEN| CCR_MEN | CCR_MSTA);
     	/* Dummy read */
-	readl(i2c->base + MPC_I2C_DR);
+	mpc_i2c_read(i2c, i2c->base + MPC_I2C_DR);

 	for(i = 0; i < length; i++) {
 		if (i2c_wait(i2c, timeout, 0) < 0)
@@ -242,7 +264,7 @@ static int mpc_read(struct mpc_i2c *i2c,
 		if (i == length - 1)
 			writeccr(i2c, CCR_MIEN | CCR_MEN |
 				      CCR_TXAK);
-		data[i] = readl(i2c->base + MPC_I2C_DR);
+		data[i] = mpc_i2c_read(i2c, i2c->base + MPC_I2C_DR);
 	}

 	return length;
@@ -260,7 +282,7 @@ static int mpc_xfer(struct i2c_adapter *
         mpc_i2c_start(i2c);

 	/* Allow bus up to 1s to become not busy */
-	while(readl(i2c->base + MPC_I2C_SR) & CSR_MBB) {
+	while(mpc_i2c_read(i2c, i2c->base + MPC_I2C_SR) & CSR_MBB) {
                 if (signal_pending(current))
 		{
 			DPRINTK("I2C: Interrupted\n");

  reply	other threads:[~2004-07-01 14:59 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-07-01 18:19 [PATCH][RFC]Updated MPC I2C driver Adrian Cox
2004-07-01 14:59 ` Matthew McClintock [this message]
2004-07-01 21:25   ` Adrian Cox
2004-07-01 22:32     ` Sylvain Munaut
2004-07-02  9:05       ` Adrian Cox
2004-07-02 11:01         ` Sylvain Munaut
2004-07-02 13:44           ` Adrian Cox
2004-07-02 15:11             ` Sylvain Munaut
2004-07-01 18:59 ` Eugene Surovegin
2004-07-01 19:20 ` Sylvain Munaut
2004-07-01 15:48   ` Matthew McClintock
2004-07-01 21:07     ` Sylvain Munaut
2004-07-01 20:54   ` Adrian Cox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1088693987.7555.60.camel@matthew-laptop \
    --to=mcclintock@freescale.com \
    --cc=adrian@humboldt.co.uk \
    --cc=kumar.gala@motorola.com \
    --cc=linuxppc-embedded@lists.linuxppc.org \
    --cc=mcclintock@motorola.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).