diff options
Diffstat (limited to 'drivers/i2c')
59 files changed, 1259 insertions, 498 deletions
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 24383afdda7..11935f66fcd 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -1,5 +1,5 @@ # -# Character device configuration +# I2C subsystem configuration # menu "I2C support" diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig index 30408015d23..c034820615b 100644 --- a/drivers/i2c/algos/Kconfig +++ b/drivers/i2c/algos/Kconfig @@ -53,12 +53,6 @@ config I2C_ALGO8XX tristate "MPC8xx CPM I2C interface" depends on 8xx && I2C -config I2C_ALGO_SIBYTE - tristate "SiByte SMBus interface" - depends on SIBYTE_SB1xxx_SOC && I2C - help - Supports the SiByte SOC on-chip I2C interfaces (2 channels). - config I2C_ALGO_SGI tristate "I2C SGI interfaces" depends on I2C && (SGI_IP22 || SGI_IP32 || X86_VISWS) diff --git a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile index 867fe1f6740..208be04a3db 100644 --- a/drivers/i2c/algos/Makefile +++ b/drivers/i2c/algos/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o obj-$(CONFIG_I2C_ALGOITE) += i2c-algo-ite.o -obj-$(CONFIG_I2C_ALGO_SIBYTE) += i2c-algo-sibyte.o obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o ifeq ($(CONFIG_I2C_DEBUG_ALGO),y) diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index df05df1a0ef..21c36bfb5e6 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -76,17 +76,15 @@ static inline void scllo(struct i2c_algo_bit_data *adap) * Raise scl line, and do checking for delays. This is necessary for slower * devices. */ -static inline int sclhi(struct i2c_algo_bit_data *adap) +static int sclhi(struct i2c_algo_bit_data *adap) { unsigned long start; setscl(adap,1); /* Not all adapters have scl sense line... */ - if (adap->getscl == NULL ) { - udelay(adap->udelay); - return 0; - } + if (!adap->getscl) + goto done; start=jiffies; while (! getscl(adap) ) { @@ -101,6 +99,8 @@ static inline int sclhi(struct i2c_algo_bit_data *adap) cond_resched(); } DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); + +done: udelay(adap->udelay); return 0; } @@ -121,7 +121,6 @@ static void i2c_repstart(struct i2c_algo_bit_data *adap) DEBPROTO(printk(" Sr ")); setsda(adap,1); sclhi(adap); - udelay(adap->udelay); sdalo(adap); scllo(adap); @@ -306,7 +305,7 @@ bailout: * 0 chip did not answer * -x transmission error */ -static inline int try_address(struct i2c_adapter *i2c_adap, +static int try_address(struct i2c_adapter *i2c_adap, unsigned char addr, int retries) { struct i2c_algo_bit_data *adap = i2c_adap->algo_data; @@ -354,15 +353,11 @@ static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) return (retval<0)? retval : -EFAULT; /* got a better one ?? */ } -#if 0 - /* from asm/delay.h */ - __delay(adap->mdelay * (loops_per_sec / 1000) ); -#endif } return wrcount; } -static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { int inval; int rdcount=0; /* counts bytes read */ @@ -372,7 +367,6 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) while (count > 0) { inval = i2c_inb(i2c_adap); -/*printk("%#02x ",inval); if ( ! (count % 16) ) printk("\n"); */ if (inval>=0) { *temp = inval; rdcount++; @@ -413,7 +407,7 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) * -x an error occurred (like: -EREMOTEIO if the device did not answer, or * -ETIMEDOUT, for example if the lines are stuck...) */ -static inline int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { unsigned short flags = msg->flags; unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; @@ -518,7 +512,7 @@ static u32 bit_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ -static struct i2c_algorithm i2c_bit_algo = { +static const struct i2c_algorithm i2c_bit_algo = { .master_xfer = bit_xfer, .functionality = bit_func, }; @@ -544,8 +538,7 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ - i2c_add_adapter(adap); - return 0; + return i2c_add_adapter(adap); } diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c index 2db7bfc8522..70d8eefb5ef 100644 --- a/drivers/i2c/algos/i2c-algo-ite.c +++ b/drivers/i2c/algos/i2c-algo-ite.c @@ -742,10 +742,8 @@ int i2c_iic_add_bus(struct i2c_adapter *adap) adap->retries = 3; /* be replaced by defines */ adap->flags = 0; - i2c_add_adapter(adap); iic_init(iic_adap); - - return 0; + return i2c_add_adapter(adap); } diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 82946acab4c..9081c9fbcd2 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -355,7 +355,7 @@ static int pca_init(struct i2c_algo_pca_data *adap) return 0; } -static struct i2c_algorithm pca_algo = { +static const struct i2c_algorithm pca_algo = { .master_xfer = pca_xfer, .functionality = pca_func, }; @@ -374,10 +374,10 @@ int i2c_pca_add_bus(struct i2c_adapter *adap) adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ - rval = pca_init(pca_adap); + if ((rval = pca_init(pca_adap))) + return rval; - if (!rval) - i2c_add_adapter(adap); + rval = i2c_add_adapter(adap); return rval; } diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 6e498df1f71..3b200339896 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -458,7 +458,7 @@ static u32 pcf_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ -static struct i2c_algorithm pcf_algo = { +static const struct i2c_algorithm pcf_algo = { .master_xfer = pcf_xfer, .functionality = pcf_func, }; @@ -479,9 +479,11 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ - rval = pcf_init_8584(pcf_adap); - if (!rval) - i2c_add_adapter(adap); + if ((rval = pcf_init_8584(pcf_adap))) + return rval; + + rval = i2c_add_adapter(adap); + return rval; } diff --git a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c index 932c4fa86c7..490d99997fd 100644 --- a/drivers/i2c/algos/i2c-algo-sgi.c +++ b/drivers/i2c/algos/i2c-algo-sgi.c @@ -157,7 +157,7 @@ static u32 sgi_func(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL; } -static struct i2c_algorithm sgi_algo = { +static const struct i2c_algorithm sgi_algo = { .master_xfer = sgi_xfer, .functionality = sgi_func, }; diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c deleted file mode 100644 index 3df3f09995c..00000000000 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ /dev/null @@ -1,217 +0,0 @@ -/* ------------------------------------------------------------------------- */ -/* i2c-algo-sibyte.c i2c driver algorithms for bit-shift adapters */ -/* ------------------------------------------------------------------------- */ -/* Copyright (C) 2001,2002,2003 Broadcom Corporation - 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. */ -/* ------------------------------------------------------------------------- */ - -/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even - Frodo Looijaard <frodol@dds.nl>. */ - -/* Ported for SiByte SOCs by Broadcom Corporation. */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> - -#include <asm/io.h> -#include <asm/sibyte/sb1250_regs.h> -#include <asm/sibyte/sb1250_smbus.h> - -#include <linux/i2c.h> -#include <linux/i2c-algo-sibyte.h> - -/* ----- global defines ----------------------------------------------- */ -#define SMB_CSR(a,r) ((long)(a->reg_base + r)) - -/* ----- global variables --------------------------------------------- */ - -/* module parameters: - */ -static int bit_scan; /* have a look at what's hanging 'round */ - - -static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, - unsigned short flags, char read_write, - u8 command, int size, union i2c_smbus_data * data) -{ - struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; - int data_bytes = 0; - int error; - - while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY) - ; - - switch (size) { - case I2C_SMBUS_QUICK: - csr_out32((V_SMB_ADDR(addr) | (read_write == I2C_SMBUS_READ ? M_SMB_QDATA : 0) | - V_SMB_TT_QUICKCMD), SMB_CSR(adap, R_SMB_START)); - break; - case I2C_SMBUS_BYTE: - if (read_write == I2C_SMBUS_READ) { - csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_RD1BYTE), - SMB_CSR(adap, R_SMB_START)); - data_bytes = 1; - } else { - csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); - csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR1BYTE), - SMB_CSR(adap, R_SMB_START)); - } - break; - case I2C_SMBUS_BYTE_DATA: - csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); - if (read_write == I2C_SMBUS_READ) { - csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD1BYTE), - SMB_CSR(adap, R_SMB_START)); - data_bytes = 1; - } else { - csr_out32(V_SMB_LB(data->byte), SMB_CSR(adap, R_SMB_DATA)); - csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE), - SMB_CSR(adap, R_SMB_START)); - } - break; - case I2C_SMBUS_WORD_DATA: - csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD)); - if (read_write == I2C_SMBUS_READ) { - csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD2BYTE), - SMB_CSR(adap, R_SMB_START)); - data_bytes = 2; - } else { - csr_out32(V_SMB_LB(data->word & 0xff), SMB_CSR(adap, R_SMB_DATA)); - csr_out32(V_SMB_MB(data->word >> 8), SMB_CSR(adap, R_SMB_DATA)); - csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE), - SMB_CSR(adap, R_SMB_START)); - } - break; - default: - return -1; /* XXXKW better error code? */ - } - - while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY) - ; - - error = csr_in32(SMB_CSR(adap, R_SMB_STATUS)); - if (error & M_SMB_ERROR) { - /* Clear error bit by writing a 1 */ - csr_out32(M_SMB_ERROR, SMB_CSR(adap, R_SMB_STATUS)); - return -1; /* XXXKW better error code? */ - } - - if (data_bytes == 1) - data->byte = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xff; - if (data_bytes == 2) - data->word = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xffff; - - return 0; -} - -static int algo_control(struct i2c_adapter *adapter, - unsigned int cmd, unsigned long arg) -{ - return 0; -} - -static u32 bit_func(struct i2c_adapter *adap) -{ - return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA); -} - - -/* -----exported algorithm data: ------------------------------------- */ - -static struct i2c_algorithm i2c_sibyte_algo = { - .smbus_xfer = smbus_xfer, - .algo_control = algo_control, /* ioctl */ - .functionality = bit_func, -}; - -/* - * registering functions to load algorithms at runtime - */ -int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) -{ - int i; - struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; - - /* register new adapter to i2c module... */ - i2c_adap->algo = &i2c_sibyte_algo; - - /* Set the frequency to 100 kHz */ - csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ)); - csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL)); - - /* scan bus */ - if (bit_scan) { - union i2c_smbus_data data; - int rc; - printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n", - i2c_adap->name); - for (i = 0x00; i < 0x7f; i++) { - /* XXXKW is this a realistic probe? */ - rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0, - I2C_SMBUS_BYTE_DATA, &data); - if (!rc) { - printk("(%02x)",i); - } else - printk("."); - } - printk("\n"); - } - - i2c_add_adapter(i2c_adap); - - return 0; -} - - -int i2c_sibyte_del_bus(struct i2c_adapter *adap) -{ - int res; - - if ((res = i2c_del_adapter(adap)) < 0) - return res; - - return 0; -} - -int __init i2c_algo_sibyte_init (void) -{ - printk("i2c-algo-sibyte.o: i2c SiByte algorithm module\n"); - return 0; -} - - -EXPORT_SYMBOL(i2c_sibyte_add_bus); -EXPORT_SYMBOL(i2c_sibyte_del_bus); - -#ifdef MODULE -MODULE_AUTHOR("Kip Walker, Broadcom Corp."); -MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); -module_param(bit_scan, int, 0); -MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - return i2c_algo_sibyte_init(); -} - -void cleanup_module(void) -{ -} -#endif diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 884320e7040..0d9667921f6 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -75,11 +75,11 @@ config I2C_AMD8111 will be called i2c-amd8111. config I2C_AU1550 - tristate "Au1550 SMBus interface" - depends on I2C && SOC_AU1550 + tristate "Au1550/Au1200 SMBus interface" + depends on I2C && (SOC_AU1550 || SOC_AU1200) help If you say yes to this option, support will be included for the - Au1550 SMBus interface. + Au1550 and Au1200 SMBus interface. This driver can also be built as a module. If so, the module will be called i2c-au1550. @@ -196,7 +196,7 @@ config I2C_IBM_IIC config I2C_IOP3XX tristate "Intel IOP3xx and IXP4xx on-chip I2C interface" - depends on (ARCH_IOP3XX || ARCH_IXP4XX) && I2C + depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX) && I2C help Say Y here if you want to use the IIC bus controller on the Intel IOP3xx I/O Processors or IXP4xx Network Processors. @@ -287,6 +287,16 @@ config I2C_OCORES This driver can also be built as a module. If so, the module will be called i2c-ocores. +config I2C_OMAP + tristate "OMAP I2C adapter" + depends on I2C && ARCH_OMAP + default y if MACH_OMAP_H3 || MACH_OMAP_OSK + help + If you say yes to this option, support will be included for the + I2C interface on the Texas Instruments OMAP1/2 family of processors. + Like OMAP1510/1610/1710/5912 and OMAP242x. + For details see http://www.ti.com/omap. + config I2C_PARPORT tristate "Parallel port adapter" depends on I2C && PARPORT @@ -482,19 +492,19 @@ config I2C_VIA will be called i2c-via. config I2C_VIAPRO - tristate "VIA 82C596/82C686/823x" + tristate "VIA 82C596/82C686/82xx" depends on I2C && PCI help If you say yes to this option, support will be included for the VIA - 82C596/82C686/823x I2C interfaces. Specifically, the following + 82C596/82C686/82xx I2C interfaces. Specifically, the following chipsets are supported: - 82C596A/B - 82C686A/B - 8231 - 8233 - 8233A - 8235 - 8237 + VT82C596A/B + VT82C686A/B + VT8231 + VT8233/A + VT8235 + VT8237R/A + VT8251 This driver can also be built as a module. If so, the module will be called i2c-viapro. diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index ac56df53155..493c87289b6 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o +obj-$(CONFIG_I2C_OMAP) += i2c-omap.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index d3ef46aeeb3..e75d339a348 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -468,7 +468,7 @@ static u32 ali1535_func(struct i2c_adapter *adapter) I2C_FUNC_SMBUS_BLOCK_DATA; } -static struct i2c_algorithm smbus_algorithm = { +static |