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) ...@@ -130,35 +130,6 @@ static inline unsigned int AOUT_FROM_REG(u8 reg)
return SCALE(reg, 1250, 255); 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 */ /* per client data */
struct adm9240_data { struct adm9240_data {
struct device *hwmon_dev; struct device *hwmon_dev;
...@@ -181,6 +152,110 @@ struct adm9240_data { ...@@ -181,6 +152,110 @@ struct adm9240_data {
u8 vrm; /* -- vrm set on startup, no accessor */ 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 ***/ /*** sysfs accessors ***/
/* temperature */ /* temperature */
...@@ -340,22 +415,6 @@ static ssize_t show_fan_div(struct device *dev, ...@@ -340,22 +415,6 @@ static ssize_t show_fan_div(struct device *dev,
return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]); 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: * set fan speed low limit:
* *
...@@ -620,49 +679,6 @@ static int adm9240_detect(struct i2c_client *new_client, ...@@ -620,49 +679,6 @@ static int adm9240_detect(struct i2c_client *new_client,
return 0; 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) static void adm9240_init_client(struct i2c_client *client)
{ {
struct adm9240_data *data = i2c_get_clientdata(client); struct adm9240_data *data = i2c_get_clientdata(client);
...@@ -705,93 +721,68 @@ static void adm9240_init_client(struct i2c_client *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;
struct adm9240_data *data = i2c_get_clientdata(client); int err;
int i;
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 */ i2c_set_clientdata(new_client, data);
if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4)) mutex_init(&data->update_lock);
|| !data->valid) {
for (i = 0; i < 6; i++) { /* read voltages */ adm9240_init_client(new_client);
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;
/* /* populate sysfs filesystem */
* read temperature: assume temperature changes less than err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
* 0.5'C per two measurement cycles thus ignore possible if (err)
* but unlikely aliasing error on lsb reading. --Grant return err;
*/
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->hwmon_dev = hwmon_device_register(&new_client->dev);
data->fan[i] = i2c_smbus_read_byte_data(client, if (IS_ERR(data->hwmon_dev)) {
ADM9240_REG_FAN(i)); err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
/* adjust fan clock divider on overflow */ return 0;
if (data->valid && data->fan[i] == 255 &&
data->fan_div[i] < 3) {
adm9240_write_fan_div(client, i, exit_remove:
++data->fan_div[i]); sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
return err;
}
/* adjust fan_min if active, but not to 0 */ static int adm9240_remove(struct i2c_client *client)
if (data->fan_min[i] < 255 && {
data->fan_min[i] >= 2) struct adm9240_data *data = i2c_get_clientdata(client);
data->fan_min[i] /= 2;
}
}
data->last_updated_measure = jiffies;
}
/* minimum config reading cycle: 300 seconds */ hwmon_device_unregister(data->hwmon_dev);
if (time_after(jiffies, data->last_updated_config + (HZ * 300)) sysfs_remove_group(&client->dev.kobj, &adm9240_group);
|| !data->valid) {
for (i = 0; i < 6; i++) { return 0;
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 */ static const struct i2c_device_id adm9240_id[] = {
i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV); { "adm9240", adm9240 },
data->fan_div[0] = (i >> 4) & 3; { "ds1780", ds1780 },
data->fan_div[1] = (i >> 6) & 3; { "lm81", lm81 },
data->vid = i & 0x0f; { }
data->vid |= (i2c_smbus_read_byte_data(client, };
ADM9240_REG_VID4) & 1) << 4; MODULE_DEVICE_TABLE(i2c, adm9240_id);
/* read analog out */
data->aout = i2c_smbus_read_byte_data(client,
ADM9240_REG_ANALOG_OUT);
data->last_updated_config = jiffies; static struct i2c_driver adm9240_driver = {
data->valid = 1; .class = I2C_CLASS_HWMON,
} .driver = {
mutex_unlock(&data->update_lock); .name = "adm9240",
return data; },
} .probe = adm9240_probe,
.remove = adm9240_remove,
.id_table = adm9240_id,
.detect = adm9240_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adm9240_driver); 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