Commit a5b08073 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6: (30 commits)
  i2c: Drop unimplemented slave functions
  i2c: Constify i2c_algorithm declarations, part 2
  i2c: Constify i2c_algorithm declarations, part 1
  i2c: Let drivers constify i2c_algorithm data
  i2c-isa: Restore driver owner
  i2c-viapro: Add support for the VT8237A and VT8251
  i2c: Warn on i2c client creation failure
  i2c-core: Drop useless bitmaskings
  i2c-algo-pcf: Discard the mdelay data struct member
  i2c-algo-bit: Cleanups
  i2c-isa: Fail adding driver on attach_adapter error
  i2c: __must_check fixes (chip drivers)
  i2c-dev: attach/detach_adapter cleanups
  i2c-stub: Chip address as a module parameter
  i2c: Plan i2c-isa for removal
  i2c: New bus driver for TI OMAP boards
  i2c-algo-bit: Discard the mdelay data struct member
  i2c-matroxfb: Struct init conversion
  i2c: Fix copy-n-paste in subsystem Kconfig
  i2c-au1550: Add I2C support for Au1200
  ...
parents ff0972c2 6d3aae9d
......@@ -313,3 +313,12 @@ Why: The stacking of class devices makes these values misleading and
Who: Kay Sievers <kay.sievers@suse.de>
---------------------------
What: i2c-isa
When: December 2006
Why: i2c-isa is a non-sense and doesn't fit in the device driver
model. Drivers relying on it are better implemented as platform
drivers.
Who: Jean Delvare <khali@linux-fr.org>
---------------------------
......@@ -7,9 +7,12 @@ Supported adapters:
* VIA Technologies, Inc. VT82C686A/B
Datasheet: Sometimes available at the VIA website
* VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237R
* VIA Technologies, Inc. VT8231, VT8233, VT8233A
Datasheet: available on request from VIA
* VIA Technologies, Inc. VT8235, VT8237R, VT8237A, VT8251
Datasheet: available on request and under NDA from VIA
Authors:
Kysti Mlkki <kmalkki@cc.hut.fi>,
Mark D. Studebaker <mdsxyz123@yahoo.com>,
......@@ -39,6 +42,8 @@ Your lspci -n listing must show one of these :
device 1106:8235 (VT8231 function 4)
device 1106:3177 (VT8235)
device 1106:3227 (VT8237R)
device 1106:3337 (VT8237A)
device 1106:3287 (VT8251)
If none of these show up, you should look in the BIOS for settings like
enable ACPI / SMBus or even USB.
......
......@@ -6,9 +6,12 @@ This module is a very simple fake I2C/SMBus driver. It implements four
types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, and
(r/w) word data.
You need to provide a chip address as a module parameter when loading
this driver, which will then only react to SMBus commands to this address.
No hardware is needed nor associated with this module. It will accept write
quick commands to all addresses; it will respond to the other commands (also
to all addresses) by reading from or writing to an array in memory. It will
quick commands to one address; it will respond to the other commands (also
to one address) by reading from or writing to an array in memory. It will
also spam the kernel logs for every command it handles.
A pointer register with auto-increment is implemented for all byte
......@@ -21,6 +24,11 @@ The typical use-case is like this:
3. load the target sensors chip driver module
4. observe its behavior in the kernel log
PARAMETERS:
int chip_addr:
The SMBus address to emulate a chip at.
CAVEATS:
There are independent arrays for byte/data and word/data commands. Depending
......@@ -33,6 +41,9 @@ If the hardware for your driver has banked registers (e.g. Winbond sensors
chips) this module will not work well - although it could be extended to
support that pretty easily.
Only one chip address is supported - although this module could be
extended to support more.
If you spam it hard enough, printk can be lossy. This module really wants
something like relayfs.
......@@ -308,7 +308,6 @@ static struct i2c_algo_bit_data ioc_data = {
.getsda = ioc_getsda,
.getscl = ioc_getscl,
.udelay = 80,
.mdelay = 80,
.timeout = 100
};
......
......@@ -293,7 +293,7 @@ static u32 acpi_ec_smb_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC);
}
static struct i2c_algorithm acpi_ec_smbus_algorithm = {
static const struct i2c_algorithm acpi_ec_smbus_algorithm = {
.smbus_xfer = acpi_ec_smb_access,
.functionality = acpi_ec_smb_func,
};
......
......@@ -243,6 +243,7 @@ static struct i2c_driver it87_driver = {
static struct i2c_driver it87_isa_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "it87-isa",
},
.attach_adapter = it87_isa_attach_adapter,
......
......@@ -175,6 +175,7 @@ static struct i2c_driver lm78_driver = {
static struct i2c_driver lm78_isa_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "lm78-isa",
},
.attach_adapter = lm78_isa_attach_adapter,
......
......@@ -238,6 +238,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev);
static struct i2c_driver pc87360_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "pc87360",
},
.attach_adapter = pc87360_detect,
......
......@@ -200,6 +200,7 @@ static void sis5595_init_client(struct i2c_client *client);
static struct i2c_driver sis5595_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "sis5595",
},
.attach_adapter = sis5595_detect,
......
......@@ -228,6 +228,7 @@ static int smsc47b397_detect(struct i2c_adapter *adapter);
static struct i2c_driver smsc47b397_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "smsc47b397",
},
.attach_adapter = smsc47b397_detect,
......
......@@ -128,6 +128,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
static struct i2c_driver smsc47m1_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "smsc47m1",
},
.attach_adapter = smsc47m1_detect,
......
......@@ -574,6 +574,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
smbus_driver and isa_driver, and clients could be of either kind */
static struct i2c_driver via686a_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "via686a",
},
.attach_adapter = via686a_detect,
......
......@@ -587,6 +587,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
static struct i2c_driver vt8231_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "vt8231",
},
.attach_adapter = vt8231_detect,
......
......@@ -903,6 +903,7 @@ static int w83627ehf_detach_client(struct i2c_client *client)
static struct i2c_driver w83627ehf_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "w83627ehf",
},
.attach_adapter = w83627ehf_detect,
......
......@@ -339,6 +339,7 @@ static void w83627hf_init_client(struct i2c_client *client);
static struct i2c_driver w83627hf_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "w83627hf",
},
.attach_adapter = w83627hf_detect,
......
......@@ -288,6 +288,7 @@ static struct i2c_driver w83781d_driver = {
static struct i2c_driver w83781d_isa_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "w83781d-isa",
},
.attach_adapter = w83781d_isa_attach_adapter,
......
#
# Character device configuration
# I2C subsystem configuration
#
menu "I2C support"
......
......@@ -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)
......
......@@ -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)
......
......@@ -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 @@ static int test_bus(struct i2c_algo_bit_data *adap, char* name) {
* 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 */
......@@ -412,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;
......@@ -517,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,
};
......
......@@ -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,
};
......
......@@ -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,
};
......
......@@ -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,
};
......
/* ------------------------------------------------------------------------- */
/* 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 Kysti Mlkki <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");
}
return i2c_add_adapter(i2c_adap);
}
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
......@@ -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.
......@@ -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.
......
......@@ -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
......
......@@ -468,7 +468,7 @@ static u32 ali1535_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_BLOCK_DATA;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = ali1535_access,
.functionality = ali1535_func,
};
......
......@@ -367,7 +367,7 @@ static void ali1563_shutdown(struct pci_dev *dev)
release_region(ali1563_smba,ALI1563_SMB_IOSIZE);
}
static struct i2c_algorithm ali1563_algorithm = {
static const struct i2c_algorithm ali1563_algorithm = {
.smbus_xfer = ali1563_access,
.functionality = ali1563_func,
};
......
......@@ -463,7 +463,7 @@ static u32 ali15x3_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_BLOCK_DATA;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = ali15x3_access,
.functionality = ali15x3_func,
};
......
......@@ -294,7 +294,7 @@ static u32 amd756_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = amd756_access,
.functionality = amd756_func,
};
......
......@@ -316,7 +316,7 @@ static u32 amd8111_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = amd8111_access,
.functionality = amd8111_func,
};
......
......@@ -34,8 +34,7 @@
#include <linux/errno.h>
#include <linux/i2c.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1550.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1xxx_psc.h>
#include "i2c-au1550.h"
......@@ -118,13 +117,19 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
/* Reset the FIFOs, clear events.
*/
sp->psc_smbpcr = PSC_SMBPCR_DC;
stat = sp->psc_smbstat;
sp->psc_smbevnt = PSC_SMBEVNT_ALLCLR;
au_sync();
if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) {
sp->psc_smbpcr = PSC_SMBPCR_DC;
au_sync();
do {
stat = sp->psc_smbpcr;
au_sync();
} while ((stat & PSC_SMBPCR_DC) != 0);
udelay(50);
}
/* Write out the i2c chip address and specify operation
*/
......@@ -279,10 +284,10 @@ au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
static u32
au1550_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C;
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static struct i2c_algorithm au1550_algo = {
static const struct i2c_algorithm au1550_algo = {
.master_xfer = au1550_xfer,
.functionality = au1550_func,
};
......
......@@ -196,7 +196,6 @@ static struct i2c_algo_pcf_data pcf_isa_data = {
.getclock = pcf_isa_getclock,
.waitforpin = pcf_isa_waitforpin,
.udelay = 10,
.mdelay = 10,
.timeout = 100,
};
......
......@@ -99,7 +99,6 @@ static struct i2c_algo_bit_data hydra_bit_data = {
.getsda = hydra_bit_getsda,
.getscl = hydra_bit_getscl,
.udelay = 5,
.mdelay = 5,
.timeout = HZ
};
......
......@@ -434,7 +434,7 @@ static u32 i801_func(struct i2c_adapter *adapter)
| (isich4 ? I2C_FUNC_SMBUS_HWPEC_CALC : 0);
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = i801_access,
.functionality = i801_func,
};
......
......@@ -166,7 +166,6 @@ static struct i2c_algo_bit_data i810_i2c_bit_data = {
.getsda = bit_i810i2c_getsda,
.getscl = bit_i810i2c_getscl,
.udelay = CYCLE_DELAY,
.mdelay = CYCLE_DELAY,
.timeout = TIMEOUT,
};
......@@ -182,7 +181,6 @@ static struct i2c_algo_bit_data i810_ddc_bit_data = {
.getsda = bit_i810ddc_getsda,
.getscl = bit_i810ddc_getscl,
.udelay = CYCLE_DELAY,
.mdelay = CYCLE_DELAY,
.timeout = TIMEOUT,
};
......
......@@ -625,7 +625,7 @@ static u32 iic_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
}
static struct i2c_algorithm iic_algo = {
static const struct i2c_algorithm iic_algo = {
.master_xfer = iic_xfer,
.functionality = iic_func
};
......
......@@ -401,7 +401,7 @@ iop3xx_i2c_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static struct i2c_algorithm iop3xx_i2c_algo = {
static const struct i2c_algorithm iop3xx_i2c_algo = {
.master_xfer = iop3xx_i2c_master_xfer,
.algo_control = iop3xx_i2c_algo_control,
.functionality = iop3xx_i2c_func,
......
......@@ -43,7 +43,7 @@
static u32 isa_func(struct i2c_adapter *adapter);
/* This is the actual algorithm we define */
static struct i2c_algorithm isa_algorithm = {
static const struct i2c_algorithm isa_algorithm = {
.functionality = isa_func,
};
......@@ -89,9 +89,14 @@ int i2c_isa_add_driver(struct i2c_driver *driver)
dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name);
/* Now look for clients */
driver->attach_adapter(&isa_adapter);
return 0;
res = driver->attach_adapter(&isa_adapter);
if (res) {
dev_err(&isa_adapter.dev,
"Driver %s failed to attach adapter, unregistering\n",
driver->driver.name);
driver_unregister(&driver->driver);
}
return res;
}
int i2c_isa_del_driver(struct i2c_driver *driver)
......@@ -125,6 +130,8 @@ int i2c_isa_del_driver(struct i2c_driver *driver)
static int __init i2c_isa_init(void)
{
int err;
mutex_init(&isa_adapter.clist_lock);
INIT_LIST_HEAD(&isa_adapter.clients);
......@@ -133,8 +140,16 @@ static int __init i2c_isa_init(void)
sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr);
isa_adapter.dev.driver = &i2c_adapter_driver;
isa_adapter.dev.release = &i2c_adapter_dev_release;
device_register(&isa_adapter.dev);
device_create_file(&isa_adapter.dev, &dev_attr_name);
err = device_register(&isa_adapter.dev);
if (err) {
printk(KERN_ERR "i2c-isa: Failed to register device\n");
goto exit;
}
err = device_create_file(&isa_adapter.dev, &dev_attr_name);
if (err) {
printk(KERN_ERR "i2c-isa: Failed to create name file\n");
goto exit_unregister;
}
/* Add this adapter to the i2c_adapter class */
memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device));
......@@ -142,11 +157,24 @@ static int __init i2c_isa_init(void)
isa_adapter.class_dev.class = &i2c_adapter_class;
strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id,
BUS_ID_SIZE);
class_device_register(&isa_adapter.class_dev);
err = class_device_register(&isa_adapter.class_dev);
if (err) {
printk(KERN_ERR "i2c-isa: Failed to register class device\n");
goto exit_remove_name;
}
dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name);
return 0;
exit_remove_name:
device_remove_file(&isa_adapter.dev, &dev_attr_name);
exit_unregister:
init_completion(&isa_adapter.dev_released); /* Needed? */
device_unregister(&isa_adapter.dev);
wait_for_completion(&isa_adapter.dev_released);
exit:
return err;
}
static void __exit i2c_isa_exit(void)
......
......@@ -114,7 +114,6 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.getsda = ixp2000_bit_getsda;
drv_data->algo_data.getscl = ixp2000_bit_getscl;
drv_data->algo_data.udelay = 6;
drv_data->algo_data.mdelay = 6;
drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP2000,
......
......@@ -122,7 +122,6 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.getsda = ixp4xx_bit_getsda;
drv_data->algo_data.getscl = ixp4xx_bit_getscl;
drv_data->algo_data.udelay = 10;
drv_data->algo_data.mdelay = 10;
drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP4XX;
......
......@@ -272,7 +272,7 @@ static u32 mpc_functionality(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static struct i2c_algorithm mpc_algo = {
static const struct i2c_algorithm mpc_algo = {
.master_xfer = mpc_xfer,
.functionality = mpc_functionality,
};
......
......@@ -431,7 +431,7 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
return num;
}
static struct i2c_algorithm mv64xxx_i2c_algo = {
static const struct i2c_algorithm mv64xxx_i2c_algo = {
.master_xfer = mv64xxx_i2c_xfer,
.functionality = mv64xxx_i2c_functionality,
};
......
......@@ -109,7 +109,7 @@ static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
static u32 nforce2_func(struct i2c_adapter *adapter);
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = nforce2_access,
.functionality = nforce2_func,
};
......
......@@ -199,7 +199,7 @@ static u32 ocores_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static struct i2c_algorithm ocores_algorithm = {
static const struct i2c_algorithm ocores_algorithm = {
.master_xfer = ocores_xfer,
.functionality = ocores_func,
};
......
This diff is collapsed.
......@@ -103,7 +103,6 @@ static struct i2c_algo_bit_data parport_algo_data = {
.getsda = parport_getsda,
.getscl = parport_getscl,
.udelay = 50,
.mdelay = 50,
.timeout = HZ,
};
......
......@@ -138,7 +138,6 @@ static struct i2c_algo_bit_data parport_algo_data = {
.getsda = parport_getsda,
.getscl = parport_getscl,
.udelay = 60,
.mdelay = 60,
.timeout = HZ,
};
......
......@@ -376,7 +376,7 @@ static u32 piix4_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_BLOCK_DATA;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = piix4_access,
.functionality = piix4_func,
};
......
......@@ -175,7 +175,7 @@ static u32 i2c_powermac_func(struct i2c_adapter * adapter)
}
/* For now, we only handle smbus */
static struct i2c_algorithm i2c_powermac_algorithm = {
static const struct i2c_algorithm i2c_powermac_algorithm = {
.smbus_xfer = i2c_powermac_smbus_xfer,
.master_xfer = i2c_powermac_master_xfer,
.functionality = i2c_powermac_func,
......
......@@ -180,7 +180,6 @@ static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, void __iom
p->algo.getsda = bit_s3via_getsda;
p->algo.getscl = bit_s3via_getscl;
p->algo.udelay = CYCLE_DELAY;
p->algo.mdelay = CYCLE_DELAY;
p->algo.timeout = TIMEOUT;
p->algo.data = p;
p->mmvga = mmvga;
......
......@@ -926,7 +926,7 @@ static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static struct i2c_algorithm i2c_pxa_algorithm = {
static const struct i2c_algorithm i2c_pxa_algorithm = {
.master_xfer = i2c_pxa_xfer,
.functionality = i2c_pxa_functionality,
};
......
......@@ -566,7 +566,7 @@ static u32 s3c24xx_i2c_func(struct i2c_adapter *adap)
/* i2c bus registration info */
static struct i2c_algorithm s3c24xx_i2c_algorithm = {
static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
.master_xfer = s3c24xx_i2c_xfer,
.functionality = s3c24xx_i2c_func,
};
......
......@@ -140,7 +140,6 @@ static struct i2c_algo_bit_data sav_i2c_bit_data = {
.getsda = bit_savi2c_getsda,
.getscl = bit_savi2c_getscl,
.udelay = CYCLE_DELAY,
.mdelay = CYCLE_DELAY,
.timeout = TIMEOUT
};
......
/*
* Copyright (C) 2004 Steven J. Hill
* 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
......@@ -17,11 +18,162 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c-algo-sibyte.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <asm/io.h>
#include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_smbus.h>
struct i2c_algo_sibyte_data {
void *data; /* private data */
int bus; /* which bus */
void *reg_base; /* CSR base */
};
/* ----- 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 */
module_param(bit_scan, int, 0);
MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
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 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 const struct i2c_algorithm i2c_sibyte_algo = {
.smbus_xfer = smbus_xfer,
.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");
}
return i2c_add_adapter(i2c_adap);
}
static struct i2c_algo_sibyte_data sibyte_board_data[2] = {
{ NULL, 0, (void *) (CKSEG1+A_SMB_BASE(0)) },
{ NULL, 1, (void *) (CKSEG1+A_SMB_BASE(1)) }
......@@ -58,13 +210,13 @@ static int __init i2c_sibyte_init(void)
static void __exit i2c_sibyte_exit(void)
{
i2c_sibyte_del_bus(&sibyte_board_adapter[0]);
i2c_sibyte_del_bus(&sibyte_board_adapter[1]);
i2c_del_bus(&sibyte_board_adapter[0]);
i2c_del_bus(&sibyte_board_adapter[1]);
}
module_init(i2c_sibyte_init);
module_exit(i2c_sibyte_exit);
MODULE_AUTHOR("Kip Walker <kwalker@broadcom.com>, Steven J. Hill <sjhill@realitydiluted.com>");
MODULE_AUTHOR("Kip Walker (Broadcom Corp.), Steven J. Hill <sjhill@realitydiluted.com>");
MODULE_DESCRIPTION("SMBus adapter routines for SiByte boards");
MODULE_LICENSE("GPL");
......@@ -358,7 +358,7 @@ static u32 sis5595_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_PROC_CALL;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = sis5595_access,
.functionality = sis5595_func,
};
......
......@@ -450,7 +450,7 @@ static int sis630_setup(struct pci_dev *sis630_dev)
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = sis630_access,
.functionality = sis630_func,
};
......
......@@ -242,7 +242,7 @@ static u32 sis96x_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_PROC_CALL;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = sis96x_access,
.functionality = sis96x_func,
};
......
......@@ -27,6 +27,10 @@
#include <linux/errno.h>
#include <linux/i2c.h>
static unsigned short chip_addr;
module_param(chip_addr, ushort, S_IRUGO);
MODULE_PARM_DESC(chip_addr, "Chip address (between 0x03 and 0x77)\n");
static u8 stub_pointer;
static u8 stub_bytes[256];
static u16 stub_words[256];
......@@ -37,6 +41,9 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
{
s32 ret;
if (addr != chip_addr)
return -ENODEV;
switch (size) {
case I2C_SMBUS_QUICK:
......@@ -108,7 +115,7 @@ static u32 stub_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.functionality = stub_func,
.smbus_xfer = stub_xfer,
};
......@@ -122,7 +129,17 @@ static struct i2c_adapter stub_adapter = {
static int __init i2c_stub_init(void)
{
printk(KERN_INFO "i2c-stub loaded\n");
if (!chip_addr) {
printk(KERN_ERR "i2c-stub: Please specify a chip address\n");
return -ENODEV;
}
if (chip_addr < 0x03 || chip_addr > 0x77) {
printk(KERN_ERR "i2c-stub: Invalid chip address 0x%02x\n",
chip_addr);
return -EINVAL;
}
printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", chip_addr);
return i2c_add_adapter(&stub_adapter);
}
......
......@@ -81,7 +81,6 @@ static struct i2c_algo_bit_data bit_data = {
.getsda = bit_via_getsda,
.getscl = bit_via_getscl,
.udelay = 5,
.mdelay = 5,
.timeout = HZ
};
......
......@@ -34,6 +34,8 @@
VT8233A 0x3147 yes?
VT8235 0x3177 yes
VT8237R 0x3227 yes
VT8237A 0x3337 yes
VT8251 0x3287 yes
Note: we assume there can only be one device, with one SMBus interface.
*/
......@@ -297,7 +299,7 @@ static u32 vt596_func(struct i2c_adapter *adapter)
return func;
}
static struct i2c_algorithm smbus_algorithm = {
static const struct i2c_algorithm smbus_algorithm = {
.smbus_xfer = vt596_access,
.functionality = vt596_func,
};
......@@ -381,7 +383,9 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba);
switch (pdev->device) {
case PCI_DEVICE_ID_VIA_8251:
case PCI_DEVICE_ID_VIA_8237:
case PCI_DEVICE_ID_VIA_8237A:
case PCI_DEVICE_ID_VIA_8235:
case PCI_DEVICE_ID_VIA_8233A:
case PCI_DEVICE_ID_VIA_8233_0:
......@@ -432,8 +436,12 @@ static struct pci_device_id vt596_ids[] = {
.driver_data = SMBBA3 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237),
.driver_data = SMBBA3 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A),
.driver_data = SMBBA3 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4),
.driver_data = SMBBA1 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8251),
.driver_data = SMBBA3 },
{ 0, }
};
......
......@@ -160,7 +160,6 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = {
.getsda = bit_vooi2c_getsda,
.getscl = bit_vooi2c_getscl,
.udelay = CYCLE_DELAY,
.mdelay = CYCLE_DELAY,
.timeout = TIMEOUT
};
......@@ -177,7 +176,6 @@ static struct i2c_algo_bit_data voo_ddc_bit_data = {
.getsda = bit_vooddc_getsda,
.getscl = bit_vooddc_getscl,
.udelay = CYCLE_DELAY,
.mdelay = CYCLE_DELAY,
.timeout = TIMEOUT
};
......
......@@ -383,7 +383,7 @@ static u32 scx200_acb_func(struct i2c_adapter *adapter)
}
/* For now, we only handle combined mode (smbus) */
static struct i2c_algorithm scx200_acb_algorithm = {
static const struct i2c_algorithm scx200_acb_algorithm = {
.smbus_xfer = scx200_acb_smbus_xfer,
.functionality = scx200_acb_func,
};
......
......@@ -71,12 +71,12 @@ static int scx200_i2c_getsda(void *data)
*/
static struct i2c_algo_bit_data scx200_i2c_data = {
NULL,
scx200_i2c_setsda,
scx200_i2c_setscl,
scx200_i2c_getsda,
scx200_i2c_getscl,
10, 10, 100, /* waits, timeout */
.setsda = scx200_i2c_setsda,
.setscl = scx200_i2c_setscl,
.getsda = scx200_i2c_getsda,
.getscl = scx200_i2c_getscl,
.udelay = 10,
.timeout = 100,
};
static struct i2c_adapter scx200_i2c_ops = {
......
......@@ -209,10 +209,14 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
}
/* create the sysfs eeprom file */
sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
err = sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
if (err)
goto exit_detach;
return 0;
exit_detach:
i2c_detach_client(new_client);
exit_kfree:
kfree(data);
exit:
......@@ -223,6 +227,8 @@ static int eeprom_detach_client(struct i2c_client *client)
{
int err;
sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr);
err = i2c_detach_client(client);
if (err)
return err;
......
......@@ -199,8 +199,7 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
mutex_init(&data->update_lock);
/* Init fake client data */
/* set the client data to the i2c_client so that it will get freed */
i2c_set_clientdata(fake_client, fake_client);
i2c_set_clientdata(fake_client, NULL);
fake_client->addr = address | 1;
fake_client->adapter = adapter;
fake_client->driver = &max6875_driver;
......@@ -214,13 +213,17 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit_kfree2;
if ((err = i2c_attach_client(fake_client)) != 0)
goto exit_detach;
goto exit_detach1;
sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr);
err = sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr);
if (err)
goto exit_detach2;
return 0;
exit_detach:
exit_detach2:
i2c_detach_client(fake_client);
exit_detach1:
i2c_detach_client(real_client);
exit_kfree2:
kfree(fake_client);
......@@ -229,14 +232,24 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
return err;
}
/* Will be called for both the real client and the fake client */
static int max6875_detach_client(struct i2c_client *client)
{
int err;
struct max6875_data *data = i2c_get_clientdata(client);
/* data is NULL for the fake client */
if (data)
sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
err = i2c_detach_client(client);
if (err)
return err;
kfree(i2c_get_clientdata(client));
if (data) /* real client */
kfree(data);
else /* fake client */
kfree(client);
return 0;
}
......
......@@ -148,11 +148,16 @@ static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind)
if ((err = i2c_attach_client(new_client)))
goto exit_kfree;
/* Register sysfs hooks (don't care about failure) */
sysfs_create_group(&new_client->dev.kobj, &pca9539_defattr_group);
/* Register sysfs hooks */
err = sysfs_create_group(&new_client->dev.kobj,
&pca9539_defattr_group);
if (err)
goto exit_detach;
return 0;
exit_detach:
i2c_detach_client(new_client);
exit_kfree:
kfree(data);
exit:
......@@ -163,6 +168,8 @@ static int pca9539_detach_client(struct i2c_client *client)
{
int err;
sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group);
if ((err = i2c_detach_client(client)))
return err;
......
......@@ -105,6 +105,16 @@ static ssize_t set_write(struct device *dev, struct device_attribute *attr, cons
static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);
static struct attribute *pcf8574_attributes[] = {
&dev_attr_read.attr,
&dev_attr_write.attr,
NULL
};
static const struct attribute_group pcf8574_attr_group = {
.attrs = pcf8574_attributes,
};
/*
* Real code
*/
......@@ -166,13 +176,13 @@ static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
pcf8574_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_read);
device_create_file(&new_client->dev, &dev_attr_write);
err = sysfs_create_group(&new_client->dev.kobj, &pcf8574_attr_group);
if (err)
goto exit_detach;
return 0;
/* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
......@@ -183,6 +193,8 @@ static int pcf8574_detach_client(struct i2c_client *client)
{
int err;
sysfs_remove_group(&client->dev.kobj, &pcf8574_attr_group);
if ((err = i2c_detach_client(client)))
return err;
......
......@@ -158,6 +158,28 @@ static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr
static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
show_out0_enable, set_out0_enable);
static struct attribute *pcf8591_attributes[] = {
&dev_attr_out0_enable.attr,
&dev_attr_out0_output.attr,
&dev_attr_in0_input.attr,
&dev_attr_in1_input.attr,
NULL
};
static const struct attribute_group pcf8591_attr_group = {
.attrs = pcf8591_attributes,
};
static struct attribute *pcf8591_attributes_opt[] = {
&dev_attr_in2_input.attr,
&dev_attr_in3_input.attr,
NULL
};
static const struct attribute_group pcf8591_attr_group_opt = {
.attrs = pcf8591_attributes_opt,
};
/*
* Real code
*/
......@@ -211,24 +233,31 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
pcf8591_init_client(new_client);
/* Register sysfs hooks */
device_create_file(&new_client->dev, &dev_attr_out0_enable);
device_create_file(&new_client->dev, &dev_attr_out0_output);
device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input);
err = sysfs_create_group(&new_client->dev.kobj, &pcf8591_attr_group);
if (err)
goto exit_detach;
/* Register input2 if not in "two differential inputs" mode */
if (input_mode != 3 )
device_create_file(&new_client->dev, &dev_attr_in2_input);
if (input_mode != 3) {
if ((err = device_create_file(&new_client->dev,
&dev_attr_in2_input)))
goto exit_sysfs_remove;
}
/* Register input3 only in "four single ended inputs" mode */
if (input_mode == 0)
device_create_file(&new_client->dev, &dev_attr_in3_input);
if (input_mode == 0) {
if ((err = device_create_file(&new_client->dev,
&dev_attr_in3_input)))
goto exit_sysfs_remove;
}
return 0;
/* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */
exit_sysfs_remove:
sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group_opt);
sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group);
exit_detach:
i2c_detach_client(new_client);
exit_kfree:
kfree(data);
exit:
......@@ -239,6 +268,9 @@ static int pcf8591_detach_client(struct i2c_client *client)
{
int err;
sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
if ((err = i2c_detach_client(client)))
return err;
......
......@@ -183,15 +183,21 @@ int i2c_add_adapter(struct i2c_adapter *adap)
sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);
adap->dev.driver = &i2c_adapter_driver;
adap->dev.release = &i2c_adapter_dev_release;
device_register(&adap->dev);
device_create_file(&adap->dev, &dev_attr_name);
res = device_register(&adap->dev);
if (res)
goto out_list;
res = device_create_file(&adap->dev, &dev_attr_name);
if (res)
goto out_unregister;
/* Add this adapter to the i2c_adapter class */
memset(&adap->class_dev, 0x00, sizeof(struct class_device));
adap->class_dev.dev = &adap->dev;
adap->class_dev.class = &i2c_adapter_class;
strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE);
class_device_register(&adap->class_dev);
res = class_device_register(&adap->class_dev);
if (res)
goto out_remove_name;
dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
......@@ -206,6 +212,17 @@ int i2c_add_adapter(struct i2c_adapter *adap)
out_unlock:
mutex_unlock(&core_lists);
return res;
out_remove_name:
device_remove_file(&adap->dev, &dev_attr_name);
out_unregister:
init_completion(&adap->dev_released); /* Needed? */
device_unregister(&adap->dev);
wait_for_completion(&adap->dev_released);
out_list:
list_del(&adap->list);
idr_remove(&i2c_adapter_idr, adap->nr);
goto out_unlock;
}
......@@ -394,14 +411,14 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr)
int i2c_attach_client(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
int res = 0;
mutex_lock(&adapter->clist_lock);
if (__i2c_check_addr(client->adapter, client->addr)) {
mutex_unlock(&adapter->clist_lock);
return -EBUSY;
res = -EBUSY;
goto out_unlock;
}
list_add_tail(&client->list,&adapter->clients);
mutex_unlock(&adapter->clist_lock);
if (adapter->client_register) {
if (adapter->client_register(client)) {
......@@ -422,10 +439,26 @@ int i2c_attach_client(struct i2c_client *client)
"%d-%04x", i2c_adapter_id(adapter), client->addr);
dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
client->name, client->dev.bus_id);
device_register(&client->dev);
device_create_file(&client->dev, &dev_attr_client_name);
res = device_register(&client->dev);
if (res)
goto out_list;
res = device_create_file(&client->dev, &dev_attr_client_name);
if (res)
goto out_unregister;
return 0;
out_unlock:
mutex_unlock(&adapter->clist_lock);
return res;
out_unregister:
init_completion(&client->released); /* Needed? */
device_unregister(&client->dev);
wait_for_completion(&client->released);
out_list:
list_del(&client->list);
dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x "
"(%d)\n", client->name, client->addr, res);
goto out_unlock;
}
......@@ -674,11 +707,16 @@ static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind,
/* Finally call the custom detection function */
err = found_proc(adapter, addr, kind);
/* -ENODEV can be returned if there is a chip at the given address
but it isn't supported by this chip driver. We catch it here as
this isn't an error. */
return (err == -ENODEV) ? 0 : err;
if (err == -ENODEV)
err = 0;
if (err)
dev_warn(&adapter->dev, "Client creation failed at 0x%x (%d)\n",
addr, err);
return err;
}
int i2c_probe(struct i2c_adapter *adapter,
......@@ -868,7 +906,7 @@ s32 i2c_smbus_read_byte(struct i2c_client *client)
I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data))
return -1;
else
return 0x0FF & data.byte;
return data.byte;
}
s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value)
......@@ -884,7 +922,7 @@ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
I2C_SMBUS_READ,command, I2C_SMBUS_BYTE_DATA,&data))
return -1;
else
return 0x0FF & data.byte;
return data.byte;
}
s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value)
......@@ -903,7 +941,7 @@ s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command)
I2C_SMBUS_READ,command, I2C_SMBUS_WORD_DATA, &data))
return -1;
else
return 0x0FFFF & data.word;
return data.word;
}
s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value)
......@@ -1006,7 +1044,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
else {
msg[0].len=3;
msgbuf0[1] = data->word & 0xff;
msgbuf0[2] = (data->word >> 8) & 0xff;
msgbuf0[2] = data->word >> 8;
}
break;
case I2C_SMBUS_PROC_CALL:
......@@ -1015,7 +1053,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
msg[0].len = 3;
msg[1].len = 2;
msgbuf0[1] = data->word & 0xff;
msgbuf0[2] = (data->word >> 8) & 0xff;
msgbuf0[2] = data->word >> 8;
break;
case I2C_SMBUS_BLOCK_DATA:
if (read_write == I2C_SMBUS_READ) {
......
......@@ -32,43 +32,35 @@
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h>
static struct i2c_client i2cdev_client_template;
static struct i2c_driver i2cdev_driver;
struct i2c_dev {
int minor;
struct list_head list;
struct i2c_adapter *adap;
struct class_device *class_dev;
};
#define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev)
#define I2C_MINORS 256
static struct i2c_dev *i2c_dev_array[I2C_MINORS];
static DEFINE_SPINLOCK(i2c_dev_array_lock);
static LIST_HEAD(i2c_dev_list);
static DEFINE_SPINLOCK(i2c_dev_list_lock);
static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)
{
struct i2c_dev *i2c_dev;
spin_lock(&i2c_dev_array_lock);
i2c_dev = i2c_dev_array[index];
spin_unlock(&i2c_dev_array_lock);
return i2c_dev;
}
static struct i2c_dev *i2c_dev_get_by_adapter(struct i2c_adapter *adap)
{
struct i2c_dev *i2c_dev = NULL;
spin_lock(&i2c_dev_array_lock);
if ((i2c_dev_array[adap->nr]) &&
(i2c_dev_array[adap->nr]->adap == adap))
i2c_dev = i2c_dev_array[adap->nr];
spin_unlock(&i2c_dev_array_lock);
spin_lock(&i2c_dev_list_lock);
list_for_each_entry(i2c_dev, &i2c_dev_list, list) {
if (i2c_dev->adap->nr == index)
goto found;
}
i2c_dev = NULL;
found:
spin_unlock(&i2c_dev_list_lock);
return i2c_dev;
}
......@@ -76,30 +68,28 @@ static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)
{
struct i2c_dev *i2c_dev;
if (adap->nr >= I2C_MINORS) {
printk(KERN_ERR "i2c-dev: Out of device minors (%d)\n",
adap->nr);
return ERR_PTR(-ENODEV);
}
i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev)
return ERR_PTR(-ENOMEM);
i2c_dev->adap = adap;
spin_lock(&i2c_dev_array_lock);
if (i2c_dev_array[adap->nr]) {
spin_unlock(&i2c_dev_array_lock);
dev_err(&adap->dev, "i2c-dev already has a device assigned to this adapter\n");
goto error;
}
i2c_dev->minor = adap->nr;
i2c_dev_array[adap->nr] = i2c_dev;
spin_unlock(&i2c_dev_array_lock);
spin_lock(&i2c_dev_list_lock);
list_add_tail(&i2c_dev->list, &i2c_dev_list);
spin_unlock(&i2c_dev_list_lock);
return i2c_dev;
error:
kfree(i2c_dev);
return ERR_PTR(-ENODEV);
}
static void return_i2c_dev(struct i2c_dev *i2c_dev)
{
spin_lock(&i2c_dev_array_lock);
i2c_dev_array[i2c_dev->minor] = NULL;
spin_unlock(&i2c_dev_array_lock);
spin_lock(&i2c_dev_list_lock);
list_del(&i2c_dev->list);
spin_unlock(&i2c_dev_list_lock);
}
static ssize_t show_adapter_name(struct class_device *class_dev, char *buf)
......@@ -375,12 +365,13 @@ static int i2cdev_open(struct inode *inode, struct file *file)
if (!adap)
return -ENODEV;
client = kmalloc(sizeof(*client), GFP_KERNEL);
client = kzalloc(sizeof(*client), GFP_KERNEL);
if (!client) {
i2c_put_adapter(adap);
return -ENOMEM;
}
memcpy(client, &i2cdev_client_template, sizeof(*client));
snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
client->driver = &i2cdev_driver;
/* registered with adapter, passed as client to user */
client->adapter = adap;
......@@ -415,41 +406,47 @@ static struct class *i2c_dev_class;
static int i2cdev_attach_adapter(struct i2c_adapter *adap)
{
struct i2c_dev *i2c_dev;
struct device *dev;
int res;
i2c_dev = get_free_i2c_dev(adap);
if (IS_ERR(i2c_dev))
return PTR_ERR(i2c_dev);
pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",
adap->name, i2c_dev->minor);
/* register this i2c device with the driver core */
i2c_dev->adap = adap;
dev = &adap->dev;
i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL,
MKDEV(I2C_MAJOR, i2c_dev->minor),
dev, "i2c-%d", i2c_dev->minor);
if (!i2c_dev->class_dev)
MKDEV(I2C_MAJOR, adap->nr),
&adap->dev, "i2c-%d",
adap->nr);
if (!i2c_dev->class_dev) {
res = -ENODEV;
goto error;
class_device_create_file(i2c_dev->class_dev, &class_device_attr_name);
}
res = class_device_create_file(i2c_dev->class_dev, &class_device_attr_name);
if (res)
goto error_destroy;
pr_debug("i2c-dev: adapter [%s] registered as minor %d\n",
adap->name, adap->nr);
return 0;
error_destroy:
class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
error:
return_i2c_dev(i2c_dev);
kfree(i2c_dev);
return -ENODEV;
return res;
}
static int i2cdev_detach_adapter(struct i2c_adapter *adap)
{
struct i2c_dev *i2c_dev;
i2c_dev = i2c_dev_get_by_adapter(adap);
if (!i2c_dev)
return -ENODEV;
i2c_dev = i2c_dev_get_by_minor(adap->nr);
if (!i2c_dev) /* attach_adapter must have failed */
return 0;
class_device_remove_file(i2c_dev->class_dev, &class_device_attr_name);
return_i2c_dev(i2c_dev);
class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, i2c_dev->minor));
class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
kfree(i2c_dev);
pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);
......@@ -471,12 +468,6 @@ static struct i2c_driver i2cdev_driver = {
.detach_client = i2cdev_detach_client,
};
static struct i2c_client i2cdev_client_template = {
.name = "I2C /dev entry",
.addr = -1,
.driver = &i2cdev_driver,
};
static int __init i2c_dev_init(void)
{
int res;
......
......@@ -137,7 +137,6 @@ static struct i2c_algo_bit_data bit_data = {
.getsda = bit_getsda,
.getscl = bit_getscl,
.udelay = 5,
.mdelay = 5,
.timeout = 100,
};
......
......@@ -100,7 +100,6 @@ static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = {
.getsda = bttv_bit_getsda,
.getscl = bttv_bit_getscl,
.udelay = 16,
.mdelay = 10,
.timeout = 200,
};
......
......@@ -155,7 +155,6 @@ static struct i2c_algo_bit_data cx8800_i2c_algo_template = {
.getsda = cx8800_bit_getsda,
.getscl = cx8800_bit_getscl,
.udelay = 16,
.mdelay = 10,
.timeout = 200,
};
......
......@@ -100,7 +100,6 @@ static struct i2c_algo_bit_data vp3054_i2c_algo_template = {
.getsda = vp3054_bit_getsda,
.getscl = vp3054_bit_getscl,
.udelay = 16,
.mdelay = 10,
.timeout = 200,
};
......
......@@ -820,7 +820,6 @@ static struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
.getsda = zoran_i2c_getsda,
.getscl = zoran_i2c_getscl,
.udelay = 10,
.mdelay = 0,
.timeout = 100,
};
......
......@@ -98,7 +98,6 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name)
chan->algo.getsda = i810i2c_getsda;
chan->algo.getscl = i810i2c_getscl;
chan->algo.udelay = 10;
chan->algo.mdelay = 10;
chan->algo.timeout = (HZ/2);
chan->algo.data = chan;
......
......@@ -95,12 +95,12 @@ static struct i2c_adapter matrox_i2c_adapter_template =
static struct i2c_algo_bit_data matrox_i2c_algo_template =
{
NULL,
matroxfb_gpio_setsda,
matroxfb_gpio_setscl,
matroxfb_gpio_getsda,
matroxfb_gpio_getscl,
10, 10, 100,
.setsda = matroxfb_gpio_setsda,
.setscl = matroxfb_gpio_setscl,
.getsda = matroxfb_gpio_getsda,
.getscl = matroxfb_gpio_getscl,
.udelay = 10,
.timeout = 100,
};
static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
......
......@@ -148,7 +148,6 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
chan->adapter.algo_data = &chan->algo;
chan->adapter.dev.parent = &chan->par->pcidev->dev;
chan->algo.udelay = 40;
chan->algo.mdelay = 5;
chan->algo.timeout = 20;
chan->algo.data = chan;
......
......@@ -40,7 +40,6 @@ struct i2c_algo_bit_data {
/* local settings */
int udelay; /* half-clock-cycle time in microsecs */
/* i.e. clock is (500 / udelay) KHz */
int mdelay; /* in millisecs, unused */
int timeout; /* in jiffies */
};
......
......@@ -35,7 +35,6 @@ struct i2c_algo_pcf_data {
/* local settings */
int udelay;
int mdelay;
int timeout;
};
......
/*
* Copyright (C) 2001,2002,2003 Broadcom Corporation
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef I2C_ALGO_SIBYTE_H
#define I2C_ALGO_SIBYTE_H 1
#include <linux/i2c.h>
struct i2c_algo_sibyte_data {
void *data; /* private data */
int bus; /* which bus */
void *reg_base; /* CSR base */
};
int i2c_sibyte_add_bus(struct i2c_adapter *, int speed);
int i2c_sibyte_del_bus(struct i2c_adapter *);
#endif /* I2C_ALGO_SIBYTE_H */
......@@ -64,14 +64,6 @@ extern int i2c_master_recv(struct i2c_client *,char* ,int);
*/
extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
/*
* Some adapter types (i.e. PCF 8584 based ones) may support slave behaviuor.
* This is not tested/implemented yet and will change in the future.
*/
extern int i2c_slave_send(struct i2c_client *,char*,int);
extern int i2c_slave_recv(struct i2c_client *,char*,int);
/* This is the very generalized SMBus access routine. You probably do not
want to use this, though; one of the functions below may be much easier,
......@@ -201,10 +193,6 @@ struct i2c_algorithm {
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data * data);
/* --- these optional/future use for some adapter types.*/
int (*slave_send)(struct i2c_adapter *,char*,int);
int (*slave_recv)(struct i2c_adapter *,char*,int);
/* --- ioctl like call to set div. parameters. */
int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long);
......@@ -220,7 +208,7 @@ struct i2c_adapter {
struct module *owner;
unsigned int id;
unsigned int class;
struct i2c_algorithm *algo;/* the algorithm to access the bus */
const struct i2c_algorithm *algo; /* the algorithm to access the bus */
void *algo_data;
/* --- administration stuff. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment