ltc4215/ltc4245: Discard obsolete detect methods
There is no point in implementing a detect callback for the LTC4215 and LTC4245, as these devices can't be detected. It was there solely to handle "force" module parameters to instantiate devices, but now we have a better sysfs interface that can do the same. So we can get rid of the ugly module parameters and the detect callbacks. This shrinks the binary module sizes by 36% and 46%, respectively. Signed-off-by: Jean Delvare <khali@linux-fr.org> Cc: Ira W. Snyder <iws@ovro.caltech.edu>
This commit is contained in:
parent
0314b020c4
commit
2d2a7cff1b
4 changed files with 18 additions and 174 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue