diff options
Diffstat (limited to 'drivers/hwmon/pcf8591.c')
| -rw-r--r-- | drivers/hwmon/pcf8591.c | 157 | 
1 files changed, 92 insertions, 65 deletions
diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c index dc7259d6981..5740888c624 100644 --- a/drivers/hwmon/pcf8591.c +++ b/drivers/hwmon/pcf8591.c @@ -1,22 +1,24 @@  /* -    Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net> -    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with -    the help of Jean Delvare <khali@linux-fr.org> - -    This program is free software; you can redistribute it and/or modify -    it under the terms of the GNU General Public License as published by -    the Free Software Foundation; either version 2 of the License, or -    (at your option) any later version. - -    This program is distributed in the hope that it will be useful, -    but WITHOUT ANY WARRANTY; without even the implied warranty of -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -    GNU General Public License for more details. + * Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net> + * Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with + * the help of Jean Delvare <jdelvare@suse.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ -    You should have received a copy of the GNU General Public License -    along with this program; if not, write to the Free Software -    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt  #include <linux/module.h>  #include <linux/init.h> @@ -37,28 +39,34 @@ MODULE_PARM_DESC(input_mode,  	" 2 = single ended and differential mixed\n"  	" 3 = two differential inputs\n"); -/* The PCF8591 control byte -      7    6    5    4    3    2    1    0 -   |  0 |AOEF|   AIP   |  0 |AINC|  AICH   | */ +/* + * The PCF8591 control byte + *      7    6    5    4    3    2    1    0 + *   |  0 |AOEF|   AIP   |  0 |AINC|  AICH   | + */  /* Analog Output Enable Flag (analog output active if 1) */  #define PCF8591_CONTROL_AOEF		0x40 -/* Analog Input Programming -   0x00 = four single ended inputs -   0x10 = three differential inputs -   0x20 = single ended and differential mixed -   0x30 = two differential inputs */ +/* + * Analog Input Programming + * 0x00 = four single ended inputs + * 0x10 = three differential inputs + * 0x20 = single ended and differential mixed + * 0x30 = two differential inputs + */  #define PCF8591_CONTROL_AIP_MASK	0x30  /* Autoincrement Flag (switch on if 1) */  #define PCF8591_CONTROL_AINC		0x04 -/* Channel selection -   0x00 = channel 0 -   0x01 = channel 1 -   0x02 = channel 2 -   0x03 = channel 3 */ +/* + * Channel selection + * 0x00 = channel 0 + * 0x01 = channel 1 + * 0x02 = channel 2 + * 0x03 = channel 3 + */  #define PCF8591_CONTROL_AICH_MASK	0x03  /* Initial values */ @@ -66,7 +74,7 @@ MODULE_PARM_DESC(input_mode,  #define PCF8591_INIT_AOUT	0	/* DAC out = 0 */  /* Conversions */ -#define REG_TO_SIGNED(reg)	(((reg) & 0x80)?((reg) - 256):(reg)) +#define REG_TO_SIGNED(reg)	(((reg) & 0x80) ? ((reg) - 256) : (reg))  struct pcf8591_data {  	struct device *hwmon_dev; @@ -81,7 +89,9 @@ static int pcf8591_read_channel(struct device *dev, int channel);  /* 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)	\ +static ssize_t show_in##channel##_input(struct device *dev,		\ +					struct device_attribute *attr,	\ +					char *buf)			\  {									\  	return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\  }									\ @@ -93,39 +103,57 @@ show_in_channel(1);  show_in_channel(2);  show_in_channel(3); -static ssize_t show_out0_ouput(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_out0_ouput(struct device *dev, +			       struct device_attribute *attr, char *buf)  {  	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));  	return sprintf(buf, "%d\n", data->aout * 10);  } -static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_out0_output(struct device *dev, +			       struct device_attribute *attr, +			       const char *buf, size_t count)  { -	unsigned int value; +	unsigned long val;  	struct i2c_client *client = to_i2c_client(dev);  	struct pcf8591_data *data = i2c_get_clientdata(client); -	if ((value = (simple_strtoul(buf, NULL, 10) + 5) / 10) <= 255) { -		data->aout = value; -		i2c_smbus_write_byte_data(client, data->control, data->aout); -		return count; -	} -	return -EINVAL; +	int err; + +	err = kstrtoul(buf, 10, &val); +	if (err) +		return err; + +	val /= 10; +	if (val > 255) +		return -EINVAL; + +	data->aout = val; +	i2c_smbus_write_byte_data(client, data->control, data->aout); +	return count;  }  static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,  		   show_out0_ouput, set_out0_output); -static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_out0_enable(struct device *dev, +				struct device_attribute *attr, char *buf)  {  	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));  	return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF)));  } -static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +static ssize_t set_out0_enable(struct device *dev, +			       struct device_attribute *attr, +			       const char *buf, size_t count)  {  	struct i2c_client *client = to_i2c_client(dev);  	struct pcf8591_data *data = i2c_get_clientdata(client); -	unsigned long val = simple_strtoul(buf, NULL, 10); +	unsigned long val; +	int err; + +	err = kstrtoul(buf, 10, &val); +	if (err) +		return err;  	mutex_lock(&data->update_lock);  	if (val) @@ -172,10 +200,10 @@ static int pcf8591_probe(struct i2c_client *client,  	struct pcf8591_data *data;  	int err; -	if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) { -		err = -ENOMEM; -		goto exit; -	} +	data = devm_kzalloc(&client->dev, sizeof(struct pcf8591_data), +			    GFP_KERNEL); +	if (!data) +		return -ENOMEM;  	i2c_set_clientdata(client, data);  	mutex_init(&data->update_lock); @@ -186,19 +214,19 @@ static int pcf8591_probe(struct i2c_client *client,  	/* Register sysfs hooks */  	err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group);  	if (err) -		goto exit_kfree; +		return err;  	/* Register input2 if not in "two differential inputs" mode */  	if (input_mode != 3) { -		if ((err = device_create_file(&client->dev, -					      &dev_attr_in2_input))) +		err = device_create_file(&client->dev, &dev_attr_in2_input); +		if (err)  			goto exit_sysfs_remove;  	}  	/* Register input3 only in "four single ended inputs" mode */  	if (input_mode == 0) { -		if ((err = device_create_file(&client->dev, -					      &dev_attr_in3_input))) +		err = device_create_file(&client->dev, &dev_attr_in3_input); +		if (err)  			goto exit_sysfs_remove;  	} @@ -213,9 +241,6 @@ static int pcf8591_probe(struct i2c_client *client,  exit_sysfs_remove:  	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);  	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); -exit_kfree: -	kfree(data); -exit:  	return err;  } @@ -226,7 +251,6 @@ static int pcf8591_remove(struct i2c_client *client)  	hwmon_device_unregister(data->hwmon_dev);  	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);  	sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group); -	kfree(i2c_get_clientdata(client));  	return 0;  } @@ -239,8 +263,10 @@ static void pcf8591_init_client(struct i2c_client *client)  	i2c_smbus_write_byte_data(client, data->control, data->aout); -	/* The first byte transmitted contains the conversion code of the -	   previous read cycle. FLUSH IT! */ +	/* +	 * The first byte transmitted contains the conversion code of the +	 * previous read cycle. FLUSH IT! +	 */  	i2c_smbus_read_byte(client);  } @@ -257,8 +283,10 @@ static int pcf8591_read_channel(struct device *dev, int channel)  			      | channel;  		i2c_smbus_write_byte(client, data->control); -		/* The first byte transmitted contains the conversion code of -		   the previous read cycle. FLUSH IT! */ +		/* +		 * The first byte transmitted contains the conversion code of +		 * the previous read cycle. FLUSH IT! +		 */  		i2c_smbus_read_byte(client);  	}  	value = i2c_smbus_read_byte(client); @@ -267,9 +295,9 @@ static int pcf8591_read_channel(struct device *dev, int channel)  	if ((channel == 2 && input_mode == 2) ||  	    (channel != 3 && (input_mode == 1 || input_mode == 3))) -		return (10 * REG_TO_SIGNED(value)); +		return 10 * REG_TO_SIGNED(value);  	else -		return (10 * value); +		return 10 * value;  }  static const struct i2c_device_id pcf8591_id[] = { @@ -290,8 +318,7 @@ static struct i2c_driver pcf8591_driver = {  static int __init pcf8591_init(void)  {  	if (input_mode < 0 || input_mode > 3) { -		printk(KERN_WARNING "pcf8591: invalid input_mode (%d)\n", -		       input_mode); +		pr_warn("invalid input_mode (%d)\n", input_mode);  		input_mode = 0;  	}  	return i2c_add_driver(&pcf8591_driver);  | 
