Skip to content

Commit

Permalink
Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/jdelvare/staging

* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  macintosh: Don't assume i2c device probing always succeeds
  i2c: Hide probe errors caused by ACPI resource conflicts
  i2c: Minor documentation update
  mfd: AB3100 drop unused module parameters
  Staging: IIO: tsl2561: Drop unused module parameters
  leds: leds-pca9532 - Drop unused module parameters
  ltc4215/ltc4245: Discard obsolete detect methods
  ds2482: Discard obsolete detect method
  max6875: Discard obsolete detect method
  i2c: Move misc devices documentation
  • Loading branch information
Linus Torvalds committed Oct 4, 2009
2 parents 58e57fb + 6f6b35e commit 663cc81
Show file tree
Hide file tree
Showing 25 changed files with 64 additions and 257 deletions.
7 changes: 4 additions & 3 deletions Documentation/hwmon/ltc4215
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ Usage Notes
-----------

This driver does not probe for LTC4215 devices, due to the fact that some
of the possible addresses are unfriendly to probing. You will need to use
the "force" parameter to tell the driver where to find the device.
of the possible addresses are unfriendly to probing. You will have to
instantiate the devices explicitly.

Example: the following will load the driver for an LTC4215 at address 0x44
on I2C bus #0:
$ modprobe ltc4215 force=0,0x44
$ modprobe ltc4215
$ echo ltc4215 0x44 > /sys/bus/i2c/devices/i2c-0/new_device


Sysfs entries
Expand Down
7 changes: 4 additions & 3 deletions Documentation/hwmon/ltc4245
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ Usage Notes
-----------

This driver does not probe for LTC4245 devices, due to the fact that some
of the possible addresses are unfriendly to probing. You will need to use
the "force" parameter to tell the driver where to find the device.
of the possible addresses are unfriendly to probing. You will have to
instantiate the devices explicitly.

Example: the following will load the driver for an LTC4245 at address 0x23
on I2C bus #1:
$ modprobe ltc4245 force=1,0x23
$ modprobe ltc4245
$ echo ltc4245 0x23 > /sys/bus/i2c/devices/i2c-1/new_device


Sysfs entries
Expand Down
2 changes: 1 addition & 1 deletion Documentation/i2c/instantiating-devices
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ segment, the address is sufficient to uniquely identify the device to be
deleted.

Example:
# echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device
# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device

While this interface should only be used when in-kernel device declaration
can't be done, there is a variety of cases where it can be helpful:
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ General Remarks

Valid addresses for the MAX6875 are 0x50 and 0x52.
Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56.
The driver does not probe any address, so you must force the address.
The driver does not probe any address, so you explicitly instantiate the
devices.

Example:
$ modprobe max6875 force=0,0x50
$ modprobe max6875
$ echo max6875 0x50 > /sys/bus/i2c/devices/i2c-0/new_device

The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
addresses. For example, for address 0x50, it also reserves 0x51.
Expand Down
6 changes: 3 additions & 3 deletions Documentation/w1/masters/ds2482
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ General Remarks

Valid addresses are 0x18, 0x19, 0x1a, and 0x1b.
However, the device cannot be detected without writing to the i2c bus, so no
detection is done.
You should force the device address.
detection is done. You should instantiate the device explicitly.

$ modprobe ds2482 force=0,0x18
$ modprobe ds2482
$ echo ds2482 0x18 > /sys/bus/i2c/devices/i2c-0/new_device

47 changes: 5 additions & 42 deletions drivers/hwmon/ltc4215.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>

static const unsigned short normal_i2c[] = { I2C_CLIENT_END };

/* Insmod parameters */
I2C_CLIENT_INSMOD_1(ltc4215);

/* Here are names of the chip's registers (a.k.a. commands) */
enum ltc4215_cmd {
LTC4215_CONTROL = 0x00, /* rw */
Expand Down Expand Up @@ -246,9 +241,13 @@ static const struct attribute_group ltc4215_group = {
static int ltc4215_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = client->adapter;
struct ltc4215_data *data;
int ret;

if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;

data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
Expand Down Expand Up @@ -294,56 +293,20 @@ static int ltc4215_remove(struct i2c_client *client)
return 0;
}

static int ltc4215_detect(struct i2c_client *client,
int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;

if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;

if (kind < 0) { /* probed detection - check the chip type */
s32 v; /* 8 bits from the chip, or -ERRNO */

/*
* Register 0x01 bit b7 is reserved, expect 0
* Register 0x03 bit b6 and b7 are reserved, expect 0
*/
v = i2c_smbus_read_byte_data(client, LTC4215_ALERT);
if (v < 0 || (v & (1 << 7)) != 0)
return -ENODEV;

v = i2c_smbus_read_byte_data(client, LTC4215_FAULT);
if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0)
return -ENODEV;
}

strlcpy(info->type, "ltc4215", I2C_NAME_SIZE);
dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n",
kind < 0 ? "probed" : "forced",
client->addr);

return 0;
}

static const struct i2c_device_id ltc4215_id[] = {
{ "ltc4215", ltc4215 },
{ "ltc4215", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc4215_id);

/* This is the driver that will be inserted */
static struct i2c_driver ltc4215_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "ltc4215",
},
.probe = ltc4215_probe,
.remove = ltc4215_remove,
.id_table = ltc4215_id,
.detect = ltc4215_detect,
.address_data = &addr_data,
};

static int __init ltc4215_init(void)
Expand Down
131 changes: 5 additions & 126 deletions drivers/hwmon/ltc4245.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>

/* Valid addresses are 0x20 - 0x3f
*
* For now, we do not probe, since some of these addresses
* are known to be unfriendly to probing */
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };

/* Insmod parameters */
I2C_CLIENT_INSMOD_1(ltc4245);

/* Here are names of the chip's registers (a.k.a. commands) */
enum ltc4245_cmd {
LTC4245_STATUS = 0x00, /* readonly */
Expand Down Expand Up @@ -369,9 +360,13 @@ static const struct attribute_group ltc4245_group = {
static int ltc4245_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = client->adapter;
struct ltc4245_data *data;
int ret;

if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;

data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
Expand Down Expand Up @@ -418,136 +413,20 @@ static int ltc4245_remove(struct i2c_client *client)
return 0;
}

/* Check that some bits in a control register appear at all possible
* locations without changing value
*
* @client: the i2c client to use
* @reg: the register to read
* @bits: the bits to check (0xff checks all bits,
* 0x03 checks only the last two bits)
*
* return -ERRNO if the register read failed
* return -ENODEV if the register value doesn't stay constant at all
* possible addresses
*
* return 0 for success
*/
static int ltc4245_check_control_reg(struct i2c_client *client, u8 reg, u8 bits)
{
int i;
s32 v, voff1, voff2;

/* Read register and check for error */
v = i2c_smbus_read_byte_data(client, reg);
if (v < 0)
return v;

v &= bits;

for (i = 0x00; i < 0xff; i += 0x20) {

voff1 = i2c_smbus_read_byte_data(client, reg + i);
if (voff1 < 0)
return voff1;

voff2 = i2c_smbus_read_byte_data(client, reg + i + 0x08);
if (voff2 < 0)
return voff2;

voff1 &= bits;
voff2 &= bits;

if (v != voff1 || v != voff2)
return -ENODEV;
}

return 0;
}

static int ltc4245_detect(struct i2c_client *client,
int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;

if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;

if (kind < 0) { /* probed detection - check the chip type */
s32 v; /* 8 bits from the chip, or -ERRNO */

/* Chip registers 0x00-0x07 are control registers
* Chip registers 0x10-0x1f are data registers
*
* Address bits b7-b5 are ignored. This makes the chip "repeat"
* in steps of 0x20. Any control registers should appear with
* the same values across all duplicated addresses.
*
* Register 0x02 bit b2 is reserved, expect 0
* Register 0x07 bits b7 to b4 are reserved, expect 0
*
* Registers 0x01, 0x02 are control registers and should not
* change on their own.
*
* Register 0x06 bits b6 and b7 are control bits, and should
* not change on their own.
*
* Register 0x07 bits b3 to b0 are control bits, and should
* not change on their own.
*/

/* read register 0x02 reserved bit, expect 0 */
v = i2c_smbus_read_byte_data(client, LTC4245_CONTROL);
if (v < 0 || (v & 0x04) != 0)
return -ENODEV;

/* read register 0x07 reserved bits, expect 0 */
v = i2c_smbus_read_byte_data(client, LTC4245_ADCADR);
if (v < 0 || (v & 0xf0) != 0)
return -ENODEV;

/* check that the alert register appears at all locations */
if (ltc4245_check_control_reg(client, LTC4245_ALERT, 0xff))
return -ENODEV;

/* check that the control register appears at all locations */
if (ltc4245_check_control_reg(client, LTC4245_CONTROL, 0xff))
return -ENODEV;

/* check that register 0x06 bits b6 and b7 stay constant */
if (ltc4245_check_control_reg(client, LTC4245_GPIO, 0xc0))
return -ENODEV;

/* check that register 0x07 bits b3-b0 stay constant */
if (ltc4245_check_control_reg(client, LTC4245_ADCADR, 0x0f))
return -ENODEV;
}

strlcpy(info->type, "ltc4245", I2C_NAME_SIZE);
dev_info(&adapter->dev, "ltc4245 %s at address 0x%02x\n",
kind < 0 ? "probed" : "forced",
client->addr);

return 0;
}

static const struct i2c_device_id ltc4245_id[] = {
{ "ltc4245", ltc4245 },
{ "ltc4245", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc4245_id);

/* This is the driver that will be inserted */
static struct i2c_driver ltc4245_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "ltc4245",
},
.probe = ltc4245_probe,
.remove = ltc4245_remove,
.id_table = ltc4245_id,
.detect = ltc4245_detect,
.address_data = &addr_data,
};

static int __init ltc4245_init(void)
Expand Down
2 changes: 1 addition & 1 deletion drivers/i2c/busses/i2c-amd756.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
amd756_driver.name);
if (error)
return error;
return -ENODEV;

if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
Expand Down
4 changes: 3 additions & 1 deletion drivers/i2c/busses/i2c-amd8111.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
smbus->size = pci_resource_len(dev, 0);

error = acpi_check_resource_conflict(&dev->resource[0]);
if (error)
if (error) {
error = -ENODEV;
goto out_kfree;
}

if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
error = -EBUSY;
Expand Down
4 changes: 3 additions & 1 deletion drivers/i2c/busses/i2c-i801.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
}

err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
if (err)
if (err) {
err = -ENODEV;
goto exit;
}

err = pci_request_region(dev, SMBBAR, i801_driver.name);
if (err) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/i2c/busses/i2c-isch.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ static int __devinit sch_probe(struct pci_dev *dev,
return -ENODEV;
}
if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
return -EBUSY;
return -ENODEV;
if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
sch_smba);
Expand Down
4 changes: 2 additions & 2 deletions drivers/i2c/busses/i2c-piix4.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
}

if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
return -EBUSY;
return -ENODEV;

if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
Expand Down Expand Up @@ -260,7 +260,7 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,

piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
return -EBUSY;
return -ENODEV;

if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
Expand Down
2 changes: 1 addition & 1 deletion drivers/i2c/busses/i2c-sis96x.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev,

retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]);
if (retval)
return retval;
return -ENODEV;

/* Everything is happy, let's grab the memory and set things up. */
if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
Expand Down
2 changes: 1 addition & 1 deletion drivers/i2c/busses/i2c-viapro.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
found:
error = acpi_check_region(vt596_smba, 8, vt596_driver.name);
if (error)
return error;
return -ENODEV;

if (!request_region(vt596_smba, 8, vt596_driver.name)) {
dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
Expand Down
Loading

0 comments on commit 663cc81

Please sign in to comment.