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

Commit 28e6274d authored by Axel Lin's avatar Axel Lin Committed by Guenter Roeck
Browse files

hwmon: (amc6821) Avoid forward declaration



Reorder functions to avoid forward declaration.

Signed-off-by: default avatarAxel Lin <axel.lin@ingics.com>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent 4fd5233f
Loading
Loading
Loading
Loading
+154 −206
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#include <linux/kernel.h>	/* Needed for KERN_INFO */
#include <linux/module.h>
#include <linux/init.h>
@@ -33,7 +32,6 @@
#include <linux/err.h>
#include <linux/mutex.h>


/*
 * Addresses to scan.
 */
@@ -41,8 +39,6 @@
static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
	0x4c, 0x4d, 0x4e, I2C_CLIENT_END};



/*
 * Insmod parameters
 */
@@ -53,7 +49,6 @@ module_param(pwminv, int, S_IRUGO);
static int init = 1; /*Power-on initialization.*/
module_param(init, int, S_IRUGO);


enum chips { amc6821 };

#define AMC6821_REG_DEV_ID 0x3D
@@ -152,40 +147,6 @@ static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI,
			AMC6821_REG_TACH_LLIMITH,
			AMC6821_REG_TACH_HLIMITH, };

static int amc6821_probe(
		struct i2c_client *client,
		const struct i2c_device_id *id);
static int amc6821_detect(
		struct i2c_client *client,
		struct i2c_board_info *info);
static int amc6821_init_client(struct i2c_client *client);
static int amc6821_remove(struct i2c_client *client);
static struct amc6821_data *amc6821_update_device(struct device *dev);

/*
 * Driver data (common to all clients)
 */

static const struct i2c_device_id amc6821_id[] = {
	{ "amc6821", amc6821 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, amc6821_id);

static struct i2c_driver amc6821_driver = {
	.class = I2C_CLASS_HWMON,
	.driver = {
		.name	= "amc6821",
	},
	.probe = amc6821_probe,
	.remove = amc6821_remove,
	.id_table = amc6821_id,
	.detect = amc6821_detect,
	.address_list = normal_i2c,
};


/*
 * Client data (each client gets its own)
 */
@@ -213,6 +174,108 @@ struct amc6821_data {
	u8 stat2;
};

static struct amc6821_data *amc6821_update_device(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct amc6821_data *data = i2c_get_clientdata(client);
	int timeout = HZ;
	u8 reg;
	int i;

	mutex_lock(&data->update_lock);

	if (time_after(jiffies, data->last_updated + timeout) ||
			!data->valid) {

		for (i = 0; i < TEMP_IDX_LEN; i++)
			data->temp[i] = i2c_smbus_read_byte_data(client,
				temp_reg[i]);

		data->stat1 = i2c_smbus_read_byte_data(client,
			AMC6821_REG_STAT1);
		data->stat2 = i2c_smbus_read_byte_data(client,
			AMC6821_REG_STAT2);

		data->pwm1 = i2c_smbus_read_byte_data(client,
			AMC6821_REG_DCY);
		for (i = 0; i < FAN1_IDX_LEN; i++) {
			data->fan[i] = i2c_smbus_read_byte_data(
					client,
					fan_reg_low[i]);
			data->fan[i] += i2c_smbus_read_byte_data(
					client,
					fan_reg_hi[i]) << 8;
		}
		data->fan1_div = i2c_smbus_read_byte_data(client,
			AMC6821_REG_CONF4);
		data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;

		data->pwm1_auto_point_pwm[0] = 0;
		data->pwm1_auto_point_pwm[2] = 255;
		data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
			AMC6821_REG_DCY_LOW_TEMP);

		data->temp1_auto_point_temp[0] =
			i2c_smbus_read_byte_data(client,
					AMC6821_REG_PSV_TEMP);
		data->temp2_auto_point_temp[0] =
				data->temp1_auto_point_temp[0];
		reg = i2c_smbus_read_byte_data(client,
			AMC6821_REG_LTEMP_FAN_CTRL);
		data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
		reg &= 0x07;
		reg = 0x20 >> reg;
		if (reg > 0)
			data->temp1_auto_point_temp[2] =
				data->temp1_auto_point_temp[1] +
				(data->pwm1_auto_point_pwm[2] -
				data->pwm1_auto_point_pwm[1]) / reg;
		else
			data->temp1_auto_point_temp[2] = 255;

		reg = i2c_smbus_read_byte_data(client,
			AMC6821_REG_RTEMP_FAN_CTRL);
		data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
		reg &= 0x07;
		reg = 0x20 >> reg;
		if (reg > 0)
			data->temp2_auto_point_temp[2] =
				data->temp2_auto_point_temp[1] +
				(data->pwm1_auto_point_pwm[2] -
				data->pwm1_auto_point_pwm[1]) / reg;
		else
			data->temp2_auto_point_temp[2] = 255;

		reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
		reg = (reg >> 5) & 0x3;
		switch (reg) {
		case 0: /*open loop: software sets pwm1*/
			data->pwm1_auto_channels_temp = 0;
			data->pwm1_enable = 1;
			break;
		case 2: /*closed loop: remote T (temp2)*/
			data->pwm1_auto_channels_temp = 2;
			data->pwm1_enable = 2;
			break;
		case 3: /*closed loop: local and remote T (temp2)*/
			data->pwm1_auto_channels_temp = 3;
			data->pwm1_enable = 3;
			break;
		case 1: /*
			 * semi-open loop: software sets rpm, chip controls
			 * pwm1, currently not implemented
			 */
			data->pwm1_auto_channels_temp = 0;
			data->pwm1_enable = 0;
			break;
		}

		data->last_updated = jiffies;
		data->valid = 1;
	}
	mutex_unlock(&data->update_lock);
	return data;
}

static ssize_t get_temp(
		struct device *dev,
@@ -225,8 +288,6 @@ static ssize_t get_temp(
	return sprintf(buf, "%d\n", data->temp[ix] * 1000);
}



static ssize_t set_temp(
		struct device *dev,
		struct device_attribute *attr,
@@ -253,9 +314,6 @@ static ssize_t set_temp(
	return count;
}




static ssize_t get_temp_alarm(
	struct device *dev,
	struct device_attribute *devattr,
@@ -294,9 +352,6 @@ static ssize_t get_temp_alarm(
		return sprintf(buf, "0");
}




static ssize_t get_temp2_fault(
		struct device *dev,
		struct device_attribute *devattr,
@@ -396,7 +451,6 @@ static ssize_t set_pwm1_enable(
	return count;
}


static ssize_t get_pwm1_auto_channels_temp(
		struct device *dev,
		struct device_attribute *devattr,
@@ -406,7 +460,6 @@ static ssize_t get_pwm1_auto_channels_temp(
	return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp);
}


static ssize_t get_temp_auto_point_temp(
		struct device *dev,
		struct device_attribute *devattr,
@@ -428,7 +481,6 @@ static ssize_t get_temp_auto_point_temp(
	}
}


static ssize_t get_pwm1_auto_point_pwm(
		struct device *dev,
		struct device_attribute *devattr,
@@ -439,7 +491,6 @@ static ssize_t get_pwm1_auto_point_pwm(
	return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]);
}


static inline ssize_t set_slope_register(struct i2c_client *client,
		u8 reg,
		u8 dpwm,
@@ -462,8 +513,6 @@ static inline ssize_t set_slope_register(struct i2c_client *client,
	return 0;
}



static ssize_t set_temp_auto_point_temp(
		struct device *dev,
		struct device_attribute *attr,
@@ -537,8 +586,6 @@ static ssize_t set_temp_auto_point_temp(
	return count;
}



static ssize_t set_pwm1_auto_point_pwm(
		struct device *dev,
		struct device_attribute *attr,
@@ -591,8 +638,6 @@ static ssize_t get_fan(
	return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix]));
}



static ssize_t get_fan1_fault(
		struct device *dev,
		struct device_attribute *devattr,
@@ -605,8 +650,6 @@ static ssize_t get_fan1_fault(
		return sprintf(buf, "0");
}



static ssize_t set_fan(
		struct device *dev,
		struct device_attribute *attr,
@@ -639,8 +682,6 @@ static ssize_t set_fan(
	return count;
}



static ssize_t get_fan1_div(
		struct device *dev,
		struct device_attribute *devattr,
@@ -693,8 +734,6 @@ static ssize_t set_fan1_div(
	return count;
}



static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
	get_temp, NULL, IDX_TEMP1_INPUT);
static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp,
@@ -759,8 +798,6 @@ static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO,
	get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2);



static struct attribute *amc6821_attrs[] = {
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	&sensor_dev_attr_temp1_min.dev_attr.attr,
@@ -801,8 +838,6 @@ static struct attribute_group amc6821_attr_grp = {
	.attrs = amc6821_attrs,
};



/* Return 0 if detection is successful, -ENODEV otherwise */
static int amc6821_detect(
		struct i2c_client *client,
@@ -849,53 +884,6 @@ static int amc6821_detect(
	return 0;
}

static int amc6821_probe(
	struct i2c_client *client,
	const struct i2c_device_id *id)
{
	struct amc6821_data *data;
	int err;

	data = devm_kzalloc(&client->dev, sizeof(struct amc6821_data),
			    GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	i2c_set_clientdata(client, data);
	mutex_init(&data->update_lock);

	/*
	 * Initialize the amc6821 chip
	 */
	err = amc6821_init_client(client);
	if (err)
		return err;

	err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp);
	if (err)
		return err;

	data->hwmon_dev = hwmon_device_register(&client->dev);
	if (!IS_ERR(data->hwmon_dev))
		return 0;

	err = PTR_ERR(data->hwmon_dev);
	dev_err(&client->dev, "error registering hwmon device.\n");
	sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
	return err;
}

static int amc6821_remove(struct i2c_client *client)
{
	struct amc6821_data *data = i2c_get_clientdata(client);

	hwmon_device_unregister(data->hwmon_dev);
	sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);

	return 0;
}


static int amc6821_init_client(struct i2c_client *client)
{
	int config;
@@ -982,109 +970,69 @@ static int amc6821_init_client(struct i2c_client *client)
	return 0;
}


static struct amc6821_data *amc6821_update_device(struct device *dev)
static int amc6821_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct amc6821_data *data = i2c_get_clientdata(client);
	int timeout = HZ;
	u8 reg;
	int i;
	struct amc6821_data *data;
	int err;

	mutex_lock(&data->update_lock);
	data = devm_kzalloc(&client->dev, sizeof(struct amc6821_data),
			    GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	if (time_after(jiffies, data->last_updated + timeout) ||
			!data->valid) {
	i2c_set_clientdata(client, data);
	mutex_init(&data->update_lock);

		for (i = 0; i < TEMP_IDX_LEN; i++)
			data->temp[i] = i2c_smbus_read_byte_data(client,
				temp_reg[i]);
	/*
	 * Initialize the amc6821 chip
	 */
	err = amc6821_init_client(client);
	if (err)
		return err;

		data->stat1 = i2c_smbus_read_byte_data(client,
			AMC6821_REG_STAT1);
		data->stat2 = i2c_smbus_read_byte_data(client,
			AMC6821_REG_STAT2);
	err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp);
	if (err)
		return err;

		data->pwm1 = i2c_smbus_read_byte_data(client,
			AMC6821_REG_DCY);
		for (i = 0; i < FAN1_IDX_LEN; i++) {
			data->fan[i] = i2c_smbus_read_byte_data(
					client,
					fan_reg_low[i]);
			data->fan[i] += i2c_smbus_read_byte_data(
					client,
					fan_reg_hi[i]) << 8;
		}
		data->fan1_div = i2c_smbus_read_byte_data(client,
			AMC6821_REG_CONF4);
		data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
	data->hwmon_dev = hwmon_device_register(&client->dev);
	if (!IS_ERR(data->hwmon_dev))
		return 0;

		data->pwm1_auto_point_pwm[0] = 0;
		data->pwm1_auto_point_pwm[2] = 255;
		data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
			AMC6821_REG_DCY_LOW_TEMP);
	err = PTR_ERR(data->hwmon_dev);
	dev_err(&client->dev, "error registering hwmon device.\n");
	sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
	return err;
}

		data->temp1_auto_point_temp[0] =
			i2c_smbus_read_byte_data(client,
					AMC6821_REG_PSV_TEMP);
		data->temp2_auto_point_temp[0] =
				data->temp1_auto_point_temp[0];
		reg = i2c_smbus_read_byte_data(client,
			AMC6821_REG_LTEMP_FAN_CTRL);
		data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
		reg &= 0x07;
		reg = 0x20 >> reg;
		if (reg > 0)
			data->temp1_auto_point_temp[2] =
				data->temp1_auto_point_temp[1] +
				(data->pwm1_auto_point_pwm[2] -
				data->pwm1_auto_point_pwm[1]) / reg;
		else
			data->temp1_auto_point_temp[2] = 255;
static int amc6821_remove(struct i2c_client *client)
{
	struct amc6821_data *data = i2c_get_clientdata(client);

		reg = i2c_smbus_read_byte_data(client,
			AMC6821_REG_RTEMP_FAN_CTRL);
		data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
		reg &= 0x07;
		reg = 0x20 >> reg;
		if (reg > 0)
			data->temp2_auto_point_temp[2] =
				data->temp2_auto_point_temp[1] +
				(data->pwm1_auto_point_pwm[2] -
				data->pwm1_auto_point_pwm[1]) / reg;
		else
			data->temp2_auto_point_temp[2] = 255;
	hwmon_device_unregister(data->hwmon_dev);
	sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);

		reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
		reg = (reg >> 5) & 0x3;
		switch (reg) {
		case 0: /*open loop: software sets pwm1*/
			data->pwm1_auto_channels_temp = 0;
			data->pwm1_enable = 1;
			break;
		case 2: /*closed loop: remote T (temp2)*/
			data->pwm1_auto_channels_temp = 2;
			data->pwm1_enable = 2;
			break;
		case 3: /*closed loop: local and remote T (temp2)*/
			data->pwm1_auto_channels_temp = 3;
			data->pwm1_enable = 3;
			break;
		case 1: /*
			 * semi-open loop: software sets rpm, chip controls
			 * pwm1, currently not implemented
			 */
			data->pwm1_auto_channels_temp = 0;
			data->pwm1_enable = 0;
			break;
	return 0;
}

		data->last_updated = jiffies;
		data->valid = 1;
	}
	mutex_unlock(&data->update_lock);
	return data;
}
static const struct i2c_device_id amc6821_id[] = {
	{ "amc6821", amc6821 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, amc6821_id);

static struct i2c_driver amc6821_driver = {
	.class = I2C_CLASS_HWMON,
	.driver = {
		.name	= "amc6821",
	},
	.probe = amc6821_probe,
	.remove = amc6821_remove,
	.id_table = amc6821_id,
	.detect = amc6821_detect,
	.address_list = normal_i2c,
};

module_i2c_driver(amc6821_driver);