Path: blob/master/arch/cris/arch-v10/drivers/i2c.c
15126 views
/*!***************************************************************************1*!2*! FILE NAME : i2c.c3*!4*! DESCRIPTION: implements an interface for IIC/I2C, both directly from other5*! kernel modules (i2c_writereg/readreg) and from userspace using6*! ioctl()'s7*!8*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN9*!10*!***************************************************************************/1112/****************** INCLUDE FILES SECTION ***********************************/1314#include <linux/module.h>15#include <linux/sched.h>16#include <linux/errno.h>17#include <linux/kernel.h>18#include <linux/fs.h>19#include <linux/string.h>20#include <linux/init.h>2122#include <asm/etraxi2c.h>2324#include <asm/system.h>25#include <arch/svinto.h>26#include <asm/io.h>27#include <asm/delay.h>28#include <arch/io_interface_mux.h>2930#include "i2c.h"3132/****************** I2C DEFINITION SECTION *************************/3334#define D(x)3536#define I2C_MAJOR 123 /* LOCAL/EXPERIMENTAL */37static const char i2c_name[] = "i2c";3839#define CLOCK_LOW_TIME 840#define CLOCK_HIGH_TIME 841#define START_CONDITION_HOLD_TIME 842#define STOP_CONDITION_HOLD_TIME 843#define ENABLE_OUTPUT 0x0144#define ENABLE_INPUT 0x0045#define I2C_CLOCK_HIGH 146#define I2C_CLOCK_LOW 047#define I2C_DATA_HIGH 148#define I2C_DATA_LOW 04950#ifdef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C51/* Use PB and not PB_I2C */52#ifndef CONFIG_ETRAX_I2C_DATA_PORT53#define CONFIG_ETRAX_I2C_DATA_PORT 054#endif55#ifndef CONFIG_ETRAX_I2C_CLK_PORT56#define CONFIG_ETRAX_I2C_CLK_PORT 157#endif5859#define SDABIT CONFIG_ETRAX_I2C_DATA_PORT60#define SCLBIT CONFIG_ETRAX_I2C_CLK_PORT61#define i2c_enable()62#define i2c_disable()6364/* enable or disable output-enable, to select output or input on the i2c bus */6566#define i2c_dir_out() \67REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 1)68#define i2c_dir_in() \69REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, SDABIT, 0)7071/* control the i2c clock and data signals */7273#define i2c_clk(x) \74REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SCLBIT, x)75#define i2c_data(x) \76REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, SDABIT, x)7778/* read a bit from the i2c interface */7980#define i2c_getbit() (((*R_PORT_PB_READ & (1 << SDABIT))) >> SDABIT)8182#else83/* enable or disable the i2c interface */8485#define i2c_enable() *R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_en))86#define i2c_disable() *R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_en))8788/* enable or disable output-enable, to select output or input on the i2c bus */8990#define i2c_dir_out() \91*R_PORT_PB_I2C = (port_pb_i2c_shadow &= ~IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \92REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 1);93#define i2c_dir_in() \94*R_PORT_PB_I2C = (port_pb_i2c_shadow |= IO_MASK(R_PORT_PB_I2C, i2c_oe_)); \95REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, 0, 0);9697/* control the i2c clock and data signals */9899#define i2c_clk(x) \100*R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \101~IO_MASK(R_PORT_PB_I2C, i2c_clk)) | IO_FIELD(R_PORT_PB_I2C, i2c_clk, (x))); \102REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 1, x);103104#define i2c_data(x) \105*R_PORT_PB_I2C = (port_pb_i2c_shadow = (port_pb_i2c_shadow & \106~IO_MASK(R_PORT_PB_I2C, i2c_d)) | IO_FIELD(R_PORT_PB_I2C, i2c_d, (x))); \107REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 0, x);108109/* read a bit from the i2c interface */110111#define i2c_getbit() (*R_PORT_PB_READ & 0x1)112#endif113114/* use the kernels delay routine */115116#define i2c_delay(usecs) udelay(usecs)117118static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */119120/****************** FUNCTION DEFINITION SECTION *************************/121122123/* generate i2c start condition */124125void126i2c_start(void)127{128/*129* SCL=1 SDA=1130*/131i2c_dir_out();132i2c_delay(CLOCK_HIGH_TIME/6);133i2c_data(I2C_DATA_HIGH);134i2c_clk(I2C_CLOCK_HIGH);135i2c_delay(CLOCK_HIGH_TIME);136/*137* SCL=1 SDA=0138*/139i2c_data(I2C_DATA_LOW);140i2c_delay(START_CONDITION_HOLD_TIME);141/*142* SCL=0 SDA=0143*/144i2c_clk(I2C_CLOCK_LOW);145i2c_delay(CLOCK_LOW_TIME);146}147148/* generate i2c stop condition */149150void151i2c_stop(void)152{153i2c_dir_out();154155/*156* SCL=0 SDA=0157*/158i2c_clk(I2C_CLOCK_LOW);159i2c_data(I2C_DATA_LOW);160i2c_delay(CLOCK_LOW_TIME*2);161/*162* SCL=1 SDA=0163*/164i2c_clk(I2C_CLOCK_HIGH);165i2c_delay(CLOCK_HIGH_TIME*2);166/*167* SCL=1 SDA=1168*/169i2c_data(I2C_DATA_HIGH);170i2c_delay(STOP_CONDITION_HOLD_TIME);171172i2c_dir_in();173}174175/* write a byte to the i2c interface */176177void178i2c_outbyte(unsigned char x)179{180int i;181182i2c_dir_out();183184for (i = 0; i < 8; i++) {185if (x & 0x80) {186i2c_data(I2C_DATA_HIGH);187} else {188i2c_data(I2C_DATA_LOW);189}190191i2c_delay(CLOCK_LOW_TIME/2);192i2c_clk(I2C_CLOCK_HIGH);193i2c_delay(CLOCK_HIGH_TIME);194i2c_clk(I2C_CLOCK_LOW);195i2c_delay(CLOCK_LOW_TIME/2);196x <<= 1;197}198i2c_data(I2C_DATA_LOW);199i2c_delay(CLOCK_LOW_TIME/2);200201/*202* enable input203*/204i2c_dir_in();205}206207/* read a byte from the i2c interface */208209unsigned char210i2c_inbyte(void)211{212unsigned char aBitByte = 0;213int i;214215/* Switch off I2C to get bit */216i2c_disable();217i2c_dir_in();218i2c_delay(CLOCK_HIGH_TIME/2);219220/* Get bit */221aBitByte |= i2c_getbit();222223/* Enable I2C */224i2c_enable();225i2c_delay(CLOCK_LOW_TIME/2);226227for (i = 1; i < 8; i++) {228aBitByte <<= 1;229/* Clock pulse */230i2c_clk(I2C_CLOCK_HIGH);231i2c_delay(CLOCK_HIGH_TIME);232i2c_clk(I2C_CLOCK_LOW);233i2c_delay(CLOCK_LOW_TIME);234235/* Switch off I2C to get bit */236i2c_disable();237i2c_dir_in();238i2c_delay(CLOCK_HIGH_TIME/2);239240/* Get bit */241aBitByte |= i2c_getbit();242243/* Enable I2C */244i2c_enable();245i2c_delay(CLOCK_LOW_TIME/2);246}247i2c_clk(I2C_CLOCK_HIGH);248i2c_delay(CLOCK_HIGH_TIME);249250/*251* we leave the clock low, getbyte is usually followed252* by sendack/nack, they assume the clock to be low253*/254i2c_clk(I2C_CLOCK_LOW);255return aBitByte;256}257258/*#---------------------------------------------------------------------------259*#260*# FUNCTION NAME: i2c_getack261*#262*# DESCRIPTION : checks if ack was received from ic2263*#264*#--------------------------------------------------------------------------*/265266int267i2c_getack(void)268{269int ack = 1;270/*271* enable output272*/273i2c_dir_out();274/*275* Release data bus by setting276* data high277*/278i2c_data(I2C_DATA_HIGH);279/*280* enable input281*/282i2c_dir_in();283i2c_delay(CLOCK_HIGH_TIME/4);284/*285* generate ACK clock pulse286*/287i2c_clk(I2C_CLOCK_HIGH);288/*289* Use PORT PB instead of I2C290* for input. (I2C not working)291*/292i2c_clk(1);293i2c_data(1);294/*295* switch off I2C296*/297i2c_data(1);298i2c_disable();299i2c_dir_in();300/*301* now wait for ack302*/303i2c_delay(CLOCK_HIGH_TIME/2);304/*305* check for ack306*/307if(i2c_getbit())308ack = 0;309i2c_delay(CLOCK_HIGH_TIME/2);310if(!ack){311if(!i2c_getbit()) /* receiver pulld SDA low */312ack = 1;313i2c_delay(CLOCK_HIGH_TIME/2);314}315316/*317* our clock is high now, make sure data is low318* before we enable our output. If we keep data high319* and enable output, we would generate a stop condition.320*/321i2c_data(I2C_DATA_LOW);322323/*324* end clock pulse325*/326i2c_enable();327i2c_dir_out();328i2c_clk(I2C_CLOCK_LOW);329i2c_delay(CLOCK_HIGH_TIME/4);330/*331* enable output332*/333i2c_dir_out();334/*335* remove ACK clock pulse336*/337i2c_data(I2C_DATA_HIGH);338i2c_delay(CLOCK_LOW_TIME/2);339return ack;340}341342/*#---------------------------------------------------------------------------343*#344*# FUNCTION NAME: I2C::sendAck345*#346*# DESCRIPTION : Send ACK on received data347*#348*#--------------------------------------------------------------------------*/349void350i2c_sendack(void)351{352/*353* enable output354*/355i2c_delay(CLOCK_LOW_TIME);356i2c_dir_out();357/*358* set ack pulse high359*/360i2c_data(I2C_DATA_LOW);361/*362* generate clock pulse363*/364i2c_delay(CLOCK_HIGH_TIME/6);365i2c_clk(I2C_CLOCK_HIGH);366i2c_delay(CLOCK_HIGH_TIME);367i2c_clk(I2C_CLOCK_LOW);368i2c_delay(CLOCK_LOW_TIME/6);369/*370* reset data out371*/372i2c_data(I2C_DATA_HIGH);373i2c_delay(CLOCK_LOW_TIME);374375i2c_dir_in();376}377378/*#---------------------------------------------------------------------------379*#380*# FUNCTION NAME: i2c_sendnack381*#382*# DESCRIPTION : Sends NACK on received data383*#384*#--------------------------------------------------------------------------*/385void386i2c_sendnack(void)387{388/*389* enable output390*/391i2c_delay(CLOCK_LOW_TIME);392i2c_dir_out();393/*394* set data high395*/396i2c_data(I2C_DATA_HIGH);397/*398* generate clock pulse399*/400i2c_delay(CLOCK_HIGH_TIME/6);401i2c_clk(I2C_CLOCK_HIGH);402i2c_delay(CLOCK_HIGH_TIME);403i2c_clk(I2C_CLOCK_LOW);404i2c_delay(CLOCK_LOW_TIME);405406i2c_dir_in();407}408409/*#---------------------------------------------------------------------------410*#411*# FUNCTION NAME: i2c_writereg412*#413*# DESCRIPTION : Writes a value to an I2C device414*#415*#--------------------------------------------------------------------------*/416int417i2c_writereg(unsigned char theSlave, unsigned char theReg,418unsigned char theValue)419{420int error, cntr = 3;421unsigned long flags;422423spin_lock(&i2c_lock);424425do {426error = 0;427/*428* we don't like to be interrupted429*/430local_irq_save(flags);431432i2c_start();433/*434* send slave address435*/436i2c_outbyte((theSlave & 0xfe));437/*438* wait for ack439*/440if(!i2c_getack())441error = 1;442/*443* now select register444*/445i2c_dir_out();446i2c_outbyte(theReg);447/*448* now it's time to wait for ack449*/450if(!i2c_getack())451error |= 2;452/*453* send register register data454*/455i2c_outbyte(theValue);456/*457* now it's time to wait for ack458*/459if(!i2c_getack())460error |= 4;461/*462* end byte stream463*/464i2c_stop();465/*466* enable interrupt again467*/468local_irq_restore(flags);469470} while(error && cntr--);471472i2c_delay(CLOCK_LOW_TIME);473474spin_unlock(&i2c_lock);475476return -error;477}478479/*#---------------------------------------------------------------------------480*#481*# FUNCTION NAME: i2c_readreg482*#483*# DESCRIPTION : Reads a value from the decoder registers.484*#485*#--------------------------------------------------------------------------*/486unsigned char487i2c_readreg(unsigned char theSlave, unsigned char theReg)488{489unsigned char b = 0;490int error, cntr = 3;491unsigned long flags;492493spin_lock(&i2c_lock);494495do {496error = 0;497/*498* we don't like to be interrupted499*/500local_irq_save(flags);501/*502* generate start condition503*/504i2c_start();505506/*507* send slave address508*/509i2c_outbyte((theSlave & 0xfe));510/*511* wait for ack512*/513if(!i2c_getack())514error = 1;515/*516* now select register517*/518i2c_dir_out();519i2c_outbyte(theReg);520/*521* now it's time to wait for ack522*/523if(!i2c_getack())524error = 1;525/*526* repeat start condition527*/528i2c_delay(CLOCK_LOW_TIME);529i2c_start();530/*531* send slave address532*/533i2c_outbyte(theSlave | 0x01);534/*535* wait for ack536*/537if(!i2c_getack())538error = 1;539/*540* fetch register541*/542b = i2c_inbyte();543/*544* last received byte needs to be nacked545* instead of acked546*/547i2c_sendnack();548/*549* end sequence550*/551i2c_stop();552/*553* enable interrupt again554*/555local_irq_restore(flags);556557} while(error && cntr--);558559spin_unlock(&i2c_lock);560561return b;562}563564static int565i2c_open(struct inode *inode, struct file *filp)566{567return 0;568}569570static int571i2c_release(struct inode *inode, struct file *filp)572{573return 0;574}575576/* Main device API. ioctl's to write or read to/from i2c registers.577*/578579static long i2c_ioctl(struct file *file, unsigned int cmd, unsigned long arg)580{581if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {582return -EINVAL;583}584585switch (_IOC_NR(cmd)) {586case I2C_WRITEREG:587/* write to an i2c slave */588D(printk(KERN_DEBUG "i2cw %d %d %d\n",589I2C_ARGSLAVE(arg),590I2C_ARGREG(arg),591I2C_ARGVALUE(arg)));592593return i2c_writereg(I2C_ARGSLAVE(arg),594I2C_ARGREG(arg),595I2C_ARGVALUE(arg));596case I2C_READREG:597{598unsigned char val;599/* read from an i2c slave */600D(printk(KERN_DEBUG "i2cr %d %d ",601I2C_ARGSLAVE(arg),602I2C_ARGREG(arg)));603val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));604D(printk(KERN_DEBUG "= %d\n", val));605return val;606}607default:608return -EINVAL;609610}611return 0;612}613614static const struct file_operations i2c_fops = {615.owner = THIS_MODULE,616.unlocked_ioctl = i2c_ioctl,617.open = i2c_open,618.release = i2c_release,619.llseek = noop_llseek,620};621622int __init623i2c_init(void)624{625static int res = 0;626static int first = 1;627628if (!first) {629return res;630}631first = 0;632633/* Setup and enable the Port B I2C interface */634635#ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C636if ((res = cris_request_io_interface(if_i2c, "I2C"))) {637printk(KERN_CRIT "i2c_init: Failed to get IO interface\n");638return res;639}640641*R_PORT_PB_I2C = port_pb_i2c_shadow |=642IO_STATE(R_PORT_PB_I2C, i2c_en, on) |643IO_FIELD(R_PORT_PB_I2C, i2c_d, 1) |644IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1) |645IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable);646647port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0);648port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1);649650*R_PORT_PB_DIR = (port_pb_dir_shadow |=651IO_STATE(R_PORT_PB_DIR, dir0, input) |652IO_STATE(R_PORT_PB_DIR, dir1, output));653#else654if ((res = cris_io_interface_allocate_pins(if_i2c,655'b',656CONFIG_ETRAX_I2C_DATA_PORT,657CONFIG_ETRAX_I2C_DATA_PORT))) {658printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C data port\n");659return res;660} else if ((res = cris_io_interface_allocate_pins(if_i2c,661'b',662CONFIG_ETRAX_I2C_CLK_PORT,663CONFIG_ETRAX_I2C_CLK_PORT))) {664cris_io_interface_free_pins(if_i2c,665'b',666CONFIG_ETRAX_I2C_DATA_PORT,667CONFIG_ETRAX_I2C_DATA_PORT);668printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C clk port\n");669}670#endif671672return res;673}674675static int __init676i2c_register(void)677{678int res;679680res = i2c_init();681if (res < 0)682return res;683res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);684if(res < 0) {685printk(KERN_ERR "i2c: couldn't get a major number.\n");686return res;687}688689printk(KERN_INFO "I2C driver v2.2, (c) 1999-2004 Axis Communications AB\n");690691return 0;692}693694/* this makes sure that i2c_register is called during boot */695696module_init(i2c_register);697698/****************** END OF FILE i2c.c ********************************/699700701