Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a3cf8593 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
  ...
parents 3c3622dc 33468e76
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+9 −1
Original line number Diff line number Diff line
@@ -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
-------------

+5 −7
Original line number Diff line number Diff line
@@ -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):
+3 −6
Original line number Diff line number Diff line
@@ -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
--------------
+26 −83
Original line number Diff line number Diff line
@@ -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;
}
Loading