aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/max6639.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/max6639.c')
-rw-r--r--drivers/hwmon/max6639.c79
1 files changed, 61 insertions, 18 deletions
diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c
index 2d56e97aa5fa..9b895402c80d 100644
--- a/drivers/hwmon/max6639.c
+++ b/drivers/hwmon/max6639.c
@@ -69,7 +69,7 @@ static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 };
struct max6639_data {
struct i2c_client *client;
struct mutex update_lock;
- char valid; /* !=0 if following fields are valid */
+ bool valid; /* true if following fields are valid */
unsigned long last_updated; /* In jiffies */
/* Register values sampled regularly */
@@ -87,6 +87,9 @@ struct max6639_data {
/* Register values initialized only once */
u8 ppr; /* Pulses per rotation 0..3 for 1..4 ppr */
u8 rpm_range; /* Index in above rpm_ranges table */
+
+ /* Optional regulator for FAN supply */
+ struct regulator *reg;
};
static struct max6639_data *max6639_update_device(struct device *dev)
@@ -141,7 +144,7 @@ static struct max6639_data *max6639_update_device(struct device *dev)
}
data->last_updated = jiffies;
- data->valid = 1;
+ data->valid = true;
}
abort:
mutex_unlock(&data->update_lock);
@@ -511,13 +514,17 @@ static int max6639_detect(struct i2c_client *client,
if (dev_id != 0x58 || manu_id != 0x4D)
return -ENODEV;
- strlcpy(info->type, "max6639", I2C_NAME_SIZE);
+ strscpy(info->type, "max6639", I2C_NAME_SIZE);
return 0;
}
-static int max6639_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static void max6639_regulator_disable(void *data)
+{
+ regulator_disable(data);
+}
+
+static int max6639_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct max6639_data *data;
@@ -529,6 +536,28 @@ static int max6639_probe(struct i2c_client *client,
return -ENOMEM;
data->client = client;
+
+ data->reg = devm_regulator_get_optional(dev, "fan");
+ if (IS_ERR(data->reg)) {
+ if (PTR_ERR(data->reg) != -ENODEV)
+ return PTR_ERR(data->reg);
+
+ data->reg = NULL;
+ } else {
+ /* Spin up fans */
+ err = regulator_enable(data->reg);
+ if (err) {
+ dev_err(dev, "Failed to enable fan supply: %d\n", err);
+ return err;
+ }
+ err = devm_add_action_or_reset(dev, max6639_regulator_disable,
+ data->reg);
+ if (err) {
+ dev_err(dev, "Failed to register action: %d\n", err);
+ return err;
+ }
+ }
+
mutex_init(&data->update_lock);
/* Initialize the max6639 chip */
@@ -542,29 +571,43 @@ static int max6639_probe(struct i2c_client *client,
return PTR_ERR_OR_ZERO(hwmon_dev);
}
-#ifdef CONFIG_PM_SLEEP
static int max6639_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
- int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG);
- if (data < 0)
- return data;
+ struct max6639_data *data = dev_get_drvdata(dev);
+ int ret = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG);
+
+ if (ret < 0)
+ return ret;
+
+ if (data->reg)
+ regulator_disable(data->reg);
return i2c_smbus_write_byte_data(client,
- MAX6639_REG_GCONFIG, data | MAX6639_GCONFIG_STANDBY);
+ MAX6639_REG_GCONFIG, ret | MAX6639_GCONFIG_STANDBY);
}
static int max6639_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
- int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG);
- if (data < 0)
- return data;
+ struct max6639_data *data = dev_get_drvdata(dev);
+ int ret;
+
+ if (data->reg) {
+ ret = regulator_enable(data->reg);
+ if (ret) {
+ dev_err(dev, "Failed to enable fan supply: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG);
+ if (ret < 0)
+ return ret;
return i2c_smbus_write_byte_data(client,
- MAX6639_REG_GCONFIG, data & ~MAX6639_GCONFIG_STANDBY);
+ MAX6639_REG_GCONFIG, ret & ~MAX6639_GCONFIG_STANDBY);
}
-#endif /* CONFIG_PM_SLEEP */
static const struct i2c_device_id max6639_id[] = {
{"max6639", 0},
@@ -573,15 +616,15 @@ static const struct i2c_device_id max6639_id[] = {
MODULE_DEVICE_TABLE(i2c, max6639_id);
-static SIMPLE_DEV_PM_OPS(max6639_pm_ops, max6639_suspend, max6639_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(max6639_pm_ops, max6639_suspend, max6639_resume);
static struct i2c_driver max6639_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "max6639",
- .pm = &max6639_pm_ops,
+ .pm = pm_sleep_ptr(&max6639_pm_ops),
},
- .probe = max6639_probe,
+ .probe_new = max6639_probe,
.id_table = max6639_id,
.detect = max6639_detect,
.address_list = normal_i2c,