* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Joakim Tjernlund
0 siblings, 0 replies; 43+ messages in thread
From: Joakim Tjernlund @ 2005-05-19 6:23 UTC (permalink / raw)
To: Tom Rini; +Cc: linuxppc-embedded, sensors
>
> On Fri, Oct 11, 2002 at 11:12:02AM +0200, Joakim Tjernlund wrote:
>
> > OK, here it is.
> >
> > Perhaps someone can add it to the ppctree?
>
> If you can submit this as a patch vs what's in the i2c CVS tree or the
> ppctree, than yes, this can be committed there, and to the ppctrees.
>
> --
> Tom Rini (TR1265)
> http://gate.crashing.org/~trini/
>
> ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
Tom, do you look after 8xx_io/enet.c? I sent a patch to the emmbedded list
yesterday that does away with an expensive memcpy.
Jocke
--- i2c-algo-8xx.c Mon Sep 30 16:20:42 2002
+++ i2c-algo-8xx.c.clean Tue Oct 22 10:49:33 2002
@@ -7,15 +7,12 @@
* Brad Parker (brad@heeltoe.com)
*/
-// XXX todo
-// timeout sleep?
-
/* $Id$ */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include <linux/init.h>
#include <asm/uaccess.h>
@@ -30,25 +27,25 @@
#include <linux/i2c-algo-8xx.h>
#define CPM_MAX_READ 513
-
+/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */
static wait_queue_head_t iic_wait;
static ushort r_tbase, r_rbase;
int cpm_scan = 0;
-int cpm_debug = 1;
+int cpm_debug = 0;
-static void
-cpm_iic_interrupt(void *dev_id)
+static void
+cpm_iic_interrupt(void *dev_id, struct pt_regs *regs)
{
volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id;
-
if (cpm_debug > 1)
printk("cpm_iic_interrupt(dev_id=%p)\n", dev_id);
-
- /* Chip errata, clear enable.
- */
- i2c->i2c_i2mod = 0;
-
+#if 0
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs */
+ /* This should probably be removed and replaced by I2C_CHIP_ERRATA stuff */
+ /* Someone with a buggy CPU needs to confirm that */
+ i2c->i2c_i2mod &= ~1;
+#endif
/* Clear interrupt.
*/
i2c->i2c_i2cer = 0xff;
@@ -63,6 +60,8 @@
{
volatile iic_t *iip = cpm_adap->iip;
volatile i2c8xx_t *i2c = cpm_adap->i2c;
+ unsigned char brg;
+ bd_t *bd = (bd_t *)__res;
if (cpm_debug) printk("cpm_iic_init()\n");
@@ -101,15 +100,24 @@
cp->cp_cpcr mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
while (cp->cp_cpcr & CPM_CR_FLG);
+ } else {
+ iip->iic_rbptr = iip->iic_rbase;
+ iip->iic_tbptr = iip->iic_tbase;
+ iip->iic_rstate = 0;
+ iip->iic_tstate = 0;
}
/* Select an arbitrary address. Just make sure it is unique.
*/
- i2c->i2c_i2add = 0x34;
+ i2c->i2c_i2add = 0xfe;
- /* Make clock run maximum slow.
+ /* Make clock run at 60 KHz.
*/
- i2c->i2c_i2brg = 7;
+ brg = (unsigned char) (bd->bi_intfreq/(32*2*60000) -3);
+ i2c->i2c_i2brg = brg;
+
+ i2c->i2c_i2mod = 0x00;
+ i2c->i2c_i2com = 0x01; /* Master mode */
/* Disable interrupts.
*/
@@ -131,7 +139,7 @@
/* Shut down IIC.
*/
- i2c->i2c_i2mod = 0;
+ i2c->i2c_i2mod &= ~1;
i2c->i2c_i2cmr = 0;
i2c->i2c_i2cer = 0xff;
@@ -151,22 +159,24 @@
iip->iic_rstate = 0;
iip->iic_rdp = 0;
- iip->iic_rbptr = 0;
+ iip->iic_rbptr = iip->iic_rbase;
iip->iic_rbc = 0;
iip->iic_rxtmp = 0;
iip->iic_tstate = 0;
iip->iic_tdp = 0;
- iip->iic_tbptr = 0;
+ iip->iic_tbptr = iip->iic_tbase;
iip->iic_tbc = 0;
iip->iic_txtmp = 0;
}
#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */
+#define BD_SC_OV ((ushort)0x0002) /* OV - receive overrun */
#define CPM_CR_CLOSE_RXBD ((ushort)0x0007)
static void force_close(struct i2c_algo_8xx_data *cpm)
{
- if (cpm->reloc = 0) {
+ volatile i2c8xx_t *i2c = cpm->i2c;
+ if (cpm->reloc = 0) { /* micro code disabled */
volatile cpm8xx_t *cp = cpm->cp;
if (cpm_debug) printk("force_close()\n");
@@ -176,6 +186,8 @@
while (cp->cp_cpcr & CPM_CR_FLG);
}
+ i2c->i2c_i2cmr = 0x00; /* Disable all interrupts */
+ i2c->i2c_i2cer = 0xff;
}
@@ -190,7 +202,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf, *rbdf;
u_char *tb;
- unsigned long flags;
+ unsigned long flags, tmo;
if (count >= CPM_MAX_READ)
return -EINVAL;
@@ -207,68 +219,104 @@
* All that is used is the first byte for address, the remainder
* is just used for timing (and doesn't really have to exist).
*/
- if (cpm->reloc) {
- cpm_reset_iic_params(iip);
- }
tb = cpm->temp;
tb = (u_char *)(((uint)tb + 15) & ~15);
tb[0] = abyte; /* Device address byte w/rw flag */
- flush_dcache_range(tb, tb+1);
-
+ flush_dcache_range((unsigned long)tb, (unsigned long)(tb+1));
if (cpm_debug) printk("cpm_iic_read(abyte=0x%x)\n", abyte);
tbdf->cbd_bufaddr = __pa(tb);
tbdf->cbd_datlen = count + 1;
tbdf->cbd_sc - BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
+ BD_SC_READY | BD_SC_LAST |
BD_SC_WRAP | BD_IIC_START;
+ iip->iic_mrblr = count +1; /* prevent excessive read, +1
+ is needed otherwise will the
+ RXB interrupt come too early */
+
+ /* flush will invalidate too. */
+ flush_dcache_range((unsigned long)buf, (unsigned long)(buf+count));
+
rbdf->cbd_datlen = 0;
rbdf->cbd_bufaddr = __pa(buf);
- rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
-
- /* Chip bug, set enable here */
- save_flags(flags); cli();
- i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
- i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT;
+ if(count > 16){
+ /* Chip bug, set enable here */
+ local_irq_save(flags);
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+
+ /* Wait for IIC transfer */
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
+ local_irq_restore(flags);
+ } else { /* busy wait for small transfers, its faster */
+ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+ tmo = jiffies + 1*HZ;
+ while(!(i2c->i2c_i2cer & 0x11 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */
+ }
- /* Wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
- restore_flags(flags);
- if (signal_pending(current))
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug)
+ printk("IIC read: timeout!\n");
return -EIO;
-
+ }
+#ifdef I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
if (cpm_debug) {
printk("tx sc %04x, rx sc %04x\n",
tbdf->cbd_sc, rbdf->cbd_sc);
}
+ if (tbdf->cbd_sc & BD_SC_READY) {
+ printk("IIC read; complete but tbuf ready\n");
+ force_close(cpm);
+ printk("tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+
if (tbdf->cbd_sc & BD_SC_NAK) {
- printk("IIC read; no ack\n");
- return 0;
+ if (cpm_debug)
+ printk("IIC read; no ack\n");
+ return -EREMOTEIO;
}
if (rbdf->cbd_sc & BD_SC_EMPTY) {
- printk("IIC read; complete but rbuf empty\n");
- force_close(cpm);
- printk("tx sc %04x, rx sc %04x\n",
- tbdf->cbd_sc, rbdf->cbd_sc);
+ /* force_close(cpm); */
+ if (cpm_debug){
+ printk("IIC read; complete but rbuf empty\n");
+ printk("tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+ return -EREMOTEIO;
+ }
+
+ if (rbdf->cbd_sc & BD_SC_OV) {
+ if (cpm_debug)
+ printk("IIC read; Overrun\n");
+ return -EREMOTEIO;;
}
if (cpm_debug) printk("read %d bytes\n", rbdf->cbd_datlen);
if (rbdf->cbd_datlen < count) {
- printk("IIC read; short, wanted %d got %d\n",
- count, rbdf->cbd_datlen);
+ if (cpm_debug)
+ printk("IIC read; short, wanted %d got %d\n",
+ count, rbdf->cbd_datlen);
return 0;
}
-
- invalidate_dcache_range(buf, buf+count);
-
return count;
}
@@ -283,7 +331,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf;
u_char *tb;
- unsigned long flags;
+ unsigned long flags, tmo;
/* check for and use a microcode relocation patch */
if (cpm->reloc) {
@@ -293,8 +341,8 @@
tb = (u_char *)(((uint)tb + 15) & ~15);
*tb = abyte; /* Device address byte w/rw flag */
- flush_dcache_range(tb, tb+1);
- flush_dcache_range(buf, buf+count);
+ flush_dcache_range((unsigned long)tb, (unsigned long)(tb+1));
+ flush_dcache_range((unsigned long)buf, (unsigned long)(buf+count));
if (cpm_debug) printk("cpm_iic_write(abyte=0x%x)\n", abyte);
@@ -309,31 +357,53 @@
tbdf[1].cbd_datlen = count;
tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP;
- /* Chip bug, set enable here */
- save_flags(flags); cli();
- i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
- i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ if(count > 16){
+ /* Chip bug, set enable here */
+ local_irq_save(flags);
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+
+ /* Wait for IIC transfer */
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
+ local_irq_restore(flags);
+ } else { /* busy wait for small transfers, its faster */
+ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+ tmo = jiffies + 1*HZ;
+ while(!(i2c->i2c_i2cer & 0x12 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */
+ }
- /* Wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
- restore_flags(flags);
- if (signal_pending(current))
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug && !tmo)
+ printk("IIC write: timeout!\n");
return -EIO;
-
+ }
+
+#if I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
if (cpm_debug) {
printk("tx0 sc %04x, tx1 sc %04x\n",
tbdf[0].cbd_sc, tbdf[1].cbd_sc);
}
if (tbdf->cbd_sc & BD_SC_NAK) {
- printk("IIC write; no ack\n");
+ if (cpm_debug)
+ printk("IIC write; no ack\n");
return 0;
}
if (tbdf->cbd_sc & BD_SC_READY) {
- printk("IIC write; complete but tbuf ready\n");
+ if (cpm_debug)
+ printk("IIC write; complete but tbuf ready\n");
return 0;
}
@@ -351,7 +421,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf, *rbdf;
u_char *tb;
- unsigned long flags, len;
+ unsigned long flags, len, tmo;
if (cpm_debug > 1)
printk("cpm_iic_tryaddress(cpm=%p,addr=%d)\n", cpm, addr);
@@ -376,31 +446,43 @@
tb[0] = (addr << 1) | 1; /* device address (+ read) */
len = 2;
- flush_dcache_range(tb, tb+1);
+ flush_dcache_range((unsigned long)tb, (unsigned long)(tb+2));
tbdf->cbd_bufaddr = __pa(tb);
tbdf->cbd_datlen = len;
tbdf->cbd_sc - BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
+ BD_SC_READY | BD_SC_LAST |
BD_SC_WRAP | BD_IIC_START;
rbdf->cbd_datlen = 0;
rbdf->cbd_bufaddr = __pa(tb+2);
- rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;
- save_flags(flags); cli();
+ local_irq_save(flags);
i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
if (cpm_debug > 1) printk("about to sleep\n");
/* wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
- restore_flags(flags);
- if (signal_pending(current))
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
+ local_irq_restore(flags);
+
+#ifdef I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
+
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug && !tmo)
+ printk("IIC tryaddress: timeout!\n");
return -EIO;
+ }
if (cpm_debug > 1) printk("back from sleep\n");
@@ -430,8 +512,8 @@
if (cpm_debug)
printk("i2c-algo-8xx.o: "
- "#%d addr=0x%x flags=0x%x len=%d\n",
- i, pmsg->addr, pmsg->flags, pmsg->len);
+ "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n",
+ i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf);
addr = pmsg->addr << 1;
if (pmsg->flags & I2C_M_RD )
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
@ 2005-05-19 6:23 ` Tom Rini
-1 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2002-10-24 16:10 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: linuxppc-embedded, sensors
On Tue, Oct 22, 2002 at 11:15:38AM +0200, Joakim Tjernlund wrote:
>
> > On Fri, Oct 11, 2002 at 11:12:02AM +0200, Joakim Tjernlund wrote:
> >
> > > OK, here it is.
> > >
> > > Perhaps someone can add it to the ppctree?
> >
> > If you can submit this as a patch vs what's in the i2c CVS tree or the
> > ppctree, than yes, this can be committed there, and to the ppctrees.
>
> Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
Can you please split this into logical chunks, or give me a list of each
fix in here? Thanks.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread
* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Tom Rini
0 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2005-05-19 6:23 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: linuxppc-embedded, sensors
On Tue, Oct 22, 2002 at 11:15:38AM +0200, Joakim Tjernlund wrote:
>
> > On Fri, Oct 11, 2002 at 11:12:02AM +0200, Joakim Tjernlund wrote:
> >
> > > OK, here it is.
> > >
> > > Perhaps someone can add it to the ppctree?
> >
> > If you can submit this as a patch vs what's in the i2c CVS tree or the
> > ppctree, than yes, this can be committed there, and to the ppctrees.
>
> Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
Can you please split this into logical chunks, or give me a list of each
fix in here? Thanks.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
@ 2005-05-19 6:23 ` Joakim Tjernlund
-1 siblings, 0 replies; 43+ messages in thread
From: Joakim Tjernlund @ 2002-10-24 18:21 UTC (permalink / raw)
To: Tom Rini; +Cc: linuxppc-embedded, sensors
> >
> > Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
>
> Can you please split this into logical chunks, or give me a list of each
> fix in here? Thanks.
ohh, kind of hard to remember all that went into that patch. The path
has evoled over many days, but I can try summarize. I have tested this code
pretty well it does not fail for me. Speed has been between 10-150KHz. The
old code fails as soon you start to stress it a little.
- replace invalidate_dcache_range with flush_dcache_range, since buffers are
NOT cache aligned. flush will write to memory AND invalidate the cache.
- move the chip errata stuff from irq routine into read/write routines. Made
it default off since it causes lock ups on my I2C device. I think it causes
a too short STOP condition. If enabled I2C will behave better than before, but
may still cause problems if the read/write is interrupted with a signal while
microcode is enabled.
- set default speed to 60 KHz instead.
- missing/faulty initialization of parameter ram when I2C micro patch is active.
- replaced assingments with mask operations with relevant bits. Example:
/* Shut down IIC. */
i2c->i2c_i2mod = 0;
i2c->i2c_i2mod &= ~1;
- When reading from I2C device, let the receive BD generate interrupt instead of
the dummy trasmit. This is important since the TX interrupt will be too early sometimes, before
the RX BD has closed. There is one case where the RX irq is before the TX irq, if iic_mrblr is set
to match the number of bytes to read. Therefore must the iic_mrblr be one byte larger than
the expected number of bytes.
- busy wait for small transfers since it's faster.
- save_flags(flags); cli(); cleanups
- interruptible_sleep_on_timeout() instead of interruptible_sleep_on() so it won't hang forever if an
irq is lost.
Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Joakim Tjernlund
0 siblings, 0 replies; 43+ messages in thread
From: Joakim Tjernlund @ 2005-05-19 6:23 UTC (permalink / raw)
To: Tom Rini; +Cc: linuxppc-embedded, sensors
> >
> > Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
>
> Can you please split this into logical chunks, or give me a list of each
> fix in here? Thanks.
ohh, kind of hard to remember all that went into that patch. The path
has evoled over many days, but I can try summarize. I have tested this code
pretty well it does not fail for me. Speed has been between 10-150KHz. The
old code fails as soon you start to stress it a little.
- replace invalidate_dcache_range with flush_dcache_range, since buffers are
NOT cache aligned. flush will write to memory AND invalidate the cache.
- move the chip errata stuff from irq routine into read/write routines. Made
it default off since it causes lock ups on my I2C device. I think it causes
a too short STOP condition. If enabled I2C will behave better than before, but
may still cause problems if the read/write is interrupted with a signal while
microcode is enabled.
- set default speed to 60 KHz instead.
- missing/faulty initialization of parameter ram when I2C micro patch is active.
- replaced assingments with mask operations with relevant bits. Example:
/* Shut down IIC. */
i2c->i2c_i2mod = 0;
i2c->i2c_i2mod &= ~1;
- When reading from I2C device, let the receive BD generate interrupt instead of
the dummy trasmit. This is important since the TX interrupt will be too early sometimes, before
the RX BD has closed. There is one case where the RX irq is before the TX irq, if iic_mrblr is set
to match the number of bytes to read. Therefore must the iic_mrblr be one byte larger than
the expected number of bytes.
- busy wait for small transfers since it's faster.
- save_flags(flags); cli(); cleanups
- interruptible_sleep_on_timeout() instead of interruptible_sleep_on() so it won't hang forever if an
irq is lost.
Jocke
^ permalink raw reply [flat|nested] 43+ messages in thread* RE: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
(?)
@ 2002-11-01 11:01 ` Joakim Tjernlund
2002-11-01 19:19 ` Tom Rini
-1 siblings, 1 reply; 43+ messages in thread
From: Joakim Tjernlund @ 2002-11-01 11:01 UTC (permalink / raw)
To: Tom Rini; +Cc: linuxppc-embedded, sensors
Hi Tom
Will you apply this patch? No problems reported so far.
Jocke
> > >
> > > Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
> >
> > Can you please split this into logical chunks, or give me a list of each
> > fix in here? Thanks.
>
> ohh, kind of hard to remember all that went into that patch. The path
> has evoled over many days, but I can try summarize. I have tested this code
> pretty well it does not fail for me. Speed has been between 10-150KHz. The
> old code fails as soon you start to stress it a little.
>
> - replace invalidate_dcache_range with flush_dcache_range, since buffers are
> NOT cache aligned. flush will write to memory AND invalidate the cache.
>
> - move the chip errata stuff from irq routine into read/write routines. Made
> it default off since it causes lock ups on my I2C device. I think it causes
> a too short STOP condition. If enabled I2C will behave better than before, but
> may still cause problems if the read/write is interrupted with a signal while
> microcode is enabled.
>
> - set default speed to 60 KHz instead.
>
> - missing/faulty initialization of parameter ram when I2C micro patch is active.
>
> - replaced assingments with mask operations with relevant bits. Example:
> /* Shut down IIC. */
> i2c->i2c_i2mod = 0;
> i2c->i2c_i2mod &= ~1;
>
> - When reading from I2C device, let the receive BD generate interrupt instead of
> the dummy trasmit. This is important since the TX interrupt will be too early sometimes, before
> the RX BD has closed. There is one case where the RX irq is before the TX irq, if iic_mrblr is set
> to match the number of bytes to read. Therefore must the iic_mrblr be one byte larger than
> the expected number of bytes.
>
> - busy wait for small transfers since it's faster.
>
> - save_flags(flags); cli(); cleanups
>
> - interruptible_sleep_on_timeout() instead of interruptible_sleep_on() so it won't hang forever if an
> irq is lost.
>
> Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
@ 2005-05-19 6:23 ` Mark D. Studebaker
-1 siblings, 0 replies; 43+ messages in thread
From: Mark D. Studebaker @ 2002-11-17 20:51 UTC (permalink / raw)
To: joakim.tjernlund; +Cc: Tom Rini, linuxppc-embedded, sensors
Tom + Joakim,
we're doing a release soon over here at sensors/i2c,
do you want this checked in as-is, with mods, or not at all?
Joakim Tjernlund wrote:
>
> > >
> > > Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
> >
> > Can you please split this into logical chunks, or give me a list of each
> > fix in here? Thanks.
>
> ohh, kind of hard to remember all that went into that patch. The path
> has evoled over many days, but I can try summarize. I have tested this code
> pretty well it does not fail for me. Speed has been between 10-150KHz. The
> old code fails as soon you start to stress it a little.
>
> - replace invalidate_dcache_range with flush_dcache_range, since buffers are
> NOT cache aligned. flush will write to memory AND invalidate the cache.
>
> - move the chip errata stuff from irq routine into read/write routines. Made
> it default off since it causes lock ups on my I2C device. I think it causes
> a too short STOP condition. If enabled I2C will behave better than before, but
> may still cause problems if the read/write is interrupted with a signal while
> microcode is enabled.
>
> - set default speed to 60 KHz instead.
>
> - missing/faulty initialization of parameter ram when I2C micro patch is active.
>
> - replaced assingments with mask operations with relevant bits. Example:
> /* Shut down IIC. */
> i2c->i2c_i2mod = 0;
> i2c->i2c_i2mod &= ~1;
>
> - When reading from I2C device, let the receive BD generate interrupt instead of
> the dummy trasmit. This is important since the TX interrupt will be too early sometimes, before
> the RX BD has closed. There is one case where the RX irq is before the TX irq, if iic_mrblr is set
> to match the number of bytes to read. Therefore must the iic_mrblr be one byte larger than
> the expected number of bytes.
>
> - busy wait for small transfers since it's faster.
>
> - save_flags(flags); cli(); cleanups
>
> - interruptible_sleep_on_timeout() instead of interruptible_sleep_on() so it won't hang forever if an
> irq is lost.
>
> Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread
* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Mark D. Studebaker
0 siblings, 0 replies; 43+ messages in thread
From: Mark D. Studebaker @ 2005-05-19 6:23 UTC (permalink / raw)
To: joakim.tjernlund; +Cc: Tom Rini, linuxppc-embedded, sensors
Tom + Joakim,
we're doing a release soon over here at sensors/i2c,
do you want this checked in as-is, with mods, or not at all?
Joakim Tjernlund wrote:
>
> > >
> > > Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
> >
> > Can you please split this into logical chunks, or give me a list of each
> > fix in here? Thanks.
>
> ohh, kind of hard to remember all that went into that patch. The path
> has evoled over many days, but I can try summarize. I have tested this code
> pretty well it does not fail for me. Speed has been between 10-150KHz. The
> old code fails as soon you start to stress it a little.
>
> - replace invalidate_dcache_range with flush_dcache_range, since buffers are
> NOT cache aligned. flush will write to memory AND invalidate the cache.
>
> - move the chip errata stuff from irq routine into read/write routines. Made
> it default off since it causes lock ups on my I2C device. I think it causes
> a too short STOP condition. If enabled I2C will behave better than before, but
> may still cause problems if the read/write is interrupted with a signal while
> microcode is enabled.
>
> - set default speed to 60 KHz instead.
>
> - missing/faulty initialization of parameter ram when I2C micro patch is active.
>
> - replaced assingments with mask operations with relevant bits. Example:
> /* Shut down IIC. */
> i2c->i2c_i2mod = 0;
> i2c->i2c_i2mod &= ~1;
>
> - When reading from I2C device, let the receive BD generate interrupt instead of
> the dummy trasmit. This is important since the TX interrupt will be too early sometimes, before
> the RX BD has closed. There is one case where the RX irq is before the TX irq, if iic_mrblr is set
> to match the number of bytes to read. Therefore must the iic_mrblr be one byte larger than
> the expected number of bytes.
>
> - busy wait for small transfers since it's faster.
>
> - save_flags(flags); cli(); cleanups
>
> - interruptible_sleep_on_timeout() instead of interruptible_sleep_on() so it won't hang forever if an
> irq is lost.
>
> Jocke
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Mark D. Studebaker
(?)
@ 2002-11-17 21:44 ` Joakim Tjernlund
2005-05-19 6:23 ` Tom Rini
-1 siblings, 1 reply; 43+ messages in thread
From: Joakim Tjernlund @ 2002-11-17 21:44 UTC (permalink / raw)
To: Mark D. Studebaker; +Cc: Tom Rini, linuxppc-embedded, sensors
As-is for me. No problems reported to me.
Joakim
> Tom + Joakim,
> we're doing a release soon over here at sensors/i2c,
> do you want this checked in as-is, with mods, or not at all?
>
> Joakim Tjernlund wrote:
> >
> > > >
> > > > Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
> > >
> > > Can you please split this into logical chunks, or give me a list of each
> > > fix in here? Thanks.
> >
> > ohh, kind of hard to remember all that went into that patch. The path
> > has evoled over many days, but I can try summarize. I have tested this code
> > pretty well it does not fail for me. Speed has been between 10-150KHz. The
> > old code fails as soon you start to stress it a little.
> >
> > - replace invalidate_dcache_range with flush_dcache_range, since buffers are
> > NOT cache aligned. flush will write to memory AND invalidate the cache.
> >
> > - move the chip errata stuff from irq routine into read/write routines. Made
> > it default off since it causes lock ups on my I2C device. I think it causes
> > a too short STOP condition. If enabled I2C will behave better than before, but
> > may still cause problems if the read/write is interrupted with a signal while
> > microcode is enabled.
> >
> > - set default speed to 60 KHz instead.
> >
> > - missing/faulty initialization of parameter ram when I2C micro patch is active.
> >
> > - replaced assingments with mask operations with relevant bits. Example:
> > /* Shut down IIC. */
> > i2c->i2c_i2mod = 0;
> > i2c->i2c_i2mod &= ~1;
> >
> > - When reading from I2C device, let the receive BD generate interrupt instead of
> > the dummy trasmit. This is important since the TX interrupt will be too early sometimes, before
> > the RX BD has closed. There is one case where the RX irq is before the TX irq, if iic_mrblr is set
> > to match the number of bytes to read. Therefore must the iic_mrblr be one byte larger than
> > the expected number of bytes.
> >
> > - busy wait for small transfers since it's faster.
> >
> > - save_flags(flags); cli(); cleanups
> >
> > - interruptible_sleep_on_timeout() instead of interruptible_sleep_on() so it won't hang forever if an
> > irq is lost.
> >
> > Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: 8xx i2c refers to unspecified chip errata
2002-11-17 21:44 ` Joakim Tjernlund
@ 2005-05-19 6:23 ` Tom Rini
0 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2002-11-18 14:10 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Mark D. Studebaker, linuxppc-embedded, sensors
On Sun, Nov 17, 2002 at 10:44:40PM +0100, Joakim Tjernlund wrote:
> > Tom + Joakim,
> > we're doing a release soon over here at sensors/i2c,
> > do you want this checked in as-is, with mods, or not at all?
>
> As-is for me. No problems reported to me.
Works for me then.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread
* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Tom Rini
0 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2005-05-19 6:23 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Mark D. Studebaker, linuxppc-embedded, sensors
On Sun, Nov 17, 2002 at 10:44:40PM +0100, Joakim Tjernlund wrote:
> > Tom + Joakim,
> > we're doing a release soon over here at sensors/i2c,
> > do you want this checked in as-is, with mods, or not at all?
>
> As-is for me. No problems reported to me.
Works for me then.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Tom Rini
@ 2005-05-19 6:23 ` Mark D. Studebaker
-1 siblings, 0 replies; 43+ messages in thread
From: Mark D. Studebaker @ 2002-11-18 19:04 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Tom Rini, linuxppc-embedded, sensors
[-- Attachment #1: Type: text/plain, Size: 529 bytes --]
whatever your patch was against didn't match our tree very well. would
you please
resolve the differences and generate a new patch against our tree?
thanks
mds
Tom Rini wrote:
>
> On Sun, Nov 17, 2002 at 10:44:40PM +0100, Joakim Tjernlund wrote:
>
> > > Tom + Joakim,
> > > we're doing a release soon over here at sensors/i2c,
> > > do you want this checked in as-is, with mods, or not at all?
> >
> > As-is for me. No problems reported to me.
>
> Works for me then.
>
> --
> Tom Rini (TR1265)
> http://gate.crashing.org/~trini/
[-- Attachment #2: fail --]
[-- Type: text/plain, Size: 537 bytes --]
patching file i2c-algo-8xx.c
Hunk #1 FAILED at 7.
Hunk #2 FAILED at 27.
Hunk #3 succeeded at 74 with fuzz 2 (offset 14 lines).
Hunk #5 succeeded at 157 (offset 18 lines).
Hunk #6 FAILED at 177.
Hunk #8 succeeded at 220 (offset 18 lines).
Hunk #9 FAILED at 237.
Hunk #10 succeeded at 333 (offset 2 lines).
Hunk #11 FAILED at 343.
Hunk #12 FAILED at 359.
Hunk #13 succeeded at 439 (offset 18 lines).
Hunk #14 FAILED at 464.
Hunk #15 succeeded at 514 (offset 2 lines).
7 out of 15 hunks FAILED -- saving rejects to file i2c-algo-8xx.c.rej
^ permalink raw reply [flat|nested] 43+ messages in thread
* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Mark D. Studebaker
0 siblings, 0 replies; 43+ messages in thread
From: Mark D. Studebaker @ 2005-05-19 6:23 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Tom Rini, linuxppc-embedded, sensors
whatever your patch was against didn't match our tree very well. would
you please
resolve the differences and generate a new patch against our tree?
thanks
mds
Tom Rini wrote:
>
> On Sun, Nov 17, 2002 at 10:44:40PM +0100, Joakim Tjernlund wrote:
>
> > > Tom + Joakim,
> > > we're doing a release soon over here at sensors/i2c,
> > > do you want this checked in as-is, with mods, or not at all?
> >
> > As-is for me. No problems reported to me.
>
> Works for me then.
>
> --
> Tom Rini (TR1265)
> http://gate.crashing.org/~trini/
-------------- next part --------------
patching file i2c-algo-8xx.c
Hunk #1 FAILED at 7.
Hunk #2 FAILED at 27.
Hunk #3 succeeded at 74 with fuzz 2 (offset 14 lines).
Hunk #5 succeeded at 157 (offset 18 lines).
Hunk #6 FAILED at 177.
Hunk #8 succeeded at 220 (offset 18 lines).
Hunk #9 FAILED at 237.
Hunk #10 succeeded at 333 (offset 2 lines).
Hunk #11 FAILED at 343.
Hunk #12 FAILED at 359.
Hunk #13 succeeded at 439 (offset 18 lines).
Hunk #14 FAILED at 464.
Hunk #15 succeeded at 514 (offset 2 lines).
7 out of 15 hunks FAILED -- saving rejects to file i2c-algo-8xx.c.rej
^ permalink raw reply [flat|nested] 43+ messages in thread
* RE: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
@ 2005-05-19 6:23 ` Joakim Tjernlund
-1 siblings, 0 replies; 43+ messages in thread
From: Joakim Tjernlund @ 2002-11-18 19:24 UTC (permalink / raw)
To: Mark D. Studebaker; +Cc: Tom Rini, linuxppc-embedded, sensors
> whatever your patch was against didn't match our tree very well. would
> you please
> resolve the differences and generate a new patch against our tree?
> thanks
> mds
Patch was(and still is, I think) against linuxppc_2_4_devel. Don't know your tree, is
it not the same as linuxppc? Anyhow, too much time has passed for me
to remember all details and I don't have the time to go back and do it all over again.
I suggest you take the linuxppc version, patch it and adopt it to your tree.
Regards
Jocke
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Joakim Tjernlund
0 siblings, 0 replies; 43+ messages in thread
From: Joakim Tjernlund @ 2005-05-19 6:23 UTC (permalink / raw)
To: Mark D. Studebaker; +Cc: Tom Rini, linuxppc-embedded, sensors
> whatever your patch was against didn't match our tree very well. would
> you please
> resolve the differences and generate a new patch against our tree?
> thanks
> mds
Patch was(and still is, I think) against linuxppc_2_4_devel. Don't know your tree, is
it not the same as linuxppc? Anyhow, too much time has passed for me
to remember all details and I don't have the time to go back and do it all over again.
I suggest you take the linuxppc version, patch it and adopt it to your tree.
Regards
Jocke
^ permalink raw reply [flat|nested] 43+ messages in thread* Re: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
@ 2005-05-19 6:23 ` Tom Rini
-1 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2002-11-18 19:31 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Mark D. Studebaker, linuxppc-embedded, sensors
On Mon, Nov 18, 2002 at 08:24:32PM +0100, Joakim Tjernlund wrote:
> > whatever your patch was against didn't match our tree very well. would
> > you please
> > resolve the differences and generate a new patch against our tree?
> > thanks
> > mds
>
> Patch was(and still is, I think) against linuxppc_2_4_devel. Don't know your tree, is
> it not the same as linuxppc? Anyhow, too much time has passed for me
> to remember all details and I don't have the time to go back and do it all over again.
> I suggest you take the linuxppc version, patch it and adopt it to your tree.
I'll go create a proper patch vs the i2c tree later today.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread
* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Tom Rini
0 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2005-05-19 6:23 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Mark D. Studebaker, linuxppc-embedded, sensors
On Mon, Nov 18, 2002 at 08:24:32PM +0100, Joakim Tjernlund wrote:
> > whatever your patch was against didn't match our tree very well. would
> > you please
> > resolve the differences and generate a new patch against our tree?
> > thanks
> > mds
>
> Patch was(and still is, I think) against linuxppc_2_4_devel. Don't know your tree, is
> it not the same as linuxppc? Anyhow, too much time has passed for me
> to remember all details and I don't have the time to go back and do it all over again.
> I suggest you take the linuxppc version, patch it and adopt it to your tree.
I'll go create a proper patch vs the i2c tree later today.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
@ 2005-05-19 6:23 ` Jean Delvare
-1 siblings, 0 replies; 43+ messages in thread
From: Jean Delvare @ 2002-11-18 19:42 UTC (permalink / raw)
To: joakim.tjernlund; +Cc: mds, trini, linuxppc-embedded, sensors
> Patch was(and still is, I think) against linuxppc_2_4_devel. Don't
> know your tree, is it not the same as linuxppc? Anyhow, too much time
> has passed for me to remember all details and I don't have the time to
> go back and do it all over again. I suggest you take the linuxppc
> version, patch it and adopt it to your tree.
Why the hell are there two different trees? :'( Can't we work all
together for a better result?
--
Jean Delvare
http://www.ensicaen.ismra.fr/~delvare/
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread
* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Jean Delvare
0 siblings, 0 replies; 43+ messages in thread
From: Jean Delvare @ 2005-05-19 6:23 UTC (permalink / raw)
To: joakim.tjernlund; +Cc: mds, trini, linuxppc-embedded, sensors
> Patch was(and still is, I think) against linuxppc_2_4_devel. Don't
> know your tree, is it not the same as linuxppc? Anyhow, too much time
> has passed for me to remember all details and I don't have the time to
> go back and do it all over again. I suggest you take the linuxppc
> version, patch it and adopt it to your tree.
Why the hell are there two different trees? :'( Can't we work all
together for a better result?
--
Jean Delvare
http://www.ensicaen.ismra.fr/~delvare/
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Jean Delvare
@ 2005-05-19 6:23 ` Tom Rini
-1 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2002-11-18 19:46 UTC (permalink / raw)
To: Jean Delvare; +Cc: joakim.tjernlund, mds, linuxppc-embedded, sensors
On Mon, Nov 18, 2002 at 08:42:48PM +0100, Jean Delvare wrote:
>
> > Patch was(and still is, I think) against linuxppc_2_4_devel. Don't
> > know your tree, is it not the same as linuxppc? Anyhow, too much time
> > has passed for me to remember all details and I don't have the time to
> > go back and do it all over again. I suggest you take the linuxppc
> > version, patch it and adopt it to your tree.
>
> Why the hell are there two different trees? :'( Can't we work all
> together for a better result?
Because the linuxppc tree doesn't track the whole i2c tree, as that would
be quite silly. :)
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
^ permalink raw reply [flat|nested] 43+ messages in thread
* 8xx i2c refers to unspecified chip errata
@ 2005-05-19 6:23 ` Tom Rini
0 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2005-05-19 6:23 UTC (permalink / raw)
To: Jean Delvare; +Cc: joakim.tjernlund, mds, linuxppc-embedded, sensors
On Mon, Nov 18, 2002 at 08:42:48PM +0100, Jean Delvare wrote:
>
> > Patch was(and still is, I think) against linuxppc_2_4_devel. Don't
> > know your tree, is it not the same as linuxppc? Anyhow, too much time
> > has passed for me to remember all details and I don't have the time to
> > go back and do it all over again. I suggest you take the linuxppc
> > version, patch it and adopt it to your tree.
>
> Why the hell are there two different trees? :'( Can't we work all
> together for a better result?
Because the linuxppc tree doesn't track the whole i2c tree, as that would
be quite silly. :)
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
^ permalink raw reply [flat|nested] 43+ messages in thread
* 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
(?)
(?)
@ 2005-05-19 6:23 ` Joakim Tjernlund
-1 siblings, 0 replies; 43+ messages in thread
From: Joakim Tjernlund @ 2005-05-19 6:23 UTC (permalink / raw)
To: lm-sensors
Hmm, seems like this didn't make it to the embbedded list. Resending
Jocke
>
> On Fri, Oct 11, 2002 at 11:12:02AM +0200, Joakim Tjernlund wrote:
>
> > OK, here it is.
> >
> > Perhaps someone can add it to the ppctree?
>
> If you can submit this as a patch vs what's in the i2c CVS tree or the
> ppctree, than yes, this can be committed there, and to the ppctrees.
>
> --
> Tom Rini (TR1265)
> http://gate.crashing.org/~trini/
>
> ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Here is a patch against the PPC 2.4 devel tree for the i2c-algo-8xx.c
Tom, do you look after 8xx_io/enet.c? I sent a patch to the emmbedded list
yesterday that does away with an expensive memcpy.
Jocke
--- i2c-algo-8xx.c Mon Sep 30 16:20:42 2002
+++ i2c-algo-8xx.c.clean Tue Oct 22 10:49:33 2002
@@ -7,15 +7,12 @@
* Brad Parker (brad@heeltoe.com)
*/
-// XXX todo
-// timeout sleep?
-
/* $Id$ */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/version.h>
#include <linux/init.h>
#include <asm/uaccess.h>
@@ -30,25 +27,25 @@
#include <linux/i2c-algo-8xx.h>
#define CPM_MAX_READ 513
-
+/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */
static wait_queue_head_t iic_wait;
static ushort r_tbase, r_rbase;
int cpm_scan = 0;
-int cpm_debug = 1;
+int cpm_debug = 0;
-static void
-cpm_iic_interrupt(void *dev_id)
+static void
+cpm_iic_interrupt(void *dev_id, struct pt_regs *regs)
{
volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id;
-
if (cpm_debug > 1)
printk("cpm_iic_interrupt(dev_id=%p)\n", dev_id);
-
- /* Chip errata, clear enable.
- */
- i2c->i2c_i2mod = 0;
-
+#if 0
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs */
+ /* This should probably be removed and replaced by I2C_CHIP_ERRATA stuff */
+ /* Someone with a buggy CPU needs to confirm that */
+ i2c->i2c_i2mod &= ~1;
+#endif
/* Clear interrupt.
*/
i2c->i2c_i2cer = 0xff;
@@ -63,6 +60,8 @@
{
volatile iic_t *iip = cpm_adap->iip;
volatile i2c8xx_t *i2c = cpm_adap->i2c;
+ unsigned char brg;
+ bd_t *bd = (bd_t *)__res;
if (cpm_debug) printk("cpm_iic_init()\n");
@@ -101,15 +100,24 @@
cp->cp_cpcr mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
while (cp->cp_cpcr & CPM_CR_FLG);
+ } else {
+ iip->iic_rbptr = iip->iic_rbase;
+ iip->iic_tbptr = iip->iic_tbase;
+ iip->iic_rstate = 0;
+ iip->iic_tstate = 0;
}
/* Select an arbitrary address. Just make sure it is unique.
*/
- i2c->i2c_i2add = 0x34;
+ i2c->i2c_i2add = 0xfe;
- /* Make clock run maximum slow.
+ /* Make clock run at 60 KHz.
*/
- i2c->i2c_i2brg = 7;
+ brg = (unsigned char) (bd->bi_intfreq/(32*2*60000) -3);
+ i2c->i2c_i2brg = brg;
+
+ i2c->i2c_i2mod = 0x00;
+ i2c->i2c_i2com = 0x01; /* Master mode */
/* Disable interrupts.
*/
@@ -131,7 +139,7 @@
/* Shut down IIC.
*/
- i2c->i2c_i2mod = 0;
+ i2c->i2c_i2mod &= ~1;
i2c->i2c_i2cmr = 0;
i2c->i2c_i2cer = 0xff;
@@ -151,22 +159,24 @@
iip->iic_rstate = 0;
iip->iic_rdp = 0;
- iip->iic_rbptr = 0;
+ iip->iic_rbptr = iip->iic_rbase;
iip->iic_rbc = 0;
iip->iic_rxtmp = 0;
iip->iic_tstate = 0;
iip->iic_tdp = 0;
- iip->iic_tbptr = 0;
+ iip->iic_tbptr = iip->iic_tbase;
iip->iic_tbc = 0;
iip->iic_txtmp = 0;
}
#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */
+#define BD_SC_OV ((ushort)0x0002) /* OV - receive overrun */
#define CPM_CR_CLOSE_RXBD ((ushort)0x0007)
static void force_close(struct i2c_algo_8xx_data *cpm)
{
- if (cpm->reloc = 0) {
+ volatile i2c8xx_t *i2c = cpm->i2c;
+ if (cpm->reloc = 0) { /* micro code disabled */
volatile cpm8xx_t *cp = cpm->cp;
if (cpm_debug) printk("force_close()\n");
@@ -176,6 +186,8 @@
while (cp->cp_cpcr & CPM_CR_FLG);
}
+ i2c->i2c_i2cmr = 0x00; /* Disable all interrupts */
+ i2c->i2c_i2cer = 0xff;
}
@@ -190,7 +202,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf, *rbdf;
u_char *tb;
- unsigned long flags;
+ unsigned long flags, tmo;
if (count >= CPM_MAX_READ)
return -EINVAL;
@@ -207,68 +219,104 @@
* All that is used is the first byte for address, the remainder
* is just used for timing (and doesn't really have to exist).
*/
- if (cpm->reloc) {
- cpm_reset_iic_params(iip);
- }
tb = cpm->temp;
tb = (u_char *)(((uint)tb + 15) & ~15);
tb[0] = abyte; /* Device address byte w/rw flag */
- flush_dcache_range(tb, tb+1);
-
+ flush_dcache_range((unsigned long)tb, (unsigned long)(tb+1));
if (cpm_debug) printk("cpm_iic_read(abyte=0x%x)\n", abyte);
tbdf->cbd_bufaddr = __pa(tb);
tbdf->cbd_datlen = count + 1;
tbdf->cbd_sc - BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
+ BD_SC_READY | BD_SC_LAST |
BD_SC_WRAP | BD_IIC_START;
+ iip->iic_mrblr = count +1; /* prevent excessive read, +1
+ is needed otherwise will the
+ RXB interrupt come too early */
+
+ /* flush will invalidate too. */
+ flush_dcache_range((unsigned long)buf, (unsigned long)(buf+count));
+
rbdf->cbd_datlen = 0;
rbdf->cbd_bufaddr = __pa(buf);
- rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
-
- /* Chip bug, set enable here */
- save_flags(flags); cli();
- i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
- i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT;
+ if(count > 16){
+ /* Chip bug, set enable here */
+ local_irq_save(flags);
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+
+ /* Wait for IIC transfer */
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
+ local_irq_restore(flags);
+ } else { /* busy wait for small transfers, its faster */
+ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+ tmo = jiffies + 1*HZ;
+ while(!(i2c->i2c_i2cer & 0x11 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */
+ }
- /* Wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
- restore_flags(flags);
- if (signal_pending(current))
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug)
+ printk("IIC read: timeout!\n");
return -EIO;
-
+ }
+#ifdef I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
if (cpm_debug) {
printk("tx sc %04x, rx sc %04x\n",
tbdf->cbd_sc, rbdf->cbd_sc);
}
+ if (tbdf->cbd_sc & BD_SC_READY) {
+ printk("IIC read; complete but tbuf ready\n");
+ force_close(cpm);
+ printk("tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+
if (tbdf->cbd_sc & BD_SC_NAK) {
- printk("IIC read; no ack\n");
- return 0;
+ if (cpm_debug)
+ printk("IIC read; no ack\n");
+ return -EREMOTEIO;
}
if (rbdf->cbd_sc & BD_SC_EMPTY) {
- printk("IIC read; complete but rbuf empty\n");
- force_close(cpm);
- printk("tx sc %04x, rx sc %04x\n",
- tbdf->cbd_sc, rbdf->cbd_sc);
+ /* force_close(cpm); */
+ if (cpm_debug){
+ printk("IIC read; complete but rbuf empty\n");
+ printk("tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+ return -EREMOTEIO;
+ }
+
+ if (rbdf->cbd_sc & BD_SC_OV) {
+ if (cpm_debug)
+ printk("IIC read; Overrun\n");
+ return -EREMOTEIO;;
}
if (cpm_debug) printk("read %d bytes\n", rbdf->cbd_datlen);
if (rbdf->cbd_datlen < count) {
- printk("IIC read; short, wanted %d got %d\n",
- count, rbdf->cbd_datlen);
+ if (cpm_debug)
+ printk("IIC read; short, wanted %d got %d\n",
+ count, rbdf->cbd_datlen);
return 0;
}
-
- invalidate_dcache_range(buf, buf+count);
-
return count;
}
@@ -283,7 +331,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf;
u_char *tb;
- unsigned long flags;
+ unsigned long flags, tmo;
/* check for and use a microcode relocation patch */
if (cpm->reloc) {
@@ -293,8 +341,8 @@
tb = (u_char *)(((uint)tb + 15) & ~15);
*tb = abyte; /* Device address byte w/rw flag */
- flush_dcache_range(tb, tb+1);
- flush_dcache_range(buf, buf+count);
+ flush_dcache_range((unsigned long)tb, (unsigned long)(tb+1));
+ flush_dcache_range((unsigned long)buf, (unsigned long)(buf+count));
if (cpm_debug) printk("cpm_iic_write(abyte=0x%x)\n", abyte);
@@ -309,31 +357,53 @@
tbdf[1].cbd_datlen = count;
tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP;
- /* Chip bug, set enable here */
- save_flags(flags); cli();
- i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
- i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ if(count > 16){
+ /* Chip bug, set enable here */
+ local_irq_save(flags);
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+
+ /* Wait for IIC transfer */
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
+ local_irq_restore(flags);
+ } else { /* busy wait for small transfers, its faster */
+ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+ tmo = jiffies + 1*HZ;
+ while(!(i2c->i2c_i2cer & 0x12 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */
+ }
- /* Wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
- restore_flags(flags);
- if (signal_pending(current))
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug && !tmo)
+ printk("IIC write: timeout!\n");
return -EIO;
-
+ }
+
+#if I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
if (cpm_debug) {
printk("tx0 sc %04x, tx1 sc %04x\n",
tbdf[0].cbd_sc, tbdf[1].cbd_sc);
}
if (tbdf->cbd_sc & BD_SC_NAK) {
- printk("IIC write; no ack\n");
+ if (cpm_debug)
+ printk("IIC write; no ack\n");
return 0;
}
if (tbdf->cbd_sc & BD_SC_READY) {
- printk("IIC write; complete but tbuf ready\n");
+ if (cpm_debug)
+ printk("IIC write; complete but tbuf ready\n");
return 0;
}
@@ -351,7 +421,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf, *rbdf;
u_char *tb;
- unsigned long flags, len;
+ unsigned long flags, len, tmo;
if (cpm_debug > 1)
printk("cpm_iic_tryaddress(cpm=%p,addr=%d)\n", cpm, addr);
@@ -376,31 +446,43 @@
tb[0] = (addr << 1) | 1; /* device address (+ read) */
len = 2;
- flush_dcache_range(tb, tb+1);
+ flush_dcache_range((unsigned long)tb, (unsigned long)(tb+2));
tbdf->cbd_bufaddr = __pa(tb);
tbdf->cbd_datlen = len;
tbdf->cbd_sc - BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
+ BD_SC_READY | BD_SC_LAST |
BD_SC_WRAP | BD_IIC_START;
rbdf->cbd_datlen = 0;
rbdf->cbd_bufaddr = __pa(tb+2);
- rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;
- save_flags(flags); cli();
+ local_irq_save(flags);
i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
if (cpm_debug > 1) printk("about to sleep\n");
/* wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
- restore_flags(flags);
- if (signal_pending(current))
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
+ local_irq_restore(flags);
+
+#ifdef I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
+
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug && !tmo)
+ printk("IIC tryaddress: timeout!\n");
return -EIO;
+ }
if (cpm_debug > 1) printk("back from sleep\n");
@@ -430,8 +512,8 @@
if (cpm_debug)
printk("i2c-algo-8xx.o: "
- "#%d addr=0x%x flags=0x%x len=%d\n",
- i, pmsg->addr, pmsg->flags, pmsg->len);
+ "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n",
+ i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf);
addr = pmsg->addr << 1;
if (pmsg->flags & I2C_M_RD )
^ permalink raw reply [flat|nested] 43+ messages in thread* 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
` (2 preceding siblings ...)
(?)
@ 2005-05-19 6:23 ` Mark D. Studebaker
-1 siblings, 0 replies; 43+ messages in thread
From: Mark D. Studebaker @ 2005-05-19 6:23 UTC (permalink / raw)
To: lm-sensors
committed.
thanks
Tom Rini wrote:
>
> On Mon, Nov 18, 2002 at 02:04:21PM -0500, Mark D. Studebaker wrote:
>
> > whatever your patch was against didn't match our tree very well. would
> > you please
> > resolve the differences and generate a new patch against our tree?
> > thanks
>
> Here's a patch vs current i2c CVS (HEAD, if that makes a difference),
> which brings things back into line.
>
> Let me know when you commit this, and I'll bring the linuxppc BK trees
> back into line.
>
^ permalink raw reply [flat|nested] 43+ messages in thread* 8xx i2c refers to unspecified chip errata
2005-05-19 6:23 ` Joakim Tjernlund
` (3 preceding siblings ...)
(?)
@ 2005-05-19 6:23 ` Tom Rini
-1 siblings, 0 replies; 43+ messages in thread
From: Tom Rini @ 2005-05-19 6:23 UTC (permalink / raw)
To: lm-sensors
On Mon, Nov 18, 2002 at 02:04:21PM -0500, Mark D. Studebaker wrote:
> whatever your patch was against didn't match our tree very well. would
> you please
> resolve the differences and generate a new patch against our tree?
> thanks
Here's a patch vs current i2c CVS (HEAD, if that makes a difference),
which brings things back into line.
Let me know when you commit this, and I'll bring the linuxppc BK trees
back into line.
--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/
Index: i2c-algo-8xx.c
=================================RCS file: /home/cvs/i2c/kernel/i2c-algo-8xx.c,v
retrieving revision 1.7
diff -u -r1.7 i2c-algo-8xx.c
--- i2c-algo-8xx.c 2002/08/03 22:48:18 1.7
+++ i2c-algo-8xx.c 2002/11/18 20:40:55
@@ -44,25 +44,25 @@
#include <linux/i2c-algo-8xx.h>
#define CPM_MAX_READ 513
-
+/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older CPU(earlier than rev D4) */
static wait_queue_head_t iic_wait;
static ushort r_tbase, r_rbase;
-int cpm_scan = 1;
+int cpm_scan = 0;
int cpm_debug = 0;
-static void
-cpm_iic_interrupt(void *dev_id, void *regs)
+static void
+cpm_iic_interrupt(void *dev_id, struct pt_regs *regs)
{
volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id;
-
if (cpm_debug > 1)
printk("cpm_iic_interrupt(dev_id=%p)\n", dev_id);
-
- /* Chip errata, clear enable.
- */
- i2c->i2c_i2mod = 0;
-
+#if 0
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs */
+ /* This should probably be removed and replaced by I2C_CHIP_ERRATA stuff */
+ /* Someone with a buggy CPU needs to confirm that */
+ i2c->i2c_i2mod &= ~1;
+#endif
/* Clear interrupt.
*/
i2c->i2c_i2cer = 0xff;
@@ -77,8 +77,10 @@
{
volatile iic_t *iip = cpm_adap->iip;
volatile i2c8xx_t *i2c = cpm_adap->i2c;
+ unsigned char brg;
+ bd_t *bd = (bd_t *)__res;
- if (cpm_debug) printk("cpm_iic_init() - iip=%p\n",iip);
+ if (cpm_debug) printk(KERN_DEBUG "cpm_iic_init()\n");
/* Initialize the parameter ram.
* We need to make sure many things are initialized to zero,
@@ -115,15 +117,24 @@
cp->cp_cpcr mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
while (cp->cp_cpcr & CPM_CR_FLG);
+ } else {
+ iip->iic_rbptr = iip->iic_rbase;
+ iip->iic_tbptr = iip->iic_tbase;
+ iip->iic_rstate = 0;
+ iip->iic_tstate = 0;
}
/* Select an arbitrary address. Just make sure it is unique.
*/
- i2c->i2c_i2add = 0x34;
+ i2c->i2c_i2add = 0xfe;
- /* Make clock run maximum slow.
+ /* Make clock run at 60 KHz.
*/
- i2c->i2c_i2brg = 7;
+ brg = (unsigned char) (bd->bi_intfreq/(32*2*60000) -3);
+ i2c->i2c_i2brg = brg;
+
+ i2c->i2c_i2mod = 0x00;
+ i2c->i2c_i2com = 0x01; /* Master mode */
/* Disable interrupts.
*/
@@ -149,7 +160,7 @@
/* Shut down IIC.
*/
- i2c->i2c_i2mod = 0;
+ i2c->i2c_i2mod &= ~1;
i2c->i2c_i2cmr = 0;
i2c->i2c_i2cer = 0xff;
@@ -169,22 +180,24 @@
iip->iic_rstate = 0;
iip->iic_rdp = 0;
- iip->iic_rbptr = r_rbase;
+ iip->iic_rbptr = iip->iic_rbase;
iip->iic_rbc = 0;
iip->iic_rxtmp = 0;
iip->iic_tstate = 0;
iip->iic_tdp = 0;
- iip->iic_tbptr = r_tbase;
+ iip->iic_tbptr = iip->iic_tbase;
iip->iic_tbc = 0;
iip->iic_txtmp = 0;
}
#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */
+#define BD_SC_OV ((ushort)0x0002) /* OV - receive overrun */
#define CPM_CR_CLOSE_RXBD ((ushort)0x0007)
static void force_close(struct i2c_algo_8xx_data *cpm)
{
- if (cpm->reloc = 0) {
+ volatile i2c8xx_t *i2c = cpm->i2c;
+ if (cpm->reloc = 0) { /* micro code disabled */
volatile cpm8xx_t *cp = cpm->cp;
if (cpm_debug) printk("force_close()\n");
@@ -194,6 +207,8 @@
while (cp->cp_cpcr & CPM_CR_FLG);
}
+ i2c->i2c_i2cmr = 0x00; /* Disable all interrupts */
+ i2c->i2c_i2cer = 0xff;
}
@@ -208,7 +223,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf, *rbdf;
u_char *tb;
- unsigned long flags;
+ unsigned long flags, tmo;
if (count >= CPM_MAX_READ)
return -EINVAL;
@@ -225,9 +240,6 @@
* All that is used is the first byte for address, the remainder
* is just used for timing (and doesn't really have to exist).
*/
- if (cpm->reloc) {
- cpm_reset_iic_params(iip);
- }
tb = cpm->temp;
tb = (u_char *)(((uint)tb + 15) & ~15);
tb[0] = abyte; /* Device address byte w/rw flag */
@@ -239,56 +251,94 @@
tbdf->cbd_bufaddr = __pa(tb);
tbdf->cbd_datlen = count + 1;
tbdf->cbd_sc - BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
+ BD_SC_READY | BD_SC_LAST |
BD_SC_WRAP | BD_IIC_START;
- rbdf->cbd_datlen = 0;
- rbdf->cbd_bufaddr = __pa(buf);
- rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+ iip->iic_mrblr = count +1; /* prevent excessive read, +1
+ is needed otherwise will the
+ RXB interrupt come too early */
- invalidate_dcache_range((unsigned long) buf, (unsigned long) (buf+count));
+ /* flush will invalidate too. */
+ flush_dcache_range((unsigned long) buf, (unsigned long) (buf+count));
- /* Chip bug, set enable here */
- local_irq_save(flags);
- i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
- i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ rbdf->cbd_datlen = 0;
+ rbdf->cbd_bufaddr = __pa(buf);
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT;
+ if(count > 16){
+ /* Chip bug, set enable here */
+ local_irq_save(flags);
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+
+ /* Wait for IIC transfer */
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
+ local_irq_restore(flags);
+ } else { /* busy wait for small transfers, its faster */
+ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+ tmo = jiffies + 1*HZ;
+ while(!(i2c->i2c_i2cer & 0x11 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */
+ }
- /* Wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
- local_irq_restore(flags);
- if (signal_pending(current))
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug)
+ printk("IIC read: timeout!\n");
return -EIO;
-
+ }
+#ifdef I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
if (cpm_debug) {
printk("tx sc %04x, rx sc %04x\n",
tbdf->cbd_sc, rbdf->cbd_sc);
}
+ if (tbdf->cbd_sc & BD_SC_READY) {
+ printk("IIC read; complete but tbuf ready\n");
+ force_close(cpm);
+ printk("tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+
if (tbdf->cbd_sc & BD_SC_NAK) {
- printk("IIC read; no ack\n");
- return 0;
+ if (cpm_debug)
+ printk("IIC read; no ack\n");
+ return -EREMOTEIO;
}
if (rbdf->cbd_sc & BD_SC_EMPTY) {
- printk("IIC read; complete but rbuf empty\n");
- force_close(cpm);
- printk("tx sc %04x, rx sc %04x\n",
- tbdf->cbd_sc, rbdf->cbd_sc);
+ /* force_close(cpm); */
+ if (cpm_debug){
+ printk("IIC read; complete but rbuf empty\n");
+ printk("tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+ return -EREMOTEIO;
}
+ if (rbdf->cbd_sc & BD_SC_OV) {
+ if (cpm_debug)
+ printk("IIC read; Overrun\n");
+ return -EREMOTEIO;;
+ }
+
if (cpm_debug) printk("read %d bytes\n", rbdf->cbd_datlen);
if (rbdf->cbd_datlen < count) {
- printk("IIC read; short, wanted %d got %d\n",
- count, rbdf->cbd_datlen);
+ if (cpm_debug)
+ printk("IIC read; short, wanted %d got %d\n",
+ count, rbdf->cbd_datlen);
return 0;
}
-
- invalidate_dcache_range((unsigned long) buf, (unsigned long) (buf+count));
-
return count;
}
@@ -303,7 +353,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf;
u_char *tb;
- unsigned long flags;
+ unsigned long flags, tmo;
/* check for and use a microcode relocation patch */
if (cpm->reloc) {
@@ -329,31 +379,53 @@
tbdf[1].cbd_datlen = count;
tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP;
- /* Chip bug, set enable here */
- local_irq_save(flags);
- i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
- i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ if(count > 16){
+ /* Chip bug, set enable here */
+ local_irq_save(flags);
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+
+ /* Wait for IIC transfer */
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
+ local_irq_restore(flags);
+ } else { /* busy wait for small transfers, its faster */
+ i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
+ tmo = jiffies + 1*HZ;
+ while(!(i2c->i2c_i2cer & 0x12 || time_after(jiffies, tmo))); /* Busy wait, with a timeout */
+ }
- /* Wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
- local_irq_restore(flags);
- if (signal_pending(current))
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug && !tmo)
+ printk("IIC write: timeout!\n");
return -EIO;
-
+ }
+
+#if I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
if (cpm_debug) {
printk("tx0 sc %04x, tx1 sc %04x\n",
tbdf[0].cbd_sc, tbdf[1].cbd_sc);
}
if (tbdf->cbd_sc & BD_SC_NAK) {
- printk("IIC write; no ack\n");
+ if (cpm_debug)
+ printk("IIC write; no ack\n");
return 0;
}
if (tbdf->cbd_sc & BD_SC_READY) {
- printk("IIC write; complete but tbuf ready\n");
+ if (cpm_debug)
+ printk("IIC write; complete but tbuf ready\n");
return 0;
}
@@ -371,7 +443,7 @@
volatile cpm8xx_t *cp = cpm->cp;
volatile cbd_t *tbdf, *rbdf;
u_char *tb;
- unsigned long flags, len;
+ unsigned long flags, len, tmo;
if (cpm_debug > 1)
printk("cpm_iic_tryaddress(cpm=%p,addr=%d)\n", cpm, addr);
@@ -396,31 +468,43 @@
tb[0] = (addr << 1) | 1; /* device address (+ read) */
len = 2;
- flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1));
+ flush_dcache_range((unsigned long) tb, (unsigned long) (tb+2));
tbdf->cbd_bufaddr = __pa(tb);
tbdf->cbd_datlen = len;
tbdf->cbd_sc - BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
+ BD_SC_READY | BD_SC_LAST |
BD_SC_WRAP | BD_IIC_START;
rbdf->cbd_datlen = 0;
rbdf->cbd_bufaddr = __pa(tb+2);
- rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT;
local_irq_save(flags);
i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
i2c->i2c_i2cer = 0xff;
- i2c->i2c_i2mod = 1; /* Enable */
- i2c->i2c_i2com = 0x81; /* Start master */
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com |= 0x80; /* Begin transmission */
if (cpm_debug > 1) printk("about to sleep\n");
/* wait for IIC transfer */
- interruptible_sleep_on(&iic_wait);
+ tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ);
local_irq_restore(flags);
- if (signal_pending(current))
+
+#ifdef I2C_CHIP_ERRATA
+ /* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+ Disabling I2C too early may cause too short stop condition */
+ udelay(4);
+ i2c->i2c_i2mod &= ~1;
+#endif
+
+ if (signal_pending(current) || !tmo){
+ force_close(cpm);
+ if(cpm_debug && !tmo)
+ printk("IIC tryaddress: timeout!\n");
return -EIO;
+ }
if (cpm_debug > 1) printk("back from sleep\n");
@@ -450,8 +534,8 @@
if (cpm_debug)
printk("i2c-algo-8xx.o: "
- "#%d addr=0x%x flags=0x%x len=%d\n",
- i, pmsg->addr, pmsg->flags, pmsg->len);
+ "#%d addr=0x%x flags=0x%x len=%d\n buf=%lx\n",
+ i, pmsg->addr, pmsg->flags, pmsg->len, (unsigned long)pmsg->buf);
addr = pmsg->addr << 1;
if (pmsg->flags & I2C_M_RD )
^ permalink raw reply [flat|nested] 43+ messages in thread