* MPC8xx CPM I2C interface driver
@ 2006-10-10 9:05 Norbert van Bolhuis
2006-10-10 9:25 ` Abdul Rahaman
2006-10-22 22:50 ` Vitaly Bordug
0 siblings, 2 replies; 6+ messages in thread
From: Norbert van Bolhuis @ 2006-10-10 9:05 UTC (permalink / raw)
To: linuxppc-embedded
Is there no MPC8xx CPM I2C interface driver in (latest) linux v2.6 or am I
mistaken ?
There's no code for CONFIG_I2C_ALGO8XX.
I've a MPC870 based board and I was hoping for a MPC8xx CPM I2C interface driver
to be there (allowing user applications to open and read/write /dev/i2c-0)
Thanks,
N.
--
This message has been scanned for viruses and is believed to be clean
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: MPC8xx CPM I2C interface driver
2006-10-10 9:05 Norbert van Bolhuis
@ 2006-10-10 9:25 ` Abdul Rahaman
2006-10-22 22:50 ` Vitaly Bordug
1 sibling, 0 replies; 6+ messages in thread
From: Abdul Rahaman @ 2006-10-10 9:25 UTC (permalink / raw)
To: Norbert van Bolhuis, linuxppc-embedded
Can somebody can provide me ramdisk iamge to me (initd.boot)
Or some clear procedure build my self.
Right now my kernel is booting but is not able come to application shell
stage.
Thanks
Rahaman
----- Original Message -----
From: "Norbert van Bolhuis" <nvbolhuis@aimsys.nl>
To: <linuxppc-embedded@ozlabs.org>
Sent: Tuesday, October 10, 2006 2:35 PM
Subject: MPC8xx CPM I2C interface driver
>
> Is there no MPC8xx CPM I2C interface driver in (latest) linux v2.6 or am I
> mistaken ?
> There's no code for CONFIG_I2C_ALGO8XX.
>
> I've a MPC870 based board and I was hoping for a MPC8xx CPM I2C interface
driver
> to be there (allowing user applications to open and read/write /dev/i2c-0)
>
> Thanks,
> N.
>
>
>
> --
> This message has been scanned for viruses and is believed to be clean
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: MPC8xx CPM I2C interface driver
@ 2006-10-10 9:26 Abdul Rahaman
0 siblings, 0 replies; 6+ messages in thread
From: Abdul Rahaman @ 2006-10-10 9:26 UTC (permalink / raw)
To: Norbert van Bolhuis, linuxppc-embedded
sorry I forgot to mention its MPC 8xx
Can somebody can provide me ramdisk iamge to me (initd.boot)
Or some clear procedure build my self.
Right now my kernel is booting but is not able come to application shell
stage.
Thanks
Rahaman
----- Original Message -----
From: "Abdul Rahaman" <abdul.rahaman@semindia.in>
To: "Norbert van Bolhuis" <nvbolhuis@aimsys.nl>;
<linuxppc-embedded@ozlabs.org>
Sent: Tuesday, October 10, 2006 2:55 PM
Subject: Re: MPC8xx CPM I2C interface driver
> Can somebody can provide me ramdisk iamge to me (initd.boot)
>
> Or some clear procedure build my self.
>
> Right now my kernel is booting but is not able come to application shell
> stage.
>
> Thanks
> Rahaman
> ----- Original Message -----
> From: "Norbert van Bolhuis" <nvbolhuis@aimsys.nl>
> To: <linuxppc-embedded@ozlabs.org>
> Sent: Tuesday, October 10, 2006 2:35 PM
> Subject: MPC8xx CPM I2C interface driver
>
>
> >
> > Is there no MPC8xx CPM I2C interface driver in (latest) linux v2.6 or am
I
> > mistaken ?
> > There's no code for CONFIG_I2C_ALGO8XX.
> >
> > I've a MPC870 based board and I was hoping for a MPC8xx CPM I2C
interface
> driver
> > to be there (allowing user applications to open and read/write
/dev/i2c-0)
> >
> > Thanks,
> > N.
> >
> >
> >
> > --
> > This message has been scanned for viruses and is believed to be clean
> >
> > _______________________________________________
> > Linuxppc-embedded mailing list
> > Linuxppc-embedded@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> >
> >
> >
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: MPC8xx CPM I2C interface driver
2006-10-10 9:05 Norbert van Bolhuis
2006-10-10 9:25 ` Abdul Rahaman
@ 2006-10-22 22:50 ` Vitaly Bordug
2006-10-23 20:17 ` Christopher Murch
2006-10-24 6:58 ` Norbert van Bolhuis
1 sibling, 2 replies; 6+ messages in thread
From: Vitaly Bordug @ 2006-10-22 22:50 UTC (permalink / raw)
To: Norbert van Bolhuis; +Cc: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 771 bytes --]
On Tue, 10 Oct 2006 11:05:49 +0200
Norbert van Bolhuis wrote:
>
> Is there no MPC8xx CPM I2C interface driver in (latest) linux v2.6 or
> am I mistaken ?
> There's no code for CONFIG_I2C_ALGO8XX.
The answer is - no, there is no stuff in the 2.6 kernel. I used to have the port from 2.4 a while ago (an
improvement to the patches posted here btw) but had no chance to cleanup it and push through lm_sensors.
>
> I've a MPC870 based board and I was hoping for a MPC8xx CPM I2C
> interface driver to be there (allowing user applications to open and
> read/write /dev/i2c-0)
>
You should be able to locate sources in this list's archives. Ping me once more if not, I'll try to dig it out of my HDD then...
> Thanks,
> N.
>
>
>
--
-Vitaly
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: MPC8xx CPM I2C interface driver
2006-10-22 22:50 ` Vitaly Bordug
@ 2006-10-23 20:17 ` Christopher Murch
2006-10-24 6:58 ` Norbert van Bolhuis
1 sibling, 0 replies; 6+ messages in thread
From: Christopher Murch @ 2006-10-23 20:17 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 731 bytes --]
Here's a simple driver that we wrote for 8xx i2c master-only usage. It
only supports the I2C_RDWR ioctl to send and receive reads/writes to
various devices.
To integrate the patch, it will be necessary to modify your
linux/drivers/i2c/Makefile to build in the i2c-cpm support.
We've used this driver successfully with LM77 temp sensors, DS1337 RTC
and some EEPROMs.
On Sun, 2006-10-22 at 18:50 -0400, Vitaly Bordug wrote:
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
> email message attachment
> > -------- Forwarded Message --------
> > Subject:
> > Date: Sun, 22 Oct 2006 18:57:11 -0400
> >
[-- Attachment #2: i2c-cpm.patch --]
[-- Type: text/x-patch, Size: 28109 bytes --]
--- nothing 1969-12-31 19:00:00.000000000 -0500
+++ i2c-cpm.c 2006-10-23 16:00:56.000000000 -0400
@@ -0,0 +1,999 @@
+/*
+ * ASP Watchdog 0.05: In-Reach ASP Watchdog Device
+ *
+ * (c) Copyright 2002 Ken Poole <kpoole@mrv.com>, All Rights Reserved.
+ * http://www.mrv.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Neither Ken Poole nor MRV Communications, Inc. admit liability
+ * nor provide warranty for any of this software. This material is
+ * provided "AS-IS" and at no charge.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/i2c-dev.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/proc_fs.h>
+#include <linux/dma-mapping.h>
+#include <asm/commproc.h>
+#include <asm/8xx_immap.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#define CPM_MAX_READ 513
+#define CPM_TIMEOUT 1000
+#define CPM_NUM_BDS 4
+#define CPM_WRT_BUF_SZ 128
+
+#define BD_SC_CLEARALL (BD_SC_LAST | BD_SC_INTRPT | BD_IIC_START \
+ | BD_SC_READY | BD_IIC_NAK | BD_IIC_UN | BD_IIC_CL)
+
+#define LOG_INT 1
+#define LOG_WRITE_ENT 2
+#define LOG_WRITE_CMD 3
+#define LOG_READ_ENT 4
+#define LOG_READ_CMD 5
+#define LOG_WRITE_DONE 6
+#define LOG_READ_DONE 7
+#define LOG_SIZE 128
+#define LOG_DISP 32
+
+struct i2c_datalog {
+ char type;
+ char displayed;
+ char pad[2];
+ unsigned long msecs;
+ cbd_t *tbdf;
+ cbd_t *rbdf;
+ u16 tx_sc;
+ u16 rx_sc;
+ u16 tbptr;
+ u16 rbptr;
+};
+
+int i2c_logindex = 0;
+
+struct i2c_datalog i2c_log[LOG_SIZE];
+
+struct i2c_8xx {
+ uint dp_addr;
+ u16 reloc;
+ volatile i2c8xx_t *i2c;
+ volatile iic_t *iip;
+ volatile cpm8xx_t *cp;
+ spinlock_t lock;
+};
+
+struct i2c_8xx cpm_i2c_8xx;
+
+#ifdef DECLARE_WAITQUEUE
+static wait_queue_head_t iic_rd_wait;
+static wait_queue_head_t iic_wr_wait;
+static wait_queue_head_t iic_cbd_wait;
+#else
+static struct wait_queue *iic_rd_wait;
+static struct wait_queue *iic_wr_wait;
+static struct wait_queue *iic_cbd_wait;
+#endif
+
+static ushort r_tbase, r_rbase;
+volatile static cbd_t *tbdf_cur, *rbdf_cur, *tbdf_base, *rbdf_base;
+#ifdef DEBUG_SHORT
+static char spbuf[256]; /* TEST TEST TEST */
+#endif
+
+#ifdef DEBUG_TIMEOUT
+unsigned char save_cer[32];
+int save_idx = 0;
+#endif
+
+unsigned char in_use;
+
+int cpm_scan = 0;
+int cpm_debug;
+
+static int cpm_iic_release(struct inode *inode, struct file *file);
+
+static unsigned long last_jifs = 0;
+
+static void make_log (char type, volatile cbd_t *tbdf, volatile cbd_t *rbdf)
+{
+ volatile iic_t *iip = cpm_i2c_8xx.iip;
+
+ i2c_log[i2c_logindex].type = type;
+ i2c_log[i2c_logindex].displayed = 0;
+ i2c_log[i2c_logindex].tbdf = (cbd_t *)tbdf;
+ i2c_log[i2c_logindex].rbdf = (cbd_t *)rbdf;
+ i2c_log[i2c_logindex].tx_sc = tbdf->cbd_sc;
+ i2c_log[i2c_logindex].rx_sc = rbdf->cbd_sc;
+ i2c_log[i2c_logindex].tbptr = iip->iic_tbptr;
+ i2c_log[i2c_logindex].rbptr = iip->iic_rbptr;
+ i2c_log[i2c_logindex].msecs = jiffies - last_jifs;
+
+ last_jifs = jiffies;
+
+ if (++i2c_logindex >= sizeof(i2c_log)/sizeof(struct i2c_datalog))
+ i2c_logindex = 0;
+}
+
+static void show_log (void)
+{
+ int index;
+ int count = 0;
+
+ index = i2c_logindex - LOG_DISP;
+ if (index < 0)
+ index = LOG_SIZE + index;
+
+ printk(KERN_DEBUG "logindex is %d\n", i2c_logindex);
+ while(1) {
+ if (i2c_log[index].displayed == 0) {
+ printk(KERN_DEBUG "%03d ", index);
+ printk(KERN_DEBUG "%04ld ", i2c_log[index].msecs);
+ switch (i2c_log[index].type) {
+ case LOG_INT:
+ printk(KERN_DEBUG "intrpt "); break;
+ case LOG_WRITE_ENT:
+ printk(KERN_DEBUG "write ent "); break;
+ case LOG_WRITE_CMD:
+ printk(KERN_DEBUG "write cmd "); break;
+ case LOG_READ_ENT:
+ printk(KERN_DEBUG "read ent "); break;
+ case LOG_READ_CMD:
+ printk(KERN_DEBUG "read cmd "); break;
+ case LOG_WRITE_DONE:
+ printk(KERN_DEBUG "write done "); break;
+ case LOG_READ_DONE:
+ printk(KERN_DEBUG "read done "); break;
+ }
+ printk(KERN_DEBUG "tbdf=%p rbdf=%p tx_sc=%04x rx_sc=%04x tbptr=%04x rbptr=%04x\n",
+ i2c_log[index].tbdf, i2c_log[index].rbdf, i2c_log[index].tx_sc, i2c_log[index].rx_sc,
+ i2c_log[index].tbptr, i2c_log[index].rbptr);
+ i2c_log[index].displayed = 1;
+ }
+ if (++index >= LOG_SIZE)
+ index = 0;
+ if (++count >= LOG_DISP)
+ break;
+ }
+ return;
+}
+
+static irqreturn_t
+cpm_iic_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id;
+ unsigned char local_cer;
+ volatile iic_t *iip = cpm_i2c_8xx.iip;
+ volatile cpm8xx_t *cp = cpm_i2c_8xx.cp;
+
+ if (cpm_debug > 1)
+ printk("cpm_iic_interrupt(dev_id=%p)\n", dev_id);
+
+ /* Save status */
+ local_cer = i2c->i2c_i2cer;
+ /* Clear interrupt */
+ i2c->i2c_i2cer = local_cer;
+
+ if ((local_cer & 0x14) && cpm_debug)
+ printk("cpm_iic_int: error int %02x\n", local_cer);
+
+ /* Chip errata, clear enable.
+ */
+ /* i2c->i2c_i2mod = 0; */
+
+#ifdef DEBUG_TIMEOUT
+ /* Record interrupt status */
+ save_cer[++save_idx] = local_cer;
+ if (save_idx >= 32)
+ save_idx = 0;
+#endif
+ /* printk(KERN_ERR "cpm_iic_int: iip=%p tbdf=%p rbdf=%p\n",
+ iip, &cp->cp_dpmem[iip->iic_tbptr],
+ &cp->cp_dpmem[iip->iic_rbptr]); */
+ make_log(LOG_INT, (cbd_t *)&cp->cp_dpmem[iip->iic_tbptr], (cbd_t *)&cp->cp_dpmem[iip->iic_rbptr]);
+
+ /* Get 'me going again.
+ */
+ if (local_cer & 0x01) {
+ wake_up_interruptible(&iic_rd_wait);
+ }
+ if (local_cer & 0x02) {
+ wake_up_interruptible(&iic_wr_wait);
+ }
+ if (local_cer & 0x14) {
+ wake_up_interruptible(&iic_rd_wait);
+ wake_up_interruptible(&iic_wr_wait);
+ }
+ return IRQ_HANDLED;
+}
+
+#ifdef DEBUG_TIMEOUT
+static void
+show_last_ints(void)
+{
+ int i, j;
+
+ j = save_idx - 7;
+ if (j < 0)
+ j = save_idx + 32;
+
+ printk("last 8 ints (idx=%d): ", save_idx);
+ for ( i = 0; i < 8; i++) {
+ printk(" %02x", save_cer[j]);
+ if (j++ >= 32)
+ j = 0;
+ }
+ printk("\n");
+}
+#endif
+
+
+static void
+cpm_reset_iic_params(volatile iic_t *iip)
+{
+ iip->iic_tbase = r_tbase;
+ iip->iic_rbase = r_rbase;
+
+ tbdf_cur = tbdf_base;
+ rbdf_cur = rbdf_base;
+
+ iip->iic_tfcr = SMC_EB;
+ iip->iic_rfcr = SMC_EB;
+
+ iip->iic_mrblr = CPM_MAX_READ;
+
+ iip->iic_rstate = 0;
+ iip->iic_rdp = 0;
+ iip->iic_rbptr = 0;
+ iip->iic_rbc = 0;
+ iip->iic_rxtmp = 0;
+ iip->iic_tstate = 0;
+ iip->iic_tdp = 0;
+ iip->iic_tbptr = 0;
+ iip->iic_tbc = 0;
+ iip->iic_txtmp = 0;
+}
+
+#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */
+
+static void force_close(struct i2c_8xx *cpm)
+{
+ if (cpm->reloc == 0) {
+ volatile cpm8xx_t *cp = cpm->cp;
+
+ if (cpm_debug) printk("force_close()\n");
+ cp->cp_cpcr =
+ mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RX_BD) |
+ CPM_CR_FLG;
+
+ while (cp->cp_cpcr & CPM_CR_FLG);
+ }
+}
+
+/*
+ */
+static int cpm_iic_open(struct inode *inode, struct file *file)
+{
+ /* Ok, so what do we do with the open? */
+
+ return 0;
+}
+
+ssize_t cpm_iic_read(u_char abyte, dma_addr_t buf, int count)
+{
+ DECLARE_WAITQUEUE(rdwait, current);
+ volatile iic_t *iip = cpm_i2c_8xx.iip;
+ volatile i2c8xx_t *i2c = cpm_i2c_8xx.i2c;
+ volatile cpm8xx_t *cp = cpm_i2c_8xx.cp;
+ volatile cbd_t *tbdf, *rbdf;
+ u_char *tb;
+ dma_addr_t tx_dma;
+ unsigned long orig;
+ int i;
+#ifdef DEBUG_TIMEOUT
+ int save_save_idx;
+#endif
+ if (count >= CPM_MAX_READ)
+ return -EINVAL;
+
+ /* check for and use a microcode relocation patch */
+ if (cpm_i2c_8xx.reloc) {
+ cpm_reset_iic_params(iip);
+ }
+
+ if (cpm_debug) printk("cpm_iic_read(abyte=0x%x)\n", abyte);
+
+ tbdf = tbdf_cur;
+ rbdf = rbdf_cur;
+
+ /* Bump current and wrap */
+ if (tbdf->cbd_sc & BD_SC_WRAP)
+ tbdf_cur = tbdf_base;
+ else
+ tbdf_cur = tbdf + 1;
+
+ if (rbdf->cbd_sc & BD_SC_WRAP)
+ rbdf_cur = rbdf_base;
+ else
+ rbdf_cur = rbdf + 1;
+
+ /* Allocate one transmit buffer. To read, we need an empty buffer
+ * of the proper length. All that is used is the first byte for
+ * address, the remainder is just used for timing (and doesn't
+ * really have to exist).
+ */
+ tb = dma_alloc_coherent(NULL, CPM_WRT_BUF_SZ, &tx_dma, GFP_KERNEL);
+ if (tb == NULL) {
+ printk(KERN_ERR "cpm_iic_read: allocate failed\n");
+ }
+
+ tb[0] = abyte; /* Device address byte w/rw flag */
+
+ //spin_lock_irqsave(&cpm_i2c_8xx.lock, flags );
+ spin_lock_irq(&cpm_i2c_8xx.lock);
+
+ /* Set up tx and rx descriptors */
+ tbdf->cbd_bufaddr = tx_dma;
+ tbdf->cbd_datlen = count + 1;
+
+ rbdf->cbd_datlen = 0;
+ rbdf->cbd_bufaddr = buf;
+
+ rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_INTRPT;
+ tbdf->cbd_sc |= BD_SC_READY | BD_SC_LAST | BD_IIC_START;
+
+ make_log(LOG_READ_CMD, tbdf, rbdf);
+
+ if (cpm_debug)
+ printk("cpm_iic_read: tbdf=%p rbdf=%p rbptr=%x tx sc=%04x rx sc=%04x\n",
+ tbdf, rbdf, iip->iic_rbptr, tbdf->cbd_sc, rbdf->cbd_sc);
+
+ /* Chip bug, set enable here */
+ i2c->i2c_i2cer = i2c->i2c_i2cer;
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2mod = 1; /* Enable */
+ i2c->i2c_i2com = 0x81; /* Start master */
+#ifdef DEBUG_TIMEOUT
+ save_save_idx = save_idx;
+#endif
+ orig = jiffies; /* Remember start time */
+ add_wait_queue(&iic_rd_wait, &rdwait);
+ spin_unlock_irq(&cpm_i2c_8xx.lock);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ /* Wait for IIC transfer */
+ while(1) {
+ if (!(rbdf->cbd_sc & BD_SC_EMPTY) && !(tbdf->cbd_sc & BD_SC_READY))
+ break;
+ if (tbdf->cbd_sc & (BD_SC_NAK | BD_SC_OV | BD_SC_CL))
+ break;
+
+ if ((jiffies - orig) >= CPM_TIMEOUT) {
+#ifdef DEBUG_TIMEOUT
+ printk("cpm_iic_read: timed out tx sc %04x, rx sc %04x \n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ printk("cpm_iic_read: tbdf=%p rbdf=%p rbptr=%x\n",
+ tbdf, rbdf, iip->iic_rbptr);
+ show_last_ints();
+#endif
+ /* read_int_defect: */
+ show_log();
+ printk(KERN_DEBUG "cpm_iic_read: timed out wait for complete tbdf=%p rbdf=%p tx sc=%04x, rx sc=%04x\n",
+ tbdf, rbdf, tbdf->cbd_sc, rbdf->cbd_sc);
+ tbdf->cbd_sc &= ~BD_SC_CLEARALL;
+ rbdf->cbd_sc &= ~BD_SC_OV;
+ /* Restore BD ptrs by reading controller reg */
+ tbdf_cur = (cbd_t *)&cp->cp_dpmem[iip->iic_tbptr];
+ rbdf_cur = (cbd_t *)&cp->cp_dpmem[iip->iic_rbptr];
+ i2c->i2c_i2mod = 0;
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_rd_wait, &rdwait);
+ dma_free_coherent(NULL, CPM_WRT_BUF_SZ, tb, tx_dma);
+ return -ETIMEDOUT;
+ }
+ schedule_timeout(CPM_TIMEOUT);
+
+ if (signal_pending(current)) {
+ i2c->i2c_i2mod = 0;
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_rd_wait, &rdwait);
+ dma_free_coherent(NULL, CPM_WRT_BUF_SZ, tb, tx_dma);
+ return -EIO;
+ }
+ }
+
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_rd_wait, &rdwait);
+ dma_free_coherent(NULL, CPM_WRT_BUF_SZ, tb, tx_dma);
+
+ make_log(LOG_READ_DONE, tbdf, rbdf);
+
+ if (cpm_debug) {
+ printk("tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+
+ if (tbdf->cbd_sc & BD_SC_NAK) {
+ if (cpm_debug)
+ printk("IIC read; no ack tbdf %p rbdf %p\n",
+ tbdf, rbdf);
+ force_close(&cpm_i2c_8xx);
+ /* NAK does not bump internal RBD pointer, so
+ we have to re-use the software rbd index */
+ rbdf_cur = rbdf;
+ count = -ENODEV;
+ goto read_out;
+ }
+
+ if (rbdf->cbd_sc & BD_SC_EMPTY) {
+ printk("IIC read; complete but rbuf empty\n");
+ printk("tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ force_close(&cpm_i2c_8xx);
+ }
+
+ if (rbdf->cbd_datlen < count) {
+ show_log();
+ printk("IIC read; short, wanted %d got %d (%d) ",
+ count, rbdf->cbd_datlen, tbdf->cbd_datlen);
+ //for (i = 0; i < rbdf->cbd_datlen; i++)
+ //printk(" %02x", buf[i]);
+ printk(" tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+
+ /* To recover from this, we pulse the SCL clock line
+ manually for 10 more cycles */
+ cp->cp_pbpar &= ~0x00000020;
+ for (i = 0; i < 10; i++) {
+ cp->cp_pbdat |= 0x00000020;
+ udelay(10);
+ cp->cp_pbdat &= ~0x00000020;
+ udelay(10);
+ }
+ cp->cp_pbpar |= 0x00000020;
+#ifdef DEBUG_SHORT
+ printk("prev write: %s", spbuf);
+#endif
+#ifdef DEBUG_TIMEOUT
+ show_last_ints();
+#endif
+ count = 0;
+ /* Fall through */
+ }
+
+read_out:
+ i2c->i2c_i2mod = 0;
+ tbdf->cbd_sc &= ~BD_SC_CLEARALL;
+ rbdf->cbd_sc &= ~BD_IIC_OV;
+ return count;
+}
+
+ssize_t cpm_iic_write(u_char abyte, dma_addr_t buf, int count)
+{
+ DECLARE_WAITQUEUE(wrwait, current);
+ volatile iic_t *iip = cpm_i2c_8xx.iip;
+ volatile i2c8xx_t *i2c = cpm_i2c_8xx.i2c;
+ volatile cpm8xx_t *cp = cpm_i2c_8xx.cp;
+ volatile cbd_t *tbdf0, *tbdf1;
+ u_char *tb;
+ dma_addr_t tx_dma;
+ unsigned long orig;
+#ifdef DEBUG_SHORT
+ int i, len = 0;
+#endif
+#ifdef DEBUG_TIMEOUT
+ int save_save_idx;
+#endif
+ /* check for and use a microcode relocation patch */
+ if (cpm_i2c_8xx.reloc) {
+ cpm_reset_iic_params(iip);
+ }
+
+ if (cpm_debug) printk("cpm_iic_write(abyte=0x%x)\n", abyte);
+
+ /* Get a descriptor */
+ tbdf0 = tbdf_cur;
+ /* Get next descriptor */
+ if (tbdf0->cbd_sc & BD_SC_WRAP)
+ tbdf1 = tbdf_base;
+ else
+ tbdf1 = tbdf0 + 1;
+
+ /* Bump current and and wrap */
+ if (tbdf1->cbd_sc & BD_SC_WRAP)
+ tbdf_cur = tbdf_base;
+ else
+ tbdf_cur = tbdf1 + 1;
+
+ /* Allocate one transmit message buffer */
+ tb = dma_alloc_coherent(NULL, CPM_WRT_BUF_SZ, &tx_dma, GFP_KERNEL);
+ if (tb == NULL) {
+ printk(KERN_ERR "cpm_iic_read: allocate failed\n");
+ }
+
+ *tb = abyte; /* Device address byte w/rw flag */
+
+ //spin_lock_irqsave(&cpm_i2c_8xx.lock, flags);
+ spin_lock_irq(&cpm_i2c_8xx.lock);
+
+ /* Set up 1st descriptor */
+ tbdf0->cbd_datlen = 1;
+ tbdf0->cbd_bufaddr = tx_dma;
+
+ /* Set up 2nd desc */
+ //tbdf1->cbd_bufaddr = __pa(buf);
+ tbdf1->cbd_bufaddr = buf;
+ tbdf1->cbd_datlen = count;
+
+ tbdf1->cbd_sc |= BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST;
+ tbdf0->cbd_sc |= BD_SC_READY | BD_IIC_START;
+
+ make_log(LOG_WRITE_CMD, tbdf0, tbdf1);
+
+ if (cpm_debug)
+ printk("cpm_iic_write: tbdf0=%p tbdf1=%p sc=%04x %04x abyte=%02x\n",
+ tbdf0, tbdf1, tbdf0->cbd_sc, tbdf1->cbd_sc, abyte);
+
+ orig = jiffies; /* Remember start time */
+
+ /* Chip bug, set enable here */
+ i2c->i2c_i2cer = i2c->i2c_i2cer;
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2mod = 1; /* Enable */
+ i2c->i2c_i2com = 0x81; /* Start master */
+#ifdef DEBUG_TIMEOUT
+ save_save_idx = save_idx;
+#endif
+ add_wait_queue(&iic_wr_wait, &wrwait);
+ spin_unlock_irq(&cpm_i2c_8xx.lock);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ /* Wait for IIC transfer */
+ while(1) {
+ if (!(tbdf1->cbd_sc & BD_SC_READY))
+ break;
+
+ if ((jiffies - orig) >= CPM_TIMEOUT) {
+#ifdef DEBUG_TIMEOUT
+ printk("cpm_iic_write: timed out tx0 sc %04x, tx1 sc %04x\n",
+ tbdf0->cbd_sc, tbdf1->cbd_sc);
+ printk("cpm_iic_write: tbdf0=%p tbdf1=%p tbptr=%04x\n",
+ tbdf0, tbdf1, iip->iic_tbptr);
+ show_last_ints();
+#endif
+ show_log();
+ printk(KERN_DEBUG "cpm_iic_write: timed out wait for complete tbdf0=%p tbdf1=%p tx sc=%04x, tx sc=%04x\n",
+ tbdf0, tbdf1, tbdf0->cbd_sc, tbdf1->cbd_sc);
+ tbdf0->cbd_sc &= ~BD_SC_CLEARALL;
+ tbdf1->cbd_sc &= ~BD_SC_CLEARALL;
+ /* Restore BD ptr by reading controller reg */
+ tbdf_cur = (cbd_t *)&cp->cp_dpmem[iip->iic_tbptr];
+ i2c->i2c_i2mod = 0;
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_wr_wait, &wrwait);
+ dma_free_coherent(NULL, CPM_WRT_BUF_SZ, tb, tx_dma);
+ return -ETIMEDOUT;
+ }
+ schedule_timeout(CPM_TIMEOUT);
+
+ if (signal_pending(current)) {
+ i2c->i2c_i2mod = 0;
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_wr_wait, &wrwait);
+ dma_free_coherent(NULL, CPM_WRT_BUF_SZ, tb, tx_dma);
+ return -EIO;
+ }
+ }
+
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_wr_wait, &wrwait);
+ dma_free_coherent(NULL, CPM_WRT_BUF_SZ, tb, tx_dma);
+
+ make_log(LOG_WRITE_DONE, tbdf0, tbdf1);
+
+ if (cpm_debug) {
+ printk("tx0 sc %04x, tx1 sc %04x\n",
+ tbdf0->cbd_sc, tbdf1->cbd_sc);
+ }
+
+ if (tbdf0->cbd_sc & BD_SC_NAK) {
+ if (cpm_debug)
+ printk("IIC write; no ack abyte=%02x\n", abyte);
+ tbdf_cur = (cbd_t *)&cp->cp_dpmem[iip->iic_tbptr];
+ count = -ENODEV;
+ goto write_out;
+ }
+
+ if (tbdf0->cbd_sc & BD_SC_READY) {
+ show_log();
+ printk("IIC write; complete but tbuf ready tbdf0=%p tcur=%p txsc=%04x tbptr=%04x\n", tbdf0, tbdf_cur, tbdf0->cbd_sc, iip->iic_tbptr);
+ tbdf_cur = (cbd_t *)&cp->cp_dpmem[iip->iic_tbptr];
+ count = 0;
+ goto write_out;
+ }
+
+#ifdef DEBUG_SHORT
+ /* Save status of write for later */
+ len = sprintf(spbuf, "cpm_iic_write: wrote %d bytes ", tbdf1->cbd_datlen);
+ //for (i = 0; i < tbdf1->cbd_datlen; i++)
+ //len += sprintf(spbuf+len, " %02x", ((u_char *)buf)[i]);
+ len += sprintf(spbuf+len, " tx0 sc %04x, tx1 sc %04x idx=%d\n",
+ tbdf0->cbd_sc, tbdf1->cbd_sc, save_save_idx);
+#endif
+write_out:
+ i2c->i2c_i2mod = 0;
+ tbdf0->cbd_sc &= ~BD_SC_CLEARALL;
+ tbdf1->cbd_sc &= ~BD_SC_CLEARALL;
+
+ return count;
+}
+
+static int cpm_xfer(struct file *file, struct i2c_msg *pmsg, u_char *virt, dma_addr_t dma)
+{
+ int j, ret;
+ u_char addr;
+
+ if (cpm_debug)
+ printk("cpm_xfer: "
+ "addr=0x%x flags=0x%x len=%d virt=%p dma=%x\n",
+ pmsg->addr, pmsg->flags, pmsg->len, virt, dma);
+
+ addr = pmsg->addr << 1;
+ if (pmsg->flags & I2C_M_RD )
+ addr |= 1;
+ if (pmsg->flags & I2C_M_REV_DIR_ADDR )
+ addr ^= 1;
+
+ if (!(pmsg->flags & I2C_M_NOSTART)) {
+ }
+ if (pmsg->flags & I2C_M_RD ) {
+ /* read bytes into buffer*/
+ ret = cpm_iic_read(addr, dma, pmsg->len);
+ if (cpm_debug) {
+ printk("cpm_xfer: read %d bytes ", ret);
+ for(j = 0; j < ret; j++)
+ printk("%02x ", virt[j]);
+ printk("\n");
+ }
+ if (ret < pmsg->len ) {
+ return (ret<0)? ret : -EREMOTEIO;
+ }
+ } else {
+ /* write bytes from buffer */
+ ret = cpm_iic_write(addr, dma, pmsg->len);
+ if (cpm_debug) {
+ printk("cpm_xfer: wrote %d bytes ", ret);
+ for(j = 0; j < ret; j++)
+ printk("%02x ", virt[j]);
+ printk("\n");
+ }
+ if (ret < pmsg->len ) {
+ return (ret<0) ? ret : -EREMOTEIO;
+ }
+ }
+
+ return (ret);
+}
+
+static int cpm_iic_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ DECLARE_WAITQUEUE(cbdwait, current);
+ struct i2c_rdwr_ioctl_data rdwr_arg;
+ struct i2c_msg *rdwr_pa;
+ u8 __user *virt_ptr;
+ dma_addr_t dma_addr;
+ unsigned long orig;
+ int i, res;
+
+ switch(cmd) {
+ case I2C_RDWR:
+ /* Wait for the controller to become available */
+ orig = jiffies; /* Remember start time */
+ add_wait_queue(&iic_cbd_wait, &cbdwait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ while(1) {
+ /* Test and set 'in use' flags, update of 'current' must be atomic */
+ spin_lock_irq(&cpm_i2c_8xx.lock);
+ if (in_use == 0) {
+ in_use = 1;
+ spin_unlock_irq(&cpm_i2c_8xx.lock);
+ break;
+ }
+ spin_unlock_irq(&cpm_i2c_8xx.lock);
+
+ if ((jiffies - orig) >= CPM_TIMEOUT) {
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_cbd_wait, &cbdwait);
+ printk(KERN_DEBUG "cpm_iic_read: timed out wait for controller\n");
+ return -ETIMEDOUT;
+ }
+ schedule_timeout(CPM_TIMEOUT);
+
+ if (signal_pending(current)) {
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_cbd_wait, &cbdwait);
+ return -EIO;
+ }
+ }
+
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&iic_cbd_wait, &cbdwait);
+
+ /* Local copy of all args */
+ if (copy_from_user(&rdwr_arg,
+ (struct i2c_rdwr_ioctl_data __user *)arg,
+ sizeof(rdwr_arg))) {
+ res = -EFAULT;
+ goto rdwr_out;
+ }
+
+ /* Put an arbritrary limit on the number of messages that can
+ * be sent at once */
+ if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS) {
+ res = -EINVAL;
+ goto rdwr_out;
+ }
+
+ /* Buffer for local copy of msgs pointed to by args */
+ rdwr_pa = (struct i2c_msg *)
+ kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
+ GFP_KERNEL);
+ if (rdwr_pa == NULL) {
+ res = -ENOMEM;
+ goto rdwr_out;
+ }
+
+ /* Copy header portion of the messages into local buffer */
+ if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
+ rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
+ kfree(rdwr_pa);
+ res = -EFAULT;
+ goto rdwr_out;
+ }
+
+ res = 0;
+ /* For each message ... */
+ for( i=0; i<rdwr_arg.nmsgs; i++ ) {
+ /* Limit the size of the message to a sane amount */
+ if (rdwr_pa[i].len > 8192) {
+ res = -EINVAL;
+ break;
+ }
+ /* Allocate a DMA buffer */
+ virt_ptr = dma_alloc_coherent(NULL, L1_CACHE_ALIGN(rdwr_pa[i].len), &dma_addr, GFP_KERNEL);
+ if(virt_ptr == NULL) {
+ res = -ENOMEM;
+ break;
+ }
+ /* Copy the data buffer portion of the message */
+ if(copy_from_user(virt_ptr,
+ rdwr_pa[i].buf,
+ rdwr_pa[i].len)) {
+ ++i; /* Needs to be kfreed too */
+ res = -EFAULT;
+ break;
+ }
+ /* Do the actual transfer */
+ res = cpm_xfer(file, &rdwr_pa[i], virt_ptr, dma_addr);
+ if (cpm_debug)
+ printk(KERN_ERR "i2c_rdwr: cpm_xfer returned %d\n", res);
+
+ /* If a read, copy the resulting data back */
+ if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) {
+ if(copy_to_user(rdwr_pa[i].buf,
+ virt_ptr,
+ rdwr_pa[i].len)) {
+ res = -EFAULT;
+ }
+ }
+ dma_free_coherent(NULL, L1_CACHE_ALIGN(rdwr_pa[i].len), virt_ptr, dma_addr);
+ }
+
+ kfree(rdwr_pa);
+rdwr_out:
+ in_use = 0;
+ wake_up_interruptible(&iic_cbd_wait);
+ schedule();
+ return res;
+ default:
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
+
+static struct file_operations cpm_iic_fops = {
+ owner: THIS_MODULE,
+ ioctl: cpm_iic_ioctl,
+ open: cpm_iic_open,
+ release: cpm_iic_release,
+};
+
+static struct miscdevice cpm_iic_miscdev = {
+ minor: CPM_IIC_MINOR,
+ name: "i2c-0",
+ fops: &cpm_iic_fops,
+};
+
+static int __init cpm_iic_init(void)
+{
+ volatile iic_t *iip;
+ volatile i2c8xx_t *i2c;
+ volatile cbd_t *bdp;
+ volatile cpm8xx_t *cp;
+ volatile immap_t *immap;
+ int j, ret;
+
+ ret = misc_register(&cpm_iic_miscdev);
+ if (ret)
+ return ret;
+
+ cp = cpmp; /* Get pointer to Communication Processor */
+ immap = (immap_t *)IMAP_ADDR; /* and to internal registers */
+
+ cpm_i2c_8xx.iip = iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
+ cpm_i2c_8xx.reloc = 0;
+
+ /* Check for and use a microcode relocation patch.
+ */
+#if 0
+ if ((cpm_i2c_8xx.reloc = cpm_i2c_8xx.iip->iic_rpbase))
+ cpm_i2c_8xx.iip = (iic_t *)&cp->cp_dpmem[cpm_i2c_8xx.iip->iic_rpbase];
+#endif
+ cpm_debug = 0;
+
+ cpm_i2c_8xx.i2c = i2c = (i2c8xx_t *)&(immap->im_i2c);
+ cpm_i2c_8xx.cp = cp;
+ cpm_i2c_8xx.lock = SPIN_LOCK_UNLOCKED;
+
+ /* Initialize Port B IIC pins.
+ */
+ cp->cp_pbpar |= 0x00000030;
+ cp->cp_pbdir |= 0x00000030;
+ cp->cp_pbodr |= 0x00000030;
+
+ /* Allocate space for two transmit and two receive buffer
+ * descriptors in the DP ram.
+ */
+ cpm_i2c_8xx.dp_addr = cpm_dpalloc(sizeof(cbd_t) * (CPM_NUM_BDS*2), 8);
+ if (cpm_debug) printk("cpm_iic_init: dp_addr %x\n", cpm_i2c_8xx.dp_addr);
+
+ /* ptr to i2c area */
+ cpm_i2c_8xx.i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c);
+
+ if (cpm_debug) printk("cpm_iic_init() - iip=%p\n",iip);
+
+ /* Initialize the parameter ram.
+ * We need to make sure many things are initialized to zero,
+ * especially in the case of a microcode patch.
+ */
+ iip->iic_rstate = 0;
+ iip->iic_rdp = 0;
+ iip->iic_rbptr = 0;
+ iip->iic_rbc = 0;
+ iip->iic_rxtmp = 0;
+ iip->iic_tstate = 0;
+ iip->iic_tdp = 0;
+ iip->iic_tbptr = 0;
+ iip->iic_tbc = 0;
+ iip->iic_txtmp = 0;
+
+ /* Set up the IIC parameters in the parameter ram.
+ */
+ iip->iic_tbase = r_tbase = cpm_i2c_8xx.dp_addr;
+ iip->iic_rbase = r_rbase = cpm_i2c_8xx.dp_addr + sizeof(cbd_t)*CPM_NUM_BDS;
+
+ tbdf_cur = tbdf_base = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
+ rbdf_cur = rbdf_base = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
+
+ bdp = tbdf_cur;
+ for (j=0; j<(CPM_NUM_BDS-1); j++) {
+ bdp->cbd_sc = 0;
+ /* bdp->cbd_sc &= ~( BD_SC_LAST | BD_SC_INTRPT | BD_IIC_START); */
+ bdp++;
+ }
+ bdp->cbd_sc = 0;
+ /* bdp->cbd_sc &= ~( BD_SC_LAST | BD_SC_INTRPT | BD_IIC_START); */
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ bdp = rbdf_cur;
+ for (j=0; j<(CPM_NUM_BDS-1); j++) {
+ bdp->cbd_sc = BD_SC_INTRPT;
+ bdp->cbd_sc &= ~BD_SC_EMPTY;
+ bdp++;
+ }
+ bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
+ bdp->cbd_sc &= ~BD_SC_EMPTY;
+
+ if (cpm_debug)
+ printk("cpm_iic_init: tbdf_cur=%p rbdf_cur=%p\n", tbdf_cur, rbdf_cur);
+
+ in_use = 0;
+
+ iip->iic_tfcr = SMC_EB;
+ iip->iic_rfcr = SMC_EB;
+
+ /* Set maximum receive size.
+ */
+ iip->iic_mrblr = CPM_MAX_READ;
+
+ /* Initialize Tx/Rx parameters.
+ */
+ if (cpm_i2c_8xx.reloc == 0) {
+ volatile cpm8xx_t *cp = cpm_i2c_8xx.cp;
+
+ cp->cp_cpcr =
+ mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+ }
+
+ /* Select an arbitrary address. Just make sure it is unique.
+ */
+ i2c->i2c_i2add = 0x34;
+
+ /* Make clock run maximum slow.
+ */
+ i2c->i2c_i2brg = 7;
+
+ /* Disable interrupts.
+ */
+ i2c->i2c_i2cmr = 0;
+ i2c->i2c_i2cer = 0xff;
+
+ init_waitqueue_head(&iic_rd_wait);
+ init_waitqueue_head(&iic_wr_wait);
+ init_waitqueue_head(&iic_cbd_wait);
+
+ /* Install interrupt handler.
+ */
+ if (cpm_debug) {
+ printk ("%s[%d] Install ISR for IRQ %d\n",
+ __func__,__LINE__, CPMVEC_I2C);
+ }
+ request_irq(CPMVEC_I2C + CPM_IRQ_OFFSET, cpm_iic_interrupt, 0, "cpm_i2c", (void *)i2c);
+
+ //cpm_debug = 1;
+
+ return(0);
+}
+
+static int
+cpm_iic_release(struct inode *inode, struct file *file)
+{
+ /*
+ * We don't do anything in the open, so don't do anything in the close.
+ * Any operation on the physical device could affect other tasks that
+ * might be using it.
+ */
+ return(0);
+}
+
+static void __exit cpm_iic_exit(void)
+{
+ misc_deregister(&cpm_iic_miscdev);
+}
+
+module_init(cpm_iic_init);
+module_exit(cpm_iic_exit);
+
+MODULE_AUTHOR("Ken Poole");
+MODULE_DESCRIPTION("MRV LX CPM_i2c Device Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(CPM_IIC_MINOR);
--- /home/cmurch/kernels/linux-2.6.18/include/linux/i2c-dev.h 2006-09-19 23:42:06.000000000 -0400
+++ i2c-dev.h 2006-10-23 16:00:55.000000000 -0400
@@ -19,6 +19,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/* $Id: i2c-dev.h,v 1.2 2005/02/23 14:50:02 kpoole Exp $ */
+
#ifndef _LINUX_I2C_DEV_H
#define _LINUX_I2C_DEV_H
@@ -36,6 +38,22 @@
union i2c_smbus_data __user *data;
};
+/*
+ * I2C Message - used for pure i2c transaction, also from /dev interface
+ */
+struct i2c_msg {
+ __u16 addr; /* slave address */
+ __u16 flags;
+#define I2C_M_TEN 0x10 /* we have a ten bit chip address */
+#define I2C_M_RD 0x01
+#define I2C_M_NOSTART 0x4000
+#define I2C_M_REV_DIR_ADDR 0x2000
+#define I2C_M_IGNORE_NAK 0x1000
+#define I2C_M_NO_RD_ACK 0x0800
+ __u16 len; /* msg length */
+ __u8 *buf; /* pointer to msg data */
+};
+
/* This is the structure as used in the I2C_RDWR ioctl call */
struct i2c_rdwr_ioctl_data {
struct i2c_msg __user *msgs; /* pointers to i2c_msgs */
@@ -44,4 +62,6 @@
#define I2C_RDRW_IOCTL_MAX_MSGS 42
+#define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/
+
#endif /* _LINUX_I2C_DEV_H */
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: MPC8xx CPM I2C interface driver
2006-10-22 22:50 ` Vitaly Bordug
2006-10-23 20:17 ` Christopher Murch
@ 2006-10-24 6:58 ` Norbert van Bolhuis
1 sibling, 0 replies; 6+ messages in thread
From: Norbert van Bolhuis @ 2006-10-24 6:58 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: linuxppc-embedded
Hi Vitaly,
>>Is there no MPC8xx CPM I2C interface driver in (latest) linux v2.6 or
>>am I mistaken ?
>>There's no code for CONFIG_I2C_ALGO8XX.
>
> The answer is - no, there is no stuff in the 2.6 kernel. I used to have the port from 2.4 a while ago (an
> improvement to the patches posted here btw) but had no chance to cleanup it and push through lm_sensors.
>
>
>>I've a MPC870 based board and I was hoping for a MPC8xx CPM I2C
>>interface driver to be there (allowing user applications to open and
>>read/write /dev/i2c-0)
>>
>
> You should be able to locate sources in this list's archives. Ping me once more if not, I'll try to dig it out of my HDD then...
>
Yes indeed. I got i2c-algo-8xx.c from 2005-August. Also in the mail archives there
are some patches to this file and the I2C RPX adapter (which is about the only one
using I2C algo 8xx).
Btw. One of the changes had to do with I2C RPX adapter not requesting the I2C IRQ
since I2C algo is already doing that.
Anyway, it all seems to work now.
Thanks.
N.
--
This message has been scanned for viruses and is believed to be clean
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-10-24 6:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-10 9:26 MPC8xx CPM I2C interface driver Abdul Rahaman
-- strict thread matches above, loose matches on Subject: below --
2006-10-10 9:05 Norbert van Bolhuis
2006-10-10 9:25 ` Abdul Rahaman
2006-10-22 22:50 ` Vitaly Bordug
2006-10-23 20:17 ` Christopher Murch
2006-10-24 6:58 ` Norbert van Bolhuis
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).