Commit 97df5566 authored by Axel Lin's avatar Axel Lin Committed by Guenter Roeck

hwmon: (adm1026) 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 aab3f57a
......@@ -298,37 +298,6 @@ struct adm1026_data {
u8 config3; /* Register value */
};
static int adm1026_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1026_detect(struct i2c_client *client,
struct i2c_board_info *info);
static int adm1026_remove(struct i2c_client *client);
static int adm1026_read_value(struct i2c_client *client, u8 reg);
static int adm1026_write_value(struct i2c_client *client, u8 reg, int value);
static void adm1026_print_gpio(struct i2c_client *client);
static void adm1026_fixup_gpio(struct i2c_client *client);
static struct adm1026_data *adm1026_update_device(struct device *dev);
static void adm1026_init_client(struct i2c_client *client);
static const struct i2c_device_id adm1026_id[] = {
{ "adm1026", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1026_id);
static struct i2c_driver adm1026_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1026",
},
.probe = adm1026_probe,
.remove = adm1026_remove,
.id_table = adm1026_id,
.detect = adm1026_detect,
.address_list = normal_i2c,
};
static int adm1026_read_value(struct i2c_client *client, u8 reg)
{
int res;
......@@ -357,208 +326,6 @@ static int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
return res;
}
static void adm1026_init_client(struct i2c_client *client)
{
int value, i;
struct adm1026_data *data = i2c_get_clientdata(client);
dev_dbg(&client->dev, "Initializing device\n");
/* Read chip config */
data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
/* Inform user of chip config */
dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
data->config1);
if ((data->config1 & CFG1_MONITOR) == 0) {
dev_dbg(&client->dev,
"Monitoring not currently enabled.\n");
}
if (data->config1 & CFG1_INT_ENABLE) {
dev_dbg(&client->dev,
"SMBALERT interrupts are enabled.\n");
}
if (data->config1 & CFG1_AIN8_9) {
dev_dbg(&client->dev,
"in8 and in9 enabled. temp3 disabled.\n");
} else {
dev_dbg(&client->dev,
"temp3 enabled. in8 and in9 disabled.\n");
}
if (data->config1 & CFG1_THERM_HOT) {
dev_dbg(&client->dev,
"Automatic THERM, PWM, and temp limits enabled.\n");
}
if (data->config3 & CFG3_GPIO16_ENABLE) {
dev_dbg(&client->dev,
"GPIO16 enabled. THERM pin disabled.\n");
} else {
dev_dbg(&client->dev,
"THERM pin enabled. GPIO16 disabled.\n");
}
if (data->config3 & CFG3_VREF_250)
dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
else
dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
/* Read and pick apart the existing GPIO configuration */
value = 0;
for (i = 0; i <= 15; ++i) {
if ((i & 0x03) == 0) {
value = adm1026_read_value(client,
ADM1026_REG_GPIO_CFG_0_3 + i / 4);
}
data->gpio_config[i] = value & 0x03;
value >>= 2;
}
data->gpio_config[16] = (data->config3 >> 6) & 0x03;
/* ... and then print it */
adm1026_print_gpio(client);
/*
* If the user asks us to reprogram the GPIO config, then
* do it now.
*/
if (gpio_input[0] != -1 || gpio_output[0] != -1
|| gpio_inverted[0] != -1 || gpio_normal[0] != -1
|| gpio_fan[0] != -1) {
adm1026_fixup_gpio(client);
}
/*
* WE INTENTIONALLY make no changes to the limits,
* offsets, pwms, fans and zones. If they were
* configured, we don't want to mess with them.
* If they weren't, the default is 100% PWM, no
* control and will suffice until 'sensors -s'
* can be run by the user. We DO set the default
* value for pwm1.auto_pwm_min to its maximum
* so that enabling automatic pwm fan control
* without first setting a value for pwm1.auto_pwm_min
* will not result in potentially dangerous fan speed decrease.
*/
data->pwm1.auto_pwm_min = 255;
/* Start monitoring */
value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
/* Set MONITOR, clear interrupt acknowledge and s/w reset */
value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
data->config1 = value;
adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
/* initialize fan_div[] to hardware defaults */
value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
for (i = 0; i <= 7; ++i) {
data->fan_div[i] = DIV_FROM_REG(value & 0x03);
value >>= 2;
}
}
static void adm1026_print_gpio(struct i2c_client *client)
{
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
dev_dbg(&client->dev, "GPIO config is:\n");
for (i = 0; i <= 7; ++i) {
if (data->config2 & (1 << i)) {
dev_dbg(&client->dev, "\t%sGP%s%d\n",
data->gpio_config[i] & 0x02 ? "" : "!",
data->gpio_config[i] & 0x01 ? "OUT" : "IN",
i);
} else {
dev_dbg(&client->dev, "\tFAN%d\n", i);
}
}
for (i = 8; i <= 15; ++i) {
dev_dbg(&client->dev, "\t%sGP%s%d\n",
data->gpio_config[i] & 0x02 ? "" : "!",
data->gpio_config[i] & 0x01 ? "OUT" : "IN",
i);
}
if (data->config3 & CFG3_GPIO16_ENABLE) {
dev_dbg(&client->dev, "\t%sGP%s16\n",
data->gpio_config[16] & 0x02 ? "" : "!",
data->gpio_config[16] & 0x01 ? "OUT" : "IN");
} else {
/* GPIO16 is THERM */
dev_dbg(&client->dev, "\tTHERM\n");
}
}
static void adm1026_fixup_gpio(struct i2c_client *client)
{
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
int value;
/* Make the changes requested. */
/*
* We may need to unlock/stop monitoring or soft-reset the
* chip before we can make changes. This hasn't been
* tested much. FIXME
*/
/* Make outputs */
for (i = 0; i <= 16; ++i) {
if (gpio_output[i] >= 0 && gpio_output[i] <= 16)
data->gpio_config[gpio_output[i]] |= 0x01;
/* if GPIO0-7 is output, it isn't a FAN tach */
if (gpio_output[i] >= 0 && gpio_output[i] <= 7)
data->config2 |= 1 << gpio_output[i];
}
/* Input overrides output */
for (i = 0; i <= 16; ++i) {
if (gpio_input[i] >= 0 && gpio_input[i] <= 16)
data->gpio_config[gpio_input[i]] &= ~0x01;
/* if GPIO0-7 is input, it isn't a FAN tach */
if (gpio_input[i] >= 0 && gpio_input[i] <= 7)
data->config2 |= 1 << gpio_input[i];
}
/* Inverted */
for (i = 0; i <= 16; ++i) {
if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16)
data->gpio_config[gpio_inverted[i]] &= ~0x02;
}
/* Normal overrides inverted */
for (i = 0; i <= 16; ++i) {
if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16)
data->gpio_config[gpio_normal[i]] |= 0x02;
}
/* Fan overrides input and output */
for (i = 0; i <= 7; ++i) {
if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7)
data->config2 &= ~(1 << gpio_fan[i]);
}
/* Write new configs to registers */
adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
data->config3 = (data->config3 & 0x3f)
| ((data->gpio_config[16] & 0x03) << 6);
adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
for (i = 15, value = 0; i >= 0; --i) {
value <<= 2;
value |= data->gpio_config[i] & 0x03;
if ((i & 0x03) == 0) {
adm1026_write_value(client,
ADM1026_REG_GPIO_CFG_0_3 + i/4,
value);
value = 0;
}
}
/* Print the new config */
adm1026_print_gpio(client);
}
static struct adm1026_data *adm1026_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
......@@ -1829,6 +1596,207 @@ static int adm1026_detect(struct i2c_client *client,
return 0;
}
static void adm1026_print_gpio(struct i2c_client *client)
{
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
dev_dbg(&client->dev, "GPIO config is:\n");
for (i = 0; i <= 7; ++i) {
if (data->config2 & (1 << i)) {
dev_dbg(&client->dev, "\t%sGP%s%d\n",
data->gpio_config[i] & 0x02 ? "" : "!",
data->gpio_config[i] & 0x01 ? "OUT" : "IN",
i);
} else {
dev_dbg(&client->dev, "\tFAN%d\n", i);
}
}
for (i = 8; i <= 15; ++i) {
dev_dbg(&client->dev, "\t%sGP%s%d\n",
data->gpio_config[i] & 0x02 ? "" : "!",
data->gpio_config[i] & 0x01 ? "OUT" : "IN",
i);
}
if (data->config3 & CFG3_GPIO16_ENABLE) {
dev_dbg(&client->dev, "\t%sGP%s16\n",
data->gpio_config[16] & 0x02 ? "" : "!",
data->gpio_config[16] & 0x01 ? "OUT" : "IN");
} else {
/* GPIO16 is THERM */
dev_dbg(&client->dev, "\tTHERM\n");
}
}
static void adm1026_fixup_gpio(struct i2c_client *client)
{
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
int value;
/* Make the changes requested. */
/*
* We may need to unlock/stop monitoring or soft-reset the
* chip before we can make changes. This hasn't been
* tested much. FIXME
*/
/* Make outputs */
for (i = 0; i <= 16; ++i) {
if (gpio_output[i] >= 0 && gpio_output[i] <= 16)
data->gpio_config[gpio_output[i]] |= 0x01;
/* if GPIO0-7 is output, it isn't a FAN tach */
if (gpio_output[i] >= 0 && gpio_output[i] <= 7)
data->config2 |= 1 << gpio_output[i];
}
/* Input overrides output */
for (i = 0; i <= 16; ++i) {
if (gpio_input[i] >= 0 && gpio_input[i] <= 16)
data->gpio_config[gpio_input[i]] &= ~0x01;
/* if GPIO0-7 is input, it isn't a FAN tach */
if (gpio_input[i] >= 0 && gpio_input[i] <= 7)
data->config2 |= 1 << gpio_input[i];
}
/* Inverted */
for (i = 0; i <= 16; ++i) {
if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16)
data->gpio_config[gpio_inverted[i]] &= ~0x02;
}
/* Normal overrides inverted */
for (i = 0; i <= 16; ++i) {
if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16)
data->gpio_config[gpio_normal[i]] |= 0x02;
}
/* Fan overrides input and output */
for (i = 0; i <= 7; ++i) {
if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7)
data->config2 &= ~(1 << gpio_fan[i]);
}
/* Write new configs to registers */
adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
data->config3 = (data->config3 & 0x3f)
| ((data->gpio_config[16] & 0x03) << 6);
adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
for (i = 15, value = 0; i >= 0; --i) {
value <<= 2;
value |= data->gpio_config[i] & 0x03;
if ((i & 0x03) == 0) {
adm1026_write_value(client,
ADM1026_REG_GPIO_CFG_0_3 + i/4,
value);
value = 0;
}
}
/* Print the new config */
adm1026_print_gpio(client);
}
static void adm1026_init_client(struct i2c_client *client)
{
int value, i;
struct adm1026_data *data = i2c_get_clientdata(client);
dev_dbg(&client->dev, "Initializing device\n");
/* Read chip config */
data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
/* Inform user of chip config */
dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
data->config1);
if ((data->config1 & CFG1_MONITOR) == 0) {
dev_dbg(&client->dev,
"Monitoring not currently enabled.\n");
}
if (data->config1 & CFG1_INT_ENABLE) {
dev_dbg(&client->dev,
"SMBALERT interrupts are enabled.\n");
}
if (data->config1 & CFG1_AIN8_9) {
dev_dbg(&client->dev,
"in8 and in9 enabled. temp3 disabled.\n");
} else {
dev_dbg(&client->dev,
"temp3 enabled. in8 and in9 disabled.\n");
}
if (data->config1 & CFG1_THERM_HOT) {
dev_dbg(&client->dev,
"Automatic THERM, PWM, and temp limits enabled.\n");
}
if (data->config3 & CFG3_GPIO16_ENABLE) {
dev_dbg(&client->dev,
"GPIO16 enabled. THERM pin disabled.\n");
} else {
dev_dbg(&client->dev,
"THERM pin enabled. GPIO16 disabled.\n");
}
if (data->config3 & CFG3_VREF_250)
dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
else
dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
/* Read and pick apart the existing GPIO configuration */
value = 0;
for (i = 0; i <= 15; ++i) {
if ((i & 0x03) == 0) {
value = adm1026_read_value(client,
ADM1026_REG_GPIO_CFG_0_3 + i / 4);
}
data->gpio_config[i] = value & 0x03;
value >>= 2;
}
data->gpio_config[16] = (data->config3 >> 6) & 0x03;
/* ... and then print it */
adm1026_print_gpio(client);
/*
* If the user asks us to reprogram the GPIO config, then
* do it now.
*/
if (gpio_input[0] != -1 || gpio_output[0] != -1
|| gpio_inverted[0] != -1 || gpio_normal[0] != -1
|| gpio_fan[0] != -1) {
adm1026_fixup_gpio(client);
}
/*
* WE INTENTIONALLY make no changes to the limits,
* offsets, pwms, fans and zones. If they were
* configured, we don't want to mess with them.
* If they weren't, the default is 100% PWM, no
* control and will suffice until 'sensors -s'
* can be run by the user. We DO set the default
* value for pwm1.auto_pwm_min to its maximum
* so that enabling automatic pwm fan control
* without first setting a value for pwm1.auto_pwm_min
* will not result in potentially dangerous fan speed decrease.
*/
data->pwm1.auto_pwm_min = 255;
/* Start monitoring */
value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
/* Set MONITOR, clear interrupt acknowledge and s/w reset */
value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
data->config1 = value;
adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
/* initialize fan_div[] to hardware defaults */
value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
for (i = 0; i <= 7; ++i) {
data->fan_div[i] = DIV_FROM_REG(value & 0x03);
value >>= 2;
}
}
static int adm1026_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
......@@ -1892,6 +1860,24 @@ static int adm1026_remove(struct i2c_client *client)
return 0;
}
static const struct i2c_device_id adm1026_id[] = {
{ "adm1026", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1026_id);
static struct i2c_driver adm1026_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1026",
},
.probe = adm1026_probe,
.remove = adm1026_remove,
.id_table = adm1026_id,
.detect = adm1026_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adm1026_driver);
MODULE_LICENSE("GPL");
......
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