Commit 4341fc3f authored by Axel Lin's avatar Axel Lin Committed by Guenter Roeck

hwmon: (adm9240) 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 b060f3c4
......@@ -130,35 +130,6 @@ static inline unsigned int AOUT_FROM_REG(u8 reg)
return SCALE(reg, 1250, 255);
}
static int adm9240_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm9240_detect(struct i2c_client *client,
struct i2c_board_info *info);
static void adm9240_init_client(struct i2c_client *client);
static int adm9240_remove(struct i2c_client *client);
static struct adm9240_data *adm9240_update_device(struct device *dev);
/* driver data */
static const struct i2c_device_id adm9240_id[] = {
{ "adm9240", adm9240 },
{ "ds1780", ds1780 },
{ "lm81", lm81 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm9240_id);
static struct i2c_driver adm9240_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm9240",
},
.probe = adm9240_probe,
.remove = adm9240_remove,
.id_table = adm9240_id,
.detect = adm9240_detect,
.address_list = normal_i2c,
};
/* per client data */
struct adm9240_data {
struct device *hwmon_dev;
......@@ -181,6 +152,110 @@ struct adm9240_data {
u8 vrm; /* -- vrm set on startup, no accessor */
};
/* write new fan div, callers must hold data->update_lock */
static void adm9240_write_fan_div(struct i2c_client *client, int nr,
u8 fan_div)
{
u8 reg, old, shift = (nr + 2) * 2;
reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
old = (reg >> shift) & 3;
reg &= ~(3 << shift);
reg |= (fan_div << shift);
i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
dev_dbg(&client->dev,
"fan%d clock divider changed from %u to %u\n",
nr + 1, 1 << old, 1 << fan_div);
}
static struct adm9240_data *adm9240_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
int i;
mutex_lock(&data->update_lock);
/* minimum measurement cycle: 1.75 seconds */
if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
|| !data->valid) {
for (i = 0; i < 6; i++) { /* read voltages */
data->in[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN(i));
}
data->alarms = i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(0)) |
i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(1)) << 8;
/*
* read temperature: assume temperature changes less than
* 0.5'C per two measurement cycles thus ignore possible
* but unlikely aliasing error on lsb reading. --Grant
*/
data->temp = ((i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP) << 8) |
i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_CONF)) / 128;
for (i = 0; i < 2; i++) { /* read fans */
data->fan[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN(i));
/* adjust fan clock divider on overflow */
if (data->valid && data->fan[i] == 255 &&
data->fan_div[i] < 3) {
adm9240_write_fan_div(client, i,
++data->fan_div[i]);
/* adjust fan_min if active, but not to 0 */
if (data->fan_min[i] < 255 &&
data->fan_min[i] >= 2)
data->fan_min[i] /= 2;
}
}
data->last_updated_measure = jiffies;
}
/* minimum config reading cycle: 300 seconds */
if (time_after(jiffies, data->last_updated_config + (HZ * 300))
|| !data->valid) {
for (i = 0; i < 6; i++) {
data->in_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MIN(i));
data->in_max[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MAX(i));
}
for (i = 0; i < 2; i++) {
data->fan_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN_MIN(i));
}
data->temp_max[0] = i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_MAX(0));
data->temp_max[1] = i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_MAX(1));
/* read fan divs and 5-bit VID */
i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
data->fan_div[0] = (i >> 4) & 3;
data->fan_div[1] = (i >> 6) & 3;
data->vid = i & 0x0f;
data->vid |= (i2c_smbus_read_byte_data(client,
ADM9240_REG_VID4) & 1) << 4;
/* read analog out */
data->aout = i2c_smbus_read_byte_data(client,
ADM9240_REG_ANALOG_OUT);
data->last_updated_config = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
/*** sysfs accessors ***/
/* temperature */
......@@ -340,22 +415,6 @@ static ssize_t show_fan_div(struct device *dev,
return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
}
/* write new fan div, callers must hold data->update_lock */
static void adm9240_write_fan_div(struct i2c_client *client, int nr,
u8 fan_div)
{
u8 reg, old, shift = (nr + 2) * 2;
reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
old = (reg >> shift) & 3;
reg &= ~(3 << shift);
reg |= (fan_div << shift);
i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
dev_dbg(&client->dev,
"fan%d clock divider changed from %u to %u\n",
nr + 1, 1 << old, 1 << fan_div);
}
/*
* set fan speed low limit:
*
......@@ -620,49 +679,6 @@ static int adm9240_detect(struct i2c_client *new_client,
return 0;
}
static int adm9240_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct adm9240_data *data;
int err;
data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(new_client, data);
mutex_init(&data->update_lock);
adm9240_init_client(new_client);
/* populate sysfs filesystem */
err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
return err;
}
static int adm9240_remove(struct i2c_client *client)
{
struct adm9240_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm9240_group);
return 0;
}
static void adm9240_init_client(struct i2c_client *client)
{
struct adm9240_data *data = i2c_get_clientdata(client);
......@@ -705,93 +721,68 @@ static void adm9240_init_client(struct i2c_client *client)
}
}
static struct adm9240_data *adm9240_update_device(struct device *dev)
static int adm9240_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
int i;
struct adm9240_data *data;
int err;
mutex_lock(&data->update_lock);
data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
/* minimum measurement cycle: 1.75 seconds */
if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
|| !data->valid) {
i2c_set_clientdata(new_client, data);
mutex_init(&data->update_lock);
for (i = 0; i < 6; i++) { /* read voltages */
data->in[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN(i));
}
data->alarms = i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(0)) |
i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(1)) << 8;
adm9240_init_client(new_client);
/*
* read temperature: assume temperature changes less than
* 0.5'C per two measurement cycles thus ignore possible
* but unlikely aliasing error on lsb reading. --Grant
*/
data->temp = ((i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP) << 8) |
i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_CONF)) / 128;
/* populate sysfs filesystem */
err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
if (err)
return err;
for (i = 0; i < 2; i++) { /* read fans */
data->fan[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN(i));
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
/* adjust fan clock divider on overflow */
if (data->valid && data->fan[i] == 255 &&
data->fan_div[i] < 3) {
return 0;
adm9240_write_fan_div(client, i,
++data->fan_div[i]);
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
return err;
}
/* adjust fan_min if active, but not to 0 */
if (data->fan_min[i] < 255 &&
data->fan_min[i] >= 2)
data->fan_min[i] /= 2;
}
}
data->last_updated_measure = jiffies;
}
static int adm9240_remove(struct i2c_client *client)
{
struct adm9240_data *data = i2c_get_clientdata(client);
/* minimum config reading cycle: 300 seconds */
if (time_after(jiffies, data->last_updated_config + (HZ * 300))
|| !data->valid) {
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm9240_group);
for (i = 0; i < 6; i++) {
data->in_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MIN(i));
data->in_max[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MAX(i));
}
for (i = 0; i < 2; i++) {
data->fan_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN_MIN(i));
}
data->temp_max[0] = i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_MAX(0));
data->temp_max[1] = i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_MAX(1));
return 0;
}
/* read fan divs and 5-bit VID */
i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
data->fan_div[0] = (i >> 4) & 3;
data->fan_div[1] = (i >> 6) & 3;
data->vid = i & 0x0f;
data->vid |= (i2c_smbus_read_byte_data(client,
ADM9240_REG_VID4) & 1) << 4;
/* read analog out */
data->aout = i2c_smbus_read_byte_data(client,
ADM9240_REG_ANALOG_OUT);
static const struct i2c_device_id adm9240_id[] = {
{ "adm9240", adm9240 },
{ "ds1780", ds1780 },
{ "lm81", lm81 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm9240_id);
data->last_updated_config = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
static struct i2c_driver adm9240_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm9240",
},
.probe = adm9240_probe,
.remove = adm9240_remove,
.id_table = adm9240_id,
.detect = adm9240_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adm9240_driver);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment