Commit e0bc5d4a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging

* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  i2c-nforce2: Remove redundant error messages on ACPI conflict
  i2c: Use <linux/io.h> instead of <asm/io.h>
  i2c-algo-pca: Fix coding style issues
  i2c-dev: Fix all coding style issues
  i2c-core: Fix some coding style issues
  i2c-gpio: Move initialization code to subsys_initcall()
  i2c-parport: Make template structure const
  i2c-dev: Remove unnecessary casts
  at24: Fall back to byte or word reads if needed
  i2c-stub: Expose the default functionality flags
  i2c/scx200_acb: Make PCI device ids constant
  i2c-i801: Fix all checkpatch warnings
  i2c-i801: All newer devices have all the optional features
  i2c-i801: Let the user disable selected driver features
parents 7f02ab3c 7c4fda1a
......@@ -27,7 +27,13 @@ Authors:
Module Parameters
-----------------
None.
* disable_features (bit vector)
Disable selected features normally supported by the device. This makes it
possible to work around possible driver or hardware bugs if the feature in
question doesn't work as intended for whatever reason. Bit values:
1 disable SMBus PEC
2 disable the block buffer
8 disable the I2C block read functionality
Description
......
......@@ -114,8 +114,8 @@ static int pca_address(struct i2c_algo_pca_data *adap,
int sta = pca_get_con(adap);
int addr;
addr = ( (0x7f & msg->addr) << 1 );
if (msg->flags & I2C_M_RD )
addr = ((0x7f & msg->addr) << 1);
if (msg->flags & I2C_M_RD)
addr |= 1;
DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n",
msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);
......@@ -170,7 +170,7 @@ static int pca_rx_ack(struct i2c_algo_pca_data *adap,
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI|I2C_PCA_CON_AA);
if ( ack )
if (ack)
sta |= I2C_PCA_CON_AA;
pca_set_con(adap, sta);
......@@ -202,21 +202,21 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
DEB1("{{{ XFER %d messages\n", num);
if (i2c_debug>=2) {
if (i2c_debug >= 2) {
for (curmsg = 0; curmsg < num; curmsg++) {
int addr, i;
msg = &msgs[curmsg];
addr = (0x7f & msg->addr) ;
if (msg->flags & I2C_M_RD )
if (msg->flags & I2C_M_RD)
printk(KERN_INFO " [%02d] RD %d bytes from %#02x [%#02x, ...]\n",
curmsg, msg->len, addr, (addr<<1) | 1);
curmsg, msg->len, addr, (addr << 1) | 1);
else {
printk(KERN_INFO " [%02d] WR %d bytes to %#02x [%#02x%s",
curmsg, msg->len, addr, addr<<1,
curmsg, msg->len, addr, addr << 1,
msg->len == 0 ? "" : ", ");
for(i=0; i < msg->len; i++)
for (i = 0; i < msg->len; i++)
printk("%#04x%s", msg->buf[i], i == msg->len - 1 ? "" : ", ");
printk("]\n");
}
......@@ -305,7 +305,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
goto out;
case 0x58: /* Data byte has been received; NOT ACK has been returned */
if ( numbytes == msg->len - 1 ) {
if (numbytes == msg->len - 1) {
pca_rx_byte(adap, &msg->buf[numbytes], 0);
curmsg++; numbytes = 0;
if (curmsg == num)
......
......@@ -60,7 +60,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <linux/io.h>
/* ALI1535 SMBus address offsets */
......
......@@ -67,7 +67,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <linux/io.h>
/* ALI15X3 SMBus address offsets */
#define SMBHSTSTS (0 + ali15x3_smba)
......
......@@ -43,7 +43,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <linux/io.h>
/* AMD756 SMBus address offsets */
#define SMB_ADDR_OFFSET 0xE0
......
......@@ -18,7 +18,7 @@
#include <linux/delay.h>
#include <linux/acpi.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/io.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Vojtech Pavlik <vojtech@suse.cz>");
......
......@@ -23,8 +23,7 @@
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <linux/io.h>
#include <mach/at91_twi.h>
#include <mach/board.h>
......
......@@ -37,8 +37,8 @@
#include <linux/isa.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-pcf.h>
#include <linux/io.h>
#include <asm/io.h>
#include <asm/irq.h>
#include "../algos/i2c-algo-pcf.h"
......
......@@ -211,7 +211,7 @@ static int __init i2c_gpio_init(void)
return ret;
}
module_init(i2c_gpio_init);
subsys_initcall(i2c_gpio_init);
static void __exit i2c_gpio_exit(void)
{
......
......@@ -28,7 +28,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/io.h>
#include <asm/hydra.h>
......
......@@ -138,6 +138,17 @@ static struct pci_dev *I801_dev;
#define FEATURE_I2C_BLOCK_READ (1 << 3)
static unsigned int i801_features;
static const char *i801_feature_names[] = {
"SMBus PEC",
"Block buffer",
"Block process call",
"I2C block read",
};
static unsigned int disable_features;
module_param(disable_features, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(disable_features, "Disable selected driver features");
/* Make sure the SMBus host is ready to start transmitting.
Return 0 if it is, -EBUSY if it is not. */
static int i801_check_pre(void)
......@@ -341,8 +352,7 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
do {
msleep(1);
status = inb_p(SMBHSTSTS);
}
while ((!(status & SMBHSTSTS_BYTE_DONE))
} while ((!(status & SMBHSTSTS_BYTE_DONE))
&& (timeout++ < MAX_TIMEOUT));
result = i801_check_post(status, timeout > MAX_TIMEOUT);
......@@ -440,9 +450,9 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
}
/* Return negative errno on error. */
static s32 i801_access(struct i2c_adapter * adap, u16 addr,
static s32 i801_access(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data * data)
int size, union i2c_smbus_data *data)
{
int hwpec;
int block = 0;
......@@ -511,7 +521,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
else
outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
if(block)
if (block)
ret = i801_block_transaction(data, read_write, size, hwpec);
else
ret = i801_transaction(xact | ENABLE_INT9);
......@@ -523,9 +533,9 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
outb_p(inb_p(SMBAUXCTL) & ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
SMBAUXCTL);
if(block)
if (block)
return ret;
if(ret)
if (ret)
return ret;
if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
return 0;
......@@ -585,7 +595,7 @@ static const struct pci_device_id i801_ids[] = {
{ 0, }
};
MODULE_DEVICE_TABLE (pci, i801_ids);
MODULE_DEVICE_TABLE(pci, i801_ids);
#if defined CONFIG_INPUT_APANEL || defined CONFIG_INPUT_APANEL_MODULE
static unsigned char apanel_addr;
......@@ -689,10 +699,11 @@ static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm,
}
#endif
static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
static int __devinit i801_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
unsigned char temp;
int err;
int err, i;
#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
const char *vendor;
#endif
......@@ -700,26 +711,28 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
I801_dev = dev;
i801_features = 0;
switch (dev->device) {
case PCI_DEVICE_ID_INTEL_82801EB_3:
case PCI_DEVICE_ID_INTEL_ESB_4:
case PCI_DEVICE_ID_INTEL_ICH6_16:
case PCI_DEVICE_ID_INTEL_ICH7_17:
case PCI_DEVICE_ID_INTEL_ESB2_17:
case PCI_DEVICE_ID_INTEL_ICH8_5:
case PCI_DEVICE_ID_INTEL_ICH9_6:
case PCI_DEVICE_ID_INTEL_TOLAPAI_1:
case PCI_DEVICE_ID_INTEL_ICH10_4:
case PCI_DEVICE_ID_INTEL_ICH10_5:
case PCI_DEVICE_ID_INTEL_PCH_SMBUS:
case PCI_DEVICE_ID_INTEL_CPT_SMBUS:
default:
i801_features |= FEATURE_I2C_BLOCK_READ;
/* fall through */
case PCI_DEVICE_ID_INTEL_82801DB_3:
i801_features |= FEATURE_SMBUS_PEC;
i801_features |= FEATURE_BLOCK_BUFFER;
/* fall through */
case PCI_DEVICE_ID_INTEL_82801CA_3:
case PCI_DEVICE_ID_INTEL_82801BA_2:
case PCI_DEVICE_ID_INTEL_82801AB_3:
case PCI_DEVICE_ID_INTEL_82801AA_3:
break;
}
/* Disable features on user request */
for (i = 0; i < ARRAY_SIZE(i801_feature_names); i++) {
if (i801_features & disable_features & (1 << i))
dev_notice(&dev->dev, "%s disabled by user\n",
i801_feature_names[i]);
}
i801_features &= ~disable_features;
err = pci_enable_device(dev);
if (err) {
dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
......
......@@ -39,7 +39,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/of_platform.h>
......
......@@ -38,8 +38,7 @@
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <asm/io.h>
#include <linux/io.h>
#include "i2c-iop3xx.h"
......
......@@ -17,8 +17,7 @@
#include <linux/interrupt.h>
#include <linux/mv643xx_i2c.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <linux/io.h>
/* Register defines */
#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00
......
......@@ -57,7 +57,7 @@
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/io.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Hans-Frieder Vogt <hfvogt@gmx.net>");
......@@ -404,10 +404,9 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
/* SMBus adapter 1 */
res1 = nforce2_probe_smb(dev, 4, NFORCE_PCI_SMB1, &smbuses[0], "SMB1");
if (res1 < 0) {
dev_err(&dev->dev, "Error probing SMB1.\n");
if (res1 < 0)
smbuses[0].base = 0; /* to have a check value */
}
/* SMBus adapter 2 */
if (dmi_check_system(nforce2_dmi_blacklist2)) {
dev_err(&dev->dev, "Disabling SMB2 for safety reasons.\n");
......@@ -416,11 +415,10 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
} else {
res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1],
"SMB2");
if (res2 < 0) {
dev_err(&dev->dev, "Error probing SMB2.\n");
if (res2 < 0)
smbuses[1].base = 0; /* to have a check value */
}
}
if ((res1 < 0) && (res2 < 0)) {
/* we did not find even one of the SMBuses, so we give up */
kfree(smbuses);
......
......@@ -19,7 +19,7 @@
#include <linux/wait.h>
#include <linux/i2c-ocores.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/io.h>
struct ocores_i2c {
void __iomem *base;
......
......@@ -33,7 +33,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-smbus.h>
#include <asm/io.h>
#include <linux/io.h>
#include "i2c-parport.h"
#define DEFAULT_BASE 0x378
......
......@@ -137,7 +137,7 @@ static int parport_getsda(void *data)
copied. The attaching code will set getscl to NULL for adapters that
cannot read SCL back, and will also make the data field point to
the parallel port structure. */
static struct i2c_algo_bit_data parport_algo_data = {
static const struct i2c_algo_bit_data parport_algo_data = {
.setsda = parport_setsda,
.setscl = parport_setscl,
.getsda = parport_getsda,
......
......@@ -25,7 +25,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/io.h>
static struct pci_driver pasemi_smb_driver;
......
......@@ -30,8 +30,8 @@
#include <linux/isa.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-pca.h>
#include <linux/io.h>
#include <asm/io.h>
#include <asm/irq.h>
#define DRIVER "i2c-pca-isa"
......
......@@ -23,9 +23,9 @@
#include <linux/i2c-algo-pca.h>
#include <linux/i2c-pca-platform.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/io.h>
struct i2c_pca_pf_data {
void __iomem *reg_base;
......
......@@ -39,7 +39,7 @@
#include <linux/init.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <linux/io.h>
/* PIIX4 SMBus address offsets */
......
......@@ -33,7 +33,7 @@
#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/io.h>
#define DRV_NAME "pmcmsptwi"
......
......@@ -34,9 +34,9 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <plat/i2c.h>
/*
......
......@@ -35,9 +35,9 @@
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <plat/regs-iic.h>
#include <plat/iic.h>
......
......@@ -36,8 +36,8 @@
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/io.h>
#include "i2c-s6000.h"
#define DRV_NAME "i2c-s6000"
......
......@@ -16,10 +16,10 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <asm/clock.h>
#include <asm/i2c-sh7760.h>
#include <asm/io.h>
/* register offsets */
#define I2CSCR 0x0 /* slave ctrl */
......
......@@ -22,7 +22,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <asm/io.h>
#include <linux/io.h>
#include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_smbus.h>
......
......@@ -24,12 +24,11 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/io.h>
struct simtec_i2c_data {
struct resource *ioarea;
void __iomem *reg;
......
......@@ -61,7 +61,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <linux/io.h>
static int blacklist[] = {
PCI_DEVICE_ID_SI_540,
......
......@@ -53,7 +53,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <linux/io.h>
/* SIS630 SMBus registers */
#define SMB_STS 0x80 /* status */
......
......@@ -38,7 +38,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <linux/io.h>
/* base address register in PCI config space */
#define SIS96x_BAR 0x04
......
......@@ -29,13 +29,16 @@
#include <linux/i2c.h>
#define MAX_CHIPS 10
#define STUB_FUNC (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | \
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | \
I2C_FUNC_SMBUS_I2C_BLOCK)
static unsigned short chip_addr[MAX_CHIPS];
module_param_array(chip_addr, ushort, NULL, S_IRUGO);
MODULE_PARM_DESC(chip_addr,
"Chip addresses (up to 10, between 0x03 and 0x77)");
static unsigned long functionality = ~0UL;
static unsigned long functionality = STUB_FUNC;
module_param(functionality, ulong, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(functionality, "Override functionality bitfield");
......@@ -156,9 +159,7 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
static u32 stub_func(struct i2c_adapter *adapter)
{
return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK) & functionality;
return STUB_FUNC & functionality;
}
static const struct i2c_algorithm smbus_algorithm = {
......
......@@ -15,8 +15,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/io.h>
#define I2C_CONTROL 0x00
#define I2C_CONTROLS 0x00
......
......@@ -25,7 +25,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/io.h>
#include <linux/io.h>
/* Power management registers */
#define PM_CFG_REVID 0x08 /* silicon revision code */
......
......@@ -51,7 +51,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>
#include <linux/io.h>
static struct pci_dev *vt596_pdev;
......
......@@ -32,7 +32,7 @@
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/io.h>
#include <linux/scx200.h>
......@@ -552,7 +552,7 @@ static int __init scx200_create_isa(const char *text, unsigned long base,
* the name and the BAR where the I/O address resource is located. ISA
* devices are flagged with a bar value of -1 */
static struct pci_device_id scx200_pci[] = {
static const struct pci_device_id scx200_pci[] __initconst = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE),
.driver_data = 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE),
......
......@@ -27,7 +27,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/io.h>
#include <linux/io.h>
#include <linux/scx200_gpio.h>
......
......@@ -1221,10 +1221,10 @@ EXPORT_SYMBOL(i2c_transfer);
*
* Returns negative errno, or else the number of bytes written.
*/
int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
int i2c_master_send(struct i2c_client *client, const char *buf, int count)
{
int ret;
struct i2c_adapter *adap=client->adapter;
struct i2c_adapter *adap = client->adapter;
struct i2c_msg msg;
msg.addr = client->addr;
......@@ -1248,9 +1248,9 @@ EXPORT_SYMBOL(i2c_master_send);
*
* Returns negative errno, or else the number of bytes read.
*/
int i2c_master_recv(struct i2c_client *client, char *buf ,int count)
int i2c_master_recv(struct i2c_client *client, char *buf, int count)
{
struct i2c_adapter *adap=client->adapter;
struct i2c_adapter *adap = client->adapter;
struct i2c_msg msg;
int ret;
......@@ -1452,7 +1452,7 @@ i2c_new_probed_device(struct i2c_adapter *adap,
}
EXPORT_SYMBOL_GPL(i2c_new_probed_device);
struct i2c_adapter* i2c_get_adapter(int id)
struct i2c_adapter *i2c_get_adapter(int id)
{
struct i2c_adapter *adapter;
......@@ -1479,7 +1479,7 @@ static u8 crc8(u16 data)
{
int i;
for(i = 0; i < 8; i++) {
for (i = 0; i < 8; i++) {
if (data & 0x8000)
data = data ^ POLY;
data = data << 1;
......@@ -1492,7 +1492,7 @@ static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
{
int i;
for(i = 0; i < count; i++)
for (i = 0; i < count; i++)
crc = crc8((crc ^ p[i]) << 8);
return crc;
}
......@@ -1562,7 +1562,7 @@ EXPORT_SYMBOL(i2c_smbus_read_byte);
*/
s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value)
{
return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
}
EXPORT_SYMBOL(i2c_smbus_write_byte);
......@@ -1600,9 +1600,9 @@ s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value)
{
union i2c_smbus_data data;
data.byte = value;
return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
I2C_SMBUS_WRITE,command,
I2C_SMBUS_BYTE_DATA,&data);
return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_BYTE_DATA, &data);
}
EXPORT_SYMBOL(i2c_smbus_write_byte_data);
......@@ -1639,9 +1639,9 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value)
{
union i2c_smbus_data data;
data.word = value;
return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
I2C_SMBUS_WRITE,command,
I2C_SMBUS_WORD_DATA,&data);
return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_WORD_DATA, &data);
}
EXPORT_SYMBOL(i2c_smbus_write_word_data);
......@@ -1718,9 +1718,9 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
length = I2C_SMBUS_BLOCK_MAX;
data.block[0] = length;
memcpy(&data.block[1], values, length);
return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
I2C_SMBUS_WRITE,command,
I2C_SMBUS_BLOCK_DATA,&data);
return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_BLOCK_DATA, &data);
}
EXPORT_SYMBOL(i2c_smbus_write_block_data);
......@@ -1762,10 +1762,10 @@ EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
/* Simulate a SMBus command using the i2c protocol
No checking of parameters is done! */
static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
unsigned short flags,
char read_write, u8 command, int size,
union i2c_smbus_data * data)
union i2c_smbus_data *data)
{
/* So we need to generate a series of msgs. In the case of writing, we
need to use only one message; when reading, we need two. We initialize
......@@ -1773,7 +1773,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
simpler. */
unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
int num = read_write == I2C_SMBUS_READ?2:1;
int num = read_write == I2C_SMBUS_READ ? 2 : 1;
struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
{ addr, flags | I2C_M_RD, 0, msgbuf1 }
};
......@@ -1782,7 +1782,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
int status;
msgbuf0[0] = command;
switch(size) {
switch (size) {
case I2C_SMBUS_QUICK:
msg[0].len = 0;
/* Special case: The read/write field is used as data */
......@@ -1809,7 +1809,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
if (read_write == I2C_SMBUS_READ)
msg[1].len = 2;
else {
msg[0].len=3;
msg[0].len = 3;
msgbuf0[1] = data->word & 0xff;
msgbuf0[2] = data->word >> 8;
}
......@@ -1902,7 +1902,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
}
if (read_write == I2C_SMBUS_READ)
switch(size) {
switch (size) {
case I2C_SMBUS_BYTE:
data->byte = msgbuf0[0];
break;
......@@ -1966,7 +1966,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
}
rt_mutex_unlock(&adapter->bus_lock);
} else
res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
command, protocol, data);
return res;
......
......@@ -35,7 +35,7 @@
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/jiffies.h>
#include <asm/uaccess.h>
#include <linux/uaccess.h>
static struct i2c_driver i2cdev_driver;
......@@ -132,45 +132,45 @@ static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
* needed by those system calls and by this SMBus interface.
*/
static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
loff_t *offset)
{
char *tmp;
int ret;
struct i2c_client *client = (struct i2c_client *)file->private_data;
struct i2c_client *client = file->private_data;
if (count > 8192)
count = 8192;
tmp = kmalloc(count,GFP_KERNEL);
if (tmp==NULL)
tmp = kmalloc(count, GFP_KERNEL);
if (tmp == NULL)
return -ENOMEM;
pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
iminor(file->f_path.dentry->d_inode), count);
ret = i2c_master_recv(client,tmp,count);
ret = i2c_master_recv(client, tmp, count);
if (ret >= 0)
ret = copy_to_user(buf,tmp,count)?-EFAULT:ret;
ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;
kfree(tmp);
return ret;
}
static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t count,
loff_t *offset)
static ssize_t i2cdev_write(struct file *file, const char __user *buf,
size_t count, loff_t *offset)
{
int ret;
char *tmp;
struct i2c_client *client = (struct i2c_client *)file->private_data;
struct i2c_client *client = file->private_data;
if (count > 8192)
count = 8192;
tmp = kmalloc(count,GFP_KERNEL);
if (tmp==NULL)
tmp = kmalloc(count, GFP_KERNEL);
if (tmp == NULL)
return -ENOMEM;
if (copy_from_user(tmp,buf,count)) {
if (copy_from_user(tmp, buf, count)) {
kfree(tmp);
return -EFAULT;
}
......@@ -178,7 +178,7 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
iminor(file->f_path.dentry->d_inode), count);
ret = i2c_master_send(client,tmp,count);
ret = i2c_master_send(client, tmp, count);
kfree(tmp);
return ret;
}
......@@ -369,13 +369,13 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct i2c_client *client = (struct i2c_client *)file->private_data;
struct i2c_client *client = file->private_data;
unsigned long funcs;
dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
cmd, arg);
switch ( cmd ) {
switch (cmd) {
case I2C_SLAVE:
case I2C_SLAVE_FORCE:
/* NOTE: devices set up to work with "new style" drivers
......@@ -601,7 +601,7 @@ static void __exit i2c_dev_exit(void)
{
i2c_del_driver(&i2cdev_driver);
class_destroy(i2c_dev_class);
unregister_chrdev(I2C_MAJOR,"i2c");
unregister_chrdev(I2C_MAJOR, "i2c");
}
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
......
......@@ -54,7 +54,7 @@
struct at24_data {
struct at24_platform_data chip;
struct memory_accessor macc;
bool use_smbus;
int use_smbus;
/*
* Lock protects against activities from other Linux tasks,
......@@ -184,11 +184,19 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
if (count > io_limit)
count = io_limit;
if (at24->use_smbus) {
switch (at24->use_smbus) {
case I2C_SMBUS_I2C_BLOCK_DATA:
/* Smaller eeproms can work given some SMBus extension calls */
if (count > I2C_SMBUS_BLOCK_MAX)
count = I2C_SMBUS_BLOCK_MAX;
} else {
break;
case I2C_SMBUS_WORD_DATA:
count = 2;
break;
case I2C_SMBUS_BYTE_DATA:
count = 1;
break;
default:
/*
* When we have a better choice than SMBus calls, use a
* combined I2C message. Write address; then read up to
......@@ -219,10 +227,27 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
timeout = jiffies + msecs_to_jiffies(write_timeout);
do {
read_time = jiffies;
if (at24->use_smbus) {
switch (at24->use_smbus) {
case I2C_SMBUS_I2C_BLOCK_DATA:
status = i2c_smbus_read_i2c_block_data(client, offset,
count, buf);
} else {
break;
case I2C_SMBUS_WORD_DATA:
status = i2c_smbus_read_word_data(client, offset);
if (status >= 0) {
buf[0] = status & 0xff;
buf[1] = status >> 8;
status = count;
}
break;
case I2C_SMBUS_BYTE_DATA:
status = i2c_smbus_read_byte_data(client, offset);
if (status >= 0) {
buf[0] = status;
status = count;
}
break;
default:
status = i2c_transfer(client->adapter, msg, 2);
if (status == 2)
status = count;
......@@ -436,7 +461,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct at24_platform_data chip;
bool writable;
bool use_smbus = false;
int use_smbus = 0;
struct at24_data *at24;
int err;
unsigned i, num_addresses;
......@@ -477,12 +502,19 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
err = -EPFNOSUPPORT;
goto err_out;
}
if (!i2c_check_functionality(client->adapter,
if (i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
use_smbus = I2C_SMBUS_I2C_BLOCK_DATA;
} else if (i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_WORD_DATA)) {
use_smbus = I2C_SMBUS_WORD_DATA;
} else if (i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
use_smbus = I2C_SMBUS_BYTE_DATA;
} else {
err = -EPFNOSUPPORT;
goto err_out;
}
use_smbus = true;
}
if (chip.flags & AT24_FLAG_TAKE8ADDR)
......@@ -568,11 +600,16 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_info(&client->dev, "%zu byte %s EEPROM %s\n",
at24->bin.size, client->name,
writable ? "(writable)" : "(read-only)");
if (use_smbus == I2C_SMBUS_WORD_DATA ||
use_smbus == I2C_SMBUS_BYTE_DATA) {
dev_notice(&client->dev, "Falling back to %s reads, "
"performance will suffer\n", use_smbus ==
I2C_SMBUS_WORD_DATA ? "word" : "byte");
}
dev_dbg(&client->dev,
"page_size %d, num_addresses %d, write_max %d%s\n",
"page_size %d, num_addresses %d, write_max %d, use_smbus %d\n",
chip.page_size, num_addresses,
at24->write_max,
use_smbus ? ", use_smbus" : "");
at24->write_max, use_smbus);
/* export data to kernel code */
if (chip.setup)
......
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