don't know what happened, thought I posted this yesterday...
I have attached the sample code. I was using gpio14/15 for my i2c
bus. change the 6 defines to change it to what you are using.
this uses the i2c-algo-bit driver which in turn uses the i2c-core
driver, so both of these must be built in to the kernel or loaded as
modules.
PS I know the driver use save_flags/cli/restore_flags rather than
the current method of spin_lock_irqsave / spin_unlock_irqrestore.
just never updated it
//-------------------------------------------------------------------
----------
// $RCSfile: i2c-ep93xx.c,v $
// $Revision: 1.1 $
// See End of File for Modification History
//
/// \brief
/// i2c device driver using the gpio ports on a cirrus Ep93xx
device
//-------------------------------------------------------------------
---------
/// derived from i2c-guide.c
/********************************************************************
****************\
Copyright : Copyright (C) 1995-2000 Simon G. Vogl
Copyright 2002 IDERs Incorporated
File Name : i2c-guide.c
Description : this i2c driver uses the GPIO port B pin 0 and pin
1 on the cs89712.
Notes : To change the bit rate, change the structure
i2c_algo_bit_data
: to 10 10 100
Contact :
License : This source code is free software; you can
redistribute it and/or
modify it under the terms of the GNU General
Public License
version 2 as published by the Free Software
Foundation.
\********************************************************************
****************/
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h> /* for 2.0 kernels to get NULL */
#include <asm/errno.h> /* for 2.0 kernels to get ENODEV */
#include <asm/io.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
/* ----- global defines ---------------------------------------------
-- */
#define DEB(x) /* should be reasonable open, close &c.
*/
#define DEB2(x) /* low level debugging - very slow
*/
#define DEBE(x) x /* error messages
*/
#define I2C_SDA_PORT GPIO_PBDR
#define I2C_SDA_DIR GPIO_PBDDR
#define I2C_SDA_MASK 0x80 /* EGPIO14 (port B bit 6)*/
#define I2C_SCL_PORT GPIO_PBDR
#define I2C_SCL_DIR GPIO_PBDDR
#define I2C_SCL_MASK 0x40 /* EGPIO15 (port B bit 7)*/
#ifndef I2C_HW_B_EP93XX
# define I2C_HW_B_EP93XX 0xffff
#endif
/* ----- local functions --------------------------------------------
------- */
//===================================================================
========
/// \brief write SCL pin
//===================================================================
========
static void bit_ep93xx_setscl(void* data, int state)
{
unsigned long flags;
save_flags(flags);
if (state)
{
cli();
outl(inl(I2C_SCL_DIR) & ~I2C_SCL_MASK,
I2C_SCL_DIR); // tristate pin
outl(inl(I2C_SCL_PORT) | I2C_SCL_MASK,
I2C_SCL_PORT); // drive pin
}
else
{
cli();
outl(inl(I2C_SCL_PORT) & ~I2C_SCL_MASK,
I2C_SCL_PORT); // drive pin
outl(inl(I2C_SCL_DIR) | I2C_SCL_MASK,
I2C_SCL_DIR); // enable pin
}
restore_flags(flags);
}
//===================================================================
========
/// \brief write SCL pin
//===================================================================
========
static void bit_ep93xx_setsda(void* data, int state)
{
unsigned long flags;
save_flags(flags);
if (state) {
cli();
outl(inl(I2C_SDA_PORT) | I2C_SDA_MASK,
I2C_SDA_PORT); // drive pin
outl(inl(I2C_SDA_DIR) & ~I2C_SDA_MASK,
I2C_SDA_DIR); // tristate pin
}
else
{
cli();
outl(inl(I2C_SDA_PORT) & ~I2C_SDA_MASK,
I2C_SDA_PORT); // drive pin
outl(inl(I2C_SDA_DIR) | I2C_SDA_MASK,
I2C_SDA_DIR); // enable pin
}
restore_flags(flags);
}
//===================================================================
========
/// \brief read SCL pin
//===================================================================
========
static int bit_ep93xx_getscl(void *data)
{
return ( (inl(I2C_SCL_PORT) & I2C_SCL_MASK) != 0);
}
//===================================================================
========
/// \brief read SDA pin
//===================================================================
========
static int bit_ep93xx_getsda(void *data)
{
return ( (inl(I2C_SDA_PORT) & I2C_SDA_MASK) != 0 );
}
static int bit_ep93xx_reg(struct i2c_client *client)
{
return 0;
}
static int bit_ep93xx_unreg(struct i2c_client *client)
{
return 0;
}
static void bit_ep93xx_inc_use(struct i2c_adapter *adap)
{
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
}
static void bit_ep93xx_dec_use(struct i2c_adapter *adap)
{
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
}
/* ------------------------------------------------------------------
------
* Encapsulate the above functions in the correct operations
structure.
* This is only done when more than one hardware adapter is
supported.
*/
/* last line (us, ms, timout)
* us dominates the bit rate: 10us means: 100Kbit/sec(25 means
40kbps)
* 10ms not known
* 100ms timeout
*/
static struct i2c_algo_bit_data bit_ep93xx_data = {
NULL,
bit_ep93xx_setsda,
bit_ep93xx_setscl,
bit_ep93xx_getsda,
bit_ep93xx_getscl,
/* bit delay us */ 30,
/* byte delay ms (not used?) */ 10 ,
/* bit timeout in jiffies (us) (may be reset by algo)*/ 100,
};
static struct i2c_adapter bit_ep93xx_ops = {
"ep93xx I2C",
I2C_HW_B_EP93XX,
NULL,
&bit_ep93xx_data,
bit_ep93xx_inc_use,
bit_ep93xx_dec_use,
bit_ep93xx_reg,
bit_ep93xx_unreg,
};
//===================================================================
========
//===================================================================
========
static int __init i2c_ep93xx_init(void)
{
printk(KERN_DEBUG"i2c-ep93xx.o: i2c driver init.\n");
// set SCL/SDA to 1 (input)
bit_ep93xx_setscl(NULL, 1);
bit_ep93xx_setsda(NULL, 1);
if(i2c_bit_add_bus(&bit_ep93xx_ops) < 0)
return -ENODEV;
return 0;
}
//===================================================================
========
//===================================================================
========
static void __exit i2c_ep93xx_exit(void)
{
}
EXPORT_NO_SYMBOLS;
MODULE_AUTHOR("msw
MODULE_DESCRIPTION("I2C-Bus routines for EP93xx");
MODULE_LICENSE("GPL");
module_init(i2c_ep93xx_init);
module_exit(i2c_ep93xx_exit);
//-------------------------------------------------------------------
-----------
// Modification History:
// $Log: i2c-ep93xx.c,v $
// Revision 1.1 2006/01/27 02:06:18 msw
// creation
//
//
//-------------------------------------------------------------------
-----------
--- In wrote:
>
> Thanks, I was hoping it would be easy. If you have code I can look
at, I would
> be very happy to have it. I am just getting ready to get the
board, and trying
> to nail down the software requirements for my first application.
>
>
> Tom
>
>
> Quoting john bogus <>:
>
> > --- In linux@ wrote:
> > >
> > > I am considering serial interface options on a TS-7260. I am
> > looking at some
> > > sensors with SPI and I2C interfaces. I know I can use the SPI
> > device, but is
> > > there a way to interface to I2C devices? Fewer wires is a plus
in
> > this application.
> > >
> > > Thanks,
> > >
> > > Tom
> > >
> >
> > worse case -> you write the adpter driver to use the gpio pins
(a
> > small task) on the i2c-algo-bit algorithm drivers. This will
use
> > two gpio pins to bit-bash the i2c tansactions.
> >
> > see Documentation/i2c/summary in the linux tree for references.
> >
> > If you need it I can provide some sample code.
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|