Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: (44 commits)
  hwmon: (w83l786ng) Convert to a new-style i2c driver
  hwmon: (w83l785ts) Convert to a new-style i2c driver
  hwmon: (w83793) Convert to a new-style i2c driver
  hwmon: (w83792d) Convert to a new-style i2c driver
  hwmon: (w83791d) Convert to a new-style i2c driver
  hwmon: (thmc50) Convert to a new-style i2c driver
  hwmon: (smsc47m192) Convert to a new-style i2c driver
  hwmon: (max6650) Convert to a new-style i2c driver
  hwmon: (max1619) Convert to a new-style i2c driver
  hwmon: (lm93) Convert to a new-style i2c driver
  hwmon: (lm92) Convert to a new-style i2c driver
  hwmon: (lm90) Convert to a new-style i2c driver
  hwmon: (lm87) Convert to a new-style i2c driver
  hwmon: (lm83) Convert to a new-style i2c driver
  hwmon: (lm80) Convert to a new-style i2c driver
  hwmon: (lm77) Convert to a new-style i2c driver
  hwmon: (lm63) Convert to a new-style i2c driver
  hwmon: (gl520sm) Convert to a new-style i2c driver
  hwmon: (gl518sm) Convert to a new-style i2c driver
  hwmon: (fscpos) Convert to a new-style i2c driver
  ...
This commit is contained in:
Linus Torvalds 2008-07-16 11:47:35 -07:00
commit a3cf859321
50 changed files with 2143 additions and 2811 deletions

View File

@ -49,7 +49,7 @@ $ modprobe max6875 force=0,0x50
The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
addresses. For example, for address 0x50, it also reserves 0x51.
The even-address instance is called 'max6875', the odd one is 'max6875 subclient'.
The even-address instance is called 'max6875', the odd one is 'dummy'.
Programming the chip using i2c-dev

View File

@ -7,7 +7,7 @@ drivers/gpio/pca9539.c instead.
Supported chips:
* Philips PCA9539
Prefix: 'pca9539'
Addresses scanned: 0x74 - 0x77
Addresses scanned: none
Datasheet:
http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf
@ -23,6 +23,14 @@ The input sense can also be inverted.
The 16 lines are split between two bytes.
Detection
---------
The PCA9539 is difficult to detect and not commonly found in PC machines,
so you have to pass the I2C bus and address of the installed PCA9539
devices explicitly to the driver at load time via the force=... parameter.
Sysfs entries
-------------

View File

@ -4,13 +4,13 @@ Kernel driver pcf8574
Supported chips:
* Philips PCF8574
Prefix: 'pcf8574'
Addresses scanned: I2C 0x20 - 0x27
Addresses scanned: none
Datasheet: Publicly available at the Philips Semiconductors website
http://www.semiconductors.philips.com/pip/PCF8574P.html
* Philips PCF8574A
Prefix: 'pcf8574a'
Addresses scanned: I2C 0x38 - 0x3f
Addresses scanned: none
Datasheet: Publicly available at the Philips Semiconductors website
http://www.semiconductors.philips.com/pip/PCF8574P.html
@ -38,12 +38,10 @@ For more informations see the datasheet.
Accessing PCF8574(A) via /sys interface
-------------------------------------
! Be careful !
The PCF8574(A) is plainly impossible to detect ! Stupid chip.
So every chip with address in the interval [20..27] and [38..3f] are
detected as PCF8574(A). If you have other chips in this address
range, the workaround is to load this module after the one
for your others chips.
So, you have to pass the I2C bus and address of the installed PCF857A
and PCF8574A devices explicitly to the driver at load time via the
force=... parameter.
On detection (i.e. insmod, modprobe et al.), directories are being
created for each detected PCF8574(A):

View File

@ -40,12 +40,9 @@ Detection
---------
There is no method known to detect whether a chip on a given I2C address is
a PCF8575 or whether it is any other I2C device. So there are two alternatives
to let the driver find the installed PCF8575 devices:
- Load this driver after any other I2C driver for I2C devices with addresses
in the range 0x20 .. 0x27.
- Pass the I2C bus and address of the installed PCF8575 devices explicitly to
the driver at load time via the probe=... or force=... parameters.
a PCF8575 or whether it is any other I2C device, so you have to pass the I2C
bus and address of the installed PCF8575 devices explicitly to the driver at
load time via the force=... parameter.
/sys interface
--------------

View File

@ -23,12 +23,9 @@
#include "lm75.h"
#define DRV_VERSION "0.3"
#define DRV_VERSION "0.4"
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_3(ad7416, ad7417, ad7418);
enum chips { ad7416, ad7417, ad7418 };
/* AD7418 registers */
#define AD7418_REG_TEMP_IN 0x00
@ -46,7 +43,6 @@ static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN,
AD7418_REG_TEMP_OS };
struct ad7418_data {
struct i2c_client client;
struct device *hwmon_dev;
struct attribute_group attrs;
enum chips type;
@ -58,16 +54,25 @@ struct ad7418_data {
u16 in[4];
};
static int ad7418_attach_adapter(struct i2c_adapter *adapter);
static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind);
static int ad7418_detach_client(struct i2c_client *client);
static int ad7418_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int ad7418_remove(struct i2c_client *client);
static const struct i2c_device_id ad7418_id[] = {
{ "ad7416", ad7416 },
{ "ad7417", ad7417 },
{ "ad7418", ad7418 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad7418_id);
static struct i2c_driver ad7418_driver = {
.driver = {
.name = "ad7418",
},
.attach_adapter = ad7418_attach_adapter,
.detach_client = ad7418_detach_client,
.probe = ad7418_probe,
.remove = ad7418_remove,
.id_table = ad7418_id,
};
/* All registers are word-sized, except for the configuration registers.
@ -192,13 +197,6 @@ static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 1);
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2);
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3);
static int ad7418_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, ad7418_detect);
}
static struct attribute *ad7416_attributes[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
@ -225,98 +223,46 @@ static struct attribute *ad7418_attributes[] = {
NULL
};
static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind)
static int ad7418_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_client *client;
struct i2c_adapter *adapter = client->adapter;
struct ad7418_data *data;
int err = 0;
int err;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
I2C_FUNC_SMBUS_WORD_DATA)) {
err = -EOPNOTSUPP;
goto exit;
}
if (!(data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
client->addr = address;
client->adapter = adapter;
client->driver = &ad7418_driver;
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
/* AD7418 has a curious behaviour on registers 6 and 7. They
* both always read 0xC071 and are not documented on the datasheet.
* We use them to detect the chip.
*/
if (kind <= 0) {
int reg, reg6, reg7;
/* the AD7416 lies within this address range, but I have
* no means to check.
*/
if (address >= 0x48 && address <= 0x4f) {
/* XXX add tests for AD7416 here */
/* data->type = ad7416; */
}
/* here we might have AD7417 or AD7418 */
else if (address >= 0x28 && address <= 0x2f) {
reg6 = i2c_smbus_read_word_data(client, 0x06);
reg7 = i2c_smbus_read_word_data(client, 0x07);
if (address == 0x28 && reg6 == 0xC071 && reg7 == 0xC071)
data->type = ad7418;
/* XXX add tests for AD7417 here */
/* both AD7417 and AD7418 have bits 0-5 of
* the CONF2 register at 0
*/
reg = i2c_smbus_read_byte_data(client,
AD7418_REG_CONF2);
if (reg & 0x3F)
data->type = any_chip; /* detection failed */
}
} else {
dev_dbg(&adapter->dev, "detection forced\n");
}
if (kind > 0)
data->type = kind;
else if (kind < 0 && data->type == any_chip) {
err = -ENODEV;
goto exit_free;
}
data->type = id->driver_data;
switch (data->type) {
case any_chip:
case ad7416:
data->adc_max = 0;
data->attrs.attrs = ad7416_attributes;
strlcpy(client->name, "ad7416", I2C_NAME_SIZE);
break;
case ad7417:
data->adc_max = 4;
data->attrs.attrs = ad7417_attributes;
strlcpy(client->name, "ad7417", I2C_NAME_SIZE);
break;
case ad7418:
data->adc_max = 1;
data->attrs.attrs = ad7418_attributes;
strlcpy(client->name, "ad7418", I2C_NAME_SIZE);
break;
}
if ((err = i2c_attach_client(client)))
goto exit_free;
dev_info(&client->dev, "%s chip found\n", client->name);
/* Initialize the AD7418 chip */
@ -324,7 +270,7 @@ static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind)
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -336,20 +282,17 @@ static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&client->dev.kobj, &data->attrs);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int ad7418_detach_client(struct i2c_client *client)
static int ad7418_remove(struct i2c_client *client)
{
struct ad7418_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &data->attrs);
i2c_detach_client(client);
kfree(data);
return 0;
}

View File

@ -78,7 +78,6 @@ clearing it. Weird, ey? --Phil */
/* Each client has this additional data */
struct adm1021_data {
struct i2c_client client;
struct device *hwmon_dev;
enum chips type;
@ -98,23 +97,42 @@ struct adm1021_data {
u8 remote_temp_offset_prec;
};
static int adm1021_attach_adapter(struct i2c_adapter *adapter);
static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind);
static int adm1021_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1021_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void adm1021_init_client(struct i2c_client *client);
static int adm1021_detach_client(struct i2c_client *client);
static int adm1021_remove(struct i2c_client *client);
static struct adm1021_data *adm1021_update_device(struct device *dev);
/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
static int read_only;
static const struct i2c_device_id adm1021_id[] = {
{ "adm1021", adm1021 },
{ "adm1023", adm1023 },
{ "max1617", max1617 },
{ "max1617a", max1617a },
{ "thmc10", thmc10 },
{ "lm84", lm84 },
{ "gl523sm", gl523sm },
{ "mc1066", mc1066 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1021_id);
/* This is the driver that will be inserted */
static struct i2c_driver adm1021_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1021",
},
.attach_adapter = adm1021_attach_adapter,
.detach_client = adm1021_detach_client,
.probe = adm1021_probe,
.remove = adm1021_remove,
.id_table = adm1021_id,
.detect = adm1021_detect,
.address_data = &addr_data,
};
static ssize_t show_temp(struct device *dev,
@ -216,13 +234,6 @@ static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
static int adm1021_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, adm1021_detect);
}
static struct attribute *adm1021_attributes[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
@ -243,36 +254,21 @@ static const struct attribute_group adm1021_group = {
.attrs = adm1021_attributes,
};
static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adm1021_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
int i;
struct i2c_client *client;
struct adm1021_data *data;
int err = 0;
const char *type_name = "";
int conv_rate, status, config;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
pr_debug("adm1021: detect failed, "
"smbus byte data not supported!\n");
goto error0;
return -ENODEV;
}
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access adm1021 register values. */
if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
pr_debug("adm1021: detect failed, kzalloc failed!\n");
err = -ENOMEM;
goto error0;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &adm1021_driver;
status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS);
conv_rate = i2c_smbus_read_byte_data(client,
ADM1021_REG_CONV_RATE_R);
@ -284,8 +280,7 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
|| (conv_rate & 0xF8) != 0x00) {
pr_debug("adm1021: detect failed, "
"chip not detected!\n");
err = -ENODEV;
goto error1;
return -ENODEV;
}
}
@ -336,24 +331,36 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
type_name = "mc1066";
}
pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n",
type_name, i2c_adapter_id(adapter), address);
type_name, i2c_adapter_id(adapter), client->addr);
strlcpy(info->type, type_name, I2C_NAME_SIZE);
/* Fill in the remaining client fields */
strlcpy(client->name, type_name, I2C_NAME_SIZE);
data->type = kind;
return 0;
}
static int adm1021_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1021_data *data;
int err;
data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL);
if (!data) {
pr_debug("adm1021: detect failed, kzalloc failed!\n");
err = -ENOMEM;
goto error0;
}
i2c_set_clientdata(client, data);
data->type = id->driver_data;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto error1;
/* Initialize the ADM1021 chip */
if (kind != lm84 && !read_only)
if (data->type != lm84 && !read_only)
adm1021_init_client(client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group)))
goto error2;
goto error1;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -365,8 +372,6 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
error3:
sysfs_remove_group(&client->dev.kobj, &adm1021_group);
error2:
i2c_detach_client(client);
error1:
kfree(data);
error0:
@ -382,17 +387,13 @@ static void adm1021_init_client(struct i2c_client *client)
i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
}
static int adm1021_detach_client(struct i2c_client *client)
static int adm1021_remove(struct i2c_client *client)
{
struct adm1021_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm1021_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -2,7 +2,7 @@
* adm1025.c
*
* Copyright (C) 2000 Chen-Yuan Wu <gwu@esoft.com>
* Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org>
* Copyright (C) 2003-2008 Jean Delvare <khali@linux-fr.org>
*
* The ADM1025 is a sensor chip made by Analog Devices. It reports up to 6
* voltages (including its own power source) and up to two temperatures
@ -109,22 +109,35 @@ static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 };
* Functions declaration
*/
static int adm1025_attach_adapter(struct i2c_adapter *adapter);
static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind);
static int adm1025_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1025_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void adm1025_init_client(struct i2c_client *client);
static int adm1025_detach_client(struct i2c_client *client);
static int adm1025_remove(struct i2c_client *client);
static struct adm1025_data *adm1025_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id adm1025_id[] = {
{ "adm1025", adm1025 },
{ "ne1619", ne1619 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1025_id);
static struct i2c_driver adm1025_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1025",
},
.attach_adapter = adm1025_attach_adapter,
.detach_client = adm1025_detach_client,
.probe = adm1025_probe,
.remove = adm1025_remove,
.id_table = adm1025_id,
.detect = adm1025_detect,
.address_data = &addr_data,
};
/*
@ -132,7 +145,6 @@ static struct i2c_driver adm1025_driver = {
*/
struct adm1025_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -344,13 +356,6 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
* Real code
*/
static int adm1025_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, adm1025_detect);
}
static struct attribute *adm1025_attributes[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
@ -403,31 +408,16 @@ static const struct attribute_group adm1025_group_in4 = {
.attrs = adm1025_attributes_in4,
};
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adm1025_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *client;
struct adm1025_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
const char *name = "";
u8 config;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct adm1025_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &adm1025_driver;
return -ENODEV;
/*
* Now we do the remaining detection. A negative kind means that
@ -448,8 +438,8 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
ADM1025_REG_STATUS2) & 0xBC) != 0x00) {
dev_dbg(&adapter->dev,
"ADM1025 detection failed at 0x%02x.\n",
address);
goto exit_free;
client->addr);
return -ENODEV;
}
}
@ -465,7 +455,7 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
}
} else
if (man_id == 0xA1) { /* Philips */
if (address != 0x2E
if (client->addr != 0x2E
&& (chip_id & 0xF0) == 0x20) { /* NE1619 */
kind = ne1619;
}
@ -475,7 +465,7 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&adapter->dev,
"Unsupported chip (man_id=0x%02X, "
"chip_id=0x%02X).\n", man_id, chip_id);
goto exit_free;
return -ENODEV;
}
}
@ -484,23 +474,36 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
} else if (kind == ne1619) {
name = "ne1619";
}
strlcpy(info->type, name, I2C_NAME_SIZE);
/* We can fill in the remaining client fields */
strlcpy(client->name, name, I2C_NAME_SIZE);
return 0;
}
static int adm1025_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1025_data *data;
int err;
u8 config;
data = kzalloc(sizeof(struct adm1025_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
/* Initialize the ADM1025 chip */
adm1025_init_client(client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &adm1025_group)))
goto exit_detach;
goto exit_free;
/* Pin 11 is either in4 (+12V) or VID4 */
config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
if (!(config & 0x20)) {
if ((err = sysfs_create_group(&client->dev.kobj,
&adm1025_group_in4)))
@ -518,8 +521,6 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&client->dev.kobj, &adm1025_group);
sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
@ -568,18 +569,14 @@ static void adm1025_init_client(struct i2c_client *client)
(reg&0x7E)|0x01);
}
static int adm1025_detach_client(struct i2c_client *client)
static int adm1025_remove(struct i2c_client *client)
{
struct adm1025_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm1025_group);
sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -259,7 +259,6 @@ struct pwm_data {
};
struct adm1026_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
@ -293,10 +292,11 @@ struct adm1026_data {
u8 config3; /* Register value */
};
static int adm1026_attach_adapter(struct i2c_adapter *adapter);
static int adm1026_detect(struct i2c_adapter *adapter, int address,
int kind);
static int adm1026_detach_client(struct i2c_client *client);
static int adm1026_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1026_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int adm1026_remove(struct i2c_client *client);
static int adm1026_read_value(struct i2c_client *client, u8 reg);
static int adm1026_write_value(struct i2c_client *client, u8 reg, int value);
static void adm1026_print_gpio(struct i2c_client *client);
@ -305,22 +305,24 @@ static struct adm1026_data *adm1026_update_device(struct device *dev);
static void adm1026_init_client(struct i2c_client *client);
static const struct i2c_device_id adm1026_id[] = {
{ "adm1026", adm1026 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1026_id);
static struct i2c_driver adm1026_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1026",
},
.attach_adapter = adm1026_attach_adapter,
.detach_client = adm1026_detach_client,
.probe = adm1026_probe,
.remove = adm1026_remove,
.id_table = adm1026_id,
.detect = adm1026_detect,
.address_data = &addr_data,
};
static int adm1026_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON)) {
return 0;
}
return i2c_probe(adapter, &addr_data, adm1026_detect);
}
static int adm1026_read_value(struct i2c_client *client, u8 reg)
{
int res;
@ -1647,48 +1649,32 @@ static const struct attribute_group adm1026_group_in8_9 = {
.attrs = adm1026_attributes_in8_9,
};
static int adm1026_detect(struct i2c_adapter *adapter, int address,
int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adm1026_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
int address = client->addr;
int company, verstep;
struct i2c_client *client;
struct adm1026_data *data;
int err = 0;
const char *type_name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
/* We need to be able to do byte I/O */
goto exit;
return -ENODEV;
};
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access adm1026_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &adm1026_driver;
/* Now, we do the remaining detection. */
company = adm1026_read_value(client, ADM1026_REG_COMPANY);
verstep = adm1026_read_value(client, ADM1026_REG_VERSTEP);
dev_dbg(&client->dev, "Detecting device at %d,0x%02x with"
dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with"
" COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
i2c_adapter_id(client->adapter), client->addr,
company, verstep);
/* If auto-detecting, Determine the chip type. */
if (kind <= 0) {
dev_dbg(&client->dev, "Autodetecting device at %d,0x%02x "
dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x "
"...\n", i2c_adapter_id(adapter), address);
if (company == ADM1026_COMPANY_ANALOG_DEV
&& verstep == ADM1026_VERSTEP_ADM1026) {
@ -1704,7 +1690,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address,
verstep);
kind = any_chip;
} else {
dev_dbg(&client->dev, ": Autodetection "
dev_dbg(&adapter->dev, ": Autodetection "
"failed\n");
/* Not an ADM1026 ... */
if (kind == 0) { /* User used force=x,y */
@ -1713,33 +1699,29 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address,
"force_adm1026.\n",
i2c_adapter_id(adapter), address);
}
goto exitfree;
return -ENODEV;
}
}
strlcpy(info->type, "adm1026", I2C_NAME_SIZE);
/* Fill in the chip specific driver values */
switch (kind) {
case any_chip :
type_name = "adm1026";
break;
case adm1026 :
type_name = "adm1026";
break;
default :
dev_err(&adapter->dev, ": Internal error, invalid "
"kind (%d)!\n", kind);
err = -EFAULT;
goto exitfree;
return 0;
}
static int adm1026_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1026_data *data;
int err;
data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
strlcpy(client->name, type_name, I2C_NAME_SIZE);
/* Fill in the remaining client fields */
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exitfree;
/* Set the VRM version */
data->vrm = vid_which_vrm();
@ -1748,7 +1730,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address,
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group)))
goto exitdetach;
goto exitfree;
if (data->config1 & CFG1_AIN8_9)
err = sysfs_create_group(&client->dev.kobj,
&adm1026_group_in8_9);
@ -1773,15 +1755,13 @@ exitremove:
sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9);
else
sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3);
exitdetach:
i2c_detach_client(client);
exitfree:
kfree(data);
exit:
return err;
}
static int adm1026_detach_client(struct i2c_client *client)
static int adm1026_remove(struct i2c_client *client)
{
struct adm1026_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
@ -1790,7 +1770,6 @@ static int adm1026_detach_client(struct i2c_client *client)
sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9);
else
sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3);
i2c_detach_client(client);
kfree(data);
return 0;
}

View File

@ -115,9 +115,11 @@ static const u8 ADM1029_REG_FAN_DIV[] = {
* Functions declaration
*/
static int adm1029_attach_adapter(struct i2c_adapter *adapter);
static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind);
static int adm1029_detach_client(struct i2c_client *client);
static int adm1029_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1029_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int adm1029_remove(struct i2c_client *client);
static struct adm1029_data *adm1029_update_device(struct device *dev);
static int adm1029_init_client(struct i2c_client *client);
@ -125,12 +127,22 @@ static int adm1029_init_client(struct i2c_client *client);
* Driver data (common to all clients)
*/
static const struct i2c_device_id adm1029_id[] = {
{ "adm1029", adm1029 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1029_id);
static struct i2c_driver adm1029_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1029",
},
.attach_adapter = adm1029_attach_adapter,
.detach_client = adm1029_detach_client,
.probe = adm1029_probe,
.remove = adm1029_remove,
.id_table = adm1029_id,
.detect = adm1029_detect,
.address_data = &addr_data,
};
/*
@ -138,7 +150,6 @@ static struct i2c_driver adm1029_driver = {
*/
struct adm1029_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -284,37 +295,14 @@ static const struct attribute_group adm1029_group = {
* Real code
*/
static int adm1029_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adm1029_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, adm1029_detect);
}
struct i2c_adapter *adapter = client->adapter;
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct adm1029_data *data;
int err = 0;
const char *name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct adm1029_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &adm1029_driver;
return -ENODEV;
/* Now we do the detection and identification. A negative kind
* means that the driver was loaded with no force parameter
@ -362,32 +350,41 @@ static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind <= 0) { /* identification failed */
pr_debug("adm1029: Unsupported chip (man_id=0x%02X, "
"chip_id=0x%02X)\n", man_id, chip_id);
goto exit_free;
return -ENODEV;
}
}
strlcpy(info->type, "adm1029", I2C_NAME_SIZE);
if (kind == adm1029) {
name = "adm1029";
return 0;
}
static int adm1029_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1029_data *data;
int err;
data = kzalloc(sizeof(struct adm1029_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
/* We can fill in the remaining client fields */
strlcpy(client->name, name, I2C_NAME_SIZE);
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
/*
* Initialize the ADM1029 chip
* Check config register
*/
if (adm1029_init_client(client) == 0)
goto exit_detach;
if (adm1029_init_client(client) == 0) {
err = -ENODEV;
goto exit_free;
}
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -399,8 +396,6 @@ static int adm1029_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&client->dev.kobj, &adm1029_group);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
@ -424,17 +419,13 @@ static int adm1029_init_client(struct i2c_client *client)
return 1;
}
static int adm1029_detach_client(struct i2c_client *client)
static int adm1029_remove(struct i2c_client *client)
{
struct adm1029_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm1029_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -70,7 +70,6 @@ typedef u8 auto_chan_table_t[8][2];
/* Each client has this additional data */
struct adm1031_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
int chip_type;
@ -99,19 +98,32 @@ struct adm1031_data {
s8 temp_crit[3];
};
static int adm1031_attach_adapter(struct i2c_adapter *adapter);
static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind);
static int adm1031_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1031_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void adm1031_init_client(struct i2c_client *client);
static int adm1031_detach_client(struct i2c_client *client);
static int adm1031_remove(struct i2c_client *client);
static struct adm1031_data *adm1031_update_device(struct device *dev);
static const struct i2c_device_id adm1031_id[] = {
{ "adm1030", adm1030 },
{ "adm1031", adm1031 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1031_id);
/* This is the driver that will be inserted */
static struct i2c_driver adm1031_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1031",
},
.attach_adapter = adm1031_attach_adapter,
.detach_client = adm1031_detach_client,
.probe = adm1031_probe,
.remove = adm1031_remove,
.id_table = adm1031_id,
.detect = adm1031_detect,
.address_data = &addr_data,
};
static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
@ -693,13 +705,6 @@ static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO, show_alarm, NULL, 12);
static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 13);
static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 14);
static int adm1031_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, adm1031_detect);
}
static struct attribute *adm1031_attributes[] = {
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan1_div.dev_attr.attr,
@ -770,27 +775,15 @@ static const struct attribute_group adm1031_group_opt = {
.attrs = adm1031_attributes_opt,
};
/* This function is called by i2c_probe */
static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adm1031_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *client;
struct adm1031_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
const char *name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &adm1031_driver;
return -ENODEV;
if (kind < 0) {
int id, co;
@ -798,7 +791,7 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
co = i2c_smbus_read_byte_data(client, 0x3e);
if (!((id == 0x31 || id == 0x30) && co == 0x41))
goto exit_free;
return -ENODEV;
kind = (id == 0x30) ? adm1030 : adm1031;
}
@ -809,28 +802,43 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
* auto fan control helper table. */
if (kind == adm1030) {
name = "adm1030";
data->chan_select_table = &auto_channel_select_table_adm1030;
} else if (kind == adm1031) {
name = "adm1031";
data->chan_select_table = &auto_channel_select_table_adm1031;
}
data->chip_type = kind;
strlcpy(info->type, name, I2C_NAME_SIZE);
strlcpy(client->name, name, I2C_NAME_SIZE);
return 0;
}
static int adm1031_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1031_data *data;
int err;
data = kzalloc(sizeof(struct adm1031_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->chip_type = id->driver_data;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
if (data->chip_type == adm1030)
data->chan_select_table = &auto_channel_select_table_adm1030;
else
data->chan_select_table = &auto_channel_select_table_adm1031;
/* Initialize the ADM1031 chip */
adm1031_init_client(client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &adm1031_group)))
goto exit_detach;
goto exit_free;
if (kind == adm1031) {
if (data->chip_type == adm1031) {
if ((err = sysfs_create_group(&client->dev.kobj,
&adm1031_group_opt)))
goto exit_remove;
@ -847,25 +855,19 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&client->dev.kobj, &adm1031_group);
sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int adm1031_detach_client(struct i2c_client *client)
static int adm1031_remove(struct i2c_client *client)
{
struct adm1031_data *data = i2c_get_clientdata(client);
int ret;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm1031_group);
sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
if ((ret = i2c_detach_client(client)) != 0) {
return ret;
}
kfree(data);
return 0;
}

View File

@ -130,25 +130,37 @@ static inline unsigned int AOUT_FROM_REG(u8 reg)
return SCALE(reg, 1250, 255);
}
static int adm9240_attach_adapter(struct i2c_adapter *adapter);
static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind);
static int adm9240_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm9240_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void adm9240_init_client(struct i2c_client *client);
static int adm9240_detach_client(struct i2c_client *client);
static int adm9240_remove(struct i2c_client *client);
static struct adm9240_data *adm9240_update_device(struct device *dev);
/* driver data */
static const struct i2c_device_id adm9240_id[] = {
{ "adm9240", adm9240 },
{ "ds1780", ds1780 },
{ "lm81", lm81 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm9240_id);
static struct i2c_driver adm9240_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm9240",
},
.attach_adapter = adm9240_attach_adapter,
.detach_client = adm9240_detach_client,
.probe = adm9240_probe,
.remove = adm9240_remove,
.id_table = adm9240_id,
.detect = adm9240_detect,
.address_data = &addr_data,
};
/* per client data */
struct adm9240_data {
enum chips type;
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid;
@ -532,28 +544,17 @@ static const struct attribute_group adm9240_group = {
/*** sensor chip detect and driver install ***/
static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adm9240_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *new_client;
struct adm9240_data *data;
int err = 0;
struct i2c_adapter *adapter = new_client->adapter;
const char *name = "";
int address = new_client->addr;
u8 man_id, die_rev;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &adm9240_driver;
new_client->flags = 0;
return -ENODEV;
if (kind == 0) {
kind = adm9240;
@ -566,7 +567,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
!= address) {
dev_err(&adapter->dev, "detect fail: address match, "
"0x%02x\n", address);
goto exit_free;
return -ENODEV;
}
/* check known chip manufacturer */
@ -581,7 +582,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
} else {
dev_err(&adapter->dev, "detect fail: unknown manuf, "
"0x%02x\n", man_id);
goto exit_free;
return -ENODEV;
}
/* successful detect, print chip info */
@ -600,20 +601,31 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
} else if (kind == lm81) {
name = "lm81";
}
strlcpy(info->type, name, I2C_NAME_SIZE);
/* fill in the remaining client fields and attach */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->type = kind;
return 0;
}
static int adm9240_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct adm9240_data *data;
int err;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
mutex_init(&data->update_lock);
if ((err = i2c_attach_client(new_client)))
goto exit_free;
adm9240_init_client(new_client);
/* populate sysfs filesystem */
if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -625,32 +637,19 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
return err;
}
static int adm9240_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, adm9240_detect);
}
static int adm9240_detach_client(struct i2c_client *client)
static int adm9240_remove(struct i2c_client *client)
{
struct adm9240_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm9240_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -64,7 +64,6 @@ static unsigned int ads7828_lsb_resol; /* resolution of the ADC sample lsb */
/* Each client has this additional data */
struct ads7828_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock; /* mutex protect updates */
char valid; /* !=0 if following fields are valid */
@ -73,7 +72,10 @@ struct ads7828_data {
};
/* Function declaration - necessary due to function dependencies */
static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind);
static int ads7828_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int ads7828_probe(struct i2c_client *client,
const struct i2c_device_id *id);
/* The ADS7828 returns the 12-bit sample in two bytes,
these are read as a word then byte-swapped */
@ -156,58 +158,43 @@ static const struct attribute_group ads7828_group = {
.attrs = ads7828_attributes,
};
static int ads7828_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, ads7828_detect);
}
static int ads7828_detach_client(struct i2c_client *client)
static int ads7828_remove(struct i2c_client *client)
{
struct ads7828_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &ads7828_group);
i2c_detach_client(client);
kfree(i2c_get_clientdata(client));
return 0;
}
static const struct i2c_device_id ads7828_id[] = {
{ "ads7828", ads7828 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ads7828_id);
/* This is the driver that will be inserted */
static struct i2c_driver ads7828_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "ads7828",
},
.attach_adapter = ads7828_attach_adapter,
.detach_client = ads7828_detach_client,
.probe = ads7828_probe,
.remove = ads7828_remove,
.id_table = ads7828_id,
.detect = ads7828_detect,
.address_data = &addr_data,
};
/* This function is called by i2c_probe */
static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int ads7828_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *client;
struct ads7828_data *data;
int err = 0;
const char *name = "";
struct i2c_adapter *adapter = client->adapter;
/* Check we have a valid client */
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access ads7828_read_value. */
data = kzalloc(sizeof(struct ads7828_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &ads7828_driver;
return -ENODEV;
/* Now, we do the remaining detection. There is no identification
dedicated register so attempt to sanity check using knowledge of
@ -225,32 +212,34 @@ static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind)
printk(KERN_DEBUG
"%s : Doesn't look like an ads7828 device\n",
__func__);
goto exit_free;
return -ENODEV;
}
}
}
strlcpy(info->type, "ads7828", I2C_NAME_SIZE);
/* Determine the chip type - only one kind supported! */
if (kind <= 0)
kind = ads7828;
return 0;
}
if (kind == ads7828)
name = "ads7828";
static int ads7828_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ads7828_data *data;
int err;
/* Fill in the remaining client fields, put it into the global list */
strlcpy(client->name, name, I2C_NAME_SIZE);
data = kzalloc(sizeof(struct ads7828_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
err = i2c_attach_client(client);
if (err)
goto exit_free;
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &ads7828_group);
if (err)
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -262,8 +251,6 @@ static int ads7828_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&client->dev.kobj, &ads7828_group);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:

View File

@ -138,7 +138,6 @@ I2C_CLIENT_INSMOD_1(adt7470);
#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID)
struct adt7470_data {
struct i2c_client client;
struct device *hwmon_dev;
struct attribute_group attrs;
struct mutex lock;
@ -164,16 +163,28 @@ struct adt7470_data {
u8 pwm_auto_temp[ADT7470_PWM_COUNT];
};
static int adt7470_attach_adapter(struct i2c_adapter *adapter);
static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind);
static int adt7470_detach_client(struct i2c_client *client);
static int adt7470_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adt7470_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int adt7470_remove(struct i2c_client *client);
static const struct i2c_device_id adt7470_id[] = {
{ "adt7470", adt7470 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adt7470_id);
static struct i2c_driver adt7470_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adt7470",
},
.attach_adapter = adt7470_attach_adapter,
.detach_client = adt7470_detach_client,
.probe = adt7470_probe,
.remove = adt7470_remove,
.id_table = adt7470_id,
.detect = adt7470_detect,
.address_data = &addr_data,
};
/*
@ -1004,64 +1015,52 @@ static struct attribute *adt7470_attr[] =
NULL
};
static int adt7470_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adt7470_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, adt7470_detect);
}
static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct adt7470_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
client->addr = address;
client->adapter = adapter;
client->driver = &adt7470_driver;
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
return -ENODEV;
if (kind <= 0) {
int vendor, device, revision;
vendor = i2c_smbus_read_byte_data(client, ADT7470_REG_VENDOR);
if (vendor != ADT7470_VENDOR) {
err = -ENODEV;
goto exit_free;
}
if (vendor != ADT7470_VENDOR)
return -ENODEV;
device = i2c_smbus_read_byte_data(client, ADT7470_REG_DEVICE);
if (device != ADT7470_DEVICE) {
err = -ENODEV;
goto exit_free;
}
if (device != ADT7470_DEVICE)
return -ENODEV;
revision = i2c_smbus_read_byte_data(client,
ADT7470_REG_REVISION);
if (revision != ADT7470_REVISION) {
err = -ENODEV;
goto exit_free;
}
if (revision != ADT7470_REVISION)
return -ENODEV;
} else
dev_dbg(&adapter->dev, "detection forced\n");
strlcpy(client->name, "adt7470", I2C_NAME_SIZE);
strlcpy(info->type, "adt7470", I2C_NAME_SIZE);
if ((err = i2c_attach_client(client)))
goto exit_free;
return 0;
}
static int adt7470_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adt7470_data *data;
int err;
data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
dev_info(&client->dev, "%s chip found\n", client->name);
@ -1071,7 +1070,7 @@ static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind)
/* Register sysfs hooks */
data->attrs.attrs = adt7470_attr;
if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -1083,21 +1082,18 @@ static int adt7470_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&client->dev.kobj, &data->attrs);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int adt7470_detach_client(struct i2c_client *client)
static int adt7470_remove(struct i2c_client *client)
{
struct adt7470_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &data->attrs);
i2c_detach_client(client);
kfree(data);
return 0;
}

View File

@ -143,7 +143,6 @@ I2C_CLIENT_INSMOD_1(adt7473);
#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID)
struct adt7473_data {
struct i2c_client client;
struct device *hwmon_dev;
struct attribute_group attrs;
struct mutex lock;
@ -178,16 +177,28 @@ struct adt7473_data {
u8 max_duty_at_overheat;
};
static int adt7473_attach_adapter(struct i2c_adapter *adapter);
static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind);
static int adt7473_detach_client(struct i2c_client *client);
static int adt7473_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adt7473_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int adt7473_remove(struct i2c_client *client);
static const struct i2c_device_id adt7473_id[] = {
{ "adt7473", adt7473 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adt7473_id);
static struct i2c_driver adt7473_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adt7473",
},
.attach_adapter = adt7473_attach_adapter,
.detach_client = adt7473_detach_client,
.probe = adt7473_probe,
.remove = adt7473_remove,
.id_table = adt7473_id,
.detect = adt7473_detect,
.address_data = &addr_data,
};
/*
@ -1042,21 +1053,43 @@ static struct attribute *adt7473_attr[] =
NULL
};
static int adt7473_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adt7473_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, adt7473_detect);
}
static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct adt7473_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
return -ENODEV;
if (kind <= 0) {
int vendor, device, revision;
vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
if (vendor != ADT7473_VENDOR)
return -ENODEV;
device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
if (device != ADT7473_DEVICE)
return -ENODEV;
revision = i2c_smbus_read_byte_data(client,
ADT7473_REG_REVISION);
if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69)
return -ENODEV;
} else
dev_dbg(&adapter->dev, "detection forced\n");
strlcpy(info->type, "adt7473", I2C_NAME_SIZE);
return 0;
}
static int adt7473_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adt7473_data *data;
int err;
data = kzalloc(sizeof(struct adt7473_data), GFP_KERNEL);
if (!data) {
@ -1064,45 +1097,9 @@ static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind)
goto exit;
}
client = &data->client;
client->addr = address;
client->adapter = adapter;
client->driver = &adt7473_driver;
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
if (kind <= 0) {
int vendor, device, revision;
vendor = i2c_smbus_read_byte_data(client, ADT7473_REG_VENDOR);
if (vendor != ADT7473_VENDOR) {
err = -ENODEV;
goto exit_free;
}
device = i2c_smbus_read_byte_data(client, ADT7473_REG_DEVICE);
if (device != ADT7473_DEVICE) {
err = -ENODEV;
goto exit_free;
}
revision = i2c_smbus_read_byte_data(client,
ADT7473_REG_REVISION);
if (revision != ADT7473_REV_68 && revision != ADT7473_REV_69) {
err = -ENODEV;
goto exit_free;
}
} else
dev_dbg(&adapter->dev, "detection forced\n");
strlcpy(client->name, "adt7473", I2C_NAME_SIZE);
err = i2c_attach_client(client);
if (err)
goto exit_free;
dev_info(&client->dev, "%s chip found\n", client->name);
/* Initialize the ADT7473 chip */
@ -1112,7 +1109,7 @@ static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind)
data->attrs.attrs = adt7473_attr;
err = sysfs_create_group(&client->dev.kobj, &data->attrs);
if (err)
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -1124,21 +1121,18 @@ static int adt7473_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&client->dev.kobj, &data->attrs);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int adt7473_detach_client(struct i2c_client *client)
static int adt7473_remove(struct i2c_client *client)
{
struct adt7473_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &data->attrs);
i2c_detach_client(client);
kfree(data);
return 0;
}

View File

@ -176,10 +176,8 @@ static u8 DIV_TO_REG(long val)
data is pointed to by client->data. The structure itself is
dynamically allocated, at the same time the client itself is allocated. */
struct asb100_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex lock;
enum chips type;
struct mutex update_lock;
unsigned long last_updated; /* In jiffies */
@ -206,18 +204,30 @@ struct asb100_data {
static int asb100_read_value(struct i2c_client *client, u16 reg);
static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val);
static int asb100_attach_adapter(struct i2c_adapter *adapter);
static int asb100_detect(struct i2c_adapter *adapter, int address, int kind);
static int asb100_detach_client(struct i2c_client *client);
static int asb100_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int asb100_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int asb100_remove(struct i2c_client *client);
static struct asb100_data *asb100_update_device(struct device *dev);
static void asb100_init_client(struct i2c_client *client);
static const struct i2c_device_id asb100_id[] = {
{ "asb100", asb100 },
{ }
};
MODULE_DEVICE_TABLE(i2c, asb100_id);
static struct i2c_driver asb100_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "asb100",
},
.attach_adapter = asb100_attach_adapter,
.detach_client = asb100_detach_client,
.probe = asb100_probe,
.remove = asb100_remove,
.id_table = asb100_id,
.detect = asb100_detect,
.address_data = &addr_data,
};
/* 7 Voltages */
@ -619,35 +629,13 @@ static const struct attribute_group asb100_group = {
.attrs = asb100_attributes,
};
/* This function is called when:
asb100_driver is inserted (when this module is loaded), for each
available adapter
when a new adapter is inserted (and asb100_driver is still present)
*/
static int asb100_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, asb100_detect);
}
static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
int kind, struct i2c_client *client)
static int asb100_detect_subclients(struct i2c_client *client)
{
int i, id, err;
int address = client->addr;
unsigned short sc_addr[2];
struct asb100_data *data = i2c_get_clientdata(client);
data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(data->lm75[0])) {
err = -ENOMEM;
goto ERROR_SC_0;
}
data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(data->lm75[1])) {
err = -ENOMEM;
goto ERROR_SC_1;
}
struct i2c_adapter *adapter = client->adapter;
id = i2c_adapter_id(adapter);
@ -665,37 +653,34 @@ static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
asb100_write_value(client, ASB100_REG_I2C_SUBADDR,
(force_subclients[2] & 0x07) |
((force_subclients[3] & 0x07) << 4));
data->lm75[0]->addr = force_subclients[2];
data->lm75[1]->addr = force_subclients[3];
sc_addr[0] = force_subclients[2];
sc_addr[1] = force_subclients[3];
} else {
int val = asb100_read_value(client, ASB100_REG_I2C_SUBADDR);
data->lm75[0]->addr = 0x48 + (val & 0x07);
data->lm75[1]->addr = 0x48 + ((val >> 4) & 0x07);
sc_addr[0] = 0x48 + (val & 0x07);
sc_addr[1] = 0x48 + ((val >> 4) & 0x07);
}
if (data->lm75[0]->addr == data->lm75[1]->addr) {
if (sc_addr[0] == sc_addr[1]) {
dev_err(&client->dev, "duplicate addresses 0x%x "
"for subclients\n", data->lm75[0]->addr);
"for subclients\n", sc_addr[0]);
err = -ENODEV;
goto ERROR_SC_2;
}
for (i = 0; i <= 1; i++) {
i2c_set_clientdata(data->lm75[i], NULL);
data->lm75[i]->adapter = adapter;
data->lm75[i]->driver = &asb100_driver;
strlcpy(data->lm75[i]->name, "asb100 subclient", I2C_NAME_SIZE);
}
if ((err = i2c_attach_client(data->lm75[0]))) {
data->lm75[0] = i2c_new_dummy(adapter, sc_addr[0]);
if (!data->lm75[0]) {
dev_err(&client->dev, "subclient %d registration "
"at address 0x%x failed.\n", i, data->lm75[0]->addr);
"at address 0x%x failed.\n", 1, sc_addr[0]);
err = -ENOMEM;
goto ERROR_SC_2;
}
if ((err = i2c_attach_client(data->lm75[1]))) {
data->lm75[1] = i2c_new_dummy(adapter, sc_addr[1]);
if (!data->lm75[1]) {
dev_err(&client->dev, "subclient %d registration "
"at address 0x%x failed.\n", i, data->lm75[1]->addr);
"at address 0x%x failed.\n", 2, sc_addr[1]);
err = -ENOMEM;
goto ERROR_SC_3;
}
@ -703,55 +688,31 @@ static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
/* Undo inits in case of errors */
ERROR_SC_3:
i2c_detach_client(data->lm75[0]);
i2c_unregister_device(data->lm75[0]);
ERROR_SC_2:
kfree(data->lm75[1]);
ERROR_SC_1:
kfree(data->lm75[0]);
ERROR_SC_0:
return err;
}
static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int asb100_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
int err;
struct i2c_client *client;
struct asb100_data *data;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
pr_debug("asb100.o: detect failed, "
"smbus byte data not supported!\n");
err = -ENODEV;
goto ERROR0;
return -ENODEV;
}
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access asb100_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
pr_debug("asb100.o: detect failed, kzalloc failed!\n");
err = -ENOMEM;
goto ERROR0;
}
client = &data->client;
mutex_init(&data->lock);
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &asb100_driver;
/* Now, we do the remaining detection. */
/* The chip may be stuck in some other bank than bank 0. This may
make reading other information impossible. Specify a force=... or
force_*=... parameter, and the chip will be reset to the right
bank. */
if (kind < 0) {
int val1 = asb100_read_value(client, ASB100_REG_BANK);
int val2 = asb100_read_value(client, ASB100_REG_CHIPMAN);
int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_BANK);
int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
/* If we're in bank 0 */
if ((!(val1 & 0x07)) &&
@ -761,48 +722,60 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
((val1 & 0x80) && (val2 != 0x06)))) {
pr_debug("asb100.o: detect failed, "
"bad chip id 0x%02x!\n", val2);
err = -ENODEV;
goto ERROR1;
return -ENODEV;
}
} /* kind < 0 */
/* We have either had a force parameter, or we have already detected
Winbond. Put it now into bank 0 and Vendor ID High Byte */
asb100_write_value(client, ASB100_REG_BANK,
(asb100_read_value(client, ASB100_REG_BANK) & 0x78) | 0x80);
i2c_smbus_write_byte_data(client, ASB100_REG_BANK,
(i2c_smbus_read_byte_data(client, ASB100_REG_BANK) & 0x78)
| 0x80);
/* Determine the chip type. */
if (kind <= 0) {
int val1 = asb100_read_value(client, ASB100_REG_WCHIPID);
int val2 = asb100_read_value(client, ASB100_REG_CHIPMAN);
int val1 = i2c_smbus_read_byte_data(client, ASB100_REG_WCHIPID);
int val2 = i2c_smbus_read_byte_data(client, ASB100_REG_CHIPMAN);
if ((val1 == 0x31) && (val2 == 0x06))
kind = asb100;
else {
if (kind == 0)
dev_warn(&client->dev, "ignoring "
dev_warn(&adapter->dev, "ignoring "
"'force' parameter for unknown chip "
"at adapter %d, address 0x%02x.\n",
i2c_adapter_id(adapter), address);
err = -ENODEV;
goto ERROR1;
i2c_adapter_id(adapter), client->addr);
return -ENODEV;
}
}
/* Fill in remaining client fields and put it into the global list */
strlcpy(client->name, "asb100", I2C_NAME_SIZE);
data->type = kind;
strlcpy(info->type, "asb100", I2C_NAME_SIZE);
return 0;
}
static int asb100_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err;
struct asb100_data *data;
data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL);
if (!data) {
pr_debug("asb100.o: probe failed, kzalloc failed!\n");
err = -ENOMEM;
goto ERROR0;
}
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto ERROR1;
/* Attach secondary lm75 clients */
if ((err = asb100_detect_subclients(adapter, address, kind,
client)))
goto ERROR2;
err = asb100_detect_subclients(client);
if (err)
goto ERROR1;
/* Initialize the chip */
asb100_init_client(client);
@ -827,39 +800,25 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
ERROR4:
sysfs_remove_group(&client->dev.kobj, &asb100_group);
ERROR3:
i2c_detach_client(data->lm75[1]);
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[1]);
kfree(data->lm75[0]);
ERROR2:
i2c_detach_client(client);
i2c_unregister_device(data->lm75[1]);
i2c_unregister_device(data->lm75[0]);
ERROR1:
kfree(data);
ERROR0:
return err;
}
static int asb100_detach_client(struct i2c_client *client)
static int asb100_remove(struct i2c_client *client)
{
struct asb100_data *data = i2c_get_clientdata(client);
int err;
/* main client */
if (data) {
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &asb100_group);
}
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &asb100_group);
if ((err = i2c_detach_client(client)))
return err;
i2c_unregister_device(data->lm75[1]);
i2c_unregister_device(data->lm75[0]);
/* main client */
if (data)
kfree(data);
/* subclient */
else
kfree(client);
kfree(data);
return 0;
}

View File

@ -46,21 +46,32 @@ static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
I2C_CLIENT_INSMOD_1(atxp1);
static int atxp1_attach_adapter(struct i2c_adapter * adapter);
static int atxp1_detach_client(struct i2c_client * client);
static int atxp1_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int atxp1_remove(struct i2c_client *client);
static struct atxp1_data * atxp1_update_device(struct device *dev);
static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind);
static int atxp1_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static const struct i2c_device_id atxp1_id[] = {
{ "atxp1", atxp1 },
{ }
};
MODULE_DEVICE_TABLE(i2c, atxp1_id);
static struct i2c_driver atxp1_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "atxp1",
},
.attach_adapter = atxp1_attach_adapter,
.detach_client = atxp1_detach_client,
.probe = atxp1_probe,
.remove = atxp1_remove,
.id_table = atxp1_id,
.detect = atxp1_detect,
.address_data = &addr_data,
};
struct atxp1_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
unsigned long last_updated;
@ -263,35 +274,16 @@ static const struct attribute_group atxp1_group = {
};
static int atxp1_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int atxp1_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, &atxp1_detect);
};
struct i2c_adapter *adapter = new_client->adapter;
static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client * new_client;
struct atxp1_data * data;
int err = 0;
u8 temp;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &atxp1_driver;
new_client->flags = 0;
return -ENODEV;
/* Detect ATXP1, checking if vendor ID registers are all zero */
if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) &&
@ -305,35 +297,46 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) &&
(i2c_smbus_read_byte_data(new_client, 0x11) == temp) ))
goto exit_free;
return -ENODEV;
}
/* Get VRM */
temp = vid_which_vrm();
if ((temp != 90) && (temp != 91)) {
dev_err(&adapter->dev, "atxp1: Not supporting VRM %d.%d\n",
temp / 10, temp % 10);
return -ENODEV;
}
strlcpy(info->type, "atxp1", I2C_NAME_SIZE);
return 0;
}
static int atxp1_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct atxp1_data *data;
int err;
data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
/* Get VRM */
data->vrm = vid_which_vrm();
if ((data->vrm != 90) && (data->vrm != 91)) {
dev_err(&new_client->dev, "Not supporting VRM %d.%d\n",
data->vrm / 10, data->vrm % 10);
goto exit_free;
}
strncpy(new_client->name, "atxp1", I2C_NAME_SIZE);
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
err = i2c_attach_client(new_client);
if (err)
{
dev_err(&new_client->dev, "Attach client error.\n");
goto exit_free;
}
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -348,30 +351,22 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &atxp1_group);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
return err;
};
static int atxp1_detach_client(struct i2c_client * client)
static int atxp1_remove(struct i2c_client *client)
{
struct atxp1_data * data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &atxp1_group);
err = i2c_detach_client(client);
kfree(data);
if (err)
dev_err(&client->dev, "Failed to detach client.\n");
else
kfree(data);
return err;
return 0;
};
static int __init atxp1_init(void)

View File

@ -72,7 +72,6 @@ static const u8 DS1621_REG_TEMP[3] = {
/* Each client has this additional data */
struct ds1621_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
@ -82,20 +81,32 @@ struct ds1621_data {
u8 conf; /* Register encoding, combined */
};
static int ds1621_attach_adapter(struct i2c_adapter *adapter);
static int ds1621_detect(struct i2c_adapter *adapter, int address,
int kind);
static int ds1621_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int ds1621_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void ds1621_init_client(struct i2c_client *client);
static int ds1621_detach_client(struct i2c_client *client);
static int ds1621_remove(struct i2c_client *client);
static struct ds1621_data *ds1621_update_client(struct device *dev);
static const struct i2c_device_id ds1621_id[] = {
{ "ds1621", ds1621 },
{ "ds1625", ds1621 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ds1621_id);
/* This is the driver that will be inserted */
static struct i2c_driver ds1621_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "ds1621",
},
.attach_adapter = ds1621_attach_adapter,
.detach_client = ds1621_detach_client,
.probe = ds1621_probe,
.remove = ds1621_remove,
.id_table = ds1621_id,
.detect = ds1621_detect,
.address_data = &addr_data,
};
/* All registers are word-sized, except for the configuration register.
@ -199,40 +210,18 @@ static const struct attribute_group ds1621_group = {
};
static int ds1621_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, ds1621_detect);
}
/* This function is called by i2c_probe */
static int ds1621_detect(struct i2c_adapter *adapter, int address,
int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int ds1621_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
int conf, temp;
struct i2c_client *client;
struct ds1621_data *data;
int i, err = 0;
int i;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
| I2C_FUNC_SMBUS_WORD_DATA
| I2C_FUNC_SMBUS_WRITE_BYTE))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access ds1621_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &ds1621_driver;
return -ENODEV;
/* Now, we do the remaining detection. It is lousy. */
if (kind < 0) {
@ -241,29 +230,41 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address,
improbable in our case. */
conf = ds1621_read_value(client, DS1621_REG_CONF);
if (conf & DS1621_REG_CONFIG_NVB)
goto exit_free;
return -ENODEV;
/* The 7 lowest bits of a temperature should always be 0. */
for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) {
temp = ds1621_read_value(client, DS1621_REG_TEMP[i]);
if (temp & 0x007f)
goto exit_free;
return -ENODEV;
}
}
/* Fill in remaining client fields and put it into the global list */
strlcpy(client->name, "ds1621", I2C_NAME_SIZE);
mutex_init(&data->update_lock);
strlcpy(info->type, "ds1621", I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
return 0;
}
static int ds1621_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ds1621_data *data;
int err;
data = kzalloc(sizeof(struct ds1621_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Initialize the DS1621 chip */
ds1621_init_client(client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -275,25 +276,19 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address,
exit_remove_files:
sysfs_remove_group(&client->dev.kobj, &ds1621_group);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int ds1621_detach_client(struct i2c_client *client)
static int ds1621_remove(struct i2c_client *client)
{
struct ds1621_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &ds1621_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;

View File

@ -87,7 +87,6 @@ I2C_CLIENT_INSMOD_2(f75373, f75375);
struct f75375_data {
unsigned short addr;
struct i2c_client *client;
struct device *hwmon_dev;
const char *name;
@ -114,21 +113,12 @@ struct f75375_data {
s8 temp_max_hyst[2];
};
static int f75375_attach_adapter(struct i2c_adapter *adapter);
static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
static int f75375_detach_client(struct i2c_client *client);
static int f75375_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int f75375_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int f75375_remove(struct i2c_client *client);
static struct i2c_driver f75375_legacy_driver = {
.driver = {
.name = "f75375_legacy",
},
.attach_adapter = f75375_attach_adapter,
.detach_client = f75375_detach_client,
};
static const struct i2c_device_id f75375_id[] = {
{ "f75373", f75373 },
{ "f75375", f75375 },
@ -137,12 +127,15 @@ static const struct i2c_device_id f75375_id[] = {
MODULE_DEVICE_TABLE(i2c, f75375_id);
static struct i2c_driver f75375_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "f75375",
},
.probe = f75375_probe,
.remove = f75375_remove,
.id_table = f75375_id,
.detect = f75375_detect,
.address_data = &addr_data,
};
static inline int f75375_read8(struct i2c_client *client, u8 reg)
@ -607,22 +600,6 @@ static const struct attribute_group f75375_group = {
.attrs = f75375_attributes,
};
static int f75375_detach_client(struct i2c_client *client)
{
int err;
f75375_remove(client);
err = i2c_detach_client(client);
if (err) {
dev_err(&client->dev,
"Client deregistration failed, "
"client not detached.\n");
return err;
}
kfree(client);
return 0;
}
static void f75375_init(struct i2c_client *client, struct f75375_data *data,
struct f75375s_platform_data *f75375s_pdata)
{
@ -651,7 +628,6 @@ static int f75375_probe(struct i2c_client *client,
return -ENOMEM;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->update_lock);
data->kind = id->driver_data;
@ -700,29 +676,13 @@ static int f75375_remove(struct i2c_client *client)
return 0;
}
static int f75375_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int f75375_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, f75375_detect);
}
/* This function is called by i2c_probe */
static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct i2c_adapter *adapter = client->adapter;
u8 version = 0;
int err = 0;
const char *name = "";
struct i2c_device_id id;
if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client->addr = address;
client->adapter = adapter;
client->driver = &f75375_legacy_driver;
if (kind < 0) {
u16 vendid = f75375_read16(client, F75375_REG_VENDOR);
@ -736,7 +696,7 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
dev_err(&adapter->dev,
"failed,%02X,%02X,%02X\n",
chipid, version, vendid);
goto exit_free;
return -ENODEV;
}
}
@ -746,43 +706,18 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
name = "f75373";
}
dev_info(&adapter->dev, "found %s version: %02X\n", name, version);
strlcpy(client->name, name, I2C_NAME_SIZE);
if ((err = i2c_attach_client(client)))
goto exit_free;
strlcpy(id.name, name, I2C_NAME_SIZE);
id.driver_data = kind;
if ((err = f75375_probe(client, &id)) < 0)
goto exit_detach;
strlcpy(info->type, name, I2C_NAME_SIZE);
return 0;
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(client);
exit:
return err;
}
static int __init sensors_f75375_init(void)
{
int status;
status = i2c_add_driver(&f75375_driver);
if (status)
return status;
status = i2c_add_driver(&f75375_legacy_driver);
if (status)
i2c_del_driver(&f75375_driver);
return status;
return i2c_add_driver(&f75375_driver);
}
static void __exit sensors_f75375_exit(void)
{
i2c_del_driver(&f75375_legacy_driver);
i2c_del_driver(&f75375_driver);
}

View File

@ -106,9 +106,11 @@ I2C_CLIENT_INSMOD_1(fscher);
* Functions declaration
*/
static int fscher_attach_adapter(struct i2c_adapter *adapter);
static int fscher_detect(struct i2c_adapter *adapter, int address, int kind);
static int fscher_detach_client(struct i2c_client *client);
static int fscher_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int fscher_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int fscher_remove(struct i2c_client *client);
static struct fscher_data *fscher_update_device(struct device *dev);
static void fscher_init_client(struct i2c_client *client);
@ -119,12 +121,21 @@ static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value);
* Driver data (common to all clients)
*/
static const struct i2c_device_id fscher_id[] = {
{ "fscher", fscher },
{ }
};
static struct i2c_driver fscher_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "fscher",
},
.attach_adapter = fscher_attach_adapter,
.detach_client = fscher_detach_client,
.probe = fscher_probe,
.remove = fscher_remove,
.id_table = fscher_id,
.detect = fscher_detect,
.address_data = &addr_data,
};
/*
@ -132,7 +143,6 @@ static struct i2c_driver fscher_driver = {
*/
struct fscher_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -283,38 +293,14 @@ static const struct attribute_group fscher_group = {
* Real code
*/
static int fscher_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int fscher_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, fscher_detect);
}
static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct fscher_data *data;
int err = 0;
struct i2c_adapter *adapter = new_client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
* client structure, even though we cannot fill it completely yet.
* But it allows us to access i2c_smbus_read_byte_data. */
if (!(data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
/* The common I2C client data is placed right before the
* Hermes-specific data. */
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &fscher_driver;
new_client->flags = 0;
return -ENODEV;
/* Do the remaining detection unless force or force_fscher parameter */
if (kind < 0) {
@ -324,24 +310,35 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
FSCHER_REG_IDENT_1) != 0x45) /* 'E' */
|| (i2c_smbus_read_byte_data(new_client,
FSCHER_REG_IDENT_2) != 0x52)) /* 'R' */
goto exit_free;
return -ENODEV;
}
/* Fill in the remaining client fields and put it into the
* global list */
strlcpy(new_client->name, "fscher", I2C_NAME_SIZE);
strlcpy(info->type, "fscher", I2C_NAME_SIZE);
return 0;
}
static int fscher_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct fscher_data *data;
int err;
data = kzalloc(sizeof(struct fscher_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
fscher_init_client(new_client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &fscher_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -353,25 +350,19 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &fscher_group);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
return err;
}
static int fscher_detach_client(struct i2c_client *client)
static int fscher_remove(struct i2c_client *client)
{
struct fscher_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &fscher_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -171,20 +171,37 @@ static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
* Functions declarations
*/
static int fschmd_attach_adapter(struct i2c_adapter *adapter);
static int fschmd_detach_client(struct i2c_client *client);
static int fschmd_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int fschmd_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int fschmd_remove(struct i2c_client *client);
static struct fschmd_data *fschmd_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id fschmd_id[] = {
{ "fscpos", fscpos },
{ "fscher", fscher },
{ "fscscy", fscscy },
{ "fschrc", fschrc },
{ "fschmd", fschmd },
{ }
};
MODULE_DEVICE_TABLE(i2c, fschmd_id);
static struct i2c_driver fschmd_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = FSCHMD_NAME,
},
.attach_adapter = fschmd_attach_adapter,
.detach_client = fschmd_detach_client,
.probe = fschmd_probe,
.remove = fschmd_remove,
.id_table = fschmd_id,
.detect = fschmd_detect,
.address_data = &addr_data,
};
/*
@ -192,7 +209,6 @@ static struct i2c_driver fschmd_driver = {
*/
struct fschmd_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
int kind;
@ -269,7 +285,7 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute
v = SENSORS_LIMIT(v, -128, 127) + 128;
mutex_lock(&data->update_lock);
i2c_smbus_write_byte_data(&data->client,
i2c_smbus_write_byte_data(to_i2c_client(dev),
FSCHMD_REG_TEMP_LIMIT[data->kind][index], v);
data->temp_max[index] = v;
mutex_unlock(&data->update_lock);
@ -346,14 +362,14 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute
mutex_lock(&data->update_lock);
reg = i2c_smbus_read_byte_data(&data->client,
reg = i2c_smbus_read_byte_data(to_i2c_client(dev),
FSCHMD_REG_FAN_RIPPLE[data->kind][index]);
/* bits 2..7 reserved => mask with 0x03 */
reg &= ~0x03;
reg |= v;
i2c_smbus_write_byte_data(&data->client,
i2c_smbus_write_byte_data(to_i2c_client(dev),
FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg);
data->fan_ripple[index] = reg;
@ -416,7 +432,7 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
mutex_lock(&data->update_lock);
i2c_smbus_write_byte_data(&data->client,
i2c_smbus_write_byte_data(to_i2c_client(dev),
FSCHMD_REG_FAN_MIN[data->kind][index], v);
data->fan_min[index] = v;
@ -448,14 +464,14 @@ static ssize_t store_alert_led(struct device *dev,
mutex_lock(&data->update_lock);
reg = i2c_smbus_read_byte_data(&data->client, FSCHMD_REG_CONTROL);
reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL);
if (v)
reg |= FSCHMD_CONTROL_ALERT_LED_MASK;
else
reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK;
i2c_smbus_write_byte_data(&data->client, FSCHMD_REG_CONTROL, reg);
i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg);
data->global_control = reg;
@ -600,32 +616,15 @@ static void fschmd_dmi_decode(const struct dmi_header *header)
}
}
static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
static int fschmd_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *client;
struct fschmd_data *data;
u8 revision;
const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
"Heracles", "Heimdall" };
struct i2c_adapter *adapter = client->adapter;
const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
"fschrc", "fschmd" };
int i, err = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return 0;
/* OK. For now, we presume we have a valid client. We now create the
* client structure, even though we cannot fill it completely yet.
* But it allows us to access i2c_smbus_read_byte_data. */
if (!(data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL)))
return -ENOMEM;
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &fschmd_driver;
mutex_init(&data->update_lock);
return -ENODEV;
/* Detect & Identify the chip */
if (kind <= 0) {
@ -650,9 +649,31 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
else if (!strcmp(id, "HMD"))
kind = fschmd;
else
goto exit_free;
return -ENODEV;
}
strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE);
return 0;
}
static int fschmd_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct fschmd_data *data;
u8 revision;
const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
"Heracles", "Heimdall" };
int i, err;
enum chips kind = id->driver_data;
data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
if (kind == fscpos) {
/* The Poseidon has hardwired temp limits, fill these
in for the alarm resetting code */
@ -674,11 +695,6 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
/* i2c kind goes from 1-5, we want from 0-4 to address arrays */
data->kind = kind - 1;
strlcpy(client->name, client_names[data->kind], I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
err = device_create_file(&client->dev,
@ -726,25 +742,14 @@ static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
return 0;
exit_detach:
fschmd_detach_client(client); /* will also free data for us */
return err;
exit_free:
kfree(data);
fschmd_remove(client); /* will also free data for us */
return err;
}
static int fschmd_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, fschmd_detect);
}
static int fschmd_detach_client(struct i2c_client *client)
static int fschmd_remove(struct i2c_client *client)
{
struct fschmd_data *data = i2c_get_clientdata(client);
int i, err;
int i;
/* Check if registered in case we're called from fschmd_detect
to cleanup after an error */
@ -760,9 +765,6 @@ static int fschmd_detach_client(struct i2c_client *client)
device_remove_file(&client->dev,
&fschmd_fan_attr[i].dev_attr);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -87,9 +87,11 @@ static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 };
/*
* Functions declaration
*/
static int fscpos_attach_adapter(struct i2c_adapter *adapter);
static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind);
static int fscpos_detach_client(struct i2c_client *client);
static int fscpos_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int fscpos_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int fscpos_remove(struct i2c_client *client);
static int fscpos_read_value(struct i2c_client *client, u8 reg);
static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value);
@ -101,19 +103,27 @@ static void reset_fan_alarm(struct i2c_client *client, int nr);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id fscpos_id[] = {
{ "fscpos", fscpos },
{ }
};
static struct i2c_driver fscpos_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "fscpos",
},
.attach_adapter = fscpos_attach_adapter,
.detach_client = fscpos_detach_client,
.probe = fscpos_probe,
.remove = fscpos_remove,
.id_table = fscpos_id,
.detect = fscpos_detect,
.address_data = &addr_data,
};
/*
* Client data (each client gets its own)
*/
struct fscpos_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* 0 until following fields are valid */
@ -470,39 +480,14 @@ static const struct attribute_group fscpos_group = {
.attrs = fscpos_attributes,
};
static int fscpos_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int fscpos_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, fscpos_detect);
}
static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct fscpos_data *data;
int err = 0;
struct i2c_adapter *adapter = new_client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
/*
* OK. For now, we presume we have a valid client. We now create the
* client structure, even though we cannot fill it completely yet.
* But it allows us to access fscpos_{read,write}_value.
*/
if (!(data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &fscpos_driver;
new_client->flags = 0;
return -ENODEV;
/* Do the remaining detection unless force or force_fscpos parameter */
if (kind < 0) {
@ -512,22 +497,30 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
!= 0x45) /* 'E' */
|| (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2)
!= 0x47))/* 'G' */
{
dev_dbg(&new_client->dev, "fscpos detection failed\n");
goto exit_free;
}
return -ENODEV;
}
/* Fill in the remaining client fields and put it in the global list */
strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE);
strlcpy(info->type, "fscpos", I2C_NAME_SIZE);
return 0;
}
static int fscpos_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct fscpos_data *data;
int err;
data = kzalloc(sizeof(struct fscpos_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Inizialize the fscpos chip */
fscpos_init_client(new_client);
@ -536,7 +529,7 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &fscpos_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -548,24 +541,19 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &fscpos_group);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
return err;
}
static int fscpos_detach_client(struct i2c_client *client)
static int fscpos_remove(struct i2c_client *client)
{
struct fscpos_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &fscpos_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -114,7 +114,6 @@ static inline u8 FAN_TO_REG(long rpm, int div)
/* Each client has this additional data */
struct gl518_data {
struct i2c_client client;
struct device *hwmon_dev;
enum chips type;
@ -138,21 +137,33 @@ struct gl518_data {
u8 beep_enable; /* Boolean */
};
static int gl518_attach_adapter(struct i2c_adapter *adapter);
static int gl518_detect(struct i2c_adapter *adapter, int address, int kind);
static int gl518_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int gl518_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void gl518_init_client(struct i2c_client *client);
static int gl518_detach_client(struct i2c_client *client);
static int gl518_remove(struct i2c_client *client);
static int gl518_read_value(struct i2c_client *client, u8 reg);
static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value);
static struct gl518_data *gl518_update_device(struct device *dev);
static const struct i2c_device_id gl518_id[] = {
{ "gl518sm", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, gl518_id);
/* This is the driver that will be inserted */
static struct i2c_driver gl518_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "gl518sm",
},
.attach_adapter = gl518_attach_adapter,
.detach_client = gl518_detach_client,
.probe = gl518_probe,
.remove = gl518_remove,
.id_table = gl518_id,
.detect = gl518_detect,
.address_data = &addr_data,
};
/*
@ -472,46 +483,23 @@ static const struct attribute_group gl518_group_r80 = {
* Real code
*/
static int gl518_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, gl518_detect);
}
static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int gl518_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
int i;
struct i2c_client *client;
struct gl518_data *data;
int err = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access gl518_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &gl518_driver;
return -ENODEV;
/* Now, we do the remaining detection. */
if (kind < 0) {
if ((gl518_read_value(client, GL518_REG_CHIP_ID) != 0x80)
|| (gl518_read_value(client, GL518_REG_CONF) & 0x80))
goto exit_free;
return -ENODEV;
}
/* Determine the chip type. */
@ -526,19 +514,32 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&adapter->dev,
"Ignoring 'force' parameter for unknown "
"chip at adapter %d, address 0x%02x\n",
i2c_adapter_id(adapter), address);
goto exit_free;
i2c_adapter_id(adapter), client->addr);
return -ENODEV;
}
}
/* Fill in the remaining client fields */
strlcpy(client->name, "gl518sm", I2C_NAME_SIZE);
data->type = kind;
mutex_init(&data->update_lock);
strlcpy(info->type, "gl518sm", I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
return 0;
}
static int gl518_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct gl518_data *data;
int err, revision;
data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
revision = gl518_read_value(client, GL518_REG_REVISION);
data->type = revision == 0x80 ? gl518sm_r80 : gl518sm_r00;
mutex_init(&data->update_lock);
/* Initialize the GL518SM chip */
data->alarm_mask = 0xff;
@ -546,7 +547,7 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &gl518_group)))
goto exit_detach;
goto exit_free;
if (data->type == gl518sm_r80)
if ((err = sysfs_create_group(&client->dev.kobj,
&gl518_group_r80)))
@ -564,8 +565,6 @@ exit_remove_files:
sysfs_remove_group(&client->dev.kobj, &gl518_group);
if (data->type == gl518sm_r80)
sysfs_remove_group(&client->dev.kobj, &gl518_group_r80);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
@ -591,19 +590,15 @@ static void gl518_init_client(struct i2c_client *client)
gl518_write_value(client, GL518_REG_CONF, 0x40 | regvalue);
}
static int gl518_detach_client(struct i2c_client *client)
static int gl518_remove(struct i2c_client *client)
{
struct gl518_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &gl518_group);
if (data->type == gl518sm_r80)
sysfs_remove_group(&client->dev.kobj, &gl518_group_r80);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -79,26 +79,37 @@ static const u8 GL520_REG_TEMP_MAX_HYST[] = { 0x06, 0x18 };
* Function declarations
*/
static int gl520_attach_adapter(struct i2c_adapter *adapter);
static int gl520_detect(struct i2c_adapter *adapter, int address, int kind);
static int gl520_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int gl520_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void gl520_init_client(struct i2c_client *client);
static int gl520_detach_client(struct i2c_client *client);
static int gl520_remove(struct i2c_client *client);
static int gl520_read_value(struct i2c_client *client, u8 reg);
static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value);
static struct gl520_data *gl520_update_device(struct device *dev);
/* Driver data */
static const struct i2c_device_id gl520_id[] = {
{ "gl520sm", gl520sm },
{ }
};
MODULE_DEVICE_TABLE(i2c, gl520_id);
static struct i2c_driver gl520_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "gl520sm",
},
.attach_adapter = gl520_attach_adapter,
.detach_client = gl520_detach_client,
.probe = gl520_probe,
.remove = gl520_remove,
.id_table = gl520_id,
.detect = gl520_detect,
.address_data = &addr_data,
};
/* Client data */
struct gl520_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until the following fields are valid */
@ -669,37 +680,15 @@ static const struct attribute_group gl520_group_opt = {
* Real code
*/
static int gl520_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int gl520_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, gl520_detect);
}
static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct gl520_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access gl520_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &gl520_driver;
return -ENODEV;
/* Determine the chip type. */
if (kind < 0) {
@ -707,24 +696,36 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) {
dev_dbg(&client->dev, "Unknown chip type, skipping\n");
goto exit_free;
return -ENODEV;
}
}
/* Fill in the remaining client fields */
strlcpy(client->name, "gl520sm", I2C_NAME_SIZE);
mutex_init(&data->update_lock);
strlcpy(info->type, "gl520sm", I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
return 0;
}
static int gl520_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct gl520_data *data;
int err;
data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Initialize the GL520SM chip */
gl520_init_client(client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &gl520_group)))
goto exit_detach;
goto exit_free;
if (data->two_temps) {
if ((err = device_create_file(&client->dev,
@ -764,8 +765,6 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&client->dev.kobj, &gl520_group);
sysfs_remove_group(&client->dev.kobj, &gl520_group_opt);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
@ -811,18 +810,14 @@ static void gl520_init_client(struct i2c_client *client)
gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
}
static int gl520_detach_client(struct i2c_client *client)
static int gl520_remove(struct i2c_client *client)
{
struct gl520_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &gl520_group);
sysfs_remove_group(&client->dev.kobj, &gl520_group_opt);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -1,7 +1,7 @@
/*
* lm63.c - driver for the National Semiconductor LM63 temperature sensor
* with integrated fan control
* Copyright (C) 2004-2006 Jean Delvare <khali@linux-fr.org>
* Copyright (C) 2004-2008 Jean Delvare <khali@linux-fr.org>
* Based on the lm90 driver.
*
* The LM63 is a sensor chip made by National Semiconductor. It measures
@ -128,24 +128,36 @@ I2C_CLIENT_INSMOD_1(lm63);
* Functions declaration
*/
static int lm63_attach_adapter(struct i2c_adapter *adapter);
static int lm63_detach_client(struct i2c_client *client);
static int lm63_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int lm63_remove(struct i2c_client *client);
static struct lm63_data *lm63_update_device(struct device *dev);
static int lm63_detect(struct i2c_adapter *adapter, int address, int kind);
static int lm63_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void lm63_init_client(struct i2c_client *client);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id lm63_id[] = {
{ "lm63", lm63 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm63_id);
static struct i2c_driver lm63_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm63",
},
.attach_adapter = lm63_attach_adapter,
.detach_client = lm63_detach_client,
.probe = lm63_probe,
.remove = lm63_remove,
.id_table = lm63_id,
.detect = lm63_detect,
.address_data = &addr_data,
};
/*
@ -153,7 +165,6 @@ static struct i2c_driver lm63_driver = {
*/
struct lm63_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -411,43 +422,14 @@ static const struct attribute_group lm63_group_fan1 = {
* Real code
*/
static int lm63_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm63_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm63_detect);
}
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct lm63_data *data;
int err = 0;
struct i2c_adapter *adapter = new_client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
/* The common I2C client data is placed right before the
LM63-specific data. */
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &lm63_driver;
new_client->flags = 0;
/* Default to an LM63 if forced */
if (kind == 0)
kind = lm63;
return -ENODEV;
if (kind < 0) { /* must identify */
u8 man_id, chip_id, reg_config1, reg_config2;
@ -477,25 +459,38 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
dev_dbg(&adapter->dev, "Unsupported chip "
"(man_id=0x%02X, chip_id=0x%02X).\n",
man_id, chip_id);
goto exit_free;
return -ENODEV;
}
}
strlcpy(new_client->name, "lm63", I2C_NAME_SIZE);
strlcpy(info->type, "lm63", I2C_NAME_SIZE);
return 0;
}
static int lm63_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct lm63_data *data;
int err;
data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Initialize the LM63 chip */
lm63_init_client(new_client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj,
&lm63_group)))
goto exit_detach;
goto exit_free;
if (data->config & 0x04) { /* tachometer enabled */
if ((err = sysfs_create_group(&new_client->dev.kobj,
&lm63_group_fan1)))
@ -513,8 +508,6 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &lm63_group);
sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
@ -556,18 +549,14 @@ static void lm63_init_client(struct i2c_client *client)
(data->config_fan & 0x20) ? "manual" : "auto");
}
static int lm63_detach_client(struct i2c_client *client)
static int lm63_remove(struct i2c_client *client)
{
struct lm63_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm63_group);
sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -52,7 +52,6 @@ I2C_CLIENT_INSMOD_1(lm77);
/* Each client has this additional data */
struct lm77_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid;
@ -65,23 +64,35 @@ struct lm77_data {
u8 alarms;
};
static int lm77_attach_adapter(struct i2c_adapter *adapter);
static int lm77_detect(struct i2c_adapter *adapter, int address, int kind);
static int lm77_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int lm77_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void lm77_init_client(struct i2c_client *client);
static int lm77_detach_client(struct i2c_client *client);
static int lm77_remove(struct i2c_client *client);
static u16 lm77_read_value(struct i2c_client *client, u8 reg);
static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value);
static struct lm77_data *lm77_update_device(struct device *dev);
static const struct i2c_device_id lm77_id[] = {
{ "lm77", lm77 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm77_id);
/* This is the driver that will be inserted */
static struct i2c_driver lm77_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm77",
},
.attach_adapter = lm77_attach_adapter,
.detach_client = lm77_detach_client,
.probe = lm77_probe,
.remove = lm77_remove,
.id_table = lm77_id,
.detect = lm77_detect,
.address_data = &addr_data,
};
/* straight from the datasheet */
@ -215,13 +226,6 @@ static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2);
static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1);
static int lm77_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm77_detect);
}
static struct attribute *lm77_attributes[] = {
&dev_attr_temp1_input.attr,
&dev_attr_temp1_crit.attr,
@ -240,32 +244,15 @@ static const struct attribute_group lm77_group = {
.attrs = lm77_attributes,
};
/* This function is called by i2c_probe */
static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm77_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *new_client;
struct lm77_data *data;
int err = 0;
const char *name = "";
struct i2c_adapter *adapter = new_client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access lm77_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &lm77_driver;
new_client->flags = 0;
return -ENODEV;
/* Here comes the remaining detection. Since the LM77 has no
register dedicated to identification, we have to rely on the
@ -294,7 +281,7 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
|| i2c_smbus_read_word_data(new_client, i + 3) != crit
|| i2c_smbus_read_word_data(new_client, i + 4) != min
|| i2c_smbus_read_word_data(new_client, i + 5) != max)
goto exit_free;
return -ENODEV;
/* sign bits */
if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0)
@ -302,51 +289,55 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
|| ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0)
|| ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0)
|| ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0))
goto exit_free;
return -ENODEV;
/* unused bits */
if (conf & 0xe0)
goto exit_free;
return -ENODEV;
/* 0x06 and 0x07 return the last read value */
cur = i2c_smbus_read_word_data(new_client, 0);
if (i2c_smbus_read_word_data(new_client, 6) != cur
|| i2c_smbus_read_word_data(new_client, 7) != cur)
goto exit_free;
return -ENODEV;
hyst = i2c_smbus_read_word_data(new_client, 2);
if (i2c_smbus_read_word_data(new_client, 6) != hyst
|| i2c_smbus_read_word_data(new_client, 7) != hyst)
goto exit_free;
return -ENODEV;
min = i2c_smbus_read_word_data(new_client, 4);
if (i2c_smbus_read_word_data(new_client, 6) != min
|| i2c_smbus_read_word_data(new_client, 7) != min)
goto exit_free;
return -ENODEV;
}
/* Determine the chip type - only one kind supported! */
if (kind <= 0)
kind = lm77;
strlcpy(info->type, "lm77", I2C_NAME_SIZE);
if (kind == lm77) {
name = "lm77";
return 0;
}
static int lm77_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct lm77_data *data;
int err;
data = kzalloc(sizeof(struct lm77_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Initialize the LM77 chip */
lm77_init_client(new_client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -358,20 +349,17 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &lm77_group);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
return err;
}
static int lm77_detach_client(struct i2c_client *client)
static int lm77_remove(struct i2c_client *client)
{
struct lm77_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm77_group);
i2c_detach_client(client);
kfree(data);
return 0;
}

View File

@ -108,7 +108,6 @@ static inline long TEMP_FROM_REG(u16 temp)
*/
struct lm80_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
@ -132,10 +131,12 @@ struct lm80_data {
* Functions declaration
*/
static int lm80_attach_adapter(struct i2c_adapter *adapter);
static int lm80_detect(struct i2c_adapter *adapter, int address, int kind);
static int lm80_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int lm80_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void lm80_init_client(struct i2c_client *client);
static int lm80_detach_client(struct i2c_client *client);
static int lm80_remove(struct i2c_client *client);
static struct lm80_data *lm80_update_device(struct device *dev);
static int lm80_read_value(struct i2c_client *client, u8 reg);
static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);
@ -144,12 +145,22 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);
* Driver data (common to all clients)
*/
static const struct i2c_device_id lm80_id[] = {
{ "lm80", lm80 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm80_id);
static struct i2c_driver lm80_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm80",
},
.attach_adapter = lm80_attach_adapter,
.detach_client = lm80_detach_client,
.probe = lm80_probe,
.remove = lm80_remove,
.id_table = lm80_id,
.detect = lm80_detect,
.address_data = &addr_data,
};
/*
@ -383,13 +394,6 @@ static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 13);
* Real code
*/
static int lm80_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm80_detect);
}
static struct attribute *lm80_attributes[] = {
&sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in1_min.dev_attr.attr,
@ -442,54 +446,47 @@ static const struct attribute_group lm80_group = {
.attrs = lm80_attributes,
};
static int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm80_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
int i, cur;
struct i2c_client *client;
struct lm80_data *data;
int err = 0;
const char *name;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access lm80_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &lm80_driver;
return -ENODEV;
/* Now, we do the remaining detection. It is lousy. */
if (lm80_read_value(client, LM80_REG_ALARM2) & 0xc0)
goto error_free;
return -ENODEV;
for (i = 0x2a; i <= 0x3d; i++) {
cur = i2c_smbus_read_byte_data(client, i);
if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur)
|| (i2c_smbus_read_byte_data(client, i + 0x80) != cur)
|| (i2c_smbus_read_byte_data(client, i + 0xc0) != cur))
goto error_free;
return -ENODEV;
}
/* Determine the chip type - only one kind supported! */
kind = lm80;
name = "lm80";
strlcpy(info->type, "lm80", I2C_NAME_SIZE);
/* Fill in the remaining client fields */
strlcpy(client->name, name, I2C_NAME_SIZE);
return 0;
}
static int lm80_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lm80_data *data;
int err;
data = kzalloc(sizeof(struct lm80_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto error_free;
/* Initialize the LM80 chip */
lm80_init_client(client);
@ -499,7 +496,7 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &lm80_group)))
goto error_detach;
goto error_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -511,23 +508,18 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
error_remove:
sysfs_remove_group(&client->dev.kobj, &lm80_group);
error_detach:
i2c_detach_client(client);
error_free:
kfree(data);
exit:
return err;
}
static int lm80_detach_client(struct i2c_client *client)
static int lm80_remove(struct i2c_client *client)
{
struct lm80_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm80_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;

View File

@ -1,7 +1,7 @@
/*
* lm83.c - Part of lm_sensors, Linux kernel modules for hardware
* monitoring
* Copyright (C) 2003-2006 Jean Delvare <khali@linux-fr.org>
* Copyright (C) 2003-2008 Jean Delvare <khali@linux-fr.org>
*
* Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is
* a sensor chip made by National Semiconductor. It reports up to four
@ -118,21 +118,34 @@ static const u8 LM83_REG_W_HIGH[] = {
* Functions declaration
*/
static int lm83_attach_adapter(struct i2c_adapter *adapter);
static int lm83_detect(struct i2c_adapter *adapter, int address, int kind);
static int lm83_detach_client(struct i2c_client *client);
static int lm83_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info);
static int lm83_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int lm83_remove(struct i2c_client *client);
static struct lm83_data *lm83_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id lm83_id[] = {
{ "lm83", lm83 },
{ "lm82", lm82 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm83_id);
static struct i2c_driver lm83_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm83",
},
.attach_adapter = lm83_attach_adapter,
.detach_client = lm83_detach_client,
.probe = lm83_probe,
.remove = lm83_remove,
.id_table = lm83_id,
.detect = lm83_detect,
.address_data = &addr_data,
};
/*
@ -140,7 +153,6 @@ static struct i2c_driver lm83_driver = {
*/
struct lm83_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -278,40 +290,15 @@ static const struct attribute_group lm83_group_opt = {
* Real code
*/
static int lm83_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm83_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm83_detect);
}
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct lm83_data *data;
int err = 0;
struct i2c_adapter *adapter = new_client->adapter;
const char *name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
/* The common I2C client data is placed right after the
* LM83-specific data. */
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &lm83_driver;
new_client->flags = 0;
return -ENODEV;
/* Now we do the detection and identification. A negative kind
* means that the driver was loaded with no force parameter
@ -335,8 +322,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG)
& 0x41) != 0x00)) {
dev_dbg(&adapter->dev,
"LM83 detection failed at 0x%02x.\n", address);
goto exit_free;
"LM83 detection failed at 0x%02x.\n",
new_client->addr);
return -ENODEV;
}
}
@ -361,7 +349,7 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&adapter->dev,
"Unsupported chip (man_id=0x%02X, "
"chip_id=0x%02X).\n", man_id, chip_id);
goto exit_free;
return -ENODEV;
}
}
@ -372,15 +360,27 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
name = "lm82";
}
/* We can fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
strlcpy(info->type, name, I2C_NAME_SIZE);
return 0;
}
static int lm83_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct lm83_data *data;
int err;
data = kzalloc(sizeof(struct lm83_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/*
* Register sysfs hooks
* The LM82 can only monitor one external diode which is
@ -389,9 +389,9 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
*/
if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group)))
goto exit_detach;
goto exit_free;
if (kind == lm83) {
if (id->driver_data == lm83) {
if ((err = sysfs_create_group(&new_client->dev.kobj,
&lm83_group_opt)))
goto exit_remove_files;
@ -408,26 +408,20 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &lm83_group);
sysfs_remove_group(&new_client->dev.kobj, &lm83_group_opt);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
return err;
}
static int lm83_detach_client(struct i2c_client *client)
static int lm83_remove(struct i2c_client *client)
{
struct lm83_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm83_group);
sysfs_remove_group(&client->dev.kobj, &lm83_group_opt);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -5,7 +5,7 @@
* Philip Edelbrock <phil@netroedge.com>
* Stephen Rousset <stephen.rousset@rocketlogix.com>
* Dan Eaton <dan.eaton@rocketlogix.com>
* Copyright (C) 2004,2007 Jean Delvare <khali@linux-fr.org>
* Copyright (C) 2004-2008 Jean Delvare <khali@linux-fr.org>
*
* Original port to Linux 2.6 by Jeff Oliver.
*
@ -157,22 +157,35 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C };
* Functions declaration
*/
static int lm87_attach_adapter(struct i2c_adapter *adapter);
static int lm87_detect(struct i2c_adapter *adapter, int address, int kind);
static int lm87_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int lm87_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info);
static void lm87_init_client(struct i2c_client *client);
static int lm87_detach_client(struct i2c_client *client);
static int lm87_remove(struct i2c_client *client);
static struct lm87_data *lm87_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id lm87_id[] = {
{ "lm87", lm87 },
{ "adm1024", adm1024 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm87_id);
static struct i2c_driver lm87_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm87",
},
.attach_adapter = lm87_attach_adapter,
.detach_client = lm87_detach_client,
.probe = lm87_probe,
.remove = lm87_remove,
.id_table = lm87_id,
.detect = lm87_detect,
.address_data = &addr_data,
};
/*
@ -180,7 +193,6 @@ static struct i2c_driver lm87_driver = {
*/
struct lm87_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -562,13 +574,6 @@ static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15);
* Real code
*/
static int lm87_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm87_detect);
}
static struct attribute *lm87_attributes[] = {
&dev_attr_in1_input.attr,
&dev_attr_in1_min.attr,
@ -656,33 +661,15 @@ static const struct attribute_group lm87_group_opt = {
.attrs = lm87_attributes_opt,
};
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm87_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *new_client;
struct lm87_data *data;
int err = 0;
struct i2c_adapter *adapter = new_client->adapter;
static const char *names[] = { "lm87", "adm1024" };
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
/* The common I2C client data is placed right before the
LM87-specific data. */
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &lm87_driver;
new_client->flags = 0;
return -ENODEV;
/* Default to an LM87 if forced */
if (kind == 0)
@ -704,20 +691,32 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
|| (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)) {
dev_dbg(&adapter->dev,
"LM87 detection failed at 0x%02x.\n",
address);
goto exit_free;
new_client->addr);
return -ENODEV;
}
}
/* We can fill in the remaining client fields */
strlcpy(new_client->name, names[kind - 1], I2C_NAME_SIZE);
strlcpy(info->type, names[kind - 1], I2C_NAME_SIZE);
return 0;
}
static int lm87_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct lm87_data *data;
int err;
data = kzalloc(sizeof(struct lm87_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Initialize the LM87 chip */
lm87_init_client(new_client);
@ -732,7 +731,7 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group)))
goto exit_detach;
goto exit_free;
if (data->channel & CHAN_NO_FAN(0)) {
if ((err = device_create_file(&new_client->dev,
@ -832,8 +831,6 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &lm87_group);
sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
@ -877,18 +874,14 @@ static void lm87_init_client(struct i2c_client *client)
}
}
static int lm87_detach_client(struct i2c_client *client)
static int lm87_remove(struct i2c_client *client)
{
struct lm87_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm87_group);
sysfs_remove_group(&client->dev.kobj, &lm87_group_opt);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -187,23 +187,44 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680);
* Functions declaration
*/
static int lm90_attach_adapter(struct i2c_adapter *adapter);
static int lm90_detect(struct i2c_adapter *adapter, int address,
int kind);
static int lm90_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int lm90_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static void lm90_init_client(struct i2c_client *client);
static int lm90_detach_client(struct i2c_client *client);
static int lm90_remove(struct i2c_client *client);
static struct lm90_data *lm90_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id lm90_id[] = {
{ "adm1032", adm1032 },
{ "adt7461", adt7461 },
{ "lm90", lm90 },
{ "lm86", lm86 },
{ "lm89", lm99 },
{ "lm99", lm99 }, /* Missing temperature offset */
{ "max6657", max6657 },
{ "max6658", max6657 },
{ "max6659", max6657 },
{ "max6680", max6680 },
{ "max6681", max6680 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm90_id);
static struct i2c_driver lm90_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm90",
},
.attach_adapter = lm90_attach_adapter,
.detach_client = lm90_detach_client,
.probe = lm90_probe,
.remove = lm90_remove,
.id_table = lm90_id,
.detect = lm90_detect,
.address_data = &addr_data,
};
/*
@ -211,7 +232,6 @@ static struct i2c_driver lm90_driver = {
*/
struct lm90_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -477,40 +497,16 @@ static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value)
return 0;
}
static int lm90_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm90_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm90_detect);
}
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct lm90_data *data;
int err = 0;
struct i2c_adapter *adapter = new_client->adapter;
int address = new_client->addr;
const char *name = "";
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
/* The common I2C client data is placed right before the
LM90-specific data. */
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &lm90_driver;
new_client->flags = 0;
return -ENODEV;
/*
* Now we do the remaining detection. A negative kind means that
@ -538,7 +534,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
LM90_REG_R_CONFIG1)) < 0
|| (reg_convrate = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_CONVRATE)) < 0)
goto exit_free;
return -ENODEV;
if ((address == 0x4C || address == 0x4D)
&& man_id == 0x01) { /* National Semiconductor */
@ -546,7 +542,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
if ((reg_config2 = i2c_smbus_read_byte_data(new_client,
LM90_REG_R_CONFIG2)) < 0)
goto exit_free;
return -ENODEV;
if ((reg_config1 & 0x2A) == 0x00
&& (reg_config2 & 0xF8) == 0x00
@ -610,10 +606,11 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&adapter->dev,
"Unsupported chip (man_id=0x%02X, "
"chip_id=0x%02X).\n", man_id, chip_id);
goto exit_free;
return -ENODEV;
}
}
/* Fill the i2c board info */
if (kind == lm90) {
name = "lm90";
} else if (kind == adm1032) {
@ -621,7 +618,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
/* The ADM1032 supports PEC, but only if combined
transactions are not used. */
if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
new_client->flags |= I2C_CLIENT_PEC;
info->flags |= I2C_CLIENT_PEC;
} else if (kind == lm99) {
name = "lm99";
} else if (kind == lm86) {
@ -633,23 +630,39 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
} else if (kind == adt7461) {
name = "adt7461";
}
strlcpy(info->type, name, I2C_NAME_SIZE);
/* We can fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
data->kind = kind;
return 0;
}
static int lm90_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(new_client->dev.parent);
struct lm90_data *data;
int err;
data = kzalloc(sizeof(struct lm90_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Set the device type */
data->kind = id->driver_data;
if (data->kind == adm1032) {
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
new_client->flags &= ~I2C_CLIENT_PEC;
}
/* Initialize the LM90 chip */
lm90_init_client(new_client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &lm90_group)))
goto exit_detach;
goto exit_free;
if (new_client->flags & I2C_CLIENT_PEC) {
if ((err = device_create_file(&new_client->dev,
&dev_attr_pec)))
@ -672,8 +685,6 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &lm90_group);
device_remove_file(&new_client->dev, &dev_attr_pec);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
@ -710,10 +721,9 @@ static void lm90_init_client(struct i2c_client *client)
i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
}
static int lm90_detach_client(struct i2c_client *client)
static int lm90_remove(struct i2c_client *client)
{
struct lm90_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm90_group);
@ -722,9 +732,6 @@ static int lm90_detach_client(struct i2c_client *client)
device_remove_file(&client->dev,
&sensor_dev_attr_temp2_offset.dev_attr);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -1,6 +1,6 @@
/*
* lm92 - Hardware monitoring driver
* Copyright (C) 2005 Jean Delvare <khali@linux-fr.org>
* Copyright (C) 2005-2008 Jean Delvare <khali@linux-fr.org>
*
* Based on the lm90 driver, with some ideas taken from the lm_sensors
* lm92 driver as well.
@ -96,7 +96,6 @@ static struct i2c_driver lm92_driver;
/* Client data (each client gets its own) */
struct lm92_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -319,32 +318,15 @@ static const struct attribute_group lm92_group = {
.attrs = lm92_attributes,
};
/* The following function does more than just detection. If detection
succeeds, it also registers the new chip. */
static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm92_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *new_client;
struct lm92_data *data;
int err = 0;
char *name;
struct i2c_adapter *adapter = new_client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
| I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
/* Fill in enough client fields so that we can read from the chip,
which is required for identication */
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &lm92_driver;
new_client->flags = 0;
return -ENODEV;
/* A negative kind means that the driver was loaded with no force
parameter (default), so we must identify the chip. */
@ -364,34 +346,36 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
kind = lm92; /* No separate prefix */
}
else
goto exit_free;
} else
if (kind == 0) /* Default to an LM92 if forced */
kind = lm92;
/* Give it the proper name */
if (kind == lm92) {
name = "lm92";
} else { /* Supposedly cannot happen */
dev_dbg(&new_client->dev, "Kind out of range?\n");
goto exit_free;
return -ENODEV;
}
/* Fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
strlcpy(info->type, "lm92", I2C_NAME_SIZE);
return 0;
}
static int lm92_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct lm92_data *data;
int err;
data = kzalloc(sizeof(struct lm92_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the i2c subsystem a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Initialize the chipset */
lm92_init_client(new_client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -403,32 +387,19 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &lm92_group);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
return err;
}
static int lm92_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm92_detect);
}
static int lm92_detach_client(struct i2c_client *client)
static int lm92_remove(struct i2c_client *client)
{
struct lm92_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm92_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}
@ -438,12 +409,23 @@ static int lm92_detach_client(struct i2c_client *client)
* Module and driver stuff
*/
static const struct i2c_device_id lm92_id[] = {
{ "lm92", lm92 },
/* max6635 could be added here */
{ }
};
MODULE_DEVICE_TABLE(i2c, lm92_id);
static struct i2c_driver lm92_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm92",
},
.attach_adapter = lm92_attach_adapter,
.detach_client = lm92_detach_client,
.probe = lm92_probe,
.remove = lm92_remove,
.id_table = lm92_id,
.detect = lm92_detect,
.address_data = &addr_data,
};
static int __init sensors_lm92_init(void)

View File

@ -200,7 +200,6 @@ struct block1_t {
* Client-specific data
*/
struct lm93_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
@ -2501,45 +2500,14 @@ static void lm93_init_client(struct i2c_client *client)
"chip to signal ready!\n");
}
static int lm93_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm93_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct lm93_data *data;
struct i2c_client *client;
struct i2c_adapter *adapter = client->adapter;
int err = -ENODEV, func;
void (*update)(struct lm93_data *, struct i2c_client *);
/* choose update routine based on bus capabilities */
func = i2c_get_functionality(adapter);
if ( ((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) &&
(!disable_block) ) {
dev_dbg(&adapter->dev,"using SMBus block data transactions\n");
update = lm93_update_client_full;
} else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) {
dev_dbg(&adapter->dev,"disabled SMBus block data "
"transactions\n");
update = lm93_update_client_min;
} else {
dev_dbg(&adapter->dev,"detect failed, "
"smbus byte and/or word data not supported!\n");
goto err_out;
}
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access lm78_{read,write}_value. */
if ( !(data = kzalloc(sizeof(struct lm93_data), GFP_KERNEL))) {
dev_dbg(&adapter->dev,"out of memory!\n");
err = -ENOMEM;
goto err_out;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &lm93_driver;
if (!i2c_check_functionality(adapter, LM93_SMBUS_FUNC_MIN))
return -ENODEV;
/* detection */
if (kind < 0) {
@ -2548,7 +2516,7 @@ static int lm93_detect(struct i2c_adapter *adapter, int address, int kind)
if (mfr != 0x01) {
dev_dbg(&adapter->dev,"detect failed, "
"bad manufacturer id 0x%02x!\n", mfr);
goto err_free;
return -ENODEV;
}
}
@ -2563,31 +2531,61 @@ static int lm93_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind == 0)
dev_dbg(&adapter->dev,
"(ignored 'force' parameter)\n");
goto err_free;
return -ENODEV;
}
}
/* fill in remaining client fields */
strlcpy(client->name, "lm93", I2C_NAME_SIZE);
strlcpy(info->type, "lm93", I2C_NAME_SIZE);
dev_dbg(&adapter->dev,"loading %s at %d,0x%02x\n",
client->name, i2c_adapter_id(client->adapter),
client->addr);
return 0;
}
static int lm93_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lm93_data *data;
int err, func;
void (*update)(struct lm93_data *, struct i2c_client *);
/* choose update routine based on bus capabilities */
func = i2c_get_functionality(client->adapter);
if (((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) &&
(!disable_block)) {
dev_dbg(&client->dev, "using SMBus block data transactions\n");
update = lm93_update_client_full;
} else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) {
dev_dbg(&client->dev, "disabled SMBus block data "
"transactions\n");
update = lm93_update_client_min;
} else {
dev_dbg(&client->dev, "detect failed, "
"smbus byte and/or word data not supported!\n");
err = -ENODEV;
goto err_out;
}
data = kzalloc(sizeof(struct lm93_data), GFP_KERNEL);
if (!data) {
dev_dbg(&client->dev, "out of memory!\n");
err = -ENOMEM;
goto err_out;
}
i2c_set_clientdata(client, data);
/* housekeeping */
data->valid = 0;
data->update = update;
mutex_init(&data->update_lock);
/* tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto err_free;
/* initialize the chip */
lm93_init_client(client);
err = sysfs_create_group(&client->dev.kobj, &lm93_attr_grp);
if (err)
goto err_detach;
goto err_free;
/* Register hwmon driver class */
data->hwmon_dev = hwmon_device_register(&client->dev);
@ -2597,43 +2595,39 @@ static int lm93_detect(struct i2c_adapter *adapter, int address, int kind)
err = PTR_ERR(data->hwmon_dev);
dev_err(&client->dev, "error registering hwmon device.\n");
sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp);
err_detach:
i2c_detach_client(client);
err_free:
kfree(data);
err_out:
return err;
}
/* This function is called when:
* lm93_driver is inserted (when this module is loaded), for each
available adapter
* when a new adapter is inserted (and lm93_driver is still present) */
static int lm93_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_probe(adapter, &addr_data, lm93_detect);
}
static int lm93_detach_client(struct i2c_client *client)
static int lm93_remove(struct i2c_client *client)
{
struct lm93_data *data = i2c_get_clientdata(client);
int err = 0;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp);
err = i2c_detach_client(client);
if (!err)
kfree(data);
return err;
kfree(data);
return 0;
}
static const struct i2c_device_id lm93_id[] = {
{ "lm93", lm93 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm93_id);
static struct i2c_driver lm93_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm93",
},
.attach_adapter = lm93_attach_adapter,
.detach_client = lm93_detach_client,
.probe = lm93_probe,
.remove = lm93_remove,
.id_table = lm93_id,
.detect = lm93_detect,
.address_data = &addr_data,
};
static int __init lm93_init(void)

View File

@ -79,23 +79,34 @@ I2C_CLIENT_INSMOD_1(max1619);
* Functions declaration
*/
static int max1619_attach_adapter(struct i2c_adapter *adapter);
static int max1619_detect(struct i2c_adapter *adapter, int address,
int kind);
static int max1619_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int max1619_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static void max1619_init_client(struct i2c_client *client);
static int max1619_detach_client(struct i2c_client *client);
static int max1619_remove(struct i2c_client *client);
static struct max1619_data *max1619_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id max1619_id[] = {
{ "max1619", max1619 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max1619_id);
static struct i2c_driver max1619_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "max1619",
},
.attach_adapter = max1619_attach_adapter,
.detach_client = max1619_detach_client,
.probe = max1619_probe,
.remove = max1619_remove,
.id_table = max1619_id,
.detect = max1619_detect,
.address_data = &addr_data,
};
/*
@ -103,7 +114,6 @@ static struct i2c_driver max1619_driver = {
*/
struct max1619_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -208,41 +218,15 @@ static const struct attribute_group max1619_group = {
* Real code
*/
static int max1619_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int max1619_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, max1619_detect);
}
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct max1619_data *data;
int err = 0;
const char *name = "";
struct i2c_adapter *adapter = new_client->adapter;
u8 reg_config=0, reg_convrate=0, reg_status=0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
/* The common I2C client data is placed right before the
MAX1619-specific data. */
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &max1619_driver;
new_client->flags = 0;
return -ENODEV;
/*
* Now we do the remaining detection. A negative kind means that
@ -265,8 +249,8 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
|| reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) {
dev_dbg(&adapter->dev,
"MAX1619 detection failed at 0x%02x.\n",
address);
goto exit_free;
new_client->addr);
return -ENODEV;
}
}
@ -285,28 +269,37 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&adapter->dev,
"Unsupported chip (man_id=0x%02X, "
"chip_id=0x%02X).\n", man_id, chip_id);
goto exit_free;
return -ENODEV;
}
}
if (kind == max1619)
name = "max1619";
strlcpy(info->type, "max1619", I2C_NAME_SIZE);
/* We can fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
return 0;
}
static int max1619_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct max1619_data *data;
int err;
data = kzalloc(sizeof(struct max1619_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Initialize the MAX1619 chip */
max1619_init_client(new_client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group)))
goto exit_detach;
goto exit_free;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
@ -318,8 +311,6 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &max1619_group);
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
@ -341,17 +332,13 @@ static void max1619_init_client(struct i2c_client *client)
config & 0xBF); /* run */
}
static int max1619_detach_client(struct i2c_client *client)
static int max1619_remove(struct i2c_client *client)
{
struct max1619_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &max1619_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
}

View File

@ -104,22 +104,34 @@ I2C_CLIENT_INSMOD_1(max6650);
#define DIV_FROM_REG(reg) (1 << (reg & 7))
static int max6650_attach_adapter(struct i2c_adapter *adapter);
static int max6650_detect(struct i2c_adapter *adapter, int address, int kind);
static int max6650_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int max6650_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int max6650_init_client(struct i2c_client *client);
static int max6650_detach_client(struct i2c_client *client);
static int max6650_remove(struct i2c_client *client);
static struct max6650_data *max6650_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id max6650_id[] = {
{ "max6650", max6650 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max6650_id);
static struct i2c_driver max6650_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "max6650",
},
.attach_adapter = max6650_attach_adapter,
.detach_client = max6650_detach_client,
.probe = max6650_probe,
.remove = max6650_remove,
.id_table = max6650_id,
.detect = max6650_detect,
.address_data = &addr_data,
};
/*
@ -128,7 +140,6 @@ static struct i2c_driver max6650_driver = {
struct max6650_data
{
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -437,47 +448,21 @@ static struct attribute_group max6650_attr_grp = {
* Real code
*/
static int max6650_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int max6650_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON)) {
dev_dbg(&adapter->dev,
"FATAL: max6650_attach_adapter class HWMON not set\n");
return 0;
}
return i2c_probe(adapter, &addr_data, max6650_detect);
}
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int max6650_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct max6650_data *data;
int err = -ENODEV;
struct i2c_adapter *adapter = client->adapter;
int address = client->addr;
dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind);
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support "
"byte read mode, skipping.\n");
return 0;
return -ENODEV;
}
if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) {
dev_err(&adapter->dev, "max6650: out of memory.\n");
return -ENOMEM;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &max6650_driver;
/*
* Now we do the remaining detection. A negative kind means that
* the driver was loaded with no force parameter (default), so we
@ -501,28 +486,40 @@ static int max6650_detect(struct i2c_adapter *adapter, int address, int kind)
||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) {
dev_dbg(&adapter->dev,
"max6650: detection failed at 0x%02x.\n", address);
goto err_free;
return -ENODEV;
}
dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address);
strlcpy(client->name, "max6650", I2C_NAME_SIZE);
mutex_init(&data->update_lock);
strlcpy(info->type, "max6650", I2C_NAME_SIZE);
if ((err = i2c_attach_client(client))) {
dev_err(&adapter->dev, "max6650: failed to attach client.\n");
goto err_free;
return 0;
}
static int max6650_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct max6650_data *data;
int err;
if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) {
dev_err(&client->dev, "out of memory.\n");
return -ENOMEM;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/*
* Initialize the max6650 chip
*/
if (max6650_init_client(client))
goto err_detach;
err = max6650_init_client(client);
if (err)
goto err_free;
err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp);
if (err)
goto err_detach;
goto err_free;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (!IS_ERR(data->hwmon_dev))
@ -531,24 +528,19 @@ static int max6650_detect(struct i2c_adapter *adapter, int address, int kind)
err = PTR_ERR(data->hwmon_dev);
dev_err(&client->dev, "error registering hwmon device.\n");
sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
err_detach:
i2c_detach_client(client);
err_free:
kfree(data);
return err;
}
static int max6650_detach_client(struct i2c_client *client)
static int max6650_remove(struct i2c_client *client)
{
struct max6650_data *data = i2c_get_clientdata(client);
int err;
sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
hwmon_device_unregister(data->hwmon_dev);
err = i2c_detach_client(client);
if (!err)
kfree(data);
return err;
kfree(data);
return 0;
}
static int max6650_init_client(struct i2c_client *client)

View File

@ -96,7 +96,6 @@ static inline int TEMP_FROM_REG(s8 val)
}
struct smsc47m192_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
@ -114,18 +113,29 @@ struct smsc47m192_data {
u8 vrm;
};
static int smsc47m192_attach_adapter(struct i2c_adapter *adapter);
static int smsc47m192_detect(struct i2c_adapter *adapter, int address,
int kind);
static int smsc47m192_detach_client(struct i2c_client *client);
static int smsc47m192_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int smsc47m192_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int smsc47m192_remove(struct i2c_client *client);
static struct smsc47m192_data *smsc47m192_update_device(struct device *dev);
static const struct i2c_device_id smsc47m192_id[] = {
{ "smsc47m192", smsc47m192 },
{ }
};
MODULE_DEVICE_TABLE(i2c, smsc47m192_id);
static struct i2c_driver smsc47m192_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "smsc47m192",
},
.attach_adapter = smsc47m192_attach_adapter,
.detach_client = smsc47m192_detach_client,
.probe = smsc47m192_probe,
.remove = smsc47m192_remove,
.id_table = smsc47m192_id,
.detect = smsc47m192_detect,
.address_data = &addr_data,
};
/* Voltages */
@ -440,17 +450,6 @@ static const struct attribute_group smsc47m192_group_in4 = {
.attrs = smsc47m192_attributes_in4,
};
/* This function is called when:
* smsc47m192_driver is inserted (when this module is loaded), for each
available adapter
* when a new adapter is inserted (and smsc47m192_driver is still present) */
static int smsc47m192_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, smsc47m192_detect);
}
static void smsc47m192_init_client(struct i2c_client *client)
{
int i;
@ -481,31 +480,15 @@ static void smsc47m192_init_client(struct i2c_client *client)
}
}
/* This function is called by i2c_probe */
static int smsc47m192_detect(struct i2c_adapter *adapter, int address,
int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int smsc47m192_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *client;
struct smsc47m192_data *data;
int err = 0;
int version, config;
struct i2c_adapter *adapter = client->adapter;
int version;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &smsc47m192_driver;
if (kind == 0)
kind = smsc47m192;
return -ENODEV;
/* Detection criteria from sensors_detect script */
if (kind < 0) {
@ -523,26 +506,39 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address,
} else {
dev_dbg(&adapter->dev,
"SMSC47M192 detection failed at 0x%02x\n",
address);
goto exit_free;
client->addr);
return -ENODEV;
}
}
/* Fill in the remaining client fields and put into the global list */
strlcpy(client->name, "smsc47m192", I2C_NAME_SIZE);
strlcpy(info->type, "smsc47m192", I2C_NAME_SIZE);
return 0;
}
static int smsc47m192_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct smsc47m192_data *data;
int config;
int err;
data = kzalloc(sizeof(struct smsc47m192_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->vrm = vid_which_vrm();
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
/* Initialize the SMSC47M192 chip */
smsc47m192_init_client(client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group)))
goto exit_detach;
goto exit_free;
/* Pin 110 is either in4 (+12V) or VID4 */
config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
@ -563,26 +559,20 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address,
exit_remove_files:
sysfs_remove_group(&client->dev.kobj, &smsc47m192_group);
sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int smsc47m192_detach_client(struct i2c_client *client)
static int smsc47m192_remove(struct i2c_client *client)
{
struct smsc47m192_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &smsc47m192_group);
sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;

View File

@ -60,7 +60,6 @@ static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
/* Each client has this additional data */
struct thmc50_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
@ -77,17 +76,31 @@ struct thmc50_data {
u8 alarms;
};
static int thmc50_attach_adapter(struct i2c_adapter *adapter);
static int thmc50_detach_client(struct i2c_client *client);
static int thmc50_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int thmc50_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int thmc50_remove(struct i2c_client *client);
static void thmc50_init_client(struct i2c_client *client);
static struct thmc50_data *thmc50_update_device(struct device *dev);
static const struct i2c_device_id thmc50_id[] = {
{ "adm1022", adm1022 },
{ "thmc50", thmc50 },
{ }
};
MODULE_DEVICE_TABLE(i2c, thmc50_id);
static struct i2c_driver thmc50_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "thmc50",
},
.attach_adapter = thmc50_attach_adapter,
.detach_client = thmc50_detach_client,
.probe = thmc50_probe,
.remove = thmc50_remove,
.id_table = thmc50_id,
.detect = thmc50_detect,
.address_data = &addr_data,
};
static ssize_t show_analog_out(struct device *dev,
@ -250,39 +263,23 @@ static const struct attribute_group temp3_group = {
.attrs = temp3_attributes,
};
static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int thmc50_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
unsigned company;
unsigned revision;
unsigned config;
struct i2c_client *client;
struct thmc50_data *data;
struct device *dev;
struct i2c_adapter *adapter = client->adapter;
int err = 0;
const char *type_name;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
pr_debug("thmc50: detect failed, "
"smbus byte data not supported!\n");
goto exit;
return -ENODEV;
}
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access thmc50 registers. */
if (!(data = kzalloc(sizeof(struct thmc50_data), GFP_KERNEL))) {
pr_debug("thmc50: detect failed, kzalloc failed!\n");
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &thmc50_driver;
dev = &client->dev;
pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n",
client->addr, i2c_adapter_id(client->adapter));
@ -307,21 +304,22 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
}
if (err == -ENODEV) {
pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
goto exit_free;
return err;
}
data->type = kind;
if (kind == adm1022) {
int id = i2c_adapter_id(client->adapter);
int i;
type_name = "adm1022";
data->has_temp3 = (config >> 7) & 1; /* config MSB */
for (i = 0; i + 1 < adm1022_temp3_num; i += 2)
if (adm1022_temp3[i] == id &&
adm1022_temp3[i + 1] == address) {
adm1022_temp3[i + 1] == client->addr) {
/* enable 2nd remote temp */
data->has_temp3 = 1;
config |= (1 << 7);
i2c_smbus_write_byte_data(client,
THMC50_REG_CONF,
config);
break;
}
} else {
@ -330,19 +328,33 @@ static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
pr_debug("thmc50: Detected %s (version %x, revision %x)\n",
type_name, (revision >> 4) - 0xc, revision & 0xf);
/* Fill in the remaining client fields & put it into the global list */
strlcpy(client->name, type_name, I2C_NAME_SIZE);
mutex_init(&data->update_lock);
strlcpy(info->type, type_name, I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
return 0;
}
static int thmc50_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct thmc50_data *data;
int err;
data = kzalloc(sizeof(struct thmc50_data), GFP_KERNEL);
if (!data) {
pr_debug("thmc50: detect failed, kzalloc failed!\n");
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->type = id->driver_data;
mutex_init(&data->update_lock);
thmc50_init_client(client);
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &thmc50_group)))
goto exit_detach;
goto exit_free;
/* Register ADM1022 sysfs hooks */
if (data->has_temp3)
@ -364,34 +376,21 @@ exit_remove_sysfs:
sysfs_remove_group(&client->dev.kobj, &temp3_group);
exit_remove_sysfs_thmc50:
sysfs_remove_group(&client->dev.kobj, &thmc50_group);
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int thmc50_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, thmc50_detect);
}
static int thmc50_detach_client(struct i2c_client *client)
static int thmc50_remove(struct i2c_client *client)
{
struct thmc50_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &thmc50_group);
if (data->has_temp3)
sysfs_remove_group(&client->dev.kobj, &temp3_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
@ -412,8 +411,8 @@ static void thmc50_init_client(struct i2c_client *client)
}
config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
config |= 0x1; /* start the chip if it is in standby mode */
if (data->has_temp3)
config |= 0x80; /* enable 2nd remote temp */
if (data->type == adm1022 && (config & (1 << 7)))
data->has_temp3 = 1;
i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);
}

View File

@ -247,7 +247,6 @@ static u8 div_to_reg(int nr, long val)
}
struct w83791d_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
@ -286,9 +285,11 @@ struct w83791d_data {
u8 vrm; /* hwmon-vid */
};
static int w83791d_attach_adapter(struct i2c_adapter *adapter);
static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
static int w83791d_detach_client(struct i2c_client *client);
static int w83791d_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int w83791d_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int w83791d_remove(struct i2c_client *client);
static int w83791d_read(struct i2c_client *client, u8 register);
static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
@ -300,12 +301,22 @@ static void w83791d_print_debug(struct w83791d_data *data, struct device *dev);
static void w83791d_init_client(struct i2c_client *client);
static const struct i2c_device_id w83791d_id[] = {
{ "w83791d", w83791d },
{ }
};
MODULE_DEVICE_TABLE(i2c, w83791d_id);
static struct i2c_driver w83791d_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "w83791d",
},
.attach_adapter = w83791d_attach_adapter,
.detach_client = w83791d_detach_client,
.probe = w83791d_probe,
.remove = w83791d_remove,
.id_table = w83791d_id,
.detect = w83791d_detect,
.address_data = &addr_data,
};
/* following are the sysfs callback functions */
@ -905,49 +916,12 @@ static const struct attribute_group w83791d_group = {
.attrs = w83791d_attributes,
};
/* This function is called when:
* w83791d_driver is inserted (when this module is loaded), for each
available adapter
* when a new adapter is inserted (and w83791d_driver is still present) */
static int w83791d_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, w83791d_detect);
}
static int w83791d_create_subclient(struct i2c_adapter *adapter,
struct i2c_client *client, int addr,
struct i2c_client **sub_cli)
{
int err;
struct i2c_client *sub_client;
(*sub_cli) = sub_client =
kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(sub_client)) {
return -ENOMEM;
}
sub_client->addr = 0x48 + addr;
i2c_set_clientdata(sub_client, NULL);
sub_client->adapter = adapter;
sub_client->driver = &w83791d_driver;
strlcpy(sub_client->name, "w83791d subclient", I2C_NAME_SIZE);
if ((err = i2c_attach_client(sub_client))) {
dev_err(&client->dev, "subclient registration "
"at address 0x%x failed\n", sub_client->addr);
kfree(sub_client);
return err;
}
return 0;
}
static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address,
int kind, struct i2c_client *client)
static int w83791d_detect_subclients(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
struct w83791d_data *data = i2c_get_clientdata(client);
int address = client->addr;
int i, id, err;
u8 val;
@ -971,10 +945,7 @@ static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address,
val = w83791d_read(client, W83791D_REG_I2C_SUBADDR);
if (!(val & 0x08)) {
err = w83791d_create_subclient(adapter, client,
val & 0x7, &data->lm75[0]);
if (err < 0)
goto error_sc_0;
data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7));
}
if (!(val & 0x80)) {
if ((data->lm75[0] != NULL) &&
@ -986,10 +957,8 @@ static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address,
err = -ENODEV;
goto error_sc_1;
}
err = w83791d_create_subclient(adapter, client,
(val >> 4) & 0x7, &data->lm75[1]);
if (err < 0)
goto error_sc_1;
data->lm75[1] = i2c_new_dummy(adapter,
0x48 + ((val >> 4) & 0x7));
}
return 0;
@ -997,53 +966,31 @@ static int w83791d_detect_subclients(struct i2c_adapter *adapter, int address,
/* Undo inits in case of errors */
error_sc_1:
if (data->lm75[0] != NULL) {
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[0]);
}
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
error_sc_0:
return err;
}
static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int w83791d_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *client;
struct device *dev;
struct w83791d_data *data;
int i, val1, val2;
int err = 0;
const char *client_name = "";
struct i2c_adapter *adapter = client->adapter;
int val1, val2;
unsigned short address = client->addr;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
goto error0;
return -ENODEV;
}
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access w83791d_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct w83791d_data), GFP_KERNEL))) {
err = -ENOMEM;
goto error0;
}
client = &data->client;
dev = &client->dev;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &w83791d_driver;
mutex_init(&data->update_lock);
/* Now, we do the remaining detection. */
/* The w83791d may be stuck in some other bank than bank 0. This may
make reading other information impossible. Specify a force=...
parameter, and the Winbond will be reset to the right bank. */
if (kind < 0) {
if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80) {
dev_dbg(dev, "Detection failed at step 1\n");
goto error1;
return -ENODEV;
}
val1 = w83791d_read(client, W83791D_REG_BANK);
val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
@ -1052,15 +999,13 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
/* yes it is Bank0 */
if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
((val1 & 0x80) && (val2 != 0x5c))) {
dev_dbg(dev, "Detection failed at step 2\n");
goto error1;
return -ENODEV;
}
}
/* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
should match */
if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address) {
dev_dbg(dev, "Detection failed at step 3\n");
goto error1;
return -ENODEV;
}
}
@ -1075,30 +1020,33 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
/* get vendor ID */
val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
if (val2 != 0x5c) { /* the vendor is NOT Winbond */
dev_dbg(dev, "Detection failed at step 4\n");
goto error1;
return -ENODEV;
}
val1 = w83791d_read(client, W83791D_REG_WCHIPID);
if (val1 == 0x71) {
kind = w83791d;
} else {
if (kind == 0)
dev_warn(dev,
dev_warn(&adapter->dev,
"w83791d: Ignoring 'force' parameter "
"for unknown chip at adapter %d, "
"address 0x%02x\n",
i2c_adapter_id(adapter), address);
goto error1;
return -ENODEV;
}
}
if (kind == w83791d) {
client_name = "w83791d";
} else {
dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?\n",
kind);
goto error1;
}
strlcpy(info->type, "w83791d", I2C_NAME_SIZE);
return 0;
}
static int w83791d_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct w83791d_data *data;
struct device *dev = &client->dev;
int i, val1, err;
#ifdef DEBUG
val1 = w83791d_read(client, W83791D_REG_DID_VID4);
@ -1106,16 +1054,19 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
(val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1);
#endif
/* Fill in the remaining client fields and put into the global list */
strlcpy(client->name, client_name, I2C_NAME_SIZE);
data = kzalloc(sizeof(struct w83791d_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto error0;
}
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
err = w83791d_detect_subclients(client);
if (err)
goto error1;
if ((err = w83791d_detect_subclients(adapter, address, kind, client)))
goto error2;
/* Initialize the chip */
w83791d_init_client(client);
@ -1141,43 +1092,29 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
error4:
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
error3:
if (data->lm75[0] != NULL) {
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[0]);
}
if (data->lm75[1] != NULL) {
i2c_detach_client(data->lm75[1]);
kfree(data->lm75[1]);
}
error2:
i2c_detach_client(client);
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
if (data->lm75[1] != NULL)
i2c_unregister_device(data->lm75[1]);
error1:
kfree(data);
error0:
return err;
}
static int w83791d_detach_client(struct i2c_client *client)
static int w83791d_remove(struct i2c_client *client)
{
struct w83791d_data *data = i2c_get_clientdata(client);
int err;
/* main client */
if (data) {
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
}
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
if ((err = i2c_detach_client(client)))
return err;
/* main client */
if (data)
kfree(data);
/* subclient */
else
kfree(client);
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
if (data->lm75[1] != NULL)
i2c_unregister_device(data->lm75[1]);
kfree(data);
return 0;
}

View File

@ -267,9 +267,7 @@ DIV_TO_REG(long val)
}
struct w83792d_data {
struct i2c_client client;
struct device *hwmon_dev;
enum chips type;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
@ -299,9 +297,11 @@ struct w83792d_data {
u8 sf2_levels[3][4]; /* Smart FanII: Fan1,2,3 duty cycle levels */
};
static int w83792d_attach_adapter(struct i2c_adapter *adapter);
static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind);
static int w83792d_detach_client(struct i2c_client *client);
static int w83792d_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int w83792d_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int w83792d_remove(struct i2c_client *client);
static struct w83792d_data *w83792d_update_device(struct device *dev);
#ifdef DEBUG
@ -310,12 +310,22 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev);
static void w83792d_init_client(struct i2c_client *client);
static const struct i2c_device_id w83792d_id[] = {
{ "w83792d", w83792d },
{ }
};
MODULE_DEVICE_TABLE(i2c, w83792d_id);
static struct i2c_driver w83792d_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "w83792d",
},
.attach_adapter = w83792d_attach_adapter,
.detach_client = w83792d_detach_client,
.probe = w83792d_probe,
.remove = w83792d_remove,
.id_table = w83792d_id,
.detect = w83792d_detect,
.address_data = &addr_data,
};
static inline long in_count_from_reg(int nr, struct w83792d_data *data)
@ -864,53 +874,14 @@ store_sf2_level(struct device *dev, struct device_attribute *attr,
return count;
}
/* This function is called when:
* w83792d_driver is inserted (when this module is loaded), for each
available adapter
* when a new adapter is inserted (and w83792d_driver is still present) */
static int
w83792d_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, w83792d_detect);
}
static int
w83792d_create_subclient(struct i2c_adapter *adapter,
struct i2c_client *new_client, int addr,
struct i2c_client **sub_cli)
{
int err;
struct i2c_client *sub_client;
(*sub_cli) = sub_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(sub_client)) {
return -ENOMEM;
}
sub_client->addr = 0x48 + addr;
i2c_set_clientdata(sub_client, NULL);
sub_client->adapter = adapter;
sub_client->driver = &w83792d_driver;
sub_client->flags = 0;
strlcpy(sub_client->name, "w83792d subclient", I2C_NAME_SIZE);
if ((err = i2c_attach_client(sub_client))) {
dev_err(&new_client->dev, "subclient registration "
"at address 0x%x failed\n", sub_client->addr);
kfree(sub_client);
return err;
}
return 0;
}
static int
w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
struct i2c_client *new_client)
w83792d_detect_subclients(struct i2c_client *new_client)
{
int i, id, err;
int address = new_client->addr;
u8 val;
struct i2c_adapter *adapter = new_client->adapter;
struct w83792d_data *data = i2c_get_clientdata(new_client);
id = i2c_adapter_id(adapter);
@ -932,10 +903,7 @@ w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR);
if (!(val & 0x08)) {
err = w83792d_create_subclient(adapter, new_client, val & 0x7,
&data->lm75[0]);
if (err < 0)
goto ERROR_SC_0;
data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7));
}
if (!(val & 0x80)) {
if ((data->lm75[0] != NULL) &&
@ -945,10 +913,8 @@ w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
err = -ENODEV;
goto ERROR_SC_1;
}
err = w83792d_create_subclient(adapter, new_client,
(val >> 4) & 0x7, &data->lm75[1]);
if (err < 0)
goto ERROR_SC_1;
data->lm75[1] = i2c_new_dummy(adapter,
0x48 + ((val >> 4) & 0x7));
}
return 0;
@ -956,10 +922,8 @@ w83792d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
/* Undo inits in case of errors */
ERROR_SC_1:
if (data->lm75[0] != NULL) {
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[0]);
}
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
ERROR_SC_0:
return err;
}
@ -1294,47 +1258,25 @@ static const struct attribute_group w83792d_group = {
.attrs = w83792d_attributes,
};
/* Return 0 if detection is successful, -ENODEV otherwise */
static int
w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
w83792d_detect(struct i2c_client *client, int kind, struct i2c_board_info *info)
{
int i = 0, val1 = 0, val2;
struct i2c_client *client;
struct device *dev;
struct w83792d_data *data;
int err = 0;
const char *client_name = "";
struct i2c_adapter *adapter = client->adapter;
int val1, val2;
unsigned short address = client->addr;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
goto ERROR0;
return -ENODEV;
}
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access w83792d_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR0;
}
client = &data->client;
dev = &client->dev;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &w83792d_driver;
client->flags = 0;
/* Now, we do the remaining detection. */
/* The w83792d may be stuck in some other bank than bank 0. This may
make reading other information impossible. Specify a force=... or
force_*=... parameter, and the Winbond will be reset to the right
bank. */
if (kind < 0) {
if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) {
dev_dbg(dev, "Detection failed at step 1\n");
goto ERROR1;
return -ENODEV;
}
val1 = w83792d_read_value(client, W83792D_REG_BANK);
val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
@ -1342,16 +1284,14 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
if (!(val1 & 0x07)) { /* is Bank0 */
if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
((val1 & 0x80) && (val2 != 0x5c))) {
dev_dbg(dev, "Detection failed at step 2\n");
goto ERROR1;
return -ENODEV;
}
}
/* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
should match */
if (w83792d_read_value(client,
W83792D_REG_I2C_ADDR) != address) {
dev_dbg(dev, "Detection failed at step 3\n");
goto ERROR1;
return -ENODEV;
}
}
@ -1367,45 +1307,48 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
/* get vendor ID */
val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
if (val2 != 0x5c) { /* the vendor is NOT Winbond */
goto ERROR1;
return -ENODEV;
}
val1 = w83792d_read_value(client, W83792D_REG_WCHIPID);
if (val1 == 0x7a) {
kind = w83792d;
} else {
if (kind == 0)
dev_warn(dev,
dev_warn(&adapter->dev,
"w83792d: Ignoring 'force' parameter for"
" unknown chip at adapter %d, address"
" 0x%02x\n", i2c_adapter_id(adapter),
address);
goto ERROR1;
return -ENODEV;
}
}
if (kind == w83792d) {
client_name = "w83792d";
} else {
dev_err(dev, "w83792d: Internal error: unknown kind (%d)?!?\n",
kind);
goto ERROR1;
strlcpy(info->type, "w83792d", I2C_NAME_SIZE);
return 0;
}
static int
w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct w83792d_data *data;
struct device *dev = &client->dev;
int i, val1, err;
data = kzalloc(sizeof(struct w83792d_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto ERROR0;
}
/* Fill in the remaining client fields and put into the global list */
strlcpy(client->name, client_name, I2C_NAME_SIZE);
data->type = kind;
i2c_set_clientdata(client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
err = w83792d_detect_subclients(client);
if (err)
goto ERROR1;
if ((err = w83792d_detect_subclients(adapter, address,
kind, client)))
goto ERROR2;
/* Initialize the chip */
w83792d_init_client(client);
@ -1457,16 +1400,10 @@ exit_remove_files:
for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++)
sysfs_remove_group(&dev->kobj, &w83792d_group_fan[i]);
ERROR3:
if (data->lm75[0] != NULL) {
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[0]);
}
if (data->lm75[1] != NULL) {
i2c_detach_client(data->lm75[1]);
kfree(data->lm75[1]);
}
ERROR2:
i2c_detach_client(client);
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
if (data->lm75[1] != NULL)
i2c_unregister_device(data->lm75[1]);
ERROR1:
kfree(data);
ERROR0:
@ -1474,30 +1411,23 @@ ERROR0:
}
static int
w83792d_detach_client(struct i2c_client *client)
w83792d_remove(struct i2c_client *client)
{
struct w83792d_data *data = i2c_get_clientdata(client);
int err, i;
int i;
/* main client */
if (data) {
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &w83792d_group);
for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++)
sysfs_remove_group(&client->dev.kobj,
&w83792d_group_fan[i]);
}
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &w83792d_group);
for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++)
sysfs_remove_group(&client->dev.kobj,
&w83792d_group_fan[i]);
if ((err = i2c_detach_client(client)))
return err;
/* main client */
if (data)
kfree(data);
/* subclient */
else
kfree(client);
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
if (data->lm75[1] != NULL)
i2c_unregister_device(data->lm75[1]);
kfree(data);
return 0;
}

View File

@ -179,7 +179,6 @@ static inline s8 TEMP_TO_REG(long val, s8 min, s8 max)
}
struct w83793_data {
struct i2c_client client;
struct i2c_client *lm75[2];
struct device *hwmon_dev;
struct mutex update_lock;
@ -226,19 +225,31 @@ struct w83793_data {
static u8 w83793_read_value(struct i2c_client *client, u16 reg);
static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value);
static int w83793_attach_adapter(struct i2c_adapter *adapter);
static int w83793_detect(struct i2c_adapter *adapter, int address, int kind);
static int w83793_detach_client(struct i2c_client *client);
static int w83793_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int w83793_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int w83793_remove(struct i2c_client *client);
static void w83793_init_client(struct i2c_client *client);
static void w83793_update_nonvolatile(struct device *dev);
static struct w83793_data *w83793_update_device(struct device *dev);
static const struct i2c_device_id w83793_id[] = {
{ "w83793", w83793 },
{ }
};
MODULE_DEVICE_TABLE(i2c, w83793_id);
static struct i2c_driver w83793_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "w83793",
},
.attach_adapter = w83793_attach_adapter,
.detach_client = w83793_detach_client,
.probe = w83793_probe,
.remove = w83793_remove,
.id_table = w83793_id,
.detect = w83793_detect,
.address_data = &addr_data,
};
static ssize_t
@ -1053,89 +1064,51 @@ static void w83793_init_client(struct i2c_client *client)
}
static int w83793_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, w83793_detect);
}
static int w83793_detach_client(struct i2c_client *client)
static int w83793_remove(struct i2c_client *client)
{
struct w83793_data *data = i2c_get_clientdata(client);
struct device *dev = &client->dev;
int err, i;
int i;
/* main client */
if (data) {
hwmon_device_unregister(data->hwmon_dev);
hwmon_device_unregister(data->hwmon_dev);
for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++)
device_remove_file(dev,
&w83793_sensor_attr_2[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++)
device_remove_file(dev,
&w83793_sensor_attr_2[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
device_remove_file(dev, &sda_single_files[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
device_remove_file(dev, &sda_single_files[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(w83793_vid); i++)
device_remove_file(dev, &w83793_vid[i].dev_attr);
device_remove_file(dev, &dev_attr_vrm);
for (i = 0; i < ARRAY_SIZE(w83793_vid); i++)
device_remove_file(dev, &w83793_vid[i].dev_attr);
device_remove_file(dev, &dev_attr_vrm);
for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
device_remove_file(dev, &w83793_left_fan[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
device_remove_file(dev, &w83793_left_fan[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++)
device_remove_file(dev, &w83793_left_pwm[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++)
device_remove_file(dev, &w83793_left_pwm[i].dev_attr);
for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
device_remove_file(dev, &w83793_temp[i].dev_attr);
}
for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
device_remove_file(dev, &w83793_temp[i].dev_attr);
if ((err = i2c_detach_client(client)))
return err;
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
if (data->lm75[1] != NULL)
i2c_unregister_device(data->lm75[1]);
/* main client */
if (data)
kfree(data);
/* subclient */
else
kfree(client);
kfree(data);
return 0;
}
static int
w83793_create_subclient(struct i2c_adapter *adapter,
struct i2c_client *client, int addr,
struct i2c_client **sub_cli)
{
int err = 0;
struct i2c_client *sub_client;
(*sub_cli) = sub_client =
kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!(sub_client)) {
return -ENOMEM;
}
sub_client->addr = 0x48 + addr;
i2c_set_clientdata(sub_client, NULL);
sub_client->adapter = adapter;
sub_client->driver = &w83793_driver;
strlcpy(sub_client->name, "w83793 subclient", I2C_NAME_SIZE);
if ((err = i2c_attach_client(sub_client))) {
dev_err(&client->dev, "subclient registration "
"at address 0x%x failed\n", sub_client->addr);
kfree(sub_client);
}
return err;
}
static int
w83793_detect_subclients(struct i2c_adapter *adapter, int address,
int kind, struct i2c_client *client)
w83793_detect_subclients(struct i2c_client *client)
{
int i, id, err;
int address = client->addr;
u8 tmp;
struct i2c_adapter *adapter = client->adapter;
struct w83793_data *data = i2c_get_clientdata(client);
id = i2c_adapter_id(adapter);
@ -1158,11 +1131,7 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address,
tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR);
if (!(tmp & 0x08)) {
err =
w83793_create_subclient(adapter, client, tmp & 0x7,
&data->lm75[0]);
if (err < 0)
goto ERROR_SC_0;
data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (tmp & 0x7));
}
if (!(tmp & 0x80)) {
if ((data->lm75[0] != NULL)
@ -1173,10 +1142,8 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address,
err = -ENODEV;
goto ERROR_SC_1;
}
err = w83793_create_subclient(adapter, client,
(tmp >> 4) & 0x7, &data->lm75[1]);
if (err < 0)
goto ERROR_SC_1;
data->lm75[1] = i2c_new_dummy(adapter,
0x48 + ((tmp >> 4) & 0x7));
}
return 0;
@ -1184,69 +1151,44 @@ w83793_detect_subclients(struct i2c_adapter *adapter, int address,
/* Undo inits in case of errors */
ERROR_SC_1:
if (data->lm75[0] != NULL) {
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[0]);
}
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
ERROR_SC_0:
return err;
}
static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int w83793_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
int i;
u8 tmp, val;
struct i2c_client *client;
struct device *dev;
struct w83793_data *data;
int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5;
int files_temp = ARRAY_SIZE(w83793_temp) / 6;
int err = 0;
u8 tmp, bank;
struct i2c_adapter *adapter = client->adapter;
unsigned short address = client->addr;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
goto exit;
return -ENODEV;
}
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access w83793_{read,write}_value. */
bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
if (!(data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
dev = &client->dev;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &w83793_driver;
data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
/* Now, we do the remaining detection. */
if (kind < 0) {
tmp = data->bank & 0x80 ? 0x5c : 0xa3;
tmp = bank & 0x80 ? 0x5c : 0xa3;
/* Check Winbond vendor ID */
if (tmp != i2c_smbus_read_byte_data(client,
W83793_REG_VENDORID)) {
pr_debug("w83793: Detection failed at check "
"vendor id\n");
err = -ENODEV;
goto free_mem;
return -ENODEV;
}
/* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
should match */
if ((data->bank & 0x07) == 0
if ((bank & 0x07) == 0
&& i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
(address << 1)) {
pr_debug("w83793: Detection failed at check "
"i2c addr\n");
err = -ENODEV;
goto free_mem;
return -ENODEV;
}
}
@ -1255,30 +1197,47 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
Winbond. Determine the chip type now */
if (kind <= 0) {
if (0x7b == w83793_read_value(client, W83793_REG_CHIPID)) {
if (0x7b == i2c_smbus_read_byte_data(client,
W83793_REG_CHIPID)) {
kind = w83793;
} else {
if (kind == 0)
dev_warn(&adapter->dev, "w83793: Ignoring "
"'force' parameter for unknown chip "
"at address 0x%02x\n", address);
err = -ENODEV;
goto free_mem;
return -ENODEV;
}
}
/* Fill in the remaining client fields and put into the global list */
strlcpy(client->name, "w83793", I2C_NAME_SIZE);
strlcpy(info->type, "w83793", I2C_NAME_SIZE);
return 0;
}
static int w83793_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct w83793_data *data;
int i, tmp, val, err;
int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5;
int files_temp = ARRAY_SIZE(w83793_temp) / 6;
data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
data->bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
err = w83793_detect_subclients(client);
if (err)
goto free_mem;
if ((err = w83793_detect_subclients(adapter, address, kind, client)))
goto detach_client;
/* Initialize the chip */
w83793_init_client(client);
@ -1459,16 +1418,10 @@ exit_remove:
for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
device_remove_file(dev, &w83793_temp[i].dev_attr);
if (data->lm75[0] != NULL) {
i2c_detach_client(data->lm75[0]);
kfree(data->lm75[0]);
}
if (data->lm75[1] != NULL) {
i2c_detach_client(data->lm75[1]);
kfree(data->lm75[1]);
}
detach_client:
i2c_detach_client(client);
if (data->lm75[0] != NULL)
i2c_unregister_device(data->lm75[0]);
if (data->lm75[1] != NULL)
i2c_unregister_device(data->lm75[1]);
free_mem:
kfree(data);
exit:

View File

@ -81,10 +81,11 @@ I2C_CLIENT_INSMOD_1(w83l785ts);
* Functions declaration
*/
static int w83l785ts_attach_adapter(struct i2c_adapter *adapter);
static int w83l785ts_detect(struct i2c_adapter *adapter, int address,
int kind);
static int w83l785ts_detach_client(struct i2c_client *client);
static int w83l785ts_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int w83l785ts_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int w83l785ts_remove(struct i2c_client *client);
static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval);
static struct w83l785ts_data *w83l785ts_update_device(struct device *dev);
@ -92,12 +93,22 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev);
* Driver data (common to all clients)
*/
static const struct i2c_device_id w83l785ts_id[] = {
{ "w83l785ts", w83l785ts },
{ }
};
MODULE_DEVICE_TABLE(i2c, w83l785ts_id);
static struct i2c_driver w83l785ts_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "w83l785ts",
},
.attach_adapter = w83l785ts_attach_adapter,
.detach_client = w83l785ts_detach_client,
.probe = w83l785ts_probe,
.remove = w83l785ts_remove,
.id_table = w83l785ts_id,
.detect = w83l785ts_detect,
.address_data = &addr_data,
};
/*
@ -105,7 +116,6 @@ static struct i2c_driver w83l785ts_driver = {
*/
struct w83l785ts_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
@ -135,40 +145,14 @@ static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 1);
* Real code
*/
static int w83l785ts_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int w83l785ts_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, w83l785ts_detect);
}
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *new_client;
struct w83l785ts_data *data;
int err = 0;
struct i2c_adapter *adapter = new_client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
if (!(data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
/* The common I2C client data is placed right before the
* W83L785TS-specific data. */
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &w83l785ts_driver;
new_client->flags = 0;
return -ENODEV;
/*
* Now we do the remaining detection. A negative kind means that
@ -188,8 +172,8 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) {
dev_dbg(&adapter->dev,
"W83L785TS-S detection failed at 0x%02x.\n",
address);
goto exit_free;
new_client->addr);
return -ENODEV;
}
}
@ -214,22 +198,34 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&adapter->dev,
"Unsupported chip (man_id=0x%04X, "
"chip_id=0x%02X).\n", man_id, chip_id);
goto exit_free;
return -ENODEV;
}
}
/* We can fill in the remaining client fields. */
strlcpy(new_client->name, "w83l785ts", I2C_NAME_SIZE);
strlcpy(info->type, "w83l785ts", I2C_NAME_SIZE);
return 0;
}
static int w83l785ts_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct w83l785ts_data *data;
int err = 0;
data = kzalloc(sizeof(struct w83l785ts_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(new_client, data);
data->valid = 0;
mutex_init(&data->update_lock);
/* Default values in case the first read fails (unlikely). */
data->temp[1] = data->temp[0] = 0;
/* Tell the I2C layer a new client has arrived. */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/*
* Initialize the W83L785TS chip
* Nothing yet, assume it is already started.
@ -259,25 +255,20 @@ exit_remove:
&sensor_dev_attr_temp1_input.dev_attr);
device_remove_file(&new_client->dev,
&sensor_dev_attr_temp1_max.dev_attr);
i2c_detach_client(new_client);
exit_free:
kfree(data);
exit:
return err;
}
static int w83l785ts_detach_client(struct i2c_client *client)
static int w83l785ts_remove(struct i2c_client *client)
{
struct w83l785ts_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
device_remove_file(&client->dev,
&sensor_dev_attr_temp1_input.dev_attr);
device_remove_file(&client->dev,
&sensor_dev_attr_temp1_max.dev_attr);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;
@ -286,6 +277,18 @@ static int w83l785ts_detach_client(struct i2c_client *client)
static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval)
{
int value, i;
struct device *dev;
const char *prefix;
/* We might be called during detection, at which point the client
isn't yet fully initialized, so we can't use dev_dbg on it */
if (i2c_get_clientdata(client)) {
dev = &client->dev;
prefix = "";
} else {
dev = &client->adapter->dev;
prefix = "w83l785ts: ";
}
/* Frequent read errors have been reported on Asus boards, so we
* retry on read errors. If it still fails (unlikely), return the
@ -293,15 +296,15 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval)
for (i = 1; i <= MAX_RETRIES; i++) {
value = i2c_smbus_read_byte_data(client, reg);
if (value >= 0) {
dev_dbg(&client->dev, "Read 0x%02x from register "
"0x%02x.\n", value, reg);
dev_dbg(dev, "%sRead 0x%02x from register 0x%02x.\n",
prefix, value, reg);
return value;
}
dev_dbg(&client->dev, "Read failed, will retry in %d.\n", i);
dev_dbg(dev, "%sRead failed, will retry in %d.\n", prefix, i);
msleep(i);
}
dev_err(&client->dev, "Couldn't read value from register 0x%02x.\n",
dev_err(dev, "%sCouldn't read value from register 0x%02x.\n", prefix,
reg);
return defval;
}

View File

@ -121,7 +121,6 @@ DIV_TO_REG(long val)
}
struct w83l786ng_data {
struct i2c_client client;
struct device *hwmon_dev;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
@ -146,18 +145,30 @@ struct w83l786ng_data {
u8 tolerance[2];
};
static int w83l786ng_attach_adapter(struct i2c_adapter *adapter);
static int w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind);
static int w83l786ng_detach_client(struct i2c_client *client);
static int w83l786ng_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int w83l786ng_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int w83l786ng_remove(struct i2c_client *client);
static void w83l786ng_init_client(struct i2c_client *client);
static struct w83l786ng_data *w83l786ng_update_device(struct device *dev);
static const struct i2c_device_id w83l786ng_id[] = {
{ "w83l786ng", w83l786ng },
{ }
};
MODULE_DEVICE_TABLE(i2c, w83l786ng_id);
static struct i2c_driver w83l786ng_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "w83l786ng",
},
.attach_adapter = w83l786ng_attach_adapter,
.detach_client = w83l786ng_detach_client,
.probe = w83l786ng_probe,
.remove = w83l786ng_remove,
.id_table = w83l786ng_id,
.detect = w83l786ng_detect,
.address_data = &addr_data,
};
static u8
@ -575,42 +586,15 @@ static const struct attribute_group w83l786ng_group = {
};
static int
w83l786ng_attach_adapter(struct i2c_adapter *adapter)
w83l786ng_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, w83l786ng_detect);
}
static int
w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct device *dev;
struct w83l786ng_data *data;
int i, err = 0;
u8 reg_tmp;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
goto exit;
return -ENODEV;
}
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access w83l786ng_{read,write}_value. */
if (!(data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
dev = &client->dev;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &w83l786ng_driver;
/*
* Now we do the remaining detection. A negative kind means that
* the driver was loaded with no force parameter (default), so we
@ -627,8 +611,8 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind)
W83L786NG_REG_CONFIG) & 0x80) != 0x00)) {
dev_dbg(&adapter->dev,
"W83L786NG detection failed at 0x%02x.\n",
address);
goto exit_free;
client->addr);
return -ENODEV;
}
}
@ -651,17 +635,31 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind)
dev_info(&adapter->dev,
"Unsupported chip (man_id=0x%04X, "
"chip_id=0x%02X).\n", man_id, chip_id);
goto exit_free;
return -ENODEV;
}
}
/* Fill in the remaining client fields and put into the global list */
strlcpy(client->name, "w83l786ng", I2C_NAME_SIZE);
mutex_init(&data->update_lock);
strlcpy(info->type, "w83l786ng", I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
return 0;
}
static int
w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct w83l786ng_data *data;
int i, err = 0;
u8 reg_tmp;
data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Initialize the chip */
w83l786ng_init_client(client);
@ -693,25 +691,19 @@ w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind)
exit_remove:
sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int
w83l786ng_detach_client(struct i2c_client *client)
w83l786ng_remove(struct i2c_client *client)
{
struct w83l786ng_data *data = i2c_get_clientdata(client);
int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(data);
return 0;

View File

@ -155,6 +155,16 @@ static int __init amd756_s4882_init(void)
int i, error;
union i2c_smbus_data ioconfig;
/* Configure the PCA9556 multiplexer */
ioconfig.byte = 0x00; /* All I/O to output mode */
error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
I2C_SMBUS_BYTE_DATA, &ioconfig);
if (error) {
dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n");
error = -EIO;
goto ERROR0;
}
/* Unregister physical bus */
error = i2c_del_adapter(&amd756_smbus);
if (error) {
@ -198,22 +208,11 @@ static int __init amd756_s4882_init(void)
s4882_algo[3].smbus_xfer = amd756_access_virt3;
s4882_algo[4].smbus_xfer = amd756_access_virt4;
/* Configure the PCA9556 multiplexer */
ioconfig.byte = 0x00; /* All I/O to output mode */
error = amd756_smbus.algo->smbus_xfer(&amd756_smbus, 0x18, 0,
I2C_SMBUS_WRITE, 0x03,
I2C_SMBUS_BYTE_DATA, &ioconfig);
if (error) {
dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n");
error = -EIO;
goto ERROR3;
}
/* Register virtual adapters */
for (i = 0; i < 5; i++) {
error = i2c_add_adapter(s4882_adapter+i);
if (error) {
dev_err(&amd756_smbus.dev,
printk(KERN_ERR "i2c-amd756-s4882: "
"Virtual adapter %d registration "
"failed, module not inserted\n", i);
for (i--; i >= 0; i--)
@ -252,8 +251,8 @@ static void __exit amd756_s4882_exit(void)
/* Restore physical bus */
if (i2c_add_adapter(&amd756_smbus))
dev_err(&amd756_smbus.dev, "Physical bus restoration "
"failed\n");
printk(KERN_ERR "i2c-amd756-s4882: "
"Physical bus restoration failed\n");
}
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");

View File

@ -150,6 +150,16 @@ static int __init nforce2_s4985_init(void)
int i, error;
union i2c_smbus_data ioconfig;
/* Configure the PCA9556 multiplexer */
ioconfig.byte = 0x00; /* All I/O to output mode */
error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
I2C_SMBUS_BYTE_DATA, &ioconfig);
if (error) {
dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
error = -EIO;
goto ERROR0;
}
/* Unregister physical bus */
if (!nforce2_smbus)
return -ENODEV;
@ -191,24 +201,13 @@ static int __init nforce2_s4985_init(void)
s4985_algo[3].smbus_xfer = nforce2_access_virt3;
s4985_algo[4].smbus_xfer = nforce2_access_virt4;
/* Configure the PCA9556 multiplexer */
ioconfig.byte = 0x00; /* All I/O to output mode */
error = nforce2_smbus->algo->smbus_xfer(nforce2_smbus, 0x18, 0,
I2C_SMBUS_WRITE, 0x03,
I2C_SMBUS_BYTE_DATA, &ioconfig);
if (error) {
dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
error = -EIO;
goto ERROR3;
}
/* Register virtual adapters */
for (i = 0; i < 5; i++) {
error = i2c_add_adapter(s4985_adapter + i);
if (error) {
dev_err(&nforce2_smbus->dev,
"Virtual adapter %d registration "
"failed, module not inserted\n", i);
printk(KERN_ERR "i2c-nforce2-s4985: "
"Virtual adapter %d registration "
"failed, module not inserted\n", i);
for (i--; i >= 0; i--)
i2c_del_adapter(s4985_adapter + i);
goto ERROR3;
@ -245,8 +244,8 @@ static void __exit nforce2_s4985_exit(void)
/* Restore physical bus */
if (i2c_add_adapter(nforce2_smbus))
dev_err(&nforce2_smbus->dev, "Physical bus restoration "
"failed\n");
printk(KERN_ERR "i2c-nforce2-s4985: "
"Physical bus restoration failed\n");
}
MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");

View File

@ -47,7 +47,6 @@ enum eeprom_nature {
/* Each client has this additional data */
struct eeprom_data {
struct i2c_client client;
struct mutex update_lock;
u8 valid; /* bitfield, bit!=0 if slice is valid */
unsigned long last_updated[8]; /* In jiffies, 8 slices */
@ -56,19 +55,6 @@ struct eeprom_data {
};
static int eeprom_attach_adapter(struct i2c_adapter *adapter);
static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind);
static int eeprom_detach_client(struct i2c_client *client);
/* This is the driver that will be inserted */
static struct i2c_driver eeprom_driver = {
.driver = {
.name = "eeprom",
},
.attach_adapter = eeprom_attach_adapter,
.detach_client = eeprom_detach_client,
};
static void eeprom_update_client(struct i2c_client *client, u8 slice)
{
struct eeprom_data *data = i2c_get_clientdata(client);
@ -148,25 +134,17 @@ static struct bin_attribute eeprom_attr = {
.read = eeprom_read,
};
static int eeprom_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int eeprom_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
if (!(adapter->class & (I2C_CLASS_DDC | I2C_CLASS_SPD)))
return 0;
return i2c_probe(adapter, &addr_data, eeprom_detect);
}
/* This function is called by i2c_probe */
static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct eeprom_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
/* EDID EEPROMs are often 24C00 EEPROMs, which answer to all
addresses 0x50-0x57, but we only care about 0x50. So decline
attaching to addresses >= 0x51 on DDC buses */
if (!(adapter->class & I2C_CLASS_SPD) && address >= 0x51)
goto exit;
if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51)
return -ENODEV;
/* There are four ways we can read the EEPROM data:
(1) I2C block reads (faster, but unsupported by most adapters)
@ -177,32 +155,33 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
because all known adapters support one of the first two. */
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)
&& !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK))
goto exit;
return -ENODEV;
strlcpy(info->type, "eeprom", I2C_NAME_SIZE);
return 0;
}
static int eeprom_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = client->adapter;
struct eeprom_data *data;
int err;
if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
memset(data->data, 0xff, EEPROM_SIZE);
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &eeprom_driver;
/* Fill in the remaining client fields */
strlcpy(client->name, "eeprom", I2C_NAME_SIZE);
mutex_init(&data->update_lock);
data->nature = UNKNOWN;
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_kfree;
/* Detect the Vaio nature of EEPROMs.
We use the "PCG-" or "VGN-" prefix as the signature. */
if (address == 0x57
if (client->addr == 0x57
&& i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
char name[4];
@ -221,33 +200,42 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
/* create the sysfs eeprom file */
err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr);
if (err)
goto exit_detach;
goto exit_kfree;
return 0;
exit_detach:
i2c_detach_client(client);
exit_kfree:
kfree(data);
exit:
return err;
}
static int eeprom_detach_client(struct i2c_client *client)
static int eeprom_remove(struct i2c_client *client)
{
int err;
sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr);
err = i2c_detach_client(client);
if (err)
return err;
kfree(i2c_get_clientdata(client));
return 0;
}
static const struct i2c_device_id eeprom_id[] = {
{ "eeprom", 0 },
{ }
};
static struct i2c_driver eeprom_driver = {
.driver = {
.name = "eeprom",
},
.probe = eeprom_probe,
.remove = eeprom_remove,
.id_table = eeprom_id,
.class = I2C_CLASS_DDC | I2C_CLASS_SPD,
.detect = eeprom_detect,
.address_data = &addr_data,
};
static int __init eeprom_init(void)
{
return i2c_add_driver(&eeprom_driver);

View File

@ -53,7 +53,7 @@ I2C_CLIENT_INSMOD_1(max6875);
/* Each client has this additional data */
struct max6875_data {
struct i2c_client client;
struct i2c_client *fake_client;
struct mutex update_lock;
u32 valid;
@ -61,19 +61,6 @@ struct max6875_data {
unsigned long last_updated[USER_EEPROM_SLICES];
};
static int max6875_attach_adapter(struct i2c_adapter *adapter);
static int max6875_detect(struct i2c_adapter *adapter, int address, int kind);
static int max6875_detach_client(struct i2c_client *client);
/* This is the driver that will be inserted */
static struct i2c_driver max6875_driver = {
.driver = {
.name = "max6875",
},
.attach_adapter = max6875_attach_adapter,
.detach_client = max6875_detach_client,
};
static void max6875_update_slice(struct i2c_client *client, int slice)
{
struct max6875_data *data = i2c_get_clientdata(client);
@ -159,96 +146,87 @@ static struct bin_attribute user_eeprom_attr = {
.read = max6875_read,
};
static int max6875_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int max6875_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
return i2c_probe(adapter, &addr_data, max6875_detect);
}
/* This function is called by i2c_probe */
static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *real_client;
struct i2c_client *fake_client;
struct max6875_data *data;
int err;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
| I2C_FUNC_SMBUS_READ_BYTE))
return 0;
return -ENODEV;
/* Only check even addresses */
if (address & 1)
return 0;
if (client->addr & 1)
return -ENODEV;
strlcpy(info->type, "max6875", I2C_NAME_SIZE);
return 0;
}
static int max6875_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct max6875_data *data;
int err;
if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
return -ENOMEM;
/* A fake client is created on the odd address */
if (!(fake_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
data->fake_client = i2c_new_dummy(client->adapter, client->addr + 1);
if (!data->fake_client) {
err = -ENOMEM;
goto exit_kfree1;
goto exit_kfree;
}
/* Init real i2c_client */
real_client = &data->client;
i2c_set_clientdata(real_client, data);
real_client->addr = address;
real_client->adapter = adapter;
real_client->driver = &max6875_driver;
strlcpy(real_client->name, "max6875", I2C_NAME_SIZE);
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Init fake client data */
i2c_set_clientdata(fake_client, NULL);
fake_client->addr = address | 1;
fake_client->adapter = adapter;
fake_client->driver = &max6875_driver;
strlcpy(fake_client->name, "max6875 subclient", I2C_NAME_SIZE);
if ((err = i2c_attach_client(real_client)) != 0)
goto exit_kfree2;
if ((err = i2c_attach_client(fake_client)) != 0)
goto exit_detach1;
err = sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr);
err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr);
if (err)
goto exit_detach2;
goto exit_remove_fake;
return 0;
exit_detach2:
i2c_detach_client(fake_client);
exit_detach1:
i2c_detach_client(real_client);
exit_kfree2:
kfree(fake_client);
exit_kfree1:
exit_remove_fake:
i2c_unregister_device(data->fake_client);
exit_kfree:
kfree(data);
return err;
}
/* Will be called for both the real client and the fake client */
static int max6875_detach_client(struct i2c_client *client)
static int max6875_remove(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);
i2c_unregister_device(data->fake_client);
err = i2c_detach_client(client);
if (err)
return err;
sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
kfree(data);
if (data) /* real client */
kfree(data);
else /* fake client */
kfree(client);
return 0;
}
static const struct i2c_device_id max6875_id[] = {
{ "max6875", 0 },
{ }
};
static struct i2c_driver max6875_driver = {
.driver = {
.name = "max6875",
},
.probe = max6875_probe,
.remove = max6875_remove,
.id_table = max6875_id,
.detect = max6875_detect,
.address_data = &addr_data,
};
static int __init max6875_init(void)
{
return i2c_add_driver(&max6875_driver);

View File

@ -14,8 +14,8 @@
#include <linux/i2c.h>
#include <linux/hwmon-sysfs.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = {0x74, 0x75, 0x76, 0x77, I2C_CLIENT_END};
/* Addresses to scan: none, device is not autodetected */
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(pca9539);
@ -32,23 +32,6 @@ enum pca9539_cmd
PCA9539_DIRECTION_1 = 7,
};
static int pca9539_attach_adapter(struct i2c_adapter *adapter);
static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind);
static int pca9539_detach_client(struct i2c_client *client);
/* This is the driver that will be inserted */
static struct i2c_driver pca9539_driver = {
.driver = {
.name = "pca9539",
},
.attach_adapter = pca9539_attach_adapter,
.detach_client = pca9539_detach_client,
};
struct pca9539_data {
struct i2c_client client;
};
/* following are the sysfs callback functions */
static ssize_t pca9539_show(struct device *dev, struct device_attribute *attr,
char *buf)
@ -105,77 +88,51 @@ static struct attribute_group pca9539_defattr_group = {
.attrs = pca9539_attributes,
};
static int pca9539_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int pca9539_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
return i2c_probe(adapter, &addr_data, pca9539_detect);
}
/* This function is called by i2c_probe */
static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct pca9539_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
goto exit;
return -ENODEV;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
if (!(data = kzalloc(sizeof(struct pca9539_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &pca9539_driver;
if (kind < 0) {
/* Detection: the pca9539 only has 8 registers (0-7).
A read of 7 should succeed, but a read of 8 should fail. */
if ((i2c_smbus_read_byte_data(client, 7) < 0) ||
(i2c_smbus_read_byte_data(client, 8) >= 0))
goto exit_kfree;
}
strlcpy(client->name, "pca9539", I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_kfree;
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj,
&pca9539_defattr_group);
if (err)
goto exit_detach;
strlcpy(info->type, "pca9539", I2C_NAME_SIZE);
return 0;
exit_detach:
i2c_detach_client(client);
exit_kfree:
kfree(data);
exit:
return err;
}
static int pca9539_detach_client(struct i2c_client *client)
static int pca9539_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err;
/* Register sysfs hooks */
return sysfs_create_group(&client->dev.kobj,
&pca9539_defattr_group);
}
static int pca9539_remove(struct i2c_client *client)
{
sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(i2c_get_clientdata(client));
return 0;
}
static const struct i2c_device_id pca9539_id[] = {
{ "pca9539", 0 },
{ }
};
static struct i2c_driver pca9539_driver = {
.driver = {
.name = "pca9539",
},
.probe = pca9539_probe,
.remove = pca9539_remove,
.id_table = pca9539_id,
.detect = pca9539_detect,
.address_data = &addr_data,
};
static int __init pca9539_init(void)
{
return i2c_add_driver(&pca9539_driver);

View File

@ -38,37 +38,19 @@
#include <linux/slab.h>
#include <linux/i2c.h>
/* Addresses to scan */
static const unsigned short normal_i2c[] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
I2C_CLIENT_END
};
/* Addresses to scan: none, device can't be detected */
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD_2(pcf8574, pcf8574a);
/* Each client has this additional data */
struct pcf8574_data {
struct i2c_client client;
int write; /* Remember last written value */
};
static int pcf8574_attach_adapter(struct i2c_adapter *adapter);
static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind);
static int pcf8574_detach_client(struct i2c_client *client);
static void pcf8574_init_client(struct i2c_client *client);
/* This is the driver that will be inserted */
static struct i2c_driver pcf8574_driver = {
.driver = {
.name = "pcf8574",
},
.attach_adapter = pcf8574_attach_adapter,
.detach_client = pcf8574_detach_client,
};
/* following are the sysfs callback functions */
static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf)
{
@ -119,41 +101,22 @@ static const struct attribute_group pcf8574_attr_group = {
* Real code
*/
static int pcf8574_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int pcf8574_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
return i2c_probe(adapter, &addr_data, pcf8574_detect);
}
/* This function is called by i2c_probe */
static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct pcf8574_data *data;
int err = 0;
const char *client_name = "";
struct i2c_adapter *adapter = client->adapter;
const char *client_name;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
goto exit;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
if (!(data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &pcf8574_driver;
return -ENODEV;
/* Now, we would do the remaining detection. But the PCF8574 is plainly
impossible to detect! Stupid chip. */
/* Determine the chip type */
if (kind <= 0) {
if (address >= 0x38 && address <= 0x3f)
if (client->addr >= 0x38 && client->addr <= 0x3f)
kind = pcf8574a;
else
kind = pcf8574;
@ -163,40 +126,43 @@ static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
client_name = "pcf8574a";
else
client_name = "pcf8574";
strlcpy(info->type, client_name, I2C_NAME_SIZE);
/* Fill in the remaining client fields and put it into the global list */
strlcpy(client->name, client_name, I2C_NAME_SIZE);
return 0;
}
static int pcf8574_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pcf8574_data *data;
int err;
data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_free;
/* Initialize the PCF8574 chip */
pcf8574_init_client(client);
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &pcf8574_attr_group);
if (err)
goto exit_detach;
goto exit_free;
return 0;
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int pcf8574_detach_client(struct i2c_client *client)
static int pcf8574_remove(struct i2c_client *client)
{
int err;
sysfs_remove_group(&client->dev.kobj, &pcf8574_attr_group);
if ((err = i2c_detach_client(client)))
return err;
kfree(i2c_get_clientdata(client));
return 0;
}
@ -208,6 +174,24 @@ static void pcf8574_init_client(struct i2c_client *client)
data->write = -EAGAIN;
}
static const struct i2c_device_id pcf8574_id[] = {
{ "pcf8574", 0 },
{ "pcf8574a", 0 },
{ }
};
static struct i2c_driver pcf8574_driver = {
.driver = {
.name = "pcf8574",
},
.probe = pcf8574_probe,
.remove = pcf8574_remove,
.id_table = pcf8574_id,
.detect = pcf8574_detect,
.address_data = &addr_data,
};
static int __init pcf8574_init(void)
{
return i2c_add_driver(&pcf8574_driver);

View File

@ -32,11 +32,8 @@
#include <linux/slab.h> /* kzalloc() */
#include <linux/sysfs.h> /* sysfs_create_group() */
/* Addresses to scan */
static const unsigned short normal_i2c[] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
I2C_CLIENT_END
};
/* Addresses to scan: none, device can't be detected */
static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
/* Insmod parameters */
I2C_CLIENT_INSMOD;
@ -44,24 +41,9 @@ I2C_CLIENT_INSMOD;
/* Each client has this additional data */
struct pcf8575_data {
struct i2c_client client;
int write; /* last written value, or error code */
};
static int pcf8575_attach_adapter(struct i2c_adapter *adapter);
static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind);
static int pcf8575_detach_client(struct i2c_client *client);
/* This is the driver that will be inserted */
static struct i2c_driver pcf8575_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "pcf8575",
},
.attach_adapter = pcf8575_attach_adapter,
.detach_client = pcf8575_detach_client,
};
/* following are the sysfs callback functions */
static ssize_t show_read(struct device *dev, struct device_attribute *attr,
char *buf)
@ -126,75 +108,77 @@ static const struct attribute_group pcf8575_attr_group = {
* Real code
*/
static int pcf8575_attach_adapter(struct i2c_adapter *adapter)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int pcf8575_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
return i2c_probe(adapter, &addr_data, pcf8575_detect);
}
/* This function is called by i2c_probe */
static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct i2c_client *client;
struct pcf8575_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
goto exit;
return -ENODEV;
/* This is the place to detect whether the chip at the specified
address really is a PCF8575 chip. However, there is no method known
to detect whether an I2C chip is a PCF8575 or any other I2C chip. */
strlcpy(info->type, "pcf8575", I2C_NAME_SIZE);
return 0;
}
static int pcf8575_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pcf8575_data *data;
int err;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
data = kzalloc(sizeof(struct pcf8575_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &pcf8575_driver;
strlcpy(client->name, "pcf8575", I2C_NAME_SIZE);
data->write = -EAGAIN;
/* This is the place to detect whether the chip at the specified
address really is a PCF8575 chip. However, there is no method known
to detect whether an I2C chip is a PCF8575 or any other I2C chip. */
/* Tell the I2C layer a new client has arrived */
err = i2c_attach_client(client);
if (err)
goto exit_free;
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &pcf8575_attr_group);
if (err)
goto exit_detach;
goto exit_free;
return 0;
exit_detach:
i2c_detach_client(client);
exit_free:
kfree(data);
exit:
return err;
}
static int pcf8575_detach_client(struct i2c_client *client)
static int pcf8575_remove(struct i2c_client *client)
{
int err;
sysfs_remove_group(&client->dev.kobj, &pcf8575_attr_group);
err = i2c_detach_client(client);
if (err)
return err;
kfree(i2c_get_clientdata(client));
return 0;
}
static const struct i2c_device_id pcf8575_id[] = {
{ "pcf8575", 0 },
{ }
};
static struct i2c_driver pcf8575_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "pcf8575",
},
.probe = pcf8575_probe,
.remove = pcf8575_remove,
.id_table = pcf8575_id,
.detect = pcf8575_detect,
.address_data = &addr_data,
};
static int __init pcf8575_init(void)
{
return i2c_add_driver(&pcf8575_driver);

View File

@ -72,28 +72,15 @@ MODULE_PARM_DESC(input_mode,
#define REG_TO_SIGNED(reg) (((reg) & 0x80)?((reg) - 256):(reg))
struct pcf8591_data {
struct i2c_client client;
struct mutex update_lock;
u8 control;
u8 aout;
};
static int pcf8591_attach_adapter(struct i2c_adapter *adapter);
static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind);
static int pcf8591_detach_client(struct i2c_client *client);
static void pcf8591_init_client(struct i2c_client *client);
static int pcf8591_read_channel(struct device *dev, int channel);
/* This is the driver that will be inserted */
static struct i2c_driver pcf8591_driver = {
.driver = {
.name = "pcf8591",
},
.attach_adapter = pcf8591_attach_adapter,
.detach_client = pcf8591_detach_client,
};
/* following are the sysfs callback functions */
#define show_in_channel(channel) \
static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf) \
@ -180,58 +167,46 @@ static const struct attribute_group pcf8591_attr_group_opt = {
/*
* Real code
*/
static int pcf8591_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_probe(adapter, &addr_data, pcf8591_detect);
}
/* This function is called by i2c_probe */
static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int pcf8591_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_client *client;
struct pcf8591_data *data;
int err = 0;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE
| I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
goto exit;
return -ENODEV;
/* Now, we would do the remaining detection. But the PCF8591 is plainly
impossible to detect! Stupid chip. */
strlcpy(info->type, "pcf8591", I2C_NAME_SIZE);
return 0;
}
static int pcf8591_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pcf8591_data *data;
int err;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. */
if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &pcf8591_driver;
/* Now, we would do the remaining detection. But the PCF8591 is plainly
impossible to detect! Stupid chip. */
/* Determine the chip type - only one kind supported! */
if (kind <= 0)
kind = pcf8591;
/* Fill in the remaining client fields and put it into the global
list */
strlcpy(client->name, "pcf8591", I2C_NAME_SIZE);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto exit_kfree;
/* Initialize the PCF8591 chip */
pcf8591_init_client(client);
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group);
if (err)
goto exit_detach;
goto exit_kfree;
/* Register input2 if not in "two differential inputs" mode */
if (input_mode != 3) {
@ -252,24 +227,16 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
exit_sysfs_remove:
sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
exit_detach:
i2c_detach_client(client);
exit_kfree:
kfree(data);
exit:
return err;
}
static int pcf8591_detach_client(struct i2c_client *client)
static int pcf8591_remove(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;
kfree(i2c_get_clientdata(client));
return 0;
}
@ -316,6 +283,25 @@ static int pcf8591_read_channel(struct device *dev, int channel)
return (10 * value);
}
static const struct i2c_device_id pcf8591_id[] = {
{ "pcf8591", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pcf8591_id);
static struct i2c_driver pcf8591_driver = {
.driver = {
.name = "pcf8591",
},
.probe = pcf8591_probe,
.remove = pcf8591_remove,
.id_table = pcf8591_id,
.class = I2C_CLASS_HWMON, /* Nearest choice */
.detect = pcf8591_detect,
.address_data = &addr_data,
};
static int __init pcf8591_init(void)
{
if (input_mode < 0 || input_mode > 3) {

View File

@ -654,6 +654,10 @@ int i2c_del_adapter(struct i2c_adapter *adap)
dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
/* Clear the device structure in case this adapter is ever going to be
added again */
memset(&adap->dev, 0, sizeof(adap->dev));
out_unlock:
mutex_unlock(&core_lock);
return res;

View File

@ -94,21 +94,31 @@ static const u8 ds2482_chan_rd[8] =
#define DS2482_REG_STS_1WB 0x01
static int ds2482_attach_adapter(struct i2c_adapter *adapter);
static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind);
static int ds2482_detach_client(struct i2c_client *client);
static int ds2482_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int ds2482_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info);
static int ds2482_remove(struct i2c_client *client);
/**
* Driver data (common to all clients)
*/
static const struct i2c_device_id ds2482_id[] = {
{ "ds2482", 0 },
{ }
};
static struct i2c_driver ds2482_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ds2482",
},
.attach_adapter = ds2482_attach_adapter,
.detach_client = ds2482_detach_client,
.probe = ds2482_probe,
.remove = ds2482_remove,
.id_table = ds2482_id,
.detect = ds2482_detect,
.address_data = &addr_data,
};
/*
@ -124,7 +134,7 @@ struct ds2482_w1_chan {
};
struct ds2482_data {
struct i2c_client client;
struct i2c_client *client;
struct mutex access_lock;
/* 1-wire interface(s) */
@ -147,7 +157,7 @@ struct ds2482_data {
static inline int ds2482_select_register(struct ds2482_data *pdev, u8 read_ptr)
{
if (pdev->read_prt != read_ptr) {
if (i2c_smbus_write_byte_data(&pdev->client,
if (i2c_smbus_write_byte_data(pdev->client,
DS2482_CMD_SET_READ_PTR,
read_ptr) < 0)
return -1;
@ -167,7 +177,7 @@ static inline int ds2482_select_register(struct ds2482_data *pdev, u8 read_ptr)
*/
static inline int ds2482_send_cmd(struct ds2482_data *pdev, u8 cmd)
{
if (i2c_smbus_write_byte(&pdev->client, cmd) < 0)
if (i2c_smbus_write_byte(pdev->client, cmd) < 0)
return -1;
pdev->read_prt = DS2482_PTR_CODE_STATUS;
@ -187,7 +197,7 @@ static inline int ds2482_send_cmd(struct ds2482_data *pdev, u8 cmd)
static inline int ds2482_send_cmd_data(struct ds2482_data *pdev,
u8 cmd, u8 byte)
{
if (i2c_smbus_write_byte_data(&pdev->client, cmd, byte) < 0)
if (i2c_smbus_write_byte_data(pdev->client, cmd, byte) < 0)
return -1;
/* all cmds leave in STATUS, except CONFIG */
@ -216,7 +226,7 @@ static int ds2482_wait_1wire_idle(struct ds2482_data *pdev)
if (!ds2482_select_register(pdev, DS2482_PTR_CODE_STATUS)) {
do {
temp = i2c_smbus_read_byte(&pdev->client);
temp = i2c_smbus_read_byte(pdev->client);
} while ((temp >= 0) && (temp & DS2482_REG_STS_1WB) &&
(++retries < DS2482_WAIT_IDLE_TIMEOUT));
}
@ -238,13 +248,13 @@ static int ds2482_wait_1wire_idle(struct ds2482_data *pdev)
*/
static int ds2482_set_channel(struct ds2482_data *pdev, u8 channel)
{
if (i2c_smbus_write_byte_data(&pdev->client, DS2482_CMD_CHANNEL_SELECT,
if (i2c_smbus_write_byte_data(pdev->client, DS2482_CMD_CHANNEL_SELECT,
ds2482_chan_wr[channel]) < 0)
return -1;
pdev->read_prt = DS2482_PTR_CODE_CHANNEL;
pdev->channel = -1;
if (i2c_smbus_read_byte(&pdev->client) == ds2482_chan_rd[channel]) {
if (i2c_smbus_read_byte(pdev->client) == ds2482_chan_rd[channel]) {
pdev->channel = channel;
return 0;
}
@ -368,7 +378,7 @@ static u8 ds2482_w1_read_byte(void *data)
ds2482_select_register(pdev, DS2482_PTR_CODE_DATA);
/* Read the data byte */
result = i2c_smbus_read_byte(&pdev->client);
result = i2c_smbus_read_byte(pdev->client);
mutex_unlock(&pdev->access_lock);
@ -415,47 +425,38 @@ static u8 ds2482_w1_reset_bus(void *data)
}
/**
* Called to see if the device exists on an i2c bus.
*/
static int ds2482_attach_adapter(struct i2c_adapter *adapter)
static int ds2482_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
return i2c_probe(adapter, &addr_data, ds2482_detect);
}
/*
* The following function does more than just detection. If detection
* succeeds, it also registers the new chip.
*/
static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind)
{
struct ds2482_data *data;
struct i2c_client *new_client;
int err = 0;
int temp1;
int idx;
if (!i2c_check_functionality(adapter,
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
I2C_FUNC_SMBUS_BYTE))
goto exit;
return -ENODEV;
strlcpy(info->type, "ds2482", I2C_NAME_SIZE);
return 0;
}
static int ds2482_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ds2482_data *data;
int err = -ENODEV;
int temp1;
int idx;
if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->driver = &ds2482_driver;
new_client->adapter = adapter;
data->client = client;
i2c_set_clientdata(client, data);
/* Reset the device (sets the read_ptr to status) */
if (ds2482_send_cmd(data, DS2482_CMD_RESET) < 0) {
dev_dbg(&adapter->dev, "DS2482 reset failed at 0x%02x.\n",
address);
dev_warn(&client->dev, "DS2482 reset failed.\n");
goto exit_free;
}
@ -463,10 +464,10 @@ static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind)
ndelay(525);
/* Read the status byte - only reset bit and line should be set */
temp1 = i2c_smbus_read_byte(new_client);
temp1 = i2c_smbus_read_byte(client);
if (temp1 != (DS2482_REG_STS_LL | DS2482_REG_STS_RST)) {
dev_dbg(&adapter->dev, "DS2482 (0x%02x) reset status "
"0x%02X - not a DS2482\n", address, temp1);
dev_warn(&client->dev, "DS2482 reset status "
"0x%02X - not a DS2482\n", temp1);
goto exit_free;
}
@ -478,16 +479,8 @@ static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind)
/* Set all config items to 0 (off) */
ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, 0xF0);
/* We can fill in the remaining client fields */
snprintf(new_client->name, sizeof(new_client->name), "ds2482-%d00",
data->w1_count);
mutex_init(&data->access_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
/* Register 1-wire interface(s) */
for (idx = 0; idx < data->w1_count; idx++) {
data->w1_ch[idx].pdev = data;
@ -511,8 +504,6 @@ static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind)
return 0;
exit_w1_remove:
i2c_detach_client(new_client);
for (idx = 0; idx < data->w1_count; idx++) {
if (data->w1_ch[idx].pdev != NULL)
w1_remove_master_device(&data->w1_ch[idx].w1_bm);
@ -523,10 +514,10 @@ exit:
return err;
}
static int ds2482_detach_client(struct i2c_client *client)
static int ds2482_remove(struct i2c_client *client)
{
struct ds2482_data *data = i2c_get_clientdata(client);
int err, idx;
int idx;
/* Unregister the 1-wire bridge(s) */
for (idx = 0; idx < data->w1_count; idx++) {
@ -534,13 +525,6 @@ static int ds2482_detach_client(struct i2c_client *client)
w1_remove_master_device(&data->w1_ch[idx].w1_bm);
}
/* Detach the i2c device */
if ((err = i2c_detach_client(client))) {
dev_err(&client->dev,
"Deregistration failed, client not detached.\n");
return err;
}
/* Free the memory */
kfree(data);
return 0;