All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laurent Pinchart <laurentp@cse-semaphore.com>
To: lm-sensors@vger.kernel.org
Subject: [lm-sensors] lm75: Convert to new-style I2C driver
Date: Wed, 16 Apr 2008 12:34:53 +0000	[thread overview]
Message-ID: <200804161434.54335.laurentp@cse-semaphore.com> (raw)

This patch converts the lm75 driver into a new-style I2C driver.

Signed-off-by: Laurent Pinchart <laurent@pclaurent.belgium.cse-semaphore.com>
---
 drivers/hwmon/lm75.c |  292 +++++++++++++++++++++-----------------------------
 1 files changed, 124 insertions(+), 168 deletions(-)

diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index d7a22a5..7c17611 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -29,14 +29,6 @@
 #include <linux/mutex.h>
 #include "lm75.h"
 
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
-					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(lm75);
-
 /* Many LM75 constants specified below */
 
 /* The LM75 registers */
@@ -49,34 +41,61 @@ static const u8 LM75_REG_TEMP[3] = {
 
 /* Each client has this additional data */
 struct lm75_data {
-	struct i2c_client	client;
-	struct device *hwmon_dev;
-	struct mutex		update_lock;
-	char			valid;		/* !=0 if following fields are valid */
-	unsigned long		last_updated;	/* In jiffies */
-	u16			temp[3];	/* Register values,
-						   0 = input
-						   1 = max
-						   2 = hyst */
+	struct device	*hwmon_dev;
+	struct mutex	update_lock;
+	char		valid;		/* !=0 if following fields are valid */
+	unsigned long	last_updated;	/* In jiffies */
+	u16		temp[3];	/* Register values,
+					   0 = input
+					   1 = max
+					   2 = hyst */
 };
 
-static int lm75_attach_adapter(struct i2c_adapter *adapter);
-static int lm75_detect(struct i2c_adapter *adapter, int address, int kind);
-static void lm75_init_client(struct i2c_client *client);
-static int lm75_detach_client(struct i2c_client *client);
-static int lm75_read_value(struct i2c_client *client, u8 reg);
-static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
-static struct lm75_data *lm75_update_device(struct device *dev);
+/* All registers are word-sized, except for the configuration register.
+   LM75 uses a high-byte first convention, which is exactly opposite to
+   the usual practice. */
+static int lm75_read_value(struct i2c_client *client, u8 reg)
+{
+	if (reg = LM75_REG_CONF)
+		return i2c_smbus_read_byte_data(client, reg);
+	else
+		return swab16(i2c_smbus_read_word_data(client, reg));
+}
 
+/* All registers are word-sized, except for the configuration register.
+   LM75 uses a high-byte first convention, which is exactly opposite to
+   the usual practice. */
+static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if (reg = LM75_REG_CONF)
+		return i2c_smbus_write_byte_data(client, reg, value);
+	else
+		return i2c_smbus_write_word_data(client, reg, swab16(value));
+}
 
-/* This is the driver that will be inserted */
-static struct i2c_driver lm75_driver = {
-	.driver = {
-		.name	= "lm75",
-	},
-	.attach_adapter	= lm75_attach_adapter,
-	.detach_client	= lm75_detach_client,
-};
+static struct lm75_data *lm75_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm75_data *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		int i;
+		dev_dbg(&client->dev, "Starting lm75 update\n");
+
+		for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+			data->temp[i] = lm75_read_value(client,
+							LM75_REG_TEMP[i]);
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
 
 static ssize_t show_temp(struct device *dev, struct device_attribute *da,
 			 char *buf)
@@ -109,13 +128,6 @@ static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
 			show_temp, set_temp, 2);
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
 
-static int lm75_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_probe(adapter, &addr_data, lm75_detect);
-}
-
 static struct attribute *lm75_attributes[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -128,180 +140,124 @@ static const struct attribute_group lm75_group = {
 	.attrs = lm75_attributes,
 };
 
-/* This function is called by i2c_probe */
-static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
+static void lm75_init_client(struct i2c_client *client)
 {
-	int i;
-	struct i2c_client *new_client;
-	struct lm75_data *data;
-	int err = 0;
-	const char *name = "";
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-				     I2C_FUNC_SMBUS_WORD_DATA))
-		goto exit;
+	int reg;
 
-	/* 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 lm75_{read,write}_value. */
-	if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
+	/* Enable if in shutdown mode */
+	reg = lm75_read_value(client, LM75_REG_CONF);
+	if (reg >= 0 && (reg & 0x01))
+		lm75_write_value(client, LM75_REG_CONF, reg & 0xfe);
+}
 
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm75_driver;
-	new_client->flags = 0;
+static int lm75_detect(struct i2c_client *client)
+{
+	int cur, conf, hyst, os, na, i;
 
-	/* Now, we do the remaining detection. There is no identification-
+	/* Try to identify the chip. There is no identification-
 	   dedicated register so we have to rely on several tricks:
 	   unused bits, registers cycling over 8-address boundaries,
-	   addresses 0x04-0x07 returning the last read value (LM75) or
-	   0xffff (Philips LM75A).
+           addresses 0x04-0x07 returning the last read value (LM75) or
+           0xffff (Philips LM75A).
 	   The cycling+unused addresses combination is not tested,
 	   since it would significantly slow the detection down and would
 	   hardly add any value. */
-	if (kind < 0) {
-		int cur, conf, hyst, os, na;
-
-		/* Unused addresses */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		conf = i2c_smbus_read_byte_data(new_client, 1);
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		for (i = 4; i < 8; ++i) {
-			na = i2c_smbus_read_word_data(new_client, i);
-			if (na != hyst && na != 0xffff)
-				goto exit_free;
-		}
-		os = i2c_smbus_read_word_data(new_client, 3);
-		for (i = 4; i < 8; ++i) {
-			na = i2c_smbus_read_word_data(new_client, i);
-			if (na != os && na != 0xffff)
-				goto exit_free;
-		}
-
-		/* Unused bits */
-		if (conf & 0xe0)
-		 	goto exit_free;
-
-		/* Addresses cycling */
-		for (i = 8; i < 0xff; i += 8)
-			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
-			 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
-			 || i2c_smbus_read_word_data(new_client, i + 3) != os)
-				goto exit_free;
+
+	/* Unused addresses */
+	cur = i2c_smbus_read_word_data(client, 0);
+	conf = i2c_smbus_read_byte_data(client, 1);
+	hyst = i2c_smbus_read_word_data(client, 2);
+	for (i = 4; i < 8; ++i) {
+		na = i2c_smbus_read_word_data(client, i);
+		if (na != hyst && na != 0xffff)
+			return -ENODEV;
+	}
+	os = i2c_smbus_read_word_data(client, 3);
+	for (i = 4; i < 8; ++i) {
+		na = i2c_smbus_read_word_data(client, i);
+		if (na != os && na != 0xffff)
+			return -ENODEV;
 	}
 
-	/* Determine the chip type - only one kind supported! */
-	if (kind <= 0)
-		kind = lm75;
+	/* Unused bits */
+	if (conf & 0xe0)
+		return -ENODEV;
 
-	if (kind = lm75) {
-		name = "lm75";
+	/* Addresses cycling */
+	for (i = 8; i < 0xff; i += 8)
+		if (i2c_smbus_read_byte_data(client, i + 1) != conf
+		 || i2c_smbus_read_word_data(client, i + 2) != hyst
+		 || i2c_smbus_read_word_data(client, i + 3) != os)
+			return -ENODEV;
+
+	return 0;
+}
+
+static int lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct lm75_data *data;
+	int err = 0;
+
+	if (!(data = kzalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
+		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);
-	data->valid = 0;
 	mutex_init(&data->update_lock);
+	data->valid = 0;
 
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
+	/* Make sure this is really a LM75 */
+	if ((err = lm75_detect(client)) < 0)
 		goto exit_free;
 
 	/* Initialize the LM75 chip */
-	lm75_init_client(new_client);
+	lm75_init_client(client);
 	
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &lm75_group)))
-		goto exit_detach;
+	if ((err = sysfs_create_group(&client->dev.kobj, &lm75_group)))
+		goto exit_free;
 
-	data->hwmon_dev = hwmon_device_register(&new_client->dev);
+	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (IS_ERR(data->hwmon_dev)) {
 		err = PTR_ERR(data->hwmon_dev);
 		goto exit_remove;
 	}
 
+	i2c_set_clientdata(client, data);
 	return 0;
 
 exit_remove:
-	sysfs_remove_group(&new_client->dev.kobj, &lm75_group);
-exit_detach:
-	i2c_detach_client(new_client);
+	sysfs_remove_group(&client->dev.kobj, &lm75_group);
 exit_free:
 	kfree(data);
 exit:
 	return err;
 }
 
-static int lm75_detach_client(struct i2c_client *client)
+static int lm75_remove(struct i2c_client *client)
 {
 	struct lm75_data *data = i2c_get_clientdata(client);
 	hwmon_device_unregister(data->hwmon_dev);
 	sysfs_remove_group(&client->dev.kobj, &lm75_group);
-	i2c_detach_client(client);
 	kfree(data);
 	return 0;
 }
 
-/* All registers are word-sized, except for the configuration register.
-   LM75 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
-static int lm75_read_value(struct i2c_client *client, u8 reg)
-{
-	if (reg = LM75_REG_CONF)
-		return i2c_smbus_read_byte_data(client, reg);
-	else
-		return swab16(i2c_smbus_read_word_data(client, reg));
-}
-
-/* All registers are word-sized, except for the configuration register.
-   LM75 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
-static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if (reg = LM75_REG_CONF)
-		return i2c_smbus_write_byte_data(client, reg, value);
-	else
-		return i2c_smbus_write_word_data(client, reg, swab16(value));
-}
-
-static void lm75_init_client(struct i2c_client *client)
-{
-	int reg;
-
-	/* Enable if in shutdown mode */
-	reg = lm75_read_value(client, LM75_REG_CONF);
-	if (reg >= 0 && (reg & 0x01))
-		lm75_write_value(client, LM75_REG_CONF, reg & 0xfe);
-}
-
-static struct lm75_data *lm75_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm75_data *data = i2c_get_clientdata(client);
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		int i;
-		dev_dbg(&client->dev, "Starting lm75 update\n");
-
-		for (i = 0; i < ARRAY_SIZE(data->temp); i++)
-			data->temp[i] = lm75_read_value(client,
-							LM75_REG_TEMP[i]);
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	mutex_unlock(&data->update_lock);
+static struct i2c_device_id lm75_id[] = {
+	{ "lm75", 0 },
+	{ "lm75a", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, lm75_id);
 
-	return data;
-}
+static struct i2c_driver lm75_driver = {
+	.driver = {
+		.name	= "lm75",
+	},
+	.probe = lm75_probe,
+	.remove = lm75_remove,
+	.id_table = lm75_id,
+};
 
 static int __init sensors_lm75_init(void)
 {
-- 
1.5.0


-- 
Laurent Pinchart
CSE Semaphore Belgium

Chaussee de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
F +32 (2) 387 42 75

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

             reply	other threads:[~2008-04-16 12:34 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-16 12:34 Laurent Pinchart [this message]
2008-04-16 13:30 ` [lm-sensors] lm75: Convert to new-style I2C driver Jean Delvare
2008-04-16 13:49 ` Laurent Pinchart
2008-04-16 14:04 ` Jean Delvare
2008-04-16 17:27 ` David Brownell
     [not found]   ` <200804161027.49943.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-05-02 11:10     ` [patch 2.6.25-git] i2c: smbalert# support David Brownell
     [not found]       ` <200805020410.44723.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-05-05  5:56         ` [patch 2.6.265-rc1] " David Brownell
     [not found]           ` <200805042256.49252.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-09-23 22:32             ` [patch 2.6.27-rc7] " David Brownell
2008-09-23 22:32               ` [lm-sensors] " David Brownell
     [not found]               ` <200809231532.40083.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-09-26  1:07                 ` Trent Piepho
2008-09-26  1:07                   ` Trent Piepho
     [not found]                   ` <Pine.LNX.4.64.0809251728130.7680-3bmvVOk6DZ+DGx/iekXGtrjh7zpefjiS@public.gmane.org>
2008-09-26  2:01                     ` David Brownell
2008-09-26  2:01                       ` David Brownell
     [not found]                       ` <200809251902.00201.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-09-27  0:29                         ` Trent Piepho
2008-09-27  0:29                           ` Trent Piepho
     [not found]                           ` <Pine.LNX.4.64.0809261652040.7680-3bmvVOk6DZ+DGx/iekXGtrjh7zpefjiS@public.gmane.org>
2008-10-17 19:04                             ` David Brownell
2008-10-17 19:04                               ` David Brownell
     [not found]                               ` <200810171204.54448.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-10-17 20:43                                 ` Trent Piepho
2008-10-17 20:43                                   ` [lm-sensors] [i2c] " Trent Piepho
2008-11-18  8:15                 ` Jean Delvare
2008-11-18  8:15                   ` [lm-sensors] " Jean Delvare
     [not found]                   ` <20081118091546.421d6b78-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-11-18 22:01                     ` David Brownell
2008-11-18 22:01                       ` [lm-sensors] " David Brownell
     [not found]                       ` <200811181401.34809.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-11-19  9:51                         ` Trent Piepho
2008-11-19  9:51                           ` Trent Piepho
     [not found]                           ` <Pine.LNX.4.64.0811190140510.11673-3bmvVOk6DZ+DGx/iekXGtrjh7zpefjiS@public.gmane.org>
2008-11-19 15:16                             ` Jean Delvare
2008-11-19 15:16                               ` Jean Delvare
     [not found]                               ` <20081119161632.2d0bde9e-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-11-20 22:00                                 ` Trent Piepho
2008-11-20 22:00                                   ` Trent Piepho
     [not found]                                   ` <Pine.LNX.4.64.0811201354310.11673-3bmvVOk6DZ+DGx/iekXGtrjh7zpefjiS@public.gmane.org>
2008-11-20 22:56                                     ` David Brownell
2008-11-20 22:56                                       ` David Brownell
     [not found]                                       ` <200811201456.36551.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-11-22  0:55                                         ` Trent Piepho
2008-11-22  0:55                                           ` Trent Piepho
     [not found]                                           ` <Pine.LNX.4.64.0811211621340.18022-3bmvVOk6DZ+DGx/iekXGtrjh7zpefjiS@public.gmane.org>
2008-11-22  2:58                                             ` David Brownell
2008-11-22  2:58                                               ` David Brownell
2008-11-21  8:42                                     ` Jean Delvare
2008-11-21  8:42                                       ` [lm-sensors] " Jean Delvare
     [not found]                                       ` <20081121094218.34ecd82a-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-11-22  6:04                                         ` Trent Piepho
2008-11-22  6:04                                           ` [lm-sensors] " Trent Piepho
     [not found]                                           ` <Pine.LNX.4.64.0811212122370.18022-3bmvVOk6DZ+DGx/iekXGtrjh7zpefjiS@public.gmane.org>
2008-11-22 10:13                                             ` Jean Delvare
2008-11-22 10:13                                               ` [lm-sensors] " Jean Delvare
     [not found]                                               ` <20081122111340.0bfc2c05-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-11-22 20:28                                                 ` Trent Piepho
2008-11-22 20:28                                                   ` [lm-sensors] " Trent Piepho
     [not found]                                                   ` <Pine.LNX.4.64.0811221055470.18022-3bmvVOk6DZ+DGx/iekXGtrjh7zpefjiS@public.gmane.org>
2008-11-23 21:45                                                     ` Jean Delvare
2008-11-23 21:45                                                       ` [lm-sensors] " Jean Delvare
2008-11-19 13:57                         ` Jean Delvare
     [not found]                           ` <20081119145712.1abaa63f-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-11-19 18:08                             ` David Brownell
2008-11-21 14:18                         ` Jean Delvare
     [not found]                           ` <20081121151808.324ca78c-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-11-21 16:24                             ` David Brownell
     [not found]                               ` <200811210824.55601.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-11-21 19:22                                 ` Jean Delvare
     [not found]                                   ` <20081121202223.0261fb9c-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-11-21 21:54                                     ` David Brownell
     [not found]                                       ` <200811211354.51501.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2008-11-22  9:03                                         ` Jean Delvare
     [not found]                                           ` <20081122100344.61cf42b7-ig7AzVSIIG7kN2dkZ6Wm7A@public.gmane.org>
2008-11-22  9:48                                             ` David Brownell
2008-04-16 17:52 ` [lm-sensors] lm75: Convert to new-style I2C driver David Brownell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200804161434.54335.laurentp@cse-semaphore.com \
    --to=laurentp@cse-semaphore.com \
    --cc=lm-sensors@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.