w83781d i2c driver updated for 2.5.66 (without sysfs support)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Mar 26, 2003 at 08:40:58PM +0100, Jan Dittmer wrote:
> Martin Schlemmer wrote:
> >
> >I did look at the changes needed for sysfs, but this beast have
> >about 6 ctl_tables, and is hairy in general.  I am not sure what
> >is the best way to do it for the different chips, so here is what
> >I have until I or somebody else can do the sysfs stuff.
> >
> I've just done this with the via686a driver. Saves about 100 lines of code.
> 
> Comments?

<snip>

> +/* following are the sysfs callback functions */
> +static ssize_t show_in(struct device *dev, char *buf, int nr) {
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct via686a_data *data = i2c_get_clientdata(client);
> +	via686a_update_client(client);
> +
> +	return sprintf(buf,"%ld %ld %ld\n",
> +		IN_FROM_REG(data->in_min[nr], nr),
> +		IN_FROM_REG(data->in_max[nr], nr),
> +		IN_FROM_REG(data->in[nr], nr) );
> +}

We should really split these multivalue files up into individual files,
as sysfs is for single value files.  Makes parsing easier too.

Here's a patch for the lm75.c driver that does this.  As we are going to
need a "generic" read and write for the "real" values that the i2c
drivers use, I added these files to the i2c-proc.c file.

Yes, i2c_read_real() doesn't really work just yet :)

Anyway, I think this is the direction we should be moving to.  And what
is "temp_os" and "temp_hyst"?  Should these files be named something a
bit more descriptive?

thanks,

greg k-h

diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
--- a/drivers/i2c/chips/lm75.c	Wed Mar 26 12:28:45 2003
+++ b/drivers/i2c/chips/lm75.c	Wed Mar 26 12:28:45 2003
@@ -102,6 +102,49 @@
 
 static int lm75_id = 0;
 
+#define show(value)	\
+static ssize_t show_##value(struct device *dev, char *buf)	\
+{								\
+	struct i2c_client *client = to_i2c_client(dev);		\
+	struct lm75_data *data = i2c_get_clientdata(client);	\
+	int temp;						\
+								\
+	lm75_update_client(client);				\
+	temp = TEMP_FROM_REG(data->value);			\
+	return i2c_write_real(buf, temp, 1);			\
+}
+show(temp);
+show(temp_os);
+show(temp_hyst);
+
+static ssize_t set_temp_os(struct device *dev, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm75_data *data = i2c_get_clientdata(client);
+	int temp;
+
+	i2c_read_real(buf, &temp, 1);
+	data->temp_os = TEMP_TO_REG(temp);
+	lm75_write_value(client, LM75_REG_TEMP_OS, data->temp_os);
+	return count;
+}
+
+static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm75_data *data = i2c_get_clientdata(client);
+	int temp;
+
+	i2c_read_real(buf, &temp, 1);
+	data->temp_hyst = TEMP_TO_REG(temp);
+	lm75_write_value(client, LM75_REG_TEMP_HYST, data->temp_hyst);
+	return count;
+}
+
+static DEVICE_ATTR(temp, S_IRUGO, show_temp, NULL);
+static DEVICE_ATTR(temp_os, 0644, show_temp_os, set_temp_os);
+static DEVICE_ATTR(temp_hyst, 0644, show_temp_hyst, set_temp_hyst);
+
 static int lm75_attach_adapter(struct i2c_adapter *adapter)
 {
 	return i2c_detect(adapter, &addr_data, lm75_detect);
@@ -192,6 +235,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto error3;
 
+	device_create_file(&new_client->dev, &dev_attr_temp);
+	device_create_file(&new_client->dev, &dev_attr_temp_os);
+	device_create_file(&new_client->dev, &dev_attr_temp_hyst);
+
 	/* Register a new directory entry with module sensors */
 	i = i2c_register_entry(new_client, type_name, lm75_dir_table_template);
 	if (i < 0) {
diff -Nru a/drivers/i2c/i2c-proc.c b/drivers/i2c/i2c-proc.c
--- a/drivers/i2c/i2c-proc.c	Wed Mar 26 12:28:45 2003
+++ b/drivers/i2c/i2c-proc.c	Wed Mar 26 12:28:45 2003
@@ -381,6 +381,14 @@
 	return ret;
 }
 
+int i2c_read_real(const char *buf, int *real, int magnitude)
+{
+	char *temp;
+
+	*real = simple_strtoul(buf, &temp, 10);
+
+	return 0;
+}
 
 /* nrels contains initially the maximum number of elements which can be
    put in results, and finally the number of elements actually put there.
@@ -499,6 +507,29 @@
 	return 0;
 }
 
+int i2c_write_real(char *buf, int real, int magnitude)
+{
+	char printfstr[12];
+	int mag;
+	int times;
+	int field_location;
+
+	mag = magnitude;
+	for (times = 1; mag-- > 0; times *= 10)
+		;
+
+	if (real < 0) {
+		strcpy(printfstr, "-%ld.%0Xld");
+		field_location = 7;
+	} else {
+		strcpy(printfstr, "%ld.%0Xld");
+		field_location = 6;
+	}
+	printfstr[field_location] = magnitude + '0';
+	real = abs(real);
+	return sprintf(buf, printfstr, real / times, real % times);
+}
+
 static int i2c_write_reals(int nrels, void *buffer, size_t *bufsize,
 			 long *results, int magnitude)
 {
@@ -724,6 +755,8 @@
 EXPORT_SYMBOL(i2c_proc_real);
 EXPORT_SYMBOL(i2c_sysctl_real);
 EXPORT_SYMBOL(i2c_detect);
+EXPORT_SYMBOL(i2c_write_real);
+EXPORT_SYMBOL(i2c_read_real);
 
 MODULE_AUTHOR("Frodo Looijaard <frodol at dds.nl>");
 MODULE_DESCRIPTION("i2c-proc driver");
diff -Nru a/include/linux/i2c-proc.h b/include/linux/i2c-proc.h
--- a/include/linux/i2c-proc.h	Wed Mar 26 12:28:45 2003
+++ b/include/linux/i2c-proc.h	Wed Mar 26 12:28:45 2003
@@ -410,5 +410,8 @@
 	char name[SENSORS_PREFIX_MAX + 13];
 };
 
+extern int i2c_write_real(char *buf, int real, int magnitude);
+extern int i2c_read_real(const char *buf, int *real, int magnitude);
+
 #endif				/* def _LINUX_I2C_PROC_H */
 



[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux