All of lore.kernel.org
 help / color / mirror / Atom feed
* Question on I2C driver development for Motorola chips
@ 2005-05-19  6:24 Xiao Xianghua-r6aads
  2005-05-19  6:24 ` Fw: " Mike Primm
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Xiao Xianghua-r6aads @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

Hello,

I'm an engineer working in Motorola. I have a 'working' I2C driver for the new chip MPC8540/MPC8560 and I'm eager to add this driver to your CVS, and I hope it can be pushed to the linux kernel in the near future.

I noticed a MPC8245 I2C driver is under development by Mike Primm from your newdriver webpage(http://secure.netroedge.com/%7Elm78/newdrivers.html), and I'm very interested in his progress, however there is no way for me to reach him(there is no email address :( ). Additionally, there is another Linux I2C driver for MPC824x(http://www.humboldt.co.uk/mpc10xi2c.html). Include my driver, all of us are trying to do the same thing because MPC8540/MPC8560/MPC824x/MPC107 are having the similar I2C design. I would like to find a way to provide a generic I2C for all these Motorola chips.

I'm also interested in getting the current Motorola 8xx I2C driver a new name if possible, because that driver can also be shared by 8xx/82xx/83xx(forthcoming new chip), i.e. any Motorola chip with a CPM(Communication Process Module) part on it.

Thanks a lot for your helps.

Xianghua

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Fw: Question on I2C driver development for Motorola chips
  2005-05-19  6:24 Question on I2C driver development for Motorola chips Xiao Xianghua-r6aads
  2005-05-19  6:24 ` Fw: " Mike Primm
  2005-05-19  6:24 ` Mark Studebaker
@ 2005-05-19  6:24 ` Jean Delvare
  2 siblings, 0 replies; 4+ messages in thread
From: Jean Delvare @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors


Hi Michael,

Xianghua is trying to reach you to share your works on Motorola MPC
drivers, so I am forwarding his message to you so that you can get in
touch.

Begin forwarded message:

Date: Tue, 21 Oct 2003 13:10:26 -0700
From: Xiao Xianghua-r6aads <X.Xiao@motorola.com>
To: "'sensors@stimpy.netroedge.com'" <sensors@Stimpy.netroedge.com>
Cc: Xiao Xianghua-r6aads <X.Xiao@motorola.com>
Subject: Question on I2C driver development for Motorola chips


Hello,

I'm an engineer working in Motorola. I have a 'working' I2C driver for
the new chip MPC8540/MPC8560 and I'm eager to add this driver to your
CVS, and I hope it can be pushed to the linux kernel in the near future.

I noticed a MPC8245 I2C driver is under development by Mike Primm from
your newdriver
webpage(http://secure.netroedge.com/%7Elm78/newdrivers.html), and I'm
very interested in his progress, however there is no way for me to reach
him(there is no email address :( ). Additionally, there is another Linux
I2C driver for MPC824x(http://www.humboldt.co.uk/mpc10xi2c.html).
Include my driver, all of us are trying to do the same thing because
MPC8540/MPC8560/MPC824x/MPC107 are having the similar I2C design. I
would like to find a way to provide a generic I2C for all these Motorola
chips.

I'm also interested in getting the current Motorola 8xx I2C driver a new
name if possible, because that driver can also be shared by
8xx/82xx/83xx(forthcoming new chip), i.e. any Motorola chip with a
CPM(Communication Process Module) part on it.

Thanks a lot for your helps.

Xianghua



-- 
Jean Delvare
http://www.ensicaen.ismra.fr/~delvare/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Fw: Question on I2C driver development for Motorola chips
  2005-05-19  6:24 Question on I2C driver development for Motorola chips Xiao Xianghua-r6aads
@ 2005-05-19  6:24 ` Mike Primm
  2005-05-19  6:24 ` Mark Studebaker
  2005-05-19  6:24 ` Jean Delvare
  2 siblings, 0 replies; 4+ messages in thread
From: Mike Primm @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

I'd be happy to share our driver.....it has some "proprietary" adders 
(as we need to be able to use it kernel mode, as well as through the 
standard ioctl-style interfaces), but should be fine for incorporation 
into a shared codebase.  Here are the driver files:

--Mike

Jean Delvare wrote:

>Hi Michael,
>
>Xianghua is trying to reach you to share your works on Motorola MPC
>drivers, so I am forwarding his message to you so that you can get in
>touch.
>
>Begin forwarded message:
>
>Date: Tue, 21 Oct 2003 13:10:26 -0700
>From: Xiao Xianghua-r6aads <X.Xiao@motorola.com>
>To: "'sensors@stimpy.netroedge.com'" <sensors@Stimpy.netroedge.com>
>Cc: Xiao Xianghua-r6aads <X.Xiao@motorola.com>
>Subject: Question on I2C driver development for Motorola chips
>
>
>Hello,
>
>I'm an engineer working in Motorola. I have a 'working' I2C driver for
>the new chip MPC8540/MPC8560 and I'm eager to add this driver to your
>CVS, and I hope it can be pushed to the linux kernel in the near future.
>
>I noticed a MPC8245 I2C driver is under development by Mike Primm from
>your newdriver
>webpage(http://secure.netroedge.com/%7Elm78/newdrivers.html), and I'm
>very interested in his progress, however there is no way for me to reach
>him(there is no email address :( ). Additionally, there is another Linux
>I2C driver for MPC824x(http://www.humboldt.co.uk/mpc10xi2c.html).
>Include my driver, all of us are trying to do the same thing because
>MPC8540/MPC8560/MPC824x/MPC107 are having the similar I2C design. I
>would like to find a way to provide a generic I2C for all these Motorola
>chips.
>
>I'm also interested in getting the current Motorola 8xx I2C driver a new
>name if possible, because that driver can also be shared by
>8xx/82xx/83xx(forthcoming new chip), i.e. any Motorola chip with a
>CPM(Communication Process Module) part on it.
>
>Thanks a lot for your helps.
>
>Xianghua
>
>
>
>  
>

-- 
--Mike
--

-------------- next part --------------
/* ------------------------------------------------------------------------- */
/* i2c-algo-mpc824x.c i2c driver algorithms for mpc824x i2c interfaces	     */
/* ------------------------------------------------------------------------- */
/*   Copyright (C) 2002 NetBotz Inc <primm@netbotz.com>			     */
/* Derived from i2c-algo-bit.c						     */
/*   Copyright (C) 1995-2000 Simon G. Vogl

    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
/* ------------------------------------------------------------------------- */

/* $Id: i2c-algo-mpc824x.c,v 1.11 2003/05/27 16:11:46 primm Exp $ */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-mpc824x.h>
#include <linux/smp_lock.h>

#define DRV_VERSION "0.1"

/* PCI device */
#define PCI_DEVICE_ID_BRIDGE_MPC8240	0x0003
#define PCI_DEVICE_ID_BRIDGE_MPC8245	0x0006

#define PCI_CONFIG_EUMB_BASE_ADDR	0x78
#define I2C_REGISTER_BASE_OFFSET	0x03000

#define USE_ASYNC_FOR_XFER
#define USE_HW_INT_FOR_XFER

#ifdef USE_HW_INT_FOR_XFER
#define	TIMER_PERIOD	(HZ/50)
#else
#define TIMER_PERIOD	(1)
#endif

#define HW_INT 129

enum i2c_mpc824x_regs {
	I2CADR, I2CFDR, I2CCR, I2CSR, I2CDR
};

typedef enum _i2c_mpc824x_status {
	ERROR = -1,
	NO_EVENT = -2,
	XMIT_ERROR = -3,
	RCV_ERROR = -4,
	BUS_BUSY = -5,
	ARB_LOST = -6,
	/* Pur errors before SUCCESS					*/
	SUCCESS = 0,
	ADDRESS_SENT,
	RECV_BUF_FULL,
	XMIT_BUF_EMPTY,
} i2c_mpc824x_status;

struct i2c_mpc824x_xfer_req {
	struct i2c_mpc824x_xfer_req *next;

	struct i2c_adapter *i2c_adap;
	struct i2c_msg *msgs;
	int num;
	void *usr_data;
	void (*callback)(struct i2c_adapter *, struct i2c_msg *,
		int num, int rc, void *usr_data);
	/* State variables						*/
	int cur_buf_num;	/* Current buffer index			*/
	int cur_do_xmit;	/* Current buffer is a transmit		*/
	unsigned long cur_wait_time;	/* Next timeout time (jiffies)	*/
};

static int	did_init = 0;
static spinlock_t	lock;
static struct i2c_mpc824x_xfer_req *req_head = NULL;
static struct i2c_mpc824x_xfer_req *req_tail = NULL;
static struct timer_list our_timer;
static int timer_added = 0;
static struct i2c_adapter *mpc_adap;

/* Default divisor of 1536 : gives us < 100KHz for 133MHz or less 	*/
#define DEFAULT_FDR	(0x0A)
/* Defines for i2c_mpc824x_get/setbits					*/
#define I2C_BITS(reg, off, mask) ((((reg) & 0xFF) << 24) | \
	(((off) & 0xFF) << 16) | ((mask) & 0xFFFF))
#define I2C_GETOFF(v) 		(((v) >> 16) & 0xFF)
#define I2C_GETMASK(v)		((v) & 0xFFFF)
#define I2C_GETREG(v) 		(((v) >> 24) & 0xFF)

#define I2C_MPC824X_ADR_ADDR	I2C_BITS(I2CADR, 1, 0x7F)
#define I2C_MPC824X_FDR_DFFAR	I2C_BITS(I2CFDR, 8, 0x3F)
#define I2C_MPC824X_FDR_FDR	I2C_BITS(I2CFDR, 0, 0x3F)
#define I2C_MPC824X_FDR		I2C_BITS(I2CFDR, 0, 0x3F3F)
#define I2C_MPC824X_CR_MEN	I2C_BITS(I2CCR, 7, 0x01)
#define I2C_MPC824X_CR_MIEN	I2C_BITS(I2CCR, 6, 0x01)
#define I2C_MPC824X_CR_MSTA	I2C_BITS(I2CCR, 5, 0x01)
#define I2C_MPC824X_CR_MTX	I2C_BITS(I2CCR, 4, 0x01)
#define I2C_MPC824X_CR_TXAK	I2C_BITS(I2CCR, 3, 0x01)
#define I2C_MPC824X_CR_RSTA	I2C_BITS(I2CCR, 2, 0x01)
#define I2C_MPC824X_CR_PCII	I2C_BITS(I2CCR, 1, 0x01)
#define I2C_MPC824X_CR_BCST	I2C_BITS(I2CCR, 0, 0x01)
#define I2C_MPC824X_CR		I2C_BITS(I2CCR, 0, 0xFF)
#define I2C_MPC824X_SR_MCF	I2C_BITS(I2CSR, 7, 0x01)
#define I2C_MPC824X_SR_MAAS	I2C_BITS(I2CSR, 6, 0x01)
#define I2C_MPC824X_SR_MBB	I2C_BITS(I2CSR, 5, 0x01)
#define I2C_MPC824X_SR_MAL	I2C_BITS(I2CSR, 4, 0x01)
#define I2C_MPC824X_SR_BCA	I2C_BITS(I2CSR, 3, 0x01)
#define I2C_MPC824X_SR_SRW	I2C_BITS(I2CSR, 2, 0x01)
#define I2C_MPC824X_SR_MIF	I2C_BITS(I2CSR, 1, 0x01)
#define I2C_MPC824X_SR_RXAK	I2C_BITS(I2CSR, 0, 0x01)
#define I2C_MPC824X_SR		I2C_BITS(I2CSR, 0, 0xFF)
#define I2C_MPC824X_DR_DATA	I2C_BITS(I2CDR, 0, 0xFF)

/* ----- global variables ---------------------------------------------	*/
static int debug_level = 1;

static u32 *eumb_base = NULL;

#define DEB(x, arg...) if((x) <= debug_level) { printk(arg); }

/* --- other auxiliary functions --------------------------------------	*/
static u32 i2c_mpc824x_getbits(u32 field)
{
	u32 val;
	val = in_le32(eumb_base + I2C_GETREG(field));
	val >>= I2C_GETOFF(field);	/* Shift field into place	*/
	val &= I2C_GETMASK(field);	/* And mask off other data	*/
	DEB(3, "i2c_mpc824x_getbits(0x%.8x)=0x%.8x\n",
		field, val);
	return val;
}

static void i2c_mpc824x_setbits(u32 field, u32 val)
{
	u32 oldval;
	u32 mask;
	u32 newval;

	DEB(3, "i2c_mpc824x_setbits(0x%.8x, 0x%.8x)\n",
		field, val);
	/* Get current value						*/
	oldval = in_le32(eumb_base + I2C_GETREG(field));
	mask = I2C_GETMASK(field);	/* Get mask			*/
	/* Mask off old values to keep					*/
	newval = oldval & (~(mask << I2C_GETOFF(field)));
	/* Now, add in the new value					*/
	newval |= (val & mask) << I2C_GETOFF(field);
	/* Now write out the modified register				*/
	out_le32(eumb_base + I2C_GETREG(field), newval);
}

static void i2c_init(void)
{
	DEB(2, "i2c_init()\n");
	/* Clear control register, for starters				*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR, 0);
	/* Set FDR to a reasonable value (assume SDRAM clk <= 133MHz)	*/
	i2c_mpc824x_setbits(I2C_MPC824X_FDR_FDR,
		DEFAULT_FDR);
	/* Set slave address to invalid address (we don't do slave)     */
	i2c_mpc824x_setbits(I2C_MPC824X_ADR_ADDR, 0x7F);
#ifdef USE_HW_INT_FOR_XFER
	/* Initialize to interrupts enabled				*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR_MIEN, 1);
#else
	/* Initialize to interrupts disabled (for now)			*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR_MIEN, 0);
#endif
	/* We're all set : enable module				*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR_MEN, 1);
}

static void i2c_term(void)
{
	DEB(2, "i2c_term()\n");
	/* Clear control register					*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR, 0);
}

static i2c_mpc824x_status i2c_start(struct i2c_algo_mpc824x_data *adap)
{
	DEB(2, "i2c_start()\n");
	/* Complain if not initialized					*/
	if(i2c_mpc824x_getbits(I2C_MPC824X_CR_MEN) = 0) {
		DEB(1, "i2c-algo-mpc824x: not initialized\n");
		return ERROR;
	}
	/* Check to see if bus is free (only if we're not restarting)	*/
	if(i2c_mpc824x_getbits(I2C_MPC824X_SR_MBB) &&
		(adap->is_restart = 0)) {
		DEB(2, "i2c-algo-mpc824x: bus busy - resetting\n");
		i2c_init();	/* Reinitialize				*/
		return BUS_BUSY;
	}
	/* Set master mode						*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR_MSTA, 1);
	/* Set MTC to indicate transmit					*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR_MTX, 1);
	/* Clear txak							*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR_TXAK, 0);
	/* Set restart appropriately					*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR_RSTA,
		adap->is_restart?1:0);
	/* Write slave address being called into the data register	*/
	i2c_mpc824x_setbits(I2C_MPC824X_DR_DATA,
		(((u32)adap->slaveaddr & 0x7F) << 1) |
		(adap->is_xmit?0x00:0x01));
	/* If receive, then we're in the address phase			*/
	if(adap->is_xmit) {
		adap->is_rcv_addr = 0;
	} else {
		adap->is_rcv_addr = 1;
	}
	return SUCCESS;
}

static void i2c_stop(void)
{
	DEB(2, "i2c_stop()\n");
	/* Clear the master mode bit					*/
	i2c_mpc824x_setbits(I2C_MPC824X_CR_MSTA, 0);
}

/* Transmit next pending byte : return 1 if no more bytes, 0 if sent,
 * -1 if error								*/
static i2c_mpc824x_status i2c_xmit_next_byte(struct
	i2c_algo_mpc824x_data *adap)
{
	DEB(2, "i2c_xmit_next_byte()\n");
	/* If any bytes to send						*/
	if(adap->bufindex >= 0) {
		/* If we've sent the last byte				*/
		if(adap->bufindex = adap->buflen) {
			adap->bufindex = -1;	/* Mark we're done	*/
			/* If we want to stop, do it			*/
			if(adap->stop_when_done) {
				i2c_stop();
			}
			return XMIT_BUF_EMPTY;
		}
		/* Send next byte					*/
		i2c_mpc824x_setbits(I2C_MPC824X_DR_DATA,
			adap->buffer[adap->bufindex]);
		/* Increment index					*/
		adap->bufindex++;
		return SUCCESS;
	}
	return XMIT_BUF_EMPTY;
}

/* Receive next byte into buffer : return 1 if full, 0 if byte read,
 * -1 if error								*/
 static i2c_mpc824x_status i2c_recv_next_byte(struct
 	i2c_algo_mpc824x_data *adap)
 {
 	DEB(2, "i2c_recv_next_byte()\n");
 	/* If we're still receiving bytes				*/
	if(adap->bufindex >= 0) {
		/* If we're up to the next to last byte, we need to
		 * set the TXAK bit to tell the sender to stop		*/
		if((adap->buflen - adap->bufindex) = 2) {
			i2c_mpc824x_setbits(I2C_MPC824X_CR_TXAK, 1);
		}
		/* If we're about to receive the last one, and we want
		 * to stop after it, do so				*/
		if(((adap->buflen - adap->bufindex) = 1) &&
			adap->stop_when_done) {
			i2c_stop();
		}
		/* Now, read the data register				*/
		adap->buffer[adap->bufindex] = (u8)i2c_mpc824x_getbits(
			I2C_MPC824X_DR_DATA);
		adap->bufindex++;
		/* If that was the last one, return appropriately	*/
		if(adap->bufindex = adap->buflen) {
			adap->bufindex = -1;
			return RECV_BUF_FULL;
		}
		return SUCCESS;
	}
	return RECV_BUF_FULL;
}

/* Master ISR for I2C state machine					*/
static i2c_mpc824x_status i2c_isr(struct i2c_algo_mpc824x_data *adap)
{
	DEB(3, "i2c_isr: i2ccr=0x%.4x, i2csr=0x%.4x\n",
		i2c_mpc824x_getbits(I2C_MPC824X_CR),
		i2c_mpc824x_getbits(I2C_MPC824X_SR));
	/* Fist, clear the MIF flag					*/
	i2c_mpc824x_setbits(I2C_MPC824X_SR_MIF, 0);
	/* If we've completed a byte transfer				*/
	if(i2c_mpc824x_getbits(I2C_MPC824X_SR_MCF)) {
		/* If we're in master mode				*/
		if(i2c_mpc824x_getbits(I2C_MPC824X_CR_MSTA)) {
			/* If transmit mode				*/
			if(i2c_mpc824x_getbits(I2C_MPC824X_CR_MTX)) {
				/* If receive address mode		*/
				if(adap->is_rcv_addr) {
					/* Switch to receiving		*/
					i2c_mpc824x_setbits(
						I2C_MPC824X_CR_MTX, 0);
					/* If only getting 1 byte, and
					 * want to stop after: set ak	*/
					if((adap->buflen = 1) &&
						(adap->stop_when_done)) {
						i2c_mpc824x_setbits(
							I2C_MPC824X_CR_TXAK, 1);
					}
					/* Do fake read first		*/
					i2c_mpc824x_getbits(
						I2C_MPC824X_DR_DATA);
					adap->is_rcv_addr = 0;
					/* Return (in address state)	*/
					return ADDRESS_SENT;
				}
				/* Master xmit : has slave acknowledged */
				if(i2c_mpc824x_getbits(
					I2C_MPC824X_SR_RXAK) = 0) {
					/* If so, send next byte	*/
					return i2c_xmit_next_byte(adap);
				}
				/* Else, no ACK : do stop if needed	*/
				if(adap->stop_when_done) {
					i2c_stop();
				}
				return SUCCESS;
			}
			else {	/* Else, we're receiving		*/
				return i2c_recv_next_byte(adap);
			}
		}
		else {	/* Else, slave mode				*/
			/* We don't do this....shouldn't happen		*/
			DEB(1, "i2c-algo-mpc824x: slave mode - not supported!!!\n");
			return ERROR;
		}
	}
	/* Else if received call from master - not supported		*/
	else if(i2c_mpc824x_getbits(I2C_MPC824X_SR_MAAS)) {
		DEB(1, "i2c-algo-mpc824x: received call from master - "
			"slave mode not supported!!!\n");
		return ERROR;
	}
	/* Else, has to be arbitration lost				*/
	else {
		/* Clear MAL flag					*/
		i2c_mpc824x_setbits(I2C_MPC824X_SR_MAL, 0);
		/* Return to receive mode				*/
		i2c_stop();
	}
	return SUCCESS;
}

/* I2C timer function : used if periodic polling is used instead if ints*/
static i2c_mpc824x_status i2c_timer_event(struct
	i2c_algo_mpc824x_data *adap)
{
	/* If interrupt flag set, call ISR				*/
	if(i2c_mpc824x_getbits(I2C_MPC824X_SR_MIF)) {
		//printk("MIF\n");
		return i2c_isr(adap);
	}
	else {	/* Else, no event					*/
		//printk("NO_EVENT\n");
		return NO_EVENT;
	}
}

/* Function to initialize a xmit/recv operation				*/
static i2c_mpc824x_status i2c_init_xmit_recv(struct
	i2c_algo_mpc824x_data *adap, int address, u8 *buffer,
	int buflen, int stop_when_done, int is_restart, int is_xmit)
{
	if((is_xmit = 0) && ((buffer = NULL) || (buflen = 0))) {
		DEB(1, "i2c-algo-mpc824x: zero length recv unsupported!\n");
		return ERROR;
	}
	/* Initialize all state variables for transfer			*/
	adap->buffer = buffer;
	adap->buflen = buflen;
	adap->bufindex = 0;
	adap->slaveaddr = address;
	adap->is_xmit = is_xmit;
	adap->stop_when_done = stop_when_done;
	adap->is_restart = is_restart;
	adap->is_rcv_addr = 0;
	/* Now, start the transfer					*/
	return i2c_start(adap);
}

/* Function to do polling mode processing of one buffer			*/
static i2c_mpc824x_status i2c_do_buffer(struct i2c_algo_mpc824x_data *
	adap, int do_xmit, int address, u8 *buffer, int buflen,
	int stop_when_done, int do_restart)
{
	i2c_mpc824x_status rc;
	u8 minbuf[1];
	/* Initialize the transfer itself				*/
	if((do_xmit = 0) && (buflen = 0)) {
		buffer = minbuf;
		buflen = 1;
	}
	rc = i2c_init_xmit_recv(adap, address, buffer, buflen,
		stop_when_done, do_restart, do_xmit);
	/* If not started successfully, we're done			*/
	if(rc != SUCCESS) {
		DEB(1, "i2c-algo-mpc824x: start failed: i2ccr=0x%.4x, "
			"i2csr=0%.4x\n", i2c_mpc824x_getbits(
			I2C_MPC824X_CR), i2c_mpc824x_getbits(
			I2C_MPC824X_SR));
		i2c_stop();
		return ERROR;
	}
	/* Now, wait for it to get done					*/
	while((rc = SUCCESS) || (rc = ADDRESS_SENT)) {
		unsigned long wait_time = jiffies + 2*HZ;
		unsigned long wait_cnt = 0;

		/* Poll the device until something happens		*/
		do {
			rc = i2c_timer_event(adap);
			wait_cnt++;
		} while ((rc = NO_EVENT) && (jiffies < wait_time) &&
			(wait_cnt < 1000000));
		/* If error, quit					*/
		if(rc < SUCCESS) {
			DEB(1, "i2c-algo-mpc824x: do_buffer failed(%d) - "
				"i2ccr=0x%.4x, i2csr=0x%.4x\n", rc,
				i2c_mpc824x_getbits(
				I2C_MPC824X_CR), i2c_mpc824x_getbits(
				I2C_MPC824X_SR));
			return ERROR;
		}
	}
	return SUCCESS;
}

/* IRQ function : used for timer and for hw irq				*/
static void i2c_mpc824x_irq_func(unsigned long data)
{
	int rc = 0;
	int cur_cmd_done = 0;
	int cur_req_done = 0;
	unsigned long flags;
	struct i2c_msg *pmsg;
	static u8 minbuf[1];
	int len;
	u8 *buf;
	struct i2c_mpc824x_xfer_req *req;

	req = req_head;
	/* If active request, process it			*/
	if(req) {
		/* If buffer is in progress			*/
		if(req->cur_buf_num >= 0) {
			/* Process tick to advance it		*/
			rc = i2c_timer_event(
				req->i2c_adap->algo_data);
			/* If nothing happened, consider timeout*/
			if(rc = NO_EVENT) {
				/* If we're out of time		*/
				if(jiffies >
					req->cur_wait_time) {
					rc = -EREMOTEIO;
					cur_req_done = 1;
				}
			}
			/* If error, we're done			*/
			else if(rc < SUCCESS) {
				rc = -EREMOTEIO;
				cur_req_done = 1;
			}
			/* Else, reset wait timer		*/
			else if((rc = SUCCESS) || (rc = ADDRESS_SENT)) {
				req->cur_wait_time 					jiffies + 2*HZ;
			}
			/* Else, we're done!			*/
			else {
				rc = 0;
				cur_cmd_done = 1;
			}
		}
		else {	/* If not running yet, we need to start */
			cur_cmd_done = 1;
		}
		/* If we finished one (or need to start)	*/
		if(cur_cmd_done) {
			req->cur_buf_num++;
			/* See if there are more buffers	*/
			if(req->cur_buf_num >= req->num) {
				/* If not, we're done		*/
				cur_req_done = 1;
				/* Set return code		*/
				rc = req->num;
			}
			/* Else, start next one			*/
			else {
				pmsg = &(req->msgs[
					req->cur_buf_num]);

				if(pmsg->flags & I2C_M_RD)
					req->cur_do_xmit = 0;
				else
					req->cur_do_xmit = 1;
				len = pmsg->len;
				buf = pmsg->buf;
				/* Make sure its minimum read   */
				if((req->cur_do_xmit = 0) &&
					(len = 0)) {
					buf = minbuf;
					len = 1;
				}
				/* Start the new request	*/
				rc = i2c_init_xmit_recv(
					req->i2c_adap->algo_data,
					pmsg->addr, buf, len,
					(req->cur_buf_num =
					 (req->num - 1)),
					req->cur_buf_num > 0,
					req->cur_do_xmit);
				if(rc != SUCCESS) {
					rc = -EREMOTEIO;
					cur_req_done = 1;
					DEB(2,
						"i2c-algo-mpc824x: xfer init failed\n");
				}
			}
		}
		/* If the request is complete			*/
		if(cur_req_done) {
			/* If not, request is complete		*/
			if(req->callback) {
				/* Do callback			*/
				req->callback(req->i2c_adap,
					req->msgs, req->num,
					rc, req->usr_data);
			}
			/* Dequueue from list		        */
			spin_lock_irqsave(&lock, flags);
			req_head = req->next;
			if(req_head = NULL) req_tail = NULL;
			spin_unlock_irqrestore(&lock, flags);
			/* Free the record			*/
			kfree(req);
		}
	}
}

/* Timer function : called every tick when active	 	    */
static void i2c_mpc824x_timer_func(unsigned long data)
{
	unsigned long flags;

	spin_lock_irqsave(&lock, flags);
	timer_added = 0;
	spin_unlock_irqrestore(&lock, flags);

	//printk("timer\n");

	i2c_mpc824x_irq_func(data);

	spin_lock_irqsave(&lock, flags);
	/* Requeue the timer function IF a request is active    */
	if(req_head && (!timer_added)) {
		our_timer.expires = jiffies + TIMER_PERIOD;
		our_timer.function = i2c_mpc824x_timer_func;
		add_timer(&our_timer);
		timer_added = 1;
	}
	spin_unlock_irqrestore(&lock, flags);
}

static void i2c_mpc824x_interrupt_func(int this_irq, void *dev_id,
	struct pt_regs *regs)
{
	if(i2c_mpc824x_getbits(I2C_MPC824X_SR_MIF)) {
		//printk("irq:MIF\n");
		i2c_mpc824x_irq_func(NULL);
		i2c_mpc824x_setbits(I2C_MPC824X_SR_MIF, 0);
	}
	else {
		//printk("irq:!MIF\n");
	}
}

/* Submit a non-blocking request to issue I2C commands			*/
int i2c_mpc824x_xfer_async(struct i2c_adapter *i2c_adap,
	struct i2c_msg *msgs, int num, void (*callback)
	(struct i2c_adapter *, struct i2c_msg *, int num, int rc,
	void *usr_data), void *usr_data)
{
	unsigned long flags;
	struct i2c_mpc824x_xfer_req *req;
	int did_first_add = 0;

	/* Allocate request block					*/
	req = kmalloc(sizeof(*req), GFP_ATOMIC);
	if(!req) {
		DEB(1, "i2c_algo_mpc824x: kmalloc failed!\n");
		return -ENOMEM;
	}
	req->i2c_adap = i2c_adap;
	req->msgs = &msgs[0];
	req->num = num;
	req->usr_data = usr_data;
	req->callback = callback;
	req->cur_buf_num = -1;
	req->cur_do_xmit = 0;
	req->next = NULL;
	req->cur_wait_time = 0;
	/* Add to list							*/
	spin_lock_irqsave(&lock, flags);
	if(req_tail = NULL) {	/* Empty list				*/
		req_tail = req_head = req;
		did_first_add = 1;
	}
	else {
		req_tail->next = req;
		req_tail = req;
	}
	/* If first on list, start timer back up			*/
	if(did_first_add && (!timer_added)) {
		our_timer.expires = jiffies;
		our_timer.function = i2c_mpc824x_timer_func;
		timer_added = 1;
		add_timer(&our_timer);
	}
	spin_unlock_irqrestore(&lock, flags);

	return 0;
}

/* Find the I2C registers					*/
static __init u32 *find_mpc824x_i2c(void)
{
	struct pci_dev *s_bridge;
	u32 eumb_base;

	if (!pci_present())
		return NULL;

	s_bridge = pci_find_device(PCI_VENDOR_ID_MOTOROLA,
		PCI_DEVICE_ID_BRIDGE_MPC8240, NULL);

	if (!s_bridge) {
		s_bridge = pci_find_device(PCI_VENDOR_ID_MOTOROLA,
			PCI_DEVICE_ID_BRIDGE_MPC8245, NULL);
		if(!s_bridge) {
			DEB(1, "i2c-algo-mpc824x.o: mpc824x not found\n");
			return NULL;
		}
	}
	/* Read EUMB base address				    */
	if(pci_read_config_dword(s_bridge, PCI_CONFIG_EUMB_BASE_ADDR,
		&eumb_base) != PCIBIOS_SUCCESSFUL) {
		return NULL;
	}

	return (u32 *)(eumb_base + I2C_REGISTER_BASE_OFFSET);
}

static int i2c_mpc824x_xfer_sync(struct i2c_adapter *i2c_adap,
	struct i2c_msg *msgs, int num)
{
	struct i2c_msg *pmsg;
	struct i2c_algo_mpc824x_data *adap = i2c_adap->algo_data;
	int i;

	for (i=0;i<num;i++) {
		pmsg = &msgs[i];	/* Get pointer to message	*/
		/* If message is not requesting a no-start		*/
		if (!(pmsg->flags & I2C_M_NOSTART)) {
			i2c_mpc824x_status rc;
			int do_xmit = 1;

			if(pmsg->flags & I2C_M_RD)
				do_xmit = 0;

			rc = i2c_do_buffer(adap, do_xmit,
				pmsg->addr, pmsg->buf ,pmsg->len,
				(i = (num-1)),
				(i > 0));
			if (rc < SUCCESS) {
				DEB(1, "i2c-algo-mpc824x.o:"
					"error(%d) from device adr %#2x "
					"msg #%d\n", rc, msgs[i].addr,
					i);
				return -EREMOTEIO;
			}
		}
	}
	return num;
}

#ifdef USE_ASYNC_FOR_XFER
struct i2c_wait_rslt {
	wait_queue_head_t update_wait_q;
	int rc;
};

static void i2c_mpc824x_xfer_callback(struct i2c_adapter *adap,
	struct i2c_msg *msgs, int num, int rc, void *usr_data)
{
	struct i2c_wait_rslt *rslt = (struct i2c_wait_rslt *)usr_data;
	rslt->rc = rc;
	wake_up_interruptible(&(rslt->update_wait_q));
}
#endif


static int i2c_mpc824x_xfer(struct i2c_adapter *i2c_adap,
	struct i2c_msg msgs[], int num)
{
	int rc;
#ifdef USE_ASYNC_FOR_XFER
	struct i2c_wait_rslt rslt;

	init_waitqueue_head(&(rslt.update_wait_q));
	rslt.rc = -EREMOTEIO;
	rc = i2c_mpc824x_xfer_async(i2c_adap, msgs, num,
		i2c_mpc824x_xfer_callback, &rslt);
	if(rc = 0) {
		interruptible_sleep_on(&(rslt.update_wait_q));
		rc = rslt.rc;
	}
#else
	rc = i2c_mpc824x_xfer_sync(i2c_adap, &msgs[0], num);
#endif
	//printk("i2c_mpc824x_xfer() - rc=%d\n", rc);
	return rc;
}

static int algo_control(struct i2c_adapter *adapter,
	unsigned int cmd, unsigned long arg)
{
	return 0;
}

static u32 i2c_mpc824x_func(struct i2c_adapter *adap)
{
	return I2C_FUNC_SMBUS_EMUL |
	       I2C_FUNC_PROTOCOL_MANGLING;
}

#ifdef CONFIG_RAPTOR
/* Special entry point used for I2C commands issued for system hard reset
 * from raptor_setup.c - needs to be interrupt time callable		*/
void i2c_mpc824x_do_cmds(void *eumb_addr, struct i2c_msg msgs[],
	int num)
{
	struct i2c_algo_mpc824x_data algo;
	struct i2c_adapter adap;
	unsigned long flags;
	int was_up = 0;

	/* Make bogus adapter structure ... enough to work with calls	*/
	memset(&adap, 0, sizeof(adap));
	adap.algo_data = &algo;
	memset(&algo, 0, sizeof(algo));

	eumb_base = (u32 *)((unsigned long)eumb_addr +
		I2C_REGISTER_BASE_OFFSET);

	if(!did_init)	/* If not initialized, init the lock		*/
		lock = (spinlock_t)SPIN_LOCK_UNLOCKED;

	/* Disable interrupts if we're initialized			*/
	spin_lock_irqsave(&lock, flags);

	/* Now do a stop (if we were already active)			*/
	if(i2c_mpc824x_getbits(I2C_MPC824X_CR_MEN)) {
		i2c_stop();
		i2c_term();
		was_up = 1;
	}
	/* Reinitialize if needed					*/
	i2c_init();
	/* Now send the messages					*/
	i2c_mpc824x_xfer_sync(&adap, msgs, num);
	/* Now terminate if we weren't active before			*/
	if(was_up = 0) {
		i2c_term();
	}
	/* Drop lock							*/
	spin_unlock_irqrestore(&lock, flags);
}

/* Special entry point used for I2C commands issued for modules		*/
void i2c_mpc824x_do_cmds_async(struct i2c_msg *msgs,
	int num, void (*callback)(struct i2c_adapter *, struct i2c_msg *, 
	int num, int rc, void *usr_data), void *usr_data)
{
	if(mpc_adap) {
		i2c_mpc824x_xfer_async(mpc_adap, msgs, num,
			callback, usr_data);
	}
	else {
		callback(NULL, msgs, num, -1, usr_data);
	}
}

#endif
/* -----exported algorithm data: -------------------------------------	*/

static struct i2c_algorithm i2c_bit_algo = {
	"Motorola mpc824x algorithm",
	I2C_ALGO_MPC824X,
	i2c_mpc824x_xfer,
	NULL,
	NULL,				/* slave_xmit		*/
	NULL,				/* slave_recv		*/
	algo_control,			/* ioctl		*/
	i2c_mpc824x_func,		/* functionality	*/
};

/*
 * registering functions to load algorithms at runtime
 */
int i2c_mpc824x_add_bus(struct i2c_adapter *i2c_adap)
{
	DEB(2, "i2c-algo-mpc824x.o: hw routines for %s registered.\n",
	            i2c_adap->name);

	/* Initialize the hardware				*/
	i2c_init();

	/* register new adapter to i2c module... */
	i2c_adap->id |= i2c_bit_algo.id;
	i2c_adap->algo = &i2c_bit_algo;

	i2c_adap->timeout = 100;/* default values, should	*/
	i2c_adap->retries = 3;	/* be replaced by defines	*/

#ifdef MODULE
	MOD_INC_USE_COUNT;
#endif
	i2c_add_adapter(i2c_adap);

	mpc_adap = i2c_adap;

	return 0;
}

int i2c_mpc824x_del_bus(struct i2c_adapter *adap)
{
	int res;

	if ((res = i2c_del_adapter(adap)) < 0) {
		return res;
	}

	DEB(2, "i2c-algo-mpc824x.o: adapter unregistered: %s\n",adap->name);

	i2c_term();		/* Shutdown hardware		 */

	mpc_adap = NULL;
 
#ifdef MODULE
	MOD_DEC_USE_COUNT;
#endif
	return 0;
}

int __init i2c_algo_mpc824x_init (void)
{
	DEB(1, "i2c-algo-mpc824x.o: i2c mpc824x algorithm module version %s\n", DRV_VERSION);

	did_init = 1;

	lock = (spinlock_t)SPIN_LOCK_UNLOCKED;

	eumb_base = find_mpc824x_i2c();
	if(eumb_base = NULL) {
		DEB(1, "i2c-algo-mpc824x.o: no mpc824x found!\n");
		return -ENODEV;
	}
#ifdef USE_HW_INT_FOR_XFER
	if (request_irq(HW_INT, i2c_mpc824x_interrupt_func, 0, "i2c mpc824x", NULL) < 0) {
		DEB(1, "i2c-algo-mpc824x.o: error registering irq\n");
		return -ENODEV;
	}
#endif
	return 0;
}

EXPORT_SYMBOL(i2c_mpc824x_add_bus);
EXPORT_SYMBOL(i2c_mpc824x_del_bus);
#ifdef CONFIG_RAPTOR
EXPORT_SYMBOL(i2c_mpc824x_do_cmds);
EXPORT_SYMBOL(i2c_mpc824x_do_cmds_async);
#endif

#ifdef MODULE

MODULE_AUTHOR("Michael Primm <primm@netbotz.com>");
MODULE_DESCRIPTION("I2C-Bus mpc824x algorithm");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif

MODULE_PARM(debug_level,"i");
MODULE_PARM_DESC(debug_level,
            "debug level - 0 off; 1 normal; 2,3 more verbose");

int init_module(void)
{
	return i2c_algo_mpc824x_init();
}

void cleanup_module(void)
{
#ifdef USE_HW_INT_FOR_XFER
	free_irq(HW_INT, NULL);
#endif
}
#endif
-------------- next part --------------
/*
    i2c-mpc824x.c - Adapter driver for I2C support on Motorola MPC824x

    Copyright (c) 2002 NetBotz Inc <primm@netbotz.com>

    Derived from i2c-via.c

    Copyright (c) 1998, 1999 Kysti M???kki <kmalkki@cc.hut.fi>

    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-mpc824x.h>
#include <linux/init.h>

#define DRV_VERSION	"0.1"

#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif

/* ----- local functions ----------------------------------------------	*/
static void i2c_mpc824x_inc(struct i2c_adapter *adapter)
{
	MOD_INC_USE_COUNT;
}

static void i2c_mpc824x_dec(struct i2c_adapter *adapter)
{
	MOD_DEC_USE_COUNT;
}

/* ------------------------------------------------------------------------ */

static struct i2c_algo_mpc824x_data i2c_mpc824x_data = { 0 };

static struct i2c_adapter i2c_mpc824x_ops = {
	"Motorola mpc824X i2c",
	I2C_HW_MPC824X,
	NULL,
	&i2c_mpc824x_data,
	i2c_mpc824x_inc,
	i2c_mpc824x_dec,
	NULL,
	NULL,
};

#ifdef MODULE
static
#else
extern
#endif
int __init i2c_mpc824x_init(void)
{
	printk("i2c-mpc824x.o version %s\n", DRV_VERSION);
	if (i2c_mpc824x_add_bus(&i2c_mpc824x_ops) = 0) {
		printk("i2c-mpc824x.o: Module succesfully loaded\n");
		return 0;
	} else {
		printk("i2c-mpc824x.o: Algo-mpc824x error, couldn't register bus\n");
		return -ENODEV;
	}
}

EXPORT_NO_SYMBOLS;

#ifdef MODULE
MODULE_AUTHOR("Michael Primm <primm@netbotz.com>");
MODULE_DESCRIPTION("i2c for Motorola mpc824x");

int init_module(void)
{
	return i2c_mpc824x_init();
}

void cleanup_module(void)
{
	i2c_mpc824x_del_bus(&i2c_mpc824x_ops);
}
#endif
-------------- next part --------------
/* ------------------------------------------------------------------------- */
/* i2c-algo-mpc824x.h i2c driver algorithms for Motorola mpc824x processors  */
/* ------------------------------------------------------------------------- */
/*   Copyright (C) 2002 NetBotz Inc <primm@netbotz.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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
/* ------------------------------------------------------------------------- */

/* $Id: i2c-algo-mpc824x.h,v 1.5 2003/02/10 06:08:11 primm Exp $ */

#ifndef I2C_ALGO_MPC824X_H
#define I2C_ALGO_MPC824X_H 1

#include <linux/i2c.h>

/* --- Defines for mpc824x-adapters ----------------------------------	*/

/* Structures for I2C registers					        */

/* I2C Address Register							*/
union i2c_mpc824x_i2cadr {
	struct {
		u32	reserved : 24;
		/* Slave address					*/
		u32	addr : 7;
		u32	reserved2 : 1;
	} bits;
	u32	reg;
};

/* I2C Frequency Divider Register					*/
union i2c_mpc824x_i2cfdr {
	struct {
		u32	reserved : 18;
		/* Digital filter frequency sampling rate		*/
		u32	dffsr : 6;
		u32	reserved2 : 2;
		/* Frequency divider ratio				*/
		u32	fdr : 6;
	} bits;
	u32	reg;
};

/* I2C Control Register							*/
union i2c_mpc824x_i2ccr {
	struct {
		u32	reserved : 24;
		/* Module enable					*/
		u32	men : 1;
		/* Module interrupt enable				*/
		u32	mien : 1;
		/* Master/slave mode START				*/
		u32	msta : 1;
		/* Transmit/receive mode select				*/
		u32	mtx : 1;
		/* Transfer acknowledge					*/
		u32	txak : 1;
		/* Repeat START						*/
		u32	rsta : 1;
		/* PCI interrupt enable					*/
		u32	pcii : 1;
		/* Broadcast enable					*/
		u32	bcst : 1;
	} bits;
	u32 reg;
};
	
/* I2C Status Register							*/
union i2c_mpc824x_i2csr {
	struct {
		u32	reserved : 24;
		/* Data transferring					*/
		u32	mcf : 1;
		/* Addressed as a slave					*/
		u32	maas : 1;
		/* Bus busy						*/
		u32	mbb : 1;
		/* Arbitration lost					*/
		u32	mal : 1;
		/* Broadcast address detection				*/
		u32	bca : 1;
		/* Slave read/write					*/
		u32	srw : 1;
		/* Module interrupt					*/
		u32	mif : 1;
		/* Received acknowledge					*/
		u32	rxak : 1;
	} bits;
	u32	reg;
};

/* I2C Data Register							*/
union i2c_mpc824x_i2cdr {
	struct {
		u32	reserved : 24;
		/* Data register					*/
		u32	data : 8;
	} bits;
	u32	reg;
};

/*
 * This struct contains the hardware specific information for the port.
 */
struct i2c_algo_mpc824x_data {
	/* State of current transfer					*/
	int	is_xmit;	/* 1 = XMIT, 0 = RECV			*/
	u8 *	buffer;		/* xmit/recv buffer for data		*/
	int	buflen;		/* Length of buffer recv/xmit		*/
	int	bufindex;	/* Current index into buffer		*/
	u8	slaveaddr;	/* Current slave address		*/
	u8	stop_when_done;	/* 1=do STOP when completed		*/
	u8	is_restart;	/* Are we doing a repeat start		*/
	u8	is_rcv_addr;	/* Is receive address phase		*/
};

#define I2C_BIT_ADAP_MAX	16

int i2c_mpc824x_add_bus(struct i2c_adapter *);
int i2c_mpc824x_del_bus(struct i2c_adapter *);

#ifdef CONFIG_RAPTOR
void i2c_mpc824x_do_cmds(void *eumb_addr, struct i2c_msg msgs[],
	int num);
/* Special entry point used for I2C commands issued for modules		*/
void i2c_mpc824x_do_cmds_async(struct i2c_msg *msgs,
	int num, void (*callback)(struct i2c_adapter *, struct i2c_msg *, 
	int num, int rc, void *usr_data), void *usr_data);
#endif

#endif /* I2C_ALGO_MPC824X_H */
-------------- next part --------------
/* ------------------------------------------------------------------------- */
/* 									     */
/* i2c.h - definitions for the i2c-bus interface			     */
/* 									     */
/* ------------------------------------------------------------------------- */
/*   Copyright (C) 1995-1999 Simon G. Vogl

    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.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
/* ------------------------------------------------------------------------- */

/* $Id: i2c-id.h,v 1.3 2003/02/21 23:35:04 primm Exp $ */

#ifndef I2C_ID_H
#define I2C_ID_H
/*
 * This file is part of the i2c-bus package and contains the identifier
 * values for drivers, adapters and other folk populating these serial
 * worlds. 
 *
 * These will change often (i.e. additions) , therefore this has been 
 * separated from the functional interface definitions of the i2c api.
 *
 */

/*
 * ---- Driver types -----------------------------------------------------
 *       device id name + number        function description, i2c address(es)
 *
 *  Range 1000-1999 range is defined in sensors/sensors.h 
 *  Range 0x100 - 0x1ff is for V4L2 Common Components 
 *  Range 0xf000 - 0xffff is reserved for local experimentation, and should
 *        never be used in official drivers 
 */

#define I2C_DRIVERID_MSP3400	 1
#define I2C_DRIVERID_TUNER	 2
#define I2C_DRIVERID_VIDEOTEX	 3	/* please rename		*/
#define I2C_DRIVERID_TDA8425	 4	/* stereo sound processor	*/
#define I2C_DRIVERID_TEA6420	 5	/* audio matrix switch		*/
#define I2C_DRIVERID_TEA6415C	 6	/* video matrix switch		*/
#define I2C_DRIVERID_TDA9840	 7	/* stereo sound processor	*/
#define I2C_DRIVERID_SAA7111A	 8	/* video input processor	*/
#define I2C_DRIVERID_SAA5281	 9	/* videotext decoder		*/
#define I2C_DRIVERID_SAA7112	10	/* video decoder, image scaler	*/
#define I2C_DRIVERID_SAA7120	11	/* video encoder		*/
#define I2C_DRIVERID_SAA7121	12	/* video encoder		*/
#define I2C_DRIVERID_SAA7185B	13	/* video encoder		*/
#define I2C_DRIVERID_CH7003	14	/* digital pc to tv encoder 	*/
#define I2C_DRIVERID_PCF8574A	15	/* i2c expander - 8 bit in/out	*/
#define I2C_DRIVERID_PCF8582C	16	/* eeprom			*/
#define I2C_DRIVERID_AT24Cxx	17	/* eeprom 1/2/4/8/16 K 		*/
#define I2C_DRIVERID_TEA6300	18	/* audio mixer			*/
#define I2C_DRIVERID_BT829	19	/* pc to tv encoder		*/
#define I2C_DRIVERID_TDA9850	20	/* audio mixer			*/
#define I2C_DRIVERID_TDA9855	21	/* audio mixer			*/
#define I2C_DRIVERID_SAA7110	22	/* video decoder		*/
#define I2C_DRIVERID_MGATVO	23	/* Matrox TVOut			*/
#define I2C_DRIVERID_SAA5249	24	/* SAA5249 and compatibles	*/
#define I2C_DRIVERID_PCF8583	25	/* real time clock		*/
#define I2C_DRIVERID_SAB3036	26	/* SAB3036 tuner		*/
#define I2C_DRIVERID_TDA7432	27	/* Stereo sound processor	*/
#define I2C_DRIVERID_TVMIXER    28      /* Mixer driver for tv cards    */
#define I2C_DRIVERID_TVAUDIO    29      /* Generic TV sound driver      */
#define I2C_DRIVERID_DPL3518    30      /* Dolby decoder chip           */
#define I2C_DRIVERID_TDA9873    31      /* TV sound decoder chip        */
#define I2C_DRIVERID_TDA9875    32      /* TV sound decoder chip        */
#define I2C_DRIVERID_PIC16C54_PV9 33    /* Audio mux/ir receiver        */

#define I2C_DRIVERID_SBATT      34     /* Smart Battery Device		*/
#define I2C_DRIVERID_SBS        35     /* SB System Manager		*/
#define I2C_DRIVERID_VES1893	36     /* VLSI DVB-S decoder		*/
#define I2C_DRIVERID_VES1820	37     /* VLSI DVB-C decoder		*/
#define I2C_DRIVERID_SAA7113	38     /* video decoder			*/
#define I2C_DRIVERID_TDA8444	39     /* octuple 6-bit DAC             */
#define I2C_DRIVERID_BT819	40     /* video decoder			*/
#define I2C_DRIVERID_BT856	41     /* video encoder			*/
#define I2C_DRIVERID_VPX32XX	42     /* video decoder+vbi/vtxt	*/
#define I2C_DRIVERID_DRP3510	43     /* ADR decoder (Astra Radio)	*/
#define I2C_DRIVERID_SP5055	44     /* Satellite tuner		*/
#define I2C_DRIVERID_STV0030	45     /* Multipurpose switch		*/

#define I2C_DRIVERID_EXP0	0xF0	/* experimental use id's	*/
#define I2C_DRIVERID_EXP1	0xF1
#define I2C_DRIVERID_EXP2	0xF2
#define I2C_DRIVERID_EXP3	0xF3

#define I2C_DRIVERID_I2CDEV	900
#define I2C_DRIVERID_I2CPROC	901

/* IDs --   Use DRIVERIDs 1000-1999 for sensors. 
   These were originally in sensors.h in the lm_sensors package */
#define I2C_DRIVERID_LM78 1002
#define I2C_DRIVERID_LM75 1003
#define I2C_DRIVERID_GL518 1004
#define I2C_DRIVERID_EEPROM 1005
#define I2C_DRIVERID_W83781D 1006
#define I2C_DRIVERID_LM80 1007
#define I2C_DRIVERID_ADM1021 1008
#define I2C_DRIVERID_ADM9240 1009
#define I2C_DRIVERID_LTC1710 1010
#define I2C_DRIVERID_SIS5595 1011
#define I2C_DRIVERID_ICSPLL 1012
#define I2C_DRIVERID_BT869 1013
#define I2C_DRIVERID_MAXILIFE 1014
#define I2C_DRIVERID_MATORB 1015
#define I2C_DRIVERID_GL520 1016
#define I2C_DRIVERID_THMC50 1017
#define I2C_DRIVERID_DDCMON 1018
#define I2C_DRIVERID_VIA686A 1019
#define I2C_DRIVERID_ADM1025 1020
#define I2C_DRIVERID_LM87 1021
#define I2C_DRIVERID_PCF8574 1022
#define I2C_DRIVERID_MTP008 1023
#define I2C_DRIVERID_DS1621 1024
#define I2C_DRIVERID_ADM1024 1025
#define I2C_DRIVERID_IT87 1026
#define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */

/*
 * ---- Adapter types ----------------------------------------------------
 *
 * First, we distinguish between several algorithms to access the hardware
 * interface types, as a PCF 8584 needs other care than a bit adapter.
 */

#define I2C_ALGO_NONE	0x000000
#define I2C_ALGO_BIT	0x010000	/* bit style adapters		*/
#define I2C_ALGO_PCF	0x020000	/* PCF 8584 style adapters	*/
#define I2C_ALGO_ATI	0x030000	/* ATI video card		*/
#define I2C_ALGO_SMBUS	0x040000
#define I2C_ALGO_ISA 	0x050000	/* lm_sensors ISA pseudo-adapter */
#define I2C_ALGO_SAA7146 0x060000	/* SAA 7146 video decoder bus	*/
#define I2C_ALGO_ACB 	0x070000	/* ACCESS.bus algorithm         */
#define I2C_ALGO_MPC824X 0x0a0000       /* Motorola MPC824x             */
#define I2C_ALGO_EC     0x100000        /* ACPI embedded controller     */

#define I2C_ALGO_MPC8XX 0x110000	/* MPC8xx PowerPC I2C algorithm */
#define I2C_HW_MPC824X  0x00            /* Motorola 8240/8245           */
#define I2C_ALGO_EXP	0x800000	/* experimental			*/

#define I2C_ALGO_MASK	0xff0000	/* Mask for algorithms		*/
#define I2C_ALGO_SHIFT	0x10	/* right shift to get index values 	*/

#define I2C_HW_ADAPS	0x10000		/* # adapter types		*/
#define I2C_HW_MASK	0xffff		


/* hw specific modules that are defined per algorithm layer
 */

/* --- Bit algorithm adapters 						*/
#define I2C_HW_B_LP	0x00	/* Parallel port Philips style adapter	*/
#define I2C_HW_B_LPC	0x01	/* Parallel port, over control reg.	*/
#define I2C_HW_B_SER	0x02	/* Serial line interface		*/
#define I2C_HW_B_ELV	0x03	/* ELV Card				*/
#define I2C_HW_B_VELLE	0x04	/* Vellemann K8000			*/
#define I2C_HW_B_BT848	0x05	/* BT848 video boards			*/
#define I2C_HW_B_WNV	0x06	/* Winnov Videums			*/
#define I2C_HW_B_VIA	0x07	/* Via vt82c586b			*/
#define I2C_HW_B_HYDRA	0x08	/* Apple Hydra Mac I/O			*/
#define I2C_HW_B_G400	0x09	/* Matrox G400				*/
#define I2C_HW_B_I810	0x0a	/* Intel I810 				*/
#define I2C_HW_B_VOO	0x0b	/* 3dfx Voodoo 3 / Banshee      	*/
#define I2C_HW_B_PPORT  0x0c	/* Primitive parallel port adapter	*/
#define I2C_HW_B_RIVA	0x10	/* Riva based graphics cards		*/
#define I2C_HW_B_IOC	0x11	/* IOC bit-wiggling			*/
#define I2C_HW_B_TSUNA  0x12	/* DEC Tsunami chipset			*/

/* --- PCF 8584 based algorithms					*/
#define I2C_HW_P_LP	0x00	/* Parallel port interface		*/
#define I2C_HW_P_ISA	0x01	/* generic ISA Bus inteface card	*/
#define I2C_HW_P_ELEK	0x02	/* Elektor ISA Bus inteface card	*/

/* --- ACPI Embedded controller algorithms                              */
#define I2C_HW_ACPI_EC          0x00

/* --- MPC8xx PowerPC adapters						*/
#define I2C_HW_MPC8XX_EPON 0x00	/* Eponymous MPC8xx I2C adapter 	*/

/* --- SMBus only adapters						*/
#define I2C_HW_SMBUS_PIIX4	0x00
#define I2C_HW_SMBUS_ALI15X3	0x01
#define I2C_HW_SMBUS_VIA2	0x02
#define I2C_HW_SMBUS_VOODOO3	0x03
#define I2C_HW_SMBUS_I801	0x04
#define I2C_HW_SMBUS_AMD756	0x05
#define I2C_HW_SMBUS_SIS5595	0x06
#define I2C_HW_SMBUS_ALI1535	0x07

/* --- ISA pseudo-adapter						*/
#define I2C_HW_ISA 0x00

#endif /* I2C_ID_H */

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Fw: Question on I2C driver development for Motorola chips
  2005-05-19  6:24 Question on I2C driver development for Motorola chips Xiao Xianghua-r6aads
  2005-05-19  6:24 ` Fw: " Mike Primm
@ 2005-05-19  6:24 ` Mark Studebaker
  2005-05-19  6:24 ` Jean Delvare
  2 siblings, 0 replies; 4+ messages in thread
From: Mark Studebaker @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

Xianghua,
we appreciate your offer.
Of course any contribution must be GPL.
A consolidated driver would be helpful.
While we have PPC drivers in our tree, they may not get as much
use or maintenance as the drivers in the PPC-specific kernel branches
found elsewhere on the net.
You should consider where the best home for your consolidated
driver should be, and perhaps discuss it on the appropriate
PPC mailing list.

mds


Jean Delvare wrote:
> 
> Hi Michael,
> 
> Xianghua is trying to reach you to share your works on Motorola MPC
> drivers, so I am forwarding his message to you so that you can get in
> touch.
> 
> Begin forwarded message:
> 
> Date: Tue, 21 Oct 2003 13:10:26 -0700
> From: Xiao Xianghua-r6aads <X.Xiao@motorola.com>
> To: "'sensors@stimpy.netroedge.com'" <sensors@Stimpy.netroedge.com>
> Cc: Xiao Xianghua-r6aads <X.Xiao@motorola.com>
> Subject: Question on I2C driver development for Motorola chips
> 
> Hello,
> 
> I'm an engineer working in Motorola. I have a 'working' I2C driver for
> the new chip MPC8540/MPC8560 and I'm eager to add this driver to your
> CVS, and I hope it can be pushed to the linux kernel in the near future.
> 
> I noticed a MPC8245 I2C driver is under development by Mike Primm from
> your newdriver
> webpage(http://secure.netroedge.com/%7Elm78/newdrivers.html), and I'm
> very interested in his progress, however there is no way for me to reach
> him(there is no email address :( ). Additionally, there is another Linux
> I2C driver for MPC824x(http://www.humboldt.co.uk/mpc10xi2c.html).
> Include my driver, all of us are trying to do the same thing because
> MPC8540/MPC8560/MPC824x/MPC107 are having the similar I2C design. I
> would like to find a way to provide a generic I2C for all these Motorola
> chips.
> 
> I'm also interested in getting the current Motorola 8xx I2C driver a new
> name if possible, because that driver can also be shared by
> 8xx/82xx/83xx(forthcoming new chip), i.e. any Motorola chip with a
> CPM(Communication Process Module) part on it.
> 
> Thanks a lot for your helps.
> 
> Xianghua
> 
> --
> Jean Delvare
> http://www.ensicaen.ismra.fr/~delvare/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-05-19  6:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-19  6:24 Question on I2C driver development for Motorola chips Xiao Xianghua-r6aads
2005-05-19  6:24 ` Fw: " Mike Primm
2005-05-19  6:24 ` Mark Studebaker
2005-05-19  6:24 ` Jean Delvare

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.